aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2008-06-30 13:39:59 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-07-21 18:16:51 -0400
commitf756cbd458ab71c996a069cb3928fb1e2d7cd9cc (patch)
tree4caadc9f8a55e662d144535b855ad442af19fc50
parent86c57edf60f5c98adb496880f56cd0e5a3423153 (diff)
usb-storage: revert DMA-alignment change for Wireless USB
This patch (as1110) reverts an earlier patch meant to help with Wireless USB host controllers. These controllers can have bulk maxpacket values larger than 512, which puts unusual constraints on the sizes of scatter-gather list elements. However it turns out that the block layer does not provide the support we need to enforce these constraints; merely changing the DMA alignment mask doesn't help. Hence there's no reason to keep the original patch. The Wireless USB problem will have to be solved a different way. In addition, there is a reason to get rid of the earlier patch. By dereferencing a pointer stored in the ep_in array of struct usb_device, the current code risks an invalid memory access when it runs concurrently with device removal. The members of that array are cleared before the driver's disconnect method is called, so it should not try to use them. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/storage/scsiglue.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index b4c9e0f18a82..09779f6a8179 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -71,7 +71,6 @@ static const char* host_info(struct Scsi_Host *host)
71static int slave_alloc (struct scsi_device *sdev) 71static int slave_alloc (struct scsi_device *sdev)
72{ 72{
73 struct us_data *us = host_to_us(sdev->host); 73 struct us_data *us = host_to_us(sdev->host);
74 struct usb_host_endpoint *bulk_in_ep;
75 74
76 /* 75 /*
77 * Set the INQUIRY transfer length to 36. We don't use any of 76 * Set the INQUIRY transfer length to 36. We don't use any of
@@ -80,16 +79,22 @@ static int slave_alloc (struct scsi_device *sdev)
80 */ 79 */
81 sdev->inquiry_len = 36; 80 sdev->inquiry_len = 36;
82 81
83 /* Scatter-gather buffers (all but the last) must have a length 82 /* USB has unusual DMA-alignment requirements: Although the
84 * divisible by the bulk maxpacket size. Otherwise a data packet 83 * starting address of each scatter-gather element doesn't matter,
85 * would end up being short, causing a premature end to the data 84 * the length of each element except the last must be divisible
86 * transfer. We'll use the maxpacket value of the bulk-IN pipe 85 * by the Bulk maxpacket value. There's currently no way to
87 * to set the SCSI device queue's DMA alignment mask. 86 * express this by block-layer constraints, so we'll cop out
87 * and simply require addresses to be aligned at 512-byte
88 * boundaries. This is okay since most block I/O involves
89 * hardware sectors that are multiples of 512 bytes in length,
90 * and since host controllers up through USB 2.0 have maxpacket
91 * values no larger than 512.
92 *
93 * But it doesn't suffice for Wireless USB, where Bulk maxpacket
94 * values can be as large as 2048. To make that work properly
95 * will require changes to the block layer.
88 */ 96 */
89 bulk_in_ep = us->pusb_dev->ep_in[usb_pipeendpoint(us->recv_bulk_pipe)]; 97 blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1));
90 blk_queue_update_dma_alignment(sdev->request_queue,
91 le16_to_cpu(bulk_in_ep->desc.wMaxPacketSize) - 1);
92 /* wMaxPacketSize must be a power of 2 */
93 98
94 /* 99 /*
95 * The UFI spec treates the Peripheral Qualifier bits in an 100 * The UFI spec treates the Peripheral Qualifier bits in an