[PATCH 2.6.30 1/1] usb-storage: handle unusual dev Realtek Usb Card Reader (0x0bda:0x0152)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds support for a Realtek Usb Card Reader (0x0bda:0x0152), 
treating it as unusual device. This card reader provides four slots to handle 
different cards but only the first one (for compact flash) is detected, while the 
others are not. This occurs due to the fact that the device doesn't seem to 
provide correct information in GetMaxLUN and us->max_lun is set to 0.
The patch also provides a flag (US_FL_SKIP_MAX_LUN) needed to skip GetMaxLUN 
and to allow us->max_lun to be set in its init function. The flag can 
eventually be used for other devices that require the same handling.

Signed-off-by: Giacomo Lozito <james@xxxxxxxxxxx>
---

This device is provided by Realtek for the desktop pc HP Pavilion m9567 (and 
similar models, I suppose). The device is installed in the front bay but it's 
actually a usb device (vid=0x0bda pid=0x0152).

Looking around on the web, it seems that few linux users have run into this 
device so far (there's no mention of it being supported or not, except for a 
couple of cases about people with the same issue which stood unresolved).
So I decided to figure it out myself.

I'm using a vanilla kernel 2.6.30 with CONFIG_SCSI_MULTI_LUN enabled.

This is what I have before the patch is applied:

scsi 6:0:0:0: Direct-Access     Generic- Compact Flash    1.00 PQ: 0 ANSI: 0 
CCS
sd 6:0:0:0: Attached scsi generic sg2 type 0
sd 6:0:0:0: [sdb] Attached SCSI removable disk



This is what I (correctly) have after the patch has been applied:

scsi 6:0:0:0: Direct-Access     Generic- Compact Flash    1.00 PQ: 0 ANSI: 0 
CCS
sd 6:0:0:0: Attached scsi generic sg2 type 0
sd 6:0:0:0: [sdb] Attached SCSI removable disk
scsi 6:0:0:1: Direct-Access     Generic- SM/xD-Picture    1.00 PQ: 0 ANSI: 0 
CCS
sd 6:0:0:1: Attached scsi generic sg3 type 0
sd 6:0:0:1: [sdc] Attached SCSI removable disk
scsi 6:0:0:2: Direct-Access     Generic- SD/MMC           1.00 PQ: 0 ANSI: 0 
CCS
sd 6:0:0:2: Attached scsi generic sg4 type 0
sd 6:0:0:2: [sdd] Attached SCSI removable disk
scsi 6:0:0:3: Direct-Access     Generic- MS/MS-Pro        1.00 PQ: 0 ANSI: 0 
CCS
sd 6:0:0:3: Attached scsi generic sg5 type 0
sd 6:0:0:3: [sde] Attached SCSI removable disk



Debug for usb-storage and GetMaxLun before the patch was applied:

Jul  1 01:10:12 bahamut kernel: usb-storage: usb_stor_control_msg: rq=fe 
rqtype=a1 value=0000 index=00 len=1
Jul  1 01:10:12 bahamut kernel: usb-storage: Timeout -- cancelling URB
Jul  1 01:10:12 bahamut kernel: usb-storage: GetMaxLUN command result is -2, 
data is 0



As requested in unusual_devs.h, this is my /proc/bus/usb/devices after 
patching:


T:  Bus=08 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12  MxCh= 2
B:  Alloc= 13/900 us ( 1%), #Int=  1, #Iso=  0
D:  Ver= 1.10 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0001 Rev= 2.06
S:  Manufacturer=Linux 2.6.30-smp uhci_hcd
S:  Product=UHCI Host Controller
S:  SerialNumber=0000:00:1d.3
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   2 Ivl=255ms

T:  Bus=08 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=1.5 MxCh= 0
D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=051d ProdID=0002 Rev= 1.06
S:  Manufacturer=American Power Conversion
S:  Product=Back-UPS BR  800 FW:9.o4 .I USB FW:o4 
S:  SerialNumber=BB0100009999  
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr= 24mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid
E:  Ad=81(I) Atr=03(Int.) MxPS=   6 Ivl=10ms

T:  Bus=07 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12  MxCh= 2
B:  Alloc=  0/900 us ( 0%), #Int=  0, #Iso=  0
D:  Ver= 1.10 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0001 Rev= 2.06
S:  Manufacturer=Linux 2.6.30-smp uhci_hcd
S:  Product=UHCI Host Controller
S:  SerialNumber=0000:00:1d.2
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   2 Ivl=255ms

