Index: svwsata.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/svwsata.c,v retrieving revision 1.13 diff -p -r1.13 svwsata.c *** svwsata.c 4 Apr 2011 20:37:56 -0000 1.13 --- svwsata.c 4 May 2012 08:57:47 -0000 *************** __KERNEL_RCSID(0, "$NetBSD: svwsata.c,v *** 21,26 **** --- 21,27 ---- #include #include + #include #include #include *************** svwsata_chip_map(struct pciide_softc *sc *** 129,134 **** --- 130,150 ---- return; } + if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SERVERWORKS_FRODO4_SATA) { + /* + * Frodo4 has 8 ports, or so it seems. We need to allocate more + * channels space than the default. + */ + sc->sc_wdcdev.sc_atac.atac_nchannels = 8; + sc->sc_wdcdev.sc_atac.atac_channels = + kmem_alloc(sizeof(*sc->sc_wdcdev.sc_atac.atac_channels) * + sc->sc_wdcdev.sc_atac.atac_nchannels, KM_SLEEP); + } else { + sc->sc_wdcdev.sc_atac.atac_nchannels = 4; + sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; + } + sc->sc_wdcdev.sc_atac.atac_set_modes = sata_setup_channel; + aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev, "bus-master DMA support present"); svwsata_mapreg_dma(sc, pa); *************** svwsata_chip_map(struct pciide_softc *sc *** 145,154 **** sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; } - sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; - sc->sc_wdcdev.sc_atac.atac_nchannels = 4; - sc->sc_wdcdev.sc_atac.atac_set_modes = sata_setup_channel; - /* We can use SControl and SStatus to probe for drives. */ sc->sc_wdcdev.sc_atac.atac_probe = wdc_sataprobe; --- 161,166 ---- *************** svwsata_chip_map(struct pciide_softc *sc *** 190,195 **** --- 202,212 ---- } } + /* + * detach should free atac_channels if + * sc->sc_wdcdev.sc_atac.atac_channels == sc->wdc_chanarray + */ + static void svwsata_mapreg_dma(struct pciide_softc *sc, const struct pci_attach_args *pa) { *************** svwsata_mapreg_dma(struct pciide_softc * *** 216,222 **** */ sc->sc_dma_iot = sc->sc_ba5_st; ! for (chan = 0; chan < 4; chan++) { pc = &sc->pciide_channels[chan]; for (reg = 0; reg < IDEDMA_NREGS; reg++) { size = 4; --- 233,239 ---- */ sc->sc_dma_iot = sc->sc_ba5_st; ! for (chan = 0; chan < sc->sc_wdcdev.sc_atac.atac_nchannels; chan++) { pc = &sc->pciide_channels[chan]; for (reg = 0; reg < IDEDMA_NREGS; reg++) { size = 4;