00001
00044 #include <assert.h>
00045 #include <bitops.h>
00046 #include <debug.h>
00047 #include <malloc.h>
00048 #include <status-codes.h>
00049 #include <string.h>
00050 #include <block/device.h>
00051 #include <block/dummy.h>
00052
00053 static void dummy_do_read(struct block_device *bdev, struct block_request *req)
00054 {
00055 struct buffer *buf;
00056 size_t bytes_read = 0;
00057
00058 blk_req_for_each_buffer(req, buf) {
00059 bytes_read += buf->len;
00060 memset(buf->addr.ptr, 0, buf->len);
00061 }
00062
00063 req->bytes_xfered = bytes_read;
00064 req->status = 0;
00065
00066 req->req_done(bdev, req);
00067 free(req);
00068 }
00069
00070 static void dummy_do_write(struct block_device *bdev, struct block_request *req)
00071 {
00072 struct buffer *buf;
00073 size_t bytes_written = 0;
00074
00075 blk_req_for_each_buffer(req, buf)
00076 bytes_written += buf->len;
00077
00078 req->bytes_xfered = bytes_written;
00079 req->status = 0;
00080
00081 req->req_done(bdev, req);
00082 free(req);
00083 }
00084
00085 static void dummy_prepare_req(struct block_device *bdev,
00086 struct block_request *req,
00087 uint32_t lba, uint32_t nr_blocks,
00088 enum block_operation operation)
00089 {
00090 slist_init(&req->buf_list);
00091 req->status = -STATUS_IN_PROGRESS;
00092 req->bytes_xfered = 0;
00093 switch (operation) {
00094 case BLK_OP_READ:
00095 req->req_submit = dummy_do_read;
00096 break;
00097 case BLK_OP_WRITE:
00098 req->req_submit = dummy_do_write;
00099 break;
00100 default:
00101 unhandled_case(operation);
00102 }
00103 }
00104
00105 static struct block_request *dummy_alloc_req(struct block_device *bdev)
00106 {
00107 struct block_request *req;
00108
00109 req = malloc(sizeof(struct block_request));
00110 if (unlikely(!req))
00111 return NULL;
00112 memset(req, 0, sizeof(struct block_request));
00113
00114 return req;
00115 }
00116
00117 static void dummy_free_req(struct block_device *bdev, struct block_request *req)
00118 {
00119 free(req);
00120 }
00121
00122 static uint32_t dummy_get_dev_id(struct block_device *bdev)
00123 {
00124 return 0;
00125 }
00126
00138 struct block_device *dummy_blkdev_init(uint16_t block_size, uint32_t nr_blocks,
00139 bool writeable)
00140 {
00141 struct block_device *bdev;
00142
00143 bdev = malloc(sizeof(struct block_device));
00144 if (!bdev)
00145 return NULL;
00146 memset(bdev, 0, sizeof(struct block_device));
00147
00148 bdev->block_size = block_size;
00149 bdev->nr_blocks = nr_blocks;
00150
00151 if (writeable)
00152 set_bit(BDEV_WRITEABLE, &bdev->flags);
00153 set_bit(BDEV_PRESENT, &bdev->flags);
00154
00155 bdev->prepare_req = dummy_prepare_req;
00156 bdev->alloc_req = dummy_alloc_req;
00157 bdev->free_req = dummy_free_req;
00158 bdev->get_dev_id = dummy_get_dev_id;
00159
00160 return bdev;
00161 }