Changes in uspace/lib/usbhost/src/iface.c [ef40434:77ad86c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/iface.c
ref40434 r77ad86c 40 40 #include <usb/host/endpoint.h> 41 41 #include <usb/host/hcd.h> 42 #include "ddf_helpers.h" 42 43 /** Prepare generic usb_transfer_batch and schedule it. 44 * @param fun DDF fun 45 * @param target address and endpoint number. 46 * @param setup_data Data to use in setup stage (Control communication type) 47 * @param in Callback for device to host communication. 48 * @param out Callback for host to device communication. 49 * @param arg Callback parameter. 50 * @param name Communication identifier (for nicer output). 51 * @return Error code. 52 */ 53 static inline int send_batch( 54 ddf_fun_t *fun, usb_target_t target, usb_direction_t direction, 55 void *data, size_t size, uint64_t setup_data, 56 usbhc_iface_transfer_in_callback_t in, 57 usbhc_iface_transfer_out_callback_t out, void *arg, const char* name) 58 { 59 assert(fun); 60 hcd_t *hcd = fun_to_hcd(fun); 61 assert(hcd); 62 63 endpoint_t *ep = usb_endpoint_manager_find_ep(&hcd->ep_manager, 64 target.address, target.endpoint, direction); 65 if (ep == NULL) { 66 usb_log_error("Endpoint(%d:%d) not registered for %s.\n", 67 target.address, target.endpoint, name); 68 return ENOENT; 69 } 70 71 usb_log_debug2("%s %d:%d %zu(%zu).\n", 72 name, target.address, target.endpoint, size, ep->max_packet_size); 73 74 const size_t bw = bandwidth_count_usb11( 75 ep->speed, ep->transfer_type, size, ep->max_packet_size); 76 /* Check if we have enough bandwidth reserved */ 77 if (ep->bandwidth < bw) { 78 usb_log_error("Endpoint(%d:%d) %s needs %zu bw " 79 "but only %zu is reserved.\n", 80 ep->address, ep->endpoint, name, bw, ep->bandwidth); 81 return ENOSPC; 82 } 83 if (!hcd->schedule) { 84 usb_log_error("HCD does not implement scheduler.\n"); 85 return ENOTSUP; 86 } 87 88 /* No private data and no private data dtor */ 89 usb_transfer_batch_t *batch = 90 usb_transfer_batch_create(ep, data, size, setup_data, 91 in, out, arg, fun, NULL, NULL); 92 if (!batch) { 93 return ENOMEM; 94 } 95 96 const int ret = hcd->schedule(hcd, batch); 97 if (ret != EOK) 98 usb_transfer_batch_destroy(batch); 99 100 return ret; 101 } 102 103 /** Calls ep_add_hook upon endpoint registration. 104 * @param ep Endpoint to be registered. 105 * @param arg hcd_t in disguise. 106 * @return Error code. 107 */ 108 static int register_helper(endpoint_t *ep, void *arg) 109 { 110 hcd_t *hcd = arg; 111 assert(ep); 112 assert(hcd); 113 if (hcd->ep_add_hook) 114 return hcd->ep_add_hook(hcd, ep); 115 return EOK; 116 } 117 118 /** Calls ep_remove_hook upon endpoint removal. 119 * @param ep Endpoint to be unregistered. 120 * @param arg hcd_t in disguise. 121 */ 122 static void unregister_helper(endpoint_t *ep, void *arg) 123 { 124 hcd_t *hcd = arg; 125 assert(ep); 126 assert(hcd); 127 if (hcd->ep_remove_hook) 128 hcd->ep_remove_hook(hcd, ep); 129 } 130 131 /** Calls ep_remove_hook upon endpoint removal. Prints warning. 132 * @param ep Endpoint to be unregistered. 133 * @param arg hcd_t in disguise. 134 */ 135 static void unregister_helper_warn(endpoint_t *ep, void *arg) 136 { 137 hcd_t *hcd = arg; 138 assert(ep); 139 assert(hcd); 140 usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n", 141 ep->address, ep->endpoint, usb_str_direction(ep->direction)); 142 if (hcd->ep_remove_hook) 143 hcd->ep_remove_hook(hcd, ep); 144 } 145 146 /** Request address interface function. 147 * 148 * @param[in] fun DDF function that was called. 149 * @param[in] address Pointer to preferred USB address. 150 * @param[out] address Place to write a new address. 151 * @param[in] strict Fail if the preferred address is not available. 152 * @param[in] speed Speed to associate with the new default address. 153 * @return Error code. 154 */ 155 static int request_address( 156 ddf_fun_t *fun, usb_address_t *address, bool strict, usb_speed_t speed) 157 { 158 assert(fun); 159 hcd_t *hcd = fun_to_hcd(fun); 160 assert(hcd); 161 assert(address); 162 163 usb_log_debug("Address request: speed: %s, address: %d, strict: %s.\n", 164 usb_str_speed(speed), *address, strict ? "YES" : "NO"); 165 return usb_device_manager_request_address( 166 &hcd->dev_manager, address, strict, speed); 167 } 168 169 /** Bind address interface function. 170 * 171 * @param[in] fun DDF function that was called. 172 * @param[in] address Address of the device 173 * @param[in] handle Devman handle of the device driver. 174 * @return Error code. 175 */ 176 static int bind_address( 177 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle) 178 { 179 assert(fun); 180 hcd_t *hcd = fun_to_hcd(fun); 181 assert(hcd); 182 183 usb_log_debug("Address bind %d-%" PRIun ".\n", address, handle); 184 return usb_device_manager_bind_address( 185 &hcd->dev_manager, address, handle); 186 } 43 187 44 188 /** Find device handle by address interface function. … … 53 197 { 54 198 assert(fun); 55 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));199 hcd_t *hcd = fun_to_hcd(fun); 56 200 assert(hcd); 57 201 return usb_device_manager_get_info_by_address( 58 202 &hcd->dev_manager, address, handle, NULL); 203 } 204 205 /** Release address interface function. 206 * 207 * @param[in] fun DDF function that was called. 208 * @param[in] address USB address to be released. 209 * @return Error code. 210 */ 211 static int release_address(ddf_fun_t *fun, usb_address_t address) 212 { 213 assert(fun); 214 hcd_t *hcd = fun_to_hcd(fun); 215 assert(hcd); 216 usb_log_debug("Address release %d.\n", address); 217 usb_device_manager_release_address(&hcd->dev_manager, address); 218 usb_endpoint_manager_remove_address(&hcd->ep_manager, address, 219 unregister_helper_warn, hcd); 220 return EOK; 59 221 } 60 222 … … 75 237 { 76 238 assert(fun); 77 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));239 hcd_t *hcd = fun_to_hcd(fun); 78 240 assert(hcd); 79 241 const size_t size = max_packet_size; 80 const usb_target_t target = {{.address = address, .endpoint = endpoint}}; 81 82 usb_log_debug("Register endpoint %d:%d %s-%s %zuB %ums.\n", 242 usb_speed_t speed = USB_SPEED_MAX; 243 const int ret = usb_device_manager_get_info_by_address( 244 &hcd->dev_manager, address, NULL, &speed); 245 if (ret != EOK) { 246 return ret; 247 } 248 249 usb_log_debug("Register endpoint %d:%d %s-%s %s %zuB %ums.\n", 83 250 address, endpoint, usb_str_transfer_type(transfer_type), 84 usb_str_direction(direction), max_packet_size, interval); 85 86 return hcd_add_ep(hcd, target, direction, transfer_type, 87 max_packet_size, size); 251 usb_str_direction(direction), usb_str_speed(speed), 252 max_packet_size, interval); 253 254 return usb_endpoint_manager_add_ep(&hcd->ep_manager, address, endpoint, 255 direction, transfer_type, speed, max_packet_size, size, 256 register_helper, hcd); 88 257 } 89 258 … … 100 269 { 101 270 assert(fun); 102 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 103 assert(hcd); 104 const usb_target_t target = {{.address = address, .endpoint = endpoint}}; 271 hcd_t *hcd = fun_to_hcd(fun); 272 assert(hcd); 105 273 usb_log_debug("Unregister endpoint %d:%d %s.\n", 106 274 address, endpoint, usb_str_direction(direction)); 107 return hcd_remove_ep(hcd, target, direction); 275 return usb_endpoint_manager_remove_ep(&hcd->ep_manager, address, 276 endpoint, direction, unregister_helper, hcd); 108 277 } 109 278 … … 122 291 void *arg) 123 292 { 124 return hcd_send_batch(dev_to_hcd(ddf_fun_get_dev(fun)), target, 125 USB_DIRECTION_IN, data, size, setup_data, callback, NULL, arg, 126 "READ"); 293 return send_batch(fun, target, USB_DIRECTION_IN, data, size, 294 setup_data, callback, NULL, arg, "READ"); 127 295 } 128 296 … … 141 309 usbhc_iface_transfer_out_callback_t callback, void *arg) 142 310 { 143 return hcd_send_batch(dev_to_hcd(ddf_fun_get_dev(fun)), 144 target, USB_DIRECTION_OUT, (uint8_t*)data, size, setup_data, NULL, 145 callback, arg, "WRITE"); 311 return send_batch(fun, target, USB_DIRECTION_OUT, (uint8_t*)data, size, 312 setup_data, NULL, callback, arg, "WRITE"); 146 313 } 147 314 148 315 /** usbhc Interface implementation using hcd_t from libusbhost library. */ 149 316 usbhc_iface_t hcd_iface = { 317 .request_address = request_address, 318 .bind_address = bind_address, 150 319 .get_handle = find_by_address, 320 .release_address = release_address, 151 321 152 322 .register_endpoint = register_endpoint,
Note:
See TracChangeset
for help on using the changeset viewer.