Here is a patch of support IT8213 on NetBSD 3.x . I think that it can adapt 5.x or -current by few changes. This patch supports only PIO mode. DMA/UDMA mode are NOT supported here. Enjoy it! isaki@NetBSD.org, 2010/07 diff -u -r1.1.1.1 iteide.c --- sys/dev/pci/iteide.c 10 Jun 2005 13:22:32 -0000 1.1.1.1 +++ sys/dev/pci/iteide.c 14 Jun 2011 01:43:43 -0000 @@ -41,6 +41,7 @@ static void ite_chip_map(struct pciide_softc*, struct pci_attach_args*); static void ite_setup_channel(struct ata_channel*); +static void ite_setup_channel_8213(struct ata_channel*); static int iteide_match(struct device *, struct cfdata *, void *); static void iteide_attach(struct device *, struct device *, void *); @@ -54,6 +55,11 @@ "Integrated Technology Express IDE controller", ite_chip_map, }, + { PCI_PRODUCT_ITE_IT8213, + 0, + "Integrated Technology Express IDE controller", + ite_chip_map, + }, { 0, 0, NULL, @@ -91,6 +97,11 @@ pcireg_t interface; bus_size_t cmdsize, ctlsize; pcireg_t cfg, modectl; + int it8213 = 0; + + if (sc->sc_pp->ide_product == PCI_PRODUCT_ITE_IT8213) { + it8213 = 1; + } /* fake interface since IT8212 claims to be a RAID device */ interface = PCIIDE_INTERFACE_BUS_MASTER_DMA | @@ -120,9 +131,14 @@ sc->sc_wdcdev.sc_atac.atac_dma_cap = 2; sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; - sc->sc_wdcdev.sc_atac.atac_set_modes = ite_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; - sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + if (it8213) { + sc->sc_wdcdev.sc_atac.atac_set_modes = ite_setup_channel_8213; + sc->sc_wdcdev.sc_atac.atac_nchannels = 1; + } else { + sc->sc_wdcdev.sc_atac.atac_set_modes = ite_setup_channel; + sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + } wdc_allocate_regs(&sc->sc_wdcdev); @@ -131,7 +147,9 @@ /* Disable CPU firmware mode */ modectl &= ~IT_MODE_CPU; - pci_conf_write(sc->sc_pc, sc->sc_tag, IT_MODE, modectl); + if (!it8213) { + pci_conf_write(sc->sc_pc, sc->sc_tag, IT_MODE, modectl); + } for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels; channel++) { cp = &sc->pciide_channels[channel]; @@ -252,3 +270,67 @@ cp->dma_iohs[IDEDMA_CTL], 0, idedma_ctl); } } + +static void +ite_setup_channel_8213(struct ata_channel *chp) +{ + struct ata_drive_datas *drvp; + int drive; + struct pciide_softc *sc = CHAN_TO_PCIIDE(chp); + int piomode; + pcireg_t reg40L; + pcireg_t reg44L; + uint16_t reg40; + uint8_t reg44; + uint16_t ctltab[] = { 0x0, 0x0, 0x1, 0x3, 0x3, }; + uint16_t timingA[] = { 0, 0, 0, 1, 3, }; + uint16_t timingB[] = { 0, 0, 1, 2, 2, }; + + /* IT8213 has only 1 channel */ + KASSERT(chp->ch_channel == 0); + + reg40L = pci_conf_read(sc->sc_pc, sc->sc_tag, 0x40); + reg40 = reg40L & 0xffff; + reg44L = pci_conf_read(sc->sc_pc, sc->sc_tag, 0x44); + reg44 = reg44L & 0xff; + + for (drive = 0; drive < 2; drive++) { + drvp = &chp->ch_drive[drive]; + + /* If no drive, skip */ + if ((drvp->drive_flags & DRIVE) == 0) + continue; + + /* XXX DMA/UDMA not supported yet */ + drvp->drive_flags &= ~DRIVE_UDMA; + drvp->drive_flags &= ~DRIVE_DMA; + + piomode = drvp->PIO_mode; + if (piomode > 4) + piomode = 4; + + if (drive == 0) { + /* master */ + /* set master's Ctrl/Timing */ + reg40 &= ~0x3307; + reg40 |= ctltab[piomode]; + reg40 |= timingA[piomode] << 8; + reg40 |= timingB[piomode] << 12; + } else { + /* slave */ + reg40 |= 0x4000; /* Slave exists */ + + reg40 &= ~0x0070; + reg40 |= ctltab[piomode] << 4; + + reg44 &= ~0x0f; + reg44 |= timingA[piomode]; + reg44 |= timingB[piomode] << 2; + } + } + + reg40L = (reg40L & 0xffff0000) | reg40; + pci_conf_write(sc->sc_pc, sc->sc_tag, 0x40, reg40L); + reg44L = (reg44L & 0xffffff00) | reg44; + pci_conf_write(sc->sc_pc, sc->sc_tag, 0x44, reg44L); +} diff -u -r1.8 -r1.9 --- sys/dev/pci/pcidevs 7 Jan 2010 08:57:19 -0000 1.8 +++ sys/dev/pci/pcidevs 4 Feb 2010 07:01:13 -0000 1.9 @@ -2088,6 +2088,7 @@ /* ITE products */ product ITE IT8152 0x8152 IT8152 Host Bridge product ITE IT8212 0x8212 IT8212 IDE controller +product ITE IT8213 0x8213 IT8213 IDE controller /* I. T. T. products */ product ITT AGX016 0x0001 AGX016