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