Changeset 41924f30 in mainline for uspace/lib/usbhost/src
- Timestamp:
- 2017-10-12T14:07:27Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a5976973
- Parents:
- 7e74911
- Location:
- uspace/lib/usbhost/src
- Files:
-
- 3 added
- 1 deleted
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/ddf_helpers.c
r7e74911 r41924f30 469 469 470 470 /* This checks whether the default address is reserved and gets speed */ 471 int ret = usb_bus_get_speed(&hcd->bus, USB_ADDRESS_DEFAULT, &speed);471 int ret = bus_get_speed(hcd->bus, USB_ADDRESS_DEFAULT, &speed); 472 472 if (ret != EOK) { 473 473 usb_log_error("Failed to verify speed: %s.", str_error(ret)); … … 623 623 assert(hcd); 624 624 625 hcd_reserve_default_address(hcd, hcd->bus.max_speed);625 hcd_reserve_default_address(hcd, USB_SPEED_MAX); 626 626 const int ret = hcd_ddf_new_device(device, NULL, 0); 627 627 hcd_release_default_address(hcd); … … 639 639 * This function does all the ddf work for hc driver. 640 640 */ 641 int hcd_ddf_setup_hc(ddf_dev_t *device, usb_speed_t max_speed, 642 size_t bw, bw_count_func_t bw_count) 641 int hcd_ddf_setup_hc(ddf_dev_t *device) 643 642 { 644 643 assert(device); … … 650 649 } 651 650 instance->root_hub = NULL; 652 hcd_init(&instance->hcd , max_speed, bw, bw_count);651 hcd_init(&instance->hcd); 653 652 654 653 int ret = ENOMEM; … … 851 850 { 852 851 assert(driver); 853 static const struct { size_t bw; bw_count_func_t bw_count; }bw[] = {854 [USB_SPEED_FULL] = { .bw = BANDWIDTH_AVAILABLE_USB11,855 .bw_count = bandwidth_count_usb11 },856 [USB_SPEED_HIGH] = { .bw = BANDWIDTH_AVAILABLE_USB11,857 .bw_count = bandwidth_count_usb11 },858 [USB_SPEED_SUPER] = { .bw = BANDWIDTH_AVAILABLE_USB11,859 .bw_count = bandwidth_count_usb11 },860 };861 852 862 853 int ret = EOK; 863 const usb_speed_t speed = driver->hc_speed;864 if (speed >= ARRAY_SIZE(bw) || bw[speed].bw == 0) {865 usb_log_error("Driver `%s' reported unsupported speed: %s",866 driver->name, usb_str_speed(speed));867 return ENOTSUP;868 }869 854 870 855 hw_res_list_parsed_t hw_res; … … 877 862 } 878 863 879 ret = hcd_ddf_setup_hc(device , speed, bw[speed].bw, bw[speed].bw_count);864 ret = hcd_ddf_setup_hc(device); 880 865 if (ret != EOK) { 881 866 usb_log_error("Failed to setup generic HCD.\n"); -
uspace/lib/usbhost/src/endpoint.c
r7e74911 r41924f30 1 1 /* 2 2 * Copyright (c) 2011 Jan Vesely 3 * Copyright (c) 2017 Ondrej Hlavaty <aearsis@eideo.cz> 3 4 * All rights reserved. 4 5 * … … 35 36 36 37 #include <usb/host/endpoint.h> 38 #include <usb/host/bus.h> 37 39 38 40 #include <assert.h> 41 #include <atomic.h> 42 #include <mem.h> 39 43 #include <stdlib.h> 40 #include <atomic.h>41 44 42 /** Allocate ad initialize endpoint_t structure. 43 * @param address USB address. 44 * @param endpoint USB endpoint number. 45 * @param direction Communication direction. 46 * @param type USB transfer type. 47 * @param speed Communication speed. 48 * @param max_packet_size Maximum size of data packets. 49 * @param bw Required bandwidth. 50 * @return Pointer to initialized endpoint_t structure, NULL on failure. 45 /** Initialize provided endpoint structure. 51 46 */ 52 endpoint_t * endpoint_create(usb_address_t address, usb_endpoint_t endpoint, 53 usb_direction_t direction, usb_transfer_type_t type, usb_speed_t speed, 54 size_t max_packet_size, unsigned packets, size_t bw, 55 usb_address_t tt_address, unsigned tt_p) 47 void endpoint_init(endpoint_t *ep, bus_t *bus) 56 48 { 57 endpoint_t *instance = malloc(sizeof(endpoint_t)); 58 if (instance) { 59 atomic_set(&instance->refcnt, 0); 60 instance->address = address; 61 instance->endpoint = endpoint; 62 instance->direction = direction; 63 instance->transfer_type = type; 64 instance->speed = speed; 65 instance->max_packet_size = max_packet_size; 66 instance->packets = packets; 67 instance->bandwidth = bw; 68 instance->toggle = 0; 69 instance->active = false; 70 instance->tt.address = tt_address; 71 instance->tt.port = tt_p; 72 instance->hc_data.data = NULL; 73 instance->hc_data.toggle_get = NULL; 74 instance->hc_data.toggle_set = NULL; 75 link_initialize(&instance->link); 76 fibril_mutex_initialize(&instance->guard); 77 fibril_condvar_initialize(&instance->avail); 78 } 79 return instance; 49 memset(ep, 0, sizeof(endpoint_t)); 50 51 ep->bus = bus; 52 atomic_set(&ep->refcnt, 0); 53 link_initialize(&ep->link); 54 fibril_mutex_initialize(&ep->guard); 55 fibril_condvar_initialize(&ep->avail); 80 56 } 81 57 82 /** Properly dispose of endpoint_t structure. 83 * @param instance endpoint_t structure. 84 */ 85 void endpoint_destroy(endpoint_t *instance) 58 void endpoint_add_ref(endpoint_t *ep) 86 59 { 87 assert(instance); 88 assert(!instance->active); 89 assert(instance->hc_data.data == NULL); 90 free(instance); 60 atomic_inc(&ep->refcnt); 91 61 } 92 62 93 void endpoint_ add_ref(endpoint_t *instance)63 void endpoint_del_ref(endpoint_t *ep) 94 64 { 95 atomic_inc(&instance->refcnt); 96 } 65 if (atomic_predec(&ep->refcnt) == 0) { 66 if (ep->bus->ops.destroy_endpoint) { 67 ep->bus->ops.destroy_endpoint(ep); 68 } 69 else { 70 assert(!ep->active); 97 71 98 void endpoint_del_ref(endpoint_t *instance) 99 { 100 if (atomic_predec(&instance->refcnt) == 0) 101 endpoint_destroy(instance); 102 } 103 104 /** Set device specific data and hooks. 105 * @param instance endpoint_t structure. 106 * @param data device specific data. 107 * @param toggle_get Hook to call when retrieving value of toggle bit. 108 * @param toggle_set Hook to call when setting the value of toggle bit. 109 */ 110 void endpoint_set_hc_data(endpoint_t *instance, 111 void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int)) 112 { 113 assert(instance); 114 fibril_mutex_lock(&instance->guard); 115 instance->hc_data.data = data; 116 instance->hc_data.toggle_get = toggle_get; 117 instance->hc_data.toggle_set = toggle_set; 118 fibril_mutex_unlock(&instance->guard); 119 } 120 121 /** Clear device specific data and hooks. 122 * @param instance endpoint_t structure. 123 * @note This function does not free memory pointed to by data pointer. 124 */ 125 void endpoint_clear_hc_data(endpoint_t *instance) 126 { 127 assert(instance); 128 endpoint_set_hc_data(instance, NULL, NULL, NULL); 72 /* Assume mostly the eps will be allocated by malloc. */ 73 free(ep); 74 } 75 } 129 76 } 130 77 131 78 /** Mark the endpoint as active and block access for further fibrils. 132 * @param instanceendpoint_t structure.79 * @param ep endpoint_t structure. 133 80 */ 134 void endpoint_use(endpoint_t * instance)81 void endpoint_use(endpoint_t *ep) 135 82 { 136 assert( instance);83 assert(ep); 137 84 /* Add reference for active endpoint. */ 138 endpoint_add_ref( instance);139 fibril_mutex_lock(& instance->guard);140 while ( instance->active)141 fibril_condvar_wait(& instance->avail, &instance->guard);142 instance->active = true;143 fibril_mutex_unlock(& instance->guard);85 endpoint_add_ref(ep); 86 fibril_mutex_lock(&ep->guard); 87 while (ep->active) 88 fibril_condvar_wait(&ep->avail, &ep->guard); 89 ep->active = true; 90 fibril_mutex_unlock(&ep->guard); 144 91 } 145 92 146 93 /** Mark the endpoint as inactive and allow access for further fibrils. 147 * @param instanceendpoint_t structure.94 * @param ep endpoint_t structure. 148 95 */ 149 void endpoint_release(endpoint_t * instance)96 void endpoint_release(endpoint_t *ep) 150 97 { 151 assert( instance);152 fibril_mutex_lock(& instance->guard);153 instance->active = false;154 fibril_mutex_unlock(& instance->guard);155 fibril_condvar_signal(& instance->avail);98 assert(ep); 99 fibril_mutex_lock(&ep->guard); 100 ep->active = false; 101 fibril_mutex_unlock(&ep->guard); 102 fibril_condvar_signal(&ep->avail); 156 103 /* Drop reference for active endpoint. */ 157 endpoint_del_ref( instance);104 endpoint_del_ref(ep); 158 105 } 159 106 160 /** Get the value of toggle bit. 161 * @param instance endpoint_t structure.162 * @ note Will use provided hook.107 /** Get the value of toggle bit. Either uses the toggle_get op, or just returns 108 * the value of the toggle. 109 * @param ep endpoint_t structure. 163 110 */ 164 int endpoint_toggle_get(endpoint_t * instance)111 int endpoint_toggle_get(endpoint_t *ep) 165 112 { 166 assert(instance); 167 fibril_mutex_lock(&instance->guard); 168 if (instance->hc_data.toggle_get) 169 instance->toggle = 170 instance->hc_data.toggle_get(instance->hc_data.data); 171 const int ret = instance->toggle; 172 fibril_mutex_unlock(&instance->guard); 113 assert(ep); 114 fibril_mutex_lock(&ep->guard); 115 const int ret = ep->bus->ops.endpoint_get_toggle 116 ? ep->bus->ops.endpoint_get_toggle(ep) 117 : ep->toggle; 118 fibril_mutex_unlock(&ep->guard); 173 119 return ret; 174 120 } 175 121 176 /** Set the value of toggle bit. 177 * @param instance endpoint_t structure.178 * @ note Will use provided hook.122 /** Set the value of toggle bit. Either uses the toggle_set op, or just sets 123 * the toggle inside. 124 * @param ep endpoint_t structure. 179 125 */ 180 void endpoint_toggle_set(endpoint_t * instance, inttoggle)126 void endpoint_toggle_set(endpoint_t *ep, unsigned toggle) 181 127 { 182 assert( instance);128 assert(ep); 183 129 assert(toggle == 0 || toggle == 1); 184 fibril_mutex_lock(&instance->guard); 185 instance->toggle = toggle; 186 if (instance->hc_data.toggle_set) 187 instance->hc_data.toggle_set(instance->hc_data.data, toggle); 188 fibril_mutex_unlock(&instance->guard); 130 fibril_mutex_lock(&ep->guard); 131 if (ep->bus->ops.endpoint_set_toggle) { 132 ep->bus->ops.endpoint_set_toggle(ep, toggle); 133 } 134 else { 135 ep->toggle = toggle; 136 } 137 fibril_mutex_unlock(&ep->guard); 189 138 } 139 190 140 191 141 /** -
uspace/lib/usbhost/src/hcd.c
r7e74911 r41924f30 44 44 #include "hcd.h" 45 45 46 /** Calls ep_add_hook upon endpoint registration. 46 47 /*[>* Calls ep_add_hook upon endpoint registration. 47 48 * @param ep Endpoint to be registered. 48 49 * @param arg hcd_t in disguise. 49 50 * @return Error code. 50 */ 51 * OH TODO: remove 52 <] 51 53 static int register_helper(endpoint_t *ep, void *arg) 52 54 { … … 59 61 } 60 62 61 /** Calls ep_remove_hook upon endpoint removal.63 [>* Calls ep_remove_hook upon endpoint removal. 62 64 * @param ep Endpoint to be unregistered. 63 65 * @param arg hcd_t in disguise. 64 */ 66 * OH TODO: remove 67 <] 65 68 static void unregister_helper(endpoint_t *ep, void *arg) 66 69 { … … 72 75 } 73 76 74 /** Calls ep_remove_hook upon endpoint removal. Prints warning.77 [>* Calls ep_remove_hook upon endpoint removal. Prints warning. 75 78 * * @param ep Endpoint to be unregistered. 76 79 * * @param arg hcd_t in disguise. 77 * */ 80 * OH TODO: remove 81 * <] 78 82 static void unregister_helper_warn(endpoint_t *ep, void *arg) 79 83 { 80 84 assert(ep); 81 85 usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n", 82 ep-> address, ep->endpoint, usb_str_direction(ep->direction));86 ep->target.address, ep->target.endpoint, usb_str_direction(ep->direction)); 83 87 unregister_helper(ep, arg); 84 88 } 85 89 */ 86 90 87 91 /** Initialize hcd_t structure. … … 93 97 * @param bw_count Bandwidth compute function, passed to endpoint manager. 94 98 */ 95 void hcd_init(hcd_t *hcd, usb_speed_t max_speed, size_t bandwidth, 96 bw_count_func_t bw_count) 97 { 98 assert(hcd); 99 usb_bus_init(&hcd->bus, bandwidth, bw_count, max_speed); 100 101 hcd_set_implementation(hcd, NULL, NULL); 99 void hcd_init(hcd_t *hcd) { 100 assert(hcd); 101 102 hcd_set_implementation(hcd, NULL, NULL, NULL); 102 103 } 103 104 … … 106 107 assert(hcd); 107 108 usb_address_t address = 0; 108 const int ret = usb_bus_request_address( 109 &hcd->bus, &address, false, speed); 109 const int ret = bus_request_address(hcd->bus, &address, false, speed); 110 110 if (ret != EOK) 111 111 return ret; … … 116 116 { 117 117 assert(hcd); 118 return usb_bus_remove_address(&hcd->bus, address,119 unregister_helper_warn, hcd);118 return bus_release_address(hcd->bus, address); 119 // OH TODO removed helper 120 120 } 121 121 … … 124 124 assert(hcd); 125 125 usb_address_t address = 0; 126 return usb_bus_request_address(&hcd->bus, &address, true, speed);126 return bus_request_address(hcd->bus, &address, true, speed); 127 127 } 128 128 … … 132 132 { 133 133 assert(hcd); 134 return usb_bus_add_ep(&hcd->bus, target.address, 135 target.endpoint, dir, type, max_packet_size, packets, size, 136 register_helper, hcd, tt_address, tt_port); 134 135 /* Temporary reference */ 136 endpoint_t *ep = bus_create_endpoint(hcd->bus); 137 if (!ep) 138 return ENOMEM; 139 140 ep->target = target; 141 ep->direction = dir; 142 ep->transfer_type = type; 143 ep->max_packet_size = max_packet_size; 144 ep->packets = packets; 145 146 ep->tt.address = tt_address; 147 ep->tt.port = tt_port; 148 149 const int err = bus_register_endpoint(hcd->bus, ep); 150 151 /* drop Temporary reference */ 152 endpoint_del_ref(ep); 153 154 return err; 137 155 } 138 156 … … 140 158 { 141 159 assert(hcd); 142 return usb_bus_remove_ep(&hcd->bus, target.address, 143 target.endpoint, dir, unregister_helper, hcd); 160 endpoint_t *ep = bus_find_endpoint(hcd->bus, target, dir); 161 if (!ep) 162 return ENOENT; 163 164 return bus_release_endpoint(hcd->bus, ep); 165 // OH TODO removed helper 144 166 } 145 167 … … 159 181 usb_log_debug2("Reseting toggle on %d:%d.\n", 160 182 toggle->target.address, toggle->target.endpoint); 161 usb_bus_reset_toggle(&toggle->hcd->bus,183 bus_reset_toggle(toggle->hcd->bus, 162 184 toggle->target, toggle->target.endpoint == 0); 163 185 } … … 185 207 assert(hcd); 186 208 187 endpoint_t *ep = usb_bus_find_ep(&hcd->bus, 188 target.address, target.endpoint, direction); 209 endpoint_t *ep = bus_find_endpoint(hcd->bus, target, direction); 189 210 if (ep == NULL) { 190 211 usb_log_error("Endpoint(%d:%d) not registered for %s.\n", … … 196 217 name, target.address, target.endpoint, size, ep->max_packet_size); 197 218 198 const size_t bw = bandwidth_count_usb11( 199 ep->speed, ep->transfer_type, size, ep->max_packet_size); 219 const size_t bw = bus_count_bw(ep, size); 200 220 /* Check if we have enough bandwidth reserved */ 201 221 if (ep->bandwidth < bw) { 202 222 usb_log_error("Endpoint(%d:%d) %s needs %zu bw " 203 223 "but only %zu is reserved.\n", 204 ep-> address, ep->endpoint, name, bw, ep->bandwidth);224 ep->target.address, ep->target.endpoint, name, bw, ep->bandwidth); 205 225 return ENOSPC; 206 226 }
Note:
See TracChangeset
for help on using the changeset viewer.