// Configure a usb msc device. int usb_msc_setup(struct usbdevice_s *usbdev) { if (!CONFIG_USB_MSC) return -1; // Verify right kind of device struct usb_interface_descriptor *iface = usbdev->iface; if ((iface->bInterfaceSubClass != US_SC_SCSI && iface->bInterfaceSubClass != US_SC_ATAPI_8070 && iface->bInterfaceSubClass != US_SC_ATAPI_8020) || iface->bInterfaceProtocol != US_PR_BULK) { dprintf(1, "Unsupported MSC USB device (subclass=%02x proto=%02x)\n" , iface->bInterfaceSubClass, iface->bInterfaceProtocol); return -1; } // Find bulk in and bulk out endpoints. struct usb_pipe *inpipe = NULL, *outpipe = NULL; struct usb_endpoint_descriptor *indesc = usb_find_desc( usbdev, USB_ENDPOINT_XFER_BULK, USB_DIR_IN); struct usb_endpoint_descriptor *outdesc = usb_find_desc( usbdev, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT); if (!indesc || !outdesc) goto fail; inpipe = usb_alloc_pipe(usbdev, indesc); outpipe = usb_alloc_pipe(usbdev, outdesc); if (!inpipe || !outpipe) goto fail; int maxlun = usb_msc_maxlun(usbdev->defpipe); int lun, pipesused = 0; for (lun = 0; lun < maxlun + 1; lun++) { int ret = usb_msc_lun_setup(inpipe, outpipe, usbdev, lun); if (!ret) pipesused = 1; } if (!pipesused) goto fail; return 0; fail: dprintf(1, "Unable to configure USB MSC device.\n"); usb_free_pipe(usbdev, inpipe); usb_free_pipe(usbdev, outpipe); return -1; }
static int usb_mouse_setup(struct usbdevice_s *usbdev , struct usb_endpoint_descriptor *epdesc) { if (! CONFIG_USB_MOUSE) return -1; if (mouse_pipe) // XXX - this enables the first found mouse (could be random) return -1; if (epdesc->wMaxPacketSize < 3 || epdesc->wMaxPacketSize > 8) return -1; // Enable "boot" protocol. int ret = set_protocol(usbdev->defpipe, 0); if (ret) return -1; mouse_pipe = usb_alloc_pipe(usbdev, epdesc); if (!mouse_pipe) return -1; dprintf(1, "USB mouse initialized\n"); return 0; }
static int usb_kbd_setup(struct usbdevice_s *usbdev , struct usb_endpoint_descriptor *epdesc) { if (! CONFIG_USB_KEYBOARD) return -1; if (keyboard_pipe) // XXX - this enables the first found keyboard (could be random) return -1; if (epdesc->wMaxPacketSize != 8) return -1; // Enable "boot" protocol. int ret = set_protocol(usbdev->defpipe, 0); if (ret) return -1; // Periodically send reports to enable key repeat. ret = set_idle(usbdev->defpipe, KEYREPEATMS); if (ret) return -1; keyboard_pipe = usb_alloc_pipe(usbdev, epdesc); if (!keyboard_pipe) return -1; dprintf(1, "USB keyboard initialized\n"); return 0; }
// Assign an address to a device in the default state on the given // controller. static int usb_set_address(struct usbdevice_s *usbdev) { ASSERT32FLAT(); struct usb_s *cntl = usbdev->hub->cntl; dprintf(3, "set_address %p\n", cntl); if (cntl->maxaddr >= USB_MAXADDR) return -1; msleep(USB_TIME_RSTRCY); // Create a pipe for the default address. struct usb_endpoint_descriptor epdesc = { .wMaxPacketSize = speed_to_ctlsize[usbdev->speed], .bmAttributes = USB_ENDPOINT_XFER_CONTROL, }; usbdev->defpipe = usb_alloc_pipe(usbdev, &epdesc); if (!usbdev->defpipe) return -1; // Send set_address command. struct usb_ctrlrequest req; req.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE; req.bRequest = USB_REQ_SET_ADDRESS; req.wValue = cntl->maxaddr + 1; req.wIndex = 0; req.wLength = 0; int ret = usb_send_default_control(usbdev->defpipe, &req, NULL); if (ret) { usb_free_pipe(usbdev, usbdev->defpipe); return -1; } msleep(USB_TIME_SETADDR_RECOVERY); cntl->maxaddr++; usbdev->devaddr = cntl->maxaddr; usbdev->defpipe = usb_realloc_pipe(usbdev, usbdev->defpipe, &epdesc); if (!usbdev->defpipe) return -1; return 0; }