T:  Bus=06 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12  MxCh= 2
B:  Alloc=  0/900 us ( 0%), #Int=  0, #Iso=  0
D:  Ver= 1.10 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0001 Rev= 2.06
S:  Manufacturer=Linux 2.6.30-smp uhci_hcd
S:  Product=UHCI Host Controller
S:  SerialNumber=0000:00:1d.1
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   2 Ivl=255ms

T:  Bus=05 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12  MxCh= 2
B:  Alloc=  0/900 us ( 0%), #Int=  0, #Iso=  0
D:  Ver= 1.10 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0001 Rev= 2.06
S:  Manufacturer=Linux 2.6.30-smp uhci_hcd
S:  Product=UHCI Host Controller
S:  SerialNumber=0000:00:1d.0
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   2 Ivl=255ms

T:  Bus=04 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12  MxCh= 2
B:  Alloc= 29/900 us ( 3%), #Int=  3, #Iso=  0
D:  Ver= 1.10 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0001 Rev= 2.06
S:  Manufacturer=Linux 2.6.30-smp uhci_hcd
S:  Product=UHCI Host Controller
S:  SerialNumber=0000:00:1a.1
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   2 Ivl=255ms

T:  Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=12  MxCh= 4
D:  Ver= 1.10 Cls=09(hub  ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=046d ProdID=c223 Rev= 1.03
S:  Manufacturer=Logitech
S:  Product=Logitech G15 Keyboard
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   1 Ivl=255ms

T:  Bus=04 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#=  3 Spd=1.5 MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=046d ProdID=c221 Rev= 1.70
S:  Manufacturer=Logitech
S:  Product=Logitech Gaming Keyboard
C:* #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=01 Driver=usbhid
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=10ms
I:* If#= 1 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid
E:  Ad=82(I) Atr=03(Int.) MxPS=   8 Ivl=10ms

T:  Bus=04 Lev=02 Prnt=02 Port=03 Cnt=02 Dev#=  4 Spd=12  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=046d ProdID=c222 Rev= 1.03
S:  Manufacturer=G15 Keyboard
S:  Product=G15 Keyboard
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbfs
E:  Ad=81(I) Atr=03(Int.) MxPS=  32 Ivl=1ms
E:  Ad=02(O) Atr=03(Int.) MxPS=  32 Ivl=1ms

T:  Bus=03 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12  MxCh= 2
B:  Alloc=  0/900 us ( 0%), #Int=  0, #Iso=  0
D:  Ver= 1.10 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0001 Rev= 2.06
S:  Manufacturer=Linux 2.6.30-smp uhci_hcd
S:  Product=UHCI Host Controller
S:  SerialNumber=0000:00:1a.0
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   2 Ivl=255ms

T:  Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480 MxCh= 8
B:  Alloc=  0/800 us ( 0%), #Int=  2, #Iso=  0
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0002 Rev= 2.06
S:  Manufacturer=Linux 2.6.30-smp ehci_hcd
S:  Product=EHCI Host Controller
S:  SerialNumber=0000:00:1d.7
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=256ms

T:  Bus=02 Lev=01 Prnt=01 Port=04 Cnt=01 Dev#=  2 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=0bda ProdID=0152 Rev=51.95
S:  Manufacturer=Generic
S:  Product=USB2.0-CRW
S:  SerialNumber=20060413092100000
C:* #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=500mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid
E:  Ad=83(I) Atr=03(Int.) MxPS=   1 Ivl=64ms

T:  Bus=02 Lev=01 Prnt=01 Port=07 Cnt=02 Dev#=  4 Spd=480 MxCh= 4
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=05e3 ProdID=0605 Rev= 6.0b
S:  Product=USB2.0 Hub
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   1 Ivl=256ms

T:  Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480 MxCh= 4
B:  Alloc=  0/800 us ( 0%), #Int=  0, #Iso=  0
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0002 Rev= 2.06
S:  Manufacturer=Linux 2.6.30-smp ehci_hcd
S:  Product=EHCI Host Controller
S:  SerialNumber=0000:00:1a.7
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=256ms


Best regards,
Giacomo Lozito
--- linux-2.6.30.vanilla/include/linux/usb_usual.h	2009-06-10 05:05:27.000000000 +0200
+++ linux-2.6.30/include/linux/usb_usual.h	2009-07-01 01:31:55.000000000 +0200
@@ -56,7 +56,9 @@
 	US_FLAG(SANE_SENSE,     0x00008000)			\
 		/* Sane Sense (> 18 bytes) */			\
 	US_FLAG(CAPACITY_OK,	0x00010000)			\
-		/* READ CAPACITY response is correct */
+		/* READ CAPACITY response is correct */		\
+	US_FLAG(SKIP_MAX_LUN,	0x00020000)			\
+		/* skip max lun detection */
 
 #define US_FLAG(name, value)	US_FL_##name = value ,
 enum { US_DO_ALL_FLAGS };
diff -ur linux-2.6.30.vanilla/drivers/usb/storage/initializers.c linux-2.6.30/drivers/usb/storage/initializers.c
--- linux-2.6.30.vanilla/drivers/usb/storage/initializers.c	2009-06-10 05:05:27.000000000 +0200
+++ linux-2.6.30/drivers/usb/storage/initializers.c	2009-07-01 01:39:55.000000000 +0200
@@ -102,3 +102,12 @@
 	US_DEBUGP("usb_control_msg performing result is %d\n", result);
 	return (result ? 0 : -1);
 }
