10f66f451Sopenharmony_ci/* eject.c - eject device. 20f66f451Sopenharmony_ci * 30f66f451Sopenharmony_ci * Copyright 2012 Harvind Singh <harvindsingh1981@gmail.com> 40f66f451Sopenharmony_ci * Copyright 2013 Kyungwan Han <asura321@gamil.com> 50f66f451Sopenharmony_ci * 60f66f451Sopenharmony_ci * No standard. 70f66f451Sopenharmony_ci 80f66f451Sopenharmony_ciUSE_EJECT(NEWTOY(eject, ">1stT[!tT]", TOYFLAG_USR|TOYFLAG_BIN)) 90f66f451Sopenharmony_ci 100f66f451Sopenharmony_ciconfig EJECT 110f66f451Sopenharmony_ci bool "eject" 120f66f451Sopenharmony_ci default y 130f66f451Sopenharmony_ci help 140f66f451Sopenharmony_ci usage: eject [-stT] [DEVICE] 150f66f451Sopenharmony_ci 160f66f451Sopenharmony_ci Eject DEVICE or default /dev/cdrom 170f66f451Sopenharmony_ci 180f66f451Sopenharmony_ci -s SCSI device 190f66f451Sopenharmony_ci -t Close tray 200f66f451Sopenharmony_ci -T Open/close tray (toggle) 210f66f451Sopenharmony_ci*/ 220f66f451Sopenharmony_ci 230f66f451Sopenharmony_ci#define FOR_eject 240f66f451Sopenharmony_ci#include "toys.h" 250f66f451Sopenharmony_ci#include <scsi/sg.h> 260f66f451Sopenharmony_ci#include <scsi/scsi.h> 270f66f451Sopenharmony_ci#include <linux/cdrom.h> 280f66f451Sopenharmony_ci 290f66f451Sopenharmony_ci// SCSI's overcomplicated way of requesting eject 300f66f451Sopenharmony_cistatic void remove_scsi(int fd) 310f66f451Sopenharmony_ci{ 320f66f451Sopenharmony_ci unsigned i; 330f66f451Sopenharmony_ci sg_io_hdr_t *header = (sg_io_hdr_t *)(toybuf+64); 340f66f451Sopenharmony_ci char sg_driver_cmd[][6] = { 350f66f451Sopenharmony_ci { ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0 }, 360f66f451Sopenharmony_ci { START_STOP, 0, 0, 0, 1, 0 }, //start the motor 370f66f451Sopenharmony_ci { START_STOP, 0, 0, 0, 2, 0 } //eject the media 380f66f451Sopenharmony_ci }; 390f66f451Sopenharmony_ci 400f66f451Sopenharmony_ci header->interface_id = 'S'; 410f66f451Sopenharmony_ci header->cmd_len = 6; 420f66f451Sopenharmony_ci header->mx_sb_len = 32; 430f66f451Sopenharmony_ci header->dxfer_direction = SG_DXFER_NONE; 440f66f451Sopenharmony_ci header->dxferp = toybuf + 32; 450f66f451Sopenharmony_ci header->sbp = (void *)toybuf; 460f66f451Sopenharmony_ci header->timeout = 2000; 470f66f451Sopenharmony_ci 480f66f451Sopenharmony_ci for (i = 0; i < ARRAY_LEN(sg_driver_cmd); i++) { 490f66f451Sopenharmony_ci header->cmdp = (void *)sg_driver_cmd[i]; 500f66f451Sopenharmony_ci xioctl(fd, SG_IO, header); 510f66f451Sopenharmony_ci } 520f66f451Sopenharmony_ci 530f66f451Sopenharmony_ci // force kernel to reread partition table when new disc is inserted 540f66f451Sopenharmony_ci ioctl(fd, BLKRRPART); 550f66f451Sopenharmony_ci} 560f66f451Sopenharmony_ci 570f66f451Sopenharmony_civoid eject_main(void) 580f66f451Sopenharmony_ci{ 590f66f451Sopenharmony_ci int fd = xopen(*toys.optargs ? : "/dev/cdrom", O_RDONLY | O_NONBLOCK); 600f66f451Sopenharmony_ci 610f66f451Sopenharmony_ci if (FLAG(s)) remove_scsi(fd); 620f66f451Sopenharmony_ci else if (FLAG(T) && CDS_TRAY_OPEN == ioctl(fd, CDROM_DRIVE_STATUS, toybuf)) 630f66f451Sopenharmony_ci xioctl(fd, CDROMCLOSETRAY, toybuf); 640f66f451Sopenharmony_ci else xioctl(fd, CDROMEJECT, toybuf); 650f66f451Sopenharmony_ci if (CFG_TOYBOX_FREE) xclose(fd); 660f66f451Sopenharmony_ci} 67