1 /* 2 * Copyright (c) 2021, STMicroelectronics - All Rights Reserved 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <stdint.h> 9 10 #include <common/debug.h> 11 #include <drivers/usb_device.h> 12 13 /* Define for EP address */ 14 #define EP_DIR_MASK BIT(7) 15 #define EP_DIR_IN BIT(7) 16 #define EP_NUM_MASK GENMASK(3, 0) 17 18 #define EP0_IN (0U | EP_DIR_IN) 19 #define EP0_OUT 0U 20 21 /* USB address between 1 through 127 = 0x7F mask */ 22 #define ADDRESS_MASK GENMASK(6, 0) 23 24 /* 25 * Set a STALL condition over an endpoint 26 * pdev: USB handle 27 * ep_addr: endpoint address 28 * return : status 29 */ 30 static enum usb_status usb_core_set_stall(struct usb_handle *pdev, uint8_t ep_addr) 31 { 32 struct usbd_ep *ep; 33 struct pcd_handle *hpcd = (struct pcd_handle *)pdev->data; 34 uint8_t num; 35 36 num = ep_addr & EP_NUM_MASK; 37 if (num >= USBD_EP_NB) { 38 return USBD_FAIL; 39 } 40 if ((EP_DIR_MASK & ep_addr) == EP_DIR_IN) { 41 ep = &hpcd->in_ep[num]; 42 ep->is_in = true; 43 } else { 44 ep = &hpcd->out_ep[num]; 45 ep->is_in = false; 46 } 47 ep->num = num; 48 49 pdev->driver->ep_set_stall(hpcd->instance, ep); 50 if (num == 0U) { 51 pdev->driver->ep0_out_start(hpcd->instance); 52 } 53 54 return USBD_OK; 55 } 56 57 /* 58 * usb_core_get_desc 59 * Handle Get Descriptor requests 60 * pdev : device instance 61 * req : usb request 62 */ 63 static void usb_core_get_desc(struct usb_handle *pdev, struct usb_setup_req *req) 64 { 65 uint16_t len; 66 uint8_t *pbuf; 67 uint8_t desc_type = HIBYTE(req->value); 68 uint8_t desc_idx = LOBYTE(req->value); 69 70 switch (desc_type) { 71 case USB_DESC_TYPE_DEVICE: 72 pbuf = pdev->desc->get_device_desc(&len); 73 break; 74 75 case USB_DESC_TYPE_CONFIGURATION: 76 pbuf = (uint8_t *)pdev->desc->get_config_desc(&len); 77 pbuf[1] = USB_DESC_TYPE_CONFIGURATION; 78 break; 79 80 case USB_DESC_TYPE_STRING: 81 switch (desc_idx) { 82 case USBD_IDX_LANGID_STR: 83 pbuf = pdev->desc->get_lang_id_desc(&len); 84 break; 85 86 case USBD_IDX_MFC_STR: 87 pbuf = pdev->desc->get_manufacturer_desc(&len); 88 break; 89 90 case USBD_IDX_PRODUCT_STR: 91 pbuf = pdev->desc->get_product_desc(&len); 92 break; 93 94 case USBD_IDX_SERIAL_STR: 95 pbuf = pdev->desc->get_serial_desc(&len); 96 break; 97 98 case USBD_IDX_CONFIG_STR: 99 pbuf = pdev->desc->get_configuration_desc(&len); 100 break; 101 102 case USBD_IDX_INTERFACE_STR: 103 pbuf = pdev->desc->get_interface_desc(&len); 104 break; 105 106 /* For all USER string */ 107 case USBD_IDX_USER0_STR: 108 default: 109 pbuf = pdev->desc->get_usr_desc(desc_idx - USBD_IDX_USER0_STR, &len); 110 break; 111 } 112 break; 113 114 case USB_DESC_TYPE_DEVICE_QUALIFIER: 115 pbuf = (uint8_t *)pdev->desc->get_device_qualifier_desc(&len); 116 break; 117 118 case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: 119 pbuf = (uint8_t *)pdev->desc->get_config_desc(&len); 120 pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; 121 break; 122 123 default: 124 ERROR("Unknown request %i\n", desc_type); 125 usb_core_ctl_error(pdev); 126 return; 127 } 128 129 if ((len != 0U) && (req->length != 0U)) { 130 len = MIN(len, req->length); 131 132 /* Start the transfer */ 133 usb_core_transmit_ep0(pdev, pbuf, len); 134 } 135 } 136 137 /* 138 * usb_core_set_config 139 * Handle Set device configuration request 140 * pdev : device instance 141 * req : usb request 142 */ 143 static void usb_core_set_config(struct usb_handle *pdev, struct usb_setup_req *req) 144 { 145 static uint8_t cfgidx; 146 147 cfgidx = LOBYTE(req->value); 148 149 if (cfgidx > USBD_MAX_NUM_CONFIGURATION) { 150 usb_core_ctl_error(pdev); 151 return; 152 } 153 154 switch (pdev->dev_state) { 155 case USBD_STATE_ADDRESSED: 156 if (cfgidx != 0U) { 157 pdev->dev_config = cfgidx; 158 pdev->dev_state = USBD_STATE_CONFIGURED; 159 if (!pdev->class) { 160 usb_core_ctl_error(pdev); 161 return; 162 } 163 /* Set configuration and Start the Class */ 164 if (pdev->class->init(pdev, cfgidx) != 0U) { 165 usb_core_ctl_error(pdev); 166 return; 167 } 168 } 169 break; 170 171 case USBD_STATE_CONFIGURED: 172 if (cfgidx == 0U) { 173 pdev->dev_state = USBD_STATE_ADDRESSED; 174 pdev->dev_config = cfgidx; 175 pdev->class->de_init(pdev, cfgidx); 176 } else if (cfgidx != pdev->dev_config) { 177 if (pdev->class == NULL) { 178 usb_core_ctl_error(pdev); 179 return; 180 } 181 /* Clear old configuration */ 182 pdev->class->de_init(pdev, pdev->dev_config); 183 /* Set new configuration */ 184 pdev->dev_config = cfgidx; 185 /* Set configuration and start the USB class */ 186 if (pdev->class->init(pdev, cfgidx) != 0U) { 187 usb_core_ctl_error(pdev); 188 return; 189 } 190 } 191 break; 192 193 default: 194 usb_core_ctl_error(pdev); 195 return; 196 } 197 198 /* Send status */ 199 usb_core_transmit_ep0(pdev, NULL, 0U); 200 } 201 202 /* 203 * usb_core_get_status 204 * Handle Get Status request 205 * pdev : device instance 206 * req : usb request 207 */ 208 static void usb_core_get_status(struct usb_handle *pdev, 209 struct usb_setup_req *req) 210 { 211 if ((pdev->dev_state != USBD_STATE_ADDRESSED) && 212 (pdev->dev_state != USBD_STATE_CONFIGURED)) { 213 usb_core_ctl_error(pdev); 214 return; 215 } 216 217 pdev->dev_config_status = USB_CONFIG_SELF_POWERED; 218 219 if (pdev->dev_remote_wakeup != 0U) { 220 pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; 221 } 222 223 /* Start the transfer */ 224 usb_core_transmit_ep0(pdev, (uint8_t *)&pdev->dev_config_status, 2U); 225 } 226 227 /* 228 * usb_core_set_address 229 * Set device address 230 * pdev : device instance 231 * req : usb request 232 */ 233 static void usb_core_set_address(struct usb_handle *pdev, 234 struct usb_setup_req *req) 235 { 236 uint8_t dev_addr; 237 238 if ((req->index != 0U) || (req->length != 0U)) { 239 usb_core_ctl_error(pdev); 240 return; 241 } 242 243 dev_addr = req->value & ADDRESS_MASK; 244 if (pdev->dev_state != USBD_STATE_DEFAULT) { 245 usb_core_ctl_error(pdev); 246 return; 247 } 248 249 pdev->dev_address = dev_addr; 250 pdev->driver->set_address(((struct pcd_handle *)(pdev->data))->instance, dev_addr); 251 252 /* Send status */ 253 usb_core_transmit_ep0(pdev, NULL, 0U); 254 255 if (dev_addr != 0U) { 256 pdev->dev_state = USBD_STATE_ADDRESSED; 257 } else { 258 pdev->dev_state = USBD_STATE_DEFAULT; 259 } 260 } 261 262 /* 263 * usb_core_dev_req 264 * Handle standard usb device requests 265 * pdev : device instance 266 * req : usb request 267 * return : status 268 */ 269 static enum usb_status usb_core_dev_req(struct usb_handle *pdev, 270 struct usb_setup_req *req) 271 { 272 VERBOSE("receive request %i\n", req->b_request); 273 switch (req->b_request) { 274 case USB_REQ_GET_DESCRIPTOR: 275 usb_core_get_desc(pdev, req); 276 break; 277 278 case USB_REQ_SET_CONFIGURATION: 279 usb_core_set_config(pdev, req); 280 break; 281 282 case USB_REQ_GET_STATUS: 283 usb_core_get_status(pdev, req); 284 break; 285 286 case USB_REQ_SET_ADDRESS: 287 usb_core_set_address(pdev, req); 288 break; 289 290 case USB_REQ_GET_CONFIGURATION: 291 case USB_REQ_SET_FEATURE: 292 case USB_REQ_CLEAR_FEATURE: 293 default: 294 ERROR("NOT SUPPORTED %i\n", req->b_request); 295 usb_core_ctl_error(pdev); 296 break; 297 } 298 299 return USBD_OK; 300 } 301 302 /* 303 * usb_core_itf_req 304 * Handle standard usb interface requests 305 * pdev : device instance 306 * req : usb request 307 * return : status 308 */ 309 static enum usb_status usb_core_itf_req(struct usb_handle *pdev, 310 struct usb_setup_req *req) 311 { 312 if (pdev->dev_state != USBD_STATE_CONFIGURED) { 313 usb_core_ctl_error(pdev); 314 return USBD_OK; 315 } 316 317 if (LOBYTE(req->index) <= USBD_MAX_NUM_INTERFACES) { 318 pdev->class->setup(pdev, req); 319 320 if (req->length == 0U) { 321 usb_core_transmit_ep0(pdev, NULL, 0U); 322 } 323 } else { 324 usb_core_ctl_error(pdev); 325 } 326 327 return USBD_OK; 328 } 329 330 /* 331 * usb_core_setup_stage 332 * Handle the setup stage 333 * pdev: device instance 334 * psetup : setup buffer 335 * return : status 336 */ 337 static enum usb_status usb_core_setup_stage(struct usb_handle *pdev, 338 uint8_t *psetup) 339 { 340 struct usb_setup_req *req = &pdev->request; 341 342 /* Copy setup buffer into req structure */ 343 req->bm_request = psetup[0]; 344 req->b_request = psetup[1]; 345 req->value = psetup[2] + (psetup[3] << 8); 346 req->index = psetup[4] + (psetup[5] << 8); 347 req->length = psetup[6] + (psetup[7] << 8); 348 349 pdev->ep0_state = USBD_EP0_SETUP; 350 pdev->ep0_data_len = pdev->request.length; 351 352 switch (pdev->request.bm_request & USB_REQ_RECIPIENT_MASK) { 353 case USB_REQ_RECIPIENT_DEVICE: 354 usb_core_dev_req(pdev, &pdev->request); 355 break; 356 357 case USB_REQ_RECIPIENT_INTERFACE: 358 usb_core_itf_req(pdev, &pdev->request); 359 break; 360 361 case USB_REQ_RECIPIENT_ENDPOINT: 362 default: 363 ERROR("receive unsupported request %i", 364 pdev->request.bm_request & USB_REQ_RECIPIENT_MASK); 365 usb_core_set_stall(pdev, pdev->request.bm_request & USB_REQ_DIRECTION); 366 return USBD_FAIL; 367 } 368 369 return USBD_OK; 370 } 371 372 /* 373 * usb_core_data_out 374 * Handle data OUT stage 375 * pdev: device instance 376 * epnum: endpoint index 377 * pdata: buffer to sent 378 * return : status 379 */ 380 static enum usb_status usb_core_data_out(struct usb_handle *pdev, uint8_t epnum, 381 uint8_t *pdata) 382 { 383 struct usb_endpoint *pep; 384 385 if (epnum == 0U) { 386 pep = &pdev->ep_out[0]; 387 if (pdev->ep0_state == USBD_EP0_DATA_OUT) { 388 if (pep->rem_length > pep->maxpacket) { 389 pep->rem_length -= pep->maxpacket; 390 391 usb_core_receive(pdev, 0U, pdata, 392 MIN(pep->rem_length, 393 pep->maxpacket)); 394 } else { 395 if (pdev->class->ep0_rx_ready && 396 (pdev->dev_state == USBD_STATE_CONFIGURED)) { 397 pdev->class->ep0_rx_ready(pdev); 398 } 399 400 usb_core_transmit_ep0(pdev, NULL, 0U); 401 } 402 } 403 } else if (pdev->class->data_out != NULL && 404 (pdev->dev_state == USBD_STATE_CONFIGURED)) { 405 pdev->class->data_out(pdev, epnum); 406 } 407 408 return USBD_OK; 409 } 410 411 /* 412 * usb_core_data_in 413 * Handle data in stage 414 * pdev: device instance 415 * epnum: endpoint index 416 * pdata: buffer to fill 417 * return : status 418 */ 419 static enum usb_status usb_core_data_in(struct usb_handle *pdev, uint8_t epnum, 420 uint8_t *pdata) 421 { 422 if (epnum == 0U) { 423 struct usb_endpoint *pep = &pdev->ep_in[0]; 424 425 if (pdev->ep0_state == USBD_EP0_DATA_IN) { 426 if (pep->rem_length > pep->maxpacket) { 427 pep->rem_length -= pep->maxpacket; 428 429 usb_core_transmit(pdev, 0U, pdata, 430 pep->rem_length); 431 432 /* Prepare EP for premature end of transfer */ 433 usb_core_receive(pdev, 0U, NULL, 0U); 434 } else { 435 /* Last packet is MPS multiple, send ZLP packet */ 436 if ((pep->total_length % pep->maxpacket == 0U) && 437 (pep->total_length >= pep->maxpacket) && 438 (pep->total_length < pdev->ep0_data_len)) { 439 usb_core_transmit(pdev, 0U, NULL, 0U); 440 441 pdev->ep0_data_len = 0U; 442 443 /* Prepare endpoint for premature end of transfer */ 444 usb_core_receive(pdev, 0U, NULL, 0U); 445 } else { 446 if (pdev->class->ep0_tx_sent != NULL && 447 (pdev->dev_state == 448 USBD_STATE_CONFIGURED)) { 449 pdev->class->ep0_tx_sent(pdev); 450 } 451 /* Start the transfer */ 452 usb_core_receive_ep0(pdev, NULL, 0U); 453 } 454 } 455 } 456 } else if ((pdev->class->data_in != NULL) && 457 (pdev->dev_state == USBD_STATE_CONFIGURED)) { 458 pdev->class->data_in(pdev, epnum); 459 } 460 461 return USBD_OK; 462 } 463 464 /* 465 * usb_core_suspend 466 * Handle suspend event 467 * pdev : device instance 468 * return : status 469 */ 470 static enum usb_status usb_core_suspend(struct usb_handle *pdev) 471 { 472 INFO("USB Suspend mode\n"); 473 pdev->dev_old_state = pdev->dev_state; 474 pdev->dev_state = USBD_STATE_SUSPENDED; 475 476 return USBD_OK; 477 } 478 479 /* 480 * usb_core_resume 481 * Handle resume event 482 * pdev : device instance 483 * return : status 484 */ 485 static enum usb_status usb_core_resume(struct usb_handle *pdev) 486 { 487 INFO("USB Resume\n"); 488 pdev->dev_state = pdev->dev_old_state; 489 490 return USBD_OK; 491 } 492 493 /* 494 * usb_core_sof 495 * Handle SOF event 496 * pdev : device instance 497 * return : status 498 */ 499 static enum usb_status usb_core_sof(struct usb_handle *pdev) 500 { 501 if (pdev->dev_state == USBD_STATE_CONFIGURED) { 502 if (pdev->class->sof != NULL) { 503 pdev->class->sof(pdev); 504 } 505 } 506 507 return USBD_OK; 508 } 509 510 /* 511 * usb_core_disconnect 512 * Handle device disconnection event 513 * pdev : device instance 514 * return : status 515 */ 516 static enum usb_status usb_core_disconnect(struct usb_handle *pdev) 517 { 518 /* Free class resources */ 519 pdev->dev_state = USBD_STATE_DEFAULT; 520 pdev->class->de_init(pdev, pdev->dev_config); 521 522 return USBD_OK; 523 } 524 525 enum usb_status usb_core_handle_it(struct usb_handle *pdev) 526 { 527 uint32_t param = 0U; 528 uint32_t len = 0U; 529 struct usbd_ep *ep; 530 531 switch (pdev->driver->it_handler(pdev->data->instance, ¶m)) { 532 case USB_DATA_OUT: 533 usb_core_data_out(pdev, param, 534 pdev->data->out_ep[param].xfer_buff); 535 break; 536 537 case USB_DATA_IN: 538 usb_core_data_in(pdev, param, 539 pdev->data->in_ep[param].xfer_buff); 540 break; 541 542 case USB_SETUP: 543 usb_core_setup_stage(pdev, (uint8_t *)pdev->data->setup); 544 break; 545 546 case USB_ENUM_DONE: 547 break; 548 549 case USB_READ_DATA_PACKET: 550 ep = &pdev->data->out_ep[param & USBD_OUT_EPNUM_MASK]; 551 len = (param & USBD_OUT_COUNT_MASK) >> USBD_OUT_COUNT_SHIFT; 552 pdev->driver->read_packet(pdev->data->instance, 553 ep->xfer_buff, len); 554 ep->xfer_buff += len; 555 ep->xfer_count += len; 556 break; 557 558 case USB_READ_SETUP_PACKET: 559 ep = &pdev->data->out_ep[param & USBD_OUT_EPNUM_MASK]; 560 len = (param & USBD_OUT_COUNT_MASK) >> 0x10; 561 pdev->driver->read_packet(pdev->data->instance, 562 (uint8_t *)pdev->data->setup, 8); 563 ep->xfer_count += len; 564 break; 565 566 case USB_RESET: 567 pdev->dev_state = USBD_STATE_DEFAULT; 568 break; 569 570 case USB_RESUME: 571 if (pdev->data->lpm_state == LPM_L1) { 572 pdev->data->lpm_state = LPM_L0; 573 } else { 574 usb_core_resume(pdev); 575 } 576 break; 577 578 case USB_SUSPEND: 579 usb_core_suspend(pdev); 580 break; 581 582 case USB_LPM: 583 if (pdev->data->lpm_state == LPM_L0) { 584 pdev->data->lpm_state = LPM_L1; 585 } else { 586 usb_core_suspend(pdev); 587 } 588 break; 589 590 case USB_SOF: 591 usb_core_sof(pdev); 592 break; 593 594 case USB_DISCONNECT: 595 usb_core_disconnect(pdev); 596 break; 597 598 case USB_WRITE_EMPTY: 599 pdev->driver->write_empty_tx_fifo(pdev->data->instance, param, 600 pdev->data->in_ep[param].xfer_len, 601 (uint32_t *)&pdev->data->in_ep[param].xfer_count, 602 pdev->data->in_ep[param].maxpacket, 603 &pdev->data->in_ep[param].xfer_buff); 604 break; 605 606 case USB_NOTHING: 607 default: 608 break; 609 } 610 611 return USBD_OK; 612 } 613 614 static void usb_core_start_xfer(struct usb_handle *pdev, 615 void *handle, 616 struct usbd_ep *ep) 617 { 618 if (ep->num == 0U) { 619 pdev->driver->ep0_start_xfer(handle, ep); 620 } else { 621 pdev->driver->ep_start_xfer(handle, ep); 622 } 623 } 624 625 /* 626 * usb_core_receive 627 * Receive an amount of data 628 * pdev: USB handle 629 * ep_addr: endpoint address 630 * buf: pointer to the reception buffer 631 * len: amount of data to be received 632 * return : status 633 */ 634 enum usb_status usb_core_receive(struct usb_handle *pdev, uint8_t ep_addr, 635 uint8_t *buf, uint32_t len) 636 { 637 struct usbd_ep *ep; 638 struct pcd_handle *hpcd = (struct pcd_handle *)pdev->data; 639 uint8_t num; 640 641 num = ep_addr & EP_NUM_MASK; 642 if (num >= USBD_EP_NB) { 643 return USBD_FAIL; 644 } 645 ep = &hpcd->out_ep[num]; 646 647 /* Setup and start the Xfer */ 648 ep->xfer_buff = buf; 649 ep->xfer_len = len; 650 ep->xfer_count = 0U; 651 ep->is_in = false; 652 ep->num = num; 653 654 usb_core_start_xfer(pdev, hpcd->instance, ep); 655 656 return USBD_OK; 657 } 658 659 /* 660 * usb_core_transmit 661 * Send an amount of data 662 * pdev: USB handle 663 * ep_addr: endpoint address 664 * buf: pointer to the transmission buffer 665 * len: amount of data to be sent 666 * return : status 667 */ 668 enum usb_status usb_core_transmit(struct usb_handle *pdev, uint8_t ep_addr, 669 uint8_t *buf, uint32_t len) 670 { 671 struct usbd_ep *ep; 672 struct pcd_handle *hpcd = (struct pcd_handle *)pdev->data; 673 uint8_t num; 674 675 num = ep_addr & EP_NUM_MASK; 676 if (num >= USBD_EP_NB) { 677 return USBD_FAIL; 678 } 679 ep = &hpcd->in_ep[num]; 680 681 /* Setup and start the Xfer */ 682 ep->xfer_buff = buf; 683 ep->xfer_len = len; 684 ep->xfer_count = 0U; 685 ep->is_in = true; 686 ep->num = num; 687 688 usb_core_start_xfer(pdev, hpcd->instance, ep); 689 690 return USBD_OK; 691 } 692 693 /* 694 * usb_core_receive_ep0 695 * Receive an amount of data on ep0 696 * pdev: USB handle 697 * buf: pointer to the reception buffer 698 * len: amount of data to be received 699 * return : status 700 */ 701 enum usb_status usb_core_receive_ep0(struct usb_handle *pdev, uint8_t *buf, 702 uint32_t len) 703 { 704 /* Prepare the reception of the buffer over EP0 */ 705 if (len != 0U) { 706 pdev->ep0_state = USBD_EP0_DATA_OUT; 707 } else { 708 pdev->ep0_state = USBD_EP0_STATUS_OUT; 709 } 710 711 pdev->ep_out[0].total_length = len; 712 pdev->ep_out[0].rem_length = len; 713 714 /* Start the transfer */ 715 return usb_core_receive(pdev, 0U, buf, len); 716 } 717 718 /* 719 * usb_core_transmit_ep0 720 * Send an amount of data on ep0 721 * pdev: USB handle 722 * buf: pointer to the transmission buffer 723 * len: amount of data to be sent 724 * return : status 725 */ 726 enum usb_status usb_core_transmit_ep0(struct usb_handle *pdev, uint8_t *buf, 727 uint32_t len) 728 { 729 /* Set EP0 State */ 730 if (len != 0U) { 731 pdev->ep0_state = USBD_EP0_DATA_IN; 732 } else { 733 pdev->ep0_state = USBD_EP0_STATUS_IN; 734 } 735 736 pdev->ep_in[0].total_length = len; 737 pdev->ep_in[0].rem_length = len; 738 739 /* Start the transfer */ 740 return usb_core_transmit(pdev, 0U, buf, len); 741 } 742 743 /* 744 * usb_core_ctl_error 745 * Handle USB low level error 746 * pdev: device instance 747 * req: usb request 748 * return : None 749 */ 750 751 void usb_core_ctl_error(struct usb_handle *pdev) 752 { 753 ERROR("%s : Send an ERROR\n", __func__); 754 usb_core_set_stall(pdev, EP0_IN); 755 usb_core_set_stall(pdev, EP0_OUT); 756 } 757 758 /* 759 * usb_core_start 760 * Start the USB device core. 761 * pdev: Device Handle 762 * return : USBD Status 763 */ 764 enum usb_status usb_core_start(struct usb_handle *pdev) 765 { 766 /* Start the low level driver */ 767 pdev->driver->start_device(pdev->data->instance); 768 769 return USBD_OK; 770 } 771 772 /* 773 * usb_core_stop 774 * Stop the USB device core. 775 * pdev: Device Handle 776 * return : USBD Status 777 */ 778 enum usb_status usb_core_stop(struct usb_handle *pdev) 779 { 780 /* Free class resources */ 781 pdev->class->de_init(pdev, pdev->dev_config); 782 783 /* Stop the low level driver */ 784 pdev->driver->stop_device(pdev->data->instance); 785 786 return USBD_OK; 787 } 788 789 /* 790 * register_usb_driver 791 * Stop the USB device core. 792 * pdev: Device Handle 793 * pcd_handle: PCD handle 794 * driver: USB driver 795 * driver_handle: USB driver handle 796 * return : USBD Status 797 */ 798 enum usb_status register_usb_driver(struct usb_handle *pdev, 799 struct pcd_handle *pcd_handle, 800 const struct usb_driver *driver, 801 void *driver_handle) 802 { 803 uint8_t i; 804 805 assert(pdev != NULL); 806 assert(pcd_handle != NULL); 807 assert(driver != NULL); 808 assert(driver_handle != NULL); 809 810 /* Free class resources */ 811 pdev->driver = driver; 812 pdev->data = pcd_handle; 813 pdev->data->instance = driver_handle; 814 pdev->dev_state = USBD_STATE_DEFAULT; 815 pdev->ep0_state = USBD_EP0_IDLE; 816 817 /* Copy endpoint information */ 818 for (i = 0U; i < USBD_EP_NB; i++) { 819 pdev->ep_in[i].maxpacket = pdev->data->in_ep[i].maxpacket; 820 pdev->ep_out[i].maxpacket = pdev->data->out_ep[i].maxpacket; 821 } 822 823 return USBD_OK; 824 } 825 826 /* 827 * register_platform 828 * Register the USB device core. 829 * pdev: Device Handle 830 * plat_call_back: callback 831 * return : USBD Status 832 */ 833 enum usb_status register_platform(struct usb_handle *pdev, 834 const struct usb_desc *plat_call_back) 835 { 836 assert(pdev != NULL); 837 assert(plat_call_back != NULL); 838 839 /* Save platform info in class resources */ 840 pdev->desc = plat_call_back; 841 842 return USBD_OK; 843 } 844