Changeset e50cd7f in mainline for uspace/drv/uhci-hcd/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/uhci-hcd/iface.c
ref354b6 re50cd7f 41 41 #include "hc.h" 42 42 43 /** Reserve default address interface function 44 * 45 * @param[in] fun DDF function that was called. 46 * @param[in] speed Speed to associate with the new default address. 47 * @return Error code. 48 */ 49 static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed) 50 { 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); 51 52 assert(fun); 52 hc_t *hc = fun_to_hc(fun); 53 assert(hc); 54 usb_log_debug("Default address request with speed %d.\n", speed); 55 usb_device_keeper_reserve_default_address(&hc->manager, speed); 56 return EOK; 57 #if 0 58 endpoint_t *ep = malloc(sizeof(endpoint_t)); 59 if (ep == NULL) 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) 60 80 return ENOMEM; 61 const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64;62 endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size);63 int ret;64 try_retgister:65 ret = usb_endpoint_manager_register_ep(&hc->ep_manager,66 USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0);67 if (ret == EEXISTS) {68 async_usleep(1000);69 goto try_retgister;70 }71 if (ret != EOK) {72 endpoint_destroy(ep);73 }74 return ret;75 #endif76 }77 /*----------------------------------------------------------------------------*/78 /** Release default address interface function79 *80 * @param[in] fun DDF function that was called.81 * @return Error code.82 */83 static int release_default_address(ddf_fun_t *fun)84 {85 assert(fun);86 hc_t *hc = fun_to_hc(fun);87 assert(hc);88 usb_log_debug("Default address release.\n");89 // return usb_endpoint_manager_unregister_ep(&hc->ep_manager,90 // USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH);91 usb_device_keeper_release_default_address(&hc->manager);92 81 return EOK; 93 82 } … … 151 140 /*----------------------------------------------------------------------------*/ 152 141 static int register_endpoint( 153 ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint, 142 ddf_fun_t *fun, usb_address_t address, usb_speed_t ep_speed, 143 usb_endpoint_t endpoint, 154 144 usb_transfer_type_t transfer_type, usb_direction_t direction, 155 145 size_t max_packet_size, unsigned int interval) … … 157 147 hc_t *hc = fun_to_hc(fun); 158 148 assert(hc); 159 const usb_speed_t speed = 160 usb_device_keeper_get_speed(&hc->manager, address); 161 const size_t size = 162 (transfer_type == USB_TRANSFER_INTERRUPT 163 || transfer_type == USB_TRANSFER_ISOCHRONOUS) ? 164 max_packet_size : 0; 165 int ret; 166 167 endpoint_t *ep = malloc(sizeof(endpoint_t)); 168 if (ep == NULL) 169 return ENOMEM; 170 ret = endpoint_init(ep, address, endpoint, direction, 171 transfer_type, speed, max_packet_size); 172 if (ret != EOK) { 173 free(ep); 174 return ret; 175 } 176 149 const size_t size = max_packet_size; 150 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address); 151 if (speed >= USB_SPEED_MAX) { 152 speed = ep_speed; 153 } 177 154 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n", 178 155 address, endpoint, usb_str_transfer_type(transfer_type), 179 156 usb_str_speed(speed), direction, size, max_packet_size, interval); 180 157 181 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size); 182 if (ret != EOK) { 183 endpoint_destroy(ep); 184 } else { 185 usb_device_keeper_add_ep(&hc->manager, address, ep); 186 } 187 return ret; 158 return usb_endpoint_manager_add_ep(&hc->ep_manager, address, endpoint, 159 direction, transfer_type, speed, max_packet_size, size); 188 160 } 189 161 /*----------------------------------------------------------------------------*/ … … 204 176 * @param[in] fun DDF function that was called. 205 177 * @param[in] target USB device to write to. 206 * @param[in] max_packet_size maximum size of data packet the device accepts207 178 * @param[in] data Source of data. 208 179 * @param[in] size Size of data source. … … 212 183 */ 213 184 static int interrupt_out( 214 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,185 ddf_fun_t *fun, usb_target_t target, void *data, 215 186 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 216 187 { 217 assert(fun); 218 hc_t *hc = fun_to_hc(fun); 219 assert(hc); 220 221 usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n", 222 target.address, target.endpoint, size, max_packet_size); 223 224 size_t res_bw; 225 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 226 target.address, target.endpoint, USB_DIRECTION_OUT, &res_bw); 227 if (ep == NULL) { 228 usb_log_error("Endpoint(%d:%d) not registered for INT OUT.\n", 229 target.address, target.endpoint); 230 return ENOENT; 231 } 232 const size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type, 233 size, ep->max_packet_size); 234 if (res_bw < bw) 235 { 236 usb_log_error("Endpoint(%d:%d) INT IN needs %zu bw " 237 "but only %zu is reserved.\n", 238 target.address, target.endpoint, bw, res_bw); 239 return ENOENT; 240 } 241 assert(ep->speed == 242 usb_device_keeper_get_speed(&hc->manager, target.address)); 243 assert(ep->max_packet_size == max_packet_size); 244 assert(ep->transfer_type == USB_TRANSFER_INTERRUPT); 245 246 usb_transfer_batch_t *batch = 247 batch_get(fun, target, ep->transfer_type, ep->max_packet_size, 248 ep->speed, data, size, NULL, 0, NULL, callback, arg, ep); 249 if (!batch) 250 return ENOMEM; 188 usb_transfer_batch_t *batch = NULL; 189 hc_t *hc = NULL; 190 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 191 NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch); 192 if (ret != EOK) 193 return ret; 251 194 batch_interrupt_out(batch); 252 const intret = hc_schedule(hc, batch);253 if (ret != EOK) { 254 batch_dispose(batch);195 ret = hc_schedule(hc, batch); 196 if (ret != EOK) { 197 usb_transfer_batch_dispose(batch); 255 198 } 256 199 return ret; … … 261 204 * @param[in] fun DDF function that was called. 262 205 * @param[in] target USB device to write to. 263 * @param[in] max_packet_size maximum size of data packet the device accepts264 206 * @param[out] data Data destination. 265 207 * @param[in] size Size of data source. … … 269 211 */ 270 212 static int interrupt_in( 271 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,213 ddf_fun_t *fun, usb_target_t target, void *data, 272 214 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 273 215 { 274 assert(fun); 275 hc_t *hc = fun_to_hc(fun); 276 assert(hc); 277 278 usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n", 279 target.address, target.endpoint, size, max_packet_size); 280 281 size_t res_bw; 282 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 283 target.address, target.endpoint, USB_DIRECTION_IN, &res_bw); 284 if (ep == NULL) { 285 usb_log_error("Endpoint(%d:%d) not registered for INT IN.\n", 286 target.address, target.endpoint); 287 return ENOENT; 288 } 289 const size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type, 290 size, ep->max_packet_size); 291 if (res_bw < bw) 292 { 293 usb_log_error("Endpoint(%d:%d) INT IN needs %zu bw " 294 "but only %zu bw is reserved.\n", 295 target.address, target.endpoint, bw, res_bw); 296 return ENOENT; 297 } 298 299 assert(ep->speed == 300 usb_device_keeper_get_speed(&hc->manager, target.address)); 301 assert(ep->max_packet_size == max_packet_size); 302 assert(ep->transfer_type == USB_TRANSFER_INTERRUPT); 303 304 usb_transfer_batch_t *batch = 305 batch_get(fun, target, ep->transfer_type, ep->max_packet_size, 306 ep->speed, data, size, NULL, 0, callback, NULL, arg, ep); 307 if (!batch) 308 return ENOMEM; 216 usb_transfer_batch_t *batch = NULL; 217 hc_t *hc = NULL; 218 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 219 NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch); 220 if (ret != EOK) 221 return ret; 309 222 batch_interrupt_in(batch); 310 const intret = hc_schedule(hc, batch);311 if (ret != EOK) { 312 batch_dispose(batch);223 ret = hc_schedule(hc, batch); 224 if (ret != EOK) { 225 usb_transfer_batch_dispose(batch); 313 226 } 314 227 return ret; … … 319 232 * @param[in] fun DDF function that was called. 320 233 * @param[in] target USB device to write to. 321 * @param[in] max_packet_size maximum size of data packet the device accepts322 234 * @param[in] data Source of data. 323 235 * @param[in] size Size of data source. … … 327 239 */ 328 240 static int bulk_out( 329 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,241 ddf_fun_t *fun, usb_target_t target, void *data, 330 242 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 331 243 { 332 assert(fun); 333 hc_t *hc = fun_to_hc(fun); 334 assert(hc); 335 336 usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n", 337 target.address, target.endpoint, size, max_packet_size); 338 339 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 340 target.address, target.endpoint, USB_DIRECTION_OUT, NULL); 341 if (ep == NULL) { 342 usb_log_error("Endpoint(%d:%d) not registered for BULK OUT.\n", 343 target.address, target.endpoint); 344 return ENOENT; 345 } 346 assert(ep->speed == 347 usb_device_keeper_get_speed(&hc->manager, target.address)); 348 assert(ep->max_packet_size == max_packet_size); 349 assert(ep->transfer_type == USB_TRANSFER_BULK); 350 351 usb_transfer_batch_t *batch = 352 batch_get(fun, target, ep->transfer_type, ep->max_packet_size, 353 ep->speed, data, size, NULL, 0, NULL, callback, arg, ep); 354 if (!batch) 355 return ENOMEM; 244 usb_transfer_batch_t *batch = NULL; 245 hc_t *hc = NULL; 246 int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size, 247 NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch); 248 if (ret != EOK) 249 return ret; 356 250 batch_bulk_out(batch); 357 const intret = hc_schedule(hc, batch);358 if (ret != EOK) { 359 batch_dispose(batch);251 ret = hc_schedule(hc, batch); 252 if (ret != EOK) { 253 usb_transfer_batch_dispose(batch); 360 254 } 361 255 return ret; … … 366 260 * @param[in] fun DDF function that was called. 367 261 * @param[in] target USB device to write to. 368 * @param[in] max_packet_size maximum size of data packet the device accepts369 262 * @param[out] data Data destination. 370 263 * @param[in] size Size of data source. … … 374 267 */ 375 268 static int bulk_in( 376 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,void *data,269 ddf_fun_t *fun, usb_target_t target, void *data, 377 270 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 378 271 { 379 assert(fun); 380 hc_t *hc = fun_to_hc(fun); 381 assert(hc); 382 usb_log_debug("Bulk IN %d:%d %zu(%zu).\n", 383 target.address, target.endpoint, size, max_packet_size); 384 385 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 386 target.address, target.endpoint, USB_DIRECTION_IN, NULL); 387 if (ep == NULL) { 388 usb_log_error("Endpoint(%d:%d) not registered for BULK IN.\n", 389 target.address, target.endpoint); 390 return ENOENT; 391 } 392 assert(ep->speed == 393 usb_device_keeper_get_speed(&hc->manager, target.address)); 394 assert(ep->max_packet_size == max_packet_size); 395 assert(ep->transfer_type == USB_TRANSFER_BULK); 396 397 usb_transfer_batch_t *batch = 398 batch_get(fun, target, ep->transfer_type, ep->max_packet_size, 399 ep->speed, data, size, NULL, 0, callback, NULL, arg, ep); 400 if (!batch) 401 return ENOMEM; 272 usb_transfer_batch_t *batch = NULL; 273 hc_t *hc = NULL; 274 int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size, 275 NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch); 276 if (ret != EOK) 277 return ret; 402 278 batch_bulk_in(batch); 403 const intret = hc_schedule(hc, batch);404 if (ret != EOK) { 405 batch_dispose(batch);279 ret = hc_schedule(hc, batch); 280 if (ret != EOK) { 281 usb_transfer_batch_dispose(batch); 406 282 } 407 283 return ret; … … 412 288 * @param[in] fun DDF function that was called. 413 289 * @param[in] target USB device to write to. 414 * @param[in] max_packet_size maximum size of data packet the device accepts.415 290 * @param[in] setup_data Data to send with SETUP transfer. 416 291 * @param[in] setup_size Size of data to send with SETUP transfer (always 8B). … … 422 297 */ 423 298 static int control_write( 424 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,299 ddf_fun_t *fun, usb_target_t target, 425 300 void *setup_data, size_t setup_size, void *data, size_t size, 426 301 usbhc_iface_transfer_out_callback_t callback, void *arg) 427 302 { 428 assert(fun); 429 hc_t *hc = fun_to_hc(fun); 430 assert(hc); 431 usb_speed_t speed = 432 usb_device_keeper_get_speed(&hc->manager, target.address); 433 usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n", 434 speed, target.address, target.endpoint, size, max_packet_size); 435 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 436 target.address, target.endpoint, USB_DIRECTION_BOTH, NULL); 437 if (ep == NULL) { 438 usb_log_warning("Endpoint(%d:%d) not registered for CONTROL.\n", 439 target.address, target.endpoint); 440 } 441 442 if (setup_size != 8) 443 return EINVAL; 444 445 usb_transfer_batch_t *batch = 446 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed, 447 data, size, setup_data, setup_size, NULL, callback, arg, ep); 448 if (!batch) 449 return ENOMEM; 450 usb_device_keeper_reset_if_need(&hc->manager, target, setup_data); 303 usb_transfer_batch_t *batch = NULL; 304 hc_t *hc = NULL; 305 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 306 setup_data, setup_size, NULL, callback, arg, "Control WRITE", 307 &hc, &batch); 308 if (ret != EOK) 309 return ret; 310 usb_endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data); 451 311 batch_control_write(batch); 452 const intret = hc_schedule(hc, batch);453 if (ret != EOK) { 454 batch_dispose(batch);312 ret = hc_schedule(hc, batch); 313 if (ret != EOK) { 314 usb_transfer_batch_dispose(batch); 455 315 } 456 316 return ret; … … 461 321 * @param[in] fun DDF function that was called. 462 322 * @param[in] target USB device to write to. 463 * @param[in] max_packet_size maximum size of data packet the device accepts.464 323 * @param[in] setup_data Data to send with SETUP packet. 465 324 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B). … … 471 330 */ 472 331 static int control_read( 473 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size,332 ddf_fun_t *fun, usb_target_t target, 474 333 void *setup_data, size_t setup_size, void *data, size_t size, 475 334 usbhc_iface_transfer_in_callback_t callback, void *arg) 476 335 { 477 assert(fun); 478 hc_t *hc = fun_to_hc(fun); 479 assert(hc); 480 usb_speed_t speed = 481 usb_device_keeper_get_speed(&hc->manager, target.address); 482 483 usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n", 484 speed, target.address, target.endpoint, size, max_packet_size); 485 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager, 486 target.address, target.endpoint, USB_DIRECTION_BOTH, NULL); 487 if (ep == NULL) { 488 usb_log_warning("Endpoint(%d:%d) not registered for CONTROL.\n", 489 target.address, target.endpoint); 490 } 491 usb_transfer_batch_t *batch = 492 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed, 493 data, size, setup_data, setup_size, callback, NULL, arg, ep); 494 if (!batch) 495 return ENOMEM; 336 usb_transfer_batch_t *batch = NULL; 337 hc_t *hc = NULL; 338 int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size, 339 setup_data, setup_size, callback, NULL, arg, "Control READ", 340 &hc, &batch); 341 if (ret != EOK) 342 return ret; 496 343 batch_control_read(batch); 497 const intret = hc_schedule(hc, batch);498 if (ret != EOK) { 499 batch_dispose(batch);344 ret = hc_schedule(hc, batch); 345 if (ret != EOK) { 346 usb_transfer_batch_dispose(batch); 500 347 } 501 348 return ret; … … 503 350 /*----------------------------------------------------------------------------*/ 504 351 usbhc_iface_t hc_iface = { 505 .reserve_default_address = reserve_default_address,506 .release_default_address = release_default_address,507 352 .request_address = request_address, 508 353 .bind_address = bind_address,
Note:
See TracChangeset
for help on using the changeset viewer.