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