Changes in uspace/drv/ohci/iface.c [a19a2d7:1998bcd] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/iface.c
ra19a2d7 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 const size_t bw = bandwidth_count_usb11( 66 ep->speed, ep->transfer_type, size, ep->max_packet_size); 67 if (res_bw < bw) { 68 usb_log_error("Endpoint(%d:%d) %s needs %zu bw " 69 "but only %zu is reserved.\n", 70 name, target.address, target.endpoint, bw, res_bw); 71 return ENOSPC; 72 } 73 usb_log_debug("%s %d:%d %zu(%zu).\n", 74 name, target.address, target.endpoint, size, ep->max_packet_size); 75 76 *batch = batch_get( 77 fun, ep, data, size, setup_data, setup_size, in, out, arg); 78 if (!*batch) 79 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); 80 62 return EOK; 81 63 } 82 64 /*----------------------------------------------------------------------------*/ 83 /** Request address interface function 84 * 85 * @param[in] fun DDF function that was called. 86 * @param[in] speed Speed to associate with the new default address. 87 * @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. 88 85 * @return Error code. 89 86 */ … … 104 101 } 105 102 /*----------------------------------------------------------------------------*/ 106 /** Bind address interface function107 * 108 * @param[in] fun D DF function that was called.109 * @param[in] address Address of the device110 * @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. 111 108 * @return Error code. 112 109 */ 113 110 static int bind_address( 114 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) 115 112 { 116 113 assert(fun); … … 122 119 } 123 120 /*----------------------------------------------------------------------------*/ 124 /** Release address interface function125 * 126 * @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. 127 124 * @param[in] address USB address to be released. 128 125 * @return Error code. … … 155 152 size_t max_packet_size, unsigned int interval) 156 153 { 154 assert(fun); 157 155 hc_t *hc = fun_to_hc(fun); 158 156 assert(hc); … … 163 161 speed = ep_speed; 164 162 } 165 const size_t size = 166 (transfer_type == USB_TRANSFER_INTERRUPT 167 || transfer_type == USB_TRANSFER_ISOCHRONOUS) ? 168 max_packet_size : 0; 169 int ret; 170 171 endpoint_t *ep = malloc(sizeof(endpoint_t)); 172 if (ep == NULL) 173 return ENOMEM; 174 ret = endpoint_init(ep, address, endpoint, direction, 175 transfer_type, speed, max_packet_size); 176 if (ret != EOK) { 177 free(ep); 178 return ret; 179 } 180 163 const size_t size = max_packet_size; 181 164 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n", 182 165 address, endpoint, usb_str_transfer_type(transfer_type), 183 166 usb_str_speed(speed), direction, size, max_packet_size, interval); 184 185 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size); 186 if (ret != EOK) { 187 endpoint_destroy(ep); 188 } 189 return ret; 190 } 191 /*----------------------------------------------------------------------------*/ 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 */ 192 179 static int unregister_endpoint( 193 180 ddf_fun_t *fun, usb_address_t address, 194 181 usb_endpoint_t endpoint, usb_direction_t direction) 195 182 { 183 assert(fun); 196 184 hc_t *hc = fun_to_hc(fun); 197 185 assert(hc); 198 186 usb_log_debug("Unregister endpoint %d:%d %d.\n", 199 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 } 200 193 return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address, 201 194 endpoint, direction); … … 222 215 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 223 216 { 224 usb_transfer_batch_t *batch = NULL; 225 hc_t *hc = NULL; 226 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 227 NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch); 228 if (ret != EOK) 229 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; 230 235 batch_interrupt_out(batch); 231 ret = hc_schedule(hc, batch);236 const int ret = hc_schedule(hc, batch); 232 237 if (ret != EOK) { 233 238 batch_dispose(batch); … … 256 261 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 257 262 { 258 usb_transfer_batch_t *batch = NULL; 259 hc_t *hc = NULL; 260 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 261 NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch); 262 if (ret != EOK) 263 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; 264 280 batch_interrupt_in(batch); 265 ret = hc_schedule(hc, batch);281 const int ret = hc_schedule(hc, batch); 266 282 if (ret != EOK) { 267 283 batch_dispose(batch); … … 290 306 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 291 307 { 292 usb_transfer_batch_t *batch = NULL; 293 hc_t *hc = NULL; 294 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 295 NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch); 296 if (ret != EOK) 297 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; 298 326 batch_bulk_out(batch); 299 ret = hc_schedule(hc, batch);327 const int ret = hc_schedule(hc, batch); 300 328 if (ret != EOK) { 301 329 batch_dispose(batch); … … 324 352 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 325 353 { 326 usb_transfer_batch_t *batch = NULL; 327 hc_t *hc = NULL; 328 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 329 NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch); 330 if (ret != EOK) 331 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; 332 371 batch_bulk_in(batch); 333 ret = hc_schedule(hc, batch);372 const int ret = hc_schedule(hc, batch); 334 373 if (ret != EOK) { 335 374 batch_dispose(batch); … … 362 401 usbhc_iface_transfer_out_callback_t callback, void *arg) 363 402 { 364 usb_transfer_batch_t *batch = NULL; 365 hc_t *hc = NULL; 366 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 367 setup_data, setup_size, NULL, callback, arg, "Control WRITE", 368 &hc, &batch); 369 if (ret != EOK) 370 return ret; 371 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); 372 425 batch_control_write(batch); 373 ret = hc_schedule(hc, batch);426 const int ret = hc_schedule(hc, batch); 374 427 if (ret != EOK) { 375 428 batch_dispose(batch); … … 402 455 usbhc_iface_transfer_in_callback_t callback, void *arg) 403 456 { 404 usb_transfer_batch_t *batch = NULL; 405 hc_t *hc = NULL; 406 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 407 setup_data, setup_size, callback, NULL, arg, "Control READ", 408 &hc, &batch); 409 if (ret != EOK) 410 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; 411 475 batch_control_read(batch); 412 ret = hc_schedule(hc, batch);476 const int ret = hc_schedule(hc, batch); 413 477 if (ret != EOK) { 414 478 batch_dispose(batch); … … 417 481 } 418 482 /*----------------------------------------------------------------------------*/ 483 /** Host controller interface implementation for OHCI. */ 419 484 usbhc_iface_t hc_iface = { 485 .reserve_default_address = reserve_default_address, 486 .release_default_address = release_default_address, 420 487 .request_address = request_address, 421 488 .bind_address = bind_address, … … 434 501 .control_read = control_read, 435 502 }; 503 436 504 /** 437 505 * @}
Note:
See TracChangeset
for help on using the changeset viewer.