ssize_t usbControlTransfer ( UsbDevice *device, uint8_t direction, uint8_t recipient, uint8_t type, uint8_t request, uint16_t value, uint16_t index, void *buffer, uint16_t length, int timeout ) { UsbDeviceExtension *devx = device->extension; if (usbOpenUsbfsFile(devx)) { union { struct usbdevfs_ctrltransfer transfer; UsbSetupPacket setup; } arg; memset(&arg, 0, sizeof(arg)); arg.setup.bRequestType = direction | recipient | type; arg.setup.bRequest = request; putLittleEndian16(&arg.setup.wValue, value); putLittleEndian16(&arg.setup.wIndex, index); putLittleEndian16(&arg.setup.wLength, length); arg.transfer.data = buffer; arg.transfer.timeout = timeout; usbLogSetupPacket(&arg.setup); if (direction == UsbControlDirection_Output) { if (length) logBytes(LOG_CATEGORY(USB_IO), "control output", buffer, length); } { int count = ioctl(devx->usbfsFile, USBDEVFS_CONTROL, &arg); if (count != -1) { if (direction == UsbControlDirection_Input) { logBytes(LOG_CATEGORY(USB_IO), "control input", buffer, length); } return count; } logSystemError("USB control transfer"); } } return -1; }
void usbMakeSetupPacket ( UsbSetupPacket *setup, uint8_t direction, uint8_t recipient, uint8_t type, uint8_t request, uint16_t value, uint16_t index, uint16_t length ) { setup->bRequestType = direction | recipient | type; setup->bRequest = request; putLittleEndian16(&setup->wValue, value); putLittleEndian16(&setup->wIndex, index); putLittleEndian16(&setup->wLength, length); usbLogSetupPacket(setup); }