From: jwiegand@moe.eng.temple.edu Subject: (none) Date: Wed, 19 Aug 1992 05:40:57 GMT
RE: HD: read_intr: status = 0x51
There seems to be a problem with certain hd's that have a braindead
IDE bios. They return READY_STAT but do not clear the lower bits.
This results in silly messages like:
HD: read_intr: status = 0x51
This happened with my Brand Technologies 200 MB hard drive
and is fixed by ignoring the confused condition.
I have used this patch on MSDOS and EXTFS partitions on the BT drive
and have had no trouble backing up Linux (~150 MB of tar files)
and transferring other big numbers of files. I was waiting for someone
else to mention this before perpetrating the following on an
unsuspecting world:
*** hd.c.old Wed Aug 19 00:50:49 1992
--- hd.c Wed Aug 19 00:29:33 1992
***************
*** 248,256 ****
{
int i;
i = (unsigned) inb_p(HD_STATUS);
! if ((i & STAT_MASK) != STAT_OK) {
printk("HD: read_intr: status = 0x%02x\n",i);
goto bad_read;
}
if (wait_DRQ()) {
--- 248,256 ----
{
int i;
i = (unsigned) inb_p(HD_STATUS);
! if (((i & STAT_MASK) != STAT_OK) && !(i & READY_STAT)) {
printk("HD: read_intr: status = 0x%02x\n",i);
goto bad_read;
}
if (wait_DRQ()) {
***************
*** 259,267 ****
}
port_read(HD_DATA,CURRENT->buffer,256);
i = (unsigned) inb_p(HD_STATUS);
if (!(i & BUSY_STAT))
! if ((i & STAT_MASK) != STAT_OK) {
printk("HD: read_intr: second status = 0x%02x\n",i);
goto bad_read;
}
CURRENT->errors = 0;
--- 259,267 ----
}
port_read(HD_DATA,CURRENT->buffer,256);
i = (unsigned) inb_p(HD_STATUS);
if (!(i & BUSY_STAT))
! if (((i & STAT_MASK) != STAT_OK) && !(i & READY_STAT)) {
printk("HD: read_intr: second status = 0x%02x\n",i);
goto bad_read;
}
CURRENT->errors = 0;
***************
*** 286,294 ****
#endif
do_hd_request();
return;
bad_read:
! if (i & ERR_STAT) {
i = (unsigned) inb(HD_ERROR);
printk("HD: read_intr: error = 0x%02x\n",i);
}
bad_rw_intr();
--- 286,294 ----
#endif
do_hd_request();
return;
bad_read:
! if (i & ERR_STAT) {
i = (unsigned) inb(HD_ERROR);
printk("HD: read_intr: error = 0x%02x\n",i);
}
bad_rw_intr();
***************
*** 300,308 ****
{
int i;
i = (unsigned) inb_p(HD_STATUS);
! if ((i & STAT_MASK) != STAT_OK) {
printk("HD: write_intr: status = 0x%02x\n",i);
goto bad_write;
}
if (CURRENT->nr_sectors > 1 && wait_DRQ()) {
--- 300,308 ----
{
int i;
i = (unsigned) inb_p(HD_STATUS);
! if (((i & STAT_MASK) != STAT_OK) && !(i & READY_STAT)) {
printk("HD: write_intr: status = 0x%02x\n",i);
goto bad_write;
}
if (CURRENT->nr_sectors > 1 && wait_DRQ()) {
Of course Linus can clean this up by fiddling with the macros,
but there it is!
jim