* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/config.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/suspend.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/kthread.h>
-#include <linux/mutex.h>
-#include <linux/utsrelease.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
struct us_data *us = usb_get_intfdata(iface);
/* Wait until no command is running */
- mutex_lock(&us->dev_mutex);
+ down(&us->dev_semaphore);
US_DEBUGP("%s\n", __FUNCTION__);
if (us->suspend_resume_hook)
/* When runtime PM is working, we'll set a flag to indicate
* whether we should autoresume when a SCSI request arrives. */
- mutex_unlock(&us->dev_mutex);
+ up(&us->dev_semaphore);
return 0;
}
{
struct us_data *us = usb_get_intfdata(iface);
- mutex_lock(&us->dev_mutex);
+ down(&us->dev_semaphore);
US_DEBUGP("%s\n", __FUNCTION__);
if (us->suspend_resume_hook)
(us->suspend_resume_hook)(us, US_RESUME);
iface->dev.power.power_state.event = PM_EVENT_ON;
- mutex_unlock(&us->dev_mutex);
+ up(&us->dev_semaphore);
return 0;
}
#endif /* CONFIG_PM */
-/*
- * The next two routines get called just before and just after
- * a USB port reset, whether from this driver or a different one.
- */
-
-static void storage_pre_reset(struct usb_interface *iface)
-{
- struct us_data *us = usb_get_intfdata(iface);
-
- US_DEBUGP("%s\n", __FUNCTION__);
-
- /* Make sure no command runs during the reset */
- mutex_lock(&us->dev_mutex);
-}
-
-static void storage_post_reset(struct usb_interface *iface)
-{
- struct us_data *us = usb_get_intfdata(iface);
-
- US_DEBUGP("%s\n", __FUNCTION__);
-
- /* Report the reset to the SCSI core */
- scsi_lock(us_to_host(us));
- usb_stor_report_bus_reset(us);
- scsi_unlock(us_to_host(us));
-
- /* FIXME: Notify the subdrivers that they need to reinitialize
- * the device */
- mutex_unlock(&us->dev_mutex);
-}
-
/*
* fill_inquiry_response takes an unsigned char array (which must
* be at least 36 characters) and populates the vendor name,
US_DEBUGP("*** thread awakened.\n");
/* lock the device pointers */
- mutex_lock(&(us->dev_mutex));
+ down(&(us->dev_semaphore));
/* if the device has disconnected, we are free to exit */
if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
US_DEBUGP("-- exiting\n");
- mutex_unlock(&us->dev_mutex);
+ up(&(us->dev_semaphore));
break;
}
/* lock access to the state */
scsi_lock(host);
- /* did the command already complete because of a disconnect? */
- if (!us->srb)
- ; /* nothing to do */
-
/* indicate that the command is done */
- else if (us->srb->result != DID_ABORT << 16) {
+ if (us->srb->result != DID_ABORT << 16) {
US_DEBUGP("scsi cmd done, result=0x%x\n",
us->srb->result);
us->srb->scsi_done(us->srb);
scsi_unlock(host);
/* unlock the device pointers */
- mutex_unlock(&us->dev_mutex);
+ up(&(us->dev_semaphore));
} /* for (;;) */
scsi_host_put(host);
}
/* Get the unusual_devs entries and the string descriptors */
-static int get_device_info(struct us_data *us, const struct usb_device_id *id)
+static void get_device_info(struct us_data *us, const struct usb_device_id *id)
{
struct usb_device *dev = us->pusb_dev;
struct usb_interface_descriptor *idesc =
unusual_dev->useTransport;
us->flags = USB_US_ORIG_FLAGS(id->driver_info);
- if (us->flags & US_FL_IGNORE_DEVICE) {
- printk(KERN_INFO USB_STORAGE "device ignored\n");
- return -ENODEV;
- }
-
/*
* This flag is only needed when we're in high-speed, so let's
* disable it if we're in full-speed
if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE))
printk(KERN_NOTICE USB_STORAGE "This device "
"(%04x,%04x,%04x S %02x P %02x)"
- " has %s in unusual_devs.h (kernel"
- " %s)\n"
+ " has %s in unusual_devs.h\n"
" Please send a copy of this message to "
"<linux-usb-devel@lists.sourceforge.net>\n",
le16_to_cpu(ddesc->idVendor),
le16_to_cpu(ddesc->bcdDevice),
idesc->bInterfaceSubClass,
idesc->bInterfaceProtocol,
- msgs[msg],
- UTS_RELEASE);
+ msgs[msg]);
}
-
- return 0;
}
/* Get the transport settings */
break;
#endif
-#ifdef CONFIG_USB_STORAGE_ALAUDA
- case US_PR_ALAUDA:
- us->transport_name = "Alauda Control/Bulk";
- us->transport = alauda_transport;
- us->transport_reset = usb_stor_Bulk_reset;
- us->max_lun = 1;
- break;
-#endif
-
default:
return -EIO;
}
break;
#endif
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+ case US_PR_ALAUDA:
+ us->transport_name = "Alauda Control/Bulk";
+ us->transport = alauda_transport;
+ us->transport_reset = usb_stor_Bulk_reset;
+ us->max_lun = 1;
+ break;
+#endif
+
default:
return -EIO;
}
* the host */
static void quiesce_and_remove_host(struct us_data *us)
{
- struct Scsi_Host *host = us_to_host(us);
-
/* Prevent new USB transfers, stop the current command, and
* interrupt a SCSI-scan or device-reset delay */
- scsi_lock(host);
set_bit(US_FLIDX_DISCONNECTING, &us->flags);
- scsi_unlock(host);
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);
+
/* queuecommand won't accept any new commands and the control
* thread won't execute a previously-queued command. If there
* is such a command pending, complete it with an error. */
- mutex_lock(&us->dev_mutex);
if (us->srb) {
us->srb->result = DID_NO_CONNECT << 16;
- scsi_lock(host);
+ scsi_lock(us_to_host(us));
us->srb->scsi_done(us->srb);
us->srb = NULL;
- scsi_unlock(host);
+ scsi_unlock(us_to_host(us));
}
- mutex_unlock(&us->dev_mutex);
/* Now we own no commands so it's safe to remove the SCSI host */
- scsi_remove_host(host);
+ scsi_remove_host(us_to_host(us));
}
/* Second stage of disconnect processing: deallocate all resources */
/* For bulk-only devices, determine the max LUN value */
if (us->protocol == US_PR_BULK &&
!(us->flags & US_FL_SINGLE_LUN)) {
- mutex_lock(&us->dev_mutex);
+ down(&us->dev_semaphore);
us->max_lun = usb_stor_Bulk_max_lun(us);
- mutex_unlock(&us->dev_mutex);
+ up(&us->dev_semaphore);
}
scsi_scan_host(us_to_host(us));
printk(KERN_DEBUG "usb-storage: device scan complete\n");
us = host_to_us(host);
memset(us, 0, sizeof(struct us_data));
- mutex_init(&(us->dev_mutex));
+ init_MUTEX(&(us->dev_semaphore));
init_MUTEX_LOCKED(&(us->sema));
init_completion(&(us->notify));
init_waitqueue_head(&us->delay_wait);
* of the match from the usb_device_id table, so we can find the
* corresponding entry in the private table.
*/
- result = get_device_info(us, id);
- if (result)
- goto BadDevice;
+ get_device_info(us, id);
/* Get the transport, protocol, and pipe settings */
result = get_transport(us);
.suspend = storage_suspend,
.resume = storage_resume,
#endif
- .pre_reset = storage_pre_reset,
- .post_reset = storage_post_reset,
.id_table = storage_usb_ids,
};