Skip to content

Commit 0b8aa1b

Browse files
committed
usb: fix remaining USB issues for OHCI in terms of cross-page buffers
1 parent 6ec83a5 commit 0b8aa1b

17 files changed

Lines changed: 204 additions & 124 deletions

File tree

librt/libc/io/open.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ __read_large(
206206
TRACE("__read_large: aligning buffer=0x%" PRIxIN ", align=0x%" PRIxIN,
207207
buffer, bytesToAlign);
208208
oserr = __file_read(handle, buffer, bytesToAlign, bytesReadOut);
209-
if (oserr != OS_EOK) {
209+
if (oserr != OS_EOK || *bytesReadOut == 0) {
210210
return oserr;
211211
}
212212
adjustedPointer = (void*)((uintptr_t)buffer + bytesToAlign);
@@ -302,7 +302,7 @@ __write_large(
302302
TRACE("__write_large: aligning buffer=0x%" PRIxIN ", align=0x%" PRIxIN,
303303
buffer, bytesToAlign);
304304
oserr = __file_write(handle, buffer, bytesToAlign, bytesWrittenOut);
305-
if (oserr != OS_EOK) {
305+
if (oserr != OS_EOK|| *bytesWrittenOut == 0) {
306306
return oserr;
307307
}
308308
adjustedPointer = (void*)((uintptr_t)buffer + bytesToAlign);

librt/libc/os/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

18-
#define __TRACE
18+
//#define __TRACE
1919
#define __need_quantity
2020

2121
#include <assert.h>

librt/libc/stdio/fwrite.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ __prewrite_buffer(
5252

5353
size_t fwrite(const void* vptr, size_t size, size_t count, FILE* stream)
5454
{
55-
size_t wrcnt = size * count;
56-
int written = 0;
55+
size_t wrcnt = size * count;
56+
int written = 0;
57+
const char* p = vptr;
5758
TRACE("fwrite(count=%u)", wrcnt);
5859

5960
if (vptr == NULL || stream == NULL) {
@@ -81,12 +82,12 @@ size_t fwrite(const void* vptr, size_t size, size_t count, FILE* stream)
8182
// Fill the buffer before continuing, and flush if neccessary.
8283
if (__FILE_IsBuffered(stream) && __FILE_BufferPosition(stream) > 0) {
8384
int bytesAvailable = stream->BufferSize - __FILE_BufferPosition(stream);
84-
int bytesWritten = __prewrite_buffer(stream, vptr, (int)wrcnt);
85+
int bytesWritten = __prewrite_buffer(stream, p, (int)wrcnt);
8586
if (bytesWritten) {
8687
TRACE("fwrite: wrote %i bytes to internal buffer", bytesWritten);
8788
written += bytesWritten;
8889
wrcnt -= bytesWritten;
89-
vptr = (const char*)vptr + bytesWritten;
90+
p += bytesWritten;
9091
}
9192

9293
// Should we flush?
@@ -120,13 +121,13 @@ size_t fwrite(const void* vptr, size_t size, size_t count, FILE* stream)
120121
// than what can fit in the buffer space, which means we just fill the buffer
121122
// and move on, or we need to write more than can fit.
122123
if (__FILE_IsBuffered(stream) && chunkSize < stream->BufferSize) {
123-
bytesWritten = __prewrite_buffer(stream, vptr, chunkSize);
124+
bytesWritten = __prewrite_buffer(stream, p, chunkSize);
124125
if (bytesWritten > 0) {
125126
stream->Flags |= _IOMOD;
126127
}
127128
} else {
128129
TRACE("fwrite: writing %u bytes directly", chunkSize);
129-
bytesWritten = write(stream->IOD, vptr, chunkSize);
130+
bytesWritten = write(stream->IOD, p, chunkSize);
130131
}
131132
TRACE("fwrite: wrote %i bytes", bytesWritten);
132133

@@ -136,7 +137,7 @@ size_t fwrite(const void* vptr, size_t size, size_t count, FILE* stream)
136137
} else if (bytesWritten > 0) {
137138
written += bytesWritten;
138139
wrcnt -= bytesWritten;
139-
vptr = (const char*)vptr + bytesWritten;
140+
p += bytesWritten;
140141
}
141142
}
142143
funlockfile(stream);

librt/libddk/include/ddk/utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
/* Global <always-on> definitions
3030
* These are enabled no matter which kind of debugging is enabled */
3131
#define STR(str) str
32+
#define NOTICE(...) SystemDebug(OSSYSLOGLEVEL_TRACE, __VA_ARGS__)
3233
#define DEBUG(...) SystemDebug(OSSYSLOGLEVEL_DEBUG, __VA_ARGS__)
3334
#define WARNING(...) SystemDebug(OSSYSLOGLEVEL_WARNING, __VA_ARGS__)
3435
#define WARNING_IF(cond, ...) { if ((cond)) { SystemDebug(OSSYSLOGLEVEL_WARNING, __VA_ARGS__); } }

modules/filesystems/mfs/directory_operations.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,7 @@ FsReadFromDirectory(
150150
if (position == (entry->BucketByteBoundary + bucketSize)) {
151151
TRACE("read_metrics::position %u, limit %u", LODWORD(position),
152152
LODWORD(entry->BucketByteBoundary + bucketSize));
153-
oserr = MFSAdvanceToNextBucket(
154-
mfs, entry,
155-
mfs->SectorsPerBucket * mfs->SectorSize
156-
);
153+
oserr = MFSAdvanceToNextBucket(mfs, entry);
157154
if (oserr != OS_EOK) {
158155
if (oserr == OS_ENOENT) {
159156
oserr = OS_EOK;

modules/filesystems/mfs/file_operations.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ FsReadFromFile(
169169
// Do we need to switch bucket?
170170
// We do if the position we have read to equals end of bucket
171171
if (position == (entry->BucketByteBoundary + (entry->DataBucketLength * bucketSizeBytes))) {
172-
oserr = MFSAdvanceToNextBucket(mfs, entry, bucketSizeBytes);
172+
oserr = MFSAdvanceToNextBucket(mfs, entry);
173173
if (oserr != OS_EOK) {
174174
if (oserr == OS_ENOENT) {
175175
oserr = OS_EOK;
@@ -226,6 +226,19 @@ FsWriteToFile(
226226

227227
// Write in a loop to make sure we write all requested bytes
228228
while (bytesToWrite) {
229+
// Determine whether we need to switch bucket as the first step of writing. Do
230+
// this to avoid switching buckets when writing the last byte of a file. There will
231+
// always be enough space to write because of Ensure.
232+
TRACE("FsWriteToFile: position=0x%llx, boundary at 0x%llx",
233+
position, (entry->BucketByteBoundary + (entry->DataBucketLength * bucketSizeBytes)));
234+
if (position == (entry->BucketByteBoundary + (entry->DataBucketLength * bucketSizeBytes))) {
235+
oserr = MFSAdvanceToNextBucket(mfs, entry);
236+
if (oserr != OS_EOK) {
237+
ERROR("FsWriteToFile: failed to get next data bucket: %u", oserr);
238+
break;
239+
}
240+
}
241+
229242
// Calculate which bucket, then the sector offset
230243
// Then calculate how many sectors of the bucket we need to read
231244
uint64_t bucketSector = MFS_GETSECTOR(mfs, entry->DataBucketPosition);
@@ -236,6 +249,8 @@ FsWriteToFile(
236249
size_t sectorsWritten;
237250
size_t byteCount;
238251

252+
TRACE("FsWriteToFile: position=0x%llx, entry->BucketByteBoundary=0x%llx",
253+
position, entry->BucketByteBoundary);
239254
TRACE("FsWriteToFile: bucketSector=0x%llx, sectorIndex=0x%" PRIxIN ", sectorOffset=0x%llx",
240255
bucketSector, bucketSectorOffset, sectorIndex);
241256

@@ -341,23 +356,12 @@ FsWriteToFile(
341356
byteCount = (mfs->SectorSize * sectorsWritten) - bucketSectorOffset;
342357
}
343358

344-
TRACE("FsWriteToFile: written 0x%" PRIuIN " bytes", byteCount);
359+
TRACE("FsWriteToFile: written %" PRIuIN " bytes", byteCount);
345360
*unitsWritten += byteCount;
346361
accumOffset += byteCount;
347362
position += byteCount;
348363
bytesToWrite -= byteCount;
349364
}
350-
351-
// Do we need to switch bucket?
352-
// We do if the position we have read to equals end of bucket
353-
TRACE("FsWriteToFile: position=0x%llx, boundary at 0x%llx",
354-
position, (entry->BucketByteBoundary + (entry->DataBucketLength * bucketSizeBytes)));
355-
if (position == (entry->BucketByteBoundary + (entry->DataBucketLength * bucketSizeBytes))) {
356-
oserr = MFSAdvanceToNextBucket(mfs, entry, bucketSizeBytes);
357-
if (oserr != OS_EOK) {
358-
break;
359-
}
360-
}
361365
}
362366

363367
// Store the new position we've calculated during the read operation.

modules/filesystems/mfs/mfs.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -321,14 +321,12 @@ MFSBucketMapSetLinkAndLength(
321321
* @brief
322322
* @param mfs
323323
* @param entry
324-
* @param bucketSizeBytes
325324
* @return
326325
*/
327326
extern oserr_t
328327
MFSAdvanceToNextBucket(
329328
_In_ FileSystemMFS_t* mfs,
330-
_In_ MFSEntry_t* entry,
331-
_In_ size_t bucketSizeBytes);
329+
_In_ MFSEntry_t* entry);
332330

333331
/* MfsZeroBucket
334332
* Wipes the given bucket and count with zero values

modules/filesystems/mfs/utilities.c

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,10 @@ MfsEnsureRecordSpace(
179179
size_t sectorCount = (size_t)(DIVUP((spaceRequired - entry->AllocatedSize), mfs->SectorSize));
180180
size_t bucketCount = DIVUP(sectorCount, mfs->SectorsPerBucket);
181181
uint32_t bucketPointer, previousBucketPointer;
182-
MapRecord_t iterator, link;
182+
MapRecord_t iterator, record;
183183

184184
// Perform the allocation of buckets
185-
if (MFSBucketMapAllocate(mfs, bucketCount, &link) != OS_EOK) {
185+
if (MFSBucketMapAllocate(mfs, bucketCount, &record) != OS_EOK) {
186186
ERROR("Failed to allocate %u buckets for file", bucketCount);
187187
return OS_EDEVFAULT;
188188
}
@@ -193,20 +193,24 @@ MfsEnsureRecordSpace(
193193
while (bucketPointer != MFS_ENDOFCHAIN) {
194194
previousBucketPointer = bucketPointer;
195195
if (MFSBucketMapGetLengthAndLink(mfs, bucketPointer, &iterator) != OS_EOK) {
196-
ERROR("MfsEnsureRecordSpace failed to get link for bucket %u", bucketPointer);
196+
ERROR("MfsEnsureRecordSpace: failed to get record for bucket %u", bucketPointer);
197197
return OS_EDEVFAULT;
198198
}
199199
bucketPointer = iterator.Link;
200200
}
201201

202202
// We have a special case if previous == MFS_ENDOFCHAIN
203203
if (previousBucketPointer == MFS_ENDOFCHAIN) {
204+
TRACE("MfsEnsureRecordSpace: initializing record %ms to start=0x%x, length=0x%x",
205+
entry->Name, record.Link, record.Length);
204206
// This means file had nothing allocated
205-
entry->StartBucket = link.Link;
206-
entry->StartLength = link.Length;
207+
entry->StartBucket = record.Link;
208+
entry->StartLength = record.Length;
207209
} else {
208-
if (MFSBucketMapSetLinkAndLength(mfs, previousBucketPointer, link.Link, link.Length, true) != OS_EOK) {
209-
ERROR("Failed to set link for bucket %u", previousBucketPointer);
210+
TRACE("MfsEnsureRecordSpace: extending record %ms at bucket=0x%x with link=0x%x, length=0x%x",
211+
entry->Name, previousBucketPointer, record.Link, record.Length);
212+
if (MFSBucketMapSetLinkAndLength(mfs, previousBucketPointer, record.Link, 0, false) != OS_EOK) {
213+
ERROR("Failed to set record for bucket %u", previousBucketPointer);
210214
return OS_EDEVFAULT;
211215
}
212216
}
@@ -233,33 +237,40 @@ MFSCloneBucketData(
233237
oserr_t
234238
MFSAdvanceToNextBucket(
235239
_In_ FileSystemMFS_t* mfs,
236-
_In_ MFSEntry_t* entry,
237-
_In_ size_t bucketSizeBytes)
240+
_In_ MFSEntry_t* entry)
238241
{
239-
MapRecord_t link;
242+
MapRecord_t record;
240243
uint32_t nextDataBucketPosition;
244+
size_t bucketSizeBytes = mfs->SectorsPerBucket * mfs->SectorSize;
245+
size_t currentLinkLength;
241246

242-
// We have to look up the link for current bucket
243-
if (MFSBucketMapGetLengthAndLink(mfs, entry->DataBucketPosition, &link) != OS_EOK) {
244-
ERROR("MFSAdvanceToNextBucket failed to get link for bucket %u", entry->DataBucketPosition);
247+
// We have to look up the record for current bucket
248+
if (MFSBucketMapGetLengthAndLink(mfs, entry->DataBucketPosition, &record) != OS_EOK) {
249+
ERROR("MFSAdvanceToNextBucket failed to get record for bucket %u", entry->DataBucketPosition);
245250
return OS_EDEVFAULT;
246251
}
252+
TRACE("MFSAdvanceToNextBucket: bucket 0x%x, record=0x%x, length=0x%x",
253+
entry->DataBucketPosition, record.Link, record.Length);
247254

248255
// Check for EOL
249-
if (link.Link == MFS_ENDOFCHAIN) {
256+
if (record.Link == MFS_ENDOFCHAIN) {
250257
return OS_ENOENT;
251258
}
252-
nextDataBucketPosition = link.Link;
253259

254-
// Lookup length of link
255-
if (MFSBucketMapGetLengthAndLink(mfs, entry->DataBucketPosition, &link) != OS_EOK) {
260+
currentLinkLength = (record.Length * bucketSizeBytes);
261+
nextDataBucketPosition = record.Link;
262+
263+
// Lookup length of record
264+
if (MFSBucketMapGetLengthAndLink(mfs, record.Link, &record) != OS_EOK) {
256265
ERROR("Failed to get length for bucket %u", entry->DataBucketPosition);
257266
return OS_EDEVFAULT;
258267
}
268+
TRACE("MFSAdvanceToNextBucket: bucket 0x%x, record=0x%x, length=0x%x",
269+
nextDataBucketPosition, record.Link, record.Length);
259270

260271
// Store length & Update bucket boundary
272+
entry->BucketByteBoundary += currentLinkLength;
261273
entry->DataBucketPosition = nextDataBucketPosition;
262-
entry->DataBucketLength = link.Length;
263-
entry->BucketByteBoundary += (link.Length * bucketSizeBytes);
274+
entry->DataBucketLength = record.Length;
264275
return OS_EOK;
265276
}

modules/serial/usb/common/transfer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
#include <os/spinlock.h>
2626
#include <threads.h>
2727

28+
#define __XPAGE(_a) ((_a) & ~((uintptr_t)0xFFF))
29+
#define __XPAGEOFFSET(_a) ((_a) & 0xFFF)
30+
#define __XUPPAGE(_a) (__XPAGE(_a) + 0x1000)
31+
2832
#define __USBTRANSFER_FLAG_SHORT 0x1
2933
#define __USBTRANSFER_FLAG_NOTIFIED 0x2
3034
#define __USBTRANSFER_FLAG_SILENT 0x4

modules/serial/usb/ohci/structures/itd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ OHCITDIsochronous(
4949
iTd->Flags |= OHCI_TD_ACTIVE;
5050

5151
iTd->Cbp = element->Data.OHCI.Page0;
52-
iTd->BufferEnd = element->Data.OHCI.Page1 + element->Data.OHCI.Offsets[frameCount - 1];
52+
iTd->BufferEnd = element->Data.OHCI.Page1;
5353
for (int i = 0; i < frameCount; i++) {
5454
iTd->Offsets[i] = element->Data.OHCI.Offsets[i];
5555
iTd->OriginalOffsets[i] = element->Data.OHCI.Offsets[i];

0 commit comments

Comments
 (0)