summaryrefslogtreecommitdiffstats
path: root/misc-utils/eject.c
diff options
context:
space:
mode:
authorKarel Zak2012-03-27 17:55:30 +0200
committerKarel Zak2012-03-27 17:55:30 +0200
commit6ef30f290c9c87428672283cf3df784a40221209 (patch)
treeec28552d8fa86eed3d6d040a1dcd7c5fad5c19cb /misc-utils/eject.c
parenteject: support CDIOCEJECT ioctl (diff)
downloadkernel-qcow2-util-linux-6ef30f290c9c87428672283cf3df784a40221209.tar.gz
kernel-qcow2-util-linux-6ef30f290c9c87428672283cf3df784a40221209.tar.xz
kernel-qcow2-util-linux-6ef30f290c9c87428672283cf3df784a40221209.zip
eject: use SG_IO ioctl for scsi
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'misc-utils/eject.c')
-rw-r--r--misc-utils/eject.c71
1 files changed, 35 insertions, 36 deletions
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.
*/