1#include <asm.h>
2#include <block/sched.h>
3#include <drivers/nvme.h>
4#include <enforce.h>
5#include <mem/alloc.h>
6#include <mem/vmm.h>
7#include <thread/workqueue.h>
8
9#include "drivers/nvme/internal.h"
10
11static void nvme_on_bio_complete(struct nvme_request *req) {
12 struct bio_request *bio = (struct bio_request *) req->user_data;
13
14 bio->done = true;
15
16 /* the NVMe status is already converted to a
17 * bio status before we get here */
18 bio->status = req->status;
19
20 if (bio->on_complete)
21 bio->on_complete(bio);
22
23 vfree(req);
24}
25
26bool nvme_submit_bio_request(struct block_device *disk,
27 struct bio_request *bio) {
28 struct nvme_request *req = vnew(req, ALLOC_ZERO);
29 if (!req)
30 return false;
31
32 req->buffer = bio->buffer;
33 req->done = false;
34 req->lba = bio->lba;
35
36 struct nvme_device *dev = disk->driver_data;
37 req->qid = THIS_QID(dev);
38 req->sector_count = bio->sector_count;
39 req->size = bio->size;
40 req->write = bio->write;
41 req->user_data = bio;
42 list_node_init(n: &req->list_node);
43
44 req->on_complete = nvme_on_bio_complete;
45
46 if (bio->write) {
47 return nvme_write_sector_async_wrapper(disk, req);
48 } else {
49 return nvme_read_sector_async_wrapper(disk, req);
50 }
51}
52