📄 pciide.c
字号:
/* $OpenBSD: pciide.c,v 1.23 2000/05/04 19:42:53 millert Exp $ *//* $NetBSD: pciide.c,v 1.48 1999/11/28 20:05:18 bouyer Exp $ *//* * Copyright (c) 1999 Manuel Bouyer. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *//* * Copyright (c) 1996, 1998 Christopher G. Demetriou. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Christopher G. Demetriou * for the NetBSD Project. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *//* * PCI IDE controller driver. * * Author: Christopher G. Demetriou, March 2, 1998 (derived from NetBSD * sys/dev/pci/ppb.c, revision 1.16). * * See "PCI IDE Controller Specification, Revision 1.0 3/4/94" and * "Programming Interface for Bus Master IDE Controller, Revision 1.0 * 5/16/94" from the PCI SIG. * */#define DEBUG_DMA 0x01#define DEBUG_XFERS 0x02#define DEBUG_FUNCS 0x08#define DEBUG_PROBE 0x10#ifdef WDCDEBUGint wdcdebug_pciide_mask = DEBUG_DMA|DEBUG_XFERS|DEBUG_FUNCS|DEBUG_PROBE;#define WDCDEBUG_PRINT(args, level) \ printf args#else#define WDCDEBUG_PRINT(args, level)#endif#include <sys/param.h>#include <sys/systm.h>#include <sys/device.h>#include <sys/malloc.h>#include <vm/vm.h>#include <vm/vm_param.h>#include <vm/vm_kern.h>#include <dev/pci/pcireg.h>#include <dev/pci/pcivar.h>#include <dev/pci/pcidevs.h>#include <dev/pci/pciidereg.h>#include <dev/pci/pciidevar.h>#include <dev/pci/pciide_piix_reg.h>#ifndef PMON#include <dev/pci/pciide_amd_reg.h>#include <dev/pci/pciide_apollo_reg.h>#endif#include <dev/pci/pciide_cmd_reg.h>#ifndef PMON#include <dev/pci/pciide_cy693_reg.h>#include <dev/pci/pciide_sis_reg.h>#endif#include <dev/pci/pciide_acer_reg.h>#include <dev/pci/pciide_pdc202xx_reg.h>#include <dev/pci/pciide_ite_reg.h>#include <dev/ata/atavar.h>#include <dev/ic/wdcreg.h>#include <dev/ic/wdcvar.h>#if BYTE_ORDER == BIG_ENDIAN#if 0#include <machine/bswap.h> #endif#define htopci(x) bswap32(x)#define pcitoh(x) bswap32(x)#else #define htopci(x) (x)#define pcitoh(x) (x)#endif/* inlines for reading/writing 8-bit PCI registers */static __inline u_int8_t pciide_pci_read __P((pci_chipset_tag_t, pcitag_t, int));static __inline void pciide_pci_write __P((pci_chipset_tag_t, pcitag_t, int, u_int8_t));static __inline u_int8_tpciide_pci_read(pc, pa, reg) pci_chipset_tag_t pc; pcitag_t pa; int reg;{ return (pci_conf_read(pc, pa, (reg & ~0x03)) >> ((reg & 0x03) * 8) & 0xff);}static __inline voidpciide_pci_write(pc, pa, reg, val) pci_chipset_tag_t pc; pcitag_t pa; int reg; u_int8_t val;{ pcireg_t pcival; pcival = pci_conf_read(pc, pa, (reg & ~0x03)); pcival &= ~(0xff << ((reg & 0x03) * 8)); pcival |= (val << ((reg & 0x03) * 8)); pci_conf_write(pc, pa, (reg & ~0x03), pcival);}struct pciide_softc { struct wdc_softc sc_wdcdev; /* common wdc definitions */ pci_chipset_tag_t sc_pc; /* PCI registers info */ pcitag_t sc_tag; void *sc_pci_ih; /* PCI interrupt handle */ int sc_dma_ok; /* bus-master DMA info */ bus_space_tag_t sc_dma_iot; bus_space_handle_t sc_dma_ioh; bus_dma_tag_t sc_dmat; /* Chip description */ const struct pciide_product_desc *sc_pp; /* common definitions */ struct channel_softc *wdc_chanarray[PCIIDE_NUM_CHANNELS]; /* internal bookkeeping */ struct pciide_channel { /* per-channel data */ struct channel_softc wdc_channel; /* generic part */ char *name; int hw_ok; /* hardware mapped & OK? */ int compat; /* is it compat? */ void *ih; /* compat or pci handle */ /* DMA tables and DMA map for xfer, for each drive */ struct pciide_dma_maps { bus_dmamap_t dmamap_table; struct idedma_table *dma_table; bus_dmamap_t dmamap_xfer; } dma_maps[2]; } pciide_channels[PCIIDE_NUM_CHANNELS];};void default_chip_map __P((struct pciide_softc*, struct pci_attach_args*));void piix_chip_map __P((struct pciide_softc*, struct pci_attach_args*));void piix_setup_channel __P((struct channel_softc*));void piix3_4_setup_channel __P((struct channel_softc*));static u_int32_t piix_setup_idetim_timings __P((u_int8_t, u_int8_t, u_int8_t));static u_int32_t piix_setup_idetim_drvs __P((struct ata_drive_datas*));static u_int32_t piix_setup_sidetim_timings __P((u_int8_t, u_int8_t, u_int8_t));#ifndef PMONvoid amd756_chip_map __P((struct pciide_softc*, struct pci_attach_args*));void amd756_setup_channel __P((struct channel_softc*));void apollo_chip_map __P((struct pciide_softc*, struct pci_attach_args*));void apollo_setup_channel __P((struct channel_softc*));#endifvoid cmd_chip_map __P((struct pciide_softc*, struct pci_attach_args*));void cmd0643_6_chip_map __P((struct pciide_softc*, struct pci_attach_args*));void cmd0643_6_setup_channel __P((struct channel_softc*));void cmd_channel_map __P((struct pci_attach_args *, struct pciide_softc *, int));int cmd_pci_intr __P((void *));#ifndef PMONvoid cy693_chip_map __P((struct pciide_softc*, struct pci_attach_args*));void cy693_setup_channel __P((struct channel_softc*));void sis_chip_map __P((struct pciide_softc*, struct pci_attach_args*));void sis_setup_channel __P((struct channel_softc*));#endifvoid acer_chip_map __P((struct pciide_softc*, struct pci_attach_args*));void acer_setup_channel __P((struct channel_softc*));int acer_pci_intr __P((void *));void pdc202xx_chip_map __P((struct pciide_softc*, struct pci_attach_args*));void pdc202xx_setup_channel __P((struct channel_softc*));void pdc20268_setup_channel __P((struct channel_softc*));int pdc202xx_pci_intr __P((void *));int pdc20265_pci_intr __P((void *));void ite_chip_map __P((struct pciide_softc*, struct pci_attach_args*));void ite_setup_channel __P((struct channel_softc*));int ite_pci_intr __P((void *)); #ifndef PMONvoid pciide_channel_dma_setup __P((struct pciide_channel *));int pciide_dma_table_setup __P((struct pciide_softc*, int, int));int pciide_dma_init __P((void*, int, int, void *, size_t, int));void pciide_dma_start __P((void*, int, int, int));int pciide_dma_finish __P((void*, int, int, int));#else#define pciide_channel_dma_setup(cp) /* Nothing */#endifvoid pciide_print_modes __P((struct pciide_channel *));void pciide_print_channels __P((int, pcireg_t));;struct pciide_product_desc { u_int32_t ide_product; u_short ide_flags; /* map and setup chip, probe drives */ void (*chip_map) __P((struct pciide_softc*, struct pci_attach_args*));};/* Flags for ide_flags */#define IDE_PCI_CLASS_OVERRIDE 0x0001 /* accept even if class != pciide *//* Default product description for devices not known from this controller */const struct pciide_product_desc default_product_desc = { 0, /* Generic PCI IDE controller */ 0, default_chip_map};const struct pciide_product_desc pciide_intel_products[] = { { PCI_PRODUCT_INTEL_82092AA, /* Intel 82092AA IDE */ 0, default_chip_map }, { PCI_PRODUCT_INTEL_82371FB_IDE, /* Intel 82371FB IDE (PIIX) */ 0, piix_chip_map }, { PCI_PRODUCT_INTEL_82371SB_IDE, /* Intel 82371SB IDE (PIIX3) */ 0, piix_chip_map }, { PCI_PRODUCT_INTEL_82371AB_IDE, /* Intel 82371AB IDE (PIIX4) */ 0, piix_chip_map }, { PCI_PRODUCT_INTEL_82801AA_IDE, /* Intel 82801AA IDE (ICH) */ 0, piix_chip_map }, { PCI_PRODUCT_INTEL_82801AB_IDE, /* Intel 82801AB IDE (ICH0) */ 0, piix_chip_map },};#ifndef PMONconst struct pciide_product_desc pciide_amd_products[] = { { PCI_PRODUCT_AMD_PBC756_IDE, /* AMD 756 */ 0, amd756_chip_map },};#endifconst struct pciide_product_desc pciide_cmd_products[] = { { PCI_PRODUCT_CMDTECH_640, /* CMD Technology PCI0640 */ 0, cmd_chip_map }, { PCI_PRODUCT_CMDTECH_643, /* CMD Technology PCI0643 */ 0, cmd0643_6_chip_map }, { PCI_PRODUCT_CMDTECH_646, /* CMD Technology PCI0646 */ 0, cmd0643_6_chip_map }, { PCI_PRODUCT_CMDTECH_648, /* CMD Technology PCI0648 */ 0, cmd0643_6_chip_map }};#ifndef PMONconst struct pciide_product_desc pciide_via_products[] = { { PCI_PRODUCT_VIATECH_VT82C586_IDE, /* VIA VT82C586 (Apollo VP) IDE */ 0, apollo_chip_map }, { PCI_PRODUCT_VIATECH_VT82C586A_IDE, /* VIA VT82C586A IDE */ 0, apollo_chip_map }};const struct pciide_product_desc pciide_cypress_products[] = { { PCI_PRODUCT_CONTAQ_82C693, /* Contaq CY82C693 IDE */ 0, cy693_chip_map }};const struct pciide_product_desc pciide_sis_products[] = { { PCI_PRODUCT_SIS_5513, /* SIS 5513 EIDE */ 0, sis_chip_map }};#endifconst struct pciide_product_desc pciide_acer_products[] = { { PCI_PRODUCT_ALI_M5229, /* Acer Labs M5229 UDMA IDE */ 0, acer_chip_map }};const struct pciide_product_desc pciide_promise_products[] = { { PCI_PRODUCT_PROMISE_PDC20246, IDE_PCI_CLASS_OVERRIDE, pdc202xx_chip_map, }, { PCI_PRODUCT_PROMISE_PDC20262, IDE_PCI_CLASS_OVERRIDE, pdc202xx_chip_map, }, { PCI_PRODUCT_PROMISE_PDC20265, IDE_PCI_CLASS_OVERRIDE, pdc202xx_chip_map, }, { PCI_PRODUCT_PROMISE_PDC20267, IDE_PCI_CLASS_OVERRIDE, pdc202xx_chip_map, }, { PCI_PRODUCT_PROMISE_PDC20268, IDE_PCI_CLASS_OVERRIDE, default_chip_map, }, { PCI_PRODUCT_PROMISE_PDC20268R, IDE_PCI_CLASS_OVERRIDE, default_chip_map, }, { PCI_PRODUCT_PROMISE_PDC20269, IDE_PCI_CLASS_OVERRIDE, pdc202xx_chip_map, }};const struct pciide_product_desc pciide_ite_products[] = { { PCI_PRODUCT_ITEXPRESS_IT8172, 0, ite_chip_map }};struct pciide_vendor_desc { u_int32_t ide_vendor; const struct pciide_product_desc *ide_products; int ide_nproducts;};const struct pciide_vendor_desc pciide_vendors[] = { { PCI_VENDOR_INTEL, pciide_intel_products, sizeof(pciide_intel_products)/sizeof(pciide_intel_products[0]) },#ifndef PMON { PCI_VENDOR_AMD, pciide_amd_products, sizeof(pciide_amd_products)/sizeof(pciide_amd_products[0]) },#endif { PCI_VENDOR_CMDTECH, pciide_cmd_products, sizeof(pciide_cmd_products)/sizeof(pciide_cmd_products[0]) },#ifndef PMON { PCI_VENDOR_VIATECH, pciide_via_products, sizeof(pciide_via_products)/sizeof(pciide_via_products[0]) }, { PCI_VENDOR_CONTAQ, pciide_cypress_products, sizeof(pciide_cypress_products)/sizeof(pciide_cypress_products[0]) }, { PCI_VENDOR_SIS, pciide_sis_products, sizeof(pciide_sis_products)/sizeof(pciide_sis_products[0]) },#endif { PCI_VENDOR_ALI, pciide_acer_products, sizeof(pciide_acer_products)/sizeof(pciide_acer_products[0]) }, { PCI_VENDOR_PROMISE, pciide_promise_products, sizeof(pciide_promise_products)/sizeof(pciide_promise_products[0]) }, { PCI_VENDOR_ITEXPRESS, pciide_ite_products, sizeof(pciide_ite_products)/sizeof(pciide_ite_products[0]) }};#define PCIIDE_CHANNEL_NAME(chan) ((chan) == 0 ? "ch 0" : "ch 1")/* options passed via the 'flags' config keyword */#define PCIIDE_OPTIONS_DMA 0x01#ifndef __OpenBSD__int pciide_match __P((struct device *, struct cfdata *, void *));#elseint pciide_match __P((struct device *, void *, void *));#endifvoid pciide_attach __P((struct device *, struct device *, void *));struct cfattach pciide_ca = { sizeof(struct pciide_softc), pciide_match, pciide_attach};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -