00001
00006 #include <stdlib.h>
00007 #include <stdio.h>
00008 #include <string.h>
00009 #include <kernel/list.h>
00010 #include <endian.h>
00011 #include <debug.h>
00012 #include "threads/malloc.h"
00013 #include "threads/palloc.h"
00014 #include "threads/thread.h"
00015 #include "devices/timer.h"
00016 #include "threads/synch.h"
00017 #include "threads/pte.h"
00018 #include "devices/usb.h"
00019 #include "devices/block.h"
00020 #include "devices/partition.h"
00021
00022
00023 #define USB_CLASS_MASS_STORAGE 0x08
00024
00025 #define USB_SUBCLASS_RBC 0x01
00026 #define USB_SUBCLASS_ATAPI 0x02
00027 #define USB_SUBCLASS_TAPE 0x03
00028 #define USB_SUBCLASS_UFI 0x04
00029 #define USB_SUBCLASS_SFF8070 0x05
00030 #define USB_SUBCLASS_SCSI 0x06
00031
00032 #define USB_PROTO_COMPLETE 0x00
00033 #define USB_PROTO_NO_COMPLETE 0x01
00034 #define USB_PROTO_BULK 0x50
00035
00036 #pragma pack(1)
00037
00038 #define CBW_SIG_MAGIC 0x43425355
00039
00040 #define CBW_FL_IN (1 << 7)
00041 #define CBW_FL_OUT 0
00042
00044
00045 struct msc_cbw
00046 {
00047 uint32_t sig;
00048 uint32_t tag;
00049 uint32_t tx_len;
00050 uint8_t flags;
00051 uint8_t lun;
00052 uint8_t cb_len;
00053 uint8_t cb[16];
00054 };
00055
00056 #define CSW_SIG_MAGIC 0x53425355
00057 #define CSW_STATUS_PASSED 0
00058 #define CSW_STATUS_FAILED 1
00059 #define CSW_STATUS_PHASE 2
00060
00061 struct msc_csw
00062 {
00063 uint32_t sig;
00064 uint32_t tag;
00065 uint32_t residue;
00066 uint8_t status;
00067 };
00068
00069 struct scsi_cdb6
00070 {
00071 uint8_t op;
00072 uint8_t lba[3];
00073 uint8_t len;
00074 uint8_t control;
00075 };
00076
00077 struct scsi_cdb10
00078 {
00079 uint8_t op;
00080 uint8_t action;
00081 uint32_t lba;
00082 uint8_t resv;
00083 uint16_t len;
00084 uint8_t control;
00085 };
00086
00087 struct scsi_cdb12
00088 {
00089 uint8_t op;
00090 uint8_t action;
00091 uint32_t lba;
00092 uint32_t len;
00093 uint8_t resv;
00094 uint8_t control;
00095 };
00096
00097 struct scsi_cdb16
00098 {
00099 uint8_t op;
00100 uint8_t action;
00101 uint32_t lba;
00102 uint32_t data;
00103 uint32_t len;
00104 uint8_t resv;
00105 uint8_t control;
00106 };
00107
00108 struct scsi_capacity10
00109 {
00110 uint32_t blocks;
00111 uint32_t block_len;
00112 };
00113
00114 #define SCSI_OP_WRITE6 0xa
00115 #define SCSI_OP_READ6 0x8
00116 #define SCSI_OP_TEST_READY 0x00
00117 #define SCSI_OP_SEEK8 0x0b
00118 #define SCSI_OP_MODE_SENSE8 0x1a
00119 #define SCSI_OP_MODE_SELECT8 0x15
00120 #define SCSI_OP_READ_CAPACITY10 0x25
00121 #define SCSI_OP_READ_CAPACITY16 0x9e
00122 #define SCSI_OP_WRITE10 0x2a
00123 #define SCSI_OP_READ10 0x28
00124 #define SCSI_OP_SEEK10 0x2b
00125 #define SCSI_OP_MODE_SENSE10 0x5a
00126 #define SCSI_OP_MODE_SELECT10 0x55
00127
00128
00129 #pragma pack()
00130
00131 static void *msc_attached (struct usb_iface *);
00132 static void msc_detached (class_info);
00133
00134 static void msc_reset_endpoint (struct usb_endpoint *eop);
00135
00136 static struct usb_class storage_class = {
00137 .attached = msc_attached,
00138 .detached = msc_detached,
00139 .name = "Mass Storage",
00140 .class_id = USB_CLASS_MASS_STORAGE
00141 };
00142
00143 #define mci_lock(x) lock_acquire(&(x)->lock)
00144 #define mci_unlock(x) lock_release(&(x)->lock)
00145
00146 struct msc_class_info
00147 {
00148 int refs;
00149 struct lock lock;
00150 struct usb_iface *ui;
00151 int blk_size;
00152 int blk_count;
00153 bool retrying;
00154 uint32_t tag;
00155 void *bounce_buffer;
00156
00157 struct usb_endpoint *eop_in;
00158 struct usb_endpoint *eop_out;
00159 struct list_elem peers;
00160 };
00161 static void msc_get_geometry (struct msc_class_info *);
00162 static void msc_io (struct msc_class_info *, block_sector_t, void *buf, bool wr);
00163 static void msc_reset_recovery(struct msc_class_info* mci);
00164 static void msc_bulk_reset(struct msc_class_info* mci);
00165
00166 struct msc_blk_info
00167 {
00168 struct msc_class_info *mci;
00169 };
00170
00171 static struct list device_list;
00172 static struct block_operations msc_operations;
00173
00174 void usb_storage_init (void);
00175
00176 void
00177 usb_storage_init (void)
00178 {
00179 list_init (&device_list);
00180 usb_register_class (&storage_class);
00181 }
00182
00183
00184 static class_info
00185 msc_attached (struct usb_iface *ui)
00186 {
00187 static int dev_no;
00188
00189 struct msc_class_info *mci;
00190 struct msc_blk_info *mbi;
00191 struct list_elem *li;
00192 struct block *block;
00193 char name[16];
00194
00195 if (ui->subclass_id != USB_SUBCLASS_SCSI)
00196 {
00197 printf ("usb_storage: Only support SCSI-type devices\n");
00198 return NULL;
00199 }
00200
00201 mci = malloc (sizeof (struct msc_class_info));
00202
00203 mci->refs = 0;
00204 mci->retrying = false;
00205 lock_init (&mci->lock);
00206 mci->ui = ui;
00207 list_push_back (&device_list, &mci->peers);
00208
00209
00210 li = list_begin (&ui->endpoints);
00211 mci->eop_in = NULL;
00212 mci->eop_out = NULL;
00213 while (li != list_end (&ui->endpoints))
00214 {
00215 struct usb_endpoint *ue;
00216
00217 ue = list_entry (li, struct usb_endpoint, peers);
00218 li = list_next (li);
00219
00220 if (ue->attr == USB_EOP_ATTR_BULK)
00221 {
00222 if (ue->direction == 0)
00223 mci->eop_out = ue;
00224 else
00225 mci->eop_in = ue;
00226 }
00227 }
00228
00229 ASSERT (mci->eop_in != NULL && mci->eop_out != NULL);
00230
00231 msc_get_geometry (mci);
00232
00233 if (mci->blk_size != 512)
00234 {
00235 printf ("ignoring device with %d-byte sectors\n", mci->blk_size);
00236 return NULL;
00237 }
00238
00239 mci->bounce_buffer = palloc_get_multiple (PAL_ASSERT,
00240 DIV_ROUND_UP (mci->blk_size,
00241 PGSIZE));
00242 mbi = malloc (sizeof (struct msc_blk_info));
00243 mbi->mci = mci;
00244 snprintf (name, sizeof name, "ud%c", 'a' + dev_no++);
00245 block = block_register (name, BLOCK_RAW, "USB", mci->blk_count,
00246 &msc_operations, mbi);
00247 partition_scan (block);
00248
00249 return mci;
00250 }
00251
00252 static void
00253 msc_detached (class_info ci UNUSED)
00254 {
00255 PANIC ("msc_detached: STUB");
00256 }
00257
00258 static void
00259 msc_read (void *mbi_, block_sector_t sector, void *buffer)
00260 {
00261 struct msc_blk_info *mbi = mbi_;
00262
00263 mci_lock (mbi->mci);
00264 msc_io (mbi->mci, sector, buffer, false);
00265 mci_unlock (mbi->mci);
00266 }
00267
00268 static void
00269 msc_write (void *mbi_, block_sector_t sector, const void *buffer)
00270 {
00271 struct msc_blk_info *mbi = mbi_;
00272
00273 mci_lock (mbi->mci);
00274 msc_io (mbi->mci, sector, (void *) buffer, true);
00275 mci_unlock (mbi->mci);
00276 }
00277
00278 static struct block_operations msc_operations =
00279 {
00280 msc_read,
00281 msc_write,
00282 };
00283
00284 static void
00285 msc_get_geometry (struct msc_class_info *mci)
00286 {
00287 struct msc_cbw cbw;
00288 struct scsi_capacity10 *cap;
00289 uint8_t buf[sizeof (struct msc_csw) + sizeof (struct scsi_capacity10)];
00290 struct scsi_cdb10 *cdb;
00291 struct msc_csw *csw;
00292 int tx;
00293
00294
00295 cap = (struct scsi_capacity10 *) (buf);
00296 csw = (struct msc_csw *) (&buf[sizeof (struct scsi_capacity10)]);
00297
00298 cbw.sig = CBW_SIG_MAGIC;
00299 cbw.tag = mci->tag++;
00300 cbw.tx_len = sizeof (struct scsi_capacity10);
00301 cbw.flags = CBW_FL_IN;
00302 cbw.lun = 0;
00303 cbw.cb_len = sizeof (struct scsi_cdb10);
00304
00305 cdb = (void *) (&cbw.cb);
00306 memset (cdb, 0, sizeof (struct scsi_cdb10));
00307 cdb->op = SCSI_OP_READ_CAPACITY10;
00308
00309 usb_dev_bulk (mci->eop_out, &cbw, sizeof (cbw), &tx);
00310 usb_dev_bulk (mci->eop_in, &buf, sizeof (buf), &tx);
00311
00312 mci->blk_count = be32_to_machine (cap->blocks) + 1;
00313 mci->blk_size = be32_to_machine (cap->block_len);
00314
00315
00316 if (tx == sizeof (struct scsi_capacity10))
00317 {
00318 msc_reset_endpoint (mci->eop_in);
00319 usb_dev_bulk (mci->eop_in, csw, sizeof (*csw), &tx);
00320 }
00321
00322 ASSERT (csw->sig == CSW_SIG_MAGIC);
00323
00324 if (csw->status != CSW_STATUS_PASSED)
00325 {
00326 PANIC ("USB storage geometry read failure!\n");
00327 }
00328
00329 }
00330
00331 static void
00332 msc_io (struct msc_class_info *mci, block_sector_t bn, void *buf, bool wr)
00333 {
00334 struct msc_cbw cbw;
00335 struct msc_csw csw;
00336 struct scsi_cdb10 *cdb;
00337 int tx;
00338 int err;
00339
00340 if (wr)
00341 memcpy (mci->bounce_buffer, buf, mci->blk_size);
00342
00343 memset (&cbw, 0, sizeof (cbw));
00344 cbw.sig = CBW_SIG_MAGIC;
00345 cbw.tag = mci->tag++;
00346 cbw.tx_len = mci->blk_size;
00347 cbw.flags = (wr) ? CBW_FL_OUT : CBW_FL_IN;
00348 cbw.lun = 0;
00349 cbw.cb_len = sizeof (struct scsi_cdb10);
00350
00351 cdb = (void *) (&cbw.cb);
00352 cdb->op = (wr) ? SCSI_OP_WRITE10 : SCSI_OP_READ10;
00353 *((uint32_t *) ((uint8_t *) (&cdb->lba) + 1)) = machine_to_be24 (bn);
00354 cdb->len = machine_to_be16 (1);
00355
00356
00357
00358
00359
00360 err = usb_dev_bulk (mci->eop_out, &cbw, sizeof (cbw), &tx);
00361 if (err != 0)
00362 {
00363 msc_reset_endpoint (mci->eop_out);
00364 err = usb_dev_bulk (mci->eop_out, &cbw, sizeof (cbw), &tx);
00365 }
00366
00367
00368 err = usb_dev_bulk ((wr) ? mci->eop_out : mci->eop_in,
00369 mci->bounce_buffer, mci->blk_size, &tx);
00370 memset (&csw, 0, sizeof (csw));
00371 ASSERT (tx == mci->blk_size);
00372
00373
00374
00375 err = usb_dev_bulk (mci->eop_in, &csw, sizeof (csw), &tx);
00376 if (err != 0)
00377 {
00378 msc_reset_endpoint (mci->eop_in);
00379 msc_reset_endpoint (mci->eop_out);
00380 err = usb_dev_bulk (mci->eop_in, &csw, sizeof (csw), &tx);
00381 if (err != 0)
00382 PANIC ("msc_io: error %d\n", err);
00383 }
00384
00385 if (csw.sig != CSW_SIG_MAGIC)
00386 {
00387 if (mci->retrying == true)
00388 PANIC ("usb_msd: CSW still missing. Bail out\n");
00389 printf ("usb_msd: no command status, resetting. Buggy device?\n");
00390 msc_reset_recovery(mci);
00391 printf ("reset complete\n");
00392 mci->retrying = true;
00393 msc_io (mci, bn, buf, wr);
00394 return;
00395 }
00396 mci->retrying = false;
00397
00398 if (csw.status != CSW_STATUS_PASSED)
00399 {
00400 PANIC ("USB storage IO failure! - error %d\n", csw.status);
00401 }
00402 if (!wr)
00403 memcpy (buf, mci->bounce_buffer, mci->blk_size);
00404 }
00405
00406 static void
00407 msc_reset_endpoint (struct usb_endpoint *eop)
00408 {
00409 struct usb_setup_pkt sp;
00410
00411 sp.recipient = USB_SETUP_RECIP_ENDPT;
00412 sp.type = USB_SETUP_TYPE_STD;
00413 sp.direction = 0;
00414 sp.request = REQ_STD_CLR_FEAT;
00415 sp.value = 0;
00416 sp.index = eop->eop;
00417 sp.length = 0;
00418 usb_dev_setup (eop, true, &sp, NULL, 0);
00419 }
00420
00421 static void
00422 msc_reset_recovery(struct msc_class_info* mci)
00423 {
00424 msc_bulk_reset (mci);
00425 msc_reset_endpoint (mci->eop_in);
00426 msc_reset_endpoint (mci->eop_out);
00427 }
00428
00429 static void msc_bulk_reset(struct msc_class_info* mci)
00430 {
00431 struct usb_setup_pkt sp;
00432
00433 sp.recipient = USB_SETUP_RECIP_DEV;
00434 sp.type = USB_SETUP_TYPE_CLASS;
00435 sp.direction = 0;
00436 sp.request = 0xff;
00437 sp.value = 0;
00438 sp.index = mci->ui->iface_num;
00439 sp.length = 0;
00440 usb_dev_setup (&mci->ui->dev->cfg_eop, true, &sp, NULL, 0);
00441 }