• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /* eject.c - eject device.
2   *
3   * Copyright 2012 Harvind Singh <harvindsingh1981@gmail.com>
4   * Copyright 2013 Kyungwan Han <asura321@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
remove_scsi(int fd)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   */
eject_main(void)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