Changeset a43f1d18 in mainline for uspace/drv/ohci/iface.c
- Timestamp:
- 2011-04-09T18:26:22Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2ad98fd
- Parents:
- f35b294 (diff), 97e7e8a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/iface.c
rf35b294 ra43f1d18 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. 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 assert(ep->speed == 77 usb_device_keeper_get_speed(&(*hc)->manager, target.address)); 78 // assert(ep->max_packet_size == max_packet_size); 79 // assert(ep->transfer_type == USB_TRANSFER_CONTROL); 80 81 *batch = 82 batch_get(fun, ep, data, size, setup_data, setup_size, 83 in, out, arg); 84 if (!batch) 85 return ENOMEM; 86 return EOK; 87 } 88 89 90 /** Reserve default address interface function 91 * 92 * @param[in] fun DDF function that was called. 93 * @param[in] speed Speed to associate with the new default address. 53 94 * @return Error code. 54 95 */ … … 61 102 usb_device_keeper_reserve_default_address(&hc->manager, speed); 62 103 return EOK; 63 } 64 /*----------------------------------------------------------------------------*/ 65 /** Release default address. 66 * 67 * @param[in] fun Device function the action was invoked on. 104 #if 0 105 endpoint_t *ep = malloc(sizeof(endpoint_t)); 106 if (ep == NULL) 107 return ENOMEM; 108 const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64; 109 endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size); 110 int ret; 111 try_retgister: 112 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, 113 USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0); 114 if (ret == EEXISTS) { 115 async_usleep(1000); 116 goto try_retgister; 117 } 118 if (ret != EOK) { 119 endpoint_destroy(ep); 120 } 121 return ret; 122 #endif 123 } 124 /*----------------------------------------------------------------------------*/ 125 /** Release default address interface function 126 * 127 * @param[in] fun DDF function that was called. 68 128 * @return Error code. 69 129 */ … … 74 134 assert(hc); 75 135 usb_log_debug("Default address release.\n"); 136 // return usb_endpoint_manager_unregister_ep(&hc->ep_manager, 137 // USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH); 76 138 usb_device_keeper_release_default_address(&hc->manager); 77 139 return EOK; 78 140 } 79 141 /*----------------------------------------------------------------------------*/ 80 /** Found free USB address.81 * 82 * @param[in] fun D evice function the action was invoked on.83 * @param[in] speed Speed of the device that will get thisaddress.84 * @param[out] address Non-null pointer where to store the freeaddress.142 /** Request address interface function 143 * 144 * @param[in] fun DDF function that was called. 145 * @param[in] speed Speed to associate with the new default address. 146 * @param[out] address Place to write a new address. 85 147 * @return Error code. 86 148 */ … … 101 163 } 102 164 /*----------------------------------------------------------------------------*/ 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 .165 /** Bind address interface function 166 * 167 * @param[in] fun DDF function that was called. 168 * @param[in] address Address of the device 169 * @param[in] handle Devman handle of the device driver. 108 170 * @return Error code. 109 171 */ 110 172 static int bind_address( 111 173 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle) 112 174 { 113 175 assert(fun); … … 119 181 } 120 182 /*----------------------------------------------------------------------------*/ 121 /** Release previously requested address.122 * 123 * @param[in] fun D evice function the action was invoked on.183 /** Release address interface function 184 * 185 * @param[in] fun DDF function that was called. 124 186 * @param[in] address USB address to be released. 125 187 * @return Error code. … … 139 201 * @param[in] fun Device function the action was invoked on. 140 202 * @param[in] address USB address of the device. 203 * @param[in] ep_speed Endpoint speed (invalid means to use device one). 141 204 * @param[in] endpoint Endpoint number. 142 205 * @param[in] transfer_type USB transfer type. … … 146 209 * @return Error code. 147 210 */ 148 static int register_endpoint( 149 ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,211 static int register_endpoint(ddf_fun_t *fun, 212 usb_address_t address, usb_speed_t ep_speed, usb_endpoint_t endpoint, 150 213 usb_transfer_type_t transfer_type, usb_direction_t direction, 151 214 size_t max_packet_size, unsigned int interval) 152 215 { 153 assert(fun);154 216 hc_t *hc = fun_to_hc(fun); 155 217 assert(hc); 156 218 if (address == hc->rh.address) 157 219 return EOK; 158 const usb_speed_t speed = 159 usb_device_keeper_get_speed(&hc->manager, address); 160 const size_t size = max_packet_size; 220 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address); 221 if (speed >= USB_SPEED_MAX) { 222 speed = ep_speed; 223 } 224 const size_t size = 225 (transfer_type == USB_TRANSFER_INTERRUPT 226 || transfer_type == USB_TRANSFER_ISOCHRONOUS) ? 227 max_packet_size : 0; 228 int ret; 229 230 endpoint_t *ep = malloc(sizeof(endpoint_t)); 231 if (ep == NULL) 232 return ENOMEM; 233 ret = endpoint_init(ep, address, endpoint, direction, 234 transfer_type, speed, max_packet_size); 235 if (ret != EOK) { 236 free(ep); 237 return ret; 238 } 239 161 240 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n", 162 241 address, endpoint, usb_str_transfer_type(transfer_type), 163 242 usb_str_speed(speed), direction, size, max_packet_size, interval); 164 // TODO use real endpoint here! 165 return usb_endpoint_manager_register_ep(&hc->ep_manager,NULL, 0); 166 } 167 /*----------------------------------------------------------------------------*/ 168 /** Unregister endpoint (free some bandwidth reservation). 169 * 170 * @param[in] fun Device function the action was invoked on. 171 * @param[in] address USB address of the device. 172 * @param[in] endpoint Endpoint number. 173 * @param[in] direction Endpoint data direction. 174 * @return Error code. 175 */ 243 244 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size); 245 if (ret != EOK) { 246 endpoint_destroy(ep); 247 } else { 248 usb_device_keeper_add_ep(&hc->manager, address, ep); 249 } 250 return ret; 251 } 252 /*----------------------------------------------------------------------------*/ 176 253 static int unregister_endpoint( 177 254 ddf_fun_t *fun, usb_address_t address, 178 255 usb_endpoint_t endpoint, usb_direction_t direction) 179 256 { 180 assert(fun);181 257 hc_t *hc = fun_to_hc(fun); 182 258 assert(hc); 183 259 usb_log_debug("Unregister endpoint %d:%d %d.\n", 184 260 address, endpoint, direction); 261 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 262 address, endpoint, direction, NULL); 263 if (ep != NULL) { 264 usb_device_keeper_del_ep(&hc->manager, address, ep); 265 } 185 266 return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address, 186 267 endpoint, direction); … … 196 277 * @param[in] fun Device function the action was invoked on. 197 278 * @param[in] target Target pipe (address and endpoint number) specification. 198 * @param[in] max_packet_size Max packet size for the transfer.199 279 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated 200 280 * by the caller). … … 205 285 */ 206 286 static int interrupt_out( 207 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,287 ddf_fun_t *fun, usb_target_t target, void *data, 208 288 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 209 289 { 210 assert(fun); 211 hc_t *hc = fun_to_hc(fun); 212 assert(hc); 213 usb_speed_t speed = 214 usb_device_keeper_get_speed(&hc->manager, target.address); 215 216 usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n", 217 target.address, target.endpoint, size, max_packet_size); 218 219 usb_transfer_batch_t *batch = 220 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 221 speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager); 222 if (!batch) 223 return ENOMEM; 290 usb_transfer_batch_t *batch = NULL; 291 hc_t *hc = NULL; 292 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 293 NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch); 294 if (ret != EOK) 295 return ret; 224 296 batch_interrupt_out(batch); 225 const intret = hc_schedule(hc, batch);297 ret = hc_schedule(hc, batch); 226 298 if (ret != EOK) { 227 299 batch_dispose(batch); … … 239 311 * @param[in] fun Device function the action was invoked on. 240 312 * @param[in] target Target pipe (address and endpoint number) specification. 241 * @param[in] max_packet_size Max packet size for the transfer.242 313 * @param[in] data Buffer where to store the data (in USB endianess, 243 314 * allocated and deallocated by the caller). … … 248 319 */ 249 320 static int interrupt_in( 250 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,321 ddf_fun_t *fun, usb_target_t target, void *data, 251 322 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 252 323 { 253 assert(fun); 254 hc_t *hc = fun_to_hc(fun); 255 assert(hc); 256 usb_speed_t speed = 257 usb_device_keeper_get_speed(&hc->manager, target.address); 258 usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n", 259 target.address, target.endpoint, size, max_packet_size); 260 261 usb_transfer_batch_t *batch = 262 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 263 speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager); 264 if (!batch) 265 return ENOMEM; 324 usb_transfer_batch_t *batch = NULL; 325 hc_t *hc = NULL; 326 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 327 NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch); 328 if (ret != EOK) 329 return ret; 266 330 batch_interrupt_in(batch); 267 const intret = hc_schedule(hc, batch);331 ret = hc_schedule(hc, batch); 268 332 if (ret != EOK) { 269 333 batch_dispose(batch); … … 281 345 * @param[in] fun Device function the action was invoked on. 282 346 * @param[in] target Target pipe (address and endpoint number) specification. 283 * @param[in] max_packet_size Max packet size for the transfer.284 347 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated 285 348 * by the caller). … … 290 353 */ 291 354 static int bulk_out( 292 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,355 ddf_fun_t *fun, usb_target_t target, void *data, 293 356 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 294 357 { 295 assert(fun); 296 hc_t *hc = fun_to_hc(fun); 297 assert(hc); 298 usb_speed_t speed = 299 usb_device_keeper_get_speed(&hc->manager, target.address); 300 301 usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n", 302 target.address, target.endpoint, size, max_packet_size); 303 304 usb_transfer_batch_t *batch = 305 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 306 data, size, NULL, 0, NULL, callback, arg, &hc->manager); 307 if (!batch) 308 return ENOMEM; 358 usb_transfer_batch_t *batch = NULL; 359 hc_t *hc = NULL; 360 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 361 NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch); 362 if (ret != EOK) 363 return ret; 309 364 batch_bulk_out(batch); 310 const intret = hc_schedule(hc, batch);365 ret = hc_schedule(hc, batch); 311 366 if (ret != EOK) { 312 367 batch_dispose(batch); … … 324 379 * @param[in] fun Device function the action was invoked on. 325 380 * @param[in] target Target pipe (address and endpoint number) specification. 326 * @param[in] max_packet_size Max packet size for the transfer.327 381 * @param[in] data Buffer where to store the data (in USB endianess, 328 382 * allocated and deallocated by the caller). … … 333 387 */ 334 388 static int bulk_in( 335 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,389 ddf_fun_t *fun, usb_target_t target, void *data, 336 390 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 337 391 { 338 assert(fun); 339 hc_t *hc = fun_to_hc(fun); 340 assert(hc); 341 usb_speed_t speed = 342 usb_device_keeper_get_speed(&hc->manager, target.address); 343 usb_log_debug("Bulk IN %d:%d %zu(%zu).\n", 344 target.address, target.endpoint, size, max_packet_size); 345 346 usb_transfer_batch_t *batch = 347 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 348 data, size, NULL, 0, callback, NULL, arg, &hc->manager); 349 if (!batch) 350 return ENOMEM; 392 usb_transfer_batch_t *batch = NULL; 393 hc_t *hc = NULL; 394 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 395 NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch); 396 if (ret != EOK) 397 return ret; 351 398 batch_bulk_in(batch); 352 const intret = hc_schedule(hc, batch);399 ret = hc_schedule(hc, batch); 353 400 if (ret != EOK) { 354 401 batch_dispose(batch); … … 366 413 * @param[in] fun Device function the action was invoked on. 367 414 * @param[in] target Target pipe (address and endpoint number) specification. 368 * @param[in] max_packet_size Max packet size for the transfer.369 415 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated 370 416 * and deallocated by the caller). … … 378 424 */ 379 425 static int control_write( 380 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,426 ddf_fun_t *fun, usb_target_t target, 381 427 void *setup_data, size_t setup_size, void *data, size_t size, 382 428 usbhc_iface_transfer_out_callback_t callback, void *arg) 383 429 { 384 assert(fun); 385 hc_t *hc = fun_to_hc(fun); 386 assert(hc); 387 usb_speed_t speed = 388 usb_device_keeper_get_speed(&hc->manager, target.address); 389 usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n", 390 speed, target.address, target.endpoint, size, max_packet_size); 391 392 if (setup_size != 8) 393 return EINVAL; 394 395 usb_transfer_batch_t *batch = 396 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, 397 speed, data, size, setup_data, setup_size, NULL, callback, arg, 398 &hc->manager); 399 if (!batch) 400 return ENOMEM; 430 usb_transfer_batch_t *batch = NULL; 431 hc_t *hc = NULL; 432 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 433 setup_data, setup_size, NULL, callback, arg, "Control WRITE", 434 &hc, &batch); 435 if (ret != EOK) 436 return ret; 401 437 usb_device_keeper_reset_if_need(&hc->manager, target, setup_data); 402 438 batch_control_write(batch); 403 const intret = hc_schedule(hc, batch);439 ret = hc_schedule(hc, batch); 404 440 if (ret != EOK) { 405 441 batch_dispose(batch); … … 417 453 * @param[in] fun Device function the action was invoked on. 418 454 * @param[in] target Target pipe (address and endpoint number) specification. 419 * @param[in] max_packet_size Max packet size for the transfer.420 455 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated 421 456 * and deallocated by the caller). … … 429 464 */ 430 465 static int control_read( 431 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,466 ddf_fun_t *fun, usb_target_t target, 432 467 void *setup_data, size_t setup_size, void *data, size_t size, 433 468 usbhc_iface_transfer_in_callback_t callback, void *arg) 434 469 { 435 assert(fun); 436 hc_t *hc = fun_to_hc(fun); 437 assert(hc); 438 usb_speed_t speed = 439 usb_device_keeper_get_speed(&hc->manager, target.address); 440 441 usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n", 442 speed, target.address, target.endpoint, size, max_packet_size); 443 usb_transfer_batch_t *batch = 444 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, 445 speed, data, size, setup_data, setup_size, callback, NULL, arg, 446 &hc->manager); 447 if (!batch) 448 return ENOMEM; 470 usb_transfer_batch_t *batch = NULL; 471 hc_t *hc = NULL; 472 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 473 setup_data, setup_size, callback, NULL, arg, "Control READ", 474 &hc, &batch); 475 if (ret != EOK) 476 return ret; 449 477 batch_control_read(batch); 450 const intret = hc_schedule(hc, batch);478 ret = hc_schedule(hc, batch); 451 479 if (ret != EOK) { 452 480 batch_dispose(batch); … … 455 483 } 456 484 /*----------------------------------------------------------------------------*/ 457 /** Host controller interface implementation for OHCI. */458 485 usbhc_iface_t hc_iface = { 459 486 .reserve_default_address = reserve_default_address, … … 475 502 .control_read = control_read, 476 503 }; 477 478 504 /** 479 505 * @}
Note:
See TracChangeset
for help on using the changeset viewer.