Hannes Reinecke wrote:

> this patch adds the SG_IO ioctl to the cciss driver.
> As the driver is capable of sending SCSI CDBs to the controller there is
> no reason why we shouldn't exploit it.
> This way we get to use all the nice sg_utils for the cciss driver.
> And a persistent device name for free.

Christoph Hellwigg wrote:

> Instead of adding yet another implementation of SG_IO please implement
> support for REQ_TYPE_BLOCK_PC requests and add all the nice block layer
> passthrough ioctls to it. 

James Bottomley wrote:

> Actually, I happen to know that HP is in the process of implementing
> this correctly (via REQ_TYPE_BLOCK_PC).  I can't reveal the details but
> it has something to do with a well known Linux High Availability company
> needing SG_IO for sg_persist to work ... 

How about something like this:
(Since my mailer is sure to wreck the patch, it can be found intact here:
http://cciss.cvs.sourceforge.net/*checkout*/cciss/patches/kernel.org-2.6/cciss_sg_io_block_pc.patch?revision=1.1

-- steve

Add SG_IO to cciss driver.

Not completely sure all the error handling is correct.

---

 linux-2.6.21-rc6/drivers/block/cciss.c |   90 ++++++++++++++++++++-------------
 1 files changed, 56 insertions(+), 34 deletions(-)

diff -puN linux-2.6.21-rc6/drivers/block/cciss.c~cciss_sg_io_ioctl
linux-2.6.21-rc6/drivers/block/cciss.c
--- cciss_sg_io/linux-2.6.21-rc6/drivers/block/cciss.c~cciss_sg_io_ioctl        
2007-04-06
08:11:59.000000000 -0500
+++ cciss_sg_io-scameron/linux-2.6.21-rc6/drivers/block/cciss.c 2007-04-06 
11:38:40.000000000
-0500
@@ -45,7 +45,7 @@
 #include <linux/blkdev.h>
 #include <linux/genhd.h>
 #include <linux/completion.h>
-
+#include <scsi/sg.h>
 #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
 #define DRIVER_NAME "HP CISS Driver (v 3.6.14)"
 #define DRIVER_VERSION CCISS_DRIVER_VERSION(3,6,14)
@@ -1152,6 +1152,7 @@ static int cciss_ioctl(struct inode *ino
                        kfree(ioc);
                        return status;
                }
+       case SG_IO: return scsi_cmd_ioctl(filep, disk, cmd, argp);
        default:
                return -ENOTTY;
        }
@@ -2361,6 +2362,14 @@ static inline void complete_command(ctlr
                                       " byte 2 = 0x%x\n", cmd,
                                       cmd->err_info->SenseInfo[2]
                                    );
+                               if (blk_pc_request(cmd->rq)) {
+                                       if (cmd->rq->sense) {
+                                               if (cmd->rq->sense_len > 
cmd->err_info->SenseLen)
+                                                       cmd->rq->sense_len = 
cmd->err_info->SenseLen;
+                                               memcpy(cmd->rq->sense, 
cmd->err_info->SenseInfo, cmd->rq->sense_len);
+                                       } else
+                                               cmd->rq->sense_len = 0;
+                               }
                                /* check the sense key */
                                sense_key = 0xf & cmd->err_info->SenseInfo[2];
                                /* no status or recovered error */
@@ -2374,14 +2383,16 @@ static inline void complete_command(ctlr
                        }
                        break;
                case CMD_DATA_UNDERRUN:
-                       printk(KERN_WARNING "cciss: cmd %p has"
-                              " completed with data underrun "
-                              "reported\n", cmd);
+                       if (blk_fs_request(cmd->rq))
+                               printk(KERN_WARNING "cciss: cmd %p has"
+                                      " completed with data underrun "
+                                      "reported\n", cmd);
                        break;
                case CMD_DATA_OVERRUN:
-                       printk(KERN_WARNING "cciss: cmd %p has"
-                              " completed with data overrun "
-                              "reported\n", cmd);
+                       if (blk_fs_request(cmd->rq))
+                               printk(KERN_WARNING "cciss: cmd %p has"
+                                      " completed with data overrun "
+                                      "reported\n", cmd);
                        break;
                case CMD_INVALID:
                        printk(KERN_WARNING "cciss: cmd %p is "
@@ -2443,9 +2454,12 @@ static inline void complete_command(ctlr
                resend_cciss_cmd(h, cmd);
                return;
        }
-
-       cmd->rq->completion_data = cmd;
        cmd->rq->errors = status;
+       if (blk_pc_request(cmd->rq)) {
+               cmd->rq->errors |= 0xff & cmd->err_info->ScsiStatus;
+               cmd->rq->data_len = cmd->err_info->ResidualCnt;
+       }
+       cmd->rq->completion_data = cmd;
        blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE);
        blk_complete_request(cmd->rq);
 }
