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: preparation to support multiple usb configs

- existing class drivers are placed to config 1
- drivers_connected==true is replaced with usb_config!=0
- supports config transition between nonzero configs
- STALL if request set_config was invalid

Change-Id: Ia775ae2dcb7d0cc08d2f3ee5ca41683837b04259

mojyack 03fbd278 ea49358c

+165 -137
+3
firmware/usbstack/usb_class_driver.h
··· 47 47 /* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */ 48 48 bool needs_exclusive_storage; 49 49 50 + /* USB config number this driver belongs to */ 51 + uint8_t config; 52 + 50 53 /* Endpoint allocation state table */ 51 54 uint8_t ep_allocs_size; 52 55 struct usb_class_driver_ep_allocation* ep_allocs;
+162 -137
firmware/usbstack/usb_core.c
··· 72 72 #define USB_MAX_CURRENT 500 73 73 #endif 74 74 75 + #define NUM_CONFIGS 1 76 + 75 77 /*-------------------------------------------------------------------------*/ 76 78 /* USB protocol descriptors: */ 77 79 ··· 95 97 .iManufacturer = USB_STRING_INDEX_MANUFACTURER, 96 98 .iProduct = USB_STRING_INDEX_PRODUCT, 97 99 .iSerialNumber = USB_STRING_INDEX_SERIAL, 98 - .bNumConfigurations = 1 100 + .bNumConfigurations = NUM_CONFIGS 99 101 } ; 100 102 101 103 static struct usb_config_descriptor __attribute__((aligned(2))) ··· 121 123 .bDeviceSubClass = 0, 122 124 .bDeviceProtocol = 0, 123 125 .bMaxPacketSize0 = 64, 124 - .bNumConfigurations = 1 126 + .bNumConfigurations = NUM_CONFIGS 125 127 }; 126 128 127 129 static const struct usb_string_descriptor usb_string_iManufacturer = ··· 149 151 }; 150 152 151 153 static int usb_address = 0; 154 + static int usb_config = 0; 152 155 static bool initialized = false; 153 - static bool drivers_connected = false; 154 156 static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state; 155 157 156 158 #ifdef HAVE_USB_CHARGING_ENABLE ··· 168 170 } 169 171 #endif 170 172 171 - static int usb_core_num_interfaces; 173 + static int usb_core_num_interfaces[NUM_CONFIGS]; 172 174 173 175 typedef void (*completion_handler_t)(int ep, int dir, int status, int length); 174 176 typedef bool (*fast_completion_handler_t)(int ep, int dir, int status, int length); ··· 188 190 struct usb_class_driver* owner[2]; 189 191 }; 190 192 191 - static struct ep_alloc_state ep_alloc_states[1][USB_NUM_ENDPOINTS]; 193 + static struct ep_alloc_state ep_alloc_states[NUM_CONFIGS][USB_NUM_ENDPOINTS]; 192 194 193 195 static struct usb_class_driver drivers[USB_NUM_DRIVERS] = 194 196 { ··· 196 198 [USB_DRIVER_MASS_STORAGE] = { 197 199 .enabled = false, 198 200 .needs_exclusive_storage = true, 201 + .config = 1, 199 202 .first_interface = 0, 200 203 .last_interface = 0, 201 204 .ep_allocs_size = ARRAYLEN(usb_storage_ep_allocs), ··· 216 219 [USB_DRIVER_SERIAL] = { 217 220 .enabled = false, 218 221 .needs_exclusive_storage = false, 222 + .config = 1, 219 223 .first_interface = 0, 220 224 .last_interface = 0, 221 225 .ep_allocs_size = ARRAYLEN(usb_serial_ep_allocs), ··· 236 240 [USB_DRIVER_CHARGING_ONLY] = { 237 241 .enabled = false, 238 242 .needs_exclusive_storage = false, 243 + .config = 1, 239 244 .first_interface = 0, 240 245 .last_interface = 0, 241 246 .ep_allocs_size = 0, ··· 256 261 [USB_DRIVER_HID] = { 257 262 .enabled = false, 258 263 .needs_exclusive_storage = false, 264 + .config = 1, 259 265 .first_interface = 0, 260 266 .last_interface = 0, 261 267 .ep_allocs_size = ARRAYLEN(usb_hid_ep_allocs), ··· 276 282 [USB_DRIVER_AUDIO] = { 277 283 .enabled = false, 278 284 .needs_exclusive_storage = false, 285 + .config = 1, 279 286 .first_interface = 0, 280 287 .last_interface = 0, 281 288 .ep_allocs_size = ARRAYLEN(usb_audio_ep_allocs), ··· 309 316 310 317 static unsigned char response_data[256] USB_DEVBSS_ATTR; 311 318 319 + #define is_active(driver) ((driver).enabled && (driver).config == usb_config) 320 + #define has_if(driver, interface) ((interface) >= (driver).first_interface && (interface) < (driver).last_interface) 321 + 312 322 /** NOTE Serial Number 313 323 * The serial number string is split into two parts: 314 324 * - the first character indicates the set of interfaces enabled ··· 476 486 477 487 initialized = true; 478 488 usb_state = DEFAULT; 489 + usb_config = 0; 479 490 #ifdef HAVE_USB_CHARGING_ENABLE 480 491 usb_no_host = false; 481 492 timeout_register(&usb_no_host_timeout, usb_no_host_callback, HZ*10, 0); ··· 485 496 486 497 void usb_core_exit(void) 487 498 { 488 - int i; 489 - if(drivers_connected) 490 - { 491 - for(i = 0; i < USB_NUM_DRIVERS; i++) 492 - if(drivers[i].enabled && drivers[i].disconnect != NULL) 493 - { 499 + if(usb_config != 0) { 500 + for(int i = 0; i < USB_NUM_DRIVERS; i++) { 501 + if(is_active(drivers[i]) && drivers[i].disconnect != NULL) { 494 502 drivers[i].disconnect(); 495 503 drivers[i].enabled = false; 496 504 } 497 - drivers_connected = false; 505 + } 498 506 } 499 507 500 508 if(initialized) { ··· 573 581 usb_string_iSerial.wString[0] = hex[id]; 574 582 } 575 583 584 + /* synchronize endpoint initialization state to allocation state */ 585 + static void init_deinit_endpoints(uint8_t conf_index, bool init) { 586 + for(int epnum = 0; epnum < USB_NUM_ENDPOINTS; epnum += 1) { 587 + for(int dir = 0; dir < 2; dir += 1) { 588 + struct ep_alloc_state* alloc = &ep_alloc_states[conf_index][epnum]; 589 + if(alloc->owner[dir] == NULL) { 590 + continue; 591 + } 592 + int ep = epnum | (dir == DIR_OUT ? USB_DIR_OUT : USB_DIR_IN); 593 + int ret = init ? 594 + usb_drv_init_endpoint(ep, alloc->type[dir], -1) : 595 + usb_drv_deinit_endpoint(ep); 596 + if(ret) { 597 + logf("usb_core: usb_drv_%s_endpoint failed ep=%d dir=%d", init ? "init" : "deinit", epnum, dir); 598 + continue; 599 + } 600 + if(init) { 601 + ep_data[epnum].completion_handler[dir] = alloc->owner[dir]->transfer_complete; 602 + ep_data[epnum].fast_completion_handler[dir] = alloc->owner[dir]->fast_transfer_complete; 603 + ep_data[epnum].control_handler[dir] = alloc->owner[dir]->control_request; 604 + } 605 + } 606 + } 607 + } 608 + 576 609 static void allocate_interfaces_and_endpoints(void) 577 610 { 578 - int interface = 0; 579 - 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 - } 611 + if(usb_config != 0) { 612 + /* deinit currently used endpoints */ 613 + init_deinit_endpoints(usb_config - 1, false); 592 614 } 593 615 616 + /* reset allocations */ 617 + memset(ep_alloc_states, 0, sizeof(ep_alloc_states)); 618 + 619 + int interface[NUM_CONFIGS] = {0}; 620 + 594 621 for(int i = 0; i < USB_NUM_DRIVERS; i++) { 595 622 struct usb_class_driver* driver = &drivers[i]; 623 + const uint8_t conf_index = driver->config - 1; 596 624 597 625 if(!driver->enabled) { 598 626 continue; ··· 611 639 continue; 612 640 } 613 641 /* free check */ 614 - struct ep_alloc_state* alloc = &ep_alloc_states[0][epnum]; 642 + struct ep_alloc_state* alloc = &ep_alloc_states[conf_index][epnum]; 615 643 if(alloc->owner[req->dir] != NULL) { 616 644 continue; 617 645 } ··· 650 678 const uint8_t epnum = EP_NUM(ep); 651 679 const uint8_t epdir = EP_DIR(ep); 652 680 const uint8_t dir = epdir == USB_DIR_OUT ? DIR_OUT : DIR_IN; 653 - ep_alloc_states[0][epnum].owner[dir] = NULL; 681 + ep_alloc_states[conf_index][epnum].owner[dir] = NULL; 654 682 } 655 683 break; 656 684 } ··· 661 689 } 662 690 663 691 /* assign interfaces */ 664 - driver->first_interface = interface; 665 - interface = driver->set_first_interface(interface); 666 - driver->last_interface = interface; 692 + driver->first_interface = interface[conf_index]; 693 + interface[conf_index] = driver->set_first_interface(interface[conf_index]); 694 + driver->last_interface = interface[conf_index]; 667 695 } 668 696 669 - usb_core_num_interfaces = interface; 697 + memcpy(usb_core_num_interfaces, interface, sizeof(interface)); 670 698 } 671 699 672 700 ··· 676 704 bool handled = false; 677 705 678 706 for(i = 0; i < USB_NUM_DRIVERS; i++) { 679 - if(drivers[i].enabled && 680 - drivers[i].control_request && 681 - drivers[i].first_interface <= interface && 682 - drivers[i].last_interface > interface) { 683 - /* Check for SET_INTERFACE and GET_INTERFACE */ 684 - if((req->bRequestType & USB_RECIP_MASK) == USB_RECIP_INTERFACE && 685 - (req->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { 707 + struct usb_class_driver* driver = &drivers[i]; 708 + if(!is_active(*driver) || !has_if(*driver, interface) || driver->control_request == NULL) { 709 + continue; 710 + } 686 711 687 - if(req->bRequest == USB_REQ_SET_INTERFACE) { 688 - logf("usb_core: SET INTERFACE 0x%x 0x%x", req->wValue, req->wIndex); 689 - if(drivers[i].set_interface && 690 - drivers[i].set_interface(req->wIndex, req->wValue) >= 0) { 691 - 692 - usb_drv_control_response(USB_CONTROL_ACK, NULL, 0); 693 - handled = true; 694 - } 695 - break; 712 + /* Check for SET_INTERFACE and GET_INTERFACE */ 713 + if((req->bRequestType & USB_RECIP_MASK) == USB_RECIP_INTERFACE && 714 + (req->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { 715 + if(req->bRequest == USB_REQ_SET_INTERFACE) { 716 + logf("usb_core: SET INTERFACE 0x%x 0x%x", req->wValue, req->wIndex); 717 + if(driver->set_interface && driver->set_interface(req->wIndex, req->wValue) >= 0) { 718 + usb_drv_control_response(USB_CONTROL_ACK, NULL, 0); 719 + handled = true; 696 720 } 697 - else if(req->bRequest == USB_REQ_GET_INTERFACE) { 698 - int alt = -1; 699 - logf("usb_core: GET INTERFACE 0x%x", req->wIndex); 721 + break; 722 + } else if(req->bRequest == USB_REQ_GET_INTERFACE) { 723 + int alt = -1; 724 + logf("usb_core: GET INTERFACE 0x%x", req->wIndex); 700 725 701 - if(drivers[i].get_interface) 702 - alt = drivers[i].get_interface(req->wIndex); 726 + if(drivers[i].get_interface) 727 + alt = drivers[i].get_interface(req->wIndex); 703 728 704 - if(alt >= 0 && alt < 255) { 705 - response_data[0] = alt; 706 - usb_drv_control_response(USB_CONTROL_ACK, response_data, 1); 707 - handled = true; 708 - } 709 - break; 729 + if(alt >= 0 && alt < 255) { 730 + response_data[0] = alt; 731 + usb_drv_control_response(USB_CONTROL_ACK, response_data, 1); 732 + handled = true; 710 733 } 711 - /* fallback */ 734 + break; 712 735 } 713 - 714 - handled = drivers[i].control_request(req, reqdata, response_data); 715 - break; /* no other driver can handle it because it's interface specific */ 716 736 } 737 + 738 + handled = driver->control_request(req, reqdata, response_data); 739 + break; /* no other driver can handle it because it's interface specific */ 717 740 } 718 741 if(!handled) { 719 742 /* nope. flag error */ ··· 728 751 int size; 729 752 const void* ptr = NULL; 730 753 int length = req->wLength; 754 + int type = req->wValue >> 8; 731 755 int index = req->wValue & 0xff; 732 756 733 - switch(req->wValue >> 8) { /* type */ 757 + switch(type) { 734 758 case USB_DT_DEVICE: 735 759 ptr = &device_descriptor; 736 760 size = sizeof(struct usb_device_descriptor); ··· 738 762 739 763 case USB_DT_OTHER_SPEED_CONFIG: 740 764 case USB_DT_CONFIG: { 741 - int i, max_packet_size; 765 + if(index > NUM_CONFIGS) { 766 + logf("invalid config dt index %u", index); 767 + break; 768 + } 769 + int i, max_packet_size; 742 770 743 - if(req->wValue>>8==USB_DT_CONFIG) { 744 - max_packet_size = (usb_drv_port_speed() ? 512 : 64); 745 - config_descriptor.bDescriptorType = USB_DT_CONFIG; 746 - } 747 - else { 748 - max_packet_size=(usb_drv_port_speed() ? 64 : 512); 749 - config_descriptor.bDescriptorType = 750 - USB_DT_OTHER_SPEED_CONFIG; 751 - } 771 + if(type == USB_DT_CONFIG) { 772 + max_packet_size = (usb_drv_port_speed() ? 512 : 64); 773 + config_descriptor.bDescriptorType = USB_DT_CONFIG; 774 + } 775 + else { 776 + max_packet_size = (usb_drv_port_speed() ? 64 : 512); 777 + config_descriptor.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG; 778 + } 752 779 #ifdef HAVE_USB_CHARGING_ENABLE 753 - if (usb_charging_mode == USB_CHARGING_DISABLE) { 754 - config_descriptor.bMaxPower = (100+1)/2; 755 - usb_charging_current_requested = 100; 756 - } 757 - else { 758 - config_descriptor.bMaxPower = (500+1)/2; 759 - usb_charging_current_requested = 500; 760 - } 780 + if (usb_charging_mode == USB_CHARGING_DISABLE) { 781 + config_descriptor.bMaxPower = (100+1)/2; 782 + usb_charging_current_requested = 100; 783 + } 784 + else { 785 + config_descriptor.bMaxPower = (500+1)/2; 786 + usb_charging_current_requested = 500; 787 + } 761 788 #endif 762 - size = sizeof(struct usb_config_descriptor); 763 - 764 - for(i = 0; i < USB_NUM_DRIVERS; i++) 765 - if(drivers[i].enabled && drivers[i].get_config_descriptor) 766 - size += drivers[i].get_config_descriptor( 767 - &response_data[size], max_packet_size); 768 - 769 - config_descriptor.bNumInterfaces = usb_core_num_interfaces; 770 - config_descriptor.wTotalLength = (uint16_t)size; 771 - memcpy(&response_data[0], &config_descriptor, 772 - sizeof(struct usb_config_descriptor)); 789 + size = sizeof(struct usb_config_descriptor); 773 790 774 - ptr = response_data; 775 - break; 791 + for(i = 0; i < USB_NUM_DRIVERS; i++) { 792 + if(drivers[i].enabled && drivers[i].config == index + 1 && drivers[i].get_config_descriptor) { 793 + size += drivers[i].get_config_descriptor(&response_data[size], max_packet_size); 794 + } 776 795 } 777 796 797 + config_descriptor.bNumInterfaces = usb_core_num_interfaces[index]; 798 + config_descriptor.bConfigurationValue = index + 1; 799 + config_descriptor.wTotalLength = (uint16_t)size; 800 + memcpy(&response_data[0], &config_descriptor, sizeof(struct usb_config_descriptor)); 801 + 802 + ptr = response_data; 803 + } break; 778 804 case USB_DT_STRING: 779 805 logf("STRING %d", index); 780 806 if((unsigned)index < USB_STRING_INDEX_MAX) { ··· 826 852 usb_state = ADDRESS; 827 853 } 828 854 829 - static void usb_core_do_set_config(uint8_t config) 855 + static int usb_core_do_set_config(uint8_t new_config) 830 856 { 831 - logf("usb_core: SET_CONFIG %d",config); 857 + logf("usb_core: SET_CONFIG %d to %d", usb_config, new_config); 858 + 859 + if(new_config > NUM_CONFIGS) { 860 + logf("usb_core: invalid config number"); 861 + return -1; 862 + } 832 863 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 - } 864 + /* deactivate old config */ 865 + if(usb_config != 0) { 866 + for(int i = 0; i < USB_NUM_DRIVERS; i++) { 867 + if(is_active(drivers[i]) && drivers[i].disconnect != NULL) { 868 + drivers[i].disconnect(); 857 869 } 858 870 } 871 + init_deinit_endpoints(usb_config - 1, false); 859 872 } 860 873 861 - if(config) { 862 - usb_state = CONFIGURED; 874 + memset(ep_data, 0, sizeof(ep_data)); 875 + usb_config = new_config; 876 + usb_state = usb_config == 0 ? ADDRESS : CONFIGURED; 863 877 864 - if(drivers_connected) 865 - for(int i = 0; i < USB_NUM_DRIVERS; i++) 866 - if(drivers[i].enabled && drivers[i].disconnect != NULL) 867 - drivers[i].disconnect(); 868 - 869 - for(int i = 0; i < USB_NUM_DRIVERS; i++) 870 - if(drivers[i].enabled && drivers[i].init_connection) 878 + /* activate new config */ 879 + if(usb_config != 0) { 880 + init_deinit_endpoints(usb_config - 1, true); 881 + for(int i = 0; i < USB_NUM_DRIVERS; i++) { 882 + if(is_active(drivers[i]) && drivers[i].init_connection != NULL) { 871 883 drivers[i].init_connection(); 872 - drivers_connected = true; 884 + } 885 + } 873 886 } 874 - else 875 - usb_state = ADDRESS; 887 + 876 888 #ifdef HAVE_USB_CHARGING_ENABLE 877 889 usb_charging_maxcurrent_change(usb_charging_maxcurrent()); 878 890 #endif 891 + 892 + return 0; 879 893 } 880 894 881 895 static void usb_core_do_clear_feature(int recip, int recip_nr, int feature) ··· 895 909 switch(req->bRequest) { 896 910 case USB_REQ_GET_CONFIGURATION: 897 911 logf("usb_core: GET_CONFIG"); 898 - response_data[0] = (usb_state == ADDRESS ? 0 : 1); 912 + response_data[0] = usb_config; 899 913 usb_drv_control_response(USB_CONTROL_ACK, response_data, 1); 900 914 break; 901 915 case USB_REQ_SET_CONFIGURATION: 902 916 usb_drv_cancel_all_transfers(); 903 - usb_core_do_set_config(req->wValue); 904 - usb_drv_control_response(USB_CONTROL_ACK, NULL, 0); 917 + if(usb_core_do_set_config(req->wValue) == 0) { 918 + usb_drv_control_response(USB_CONTROL_ACK, NULL, 0); 919 + } else { 920 + usb_drv_control_response(USB_CONTROL_STALL, NULL, 0); 921 + } 905 922 break; 906 923 case USB_REQ_SET_ADDRESS: 907 924 /* NOTE: We really have no business handling this and drivers ··· 946 963 logf("usb_core: SET_INTERFACE"); 947 964 case USB_REQ_GET_INTERFACE: 948 965 control_request_handler_drivers(req, reqdata); 949 - break; 950 966 break; 951 967 case USB_REQ_GET_STATUS: 952 968 response_data[0] = 0; ··· 1091 1107 logf("usb_core: bus reset"); 1092 1108 usb_address = 0; 1093 1109 usb_state = DEFAULT; 1110 + if(usb_config != 0) { 1111 + for(int i = 0; i < USB_NUM_DRIVERS; i++) { 1112 + if(is_active(drivers[i]) && drivers[i].disconnect != NULL) { 1113 + drivers[i].disconnect(); 1114 + } 1115 + } 1116 + init_deinit_endpoints(usb_config - 1, false); 1117 + usb_config = 0; 1118 + } 1094 1119 #ifdef HAVE_USB_CHARGING_ENABLE 1095 1120 #ifdef HAVE_USB_CHARGING_IN_THREAD 1096 1121 /* On some targets usb_charging_maxcurrent_change() cannot be called