Commit e5219c5d authored by Vojtech Pavlik's avatar Vojtech Pavlik Committed by Greg Kroah-Hartman

[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: default avatarVojtech Pavlik <vojtech@suse.cz>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 8727da1d
...@@ -485,7 +485,9 @@ static int isd200_action( struct us_data *us, int action, ...@@ -485,7 +485,9 @@ static int isd200_action( struct us_data *us, int action,
memcpy(srb->cmnd, &ata, sizeof(ata.generic)); memcpy(srb->cmnd, &ata, sizeof(ata.generic));
srb->cmd_len = sizeof(ata.generic); srb->cmd_len = sizeof(ata.generic);
down(&(us->pusb_dev->serialize));
status = usb_stor_Bulk_transport(srb, us); status = usb_stor_Bulk_transport(srb, us);
up(&(us->pusb_dev->serialize));
if (status == USB_STOR_TRANSPORT_GOOD) if (status == USB_STOR_TRANSPORT_GOOD)
status = ISD200_GOOD; status = ISD200_GOOD;
else { else {
...@@ -545,7 +547,9 @@ static void isd200_invoke_transport( struct us_data *us, ...@@ -545,7 +547,9 @@ static void isd200_invoke_transport( struct us_data *us,
/* send the command to the transport layer */ /* send the command to the transport layer */
memcpy(srb->cmnd, ataCdb, sizeof(ataCdb->generic)); memcpy(srb->cmnd, ataCdb, sizeof(ataCdb->generic));
srb->cmd_len = sizeof(ataCdb->generic); srb->cmd_len = sizeof(ataCdb->generic);
down(&(us->pusb_dev->serialize));
transferStatus = usb_stor_Bulk_transport(srb, us); transferStatus = usb_stor_Bulk_transport(srb, us);
up(&(us->pusb_dev->serialize));
/* if the command gets aborted by the higher layers, we need to /* if the command gets aborted by the higher layers, we need to
* short-circuit all other processing * short-circuit all other processing
......
...@@ -527,9 +527,18 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -527,9 +527,18 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
int need_auto_sense; int need_auto_sense;
int result; 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 */ /* send the command to the transport layer */
down(&(us->pusb_dev->serialize));
srb->resid = 0; srb->resid = 0;
result = us->transport(srb, us); result = us->transport(srb, us);
up(&(us->pusb_dev->serialize));
/* if the command gets aborted by the higher layers, we need to /* if the command gets aborted by the higher layers, we need to
* short-circuit all other processing * short-circuit all other processing
...@@ -648,9 +657,11 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -648,9 +657,11 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
srb->serial_number ^= 0x80000000; srb->serial_number ^= 0x80000000;
/* issue the auto-sense command */ /* issue the auto-sense command */
down(&(us->pusb_dev->serialize));
old_resid = srb->resid; old_resid = srb->resid;
srb->resid = 0; srb->resid = 0;
temp_result = us->transport(us->srb, us); temp_result = us->transport(us->srb, us);
up(&(us->pusb_dev->serialize));
/* let's clean up right away */ /* let's clean up right away */
srb->resid = old_resid; srb->resid = old_resid;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment