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