<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">From: Greg KH &lt;greg@kroah.com&gt;
To: marcelo@conectiva.com.br
Cc: linux-usb-devel@lists.sourceforge.net
Subject: [PATCH 06 of 14] USB hpusbscsi driver update

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-&gt;next;
 		o = (struct hpusbscsi *)old;
 		usb_unlink_urb(&amp;o-&gt;controlurb);
-		scsi_unregister_module(MODULE_SCSI_HA,&amp;o-&gt;ctempl);
+		if(scsi_unregister_module(MODULE_SCSI_HA,&amp;o-&gt;ctempl)&lt;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-&gt;bufflen) {
-		usb_callback = simple_command_callback;
+		if (srb-&gt;cmnd[0] == REQUEST_SENSE){
+			/* the usual buffer is not used, needs a special case */
+			hpusbscsi-&gt;current_data_pipe = usb_rcvbulkpipe(hpusbscsi-&gt;dev, hpusbscsi-&gt;ep_in);
+			usb_callback = request_sense_callback;
+		} else {
+			usb_callback = simple_command_callback;
+		}
 	} else {
         	if (srb-&gt;use_sg) {
 			usb_callback = scatter_gather_callback;
@@ -332,8 +339,8 @@
 	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb-&gt;host-&gt;hostdata[0]);
 
 	printk(KERN_DEBUG"SCSI reset requested.\n");
-	usb_reset_device(hpusbscsi-&gt;dev);
-	printk(KERN_DEBUG"SCSI reset completed.\n");
+	//usb_reset_device(hpusbscsi-&gt;dev);
+	//printk(KERN_DEBUG"SCSI reset completed.\n");
 	hpusbscsi-&gt;state = HP_STATE_FREE;
 
 	return 0;
@@ -342,10 +349,9 @@
 static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb)
 {
 	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb-&gt;host-&gt;hostdata[0]);
-	printk(KERN_DEBUG"Requested is canceled.\n");
+	printk(KERN_DEBUG"Request is canceled.\n");
 
 	usb_unlink_urb(&amp;hpusbscsi-&gt;dataurb);
-	usb_unlink_urb(&amp;hpusbscsi-&gt;controlurb);
 	hpusbscsi-&gt;state = HP_STATE_FREE;
 
 	return SCSI_ABORT_PENDING;
@@ -373,7 +379,7 @@
 		return;
 	}
 	hpusbscsi-&gt;srb-&gt;result &amp;= SCSI_ERR_MASK;
-	hpusbscsi-&gt;srb-&gt;result |= hpusbscsi-&gt;scsi_state_byte&lt;&lt;1;
+	hpusbscsi-&gt;srb-&gt;result |= hpusbscsi-&gt;scsi_state_byte;
 
 	if (hpusbscsi-&gt;scallback != NULL &amp;&amp; hpusbscsi-&gt;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-&gt;state = HP_STATE_ERROR;
+        	handle_usb_error(hpusbscsi);
 	TRACE_STATE;
 }
 
@@ -469,7 +475,7 @@
 	TRACE_STATE;
 	if (hpusbscsi-&gt;state != HP_STATE_PREMATURE) {
 		if (u-&gt;status &lt; 0)
-			hpusbscsi-&gt;state = HP_STATE_ERROR;
+			handle_usb_error(hpusbscsi);
 		else
 			hpusbscsi-&gt;state = HP_STATE_WAIT;
 		TRACE_STATE;
@@ -509,11 +515,34 @@
 	if (hpusbscsi-&gt;state != HP_STATE_PREMATURE) {
 		hpusbscsi-&gt;state = HP_STATE_WORKING;
 	TRACE_STATE;
-	} else {
-		if (hpusbscsi-&gt;scallback != NULL)
-			hpusbscsi-&gt;scallback(hpusbscsi-&gt;srb);
-		hpusbscsi-&gt;state = HP_STATE_FREE;
-	TRACE_STATE;
 	}
 }
+
+static void request_sense_callback (struct urb *u)
+{
+	struct hpusbscsi * hpusbscsi = (struct hpusbscsi *)u-&gt;context;
+
+	if (u-&gt;status&lt;0) {
+                handle_usb_error(hpusbscsi);
+		return;
+        }
+
+	FILL_BULK_URB(
+		u,
+		hpusbscsi-&gt;dev,
+		hpusbscsi-&gt;current_data_pipe,
+		hpusbscsi-&gt;srb-&gt;sense_buffer,
+		SCSI_SENSE_BUFFERSIZE,
+		simple_done,
+		hpusbscsi
+	);
+
+	if (0 &gt; usb_submit_urb(u)) {
+		handle_usb_error(hpusbscsi);
+		return;
+	}
+	if (hpusbscsi-&gt;state != HP_STATE_PREMATURE)
+		hpusbscsi-&gt;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);

</pre></body></html>