Changeset dc4c19e in mainline for uspace/drv/ohci/iface.c
- Timestamp:
- 2011-04-10T12:18:09Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 60c0573
- Parents:
- a49e171 (diff), 82e8861 (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
ra49e171 rdc4c19e 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. … … 139 143 * @param[in] fun Device function the action was invoked on. 140 144 * @param[in] address USB address of the device. 145 * @param[in] ep_speed Endpoint speed (invalid means to use device one). 141 146 * @param[in] endpoint Endpoint number. 142 147 * @param[in] transfer_type USB transfer type. … … 146 151 * @return Error code. 147 152 */ 148 static int register_endpoint( 149 ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,153 static int register_endpoint(ddf_fun_t *fun, 154 usb_address_t address, usb_speed_t ep_speed, usb_endpoint_t endpoint, 150 155 usb_transfer_type_t transfer_type, usb_direction_t direction, 151 156 size_t max_packet_size, unsigned int interval) 152 157 { 153 assert(fun);154 158 hc_t *hc = fun_to_hc(fun); 155 159 assert(hc); 156 if (address == hc->rh.address) 157 return EOK; 158 const usb_speed_t speed = 159 usb_device_keeper_get_speed(&hc->manager, address); 160 161 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address); 162 if (speed >= USB_SPEED_MAX) { 163 speed = ep_speed; 164 } 160 165 const size_t size = max_packet_size; 166 int ret; 167 161 168 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n", 162 169 address, endpoint, usb_str_transfer_type(transfer_type), 163 170 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 */ 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 /*----------------------------------------------------------------------------*/ 176 189 static int unregister_endpoint( 177 190 ddf_fun_t *fun, usb_address_t address, 178 191 usb_endpoint_t endpoint, usb_direction_t direction) 179 192 { 180 assert(fun);181 193 hc_t *hc = fun_to_hc(fun); 182 194 assert(hc); … … 196 208 * @param[in] fun Device function the action was invoked on. 197 209 * @param[in] target Target pipe (address and endpoint number) specification. 198 * @param[in] max_packet_size Max packet size for the transfer.199 210 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated 200 211 * by the caller). … … 205 216 */ 206 217 static int interrupt_out( 207 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,218 ddf_fun_t *fun, usb_target_t target, void *data, 208 219 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 209 220 { 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; 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; 224 227 batch_interrupt_out(batch); 225 const intret = hc_schedule(hc, batch);228 ret = hc_schedule(hc, batch); 226 229 if (ret != EOK) { 227 230 batch_dispose(batch); … … 239 242 * @param[in] fun Device function the action was invoked on. 240 243 * @param[in] target Target pipe (address and endpoint number) specification. 241 * @param[in] max_packet_size Max packet size for the transfer.242 244 * @param[in] data Buffer where to store the data (in USB endianess, 243 245 * allocated and deallocated by the caller). … … 248 250 */ 249 251 static int interrupt_in( 250 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,252 ddf_fun_t *fun, usb_target_t target, void *data, 251 253 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 252 254 { 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; 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; 266 261 batch_interrupt_in(batch); 267 const intret = hc_schedule(hc, batch);262 ret = hc_schedule(hc, batch); 268 263 if (ret != EOK) { 269 264 batch_dispose(batch); … … 281 276 * @param[in] fun Device function the action was invoked on. 282 277 * @param[in] target Target pipe (address and endpoint number) specification. 283 * @param[in] max_packet_size Max packet size for the transfer.284 278 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated 285 279 * by the caller). … … 290 284 */ 291 285 static int bulk_out( 292 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,286 ddf_fun_t *fun, usb_target_t target, void *data, 293 287 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 294 288 { 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; 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; 309 295 batch_bulk_out(batch); 310 const intret = hc_schedule(hc, batch);296 ret = hc_schedule(hc, batch); 311 297 if (ret != EOK) { 312 298 batch_dispose(batch); … … 324 310 * @param[in] fun Device function the action was invoked on. 325 311 * @param[in] target Target pipe (address and endpoint number) specification. 326 * @param[in] max_packet_size Max packet size for the transfer.327 312 * @param[in] data Buffer where to store the data (in USB endianess, 328 313 * allocated and deallocated by the caller). … … 333 318 */ 334 319 static int bulk_in( 335 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,320 ddf_fun_t *fun, usb_target_t target, void *data, 336 321 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 337 322 { 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; 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; 351 329 batch_bulk_in(batch); 352 const intret = hc_schedule(hc, batch);330 ret = hc_schedule(hc, batch); 353 331 if (ret != EOK) { 354 332 batch_dispose(batch); … … 366 344 * @param[in] fun Device function the action was invoked on. 367 345 * @param[in] target Target pipe (address and endpoint number) specification. 368 * @param[in] max_packet_size Max packet size for the transfer.369 346 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated 370 347 * and deallocated by the caller). … … 378 355 */ 379 356 static int control_write( 380 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,357 ddf_fun_t *fun, usb_target_t target, 381 358 void *setup_data, size_t setup_size, void *data, size_t size, 382 359 usbhc_iface_transfer_out_callback_t callback, void *arg) 383 360 { 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; 401 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); 402 369 batch_control_write(batch); 403 const intret = hc_schedule(hc, batch);370 ret = hc_schedule(hc, batch); 404 371 if (ret != EOK) { 405 372 batch_dispose(batch); … … 417 384 * @param[in] fun Device function the action was invoked on. 418 385 * @param[in] target Target pipe (address and endpoint number) specification. 419 * @param[in] max_packet_size Max packet size for the transfer.420 386 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated 421 387 * and deallocated by the caller). … … 429 395 */ 430 396 static int control_read( 431 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,397 ddf_fun_t *fun, usb_target_t target, 432 398 void *setup_data, size_t setup_size, void *data, size_t size, 433 399 usbhc_iface_transfer_in_callback_t callback, void *arg) 434 400 { 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; 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; 449 408 batch_control_read(batch); 450 const int ret = hc_schedule(hc, batch); 451 if (ret != EOK) { 452 batch_dispose(batch); 453 } 454 return ret; 455 } 456 /*----------------------------------------------------------------------------*/ 457 /** 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 /*----------------------------------------------------------------------------*/ 458 416 usbhc_iface_t hc_iface = { 459 .reserve_default_address = reserve_default_address,460 .release_default_address = release_default_address,461 417 .request_address = request_address, 462 418 .bind_address = bind_address, … … 475 431 .control_read = control_read, 476 432 }; 477 478 433 /** 479 434 * @}
Note:
See TracChangeset
for help on using the changeset viewer.