/* Need to check this again */ void udc_disable(void) { usbdbg("disable UDC"); udc_clear_mask_UDCCR(UDCCR_UDE); /* Disable clock for USB device */ writel(readl(CKEN) & ~CKEN11_USB, CKEN); /* Free ep0 URB */ if (ep0_urb) { usbd_dealloc_urb(ep0_urb); ep0_urb = NULL; } /* Reset device pointer */ udc_device = NULL; }
/* udc_disable * * disable the currently hooked device */ void udc_disable (void) { int i = 0; if (udc_state == STATE_ERROR) { DBG ("Won't disable UDC. udc_state==STATE_ERROR !\n"); return; } udc_device = 0; for (; i < MAX_ENDPOINTS; i++) { if (ep_ref[i].urb) { usbd_dealloc_urb (ep_ref[i].urb); ep_ref[i].urb = 0; } } usbp->usbmr = 0x00; usbp->usmod = ~USMOD_EN; udc_state = STATE_NOT_READY; }
/* bi_config - commission bus interface driver */ static int bi_config (struct usb_device_instance *device) { int i; struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint_descriptor; int found_tx = 0; int found_rx = 0; dbg_init (1, "checking config: config: %d interface: %d alternate: %d", device->configuration, device->interface, device->alternate); bi_disable_endpoints (device); // audit configuration for compatibility if (!(interface = usbd_device_interface_descriptor (device, 0, device->configuration, device->interface, device->alternate))) { dbg_init (0, "cannot fetch interface descriptor c:%d i:%d a:%d", device->configuration, device->interface, device->alternate); return -EINVAL; } dbg_init (2, "---> endpoints: %d", interface->bNumEndpoints); // iterate across all endpoints for this configuration and verify they are valid for (i = 0; i < interface->bNumEndpoints; i++) { int transfersize; int physical_endpoint; int logical_endpoint; //dbg_init(0, "fetching endpoint %d", i); if (!(endpoint_descriptor = usbd_device_endpoint_descriptor_index (device, 0, device-> configuration, device-> interface, device-> alternate, i))) { dbg_init (0, "cannot fetch endpoint descriptor: %d", i); continue; } // XXX check this transfersize = usbd_device_endpoint_transfersize (device, 0, device->configuration, device->interface, device->alternate, i); logical_endpoint = endpoint_descriptor->bEndpointAddress; if (! (physical_endpoint = udc_check_ep (logical_endpoint, le16_to_cpu(endpoint_descriptor->wMaxPacketSize)))) { dbg_init (2, "endpoint[%d]: l: %02x p: %02x transferSize: %d packetSize: %02x INVALID", i, logical_endpoint, physical_endpoint, transfersize, le16_to_cpu(endpoint_descriptor->wMaxPacketSize)); dbg_init (0, "invalid endpoint: %d %d", logical_endpoint, physical_endpoint); return -EINVAL; } else { struct usb_endpoint_instance *endpoint = device->bus->endpoint_array + physical_endpoint; dbg_init (2, "endpoint[%d]: l: %02x p: %02x transferSize: %d packetSize: %02x FOUND", i, logical_endpoint, physical_endpoint, transfersize, le16_to_cpu(endpoint_descriptor->wMaxPacketSize)); dbg_init (2, "epd->bEndpointAddress=%02x", endpoint_descriptor->bEndpointAddress); endpoint->endpoint_address = endpoint_descriptor->bEndpointAddress; if (le16_to_cpu(endpoint_descriptor->wMaxPacketSize) > 64) { dbg_init (0, "incompatible with endpoint size: %x", le16_to_cpu(endpoint_descriptor->wMaxPacketSize)); return -EINVAL; } if (endpoint_descriptor->bEndpointAddress & IN) { found_tx++; endpoint->tx_attributes = endpoint_descriptor->bmAttributes; endpoint->tx_transferSize = transfersize & 0xfff; endpoint->tx_packetSize = le16_to_cpu(endpoint_descriptor->wMaxPacketSize); endpoint->last = 0; if (endpoint->tx_urb) { dbg_init (1, "CLEARING tx_urb: %p", endpoint->tx_urb); usbd_dealloc_urb (endpoint->tx_urb); endpoint->tx_urb = NULL; } } else { found_rx++; endpoint->rcv_attributes = endpoint_descriptor->bmAttributes; endpoint->rcv_transferSize = transfersize & 0xfff; endpoint->rcv_packetSize = le16_to_cpu(endpoint_descriptor->wMaxPacketSize); if (endpoint->rcv_urb) { dbg_init (1, "CLEARING rcv_urb: %p", endpoint->tx_urb); usbd_dealloc_urb (endpoint->rcv_urb); endpoint->rcv_urb = NULL; } } } } // iterate across all endpoints and enable them dbg_init(1, "---> device->status: %d", device->status); if (device->status == USBD_OK) { dbg_init (1, "enabling endpoints"); for (i = 1; i < device->bus->driver->max_endpoints; i++) { struct usb_endpoint_instance *endpoint = device->bus->endpoint_array + i; dbg_init (1, "endpoint[%d]: %p addr: %02x transferSize: %d:%d packetSize: %d:%d SETUP", i, endpoint, endpoint->endpoint_address, endpoint->rcv_transferSize, endpoint->tx_transferSize, endpoint->rcv_packetSize, endpoint->tx_packetSize); //udc_setup_ep(device, i, endpoint->endpoint_address? endpoint : NULL); udc_setup_ep (device, i, endpoint); } } return 0; }