This source file includes following definitions.
- CMOS_READ
- read_timer
- hd_setup
- win_result
- controller_ready
- status_ok
- controller_busy
- hd_out
- rawstring
- identify_intr
- set_multmode_intr
- drive_busy
- reset_controller
- reset_hd
- unexpected_hd_interrupt
- bad_rw_intr
- wait_DRQ
- read_intr
- multwrite
- multwrite_intr
- write_intr
- recal_intr
- hd_times_out
- hd_request
- do_hd_request
- hd_ioctl
- hd_open
- hd_release
- hd_interrupt
- hd_geninit
- hd_init
- revalidate_hddisk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #define DEFAULT_MULT_COUNT 0
25 #define DEFAULT_UNMASK_INTR 0
26
27 #include <asm/irq.h>
28 #include <linux/errno.h>
29 #include <linux/signal.h>
30 #include <linux/sched.h>
31 #include <linux/timer.h>
32 #include <linux/fs.h>
33 #include <linux/kernel.h>
34 #include <linux/hdreg.h>
35 #include <linux/genhd.h>
36 #include <linux/config.h>
37 #include <linux/malloc.h>
38
39 #define REALLY_SLOW_IO
40 #include <asm/system.h>
41 #include <asm/io.h>
42 #include <asm/segment.h>
43
44 #define MAJOR_NR HD_MAJOR
45 #include "blk.h"
46
47 #define HD_IRQ 14
48
49 static int revalidate_hddisk(int, int);
50
51 static inline unsigned char CMOS_READ(unsigned char addr)
52 {
53 outb_p(addr,0x70);
54 return inb_p(0x71);
55 }
56
57 #define HD_DELAY 0
58
59 #define MAX_ERRORS 16
60 #define RESET_FREQ 8
61 #define RECAL_FREQ 4
62 #define MAX_HD 2
63
64 static void recal_intr(void);
65 static void bad_rw_intr(void);
66
67 static char recalibrate[MAX_HD] = { 0, };
68 static char special_op[MAX_HD] = { 0, };
69 static int access_count[MAX_HD] = {0, };
70 static char busy[MAX_HD] = {0, };
71 static struct wait_queue * busy_wait = NULL;
72
73 static int reset = 0;
74 static int hd_error = 0;
75
76
77
78
79 struct hd_i_struct {
80 unsigned int head,sect,cyl,wpcom,lzone,ctl;
81 };
82 static struct hd_driveid *hd_ident_info[MAX_HD];
83
84 #ifdef HD_TYPE
85 static struct hd_i_struct hd_info[] = { HD_TYPE };
86 struct hd_i_struct bios_info[] = { HD_TYPE };
87 static int NR_HD = ((sizeof (hd_info))/(sizeof (struct hd_i_struct)));
88 #else
89 static struct hd_i_struct hd_info[] = { {0,0,0,0,0,0},{0,0,0,0,0,0} };
90 struct hd_i_struct bios_info[] = { {0,0,0,0,0,0},{0,0,0,0,0,0} };
91 static int NR_HD = 0;
92 #endif
93
94 static struct hd_struct hd[MAX_HD<<6]={{0,0},};
95 static int hd_sizes[MAX_HD<<6] = {0, };
96 static int hd_blocksizes[MAX_HD<<6] = {0, };
97
98 #if (HD_DELAY > 0)
99 unsigned long last_req;
100
101 unsigned long read_timer(void)
102 {
103 unsigned long t, flags;
104 int i;
105
106 save_flags(flags);
107 cli();
108 t = jiffies * 11932;
109 outb_p(0, 0x43);
110 i = inb_p(0x40);
111 i |= inb(0x40) << 8;
112 restore_flags(flags);
113 return(t - i);
114 }
115 #endif
116
117 void hd_setup(char *str, int *ints)
118 {
119 int hdind = 0;
120
121 if (ints[0] != 3)
122 return;
123 if (bios_info[0].head != 0)
124 hdind=1;
125 bios_info[hdind].head = hd_info[hdind].head = ints[2];
126 bios_info[hdind].sect = hd_info[hdind].sect = ints[3];
127 bios_info[hdind].cyl = hd_info[hdind].cyl = ints[1];
128 bios_info[hdind].wpcom = hd_info[hdind].wpcom = 0;
129 bios_info[hdind].lzone = hd_info[hdind].lzone = ints[1];
130 bios_info[hdind].ctl = hd_info[hdind].ctl = (ints[2] > 8 ? 8 : 0);
131 NR_HD = hdind+1;
132 }
133
134 static int win_result(void)
135 {
136 int i=inb_p(HD_STATUS);
137
138 if ((i & (BUSY_STAT | READY_STAT | WRERR_STAT | SEEK_STAT | ERR_STAT))
139 == (READY_STAT | SEEK_STAT)) {
140 hd_error = 0;
141 return 0;
142 }
143 printk("HD: win_result: status = 0x%02x\n",i);
144 if (i&1) {
145 hd_error = inb(HD_ERROR);
146 printk("HD: win_result: error = 0x%02x\n",hd_error);
147 }
148 return 1;
149 }
150
151 static int controller_busy(void);
152 static int status_ok(void);
153
154 static int controller_ready(unsigned int drive, unsigned int head)
155 {
156 int retry = 100;
157
158 do {
159 if (controller_busy() & BUSY_STAT)
160 return 0;
161 outb_p(0xA0 | (drive<<4) | head, HD_CURRENT);
162 if (status_ok())
163 return 1;
164 } while (--retry);
165 return 0;
166 }
167
168 static int status_ok(void)
169 {
170 unsigned char status = inb_p(HD_STATUS);
171
172 if (status & BUSY_STAT)
173 return 1;
174 if (status & WRERR_STAT)
175 return 0;
176 if (!(status & READY_STAT))
177 return 0;
178 if (!(status & SEEK_STAT))
179 return 0;
180 return 1;
181 }
182
183 static int controller_busy(void)
184 {
185 int retries = 100000;
186 unsigned char status;
187
188 do {
189 status = inb_p(HD_STATUS);
190 } while ((status & BUSY_STAT) && --retries);
191 return status;
192 }
193
194 static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect,
195 unsigned int head,unsigned int cyl,unsigned int cmd,
196 void (*intr_addr)(void))
197 {
198 unsigned short port;
199
200 #ifdef DEBUG
201 if (drive>1 || head>15) {
202 printk("bad drive mapping, trying to access drive=%d, cyl=%d, head=%d, sect=%d\n",
203 drive, cyl, head, sect);
204 panic("harddisk driver problem");
205 }
206 #endif
207 #if (HD_DELAY > 0)
208 while (read_timer() - last_req < HD_DELAY)
209 ;
210 #endif
211 if (reset)
212 return;
213 if (!controller_ready(drive, head)) {
214 special_op[drive] += reset = 1;
215 return;
216 }
217 SET_INTR(intr_addr);
218 outb_p(hd_info[drive].ctl,HD_CMD);
219 port=HD_DATA;
220 outb_p(hd_info[drive].wpcom>>2,++port);
221 outb_p(nsect,++port);
222 outb_p(sect,++port);
223 outb_p(cyl,++port);
224 outb_p(cyl>>8,++port);
225 outb_p(0xA0|(drive<<4)|head,++port);
226 outb_p(cmd,++port);
227 }
228
229 static void hd_request (void);
230 static unsigned int identified [MAX_HD] = {0,};
231 static unsigned int unmask_intr [MAX_HD] = {0,};
232 static unsigned int max_mult [MAX_HD] = {0,};
233 static unsigned int mult_req [MAX_HD] = {0,};
234 static unsigned int mult_count [MAX_HD] = {0,};
235 static struct request WCURRENT;
236
237 static void rawstring (char *prefix, unsigned char *s, int n)
238 {
239 if (prefix)
240 printk(prefix);
241 if (s && *s) {
242 int i;
243 for (i=0; i < n && s[i^1] == ' '; ++i);
244 for (; i < n && s[i^1]; ++i)
245 if (s[i^1] != ' ' || ((i+1) < n && s[(i+1)^1] != ' '))
246 printk("%c",s[i^1]);
247 }
248 }
249
250 static void identify_intr(void)
251 {
252 unsigned int dev = DEVICE_NR(CURRENT->dev);
253 unsigned short stat = inb_p(HD_STATUS);
254 struct hd_driveid id;
255
256 if (unmask_intr[dev])
257 sti();
258 if (stat & (BUSY_STAT|ERR_STAT))
259 printk (" hd%c: identity unknown\n", dev+'a');
260 else {
261 insw(HD_DATA, (char *)&id, sizeof(id)/2);
262 max_mult[dev] = id.max_multsect;
263 if ((id.cur_valid&1) && id.cur_cyls && id.cur_heads && (id.cur_heads <= 16) && id.cur_sectors) {
264
265
266
267
268
269
270
271 hd_info[dev].cyl = id.cur_cyls;
272 hd_info[dev].head = id.cur_heads;
273 hd_info[dev].sect = id.cur_sectors;
274 }
275 printk (" hd%c: ", dev+'a');
276 rawstring(NULL, id.model, sizeof(id.model));
277 printk (", %dMB w/%dKB Cache, CHS=%d/%d/%d, MaxMult=%d\n",
278 id.cyls*id.heads*id.sectors/2048, id.buf_size/2,
279 hd_info[dev].cyl, hd_info[dev].head, hd_info[dev].sect, id.max_multsect);
280
281 if (NULL != (hd_ident_info[dev] = kmalloc(sizeof(id),GFP_ATOMIC)))
282 *hd_ident_info[dev] = id;
283
284
285 insw(HD_DATA,(char *)&id,sizeof(id)/2);
286 insw(HD_DATA,(char *)&id,sizeof(id)/2);
287 insw(HD_DATA,(char *)&id,sizeof(id)/2);
288 }
289 #if (HD_DELAY > 0)
290 last_req = read_timer();
291 #endif
292 hd_request();
293 return;
294 }
295
296 static void set_multmode_intr(void)
297 {
298 unsigned int dev = DEVICE_NR(CURRENT->dev), stat = inb_p(HD_STATUS);
299
300 if (unmask_intr[dev])
301 sti();
302 if (stat & (BUSY_STAT|ERR_STAT)) {
303 mult_req[dev] = mult_count[dev] = 0;
304 printk (" hd%c: set multiple mode failed\n", dev+'a');
305 } else {
306 if ((mult_count[dev] = mult_req[dev]))
307 printk (" hd%c: enabled %d-sector multiple mode\n",
308 dev+'a', mult_count[dev]);
309 else
310 printk (" hd%c: disabled multiple mode\n", dev+'a');
311 }
312 #if (HD_DELAY > 0)
313 last_req = read_timer();
314 #endif
315 hd_request();
316 return;
317 }
318
319 static int drive_busy(void)
320 {
321 unsigned int i;
322 unsigned char c;
323
324 for (i = 0; i < 500000 ; i++) {
325 c = inb_p(HD_STATUS);
326 c &= (BUSY_STAT | READY_STAT | SEEK_STAT);
327 if (c == (READY_STAT | SEEK_STAT))
328 return 0;
329 }
330 printk("HD controller times out, status = 0x%02x\n",c);
331 return 1;
332 }
333
334 static void reset_controller(void)
335 {
336 int i;
337
338 printk(KERN_DEBUG "HD-controller reset\n");
339 outb_p(4,HD_CMD);
340 for(i = 0; i < 1000; i++) nop();
341 outb(hd_info[0].ctl & 0x0f ,HD_CMD);
342 if (drive_busy())
343 printk("HD-controller still busy\n");
344 if ((hd_error = inb(HD_ERROR)) != 1)
345 printk("HD-controller reset failed: %02x\n",hd_error);
346 }
347
348 static void reset_hd(void)
349 {
350 static int i;
351
352 repeat:
353 if (reset) {
354 reset = 0;
355 i = -1;
356 reset_controller();
357 } else if (win_result()) {
358 bad_rw_intr();
359 if (reset)
360 goto repeat;
361 }
362 if (++i < NR_HD) {
363 if (unmask_intr[i]) {
364 printk("hd%c: disabled irq-unmasking\n",i+'a');
365 unmask_intr[i] = 0;
366 }
367 if (mult_req[i] || mult_count[i]) {
368 printk("hd%c: disabled multiple mode\n",i+'a');
369 mult_req[i] = mult_count[i] = 0;
370 }
371 hd_out(i,hd_info[i].sect,hd_info[i].sect,hd_info[i].head-1,
372 hd_info[i].cyl,WIN_SPECIFY,&reset_hd);
373 if (reset)
374 goto repeat;
375 } else
376 hd_request();
377 }
378
379
380
381
382
383
384 void unexpected_hd_interrupt(void)
385 {
386 sti();
387 printk(KERN_DEBUG "Unexpected HD interrupt\n");
388 SET_TIMER;
389 }
390
391
392
393
394
395
396 static void bad_rw_intr(void)
397 {
398 int dev;
399
400 if (!CURRENT)
401 return;
402 dev = MINOR(CURRENT->dev) >> 6;
403 if (++CURRENT->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) {
404 end_request(0);
405 special_op[dev] += recalibrate[dev] = 1;
406 } else if (CURRENT->errors % RESET_FREQ == 0)
407 special_op[dev] += reset = 1;
408 else if ((hd_error & TRK0_ERR) || CURRENT->errors % RECAL_FREQ == 0)
409 special_op[dev] += recalibrate[dev] = 1;
410
411 }
412
413 static inline int wait_DRQ(void)
414 {
415 int retries = 100000;
416
417 while (--retries > 0)
418 if (inb_p(HD_STATUS) & DRQ_STAT)
419 return 0;
420 return -1;
421 }
422
423 #define STAT_MASK (BUSY_STAT | READY_STAT | WRERR_STAT | SEEK_STAT | ERR_STAT)
424 #define STAT_OK (READY_STAT | SEEK_STAT)
425
426 static void read_intr(void)
427 {
428 unsigned int dev = DEVICE_NR(CURRENT->dev);
429 int i, retries = 100000, msect = mult_count[dev], nsect;
430
431 if (unmask_intr[dev])
432 sti();
433 do {
434 i = (unsigned) inb_p(HD_STATUS);
435 if (i & BUSY_STAT)
436 continue;
437 if ((i & STAT_MASK) != STAT_OK)
438 break;
439 if (i & DRQ_STAT)
440 goto ok_to_read;
441 } while (--retries > 0);
442 sti();
443 printk("hd%c: read_intr: status = 0x%02x\n",dev+'a',i);
444 if (i & ERR_STAT) {
445 hd_error = (unsigned) inb(HD_ERROR);
446 printk("hd%c: read_intr: error = 0x%02x\n",dev+'a',hd_error);
447 }
448 bad_rw_intr();
449 hd_request();
450 return;
451 ok_to_read:
452 if (msect) {
453 if ((nsect = CURRENT->current_nr_sectors) > msect)
454 nsect = msect;
455 msect -= nsect;
456 } else
457 nsect = 1;
458 insw(HD_DATA,CURRENT->buffer,nsect<<8);
459 CURRENT->sector += nsect;
460 CURRENT->buffer += nsect<<9;
461 CURRENT->errors = 0;
462 i = (CURRENT->nr_sectors -= nsect);
463
464 #ifdef DEBUG
465 printk("hd%c: read: sectors(%ld-%ld), remaining=%ld, buffer=%08lx\n",
466 dev+'a', CURRENT->sector, CURRENT->sector+nsect,
467 CURRENT->nr_sectors, (long) CURRENT->buffer+(nsect<<9));
468 #endif
469 if ((CURRENT->current_nr_sectors -= nsect) <= 0)
470 end_request(1);
471 if (i > 0) {
472 if (msect)
473 goto ok_to_read;
474 SET_INTR(&read_intr);
475 return;
476 }
477 (void) inb_p(HD_STATUS);
478 #if (HD_DELAY > 0)
479 last_req = read_timer();
480 #endif
481 if (CURRENT)
482 hd_request();
483 return;
484 }
485
486 static inline void multwrite (unsigned int dev)
487 {
488 unsigned int mcount = mult_count[dev];
489
490 while (mcount--) {
491 outsw(HD_DATA,WCURRENT.buffer,256);
492 if (!--WCURRENT.nr_sectors)
493 return;
494 WCURRENT.buffer += 512;
495 if (!--WCURRENT.current_nr_sectors) {
496 WCURRENT.bh = WCURRENT.bh->b_reqnext;
497 if (WCURRENT.bh == NULL)
498 panic("buffer list corrupted\n");
499 WCURRENT.current_nr_sectors = WCURRENT.bh->b_size>>9;
500 WCURRENT.buffer = WCURRENT.bh->b_data;
501 }
502 }
503 }
504
505 static void multwrite_intr(void)
506 {
507 int i;
508 unsigned int dev = DEVICE_NR(WCURRENT.dev);
509
510 if (unmask_intr[dev])
511 sti();
512 if (((i = inb_p(HD_STATUS)) & STAT_MASK) == STAT_OK) {
513 if (i & DRQ_STAT) {
514 if (WCURRENT.nr_sectors) {
515 multwrite(dev);
516 SET_INTR(&multwrite_intr);
517 return;
518 }
519 } else {
520 if (!WCURRENT.nr_sectors) {
521 for (i = CURRENT->nr_sectors; i > 0;){
522 i -= CURRENT->current_nr_sectors;
523 end_request(1);
524 }
525 #if (HD_DELAY > 0)
526 last_req = read_timer();
527 #endif
528 if (CURRENT)
529 hd_request();
530 return;
531 }
532 }
533 }
534 sti();
535 printk("hd%c: multwrite_intr: status = 0x%02x\n",dev+'a',i);
536 if (i & ERR_STAT) {
537 hd_error = (unsigned) inb(HD_ERROR);
538 printk("hd:%c multwrite_intr: error = 0x%02x\n",dev+'a',hd_error);
539 }
540 bad_rw_intr();
541 hd_request();
542 }
543
544 static void write_intr(void)
545 {
546 int i;
547 int retries = 100000;
548
549 if (unmask_intr[DEVICE_NR(WCURRENT.dev)])
550 sti();
551 do {
552 i = (unsigned) inb_p(HD_STATUS);
553 if (i & BUSY_STAT)
554 continue;
555 if ((i & STAT_MASK) != STAT_OK)
556 break;
557 if ((CURRENT->nr_sectors <= 1) || (i & DRQ_STAT))
558 goto ok_to_write;
559 } while (--retries > 0);
560 sti();
561 printk("HD: write_intr: status = 0x%02x\n",i);
562 if (i & ERR_STAT) {
563 hd_error = (unsigned) inb(HD_ERROR);
564 printk("HD: write_intr: error = 0x%02x\n",hd_error);
565 }
566 bad_rw_intr();
567 hd_request();
568 return;
569 ok_to_write:
570 CURRENT->sector++;
571 i = --CURRENT->nr_sectors;
572 --CURRENT->current_nr_sectors;
573 CURRENT->buffer += 512;
574 if (!i || (CURRENT->bh && !SUBSECTOR(i)))
575 end_request(1);
576 if (i > 0) {
577 SET_INTR(&write_intr);
578 outsw(HD_DATA,CURRENT->buffer,256);
579 sti();
580 } else {
581 #if (HD_DELAY > 0)
582 last_req = read_timer();
583 #endif
584 hd_request();
585 }
586 return;
587 }
588
589 static void recal_intr(void)
590 {
591 if (win_result())
592 bad_rw_intr();
593 #if (HD_DELAY > 0)
594 last_req = read_timer();
595 #endif
596 hd_request();
597 }
598
599
600
601
602
603 static void hd_times_out(void)
604 {
605 DEVICE_INTR = NULL;
606 sti();
607 reset = 1;
608 if (!CURRENT)
609 return;
610 special_op [DEVICE_NR(CURRENT->dev)] ++;
611 printk(KERN_DEBUG "HD timeout\n");
612 cli();
613 if (++CURRENT->errors >= MAX_ERRORS) {
614 #ifdef DEBUG
615 printk("hd : too many errors.\n");
616 #endif
617 end_request(0);
618 }
619
620 hd_request();
621 }
622
623
624
625
626
627
628
629
630 static void hd_request(void)
631 {
632 unsigned int block,dev;
633 unsigned int sec,head,cyl,track;
634 unsigned int nsect;
635
636 if (CURRENT && CURRENT->dev < 0) return;
637
638 if (DEVICE_INTR)
639 return;
640 repeat:
641 timer_active &= ~(1<<HD_TIMER);
642 sti();
643 INIT_REQUEST;
644 dev = MINOR(CURRENT->dev);
645 block = CURRENT->sector;
646 nsect = CURRENT->nr_sectors;
647 if (dev >= (NR_HD<<6) || block >= hd[dev].nr_sects) {
648 #ifdef DEBUG
649 printk("hd : attempted read for sector %d past end of device at sector %d.\n",
650 block, hd[dev].nr_sects);
651 #endif
652 end_request(0);
653 goto repeat;
654 }
655 block += hd[dev].start_sect;
656 dev >>= 6;
657 sec = block % hd_info[dev].sect + 1;
658 track = block / hd_info[dev].sect;
659 head = track % hd_info[dev].head;
660 cyl = track / hd_info[dev].head;
661 #ifdef DEBUG
662 printk("hd%c : cyl = %d, head = %d, sector = %d, buffer = %08x\n",
663 dev+'a', cyl, head, sec, CURRENT->buffer);
664 #endif
665 if (!unmask_intr[dev])
666 cli();
667 if (special_op[dev]) {
668 if (reset) {
669 int i;
670
671 for (i=0; i < NR_HD; i++)
672 special_op[i] = recalibrate[i] = 1;
673 cli();
674 reset_hd();
675 return;
676 }
677 if (recalibrate[dev]) {
678 recalibrate[dev] = 0;
679 hd_out(dev,hd_info[dev].sect,0,0,0,WIN_RESTORE,&recal_intr);
680 if (reset)
681 goto repeat;
682 return;
683 }
684 if (!identified[dev]) {
685 identified[dev] = 1;
686 unmask_intr[dev] = DEFAULT_UNMASK_INTR;
687 mult_req[dev] = DEFAULT_MULT_COUNT;
688 hd_out(dev,0,0,0,0,WIN_IDENTIFY,&identify_intr);
689 if (reset)
690 goto repeat;
691 return;
692 }
693 if (mult_req[dev] != mult_count[dev]) {
694 hd_out(dev,mult_req[dev],0,0,0,WIN_SETMULT,&set_multmode_intr);
695 if (reset)
696 goto repeat;
697 return;
698 }
699 if (hd_info[dev].head > 16) {
700 printk ("hd%c: cannot handle device with more than 16 heads - giving up\n", dev+'a');
701 end_request(0);
702 goto repeat;
703 }
704 --special_op[dev];
705 }
706 if (CURRENT->cmd == READ) {
707 unsigned int cmd = mult_count[dev] > 1 ? WIN_MULTREAD : WIN_READ;
708 hd_out(dev,nsect,sec,head,cyl,cmd,&read_intr);
709 if (reset)
710 goto repeat;
711 #ifdef DEBUG
712 printk("hd%c: reading %d sectors(%ld-%ld), buffer=%08lx\n",
713 dev+'a', nsect, CURRENT->sector,
714 CURRENT->sector+nsect-1, (long) CURRENT->buffer);
715 #endif
716 return;
717 }
718 if (CURRENT->cmd == WRITE) {
719 if (mult_count[dev])
720 hd_out(dev,nsect,sec,head,cyl,WIN_MULTWRITE,&multwrite_intr);
721 else
722 hd_out(dev,nsect,sec,head,cyl,WIN_WRITE,&write_intr);
723 if (reset)
724 goto repeat;
725 #ifdef DEBUG
726 printk("hd%c: writing %d sectors(%ld-%ld), buffer=%08lx\n",
727 dev+'a', nsect, CURRENT->sector,
728 CURRENT->sector+nsect-1, (long) CURRENT->buffer);
729 #endif
730 if (wait_DRQ()) {
731 printk("hd%c: hd_request: no DRQ\n", dev+'a');
732 bad_rw_intr();
733 goto repeat;
734 }
735 if (mult_count[dev]) {
736 WCURRENT = *CURRENT;
737 multwrite(dev);
738 } else {
739 outsw(HD_DATA,CURRENT->buffer,256);
740 }
741 return;
742 }
743 panic("unknown hd-command");
744 }
745
746 static void do_hd_request (void)
747 {
748 disable_irq(HD_IRQ);
749 hd_request();
750 enable_irq(HD_IRQ);
751 }
752
753 static int hd_ioctl(struct inode * inode, struct file * file,
754 unsigned int cmd, unsigned long arg)
755 {
756 struct hd_geometry *loc = (struct hd_geometry *) arg;
757 int dev, err;
758
759 if ((!inode) || (!inode->i_rdev))
760 return -EINVAL;
761 dev = MINOR(inode->i_rdev) >> 6;
762 if (dev >= NR_HD)
763 return -EINVAL;
764 switch (cmd) {
765 case HDIO_GETGEO:
766 if (!loc) return -EINVAL;
767 err = verify_area(VERIFY_WRITE, loc, sizeof(*loc));
768 if (err)
769 return err;
770 put_fs_byte(bios_info[dev].head,
771 (char *) &loc->heads);
772 put_fs_byte(bios_info[dev].sect,
773 (char *) &loc->sectors);
774 put_fs_word(bios_info[dev].cyl,
775 (short *) &loc->cylinders);
776 put_fs_long(hd[MINOR(inode->i_rdev)].start_sect,
777 (long *) &loc->start);
778 return 0;
779 case BLKRASET:
780 if(!suser()) return -EACCES;
781 if(arg > 0xff) return -EINVAL;
782 read_ahead[MAJOR(inode->i_rdev)] = arg;
783 return 0;
784 case BLKRAGET:
785 if (!arg) return -EINVAL;
786 err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
787 if (err)
788 return err;
789 put_fs_long(read_ahead[MAJOR(inode->i_rdev)],(long *) arg);
790 return 0;
791 case BLKGETSIZE:
792 if (!arg) return -EINVAL;
793 err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
794 if (err)
795 return err;
796 put_fs_long(hd[MINOR(inode->i_rdev)].nr_sects, (long *) arg);
797 return 0;
798 case BLKFLSBUF:
799 if(!suser()) return -EACCES;
800 fsync_dev(inode->i_rdev);
801 invalidate_buffers(inode->i_rdev);
802 return 0;
803
804 case BLKRRPART:
805 return revalidate_hddisk(inode->i_rdev, 1);
806
807 case HDIO_SETUNMASKINTR:
808 if (!suser()) return -EACCES;
809 if (!arg) return -EINVAL;
810 if (MINOR(inode->i_rdev) & 0x3F) return -EINVAL;
811 err = verify_area(VERIFY_READ, (long *) arg, sizeof(long));
812 if (err)
813 return err;
814 unmask_intr[dev] = get_fs_long((long *) arg);
815 return 0;
816
817 case HDIO_GETUNMASKINTR:
818 if (!arg) return -EINVAL;
819 err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
820 if (err)
821 return err;
822 put_fs_long(unmask_intr[dev], (long *) arg);
823 return 0;
824
825 case HDIO_GETMULTCOUNT:
826 if (!arg) return -EINVAL;
827 err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
828 if (err)
829 return err;
830 put_fs_long(mult_count[dev], (long *) arg);
831 return 0;
832
833 case HDIO_SETMULTCOUNT:
834 {
835 unsigned long flags;
836 if (!suser()) return -EACCES;
837 if (!arg) return -EINVAL;
838 if (MINOR(inode->i_rdev) & 0x3F) return -EINVAL;
839 err = verify_area(VERIFY_READ, (long *) arg, sizeof(long));
840 if (err)
841 return err;
842 arg = get_fs_long((long *) arg);
843 save_flags(flags);
844 cli();
845 if (arg > max_mult[dev])
846 err = -EINVAL;
847 else if (mult_req[dev] != mult_count[dev]) {
848 ++special_op[dev];
849 err = -EBUSY;
850 } else {
851 mult_req[dev] = arg;
852 ++special_op[dev];
853 err = 0;
854 }
855 restore_flags(flags);
856 return err;
857 }
858 case HDIO_GETIDENTITY:
859 if (!arg) return -EINVAL;
860 if (MINOR(inode->i_rdev) & 0x3F) return -EINVAL;
861 if (hd_ident_info[dev] == NULL) return -ENOMSG;
862 err = verify_area(VERIFY_WRITE, (char *) arg, sizeof(struct hd_driveid));
863 if (err)
864 return err;
865 memcpy_tofs((char *)arg, (char *) hd_ident_info[dev], sizeof(struct hd_driveid));
866
867 RO_IOCTLS(inode->i_rdev,arg);
868 default:
869 return -EINVAL;
870 }
871 }
872
873 static int hd_open(struct inode * inode, struct file * filp)
874 {
875 int target;
876 target = DEVICE_NR(MINOR(inode->i_rdev));
877
878 while (busy[target])
879 sleep_on(&busy_wait);
880 access_count[target]++;
881 return 0;
882 }
883
884
885
886
887
888 static void hd_release(struct inode * inode, struct file * file)
889 {
890 int target;
891 sync_dev(inode->i_rdev);
892
893 target = DEVICE_NR(MINOR(inode->i_rdev));
894 access_count[target]--;
895
896 }
897
898 static void hd_geninit(void);
899
900 static struct gendisk hd_gendisk = {
901 MAJOR_NR,
902 "hd",
903 6,
904 1 << 6,
905 MAX_HD,
906 hd_geninit,
907 hd,
908 hd_sizes,
909 0,
910 (void *) bios_info,
911 NULL
912 };
913
914 static void hd_interrupt(int unused)
915 {
916 void (*handler)(void) = DEVICE_INTR;
917
918 DEVICE_INTR = NULL;
919 timer_active &= ~(1<<HD_TIMER);
920 if (!handler)
921 handler = unexpected_hd_interrupt;
922 handler();
923 sti();
924 }
925
926
927
928
929
930
931
932
933
934
935 static void hd_geninit(void)
936 {
937 int drive, i;
938 extern struct drive_info drive_info;
939 unsigned char *BIOS = (unsigned char *) &drive_info;
940 int cmos_disks;
941
942 if (!NR_HD) {
943 for (drive=0 ; drive<2 ; drive++) {
944 bios_info[drive].cyl = hd_info[drive].cyl = *(unsigned short *) BIOS;
945 bios_info[drive].head = hd_info[drive].head = *(2+BIOS);
946 bios_info[drive].wpcom = hd_info[drive].wpcom = *(unsigned short *) (5+BIOS);
947 bios_info[drive].ctl = hd_info[drive].ctl = *(8+BIOS);
948 bios_info[drive].lzone = hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
949 bios_info[drive].sect = hd_info[drive].sect = *(14+BIOS);
950 #ifdef does_not_work_for_everybody_with_scsi_but_helps_ibm_vp
951 if (hd_info[drive].cyl && NR_HD == drive)
952 NR_HD++;
953 #endif
954 BIOS += 16;
955 }
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979 if ((cmos_disks = CMOS_READ(0x12)) & 0xf0)
980 if (cmos_disks & 0x0f)
981 NR_HD = 2;
982 else
983 NR_HD = 1;
984 }
985 i = NR_HD;
986 while (i-- > 0) {
987 hd[i<<6].nr_sects = 0;
988 if (bios_info[i].head > 16) {
989
990
991
992
993
994
995
996
997 printk("hd.c: IDE/ST-506 disk with more than 16 heads detected.\n");
998 printk(" (hd%c: cyl=%d, sect=%d, head=%d)\n", i+'a',
999 bios_info[i].cyl,
1000 bios_info[i].sect,
1001 bios_info[i].head);
1002 }
1003 hd[i<<6].nr_sects = bios_info[i].head *
1004 bios_info[i].sect * bios_info[i].cyl;
1005 hd_ident_info[i] = NULL;
1006 special_op[i] = 1;
1007 }
1008 if (NR_HD) {
1009 if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd")) {
1010 printk("hd.c: unable to get IRQ%d for the harddisk driver\n",HD_IRQ);
1011 NR_HD = 0;
1012 }
1013 }
1014 hd_gendisk.nr_real = NR_HD;
1015
1016 for(i=0;i<(MAX_HD << 6);i++) hd_blocksizes[i] = 1024;
1017 blksize_size[MAJOR_NR] = hd_blocksizes;
1018 }
1019
1020 static struct file_operations hd_fops = {
1021 NULL,
1022 block_read,
1023 block_write,
1024 NULL,
1025 NULL,
1026 hd_ioctl,
1027 NULL,
1028 hd_open,
1029 hd_release,
1030 block_fsync
1031 };
1032
1033 unsigned long hd_init(unsigned long mem_start, unsigned long mem_end)
1034 {
1035 if (register_blkdev(MAJOR_NR,"hd",&hd_fops)) {
1036 printk("Unable to get major %d for harddisk\n",MAJOR_NR);
1037 return mem_start;
1038 }
1039 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1040 read_ahead[MAJOR_NR] = 8;
1041 hd_gendisk.next = gendisk_head;
1042 gendisk_head = &hd_gendisk;
1043 timer_table[HD_TIMER].fn = hd_times_out;
1044 return mem_start;
1045 }
1046
1047 #define DEVICE_BUSY busy[target]
1048 #define USAGE access_count[target]
1049 #define CAPACITY (bios_info[target].head*bios_info[target].sect*bios_info[target].cyl)
1050
1051
1052 #undef MAYBE_REINIT
1053 #define GENDISK_STRUCT hd_gendisk
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063 static int revalidate_hddisk(int dev, int maxusage)
1064 {
1065 int target, major;
1066 struct gendisk * gdev;
1067 int max_p;
1068 int start;
1069 int i;
1070 long flags;
1071
1072 target = DEVICE_NR(MINOR(dev));
1073 gdev = &GENDISK_STRUCT;
1074
1075 save_flags(flags);
1076 cli();
1077 if (DEVICE_BUSY || USAGE > maxusage) {
1078 restore_flags(flags);
1079 return -EBUSY;
1080 };
1081 DEVICE_BUSY = 1;
1082 restore_flags(flags);
1083
1084 max_p = gdev->max_p;
1085 start = target << gdev->minor_shift;
1086 major = MAJOR_NR << 8;
1087
1088 for (i=max_p - 1; i >=0 ; i--) {
1089 sync_dev(major | start | i);
1090 invalidate_inodes(major | start | i);
1091 invalidate_buffers(major | start | i);
1092 gdev->part[start+i].start_sect = 0;
1093 gdev->part[start+i].nr_sects = 0;
1094 };
1095
1096 #ifdef MAYBE_REINIT
1097 MAYBE_REINIT;
1098 #endif
1099
1100 gdev->part[start].nr_sects = CAPACITY;
1101 resetup_one_dev(gdev, target);
1102
1103 DEVICE_BUSY = 0;
1104 wake_up(&busy_wait);
1105 return 0;
1106 }
1107