Ejemplo n.º 1
0
static void
usb_hub_port_setup(void *data)
{
    struct usbdevice_s *usbdev = data;
    struct usbhub_s *hub = usbdev->hub;
    u32 port = usbdev->port;

    for (;;) {
        // Detect if device present (and possibly start reset)
        int ret = hub->op->detect(hub, port);
        if (ret > 0)
            // Device connected.
            break;
        if (ret < 0 || timer_check(hub->detectend))
            // No device found.
            goto done;
        msleep(5);
    }

    // XXX - wait USB_TIME_ATTDB time?

    // Reset port and determine device speed
    mutex_lock(&hub->cntl->resetlock);
    int ret = hub->op->reset(hub, port);
    if (ret < 0)
        // Reset failed
        goto resetfail;
    usbdev->speed = ret;

    // Set address of port
    ret = usb_set_address(usbdev);
    if (ret) {
        hub->op->disconnect(hub, port);
        goto resetfail;
    }
    mutex_unlock(&hub->cntl->resetlock);

    // Configure the device
    int count = configure_usb_device(usbdev);
    usb_free_pipe(usbdev, usbdev->defpipe);
    if (!count)
        hub->op->disconnect(hub, port);
    hub->devcount += count;
done:
    hub->threads--;
    free(usbdev);
    return;

resetfail:
    mutex_unlock(&hub->cntl->resetlock);
    goto done;
}
Ejemplo n.º 2
0
// Find any devices connected to the root hub.
static int
check_ohci_ports(struct usb_s *cntl)
{
    // Turn on power for all devices on roothub.
    u32 rha = readl(&cntl->ohci.regs->roothub_a);
    rha &= ~(RH_A_PSM | RH_A_OCPM);
    writel(&cntl->ohci.regs->roothub_status, RH_HS_LPSC);
    writel(&cntl->ohci.regs->roothub_b, RH_B_PPCM);
    msleep((rha >> 24) * 2);

    // Count and reset connected devices
    int ports = rha & RH_A_NDP;
    int totalcount = 0;
    int i;
    for (i=0; i<ports; i++)
        if (readl(&cntl->ohci.regs->roothub_portstatus[i]) & RH_PS_CCS) {
            writel(&cntl->ohci.regs->roothub_portstatus[i], RH_PS_PRS);
            totalcount++;
        }
    if (!totalcount)
        // No devices connected
        goto shutdown;

    msleep(60);    // XXX - should poll instead of using timer.

    totalcount = 0;
    for (i=0; i<ports; i++) {
        u32 sts = readl(&cntl->ohci.regs->roothub_portstatus[i]);
        if ((sts & (RH_PS_CCS|RH_PS_PES)) == (RH_PS_CCS|RH_PS_PES)) {
            int count = configure_usb_device(cntl, !!(sts & RH_PS_LSDA));
            if (! count)
                // Shutdown port
                writel(&cntl->ohci.regs->roothub_portstatus[i]
                       , RH_PS_CCS|RH_PS_LSDA);
            totalcount += count;
        }
    }
    if (!totalcount)
        goto shutdown;

    return totalcount;

shutdown:
    // Turn off power to all ports
    writel(&cntl->ohci.regs->roothub_status, RH_HS_LPS);
    return 0;
}