ChangeSet 1.1722.83.4, 2004/06/02 13:19:56-07:00, vojtech@suse.cz [PATCH] USB: Patch to prevent overlapping access by usb-storage and usbfs usb: Based on a 2.4 patch from John_Hull@Dell.com, this patch serializes usb storage and usbfs operation, so that usbfs cannot disturb storage by seemingly harmless control reads. Signed-off-by: Vojtech Pavlik Signed-off-by: Greg Kroah-Hartman drivers/usb/storage/isd200.c | 4 ++++ drivers/usb/storage/transport.c | 11 +++++++++++ 2 files changed, 15 insertions(+) diff -Nru a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c --- a/drivers/usb/storage/isd200.c Fri Jun 18 11:07:08 2004 +++ b/drivers/usb/storage/isd200.c Fri Jun 18 11:07:08 2004 @@ -485,7 +485,9 @@ memcpy(srb->cmnd, &ata, sizeof(ata.generic)); srb->cmd_len = sizeof(ata.generic); + down(&(us->pusb_dev->serialize)); status = usb_stor_Bulk_transport(srb, us); + up(&(us->pusb_dev->serialize)); if (status == USB_STOR_TRANSPORT_GOOD) status = ISD200_GOOD; else { @@ -545,7 +547,9 @@ /* send the command to the transport layer */ memcpy(srb->cmnd, ataCdb, sizeof(ataCdb->generic)); srb->cmd_len = sizeof(ataCdb->generic); + down(&(us->pusb_dev->serialize)); transferStatus = usb_stor_Bulk_transport(srb, us); + up(&(us->pusb_dev->serialize)); /* if the command gets aborted by the higher layers, we need to * short-circuit all other processing diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c --- a/drivers/usb/storage/transport.c Fri Jun 18 11:07:08 2004 +++ b/drivers/usb/storage/transport.c Fri Jun 18 11:07:08 2004 @@ -527,9 +527,18 @@ int need_auto_sense; int result; + /* + * Grab device's serialize mutex to prevent /usbfs and others from + * sending out a command in the middle of ours (if libusb sends a + * get_descriptor or something on pipe 0 after our CBW and before + * our CSW, and then we get a stall, we have trouble) + */ + /* send the command to the transport layer */ + down(&(us->pusb_dev->serialize)); srb->resid = 0; result = us->transport(srb, us); + up(&(us->pusb_dev->serialize)); /* if the command gets aborted by the higher layers, we need to * short-circuit all other processing @@ -648,9 +657,11 @@ srb->serial_number ^= 0x80000000; /* issue the auto-sense command */ + down(&(us->pusb_dev->serialize)); old_resid = srb->resid; srb->resid = 0; temp_result = us->transport(us->srb, us); + up(&(us->pusb_dev->serialize)); /* let's clean up right away */ srb->resid = old_resid;