/** * usbd_device_endpoint_descriptor * @device: which device * @port: which port * @configuration: index to configuration, 0 - N-1 * @interface: index to interface * @alternate: alternate setting * @endpoint: which endpoint * * Return the specified endpoint descriptor for the specified device. */ struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int endpoint) { struct usb_endpoint_descriptor *endpoint_descriptor; int i; for (i = 0; !(endpoint_descriptor = usbd_device_endpoint_descriptor_index (device, port, configuration, interface, alternate, i)); i++) { if (endpoint_descriptor->bEndpointAddress == endpoint) { return endpoint_descriptor; } } return NULL; }
/* 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, endpoint_descriptor->wMaxPacketSize, device))) { dbg_init(2, "endpoint[%d]: l: %02x p: %02x transferSize: %d packetSize: %02x INVALID", i, logical_endpoint, physical_endpoint, transfersize, endpoint_descriptor->wMaxPacketSize); dbg_init(2, "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, endpoint_descriptor->wMaxPacketSize); dbg_init(2,"epd->bEndpointAddress=%d", endpoint_descriptor->bEndpointAddress); endpoint->endpoint_address = endpoint_descriptor->bEndpointAddress; if (endpoint_descriptor->wMaxPacketSize > 64) { dbg_init(0,"incompatible with endpoint size: %x", 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 = endpoint_descriptor->wMaxPacketSize; endpoint->last = 0; endpoint->tx_urb = NULL; } else { found_rx++; endpoint->rcv_attributes = endpoint_descriptor->bmAttributes; endpoint->rcv_transferSize = transfersize&0xfff; endpoint->rcv_packetSize = endpoint_descriptor->wMaxPacketSize; endpoint->rcv_urb = NULL; } } } if (device->status == USBD_OK) { for (i = 1; i < device->bus->driver->max_endpoints; i++) { struct usb_endpoint_instance *endpoint = device->bus->endpoint_array + i; // udc_setup_ep(device, i, endpoint->endpoint_address? endpoint : NULL); udc_setup_ep(device, i, endpoint); } } return 0; }