diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2008-11-04 11:29:27 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-01-07 12:59:52 -0500 |
commit | 011b15df465745474e3ec85482633685933ed5a7 (patch) | |
tree | 97df5cb516672f0a6fae5b993840beb667c76bd0 /drivers | |
parent | 857cc4dfb6420ec0a67b3cda559aaa7c429ddce7 (diff) |
USB: change interface to usb_lock_device_for_reset()
This patch (as1161) changes the interface to
usb_lock_device_for_reset(). The existing interface is apparently not
very clear, judging from the fact that several of its callers don't
use it correctly. The new interface always returns 0 for success and
it always requires the caller to unlock the device afterward.
The new routine will not return immediately if it is called while the
driver's probe method is running. Instead it will wait until the
probe is over and the device has been unlocked. This shouldn't cause
any problems; I don't know of any cases where drivers call
usb_lock_device_for_reset() during probe.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Pete Zaitcev <zaitcev@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/ub.c | 11 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 9 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 23 | ||||
-rw-r--r-- | drivers/usb/image/microtek.c | 11 | ||||
-rw-r--r-- | drivers/usb/storage/transport.c | 8 |
6 files changed, 25 insertions, 39 deletions
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 048d71d244d7..12fb816db7b0 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -1579,7 +1579,7 @@ static void ub_reset_task(struct work_struct *work) | |||
1579 | struct ub_dev *sc = container_of(work, struct ub_dev, reset_work); | 1579 | struct ub_dev *sc = container_of(work, struct ub_dev, reset_work); |
1580 | unsigned long flags; | 1580 | unsigned long flags; |
1581 | struct ub_lun *lun; | 1581 | struct ub_lun *lun; |
1582 | int lkr, rc; | 1582 | int rc; |
1583 | 1583 | ||
1584 | if (!sc->reset) { | 1584 | if (!sc->reset) { |
1585 | printk(KERN_WARNING "%s: Running reset unrequested\n", | 1585 | printk(KERN_WARNING "%s: Running reset unrequested\n", |
@@ -1597,10 +1597,11 @@ static void ub_reset_task(struct work_struct *work) | |||
1597 | } else if (sc->dev->actconfig->desc.bNumInterfaces != 1) { | 1597 | } else if (sc->dev->actconfig->desc.bNumInterfaces != 1) { |
1598 | ; | 1598 | ; |
1599 | } else { | 1599 | } else { |
1600 | if ((lkr = usb_lock_device_for_reset(sc->dev, sc->intf)) < 0) { | 1600 | rc = usb_lock_device_for_reset(sc->dev, sc->intf); |
1601 | if (rc < 0) { | ||
1601 | printk(KERN_NOTICE | 1602 | printk(KERN_NOTICE |
1602 | "%s: usb_lock_device_for_reset failed (%d)\n", | 1603 | "%s: usb_lock_device_for_reset failed (%d)\n", |
1603 | sc->name, lkr); | 1604 | sc->name, rc); |
1604 | } else { | 1605 | } else { |
1605 | rc = usb_reset_device(sc->dev); | 1606 | rc = usb_reset_device(sc->dev); |
1606 | if (rc < 0) { | 1607 | if (rc < 0) { |
@@ -1608,9 +1609,7 @@ static void ub_reset_task(struct work_struct *work) | |||
1608 | "usb_lock_device_for_reset failed (%d)\n", | 1609 | "usb_lock_device_for_reset failed (%d)\n", |
1609 | sc->name, rc); | 1610 | sc->name, rc); |
1610 | } | 1611 | } |
1611 | 1612 | usb_unlock_device(sc->dev); | |
1612 | if (lkr) | ||
1613 | usb_unlock_device(sc->dev); | ||
1614 | } | 1613 | } |
1615 | } | 1614 | } |
1616 | 1615 | ||
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 03cb494af1c5..f0a0f72238ab 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -102,7 +102,7 @@ static void hid_reset(struct work_struct *work) | |||
102 | struct usbhid_device *usbhid = | 102 | struct usbhid_device *usbhid = |
103 | container_of(work, struct usbhid_device, reset_work); | 103 | container_of(work, struct usbhid_device, reset_work); |
104 | struct hid_device *hid = usbhid->hid; | 104 | struct hid_device *hid = usbhid->hid; |
105 | int rc_lock, rc = 0; | 105 | int rc = 0; |
106 | 106 | ||
107 | if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) { | 107 | if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) { |
108 | dev_dbg(&usbhid->intf->dev, "clear halt\n"); | 108 | dev_dbg(&usbhid->intf->dev, "clear halt\n"); |
@@ -113,11 +113,10 @@ static void hid_reset(struct work_struct *work) | |||
113 | 113 | ||
114 | else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) { | 114 | else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) { |
115 | dev_dbg(&usbhid->intf->dev, "resetting device\n"); | 115 | dev_dbg(&usbhid->intf->dev, "resetting device\n"); |
116 | rc = rc_lock = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf); | 116 | rc = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf); |
117 | if (rc_lock >= 0) { | 117 | if (rc == 0) { |
118 | rc = usb_reset_device(hid_to_usb_dev(hid)); | 118 | rc = usb_reset_device(hid_to_usb_dev(hid)); |
119 | if (rc_lock) | 119 | usb_unlock_device(hid_to_usb_dev(hid)); |
120 | usb_unlock_device(hid_to_usb_dev(hid)); | ||
121 | } | 120 | } |
122 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); | 121 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); |
123 | } | 122 | } |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 8fb92ac78c7b..fa304e5f252a 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -3655,7 +3655,7 @@ void pvr2_hdw_device_reset(struct pvr2_hdw *hdw) | |||
3655 | int ret; | 3655 | int ret; |
3656 | pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset..."); | 3656 | pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset..."); |
3657 | ret = usb_lock_device_for_reset(hdw->usb_dev,NULL); | 3657 | ret = usb_lock_device_for_reset(hdw->usb_dev,NULL); |
3658 | if (ret == 1) { | 3658 | if (ret == 0) { |
3659 | ret = usb_reset_device(hdw->usb_dev); | 3659 | ret = usb_reset_device(hdw->usb_dev); |
3660 | usb_unlock_device(hdw->usb_dev); | 3660 | usb_unlock_device(hdw->usb_dev); |
3661 | } else { | 3661 | } else { |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 399e15fc5052..400fa4cc9a34 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -513,10 +513,7 @@ EXPORT_SYMBOL_GPL(usb_put_intf); | |||
513 | * disconnect; in some drivers (such as usb-storage) the disconnect() | 513 | * disconnect; in some drivers (such as usb-storage) the disconnect() |
514 | * or suspend() method will block waiting for a device reset to complete. | 514 | * or suspend() method will block waiting for a device reset to complete. |
515 | * | 515 | * |
516 | * Returns a negative error code for failure, otherwise 1 or 0 to indicate | 516 | * Returns a negative error code for failure, otherwise 0. |
517 | * that the device will or will not have to be unlocked. (0 can be | ||
518 | * returned when an interface is given and is BINDING, because in that | ||
519 | * case the driver already owns the device lock.) | ||
520 | */ | 517 | */ |
521 | int usb_lock_device_for_reset(struct usb_device *udev, | 518 | int usb_lock_device_for_reset(struct usb_device *udev, |
522 | const struct usb_interface *iface) | 519 | const struct usb_interface *iface) |
@@ -527,16 +524,9 @@ int usb_lock_device_for_reset(struct usb_device *udev, | |||
527 | return -ENODEV; | 524 | return -ENODEV; |
528 | if (udev->state == USB_STATE_SUSPENDED) | 525 | if (udev->state == USB_STATE_SUSPENDED) |
529 | return -EHOSTUNREACH; | 526 | return -EHOSTUNREACH; |
530 | if (iface) { | 527 | if (iface && (iface->condition == USB_INTERFACE_UNBINDING || |
531 | switch (iface->condition) { | 528 | iface->condition == USB_INTERFACE_UNBOUND)) |
532 | case USB_INTERFACE_BINDING: | 529 | return -EINTR; |
533 | return 0; | ||
534 | case USB_INTERFACE_BOUND: | ||
535 | break; | ||
536 | default: | ||
537 | return -EINTR; | ||
538 | } | ||
539 | } | ||
540 | 530 | ||
541 | while (usb_trylock_device(udev) != 0) { | 531 | while (usb_trylock_device(udev) != 0) { |
542 | 532 | ||
@@ -550,10 +540,11 @@ int usb_lock_device_for_reset(struct usb_device *udev, | |||
550 | return -ENODEV; | 540 | return -ENODEV; |
551 | if (udev->state == USB_STATE_SUSPENDED) | 541 | if (udev->state == USB_STATE_SUSPENDED) |
552 | return -EHOSTUNREACH; | 542 | return -EHOSTUNREACH; |
553 | if (iface && iface->condition != USB_INTERFACE_BOUND) | 543 | if (iface && (iface->condition == USB_INTERFACE_UNBINDING || |
544 | iface->condition == USB_INTERFACE_UNBOUND)) | ||
554 | return -EINTR; | 545 | return -EINTR; |
555 | } | 546 | } |
556 | return 1; | 547 | return 0; |
557 | } | 548 | } |
558 | EXPORT_SYMBOL_GPL(usb_lock_device_for_reset); | 549 | EXPORT_SYMBOL_GPL(usb_lock_device_for_reset); |
559 | 550 | ||
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 885867a86de8..4541dfcea88f 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c | |||
@@ -350,17 +350,16 @@ static int mts_scsi_abort(struct scsi_cmnd *srb) | |||
350 | static int mts_scsi_host_reset(struct scsi_cmnd *srb) | 350 | static int mts_scsi_host_reset(struct scsi_cmnd *srb) |
351 | { | 351 | { |
352 | struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); | 352 | struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); |
353 | int result, rc; | 353 | int result; |
354 | 354 | ||
355 | MTS_DEBUG_GOT_HERE(); | 355 | MTS_DEBUG_GOT_HERE(); |
356 | mts_debug_dump(desc); | 356 | mts_debug_dump(desc); |
357 | 357 | ||
358 | rc = usb_lock_device_for_reset(desc->usb_dev, desc->usb_intf); | 358 | result = usb_lock_device_for_reset(desc->usb_dev, desc->usb_intf); |
359 | if (rc < 0) | 359 | if (result == 0) { |
360 | return FAILED; | 360 | result = usb_reset_device(desc->usb_dev); |
361 | result = usb_reset_device(desc->usb_dev); | ||
362 | if (rc) | ||
363 | usb_unlock_device(desc->usb_dev); | 361 | usb_unlock_device(desc->usb_dev); |
362 | } | ||
364 | return result ? FAILED : SUCCESS; | 363 | return result ? FAILED : SUCCESS; |
365 | } | 364 | } |
366 | 365 | ||
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 79108d5d3171..2058db41618c 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c | |||
@@ -1173,10 +1173,9 @@ int usb_stor_Bulk_reset(struct us_data *us) | |||
1173 | */ | 1173 | */ |
1174 | int usb_stor_port_reset(struct us_data *us) | 1174 | int usb_stor_port_reset(struct us_data *us) |
1175 | { | 1175 | { |
1176 | int result, rc_lock; | 1176 | int result; |
1177 | 1177 | ||
1178 | result = rc_lock = | 1178 | result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf); |
1179 | usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf); | ||
1180 | if (result < 0) | 1179 | if (result < 0) |
1181 | US_DEBUGP("unable to lock device for reset: %d\n", result); | 1180 | US_DEBUGP("unable to lock device for reset: %d\n", result); |
1182 | else { | 1181 | else { |
@@ -1189,8 +1188,7 @@ int usb_stor_port_reset(struct us_data *us) | |||
1189 | US_DEBUGP("usb_reset_device returns %d\n", | 1188 | US_DEBUGP("usb_reset_device returns %d\n", |
1190 | result); | 1189 | result); |
1191 | } | 1190 | } |
1192 | if (rc_lock) | 1191 | usb_unlock_device(us->pusb_dev); |
1193 | usb_unlock_device(us->pusb_dev); | ||
1194 | } | 1192 | } |
1195 | return result; | 1193 | return result; |
1196 | } | 1194 | } |