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 _at__at_ -619,8 +619,10 _at__at_ (stat1 == err && lsb == err && msb == err && timeout > 5)) mask &= ~0x02; } + if (mask == 0) + break; ata_udelay(100000); - } + } if (bootverbose) ata_printf(ch, -1,Received on Sun Feb 27 2005 - 21:24:35 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:29 UTC