lol
1The GuruPlug's microSD card reader is a USB mass storage device that
2has two logical units (LUNs), i.e., two "SCSI disks". This patch
3adds multi-LUN support to the USB MSD driver.
4
5See the thread at <http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/85425>.
6
7--- u-boot/common/usb_storage.c 1970-01-01 01:00:01.000000000 +0100
8+++ u-boot/common/usb_storage.c 2010-10-02 00:38:15.000000000 +0200
9@@ -204,6 +204,22 @@ int usb_stor_info(void)
10 return 1;
11 }
12
13+static unsigned int usb_get_max_lun(struct us_data *us)
14+{
15+ int len;
16+ unsigned char result;
17+ len = usb_control_msg(us->pusb_dev,
18+ usb_rcvctrlpipe(us->pusb_dev, 0),
19+ US_BBB_GET_MAX_LUN,
20+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
21+ 0, us->ifnum,
22+ &result, sizeof(result),
23+ USB_CNTL_TIMEOUT * 5);
24+ USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
25+ len, (int) result);
26+ return (len > 0) ? result : 0;
27+}
28+
29 /*******************************************************************************
30 * scan the usb and reports device info
31 * to the user if mode = 1
32@@ -241,13 +257,21 @@ int usb_stor_scan(int mode)
33 break; /* no more devices avaiable */
34
35 if (usb_storage_probe(dev, 0, &usb_stor[usb_max_devs])) {
36- /* ok, it is a storage devices
37- * get info and fill it in
38- */
39- if (usb_stor_get_info(dev, &usb_stor[usb_max_devs],
40- &usb_dev_desc[usb_max_devs]) == 1)
41+ /* OK, it's a storage device. Iterate over its LUNs
42+ * and populate `usb_dev_desc'. */
43+ int lun, max_lun, start = usb_max_devs;
44+
45+ max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]);
46+ for (lun = 0;
47+ lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV;
48+ lun++) {
49+ usb_dev_desc[usb_max_devs].lun = lun;
50+ if (usb_stor_get_info(dev, &usb_stor[start],
51+ &usb_dev_desc[usb_max_devs]) == 1) {
52 usb_max_devs++;
53 }
54+ }
55+ }
56 /* if storage device */
57 if (usb_max_devs == USB_MAX_STOR_DEV) {
58 printf("max USB Storage Device reached: %d stopping\n",
59@@ -882,6 +906,7 @@ static int usb_inquiry(ccb *srb, struct
60 do {
61 memset(&srb->cmd[0], 0, 12);
62 srb->cmd[0] = SCSI_INQUIRY;
63+ srb->cmd[1] = srb->lun << 5;
64 srb->cmd[4] = 36;
65 srb->datalen = 36;
66 srb->cmdlen = 12;
67@@ -905,6 +930,7 @@ static int usb_request_sense(ccb *srb, s
68 ptr = (char *)srb->pdata;
69 memset(&srb->cmd[0], 0, 12);
70 srb->cmd[0] = SCSI_REQ_SENSE;
71+ srb->cmd[1] = srb->lun << 5;
72 srb->cmd[4] = 18;
73 srb->datalen = 18;
74 srb->pdata = &srb->sense_buf[0];
75@@ -924,6 +950,7 @@ static int usb_test_unit_ready(ccb *srb,
76 do {
77 memset(&srb->cmd[0], 0, 12);
78 srb->cmd[0] = SCSI_TST_U_RDY;
79+ srb->cmd[1] = srb->lun << 5;
80 srb->datalen = 0;
81 srb->cmdlen = 12;
82 if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD)
83@@ -943,6 +970,7 @@ static int usb_read_capacity(ccb *srb, s
84 do {
85 memset(&srb->cmd[0], 0, 12);
86 srb->cmd[0] = SCSI_RD_CAPAC;
87+ srb->cmd[1] = srb->lun << 5;
88 srb->datalen = 8;
89 srb->cmdlen = 12;
90 if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD)
91@@ -957,6 +985,7 @@ static int usb_read_10(ccb *srb, struct
92 {
93 memset(&srb->cmd[0], 0, 12);
94 srb->cmd[0] = SCSI_READ10;
95+ srb->cmd[1] = srb->lun << 5;
96 srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff;
97 srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff;
98 srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff;
99@@ -973,6 +1002,7 @@ static int usb_write_10(ccb *srb, struct
100 {
101 memset(&srb->cmd[0], 0, 12);
102 srb->cmd[0] = SCSI_WRITE10;
103+ srb->cmd[1] = srb->lun << 5;
104 srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff;
105 srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff;
106 srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff;