Changes in uspace/lib/usbhost/src/ddf_helpers.c [816f5f4:cccd60c3] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/ddf_helpers.c
r816f5f4 rcccd60c3 35 35 36 36 #include <usb/classes/classes.h> 37 #include <usb/host/bus.h>38 37 #include <usb/debug.h> 39 38 #include <usb/descriptor.h> … … 47 46 #include <ddf/interrupt.h> 48 47 #include <device/hw_res_parsed.h> 49 #include <devman.h>50 48 #include <errno.h> 51 49 #include <fibril_synch.h> 52 50 #include <macros.h> 51 #include <stdio.h> 53 52 #include <stdlib.h> 54 53 #include <str_error.h> … … 57 56 #include "ddf_helpers.h" 58 57 58 #define CTRL_PIPE_MIN_PACKET_SIZE 8 59 60 typedef struct usb_dev { 61 link_t link; 62 list_t devices; 63 fibril_mutex_t guard; 64 ddf_fun_t *fun; 65 usb_address_t address; 66 usb_speed_t speed; 67 usb_address_t tt_address; 68 unsigned port; 69 } usb_dev_t; 70 59 71 typedef struct hc_dev { 60 72 ddf_fun_t *ctl_fun; 61 73 hcd_t hcd; 74 usb_dev_t *root_hub; 62 75 } hc_dev_t; 63 76 … … 78 91 79 92 80 static int hcd_ddf_new_device( hcd_t *hcd, ddf_dev_t *hc, device_t *hub_dev, unsigned port);81 static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub, unsigned port);93 static int hcd_ddf_new_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port); 94 static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port); 82 95 83 96 … … 86 99 /** Register endpoint interface function. 87 100 * @param fun DDF function. 88 * @param endpoint_desc Endpoint description. 101 * @param address USB address of the device. 102 * @param endpoint USB endpoint number to be registered. 103 * @param transfer_type Endpoint's transfer type. 104 * @param direction USB communication direction the endpoint is capable of. 105 * @param max_packet_size Maximu size of packets the endpoint accepts. 106 * @param interval Preferred timeout between communication. 89 107 * @return Error code. 90 108 */ 91 109 static int register_endpoint( 92 ddf_fun_t *fun, usb_endpoint_desc_t *endpoint_desc) 110 ddf_fun_t *fun, usb_endpoint_t endpoint, 111 usb_transfer_type_t transfer_type, usb_direction_t direction, 112 size_t max_packet_size, unsigned packets, unsigned interval) 93 113 { 94 114 assert(fun); 95 115 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 96 device_t *dev = ddf_fun_data_get(fun);116 usb_dev_t *dev = ddf_fun_data_get(fun); 97 117 assert(hcd); 98 assert(hcd->bus);99 118 assert(dev); 100 101 const size_t size = endpoint_desc->max_packet_size; 119 const size_t size = max_packet_size; 120 const usb_target_t target = 121 {{.address = dev->address, .endpoint = endpoint}}; 102 122 103 123 usb_log_debug("Register endpoint %d:%d %s-%s %zuB %ums.\n", 104 dev->address, endpoint_desc->endpoint_no, 105 usb_str_transfer_type(endpoint_desc->transfer_type), 106 usb_str_direction(endpoint_desc->direction), 107 endpoint_desc->max_packet_size, endpoint_desc->usb2.polling_interval); 108 109 return bus_add_ep(hcd->bus, dev, endpoint_desc->endpoint_no, 110 endpoint_desc->direction, endpoint_desc->transfer_type, 111 endpoint_desc->max_packet_size, endpoint_desc->packets, 112 size); 113 } 114 115 /** Unregister endpoint interface function. 116 * @param fun DDF function. 117 * @param endpoint_desc Endpoint description. 118 * @return Error code. 119 */ 124 dev->address, endpoint, usb_str_transfer_type(transfer_type), 125 usb_str_direction(direction), max_packet_size, interval); 126 127 return hcd_add_ep(hcd, target, direction, transfer_type, 128 max_packet_size, packets, size, dev->tt_address, dev->port); 129 } 130 131 /** Unregister endpoint interface function. 132 * @param fun DDF function. 133 * @param address USB address of the endpoint. 134 * @param endpoint USB endpoint number. 135 * @param direction Communication direction of the enpdoint to unregister. 136 * @return Error code. 137 */ 120 138 static int unregister_endpoint( 121 ddf_fun_t *fun, usb_endpoint_desc_t *endpoint_desc)139 ddf_fun_t *fun, usb_endpoint_t endpoint, usb_direction_t direction) 122 140 { 123 141 assert(fun); 124 142 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 125 device_t *dev = ddf_fun_data_get(fun);143 usb_dev_t *dev = ddf_fun_data_get(fun); 126 144 assert(hcd); 127 assert(hcd->bus);128 145 assert(dev); 129 130 const usb_target_t target = {{ 131 .address = dev->address, 132 .endpoint = endpoint_desc->endpoint_no 133 }}; 134 146 const usb_target_t target = 147 {{.address = dev->address, .endpoint = endpoint}}; 135 148 usb_log_debug("Unregister endpoint %d:%d %s.\n", 136 dev->address, endpoint_desc->endpoint_no, 137 usb_str_direction(endpoint_desc->direction)); 138 return bus_remove_ep(hcd->bus, target, endpoint_desc->direction); 149 dev->address, endpoint, usb_str_direction(direction)); 150 return hcd_remove_ep(hcd, target, direction); 139 151 } 140 152 … … 143 155 assert(fun); 144 156 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 145 device_t *dev = ddf_fun_data_get(fun);157 usb_dev_t *dev = ddf_fun_data_get(fun); 146 158 assert(hcd); 147 assert(hcd->bus);148 159 assert(dev); 149 160 150 161 usb_log_debug("Device %d requested default address at %s speed\n", 151 162 dev->address, usb_str_speed(speed)); 152 return bus_reserve_default_address(hcd->bus, speed);163 return hcd_reserve_default_address(hcd, speed); 153 164 } 154 165 … … 157 168 assert(fun); 158 169 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 159 device_t *dev = ddf_fun_data_get(fun);170 usb_dev_t *dev = ddf_fun_data_get(fun); 160 171 assert(hcd); 161 assert(hcd->bus);162 172 assert(dev); 163 173 164 174 usb_log_debug("Device %d released default address\n", dev->address); 165 return bus_release_default_address(hcd->bus);175 return hcd_release_default_address(hcd); 166 176 } 167 177 168 178 static int device_enumerate(ddf_fun_t *fun, unsigned port) 169 {170 assert(fun);171 ddf_dev_t *hc = ddf_fun_get_dev(fun);172 assert(hc);173 hcd_t *hcd = dev_to_hcd(hc);174 assert(hcd);175 device_t *hub = ddf_fun_data_get(fun);176 assert(hub);177 178 usb_log_debug("Hub %d reported a new USB device on port: %u\n",179 hub->address, port);180 return hcd_ddf_new_device(hcd, hc, hub, port);181 }182 183 static int device_remove(ddf_fun_t *fun, unsigned port)184 179 { 185 180 assert(fun); 186 181 ddf_dev_t *ddf_dev = ddf_fun_get_dev(fun); 187 device_t *dev = ddf_fun_data_get(fun); 182 usb_dev_t *dev = ddf_fun_data_get(fun); 183 assert(ddf_dev); 184 assert(dev); 185 usb_log_debug("Hub %d reported a new USB device on port: %u\n", 186 dev->address, port); 187 return hcd_ddf_new_device(ddf_dev, dev, port); 188 } 189 190 static int device_remove(ddf_fun_t *fun, unsigned port) 191 { 192 assert(fun); 193 ddf_dev_t *ddf_dev = ddf_fun_get_dev(fun); 194 usb_dev_t *dev = ddf_fun_data_get(fun); 188 195 assert(ddf_dev); 189 196 assert(dev); … … 222 229 { 223 230 assert(fun); 224 device_t *dev = ddf_fun_data_get(fun);225 assert( dev);231 usb_dev_t *usb_dev = ddf_fun_data_get(fun); 232 assert(usb_dev); 226 233 const usb_target_t target = {{ 227 .address =dev->address,234 .address = usb_dev->address, 228 235 .endpoint = endpoint, 229 236 }}; … … 248 255 { 249 256 assert(fun); 250 device_t *dev = ddf_fun_data_get(fun);251 assert( dev);257 usb_dev_t *usb_dev = ddf_fun_data_get(fun); 258 assert(usb_dev); 252 259 const usb_target_t target = {{ 253 .address =dev->address,260 .address = usb_dev->address, 254 261 .endpoint = endpoint, 255 262 }}; … … 283 290 284 291 /* DDF HELPERS */ 292 293 #define GET_DEVICE_DESC(size) \ 294 { \ 295 .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST \ 296 | (USB_REQUEST_TYPE_STANDARD << 5) \ 297 | USB_REQUEST_RECIPIENT_DEVICE, \ 298 .request = USB_DEVREQ_GET_DESCRIPTOR, \ 299 .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), \ 300 .index = uint16_host2usb(0), \ 301 .length = uint16_host2usb(size), \ 302 }; 303 304 #define SET_ADDRESS(address) \ 305 { \ 306 .request_type = SETUP_REQUEST_TYPE_HOST_TO_DEVICE \ 307 | (USB_REQUEST_TYPE_STANDARD << 5) \ 308 | USB_REQUEST_RECIPIENT_DEVICE, \ 309 .request = USB_DEVREQ_SET_ADDRESS, \ 310 .value = uint16_host2usb(address), \ 311 .index = uint16_host2usb(0), \ 312 .length = uint16_host2usb(0), \ 313 }; 314 315 static int hcd_ddf_add_device(ddf_dev_t *parent, usb_dev_t *hub_dev, 316 unsigned port, usb_address_t address, usb_speed_t speed, const char *name, 317 const match_id_list_t *mids) 318 { 319 assert(parent); 320 321 char default_name[10] = { 0 }; /* usbxyz-ss */ 322 if (!name) { 323 snprintf(default_name, sizeof(default_name) - 1, 324 "usb%u-%cs", address, usb_str_speed(speed)[0]); 325 name = default_name; 326 } 327 328 ddf_fun_t *fun = ddf_fun_create(parent, fun_inner, name); 329 if (!fun) 330 return ENOMEM; 331 usb_dev_t *info = ddf_fun_data_alloc(fun, sizeof(usb_dev_t)); 332 if (!info) { 333 ddf_fun_destroy(fun); 334 return ENOMEM; 335 } 336 info->address = address; 337 info->speed = speed; 338 info->fun = fun; 339 info->port = port; 340 info->tt_address = hub_dev ? hub_dev->tt_address : -1; 341 link_initialize(&info->link); 342 list_initialize(&info->devices); 343 fibril_mutex_initialize(&info->guard); 344 345 if (hub_dev && hub_dev->speed == USB_SPEED_HIGH && usb_speed_is_11(speed)) 346 info->tt_address = hub_dev->address; 347 348 ddf_fun_set_ops(fun, &usb_ops); 349 list_foreach(mids->ids, link, const match_id_t, mid) { 350 ddf_fun_add_match_id(fun, mid->id, mid->score); 351 } 352 353 int ret = ddf_fun_bind(fun); 354 if (ret != EOK) { 355 ddf_fun_destroy(fun); 356 return ret; 357 } 358 359 if (hub_dev) { 360 fibril_mutex_lock(&hub_dev->guard); 361 list_append(&info->link, &hub_dev->devices); 362 fibril_mutex_unlock(&hub_dev->guard); 363 } else { 364 hc_dev_t *hc_dev = dev_to_hc_dev(parent); 365 assert(hc_dev->root_hub == NULL); 366 hc_dev->root_hub = info; 367 } 368 return EOK; 369 } 285 370 286 371 #define ADD_MATCHID_OR_RETURN(list, sc, str, ...) \ … … 309 394 assert(l); 310 395 assert(d); 311 396 312 397 if (d->vendor_id != 0) { 313 398 /* First, with release number. */ … … 316 401 d->vendor_id, d->product_id, (d->device_version >> 8), 317 402 (d->device_version & 0xff)); 318 403 319 404 /* Next, without release number. */ 320 405 ADD_MATCHID_OR_RETURN(l, 90, "usb&vendor=%#04x&product=%#04x", … … 330 415 331 416 return EOK; 332 } 333 334 static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub, 417 418 } 419 420 static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub, 335 421 unsigned port) 336 422 { … … 339 425 hcd_t *hcd = dev_to_hcd(device); 340 426 assert(hcd); 341 assert(hcd->bus);342 427 343 428 hc_dev_t *hc_dev = dev_to_hc_dev(device); … … 346 431 fibril_mutex_lock(&hub->guard); 347 432 348 device_t *victim = NULL;349 350 list_foreach(hub->devices, link, device_t, it) {433 usb_dev_t *victim = NULL; 434 435 list_foreach(hub->devices, link, usb_dev_t, it) { 351 436 if (it->port == port) { 352 437 victim = it; … … 355 440 } 356 441 if (victim) { 357 assert(victim->fun);358 442 assert(victim->port == port); 359 assert(victim->hub == hub);360 443 list_remove(&victim->link); 361 444 fibril_mutex_unlock(&hub->guard); … … 363 446 if (ret == EOK) { 364 447 usb_address_t address = victim->address; 365 bus_remove_device(hcd->bus, hcd, victim);366 448 ddf_fun_destroy(victim->fun); 367 bus_release_address(hcd->bus, address);449 hcd_release_address(hcd, address); 368 450 } else { 369 451 usb_log_warning("Failed to unbind device `%s': %s\n", … … 376 458 } 377 459 378 device_t *hcd_ddf_device_create(ddf_dev_t *hc, size_t device_size) 379 { 380 /* Create DDF function for the new device */ 381 ddf_fun_t *fun = ddf_fun_create(hc, fun_inner, NULL); 382 if (!fun) 383 return NULL; 384 385 ddf_fun_set_ops(fun, &usb_ops); 386 387 /* Create USB device node for the new device */ 388 device_t *dev = ddf_fun_data_alloc(fun, device_size); 389 if (!dev) { 390 ddf_fun_destroy(fun); 391 return NULL; 392 } 393 394 device_init(dev); 395 dev->fun = fun; 396 return dev; 397 } 398 399 void hcd_ddf_device_destroy(device_t *dev) 400 { 401 assert(dev); 402 assert(dev->fun); 403 ddf_fun_destroy(dev->fun); 404 } 405 406 int hcd_ddf_device_explore(hcd_t *hcd, device_t *device) 407 { 408 int err; 409 match_id_list_t mids; 460 static int hcd_ddf_new_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port) 461 { 462 assert(device); 463 464 hcd_t *hcd = dev_to_hcd(device); 465 assert(hcd); 466 467 usb_speed_t speed = USB_SPEED_MAX; 468 469 /* This checks whether the default address is reserved and gets speed */ 470 int ret = usb_bus_get_speed(&hcd->bus, USB_ADDRESS_DEFAULT, &speed); 471 if (ret != EOK) { 472 usb_log_error("Failed to verify speed: %s.", str_error(ret)); 473 return ret; 474 } 475 476 usb_log_debug("Found new %s speed USB device.", usb_str_speed(speed)); 477 478 static const usb_target_t default_target = {{ 479 .address = USB_ADDRESS_DEFAULT, 480 .endpoint = 0, 481 }}; 482 483 const usb_address_t address = hcd_request_address(hcd, speed); 484 if (address < 0) { 485 usb_log_error("Failed to reserve new address: %s.", 486 str_error(address)); 487 return address; 488 } 489 490 usb_log_debug("Reserved new address: %d\n", address); 491 492 const usb_target_t target = {{ 493 .address = address, 494 .endpoint = 0, 495 }}; 496 497 const usb_address_t tt_address = hub ? hub->tt_address : -1; 498 499 /* Add default pipe on default address */ 500 usb_log_debug("Device(%d): Adding default target(0:0)\n", address); 501 ret = hcd_add_ep(hcd, 502 default_target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 503 CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1, 504 tt_address, port); 505 if (ret != EOK) { 506 usb_log_error("Device(%d): Failed to add default target: %s.", 507 address, str_error(ret)); 508 hcd_release_address(hcd, address); 509 return ret; 510 } 511 512 /* Get max packet size for default pipe */ 410 513 usb_standard_device_descriptor_t desc = { 0 }; 411 412 init_match_ids(&mids); 413 414 usb_target_t control_ep = {{ 415 .address = device->address, 416 .endpoint = 0 417 }}; 514 const usb_device_request_setup_packet_t get_device_desc_8 = 515 GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE); 516 517 // TODO CALLBACKS 518 usb_log_debug("Device(%d): Requesting first 8B of device descriptor.", 519 address); 520 ssize_t got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_IN, 521 &desc, CTRL_PIPE_MIN_PACKET_SIZE, *(uint64_t *)&get_device_desc_8, 522 "read first 8 bytes of dev descriptor"); 523 524 if (got != CTRL_PIPE_MIN_PACKET_SIZE) { 525 ret = got < 0 ? got : EOVERFLOW; 526 usb_log_error("Device(%d): Failed to get 8B of dev descr: %s.", 527 address, str_error(ret)); 528 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH); 529 hcd_release_address(hcd, address); 530 return ret; 531 } 532 533 /* Register EP on the new address */ 534 usb_log_debug("Device(%d): Registering control EP.", address); 535 ret = hcd_add_ep(hcd, target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 536 ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)), 537 ED_MPS_TRANS_OPPORTUNITIES_GET(uint16_usb2host(desc.max_packet_size)), 538 ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)), 539 tt_address, port); 540 if (ret != EOK) { 541 usb_log_error("Device(%d): Failed to register EP0: %s", 542 address, str_error(ret)); 543 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH); 544 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 545 hcd_release_address(hcd, address); 546 return ret; 547 } 548 549 /* Set new address */ 550 const usb_device_request_setup_packet_t set_address = 551 SET_ADDRESS(target.address); 552 553 usb_log_debug("Device(%d): Setting USB address.", address); 554 got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT, 555 NULL, 0, *(uint64_t *)&set_address, "set address"); 556 557 usb_log_debug("Device(%d): Removing default (0:0) EP.", address); 558 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH); 559 560 if (got != 0) { 561 usb_log_error("Device(%d): Failed to set new address: %s.", 562 address, str_error(got)); 563 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 564 hcd_release_address(hcd, address); 565 return got; 566 } 418 567 419 568 /* Get std device descriptor */ … … 422 571 423 572 usb_log_debug("Device(%d): Requesting full device descriptor.", 424 device->address);425 ssize_t got = hcd_send_batch_sync(hcd, control_ep, USB_DIRECTION_IN,573 address); 574 got = hcd_send_batch_sync(hcd, target, USB_DIRECTION_IN, 426 575 &desc, sizeof(desc), *(uint64_t *)&get_device_desc, 427 576 "read device descriptor"); 428 if (got < 0) { 429 err = got < 0 ? got : EOVERFLOW; 577 if (ret != EOK) { 430 578 usb_log_error("Device(%d): Failed to set get dev descriptor: %s", 431 device->address, str_error(err)); 432 goto out; 579 address, str_error(ret)); 580 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 581 hcd_release_address(hcd, target.address); 582 return ret; 433 583 } 434 584 435 585 /* Create match ids from the device descriptor */ 436 usb_log_debug("Device(%d): Creating match IDs.", device->address); 437 if ((err = create_match_ids(&mids, &desc))) { 438 usb_log_error("Device(%d): Failed to create match ids: %s", device->address, str_error(err)); 439 goto out; 440 } 441 442 list_foreach(mids.ids, link, const match_id_t, mid) { 443 ddf_fun_add_match_id(device->fun, mid->id, mid->score); 444 } 445 446 out: 586 match_id_list_t mids; 587 init_match_ids(&mids); 588 589 usb_log_debug("Device(%d): Creating match IDs.", address); 590 ret = create_match_ids(&mids, &desc); 591 if (ret != EOK) { 592 usb_log_error("Device(%d): Failed to create match ids: %s", 593 address, str_error(ret)); 594 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 595 hcd_release_address(hcd, target.address); 596 return ret; 597 } 598 599 /* Register device */ 600 usb_log_debug("Device(%d): Registering DDF device.", address); 601 ret = hcd_ddf_add_device(device, hub, port, address, speed, NULL, &mids); 447 602 clean_match_ids(&mids); 448 return err; 449 } 450 451 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, device_t *hub, unsigned port) 452 { 453 int err; 454 assert(hcd); 455 assert(hcd->bus); 456 assert(hub); 457 assert(hc); 458 459 device_t *dev = hcd_ddf_device_create(hc, hcd->bus->device_size); 460 if (!dev) { 461 usb_log_error("Failed to create USB device function."); 462 return ENOMEM; 463 } 464 465 dev->hub = hub; 466 dev->port = port; 467 468 if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) { 469 usb_log_error("Failed to initialize USB dev memory structures."); 470 return err; 471 } 472 473 /* If the driver didn't name the dev when enumerating, 474 * do it in some generic way. 475 */ 476 if (!ddf_fun_get_name(dev->fun)) { 477 device_set_default_name(dev); 478 } 479 480 if ((err = ddf_fun_bind(dev->fun))) { 481 usb_log_error("Device(%d): Failed to register: %s.", dev->address, str_error(err)); 482 goto err_usb_dev; 483 } 484 485 fibril_mutex_lock(&hub->guard); 486 list_append(&dev->link, &hub->devices); 487 fibril_mutex_unlock(&hub->guard); 488 489 return EOK; 490 491 err_usb_dev: 492 hcd_ddf_device_destroy(dev); 493 return err; 603 if (ret != EOK) { 604 usb_log_error("Device(%d): Failed to register: %s.", 605 address, str_error(ret)); 606 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 607 hcd_release_address(hcd, target.address); 608 } 609 610 return ret; 494 611 } 495 612 … … 499 616 * @return Error code 500 617 */ 501 int hcd_setup_virtual_root_hub(hcd_t *hcd, ddf_dev_t *hc) 502 { 503 int err; 504 505 assert(hc); 618 int hcd_ddf_setup_root_hub(ddf_dev_t *device) 619 { 620 assert(device); 621 hcd_t *hcd = dev_to_hcd(device); 506 622 assert(hcd); 507 assert(hcd->bus); 508 509 if ((err = bus_reserve_default_address(hcd->bus, USB_SPEED_MAX))) { 510 usb_log_error("Failed to reserve default address for roothub setup: %s", str_error(err)); 511 return err; 512 } 513 514 device_t *dev = hcd_ddf_device_create(hc, USB_SPEED_MAX); 515 if (!dev) { 516 usb_log_error("Failed to create function for the root hub."); 517 goto err_default_address; 518 } 519 520 ddf_fun_set_name(dev->fun, "roothub"); 521 522 dev->tt = (usb_tt_address_t) { 523 .address = -1, 524 .port = 0, 525 }; 526 527 /* Assign an address to the device */ 528 if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) { 529 usb_log_error("Failed to enumerate roothub device: %s", str_error(err)); 530 goto err_usb_dev; 531 } 532 533 if ((err = ddf_fun_bind(dev->fun))) { 534 usb_log_error("Failed to register roothub: %s.", str_error(err)); 535 goto err_usb_dev; 536 } 537 538 bus_release_default_address(hcd->bus); 539 return EOK; 540 541 err_usb_dev: 542 hcd_ddf_device_destroy(dev); 543 err_default_address: 544 bus_release_default_address(hcd->bus); 545 return err; 623 624 hcd_reserve_default_address(hcd, hcd->bus.max_speed); 625 const int ret = hcd_ddf_new_device(device, NULL, 0); 626 hcd_release_default_address(hcd); 627 return ret; 546 628 } 547 629 … … 556 638 * This function does all the ddf work for hc driver. 557 639 */ 558 int hcd_ddf_setup_hc(ddf_dev_t *device) 640 int hcd_ddf_setup_hc(ddf_dev_t *device, usb_speed_t max_speed, 641 size_t bw, bw_count_func_t bw_count) 559 642 { 560 643 assert(device); … … 565 648 return ENOMEM; 566 649 } 567 hcd_init(&instance->hcd); 650 instance->root_hub = NULL; 651 hcd_init(&instance->hcd, max_speed, bw, bw_count); 568 652 569 653 int ret = ENOMEM; … … 607 691 } 608 692 609 //TODO: Move this to generic ddf?610 /** Call the parent driver with a request to enable interrupt s693 //TODO: Cache parent session in HCD 694 /** Call the parent driver with a request to enable interrupt 611 695 * 612 696 * @param[in] device Device asking for interrupts 697 * @param[in] inum Interrupt number 613 698 * @return Error code. 614 699 */ 615 int hcd_ddf_enable_interrupts(ddf_dev_t *device) 616 { 617 assert(device); 618 async_sess_t *parent_sess = 619 devman_parent_device_connect(ddf_dev_get_handle(device), 620 IPC_FLAG_BLOCKING); 621 const bool enabled = hw_res_enable_interrupt(parent_sess); 622 async_hangup(parent_sess); 623 624 return enabled ? EOK : EIO; 625 } 626 627 //TODO: Move this to generic ddf? 700 int hcd_ddf_enable_interrupt(ddf_dev_t *device, int inum) 701 { 702 async_sess_t *parent_sess = ddf_dev_parent_sess_get(device); 703 if (parent_sess == NULL) 704 return EIO; 705 706 return hw_res_enable_interrupt(parent_sess, inum); 707 } 708 709 //TODO: Cache parent session in HCD 628 710 int hcd_ddf_get_registers(ddf_dev_t *device, hw_res_list_parsed_t *hw_res) 629 711 { 630 assert(device); 631 assert(hw_res); 632 633 async_sess_t *parent_sess = 634 devman_parent_device_connect(ddf_dev_get_handle(device), 635 IPC_FLAG_BLOCKING); 712 async_sess_t *parent_sess = ddf_dev_parent_sess_get(device); 713 if (parent_sess == NULL) 714 return EIO; 715 636 716 hw_res_list_parsed_init(hw_res); 637 717 const int ret = hw_res_get_list_parsed(parent_sess, hw_res, 0); 638 async_hangup(parent_sess);639 718 if (ret != EOK) 640 719 hw_res_list_parsed_clean(hw_res); … … 663 742 * @param[in] gen_irq_code IRQ code generator. 664 743 * 665 * @return EOK on success or negative error code 744 * @return IRQ capability handle on success. 745 * @return Negative error code. 666 746 */ 667 747 int hcd_ddf_setup_interrupts(ddf_dev_t *device, 668 748 const hw_res_list_parsed_t *hw_res, 669 749 interrupt_handler_t handler, 670 irq_code_gen_t gen_irq_code) 671 { 750 int (*gen_irq_code)(irq_code_t *, const hw_res_list_parsed_t *hw_res)) 751 { 752 672 753 assert(device); 673 674 hcd_t *hcd = dev_to_hcd(device);675 676 754 if (!handler || !gen_irq_code) 677 755 return ENOTSUP; … … 679 757 irq_code_t irq_code = {0}; 680 758 681 const int irq = gen_irq_code(&irq_code, h cd, hw_res);759 const int irq = gen_irq_code(&irq_code, hw_res); 682 760 if (irq < 0) { 683 761 usb_log_error("Failed to generate IRQ code: %s.\n", … … 687 765 688 766 /* Register handler to avoid interrupt lockup */ 689 int ret = register_interrupt_handler(device, irq, handler, &irq_code); 767 const int irq_cap = register_interrupt_handler(device, irq, handler, 768 &irq_code); 690 769 irq_code_clean(&irq_code); 770 if (irq_cap < 0) { 771 usb_log_error("Failed to register interrupt handler: %s.\n", 772 str_error(irq_cap)); 773 return irq_cap; 774 } 775 776 /* Enable interrupts */ 777 int ret = hcd_ddf_enable_interrupt(device, irq); 691 778 if (ret != EOK) { 692 779 usb_log_error("Failed to register interrupt handler: %s.\n", 693 780 str_error(ret)); 694 return ret; 695 } 696 697 /* Enable interrupts */ 698 ret = hcd_ddf_enable_interrupts(device); 699 if (ret != EOK) { 700 usb_log_error("Failed to enable interrupts: %s.\n", 701 str_error(ret)); 702 unregister_interrupt_handler(device, irq); 703 return ret; 704 } 705 assert(irq > 0); 706 return irq; 781 unregister_interrupt_handler(device, irq_cap); 782 return ret; 783 } 784 return irq_cap; 707 785 } 708 786 … … 766 844 { 767 845 assert(driver); 846 static const struct { size_t bw; bw_count_func_t bw_count; }bw[] = { 847 [USB_SPEED_FULL] = { .bw = BANDWIDTH_AVAILABLE_USB11, 848 .bw_count = bandwidth_count_usb11 }, 849 [USB_SPEED_HIGH] = { .bw = BANDWIDTH_AVAILABLE_USB11, 850 .bw_count = bandwidth_count_usb11 }, 851 }; 768 852 769 853 int ret = EOK; 854 const usb_speed_t speed = driver->hc_speed; 855 if (speed >= ARRAY_SIZE(bw) || bw[speed].bw == 0) { 856 usb_log_error("Driver `%s' reported unsupported speed: %s", 857 driver->name, usb_str_speed(speed)); 858 return ENOTSUP; 859 } 770 860 771 861 hw_res_list_parsed_t hw_res; … … 778 868 } 779 869 780 ret = hcd_ddf_setup_hc(device );870 ret = hcd_ddf_setup_hc(device, speed, bw[speed].bw, bw[speed].bw_count); 781 871 if (ret != EOK) { 782 872 usb_log_error("Failed to setup generic HCD.\n"); 783 goto err_hw_res; 784 } 785 786 hcd_t *hcd = dev_to_hcd(device); 787 788 if (driver->init) 789 ret = driver->init(hcd, &hw_res); 790 if (ret != EOK) { 791 usb_log_error("Failed to init HCD.\n"); 792 goto err_hcd; 793 } 794 795 /* Setup interrupts */ 873 hw_res_list_parsed_clean(&hw_res); 874 return ret; 875 } 876 796 877 interrupt_handler_t *irq_handler = 797 878 driver->irq_handler ? driver->irq_handler : ddf_hcd_gen_irq_handler; 798 const int irq = hcd_ddf_setup_interrupts(device, &hw_res, irq_handler, driver->irq_code_gen); 799 if (!(irq < 0)) { 879 const int irq_cap = hcd_ddf_setup_interrupts(device, &hw_res, 880 irq_handler, driver->irq_code_gen); 881 bool irqs_enabled = !(irq_cap < 0); 882 if (irqs_enabled) { 800 883 usb_log_debug("Hw interrupts enabled.\n"); 801 884 } 802 885 803 /* Claim the device from BIOS */804 886 if (driver->claim) 805 ret = driver->claim(hcd, device); 806 if (ret != EOK) { 807 usb_log_error("Failed to claim `%s' for driver `%s': %s", 808 ddf_dev_get_name(device), driver->name, str_error(ret)); 809 goto err_irq; 810 } 811 812 /* Start hw driver */ 813 if (driver->start) 814 ret = driver->start(hcd, !(irq < 0)); 815 if (ret != EOK) { 816 usb_log_error("Failed to start HCD: %s.\n", str_error(ret)); 817 goto err_irq; 887 ret = driver->claim(device); 888 if (ret != EOK) { 889 usb_log_error("Failed to claim `%s' for driver `%s'", 890 ddf_dev_get_name(device), driver->name); 891 return ret; 892 } 893 894 895 /* Init hw driver */ 896 hcd_t *hcd = dev_to_hcd(device); 897 ret = driver->init(hcd, &hw_res, irqs_enabled); 898 hw_res_list_parsed_clean(&hw_res); 899 if (ret != EOK) { 900 usb_log_error("Failed to init HCD: %s.\n", str_error(ret)); 901 goto irq_unregister; 818 902 } 819 903 820 904 /* Need working irq replacement to setup root hub */ 821 if ( (irq < 0)&& hcd->ops.status_hook) {905 if (!irqs_enabled && hcd->ops.status_hook) { 822 906 hcd->polling_fibril = fibril_create(interrupt_polling, hcd); 823 907 if (hcd->polling_fibril == 0) { 824 908 usb_log_error("Failed to create polling fibril\n"); 825 909 ret = ENOMEM; 826 goto err_started;910 goto irq_unregister; 827 911 } 828 912 fibril_add_ready(hcd->polling_fibril); 829 913 usb_log_warning("Failed to enable interrupts: %s." 830 " Falling back to polling.\n", str_error(irq ));914 " Falling back to polling.\n", str_error(irq_cap)); 831 915 } 832 916 … … 835 919 * needs to be ready at this time. 836 920 */ 837 if (driver->setup_root_hub) 838 ret = driver->setup_root_hub(hcd, device); 921 ret = hcd_ddf_setup_root_hub(device); 839 922 if (ret != EOK) { 840 923 usb_log_error("Failed to setup HC root hub: %s.\n", 841 924 str_error(ret)); 842 goto err_polling; 925 driver->fini(dev_to_hcd(device)); 926 irq_unregister: 927 /* Unregistering non-existent should be ok */ 928 unregister_interrupt_handler(device, irq_cap); 929 hcd_ddf_clean_hc(device); 930 return ret; 843 931 } 844 932 … … 846 934 driver->name, ddf_dev_get_name(device)); 847 935 return EOK; 848 849 err_polling: 850 // TODO: Stop the polling fibril (refactor the interrupt_polling func) 851 // 852 err_started: 853 if (driver->stop) 854 driver->stop(hcd); 855 err_irq: 856 unregister_interrupt_handler(device, irq); 857 if (driver->fini) 858 driver->fini(hcd); 859 err_hcd: 860 hcd_ddf_clean_hc(device); 861 err_hw_res: 862 hw_res_list_parsed_clean(&hw_res); 863 return ret; 864 } 865 936 } 866 937 /** 867 938 * @}
Note:
See TracChangeset
for help on using the changeset viewer.