summaryrefslogtreecommitdiffstats
path: root/src/kernel/blk_drv/blk.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/blk_drv/blk.h')
-rw-r--r--src/kernel/blk_drv/blk.h140
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 */
23struct 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
45struct blk_dev_struct {
46 void (*request_fn)(void);
47 struct request * current_request;
48};
49
50extern struct blk_dev_struct blk_dev[NR_BLK_DEV];
51extern struct request request[NR_REQUEST];
52extern 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
97void (*DEVICE_INTR)(void) = NULL;
98#endif
99static void (DEVICE_REQUEST)(void);
100
101static 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
109static 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 \
128repeat: \
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