ChangeSet 1.783, 2002/12/05 14:20:31-08:00, oliver@oenone.homelinux.org [PATCH] - use of unplugged scanner oops fix diff -Nru a/drivers/usb/hpusbscsi.c b/drivers/usb/hpusbscsi.c --- a/drivers/usb/hpusbscsi.c Thu Dec 5 14:48:41 2002 +++ b/drivers/usb/hpusbscsi.c Thu Dec 5 14:48:41 2002 @@ -125,6 +125,7 @@ new->dev = dev; init_waitqueue_head (&new->pending); init_waitqueue_head (&new->deathrow); + init_MUTEX(&new->lock); INIT_LIST_HEAD (&new->lh); @@ -202,12 +203,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[] = { @@ -347,6 +348,15 @@ 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; } @@ -400,12 +410,7 @@ ); 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 +422,8 @@ } out: + up(&hpusbscsi->lock); +out_nolock: spin_lock_irq(&io_request_lock); return 0; } diff -Nru a/drivers/usb/hpusbscsi.h b/drivers/usb/hpusbscsi.h --- a/drivers/usb/hpusbscsi.h Thu Dec 5 14:48:41 2002 +++ b/drivers/usb/hpusbscsi.h Thu Dec 5 14:48:41 2002 @@ -29,6 +29,7 @@ u8 sense_command[SENSE_COMMAND_SIZE]; int use_count; + struct semaphore lock; wait_queue_head_t pending; wait_queue_head_t deathrow;