This patch alters the CSW signature checking code to work with devices that report non-standard signatures, such as some Olympus and Aldi cameras.

We now learn the first signature we see, and use it to check signatures of all subsequent transfers. This allows us to continue to benefit from the error-checking capabilities of the signature transfer, while becoming compatible with (yet more) non-standard devices.

Suggestion from Alan Stern.

Signed-off-by: Daniel Drake <[EMAIL PROTECTED]>
--- linux/drivers/usb/storage/transport.c.orig	2005-02-01 16:39:39.527908368 +0000
+++ linux/drivers/usb/storage/transport.c	2005-02-01 18:10:26.038912840 +0000
@@ -1047,14 +1047,26 @@ int usb_stor_Bulk_transport(struct scsi_
 	US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",
 			le32_to_cpu(bcs->Signature), bcs->Tag, 
 			residue, bcs->Status);
-	if ((bcs->Signature != cpu_to_le32(US_BULK_CS_SIGN) &&
-		    bcs->Signature != cpu_to_le32(US_BULK_CS_OLYMPUS_SIGN)) ||
-			bcs->Tag != srb->serial_number || 
-			bcs->Status > US_BULK_STAT_PHASE) {
+	if (bcs->Tag != srb->serial_number || bcs->Status > US_BULK_STAT_PHASE) {
 		US_DEBUGP("Bulk logical error\n");
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
+	/* Some broken devices report odd signatures, so we do not check them
+	 * for validity against the spec. We store the first one we see,
+	 * and check subsequent transfers for validity against this signature.
+	 */
+	if (!us->bcs_signature) {
+		us->bcs_signature = bcs->Signature;
+		US_DEBUGP("Learnt BCS signature 0x%08X\n",
+			  le32_to_cpu(us->bcs_signature));
+	} else if (bcs->Signature != us->bcs_signature) {
+		US_DEBUGP("Signature mismatch: device sent %08X, expecting %08X",
+			  le32_to_cpu(bcs->Signature),
+			  le32_to_cpu(us->bcs_signature));
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+
 	/* try to compute the actual residue, based on how much data
 	 * was really transferred and what the device tells us */
 	if (residue) {
--- linux/drivers/usb/storage/transport.h.orig	2005-02-01 17:57:15.195139368 +0000
+++ linux/drivers/usb/storage/transport.h	2005-02-01 17:58:13.182323976 +0000
@@ -107,9 +107,6 @@ struct bulk_cs_wrap {
 };
 
 #define US_BULK_CS_WRAP_LEN	13
-#define US_BULK_CS_SIGN		0x53425355	/* spells out 'USBS' */
-/* This is for Olympus Camedia digital cameras */
-#define US_BULK_CS_OLYMPUS_SIGN		0x55425355	/* spells out 'USBU' */
 #define US_BULK_STAT_OK		0
 #define US_BULK_STAT_FAIL	1
 #define US_BULK_STAT_PHASE	2
--- linux/drivers/usb/storage/usb.h.orig	2005-02-01 17:30:01.917435320 +0000
+++ linux/drivers/usb/storage/usb.h	2005-02-01 17:57:08.415170080 +0000
@@ -125,6 +125,7 @@ struct us_data {
 	char			serial[USB_STOR_STRING_LEN];
 	char			*transport_name;
 	char			*protocol_name;
+	__le32			bcs_signature;
 	u8			subclass;
 	u8			protocol;
 	u8			max_lun;

Reply via email to