patch-2.4.21 linux-2.4.21/drivers/usb/hpusbscsi.c

Next file: linux-2.4.21/drivers/usb/hpusbscsi.h
Previous file: linux-2.4.21/drivers/usb/host/usb-uhci.h
Back to the patch index
Back to the overall index

diff -urN linux-2.4.20/drivers/usb/hpusbscsi.c linux-2.4.21/drivers/usb/hpusbscsi.c
@@ -71,7 +71,7 @@
 
 #ifdef HPUSBSCSI_DEBUG
 #  define PDEBUG(level, fmt, args...) \
-          if (debug >= (level)) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , \
+          if (debug >= (level)) info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ , \
                  ## args)
 #else
 #  define PDEBUG(level, fmt, args...) do {} while(0)
@@ -125,7 +125,11 @@
 	new->dev = dev;
 	init_waitqueue_head (&new->pending);
 	init_waitqueue_head (&new->deathrow);
+	init_MUTEX(&new->lock);
 	INIT_LIST_HEAD (&new->lh);
+	
+	if (id->idVendor == 0x0686 && id->idProduct == 0x4004)
+		new->need_short_workaround = 1;
 
 
 
@@ -202,12 +206,12 @@
 {
 	struct hpusbscsi *hp = (struct hpusbscsi *)ptr;
 
+	down(&hp->lock);
 	usb_unlink_urb(&hp->controlurb);
 	usb_unlink_urb(&hp->dataurb);
 
-	spin_lock_irq(&io_request_lock);
 	hp->dev = NULL;
-	spin_unlock_irq(&io_request_lock);
+	up(&hp->lock);
 }
 
 static struct usb_device_id hpusbscsi_usb_ids[] = {
@@ -339,7 +343,7 @@
 {
 	struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]);
 	usb_urb_callback usb_callback;
-	int res;
+	int res, passed_length;
 
 	spin_unlock_irq(&io_request_lock);
 
@@ -347,8 +351,30 @@
 	if ( srb->device->lun || srb->device->id || srb->device->channel ) {
 		srb->result = DID_BAD_TARGET;
 		callback(srb);
+		goto out_nolock;
+	}
+
+	/* to prevent a race with removal */
+	down(&hpusbscsi->lock);
+
+	if (hpusbscsi->dev == NULL) {
+		srb->result = DID_ERROR;
+		callback(srb);
 		goto out;
 	}
+	
+	/* otto fix - the Scan Elite II has a 5 second
+	* delay anytime the srb->cmd_len=6
+	* This causes it to run very slowly unless we
+	* pad the command length to 10 */
+        
+	if (hpusbscsi -> need_short_workaround && srb->cmd_len < 10) {
+		memset(srb->cmnd + srb->cmd_len, 0, 10 - srb->cmd_len);
+		passed_length = 10;
+	} else {
+		passed_length = srb->cmd_len;
+	}
+        
 
 	/* Now we need to decide which callback to give to the urb we send the command with */
 
@@ -394,18 +420,13 @@
 		hpusbscsi->dev,
 		usb_sndbulkpipe(hpusbscsi->dev,hpusbscsi->ep_out),
 		srb->cmnd,
-		srb->cmd_len,
+		passed_length,
 		usb_callback,
 		hpusbscsi
 	);
 	hpusbscsi->scallback = callback;
 	hpusbscsi->srb = srb;
-	
-	if (hpusbscsi->dev == NULL) {
-		srb->result = DID_ERROR;
-		callback(srb);
-		goto out;
-	}
+
 
 	res = usb_submit_urb(&hpusbscsi->dataurb);
 	if (res) {
@@ -417,6 +438,8 @@
 	}
 
 out:
+	up(&hpusbscsi->lock);
+out_nolock:
 	spin_lock_irq(&io_request_lock);
 	return 0;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)