diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index efc3f14..49edfd6 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -83,6 +83,7 @@ UsbHostControllerInterface *interface; uint32_t portIndex; uint32_t id, interval; + UsbConfigurationDescriptor *descriptor; } UsbSlot; extern uint32_t serviceId; diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index efc3f14..49edfd6 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -83,6 +83,7 @@ UsbHostControllerInterface *interface; uint32_t portIndex; uint32_t id, interval; + UsbConfigurationDescriptor *descriptor; } UsbSlot; extern uint32_t serviceId; diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index 979d502..0472251 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -51,7 +51,7 @@ uint8_t getEndpointIndex(UsbEndpointDescriptor *endpoint) { uint8_t endpointNumber = endpoint->address & 0xF; // never 0 uint8_t direction = endpoint->address >> 7; - return (endpointNumber)*2 - 1 + direction; + return (endpointNumber << 1) - 1 + direction; } void setupMassStorage(UsbSlot *slot, UsbInterfaceDescriptor *interface) { @@ -65,12 +65,12 @@ registerMassStorage(slot->id | (uint32_t) inEndpoint << 16, slot->id | (uint32_t) outEndpoint << 16); } -void setupInterfaces(UsbSlot *slot, void *start, uint32_t configurationValue) { +void setupInterfaces(UsbSlot *slot) { // only doing blank interface descriptors for now, there are // also interface assosciations... - UsbInterfaceDescriptor *interface = start; - slot->interface->setupEndpointsStart(slot->data, configurationValue); - while (interface->descriptorType == 4) { + UsbInterfaceDescriptor *interface = (void *)slot->descriptor + slot->descriptor->size; + slot->interface->setupEndpointsStart(slot->data, slot->descriptor->configurationValue); + while (U32(interface) < U32(slot->descriptor) + slot->descriptor->totalLength) { printf("interface %i: %i endpoint(s), class %i, subclass %i\n", interface->interfaceNumber, interface->endpointCount, interface->interfaceClass, interface->subClass); @@ -90,7 +90,7 @@ } interface = nextInterface; } - slot->interface->setupEndpointsEnd(slot->data, configurationValue); + slot->interface->setupEndpointsEnd(slot->data, slot->descriptor->configurationValue); } ListElement *usbSlots = NULL; @@ -116,8 +116,9 @@ manufacturer, device, serial); slot->interface->getDescriptor(slot->data, 2 << 8, 0, buffer, 0); - UsbConfigurationDescriptor *configuration = malloc(((uint16_t *)buffer)[1]); - memcpy(buffer, configuration, ((uint16_t *)buffer)[1]); + UsbConfigurationDescriptor *configurationBuffer = buffer; + UsbConfigurationDescriptor *configuration = malloc(configurationBuffer->totalLength); + memcpy(buffer, configuration, configurationBuffer->totalLength); char *configurationString = usbReadString( slot, language, configuration->configurationString, buffer); printf("port %i: %i interfaces, configuration %s, %i bytes\n", @@ -125,8 +126,8 @@ configuration->totalLength); slot->id = listCount(usbSlots); listAdd(&usbSlots, slot); - setupInterfaces(slot, (void *)configuration + configuration->size, - configuration->configurationValue); + slot->descriptor = configuration; + setupInterfaces(slot); } extern UsbHostControllerInterface xhci; @@ -166,6 +167,42 @@ return usbSlot->interval; } +typedef union { + uint32_t value; + struct { + uint8_t class, subClass, protocol; + } __attribute__((packed)) types; +} UsbInterfaceType; + +uint32_t getType(uint32_t slotId) { + UsbSlot *usbSlot = listGet(usbSlots, slotId & 0xFFFF); + uint8_t endpoint = (slotId >> 16) + 1; + uint8_t address = endpoint >> 1 | ((endpoint & 1) << 7); + UsbInterfaceDescriptor *interface = (void *)usbSlot->descriptor + usbSlot->descriptor->size; + while (U32(interface) < U32(usbSlot->descriptor) + usbSlot->descriptor->totalLength) { + void *nextInterface = (void *)interface + interface->size; + for (uint32_t i = 0; i < interface->endpointCount;) { + UsbEndpointDescriptor *endpoint = nextInterface; + if (endpoint->descriptorType == 5) { + if (endpoint->address == address) { + UsbInterfaceType result = { + .types = { + .class = interface->interfaceClass, + .subClass = interface->subClass, + .protocol = interface->protocol, + } + }; + return result.value; + } + i++; + } + nextInterface += endpoint->size; + } + interface = nextInterface; + } + return -1; +} + void initialize() { serviceId = getServiceId(); // xhciEvent will carry data corresponding to the data in the xhci event @@ -175,6 +212,7 @@ loadFromInitrd("usbStorage"); createFunction("hid_normal", (void *)hidNormal); createFunction("hid_interval", (void *)hidInterval); + createFunction("get_type", (void *)getType); for (uint32_t i = 0;; i++) { uint32_t class = getDeviceClass(i, 0); if (!class) { diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index efc3f14..49edfd6 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -83,6 +83,7 @@ UsbHostControllerInterface *interface; uint32_t portIndex; uint32_t id, interval; + UsbConfigurationDescriptor *descriptor; } UsbSlot; extern uint32_t serviceId; diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index 979d502..0472251 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -51,7 +51,7 @@ uint8_t getEndpointIndex(UsbEndpointDescriptor *endpoint) { uint8_t endpointNumber = endpoint->address & 0xF; // never 0 uint8_t direction = endpoint->address >> 7; - return (endpointNumber)*2 - 1 + direction; + return (endpointNumber << 1) - 1 + direction; } void setupMassStorage(UsbSlot *slot, UsbInterfaceDescriptor *interface) { @@ -65,12 +65,12 @@ registerMassStorage(slot->id | (uint32_t) inEndpoint << 16, slot->id | (uint32_t) outEndpoint << 16); } -void setupInterfaces(UsbSlot *slot, void *start, uint32_t configurationValue) { +void setupInterfaces(UsbSlot *slot) { // only doing blank interface descriptors for now, there are // also interface assosciations... - UsbInterfaceDescriptor *interface = start; - slot->interface->setupEndpointsStart(slot->data, configurationValue); - while (interface->descriptorType == 4) { + UsbInterfaceDescriptor *interface = (void *)slot->descriptor + slot->descriptor->size; + slot->interface->setupEndpointsStart(slot->data, slot->descriptor->configurationValue); + while (U32(interface) < U32(slot->descriptor) + slot->descriptor->totalLength) { printf("interface %i: %i endpoint(s), class %i, subclass %i\n", interface->interfaceNumber, interface->endpointCount, interface->interfaceClass, interface->subClass); @@ -90,7 +90,7 @@ } interface = nextInterface; } - slot->interface->setupEndpointsEnd(slot->data, configurationValue); + slot->interface->setupEndpointsEnd(slot->data, slot->descriptor->configurationValue); } ListElement *usbSlots = NULL; @@ -116,8 +116,9 @@ manufacturer, device, serial); slot->interface->getDescriptor(slot->data, 2 << 8, 0, buffer, 0); - UsbConfigurationDescriptor *configuration = malloc(((uint16_t *)buffer)[1]); - memcpy(buffer, configuration, ((uint16_t *)buffer)[1]); + UsbConfigurationDescriptor *configurationBuffer = buffer; + UsbConfigurationDescriptor *configuration = malloc(configurationBuffer->totalLength); + memcpy(buffer, configuration, configurationBuffer->totalLength); char *configurationString = usbReadString( slot, language, configuration->configurationString, buffer); printf("port %i: %i interfaces, configuration %s, %i bytes\n", @@ -125,8 +126,8 @@ configuration->totalLength); slot->id = listCount(usbSlots); listAdd(&usbSlots, slot); - setupInterfaces(slot, (void *)configuration + configuration->size, - configuration->configurationValue); + slot->descriptor = configuration; + setupInterfaces(slot); } extern UsbHostControllerInterface xhci; @@ -166,6 +167,42 @@ return usbSlot->interval; } +typedef union { + uint32_t value; + struct { + uint8_t class, subClass, protocol; + } __attribute__((packed)) types; +} UsbInterfaceType; + +uint32_t getType(uint32_t slotId) { + UsbSlot *usbSlot = listGet(usbSlots, slotId & 0xFFFF); + uint8_t endpoint = (slotId >> 16) + 1; + uint8_t address = endpoint >> 1 | ((endpoint & 1) << 7); + UsbInterfaceDescriptor *interface = (void *)usbSlot->descriptor + usbSlot->descriptor->size; + while (U32(interface) < U32(usbSlot->descriptor) + usbSlot->descriptor->totalLength) { + void *nextInterface = (void *)interface + interface->size; + for (uint32_t i = 0; i < interface->endpointCount;) { + UsbEndpointDescriptor *endpoint = nextInterface; + if (endpoint->descriptorType == 5) { + if (endpoint->address == address) { + UsbInterfaceType result = { + .types = { + .class = interface->interfaceClass, + .subClass = interface->subClass, + .protocol = interface->protocol, + } + }; + return result.value; + } + i++; + } + nextInterface += endpoint->size; + } + interface = nextInterface; + } + return -1; +} + void initialize() { serviceId = getServiceId(); // xhciEvent will carry data corresponding to the data in the xhci event @@ -175,6 +212,7 @@ loadFromInitrd("usbStorage"); createFunction("hid_normal", (void *)hidNormal); createFunction("hid_interval", (void *)hidInterval); + createFunction("get_type", (void *)getType); for (uint32_t i = 0;; i++) { uint32_t class = getDeviceClass(i, 0); if (!class) { diff --git a/src/userland/usbStorage/main.c b/src/userland/usbStorage/main.c index 5dddcbf..4d623da 100644 --- a/src/userland/usbStorage/main.c +++ b/src/userland/usbStorage/main.c @@ -1,11 +1,49 @@ #include #include +typedef union { + uint32_t value; + struct { + uint8_t class, subClass, protocol; + } __attribute__((packed)) types; +} UsbInterfaceType; + + void setup(uint32_t in, uint32_t out, uint32_t serviceName, uint32_t serviceId) { StorageDevice *device = malloc(sizeof(StorageDevice)); device->serviceId = serviceId; - device->getType = getFunction(serviceId, "type"); - printf("in: %x, out: %x\n", in, out); + device->getType = getFunction(serviceId, "get_type"); + UsbInterfaceType typeIn = { .value = request(serviceId, device->getType, in, 0) }; + UsbInterfaceType typeOut = { .value = request(serviceId, device->getType, out, 0) }; + if (typeIn.value != typeOut.value) { + printf("something went wrong when assigning the in and out pipes, aborting...\n"); + return; + } + if (typeIn.types.class != 8) { + printf("type is not 8 (Mass storage device), aborting...\n"); + return; + } + switch (typeIn.types.subClass) { + case 0: printf("subClass: SCISI\n"); break; + case 1: printf("subClass: RBC\n"); break; + case 2: printf("subClass: MMC-5\n"); break; + case 3: printf("subClass: obsolete\n"); break; + case 4: printf("subClass: UFI\n"); break; + case 5: printf("subClass: obsolete\n"); break; + case 6: printf("subClass: SCISI transparent\n"); break; + case 7: printf("subClass: LSD FS\n"); break; + case 8: printf("subClass: IEEE 1667\n"); break; + default: printf("subClass: unknown\n"); break; + } + switch (typeIn.types.protocol) { + case 0x00: printf("protocol: CBI1\n"); break; + case 0x01: printf("protocol: CBI2\n"); break; + case 0x02: printf("protocol: Obsolete\n"); break; + case 0x50: printf("protocol: Bulk-only\n"); break; + case 0x62: printf("protocol: UAS\n"); break; + default: printf("protocol: unknown\n"); break; + } + printf("in: %x, out: %x, typeIn: %x, typeOut: %x\n", in, out, typeIn, typeOut); } int32_t main() {