BNX2X: Spatch dev_addr->ea
[akaros.git] / kern / include / blockdev.h
1 /* Copyright (c) 2010 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Block device interfaces and structures */
6
7 #ifndef ROS_KERN_BLOCKDEV_H
8 #define ROS_KERN_BLOCKDEV_H
9
10 #include <ros/common.h>
11 #include <kref.h>
12 #include <slab.h>
13 #include <pagemap.h>
14 #include <kthread.h>
15
16 /* All block IO is done assuming a certain size sector, which is the smallest
17  * possible unit of transfer between the kernel and the block layer.  This can
18  * be bigger than what the underlying hardware can handle, but it shouldn't be
19  * smaller than any higher-level block (like an FS block, which are often 1 KB).
20  */
21 #define SECTOR_SZ_LOG 9
22 #define SECTOR_SZ (1 << SECTOR_SZ_LOG)
23
24 /* Every block device is represented by one of these, with custom methods, as
25  * applicable for the type of device.  Subject to massive changes. */
26 #define BDEV_INLINE_NAME 10
27 struct block_device {
28         int                                                     b_id;
29         unsigned int                            b_sector_sz;            /* HW sector size */
30         unsigned long                           b_nr_sector;            /* Total sectors on dev */
31         struct kref                                     b_kref;
32         struct page_map                         b_pm;
33         void                                            *b_data;                        /* dev-specific use */
34         char                                            b_name[BDEV_INLINE_NAME];
35         // TODO: list or something of buffer heads (?)
36         // list of outstanding requests
37         // io scheduler
38         // callbacks for completion
39 };
40
41 /* So far, only NEEDS_ZEROED is used */
42 #define BH_LOCKED               0x001   /* involved in an IO op */
43 #define BH_UPTODATE             0x002   /* buffer is filled with file data */
44 #define BH_DIRTY                0x004   /* buffer is dirty */
45 #define BH_NEEDS_ZEROED 0x008   /* buffer should be 0'd, not read in */
46
47 /* This maps to and from a buffer within a page to a block(s) on a bdev.  Some
48  * of it might not be needed later, etc (page, numblock). */
49 struct buffer_head {
50         struct page                                     *bh_page;                       /* redundant with buffer */
51         void                                            *bh_buffer;
52         unsigned int                            bh_flags;
53         struct buffer_head                      *bh_next;                       /* circular LL of BHs */
54         struct block_device                     *bh_bdev;
55         unsigned long                           bh_sector;
56         unsigned int                            bh_nr_sector;           /* length (in sectors) */
57 };
58 struct kmem_cache *bh_kcache;
59
60 /* Buffer Head Requests.  For now, just use these for dealing with non-file IO
61  * on a block device.  Tell it what size you think blocks are. */
62 struct buffer_head *bdev_get_buffer(struct block_device *bdev,
63                                     unsigned long blk_num, unsigned int blk_sz);
64 void bdev_dirty_buffer(struct buffer_head *bh);
65 void bdev_put_buffer(struct buffer_head *bh);
66
67 /* This encapsulates the work of a request (instead of having a variety of
68  * slightly-different functions for things like read/write and scatter-gather
69  * ops).  Reads and writes are essentially the same, so all we need is a flag to
70  * differentiate.  This struct also serves as a tool to track the progress of a
71  * block request throughout its servicing.  This is analagous to Linux's struct
72  * bio.
73  *
74  * bhs normally points to the inline version (enough for a page).  kmalloc
75  * another array of BH pointers if you want more.  The BHs do not need to be
76  * linked or otherwise associated with a page mapping. */
77 #define NR_INLINE_BH (PGSIZE >> SECTOR_SZ_LOG)
78 struct block_request;
79 struct block_request {
80         unsigned int                            flags;
81         void                                            (*callback)(struct block_request *breq);
82         void                                            *data;
83         struct semaphore                        sem;
84         struct buffer_head                      **bhs;                          /* BHs describing the IOs */
85         unsigned int                            nr_bhs;
86         struct buffer_head                      *local_bhs[NR_INLINE_BH];
87 };
88 struct kmem_cache *breq_kcache; /* for the block requests */
89
90 /* Block request flags */
91 #define BREQ_READ                       0x001
92 #define BREQ_WRITE                      0x002
93
94 void block_init(void);
95 struct block_device *get_bdev(char *path);
96 void free_bhs(struct page *page);
97 int bdev_submit_request(struct block_device *bdev, struct block_request *breq);
98 void generic_breq_done(struct block_request *breq);
99 void sleep_on_breq(struct block_request *breq);
100
101 #endif /* ROS_KERN_BLOCKDEV_H */