On Mon, Jul 09, 2007 at 01:37:32PM +0900, YONETANI Tomokazu wrote:
> After having updated to HEAD yesterday, I started seeing DMA errors
> accessing filesystems on ccd devices:
>   ata0: FAILURE - oversized DMA transfer attempt 73728 > 65536

IIUC, in old-ATA, ad_strategy took care of transfer sizes larger than
the maximum I/O size of the device, but not in NATA (I guess GEOM layer
is handling it, right?).  Adjusting si_iosize_max (initially faked to
be 131072 when attached) in ccdinit() seems to work around this problem.

Cheers.

Index: ccd.c
===================================================================
RCS file: /home/source/dragonfly/cvs/src/sys/dev/disk/ccd/ccd.c,v
retrieving revision 1.48
diff -u -r1.48 ccd.c
--- ccd.c       19 Jun 2007 19:09:46 -0000      1.48
+++ ccd.c       9 Jul 2007 11:29:55 -0000
@@ -381,6 +381,7 @@
        u_int64_t size;
        u_int64_t minsize;
        int maxsecsize;
+       int maxiosize;
        struct partinfo dpart;
        struct ccdgeom *ccg = &cs->sc_geom;
        char tmppath[MAXPATHLEN];
@@ -405,6 +406,7 @@
         */
        maxsecsize = 0;
        minsize = 0;
+       maxiosize = cs->sc_dev->si_iosize_max;
        for (ix = 0; ix < cs->sc_nccdisks; ix++) {
                vp = ccd->ccd_vpp[ix];
                ci = &cs->sc_cinfo[ix];
@@ -427,6 +429,8 @@
                bcopy(tmppath, ci->ci_path, ci->ci_pathlen);
 
                ci->ci_dev = vn_todev(vp);
+               if (maxiosize > ci->ci_dev->si_iosize_max)
+                       maxiosize = ci->ci_dev->si_iosize_max;
 
                /*
                 * Get partition information for the component.
@@ -574,6 +578,11 @@
        cs->sc_flags |= CCDF_INITED;
        cs->sc_cflags = ccd->ccd_flags; /* So we can find out later... */
        cs->sc_unit = ccd->ccd_unit;
+       if (bootverbose) {
+               kprintf("%s: ccd%d: si_iosize_max %d -> %d\n", __func__,
+                       ccd->ccd_unit, cs->sc_dev->si_iosize_max, maxiosize);
+       }
+       cs->sc_dev->si_iosize_max = maxiosize;
        return (0);
 fail:
        while (ci > cs->sc_cinfo) {

Reply via email to