/* eject.c - eject device. * * Copyright 2012 Harvind Singh * Copyright 2013 Kyungwan Han * Not in SUSv4. USE_EJECT(NEWTOY(eject, ">1stT[!tT]", TOYFLAG_USR|TOYFLAG_BIN)) config EJECT bool "eject" default y help usage: eject [-s] [-t] [-T] [...] Eject DEVICE or default /dev/cdrom -s SCSI device -t Close tray -T Open/close tray (toggle). */ #define FOR_eject #include "toys.h" #include #include #define CDROM_DRIVE_STATUS 0x5326 //Get tray position, etc. #define CDROM_CLOSE_TRAY 0x5319 //Pendant of CDROM_EJECT. #define CDROM_EJECT 0x5309 //Ejects the cdrom media. #define DRIVE_NOT_READY 3 //Drive is busy. /* * Remove SCSI Device. */ static void remove_scsi(int dscptr) { char sg_driver_cmd[3][6] = { { ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0 }, //allow medium removal { START_STOP, 0, 0, 0, 1, 0 }, //start the motor { START_STOP, 0, 0, 0, 2, 0 } //eject the media }; unsigned i; unsigned char buffer1[32],buffer2[2]; sg_io_hdr_t in_out_header; if ((ioctl(dscptr, SG_GET_VERSION_NUM, &i) < 0) || (i < 30000)) error_exit("not a sg device or old sg driver"); memset(&in_out_header, 0, sizeof(sg_io_hdr_t)); in_out_header.interface_id = 'S'; in_out_header.cmd_len = 6; in_out_header.mx_sb_len = sizeof(buffer1); in_out_header.dxfer_direction = SG_DXFER_NONE; in_out_header.dxferp = buffer2; in_out_header.sbp = buffer1; in_out_header.timeout = 2000; for (i = 0; i < 3; i++) { in_out_header.cmdp = (void *)sg_driver_cmd[i]; xioctl(dscptr, SG_IO, (void *)&in_out_header); } /* force kernel to reread partition table when new disc is inserted */ ioctl(dscptr, BLKRRPART); } /* * eject main function. */ void eject_main(void) { int fd, out = 0, rc = 0; char *device_name; if (!toys.optc) device_name = "/dev/cdrom"; else device_name = toys.optargs[0]; fd = xopen(device_name, O_RDONLY | O_NONBLOCK); if (!toys.optflags) xioctl(fd, CDROM_EJECT, &out); else if (toys.optflags & FLAG_s) remove_scsi(fd); else { if (toys.optflags & FLAG_T || toys.optflags & FLAG_t) { rc = ioctl(fd, CDROM_DRIVE_STATUS, &out); if (toys.optflags & FLAG_t || rc == 2) //CDS_TRAY_OPEN = 2 xioctl(fd, CDROM_CLOSE_TRAY, &out); else xioctl(fd, CDROM_EJECT, &out); } } xclose(fd); }