Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 47104b0d authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

[PATCH] usb-storage: use usb_reset_composite_device



This patch (as701) modifies usb-storage to take advantage of the new
usb_reset_composite_device() API.  Now we will be able to safely request
port resets even if other drivers are bound to a mass-storage device.

Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 7de18d8b
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -286,11 +286,7 @@ static int bus_reset(struct scsi_cmnd *srb)
	int result;

	US_DEBUGP("%s called\n", __FUNCTION__);

	mutex_lock(&(us->dev_mutex));
	result = usb_stor_port_reset(us);
	mutex_unlock(&us->dev_mutex);

	return result < 0 ? FAILED : SUCCESS;
}

+26 −24
Original line number Diff line number Diff line
@@ -703,16 +703,19 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
	 * device reset. */
  Handle_Errors:

	/* Let the SCSI layer know we are doing a reset, set the
	 * RESETTING bit, and clear the ABORTING bit so that the reset
	 * may proceed. */
	/* Set the RESETTING bit, and clear the ABORTING bit so that
	 * the reset may proceed. */
	scsi_lock(us_to_host(us));
	usb_stor_report_bus_reset(us);
	set_bit(US_FLIDX_RESETTING, &us->flags);
	clear_bit(US_FLIDX_ABORTING, &us->flags);
	scsi_unlock(us_to_host(us));

	/* We must release the device lock because the pre_reset routine
	 * will want to acquire it. */
	mutex_unlock(&us->dev_mutex);
	result = usb_stor_port_reset(us);
	mutex_lock(&us->dev_mutex);

	if (result < 0) {
		scsi_lock(us_to_host(us));
		usb_stor_report_device_reset(us);
@@ -1196,31 +1199,30 @@ int usb_stor_Bulk_reset(struct us_data *us)
				 0, us->ifnum, NULL, 0);
}

/* Issue a USB port reset to the device.  But don't do anything if
 * there's more than one interface in the device, so that other users
 * are not affected. */
/* Issue a USB port reset to the device.  The caller must not hold
 * us->dev_mutex.
 */
int usb_stor_port_reset(struct us_data *us)
{
	int result, rc;
	int result, rc_lock;

	result = rc_lock =
		usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
	if (result < 0)
		US_DEBUGP("unable to lock device for reset: %d\n", result);
	else {
		/* Were we disconnected while waiting for the lock? */
		if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
			result = -EIO;
			US_DEBUGP("No reset during disconnect\n");
	} else if (us->pusb_dev->actconfig->desc.bNumInterfaces != 1) {
		result = -EBUSY;
		US_DEBUGP("Refusing to reset a multi-interface device\n");
		} else {
		result = rc =
			usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
		if (result < 0) {
			US_DEBUGP("unable to lock device for reset: %d\n",
			result = usb_reset_composite_device(
					us->pusb_dev, us->pusb_intf);
			US_DEBUGP("usb_reset_composite_device returns %d\n",
					result);
		} else {
			result = usb_reset_device(us->pusb_dev);
			if (rc)
				usb_unlock_device(us->pusb_dev);
			US_DEBUGP("usb_reset_device returns %d\n", result);
		}
		if (rc_lock)
			usb_unlock_device(us->pusb_dev);
	}
	return result;
}
+33 −0
Original line number Diff line number Diff line
@@ -220,6 +220,37 @@ static int storage_resume(struct usb_interface *iface)

#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,
@@ -1002,6 +1033,8 @@ static struct usb_driver usb_storage_driver = {
	.suspend =	storage_suspend,
	.resume =	storage_resume,
#endif
	.pre_reset =	storage_pre_reset,
	.post_reset =	storage_post_reset,
	.id_table =	storage_usb_ids,
};