Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 7958
b: refs/heads/master
c: 77f4632
h: refs/heads/master
v: v3
  • Loading branch information
Matthew Dharm authored and Greg Kroah-Hartman committed Sep 8, 2005
1 parent b66e508 commit 0521dde
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 28 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0f64e078139109d1902e5b1274c23cec9a9ad12e
refs/heads/master: 77f46328fb83b64befd889ebce6d7fb959932509
62 changes: 35 additions & 27 deletions trunk/drivers/usb/storage/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,7 @@ static void usb_stor_release_resources(struct us_data *us)
* any more commands.
*/
US_DEBUGP("-- sending exit command to thread\n");
set_bit(US_FLIDX_DISCONNECTING, &us->flags);
up(&us->sema);

/* Call the destructor routine, if it exists */
Expand Down Expand Up @@ -816,6 +817,36 @@ static void dissociate_dev(struct us_data *us)
usb_set_intfdata(us->pusb_intf, NULL);
}

/* First stage of disconnect processing: stop all commands and remove
* the host */
static void quiesce_and_remove_host(struct us_data *us)
{
/* Prevent new USB transfers, stop the current command, and
* interrupt a SCSI-scan or device-reset delay */
set_bit(US_FLIDX_DISCONNECTING, &us->flags);
usb_stor_stop_transport(us);
wake_up(&us->delay_wait);

/* It doesn't matter if the SCSI-scanning thread is still running.
* The thread will exit when it sees the DISCONNECTING flag. */

/* Wait for the current command to finish, then remove the host */
down(&us->dev_semaphore);
up(&us->dev_semaphore);
scsi_remove_host(us_to_host(us));
}

/* Second stage of disconnect processing: deallocate all resources */
static void release_everything(struct us_data *us)
{
usb_stor_release_resources(us);
dissociate_dev(us);

/* Drop our reference to the host; the SCSI core will free it
* (and "us" along with it) when the refcount becomes 0. */
scsi_host_put(us_to_host(us));
}

/* Thread to carry out delayed SCSI-device scanning */
static int usb_stor_scan_thread(void * __us)
{
Expand Down Expand Up @@ -956,7 +987,7 @@ static int storage_probe(struct usb_interface *intf,
if (result < 0) {
printk(KERN_WARNING USB_STORAGE
"Unable to start the device-scanning thread\n");
scsi_remove_host(host);
quiesce_and_remove_host(us);
goto BadDevice;
}
atomic_inc(&total_threads);
Expand All @@ -969,10 +1000,7 @@ static int storage_probe(struct usb_interface *intf,
/* We come here if there are any problems */
BadDevice:
US_DEBUGP("storage_probe() failed\n");
set_bit(US_FLIDX_DISCONNECTING, &us->flags);
usb_stor_release_resources(us);
dissociate_dev(us);
scsi_host_put(host);
release_everything(us);
return result;
}

Expand All @@ -982,28 +1010,8 @@ static void storage_disconnect(struct usb_interface *intf)
struct us_data *us = usb_get_intfdata(intf);

US_DEBUGP("storage_disconnect() called\n");

/* Prevent new USB transfers, stop the current command, and
* interrupt a SCSI-scan or device-reset delay */
set_bit(US_FLIDX_DISCONNECTING, &us->flags);
usb_stor_stop_transport(us);
wake_up(&us->delay_wait);

/* It doesn't matter if the SCSI-scanning thread is still running.
* The thread will exit when it sees the DISCONNECTING flag. */

/* Wait for the current command to finish, then remove the host */
down(&us->dev_semaphore);
up(&us->dev_semaphore);
scsi_remove_host(us_to_host(us));

/* Wait for everything to become idle and release all our resources */
usb_stor_release_resources(us);
dissociate_dev(us);

/* Drop our reference to the host; the SCSI core will free it
* (and "us" along with it) when the refcount becomes 0. */
scsi_host_put(us_to_host(us));
quiesce_and_remove_host(us);
release_everything(us);
}

/***********************************************************************
Expand Down

0 comments on commit 0521dde

Please sign in to comment.