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);