toybox/toys/other/eject.c
<<
>>
Prefs
   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
   8USE_EJECT(NEWTOY(eject, ">1stT[!tT]", TOYFLAG_USR|TOYFLAG_BIN))
   9
  10config 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
  29static 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 */
  59void 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