linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] fix Sony USB mass storage - pass larger receive buffer
@ 2003-11-12 23:50 Patrick Mansfield
  2003-11-13  0:09 ` Matthew Dharm
  2003-11-14  2:02 ` Douglas Gilbert
  0 siblings, 2 replies; 68+ messages in thread
From: Patrick Mansfield @ 2003-11-12 23:50 UTC (permalink / raw)
  To: James Bottomley, linux-scsi, usb-storage; +Cc: ronald, dmitrik, idan

James - can you please apply? This should not affect other devices since
we are not changing the requested length, just the size of the receive
buffer.

This patch against a recent 2.6 bk fixes problems with Sony USB mass
storage devices: they are sending back 10 bytes even when we ask for 8
bytes (USB babble).

Just use a larger receive buffer for MODE SENSE even though we are
requesting 8 bytes.

Tested by Ronald Kuetemei with his Sony camera, also tested with a USB CF
card reader.

diff -uprN -X /home/patman/dontdiff bl-25/drivers/scsi/scsi_lib.c modesense-bufflen-bk-2.5/drivers/scsi/scsi_lib.c
--- bl-25/drivers/scsi/scsi_lib.c	Mon Sep 29 12:21:09 2003
+++ modesense-bufflen-bk-2.5/drivers/scsi/scsi_lib.c	Mon Nov 10 15:42:03 2003
@@ -1348,8 +1348,9 @@ void scsi_exit_queue(void)
  *	@sreq:	SCSI request to fill in with the MODE_SENSE
  *	@dbd:	set if mode sense will allow block descriptors to be returned
  *	@modepage: mode page being requested
- *	@buffer: request buffer (may not be smaller than eight bytes)
- *	@len:	length of request buffer.
+ *	@buffer: request buffer
+ *	@len:	length passed in to scsi command
+ *	@buf_len: length of request buffer (may not be smaller than eight)
  *	@timeout: command timeout
  *	@retries: number of retries before failing
  *	@data: returns a structure abstracting the mode header data
@@ -1357,15 +1358,24 @@ void scsi_exit_queue(void)
  *	Returns zero if unsuccessful, or the header offset (either 4
  *	or 8 depending on whether a six or ten byte command was
  *	issued) if successful.
+ *
+ *	Note: buf_len is passed in as a separate value because some
+ *	devices return more data than requested.
  **/
 int
 __scsi_mode_sense(struct scsi_request *sreq, int dbd, int modepage,
-		  unsigned char *buffer, int len, int timeout, int retries,
-		  struct scsi_mode_data *data) {
+		  unsigned char *buffer, int len, int buf_len, int timeout,
+		  int retries, struct scsi_mode_data *data) {
 	unsigned char cmd[12];
 	int use_10_for_ms;
 	int header_length;
 
+	WARN_ON((buf_len < 8) || (buf_len < len));
+	if (buf_len > 255)
+		buf_len = 255;
+	if (len > 255)
+		len = 255;
+
 	memset(data, 0, sizeof(*data));
 	memset(&cmd[0], 0, 12);
 	cmd[1] = dbd & 0x18;	/* allows DBD and LLBA bits */
@@ -1395,9 +1405,9 @@ __scsi_mode_sense(struct scsi_request *s
 	sreq->sr_sense_buffer[2] = 0;
 	sreq->sr_data_direction = DMA_FROM_DEVICE;
 
-	memset(buffer, 0, len);
+	memset(buffer, 0, buf_len);
 
-	scsi_wait_req(sreq, cmd, buffer, len, timeout, retries);
+	scsi_wait_req(sreq, cmd, buffer, buf_len, timeout, retries);
 
 	/* This code looks awful: what it's doing is making sure an
 	 * ILLEGAL REQUEST sense return identifies the actual command
@@ -1439,8 +1449,9 @@ __scsi_mode_sense(struct scsi_request *s
  *	@sdev:	scsi device to send command to.
  *	@dbd:	set if mode sense will disable block descriptors in the return
  *	@modepage: mode page being requested
- *	@buffer: request buffer (may not be smaller than eight bytes)
- *	@len:	length of request buffer.
+ *	@buffer: request buffer
+ *	@len:	length passed in to scsi command
+ *	@buf_len: length of request buffer (may not be smaller than eight)
  *	@timeout: command timeout
  *	@retries: number of retries before failing
  *
@@ -1450,8 +1461,8 @@ __scsi_mode_sense(struct scsi_request *s
  **/
 int
 scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
-		unsigned char *buffer, int len, int timeout, int retries,
-		struct scsi_mode_data *data)
+		unsigned char *buffer, int len, int buf_len, int timeout,
+		int retries, struct scsi_mode_data *data)
 {
 	struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL);
 	int ret;
