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