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"
21 //http://www.usb.org/developers/defined_class
22 #define USB_CLASS_MASS_STORAGE 0x08
24 #define USB_SUBCLASS_RBC 0x01 /* reduced block commands */
25 #define USB_SUBCLASS_ATAPI 0x02 /* ATAPI - CD's */
26 #define USB_SUBCLASS_TAPE 0x03
27 #define USB_SUBCLASS_UFI 0x04 /* floppy disk */
28 #define USB_SUBCLASS_SFF8070 0x05
29 #define USB_SUBCLASS_SCSI 0x06 /* scsi transparent command set */
31 #define USB_PROTO_COMPLETE 0x00
32 #define USB_PROTO_NO_COMPLETE 0x01
33 #define USB_PROTO_BULK 0x50
37 #define CBW_SIG_MAGIC 0x43425355
39 #define CBW_FL_IN (1 << 7)
42 /** usbmassbulk_10.pdf - pg 13 */
43 /* command block wrapper */
51 uint8_t cb_len; /* command block length */
52 uint8_t cb[16]; /* command block */
55 #define CSW_SIG_MAGIC 0x53425355
56 #define CSW_STATUS_PASSED 0
57 #define CSW_STATUS_FAILED 1
58 #define CSW_STATUS_PHASE 2 /* phase error */
59 /* command status wrapper */
107 struct scsi_capacity10
113 #define SCSI_OP_WRITE6 0xa
114 #define SCSI_OP_READ6 0x8
115 #define SCSI_OP_TEST_READY 0x00
116 #define SCSI_OP_SEEK8 0x0b
117 #define SCSI_OP_MODE_SENSE8 0x1a
118 #define SCSI_OP_MODE_SELECT8 0x15
119 #define SCSI_OP_READ_CAPACITY10 0x25
120 #define SCSI_OP_READ_CAPACITY16 0x9e
121 #define SCSI_OP_WRITE10 0x2a
122 #define SCSI_OP_READ10 0x28
123 #define SCSI_OP_SEEK10 0x2b
124 #define SCSI_OP_MODE_SENSE10 0x5a
125 #define SCSI_OP_MODE_SELECT10 0x55
130 static void *msc_attached (struct usb_iface *);
131 static void msc_detached (class_info);
133 static void msc_reset_endpoint (struct usb_endpoint *eop);
135 static struct usb_class storage_class = {
136 .attached = msc_attached,
137 .detached = msc_detached,
138 .name = "Mass Storage",
139 .class_id = USB_CLASS_MASS_STORAGE
142 #define mci_lock(x) lock_acquire(&(x)->lock)
143 #define mci_unlock(x) lock_release(&(x)->lock)
145 struct msc_class_info
149 struct usb_iface *ui;
156 struct usb_endpoint *eop_in;
157 struct usb_endpoint *eop_out;
158 struct list_elem peers;
160 static void msc_get_geometry (struct msc_class_info *);
161 static void msc_io (struct msc_class_info *, block_sector_t, void *buf, bool wr);
162 static void msc_reset_recovery(struct msc_class_info* mci);
163 static void msc_bulk_reset(struct msc_class_info* mci);
167 struct msc_class_info *mci;
170 static struct list device_list;
171 static struct block_operations msc_operations;
173 void usb_storage_init (void);
176 usb_storage_init (void)
178 list_init (&device_list);
179 usb_register_class (&storage_class);
184 msc_attached (struct usb_iface *ui)
188 struct msc_class_info *mci;
189 struct msc_blk_info *mbi;
190 struct list_elem *li;
194 if (ui->subclass_id != USB_SUBCLASS_SCSI)
196 printf ("usb_storage: Only support SCSI-type devices\n");
200 mci = malloc (sizeof (struct msc_class_info));
203 mci->retrying = false;
204 lock_init (&mci->lock);
206 list_push_back (&device_list, &mci->peers);
209 li = list_begin (&ui->endpoints);
212 while (li != list_end (&ui->endpoints))
214 struct usb_endpoint *ue;
216 ue = list_entry (li, struct usb_endpoint, peers);
219 if (ue->attr == USB_EOP_ATTR_BULK)
221 if (ue->direction == 0)
228 ASSERT (mci->eop_in != NULL && mci->eop_out != NULL);
230 msc_get_geometry (mci);
232 if (mci->blk_size != 512)
234 printf ("ignoring device with %d-byte sectors\n", mci->blk_size);
238 mci->bounce_buffer = palloc_get_multiple (PAL_ASSERT,
239 DIV_ROUND_UP (mci->blk_size,
241 mbi = malloc (sizeof (struct msc_blk_info));
243 snprintf (name, sizeof name, "ud%c", 'a' + dev_no++);
244 block = block_register (name, BLOCK_RAW, "USB", mci->blk_count,
245 &msc_operations, mbi);
246 partition_scan (block);
252 msc_detached (class_info ci UNUSED)
254 PANIC ("msc_detached: STUB");
258 msc_read (void *mbi_, block_sector_t sector, void *buffer)
260 struct msc_blk_info *mbi = mbi_;
263 msc_io (mbi->mci, sector, buffer, false);
264 mci_unlock (mbi->mci);
268 msc_write (void *mbi_, block_sector_t sector, const void *buffer)
270 struct msc_blk_info *mbi = mbi_;
273 msc_io (mbi->mci, sector, (void *) buffer, true);
274 mci_unlock (mbi->mci);
277 static struct block_operations msc_operations =
284 msc_get_geometry (struct msc_class_info *mci)
287 struct scsi_capacity10 *cap;
288 uint8_t buf[sizeof (struct msc_csw) + sizeof (struct scsi_capacity10)];
289 struct scsi_cdb10 *cdb;
293 /* cap + csw must be read in one shot, combine into a single buffer */
294 cap = (struct scsi_capacity10 *) (buf);
295 csw = (struct msc_csw *) (&buf[sizeof (struct scsi_capacity10)]);
297 cbw.sig = CBW_SIG_MAGIC;
298 cbw.tag = mci->tag++;
299 cbw.tx_len = sizeof (struct scsi_capacity10);
300 cbw.flags = CBW_FL_IN;
302 cbw.cb_len = sizeof (struct scsi_cdb10);
304 cdb = (void *) (&cbw.cb);
305 memset (cdb, 0, sizeof (struct scsi_cdb10));
306 cdb->op = SCSI_OP_READ_CAPACITY10;
308 usb_dev_bulk (mci->eop_out, &cbw, sizeof (cbw), &tx);
309 usb_dev_bulk (mci->eop_in, &buf, sizeof (buf), &tx);
311 mci->blk_count = be32_to_machine (cap->blocks) + 1;
312 mci->blk_size = be32_to_machine (cap->block_len);
315 if (tx == sizeof (struct scsi_capacity10))
317 msc_reset_endpoint (mci->eop_in);
318 usb_dev_bulk (mci->eop_in, csw, sizeof (*csw), &tx);
321 ASSERT (csw->sig == CSW_SIG_MAGIC);
323 if (csw->status != CSW_STATUS_PASSED)
325 PANIC ("USB storage geometry read failure!\n");
331 msc_io (struct msc_class_info *mci, block_sector_t bn, void *buf, bool wr)
335 struct scsi_cdb10 *cdb;
340 memcpy (mci->bounce_buffer, buf, mci->blk_size);
342 memset (&cbw, 0, sizeof (cbw));
343 cbw.sig = CBW_SIG_MAGIC;
344 cbw.tag = mci->tag++;
345 cbw.tx_len = mci->blk_size;
346 cbw.flags = (wr) ? CBW_FL_OUT : CBW_FL_IN;
348 cbw.cb_len = sizeof (struct scsi_cdb10);
350 cdb = (void *) (&cbw.cb);
351 cdb->op = (wr) ? SCSI_OP_WRITE10 : SCSI_OP_READ10;
352 *((uint32_t *) ((uint8_t *) (&cdb->lba) + 1)) = machine_to_be24 (bn);
353 cdb->len = machine_to_be16 (1);
355 // msc_reset_endpoint (mci->eop_in);
356 // msc_reset_endpoint (mci->eop_out);
359 err = usb_dev_bulk (mci->eop_out, &cbw, sizeof (cbw), &tx);
362 msc_reset_endpoint (mci->eop_out);
363 err = usb_dev_bulk (mci->eop_out, &cbw, sizeof (cbw), &tx);
367 err = usb_dev_bulk ((wr) ? mci->eop_out : mci->eop_in,
368 mci->bounce_buffer, mci->blk_size, &tx);
369 memset (&csw, 0, sizeof (csw));
370 ASSERT (tx == mci->blk_size);
373 /* get command status */
374 err = usb_dev_bulk (mci->eop_in, &csw, sizeof (csw), &tx);
377 msc_reset_endpoint (mci->eop_in);
378 msc_reset_endpoint (mci->eop_out);
379 err = usb_dev_bulk (mci->eop_in, &csw, sizeof (csw), &tx);
381 PANIC ("msc_io: error %d\n", err);
384 if (csw.sig != CSW_SIG_MAGIC)
386 if (mci->retrying == true)
387 PANIC ("usb_msd: CSW still missing. Bail out\n");
388 printf ("usb_msd: no command status, resetting. Buggy device?\n");
389 msc_reset_recovery(mci);
390 printf ("reset complete\n");
391 mci->retrying = true;
392 msc_io (mci, bn, buf, wr);
395 mci->retrying = false;
397 if (csw.status != CSW_STATUS_PASSED)
399 PANIC ("USB storage IO failure! - error %d\n", csw.status);
402 memcpy (buf, mci->bounce_buffer, mci->blk_size);
406 msc_reset_endpoint (struct usb_endpoint *eop)
408 struct usb_setup_pkt sp;
410 sp.recipient = USB_SETUP_RECIP_ENDPT;
411 sp.type = USB_SETUP_TYPE_STD;
413 sp.request = REQ_STD_CLR_FEAT;
414 sp.value = 0; /* 0 is ENDPOINT_HALT */
417 usb_dev_setup (eop, true, &sp, NULL, 0);
421 msc_reset_recovery(struct msc_class_info* mci)
423 msc_bulk_reset (mci);
424 msc_reset_endpoint (mci->eop_in);
425 msc_reset_endpoint (mci->eop_out);
428 static void msc_bulk_reset(struct msc_class_info* mci)
430 struct usb_setup_pkt sp;
432 sp.recipient = USB_SETUP_RECIP_DEV;
433 sp.type = USB_SETUP_TYPE_CLASS;
437 sp.index = mci->ui->iface_num;
439 usb_dev_setup (&mci->ui->dev->cfg_eop, true, &sp, NULL, 0);