⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blk.h.txt

📁 Linux块设备驱动分析与模拟实现
💻 TXT
字号:
  1 #ifndef _BLK_H
  2 #define _BLK_H
  3 
  4 #include <linux/major.h>
  5 #include <linux/sched.h>
  6 #include <linux/locks.h>
  7 #include <linux/genhd.h>
  8 
  9 /*
 10  * NR_REQUEST is the number of entries in the request-queue.
 11  * NOTE that writes may use only the low 2/3 of these: reads
 12  * take precedence.
 13  *
 14  * 32 seems to be a reasonable number: enough to get some benefit
 15  * from the elevator-mechanism, but not so much as to lock a lot of
 16  * buffers when they are in the queue. 64 seems to be too many (easily
 17  * long pauses in reading when heavy writing/syncing is going on)
 18  */
 19 #define NR_REQUEST      64
 20 
 21 /*
 22  * Ok, this is an expanded form so that we can use the same
 23  * request for paging requests when that is implemented. In
 24  * paging, 'bh' is NULL, and 'waiting' is used to wait for
 25  * read/write completion.
 26  */
 27 struct request {
 28         int dev;                /* -1 if no request */
 29         int cmd;                /* READ or WRITE */
 30         int errors;
 31         unsigned long sector;
 32         unsigned long nr_sectors;
 33         unsigned long current_nr_sectors;
 34         char * buffer;
 35         struct task_struct * waiting;
 36         struct buffer_head * bh;
 37         struct buffer_head * bhtail;
 38         struct request * next;
 39 };
 40 
 41 /*
 42  * This is used in the elevator algorithm: Note that
 43  * reads always go before writes. This is natural: reads
 44  * are much more time-critical than writes.
 45  */
 46 #define IN_ORDER(s1,s2) \
 47 ((s1)->cmd < (s2)->cmd || ((s1)->cmd == (s2)->cmd && \
 48 ((s1)->dev < (s2)->dev || (((s1)->dev == (s2)->dev && \
 49 (s1)->sector < (s2)->sector)))))
 50 
 51 struct blk_dev_struct {
 52         void (*request_fn)(void);
 53         struct request * current_request;
 54 };
 55 
 56 
 57 struct sec_size {
 58         unsigned block_size;
 59         unsigned block_size_bits;
 60 };
 61 
 62 /*
 63  * These will have to be changed to be aware of different buffer
 64  * sizes etc.. It actually needs a major cleanup.
 65  */
 66 #define SECTOR_MASK (blksize_size[MAJOR_NR] &&     \
 67         blksize_size[MAJOR_NR][MINOR(CURRENT->dev)] ? \
 68         ((blksize_size[MAJOR_NR][MINOR(CURRENT->dev)] >> 9) - 1) :  \
 69         ((BLOCK_SIZE >> 9)  -  1))
 70 
 71 #define SUBSECTOR(block) (CURRENT->current_nr_sectors > 0)
 72 
 73 extern struct sec_size * blk_sec[MAX_BLKDEV];
 74 extern struct blk_dev_struct blk_dev[MAX_BLKDEV];
 75 extern struct wait_queue * wait_for_request;
 76 extern void resetup_one_dev(struct gendisk *dev, int drive);
 77 
 78 extern int * blk_size[MAX_BLKDEV];
 79 
 80 extern int * blksize_size[MAX_BLKDEV];
 81 
 82 extern unsigned long hd_init(unsigned long mem_start, unsigned long mem_end);
 83 extern unsigned long cdu31a_init(unsigned long mem_start, unsigned long mem_end);
 84 extern unsigned long mcd_init(unsigned long mem_start, unsigned long mem_end);
 85 extern int is_read_only(int dev);
 86 extern void set_device_ro(int dev,int flag);
 87 
 88 extern void rd_load(void);
 89 extern long rd_init(long mem_start, int length);
 90 extern int ramdisk_size;
 91 
 92 extern unsigned long xd_init(unsigned long mem_start, unsigned long mem_end);
 93 
 94 #define RO_IOCTLS(dev,where) \
 95   case BLKROSET: if (!suser()) return -EPERM; \
 96                  set_device_ro((dev),get_fs_long((long *) (where))); return 0; \
 97   case BLKROGET: { int __err = verify_area(VERIFY_WRITE, (void *) (where), sizeof(long)); \
 98                    if (!__err) put_fs_long(is_read_only(dev),(long *) (where)); return __err; }
 99                  
