/* eject.c - eject device. * * Copyright 2012 Harvind Singh <harvindsingh1981@gmail.com> * Copyright 2013 Kyungwan Han <asura321@gamil.com> * * No standard. USE_EJECT(NEWTOY(eject, ">1stT[!tT]", TOYFLAG_USR|TOYFLAG_BIN)) config EJECT bool "eject" default y help usage: eject [-stT] [DEVICE] Eject DEVICE or default /dev/cdrom -s SCSI device -t Close tray -T Open/close tray (toggle). */ #define FOR_eject #include "toys.h" #include <scsi/sg.h> #include <scsi/scsi.h> // The SCSI way of requesting eject static void remove_scsi(int fd) { unsigned i; sg_io_hdr_t *header = (sg_io_hdr_t *)(toybuf+64); char sg_driver_cmd[3][6] = { { ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0 }, { START_STOP, 0, 0, 0, 1, 0 }, //start the motor { START_STOP, 0, 0, 0, 2, 0 } //eject the media }; header->interface_id = 'S'; header->cmd_len = 6; header->mx_sb_len = 32; header->dxfer_direction = SG_DXFER_NONE; header->dxferp = toybuf + 32; header->sbp = (void *)toybuf; header->timeout = 2000; for (i = 0; i < 3; i++) { header->cmdp = (void *)sg_driver_cmd[i]; xioctl(fd, SG_IO, (void *)header); } // force kernel to reread partition table when new disc is inserted ioctl(fd, BLKRRPART); } /* * eject main function. */ void eject_main(void) { int fd, out = 0; char *device_name = "/dev/cdrom"; if (*toys.optargs) device_name = *toys.optargs; fd = xopen(device_name, O_RDONLY | O_NONBLOCK); if (!toys.optflags) xioctl(fd, 0x5309, &out); // CDROM_EJECT else if (toys.optflags & FLAG_s) remove_scsi(fd); else { if ((toys.optflags & FLAG_T) || (toys.optflags & FLAG_t)) { int rc = ioctl(fd, 0x5326, &out); // CDROM_DRIVE_STATUS if ((toys.optflags & FLAG_t) || rc == 2) // CDS_TRAY_OPEN xioctl(fd, 0x5319, &out); // CDROM_CLOSE_TRAY else xioctl(fd, 0x5309, &out); // CDROM_EJECT } } if (CFG_TOYBOX_FREE) xclose(fd); }