public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2.6.15-rc6] block: Make CDROMEJECT more robust
@ 2005-12-19 15:32 Ben Collins
  2005-12-19 19:35 ` Jens Axboe
  0 siblings, 1 reply; 13+ messages in thread
From: Ben Collins @ 2005-12-19 15:32 UTC (permalink / raw)
  To: torvalds, akpm; +Cc: linux-kernel

Reference: https://bugzilla.ubuntu.com/5049

The eject command was failing for a large group of users for removable
devices. The "eject -r" command, which uses the CDROMEJECT ioctl would not
work, however "eject -s", which uses SG_IO did work, but required root access.

Since SG_IO was using the same mechanism as CDROMEJECT, there should be no
difference. The main reason for getting the CDROMEJECT ioctl working was
because it didn't need root privileges like the SG_IO commands did.

One bug was noticed, and that is CDROMEJECT was setting the blk request to a
WRITE operation, when in fact it wasn't. The block layer did not like getting
WRITE requests when data_len==0 and data==NULL.

The other issue was that "eject -s" was sending two extra commands that
seemed to work for just about any removable device. CDROMEJECT works as
such:

START_STOP : 0x02

While "eject -s" sent(via SG_IO):

ALLOW_MEDIUM_REMOVAL
START_STOP : 0x01
START_STOP : 0x02

This patch fixes the WRITE vs READ issue, and also sends the extra two
commands. Anyone with an iPod connected via USB (not sure about firewire)
should be able to reproduce this issue, and verify the patch.


diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 382dea7..573da94 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -442,11 +442,38 @@ error:
 	return err;
 }
 
+/* This is only useful for the following macros */
+static int __blk_send_generic(request_queue_t *q, struct gendisk *bd_disk, int cmd, int data)
+{
+	struct request *rq;
+	int err;
+
+	rq = blk_get_request(q, READ, __GFP_WAIT);
+	rq->flags |= REQ_BLOCK_PC;
+	rq->data = NULL;
+	rq->data_len = 0;
+	rq->timeout = BLK_DEFAULT_TIMEOUT;
+	memset(rq->cmd, 0, sizeof(rq->cmd));
+	rq->cmd[0] = cmd;
+	rq->cmd[4] = data;
+	rq->cmd_len = 6;
+	err = blk_execute_rq(q, bd_disk, rq, 0);
+	blk_put_request(rq);
+
+	return err;
+}
+
+#define blk_send_start_stop(q, bd_disk, data) \
+	__blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data)
+
+#define blk_send_allow_medium_removal(q, bd_disk) \
+	__blk_send_generic(q, bd_disk, GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL, 0)
+
+
 int scsi_cmd_ioctl(struct file *file, struct gendisk *bd_disk, unsigned int cmd, void __user *arg)
 {
 	request_queue_t *q;
-	struct request *rq;
-	int close = 0, err;
+	int err;
 
 	q = bd_disk->queue;
 	if (!q)
@@ -564,19 +591,14 @@ int scsi_cmd_ioctl(struct file *file, st
 			err = sg_scsi_ioctl(file, q, bd_disk, arg);
 			break;
 		case CDROMCLOSETRAY:
-			close = 1;
+			err = blk_send_start_stop(q, bd_disk, 0x03);
+			break;
 		case CDROMEJECT:
-			rq = blk_get_request(q, WRITE, __GFP_WAIT);
-			rq->flags |= REQ_BLOCK_PC;
-			rq->data = NULL;
-			rq->data_len = 0;
-			rq->timeout = BLK_DEFAULT_TIMEOUT;
-			memset(rq->cmd, 0, sizeof(rq->cmd));
-			rq->cmd[0] = GPCMD_START_STOP_UNIT;
-			rq->cmd[4] = 0x02 + (close != 0);
-			rq->cmd_len = 6;
-			err = blk_execute_rq(q, bd_disk, rq, 0);
-			blk_put_request(rq);
+			err = 0;
+
+			err |= blk_send_allow_medium_removal(q, bd_disk);
+			err |= blk_send_start_stop(q, bd_disk, 0x01);
+			err |= blk_send_start_stop(q, bd_disk, 0x02);
 			break;
 		default:
 			err = -ENOTTY;

^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2005-12-19 21:24 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-12-19 15:32 [PATCH 2.6.15-rc6] block: Make CDROMEJECT more robust Ben Collins
2005-12-19 19:35 ` Jens Axboe
2005-12-19 19:35   ` Jens Axboe
2005-12-19 19:44   ` Ben Collins
2005-12-19 19:56     ` Jens Axboe
2005-12-19 20:27       ` Ben Collins
2005-12-19 20:46         ` Jens Axboe
2005-12-19 21:24           ` Ben Collins
2005-12-19 20:02     ` Linus Torvalds
2005-12-19 20:07       ` Jens Axboe
2005-12-19 20:37       ` Ben Collins
2005-12-19 19:58   ` Ben Collins
2005-12-19 20:05     ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox