Changeset e50cd7f in mainline for uspace/drv/ohci/iface.c
- Timestamp:
- 2011-04-17T19:17:55Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 63517c2, cfbbe1d3
- Parents:
- ef354b6 (diff), 8595577b (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
ref354b6 re50cd7f 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 = hc_get_endpoint(*hc, 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 161 167 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n", 162 168 address, endpoint, usb_str_transfer_type(transfer_type), 163 169 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 */ 170 171 return hc_add_endpoint(hc, address, endpoint, speed, transfer_type, 172 direction, max_packet_size, size, interval); 173 } 174 /*----------------------------------------------------------------------------*/ 176 175 static int unregister_endpoint( 177 176 ddf_fun_t *fun, usb_address_t address, 178 177 usb_endpoint_t endpoint, usb_direction_t direction) 179 178 { 180 assert(fun);181 179 hc_t *hc = fun_to_hc(fun); 182 180 assert(hc); 183 181 usb_log_debug("Unregister endpoint %d:%d %d.\n", 184 182 address, endpoint, direction); 185 return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address, 186 endpoint, direction); 183 return hc_remove_endpoint(hc, address, endpoint, direction); 187 184 } 188 185 /*----------------------------------------------------------------------------*/ … … 196 193 * @param[in] fun Device function the action was invoked on. 197 194 * @param[in] target Target pipe (address and endpoint number) specification. 198 * @param[in] max_packet_size Max packet size for the transfer.199 195 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated 200 196 * by the caller). … … 205 201 */ 206 202 static int interrupt_out( 207 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,203 ddf_fun_t *fun, usb_target_t target, void *data, 208 204 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 209 205 { 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; 206 usb_transfer_batch_t *batch = NULL; 207 hc_t *hc = NULL; 208 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 209 NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch); 210 if (ret != EOK) 211 return ret; 224 212 batch_interrupt_out(batch); 225 const intret = hc_schedule(hc, batch);226 if (ret != EOK) { 227 batch_dispose(batch);213 ret = hc_schedule(hc, batch); 214 if (ret != EOK) { 215 usb_transfer_batch_dispose(batch); 228 216 } 229 217 return ret; … … 239 227 * @param[in] fun Device function the action was invoked on. 240 228 * @param[in] target Target pipe (address and endpoint number) specification. 241 * @param[in] max_packet_size Max packet size for the transfer.242 229 * @param[in] data Buffer where to store the data (in USB endianess, 243 230 * allocated and deallocated by the caller). … … 248 235 */ 249 236 static int interrupt_in( 250 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,237 ddf_fun_t *fun, usb_target_t target, void *data, 251 238 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 252 239 { 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; 240 usb_transfer_batch_t *batch = NULL; 241 hc_t *hc = NULL; 242 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 243 NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch); 244 if (ret != EOK) 245 return ret; 266 246 batch_interrupt_in(batch); 267 const intret = hc_schedule(hc, batch);268 if (ret != EOK) { 269 batch_dispose(batch);247 ret = hc_schedule(hc, batch); 248 if (ret != EOK) { 249 usb_transfer_batch_dispose(batch); 270 250 } 271 251 return ret; … … 281 261 * @param[in] fun Device function the action was invoked on. 282 262 * @param[in] target Target pipe (address and endpoint number) specification. 283 * @param[in] max_packet_size Max packet size for the transfer.284 263 * @param[in] data Data to be sent (in USB endianess, allocated and deallocated 285 264 * by the caller). … … 290 269 */ 291 270 static int bulk_out( 292 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,271 ddf_fun_t *fun, usb_target_t target, void *data, 293 272 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 294 273 { 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; 274 usb_transfer_batch_t *batch = NULL; 275 hc_t *hc = NULL; 276 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 277 NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch); 278 if (ret != EOK) 279 return ret; 309 280 batch_bulk_out(batch); 310 const intret = hc_schedule(hc, batch);311 if (ret != EOK) { 312 batch_dispose(batch);281 ret = hc_schedule(hc, batch); 282 if (ret != EOK) { 283 usb_transfer_batch_dispose(batch); 313 284 } 314 285 return ret; … … 324 295 * @param[in] fun Device function the action was invoked on. 325 296 * @param[in] target Target pipe (address and endpoint number) specification. 326 * @param[in] max_packet_size Max packet size for the transfer.327 297 * @param[in] data Buffer where to store the data (in USB endianess, 328 298 * allocated and deallocated by the caller). … … 333 303 */ 334 304 static int bulk_in( 335 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,305 ddf_fun_t *fun, usb_target_t target, void *data, 336 306 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 337 307 { 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; 308 usb_transfer_batch_t *batch = NULL; 309 hc_t *hc = NULL; 310 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 311 NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch); 312 if (ret != EOK) 313 return ret; 351 314 batch_bulk_in(batch); 352 const intret = hc_schedule(hc, batch);353 if (ret != EOK) { 354 batch_dispose(batch);315 ret = hc_schedule(hc, batch); 316 if (ret != EOK) { 317 usb_transfer_batch_dispose(batch); 355 318 } 356 319 return ret; … … 366 329 * @param[in] fun Device function the action was invoked on. 367 330 * @param[in] target Target pipe (address and endpoint number) specification. 368 * @param[in] max_packet_size Max packet size for the transfer.369 331 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated 370 332 * and deallocated by the caller). 371 * @param[in] setup_ packet_size Size of @p setup_packet buffer in bytes.333 * @param[in] setup_size Size of @p setup_packet buffer in bytes. 372 334 * @param[in] data_buffer Data buffer (in USB endianess, allocated and 373 335 * deallocated by the caller). 374 * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.336 * @param[in] size Size of @p data_buffer buffer in bytes. 375 337 * @param[in] callback Callback to be issued once the transfer is complete. 376 338 * @param[in] arg Pass-through argument to the callback. … … 378 340 */ 379 341 static int control_write( 380 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,342 ddf_fun_t *fun, usb_target_t target, 381 343 void *setup_data, size_t setup_size, void *data, size_t size, 382 344 usbhc_iface_transfer_out_callback_t callback, void *arg) 383 345 { 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); 346 usb_transfer_batch_t *batch = NULL; 347 hc_t *hc = NULL; 348 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 349 setup_data, setup_size, NULL, callback, arg, "Control WRITE", 350 &hc, &batch); 351 if (ret != EOK) 352 return ret; 353 usb_endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data); 402 354 batch_control_write(batch); 403 const intret = hc_schedule(hc, batch);404 if (ret != EOK) { 405 batch_dispose(batch);355 ret = hc_schedule(hc, batch); 356 if (ret != EOK) { 357 usb_transfer_batch_dispose(batch); 406 358 } 407 359 return ret; … … 417 369 * @param[in] fun Device function the action was invoked on. 418 370 * @param[in] target Target pipe (address and endpoint number) specification. 419 * @param[in] max_packet_size Max packet size for the transfer.420 371 * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated 421 372 * and deallocated by the caller). 422 * @param[in] setup_ packet_size Size of @p setup_packet buffer in bytes.373 * @param[in] setup_size Size of @p setup_packet buffer in bytes. 423 374 * @param[in] data_buffer Buffer where to store the data (in USB endianess, 424 375 * allocated and deallocated by the caller). 425 * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.376 * @param[in] size Size of @p data_buffer buffer in bytes. 426 377 * @param[in] callback Callback to be issued once the transfer is complete. 427 378 * @param[in] arg Pass-through argument to the callback. … … 429 380 */ 430 381 static int control_read( 431 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,382 ddf_fun_t *fun, usb_target_t target, 432 383 void *setup_data, size_t setup_size, void *data, size_t size, 433 384 usbhc_iface_transfer_in_callback_t callback, void *arg) 434 385 { 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; 386 usb_transfer_batch_t *batch = NULL; 387 hc_t *hc = NULL; 388 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 389 setup_data, setup_size, callback, NULL, arg, "Control READ", 390 &hc, &batch); 391 if (ret != EOK) 392 return ret; 449 393 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. */ 394 ret = hc_schedule(hc, batch); 395 if (ret != EOK) { 396 usb_transfer_batch_dispose(batch); 397 } 398 return ret; 399 } 400 /*----------------------------------------------------------------------------*/ 458 401 usbhc_iface_t hc_iface = { 459 .reserve_default_address = reserve_default_address,460 .release_default_address = release_default_address,461 402 .request_address = request_address, 462 403 .bind_address = bind_address, … … 475 416 .control_read = control_read, 476 417 }; 477 478 418 /** 479 419 * @}
Note:
See TracChangeset
for help on using the changeset viewer.