# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#                  ChangeSet    1.551   -> 1.552  
#       drivers/usb/hpusbscsi.h 1.4     -> 1.5    
#       drivers/usb/hpusbscsi.c 1.9     -> 1.10   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/03/19      [EMAIL PROTECTED]     1.552
# USB hpusbscsi driver
# 
# Port changes from 2.4:
#   We do request_sense ourselves to comply with
#   the scanner command set
# --------------------------------------------
#
diff -Nru a/drivers/usb/hpusbscsi.c b/drivers/usb/hpusbscsi.c
--- a/drivers/usb/hpusbscsi.c   Wed Apr  3 16:39:56 2002
+++ b/drivers/usb/hpusbscsi.c   Wed Apr  3 16:39:56 2002
@@ -129,6 +129,9 @@
        if (scsi_register_host(&new->ctempl))
                goto err_out;
 
+       new->sense_command[0] = REQUEST_SENSE;
+       new->sense_command[4] = HPUSBSCSI_SENSE_LENGTH;
+
        /* adding to list for module unload */
        list_add (&hpusbscsi_devices, &new->lh);
 
@@ -379,6 +382,7 @@
 static void  control_interrupt_callback (struct urb *u)
 {
        struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
+       u8 scsi_state;
 
 DEBUG("Getting status byte %d \n",hpusbscsi->scsi_state_byte);
        if(unlikely(u->status < 0)) {
@@ -386,10 +390,23 @@
                         handle_usb_error(hpusbscsi);
                return;
        }
-       hpusbscsi->srb->result &= SCSI_ERR_MASK;
-       hpusbscsi->srb->result |= hpusbscsi->scsi_state_byte;
 
-       if (hpusbscsi->scallback != NULL && hpusbscsi->state == HP_STATE_WAIT)
+       scsi_state = hpusbscsi->scsi_state_byte;
+       if (hpusbscsi->state != HP_STATE_ERROR) {
+               hpusbscsi->srb->result &= SCSI_ERR_MASK;
+               hpusbscsi->srb->result |= scsi_state;
+       }
+
+       if (scsi_state == CHECK_CONDITION << 1) {
+               if (hpusbscsi->state == HP_STATE_WAIT) {
+                       issue_request_sense(hpusbscsi);
+               } else {
+                       /* we request sense after an eventual data transfer */
+                       hpusbscsi->state = HP_STATE_ERROR;
+               }
+       }
+
+       if (hpusbscsi->scallback != NULL && hpusbscsi->state == HP_STATE_WAIT && 
+scsi_state != CHECK_CONDITION <<1 )
                /* we do a callback to the scsi layer if and only if all data has been 
transfered */
                hpusbscsi->scallback(hpusbscsi->srb);
 
@@ -404,6 +421,8 @@
                hpusbscsi->state = HP_STATE_PREMATURE;
        TRACE_STATE;
                break;
+       case HP_STATE_ERROR:
+               break;
        default:
                printk(KERN_ERR"hpusbscsi: Unexpected status report.\n");
        TRACE_STATE;
@@ -432,32 +451,6 @@
        }
 }
 
-static void request_sense_callback (struct urb *u)
-{
-       struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
-
-       if (unlikely(u->status<0)) {
-               handle_usb_error(hpusbscsi);
-               return;
-        }
-
-       FILL_BULK_URB(
-               u,
-               hpusbscsi->dev,
-               hpusbscsi->current_data_pipe,
-               hpusbscsi->srb->sense_buffer,
-               SCSI_SENSE_BUFFERSIZE,
-               simple_done,
-               hpusbscsi
-       );
-
-       if (unlikely(0 > usb_submit_urb(u, GFP_ATOMIC))) {
-               handle_usb_error(hpusbscsi);
-               return;
-       }
-       hpusbscsi->state = HP_STATE_WORKING;
-}
-
 static void scatter_gather_callback(struct urb *u)
 {
        struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
@@ -494,7 +487,7 @@
 
         res = usb_submit_urb(u, GFP_ATOMIC);
         if (unlikely(res))
-                hpusbscsi->state = HP_STATE_ERROR;
+                handle_usb_error(hpusbscsi);
        TRACE_STATE;
 }
 
