00001
00041 #ifndef BLOCK_DEVICE_H_INCLUDED
00042 #define BLOCK_DEVICE_H_INCLUDED
00043
00044 #include <buffer.h>
00045 #include <slist.h>
00046 #include <types.h>
00047
00051 typedef uint32_t block_addr_t;
00052
00056 typedef uint32_t block_len_t;
00057
00058 struct block_device;
00059
00069 struct block_request {
00071 struct slist buf_list;
00072 void (*req_started)(struct block_device *bdev,
00073 struct block_request *req);
00081 void (*req_done)(struct block_device *bdev, struct block_request *req);
00082 void (*buf_list_done)(struct block_device *bdev,
00083 struct block_request *req, struct slist *buf_list);
00084 void (*req_submit)(struct block_device *bdev,
00085 struct block_request *req);
00086 int (*req_submit_buf_list)(struct block_device *bdev,
00087 struct block_request *req, struct slist *buf_list);
00088 void (*req_abort)(struct block_device *bdev,
00089 struct block_request *req);
00094 void *context;
00105 int status;
00106 size_t bytes_xfered;
00108 struct block_device *bdev;
00109 };
00110
00114 enum block_device_flag {
00115 BDEV_UNIT_ATTENTION,
00116 BDEV_PRESENT,
00117 BDEV_WRITEABLE,
00118 };
00119
00123 enum block_operation {
00124 BLK_OP_READ,
00125 BLK_OP_WRITE,
00126 };
00127
00134 struct block_device {
00136 uint16_t block_size;
00138 uint32_t nr_blocks;
00140 unsigned long flags;
00142 void (*prepare_req)(struct block_device *bdev,
00143 struct block_request *req,
00144 block_addr_t lba, uint32_t nr_blocks,
00145 enum block_operation operation);
00147 struct block_request *(*alloc_req)(struct block_device *bdev);
00149 void (*free_req)(struct block_device *bdev, struct block_request *req);
00151 uint32_t (*get_dev_id)(struct block_device *bdev);
00152 };
00153
00154 extern struct block_request *block_alloc_request(struct block_device *bdev);
00155 extern void block_free_request(struct block_device *bdev,
00156 struct block_request *req);
00157
00174 static inline void block_prepare_req(struct block_device *bdev,
00175 struct block_request *req, block_addr_t lba,
00176 uint32_t nr_blocks, enum block_operation operation)
00177 {
00178 assert(bdev == req->bdev);
00179
00180 bdev->prepare_req(bdev, req, lba, nr_blocks, operation);
00181 }
00182
00192 static inline void block_submit_req(struct block_device *bdev,
00193 struct block_request *req)
00194 {
00195 assert(bdev == req->bdev);
00196
00197 req->req_submit(bdev, req);
00198 }
00199
00200 static inline void block_queue_req(struct block_device *bdev,
00201 struct block_request *req, block_addr_t lba,
00202 uint32_t nr_blocks, enum block_operation operation)
00203 {
00204 block_prepare_req(bdev, req, lba, nr_blocks, operation);
00205 block_submit_req(bdev, req);
00206 }
00207
00208 static inline void block_abort_req(struct block_device *bdev,
00209 struct block_request *req)
00210 {
00211
00212 }
00213
00214 static inline uint32_t block_get_dev_id(struct block_device *bdev)
00215 {
00216 assert(bdev);
00217 assert(bdev->get_dev_id);
00218
00219 return bdev->get_dev_id(bdev);
00220 }
00221
00239 static inline int block_submit_buf_list(struct block_device *bdev,
00240 struct block_request *breq, struct slist *buf_list)
00241 {
00242 assert(breq->bdev == bdev);
00243 assert(breq->req_submit_buf_list);
00244
00245 return breq->req_submit_buf_list(bdev, breq, buf_list);
00246 }
00247
00260 static inline block_len_t blk_req_get_blocks_xfered(struct block_device *bdev,
00261 struct block_request *breq)
00262 {
00263 assert(bdev == breq->bdev);
00264
00265 return breq->bytes_xfered / bdev->block_size;
00266 }
00267
00280 static inline size_t blk_req_get_bytes_xfered(struct block_device *bdev,
00281 struct block_request *breq)
00282 {
00283 assert(bdev == breq->bdev);
00284
00285 return breq->bytes_xfered;
00286 }
00287
00292 #define blk_req_for_each_buffer(req, buf) \
00293 slist_for_each(&req->buf_list, buf, node)
00294
00299 #define blk_req_for_each_buffer_safe(req, buf, next) \
00300 slist_for_each_safe(&req->buf_list, buf, next, node)
00301
00305 static inline void blk_req_add_buffer(struct block_request *req,
00306 struct buffer *buf)
00307 {
00308 slist_insert_tail(&req->buf_list, &buf->node);
00309 }
00310
00317 static inline void blk_req_add_buffer_list(struct block_request *req,
00318 struct slist *list)
00319 {
00320 slist_move_to_tail(&req->buf_list, list);
00321 }
00322
00326 static inline void blk_req_free_all_buffers(struct block_request *req)
00327 {
00328 struct buffer *buf;
00329 struct buffer *next;
00330
00331 blk_req_for_each_buffer_safe(req, buf, next)
00332 buffer_free(buf);
00333 }
00334
00335 #endif