diff --git a/src/userland/scisi/include/scisi.h b/src/userland/scisi/include/scisi.h index 7faddb1..bcd6da5 100644 --- a/src/userland/scisi/include/scisi.h +++ b/src/userland/scisi/include/scisi.h @@ -9,4 +9,14 @@ uint32_t inFunction, outFunction; } ScisiDevice; +typedef struct { + uint32_t size; + uint8_t operationCode; // 0x12 + uint8_t evpd; // probably 0 + uint8_t pageCode; // must be 0 when evpd is 0 + uint8_t allocationLengthHigh; // should be at least 5 + uint8_t allocationLengthLow; + uint8_t control; +} __attribute__((packed)) InquiryCommand; + #endif \ No newline at end of file diff --git a/src/userland/scisi/include/scisi.h b/src/userland/scisi/include/scisi.h index 7faddb1..bcd6da5 100644 --- a/src/userland/scisi/include/scisi.h +++ b/src/userland/scisi/include/scisi.h @@ -9,4 +9,14 @@ uint32_t inFunction, outFunction; } ScisiDevice; +typedef struct { + uint32_t size; + uint8_t operationCode; // 0x12 + uint8_t evpd; // probably 0 + uint8_t pageCode; // must be 0 when evpd is 0 + uint8_t allocationLengthHigh; // should be at least 5 + uint8_t allocationLengthLow; + uint8_t control; +} __attribute__((packed)) InquiryCommand; + #endif \ No newline at end of file diff --git a/src/userland/scisi/main.c b/src/userland/scisi/main.c index 9ac7c4e..ade0a20 100644 --- a/src/userland/scisi/main.c +++ b/src/userland/scisi/main.c @@ -3,6 +3,18 @@ ListElement *devices = NULL; +void doInquiry(ScisiDevice *device) { + InquiryCommand *command = malloc(sizeof(InquiryCommand)); + command->operationCode = 0x12; + command->pageCode = 0; + command->evpd = 0; + command->allocationLengthHigh = 0; + command->allocationLengthLow = 5; + command->control = 0; + command->size = sizeof(InquiryCommand) - sizeof(uint32_t); + request(device->serviceId, device->outFunction, device->out, U32(getPhysicalAddress(command))); +} + int32_t registerDevice(uint32_t in, uint32_t out, uint32_t serviceName, uint32_t serviceId) { ScisiDevice *device = malloc(sizeof(ScisiDevice)); device->serviceId = serviceId; @@ -13,10 +25,8 @@ device->outFunction = getFunction(serviceId, "scisi_out"); listAdd(&devices, device); printf("registering a new SCISI device (in: %x, out: %x)\n", in, out); - request(device->serviceId, device->outFunction, device->out, 0); - request(device->serviceId, device->inFunction, device->in, 0); + doInquiry(device); return 0; - } int32_t main() { diff --git a/src/userland/scisi/include/scisi.h b/src/userland/scisi/include/scisi.h index 7faddb1..bcd6da5 100644 --- a/src/userland/scisi/include/scisi.h +++ b/src/userland/scisi/include/scisi.h @@ -9,4 +9,14 @@ uint32_t inFunction, outFunction; } ScisiDevice; +typedef struct { + uint32_t size; + uint8_t operationCode; // 0x12 + uint8_t evpd; // probably 0 + uint8_t pageCode; // must be 0 when evpd is 0 + uint8_t allocationLengthHigh; // should be at least 5 + uint8_t allocationLengthLow; + uint8_t control; +} __attribute__((packed)) InquiryCommand; + #endif \ No newline at end of file diff --git a/src/userland/scisi/main.c b/src/userland/scisi/main.c index 9ac7c4e..ade0a20 100644 --- a/src/userland/scisi/main.c +++ b/src/userland/scisi/main.c @@ -3,6 +3,18 @@ ListElement *devices = NULL; +void doInquiry(ScisiDevice *device) { + InquiryCommand *command = malloc(sizeof(InquiryCommand)); + command->operationCode = 0x12; + command->pageCode = 0; + command->evpd = 0; + command->allocationLengthHigh = 0; + command->allocationLengthLow = 5; + command->control = 0; + command->size = sizeof(InquiryCommand) - sizeof(uint32_t); + request(device->serviceId, device->outFunction, device->out, U32(getPhysicalAddress(command))); +} + int32_t registerDevice(uint32_t in, uint32_t out, uint32_t serviceName, uint32_t serviceId) { ScisiDevice *device = malloc(sizeof(ScisiDevice)); device->serviceId = serviceId; @@ -13,10 +25,8 @@ device->outFunction = getFunction(serviceId, "scisi_out"); listAdd(&devices, device); printf("registering a new SCISI device (in: %x, out: %x)\n", in, out); - request(device->serviceId, device->outFunction, device->out, 0); - request(device->serviceId, device->inFunction, device->in, 0); + doInquiry(device); return 0; - } int32_t main() { diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index 49edfd6..f73e4c6 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -71,6 +71,7 @@ void (*doNormal)(void *, void *, uint32_t); void (*command)(void *, uint8_t, uint8_t, uint16_t, uint8_t); uint32_t (*configureEndpoint)(void *, UsbEndpointDescriptor *); + void (*writeNormal)(void *, void *, uint32_t, uint32_t); } UsbHostControllerInterface; typedef struct { diff --git a/src/userland/scisi/include/scisi.h b/src/userland/scisi/include/scisi.h index 7faddb1..bcd6da5 100644 --- a/src/userland/scisi/include/scisi.h +++ b/src/userland/scisi/include/scisi.h @@ -9,4 +9,14 @@ uint32_t inFunction, outFunction; } ScisiDevice; +typedef struct { + uint32_t size; + uint8_t operationCode; // 0x12 + uint8_t evpd; // probably 0 + uint8_t pageCode; // must be 0 when evpd is 0 + uint8_t allocationLengthHigh; // should be at least 5 + uint8_t allocationLengthLow; + uint8_t control; +} __attribute__((packed)) InquiryCommand; + #endif \ No newline at end of file diff --git a/src/userland/scisi/main.c b/src/userland/scisi/main.c index 9ac7c4e..ade0a20 100644 --- a/src/userland/scisi/main.c +++ b/src/userland/scisi/main.c @@ -3,6 +3,18 @@ ListElement *devices = NULL; +void doInquiry(ScisiDevice *device) { + InquiryCommand *command = malloc(sizeof(InquiryCommand)); + command->operationCode = 0x12; + command->pageCode = 0; + command->evpd = 0; + command->allocationLengthHigh = 0; + command->allocationLengthLow = 5; + command->control = 0; + command->size = sizeof(InquiryCommand) - sizeof(uint32_t); + request(device->serviceId, device->outFunction, device->out, U32(getPhysicalAddress(command))); +} + int32_t registerDevice(uint32_t in, uint32_t out, uint32_t serviceName, uint32_t serviceId) { ScisiDevice *device = malloc(sizeof(ScisiDevice)); device->serviceId = serviceId; @@ -13,10 +25,8 @@ device->outFunction = getFunction(serviceId, "scisi_out"); listAdd(&devices, device); printf("registering a new SCISI device (in: %x, out: %x)\n", in, out); - request(device->serviceId, device->outFunction, device->out, 0); - request(device->serviceId, device->inFunction, device->in, 0); + doInquiry(device); return 0; - } int32_t main() { diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index 49edfd6..f73e4c6 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -71,6 +71,7 @@ void (*doNormal)(void *, void *, uint32_t); void (*command)(void *, uint8_t, uint8_t, uint16_t, uint8_t); uint32_t (*configureEndpoint)(void *, UsbEndpointDescriptor *); + void (*writeNormal)(void *, void *, uint32_t, uint32_t); } UsbHostControllerInterface; typedef struct { diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index 0472251..13903a7 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -162,6 +162,15 @@ // data is returned to buffer } +void storageWrite(uint32_t slotId, void *buffer) { + uint32_t *bufferHere = requestMemory(1, NULL, buffer); + uint32_t size = *bufferHere; + UsbSlot *usbSlot = listGet(usbSlots, slotId & 0xFFFF); + printf("write: %x, %x -> %x, %x (slot %i)\n", slotId, buffer, bufferHere, buffer + 4, slotId >> 16); + void (*write)(void *, void *, uint32_t, uint32_t) = usbSlot->interface->writeNormal; + write(usbSlot->data, buffer + 4, slotId >> 16, size); +} + uint32_t hidInterval(uint32_t slotId) { UsbSlot *usbSlot = listGet(usbSlots, slotId & 0xFFFF); return usbSlot->interval; @@ -212,6 +221,7 @@ loadFromInitrd("usbStorage"); createFunction("hid_normal", (void *)hidNormal); createFunction("hid_interval", (void *)hidInterval); + createFunction("storage_out", (void *)storageWrite); createFunction("get_type", (void *)getType); for (uint32_t i = 0;; i++) { uint32_t class = getDeviceClass(i, 0); diff --git a/src/userland/scisi/include/scisi.h b/src/userland/scisi/include/scisi.h index 7faddb1..bcd6da5 100644 --- a/src/userland/scisi/include/scisi.h +++ b/src/userland/scisi/include/scisi.h @@ -9,4 +9,14 @@ uint32_t inFunction, outFunction; } ScisiDevice; +typedef struct { + uint32_t size; + uint8_t operationCode; // 0x12 + uint8_t evpd; // probably 0 + uint8_t pageCode; // must be 0 when evpd is 0 + uint8_t allocationLengthHigh; // should be at least 5 + uint8_t allocationLengthLow; + uint8_t control; +} __attribute__((packed)) InquiryCommand; + #endif \ No newline at end of file diff --git a/src/userland/scisi/main.c b/src/userland/scisi/main.c index 9ac7c4e..ade0a20 100644 --- a/src/userland/scisi/main.c +++ b/src/userland/scisi/main.c @@ -3,6 +3,18 @@ ListElement *devices = NULL; +void doInquiry(ScisiDevice *device) { + InquiryCommand *command = malloc(sizeof(InquiryCommand)); + command->operationCode = 0x12; + command->pageCode = 0; + command->evpd = 0; + command->allocationLengthHigh = 0; + command->allocationLengthLow = 5; + command->control = 0; + command->size = sizeof(InquiryCommand) - sizeof(uint32_t); + request(device->serviceId, device->outFunction, device->out, U32(getPhysicalAddress(command))); +} + int32_t registerDevice(uint32_t in, uint32_t out, uint32_t serviceName, uint32_t serviceId) { ScisiDevice *device = malloc(sizeof(ScisiDevice)); device->serviceId = serviceId; @@ -13,10 +25,8 @@ device->outFunction = getFunction(serviceId, "scisi_out"); listAdd(&devices, device); printf("registering a new SCISI device (in: %x, out: %x)\n", in, out); - request(device->serviceId, device->outFunction, device->out, 0); - request(device->serviceId, device->inFunction, device->in, 0); + doInquiry(device); return 0; - } int32_t main() { diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index 49edfd6..f73e4c6 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -71,6 +71,7 @@ void (*doNormal)(void *, void *, uint32_t); void (*command)(void *, uint8_t, uint8_t, uint16_t, uint8_t); uint32_t (*configureEndpoint)(void *, UsbEndpointDescriptor *); + void (*writeNormal)(void *, void *, uint32_t, uint32_t); } UsbHostControllerInterface; typedef struct { diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index 0472251..13903a7 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -162,6 +162,15 @@ // data is returned to buffer } +void storageWrite(uint32_t slotId, void *buffer) { + uint32_t *bufferHere = requestMemory(1, NULL, buffer); + uint32_t size = *bufferHere; + UsbSlot *usbSlot = listGet(usbSlots, slotId & 0xFFFF); + printf("write: %x, %x -> %x, %x (slot %i)\n", slotId, buffer, bufferHere, buffer + 4, slotId >> 16); + void (*write)(void *, void *, uint32_t, uint32_t) = usbSlot->interface->writeNormal; + write(usbSlot->data, buffer + 4, slotId >> 16, size); +} + uint32_t hidInterval(uint32_t slotId) { UsbSlot *usbSlot = listGet(usbSlots, slotId & 0xFFFF); return usbSlot->interval; @@ -212,6 +221,7 @@ loadFromInitrd("usbStorage"); createFunction("hid_normal", (void *)hidNormal); createFunction("hid_interval", (void *)hidInterval); + createFunction("storage_out", (void *)storageWrite); createFunction("get_type", (void *)getType); for (uint32_t i = 0;; i++) { uint32_t class = getDeviceClass(i, 0); diff --git a/src/userland/usb/xhci/xhci.c b/src/userland/usb/xhci/xhci.c index 6d8e48d..9e900bd 100644 --- a/src/userland/usb/xhci/xhci.c +++ b/src/userland/usb/xhci/xhci.c @@ -71,7 +71,6 @@ void xhciNormal(SlotXHCI *slot, void *bufferPhysical, uint32_t endpointIndex) { XHCINormalTRB normal = {0}; normal.type = 1; - normal.inDirection = 1; normal.interrupterTarget = 0; normal.interruptOnCompletion = 1; normal.interruptOnShortPacket = 1; @@ -84,6 +83,23 @@ awaitCode(serviceId, xhciEvent, commandAddress); } +void doXhciWriteNormal(SlotXHCI * slot, void *bufferPhysical, uint32_t endpointIndex, uint32_t transferSize) { + printf("still alive: %x, %x, %i, %i\n", slot, bufferPhysical, endpointIndex, transferSize); + printf("%x", slot->inputContext->deviceContext.endpoints[endpointIndex].endpointType); + XHCINormalTRB normal = {0}; + normal.dataBuffer[0] = U32(bufferPhysical); + normal.dataBuffer[1] = 0; + normal.interrupterTarget = 0; + normal.interruptOnCompletion = 1; + normal.interruptOnShortPacket = 1; + normal.transferSize = transferSize; + normal.type = 1; + uint32_t commandAddress = U32(enqueueCommand( + slot->endpointRings[endpointIndex], (void *)&normal)); + slot->controller->doorbells[slot->slotIndex] = endpointIndex + 1; + awaitCode(serviceId, xhciEvent, commandAddress); +} + void doXhciCommand(SlotXHCI *slot, uint8_t requestType, uint8_t request, uint16_t value, uint8_t direction) { XHCISetupStageTRB setup = {0}; setup.requestType = requestType; @@ -165,4 +181,5 @@ .pciClass = 0x0C0330, .doNormal = (void *)xhciNormal, .command = (void *)doXhciCommand, + .writeNormal = (void *)doXhciWriteNormal, }; diff --git a/src/userland/scisi/include/scisi.h b/src/userland/scisi/include/scisi.h index 7faddb1..bcd6da5 100644 --- a/src/userland/scisi/include/scisi.h +++ b/src/userland/scisi/include/scisi.h @@ -9,4 +9,14 @@ uint32_t inFunction, outFunction; } ScisiDevice; +typedef struct { + uint32_t size; + uint8_t operationCode; // 0x12 + uint8_t evpd; // probably 0 + uint8_t pageCode; // must be 0 when evpd is 0 + uint8_t allocationLengthHigh; // should be at least 5 + uint8_t allocationLengthLow; + uint8_t control; +} __attribute__((packed)) InquiryCommand; + #endif \ No newline at end of file diff --git a/src/userland/scisi/main.c b/src/userland/scisi/main.c index 9ac7c4e..ade0a20 100644 --- a/src/userland/scisi/main.c +++ b/src/userland/scisi/main.c @@ -3,6 +3,18 @@ ListElement *devices = NULL; +void doInquiry(ScisiDevice *device) { + InquiryCommand *command = malloc(sizeof(InquiryCommand)); + command->operationCode = 0x12; + command->pageCode = 0; + command->evpd = 0; + command->allocationLengthHigh = 0; + command->allocationLengthLow = 5; + command->control = 0; + command->size = sizeof(InquiryCommand) - sizeof(uint32_t); + request(device->serviceId, device->outFunction, device->out, U32(getPhysicalAddress(command))); +} + int32_t registerDevice(uint32_t in, uint32_t out, uint32_t serviceName, uint32_t serviceId) { ScisiDevice *device = malloc(sizeof(ScisiDevice)); device->serviceId = serviceId; @@ -13,10 +25,8 @@ device->outFunction = getFunction(serviceId, "scisi_out"); listAdd(&devices, device); printf("registering a new SCISI device (in: %x, out: %x)\n", in, out); - request(device->serviceId, device->outFunction, device->out, 0); - request(device->serviceId, device->inFunction, device->in, 0); + doInquiry(device); return 0; - } int32_t main() { diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index 49edfd6..f73e4c6 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -71,6 +71,7 @@ void (*doNormal)(void *, void *, uint32_t); void (*command)(void *, uint8_t, uint8_t, uint16_t, uint8_t); uint32_t (*configureEndpoint)(void *, UsbEndpointDescriptor *); + void (*writeNormal)(void *, void *, uint32_t, uint32_t); } UsbHostControllerInterface; typedef struct { diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index 0472251..13903a7 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -162,6 +162,15 @@ // data is returned to buffer } +void storageWrite(uint32_t slotId, void *buffer) { + uint32_t *bufferHere = requestMemory(1, NULL, buffer); + uint32_t size = *bufferHere; + UsbSlot *usbSlot = listGet(usbSlots, slotId & 0xFFFF); + printf("write: %x, %x -> %x, %x (slot %i)\n", slotId, buffer, bufferHere, buffer + 4, slotId >> 16); + void (*write)(void *, void *, uint32_t, uint32_t) = usbSlot->interface->writeNormal; + write(usbSlot->data, buffer + 4, slotId >> 16, size); +} + uint32_t hidInterval(uint32_t slotId) { UsbSlot *usbSlot = listGet(usbSlots, slotId & 0xFFFF); return usbSlot->interval; @@ -212,6 +221,7 @@ loadFromInitrd("usbStorage"); createFunction("hid_normal", (void *)hidNormal); createFunction("hid_interval", (void *)hidInterval); + createFunction("storage_out", (void *)storageWrite); createFunction("get_type", (void *)getType); for (uint32_t i = 0;; i++) { uint32_t class = getDeviceClass(i, 0); diff --git a/src/userland/usb/xhci/xhci.c b/src/userland/usb/xhci/xhci.c index 6d8e48d..9e900bd 100644 --- a/src/userland/usb/xhci/xhci.c +++ b/src/userland/usb/xhci/xhci.c @@ -71,7 +71,6 @@ void xhciNormal(SlotXHCI *slot, void *bufferPhysical, uint32_t endpointIndex) { XHCINormalTRB normal = {0}; normal.type = 1; - normal.inDirection = 1; normal.interrupterTarget = 0; normal.interruptOnCompletion = 1; normal.interruptOnShortPacket = 1; @@ -84,6 +83,23 @@ awaitCode(serviceId, xhciEvent, commandAddress); } +void doXhciWriteNormal(SlotXHCI * slot, void *bufferPhysical, uint32_t endpointIndex, uint32_t transferSize) { + printf("still alive: %x, %x, %i, %i\n", slot, bufferPhysical, endpointIndex, transferSize); + printf("%x", slot->inputContext->deviceContext.endpoints[endpointIndex].endpointType); + XHCINormalTRB normal = {0}; + normal.dataBuffer[0] = U32(bufferPhysical); + normal.dataBuffer[1] = 0; + normal.interrupterTarget = 0; + normal.interruptOnCompletion = 1; + normal.interruptOnShortPacket = 1; + normal.transferSize = transferSize; + normal.type = 1; + uint32_t commandAddress = U32(enqueueCommand( + slot->endpointRings[endpointIndex], (void *)&normal)); + slot->controller->doorbells[slot->slotIndex] = endpointIndex + 1; + awaitCode(serviceId, xhciEvent, commandAddress); +} + void doXhciCommand(SlotXHCI *slot, uint8_t requestType, uint8_t request, uint16_t value, uint8_t direction) { XHCISetupStageTRB setup = {0}; setup.requestType = requestType; @@ -165,4 +181,5 @@ .pciClass = 0x0C0330, .doNormal = (void *)xhciNormal, .command = (void *)doXhciCommand, + .writeNormal = (void *)doXhciWriteNormal, }; diff --git a/src/userland/usb/xhci/xhci.h b/src/userland/usb/xhci/xhci.h index 5693e36..e202d23 100644 --- a/src/userland/usb/xhci/xhci.h +++ b/src/userland/usb/xhci/xhci.h @@ -114,7 +114,7 @@ uint32_t cycle : 1, evaluateNext : 1, interruptOnShortPacket : 1, noSnoop : 1, chain : 1, interruptOnCompletion : 1, immediateData : 1, - reserved : 3, type : 6, inDirection : 1; + reserved : 3, type : 6, reserved1: 16; } __attribute__((packed)) XHCINormalTRB; typedef volatile struct { diff --git a/src/userland/scisi/include/scisi.h b/src/userland/scisi/include/scisi.h index 7faddb1..bcd6da5 100644 --- a/src/userland/scisi/include/scisi.h +++ b/src/userland/scisi/include/scisi.h @@ -9,4 +9,14 @@ uint32_t inFunction, outFunction; } ScisiDevice; +typedef struct { + uint32_t size; + uint8_t operationCode; // 0x12 + uint8_t evpd; // probably 0 + uint8_t pageCode; // must be 0 when evpd is 0 + uint8_t allocationLengthHigh; // should be at least 5 + uint8_t allocationLengthLow; + uint8_t control; +} __attribute__((packed)) InquiryCommand; + #endif \ No newline at end of file diff --git a/src/userland/scisi/main.c b/src/userland/scisi/main.c index 9ac7c4e..ade0a20 100644 --- a/src/userland/scisi/main.c +++ b/src/userland/scisi/main.c @@ -3,6 +3,18 @@ ListElement *devices = NULL; +void doInquiry(ScisiDevice *device) { + InquiryCommand *command = malloc(sizeof(InquiryCommand)); + command->operationCode = 0x12; + command->pageCode = 0; + command->evpd = 0; + command->allocationLengthHigh = 0; + command->allocationLengthLow = 5; + command->control = 0; + command->size = sizeof(InquiryCommand) - sizeof(uint32_t); + request(device->serviceId, device->outFunction, device->out, U32(getPhysicalAddress(command))); +} + int32_t registerDevice(uint32_t in, uint32_t out, uint32_t serviceName, uint32_t serviceId) { ScisiDevice *device = malloc(sizeof(ScisiDevice)); device->serviceId = serviceId; @@ -13,10 +25,8 @@ device->outFunction = getFunction(serviceId, "scisi_out"); listAdd(&devices, device); printf("registering a new SCISI device (in: %x, out: %x)\n", in, out); - request(device->serviceId, device->outFunction, device->out, 0); - request(device->serviceId, device->inFunction, device->in, 0); + doInquiry(device); return 0; - } int32_t main() { diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index 49edfd6..f73e4c6 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -71,6 +71,7 @@ void (*doNormal)(void *, void *, uint32_t); void (*command)(void *, uint8_t, uint8_t, uint16_t, uint8_t); uint32_t (*configureEndpoint)(void *, UsbEndpointDescriptor *); + void (*writeNormal)(void *, void *, uint32_t, uint32_t); } UsbHostControllerInterface; typedef struct { diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index 0472251..13903a7 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -162,6 +162,15 @@ // data is returned to buffer } +void storageWrite(uint32_t slotId, void *buffer) { + uint32_t *bufferHere = requestMemory(1, NULL, buffer); + uint32_t size = *bufferHere; + UsbSlot *usbSlot = listGet(usbSlots, slotId & 0xFFFF); + printf("write: %x, %x -> %x, %x (slot %i)\n", slotId, buffer, bufferHere, buffer + 4, slotId >> 16); + void (*write)(void *, void *, uint32_t, uint32_t) = usbSlot->interface->writeNormal; + write(usbSlot->data, buffer + 4, slotId >> 16, size); +} + uint32_t hidInterval(uint32_t slotId) { UsbSlot *usbSlot = listGet(usbSlots, slotId & 0xFFFF); return usbSlot->interval; @@ -212,6 +221,7 @@ loadFromInitrd("usbStorage"); createFunction("hid_normal", (void *)hidNormal); createFunction("hid_interval", (void *)hidInterval); + createFunction("storage_out", (void *)storageWrite); createFunction("get_type", (void *)getType); for (uint32_t i = 0;; i++) { uint32_t class = getDeviceClass(i, 0); diff --git a/src/userland/usb/xhci/xhci.c b/src/userland/usb/xhci/xhci.c index 6d8e48d..9e900bd 100644 --- a/src/userland/usb/xhci/xhci.c +++ b/src/userland/usb/xhci/xhci.c @@ -71,7 +71,6 @@ void xhciNormal(SlotXHCI *slot, void *bufferPhysical, uint32_t endpointIndex) { XHCINormalTRB normal = {0}; normal.type = 1; - normal.inDirection = 1; normal.interrupterTarget = 0; normal.interruptOnCompletion = 1; normal.interruptOnShortPacket = 1; @@ -84,6 +83,23 @@ awaitCode(serviceId, xhciEvent, commandAddress); } +void doXhciWriteNormal(SlotXHCI * slot, void *bufferPhysical, uint32_t endpointIndex, uint32_t transferSize) { + printf("still alive: %x, %x, %i, %i\n", slot, bufferPhysical, endpointIndex, transferSize); + printf("%x", slot->inputContext->deviceContext.endpoints[endpointIndex].endpointType); + XHCINormalTRB normal = {0}; + normal.dataBuffer[0] = U32(bufferPhysical); + normal.dataBuffer[1] = 0; + normal.interrupterTarget = 0; + normal.interruptOnCompletion = 1; + normal.interruptOnShortPacket = 1; + normal.transferSize = transferSize; + normal.type = 1; + uint32_t commandAddress = U32(enqueueCommand( + slot->endpointRings[endpointIndex], (void *)&normal)); + slot->controller->doorbells[slot->slotIndex] = endpointIndex + 1; + awaitCode(serviceId, xhciEvent, commandAddress); +} + void doXhciCommand(SlotXHCI *slot, uint8_t requestType, uint8_t request, uint16_t value, uint8_t direction) { XHCISetupStageTRB setup = {0}; setup.requestType = requestType; @@ -165,4 +181,5 @@ .pciClass = 0x0C0330, .doNormal = (void *)xhciNormal, .command = (void *)doXhciCommand, + .writeNormal = (void *)doXhciWriteNormal, }; diff --git a/src/userland/usb/xhci/xhci.h b/src/userland/usb/xhci/xhci.h index 5693e36..e202d23 100644 --- a/src/userland/usb/xhci/xhci.h +++ b/src/userland/usb/xhci/xhci.h @@ -114,7 +114,7 @@ uint32_t cycle : 1, evaluateNext : 1, interruptOnShortPacket : 1, noSnoop : 1, chain : 1, interruptOnCompletion : 1, immediateData : 1, - reserved : 3, type : 6, inDirection : 1; + reserved : 3, type : 6, reserved1: 16; } __attribute__((packed)) XHCINormalTRB; typedef volatile struct { diff --git a/src/userland/usbStorage/include/storage.h b/src/userland/usbStorage/include/storage.h index 4049225..47cb7ef 100644 --- a/src/userland/usbStorage/include/storage.h +++ b/src/userland/usbStorage/include/storage.h @@ -7,6 +7,7 @@ uint32_t serviceId; uint32_t deviceId; uint32_t id; + uint32_t inFunction, outFunction; } StorageDevice; typedef enum UsbStorageSubClass { @@ -31,4 +32,22 @@ UnknownProtocol = 5 } UsbStorageProtocol; +typedef struct { + uint32_t size; + uint32_t signature; + uint32_t tag; + uint32_t transferSize; + union { + uint8_t byte; + struct { + uint8_t reserved: 6; + uint8_t obsolete: 1; + uint8_t direction: 1; + } __attribute__((packed)) values; + } flags; + uint8_t LUN; + uint8_t length; + uint8_t data[16]; +} CommandBlockWrapper; + #endif // STORAGE_H \ No newline at end of file diff --git a/src/userland/scisi/include/scisi.h b/src/userland/scisi/include/scisi.h index 7faddb1..bcd6da5 100644 --- a/src/userland/scisi/include/scisi.h +++ b/src/userland/scisi/include/scisi.h @@ -9,4 +9,14 @@ uint32_t inFunction, outFunction; } ScisiDevice; +typedef struct { + uint32_t size; + uint8_t operationCode; // 0x12 + uint8_t evpd; // probably 0 + uint8_t pageCode; // must be 0 when evpd is 0 + uint8_t allocationLengthHigh; // should be at least 5 + uint8_t allocationLengthLow; + uint8_t control; +} __attribute__((packed)) InquiryCommand; + #endif \ No newline at end of file diff --git a/src/userland/scisi/main.c b/src/userland/scisi/main.c index 9ac7c4e..ade0a20 100644 --- a/src/userland/scisi/main.c +++ b/src/userland/scisi/main.c @@ -3,6 +3,18 @@ ListElement *devices = NULL; +void doInquiry(ScisiDevice *device) { + InquiryCommand *command = malloc(sizeof(InquiryCommand)); + command->operationCode = 0x12; + command->pageCode = 0; + command->evpd = 0; + command->allocationLengthHigh = 0; + command->allocationLengthLow = 5; + command->control = 0; + command->size = sizeof(InquiryCommand) - sizeof(uint32_t); + request(device->serviceId, device->outFunction, device->out, U32(getPhysicalAddress(command))); +} + int32_t registerDevice(uint32_t in, uint32_t out, uint32_t serviceName, uint32_t serviceId) { ScisiDevice *device = malloc(sizeof(ScisiDevice)); device->serviceId = serviceId; @@ -13,10 +25,8 @@ device->outFunction = getFunction(serviceId, "scisi_out"); listAdd(&devices, device); printf("registering a new SCISI device (in: %x, out: %x)\n", in, out); - request(device->serviceId, device->outFunction, device->out, 0); - request(device->serviceId, device->inFunction, device->in, 0); + doInquiry(device); return 0; - } int32_t main() { diff --git a/src/userland/usb/include/usb.h b/src/userland/usb/include/usb.h index 49edfd6..f73e4c6 100644 --- a/src/userland/usb/include/usb.h +++ b/src/userland/usb/include/usb.h @@ -71,6 +71,7 @@ void (*doNormal)(void *, void *, uint32_t); void (*command)(void *, uint8_t, uint8_t, uint16_t, uint8_t); uint32_t (*configureEndpoint)(void *, UsbEndpointDescriptor *); + void (*writeNormal)(void *, void *, uint32_t, uint32_t); } UsbHostControllerInterface; typedef struct { diff --git a/src/userland/usb/main.c b/src/userland/usb/main.c index 0472251..13903a7 100644 --- a/src/userland/usb/main.c +++ b/src/userland/usb/main.c @@ -162,6 +162,15 @@ // data is returned to buffer } +void storageWrite(uint32_t slotId, void *buffer) { + uint32_t *bufferHere = requestMemory(1, NULL, buffer); + uint32_t size = *bufferHere; + UsbSlot *usbSlot = listGet(usbSlots, slotId & 0xFFFF); + printf("write: %x, %x -> %x, %x (slot %i)\n", slotId, buffer, bufferHere, buffer + 4, slotId >> 16); + void (*write)(void *, void *, uint32_t, uint32_t) = usbSlot->interface->writeNormal; + write(usbSlot->data, buffer + 4, slotId >> 16, size); +} + uint32_t hidInterval(uint32_t slotId) { UsbSlot *usbSlot = listGet(usbSlots, slotId & 0xFFFF); return usbSlot->interval; @@ -212,6 +221,7 @@ loadFromInitrd("usbStorage"); createFunction("hid_normal", (void *)hidNormal); createFunction("hid_interval", (void *)hidInterval); + createFunction("storage_out", (void *)storageWrite); createFunction("get_type", (void *)getType); for (uint32_t i = 0;; i++) { uint32_t class = getDeviceClass(i, 0); diff --git a/src/userland/usb/xhci/xhci.c b/src/userland/usb/xhci/xhci.c index 6d8e48d..9e900bd 100644 --- a/src/userland/usb/xhci/xhci.c +++ b/src/userland/usb/xhci/xhci.c @@ -71,7 +71,6 @@ void xhciNormal(SlotXHCI *slot, void *bufferPhysical, uint32_t endpointIndex) { XHCINormalTRB normal = {0}; normal.type = 1; - normal.inDirection = 1; normal.interrupterTarget = 0; normal.interruptOnCompletion = 1; normal.interruptOnShortPacket = 1; @@ -84,6 +83,23 @@ awaitCode(serviceId, xhciEvent, commandAddress); } +void doXhciWriteNormal(SlotXHCI * slot, void *bufferPhysical, uint32_t endpointIndex, uint32_t transferSize) { + printf("still alive: %x, %x, %i, %i\n", slot, bufferPhysical, endpointIndex, transferSize); + printf("%x", slot->inputContext->deviceContext.endpoints[endpointIndex].endpointType); + XHCINormalTRB normal = {0}; + normal.dataBuffer[0] = U32(bufferPhysical); + normal.dataBuffer[1] = 0; + normal.interrupterTarget = 0; + normal.interruptOnCompletion = 1; + normal.interruptOnShortPacket = 1; + normal.transferSize = transferSize; + normal.type = 1; + uint32_t commandAddress = U32(enqueueCommand( + slot->endpointRings[endpointIndex], (void *)&normal)); + slot->controller->doorbells[slot->slotIndex] = endpointIndex + 1; + awaitCode(serviceId, xhciEvent, commandAddress); +} + void doXhciCommand(SlotXHCI *slot, uint8_t requestType, uint8_t request, uint16_t value, uint8_t direction) { XHCISetupStageTRB setup = {0}; setup.requestType = requestType; @@ -165,4 +181,5 @@ .pciClass = 0x0C0330, .doNormal = (void *)xhciNormal, .command = (void *)doXhciCommand, + .writeNormal = (void *)doXhciWriteNormal, }; diff --git a/src/userland/usb/xhci/xhci.h b/src/userland/usb/xhci/xhci.h index 5693e36..e202d23 100644 --- a/src/userland/usb/xhci/xhci.h +++ b/src/userland/usb/xhci/xhci.h @@ -114,7 +114,7 @@ uint32_t cycle : 1, evaluateNext : 1, interruptOnShortPacket : 1, noSnoop : 1, chain : 1, interruptOnCompletion : 1, immediateData : 1, - reserved : 3, type : 6, inDirection : 1; + reserved : 3, type : 6, reserved1: 16; } __attribute__((packed)) XHCINormalTRB; typedef volatile struct { diff --git a/src/userland/usbStorage/include/storage.h b/src/userland/usbStorage/include/storage.h index 4049225..47cb7ef 100644 --- a/src/userland/usbStorage/include/storage.h +++ b/src/userland/usbStorage/include/storage.h @@ -7,6 +7,7 @@ uint32_t serviceId; uint32_t deviceId; uint32_t id; + uint32_t inFunction, outFunction; } StorageDevice; typedef enum UsbStorageSubClass { @@ -31,4 +32,22 @@ UnknownProtocol = 5 } UsbStorageProtocol; +typedef struct { + uint32_t size; + uint32_t signature; + uint32_t tag; + uint32_t transferSize; + union { + uint8_t byte; + struct { + uint8_t reserved: 6; + uint8_t obsolete: 1; + uint8_t direction: 1; + } __attribute__((packed)) values; + } flags; + uint8_t LUN; + uint8_t length; + uint8_t data[16]; +} CommandBlockWrapper; + #endif // STORAGE_H \ No newline at end of file diff --git a/src/userland/usbStorage/main.c b/src/userland/usbStorage/main.c index 91655ae..184ce0c 100644 --- a/src/userland/usbStorage/main.c +++ b/src/userland/usbStorage/main.c @@ -40,10 +40,23 @@ return 0; } -uint32_t out(uint32_t out) { +uint32_t out(uint32_t out, void *data) { + uint32_t *dataHere = requestMemory(1, NULL, data); + uint32_t size = *dataHere; StorageDevice *device = listGet(devices, out & 0xFFFF); uint16_t endpoint = out >> 16; + CommandBlockWrapper *command = malloc(sizeof(CommandBlockWrapper)); + command->size = 15 + size; + command->signature = 0x43425355; + command->tag = 0xB105F00D; // just testing for now... + command->length = 0; + command->flags.values.direction = 1; + command->LUN = 0; + command->length = size; + memcpy(dataHere + 1, command->data, size); + request(device->serviceId, device->outFunction, out & 0xFFFF0000 | device->deviceId, U32(getPhysicalAddress(command))); printf("writing to device %i (usb device %i, endpoint %i, id %x)...\n", device->id, device->deviceId, endpoint, out); + freePage(dataHere); return 0; } @@ -89,6 +102,9 @@ StorageDevice *device = malloc(sizeof(StorageDevice)); device->serviceId = serviceId; device->id = listCount(devices); + device->deviceId = in & 0xFFFF; + device->inFunction = getFunction(serviceId, "storage_in"); + device->outFunction = getFunction(serviceId, "storage_out"); listAdd(&devices, device); if (subClass == SCISI_Transparent && protocol == BulkOnly) { registerScisi(device->id | (in & 0xFFFF0000), device->id | (out & 0xFFFF0000));