On Sun, Oct 17, 1999 at 10:54:04PM -0400, Douglas Gilbert wrote:
> >     Is there a way to send SCSI commands of length 16 bytes? Or which
> > version of SG driver is applicable ?
> 
> Warren,
> The simple answer is no. Getting sg to accept 16 byte commands
> ...
> Do you have a work-around for 16 byte SCSI commands?

Here is a patch the GFS group has had for a while that fixes the SCSI midlayer
to deal with 16-byte CDBs.  As for the lowlevel drivers, I've tested the
qlogicfc and aic7xxx drivers with 16-byte CDBs and they work.  I don't know
about any of the others.


(The patch is against 2.2.11.)

--CUT-HERE--
diff -urN linux/drivers/scsi/constants.c linux-GFS/drivers/scsi/constants.c
--- linux/drivers/scsi/constants.c      Tue Aug 10 03:10:52 1999
+++ linux-GFS/drivers/scsi/constants.c  Tue Aug 10 03:17:49 1999
@@ -74,6 +74,14 @@
 };
 
 
+static const char *group_4_commands[] = {
+/* 80-87 */ unknown, unknown, unknown, "Dlock", unknown, unknown, unknown, unknown,
+/* 88-8F */ unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown,
+/* 90-97 */ unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown,
+/* 98-9F */ unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown,
+};
+
+
 /* The following are 12 byte commands in group 5 */
 static const char *group_5_commands[] = {
 /* a0-a5 */ unknown, unknown, unknown, unknown, unknown,
@@ -89,7 +97,6 @@
 };
 
 
-
 #define group(opcode) (((opcode) >> 5) & 7)
 
 #define RESERVED_GROUP  0
@@ -97,7 +104,7 @@
 
 static const char **commands[] = {
     group_0_commands, group_1_commands, group_2_commands, 
-    (const char **) RESERVED_GROUP, (const char **) RESERVED_GROUP, 
+    (const char **) RESERVED_GROUP, group_4_commands, 
     group_5_commands, (const char **) VENDOR_GROUP, 
     (const char **) VENDOR_GROUP
 };
diff -urN linux/drivers/scsi/scsi.c linux-GFS/drivers/scsi/scsi.c
--- linux/drivers/scsi/scsi.c   Tue Aug 10 03:10:52 1999
+++ linux-GFS/drivers/scsi/scsi.c       Tue Aug 10 03:16:33 1999
@@ -118,9 +118,9 @@
  */
 unsigned long             scsi_pid = 0;
 Scsi_Cmnd               * last_cmnd = NULL;
-/* Command groups 3 and 4 are reserved and should never be used.  */
+/* Command group 3 is reserved and should never be used.  */
 const unsigned char       scsi_command_size[8] = { 6, 10, 10, 12, 
-                                                   12, 12, 10, 10 };
+                                                   16, 12, 10, 10 };
 static unsigned long      serial_number = 0;
 static Scsi_Cmnd        * scsi_bh_queue_head = NULL;
 static Scsi_Cmnd       * scsi_bh_queue_tail = NULL;
@@ -1465,12 +1465,13 @@
     {
        int i;
        int target = SCpnt->target;
+        int size = COMMAND_SIZE(((const unsigned char *)cmnd)[0]);
        printk ("scsi_do_cmd (host = %d, channel = %d target = %d, "
                "buffer =%p, bufflen = %d, done = %p, timeout = %d, "
                "retries = %d)\n"
                "command : " , host->host_no, SCpnt->channel, target, buffer,
                bufflen, done, timeout, retries);
-       for (i = 0; i < 10; ++i)
+       for (i = 0; i < size; ++i)
            printk ("%02x  ", ((unsigned char *) cmnd)[i]);
        printk("\n");
     });
@@ -1513,7 +1514,10 @@
      * the completion function for the high level driver.
      */
 
-    memcpy ((void *) SCpnt->data_cmnd , (const void *) cmnd, 12);
+    if (SCpnt->cmd_len == 0)
+       SCpnt->cmd_len = COMMAND_SIZE(((const unsigned char *)cmnd)[0]);
+
+    memcpy ((void *) SCpnt->data_cmnd , (const void *) cmnd, SCpnt->cmd_len);
     SCpnt->reset_chain = NULL;
     SCpnt->serial_number = 0;
     SCpnt->serial_number_at_timeout = 0;
@@ -1525,7 +1529,7 @@
     SCpnt->done = done;
     SCpnt->timeout_per_command = timeout;
 
-    memcpy ((void *) SCpnt->cmnd , (const void *) cmnd, 12);
+    memcpy ((void *) SCpnt->cmnd , (const void *) cmnd, SCpnt->cmd_len);
     /* Zero the sense buffer.  Some host adapters automatically request
      * sense on error.  0 is not a valid sense code.
      */
@@ -1533,8 +1537,6 @@
     SCpnt->request_buffer = buffer;
     SCpnt->request_bufflen = bufflen;
     SCpnt->old_use_sg = SCpnt->use_sg;
-    if (SCpnt->cmd_len == 0)
-       SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
     SCpnt->old_cmd_len = SCpnt->cmd_len;
 
     /* Start the timer ticking.  */
diff -urN linux/drivers/scsi/scsi.h linux-GFS/drivers/scsi/scsi.h
--- linux/drivers/scsi/scsi.h   Tue Aug 10 03:10:52 1999
+++ linux-GFS/drivers/scsi/scsi.h       Tue Aug 10 03:16:33 1999
@@ -286,7 +286,7 @@
 #define DRIVER_MASK         0x0f
 #define SUGGEST_MASK        0xf0
 
-#define MAX_COMMAND_SIZE    12
+#define MAX_COMMAND_SIZE    16
 
 /*
  *  SCSI command sets
@@ -547,14 +547,14 @@
     unsigned char      old_cmd_len;
 
     /* These elements define the operation we are about to perform */
-    unsigned char      cmnd[12];
+    unsigned char      cmnd[MAX_COMMAND_SIZE];
     unsigned           request_bufflen;        /* Actual request size */
     
     struct timer_list  eh_timeout;         /* Used to time out the command. */
     void             * request_buffer; /* Actual requested buffer */
     
     /* These elements define the operation we ultimately want to perform */
-    unsigned char      data_cmnd[12];
+    unsigned char      data_cmnd[MAX_COMMAND_SIZE];
     unsigned short     old_use_sg;     /* We save  use_sg here when requesting
                                          * sense info */
     unsigned short     use_sg;          /* Number of pieces of scatter-gather */



-- 
Ken Preslan <[EMAIL PROTECTED]>


-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]

Reply via email to