@@ -1459,7 +1470,7 @@ scsi_mode_sense(struct scsi_device *sdev
 	if (!sreq)
 		return -1;
 
-	ret = __scsi_mode_sense(sreq, dbd, modepage, buffer, len,
+	ret = __scsi_mode_sense(sreq, dbd, modepage, buffer, len, buf_len,
 				timeout, retries, data);
 
 	scsi_release_request(sreq);
diff -uprN -X /home/patman/dontdiff bl-25/drivers/scsi/sd.c modesense-bufflen-bk-2.5/drivers/scsi/sd.c
--- bl-25/drivers/scsi/sd.c	Mon Oct 27 14:28:18 2003
+++ modesense-bufflen-bk-2.5/drivers/scsi/sd.c	Mon Nov 10 15:38:06 2003
@@ -1073,19 +1073,21 @@ got_data:
 /* called with buffer of length 512 */
 static inline int
 sd_do_mode_sense(struct scsi_request *SRpnt, int dbd, int modepage,
-		 unsigned char *buffer, int len, struct scsi_mode_data *data)
+		 unsigned char *buffer, int len, int buf_len,
+		 struct scsi_mode_data *data)
 {
-	return __scsi_mode_sense(SRpnt, dbd, modepage, buffer, len,
+	return __scsi_mode_sense(SRpnt, dbd, modepage, buffer, len, buf_len,
 				 SD_TIMEOUT, SD_MAX_RETRIES, data);
 }
 
 /*
  * read write protect setting, if possible - called only in sd_revalidate_disk()
- * called with buffer of length 512
  */
 static void
 sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
-		   struct scsi_request *SRpnt, unsigned char *buffer) {
+		   struct scsi_request *SRpnt, unsigned char *buffer,
+		   int buf_len) 
+{
 	int res;
 	struct scsi_mode_data data;
 
@@ -1099,7 +1101,7 @@ sd_read_write_protect_flag(struct scsi_d
 	 * We have to start carefully: some devices hang if we ask
 	 * for more than is available.
 	 */
-	res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 4, &data);
+	res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 4, buf_len, &data);
 
 	/*
 	 * Second attempt: ask for page 0
@@ -1107,13 +1109,14 @@ sd_read_write_protect_flag(struct scsi_d
 	 * Sense Key 5: Illegal Request, Sense Code 24: Invalid field in CDB.
 	 */
 	if (!scsi_status_is_good(res))
-		res = sd_do_mode_sense(SRpnt, 0, 0, buffer, 4, &data);
+		res = sd_do_mode_sense(SRpnt, 0, 0, buffer, 4, buf_len, &data);
 
 	/*
 	 * Third attempt: ask 255 bytes, as we did earlier.
 	 */
 	if (!scsi_status_is_good(res))
-		res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 255, &data);
+		res = sd_do_mode_sense(SRpnt, 0, 0x3F, buffer, 255, buf_len,
+				       &data);
 
 	if (!scsi_status_is_good(res)) {
 		printk(KERN_WARNING
@@ -1129,11 +1132,12 @@ sd_read_write_protect_flag(struct scsi_d
 
 /*
  * sd_read_cache_type - called only from sd_revalidate_disk()
- * called with buffer of length 512
  */
 static void
 sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
-		   struct scsi_request *SRpnt, unsigned char *buffer) {
+		   struct scsi_request *SRpnt, unsigned char *buffer,
+		   int buf_len) 
+{
 	int len = 0, res;
 
 	const int dbd = 0;	   /* DBD */
@@ -1144,7 +1148,7 @@ sd_read_cache_type(struct scsi_disk *sdk
 		goto defaults;
 
 	/* cautiously ask */
-	res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4, &data);
+	res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4, buf_len, &data);
 
 	if (!scsi_status_is_good(res))
 		goto bad_sense;
@@ -1165,7 +1169,8 @@ sd_read_cache_type(struct scsi_disk *sdk
 	len += data.header_length + data.block_descriptor_length;
 
 	/* Get the data */
-	res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, len, &data);
+	res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, len, buf_len,
+			       &data);
 
 	if (scsi_status_is_good(res)) {
 		const char *types[] = {
@@ -1260,8 +1265,8 @@ static int sd_revalidate_disk(struct gen
 		sd_read_capacity(sdkp, disk->disk_name, sreq, buffer);
 		if (sdp->removable)
 			sd_read_write_protect_flag(sdkp, disk->disk_name,
-					sreq, buffer);
-		sd_read_cache_type(sdkp, disk->disk_name, sreq, buffer);
+					sreq, buffer, 512);
+		sd_read_cache_type(sdkp, disk->disk_name, sreq, buffer, 512);
 	}
 		
 	set_capacity(disk, sdkp->capacity);
diff -uprN -X /home/patman/dontdiff bl-25/drivers/scsi/sr.c modesense-bufflen-bk-2.5/drivers/scsi/sr.c
--- bl-25/drivers/scsi/sr.c	Wed Oct 22 13:30:58 2003
+++ modesense-bufflen-bk-2.5/drivers/scsi/sr.c	Mon Nov 10 15:32:16 2003
@@ -751,7 +751,7 @@ static void get_capabilities(struct scsi
 		   SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION)));
 
 	/* ask for mode page 0x2a */
