# HG changeset patch # User Rob Landley # Date 1373583774 18000 # Node ID b8ab0a8f8cefdc96114eee06f67c47121c46d91f # Parent 436c601246743e4f3d362a7226bae554f1bacd33 Eject, by Kyungwan Han. diff -r 436c60124674 -r b8ab0a8f8cef toys/other/eject.c --- /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 + * Copyright 2013 Kyungwan Han + * 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 +#include + +#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); +}