Home | History | Annotate | Download | only in other
      1 /* eject.c - eject device.
      2  *
      3  * Copyright 2012 Harvind Singh <harvindsingh1981 (at) gmail.com>
      4  * Copyright 2013 Kyungwan Han <asura321 (at) gamil.com>
      5  *
      6  * No standard.
      7 
      8 USE_EJECT(NEWTOY(eject, ">1stT[!tT]", TOYFLAG_USR|TOYFLAG_BIN))
      9 
     10 config EJECT
     11   bool "eject"
     12   default y
     13   help
     14     usage: eject [-stT] [DEVICE]
     15 
     16     Eject DEVICE or default /dev/cdrom
     17 
     18     -s	SCSI device
     19     -t	Close tray
     20     -T	Open/close tray (toggle)
     21 */
     22 
     23 #define FOR_eject
     24 #include "toys.h"
     25 #include <scsi/sg.h>
     26 #include <scsi/scsi.h>
     27 
     28 // The SCSI way of requesting eject
     29 static void remove_scsi(int fd)
     30 {
     31   unsigned i;
     32   sg_io_hdr_t *header = (sg_io_hdr_t *)(toybuf+64);
     33   char sg_driver_cmd[3][6] = {
     34     { ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0 },
     35     { START_STOP, 0, 0, 0, 1, 0 }, //start the motor
     36     { START_STOP, 0, 0, 0, 2, 0 } //eject the media
     37   };
     38 
     39   header->interface_id = 'S';
     40   header->cmd_len = 6;
     41   header->mx_sb_len = 32;
     42   header->dxfer_direction = SG_DXFER_NONE;
     43   header->dxferp = toybuf + 32;
     44   header->sbp = (void *)toybuf;
     45   header->timeout = 2000;
     46 
     47   for (i = 0; i < 3; i++) {
     48     header->cmdp = (void *)sg_driver_cmd[i];
     49     xioctl(fd, SG_IO, (void *)header);
     50   }
     51 
     52   // force kernel to reread partition table when new disc is inserted
     53   ioctl(fd, BLKRRPART);
     54 }
     55 
     56 /*
     57  * eject main function.
     58  */
     59 void eject_main(void)
     60 {
     61   int fd, out = 0;
     62   char *device_name = "/dev/cdrom";
     63 
     64   if (*toys.optargs) device_name = *toys.optargs;
     65 
     66   fd = xopen(device_name, O_RDONLY | O_NONBLOCK);
     67   if (!toys.optflags) xioctl(fd, 0x5309, &out);		// CDROM_EJECT
     68   else if (toys.optflags & FLAG_s) remove_scsi(fd);
     69   else {
     70     if ((toys.optflags & FLAG_T) || (toys.optflags & FLAG_t)) {
     71       int rc = ioctl(fd, 0x5326, &out);			// CDROM_DRIVE_STATUS
     72       if ((toys.optflags & FLAG_t) || rc == 2)		// CDS_TRAY_OPEN
     73         xioctl(fd, 0x5319, &out);			// CDROM_CLOSE_TRAY
     74       else xioctl(fd, 0x5309, &out);			// CDROM_EJECT
     75     }
     76   }
     77   if (CFG_TOYBOX_FREE) xclose(fd);
     78 }
     79