@@ -2539,32 +2553,40 @@ static void do_cciss_request(request_que
 #endif                         /* CCISS_DEBUG */
 
        c->Header.SGList = c->Header.SGTotal = seg;
-       if(h->cciss_read == CCISS_READ_10) {
-               c->Request.CDB[1] = 0;
-               c->Request.CDB[2] = (start_blk >> 24) & 0xff;   //MSB
-               c->Request.CDB[3] = (start_blk >> 16) & 0xff;
-               c->Request.CDB[4] = (start_blk >> 8) & 0xff;
-               c->Request.CDB[5] = start_blk & 0xff;
-               c->Request.CDB[6] = 0;  // (sect >> 24) & 0xff; MSB
-               c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff;
-               c->Request.CDB[8] = creq->nr_sectors & 0xff;
-               c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
+       if (likely(blk_fs_request(creq))) {
+               if(h->cciss_read == CCISS_READ_10) {
+                       c->Request.CDB[1] = 0;
+                       c->Request.CDB[2] = (start_blk >> 24) & 0xff;   //MSB
+                       c->Request.CDB[3] = (start_blk >> 16) & 0xff;
+                       c->Request.CDB[4] = (start_blk >> 8) & 0xff;
+                       c->Request.CDB[5] = start_blk & 0xff;
+                       c->Request.CDB[6] = 0;  // (sect >> 24) & 0xff; MSB
+                       c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff;
+                       c->Request.CDB[8] = creq->nr_sectors & 0xff;
+                       c->Request.CDB[9] = c->Request.CDB[11] = 
c->Request.CDB[12] = 0;
+               } else {
+                       c->Request.CDBLen = 16;
+                       c->Request.CDB[1]= 0;
+                       c->Request.CDB[2]= (start_blk >> 56) & 0xff;    //MSB
+                       c->Request.CDB[3]= (start_blk >> 48) & 0xff;
+                       c->Request.CDB[4]= (start_blk >> 40) & 0xff;
+                       c->Request.CDB[5]= (start_blk >> 32) & 0xff;
+                       c->Request.CDB[6]= (start_blk >> 24) & 0xff;
+                       c->Request.CDB[7]= (start_blk >> 16) & 0xff;
+                       c->Request.CDB[8]= (start_blk >>  8) & 0xff;
+                       c->Request.CDB[9]= start_blk & 0xff;
+                       c->Request.CDB[10]= (creq->nr_sectors >>  24) & 0xff;
+                       c->Request.CDB[11]= (creq->nr_sectors >>  16) & 0xff;
+                       c->Request.CDB[12]= (creq->nr_sectors >>  8) & 0xff;
+                       c->Request.CDB[13]= creq->nr_sectors & 0xff;
+                       c->Request.CDB[14] = c->Request.CDB[15] = 0;
+               }
+       } else if (blk_pc_request(creq)) {
+               c->Request.CDBLen = creq->cmd_len;
+               memcpy(c->Request.CDB, creq->cmd, BLK_MAX_CDB);
        } else {
-               c->Request.CDBLen = 16;
-               c->Request.CDB[1]= 0;
-               c->Request.CDB[2]= (start_blk >> 56) & 0xff;    //MSB
-               c->Request.CDB[3]= (start_blk >> 48) & 0xff;
-               c->Request.CDB[4]= (start_blk >> 40) & 0xff;
-               c->Request.CDB[5]= (start_blk >> 32) & 0xff;
-               c->Request.CDB[6]= (start_blk >> 24) & 0xff;
-               c->Request.CDB[7]= (start_blk >> 16) & 0xff;
-               c->Request.CDB[8]= (start_blk >>  8) & 0xff;
-               c->Request.CDB[9]= start_blk & 0xff;
-               c->Request.CDB[10]= (creq->nr_sectors >>  24) & 0xff;
-               c->Request.CDB[11]= (creq->nr_sectors >>  16) & 0xff;
-               c->Request.CDB[12]= (creq->nr_sectors >>  8) & 0xff;
-               c->Request.CDB[13]= creq->nr_sectors & 0xff;
-               c->Request.CDB[14] = c->Request.CDB[15] = 0;
+               printk(KERN_WARNING "cciss%d: bad request type %d\n", h->ctlr, 
creq->cmd_type);
+               BUG();
        }
 
        spin_lock_irq(q->queue_lock);
_



 
____________________________________________________________________________________
8:00? 8:25? 8:40? Find a flick in no time 
with the Yahoo! Search movie showtime shortcut.
http://tools.search.yahoo.com/shortcuts/#news
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to