+
+/* This function is required to activate all four slots on the Realtek
+ * USB Card Reader (0bda:0152) */
+int usb_stor_realtek_pid0152_init(struct us_data *us)
+{
+	US_DEBUGP("Forcing max_lun to 3 for Realtek USB Card Reader (0bda:0152)...\n");
+	us->max_lun = 3;
+	return 0;
+}
diff -ur linux-2.6.30.vanilla/drivers/usb/storage/initializers.h linux-2.6.30/drivers/usb/storage/initializers.h
--- linux-2.6.30.vanilla/drivers/usb/storage/initializers.h	2009-06-10 05:05:27.000000000 +0200
+++ linux-2.6.30/drivers/usb/storage/initializers.h	2009-07-01 01:40:11.000000000 +0200
@@ -48,3 +48,7 @@
 
 /* This places the HUAWEI E220 devices in multi-port mode */
 int usb_stor_huawei_e220_init(struct us_data *us);
+
+/* This function is required to activate all four slots on the Realtek
+ * USB Card Reader (0bda:0152) */
+int usb_stor_realtek_pid0152_init(struct us_data *us);
diff -ur linux-2.6.30.vanilla/drivers/usb/storage/unusual_devs.h linux-2.6.30/drivers/usb/storage/unusual_devs.h
--- linux-2.6.30.vanilla/drivers/usb/storage/unusual_devs.h	2009-06-10 05:05:27.000000000 +0200
+++ linux-2.6.30/drivers/usb/storage/unusual_devs.h	2009-07-01 01:33:57.000000000 +0200
@@ -1169,6 +1169,13 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_SANE_SENSE ),
 
+/* Reported by Giacomo Lozito <james@xxxxxxxxxxx> */
+UNUSUAL_DEV( 0x0bda, 0x0152, 0x0000, 0x9999,
+                "Realtek",
+                "USB Card Reader",
+		US_SC_DEVICE, US_PR_DEVICE, usb_stor_realtek_pid0152_init,
+		US_FL_SKIP_MAX_LUN ),
+
 UNUSUAL_DEV(  0x0d49, 0x7310, 0x0000, 0x9999,
 		"Maxtor",
 		"USB to SATA",
Only in linux-2.6.30/drivers/usb/storage: usb-storage.o
diff -ur linux-2.6.30.vanilla/drivers/usb/storage/usb.c linux-2.6.30/drivers/usb/storage/usb.c
--- linux-2.6.30.vanilla/drivers/usb/storage/usb.c	2009-06-10 05:05:27.000000000 +0200
+++ linux-2.6.30/drivers/usb/storage/usb.c	2009-07-01 01:35:15.000000000 +0200
@@ -826,7 +826,8 @@
 
 		/* For bulk-only devices, determine the max LUN value */
 		if (us->protocol == US_PR_BULK &&
-				!(us->fflags & US_FL_SINGLE_LUN)) {
+				!(us->fflags & US_FL_SINGLE_LUN) &&
+                                !(us->fflags & US_FL_SKIP_MAX_LUN)) {
 			mutex_lock(&us->dev_mutex);
 			us->max_lun = usb_stor_Bulk_max_lun(us);
 			mutex_unlock(&us->dev_mutex);

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux