This patch adds USB capabilities to libpayload. It requires some
[coreboot.git] / payloads / libpayload / drivers / usb / usbmsc.c
1 /*
2  * This file is part of the libpayload project.
3  *
4  * Copyright (C) 2008 coresystems GmbH
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <arch/endian.h>
31 #include "usb.h"
32 #include "usbmsc.h"
33 #include "usbdisk.h"
34
35 enum {
36         msc_subclass_rbc = 0x1,
37         msc_subclass_mmc2 = 0x2,
38         msc_subclass_qic157 = 0x3,
39         msc_subclass_ufi = 0x4,
40         msc_subclass_sff8070i = 0x5,
41         msc_subclass_scsitrans = 0x6
42 };
43 static const char *msc_subclass_strings[7] = {
44         "(none)",
45         "RBC",
46         "MMC-2",
47         "QIC-157",
48         "UFI",
49         "SFF-8070i",
50         "SCSI transparent"
51 };
52 enum {
53         msc_proto_cbi_wcomp = 0x0,
54         msc_proto_cbi_wocomp = 0x1,
55         msc_proto_bulk_only = 0x50
56 };
57 static const char *msc_protocol_strings[0x51] = {
58         "Control/Bulk/Interrupt protocol (with command completion interrupt)",
59         "Control/Bulk/Interrupt protocol (with no command completion interrupt)",
60         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65         "Bulk-Only Transport"
66 };
67
68
69 static void
70 usb_msc_destroy (usbdev_t *dev)
71 {
72         usbdisk_remove (dev);
73         free (dev->data);
74         dev->data = 0;
75 }
76
77 static void
78 usb_msc_poll (usbdev_t *dev)
79 {
80 }
81
82 const int DEV_RESET = 0xff;
83 const int GET_MAX_LUN = 0xfe;
84
85 const unsigned int cbw_signature = 0x43425355;
86 const unsigned int csw_signature = 0x53425355;
87
88 typedef struct {
89         unsigned int dCBWSignature;
90         unsigned int dCBWTag;
91         unsigned int dCBWDataTransferLength;
92         unsigned char bmCBWFlags;
93         unsigned long bCBWLUN:4;
94         unsigned long:4;
95         unsigned long bCBWCBLength:5;
96         unsigned long:3;
97         unsigned char CBWCB[31 - 15];
98 } __attribute__ ((packed))
99      cbw_t;
100
101      typedef struct {
102              unsigned int dCSWSignature;
103              unsigned int dCSWTag;
104              unsigned int dCSWDataResidue;
105              unsigned char bCSWStatus;
106      } __attribute__ ((packed))
107      csw_t;
108
109      static void
110        reset_transport (usbdev_t *dev)
111 {
112         dev_req_t dr;
113         memset (&dr, 0, sizeof (dr));
114         dr.bmRequestType = 0;
115         dr.data_dir = host_to_device;
116 #ifndef QEMU
117         dr.req_type = class_type;
118         dr.req_recp = iface_recp;
119 #endif
120         dr.bRequest = DEV_RESET;
121         dr.wValue = 0;
122         dr.wIndex = 0;
123         dr.wLength = 0;
124         dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0);
125         clear_stall (MSC_INST (dev)->bulk_in);
126         clear_stall (MSC_INST (dev)->bulk_out);
127 }
128
129 /* device may stall this command, so beware! */
130 static int
131 get_max_luns (usbdev_t *dev)
132 {
133         unsigned char luns = 75;
134         dev_req_t dr;
135         dr.bmRequestType = 0;
136         dr.data_dir = device_to_host;
137 #ifndef QEMU
138         dr.req_type = class_type;
139         dr.req_recp = iface_recp;
140 #endif
141         dr.bRequest = GET_MAX_LUN;
142         dr.wValue = 0;
143         dr.wIndex = 0;
144         dr.wLength = 1;
145         if (dev->controller->control (dev, IN, sizeof (dr), &dr, 1, &luns)) {
146                 luns = 0;       // assume only 1 lun if req fails
147         }
148         return luns;
149 }
150
151 int tag;
152 int lun = 0;
153
154 static void
155 wrap_cbw (cbw_t *cbw, int datalen, cbw_direction dir, const u8 *cmd,
156           int cmdlen)
157 {
158         memset (cbw, 0, sizeof (cbw_t));
159
160         cbw->dCBWSignature = cbw_signature;
161         cbw->dCBWTag = tag++;
162         cbw->bCBWLUN = lun;     // static value per device
163
164         cbw->dCBWDataTransferLength = datalen;
165         cbw->bmCBWFlags = dir;
166         memcpy (cbw->CBWCB, cmd, sizeof (cbw->CBWCB));
167         cbw->bCBWCBLength = cmdlen;
168 }
169
170 static void
171 get_csw (endpoint_t *ep, csw_t *csw)
172 {
173         ep->dev->controller->bulk (ep, sizeof (csw_t), (u8 *) csw, 1);
174 }
175
176 static int
177 execute_command (usbdev_t *dev, cbw_direction dir, const u8 *cb, int cblen,
178                  u8 *buf, int buflen)
179 {
180         cbw_t cbw;
181         csw_t csw;
182
183         int always_succeed = 0;
184         if ((cb[0] == 0x1b) && (cb[4] == 1)) {  //start command, always succeed
185                 always_succeed = 1;
186         }
187         wrap_cbw (&cbw, buflen, dir, cb, cblen);
188         if (dev->controller->
189             bulk (MSC_INST (dev)->bulk_out, sizeof (cbw), (u8 *) &cbw, 0)) {
190                 clear_stall (MSC_INST (dev)->bulk_out);
191                 return 1;
192         }
193         mdelay (10);
194         if (dir == cbw_direction_data_in) {
195                 if (dev->controller->
196                     bulk (MSC_INST (dev)->bulk_in, buflen, buf, 0)) {
197                         clear_stall (MSC_INST (dev)->bulk_in);
198                         return 1;
199                 }
200         } else {
201                 if (dev->controller->
202                     bulk (MSC_INST (dev)->bulk_out, buflen, buf, 0)) {
203                         clear_stall (MSC_INST (dev)->bulk_out);
204                         return 1;
205                 }
206         }
207         get_csw (MSC_INST (dev)->bulk_in, &csw);
208         if (always_succeed == 1) {
209                 // return success, regardless of message
210                 return 0;
211         }
212         if (csw.bCSWStatus == 2) {
213                 // phase error, reset transport
214                 reset_transport (dev);
215                 return 1;
216         }
217         if (csw.bCSWStatus == 0) {
218                 // no error, exit
219                 return 0;
220         }
221         // error "check condition" or reserved error
222         return 1;
223 }
224
225 typedef struct {
226         unsigned char command;  //0
227         unsigned char res1;     //1
228         unsigned int block;     //2-5
229         unsigned char res2;     //6
230         unsigned short numblocks;       //7-8
231         unsigned char res3;     //9 - the block is 10 bytes long
232 } __attribute__ ((packed)) cmdblock_t;
233
234 typedef struct {
235         unsigned char command;  //0
236         unsigned char res1;     //1
237         unsigned char res2;     //2
238         unsigned char res3;     //3
239         unsigned char lun;      //4
240         unsigned char res4;     //5
241 } __attribute__ ((packed)) cmdblock6_t;
242
243
244 /**
245  * Reads or writes a number of sequential blocks on a USB storage device.
246  * As it uses the READ(10) SCSI-2 command, it's limited to storage devices
247  * of at most 2TB. It assumes sectors of 512 bytes.
248  *
249  * @param dev device to access
250  * @param start first sector to access
251  * @param n number of sectors to access
252  * @param dir direction of access: cbw_direction_data_in == read, cbw_direction_data_out == write
253  * @param buf buffer to read into or write from. Must be at least n*512 bytes
254  * @return 0 on success, 1 on failure
255  */
256 int
257 readwrite_blocks (usbdev_t *dev, int start, int n, cbw_direction dir, u8 *buf)
258 {
259         cmdblock_t cb;
260         memset (&cb, 0, sizeof (cb));
261         if (dir == cbw_direction_data_in) {
262                 // read
263                 cb.command = 0x28;
264         } else {
265                 // write
266                 cb.command = 0x2a;
267         }
268         cb.block = ntohl (start);
269         cb.numblocks = ntohw (n);
270         return execute_command (dev, dir, (u8 *) &cb, sizeof (cb), buf,
271                                 n * 512);
272 }
273
274 static int
275 test_unit_ready (usbdev_t *dev)
276 {
277         cmdblock6_t cb;
278         memset (&cb, 0, sizeof (cb));   // full initialization for T-U-R
279         return execute_command (dev, cbw_direction_data_out, (u8 *) &cb,
280                                 sizeof (cb), 0, 0);
281 }
282
283 static int
284 spin_up (usbdev_t *dev)
285 {
286         cmdblock6_t cb;
287         memset (&cb, 0, sizeof (cb));
288         cb.command = 0x1b;
289         cb.lun = 1;
290         return execute_command (dev, cbw_direction_data_out, (u8 *) &cb,
291                                 sizeof (cb), 0, 0);
292 }
293
294 static void
295 read_capacity (usbdev_t *dev)
296 {
297         cmdblock_t cb;
298         memset (&cb, 0, sizeof (cb));
299         cb.command = 0x25;      // read capacity
300         u8 buf[8];
301         int count = 0;
302         while ((count++ < 20)
303                &&
304                (execute_command
305                 (dev, cbw_direction_data_in, (u8 *) &cb, sizeof (cb), buf,
306                  8) == 1));
307         if (count >= 20) {
308                 // still not successful, assume 2tb in 512byte sectors, which is just the same garbage as any other number, but probably reasonable.
309                 printf ("assuming 2TB in 512byte sectors as READ CAPACITY didn't answer.\n");
310                 MSC_INST (dev)->numblocks = 0xffffffff;
311                 MSC_INST (dev)->blocksize = 512;
312         } else {
313                 MSC_INST (dev)->numblocks = ntohl (*(u32 *) buf) + 1;
314                 MSC_INST (dev)->blocksize = ntohl (*(u32 *) (buf + 4));
315         }
316         printf ("  has %d blocks sized %db\n", MSC_INST (dev)->numblocks,
317                 MSC_INST (dev)->blocksize);
318 }
319
320 void
321 usb_msc_init (usbdev_t *dev)
322 {
323         int i, timeout;
324
325         dev->destroy = usb_msc_destroy;
326         dev->poll = usb_msc_poll;
327
328         configuration_descriptor_t *cd =
329                 (configuration_descriptor_t *) dev->configuration;
330         interface_descriptor_t *interface =
331                 (interface_descriptor_t *) (((char *) cd) + cd->bLength);
332
333         printf ("  it uses %s command set\n",
334                 msc_subclass_strings[interface->bInterfaceSubClass]);
335         printf ("  it uses %s protocol\n",
336                 msc_protocol_strings[interface->bInterfaceProtocol]);
337
338         if ((interface->bInterfaceProtocol != 0x50)
339             || (interface->bInterfaceSubClass != 6)) {
340                 /* Other protocols, such as ATAPI don't seem to be very popular. looks like ATAPI would be really easy to add, if necessary. */
341                 printf ("  Only SCSI over Bulk is supported.\n");
342                 return;
343         }
344
345         dev->data = malloc (sizeof (usbmsc_inst_t));
346         MSC_INST (dev)->bulk_in = 0;
347         MSC_INST (dev)->bulk_out = 0;
348
349         for (i = 1; i <= dev->num_endp; i++) {
350                 if (dev->endpoints[i].endpoint == 0)
351                         continue;
352                 if (dev->endpoints[i].type != BULK)
353                         continue;
354                 if ((dev->endpoints[i].direction == IN)
355                     && (MSC_INST (dev)->bulk_in == 0))
356                         MSC_INST (dev)->bulk_in = &dev->endpoints[i];
357                 if ((dev->endpoints[i].direction == OUT)
358                     && (MSC_INST (dev)->bulk_out == 0))
359                         MSC_INST (dev)->bulk_out = &dev->endpoints[i];
360         }
361
362         if (MSC_INST (dev)->bulk_in == 0)
363                 fatal ("couldn't find bulk-in endpoint");
364         if (MSC_INST (dev)->bulk_out == 0)
365                 fatal ("couldn't find bulk-out endpoint");
366         printf ("  using endpoint %x as in, %x as out\n",
367                 MSC_INST (dev)->bulk_in->endpoint,
368                 MSC_INST (dev)->bulk_out->endpoint);
369
370         printf ("  has %d luns\n", get_max_luns (dev) + 1);
371
372         printf ("  Waiting for device to become ready... ");
373         timeout = 10;
374         while (test_unit_ready (dev) && --timeout) {
375                 mdelay (100);
376                 printf (".");
377         }
378         if (test_unit_ready (dev)) {
379                 printf ("timeout. Device not ready. Still trying...\n");
380         } else {
381                 printf ("ok.\n");
382         }
383
384         printf ("  spin up");
385         for (i = 0; i < 30; i++) {
386                 printf (".");
387                 if (!spin_up (dev)) {
388                         printf (" OK.");
389                         break;
390                 }
391                 mdelay (100);
392         }
393         printf ("\n");
394
395         read_capacity (dev);
396         usbdisk_create (dev);
397 }