SII3512 rev0 ?

Peter B pb at ludd.ltu.se
Sun Jul 1 18:03:24 UTC 2007


>NetBSD:
>	dev/pci/satalink.c
>
>        /*
>         * Rev. <= 0x01 of the 3112 have a bug that can cause data
>         * corruption if DMA transfers cross an 8K boundary.  This is
>         * apparently hard to tickle, but we'll go ahead and play it
>         * safe.
>         */
>        if (PCI_REVISION(pa->pa_class) <= 0x01) {
>                sc->sc_dma_maxsegsz = 8192;
>                sc->sc_dma_boundary = 8192;
>
>FreeBSD:
>	dev/ata/ata-chipset.c
>
>    if ((ctlr->chip->cfg2 & SIIBUG) && ch->dma) {
>        /* work around errata in early chips */
>        ch->dma->boundary = 16 * DEV_BSIZE;
>        ch->dma->segsize = 15 * DEV_BSIZE;

DEV_BSIZE = (1<<9) = 512 bytes
boundary = 8192
segsize =  7680		<- Differs by 512 bytes from NetBSD..

Anyone knows why segsize differs?

>And of course there may be other differences I didn't find.

The table used to parse pci setup:
    {{ ATA_SII3114,   0x00, SIIMEMIO, SII4CH,    ATA_SA150, "SiI 3114" },
     { ATA_SII3512,   0x02, SIIMEMIO, 0,         ATA_SA150, "SiI 3512" },
     { ATA_SII3112,   0x02, SIIMEMIO, 0,         ATA_SA150, "SiI 3112" },
     { ATA_SII3112_1, 0x02, SIIMEMIO, 0,         ATA_SA150, "SiI 3112" },
     { ATA_SII3512,   0x00, SIIMEMIO, SIIBUG,    ATA_SA150, "SiI 3512" },
     { ATA_SII3112,   0x00, SIIMEMIO, SIIBUG,    ATA_SA150, "SiI 3112" },
     { ATA_SII3112_1, 0x00, SIIMEMIO, SIIBUG,    ATA_SA150, "SiI 3112" },
     { ATA_SII3124,   0x00, SIIPRBIO, SII4CH,    ATA_SA300, "SiI 3124" },
     { ATA_SII3132,   0x00, SIIPRBIO, 0,         ATA_SA300, "SiI 3132" },

And it's parsed with this conditional:
  pci_get_revid(dev) >= index->chiprev     /* ata_match_chip() */

So for 3112 rev 0,1 SIIBUG will be enabled on FreeBSD-curr. Ie same behaviour
as for when to apply the fix.

This hw seems to be like russian roulette ;)

Maybe it would be a good idea to have chip revision displayed in the syslog
such that an sysadm can quickly spot possible troublesome hw..
  In ata_sii_ident() replace:
    sprintf(buffer, "%s %s controller", idx->text, ata_mode2str(idx->max_dma));
  With something along the lines of:
    int chiprev;
    chiprev = (int)pci_get_revid(dev);            /* assumed unfailable :) */
    sprintf(buffer, "%s rev %d %s controller",
      idx->text, chiprev, ata_mode2str(idx->max_dma) );

   /P



More information about the freebsd-hackers mailing list