All of lore.kernel.org
 help / color / mirror / Atom feed
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.

             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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.