summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2005-10-23 19:40:22 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2005-10-28 16:47:50 -0700
commitbbafa4668f37f5093a3ae2a8b0cbe327e24e12da (patch)
treee679db87309810e8da8092ffcb3df5a9dd7323e0 /drivers
parentb876aef7f890d8c59a45b78858a36cf60fddf522 (diff)
downloadlinux-bbafa4668f37f5093a3ae2a8b0cbe327e24e12da.tar.gz
[PATCH] PATCH: usb-storage: allocate separate sense buffer
This patch is from Alan Stern (as560).  It has been rediffed against a
current tree.

This patch allocates a separate buffer for usb-storage to use when
auto-sensing.  Up to now we have been using the sense buffer embedded in a
scsi_cmnd struct, which is dangerous on hosts that (a) don't do
cache-coherent DMA or (b) have DMA alignment restrictions.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/storage/transport.c5
-rw-r--r--drivers/usb/storage/usb.c8
-rw-r--r--drivers/usb/storage/usb.h2
3 files changed, 13 insertions, 2 deletions
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index e89e945fc4a7..7ca896a342e3 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -636,11 +636,11 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
 
 		/* use the new buffer we have */
 		old_request_buffer = srb->request_buffer;
-		srb->request_buffer = srb->sense_buffer;
+		srb->request_buffer = us->sensebuf;
 
 		/* set the buffer length for transfer */
 		old_request_bufflen = srb->request_bufflen;
-		srb->request_bufflen = 18;
+		srb->request_bufflen = US_SENSE_SIZE;
 
 		/* set up for no scatter-gather use */
 		old_sg = srb->use_sg;
@@ -652,6 +652,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
 		temp_result = us->transport(us->srb, us);
 
 		/* let's clean up right away */
+		memcpy(srb->sense_buffer, us->sensebuf, US_SENSE_SIZE);
 		srb->resid = old_resid;
 		srb->request_buffer = old_request_buffer;
 		srb->request_bufflen = old_request_bufflen;
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 92ee079d9172..eb901817b7d2 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -467,6 +467,12 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf)
 		US_DEBUGP("I/O buffer allocation failed\n");
 		return -ENOMEM;
 	}
+
+	us->sensebuf = kmalloc(US_SENSE_SIZE, GFP_KERNEL);
+	if (!us->sensebuf) {
+		US_DEBUGP("Sense buffer allocation failed\n");
+		return -ENOMEM;
+	}
 	return 0;
 }
 
@@ -800,6 +806,8 @@ static void dissociate_dev(struct us_data *us)
 {
 	US_DEBUGP("-- %s\n", __FUNCTION__);
 
+	kfree(us->sensebuf);
+
 	/* Free the device-related DMA-mapped buffers */
 	if (us->cr)
 		usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr,
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index a195adae57b6..dfa4dc71dd3e 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -117,6 +117,7 @@ enum { US_DO_ALL_FLAGS };
  */
 
 #define US_IOBUF_SIZE		64	/* Size of the DMA-mapped I/O buffer */
+#define US_SENSE_SIZE		18	/* Size of the autosense data buffer */
 
 typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*);
 typedef int (*trans_reset)(struct us_data*);
@@ -168,6 +169,7 @@ struct us_data {
 	struct usb_ctrlrequest	*cr;		 /* control requests	 */
 	struct usb_sg_request	current_sg;	 /* scatter-gather req.  */
 	unsigned char		*iobuf;		 /* I/O buffer		 */
+	unsigned char		*sensebuf;	 /* sense data buffer	 */
 	dma_addr_t		cr_dma;		 /* buffer DMA addresses */
 	dma_addr_t		iobuf_dma;