Changes in uspace/drv/ohci/iface.c [1998bcd:0ede0c3] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/iface.c
r1998bcd r0ede0c3 1 1 /* 2 * Copyright (c) 2011 Vojtech Horky 2 * Copyright (c) 2011 Vojtech Horky, Jan Vesely 3 3 * All rights reserved. 4 4 * … … 30 30 */ 31 31 /** @file 32 * USB-HC interface implementation.32 * @brief OHCI driver 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> 38 39 39 40 #include "iface.h" 40 41 #include "hc.h" 41 42 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 { 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); 57 52 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); 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; 62 81 return EOK; 63 82 } 64 83 /*----------------------------------------------------------------------------*/ 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. 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. 85 89 * @return Error code. 86 90 */ … … 101 105 } 102 106 /*----------------------------------------------------------------------------*/ 103 /** Bind USB address with device devman handle.104 * 105 * @param[in] fun D evice function the action was invoked on.106 * @param[in] address USB address of the device.107 * @param[in] handle Devman handle of the device .107 /** Bind address interface function 108 * 109 * @param[in] fun DDF function that was called. 110 * @param[in] address Address of the device 111 * @param[in] handle Devman handle of the device driver. 108 112 * @return Error code. 109 113 */ 110 114 static int bind_address( 111 115 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle) 112 116 { 113 117 assert(fun); … … 119 123 } 120 124 /*----------------------------------------------------------------------------*/ 121 /** Release previously requested address.122 * 123 * @param[in] fun D evice function the action was invoked on.125 /** Release address interface function 126 * 127 * @param[in] fun DDF function that was called. 124 128 * @param[in] address USB address to be released. 125 129 * @return Error code. … … 152 156 size_t max_packet_size, unsigned int interval) 153 157 { 154 assert(fun);155 158 hc_t *hc = fun_to_hc(fun); 156 159 assert(hc); 157 if (address == hc->rh.address) 158 return EOK; 160 159 161 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address); 160 162 if (speed >= USB_SPEED_MAX) { … … 162 164 } 163 165 const size_t size = max_packet_size; 166 int ret; 167 164 168 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n", 165 169 address, endpoint, usb_str_transfer_type(transfer_type), 166 170 usb_str_speed(speed), direction, size, max_packet_size, interval); 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 */ 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 /*----------------------------------------------------------------------------*/ 179 189 static int unregister_endpoint( 180 190 ddf_fun_t *fun, usb_address_t address, 181 191 usb_endpoint_t endpoint, usb_direction_t direction) 182 192 { 183 assert(fun);184 193 hc_t *hc = fun_to_hc(fun); 185 194 assert(hc); 186 195 usb_log_debug("Unregister endpoint %d:%d %d.\n", 187 196 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 }193 197 return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address, 194 198 endpoint, direction); … … 215 219 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 216 220 { 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; 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; 235 227 batch_interrupt_out(batch); 236 const intret = hc_schedule(hc, batch);228 ret = hc_schedule(hc, batch); 237 229 if (ret != EOK) { 238 230 batch_dispose(batch); … … 261 253 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 262 254 { 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; 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; 280 261 batch_interrupt_in(batch); 281 const intret = hc_schedule(hc, batch);262 ret = hc_schedule(hc, batch); 282 263 if (ret != EOK) { 283 264 batch_dispose(batch); … … 306 287 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 307 288 { 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; 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; 326 295 batch_bulk_out(batch); 327 const intret = hc_schedule(hc, batch);296 ret = hc_schedule(hc, batch); 328 297 if (ret != EOK) { 329 298 batch_dispose(batch); … … 352 321 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 353 322 { 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; 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; 371 329 batch_bulk_in(batch); 372 const intret = hc_schedule(hc, batch);330 ret = hc_schedule(hc, batch); 373 331 if (ret != EOK) { 374 332 batch_dispose(batch); … … 401 359 usbhc_iface_transfer_out_callback_t callback, void *arg) 402 360 { 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); 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); 425 369 batch_control_write(batch); 426 const intret = hc_schedule(hc, batch);370 ret = hc_schedule(hc, batch); 427 371 if (ret != EOK) { 428 372 batch_dispose(batch); … … 455 399 usbhc_iface_transfer_in_callback_t callback, void *arg) 456 400 { 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; 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; 475 408 batch_control_read(batch); 476 const int ret = hc_schedule(hc, batch); 477 if (ret != EOK) { 478 batch_dispose(batch); 479 } 480 return ret; 481 } 482 /*----------------------------------------------------------------------------*/ 483 /** Host controller interface implementation for OHCI. */ 409 ret = hc_schedule(hc, batch); 410 if (ret != EOK) { 411 batch_dispose(batch); 412 } 413 return ret; 414 } 415 /*----------------------------------------------------------------------------*/ 484 416 usbhc_iface_t hc_iface = { 485 .reserve_default_address = reserve_default_address,486 .release_default_address = release_default_address,487 417 .request_address = request_address, 488 418 .bind_address = bind_address, … … 501 431 .control_read = control_read, 502 432 }; 503 504 433 /** 505 434 * @}
Note:
See TracChangeset
for help on using the changeset viewer.