diff --git a/src/userland/scisi/include/scisi.h b/src/userland/scisi/include/scisi.h index 41e3b04..7f88c95 100644 --- a/src/userland/scisi/include/scisi.h +++ b/src/userland/scisi/include/scisi.h @@ -14,6 +14,7 @@ typedef struct { uint32_t size; + uint32_t transferSize; uint8_t operationCode; // 0x12 uint8_t evpd; // probably 0 uint8_t pageCode; // must be 0 when evpd is 0 @@ -48,6 +49,7 @@ typedef struct { uint32_t size; + uint32_t transferSize; uint8_t operationCode; // 0x25 uint8_t obsolete; uint32_t LBAObsolete; // set to 0, must be inserted with MSB first. @@ -64,6 +66,7 @@ typedef struct { uint32_t size; + uint32_t transferSize; uint8_t operationCode; // 0x28 uint8_t protect; // leave at 0 for now uint8_t lba[4]; // most significant byte first diff --git a/src/userland/scisi/include/scisi.h b/src/userland/scisi/include/scisi.h index 41e3b04..7f88c95 100644 --- a/src/userland/scisi/include/scisi.h +++ b/src/userland/scisi/include/scisi.h @@ -14,6 +14,7 @@ typedef struct { uint32_t size; + uint32_t transferSize; uint8_t operationCode; // 0x12 uint8_t evpd; // probably 0 uint8_t pageCode; // must be 0 when evpd is 0 @@ -48,6 +49,7 @@ typedef struct { uint32_t size; + uint32_t transferSize; uint8_t operationCode; // 0x25 uint8_t obsolete; uint32_t LBAObsolete; // set to 0, must be inserted with MSB first. @@ -64,6 +66,7 @@ typedef struct { uint32_t size; + uint32_t transferSize; uint8_t operationCode; // 0x28 uint8_t protect; // leave at 0 for now uint8_t lba[4]; // most significant byte first diff --git a/src/userland/scisi/main.c b/src/userland/scisi/main.c index d258918..e6abe97 100644 --- a/src/userland/scisi/main.c +++ b/src/userland/scisi/main.c @@ -5,6 +5,8 @@ void doInquiry(ScisiDevice *device) { InquiryCommand *command = malloc(sizeof(InquiryCommand)); + command->size = sizeof(InquiryCommand) - 2*sizeof(uint32_t); + command->transferSize = 5; command->operationCode = 0x12; command->pageCode = 0; command->evpd = 0; @@ -18,6 +20,7 @@ response->size = sizeof(InquiryResponse) - sizeof(uint32_t); request(device->serviceId, device->inFunction, device->in, U32(getPhysicalAddress(response))); command->allocationLengthLow = 5 + response->additionalLength; + command->transferSize = command->allocationLengthLow; request(device->serviceId, device->outFunction, device->out, U32(getPhysicalAddress(command))); request(device->serviceId, device->inFunction, device->in, U32(getPhysicalAddress(response))); @@ -27,7 +30,8 @@ void readSize(ScisiDevice *device) { ReadCapacity10Command *command = malloc(sizeof(ReadCapacity10Command)); - command->size = sizeof(ReadCapacity10Command) - sizeof(uint32_t); + command->size = sizeof(ReadCapacity10Command) - 2*sizeof(uint32_t); + command->transferSize = sizeof(ReadCapacity10Response) - sizeof(uint32_t); command->operationCode = 0x25; command->control = 0; @@ -47,14 +51,15 @@ if (size == 0) { return malloc(1); } + uint32_t blockCount = (size-1) / device->blockSize + 1; Read10Command *command = malloc(sizeof(Read10Command)); - command->size = sizeof(Read10Command) - sizeof(uint32_t); + command->size = sizeof(Read10Command) - 2*sizeof(uint32_t); + command->transferSize = size; command->operationCode = 0x28; command->lba[0] = (uint8_t) (address >> 24); command->lba[1] = (uint8_t) (address >> 16); command->lba[2] = (uint8_t) (address >> 8); command->lba[3] = (uint8_t) (address); - uint32_t blockCount = (size-1) / device->blockSize + 1; command->transferLength[0] = (uint8_t) (blockCount >> 8); command->transferLength[1] = (uint8_t) (blockCount); @@ -69,6 +74,16 @@ return data + 1; // todo: ensure free will work on this } +void *doRead(uint32_t deviceSize, uint32_t blockId) { + uint32_t deviceId = deviceSize & 0xFFFF; + ScisiDevice *device = listGet(devices, deviceId); + void *result = read(device, blockId, deviceSize >> 16); + printf("reading %i bytes from position %i from device %i: %x\n", deviceSize >> 16, blockId, deviceId, getPhysicalAddress(result)); + return getPhysicalAddress(result); +} + +REQUEST(registerMBR, "mbr", "register"); + int32_t registerDevice(uint32_t in, uint32_t out, uint32_t serviceName, uint32_t serviceId) { ScisiDevice *device = malloc(sizeof(ScisiDevice)); device->serviceId = serviceId; @@ -87,10 +102,12 @@ printf("device %i is bootable!\n", device->id); } free(buffer - 4); + registerMBR(device->id, 0); return 0; } int32_t main() { createFunction("register", (void *)registerDevice); + createFunction("mbr_read", (void *)doRead); return 0; } \ No newline at end of file diff --git a/src/userland/scisi/include/scisi.h b/src/userland/scisi/include/scisi.h index 41e3b04..7f88c95 100644 --- a/src/userland/scisi/include/scisi.h +++ b/src/userland/scisi/include/scisi.h @@ -14,6 +14,7 @@ typedef struct { uint32_t size; + uint32_t transferSize; uint8_t operationCode; // 0x12 uint8_t evpd; // probably 0 uint8_t pageCode; // must be 0 when evpd is 0 @@ -48,6 +49,7 @@ typedef struct { uint32_t size; + uint32_t transferSize; uint8_t operationCode; // 0x25 uint8_t obsolete; uint32_t LBAObsolete; // set to 0, must be inserted with MSB first. @@ -64,6 +66,7 @@ typedef struct { uint32_t size; + uint32_t transferSize; uint8_t operationCode; // 0x28 uint8_t protect; // leave at 0 for now uint8_t lba[4]; // most significant byte first diff --git a/src/userland/scisi/main.c b/src/userland/scisi/main.c index d258918..e6abe97 100644 --- a/src/userland/scisi/main.c +++ b/src/userland/scisi/main.c @@ -5,6 +5,8 @@ void doInquiry(ScisiDevice *device) { InquiryCommand *command = malloc(sizeof(InquiryCommand)); + command->size = sizeof(InquiryCommand) - 2*sizeof(uint32_t); + command->transferSize = 5; command->operationCode = 0x12; command->pageCode = 0; command->evpd = 0; @@ -18,6 +20,7 @@ response->size = sizeof(InquiryResponse) - sizeof(uint32_t); request(device->serviceId, device->inFunction, device->in, U32(getPhysicalAddress(response))); command->allocationLengthLow = 5 + response->additionalLength; + command->transferSize = command->allocationLengthLow; request(device->serviceId, device->outFunction, device->out, U32(getPhysicalAddress(command))); request(device->serviceId, device->inFunction, device->in, U32(getPhysicalAddress(response))); @@ -27,7 +30,8 @@ void readSize(ScisiDevice *device) { ReadCapacity10Command *command = malloc(sizeof(ReadCapacity10Command)); - command->size = sizeof(ReadCapacity10Command) - sizeof(uint32_t); + command->size = sizeof(ReadCapacity10Command) - 2*sizeof(uint32_t); + command->transferSize = sizeof(ReadCapacity10Response) - sizeof(uint32_t); command->operationCode = 0x25; command->control = 0; @@ -47,14 +51,15 @@ if (size == 0) { return malloc(1); } + uint32_t blockCount = (size-1) / device->blockSize + 1; Read10Command *command = malloc(sizeof(Read10Command)); - command->size = sizeof(Read10Command) - sizeof(uint32_t); + command->size = sizeof(Read10Command) - 2*sizeof(uint32_t); + command->transferSize = size; command->operationCode = 0x28; command->lba[0] = (uint8_t) (address >> 24); command->lba[1] = (uint8_t) (address >> 16); command->lba[2] = (uint8_t) (address >> 8); command->lba[3] = (uint8_t) (address); - uint32_t blockCount = (size-1) / device->blockSize + 1; command->transferLength[0] = (uint8_t) (blockCount >> 8); command->transferLength[1] = (uint8_t) (blockCount); @@ -69,6 +74,16 @@ return data + 1; // todo: ensure free will work on this } +void *doRead(uint32_t deviceSize, uint32_t blockId) { + uint32_t deviceId = deviceSize & 0xFFFF; + ScisiDevice *device = listGet(devices, deviceId); + void *result = read(device, blockId, deviceSize >> 16); + printf("reading %i bytes from position %i from device %i: %x\n", deviceSize >> 16, blockId, deviceId, getPhysicalAddress(result)); + return getPhysicalAddress(result); +} + +REQUEST(registerMBR, "mbr", "register"); + int32_t registerDevice(uint32_t in, uint32_t out, uint32_t serviceName, uint32_t serviceId) { ScisiDevice *device = malloc(sizeof(ScisiDevice)); device->serviceId = serviceId; @@ -87,10 +102,12 @@ printf("device %i is bootable!\n", device->id); } free(buffer - 4); + registerMBR(device->id, 0); return 0; } int32_t main() { createFunction("register", (void *)registerDevice); + createFunction("mbr_read", (void *)doRead); return 0; } \ No newline at end of file diff --git a/src/userland/usbStorage/main.c b/src/userland/usbStorage/main.c index 50a23d3..0a3ebff 100644 --- a/src/userland/usbStorage/main.c +++ b/src/userland/usbStorage/main.c @@ -57,6 +57,9 @@ uint32_t out(uint32_t out, void *data) { uint32_t *dataHere = requestMemory(1, NULL, data); uint32_t size = *dataHere; + dataHere++; + uint32_t transferSize = *dataHere; + dataHere++; StorageDevice *device = listGet(devices, out & 0xFFFF); uint16_t endpoint = out >> 16; CommandBlockWrapper *command = malloc(sizeof(CommandBlockWrapper)); @@ -67,10 +70,11 @@ command->flags.values.direction = 1; command->LUN = 0; command->length = size; - command->transferSize = 5; - memcpy(dataHere + 1, command->data, size); + command->transferSize = transferSize; // todo: fix this + memcpy(dataHere, command->data, size); request(device->serviceId, device->outFunction, out & 0xFFFF0000 | device->deviceId, U32(getPhysicalAddress(command))); - freePage(dataHere); + freePage(dataHere - 2); + free(command); return 0; }