From 6ef30f290c9c87428672283cf3df784a40221209 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 27 Mar 2012 17:55:30 +0200 Subject: eject: use SG_IO ioctl for scsi Signed-off-by: Karel Zak --- misc-utils/eject.c | 71 +++++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 36 deletions(-) (limited to 'misc-utils/eject.c') diff --git a/misc-utils/eject.c b/misc-utils/eject.c index 402dfe4a2..785075b2d 100644 --- a/misc-utils/eject.c +++ b/misc-utils/eject.c @@ -537,54 +537,53 @@ static int eject_cdrom(int fd) } /* - * Eject using SCSI commands. Return 1 if successful, 0 otherwise. + * Eject using SCSI SG_IO commands. Return 1 if successful, 0 otherwise. */ static int eject_scsi(int fd) { - struct sdata { - int inlen; - int outlen; - char cmd[256]; - } scsi_cmd; - - scsi_cmd.inlen = 0; - scsi_cmd.outlen = 0; - scsi_cmd.cmd[0] = ALLOW_MEDIUM_REMOVAL; - scsi_cmd.cmd[1] = 0; - scsi_cmd.cmd[2] = 0; - scsi_cmd.cmd[3] = 0; - scsi_cmd.cmd[4] = 0; - scsi_cmd.cmd[5] = 0; - if (ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd) != 0) + int status, k; + sg_io_hdr_t io_hdr; + unsigned char allowRmBlk[6] = {ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0}; + unsigned char startStop1Blk[6] = {START_STOP, 0, 0, 0, 1, 0}; + unsigned char startStop2Blk[6] = {START_STOP, 0, 0, 0, 2, 0}; + unsigned char inqBuff[2]; + unsigned char sense_buffer[32]; + + if ((ioctl(fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) { + verbose(_("not an sg device, or old sg driver")); return 0; + } - scsi_cmd.inlen = 0; - scsi_cmd.outlen = 0; - scsi_cmd.cmd[0] = START_STOP; - scsi_cmd.cmd[1] = 0; - scsi_cmd.cmd[2] = 0; - scsi_cmd.cmd[3] = 0; - scsi_cmd.cmd[4] = 1; - scsi_cmd.cmd[5] = 0; - if (ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd) != 0) + memset(&io_hdr, 0, sizeof(sg_io_hdr_t)); + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = 6; + io_hdr.mx_sb_len = sizeof(sense_buffer); + io_hdr.dxfer_direction = SG_DXFER_NONE; + io_hdr.dxfer_len = 0; + io_hdr.dxferp = inqBuff; + io_hdr.sbp = sense_buffer; + io_hdr.timeout = 10000; + + io_hdr.cmdp = allowRmBlk; + status = ioctl(fd, SG_IO, (void *)&io_hdr); + if (status < 0) return 0; - scsi_cmd.inlen = 0; - scsi_cmd.outlen = 0; - scsi_cmd.cmd[0] = START_STOP; - scsi_cmd.cmd[1] = 0; - scsi_cmd.cmd[2] = 0; - scsi_cmd.cmd[3] = 0; - scsi_cmd.cmd[4] = 2; - scsi_cmd.cmd[5] = 0; - if (ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd) != 0) + io_hdr.cmdp = startStop1Blk; + status = ioctl(fd, SG_IO, (void *)&io_hdr); + if (status < 0) + return 0; + + io_hdr.cmdp = startStop2Blk; + status = ioctl(fd, SG_IO, (void *)&io_hdr); + if (status < 0) return 0; /* force kernel to reread partition table when new disc inserted */ - return ioctl(fd, BLKRRPART) == 0; + status = ioctl(fd, BLKRRPART); + return 1; } - /* * Eject using FDEJECT ioctl. Return 1 if successful, 0 otherwise. */ -- cgit v1.2.3-55-g7522