Changes in uspace/lib/usbhost/src/iface.c [8b54fe6:77ad86c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/iface.c
r8b54fe6 r77ad86c 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 /** @addtogroup libusbhost 29 30 * @{ … … 32 33 * @brief HCD DDF interface implementation 33 34 */ 35 34 36 #include <ddf/driver.h> 35 37 #include <errno.h> … … 39 41 #include <usb/host/hcd.h> 40 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 */ 41 53 static inline int send_batch( 42 54 ddf_fun_t *fun, usb_target_t target, usb_direction_t direction, … … 49 61 assert(hcd); 50 62 51 int ret; 52 53 size_t res_bw; 54 endpoint_t *ep = usb_endpoint_manager_get_ep(&hcd->ep_manager, 55 target.address, target.endpoint, direction, &res_bw); 63 endpoint_t *ep = usb_endpoint_manager_find_ep(&hcd->ep_manager, 64 target.address, target.endpoint, direction); 56 65 if (ep == NULL) { 57 66 usb_log_error("Endpoint(%d:%d) not registered for %s.\n", … … 65 74 const size_t bw = bandwidth_count_usb11( 66 75 ep->speed, ep->transfer_type, size, ep->max_packet_size); 67 if (res_bw < bw) { 76 /* Check if we have enough bandwidth reserved */ 77 if (ep->bandwidth < bw) { 68 78 usb_log_error("Endpoint(%d:%d) %s needs %zu bw " 69 79 "but only %zu is reserved.\n", 70 target.address, target.endpoint, name, bw, res_bw);80 ep->address, ep->endpoint, name, bw, ep->bandwidth); 71 81 return ENOSPC; 72 82 } … … 78 88 /* No private data and no private data dtor */ 79 89 usb_transfer_batch_t *batch = 80 usb_transfer_batch_ get(ep, data, size, setup_data,90 usb_transfer_batch_create(ep, data, size, setup_data, 81 91 in, out, arg, fun, NULL, NULL); 82 92 if (!batch) { … … 84 94 } 85 95 86 ret = hcd->schedule(hcd, batch);96 const int ret = hcd->schedule(hcd, batch); 87 97 if (ret != EOK) 88 usb_transfer_batch_d ispose(batch);98 usb_transfer_batch_destroy(batch); 89 99 90 100 return ret; 91 101 } 92 /*----------------------------------------------------------------------------*/ 93 /** Request address interface function 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. 94 147 * 95 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. 96 152 * @param[in] speed Speed to associate with the new default address. 97 * @param[out] address Place to write a new address.98 153 * @return Error code. 99 154 */ 100 155 static int request_address( 101 ddf_fun_t *fun, usb_ speed_t speed, usb_address_t *address)156 ddf_fun_t *fun, usb_address_t *address, bool strict, usb_speed_t speed) 102 157 { 103 158 assert(fun); … … 106 161 assert(address); 107 162 108 usb_log_debug("Address request speed: %s.\n", usb_str_speed(speed)); 109 *address = 110 usb_device_manager_get_free_address(&hcd->dev_manager, speed); 111 usb_log_debug("Address request with result: %d.\n", *address); 112 if (*address <= 0) 113 return *address; 114 return EOK; 115 } 116 /*----------------------------------------------------------------------------*/ 117 /** Bind address interface function 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. 118 170 * 119 171 * @param[in] fun DDF function that was called. … … 123 175 */ 124 176 static int bind_address( 125 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)177 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle) 126 178 { 127 179 assert(fun); … … 130 182 131 183 usb_log_debug("Address bind %d-%" PRIun ".\n", address, handle); 132 usb_device_manager_bind(&hcd->dev_manager, address, handle);133 return EOK;134 } 135 /*----------------------------------------------------------------------------*/ 184 return usb_device_manager_bind_address( 185 &hcd->dev_manager, address, handle); 186 } 187 136 188 /** Find device handle by address interface function. 137 189 * … … 147 199 hcd_t *hcd = fun_to_hcd(fun); 148 200 assert(hcd); 149 const bool found = 150 usb_device_manager_find_by_address(&hcd->dev_manager, address, handle); 151 return found ? EOK : ENOENT; 152 } 153 /*----------------------------------------------------------------------------*/ 154 /** Release address interface function 201 return usb_device_manager_get_info_by_address( 202 &hcd->dev_manager, address, handle, NULL); 203 } 204 205 /** Release address interface function. 155 206 * 156 207 * @param[in] fun DDF function that was called. … … 164 215 assert(hcd); 165 216 usb_log_debug("Address release %d.\n", address); 166 usb_device_manager_release(&hcd->dev_manager, 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); 167 220 return EOK; 168 221 } 169 /*----------------------------------------------------------------------------*/ 222 223 /** Register endpoint interface function. 224 * @param fun DDF function. 225 * @param address USB address of the device. 226 * @param endpoint USB endpoint number to be registered. 227 * @param transfer_type Endpoint's transfer type. 228 * @param direction USB communication direction the endpoint is capable of. 229 * @param max_packet_size Maximu size of packets the endpoint accepts. 230 * @param interval Preferred timeout between communication. 231 * @return Error code. 232 */ 170 233 static int register_endpoint( 171 ddf_fun_t *fun, usb_address_t address, usb_speed_t ep_speed, 172 usb_endpoint_t endpoint, 234 ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint, 173 235 usb_transfer_type_t transfer_type, usb_direction_t direction, 174 size_t max_packet_size, unsigned int interval)236 size_t max_packet_size, unsigned interval) 175 237 { 176 238 assert(fun); … … 178 240 assert(hcd); 179 241 const size_t size = max_packet_size; 180 /* Default address is not bound or registered, 181 * thus it does not provide speed info. */ 182 const usb_speed_t speed = (address == 0) ? ep_speed : 183 usb_device_manager_get_speed(&hcd->dev_manager, address); 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 } 184 248 185 249 usb_log_debug("Register endpoint %d:%d %s-%s %s %zuB %ums.\n", … … 188 252 max_packet_size, interval); 189 253 190 endpoint_t *ep = endpoint_get( 191 address, endpoint, direction, transfer_type, speed, max_packet_size); 192 if (!ep) 193 return ENOMEM; 194 int ret = EOK; 195 196 if (hcd->ep_add_hook) { 197 ret = hcd->ep_add_hook(hcd, ep); 198 } 199 if (ret != EOK) { 200 endpoint_destroy(ep); 201 return ret; 202 } 203 204 ret = usb_endpoint_manager_register_ep(&hcd->ep_manager, ep, size); 205 if (ret != EOK) { 206 endpoint_destroy(ep); 207 } 208 return ret; 209 } 210 /*----------------------------------------------------------------------------*/ 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); 257 } 258 259 /** Unregister endpoint interface function. 260 * @param fun DDF function. 261 * @param address USB address of the endpoint. 262 * @param endpoint USB endpoint number. 263 * @param direction Communication direction of the enpdoint to unregister. 264 * @return Error code. 265 */ 211 266 static int unregister_endpoint( 212 267 ddf_fun_t *fun, usb_address_t address, … … 218 273 usb_log_debug("Unregister endpoint %d:%d %s.\n", 219 274 address, endpoint, usb_str_direction(direction)); 220 return usb_endpoint_manager_unregister_ep(&hcd->ep_manager, address, 221 endpoint, direction); 222 } 223 /*----------------------------------------------------------------------------*/ 275 return usb_endpoint_manager_remove_ep(&hcd->ep_manager, address, 276 endpoint, direction, unregister_helper, hcd); 277 } 278 279 /** Inbound communication interface function. 280 * @param fun DDF function. 281 * @param target Communication target. 282 * @param setup_data Data to use in setup stage (control transfers). 283 * @param data Pointer to data buffer. 284 * @param size Size of the data buffer. 285 * @param callback Function to call on communication end. 286 * @param arg Argument passed to the callback function. 287 * @return Error code. 288 */ 224 289 static int usb_read(ddf_fun_t *fun, usb_target_t target, uint64_t setup_data, 225 290 uint8_t *data, size_t size, usbhc_iface_transfer_in_callback_t callback, … … 229 294 setup_data, callback, NULL, arg, "READ"); 230 295 } 231 /*----------------------------------------------------------------------------*/ 296 297 /** Outbound communication interface function. 298 * @param fun DDF function. 299 * @param target Communication target. 300 * @param setup_data Data to use in setup stage (control transfers). 301 * @param data Pointer to data buffer. 302 * @param size Size of the data buffer. 303 * @param callback Function to call on communication end. 304 * @param arg Argument passed to the callback function. 305 * @return Error code. 306 */ 232 307 static int usb_write(ddf_fun_t *fun, usb_target_t target, uint64_t setup_data, 233 308 const uint8_t *data, size_t size, … … 237 312 setup_data, NULL, callback, arg, "WRITE"); 238 313 } 239 /*----------------------------------------------------------------------------*/ 314 315 /** usbhc Interface implementation using hcd_t from libusbhost library. */ 240 316 usbhc_iface_t hcd_iface = { 241 317 .request_address = request_address, 242 318 .bind_address = bind_address, 243 . find_by_address= find_by_address,319 .get_handle = find_by_address, 244 320 .release_address = release_address, 245 321 … … 250 326 .write = usb_write, 251 327 }; 328 252 329 /** 253 330 * @}
Note:
See TracChangeset
for help on using the changeset viewer.