Changes in uspace/drv/ohci/iface.c [0ede0c3:1998bcd] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/iface.c
r0ede0c3 r1998bcd 1 1 /* 2 * Copyright (c) 2011 Vojtech Horky , Jan Vesely2 * Copyright (c) 2011 Vojtech Horky 3 3 * All rights reserved. 4 4 * … … 30 30 */ 31 31 /** @file 32 * @brief OHCI driver hc interface implementation32 * USB-HC interface implementation. 33 33 */ 34 34 #include <ddf/driver.h> … … 36 36 37 37 #include <usb/debug.h> 38 #include <usb/host/endpoint.h>39 38 40 39 #include "iface.h" 41 40 #include "hc.h" 42 41 43 static inline int setup_batch( 44 ddf_fun_t *fun, usb_target_t target, usb_direction_t direction, 45 void *data, size_t size, void * setup_data, size_t setup_size, 46 usbhc_iface_transfer_in_callback_t in, 47 usbhc_iface_transfer_out_callback_t out, void *arg, const char* name, 48 hc_t **hc, usb_transfer_batch_t **batch) 49 { 50 assert(hc); 51 assert(batch); 52 assert(fun); 53 *hc = fun_to_hc(fun); 54 assert(*hc); 55 56 size_t res_bw; 57 endpoint_t *ep = usb_endpoint_manager_get_ep(&(*hc)->ep_manager, 58 target.address, target.endpoint, direction, &res_bw); 59 if (ep == NULL) { 60 usb_log_error("Endpoint(%d:%d) not registered for %s.\n", 61 target.address, target.endpoint, name); 62 return ENOENT; 63 } 64 65 usb_log_debug("%s %d:%d %zu(%zu).\n", 66 name, target.address, target.endpoint, size, ep->max_packet_size); 67 68 const size_t bw = bandwidth_count_usb11( 69 ep->speed, ep->transfer_type, size, ep->max_packet_size); 70 if (res_bw < bw) { 71 usb_log_error("Endpoint(%d:%d) %s needs %zu bw " 72 "but only %zu is reserved.\n", 73 target.address, target.endpoint, name, bw, res_bw); 74 return ENOSPC; 75 } 76 77 *batch = batch_get( 78 fun, ep, data, size, setup_data, setup_size, in, out, arg); 79 if (!*batch) 80 return ENOMEM; 42 #define UNSUPPORTED(methodname) \ 43 usb_log_warning("Unsupported interface method `%s()' in %s:%d.\n", \ 44 methodname, __FILE__, __LINE__) 45 46 /** Reserve default address. 47 * 48 * This function may block the caller. 49 * 50 * @param[in] fun Device function the action was invoked on. 51 * @param[in] speed Speed of the device for which the default address is 52 * reserved. 53 * @return Error code. 54 */ 55 static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed) 56 { 57 assert(fun); 58 hc_t *hc = fun_to_hc(fun); 59 assert(hc); 60 usb_log_debug("Default address request with speed %d.\n", speed); 61 usb_device_keeper_reserve_default_address(&hc->manager, speed); 81 62 return EOK; 82 63 } 83 64 /*----------------------------------------------------------------------------*/ 84 /** Request address interface function 85 * 86 * @param[in] fun DDF function that was called. 87 * @param[in] speed Speed to associate with the new default address. 88 * @param[out] address Place to write a new address. 65 /** Release default address. 66 * 67 * @param[in] fun Device function the action was invoked on. 68 * @return Error code. 69 */ 70 static int release_default_address(ddf_fun_t *fun) 71 { 72 assert(fun); 73 hc_t *hc = fun_to_hc(fun); 74 assert(hc); 75 usb_log_debug("Default address release.\n"); 76 usb_device_keeper_release_default_address(&hc->manager); 77 return EOK; 78 } 79 /*----------------------------------------------------------------------------*/ 80 /** Found free USB address. 81 * 82 * @param[in] fun Device function the action was invoked on. 83 * @param[in] speed Speed of the device that will get this address. 84 * @param[out] address Non-null pointer where to store the free address. 89 85 * @return Error code. 90 86 */ … … 105 101 } 106 102 /*----------------------------------------------------------------------------*/ 107 /** Bind address interface function108 * 109 * @param[in] fun D DF function that was called.110 * @param[in] address Address of the device111 * @param[in] handle Devman handle of the device driver.103 /** Bind USB address with device devman handle. 104 * 105 * @param[in] fun Device function the action was invoked on. 106 * @param[in] address USB address of the device. 107 * @param[in] handle Devman handle of the device. 112 108 * @return Error code. 113 109 */ 114 110 static int bind_address( 115 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)111 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle) 116 112 { 117 113 assert(fun); … … 123 119 } 124 120 /*----------------------------------------------------------------------------*/ 125 /** Release address interface function126 * 127 * @param[in] fun D DF function that was called.121 /** Release previously requested address. 122 * 123 * @param[in] fun Device function the action was invoked on. 128 124 * @param[in] address USB address to be released. 129 125 * @return Error code. … … 156 152 size_t max_packet_size, unsigned int interval) 157 153 { 158 hc_t *hc = fun_to_hc(fun); 159 assert(hc); 160 154 assert(fun); 155 hc_t *hc = fun_to_hc(fun); 156 assert(hc); 157 if (address == hc->rh.address) 158 return EOK; 161 159 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address); 162 160 if (speed >= USB_SPEED_MAX) { … … 164 162 } 165 163 const size_t size = max_packet_size; 166 int ret;167 168 164 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n", 169 165 address, endpoint, usb_str_transfer_type(transfer_type), 170 166 usb_str_speed(speed), direction, size, max_packet_size, interval); 171 172 endpoint_t *ep = malloc(sizeof(endpoint_t)); 173 if (ep == NULL) 174 return ENOMEM; 175 ret = endpoint_init(ep, address, endpoint, direction, 176 transfer_type, speed, max_packet_size); 177 if (ret != EOK) { 178 free(ep); 179 return ret; 180 } 181 182 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size); 183 if (ret != EOK) { 184 endpoint_destroy(ep); 185 } 186 return ret; 187 } 188 /*----------------------------------------------------------------------------*/ 167 // TODO use real endpoint here! 168 return usb_endpoint_manager_register_ep(&hc->ep_manager,NULL, 0); 169 } 170 /*----------------------------------------------------------------------------*/ 171 /** Unregister endpoint (free some bandwidth reservation). 172 * 173 * @param[in] fun Device function the action was invoked on. 174 * @param[in] address USB address of the device. 175 * @param[in] endpoint Endpoint number. 176 * @param[in] direction Endpoint data direction. 177 * @return Error code. 178 */ 189 179 static int unregister_endpoint( 190 180 ddf_fun_t *fun, usb_address_t address, 191 181 usb_endpoint_t endpoint, usb_direction_t direction) 192 182 { 183 assert(fun); 193 184 hc_t *hc = fun_to_hc(fun); 194 185 assert(hc); 195 186 usb_log_debug("Unregister endpoint %d:%d %d.\n", 196 187 address, endpoint, direction); 188 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 189 address, endpoint, direction, NULL); 190 if (ep != NULL) { 191 usb_device_keeper_del_ep(&hc->manager, address, ep); 192 } 197 193 return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address, 198 194 endpoint, direction); … … 219 215 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 220 216 { 221 usb_transfer_batch_t *batch = NULL; 222 hc_t *hc = NULL; 223 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 224 NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch); 225 if (ret != EOK) 226 return ret; 217 assert(fun); 218 219 // FIXME: get from endpoint manager 220 size_t max_packet_size = 8; 221 222 hc_t *hc = fun_to_hc(fun); 223 assert(hc); 224 usb_speed_t speed = 225 usb_device_keeper_get_speed(&hc->manager, target.address); 226 227 usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n", 228 target.address, target.endpoint, size, max_packet_size); 229 230 usb_transfer_batch_t *batch = 231 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 232 speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager); 233 if (!batch) 234 return ENOMEM; 227 235 batch_interrupt_out(batch); 228 ret = hc_schedule(hc, batch);236 const int ret = hc_schedule(hc, batch); 229 237 if (ret != EOK) { 230 238 batch_dispose(batch); … … 253 261 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 254 262 { 255 usb_transfer_batch_t *batch = NULL; 256 hc_t *hc = NULL; 257 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 258 NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch); 259 if (ret != EOK) 260 return ret; 263 assert(fun); 264 265 // FIXME: get from endpoint manager 266 size_t max_packet_size = 8; 267 268 hc_t *hc = fun_to_hc(fun); 269 assert(hc); 270 usb_speed_t speed = 271 usb_device_keeper_get_speed(&hc->manager, target.address); 272 usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n", 273 target.address, target.endpoint, size, max_packet_size); 274 275 usb_transfer_batch_t *batch = 276 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 277 speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager); 278 if (!batch) 279 return ENOMEM; 261 280 batch_interrupt_in(batch); 262 ret = hc_schedule(hc, batch);281 const int ret = hc_schedule(hc, batch); 263 282 if (ret != EOK) { 264 283 batch_dispose(batch); … … 287 306 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 288 307 { 289 usb_transfer_batch_t *batch = NULL; 290 hc_t *hc = NULL; 291 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 292 NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch); 293 if (ret != EOK) 294 return ret; 308 assert(fun); 309 310 // FIXME: get from endpoint manager 311 size_t max_packet_size = 8; 312 313 hc_t *hc = fun_to_hc(fun); 314 assert(hc); 315 usb_speed_t speed = 316 usb_device_keeper_get_speed(&hc->manager, target.address); 317 318 usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n", 319 target.address, target.endpoint, size, max_packet_size); 320 321 usb_transfer_batch_t *batch = 322 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 323 data, size, NULL, 0, NULL, callback, arg, &hc->manager); 324 if (!batch) 325 return ENOMEM; 295 326 batch_bulk_out(batch); 296 ret = hc_schedule(hc, batch);327 const int ret = hc_schedule(hc, batch); 297 328 if (ret != EOK) { 298 329 batch_dispose(batch); … … 321 352 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 322 353 { 323 usb_transfer_batch_t *batch = NULL; 324 hc_t *hc = NULL; 325 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 326 NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch); 327 if (ret != EOK) 328 return ret; 354 assert(fun); 355 356 // FIXME: get from endpoint manager 357 size_t max_packet_size = 8; 358 359 hc_t *hc = fun_to_hc(fun); 360 assert(hc); 361 usb_speed_t speed = 362 usb_device_keeper_get_speed(&hc->manager, target.address); 363 usb_log_debug("Bulk IN %d:%d %zu(%zu).\n", 364 target.address, target.endpoint, size, max_packet_size); 365 366 usb_transfer_batch_t *batch = 367 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 368 data, size, NULL, 0, callback, NULL, arg, &hc->manager); 369 if (!batch) 370 return ENOMEM; 329 371 batch_bulk_in(batch); 330 ret = hc_schedule(hc, batch);372 const int ret = hc_schedule(hc, batch); 331 373 if (ret != EOK) { 332 374 batch_dispose(batch); … … 359 401 usbhc_iface_transfer_out_callback_t callback, void *arg) 360 402 { 361 usb_transfer_batch_t *batch = NULL; 362 hc_t *hc = NULL; 363 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 364 setup_data, setup_size, NULL, callback, arg, "Control WRITE", 365 &hc, &batch); 366 if (ret != EOK) 367 return ret; 368 usb_endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data); 403 assert(fun); 404 405 // FIXME: get from endpoint manager 406 size_t max_packet_size = 8; 407 408 hc_t *hc = fun_to_hc(fun); 409 assert(hc); 410 usb_speed_t speed = 411 usb_device_keeper_get_speed(&hc->manager, target.address); 412 usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n", 413 speed, target.address, target.endpoint, size, max_packet_size); 414 415 if (setup_size != 8) 416 return EINVAL; 417 418 usb_transfer_batch_t *batch = 419 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, 420 speed, data, size, setup_data, setup_size, NULL, callback, arg, 421 &hc->manager); 422 if (!batch) 423 return ENOMEM; 424 usb_device_keeper_reset_if_need(&hc->manager, target, setup_data); 369 425 batch_control_write(batch); 370 ret = hc_schedule(hc, batch);426 const int ret = hc_schedule(hc, batch); 371 427 if (ret != EOK) { 372 428 batch_dispose(batch); … … 399 455 usbhc_iface_transfer_in_callback_t callback, void *arg) 400 456 { 401 usb_transfer_batch_t *batch = NULL; 402 hc_t *hc = NULL; 403 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 404 setup_data, setup_size, callback, NULL, arg, "Control READ", 405 &hc, &batch); 406 if (ret != EOK) 407 return ret; 457 assert(fun); 458 459 // FIXME: get from endpoint manager 460 size_t max_packet_size = 8; 461 462 hc_t *hc = fun_to_hc(fun); 463 assert(hc); 464 usb_speed_t speed = 465 usb_device_keeper_get_speed(&hc->manager, target.address); 466 467 usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n", 468 speed, target.address, target.endpoint, size, max_packet_size); 469 usb_transfer_batch_t *batch = 470 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, 471 speed, data, size, setup_data, setup_size, callback, NULL, arg, 472 &hc->manager); 473 if (!batch) 474 return ENOMEM; 408 475 batch_control_read(batch); 409 ret = hc_schedule(hc, batch);476 const int ret = hc_schedule(hc, batch); 410 477 if (ret != EOK) { 411 478 batch_dispose(batch); … … 414 481 } 415 482 /*----------------------------------------------------------------------------*/ 483 /** Host controller interface implementation for OHCI. */ 416 484 usbhc_iface_t hc_iface = { 485 .reserve_default_address = reserve_default_address, 486 .release_default_address = release_default_address, 417 487 .request_address = request_address, 418 488 .bind_address = bind_address, … … 431 501 .control_read = control_read, 432 502 }; 503 433 504 /** 434 505 * @}
Note:
See TracChangeset
for help on using the changeset viewer.