changeset 946:b8ab0a8f8cef

Eject, by Kyungwan Han.
author Rob Landley <rob@landley.net>
date Thu, 11 Jul 2013 18:02:54 -0500
parents 436c60124674
children 9310246414a2
files toys/other/eject.c
diffstat 1 files changed, 89 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toys/other/eject.c	Thu Jul 11 18:02:54 2013 -0500
@@ -0,0 +1,89 @@
+/* eject.c - eject device.
+ *
+ * Copyright 2012 Harvind Singh <harvindsingh1981@gmail.com>
+ * Copyright 2013 Kyungwan Han <asura321@gamil.com>
+ * 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 <scsi/sg.h>
+#include <scsi/scsi.h>
+
+#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);
+}