100 #ifdef MAJOR_NR
101 
102 /*
103  * Add entries as needed. Currently the only block devices
104  * supported are hard-disks and floppies.
105  */
106 
107 #if (MAJOR_NR == MEM_MAJOR)
108 
109 /* ram disk */
110 #define DEVICE_NAME "ramdisk"
111 #define DEVICE_REQUEST do_rd_request
112 #define DEVICE_NR(device) ((device) & 7)
113 #define DEVICE_ON(device) 
114 #define DEVICE_OFF(device)
115 
116 #elif (MAJOR_NR == FLOPPY_MAJOR)
117 
118 static void floppy_on(unsigned int nr);
119 static void floppy_off(unsigned int nr);
120 
121 #define DEVICE_NAME "floppy"
122 #define DEVICE_INTR do_floppy
123 #define DEVICE_REQUEST do_fd_request
124 #define DEVICE_NR(device) ((device) & 3)
125 #define DEVICE_ON(device) floppy_on(DEVICE_NR(device))
126 #define DEVICE_OFF(device) floppy_off(DEVICE_NR(device))
127 
128 #elif (MAJOR_NR == HD_MAJOR)
129 
130 /* harddisk: timeout is 6 seconds.. */
131 #define DEVICE_NAME "harddisk"
132 #define DEVICE_INTR do_hd
133 #define DEVICE_TIMEOUT HD_TIMER
134 #define TIMEOUT_VALUE 600
135 #define DEVICE_REQUEST do_hd_request
136 #define DEVICE_NR(device) (MINOR(device)>>6)
137 #define DEVICE_ON(device)
138 #define DEVICE_OFF(device)
139 
140 #elif (MAJOR_NR == SCSI_DISK_MAJOR)
141 
142 #define DEVICE_NAME "scsidisk"
143 #define DEVICE_INTR do_sd  
144 #define TIMEOUT_VALUE 200
145 #define DEVICE_REQUEST do_sd_request
146 #define DEVICE_NR(device) (MINOR(device) >> 4)
147 #define DEVICE_ON(device)
148 #define DEVICE_OFF(device)
149 
150 #elif (MAJOR_NR == SCSI_TAPE_MAJOR)
151 
152 #define DEVICE_NAME "scsitape"
153 #define DEVICE_INTR do_st  
154 #define DEVICE_NR(device) (MINOR(device))
155 #define DEVICE_ON(device)
156 #define DEVICE_OFF(device)
157 
158 #elif (MAJOR_NR == SCSI_CDROM_MAJOR)
159 
160 #define DEVICE_NAME "CD-ROM"
161 #define DEVICE_INTR do_sr
162 #define DEVICE_REQUEST do_sr_request
163 #define DEVICE_NR(device) (MINOR(device))
164 #define DEVICE_ON(device)
165 #define DEVICE_OFF(device)
166 
167 #elif (MAJOR_NR == XT_DISK_MAJOR)
168 
169 #define DEVICE_NAME "xt disk"
170 #define DEVICE_REQUEST do_xd_request
171 #define DEVICE_NR(device) (MINOR(device) >> 6)
172 #define DEVICE_ON(device)
173 #define DEVICE_OFF(device)
174 
175 #elif (MAJOR_NR == CDU31A_CDROM_MAJOR)
176 
177 #define DEVICE_NAME "CDU31A"
178 #define DEVICE_REQUEST do_cdu31a_request
179 #define DEVICE_NR(device) (MINOR(device))
180 #define DEVICE_ON(device)
181 #define DEVICE_OFF(device)
182 
183 #elif (MAJOR_NR == MITSUMI_CDROM_MAJOR)
184 
185 #define DEVICE_NAME "Mitsumi CD-ROM"
186 /* #define DEVICE_INTR do_mcd */
187 #define DEVICE_REQUEST do_mcd_request
188 #define DEVICE_NR(device) (MINOR(device))
189 #define DEVICE_ON(device)
190 #define DEVICE_OFF(device)
191 
192 #elif (MAJOR_NR == MATSUSHITA_CDROM_MAJOR)
193 
194 #define DEVICE_NAME "Matsushita CD-ROM"
195 #define DEVICE_REQUEST do_sbpcd_request
196 #define DEVICE_NR(device) (MINOR(device))
197 #define DEVICE_ON(device)
198 #define DEVICE_OFF(device)
199 
200 #else
201 
202 #error "unknown blk device"
203 
204 #endif
205 
206 #if (MAJOR_NR != SCSI_TAPE_MAJOR)
207 
208 #ifndef CURRENT
209 #define CURRENT (blk_dev[MAJOR_NR].current_request)
210 #endif
211 
212 #define CURRENT_DEV DEVICE_NR(CURRENT->dev)
213 
214 #ifdef DEVICE_INTR
215 void (*DEVICE_INTR)(void) = NULL;
216 #endif
217 #ifdef DEVICE_TIMEOUT
218 
219 #define SET_TIMER \
220 ((timer_table[DEVICE_TIMEOUT].expires = jiffies + TIMEOUT_VALUE), \
221 (timer_active |= 1<<DEVICE_TIMEOUT))
222 
223 #define CLEAR_TIMER \
224 timer_active &= ~(1<<DEVICE_TIMEOUT)
225 
226 #define SET_INTR(x) \
227 if ((DEVICE_INTR = (x)) != NULL) \
228         SET_TIMER; \
229 else \
230         CLEAR_TIMER;
231 
232 #else
233 
234 #define SET_INTR(x) (DEVICE_INTR = (x))
235 
236 #endif
237 static void (DEVICE_REQUEST)(void);
238 
239 /* end_request() - SCSI devices have their own version */
240 
241 #if ! SCSI_MAJOR(MAJOR_NR)
242 
243 static void end_request(int uptodate)
244 {
245         struct request * req;
246         struct buffer_head * bh;
247         struct task_struct * p;
248 
249         req = CURRENT;
250         req->errors = 0;
251         if (!uptodate) {
252                 printk(DEVICE_NAME " I/O error\n");
253                 printk("dev %04lX, sector %lu\n",
254                        (unsigned long)req->dev, req->sector);
255                 req->nr_sectors--;
256                 req->nr_sectors &= ~SECTOR_MASK;
257                 req->sector += (BLOCK_SIZE / 512);
258                 req->sector &= ~SECTOR_MASK;            
259         }
260 
261         if ((bh = req->bh) != NULL) {
262                 req->bh = bh->b_reqnext;
263                 bh->b_reqnext = NULL;
264                 bh->b_uptodate = uptodate;
265                 unlock_buffer(bh);
266                 if ((bh = req->bh) != NULL) {
267                         req->current_nr_sectors = bh->b_size >> 9;
268                         if (req->nr_sectors < req->current_nr_sectors) {
269                                 req->nr_sectors = req->current_nr_sectors;
270                                 printk("end_request: buffer-list destroyed\n");
271                         }
272                         req->buffer = bh->b_data;
273                         return;
274                 }
275         }
276         DEVICE_OFF(req->dev);
277         CURRENT = req->next;
278         if ((p = req->waiting) != NULL) {
279                 req->waiting = NULL;
280                 p->state = TASK_RUNNING;
281                 if (p->counter > current->counter)
282                         need_resched = 1;
283         }
284         req->dev = -1;
285         wake_up(&wait_for_request);
286 }
287 #endif
288 
289 #ifdef DEVICE_INTR
290 #define CLEAR_INTR SET_INTR(NULL)
291 #else
292 #define CLEAR_INTR
293 #endif
294 
295 #define INIT_REQUEST \
296         if (!CURRENT) {\
297                 CLEAR_INTR; \
298                 return; \
299         } \
300         if (MAJOR(CURRENT->dev) != MAJOR_NR) \
301                 panic(DEVICE_NAME ": request list destroyed"); \
302         if (CURRENT->bh) { \
303                 if (!CURRENT->bh->b_lock) \
304                         panic(DEVICE_NAME ": block not locked"); \
305         }
306 
307 #endif
308 
309 #endif
310 #endif
311 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -