summaryrefslogtreecommitdiff
path: root/src/kernel/arch/amd64/driver/util.c
diff options
context:
space:
mode:
authordzwdz2022-09-03 14:56:05 +0200
committerdzwdz2022-09-03 14:56:05 +0200
commit9889b47b5216bdcd301e2b63baf71683bcbb22af (patch)
treeaf8879a53ea7f6d249b4143d31a18e5363853d9f /src/kernel/arch/amd64/driver/util.c
parent6e4b9831f903e583d58de8b4265159f6d859ebc2 (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.c22
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;
+}