Subject: Re: 1.3 apm problems
To: Johan Danielsson <joda@pdc.kth.se>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: port-i386
Date: 05/06/1998 10:34:28
On May 6, Johan Danielsson wrote
>
> After a resume there seems to be a short period (~26-27 seconds)
> during which the IDE controller (or disk or whatever) doesn't seem
> very responsive.
I suspect this is the time needed by the IDE disk to recover from
the 'sleep' mode.
> Specifically files read during that period are
> mostly garbage, for instance /etc/apm/resume. If I put a `sleep(30)'
> in apmd.c:resume(), those specific problems goes away, but this sounds
> like a more serious problem.
>
There is a problem in 1.3 and 1.3.1 with disk adress calculation. Basically,
when retrying a command after a timeout, the wrong disk adress is used
(reported by Robert V. Baron).
This is what happens at resume time: the disk time out, the command is
retried and data are read from the wrong disk block. This has been fixed
in -current, and will be fixed in 1.3.2. A patch against 1.3.1 is appended
at the end.
--
Manuel Bouyer, LIP6, Universite Paris VI. Manuel.Bouyer@lip6.fr
--
Index: wd.c
===================================================================
RCS file: /archive/cvs/cvsroot/NetBSD/src/sys/dev/isa/wd.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 wd.c
--- wd.c 1997/12/15 16:49:50 1.1.1.1
+++ wd.c 1998/04/23 11:55:27
@@ -285,7 +285,7 @@
struct buf *dp, *bp=0;
struct wd_link *d_link = wd->d_link;
struct wdc_xfer *xfer;
- u_long p_offset;
+ daddr_t blkno, p_offset;
while (d_link->openings > 0) {
@@ -304,6 +304,8 @@
wd->sc_dk.dk_label->d_partitions[WDPART(bp->b_dev)].p_offset;
else
p_offset = 0;
+ blkno = bp->b_blkno + p_offset;
+ blkno /= (wd->d_link->sc_lp->d_secsize / DEV_BSIZE);
xfer = wdc_get_xfer(0);
if (xfer == NULL)
@@ -311,11 +313,10 @@
xfer->d_link = d_link;
xfer->c_bp = bp;
- xfer->c_p_offset = p_offset;
xfer->databuf = bp->b_data;
xfer->c_bcount = bp->b_bcount;
xfer->c_flags |= bp->b_flags & (B_READ|B_WRITE);
- xfer->c_blkno = bp->b_blkno;
+ xfer->c_blkno = blkno;
/* Instrumentation. */
disk_busy(&wd->sc_dk);
Index: wdc.c
===================================================================
RCS file: /archive/cvs/cvsroot/NetBSD/src/sys/dev/isa/wdc.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 wdc.c
--- wdc.c 1998/01/26 13:45:40 1.1.1.2
+++ wdc.c 1998/04/23 11:55:31
@@ -438,15 +438,10 @@
/* When starting a transfer... */
if (xfer->c_skip == 0) {
- daddr_t blkno;
-
WDDEBUG_PRINT(("\n%s: wdc_ata_start %s %d@%d; map ",
wdc->sc_dev.dv_xname,
(xfer->c_flags & B_READ) ? "read" : "write",
xfer->c_bcount, xfer->c_blkno));
-
- blkno = xfer->c_blkno+xfer->c_p_offset;
- xfer->c_blkno = blkno / (d_link->sc_lp->d_secsize / DEV_BSIZE);
} else {
WDDEBUG_PRINT((" %d)%x", xfer->c_skip,
inb(wdc->sc_iobase + wd_altsts)));
Index: wdlink.h
===================================================================
RCS file: /archive/cvs/cvsroot/NetBSD/src/sys/dev/isa/wdlink.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 wdlink.h
--- wdlink.h 1997/12/15 16:49:51 1.1.1.1
+++ wdlink.h 1998/04/23 11:55:32
@@ -122,7 +122,6 @@
int c_skip; /* bytes already transferred */
int c_nblks; /* number of blocks currently transferring */
int c_nbytes; /* number of bytes currently transferring */
- u_long c_p_offset; /* offset of the partition */
TAILQ_ENTRY(wdc_xfer) c_xferchain;
LIST_ENTRY(wdc_xfer) free_list;
};