diff options
Diffstat (limited to 'src/kernel/blk_drv/blk.h')
-rw-r--r-- | src/kernel/blk_drv/blk.h | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/src/kernel/blk_drv/blk.h b/src/kernel/blk_drv/blk.h new file mode 100644 index 0000000..b272173 --- /dev/null +++ b/src/kernel/blk_drv/blk.h | |||
@@ -0,0 +1,140 @@ | |||
1 | #ifndef _BLK_H | ||
2 | #define _BLK_H | ||
3 | |||
4 | #define NR_BLK_DEV 7 | ||
5 | /* | ||
6 | * NR_REQUEST is the number of entries in the request-queue. | ||
7 | * NOTE that writes may use only the low 2/3 of these: reads | ||
8 | * take precedence. | ||
9 | * | ||
10 | * 32 seems to be a reasonable number: enough to get some benefit | ||
11 | * from the elevator-mechanism, but not so much as to lock a lot of | ||
12 | * buffers when they are in the queue. 64 seems to be too many (easily | ||
13 | * long pauses in reading when heavy writing/syncing is going on) | ||
14 | */ | ||
15 | #define NR_REQUEST 32 | ||
16 | |||
17 | /* | ||
18 | * Ok, this is an expanded form so that we can use the same | ||
19 | * request for paging requests when that is implemented. In | ||
20 | * paging, 'bh' is NULL, and 'waiting' is used to wait for | ||
21 | * read/write completion. | ||
22 | */ | ||
23 | struct request { | ||
24 | int dev; /* -1 if no request */ | ||
25 | int cmd; /* READ or WRITE */ | ||
26 | int errors; | ||
27 | unsigned long sector; | ||
28 | unsigned long nr_sectors; | ||
29 | char * buffer; | ||
30 | struct task_struct * waiting; | ||
31 | struct buffer_head * bh; | ||
32 | struct request * next; | ||
33 | }; | ||
34 | |||
35 | /* | ||
36 | * This is used in the elevator algorithm: Note that | ||
37 | * reads always go before writes. This is natural: reads | ||
38 | * are much more time-critical than writes. | ||
39 | */ | ||
40 | #define IN_ORDER(s1,s2) \ | ||
41 | ((s1)->cmd<(s2)->cmd || ((s1)->cmd==(s2)->cmd && \ | ||
42 | ((s1)->dev < (s2)->dev || ((s1)->dev == (s2)->dev && \ | ||
43 | (s1)->sector < (s2)->sector)))) | ||
44 | |||
45 | struct blk_dev_struct { | ||
46 | void (*request_fn)(void); | ||
47 | struct request * current_request; | ||
48 | }; | ||
49 | |||
50 | extern struct blk_dev_struct blk_dev[NR_BLK_DEV]; | ||
51 | extern struct request request[NR_REQUEST]; | ||
52 | extern struct task_struct * wait_for_request; | ||
53 | |||
54 | #ifdef MAJOR_NR | ||
55 | |||
56 | /* | ||
57 | * Add entries as needed. Currently the only block devices | ||
58 | * supported are hard-disks and floppies. | ||
59 | */ | ||
60 | |||
61 | #if (MAJOR_NR == 1) | ||
62 | /* ram disk */ | ||
63 | #define DEVICE_NAME "ramdisk" | ||
64 | #define DEVICE_REQUEST do_rd_request | ||
65 | #define DEVICE_NR(device) ((device) & 7) | ||
66 | #define DEVICE_ON(device) | ||
67 | #define DEVICE_OFF(device) | ||
68 | |||
69 | #elif (MAJOR_NR == 2) | ||
70 | /* floppy */ | ||
71 | #define DEVICE_NAME "floppy" | ||
72 | #define DEVICE_INTR do_floppy | ||
73 | #define DEVICE_REQUEST do_fd_request | ||
74 | #define DEVICE_NR(device) ((device) & 3) | ||
75 | #define DEVICE_ON(device) floppy_on(DEVICE_NR(device)) | ||
76 | #define DEVICE_OFF(device) floppy_off(DEVICE_NR(device)) | ||
77 | |||
78 | #elif (MAJOR_NR == 3) | ||
79 | /* harddisk */ | ||
80 | #define DEVICE_NAME "harddisk" | ||
81 | #define DEVICE_INTR do_hd | ||
82 | #define DEVICE_REQUEST do_hd_request | ||
83 | #define DEVICE_NR(device) (MINOR(device)/5) | ||
84 | #define DEVICE_ON(device) | ||
85 | #define DEVICE_OFF(device) | ||
86 | |||
87 | #else | ||
88 | /* unknown blk device */ | ||
89 | #error "unknown blk device" | ||
90 | |||
91 | #endif | ||
92 | |||
93 | #define CURRENT (blk_dev[MAJOR_NR].current_request) | ||
94 | #define CURRENT_DEV DEVICE_NR(CURRENT->dev) | ||
95 | |||
96 | #ifdef DEVICE_INTR | ||
97 | void (*DEVICE_INTR)(void) = NULL; | ||
98 | #endif | ||
99 | static void (DEVICE_REQUEST)(void); | ||
100 | |||
101 | static inline void unlock_buffer(struct buffer_head * bh) | ||
102 | { | ||
103 | if (!bh->b_lock) | ||
104 | printk(DEVICE_NAME ": free buffer being unlocked\n"); | ||
105 | bh->b_lock=0; | ||
106 | wake_up(&bh->b_wait); | ||
107 | } | ||
108 | |||
109 | static inline void end_request(int uptodate) | ||
110 | { | ||
111 | DEVICE_OFF(CURRENT->dev); | ||
112 | if (CURRENT->bh) { | ||
113 | CURRENT->bh->b_uptodate = uptodate; | ||
114 | unlock_buffer(CURRENT->bh); | ||
115 | } | ||
116 | if (!uptodate) { | ||
117 | printk(DEVICE_NAME " I/O error\n\r"); | ||
118 | printk("dev %04x, block %d\n\r",CURRENT->dev, | ||
119 | CURRENT->bh->b_blocknr); | ||
120 | } | ||
121 | wake_up(&CURRENT->waiting); | ||
122 | wake_up(&wait_for_request); | ||
123 | CURRENT->dev = -1; | ||
124 | CURRENT = CURRENT->next; | ||
125 | } | ||
126 | |||
127 | #define INIT_REQUEST \ | ||
128 | repeat: \ | ||
129 | if (!CURRENT) \ | ||
130 | return; \ | ||
131 | if (MAJOR(CURRENT->dev) != MAJOR_NR) \ | ||
132 | panic(DEVICE_NAME ": request list destroyed"); \ | ||
133 | if (CURRENT->bh) { \ | ||
134 | if (!CURRENT->bh->b_lock) \ | ||
135 | panic(DEVICE_NAME ": block not locked"); \ | ||
136 | } | ||
137 | |||
138 | #endif | ||
139 | |||
140 | #endif | ||