From: Ben Collins <bcollins@ubuntu.com>
To: torvalds@osdl.org, akpm@osdl.org
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH 2.6.15-rc6] block: Make CDROMEJECT more robust
Date: Mon, 19 Dec 2005 07:32:36 -0800 [thread overview]
Message-ID: <20051219153236.GA10905@swissdisk.com> (raw)
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;
next reply other threads:[~2005-12-19 16:41 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-12-19 15:32 Ben Collins [this message]
2005-12-19 19:35 ` [PATCH 2.6.15-rc6] block: Make CDROMEJECT more robust 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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20051219153236.GA10905@swissdisk.com \
--to=bcollins@ubuntu.com \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox