1 /* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2012-10-01 Yi Qiu first version 9 * 2012-11-25 Heyuanjie87 reduce the memory consumption 10 * 2012-12-09 Heyuanjie87 change function and endpoint handler 11 * 2013-07-25 Yi Qiu update for USB CV test 12 */ 13 14 #include <rtthread.h> 15 #include <rtservice.h> 16 #include "drivers/usb_device.h" 17 #include "mstorage.h" 18 19 #ifdef RT_USB_DEVICE_MSTORAGE 20 21 enum STAT 22 { 23 STAT_CBW, 24 STAT_CMD, 25 STAT_CSW, 26 STAT_RECEIVE, 27 STAT_SEND, 28 }; 29 30 typedef enum 31 { 32 FIXED, 33 COUNT, 34 BLOCK_COUNT, 35 }CB_SIZE_TYPE; 36 37 typedef enum 38 { 39 DIR_IN, 40 DIR_OUT, 41 DIR_NONE, 42 }CB_DIR; 43 44 typedef rt_size_t (*cbw_handler)(ufunction_t func, ustorage_cbw_t cbw); 45 46 struct scsi_cmd 47 { 48 rt_uint16_t cmd; 49 cbw_handler handler; 50 rt_size_t cmd_len; 51 CB_SIZE_TYPE type; 52 rt_size_t data_size; 53 CB_DIR dir; 54 }; 55 56 struct mstorage 57 { 58 struct ustorage_csw csw_response; 59 uep_t ep_in; 60 uep_t ep_out; 61 int status; 62 rt_uint32_t cb_data_size; 63 rt_device_t disk; 64 rt_uint32_t block; 65 rt_int32_t count; 66 rt_int32_t size; 67 struct scsi_cmd* processing; 68 struct rt_device_blk_geometry geometry; 69 }; 70 71 ALIGN(4) 72 static struct udevice_descriptor dev_desc = 73 { 74 USB_DESC_LENGTH_DEVICE, //bLength; 75 USB_DESC_TYPE_DEVICE, //type; 76 USB_BCD_VERSION, //bcdUSB; 77 USB_CLASS_MASS_STORAGE, //bDeviceClass; 78 0x06, //bDeviceSubClass; 79 0x50, //bDeviceProtocol; 80 0x40, //bMaxPacketSize0; 81 _VENDOR_ID, //idVendor; 82 _PRODUCT_ID, //idProduct; 83 USB_BCD_DEVICE, //bcdDevice; 84 USB_STRING_MANU_INDEX, //iManufacturer; 85 USB_STRING_PRODUCT_INDEX, //iProduct; 86 USB_STRING_SERIAL_INDEX, //iSerialNumber; 87 USB_DYNAMIC, //bNumConfigurations; 88 }; 89 90 //FS and HS needed 91 ALIGN(4) 92 static struct usb_qualifier_descriptor dev_qualifier = 93 { 94 sizeof(dev_qualifier), //bLength 95 USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType 96 0x0200, //bcdUSB 97 USB_CLASS_MASS_STORAGE, //bDeviceClass 98 0x06, //bDeviceSubClass 99 0x50, //bDeviceProtocol 100 64, //bMaxPacketSize0 101 0x01, //bNumConfigurations 102 0, 103 }; 104 105 106 ALIGN(4) 107 const static struct umass_descriptor _mass_desc = 108 { 109 #ifdef RT_USB_DEVICE_COMPOSITE 110 /* Interface Association Descriptor */ 111 { 112 USB_DESC_LENGTH_IAD, 113 USB_DESC_TYPE_IAD, 114 USB_DYNAMIC, 115 0x01, 116 USB_CLASS_MASS_STORAGE, 117 0x06, 118 0x50, 119 0x00, 120 }, 121 #endif 122 { 123 USB_DESC_LENGTH_INTERFACE, //bLength; 124 USB_DESC_TYPE_INTERFACE, //type; 125 USB_DYNAMIC, //bInterfaceNumber; 126 0x00, //bAlternateSetting; 127 0x02, //bNumEndpoints 128 USB_CLASS_MASS_STORAGE, //bInterfaceClass; 129 0x06, //bInterfaceSubClass; 130 0x50, //bInterfaceProtocol; 131 0x00, //iInterface; 132 }, 133 134 { 135 USB_DESC_LENGTH_ENDPOINT, //bLength; 136 USB_DESC_TYPE_ENDPOINT, //type; 137 USB_DYNAMIC | USB_DIR_OUT, //bEndpointAddress; 138 USB_EP_ATTR_BULK, //bmAttributes; 139 USB_DYNAMIC, //wMaxPacketSize; 140 0x00, //bInterval; 141 }, 142 143 { 144 USB_DESC_LENGTH_ENDPOINT, //bLength; 145 USB_DESC_TYPE_ENDPOINT, //type; 146 USB_DYNAMIC | USB_DIR_IN, //bEndpointAddress; 147 USB_EP_ATTR_BULK, //bmAttributes; 148 USB_DYNAMIC, //wMaxPacketSize; 149 0x00, //bInterval; 150 }, 151 }; 152 153 ALIGN(4) 154 const static char* _ustring[] = 155 { 156 "Language", 157 "RT-Thread Team.", 158 "RTT Mass Storage", 159 "320219198301", 160 "Configuration", 161 "Interface", 162 }; 163 164 static rt_size_t _test_unit_ready(ufunction_t func, ustorage_cbw_t cbw); 165 static rt_size_t _request_sense(ufunction_t func, ustorage_cbw_t cbw); 166 static rt_size_t _inquiry_cmd(ufunction_t func, ustorage_cbw_t cbw); 167 static rt_size_t _allow_removal(ufunction_t func, ustorage_cbw_t cbw); 168 static rt_size_t _start_stop(ufunction_t func, ustorage_cbw_t cbw); 169 static rt_size_t _mode_sense_6(ufunction_t func, ustorage_cbw_t cbw); 170 static rt_size_t _read_capacities(ufunction_t func, ustorage_cbw_t cbw); 171 static rt_size_t _read_capacity(ufunction_t func, ustorage_cbw_t cbw); 172 static rt_size_t _read_10(ufunction_t func, ustorage_cbw_t cbw); 173 static rt_size_t _write_10(ufunction_t func, ustorage_cbw_t cbw); 174 static rt_size_t _verify_10(ufunction_t func, ustorage_cbw_t cbw); 175 176 ALIGN(4) 177 static struct scsi_cmd cmd_data[] = 178 { 179 {SCSI_TEST_UNIT_READY, _test_unit_ready, 6, FIXED, 0, DIR_NONE}, 180 {SCSI_REQUEST_SENSE, _request_sense, 6, COUNT, 0, DIR_IN}, 181 {SCSI_INQUIRY_CMD, _inquiry_cmd, 6, COUNT, 0, DIR_IN}, 182 {SCSI_ALLOW_REMOVAL, _allow_removal, 6, FIXED, 0, DIR_NONE}, 183 {SCSI_MODE_SENSE_6, _mode_sense_6, 6, COUNT, 0, DIR_IN}, 184 {SCSI_START_STOP, _start_stop, 6, FIXED, 0, DIR_NONE}, 185 {SCSI_READ_CAPACITIES, _read_capacities, 10, COUNT, 0, DIR_NONE}, 186 {SCSI_READ_CAPACITY, _read_capacity, 10, FIXED, 8, DIR_IN}, 187 {SCSI_READ_10, _read_10, 10, BLOCK_COUNT, 0, DIR_IN}, 188 {SCSI_WRITE_10, _write_10, 10, BLOCK_COUNT, 0, DIR_OUT}, 189 {SCSI_VERIFY_10, _verify_10, 10, FIXED, 0, DIR_NONE}, 190 }; 191 192 static void _send_status(ufunction_t func) 193 { 194 struct mstorage *data; 195 196 RT_ASSERT(func != RT_NULL); 197 198 RT_DEBUG_LOG(RT_DEBUG_USB, ("_send_status\n")); 199 200 data = (struct mstorage*)func->user_data; 201 data->ep_in->request.buffer = (rt_uint8_t*)&data->csw_response; 202 data->ep_in->request.size = SIZEOF_CSW; 203 data->ep_in->request.req_type = UIO_REQUEST_WRITE; 204 rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); 205 data->status = STAT_CSW; 206 } 207 208 static rt_size_t _test_unit_ready(ufunction_t func, ustorage_cbw_t cbw) 209 { 210 struct mstorage *data; 211 212 RT_ASSERT(func != RT_NULL); 213 RT_ASSERT(func->device != RT_NULL); 214 215 RT_DEBUG_LOG(RT_DEBUG_USB, ("_test_unit_ready\n")); 216 217 data = (struct mstorage*)func->user_data; 218 data->csw_response.status = 0; 219 220 return 0; 221 } 222 223 static rt_size_t _allow_removal(ufunction_t func, ustorage_cbw_t cbw) 224 { 225 struct mstorage *data; 226 227 RT_ASSERT(func != RT_NULL); 228 RT_ASSERT(func->device != RT_NULL); 229 230 RT_DEBUG_LOG(RT_DEBUG_USB, ("_allow_removal\n")); 231 232 data = (struct mstorage*)func->user_data; 233 data->csw_response.status = 0; 234 235 return 0; 236 } 237 238 /** 239 * This function will handle inquiry command request. 240 * 241 * @param func the usb function object. 242 * @param cbw the command block wrapper. 243 * 244 * @return RT_EOK on successful. 245 */ 246 247 static rt_size_t _inquiry_cmd(ufunction_t func, ustorage_cbw_t cbw) 248 { 249 struct mstorage *data; 250 rt_uint8_t *buf; 251 252 RT_ASSERT(func != RT_NULL); 253 RT_ASSERT(func->device != RT_NULL); 254 RT_ASSERT(cbw != RT_NULL); 255 256 RT_DEBUG_LOG(RT_DEBUG_USB, ("_inquiry_cmd\n")); 257 258 data = (struct mstorage*)func->user_data; 259 buf = data->ep_in->buffer; 260 261 *(rt_uint32_t*)&buf[0] = 0x0 | (0x80 << 8); 262 *(rt_uint32_t*)&buf[4] = 31; 263 264 rt_memset(&buf[8], 0x20, 28); 265 rt_memcpy(&buf[8], "RTT", 3); 266 rt_memcpy(&buf[16], "USB Disk", 8); 267 268 data->cb_data_size = MIN(data->cb_data_size, SIZEOF_INQUIRY_CMD); 269 data->ep_in->request.buffer = buf; 270 data->ep_in->request.size = data->cb_data_size; 271 data->ep_in->request.req_type = UIO_REQUEST_WRITE; 272 rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); 273 data->status = STAT_CMD; 274 275 return data->cb_data_size; 276 } 277 278 /** 279 * This function will handle sense request. 280 * 281 * @param func the usb function object. 282 * @param cbw the command block wrapper. 283 * 284 * @return RT_EOK on successful. 285 */ 286 static rt_size_t _request_sense(ufunction_t func, ustorage_cbw_t cbw) 287 { 288 struct mstorage *data; 289 struct request_sense_data *buf; 290 291 RT_ASSERT(func != RT_NULL); 292 RT_ASSERT(func->device != RT_NULL); 293 RT_ASSERT(cbw != RT_NULL); 294 295 RT_DEBUG_LOG(RT_DEBUG_USB, ("_request_sense\n")); 296 297 data = (struct mstorage*)func->user_data; 298 buf = (struct request_sense_data *)data->ep_in->buffer; 299 300 buf->ErrorCode = 0x70; 301 buf->Valid = 0; 302 buf->SenseKey = 2; 303 buf->Information[0] = 0; 304 buf->Information[1] = 0; 305 buf->Information[2] = 0; 306 buf->Information[3] = 0; 307 buf->AdditionalSenseLength = 0x0a; 308 buf->AdditionalSenseCode = 0x3a; 309 buf->AdditionalSenseCodeQualifier = 0; 310 311 data->cb_data_size = MIN(data->cb_data_size, SIZEOF_REQUEST_SENSE); 312 data->ep_in->request.buffer = (rt_uint8_t*)data->ep_in->buffer; 313 data->ep_in->request.size = data->cb_data_size; 314 data->ep_in->request.req_type = UIO_REQUEST_WRITE; 315 rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); 316 data->status = STAT_CMD; 317 318 return data->cb_data_size; 319 } 320 321 /** 322 * This function will handle mode_sense_6 request. 323 * 324 * @param func the usb function object. 325 * @param cbw the command block wrapper. 326 * 327 * @return RT_EOK on successful. 328 */ 329 static rt_size_t _mode_sense_6(ufunction_t func, ustorage_cbw_t cbw) 330 { 331 struct mstorage *data; 332 rt_uint8_t *buf; 333 334 RT_ASSERT(func != RT_NULL); 335 RT_ASSERT(func->device != RT_NULL); 336 RT_ASSERT(cbw != RT_NULL); 337 338 RT_DEBUG_LOG(RT_DEBUG_USB, ("_mode_sense_6\n")); 339 340 data = (struct mstorage*)func->user_data; 341 buf = data->ep_in->buffer; 342 buf[0] = 3; 343 buf[1] = 0; 344 buf[2] = 0; 345 buf[3] = 0; 346 347 data->cb_data_size = MIN(data->cb_data_size, SIZEOF_MODE_SENSE_6); 348 data->ep_in->request.buffer = buf; 349 data->ep_in->request.size = data->cb_data_size; 350 data->ep_in->request.req_type = UIO_REQUEST_WRITE; 351 rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); 352 data->status = STAT_CMD; 353 354 return data->cb_data_size; 355 } 356 357 /** 358 * This function will handle read_capacities request. 359 * 360 * @param func the usb function object. 361 * @param cbw the command block wrapper. 362 * 363 * @return RT_EOK on successful. 364 */ 365 static rt_size_t _read_capacities(ufunction_t func, ustorage_cbw_t cbw) 366 { 367 struct mstorage *data; 368 rt_uint8_t *buf; 369 rt_uint32_t sector_count, sector_size; 370 371 RT_ASSERT(func != RT_NULL); 372 RT_ASSERT(func->device != RT_NULL); 373 RT_ASSERT(cbw != RT_NULL); 374 375 RT_DEBUG_LOG(RT_DEBUG_USB, ("_read_capacities\n")); 376 377 data = (struct mstorage*)func->user_data; 378 buf = data->ep_in->buffer; 379 sector_count = data->geometry.sector_count; 380 sector_size = data->geometry.bytes_per_sector; 381 382 *(rt_uint32_t*)&buf[0] = 0x08000000; 383 buf[4] = sector_count >> 24; 384 buf[5] = 0xff & (sector_count >> 16); 385 buf[6] = 0xff & (sector_count >> 8); 386 buf[7] = 0xff & (sector_count); 387 buf[8] = 0x02; 388 buf[9] = 0xff & (sector_size >> 16); 389 buf[10] = 0xff & (sector_size >> 8); 390 buf[11] = 0xff & sector_size; 391 392 data->cb_data_size = MIN(data->cb_data_size, SIZEOF_READ_CAPACITIES); 393 data->ep_in->request.buffer = buf; 394 data->ep_in->request.size = data->cb_data_size; 395 data->ep_in->request.req_type = UIO_REQUEST_WRITE; 396 rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); 397 data->status = STAT_CMD; 398 399 return data->cb_data_size; 400 } 401 402 /** 403 * This function will handle read_capacity request. 404 * 405 * @param func the usb function object. 406 * @param cbw the command block wapper. 407 * 408 * @return RT_EOK on successful. 409 */ 410 static rt_size_t _read_capacity(ufunction_t func, ustorage_cbw_t cbw) 411 { 412 struct mstorage *data; 413 414 rt_uint8_t *buf; 415 rt_uint32_t sector_count, sector_size; 416 417 RT_ASSERT(func != RT_NULL); 418 RT_ASSERT(func->device != RT_NULL); 419 RT_ASSERT(cbw != RT_NULL); 420 421 RT_DEBUG_LOG(RT_DEBUG_USB, ("_read_capacity\n")); 422 423 data = (struct mstorage*)func->user_data; 424 buf = data->ep_in->buffer; 425 sector_count = data->geometry.sector_count; 426 sector_size = data->geometry.bytes_per_sector; 427 428 buf[0] = sector_count >> 24; 429 buf[1] = 0xff & (sector_count >> 16); 430 buf[2] = 0xff & (sector_count >> 8); 431 buf[3] = 0xff & (sector_count); 432 buf[4] = 0x0; 433 buf[5] = 0xff & (sector_size >> 16); 434 buf[6] = 0xff & (sector_size >> 8); 435 buf[7] = 0xff & sector_size; 436 437 data->cb_data_size = MIN(data->cb_data_size, SIZEOF_READ_CAPACITY); 438 data->ep_in->request.buffer = buf; 439 data->ep_in->request.size = data->cb_data_size; 440 data->ep_in->request.req_type = UIO_REQUEST_WRITE; 441 rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); 442 data->status = STAT_CMD; 443 444 return data->cb_data_size; 445 } 446 447 /** 448 * This function will handle read_10 request. 449 * 450 * @param func the usb function object. 451 * @param cbw the command block wrapper. 452 * 453 * @return RT_EOK on successful. 454 */ 455 static rt_size_t _read_10(ufunction_t func, ustorage_cbw_t cbw) 456 { 457 struct mstorage *data; 458 rt_size_t size; 459 460 RT_ASSERT(func != RT_NULL); 461 RT_ASSERT(func->device != RT_NULL); 462 RT_ASSERT(cbw != RT_NULL); 463 464 data = (struct mstorage*)func->user_data; 465 data->block = cbw->cb[2]<<24 | cbw->cb[3]<<16 | cbw->cb[4]<<8 | 466 cbw->cb[5]<<0; 467 data->count = cbw->cb[7]<<8 | cbw->cb[8]<<0; 468 469 RT_ASSERT(data->count < data->geometry.sector_count); 470 471 data->csw_response.data_reside = data->cb_data_size; 472 size = rt_device_read(data->disk, data->block, data->ep_in->buffer, 1); 473 if(size == 0) 474 { 475 rt_kprintf("read data error\n"); 476 } 477 478 data->ep_in->request.buffer = data->ep_in->buffer; 479 data->ep_in->request.size = data->geometry.bytes_per_sector; 480 data->ep_in->request.req_type = UIO_REQUEST_WRITE; 481 rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); 482 data->status = STAT_SEND; 483 484 return data->geometry.bytes_per_sector; 485 } 486 487 /** 488 * This function will handle write_10 request. 489 * 490 * @param func the usb function object. 491 * @param cbw the command block wrapper. 492 * 493 * @return RT_EOK on successful. 494 */ 495 static rt_size_t _write_10(ufunction_t func, ustorage_cbw_t cbw) 496 { 497 struct mstorage *data; 498 499 RT_ASSERT(func != RT_NULL); 500 RT_ASSERT(func->device != RT_NULL); 501 RT_ASSERT(cbw != RT_NULL); 502 503 data = (struct mstorage*)func->user_data; 504 505 data->block = cbw->cb[2]<<24 | cbw->cb[3]<<16 | cbw->cb[4]<<8 | 506 cbw->cb[5]<<0; 507 data->count = cbw->cb[7]<<8 | cbw->cb[8]; 508 data->csw_response.data_reside = cbw->xfer_len; 509 data->size = data->count * data->geometry.bytes_per_sector; 510 511 RT_DEBUG_LOG(RT_DEBUG_USB, ("_write_10 count 0x%x block 0x%x 0x%x\n", 512 data->count, data->block, data->geometry.sector_count)); 513 514 data->csw_response.data_reside = data->cb_data_size; 515 516 data->ep_out->request.buffer = data->ep_out->buffer; 517 data->ep_out->request.size = data->geometry.bytes_per_sector; 518 data->ep_out->request.req_type = UIO_REQUEST_READ_FULL; 519 rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); 520 data->status = STAT_RECEIVE; 521 522 return data->geometry.bytes_per_sector; 523 } 524 525 /** 526 * This function will handle verify_10 request. 527 * 528 * @param func the usb function object. 529 * 530 * @return RT_EOK on successful. 531 */ 532 static rt_size_t _verify_10(ufunction_t func, ustorage_cbw_t cbw) 533 { 534 struct mstorage *data; 535 536 RT_ASSERT(func != RT_NULL); 537 RT_ASSERT(func->device != RT_NULL); 538 539 RT_DEBUG_LOG(RT_DEBUG_USB, ("_verify_10\n")); 540 541 data = (struct mstorage*)func->user_data; 542 data->csw_response.status = 0; 543 544 return 0; 545 } 546 547 static rt_size_t _start_stop(ufunction_t func, 548 ustorage_cbw_t cbw) 549 { 550 struct mstorage *data; 551 552 RT_ASSERT(func != RT_NULL); 553 RT_ASSERT(func->device != RT_NULL); 554 555 RT_DEBUG_LOG(RT_DEBUG_USB, ("_start_stop\n")); 556 557 data = (struct mstorage*)func->user_data; 558 data->csw_response.status = 0; 559 560 return 0; 561 } 562 563 static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size) 564 { 565 struct mstorage *data; 566 567 RT_ASSERT(func != RT_NULL); 568 RT_ASSERT(func->device != RT_NULL); 569 570 RT_DEBUG_LOG(RT_DEBUG_USB, ("_ep_in_handler\n")); 571 572 data = (struct mstorage*)func->user_data; 573 574 switch(data->status) 575 { 576 case STAT_CSW: 577 if(data->ep_in->request.size != SIZEOF_CSW) 578 { 579 rt_kprintf("Size of csw command error\n"); 580 rt_usbd_ep_set_stall(func->device, data->ep_in); 581 } 582 else 583 { 584 RT_DEBUG_LOG(RT_DEBUG_USB, ("return to cbw status\n")); 585 data->ep_out->request.buffer = data->ep_out->buffer; 586 data->ep_out->request.size = SIZEOF_CBW; 587 data->ep_out->request.req_type = UIO_REQUEST_READ_FULL; 588 rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); 589 data->status = STAT_CBW; 590 } 591 break; 592 case STAT_CMD: 593 if(data->csw_response.data_reside == 0xFF) 594 { 595 data->csw_response.data_reside = 0; 596 } 597 else 598 { 599 data->csw_response.data_reside -= data->ep_in->request.size; 600 if(data->csw_response.data_reside != 0) 601 { 602 RT_DEBUG_LOG(RT_DEBUG_USB, ("data_reside %d, request %d\n", 603 data->csw_response.data_reside, data->ep_in->request.size)); 604 if(data->processing->dir == DIR_OUT) 605 { 606 rt_usbd_ep_set_stall(func->device, data->ep_out); 607 } 608 else 609 { 610 rt_usbd_ep_set_stall(func->device, data->ep_in); 611 } 612 data->csw_response.data_reside = 0; 613 } 614 } 615 _send_status(func); 616 break; 617 case STAT_SEND: 618 data->csw_response.data_reside -= data->ep_in->request.size; 619 data->count--; 620 data->block++; 621 if(data->count > 0 && data->csw_response.data_reside > 0) 622 { 623 if(rt_device_read(data->disk, data->block, data->ep_in->buffer, 1) == 0) 624 { 625 rt_kprintf("disk read error\n"); 626 rt_usbd_ep_set_stall(func->device, data->ep_in); 627 return -RT_ERROR; 628 } 629 630 data->ep_in->request.buffer = data->ep_in->buffer; 631 data->ep_in->request.size = data->geometry.bytes_per_sector; 632 data->ep_in->request.req_type = UIO_REQUEST_WRITE; 633 rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); 634 } 635 else 636 { 637 _send_status(func); 638 } 639 break; 640 } 641 642 return RT_EOK; 643 } 644 645 #ifdef MASS_CBW_DUMP 646 static void cbw_dump(struct ustorage_cbw* cbw) 647 { 648 RT_ASSERT(cbw != RT_NULL); 649 650 RT_DEBUG_LOG(RT_DEBUG_USB, ("signature 0x%x\n", cbw->signature)); 651 RT_DEBUG_LOG(RT_DEBUG_USB, ("tag 0x%x\n", cbw->tag)); 652 RT_DEBUG_LOG(RT_DEBUG_USB, ("xfer_len 0x%x\n", cbw->xfer_len)); 653 RT_DEBUG_LOG(RT_DEBUG_USB, ("dflags 0x%x\n", cbw->dflags)); 654 RT_DEBUG_LOG(RT_DEBUG_USB, ("lun 0x%x\n", cbw->lun)); 655 RT_DEBUG_LOG(RT_DEBUG_USB, ("cb_len 0x%x\n", cbw->cb_len)); 656 RT_DEBUG_LOG(RT_DEBUG_USB, ("cb[0] 0x%x\n", cbw->cb[0])); 657 } 658 #endif 659 660 static struct scsi_cmd* _find_cbw_command(rt_uint16_t cmd) 661 { 662 int i; 663 664 for(i=0; i<sizeof(cmd_data)/sizeof(struct scsi_cmd); i++) 665 { 666 if(cmd_data[i].cmd == cmd) 667 return &cmd_data[i]; 668 } 669 670 return RT_NULL; 671 } 672 673 static void _cb_len_calc(ufunction_t func, struct scsi_cmd* cmd, 674 ustorage_cbw_t cbw) 675 { 676 struct mstorage *data; 677 678 RT_ASSERT(func != RT_NULL); 679 RT_ASSERT(cmd != RT_NULL); 680 RT_ASSERT(cbw != RT_NULL); 681 682 data = (struct mstorage*)func->user_data; 683 if(cmd->cmd_len == 6) 684 { 685 switch(cmd->type) 686 { 687 case COUNT: 688 data->cb_data_size = cbw->cb[4]; 689 break; 690 case BLOCK_COUNT: 691 data->cb_data_size = cbw->cb[4] * data->geometry.bytes_per_sector; 692 break; 693 case FIXED: 694 data->cb_data_size = cmd->data_size; 695 break; 696 default: 697 break; 698 } 699 } 700 else if(cmd->cmd_len == 10) 701 { 702 switch(cmd->type) 703 { 704 case COUNT: 705 data->cb_data_size = cbw->cb[7]<<8 | cbw->cb[8]; 706 break; 707 case BLOCK_COUNT: 708 data->cb_data_size = (cbw->cb[7]<<8 | cbw->cb[8]) * 709 data->geometry.bytes_per_sector; 710 break; 711 case FIXED: 712 data->cb_data_size = cmd->data_size; 713 break; 714 default: 715 break; 716 } 717 } 718 else 719 { 720 // rt_kprintf("cmd_len error %d\n", cmd->cmd_len); 721 } 722 } 723 724 static rt_bool_t _cbw_verify(ufunction_t func, struct scsi_cmd* cmd, 725 ustorage_cbw_t cbw) 726 { 727 struct mstorage *data; 728 729 RT_ASSERT(cmd != RT_NULL); 730 RT_ASSERT(cbw != RT_NULL); 731 RT_ASSERT(func != RT_NULL); 732 733 data = (struct mstorage*)func->user_data; 734 if(cmd->cmd_len != cbw->cb_len) 735 { 736 // rt_kprintf("cb_len error\n"); 737 cmd->cmd_len = cbw->cb_len; 738 } 739 740 if(cbw->xfer_len > 0 && data->cb_data_size == 0) 741 { 742 rt_kprintf("xfer_len > 0 && data_size == 0\n"); 743 return RT_FALSE; 744 } 745 746 if(cbw->xfer_len == 0 && data->cb_data_size > 0) 747 { 748 rt_kprintf("xfer_len == 0 && data_size > 0"); 749 return RT_FALSE; 750 } 751 752 if(((cbw->dflags & USB_DIR_IN) && (cmd->dir == DIR_OUT)) || 753 (!(cbw->dflags & USB_DIR_IN) && (cmd->dir == DIR_IN))) 754 { 755 rt_kprintf("dir error\n"); 756 return RT_FALSE; 757 } 758 759 if(cbw->xfer_len > data->cb_data_size) 760 { 761 rt_kprintf("xfer_len > data_size\n"); 762 return RT_FALSE; 763 } 764 765 if(cbw->xfer_len < data->cb_data_size) 766 { 767 // rt_kprintf("xfer_len < data_size\n"); 768 data->cb_data_size = cbw->xfer_len; 769 data->csw_response.status = 1; 770 } 771 772 return RT_TRUE; 773 } 774 775 static rt_size_t _cbw_handler(ufunction_t func, struct scsi_cmd* cmd, 776 ustorage_cbw_t cbw) 777 { 778 struct mstorage *data; 779 780 RT_ASSERT(func != RT_NULL); 781 RT_ASSERT(cbw != RT_NULL); 782 RT_ASSERT(cmd->handler != RT_NULL); 783 784 data = (struct mstorage*)func->user_data; 785 data->processing = cmd; 786 return cmd->handler(func, cbw); 787 } 788 789 /** 790 * This function will handle mass storage bulk out endpoint request. 791 * 792 * @param func the usb function object. 793 * @param size request size. 794 * 795 * @return RT_EOK. 796 */ 797 static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size) 798 { 799 struct mstorage *data; 800 struct scsi_cmd* cmd; 801 rt_size_t len; 802 struct ustorage_cbw* cbw; 803 804 RT_ASSERT(func != RT_NULL); 805 RT_ASSERT(func->device != RT_NULL); 806 807 RT_DEBUG_LOG(RT_DEBUG_USB, ("_ep_out_handler %d\n", size)); 808 809 data = (struct mstorage*)func->user_data; 810 cbw = (struct ustorage_cbw*)data->ep_out->buffer; 811 if(data->status == STAT_CBW) 812 { 813 /* dump cbw information */ 814 if(cbw->signature != CBW_SIGNATURE || size != SIZEOF_CBW) 815 { 816 goto exit; 817 } 818 819 data->csw_response.signature = CSW_SIGNATURE; 820 data->csw_response.tag = cbw->tag; 821 data->csw_response.data_reside = cbw->xfer_len; 822 data->csw_response.status = 0; 823 824 RT_DEBUG_LOG(RT_DEBUG_USB, ("ep_out reside %d\n", data->csw_response.data_reside)); 825 826 cmd = _find_cbw_command(cbw->cb[0]); 827 if(cmd == RT_NULL) 828 { 829 rt_kprintf("can't find cbw command\n"); 830 goto exit; 831 } 832 833 _cb_len_calc(func, cmd, cbw); 834 if(!_cbw_verify(func, cmd, cbw)) 835 { 836 goto exit; 837 } 838 839 len = _cbw_handler(func, cmd, cbw); 840 if(len == 0) 841 { 842 _send_status(func); 843 } 844 845 return RT_EOK; 846 } 847 else if(data->status == STAT_RECEIVE) 848 { 849 RT_DEBUG_LOG(RT_DEBUG_USB, ("\nwrite size %d block 0x%x oount 0x%x\n", 850 size, data->block, data->size)); 851 852 data->size -= size; 853 data->csw_response.data_reside -= size; 854 855 rt_device_write(data->disk, data->block, data->ep_out->buffer, 1); 856 857 if(data->csw_response.data_reside != 0) 858 { 859 data->ep_out->request.buffer = data->ep_out->buffer; 860 data->ep_out->request.size = data->geometry.bytes_per_sector; 861 data->ep_out->request.req_type = UIO_REQUEST_READ_FULL; 862 rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); 863 data->block ++; 864 } 865 else 866 { 867 _send_status(func); 868 } 869 870 return RT_EOK; 871 } 872 873 exit: 874 if(data->csw_response.data_reside) 875 { 876 if(cbw->dflags & USB_DIR_IN) 877 { 878 rt_usbd_ep_set_stall(func->device, data->ep_in); 879 } 880 else 881 { 882 rt_usbd_ep_set_stall(func->device, data->ep_in); 883 rt_usbd_ep_set_stall(func->device, data->ep_out); 884 } 885 } 886 data->csw_response.status = 1; 887 _send_status(func); 888 889 return -RT_ERROR; 890 } 891 892 /** 893 * This function will handle mass storage interface request. 894 * 895 * @param func the usb function object. 896 * @param setup the setup request. 897 * 898 * @return RT_EOK on successful. 899 */ 900 static rt_err_t _interface_handler(ufunction_t func, ureq_t setup) 901 { 902 rt_uint8_t lun = 0; 903 904 RT_ASSERT(func != RT_NULL); 905 RT_ASSERT(func->device != RT_NULL); 906 RT_ASSERT(setup != RT_NULL); 907 908 RT_DEBUG_LOG(RT_DEBUG_USB, ("mstorage_interface_handler\n")); 909 910 switch(setup->bRequest) 911 { 912 case USBREQ_GET_MAX_LUN: 913 914 RT_DEBUG_LOG(RT_DEBUG_USB, ("USBREQ_GET_MAX_LUN\n")); 915 916 if(setup->wValue || setup->wLength != 1) 917 { 918 rt_usbd_ep0_set_stall(func->device); 919 } 920 else 921 { 922 rt_usbd_ep0_write(func->device, &lun, setup->wLength); 923 } 924 break; 925 case USBREQ_MASS_STORAGE_RESET: 926 927 RT_DEBUG_LOG(RT_DEBUG_USB, ("USBREQ_MASS_STORAGE_RESET\n")); 928 929 if(setup->wValue || setup->wLength != 0) 930 { 931 rt_usbd_ep0_set_stall(func->device); 932 } 933 else 934 { 935 dcd_ep0_send_status(func->device->dcd); 936 } 937 break; 938 default: 939 rt_kprintf("unknown interface request\n"); 940 break; 941 } 942 943 return RT_EOK; 944 } 945 946 /** 947 * This function will run mass storage function, it will be called on handle set configuration request. 948 * 949 * @param func the usb function object. 950 * 951 * @return RT_EOK on successful. 952 */ 953 static rt_err_t _function_enable(ufunction_t func) 954 { 955 struct mstorage *data; 956 RT_ASSERT(func != RT_NULL); 957 RT_DEBUG_LOG(RT_DEBUG_USB, ("Mass storage function enabled\n")); 958 data = (struct mstorage*)func->user_data; 959 960 data->disk = rt_device_find(RT_USB_MSTORAGE_DISK_NAME); 961 if(data->disk == RT_NULL) 962 { 963 rt_kprintf("no data->disk named %s\n", RT_USB_MSTORAGE_DISK_NAME); 964 return -RT_ERROR; 965 } 966 967 if(rt_device_open(data->disk, RT_DEVICE_OFLAG_RDWR) != RT_EOK) 968 { 969 rt_kprintf("disk open error\n"); 970 return -RT_ERROR; 971 } 972 973 if(rt_device_control(data->disk, RT_DEVICE_CTRL_BLK_GETGEOME, 974 (void*)&data->geometry) != RT_EOK) 975 { 976 rt_kprintf("get disk info error\n"); 977 return -RT_ERROR; 978 } 979 980 data->ep_in->buffer = (rt_uint8_t*)rt_malloc(data->geometry.bytes_per_sector); 981 if(data->ep_in->buffer == RT_NULL) 982 { 983 rt_kprintf("no memory\n"); 984 return -RT_ENOMEM; 985 } 986 data->ep_out->buffer = (rt_uint8_t*)rt_malloc(data->geometry.bytes_per_sector); 987 if(data->ep_out->buffer == RT_NULL) 988 { 989 rt_free(data->ep_in->buffer); 990 rt_kprintf("no memory\n"); 991 return -RT_ENOMEM; 992 } 993 994 /* prepare to read CBW request */ 995 data->ep_out->request.buffer = data->ep_out->buffer; 996 data->ep_out->request.size = SIZEOF_CBW; 997 data->ep_out->request.req_type = UIO_REQUEST_READ_FULL; 998 rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); 999 1000 return RT_EOK; 1001 } 1002 1003 /** 1004 * This function will stop mass storage function, it will be called on handle set configuration request. 1005 * 1006 * @param device the usb device object. 1007 * 1008 * @return RT_EOK on successful. 1009 */ 1010 static rt_err_t _function_disable(ufunction_t func) 1011 { 1012 struct mstorage *data; 1013 RT_ASSERT(func != RT_NULL); 1014 1015 RT_DEBUG_LOG(RT_DEBUG_USB, ("Mass storage function disabled\n")); 1016 1017 data = (struct mstorage*)func->user_data; 1018 if(data->ep_in->buffer != RT_NULL) 1019 { 1020 rt_free(data->ep_in->buffer); 1021 data->ep_in->buffer = RT_NULL; 1022 } 1023 1024 if(data->ep_out->buffer != RT_NULL) 1025 { 1026 rt_free(data->ep_out->buffer); 1027 data->ep_out->buffer = RT_NULL; 1028 } 1029 if(data->disk != RT_NULL) 1030 { 1031 rt_device_close(data->disk); 1032 data->disk = RT_NULL; 1033 } 1034 1035 data->status = STAT_CBW; 1036 1037 return RT_EOK; 1038 } 1039 1040 static struct ufunction_ops ops = 1041 { 1042 _function_enable, 1043 _function_disable, 1044 RT_NULL, 1045 }; 1046 static rt_err_t _mstorage_descriptor_config(umass_desc_t desc, rt_uint8_t cintf_nr, rt_uint8_t device_is_hs) 1047 { 1048 #ifdef RT_USB_DEVICE_COMPOSITE 1049 desc->iad_desc.bFirstInterface = cintf_nr; 1050 #endif 1051 desc->ep_out_desc.wMaxPacketSize = device_is_hs ? 512 : 64; 1052 desc->ep_in_desc.wMaxPacketSize = device_is_hs ? 512 : 64; 1053 return RT_EOK; 1054 } 1055 /** 1056 * This function will create a mass storage function instance. 1057 * 1058 * @param device the usb device object. 1059 * 1060 * @return RT_EOK on successful. 1061 */ 1062 ufunction_t rt_usbd_function_mstorage_create(udevice_t device) 1063 { 1064 uintf_t intf; 1065 struct mstorage *data; 1066 ufunction_t func; 1067 ualtsetting_t setting; 1068 umass_desc_t mass_desc; 1069 1070 /* parameter check */ 1071 RT_ASSERT(device != RT_NULL); 1072 1073 /* set usb device string description */ 1074 rt_usbd_device_set_string(device, _ustring); 1075 1076 /* create a mass storage function */ 1077 func = rt_usbd_function_new(device, &dev_desc, &ops); 1078 device->dev_qualifier = &dev_qualifier; 1079 1080 /* allocate memory for mass storage function data */ 1081 data = (struct mstorage*)rt_malloc(sizeof(struct mstorage)); 1082 rt_memset(data, 0, sizeof(struct mstorage)); 1083 func->user_data = (void*)data; 1084 1085 /* create an interface object */ 1086 intf = rt_usbd_interface_new(device, _interface_handler); 1087 1088 /* create an alternate setting object */ 1089 setting = rt_usbd_altsetting_new(sizeof(struct umass_descriptor)); 1090 1091 /* config desc in alternate setting */ 1092 rt_usbd_altsetting_config_descriptor(setting, &_mass_desc, (rt_off_t)&((umass_desc_t)0)->intf_desc); 1093 1094 /* configure the msc interface descriptor */ 1095 _mstorage_descriptor_config(setting->desc, intf->intf_num, device->dcd->device_is_hs); 1096 1097 /* create a bulk out and a bulk in endpoint */ 1098 mass_desc = (umass_desc_t)setting->desc; 1099 data->ep_in = rt_usbd_endpoint_new(&mass_desc->ep_in_desc, _ep_in_handler); 1100 data->ep_out = rt_usbd_endpoint_new(&mass_desc->ep_out_desc, _ep_out_handler); 1101 1102 /* add the bulk out and bulk in endpoint to the alternate setting */ 1103 rt_usbd_altsetting_add_endpoint(setting, data->ep_out); 1104 rt_usbd_altsetting_add_endpoint(setting, data->ep_in); 1105 1106 /* add the alternate setting to the interface, then set default setting */ 1107 rt_usbd_interface_add_altsetting(intf, setting); 1108 rt_usbd_set_altsetting(intf, 0); 1109 1110 /* add the interface to the mass storage function */ 1111 rt_usbd_function_add_interface(func, intf); 1112 1113 return func; 1114 } 1115 struct udclass msc_class = 1116 { 1117 .rt_usbd_function_create = rt_usbd_function_mstorage_create 1118 }; 1119 1120 int rt_usbd_msc_class_register(void) 1121 { 1122 rt_usbd_class_register(&msc_class); 1123 return 0; 1124 } 1125 INIT_PREV_EXPORT(rt_usbd_msc_class_register); 1126 1127 #endif 1128