static void control_request_handler_drivers(struct usb_ctrlrequest* req) { int i, interface = req->wIndex & 0xff; bool handled = false; for(i = 0; i < USB_NUM_DRIVERS; i++) { if(drivers[i].enabled && drivers[i].control_request && drivers[i].first_interface <= interface && drivers[i].last_interface > interface) { handled = drivers[i].control_request(req, response_data); if(handled) break; } } if(!handled) { /* nope. flag error */ logf("bad req:desc %d:%d", req->bRequest, req->wValue >> 8); usb_drv_stall(EP_CONTROL, true, true); }
static void handle_std_dev_desc(struct usb_ctrlrequest *req) { int size; const void* ptr = NULL; unsigned index = req->wValue & 0xff; switch(req->wValue >> 8) { case USB_DT_DEVICE: ptr = &device_descriptor; size = sizeof(struct usb_device_descriptor); break; case USB_DT_OTHER_SPEED_CONFIG: case USB_DT_CONFIG: { int max_packet_size; /* config desc */ if((req->wValue >> 8) ==USB_DT_CONFIG) { max_packet_size = (usb_drv_port_speed() ? 512 : 64); config_descriptor.bDescriptorType = USB_DT_CONFIG; } else { max_packet_size=(usb_drv_port_speed() ? 64 : 512); config_descriptor.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG; } size = sizeof(struct usb_config_descriptor); /* interface */ memcpy(usb_buffer + size, (void *)&interface_descriptor, sizeof(interface_descriptor)); size += sizeof(interface_descriptor); /* endpoint 1: bulk out */ endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_OUT; endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK; endpoint_descriptor.wMaxPacketSize = 512; memcpy(usb_buffer + size, (void *)&endpoint_descriptor, sizeof(endpoint_descriptor)); size += sizeof(endpoint_descriptor); /* endpoint 2: bulk in */ endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_IN; endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK; endpoint_descriptor.wMaxPacketSize = 512; memcpy(usb_buffer + size, (void *)&endpoint_descriptor, sizeof(endpoint_descriptor)); size += sizeof(endpoint_descriptor); /* endpoint 3: int in */ endpoint_descriptor.bEndpointAddress = EP_INT | USB_DIR_IN; endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_INT; endpoint_descriptor.wMaxPacketSize = 1024; memcpy(usb_buffer + size, (void *)&endpoint_descriptor, sizeof(endpoint_descriptor)); size += sizeof(endpoint_descriptor); /* fix config descriptor */ config_descriptor.bNumInterfaces = 1; config_descriptor.wTotalLength = size; memcpy(usb_buffer, (void *)&config_descriptor, sizeof(config_descriptor)); ptr = usb_buffer; break; } case USB_DT_STRING: if(index < USB_NUM_STRINGS) { size = usb_strings[index]->bLength; ptr = usb_strings[index]; } else usb_drv_stall(EP_CONTROL, true, true); break; default: break; }
static void handle_std_dev_desc(struct usb_ctrlrequest *req) { int size; void* ptr = NULL; unsigned index = req->wValue & 0xff; switch(req->wValue >> 8) { case USB_DT_DEVICE: ptr = &device_descriptor; size = sizeof(struct usb_device_descriptor); break; case USB_DT_OTHER_SPEED_CONFIG: case USB_DT_CONFIG: { int max_packet_size; /* config desc */ if((req->wValue >> 8) ==USB_DT_CONFIG) { max_packet_size = (usb_drv_port_speed() ? 512 : 64); config_descriptor.bDescriptorType = USB_DT_CONFIG; } else { max_packet_size=(usb_drv_port_speed() ? 64 : 512); config_descriptor.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG; } size = sizeof(struct usb_config_descriptor); /* hwstub version */ memcpy(usb_buffer + size, (void *)&version_descriptor, sizeof(version_descriptor)); size += sizeof(version_descriptor); /* hwstub layout */ fill_layout_info(); memcpy(usb_buffer + size, (void *)&layout_descriptor, sizeof(layout_descriptor)); size += sizeof(layout_descriptor); /* hwstub target */ fill_layout_info(); memcpy(usb_buffer + size, (void *)&target_descriptor, sizeof(target_descriptor)); size += sizeof(target_descriptor); /* target specific descriptors */ target_get_config_desc(usb_buffer + size, &size); /* fix config descriptor */ config_descriptor.bNumInterfaces = 1; config_descriptor.wTotalLength = size; memcpy(usb_buffer, (void *)&config_descriptor, sizeof(config_descriptor)); ptr = usb_buffer; break; } case USB_DT_STRING: if(index < USB_NUM_STRINGS) { size = usb_strings[index]->bLength; ptr = (void *)usb_strings[index]; } else usb_drv_stall(EP_CONTROL, true, true); break; case HWSTUB_DT_VERSION: ptr = &version_descriptor; size = sizeof(version_descriptor); break; case HWSTUB_DT_LAYOUT: ptr = &layout_descriptor; size = sizeof(layout_descriptor); break; case HWSTUB_DT_TARGET: ptr = &target_descriptor; size = sizeof(target_descriptor); break; default: target_get_desc(req->wValue >> 8, &ptr); if(ptr != 0) size = ((struct usb_descriptor_header *)ptr)->bLength; break; }