Hi,

Here's a patch against 2.4.19-pre2 that updates the USB hpusbscsi driver
to the latest version.  It contains the following changes:
        - check for error in scsi unregistering
        - special casing of request_sense
        - scsi reset removed
        - cancellation fixed
        - usb and scsi error reporting fixed
This patch was done by Oliver Neukum.

thanks,

greg k-h



diff -Nru a/drivers/usb/hpusbscsi.c b/drivers/usb/hpusbscsi.c
--- a/drivers/usb/hpusbscsi.c   Mon Mar  4 08:48:59 2002
+++ b/drivers/usb/hpusbscsi.c   Mon Mar  4 08:48:59 2002
@@ -185,7 +185,8 @@
                tmp = tmp->next;
                o = (struct hpusbscsi *)old;
                usb_unlink_urb(&o->controlurb);
-               scsi_unregister_module(MODULE_SCSI_HA,&o->ctempl);
+               if(scsi_unregister_module(MODULE_SCSI_HA,&o->ctempl)<0)
+                       printk(KERN_CRIT"Deregistering failed!\n");
                kfree(old);
        }
 
@@ -270,7 +271,13 @@
        /* Now we need to decide which callback to give to the urb we send the command 
with */
 
        if (!srb->bufflen) {
-               usb_callback = simple_command_callback;
+               if (srb->cmnd[0] == REQUEST_SENSE){
+                       /* the usual buffer is not used, needs a special case */
+                       hpusbscsi->current_data_pipe = usb_rcvbulkpipe(hpusbscsi->dev, 
+hpusbscsi->ep_in);
+                       usb_callback = request_sense_callback;
+               } else {
+                       usb_callback = simple_command_callback;
+               }
        } else {
                if (srb->use_sg) {
                        usb_callback = scatter_gather_callback;
@@ -332,8 +339,8 @@
        struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
 
        printk(KERN_DEBUG"SCSI reset requested.\n");
-       usb_reset_device(hpusbscsi->dev);
-       printk(KERN_DEBUG"SCSI reset completed.\n");
+       //usb_reset_device(hpusbscsi->dev);
+       //printk(KERN_DEBUG"SCSI reset completed.\n");
        hpusbscsi->state = HP_STATE_FREE;
 
        return 0;
@@ -342,10 +349,9 @@
 static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb)
 {
        struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
-       printk(KERN_DEBUG"Requested is canceled.\n");
+       printk(KERN_DEBUG"Request is canceled.\n");
 
        usb_unlink_urb(&hpusbscsi->dataurb);
-       usb_unlink_urb(&hpusbscsi->controlurb);
        hpusbscsi->state = HP_STATE_FREE;
 
        return SCSI_ABORT_PENDING;
@@ -373,7 +379,7 @@
                return;
        }
        hpusbscsi->srb->result &= SCSI_ERR_MASK;
-       hpusbscsi->srb->result |= hpusbscsi->scsi_state_byte<<1;
+       hpusbscsi->srb->result |= hpusbscsi->scsi_state_byte;
 
        if (hpusbscsi->scallback != NULL && hpusbscsi->state == HP_STATE_WAIT)
                /* we do a callback to the scsi layer if and only if all data has been 
transfered */
@@ -453,7 +459,7 @@
 
         res = usb_submit_urb(u);
         if (res)
-                hpusbscsi->state = HP_STATE_ERROR;
+               handle_usb_error(hpusbscsi);
        TRACE_STATE;
 }
 
@@ -469,7 +475,7 @@
        TRACE_STATE;
        if (hpusbscsi->state != HP_STATE_PREMATURE) {
                if (u->status < 0)
-                       hpusbscsi->state = HP_STATE_ERROR;
+                       handle_usb_error(hpusbscsi);
                else
                        hpusbscsi->state = HP_STATE_WAIT;
                TRACE_STATE;
@@ -509,11 +515,34 @@
        if (hpusbscsi->state != HP_STATE_PREMATURE) {
                hpusbscsi->state = HP_STATE_WORKING;
        TRACE_STATE;
-       } else {
-               if (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)) {
+               handle_usb_error(hpusbscsi);
+               return;
+       }
+       if (hpusbscsi->state != HP_STATE_PREMATURE)
+               hpusbscsi->state = HP_STATE_WORKING;
+}
+
 
diff -Nru a/drivers/usb/hpusbscsi.h b/drivers/usb/hpusbscsi.h
--- a/drivers/usb/hpusbscsi.h   Mon Mar  4 08:48:59 2002
+++ b/drivers/usb/hpusbscsi.h   Mon Mar  4 08:48:59 2002
@@ -51,7 +51,8 @@
 static void simple_command_callback(struct urb *u);
 static void scatter_gather_callback(struct urb *u);
 static void simple_payload_callback (struct urb *u);
-static void  control_interrupt_callback (struct urb *u);
+static void control_interrupt_callback (struct urb *u);
+static void request_sense_callback (struct urb *u);
 static void simple_done (struct urb *u);
 static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback);
 static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb);


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

Reply via email to