patch-2.4.21 linux-2.4.21/drivers/usb/storage/scsiglue.c
Next file: linux-2.4.21/drivers/usb/storage/sddr09.c
Previous file: linux-2.4.21/drivers/usb/storage/jumpshot.c
Back to the patch index
Back to the overall index
- Lines: 89
- Date:
2003-06-13 07:51:37.000000000 -0700
- Orig file:
linux-2.4.20/drivers/usb/storage/scsiglue.c
- Orig date:
2002-11-28 15:53:15.000000000 -0800
diff -urN linux-2.4.20/drivers/usb/storage/scsiglue.c linux-2.4.21/drivers/usb/storage/scsiglue.c
@@ -75,15 +75,15 @@
{
struct us_data *us;
char local_name[32];
-
+ /* Note: this function gets called with io_request_lock spinlock helt! */
/* This is not nice at all, but how else are we to get the
* data here? */
us = (struct us_data *)sht->proc_dir;
/* set up the name of our subdirectory under /proc/scsi/ */
sprintf(local_name, "usb-storage-%d", us->host_number);
- sht->proc_name = kmalloc (strlen(local_name) + 1, GFP_KERNEL);
- if (!sht->proc_name)
+ sht->proc_name = kmalloc (strlen(local_name) + 1, GFP_ATOMIC);
+ if (!sht->proc_name)
return 0;
strcpy(sht->proc_name, local_name);
@@ -145,12 +145,13 @@
static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
{
struct us_data *us = (struct us_data *)srb->host->hostdata[0];
+ unsigned long flags;
US_DEBUGP("queuecommand() called\n");
srb->host_scribble = (unsigned char *)us;
/* get exclusive access to the structures we want */
- down(&(us->queue_exclusion));
+ spin_lock_irqsave(&(us->queue_exclusion), flags);
/* enqueue the command */
us->queue_srb = srb;
@@ -158,7 +159,7 @@
us->action = US_ACT_COMMAND;
/* release the lock on the structure */
- up(&(us->queue_exclusion));
+ spin_unlock_irqrestore(&(us->queue_exclusion), flags);
/* wake up the process task */
up(&(us->sema));
@@ -191,11 +192,15 @@
/* if we have an urb pending, let's wake the control thread up */
if (!us->current_done.done) {
+ atomic_inc(&us->abortcnt);
+ spin_unlock_irq(&io_request_lock);
/* cancel the URB -- this will automatically wake the thread */
usb_unlink_urb(us->current_urb);
/* wait for us to be done */
wait_for_completion(&(us->notify));
+ spin_lock_irq(&io_request_lock);
+ atomic_dec(&us->abortcnt);
return SUCCESS;
}
@@ -231,6 +236,8 @@
return SUCCESS;
}
+ spin_unlock_irq(&io_request_lock);
+
/* release the IRQ, if we have one */
down(&(us->irq_urb_sem));
if (us->irq_urb) {
@@ -241,8 +248,10 @@
up(&(us->irq_urb_sem));
/* attempt to reset the port */
- if (usb_reset_device(us->pusb_dev) < 0)
+ if (usb_reset_device(us->pusb_dev) < 0) {
+ spin_lock_irq(&io_request_lock);
return FAILED;
+ }
/* FIXME: This needs to lock out driver probing while it's working
* or we can have race conditions */
@@ -282,6 +291,8 @@
US_DEBUGP("usb_submit_urb() returns %d\n", result);
up(&(us->irq_urb_sem));
}
+
+ spin_lock_irq(&io_request_lock);
US_DEBUGP("bus_reset() complete\n");
return SUCCESS;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)