[BACK]Return to pciide.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/pciide.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: pciide.c,v 1.272 2007/07/02 14:01:14 dlg Exp $        */
        !             2: /*     $NetBSD: pciide.c,v 1.127 2001/08/03 01:31:08 tsutsui Exp $     */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1999, 2000, 2001 Manuel Bouyer.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  * 3. All advertising materials mentioning features or use of this software
        !            16:  *    must display the following acknowledgement:
        !            17:  *     This product includes software developed by Manuel Bouyer.
        !            18:  * 4. Neither the name of the University nor the names of its contributors
        !            19:  *    may be used to endorse or promote products derived from this software
        !            20:  *    without specific prior written permission.
        !            21:  *
        !            22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            31:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            32:  *
        !            33:  */
        !            34:
        !            35: /*
        !            36:  * Copyright (c) 1996, 1998 Christopher G. Demetriou.  All rights reserved.
        !            37:  *
        !            38:  * Redistribution and use in source and binary forms, with or without
        !            39:  * modification, are permitted provided that the following conditions
        !            40:  * are met:
        !            41:  * 1. Redistributions of source code must retain the above copyright
        !            42:  *    notice, this list of conditions and the following disclaimer.
        !            43:  * 2. Redistributions in binary form must reproduce the above copyright
        !            44:  *    notice, this list of conditions and the following disclaimer in the
        !            45:  *    documentation and/or other materials provided with the distribution.
        !            46:  * 3. All advertising materials mentioning features or use of this software
        !            47:  *    must display the following acknowledgement:
        !            48:  *      This product includes software developed by Christopher G. Demetriou
        !            49:  *     for the NetBSD Project.
        !            50:  * 4. The name of the author may not be used to endorse or promote products
        !            51:  *    derived from this software without specific prior written permission
        !            52:  *
        !            53:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            54:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            55:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            56:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            57:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            58:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            59:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            60:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            61:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            62:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            63:  */
        !            64:
        !            65: /*
        !            66:  * PCI IDE controller driver.
        !            67:  *
        !            68:  * Author: Christopher G. Demetriou, March 2, 1998 (derived from NetBSD
        !            69:  * sys/dev/pci/ppb.c, revision 1.16).
        !            70:  *
        !            71:  * See "PCI IDE Controller Specification, Revision 1.0 3/4/94" and
        !            72:  * "Programming Interface for Bus Master IDE Controller, Revision 1.0
        !            73:  * 5/16/94" from the PCI SIG.
        !            74:  *
        !            75:  */
        !            76:
        !            77: #define DEBUG_DMA      0x01
        !            78: #define DEBUG_XFERS    0x02
        !            79: #define DEBUG_FUNCS    0x08
        !            80: #define DEBUG_PROBE    0x10
        !            81:
        !            82: #ifdef WDCDEBUG
        !            83: #ifndef WDCDEBUG_PCIIDE_MASK
        !            84: #define WDCDEBUG_PCIIDE_MASK 0x00
        !            85: #endif
        !            86: int wdcdebug_pciide_mask = WDCDEBUG_PCIIDE_MASK;
        !            87: #define WDCDEBUG_PRINT(args, level) do {               \
        !            88:        if ((wdcdebug_pciide_mask & (level)) != 0)      \
        !            89:                printf args;                            \
        !            90: } while (0)
        !            91: #else
        !            92: #define WDCDEBUG_PRINT(args, level)
        !            93: #endif
        !            94: #include <sys/param.h>
        !            95: #include <sys/systm.h>
        !            96: #include <sys/device.h>
        !            97: #include <sys/malloc.h>
        !            98:
        !            99: #include <machine/bus.h>
        !           100: #include <machine/endian.h>
        !           101:
        !           102: #include <dev/ata/atavar.h>
        !           103: #include <dev/ata/satareg.h>
        !           104: #include <dev/ic/wdcreg.h>
        !           105: #include <dev/ic/wdcvar.h>
        !           106:
        !           107: #include <dev/pci/pcireg.h>
        !           108: #include <dev/pci/pcivar.h>
        !           109: #include <dev/pci/pcidevs.h>
        !           110:
        !           111: #if defined(SMALL_KERNEL)
        !           112: #define        INLINE
        !           113: #else
        !           114: #define        INLINE __inline
        !           115: #endif
        !           116:
        !           117: #include <dev/pci/pciidereg.h>
        !           118: #include <dev/pci/pciidevar.h>
        !           119: #include <dev/pci/pciide_piix_reg.h>
        !           120: #include <dev/pci/pciide_amd_reg.h>
        !           121: #include <dev/pci/pciide_apollo_reg.h>
        !           122: #include <dev/pci/pciide_cmd_reg.h>
        !           123: #include <dev/pci/pciide_sii3112_reg.h>
        !           124: #include <dev/pci/pciide_cy693_reg.h>
        !           125: #include <dev/pci/pciide_sis_reg.h>
        !           126: #include <dev/pci/pciide_acer_reg.h>
        !           127: #include <dev/pci/pciide_pdc202xx_reg.h>
        !           128: #include <dev/pci/pciide_opti_reg.h>
        !           129: #include <dev/pci/pciide_hpt_reg.h>
        !           130: #include <dev/pci/pciide_acard_reg.h>
        !           131: #include <dev/pci/pciide_natsemi_reg.h>
        !           132: #include <dev/pci/pciide_nforce_reg.h>
        !           133: #include <dev/pci/pciide_i31244_reg.h>
        !           134: #include <dev/pci/pciide_ite_reg.h>
        !           135: #include <dev/pci/pciide_ixp_reg.h>
        !           136: #include <dev/pci/pciide_svwsata_reg.h>
        !           137: #include <dev/pci/pciide_jmicron_reg.h>
        !           138: #include <dev/pci/cy82c693var.h>
        !           139:
        !           140: /* inlines for reading/writing 8-bit PCI registers */
        !           141:
        !           142: static INLINE u_int8_t pciide_pci_read(pci_chipset_tag_t, pcitag_t,
        !           143:                                        int);
        !           144: static INLINE void pciide_pci_write(pci_chipset_tag_t, pcitag_t,
        !           145:                                        int, u_int8_t);
        !           146:
        !           147: static INLINE u_int8_t
        !           148: pciide_pci_read(pci_chipset_tag_t pc, pcitag_t pa, int reg)
        !           149: {
        !           150:        return (pci_conf_read(pc, pa, (reg & ~0x03)) >>
        !           151:            ((reg & 0x03) * 8) & 0xff);
        !           152: }
        !           153:
        !           154: static INLINE void
        !           155: pciide_pci_write(pci_chipset_tag_t pc, pcitag_t pa, int reg, u_int8_t val)
        !           156: {
        !           157:        pcireg_t pcival;
        !           158:
        !           159:        pcival = pci_conf_read(pc, pa, (reg & ~0x03));
        !           160:        pcival &= ~(0xff << ((reg & 0x03) * 8));
        !           161:        pcival |= (val << ((reg & 0x03) * 8));
        !           162:        pci_conf_write(pc, pa, (reg & ~0x03), pcival);
        !           163: }
        !           164:
        !           165: void default_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           166:
        !           167: void sata_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           168: void sata_setup_channel(struct channel_softc *);
        !           169:
        !           170: void piix_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           171: void piixsata_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           172: void piix_setup_channel(struct channel_softc *);
        !           173: void piix3_4_setup_channel(struct channel_softc *);
        !           174: void piix_timing_debug(struct pciide_softc *);
        !           175:
        !           176: static u_int32_t piix_setup_idetim_timings(u_int8_t, u_int8_t, u_int8_t);
        !           177: static u_int32_t piix_setup_idetim_drvs(struct ata_drive_datas *);
        !           178: static u_int32_t piix_setup_sidetim_timings(u_int8_t, u_int8_t, u_int8_t);
        !           179:
        !           180: void amd756_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           181: void amd756_setup_channel(struct channel_softc *);
        !           182:
        !           183: void apollo_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           184: void apollo_setup_channel(struct channel_softc *);
        !           185:
        !           186: void cmd_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           187: void cmd0643_9_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           188: void cmd0643_9_setup_channel(struct channel_softc *);
        !           189: void cmd680_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           190: void cmd680_setup_channel(struct channel_softc *);
        !           191: void cmd680_channel_map(struct pci_attach_args *, struct pciide_softc *, int);
        !           192: void cmd_channel_map(struct pci_attach_args *,
        !           193:                        struct pciide_softc *, int);
        !           194: int  cmd_pci_intr(void *);
        !           195: void cmd646_9_irqack(struct channel_softc *);
        !           196:
        !           197: void sii_fixup_cacheline(struct pciide_softc *, struct pci_attach_args *);
        !           198: void sii3112_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           199: void sii3112_setup_channel(struct channel_softc *);
        !           200: void sii3112_drv_probe(struct channel_softc *);
        !           201: void sii3114_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           202: void sii3114_mapreg_dma(struct pciide_softc *, struct pci_attach_args *);
        !           203: int  sii3114_chansetup(struct pciide_softc *, int);
        !           204: void sii3114_mapchan(struct pciide_channel *);
        !           205: u_int8_t sii3114_dmacmd_read(struct pciide_softc *, int);
        !           206: void sii3114_dmacmd_write(struct pciide_softc *, int, u_int8_t);
        !           207: u_int8_t sii3114_dmactl_read(struct pciide_softc *, int);
        !           208: void sii3114_dmactl_write(struct pciide_softc *, int, u_int8_t);
        !           209: void sii3114_dmatbl_write(struct pciide_softc *, int, u_int32_t);
        !           210:
        !           211: void cy693_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           212: void cy693_setup_channel(struct channel_softc *);
        !           213:
        !           214: void sis_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           215: void sis_setup_channel(struct channel_softc *);
        !           216: void sis96x_setup_channel(struct channel_softc *);
        !           217: int  sis_hostbr_match(struct pci_attach_args *);
        !           218: int  sis_south_match(struct pci_attach_args *);
        !           219:
        !           220: void natsemi_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           221: void natsemi_setup_channel(struct channel_softc *);
        !           222: int  natsemi_pci_intr(void *);
        !           223: void natsemi_irqack(struct channel_softc *);
        !           224: void ns_scx200_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           225: void ns_scx200_setup_channel(struct channel_softc *);
        !           226:
        !           227: void acer_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           228: void acer_setup_channel(struct channel_softc *);
        !           229: int  acer_pci_intr(void *);
        !           230:
        !           231: void pdc202xx_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           232: void pdc202xx_setup_channel(struct channel_softc *);
        !           233: void pdc20268_setup_channel(struct channel_softc *);
        !           234: int  pdc202xx_pci_intr(void *);
        !           235: int  pdc20265_pci_intr(void *);
        !           236: void pdc20262_dma_start(void *, int, int);
        !           237: int  pdc20262_dma_finish(void *, int, int, int);
        !           238:
        !           239: void pdcsata_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           240: void pdc203xx_setup_channel(struct channel_softc *);
        !           241: int  pdc203xx_pci_intr(void *);
        !           242: void pdc203xx_irqack(struct channel_softc *);
        !           243: void pdc203xx_dma_start(void *,int ,int);
        !           244: int  pdc203xx_dma_finish(void *, int, int, int);
        !           245: int  pdc205xx_pci_intr(void *);
        !           246: void pdc205xx_do_reset(struct channel_softc *);
        !           247: void pdc205xx_drv_probe(struct channel_softc *);
        !           248:
        !           249: void opti_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           250: void opti_setup_channel(struct channel_softc *);
        !           251:
        !           252: void hpt_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           253: void hpt_setup_channel(struct channel_softc *);
        !           254: int  hpt_pci_intr(void *);
        !           255:
        !           256: void acard_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           257: void acard_setup_channel(struct channel_softc *);
        !           258:
        !           259: void serverworks_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           260: void serverworks_setup_channel(struct channel_softc *);
        !           261: int  serverworks_pci_intr(void *);
        !           262:
        !           263: void svwsata_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           264: void svwsata_mapreg_dma(struct pciide_softc *, struct pci_attach_args *);
        !           265: void svwsata_mapchan(struct pciide_channel *);
        !           266: u_int8_t svwsata_dmacmd_read(struct pciide_softc *, int);
        !           267: void svwsata_dmacmd_write(struct pciide_softc *, int, u_int8_t);
        !           268: u_int8_t svwsata_dmactl_read(struct pciide_softc *, int);
        !           269: void svwsata_dmactl_write(struct pciide_softc *, int, u_int8_t);
        !           270: void svwsata_dmatbl_write(struct pciide_softc *, int, u_int32_t);
        !           271: void svwsata_drv_probe(struct channel_softc *);
        !           272:
        !           273: void nforce_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           274: void nforce_setup_channel(struct channel_softc *);
        !           275: int  nforce_pci_intr(void *);
        !           276:
        !           277: void artisea_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           278:
        !           279: void ite_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           280: void ite_setup_channel(struct channel_softc *);
        !           281:
        !           282: void ixp_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           283: void ixp_setup_channel(struct channel_softc *);
        !           284:
        !           285: void jmicron_chip_map(struct pciide_softc *, struct pci_attach_args *);
        !           286: void jmicron_setup_channel(struct channel_softc *);
        !           287:
        !           288: u_int8_t pciide_dmacmd_read(struct pciide_softc *, int);
        !           289: void pciide_dmacmd_write(struct pciide_softc *, int, u_int8_t);
        !           290: u_int8_t pciide_dmactl_read(struct pciide_softc *, int);
        !           291: void pciide_dmactl_write(struct pciide_softc *, int, u_int8_t);
        !           292: void pciide_dmatbl_write(struct pciide_softc *, int, u_int32_t);
        !           293:
        !           294: void pciide_channel_dma_setup(struct pciide_channel *);
        !           295: int  pciide_dma_table_setup(struct pciide_softc *, int, int);
        !           296: int  pciide_dma_init(void *, int, int, void *, size_t, int);
        !           297: void pciide_dma_start(void *, int, int);
        !           298: int  pciide_dma_finish(void *, int, int, int);
        !           299: void pciide_irqack(struct channel_softc *);
        !           300: void pciide_print_modes(struct pciide_channel *);
        !           301: void pciide_print_channels(int, pcireg_t);
        !           302:
        !           303: struct pciide_product_desc {
        !           304:        u_int32_t ide_product;
        !           305:        u_short ide_flags;
        !           306:        /* map and setup chip, probe drives */
        !           307:        void (*chip_map)(struct pciide_softc *, struct pci_attach_args *);
        !           308: };
        !           309:
        !           310: /* Flags for ide_flags */
        !           311: #define IDE_PCI_CLASS_OVERRIDE 0x0001  /* accept even if class != pciide */
        !           312: #define IDE_16BIT_IOSPACE      0x0002  /* I/O space BARS ignore upper word */
        !           313:
        !           314: /* Default product description for devices not known from this controller */
        !           315: const struct pciide_product_desc default_product_desc = {
        !           316:        0,                              /* Generic PCI IDE controller */
        !           317:        0,
        !           318:        default_chip_map
        !           319: };
        !           320:
        !           321: const struct pciide_product_desc pciide_intel_products[] =  {
        !           322:        { PCI_PRODUCT_INTEL_31244,      /* Intel 31244 SATA */
        !           323:          0,
        !           324:          artisea_chip_map
        !           325:        },
        !           326:        { PCI_PRODUCT_INTEL_82092AA,    /* Intel 82092AA IDE */
        !           327:          0,
        !           328:          default_chip_map
        !           329:        },
        !           330:        { PCI_PRODUCT_INTEL_82371FB_IDE, /* Intel 82371FB IDE (PIIX) */
        !           331:          0,
        !           332:          piix_chip_map
        !           333:        },
        !           334:        { PCI_PRODUCT_INTEL_82371FB_ISA, /* Intel 82371FB IDE (PIIX) */
        !           335:          0,
        !           336:          piix_chip_map
        !           337:        },
        !           338:        { PCI_PRODUCT_INTEL_82372FB_IDE, /* Intel 82372FB IDE (PIIX4) */
        !           339:          0,
        !           340:          piix_chip_map
        !           341:        },
        !           342:        { PCI_PRODUCT_INTEL_82371SB_IDE, /* Intel 82371SB IDE (PIIX3) */
        !           343:          0,
        !           344:          piix_chip_map
        !           345:        },
        !           346:        { PCI_PRODUCT_INTEL_82371AB_IDE, /* Intel 82371AB IDE (PIIX4) */
        !           347:          0,
        !           348:          piix_chip_map
        !           349:        },
        !           350:        { PCI_PRODUCT_INTEL_82371MX, /* Intel 82371MX IDE */
        !           351:          0,
        !           352:          piix_chip_map
        !           353:        },
        !           354:        { PCI_PRODUCT_INTEL_82440MX_IDE, /* Intel 82440MX IDE */
        !           355:          0,
        !           356:          piix_chip_map
        !           357:        },
        !           358:        { PCI_PRODUCT_INTEL_82451NX, /* Intel 82451NX (PIIX4) IDE */
        !           359:          0,
        !           360:          piix_chip_map
        !           361:        },
        !           362:        { PCI_PRODUCT_INTEL_82801AA_IDE, /* Intel 82801AA IDE (ICH) */
        !           363:          0,
        !           364:          piix_chip_map
        !           365:        },
        !           366:        { PCI_PRODUCT_INTEL_82801AB_IDE, /* Intel 82801AB IDE (ICH0) */
        !           367:          0,
        !           368:          piix_chip_map
        !           369:        },
        !           370:        { PCI_PRODUCT_INTEL_82801BAM_IDE, /* Intel 82801BAM IDE (ICH2) */
        !           371:          0,
        !           372:          piix_chip_map
        !           373:        },
        !           374:        { PCI_PRODUCT_INTEL_82801BA_IDE, /* Intel 82801BA IDE (ICH2) */
        !           375:          0,
        !           376:          piix_chip_map
        !           377:        },
        !           378:        { PCI_PRODUCT_INTEL_82801CAM_IDE, /* Intel 82801CAM IDE (ICH3) */
        !           379:          0,
        !           380:          piix_chip_map
        !           381:        },
        !           382:        { PCI_PRODUCT_INTEL_82801CA_IDE, /* Intel 82801CA IDE (ICH3) */
        !           383:          0,
        !           384:          piix_chip_map
        !           385:        },
        !           386:        { PCI_PRODUCT_INTEL_82801DB_IDE, /* Intel 82801DB IDE (ICH4) */
        !           387:          0,
        !           388:          piix_chip_map
        !           389:        },
        !           390:        { PCI_PRODUCT_INTEL_82801DBL_IDE, /* Intel 82801DBL IDE (ICH4-L) */
        !           391:          0,
        !           392:          piix_chip_map
        !           393:        },
        !           394:        { PCI_PRODUCT_INTEL_82801DBM_IDE, /* Intel 82801DBM IDE (ICH4-M) */
        !           395:          0,
        !           396:          piix_chip_map
        !           397:        },
        !           398:        { PCI_PRODUCT_INTEL_82801EB_IDE, /* Intel 82801EB/ER (ICH5/5R) IDE */
        !           399:          0,
        !           400:          piix_chip_map
        !           401:        },
        !           402:        { PCI_PRODUCT_INTEL_82801EB_SATA, /* Intel 82801EB (ICH5) SATA */
        !           403:          0,
        !           404:          piixsata_chip_map
        !           405:        },
        !           406:        { PCI_PRODUCT_INTEL_82801ER_SATA, /* Intel 82801ER (ICH5R) SATA */
        !           407:          IDE_PCI_CLASS_OVERRIDE,
        !           408:          piixsata_chip_map
        !           409:        },
        !           410:        { PCI_PRODUCT_INTEL_6300ESB_IDE, /* Intel 6300ESB IDE */
        !           411:          IDE_PCI_CLASS_OVERRIDE,
        !           412:          piix_chip_map
        !           413:        },
        !           414:        { PCI_PRODUCT_INTEL_6300ESB_SATA, /* Intel 6300ESB SATA */
        !           415:          IDE_PCI_CLASS_OVERRIDE,
        !           416:          piixsata_chip_map
        !           417:        },
        !           418:        { PCI_PRODUCT_INTEL_6300ESB_SATA2, /* Intel 6300ESB SATA */
        !           419:          IDE_PCI_CLASS_OVERRIDE,
        !           420:          piixsata_chip_map
        !           421:        },
        !           422:        { PCI_PRODUCT_INTEL_6321ESB_IDE, /* Intel 6321ESB IDE */
        !           423:          IDE_PCI_CLASS_OVERRIDE,
        !           424:          piix_chip_map
        !           425:        },
        !           426:        { PCI_PRODUCT_INTEL_82801FB_IDE,  /* Intel 82801FB (ICH6) IDE */
        !           427:          IDE_PCI_CLASS_OVERRIDE,
        !           428:          piix_chip_map
        !           429:        },
        !           430:        { PCI_PRODUCT_INTEL_82801FBM_SATA,  /* Intel 82801FBM (ICH6M) SATA */
        !           431:          IDE_PCI_CLASS_OVERRIDE,
        !           432:          piixsata_chip_map
        !           433:        },
        !           434:        { PCI_PRODUCT_INTEL_82801FB_SATA, /* Intel 82801FB (ICH6) SATA */
        !           435:          IDE_PCI_CLASS_OVERRIDE,
        !           436:          piixsata_chip_map
        !           437:        },
        !           438:        { PCI_PRODUCT_INTEL_82801FR_SATA, /* Intel 82801FR (ICH6R) SATA */
        !           439:          IDE_PCI_CLASS_OVERRIDE,
        !           440:          piixsata_chip_map
        !           441:        },
        !           442:        { PCI_PRODUCT_INTEL_82801GB_IDE,  /* Intel 82801GB (ICH7) IDE */
        !           443:          IDE_PCI_CLASS_OVERRIDE,
        !           444:          piix_chip_map
        !           445:        },
        !           446:        { PCI_PRODUCT_INTEL_82801GB_SATA, /* Intel 82801GB (ICH7) SATA */
        !           447:          IDE_PCI_CLASS_OVERRIDE,
        !           448:          piixsata_chip_map
        !           449:        },
        !           450:        { PCI_PRODUCT_INTEL_82801GR_SATA, /* Intel 82801GR (ICH7R) SATA */
        !           451:          IDE_PCI_CLASS_OVERRIDE,
        !           452:          piixsata_chip_map
        !           453:        },
        !           454:        { PCI_PRODUCT_INTEL_82801GR_AHCI, /* Intel 82801GR (ICH7R) AHCI */
        !           455:          IDE_PCI_CLASS_OVERRIDE,
        !           456:          piixsata_chip_map
        !           457:        },
        !           458:        { PCI_PRODUCT_INTEL_82801GBM_SATA, /* Intel 82801GBM (ICH7M) SATA */
        !           459:          IDE_PCI_CLASS_OVERRIDE,
        !           460:          piixsata_chip_map
        !           461:        },
        !           462:        { PCI_PRODUCT_INTEL_82801GBM_AHCI, /* Intel 82801GBM (ICH7M) AHCI */
        !           463:          IDE_PCI_CLASS_OVERRIDE,
        !           464:          piixsata_chip_map
        !           465:        },
        !           466:        { PCI_PRODUCT_INTEL_82801GHM_RAID, /* Intel 82801GHM (ICH7-M DH) SATA */
        !           467:          IDE_PCI_CLASS_OVERRIDE,
        !           468:          piixsata_chip_map
        !           469:        },
        !           470:        { PCI_PRODUCT_INTEL_82801H_SATA_1_6P, /* Intel 82801H (ICH8) SATA */
        !           471:          IDE_PCI_CLASS_OVERRIDE,
        !           472:          piixsata_chip_map
        !           473:        },
        !           474:        { PCI_PRODUCT_INTEL_82801H_AHCI, /* Intel 82801H (ICH8) AHCI */
        !           475:          IDE_PCI_CLASS_OVERRIDE,
        !           476:          piixsata_chip_map
        !           477:        },
        !           478:        { PCI_PRODUCT_INTEL_82801H_RAID, /* Intel 82801H (ICH8) SATA */
        !           479:          IDE_PCI_CLASS_OVERRIDE,
        !           480:          piixsata_chip_map
        !           481:        },
        !           482:        { PCI_PRODUCT_INTEL_82801H_SATA_1_4P, /* Intel 82801H (ICH8) SATA */
        !           483:          IDE_PCI_CLASS_OVERRIDE,
        !           484:          piixsata_chip_map
        !           485:        },
        !           486:        { PCI_PRODUCT_INTEL_82801H_SATA_2, /* Intel 82801H (ICH8) SATA */
        !           487:          IDE_PCI_CLASS_OVERRIDE,
        !           488:          piixsata_chip_map
        !           489:        },
        !           490:        { PCI_PRODUCT_INTEL_82801HBM_SATA_1, /* Intel 82801HBM (ICH8M) SATA */
        !           491:          IDE_PCI_CLASS_OVERRIDE,
        !           492:          piixsata_chip_map
        !           493:        },
        !           494:        { PCI_PRODUCT_INTEL_82801HBM_SATA_2, /* Intel 82801HBM (ICH8M) SATA */
        !           495:          IDE_PCI_CLASS_OVERRIDE,
        !           496:          piixsata_chip_map
        !           497:        },
        !           498:        { PCI_PRODUCT_INTEL_82801HBM_IDE, /* Intel 82801HBM (ICH8M) IDE */
        !           499:          0,
        !           500:          piix_chip_map
        !           501:        },
        !           502:        { PCI_PRODUCT_INTEL_6321ESB_SATA, /* Intel 6321ESB SATA */
        !           503:          0,
        !           504:          piixsata_chip_map
        !           505:        }
        !           506: };
        !           507:
        !           508: const struct pciide_product_desc pciide_amd_products[] =  {
        !           509:        { PCI_PRODUCT_AMD_PBC756_IDE,   /* AMD 756 */
        !           510:          0,
        !           511:          amd756_chip_map
        !           512:        },
        !           513:        { PCI_PRODUCT_AMD_766_IDE, /* AMD 766 */
        !           514:          0,
        !           515:          amd756_chip_map
        !           516:        },
        !           517:        { PCI_PRODUCT_AMD_PBC768_IDE,
        !           518:          0,
        !           519:          amd756_chip_map
        !           520:        },
        !           521:        { PCI_PRODUCT_AMD_8111_IDE,
        !           522:          0,
        !           523:          amd756_chip_map
        !           524:        },
        !           525:        { PCI_PRODUCT_AMD_CS5536_IDE,
        !           526:          0,
        !           527:          amd756_chip_map
        !           528:        }
        !           529: };
        !           530:
        !           531: #ifdef notyet
        !           532: const struct pciide_product_desc pciide_opti_products[] = {
        !           533:
        !           534:        { PCI_PRODUCT_OPTI_82C621,
        !           535:          0,
        !           536:          opti_chip_map
        !           537:        },
        !           538:        { PCI_PRODUCT_OPTI_82C568,
        !           539:          0,
        !           540:          opti_chip_map
        !           541:        },
        !           542:        { PCI_PRODUCT_OPTI_82D568,
        !           543:          0,
        !           544:          opti_chip_map
        !           545:        }
        !           546: };
        !           547: #endif
        !           548:
        !           549: const struct pciide_product_desc pciide_cmd_products[] =  {
        !           550:        { PCI_PRODUCT_CMDTECH_640,      /* CMD Technology PCI0640 */
        !           551:          0,
        !           552:          cmd_chip_map
        !           553:        },
        !           554:        { PCI_PRODUCT_CMDTECH_643,      /* CMD Technology PCI0643 */
        !           555:          0,
        !           556:          cmd0643_9_chip_map
        !           557:        },
        !           558:        { PCI_PRODUCT_CMDTECH_646,      /* CMD Technology PCI0646 */
        !           559:          0,
        !           560:          cmd0643_9_chip_map
        !           561:        },
        !           562:        { PCI_PRODUCT_CMDTECH_648,      /* CMD Technology PCI0648 */
        !           563:          IDE_PCI_CLASS_OVERRIDE,
        !           564:          cmd0643_9_chip_map
        !           565:        },
        !           566:        { PCI_PRODUCT_CMDTECH_649,      /* CMD Technology PCI0649 */
        !           567:          IDE_PCI_CLASS_OVERRIDE,
        !           568:          cmd0643_9_chip_map
        !           569:        },
        !           570:        { PCI_PRODUCT_CMDTECH_680,      /* CMD Technology PCI0680 */
        !           571:          IDE_PCI_CLASS_OVERRIDE,
        !           572:          cmd680_chip_map
        !           573:        },
        !           574:        { PCI_PRODUCT_CMDTECH_3112,     /* SiI3112 SATA */
        !           575:          IDE_PCI_CLASS_OVERRIDE,
        !           576:          sii3112_chip_map
        !           577:        },
        !           578:        { PCI_PRODUCT_CMDTECH_3512,     /* SiI3512 SATA */
        !           579:          IDE_PCI_CLASS_OVERRIDE,
        !           580:          sii3112_chip_map
        !           581:        },
        !           582:        { PCI_PRODUCT_CMDTECH_AAR_1210SA, /* Adaptec AAR-1210SA */
        !           583:          IDE_PCI_CLASS_OVERRIDE,
        !           584:          sii3112_chip_map
        !           585:        },
        !           586:        { PCI_PRODUCT_CMDTECH_3114,     /* SiI3114 */
        !           587:          IDE_PCI_CLASS_OVERRIDE,
        !           588:          sii3114_chip_map
        !           589:        }
        !           590: };
        !           591:
        !           592: const struct pciide_product_desc pciide_via_products[] =  {
        !           593:        { PCI_PRODUCT_VIATECH_VT82C416, /* VIA VT82C416 IDE */
        !           594:          0,
        !           595:          apollo_chip_map
        !           596:        },
        !           597:        { PCI_PRODUCT_VIATECH_VT82C571, /* VIA VT82C571 IDE */
        !           598:          0,
        !           599:          apollo_chip_map
        !           600:        },
        !           601:        { PCI_PRODUCT_VIATECH_VT6410, /* VIA VT6410 IDE */
        !           602:          IDE_PCI_CLASS_OVERRIDE,
        !           603:          apollo_chip_map
        !           604:        },
        !           605:        { PCI_PRODUCT_VIATECH_CX700_IDE, /* VIA CX700 IDE */
        !           606:          0,
        !           607:          apollo_chip_map
        !           608:        },
        !           609:        { PCI_PRODUCT_VIATECH_VT6420_SATA, /* VIA VT6420 SATA */
        !           610:          IDE_PCI_CLASS_OVERRIDE,
        !           611:          sata_chip_map
        !           612:        },
        !           613:        { PCI_PRODUCT_VIATECH_VT6421_SATA, /* VIA VT6421 SATA */
        !           614:          IDE_PCI_CLASS_OVERRIDE,
        !           615:          sata_chip_map
        !           616:        },
        !           617:        { PCI_PRODUCT_VIATECH_VT8237A_SATA, /* VIA VT8237A SATA */
        !           618:          IDE_PCI_CLASS_OVERRIDE,
        !           619:          sata_chip_map
        !           620:        },
        !           621:        { PCI_PRODUCT_VIATECH_VT8237A_SATA_2, /* VIA VT8237A SATA */
        !           622:          0,
        !           623:          sata_chip_map
        !           624:        },
        !           625:        { PCI_PRODUCT_VIATECH_VT8251_SATA, /* VIA VT8251 SATA */
        !           626:          IDE_PCI_CLASS_OVERRIDE,
        !           627:          sata_chip_map
        !           628:        }
        !           629: };
        !           630:
        !           631: const struct pciide_product_desc pciide_cypress_products[] =  {
        !           632:        { PCI_PRODUCT_CONTAQ_82C693,    /* Contaq CY82C693 IDE */
        !           633:          IDE_16BIT_IOSPACE,
        !           634:          cy693_chip_map
        !           635:        }
        !           636: };
        !           637:
        !           638: const struct pciide_product_desc pciide_sis_products[] =  {
        !           639:        { PCI_PRODUCT_SIS_5513,         /* SIS 5513 EIDE */
        !           640:          0,
        !           641:          sis_chip_map
        !           642:        },
        !           643:        { PCI_PRODUCT_SIS_180,          /* SIS 180 SATA */
        !           644:          IDE_PCI_CLASS_OVERRIDE,
        !           645:          sata_chip_map
        !           646:        },
        !           647:        { PCI_PRODUCT_SIS_181,          /* SIS 181 SATA */
        !           648:          IDE_PCI_CLASS_OVERRIDE,
        !           649:          sata_chip_map
        !           650:        },
        !           651:        { PCI_PRODUCT_SIS_182,          /* SIS 182 SATA */
        !           652:          IDE_PCI_CLASS_OVERRIDE,
        !           653:          sata_chip_map
        !           654:        }
        !           655: };
        !           656:
        !           657: const struct pciide_product_desc pciide_natsemi_products[] =  {
        !           658:        { PCI_PRODUCT_NS_PC87415,       /* National Semi PC87415 IDE */
        !           659:          0,
        !           660:          natsemi_chip_map
        !           661:        },
        !           662:        { PCI_PRODUCT_NS_SCx200_IDE,    /* National Semi SCx200 IDE */
        !           663:          0,
        !           664:          ns_scx200_chip_map
        !           665:        }
        !           666: };
        !           667:
        !           668: const struct pciide_product_desc pciide_acer_products[] =  {
        !           669:        { PCI_PRODUCT_ALI_M5229,        /* Acer Labs M5229 UDMA IDE */
        !           670:          0,
        !           671:          acer_chip_map
        !           672:        }
        !           673: };
        !           674:
        !           675: const struct pciide_product_desc pciide_triones_products[] =  {
        !           676:        { PCI_PRODUCT_TRIONES_HPT366,   /* Highpoint HPT36x/37x IDE */
        !           677:          IDE_PCI_CLASS_OVERRIDE,
        !           678:          hpt_chip_map,
        !           679:        },
        !           680:        { PCI_PRODUCT_TRIONES_HPT372A,  /* Highpoint HPT372A IDE */
        !           681:          IDE_PCI_CLASS_OVERRIDE,
        !           682:          hpt_chip_map
        !           683:        },
        !           684:        { PCI_PRODUCT_TRIONES_HPT302,   /* Highpoint HPT302 IDE */
        !           685:          IDE_PCI_CLASS_OVERRIDE,
        !           686:          hpt_chip_map
        !           687:        },
        !           688:        { PCI_PRODUCT_TRIONES_HPT371,   /* Highpoint HPT371 IDE */
        !           689:          IDE_PCI_CLASS_OVERRIDE,
        !           690:          hpt_chip_map
        !           691:        },
        !           692:        { PCI_PRODUCT_TRIONES_HPT374,   /* Highpoint HPT374 IDE */
        !           693:          IDE_PCI_CLASS_OVERRIDE,
        !           694:          hpt_chip_map
        !           695:        }
        !           696: };
        !           697:
        !           698: const struct pciide_product_desc pciide_promise_products[] =  {
        !           699:        { PCI_PRODUCT_PROMISE_PDC20246,
        !           700:          IDE_PCI_CLASS_OVERRIDE,
        !           701:          pdc202xx_chip_map,
        !           702:        },
        !           703:        { PCI_PRODUCT_PROMISE_PDC20262,
        !           704:          IDE_PCI_CLASS_OVERRIDE,
        !           705:          pdc202xx_chip_map,
        !           706:        },
        !           707:        { PCI_PRODUCT_PROMISE_PDC20265,
        !           708:          IDE_PCI_CLASS_OVERRIDE,
        !           709:          pdc202xx_chip_map,
        !           710:        },
        !           711:        { PCI_PRODUCT_PROMISE_PDC20267,
        !           712:          IDE_PCI_CLASS_OVERRIDE,
        !           713:          pdc202xx_chip_map,
        !           714:        },
        !           715:        { PCI_PRODUCT_PROMISE_PDC20268,
        !           716:          IDE_PCI_CLASS_OVERRIDE,
        !           717:          pdc202xx_chip_map,
        !           718:        },
        !           719:        { PCI_PRODUCT_PROMISE_PDC20268R,
        !           720:          IDE_PCI_CLASS_OVERRIDE,
        !           721:          pdc202xx_chip_map,
        !           722:        },
        !           723:        { PCI_PRODUCT_PROMISE_PDC20269,
        !           724:          IDE_PCI_CLASS_OVERRIDE,
        !           725:          pdc202xx_chip_map,
        !           726:        },
        !           727:        { PCI_PRODUCT_PROMISE_PDC20271,
        !           728:          IDE_PCI_CLASS_OVERRIDE,
        !           729:          pdc202xx_chip_map,
        !           730:        },
        !           731:        { PCI_PRODUCT_PROMISE_PDC20275,
        !           732:          IDE_PCI_CLASS_OVERRIDE,
        !           733:          pdc202xx_chip_map,
        !           734:        },
        !           735:        { PCI_PRODUCT_PROMISE_PDC20276,
        !           736:          IDE_PCI_CLASS_OVERRIDE,
        !           737:          pdc202xx_chip_map,
        !           738:        },
        !           739:        { PCI_PRODUCT_PROMISE_PDC20277,
        !           740:          IDE_PCI_CLASS_OVERRIDE,
        !           741:          pdc202xx_chip_map,
        !           742:        },
        !           743:        { PCI_PRODUCT_PROMISE_PDC20318,
        !           744:          IDE_PCI_CLASS_OVERRIDE,
        !           745:          pdcsata_chip_map,
        !           746:        },
        !           747:        { PCI_PRODUCT_PROMISE_PDC20319,
        !           748:          IDE_PCI_CLASS_OVERRIDE,
        !           749:          pdcsata_chip_map,
        !           750:        },
        !           751:        { PCI_PRODUCT_PROMISE_PDC20371,
        !           752:          IDE_PCI_CLASS_OVERRIDE,
        !           753:          pdcsata_chip_map,
        !           754:        },
        !           755:        { PCI_PRODUCT_PROMISE_PDC20375,
        !           756:          IDE_PCI_CLASS_OVERRIDE,
        !           757:          pdcsata_chip_map,
        !           758:        },
        !           759:        { PCI_PRODUCT_PROMISE_PDC20376,
        !           760:          IDE_PCI_CLASS_OVERRIDE,
        !           761:          pdcsata_chip_map,
        !           762:        },
        !           763:        { PCI_PRODUCT_PROMISE_PDC20377,
        !           764:          IDE_PCI_CLASS_OVERRIDE,
        !           765:          pdcsata_chip_map,
        !           766:        },
        !           767:        { PCI_PRODUCT_PROMISE_PDC20378,
        !           768:          IDE_PCI_CLASS_OVERRIDE,
        !           769:          pdcsata_chip_map,
        !           770:        },
        !           771:        { PCI_PRODUCT_PROMISE_PDC20379,
        !           772:          IDE_PCI_CLASS_OVERRIDE,
        !           773:          pdcsata_chip_map,
        !           774:        },
        !           775:        { PCI_PRODUCT_PROMISE_PDC40518,
        !           776:          IDE_PCI_CLASS_OVERRIDE,
        !           777:          pdcsata_chip_map,
        !           778:        },
        !           779:        { PCI_PRODUCT_PROMISE_PDC40519,
        !           780:          IDE_PCI_CLASS_OVERRIDE,
        !           781:          pdcsata_chip_map,
        !           782:        },
        !           783:        { PCI_PRODUCT_PROMISE_PDC40718,
        !           784:          IDE_PCI_CLASS_OVERRIDE,
        !           785:          pdcsata_chip_map,
        !           786:        },
        !           787:        { PCI_PRODUCT_PROMISE_PDC40719,
        !           788:          IDE_PCI_CLASS_OVERRIDE,
        !           789:          pdcsata_chip_map,
        !           790:        },
        !           791:        { PCI_PRODUCT_PROMISE_PDC40779,
        !           792:          IDE_PCI_CLASS_OVERRIDE,
        !           793:          pdcsata_chip_map,
        !           794:        },
        !           795:        { PCI_PRODUCT_PROMISE_PDC20571,
        !           796:          IDE_PCI_CLASS_OVERRIDE,
        !           797:          pdcsata_chip_map,
        !           798:        },
        !           799:        { PCI_PRODUCT_PROMISE_PDC20575,
        !           800:          IDE_PCI_CLASS_OVERRIDE,
        !           801:          pdcsata_chip_map,
        !           802:        },
        !           803:        { PCI_PRODUCT_PROMISE_PDC20579,
        !           804:          IDE_PCI_CLASS_OVERRIDE,
        !           805:          pdcsata_chip_map,
        !           806:        },
        !           807:        { PCI_PRODUCT_PROMISE_PDC20771,
        !           808:          IDE_PCI_CLASS_OVERRIDE,
        !           809:          pdcsata_chip_map,
        !           810:        },
        !           811:        { PCI_PRODUCT_PROMISE_PDC20775,
        !           812:          IDE_PCI_CLASS_OVERRIDE,
        !           813:          pdcsata_chip_map,
        !           814:        }
        !           815: };
        !           816:
        !           817: const struct pciide_product_desc pciide_acard_products[] =  {
        !           818:        { PCI_PRODUCT_ACARD_ATP850U,    /* Acard ATP850U Ultra33 Controller */
        !           819:          IDE_PCI_CLASS_OVERRIDE,
        !           820:          acard_chip_map,
        !           821:        },
        !           822:        { PCI_PRODUCT_ACARD_ATP860,     /* Acard ATP860 Ultra66 Controller */
        !           823:          IDE_PCI_CLASS_OVERRIDE,
        !           824:          acard_chip_map,
        !           825:        },
        !           826:        { PCI_PRODUCT_ACARD_ATP860A,    /* Acard ATP860-A Ultra66 Controller */
        !           827:          IDE_PCI_CLASS_OVERRIDE,
        !           828:          acard_chip_map,
        !           829:        },
        !           830:        { PCI_PRODUCT_ACARD_ATP865A,    /* Acard ATP865-A Ultra133 Controller */
        !           831:          IDE_PCI_CLASS_OVERRIDE,
        !           832:          acard_chip_map,
        !           833:        },
        !           834:        { PCI_PRODUCT_ACARD_ATP865R,    /* Acard ATP865-R Ultra133 Controller */
        !           835:          IDE_PCI_CLASS_OVERRIDE,
        !           836:          acard_chip_map,
        !           837:        }
        !           838: };
        !           839:
        !           840: const struct pciide_product_desc pciide_serverworks_products[] =  {
        !           841:        { PCI_PRODUCT_RCC_OSB4_IDE,
        !           842:          0,
        !           843:          serverworks_chip_map,
        !           844:        },
        !           845:        { PCI_PRODUCT_RCC_CSB5_IDE,
        !           846:          0,
        !           847:          serverworks_chip_map,
        !           848:        },
        !           849:        { PCI_PRODUCT_RCC_CSB6_IDE,
        !           850:          0,
        !           851:          serverworks_chip_map,
        !           852:        },
        !           853:        { PCI_PRODUCT_RCC_CSB6_RAID_IDE,
        !           854:          0,
        !           855:          serverworks_chip_map,
        !           856:        },
        !           857:        { PCI_PRODUCT_RCC_HT_1000_IDE,
        !           858:          0,
        !           859:          serverworks_chip_map,
        !           860:        },
        !           861:        { PCI_PRODUCT_RCC_K2_SATA,
        !           862:          IDE_PCI_CLASS_OVERRIDE,
        !           863:          svwsata_chip_map,
        !           864:        },
        !           865:        { PCI_PRODUCT_RCC_FRODO4_SATA,
        !           866:          0,
        !           867:          svwsata_chip_map,
        !           868:        },
        !           869:        { PCI_PRODUCT_RCC_FRODO8_SATA,
        !           870:          0,
        !           871:          svwsata_chip_map,
        !           872:        },
        !           873:        { PCI_PRODUCT_RCC_HT_1000_SATA_1,
        !           874:          0,
        !           875:          svwsata_chip_map,
        !           876:        },
        !           877:        { PCI_PRODUCT_RCC_HT_1000_SATA_2,
        !           878:          0,
        !           879:          svwsata_chip_map,
        !           880:        }
        !           881: };
        !           882:
        !           883: const struct pciide_product_desc pciide_nvidia_products[] = {
        !           884:        { PCI_PRODUCT_NVIDIA_NFORCE_IDE,
        !           885:          0,
        !           886:          nforce_chip_map
        !           887:        },
        !           888:        { PCI_PRODUCT_NVIDIA_NFORCE2_IDE,
        !           889:          0,
        !           890:          nforce_chip_map
        !           891:        },
        !           892:        { PCI_PRODUCT_NVIDIA_NFORCE2_400_IDE,
        !           893:          0,
        !           894:          nforce_chip_map
        !           895:        },
        !           896:        { PCI_PRODUCT_NVIDIA_NFORCE3_IDE,
        !           897:          0,
        !           898:          nforce_chip_map
        !           899:        },
        !           900:        { PCI_PRODUCT_NVIDIA_NFORCE3_250_IDE,
        !           901:          0,
        !           902:          nforce_chip_map
        !           903:        },
        !           904:        { PCI_PRODUCT_NVIDIA_NFORCE4_ATA133,
        !           905:          0,
        !           906:          nforce_chip_map
        !           907:        },
        !           908:        { PCI_PRODUCT_NVIDIA_MCP04_IDE,
        !           909:          0,
        !           910:          nforce_chip_map
        !           911:        },
        !           912:        { PCI_PRODUCT_NVIDIA_MCP51_IDE,
        !           913:          0,
        !           914:          nforce_chip_map
        !           915:        },
        !           916:        { PCI_PRODUCT_NVIDIA_MCP55_IDE,
        !           917:          0,
        !           918:          nforce_chip_map
        !           919:        },
        !           920:        { PCI_PRODUCT_NVIDIA_MCP61_IDE,
        !           921:          0,
        !           922:          nforce_chip_map
        !           923:        },
        !           924:        { PCI_PRODUCT_NVIDIA_MCP65_IDE,
        !           925:          0,
        !           926:          nforce_chip_map
        !           927:        },
        !           928:        { PCI_PRODUCT_NVIDIA_MCP67_IDE,
        !           929:          0,
        !           930:          nforce_chip_map
        !           931:        },
        !           932:        { PCI_PRODUCT_NVIDIA_NFORCE2_400_SATA,
        !           933:          0,
        !           934:          sata_chip_map
        !           935:        },
        !           936:        { PCI_PRODUCT_NVIDIA_NFORCE3_250_SATA,
        !           937:          0,
        !           938:          sata_chip_map
        !           939:        },
        !           940:        { PCI_PRODUCT_NVIDIA_NFORCE3_250_SATA2,
        !           941:          0,
        !           942:          sata_chip_map
        !           943:        },
        !           944:        { PCI_PRODUCT_NVIDIA_NFORCE4_SATA1,
        !           945:          0,
        !           946:          sata_chip_map
        !           947:        },
        !           948:        { PCI_PRODUCT_NVIDIA_NFORCE4_SATA2,
        !           949:          0,
        !           950:          sata_chip_map
        !           951:        },
        !           952:        { PCI_PRODUCT_NVIDIA_MCP04_SATA,
        !           953:          0,
        !           954:          sata_chip_map
        !           955:        },
        !           956:        { PCI_PRODUCT_NVIDIA_MCP04_SATA2,
        !           957:          0,
        !           958:          sata_chip_map
        !           959:        },
        !           960:        { PCI_PRODUCT_NVIDIA_MCP51_SATA,
        !           961:          0,
        !           962:          sata_chip_map
        !           963:        },
        !           964:        { PCI_PRODUCT_NVIDIA_MCP51_SATA2,
        !           965:          0,
        !           966:          sata_chip_map
        !           967:        },
        !           968:        { PCI_PRODUCT_NVIDIA_MCP55_SATA,
        !           969:          0,
        !           970:          sata_chip_map
        !           971:        },
        !           972:        { PCI_PRODUCT_NVIDIA_MCP55_SATA2,
        !           973:          0,
        !           974:          sata_chip_map
        !           975:        },
        !           976:        { PCI_PRODUCT_NVIDIA_MCP61_SATA,
        !           977:          0,
        !           978:          sata_chip_map
        !           979:        },
        !           980:        { PCI_PRODUCT_NVIDIA_MCP61_SATA2,
        !           981:          0,
        !           982:          sata_chip_map
        !           983:        },
        !           984:        { PCI_PRODUCT_NVIDIA_MCP61_SATA3,
        !           985:          0,
        !           986:          sata_chip_map
        !           987:        },
        !           988:        { PCI_PRODUCT_NVIDIA_MCP65_SATA,
        !           989:          0,
        !           990:          sata_chip_map
        !           991:        },
        !           992:        { PCI_PRODUCT_NVIDIA_MCP65_SATA2,
        !           993:          0,
        !           994:          sata_chip_map
        !           995:        },
        !           996:        { PCI_PRODUCT_NVIDIA_MCP65_SATA3,
        !           997:          0,
        !           998:          sata_chip_map
        !           999:        },
        !          1000:        { PCI_PRODUCT_NVIDIA_MCP65_SATA4,
        !          1001:          0,
        !          1002:          sata_chip_map
        !          1003:        },
        !          1004:        { PCI_PRODUCT_NVIDIA_MCP67_SATA,
        !          1005:          0,
        !          1006:          sata_chip_map
        !          1007:        },
        !          1008:        { PCI_PRODUCT_NVIDIA_MCP67_SATA2,
        !          1009:          0,
        !          1010:          sata_chip_map
        !          1011:        },
        !          1012:        { PCI_PRODUCT_NVIDIA_MCP67_SATA3,
        !          1013:          0,
        !          1014:          sata_chip_map
        !          1015:        },
        !          1016:        { PCI_PRODUCT_NVIDIA_MCP67_SATA4,
        !          1017:          0,
        !          1018:          sata_chip_map
        !          1019:        }
        !          1020: };
        !          1021:
        !          1022: const struct pciide_product_desc pciide_ite_products[] = {
        !          1023:        { PCI_PRODUCT_ITEXPRESS_IT8211F,
        !          1024:          IDE_PCI_CLASS_OVERRIDE,
        !          1025:          ite_chip_map
        !          1026:        },
        !          1027:        { PCI_PRODUCT_ITEXPRESS_IT8212F,
        !          1028:          IDE_PCI_CLASS_OVERRIDE,
        !          1029:          ite_chip_map
        !          1030:        }
        !          1031: };
        !          1032:
        !          1033: const struct pciide_product_desc pciide_ati_products[] = {
        !          1034:        { PCI_PRODUCT_ATI_IXP_IDE_200,
        !          1035:          0,
        !          1036:          ixp_chip_map
        !          1037:        },
        !          1038:        { PCI_PRODUCT_ATI_IXP_IDE_300,
        !          1039:          0,
        !          1040:          ixp_chip_map
        !          1041:        },
        !          1042:        { PCI_PRODUCT_ATI_IXP_IDE_400,
        !          1043:          0,
        !          1044:          ixp_chip_map
        !          1045:        },
        !          1046:        { PCI_PRODUCT_ATI_IXP_IDE_600,
        !          1047:          0,
        !          1048:          ixp_chip_map
        !          1049:        },
        !          1050:        { PCI_PRODUCT_ATI_IXP_SATA_300,
        !          1051:          IDE_PCI_CLASS_OVERRIDE,
        !          1052:          sii3112_chip_map
        !          1053:        },
        !          1054:        { PCI_PRODUCT_ATI_IXP_SATA_400_1,
        !          1055:          IDE_PCI_CLASS_OVERRIDE,
        !          1056:          sii3112_chip_map
        !          1057:        },
        !          1058:        { PCI_PRODUCT_ATI_IXP_SATA_400_2,
        !          1059:          IDE_PCI_CLASS_OVERRIDE,
        !          1060:          sii3112_chip_map
        !          1061:        }
        !          1062: };
        !          1063:
        !          1064: const struct pciide_product_desc pciide_jmicron_products[] = {
        !          1065:        { PCI_PRODUCT_JMICRON_JMB361,
        !          1066:          0,
        !          1067:          jmicron_chip_map
        !          1068:        },
        !          1069:        { PCI_PRODUCT_JMICRON_JMB363,
        !          1070:          0,
        !          1071:          jmicron_chip_map
        !          1072:        },
        !          1073:        { PCI_PRODUCT_JMICRON_JMB365,
        !          1074:          0,
        !          1075:          jmicron_chip_map
        !          1076:        },
        !          1077:        { PCI_PRODUCT_JMICRON_JMB366,
        !          1078:          0,
        !          1079:          jmicron_chip_map
        !          1080:        },
        !          1081:        { PCI_PRODUCT_JMICRON_JMB368,
        !          1082:          0,
        !          1083:          jmicron_chip_map
        !          1084:        }
        !          1085: };
        !          1086:
        !          1087: struct pciide_vendor_desc {
        !          1088:        u_int32_t ide_vendor;
        !          1089:        const struct pciide_product_desc *ide_products;
        !          1090:        int ide_nproducts;
        !          1091: };
        !          1092:
        !          1093: const struct pciide_vendor_desc pciide_vendors[] = {
        !          1094:        { PCI_VENDOR_INTEL, pciide_intel_products,
        !          1095:          sizeof(pciide_intel_products)/sizeof(pciide_intel_products[0]) },
        !          1096:        { PCI_VENDOR_AMD, pciide_amd_products,
        !          1097:          sizeof(pciide_amd_products)/sizeof(pciide_amd_products[0]) },
        !          1098: #ifdef notyet
        !          1099:        { PCI_VENDOR_OPTI, pciide_opti_products,
        !          1100:          sizeof(pciide_opti_products)/sizeof(pciide_opti_products[0]) },
        !          1101: #endif
        !          1102:        { PCI_VENDOR_CMDTECH, pciide_cmd_products,
        !          1103:          sizeof(pciide_cmd_products)/sizeof(pciide_cmd_products[0]) },
        !          1104:        { PCI_VENDOR_VIATECH, pciide_via_products,
        !          1105:          sizeof(pciide_via_products)/sizeof(pciide_via_products[0]) },
        !          1106:        { PCI_VENDOR_CONTAQ, pciide_cypress_products,
        !          1107:          sizeof(pciide_cypress_products)/sizeof(pciide_cypress_products[0]) },
        !          1108:        { PCI_VENDOR_SIS, pciide_sis_products,
        !          1109:          sizeof(pciide_sis_products)/sizeof(pciide_sis_products[0]) },
        !          1110:        { PCI_VENDOR_NS, pciide_natsemi_products,
        !          1111:          sizeof(pciide_natsemi_products)/sizeof(pciide_natsemi_products[0]) },
        !          1112:        { PCI_VENDOR_ALI, pciide_acer_products,
        !          1113:          sizeof(pciide_acer_products)/sizeof(pciide_acer_products[0]) },
        !          1114:        { PCI_VENDOR_TRIONES, pciide_triones_products,
        !          1115:          sizeof(pciide_triones_products)/sizeof(pciide_triones_products[0]) },
        !          1116:        { PCI_VENDOR_ACARD, pciide_acard_products,
        !          1117:          sizeof(pciide_acard_products)/sizeof(pciide_acard_products[0]) },
        !          1118:        { PCI_VENDOR_RCC, pciide_serverworks_products,
        !          1119:          sizeof(pciide_serverworks_products)/sizeof(pciide_serverworks_products[0]) },
        !          1120:        { PCI_VENDOR_PROMISE, pciide_promise_products,
        !          1121:          sizeof(pciide_promise_products)/sizeof(pciide_promise_products[0]) },
        !          1122:        { PCI_VENDOR_NVIDIA, pciide_nvidia_products,
        !          1123:          sizeof(pciide_nvidia_products)/sizeof(pciide_nvidia_products[0]) },
        !          1124:        { PCI_VENDOR_ITEXPRESS, pciide_ite_products,
        !          1125:          sizeof(pciide_ite_products)/sizeof(pciide_ite_products[0]) },
        !          1126:        { PCI_VENDOR_ATI, pciide_ati_products,
        !          1127:          sizeof(pciide_ati_products)/sizeof(pciide_ati_products[0]) },
        !          1128:        { PCI_VENDOR_JMICRON, pciide_jmicron_products,
        !          1129:          sizeof(pciide_jmicron_products)/sizeof(pciide_jmicron_products[0]) }
        !          1130: };
        !          1131:
        !          1132: /* options passed via the 'flags' config keyword */
        !          1133: #define PCIIDE_OPTIONS_DMA     0x01
        !          1134:
        !          1135: int    pciide_match(struct device *, void *, void *);
        !          1136: void   pciide_attach(struct device *, struct device *, void *);
        !          1137:
        !          1138: struct cfattach pciide_pci_ca = {
        !          1139:        sizeof(struct pciide_softc), pciide_match, pciide_attach
        !          1140: };
        !          1141:
        !          1142: struct cfattach pciide_jmb_ca = {
        !          1143:        sizeof(struct pciide_softc), pciide_match, pciide_attach
        !          1144: };
        !          1145:
        !          1146: struct cfdriver pciide_cd = {
        !          1147:        NULL, "pciide", DV_DULL
        !          1148: };
        !          1149:
        !          1150: int    pciide_mapregs_compat( struct pci_attach_args *,
        !          1151:            struct pciide_channel *, int, bus_size_t *, bus_size_t *);
        !          1152: int    pciide_mapregs_native(struct pci_attach_args *,
        !          1153:            struct pciide_channel *, bus_size_t *, bus_size_t *,
        !          1154:            int (*pci_intr)(void *));
        !          1155: void   pciide_mapreg_dma(struct pciide_softc *,
        !          1156:            struct pci_attach_args *);
        !          1157: int    pciide_chansetup(struct pciide_softc *, int, pcireg_t);
        !          1158: void   pciide_mapchan(struct pci_attach_args *,
        !          1159:            struct pciide_channel *, pcireg_t, bus_size_t *, bus_size_t *,
        !          1160:            int (*pci_intr)(void *));
        !          1161: int    pciide_chan_candisable(struct pciide_channel *);
        !          1162: void   pciide_map_compat_intr( struct pci_attach_args *,
        !          1163:            struct pciide_channel *, int, int);
        !          1164: void   pciide_unmap_compat_intr( struct pci_attach_args *,
        !          1165:            struct pciide_channel *, int, int);
        !          1166: int    pciide_compat_intr(void *);
        !          1167: int    pciide_pci_intr(void *);
        !          1168: int    pciide_intr_flag(struct pciide_channel *);
        !          1169:
        !          1170: const struct pciide_product_desc *pciide_lookup_product(u_int32_t);
        !          1171:
        !          1172: const struct pciide_product_desc *
        !          1173: pciide_lookup_product(u_int32_t id)
        !          1174: {
        !          1175:        const struct pciide_product_desc *pp;
        !          1176:        const struct pciide_vendor_desc *vp;
        !          1177:        int i;
        !          1178:
        !          1179:        for (i = 0, vp = pciide_vendors;
        !          1180:            i < sizeof(pciide_vendors)/sizeof(pciide_vendors[0]);
        !          1181:            vp++, i++)
        !          1182:                if (PCI_VENDOR(id) == vp->ide_vendor)
        !          1183:                        break;
        !          1184:
        !          1185:        if (i == sizeof(pciide_vendors)/sizeof(pciide_vendors[0]))
        !          1186:                return (NULL);
        !          1187:
        !          1188:        for (pp = vp->ide_products, i = 0; i < vp->ide_nproducts; pp++, i++)
        !          1189:                if (PCI_PRODUCT(id) == pp->ide_product)
        !          1190:                        break;
        !          1191:
        !          1192:        if (i == vp->ide_nproducts)
        !          1193:                return (NULL);
        !          1194:        return (pp);
        !          1195: }
        !          1196:
        !          1197: int
        !          1198: pciide_match(struct device *parent, void *match, void *aux)
        !          1199: {
        !          1200:        struct pci_attach_args *pa = aux;
        !          1201:        const struct pciide_product_desc *pp;
        !          1202:
        !          1203:        /*
        !          1204:         * Some IDE controllers have severe bugs when used in PCI mode.
        !          1205:         * We punt and attach them to the ISA bus instead.
        !          1206:         */
        !          1207:        if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_PCTECH &&
        !          1208:            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_PCTECH_RZ1000)
        !          1209:                return (0);
        !          1210:
        !          1211:        /*
        !          1212:         * Some controllers (e.g. promise Ultra-33) don't claim to be PCI IDE
        !          1213:         * controllers. Let see if we can deal with it anyway.
        !          1214:         */
        !          1215:        pp = pciide_lookup_product(pa->pa_id);
        !          1216:        if (pp  && (pp->ide_flags & IDE_PCI_CLASS_OVERRIDE))
        !          1217:                return (1);
        !          1218:
        !          1219:        /*
        !          1220:         * Check the ID register to see that it's a PCI IDE controller.
        !          1221:         * If it is, we assume that we can deal with it; it _should_
        !          1222:         * work in a standardized way...
        !          1223:         */
        !          1224:        if (PCI_CLASS(pa->pa_class) == PCI_CLASS_MASS_STORAGE) {
        !          1225:                switch (PCI_SUBCLASS(pa->pa_class)) {
        !          1226:                case PCI_SUBCLASS_MASS_STORAGE_IDE:
        !          1227:                        return (1);
        !          1228:
        !          1229:                /*
        !          1230:                 * We only match these if we know they have
        !          1231:                 * a match, as we may not support native interfaces
        !          1232:                 * on them.
        !          1233:                 */
        !          1234:                case PCI_SUBCLASS_MASS_STORAGE_SATA:
        !          1235:                case PCI_SUBCLASS_MASS_STORAGE_RAID:
        !          1236:                        if (pp)
        !          1237:                                return (1);
        !          1238:                        else
        !          1239:                                return (0);
        !          1240:                        break;
        !          1241:                }
        !          1242:        }
        !          1243:
        !          1244:        return (0);
        !          1245: }
        !          1246:
        !          1247: void
        !          1248: pciide_attach(struct device *parent, struct device *self, void *aux)
        !          1249: {
        !          1250:        struct pciide_softc *sc = (struct pciide_softc *)self;
        !          1251:        struct pci_attach_args *pa = aux;
        !          1252:
        !          1253:        sc->sc_pp = pciide_lookup_product(pa->pa_id);
        !          1254:        if (sc->sc_pp == NULL)
        !          1255:                sc->sc_pp = &default_product_desc;
        !          1256:        sc->sc_rev = PCI_REVISION(pa->pa_class);
        !          1257:
        !          1258:        sc->sc_pc = pa->pa_pc;
        !          1259:        sc->sc_tag = pa->pa_tag;
        !          1260:
        !          1261:        /* Set up DMA defaults; these might be adjusted by chip_map. */
        !          1262:        sc->sc_dma_maxsegsz = IDEDMA_BYTE_COUNT_MAX;
        !          1263:        sc->sc_dma_boundary = IDEDMA_BYTE_COUNT_ALIGN;
        !          1264:
        !          1265:        sc->sc_dmacmd_read = pciide_dmacmd_read;
        !          1266:        sc->sc_dmacmd_write = pciide_dmacmd_write;
        !          1267:        sc->sc_dmactl_read = pciide_dmactl_read;
        !          1268:        sc->sc_dmactl_write = pciide_dmactl_write;
        !          1269:        sc->sc_dmatbl_write = pciide_dmatbl_write;
        !          1270:
        !          1271:        WDCDEBUG_PRINT((" sc_pc=%p, sc_tag=%p, pa_class=0x%x\n", sc->sc_pc,
        !          1272:            sc->sc_tag, pa->pa_class), DEBUG_PROBE);
        !          1273:
        !          1274:        sc->sc_pp->chip_map(sc, pa);
        !          1275:
        !          1276:        WDCDEBUG_PRINT(("pciide: command/status register=0x%x\n",
        !          1277:            pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG)),
        !          1278:            DEBUG_PROBE);
        !          1279: }
        !          1280:
        !          1281: int
        !          1282: pciide_mapregs_compat(struct pci_attach_args *pa, struct pciide_channel *cp,
        !          1283:     int compatchan, bus_size_t *cmdsizep, bus_size_t *ctlsizep)
        !          1284: {
        !          1285:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          1286:        struct channel_softc *wdc_cp = &cp->wdc_channel;
        !          1287:        pcireg_t csr;
        !          1288:
        !          1289:        cp->compat = 1;
        !          1290:        *cmdsizep = PCIIDE_COMPAT_CMD_SIZE;
        !          1291:        *ctlsizep = PCIIDE_COMPAT_CTL_SIZE;
        !          1292:
        !          1293:        csr = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG);
        !          1294:        pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG,
        !          1295:            csr | PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MASTER_ENABLE);
        !          1296:
        !          1297:        wdc_cp->cmd_iot = pa->pa_iot;
        !          1298:
        !          1299:        if (bus_space_map(wdc_cp->cmd_iot, PCIIDE_COMPAT_CMD_BASE(compatchan),
        !          1300:            PCIIDE_COMPAT_CMD_SIZE, 0, &wdc_cp->cmd_ioh) != 0) {
        !          1301:                printf("%s: couldn't map %s cmd regs\n",
        !          1302:                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          1303:                return (0);
        !          1304:        }
        !          1305:
        !          1306:        wdc_cp->ctl_iot = pa->pa_iot;
        !          1307:
        !          1308:        if (bus_space_map(wdc_cp->ctl_iot, PCIIDE_COMPAT_CTL_BASE(compatchan),
        !          1309:            PCIIDE_COMPAT_CTL_SIZE, 0, &wdc_cp->ctl_ioh) != 0) {
        !          1310:                printf("%s: couldn't map %s ctl regs\n",
        !          1311:                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          1312:                bus_space_unmap(wdc_cp->cmd_iot, wdc_cp->cmd_ioh,
        !          1313:                    PCIIDE_COMPAT_CMD_SIZE);
        !          1314:                return (0);
        !          1315:        }
        !          1316:
        !          1317:        return (1);
        !          1318: }
        !          1319:
        !          1320: int
        !          1321: pciide_mapregs_native(struct pci_attach_args *pa, struct pciide_channel *cp,
        !          1322:     bus_size_t *cmdsizep, bus_size_t *ctlsizep, int (*pci_intr)(void *))
        !          1323: {
        !          1324:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          1325:        struct channel_softc *wdc_cp = &cp->wdc_channel;
        !          1326:        const char *intrstr;
        !          1327:        pci_intr_handle_t intrhandle;
        !          1328:        pcireg_t maptype;
        !          1329:
        !          1330:        cp->compat = 0;
        !          1331:
        !          1332:        if (sc->sc_pci_ih == NULL) {
        !          1333:                if (pci_intr_map(pa, &intrhandle) != 0) {
        !          1334:                        printf("%s: couldn't map native-PCI interrupt\n",
        !          1335:                            sc->sc_wdcdev.sc_dev.dv_xname);
        !          1336:                        return (0);
        !          1337:                }
        !          1338:                intrstr = pci_intr_string(pa->pa_pc, intrhandle);
        !          1339:                sc->sc_pci_ih = pci_intr_establish(pa->pa_pc,
        !          1340:                    intrhandle, IPL_BIO, pci_intr, sc,
        !          1341:                    sc->sc_wdcdev.sc_dev.dv_xname);
        !          1342:                if (sc->sc_pci_ih != NULL) {
        !          1343:                        printf("%s: using %s for native-PCI interrupt\n",
        !          1344:                            sc->sc_wdcdev.sc_dev.dv_xname,
        !          1345:                            intrstr ? intrstr : "unknown interrupt");
        !          1346:                } else {
        !          1347:                        printf("%s: couldn't establish native-PCI interrupt",
        !          1348:                            sc->sc_wdcdev.sc_dev.dv_xname);
        !          1349:                        if (intrstr != NULL)
        !          1350:                                printf(" at %s", intrstr);
        !          1351:                        printf("\n");
        !          1352:                        return (0);
        !          1353:                }
        !          1354:        }
        !          1355:        cp->ih = sc->sc_pci_ih;
        !          1356:
        !          1357:        maptype = pci_mapreg_type(pa->pa_pc, pa->pa_tag,
        !          1358:            PCIIDE_REG_CMD_BASE(wdc_cp->channel));
        !          1359:        WDCDEBUG_PRINT(("%s: %s cmd regs mapping: %s\n",
        !          1360:            sc->sc_wdcdev.sc_dev.dv_xname, cp->name,
        !          1361:            (maptype == PCI_MAPREG_TYPE_IO ? "I/O" : "memory")), DEBUG_PROBE);
        !          1362:        if (pci_mapreg_map(pa, PCIIDE_REG_CMD_BASE(wdc_cp->channel),
        !          1363:            maptype, 0,
        !          1364:            &wdc_cp->cmd_iot, &wdc_cp->cmd_ioh, NULL, cmdsizep, 0) != 0) {
        !          1365:                printf("%s: couldn't map %s cmd regs\n",
        !          1366:                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          1367:                return (0);
        !          1368:        }
        !          1369:
        !          1370:        maptype = pci_mapreg_type(pa->pa_pc, pa->pa_tag,
        !          1371:            PCIIDE_REG_CTL_BASE(wdc_cp->channel));
        !          1372:        WDCDEBUG_PRINT(("%s: %s ctl regs mapping: %s\n",
        !          1373:            sc->sc_wdcdev.sc_dev.dv_xname, cp->name,
        !          1374:            (maptype == PCI_MAPREG_TYPE_IO ? "I/O": "memory")), DEBUG_PROBE);
        !          1375:        if (pci_mapreg_map(pa, PCIIDE_REG_CTL_BASE(wdc_cp->channel),
        !          1376:            maptype, 0,
        !          1377:            &wdc_cp->ctl_iot, &cp->ctl_baseioh, NULL, ctlsizep, 0) != 0) {
        !          1378:                printf("%s: couldn't map %s ctl regs\n",
        !          1379:                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          1380:                bus_space_unmap(wdc_cp->cmd_iot, wdc_cp->cmd_ioh, *cmdsizep);
        !          1381:                return (0);
        !          1382:        }
        !          1383:        /*
        !          1384:         * In native mode, 4 bytes of I/O space are mapped for the control
        !          1385:         * register, the control register is at offset 2. Pass the generic
        !          1386:         * code a handle for only one byte at the right offset.
        !          1387:         */
        !          1388:        if (bus_space_subregion(wdc_cp->ctl_iot, cp->ctl_baseioh, 2, 1,
        !          1389:            &wdc_cp->ctl_ioh) != 0) {
        !          1390:                printf("%s: unable to subregion %s ctl regs\n",
        !          1391:                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          1392:                bus_space_unmap(wdc_cp->cmd_iot, wdc_cp->cmd_ioh, *cmdsizep);
        !          1393:                bus_space_unmap(wdc_cp->cmd_iot, cp->ctl_baseioh, *ctlsizep);
        !          1394:                return (0);
        !          1395:        }
        !          1396:        return (1);
        !          1397: }
        !          1398:
        !          1399: void
        !          1400: pciide_mapreg_dma(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          1401: {
        !          1402:        pcireg_t maptype;
        !          1403:        bus_addr_t addr;
        !          1404:
        !          1405:        /*
        !          1406:         * Map DMA registers
        !          1407:         *
        !          1408:         * Note that sc_dma_ok is the right variable to test to see if
        !          1409:         * DMA can be done.  If the interface doesn't support DMA,
        !          1410:         * sc_dma_ok will never be non-zero.  If the DMA regs couldn't
        !          1411:         * be mapped, it'll be zero.  I.e., sc_dma_ok will only be
        !          1412:         * non-zero if the interface supports DMA and the registers
        !          1413:         * could be mapped.
        !          1414:         *
        !          1415:         * XXX Note that despite the fact that the Bus Master IDE specs
        !          1416:         * XXX say that "The bus master IDE function uses 16 bytes of IO
        !          1417:         * XXX space", some controllers (at least the United
        !          1418:         * XXX Microelectronics UM8886BF) place it in memory space.
        !          1419:         */
        !          1420:
        !          1421:        maptype = pci_mapreg_type(pa->pa_pc, pa->pa_tag,
        !          1422:            PCIIDE_REG_BUS_MASTER_DMA);
        !          1423:
        !          1424:        switch (maptype) {
        !          1425:        case PCI_MAPREG_TYPE_IO:
        !          1426:                sc->sc_dma_ok = (pci_mapreg_info(pa->pa_pc, pa->pa_tag,
        !          1427:                    PCIIDE_REG_BUS_MASTER_DMA, PCI_MAPREG_TYPE_IO,
        !          1428:                    &addr, NULL, NULL) == 0);
        !          1429:                if (sc->sc_dma_ok == 0) {
        !          1430:                        printf(", unused (couldn't query registers)");
        !          1431:                        break;
        !          1432:                }
        !          1433:                if ((sc->sc_pp->ide_flags & IDE_16BIT_IOSPACE)
        !          1434:                    && addr >= 0x10000) {
        !          1435:                        sc->sc_dma_ok = 0;
        !          1436:                        printf(", unused (registers at unsafe address %#lx)", addr);
        !          1437:                        break;
        !          1438:                }
        !          1439:                /* FALLTHROUGH */
        !          1440:
        !          1441:        case PCI_MAPREG_MEM_TYPE_32BIT:
        !          1442:                sc->sc_dma_ok = (pci_mapreg_map(pa,
        !          1443:                    PCIIDE_REG_BUS_MASTER_DMA, maptype, 0,
        !          1444:                    &sc->sc_dma_iot, &sc->sc_dma_ioh, NULL, NULL, 0) == 0);
        !          1445:                sc->sc_dmat = pa->pa_dmat;
        !          1446:                if (sc->sc_dma_ok == 0) {
        !          1447:                        printf(", unused (couldn't map registers)");
        !          1448:                } else {
        !          1449:                        sc->sc_wdcdev.dma_arg = sc;
        !          1450:                        sc->sc_wdcdev.dma_init = pciide_dma_init;
        !          1451:                        sc->sc_wdcdev.dma_start = pciide_dma_start;
        !          1452:                        sc->sc_wdcdev.dma_finish = pciide_dma_finish;
        !          1453:                }
        !          1454:                break;
        !          1455:
        !          1456:        default:
        !          1457:                sc->sc_dma_ok = 0;
        !          1458:                printf(", (unsupported maptype 0x%x)", maptype);
        !          1459:                break;
        !          1460:        }
        !          1461: }
        !          1462:
        !          1463: int
        !          1464: pciide_intr_flag(struct pciide_channel *cp)
        !          1465: {
        !          1466:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          1467:        int chan = cp->wdc_channel.channel;
        !          1468:
        !          1469:        if (cp->dma_in_progress) {
        !          1470:                int retry = 10;
        !          1471:                int status;
        !          1472:
        !          1473:                /* Check the status register */
        !          1474:                for (retry = 10; retry > 0; retry--) {
        !          1475:                        status = PCIIDE_DMACTL_READ(sc, chan);
        !          1476:                        if (status & IDEDMA_CTL_INTR) {
        !          1477:                                break;
        !          1478:                        }
        !          1479:                        DELAY(5);
        !          1480:                }
        !          1481:
        !          1482:                /* Not for us.  */
        !          1483:                if (retry == 0)
        !          1484:                        return (0);
        !          1485:
        !          1486:                return (1);
        !          1487:        }
        !          1488:
        !          1489:        return (-1);
        !          1490: }
        !          1491:
        !          1492: int
        !          1493: pciide_compat_intr(void *arg)
        !          1494: {
        !          1495:        struct pciide_channel *cp = arg;
        !          1496:
        !          1497:        if (pciide_intr_flag(cp) == 0)
        !          1498:                return (0);
        !          1499:
        !          1500: #ifdef DIAGNOSTIC
        !          1501:        /* should only be called for a compat channel */
        !          1502:        if (cp->compat == 0)
        !          1503:                panic("pciide compat intr called for non-compat chan %p", cp);
        !          1504: #endif
        !          1505:        return (wdcintr(&cp->wdc_channel));
        !          1506: }
        !          1507:
        !          1508: int
        !          1509: pciide_pci_intr(void *arg)
        !          1510: {
        !          1511:        struct pciide_softc *sc = arg;
        !          1512:        struct pciide_channel *cp;
        !          1513:        struct channel_softc *wdc_cp;
        !          1514:        int i, rv, crv;
        !          1515:
        !          1516:        rv = 0;
        !          1517:        for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {
        !          1518:                cp = &sc->pciide_channels[i];
        !          1519:                wdc_cp = &cp->wdc_channel;
        !          1520:
        !          1521:                /* If a compat channel skip. */
        !          1522:                if (cp->compat)
        !          1523:                        continue;
        !          1524:
        !          1525:                if (pciide_intr_flag(cp) == 0)
        !          1526:                        continue;
        !          1527:
        !          1528:                crv = wdcintr(wdc_cp);
        !          1529:                if (crv == 0)
        !          1530:                        ;               /* leave rv alone */
        !          1531:                else if (crv == 1)
        !          1532:                        rv = 1;         /* claim the intr */
        !          1533:                else if (rv == 0)       /* crv should be -1 in this case */
        !          1534:                        rv = crv;       /* if we've done no better, take it */
        !          1535:        }
        !          1536:        return (rv);
        !          1537: }
        !          1538:
        !          1539: u_int8_t
        !          1540: pciide_dmacmd_read(struct pciide_softc *sc, int chan)
        !          1541: {
        !          1542:        return (bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          1543:            IDEDMA_CMD(chan)));
        !          1544: }
        !          1545:
        !          1546: void
        !          1547: pciide_dmacmd_write(struct pciide_softc *sc, int chan, u_int8_t val)
        !          1548: {
        !          1549:        bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          1550:            IDEDMA_CMD(chan), val);
        !          1551: }
        !          1552:
        !          1553: u_int8_t
        !          1554: pciide_dmactl_read(struct pciide_softc *sc, int chan)
        !          1555: {
        !          1556:        return (bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          1557:            IDEDMA_CTL(chan)));
        !          1558: }
        !          1559:
        !          1560: void
        !          1561: pciide_dmactl_write(struct pciide_softc *sc, int chan, u_int8_t val)
        !          1562: {
        !          1563:        bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          1564:            IDEDMA_CTL(chan), val);
        !          1565: }
        !          1566:
        !          1567: void
        !          1568: pciide_dmatbl_write(struct pciide_softc *sc, int chan, u_int32_t val)
        !          1569: {
        !          1570:        bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          1571:            IDEDMA_TBL(chan), val);
        !          1572: }
        !          1573:
        !          1574: void
        !          1575: pciide_channel_dma_setup(struct pciide_channel *cp)
        !          1576: {
        !          1577:        int drive;
        !          1578:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          1579:        struct ata_drive_datas *drvp;
        !          1580:
        !          1581:        for (drive = 0; drive < 2; drive++) {
        !          1582:                drvp = &cp->wdc_channel.ch_drive[drive];
        !          1583:                /* If no drive, skip */
        !          1584:                if ((drvp->drive_flags & DRIVE) == 0)
        !          1585:                        continue;
        !          1586:                /* setup DMA if needed */
        !          1587:                if (((drvp->drive_flags & DRIVE_DMA) == 0 &&
        !          1588:                    (drvp->drive_flags & DRIVE_UDMA) == 0) ||
        !          1589:                    sc->sc_dma_ok == 0) {
        !          1590:                        drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA);
        !          1591:                        continue;
        !          1592:                }
        !          1593:                if (pciide_dma_table_setup(sc, cp->wdc_channel.channel, drive)
        !          1594:                    != 0) {
        !          1595:                        /* Abort DMA setup */
        !          1596:                        drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA);
        !          1597:                        continue;
        !          1598:                }
        !          1599:        }
        !          1600: }
        !          1601:
        !          1602: int
        !          1603: pciide_dma_table_setup(struct pciide_softc *sc, int channel, int drive)
        !          1604: {
        !          1605:        bus_dma_segment_t seg;
        !          1606:        int error, rseg;
        !          1607:        const bus_size_t dma_table_size =
        !          1608:            sizeof(struct idedma_table) * NIDEDMA_TABLES;
        !          1609:        struct pciide_dma_maps *dma_maps =
        !          1610:            &sc->pciide_channels[channel].dma_maps[drive];
        !          1611:
        !          1612:        /* If table was already allocated, just return */
        !          1613:        if (dma_maps->dma_table)
        !          1614:                return (0);
        !          1615:
        !          1616:        /* Allocate memory for the DMA tables and map it */
        !          1617:        if ((error = bus_dmamem_alloc(sc->sc_dmat, dma_table_size,
        !          1618:            IDEDMA_TBL_ALIGN, IDEDMA_TBL_ALIGN, &seg, 1, &rseg,
        !          1619:            BUS_DMA_NOWAIT)) != 0) {
        !          1620:                printf("%s:%d: unable to allocate table DMA for "
        !          1621:                    "drive %d, error=%d\n", sc->sc_wdcdev.sc_dev.dv_xname,
        !          1622:                    channel, drive, error);
        !          1623:                return (error);
        !          1624:        }
        !          1625:
        !          1626:        if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
        !          1627:            dma_table_size,
        !          1628:            (caddr_t *)&dma_maps->dma_table,
        !          1629:            BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
        !          1630:                printf("%s:%d: unable to map table DMA for"
        !          1631:                    "drive %d, error=%d\n", sc->sc_wdcdev.sc_dev.dv_xname,
        !          1632:                    channel, drive, error);
        !          1633:                return (error);
        !          1634:        }
        !          1635:
        !          1636:        WDCDEBUG_PRINT(("pciide_dma_table_setup: table at %p len %ld, "
        !          1637:            "phy 0x%lx\n", dma_maps->dma_table, dma_table_size,
        !          1638:            seg.ds_addr), DEBUG_PROBE);
        !          1639:
        !          1640:        /* Create and load table DMA map for this disk */
        !          1641:        if ((error = bus_dmamap_create(sc->sc_dmat, dma_table_size,
        !          1642:            1, dma_table_size, IDEDMA_TBL_ALIGN, BUS_DMA_NOWAIT,
        !          1643:            &dma_maps->dmamap_table)) != 0) {
        !          1644:                printf("%s:%d: unable to create table DMA map for "
        !          1645:                    "drive %d, error=%d\n", sc->sc_wdcdev.sc_dev.dv_xname,
        !          1646:                    channel, drive, error);
        !          1647:                return (error);
        !          1648:        }
        !          1649:        if ((error = bus_dmamap_load(sc->sc_dmat,
        !          1650:            dma_maps->dmamap_table,
        !          1651:            dma_maps->dma_table,
        !          1652:            dma_table_size, NULL, BUS_DMA_NOWAIT)) != 0) {
        !          1653:                printf("%s:%d: unable to load table DMA map for "
        !          1654:                    "drive %d, error=%d\n", sc->sc_wdcdev.sc_dev.dv_xname,
        !          1655:                    channel, drive, error);
        !          1656:                return (error);
        !          1657:        }
        !          1658:        WDCDEBUG_PRINT(("pciide_dma_table_setup: phy addr of table 0x%lx\n",
        !          1659:            dma_maps->dmamap_table->dm_segs[0].ds_addr), DEBUG_PROBE);
        !          1660:        /* Create a xfer DMA map for this drive */
        !          1661:        if ((error = bus_dmamap_create(sc->sc_dmat, IDEDMA_BYTE_COUNT_MAX,
        !          1662:            NIDEDMA_TABLES, sc->sc_dma_maxsegsz, sc->sc_dma_boundary,
        !          1663:            BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
        !          1664:            &dma_maps->dmamap_xfer)) != 0) {
        !          1665:                printf("%s:%d: unable to create xfer DMA map for "
        !          1666:                    "drive %d, error=%d\n", sc->sc_wdcdev.sc_dev.dv_xname,
        !          1667:                    channel, drive, error);
        !          1668:                return (error);
        !          1669:        }
        !          1670:        return (0);
        !          1671: }
        !          1672:
        !          1673: int
        !          1674: pciide_dma_init(void *v, int channel, int drive, void *databuf,
        !          1675:     size_t datalen, int flags)
        !          1676: {
        !          1677:        struct pciide_softc *sc = v;
        !          1678:        int error, seg;
        !          1679:        struct pciide_channel *cp = &sc->pciide_channels[channel];
        !          1680:        struct pciide_dma_maps *dma_maps =
        !          1681:            &sc->pciide_channels[channel].dma_maps[drive];
        !          1682: #ifndef BUS_DMA_RAW
        !          1683: #define BUS_DMA_RAW 0
        !          1684: #endif
        !          1685:
        !          1686:        error = bus_dmamap_load(sc->sc_dmat,
        !          1687:            dma_maps->dmamap_xfer,
        !          1688:            databuf, datalen, NULL, BUS_DMA_NOWAIT|BUS_DMA_RAW);
        !          1689:        if (error) {
        !          1690:                printf("%s:%d: unable to load xfer DMA map for "
        !          1691:                    "drive %d, error=%d\n", sc->sc_wdcdev.sc_dev.dv_xname,
        !          1692:                    channel, drive, error);
        !          1693:                return (error);
        !          1694:        }
        !          1695:
        !          1696:        bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_xfer, 0,
        !          1697:            dma_maps->dmamap_xfer->dm_mapsize,
        !          1698:            (flags & WDC_DMA_READ) ?
        !          1699:            BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
        !          1700:
        !          1701:        for (seg = 0; seg < dma_maps->dmamap_xfer->dm_nsegs; seg++) {
        !          1702: #ifdef DIAGNOSTIC
        !          1703:                /* A segment must not cross a 64k boundary */
        !          1704:                {
        !          1705:                u_long phys = dma_maps->dmamap_xfer->dm_segs[seg].ds_addr;
        !          1706:                u_long len = dma_maps->dmamap_xfer->dm_segs[seg].ds_len;
        !          1707:                if ((phys & ~IDEDMA_BYTE_COUNT_MASK) !=
        !          1708:                    ((phys + len - 1) & ~IDEDMA_BYTE_COUNT_MASK)) {
        !          1709:                        printf("pciide_dma: segment %d physical addr 0x%lx"
        !          1710:                            " len 0x%lx not properly aligned\n",
        !          1711:                            seg, phys, len);
        !          1712:                        panic("pciide_dma: buf align");
        !          1713:                }
        !          1714:                }
        !          1715: #endif
        !          1716:                dma_maps->dma_table[seg].base_addr =
        !          1717:                    htole32(dma_maps->dmamap_xfer->dm_segs[seg].ds_addr);
        !          1718:                dma_maps->dma_table[seg].byte_count =
        !          1719:                    htole32(dma_maps->dmamap_xfer->dm_segs[seg].ds_len &
        !          1720:                    IDEDMA_BYTE_COUNT_MASK);
        !          1721:                WDCDEBUG_PRINT(("\t seg %d len %d addr 0x%x\n",
        !          1722:                   seg, letoh32(dma_maps->dma_table[seg].byte_count),
        !          1723:                   letoh32(dma_maps->dma_table[seg].base_addr)), DEBUG_DMA);
        !          1724:
        !          1725:        }
        !          1726:        dma_maps->dma_table[dma_maps->dmamap_xfer->dm_nsegs -1].byte_count |=
        !          1727:            htole32(IDEDMA_BYTE_COUNT_EOT);
        !          1728:
        !          1729:        bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_table, 0,
        !          1730:            dma_maps->dmamap_table->dm_mapsize,
        !          1731:            BUS_DMASYNC_PREWRITE);
        !          1732:
        !          1733:        /* Maps are ready. Start DMA function */
        !          1734: #ifdef DIAGNOSTIC
        !          1735:        if (dma_maps->dmamap_table->dm_segs[0].ds_addr & ~IDEDMA_TBL_MASK) {
        !          1736:                printf("pciide_dma_init: addr 0x%lx not properly aligned\n",
        !          1737:                    dma_maps->dmamap_table->dm_segs[0].ds_addr);
        !          1738:                panic("pciide_dma_init: table align");
        !          1739:        }
        !          1740: #endif
        !          1741:
        !          1742:        /* Clear status bits */
        !          1743:        PCIIDE_DMACTL_WRITE(sc, channel, PCIIDE_DMACTL_READ(sc, channel));
        !          1744:        /* Write table addr */
        !          1745:        PCIIDE_DMATBL_WRITE(sc, channel,
        !          1746:            dma_maps->dmamap_table->dm_segs[0].ds_addr);
        !          1747:        /* set read/write */
        !          1748:        PCIIDE_DMACMD_WRITE(sc, channel,
        !          1749:            ((flags & WDC_DMA_READ) ? IDEDMA_CMD_WRITE : 0) | cp->idedma_cmd);
        !          1750:        /* remember flags */
        !          1751:        dma_maps->dma_flags = flags;
        !          1752:        return (0);
        !          1753: }
        !          1754:
        !          1755: void
        !          1756: pciide_dma_start(void *v, int channel, int drive)
        !          1757: {
        !          1758:        struct pciide_softc *sc = v;
        !          1759:
        !          1760:        WDCDEBUG_PRINT(("pciide_dma_start\n"), DEBUG_XFERS);
        !          1761:        PCIIDE_DMACMD_WRITE(sc, channel, PCIIDE_DMACMD_READ(sc, channel) |
        !          1762:            IDEDMA_CMD_START);
        !          1763:
        !          1764:        sc->pciide_channels[channel].dma_in_progress = 1;
        !          1765: }
        !          1766:
        !          1767: int
        !          1768: pciide_dma_finish(void *v, int channel, int drive, int force)
        !          1769: {
        !          1770:        struct pciide_softc *sc = v;
        !          1771:        struct pciide_channel *cp = &sc->pciide_channels[channel];
        !          1772:        u_int8_t status;
        !          1773:        int error = 0;
        !          1774:        struct pciide_dma_maps *dma_maps =
        !          1775:            &sc->pciide_channels[channel].dma_maps[drive];
        !          1776:
        !          1777:        status = PCIIDE_DMACTL_READ(sc, channel);
        !          1778:        WDCDEBUG_PRINT(("pciide_dma_finish: status 0x%x\n", status),
        !          1779:            DEBUG_XFERS);
        !          1780:
        !          1781:        if (force == 0 && (status & IDEDMA_CTL_INTR) == 0) {
        !          1782:                error = WDC_DMAST_NOIRQ;
        !          1783:                goto done;
        !          1784:        }
        !          1785:
        !          1786:        /* stop DMA channel */
        !          1787:        PCIIDE_DMACMD_WRITE(sc, channel,
        !          1788:            ((dma_maps->dma_flags & WDC_DMA_READ) ?
        !          1789:            0x00 : IDEDMA_CMD_WRITE) | cp->idedma_cmd);
        !          1790:
        !          1791:        /* Unload the map of the data buffer */
        !          1792:        bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_xfer, 0,
        !          1793:            dma_maps->dmamap_xfer->dm_mapsize,
        !          1794:            (dma_maps->dma_flags & WDC_DMA_READ) ?
        !          1795:            BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
        !          1796:        bus_dmamap_unload(sc->sc_dmat, dma_maps->dmamap_xfer);
        !          1797:
        !          1798:        /* Clear status bits */
        !          1799:        PCIIDE_DMACTL_WRITE(sc, channel, status);
        !          1800:
        !          1801:        if ((status & IDEDMA_CTL_ERR) != 0) {
        !          1802:                printf("%s:%d:%d: bus-master DMA error: status=0x%x\n",
        !          1803:                    sc->sc_wdcdev.sc_dev.dv_xname, channel, drive, status);
        !          1804:                error |= WDC_DMAST_ERR;
        !          1805:        }
        !          1806:
        !          1807:        if ((status & IDEDMA_CTL_INTR) == 0) {
        !          1808:                printf("%s:%d:%d: bus-master DMA error: missing interrupt, "
        !          1809:                    "status=0x%x\n", sc->sc_wdcdev.sc_dev.dv_xname, channel,
        !          1810:                    drive, status);
        !          1811:                error |= WDC_DMAST_NOIRQ;
        !          1812:        }
        !          1813:
        !          1814:        if ((status & IDEDMA_CTL_ACT) != 0) {
        !          1815:                /* data underrun, may be a valid condition for ATAPI */
        !          1816:                error |= WDC_DMAST_UNDER;
        !          1817:        }
        !          1818:
        !          1819: done:
        !          1820:        sc->pciide_channels[channel].dma_in_progress = 0;
        !          1821:        return (error);
        !          1822: }
        !          1823:
        !          1824: void
        !          1825: pciide_irqack(struct channel_softc *chp)
        !          1826: {
        !          1827:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          1828:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          1829:        int chan = chp->channel;
        !          1830:
        !          1831:        /* clear status bits in IDE DMA registers */
        !          1832:        PCIIDE_DMACTL_WRITE(sc, chan, PCIIDE_DMACTL_READ(sc, chan));
        !          1833: }
        !          1834:
        !          1835: /* some common code used by several chip_map */
        !          1836: int
        !          1837: pciide_chansetup(struct pciide_softc *sc, int channel, pcireg_t interface)
        !          1838: {
        !          1839:        struct pciide_channel *cp = &sc->pciide_channels[channel];
        !          1840:        sc->wdc_chanarray[channel] = &cp->wdc_channel;
        !          1841:        cp->name = PCIIDE_CHANNEL_NAME(channel);
        !          1842:        cp->wdc_channel.channel = channel;
        !          1843:        cp->wdc_channel.wdc = &sc->sc_wdcdev;
        !          1844:        cp->wdc_channel.ch_queue =
        !          1845:            malloc(sizeof(struct channel_queue), M_DEVBUF, M_NOWAIT);
        !          1846:        if (cp->wdc_channel.ch_queue == NULL) {
        !          1847:                printf("%s: %s "
        !          1848:                    "cannot allocate memory for command queue",
        !          1849:                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          1850:                return (0);
        !          1851:        }
        !          1852:        cp->hw_ok = 1;
        !          1853:
        !          1854:        return (1);
        !          1855: }
        !          1856:
        !          1857: /* some common code used by several chip channel_map */
        !          1858: void
        !          1859: pciide_mapchan(struct pci_attach_args *pa, struct pciide_channel *cp,
        !          1860:     pcireg_t interface, bus_size_t *cmdsizep, bus_size_t *ctlsizep,
        !          1861:     int (*pci_intr)(void *))
        !          1862: {
        !          1863:        struct channel_softc *wdc_cp = &cp->wdc_channel;
        !          1864:
        !          1865:        if (interface & PCIIDE_INTERFACE_PCI(wdc_cp->channel))
        !          1866:                cp->hw_ok = pciide_mapregs_native(pa, cp, cmdsizep, ctlsizep,
        !          1867:                    pci_intr);
        !          1868:        else
        !          1869:                cp->hw_ok = pciide_mapregs_compat(pa, cp,
        !          1870:                    wdc_cp->channel, cmdsizep, ctlsizep);
        !          1871:        if (cp->hw_ok == 0)
        !          1872:                return;
        !          1873:        wdc_cp->data32iot = wdc_cp->cmd_iot;
        !          1874:        wdc_cp->data32ioh = wdc_cp->cmd_ioh;
        !          1875:        wdcattach(wdc_cp);
        !          1876: }
        !          1877:
        !          1878: /*
        !          1879:  * Generic code to call to know if a channel can be disabled. Return 1
        !          1880:  * if channel can be disabled, 0 if not
        !          1881:  */
        !          1882: int
        !          1883: pciide_chan_candisable(struct pciide_channel *cp)
        !          1884: {
        !          1885:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          1886:        struct channel_softc *wdc_cp = &cp->wdc_channel;
        !          1887:
        !          1888:        if ((wdc_cp->ch_drive[0].drive_flags & DRIVE) == 0 &&
        !          1889:            (wdc_cp->ch_drive[1].drive_flags & DRIVE) == 0) {
        !          1890:                printf("%s: %s disabled (no drives)\n",
        !          1891:                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          1892:                cp->hw_ok = 0;
        !          1893:                return (1);
        !          1894:        }
        !          1895:        return (0);
        !          1896: }
        !          1897:
        !          1898: /*
        !          1899:  * generic code to map the compat intr if hw_ok=1 and it is a compat channel.
        !          1900:  * Set hw_ok=0 on failure
        !          1901:  */
        !          1902: void
        !          1903: pciide_map_compat_intr(struct pci_attach_args *pa, struct pciide_channel *cp,
        !          1904:     int compatchan, int interface)
        !          1905: {
        !          1906:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          1907:        struct channel_softc *wdc_cp = &cp->wdc_channel;
        !          1908:
        !          1909:        if ((interface & PCIIDE_INTERFACE_PCI(wdc_cp->channel)) != 0)
        !          1910:                return;
        !          1911:
        !          1912:        cp->compat = 1;
        !          1913:        cp->ih = pciide_machdep_compat_intr_establish(&sc->sc_wdcdev.sc_dev,
        !          1914:            pa, compatchan, pciide_compat_intr, cp);
        !          1915:        if (cp->ih == NULL) {
        !          1916:                printf("%s: no compatibility interrupt for use by %s\n",
        !          1917:                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          1918:                cp->hw_ok = 0;
        !          1919:        }
        !          1920: }
        !          1921:
        !          1922: /*
        !          1923:  * generic code to unmap the compat intr if hw_ok=1 and it is a compat channel.
        !          1924:  * Set hw_ok=0 on failure
        !          1925:  */
        !          1926: void
        !          1927: pciide_unmap_compat_intr(struct pci_attach_args *pa, struct pciide_channel *cp,
        !          1928:     int compatchan, int interface)
        !          1929: {
        !          1930:        struct channel_softc *wdc_cp = &cp->wdc_channel;
        !          1931:
        !          1932:        if ((interface & PCIIDE_INTERFACE_PCI(wdc_cp->channel)) != 0)
        !          1933:                return;
        !          1934:
        !          1935:        pciide_machdep_compat_intr_disestablish(pa->pa_pc, cp->ih);
        !          1936: }
        !          1937:
        !          1938: void
        !          1939: pciide_print_channels(int nchannels, pcireg_t interface)
        !          1940: {
        !          1941:        int i;
        !          1942:
        !          1943:        for (i = 0; i < nchannels; i++) {
        !          1944:                printf(", %s %s to %s", PCIIDE_CHANNEL_NAME(i),
        !          1945:                    (interface & PCIIDE_INTERFACE_SETTABLE(i)) ?
        !          1946:                    "configured" : "wired",
        !          1947:                    (interface & PCIIDE_INTERFACE_PCI(i)) ? "native-PCI" :
        !          1948:                    "compatibility");
        !          1949:        }
        !          1950:
        !          1951:        printf("\n");
        !          1952: }
        !          1953:
        !          1954: void
        !          1955: pciide_print_modes(struct pciide_channel *cp)
        !          1956: {
        !          1957:        wdc_print_current_modes(&cp->wdc_channel);
        !          1958: }
        !          1959:
        !          1960: void
        !          1961: default_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          1962: {
        !          1963:        struct pciide_channel *cp;
        !          1964:        pcireg_t interface = PCI_INTERFACE(pa->pa_class);
        !          1965:        pcireg_t csr;
        !          1966:        int channel, drive;
        !          1967:        struct ata_drive_datas *drvp;
        !          1968:        u_int8_t idedma_ctl;
        !          1969:        bus_size_t cmdsize, ctlsize;
        !          1970:        char *failreason;
        !          1971:
        !          1972:        if (interface & PCIIDE_INTERFACE_BUS_MASTER_DMA) {
        !          1973:                printf(": DMA");
        !          1974:                if (sc->sc_pp == &default_product_desc &&
        !          1975:                    (sc->sc_wdcdev.sc_dev.dv_cfdata->cf_flags &
        !          1976:                    PCIIDE_OPTIONS_DMA) == 0) {
        !          1977:                        printf(" (unsupported)");
        !          1978:                        sc->sc_dma_ok = 0;
        !          1979:                } else {
        !          1980:                        pciide_mapreg_dma(sc, pa);
        !          1981:                        if (sc->sc_dma_ok != 0)
        !          1982:                                printf(", (partial support)");
        !          1983:                }
        !          1984:        } else {
        !          1985:                printf(": no DMA");
        !          1986:                sc->sc_dma_ok = 0;
        !          1987:        }
        !          1988:        if (sc->sc_dma_ok) {
        !          1989:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
        !          1990:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          1991:        }
        !          1992:        sc->sc_wdcdev.PIO_cap = 0;
        !          1993:        sc->sc_wdcdev.DMA_cap = 0;
        !          1994:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          1995:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          1996:        sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16;
        !          1997:
        !          1998:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          1999:
        !          2000:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          2001:                cp = &sc->pciide_channels[channel];
        !          2002:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          2003:                        continue;
        !          2004:                if (interface & PCIIDE_INTERFACE_PCI(channel)) {
        !          2005:                        cp->hw_ok = pciide_mapregs_native(pa, cp, &cmdsize,
        !          2006:                            &ctlsize, pciide_pci_intr);
        !          2007:                } else {
        !          2008:                        cp->hw_ok = pciide_mapregs_compat(pa, cp,
        !          2009:                            channel, &cmdsize, &ctlsize);
        !          2010:                }
        !          2011:                if (cp->hw_ok == 0)
        !          2012:                        continue;
        !          2013:                /*
        !          2014:                 * Check to see if something appears to be there.
        !          2015:                 */
        !          2016:                failreason = NULL;
        !          2017:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          2018:                if (cp->hw_ok == 0)
        !          2019:                        continue;
        !          2020:                if (!wdcprobe(&cp->wdc_channel)) {
        !          2021:                        failreason = "not responding; disabled or no drives?";
        !          2022:                        goto next;
        !          2023:                }
        !          2024:                /*
        !          2025:                 * Now, make sure it's actually attributable to this PCI IDE
        !          2026:                 * channel by trying to access the channel again while the
        !          2027:                 * PCI IDE controller's I/O space is disabled.  (If the
        !          2028:                 * channel no longer appears to be there, it belongs to
        !          2029:                 * this controller.)  YUCK!
        !          2030:                 */
        !          2031:                csr = pci_conf_read(sc->sc_pc, sc->sc_tag,
        !          2032:                    PCI_COMMAND_STATUS_REG);
        !          2033:                pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG,
        !          2034:                    csr & ~PCI_COMMAND_IO_ENABLE);
        !          2035:                if (wdcprobe(&cp->wdc_channel))
        !          2036:                        failreason = "other hardware responding at addresses";
        !          2037:                pci_conf_write(sc->sc_pc, sc->sc_tag,
        !          2038:                    PCI_COMMAND_STATUS_REG, csr);
        !          2039: next:
        !          2040:                if (failreason) {
        !          2041:                        printf("%s: %s ignored (%s)\n",
        !          2042:                            sc->sc_wdcdev.sc_dev.dv_xname, cp->name,
        !          2043:                            failreason);
        !          2044:                        cp->hw_ok = 0;
        !          2045:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          2046:                        bus_space_unmap(cp->wdc_channel.cmd_iot,
        !          2047:                            cp->wdc_channel.cmd_ioh, cmdsize);
        !          2048:                        if (interface & PCIIDE_INTERFACE_PCI(channel))
        !          2049:                                bus_space_unmap(cp->wdc_channel.ctl_iot,
        !          2050:                                    cp->ctl_baseioh, ctlsize);
        !          2051:                        else
        !          2052:                                bus_space_unmap(cp->wdc_channel.ctl_iot,
        !          2053:                                    cp->wdc_channel.ctl_ioh, ctlsize);
        !          2054:                }
        !          2055:                if (cp->hw_ok) {
        !          2056:                        cp->wdc_channel.data32iot = cp->wdc_channel.cmd_iot;
        !          2057:                        cp->wdc_channel.data32ioh = cp->wdc_channel.cmd_ioh;
        !          2058:                        wdcattach(&cp->wdc_channel);
        !          2059:                }
        !          2060:        }
        !          2061:
        !          2062:        if (sc->sc_dma_ok == 0)
        !          2063:                return;
        !          2064:
        !          2065:        /* Allocate DMA maps */
        !          2066:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          2067:                idedma_ctl = 0;
        !          2068:                cp = &sc->pciide_channels[channel];
        !          2069:                for (drive = 0; drive < 2; drive++) {
        !          2070:                        drvp = &cp->wdc_channel.ch_drive[drive];
        !          2071:                        /* If no drive, skip */
        !          2072:                        if ((drvp->drive_flags & DRIVE) == 0)
        !          2073:                                continue;
        !          2074:                        if ((drvp->drive_flags & DRIVE_DMA) == 0)
        !          2075:                                continue;
        !          2076:                        if (pciide_dma_table_setup(sc, channel, drive) != 0) {
        !          2077:                                /* Abort DMA setup */
        !          2078:                                printf("%s:%d:%d: cannot allocate DMA maps, "
        !          2079:                                    "using PIO transfers\n",
        !          2080:                                    sc->sc_wdcdev.sc_dev.dv_xname,
        !          2081:                                    channel, drive);
        !          2082:                                drvp->drive_flags &= ~DRIVE_DMA;
        !          2083:                        }
        !          2084:                        printf("%s:%d:%d: using DMA data transfers\n",
        !          2085:                            sc->sc_wdcdev.sc_dev.dv_xname,
        !          2086:                            channel, drive);
        !          2087:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          2088:                }
        !          2089:                if (idedma_ctl != 0) {
        !          2090:                        /* Add software bits in status register */
        !          2091:                        PCIIDE_DMACTL_WRITE(sc, channel, idedma_ctl);
        !          2092:                }
        !          2093:        }
        !          2094: }
        !          2095:
        !          2096: void
        !          2097: sata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          2098: {
        !          2099:        struct pciide_channel *cp;
        !          2100:        pcireg_t interface = PCI_INTERFACE(pa->pa_class);
        !          2101:        int channel;
        !          2102:        bus_size_t cmdsize, ctlsize;
        !          2103:
        !          2104:        if (interface == 0) {
        !          2105:                WDCDEBUG_PRINT(("sata_chip_map interface == 0\n"),
        !          2106:                    DEBUG_PROBE);
        !          2107:                interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
        !          2108:                    PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
        !          2109:        }
        !          2110:
        !          2111:        printf(": DMA");
        !          2112:        pciide_mapreg_dma(sc, pa);
        !          2113:        printf("\n");
        !          2114:
        !          2115:        if (sc->sc_dma_ok) {
        !          2116:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA |
        !          2117:                    WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
        !          2118:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          2119:        }
        !          2120:        sc->sc_wdcdev.PIO_cap = 4;
        !          2121:        sc->sc_wdcdev.DMA_cap = 2;
        !          2122:        sc->sc_wdcdev.UDMA_cap = 6;
        !          2123:
        !          2124:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          2125:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          2126:        sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          2127:            WDC_CAPABILITY_MODE | WDC_CAPABILITY_SATA;
        !          2128:        sc->sc_wdcdev.set_modes = sata_setup_channel;
        !          2129:
        !          2130:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          2131:                cp = &sc->pciide_channels[channel];
        !          2132:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          2133:                        continue;
        !          2134:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          2135:                    pciide_pci_intr);
        !          2136:                sata_setup_channel(&cp->wdc_channel);
        !          2137:        }
        !          2138: }
        !          2139:
        !          2140: void
        !          2141: sata_setup_channel(struct channel_softc *chp)
        !          2142: {
        !          2143:        struct ata_drive_datas *drvp;
        !          2144:        int drive;
        !          2145:        u_int32_t idedma_ctl;
        !          2146:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          2147:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          2148:
        !          2149:        /* setup DMA if needed */
        !          2150:        pciide_channel_dma_setup(cp);
        !          2151:
        !          2152:        idedma_ctl = 0;
        !          2153:
        !          2154:        for (drive = 0; drive < 2; drive++) {
        !          2155:                drvp = &chp->ch_drive[drive];
        !          2156:                /* If no drive, skip */
        !          2157:                if ((drvp->drive_flags & DRIVE) == 0)
        !          2158:                        continue;
        !          2159:                if (drvp->drive_flags & DRIVE_UDMA) {
        !          2160:                        /* use Ultra/DMA */
        !          2161:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          2162:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          2163:                } else if (drvp->drive_flags & DRIVE_DMA) {
        !          2164:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          2165:                }
        !          2166:        }
        !          2167:
        !          2168:        /*
        !          2169:         * Nothing to do to setup modes; it is meaningless in S-ATA
        !          2170:         * (but many S-ATA drives still want to get the SET_FEATURE
        !          2171:         * command).
        !          2172:         */
        !          2173:        if (idedma_ctl != 0) {
        !          2174:                /* Add software bits in status register */
        !          2175:                PCIIDE_DMACTL_WRITE(sc, chp->channel, idedma_ctl);
        !          2176:        }
        !          2177:        pciide_print_modes(cp);
        !          2178: }
        !          2179:
        !          2180: void
        !          2181: piix_timing_debug(struct pciide_softc *sc)
        !          2182: {
        !          2183:        WDCDEBUG_PRINT(("piix_setup_chip: idetim=0x%x",
        !          2184:            pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_IDETIM)),
        !          2185:            DEBUG_PROBE);
        !          2186:        if (sc->sc_pp->ide_product != PCI_PRODUCT_INTEL_82371FB_IDE &&
        !          2187:            sc->sc_pp->ide_product != PCI_PRODUCT_INTEL_82371FB_ISA) {
        !          2188:                WDCDEBUG_PRINT((", sidetim=0x%x",
        !          2189:                    pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_SIDETIM)),
        !          2190:                    DEBUG_PROBE);
        !          2191:                if (sc->sc_wdcdev.cap & WDC_CAPABILITY_UDMA) {
        !          2192:                        WDCDEBUG_PRINT((", udamreg 0x%x",
        !          2193:                            pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_UDMAREG)),
        !          2194:                            DEBUG_PROBE);
        !          2195:                }
        !          2196:                if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_6300ESB_IDE ||
        !          2197:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_6321ESB_IDE ||
        !          2198:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801AA_IDE ||
        !          2199:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801AB_IDE ||
        !          2200:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BAM_IDE ||
        !          2201:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BA_IDE ||
        !          2202:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801CAM_IDE ||
        !          2203:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801CA_IDE ||
        !          2204:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DB_IDE ||
        !          2205:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DBL_IDE ||
        !          2206:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DBM_IDE ||
        !          2207:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801EB_IDE ||
        !          2208:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801FB_IDE ||
        !          2209:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801GB_IDE ||
        !          2210:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801HBM_IDE ||
        !          2211:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82372FB_IDE) {
        !          2212:                        WDCDEBUG_PRINT((", IDE_CONTROL 0x%x",
        !          2213:                            pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_CONFIG)),
        !          2214:                            DEBUG_PROBE);
        !          2215:                }
        !          2216:        }
        !          2217:        WDCDEBUG_PRINT(("\n"), DEBUG_PROBE);
        !          2218: }
        !          2219:
        !          2220: void
        !          2221: piix_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          2222: {
        !          2223:        struct pciide_channel *cp;
        !          2224:        int channel;
        !          2225:        u_int32_t idetim;
        !          2226:        bus_size_t cmdsize, ctlsize;
        !          2227:
        !          2228:        pcireg_t interface = PCI_INTERFACE(pa->pa_class);
        !          2229:
        !          2230:        printf(": DMA");
        !          2231:        pciide_mapreg_dma(sc, pa);
        !          2232:        sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          2233:            WDC_CAPABILITY_MODE;
        !          2234:        if (sc->sc_dma_ok) {
        !          2235:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
        !          2236:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          2237:                switch (sc->sc_pp->ide_product) {
        !          2238:                case PCI_PRODUCT_INTEL_6300ESB_IDE:
        !          2239:                case PCI_PRODUCT_INTEL_6321ESB_IDE:
        !          2240:                case PCI_PRODUCT_INTEL_82371AB_IDE:
        !          2241:                case PCI_PRODUCT_INTEL_82372FB_IDE:
        !          2242:                case PCI_PRODUCT_INTEL_82440MX_IDE:
        !          2243:                case PCI_PRODUCT_INTEL_82451NX:
        !          2244:                case PCI_PRODUCT_INTEL_82801AA_IDE:
        !          2245:                case PCI_PRODUCT_INTEL_82801AB_IDE:
        !          2246:                case PCI_PRODUCT_INTEL_82801BAM_IDE:
        !          2247:                case PCI_PRODUCT_INTEL_82801BA_IDE:
        !          2248:                case PCI_PRODUCT_INTEL_82801CAM_IDE:
        !          2249:                case PCI_PRODUCT_INTEL_82801CA_IDE:
        !          2250:                case PCI_PRODUCT_INTEL_82801DB_IDE:
        !          2251:                case PCI_PRODUCT_INTEL_82801DBL_IDE:
        !          2252:                case PCI_PRODUCT_INTEL_82801DBM_IDE:
        !          2253:                case PCI_PRODUCT_INTEL_82801EB_IDE:
        !          2254:                case PCI_PRODUCT_INTEL_82801FB_IDE:
        !          2255:                case PCI_PRODUCT_INTEL_82801GB_IDE:
        !          2256:                case PCI_PRODUCT_INTEL_82801HBM_IDE:
        !          2257:                        sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA;
        !          2258:                        break;
        !          2259:                }
        !          2260:        }
        !          2261:        sc->sc_wdcdev.PIO_cap = 4;
        !          2262:        sc->sc_wdcdev.DMA_cap = 2;
        !          2263:        switch (sc->sc_pp->ide_product) {
        !          2264:        case PCI_PRODUCT_INTEL_82801AA_IDE:
        !          2265:        case PCI_PRODUCT_INTEL_82372FB_IDE:
        !          2266:                sc->sc_wdcdev.UDMA_cap = 4;
        !          2267:                break;
        !          2268:        case PCI_PRODUCT_INTEL_6300ESB_IDE:
        !          2269:        case PCI_PRODUCT_INTEL_6321ESB_IDE:
        !          2270:        case PCI_PRODUCT_INTEL_82801BAM_IDE:
        !          2271:        case PCI_PRODUCT_INTEL_82801BA_IDE:
        !          2272:        case PCI_PRODUCT_INTEL_82801CAM_IDE:
        !          2273:        case PCI_PRODUCT_INTEL_82801CA_IDE:
        !          2274:        case PCI_PRODUCT_INTEL_82801DB_IDE:
        !          2275:        case PCI_PRODUCT_INTEL_82801DBL_IDE:
        !          2276:        case PCI_PRODUCT_INTEL_82801DBM_IDE:
        !          2277:        case PCI_PRODUCT_INTEL_82801EB_IDE:
        !          2278:        case PCI_PRODUCT_INTEL_82801FB_IDE:
        !          2279:        case PCI_PRODUCT_INTEL_82801GB_IDE:
        !          2280:        case PCI_PRODUCT_INTEL_82801HBM_IDE:
        !          2281:                sc->sc_wdcdev.UDMA_cap = 5;
        !          2282:                break;
        !          2283:        default:
        !          2284:                sc->sc_wdcdev.UDMA_cap = 2;
        !          2285:                break;
        !          2286:        }
        !          2287:
        !          2288:        if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82371FB_IDE ||
        !          2289:                   sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82371FB_ISA) {
        !          2290:                sc->sc_wdcdev.set_modes = piix_setup_channel;
        !          2291:        } else {
        !          2292:                sc->sc_wdcdev.set_modes = piix3_4_setup_channel;
        !          2293:        }
        !          2294:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          2295:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          2296:
        !          2297:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          2298:
        !          2299:        piix_timing_debug(sc);
        !          2300:
        !          2301:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          2302:                cp = &sc->pciide_channels[channel];
        !          2303:
        !          2304:                /* PIIX is compat-only */
        !          2305:                if (pciide_chansetup(sc, channel, 0) == 0)
        !          2306:                        continue;
        !          2307:                idetim = pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_IDETIM);
        !          2308:                if ((PIIX_IDETIM_READ(idetim, channel) &
        !          2309:                    PIIX_IDETIM_IDE) == 0) {
        !          2310:                        printf("%s: %s ignored (disabled)\n",
        !          2311:                            sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          2312:                        continue;
        !          2313:                }
        !          2314:                /* PIIX are compat-only pciide devices */
        !          2315:                pciide_map_compat_intr(pa, cp, channel, 0);
        !          2316:                if (cp->hw_ok == 0)
        !          2317:                        continue;
        !          2318:                pciide_mapchan(pa, cp, 0, &cmdsize, &ctlsize, pciide_pci_intr);
        !          2319:                if (cp->hw_ok == 0)
        !          2320:                        goto next;
        !          2321:                if (pciide_chan_candisable(cp)) {
        !          2322:                        idetim = PIIX_IDETIM_CLEAR(idetim, PIIX_IDETIM_IDE,
        !          2323:                            channel);
        !          2324:                        pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_IDETIM,
        !          2325:                            idetim);
        !          2326:                }
        !          2327:                if (cp->hw_ok == 0)
        !          2328:                        goto next;
        !          2329:                sc->sc_wdcdev.set_modes(&cp->wdc_channel);
        !          2330: next:
        !          2331:                if (cp->hw_ok == 0)
        !          2332:                        pciide_unmap_compat_intr(pa, cp, channel, 0);
        !          2333:        }
        !          2334:
        !          2335:        piix_timing_debug(sc);
        !          2336: }
        !          2337:
        !          2338: void
        !          2339: piixsata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          2340: {
        !          2341:        struct pciide_channel *cp;
        !          2342:        pcireg_t interface = PCI_INTERFACE(pa->pa_class);
        !          2343:        int channel;
        !          2344:        bus_size_t cmdsize, ctlsize;
        !          2345:        u_int8_t reg, ich = 0;
        !          2346:
        !          2347:        printf(": DMA");
        !          2348:        pciide_mapreg_dma(sc, pa);
        !          2349:
        !          2350:        if (sc->sc_dma_ok) {
        !          2351:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA |
        !          2352:                    WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
        !          2353:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          2354:                sc->sc_wdcdev.DMA_cap = 2;
        !          2355:                sc->sc_wdcdev.UDMA_cap = 6;
        !          2356:        }
        !          2357:        sc->sc_wdcdev.PIO_cap = 4;
        !          2358:
        !          2359:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          2360:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          2361:        sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          2362:            WDC_CAPABILITY_MODE | WDC_CAPABILITY_SATA;
        !          2363:        sc->sc_wdcdev.set_modes = sata_setup_channel;
        !          2364:
        !          2365:        switch(sc->sc_pp->ide_product) {
        !          2366:        case PCI_PRODUCT_INTEL_6300ESB_SATA:
        !          2367:        case PCI_PRODUCT_INTEL_6300ESB_SATA2:
        !          2368:        case PCI_PRODUCT_INTEL_82801EB_SATA:
        !          2369:        case PCI_PRODUCT_INTEL_82801ER_SATA:
        !          2370:                ich = 5;
        !          2371:                break;
        !          2372:        case PCI_PRODUCT_INTEL_82801FB_SATA:
        !          2373:        case PCI_PRODUCT_INTEL_82801FR_SATA:
        !          2374:        case PCI_PRODUCT_INTEL_82801FBM_SATA:
        !          2375:                ich = 6;
        !          2376:                break;
        !          2377:        default:
        !          2378:                ich = 7;
        !          2379:                break;
        !          2380:        }
        !          2381:
        !          2382:        /*
        !          2383:         * Put the SATA portion of controllers that don't operate in combined
        !          2384:         * mode into native PCI modes so the maximum number of devices can be
        !          2385:         * used.  Intel calls this "enhanced mode"
        !          2386:         */
        !          2387:        if (ich == 5) {
        !          2388:                reg = pciide_pci_read(sc->sc_pc, sc->sc_tag, ICH5_SATA_MAP);
        !          2389:                if ((reg & ICH5_SATA_MAP_COMBINED) == 0) {
        !          2390:                        reg = pciide_pci_read(pa->pa_pc, pa->pa_tag,
        !          2391:                            ICH5_SATA_PI);
        !          2392:                        reg |= ICH5_SATA_PI_PRI_NATIVE |
        !          2393:                            ICH5_SATA_PI_SEC_NATIVE;
        !          2394:                        pciide_pci_write(pa->pa_pc, pa->pa_tag,
        !          2395:                            ICH5_SATA_PI, reg);
        !          2396:                        interface |= PCIIDE_INTERFACE_PCI(0) |
        !          2397:                            PCIIDE_INTERFACE_PCI(1);
        !          2398:                }
        !          2399:        } else {
        !          2400:                reg = pciide_pci_read(sc->sc_pc, sc->sc_tag, ICH5_SATA_MAP) &
        !          2401:                    ICH6_SATA_MAP_CMB_MASK;
        !          2402:                if (reg != ICH6_SATA_MAP_CMB_PRI &&
        !          2403:                    reg != ICH6_SATA_MAP_CMB_SEC) {
        !          2404:                        reg = pciide_pci_read(pa->pa_pc, pa->pa_tag,
        !          2405:                            ICH5_SATA_PI);
        !          2406:                        reg |= ICH5_SATA_PI_PRI_NATIVE |
        !          2407:                            ICH5_SATA_PI_SEC_NATIVE;
        !          2408:
        !          2409:                        pciide_pci_write(pa->pa_pc, pa->pa_tag,
        !          2410:                            ICH5_SATA_PI, reg);
        !          2411:                        interface |= PCIIDE_INTERFACE_PCI(0) |
        !          2412:                            PCIIDE_INTERFACE_PCI(1);
        !          2413:
        !          2414:                        /*
        !          2415:                         * Ask for SATA IDE Mode, we don't need to do this
        !          2416:                         * for the combined mode case as combined mode is
        !          2417:                         * only allowed in IDE Mode
        !          2418:                         */
        !          2419:                        if (ich >= 7) {
        !          2420:                                reg = pciide_pci_read(sc->sc_pc, sc->sc_tag,
        !          2421:                                    ICH5_SATA_MAP) & ~ICH7_SATA_MAP_SMS_MASK;
        !          2422:                                pciide_pci_write(pa->pa_pc, pa->pa_tag,
        !          2423:                                    ICH5_SATA_MAP, reg);
        !          2424:                        }
        !          2425:                }
        !          2426:        }
        !          2427:
        !          2428:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          2429:
        !          2430:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          2431:                cp = &sc->pciide_channels[channel];
        !          2432:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          2433:                        continue;
        !          2434:
        !          2435:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          2436:                if (cp->hw_ok == 0)
        !          2437:                        continue;
        !          2438:
        !          2439:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          2440:                    pciide_pci_intr);
        !          2441:                if (cp->hw_ok != 0)
        !          2442:                        sc->sc_wdcdev.set_modes(&cp->wdc_channel);
        !          2443:
        !          2444:                if (cp->hw_ok == 0)
        !          2445:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          2446:        }
        !          2447: }
        !          2448:
        !          2449: void
        !          2450: piix_setup_channel(struct channel_softc *chp)
        !          2451: {
        !          2452:        u_int8_t mode[2], drive;
        !          2453:        u_int32_t oidetim, idetim, idedma_ctl;
        !          2454:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          2455:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          2456:        struct ata_drive_datas *drvp = cp->wdc_channel.ch_drive;
        !          2457:
        !          2458:        oidetim = pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_IDETIM);
        !          2459:        idetim = PIIX_IDETIM_CLEAR(oidetim, 0xffff, chp->channel);
        !          2460:        idedma_ctl = 0;
        !          2461:
        !          2462:        /* set up new idetim: Enable IDE registers decode */
        !          2463:        idetim = PIIX_IDETIM_SET(idetim, PIIX_IDETIM_IDE,
        !          2464:            chp->channel);
        !          2465:
        !          2466:        /* setup DMA */
        !          2467:        pciide_channel_dma_setup(cp);
        !          2468:
        !          2469:        /*
        !          2470:         * Here we have to mess up with drives mode: PIIX can't have
        !          2471:         * different timings for master and slave drives.
        !          2472:         * We need to find the best combination.
        !          2473:         */
        !          2474:
        !          2475:        /* If both drives supports DMA, take the lower mode */
        !          2476:        if ((drvp[0].drive_flags & DRIVE_DMA) &&
        !          2477:            (drvp[1].drive_flags & DRIVE_DMA)) {
        !          2478:                mode[0] = mode[1] =
        !          2479:                    min(drvp[0].DMA_mode, drvp[1].DMA_mode);
        !          2480:                    drvp[0].DMA_mode = mode[0];
        !          2481:                    drvp[1].DMA_mode = mode[1];
        !          2482:                goto ok;
        !          2483:        }
        !          2484:        /*
        !          2485:         * If only one drive supports DMA, use its mode, and
        !          2486:         * put the other one in PIO mode 0 if mode not compatible
        !          2487:         */
        !          2488:        if (drvp[0].drive_flags & DRIVE_DMA) {
        !          2489:                mode[0] = drvp[0].DMA_mode;
        !          2490:                mode[1] = drvp[1].PIO_mode;
        !          2491:                if (piix_isp_pio[mode[1]] != piix_isp_dma[mode[0]] ||
        !          2492:                    piix_rtc_pio[mode[1]] != piix_rtc_dma[mode[0]])
        !          2493:                        mode[1] = drvp[1].PIO_mode = 0;
        !          2494:                goto ok;
        !          2495:        }
        !          2496:        if (drvp[1].drive_flags & DRIVE_DMA) {
        !          2497:                mode[1] = drvp[1].DMA_mode;
        !          2498:                mode[0] = drvp[0].PIO_mode;
        !          2499:                if (piix_isp_pio[mode[0]] != piix_isp_dma[mode[1]] ||
        !          2500:                    piix_rtc_pio[mode[0]] != piix_rtc_dma[mode[1]])
        !          2501:                        mode[0] = drvp[0].PIO_mode = 0;
        !          2502:                goto ok;
        !          2503:        }
        !          2504:        /*
        !          2505:         * If both drives are not DMA, takes the lower mode, unless
        !          2506:         * one of them is PIO mode < 2
        !          2507:         */
        !          2508:        if (drvp[0].PIO_mode < 2) {
        !          2509:                mode[0] = drvp[0].PIO_mode = 0;
        !          2510:                mode[1] = drvp[1].PIO_mode;
        !          2511:        } else if (drvp[1].PIO_mode < 2) {
        !          2512:                mode[1] = drvp[1].PIO_mode = 0;
        !          2513:                mode[0] = drvp[0].PIO_mode;
        !          2514:        } else {
        !          2515:                mode[0] = mode[1] =
        !          2516:                    min(drvp[1].PIO_mode, drvp[0].PIO_mode);
        !          2517:                drvp[0].PIO_mode = mode[0];
        !          2518:                drvp[1].PIO_mode = mode[1];
        !          2519:        }
        !          2520: ok:    /* The modes are setup */
        !          2521:        for (drive = 0; drive < 2; drive++) {
        !          2522:                if (drvp[drive].drive_flags & DRIVE_DMA) {
        !          2523:                        idetim |= piix_setup_idetim_timings(
        !          2524:                            mode[drive], 1, chp->channel);
        !          2525:                        goto end;
        !          2526:                }
        !          2527:        }
        !          2528:        /* If we are there, none of the drives are DMA */
        !          2529:        if (mode[0] >= 2)
        !          2530:                idetim |= piix_setup_idetim_timings(
        !          2531:                    mode[0], 0, chp->channel);
        !          2532:        else
        !          2533:                idetim |= piix_setup_idetim_timings(
        !          2534:                    mode[1], 0, chp->channel);
        !          2535: end:   /*
        !          2536:         * timing mode is now set up in the controller. Enable
        !          2537:         * it per-drive
        !          2538:         */
        !          2539:        for (drive = 0; drive < 2; drive++) {
        !          2540:                /* If no drive, skip */
        !          2541:                if ((drvp[drive].drive_flags & DRIVE) == 0)
        !          2542:                        continue;
        !          2543:                idetim |= piix_setup_idetim_drvs(&drvp[drive]);
        !          2544:                if (drvp[drive].drive_flags & DRIVE_DMA)
        !          2545:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          2546:        }
        !          2547:        if (idedma_ctl != 0) {
        !          2548:                /* Add software bits in status register */
        !          2549:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          2550:                    IDEDMA_CTL(chp->channel),
        !          2551:                    idedma_ctl);
        !          2552:        }
        !          2553:        pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_IDETIM, idetim);
        !          2554:        pciide_print_modes(cp);
        !          2555: }
        !          2556:
        !          2557: void
        !          2558: piix3_4_setup_channel(struct channel_softc *chp)
        !          2559: {
        !          2560:        struct ata_drive_datas *drvp;
        !          2561:        u_int32_t oidetim, idetim, sidetim, udmareg, ideconf, idedma_ctl;
        !          2562:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          2563:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          2564:        int drive;
        !          2565:        int channel = chp->channel;
        !          2566:
        !          2567:        oidetim = pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_IDETIM);
        !          2568:        sidetim = pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_SIDETIM);
        !          2569:        udmareg = pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_UDMAREG);
        !          2570:        ideconf = pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_CONFIG);
        !          2571:        idetim = PIIX_IDETIM_CLEAR(oidetim, 0xffff, channel);
        !          2572:        sidetim &= ~(PIIX_SIDETIM_ISP_MASK(channel) |
        !          2573:            PIIX_SIDETIM_RTC_MASK(channel));
        !          2574:
        !          2575:        idedma_ctl = 0;
        !          2576:        /* If channel disabled, no need to go further */
        !          2577:        if ((PIIX_IDETIM_READ(oidetim, channel) & PIIX_IDETIM_IDE) == 0)
        !          2578:                return;
        !          2579:        /* set up new idetim: Enable IDE registers decode */
        !          2580:        idetim = PIIX_IDETIM_SET(idetim, PIIX_IDETIM_IDE, channel);
        !          2581:
        !          2582:        /* setup DMA if needed */
        !          2583:        pciide_channel_dma_setup(cp);
        !          2584:
        !          2585:        for (drive = 0; drive < 2; drive++) {
        !          2586:                udmareg &= ~(PIIX_UDMACTL_DRV_EN(channel, drive) |
        !          2587:                    PIIX_UDMATIM_SET(0x3, channel, drive));
        !          2588:                drvp = &chp->ch_drive[drive];
        !          2589:                /* If no drive, skip */
        !          2590:                if ((drvp->drive_flags & DRIVE) == 0)
        !          2591:                        continue;
        !          2592:                if (((drvp->drive_flags & DRIVE_DMA) == 0 &&
        !          2593:                    (drvp->drive_flags & DRIVE_UDMA) == 0))
        !          2594:                        goto pio;
        !          2595:
        !          2596:                if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_6300ESB_IDE ||
        !          2597:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_6321ESB_IDE ||
        !          2598:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801AA_IDE ||
        !          2599:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801AB_IDE ||
        !          2600:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BAM_IDE ||
        !          2601:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BA_IDE ||
        !          2602:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801CAM_IDE ||
        !          2603:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801CA_IDE ||
        !          2604:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DB_IDE ||
        !          2605:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DBL_IDE ||
        !          2606:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DBM_IDE ||
        !          2607:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801EB_IDE ||
        !          2608:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801FB_IDE ||
        !          2609:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801GB_IDE ||
        !          2610:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801HBM_IDE ||
        !          2611:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82372FB_IDE) {
        !          2612:                        ideconf |= PIIX_CONFIG_PINGPONG;
        !          2613:                }
        !          2614:                if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_6300ESB_IDE ||
        !          2615:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_6321ESB_IDE ||
        !          2616:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BAM_IDE ||
        !          2617:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801BA_IDE||
        !          2618:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801CAM_IDE||
        !          2619:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801CA_IDE ||
        !          2620:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DB_IDE ||
        !          2621:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DBL_IDE ||
        !          2622:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801DBM_IDE ||
        !          2623:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801EB_IDE ||
        !          2624:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801FB_IDE ||
        !          2625:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801GB_IDE ||
        !          2626:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801HBM_IDE) {
        !          2627:                        /* setup Ultra/100 */
        !          2628:                        if (drvp->UDMA_mode > 2 &&
        !          2629:                            (ideconf & PIIX_CONFIG_CR(channel, drive)) == 0)
        !          2630:                                drvp->UDMA_mode = 2;
        !          2631:                        if (drvp->UDMA_mode > 4) {
        !          2632:                                ideconf |= PIIX_CONFIG_UDMA100(channel, drive);
        !          2633:                        } else {
        !          2634:                                ideconf &= ~PIIX_CONFIG_UDMA100(channel, drive);
        !          2635:                                if (drvp->UDMA_mode > 2) {
        !          2636:                                        ideconf |= PIIX_CONFIG_UDMA66(channel,
        !          2637:                                            drive);
        !          2638:                                } else {
        !          2639:                                        ideconf &= ~PIIX_CONFIG_UDMA66(channel,
        !          2640:                                            drive);
        !          2641:                                }
        !          2642:                        }
        !          2643:                }
        !          2644:                if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801AA_IDE ||
        !          2645:                    sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82372FB_IDE) {
        !          2646:                        /* setup Ultra/66 */
        !          2647:                        if (drvp->UDMA_mode > 2 &&
        !          2648:                            (ideconf & PIIX_CONFIG_CR(channel, drive)) == 0)
        !          2649:                                drvp->UDMA_mode = 2;
        !          2650:                        if (drvp->UDMA_mode > 2)
        !          2651:                                ideconf |= PIIX_CONFIG_UDMA66(channel, drive);
        !          2652:                        else
        !          2653:                                ideconf &= ~PIIX_CONFIG_UDMA66(channel, drive);
        !          2654:                }
        !          2655:
        !          2656:                if ((chp->wdc->cap & WDC_CAPABILITY_UDMA) &&
        !          2657:                    (drvp->drive_flags & DRIVE_UDMA)) {
        !          2658:                        /* use Ultra/DMA */
        !          2659:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          2660:                        udmareg |= PIIX_UDMACTL_DRV_EN( channel, drive);
        !          2661:                        udmareg |= PIIX_UDMATIM_SET(
        !          2662:                            piix4_sct_udma[drvp->UDMA_mode], channel, drive);
        !          2663:                } else {
        !          2664:                        /* use Multiword DMA */
        !          2665:                        drvp->drive_flags &= ~DRIVE_UDMA;
        !          2666:                        if (drive == 0) {
        !          2667:                                idetim |= piix_setup_idetim_timings(
        !          2668:                                    drvp->DMA_mode, 1, channel);
        !          2669:                        } else {
        !          2670:                                sidetim |= piix_setup_sidetim_timings(
        !          2671:                                        drvp->DMA_mode, 1, channel);
        !          2672:                                idetim =PIIX_IDETIM_SET(idetim,
        !          2673:                                    PIIX_IDETIM_SITRE, channel);
        !          2674:                        }
        !          2675:                }
        !          2676:                idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          2677:
        !          2678: pio:           /* use PIO mode */
        !          2679:                idetim |= piix_setup_idetim_drvs(drvp);
        !          2680:                if (drive == 0) {
        !          2681:                        idetim |= piix_setup_idetim_timings(
        !          2682:                            drvp->PIO_mode, 0, channel);
        !          2683:                } else {
        !          2684:                        sidetim |= piix_setup_sidetim_timings(
        !          2685:                                drvp->PIO_mode, 0, channel);
        !          2686:                        idetim =PIIX_IDETIM_SET(idetim,
        !          2687:                            PIIX_IDETIM_SITRE, channel);
        !          2688:                }
        !          2689:        }
        !          2690:        if (idedma_ctl != 0) {
        !          2691:                /* Add software bits in status register */
        !          2692:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          2693:                    IDEDMA_CTL(channel),
        !          2694:                    idedma_ctl);
        !          2695:        }
        !          2696:        pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_IDETIM, idetim);
        !          2697:        pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_SIDETIM, sidetim);
        !          2698:        pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_UDMAREG, udmareg);
        !          2699:        pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_CONFIG, ideconf);
        !          2700:        pciide_print_modes(cp);
        !          2701: }
        !          2702:
        !          2703:
        !          2704: /* setup ISP and RTC fields, based on mode */
        !          2705: static u_int32_t
        !          2706: piix_setup_idetim_timings(u_int8_t mode, u_int8_t dma, u_int8_t channel)
        !          2707: {
        !          2708:
        !          2709:        if (dma)
        !          2710:                return (PIIX_IDETIM_SET(0,
        !          2711:                    PIIX_IDETIM_ISP_SET(piix_isp_dma[mode]) |
        !          2712:                    PIIX_IDETIM_RTC_SET(piix_rtc_dma[mode]),
        !          2713:                    channel));
        !          2714:        else
        !          2715:                return (PIIX_IDETIM_SET(0,
        !          2716:                    PIIX_IDETIM_ISP_SET(piix_isp_pio[mode]) |
        !          2717:                    PIIX_IDETIM_RTC_SET(piix_rtc_pio[mode]),
        !          2718:                    channel));
        !          2719: }
        !          2720:
        !          2721: /* setup DTE, PPE, IE and TIME field based on PIO mode */
        !          2722: static u_int32_t
        !          2723: piix_setup_idetim_drvs(struct ata_drive_datas *drvp)
        !          2724: {
        !          2725:        u_int32_t ret = 0;
        !          2726:        struct channel_softc *chp = drvp->chnl_softc;
        !          2727:        u_int8_t channel = chp->channel;
        !          2728:        u_int8_t drive = drvp->drive;
        !          2729:
        !          2730:        /*
        !          2731:         * If drive is using UDMA, timings setups are independant
        !          2732:         * So just check DMA and PIO here.
        !          2733:         */
        !          2734:        if (drvp->drive_flags & DRIVE_DMA) {
        !          2735:                /* if mode = DMA mode 0, use compatible timings */
        !          2736:                if ((drvp->drive_flags & DRIVE_DMA) &&
        !          2737:                    drvp->DMA_mode == 0) {
        !          2738:                        drvp->PIO_mode = 0;
        !          2739:                        return (ret);
        !          2740:                }
        !          2741:                ret = PIIX_IDETIM_SET(ret, PIIX_IDETIM_TIME(drive), channel);
        !          2742:                /*
        !          2743:                 * PIO and DMA timings are the same, use fast timings for PIO
        !          2744:                 * too, else use compat timings.
        !          2745:                 */
        !          2746:                if ((piix_isp_pio[drvp->PIO_mode] !=
        !          2747:                    piix_isp_dma[drvp->DMA_mode]) ||
        !          2748:                    (piix_rtc_pio[drvp->PIO_mode] !=
        !          2749:                    piix_rtc_dma[drvp->DMA_mode]))
        !          2750:                        drvp->PIO_mode = 0;
        !          2751:                /* if PIO mode <= 2, use compat timings for PIO */
        !          2752:                if (drvp->PIO_mode <= 2) {
        !          2753:                        ret = PIIX_IDETIM_SET(ret, PIIX_IDETIM_DTE(drive),
        !          2754:                            channel);
        !          2755:                        return (ret);
        !          2756:                }
        !          2757:        }
        !          2758:
        !          2759:        /*
        !          2760:         * Now setup PIO modes. If mode < 2, use compat timings.
        !          2761:         * Else enable fast timings. Enable IORDY and prefetch/post
        !          2762:         * if PIO mode >= 3.
        !          2763:         */
        !          2764:
        !          2765:        if (drvp->PIO_mode < 2)
        !          2766:                return (ret);
        !          2767:
        !          2768:        ret = PIIX_IDETIM_SET(ret, PIIX_IDETIM_TIME(drive), channel);
        !          2769:        if (drvp->PIO_mode >= 3) {
        !          2770:                ret = PIIX_IDETIM_SET(ret, PIIX_IDETIM_IE(drive), channel);
        !          2771:                ret = PIIX_IDETIM_SET(ret, PIIX_IDETIM_PPE(drive), channel);
        !          2772:        }
        !          2773:        return (ret);
        !          2774: }
        !          2775:
        !          2776: /* setup values in SIDETIM registers, based on mode */
        !          2777: static u_int32_t
        !          2778: piix_setup_sidetim_timings(u_int8_t mode, u_int8_t dma, u_int8_t channel)
        !          2779: {
        !          2780:        if (dma)
        !          2781:                return (PIIX_SIDETIM_ISP_SET(piix_isp_dma[mode], channel) |
        !          2782:                    PIIX_SIDETIM_RTC_SET(piix_rtc_dma[mode], channel));
        !          2783:        else
        !          2784:                return (PIIX_SIDETIM_ISP_SET(piix_isp_pio[mode], channel) |
        !          2785:                    PIIX_SIDETIM_RTC_SET(piix_rtc_pio[mode], channel));
        !          2786: }
        !          2787:
        !          2788: void
        !          2789: amd756_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          2790: {
        !          2791:        struct pciide_channel *cp;
        !          2792:        pcireg_t interface = PCI_INTERFACE(pa->pa_class);
        !          2793:        int channel;
        !          2794:        pcireg_t chanenable;
        !          2795:        bus_size_t cmdsize, ctlsize;
        !          2796:
        !          2797:        printf(": DMA");
        !          2798:        pciide_mapreg_dma(sc, pa);
        !          2799:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          2800:            WDC_CAPABILITY_MODE;
        !          2801:        if (sc->sc_dma_ok) {
        !          2802:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
        !          2803:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          2804:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          2805:        }
        !          2806:        sc->sc_wdcdev.PIO_cap = 4;
        !          2807:        sc->sc_wdcdev.DMA_cap = 2;
        !          2808:        switch (sc->sc_pp->ide_product) {
        !          2809:        case PCI_PRODUCT_AMD_8111_IDE:
        !          2810:                sc->sc_wdcdev.UDMA_cap = 6;
        !          2811:                break;
        !          2812:        case PCI_PRODUCT_AMD_766_IDE:
        !          2813:        case PCI_PRODUCT_AMD_PBC768_IDE:
        !          2814:                sc->sc_wdcdev.UDMA_cap = 5;
        !          2815:                break;
        !          2816:        default:
        !          2817:                sc->sc_wdcdev.UDMA_cap = 4;
        !          2818:                break;
        !          2819:        }
        !          2820:        sc->sc_wdcdev.set_modes = amd756_setup_channel;
        !          2821:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          2822:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          2823:        chanenable = pci_conf_read(sc->sc_pc, sc->sc_tag, AMD756_CHANSTATUS_EN);
        !          2824:
        !          2825:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          2826:
        !          2827:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          2828:                cp = &sc->pciide_channels[channel];
        !          2829:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          2830:                        continue;
        !          2831:
        !          2832:                if ((chanenable & AMD756_CHAN_EN(channel)) == 0) {
        !          2833:                        printf("%s: %s ignored (disabled)\n",
        !          2834:                            sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          2835:                        continue;
        !          2836:                }
        !          2837:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          2838:                if (cp->hw_ok == 0)
        !          2839:                        continue;
        !          2840:
        !          2841:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          2842:                    pciide_pci_intr);
        !          2843:
        !          2844:                if (pciide_chan_candisable(cp)) {
        !          2845:                        chanenable &= ~AMD756_CHAN_EN(channel);
        !          2846:                }
        !          2847:                if (cp->hw_ok == 0) {
        !          2848:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          2849:                        continue;
        !          2850:                }
        !          2851:
        !          2852:                amd756_setup_channel(&cp->wdc_channel);
        !          2853:        }
        !          2854:        pci_conf_write(sc->sc_pc, sc->sc_tag, AMD756_CHANSTATUS_EN,
        !          2855:            chanenable);
        !          2856:        return;
        !          2857: }
        !          2858:
        !          2859: void
        !          2860: amd756_setup_channel(struct channel_softc *chp)
        !          2861: {
        !          2862:        u_int32_t udmatim_reg, datatim_reg;
        !          2863:        u_int8_t idedma_ctl;
        !          2864:        int mode, drive;
        !          2865:        struct ata_drive_datas *drvp;
        !          2866:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          2867:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          2868:        pcireg_t chanenable;
        !          2869: #ifndef        PCIIDE_AMD756_ENABLEDMA
        !          2870:        int product = sc->sc_pp->ide_product;
        !          2871:        int rev = sc->sc_rev;
        !          2872: #endif
        !          2873:
        !          2874:        idedma_ctl = 0;
        !          2875:        datatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, AMD756_DATATIM);
        !          2876:        udmatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, AMD756_UDMA);
        !          2877:        datatim_reg &= ~AMD756_DATATIM_MASK(chp->channel);
        !          2878:        udmatim_reg &= ~AMD756_UDMA_MASK(chp->channel);
        !          2879:        chanenable = pci_conf_read(sc->sc_pc, sc->sc_tag,
        !          2880:            AMD756_CHANSTATUS_EN);
        !          2881:
        !          2882:        /* setup DMA if needed */
        !          2883:        pciide_channel_dma_setup(cp);
        !          2884:
        !          2885:        for (drive = 0; drive < 2; drive++) {
        !          2886:                drvp = &chp->ch_drive[drive];
        !          2887:                /* If no drive, skip */
        !          2888:                if ((drvp->drive_flags & DRIVE) == 0)
        !          2889:                        continue;
        !          2890:                /* add timing values, setup DMA if needed */
        !          2891:                if (((drvp->drive_flags & DRIVE_DMA) == 0 &&
        !          2892:                    (drvp->drive_flags & DRIVE_UDMA) == 0)) {
        !          2893:                        mode = drvp->PIO_mode;
        !          2894:                        goto pio;
        !          2895:                }
        !          2896:                if ((chp->wdc->cap & WDC_CAPABILITY_UDMA) &&
        !          2897:                    (drvp->drive_flags & DRIVE_UDMA)) {
        !          2898:                        /* use Ultra/DMA */
        !          2899:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          2900:
        !          2901:                        /* Check cable */
        !          2902:                        if ((chanenable & AMD756_CABLE(chp->channel,
        !          2903:                            drive)) == 0 && drvp->UDMA_mode > 2) {
        !          2904:                                WDCDEBUG_PRINT(("%s(%s:%d:%d): 80-wire "
        !          2905:                                    "cable not detected\n", drvp->drive_name,
        !          2906:                                    sc->sc_wdcdev.sc_dev.dv_xname,
        !          2907:                                    chp->channel, drive), DEBUG_PROBE);
        !          2908:                                drvp->UDMA_mode = 2;
        !          2909:                        }
        !          2910:
        !          2911:                        udmatim_reg |= AMD756_UDMA_EN(chp->channel, drive) |
        !          2912:                            AMD756_UDMA_EN_MTH(chp->channel, drive) |
        !          2913:                            AMD756_UDMA_TIME(chp->channel, drive,
        !          2914:                                amd756_udma_tim[drvp->UDMA_mode]);
        !          2915:                        /* can use PIO timings, MW DMA unused */
        !          2916:                        mode = drvp->PIO_mode;
        !          2917:                } else {
        !          2918:                        /* use Multiword DMA, but only if revision is OK */
        !          2919:                        drvp->drive_flags &= ~DRIVE_UDMA;
        !          2920: #ifndef PCIIDE_AMD756_ENABLEDMA
        !          2921:                        /*
        !          2922:                         * The workaround doesn't seem to be necessary
        !          2923:                         * with all drives, so it can be disabled by
        !          2924:                         * PCIIDE_AMD756_ENABLEDMA. It causes a hard hang if
        !          2925:                         * triggered.
        !          2926:                         */
        !          2927:                        if (AMD756_CHIPREV_DISABLEDMA(product, rev)) {
        !          2928:                                printf("%s:%d:%d: multi-word DMA disabled due "
        !          2929:                                    "to chip revision\n",
        !          2930:                                    sc->sc_wdcdev.sc_dev.dv_xname,
        !          2931:                                    chp->channel, drive);
        !          2932:                                mode = drvp->PIO_mode;
        !          2933:                                drvp->drive_flags &= ~DRIVE_DMA;
        !          2934:                                goto pio;
        !          2935:                        }
        !          2936: #endif
        !          2937:                        /* mode = min(pio, dma+2) */
        !          2938:                        if (drvp->PIO_mode <= (drvp->DMA_mode +2))
        !          2939:                                mode = drvp->PIO_mode;
        !          2940:                        else
        !          2941:                                mode = drvp->DMA_mode + 2;
        !          2942:                }
        !          2943:                idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          2944:
        !          2945: pio:           /* setup PIO mode */
        !          2946:                if (mode <= 2) {
        !          2947:                        drvp->DMA_mode = 0;
        !          2948:                        drvp->PIO_mode = 0;
        !          2949:                        mode = 0;
        !          2950:                } else {
        !          2951:                        drvp->PIO_mode = mode;
        !          2952:                        drvp->DMA_mode = mode - 2;
        !          2953:                }
        !          2954:                datatim_reg |=
        !          2955:                    AMD756_DATATIM_PULSE(chp->channel, drive,
        !          2956:                        amd756_pio_set[mode]) |
        !          2957:                    AMD756_DATATIM_RECOV(chp->channel, drive,
        !          2958:                        amd756_pio_rec[mode]);
        !          2959:        }
        !          2960:        if (idedma_ctl != 0) {
        !          2961:                /* Add software bits in status register */
        !          2962:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          2963:                    IDEDMA_CTL(chp->channel),
        !          2964:                    idedma_ctl);
        !          2965:        }
        !          2966:        pciide_print_modes(cp);
        !          2967:        pci_conf_write(sc->sc_pc, sc->sc_tag, AMD756_DATATIM, datatim_reg);
        !          2968:        pci_conf_write(sc->sc_pc, sc->sc_tag, AMD756_UDMA, udmatim_reg);
        !          2969: }
        !          2970:
        !          2971: void
        !          2972: apollo_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          2973: {
        !          2974:        struct pciide_channel *cp;
        !          2975:        pcireg_t interface;
        !          2976:        int channel;
        !          2977:        u_int32_t ideconf;
        !          2978:        bus_size_t cmdsize, ctlsize;
        !          2979:        pcitag_t tag;
        !          2980:        pcireg_t id, class;
        !          2981:
        !          2982:        /*
        !          2983:         * Fake interface since VT6410 is claimed to be a ``RAID'' device.
        !          2984:         */
        !          2985:        if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_IDE) {
        !          2986:                interface = PCI_INTERFACE(pa->pa_class);
        !          2987:        } else {
        !          2988:                interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
        !          2989:                    PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
        !          2990:        }
        !          2991:
        !          2992:        if ((PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VT6410) ||
        !          2993:            (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_CX700_IDE)) {
        !          2994:                printf(": ATA133");
        !          2995:                sc->sc_wdcdev.UDMA_cap = 6;
        !          2996:        } else {
        !          2997:                /*
        !          2998:                 * Determine the DMA capabilities by looking at the
        !          2999:                 * ISA bridge.
        !          3000:                 */
        !          3001:                tag = pci_make_tag(pa->pa_pc, pa->pa_bus, pa->pa_device, 0);
        !          3002:                id = pci_conf_read(sc->sc_pc, tag, PCI_ID_REG);
        !          3003:                class = pci_conf_read(sc->sc_pc, tag, PCI_CLASS_REG);
        !          3004:
        !          3005:                /*
        !          3006:                 * XXX On the VT8237, the ISA bridge is on a different
        !          3007:                 * device.
        !          3008:                 */
        !          3009:                if (PCI_CLASS(class) != PCI_CLASS_BRIDGE &&
        !          3010:                    pa->pa_device == 15) {
        !          3011:                        tag = pci_make_tag(pa->pa_pc, pa->pa_bus, 17, 0);
        !          3012:                        id = pci_conf_read(sc->sc_pc, tag, PCI_ID_REG);
        !          3013:                        class = pci_conf_read(sc->sc_pc, tag, PCI_CLASS_REG);
        !          3014:                }
        !          3015:
        !          3016:                switch (PCI_PRODUCT(id)) {
        !          3017:                case PCI_PRODUCT_VIATECH_VT82C586_ISA:
        !          3018:                        if (PCI_REVISION(class) >= 0x02) {
        !          3019:                                printf(": ATA33");
        !          3020:                                sc->sc_wdcdev.UDMA_cap = 2;
        !          3021:                        } else {
        !          3022:                                printf(": DMA");
        !          3023:                                sc->sc_wdcdev.UDMA_cap = 0;
        !          3024:                        }
        !          3025:                        break;
        !          3026:                case PCI_PRODUCT_VIATECH_VT82C596A:
        !          3027:                        if (PCI_REVISION(class) >= 0x12) {
        !          3028:                                printf(": ATA66");
        !          3029:                                sc->sc_wdcdev.UDMA_cap = 4;
        !          3030:                        } else {
        !          3031:                                printf(": ATA33");
        !          3032:                                sc->sc_wdcdev.UDMA_cap = 2;
        !          3033:                        }
        !          3034:                        break;
        !          3035:
        !          3036:                case PCI_PRODUCT_VIATECH_VT82C686A_ISA:
        !          3037:                        if (PCI_REVISION(class) >= 0x40) {
        !          3038:                                printf(": ATA100");
        !          3039:                                sc->sc_wdcdev.UDMA_cap = 5;
        !          3040:                        } else {
        !          3041:                                printf(": ATA66");
        !          3042:                                sc->sc_wdcdev.UDMA_cap = 4;
        !          3043:                        }
        !          3044:                        break;
        !          3045:                case PCI_PRODUCT_VIATECH_VT8231_ISA:
        !          3046:                case PCI_PRODUCT_VIATECH_VT8233_ISA:
        !          3047:                        printf(": ATA100");
        !          3048:                        sc->sc_wdcdev.UDMA_cap = 5;
        !          3049:                        break;
        !          3050:                case PCI_PRODUCT_VIATECH_VT8233A_ISA:
        !          3051:                case PCI_PRODUCT_VIATECH_VT8235_ISA:
        !          3052:                case PCI_PRODUCT_VIATECH_VT8237_ISA:
        !          3053:                        printf(": ATA133");
        !          3054:                        sc->sc_wdcdev.UDMA_cap = 6;
        !          3055:                        break;
        !          3056:                default:
        !          3057:                        printf(": DMA");
        !          3058:                        sc->sc_wdcdev.UDMA_cap = 0;
        !          3059:                        break;
        !          3060:                }
        !          3061:        }
        !          3062:
        !          3063:        pciide_mapreg_dma(sc, pa);
        !          3064:        sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          3065:            WDC_CAPABILITY_MODE;
        !          3066:        if (sc->sc_dma_ok) {
        !          3067:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
        !          3068:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          3069:                if (sc->sc_wdcdev.UDMA_cap > 0)
        !          3070:                        sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA;
        !          3071:        }
        !          3072:        sc->sc_wdcdev.PIO_cap = 4;
        !          3073:        sc->sc_wdcdev.DMA_cap = 2;
        !          3074:        sc->sc_wdcdev.set_modes = apollo_setup_channel;
        !          3075:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          3076:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          3077:
        !          3078:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          3079:
        !          3080:        WDCDEBUG_PRINT(("apollo_chip_map: old APO_IDECONF=0x%x, "
        !          3081:            "APO_CTLMISC=0x%x, APO_DATATIM=0x%x, APO_UDMA=0x%x\n",
        !          3082:            pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF),
        !          3083:            pci_conf_read(sc->sc_pc, sc->sc_tag, APO_CTLMISC),
        !          3084:            pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM),
        !          3085:            pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA)),
        !          3086:            DEBUG_PROBE);
        !          3087:
        !          3088:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          3089:                cp = &sc->pciide_channels[channel];
        !          3090:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          3091:                        continue;
        !          3092:
        !          3093:                ideconf = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF);
        !          3094:                if ((ideconf & APO_IDECONF_EN(channel)) == 0) {
        !          3095:                        printf("%s: %s ignored (disabled)\n",
        !          3096:                            sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          3097:                        continue;
        !          3098:                }
        !          3099:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          3100:                if (cp->hw_ok == 0)
        !          3101:                        continue;
        !          3102:
        !          3103:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          3104:                    pciide_pci_intr);
        !          3105:                if (cp->hw_ok == 0) {
        !          3106:                        goto next;
        !          3107:                }
        !          3108:                if (pciide_chan_candisable(cp)) {
        !          3109:                        ideconf &= ~APO_IDECONF_EN(channel);
        !          3110:                        pci_conf_write(sc->sc_pc, sc->sc_tag, APO_IDECONF,
        !          3111:                            ideconf);
        !          3112:                }
        !          3113:
        !          3114:                if (cp->hw_ok == 0)
        !          3115:                        goto next;
        !          3116:                apollo_setup_channel(&sc->pciide_channels[channel].wdc_channel);
        !          3117: next:
        !          3118:                if (cp->hw_ok == 0)
        !          3119:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          3120:        }
        !          3121:        WDCDEBUG_PRINT(("apollo_chip_map: APO_DATATIM=0x%x, APO_UDMA=0x%x\n",
        !          3122:            pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM),
        !          3123:            pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA)), DEBUG_PROBE);
        !          3124: }
        !          3125:
        !          3126: void
        !          3127: apollo_setup_channel(struct channel_softc *chp)
        !          3128: {
        !          3129:        u_int32_t udmatim_reg, datatim_reg;
        !          3130:        u_int8_t idedma_ctl;
        !          3131:        int mode, drive;
        !          3132:        struct ata_drive_datas *drvp;
        !          3133:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          3134:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          3135:
        !          3136:        idedma_ctl = 0;
        !          3137:        datatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM);
        !          3138:        udmatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA);
        !          3139:        datatim_reg &= ~APO_DATATIM_MASK(chp->channel);
        !          3140:        udmatim_reg &= ~APO_UDMA_MASK(chp->channel);
        !          3141:
        !          3142:        /* setup DMA if needed */
        !          3143:        pciide_channel_dma_setup(cp);
        !          3144:
        !          3145:        /*
        !          3146:         * We can't mix Ultra/33 and Ultra/66 on the same channel, so
        !          3147:         * downgrade to Ultra/33 if needed
        !          3148:         */
        !          3149:        if ((chp->ch_drive[0].drive_flags & DRIVE_UDMA) &&
        !          3150:            (chp->ch_drive[1].drive_flags & DRIVE_UDMA)) {
        !          3151:                /* both drives UDMA */
        !          3152:                if (chp->ch_drive[0].UDMA_mode > 2 &&
        !          3153:                    chp->ch_drive[1].UDMA_mode <= 2) {
        !          3154:                        /* drive 0 Ultra/66, drive 1 Ultra/33 */
        !          3155:                        chp->ch_drive[0].UDMA_mode = 2;
        !          3156:                } else if (chp->ch_drive[1].UDMA_mode > 2 &&
        !          3157:                    chp->ch_drive[0].UDMA_mode <= 2) {
        !          3158:                        /* drive 1 Ultra/66, drive 0 Ultra/33 */
        !          3159:                        chp->ch_drive[1].UDMA_mode = 2;
        !          3160:                }
        !          3161:        }
        !          3162:
        !          3163:        for (drive = 0; drive < 2; drive++) {
        !          3164:                drvp = &chp->ch_drive[drive];
        !          3165:                /* If no drive, skip */
        !          3166:                if ((drvp->drive_flags & DRIVE) == 0)
        !          3167:                        continue;
        !          3168:                /* add timing values, setup DMA if needed */
        !          3169:                if (((drvp->drive_flags & DRIVE_DMA) == 0 &&
        !          3170:                    (drvp->drive_flags & DRIVE_UDMA) == 0)) {
        !          3171:                        mode = drvp->PIO_mode;
        !          3172:                        goto pio;
        !          3173:                }
        !          3174:                if ((chp->wdc->cap & WDC_CAPABILITY_UDMA) &&
        !          3175:                    (drvp->drive_flags & DRIVE_UDMA)) {
        !          3176:                        /* use Ultra/DMA */
        !          3177:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          3178:                        udmatim_reg |= APO_UDMA_EN(chp->channel, drive) |
        !          3179:                            APO_UDMA_EN_MTH(chp->channel, drive);
        !          3180:                        if (sc->sc_wdcdev.UDMA_cap == 6) {
        !          3181:                                udmatim_reg |= APO_UDMA_TIME(chp->channel,
        !          3182:                                    drive, apollo_udma133_tim[drvp->UDMA_mode]);
        !          3183:                        } else if (sc->sc_wdcdev.UDMA_cap == 5) {
        !          3184:                                /* 686b */
        !          3185:                                udmatim_reg |= APO_UDMA_TIME(chp->channel,
        !          3186:                                    drive, apollo_udma100_tim[drvp->UDMA_mode]);
        !          3187:                        } else if (sc->sc_wdcdev.UDMA_cap == 4) {
        !          3188:                                /* 596b or 686a */
        !          3189:                                udmatim_reg |= APO_UDMA_CLK66(chp->channel);
        !          3190:                                udmatim_reg |= APO_UDMA_TIME(chp->channel,
        !          3191:                                    drive, apollo_udma66_tim[drvp->UDMA_mode]);
        !          3192:                        } else {
        !          3193:                                /* 596a or 586b */
        !          3194:                                udmatim_reg |= APO_UDMA_TIME(chp->channel,
        !          3195:                                    drive, apollo_udma33_tim[drvp->UDMA_mode]);
        !          3196:                        }
        !          3197:                        /* can use PIO timings, MW DMA unused */
        !          3198:                        mode = drvp->PIO_mode;
        !          3199:                } else {
        !          3200:                        /* use Multiword DMA */
        !          3201:                        drvp->drive_flags &= ~DRIVE_UDMA;
        !          3202:                        /* mode = min(pio, dma+2) */
        !          3203:                        if (drvp->PIO_mode <= (drvp->DMA_mode +2))
        !          3204:                                mode = drvp->PIO_mode;
        !          3205:                        else
        !          3206:                                mode = drvp->DMA_mode + 2;
        !          3207:                }
        !          3208:                idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          3209:
        !          3210: pio:           /* setup PIO mode */
        !          3211:                if (mode <= 2) {
        !          3212:                        drvp->DMA_mode = 0;
        !          3213:                        drvp->PIO_mode = 0;
        !          3214:                        mode = 0;
        !          3215:                } else {
        !          3216:                        drvp->PIO_mode = mode;
        !          3217:                        drvp->DMA_mode = mode - 2;
        !          3218:                }
        !          3219:                datatim_reg |=
        !          3220:                    APO_DATATIM_PULSE(chp->channel, drive,
        !          3221:                        apollo_pio_set[mode]) |
        !          3222:                    APO_DATATIM_RECOV(chp->channel, drive,
        !          3223:                        apollo_pio_rec[mode]);
        !          3224:        }
        !          3225:        if (idedma_ctl != 0) {
        !          3226:                /* Add software bits in status register */
        !          3227:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          3228:                    IDEDMA_CTL(chp->channel),
        !          3229:                    idedma_ctl);
        !          3230:        }
        !          3231:        pciide_print_modes(cp);
        !          3232:        pci_conf_write(sc->sc_pc, sc->sc_tag, APO_DATATIM, datatim_reg);
        !          3233:        pci_conf_write(sc->sc_pc, sc->sc_tag, APO_UDMA, udmatim_reg);
        !          3234: }
        !          3235:
        !          3236: void
        !          3237: cmd_channel_map(struct pci_attach_args *pa, struct pciide_softc *sc,
        !          3238:     int channel)
        !          3239: {
        !          3240:        struct pciide_channel *cp = &sc->pciide_channels[channel];
        !          3241:        bus_size_t cmdsize, ctlsize;
        !          3242:        u_int8_t ctrl = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_CTRL);
        !          3243:        pcireg_t interface;
        !          3244:        int one_channel;
        !          3245:
        !          3246:        /*
        !          3247:         * The 0648/0649 can be told to identify as a RAID controller.
        !          3248:         * In this case, we have to fake interface
        !          3249:         */
        !          3250:        if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_MASS_STORAGE_IDE) {
        !          3251:                interface = PCIIDE_INTERFACE_SETTABLE(0) |
        !          3252:                    PCIIDE_INTERFACE_SETTABLE(1);
        !          3253:                if (pciide_pci_read(pa->pa_pc, pa->pa_tag, CMD_CONF) &
        !          3254:                    CMD_CONF_DSA1)
        !          3255:                        interface |= PCIIDE_INTERFACE_PCI(0) |
        !          3256:                            PCIIDE_INTERFACE_PCI(1);
        !          3257:        } else {
        !          3258:                interface = PCI_INTERFACE(pa->pa_class);
        !          3259:        }
        !          3260:
        !          3261:        sc->wdc_chanarray[channel] = &cp->wdc_channel;
        !          3262:        cp->name = PCIIDE_CHANNEL_NAME(channel);
        !          3263:        cp->wdc_channel.channel = channel;
        !          3264:        cp->wdc_channel.wdc = &sc->sc_wdcdev;
        !          3265:
        !          3266:        /*
        !          3267:         * Older CMD64X doesn't have independant channels
        !          3268:         */
        !          3269:        switch (sc->sc_pp->ide_product) {
        !          3270:        case PCI_PRODUCT_CMDTECH_649:
        !          3271:                one_channel = 0;
        !          3272:                break;
        !          3273:        default:
        !          3274:                one_channel = 1;
        !          3275:                break;
        !          3276:        }
        !          3277:
        !          3278:        if (channel > 0 && one_channel) {
        !          3279:                cp->wdc_channel.ch_queue =
        !          3280:                    sc->pciide_channels[0].wdc_channel.ch_queue;
        !          3281:        } else {
        !          3282:                cp->wdc_channel.ch_queue =
        !          3283:                    malloc(sizeof(struct channel_queue), M_DEVBUF, M_NOWAIT);
        !          3284:        }
        !          3285:        if (cp->wdc_channel.ch_queue == NULL) {
        !          3286:                printf(
        !          3287:                    "%s: %s cannot allocate memory for command queue",
        !          3288:                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          3289:                return;
        !          3290:        }
        !          3291:
        !          3292:        /*
        !          3293:         * with a CMD PCI64x, if we get here, the first channel is enabled:
        !          3294:         * there's no way to disable the first channel without disabling
        !          3295:         * the whole device
        !          3296:         */
        !          3297:         if (channel != 0 && (ctrl & CMD_CTRL_2PORT) == 0) {
        !          3298:                printf("%s: %s ignored (disabled)\n",
        !          3299:                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          3300:                return;
        !          3301:        }
        !          3302:        cp->hw_ok = 1;
        !          3303:        pciide_map_compat_intr(pa, cp, channel, interface);
        !          3304:        if (cp->hw_ok == 0)
        !          3305:                return;
        !          3306:        pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, cmd_pci_intr);
        !          3307:        if (cp->hw_ok == 0) {
        !          3308:                pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          3309:                return;
        !          3310:        }
        !          3311:        if (pciide_chan_candisable(cp)) {
        !          3312:                if (channel == 1) {
        !          3313:                        ctrl &= ~CMD_CTRL_2PORT;
        !          3314:                        pciide_pci_write(pa->pa_pc, pa->pa_tag,
        !          3315:                            CMD_CTRL, ctrl);
        !          3316:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          3317:                }
        !          3318:        }
        !          3319: }
        !          3320:
        !          3321: int
        !          3322: cmd_pci_intr(void *arg)
        !          3323: {
        !          3324:        struct pciide_softc *sc = arg;
        !          3325:        struct pciide_channel *cp;
        !          3326:        struct channel_softc *wdc_cp;
        !          3327:        int i, rv, crv;
        !          3328:        u_int32_t priirq, secirq;
        !          3329:
        !          3330:        rv = 0;
        !          3331:        priirq = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_CONF);
        !          3332:        secirq = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_ARTTIM23);
        !          3333:        for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {
        !          3334:                cp = &sc->pciide_channels[i];
        !          3335:                wdc_cp = &cp->wdc_channel;
        !          3336:                /* If a compat channel skip. */
        !          3337:                if (cp->compat)
        !          3338:                        continue;
        !          3339:                if ((i == 0 && (priirq & CMD_CONF_DRV0_INTR)) ||
        !          3340:                    (i == 1 && (secirq & CMD_ARTTIM23_IRQ))) {
        !          3341:                        crv = wdcintr(wdc_cp);
        !          3342:                        if (crv == 0) {
        !          3343: #if 0
        !          3344:                                printf("%s:%d: bogus intr\n",
        !          3345:                                    sc->sc_wdcdev.sc_dev.dv_xname, i);
        !          3346: #endif
        !          3347:                        } else
        !          3348:                                rv = 1;
        !          3349:                }
        !          3350:        }
        !          3351:        return (rv);
        !          3352: }
        !          3353:
        !          3354: void
        !          3355: cmd_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          3356: {
        !          3357:        int channel;
        !          3358:        pcireg_t interface = PCI_INTERFACE(pa->pa_class);
        !          3359:
        !          3360:        printf(": no DMA");
        !          3361:        sc->sc_dma_ok = 0;
        !          3362:
        !          3363:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          3364:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          3365:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16;
        !          3366:
        !          3367:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          3368:
        !          3369:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          3370:                cmd_channel_map(pa, sc, channel);
        !          3371:        }
        !          3372: }
        !          3373:
        !          3374: void
        !          3375: cmd0643_9_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          3376: {
        !          3377:        struct pciide_channel *cp;
        !          3378:        int channel;
        !          3379:        int rev = sc->sc_rev;
        !          3380:        pcireg_t interface;
        !          3381:
        !          3382:        /*
        !          3383:         * The 0648/0649 can be told to identify as a RAID controller.
        !          3384:         * In this case, we have to fake interface
        !          3385:         */
        !          3386:        if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_MASS_STORAGE_IDE) {
        !          3387:                interface = PCIIDE_INTERFACE_SETTABLE(0) |
        !          3388:                    PCIIDE_INTERFACE_SETTABLE(1);
        !          3389:                if (pciide_pci_read(pa->pa_pc, pa->pa_tag, CMD_CONF) &
        !          3390:                    CMD_CONF_DSA1)
        !          3391:                        interface |= PCIIDE_INTERFACE_PCI(0) |
        !          3392:                            PCIIDE_INTERFACE_PCI(1);
        !          3393:        } else {
        !          3394:                interface = PCI_INTERFACE(pa->pa_class);
        !          3395:        }
        !          3396:
        !          3397:        printf(": DMA");
        !          3398:        pciide_mapreg_dma(sc, pa);
        !          3399:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          3400:            WDC_CAPABILITY_MODE;
        !          3401:        if (sc->sc_dma_ok) {
        !          3402:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
        !          3403:                switch (sc->sc_pp->ide_product) {
        !          3404:                case PCI_PRODUCT_CMDTECH_649:
        !          3405:                        sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA;
        !          3406:                        sc->sc_wdcdev.UDMA_cap = 5;
        !          3407:                        sc->sc_wdcdev.irqack = cmd646_9_irqack;
        !          3408:                        break;
        !          3409:                case PCI_PRODUCT_CMDTECH_648:
        !          3410:                        sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA;
        !          3411:                        sc->sc_wdcdev.UDMA_cap = 4;
        !          3412:                        sc->sc_wdcdev.irqack = cmd646_9_irqack;
        !          3413:                        break;
        !          3414:                case PCI_PRODUCT_CMDTECH_646:
        !          3415:                        if (rev >= CMD0646U2_REV) {
        !          3416:                                sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA;
        !          3417:                                sc->sc_wdcdev.UDMA_cap = 2;
        !          3418:                        } else if (rev >= CMD0646U_REV) {
        !          3419:                        /*
        !          3420:                         * Linux's driver claims that the 646U is broken
        !          3421:                         * with UDMA. Only enable it if we know what we're
        !          3422:                         * doing
        !          3423:                         */
        !          3424: #ifdef PCIIDE_CMD0646U_ENABLEUDMA
        !          3425:                                sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA;
        !          3426:                                sc->sc_wdcdev.UDMA_cap = 2;
        !          3427: #endif
        !          3428:                                /* explicitly disable UDMA */
        !          3429:                                pciide_pci_write(sc->sc_pc, sc->sc_tag,
        !          3430:                                    CMD_UDMATIM(0), 0);
        !          3431:                                pciide_pci_write(sc->sc_pc, sc->sc_tag,
        !          3432:                                    CMD_UDMATIM(1), 0);
        !          3433:                        }
        !          3434:                        sc->sc_wdcdev.irqack = cmd646_9_irqack;
        !          3435:                        break;
        !          3436:                default:
        !          3437:                        sc->sc_wdcdev.irqack = pciide_irqack;
        !          3438:                }
        !          3439:        }
        !          3440:
        !          3441:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          3442:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          3443:        sc->sc_wdcdev.PIO_cap = 4;
        !          3444:        sc->sc_wdcdev.DMA_cap = 2;
        !          3445:        sc->sc_wdcdev.set_modes = cmd0643_9_setup_channel;
        !          3446:
        !          3447:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          3448:
        !          3449:        WDCDEBUG_PRINT(("cmd0643_9_chip_map: old timings reg 0x%x 0x%x\n",
        !          3450:                pci_conf_read(sc->sc_pc, sc->sc_tag, 0x54),
        !          3451:                pci_conf_read(sc->sc_pc, sc->sc_tag, 0x58)),
        !          3452:                DEBUG_PROBE);
        !          3453:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          3454:                cp = &sc->pciide_channels[channel];
        !          3455:                cmd_channel_map(pa, sc, channel);
        !          3456:                if (cp->hw_ok == 0)
        !          3457:                        continue;
        !          3458:                cmd0643_9_setup_channel(&cp->wdc_channel);
        !          3459:        }
        !          3460:        /*
        !          3461:         * note - this also makes sure we clear the irq disable and reset
        !          3462:         * bits
        !          3463:         */
        !          3464:        pciide_pci_write(sc->sc_pc, sc->sc_tag, CMD_DMA_MODE, CMD_DMA_MULTIPLE);
        !          3465:        WDCDEBUG_PRINT(("cmd0643_9_chip_map: timings reg now 0x%x 0x%x\n",
        !          3466:            pci_conf_read(sc->sc_pc, sc->sc_tag, 0x54),
        !          3467:            pci_conf_read(sc->sc_pc, sc->sc_tag, 0x58)),
        !          3468:            DEBUG_PROBE);
        !          3469: }
        !          3470:
        !          3471: void
        !          3472: cmd0643_9_setup_channel(struct channel_softc *chp)
        !          3473: {
        !          3474:        struct ata_drive_datas *drvp;
        !          3475:        u_int8_t tim;
        !          3476:        u_int32_t idedma_ctl, udma_reg;
        !          3477:        int drive;
        !          3478:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          3479:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          3480:
        !          3481:        idedma_ctl = 0;
        !          3482:        /* setup DMA if needed */
        !          3483:        pciide_channel_dma_setup(cp);
        !          3484:
        !          3485:        for (drive = 0; drive < 2; drive++) {
        !          3486:                drvp = &chp->ch_drive[drive];
        !          3487:                /* If no drive, skip */
        !          3488:                if ((drvp->drive_flags & DRIVE) == 0)
        !          3489:                        continue;
        !          3490:                /* add timing values, setup DMA if needed */
        !          3491:                tim = cmd0643_9_data_tim_pio[drvp->PIO_mode];
        !          3492:                if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) {
        !          3493:                        if (drvp->drive_flags & DRIVE_UDMA) {
        !          3494:                                /* UltraDMA on a 646U2, 0648 or 0649 */
        !          3495:                                drvp->drive_flags &= ~DRIVE_DMA;
        !          3496:                                udma_reg = pciide_pci_read(sc->sc_pc,
        !          3497:                                    sc->sc_tag, CMD_UDMATIM(chp->channel));
        !          3498:                                if (drvp->UDMA_mode > 2 &&
        !          3499:                                    (pciide_pci_read(sc->sc_pc, sc->sc_tag,
        !          3500:                                    CMD_BICSR) &
        !          3501:                                    CMD_BICSR_80(chp->channel)) == 0) {
        !          3502:                                        WDCDEBUG_PRINT(("%s(%s:%d:%d): "
        !          3503:                                            "80-wire cable not detected\n",
        !          3504:                                            drvp->drive_name,
        !          3505:                                            sc->sc_wdcdev.sc_dev.dv_xname,
        !          3506:                                            chp->channel, drive), DEBUG_PROBE);
        !          3507:                                        drvp->UDMA_mode = 2;
        !          3508:                                }
        !          3509:                                if (drvp->UDMA_mode > 2)
        !          3510:                                        udma_reg &= ~CMD_UDMATIM_UDMA33(drive);
        !          3511:                                else if (sc->sc_wdcdev.UDMA_cap > 2)
        !          3512:                                        udma_reg |= CMD_UDMATIM_UDMA33(drive);
        !          3513:                                udma_reg |= CMD_UDMATIM_UDMA(drive);
        !          3514:                                udma_reg &= ~(CMD_UDMATIM_TIM_MASK <<
        !          3515:                                    CMD_UDMATIM_TIM_OFF(drive));
        !          3516:                                udma_reg |=
        !          3517:                                    (cmd0646_9_tim_udma[drvp->UDMA_mode] <<
        !          3518:                                    CMD_UDMATIM_TIM_OFF(drive));
        !          3519:                                pciide_pci_write(sc->sc_pc, sc->sc_tag,
        !          3520:                                    CMD_UDMATIM(chp->channel), udma_reg);
        !          3521:                        } else {
        !          3522:                                /*
        !          3523:                                 * use Multiword DMA.
        !          3524:                                 * Timings will be used for both PIO and DMA,
        !          3525:                                 * so adjust DMA mode if needed
        !          3526:                                 * if we have a 0646U2/8/9, turn off UDMA
        !          3527:                                 */
        !          3528:                                if (sc->sc_wdcdev.cap & WDC_CAPABILITY_UDMA) {
        !          3529:                                        udma_reg = pciide_pci_read(sc->sc_pc,
        !          3530:                                            sc->sc_tag,
        !          3531:                                            CMD_UDMATIM(chp->channel));
        !          3532:                                        udma_reg &= ~CMD_UDMATIM_UDMA(drive);
        !          3533:                                        pciide_pci_write(sc->sc_pc, sc->sc_tag,
        !          3534:                                            CMD_UDMATIM(chp->channel),
        !          3535:                                            udma_reg);
        !          3536:                                }
        !          3537:                                if (drvp->PIO_mode >= 3 &&
        !          3538:                                    (drvp->DMA_mode + 2) > drvp->PIO_mode) {
        !          3539:                                        drvp->DMA_mode = drvp->PIO_mode - 2;
        !          3540:                                }
        !          3541:                                tim = cmd0643_9_data_tim_dma[drvp->DMA_mode];
        !          3542:                        }
        !          3543:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          3544:                }
        !          3545:                pciide_pci_write(sc->sc_pc, sc->sc_tag,
        !          3546:                    CMD_DATA_TIM(chp->channel, drive), tim);
        !          3547:        }
        !          3548:        if (idedma_ctl != 0) {
        !          3549:                /* Add software bits in status register */
        !          3550:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          3551:                    IDEDMA_CTL(chp->channel),
        !          3552:                    idedma_ctl);
        !          3553:        }
        !          3554:        pciide_print_modes(cp);
        !          3555: #ifdef __sparc64__
        !          3556:        /*
        !          3557:         * The Ultra 5 has a tendency to hang during reboot.  This is due
        !          3558:         * to the PCI0646U asserting a PCI interrupt line when the chip
        !          3559:         * registers claim that it is not.  Performing a reset at this
        !          3560:         * point appears to eliminate the symptoms.  It is likely the
        !          3561:         * real cause is still lurking somewhere in the code.
        !          3562:         */
        !          3563:        wdcreset(chp, SILENT);
        !          3564: #endif /* __sparc64__ */
        !          3565: }
        !          3566:
        !          3567: void
        !          3568: cmd646_9_irqack(struct channel_softc *chp)
        !          3569: {
        !          3570:        u_int32_t priirq, secirq;
        !          3571:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          3572:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          3573:
        !          3574:        if (chp->channel == 0) {
        !          3575:                priirq = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_CONF);
        !          3576:                pciide_pci_write(sc->sc_pc, sc->sc_tag, CMD_CONF, priirq);
        !          3577:        } else {
        !          3578:                secirq = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_ARTTIM23);
        !          3579:                pciide_pci_write(sc->sc_pc, sc->sc_tag, CMD_ARTTIM23, secirq);
        !          3580:        }
        !          3581:        pciide_irqack(chp);
        !          3582: }
        !          3583:
        !          3584: void
        !          3585: cmd680_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          3586: {
        !          3587:        struct pciide_channel *cp;
        !          3588:        int channel;
        !          3589:
        !          3590:        printf("\n%s: bus-master DMA support present",
        !          3591:            sc->sc_wdcdev.sc_dev.dv_xname);
        !          3592:        pciide_mapreg_dma(sc, pa);
        !          3593:        printf("\n");
        !          3594:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          3595:            WDC_CAPABILITY_MODE;
        !          3596:        if (sc->sc_dma_ok) {
        !          3597:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
        !          3598:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA;
        !          3599:                sc->sc_wdcdev.UDMA_cap = 6;
        !          3600:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          3601:        }
        !          3602:
        !          3603:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          3604:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          3605:        sc->sc_wdcdev.PIO_cap = 4;
        !          3606:        sc->sc_wdcdev.DMA_cap = 2;
        !          3607:        sc->sc_wdcdev.set_modes = cmd680_setup_channel;
        !          3608:
        !          3609:        pciide_pci_write(sc->sc_pc, sc->sc_tag, 0x80, 0x00);
        !          3610:        pciide_pci_write(sc->sc_pc, sc->sc_tag, 0x84, 0x00);
        !          3611:        pciide_pci_write(sc->sc_pc, sc->sc_tag, 0x8a,
        !          3612:            pciide_pci_read(sc->sc_pc, sc->sc_tag, 0x8a) | 0x01);
        !          3613:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          3614:                cp = &sc->pciide_channels[channel];
        !          3615:                cmd680_channel_map(pa, sc, channel);
        !          3616:                if (cp->hw_ok == 0)
        !          3617:                        continue;
        !          3618:                cmd680_setup_channel(&cp->wdc_channel);
        !          3619:        }
        !          3620: }
        !          3621:
        !          3622: void
        !          3623: cmd680_channel_map(struct pci_attach_args *pa, struct pciide_softc *sc,
        !          3624:     int channel)
        !          3625: {
        !          3626:        struct pciide_channel *cp = &sc->pciide_channels[channel];
        !          3627:        bus_size_t cmdsize, ctlsize;
        !          3628:        int interface, i, reg;
        !          3629:        static const u_int8_t init_val[] =
        !          3630:            {             0x8a, 0x32, 0x8a, 0x32, 0x8a, 0x32,
        !          3631:              0x92, 0x43, 0x92, 0x43, 0x09, 0x40, 0x09, 0x40 };
        !          3632:
        !          3633:        if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_MASS_STORAGE_IDE) {
        !          3634:                interface = PCIIDE_INTERFACE_SETTABLE(0) |
        !          3635:                    PCIIDE_INTERFACE_SETTABLE(1);
        !          3636:                interface |= PCIIDE_INTERFACE_PCI(0) |
        !          3637:                    PCIIDE_INTERFACE_PCI(1);
        !          3638:        } else {
        !          3639:                interface = PCI_INTERFACE(pa->pa_class);
        !          3640:        }
        !          3641:
        !          3642:        sc->wdc_chanarray[channel] = &cp->wdc_channel;
        !          3643:        cp->name = PCIIDE_CHANNEL_NAME(channel);
        !          3644:        cp->wdc_channel.channel = channel;
        !          3645:        cp->wdc_channel.wdc = &sc->sc_wdcdev;
        !          3646:
        !          3647:        cp->wdc_channel.ch_queue =
        !          3648:            malloc(sizeof(struct channel_queue), M_DEVBUF, M_NOWAIT);
        !          3649:        if (cp->wdc_channel.ch_queue == NULL) {
        !          3650:                printf("%s %s: "
        !          3651:                    "can't allocate memory for command queue",
        !          3652:                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          3653:                    return;
        !          3654:        }
        !          3655:
        !          3656:        /* XXX */
        !          3657:        reg = 0xa2 + channel * 16;
        !          3658:        for (i = 0; i < sizeof(init_val); i++)
        !          3659:                pciide_pci_write(sc->sc_pc, sc->sc_tag, reg + i, init_val[i]);
        !          3660:
        !          3661:        printf("%s: %s %s to %s mode\n",
        !          3662:            sc->sc_wdcdev.sc_dev.dv_xname, cp->name,
        !          3663:            (interface & PCIIDE_INTERFACE_SETTABLE(channel)) ?
        !          3664:            "configured" : "wired",
        !          3665:            (interface & PCIIDE_INTERFACE_PCI(channel)) ?
        !          3666:            "native-PCI" : "compatibility");
        !          3667:
        !          3668:        pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, pciide_pci_intr);
        !          3669:        if (cp->hw_ok == 0)
        !          3670:                return;
        !          3671:        pciide_map_compat_intr(pa, cp, channel, interface);
        !          3672: }
        !          3673:
        !          3674: void
        !          3675: cmd680_setup_channel(struct channel_softc *chp)
        !          3676: {
        !          3677:        struct ata_drive_datas *drvp;
        !          3678:        u_int8_t mode, off, scsc;
        !          3679:        u_int16_t val;
        !          3680:        u_int32_t idedma_ctl;
        !          3681:        int drive;
        !          3682:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          3683:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          3684:        pci_chipset_tag_t pc = sc->sc_pc;
        !          3685:        pcitag_t pa = sc->sc_tag;
        !          3686:        static const u_int8_t udma2_tbl[] =
        !          3687:            { 0x0f, 0x0b, 0x07, 0x06, 0x03, 0x02, 0x01 };
        !          3688:        static const u_int8_t udma_tbl[] =
        !          3689:            { 0x0c, 0x07, 0x05, 0x04, 0x02, 0x01, 0x00 };
        !          3690:        static const u_int16_t dma_tbl[] =
        !          3691:            { 0x2208, 0x10c2, 0x10c1 };
        !          3692:        static const u_int16_t pio_tbl[] =
        !          3693:            { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
        !          3694:
        !          3695:        idedma_ctl = 0;
        !          3696:        pciide_channel_dma_setup(cp);
        !          3697:        mode = pciide_pci_read(pc, pa, 0x80 + chp->channel * 4);
        !          3698:
        !          3699:        for (drive = 0; drive < 2; drive++) {
        !          3700:                drvp = &chp->ch_drive[drive];
        !          3701:                /* If no drive, skip */
        !          3702:                if ((drvp->drive_flags & DRIVE) == 0)
        !          3703:                        continue;
        !          3704:                mode &= ~(0x03 << (drive * 4));
        !          3705:                if (drvp->drive_flags & DRIVE_UDMA) {
        !          3706:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          3707:                        off = 0xa0 + chp->channel * 16;
        !          3708:                        if (drvp->UDMA_mode > 2 &&
        !          3709:                            (pciide_pci_read(pc, pa, off) & 0x01) == 0)
        !          3710:                                drvp->UDMA_mode = 2;
        !          3711:                        scsc = pciide_pci_read(pc, pa, 0x8a);
        !          3712:                        if (drvp->UDMA_mode == 6 && (scsc & 0x30) == 0) {
        !          3713:                                pciide_pci_write(pc, pa, 0x8a, scsc | 0x01);
        !          3714:                                scsc = pciide_pci_read(pc, pa, 0x8a);
        !          3715:                                if ((scsc & 0x30) == 0)
        !          3716:                                        drvp->UDMA_mode = 5;
        !          3717:                        }
        !          3718:                        mode |= 0x03 << (drive * 4);
        !          3719:                        off = 0xac + chp->channel * 16 + drive * 2;
        !          3720:                        val = pciide_pci_read(pc, pa, off) & ~0x3f;
        !          3721:                        if (scsc & 0x30)
        !          3722:                                val |= udma2_tbl[drvp->UDMA_mode];
        !          3723:                        else
        !          3724:                                val |= udma_tbl[drvp->UDMA_mode];
        !          3725:                        pciide_pci_write(pc, pa, off, val);
        !          3726:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          3727:                } else if (drvp->drive_flags & DRIVE_DMA) {
        !          3728:                        mode |= 0x02 << (drive * 4);
        !          3729:                        off = 0xa8 + chp->channel * 16 + drive * 2;
        !          3730:                        val = dma_tbl[drvp->DMA_mode];
        !          3731:                        pciide_pci_write(pc, pa, off, val & 0xff);
        !          3732:                        pciide_pci_write(pc, pa, off, val >> 8);
        !          3733:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          3734:                } else {
        !          3735:                        mode |= 0x01 << (drive * 4);
        !          3736:                        off = 0xa4 + chp->channel * 16 + drive * 2;
        !          3737:                        val = pio_tbl[drvp->PIO_mode];
        !          3738:                        pciide_pci_write(pc, pa, off, val & 0xff);
        !          3739:                        pciide_pci_write(pc, pa, off, val >> 8);
        !          3740:                }
        !          3741:        }
        !          3742:
        !          3743:        pciide_pci_write(pc, pa, 0x80 + chp->channel * 4, mode);
        !          3744:        if (idedma_ctl != 0) {
        !          3745:                /* Add software bits in status register */
        !          3746:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          3747:                    IDEDMA_CTL(chp->channel),
        !          3748:                    idedma_ctl);
        !          3749:        }
        !          3750:        pciide_print_modes(cp);
        !          3751: }
        !          3752:
        !          3753: /*
        !          3754:  * When the Silicon Image 3112 retries a PCI memory read command,
        !          3755:  * it may retry it as a memory read multiple command under some
        !          3756:  * circumstances.  This can totally confuse some PCI controllers,
        !          3757:  * so ensure that it will never do this by making sure that the
        !          3758:  * Read Threshold (FIFO Read Request Control) field of the FIFO
        !          3759:  * Valid Byte Count and Control registers for both channels (BA5
        !          3760:  * offset 0x40 and 0x44) are set to be at least as large as the
        !          3761:  * cacheline size register.
        !          3762:  */
        !          3763: void
        !          3764: sii_fixup_cacheline(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          3765: {
        !          3766:        pcireg_t cls, reg40, reg44;
        !          3767:
        !          3768:        cls = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
        !          3769:        cls = (cls >> PCI_CACHELINE_SHIFT) & PCI_CACHELINE_MASK;
        !          3770:        cls *= 4;
        !          3771:        if (cls > 224) {
        !          3772:                cls = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
        !          3773:                cls &= ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT);
        !          3774:                cls |= ((224/4) << PCI_CACHELINE_SHIFT);
        !          3775:                pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, cls);
        !          3776:                cls = 224;
        !          3777:        }
        !          3778:        if (cls < 32)
        !          3779:                cls = 32;
        !          3780:        cls = (cls + 31) / 32;
        !          3781:        reg40 = ba5_read_4(sc, 0x40);
        !          3782:        reg44 = ba5_read_4(sc, 0x44);
        !          3783:        if ((reg40 & 0x7) < cls)
        !          3784:                ba5_write_4(sc, 0x40, (reg40 & ~0x07) | cls);
        !          3785:        if ((reg44 & 0x7) < cls)
        !          3786:                ba5_write_4(sc, 0x44, (reg44 & ~0x07) | cls);
        !          3787: }
        !          3788:
        !          3789: void
        !          3790: sii3112_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          3791: {
        !          3792:        struct pciide_channel *cp;
        !          3793:        bus_size_t cmdsize, ctlsize;
        !          3794:        pcireg_t interface, scs_cmd, cfgctl;
        !          3795:        int channel;
        !          3796:        struct pciide_satalink *sl = sc->sc_cookie;
        !          3797:
        !          3798:        /* Allocate memory for private data */
        !          3799:        sc->sc_cookie = malloc(sizeof(struct pciide_satalink), M_DEVBUF,
        !          3800:            M_NOWAIT);
        !          3801:        sl = sc->sc_cookie;
        !          3802:        bzero(sl, sizeof(*sl));
        !          3803:
        !          3804: #define        SII3112_RESET_BITS                                              \
        !          3805:        (SCS_CMD_PBM_RESET | SCS_CMD_ARB_RESET |                        \
        !          3806:         SCS_CMD_FF1_RESET | SCS_CMD_FF0_RESET |                        \
        !          3807:         SCS_CMD_IDE1_RESET | SCS_CMD_IDE0_RESET)
        !          3808:
        !          3809:        /*
        !          3810:         * Reset everything and then unblock all of the interrupts.
        !          3811:         */
        !          3812:        scs_cmd = pci_conf_read(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD);
        !          3813:        pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD,
        !          3814:                       scs_cmd | SII3112_RESET_BITS);
        !          3815:        delay(50 * 1000);
        !          3816:        pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD,
        !          3817:                       scs_cmd & SCS_CMD_BA5_EN);
        !          3818:        delay(50 * 1000);
        !          3819:
        !          3820:        if (scs_cmd & SCS_CMD_BA5_EN) {
        !          3821:                if (pci_mapreg_map(pa, PCI_MAPREG_START + 0x14,
        !          3822:                                   PCI_MAPREG_TYPE_MEM |
        !          3823:                                   PCI_MAPREG_MEM_TYPE_32BIT, 0,
        !          3824:                                   &sl->ba5_st, &sl->ba5_sh,
        !          3825:                                   NULL, NULL, 0) != 0)
        !          3826:                        printf(": unable to map BA5 register space\n");
        !          3827:                else
        !          3828:                        sl->ba5_en = 1;
        !          3829:        } else {
        !          3830:                cfgctl = pci_conf_read(pa->pa_pc, pa->pa_tag,
        !          3831:                                       SII3112_PCI_CFGCTL);
        !          3832:                pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_PCI_CFGCTL,
        !          3833:                               cfgctl | CFGCTL_BA5INDEN);
        !          3834:        }
        !          3835:
        !          3836:        printf(": DMA");
        !          3837:        pciide_mapreg_dma(sc, pa);
        !          3838:        printf("\n");
        !          3839:
        !          3840:        /*
        !          3841:         * Rev. <= 0x01 of the 3112 have a bug that can cause data
        !          3842:         * corruption if DMA transfers cross an 8K boundary.  This is
        !          3843:         * apparently hard to tickle, but we'll go ahead and play it
        !          3844:         * safe.
        !          3845:         */
        !          3846:        if (sc->sc_rev <= 0x01) {
        !          3847:                sc->sc_dma_maxsegsz = 8192;
        !          3848:                sc->sc_dma_boundary = 8192;
        !          3849:        }
        !          3850:
        !          3851:        sii_fixup_cacheline(sc, pa);
        !          3852:
        !          3853:        sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32;
        !          3854:        sc->sc_wdcdev.PIO_cap = 4;
        !          3855:        if (sc->sc_dma_ok) {
        !          3856:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
        !          3857:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          3858:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          3859:                sc->sc_wdcdev.DMA_cap = 2;
        !          3860:                sc->sc_wdcdev.UDMA_cap = 6;
        !          3861:        }
        !          3862:        sc->sc_wdcdev.set_modes = sii3112_setup_channel;
        !          3863:
        !          3864:        /* We can use SControl and SStatus to probe for drives. */
        !          3865:        sc->sc_wdcdev.drv_probe = sii3112_drv_probe;
        !          3866:
        !          3867:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          3868:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          3869:
        !          3870:        /*
        !          3871:         * The 3112 either identifies itself as a RAID storage device
        !          3872:         * or a Misc storage device.  Fake up the interface bits for
        !          3873:         * what our driver expects.
        !          3874:         */
        !          3875:        if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_IDE) {
        !          3876:                interface = PCI_INTERFACE(pa->pa_class);
        !          3877:        } else {
        !          3878:                interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
        !          3879:                    PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
        !          3880:        }
        !          3881:
        !          3882:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          3883:                cp = &sc->pciide_channels[channel];
        !          3884:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          3885:                        continue;
        !          3886:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          3887:                    pciide_pci_intr);
        !          3888:                if (cp->hw_ok == 0)
        !          3889:                        continue;
        !          3890:                sc->sc_wdcdev.set_modes(&cp->wdc_channel);
        !          3891:        }
        !          3892: }
        !          3893:
        !          3894: void
        !          3895: sii3112_setup_channel(struct channel_softc *chp)
        !          3896: {
        !          3897:        struct ata_drive_datas *drvp;
        !          3898:        int drive;
        !          3899:        u_int32_t idedma_ctl, dtm;
        !          3900:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          3901:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          3902:
        !          3903:        /* setup DMA if needed */
        !          3904:        pciide_channel_dma_setup(cp);
        !          3905:
        !          3906:        idedma_ctl = 0;
        !          3907:        dtm = 0;
        !          3908:
        !          3909:        for (drive = 0; drive < 2; drive++) {
        !          3910:                drvp = &chp->ch_drive[drive];
        !          3911:                /* If no drive, skip */
        !          3912:                if ((drvp->drive_flags & DRIVE) == 0)
        !          3913:                        continue;
        !          3914:                if (drvp->drive_flags & DRIVE_UDMA) {
        !          3915:                        /* use Ultra/DMA */
        !          3916:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          3917:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          3918:                        dtm |= DTM_IDEx_DMA;
        !          3919:                } else if (drvp->drive_flags & DRIVE_DMA) {
        !          3920:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          3921:                        dtm |= DTM_IDEx_DMA;
        !          3922:                } else {
        !          3923:                        dtm |= DTM_IDEx_PIO;
        !          3924:                }
        !          3925:        }
        !          3926:
        !          3927:        /*
        !          3928:         * Nothing to do to setup modes; it is meaningless in S-ATA
        !          3929:         * (but many S-ATA drives still want to get the SET_FEATURE
        !          3930:         * command).
        !          3931:         */
        !          3932:        if (idedma_ctl != 0) {
        !          3933:                /* Add software bits in status register */
        !          3934:                PCIIDE_DMACTL_WRITE(sc, chp->channel, idedma_ctl);
        !          3935:        }
        !          3936:        BA5_WRITE_4(sc, chp->channel, ba5_IDE_DTM, dtm);
        !          3937:        pciide_print_modes(cp);
        !          3938: }
        !          3939:
        !          3940: void
        !          3941: sii3112_drv_probe(struct channel_softc *chp)
        !          3942: {
        !          3943:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          3944:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          3945:        uint32_t scontrol, sstatus;
        !          3946:        uint8_t scnt, sn, cl, ch;
        !          3947:        int i, s;
        !          3948:
        !          3949:        /* XXX This should be done by other code. */
        !          3950:        for (i = 0; i < 2; i++) {
        !          3951:                chp->ch_drive[i].chnl_softc = chp;
        !          3952:                chp->ch_drive[i].drive = i;
        !          3953:        }
        !          3954:
        !          3955:        /*
        !          3956:         * The 3112 is a 2-port part, and only has one drive per channel
        !          3957:         * (each port emulates a master drive).
        !          3958:         *
        !          3959:         * The 3114 is similar, but has 4 channels.
        !          3960:         */
        !          3961:
        !          3962:        /*
        !          3963:         * Request communication initialization sequence, any speed.
        !          3964:         * Performing this is the equivalent of an ATA Reset.
        !          3965:         */
        !          3966:        scontrol = SControl_DET_INIT | SControl_SPD_ANY;
        !          3967:
        !          3968:        /*
        !          3969:         * XXX We don't yet support SATA power management; disable all
        !          3970:         * power management state transitions.
        !          3971:         */
        !          3972:        scontrol |= SControl_IPM_NONE;
        !          3973:
        !          3974:        BA5_WRITE_4(sc, chp->channel, ba5_SControl, scontrol);
        !          3975:        delay(50 * 1000);
        !          3976:        scontrol &= ~SControl_DET_INIT;
        !          3977:        BA5_WRITE_4(sc, chp->channel, ba5_SControl, scontrol);
        !          3978:        delay(50 * 1000);
        !          3979:
        !          3980:        sstatus = BA5_READ_4(sc, chp->channel, ba5_SStatus);
        !          3981: #if 0
        !          3982:        printf("%s: port %d: SStatus=0x%08x, SControl=0x%08x\n",
        !          3983:            sc->sc_wdcdev.sc_dev.dv_xname, chp->channel, sstatus,
        !          3984:            BA5_READ_4(sc, chp->channel, ba5_SControl));
        !          3985: #endif
        !          3986:        switch (sstatus & SStatus_DET_mask) {
        !          3987:        case SStatus_DET_NODEV:
        !          3988:                /* No device; be silent. */
        !          3989:                break;
        !          3990:
        !          3991:        case SStatus_DET_DEV_NE:
        !          3992:                printf("%s: port %d: device connected, but "
        !          3993:                    "communication not established\n",
        !          3994:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel);
        !          3995:                break;
        !          3996:
        !          3997:        case SStatus_DET_OFFLINE:
        !          3998:                printf("%s: port %d: PHY offline\n",
        !          3999:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel);
        !          4000:                break;
        !          4001:
        !          4002:        case SStatus_DET_DEV:
        !          4003:                /*
        !          4004:                 * XXX ATAPI detection doesn't currently work.  Don't
        !          4005:                 * XXX know why.  But, it's not like the standard method
        !          4006:                 * XXX can detect an ATAPI device connected via a SATA/PATA
        !          4007:                 * XXX bridge, so at least this is no worse.  --thorpej
        !          4008:                 */
        !          4009:                if (chp->_vtbl != NULL)
        !          4010:                        CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (0 << 4));
        !          4011:                else
        !          4012:                        bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
        !          4013:                            wdr_sdh & _WDC_REGMASK, WDSD_IBM | (0 << 4));
        !          4014:                delay(10);      /* 400ns delay */
        !          4015:                /* Save register contents. */
        !          4016:                if (chp->_vtbl != NULL) {
        !          4017:                        scnt = CHP_READ_REG(chp, wdr_seccnt);
        !          4018:                        sn = CHP_READ_REG(chp, wdr_sector);
        !          4019:                        cl = CHP_READ_REG(chp, wdr_cyl_lo);
        !          4020:                        ch = CHP_READ_REG(chp, wdr_cyl_hi);
        !          4021:                } else {
        !          4022:                        scnt = bus_space_read_1(chp->cmd_iot,
        !          4023:                            chp->cmd_ioh, wdr_seccnt & _WDC_REGMASK);
        !          4024:                        sn = bus_space_read_1(chp->cmd_iot,
        !          4025:                            chp->cmd_ioh, wdr_sector & _WDC_REGMASK);
        !          4026:                        cl = bus_space_read_1(chp->cmd_iot,
        !          4027:                            chp->cmd_ioh, wdr_cyl_lo & _WDC_REGMASK);
        !          4028:                        ch = bus_space_read_1(chp->cmd_iot,
        !          4029:                            chp->cmd_ioh, wdr_cyl_hi & _WDC_REGMASK);
        !          4030:                }
        !          4031: #if 0
        !          4032:                printf("%s: port %d: scnt=0x%x sn=0x%x cl=0x%x ch=0x%x\n",
        !          4033:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel,
        !          4034:                    scnt, sn, cl, ch);
        !          4035: #endif
        !          4036:                /*
        !          4037:                 * scnt and sn are supposed to be 0x1 for ATAPI, but in some
        !          4038:                 * cases we get wrong values here, so ignore it.
        !          4039:                 */
        !          4040:                s = splbio();
        !          4041:                if (cl == 0x14 && ch == 0xeb)
        !          4042:                        chp->ch_drive[0].drive_flags |= DRIVE_ATAPI;
        !          4043:                else
        !          4044:                        chp->ch_drive[0].drive_flags |= DRIVE_ATA;
        !          4045:                splx(s);
        !          4046:
        !          4047:                printf("%s: port %d: device present",
        !          4048:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel);
        !          4049:                switch ((sstatus & SStatus_SPD_mask) >> SStatus_SPD_shift) {
        !          4050:                case 1:
        !          4051:                        printf(", speed: 1.5Gb/s");
        !          4052:                        break;
        !          4053:                case 2:
        !          4054:                        printf(", speed: 3.0Gb/s");
        !          4055:                        break;
        !          4056:                }
        !          4057:                printf("\n");
        !          4058:                break;
        !          4059:
        !          4060:        default:
        !          4061:                printf("%s: port %d: unknown SStatus: 0x%08x\n",
        !          4062:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel, sstatus);
        !          4063:        }
        !          4064: }
        !          4065:
        !          4066: void
        !          4067: sii3114_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          4068: {
        !          4069:        struct pciide_channel *cp;
        !          4070:        pcireg_t scs_cmd;
        !          4071:        pci_intr_handle_t intrhandle;
        !          4072:        const char *intrstr;
        !          4073:        int channel;
        !          4074:        struct pciide_satalink *sl = sc->sc_cookie;
        !          4075:
        !          4076:        /* Allocate memory for private data */
        !          4077:        sc->sc_cookie = malloc(sizeof(struct pciide_satalink), M_DEVBUF,
        !          4078:            M_NOWAIT);
        !          4079:        sl = sc->sc_cookie;
        !          4080:        bzero(sl, sizeof(*sl));
        !          4081:
        !          4082: #define        SII3114_RESET_BITS                                              \
        !          4083:        (SCS_CMD_PBM_RESET | SCS_CMD_ARB_RESET |                        \
        !          4084:         SCS_CMD_FF1_RESET | SCS_CMD_FF0_RESET |                        \
        !          4085:         SCS_CMD_FF3_RESET | SCS_CMD_FF2_RESET |                        \
        !          4086:         SCS_CMD_IDE1_RESET | SCS_CMD_IDE0_RESET |                      \
        !          4087:         SCS_CMD_IDE3_RESET | SCS_CMD_IDE2_RESET)
        !          4088:
        !          4089:        /*
        !          4090:         * Reset everything and then unblock all of the interrupts.
        !          4091:         */
        !          4092:        scs_cmd = pci_conf_read(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD);
        !          4093:        pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD,
        !          4094:                       scs_cmd | SII3114_RESET_BITS);
        !          4095:        delay(50 * 1000);
        !          4096:        pci_conf_write(pa->pa_pc, pa->pa_tag, SII3112_SCS_CMD,
        !          4097:                       scs_cmd & SCS_CMD_M66EN);
        !          4098:        delay(50 * 1000);
        !          4099:
        !          4100:        /*
        !          4101:         * On the 3114, the BA5 register space is always enabled.  In
        !          4102:         * order to use the 3114 in any sane way, we must use this BA5
        !          4103:         * register space, and so we consider it an error if we cannot
        !          4104:         * map it.
        !          4105:         *
        !          4106:         * As a consequence of using BA5, our register mapping is different
        !          4107:         * from a normal PCI IDE controller's, and so we are unable to use
        !          4108:         * most of the common PCI IDE register mapping functions.
        !          4109:         */
        !          4110:        if (pci_mapreg_map(pa, PCI_MAPREG_START + 0x14,
        !          4111:                           PCI_MAPREG_TYPE_MEM |
        !          4112:                           PCI_MAPREG_MEM_TYPE_32BIT, 0,
        !          4113:                           &sl->ba5_st, &sl->ba5_sh,
        !          4114:                           NULL, NULL, 0) != 0) {
        !          4115:                printf(": unable to map BA5 register space\n");
        !          4116:                return;
        !          4117:        }
        !          4118:        sl->ba5_en = 1;
        !          4119:
        !          4120:        /*
        !          4121:         * Set the Interrupt Steering bit in the IDEDMA_CMD register of
        !          4122:         * channel 2.  This is required at all times for proper operation
        !          4123:         * when using the BA5 register space (otherwise interrupts from
        !          4124:         * all 4 channels won't work).
        !          4125:         */
        !          4126:        BA5_WRITE_4(sc, 2, ba5_IDEDMA_CMD, IDEDMA_CMD_INT_STEER);
        !          4127:
        !          4128:        printf(": DMA");
        !          4129:        sii3114_mapreg_dma(sc, pa);
        !          4130:        printf("\n");
        !          4131:
        !          4132:        sii_fixup_cacheline(sc, pa);
        !          4133:
        !          4134:        sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32;
        !          4135:        sc->sc_wdcdev.PIO_cap = 4;
        !          4136:        if (sc->sc_dma_ok) {
        !          4137:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
        !          4138:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          4139:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          4140:                sc->sc_wdcdev.DMA_cap = 2;
        !          4141:                sc->sc_wdcdev.UDMA_cap = 6;
        !          4142:        }
        !          4143:        sc->sc_wdcdev.set_modes = sii3112_setup_channel;
        !          4144:
        !          4145:        /* We can use SControl and SStatus to probe for drives. */
        !          4146:        sc->sc_wdcdev.drv_probe = sii3112_drv_probe;
        !          4147:
        !          4148:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          4149:        sc->sc_wdcdev.nchannels = 4;
        !          4150:
        !          4151:        /* Map and establish the interrupt handler. */
        !          4152:        if (pci_intr_map(pa, &intrhandle) != 0) {
        !          4153:                printf("%s: couldn't map native-PCI interrupt\n",
        !          4154:                    sc->sc_wdcdev.sc_dev.dv_xname);
        !          4155:                return;
        !          4156:        }
        !          4157:        intrstr = pci_intr_string(pa->pa_pc, intrhandle);
        !          4158:        sc->sc_pci_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO,
        !          4159:                                           /* XXX */
        !          4160:                                           pciide_pci_intr, sc,
        !          4161:                                           sc->sc_wdcdev.sc_dev.dv_xname);
        !          4162:        if (sc->sc_pci_ih != NULL) {
        !          4163:                printf("%s: using %s for native-PCI interrupt\n",
        !          4164:                    sc->sc_wdcdev.sc_dev.dv_xname,
        !          4165:                    intrstr ? intrstr : "unknown interrupt");
        !          4166:        } else {
        !          4167:                printf("%s: couldn't establish native-PCI interrupt",
        !          4168:                    sc->sc_wdcdev.sc_dev.dv_xname);
        !          4169:                if (intrstr != NULL)
        !          4170:                        printf(" at %s", intrstr);
        !          4171:                printf("\n");
        !          4172:                return;
        !          4173:        }
        !          4174:
        !          4175:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          4176:                cp = &sc->pciide_channels[channel];
        !          4177:                if (sii3114_chansetup(sc, channel) == 0)
        !          4178:                        continue;
        !          4179:                sii3114_mapchan(cp);
        !          4180:                if (cp->hw_ok == 0)
        !          4181:                        continue;
        !          4182:                sc->sc_wdcdev.set_modes(&cp->wdc_channel);
        !          4183:        }
        !          4184: }
        !          4185:
        !          4186: void
        !          4187: sii3114_mapreg_dma(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          4188: {
        !          4189:        struct pciide_channel *pc;
        !          4190:        int chan, reg;
        !          4191:        bus_size_t size;
        !          4192:        struct pciide_satalink *sl = sc->sc_cookie;
        !          4193:
        !          4194:        sc->sc_wdcdev.dma_arg = sc;
        !          4195:        sc->sc_wdcdev.dma_init = pciide_dma_init;
        !          4196:        sc->sc_wdcdev.dma_start = pciide_dma_start;
        !          4197:        sc->sc_wdcdev.dma_finish = pciide_dma_finish;
        !          4198:
        !          4199:        /*
        !          4200:         * Slice off a subregion of BA5 for each of the channel's DMA
        !          4201:         * registers.
        !          4202:         */
        !          4203:
        !          4204:        sc->sc_dma_iot = sl->ba5_st;
        !          4205:        for (chan = 0; chan < 4; chan++) {
        !          4206:                pc = &sc->pciide_channels[chan];
        !          4207:                for (reg = 0; reg < IDEDMA_NREGS; reg++) {
        !          4208:                        size = 4;
        !          4209:                        if (size > (IDEDMA_SCH_OFFSET - reg))
        !          4210:                                size = IDEDMA_SCH_OFFSET - reg;
        !          4211:                        if (bus_space_subregion(sl->ba5_st,
        !          4212:                            sl->ba5_sh,
        !          4213:                            satalink_ba5_regmap[chan].ba5_IDEDMA_CMD + reg,
        !          4214:                            size, &sl->regs[chan].dma_iohs[reg]) != 0) {
        !          4215:                                sc->sc_dma_ok = 0;
        !          4216:                                printf(": can't subregion offset "
        !          4217:                                    "%lu size %lu",
        !          4218:                                    (u_long) satalink_ba5_regmap[
        !          4219:                                                chan].ba5_IDEDMA_CMD + reg,
        !          4220:                                    (u_long) size);
        !          4221:                                return;
        !          4222:                        }
        !          4223:                }
        !          4224:        }
        !          4225:
        !          4226:        sc->sc_dmacmd_read = sii3114_dmacmd_read;
        !          4227:        sc->sc_dmacmd_write = sii3114_dmacmd_write;
        !          4228:        sc->sc_dmactl_read = sii3114_dmactl_read;
        !          4229:        sc->sc_dmactl_write = sii3114_dmactl_write;
        !          4230:        sc->sc_dmatbl_write = sii3114_dmatbl_write;
        !          4231:
        !          4232:        /* DMA registers all set up! */
        !          4233:        sc->sc_dmat = pa->pa_dmat;
        !          4234:        sc->sc_dma_ok = 1;
        !          4235: }
        !          4236:
        !          4237: int
        !          4238: sii3114_chansetup(struct pciide_softc *sc, int channel)
        !          4239: {
        !          4240:        static const char *channel_names[] = {
        !          4241:                "port 0",
        !          4242:                "port 1",
        !          4243:                "port 2",
        !          4244:                "port 3",
        !          4245:        };
        !          4246:        struct pciide_channel *cp = &sc->pciide_channels[channel];
        !          4247:
        !          4248:        sc->wdc_chanarray[channel] = &cp->wdc_channel;
        !          4249:
        !          4250:        /*
        !          4251:         * We must always keep the Interrupt Steering bit set in channel 2's
        !          4252:         * IDEDMA_CMD register.
        !          4253:         */
        !          4254:        if (channel == 2)
        !          4255:                cp->idedma_cmd = IDEDMA_CMD_INT_STEER;
        !          4256:
        !          4257:        cp->name = channel_names[channel];
        !          4258:        cp->wdc_channel.channel = channel;
        !          4259:        cp->wdc_channel.wdc = &sc->sc_wdcdev;
        !          4260:        cp->wdc_channel.ch_queue =
        !          4261:            malloc(sizeof(struct channel_queue), M_DEVBUF, M_NOWAIT);
        !          4262:        if (cp->wdc_channel.ch_queue == NULL) {
        !          4263:                printf("%s %s channel: "
        !          4264:                    "can't allocate memory for command queue",
        !          4265:                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          4266:                return (0);
        !          4267:        }
        !          4268:        return (1);
        !          4269: }
        !          4270:
        !          4271: void
        !          4272: sii3114_mapchan(struct pciide_channel *cp)
        !          4273: {
        !          4274:        struct channel_softc *wdc_cp = &cp->wdc_channel;
        !          4275:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          4276:        struct pciide_satalink *sl = sc->sc_cookie;
        !          4277:        int chan = wdc_cp->channel;
        !          4278:        int i;
        !          4279:
        !          4280:        cp->hw_ok = 0;
        !          4281:        cp->compat = 0;
        !          4282:        cp->ih = sc->sc_pci_ih;
        !          4283:
        !          4284:        sl->regs[chan].cmd_iot = sl->ba5_st;
        !          4285:        if (bus_space_subregion(sl->ba5_st, sl->ba5_sh,
        !          4286:                        satalink_ba5_regmap[chan].ba5_IDE_TF0,
        !          4287:                        9, &sl->regs[chan].cmd_baseioh) != 0) {
        !          4288:                printf("%s: couldn't subregion %s cmd base\n",
        !          4289:                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          4290:                return;
        !          4291:        }
        !          4292:
        !          4293:        sl->regs[chan].ctl_iot = sl->ba5_st;
        !          4294:        if (bus_space_subregion(sl->ba5_st, sl->ba5_sh,
        !          4295:                        satalink_ba5_regmap[chan].ba5_IDE_TF8,
        !          4296:                        1, &cp->ctl_baseioh) != 0) {
        !          4297:                printf("%s: couldn't subregion %s ctl base\n",
        !          4298:                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          4299:                return;
        !          4300:        }
        !          4301:        sl->regs[chan].ctl_ioh = cp->ctl_baseioh;
        !          4302:
        !          4303:        for (i = 0; i < WDC_NREG; i++) {
        !          4304:                if (bus_space_subregion(sl->regs[chan].cmd_iot,
        !          4305:                    sl->regs[chan].cmd_baseioh,
        !          4306:                    i, i == 0 ? 4 : 1,
        !          4307:                    &sl->regs[chan].cmd_iohs[i]) != 0) {
        !          4308:                        printf("%s: couldn't subregion %s channel "
        !          4309:                            "cmd regs\n",
        !          4310:                            sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          4311:                        return;
        !          4312:                }
        !          4313:        }
        !          4314:        sl->regs[chan].cmd_iohs[wdr_status & _WDC_REGMASK] =
        !          4315:            sl->regs[chan].cmd_iohs[wdr_command & _WDC_REGMASK];
        !          4316:        sl->regs[chan].cmd_iohs[wdr_features & _WDC_REGMASK] =
        !          4317:            sl->regs[chan].cmd_iohs[wdr_error & _WDC_REGMASK];
        !          4318:        wdc_cp->data32iot = wdc_cp->cmd_iot = sl->regs[chan].cmd_iot;
        !          4319:        wdc_cp->data32ioh = wdc_cp->cmd_ioh = sl->regs[chan].cmd_iohs[0];
        !          4320:        wdc_cp->_vtbl = &wdc_sii3114_vtbl;
        !          4321:        wdcattach(wdc_cp);
        !          4322:        cp->hw_ok = 1;
        !          4323: }
        !          4324:
        !          4325: u_int8_t
        !          4326: sii3114_read_reg(struct channel_softc *chp, enum wdc_regs reg)
        !          4327: {
        !          4328:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          4329:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          4330:        struct pciide_satalink *sl = sc->sc_cookie;
        !          4331:
        !          4332:        if (reg & _WDC_AUX)
        !          4333:                return (bus_space_read_1(sl->regs[chp->channel].ctl_iot,
        !          4334:                    sl->regs[chp->channel].ctl_ioh, reg & _WDC_REGMASK));
        !          4335:        else
        !          4336:                return (bus_space_read_1(sl->regs[chp->channel].cmd_iot,
        !          4337:                    sl->regs[chp->channel].cmd_iohs[reg & _WDC_REGMASK], 0));
        !          4338: }
        !          4339:
        !          4340: void
        !          4341: sii3114_write_reg(struct channel_softc *chp, enum wdc_regs reg, u_int8_t val)
        !          4342: {
        !          4343:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          4344:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          4345:        struct pciide_satalink *sl = sc->sc_cookie;
        !          4346:
        !          4347:        if (reg & _WDC_AUX)
        !          4348:                bus_space_write_1(sl->regs[chp->channel].ctl_iot,
        !          4349:                    sl->regs[chp->channel].ctl_ioh, reg & _WDC_REGMASK, val);
        !          4350:        else
        !          4351:                bus_space_write_1(sl->regs[chp->channel].cmd_iot,
        !          4352:                    sl->regs[chp->channel].cmd_iohs[reg & _WDC_REGMASK],
        !          4353:                    0, val);
        !          4354: }
        !          4355:
        !          4356: u_int8_t
        !          4357: sii3114_dmacmd_read(struct pciide_softc *sc, int chan)
        !          4358: {
        !          4359:        struct pciide_satalink *sl = sc->sc_cookie;
        !          4360:
        !          4361:        return (bus_space_read_1(sc->sc_dma_iot,
        !          4362:            sl->regs[chan].dma_iohs[IDEDMA_CMD(0)], 0));
        !          4363: }
        !          4364:
        !          4365: void
        !          4366: sii3114_dmacmd_write(struct pciide_softc *sc, int chan, u_int8_t val)
        !          4367: {
        !          4368:        struct pciide_satalink *sl = sc->sc_cookie;
        !          4369:
        !          4370:        bus_space_write_1(sc->sc_dma_iot,
        !          4371:            sl->regs[chan].dma_iohs[IDEDMA_CMD(0)], 0, val);
        !          4372: }
        !          4373:
        !          4374: u_int8_t
        !          4375: sii3114_dmactl_read(struct pciide_softc *sc, int chan)
        !          4376: {
        !          4377:        struct pciide_satalink *sl = sc->sc_cookie;
        !          4378:
        !          4379:        return (bus_space_read_1(sc->sc_dma_iot,
        !          4380:            sl->regs[chan].dma_iohs[IDEDMA_CTL(0)], 0));
        !          4381: }
        !          4382:
        !          4383: void
        !          4384: sii3114_dmactl_write(struct pciide_softc *sc, int chan, u_int8_t val)
        !          4385: {
        !          4386:        struct pciide_satalink *sl = sc->sc_cookie;
        !          4387:
        !          4388:        bus_space_write_1(sc->sc_dma_iot,
        !          4389:            sl->regs[chan].dma_iohs[IDEDMA_CTL(0)], 0, val);
        !          4390: }
        !          4391:
        !          4392: void
        !          4393: sii3114_dmatbl_write(struct pciide_softc *sc, int chan, u_int32_t val)
        !          4394: {
        !          4395:        struct pciide_satalink *sl = sc->sc_cookie;
        !          4396:
        !          4397:        bus_space_write_4(sc->sc_dma_iot,
        !          4398:            sl->regs[chan].dma_iohs[IDEDMA_TBL(0)], 0, val);
        !          4399: }
        !          4400:
        !          4401: void
        !          4402: cy693_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          4403: {
        !          4404:        struct pciide_channel *cp;
        !          4405:        pcireg_t interface = PCI_INTERFACE(pa->pa_class);
        !          4406:        bus_size_t cmdsize, ctlsize;
        !          4407:        struct pciide_cy *cy;
        !          4408:
        !          4409:        /* Allocate memory for private data */
        !          4410:        sc->sc_cookie = malloc(sizeof(struct pciide_cy), M_DEVBUF, M_NOWAIT);
        !          4411:        cy = sc->sc_cookie;
        !          4412:        bzero(cy, sizeof(*cy));
        !          4413:
        !          4414:        /*
        !          4415:         * this chip has 2 PCI IDE functions, one for primary and one for
        !          4416:         * secondary. So we need to call pciide_mapregs_compat() with
        !          4417:         * the real channel
        !          4418:         */
        !          4419:        if (pa->pa_function == 1) {
        !          4420:                cy->cy_compatchan = 0;
        !          4421:        } else if (pa->pa_function == 2) {
        !          4422:                cy->cy_compatchan = 1;
        !          4423:        } else {
        !          4424:                printf(": unexpected PCI function %d\n", pa->pa_function);
        !          4425:                return;
        !          4426:        }
        !          4427:
        !          4428:        if (interface & PCIIDE_INTERFACE_BUS_MASTER_DMA) {
        !          4429:                printf(": DMA");
        !          4430:                pciide_mapreg_dma(sc, pa);
        !          4431:        } else {
        !          4432:                printf(": no DMA");
        !          4433:                sc->sc_dma_ok = 0;
        !          4434:        }
        !          4435:
        !          4436:        cy->cy_handle = cy82c693_init(pa->pa_iot);
        !          4437:        if (cy->cy_handle == NULL) {
        !          4438:                printf(", (unable to map ctl registers)");
        !          4439:                sc->sc_dma_ok = 0;
        !          4440:        }
        !          4441:
        !          4442:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          4443:            WDC_CAPABILITY_MODE;
        !          4444:        if (sc->sc_dma_ok) {
        !          4445:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
        !          4446:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          4447:        }
        !          4448:        sc->sc_wdcdev.PIO_cap = 4;
        !          4449:        sc->sc_wdcdev.DMA_cap = 2;
        !          4450:        sc->sc_wdcdev.set_modes = cy693_setup_channel;
        !          4451:
        !          4452:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          4453:        sc->sc_wdcdev.nchannels = 1;
        !          4454:
        !          4455:        /* Only one channel for this chip; if we are here it's enabled */
        !          4456:        cp = &sc->pciide_channels[0];
        !          4457:        sc->wdc_chanarray[0] = &cp->wdc_channel;
        !          4458:        cp->name = PCIIDE_CHANNEL_NAME(0);
        !          4459:        cp->wdc_channel.channel = 0;
        !          4460:        cp->wdc_channel.wdc = &sc->sc_wdcdev;
        !          4461:        cp->wdc_channel.ch_queue =
        !          4462:            malloc(sizeof(struct channel_queue), M_DEVBUF, M_NOWAIT);
        !          4463:        if (cp->wdc_channel.ch_queue == NULL) {
        !          4464:                printf(": cannot allocate memory for command queue\n");
        !          4465:                return;
        !          4466:        }
        !          4467:        printf(", %s %s to ", PCIIDE_CHANNEL_NAME(0),
        !          4468:            (interface & PCIIDE_INTERFACE_SETTABLE(0)) ?
        !          4469:            "configured" : "wired");
        !          4470:        if (interface & PCIIDE_INTERFACE_PCI(0)) {
        !          4471:                printf("native-PCI\n");
        !          4472:                cp->hw_ok = pciide_mapregs_native(pa, cp, &cmdsize, &ctlsize,
        !          4473:                    pciide_pci_intr);
        !          4474:        } else {
        !          4475:                printf("compatibility\n");
        !          4476:                cp->hw_ok = pciide_mapregs_compat(pa, cp, cy->cy_compatchan,
        !          4477:                    &cmdsize, &ctlsize);
        !          4478:        }
        !          4479:
        !          4480:        cp->wdc_channel.data32iot = cp->wdc_channel.cmd_iot;
        !          4481:        cp->wdc_channel.data32ioh = cp->wdc_channel.cmd_ioh;
        !          4482:        pciide_map_compat_intr(pa, cp, cy->cy_compatchan, interface);
        !          4483:        if (cp->hw_ok == 0)
        !          4484:                return;
        !          4485:        wdcattach(&cp->wdc_channel);
        !          4486:        if (pciide_chan_candisable(cp)) {
        !          4487:                pci_conf_write(sc->sc_pc, sc->sc_tag,
        !          4488:                    PCI_COMMAND_STATUS_REG, 0);
        !          4489:        }
        !          4490:        if (cp->hw_ok == 0) {
        !          4491:                pciide_unmap_compat_intr(pa, cp, cy->cy_compatchan,
        !          4492:                    interface);
        !          4493:                return;
        !          4494:        }
        !          4495:
        !          4496:        WDCDEBUG_PRINT(("cy693_chip_map: old timings reg 0x%x\n",
        !          4497:            pci_conf_read(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL)), DEBUG_PROBE);
        !          4498:        cy693_setup_channel(&cp->wdc_channel);
        !          4499:        WDCDEBUG_PRINT(("cy693_chip_map: new timings reg 0x%x\n",
        !          4500:            pci_conf_read(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL)), DEBUG_PROBE);
        !          4501: }
        !          4502:
        !          4503: void
        !          4504: cy693_setup_channel(struct channel_softc *chp)
        !          4505: {
        !          4506:        struct ata_drive_datas *drvp;
        !          4507:        int drive;
        !          4508:        u_int32_t cy_cmd_ctrl;
        !          4509:        u_int32_t idedma_ctl;
        !          4510:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          4511:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          4512:        int dma_mode = -1;
        !          4513:        struct pciide_cy *cy = sc->sc_cookie;
        !          4514:
        !          4515:        cy_cmd_ctrl = idedma_ctl = 0;
        !          4516:
        !          4517:        /* setup DMA if needed */
        !          4518:        pciide_channel_dma_setup(cp);
        !          4519:
        !          4520:        for (drive = 0; drive < 2; drive++) {
        !          4521:                drvp = &chp->ch_drive[drive];
        !          4522:                /* If no drive, skip */
        !          4523:                if ((drvp->drive_flags & DRIVE) == 0)
        !          4524:                        continue;
        !          4525:                /* add timing values, setup DMA if needed */
        !          4526:                if (drvp->drive_flags & DRIVE_DMA) {
        !          4527:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          4528:                        /* use Multiword DMA */
        !          4529:                        if (dma_mode == -1 || dma_mode > drvp->DMA_mode)
        !          4530:                                dma_mode = drvp->DMA_mode;
        !          4531:                }
        !          4532:                cy_cmd_ctrl |= (cy_pio_pulse[drvp->PIO_mode] <<
        !          4533:                    CY_CMD_CTRL_IOW_PULSE_OFF(drive));
        !          4534:                cy_cmd_ctrl |= (cy_pio_rec[drvp->PIO_mode] <<
        !          4535:                    CY_CMD_CTRL_IOW_REC_OFF(drive));
        !          4536:                cy_cmd_ctrl |= (cy_pio_pulse[drvp->PIO_mode] <<
        !          4537:                    CY_CMD_CTRL_IOR_PULSE_OFF(drive));
        !          4538:                cy_cmd_ctrl |= (cy_pio_rec[drvp->PIO_mode] <<
        !          4539:                    CY_CMD_CTRL_IOR_REC_OFF(drive));
        !          4540:        }
        !          4541:        pci_conf_write(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL, cy_cmd_ctrl);
        !          4542:        chp->ch_drive[0].DMA_mode = dma_mode;
        !          4543:        chp->ch_drive[1].DMA_mode = dma_mode;
        !          4544:
        !          4545:        if (dma_mode == -1)
        !          4546:                dma_mode = 0;
        !          4547:
        !          4548:        if (cy->cy_handle != NULL) {
        !          4549:                /* Note: `multiple' is implied. */
        !          4550:                cy82c693_write(cy->cy_handle,
        !          4551:                    (cy->cy_compatchan == 0) ?
        !          4552:                    CY_DMA_IDX_PRIMARY : CY_DMA_IDX_SECONDARY, dma_mode);
        !          4553:        }
        !          4554:
        !          4555:        pciide_print_modes(cp);
        !          4556:
        !          4557:        if (idedma_ctl != 0) {
        !          4558:                /* Add software bits in status register */
        !          4559:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          4560:                    IDEDMA_CTL(chp->channel), idedma_ctl);
        !          4561:        }
        !          4562: }
        !          4563:
        !          4564: static struct sis_hostbr_type {
        !          4565:        u_int16_t id;
        !          4566:        u_int8_t rev;
        !          4567:        u_int8_t udma_mode;
        !          4568:        char *name;
        !          4569:        u_int8_t type;
        !          4570: #define SIS_TYPE_NOUDMA        0
        !          4571: #define SIS_TYPE_66    1
        !          4572: #define SIS_TYPE_100OLD        2
        !          4573: #define SIS_TYPE_100NEW 3
        !          4574: #define SIS_TYPE_133OLD 4
        !          4575: #define SIS_TYPE_133NEW 5
        !          4576: #define SIS_TYPE_SOUTH 6
        !          4577: } sis_hostbr_type[] = {
        !          4578:        /* Most infos here are from sos@freebsd.org */
        !          4579:        {PCI_PRODUCT_SIS_530, 0x00, 4, "530", SIS_TYPE_66},
        !          4580: #if 0
        !          4581:        /*
        !          4582:         * controllers associated to a rev 0x2 530 Host to PCI Bridge
        !          4583:         * have problems with UDMA (info provided by Christos)
        !          4584:         */
        !          4585:        {PCI_PRODUCT_SIS_530, 0x02, 0, "530 (buggy)", SIS_TYPE_NOUDMA},
        !          4586: #endif
        !          4587:        {PCI_PRODUCT_SIS_540, 0x00, 4, "540", SIS_TYPE_66},
        !          4588:        {PCI_PRODUCT_SIS_550, 0x00, 4, "550", SIS_TYPE_66},
        !          4589:        {PCI_PRODUCT_SIS_620, 0x00, 4, "620", SIS_TYPE_66},
        !          4590:        {PCI_PRODUCT_SIS_630, 0x00, 4, "630", SIS_TYPE_66},
        !          4591:        {PCI_PRODUCT_SIS_630, 0x30, 5, "630S", SIS_TYPE_100NEW},
        !          4592:        {PCI_PRODUCT_SIS_633, 0x00, 5, "633", SIS_TYPE_100NEW},
        !          4593:        {PCI_PRODUCT_SIS_635, 0x00, 5, "635", SIS_TYPE_100NEW},
        !          4594:        {PCI_PRODUCT_SIS_640, 0x00, 4, "640", SIS_TYPE_SOUTH},
        !          4595:        {PCI_PRODUCT_SIS_645, 0x00, 6, "645", SIS_TYPE_SOUTH},
        !          4596:        {PCI_PRODUCT_SIS_646, 0x00, 6, "645DX", SIS_TYPE_SOUTH},
        !          4597:        {PCI_PRODUCT_SIS_648, 0x00, 6, "648", SIS_TYPE_SOUTH},
        !          4598:        {PCI_PRODUCT_SIS_650, 0x00, 6, "650", SIS_TYPE_SOUTH},
        !          4599:        {PCI_PRODUCT_SIS_651, 0x00, 6, "651", SIS_TYPE_SOUTH},
        !          4600:        {PCI_PRODUCT_SIS_652, 0x00, 6, "652", SIS_TYPE_SOUTH},
        !          4601:        {PCI_PRODUCT_SIS_655, 0x00, 6, "655", SIS_TYPE_SOUTH},
        !          4602:        {PCI_PRODUCT_SIS_658, 0x00, 6, "658", SIS_TYPE_SOUTH},
        !          4603:        {PCI_PRODUCT_SIS_661, 0x00, 6, "661", SIS_TYPE_SOUTH},
        !          4604:        {PCI_PRODUCT_SIS_730, 0x00, 5, "730", SIS_TYPE_100OLD},
        !          4605:        {PCI_PRODUCT_SIS_733, 0x00, 5, "733", SIS_TYPE_100NEW},
        !          4606:        {PCI_PRODUCT_SIS_735, 0x00, 5, "735", SIS_TYPE_100NEW},
        !          4607:        {PCI_PRODUCT_SIS_740, 0x00, 5, "740", SIS_TYPE_SOUTH},
        !          4608:        {PCI_PRODUCT_SIS_741, 0x00, 6, "741", SIS_TYPE_SOUTH},
        !          4609:        {PCI_PRODUCT_SIS_745, 0x00, 5, "745", SIS_TYPE_100NEW},
        !          4610:        {PCI_PRODUCT_SIS_746, 0x00, 6, "746", SIS_TYPE_SOUTH},
        !          4611:        {PCI_PRODUCT_SIS_748, 0x00, 6, "748", SIS_TYPE_SOUTH},
        !          4612:        {PCI_PRODUCT_SIS_750, 0x00, 6, "750", SIS_TYPE_SOUTH},
        !          4613:        {PCI_PRODUCT_SIS_751, 0x00, 6, "751", SIS_TYPE_SOUTH},
        !          4614:        {PCI_PRODUCT_SIS_752, 0x00, 6, "752", SIS_TYPE_SOUTH},
        !          4615:        {PCI_PRODUCT_SIS_755, 0x00, 6, "755", SIS_TYPE_SOUTH},
        !          4616:        {PCI_PRODUCT_SIS_760, 0x00, 6, "760", SIS_TYPE_SOUTH},
        !          4617:        /*
        !          4618:         * From sos@freebsd.org: the 0x961 ID will never be found in real world
        !          4619:         * {PCI_PRODUCT_SIS_961, 0x00, 6, "961", SIS_TYPE_133NEW},
        !          4620:         */
        !          4621:        {PCI_PRODUCT_SIS_962, 0x00, 6, "962", SIS_TYPE_133NEW},
        !          4622:        {PCI_PRODUCT_SIS_963, 0x00, 6, "963", SIS_TYPE_133NEW}
        !          4623: };
        !          4624:
        !          4625: static struct sis_hostbr_type *sis_hostbr_type_match;
        !          4626:
        !          4627: int
        !          4628: sis_hostbr_match(struct pci_attach_args *pa)
        !          4629: {
        !          4630:        int i;
        !          4631:
        !          4632:        if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_SIS)
        !          4633:                return (0);
        !          4634:        sis_hostbr_type_match = NULL;
        !          4635:        for (i = 0;
        !          4636:            i < sizeof(sis_hostbr_type) / sizeof(sis_hostbr_type[0]);
        !          4637:            i++) {
        !          4638:                if (PCI_PRODUCT(pa->pa_id) == sis_hostbr_type[i].id &&
        !          4639:                    PCI_REVISION(pa->pa_class) >= sis_hostbr_type[i].rev)
        !          4640:                        sis_hostbr_type_match = &sis_hostbr_type[i];
        !          4641:        }
        !          4642:        return (sis_hostbr_type_match != NULL);
        !          4643: }
        !          4644:
        !          4645: int
        !          4646: sis_south_match(struct pci_attach_args *pa)
        !          4647: {
        !          4648:        return(PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SIS &&
        !          4649:            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SIS_85C503 &&
        !          4650:            PCI_REVISION(pa->pa_class) >= 0x10);
        !          4651: }
        !          4652:
        !          4653: void
        !          4654: sis_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          4655: {
        !          4656:        struct pciide_channel *cp;
        !          4657:        int channel;
        !          4658:        u_int8_t sis_ctr0 = pciide_pci_read(sc->sc_pc, sc->sc_tag, SIS_CTRL0);
        !          4659:        pcireg_t interface = PCI_INTERFACE(pa->pa_class);
        !          4660:        int rev = sc->sc_rev;
        !          4661:        bus_size_t cmdsize, ctlsize;
        !          4662:        pcitag_t br_tag;
        !          4663:        struct pci_attach_args br_pa;
        !          4664:        struct pciide_sis *sis;
        !          4665:
        !          4666:        /* Allocate memory for private data */
        !          4667:        sc->sc_cookie = malloc(sizeof(struct pciide_sis), M_DEVBUF, M_NOWAIT);
        !          4668:        sis = sc->sc_cookie;
        !          4669:        bzero(sis, sizeof(*sis));
        !          4670:
        !          4671:        /* Find PCI bridge (dev 0 func 0 on the same bus) */
        !          4672:        br_tag = pci_make_tag(pa->pa_pc, pa->pa_bus, 0, 0);
        !          4673:        br_pa.pa_id = pci_conf_read(sc->sc_pc, br_tag, PCI_ID_REG);
        !          4674:        br_pa.pa_class = pci_conf_read(sc->sc_pc, br_tag, PCI_CLASS_REG);
        !          4675:        WDCDEBUG_PRINT(("%s: PCI bridge pa_id=0x%x pa_class=0x%x\n",
        !          4676:            __func__, br_pa.pa_id, br_pa.pa_class), DEBUG_PROBE);
        !          4677:
        !          4678:        if (sis_hostbr_match(&br_pa)) {
        !          4679:                if (sis_hostbr_type_match->type == SIS_TYPE_SOUTH) {
        !          4680:                        pciide_pci_write(sc->sc_pc, sc->sc_tag, SIS_REG_57,
        !          4681:                            pciide_pci_read(sc->sc_pc, sc->sc_tag,
        !          4682:                            SIS_REG_57) & 0x7f);
        !          4683:                        if (sc->sc_pp->ide_product == SIS_PRODUCT_5518) {
        !          4684:                                sis->sis_type = SIS_TYPE_133NEW;
        !          4685:                                sc->sc_wdcdev.UDMA_cap =
        !          4686:                                    sis_hostbr_type_match->udma_mode;
        !          4687:                        } else {
        !          4688:                                /* Find ISA bridge (func 0 of the same dev) */
        !          4689:                                br_tag = pci_make_tag(pa->pa_pc, pa->pa_bus,
        !          4690:                                    pa->pa_device, 0);
        !          4691:                                br_pa.pa_id = pci_conf_read(sc->sc_pc,
        !          4692:                                    br_tag, PCI_ID_REG);
        !          4693:                                br_pa.pa_class = pci_conf_read(sc->sc_pc,
        !          4694:                                    br_tag, PCI_CLASS_REG);
        !          4695:                                WDCDEBUG_PRINT(("%s: ISA bridge "
        !          4696:                                    "pa_id=0x%x pa_class=0x%x\n",
        !          4697:                                    __func__, br_pa.pa_id, br_pa.pa_class),
        !          4698:                                    DEBUG_PROBE);
        !          4699:
        !          4700:                                if (sis_south_match(&br_pa)) {
        !          4701:                                        sis->sis_type = SIS_TYPE_133OLD;
        !          4702:                                        sc->sc_wdcdev.UDMA_cap =
        !          4703:                                            sis_hostbr_type_match->udma_mode;
        !          4704:                                } else {
        !          4705:                                        sis->sis_type = SIS_TYPE_100NEW;
        !          4706:                                        sc->sc_wdcdev.UDMA_cap =
        !          4707:                                            sis_hostbr_type_match->udma_mode;
        !          4708:                                }
        !          4709:                        }
        !          4710:                } else {
        !          4711:                        sis->sis_type = sis_hostbr_type_match->type;
        !          4712:                        sc->sc_wdcdev.UDMA_cap =
        !          4713:                            sis_hostbr_type_match->udma_mode;
        !          4714:                }
        !          4715:                printf(": %s", sis_hostbr_type_match->name);
        !          4716:        } else {
        !          4717:                printf(": 5597/5598");
        !          4718:                if (rev >= 0xd0) {
        !          4719:                        sc->sc_wdcdev.UDMA_cap = 2;
        !          4720:                        sis->sis_type = SIS_TYPE_66;
        !          4721:                } else {
        !          4722:                        sc->sc_wdcdev.UDMA_cap = 0;
        !          4723:                        sis->sis_type = SIS_TYPE_NOUDMA;
        !          4724:                }
        !          4725:        }
        !          4726:
        !          4727:        printf(": DMA");
        !          4728:        pciide_mapreg_dma(sc, pa);
        !          4729:
        !          4730:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          4731:            WDC_CAPABILITY_MODE;
        !          4732:        if (sc->sc_dma_ok) {
        !          4733:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
        !          4734:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          4735:                if (sis->sis_type >= SIS_TYPE_66)
        !          4736:                        sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA;
        !          4737:        }
        !          4738:
        !          4739:        sc->sc_wdcdev.PIO_cap = 4;
        !          4740:        sc->sc_wdcdev.DMA_cap = 2;
        !          4741:
        !          4742:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          4743:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          4744:        switch (sis->sis_type) {
        !          4745:        case SIS_TYPE_NOUDMA:
        !          4746:        case SIS_TYPE_66:
        !          4747:        case SIS_TYPE_100OLD:
        !          4748:                sc->sc_wdcdev.set_modes = sis_setup_channel;
        !          4749:                pciide_pci_write(sc->sc_pc, sc->sc_tag, SIS_MISC,
        !          4750:                    pciide_pci_read(sc->sc_pc, sc->sc_tag, SIS_MISC) |
        !          4751:                    SIS_MISC_TIM_SEL | SIS_MISC_FIFO_SIZE | SIS_MISC_GTC);
        !          4752:                break;
        !          4753:        case SIS_TYPE_100NEW:
        !          4754:        case SIS_TYPE_133OLD:
        !          4755:                sc->sc_wdcdev.set_modes = sis_setup_channel;
        !          4756:                pciide_pci_write(sc->sc_pc, sc->sc_tag, SIS_REG_49,
        !          4757:                    pciide_pci_read(sc->sc_pc, sc->sc_tag, SIS_REG_49) | 0x01);
        !          4758:                break;
        !          4759:        case SIS_TYPE_133NEW:
        !          4760:                sc->sc_wdcdev.set_modes = sis96x_setup_channel;
        !          4761:                pciide_pci_write(sc->sc_pc, sc->sc_tag, SIS_REG_50,
        !          4762:                    pciide_pci_read(sc->sc_pc, sc->sc_tag, SIS_REG_50) & 0xf7);
        !          4763:                pciide_pci_write(sc->sc_pc, sc->sc_tag, SIS_REG_52,
        !          4764:                    pciide_pci_read(sc->sc_pc, sc->sc_tag, SIS_REG_52) & 0xf7);
        !          4765:                break;
        !          4766:        }
        !          4767:
        !          4768:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          4769:
        !          4770:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          4771:                cp = &sc->pciide_channels[channel];
        !          4772:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          4773:                        continue;
        !          4774:                if ((channel == 0 && (sis_ctr0 & SIS_CTRL0_CHAN0_EN) == 0) ||
        !          4775:                    (channel == 1 && (sis_ctr0 & SIS_CTRL0_CHAN1_EN) == 0)) {
        !          4776:                        printf("%s: %s ignored (disabled)\n",
        !          4777:                            sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          4778:                        continue;
        !          4779:                }
        !          4780:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          4781:                if (cp->hw_ok == 0)
        !          4782:                        continue;
        !          4783:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          4784:                    pciide_pci_intr);
        !          4785:                if (cp->hw_ok == 0) {
        !          4786:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          4787:                        continue;
        !          4788:                }
        !          4789:                if (pciide_chan_candisable(cp)) {
        !          4790:                        if (channel == 0)
        !          4791:                                sis_ctr0 &= ~SIS_CTRL0_CHAN0_EN;
        !          4792:                        else
        !          4793:                                sis_ctr0 &= ~SIS_CTRL0_CHAN1_EN;
        !          4794:                        pciide_pci_write(sc->sc_pc, sc->sc_tag, SIS_CTRL0,
        !          4795:                            sis_ctr0);
        !          4796:                }
        !          4797:                if (cp->hw_ok == 0) {
        !          4798:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          4799:                        continue;
        !          4800:                }
        !          4801:                sc->sc_wdcdev.set_modes(&cp->wdc_channel);
        !          4802:        }
        !          4803: }
        !          4804:
        !          4805: void
        !          4806: sis96x_setup_channel(struct channel_softc *chp)
        !          4807: {
        !          4808:        struct ata_drive_datas *drvp;
        !          4809:        int drive;
        !          4810:        u_int32_t sis_tim;
        !          4811:        u_int32_t idedma_ctl;
        !          4812:        int regtim;
        !          4813:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          4814:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          4815:
        !          4816:        sis_tim = 0;
        !          4817:        idedma_ctl = 0;
        !          4818:        /* setup DMA if needed */
        !          4819:        pciide_channel_dma_setup(cp);
        !          4820:
        !          4821:        for (drive = 0; drive < 2; drive++) {
        !          4822:                regtim = SIS_TIM133(
        !          4823:                    pciide_pci_read(sc->sc_pc, sc->sc_tag, SIS_REG_57),
        !          4824:                    chp->channel, drive);
        !          4825:                drvp = &chp->ch_drive[drive];
        !          4826:                /* If no drive, skip */
        !          4827:                if ((drvp->drive_flags & DRIVE) == 0)
        !          4828:                        continue;
        !          4829:                /* add timing values, setup DMA if needed */
        !          4830:                if (drvp->drive_flags & DRIVE_UDMA) {
        !          4831:                        /* use Ultra/DMA */
        !          4832:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          4833:                        if (pciide_pci_read(sc->sc_pc, sc->sc_tag,
        !          4834:                            SIS96x_REG_CBL(chp->channel)) & SIS96x_REG_CBL_33) {
        !          4835:                                if (drvp->UDMA_mode > 2)
        !          4836:                                        drvp->UDMA_mode = 2;
        !          4837:                        }
        !          4838:                        sis_tim |= sis_udma133new_tim[drvp->UDMA_mode];
        !          4839:                        sis_tim |= sis_pio133new_tim[drvp->PIO_mode];
        !          4840:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          4841:                } else if (drvp->drive_flags & DRIVE_DMA) {
        !          4842:                        /*
        !          4843:                         * use Multiword DMA
        !          4844:                         * Timings will be used for both PIO and DMA,
        !          4845:                         * so adjust DMA mode if needed
        !          4846:                         */
        !          4847:                        if (drvp->PIO_mode > (drvp->DMA_mode + 2))
        !          4848:                                drvp->PIO_mode = drvp->DMA_mode + 2;
        !          4849:                        if (drvp->DMA_mode + 2 > (drvp->PIO_mode))
        !          4850:                                drvp->DMA_mode = (drvp->PIO_mode > 2) ?
        !          4851:                                    drvp->PIO_mode - 2 : 0;
        !          4852:                        sis_tim |= sis_dma133new_tim[drvp->DMA_mode];
        !          4853:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          4854:                } else {
        !          4855:                        sis_tim |= sis_pio133new_tim[drvp->PIO_mode];
        !          4856:                }
        !          4857:                WDCDEBUG_PRINT(("sis96x_setup_channel: new timings reg for "
        !          4858:                    "channel %d drive %d: 0x%x (reg 0x%x)\n",
        !          4859:                    chp->channel, drive, sis_tim, regtim), DEBUG_PROBE);
        !          4860:                pci_conf_write(sc->sc_pc, sc->sc_tag, regtim, sis_tim);
        !          4861:        }
        !          4862:        if (idedma_ctl != 0) {
        !          4863:                /* Add software bits in status register */
        !          4864:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          4865:                    IDEDMA_CTL(chp->channel), idedma_ctl);
        !          4866:        }
        !          4867:        pciide_print_modes(cp);
        !          4868: }
        !          4869:
        !          4870: void
        !          4871: sis_setup_channel(struct channel_softc *chp)
        !          4872: {
        !          4873:        struct ata_drive_datas *drvp;
        !          4874:        int drive;
        !          4875:        u_int32_t sis_tim;
        !          4876:        u_int32_t idedma_ctl;
        !          4877:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          4878:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          4879:        struct pciide_sis *sis = sc->sc_cookie;
        !          4880:
        !          4881:        WDCDEBUG_PRINT(("sis_setup_channel: old timings reg for "
        !          4882:            "channel %d 0x%x\n", chp->channel,
        !          4883:            pci_conf_read(sc->sc_pc, sc->sc_tag, SIS_TIM(chp->channel))),
        !          4884:            DEBUG_PROBE);
        !          4885:        sis_tim = 0;
        !          4886:        idedma_ctl = 0;
        !          4887:        /* setup DMA if needed */
        !          4888:        pciide_channel_dma_setup(cp);
        !          4889:
        !          4890:        for (drive = 0; drive < 2; drive++) {
        !          4891:                drvp = &chp->ch_drive[drive];
        !          4892:                /* If no drive, skip */
        !          4893:                if ((drvp->drive_flags & DRIVE) == 0)
        !          4894:                        continue;
        !          4895:                /* add timing values, setup DMA if needed */
        !          4896:                if ((drvp->drive_flags & DRIVE_DMA) == 0 &&
        !          4897:                    (drvp->drive_flags & DRIVE_UDMA) == 0)
        !          4898:                        goto pio;
        !          4899:
        !          4900:                if (drvp->drive_flags & DRIVE_UDMA) {
        !          4901:                        /* use Ultra/DMA */
        !          4902:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          4903:                        if (pciide_pci_read(sc->sc_pc, sc->sc_tag,
        !          4904:                            SIS_REG_CBL) & SIS_REG_CBL_33(chp->channel)) {
        !          4905:                                if (drvp->UDMA_mode > 2)
        !          4906:                                        drvp->UDMA_mode = 2;
        !          4907:                        }
        !          4908:                        switch (sis->sis_type) {
        !          4909:                        case SIS_TYPE_66:
        !          4910:                        case SIS_TYPE_100OLD:
        !          4911:                                sis_tim |= sis_udma66_tim[drvp->UDMA_mode] <<
        !          4912:                                    SIS_TIM66_UDMA_TIME_OFF(drive);
        !          4913:                                break;
        !          4914:                        case SIS_TYPE_100NEW:
        !          4915:                                sis_tim |=
        !          4916:                                    sis_udma100new_tim[drvp->UDMA_mode] <<
        !          4917:                                    SIS_TIM100_UDMA_TIME_OFF(drive);
        !          4918:                                break;
        !          4919:                        case SIS_TYPE_133OLD:
        !          4920:                                sis_tim |=
        !          4921:                                    sis_udma133old_tim[drvp->UDMA_mode] <<
        !          4922:                                    SIS_TIM100_UDMA_TIME_OFF(drive);
        !          4923:                                break;
        !          4924:                        default:
        !          4925:                                printf("unknown SiS IDE type %d\n",
        !          4926:                                    sis->sis_type);
        !          4927:                        }
        !          4928:                } else {
        !          4929:                        /*
        !          4930:                         * use Multiword DMA
        !          4931:                         * Timings will be used for both PIO and DMA,
        !          4932:                         * so adjust DMA mode if needed
        !          4933:                         */
        !          4934:                        if (drvp->PIO_mode > (drvp->DMA_mode + 2))
        !          4935:                                drvp->PIO_mode = drvp->DMA_mode + 2;
        !          4936:                        if (drvp->DMA_mode + 2 > (drvp->PIO_mode))
        !          4937:                                drvp->DMA_mode = (drvp->PIO_mode > 2) ?
        !          4938:                                    drvp->PIO_mode - 2 : 0;
        !          4939:                        if (drvp->DMA_mode == 0)
        !          4940:                                drvp->PIO_mode = 0;
        !          4941:                }
        !          4942:                idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          4943: pio:           switch (sis->sis_type) {
        !          4944:                case SIS_TYPE_NOUDMA:
        !          4945:                case SIS_TYPE_66:
        !          4946:                case SIS_TYPE_100OLD:
        !          4947:                        sis_tim |= sis_pio_act[drvp->PIO_mode] <<
        !          4948:                            SIS_TIM66_ACT_OFF(drive);
        !          4949:                        sis_tim |= sis_pio_rec[drvp->PIO_mode] <<
        !          4950:                            SIS_TIM66_REC_OFF(drive);
        !          4951:                        break;
        !          4952:                case SIS_TYPE_100NEW:
        !          4953:                case SIS_TYPE_133OLD:
        !          4954:                        sis_tim |= sis_pio_act[drvp->PIO_mode] <<
        !          4955:                            SIS_TIM100_ACT_OFF(drive);
        !          4956:                        sis_tim |= sis_pio_rec[drvp->PIO_mode] <<
        !          4957:                            SIS_TIM100_REC_OFF(drive);
        !          4958:                        break;
        !          4959:                default:
        !          4960:                        printf("unknown SiS IDE type %d\n",
        !          4961:                            sis->sis_type);
        !          4962:                }
        !          4963:        }
        !          4964:        WDCDEBUG_PRINT(("sis_setup_channel: new timings reg for "
        !          4965:            "channel %d 0x%x\n", chp->channel, sis_tim), DEBUG_PROBE);
        !          4966:        pci_conf_write(sc->sc_pc, sc->sc_tag, SIS_TIM(chp->channel), sis_tim);
        !          4967:        if (idedma_ctl != 0) {
        !          4968:                /* Add software bits in status register */
        !          4969:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          4970:                    IDEDMA_CTL(chp->channel), idedma_ctl);
        !          4971:        }
        !          4972:        pciide_print_modes(cp);
        !          4973: }
        !          4974:
        !          4975: void
        !          4976: natsemi_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          4977: {
        !          4978:        struct pciide_channel *cp;
        !          4979:        int channel;
        !          4980:        pcireg_t interface, ctl;
        !          4981:        bus_size_t cmdsize, ctlsize;
        !          4982:
        !          4983:        printf(": DMA");
        !          4984:        pciide_mapreg_dma(sc, pa);
        !          4985:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16;
        !          4986:
        !          4987:        if (sc->sc_dma_ok) {
        !          4988:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
        !          4989:                sc->sc_wdcdev.irqack = natsemi_irqack;
        !          4990:        }
        !          4991:
        !          4992:        pciide_pci_write(sc->sc_pc, sc->sc_tag, NATSEMI_CCBT, 0xb7);
        !          4993:
        !          4994:        /*
        !          4995:         * Mask off interrupts from both channels, appropriate channel(s)
        !          4996:         * will be unmasked later.
        !          4997:         */
        !          4998:        pciide_pci_write(sc->sc_pc, sc->sc_tag, NATSEMI_CTRL2,
        !          4999:            pciide_pci_read(sc->sc_pc, sc->sc_tag, NATSEMI_CTRL2) |
        !          5000:            NATSEMI_CHMASK(0) | NATSEMI_CHMASK(1));
        !          5001:
        !          5002:        sc->sc_wdcdev.PIO_cap = 4;
        !          5003:        sc->sc_wdcdev.DMA_cap = 2;
        !          5004:        sc->sc_wdcdev.set_modes = natsemi_setup_channel;
        !          5005:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          5006:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          5007:
        !          5008:        interface = PCI_INTERFACE(pci_conf_read(sc->sc_pc, sc->sc_tag,
        !          5009:            PCI_CLASS_REG));
        !          5010:        interface &= ~PCIIDE_CHANSTATUS_EN;     /* Reserved on PC87415 */
        !          5011:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          5012:
        !          5013:        /* If we're in PCIIDE mode, unmask INTA, otherwise mask it. */
        !          5014:        ctl = pciide_pci_read(sc->sc_pc, sc->sc_tag, NATSEMI_CTRL1);
        !          5015:        if (interface & (PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1)))
        !          5016:                ctl &= ~NATSEMI_CTRL1_INTAMASK;
        !          5017:        else
        !          5018:                ctl |= NATSEMI_CTRL1_INTAMASK;
        !          5019:        pciide_pci_write(sc->sc_pc, sc->sc_tag, NATSEMI_CTRL1, ctl);
        !          5020:
        !          5021:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          5022:                cp = &sc->pciide_channels[channel];
        !          5023:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          5024:                        continue;
        !          5025:
        !          5026:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          5027:                if (cp->hw_ok == 0)
        !          5028:                        continue;
        !          5029:
        !          5030:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          5031:                    natsemi_pci_intr);
        !          5032:                if (cp->hw_ok == 0) {
        !          5033:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          5034:                        continue;
        !          5035:                }
        !          5036:                natsemi_setup_channel(&cp->wdc_channel);
        !          5037:        }
        !          5038: }
        !          5039:
        !          5040: void
        !          5041: natsemi_setup_channel(struct channel_softc *chp)
        !          5042: {
        !          5043:        struct ata_drive_datas *drvp;
        !          5044:        int drive, ndrives = 0;
        !          5045:        u_int32_t idedma_ctl = 0;
        !          5046:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          5047:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          5048:        u_int8_t tim;
        !          5049:
        !          5050:        /* setup DMA if needed */
        !          5051:        pciide_channel_dma_setup(cp);
        !          5052:
        !          5053:        for (drive = 0; drive < 2; drive++) {
        !          5054:                drvp = &chp->ch_drive[drive];
        !          5055:                /* If no drive, skip */
        !          5056:                if ((drvp->drive_flags & DRIVE) == 0)
        !          5057:                        continue;
        !          5058:
        !          5059:                ndrives++;
        !          5060:                /* add timing values, setup DMA if needed */
        !          5061:                if ((drvp->drive_flags & DRIVE_DMA) == 0) {
        !          5062:                        tim = natsemi_pio_pulse[drvp->PIO_mode] |
        !          5063:                            (natsemi_pio_recover[drvp->PIO_mode] << 4);
        !          5064:                } else {
        !          5065:                        /*
        !          5066:                         * use Multiword DMA
        !          5067:                         * Timings will be used for both PIO and DMA,
        !          5068:                         * so adjust DMA mode if needed
        !          5069:                         */
        !          5070:                        if (drvp->PIO_mode >= 3 &&
        !          5071:                            (drvp->DMA_mode + 2) > drvp->PIO_mode) {
        !          5072:                                drvp->DMA_mode = drvp->PIO_mode - 2;
        !          5073:                        }
        !          5074:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          5075:                        tim = natsemi_dma_pulse[drvp->DMA_mode] |
        !          5076:                            (natsemi_dma_recover[drvp->DMA_mode] << 4);
        !          5077:                }
        !          5078:
        !          5079:                pciide_pci_write(sc->sc_pc, sc->sc_tag,
        !          5080:                    NATSEMI_RTREG(chp->channel, drive), tim);
        !          5081:                pciide_pci_write(sc->sc_pc, sc->sc_tag,
        !          5082:                    NATSEMI_WTREG(chp->channel, drive), tim);
        !          5083:        }
        !          5084:        if (idedma_ctl != 0) {
        !          5085:                /* Add software bits in status register */
        !          5086:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5087:                    IDEDMA_CTL(chp->channel), idedma_ctl);
        !          5088:        }
        !          5089:        if (ndrives > 0) {
        !          5090:                /* Unmask the channel if at least one drive is found */
        !          5091:                pciide_pci_write(sc->sc_pc, sc->sc_tag, NATSEMI_CTRL2,
        !          5092:                    pciide_pci_read(sc->sc_pc, sc->sc_tag, NATSEMI_CTRL2) &
        !          5093:                    ~(NATSEMI_CHMASK(chp->channel)));
        !          5094:        }
        !          5095:
        !          5096:        pciide_print_modes(cp);
        !          5097:
        !          5098:        /* Go ahead and ack interrupts generated during probe. */
        !          5099:        bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5100:            IDEDMA_CTL(chp->channel),
        !          5101:            bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5102:                IDEDMA_CTL(chp->channel)));
        !          5103: }
        !          5104:
        !          5105: void
        !          5106: natsemi_irqack(struct channel_softc *chp)
        !          5107: {
        !          5108:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          5109:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          5110:        u_int8_t clr;
        !          5111:
        !          5112:        /* The "clear" bits are in the wrong register *sigh* */
        !          5113:        clr = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5114:            IDEDMA_CMD(chp->channel));
        !          5115:        clr |= bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5116:            IDEDMA_CTL(chp->channel)) &
        !          5117:            (IDEDMA_CTL_ERR | IDEDMA_CTL_INTR);
        !          5118:        bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5119:            IDEDMA_CMD(chp->channel), clr);
        !          5120: }
        !          5121:
        !          5122: int
        !          5123: natsemi_pci_intr(void *arg)
        !          5124: {
        !          5125:        struct pciide_softc *sc = arg;
        !          5126:        struct pciide_channel *cp;
        !          5127:        struct channel_softc *wdc_cp;
        !          5128:        int i, rv, crv;
        !          5129:        u_int8_t msk;
        !          5130:
        !          5131:        rv = 0;
        !          5132:        msk = pciide_pci_read(sc->sc_pc, sc->sc_tag, NATSEMI_CTRL2);
        !          5133:        for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {
        !          5134:                cp = &sc->pciide_channels[i];
        !          5135:                wdc_cp = &cp->wdc_channel;
        !          5136:
        !          5137:                /* If a compat channel skip. */
        !          5138:                if (cp->compat)
        !          5139:                        continue;
        !          5140:
        !          5141:                /* If this channel is masked, skip it. */
        !          5142:                if (msk & NATSEMI_CHMASK(i))
        !          5143:                        continue;
        !          5144:
        !          5145:                if (pciide_intr_flag(cp) == 0)
        !          5146:                        continue;
        !          5147:
        !          5148:                crv = wdcintr(wdc_cp);
        !          5149:                if (crv == 0)
        !          5150:                        ;               /* leave rv alone */
        !          5151:                else if (crv == 1)
        !          5152:                        rv = 1;         /* claim the intr */
        !          5153:                else if (rv == 0)       /* crv should be -1 in this case */
        !          5154:                        rv = crv;       /* if we've done no better, take it */
        !          5155:        }
        !          5156:        return (rv);
        !          5157: }
        !          5158:
        !          5159: void
        !          5160: ns_scx200_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          5161: {
        !          5162:        struct pciide_channel *cp;
        !          5163:        int channel;
        !          5164:        pcireg_t interface = PCI_INTERFACE(pa->pa_class);
        !          5165:        bus_size_t cmdsize, ctlsize;
        !          5166:
        !          5167:        printf(": DMA");
        !          5168:        pciide_mapreg_dma(sc, pa);
        !          5169:
        !          5170:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          5171:            WDC_CAPABILITY_MODE;
        !          5172:        if (sc->sc_dma_ok) {
        !          5173:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
        !          5174:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          5175:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          5176:        }
        !          5177:        sc->sc_wdcdev.PIO_cap = 4;
        !          5178:        sc->sc_wdcdev.DMA_cap = 2;
        !          5179:        sc->sc_wdcdev.UDMA_cap = 2;
        !          5180:
        !          5181:        sc->sc_wdcdev.set_modes = ns_scx200_setup_channel;
        !          5182:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          5183:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          5184:
        !          5185:        /*
        !          5186:         * Soekris net4801 errata 0003:
        !          5187:         *
        !          5188:         * The SC1100 built in busmaster IDE controller is pretty standard,
        !          5189:         * but have two bugs: data transfers need to be dword aligned and
        !          5190:         * it cannot do an exact 64Kbyte data transfer.
        !          5191:         *
        !          5192:         * Assume that reducing maximum segment size by one page
        !          5193:         * will be enough, and restrict boundary too for extra certainty.
        !          5194:         */
        !          5195:        if (sc->sc_pp->ide_product == PCI_PRODUCT_NS_SCx200_IDE) {
        !          5196:                sc->sc_dma_maxsegsz = IDEDMA_BYTE_COUNT_MAX - PAGE_SIZE;
        !          5197:                sc->sc_dma_boundary = IDEDMA_BYTE_COUNT_MAX - PAGE_SIZE;
        !          5198:        }
        !          5199:
        !          5200:        /*
        !          5201:         * This chip seems to be unable to do one-sector transfers
        !          5202:         * using DMA.
        !          5203:         */
        !          5204:        sc->sc_wdcdev.quirks = WDC_QUIRK_NOSHORTDMA;
        !          5205:
        !          5206:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          5207:
        !          5208:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          5209:                cp = &sc->pciide_channels[channel];
        !          5210:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          5211:                        continue;
        !          5212:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          5213:                if (cp->hw_ok == 0)
        !          5214:                        continue;
        !          5215:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          5216:                    pciide_pci_intr);
        !          5217:                if (cp->hw_ok == 0) {
        !          5218:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          5219:                        continue;
        !          5220:                }
        !          5221:                sc->sc_wdcdev.set_modes(&cp->wdc_channel);
        !          5222:        }
        !          5223: }
        !          5224:
        !          5225: void
        !          5226: ns_scx200_setup_channel(struct channel_softc *chp)
        !          5227: {
        !          5228:        struct ata_drive_datas *drvp;
        !          5229:        int drive, mode;
        !          5230:        u_int32_t idedma_ctl;
        !          5231:        struct pciide_channel *cp = (struct pciide_channel*)chp;
        !          5232:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          5233:        int channel = chp->channel;
        !          5234:        int pioformat;
        !          5235:        pcireg_t piotim, dmatim;
        !          5236:
        !          5237:        /* Setup DMA if needed */
        !          5238:        pciide_channel_dma_setup(cp);
        !          5239:
        !          5240:        idedma_ctl = 0;
        !          5241:
        !          5242:        pioformat = (pci_conf_read(sc->sc_pc, sc->sc_tag,
        !          5243:            SCx200_TIM_DMA(0, 0)) >> SCx200_PIOFORMAT_SHIFT) & 0x01;
        !          5244:        WDCDEBUG_PRINT(("%s: pio format %d\n", __func__, pioformat),
        !          5245:            DEBUG_PROBE);
        !          5246:
        !          5247:        /* Per channel settings */
        !          5248:        for (drive = 0; drive < 2; drive++) {
        !          5249:                drvp = &chp->ch_drive[drive];
        !          5250:
        !          5251:                /* If no drive, skip */
        !          5252:                if ((drvp->drive_flags & DRIVE) == 0)
        !          5253:                        continue;
        !          5254:
        !          5255:                piotim = pci_conf_read(sc->sc_pc, sc->sc_tag,
        !          5256:                    SCx200_TIM_PIO(channel, drive));
        !          5257:                dmatim = pci_conf_read(sc->sc_pc, sc->sc_tag,
        !          5258:                    SCx200_TIM_DMA(channel, drive));
        !          5259:                WDCDEBUG_PRINT(("%s:%d:%d: piotim=0x%x, dmatim=0x%x\n",
        !          5260:                    sc->sc_wdcdev.sc_dev.dv_xname, channel, drive,
        !          5261:                    piotim, dmatim), DEBUG_PROBE);
        !          5262:
        !          5263:                if ((chp->wdc->cap & WDC_CAPABILITY_UDMA) != 0 &&
        !          5264:                    (drvp->drive_flags & DRIVE_UDMA) != 0) {
        !          5265:                        /* Setup UltraDMA mode */
        !          5266:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          5267:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          5268:                        dmatim = scx200_udma33[drvp->UDMA_mode];
        !          5269:                        mode = drvp->PIO_mode;
        !          5270:                } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA) != 0 &&
        !          5271:                    (drvp->drive_flags & DRIVE_DMA) != 0) {
        !          5272:                        /* Setup multiword DMA mode */
        !          5273:                        drvp->drive_flags &= ~DRIVE_UDMA;
        !          5274:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          5275:                        dmatim = scx200_dma33[drvp->DMA_mode];
        !          5276:
        !          5277:                        /* mode = min(pio, dma + 2) */
        !          5278:                        if (drvp->PIO_mode <= (drvp->DMA_mode + 2))
        !          5279:                                mode = drvp->PIO_mode;
        !          5280:                        else
        !          5281:                                mode = drvp->DMA_mode + 2;
        !          5282:                } else {
        !          5283:                        mode = drvp->PIO_mode;
        !          5284:                }
        !          5285:
        !          5286:                /* Setup PIO mode */
        !          5287:                drvp->PIO_mode = mode;
        !          5288:                if (mode < 2)
        !          5289:                        drvp->DMA_mode = 0;
        !          5290:                else
        !          5291:                        drvp->DMA_mode = mode - 2;
        !          5292:
        !          5293:                piotim = scx200_pio33[pioformat][drvp->PIO_mode];
        !          5294:
        !          5295:                WDCDEBUG_PRINT(("%s:%d:%d: new piotim=0x%x, dmatim=0x%x\n",
        !          5296:                    sc->sc_wdcdev.sc_dev.dv_xname, channel, drive,
        !          5297:                    piotim, dmatim), DEBUG_PROBE);
        !          5298:
        !          5299:                pci_conf_write(sc->sc_pc, sc->sc_tag,
        !          5300:                    SCx200_TIM_PIO(channel, drive), piotim);
        !          5301:                pci_conf_write(sc->sc_pc, sc->sc_tag,
        !          5302:                    SCx200_TIM_DMA(channel, drive), dmatim);
        !          5303:        }
        !          5304:
        !          5305:        if (idedma_ctl != 0) {
        !          5306:                /* Add software bits in status register */
        !          5307:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5308:                    IDEDMA_CTL(channel), idedma_ctl);
        !          5309:        }
        !          5310:
        !          5311:        pciide_print_modes(cp);
        !          5312: }
        !          5313:
        !          5314: void
        !          5315: acer_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          5316: {
        !          5317:        struct pciide_channel *cp;
        !          5318:        int channel;
        !          5319:        pcireg_t cr, interface;
        !          5320:        bus_size_t cmdsize, ctlsize;
        !          5321:        int rev = sc->sc_rev;
        !          5322:
        !          5323:        printf(": DMA");
        !          5324:        pciide_mapreg_dma(sc, pa);
        !          5325:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          5326:            WDC_CAPABILITY_MODE;
        !          5327:
        !          5328:        if (sc->sc_dma_ok) {
        !          5329:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA;
        !          5330:                if (rev >= 0x20) {
        !          5331:                        sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA;
        !          5332:                        if (rev >= 0xC4)
        !          5333:                                sc->sc_wdcdev.UDMA_cap = 5;
        !          5334:                        else if (rev >= 0xC2)
        !          5335:                                sc->sc_wdcdev.UDMA_cap = 4;
        !          5336:                        else
        !          5337:                                sc->sc_wdcdev.UDMA_cap = 2;
        !          5338:                }
        !          5339:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          5340:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          5341:        }
        !          5342:
        !          5343:        sc->sc_wdcdev.PIO_cap = 4;
        !          5344:        sc->sc_wdcdev.DMA_cap = 2;
        !          5345:        sc->sc_wdcdev.set_modes = acer_setup_channel;
        !          5346:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          5347:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          5348:
        !          5349:        pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_CDRC,
        !          5350:            (pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CDRC) |
        !          5351:                ACER_CDRC_DMA_EN) & ~ACER_CDRC_FIFO_DISABLE);
        !          5352:
        !          5353:        /* Enable "microsoft register bits" R/W. */
        !          5354:        pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_CCAR3,
        !          5355:            pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CCAR3) | ACER_CCAR3_PI);
        !          5356:        pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_CCAR1,
        !          5357:            pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CCAR1) &
        !          5358:            ~(ACER_CHANSTATUS_RO|PCIIDE_CHAN_RO(0)|PCIIDE_CHAN_RO(1)));
        !          5359:        pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_CCAR2,
        !          5360:            pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CCAR2) &
        !          5361:            ~ACER_CHANSTATUSREGS_RO);
        !          5362:        cr = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG);
        !          5363:        cr |= (PCIIDE_CHANSTATUS_EN << PCI_INTERFACE_SHIFT);
        !          5364:        pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG, cr);
        !          5365:        /* Don't use cr, re-read the real register content instead */
        !          5366:        interface = PCI_INTERFACE(pci_conf_read(sc->sc_pc, sc->sc_tag,
        !          5367:            PCI_CLASS_REG));
        !          5368:
        !          5369:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          5370:
        !          5371:        /* From linux: enable "Cable Detection" */
        !          5372:        if (rev >= 0xC2)
        !          5373:                pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_0x4B,
        !          5374:                    pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_0x4B)
        !          5375:                    | ACER_0x4B_CDETECT);
        !          5376:
        !          5377:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          5378:                cp = &sc->pciide_channels[channel];
        !          5379:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          5380:                        continue;
        !          5381:                if ((interface & PCIIDE_CHAN_EN(channel)) == 0) {
        !          5382:                        printf("%s: %s ignored (disabled)\n",
        !          5383:                            sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          5384:                        continue;
        !          5385:                }
        !          5386:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          5387:                if (cp->hw_ok == 0)
        !          5388:                        continue;
        !          5389:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          5390:                    (rev >= 0xC2) ? pciide_pci_intr : acer_pci_intr);
        !          5391:                if (cp->hw_ok == 0) {
        !          5392:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          5393:                        continue;
        !          5394:                }
        !          5395:                if (pciide_chan_candisable(cp)) {
        !          5396:                        cr &= ~(PCIIDE_CHAN_EN(channel) << PCI_INTERFACE_SHIFT);
        !          5397:                        pci_conf_write(sc->sc_pc, sc->sc_tag,
        !          5398:                            PCI_CLASS_REG, cr);
        !          5399:                }
        !          5400:                if (cp->hw_ok == 0) {
        !          5401:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          5402:                        continue;
        !          5403:                }
        !          5404:                acer_setup_channel(&cp->wdc_channel);
        !          5405:        }
        !          5406: }
        !          5407:
        !          5408: void
        !          5409: acer_setup_channel(struct channel_softc *chp)
        !          5410: {
        !          5411:        struct ata_drive_datas *drvp;
        !          5412:        int drive;
        !          5413:        u_int32_t acer_fifo_udma;
        !          5414:        u_int32_t idedma_ctl;
        !          5415:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          5416:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          5417:
        !          5418:        idedma_ctl = 0;
        !          5419:        acer_fifo_udma = pci_conf_read(sc->sc_pc, sc->sc_tag, ACER_FTH_UDMA);
        !          5420:        WDCDEBUG_PRINT(("acer_setup_channel: old fifo/udma reg 0x%x\n",
        !          5421:            acer_fifo_udma), DEBUG_PROBE);
        !          5422:        /* setup DMA if needed */
        !          5423:        pciide_channel_dma_setup(cp);
        !          5424:
        !          5425:        if ((chp->ch_drive[0].drive_flags | chp->ch_drive[1].drive_flags) &
        !          5426:            DRIVE_UDMA) {       /* check 80 pins cable */
        !          5427:                if (pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_0x4A) &
        !          5428:                    ACER_0x4A_80PIN(chp->channel)) {
        !          5429:                        WDCDEBUG_PRINT(("%s:%d: 80-wire cable not detected\n",
        !          5430:                            sc->sc_wdcdev.sc_dev.dv_xname, chp->channel),
        !          5431:                            DEBUG_PROBE);
        !          5432:                        if (chp->ch_drive[0].UDMA_mode > 2)
        !          5433:                                chp->ch_drive[0].UDMA_mode = 2;
        !          5434:                        if (chp->ch_drive[1].UDMA_mode > 2)
        !          5435:                                chp->ch_drive[1].UDMA_mode = 2;
        !          5436:                }
        !          5437:        }
        !          5438:
        !          5439:        for (drive = 0; drive < 2; drive++) {
        !          5440:                drvp = &chp->ch_drive[drive];
        !          5441:                /* If no drive, skip */
        !          5442:                if ((drvp->drive_flags & DRIVE) == 0)
        !          5443:                        continue;
        !          5444:                WDCDEBUG_PRINT(("acer_setup_channel: old timings reg for "
        !          5445:                    "channel %d drive %d 0x%x\n", chp->channel, drive,
        !          5446:                    pciide_pci_read(sc->sc_pc, sc->sc_tag,
        !          5447:                    ACER_IDETIM(chp->channel, drive))), DEBUG_PROBE);
        !          5448:                /* clear FIFO/DMA mode */
        !          5449:                acer_fifo_udma &= ~(ACER_FTH_OPL(chp->channel, drive, 0x3) |
        !          5450:                    ACER_UDMA_EN(chp->channel, drive) |
        !          5451:                    ACER_UDMA_TIM(chp->channel, drive, 0x7));
        !          5452:
        !          5453:                /* add timing values, setup DMA if needed */
        !          5454:                if ((drvp->drive_flags & DRIVE_DMA) == 0 &&
        !          5455:                    (drvp->drive_flags & DRIVE_UDMA) == 0) {
        !          5456:                        acer_fifo_udma |=
        !          5457:                            ACER_FTH_OPL(chp->channel, drive, 0x1);
        !          5458:                        goto pio;
        !          5459:                }
        !          5460:
        !          5461:                acer_fifo_udma |= ACER_FTH_OPL(chp->channel, drive, 0x2);
        !          5462:                if (drvp->drive_flags & DRIVE_UDMA) {
        !          5463:                        /* use Ultra/DMA */
        !          5464:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          5465:                        acer_fifo_udma |= ACER_UDMA_EN(chp->channel, drive);
        !          5466:                        acer_fifo_udma |=
        !          5467:                            ACER_UDMA_TIM(chp->channel, drive,
        !          5468:                                acer_udma[drvp->UDMA_mode]);
        !          5469:                        /* XXX disable if one drive < UDMA3 ? */
        !          5470:                        if (drvp->UDMA_mode >= 3) {
        !          5471:                                pciide_pci_write(sc->sc_pc, sc->sc_tag,
        !          5472:                                    ACER_0x4B,
        !          5473:                                    pciide_pci_read(sc->sc_pc, sc->sc_tag,
        !          5474:                                    ACER_0x4B) | ACER_0x4B_UDMA66);
        !          5475:                        }
        !          5476:                } else {
        !          5477:                        /*
        !          5478:                         * use Multiword DMA
        !          5479:                         * Timings will be used for both PIO and DMA,
        !          5480:                         * so adjust DMA mode if needed
        !          5481:                         */
        !          5482:                        if (drvp->PIO_mode > (drvp->DMA_mode + 2))
        !          5483:                                drvp->PIO_mode = drvp->DMA_mode + 2;
        !          5484:                        if (drvp->DMA_mode + 2 > (drvp->PIO_mode))
        !          5485:                                drvp->DMA_mode = (drvp->PIO_mode > 2) ?
        !          5486:                                    drvp->PIO_mode - 2 : 0;
        !          5487:                        if (drvp->DMA_mode == 0)
        !          5488:                                drvp->PIO_mode = 0;
        !          5489:                }
        !          5490:                idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          5491: pio:           pciide_pci_write(sc->sc_pc, sc->sc_tag,
        !          5492:                    ACER_IDETIM(chp->channel, drive),
        !          5493:                    acer_pio[drvp->PIO_mode]);
        !          5494:        }
        !          5495:        WDCDEBUG_PRINT(("acer_setup_channel: new fifo/udma reg 0x%x\n",
        !          5496:            acer_fifo_udma), DEBUG_PROBE);
        !          5497:        pci_conf_write(sc->sc_pc, sc->sc_tag, ACER_FTH_UDMA, acer_fifo_udma);
        !          5498:        if (idedma_ctl != 0) {
        !          5499:                /* Add software bits in status register */
        !          5500:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5501:                    IDEDMA_CTL(chp->channel), idedma_ctl);
        !          5502:        }
        !          5503:        pciide_print_modes(cp);
        !          5504: }
        !          5505:
        !          5506: int
        !          5507: acer_pci_intr(void *arg)
        !          5508: {
        !          5509:        struct pciide_softc *sc = arg;
        !          5510:        struct pciide_channel *cp;
        !          5511:        struct channel_softc *wdc_cp;
        !          5512:        int i, rv, crv;
        !          5513:        u_int32_t chids;
        !          5514:
        !          5515:        rv = 0;
        !          5516:        chids = pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CHIDS);
        !          5517:        for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {
        !          5518:                cp = &sc->pciide_channels[i];
        !          5519:                wdc_cp = &cp->wdc_channel;
        !          5520:                /* If a compat channel skip. */
        !          5521:                if (cp->compat)
        !          5522:                        continue;
        !          5523:                if (chids & ACER_CHIDS_INT(i)) {
        !          5524:                        crv = wdcintr(wdc_cp);
        !          5525:                        if (crv == 0)
        !          5526:                                printf("%s:%d: bogus intr\n",
        !          5527:                                    sc->sc_wdcdev.sc_dev.dv_xname, i);
        !          5528:                        else
        !          5529:                                rv = 1;
        !          5530:                }
        !          5531:        }
        !          5532:        return (rv);
        !          5533: }
        !          5534:
        !          5535: void
        !          5536: hpt_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          5537: {
        !          5538:        struct pciide_channel *cp;
        !          5539:        int i, compatchan, revision;
        !          5540:        pcireg_t interface;
        !          5541:        bus_size_t cmdsize, ctlsize;
        !          5542:
        !          5543:        revision = sc->sc_rev;
        !          5544:
        !          5545:        /*
        !          5546:         * when the chip is in native mode it identifies itself as a
        !          5547:         * 'misc mass storage'. Fake interface in this case.
        !          5548:         */
        !          5549:        if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_IDE) {
        !          5550:                interface = PCI_INTERFACE(pa->pa_class);
        !          5551:        } else {
        !          5552:                interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
        !          5553:                    PCIIDE_INTERFACE_PCI(0);
        !          5554:                if ((sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366 &&
        !          5555:                   (revision == HPT370_REV || revision == HPT370A_REV ||
        !          5556:                    revision == HPT372_REV)) ||
        !          5557:                    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT372A ||
        !          5558:                    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT302 ||
        !          5559:                    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT371 ||
        !          5560:                    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374)
        !          5561:                        interface |= PCIIDE_INTERFACE_PCI(1);
        !          5562:        }
        !          5563:
        !          5564:        printf(": DMA");
        !          5565:        pciide_mapreg_dma(sc, pa);
        !          5566:        printf("\n");
        !          5567:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          5568:            WDC_CAPABILITY_MODE;
        !          5569:        if (sc->sc_dma_ok) {
        !          5570:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
        !          5571:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          5572:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          5573:        }
        !          5574:        sc->sc_wdcdev.PIO_cap = 4;
        !          5575:        sc->sc_wdcdev.DMA_cap = 2;
        !          5576:
        !          5577:        sc->sc_wdcdev.set_modes = hpt_setup_channel;
        !          5578:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          5579:        if (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366 &&
        !          5580:            revision == HPT366_REV) {
        !          5581:                sc->sc_wdcdev.UDMA_cap = 4;
        !          5582:                /*
        !          5583:                 * The 366 has 2 PCI IDE functions, one for primary and one
        !          5584:                 * for secondary. So we need to call pciide_mapregs_compat()
        !          5585:                 * with the real channel
        !          5586:                 */
        !          5587:                if (pa->pa_function == 0) {
        !          5588:                        compatchan = 0;
        !          5589:                } else if (pa->pa_function == 1) {
        !          5590:                        compatchan = 1;
        !          5591:                } else {
        !          5592:                        printf("%s: unexpected PCI function %d\n",
        !          5593:                            sc->sc_wdcdev.sc_dev.dv_xname, pa->pa_function);
        !          5594:                        return;
        !          5595:                }
        !          5596:                sc->sc_wdcdev.nchannels = 1;
        !          5597:        } else {
        !          5598:                sc->sc_wdcdev.nchannels = 2;
        !          5599:                if (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT372A ||
        !          5600:                    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT302 ||
        !          5601:                    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT371 ||
        !          5602:                    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374)
        !          5603:                        sc->sc_wdcdev.UDMA_cap = 6;
        !          5604:                else if (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366) {
        !          5605:                        if (revision == HPT372_REV)
        !          5606:                                sc->sc_wdcdev.UDMA_cap = 6;
        !          5607:                        else
        !          5608:                                sc->sc_wdcdev.UDMA_cap = 5;
        !          5609:                }
        !          5610:        }
        !          5611:        for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {
        !          5612:                cp = &sc->pciide_channels[i];
        !          5613:                if (sc->sc_wdcdev.nchannels > 1) {
        !          5614:                        compatchan = i;
        !          5615:                        if((pciide_pci_read(sc->sc_pc, sc->sc_tag,
        !          5616:                            HPT370_CTRL1(i)) & HPT370_CTRL1_EN) == 0) {
        !          5617:                                printf("%s: %s ignored (disabled)\n",
        !          5618:                                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          5619:                                continue;
        !          5620:                        }
        !          5621:                }
        !          5622:                if (pciide_chansetup(sc, i, interface) == 0)
        !          5623:                        continue;
        !          5624:                if (interface & PCIIDE_INTERFACE_PCI(i)) {
        !          5625:                        cp->hw_ok = pciide_mapregs_native(pa, cp, &cmdsize,
        !          5626:                            &ctlsize, hpt_pci_intr);
        !          5627:                } else {
        !          5628:                        cp->hw_ok = pciide_mapregs_compat(pa, cp, compatchan,
        !          5629:                            &cmdsize, &ctlsize);
        !          5630:                }
        !          5631:                if (cp->hw_ok == 0)
        !          5632:                        return;
        !          5633:                cp->wdc_channel.data32iot = cp->wdc_channel.cmd_iot;
        !          5634:                cp->wdc_channel.data32ioh = cp->wdc_channel.cmd_ioh;
        !          5635:                wdcattach(&cp->wdc_channel);
        !          5636:                hpt_setup_channel(&cp->wdc_channel);
        !          5637:        }
        !          5638:        if ((sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366 &&
        !          5639:            (revision == HPT370_REV || revision == HPT370A_REV ||
        !          5640:            revision == HPT372_REV)) ||
        !          5641:            sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT372A ||
        !          5642:            sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT302 ||
        !          5643:            sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT371 ||
        !          5644:            sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374) {
        !          5645:                /*
        !          5646:                 * Turn off fast interrupts
        !          5647:                 */
        !          5648:                pciide_pci_write(sc->sc_pc, sc->sc_tag, HPT370_CTRL2(0),
        !          5649:                    pciide_pci_read(sc->sc_pc, sc->sc_tag, HPT370_CTRL2(0)) &
        !          5650:                    ~(HPT370_CTRL2_FASTIRQ | HPT370_CTRL2_HIRQ));
        !          5651:                pciide_pci_write(sc->sc_pc, sc->sc_tag, HPT370_CTRL2(1),
        !          5652:                pciide_pci_read(sc->sc_pc, sc->sc_tag, HPT370_CTRL2(1)) &
        !          5653:                ~(HPT370_CTRL2_FASTIRQ | HPT370_CTRL2_HIRQ));
        !          5654:
        !          5655:                /*
        !          5656:                 * HPT370 and highter has a bit to disable interrupts,
        !          5657:                 * make sure to clear it
        !          5658:                 */
        !          5659:                pciide_pci_write(sc->sc_pc, sc->sc_tag, HPT_CSEL,
        !          5660:                    pciide_pci_read(sc->sc_pc, sc->sc_tag, HPT_CSEL) &
        !          5661:                    ~HPT_CSEL_IRQDIS);
        !          5662:        }
        !          5663:        /* set clocks, etc (mandatory on 372/4, optional otherwise) */
        !          5664:        if (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT372A ||
        !          5665:            sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT302 ||
        !          5666:            sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT371 ||
        !          5667:            sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374 ||
        !          5668:            (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366 &&
        !          5669:            revision == HPT372_REV))
        !          5670:                pciide_pci_write(sc->sc_pc, sc->sc_tag, HPT_SC2,
        !          5671:                    (pciide_pci_read(sc->sc_pc, sc->sc_tag, HPT_SC2) &
        !          5672:                     HPT_SC2_MAEN) | HPT_SC2_OSC_EN);
        !          5673:
        !          5674:        return;
        !          5675: }
        !          5676:
        !          5677: void
        !          5678: hpt_setup_channel(struct channel_softc *chp)
        !          5679: {
        !          5680:        struct ata_drive_datas *drvp;
        !          5681:        int drive;
        !          5682:        int cable;
        !          5683:        u_int32_t before, after;
        !          5684:        u_int32_t idedma_ctl;
        !          5685:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          5686:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          5687:        int revision = sc->sc_rev;
        !          5688:        u_int32_t *tim_pio, *tim_dma, *tim_udma;
        !          5689:
        !          5690:        cable = pciide_pci_read(sc->sc_pc, sc->sc_tag, HPT_CSEL);
        !          5691:
        !          5692:        /* setup DMA if needed */
        !          5693:        pciide_channel_dma_setup(cp);
        !          5694:
        !          5695:        idedma_ctl = 0;
        !          5696:
        !          5697:        switch (sc->sc_pp->ide_product) {
        !          5698:        case PCI_PRODUCT_TRIONES_HPT366:
        !          5699:                if (revision == HPT370_REV ||
        !          5700:                    revision == HPT370A_REV) {
        !          5701:                        tim_pio = hpt370_pio;
        !          5702:                        tim_dma = hpt370_dma;
        !          5703:                        tim_udma = hpt370_udma;
        !          5704:                } else if (revision == HPT372_REV) {
        !          5705:                        tim_pio = hpt372_pio;
        !          5706:                        tim_dma = hpt372_dma;
        !          5707:                        tim_udma = hpt372_udma;
        !          5708:                } else {
        !          5709:                        tim_pio = hpt366_pio;
        !          5710:                        tim_dma = hpt366_dma;
        !          5711:                        tim_udma = hpt366_udma;
        !          5712:                }
        !          5713:                break;
        !          5714:        case PCI_PRODUCT_TRIONES_HPT372A:
        !          5715:        case PCI_PRODUCT_TRIONES_HPT302:
        !          5716:        case PCI_PRODUCT_TRIONES_HPT371:
        !          5717:                tim_pio = hpt372_pio;
        !          5718:                tim_dma = hpt372_dma;
        !          5719:                tim_udma = hpt372_udma;
        !          5720:                break;
        !          5721:        case PCI_PRODUCT_TRIONES_HPT374:
        !          5722:                tim_pio = hpt374_pio;
        !          5723:                tim_dma = hpt374_dma;
        !          5724:                tim_udma = hpt374_udma;
        !          5725:                break;
        !          5726:        default:
        !          5727:                printf("%s: no known timing values\n",
        !          5728:                    sc->sc_wdcdev.sc_dev.dv_xname);
        !          5729:                goto end;
        !          5730:        }
        !          5731:
        !          5732:        /* Per drive settings */
        !          5733:        for (drive = 0; drive < 2; drive++) {
        !          5734:                drvp = &chp->ch_drive[drive];
        !          5735:                /* If no drive, skip */
        !          5736:                if ((drvp->drive_flags & DRIVE) == 0)
        !          5737:                        continue;
        !          5738:                before = pci_conf_read(sc->sc_pc, sc->sc_tag,
        !          5739:                                       HPT_IDETIM(chp->channel, drive));
        !          5740:
        !          5741:                /* add timing values, setup DMA if needed */
        !          5742:                if (drvp->drive_flags & DRIVE_UDMA) {
        !          5743:                        /* use Ultra/DMA */
        !          5744:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          5745:                        if ((cable & HPT_CSEL_CBLID(chp->channel)) != 0 &&
        !          5746:                            drvp->UDMA_mode > 2) {
        !          5747:                                WDCDEBUG_PRINT(("%s(%s:%d:%d): 80-wire "
        !          5748:                                    "cable not detected\n", drvp->drive_name,
        !          5749:                                    sc->sc_wdcdev.sc_dev.dv_xname,
        !          5750:                                    chp->channel, drive), DEBUG_PROBE);
        !          5751:                                drvp->UDMA_mode = 2;
        !          5752:                        }
        !          5753:                        after = tim_udma[drvp->UDMA_mode];
        !          5754:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          5755:                } else if (drvp->drive_flags & DRIVE_DMA) {
        !          5756:                        /*
        !          5757:                         * use Multiword DMA.
        !          5758:                         * Timings will be used for both PIO and DMA, so adjust
        !          5759:                         * DMA mode if needed
        !          5760:                         */
        !          5761:                        if (drvp->PIO_mode >= 3 &&
        !          5762:                            (drvp->DMA_mode + 2) > drvp->PIO_mode) {
        !          5763:                                drvp->DMA_mode = drvp->PIO_mode - 2;
        !          5764:                        }
        !          5765:                        after = tim_dma[drvp->DMA_mode];
        !          5766:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          5767:                } else {
        !          5768:                        /* PIO only */
        !          5769:                        after = tim_pio[drvp->PIO_mode];
        !          5770:                }
        !          5771:                pci_conf_write(sc->sc_pc, sc->sc_tag,
        !          5772:                    HPT_IDETIM(chp->channel, drive), after);
        !          5773:                WDCDEBUG_PRINT(("%s: bus speed register set to 0x%08x "
        !          5774:                    "(BIOS 0x%08x)\n", sc->sc_wdcdev.sc_dev.dv_xname,
        !          5775:                    after, before), DEBUG_PROBE);
        !          5776:        }
        !          5777: end:
        !          5778:        if (idedma_ctl != 0) {
        !          5779:                /* Add software bits in status register */
        !          5780:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5781:                    IDEDMA_CTL(chp->channel), idedma_ctl);
        !          5782:        }
        !          5783:        pciide_print_modes(cp);
        !          5784: }
        !          5785:
        !          5786: int
        !          5787: hpt_pci_intr(void *arg)
        !          5788: {
        !          5789:        struct pciide_softc *sc = arg;
        !          5790:        struct pciide_channel *cp;
        !          5791:        struct channel_softc *wdc_cp;
        !          5792:        int rv = 0;
        !          5793:        int dmastat, i, crv;
        !          5794:
        !          5795:        for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {
        !          5796:                dmastat = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5797:                    IDEDMA_CTL(i));
        !          5798:                if((dmastat & (IDEDMA_CTL_ACT | IDEDMA_CTL_INTR)) !=
        !          5799:                    IDEDMA_CTL_INTR)
        !          5800:                    continue;
        !          5801:                cp = &sc->pciide_channels[i];
        !          5802:                wdc_cp = &cp->wdc_channel;
        !          5803:                crv = wdcintr(wdc_cp);
        !          5804:                if (crv == 0) {
        !          5805:                        printf("%s:%d: bogus intr\n",
        !          5806:                            sc->sc_wdcdev.sc_dev.dv_xname, i);
        !          5807:                        bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5808:                            IDEDMA_CTL(i), dmastat);
        !          5809:                } else
        !          5810:                        rv = 1;
        !          5811:        }
        !          5812:        return (rv);
        !          5813: }
        !          5814:
        !          5815: /* Macros to test product */
        !          5816: #define PDC_IS_262(sc)                                                 \
        !          5817:        ((sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20262 ||    \
        !          5818:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20265  ||    \
        !          5819:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20267)
        !          5820: #define PDC_IS_265(sc)                                                 \
        !          5821:        ((sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20265 ||    \
        !          5822:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20267  ||    \
        !          5823:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20268  ||    \
        !          5824:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20268R ||    \
        !          5825:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20269  ||    \
        !          5826:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20271  ||    \
        !          5827:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20275  ||    \
        !          5828:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20276  ||    \
        !          5829:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20277)
        !          5830: #define PDC_IS_268(sc)                                                 \
        !          5831:        ((sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20268 ||    \
        !          5832:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20268R ||    \
        !          5833:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20269  ||    \
        !          5834:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20271  ||    \
        !          5835:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20275  ||    \
        !          5836:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20276  ||    \
        !          5837:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20277)
        !          5838: #define PDC_IS_269(sc)                                                 \
        !          5839:        ((sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20269 ||    \
        !          5840:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20271  ||    \
        !          5841:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20275  ||    \
        !          5842:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20276  ||    \
        !          5843:        (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20277)
        !          5844:
        !          5845: static INLINE u_int8_t
        !          5846: pdc268_config_read(struct channel_softc *chp, int index)
        !          5847: {
        !          5848:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          5849:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          5850:        int channel = chp->channel;
        !          5851:
        !          5852:        bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5853:            PDC268_INDEX(channel), index);
        !          5854:        return (bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5855:            PDC268_DATA(channel)));
        !          5856: }
        !          5857:
        !          5858: /* unused */
        !          5859: static __inline void
        !          5860: pdc268_config_write(struct channel_softc *chp, int index, u_int8_t value)
        !          5861: {
        !          5862:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          5863:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          5864:        int channel = chp->channel;
        !          5865:
        !          5866:        bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5867:            PDC268_INDEX(channel), index);
        !          5868:        bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5869:            PDC268_DATA(channel), value);
        !          5870: }
        !          5871:
        !          5872: void
        !          5873: pdc202xx_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          5874: {
        !          5875:        struct pciide_channel *cp;
        !          5876:        int channel;
        !          5877:        pcireg_t interface, st, mode;
        !          5878:        bus_size_t cmdsize, ctlsize;
        !          5879:
        !          5880:        if (!PDC_IS_268(sc)) {
        !          5881:                st = pci_conf_read(sc->sc_pc, sc->sc_tag, PDC2xx_STATE);
        !          5882:                WDCDEBUG_PRINT(("pdc202xx_setup_chip: controller state 0x%x\n",
        !          5883:                    st), DEBUG_PROBE);
        !          5884:        }
        !          5885:
        !          5886:        /* turn off  RAID mode */
        !          5887:        if (!PDC_IS_268(sc))
        !          5888:                st &= ~PDC2xx_STATE_IDERAID;
        !          5889:
        !          5890:        /*
        !          5891:         * can't rely on the PCI_CLASS_REG content if the chip was in raid
        !          5892:         * mode. We have to fake interface
        !          5893:         */
        !          5894:        interface = PCIIDE_INTERFACE_SETTABLE(0) | PCIIDE_INTERFACE_SETTABLE(1);
        !          5895:        if (PDC_IS_268(sc) || (st & PDC2xx_STATE_NATIVE))
        !          5896:                interface |= PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
        !          5897:
        !          5898:        printf(": DMA");
        !          5899:        pciide_mapreg_dma(sc, pa);
        !          5900:
        !          5901:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          5902:            WDC_CAPABILITY_MODE;
        !          5903:        if (sc->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20246 ||
        !          5904:            PDC_IS_262(sc))
        !          5905:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_NO_ATAPI_DMA;
        !          5906:        if (sc->sc_dma_ok) {
        !          5907:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
        !          5908:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          5909:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          5910:        }
        !          5911:        sc->sc_wdcdev.PIO_cap = 4;
        !          5912:        sc->sc_wdcdev.DMA_cap = 2;
        !          5913:        if (PDC_IS_269(sc))
        !          5914:                sc->sc_wdcdev.UDMA_cap = 6;
        !          5915:        else if (PDC_IS_265(sc))
        !          5916:                sc->sc_wdcdev.UDMA_cap = 5;
        !          5917:        else if (PDC_IS_262(sc))
        !          5918:                sc->sc_wdcdev.UDMA_cap = 4;
        !          5919:        else
        !          5920:                sc->sc_wdcdev.UDMA_cap = 2;
        !          5921:        sc->sc_wdcdev.set_modes = PDC_IS_268(sc) ?
        !          5922:            pdc20268_setup_channel : pdc202xx_setup_channel;
        !          5923:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          5924:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          5925:
        !          5926:        if (PDC_IS_262(sc)) {
        !          5927:                sc->sc_wdcdev.dma_start = pdc20262_dma_start;
        !          5928:                sc->sc_wdcdev.dma_finish = pdc20262_dma_finish;
        !          5929:        }
        !          5930:
        !          5931:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          5932:        if (!PDC_IS_268(sc)) {
        !          5933:                /* setup failsafe defaults */
        !          5934:                mode = 0;
        !          5935:                mode = PDC2xx_TIM_SET_PA(mode, pdc2xx_pa[0]);
        !          5936:                mode = PDC2xx_TIM_SET_PB(mode, pdc2xx_pb[0]);
        !          5937:                mode = PDC2xx_TIM_SET_MB(mode, pdc2xx_dma_mb[0]);
        !          5938:                mode = PDC2xx_TIM_SET_MC(mode, pdc2xx_dma_mc[0]);
        !          5939:                for (channel = 0;
        !          5940:                     channel < sc->sc_wdcdev.nchannels;
        !          5941:                     channel++) {
        !          5942:                        WDCDEBUG_PRINT(("pdc202xx_setup_chip: channel %d "
        !          5943:                            "drive 0 initial timings  0x%x, now 0x%x\n",
        !          5944:                            channel, pci_conf_read(sc->sc_pc, sc->sc_tag,
        !          5945:                            PDC2xx_TIM(channel, 0)), mode | PDC2xx_TIM_IORDYp),
        !          5946:                            DEBUG_PROBE);
        !          5947:                        pci_conf_write(sc->sc_pc, sc->sc_tag,
        !          5948:                            PDC2xx_TIM(channel, 0), mode | PDC2xx_TIM_IORDYp);
        !          5949:                        WDCDEBUG_PRINT(("pdc202xx_setup_chip: channel %d "
        !          5950:                            "drive 1 initial timings  0x%x, now 0x%x\n",
        !          5951:                            channel, pci_conf_read(sc->sc_pc, sc->sc_tag,
        !          5952:                            PDC2xx_TIM(channel, 1)), mode), DEBUG_PROBE);
        !          5953:                        pci_conf_write(sc->sc_pc, sc->sc_tag,
        !          5954:                            PDC2xx_TIM(channel, 1), mode);
        !          5955:                }
        !          5956:
        !          5957:                mode = PDC2xx_SCR_DMA;
        !          5958:                if (PDC_IS_262(sc)) {
        !          5959:                        mode = PDC2xx_SCR_SET_GEN(mode, PDC262_SCR_GEN_LAT);
        !          5960:                } else {
        !          5961:                        /* the BIOS set it up this way */
        !          5962:                        mode = PDC2xx_SCR_SET_GEN(mode, 0x1);
        !          5963:                }
        !          5964:                mode = PDC2xx_SCR_SET_I2C(mode, 0x3); /* ditto */
        !          5965:                mode = PDC2xx_SCR_SET_POLL(mode, 0x1); /* ditto */
        !          5966:                WDCDEBUG_PRINT(("pdc202xx_setup_chip: initial SCR  0x%x, "
        !          5967:                    "now 0x%x\n",
        !          5968:                    bus_space_read_4(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5969:                        PDC2xx_SCR),
        !          5970:                    mode), DEBUG_PROBE);
        !          5971:                bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          5972:                    PDC2xx_SCR, mode);
        !          5973:
        !          5974:                /* controller initial state register is OK even without BIOS */
        !          5975:                /* Set DMA mode to IDE DMA compatibility */
        !          5976:                mode =
        !          5977:                    bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_PM);
        !          5978:                WDCDEBUG_PRINT(("pdc202xx_setup_chip: primary mode 0x%x", mode),
        !          5979:                    DEBUG_PROBE);
        !          5980:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_PM,
        !          5981:                    mode | 0x1);
        !          5982:                mode =
        !          5983:                    bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_SM);
        !          5984:                WDCDEBUG_PRINT((", secondary mode 0x%x\n", mode ), DEBUG_PROBE);
        !          5985:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_SM,
        !          5986:                    mode | 0x1);
        !          5987:        }
        !          5988:
        !          5989:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          5990:                cp = &sc->pciide_channels[channel];
        !          5991:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          5992:                        continue;
        !          5993:                if (!PDC_IS_268(sc) && (st & (PDC_IS_262(sc) ?
        !          5994:                    PDC262_STATE_EN(channel):PDC246_STATE_EN(channel))) == 0) {
        !          5995:                        printf("%s: %s ignored (disabled)\n",
        !          5996:                            sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          5997:                        continue;
        !          5998:                }
        !          5999:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          6000:                if (cp->hw_ok == 0)
        !          6001:                        continue;
        !          6002:                if (PDC_IS_265(sc))
        !          6003:                        pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          6004:                            pdc20265_pci_intr);
        !          6005:                else
        !          6006:                        pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          6007:                            pdc202xx_pci_intr);
        !          6008:                if (cp->hw_ok == 0) {
        !          6009:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          6010:                        continue;
        !          6011:                }
        !          6012:                if (!PDC_IS_268(sc) && pciide_chan_candisable(cp)) {
        !          6013:                        st &= ~(PDC_IS_262(sc) ?
        !          6014:                            PDC262_STATE_EN(channel):PDC246_STATE_EN(channel));
        !          6015:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          6016:                }
        !          6017:                if (PDC_IS_268(sc))
        !          6018:                        pdc20268_setup_channel(&cp->wdc_channel);
        !          6019:                else
        !          6020:                        pdc202xx_setup_channel(&cp->wdc_channel);
        !          6021:        }
        !          6022:        if (!PDC_IS_268(sc)) {
        !          6023:                WDCDEBUG_PRINT(("pdc202xx_setup_chip: new controller state "
        !          6024:                    "0x%x\n", st), DEBUG_PROBE);
        !          6025:                pci_conf_write(sc->sc_pc, sc->sc_tag, PDC2xx_STATE, st);
        !          6026:        }
        !          6027:        return;
        !          6028: }
        !          6029:
        !          6030: void
        !          6031: pdc202xx_setup_channel(struct channel_softc *chp)
        !          6032: {
        !          6033:        struct ata_drive_datas *drvp;
        !          6034:        int drive;
        !          6035:        pcireg_t mode, st;
        !          6036:        u_int32_t idedma_ctl, scr, atapi;
        !          6037:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          6038:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          6039:        int channel = chp->channel;
        !          6040:
        !          6041:        /* setup DMA if needed */
        !          6042:        pciide_channel_dma_setup(cp);
        !          6043:
        !          6044:        idedma_ctl = 0;
        !          6045:        WDCDEBUG_PRINT(("pdc202xx_setup_channel %s: scr 0x%x\n",
        !          6046:            sc->sc_wdcdev.sc_dev.dv_xname,
        !          6047:            bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC262_U66)),
        !          6048:            DEBUG_PROBE);
        !          6049:
        !          6050:        /* Per channel settings */
        !          6051:        if (PDC_IS_262(sc)) {
        !          6052:                scr = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          6053:                    PDC262_U66);
        !          6054:                st = pci_conf_read(sc->sc_pc, sc->sc_tag, PDC2xx_STATE);
        !          6055:                /* Check cable */
        !          6056:                if ((st & PDC262_STATE_80P(channel)) != 0 &&
        !          6057:                    ((chp->ch_drive[0].drive_flags & DRIVE_UDMA &&
        !          6058:                    chp->ch_drive[0].UDMA_mode > 2) ||
        !          6059:                    (chp->ch_drive[1].drive_flags & DRIVE_UDMA &&
        !          6060:                    chp->ch_drive[1].UDMA_mode > 2))) {
        !          6061:                        WDCDEBUG_PRINT(("%s:%d: 80-wire cable not detected\n",
        !          6062:                            sc->sc_wdcdev.sc_dev.dv_xname, channel),
        !          6063:                            DEBUG_PROBE);
        !          6064:                        if (chp->ch_drive[0].UDMA_mode > 2)
        !          6065:                                chp->ch_drive[0].UDMA_mode = 2;
        !          6066:                        if (chp->ch_drive[1].UDMA_mode > 2)
        !          6067:                                chp->ch_drive[1].UDMA_mode = 2;
        !          6068:                }
        !          6069:                /* Trim UDMA mode */
        !          6070:                if ((chp->ch_drive[0].drive_flags & DRIVE_UDMA &&
        !          6071:                    chp->ch_drive[0].UDMA_mode <= 2) ||
        !          6072:                    (chp->ch_drive[1].drive_flags & DRIVE_UDMA &&
        !          6073:                    chp->ch_drive[1].UDMA_mode <= 2)) {
        !          6074:                        if (chp->ch_drive[0].UDMA_mode > 2)
        !          6075:                                chp->ch_drive[0].UDMA_mode = 2;
        !          6076:                        if (chp->ch_drive[1].UDMA_mode > 2)
        !          6077:                                chp->ch_drive[1].UDMA_mode = 2;
        !          6078:                }
        !          6079:                /* Set U66 if needed */
        !          6080:                if ((chp->ch_drive[0].drive_flags & DRIVE_UDMA &&
        !          6081:                    chp->ch_drive[0].UDMA_mode > 2) ||
        !          6082:                    (chp->ch_drive[1].drive_flags & DRIVE_UDMA &&
        !          6083:                    chp->ch_drive[1].UDMA_mode > 2))
        !          6084:                        scr |= PDC262_U66_EN(channel);
        !          6085:                else
        !          6086:                        scr &= ~PDC262_U66_EN(channel);
        !          6087:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          6088:                    PDC262_U66, scr);
        !          6089:                WDCDEBUG_PRINT(("pdc202xx_setup_channel %s:%d: ATAPI 0x%x\n",
        !          6090:                    sc->sc_wdcdev.sc_dev.dv_xname, channel,
        !          6091:                    bus_space_read_4(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          6092:                    PDC262_ATAPI(channel))), DEBUG_PROBE);
        !          6093:                if (chp->ch_drive[0].drive_flags & DRIVE_ATAPI ||
        !          6094:                    chp->ch_drive[1].drive_flags & DRIVE_ATAPI) {
        !          6095:                        if (((chp->ch_drive[0].drive_flags & DRIVE_UDMA) &&
        !          6096:                            !(chp->ch_drive[1].drive_flags & DRIVE_UDMA) &&
        !          6097:                            (chp->ch_drive[1].drive_flags & DRIVE_DMA)) ||
        !          6098:                            ((chp->ch_drive[1].drive_flags & DRIVE_UDMA) &&
        !          6099:                            !(chp->ch_drive[0].drive_flags & DRIVE_UDMA) &&
        !          6100:                            (chp->ch_drive[0].drive_flags & DRIVE_DMA)))
        !          6101:                                atapi = 0;
        !          6102:                        else
        !          6103:                                atapi = PDC262_ATAPI_UDMA;
        !          6104:                        bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          6105:                            PDC262_ATAPI(channel), atapi);
        !          6106:                }
        !          6107:        }
        !          6108:        for (drive = 0; drive < 2; drive++) {
        !          6109:                drvp = &chp->ch_drive[drive];
        !          6110:                /* If no drive, skip */
        !          6111:                if ((drvp->drive_flags & DRIVE) == 0)
        !          6112:                        continue;
        !          6113:                mode = 0;
        !          6114:                if (drvp->drive_flags & DRIVE_UDMA) {
        !          6115:                        /* use Ultra/DMA */
        !          6116:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          6117:                        mode = PDC2xx_TIM_SET_MB(mode,
        !          6118:                           pdc2xx_udma_mb[drvp->UDMA_mode]);
        !          6119:                        mode = PDC2xx_TIM_SET_MC(mode,
        !          6120:                           pdc2xx_udma_mc[drvp->UDMA_mode]);
        !          6121:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          6122:                } else if (drvp->drive_flags & DRIVE_DMA) {
        !          6123:                        mode = PDC2xx_TIM_SET_MB(mode,
        !          6124:                            pdc2xx_dma_mb[drvp->DMA_mode]);
        !          6125:                        mode = PDC2xx_TIM_SET_MC(mode,
        !          6126:                           pdc2xx_dma_mc[drvp->DMA_mode]);
        !          6127:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          6128:                } else {
        !          6129:                        mode = PDC2xx_TIM_SET_MB(mode,
        !          6130:                            pdc2xx_dma_mb[0]);
        !          6131:                        mode = PDC2xx_TIM_SET_MC(mode,
        !          6132:                            pdc2xx_dma_mc[0]);
        !          6133:                }
        !          6134:                mode = PDC2xx_TIM_SET_PA(mode, pdc2xx_pa[drvp->PIO_mode]);
        !          6135:                mode = PDC2xx_TIM_SET_PB(mode, pdc2xx_pb[drvp->PIO_mode]);
        !          6136:                if (drvp->drive_flags & DRIVE_ATA)
        !          6137:                        mode |= PDC2xx_TIM_PRE;
        !          6138:                mode |= PDC2xx_TIM_SYNC | PDC2xx_TIM_ERRDY;
        !          6139:                if (drvp->PIO_mode >= 3) {
        !          6140:                        mode |= PDC2xx_TIM_IORDY;
        !          6141:                        if (drive == 0)
        !          6142:                                mode |= PDC2xx_TIM_IORDYp;
        !          6143:                }
        !          6144:                WDCDEBUG_PRINT(("pdc202xx_setup_channel: %s:%d:%d "
        !          6145:                    "timings 0x%x\n",
        !          6146:                    sc->sc_wdcdev.sc_dev.dv_xname,
        !          6147:                    chp->channel, drive, mode), DEBUG_PROBE);
        !          6148:                    pci_conf_write(sc->sc_pc, sc->sc_tag,
        !          6149:                    PDC2xx_TIM(chp->channel, drive), mode);
        !          6150:        }
        !          6151:        if (idedma_ctl != 0) {
        !          6152:                /* Add software bits in status register */
        !          6153:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          6154:                    IDEDMA_CTL(channel), idedma_ctl);
        !          6155:        }
        !          6156:        pciide_print_modes(cp);
        !          6157: }
        !          6158:
        !          6159: void
        !          6160: pdc20268_setup_channel(struct channel_softc *chp)
        !          6161: {
        !          6162:        struct ata_drive_datas *drvp;
        !          6163:        int drive, cable;
        !          6164:        u_int32_t idedma_ctl;
        !          6165:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          6166:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          6167:        int channel = chp->channel;
        !          6168:
        !          6169:        /* check 80 pins cable */
        !          6170:        cable = pdc268_config_read(chp, 0x0b) & PDC268_CABLE;
        !          6171:
        !          6172:        /* setup DMA if needed */
        !          6173:        pciide_channel_dma_setup(cp);
        !          6174:
        !          6175:        idedma_ctl = 0;
        !          6176:
        !          6177:        for (drive = 0; drive < 2; drive++) {
        !          6178:                drvp = &chp->ch_drive[drive];
        !          6179:                /* If no drive, skip */
        !          6180:                if ((drvp->drive_flags & DRIVE) == 0)
        !          6181:                        continue;
        !          6182:                if (drvp->drive_flags & DRIVE_UDMA) {
        !          6183:                        /* use Ultra/DMA */
        !          6184:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          6185:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          6186:                        if (cable && drvp->UDMA_mode > 2) {
        !          6187:                                WDCDEBUG_PRINT(("%s(%s:%d:%d): 80-wire "
        !          6188:                                    "cable not detected\n", drvp->drive_name,
        !          6189:                                    sc->sc_wdcdev.sc_dev.dv_xname,
        !          6190:                                    channel, drive), DEBUG_PROBE);
        !          6191:                                drvp->UDMA_mode = 2;
        !          6192:                        }
        !          6193:                } else if (drvp->drive_flags & DRIVE_DMA) {
        !          6194:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          6195:                }
        !          6196:        }
        !          6197:        /* nothing to do to setup modes, the controller snoop SET_FEATURE cmd */
        !          6198:        if (idedma_ctl != 0) {
        !          6199:                /* Add software bits in status register */
        !          6200:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          6201:                    IDEDMA_CTL(channel), idedma_ctl);
        !          6202:        }
        !          6203:        pciide_print_modes(cp);
        !          6204: }
        !          6205:
        !          6206: int
        !          6207: pdc202xx_pci_intr(void *arg)
        !          6208: {
        !          6209:        struct pciide_softc *sc = arg;
        !          6210:        struct pciide_channel *cp;
        !          6211:        struct channel_softc *wdc_cp;
        !          6212:        int i, rv, crv;
        !          6213:        u_int32_t scr;
        !          6214:
        !          6215:        rv = 0;
        !          6216:        scr = bus_space_read_4(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_SCR);
        !          6217:        for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {
        !          6218:                cp = &sc->pciide_channels[i];
        !          6219:                wdc_cp = &cp->wdc_channel;
        !          6220:                /* If a compat channel skip. */
        !          6221:                if (cp->compat)
        !          6222:                        continue;
        !          6223:                if (scr & PDC2xx_SCR_INT(i)) {
        !          6224:                        crv = wdcintr(wdc_cp);
        !          6225:                        if (crv == 0)
        !          6226:                                printf("%s:%d: bogus intr (reg 0x%x)\n",
        !          6227:                                    sc->sc_wdcdev.sc_dev.dv_xname, i, scr);
        !          6228:                        else
        !          6229:                                rv = 1;
        !          6230:                }
        !          6231:        }
        !          6232:        return (rv);
        !          6233: }
        !          6234:
        !          6235: int
        !          6236: pdc20265_pci_intr(void *arg)
        !          6237: {
        !          6238:        struct pciide_softc *sc = arg;
        !          6239:        struct pciide_channel *cp;
        !          6240:        struct channel_softc *wdc_cp;
        !          6241:        int i, rv, crv;
        !          6242:        u_int32_t dmastat;
        !          6243:
        !          6244:        rv = 0;
        !          6245:        for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {
        !          6246:                cp = &sc->pciide_channels[i];
        !          6247:                wdc_cp = &cp->wdc_channel;
        !          6248:                /* If a compat channel skip. */
        !          6249:                if (cp->compat)
        !          6250:                        continue;
        !          6251:
        !          6252:                /*
        !          6253:                 * In case of shared IRQ check that the interrupt
        !          6254:                 * was actually generated by this channel.
        !          6255:                 * Only check the channel that is enabled.
        !          6256:                 */
        !          6257:                if (cp->hw_ok && PDC_IS_268(sc)) {
        !          6258:                        if ((pdc268_config_read(wdc_cp,
        !          6259:                            0x0b) & PDC268_INTR) == 0)
        !          6260:                                continue;
        !          6261:                }
        !          6262:
        !          6263:                /*
        !          6264:                 * The Ultra/100 seems to assert PDC2xx_SCR_INT * spuriously,
        !          6265:                 * however it asserts INT in IDEDMA_CTL even for non-DMA ops.
        !          6266:                 * So use it instead (requires 2 reg reads instead of 1,
        !          6267:                 * but we can't do it another way).
        !          6268:                 */
        !          6269:                dmastat = bus_space_read_1(sc->sc_dma_iot,
        !          6270:                    sc->sc_dma_ioh, IDEDMA_CTL(i));
        !          6271:                if ((dmastat & IDEDMA_CTL_INTR) == 0)
        !          6272:                        continue;
        !          6273:
        !          6274:                crv = wdcintr(wdc_cp);
        !          6275:                if (crv == 0)
        !          6276:                        printf("%s:%d: bogus intr\n",
        !          6277:                            sc->sc_wdcdev.sc_dev.dv_xname, i);
        !          6278:                else
        !          6279:                        rv = 1;
        !          6280:        }
        !          6281:        return (rv);
        !          6282: }
        !          6283:
        !          6284: void
        !          6285: pdc20262_dma_start(void *v, int channel, int drive)
        !          6286: {
        !          6287:        struct pciide_softc *sc = v;
        !          6288:        struct pciide_dma_maps *dma_maps =
        !          6289:            &sc->pciide_channels[channel].dma_maps[drive];
        !          6290:        u_int8_t clock;
        !          6291:        u_int32_t count;
        !          6292:
        !          6293:        if (dma_maps->dma_flags & WDC_DMA_LBA48) {
        !          6294:                clock = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          6295:                    PDC262_U66);
        !          6296:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          6297:                    PDC262_U66, clock | PDC262_U66_EN(channel));
        !          6298:                count = dma_maps->dmamap_xfer->dm_mapsize >> 1;
        !          6299:                count |= dma_maps->dma_flags & WDC_DMA_READ ?
        !          6300:                    PDC262_ATAPI_LBA48_READ : PDC262_ATAPI_LBA48_WRITE;
        !          6301:                bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          6302:                    PDC262_ATAPI(channel), count);
        !          6303:        }
        !          6304:
        !          6305:        pciide_dma_start(v, channel, drive);
        !          6306: }
        !          6307:
        !          6308: int
        !          6309: pdc20262_dma_finish(void *v, int channel, int drive, int force)
        !          6310: {
        !          6311:        struct pciide_softc *sc = v;
        !          6312:        struct pciide_dma_maps *dma_maps =
        !          6313:            &sc->pciide_channels[channel].dma_maps[drive];
        !          6314:        u_int8_t clock;
        !          6315:
        !          6316:        if (dma_maps->dma_flags & WDC_DMA_LBA48) {
        !          6317:                clock = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          6318:                    PDC262_U66);
        !          6319:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          6320:                    PDC262_U66, clock & ~PDC262_U66_EN(channel));
        !          6321:                bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          6322:                    PDC262_ATAPI(channel), 0);
        !          6323:        }
        !          6324:
        !          6325:        return (pciide_dma_finish(v, channel, drive, force));
        !          6326: }
        !          6327:
        !          6328: void
        !          6329: pdcsata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          6330: {
        !          6331:        struct pciide_channel *cp;
        !          6332:        struct channel_softc *wdc_cp;
        !          6333:        struct pciide_pdcsata *ps;
        !          6334:        int channel, i;
        !          6335:        bus_size_t dmasize;
        !          6336:        pci_intr_handle_t intrhandle;
        !          6337:        const char *intrstr;
        !          6338:
        !          6339:        /* Allocate memory for private data */
        !          6340:        sc->sc_cookie = malloc(sizeof(struct pciide_pdcsata), M_DEVBUF,
        !          6341:            M_NOWAIT);
        !          6342:        ps = sc->sc_cookie;
        !          6343:        bzero(ps, sizeof(*ps));
        !          6344:
        !          6345:        /*
        !          6346:         * Promise SATA controllers have 3 or 4 channels,
        !          6347:         * the usual IDE registers are mapped in I/O space, with offsets.
        !          6348:         */
        !          6349:        if (pci_intr_map(pa, &intrhandle) != 0) {
        !          6350:                printf(": couldn't map interrupt\n");
        !          6351:                return;
        !          6352:        }
        !          6353:        intrstr = pci_intr_string(pa->pa_pc, intrhandle);
        !          6354:
        !          6355:        switch (sc->sc_pp->ide_product) {
        !          6356:        case PCI_PRODUCT_PROMISE_PDC20318:
        !          6357:        case PCI_PRODUCT_PROMISE_PDC20319:
        !          6358:        case PCI_PRODUCT_PROMISE_PDC20371:
        !          6359:        case PCI_PRODUCT_PROMISE_PDC20375:
        !          6360:        case PCI_PRODUCT_PROMISE_PDC20376:
        !          6361:        case PCI_PRODUCT_PROMISE_PDC20377:
        !          6362:        case PCI_PRODUCT_PROMISE_PDC20378:
        !          6363:        case PCI_PRODUCT_PROMISE_PDC20379:
        !          6364:        default:
        !          6365:                sc->sc_pci_ih = pci_intr_establish(pa->pa_pc,
        !          6366:                    intrhandle, IPL_BIO, pdc203xx_pci_intr, sc,
        !          6367:                    sc->sc_wdcdev.sc_dev.dv_xname);
        !          6368:                break;
        !          6369:
        !          6370:        case PCI_PRODUCT_PROMISE_PDC40518:
        !          6371:        case PCI_PRODUCT_PROMISE_PDC40519:
        !          6372:        case PCI_PRODUCT_PROMISE_PDC40718:
        !          6373:        case PCI_PRODUCT_PROMISE_PDC40719:
        !          6374:        case PCI_PRODUCT_PROMISE_PDC40779:
        !          6375:        case PCI_PRODUCT_PROMISE_PDC20571:
        !          6376:        case PCI_PRODUCT_PROMISE_PDC20575:
        !          6377:        case PCI_PRODUCT_PROMISE_PDC20579:
        !          6378:        case PCI_PRODUCT_PROMISE_PDC20771:
        !          6379:        case PCI_PRODUCT_PROMISE_PDC20775:
        !          6380:                sc->sc_pci_ih = pci_intr_establish(pa->pa_pc,
        !          6381:                    intrhandle, IPL_BIO, pdc205xx_pci_intr, sc,
        !          6382:                    sc->sc_wdcdev.sc_dev.dv_xname);
        !          6383:                break;
        !          6384:        }
        !          6385:
        !          6386:        if (sc->sc_pci_ih == NULL) {
        !          6387:                printf(": couldn't establish native-PCI interrupt");
        !          6388:                if (intrstr != NULL)
        !          6389:                        printf(" at %s", intrstr);
        !          6390:                printf("\n");
        !          6391:                return;
        !          6392:        }
        !          6393:
        !          6394:        sc->sc_dma_ok = (pci_mapreg_map(pa, PCIIDE_REG_BUS_MASTER_DMA,
        !          6395:            PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_dma_iot,
        !          6396:            &sc->sc_dma_ioh, NULL, &dmasize, 0) == 0);
        !          6397:        if (!sc->sc_dma_ok) {
        !          6398:                printf(": couldn't map bus-master DMA registers\n");
        !          6399:                pci_intr_disestablish(pa->pa_pc, sc->sc_pci_ih);
        !          6400:                return;
        !          6401:        }
        !          6402:
        !          6403:        sc->sc_dmat = pa->pa_dmat;
        !          6404:
        !          6405:        if (pci_mapreg_map(pa, PDC203xx_BAR_IDEREGS,
        !          6406:            PCI_MAPREG_MEM_TYPE_32BIT, 0, &ps->ba5_st,
        !          6407:            &ps->ba5_sh, NULL, NULL, 0) != 0) {
        !          6408:                printf(": couldn't map IDE registers\n");
        !          6409:                bus_space_unmap(sc->sc_dma_iot, sc->sc_dma_ioh, dmasize);
        !          6410:                pci_intr_disestablish(pa->pa_pc, sc->sc_pci_ih);
        !          6411:                return;
        !          6412:        }
        !          6413:
        !          6414:        printf(": DMA\n");
        !          6415:
        !          6416:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16;
        !          6417:        sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
        !          6418:        sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          6419:        sc->sc_wdcdev.irqack = pdc203xx_irqack;
        !          6420:        sc->sc_wdcdev.PIO_cap = 4;
        !          6421:        sc->sc_wdcdev.DMA_cap = 2;
        !          6422:        sc->sc_wdcdev.UDMA_cap = 6;
        !          6423:        sc->sc_wdcdev.set_modes = pdc203xx_setup_channel;
        !          6424:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          6425:
        !          6426:        switch (sc->sc_pp->ide_product) {
        !          6427:        case PCI_PRODUCT_PROMISE_PDC20318:
        !          6428:        case PCI_PRODUCT_PROMISE_PDC20319:
        !          6429:        case PCI_PRODUCT_PROMISE_PDC20371:
        !          6430:        case PCI_PRODUCT_PROMISE_PDC20375:
        !          6431:        case PCI_PRODUCT_PROMISE_PDC20376:
        !          6432:        case PCI_PRODUCT_PROMISE_PDC20377:
        !          6433:        case PCI_PRODUCT_PROMISE_PDC20378:
        !          6434:        case PCI_PRODUCT_PROMISE_PDC20379:
        !          6435:        default:
        !          6436:                bus_space_write_4(ps->ba5_st, ps->ba5_sh, 0x06c, 0x00ff0033);
        !          6437:                sc->sc_wdcdev.nchannels =
        !          6438:                    (bus_space_read_4(ps->ba5_st, ps->ba5_sh, 0x48) & 0x02) ?
        !          6439:                    PDC203xx_NCHANNELS : 3;
        !          6440:                break;
        !          6441:
        !          6442:        case PCI_PRODUCT_PROMISE_PDC40518:
        !          6443:        case PCI_PRODUCT_PROMISE_PDC40519:
        !          6444:        case PCI_PRODUCT_PROMISE_PDC40718:
        !          6445:        case PCI_PRODUCT_PROMISE_PDC40719:
        !          6446:        case PCI_PRODUCT_PROMISE_PDC40779:
        !          6447:        case PCI_PRODUCT_PROMISE_PDC20571:
        !          6448:                bus_space_write_4(ps->ba5_st, ps->ba5_sh, 0x60, 0x00ff00ff);
        !          6449:                sc->sc_wdcdev.nchannels = PDC40718_NCHANNELS;
        !          6450:
        !          6451:                sc->sc_wdcdev.reset = pdc205xx_do_reset;
        !          6452:                sc->sc_wdcdev.drv_probe = pdc205xx_drv_probe;
        !          6453:
        !          6454:                break;
        !          6455:        case PCI_PRODUCT_PROMISE_PDC20575:
        !          6456:        case PCI_PRODUCT_PROMISE_PDC20579:
        !          6457:        case PCI_PRODUCT_PROMISE_PDC20771:
        !          6458:        case PCI_PRODUCT_PROMISE_PDC20775:
        !          6459:                bus_space_write_4(ps->ba5_st, ps->ba5_sh, 0x60, 0x00ff00ff);
        !          6460:                sc->sc_wdcdev.nchannels = PDC20575_NCHANNELS;
        !          6461:
        !          6462:                sc->sc_wdcdev.reset = pdc205xx_do_reset;
        !          6463:                sc->sc_wdcdev.drv_probe = pdc205xx_drv_probe;
        !          6464:
        !          6465:                break;
        !          6466:        }
        !          6467:
        !          6468:        sc->sc_wdcdev.dma_arg = sc;
        !          6469:        sc->sc_wdcdev.dma_init = pciide_dma_init;
        !          6470:        sc->sc_wdcdev.dma_start = pdc203xx_dma_start;
        !          6471:        sc->sc_wdcdev.dma_finish = pdc203xx_dma_finish;
        !          6472:
        !          6473:        for (channel = 0; channel < sc->sc_wdcdev.nchannels;
        !          6474:             channel++) {
        !          6475:                cp = &sc->pciide_channels[channel];
        !          6476:                sc->wdc_chanarray[channel] = &cp->wdc_channel;
        !          6477:
        !          6478:                cp->ih = sc->sc_pci_ih;
        !          6479:                cp->name = NULL;
        !          6480:                cp->wdc_channel.channel = channel;
        !          6481:                cp->wdc_channel.wdc = &sc->sc_wdcdev;
        !          6482:                cp->wdc_channel.ch_queue =
        !          6483:                    malloc(sizeof(struct channel_queue), M_DEVBUF, M_NOWAIT);
        !          6484:                if (cp->wdc_channel.ch_queue == NULL) {
        !          6485:                        printf("%s: channel %d: "
        !          6486:                            "can't allocate memory for command queue\n",
        !          6487:                        sc->sc_wdcdev.sc_dev.dv_xname, channel);
        !          6488:                        continue;
        !          6489:                }
        !          6490:                wdc_cp = &cp->wdc_channel;
        !          6491:
        !          6492:                ps->regs[channel].ctl_iot = ps->ba5_st;
        !          6493:                ps->regs[channel].cmd_iot = ps->ba5_st;
        !          6494:
        !          6495:                if (bus_space_subregion(ps->ba5_st, ps->ba5_sh,
        !          6496:                    0x0238 + (channel << 7), 1,
        !          6497:                    &ps->regs[channel].ctl_ioh) != 0) {
        !          6498:                        printf("%s: couldn't map channel %d ctl regs\n",
        !          6499:                            sc->sc_wdcdev.sc_dev.dv_xname,
        !          6500:                            channel);
        !          6501:                        continue;
        !          6502:                }
        !          6503:                for (i = 0; i < WDC_NREG; i++) {
        !          6504:                        if (bus_space_subregion(ps->ba5_st, ps->ba5_sh,
        !          6505:                            0x0200 + (i << 2) + (channel << 7), i == 0 ? 4 : 1,
        !          6506:                            &ps->regs[channel].cmd_iohs[i]) != 0) {
        !          6507:                                printf("%s: couldn't map channel %d cmd "
        !          6508:                                    "regs\n",
        !          6509:                                    sc->sc_wdcdev.sc_dev.dv_xname,
        !          6510:                                    channel);
        !          6511:                                continue;
        !          6512:                        }
        !          6513:                }
        !          6514:                ps->regs[channel].cmd_iohs[wdr_status & _WDC_REGMASK] =
        !          6515:                    ps->regs[channel].cmd_iohs[wdr_command & _WDC_REGMASK];
        !          6516:                ps->regs[channel].cmd_iohs[wdr_features & _WDC_REGMASK] =
        !          6517:                    ps->regs[channel].cmd_iohs[wdr_error & _WDC_REGMASK];
        !          6518:                wdc_cp->data32iot = wdc_cp->cmd_iot =
        !          6519:                    ps->regs[channel].cmd_iot;
        !          6520:                wdc_cp->data32ioh = wdc_cp->cmd_ioh =
        !          6521:                    ps->regs[channel].cmd_iohs[0];
        !          6522:                wdc_cp->_vtbl = &wdc_pdc203xx_vtbl;
        !          6523:
        !          6524:                /*
        !          6525:                 * Subregion de busmaster registers. They're spread all over
        !          6526:                 * the controller's register space :(. They are also 4 bytes
        !          6527:                 * sized, with some specific extentions in the extra bits.
        !          6528:                 * It also seems that the IDEDMA_CTL register isn't available.
        !          6529:                 */
        !          6530:                if (bus_space_subregion(ps->ba5_st, ps->ba5_sh,
        !          6531:                    0x260 + (channel << 7), 1,
        !          6532:                    &ps->regs[channel].dma_iohs[IDEDMA_CMD(0)]) != 0) {
        !          6533:                        printf("%s channel %d: can't subregion DMA "
        !          6534:                            "registers\n",
        !          6535:                            sc->sc_wdcdev.sc_dev.dv_xname, channel);
        !          6536:                        continue;
        !          6537:                }
        !          6538:                if (bus_space_subregion(ps->ba5_st, ps->ba5_sh,
        !          6539:                    0x244 + (channel << 7), 4,
        !          6540:                    &ps->regs[channel].dma_iohs[IDEDMA_TBL(0)]) != 0) {
        !          6541:                        printf("%s channel %d: can't subregion DMA "
        !          6542:                            "registers\n",
        !          6543:                            sc->sc_wdcdev.sc_dev.dv_xname, channel);
        !          6544:                        continue;
        !          6545:                }
        !          6546:
        !          6547:                wdcattach(wdc_cp);
        !          6548:                bus_space_write_4(sc->sc_dma_iot,
        !          6549:                    ps->regs[channel].dma_iohs[IDEDMA_CMD(0)], 0,
        !          6550:                    (bus_space_read_4(sc->sc_dma_iot,
        !          6551:                        ps->regs[channel].dma_iohs[IDEDMA_CMD(0)],
        !          6552:                        0) & ~0x00003f9f) | (channel + 1));
        !          6553:                bus_space_write_4(ps->ba5_st, ps->ba5_sh,
        !          6554:                    (channel + 1) << 2, 0x00000001);
        !          6555:
        !          6556:                pdc203xx_setup_channel(&cp->wdc_channel);
        !          6557:        }
        !          6558:
        !          6559:        printf("%s: using %s for native-PCI interrupt\n",
        !          6560:            sc->sc_wdcdev.sc_dev.dv_xname,
        !          6561:            intrstr ? intrstr : "unknown interrupt");
        !          6562: }
        !          6563:
        !          6564: void
        !          6565: pdc203xx_setup_channel(struct channel_softc *chp)
        !          6566: {
        !          6567:        struct ata_drive_datas *drvp;
        !          6568:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          6569:        int drive, s;
        !          6570:
        !          6571:        pciide_channel_dma_setup(cp);
        !          6572:
        !          6573:        for (drive = 0; drive < 2; drive++) {
        !          6574:                drvp = &chp->ch_drive[drive];
        !          6575:                if ((drvp->drive_flags & DRIVE) == 0)
        !          6576:                        continue;
        !          6577:                if (drvp->drive_flags & DRIVE_UDMA) {
        !          6578:                        s = splbio();
        !          6579:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          6580:                        splx(s);
        !          6581:                }
        !          6582:        }
        !          6583:        pciide_print_modes(cp);
        !          6584: }
        !          6585:
        !          6586: int
        !          6587: pdc203xx_pci_intr(void *arg)
        !          6588: {
        !          6589:        struct pciide_softc *sc = arg;
        !          6590:        struct pciide_channel *cp;
        !          6591:        struct channel_softc *wdc_cp;
        !          6592:        struct pciide_pdcsata *ps = sc->sc_cookie;
        !          6593:        int i, rv, crv;
        !          6594:        u_int32_t scr;
        !          6595:
        !          6596:        rv = 0;
        !          6597:        scr = bus_space_read_4(ps->ba5_st, ps->ba5_sh, 0x00040);
        !          6598:
        !          6599:        for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {
        !          6600:                cp = &sc->pciide_channels[i];
        !          6601:                wdc_cp = &cp->wdc_channel;
        !          6602:                if (scr & (1 << (i + 1))) {
        !          6603:                        crv = wdcintr(wdc_cp);
        !          6604:                        if (crv == 0) {
        !          6605:                                printf("%s:%d: bogus intr (reg 0x%x)\n",
        !          6606:                                    sc->sc_wdcdev.sc_dev.dv_xname,
        !          6607:                                    i, scr);
        !          6608:                        } else
        !          6609:                                rv = 1;
        !          6610:                }
        !          6611:        }
        !          6612:
        !          6613:        return (rv);
        !          6614: }
        !          6615:
        !          6616: int
        !          6617: pdc205xx_pci_intr(void *arg)
        !          6618: {
        !          6619:        struct pciide_softc *sc = arg;
        !          6620:        struct pciide_channel *cp;
        !          6621:        struct channel_softc *wdc_cp;
        !          6622:        struct pciide_pdcsata *ps = sc->sc_cookie;
        !          6623:        int i, rv, crv;
        !          6624:        u_int32_t scr, status;
        !          6625:
        !          6626:        rv = 0;
        !          6627:        scr = bus_space_read_4(ps->ba5_st, ps->ba5_sh, 0x40);
        !          6628:        bus_space_write_4(ps->ba5_st, ps->ba5_sh, 0x40, scr & 0x0000ffff);
        !          6629:
        !          6630:        status = bus_space_read_4(ps->ba5_st, ps->ba5_sh, 0x60);
        !          6631:        bus_space_write_4(ps->ba5_st, ps->ba5_sh, 0x60, status & 0x000000ff);
        !          6632:
        !          6633:        for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {
        !          6634:                cp = &sc->pciide_channels[i];
        !          6635:                wdc_cp = &cp->wdc_channel;
        !          6636:                if (scr & (1 << (i + 1))) {
        !          6637:                        crv = wdcintr(wdc_cp);
        !          6638:                        if (crv == 0) {
        !          6639:                                printf("%s:%d: bogus intr (reg 0x%x)\n",
        !          6640:                                    sc->sc_wdcdev.sc_dev.dv_xname,
        !          6641:                                    i, scr);
        !          6642:                        } else
        !          6643:                                rv = 1;
        !          6644:                }
        !          6645:        }
        !          6646:        return rv;
        !          6647: }
        !          6648:
        !          6649: void
        !          6650: pdc203xx_irqack(struct channel_softc *chp)
        !          6651: {
        !          6652:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          6653:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          6654:        struct pciide_pdcsata *ps = sc->sc_cookie;
        !          6655:        int chan = chp->channel;
        !          6656:
        !          6657:        bus_space_write_4(sc->sc_dma_iot,
        !          6658:            ps->regs[chan].dma_iohs[IDEDMA_CMD(0)], 0,
        !          6659:            (bus_space_read_4(sc->sc_dma_iot,
        !          6660:                ps->regs[chan].dma_iohs[IDEDMA_CMD(0)],
        !          6661:                0) & ~0x00003f9f) | (chan + 1));
        !          6662:        bus_space_write_4(ps->ba5_st, ps->ba5_sh,
        !          6663:            (chan + 1) << 2, 0x00000001);
        !          6664: }
        !          6665:
        !          6666: void
        !          6667: pdc203xx_dma_start(void *v, int channel, int drive)
        !          6668: {
        !          6669:        struct pciide_softc *sc = v;
        !          6670:        struct pciide_channel *cp = &sc->pciide_channels[channel];
        !          6671:        struct pciide_dma_maps *dma_maps = &cp->dma_maps[drive];
        !          6672:        struct pciide_pdcsata *ps = sc->sc_cookie;
        !          6673:
        !          6674:        /* Write table address */
        !          6675:        bus_space_write_4(sc->sc_dma_iot,
        !          6676:            ps->regs[channel].dma_iohs[IDEDMA_TBL(0)], 0,
        !          6677:            dma_maps->dmamap_table->dm_segs[0].ds_addr);
        !          6678:
        !          6679:        /* Start DMA engine */
        !          6680:        bus_space_write_4(sc->sc_dma_iot,
        !          6681:            ps->regs[channel].dma_iohs[IDEDMA_CMD(0)], 0,
        !          6682:            (bus_space_read_4(sc->sc_dma_iot,
        !          6683:            ps->regs[channel].dma_iohs[IDEDMA_CMD(0)],
        !          6684:            0) & ~0xc0) | ((dma_maps->dma_flags & WDC_DMA_READ) ? 0x80 : 0xc0));
        !          6685: }
        !          6686:
        !          6687: int
        !          6688: pdc203xx_dma_finish(void *v, int channel, int drive, int force)
        !          6689: {
        !          6690:        struct pciide_softc *sc = v;
        !          6691:        struct pciide_channel *cp = &sc->pciide_channels[channel];
        !          6692:        struct pciide_dma_maps *dma_maps = &cp->dma_maps[drive];
        !          6693:        struct pciide_pdcsata *ps = sc->sc_cookie;
        !          6694:
        !          6695:        /* Stop DMA channel */
        !          6696:        bus_space_write_4(sc->sc_dma_iot,
        !          6697:            ps->regs[channel].dma_iohs[IDEDMA_CMD(0)], 0,
        !          6698:            (bus_space_read_4(sc->sc_dma_iot,
        !          6699:            ps->regs[channel].dma_iohs[IDEDMA_CMD(0)],
        !          6700:            0) & ~0x80));
        !          6701:
        !          6702:        /* Unload the map of the data buffer */
        !          6703:        bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_xfer, 0,
        !          6704:            dma_maps->dmamap_xfer->dm_mapsize,
        !          6705:            (dma_maps->dma_flags & WDC_DMA_READ) ?
        !          6706:            BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
        !          6707:        bus_dmamap_unload(sc->sc_dmat, dma_maps->dmamap_xfer);
        !          6708:
        !          6709:        return (0);
        !          6710: }
        !          6711:
        !          6712: u_int8_t
        !          6713: pdc203xx_read_reg(struct channel_softc *chp, enum wdc_regs reg)
        !          6714: {
        !          6715:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          6716:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          6717:        struct pciide_pdcsata *ps = sc->sc_cookie;
        !          6718:        u_int8_t val;
        !          6719:
        !          6720:        if (reg & _WDC_AUX) {
        !          6721:                return (bus_space_read_1(ps->regs[chp->channel].ctl_iot,
        !          6722:                    ps->regs[chp->channel].ctl_ioh, reg & _WDC_REGMASK));
        !          6723:        } else {
        !          6724:                val = bus_space_read_1(ps->regs[chp->channel].cmd_iot,
        !          6725:                    ps->regs[chp->channel].cmd_iohs[reg & _WDC_REGMASK], 0);
        !          6726:                return (val);
        !          6727:        }
        !          6728: }
        !          6729:
        !          6730: void
        !          6731: pdc203xx_write_reg(struct channel_softc *chp, enum wdc_regs reg, u_int8_t val)
        !          6732: {
        !          6733:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          6734:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          6735:        struct pciide_pdcsata *ps = sc->sc_cookie;
        !          6736:
        !          6737:        if (reg & _WDC_AUX)
        !          6738:                bus_space_write_1(ps->regs[chp->channel].ctl_iot,
        !          6739:                    ps->regs[chp->channel].ctl_ioh, reg & _WDC_REGMASK, val);
        !          6740:        else
        !          6741:                bus_space_write_1(ps->regs[chp->channel].cmd_iot,
        !          6742:                    ps->regs[chp->channel].cmd_iohs[reg & _WDC_REGMASK],
        !          6743:                    0, val);
        !          6744: }
        !          6745:
        !          6746: void
        !          6747: pdc205xx_do_reset(struct channel_softc *chp)
        !          6748: {
        !          6749:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          6750:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          6751:        struct pciide_pdcsata *ps = sc->sc_cookie;
        !          6752:        u_int32_t scontrol;
        !          6753:
        !          6754:        wdc_do_reset(chp);
        !          6755:
        !          6756:        /* reset SATA */
        !          6757:        scontrol = SControl_DET_INIT | SControl_SPD_ANY | SControl_IPM_NONE;
        !          6758:        SCONTROL_WRITE(ps, chp->channel, scontrol);
        !          6759:        delay(50*1000);
        !          6760:
        !          6761:        scontrol &= ~SControl_DET_INIT;
        !          6762:        SCONTROL_WRITE(ps, chp->channel, scontrol);
        !          6763:        delay(50*1000);
        !          6764: }
        !          6765:
        !          6766: void
        !          6767: pdc205xx_drv_probe(struct channel_softc *chp)
        !          6768: {
        !          6769:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          6770:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          6771:        struct pciide_pdcsata *ps = sc->sc_cookie;
        !          6772:        bus_space_handle_t *iohs;
        !          6773:        u_int32_t scontrol, sstatus;
        !          6774:        u_int16_t scnt, sn, cl, ch;
        !          6775:        int i, s;
        !          6776:
        !          6777:        /* XXX This should be done by other code. */
        !          6778:        for (i = 0; i < 2; i++) {
        !          6779:                chp->ch_drive[i].chnl_softc = chp;
        !          6780:                chp->ch_drive[i].drive = i;
        !          6781:        }
        !          6782:
        !          6783:        SCONTROL_WRITE(ps, chp->channel, 0);
        !          6784:        delay(50*1000);
        !          6785:
        !          6786:        scontrol = SControl_DET_INIT | SControl_SPD_ANY | SControl_IPM_NONE;
        !          6787:        SCONTROL_WRITE(ps,chp->channel,scontrol);
        !          6788:        delay(50*1000);
        !          6789:
        !          6790:        scontrol &= ~SControl_DET_INIT;
        !          6791:        SCONTROL_WRITE(ps,chp->channel,scontrol);
        !          6792:        delay(50*1000);
        !          6793:
        !          6794:        sstatus = SSTATUS_READ(ps,chp->channel);
        !          6795:
        !          6796:        switch (sstatus & SStatus_DET_mask) {
        !          6797:        case SStatus_DET_NODEV:
        !          6798:                /* No Device; be silent.  */
        !          6799:                break;
        !          6800:
        !          6801:        case SStatus_DET_DEV_NE:
        !          6802:                printf("%s: port %d: device connected, but "
        !          6803:                    "communication not established\n",
        !          6804:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel);
        !          6805:                break;
        !          6806:
        !          6807:        case SStatus_DET_OFFLINE:
        !          6808:                printf("%s: port %d: PHY offline\n",
        !          6809:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel);
        !          6810:                break;
        !          6811:
        !          6812:        case SStatus_DET_DEV:
        !          6813:                iohs = ps->regs[chp->channel].cmd_iohs;
        !          6814:                bus_space_write_1(chp->cmd_iot, iohs[wdr_sdh], 0,
        !          6815:                    WDSD_IBM);
        !          6816:                delay(10);      /* 400ns delay */
        !          6817:                scnt = bus_space_read_2(chp->cmd_iot, iohs[wdr_seccnt], 0);
        !          6818:                sn = bus_space_read_2(chp->cmd_iot, iohs[wdr_sector], 0);
        !          6819:                cl = bus_space_read_2(chp->cmd_iot, iohs[wdr_cyl_lo], 0);
        !          6820:                ch = bus_space_read_2(chp->cmd_iot, iohs[wdr_cyl_hi], 0);
        !          6821: #if 0
        !          6822:                printf("%s: port %d: scnt=0x%x sn=0x%x cl=0x%x ch=0x%x\n",
        !          6823:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel,
        !          6824:                    scnt, sn, cl, ch);
        !          6825: #endif
        !          6826:                /*
        !          6827:                 * scnt and sn are supposed to be 0x1 for ATAPI, but in some
        !          6828:                 * cases we get wrong values here, so ignore it.
        !          6829:                 */
        !          6830:                s = splbio();
        !          6831:                if (cl == 0x14 && ch == 0xeb)
        !          6832:                        chp->ch_drive[0].drive_flags |= DRIVE_ATAPI;
        !          6833:                else
        !          6834:                        chp->ch_drive[0].drive_flags |= DRIVE_ATA;
        !          6835:                splx(s);
        !          6836: #if 0
        !          6837:                printf("%s: port %d: device present",
        !          6838:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel);
        !          6839:                switch ((sstatus & SStatus_SPD_mask) >> SStatus_SPD_shift) {
        !          6840:                case 1:
        !          6841:                        printf(", speed: 1.5Gb/s");
        !          6842:                        break;
        !          6843:                case 2:
        !          6844:                        printf(", speed: 3.0Gb/s");
        !          6845:                        break;
        !          6846:                }
        !          6847:                printf("\n");
        !          6848: #endif
        !          6849:                break;
        !          6850:
        !          6851:        default:
        !          6852:                printf("%s: port %d: unknown SStatus: 0x%08x\n",
        !          6853:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel, sstatus);
        !          6854:        }
        !          6855: }
        !          6856:
        !          6857: #ifdef notyet
        !          6858: /*
        !          6859:  * Inline functions for accessing the timing registers of the
        !          6860:  * OPTi controller.
        !          6861:  *
        !          6862:  * These *MUST* disable interrupts as they need atomic access to
        !          6863:  * certain magic registers. Failure to adhere to this *will*
        !          6864:  * break things in subtle ways if the wdc registers are accessed
        !          6865:  * by an interrupt routine while this magic sequence is executing.
        !          6866:  */
        !          6867: static __inline__ u_int8_t
        !          6868: opti_read_config(struct channel_softc *chp, int reg)
        !          6869: {
        !          6870:        u_int8_t rv;
        !          6871:        int s = splhigh();
        !          6872:
        !          6873:        /* Two consecutive 16-bit reads from register #1 (0x1f1/0x171) */
        !          6874:        (void) bus_space_read_2(chp->cmd_iot, chp->cmd_ioh, wdr_features);
        !          6875:        (void) bus_space_read_2(chp->cmd_iot, chp->cmd_ioh, wdr_features);
        !          6876:
        !          6877:        /* Followed by an 8-bit write of 0x3 to register #2 */
        !          6878:        bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wdr_seccnt, 0x03u);
        !          6879:
        !          6880:        /* Now we can read the required register */
        !          6881:        rv = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, reg);
        !          6882:
        !          6883:        /* Restore the real registers */
        !          6884:        bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wdr_seccnt, 0x83u);
        !          6885:
        !          6886:        splx(s);
        !          6887:
        !          6888:        return (rv);
        !          6889: }
        !          6890:
        !          6891: static __inline__ void
        !          6892: opti_write_config(struct channel_softc *chp, int reg, u_int8_t val)
        !          6893: {
        !          6894:        int s = splhigh();
        !          6895:
        !          6896:        /* Two consecutive 16-bit reads from register #1 (0x1f1/0x171) */
        !          6897:        (void) bus_space_read_2(chp->cmd_iot, chp->cmd_ioh, wdr_features);
        !          6898:        (void) bus_space_read_2(chp->cmd_iot, chp->cmd_ioh, wdr_features);
        !          6899:
        !          6900:        /* Followed by an 8-bit write of 0x3 to register #2 */
        !          6901:        bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wdr_seccnt, 0x03u);
        !          6902:
        !          6903:        /* Now we can write the required register */
        !          6904:        bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, reg, val);
        !          6905:
        !          6906:        /* Restore the real registers */
        !          6907:        bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wdr_seccnt, 0x83u);
        !          6908:
        !          6909:        splx(s);
        !          6910: }
        !          6911:
        !          6912: void
        !          6913: opti_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          6914: {
        !          6915:        struct pciide_channel *cp;
        !          6916:        bus_size_t cmdsize, ctlsize;
        !          6917:        pcireg_t interface;
        !          6918:        u_int8_t init_ctrl;
        !          6919:        int channel;
        !          6920:
        !          6921:        printf(": DMA");
        !          6922:        /*
        !          6923:         * XXXSCW:
        !          6924:         * There seem to be a couple of buggy revisions/implementations
        !          6925:         * of the OPTi pciide chipset. This kludge seems to fix one of
        !          6926:         * the reported problems (NetBSD PR/11644) but still fails for the
        !          6927:         * other (NetBSD PR/13151), although the latter may be due to other
        !          6928:         * issues too...
        !          6929:         */
        !          6930:        if (sc->sc_rev <= 0x12) {
        !          6931:                printf(" (disabled)");
        !          6932:                sc->sc_dma_ok = 0;
        !          6933:                sc->sc_wdcdev.cap = 0;
        !          6934:        } else {
        !          6935:                sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA32;
        !          6936:                pciide_mapreg_dma(sc, pa);
        !          6937:        }
        !          6938:
        !          6939:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_MODE;
        !          6940:        sc->sc_wdcdev.PIO_cap = 4;
        !          6941:        if (sc->sc_dma_ok) {
        !          6942:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
        !          6943:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          6944:                sc->sc_wdcdev.DMA_cap = 2;
        !          6945:        }
        !          6946:        sc->sc_wdcdev.set_modes = opti_setup_channel;
        !          6947:
        !          6948:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          6949:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          6950:
        !          6951:        init_ctrl = pciide_pci_read(sc->sc_pc, sc->sc_tag,
        !          6952:            OPTI_REG_INIT_CONTROL);
        !          6953:
        !          6954:        interface = PCI_INTERFACE(pa->pa_class);
        !          6955:
        !          6956:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          6957:
        !          6958:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          6959:                cp = &sc->pciide_channels[channel];
        !          6960:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          6961:                        continue;
        !          6962:                if (channel == 1 &&
        !          6963:                    (init_ctrl & OPTI_INIT_CONTROL_CH2_DISABLE) != 0) {
        !          6964:                        printf("%s: %s ignored (disabled)\n",
        !          6965:                            sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          6966:                        continue;
        !          6967:                }
        !          6968:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          6969:                if (cp->hw_ok == 0)
        !          6970:                        continue;
        !          6971:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          6972:                    pciide_pci_intr);
        !          6973:                if (cp->hw_ok == 0) {
        !          6974:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          6975:                        continue;
        !          6976:                }
        !          6977:                opti_setup_channel(&cp->wdc_channel);
        !          6978:        }
        !          6979: }
        !          6980:
        !          6981: void
        !          6982: opti_setup_channel(struct channel_softc *chp)
        !          6983: {
        !          6984:        struct ata_drive_datas *drvp;
        !          6985:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          6986:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          6987:        int drive, spd;
        !          6988:        int mode[2];
        !          6989:        u_int8_t rv, mr;
        !          6990:
        !          6991:        /*
        !          6992:         * The `Delay' and `Address Setup Time' fields of the
        !          6993:         * Miscellaneous Register are always zero initially.
        !          6994:         */
        !          6995:        mr = opti_read_config(chp, OPTI_REG_MISC) & ~OPTI_MISC_INDEX_MASK;
        !          6996:        mr &= ~(OPTI_MISC_DELAY_MASK |
        !          6997:                OPTI_MISC_ADDR_SETUP_MASK |
        !          6998:                OPTI_MISC_INDEX_MASK);
        !          6999:
        !          7000:        /* Prime the control register before setting timing values */
        !          7001:        opti_write_config(chp, OPTI_REG_CONTROL, OPTI_CONTROL_DISABLE);
        !          7002:
        !          7003:        /* Determine the clockrate of the PCIbus the chip is attached to */
        !          7004:        spd = (int) opti_read_config(chp, OPTI_REG_STRAP);
        !          7005:        spd &= OPTI_STRAP_PCI_SPEED_MASK;
        !          7006:
        !          7007:        /* setup DMA if needed */
        !          7008:        pciide_channel_dma_setup(cp);
        !          7009:
        !          7010:        for (drive = 0; drive < 2; drive++) {
        !          7011:                drvp = &chp->ch_drive[drive];
        !          7012:                /* If no drive, skip */
        !          7013:                if ((drvp->drive_flags & DRIVE) == 0) {
        !          7014:                        mode[drive] = -1;
        !          7015:                        continue;
        !          7016:                }
        !          7017:
        !          7018:                if ((drvp->drive_flags & DRIVE_DMA)) {
        !          7019:                        /*
        !          7020:                         * Timings will be used for both PIO and DMA,
        !          7021:                         * so adjust DMA mode if needed
        !          7022:                         */
        !          7023:                        if (drvp->PIO_mode > (drvp->DMA_mode + 2))
        !          7024:                                drvp->PIO_mode = drvp->DMA_mode + 2;
        !          7025:                        if (drvp->DMA_mode + 2 > (drvp->PIO_mode))
        !          7026:                                drvp->DMA_mode = (drvp->PIO_mode > 2) ?
        !          7027:                                    drvp->PIO_mode - 2 : 0;
        !          7028:                        if (drvp->DMA_mode == 0)
        !          7029:                                drvp->PIO_mode = 0;
        !          7030:
        !          7031:                        mode[drive] = drvp->DMA_mode + 5;
        !          7032:                } else
        !          7033:                        mode[drive] = drvp->PIO_mode;
        !          7034:
        !          7035:                if (drive && mode[0] >= 0 &&
        !          7036:                    (opti_tim_as[spd][mode[0]] != opti_tim_as[spd][mode[1]])) {
        !          7037:                        /*
        !          7038:                         * Can't have two drives using different values
        !          7039:                         * for `Address Setup Time'.
        !          7040:                         * Slow down the faster drive to compensate.
        !          7041:                         */
        !          7042:                        int d = (opti_tim_as[spd][mode[0]] >
        !          7043:                                 opti_tim_as[spd][mode[1]]) ?  0 : 1;
        !          7044:
        !          7045:                        mode[d] = mode[1-d];
        !          7046:                        chp->ch_drive[d].PIO_mode = chp->ch_drive[1-d].PIO_mode;
        !          7047:                        chp->ch_drive[d].DMA_mode = 0;
        !          7048:                        chp->ch_drive[d].drive_flags &= DRIVE_DMA;
        !          7049:                }
        !          7050:        }
        !          7051:
        !          7052:        for (drive = 0; drive < 2; drive++) {
        !          7053:                int m;
        !          7054:                if ((m = mode[drive]) < 0)
        !          7055:                        continue;
        !          7056:
        !          7057:                /* Set the Address Setup Time and select appropriate index */
        !          7058:                rv = opti_tim_as[spd][m] << OPTI_MISC_ADDR_SETUP_SHIFT;
        !          7059:                rv |= OPTI_MISC_INDEX(drive);
        !          7060:                opti_write_config(chp, OPTI_REG_MISC, mr | rv);
        !          7061:
        !          7062:                /* Set the pulse width and recovery timing parameters */
        !          7063:                rv  = opti_tim_cp[spd][m] << OPTI_PULSE_WIDTH_SHIFT;
        !          7064:                rv |= opti_tim_rt[spd][m] << OPTI_RECOVERY_TIME_SHIFT;
        !          7065:                opti_write_config(chp, OPTI_REG_READ_CYCLE_TIMING, rv);
        !          7066:                opti_write_config(chp, OPTI_REG_WRITE_CYCLE_TIMING, rv);
        !          7067:
        !          7068:                /* Set the Enhanced Mode register appropriately */
        !          7069:                rv = pciide_pci_read(sc->sc_pc, sc->sc_tag, OPTI_REG_ENH_MODE);
        !          7070:                rv &= ~OPTI_ENH_MODE_MASK(chp->channel, drive);
        !          7071:                rv |= OPTI_ENH_MODE(chp->channel, drive, opti_tim_em[m]);
        !          7072:                pciide_pci_write(sc->sc_pc, sc->sc_tag, OPTI_REG_ENH_MODE, rv);
        !          7073:        }
        !          7074:
        !          7075:        /* Finally, enable the timings */
        !          7076:        opti_write_config(chp, OPTI_REG_CONTROL, OPTI_CONTROL_ENABLE);
        !          7077:
        !          7078:        pciide_print_modes(cp);
        !          7079: }
        !          7080: #endif
        !          7081:
        !          7082: void
        !          7083: serverworks_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          7084: {
        !          7085:        struct pciide_channel *cp;
        !          7086:        pcireg_t interface = PCI_INTERFACE(pa->pa_class);
        !          7087:        pcitag_t pcib_tag;
        !          7088:        int channel;
        !          7089:        bus_size_t cmdsize, ctlsize;
        !          7090:
        !          7091:        printf(": DMA");
        !          7092:        pciide_mapreg_dma(sc, pa);
        !          7093:        printf("\n");
        !          7094:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          7095:            WDC_CAPABILITY_MODE;
        !          7096:
        !          7097:        if (sc->sc_dma_ok) {
        !          7098:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
        !          7099:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          7100:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          7101:        }
        !          7102:        sc->sc_wdcdev.PIO_cap = 4;
        !          7103:        sc->sc_wdcdev.DMA_cap = 2;
        !          7104:        switch (sc->sc_pp->ide_product) {
        !          7105:        case PCI_PRODUCT_RCC_OSB4_IDE:
        !          7106:                sc->sc_wdcdev.UDMA_cap = 2;
        !          7107:                break;
        !          7108:        case PCI_PRODUCT_RCC_CSB5_IDE:
        !          7109:                if (sc->sc_rev < 0x92)
        !          7110:                        sc->sc_wdcdev.UDMA_cap = 4;
        !          7111:                else
        !          7112:                        sc->sc_wdcdev.UDMA_cap = 5;
        !          7113:                break;
        !          7114:        case PCI_PRODUCT_RCC_CSB6_IDE:
        !          7115:                sc->sc_wdcdev.UDMA_cap = 4;
        !          7116:                break;
        !          7117:        case PCI_PRODUCT_RCC_CSB6_RAID_IDE:
        !          7118:                sc->sc_wdcdev.UDMA_cap = 5;
        !          7119:                break;
        !          7120:        }
        !          7121:
        !          7122:        sc->sc_wdcdev.set_modes = serverworks_setup_channel;
        !          7123:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          7124:        sc->sc_wdcdev.nchannels =
        !          7125:            (sc->sc_pp->ide_product == PCI_PRODUCT_RCC_CSB6_IDE ? 1 : 2);
        !          7126:
        !          7127:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          7128:                cp = &sc->pciide_channels[channel];
        !          7129:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          7130:                        continue;
        !          7131:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          7132:                    serverworks_pci_intr);
        !          7133:                if (cp->hw_ok == 0)
        !          7134:                        return;
        !          7135:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          7136:                if (cp->hw_ok == 0)
        !          7137:                        return;
        !          7138:                serverworks_setup_channel(&cp->wdc_channel);
        !          7139:        }
        !          7140:
        !          7141:        pcib_tag = pci_make_tag(pa->pa_pc, pa->pa_bus, pa->pa_device, 0);
        !          7142:        pci_conf_write(pa->pa_pc, pcib_tag, 0x64,
        !          7143:            (pci_conf_read(pa->pa_pc, pcib_tag, 0x64) & ~0x2000) | 0x4000);
        !          7144: }
        !          7145:
        !          7146: void
        !          7147: serverworks_setup_channel(struct channel_softc *chp)
        !          7148: {
        !          7149:        struct ata_drive_datas *drvp;
        !          7150:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          7151:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          7152:        int channel = chp->channel;
        !          7153:        int drive, unit;
        !          7154:        u_int32_t pio_time, dma_time, pio_mode, udma_mode;
        !          7155:        u_int32_t idedma_ctl;
        !          7156:        static const u_int8_t pio_modes[5] = {0x5d, 0x47, 0x34, 0x22, 0x20};
        !          7157:        static const u_int8_t dma_modes[3] = {0x77, 0x21, 0x20};
        !          7158:
        !          7159:        /* setup DMA if needed */
        !          7160:        pciide_channel_dma_setup(cp);
        !          7161:
        !          7162:        pio_time = pci_conf_read(sc->sc_pc, sc->sc_tag, 0x40);
        !          7163:        dma_time = pci_conf_read(sc->sc_pc, sc->sc_tag, 0x44);
        !          7164:        pio_mode = pci_conf_read(sc->sc_pc, sc->sc_tag, 0x48);
        !          7165:        udma_mode = pci_conf_read(sc->sc_pc, sc->sc_tag, 0x54);
        !          7166:
        !          7167:        pio_time &= ~(0xffff << (16 * channel));
        !          7168:        dma_time &= ~(0xffff << (16 * channel));
        !          7169:        pio_mode &= ~(0xff << (8 * channel + 16));
        !          7170:        udma_mode &= ~(0xff << (8 * channel + 16));
        !          7171:        udma_mode &= ~(3 << (2 * channel));
        !          7172:
        !          7173:        idedma_ctl = 0;
        !          7174:
        !          7175:        /* Per drive settings */
        !          7176:        for (drive = 0; drive < 2; drive++) {
        !          7177:                drvp = &chp->ch_drive[drive];
        !          7178:                /* If no drive, skip */
        !          7179:                if ((drvp->drive_flags & DRIVE) == 0)
        !          7180:                        continue;
        !          7181:                unit = drive + 2 * channel;
        !          7182:                /* add timing values, setup DMA if needed */
        !          7183:                pio_time |= pio_modes[drvp->PIO_mode] << (8 * (unit^1));
        !          7184:                pio_mode |= drvp->PIO_mode << (4 * unit + 16);
        !          7185:                if ((chp->wdc->cap & WDC_CAPABILITY_UDMA) &&
        !          7186:                    (drvp->drive_flags & DRIVE_UDMA)) {
        !          7187:                        /* use Ultra/DMA, check for 80-pin cable */
        !          7188:                        if (sc->sc_rev <= 0x92 && drvp->UDMA_mode > 2 &&
        !          7189:                            (PCI_PRODUCT(pci_conf_read(sc->sc_pc, sc->sc_tag,
        !          7190:                            PCI_SUBSYS_ID_REG)) &
        !          7191:                            (1 << (14 + channel))) == 0) {
        !          7192:                                WDCDEBUG_PRINT(("%s(%s:%d:%d): 80-wire "
        !          7193:                                    "cable not detected\n", drvp->drive_name,
        !          7194:                                    sc->sc_wdcdev.sc_dev.dv_xname,
        !          7195:                                    channel, drive), DEBUG_PROBE);
        !          7196:                                drvp->UDMA_mode = 2;
        !          7197:                        }
        !          7198:                        dma_time |= dma_modes[drvp->DMA_mode] << (8 * (unit^1));
        !          7199:                        udma_mode |= drvp->UDMA_mode << (4 * unit + 16);
        !          7200:                        udma_mode |= 1 << unit;
        !          7201:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          7202:                } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA) &&
        !          7203:                    (drvp->drive_flags & DRIVE_DMA)) {
        !          7204:                        /* use Multiword DMA */
        !          7205:                        drvp->drive_flags &= ~DRIVE_UDMA;
        !          7206:                        dma_time |= dma_modes[drvp->DMA_mode] << (8 * (unit^1));
        !          7207:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          7208:                } else {
        !          7209:                        /* PIO only */
        !          7210:                        drvp->drive_flags &= ~(DRIVE_UDMA | DRIVE_DMA);
        !          7211:                }
        !          7212:        }
        !          7213:
        !          7214:        pci_conf_write(sc->sc_pc, sc->sc_tag, 0x40, pio_time);
        !          7215:        pci_conf_write(sc->sc_pc, sc->sc_tag, 0x44, dma_time);
        !          7216:        if (sc->sc_pp->ide_product != PCI_PRODUCT_RCC_OSB4_IDE)
        !          7217:                pci_conf_write(sc->sc_pc, sc->sc_tag, 0x48, pio_mode);
        !          7218:        pci_conf_write(sc->sc_pc, sc->sc_tag, 0x54, udma_mode);
        !          7219:
        !          7220:        if (idedma_ctl != 0) {
        !          7221:                /* Add software bits in status register */
        !          7222:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          7223:                    IDEDMA_CTL(channel), idedma_ctl);
        !          7224:        }
        !          7225:        pciide_print_modes(cp);
        !          7226: }
        !          7227:
        !          7228: int
        !          7229: serverworks_pci_intr(void *arg)
        !          7230: {
        !          7231:        struct pciide_softc *sc = arg;
        !          7232:        struct pciide_channel *cp;
        !          7233:        struct channel_softc *wdc_cp;
        !          7234:        int rv = 0;
        !          7235:        int dmastat, i, crv;
        !          7236:
        !          7237:        for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {
        !          7238:                dmastat = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          7239:                    IDEDMA_CTL(i));
        !          7240:                if ((dmastat & (IDEDMA_CTL_ACT | IDEDMA_CTL_INTR)) !=
        !          7241:                    IDEDMA_CTL_INTR)
        !          7242:                        continue;
        !          7243:                cp = &sc->pciide_channels[i];
        !          7244:                wdc_cp = &cp->wdc_channel;
        !          7245:                crv = wdcintr(wdc_cp);
        !          7246:                if (crv == 0) {
        !          7247:                        printf("%s:%d: bogus intr\n",
        !          7248:                            sc->sc_wdcdev.sc_dev.dv_xname, i);
        !          7249:                        bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          7250:                            IDEDMA_CTL(i), dmastat);
        !          7251:                } else
        !          7252:                        rv = 1;
        !          7253:        }
        !          7254:        return (rv);
        !          7255: }
        !          7256:
        !          7257: void
        !          7258: svwsata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          7259: {
        !          7260:        struct pciide_channel *cp;
        !          7261:        pci_intr_handle_t intrhandle;
        !          7262:        const char *intrstr;
        !          7263:        int channel;
        !          7264:        struct pciide_svwsata *ss;
        !          7265:
        !          7266:        /* Allocate memory for private data */
        !          7267:        sc->sc_cookie = malloc(sizeof(struct pciide_svwsata), M_DEVBUF,
        !          7268:            M_NOWAIT);
        !          7269:        ss = sc->sc_cookie;
        !          7270:        bzero(ss, sizeof(*ss));
        !          7271:
        !          7272:        /* The 4-port version has a dummy second function. */
        !          7273:        if (pci_conf_read(sc->sc_pc, sc->sc_tag,
        !          7274:            PCI_MAPREG_START + 0x14) == 0) {
        !          7275:                printf("\n");
        !          7276:                return;
        !          7277:        }
        !          7278:
        !          7279:        if (pci_mapreg_map(pa, PCI_MAPREG_START + 0x14,
        !          7280:            PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
        !          7281:            &ss->ba5_st, &ss->ba5_sh, NULL, NULL, 0) != 0) {
        !          7282:                printf(": unable to map BA5 register space\n");
        !          7283:                return;
        !          7284:        }
        !          7285:
        !          7286:        printf(": DMA");
        !          7287:        svwsata_mapreg_dma(sc, pa);
        !          7288:        printf("\n");
        !          7289:
        !          7290:        if (sc->sc_dma_ok) {
        !          7291:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA |
        !          7292:                    WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
        !          7293:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          7294:        }
        !          7295:        sc->sc_wdcdev.PIO_cap = 4;
        !          7296:        sc->sc_wdcdev.DMA_cap = 2;
        !          7297:        sc->sc_wdcdev.UDMA_cap = 6;
        !          7298:
        !          7299:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          7300:        sc->sc_wdcdev.nchannels = 4;
        !          7301:        sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          7302:            WDC_CAPABILITY_MODE | WDC_CAPABILITY_SATA;
        !          7303:        sc->sc_wdcdev.set_modes = sata_setup_channel;
        !          7304:
        !          7305:        /* We can use SControl and SStatus to probe for drives. */
        !          7306:        sc->sc_wdcdev.drv_probe = svwsata_drv_probe;
        !          7307:
        !          7308:        /* Map and establish the interrupt handler. */
        !          7309:        if(pci_intr_map(pa, &intrhandle) != 0) {
        !          7310:                printf("%s: couldn't map native-PCI interrupt\n",
        !          7311:                    sc->sc_wdcdev.sc_dev.dv_xname);
        !          7312:                return;
        !          7313:        }
        !          7314:        intrstr = pci_intr_string(pa->pa_pc, intrhandle);
        !          7315:        sc->sc_pci_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO,
        !          7316:            pciide_pci_intr, sc, sc->sc_wdcdev.sc_dev.dv_xname);
        !          7317:        if (sc->sc_pci_ih != NULL) {
        !          7318:                printf("%s: using %s for native-PCI interrupt\n",
        !          7319:                    sc->sc_wdcdev.sc_dev.dv_xname,
        !          7320:                    intrstr ? intrstr : "unknown interrupt");
        !          7321:        } else {
        !          7322:                printf("%s: couldn't establish native-PCI interrupt",
        !          7323:                    sc->sc_wdcdev.sc_dev.dv_xname);
        !          7324:                if (intrstr != NULL)
        !          7325:                        printf(" at %s", intrstr);
        !          7326:                printf("\n");
        !          7327:                return;
        !          7328:        }
        !          7329:
        !          7330:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          7331:                cp = &sc->pciide_channels[channel];
        !          7332:                if (pciide_chansetup(sc, channel, 0) == 0)
        !          7333:                        continue;
        !          7334:                svwsata_mapchan(cp);
        !          7335:                sata_setup_channel(&cp->wdc_channel);
        !          7336:        }
        !          7337: }
        !          7338:
        !          7339: void
        !          7340: svwsata_mapreg_dma(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          7341: {
        !          7342:        struct pciide_svwsata *ss = sc->sc_cookie;
        !          7343:
        !          7344:        sc->sc_wdcdev.dma_arg = sc;
        !          7345:        sc->sc_wdcdev.dma_init = pciide_dma_init;
        !          7346:        sc->sc_wdcdev.dma_start = pciide_dma_start;
        !          7347:        sc->sc_wdcdev.dma_finish = pciide_dma_finish;
        !          7348:
        !          7349:        /* XXX */
        !          7350:        sc->sc_dma_iot = ss->ba5_st;
        !          7351:        sc->sc_dma_ioh = ss->ba5_sh;
        !          7352:
        !          7353:        sc->sc_dmacmd_read = svwsata_dmacmd_read;
        !          7354:        sc->sc_dmacmd_write = svwsata_dmacmd_write;
        !          7355:        sc->sc_dmactl_read = svwsata_dmactl_read;
        !          7356:        sc->sc_dmactl_write = svwsata_dmactl_write;
        !          7357:        sc->sc_dmatbl_write = svwsata_dmatbl_write;
        !          7358:
        !          7359:        /* DMA registers all set up! */
        !          7360:        sc->sc_dmat = pa->pa_dmat;
        !          7361:        sc->sc_dma_ok = 1;
        !          7362: }
        !          7363:
        !          7364: u_int8_t
        !          7365: svwsata_dmacmd_read(struct pciide_softc *sc, int chan)
        !          7366: {
        !          7367:        return (bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          7368:            (chan << 8) + SVWSATA_DMA + IDEDMA_CMD(0)));
        !          7369: }
        !          7370:
        !          7371: void
        !          7372: svwsata_dmacmd_write(struct pciide_softc *sc, int chan, u_int8_t val)
        !          7373: {
        !          7374:        bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          7375:            (chan << 8) + SVWSATA_DMA + IDEDMA_CMD(0), val);
        !          7376: }
        !          7377:
        !          7378: u_int8_t
        !          7379: svwsata_dmactl_read(struct pciide_softc *sc, int chan)
        !          7380: {
        !          7381:        return (bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          7382:            (chan << 8) + SVWSATA_DMA + IDEDMA_CTL(0)));
        !          7383: }
        !          7384:
        !          7385: void
        !          7386: svwsata_dmactl_write(struct pciide_softc *sc, int chan, u_int8_t val)
        !          7387: {
        !          7388:        bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          7389:            (chan << 8) + SVWSATA_DMA + IDEDMA_CTL(0), val);
        !          7390: }
        !          7391:
        !          7392: void
        !          7393: svwsata_dmatbl_write(struct pciide_softc *sc, int chan, u_int32_t val)
        !          7394: {
        !          7395:        bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          7396:            (chan << 8) + SVWSATA_DMA + IDEDMA_TBL(0), val);
        !          7397: }
        !          7398:
        !          7399: void
        !          7400: svwsata_mapchan(struct pciide_channel *cp)
        !          7401: {
        !          7402:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          7403:        struct channel_softc *wdc_cp = &cp->wdc_channel;
        !          7404:        struct pciide_svwsata *ss = sc->sc_cookie;
        !          7405:
        !          7406:        cp->compat = 0;
        !          7407:        cp->ih = sc->sc_pci_ih;
        !          7408:
        !          7409:        if (bus_space_subregion(ss->ba5_st, ss->ba5_sh,
        !          7410:                (wdc_cp->channel << 8) + SVWSATA_TF0,
        !          7411:                SVWSATA_TF8 - SVWSATA_TF0, &wdc_cp->cmd_ioh) != 0) {
        !          7412:                printf("%s: couldn't map %s cmd regs\n",
        !          7413:                       sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          7414:                return;
        !          7415:        }
        !          7416:        if (bus_space_subregion(ss->ba5_st, ss->ba5_sh,
        !          7417:                (wdc_cp->channel << 8) + SVWSATA_TF8, 4,
        !          7418:                &wdc_cp->ctl_ioh) != 0) {
        !          7419:                printf("%s: couldn't map %s ctl regs\n",
        !          7420:                       sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          7421:                return;
        !          7422:        }
        !          7423:        wdc_cp->cmd_iot = wdc_cp->ctl_iot = ss->ba5_st;
        !          7424:        wdc_cp->_vtbl = &wdc_svwsata_vtbl;
        !          7425:        wdcattach(wdc_cp);
        !          7426: }
        !          7427:
        !          7428: void
        !          7429: svwsata_drv_probe(struct channel_softc *chp)
        !          7430: {
        !          7431:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          7432:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          7433:        struct pciide_svwsata *ss = sc->sc_cookie;
        !          7434:        int channel = chp->channel;
        !          7435:        uint32_t scontrol, sstatus;
        !          7436:        uint8_t scnt, sn, cl, ch;
        !          7437:        int i, s;
        !          7438:
        !          7439:        /* XXX This should be done by other code. */
        !          7440:        for (i = 0; i < 2; i++) {
        !          7441:                chp->ch_drive[i].chnl_softc = chp;
        !          7442:                chp->ch_drive[i].drive = i;
        !          7443:        }
        !          7444:
        !          7445:        /*
        !          7446:         * Request communication initialization sequence, any speed.
        !          7447:         * Performing this is the equivalent of an ATA Reset.
        !          7448:         */
        !          7449:        scontrol = SControl_DET_INIT | SControl_SPD_ANY;
        !          7450:
        !          7451:        /*
        !          7452:         * XXX We don't yet support SATA power management; disable all
        !          7453:         * power management state transitions.
        !          7454:         */
        !          7455:        scontrol |= SControl_IPM_NONE;
        !          7456:
        !          7457:        bus_space_write_4(ss->ba5_st, ss->ba5_sh,
        !          7458:            (channel << 8) + SVWSATA_SCONTROL, scontrol);
        !          7459:        delay(50 * 1000);
        !          7460:        scontrol &= ~SControl_DET_INIT;
        !          7461:        bus_space_write_4(ss->ba5_st, ss->ba5_sh,
        !          7462:            (channel << 8) + SVWSATA_SCONTROL, scontrol);
        !          7463:        delay(50 * 1000);
        !          7464:
        !          7465:        sstatus = bus_space_read_4(ss->ba5_st, ss->ba5_sh,
        !          7466:            (channel << 8) + SVWSATA_SSTATUS);
        !          7467: #if 0
        !          7468:        printf("%s: port %d: SStatus=0x%08x, SControl=0x%08x\n",
        !          7469:            sc->sc_wdcdev.sc_dev.dv_xname, chp->channel, sstatus,
        !          7470:            bus_space_read_4(ss->ba5_st, ss->ba5_sh,
        !          7471:                (channel << 8) + SVWSATA_SSTATUS));
        !          7472: #endif
        !          7473:        switch (sstatus & SStatus_DET_mask) {
        !          7474:        case SStatus_DET_NODEV:
        !          7475:                /* No device; be silent. */
        !          7476:                break;
        !          7477:
        !          7478:        case SStatus_DET_DEV_NE:
        !          7479:                printf("%s: port %d: device connected, but "
        !          7480:                    "communication not established\n",
        !          7481:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel);
        !          7482:                break;
        !          7483:
        !          7484:        case SStatus_DET_OFFLINE:
        !          7485:                printf("%s: port %d: PHY offline\n",
        !          7486:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel);
        !          7487:                break;
        !          7488:
        !          7489:        case SStatus_DET_DEV:
        !          7490:                /*
        !          7491:                 * XXX ATAPI detection doesn't currently work.  Don't
        !          7492:                 * XXX know why.  But, it's not like the standard method
        !          7493:                 * XXX can detect an ATAPI device connected via a SATA/PATA
        !          7494:                 * XXX bridge, so at least this is no worse.  --thorpej
        !          7495:                 */
        !          7496:                if (chp->_vtbl != NULL)
        !          7497:                        CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (0 << 4));
        !          7498:                else
        !          7499:                        bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
        !          7500:                            wdr_sdh & _WDC_REGMASK, WDSD_IBM | (0 << 4));
        !          7501:                delay(10);      /* 400ns delay */
        !          7502:                /* Save register contents. */
        !          7503:                if (chp->_vtbl != NULL) {
        !          7504:                        scnt = CHP_READ_REG(chp, wdr_seccnt);
        !          7505:                        sn = CHP_READ_REG(chp, wdr_sector);
        !          7506:                        cl = CHP_READ_REG(chp, wdr_cyl_lo);
        !          7507:                        ch = CHP_READ_REG(chp, wdr_cyl_hi);
        !          7508:                } else {
        !          7509:                        scnt = bus_space_read_1(chp->cmd_iot,
        !          7510:                            chp->cmd_ioh, wdr_seccnt & _WDC_REGMASK);
        !          7511:                        sn = bus_space_read_1(chp->cmd_iot,
        !          7512:                            chp->cmd_ioh, wdr_sector & _WDC_REGMASK);
        !          7513:                        cl = bus_space_read_1(chp->cmd_iot,
        !          7514:                            chp->cmd_ioh, wdr_cyl_lo & _WDC_REGMASK);
        !          7515:                        ch = bus_space_read_1(chp->cmd_iot,
        !          7516:                            chp->cmd_ioh, wdr_cyl_hi & _WDC_REGMASK);
        !          7517:                }
        !          7518: #if 0
        !          7519:                printf("%s: port %d: scnt=0x%x sn=0x%x cl=0x%x ch=0x%x\n",
        !          7520:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel,
        !          7521:                    scnt, sn, cl, ch);
        !          7522: #endif
        !          7523:                /*
        !          7524:                 * scnt and sn are supposed to be 0x1 for ATAPI, but in some
        !          7525:                 * cases we get wrong values here, so ignore it.
        !          7526:                 */
        !          7527:                s = splbio();
        !          7528:                if (cl == 0x14 && ch == 0xeb)
        !          7529:                        chp->ch_drive[0].drive_flags |= DRIVE_ATAPI;
        !          7530:                else
        !          7531:                        chp->ch_drive[0].drive_flags |= DRIVE_ATA;
        !          7532:                splx(s);
        !          7533:
        !          7534:                printf("%s: port %d: device present",
        !          7535:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel);
        !          7536:                switch ((sstatus & SStatus_SPD_mask) >> SStatus_SPD_shift) {
        !          7537:                case 1:
        !          7538:                        printf(", speed: 1.5Gb/s");
        !          7539:                        break;
        !          7540:                case 2:
        !          7541:                        printf(", speed: 3.0Gb/s");
        !          7542:                        break;
        !          7543:                }
        !          7544:                printf("\n");
        !          7545:                break;
        !          7546:
        !          7547:        default:
        !          7548:                printf("%s: port %d: unknown SStatus: 0x%08x\n",
        !          7549:                    sc->sc_wdcdev.sc_dev.dv_xname, chp->channel, sstatus);
        !          7550:        }
        !          7551: }
        !          7552:
        !          7553: u_int8_t
        !          7554: svwsata_read_reg(struct channel_softc *chp, enum wdc_regs reg)
        !          7555: {
        !          7556:        if (reg & _WDC_AUX) {
        !          7557:                return (bus_space_read_4(chp->ctl_iot, chp->ctl_ioh,
        !          7558:                    (reg & _WDC_REGMASK) << 2));
        !          7559:        } else {
        !          7560:                return (bus_space_read_4(chp->cmd_iot, chp->cmd_ioh,
        !          7561:                    (reg & _WDC_REGMASK) << 2));
        !          7562:        }
        !          7563: }
        !          7564:
        !          7565: void
        !          7566: svwsata_write_reg(struct channel_softc *chp, enum wdc_regs reg, u_int8_t val)
        !          7567: {
        !          7568:        if (reg & _WDC_AUX) {
        !          7569:                bus_space_write_4(chp->ctl_iot, chp->ctl_ioh,
        !          7570:                    (reg & _WDC_REGMASK) << 2, val);
        !          7571:        } else {
        !          7572:                bus_space_write_4(chp->cmd_iot, chp->cmd_ioh,
        !          7573:                    (reg & _WDC_REGMASK) << 2, val);
        !          7574:        }
        !          7575: }
        !          7576:
        !          7577: void
        !          7578: svwsata_lba48_write_reg(struct channel_softc *chp, enum wdc_regs reg, u_int16_t val)
        !          7579: {
        !          7580:        if (reg & _WDC_AUX) {
        !          7581:                bus_space_write_4(chp->ctl_iot, chp->ctl_ioh,
        !          7582:                    (reg & _WDC_REGMASK) << 2, val);
        !          7583:        } else {
        !          7584:                bus_space_write_4(chp->cmd_iot, chp->cmd_ioh,
        !          7585:                    (reg & _WDC_REGMASK) << 2, val);
        !          7586:        }
        !          7587: }
        !          7588:
        !          7589: #define        ACARD_IS_850(sc) \
        !          7590:        ((sc)->sc_pp->ide_product == PCI_PRODUCT_ACARD_ATP850U)
        !          7591:
        !          7592: void
        !          7593: acard_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          7594: {
        !          7595:        struct pciide_channel *cp;
        !          7596:        int i;
        !          7597:        pcireg_t interface;
        !          7598:        bus_size_t cmdsize, ctlsize;
        !          7599:
        !          7600:        /*
        !          7601:         * when the chip is in native mode it identifies itself as a
        !          7602:         * 'misc mass storage'. Fake interface in this case.
        !          7603:         */
        !          7604:        if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_IDE) {
        !          7605:                interface = PCI_INTERFACE(pa->pa_class);
        !          7606:        } else {
        !          7607:                interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
        !          7608:                    PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
        !          7609:        }
        !          7610:
        !          7611:        printf(": DMA");
        !          7612:        pciide_mapreg_dma(sc, pa);
        !          7613:        printf("\n");
        !          7614:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          7615:            WDC_CAPABILITY_MODE;
        !          7616:
        !          7617:        if (sc->sc_dma_ok) {
        !          7618:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
        !          7619:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          7620:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          7621:        }
        !          7622:        sc->sc_wdcdev.PIO_cap = 4;
        !          7623:        sc->sc_wdcdev.DMA_cap = 2;
        !          7624:        switch (sc->sc_pp->ide_product) {
        !          7625:        case PCI_PRODUCT_ACARD_ATP850U:
        !          7626:                sc->sc_wdcdev.UDMA_cap = 2;
        !          7627:                break;
        !          7628:        case PCI_PRODUCT_ACARD_ATP860:
        !          7629:        case PCI_PRODUCT_ACARD_ATP860A:
        !          7630:                sc->sc_wdcdev.UDMA_cap = 4;
        !          7631:                break;
        !          7632:        case PCI_PRODUCT_ACARD_ATP865A:
        !          7633:        case PCI_PRODUCT_ACARD_ATP865R:
        !          7634:                sc->sc_wdcdev.UDMA_cap = 6;
        !          7635:                break;
        !          7636:        }
        !          7637:
        !          7638:        sc->sc_wdcdev.set_modes = acard_setup_channel;
        !          7639:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          7640:        sc->sc_wdcdev.nchannels = 2;
        !          7641:
        !          7642:        for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {
        !          7643:                cp = &sc->pciide_channels[i];
        !          7644:                if (pciide_chansetup(sc, i, interface) == 0)
        !          7645:                        continue;
        !          7646:                if (interface & PCIIDE_INTERFACE_PCI(i)) {
        !          7647:                        cp->hw_ok = pciide_mapregs_native(pa, cp, &cmdsize,
        !          7648:                            &ctlsize, pciide_pci_intr);
        !          7649:                } else {
        !          7650:                        cp->hw_ok = pciide_mapregs_compat(pa, cp, i,
        !          7651:                            &cmdsize, &ctlsize);
        !          7652:                }
        !          7653:                if (cp->hw_ok == 0)
        !          7654:                        return;
        !          7655:                cp->wdc_channel.data32iot = cp->wdc_channel.cmd_iot;
        !          7656:                cp->wdc_channel.data32ioh = cp->wdc_channel.cmd_ioh;
        !          7657:                wdcattach(&cp->wdc_channel);
        !          7658:                acard_setup_channel(&cp->wdc_channel);
        !          7659:        }
        !          7660:        if (!ACARD_IS_850(sc)) {
        !          7661:                u_int32_t reg;
        !          7662:                reg = pci_conf_read(sc->sc_pc, sc->sc_tag, ATP8x0_CTRL);
        !          7663:                reg &= ~ATP860_CTRL_INT;
        !          7664:                pci_conf_write(sc->sc_pc, sc->sc_tag, ATP8x0_CTRL, reg);
        !          7665:        }
        !          7666: }
        !          7667:
        !          7668: void
        !          7669: acard_setup_channel(struct channel_softc *chp)
        !          7670: {
        !          7671:        struct ata_drive_datas *drvp;
        !          7672:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          7673:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          7674:        int channel = chp->channel;
        !          7675:        int drive;
        !          7676:        u_int32_t idetime, udma_mode;
        !          7677:        u_int32_t idedma_ctl;
        !          7678:
        !          7679:        /* setup DMA if needed */
        !          7680:        pciide_channel_dma_setup(cp);
        !          7681:
        !          7682:        if (ACARD_IS_850(sc)) {
        !          7683:                idetime = 0;
        !          7684:                udma_mode = pci_conf_read(sc->sc_pc, sc->sc_tag, ATP850_UDMA);
        !          7685:                udma_mode &= ~ATP850_UDMA_MASK(channel);
        !          7686:        } else {
        !          7687:                idetime = pci_conf_read(sc->sc_pc, sc->sc_tag, ATP860_IDETIME);
        !          7688:                idetime &= ~ATP860_SETTIME_MASK(channel);
        !          7689:                udma_mode = pci_conf_read(sc->sc_pc, sc->sc_tag, ATP860_UDMA);
        !          7690:                udma_mode &= ~ATP860_UDMA_MASK(channel);
        !          7691:        }
        !          7692:
        !          7693:        idedma_ctl = 0;
        !          7694:
        !          7695:        /* Per drive settings */
        !          7696:        for (drive = 0; drive < 2; drive++) {
        !          7697:                drvp = &chp->ch_drive[drive];
        !          7698:                /* If no drive, skip */
        !          7699:                if ((drvp->drive_flags & DRIVE) == 0)
        !          7700:                        continue;
        !          7701:                /* add timing values, setup DMA if needed */
        !          7702:                if ((chp->wdc->cap & WDC_CAPABILITY_UDMA) &&
        !          7703:                    (drvp->drive_flags & DRIVE_UDMA)) {
        !          7704:                        /* use Ultra/DMA */
        !          7705:                        if (ACARD_IS_850(sc)) {
        !          7706:                                idetime |= ATP850_SETTIME(drive,
        !          7707:                                    acard_act_udma[drvp->UDMA_mode],
        !          7708:                                    acard_rec_udma[drvp->UDMA_mode]);
        !          7709:                                udma_mode |= ATP850_UDMA_MODE(channel, drive,
        !          7710:                                    acard_udma_conf[drvp->UDMA_mode]);
        !          7711:                        } else {
        !          7712:                                idetime |= ATP860_SETTIME(channel, drive,
        !          7713:                                    acard_act_udma[drvp->UDMA_mode],
        !          7714:                                    acard_rec_udma[drvp->UDMA_mode]);
        !          7715:                                udma_mode |= ATP860_UDMA_MODE(channel, drive,
        !          7716:                                    acard_udma_conf[drvp->UDMA_mode]);
        !          7717:                        }
        !          7718:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          7719:                } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA) &&
        !          7720:                    (drvp->drive_flags & DRIVE_DMA)) {
        !          7721:                        /* use Multiword DMA */
        !          7722:                        drvp->drive_flags &= ~DRIVE_UDMA;
        !          7723:                        if (ACARD_IS_850(sc)) {
        !          7724:                                idetime |= ATP850_SETTIME(drive,
        !          7725:                                    acard_act_dma[drvp->DMA_mode],
        !          7726:                                    acard_rec_dma[drvp->DMA_mode]);
        !          7727:                        } else {
        !          7728:                                idetime |= ATP860_SETTIME(channel, drive,
        !          7729:                                    acard_act_dma[drvp->DMA_mode],
        !          7730:                                    acard_rec_dma[drvp->DMA_mode]);
        !          7731:                        }
        !          7732:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          7733:                } else {
        !          7734:                        /* PIO only */
        !          7735:                        drvp->drive_flags &= ~(DRIVE_UDMA | DRIVE_DMA);
        !          7736:                        if (ACARD_IS_850(sc)) {
        !          7737:                                idetime |= ATP850_SETTIME(drive,
        !          7738:                                    acard_act_pio[drvp->PIO_mode],
        !          7739:                                    acard_rec_pio[drvp->PIO_mode]);
        !          7740:                        } else {
        !          7741:                                idetime |= ATP860_SETTIME(channel, drive,
        !          7742:                                    acard_act_pio[drvp->PIO_mode],
        !          7743:                                    acard_rec_pio[drvp->PIO_mode]);
        !          7744:                        }
        !          7745:                pci_conf_write(sc->sc_pc, sc->sc_tag, ATP8x0_CTRL,
        !          7746:                    pci_conf_read(sc->sc_pc, sc->sc_tag, ATP8x0_CTRL)
        !          7747:                    | ATP8x0_CTRL_EN(channel));
        !          7748:                }
        !          7749:        }
        !          7750:
        !          7751:        if (idedma_ctl != 0) {
        !          7752:                /* Add software bits in status register */
        !          7753:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          7754:                    IDEDMA_CTL(channel), idedma_ctl);
        !          7755:        }
        !          7756:        pciide_print_modes(cp);
        !          7757:
        !          7758:        if (ACARD_IS_850(sc)) {
        !          7759:                pci_conf_write(sc->sc_pc, sc->sc_tag,
        !          7760:                    ATP850_IDETIME(channel), idetime);
        !          7761:                pci_conf_write(sc->sc_pc, sc->sc_tag, ATP850_UDMA, udma_mode);
        !          7762:        } else {
        !          7763:                pci_conf_write(sc->sc_pc, sc->sc_tag, ATP860_IDETIME, idetime);
        !          7764:                pci_conf_write(sc->sc_pc, sc->sc_tag, ATP860_UDMA, udma_mode);
        !          7765:        }
        !          7766: }
        !          7767:
        !          7768: void
        !          7769: nforce_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          7770: {
        !          7771:        struct pciide_channel *cp;
        !          7772:        int channel;
        !          7773:        pcireg_t interface = PCI_INTERFACE(pa->pa_class);
        !          7774:        bus_size_t cmdsize, ctlsize;
        !          7775:        u_int32_t conf;
        !          7776:
        !          7777:        conf = pci_conf_read(sc->sc_pc, sc->sc_tag, NFORCE_CONF);
        !          7778:        WDCDEBUG_PRINT(("%s: conf register 0x%x\n",
        !          7779:            sc->sc_wdcdev.sc_dev.dv_xname, conf), DEBUG_PROBE);
        !          7780:
        !          7781:        printf(": DMA");
        !          7782:        pciide_mapreg_dma(sc, pa);
        !          7783:
        !          7784:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          7785:            WDC_CAPABILITY_MODE;
        !          7786:        if (sc->sc_dma_ok) {
        !          7787:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
        !          7788:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          7789:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          7790:        }
        !          7791:        sc->sc_wdcdev.PIO_cap = 4;
        !          7792:        sc->sc_wdcdev.DMA_cap = 2;
        !          7793:        switch (sc->sc_pp->ide_product) {
        !          7794:        case PCI_PRODUCT_NVIDIA_NFORCE_IDE:
        !          7795:                sc->sc_wdcdev.UDMA_cap = 5;
        !          7796:                break;
        !          7797:        default:
        !          7798:                sc->sc_wdcdev.UDMA_cap = 6;
        !          7799:        }
        !          7800:        sc->sc_wdcdev.set_modes = nforce_setup_channel;
        !          7801:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          7802:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          7803:
        !          7804:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          7805:
        !          7806:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          7807:                cp = &sc->pciide_channels[channel];
        !          7808:
        !          7809:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          7810:                        continue;
        !          7811:
        !          7812:                if ((conf & NFORCE_CHAN_EN(channel)) == 0) {
        !          7813:                        printf("%s: %s ignored (disabled)\n",
        !          7814:                            sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          7815:                        continue;
        !          7816:                }
        !          7817:
        !          7818:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          7819:                if (cp->hw_ok == 0)
        !          7820:                        continue;
        !          7821:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          7822:                    nforce_pci_intr);
        !          7823:                if (cp->hw_ok == 0) {
        !          7824:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          7825:                        continue;
        !          7826:                }
        !          7827:
        !          7828:                if (pciide_chan_candisable(cp)) {
        !          7829:                        conf &= ~NFORCE_CHAN_EN(channel);
        !          7830:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          7831:                        continue;
        !          7832:                }
        !          7833:
        !          7834:                sc->sc_wdcdev.set_modes(&cp->wdc_channel);
        !          7835:        }
        !          7836:        WDCDEBUG_PRINT(("%s: new conf register 0x%x\n",
        !          7837:            sc->sc_wdcdev.sc_dev.dv_xname, conf), DEBUG_PROBE);
        !          7838:        pci_conf_write(sc->sc_pc, sc->sc_tag, NFORCE_CONF, conf);
        !          7839: }
        !          7840:
        !          7841: void
        !          7842: nforce_setup_channel(struct channel_softc *chp)
        !          7843: {
        !          7844:        struct ata_drive_datas *drvp;
        !          7845:        int drive, mode;
        !          7846:        u_int32_t idedma_ctl;
        !          7847:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          7848:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          7849:        int channel = chp->channel;
        !          7850:        u_int32_t conf, piodmatim, piotim, udmatim;
        !          7851:
        !          7852:        conf = pci_conf_read(sc->sc_pc, sc->sc_tag, NFORCE_CONF);
        !          7853:        piodmatim = pci_conf_read(sc->sc_pc, sc->sc_tag, NFORCE_PIODMATIM);
        !          7854:        piotim = pci_conf_read(sc->sc_pc, sc->sc_tag, NFORCE_PIOTIM);
        !          7855:        udmatim = pci_conf_read(sc->sc_pc, sc->sc_tag, NFORCE_UDMATIM);
        !          7856:        WDCDEBUG_PRINT(("%s: %s old timing values: piodmatim=0x%x, "
        !          7857:            "piotim=0x%x, udmatim=0x%x\n", sc->sc_wdcdev.sc_dev.dv_xname,
        !          7858:            cp->name, piodmatim, piotim, udmatim), DEBUG_PROBE);
        !          7859:
        !          7860:        /* Setup DMA if needed */
        !          7861:        pciide_channel_dma_setup(cp);
        !          7862:
        !          7863:        /* Clear all bits for this channel */
        !          7864:        idedma_ctl = 0;
        !          7865:        piodmatim &= ~NFORCE_PIODMATIM_MASK(channel);
        !          7866:        udmatim &= ~NFORCE_UDMATIM_MASK(channel);
        !          7867:
        !          7868:        /* Per channel settings */
        !          7869:        for (drive = 0; drive < 2; drive++) {
        !          7870:                drvp = &chp->ch_drive[drive];
        !          7871:
        !          7872:                /* If no drive, skip */
        !          7873:                if ((drvp->drive_flags & DRIVE) == 0)
        !          7874:                        continue;
        !          7875:
        !          7876:                if ((chp->wdc->cap & WDC_CAPABILITY_UDMA) != 0 &&
        !          7877:                    (drvp->drive_flags & DRIVE_UDMA) != 0) {
        !          7878:                        /* Setup UltraDMA mode */
        !          7879:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          7880:
        !          7881:                        udmatim |= NFORCE_UDMATIM_SET(channel, drive,
        !          7882:                            nforce_udma[drvp->UDMA_mode]) |
        !          7883:                            NFORCE_UDMA_EN(channel, drive) |
        !          7884:                            NFORCE_UDMA_ENM(channel, drive);
        !          7885:
        !          7886:                        mode = drvp->PIO_mode;
        !          7887:                } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA) != 0 &&
        !          7888:                    (drvp->drive_flags & DRIVE_DMA) != 0) {
        !          7889:                        /* Setup multiword DMA mode */
        !          7890:                        drvp->drive_flags &= ~DRIVE_UDMA;
        !          7891:
        !          7892:                        /* mode = min(pio, dma + 2) */
        !          7893:                        if (drvp->PIO_mode <= (drvp->DMA_mode + 2))
        !          7894:                                mode = drvp->PIO_mode;
        !          7895:                        else
        !          7896:                                mode = drvp->DMA_mode + 2;
        !          7897:                } else {
        !          7898:                        mode = drvp->PIO_mode;
        !          7899:                        goto pio;
        !          7900:                }
        !          7901:                idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          7902:
        !          7903: pio:
        !          7904:                /* Setup PIO mode */
        !          7905:                if (mode <= 2) {
        !          7906:                        drvp->DMA_mode = 0;
        !          7907:                        drvp->PIO_mode = 0;
        !          7908:                        mode = 0;
        !          7909:                } else {
        !          7910:                        drvp->PIO_mode = mode;
        !          7911:                        drvp->DMA_mode = mode - 2;
        !          7912:                }
        !          7913:                piodmatim |= NFORCE_PIODMATIM_SET(channel, drive,
        !          7914:                    nforce_pio[mode]);
        !          7915:        }
        !          7916:
        !          7917:        if (idedma_ctl != 0) {
        !          7918:                /* Add software bits in status register */
        !          7919:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          7920:                    IDEDMA_CTL(channel), idedma_ctl);
        !          7921:        }
        !          7922:
        !          7923:        WDCDEBUG_PRINT(("%s: %s new timing values: piodmatim=0x%x, "
        !          7924:            "piotim=0x%x, udmatim=0x%x\n", sc->sc_wdcdev.sc_dev.dv_xname,
        !          7925:            cp->name, piodmatim, piotim, udmatim), DEBUG_PROBE);
        !          7926:        pci_conf_write(sc->sc_pc, sc->sc_tag, NFORCE_PIODMATIM, piodmatim);
        !          7927:        pci_conf_write(sc->sc_pc, sc->sc_tag, NFORCE_UDMATIM, udmatim);
        !          7928:
        !          7929:        pciide_print_modes(cp);
        !          7930: }
        !          7931:
        !          7932: int
        !          7933: nforce_pci_intr(void *arg)
        !          7934: {
        !          7935:        struct pciide_softc *sc = arg;
        !          7936:        struct pciide_channel *cp;
        !          7937:        struct channel_softc *wdc_cp;
        !          7938:        int i, rv, crv;
        !          7939:        u_int32_t dmastat;
        !          7940:
        !          7941:        rv = 0;
        !          7942:        for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {
        !          7943:                cp = &sc->pciide_channels[i];
        !          7944:                wdc_cp = &cp->wdc_channel;
        !          7945:
        !          7946:                /* Skip compat channel */
        !          7947:                if (cp->compat)
        !          7948:                        continue;
        !          7949:
        !          7950:                dmastat = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          7951:                    IDEDMA_CTL(i));
        !          7952:                if ((dmastat & IDEDMA_CTL_INTR) == 0)
        !          7953:                        continue;
        !          7954:
        !          7955:                crv = wdcintr(wdc_cp);
        !          7956:                if (crv == 0)
        !          7957:                        printf("%s:%d: bogus intr\n",
        !          7958:                            sc->sc_wdcdev.sc_dev.dv_xname, i);
        !          7959:                else
        !          7960:                        rv = 1;
        !          7961:        }
        !          7962:        return (rv);
        !          7963: }
        !          7964:
        !          7965: void
        !          7966: artisea_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          7967: {
        !          7968:        struct pciide_channel *cp;
        !          7969:        bus_size_t cmdsize, ctlsize;
        !          7970:        pcireg_t interface;
        !          7971:        int channel;
        !          7972:
        !          7973:        printf(": DMA");
        !          7974: #ifdef PCIIDE_I31244_DISABLEDMA
        !          7975:        if (sc->sc_rev == 0) {
        !          7976:                printf(" disabled due to rev. 0");
        !          7977:                sc->sc_dma_ok = 0;
        !          7978:        } else
        !          7979: #endif
        !          7980:                pciide_mapreg_dma(sc, pa);
        !          7981:        printf("\n");
        !          7982:
        !          7983:        /*
        !          7984:         * XXX Configure LEDs to show activity.
        !          7985:         */
        !          7986:
        !          7987:        sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          7988:            WDC_CAPABILITY_MODE | WDC_CAPABILITY_SATA;
        !          7989:        sc->sc_wdcdev.PIO_cap = 4;
        !          7990:        if (sc->sc_dma_ok) {
        !          7991:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
        !          7992:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          7993:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          7994:                sc->sc_wdcdev.DMA_cap = 2;
        !          7995:                sc->sc_wdcdev.UDMA_cap = 6;
        !          7996:        }
        !          7997:        sc->sc_wdcdev.set_modes = sata_setup_channel;
        !          7998:
        !          7999:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          8000:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          8001:
        !          8002:        interface = PCI_INTERFACE(pa->pa_class);
        !          8003:
        !          8004:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          8005:                cp = &sc->pciide_channels[channel];
        !          8006:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          8007:                        continue;
        !          8008:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          8009:                    pciide_pci_intr);
        !          8010:                if (cp->hw_ok == 0)
        !          8011:                        continue;
        !          8012:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          8013:                sata_setup_channel(&cp->wdc_channel);
        !          8014:        }
        !          8015: }
        !          8016:
        !          8017: void
        !          8018: ite_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          8019: {
        !          8020:        struct pciide_channel *cp;
        !          8021:        int channel;
        !          8022:        pcireg_t interface;
        !          8023:        bus_size_t cmdsize, ctlsize;
        !          8024:        pcireg_t cfg, modectl;
        !          8025:
        !          8026:        /*
        !          8027:         * Fake interface since IT8212F is claimed to be a ``RAID'' device.
        !          8028:         */
        !          8029:        interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
        !          8030:            PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
        !          8031:
        !          8032:        cfg = pci_conf_read(sc->sc_pc, sc->sc_tag, IT_CFG);
        !          8033:        modectl = pci_conf_read(sc->sc_pc, sc->sc_tag, IT_MODE);
        !          8034:        WDCDEBUG_PRINT(("%s: cfg=0x%x, modectl=0x%x\n",
        !          8035:            sc->sc_wdcdev.sc_dev.dv_xname, cfg & IT_CFG_MASK,
        !          8036:            modectl & IT_MODE_MASK), DEBUG_PROBE);
        !          8037:
        !          8038:        printf(": DMA");
        !          8039:        pciide_mapreg_dma(sc, pa);
        !          8040:
        !          8041:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          8042:            WDC_CAPABILITY_MODE;
        !          8043:        if (sc->sc_dma_ok) {
        !          8044:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
        !          8045:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          8046:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          8047:        }
        !          8048:        sc->sc_wdcdev.PIO_cap = 4;
        !          8049:        sc->sc_wdcdev.DMA_cap = 2;
        !          8050:        sc->sc_wdcdev.UDMA_cap = 6;
        !          8051:
        !          8052:        sc->sc_wdcdev.set_modes = ite_setup_channel;
        !          8053:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          8054:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          8055:
        !          8056:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          8057:
        !          8058:        /* Disable RAID */
        !          8059:        modectl &= ~IT_MODE_RAID1;
        !          8060:        /* Disable CPU firmware mode */
        !          8061:        modectl &= ~IT_MODE_CPU;
        !          8062:
        !          8063:        pci_conf_write(sc->sc_pc, sc->sc_tag, IT_MODE, modectl);
        !          8064:
        !          8065:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          8066:                cp = &sc->pciide_channels[channel];
        !          8067:
        !          8068:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          8069:                        continue;
        !          8070:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          8071:                    pciide_pci_intr);
        !          8072:                sc->sc_wdcdev.set_modes(&cp->wdc_channel);
        !          8073:        }
        !          8074:
        !          8075:        /* Re-read configuration registers after channels setup */
        !          8076:        cfg = pci_conf_read(sc->sc_pc, sc->sc_tag, IT_CFG);
        !          8077:        modectl = pci_conf_read(sc->sc_pc, sc->sc_tag, IT_MODE);
        !          8078:        WDCDEBUG_PRINT(("%s: cfg=0x%x, modectl=0x%x\n",
        !          8079:            sc->sc_wdcdev.sc_dev.dv_xname, cfg & IT_CFG_MASK,
        !          8080:            modectl & IT_MODE_MASK), DEBUG_PROBE);
        !          8081: }
        !          8082:
        !          8083: void
        !          8084: ite_setup_channel(struct channel_softc *chp)
        !          8085: {
        !          8086:        struct ata_drive_datas *drvp;
        !          8087:        int drive, mode;
        !          8088:        u_int32_t idedma_ctl;
        !          8089:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          8090:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          8091:        int channel = chp->channel;
        !          8092:        pcireg_t cfg, modectl;
        !          8093:        pcireg_t tim;
        !          8094:
        !          8095:        cfg = pci_conf_read(sc->sc_pc, sc->sc_tag, IT_CFG);
        !          8096:        modectl = pci_conf_read(sc->sc_pc, sc->sc_tag, IT_MODE);
        !          8097:        tim = pci_conf_read(sc->sc_pc, sc->sc_tag, IT_TIM(channel));
        !          8098:        WDCDEBUG_PRINT(("%s:%d: tim=0x%x\n", sc->sc_wdcdev.sc_dev.dv_xname,
        !          8099:            channel, tim), DEBUG_PROBE);
        !          8100:
        !          8101:        /* Setup DMA if needed */
        !          8102:        pciide_channel_dma_setup(cp);
        !          8103:
        !          8104:        /* Clear all bits for this channel */
        !          8105:        idedma_ctl = 0;
        !          8106:
        !          8107:        /* Per channel settings */
        !          8108:        for (drive = 0; drive < 2; drive++) {
        !          8109:                drvp = &chp->ch_drive[drive];
        !          8110:
        !          8111:                /* If no drive, skip */
        !          8112:                if ((drvp->drive_flags & DRIVE) == 0)
        !          8113:                        continue;
        !          8114:
        !          8115:                if ((chp->wdc->cap & WDC_CAPABILITY_UDMA) != 0 &&
        !          8116:                    (drvp->drive_flags & DRIVE_UDMA) != 0) {
        !          8117:                        /* Setup UltraDMA mode */
        !          8118:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          8119:                        modectl &= ~IT_MODE_DMA(channel, drive);
        !          8120:
        !          8121: #if 0
        !          8122:                        /* Check cable, works only in CPU firmware mode */
        !          8123:                        if (drvp->UDMA_mode > 2 &&
        !          8124:                            (cfg & IT_CFG_CABLE(channel, drive)) == 0) {
        !          8125:                                WDCDEBUG_PRINT(("%s(%s:%d:%d): "
        !          8126:                                    "80-wire cable not detected\n",
        !          8127:                                    drvp->drive_name,
        !          8128:                                    sc->sc_wdcdev.sc_dev.dv_xname,
        !          8129:                                    channel, drive), DEBUG_PROBE);
        !          8130:                                drvp->UDMA_mode = 2;
        !          8131:                        }
        !          8132: #endif
        !          8133:
        !          8134:                        if (drvp->UDMA_mode >= 5)
        !          8135:                                tim |= IT_TIM_UDMA5(drive);
        !          8136:                        else
        !          8137:                                tim &= ~IT_TIM_UDMA5(drive);
        !          8138:
        !          8139:                        mode = drvp->PIO_mode;
        !          8140:                } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA) != 0 &&
        !          8141:                    (drvp->drive_flags & DRIVE_DMA) != 0) {
        !          8142:                        /* Setup multiword DMA mode */
        !          8143:                        drvp->drive_flags &= ~DRIVE_UDMA;
        !          8144:                        modectl |= IT_MODE_DMA(channel, drive);
        !          8145:
        !          8146:                        /* mode = min(pio, dma + 2) */
        !          8147:                        if (drvp->PIO_mode <= (drvp->DMA_mode + 2))
        !          8148:                                mode = drvp->PIO_mode;
        !          8149:                        else
        !          8150:                                mode = drvp->DMA_mode + 2;
        !          8151:                } else {
        !          8152:                        goto pio;
        !          8153:                }
        !          8154:                idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          8155:
        !          8156: pio:
        !          8157:                /* Setup PIO mode */
        !          8158:                if (mode <= 2) {
        !          8159:                        drvp->DMA_mode = 0;
        !          8160:                        drvp->PIO_mode = 0;
        !          8161:                        mode = 0;
        !          8162:                } else {
        !          8163:                        drvp->PIO_mode = mode;
        !          8164:                        drvp->DMA_mode = mode - 2;
        !          8165:                }
        !          8166:
        !          8167:                /* Enable IORDY if PIO mode >= 3 */
        !          8168:                if (drvp->PIO_mode >= 3)
        !          8169:                        cfg |= IT_CFG_IORDY(channel);
        !          8170:        }
        !          8171:
        !          8172:        WDCDEBUG_PRINT(("%s: tim=0x%x\n", sc->sc_wdcdev.sc_dev.dv_xname,
        !          8173:            tim), DEBUG_PROBE);
        !          8174:
        !          8175:        pci_conf_write(sc->sc_pc, sc->sc_tag, IT_CFG, cfg);
        !          8176:        pci_conf_write(sc->sc_pc, sc->sc_tag, IT_MODE, modectl);
        !          8177:        pci_conf_write(sc->sc_pc, sc->sc_tag, IT_TIM(channel), tim);
        !          8178:
        !          8179:        if (idedma_ctl != 0) {
        !          8180:                /* Add software bits in status register */
        !          8181:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          8182:                    IDEDMA_CTL(channel), idedma_ctl);
        !          8183:        }
        !          8184:
        !          8185:        pciide_print_modes(cp);
        !          8186: }
        !          8187:
        !          8188: void
        !          8189: ixp_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          8190: {
        !          8191:        struct pciide_channel *cp;
        !          8192:        int channel;
        !          8193:        pcireg_t interface = PCI_INTERFACE(pa->pa_class);
        !          8194:        bus_size_t cmdsize, ctlsize;
        !          8195:
        !          8196:        printf(": DMA");
        !          8197:        pciide_mapreg_dma(sc, pa);
        !          8198:
        !          8199:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          8200:            WDC_CAPABILITY_MODE;
        !          8201:        if (sc->sc_dma_ok) {
        !          8202:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
        !          8203:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          8204:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          8205:        }
        !          8206:        sc->sc_wdcdev.PIO_cap = 4;
        !          8207:        sc->sc_wdcdev.DMA_cap = 2;
        !          8208:        sc->sc_wdcdev.UDMA_cap = 6;
        !          8209:
        !          8210:        sc->sc_wdcdev.set_modes = ixp_setup_channel;
        !          8211:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          8212:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          8213:
        !          8214:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          8215:
        !          8216:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          8217:                cp = &sc->pciide_channels[channel];
        !          8218:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          8219:                        continue;
        !          8220:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          8221:                if (cp->hw_ok == 0)
        !          8222:                        continue;
        !          8223:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          8224:                    pciide_pci_intr);
        !          8225:                if (cp->hw_ok == 0) {
        !          8226:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          8227:                        continue;
        !          8228:                }
        !          8229:                sc->sc_wdcdev.set_modes(&cp->wdc_channel);
        !          8230:        }
        !          8231: }
        !          8232:
        !          8233: void
        !          8234: ixp_setup_channel(struct channel_softc *chp)
        !          8235: {
        !          8236:        struct ata_drive_datas *drvp;
        !          8237:        int drive, mode;
        !          8238:        u_int32_t idedma_ctl;
        !          8239:        struct pciide_channel *cp = (struct pciide_channel*)chp;
        !          8240:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          8241:        int channel = chp->channel;
        !          8242:        pcireg_t udma, mdma_timing, pio, pio_timing;
        !          8243:
        !          8244:        pio_timing = pci_conf_read(sc->sc_pc, sc->sc_tag, IXP_PIO_TIMING);
        !          8245:        pio = pci_conf_read(sc->sc_pc, sc->sc_tag, IXP_PIO_CTL);
        !          8246:        mdma_timing = pci_conf_read(sc->sc_pc, sc->sc_tag, IXP_MDMA_TIMING);
        !          8247:        udma = pci_conf_read(sc->sc_pc, sc->sc_tag, IXP_UDMA_CTL);
        !          8248:
        !          8249:        /* Setup DMA if needed */
        !          8250:        pciide_channel_dma_setup(cp);
        !          8251:
        !          8252:        idedma_ctl = 0;
        !          8253:
        !          8254:        /* Per channel settings */
        !          8255:        for (drive = 0; drive < 2; drive++) {
        !          8256:                drvp = &chp->ch_drive[drive];
        !          8257:
        !          8258:                /* If no drive, skip */
        !          8259:                if ((drvp->drive_flags & DRIVE) == 0)
        !          8260:                        continue;
        !          8261:                if ((chp->wdc->cap & WDC_CAPABILITY_UDMA) != 0 &&
        !          8262:                    (drvp->drive_flags & DRIVE_UDMA) != 0) {
        !          8263:                        /* Setup UltraDMA mode */
        !          8264:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          8265:                        IXP_UDMA_ENABLE(udma, chp->channel, drive);
        !          8266:                        IXP_SET_MODE(udma, chp->channel, drive,
        !          8267:                            drvp->UDMA_mode);
        !          8268:                        mode = drvp->PIO_mode;
        !          8269:                } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA) != 0 &&
        !          8270:                    (drvp->drive_flags & DRIVE_DMA) != 0) {
        !          8271:                        /* Setup multiword DMA mode */
        !          8272:                        drvp->drive_flags &= ~DRIVE_UDMA;
        !          8273:                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          8274:                        IXP_UDMA_DISABLE(udma, chp->channel, drive);
        !          8275:                        IXP_SET_TIMING(mdma_timing, chp->channel, drive,
        !          8276:                            ixp_mdma_timings[drvp->DMA_mode]);
        !          8277:
        !          8278:                        /* mode = min(pio, dma + 2) */
        !          8279:                        if (drvp->PIO_mode <= (drvp->DMA_mode + 2))
        !          8280:                                mode = drvp->PIO_mode;
        !          8281:                        else
        !          8282:                                mode = drvp->DMA_mode + 2;
        !          8283:                } else {
        !          8284:                        mode = drvp->PIO_mode;
        !          8285:                }
        !          8286:
        !          8287:                /* Setup PIO mode */
        !          8288:                drvp->PIO_mode = mode;
        !          8289:                if (mode < 2)
        !          8290:                        drvp->DMA_mode = 0;
        !          8291:                else
        !          8292:                        drvp->DMA_mode = mode - 2;
        !          8293:                /*
        !          8294:                 * Set PIO mode and timings
        !          8295:                 * Linux driver avoids PIO mode 1, let's do it too.
        !          8296:                 */
        !          8297:                if (drvp->PIO_mode == 1)
        !          8298:                        drvp->PIO_mode = 0;
        !          8299:
        !          8300:                IXP_SET_MODE(pio, chp->channel, drive, drvp->PIO_mode);
        !          8301:                IXP_SET_TIMING(pio_timing, chp->channel, drive,
        !          8302:                    ixp_pio_timings[drvp->PIO_mode]);
        !          8303:        }
        !          8304:
        !          8305:        pci_conf_write(sc->sc_pc, sc->sc_tag, IXP_UDMA_CTL, udma);
        !          8306:        pci_conf_write(sc->sc_pc, sc->sc_tag, IXP_MDMA_TIMING, mdma_timing);
        !          8307:        pci_conf_write(sc->sc_pc, sc->sc_tag, IXP_PIO_CTL, pio);
        !          8308:        pci_conf_write(sc->sc_pc, sc->sc_tag, IXP_PIO_TIMING, pio_timing);
        !          8309:
        !          8310:        if (idedma_ctl != 0) {
        !          8311:                /* Add software bits in status register */
        !          8312:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          8313:                    IDEDMA_CTL(channel), idedma_ctl);
        !          8314:        }
        !          8315:
        !          8316:        pciide_print_modes(cp);
        !          8317: }
        !          8318:
        !          8319: void
        !          8320: jmicron_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
        !          8321: {
        !          8322:        struct pciide_channel *cp;
        !          8323:        int channel;
        !          8324:        pcireg_t interface = PCI_INTERFACE(pa->pa_class);
        !          8325:        bus_size_t cmdsize, ctlsize;
        !          8326:        u_int32_t conf;
        !          8327:
        !          8328:        conf = pci_conf_read(sc->sc_pc, sc->sc_tag, JMICRON_CONF);
        !          8329:        WDCDEBUG_PRINT(("%s: conf register 0x%x\n",
        !          8330:            sc->sc_wdcdev.sc_dev.dv_xname, conf), DEBUG_PROBE);
        !          8331:
        !          8332:        printf(": DMA");
        !          8333:        pciide_mapreg_dma(sc, pa);
        !          8334:
        !          8335:        sc->sc_wdcdev.cap = WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
        !          8336:            WDC_CAPABILITY_MODE;
        !          8337:        if (sc->sc_dma_ok) {
        !          8338:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
        !          8339:                sc->sc_wdcdev.cap |= WDC_CAPABILITY_IRQACK;
        !          8340:                sc->sc_wdcdev.irqack = pciide_irqack;
        !          8341:        }
        !          8342:        sc->sc_wdcdev.PIO_cap = 4;
        !          8343:        sc->sc_wdcdev.DMA_cap = 2;
        !          8344:        sc->sc_wdcdev.UDMA_cap = 6;
        !          8345:        sc->sc_wdcdev.set_modes = jmicron_setup_channel;
        !          8346:        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        !          8347:        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        !          8348:
        !          8349:        pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
        !          8350:
        !          8351:        for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
        !          8352:                cp = &sc->pciide_channels[channel];
        !          8353:
        !          8354:                if (pciide_chansetup(sc, channel, interface) == 0)
        !          8355:                        continue;
        !          8356:
        !          8357: #if 0
        !          8358:                if ((conf & JMICRON_CHAN_EN(channel)) == 0) {
        !          8359:                        printf("%s: %s ignored (disabled)\n",
        !          8360:                            sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
        !          8361:                        continue;
        !          8362:                }
        !          8363: #endif
        !          8364:
        !          8365:                pciide_map_compat_intr(pa, cp, channel, interface);
        !          8366:                if (cp->hw_ok == 0)
        !          8367:                        continue;
        !          8368:                pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
        !          8369:                    pciide_pci_intr);
        !          8370:                if (cp->hw_ok == 0) {
        !          8371:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          8372:                        continue;
        !          8373:                }
        !          8374:
        !          8375:                if (pciide_chan_candisable(cp)) {
        !          8376:                        conf &= ~JMICRON_CHAN_EN(channel);
        !          8377:                        pciide_unmap_compat_intr(pa, cp, channel, interface);
        !          8378:                        continue;
        !          8379:                }
        !          8380:
        !          8381:                sc->sc_wdcdev.set_modes(&cp->wdc_channel);
        !          8382:        }
        !          8383:        WDCDEBUG_PRINT(("%s: new conf register 0x%x\n",
        !          8384:            sc->sc_wdcdev.sc_dev.dv_xname, conf), DEBUG_PROBE);
        !          8385:        pci_conf_write(sc->sc_pc, sc->sc_tag, NFORCE_CONF, conf);
        !          8386: }
        !          8387:
        !          8388: void
        !          8389: jmicron_setup_channel(struct channel_softc *chp)
        !          8390: {
        !          8391:        struct ata_drive_datas *drvp;
        !          8392:        int drive, mode;
        !          8393:        u_int32_t idedma_ctl;
        !          8394:        struct pciide_channel *cp = (struct pciide_channel *)chp;
        !          8395:        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
        !          8396:        int channel = chp->channel;
        !          8397:        u_int32_t conf;
        !          8398:
        !          8399:        conf = pci_conf_read(sc->sc_pc, sc->sc_tag, JMICRON_CONF);
        !          8400:
        !          8401:        /* Setup DMA if needed */
        !          8402:        pciide_channel_dma_setup(cp);
        !          8403:
        !          8404:        /* Clear all bits for this channel */
        !          8405:        idedma_ctl = 0;
        !          8406:
        !          8407:        /* Per channel settings */
        !          8408:        for (drive = 0; drive < 2; drive++) {
        !          8409:                drvp = &chp->ch_drive[drive];
        !          8410:
        !          8411:                /* If no drive, skip */
        !          8412:                if ((drvp->drive_flags & DRIVE) == 0)
        !          8413:                        continue;
        !          8414:
        !          8415:                if ((chp->wdc->cap & WDC_CAPABILITY_UDMA) != 0 &&
        !          8416:                    (drvp->drive_flags & DRIVE_UDMA) != 0) {
        !          8417:                        /* Setup UltraDMA mode */
        !          8418:                        drvp->drive_flags &= ~DRIVE_DMA;
        !          8419:
        !          8420:                        /* see if cable is up to scratch */
        !          8421:                        if ((conf & JMICRON_CONF_40PIN) &&
        !          8422:                            (drvp->UDMA_mode > 2))
        !          8423:                                drvp->UDMA_mode = 2;
        !          8424:
        !          8425:                        mode = drvp->PIO_mode;
        !          8426:                } else if ((chp->wdc->cap & WDC_CAPABILITY_DMA) != 0 &&
        !          8427:                    (drvp->drive_flags & DRIVE_DMA) != 0) {
        !          8428:                        /* Setup multiword DMA mode */
        !          8429:                        drvp->drive_flags &= ~DRIVE_UDMA;
        !          8430:
        !          8431:                        /* mode = min(pio, dma + 2) */
        !          8432:                        if (drvp->PIO_mode <= (drvp->DMA_mode + 2))
        !          8433:                                mode = drvp->PIO_mode;
        !          8434:                        else
        !          8435:                                mode = drvp->DMA_mode + 2;
        !          8436:                } else {
        !          8437:                        mode = drvp->PIO_mode;
        !          8438:                        goto pio;
        !          8439:                }
        !          8440:                idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
        !          8441:
        !          8442: pio:
        !          8443:                /* Setup PIO mode */
        !          8444:                if (mode <= 2) {
        !          8445:                        drvp->DMA_mode = 0;
        !          8446:                        drvp->PIO_mode = 0;
        !          8447:                        mode = 0;
        !          8448:                } else {
        !          8449:                        drvp->PIO_mode = mode;
        !          8450:                        drvp->DMA_mode = mode - 2;
        !          8451:                }
        !          8452:        }
        !          8453:
        !          8454:        if (idedma_ctl != 0) {
        !          8455:                /* Add software bits in status register */
        !          8456:                bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
        !          8457:                    IDEDMA_CTL(channel), idedma_ctl);
        !          8458:        }
        !          8459:
        !          8460:        pciide_print_modes(cp);
        !          8461: }

CVSweb