# 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.688 -> 1.689 # drivers/usb/hpusbscsi.c 1.8 -> 1.9 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/09/26 oliver@neukum.name 1.689 # [PATCH] USB: update of hpusbscsi # # this fixes an unplugging problem and an SMP deadlock. # -------------------------------------------- # diff -Nru a/drivers/usb/hpusbscsi.c b/drivers/usb/hpusbscsi.c --- a/drivers/usb/hpusbscsi.c Mon Sep 30 10:47:06 2002 +++ b/drivers/usb/hpusbscsi.c Mon Sep 30 10:47:06 2002 @@ -200,8 +200,14 @@ static void hpusbscsi_usb_disconnect (struct usb_device *dev, void *ptr) { - usb_unlink_urb(&(((struct hpusbscsi *) ptr)->controlurb)); - ((struct hpusbscsi *) ptr)->dev = NULL; + struct hpusbscsi *hp = (struct hpusbscsi *)ptr; + + 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); } static struct usb_device_id hpusbscsi_usb_ids[] = { @@ -335,15 +341,13 @@ usb_urb_callback usb_callback; int res; - hpusbscsi->use_count++; + spin_unlock_irq(&io_request_lock); /* we don't answer for anything but our single device on any faked host controller */ if ( srb->device->lun || srb->device->id || srb->device->channel ) { - if (callback) { - srb->result = DID_BAD_TARGET; - callback(srb); - } - goto out; + srb->result = DID_BAD_TARGET; + callback(srb); + goto out; } /* Now we need to decide which callback to give to the urb we send the command with */ @@ -407,14 +411,13 @@ if (res) { hpusbscsi->state = HP_STATE_FREE; PDEBUG(2, "state= %s", states[hpusbscsi->state]); - if (callback) { - srb->result = DID_ERROR; - callback(srb); - } + srb->result = DID_ERROR; + callback(srb); + } out: - hpusbscsi->use_count--; + spin_lock_irq(&io_request_lock); return 0; } @@ -438,7 +441,7 @@ spin_unlock_irq(&io_request_lock); usb_unlink_urb(&hpusbscsi->dataurb); hpusbscsi->state = HP_STATE_FREE; - + spin_lock_irq(&io_request_lock); return SCSI_ABORT_PENDING;