@@ -509,11 +502,15 @@
         DEBUG("Data transfer done\n");
        TRACE_STATE;
        if (hpusbscsi->state != HP_STATE_PREMATURE) {
-               if (unlikely(u->status < 0))
-                       hpusbscsi->state = HP_STATE_ERROR;
-               else
-                       hpusbscsi->state = HP_STATE_WAIT;
-               TRACE_STATE;
+               if (unlikely(u->status < 0)) {
+                       handle_usb_error(hpusbscsi);
+               } else {
+                       if (hpusbscsi->state != HP_STATE_ERROR) {
+                               hpusbscsi->state = HP_STATE_WAIT;
+                       } else {
+                               issue_request_sense(hpusbscsi);
+                       }                       
+               }
        } else {
                if (likely(hpusbscsi->scallback != NULL))
                        hpusbscsi->scallback(hpusbscsi->srb);
@@ -550,12 +547,52 @@
        if (hpusbscsi->state != HP_STATE_PREMATURE) {
                hpusbscsi->state = HP_STATE_WORKING;
        TRACE_STATE;
-       } else {
-               if (likely(hpusbscsi->scallback != NULL))
-                       hpusbscsi->scallback(hpusbscsi->srb);
-               hpusbscsi->state = HP_STATE_FREE;
-       TRACE_STATE;
+       } 
+}
+
+static void request_sense_callback (struct urb *u)
+{
+       struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u->context;
+
+       if (u->status<0) {
+                handle_usb_error(hpusbscsi);
+               return;
+        }
+
+       FILL_BULK_URB(
+               u,
+               hpusbscsi->dev,
+               hpusbscsi->current_data_pipe,
+               hpusbscsi->srb->sense_buffer,
+               SCSI_SENSE_BUFFERSIZE,
+               simple_done,
+               hpusbscsi
+       );
+
+       if (0 > usb_submit_urb(u, GFP_ATOMIC)) {
+               handle_usb_error(hpusbscsi);
+               return;
        }
+       if (hpusbscsi->state != HP_STATE_PREMATURE && hpusbscsi->state != 
+HP_STATE_ERROR)
+               hpusbscsi->state = HP_STATE_WORKING;
 }
 
+static void issue_request_sense (struct hpusbscsi *hpusbscsi)
+{
+       FILL_BULK_URB(
+               hpusbscsi->dataurb,
+               hpusbscsi->dev,
+               usb_sndbulkpipe(hpusbscsi->dev, hpusbscsi->ep_out),
+               &hpusbscsi->sense_command,
+               SENSE_COMMAND_SIZE,
+               request_sense_callback,
+               hpusbscsi
+       );
+
+       hpusbscsi->current_data_pipe = usb_rcvbulkpipe(hpusbscsi->dev, 
+hpusbscsi->ep_in);
+
+       if (0 > usb_submit_urb(hpusbscsi->dataurb, GFP_ATOMIC)) {
+               handle_usb_error(hpusbscsi);
+       }
+}
 
diff -Nru a/drivers/usb/hpusbscsi.h b/drivers/usb/hpusbscsi.h
--- a/drivers/usb/hpusbscsi.h   Wed Apr  3 16:39:56 2002
+++ b/drivers/usb/hpusbscsi.h   Wed Apr  3 16:39:56 2002
@@ -4,9 +4,14 @@
 /* large parts based on or taken from code by John Fremlin and Matt Dharm */
 /* this file is licensed under the GPL */
 
+/* A big thanks to Jose for untiring testing */
+
 typedef void (*usb_urb_callback) (struct urb *);
 typedef void (*scsi_callback)(Scsi_Cmnd *);
 
+#define SENSE_COMMAND_SIZE 6
+#define HPUSBSCSI_SENSE_LENGTH 0x16
+
 struct hpusbscsi
 {
         struct list_head lh;
@@ -19,8 +24,9 @@
         struct Scsi_Host *host;
         Scsi_Host_Template ctempl;
         int number;
-       scsi_callback scallback;
-       Scsi_Cmnd *srb;
+       scsi_callback scallback;
+       Scsi_Cmnd *srb;
+       u8 sense_command[SENSE_COMMAND_SIZE];
 
         int use_count;
         wait_queue_head_t pending;
@@ -57,6 +63,7 @@
 static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback);
 static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb);
 static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb);
+static void issue_request_sense (struct hpusbscsi *hpusbscsi);
 
 static Scsi_Host_Template hpusbscsi_scsi_host_template = {
        name:           "hpusbscsi",
@@ -84,5 +91,6 @@
 #define HP_STATE_ERROR             3  /* error has been reported */
 #define HP_STATE_WAIT                 4  /* waiting for status transfer */
 #define HP_STATE_PREMATURE              5 /* status prematurely reported */
+
 
 

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to