diff options
author | dzwdz | 2022-09-03 14:56:05 +0200 |
---|---|---|
committer | dzwdz | 2022-09-03 14:56:05 +0200 |
commit | 9889b47b5216bdcd301e2b63baf71683bcbb22af (patch) | |
tree | af8879a53ea7f6d249b4143d31a18e5363853d9f /src/kernel/arch/amd64/driver/util.c | |
parent | 6e4b9831f903e583d58de8b4265159f6d859ebc2 (diff) |
driver/ps2,serial: handle all pending reads at the same time
Diffstat (limited to 'src/kernel/arch/amd64/driver/util.c')
-rw-r--r-- | src/kernel/arch/amd64/driver/util.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/kernel/arch/amd64/driver/util.c b/src/kernel/arch/amd64/driver/util.c index 4eeaa0d..b8895b8 100644 --- a/src/kernel/arch/amd64/driver/util.c +++ b/src/kernel/arch/amd64/driver/util.c @@ -32,3 +32,25 @@ bool postqueue_pop(struct vfs_request **queue, void (*accept)(struct vfs_request accept(req); return true; } + +void postqueue_ringreadall(struct vfs_request **queue, ring_t *r) { + struct vfs_request *req; + char tmp[64]; + size_t mlen = 0; + if (ring_used(r) == 0) return; + + /* read as much as the biggest request wants */ + for (req = *queue; req; req = req->postqueue_next) + mlen = max(mlen, req->output.len); + mlen = min(mlen, sizeof tmp); + mlen = ring_get(r, tmp, mlen); + + for (req = *queue; req; req = req->postqueue_next) { + size_t ret = min(mlen, req->output.len); + assert(req->type == VFSOP_READ); + if (req->caller) + virt_cpy_to(req->caller->pages, req->output.buf, tmp, ret); + vfsreq_finish_short(req, ret); + } + *queue = NULL; +} |