1#include <asm.h>
2#include <block/sched.h>
3#include <drivers/nvme.h>
4#include <kassert.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 kfree(req);
24}
25
26bool nvme_submit_bio_request(struct block_device *disk,
27 struct bio_request *bio) {
28 struct nvme_request *req =
29 kmalloc(sizeof(struct nvme_request), ALLOC_FLAGS_ZERO);
30 if (!req)
31 return false;
32
33 req->buffer = bio->buffer;
34 req->done = false;
35 req->lba = bio->lba;
36
37 struct nvme_device *dev = disk->driver_data;
38 req->qid = THIS_QID(dev);
39 req->sector_count = bio->sector_count;
40 req->size = bio->size;
41 req->write = bio->write;
42 req->user_data = bio;
43 INIT_LIST_HEAD(list: &req->list_node);
44
45 req->on_complete = nvme_on_bio_complete;
46
47 if (bio->write) {
48 return nvme_write_sector_async_wrapper(disk, req);
49 } else {
50 return nvme_read_sector_async_wrapper(disk, req);
51 }
52}
53