My system hangs a long time in ata_generic_reset() while resuming. I did some hunting and found that the loop was running for the full 310 * 100 ms (31 seconds). The bug is that the loop never exits when mask goes to 0 even though this is a termination condition (see end of the loop where the code masks off 1 and 2).

The attached patch fixes this by exiting when the mask is set to 0 instead of looping the full 31 seconds. This is correct since setting the mask to 0 is how the loop marks master/slave "done". It also has a minor whitespace fix.

I recorded the following set of status values (with my patch) so you can see the states the master/slave go through. Each is labeled with the if() check it is associated with. For instance, "stat0 & ATA_S_BUSY" means the first if() triggered and gives further info about the status. "start:" is at the beginning of the for().

It used to print this about 300 times while making no progress at the point labeled [] below:
start: mask 0 stat0 50 stat1 0


Here's how it looks with my patch:

ata_reinit reset
ata0: reset tp1 mask=03 ostat0=80 ostat1=00
start: mask 3 stat0 80 stat1 80
stat0 & ATA_S_BUSY: stat0 80
ad0: stat=0x80 err=0x80 lsb=0x80 msb=0x80
mask == 0x03: stat0 80 stat1 80 err 80

start: mask 3 stat0 80 stat1 80
stat0 & ATA_S_BUSY: stat0 80
ad0: stat=0x80 err=0x80 lsb=0x80 msb=0x80
mask == 0x03: stat0 80 stat1 80 err 80

start: mask 3 stat0 80 stat1 80
stat0 & ATA_S_BUSY: stat0 80
ad0: stat=0x80 err=0x80 lsb=0x80 msb=0x80
mask == 0x03: stat0 80 stat1 80 err 80

start: mask 3 stat0 80 stat1 80
stat0 & ATA_S_BUSY: stat0 80
ad0: stat=0x80 err=0x80 lsb=0x80 msb=0x80
mask == 0x03: stat0 80 stat1 80 err 80

start: mask 3 stat0 80 stat1 80
stat0 & ATA_S_BUSY: stat0 80
ad0: stat=0x80 err=0x80 lsb=0x80 msb=0x80
mask == 0x03: stat0 80 stat1 80 err 80

start: mask 3 stat0 80 stat1 80
stat0 & ATA_S_BUSY: stat0 80
ad0: stat=0x80 err=0x80 lsb=0x80 msb=0x80
mask == 0x03: stat0 80 stat1 80 err 80

start: mask 3 stat0 80 stat1 80
stat0 & ATA_S_BUSY: stat0 80
ad0: stat=0x50 err=0x01 lsb=0x00 msb=0x00
!((mask == 0x03): mask 3 stat0 50 stat1 80
ata0-slave:  stat=0x00 err=0x01 lsb=0x00 msb=0x00
mask == 0x03: stat0 50 stat1 0 err 1

[mask set to 0 in both checks, code continues but used to hang here]

ata0: reset tp2 stat0=50 stat1=00 devices=0x1<ATA_MASTER>
ata0: resetting done ..

--
Nate
Index: sys/dev/ata/ata-lowlevel.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ata/ata-lowlevel.c,v
retrieving revision 1.51
diff -u -r1.51 ata-lowlevel.c
--- sys/dev/ata/ata-lowlevel.c  24 Dec 2004 13:38:25 -0000      1.51
+++ sys/dev/ata/ata-lowlevel.c  27 Feb 2005 22:19:30 -0000
@@ -619,8 +619,10 @@
                (stat1 == err && lsb == err && msb == err && timeout > 5))
                mask &= ~0x02;
        }
+       if (mask == 0)
+           break;
        ata_udelay(100000);
-    }  
+    }
 
     if (bootverbose)
        ata_printf(ch, -1,
_______________________________________________
freebsd-stable@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-stable
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to