Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: implement endpoint allocation

this commit has following changes:
- introduce `usb_drv_ep_spec` table to udc drivers, which represents
endpoint characteristics.
- introduce 'ep_allocs' table to class drivers, which represents what
endpoint type does the class driver want.
- implement endpoint matching logic to usb core.

this is a required step to implement usb config switching, because we
need to create config descriptors without actually initializing endpoints.

Change-Id: I11c324cd35189ab636744488f6259d0cdb2179f0

authored by

mojyack and committed by
Solomon Peachy
350a2250 f13f80c5

+571 -706
+16 -20
firmware/drivers/isp1583.c
··· 29 29 #include "logf.h" 30 30 #include "stdio.h" 31 31 32 + struct usb_drv_ep_spec usb_drv_ep_specs[USB_NUM_ENDPOINTS]; /* filled in usb_drv_init */ 33 + uint8_t usb_drv_ep_specs_flags = 0; 34 + 32 35 struct usb_endpoint 33 36 { 34 37 unsigned char *out_buf; ··· 48 51 unsigned char enabled[2]; 49 52 short max_pkt_size[2]; 50 53 short type; 51 - char allocation; 52 54 }; 53 55 54 56 static unsigned char setup_pkt_buf[8]; ··· 470 472 471 473 //tick_add_task(usb_helper); 472 474 475 + /* Fill endpoint spec table FIXME: should be done in usb_drv_startup() */ 476 + usb_drv_ep_specs[0].type[DIR_OUT] = USB_ENDPOINT_XFER_CONTROL; 477 + usb_drv_ep_specs[0].type[DIR_IN] = USB_ENDPOINT_XFER_CONTROL; 478 + for(int i = 1; i < USB_NUM_ENDPOINTS; i += 1) { 479 + usb_drv_ep_specs[i].type[DIR_OUT] = USB_ENDPOINT_XFER_BULK; 480 + usb_drv_ep_specs[i].type[DIR_IN] = USB_ENDPOINT_XFER_BULK; 481 + } 482 + 473 483 logf("usb_init_device() finished"); 474 484 } 475 485 ··· 616 626 endpoints[i].halt[0] = endpoints[i].halt[1] = 1; 617 627 } 618 628 619 - int usb_drv_request_endpoint(int type, int dir) 629 + int usb_drv_init_endpoint(int endpoint, int type, int max_packet_size) 620 630 { 621 - int i, bit; 622 - 623 - if (type != USB_ENDPOINT_XFER_BULK) 624 - return -1; 625 - 626 - bit=(dir & USB_DIR_IN)? 2:1; 627 - 628 - for (i=1; i < USB_NUM_ENDPOINTS; i++) { 629 - if((endpoints[i].allocation & bit)!=0) 630 - continue; 631 - endpoints[i].allocation |= bit; 632 - return i | dir; 633 - } 634 - 635 - return -1; 631 + (void)max_packet_size; /* FIXME: support max packet size override */ 632 + return 0; 636 633 } 637 634 638 - void usb_drv_release_endpoint(int ep) 635 + int usb_drv_deinit_endpoint(int endpoint) 639 636 { 640 - int mask = (ep & USB_DIR_IN)? ~2:~1; 641 - endpoints[ep & 0x7f].allocation &= mask; 637 + return 0; 642 638 } 643 639 644 640 static void bus_reset(void)
+41 -47
firmware/drivers/m66591.c
··· 59 59 * stack visible functions. 60 60 ******************************************************************************/ 61 61 62 + struct usb_drv_ep_spec usb_drv_ep_specs[USB_NUM_ENDPOINTS]; /* filled in usb_drv_init */ 63 + uint8_t usb_drv_ep_specs_flags = USB_ENDPOINT_SPEC_IO_EXCLUSIVE; 64 + 62 65 static volatile unsigned short * pipe_ctrl_addr(int pipe); 63 66 static void pipe_handshake(int pipe, int handshake); 64 67 static void pipe_c_select (int pipe, bool dir); ··· 78 81 int length; /* how match data will fit */ 79 82 volatile int count; /* actual data count */ 80 83 bool waiting; /* is there data to transfer? */ 81 - bool busy; /* has the pipe been requested for use? */ 82 84 } ; 83 85 84 86 static struct M66591_epstat M66591_eps[USB_NUM_ENDPOINTS]; ··· 638 640 M66591_TESTMODE |= mode; 639 641 } 640 642 641 - /* Request an unused endpoint */ 642 - int usb_drv_request_endpoint(int type, int dir) { 643 - int ep; 644 - int pipecfg = 0; 643 + int usb_drv_init_endpoint(int endpoint, int type, int max_packet_size) { 644 + (void)max_packet_size; /* FIXME: support max packet size override */ 645 + 646 + int pipecfg; 645 647 646 - if (type == USB_ENDPOINT_XFER_BULK) { 648 + if(type == USB_ENDPOINT_XFER_BULK) { 647 649 /* Enable double buffer mode (only used for ep 1 and 2) */ 648 650 pipecfg |= 1<<9 | 1<<8; 649 - 650 - /* Bulk endpoints must be between 1 and 4 inclusive */ 651 - ep=1; 652 - 653 - while(M66591_eps[ep].busy && ep++<5); 654 - 655 - /* If this reached 5 the endpoints were all busy */ 656 - if(ep==5) { 657 - logf("mxx: ep %d busy", ep); 658 - return -1; 659 - } 660 - } else if (type == USB_ENDPOINT_XFER_INT) { 661 - ep=5; 662 - 651 + } else if(type == USB_ENDPOINT_XFER_BULK) { 663 652 pipecfg |= 1<<13; 664 - 665 - while(M66591_eps[ep].busy && ++ep<USB_NUM_ENDPOINTS); 666 - 667 - /* If this reached USB_NUM_ENDPOINTS the endpoints were all busy */ 668 - if(ep==USB_NUM_ENDPOINTS) { 669 - logf("mxx: ep %d busy", ep); 670 - return -1; 671 - } 672 653 } else { 673 654 /* Not a supported type */ 674 655 return -1; 675 656 } 676 657 658 + int num = endpoint & USB_ENDPOINT_NUMBER_MASK; 659 + int dir = endpoint & USB_ENDPOINT_DIR_MASK; 677 660 if (dir == USB_DIR_IN) { 678 661 pipecfg |= (1<<4); 679 662 } 680 - 681 - M66591_eps[ep].busy = true; 682 - M66591_eps[ep].dir = dir; 683 - 684 - M66591_PIPE_CFGSEL=ep; 663 + 664 + M66591_eps[num].dir = dir; 685 665 666 + M66591_PIPE_CFGSEL=num; 667 + 686 668 /* Enable pipe (15) */ 687 669 pipecfg |= 1<<15; 688 670 689 - pipe_handshake(ep, PIPE_SHAKE_NAK); 671 + pipe_handshake(num, PIPE_SHAKE_NAK); 690 672 691 673 /* Setup the flags */ 692 674 M66591_PIPE_CFGWND=pipecfg; 693 675 694 - pipe_init(ep); 676 + pipe_init(num); 695 677 696 - logf("mxx: ep req ep#: %d config: 0x%04x", ep, M66591_PIPE_CFGWND); 678 + logf("mxx: ep req ep#: %d config: 0x%04x", num, M66591_PIPE_CFGWND); 697 679 698 - return ep | dir; 680 + return 0; 699 681 } 700 682 701 683 /* Used by stack to tell the helper functions that the pipe is not in use */ 702 - void usb_drv_release_endpoint(int ep) { 703 - int flags; 704 - ep &= 0x7f; 684 + int usb_drv_deinit_endpoint(int endpoint) { 685 + int num = endpoint & USB_ENDPOINT_NUMBER_MASK; 705 686 706 - if (ep < 1 || ep > USB_NUM_ENDPOINTS || M66591_eps[ep].busy == false) 707 - return ; 687 + if (num < 1 || num > USB_NUM_ENDPOINTS) { 688 + return -1; 689 + } 708 690 709 - flags = disable_irq_save(); 691 + int flags = disable_irq_save(); 710 692 711 - logf("mxx: ep %d release", ep); 693 + logf("mxx: ep %d release", num); 712 694 713 - M66591_eps[ep].busy = false; 714 - M66591_eps[ep].dir = -1; 695 + M66591_eps[num].dir = -1; 715 696 716 697 restore_irq(flags); 698 + 699 + return 0; 717 700 } 718 701 719 702 /* Periodically called to check if a cable was plugged into the device */ ··· 744 727 M66591_TRN_CTRL |=0x0001; 745 728 746 729 M66591_INTCFG_MAIN |=0x8000; /* Enable VBUS interrupt */ 730 + 731 + /* Fill endpoint spec table FIXME: should be done in usb_drv_startup() */ 732 + usb_drv_ep_specs[0].type[DIR_OUT] = USB_ENDPOINT_XFER_CONTROL; 733 + usb_drv_ep_specs[0].type[DIR_IN] = USB_ENDPOINT_XFER_CONTROL; 734 + for(int i = 1; i < 5; i += 1) { 735 + usb_drv_ep_specs[i].type[DIR_OUT] = USB_ENDPOINT_XFER_BULK; 736 + usb_drv_ep_specs[i].type[DIR_IN] = USB_ENDPOINT_XFER_BULK; 737 + } 738 + for(int i = 5; i < USB_NUM_ENDPOINTS; i += 1) { 739 + usb_drv_ep_specs[i].type[DIR_OUT] = USB_ENDPOINT_XFER_INT; 740 + usb_drv_ep_specs[i].type[DIR_IN] = USB_ENDPOINT_XFER_INT; 741 + } 747 742 } 748 743 749 744 /* fully enable driver */ ··· 757 752 M66591_eps[i].length = 0; 758 753 M66591_eps[i].count = 0; 759 754 M66591_eps[i].waiting = false; 760 - M66591_eps[i].busy = false; 761 755 } 762 756 763 757 /* Issue a h/w reset */
+47 -39
firmware/drivers/usb-designware.c
··· 144 144 struct usb_ctrlrequest pending_req; 145 145 }; 146 146 147 + struct usb_drv_ep_spec usb_drv_ep_specs[USB_NUM_ENDPOINTS]; /* filled in usb_drv_init */ 148 + uint8_t usb_drv_ep_specs_flags = 0; 149 + 147 150 static const char* const dw_dir_str[USB_DW_NUM_DIRS] = 148 151 { 149 152 [USB_DW_EPDIR_IN] = "IN", ··· 1495 1498 /* Soft reconnect */ 1496 1499 udelay(3000); 1497 1500 DWC_DCTL &= ~SDIS; 1501 + 1502 + /* Fill endpoint spec table FIXME: should be done in usb_drv_startup() */ 1503 + usb_drv_ep_specs[0].type[DIR_OUT] = USB_ENDPOINT_XFER_CONTROL; 1504 + usb_drv_ep_specs[0].type[DIR_IN] = USB_ENDPOINT_XFER_CONTROL; 1505 + for(int i = 1; i < USB_NUM_ENDPOINTS; i += 1) { 1506 + bool out_avail = usb_endpoints & (1 << (i + USB_DW_DIR_OFF(USB_DW_EPDIR_OUT))); 1507 + usb_drv_ep_specs[i].type[DIR_OUT] = out_avail ? USB_ENDPOINT_TYPE_ANY : USB_ENDPOINT_TYPE_NONE; 1508 + 1509 + bool in_avail = usb_endpoints & (1 << (i + USB_DW_DIR_OFF(USB_DW_EPDIR_IN))); 1510 + usb_drv_ep_specs[i].type[DIR_IN] = in_avail ? USB_ENDPOINT_TYPE_ANY : USB_ENDPOINT_TYPE_NONE; 1511 + } 1498 1512 } 1499 1513 1500 1514 static void usb_dw_exit(void) ··· 1592 1606 usb_dw_irq(); 1593 1607 } 1594 1608 1595 - int usb_drv_request_endpoint(int type, int dir) 1609 + int usb_drv_init_endpoint(int endpoint, int type, int max_packet_size) 1596 1610 { 1597 - int request_ep = -1; 1598 - enum usb_dw_epdir epdir = (EP_DIR(dir) == DIR_IN) ? 1599 - USB_DW_EPDIR_IN : USB_DW_EPDIR_OUT; 1611 + (void)max_packet_size; /* FIXME: support max packet size override */ 1600 1612 1601 - usb_dw_target_disable_irq(); 1602 - for (int ep = 1; ep < USB_NUM_ENDPOINTS; ep++) 1603 - { 1604 - if (usb_endpoints & (1 << (ep + USB_DW_DIR_OFF(epdir)))) 1605 - { 1606 - struct usb_dw_ep* dw_ep = usb_dw_get_ep(ep, epdir); 1607 - if (!dw_ep->active) 1608 - { 1609 - int maxpktsize = 64; 1610 - if (type == EPTYP_ISOCHRONOUS){ 1611 - maxpktsize = 1023; 1612 - } else { 1613 - maxpktsize = usb_drv_port_speed() ? 512 : 64; 1614 - } 1613 + enum usb_dw_epdir epdir = (EP_DIR(endpoint) == DIR_IN) ? USB_DW_EPDIR_IN : USB_DW_EPDIR_OUT; 1614 + struct usb_dw_ep* dw_ep = usb_dw_get_ep(EP_NUM(endpoint), epdir); 1615 1615 1616 - if (usb_dw_configure_ep(ep, epdir, type, 1617 - maxpktsize) >= 0) 1618 - { 1619 - dw_ep->active = true; 1620 - request_ep = ep | dir; 1621 - } 1622 - break; 1623 - } 1624 - } 1616 + int maxpktsize; 1617 + if(type == EPTYP_ISOCHRONOUS) 1618 + { 1619 + maxpktsize = 1023; 1625 1620 } 1621 + else 1622 + { 1623 + maxpktsize = usb_drv_port_speed() ? 512 : 64; 1624 + } 1625 + 1626 + usb_dw_target_disable_irq(); 1627 + int res = usb_dw_configure_ep(EP_NUM(endpoint), epdir, type, maxpktsize); 1626 1628 usb_dw_target_enable_irq(); 1627 - return request_ep; 1629 + 1630 + if(res >= 0) 1631 + { 1632 + dw_ep->active = true; 1633 + return 0; 1634 + } 1635 + else 1636 + { 1637 + return -1; 1638 + } 1628 1639 } 1629 1640 1630 - void usb_drv_release_endpoint(int endpoint) 1641 + int usb_drv_deinit_endpoint(int endpoint) 1631 1642 { 1632 - int epnum = EP_NUM(endpoint); 1633 - if (!epnum) return; 1634 - enum usb_dw_epdir epdir = (EP_DIR(endpoint) == DIR_IN) ? 1635 - USB_DW_EPDIR_IN : USB_DW_EPDIR_OUT; 1636 - struct usb_dw_ep* dw_ep = usb_dw_get_ep(epnum, epdir); 1643 + enum usb_dw_epdir epdir = (EP_DIR(endpoint) == DIR_IN) ? USB_DW_EPDIR_IN : USB_DW_EPDIR_OUT; 1644 + struct usb_dw_ep* dw_ep = usb_dw_get_ep(EP_NUM(endpoint), epdir); 1637 1645 1638 1646 usb_dw_target_disable_irq(); 1639 - if (dw_ep->active) 1640 - { 1641 - usb_dw_unconfigure_ep(epnum, epdir); 1642 - dw_ep->active = false; 1643 - } 1647 + usb_dw_unconfigure_ep(EP_NUM(endpoint), epdir); 1644 1648 usb_dw_target_enable_irq(); 1649 + 1650 + dw_ep->active = false; 1651 + 1652 + return 0; 1645 1653 } 1646 1654 1647 1655 int usb_drv_recv_nonblocking(int endpoint, void* ptr, int length)
-3
firmware/export/usb_core.h
··· 66 66 void usb_core_notify_set_address(uint8_t addr); 67 67 void usb_core_notify_set_config(uint8_t config); 68 68 69 - int usb_core_request_endpoint(int type, int dir,struct usb_class_driver* drv); 70 - void usb_core_release_endpoint(int dir); 71 - 72 69 #ifdef HAVE_HOTSWAP 73 70 void usb_core_hotswap_event(int volume,bool inserted); 74 71 #endif
+15 -2
firmware/export/usb_drv.h
··· 62 62 USB_CONTROL_RECEIVE, 63 63 }; 64 64 65 + #define USB_ENDPOINT_TYPE_ANY (-1) 66 + #define USB_ENDPOINT_TYPE_NONE (-2) 67 + 68 + struct usb_drv_ep_spec { 69 + int8_t type[2]; /* USB_ENDPOINT_TYPE_{ANY,NONE} USB_ENDPOINT_XFER_* */ 70 + }; 71 + 72 + extern struct usb_drv_ep_spec usb_drv_ep_specs[USB_NUM_ENDPOINTS]; 73 + 74 + #define USB_ENDPOINT_SPEC_FORCE_IO_TYPE_MATCH (1 << 0) 75 + #define USB_ENDPOINT_SPEC_IO_EXCLUSIVE (1 << 1) 76 + extern uint8_t usb_drv_ep_specs_flags; 77 + 65 78 /* one-time initialisation of the USB driver */ 66 79 void usb_drv_startup(void); 67 80 void usb_drv_int_enable(bool enable); /* Target implemented */ ··· 85 98 void usb_drv_cancel_all_transfers(void); 86 99 void usb_drv_set_test_mode(int mode); 87 100 bool usb_drv_connected(void); 88 - int usb_drv_request_endpoint(int type, int dir); 89 - void usb_drv_release_endpoint(int ep); 101 + int usb_drv_init_endpoint(int endpoint, int type, int max_packet_size); 102 + int usb_drv_deinit_endpoint(int endpoint); 90 103 #ifdef USB_HAS_ISOCHRONOUS 91 104 /* returns the last received frame number (the 11-bit number contained in the last SOF): 92 105 * - full-speed: the host sends one SOF every 1ms (so 1000 SOF/s)
+31 -57
firmware/target/arm/as3525/usb-drv-as3525.c
··· 36 36 37 37 #include "usb-drv-as3525.h" 38 38 39 + /* OUT EP 2 is an alias for OUT EP 0 on this HW! */ 40 + struct usb_drv_ep_spec usb_drv_ep_specs[USB_NUM_EPS] = { 41 + [0] = {USB_ENDPOINT_XFER_CONTROL, USB_ENDPOINT_XFER_CONTROL}, 42 + [1] = {USB_ENDPOINT_TYPE_ANY, USB_ENDPOINT_TYPE_ANY}, 43 + [2] = {USB_ENDPOINT_TYPE_NONE, USB_ENDPOINT_TYPE_ANY}, 44 + [3] = {USB_ENDPOINT_TYPE_ANY, USB_ENDPOINT_TYPE_ANY}, 45 + }; 46 + uint8_t usb_drv_ep_specs_flags = 0; 47 + 39 48 static struct usb_endpoint endpoints[USB_NUM_EPS][2]; 40 49 static int got_set_configuration = 0; 41 50 static int usb_enum_timeout = -1; ··· 154 163 static void reset_endpoints(int init) 155 164 { 156 165 int i; 157 - 158 - /* 159 - * OUT EP 2 is an alias for OUT EP 0 on this HW! 160 - * 161 - * Resonates with "3 bidirectional- plus 1 in-endpoints in device mode" 162 - * from the datasheet, but why ep2 and not ep3? 163 - * 164 - * Reserve it here so we will skip over it in request_endpoint(). 165 - */ 166 - endpoints[2][1].state |= EP_STATE_ALLOCATED; 167 166 168 167 for(i = 0; i < USB_NUM_EPS; i++) { 169 168 /* ··· 344 343 return (USB_DEV_STS & USB_DEV_STS_MASK_SPD) ? 0 : 1; 345 344 } 346 345 347 - int usb_drv_request_endpoint(int type, int dir) 348 - { 349 - int d = dir == USB_DIR_IN ? 0 : 1; 350 - int i = 1; /* skip the control EP */ 346 + int usb_drv_init_endpoint(int endpoint, int type, int max_packet_size) { 347 + (void)max_packet_size; 351 348 352 - for(; i < USB_NUM_EPS; i++) { 353 - if (endpoints[i][d].state & EP_STATE_ALLOCATED) 354 - continue; 355 - 356 - endpoints[i][d].state |= EP_STATE_ALLOCATED; 349 + int i = EP_NUM(endpoint); 350 + int d = EP_DIR(endpoint) == DIR_IN ? 0 : 1; 357 351 358 - if (dir == USB_DIR_IN) { 359 - USB_IEP_CTRL(i) = USB_EP_CTRL_FLUSH | 360 - USB_EP_CTRL_SNAK | 361 - USB_EP_CTRL_ACT | 362 - (type << 4); 363 - USB_DEV_EP_INTR_MASK &= ~(1<<i); 364 - } else { 365 - USB_OEP_CTRL(i) = USB_EP_CTRL_FLUSH | 366 - USB_EP_CTRL_SNAK | 367 - USB_EP_CTRL_ACT | 368 - (type << 4); 369 - USB_DEV_EP_INTR_MASK &= ~(1<<(16+i)); 370 - } 371 - /* logf("usb_drv_request_endpoint(%d, %d): returning %02x\n", type, dir, i | dir); */ 372 - return i | dir; 352 + if (EP_DIR(endpoint) == DIR_IN) { 353 + USB_IEP_CTRL(i) = USB_EP_CTRL_FLUSH | 354 + USB_EP_CTRL_SNAK | 355 + USB_EP_CTRL_ACT | 356 + (type << 4); 357 + USB_DEV_EP_INTR_MASK &= ~(1<<i); 358 + } else { 359 + USB_OEP_CTRL(i) = USB_EP_CTRL_FLUSH | 360 + USB_EP_CTRL_SNAK | 361 + USB_EP_CTRL_ACT | 362 + (type << 4); 363 + USB_DEV_EP_INTR_MASK &= ~(1<<(16+i)); 373 364 } 374 - 375 - logf("usb_drv_request_endpoint(%d, %d): no free endpoint found\n", type, dir); 376 - return -1; 365 + return 0; 377 366 } 378 367 379 - void usb_drv_release_endpoint(int ep) 380 - { 381 - int i = ep & 0x7f; 382 - int d = ep & USB_DIR_IN ? 0 : 1; 383 - 384 - if (i >= USB_NUM_EPS) 385 - return; 386 - /* 387 - * Check for control EP and ignore it. 388 - * Unfortunately the usb core calls 389 - * usb_drv_release_endpoint() for ep=0..(USB_NUM_ENDPOINTS-1), 390 - * but doesn't request a new control EP after that... 391 - */ 392 - if (i == 0 || /* Don't mask control EP */ 393 - (i == 2 && d == 1)) /* See reset_endpoints(), EP2_OUT == EP0_OUT */ 394 - return; 368 + int usb_drv_deinit_endpoint(int endpoint) { 369 + int i = EP_NUM(endpoint); 370 + int d = EP_DIR(endpoint) == DIR_IN ? 0 : 1; 395 371 396 - if (!(endpoints[i][d].state & EP_STATE_ALLOCATED)) 397 - return; 398 - 399 - /* logf("usb_drv_release_endpoint(%d, %d)\n", i, d); */ 400 372 endpoints[i][d].state = 0; 401 373 USB_DEV_EP_INTR_MASK |= (1<<(16*d+i)); 402 374 USB_EP_CTRL(i, !d) = USB_EP_CTRL_FLUSH | USB_EP_CTRL_SNAK; 375 + 376 + return 0; 403 377 } 404 378 405 379 void usb_drv_cancel_all_transfers(void)
+31 -30
firmware/target/arm/rk27xx/usb-drv-rk27xx.c
··· 53 53 const int type; /* EP type */ 54 54 const int dir; /* DIR_IN/DIR_OUT */ 55 55 volatile unsigned long *stat; /* RXSTAT/TXSTAT register */ 56 - bool allocated; /* flag to mark EPs taken */ 57 56 volatile void *buf; /* tx/rx buffer address */ 58 57 volatile int len; /* size of the transfer (bytes) */ 59 58 volatile int cnt; /* number of bytes transfered/received */ ··· 101 100 ENDPOINT(14, BULK, IN, &TX14STAT), /* BIN14 */ 102 101 ENDPOINT(15, INT, IN, &TX15STAT), /* IIN15 */ 103 102 }; 103 + 104 + struct usb_drv_ep_spec usb_drv_ep_specs[16]; /* filled in usb_drv_startup */ 105 + uint8_t usb_drv_ep_specs_flags = 0; 104 106 105 107 static volatile bool set_address = false; 106 108 static volatile bool set_configuration = false; ··· 260 262 } 261 263 } 262 264 265 + void usb_drv_startup(void) { 266 + /* fill the endpoint spec table */ 267 + usb_drv_ep_specs[0].type[DIR_OUT] = USB_ENDPOINT_XFER_CONTROL; 268 + usb_drv_ep_specs[0].type[DIR_IN] = USB_ENDPOINT_XFER_CONTROL; 269 + for(int ep_num = 1; ep_num < 16; ep_num++) { 270 + int dir = endpoints[ep_num].dir; 271 + int type = endpoints[ep_num].type; 272 + usb_drv_ep_specs[ep_num].type[dir] = type; 273 + usb_drv_ep_specs[ep_num].type[!dir] = USB_ENDPOINT_TYPE_NONE; 274 + } 275 + } 276 + 263 277 /* return port speed FS=0, HS=1 */ 264 278 int usb_drv_port_speed(void) 265 279 { 266 280 return (DEV_INFO & DEV_SPEED) ? 0 : 1; 267 281 } 268 282 269 - /* Reserve endpoint */ 270 - int usb_drv_request_endpoint(int type, int dir) 271 - { 272 - logf("req: %s %s", XFER_DIR_STR(dir), XFER_TYPE_STR(type)); 283 + int usb_drv_init_endpoint(int endpoint, int type, int max_packet_size) { 284 + (void)max_packet_size; /* FIXME: support max packet size override */ 285 + 286 + int num = EP_NUM(endpoint); 287 + int dir = EP_DIR(endpoint); 273 288 274 - /* Find an available ep/dir pair */ 275 - for(int ep_num = 1; ep_num<USB_NUM_ENDPOINTS;ep_num++) 276 - { 277 - struct endpoint_t *endp = &endpoints[ep_num]; 289 + struct endpoint_t *endp = &endpoints[num]; 278 290 279 - if(endp->allocated || endp->type != type || endp->dir != dir) 280 - continue; 281 - /* allocate endpoint and enable interrupt */ 282 - endp->allocated = true; 283 - if(dir == USB_DIR_IN) 284 - TXCON(endp) = (ep_num << 8) | TXEPEN | TXNAK | TXACKINTEN | TXCFINTE; 285 - else 286 - RXCON(endp) = (ep_num << 8) | RXEPEN | RXNAK | RXACKINTEN | RXCFINTE | RXERRINTEN; 287 - EN_INT |= 1 << (ep_num + 7); 291 + if(EP_DIR(endpoint) == DIR_IN) 292 + TXCON(endp) = (num << 8) | TXEPEN | TXNAK | TXACKINTEN | TXCFINTE; 293 + else 294 + RXCON(endp) = (num << 8) | RXEPEN | RXNAK | RXACKINTEN | RXCFINTE | RXERRINTEN; 295 + EN_INT |= 1 << (num + 7); 288 296 289 - logf("add: ep%d %s", ep_num, XFER_DIR_STR(dir)); 290 - return ep_num | dir; 291 - } 292 - return -1; 297 + return 0; 293 298 } 294 299 295 - /* Free endpoint */ 296 - void usb_drv_release_endpoint(int ep) 297 - { 298 - int ep_num = EP_NUM(ep); 299 - 300 - logf("rel: ep%d", ep_num); 301 - endpoints[ep_num].allocated = false; 300 + int usb_drv_deinit_endpoint(int endpoint) { 301 + int num = EP_NUM(endpoint); 302 + struct endpoint_t *endp = &endpoints[num]; 302 303 303 304 /* disable interrupt from this endpoint */ 304 - EN_INT &= ~(1 << (ep_num + 7)); 305 + EN_INT &= ~(1 << (num + 7)); 305 306 } 306 307 307 308 /* Set the address (usually it's in a register).
+2
firmware/target/arm/rk27xx/usb-rk27xx.c
··· 46 46 /* configure INTCON */ 47 47 INTCON = UDC_INTHIGH_ACT | /* interrupt high active */ 48 48 UDC_INTEN; /* enable EP0 interrupts */ 49 + 50 + usb_drv_startup(); 49 51 } 50 52 51 53 void usb_attach(void)
+24 -39
firmware/target/arm/tms320dm320/sansa-connect/tnetv105_usb_drv.c
··· 60 60 61 61 static cppi_info cppi; 62 62 63 + struct usb_drv_ep_spec usb_drv_ep_specs[USB_NUM_ENDPOINTS]; /* filled in usb_drv_startup */ 64 + uint8_t usb_drv_ep_specs_flags = 0; 65 + 63 66 static struct ep_runtime_t 64 67 { 65 68 int max_packet_size; 66 - bool in_allocated; 67 - bool out_allocated; 68 69 uint8_t *rx_buf; /* OUT */ 69 70 int rx_remaining; 70 71 int rx_size; ··· 1239 1240 } 1240 1241 } 1241 1242 1243 + void usb_drv_startup(void) 1244 + { 1245 + /* fill the endpoint spec table */ 1246 + usb_drv_ep_specs[0].type[DIR_OUT] = USB_ENDPOINT_XFER_CONTROL; 1247 + usb_drv_ep_specs[0].type[DIR_IN] = USB_ENDPOINT_XFER_CONTROL; 1248 + for(int i = 1; i < USB_NUM_ENDPOINTS; i += 1) { 1249 + usb_drv_ep_specs[i].type[DIR_OUT] = ep_const_data[i].type; 1250 + usb_drv_ep_specs[i].type[DIR_IN] = ep_const_data[i].type; 1251 + } 1252 + } 1253 + 1242 1254 void usb_drv_init(void) 1243 1255 { 1244 1256 int epn; 1245 1257 memset(ep_runtime, 0, sizeof(ep_runtime)); 1246 1258 ep_runtime[0].max_packet_size = EP0_MAX_PACKET_SIZE; 1247 - ep_runtime[0].in_allocated = true; 1248 - ep_runtime[0].out_allocated = true; 1249 1259 for (epn = 0; epn < USB_NUM_ENDPOINTS; epn++) 1250 1260 { 1251 1261 semaphore_init(&ep_runtime[epn].complete, 1, 0); ··· 1479 1489 tnetv_usb_reg_write(TNETV_USB_CTRL, usbCtrl.val); 1480 1490 } 1481 1491 1482 - int usb_drv_request_endpoint(int type, int dir) 1483 - { 1484 - int epn; 1485 - for (epn = 1; epn < USB_NUM_ENDPOINTS; epn++) 1486 - { 1487 - if (type == ep_const_data[epn].type) 1488 - { 1489 - if ((dir == USB_DIR_IN) && (!ep_runtime[epn].in_allocated)) 1490 - { 1491 - ep_runtime[epn].in_allocated = true; 1492 - tnetv_gadget_ep_enable(epn, true); 1493 - return epn | USB_DIR_IN; 1494 - } 1495 - if ((dir == USB_DIR_OUT) && (!ep_runtime[epn].out_allocated)) 1496 - { 1497 - ep_runtime[epn].out_allocated = true; 1498 - tnetv_gadget_ep_enable(epn, false); 1499 - return epn | USB_DIR_OUT; 1500 - } 1501 - } 1502 - } 1503 - return -1; 1492 + int usb_drv_init_endpoint(int endpoint, int type, int max_packet_size) { 1493 + (void)max_packet_size; /* FIXME: support max packet size override */ 1494 + 1495 + int num = EP_NUM(endpoint); 1496 + int dir = EP_DIR(endpoint); 1497 + return tnetv_gadget_ep_enable(num, dir == EP_IN); 1504 1498 } 1505 1499 1506 - void usb_drv_release_endpoint(int ep) 1507 - { 1508 - int epn = EP_NUM(ep); 1509 - if (EP_DIR(ep) == DIR_IN) 1510 - { 1511 - ep_runtime[epn].in_allocated = false; 1512 - tnetv_gadget_ep_disable(epn, true); 1513 - } 1514 - else 1515 - { 1516 - ep_runtime[epn].out_allocated = false; 1517 - tnetv_gadget_ep_disable(epn, false); 1518 - } 1500 + int usb_drv_deinit_endpoint(int endpoint) { 1501 + int num = EP_NUM(endpoint); 1502 + int dir = EP_DIR(endpoint); 1503 + return tnetv_gadget_ep_disable(num, dir == EP_IN); 1519 1504 }
+3
firmware/target/arm/tms320dm320/sansa-connect/usb-sansaconnect.c
··· 23 23 #include "system.h" 24 24 #include "kernel.h" 25 25 #include "usb_core.h" 26 + #include "usb_drv.h" 26 27 27 28 static int usb_detect_callback(struct timeout *tmo) 28 29 { ··· 82 83 83 84 /* Enable USB insert detection interrupt */ 84 85 IO_INTC_EINT1 |= (1 << 14); 86 + 87 + usb_drv_startup(); 85 88 } 86 89 87 90 void usb_enable(bool on)
+58 -111
firmware/target/arm/usb-drv-arc.c
··· 308 308 transfer size, so it seems like a good size */ 309 309 #define NUM_TDS_PER_EP 4 310 310 311 - typedef struct usb_endpoint 312 - { 313 - bool allocated[2]; 314 - short type[2]; 315 - short max_pkt_size[2]; 316 - } usb_endpoint_t; 317 - static usb_endpoint_t endpoints[USB_NUM_ENDPOINTS]; 311 + struct usb_drv_ep_spec usb_drv_ep_specs[USB_NUM_ENDPOINTS]; /* filled in usb_drv_startup */ 312 + uint8_t usb_drv_ep_specs_flags = USB_ENDPOINT_SPEC_FORCE_IO_TYPE_MATCH; 318 313 319 314 /* manual: 32.13.2 Endpoint Transfer Descriptor (dTD) */ 320 315 struct transfer_descriptor { ··· 372 367 struct transfer_descriptor* previous_td, void *ptr, int len,int pipe); 373 368 static void bus_reset(void); 374 369 static void init_control_queue_heads(void); 375 - static void init_queue_heads(void); 376 - static void init_endpoints(void); 377 370 /*-------------------------------------------------------------------------*/ 378 371 static void usb_drv_stop(void) 379 372 { ··· 430 423 for(i=0;i<USB_NUM_ENDPOINTS*2;i++) { 431 424 semaphore_init(&transfer_completion_signal[i], 1, 0); 432 425 } 426 + 427 + /* Fill the endpoint spec table */ 428 + usb_drv_ep_specs[0].type[DIR_OUT] = USB_ENDPOINT_XFER_CONTROL; 429 + usb_drv_ep_specs[0].type[DIR_IN] = USB_ENDPOINT_XFER_CONTROL; 430 + for(int i = 1; i < USB_NUM_ENDPOINTS; i += 1) { 431 + usb_drv_ep_specs[i].type[DIR_OUT] = USB_ENDPOINT_TYPE_ANY; 432 + usb_drv_ep_specs[i].type[DIR_IN] = USB_ENDPOINT_TYPE_ANY; 433 + } 433 434 } 434 435 435 436 #ifdef LOGF_ENABLE ··· 439 440 ((type) == USB_ENDPOINT_XFER_ISOC ? "ISOC" : \ 440 441 ((type) == USB_ENDPOINT_XFER_BULK ? "BULK" : \ 441 442 ((type) == USB_ENDPOINT_XFER_INT ? "INTR" : "INVL")))) 442 - 443 - static void log_ep(int ep_num, int ep_dir, char* prefix) 444 - { 445 - usb_endpoint_t* endpoint = &endpoints[ep_num]; 446 - 447 - logf("%s: ep%d %s %s %d", prefix, ep_num, XFER_DIR_STR(ep_dir), 448 - XFER_TYPE_STR(endpoint->type[ep_dir]), 449 - endpoint->max_pkt_size[ep_dir]); 450 - } 451 - #else 452 - #undef log_ep 453 - #define log_ep(...) 454 443 #endif 455 444 456 445 /* manual: 32.14.1 Device Controller Initialization */ ··· 491 480 logf("usb dccparams %x", REG_DCCPARAMS); 492 481 493 482 /* now a bus reset will occur. see bus_reset() */ 483 + 484 + /* manual: 32.9.5.18 (Caution): Leaving an unconfigured endpoint control 485 + * will cause undefined behavior for the data pid tracking on the active 486 + * endpoint/direction. */ 487 + for(int ep_num=1;ep_num<USB_NUM_ENDPOINTS;ep_num++) { 488 + usb_drv_init_endpoint(ep_num | USB_DIR_IN, USB_ENDPOINT_XFER_BULK, -1); 489 + usb_drv_init_endpoint(ep_num | USB_DIR_OUT, USB_ENDPOINT_XFER_BULK, -1); 490 + } 494 491 } 495 492 496 493 void usb_drv_exit(void) ··· 631 628 void usb_drv_set_address(int address) 632 629 { 633 630 REG_DEVICEADDR = address << USBDEVICEADDRESS_BIT_POS; 634 - init_queue_heads(); 635 - init_endpoints(); 636 631 } 637 632 638 633 void usb_drv_reset_endpoint(int endpoint, bool send) ··· 797 792 } 798 793 } 799 794 800 - int usb_drv_request_endpoint(int type, int dir) 801 - { 802 - int ep_num, ep_dir; 803 - short ep_type; 795 + int usb_drv_init_endpoint(int endpoint, int type, int max_packet_size) { 796 + int ep_num = EP_NUM(endpoint); 797 + int ep_dir = EP_DIR(endpoint); 804 798 805 - /* Safety */ 806 - ep_dir = EP_DIR(dir); 807 - ep_type = type & USB_ENDPOINT_XFERTYPE_MASK; 799 + logf("ep init: %d %s %s", ep_num, XFER_DIR_STR(ep_dir), XFER_TYPE_STR(type)); 808 800 809 - logf("req: %s %s", XFER_DIR_STR(ep_dir), XFER_TYPE_STR(ep_type)); 801 + struct queue_head* qh; 802 + unsigned int ctrl = REG_ENDPTCTRL(ep_num); 803 + if(ep_dir == DIR_IN) { 804 + ctrl &= ~EPCTRL_TX_TYPE; 805 + ctrl |= EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE | type << EPCTRL_TX_EP_TYPE_SHIFT; 806 + qh = &qh_array[ep_num * 2 + 1]; 807 + } else { 808 + ctrl &= ~EPCTRL_RX_TYPE; 809 + ctrl |= EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE | type << EPCTRL_RX_EP_TYPE_SHIFT; 810 + qh = &qh_array[ep_num * 2]; 811 + } 812 + REG_ENDPTCTRL(ep_num) = ctrl; 810 813 811 - /* Find an available ep/dir pair */ 812 - for (ep_num=1;ep_num<USB_NUM_ENDPOINTS;ep_num++) { 813 - usb_endpoint_t* endpoint=&endpoints[ep_num]; 814 - int other_dir=(ep_dir ? 0:1); 814 + if(max_packet_size == -1) { 815 + if(type == USB_ENDPOINT_XFER_ISOC) { 816 + max_packet_size = 1024; 817 + } else { 818 + max_packet_size = usb_drv_port_speed() ? 512 : 64; 819 + } 820 + } 821 + if(type == USB_ENDPOINT_XFER_ISOC) 822 + /* FIXME: we can adjust the number of packets per frame, currently use one */ 823 + qh->max_pkt_length = max_packet_size << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL | 1 << QH_MULT_POS; 824 + else 825 + qh->max_pkt_length = max_packet_size << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; 815 826 816 - if (endpoint->allocated[ep_dir]) 817 - continue; 827 + qh->dtd.next_td_ptr = QH_NEXT_TERMINATE; 818 828 819 - if (endpoint->allocated[other_dir] && 820 - endpoint->type[other_dir] != ep_type) { 821 - logf("ep of different type!"); 822 - continue; 823 - } 829 + return 0; 830 + } 824 831 832 + int usb_drv_deinit_endpoint(int endpoint) { 833 + int ep_num = EP_NUM(endpoint); 834 + int ep_dir = EP_DIR(endpoint); 825 835 826 - endpoint->allocated[ep_dir] = 1; 827 - endpoint->type[ep_dir] = ep_type; 836 + logf("ep deinit: %d %s", ep_num, XFER_DIR_STR(ep_dir)); 828 837 829 - log_ep(ep_num, ep_dir, "add"); 830 - return (ep_num | (dir & USB_ENDPOINT_DIR_MASK)); 838 + if(ep_dir == DIR_IN) { 839 + REG_ENDPTCTRL(ep_num) &= ~EPCTRL_TX_ENABLE & ~EPCTRL_TX_TYPE; 840 + } else { 841 + REG_ENDPTCTRL(ep_num) &= ~EPCTRL_RX_ENABLE & ~EPCTRL_RX_TYPE; 831 842 } 832 843 833 - return -1; 844 + return 0; 834 845 } 835 - 836 - void usb_drv_release_endpoint(int ep) 837 - { 838 - int ep_num = EP_NUM(ep); 839 - int ep_dir = EP_DIR(ep); 840 - 841 - log_ep(ep_num, ep_dir, "rel"); 842 - endpoints[ep_num].allocated[ep_dir] = 0; 843 - } 844 - 845 846 846 847 static void prepare_td(struct transfer_descriptor* td, 847 848 struct transfer_descriptor* previous_td, ··· 978 979 qh_array[EP_CONTROL+1].max_pkt_length = 64 << QH_MAX_PKT_LEN_POS; 979 980 qh_array[EP_CONTROL+1].dtd.next_td_ptr = QH_NEXT_TERMINATE; 980 981 } 981 - /* manual: 32.14.4.1 Queue Head Initialization */ 982 - static void init_queue_heads(void) 983 - { 984 - int packetsize = (usb_drv_port_speed() ? 512 : 64); 985 - int isopacketsize = (usb_drv_port_speed() ? 1024 : 1024); 986 - int i; 987 - 988 - /* TODO: this should take ep_allocation into account */ 989 - for (i=1;i<USB_NUM_ENDPOINTS;i++) { 990 - 991 - /* OUT */ 992 - if(endpoints[i].type[DIR_OUT] == USB_ENDPOINT_XFER_ISOC) 993 - /* FIXME: we can adjust the number of packets per frame, currently use one */ 994 - qh_array[i*2].max_pkt_length = isopacketsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL | 1 << QH_MULT_POS; 995 - else 996 - qh_array[i*2].max_pkt_length = packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; 997 - 998 - qh_array[i*2].dtd.next_td_ptr = QH_NEXT_TERMINATE; 999 - 1000 - /* IN */ 1001 - if(endpoints[i].type[DIR_IN] == USB_ENDPOINT_XFER_ISOC) 1002 - /* FIXME: we can adjust the number of packets per frame, currently use one */ 1003 - qh_array[i*2+1].max_pkt_length = isopacketsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL | 1 << QH_MULT_POS; 1004 - else 1005 - qh_array[i*2+1].max_pkt_length = packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; 1006 - 1007 - qh_array[i*2+1].dtd.next_td_ptr = QH_NEXT_TERMINATE; 1008 - } 1009 - } 1010 - 1011 - static void init_endpoints(void) 1012 - { 1013 - int ep_num; 1014 - 1015 - logf("init_endpoints"); 1016 - /* RX/TX from the device POV: OUT/IN, respectively */ 1017 - for(ep_num=1;ep_num<USB_NUM_ENDPOINTS;ep_num++) { 1018 - usb_endpoint_t *endpoint = &endpoints[ep_num]; 1019 - 1020 - /* manual: 32.9.5.18 (Caution): Leaving an unconfigured endpoint control 1021 - * will cause undefined behavior for the data pid tracking on the active 1022 - * endpoint/direction. */ 1023 - if (!endpoint->allocated[DIR_OUT]) 1024 - endpoint->type[DIR_OUT] = USB_ENDPOINT_XFER_BULK; 1025 - if (!endpoint->allocated[DIR_IN]) 1026 - endpoint->type[DIR_IN] = USB_ENDPOINT_XFER_BULK; 1027 - 1028 - REG_ENDPTCTRL(ep_num) = 1029 - EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE | 1030 - EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE | 1031 - (endpoint->type[DIR_OUT] << EPCTRL_RX_EP_TYPE_SHIFT) | 1032 - (endpoint->type[DIR_IN] << EPCTRL_TX_EP_TYPE_SHIFT); 1033 - } 1034 - }
+20 -22
firmware/target/arm/usb-s3c6400x.c
··· 59 59 unsigned int size; /* length of the data buffer */ 60 60 struct semaphore complete; /* wait object */ 61 61 int8_t status; /* completion status (0 for success) */ 62 - bool active; /* true is endpoint has been requested (true for EP0) */ 63 62 bool done; /* transfer completed */ 64 63 bool busy; /* true is a transfer is pending */ 65 64 }; 66 65 67 66 static const uint8_t in_ep_list[] = {0, 1, 3, 5}; 68 67 static const uint8_t out_ep_list[] = {0, 2, 4}; 68 + 69 + struct usb_drv_ep_spec usb_drv_ep_specs[USB_NUM_ENDPOINTS] = { 70 + {.type = {USB_ENDPOINT_XFER_CONTROL, USB_ENDPOINT_XFER_CONTROL}}, 71 + {.type = {USB_ENDPOINT_TYPE_NONE, USB_ENDPOINT_TYPE_ANY}}, 72 + {.type = {USB_ENDPOINT_TYPE_ANY, USB_ENDPOINT_TYPE_NONE}}, 73 + {.type = {USB_ENDPOINT_TYPE_NONE, USB_ENDPOINT_TYPE_ANY}}, 74 + {.type = {USB_ENDPOINT_TYPE_ANY, USB_ENDPOINT_TYPE_NONE}}, 75 + {.type = {USB_ENDPOINT_TYPE_NONE, USB_ENDPOINT_TYPE_ANY}}, 76 + }; 77 + uint8_t usb_drv_ep_specs_flags = 0; 69 78 70 79 /* state of EP0 (to correctly schedule setup packet enqueing) */ 71 80 enum ep0state ··· 225 234 { 226 235 int ep = ((dir == DIR_IN) ? in_ep_list : out_ep_list)[i]; 227 236 struct ep_type *endpoint = &endpoints[ep][out]; 228 - endpoint->active = false; 229 237 endpoint->busy = false; 230 238 endpoint->status = -1; 231 239 endpoint->done = true; ··· 580 588 GINTSTS = sts; 581 589 } 582 590 583 - int usb_drv_request_endpoint(int type, int dir) 584 - { 585 - bool out = dir == USB_DIR_OUT; 586 - for (unsigned i = 1; i < num_eps(out); i++) 587 - { 588 - int ep = (out ? out_ep_list : in_ep_list)[i]; 589 - bool *active = &endpoints[ep][out ? DIR_OUT : DIR_IN].active; 590 - if(*active) 591 - continue; 592 - *active = true; 593 - DEPCTL(ep, out) = (DEPCTL(ep, out) & ~(DEPCTL_eptype_bits << DEPCTL_eptype_bitp)) 594 - | DEPCTL_setd0pid | (type << DEPCTL_eptype_bitp) | DEPCTL_usbactep; 595 - return ep | dir; 596 - } 591 + int usb_drv_init_endpoint(int endpoint, int type, int max_packet_size) { 592 + (void)max_packet_size; /* FIXME: support max packet size override */ 597 593 598 - return -1; 594 + int num = EP_NUM(endpoint); 595 + int dir = EP_DIR(endpoint); 596 + bool out = dir == DIR_OUT; 597 + DEPCTL(num, out) = (DEPCTL(num, out) & ~(DEPCTL_eptype_bits << DEPCTL_eptype_bitp)) 598 + | DEPCTL_setd0pid | (type << DEPCTL_eptype_bitp) | DEPCTL_usbactep; 599 + return 0; 599 600 } 600 601 601 - void usb_drv_release_endpoint(int ep) 602 - { 603 - if ((ep & 0x7f) == 0) 604 - return; 605 - endpoints[EP_NUM(ep)][EP_DIR(ep)].active = false; 602 + int usb_drv_deinit_endpoint(int endpoint) { 603 + return 0; 606 604 } 607 605 608 606 void usb_drv_cancel_all_transfers()
+15 -41
firmware/target/arm/usb-tcc.c
··· 32 32 #ifdef HAVE_USBSTACK 33 33 #include "usb_ch9.h" 34 34 #include "usb_core.h" 35 + #include "usb_drv.h" 35 36 36 37 #define TCC7xx_USB_EPIF_IRQ_MASK 0xf 37 38 ··· 70 71 char *buf; /* user buffer to store data */ 71 72 int max_len; /* how match data will fit */ 72 73 int count; /* actual data count */ 73 - bool busy; 74 74 } ; 75 + 76 + struct usb_drv_ep_spec usb_drv_ep_specs[USB_NUM_ENDPOINTS] = { 77 + {.type = {USB_ENDPOINT_XFER_CONTROL, USB_ENDPOINT_XFER_CONTROL}}, 78 + {.type = {USB_ENDPOINT_TYPE_NONE, USB_ENDPOINT_XFER_BULK}}, 79 + {.type = {USB_ENDPOINT_XFER_BULK, USB_ENDPOINT_TYPE_NONE}}, 80 + }; 81 + uint8_t usb_drv_ep_specs_flags = 0; 75 82 76 83 static struct tcc_ep tcc_endpoints[] = { 77 84 /* control */ ··· 93 100 static bool usb_drv_write_ep(struct tcc_ep *ep); 94 101 static void usb_set_speed(int); 95 102 96 - int usb_drv_request_endpoint(int type, int dir) 97 - { 98 - int flags = disable_irq_save(); 99 - size_t ep; 100 - int ret = 0; 101 - 102 - if (type != USB_ENDPOINT_XFER_BULK) 103 - return -1; 104 - 105 - if (dir == USB_DIR_IN) 106 - ep = 1; 107 - else 108 - ep = 2; 103 + int usb_drv_init_endpoint(int endpoint, int type, int max_packet_size) { 104 + (void)max_packet_size; /* FIXME: support max packet size override */ 109 105 110 - if (!tcc_endpoints[ep].busy) { 111 - tcc_endpoints[ep].busy = true; 112 - tcc_endpoints[ep].dir = dir; 113 - ret = ep | dir; 114 - } else { 115 - ret = -1; 116 - } 117 - 118 - restore_irq(flags); 119 - return ret; 106 + tcc_endpoints[EP_NUM(endpoint)].dir = EP_DIR(endpoint) == DIR_IN ? USB_DIR_IN : USB_DIR_OUT; 107 + return 0; 120 108 } 121 109 122 - void usb_drv_release_endpoint(int ep) 123 - { 124 - int flags; 125 - ep = ep & 0x7f; 126 - 127 - if (ep < 1 || ep > USB_NUM_ENDPOINTS) 128 - return ; 129 - 130 - flags = disable_irq_save(); 131 - 132 - tcc_endpoints[ep].busy = false; 133 - tcc_endpoints[ep].dir = -1; 134 - 135 - restore_irq(flags); 110 + int usb_drv_deinit_endpoint(int endpoint) { 111 + tcc_endpoints[EP_NUM(endpoint)].dir = -1; 112 + return 0; 136 113 } 137 114 138 115 static inline void pullup_on(void) ··· 349 326 350 327 if (0 == (ep_irq & (1 << endpoint))) 351 328 continue; 352 - if (!tcc_ep->busy) 353 - panicf_my("ep%d: wasn't requested", endpoint); 354 329 355 330 TCC7xx_USB_INDEX = endpoint; 356 331 stat = TCC7xx_USB_EP_STAT; ··· 698 673 tcc_endpoints[i].id = i; 699 674 tcc_endpoints[i].mask = 1 << i; 700 675 tcc_endpoints[i].buf = NULL; 701 - tcc_endpoints[i].busy = false; 702 676 tcc_endpoints[i].dir = -1; 703 677 } 704 678
+15 -27
firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
··· 81 81 { .type = ep_interrupt, .fifo_addr = USB_FIFO_EP2, .fifo_size = 64 }, 82 82 }; 83 83 84 + struct usb_drv_ep_spec usb_drv_ep_specs[USB_NUM_ENDPOINTS] = { 85 + {.type = {USB_ENDPOINT_XFER_CONTROL, USB_ENDPOINT_XFER_CONTROL}}, 86 + {.type = {USB_ENDPOINT_XFER_BULK, USB_ENDPOINT_XFER_BULK}}, 87 + {.type = {USB_ENDPOINT_TYPE_NONE, USB_ENDPOINT_XFER_INT}}, 88 + }; 89 + uint8_t usb_drv_ep_specs_flags = 0; 90 + 84 91 static inline void select_endpoint(int ep) 85 92 { 86 93 REG_USB_REG_INDEX = ep; ··· 829 836 restore_irq(flags); 830 837 } 831 838 832 - void usb_drv_release_endpoint(int ep) 833 - { 834 - (void)ep; 835 - logf("%s(%d, %s)", __func__, (ep & 0x7F), (ep >> 7) ? "IN" : "OUT"); 839 + int usb_drv_init_endpoint(int endpoint, int type, int max_packet_size) { 840 + (void)endpoint; 841 + (void)type; 842 + (void)max_packet_size; /* FIXME: support max packet size override */ 843 + return 0; 836 844 } 837 845 838 - int usb_drv_request_endpoint(int type, int dir) 839 - { 840 - logf("%s(%d, %s)", __func__, type, (dir == USB_DIR_IN) ? "IN" : "OUT"); 841 - 842 - dir &= USB_ENDPOINT_DIR_MASK; 843 - type &= USB_ENDPOINT_XFERTYPE_MASK; 844 - 845 - /* There are only 3+2 endpoints, so hardcode this ... */ 846 - switch(type) 847 - { 848 - case USB_ENDPOINT_XFER_BULK: 849 - if(dir == USB_DIR_IN) 850 - return (1 | USB_DIR_IN); 851 - else 852 - return (1 | USB_DIR_OUT); 853 - 854 - case USB_ENDPOINT_XFER_INT: 855 - if(dir == USB_DIR_IN) 856 - return (2 | USB_DIR_IN); 857 - 858 - default: 859 - return -1; 860 - } 846 + int usb_drv_deinit_endpoint(int endpoint) { 847 + (void)endpoint; 848 + return 0; 861 849 }
+28 -71
firmware/target/mips/ingenic_jz47xx/usb-jz4760.c
··· 109 109 EP_INIT(ep_interrupt, USB_FIFO_EP(2), 512, NULL), 110 110 }; 111 111 112 + struct usb_drv_ep_spec usb_drv_ep_specs[USB_NUM_ENDPOINTS] = { 113 + {.type = {USB_ENDPOINT_XFER_CONTROL, USB_ENDPOINT_XFER_CONTROL}}, 114 + {.type = {USB_ENDPOINT_XFER_BULK, USB_ENDPOINT_XFER_BULK}}, 115 + {.type = {USB_ENDPOINT_XFER_INT, USB_ENDPOINT_XFER_INT}}, 116 + }; 117 + uint8_t usb_drv_ep_specs_flags = 0; 118 + 112 119 static inline void select_endpoint(int ep) 113 120 { 114 121 REG_USB_INDEX = ep; ··· 1185 1192 restore_irq(flags); 1186 1193 } 1187 1194 1188 - void usb_drv_release_endpoint(int ep) 1189 - { 1190 - int n = ep & 0x7f; 1191 - 1192 - logf("%s(%d, %s)", __func__, (ep & 0x7F), (ep >> 7) ? "IN" : "OUT"); 1193 - 1194 - if (n) 1195 - { 1196 - int dir = ep & USB_ENDPOINT_DIR_MASK; 1195 + int usb_drv_init_endpoint(int endpoint, int type, int max_packet_size) { 1196 + (void)max_packet_size; /* FIXME: support max packet size override */ 1197 1197 1198 - if(dir == USB_DIR_IN) 1199 - { 1200 - REG_USB_INTRINE &= ~USB_INTR_EP(n); 1201 - endpoints[n << 1].allocated = false; 1202 - } 1203 - else 1204 - { 1205 - REG_USB_INTROUTE &= ~USB_INTR_EP(n); 1206 - endpoints[(n << 1) + 1].allocated = false; 1207 - } 1208 - } 1198 + int num = EP_NUM(endpoint); 1199 + int dir = EP_DIR(endpoint); 1200 + int index = num * 2 + (dir == DIR_OUT ? 1 : 0); 1201 + endpoints[index].allocated = true; 1202 + if(dir == DIR_IN) 1203 + REG_USB_INTRINE |= USB_INTR_EP(num); 1204 + else 1205 + REG_USB_INTROUTE |= USB_INTR_EP(num); 1206 + return 0; 1209 1207 } 1210 1208 1211 - int usb_drv_request_endpoint(int type, int dir) 1212 - { 1213 - logf("%s(%d, %s)", __func__, type, (dir == USB_DIR_IN) ? "IN" : "OUT"); 1214 - 1215 - dir &= USB_ENDPOINT_DIR_MASK; 1216 - type &= USB_ENDPOINT_XFERTYPE_MASK; 1217 - 1218 - /* There are only 3+2 endpoints, so hardcode this ... */ 1219 - switch(type) 1220 - { 1221 - case USB_ENDPOINT_XFER_BULK: 1222 - if(dir == USB_DIR_IN) 1223 - { 1224 - if (endpoints[2].allocated) 1225 - break; 1226 - endpoints[2].allocated = true; 1227 - REG_USB_INTRINE |= USB_INTR_EP(1); 1228 - return (1 | USB_DIR_IN); 1229 - } 1230 - else 1231 - { 1232 - if (endpoints[3].allocated) 1233 - break; 1234 - endpoints[3].allocated = true; 1235 - REG_USB_INTROUTE |= USB_INTR_EP(1); 1236 - return (1 | USB_DIR_OUT); 1237 - } 1238 - 1239 - case USB_ENDPOINT_XFER_INT: 1240 - if(dir == USB_DIR_IN) 1241 - { 1242 - if (endpoints[4].allocated) 1243 - break; 1244 - endpoints[4].allocated = true; 1245 - REG_USB_INTRINE |= USB_INTR_EP(2); 1246 - return (2 | USB_DIR_IN); 1247 - } 1248 - else 1249 - { 1250 - if (endpoints[5].allocated) 1251 - break; 1252 - endpoints[5].allocated = true; 1253 - REG_USB_INTROUTE |= USB_INTR_EP(2); 1254 - return (2 | USB_DIR_OUT); 1255 - } 1256 - 1257 - default: 1258 - break; 1259 - } 1260 - 1261 - return -1; 1209 + int usb_drv_deinit_endpoint(int endpoint) { 1210 + int num = EP_NUM(endpoint); 1211 + int dir = EP_DIR(endpoint); 1212 + int index = num * 2 + (dir == DIR_OUT ? 1 : 0); 1213 + endpoints[index].allocated = false; 1214 + if(dir == DIR_IN) 1215 + REG_USB_INTRINE &= ~USB_INTR_EP(num); 1216 + else 1217 + REG_USB_INTROUTE &= ~USB_INTR_EP(num); 1218 + return 0; 1262 1219 }
+29 -43
firmware/usbstack/usb_audio.c
··· 297 297 298 298 static int as_playback_freq_idx; /* audio playback streaming frequency index (in hw_freq_sampr) */ 299 299 300 - static int out_iso_ep_adr; /* output isochronous endpoint */ 301 - static int in_iso_feedback_ep_adr; /* input feedback isochronous endpoint */ 300 + struct usb_class_driver_ep_allocation usb_audio_ep_allocs[2] = { 301 + /* output isochronous endpoint */ 302 + {.type = USB_ENDPOINT_XFER_ISOC, .dir = DIR_OUT, .optional = false}, 303 + /* input feedback isochronous endpoint */ 304 + {.type = USB_ENDPOINT_XFER_ISOC, .dir = DIR_IN, .optional = false}, 305 + }; 306 + 307 + #define EP_ISO_OUT (usb_audio_ep_allocs[0].ep) 308 + #define EP_ISO_FEEDBACK_IN (usb_audio_ep_allocs[1].ep) 302 309 303 310 /* small buffer used for control transfers */ 304 311 static unsigned char usb_buffer[128] USB_DEVBSS_ATTR; ··· 561 568 dsp_buf = NULL; 562 569 } 563 570 564 - int usb_audio_request_endpoints(struct usb_class_driver *drv) 565 - { 566 - // make sure we can get the buffers first... 567 - // return -1 if the allocation _failed_ 568 - if (usb_audio_request_buf()) 569 - return -1; 570 - 571 - out_iso_ep_adr = usb_core_request_endpoint(USB_ENDPOINT_XFER_ISOC, USB_DIR_OUT, drv); 572 - if(out_iso_ep_adr < 0) 573 - { 574 - logf("usbaudio: cannot get an out iso endpoint"); 575 - return -1; 576 - } 577 - 578 - in_iso_feedback_ep_adr = usb_core_request_endpoint(USB_ENDPOINT_XFER_ISOC, USB_DIR_IN, drv); 579 - if(in_iso_feedback_ep_adr < 0) 580 - { 581 - usb_core_release_endpoint(out_iso_ep_adr); 582 - logf("usbaudio: cannot get an in iso endpoint"); 583 - return -1; 584 - } 585 - 586 - logf("usbaudio: iso out ep is 0x%x, in ep is 0x%x", out_iso_ep_adr, in_iso_feedback_ep_adr); 587 - 588 - as_iso_audio_out_ep.bEndpointAddress = out_iso_ep_adr; 589 - as_iso_audio_out_ep.bSynchAddress = in_iso_feedback_ep_adr; 590 - 591 - as_iso_synch_in_ep.bEndpointAddress = in_iso_feedback_ep_adr; 592 - as_iso_synch_in_ep.bSynchAddress = 0; 593 - 594 - return 0; 595 - } 596 - 597 571 unsigned int usb_audio_get_out_ep(void) 598 572 { 599 - return out_iso_ep_adr; 573 + return EP_ISO_OUT; 600 574 } 601 575 602 576 unsigned int usb_audio_get_in_ep(void) 603 577 { 604 - return in_iso_feedback_ep_adr; 578 + return EP_ISO_FEEDBACK_IN; 605 579 } 606 580 607 581 int usb_audio_set_first_interface(int interface) ··· 638 612 639 613 /* endpoints */ 640 614 as_iso_audio_out_ep.wMaxPacketSize = 1023; 615 + as_iso_audio_out_ep.bEndpointAddress = EP_ISO_OUT; 616 + as_iso_audio_out_ep.bSynchAddress = EP_ISO_FEEDBACK_IN; 617 + as_iso_synch_in_ep.bEndpointAddress = EP_ISO_FEEDBACK_IN; 618 + as_iso_synch_in_ep.bSynchAddress = 0; 641 619 642 620 /** Endpoint Interval calculation: 643 621 * typically sampling frequency is 44100 Hz and top is 192000 Hz, which ··· 691 669 { 692 670 logf("usbaudio: recover usb rx overflow"); 693 671 usb_rx_overflow = false; 694 - usb_drv_recv_nonblocking(out_iso_ep_adr, rx_buffer, BUFFER_SIZE); 672 + usb_drv_recv_nonblocking(EP_ISO_OUT, rx_buffer, BUFFER_SIZE); 695 673 } 696 674 restore_irq(oldlevel); 697 675 } ··· 731 709 pcm_apply_settings(); 732 710 mixer_channel_set_amplitude(PCM_MIXER_CHAN_USBAUDIO, MIX_AMP_UNITY); 733 711 734 - usb_drv_recv_nonblocking(out_iso_ep_adr, rx_buffer, BUFFER_SIZE); 712 + usb_drv_recv_nonblocking(EP_ISO_OUT, rx_buffer, BUFFER_SIZE); 735 713 } 736 714 737 715 static void usb_audio_stop_playback(void) ··· 883 861 { 884 862 int ep = req->wIndex & 0xff; 885 863 886 - if(ep == out_iso_ep_adr) 864 + if(ep == EP_ISO_OUT) 887 865 return usb_audio_as_ctrldata_endpoint_request(req, reqdata); 888 866 else 889 867 { ··· 1183 1161 void usb_audio_init_connection(void) 1184 1162 { 1185 1163 logf("usbaudio: init connection"); 1164 + 1165 + // make sure we can get the buffers first... 1166 + // TODO: disable this driver when failed 1167 + if (usb_audio_request_buf()) 1168 + return; 1186 1169 1187 1170 usbaudio_active = true; 1188 1171 dsp = dsp_get_config(CODEC_IDX_AUDIO); ··· 1204 1187 { 1205 1188 logf("usbaudio: disconnect"); 1206 1189 1190 + if(!usbaudio_active) 1191 + return; 1192 + 1207 1193 usb_audio_stop_playback(); 1208 1194 usb_audio_free_buf(); 1209 1195 usbaudio_active = false; ··· 1289 1275 (void) dir; 1290 1276 bool retval = false; 1291 1277 1292 - if(ep == out_iso_ep_adr && usb_as_playback_intf_alt == 1) 1278 + if(ep == EP_ISO_OUT && usb_as_playback_intf_alt == 1) 1293 1279 { 1294 1280 // check for dropped frames 1295 1281 if (last_frame != usb_drv_get_frame_number()) ··· 1340 1326 if(rx_usb_idx != rx_play_idx) 1341 1327 { 1342 1328 logf("usbaudio: new transaction"); 1343 - usb_drv_recv_nonblocking(out_iso_ep_adr, rx_buffer, BUFFER_SIZE); 1329 + usb_drv_recv_nonblocking(EP_ISO_OUT, rx_buffer, BUFFER_SIZE); 1344 1330 } 1345 1331 else 1346 1332 { ··· 1399 1385 1400 1386 encodeFBfixedpt(sendFf, samples_fb, usb_drv_port_speed()); 1401 1387 logf("usbaudio: frame %d fbval 0x%02X%02X%02X%02X", usb_drv_get_frame_number(), sendFf[3], sendFf[2], sendFf[1], sendFf[0]); 1402 - usb_drv_send_nonblocking(in_iso_feedback_ep_adr, sendFf, usb_drv_port_speed()?4:3); 1388 + usb_drv_send_nonblocking(EP_ISO_FEEDBACK_IN, sendFf, usb_drv_port_speed()?4:3); 1403 1389 1404 1390 // debug screen counters 1405 1391 //
+1 -14
firmware/usbstack/usb_audio.h
··· 30 30 * Relevant specifications are USB 2.0 and USB Audio Class 1.0. 31 31 */ 32 32 33 - /* 34 - * usb_audio_request_endpoints(): 35 - * 36 - * Calls usb_core_request_endpoint() to request one IN and one OUT 37 - * isochronous endpoint. 38 - * 39 - * Called by allocate_interfaces_and_endpoints(). 40 - * 41 - * Returns -1 if either request fails, returns 0 if success. 42 - * 43 - * Also requests buffer allocations. If allocation fails, 44 - * returns -1 so that the driver will be disabled by the USB core. 45 - */ 46 - int usb_audio_request_endpoints(struct usb_class_driver *); 33 + extern struct usb_class_driver_ep_allocation usb_audio_ep_allocs[2]; 47 34 48 35 /* 49 36 * usb_audio_set_first_interface():
-6
firmware/usbstack/usb_charging_only.c
··· 46 46 47 47 static int usb_interface; 48 48 49 - int usb_charging_only_request_endpoints(struct usb_class_driver *drv) 50 - { 51 - (void) drv; 52 - return 0; 53 - } 54 - 55 49 int usb_charging_only_set_first_interface(int interface) 56 50 { 57 51 usb_interface = interface;
-1
firmware/usbstack/usb_charging_only.h
··· 24 24 #include "usb_ch9.h" 25 25 26 26 void usb_charging_only_init(void); 27 - int usb_charging_only_request_endpoints(struct usb_class_driver *); 28 27 int usb_charging_only_set_first_interface(int interface); 29 28 int usb_charging_only_get_config_descriptor(unsigned char *dest,int max_packet_size); 30 29 bool usb_charging_only_control_request(struct usb_ctrlrequest* req);
+10 -2
firmware/usbstack/usb_class_driver.h
··· 29 29 30 30 /* Common api, implemented by all class drivers */ 31 31 32 + struct usb_class_driver_ep_allocation { 33 + uint8_t type; /* by driver, required ep type. USB_ENDPOINT_XFER_* */ 34 + uint8_t dir; /* by driver, required ep dir. DIR_{IN,OUT} */ 35 + uint8_t ep; /* by core, allocated ep. > 0 are valid but can be 0 if optional==true */ 36 + bool optional; /* by driver, set true to mark this requirement to be optional */ 37 + }; 38 + 32 39 struct usb_class_driver { 33 40 /* First some runtime data */ 34 41 bool enabled; ··· 40 47 /* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */ 41 48 bool needs_exclusive_storage; 42 49 43 - /* Let the driver request endpoints it need. Returns zero on success */ 44 - int (*request_endpoints)(struct usb_class_driver *); 50 + /* Endpoint allocation state table */ 51 + uint8_t ep_allocs_size; 52 + struct usb_class_driver_ep_allocation* ep_allocs; 45 53 46 54 /* Tells the driver what its first interface number will be. The driver 47 55 returns the number of the first available interface for the next driver
+130 -50
firmware/usbstack/usb_core.c
··· 183 183 struct usb_transfer_completion_event_data completion_event[2]; 184 184 } ep_data[USB_NUM_ENDPOINTS]; 185 185 186 + struct ep_alloc_state { 187 + int8_t type[2]; 188 + struct usb_class_driver* owner[2]; 189 + }; 190 + 191 + static struct ep_alloc_state ep_alloc_states[1][USB_NUM_ENDPOINTS]; 192 + 186 193 static struct usb_class_driver drivers[USB_NUM_DRIVERS] = 187 194 { 188 195 #ifdef USB_ENABLE_STORAGE ··· 191 198 .needs_exclusive_storage = true, 192 199 .first_interface = 0, 193 200 .last_interface = 0, 194 - .request_endpoints = usb_storage_request_endpoints, 201 + .ep_allocs_size = ARRAYLEN(usb_storage_ep_allocs), 202 + .ep_allocs = usb_storage_ep_allocs, 195 203 .set_first_interface = usb_storage_set_first_interface, 196 204 .get_config_descriptor = usb_storage_get_config_descriptor, 197 205 .init_connection = usb_storage_init_connection, ··· 210 218 .needs_exclusive_storage = false, 211 219 .first_interface = 0, 212 220 .last_interface = 0, 213 - .request_endpoints = usb_serial_request_endpoints, 221 + .ep_allocs_size = ARRAYLEN(usb_serial_ep_allocs), 222 + .ep_allocs = usb_serial_ep_allocs, 214 223 .set_first_interface = usb_serial_set_first_interface, 215 224 .get_config_descriptor = usb_serial_get_config_descriptor, 216 225 .init_connection = usb_serial_init_connection, ··· 229 238 .needs_exclusive_storage = false, 230 239 .first_interface = 0, 231 240 .last_interface = 0, 232 - .request_endpoints = usb_charging_only_request_endpoints, 241 + .ep_allocs_size = 0, 242 + .ep_allocs = NULL, 233 243 .set_first_interface = usb_charging_only_set_first_interface, 234 244 .get_config_descriptor = usb_charging_only_get_config_descriptor, 235 245 .init_connection = NULL, ··· 248 258 .needs_exclusive_storage = false, 249 259 .first_interface = 0, 250 260 .last_interface = 0, 251 - .request_endpoints = usb_hid_request_endpoints, 261 + .ep_allocs_size = ARRAYLEN(usb_hid_ep_allocs), 262 + .ep_allocs = usb_hid_ep_allocs, 252 263 .set_first_interface = usb_hid_set_first_interface, 253 264 .get_config_descriptor = usb_hid_get_config_descriptor, 254 265 .init_connection = usb_hid_init_connection, ··· 267 278 .needs_exclusive_storage = false, 268 279 .first_interface = 0, 269 280 .last_interface = 0, 270 - .request_endpoints = usb_audio_request_endpoints, 281 + .ep_allocs_size = ARRAYLEN(usb_audio_ep_allocs), 282 + .ep_allocs = usb_audio_ep_allocs, 271 283 .set_first_interface = usb_audio_set_first_interface, 272 284 .get_config_descriptor = usb_audio_get_config_descriptor, 273 285 .init_connection = usb_audio_init_connection, ··· 459 471 if(drivers[i].init != NULL) 460 472 drivers[i].init(); 461 473 474 + /* clear endpoint allocation state */ 475 + memset(ep_alloc_states, 0, sizeof(ep_alloc_states)); 476 + 462 477 initialized = true; 463 478 usb_state = DEFAULT; 464 479 #ifdef HAVE_USB_CHARGING_ENABLE ··· 558 573 usb_string_iSerial.wString[0] = hex[id]; 559 574 } 560 575 561 - int usb_core_request_endpoint(int type, int dir, struct usb_class_driver* drv) 562 - { 563 - int ret, ep; 564 - 565 - ret = usb_drv_request_endpoint(type, dir); 566 - 567 - if(ret == -1) 568 - return -1; 569 - 570 - dir = EP_DIR(ret); 571 - ep = EP_NUM(ret); 572 - 573 - ep_data[ep].completion_handler[dir] = drv->transfer_complete; 574 - ep_data[ep].fast_completion_handler[dir] = drv->fast_transfer_complete; 575 - ep_data[ep].control_handler[dir] = drv->control_request; 576 - 577 - return ret; 578 - } 579 - 580 - void usb_core_release_endpoint(int ep) 576 + static void allocate_interfaces_and_endpoints(void) 581 577 { 582 - int dir; 578 + int interface = 0; 583 579 584 - usb_drv_release_endpoint(ep); 580 + /* deinit previously allocated endpoints */ 581 + for(int conf = 0; conf < 1; conf += 1) { 582 + for(int epnum = 0; epnum < USB_NUM_ENDPOINTS; epnum += 1) { 583 + for(int dir = 0; dir < 2; dir += 1) { 584 + struct ep_alloc_state* alloc = &ep_alloc_states[0][epnum]; 585 + if(alloc->owner[dir] != NULL) { 586 + int ep = epnum | (dir == DIR_OUT ? USB_DIR_OUT : USB_DIR_IN); 587 + usb_drv_deinit_endpoint(ep); 588 + alloc->owner[dir] = NULL; 589 + } 590 + } 591 + } 592 + } 585 593 586 - dir = EP_DIR(ep); 587 - ep = EP_NUM(ep); 594 + for(int i = 0; i < USB_NUM_DRIVERS; i++) { 595 + struct usb_class_driver* driver = &drivers[i]; 588 596 589 - ep_data[ep].completion_handler[dir] = NULL; 590 - ep_data[ep].control_handler[dir] = NULL; 591 - } 597 + if(!driver->enabled) { 598 + continue; 599 + } 592 600 593 - static void allocate_interfaces_and_endpoints(void) 594 - { 595 - int i; 596 - int interface = 0; 597 - 598 - memset(ep_data, 0, sizeof(ep_data)); 601 + /* assign endpoints */ 602 + for(int reqnum = 0; reqnum < driver->ep_allocs_size; reqnum += 1) { 603 + /* find matching ep */ 604 + struct usb_class_driver_ep_allocation* req = &driver->ep_allocs[reqnum]; 605 + req->ep = 0; 606 + for(int epnum = 1; epnum < USB_NUM_ENDPOINTS; epnum += 1) { 607 + struct usb_drv_ep_spec* spec = &usb_drv_ep_specs[epnum]; 608 + /* ep type check */ 609 + const int8_t spec_type = spec->type[req->dir]; 610 + if(spec_type != req->type && spec_type != USB_ENDPOINT_TYPE_ANY) { 611 + continue; 612 + } 613 + /* free check */ 614 + struct ep_alloc_state* alloc = &ep_alloc_states[0][epnum]; 615 + if(alloc->owner[req->dir] != NULL) { 616 + continue; 617 + } 599 618 600 - for(i = 0; i < USB_NUM_ENDPOINTS; i++) { 601 - usb_drv_release_endpoint(i | USB_DIR_OUT); 602 - usb_drv_release_endpoint(i | USB_DIR_IN); 603 - } 619 + /* this ep's requested direction is free */ 604 620 605 - for(i = 0; i < USB_NUM_DRIVERS; i++) { 606 - if(drivers[i].enabled) { 607 - drivers[i].first_interface = interface; 621 + /* another checks */ 622 + if(usb_drv_ep_specs_flags & USB_ENDPOINT_SPEC_IO_EXCLUSIVE) { 623 + /* check for the other direction type */ 624 + if(alloc->owner[!req->dir] != NULL) { 625 + /* the other side is allocated */ 626 + continue; 627 + } 628 + } 629 + if(usb_drv_ep_specs_flags & USB_ENDPOINT_SPEC_FORCE_IO_TYPE_MATCH) { 630 + /* check for other direction type */ 631 + if(alloc->owner[!req->dir] != NULL && alloc->type[!req->dir] != req->type) { 632 + /* the other side is allocated with another type */ 633 + continue; 634 + } 635 + } 608 636 609 - if(drivers[i].request_endpoints(&drivers[i])) { 610 - drivers[i].enabled = false; 611 - continue; 637 + /* all checks passed, assign it */ 638 + const int ep = epnum | (req->dir == DIR_OUT ? USB_DIR_OUT : USB_DIR_IN); 639 + req->ep = ep; 640 + alloc->owner[req->dir] = driver; 641 + alloc->type[req->dir] = req->type; 642 + break; 612 643 } 644 + if(req->ep == 0 && !req->optional) { 645 + /* no matching ep found, disable the driver */ 646 + driver->enabled = false; 647 + /* also revert all allocations for this driver */ 648 + for(reqnum = reqnum - 1; reqnum >= 0; reqnum -= 1) { 649 + const uint8_t ep = driver->ep_allocs[reqnum].ep; 650 + const uint8_t epnum = EP_NUM(ep); 651 + const uint8_t epdir = EP_DIR(ep); 652 + const uint8_t dir = epdir == USB_DIR_OUT ? DIR_OUT : DIR_IN; 653 + ep_alloc_states[0][epnum].owner[dir] = NULL; 654 + } 655 + break; 656 + } 657 + } 613 658 614 - interface = drivers[i].set_first_interface(interface); 615 - drivers[i].last_interface = interface; 659 + if(!driver->enabled) { 660 + continue; 616 661 } 662 + 663 + /* assign interfaces */ 664 + driver->first_interface = interface; 665 + interface = driver->set_first_interface(interface); 666 + driver->last_interface = interface; 617 667 } 668 + 618 669 usb_core_num_interfaces = interface; 619 670 } 620 671 ··· 778 829 static void usb_core_do_set_config(uint8_t config) 779 830 { 780 831 logf("usb_core: SET_CONFIG %d",config); 832 + 833 + /* (de)initialize allocated endpoints */ 834 + const bool init = usb_state == ADDRESS && config; 835 + const bool deinit = usb_state == CONFIGURED && !config; 836 + if(init || deinit) { 837 + memset(ep_data, 0, sizeof(ep_data)); 838 + for(int epnum = 0; epnum < USB_NUM_ENDPOINTS; epnum += 1) { 839 + for(int dir = 0; dir < 2; dir += 1) { 840 + struct ep_alloc_state* alloc = &ep_alloc_states[0][epnum]; 841 + if(alloc->owner[dir] == NULL) { 842 + continue; 843 + } 844 + int ep = epnum | (dir == DIR_OUT ? USB_DIR_OUT : USB_DIR_IN); 845 + int ret = init ? 846 + usb_drv_init_endpoint(ep, alloc->type[dir], -1) : 847 + usb_drv_deinit_endpoint(ep); 848 + if(ret) { 849 + logf("usb_core: usb_drv_%s_endpoint failed ep=%d dir=%e", init ? "init" : "deinit", epnum, dir); 850 + continue; 851 + } 852 + if(init) { 853 + ep_data[epnum].completion_handler[dir] = alloc->owner[dir]->transfer_complete; 854 + ep_data[epnum].fast_completion_handler[dir] = alloc->owner[dir]->fast_transfer_complete; 855 + ep_data[epnum].control_handler[dir] = alloc->owner[dir]->control_request; 856 + } 857 + } 858 + } 859 + } 860 + 781 861 if(config) { 782 862 usb_state = CONFIGURED; 783 863
+8 -12
firmware/usbstack/usb_hid.c
··· 186 186 187 187 static bool active = false; 188 188 static bool currently_sending = false; 189 - static int ep_in; 190 189 static int usb_interface; 190 + 191 + struct usb_class_driver_ep_allocation usb_hid_ep_allocs[1] = { 192 + {.type = USB_ENDPOINT_XFER_INT, .dir = DIR_IN, .optional = false}, 193 + }; 194 + 195 + #define EP_IN (usb_hid_ep_allocs[0].ep) 191 196 192 197 static void usb_hid_try_send_drv(void); 193 198 ··· 233 238 (*dest)++; 234 239 value >>= 8; 235 240 } 236 - } 237 - 238 - int usb_hid_request_endpoints(struct usb_class_driver *drv) 239 - { 240 - ep_in = usb_core_request_endpoint(USB_ENDPOINT_XFER_INT, USB_DIR_IN, drv); 241 - if (ep_in < 0) 242 - return -1; 243 - 244 - return 0; 245 241 } 246 242 247 243 int usb_hid_set_first_interface(int interface) ··· 608 604 /* Endpoint descriptor */ 609 605 endpoint_descriptor.wMaxPacketSize = 8; 610 606 endpoint_descriptor.bInterval = 8; 611 - endpoint_descriptor.bEndpointAddress = ep_in; 607 + endpoint_descriptor.bEndpointAddress = EP_IN; 612 608 PACK_DATA(&dest, endpoint_descriptor); 613 609 614 610 return (int)(dest - orig_dest); ··· 832 828 } 833 829 834 830 logf("HID: Sending %d bytes",length); 835 - rc = usb_drv_send_nonblocking(ep_in, send_buffer[cur_buf_send], length); 831 + rc = usb_drv_send_nonblocking(EP_IN, send_buffer[cur_buf_send], length); 836 832 currently_sending = true; 837 833 if (rc) 838 834 send_buffer_len[cur_buf_send] = 0;
+3 -2
firmware/usbstack/usb_hid.h
··· 21 21 #ifndef USB_HID_H 22 22 #define USB_HID_H 23 23 24 - #include "usb_ch9.h" 25 24 #include "usb_core.h" 25 + #include "usb_class_driver.h" 26 26 #include "usb_hid_usage_tables.h" 27 27 28 - int usb_hid_request_endpoints(struct usb_class_driver *drv); 28 + extern struct usb_class_driver_ep_allocation usb_hid_ep_allocs[1]; 29 + 29 30 int usb_hid_set_first_interface(int interface); 30 31 int usb_hid_get_config_descriptor(unsigned char *dest, int max_packet_size); 31 32 void usb_hid_init_connection(void);
+16 -30
firmware/usbstack/usb_serial.c
··· 206 206 static int buffer_transitlength; 207 207 static bool active = false; 208 208 209 - static int ep_in, ep_out, ep_int; 210 - static int control_interface, data_interface; 209 + struct usb_class_driver_ep_allocation usb_serial_ep_allocs[3] = { 210 + {.type = USB_ENDPOINT_XFER_BULK, .dir = DIR_IN, .optional = false}, 211 + {.type = USB_ENDPOINT_XFER_BULK, .dir = DIR_OUT, .optional = false}, 212 + {.type = USB_ENDPOINT_XFER_INT, .dir = DIR_IN, .optional = true}, 213 + }; 211 214 212 - int usb_serial_request_endpoints(struct usb_class_driver *drv) 213 - { 214 - ep_in = usb_core_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_IN, drv); 215 - if (ep_in < 0) 216 - return -1; 217 - 218 - ep_out = usb_core_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_OUT, 219 - drv); 220 - if (ep_out < 0) { 221 - usb_core_release_endpoint(ep_in); 222 - return -1; 223 - } 224 - 225 - /* Optional interrupt endpoint. While the code does not actively use it, 226 - * it is needed to get out-of-the-box serial port experience on Windows 227 - * and Linux. If this endpoint is not available, only CDC Data interface 228 - * will be exported (can still work on Linux with manual modprobe). 229 - */ 230 - ep_int = usb_core_request_endpoint(USB_ENDPOINT_XFER_INT, USB_DIR_IN, drv); 215 + #define EP_IN (usb_serial_ep_allocs[0].ep) 216 + #define EP_OUT (usb_serial_ep_allocs[1].ep) 217 + #define EP_INT (usb_serial_ep_allocs[2].ep) 231 218 232 - return 0; 233 - } 219 + static int control_interface, data_interface; 234 220 235 221 int usb_serial_set_first_interface(int interface) 236 222 { ··· 250 236 union_descriptor.bSubordinateInterface0 = data_interface; 251 237 data_interface_descriptor.bInterfaceNumber = data_interface; 252 238 253 - if (ep_int > 0) 239 + if (EP_INT > 0) 254 240 { 255 241 PACK_DATA(&dest, association_descriptor); 256 242 PACK_DATA(&dest, control_interface_descriptor); ··· 263 249 * both on Full and High speed. Note that max_packet_size is for bulk. 264 250 * Maximum bInterval for High Speed is 16 and for Full Speed is 255. 265 251 */ 266 - endpoint_descriptor.bEndpointAddress = ep_int; 252 + endpoint_descriptor.bEndpointAddress = EP_INT; 267 253 endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_INT; 268 254 endpoint_descriptor.wMaxPacketSize = 64; 269 255 endpoint_descriptor.bInterval = 16; ··· 271 257 } 272 258 273 259 PACK_DATA(&dest, data_interface_descriptor); 274 - endpoint_descriptor.bEndpointAddress = ep_in; 260 + endpoint_descriptor.bEndpointAddress = EP_IN; 275 261 endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK; 276 262 endpoint_descriptor.wMaxPacketSize = max_packet_size; 277 263 endpoint_descriptor.bInterval = 0; 278 264 PACK_DATA(&dest, endpoint_descriptor); 279 265 280 - endpoint_descriptor.bEndpointAddress = ep_out; 266 + endpoint_descriptor.bEndpointAddress = EP_OUT; 281 267 PACK_DATA(&dest, endpoint_descriptor); 282 268 283 269 return (dest - orig_dest); ··· 346 332 void usb_serial_init_connection(void) 347 333 { 348 334 /* prime rx endpoint */ 349 - usb_drv_recv_nonblocking(ep_out, receive_buffer, RECV_BUFFER_SIZE); 335 + usb_drv_recv_nonblocking(EP_OUT, receive_buffer, RECV_BUFFER_SIZE); 350 336 351 337 /* we come here too after a bus reset, so reset some data */ 352 338 buffer_transitlength = 0; ··· 379 365 buffer_transitlength = MIN(buffer_transitlength,TRANSIT_BUFFER_SIZE); 380 366 buffer_length -= buffer_transitlength; 381 367 memcpy(transit_buffer,&send_buffer[buffer_start],buffer_transitlength); 382 - usb_drv_send_nonblocking(ep_in,transit_buffer,buffer_transitlength); 368 + usb_drv_send_nonblocking(EP_IN,transit_buffer,buffer_transitlength); 383 369 } 384 370 } 385 371 ··· 437 423 /* Data received. TODO : Do something with it ? */ 438 424 439 425 /* Get the next bit */ 440 - usb_drv_recv_nonblocking(ep_out, receive_buffer, RECV_BUFFER_SIZE); 426 + usb_drv_recv_nonblocking(EP_OUT, receive_buffer, RECV_BUFFER_SIZE); 441 427 break; 442 428 443 429 case USB_DIR_IN:
+3 -2
firmware/usbstack/usb_serial.h
··· 21 21 #ifndef USB_SERIAL_H 22 22 #define USB_SERIAL_H 23 23 24 - #include "usb_ch9.h" 24 + #include "usb_class_driver.h" 25 + 26 + extern struct usb_class_driver_ep_allocation usb_serial_ep_allocs[3]; 25 27 26 - int usb_serial_request_endpoints(struct usb_class_driver *); 27 28 int usb_serial_set_first_interface(int interface); 28 29 int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size); 29 30 void usb_serial_init_connection(void);
+22 -33
firmware/usbstack/usb_storage.c
··· 321 321 static bool locked[NUM_DRIVES]; 322 322 323 323 static int usb_interface; 324 - static int ep_in, ep_out; 324 + 325 + struct usb_class_driver_ep_allocation usb_storage_ep_allocs[2] = { 326 + {.type = USB_ENDPOINT_XFER_BULK, .dir = DIR_IN, .optional = false}, 327 + {.type = USB_ENDPOINT_XFER_BULK, .dir = DIR_OUT, .optional = false}, 328 + }; 329 + 330 + #define EP_IN (usb_storage_ep_allocs[0].ep) 331 + #define EP_OUT (usb_storage_ep_allocs[1].ep) 325 332 326 333 #if defined(HAVE_MULTIDRIVE) 327 334 static bool skip_first = 0; ··· 399 406 logf("usb_storage_init done"); 400 407 } 401 408 402 - int usb_storage_request_endpoints(struct usb_class_driver *drv) 403 - { 404 - ep_in = usb_core_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_IN, drv); 405 - 406 - if(ep_in<0) 407 - return -1; 408 - 409 - ep_out = usb_core_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_OUT, 410 - drv); 411 - 412 - if(ep_out<0) { 413 - usb_core_release_endpoint(ep_in); 414 - return -1; 415 - } 416 - 417 - return 0; 418 - } 419 - 420 409 int usb_storage_set_first_interface(int interface) 421 410 { 422 411 usb_interface = interface; ··· 432 421 433 422 endpoint_descriptor.wMaxPacketSize = max_packet_size; 434 423 435 - endpoint_descriptor.bEndpointAddress = ep_in; 424 + endpoint_descriptor.bEndpointAddress = EP_IN; 436 425 PACK_DATA(&dest, endpoint_descriptor); 437 426 438 - endpoint_descriptor.bEndpointAddress = ep_out; 427 + endpoint_descriptor.bEndpointAddress = EP_OUT; 439 428 PACK_DATA(&dest, endpoint_descriptor); 440 429 441 430 return (dest - orig_dest); ··· 486 475 ramdisk_buffer = tb.transfer_buffer + ALLOCATE_BUFFER_SIZE; 487 476 #endif 488 477 #endif 489 - usb_drv_recv_nonblocking(ep_out, cbw_buffer, MAX_CBW_SIZE); 478 + usb_drv_recv_nonblocking(EP_OUT, cbw_buffer, MAX_CBW_SIZE); 490 479 491 480 int i; 492 481 for(i=0;i<storage_num_drives();i++) { ··· 731 720 data toggle bits and endpoint STALL conditions despite 732 721 the Bulk-Only Mass Storage Reset. */ 733 722 #if 0 734 - usb_drv_reset_endpoint(ep_in, false); 735 - usb_drv_reset_endpoint(ep_out, true); 723 + usb_drv_reset_endpoint(EP_IN, false); 724 + usb_drv_reset_endpoint(EP_OUT, true); 736 725 #endif 737 726 usb_drv_control_response(USB_CONTROL_ACK, NULL, 0); 738 727 handled = true; ··· 789 778 790 779 if(letoh32(cbw->signature) != CBW_SIGNATURE) { 791 780 logf("ums: bad cbw signature (%x)", cbw->signature); 792 - usb_drv_stall(ep_in, true,true); 793 - usb_drv_stall(ep_out, true,false); 781 + usb_drv_stall(EP_IN, true,true); 782 + usb_drv_stall(EP_OUT, true,false); 794 783 return; 795 784 } 796 785 /* Clear the signature to prevent possible bugs elsewhere ··· 1407 1396 1408 1397 static void send_block_data(void *data,int size) 1409 1398 { 1410 - usb_drv_send_nonblocking(ep_in, data,size); 1399 + usb_drv_send_nonblocking(EP_IN, data,size); 1411 1400 state = SENDING_BLOCKS; 1412 1401 } 1413 1402 1414 1403 static void send_command_result(void *data,int size) 1415 1404 { 1416 - usb_drv_send_nonblocking(ep_in, data,size); 1405 + usb_drv_send_nonblocking(EP_IN, data,size); 1417 1406 state = SENDING_RESULT; 1418 1407 } 1419 1408 1420 1409 static void send_command_failed_result(void) 1421 1410 { 1422 - usb_drv_send_nonblocking(ep_in, NULL, 0); 1411 + usb_drv_send_nonblocking(EP_IN, NULL, 0); 1423 1412 state = SENDING_FAILED_RESULT; 1424 1413 } 1425 1414 1426 1415 #if CONFIG_RTC 1427 1416 static void receive_time(void) 1428 1417 { 1429 - usb_drv_recv_nonblocking(ep_out, tb.transfer_buffer, 12); 1418 + usb_drv_recv_nonblocking(EP_OUT, tb.transfer_buffer, 12); 1430 1419 state = RECEIVING_TIME; 1431 1420 } 1432 1421 #endif /* CONFIG_RTC */ 1433 1422 1434 1423 static void receive_block_data(void *data,int size) 1435 1424 { 1436 - usb_drv_recv_nonblocking(ep_out, data, size); 1425 + usb_drv_recv_nonblocking(EP_OUT, data, size); 1437 1426 state = RECEIVING_BLOCKS; 1438 1427 } 1439 1428 ··· 1444 1433 tb.csw->data_residue = 0; 1445 1434 tb.csw->status = status; 1446 1435 1447 - usb_drv_send_nonblocking(ep_in, tb.csw, 1436 + usb_drv_send_nonblocking(EP_IN, tb.csw, 1448 1437 sizeof(struct command_status_wrapper)); 1449 1438 state = WAITING_FOR_CSW_COMPLETION_OR_COMMAND; 1450 1439 //logf("CSW: %X",status); 1451 1440 /* Already start waiting for the next command */ 1452 - usb_drv_recv_nonblocking(ep_out, cbw_buffer, MAX_CBW_SIZE); 1441 + usb_drv_recv_nonblocking(EP_OUT, cbw_buffer, MAX_CBW_SIZE); 1453 1442 /* The next completed transfer will be either the CSW one 1454 1443 * or the new command */ 1455 1444
+3 -2
firmware/usbstack/usb_storage.h
··· 21 21 #ifndef USB_STORAGE_H 22 22 #define USB_STORAGE_H 23 23 24 - #include "usb_ch9.h" 24 + #include "usb_class_driver.h" 25 + 26 + extern struct usb_class_driver_ep_allocation usb_storage_ep_allocs[2]; 25 27 26 - int usb_storage_request_endpoints(struct usb_class_driver *); 27 28 int usb_storage_set_first_interface(int interface); 28 29 int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size); 29 30 void usb_storage_init_connection(void);