Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/dreamcast/dev Set bp->b_resid properly after data t...



details:   https://anonhg.NetBSD.org/src/rev/22d0d4b74310
branches:  trunk
changeset: 757469:22d0d4b74310
user:      tsutsui <tsutsui%NetBSD.org@localhost>
date:      Tue Aug 31 12:12:48 2010 +0000

description:
Set bp->b_resid properly after data transfer is complete.
Fixes unexpected "Bad address" errors on file read ops since January 2006.

The problem is reported and tracked by Yasushi Oshima.

diffstat:

 sys/arch/dreamcast/dev/gdrom.c |  39 ++++++++++++++++++++++++---------------
 1 files changed, 24 insertions(+), 15 deletions(-)

diffs (135 lines):

diff -r 86e896841314 -r 22d0d4b74310 sys/arch/dreamcast/dev/gdrom.c
--- a/sys/arch/dreamcast/dev/gdrom.c    Tue Aug 31 07:48:23 2010 +0000
+++ b/sys/arch/dreamcast/dev/gdrom.c    Tue Aug 31 12:12:48 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: gdrom.c,v 1.26 2008/08/01 20:19:49 marcus Exp $        */
+/*     $NetBSD: gdrom.c,v 1.27 2010/08/31 12:12:48 tsutsui Exp $       */
 
 /*-
  * Copyright (c) 2001 Marcus Comstedt
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: gdrom.c,v 1.26 2008/08/01 20:19:49 marcus Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gdrom.c,v 1.27 2010/08/31 12:12:48 tsutsui Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -118,10 +118,12 @@
 #define GDROM_COND     GDROM(0x9c)
 
 int    gdrom_getstat(void);
-int    gdrom_do_command(struct gdrom_softc *, void *, void *, unsigned int);
-int    gdrom_command_sense(struct gdrom_softc *, void *, void *, unsigned int);
+int    gdrom_do_command(struct gdrom_softc *, void *, void *, unsigned int,
+           int *);
+int    gdrom_command_sense(struct gdrom_softc *, void *, void *, unsigned int,
+           int *);
 int    gdrom_read_toc(struct gdrom_softc *, struct gd_toc *);
-int    gdrom_read_sectors(struct gdrom_softc *, void *, int, int);
+int    gdrom_read_sectors(struct gdrom_softc *, void *, int, int, int *);
 int    gdrom_mount_disk(struct gdrom_softc *);
 int    gdrom_intr(void *);
 
@@ -202,7 +204,7 @@
 
 
 int gdrom_do_command(struct gdrom_softc *sc, void *req, void *buf,
-    unsigned int nbyt)
+    unsigned int nbyt, int *resid)
 {
        int i, s;
        short *ptr = req;
@@ -239,12 +241,15 @@
 
        splx(s);
 
+       if (resid != NULL)
+               *resid = sc->cmd_result_size;
+
        return sc->cmd_cond;
 }
 
 
 int gdrom_command_sense(struct gdrom_softc *sc, void *req, void *buf,
-    unsigned int nbyt)
+    unsigned int nbyt, int *resid)
 {
        /* 76543210 76543210
           0   0x13      -
@@ -257,7 +262,7 @@
        unsigned char cmd[12];
        int sense_key, sense_specific;
 
-       int cond = gdrom_do_command(sc, req, buf, nbyt);
+       int cond = gdrom_do_command(sc, req, buf, nbyt, resid);
 
        if (cond < 0) {
 #ifdef GDROMDEBUG
@@ -278,7 +283,7 @@
        cmd[0] = 0x13;
        cmd[4] = sizeof(sense_data);
        
-       gdrom_do_command(sc, cmd, sense_data, sizeof(sense_data));
+       gdrom_do_command(sc, cmd, sense_data, sizeof(sense_data), NULL);
        
        sense_key = sense_data[1] & 0xf;
        sense_specific = sense_data[4];
@@ -314,10 +319,11 @@
        cmd[3] = sizeof(struct gd_toc) >> 8;
        cmd[4] = sizeof(struct gd_toc) & 0xff;
        
-       return gdrom_command_sense(sc, cmd, toc, sizeof(struct gd_toc));
+       return gdrom_command_sense(sc, cmd, toc, sizeof(struct gd_toc), NULL);
 }
 
-int gdrom_read_sectors(struct gdrom_softc *sc, void *buf, int sector, int cnt)
+int gdrom_read_sectors(struct gdrom_softc *sc, void *buf, int sector, int cnt,
+    int *resid)
 {
        /* 76543210 76543210
           0   0x30    datafmt
@@ -339,7 +345,7 @@
        cmd[9] = cnt>>8;
        cmd[10] = cnt;
 
-       return gdrom_command_sense(sc, cmd, buf, cnt << 11);
+       return gdrom_command_sense(sc, cmd, buf, cnt << 11, resid);
 }
 
 int gdrom_mount_disk(struct gdrom_softc *sc)
@@ -358,7 +364,7 @@
        cmd[0] = 0x70;
        cmd[1] = 0x1f;
        
-       return gdrom_command_sense(sc, cmd, NULL, 0);
+       return gdrom_command_sense(sc, cmd, NULL, 0, NULL);
 }
 
 int
@@ -468,7 +474,7 @@
 gdromstrategy(struct buf *bp)
 {
        struct gdrom_softc *sc;
-       int s, unit, error;
+       int s, unit, error, resid;
 #ifdef GDROMDEBUG
        printf("GDROM: strategy\n");
 #endif
@@ -493,11 +499,14 @@
        splx(s);
 
        if ((error = gdrom_read_sectors(sc, bp->b_data, bp->b_rawblkno,
-           bp->b_bcount >> 11)))
+           bp->b_bcount >> 11, &resid)))
                bp->b_error = error;
 
        sc->is_busy = 0;
        wakeup(&sc->is_busy);
+       bp->b_resid = resid;
+       biodone(bp);
+       return;
 
  done:
        bp->b_resid = bp->b_bcount;



Home | Main Index | Thread Index | Old Index