2 * USB mass storage driver - just like the one Elvis used!
8 #include <kernel/list.h>
11 #include "threads/malloc.h"
12 #include "threads/palloc.h"
13 #include "threads/thread.h"
14 #include "devices/timer.h"
15 #include "threads/synch.h"
16 #include "threads/pte.h"
17 #include "devices/usb.h"
18 #include "devices/block.h"
19 #include "devices/partition.h"
20 #include "devices/usb_storage.h"
22 //http://www.usb.org/developers/defined_class
23 #define USB_CLASS_MASS_STORAGE 0x08
25 #define USB_SUBCLASS_RBC 0x01 /* reduced block commands */
26 #define USB_SUBCLASS_ATAPI 0x02 /* ATAPI - CD's */
27 #define USB_SUBCLASS_TAPE 0x03
28 #define USB_SUBCLASS_UFI 0x04 /* floppy disk */
29 #define USB_SUBCLASS_SFF8070 0x05
30 #define USB_SUBCLASS_SCSI 0x06 /* scsi transparent command set */
32 #define USB_PROTO_COMPLETE 0x00
33 #define USB_PROTO_NO_COMPLETE 0x01
34 #define USB_PROTO_BULK 0x50
38 #define CBW_SIG_MAGIC 0x43425355
40 #define CBW_FL_IN (1 << 7)
43 /** usbmassbulk_10.pdf - pg 13 */
44 /* command block wrapper */
52 uint8_t cb_len; /* command block length */
53 uint8_t cb[16]; /* command block */
56 #define CSW_SIG_MAGIC 0x53425355
57 #define CSW_STATUS_PASSED 0
58 #define CSW_STATUS_FAILED 1
59 #define CSW_STATUS_PHASE 2 /* phase error */
60 /* command status wrapper */
108 struct scsi_capacity10
114 #define SCSI_OP_WRITE6 0xa
115 #define SCSI_OP_READ6 0x8
116 #define SCSI_OP_TEST_READY 0x00
117 #define SCSI_OP_SEEK8 0x0b
118 #define SCSI_OP_MODE_SENSE8 0x1a
119 #define SCSI_OP_MODE_SELECT8 0x15
120 #define SCSI_OP_READ_CAPACITY10 0x25
121 #define SCSI_OP_READ_CAPACITY16 0x9e
122 #define SCSI_OP_WRITE10 0x2a
123 #define SCSI_OP_READ10 0x28
124 #define SCSI_OP_SEEK10 0x2b
125 #define SCSI_OP_MODE_SENSE10 0x5a
126 #define SCSI_OP_MODE_SELECT10 0x55
131 static void *msc_attached (struct usb_iface *);
132 static void msc_detached (class_info);
134 static void msc_reset_endpoint (struct usb_endpoint *eop);
136 static struct usb_class storage_class = {
137 .attached = msc_attached,
138 .detached = msc_detached,
139 .name = "Mass Storage",
140 .class_id = USB_CLASS_MASS_STORAGE
143 #define mci_lock(x) lock_acquire(&(x)->lock)
144 #define mci_unlock(x) lock_release(&(x)->lock)
146 struct msc_class_info
150 struct usb_iface *ui;
157 struct usb_endpoint *eop_in;
158 struct usb_endpoint *eop_out;
159 struct list_elem peers;
161 static void msc_get_geometry (struct msc_class_info *);
162 static void msc_io (struct msc_class_info *, block_sector_t, void *buf, bool wr);
163 static void msc_reset_recovery(struct msc_class_info* mci);
164 static void msc_bulk_reset(struct msc_class_info* mci);
168 struct msc_class_info *mci;
171 static struct list device_list;
172 static struct block_operations msc_operations;
174 void usb_storage_init (void);
177 usb_storage_init (void)
179 list_init (&device_list);
180 usb_register_class (&storage_class);
185 msc_attached (struct usb_iface *ui)
189 struct msc_class_info *mci;
190 struct msc_blk_info *mbi;
191 struct list_elem *li;
195 if (ui->subclass_id != USB_SUBCLASS_SCSI)
197 printf ("usb_storage: Only support SCSI-type devices\n");
201 mci = malloc (sizeof (struct msc_class_info));
204 mci->retrying = false;
205 lock_init (&mci->lock);
207 list_push_back (&device_list, &mci->peers);
210 li = list_begin (&ui->endpoints);
213 while (li != list_end (&ui->endpoints))
215 struct usb_endpoint *ue;
217 ue = list_entry (li, struct usb_endpoint, peers);
220 if (ue->attr == USB_EOP_ATTR_BULK)
222 if (ue->direction == 0)
229 ASSERT (mci->eop_in != NULL && mci->eop_out != NULL);
231 msc_get_geometry (mci);
233 if (mci->blk_size != 512)
235 printf ("ignoring device with %d-byte sectors\n", mci->blk_size);
239 mci->bounce_buffer = palloc_get_multiple (PAL_ASSERT,
240 DIV_ROUND_UP (mci->blk_size,
242 mbi = malloc (sizeof (struct msc_blk_info));
244 snprintf (name, sizeof name, "ud%c", 'a' + dev_no++);
245 block = block_register (name, BLOCK_RAW, "USB", mci->blk_count,
246 &msc_operations, mbi);
247 partition_scan (block);
253 msc_detached (class_info ci UNUSED)
255 PANIC ("msc_detached: STUB");
259 msc_read (void *mbi_, block_sector_t sector, void *buffer)
261 struct msc_blk_info *mbi = mbi_;
264 msc_io (mbi->mci, sector, buffer, false);
265 mci_unlock (mbi->mci);
269 msc_write (void *mbi_, block_sector_t sector, const void *buffer)
271 struct msc_blk_info *mbi = mbi_;
274 msc_io (mbi->mci, sector, (void *) buffer, true);
275 mci_unlock (mbi->mci);
278 static struct block_operations msc_operations =
285 msc_get_geometry (struct msc_class_info *mci)
288 struct scsi_capacity10 *cap;
289 uint8_t buf[sizeof (struct msc_csw) + sizeof (struct scsi_capacity10)];
290 struct scsi_cdb10 *cdb;
294 /* cap + csw must be read in one shot, combine into a single buffer */
295 cap = (struct scsi_capacity10 *) (buf);
296 csw = (struct msc_csw *) (&buf[sizeof (struct scsi_capacity10)]);
298 cbw.sig = CBW_SIG_MAGIC;
299 cbw.tag = mci->tag++;
300 cbw.tx_len = sizeof (struct scsi_capacity10);
301 cbw.flags = CBW_FL_IN;
303 cbw.cb_len = sizeof (struct scsi_cdb10);
305 cdb = (void *) (&cbw.cb);
306 memset (cdb, 0, sizeof (struct scsi_cdb10));
307 cdb->op = SCSI_OP_READ_CAPACITY10;
309 usb_dev_bulk (mci->eop_out, &cbw, sizeof (cbw), &tx);
310 usb_dev_bulk (mci->eop_in, &buf, sizeof (buf), &tx);
312 mci->blk_count = be32_to_machine (cap->blocks) + 1;
313 mci->blk_size = be32_to_machine (cap->block_len);
316 if (tx == sizeof (struct scsi_capacity10))
318 msc_reset_endpoint (mci->eop_in);
319 usb_dev_bulk (mci->eop_in, csw, sizeof (*csw), &tx);
322 ASSERT (csw->sig == CSW_SIG_MAGIC);
324 if (csw->status != CSW_STATUS_PASSED)
326 PANIC ("USB storage geometry read failure!\n");
332 msc_io (struct msc_class_info *mci, block_sector_t bn, void *buf, bool wr)
336 struct scsi_cdb10 *cdb;
341 memcpy (mci->bounce_buffer, buf, mci->blk_size);
343 memset (&cbw, 0, sizeof (cbw));
344 cbw.sig = CBW_SIG_MAGIC;
345 cbw.tag = mci->tag++;
346 cbw.tx_len = mci->blk_size;
347 cbw.flags = (wr) ? CBW_FL_OUT : CBW_FL_IN;
349 cbw.cb_len = sizeof (struct scsi_cdb10);
351 cdb = (void *) (&cbw.cb);
352 cdb->op = (wr) ? SCSI_OP_WRITE10 : SCSI_OP_READ10;
353 *((uint32_t *) ((uint8_t *) (&cdb->lba) + 1)) = machine_to_be24 (bn);
354 cdb->len = machine_to_be16 (1);
356 // msc_reset_endpoint (mci->eop_in);
357 // msc_reset_endpoint (mci->eop_out);
360 err = usb_dev_bulk (mci->eop_out, &cbw, sizeof (cbw), &tx);
363 msc_reset_endpoint (mci->eop_out);
364 err = usb_dev_bulk (mci->eop_out, &cbw, sizeof (cbw), &tx);
368 err = usb_dev_bulk ((wr) ? mci->eop_out : mci->eop_in,
369 mci->bounce_buffer, mci->blk_size, &tx);
370 memset (&csw, 0, sizeof (csw));
371 ASSERT (tx == mci->blk_size);
374 /* get command status */
375 err = usb_dev_bulk (mci->eop_in, &csw, sizeof (csw), &tx);
378 msc_reset_endpoint (mci->eop_in);
379 msc_reset_endpoint (mci->eop_out);
380 err = usb_dev_bulk (mci->eop_in, &csw, sizeof (csw), &tx);
382 PANIC ("msc_io: error %d\n", err);
385 if (csw.sig != CSW_SIG_MAGIC)
387 if (mci->retrying == true)
388 PANIC ("usb_msd: CSW still missing. Bail out\n");
389 printf ("usb_msd: no command status, resetting. Buggy device?\n");
390 msc_reset_recovery(mci);
391 printf ("reset complete\n");
392 mci->retrying = true;
393 msc_io (mci, bn, buf, wr);
396 mci->retrying = false;
398 if (csw.status != CSW_STATUS_PASSED)
400 PANIC ("USB storage IO failure! - error %d\n", csw.status);
403 memcpy (buf, mci->bounce_buffer, mci->blk_size);
407 msc_reset_endpoint (struct usb_endpoint *eop)
409 struct usb_setup_pkt sp;
411 sp.recipient = USB_SETUP_RECIP_ENDPT;
412 sp.type = USB_SETUP_TYPE_STD;
414 sp.request = REQ_STD_CLR_FEAT;
415 sp.value = 0; /* 0 is ENDPOINT_HALT */
418 usb_dev_setup (eop, true, &sp, NULL, 0);
422 msc_reset_recovery(struct msc_class_info* mci)
424 msc_bulk_reset (mci);
425 msc_reset_endpoint (mci->eop_in);
426 msc_reset_endpoint (mci->eop_out);
429 static void msc_bulk_reset(struct msc_class_info* mci)
431 struct usb_setup_pkt sp;
433 sp.recipient = USB_SETUP_RECIP_DEV;
434 sp.type = USB_SETUP_TYPE_CLASS;
438 sp.index = mci->ui->iface_num;
440 usb_dev_setup (&mci->ui->dev->cfg_eop, true, &sp, NULL, 0);