1 /* 2 * (C) Copyright 2017 3 * 4 * Eddie Cai <eddie.cai.linux@gmail.com> 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 #include <config.h> 9 #include <common.h> 10 #include <errno.h> 11 #include <malloc.h> 12 #include <memalign.h> 13 #include <linux/usb/ch9.h> 14 #include <linux/usb/gadget.h> 15 #include <linux/usb/composite.h> 16 #include <linux/compiler.h> 17 #include <version.h> 18 #include <g_dnl.h> 19 #include <asm/arch/f_rockusb.h> 20 21 static inline struct f_rockusb *func_to_rockusb(struct usb_function *f) 22 { 23 return container_of(f, struct f_rockusb, usb_function); 24 } 25 26 static struct usb_endpoint_descriptor fs_ep_in = { 27 .bLength = USB_DT_ENDPOINT_SIZE, 28 .bDescriptorType = USB_DT_ENDPOINT, 29 .bEndpointAddress = USB_DIR_IN, 30 .bmAttributes = USB_ENDPOINT_XFER_BULK, 31 .wMaxPacketSize = cpu_to_le16(64), 32 }; 33 34 static struct usb_endpoint_descriptor fs_ep_out = { 35 .bLength = USB_DT_ENDPOINT_SIZE, 36 .bDescriptorType = USB_DT_ENDPOINT, 37 .bEndpointAddress = USB_DIR_OUT, 38 .bmAttributes = USB_ENDPOINT_XFER_BULK, 39 .wMaxPacketSize = cpu_to_le16(64), 40 }; 41 42 static struct usb_endpoint_descriptor hs_ep_in = { 43 .bLength = USB_DT_ENDPOINT_SIZE, 44 .bDescriptorType = USB_DT_ENDPOINT, 45 .bEndpointAddress = USB_DIR_IN, 46 .bmAttributes = USB_ENDPOINT_XFER_BULK, 47 .wMaxPacketSize = cpu_to_le16(512), 48 }; 49 50 static struct usb_endpoint_descriptor hs_ep_out = { 51 .bLength = USB_DT_ENDPOINT_SIZE, 52 .bDescriptorType = USB_DT_ENDPOINT, 53 .bEndpointAddress = USB_DIR_OUT, 54 .bmAttributes = USB_ENDPOINT_XFER_BULK, 55 .wMaxPacketSize = cpu_to_le16(512), 56 }; 57 58 static struct usb_interface_descriptor interface_desc = { 59 .bLength = USB_DT_INTERFACE_SIZE, 60 .bDescriptorType = USB_DT_INTERFACE, 61 .bInterfaceNumber = 0x00, 62 .bAlternateSetting = 0x00, 63 .bNumEndpoints = 0x02, 64 .bInterfaceClass = ROCKUSB_INTERFACE_CLASS, 65 .bInterfaceSubClass = ROCKUSB_INTERFACE_SUB_CLASS, 66 .bInterfaceProtocol = ROCKUSB_INTERFACE_PROTOCOL, 67 }; 68 69 static struct usb_descriptor_header *rkusb_fs_function[] = { 70 (struct usb_descriptor_header *)&interface_desc, 71 (struct usb_descriptor_header *)&fs_ep_in, 72 (struct usb_descriptor_header *)&fs_ep_out, 73 }; 74 75 static struct usb_descriptor_header *rkusb_hs_function[] = { 76 (struct usb_descriptor_header *)&interface_desc, 77 (struct usb_descriptor_header *)&hs_ep_in, 78 (struct usb_descriptor_header *)&hs_ep_out, 79 NULL, 80 }; 81 82 static const char rkusb_name[] = "Rockchip Rockusb"; 83 84 static struct usb_string rkusb_string_defs[] = { 85 [0].s = rkusb_name, 86 { } /* end of list */ 87 }; 88 89 static struct usb_gadget_strings stringtab_rkusb = { 90 .language = 0x0409, /* en-us */ 91 .strings = rkusb_string_defs, 92 }; 93 94 static struct usb_gadget_strings *rkusb_strings[] = { 95 &stringtab_rkusb, 96 NULL, 97 }; 98 99 static struct f_rockusb *rockusb_func; 100 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req); 101 static int rockusb_tx_write_csw(u32 tag, int residue, u8 status, int size); 102 103 struct f_rockusb *get_rkusb(void) 104 { 105 struct f_rockusb *f_rkusb = rockusb_func; 106 107 if (!f_rkusb) { 108 f_rkusb = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*f_rkusb)); 109 if (!f_rkusb) 110 return 0; 111 112 rockusb_func = f_rkusb; 113 memset(f_rkusb, 0, sizeof(*f_rkusb)); 114 } 115 116 if (!f_rkusb->buf_head) { 117 f_rkusb->buf_head = memalign(CONFIG_SYS_CACHELINE_SIZE, 118 RKUSB_BUF_SIZE); 119 if (!f_rkusb->buf_head) 120 return 0; 121 122 f_rkusb->buf = f_rkusb->buf_head; 123 memset(f_rkusb->buf_head, 0, RKUSB_BUF_SIZE); 124 } 125 return f_rkusb; 126 } 127 128 static struct usb_endpoint_descriptor *rkusb_ep_desc( 129 struct usb_gadget *g, 130 struct usb_endpoint_descriptor *fs, 131 struct usb_endpoint_descriptor *hs) 132 { 133 if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) 134 return hs; 135 return fs; 136 } 137 138 static void rockusb_complete(struct usb_ep *ep, struct usb_request *req) 139 { 140 int status = req->status; 141 142 if (!status) 143 return; 144 debug("status: %d ep '%s' trans: %d\n", status, ep->name, req->actual); 145 } 146 147 /* config the rockusb device*/ 148 static int rockusb_bind(struct usb_configuration *c, struct usb_function *f) 149 { 150 int id; 151 struct usb_gadget *gadget = c->cdev->gadget; 152 struct f_rockusb *f_rkusb = func_to_rockusb(f); 153 const char *s; 154 155 id = usb_interface_id(c, f); 156 if (id < 0) 157 return id; 158 interface_desc.bInterfaceNumber = id; 159 160 id = usb_string_id(c->cdev); 161 if (id < 0) 162 return id; 163 164 rkusb_string_defs[0].id = id; 165 interface_desc.iInterface = id; 166 167 f_rkusb->in_ep = usb_ep_autoconfig(gadget, &fs_ep_in); 168 if (!f_rkusb->in_ep) 169 return -ENODEV; 170 f_rkusb->in_ep->driver_data = c->cdev; 171 172 f_rkusb->out_ep = usb_ep_autoconfig(gadget, &fs_ep_out); 173 if (!f_rkusb->out_ep) 174 return -ENODEV; 175 f_rkusb->out_ep->driver_data = c->cdev; 176 177 f->descriptors = rkusb_fs_function; 178 179 if (gadget_is_dualspeed(gadget)) { 180 hs_ep_in.bEndpointAddress = fs_ep_in.bEndpointAddress; 181 hs_ep_out.bEndpointAddress = fs_ep_out.bEndpointAddress; 182 f->hs_descriptors = rkusb_hs_function; 183 } 184 185 s = env_get("serial#"); 186 if (s) 187 g_dnl_set_serialnumber((char *)s); 188 189 return 0; 190 } 191 192 static void rockusb_unbind(struct usb_configuration *c, struct usb_function *f) 193 { 194 /* clear the configuration*/ 195 memset(rockusb_func, 0, sizeof(*rockusb_func)); 196 } 197 198 static void rockusb_disable(struct usb_function *f) 199 { 200 struct f_rockusb *f_rkusb = func_to_rockusb(f); 201 202 usb_ep_disable(f_rkusb->out_ep); 203 usb_ep_disable(f_rkusb->in_ep); 204 205 if (f_rkusb->out_req) { 206 free(f_rkusb->out_req->buf); 207 usb_ep_free_request(f_rkusb->out_ep, f_rkusb->out_req); 208 f_rkusb->out_req = NULL; 209 } 210 if (f_rkusb->in_req) { 211 free(f_rkusb->in_req->buf); 212 usb_ep_free_request(f_rkusb->in_ep, f_rkusb->in_req); 213 f_rkusb->in_req = NULL; 214 } 215 if (f_rkusb->buf_head) { 216 free(f_rkusb->buf_head); 217 f_rkusb->buf_head = NULL; 218 f_rkusb->buf = NULL; 219 } 220 } 221 222 static struct usb_request *rockusb_start_ep(struct usb_ep *ep) 223 { 224 struct usb_request *req; 225 226 req = usb_ep_alloc_request(ep, 0); 227 if (!req) 228 return NULL; 229 230 req->length = EP_BUFFER_SIZE; 231 req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, EP_BUFFER_SIZE); 232 if (!req->buf) { 233 usb_ep_free_request(ep, req); 234 return NULL; 235 } 236 memset(req->buf, 0, req->length); 237 238 return req; 239 } 240 241 static int rockusb_set_alt(struct usb_function *f, unsigned int interface, 242 unsigned int alt) 243 { 244 int ret; 245 struct usb_composite_dev *cdev = f->config->cdev; 246 struct usb_gadget *gadget = cdev->gadget; 247 struct f_rockusb *f_rkusb = func_to_rockusb(f); 248 const struct usb_endpoint_descriptor *d; 249 250 debug("%s: func: %s intf: %d alt: %d\n", 251 __func__, f->name, interface, alt); 252 253 d = rkusb_ep_desc(gadget, &fs_ep_out, &hs_ep_out); 254 ret = usb_ep_enable(f_rkusb->out_ep, d); 255 if (ret) { 256 printf("failed to enable out ep\n"); 257 return ret; 258 } 259 260 f_rkusb->out_req = rockusb_start_ep(f_rkusb->out_ep); 261 if (!f_rkusb->out_req) { 262 printf("failed to alloc out req\n"); 263 ret = -EINVAL; 264 goto err; 265 } 266 f_rkusb->out_req->complete = rx_handler_command; 267 268 d = rkusb_ep_desc(gadget, &fs_ep_in, &hs_ep_in); 269 ret = usb_ep_enable(f_rkusb->in_ep, d); 270 if (ret) { 271 printf("failed to enable in ep\n"); 272 goto err; 273 } 274 275 f_rkusb->in_req = rockusb_start_ep(f_rkusb->in_ep); 276 if (!f_rkusb->in_req) { 277 printf("failed alloc req in\n"); 278 ret = -EINVAL; 279 goto err; 280 } 281 f_rkusb->in_req->complete = rockusb_complete; 282 283 ret = usb_ep_queue(f_rkusb->out_ep, f_rkusb->out_req, 0); 284 if (ret) 285 goto err; 286 287 return 0; 288 err: 289 rockusb_disable(f); 290 return ret; 291 } 292 293 static int rockusb_add(struct usb_configuration *c) 294 { 295 struct f_rockusb *f_rkusb = get_rkusb(); 296 int status; 297 298 debug("%s: cdev: 0x%p\n", __func__, c->cdev); 299 300 f_rkusb->usb_function.name = "f_rockusb"; 301 f_rkusb->usb_function.bind = rockusb_bind; 302 f_rkusb->usb_function.unbind = rockusb_unbind; 303 f_rkusb->usb_function.set_alt = rockusb_set_alt; 304 f_rkusb->usb_function.disable = rockusb_disable; 305 f_rkusb->usb_function.strings = rkusb_strings; 306 307 status = usb_add_function(c, &f_rkusb->usb_function); 308 if (status) { 309 free(f_rkusb); 310 rockusb_func = f_rkusb; 311 } 312 return status; 313 } 314 315 void rockusb_dev_init(char *dev_type, int dev_index) 316 { 317 struct f_rockusb *f_rkusb = get_rkusb(); 318 319 f_rkusb->dev_type = dev_type; 320 f_rkusb->dev_index = dev_index; 321 } 322 323 DECLARE_GADGET_BIND_CALLBACK(usb_dnl_rockusb, rockusb_add); 324 325 static int rockusb_tx_write(const char *buffer, unsigned int buffer_size) 326 { 327 struct usb_request *in_req = rockusb_func->in_req; 328 int ret; 329 330 memcpy(in_req->buf, buffer, buffer_size); 331 in_req->length = buffer_size; 332 usb_ep_dequeue(rockusb_func->in_ep, in_req); 333 ret = usb_ep_queue(rockusb_func->in_ep, in_req, 0); 334 if (ret) 335 printf("Error %d on queue\n", ret); 336 return 0; 337 } 338 339 static int rockusb_tx_write_str(const char *buffer) 340 { 341 return rockusb_tx_write(buffer, strlen(buffer)); 342 } 343 344 #ifdef DEBUG 345 static void printcbw(char *buf) 346 { 347 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap, cbw, 348 sizeof(struct fsg_bulk_cb_wrap)); 349 350 memcpy((char *)cbw, buf, USB_BULK_CB_WRAP_LEN); 351 352 debug("cbw: signature:%x\n", cbw->signature); 353 debug("cbw: tag=%x\n", cbw->tag); 354 debug("cbw: data_transfer_length=%d\n", cbw->data_transfer_length); 355 debug("cbw: flags=%x\n", cbw->flags); 356 debug("cbw: lun=%d\n", cbw->lun); 357 debug("cbw: length=%d\n", cbw->length); 358 debug("cbw: ucOperCode=%x\n", cbw->CDB[0]); 359 debug("cbw: ucReserved=%x\n", cbw->CDB[1]); 360 debug("cbw: dwAddress:%x %x %x %x\n", cbw->CDB[5], cbw->CDB[4], 361 cbw->CDB[3], cbw->CDB[2]); 362 debug("cbw: ucReserved2=%x\n", cbw->CDB[6]); 363 debug("cbw: uslength:%x %x\n", cbw->CDB[8], cbw->CDB[7]); 364 } 365 366 static void printcsw(char *buf) 367 { 368 ALLOC_CACHE_ALIGN_BUFFER(struct bulk_cs_wrap, csw, 369 sizeof(struct bulk_cs_wrap)); 370 memcpy((char *)csw, buf, USB_BULK_CS_WRAP_LEN); 371 debug("csw: signature:%x\n", csw->signature); 372 debug("csw: tag:%x\n", csw->tag); 373 debug("csw: residue:%x\n", csw->residue); 374 debug("csw: status:%x\n", csw->status); 375 } 376 #endif 377 378 static int rockusb_tx_write_csw(u32 tag, int residue, u8 status, int size) 379 { 380 ALLOC_CACHE_ALIGN_BUFFER(struct bulk_cs_wrap, csw, 381 sizeof(struct bulk_cs_wrap)); 382 csw->signature = cpu_to_le32(USB_BULK_CS_SIG); 383 csw->tag = tag; 384 csw->residue = cpu_to_be32(residue); 385 csw->status = status; 386 #ifdef DEBUG 387 printcsw((char *)&csw); 388 #endif 389 return rockusb_tx_write((char *)csw, size); 390 } 391 392 static unsigned int rx_bytes_expected(struct usb_ep *ep) 393 { 394 struct f_rockusb *f_rkusb = get_rkusb(); 395 int rx_remain = f_rkusb->dl_size - f_rkusb->dl_bytes; 396 unsigned int rem; 397 unsigned int maxpacket = ep->maxpacket; 398 399 if (rx_remain <= 0) 400 return 0; 401 else if (rx_remain > EP_BUFFER_SIZE) 402 return EP_BUFFER_SIZE; 403 404 rem = rx_remain % maxpacket; 405 if (rem > 0) 406 rx_remain = rx_remain + (maxpacket - rem); 407 408 return rx_remain; 409 } 410 411 /* usb_request complete call back to handle down load image */ 412 static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req) 413 { 414 struct f_rockusb *f_rkusb = get_rkusb(); 415 unsigned int transfer_size = 0; 416 const unsigned char *buffer = req->buf; 417 unsigned int buffer_size = req->actual; 418 419 transfer_size = f_rkusb->dl_size - f_rkusb->dl_bytes; 420 if (!f_rkusb->desc) { 421 char *type = f_rkusb->dev_type; 422 int index = f_rkusb->dev_index; 423 424 f_rkusb->desc = blk_get_dev(type, index); 425 if (!f_rkusb->desc || 426 f_rkusb->desc->type == DEV_TYPE_UNKNOWN) { 427 puts("invalid mmc device\n"); 428 rockusb_tx_write_csw(f_rkusb->tag, 0, CSW_FAIL, 429 USB_BULK_CS_WRAP_LEN); 430 return; 431 } 432 } 433 434 if (req->status != 0) { 435 printf("Bad status: %d\n", req->status); 436 rockusb_tx_write_csw(f_rkusb->tag, 0, CSW_FAIL, 437 USB_BULK_CS_WRAP_LEN); 438 return; 439 } 440 441 if (buffer_size < transfer_size) 442 transfer_size = buffer_size; 443 444 memcpy((void *)f_rkusb->buf, buffer, transfer_size); 445 f_rkusb->dl_bytes += transfer_size; 446 int blks = 0, blkcnt = transfer_size / 512; 447 448 debug("dl %x bytes, %x blks, write lba %x, dl_size:%x, dl_bytes:%x, ", 449 transfer_size, blkcnt, f_rkusb->lba, f_rkusb->dl_size, 450 f_rkusb->dl_bytes); 451 blks = blk_dwrite(f_rkusb->desc, f_rkusb->lba, blkcnt, f_rkusb->buf); 452 if (blks != blkcnt) { 453 printf("failed writing to device %s: %d\n", f_rkusb->dev_type, 454 f_rkusb->dev_index); 455 rockusb_tx_write_csw(f_rkusb->tag, 0, CSW_FAIL, 456 USB_BULK_CS_WRAP_LEN); 457 return; 458 } 459 f_rkusb->lba += blkcnt; 460 461 /* Check if transfer is done */ 462 if (f_rkusb->dl_bytes >= f_rkusb->dl_size) { 463 req->complete = rx_handler_command; 464 req->length = EP_BUFFER_SIZE; 465 f_rkusb->buf = f_rkusb->buf_head; 466 printf("transfer 0x%x bytes done\n", f_rkusb->dl_size); 467 f_rkusb->dl_size = 0; 468 rockusb_tx_write_csw(f_rkusb->tag, 0, CSW_GOOD, 469 USB_BULK_CS_WRAP_LEN); 470 } else { 471 req->length = rx_bytes_expected(ep); 472 if (f_rkusb->buf == f_rkusb->buf_head) 473 f_rkusb->buf = f_rkusb->buf_head + EP_BUFFER_SIZE; 474 else 475 f_rkusb->buf = f_rkusb->buf_head; 476 477 debug("remain %x bytes, %x sectors\n", req->length, 478 req->length / 512); 479 } 480 481 req->actual = 0; 482 usb_ep_queue(ep, req, 0); 483 } 484 485 static void cb_test_unit_ready(struct usb_ep *ep, struct usb_request *req) 486 { 487 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap, cbw, 488 sizeof(struct fsg_bulk_cb_wrap)); 489 490 memcpy((char *)cbw, req->buf, USB_BULK_CB_WRAP_LEN); 491 492 rockusb_tx_write_csw(cbw->tag, cbw->data_transfer_length, 493 CSW_GOOD, USB_BULK_CS_WRAP_LEN); 494 } 495 496 static void cb_read_storage_id(struct usb_ep *ep, struct usb_request *req) 497 { 498 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap, cbw, 499 sizeof(struct fsg_bulk_cb_wrap)); 500 char emmc_id[] = "EMMC "; 501 502 printf("read storage id\n"); 503 memcpy((char *)cbw, req->buf, USB_BULK_CB_WRAP_LEN); 504 rockusb_tx_write_str(emmc_id); 505 rockusb_tx_write_csw(cbw->tag, cbw->data_transfer_length, CSW_GOOD, 506 USB_BULK_CS_WRAP_LEN); 507 } 508 509 static void cb_write_lba(struct usb_ep *ep, struct usb_request *req) 510 { 511 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap, cbw, 512 sizeof(struct fsg_bulk_cb_wrap)); 513 struct f_rockusb *f_rkusb = get_rkusb(); 514 int sector_count; 515 516 memcpy((char *)cbw, req->buf, USB_BULK_CB_WRAP_LEN); 517 sector_count = (int)get_unaligned_be16(&cbw->CDB[7]); 518 f_rkusb->lba = get_unaligned_be32(&cbw->CDB[2]); 519 f_rkusb->dl_size = sector_count * 512; 520 f_rkusb->dl_bytes = 0; 521 f_rkusb->tag = cbw->tag; 522 debug("require write %x bytes, %x sectors to lba %x\n", 523 f_rkusb->dl_size, sector_count, f_rkusb->lba); 524 525 if (f_rkusb->dl_size == 0) { 526 rockusb_tx_write_csw(cbw->tag, cbw->data_transfer_length, 527 CSW_FAIL, USB_BULK_CS_WRAP_LEN); 528 } else { 529 req->complete = rx_handler_dl_image; 530 req->length = rx_bytes_expected(ep); 531 } 532 } 533 534 void __weak rkusb_set_reboot_flag(int flag) 535 { 536 struct f_rockusb *f_rkusb = get_rkusb(); 537 538 printf("rockkusb set reboot flag: %d\n", f_rkusb->reboot_flag); 539 } 540 541 static void compl_do_reset(struct usb_ep *ep, struct usb_request *req) 542 { 543 struct f_rockusb *f_rkusb = get_rkusb(); 544 545 rkusb_set_reboot_flag(f_rkusb->reboot_flag); 546 do_reset(NULL, 0, 0, NULL); 547 } 548 549 static void cb_reboot(struct usb_ep *ep, struct usb_request *req) 550 { 551 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap, cbw, 552 sizeof(struct fsg_bulk_cb_wrap)); 553 struct f_rockusb *f_rkusb = get_rkusb(); 554 555 f_rkusb->reboot_flag = 0; 556 memcpy((char *)cbw, req->buf, USB_BULK_CB_WRAP_LEN); 557 f_rkusb->reboot_flag = cbw->CDB[1]; 558 rockusb_func->in_req->complete = compl_do_reset; 559 rockusb_tx_write_csw(cbw->tag, cbw->data_transfer_length, CSW_GOOD, 560 USB_BULK_CS_WRAP_LEN); 561 } 562 563 static void cb_not_support(struct usb_ep *ep, struct usb_request *req) 564 { 565 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap, cbw, 566 sizeof(struct fsg_bulk_cb_wrap)); 567 568 memcpy((char *)cbw, req->buf, USB_BULK_CB_WRAP_LEN); 569 printf("Rockusb command %x not support yet\n", cbw->CDB[0]); 570 rockusb_tx_write_csw(cbw->tag, 0, CSW_FAIL, USB_BULK_CS_WRAP_LEN); 571 } 572 573 static const struct cmd_dispatch_info cmd_dispatch_info[] = { 574 { 575 .cmd = K_FW_TEST_UNIT_READY, 576 .cb = cb_test_unit_ready, 577 }, 578 { 579 .cmd = K_FW_READ_FLASH_ID, 580 .cb = cb_read_storage_id, 581 }, 582 { 583 .cmd = K_FW_SET_DEVICE_ID, 584 .cb = cb_not_support, 585 }, 586 { 587 .cmd = K_FW_TEST_BAD_BLOCK, 588 .cb = cb_not_support, 589 }, 590 { 591 .cmd = K_FW_READ_10, 592 .cb = cb_not_support, 593 }, 594 { 595 .cmd = K_FW_WRITE_10, 596 .cb = cb_not_support, 597 }, 598 { 599 .cmd = K_FW_ERASE_10, 600 .cb = cb_not_support, 601 }, 602 { 603 .cmd = K_FW_WRITE_SPARE, 604 .cb = cb_not_support, 605 }, 606 { 607 .cmd = K_FW_READ_SPARE, 608 .cb = cb_not_support, 609 }, 610 { 611 .cmd = K_FW_ERASE_10_FORCE, 612 .cb = cb_not_support, 613 }, 614 { 615 .cmd = K_FW_GET_VERSION, 616 .cb = cb_not_support, 617 }, 618 { 619 .cmd = K_FW_LBA_READ_10, 620 .cb = cb_not_support, 621 }, 622 { 623 .cmd = K_FW_LBA_WRITE_10, 624 .cb = cb_write_lba, 625 }, 626 { 627 .cmd = K_FW_ERASE_SYS_DISK, 628 .cb = cb_not_support, 629 }, 630 { 631 .cmd = K_FW_SDRAM_READ_10, 632 .cb = cb_not_support, 633 }, 634 { 635 .cmd = K_FW_SDRAM_WRITE_10, 636 .cb = cb_not_support, 637 }, 638 { 639 .cmd = K_FW_SDRAM_EXECUTE, 640 .cb = cb_not_support, 641 }, 642 { 643 .cmd = K_FW_READ_FLASH_INFO, 644 .cb = cb_not_support, 645 }, 646 { 647 .cmd = K_FW_GET_CHIP_VER, 648 .cb = cb_not_support, 649 }, 650 { 651 .cmd = K_FW_LOW_FORMAT, 652 .cb = cb_not_support, 653 }, 654 { 655 .cmd = K_FW_SET_RESET_FLAG, 656 .cb = cb_not_support, 657 }, 658 { 659 .cmd = K_FW_SPI_READ_10, 660 .cb = cb_not_support, 661 }, 662 { 663 .cmd = K_FW_SPI_WRITE_10, 664 .cb = cb_not_support, 665 }, 666 { 667 .cmd = K_FW_SESSION, 668 .cb = cb_not_support, 669 }, 670 { 671 .cmd = K_FW_RESET, 672 .cb = cb_reboot, 673 }, 674 }; 675 676 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) 677 { 678 void (*func_cb)(struct usb_ep *ep, struct usb_request *req) = NULL; 679 680 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap, cbw, 681 sizeof(struct fsg_bulk_cb_wrap)); 682 char *cmdbuf = req->buf; 683 int i; 684 685 if (req->status || req->length == 0) 686 return; 687 688 memcpy((char *)cbw, req->buf, USB_BULK_CB_WRAP_LEN); 689 #ifdef DEBUG 690 printcbw(req->buf); 691 #endif 692 693 for (i = 0; i < ARRAY_SIZE(cmd_dispatch_info); i++) { 694 if (cmd_dispatch_info[i].cmd == cbw->CDB[0]) { 695 func_cb = cmd_dispatch_info[i].cb; 696 break; 697 } 698 } 699 700 if (!func_cb) { 701 printf("unknown command: %s\n", (char *)req->buf); 702 rockusb_tx_write_str("FAILunknown command"); 703 } else { 704 if (req->actual < req->length) { 705 u8 *buf = (u8 *)req->buf; 706 707 buf[req->actual] = 0; 708 func_cb(ep, req); 709 } else { 710 puts("buffer overflow\n"); 711 rockusb_tx_write_str("FAILbuffer overflow"); 712 } 713 } 714 715 *cmdbuf = '\0'; 716 req->actual = 0; 717 usb_ep_queue(ep, req, 0); 718 } 719