From 0b8aa1b27b4cf6b723dc019ab92781c8302b113b Mon Sep 17 00:00:00 2001 From: Philip Meulengracht Date: Fri, 12 May 2023 14:05:07 +0200 Subject: [PATCH] usb: fix remaining USB issues for OHCI in terms of cross-page buffers --- librt/libc/io/open.c | 4 +- librt/libc/os/init.c | 2 +- librt/libc/stdio/fwrite.c | 15 +-- librt/libddk/include/ddk/utils.h | 1 + .../filesystems/mfs/directory_operations.c | 5 +- modules/filesystems/mfs/file_operations.c | 30 +++-- modules/filesystems/mfs/mfs.h | 4 +- modules/filesystems/mfs/utilities.c | 49 +++++--- modules/serial/usb/common/transfer.h | 4 + modules/serial/usb/ohci/structures/itd.c | 2 +- modules/serial/usb/ohci/structures/td.c | 39 ++++-- modules/serial/usb/ohci/transfer.c | 115 ++++++++++++------ modules/storage/msd/functions.c | 27 ++-- modules/storage/msd/protocols/bulk.c | 20 ++- services/processd/pe/mapper.c | 2 +- services/served/server/install.c | 5 +- tools/setup.bochsrc | 4 +- 17 files changed, 204 insertions(+), 124 deletions(-) diff --git a/librt/libc/io/open.c b/librt/libc/io/open.c index 5b35c517a..ab484742c 100644 --- a/librt/libc/io/open.c +++ b/librt/libc/io/open.c @@ -206,7 +206,7 @@ __read_large( TRACE("__read_large: aligning buffer=0x%" PRIxIN ", align=0x%" PRIxIN, buffer, bytesToAlign); oserr = __file_read(handle, buffer, bytesToAlign, bytesReadOut); - if (oserr != OS_EOK) { + if (oserr != OS_EOK || *bytesReadOut == 0) { return oserr; } adjustedPointer = (void*)((uintptr_t)buffer + bytesToAlign); @@ -302,7 +302,7 @@ __write_large( TRACE("__write_large: aligning buffer=0x%" PRIxIN ", align=0x%" PRIxIN, buffer, bytesToAlign); oserr = __file_write(handle, buffer, bytesToAlign, bytesWrittenOut); - if (oserr != OS_EOK) { + if (oserr != OS_EOK|| *bytesWrittenOut == 0) { return oserr; } adjustedPointer = (void*)((uintptr_t)buffer + bytesToAlign); diff --git a/librt/libc/os/init.c b/librt/libc/os/init.c index 29ddad87c..75341ae67 100644 --- a/librt/libc/os/init.c +++ b/librt/libc/os/init.c @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -#define __TRACE +//#define __TRACE #define __need_quantity #include diff --git a/librt/libc/stdio/fwrite.c b/librt/libc/stdio/fwrite.c index b1150ba35..e436dfc04 100644 --- a/librt/libc/stdio/fwrite.c +++ b/librt/libc/stdio/fwrite.c @@ -52,8 +52,9 @@ __prewrite_buffer( size_t fwrite(const void* vptr, size_t size, size_t count, FILE* stream) { - size_t wrcnt = size * count; - int written = 0; + size_t wrcnt = size * count; + int written = 0; + const char* p = vptr; TRACE("fwrite(count=%u)", wrcnt); if (vptr == NULL || stream == NULL) { @@ -81,12 +82,12 @@ size_t fwrite(const void* vptr, size_t size, size_t count, FILE* stream) // Fill the buffer before continuing, and flush if neccessary. if (__FILE_IsBuffered(stream) && __FILE_BufferPosition(stream) > 0) { int bytesAvailable = stream->BufferSize - __FILE_BufferPosition(stream); - int bytesWritten = __prewrite_buffer(stream, vptr, (int)wrcnt); + int bytesWritten = __prewrite_buffer(stream, p, (int)wrcnt); if (bytesWritten) { TRACE("fwrite: wrote %i bytes to internal buffer", bytesWritten); written += bytesWritten; wrcnt -= bytesWritten; - vptr = (const char*)vptr + bytesWritten; + p += bytesWritten; } // Should we flush? @@ -120,13 +121,13 @@ size_t fwrite(const void* vptr, size_t size, size_t count, FILE* stream) // than what can fit in the buffer space, which means we just fill the buffer // and move on, or we need to write more than can fit. if (__FILE_IsBuffered(stream) && chunkSize < stream->BufferSize) { - bytesWritten = __prewrite_buffer(stream, vptr, chunkSize); + bytesWritten = __prewrite_buffer(stream, p, chunkSize); if (bytesWritten > 0) { stream->Flags |= _IOMOD; } } else { TRACE("fwrite: writing %u bytes directly", chunkSize); - bytesWritten = write(stream->IOD, vptr, chunkSize); + bytesWritten = write(stream->IOD, p, chunkSize); } TRACE("fwrite: wrote %i bytes", bytesWritten); @@ -136,7 +137,7 @@ size_t fwrite(const void* vptr, size_t size, size_t count, FILE* stream) } else if (bytesWritten > 0) { written += bytesWritten; wrcnt -= bytesWritten; - vptr = (const char*)vptr + bytesWritten; + p += bytesWritten; } } funlockfile(stream); diff --git a/librt/libddk/include/ddk/utils.h b/librt/libddk/include/ddk/utils.h index 7b46b458f..f671158e7 100644 --- a/librt/libddk/include/ddk/utils.h +++ b/librt/libddk/include/ddk/utils.h @@ -29,6 +29,7 @@ /* Global definitions * These are enabled no matter which kind of debugging is enabled */ #define STR(str) str +#define NOTICE(...) SystemDebug(OSSYSLOGLEVEL_TRACE, __VA_ARGS__) #define DEBUG(...) SystemDebug(OSSYSLOGLEVEL_DEBUG, __VA_ARGS__) #define WARNING(...) SystemDebug(OSSYSLOGLEVEL_WARNING, __VA_ARGS__) #define WARNING_IF(cond, ...) { if ((cond)) { SystemDebug(OSSYSLOGLEVEL_WARNING, __VA_ARGS__); } } diff --git a/modules/filesystems/mfs/directory_operations.c b/modules/filesystems/mfs/directory_operations.c index e854e4484..bd5c1491b 100644 --- a/modules/filesystems/mfs/directory_operations.c +++ b/modules/filesystems/mfs/directory_operations.c @@ -150,10 +150,7 @@ FsReadFromDirectory( if (position == (entry->BucketByteBoundary + bucketSize)) { TRACE("read_metrics::position %u, limit %u", LODWORD(position), LODWORD(entry->BucketByteBoundary + bucketSize)); - oserr = MFSAdvanceToNextBucket( - mfs, entry, - mfs->SectorsPerBucket * mfs->SectorSize - ); + oserr = MFSAdvanceToNextBucket(mfs, entry); if (oserr != OS_EOK) { if (oserr == OS_ENOENT) { oserr = OS_EOK; diff --git a/modules/filesystems/mfs/file_operations.c b/modules/filesystems/mfs/file_operations.c index aaba22709..cd1d8b772 100644 --- a/modules/filesystems/mfs/file_operations.c +++ b/modules/filesystems/mfs/file_operations.c @@ -169,7 +169,7 @@ FsReadFromFile( // Do we need to switch bucket? // We do if the position we have read to equals end of bucket if (position == (entry->BucketByteBoundary + (entry->DataBucketLength * bucketSizeBytes))) { - oserr = MFSAdvanceToNextBucket(mfs, entry, bucketSizeBytes); + oserr = MFSAdvanceToNextBucket(mfs, entry); if (oserr != OS_EOK) { if (oserr == OS_ENOENT) { oserr = OS_EOK; @@ -226,6 +226,19 @@ FsWriteToFile( // Write in a loop to make sure we write all requested bytes while (bytesToWrite) { + // Determine whether we need to switch bucket as the first step of writing. Do + // this to avoid switching buckets when writing the last byte of a file. There will + // always be enough space to write because of Ensure. + TRACE("FsWriteToFile: position=0x%llx, boundary at 0x%llx", + position, (entry->BucketByteBoundary + (entry->DataBucketLength * bucketSizeBytes))); + if (position == (entry->BucketByteBoundary + (entry->DataBucketLength * bucketSizeBytes))) { + oserr = MFSAdvanceToNextBucket(mfs, entry); + if (oserr != OS_EOK) { + ERROR("FsWriteToFile: failed to get next data bucket: %u", oserr); + break; + } + } + // Calculate which bucket, then the sector offset // Then calculate how many sectors of the bucket we need to read uint64_t bucketSector = MFS_GETSECTOR(mfs, entry->DataBucketPosition); @@ -236,6 +249,8 @@ FsWriteToFile( size_t sectorsWritten; size_t byteCount; + TRACE("FsWriteToFile: position=0x%llx, entry->BucketByteBoundary=0x%llx", + position, entry->BucketByteBoundary); TRACE("FsWriteToFile: bucketSector=0x%llx, sectorIndex=0x%" PRIxIN ", sectorOffset=0x%llx", bucketSector, bucketSectorOffset, sectorIndex); @@ -341,23 +356,12 @@ FsWriteToFile( byteCount = (mfs->SectorSize * sectorsWritten) - bucketSectorOffset; } - TRACE("FsWriteToFile: written 0x%" PRIuIN " bytes", byteCount); + TRACE("FsWriteToFile: written %" PRIuIN " bytes", byteCount); *unitsWritten += byteCount; accumOffset += byteCount; position += byteCount; bytesToWrite -= byteCount; } - - // Do we need to switch bucket? - // We do if the position we have read to equals end of bucket - TRACE("FsWriteToFile: position=0x%llx, boundary at 0x%llx", - position, (entry->BucketByteBoundary + (entry->DataBucketLength * bucketSizeBytes))); - if (position == (entry->BucketByteBoundary + (entry->DataBucketLength * bucketSizeBytes))) { - oserr = MFSAdvanceToNextBucket(mfs, entry, bucketSizeBytes); - if (oserr != OS_EOK) { - break; - } - } } // Store the new position we've calculated during the read operation. diff --git a/modules/filesystems/mfs/mfs.h b/modules/filesystems/mfs/mfs.h index 637ecfa95..faf909116 100644 --- a/modules/filesystems/mfs/mfs.h +++ b/modules/filesystems/mfs/mfs.h @@ -321,14 +321,12 @@ MFSBucketMapSetLinkAndLength( * @brief * @param mfs * @param entry - * @param bucketSizeBytes * @return */ extern oserr_t MFSAdvanceToNextBucket( _In_ FileSystemMFS_t* mfs, - _In_ MFSEntry_t* entry, - _In_ size_t bucketSizeBytes); + _In_ MFSEntry_t* entry); /* MfsZeroBucket * Wipes the given bucket and count with zero values diff --git a/modules/filesystems/mfs/utilities.c b/modules/filesystems/mfs/utilities.c index 8b578c0f5..c5b5da21d 100644 --- a/modules/filesystems/mfs/utilities.c +++ b/modules/filesystems/mfs/utilities.c @@ -179,10 +179,10 @@ MfsEnsureRecordSpace( size_t sectorCount = (size_t)(DIVUP((spaceRequired - entry->AllocatedSize), mfs->SectorSize)); size_t bucketCount = DIVUP(sectorCount, mfs->SectorsPerBucket); uint32_t bucketPointer, previousBucketPointer; - MapRecord_t iterator, link; + MapRecord_t iterator, record; // Perform the allocation of buckets - if (MFSBucketMapAllocate(mfs, bucketCount, &link) != OS_EOK) { + if (MFSBucketMapAllocate(mfs, bucketCount, &record) != OS_EOK) { ERROR("Failed to allocate %u buckets for file", bucketCount); return OS_EDEVFAULT; } @@ -193,7 +193,7 @@ MfsEnsureRecordSpace( while (bucketPointer != MFS_ENDOFCHAIN) { previousBucketPointer = bucketPointer; if (MFSBucketMapGetLengthAndLink(mfs, bucketPointer, &iterator) != OS_EOK) { - ERROR("MfsEnsureRecordSpace failed to get link for bucket %u", bucketPointer); + ERROR("MfsEnsureRecordSpace: failed to get record for bucket %u", bucketPointer); return OS_EDEVFAULT; } bucketPointer = iterator.Link; @@ -201,12 +201,16 @@ MfsEnsureRecordSpace( // We have a special case if previous == MFS_ENDOFCHAIN if (previousBucketPointer == MFS_ENDOFCHAIN) { + TRACE("MfsEnsureRecordSpace: initializing record %ms to start=0x%x, length=0x%x", + entry->Name, record.Link, record.Length); // This means file had nothing allocated - entry->StartBucket = link.Link; - entry->StartLength = link.Length; + entry->StartBucket = record.Link; + entry->StartLength = record.Length; } else { - if (MFSBucketMapSetLinkAndLength(mfs, previousBucketPointer, link.Link, link.Length, true) != OS_EOK) { - ERROR("Failed to set link for bucket %u", previousBucketPointer); + TRACE("MfsEnsureRecordSpace: extending record %ms at bucket=0x%x with link=0x%x, length=0x%x", + entry->Name, previousBucketPointer, record.Link, record.Length); + if (MFSBucketMapSetLinkAndLength(mfs, previousBucketPointer, record.Link, 0, false) != OS_EOK) { + ERROR("Failed to set record for bucket %u", previousBucketPointer); return OS_EDEVFAULT; } } @@ -233,33 +237,40 @@ MFSCloneBucketData( oserr_t MFSAdvanceToNextBucket( _In_ FileSystemMFS_t* mfs, - _In_ MFSEntry_t* entry, - _In_ size_t bucketSizeBytes) + _In_ MFSEntry_t* entry) { - MapRecord_t link; + MapRecord_t record; uint32_t nextDataBucketPosition; + size_t bucketSizeBytes = mfs->SectorsPerBucket * mfs->SectorSize; + size_t currentLinkLength; - // We have to look up the link for current bucket - if (MFSBucketMapGetLengthAndLink(mfs, entry->DataBucketPosition, &link) != OS_EOK) { - ERROR("MFSAdvanceToNextBucket failed to get link for bucket %u", entry->DataBucketPosition); + // We have to look up the record for current bucket + if (MFSBucketMapGetLengthAndLink(mfs, entry->DataBucketPosition, &record) != OS_EOK) { + ERROR("MFSAdvanceToNextBucket failed to get record for bucket %u", entry->DataBucketPosition); return OS_EDEVFAULT; } + TRACE("MFSAdvanceToNextBucket: bucket 0x%x, record=0x%x, length=0x%x", + entry->DataBucketPosition, record.Link, record.Length); // Check for EOL - if (link.Link == MFS_ENDOFCHAIN) { + if (record.Link == MFS_ENDOFCHAIN) { return OS_ENOENT; } - nextDataBucketPosition = link.Link; - // Lookup length of link - if (MFSBucketMapGetLengthAndLink(mfs, entry->DataBucketPosition, &link) != OS_EOK) { + currentLinkLength = (record.Length * bucketSizeBytes); + nextDataBucketPosition = record.Link; + + // Lookup length of record + if (MFSBucketMapGetLengthAndLink(mfs, record.Link, &record) != OS_EOK) { ERROR("Failed to get length for bucket %u", entry->DataBucketPosition); return OS_EDEVFAULT; } + TRACE("MFSAdvanceToNextBucket: bucket 0x%x, record=0x%x, length=0x%x", + nextDataBucketPosition, record.Link, record.Length); // Store length & Update bucket boundary + entry->BucketByteBoundary += currentLinkLength; entry->DataBucketPosition = nextDataBucketPosition; - entry->DataBucketLength = link.Length; - entry->BucketByteBoundary += (link.Length * bucketSizeBytes); + entry->DataBucketLength = record.Length; return OS_EOK; } diff --git a/modules/serial/usb/common/transfer.h b/modules/serial/usb/common/transfer.h index 8f217ae19..5bceebcc2 100644 --- a/modules/serial/usb/common/transfer.h +++ b/modules/serial/usb/common/transfer.h @@ -25,6 +25,10 @@ #include #include +#define __XPAGE(_a) ((_a) & ~((uintptr_t)0xFFF)) +#define __XPAGEOFFSET(_a) ((_a) & 0xFFF) +#define __XUPPAGE(_a) (__XPAGE(_a) + 0x1000) + #define __USBTRANSFER_FLAG_SHORT 0x1 #define __USBTRANSFER_FLAG_NOTIFIED 0x2 #define __USBTRANSFER_FLAG_SILENT 0x4 diff --git a/modules/serial/usb/ohci/structures/itd.c b/modules/serial/usb/ohci/structures/itd.c index 5d78c85bb..fcafac710 100644 --- a/modules/serial/usb/ohci/structures/itd.c +++ b/modules/serial/usb/ohci/structures/itd.c @@ -49,7 +49,7 @@ OHCITDIsochronous( iTd->Flags |= OHCI_TD_ACTIVE; iTd->Cbp = element->Data.OHCI.Page0; - iTd->BufferEnd = element->Data.OHCI.Page1 + element->Data.OHCI.Offsets[frameCount - 1]; + iTd->BufferEnd = element->Data.OHCI.Page1; for (int i = 0; i < frameCount; i++) { iTd->Offsets[i] = element->Data.OHCI.Offsets[i]; iTd->OriginalOffsets[i] = element->Data.OHCI.Offsets[i]; diff --git a/modules/serial/usb/ohci/structures/td.c b/modules/serial/usb/ohci/structures/td.c index 75f5119bc..076e828d6 100644 --- a/modules/serial/usb/ohci/structures/td.c +++ b/modules/serial/usb/ohci/structures/td.c @@ -28,7 +28,7 @@ OHCITDSetup( _In_ OhciTransferDescriptor_t* td, _In_ struct TransferElement* element) { - TRACE("OHCITDSetup(dataAddress=0x%x)", dataAddress); + TRACE("OHCITDSetup(dataAddress=0x%x)", element->Data.OHCI.Page0 + element->Data.OHCI.Offsets[0]); /** * When calling these initializers for TDs, the TDs have already been @@ -60,7 +60,7 @@ OHCITDData( _In_ struct TransferElement* element, _In_ int toggle) { - TRACE("OHCITDData(length=%u)", length); + TRACE("OHCITDData(length=%u)", element->Length); /** * When calling these initializers for TDs, the TDs have already been @@ -160,11 +160,36 @@ OHCITDVerify( // Calculate length transferred // Take into consideration the N-1 if (__Transfer_IsAsync(scanContext->Transfer) && td->BufferEnd != 0) { - int bytesTransferred; - int bytesRequested = (int)(td->BufferEnd - td->OriginalCbp) + 1; - - if (td->Cbp == 0) bytesTransferred = bytesRequested; - else bytesTransferred = (int)(td->Cbp - td->OriginalCbp); + uint32_t bytesTransferred; + uint32_t bytesRequested; + + // Is CBP and BE crossing a page? + if (__XPAGE(td->OriginalCbp) != __XPAGE(td->BufferEnd)) { + uint32_t bytesPage0 = __XUPPAGE(td->OriginalCbp) - td->OriginalCbp; + uint32_t bytesPage1 = __XPAGEOFFSET(td->BufferEnd); + bytesRequested = bytesPage0 + bytesPage1 + 1; + + if (td->Cbp == 0) { + bytesTransferred = bytesRequested; + } else { + // Partial transfer, we need to determine whether Cbp is on the + // page 0 or 1 + if (__XPAGE(td->Cbp) == __XPAGE(td->OriginalCbp)) { + bytesTransferred = td->Cbp - td->OriginalCbp; + } else { + // We still did cross transfer + bytesTransferred = bytesPage0 + __XPAGEOFFSET(td->Cbp); + } + } + } else { + // Otherwise all transfers are done in the same page, much easier. + bytesRequested = (td->BufferEnd - td->OriginalCbp) + 1; + if (td->Cbp == 0) { + bytesTransferred = bytesRequested; + } else { + bytesTransferred = td->Cbp - td->OriginalCbp; + } + } TRACE("OHCITDVerify: td has transferred %i bytes", bytesTransferred); if (bytesTransferred < bytesRequested) { diff --git a/modules/serial/usb/ohci/transfer.c b/modules/serial/usb/ohci/transfer.c index 3e28b910c..383826bb0 100644 --- a/modules/serial/usb/ohci/transfer.c +++ b/modules/serial/usb/ohci/transfer.c @@ -191,7 +191,7 @@ __GetBytesLeft( return sgTable->Entries[index].Length - offset; } -static inline void +static inline oserr_t __CalculateTransferElementMetrics( _In_ enum USBTransferType transferType, _In_ size_t maxPacketSize, @@ -201,54 +201,87 @@ __CalculateTransferElementMetrics( _In_ size_t bytesLeft, _In_ struct TransferElement* element) { - int index; - size_t offset; - TRACE("__CalculateTransferElementMetrics(offset=%u, mps=%u, len=%u)", - sgTableOffset, (uint32_t)maxPacketSize, transferLength); - - // retrieve the initial index and offset into the SG table, based on the - // start offset, and the progress into the transaction. - SHMSGTableOffset( - sgTable, - sgTableOffset + (transferLength - bytesLeft), - &index, - &offset - ); - TRACE("__CalculateTransferElementMetrics: index %i, offset: %u", index, (uint32_t)offset); - uintptr_t address = __GetAddress(sgTable, index, offset); - size_t leftInSG = __GetBytesLeft(sgTable, index, offset); + uintptr_t address = 0; + size_t leftInSG = 0; uint32_t calculatedLength = 0; int transactions = transferType == USBTRANSFER_TYPE_ISOC ? 8 : 1; - TRACE("__CalculateTransferElementMetrics: addr=0x%x, len=%u", - address, MIN(leftInSG, maxPacketSize)); - - // Set the first page of the transfer-element - element->Data.OHCI.Page0 = address & ~((uintptr_t)(0xFFF)); + TRACE("__CalculateTransferElementMetrics(offset=%u, mps=%u, len=%u)", + sgTableOffset, (uint32_t)maxPacketSize, bytesLeft); for (int i = 0; i < transactions; i++) { - uint32_t transactionSize = MIN(maxPacketSize, MIN(bytesLeft, leftInSG)); - element->Data.OHCI.Offsets[0] = address & 0xFFF; + uint32_t transactionSize; + + // update address and leftInSG if no more bytes are left + if (!leftInSG) { + int index; + size_t offset; + oserr_t oserr = SHMSGTableOffset( + sgTable, + sgTableOffset + (transferLength - (bytesLeft - calculatedLength)), + &index, + &offset + ); + if (oserr != OS_EOK) { + // Invalid offset provided. This is weird. We cannot transfer more bytes + ERROR("__CalculateTransferElementMetrics: SG does not contain enough entries for data [0,%u,%u,%u]", + (uint32_t)transferLength, (uint32_t)bytesLeft, (uint32_t)calculatedLength); + return oserr; + } + TRACE("__CalculateTransferElementMetrics: index %i, offset: %u", index, (uint32_t)offset); + address = __GetAddress(sgTable, index, offset); + leftInSG = __GetBytesLeft(sgTable, index, offset); + if (!element->Data.OHCI.Page0) { + // Set the first page of the transfer-element + element->Data.OHCI.Page0 = address & ~((uintptr_t)(0xFFF)); + TRACE("__CalculateTransferElementMetrics: page0: 0x%x", (uint32_t)element->Data.OHCI.Page0); + } + } + + // set the transaction offset, which is just the initial address + element->Data.OHCI.Offsets[i] = address & 0xFFF; // Increase the address to get the next offset - address += transactionSize; + transactionSize = MIN(maxPacketSize, MIN(bytesLeft, leftInSG)); calculatedLength += transactionSize; + address += transactionSize; leftInSG -= transactionSize; - if (!leftInSG) { - // No more data left in the SG entry, move to next - SHMSGTableOffset( + TRACE("__CalculateTransferElementMetrics: xaction[%i] addr=0x%" PRIxIN ", len=0x%x", + i, address, transactionSize); + + // If there were no more bytes left in SG page, and we need to cross to the + // next page, it depends on whether there are more bytes left (bytesLeft > transactionSize) + // and that there is space in the packet (maxPacketSize > transactionSize) + if (!leftInSG && (bytesLeft > transactionSize) && (maxPacketSize > transactionSize)) { + int index; + size_t offset; + uint32_t bytesAlreadyTransacted = transactionSize; + oserr_t oserr = SHMSGTableOffset( sgTable, - sgTableOffset + (transferLength - bytesLeft - calculatedLength), + sgTableOffset + (transferLength - (bytesLeft - calculatedLength)), &index, &offset ); + if (oserr != OS_EOK) { + ERROR("__CalculateTransferElementMetrics: SG does not contain enough entries for data [1,%u,%u,%u,%u]", + (uint32_t)transferLength, (uint32_t)bytesLeft, (uint32_t)calculatedLength, transactionSize); + return oserr; + } address = __GetAddress(sgTable, index, offset); leftInSG = __GetBytesLeft(sgTable, index, offset); + transactionSize = MIN((maxPacketSize - bytesAlreadyTransacted), MIN((bytesLeft - bytesAlreadyTransacted), leftInSG)); + + calculatedLength += transactionSize; + address += transactionSize; + leftInSG -= transactionSize; } } // set the total length including the last buffer page accesses element->Length = calculatedLength; - element->Data.OHCI.Page1 = address & ~((uintptr_t)(0xFFF)); + element->Data.OHCI.Page1 = (address - 1); // must point to the last byte + TRACE("__CalculateTransferElementMetrics: page1: 0x%x", (uint32_t)element->Data.OHCI.Page1); + TRACE("__CalculateTransferElementMetrics: total-len: 0x%x", calculatedLength); + return OS_EOK; } oserr_t @@ -281,7 +314,7 @@ HCITransferElementsNeeded( while (bytesLeft) { struct TransferElement element; - __CalculateTransferElementMetrics( + oserr_t oserr = __CalculateTransferElementMetrics( transfer->Type, transfer->MaxPacketSize, sgTable, @@ -290,6 +323,9 @@ HCITransferElementsNeeded( bytesLeft, &element ); + if (oserr != OS_EOK) { + return oserr; + } bytesLeft -= element.Length; tdsNeeded++; @@ -324,19 +360,21 @@ HCITransferElementFill( // Handle control transfers a bit different due to control transfers needing // some additional packets. if (transfer->Type == USBTRANSFER_TYPE_CONTROL) { - __CalculateTransferElementMetrics( + oserr_t oserr = __CalculateTransferElementMetrics( transfer->Type, transfer->MaxPacketSize, sgTable, sgTableOffset, - transferLength, - bytesLeft, + sizeof(usb_packet_t), + sizeof(usb_packet_t), &transfer->Elements[ei] ); + if (oserr != OS_EOK) { + return; + } - // Override the type and length, as those are fixed for the setup packaet + // Override the typ, as those are fixed for the setup packet transfer->Elements[ei].Type = TRANSFERELEMENT_TYPE_SETUP; - transfer->Elements[ei].Length = sizeof(usb_packet_t); ei++; bytesLeft -= sizeof(usb_packet_t); @@ -348,7 +386,7 @@ HCITransferElementFill( } while (bytesLeft) { - __CalculateTransferElementMetrics( + oserr_t oserr = __CalculateTransferElementMetrics( transfer->Type, transfer->MaxPacketSize, sgTable, @@ -357,6 +395,9 @@ HCITransferElementFill( bytesLeft, &transfer->Elements[ei] ); + if (oserr != OS_EOK) { + return; + } transfer->Elements[ei].Type = __TransferElement_DirectionToType(direction); bytesLeft -= transfer->Elements[ei].Length; ei++; diff --git a/modules/storage/msd/functions.c b/modules/storage/msd/functions.c index 6b4999982..18289bd2b 100644 --- a/modules/storage/msd/functions.c +++ b/modules/storage/msd/functions.c @@ -1,7 +1,5 @@ /** - * MollenOS - * - * Copyright 2017, Philip Meulengracht + * Copyright 2023, Philip Meulengracht * * This program is free software : you can redistribute it and / or modify * it under the terms of the GNU General Public License as published by @@ -167,9 +165,13 @@ __ExecuteCommand( TRACE("__ExecuteCommand(Direction %i, Command 0x%x, Start %u, Length %u)", direction, scsiCommand, LODWORD(sectorStart), dataLength); + if (direction != __STORAGE_OPERATION_READ && direction != __STORAGE_OPERATION_WRITE) { + ERROR("__ExecuteCommand: unsupported direction"); + return OS_EINVALPARAMS; + } // It is invalid to send zero length packets for bulk - if (direction == 1 && dataLength == 0) { + if (direction == __STORAGE_OPERATION_WRITE && dataLength == 0) { ERROR("__ExecuteCommand: cannot write data of length 0 to MSD devices."); return OS_EINVALPARAMS; } @@ -192,7 +194,7 @@ __ExecuteCommand( // Do the data stage (shared for all protocol) while (bytesLeft != 0) { size_t bytesTransferred = 0; - if (direction == 0) { + if (direction == __STORAGE_OPERATION_READ) { oserr = device->Operations->ReadData( device, bufferHandle, @@ -201,7 +203,7 @@ __ExecuteCommand( &transferCode, &bytesTransferred ); - } else { + } else if (direction == __STORAGE_OPERATION_WRITE) { oserr = device->Operations->WriteData( device, bufferHandle, @@ -214,6 +216,7 @@ __ExecuteCommand( if (oserr != OS_EOK) { return oserr; } + TRACE("__ExecuteCommand: bytes-transferred: 0x%llx", bytesTransferred); if (transferCode != USBTRANSFERCODE_SUCCESS && transferCode != USBTRANSFERCODE_STALL) { ERROR("__ExecuteCommand: failed to transfer data, skipping status stage"); @@ -262,7 +265,7 @@ __RequestSenseReady( if (device->Protocol != ProtocolCB && device->Protocol != ProtocolCBI) { oserr = __ExecuteCommand( device, - 0, + __STORAGE_OPERATION_READ, SCSI_TEST_UNIT_READY, 0, 0, @@ -281,7 +284,7 @@ __RequestSenseReady( // Now request the sense-status oserr = __ExecuteCommand( device, - 0, + __STORAGE_OPERATION_READ, SCSI_REQUEST_SENSE, 0, dma_pool_handle(UsbRetrievePool()), @@ -335,7 +338,7 @@ __ReadCapabilities( oserr = __ExecuteCommand( device, - 0, + __STORAGE_OPERATION_READ, SCSI_READ_CAPACITY, 0, dma_pool_handle(UsbRetrievePool()), @@ -356,7 +359,7 @@ __ReadCapabilities( // Perform extended-caps read command oserr = __ExecuteCommand( device, - 0, + __STORAGE_OPERATION_READ, SCSI_READ_CAPACITY_16, 0, dma_pool_handle(UsbRetrievePool()), @@ -413,7 +416,7 @@ MSDDeviceStart( oserr = __ExecuteCommand( device, - 0, + __STORAGE_OPERATION_READ, SCSI_INQUIRY, 0, dma_pool_handle(UsbRetrievePool()), @@ -513,7 +516,7 @@ __TransferSectors( TRACE("__TransferSectors: command %u, max sectors for command %u", command, maxSectorsPerCommand); oserr = __ExecuteCommand( device, - direction == __STORAGE_OPERATION_WRITE, + direction, command, sector, bufferHandle, diff --git a/modules/storage/msd/protocols/bulk.c b/modules/storage/msd/protocols/bulk.c index 14c975ec7..8bc40371b 100644 --- a/modules/storage/msd/protocols/bulk.c +++ b/modules/storage/msd/protocols/bulk.c @@ -19,7 +19,7 @@ * - Bulk Protocol Implementation */ -#define __TRACE +//#define __TRACE #define BULK_RESET 0x1 #define BULK_RESET_IN 0x2 @@ -503,7 +503,6 @@ __ReadData( { enum USBTransferCode transferCode; USBTransfer_t dataStage; - size_t bytesTransferred = 0; oserr_t oserr; TRACE("__ReadData(length=%u)", dataLength); @@ -523,7 +522,7 @@ __ReadData( &device->Device->DeviceContext, &dataStage, &transferCode, - &bytesTransferred + bytesRead ); // Sanitize for any transport errors // The host shall accept the data received. @@ -537,9 +536,7 @@ __ReadData( __ResetRecovery(device, BULK_RESET_ALL); } } - *transferCodeOut = transferCode; - *bytesRead = bytesTransferred; return oserr; } @@ -554,9 +551,8 @@ __WriteData( { enum USBTransferCode transferCode; USBTransfer_t DataStage; - size_t bytesTransferred; oserr_t oserr; - TRACE("__ReadData(length=%u)", dataLength); + TRACE("__WriteData(length=%u)", dataLength); // Perform the data-stage UsbTransferInitialize( @@ -575,7 +571,7 @@ __WriteData( &device->Device->DeviceContext, &DataStage, &transferCode, - &bytesTransferred + bytesWrittenOut ); if (oserr != OS_EOK) { return oserr; @@ -592,9 +588,7 @@ __WriteData( __ResetRecovery(device, BULK_RESET_ALL); } } - *transferCodeOut = transferCode; - *bytesWrittenOut = bytesTransferred; return oserr; } @@ -604,13 +598,13 @@ __GetStatus( _Out_ enum USBTransferCode* transferCodeOut) { enum USBTransferCode transferCode; - USBTransfer_t StatusStage; + USBTransfer_t statusStage; size_t bytesTransferred; oserr_t oserr; TRACE("__GetStatus()"); UsbTransferInitialize( - &StatusStage, + &statusStage, &device->Device->DeviceContext, device->In, USBTRANSFER_TYPE_BULK, @@ -623,7 +617,7 @@ __GetStatus( oserr = UsbTransferQueue( &device->Device->DeviceContext, - &StatusStage, + &statusStage, &transferCode, &bytesTransferred ); diff --git a/services/processd/pe/mapper.c b/services/processd/pe/mapper.c index 2f91010ed..598a3baa6 100644 --- a/services/processd/pe/mapper.c +++ b/services/processd/pe/mapper.c @@ -408,7 +408,7 @@ MapperLoadModule( } // Calculate the image delta for processings - DEBUG("MapperLoadModule(%ms) loaded at 0x%" PRIxIN, path, baseAddress); + NOTICE("MapperLoadModule(%ms) loaded at 0x%" PRIxIN, path, baseAddress); imageDelta = (baseAddress - module->ImageBase); // Run fixup's on the new mappings diff --git a/services/served/server/install.c b/services/served/server/install.c index a73b7e345..498a47b91 100644 --- a/services/served/server/install.c +++ b/services/served/server/install.c @@ -163,7 +163,7 @@ oserr_t InstallApplication(mstring_t* path, const char* basename) struct Application* application; mstring_t* publisher; oserr_t oserr; - TRACE("InstallApplication(path=%ms, basename=%s)", path, basename); + DEBUG("InstallApplication(path=%ms, basename=%s)", path, basename); oserr = __GetPublisher(basename, &publisher); if (oserr != OS_EOK) { @@ -186,7 +186,7 @@ void InstallBundledApplications(void) { struct DIR* setupDir; struct dirent* entry; - TRACE("InstallBundledApplications()"); + DEBUG("InstallBundledApplications()"); setupDir = opendir("/data/setup"); if (setupDir == NULL) { @@ -214,4 +214,5 @@ void InstallBundledApplications(void) if (unlink("/data/setup")) { ERROR("InstallBundledApplications failed to remove /data/setup: %i", errno); } + DEBUG("InstallBundledApplications: bundled applications has been installed"); } diff --git a/tools/setup.bochsrc b/tools/setup.bochsrc index f20f5591d..5fe2d4bd2 100644 --- a/tools/setup.bochsrc +++ b/tools/setup.bochsrc @@ -85,12 +85,12 @@ #display_library: nogui #display_library: rfb #display_library: sdl, options="fullscreen" # startup in fullscreen mode -#display_library: sdl2, options="fullscreen" # startup in fullscreen mode +display_library: sdl2 #display_library: term #display_library: vncsrv #display_library: win32 #display_library: wx -display_library: x +#display_library: x #======================================================================= # CPU: