// Configure a usb hub and then find devices connected to it. int usb_hub_setup(struct usbdevice_s *usbdev) { ASSERT32FLAT(); if (!CONFIG_USB_HUB) return -1; struct usb_hub_descriptor desc; int ret = get_hub_desc(usbdev->defpipe, &desc); if (ret) return ret; struct usbhub_s hub; memset(&hub, 0, sizeof(hub)); hub.usbdev = usbdev; hub.cntl = usbdev->defpipe->cntl; hub.powerwait = desc.bPwrOn2PwrGood * 2; hub.portcount = desc.bNbrPorts; hub.op = &HubOp; usb_enumerate(&hub); dprintf(1, "Initialized USB HUB (%d ports used)\n", hub.devcount); if (hub.devcount) return 0; return -1; }
// Find any devices connected to the root hub. static int check_ehci_ports(struct usb_ehci_s *cntl) { ASSERT32FLAT(); struct usbhub_s hub; memset(&hub, 0, sizeof(hub)); hub.cntl = &cntl->usb; hub.portcount = cntl->checkports; hub.op = &ehci_HubOp; usb_enumerate(&hub); return hub.devcount; }
int usb_rescan(void) { int i; USBStack *usb_stack; log_debug("Looking for added/removed USB devices"); // mark all known USB stacks as potentially removed for (i = 0; i < _usb_stacks.count; ++i) { usb_stack = array_get(&_usb_stacks, i); usb_stack->connected = false; } // enumerate all USB devices, mark all USB stacks that are still connected // and add USB stacks that are newly connected if (usb_enumerate() < 0) { return -1; } // remove all USB stacks that are not marked as connected. iterate backwards // so array_remove can be used without invalidating the current index for (i = _usb_stacks.count - 1; i >= 0; --i) { usb_stack = array_get(&_usb_stacks, i); if (usb_stack->connected) { continue; } log_info("Removing USB device (bus: %u, device: %u) at index %d: %s", usb_stack->bus_number, usb_stack->device_address, i, usb_stack->base.name); stack_announce_disconnect(&usb_stack->base); array_remove(&_usb_stacks, i, (ItemDestroyFunction)usb_stack_destroy); } return 0; }