jwiegand@moe.eng.temple.edu
Date: 08/19/92


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