-	rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128,
+	rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, 512,
 			     SR_TIMEOUT, 3, &data);
 
 	if (!scsi_status_is_good(rc)) {
diff -uprN -X /home/patman/dontdiff bl-25/include/scsi/scsi_device.h modesense-bufflen-bk-2.5/include/scsi/scsi_device.h
--- bl-25/include/scsi/scsi_device.h	Mon Oct 27 14:28:18 2003
+++ modesense-bufflen-bk-2.5/include/scsi/scsi_device.h	Mon Nov 10 15:28:43 2003
@@ -123,6 +123,6 @@ extern int scsi_track_queue_full(struct 
 extern int scsi_set_medium_removal(struct scsi_device *, char);
 
 extern int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
-			   unsigned char *buffer, int len, int timeout,
-			   int retries, struct scsi_mode_data *data);
+			   unsigned char *buffer, int len, int buf_len,
+			   int timeout, int retries, struct scsi_mode_data *data);
 #endif /* _SCSI_SCSI_DEVICE_H */
diff -uprN -X /home/patman/dontdiff bl-25/include/scsi/scsi_request.h modesense-bufflen-bk-2.5/include/scsi/scsi_request.h
--- bl-25/include/scsi/scsi_request.h	Mon Sep 22 13:09:11 2003
+++ modesense-bufflen-bk-2.5/include/scsi/scsi_request.h	Mon Nov 10 15:26:51 2003
@@ -66,7 +66,7 @@ struct scsi_mode_data {
 
 extern int __scsi_mode_sense(struct scsi_request *SRpnt, int dbd,
 			     int modepage, unsigned char *buffer, int len,
-			     int timeout, int retries,
+			     int buf_len, int timeout, int retries,
 			     struct scsi_mode_data *data);
 
 

^ permalink raw reply	[flat|nested] 68+ messages in thread

end of thread, other threads:[~2003-11-28 17:32 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-11-12 23:50 [PATCH] fix Sony USB mass storage - pass larger receive buffer Patrick Mansfield
2003-11-13  0:09 ` Matthew Dharm
2003-11-13  0:13   ` Patrick Mansfield
2003-11-13  0:44     ` Patrick Mansfield
2003-11-13  1:56       ` Matthew Dharm
2003-11-13 14:54         ` [usb-storage] " Alan Stern
2003-11-13 16:21           ` Pat LaVarre
2003-11-13 17:09             ` Alan Stern
2003-11-13 17:24               ` Pat LaVarre
2003-11-13 18:04                 ` Patrick Mansfield
2003-11-13 18:15                   ` Pat LaVarre
2003-11-13 18:22                     ` Pat LaVarre
2003-11-13 18:26                       ` Pat LaVarre
2003-11-13 18:37                         ` Pat LaVarre
2003-11-13 19:13                           ` Matthew Dharm
2003-11-13 19:30                             ` Pat LaVarre
2003-11-13 22:03                               ` Alan Stern
2003-11-13 23:40                                 ` Pat LaVarre
2003-11-13 23:51                                   ` Dmitri Katchalov
2003-11-14  0:16                                     ` Pat LaVarre
2003-11-14  1:04                                   ` Matthew Dharm
2003-11-14  1:10                                     ` Pat LaVarre
2003-11-14  1:13                                       ` Matthew Dharm
2003-11-13 22:01                 ` Alan Stern
2003-11-13 23:37                   ` Pat LaVarre
2003-11-14  0:24                     ` Patrick Mansfield
2003-11-14  1:54                       ` Pat LaVarre
2003-11-14  2:08                         ` Matthew Dharm
2003-11-14  2:24                           ` Pat LaVarre
2003-11-17 21:38                       ` Pat LaVarre
2003-11-17 22:00                         ` Patrick Mansfield
2003-11-17 23:36                           ` Pat LaVarre
2003-11-14  1:03                     ` Matthew Dharm
2003-11-13 23:44                   ` Pat LaVarre
2003-11-14  0:13                     ` Dmitri Katchalov
2003-11-14  0:55                       ` Pat LaVarre
2003-11-14  1:13                       ` Matthew Dharm
2003-11-14  2:02                         ` Pat LaVarre
2003-11-14  2:10                       ` Pat LaVarre
2003-11-14  2:19                         ` Matthew Dharm
2003-11-14  2:38                           ` [usb-storage] mode sense blacklist how Pat LaVarre
2003-11-14  2:44                             ` Matthew Dharm
2003-11-14 17:27                               ` Pat LaVarre
2003-11-14 17:57                                 ` Pat LaVarre
2003-11-14  3:11                             ` Dmitri Katchalov
2003-11-14 19:41                               ` Pat LaVarre
     [not found]                                 ` <20031114153607.A7207@beaverton.ibm.com>
     [not found]                                   ` <20031116121039.A13224@beaverton.ibm.com>
2003-11-17 20:14                                     ` Pat LaVarre
2003-11-19 12:55                                 ` Dmitri Katchalov
2003-11-19 16:34                                   ` Pat LaVarre
2003-11-19 17:02                                   ` Pat LaVarre
2003-11-19 23:34                                     ` Douglas Gilbert
2003-11-20 16:32                                       ` Pat LaVarre
2003-11-21  1:17                                         ` SG_IO ioctl (was: mode sense blacklist how) Douglas Gilbert
2003-11-21  3:18                                           ` Willem Riede
2003-11-21 20:51                                           ` Pat LaVarre
2003-11-28 17:07                                             ` Pat LaVarre
2003-11-28 17:14                                               ` Pat LaVarre
2003-11-28 17:31                                               ` Pat LaVarre
2003-11-28 17:09                                             ` Pat LaVarre
2003-11-21 21:29                                           ` Pat LaVarre
2003-11-20 14:06                                     ` [usb-storage] mode sense blacklist how Dmitri Katchalov
2003-11-20 15:57                                       ` Pat LaVarre
2003-11-14  1:06                     ` [usb-storage] Re: [PATCH] fix Sony USB mass storage - pass larger receive buffer Matthew Dharm
2003-11-14 16:14                     ` Alan Stern
2003-11-14 17:29                       ` Matthew Dharm
2003-11-14 17:50                       ` Pat LaVarre
2003-11-14  2:02 ` Douglas Gilbert
2003-11-14 21:45   ` [usb-storage] " Pat LaVarre

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).