4 * Copyright (C) 1991, 1992 Linus Torvalds
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.
13 * modified by Drew Eckhardt to check nr of hd's from the CMOS.
15 * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
16 * in the early extended-partition checks and added DM partitions
20 #include <linux/errno.h>
21 #include <linux/signal.h>
22 #include <linux/sched.h>
23 #include <linux/timer.h>
25 #include <linux/kernel.h>
26 #include <linux/hdreg.h>
27 #include <linux/genhd.h>
28 #include <linux/config.h>
30 #define REALLY_SLOW_IO
31 #include <asm/system.h>
33 #include <asm/segment.h>
35 #define MAJOR_NR HD_MAJOR
40 static int revalidate_hddisk(int, int);
42 static inline unsigned char CMOS_READ(unsigned char addr
)
50 #define MAX_ERRORS 16 /* Max read/write errors/sector */
51 #define RESET_FREQ 8 /* Reset controller every 8th retry */
52 #define RECAL_FREQ 4 /* Recalibrate every 4th retry */
55 static void recal_intr(void);
56 static void bad_rw_intr(void);
58 static char recalibrate
[ MAX_HD
] = { 0, };
59 static int access_count
[MAX_HD
] = {0, };
60 static char busy
[MAX_HD
] = {0, };
61 static struct wait_queue
* busy_wait
= NULL
;
64 static int hd_error
= 0;
67 unsigned long last_req
, read_timer();
71 * This struct defines the HD's and their types.
74 unsigned int head
,sect
,cyl
,wpcom
,lzone
,ctl
;
77 struct hd_i_struct hd_info
[] = { HD_TYPE
};
78 static int NR_HD
= ((sizeof (hd_info
))/(sizeof (struct hd_i_struct
)));
80 struct hd_i_struct hd_info
[] = { {0,0,0,0,0,0},{0,0,0,0,0,0} };
84 static struct hd_struct hd
[MAX_HD
<<6]={{0,0},};
85 static int hd_sizes
[MAX_HD
<<6] = {0, };
86 static int hd_blocksizes
[MAX_HD
<<6] = {0, };
89 unsigned long read_timer(void)
104 void hd_setup(char *str
, int *ints
)
110 if (hd_info
[0].head
!= 0)
112 hd_info
[hdind
].head
= ints
[2];
113 hd_info
[hdind
].sect
= ints
[3];
114 hd_info
[hdind
].cyl
= ints
[1];
115 hd_info
[hdind
].wpcom
= 0;
116 hd_info
[hdind
].lzone
= ints
[1];
117 hd_info
[hdind
].ctl
= (ints
[2] > 8 ? 8 : 0);
121 static int win_result(void)
123 int i
=inb_p(HD_STATUS
);
125 if ((i
& (BUSY_STAT
| READY_STAT
| WRERR_STAT
| SEEK_STAT
| ERR_STAT
))
126 == (READY_STAT
| SEEK_STAT
)) {
130 printk("HD: win_result: status = 0x%02x\n",i
);
132 hd_error
= inb(HD_ERROR
);
133 printk("HD: win_result: error = 0x%02x\n",hd_error
);
138 static int controller_busy(void);
139 static int status_ok(void);
141 static int controller_ready(unsigned int drive
, unsigned int head
)
146 if (controller_busy() & BUSY_STAT
)
148 outb_p(0xA0 | (drive
<<4) | head
, HD_CURRENT
);
155 static int status_ok(void)
157 unsigned char status
= inb_p(HD_STATUS
);
159 if (status
& BUSY_STAT
)
161 if (status
& WRERR_STAT
)
163 if (!(status
& READY_STAT
))
165 if (!(status
& SEEK_STAT
))
170 static int controller_busy(void)
172 int retries
= 100000;
173 unsigned char status
;
176 status
= inb_p(HD_STATUS
);
177 } while ((status
& BUSY_STAT
) && --retries
);
181 static void hd_out(unsigned int drive
,unsigned int nsect
,unsigned int sect
,
182 unsigned int head
,unsigned int cyl
,unsigned int cmd
,
183 void (*intr_addr
)(void))
187 if (drive
>1 || head
>15)
188 panic("Trying to write bad sector");
190 while (read_timer() - last_req
< HD_DELAY
)
195 if (!controller_ready(drive
, head
)) {
200 outb_p(hd_info
[drive
].ctl
,HD_CMD
);
202 outb_p(hd_info
[drive
].wpcom
>>2,++port
);
203 outb_p(nsect
,++port
);
206 outb_p(cyl
>>8,++port
);
207 outb_p(0xA0|(drive
<<4)|head
,++port
);
211 static int drive_busy(void)
216 for (i
= 0; i
< 500000 ; i
++) {
217 c
= inb_p(HD_STATUS
);
218 c
&= (BUSY_STAT
| READY_STAT
| SEEK_STAT
);
219 if (c
== (READY_STAT
| SEEK_STAT
))
222 printk("HD controller times out, status = 0x%02x\n",c
);
226 static void reset_controller(void)
230 printk(KERN_DEBUG
"HD-controller reset\n");
232 for(i
= 0; i
< 1000; i
++) nop();
233 outb(hd_info
[0].ctl
& 0x0f ,HD_CMD
);
235 printk("HD-controller still busy\n");
236 if ((hd_error
= inb(HD_ERROR
)) != 1)
237 printk("HD-controller reset failed: %02x\n",hd_error
);
240 static void reset_hd(void)
249 } else if (win_result()) {
256 hd_out(i
,hd_info
[i
].sect
,hd_info
[i
].sect
,hd_info
[i
].head
-1,
257 hd_info
[i
].cyl
,WIN_SPECIFY
,&reset_hd
);
265 * Ok, don't know what to do with the unexpected interrupts: on some machines
266 * doing a reset and a retry seems to result in an eternal loop. Right now I
267 * ignore it, and just set the timeout.
269 void unexpected_hd_interrupt(void)
272 printk(KERN_DEBUG
"Unexpected HD interrupt\n");
277 * bad_rw_intr() now tries to be a bit smarter and does things
278 * according to the error returned by the controller.
279 * -Mika Liljeberg (liljeber@cs.Helsinki.FI)
281 static void bad_rw_intr(void)
287 dev
= MINOR(CURRENT
->dev
) >> 6;
288 if (++CURRENT
->errors
>= MAX_ERRORS
|| (hd_error
& BBD_ERR
)) {
290 recalibrate
[dev
] = 1;
291 } else if (CURRENT
->errors
% RESET_FREQ
== 0)
293 else if ((hd_error
& TRK0_ERR
) || CURRENT
->errors
% RECAL_FREQ
== 0)
294 recalibrate
[dev
] = 1;
295 /* Otherwise just retry */
298 static inline int wait_DRQ(void)
300 int retries
= 100000;
302 while (--retries
> 0)
303 if (inb_p(HD_STATUS
) & DRQ_STAT
)
308 #define STAT_MASK (BUSY_STAT | READY_STAT | WRERR_STAT | SEEK_STAT | ERR_STAT)
309 #define STAT_OK (READY_STAT | SEEK_STAT)
311 static void read_intr(void)
314 int retries
= 100000;
317 i
= (unsigned) inb_p(HD_STATUS
);
320 if ((i
& STAT_MASK
) != STAT_OK
)
324 } while (--retries
> 0);
326 printk("HD: read_intr: status = 0x%02x\n",i
);
328 hd_error
= (unsigned) inb(HD_ERROR
);
329 printk("HD: read_intr: error = 0x%02x\n",hd_error
);
336 insw(HD_DATA
,CURRENT
->buffer
,256);
338 CURRENT
->buffer
+= 512;
340 i
= --CURRENT
->nr_sectors
;
341 --CURRENT
->current_nr_sectors
;
343 printk("hd%d : sector = %d, %d remaining to buffer = %08x\n",
344 MINOR(CURRENT
->dev
), CURRENT
->sector
, i
, CURRENT
->
347 if (!i
|| (CURRENT
->bh
&& !SUBSECTOR(i
)))
350 SET_INTR(&read_intr
);
354 (void) inb_p(HD_STATUS
);
356 last_req
= read_timer();
362 static void write_intr(void)
365 int retries
= 100000;
368 i
= (unsigned) inb_p(HD_STATUS
);
371 if ((i
& STAT_MASK
) != STAT_OK
)
373 if ((CURRENT
->nr_sectors
<= 1) || (i
& DRQ_STAT
))
375 } while (--retries
> 0);
377 printk("HD: write_intr: status = 0x%02x\n",i
);
379 hd_error
= (unsigned) inb(HD_ERROR
);
380 printk("HD: write_intr: error = 0x%02x\n",hd_error
);
388 i
= --CURRENT
->nr_sectors
;
389 --CURRENT
->current_nr_sectors
;
390 CURRENT
->buffer
+= 512;
391 if (!i
|| (CURRENT
->bh
&& !SUBSECTOR(i
)))
394 SET_INTR(&write_intr
);
395 outsw(HD_DATA
,CURRENT
->buffer
,256);
399 last_req
= read_timer();
406 static void recal_intr(void)
414 * This is another of the error-routines I don't know what to do with. The
415 * best idea seems to just set reset, and start all over again.
417 static void hd_times_out(void)
424 printk(KERN_DEBUG
"HD timeout\n");
426 if (++CURRENT
->errors
>= MAX_ERRORS
) {
428 printk("hd : too many errors.\n");
437 * The driver has been modified to enable interrupts a bit more: in order to
438 * do this we first (a) disable the timeout-interrupt and (b) clear the
439 * device-interrupt. This way the interrupts won't mess with out code (the
440 * worst that can happen is that an unexpected HD-interrupt comes in and
441 * sets the "reset" variable and starts the timer)
443 static void do_hd_request(void)
445 unsigned int block
,dev
;
446 unsigned int sec
,head
,cyl
,track
;
449 if (CURRENT
&& CURRENT
->dev
< 0) return;
454 timer_active
&= ~(1<<HD_TIMER
);
457 dev
= MINOR(CURRENT
->dev
);
458 block
= CURRENT
->sector
;
459 nsect
= CURRENT
->nr_sectors
;
460 if (dev
>= (NR_HD
<<6) || block
>= hd
[dev
].nr_sects
) {
462 printk("hd%d : attempted read for sector %d past end of device at sector %d.\n",
463 block
, hd
[dev
].nr_sects
);
468 block
+= hd
[dev
].start_sect
;
470 sec
= block
% hd_info
[dev
].sect
+ 1;
471 track
= block
/ hd_info
[dev
].sect
;
472 head
= track
% hd_info
[dev
].head
;
473 cyl
= track
/ hd_info
[dev
].head
;
475 printk("hd%d : cyl = %d, head = %d, sector = %d, buffer = %08x\n",
476 dev
, cyl
, head
, sec
, CURRENT
->buffer
);
482 for (i
=0; i
< NR_HD
; i
++)
488 if (recalibrate
[dev
]) {
489 recalibrate
[dev
] = 0;
490 hd_out(dev
,hd_info
[dev
].sect
,0,0,0,WIN_RESTORE
,&recal_intr
);
496 if (CURRENT
->cmd
== WRITE
) {
497 hd_out(dev
,nsect
,sec
,head
,cyl
,WIN_WRITE
,&write_intr
);
501 printk("HD: do_hd_request: no DRQ\n");
505 outsw(HD_DATA
,CURRENT
->buffer
,256);
509 if (CURRENT
->cmd
== READ
) {
510 hd_out(dev
,nsect
,sec
,head
,cyl
,WIN_READ
,&read_intr
);
516 panic("unknown hd-command");
519 static int hd_ioctl(struct inode
* inode
, struct file
* file
,
520 unsigned int cmd
, unsigned long arg
)
522 struct hd_geometry
*loc
= (struct hd_geometry
*) arg
;
527 dev
= MINOR(inode
->i_rdev
) >> 6;
532 if (!loc
) return -EINVAL
;
533 err
= verify_area(VERIFY_WRITE
, loc
, sizeof(*loc
));
536 put_fs_byte(hd_info
[dev
].head
,
537 (char *) &loc
->heads
);
538 put_fs_byte(hd_info
[dev
].sect
,
539 (char *) &loc
->sectors
);
540 put_fs_word(hd_info
[dev
].cyl
,
541 (short *) &loc
->cylinders
);
542 put_fs_long(hd
[MINOR(inode
->i_rdev
)].start_sect
,
543 (long *) &loc
->start
);
545 case BLKGETSIZE
: /* Return device size */
546 if (!arg
) return -EINVAL
;
547 err
= verify_area(VERIFY_WRITE
, (long *) arg
, sizeof(long));
550 put_fs_long(hd
[MINOR(inode
->i_rdev
)].nr_sects
,
554 if(!suser()) return -EACCES
;
555 if(!inode
->i_rdev
) return -EINVAL
;
556 fsync_dev(inode
->i_rdev
);
557 invalidate_buffers(inode
->i_rdev
);
560 case BLKRRPART
: /* Re-read partition tables */
561 return revalidate_hddisk(inode
->i_rdev
, 1);
562 RO_IOCTLS(inode
->i_rdev
,arg
);
568 static int hd_open(struct inode
* inode
, struct file
* filp
)
571 target
= DEVICE_NR(MINOR(inode
->i_rdev
));
574 sleep_on(&busy_wait
);
575 access_count
[target
]++;
580 * Releasing a block device means we sync() it, so that it can safely
581 * be forgotten about...
583 static void hd_release(struct inode
* inode
, struct file
* file
)
586 sync_dev(inode
->i_rdev
);
588 target
= DEVICE_NR(MINOR(inode
->i_rdev
));
589 access_count
[target
]--;
593 static void hd_geninit(void);
595 static struct gendisk hd_gendisk
= {
596 MAJOR_NR
, /* Major number */
597 "hd", /* Major name */
598 6, /* Bits to shift to get real from partition */
599 1 << 6, /* Number of partitions per real */
600 MAX_HD
, /* maximum number of real */
601 hd_geninit
, /* init function */
603 hd_sizes
, /* block sizes */
605 (void *) hd_info
, /* internal */
609 static void hd_interrupt(int unused
)
611 void (*handler
)(void) = DEVICE_INTR
;
614 timer_active
&= ~(1<<HD_TIMER
);
616 handler
= unexpected_hd_interrupt
;
622 * This is the harddisk IRQ description. The SA_INTERRUPT in sa_flags
623 * means we run the IRQ-handler with interrupts disabled: this is bad for
624 * interrupt latency, but anything else has led to problems on some
627 * We enable interrupts in some of the routines after making sure it's
630 static struct sigaction hd_sigaction
= {
637 static void hd_geninit(void)
640 extern struct drive_info drive_info
;
641 unsigned char *BIOS
= (unsigned char *) &drive_info
;
645 for (drive
=0 ; drive
<2 ; drive
++) {
646 hd_info
[drive
].cyl
= *(unsigned short *) BIOS
;
647 hd_info
[drive
].head
= *(2+BIOS
);
648 hd_info
[drive
].wpcom
= *(unsigned short *) (5+BIOS
);
649 hd_info
[drive
].ctl
= *(8+BIOS
);
650 hd_info
[drive
].lzone
= *(unsigned short *) (12+BIOS
);
651 hd_info
[drive
].sect
= *(14+BIOS
);
656 We querry CMOS about hard disks : it could be that
657 we have a SCSI/ESDI/etc controller that is BIOS
658 compatable with ST-506, and thus showing up in our
659 BIOS table, but not register compatable, and therefore
662 Furthurmore, we will assume that our ST-506 drives
663 <if any> are the primary drives in the system, and
664 the ones reflected as drive 1 or 2.
666 The first drive is stored in the high nibble of CMOS
667 byte 0x12, the second in the low nibble. This will be
668 either a 4 bit drive type or 0xf indicating use byte 0x19
669 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.
671 Needless to say, a non-zero value means we have
672 an AT controller hard disk for that drive.
677 if ((cmos_disks
= CMOS_READ(0x12)) & 0xf0)
678 if (cmos_disks
& 0x0f)
685 hd
[i
<<6].nr_sects
= 0;
686 if (hd_info
[i
].head
> 16) {
687 printk("hd.c: ST-506 interface disk with more than 16 heads detected,\n");
688 printk(" probably due to non-standard sector translation. Giving up.\n");
689 printk(" (disk %d: cyl=%d, sect=%d, head=%d)\n", i
,
697 hd
[i
<<6].nr_sects
= hd_info
[i
].head
*
698 hd_info
[i
].sect
*hd_info
[i
].cyl
;
701 if (irqaction(HD_IRQ
,&hd_sigaction
)) {
702 printk("hd.c: unable to get IRQ%d for the harddisk driver\n",HD_IRQ
);
706 hd_gendisk
.nr_real
= NR_HD
;
708 for(i
=0;i
<(MAX_HD
<< 6);i
++) hd_blocksizes
[i
] = 1024;
709 blksize_size
[MAJOR_NR
] = hd_blocksizes
;
712 static struct file_operations hd_fops
= {
713 NULL
, /* lseek - default */
714 block_read
, /* read - general block-dev read */
715 block_write
, /* write - general block-dev write */
716 NULL
, /* readdir - bad */
718 hd_ioctl
, /* ioctl */
721 hd_release
, /* release */
722 block_fsync
/* fsync */
725 unsigned long hd_init(unsigned long mem_start
, unsigned long mem_end
)
727 if (register_blkdev(MAJOR_NR
,"hd",&hd_fops
)) {
728 printk("Unable to get major %d for harddisk\n",MAJOR_NR
);
731 blk_dev
[MAJOR_NR
].request_fn
= DEVICE_REQUEST
;
732 read_ahead
[MAJOR_NR
] = 8; /* 8 sector (4kB) read-ahead */
733 hd_gendisk
.next
= gendisk_head
;
734 gendisk_head
= &hd_gendisk
;
735 timer_table
[HD_TIMER
].fn
= hd_times_out
;
739 #define DEVICE_BUSY busy[target]
740 #define USAGE access_count[target]
741 #define CAPACITY (hd_info[target].head*hd_info[target].sect*hd_info[target].cyl)
742 /* We assume that the the bios parameters do not change, so the disk capacity
745 #define GENDISK_STRUCT hd_gendisk
748 * This routine is called to flush all partitions and partition tables
749 * for a changed scsi disk, and then re-read the new partition table.
750 * If we are revalidating a disk because of a media change, then we
751 * enter with usage == 0. If we are using an ioctl, we automatically have
752 * usage == 1 (we need an open channel to use an ioctl :-), so this
755 static int revalidate_hddisk(int dev
, int maxusage
)
758 struct gendisk
* gdev
;
763 target
= DEVICE_NR(MINOR(dev
));
764 gdev
= &GENDISK_STRUCT
;
767 if (DEVICE_BUSY
|| USAGE
> maxusage
) {
775 start
= target
<< gdev
->minor_shift
;
776 major
= MAJOR_NR
<< 8;
778 for (i
=max_p
- 1; i
>=0 ; i
--) {
779 sync_dev(major
| start
| i
);
780 invalidate_inodes(major
| start
| i
);
781 invalidate_buffers(major
| start
| i
);
782 gdev
->part
[start
+i
].start_sect
= 0;
783 gdev
->part
[start
+i
].nr_sects
= 0;
790 gdev
->part
[start
].nr_sects
= CAPACITY
;
791 resetup_one_dev(gdev
, target
);