From: Douglas Gilbert <dougg@torque.net>
To: linux-scsi@vger.kernel.org
Cc: axboe@suse.de
Subject: [PATCH] SG_IO ioctl in block layer against lk 2.5.55
Date: Fri, 10 Jan 2003 22:37:49 +1100 [thread overview]
Message-ID: <3E1EB08D.5060105@torque.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 575 bytes --]
The attachment modifies the SG_IO ioctl that is in
the block layer to:
- convey the SCSI status value back via the sg_io_hdr
structure
- in the event of CHECK CONDITION, convey the sense
buffer back via the sg_io_hdr structure
- set "output" fields in sg_io_hdr structure to sane
values
- modify the errno behaviour to be more like the
SCSI generic driver's SG_IO ioctl
This patch was presented around lk 2.5.51 but fell between
the cracks. The only modification is to take account of
the changes to scsi/scsi_lib.c since then.
Doug Gilbert
[-- Attachment #2: blk_sgio_2555.diff --]
[-- Type: text/plain, Size: 3670 bytes --]
--- linux/drivers/block/scsi_ioctl.c 2002-11-29 09:27:35.000000000 +1100
+++ linux/drivers/block/scsi_ioctl.c2551sgio2 2002-12-14 23:18:46.000000000 +1100
@@ -40,6 +40,11 @@
#define BLK_DEFAULT_TIMEOUT (60 * HZ)
+/* defined in ../scsi/scsi.h ... should it be included? */
+#ifndef SCSI_SENSE_BUFFERSIZE
+#define SCSI_SENSE_BUFFERSIZE 64
+#endif
+
int blk_do_rq(request_queue_t *q, struct block_device *bdev, struct request *rq)
{
DECLARE_COMPLETION(wait);
@@ -126,11 +131,11 @@
struct sg_io_hdr *uptr)
{
unsigned long uaddr, start_time;
- int err, reading, writing, nr_sectors;
+ int reading, writing, nr_sectors;
struct sg_io_hdr hdr;
struct request *rq;
struct bio *bio;
- char sense[24];
+ char sense[SCSI_SENSE_BUFFERSIZE];
void *buffer;
if (!access_ok(VERIFY_WRITE, uptr, sizeof(*uptr)))
@@ -265,26 +270,36 @@
start_time = jiffies;
- /*
- * return -EIO if we didn't transfer all data, caller can look at
- * residual count to find out how much did succeed
+ /* ignore return value. All information is passed back to caller
+ * (if he doesn't check that is his problem).
+ * N.B. a non-zero SCSI status is _not_ necessarily an error.
*/
- err = blk_do_rq(q, bdev, rq);
- if (rq->data_len > 0)
- err = -EIO;
+ blk_do_rq(q, bdev, rq);
if (bio) {
bio_unmap_user(bio, reading);
bio_put(bio);
}
- hdr.status = rq->errors;
+ /* write to all output members */
+ hdr.status = rq->errors;
+ hdr.masked_status = (hdr.status >> 1) & 0x1f;
+ hdr.msg_status = 0;
+ hdr.host_status = 0;
+ hdr.driver_status = 0;
+ hdr.info = 0;
+ if (hdr.masked_status || hdr.host_status || hdr.driver_status)
+ hdr.info |= SG_INFO_CHECK;
hdr.resid = rq->data_len;
hdr.duration = (jiffies - start_time) * (1000 / HZ);
+ hdr.sb_len_wr = 0;
if (rq->sense_len && hdr.sbp) {
- if (!copy_to_user(hdr.sbp,rq->sense, rq->sense_len))
- hdr.sb_len_wr = rq->sense_len;
+ int len = (hdr.mx_sb_len < rq->sense_len) ?
+ hdr.mx_sb_len : rq->sense_len;
+
+ if (!copy_to_user(hdr.sbp, rq->sense, len))
+ hdr.sb_len_wr = len;
}
blk_put_request(rq);
@@ -297,8 +312,9 @@
kfree(buffer);
}
-
- return err;
+ /* may not have succeeded, but output values written to control
+ * structure (struct sg_io_hdr). */
+ return 0;
}
#define FORMAT_UNIT_TIMEOUT (2 * 60 * 60 * HZ)
--- linux/drivers/scsi/scsi_lib.c 2002-12-10 17:38:29.000000000 +1100
+++ linux/drivers/scsi/scsi_lib.c2551sgio 2002-12-14 23:08:25.000000000 +1100
@@ -495,6 +495,7 @@
int this_count = SCpnt->bufflen >> 9;
request_queue_t *q = SCpnt->device->request_queue;
struct request *req = SCpnt->request;
+ int clear_errors = 1;
/*
* We must do one of several things here:
@@ -528,10 +529,22 @@
kfree(SCpnt->buffer);
}
- if (blk_pc_request(req)) {
- req->errors = result & 0xff;
- if (!result)
+ if (blk_pc_request(req)) { /* SG_IO ioctl from block level */
+ req->errors = (driver_byte(result) & DRIVER_SENSE) ?
+ (CHECK_CONDITION << 1) : (result & 0xff);
+ if (!result)
req->data_len -= SCpnt->bufflen;
+ else {
+ clear_errors = 0;
+ if (SCpnt->sense_buffer[0] & 0x70) {
+ int len = 8 + SCpnt->sense_buffer[7];
+
+ if (len > SCSI_SENSE_BUFFERSIZE)
+ len = SCSI_SENSE_BUFFERSIZE;
+ memcpy(req->sense, SCpnt->sense_buffer, len);
+ req->sense_len = len;
+ }
+ }
}
/*
@@ -552,7 +565,8 @@
req->nr_sectors, good_sectors));
SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n ", SCpnt->use_sg));
- req->errors = 0;
+ if (clear_errors)
+ req->errors = 0;
/*
* If multiple sectors are requested in one buffer, then
* they will have been finished off by the first command.
next reply other threads:[~2003-01-10 11:37 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-01-10 11:37 Douglas Gilbert [this message]
2003-01-10 13:06 ` [PATCH] SG_IO ioctl in block layer against lk 2.5.55 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=3E1EB08D.5060105@torque.net \
--to=dougg@torque.net \
--cc=axboe@suse.de \
--cc=linux-scsi@vger.kernel.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