00001
00038 #include <assert.h>
00039 #include <atomic.h>
00040 #include <byteorder.h>
00041 #include <dmapool.h>
00042 #include <interrupt.h>
00043 #include <physmem.h>
00044 #include <status_codes.h>
00045 #include <string.h>
00046 #include <types.h>
00047 #include <util.h>
00048 #include <block/device.h>
00049 #include <scsi/cdb.h>
00050 #include <scsi/spc_protocol.h>
00051 #include <scsi/sbc_protocol.h>
00052 #include <usb/dev_mux.h>
00053 #include <usb/udi_msc_bulk.h>
00054 #include <usb/msc_protocol.h>
00055 #include <usb/request.h>
00056 #include <usb/usb_protocol.h>
00057 #include <usb/udc.h>
00058 #include <app/usb.h>
00059
00065 #ifndef APP_UDI_MSC_FS_BULK_EP_SIZE
00066 # define APP_UDI_MSC_FS_BULK_EP_SIZE 64
00067 #endif
00068
00069 #define MSC_DATA_BUFFER_SIZE CONFIG_DMAPOOL_LARGE_OBJ_SIZE
00070 #define MSC_MAX_NR_BUFFERS (CONFIG_DMAPOOL_NR_LARGE_OBJS / 2)
00071 #define MSC_MAX_DATA_LEN (MSC_MAX_NR_BUFFERS * MSC_DATA_BUFFER_SIZE)
00072
00073
00074 #define MSC_BULK_IN_EP_ADDR (APP_UDI_MSC_BULK_IN_EP | USB_DIR_IN)
00075 #define MSC_BULK_OUT_EP_ADDR (APP_UDI_MSC_BULK_OUT_EP | USB_DIR_OUT)
00076
00078 #define MSC_MAX_NR_SEGS (2)
00079
00080
00081 #define MSC_VPD_SERIAL_BUF_SIZE (MSC_MAX_SERIAL_LEN + SCSI_VPD_HEADER_SIZE)
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 #define MSC_VPD_ID_BUF_SIZE (SCSI_VPD_HEADER_SIZE \
00092 + SCSI_VPD_ID_HEADER_SIZE \
00093 + 8 + 16 \
00094 + MSC_MAX_SERIAL_LEN)
00095
00100 struct msc_interface {
00102 struct udm_interface iface;
00104 struct udc *udc;
00106 struct block_device *bdev;
00108 usb_ep_id_t bulk_in_ep;
00110 usb_ep_id_t bulk_out_ep;
00112 dma_addr_t sense_data;
00114 uint32_t blocks_queued;
00116 uint32_t blocks_total;
00118 uint32_t first_lba;
00120 atomic_t blk_blocks_pending;
00122 atomic_t usb_reqs_pending;
00124 dma_addr_t cbw;
00126 dma_addr_t csw;
00128 struct usb_request *cbw_csw_req;
00130 struct block_request *block_req;
00132 uint16_t busy_asc;
00134 void (*busy_cb)(void *);
00136 void *busy_cb_data;
00138 bool queue_locked;
00140 bool not_ready;
00142 bool xfer_in_progress;
00143 };
00144
00145 static inline struct msc_interface *msc_interface_of(
00146 struct udm_interface *iface)
00147 {
00148 return container_of(iface, struct msc_interface, iface);
00149 }
00150
00151 union msc_mode_param_header {
00152 struct scsi_mode_param_header6 h6;
00153 struct scsi_mode_param_header10 h10;
00154 };
00155 #define MSC_MODE_PARAM_HDR_BUF_LEN \
00156 (sizeof(union msc_mode_param_header) \
00157 + sizeof(struct sbc_slba_block_desc))
00158
00159 COMPILER_PACK_SET(1);
00160 struct msc_iface_desc {
00161 struct usb_interface_descriptor iface;
00162 struct usb_endpoint_descriptor ep[2];
00163 };
00164 COMPILER_PACK_RESET();
00165
00166 static const struct msc_iface_desc msc_desc_template = {
00167 .iface.bLength = sizeof(struct usb_interface_descriptor),
00168 .iface.bDescriptorType = USB_DT_INTERFACE,
00169 .iface.bInterfaceNumber = APP_UDI_MSC_INTERFACE_ID,
00170 .iface.bAlternateSetting = 0,
00171 .iface.bNumEndpoints = 2,
00172 .iface.bInterfaceClass = USB_CLASS_MSC,
00173
00174 .iface.bInterfaceSubClass = USB_MSC_SUBCLASS_TRANSPARENT,
00175
00176 .iface.bInterfaceProtocol = USB_MSC_PROTOCOL_BULK,
00177 .ep[0].bLength = sizeof(struct usb_endpoint_descriptor),
00178 .ep[0].bDescriptorType = USB_DT_ENDPOINT,
00179 .ep[0].bEndpointAddress = MSC_BULK_IN_EP_ADDR,
00180 .ep[0].bmAttributes = USB_EP_XFER_BULK,
00181 .ep[0].wMaxPacketSize = LE16(APP_UDI_MSC_FS_BULK_EP_SIZE),
00182 .ep[1].bLength = sizeof(struct usb_endpoint_descriptor),
00183 .ep[1].bDescriptorType = USB_DT_ENDPOINT,
00184 .ep[1].bEndpointAddress = MSC_BULK_OUT_EP_ADDR,
00185 .ep[1].bmAttributes = USB_EP_XFER_BULK,
00186 .ep[1].wMaxPacketSize = LE16(APP_UDI_MSC_FS_BULK_EP_SIZE),
00187 };
00188
00189 static const struct scsi_inquiry_data msc_inquiry_data = {
00190 .pq_pdt = SCSI_INQ_PQ_CONNECTED | SCSI_INQ_DT_DIR_ACCESS,
00191 #ifdef CONFIG_UDI_MSC_REMOVABLE
00192 .flags1 = SCSI_INQ_RMB,
00193 #else
00194 .flags1 = 0,
00195 #endif
00196 .version = SCSI_INQ_VER_SPC3,
00197 .flags3 = SCSI_INQ_HISUP | SCSI_INQ_RSP_SPC2,
00198 .addl_len = SCSI_INQ_ADDL_LEN(sizeof(msc_inquiry_data)),
00199 .vendor_id = { APP_UDI_MSC_INQ_VENDOR_ID },
00200 .product_id = { APP_UDI_MSC_INQ_PRODUCT_ID },
00201 .product_rev = { APP_UDI_MSC_INQ_PRODUCT_VERSION },
00202 };
00203
00204 static struct usb_msc_cbw *msc_get_cbw(struct msc_interface *msc)
00205 {
00206 return msc->cbw.ptr;
00207 }
00208
00209 static struct usb_msc_csw *msc_get_csw(struct msc_interface *msc)
00210 {
00211 return msc->csw.ptr;
00212 }
00213
00214 static void msc_free_dma_buf_list(struct slist *buf_list)
00215 {
00216 struct buffer *buf;
00217
00218 while (!slist_is_empty(buf_list)) {
00219 buf = slist_pop_head(buf_list, struct buffer, node);
00220 buffer_dma_free(buf, MSC_DATA_BUFFER_SIZE);
00221 }
00222 }
00223
00229 static void msc_queue_empty(struct msc_interface *msc)
00230 {
00231 irqflags_t iflags;
00232
00233 iflags = cpu_irq_save();
00234
00235 dbg_verbose("msc: queue empty, not_ready=%d busy_cb=%p\n",
00236 msc->not_ready, msc->busy_cb);
00237
00238 msc->xfer_in_progress = false;
00239 if (msc->not_ready && msc->busy_cb) {
00240 void (*busy_cb)(void *) = msc->busy_cb;
00241 void *busy_data = msc->busy_cb_data;
00242
00243 msc->busy_cb = NULL;
00244 cpu_irq_restore(iflags);
00245 busy_cb(busy_data);
00246 } else {
00247 cpu_irq_restore(iflags);
00248 }
00249 }
00250
00251 static void msc_init_sense(struct msc_interface *msc, uint8_t sense_key,
00252 uint16_t add_sense, uint32_t lba)
00253 {
00254 uint8_t *data = msc->sense_data.ptr;
00255
00256 memset(data, 0, 18);
00257 data[0] = SCSI_SENSE_VALID | SCSI_SENSE_CURRENT;
00258 data[2] = sense_key;
00259 data[3] = lba >> 24;
00260 data[4] = lba >> 16;
00261 data[5] = lba >> 8;
00262 data[6] = lba;
00263 data[7] = SCSI_SENSE_ADDL_LEN(18);
00264 data[12] = add_sense >> 8;
00265 data[13] = add_sense;
00266 }
00267
00268 static unsigned int msc_sense_len(struct msc_interface *msc)
00269 {
00270 const uint8_t *data = msc->sense_data.ptr;
00271 return data[7] + 8;
00272 }
00273
00274 static void msc_cbw_received(struct udc *udc, struct usb_request *req);
00275 static void msc_csw_sent(struct udc *udc, struct usb_request *req);
00276
00277 static void msc_prepare_csw(struct msc_interface *msc, uint32_t residue,
00278 uint8_t status)
00279 {
00280 struct usb_msc_csw *csw;
00281 struct usb_msc_cbw *cbw;
00282 struct usb_request *req;
00283 struct buffer *buf;
00284
00285 csw = msc->csw.ptr;
00286 cbw = msc->cbw.ptr;
00287 csw->dCSWTag = cbw->dCBWTag;
00288 csw->dCSWDataResidue = cpu_to_le32(residue);
00289 csw->bCSWStatus = status;
00290
00291 req = msc->cbw_csw_req;
00292 req->bytes_xfered = 0;
00293 req->req_done = msc_csw_sent;
00294 buf = usb_req_get_first_buffer(req);
00295 buffer_init_tx(buf, csw, sizeof(struct usb_msc_csw));
00296
00297 dbg_verbose("msc: CSW t%08lx r%lu s%u\n", le32_to_cpu(csw->dCSWTag),
00298 residue, status);
00299 }
00300
00301 static void msc_request_data_done(struct udc *udc, struct msc_interface *msc)
00302 {
00303 struct usb_msc_csw *csw;
00304
00305 csw = msc_get_csw(msc);
00306 if (csw->dCSWDataResidue != LE32(0) && msc->bulk_in_ep) {
00307 struct usb_msc_cbw *cbw = msc_get_cbw(msc);
00308
00309 if (cbw->bmCBWFlags & USB_CBW_DIRECTION_IN)
00310 udc_ep_set_halt(udc, msc->bulk_in_ep);
00311 else
00312 udc_ep_set_halt(udc, msc->bulk_out_ep);
00313 udc_ep_submit_in_req(udc, msc->bulk_in_ep, msc->cbw_csw_req);
00314 }
00315
00316 dbg_verbose("msc data done: t%08lx r%lu s%u %s\n",
00317 le32_to_cpu(csw->dCSWTag),
00318 le32_to_cpu(csw->dCSWDataResidue),
00319 csw->bCSWStatus,
00320 (msc_get_cbw(msc)->bmCBWFlags & USB_CBW_DIRECTION_IN)
00321 ? "IN" : "OUT");
00322 }
00323
00324 static void msc_request_done(struct udc *udc, struct msc_interface *msc,
00325 uint32_t residue)
00326 {
00327
00328
00329
00330
00331
00332
00333 if (!residue)
00334 udc_ep_submit_in_req(udc, msc->bulk_in_ep, msc->cbw_csw_req);
00335
00336 dbg_verbose("msc req done\n");
00337 }
00338
00339 static void msc_request_done_nodata(struct udc *udc, struct msc_interface *msc,
00340 uint32_t residue)
00341 {
00342 if (residue) {
00343 struct usb_msc_cbw *cbw = msc_get_cbw(msc);
00344 if (cbw->bmCBWFlags & USB_CBW_DIRECTION_IN)
00345 udc_ep_set_halt(udc, msc->bulk_in_ep);
00346 else
00347 udc_ep_set_halt(udc, msc->bulk_out_ep);
00348 }
00349
00350 udc_ep_submit_in_req(udc, msc->bulk_in_ep, msc->cbw_csw_req);
00351 }
00352
00353 static void msc_request_failed(struct msc_interface *msc, uint32_t residue,
00354 uint8_t csw_status, uint8_t sense_key, uint16_t add_sense)
00355 {
00356 dbg_warning("msc: req %02x failed: SK %02x ASC(Q) %04x\n",
00357 scsi_cdb_get_opcode(msc_get_cbw(msc)->CDB),
00358 sense_key, add_sense);
00359
00360 msc_init_sense(msc, sense_key, add_sense, 0);
00361 msc_prepare_csw(msc, residue, csw_status);
00362 msc_request_done_nodata(msc->udc, msc, residue);
00363 }
00364
00365 static void msc_phase_error(struct msc_interface *msc)
00366 {
00367 struct usb_msc_cbw *cbw = msc_get_cbw(msc);
00368 uint32_t cbw_xfer_len;
00369
00370 cbw_xfer_len = le32_to_cpu(cbw->dCBWDataTransferLength);
00371
00372 dbg_error("msc: Phase Error (opcode %02x)\n",
00373 scsi_cdb_get_opcode(cbw->CDB));
00374 dbg_verbose("msc: CBW bmCBWFlags = 0x%02x\n", cbw->bmCBWFlags);
00375 dbg_verbose("msc: CBW dCBWDataTransferLength = 0x%lx\n", cbw_xfer_len);
00376
00377 msc_prepare_csw(msc, cbw_xfer_len, USB_CSW_STATUS_PE);
00378 msc_request_done_nodata(msc->udc, msc, cbw_xfer_len);
00379 }
00380
00381 static void msc_out_of_memory(struct msc_interface *msc)
00382 {
00383 dbg_error("msc: Out of memory!\n");
00384 msc_phase_error(msc);
00385 }
00386
00387 static void msc_csw_sent(struct udc *udc, struct usb_request *req)
00388 {
00389 struct msc_interface *msc = req->context;
00390 struct buffer *buf;
00391
00392 buf = usb_req_get_first_buffer(req);
00393 assert(buf->addr.ptr == msc->csw.ptr);
00394
00395 dbg_verbose("msc: CSW sent, status=%d\n", req->status);
00396
00397 msc_queue_empty(msc);
00398
00399
00400 if (req->status)
00401 return;
00402
00403
00404 buffer_init_rx_mapped(buf, msc->cbw, sizeof(struct usb_msc_cbw));
00405 req->bytes_xfered = 0;
00406 req->req_done = msc_cbw_received;
00407
00408 udc_ep_submit_out_req(udc, msc->bulk_out_ep, req);
00409 }
00410
00411 static void msc_data_sent(struct udc *udc, struct usb_request *req)
00412 {
00413 struct msc_interface *msc = req->context;
00414 enum status_code status = req->status;
00415
00416 usb_req_free(req);
00417
00418 if (!status)
00419 msc_request_data_done(udc, msc);
00420 }
00421
00422 static void msc_buf_sent(struct udc *udc, struct usb_request *req)
00423 {
00424 struct buffer *buf;
00425
00426 buf = usb_req_get_first_buffer(req);
00427 buffer_free(buf);
00428 msc_data_sent(udc, req);
00429 }
00430
00431 static void msc_capacity_sent(struct udc *udc, struct usb_request *req)
00432 {
00433 struct buffer *buf;
00434
00435 buf = usb_req_get_first_buffer(req);
00436 buffer_dma_free(buf, sizeof(struct sbc_read_capacity10_data));
00437 msc_data_sent(udc, req);
00438 }
00439
00440 static void msc_vpd_serial_sent(struct udc *udc, struct usb_request *req)
00441 {
00442 struct buffer *buf;
00443
00444 buf = usb_req_get_first_buffer(req);
00445 buffer_dma_free(buf, MSC_VPD_SERIAL_BUF_SIZE);
00446 msc_data_sent(udc, req);
00447 }
00448
00449 static void msc_vpd_id_sent(struct udc *udc, struct usb_request *req)
00450 {
00451 struct buffer *buf;
00452
00453 buf = usb_req_get_first_buffer(req);
00454 buffer_dma_free(buf, MSC_VPD_ID_BUF_SIZE);
00455 msc_data_sent(udc, req);
00456 }
00457
00458 static void msc_sense_data_sent(struct udc *udc, struct usb_request *req)
00459 {
00460 struct msc_interface *msc = req->context;
00461 struct buffer *buf;
00462 enum status_code status = req->status;
00463
00464 dbg_verbose("msc sense data sent: %zu bytes, status %d\n",
00465 req->bytes_xfered, req->status);
00466
00467 msc_init_sense(msc, SCSI_SK_NO_SENSE,
00468 SCSI_ASC_NO_ADDITIONAL_SENSE_INFO, 0);
00469 buf = usb_req_get_first_buffer(req);
00470 buffer_free(buf);
00471 usb_req_free(req);
00472
00473 if (!status)
00474 msc_request_data_done(udc, msc);
00475 }
00476
00477 static void msc_mode_params_sent(struct udc *udc, struct usb_request *req)
00478 {
00479 struct buffer *buf;
00480
00481 buf = usb_req_get_first_buffer(req);
00482 buffer_dma_free(buf, MSC_MODE_PARAM_HDR_BUF_LEN);
00483 msc_data_sent(udc, req);
00484 }
00485
00486 static long msc_validate_req(struct msc_interface *msc, struct usb_msc_cbw *cbw,
00487 uint32_t alloc_len, uint8_t dir_flag)
00488 {
00489 uint32_t cbw_len;
00490
00491 cbw_len = le32_to_cpu(cbw->dCBWDataTransferLength);
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 if ((cbw->bmCBWFlags ^ dir_flag) & USB_CBW_DIRECTION_IN
00503 || cbw_len < alloc_len) {
00504 msc_phase_error(msc);
00505 return -1;
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 return cbw_len - alloc_len;
00517 }
00518
00519 static void msc_test_unit_ready(struct msc_interface *msc, struct udc *udc,
00520 uint32_t cbw_data_len)
00521 {
00522 dbg_verbose("msc TEST UNIT READY len %lu\n", cbw_data_len);
00523
00524 if (msc->not_ready) {
00525 msc_request_failed(msc, cbw_data_len, USB_CSW_STATUS_FAIL,
00526 SCSI_SK_NOT_READY,
00527 msc->busy_asc);
00528 } else if (test_bit(BDEV_PRESENT, &msc->bdev->flags)) {
00529 msc_prepare_csw(msc, cbw_data_len, USB_CSW_STATUS_PASS);
00530 msc_request_done_nodata(udc, msc, cbw_data_len);
00531 } else {
00532 msc_request_failed(msc, cbw_data_len, USB_CSW_STATUS_FAIL,
00533 SCSI_SK_NOT_READY,
00534 SCSI_ASC_MEDIUM_NOT_PRESENT);
00535 }
00536 }
00537
00538 static void msc_request_sense(struct msc_interface *msc, struct udc *udc,
00539 struct usb_msc_cbw *cbw)
00540 {
00541 struct usb_request *req;
00542 struct buffer *buf;
00543 const uint8_t *cdb = cbw->CDB;
00544 long residue;
00545 uint8_t alloc_len;
00546
00547 alloc_len = scsi_cdb6_get_alloc_len(cdb);
00548
00549 dbg_verbose("msc: REQUEST SENSE len %u (sense len %u)\n",
00550 alloc_len, msc_sense_len(msc));
00551
00552 residue = msc_validate_req(msc, cbw, alloc_len, USB_CBW_DIRECTION_IN);
00553 if (residue < 0)
00554 return;
00555
00556 if (alloc_len > 0) {
00557
00558
00559
00560
00561
00562
00563 req = usb_req_alloc();
00564 if (!req)
00565 goto err_req_alloc;
00566 buf = buffer_alloc();
00567 if (!buf)
00568 goto err_buf_alloc;
00569
00570 buffer_init_tx_mapped(buf, msc->sense_data,
00571 min_u(alloc_len, msc_sense_len(msc)));
00572 usb_req_add_buffer(req, buf);
00573 req->context = msc;
00574 req->req_done = msc_sense_data_sent;
00575
00576 residue += alloc_len - buf->len;
00577 msc_prepare_csw(msc, residue, USB_CSW_STATUS_PASS);
00578 udc_ep_submit_in_req(udc, msc->bulk_in_ep, req);
00579
00580 msc_request_done(udc, msc, residue);
00581 } else {
00582
00583
00584
00585
00586 msc_init_sense(msc, SCSI_SK_NO_SENSE,
00587 SCSI_ASC_NO_ADDITIONAL_SENSE_INFO, 0);
00588 msc_prepare_csw(msc, residue, USB_CSW_STATUS_PASS);
00589 msc_request_done_nodata(udc, msc, residue);
00590 }
00591
00592 return;
00593
00594 err_buf_alloc:
00595 usb_req_free(req);
00596 err_req_alloc:
00597 msc_out_of_memory(msc);
00598 }
00599
00600 static int msc_vpd_supported_pages(struct msc_interface *msc,
00601 struct usb_request *req, size_t alloc_len)
00602 {
00603 static const uint8_t vpd_page[] = {
00604 SCSI_INQ_PQ_CONNECTED | SCSI_INQ_DT_DIR_ACCESS,
00605 SCSI_VPD_SUPPORTED_PAGES,
00606 0x00,
00607 3,
00608 SCSI_VPD_SUPPORTED_PAGES,
00609 SCSI_VPD_UNIT_SERIAL_NUMBER,
00610 SCSI_VPD_DEVICE_IDENTIFICATION,
00611 };
00612 struct buffer *buf;
00613 size_t total_len = 0;
00614
00615 if (alloc_len) {
00616 buf = buffer_alloc();
00617 if (!buf)
00618 return -1;
00619
00620 total_len = min_u(alloc_len, sizeof(vpd_page));
00621 buffer_init_tx(buf, &vpd_page, total_len);
00622 usb_req_add_buffer(req, buf);
00623 req->req_done = msc_buf_sent;
00624 }
00625
00626 return total_len;
00627 }
00628
00629 static int msc_vpd_serial_number(struct msc_interface *msc,
00630 struct usb_request *req, size_t alloc_len)
00631 {
00632 struct buffer *buf;
00633 uint8_t *vpd_page;
00634 const char *serial;
00635 size_t serial_len;
00636 size_t total_len = 0;
00637
00638 if (alloc_len) {
00639 serial = app_get_serial_number();
00640 serial_len = strlen(serial);
00641
00642
00643
00644
00645
00646
00647
00648 assert(serial_len <= MSC_MAX_SERIAL_LEN);
00649
00650 buf = buffer_dma_alloc(MSC_VPD_SERIAL_BUF_SIZE);
00651 if (!buf)
00652 return -1;
00653
00654 vpd_page = buf->addr.ptr;
00655 vpd_page[0] = SCSI_INQ_PQ_CONNECTED | SCSI_INQ_DT_DIR_ACCESS;
00656 vpd_page[1] = SCSI_VPD_UNIT_SERIAL_NUMBER;
00657 vpd_page[2] = 0;
00658 vpd_page[3] = MSC_MAX_SERIAL_LEN;
00659 memset(vpd_page + SCSI_VPD_HEADER_SIZE,
00660 ' ', MSC_MAX_SERIAL_LEN - serial_len);
00661 memcpy(vpd_page + MSC_VPD_SERIAL_BUF_SIZE - serial_len,
00662 serial, serial_len);
00663
00664 total_len = MSC_VPD_SERIAL_BUF_SIZE;
00665 if (alloc_len < total_len) {
00666 total_len = alloc_len;
00667 buffer_resize(buf, total_len);
00668 }
00669
00670 usb_req_add_buffer(req, buf);
00671 req->req_done = msc_vpd_serial_sent;
00672 }
00673
00674 return total_len;
00675 }
00676
00677 static int msc_vpd_device_id(struct msc_interface *msc,
00678 struct usb_request *req, size_t alloc_len)
00679 {
00680 struct buffer *buf;
00681 const char *serial;
00682 size_t serial_len;
00683 uint8_t *vpd_page;
00684 uint8_t *p;
00685 size_t total_len = 0;
00686
00687 if (alloc_len) {
00688 serial = app_get_serial_number();
00689 serial_len = strlen(serial);
00690
00691
00692
00693
00694
00695
00696
00697 assert(serial_len <= MSC_MAX_SERIAL_LEN);
00698
00699 buf = buffer_dma_alloc(MSC_VPD_ID_BUF_SIZE);
00700 if (!buf)
00701 return -1;
00702
00703 vpd_page = buf->addr.ptr;
00704 vpd_page[0] = SCSI_INQ_PQ_CONNECTED | SCSI_INQ_DT_DIR_ACCESS;
00705 vpd_page[1] = SCSI_VPD_DEVICE_IDENTIFICATION;
00706 vpd_page[2] = 0;
00707 vpd_page[3] = MSC_VPD_ID_BUF_SIZE - SCSI_VPD_HEADER_SIZE;
00708 vpd_page[4] = SCSI_VPD_CODE_SET_ASCII;
00709 vpd_page[5] = SCSI_VPD_ID_TYPE_T10;
00710 vpd_page[6] = 0;
00711 vpd_page[7] = MSC_VPD_ID_BUF_SIZE - SCSI_VPD_HEADER_SIZE
00712 - SCSI_VPD_ID_HEADER_SIZE;
00713
00714
00715 p = vpd_page + SCSI_VPD_HEADER_SIZE + SCSI_VPD_ID_HEADER_SIZE;
00716 memcpy(p, msc_inquiry_data.vendor_id, 8 + 16);
00717
00718
00719 p += 8 + 16;
00720 memset(p, ' ', MSC_MAX_SERIAL_LEN - serial_len);
00721 p += MSC_MAX_SERIAL_LEN - serial_len;
00722 memcpy(p, serial, serial_len);
00723
00724 total_len = MSC_VPD_ID_BUF_SIZE;
00725 if (alloc_len < total_len) {
00726 total_len = alloc_len;
00727 buffer_resize(buf, total_len);
00728 }
00729
00730 usb_req_add_buffer(req, buf);
00731 req->req_done = msc_vpd_id_sent;
00732 }
00733
00734 return total_len;
00735 }
00736
00737 static void msc_inquiry(struct msc_interface *msc, struct udc *udc,
00738 struct usb_msc_cbw *cbw)
00739 {
00740 struct usb_request *req;
00741 struct buffer *buf;
00742 long residue;
00743 long ret;
00744 uint16_t alloc_len;
00745 const uint8_t *cdb = cbw->CDB;
00746 size_t total_len;
00747 uint8_t page_code;
00748
00749 alloc_len = scsi_cdb_get_u16(cdb, 3);
00750
00751 dbg_verbose("msc: INQUIRY %u (inq len %zu)\n",
00752 alloc_len, sizeof(msc_inquiry_data));
00753
00754 residue = msc_validate_req(msc, cbw, alloc_len, USB_CBW_DIRECTION_IN);
00755 if (residue < 0)
00756 return;
00757
00758 req = usb_req_alloc();
00759 if (!req)
00760 goto err_req_alloc;
00761 req->context = msc;
00762
00763 total_len = 0;
00764 page_code = cdb[2];
00765
00766 if (cdb[1] & SCSI_INQ_REQ_EVPD) {
00767
00768 switch (page_code) {
00769 case SCSI_VPD_SUPPORTED_PAGES:
00770 ret = msc_vpd_supported_pages(msc, req, alloc_len);
00771 break;
00772 case SCSI_VPD_UNIT_SERIAL_NUMBER:
00773 ret = msc_vpd_serial_number(msc, req, alloc_len);
00774 break;
00775 case SCSI_VPD_DEVICE_IDENTIFICATION:
00776 ret = msc_vpd_device_id(msc, req, alloc_len);
00777 break;
00778 default:
00779 dbg_info("msc: unsupported VPD page %02x requested\n",
00780 page_code);
00781 goto illegal_request;
00782 }
00783
00784 if (ret < 0)
00785 goto err_buf_alloc;
00786
00787 total_len = ret;
00788 } else if (page_code != 0) {
00789
00790 dbg_info("msc: INQUIRY PC=%02x but EVPD not set\n", page_code);
00791 goto illegal_request;
00792 } else if (alloc_len) {
00793
00794 buf = buffer_alloc();
00795 if (!buf)
00796 goto err_buf_alloc;
00797
00798 total_len = min_u(alloc_len, sizeof(msc_inquiry_data));
00799 buffer_init_tx(buf, &msc_inquiry_data, total_len);
00800 usb_req_add_buffer(req, buf);
00801 req->req_done = msc_buf_sent;
00802 }
00803
00804 residue += alloc_len - total_len;
00805 msc_prepare_csw(msc, residue, USB_CSW_STATUS_PASS);
00806
00807 if (total_len) {
00808 udc_ep_submit_in_req(udc, msc->bulk_in_ep, req);
00809 msc_request_done(udc, msc, residue);
00810 } else {
00811 usb_req_free(req);
00812 msc_request_done_nodata(udc, msc, residue);
00813 }
00814
00815 return;
00816
00817 illegal_request:
00818 msc_request_failed(msc, alloc_len + residue,
00819 USB_CSW_STATUS_FAIL,
00820 SCSI_SK_ILLEGAL_REQUEST,
00821 SCSI_ASC_INVALID_FIELD_IN_CDB);
00822 usb_req_free(req);
00823 return;
00824
00825 err_buf_alloc:
00826 usb_req_free(req);
00827 err_req_alloc:
00828 msc_out_of_memory(msc);
00829 }
00830
00831 static long msc_add_mode_pages(struct msc_interface *msc,
00832 struct usb_request *req, uint32_t avail_len,
00833 const uint8_t *cdb, uint32_t cbw_data_len)
00834 {
00835
00836 if (scsi_mode_sense_get_pc(cdb) == SCSI_MS_PC_CHANGEABLE) {
00837 dbg_info("msc: changeable mode pages not supported\n");
00838 goto invalid_request;
00839 }
00840
00841
00842
00843
00844
00845
00846 switch (scsi_mode_sense_get_page_code(cdb)) {
00847 case 0:
00848
00849 break;
00850 case SCSI_MS_PAGE_ALL:
00851
00852 break;
00853 default:
00854 dbg_info("msc: unsupported mode page 0x%x\n",
00855 scsi_mode_sense_get_page_code(cdb));
00856 goto invalid_request;
00857 }
00858
00859 return 0;
00860
00861 invalid_request:
00862 msc_request_failed(msc, cbw_data_len, USB_CSW_STATUS_FAIL,
00863 SCSI_SK_ILLEGAL_REQUEST,
00864 SCSI_ASC_INVALID_FIELD_IN_CDB);
00865 return -1;
00866 }
00867
00868 static void msc_mode_sense(struct msc_interface *msc, struct udc *udc,
00869 struct usb_msc_cbw *cbw, uint32_t alloc_len)
00870 {
00871 union msc_mode_param_header *header;
00872 struct usb_request *req;
00873 struct buffer *buf;
00874 const uint8_t *cdb = cbw->CDB;
00875 long residue;
00876 long ret;
00877 size_t total_size;
00878
00879 dbg_verbose("msc MODE SENSE(N) page %u PC%u len %lu\n",
00880 scsi_mode_sense_get_page_code(cdb),
00881 scsi_mode_sense_get_pc(cdb),
00882 alloc_len);
00883
00884 residue = msc_validate_req(msc, cbw, alloc_len, USB_CBW_DIRECTION_IN);
00885 if (residue < 0)
00886 return;
00887
00888 req = usb_req_alloc();
00889 if (!req)
00890 goto err_req_alloc;
00891 req->context = msc;
00892 req->req_done = msc_mode_params_sent;
00893
00894
00895
00896
00897
00898 buf = buffer_dma_alloc(MSC_MODE_PARAM_HDR_BUF_LEN);
00899 if (!buf)
00900 goto err_buf_alloc;
00901 usb_req_add_buffer(req, buf);
00902
00903 header = buf->addr.ptr;
00904 memset(header, 0, MSC_MODE_PARAM_HDR_BUF_LEN);
00905
00906
00907 if (scsi_cdb_get_opcode(cdb) == SCSI_CMD_MODE_SENSE6) {
00908 if (!test_bit(BDEV_WRITEABLE, &msc->bdev->flags))
00909 header->h6.device_specific_parameter = SCSI_MS_SBC_WP;
00910 total_size = sizeof(header->h6);
00911 } else {
00912 if (!test_bit(BDEV_WRITEABLE, &msc->bdev->flags))
00913 header->h10.device_specific_parameter = SCSI_MS_SBC_WP;
00914 total_size = sizeof(header->h10);
00915 }
00916
00917
00918
00919
00920
00921 if (!scsi_mode_sense_dbd_is_set(cdb)) {
00922 struct sbc_slba_block_desc *desc;
00923
00924 total_size += sizeof(*desc);
00925 if (scsi_cdb_get_opcode(cdb) == SCSI_CMD_MODE_SENSE6) {
00926 header->h6.block_descriptor_length = sizeof(*desc);
00927 desc = (struct sbc_slba_block_desc *)(&header->h6 + 1);
00928 } else {
00929 header->h10.block_descriptor_length
00930 = cpu_to_be16(sizeof(*desc));
00931 desc = (struct sbc_slba_block_desc *)(&header->h10 + 1);
00932 }
00933 desc->nr_blocks = cpu_to_be32(msc->bdev->nr_blocks);
00934 desc->block_len = cpu_to_be32(blkdev_get_block_size(msc->bdev));
00935 assert(!(be32_to_cpu(desc->block_len)
00936 & ~SBC_SLBA_BLOCK_LEN_MASK));
00937 }
00938
00939 buffer_resize(buf, total_size);
00940
00941
00942 ret = msc_add_mode_pages(msc, req, alloc_len - total_size, cdb,
00943 alloc_len + residue);
00944 if (ret < 0) {
00945 usb_req_free(req);
00946 buffer_dma_free(buf, MSC_MODE_PARAM_HDR_BUF_LEN);
00947 return;
00948 }
00949
00950 total_size += ret;
00951 if (scsi_cdb_get_opcode(cdb) == SCSI_CMD_MODE_SENSE6)
00952 header->h6.mode_data_length = total_size - 1;
00953 else
00954 header->h10.mode_data_length = cpu_to_be16(total_size - 2);
00955
00956
00957
00958
00959
00960 residue += alloc_len - min_u(alloc_len, total_size);
00961 msc_prepare_csw(msc, residue, USB_CSW_STATUS_PASS);
00962 if (alloc_len > 0) {
00963 udc_ep_submit_in_req(udc, msc->bulk_in_ep, req);
00964 msc_request_done(udc, msc, residue);
00965 } else {
00966 usb_req_free(req);
00967 buffer_dma_free(buf, MSC_MODE_PARAM_HDR_BUF_LEN);
00968 msc_request_done_nodata(udc, msc, residue);
00969 }
00970
00971 return;
00972
00973 err_buf_alloc:
00974 usb_req_free(req);
00975 err_req_alloc:
00976 msc_out_of_memory(msc);
00977 }
00978
00979 static void msc_read_capacity(struct msc_interface *msc, struct udc *udc,
00980 struct usb_msc_cbw *cbw)
00981 {
00982 struct sbc_read_capacity10_data *response;
00983 struct usb_request *req;
00984 struct buffer *buf;
00985 long residue;
00986
00987 build_assert(sizeof(*response) == 8);
00988
00989 dbg_verbose("msc READ CAPACITY LBA %lx blklen %u\n",
00990 msc->bdev->nr_blocks - 1,
00991 blkdev_get_block_size(msc->bdev));
00992
00993 residue = msc_validate_req(msc, cbw, 8, USB_CBW_DIRECTION_IN);
00994 if (residue < 0)
00995 return;
00996
00997 req = usb_req_alloc();
00998 if (!req)
00999 goto err_req_alloc;
01000 req->req_done = msc_capacity_sent;
01001 req->context = msc;
01002
01003 buf = buffer_dma_alloc(sizeof(*response));
01004 if (!buf)
01005 goto err_buf_alloc;
01006 usb_req_add_buffer(req, buf);
01007
01008 response = buf->addr.ptr;
01009 response->max_lba = cpu_to_be32(msc->bdev->nr_blocks - 1);
01010 response->block_len = cpu_to_be32(blkdev_get_block_size(msc->bdev));
01011
01012 msc_prepare_csw(msc, residue, USB_CSW_STATUS_PASS);
01013 udc_ep_submit_in_req(udc, msc->bulk_in_ep, req);
01014 msc_request_done(udc, msc, residue);
01015
01016 return;
01017
01018 err_buf_alloc:
01019 usb_req_free(req);
01020 err_req_alloc:
01021 msc_out_of_memory(msc);
01022 }
01023
01024 static uint32_t msc_fill_buffer_list(struct slist *buf_list,
01025 unsigned int block_size, uint32_t nr_blocks)
01026 {
01027 uint32_t blocks_remaining;
01028 uint32_t blocks_per_buf;
01029 uint_fast8_t i;
01030
01031 blocks_remaining = nr_blocks;
01032 blocks_per_buf = MSC_DATA_BUFFER_SIZE / block_size;
01033
01034 for (i = 0; i < MSC_MAX_NR_BUFFERS; i++) {
01035 struct buffer *buf;
01036
01037 buf = buffer_dma_alloc(MSC_DATA_BUFFER_SIZE);
01038 if (!buf)
01039 break;
01040
01041 if (blocks_per_buf > blocks_remaining) {
01042 blocks_per_buf = blocks_remaining;
01043 buffer_resize(buf, blocks_per_buf * block_size);
01044 }
01045
01046 slist_insert_tail(buf_list, &buf->node);
01047 blocks_remaining -= blocks_per_buf;
01048 if (!blocks_remaining)
01049 break;
01050 }
01051
01052 return nr_blocks - blocks_remaining;
01053 }
01054
01067 static int msc_submit_read_buffers(struct msc_interface *msc,
01068 struct block_device *bdev, struct block_request *breq,
01069 uint32_t nr_blocks)
01070 {
01071 struct slist buf_list;
01072 uint32_t blocks_queued;
01073
01074 slist_init(&buf_list);
01075 blocks_queued = msc_fill_buffer_list(&buf_list,
01076 blkdev_get_block_size(bdev), nr_blocks);
01077
01078 dbg_verbose("msc: blocks %lu/%lu queued for read\n", blocks_queued,
01079 nr_blocks);
01080
01081 if (unlikely(!blocks_queued))
01082 return 0;
01083
01084
01085
01086
01087
01088 atomic_add(&msc->blk_blocks_pending, blocks_queued);
01089 if (block_submit_buf_list(bdev, breq, &buf_list)) {
01090 atomic_sub(&msc->blk_blocks_pending, blocks_queued);
01091 msc_free_dma_buf_list(&buf_list);
01092 return 0;
01093 }
01094
01095 msc->blocks_queued += blocks_queued;
01096
01097 return blocks_queued;
01098 }
01099
01111 static void msc_read_worker(struct msc_interface *msc)
01112 {
01113 struct block_device *bdev = msc->bdev;
01114 struct block_request *breq = msc->block_req;
01115 uint32_t blocks_remaining;
01116 uint32_t submitted;
01117 uint32_t blocks_per_seg;
01118
01119 cpu_irq_disable();
01120 dbg_verbose("msc: blk pending %u locked %d\n",
01121 atomic_read(&msc->blk_blocks_pending),
01122 msc->queue_locked);
01123 blocks_per_seg = MSC_DATA_BUFFER_SIZE / blkdev_get_block_size(bdev);
01124 while ((atomic_read(&msc->blk_blocks_pending) * blocks_per_seg)
01125 < MSC_MAX_NR_SEGS
01126 && !msc->queue_locked) {
01127 dbg_verbose("msc: read worker: q%lu <= t%lu s %d\n",
01128 msc->blocks_queued, msc->blocks_total,
01129 breq->status);
01130 assert(msc->blocks_queued <= msc->blocks_total);
01131 blocks_remaining = msc->blocks_total - msc->blocks_queued;
01132 if (!blocks_remaining)
01133 break;
01134
01135 msc->queue_locked = true;
01136 cpu_irq_enable();
01137
01138 submitted = msc_submit_read_buffers(msc, bdev, breq,
01139 blocks_remaining);
01140
01141 cpu_irq_disable();
01142 msc->queue_locked = false;
01143
01144 if (!submitted)
01145 break;
01146 }
01147 cpu_irq_enable();
01148
01149 dbg_verbose("msc read worker done\n");
01150 }
01151
01152 static void msc_read_data_sent(struct udc *udc, struct usb_request *req)
01153 {
01154 struct msc_interface *msc = req->context;
01155 uint32_t blocks_remaining;
01156 enum status_code status;
01157
01158 dbg_verbose("msc: data sent: first=%p last=%p\n",
01159 slist_peek_head_node(&req->buf_list),
01160 slist_peek_tail_node(&req->buf_list));
01161
01162 msc_free_dma_buf_list(&req->buf_list);
01163 status = req->status;
01164 usb_req_free(req);
01165
01166 assert(atomic_read(&msc->usb_reqs_pending) > 0);
01167 atomic_dec(&msc->usb_reqs_pending);
01168
01169
01170
01171
01172
01173 if (status) {
01174 block_abort_req(msc->bdev, msc->block_req);
01175 return;
01176 }
01177
01178 blocks_remaining = msc->blocks_total - msc->blocks_queued;
01179 if (!blocks_remaining)
01180 msc_request_data_done(udc, msc);
01181 else
01182 msc_read_worker(msc);
01183 }
01184
01185
01186
01187
01188
01189
01190
01191
01192 static void msc_block_read_started(struct block_device *bdev,
01193 struct block_request *breq)
01194 {
01195 struct msc_interface *msc = breq->context;
01196
01197 if (msc->blocks_queued < msc->blocks_total)
01198 msc_read_worker(msc);
01199 }
01200
01201 static void msc_block_read_done(struct block_device *bdev,
01202 struct block_request *breq)
01203 {
01204 struct msc_interface *msc = breq->context;
01205 struct usb_msc_csw *csw = msc_get_csw(msc);
01206 uint32_t residue;
01207
01208 assert(breq == msc->block_req);
01209
01210 residue = le32_to_cpu(csw->dCSWDataResidue);
01211
01212 if (breq->status) {
01213 uint32_t blocks_xfered;
01214 struct usb_msc_cbw *cbw;
01215
01216 blocks_xfered = blk_req_get_blocks_xfered(bdev, breq);
01217
01218 dbg_warning("msc: block read failed: %d (after %lu blocks)\n",
01219 breq->status, blocks_xfered);
01220
01221 cbw = msc_get_cbw(msc);
01222 residue = le32_to_cpu(cbw->dCBWDataTransferLength);
01223 residue -= blkdev_get_block_size(bdev) * blocks_xfered;
01224 csw->dCSWDataResidue = cpu_to_le32(residue);
01225 csw->bCSWStatus = USB_CSW_STATUS_FAIL;
01226
01227 msc_init_sense(msc, SCSI_SK_MEDIUM_ERROR,
01228 SCSI_ASC_UNRECOVERED_READ_ERROR,
01229 msc->first_lba + blocks_xfered);
01230 }
01231
01232 msc_request_done(msc->udc, msc, residue);
01233 }
01234
01235 static void msc_block_read_buffers_done(struct block_device *bdev,
01236 struct block_request *breq, struct slist *buf_list)
01237 {
01238 struct msc_interface *msc = breq->context;
01239 struct usb_request *req;
01240 struct buffer *buf;
01241 uint32_t nr_blocks;
01242
01243 assert(!slist_is_empty(buf_list));
01244
01245 dbg_verbose("msc: read bufs done: status %d\n", breq->status);
01246
01247 if (breq->status != OPERATION_IN_PROGRESS || !msc->bulk_in_ep) {
01248 dbg_verbose(" request terminated, discarding buffers\n");
01249 msc_free_dma_buf_list(buf_list);
01250 return;
01251 }
01252
01253 req = usb_req_alloc();
01254 if (!req) {
01255 block_abort_req(bdev, breq);
01256 msc_free_dma_buf_list(buf_list);
01257 msc_out_of_memory(msc);
01258 return;
01259 }
01260
01261 assert(atomic_read(&msc->blk_blocks_pending) > 0);
01262 atomic_inc(&msc->usb_reqs_pending);
01263
01264 for (nr_blocks = 0, buf = buf_list_peek_head(buf_list);
01265 slist_node_is_valid(buf_list, &buf->node);
01266 buf = buf_list_peek_next(buf)) {
01267 nr_blocks += buf->len / blkdev_get_block_size(bdev);
01268 }
01269 atomic_sub(&msc->blk_blocks_pending, nr_blocks);
01270
01271 slist_move_to_tail(&req->buf_list, buf_list);
01272 req->req_done = msc_read_data_sent;
01273 req->context = msc;
01274 dbg_verbose(" submitting IN request...\n");
01275 udc_ep_submit_in_req(msc->udc, msc->bulk_in_ep, req);
01276 }
01277
01286 static void msc_do_read(struct msc_interface *msc, struct udc *udc,
01287 struct usb_msc_cbw *cbw, uint32_t lba, uint32_t nr_blocks)
01288 {
01289 struct block_device *bdev = msc->bdev;
01290 struct block_request *breq;
01291 long residue;
01292 uint32_t cdb_data_len;
01293 uint32_t blocks_queued;
01294 irqflags_t iflags;
01295
01296 dbg_verbose("msc READ(x) %lu blocks, LBA %lu\n", nr_blocks, lba);
01297
01298 assert(!msc->xfer_in_progress);
01299
01300
01301
01302
01303
01304 cdb_data_len = nr_blocks * blkdev_get_block_size(bdev);
01305
01306 residue = msc_validate_req(msc, cbw, cdb_data_len,
01307 USB_CBW_DIRECTION_IN);
01308 if (unlikely(residue < 0))
01309 return;
01310
01311 iflags = cpu_irq_save();
01312 if (msc->not_ready) {
01313 cpu_irq_restore(iflags);
01314 msc_request_failed(msc,
01315 le32_to_cpu(cbw->dCBWDataTransferLength),
01316 USB_CSW_STATUS_FAIL,
01317 SCSI_SK_NOT_READY, msc->busy_asc);
01318 return;
01319 }
01320
01321 msc->xfer_in_progress = true;
01322 cpu_irq_restore(iflags);
01323
01324 msc_prepare_csw(msc, residue, USB_CSW_STATUS_PASS);
01325
01326
01327 if (unlikely(nr_blocks == 0)) {
01328 msc_request_done_nodata(udc, msc, residue);
01329 return;
01330 }
01331
01332 msc->blocks_total = nr_blocks;
01333 msc->blocks_queued = 0;
01334 msc->queue_locked = true;
01335 atomic_write(&msc->blk_blocks_pending, 0);
01336 atomic_write(&msc->usb_reqs_pending, 0);
01337
01338 breq = msc->block_req;
01339 breq->req_started = msc_block_read_started;
01340 breq->req_done = msc_block_read_done;
01341 breq->buf_list_done = msc_block_read_buffers_done;
01342 breq->context = msc;
01343 block_queue_req(bdev, breq, lba, nr_blocks, BLK_OP_READ);
01344
01345 blocks_queued = msc_submit_read_buffers(msc, bdev, breq, nr_blocks);
01346 if (blocks_queued == 0) {
01347 block_abort_req(bdev, breq);
01348 msc_out_of_memory(msc);
01349 }
01350 msc->queue_locked = false;
01351 }
01352
01353 static void msc_write_data_received(struct udc *udc, struct usb_request *req);
01354
01366 static int msc_submit_write_data_req(struct msc_interface *msc,
01367 struct block_device *bdev, uint32_t nr_blocks)
01368 {
01369 struct usb_request *req;
01370 uint32_t blocks_queued;
01371
01372 req = usb_req_alloc();
01373 if (!req)
01374 return 0;
01375
01376 req->context = msc;
01377 req->req_done = msc_write_data_received;
01378
01379 blocks_queued = msc_fill_buffer_list(&req->buf_list,
01380 blkdev_get_block_size(bdev), nr_blocks);
01381
01382 dbg_verbose("msc: blocks %lu/%lu queued for write\n", blocks_queued,
01383 nr_blocks);
01384
01385 if (unlikely(!blocks_queued)) {
01386 usb_req_free(req);
01387 return 0;
01388 }
01389
01390 msc->blocks_queued += blocks_queued;
01391
01392 atomic_inc(&msc->usb_reqs_pending);
01393 udc_ep_submit_out_req(msc->udc, msc->bulk_out_ep, req);
01394
01395 return blocks_queued;
01396 }
01397
01409 static void msc_write_worker(void *data)
01410 {
01411 struct msc_interface *msc = data;
01412 struct block_device *bdev = msc->bdev;
01413 uint32_t blocks_remaining;
01414 uint32_t submitted;
01415
01416 while (atomic_read(&msc->usb_reqs_pending) < MSC_MAX_NR_SEGS
01417 && !msc->queue_locked) {
01418 dbg_verbose("msc: write worker: q%lu <= 5%lu s %d\n",
01419 msc->blocks_queued, msc->blocks_total,
01420 msc->block_req->status);
01421 assert(msc->blocks_queued <= msc->blocks_total);
01422 blocks_remaining = msc->blocks_total - msc->blocks_queued;
01423 if (!blocks_remaining)
01424 break;
01425
01426 msc->queue_locked = true;
01427 cpu_irq_enable();
01428
01429 submitted = msc_submit_write_data_req(msc, bdev,
01430 blocks_remaining);
01431
01432 cpu_irq_disable();
01433 msc->queue_locked = false;
01434
01435 if (!submitted)
01436 break;
01437 }
01438 }
01439
01440 static void msc_block_write_started(struct block_device *bdev,
01441 struct block_request *breq)
01442 {
01443 struct msc_interface *msc = breq->context;
01444
01445 if (msc->blocks_queued < msc->blocks_total)
01446 msc_write_worker(msc);
01447 }
01448
01449 static void msc_block_write_done(struct block_device *bdev,
01450 struct block_request *breq)
01451 {
01452 struct msc_interface *msc = breq->context;
01453 struct usb_msc_csw *csw = msc_get_csw(msc);
01454 uint32_t residue;
01455
01456 assert(breq == msc->block_req);
01457
01458 residue = le32_to_cpu(csw->dCSWDataResidue);
01459
01460 if (breq->status) {
01461 uint32_t blocks_xfered;
01462 struct usb_msc_cbw *cbw;
01463
01464 blocks_xfered = blk_req_get_blocks_xfered(bdev, breq);
01465
01466 dbg_warning("msc: block write failed: %d (after %lu blocks)\n",
01467 breq->status, blocks_xfered);
01468
01469 cbw = msc_get_cbw(msc);
01470 residue = le32_to_cpu(cbw->dCBWDataTransferLength);
01471 residue -= blkdev_get_block_size(bdev) * blocks_xfered;
01472 csw->dCSWDataResidue = cpu_to_le32(residue);
01473 csw->bCSWStatus = USB_CSW_STATUS_FAIL;
01474
01475 msc_init_sense(msc, SCSI_SK_MEDIUM_ERROR,
01476 SCSI_ASC_WRITE_ERROR,
01477 msc->first_lba + blocks_xfered);
01478 }
01479
01480 msc_request_done(msc->udc, msc, residue);
01481 msc_request_data_done(msc->udc, msc);
01482 }
01483
01484 static void msc_block_write_buffers_done(struct block_device *bdev,
01485 struct block_request *breq, struct slist *buf_list)
01486 {
01487 struct msc_interface *msc = breq->context;
01488 struct buffer *buf;
01489 uint32_t nr_blocks;
01490
01491 msc_free_dma_buf_list(buf_list);
01492
01493 assert(atomic_read(&msc->blk_blocks_pending) > 0);
01494
01495 for (nr_blocks = 0, buf = buf_list_peek_head(buf_list);
01496 slist_node_is_valid(buf_list, &buf->node);
01497 buf = buf_list_peek_next(buf)) {
01498 nr_blocks += buf->len / blkdev_get_block_size(bdev);
01499 }
01500 atomic_sub(&msc->blk_blocks_pending, nr_blocks);
01501
01502 assert(msc->blocks_queued <= msc->blocks_total);
01503 if (msc->blocks_queued < msc->blocks_total)
01504 msc_write_worker(msc);
01505 }
01506
01507 static void msc_write_data_received(struct udc *udc, struct usb_request *req)
01508 {
01509 struct slist buf_list;
01510 struct msc_interface *msc = req->context;
01511 struct block_device *bdev;
01512 struct block_request *breq;
01513 enum status_code status;
01514 struct buffer *buf;
01515 uint32_t nr_blocks;
01516
01517 status = req->status;
01518 slist_init(&buf_list);
01519 slist_move_to_tail(&buf_list, &req->buf_list);
01520 usb_req_free(req);
01521
01522 bdev = msc->bdev;
01523 breq = msc->block_req;
01524
01525 for (nr_blocks = 0, buf = buf_list_peek_head(&buf_list);
01526 slist_node_is_valid(&buf_list, &buf->node);
01527 buf = buf_list_peek_next(buf)) {
01528 nr_blocks += buf->len / blkdev_get_block_size(bdev);
01529 }
01530
01531 if (!status) {
01532 atomic_add(&msc->blk_blocks_pending, nr_blocks);
01533 atomic_dec(&msc->usb_reqs_pending);
01534
01535 if (block_submit_buf_list(bdev, breq, &buf_list)) {
01536 atomic_sub(&msc->blk_blocks_pending, nr_blocks);
01537 msc_free_dma_buf_list(&buf_list);
01538 }
01539 } else {
01540 block_abort_req(bdev, breq);
01541 }
01542 }
01543
01544 static void msc_do_write(struct msc_interface *msc, struct udc *udc,
01545 struct usb_msc_cbw *cbw, uint32_t lba, uint32_t nr_blocks)
01546 {
01547 struct block_device *bdev = msc->bdev;
01548 struct block_request *breq;
01549 long residue;
01550 uint32_t cdb_data_len;
01551 uint32_t blocks_queued;
01552 irqflags_t iflags;
01553
01554 dbg_verbose("msc WRITE(x) %lu blocks, LBA %lu\n", nr_blocks, lba);
01555
01556 assert(!msc->xfer_in_progress);
01557
01558
01559
01560
01561
01562 cdb_data_len = nr_blocks * blkdev_get_block_size(bdev);
01563
01564 residue = msc_validate_req(msc, cbw, cdb_data_len, 0);
01565 if (unlikely(residue < 0))
01566 return;
01567
01568 iflags = cpu_irq_save();
01569 if (msc->not_ready) {
01570 cpu_irq_restore(iflags);
01571 msc_request_failed(msc,
01572 le32_to_cpu(cbw->dCBWDataTransferLength),
01573 USB_CSW_STATUS_FAIL,
01574 SCSI_SK_NOT_READY, msc->busy_asc);
01575 return;
01576 }
01577
01578 msc->xfer_in_progress = true;
01579 cpu_irq_restore(iflags);
01580
01581 msc_prepare_csw(msc, residue, USB_CSW_STATUS_PASS);
01582
01583
01584 if (unlikely(nr_blocks == 0)) {
01585 msc_request_done_nodata(udc, msc, residue);
01586 return;
01587 }
01588
01589 msc->blocks_total = nr_blocks;
01590 msc->blocks_queued = 0;
01591 msc->queue_locked = true;
01592 atomic_write(&msc->blk_blocks_pending, 0);
01593 atomic_write(&msc->usb_reqs_pending, 0);
01594
01595 breq = msc->block_req;
01596 breq->req_started = msc_block_write_started;
01597 breq->req_done = msc_block_write_done;
01598 breq->buf_list_done = msc_block_write_buffers_done;
01599 breq->context = msc;
01600 block_queue_req(bdev, breq, lba, nr_blocks, BLK_OP_WRITE);
01601
01602 blocks_queued = msc_submit_write_data_req(msc, bdev, nr_blocks);
01603 if (blocks_queued == 0) {
01604 block_abort_req(bdev, breq);
01605 msc_out_of_memory(msc);
01606 }
01607 msc->queue_locked = false;
01608 }
01609
01610 static void msc_verify_read(struct msc_interface *msc,
01611 struct block_device *bdev, uint32_t first_lba,
01612 uint32_t nr_blocks);
01613 static void msc_verify_bytchk(struct msc_interface *msc,
01614 struct block_device *bdev, uint32_t first_lba,
01615 uint32_t nr_blocks);
01616
01617 static void msc_verify_bytchk(struct msc_interface *msc,
01618 struct block_device *bdev,
01619 uint32_t first_lba, uint32_t nr_blocks)
01620 {
01621 msc_request_failed(msc, le32_to_cpu(msc_get_csw(msc)->dCSWDataResidue),
01622 USB_CSW_STATUS_FAIL, SCSI_SK_ILLEGAL_REQUEST,
01623 SCSI_ASC_INVALID_FIELD_IN_CDB);
01624 }
01625
01626 static void msc_verify_read_done(struct block_device *bdev,
01627 struct block_request *breq)
01628 {
01629 struct msc_interface *msc = breq->context;
01630 struct usb_msc_csw *csw = msc_get_csw(msc);
01631
01632 assert(breq == msc->block_req);
01633
01634 if (breq->status) {
01635 uint32_t blocks_xfered;
01636
01637 blocks_xfered = blk_req_get_blocks_xfered(bdev, breq);
01638
01639 csw->bCSWStatus = USB_CSW_STATUS_FAIL;
01640 msc_init_sense(msc, SCSI_SK_MEDIUM_ERROR,
01641 SCSI_ASC_UNRECOVERED_READ_ERROR,
01642 msc->first_lba + blocks_xfered);
01643 }
01644
01645 msc_request_done_nodata(msc->udc, msc,
01646 le32_to_cpu(csw->dCSWDataResidue));
01647 }
01648
01649 static void msc_verify_read_buffers_done(struct block_device *bdev,
01650 struct block_request *breq, struct slist *buf_list)
01651 {
01652 struct slist new_buf_list;
01653 struct msc_interface *msc = breq->context;
01654 unsigned int block_size;
01655 uint32_t blocks_queued;
01656 uint32_t blocks_total;
01657 unsigned int blocks_per_buf;
01658
01659 blocks_total = msc->blocks_total;
01660 blocks_queued = msc->blocks_queued;
01661 block_size = blkdev_get_block_size(bdev);
01662 blocks_per_buf = MSC_DATA_BUFFER_SIZE / block_size;
01663 slist_init(&new_buf_list);
01664
01665 while (!slist_is_empty(buf_list)) {
01666 struct buffer *buf;
01667
01668 assert(blocks_queued <= blocks_total);
01669 if (blocks_queued == blocks_total)
01670 break;
01671
01672 buf = slist_pop_head(buf_list, struct buffer, node);
01673 blocks_queued += blocks_per_buf;
01674
01675 if (blocks_queued > blocks_total) {
01676 blocks_per_buf -= blocks_queued - blocks_total;
01677 buffer_resize(buf, block_size * blocks_per_buf);
01678 blocks_queued = blocks_total;
01679 }
01680 slist_insert_tail(&new_buf_list, &buf->node);
01681 }
01682
01683 if (!slist_is_empty(&new_buf_list)) {
01684 if (block_submit_buf_list(bdev, breq, &new_buf_list))
01685 msc_free_dma_buf_list(&new_buf_list);
01686 else
01687 msc->blocks_queued = blocks_queued;
01688 }
01689
01690
01691 msc_free_dma_buf_list(buf_list);
01692 }
01693
01694 static void msc_verify_read(struct msc_interface *msc, struct block_device *bdev,
01695 uint32_t first_lba, uint32_t nr_blocks)
01696 {
01697 struct slist buf_list;
01698 struct block_request *breq;
01699 uint32_t blocks_queued;
01700
01701
01702
01703
01704
01705 msc->blocks_total = nr_blocks;
01706 breq = msc->block_req;
01707 breq->req_started = NULL;
01708 breq->req_done = msc_verify_read_done;
01709 breq->buf_list_done = msc_verify_read_buffers_done;
01710 breq->context = msc;
01711 block_queue_req(bdev, breq, first_lba, nr_blocks, BLK_OP_READ);
01712
01713 slist_init(&buf_list);
01714
01715 blocks_queued = msc_fill_buffer_list(&buf_list,
01716 blkdev_get_block_size(bdev), nr_blocks);
01717
01718 if (unlikely(blocks_queued == 0)) {
01719 block_abort_req(bdev, breq);
01720 msc_out_of_memory(msc);
01721 return;
01722 }
01723
01724 msc->blocks_queued = blocks_queued;
01725 if (block_submit_buf_list(bdev, breq, &buf_list)) {
01726 block_abort_req(bdev, breq);
01727 msc_free_dma_buf_list(&buf_list);
01728 msc_out_of_memory(msc);
01729 }
01730 }
01731
01732 static void msc_do_verify(struct msc_interface *msc, struct udc *udc,
01733 struct usb_msc_cbw *cbw, uint32_t lba, uint32_t nr_blocks,
01734 bool bytchk)
01735 {
01736 struct block_device *bdev = msc->bdev;
01737 long residue;
01738 uint32_t cdb_data_len = 0;
01739 irqflags_t iflags;
01740
01741 dbg_verbose("msc VERIFY(x) %lu blocks, LBA %lu\n", nr_blocks, lba);
01742
01743
01744 if (bytchk)
01745 cdb_data_len = nr_blocks * blkdev_get_block_size(bdev);
01746
01747 residue = msc_validate_req(msc, cbw, cdb_data_len, 0);
01748 if (unlikely(residue < 0))
01749 return;
01750
01751 iflags = cpu_irq_save();
01752 if (msc->not_ready) {
01753 cpu_irq_restore(iflags);
01754 msc_request_failed(msc,
01755 le32_to_cpu(cbw->dCBWDataTransferLength),
01756 USB_CSW_STATUS_FAIL,
01757 SCSI_SK_NOT_READY, msc->busy_asc);
01758 return;
01759 }
01760
01761 msc->xfer_in_progress = true;
01762 cpu_irq_restore(iflags);
01763
01764 msc_prepare_csw(msc, residue, USB_CSW_STATUS_PASS);
01765
01766 if (unlikely(nr_blocks == 0)) {
01767
01768 msc_request_done_nodata(udc, msc, residue);
01769 return;
01770 }
01771
01772 if (bytchk)
01773 msc_verify_bytchk(msc, bdev, lba, nr_blocks);
01774 else
01775 msc_verify_read(msc, bdev, lba, nr_blocks);
01776 }
01777
01778 static void msc_cbw_received(struct udc *udc, struct usb_request *req)
01779 {
01780 struct msc_interface *msc = req->context;
01781 struct usb_msc_cbw *cbw;
01782 uint8_t opcode;
01783
01784 dbg_verbose("cbw received: status %d len %zu\n",
01785 req->status, req->bytes_xfered);
01786
01787 cbw = msc_get_cbw(msc);
01788 assert(req == msc->cbw_csw_req);
01789 assert(cbw == usb_req_get_first_buffer(req)->addr.ptr);
01790
01791
01792 if (req->status)
01793 return;
01794
01795
01796 if (cbw->dCBWSignature != LE32(USB_CBW_SIGNATURE)
01797 || req->bytes_xfered != 31) {
01798
01799
01800
01801
01802 udc_ep_set_wedge(udc, msc->bulk_in_ep);
01803 udc_ep_set_wedge(udc, msc->bulk_out_ep);
01804 return;
01805 }
01806
01807 opcode = scsi_cdb_get_opcode(cbw->CDB);
01808
01809
01810 switch (opcode) {
01811 case SCSI_CMD_TEST_UNIT_READY:
01812 msc_test_unit_ready(msc, udc,
01813 le32_to_cpu(cbw->dCBWDataTransferLength));
01814 break;
01815
01816 case SCSI_CMD_REQUEST_SENSE:
01817 msc_request_sense(msc, udc, cbw);
01818 break;
01819
01820 case SCSI_CMD_READ6:
01821 msc_do_read(msc, udc, cbw, scsi_cdb6_get_lba(cbw->CDB),
01822 scsi_cdb6_get_xfer_len(cbw->CDB));
01823 break;
01824
01825 case SCSI_CMD_WRITE6:
01826 msc_do_write(msc, udc, cbw, scsi_cdb6_get_lba(cbw->CDB),
01827 scsi_cdb6_get_xfer_len(cbw->CDB));
01828 break;
01829
01830 case SCSI_CMD_INQUIRY:
01831 msc_inquiry(msc, udc, cbw);
01832 break;
01833
01834 case SCSI_CMD_MODE_SENSE6:
01835 msc_mode_sense(msc, udc, cbw,
01836 scsi_cdb6_get_alloc_len(cbw->CDB));
01837 break;
01838
01839 case SCSI_CMD_READ_CAPACITY10:
01840 msc_read_capacity(msc, udc, cbw);
01841 break;
01842
01843 case SCSI_CMD_READ10:
01844 msc_do_read(msc, udc, cbw, scsi_cdb10_get_lba(cbw->CDB),
01845 scsi_cdb10_get_xfer_len(cbw->CDB));
01846 break;
01847
01848 case SCSI_CMD_WRITE10:
01849 msc_do_write(msc, udc, cbw, scsi_cdb10_get_lba(cbw->CDB),
01850 scsi_cdb10_get_xfer_len(cbw->CDB));
01851 break;
01852
01853 case SCSI_CMD_VERIFY10:
01854 msc_do_verify(msc, udc, cbw, scsi_cdb10_get_lba(cbw->CDB),
01855 scsi_cdb10_get_xfer_len(cbw->CDB),
01856 scsi_cdb10_bytchk_is_set(cbw->CDB));
01857 break;
01858
01859 case SCSI_CMD_MODE_SENSE10:
01860 msc_mode_sense(msc, udc, cbw,
01861 scsi_cdb10_get_alloc_len(cbw->CDB));
01862 break;
01863
01864 default:
01865 dbg_verbose("MSC: Unhandled opcode %02x\n", opcode);
01866
01867 msc_request_failed(msc,
01868 le32_to_cpu(cbw->dCBWDataTransferLength),
01869 USB_CSW_STATUS_FAIL,
01870 SCSI_SK_ILLEGAL_REQUEST,
01871 SCSI_ASC_INVALID_COMMAND_OPERATION_CODE);
01872 break;
01873 }
01874 }
01875
01893 status_t udi_msc_enable(struct udc *udc, struct udm_interface *iface,
01894 uint16_t setting)
01895 {
01896 struct msc_interface *msc = msc_interface_of(iface);
01897 struct usb_msc_csw *csw;
01898 dma_addr_t addr;
01899 struct usb_request *req;
01900 struct buffer *buf;
01901 uint16_t ep_size;
01902 usb_ep_id_t ep_id;
01903
01904 dbg_verbose("msc: enabling interface setting %u...\n", setting);
01905
01906 if (setting != 0)
01907 return ERR_INVALID_ARG;
01908
01909 msc->udc = udc;
01910 msc_queue_empty(msc);
01911
01912 ep_size = APP_UDI_MSC_FS_BULK_EP_SIZE;
01913 if (udc_is_high_speed(udc))
01914 ep_size = 512;
01915
01916 dbg_verbose(" creating bulk-in ep%02x: %u bytes\n",
01917 MSC_BULK_IN_EP_ADDR, ep_size);
01918 ep_id = udc_ep_create_bulk(udc, MSC_BULK_IN_EP_ADDR, ep_size);
01919 if (ep_id < 0)
01920 goto err_create_in_ep;
01921 msc->bulk_in_ep = ep_id;
01922 dbg_verbose(" creating bulk-out ep%02x: %u bytes\n",
01923 MSC_BULK_OUT_EP_ADDR, ep_size);
01924 ep_id = udc_ep_create_bulk(udc, MSC_BULK_OUT_EP_ADDR, ep_size);
01925 if (ep_id < 0)
01926 goto err_create_out_ep;
01927 msc->bulk_out_ep = ep_id;
01928
01929 dbg_verbose(" allocating block device request\n");
01930 msc->block_req = block_alloc_request(msc->bdev);
01931 if (!msc->block_req)
01932 goto err_alloc_breq;
01933
01934 dbg_verbose(" allocating DMA memory for CSW\n");
01935 addr = dma_alloc(sizeof(struct usb_msc_csw));
01936 if (!addr.ptr)
01937 goto err_alloc_csw;
01938 csw = addr.ptr;
01939 csw->dCSWSignature = LE32(USB_CSW_SIGNATURE);
01940 msc->csw = addr;
01941
01942 dbg_verbose(" allocating DMA memory for CBW\n");
01943 addr = dma_alloc(sizeof(struct usb_msc_cbw));
01944 if (!addr.ptr)
01945 goto err_alloc_cbw;
01946 msc->cbw = addr;
01947
01948 dbg_verbose(" allocating USB request for CBW and CSW\n");
01949 req = usb_req_alloc();
01950 if (!req)
01951 goto err_alloc_cbw_req;
01952 req->req_done = msc_cbw_received;
01953 req->context = msc;
01954 msc->cbw_csw_req = req;
01955
01956 dbg_verbose(" allocating buffer to hold CBW and CSW\n");
01957 buf = buffer_alloc();
01958 if (!buf)
01959 goto err_alloc_buf;
01960 buffer_init_rx_mapped(buf, addr, sizeof(struct usb_msc_cbw));
01961 usb_req_add_buffer(req, buf);
01962
01963 dbg_verbose(" submitting CBW - done!\n");
01964 udc_ep_submit_out_req(udc, msc->bulk_out_ep, req);
01965
01966 return 0;
01967
01968 err_alloc_buf:
01969 usb_req_free(req);
01970 err_alloc_cbw_req:
01971 dma_free(msc->cbw, sizeof(struct usb_msc_cbw));
01972 err_alloc_cbw:
01973 dma_free(msc->csw, sizeof(struct usb_msc_csw));
01974 err_alloc_csw:
01975 block_free_request(msc->bdev, msc->block_req);
01976 err_alloc_breq:
01977 ep_id = msc->bulk_out_ep;
01978 msc->bulk_out_ep = 0;
01979 udc_ep_destroy(udc, ep_id);
01980 err_create_out_ep:
01981 ep_id = msc->bulk_in_ep;
01982 msc->bulk_in_ep = 0;
01983 udc_ep_destroy(udc, ep_id);
01984 err_create_in_ep:
01985 return -1;
01986 }
01987
01997 void udi_msc_disable(struct udc *udc, struct udm_interface *iface)
01998 {
01999 struct msc_interface *msc = msc_interface_of(iface);
02000 usb_ep_id_t in, out;
02001
02002 msc_queue_empty(msc);
02003
02004 in = msc->bulk_in_ep;
02005 msc->bulk_in_ep = 0;
02006 out = msc->bulk_out_ep;
02007 msc->bulk_out_ep = 0;
02008
02009 if (in > 0)
02010 udc_ep_destroy(udc, in);
02011 if (out > 0)
02012 udc_ep_destroy(udc, out);
02013
02014 dma_free(msc->cbw, sizeof(struct usb_msc_cbw));
02015 dma_free(msc->csw, sizeof(struct usb_msc_csw));
02016 buffer_free(usb_req_get_first_buffer(msc->cbw_csw_req));
02017 usb_req_free(msc->cbw_csw_req);
02018 block_free_request(msc->bdev, msc->block_req);
02019 }
02020
02021 static int msc_bulk_reset(struct udc *udc, struct msc_interface *msc)
02022 {
02023 struct usb_request *req;
02024 struct buffer *buf;
02025
02026 dbg_info("MSC Bulk Reset\n");
02027
02028
02029
02030
02031
02032
02033
02034 if (msc->bulk_in_ep > 0) {
02035 udc_ep_flush(udc, msc->bulk_in_ep);
02036 udc_ep_clear_wedge(udc, msc->bulk_in_ep);
02037 }
02038 if (msc->bulk_out_ep > 0) {
02039 udc_ep_flush(udc, msc->bulk_out_ep);
02040 udc_ep_clear_wedge(udc, msc->bulk_out_ep);
02041 }
02042
02043 msc_queue_empty(msc);
02044
02045
02046 req = msc->cbw_csw_req;
02047 buf = usb_req_get_first_buffer(req);
02048 usb_req_init(req);
02049
02050 buffer_init_rx_mapped(buf, msc->cbw, sizeof(struct usb_msc_cbw));
02051 usb_req_add_buffer(req, buf);
02052 req->req_done = msc_cbw_received;
02053
02054 udc_ep_submit_out_req(udc, msc->bulk_out_ep, req);
02055
02056 return 0;
02057 }
02058
02072 status_t udi_msc_setup(struct udc *udc, struct udm_interface *iface,
02073 struct usb_setup_req *req)
02074 {
02075 uint16_t value = le16_to_cpu(req->wValue);
02076 uint16_t len = le16_to_cpu(req->wLength);
02077 uint8_t byte;
02078
02079 if (usb_setup_type(req) != USB_REQTYPE_CLASS)
02080 return -1;
02081
02082 switch (req->bRequest) {
02083 case USB_MSC_REQ_BULK_RESET:
02084 if (len || value || usb_setup_is_in(req))
02085 return -1;
02086
02087 if (msc_bulk_reset(udc, msc_interface_of(iface)))
02088 return -1;
02089
02090 udc_ep0_send_status(udc);
02091 break;
02092
02093 case USB_MSC_REQ_GET_MAX_LUN:
02094 if (len != 1 || value || usb_setup_is_out(req))
02095 return -1;
02096
02097
02098 byte = 0;
02099 udc_ep0_write_sync(udc, &byte, sizeof(byte));
02100 udc_ep0_expect_status(udc);
02101 break;
02102
02103 default:
02104 return -1;
02105 }
02106
02107 return 0;
02108 }
02109
02130 status_t udi_msc_get_iface_descriptor(struct udm_interface *iface,
02131 struct usb_request *req, enum usb_device_speed speed,
02132 uint16_t len)
02133 {
02134 struct msc_iface_desc *desc;
02135 struct buffer *buf;
02136
02137 if (!len)
02138
02139 goto out;
02140
02141 buf = buffer_dma_alloc(sizeof(struct msc_iface_desc));
02142 desc = buf->addr.ptr;
02143
02144
02145 memcpy(desc, &msc_desc_template, sizeof(struct msc_iface_desc));
02146
02147
02148 desc->iface.bInterfaceNumber = iface->iface_number;
02149 #ifdef CONFIG_UDC_HIGH_SPEED
02150 if (speed == USB_SPEED_HIGH) {
02151
02152 desc->ep[0].wMaxPacketSize = LE16(512);
02153 desc->ep[1].wMaxPacketSize = LE16(512);
02154 }
02155 #endif
02156
02157 if (len < sizeof(struct msc_iface_desc))
02158 buffer_resize(buf, len);
02159
02160 usb_req_add_buffer(req, buf);
02161
02162 out:
02163 return sizeof(struct msc_iface_desc);
02164 }
02165
02182 void udi_msc_free_descriptor(struct udm_interface *iface,
02183 struct usb_request *req)
02184 {
02185 struct buffer *buf;
02186
02187 buf = slist_pop_head(&req->buf_list, struct buffer, node);
02188 assert(buf->len <= sizeof(struct msc_iface_desc));
02189 buffer_dma_free(buf, sizeof(struct msc_iface_desc));
02190 }
02191
02205 void udi_msc_set_busy(struct udm_interface *iface, uint16_t asc,
02206 void (*queue_empty)(void *data), void *data)
02207 {
02208 struct msc_interface *msc = msc_interface_of(iface);
02209 irqflags_t iflags;
02210
02211 iflags = cpu_irq_save();
02212 msc->not_ready = true;
02213 msc->busy_asc = asc;
02214 dbg_verbose("msc_set_busy: ASC(Q) %04x in_progress: %d\n",
02215 asc, msc->xfer_in_progress);
02216 if (msc->xfer_in_progress) {
02217 msc->busy_cb = queue_empty;
02218 msc->busy_cb_data = data;
02219 cpu_irq_restore(iflags);
02220 } else {
02221 cpu_irq_restore(iflags);
02222 queue_empty(data);
02223 }
02224 }
02225
02232 void udi_msc_set_ready(struct udm_interface *iface)
02233 {
02234 struct msc_interface *msc = msc_interface_of(iface);
02235
02236 msc->not_ready = false;
02237 }
02238
02239 static struct msc_interface msc_interface = {
02240 .iface.iface_number = APP_UDI_MSC_INTERFACE_ID,
02241 .iface.enable = udi_msc_enable,
02242 .iface.disable = udi_msc_disable,
02243 .iface.setup = udi_msc_setup,
02244 .iface.get_iface_descriptor = udi_msc_get_iface_descriptor,
02245 .iface.free_descriptor = udi_msc_free_descriptor,
02246 };
02247
02248 struct udm_interface *udi_msc_create_iface(struct block_device *bdev)
02249 {
02250 struct msc_interface *msc = &msc_interface;
02251
02252 msc->bdev = bdev;
02253
02254 build_assert(CONFIG_DMAPOOL_SMALL_OBJ_SIZE % 4 == 0);
02255 build_assert(MSC_DATA_BUFFER_SIZE % 512 == 0);
02256
02257 msc->sense_data = dma_alloc(32);
02258 msc_init_sense(msc, SCSI_SK_NO_SENSE,
02259 SCSI_ASC_NO_ADDITIONAL_SENSE_INFO, 0);
02260
02261 return &msc->iface;
02262 }
02263