Changes in uspace/lib/usbhost/src/ddf_helpers.c [cccd60c3:0f6b50f] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/ddf_helpers.c
rcccd60c3 r0f6b50f 35 35 36 36 #include <usb/classes/classes.h> 37 #include <usb/host/bus.h> 37 38 #include <usb/debug.h> 38 39 #include <usb/descriptor.h> … … 49 50 #include <fibril_synch.h> 50 51 #include <macros.h> 51 #include <stdio.h>52 52 #include <stdlib.h> 53 53 #include <str_error.h> … … 56 56 #include "ddf_helpers.h" 57 57 58 #define CTRL_PIPE_MIN_PACKET_SIZE 859 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 71 58 typedef struct hc_dev { 72 59 ddf_fun_t *ctl_fun; 73 60 hcd_t hcd; 74 usb_dev_t *root_hub;75 61 } hc_dev_t; 76 62 … … 91 77 92 78 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);79 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, device_t *hub_dev, unsigned port); 80 static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub, unsigned port); 95 81 96 82 … … 99 85 /** Register endpoint interface function. 100 86 * @param fun DDF function. 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. 87 * @param endpoint_desc Endpoint description. 107 88 * @return Error code. 108 89 */ 109 90 static int register_endpoint( 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) 91 ddf_fun_t *fun, usb_endpoint_desc_t *endpoint_desc) 113 92 { 114 93 assert(fun); 115 94 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 116 usb_dev_t *dev = ddf_fun_data_get(fun);95 device_t *dev = ddf_fun_data_get(fun); 117 96 assert(hcd); 97 assert(hcd->bus); 118 98 assert(dev); 119 const size_t size = max_packet_size; 120 const usb_target_t target = 121 {{.address = dev->address, .endpoint = endpoint}}; 99 100 const size_t size = endpoint_desc->max_packet_size; 122 101 123 102 usb_log_debug("Register endpoint %d:%d %s-%s %zuB %ums.\n", 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 */ 103 dev->address, endpoint_desc->endpoint_no, 104 usb_str_transfer_type(endpoint_desc->transfer_type), 105 usb_str_direction(endpoint_desc->direction), 106 endpoint_desc->max_packet_size, endpoint_desc->usb2.polling_interval); 107 108 return bus_add_ep(hcd->bus, dev, endpoint_desc->endpoint_no, 109 endpoint_desc->direction, endpoint_desc->transfer_type, 110 endpoint_desc->max_packet_size, endpoint_desc->packets, 111 size); 112 } 113 114 /** Unregister endpoint interface function. 115 * @param fun DDF function. 116 * @param endpoint_desc Endpoint description. 117 * @return Error code. 118 */ 138 119 static int unregister_endpoint( 139 ddf_fun_t *fun, usb_endpoint_t endpoint, usb_direction_t direction)120 ddf_fun_t *fun, usb_endpoint_desc_t *endpoint_desc) 140 121 { 141 122 assert(fun); 142 123 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 143 usb_dev_t *dev = ddf_fun_data_get(fun);124 device_t *dev = ddf_fun_data_get(fun); 144 125 assert(hcd); 126 assert(hcd->bus); 145 127 assert(dev); 146 const usb_target_t target = 147 {{.address = dev->address, .endpoint = endpoint}}; 128 129 const usb_target_t target = {{ 130 .address = dev->address, 131 .endpoint = endpoint_desc->endpoint_no 132 }}; 133 148 134 usb_log_debug("Unregister endpoint %d:%d %s.\n", 149 dev->address, endpoint, usb_str_direction(direction)); 150 return hcd_remove_ep(hcd, target, direction); 135 dev->address, endpoint_desc->endpoint_no, 136 usb_str_direction(endpoint_desc->direction)); 137 return bus_remove_ep(hcd->bus, target, endpoint_desc->direction); 151 138 } 152 139 … … 155 142 assert(fun); 156 143 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 157 usb_dev_t *dev = ddf_fun_data_get(fun);144 device_t *dev = ddf_fun_data_get(fun); 158 145 assert(hcd); 146 assert(hcd->bus); 159 147 assert(dev); 160 148 161 149 usb_log_debug("Device %d requested default address at %s speed\n", 162 150 dev->address, usb_str_speed(speed)); 163 return hcd_reserve_default_address(hcd, speed);151 return bus_reserve_default_address(hcd->bus, speed); 164 152 } 165 153 … … 168 156 assert(fun); 169 157 hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun)); 170 usb_dev_t *dev = ddf_fun_data_get(fun);158 device_t *dev = ddf_fun_data_get(fun); 171 159 assert(hcd); 160 assert(hcd->bus); 172 161 assert(dev); 173 162 174 163 usb_log_debug("Device %d released default address\n", dev->address); 175 return hcd_release_default_address(hcd);164 return bus_release_default_address(hcd->bus); 176 165 } 177 166 178 167 static int device_enumerate(ddf_fun_t *fun, unsigned port) 168 { 169 assert(fun); 170 ddf_dev_t *hc = ddf_fun_get_dev(fun); 171 assert(hc); 172 hcd_t *hcd = dev_to_hcd(hc); 173 assert(hcd); 174 device_t *hub = ddf_fun_data_get(fun); 175 assert(hub); 176 177 usb_log_debug("Hub %d reported a new USB device on port: %u\n", 178 hub->address, port); 179 return hcd_ddf_new_device(hcd, hc, hub, port); 180 } 181 182 static int device_remove(ddf_fun_t *fun, unsigned port) 179 183 { 180 184 assert(fun); 181 185 ddf_dev_t *ddf_dev = ddf_fun_get_dev(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); 186 device_t *dev = ddf_fun_data_get(fun); 195 187 assert(ddf_dev); 196 188 assert(dev); … … 229 221 { 230 222 assert(fun); 231 usb_dev_t *usb_dev = ddf_fun_data_get(fun);232 assert( usb_dev);223 device_t *dev = ddf_fun_data_get(fun); 224 assert(dev); 233 225 const usb_target_t target = {{ 234 .address = usb_dev->address,226 .address = dev->address, 235 227 .endpoint = endpoint, 236 228 }}; … … 255 247 { 256 248 assert(fun); 257 usb_dev_t *usb_dev = ddf_fun_data_get(fun);258 assert( usb_dev);249 device_t *dev = ddf_fun_data_get(fun); 250 assert(dev); 259 251 const usb_target_t target = {{ 260 .address = usb_dev->address,252 .address = dev->address, 261 253 .endpoint = endpoint, 262 254 }}; … … 290 282 291 283 /* 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 }370 284 371 285 #define ADD_MATCHID_OR_RETURN(list, sc, str, ...) \ … … 394 308 assert(l); 395 309 assert(d); 396 310 397 311 if (d->vendor_id != 0) { 398 312 /* First, with release number. */ … … 401 315 d->vendor_id, d->product_id, (d->device_version >> 8), 402 316 (d->device_version & 0xff)); 403 317 404 318 /* Next, without release number. */ 405 319 ADD_MATCHID_OR_RETURN(l, 90, "usb&vendor=%#04x&product=%#04x", … … 415 329 416 330 return EOK; 417 418 } 419 420 static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub, 331 } 332 333 static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub, 421 334 unsigned port) 422 335 { … … 425 338 hcd_t *hcd = dev_to_hcd(device); 426 339 assert(hcd); 340 assert(hcd->bus); 427 341 428 342 hc_dev_t *hc_dev = dev_to_hc_dev(device); … … 431 345 fibril_mutex_lock(&hub->guard); 432 346 433 usb_dev_t *victim = NULL;434 435 list_foreach(hub->devices, link, usb_dev_t, it) {347 device_t *victim = NULL; 348 349 list_foreach(hub->devices, link, device_t, it) { 436 350 if (it->port == port) { 437 351 victim = it; … … 440 354 } 441 355 if (victim) { 356 assert(victim->fun); 442 357 assert(victim->port == port); 358 assert(victim->hub == hub); 443 359 list_remove(&victim->link); 444 360 fibril_mutex_unlock(&hub->guard); … … 446 362 if (ret == EOK) { 447 363 usb_address_t address = victim->address; 364 bus_remove_device(hcd->bus, hcd, victim); 448 365 ddf_fun_destroy(victim->fun); 449 hcd_release_address(hcd, address);366 bus_release_address(hcd->bus, address); 450 367 } else { 451 368 usb_log_warning("Failed to unbind device `%s': %s\n", … … 458 375 } 459 376 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, 377 device_t *hcd_ddf_device_create(ddf_dev_t *hc, size_t device_size) 378 { 379 /* Create DDF function for the new device */ 380 ddf_fun_t *fun = ddf_fun_create(hc, fun_inner, NULL); 381 if (!fun) 382 return NULL; 383 384 ddf_fun_set_ops(fun, &usb_ops); 385 386 /* Create USB device node for the new device */ 387 device_t *dev = ddf_fun_data_alloc(fun, device_size); 388 if (!dev) { 389 ddf_fun_destroy(fun); 390 return NULL; 391 } 392 393 device_init(dev); 394 dev->fun = fun; 395 return dev; 396 } 397 398 void hcd_ddf_device_destroy(device_t *dev) 399 { 400 assert(dev); 401 assert(dev->fun); 402 ddf_fun_destroy(dev->fun); 403 } 404 405 int hcd_ddf_device_explore(hcd_t *hcd, device_t *device) 406 { 407 int err; 408 match_id_list_t mids; 409 usb_standard_device_descriptor_t desc = { 0 }; 410 411 init_match_ids(&mids); 412 413 usb_target_t control_ep = {{ 414 .address = device->address, 415 .endpoint = 0 481 416 }}; 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 */513 usb_standard_device_descriptor_t desc = { 0 };514 const usb_device_request_setup_packet_t get_device_desc_8 =515 GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE);516 517 // TODO CALLBACKS518 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 }567 417 568 418 /* Get std device descriptor */ … … 571 421 572 422 usb_log_debug("Device(%d): Requesting full device descriptor.", 573 address);574 got = hcd_send_batch_sync(hcd, target, USB_DIRECTION_IN,423 device->address); 424 ssize_t got = hcd_send_batch_sync(hcd, control_ep, USB_DIRECTION_IN, 575 425 &desc, sizeof(desc), *(uint64_t *)&get_device_desc, 576 426 "read device descriptor"); 577 if (ret != EOK) { 427 if (got < 0) { 428 err = got < 0 ? got : EOVERFLOW; 578 429 usb_log_error("Device(%d): Failed to set get dev descriptor: %s", 579 address, str_error(ret)); 580 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH); 581 hcd_release_address(hcd, target.address); 582 return ret; 430 device->address, str_error(err)); 431 goto out; 583 432 } 584 433 585 434 /* Create match ids from the device descriptor */ 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); 435 usb_log_debug("Device(%d): Creating match IDs.", device->address); 436 if ((err = create_match_ids(&mids, &desc))) { 437 usb_log_error("Device(%d): Failed to create match ids: %s", device->address, str_error(err)); 438 goto out; 439 } 440 441 list_foreach(mids.ids, link, const match_id_t, mid) { 442 ddf_fun_add_match_id(device->fun, mid->id, mid->score); 443 } 444 445 out: 602 446 clean_match_ids(&mids); 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; 447 return err; 448 } 449 450 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, device_t *hub, unsigned port) 451 { 452 int err; 453 assert(hcd); 454 assert(hcd->bus); 455 assert(hub); 456 assert(hc); 457 458 device_t *dev = hcd_ddf_device_create(hc, hcd->bus->device_size); 459 if (!dev) { 460 usb_log_error("Failed to create USB device function."); 461 return ENOMEM; 462 } 463 464 dev->hub = hub; 465 dev->port = port; 466 467 if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) { 468 usb_log_error("Failed to initialize USB dev memory structures."); 469 return err; 470 } 471 472 /* If the driver didn't name the dev when enumerating, 473 * do it in some generic way. 474 */ 475 if (!ddf_fun_get_name(dev->fun)) { 476 device_set_default_name(dev); 477 } 478 479 if ((err = ddf_fun_bind(dev->fun))) { 480 usb_log_error("Device(%d): Failed to register: %s.", dev->address, str_error(err)); 481 goto err_usb_dev; 482 } 483 484 fibril_mutex_lock(&hub->guard); 485 list_append(&dev->link, &hub->devices); 486 fibril_mutex_unlock(&hub->guard); 487 488 return EOK; 489 490 err_usb_dev: 491 hcd_ddf_device_destroy(dev); 492 return err; 611 493 } 612 494 … … 616 498 * @return Error code 617 499 */ 618 int hcd_ddf_setup_root_hub(ddf_dev_t *device) 619 { 620 assert(device); 621 hcd_t *hcd = dev_to_hcd(device); 500 int hcd_setup_virtual_root_hub(hcd_t *hcd, ddf_dev_t *hc) 501 { 502 int err; 503 504 assert(hc); 622 505 assert(hcd); 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; 506 assert(hcd->bus); 507 508 if ((err = bus_reserve_default_address(hcd->bus, USB_SPEED_MAX))) { 509 usb_log_error("Failed to reserve default address for roothub setup: %s", str_error(err)); 510 return err; 511 } 512 513 device_t *dev = hcd_ddf_device_create(hc, USB_SPEED_MAX); 514 if (!dev) { 515 usb_log_error("Failed to create function for the root hub."); 516 goto err_default_address; 517 } 518 519 ddf_fun_set_name(dev->fun, "roothub"); 520 521 dev->tt = (usb_tt_address_t) { 522 .address = -1, 523 .port = 0, 524 }; 525 526 /* Assign an address to the device */ 527 if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) { 528 usb_log_error("Failed to enumerate roothub device: %s", str_error(err)); 529 goto err_usb_dev; 530 } 531 532 if ((err = ddf_fun_bind(dev->fun))) { 533 usb_log_error("Failed to register roothub: %s.", str_error(err)); 534 goto err_usb_dev; 535 } 536 537 bus_release_default_address(hcd->bus); 538 return EOK; 539 540 err_usb_dev: 541 hcd_ddf_device_destroy(dev); 542 err_default_address: 543 bus_release_default_address(hcd->bus); 544 return err; 628 545 } 629 546 … … 638 555 * This function does all the ddf work for hc driver. 639 556 */ 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) 557 int hcd_ddf_setup_hc(ddf_dev_t *device) 642 558 { 643 559 assert(device); … … 648 564 return ENOMEM; 649 565 } 650 instance->root_hub = NULL; 651 hcd_init(&instance->hcd, max_speed, bw, bw_count); 566 hcd_init(&instance->hcd); 652 567 653 568 int ret = ENOMEM; … … 748 663 const hw_res_list_parsed_t *hw_res, 749 664 interrupt_handler_t handler, 750 int (*gen_irq_code)(irq_code_t *, const hw_res_list_parsed_t *hw_res)) 751 { 752 665 irq_code_gen_t gen_irq_code) 666 { 753 667 assert(device); 668 669 hcd_t *hcd = dev_to_hcd(device); 670 754 671 if (!handler || !gen_irq_code) 755 672 return ENOTSUP; … … 757 674 irq_code_t irq_code = {0}; 758 675 759 const int irq = gen_irq_code(&irq_code, h w_res);676 const int irq = gen_irq_code(&irq_code, hcd, hw_res); 760 677 if (irq < 0) { 761 678 usb_log_error("Failed to generate IRQ code: %s.\n", … … 777 694 int ret = hcd_ddf_enable_interrupt(device, irq); 778 695 if (ret != EOK) { 779 usb_log_error("Failed to register interrupt handler: %s.\n",696 usb_log_error("Failed to enable interrupts: %s.\n", 780 697 str_error(ret)); 781 698 unregister_interrupt_handler(device, irq_cap); … … 844 761 { 845 762 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 };852 763 853 764 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 }860 765 861 766 hw_res_list_parsed_t hw_res; … … 868 773 } 869 774 870 ret = hcd_ddf_setup_hc(device , speed, bw[speed].bw, bw[speed].bw_count);775 ret = hcd_ddf_setup_hc(device); 871 776 if (ret != EOK) { 872 777 usb_log_error("Failed to setup generic HCD.\n"); 873 hw_res_list_parsed_clean(&hw_res); 874 return ret; 875 } 876 778 goto err_hw_res; 779 } 780 781 hcd_t *hcd = dev_to_hcd(device); 782 783 if (driver->init) 784 ret = driver->init(hcd, &hw_res, device); 785 if (ret != EOK) { 786 usb_log_error("Failed to init HCD.\n"); 787 goto err_hcd; 788 } 789 790 /* Setup interrupts */ 877 791 interrupt_handler_t *irq_handler = 878 792 driver->irq_handler ? driver->irq_handler : ddf_hcd_gen_irq_handler; … … 884 798 } 885 799 800 /* Claim the device from BIOS */ 886 801 if (driver->claim) 887 ret = driver->claim( device);802 ret = driver->claim(hcd, device); 888 803 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); 804 usb_log_error("Failed to claim `%s' for driver `%s': %s", 805 ddf_dev_get_name(device), driver->name, str_error(ret)); 806 goto err_irq; 807 } 808 809 /* Start hw driver */ 810 if (driver->start) 811 ret = driver->start(hcd, irqs_enabled); 899 812 if (ret != EOK) { 900 usb_log_error("Failed to init HCD: %s.\n", str_error(ret));901 goto irq_unregister;813 usb_log_error("Failed to start HCD: %s.\n", str_error(ret)); 814 goto err_irq; 902 815 } 903 816 … … 908 821 usb_log_error("Failed to create polling fibril\n"); 909 822 ret = ENOMEM; 910 goto irq_unregister;823 goto err_started; 911 824 } 912 825 fibril_add_ready(hcd->polling_fibril); … … 919 832 * needs to be ready at this time. 920 833 */ 921 ret = hcd_ddf_setup_root_hub(device); 834 if (driver->setup_root_hub) 835 ret = driver->setup_root_hub(hcd, device); 922 836 if (ret != EOK) { 923 837 usb_log_error("Failed to setup HC root hub: %s.\n", 924 838 str_error(ret)); 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; 839 goto err_polling; 931 840 } 932 841 … … 934 843 driver->name, ddf_dev_get_name(device)); 935 844 return EOK; 936 } 845 846 err_polling: 847 // TODO: Stop the polling fibril (refactor the interrupt_polling func) 848 // 849 err_started: 850 if (driver->stop) 851 driver->stop(hcd); 852 err_irq: 853 unregister_interrupt_handler(device, irq_cap); 854 if (driver->fini) 855 driver->fini(hcd); 856 err_hcd: 857 hcd_ddf_clean_hc(device); 858 err_hw_res: 859 hw_res_list_parsed_clean(&hw_res); 860 return ret; 861 } 862 937 863 /** 938 864 * @}
Note:
See TracChangeset
for help on using the changeset viewer.