1 #include <lunaix/blkio.h>
2 #include <lunaix/mm/cake.h>
3 #include <lunaix/mm/valloc.h>
5 static struct cake_pile* blkio_reqpile;
10 blkio_reqpile = cake_new_pile("blkio_req", sizeof(struct blkio_req), 1, 0);
13 static inline struct blkio_req*
14 __blkio_req_create(struct vecbuf* buffer,
20 options = options & ~0xf;
21 struct blkio_req* breq = (struct blkio_req*)cake_grab(blkio_reqpile);
22 *breq = (struct blkio_req){ .blk_addr = start_lba,
23 .completed = completed,
25 .evt_args = evt_args };
27 waitq_init(&breq->wait);
32 blkio_vrd(struct vecbuf* buffer,
38 return __blkio_req_create(buffer, start_lba, completed, evt_args, options);
42 blkio_vwr(struct vecbuf* buffer,
48 struct blkio_req* breq =
49 __blkio_req_create(buffer, start_lba, completed, evt_args, options);
50 breq->flags |= BLKIO_WRITE;
55 blkio_free_req(struct blkio_req* req)
57 cake_release(blkio_reqpile, (void*)req);
61 blkio_newctx(req_handler handler)
63 struct blkio_context* ctx =
64 (struct blkio_context*)vzalloc(sizeof(struct blkio_context));
65 ctx->handle_one = handler;
67 llist_init_head(&ctx->queue);
73 blkio_commit(struct blkio_context* ctx, struct blkio_req* req)
75 req->flags |= BLKIO_PENDING;
77 llist_append(&ctx->queue, &req->reqs);
79 // if the pipeline is not running (e.g., stalling). Then we should schedule
80 // one immediately and kick it started.
87 blkio_schedule(struct blkio_context* ctx)
89 if (llist_empty(&ctx->queue)) {
93 struct blkio_req* head = (struct blkio_req*)ctx->queue.next;
94 llist_delete(&head->reqs);
96 head->flags |= BLKIO_BUSY;
99 ctx->handle_one(head);
103 blkio_complete(struct blkio_req* req)
105 req->flags &= ~(BLKIO_BUSY | BLKIO_PENDING);
107 if (req->completed) {
111 // FIXME Not working in first process! Need a dummy process.
112 // Wake all blocked processes on completion,
113 // albeit should be no more than one process in everycase (by design)
114 pwake_all(&req->wait);
116 if ((req->flags & BLKIO_FOC)) {
122 blkio_schedule(req->io_ctx);