1 /*
2 * linux/drivers/ide/hd.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
6
7 /*
8 * This is the low-level hd interrupt support. It traverses the
9 * request-list, using interrupts to jump between functions. As
10 * all the functions are called within interrupts, we may not
11 * sleep. Special care is recommended.
12 *
13 * modified by Drew Eckhardt to check nr of hd's from the CMOS.
14 *
15 * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
16 * in the early extended-partition checks and added DM partitions
17 *
18 * IRQ-unmask, drive-id, multiple-mode, support for ">16 heads",
19 * and general streamlining by Mark Lord.
20 *
21 * Removed 99% of above. Use Mark's ide driver for those options.
22 * This is now a lightweight ST-506 driver. (Paul Gortmaker)
23 *
24 * Modified 1995 Russell King for ARM processor.
25 */
26
27 /* Uncomment the following if you want verbose error reports. */
28 /* #define VERBOSE_ERRORS */
29
30 #include <linux/errno.h>
31 #include <linux/signal.h>
32 #include <linux/sched.h>
33 #include <linux/timer.h>
34 #include <linux/fs.h>
35 #include <linux/devfs_fs_kernel.h>
36 #include <linux/kernel.h>
37 #include <linux/hdreg.h>
38 #include <linux/genhd.h>
39 #include <linux/malloc.h>
40 #include <linux/string.h>
41 #include <linux/ioport.h>
42 #include <linux/mc146818rtc.h> /* CMOS defines */
43 #include <linux/init.h>
44 #include <linux/blkpg.h>
45
46 #define REALLY_SLOW_IO
47 #include <asm/system.h>
48 #include <asm/io.h>
49 #include <asm/uaccess.h>
50
51 #define MAJOR_NR HD_MAJOR
52 #include <linux/blk.h>
53
54 #ifdef __arm__
55 #undef HD_IRQ
56 #endif
57 #include <asm/irq.h>
58 #ifdef __arm__
59 #define HD_IRQ IRQ_HARDDISK
60 #endif
61
62 static int revalidate_hddisk(kdev_t, int);
63
64 #define HD_DELAY 0
65
66 #define MAX_ERRORS 16 /* Max read/write errors/sector */
67 #define RESET_FREQ 8 /* Reset controller every 8th retry */
68 #define RECAL_FREQ 4 /* Recalibrate every 4th retry */
69 #define MAX_HD 2
70
71 #define STAT_OK (READY_STAT|SEEK_STAT)
72 #define OK_STATUS(s) (((s)&(STAT_OK|(BUSY_STAT|WRERR_STAT|ERR_STAT)))==STAT_OK)
73
74 static void recal_intr(void);
75 static void bad_rw_intr(void);
76
77 static char recalibrate[MAX_HD];
78 static char special_op[MAX_HD];
79 static int access_count[MAX_HD];
80 static char busy[MAX_HD];
81 static DECLARE_WAIT_QUEUE_HEAD(busy_wait);
82
83 static int reset;
84 static int hd_error;
85
86 #define SUBSECTOR(block) (CURRENT->current_nr_sectors > 0)
87
88 /*
89 * This struct defines the HD's and their types.
90 */
91 struct hd_i_struct {
92 unsigned int head,sect,cyl,wpcom,lzone,ctl;
93 };
94
95 #ifdef HD_TYPE
96 static struct hd_i_struct hd_info[] = { HD_TYPE };
97 static int NR_HD = ((sizeof (hd_info))/(sizeof (struct hd_i_struct)));
98 #else
99 static struct hd_i_struct hd_info[MAX_HD];
100 static int NR_HD;
101 #endif
102
103 static struct hd_struct hd[MAX_HD<<6];
104 static int hd_sizes[MAX_HD<<6];
105 static int hd_blocksizes[MAX_HD<<6];
106 static int hd_hardsectsizes[MAX_HD<<6];
107
108 static struct timer_list device_timer;
109
110 #define SET_TIMER \
111 do { \
112 mod_timer(&device_timer, jiffies + TIMEOUT_VALUE); \
113 } while (0)
114
115 #define CLEAR_TIMER del_timer(&device_timer);
116
117 #undef SET_INTR
118
119 #define SET_INTR(x) \
120 if ((DEVICE_INTR = (x)) != NULL) \
121 SET_TIMER; \
122 else \
123 CLEAR_TIMER;
124
125
126 #if (HD_DELAY > 0)
127 unsigned long last_req;
128
129 unsigned long read_timer(void)
130 {
131 unsigned long t, flags;
132 int i;
133
134 save_flags(flags);
135 cli();
136 t = jiffies * 11932;
137 outb_p(0, 0x43);
138 i = inb_p(0x40);
139 i |= inb(0x40) << 8;
140 restore_flags(flags);
141 return(t - i);
142 }
143 #endif
144
145 void __init hd_setup(char *str, int *ints)
146 {
147 int hdind = 0;
148
149 if (ints[0] != 3)
150 return;
151 if (hd_info[0].head != 0)
152 hdind=1;
153 hd_info[hdind].head = ints[2];
154 hd_info[hdind].sect = ints[3];
155 hd_info[hdind].cyl = ints[1];
156 hd_info[hdind].wpcom = 0;
157 hd_info[hdind].lzone = ints[1];
158 hd_info[hdind].ctl = (ints[2] > 8 ? 8 : 0);
159 NR_HD = hdind+1;
160 }
161
162 static void dump_status (const char *msg, unsigned int stat)
163 {
164 unsigned long flags;
165 char devc;
166
167 devc = !QUEUE_EMPTY ? 'a' + DEVICE_NR(CURRENT->rq_dev) : '?';
168 save_flags (flags);
169 sti();
170 #ifdef VERBOSE_ERRORS
171 printk("hd%c: %s: status=0x%02x { ", devc, msg, stat & 0xff);
172 if (stat & BUSY_STAT) printk("Busy ");
173 if (stat & READY_STAT) printk("DriveReady ");
174 if (stat & WRERR_STAT) printk("WriteFault ");
175 if (stat & SEEK_STAT) printk("SeekComplete ");
176 if (stat & DRQ_STAT) printk("DataRequest ");
177 if (stat & ECC_STAT) printk("CorrectedError ");
178 if (stat & INDEX_STAT) printk("Index ");
179 if (stat & ERR_STAT) printk("Error ");
180 printk("}\n");
181 if ((stat & ERR_STAT) == 0) {
182 hd_error = 0;
183 } else {
184 hd_error = inb(HD_ERROR);
185 printk("hd%c: %s: error=0x%02x { ", devc, msg, hd_error & 0xff);
186 if (hd_error & BBD_ERR) printk("BadSector ");
187 if (hd_error & ECC_ERR) printk("UncorrectableError ");
188 if (hd_error & ID_ERR) printk("SectorIdNotFound ");
189 if (hd_error & ABRT_ERR) printk("DriveStatusError ");
190 if (hd_error & TRK0_ERR) printk("TrackZeroNotFound ");
191 if (hd_error & MARK_ERR) printk("AddrMarkNotFound ");
192 printk("}");
193 if (hd_error & (BBD_ERR|ECC_ERR|ID_ERR|MARK_ERR)) {
194 printk(", CHS=%d/%d/%d", (inb(HD_HCYL)<<8) + inb(HD_LCYL),
195 inb(HD_CURRENT) & 0xf, inb(HD_SECTOR));
196 if (!QUEUE_EMPTY)
197 printk(", sector=%ld", CURRENT->sector);
198 }
199 printk("\n");
200 }
201 #else
202 printk("hd%c: %s: status=0x%02x.\n", devc, msg, stat & 0xff);
203 if ((stat & ERR_STAT) == 0) {
204 hd_error = 0;
205 } else {
206 hd_error = inb(HD_ERROR);
207 printk("hd%c: %s: error=0x%02x.\n", devc, msg, hd_error & 0xff);
208 }
209 #endif /* verbose errors */
210 restore_flags (flags);
211 }
212
213 void check_status(void)
214 {
215 int i = inb_p(HD_STATUS);
216
217 if (!OK_STATUS(i)) {
218 dump_status("check_status", i);
219 bad_rw_intr();
220 }
221 }
222
223 static int controller_busy(void)
224 {
225 int retries = 100000;
226 unsigned char status;
227
228 do {
229 status = inb_p(HD_STATUS);
230 } while ((status & BUSY_STAT) && --retries);
231 return status;
232 }
233
234 static int status_ok(void)
235 {
236 unsigned char status = inb_p(HD_STATUS);
237
238 if (status & BUSY_STAT)
239 return 1; /* Ancient, but does it make sense??? */
240 if (status & WRERR_STAT)
241 return 0;
242 if (!(status & READY_STAT))
243 return 0;
244 if (!(status & SEEK_STAT))
245 return 0;
246 return 1;
247 }
248
249 static int controller_ready(unsigned int drive, unsigned int head)
250 {
251 int retry = 100;
252
253 do {
254 if (controller_busy() & BUSY_STAT)
255 return 0;
256 outb_p(0xA0 | (drive<<4) | head, HD_CURRENT);
257 if (status_ok())
258 return 1;
259 } while (--retry);
260 return 0;
261 }
262
263 static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect,
264 unsigned int head,unsigned int cyl,unsigned int cmd,
265 void (*intr_addr)(void))
266 {
267 unsigned short port;
268
269 #if (HD_DELAY > 0)
270 while (read_timer() - last_req < HD_DELAY)
271 /* nothing */;
272 #endif
273 if (reset)
274 return;
275 if (!controller_ready(drive, head)) {
276 reset = 1;
277 return;
278 }
279 SET_INTR(intr_addr);
280 outb_p(hd_info[drive].ctl,HD_CMD);
281 port=HD_DATA;
282 outb_p(hd_info[drive].wpcom>>2,++port);
283 outb_p(nsect,++port);
284 outb_p(sect,++port);
285 outb_p(cyl,++port);
286 outb_p(cyl>>8,++port);
287 outb_p(0xA0|(drive<<4)|head,++port);
288 outb_p(cmd,++port);
289 }
290
291 static void hd_request (void);
292
293 static int drive_busy(void)
294 {
295 unsigned int i;
296 unsigned char c;
297
298 for (i = 0; i < 500000 ; i++) {
299 c = inb_p(HD_STATUS);
300 if ((c & (BUSY_STAT | READY_STAT | SEEK_STAT)) == STAT_OK)
301 return 0;
302 }
303 dump_status("reset timed out", c);
304 return 1;
305 }
306
307 static void reset_controller(void)
308 {
309 int i;
310
311 outb_p(4,HD_CMD);
312 for(i = 0; i < 1000; i++) barrier();
313 outb_p(hd_info[0].ctl & 0x0f,HD_CMD);
314 for(i = 0; i < 1000; i++) barrier();
315 if (drive_busy())
316 printk("hd: controller still busy\n");
317 else if ((hd_error = inb(HD_ERROR)) != 1)
318 printk("hd: controller reset failed: %02x\n",hd_error);
319 }
320
321 static void reset_hd(void)
322 {
323 static int i;
324
325 repeat:
326 if (reset) {
327 reset = 0;
328 i = -1;
329 reset_controller();
330 } else {
331 check_status();
332 if (reset)
333 goto repeat;
334 }
335 if (++i < NR_HD) {
336 special_op[i] = recalibrate[i] = 1;
337 hd_out(i,hd_info[i].sect,hd_info[i].sect,hd_info[i].head-1,
338 hd_info[i].cyl,WIN_SPECIFY,&reset_hd);
339 if (reset)
340 goto repeat;
341 } else
342 hd_request();
343 }
344
345 /*
346 * Ok, don't know what to do with the unexpected interrupts: on some machines
347 * doing a reset and a retry seems to result in an eternal loop. Right now I
348 * ignore it, and just set the timeout.
349 *
350 * On laptops (and "green" PCs), an unexpected interrupt occurs whenever the
351 * drive enters "idle", "standby", or "sleep" mode, so if the status looks
352 * "good", we just ignore the interrupt completely.
353 */
354 void unexpected_hd_interrupt(void)
355 {
356 unsigned int stat = inb_p(HD_STATUS);
357
358 if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) {
359 dump_status ("unexpected interrupt", stat);
360 SET_TIMER;
361 }
362 }
363
364 /*
365 * bad_rw_intr() now tries to be a bit smarter and does things
366 * according to the error returned by the controller.
367 * -Mika Liljeberg (liljeber@cs.Helsinki.FI)
368 */
369 static void bad_rw_intr(void)
370 {
371 int dev;
372
373 if (QUEUE_EMPTY)
374 return;
375 dev = DEVICE_NR(CURRENT->rq_dev);
376 if (++CURRENT->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) {
377 end_request(0);
378 special_op[dev] = recalibrate[dev] = 1;
379 } else if (CURRENT->errors % RESET_FREQ == 0)
380 reset = 1;
381 else if ((hd_error & TRK0_ERR) || CURRENT->errors % RECAL_FREQ == 0)
382 special_op[dev] = recalibrate[dev] = 1;
383 /* Otherwise just retry */
384 }
385
386 static inline int wait_DRQ(void)
387 {
388 int retries = 100000, stat;
389
390 while (--retries > 0)
391 if ((stat = inb_p(HD_STATUS)) & DRQ_STAT)
392 return 0;
393 dump_status("wait_DRQ", stat);
394 return -1;
395 }
396
397 static void read_intr(void)
398 {
399 int i, retries = 100000;
400
401 do {
402 i = (unsigned) inb_p(HD_STATUS);
403 if (i & BUSY_STAT)
404 continue;
405 if (!OK_STATUS(i))
406 break;
407 if (i & DRQ_STAT)
408 goto ok_to_read;
409 } while (--retries > 0);
410 dump_status("read_intr", i);
411 bad_rw_intr();
412 hd_request();
413 return;
414 ok_to_read:
415 insw(HD_DATA,CURRENT->buffer,256);
416 CURRENT->sector++;
417 CURRENT->buffer += 512;
418 CURRENT->errors = 0;
419 i = --CURRENT->nr_sectors;
420 --CURRENT->current_nr_sectors;
421 #ifdef DEBUG
422 printk("hd%c: read: sector %ld, remaining = %ld, buffer=0x%08lx\n",
423 dev+'a', CURRENT->sector, CURRENT->nr_sectors,
424 (unsigned long) CURRENT->buffer+512));
425 #endif
426 if (CURRENT->current_nr_sectors <= 0)
427 end_request(1);
428 if (i > 0) {
429 SET_INTR(&read_intr);
430 return;
431 }
432 (void) inb_p(HD_STATUS);
433 #if (HD_DELAY > 0)
434 last_req = read_timer();
435 #endif
436 if (!QUEUE_EMPTY)
437 hd_request();
438 return;
439 }
440
441 static void write_intr(void)
442 {
443 int i;
444 int retries = 100000;
445
446 do {
447 i = (unsigned) inb_p(HD_STATUS);
448 if (i & BUSY_STAT)
449 continue;
450 if (!OK_STATUS(i))
451 break;
452 if ((CURRENT->nr_sectors <= 1) || (i & DRQ_STAT))
453 goto ok_to_write;
454 } while (--retries > 0);
455 dump_status("write_intr", i);
456 bad_rw_intr();
457 hd_request();
458 return;
459 ok_to_write:
460 CURRENT->sector++;
461 i = --CURRENT->nr_sectors;
462 --CURRENT->current_nr_sectors;
463 CURRENT->buffer += 512;
464 if (!i || (CURRENT->bh && !SUBSECTOR(i)))
465 end_request(1);
466 if (i > 0) {
467 SET_INTR(&write_intr);
468 outsw(HD_DATA,CURRENT->buffer,256);
469 sti();
470 } else {
471 #if (HD_DELAY > 0)
472 last_req = read_timer();
473 #endif
474 hd_request();
475 }
476 return;
477 }
478
479 static void recal_intr(void)
480 {
481 check_status();
482 #if (HD_DELAY > 0)
483 last_req = read_timer();
484 #endif
485 hd_request();
486 }
487
488 /*
489 * This is another of the error-routines I don't know what to do with. The
490 * best idea seems to just set reset, and start all over again.
491 */
492 static void hd_times_out(unsigned long dummy)
493 {
494 unsigned int dev;
495
496 DEVICE_INTR = NULL;
497 if (QUEUE_EMPTY)
498 return;
499 disable_irq(HD_IRQ);
500 sti();
501 reset = 1;
502 dev = DEVICE_NR(CURRENT->rq_dev);
503 printk("hd%c: timeout\n", dev+'a');
504 if (++CURRENT->errors >= MAX_ERRORS) {
505 #ifdef DEBUG
506 printk("hd%c: too many errors\n", dev+'a');
507 #endif
508 end_request(0);
509 }
510 cli();
511 hd_request();
512 enable_irq(HD_IRQ);
513 }
514
515 int do_special_op (unsigned int dev)
516 {
517 if (recalibrate[dev]) {
518 recalibrate[dev] = 0;
519 hd_out(dev,hd_info[dev].sect,0,0,0,WIN_RESTORE,&recal_intr);
520 return reset;
521 }
522 if (hd_info[dev].head > 16) {
523 printk ("hd%c: cannot handle device with more than 16 heads - giving up\n", dev+'a');
524 end_request(0);
525 }
526 special_op[dev] = 0;
527 return 1;
528 }
529
530 /*
531 * The driver enables interrupts as much as possible. In order to do this,
532 * (a) the device-interrupt is disabled before entering hd_request(),
533 * and (b) the timeout-interrupt is disabled before the sti().
534 *
535 * Interrupts are still masked (by default) whenever we are exchanging
536 * data/cmds with a drive, because some drives seem to have very poor
537 * tolerance for latency during I/O. The IDE driver has support to unmask
538 * interrupts for non-broken hardware, so use that driver if required.
539 */
540 static void hd_request(void)
541 {
542 unsigned int dev, block, nsect, sec, track, head, cyl;
543
544 if (!QUEUE_EMPTY && CURRENT->rq_status == RQ_INACTIVE) return;
545 if (DEVICE_INTR)
546 return;
547 repeat:
548 del_timer(&device_timer);
549 sti();
550 INIT_REQUEST;
551 if (reset) {
552 cli();
553 reset_hd();
554 return;
555 }
556 dev = MINOR(CURRENT->rq_dev);
557 block = CURRENT->sector;
558 nsect = CURRENT->nr_sectors;
559 if (dev >= (NR_HD<<6) || block >= hd[dev].nr_sects || ((block+nsect) > hd[dev].nr_sects)) {
560 #ifdef DEBUG
561 if (dev >= (NR_HD<<6))
562 printk("hd: bad minor number: device=%s\n",
563 kdevname(CURRENT->rq_dev));
564 else
565 printk("hd%c: bad access: block=%d, count=%d\n",
566 (MINOR(CURRENT->rq_dev)>>6)+'a', block, nsect);
567 #endif
568 end_request(0);
569 goto repeat;
570 }
571 block += hd[dev].start_sect;
572 dev >>= 6;
573 if (special_op[dev]) {
574 if (do_special_op(dev))
575 goto repeat;
576 return;
577 }
578 sec = block % hd_info[dev].sect + 1;
579 track = block / hd_info[dev].sect;
580 head = track % hd_info[dev].head;
581 cyl = track / hd_info[dev].head;
582 #ifdef DEBUG
583 printk("hd%c: %sing: CHS=%d/%d/%d, sectors=%d, buffer=0x%08lx\n",
584 dev+'a', (CURRENT->cmd == READ)?"read":"writ",
585 cyl, head, sec, nsect, (unsigned long) CURRENT->buffer);
586 #endif
587 if (CURRENT->cmd == READ) {
588 hd_out(dev,nsect,sec,head,cyl,WIN_READ,&read_intr);
589 if (reset)
590 goto repeat;
591 return;
592 }
593 if (CURRENT->cmd == WRITE) {
594 hd_out(dev,nsect,sec,head,cyl,WIN_WRITE,&write_intr);
595 if (reset)
596 goto repeat;
597 if (wait_DRQ()) {
598 bad_rw_intr();
599 goto repeat;
600 }
601 outsw(HD_DATA,CURRENT->buffer,256);
602 return;
603 }
604 panic("unknown hd-command");
605 }
606
607 static void do_hd_request (request_queue_t * q)
608 {
609 disable_irq(HD_IRQ);
610 hd_request();
611 enable_irq(HD_IRQ);
612 }
613
614 static int hd_ioctl(struct inode * inode, struct file * file,
615 unsigned int cmd, unsigned long arg)
616 {
617 struct hd_geometry *loc = (struct hd_geometry *) arg;
618 int dev;
619
620 if ((!inode) || !(inode->i_rdev))
621 return -EINVAL;
622 dev = DEVICE_NR(inode->i_rdev);
623 if (dev >= NR_HD)
624 return -EINVAL;
625 switch (cmd) {
626 case HDIO_GETGEO:
627 {
628 struct hd_geometry g;
629 if (!loc) return -EINVAL;
630 g.heads = hd_info[dev].head;
631 g.sectors = hd_info[dev].sect;
632 g.cylinders = hd_info[dev].cyl;
633 g.start = hd[MINOR(inode->i_rdev)].start_sect;
634 return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0;
635 }
636
637 case BLKGETSIZE: /* Return device size */
638 if (!arg) return -EINVAL;
639 return put_user(hd[MINOR(inode->i_rdev)].nr_sects,
640 (long *) arg);
641
642 case BLKRRPART: /* Re-read partition tables */
643 if (!capable(CAP_SYS_ADMIN))
644 return -EACCES;
645 return revalidate_hddisk(inode->i_rdev, 1);
646
647 case BLKROSET:
648 case BLKROGET:
649 case BLKRASET:
650 case BLKRAGET:
651 case BLKFLSBUF:
652 case BLKPG:
653 return blk_ioctl(inode->i_rdev, cmd, arg);
654
655 default:
656 return -EINVAL;
657 }
658 }
659
660 static int hd_open(struct inode * inode, struct file * filp)
661 {
662 int target;
663 target = DEVICE_NR(inode->i_rdev);
664
665 if (target >= NR_HD)
666 return -ENODEV;
667 while (busy[target])
668 sleep_on(&busy_wait);
669 access_count[target]++;
670 return 0;
671 }
672
673 /*
674 * Releasing a block device means we sync() it, so that it can safely
675 * be forgotten about...
676 */
677 static int hd_release(struct inode * inode, struct file * file)
678 {
679 int target = DEVICE_NR(inode->i_rdev);
680 access_count[target]--;
681 return 0;
682 }
683
684 extern struct block_device_operations hd_fops;
685
686 static struct gendisk hd_gendisk = {
687 MAJOR_NR, /* Major number */
688 "hd", /* Major name */
689 6, /* Bits to shift to get real from partition */
690 1 << 6, /* Number of partitions per real */
691 hd, /* hd struct */
692 hd_sizes, /* block sizes */
693 0, /* number */
694 NULL, /* internal use, not presently used */
695 NULL, /* next */
696 &hd_fops, /* file operations */
697 };
698
699 static void hd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
700 {
701 void (*handler)(void) = DEVICE_INTR;
702
703 DEVICE_INTR = NULL;
704 del_timer(&device_timer);
705 if (!handler)
706 handler = unexpected_hd_interrupt;
707 handler();
708 sti();
709 }
710
711 static struct block_device_operations hd_fops = {
712 open: hd_open,
713 release: hd_release,
714 ioctl: hd_ioctl,
715 };
716
717 /*
718 * This is the hard disk IRQ description. The SA_INTERRUPT in sa_flags
719 * means we run the IRQ-handler with interrupts disabled: this is bad for
720 * interrupt latency, but anything else has led to problems on some
721 * machines.
722 *
723 * We enable interrupts in some of the routines after making sure it's
724 * safe.
725 */
726 static void __init hd_geninit(void)
727 {
728 int drive;
729
730 for(drive=0; drive < (MAX_HD << 6); drive++) {
731 hd_blocksizes[drive] = 1024;
732 hd_hardsectsizes[drive] = 512;
733 }
734 blksize_size[MAJOR_NR] = hd_blocksizes;
735 hardsect_size[MAJOR_NR] = hd_hardsectsizes;
736
737 #ifdef __i386__
738 if (!NR_HD) {
739 extern struct drive_info drive_info;
740 unsigned char *BIOS = (unsigned char *) &drive_info;
741 unsigned long flags;
742 int cmos_disks;
743
744 for (drive=0 ; drive<2 ; drive++) {
745 hd_info[drive].cyl = *(unsigned short *) BIOS;
746 hd_info[drive].head = *(2+BIOS);
747 hd_info[drive].wpcom = *(unsigned short *) (5+BIOS);
748 hd_info[drive].ctl = *(8+BIOS);
749 hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
750 hd_info[drive].sect = *(14+BIOS);
751 #ifdef does_not_work_for_everybody_with_scsi_but_helps_ibm_vp
752 if (hd_info[drive].cyl && NR_HD == drive)
753 NR_HD++;
754 #endif
755 BIOS += 16;
756 }
757
758 /*
759 We query CMOS about hard disks : it could be that
760 we have a SCSI/ESDI/etc controller that is BIOS
761 compatible with ST-506, and thus showing up in our
762 BIOS table, but not register compatible, and therefore
763 not present in CMOS.
764
765 Furthermore, we will assume that our ST-506 drives
766 <if any> are the primary drives in the system, and
767 the ones reflected as drive 1 or 2.
768
769 The first drive is stored in the high nibble of CMOS
770 byte 0x12, the second in the low nibble. This will be
771 either a 4 bit drive type or 0xf indicating use byte 0x19
772 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.
773
774 Needless to say, a non-zero value means we have
775 an AT controller hard disk for that drive.
776
777 Currently the rtc_lock is a bit academic since this
778 driver is non-modular, but someday... ? Paul G.
779 */
780
781 spin_lock_irqsave(&rtc_lock, flags);
782 cmos_disks = CMOS_READ(0x12);
783 spin_unlock_irqrestore(&rtc_lock, flags);
784
785 if (cmos_disks & 0xf0) {
786 if (cmos_disks & 0x0f)
787 NR_HD = 2;
788 else
789 NR_HD = 1;
790 }
791 }
792 #endif /* __i386__ */
793 #ifdef __arm__
794 if (!NR_HD) {
795 /* We don't know anything about the drive. This means
796 * that you *MUST* specify the drive parameters to the
797 * kernel yourself.
798 */
799 printk("hd: no drives specified - use hd=cyl,head,sectors"
800 " on kernel command line\n");
801 }
802 #endif
803
804 for (drive=0 ; drive < NR_HD ; drive++) {
805 hd[drive<<6].nr_sects = hd_info[drive].head *
806 hd_info[drive].sect * hd_info[drive].cyl;
807 printk ("hd%c: %ldMB, CHS=%d/%d/%d\n", drive+'a',
808 hd[drive<<6].nr_sects / 2048, hd_info[drive].cyl,
809 hd_info[drive].head, hd_info[drive].sect);
810 }
811 if (!NR_HD)
812 return;
813
814 if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd", NULL)) {
815 printk("hd: unable to get IRQ%d for the hard disk driver\n",
816 HD_IRQ);
817 NR_HD = 0;
818 return;
819 }
820 request_region(HD_DATA, 8, "hd");
821 request_region(HD_CMD, 1, "hd(cmd)");
822
823 hd_gendisk.nr_real = NR_HD;
824
825 for(drive=0; drive < NR_HD; drive++)
826 register_disk(&hd_gendisk, MKDEV(MAJOR_NR,drive<<6), 1<<6,
827 &hd_fops, hd_info[drive].head * hd_info[drive].sect *
828 hd_info[drive].cyl);
829 }
830
831 int __init hd_init(void)
832 {
833 if (devfs_register_blkdev(MAJOR_NR,"hd",&hd_fops)) {
834 printk("hd: unable to get major %d for hard disk\n",MAJOR_NR);
835 return -1;
836 }
837 blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
838 read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */
839 hd_gendisk.next = gendisk_head;
840 gendisk_head = &hd_gendisk;
841 init_timer(&device_timer);
842 device_timer.function = hd_times_out;
843 hd_geninit();
844 return 0;
845 }
846
847 #define DEVICE_BUSY busy[target]
848 #define USAGE access_count[target]
849 #define CAPACITY (hd_info[target].head*hd_info[target].sect*hd_info[target].cyl)
850 /* We assume that the BIOS parameters do not change, so the disk capacity
851 will not change */
852 #undef MAYBE_REINIT
853 #define GENDISK_STRUCT hd_gendisk
854
855 /*
856 * This routine is called to flush all partitions and partition tables
857 * for a changed disk, and then re-read the new partition table.
858 * If we are revalidating a disk because of a media change, then we
859 * enter with usage == 0. If we are using an ioctl, we automatically have
860 * usage == 1 (we need an open channel to use an ioctl :-), so this
861 * is our limit.
862 */
863 static int revalidate_hddisk(kdev_t dev, int maxusage)
864 {
865 int target;
866 struct gendisk * gdev;
867 int max_p;
868 int start;
869 int i;
870 long flags;
871
872 target = DEVICE_NR(dev);
873 gdev = &GENDISK_STRUCT;
874
875 save_flags(flags);
876 cli();
877 if (DEVICE_BUSY || USAGE > maxusage) {
878 restore_flags(flags);
879 return -EBUSY;
880 }
881 DEVICE_BUSY = 1;
882 restore_flags(flags);
883
884 max_p = gdev->max_p;
885 start = target << gdev->minor_shift;
886
887 for (i=max_p - 1; i >=0 ; i--) {
888 int minor = start + i;
889 kdev_t devi = MKDEV(MAJOR_NR, minor);
890 struct super_block *sb = get_super(devi);
891
892 sync_dev(devi);
893 if (sb)
894 invalidate_inodes(sb);
895 invalidate_buffers(devi);
896 gdev->part[minor].start_sect = 0;
897 gdev->part[minor].nr_sects = 0;
898 }
899
900 #ifdef MAYBE_REINIT
901 MAYBE_REINIT;
902 #endif
903
904 grok_partitions(gdev, target, 1<<6, CAPACITY);
905
906 DEVICE_BUSY = 0;
907 wake_up(&busy_wait);
908 return 0;
909 }
910
911 static int parse_hd_setup (char *line) {
912 int ints[6];
913
914 (void) get_options(line, ARRAY_SIZE(ints), ints);
915 hd_setup(NULL, ints);
916
917 return 1;
918 }
919 __setup("hd=", parse_hd_setup);
920
921
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.