ahc_pci.c
来自「基于组件方式开发操作系统的OSKIT源代码」· C语言 代码 · 共 1,611 行 · 第 1/3 页
C
1,611 行
/* * Product specific probe and attach routines for: * 3940, 2940, aic7895, aic7890, aic7880, * aic7870, aic7860 and aic7850 SCSI controllers * * Copyright (c) 1995, 1996, 1997, 1998 Justin T. Gibbs * 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, * without modification, immediately at the beginning of the file. * 2. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * Where this Software is combined with software released under the terms of * the GNU Public License ("GPL") and the terms of the GPL would require the * combined work to also be released under the terms of the GPL, the terms * and conditions of this License will apply in addition to those of the * GPL with the exception of any terms or conditions of this License that * conflict with, or are expressly prohibited by, the GPL. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. * * $Id: ahc_pci.c,v 1.5.2.5 1999/05/17 21:58:40 gibbs Exp $ */#include <pci.h>#if NPCI > 0#include <sys/param.h>#include <sys/systm.h>#include <sys/kernel.h>#include <pci/pcireg.h>#include <pci/pcivar.h>#include <machine/bus_memio.h>#include <machine/bus_pio.h>#include <machine/bus.h>#include <machine/clock.h>#include <cam/cam.h>#include <cam/cam_ccb.h>#include <cam/cam_sim.h>#include <cam/cam_xpt_sim.h>#include <cam/scsi/scsi_all.h>#include <dev/aic7xxx/aic7xxx.h>#include <dev/aic7xxx/93cx6.h>#include <aic7xxx_reg.h>#define AHC_PCI_IOADDR PCIR_MAPS /* I/O Address */#define AHC_PCI_MEMADDR (PCIR_MAPS + 4) /* Mem I/O Address */static __inline u_int64_tahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor){ u_int64_t id; id = subvendor | (subdevice << 16) | ((u_int64_t)vendor << 32) | ((u_int64_t)device << 48); return (id);}#define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull#define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull#define ID_AIC7850 0x5078900400000000ull#define ID_AHA_2910_15_20_30C 0x5078900478509004ull#define ID_AIC7855 0x5578900400000000ull#define ID_AIC7860 0x6078900400000000ull#define ID_AIC7860C 0x6078900478609004ull#define ID_AHA_2940AU_0 0x6178900400000000ull#define ID_AHA_2940AU_1 0x6178900478619004ull#define ID_AHA_2930C_VAR 0x6038900438689004ull#define ID_AIC7870 0x7078900400000000ull#define ID_AHA_2940 0x7178900400000000ull#define ID_AHA_3940 0x7278900400000000ull#define ID_AHA_398X 0x7378900400000000ull#define ID_AHA_2944 0x7478900400000000ull#define ID_AHA_3944 0x7578900400000000ull#define ID_AIC7880 0x8078900400000000ull#define ID_AIC7880_B 0x8078900478809004ull#define ID_AHA_2940AU_CN 0x2178900478219004ull#define ID_AHA_2940U 0x8178900400000000ull#define ID_AHA_3940U 0x8278900400000000ull#define ID_AHA_2944U 0x8478900400000000ull#define ID_AHA_3944U 0x8578900400000000ull#define ID_AHA_398XU 0x8378900400000000ull#define ID_AHA_4944U 0x8678900400000000ull#define ID_AHA_2940UB 0x8178900478819004ull#define ID_AHA_2930U 0x8878900478889004ull#define ID_AHA_2940U_PRO 0x8778900478879004ull#define ID_AHA_2940U_CN 0x0078900478009004ull#define ID_AIC7895 0x7895900478959004ull#define ID_AIC7895_RAID_PORT 0x7893900478939004ull#define ID_AHA_2940U_DUAL 0x7895900478919004ull#define ID_AHA_3940AU 0x7895900478929004ull#define ID_AHA_3944AU 0x7895900478949004ull#define ID_AIC7890 0x001F9005000F9005ull#define ID_AHA_2930U2 0x0011900501819005ull#define ID_AHA_2940U2B 0x00109005A1009005ull#define ID_AHA_2940U2_OEM 0x0010900521809005ull#define ID_AHA_2940U2 0x00109005A1809005ull#define ID_AHA_2950U2B 0x00109005E1009005ull#define ID_AIC7896 0x005F9005FFFF9005ull#define ID_AHA_3950U2B_0 0x00509005FFFF9005ull#define ID_AHA_3950U2B_1 0x00509005F5009005ull#define ID_AHA_3950U2D_0 0x00519005FFFF9005ull#define ID_AHA_3950U2D_1 0x00519005B5009005ull#define ID_AIC7810 0x1078900400000000ull#define ID_AIC7815 0x1578900400000000ulltypedef int (ahc_device_setup_t)(pcici_t, char *, ahc_chip *, ahc_feature *, ahc_flag *);static ahc_device_setup_t ahc_aic7850_setup;static ahc_device_setup_t ahc_aic7860_setup;static ahc_device_setup_t ahc_aic7870_setup;static ahc_device_setup_t ahc_aha394X_setup;static ahc_device_setup_t ahc_aha398X_setup;static ahc_device_setup_t ahc_aic7880_setup;static ahc_device_setup_t ahc_aha394XU_setup;static ahc_device_setup_t ahc_aha398XU_setup;static ahc_device_setup_t ahc_aic7890_setup;static ahc_device_setup_t ahc_aic7895_setup;static ahc_device_setup_t ahc_aic7896_setup;static ahc_device_setup_t ahc_raid_setup;static ahc_device_setup_t ahc_aha394XX_setup;static ahc_device_setup_t ahc_aha398XX_setup;struct ahc_pci_identity { u_int64_t full_id; u_int64_t id_mask; char *name; ahc_device_setup_t *setup;};struct ahc_pci_identity ahc_pci_ident_table [] ={ /* aic7850 based controllers */ { ID_AHA_2910_15_20_30C, ID_ALL_MASK, "Adaptec 2910/15/20/30C SCSI adapter", ahc_aic7850_setup }, /* aic7860 based controllers */ { ID_AHA_2940AU_0 & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec 2940A Ultra SCSI adapter", ahc_aic7860_setup }, { ID_AHA_2930C_VAR, ID_ALL_MASK, "Adaptec 2930C SCSI adapter (VAR)", ahc_aic7860_setup }, /* aic7870 based controllers */ { ID_AHA_2940, ID_ALL_MASK, "Adaptec 2940 SCSI adapter", ahc_aic7870_setup }, { ID_AHA_3940, ID_ALL_MASK, "Adaptec 3940 SCSI adapter", ahc_aha394X_setup }, { ID_AHA_398X, ID_ALL_MASK, "Adaptec 398X SCSI RAID adapter", ahc_aha398X_setup }, { ID_AHA_2944, ID_ALL_MASK, "Adaptec 2944 SCSI adapter", ahc_aic7870_setup }, { ID_AHA_3944, ID_ALL_MASK, "Adaptec 3944 SCSI adapter", ahc_aha394X_setup }, /* aic7880 based controllers */ { ID_AHA_2940AU_CN, ID_ALL_MASK, "Adaptec 2940A/CN Ultra SCSI adapter", ahc_aic7880_setup }, { ID_AHA_2940U, ID_ALL_MASK, "Adaptec 2940 Ultra SCSI adapter", ahc_aic7880_setup }, { ID_AHA_3940U, ID_ALL_MASK, "Adaptec 3940 Ultra SCSI adapter", ahc_aha394XU_setup }, { ID_AHA_2944U, ID_ALL_MASK, "Adaptec 2944 Ultra SCSI adapter", ahc_aic7880_setup }, { ID_AHA_3944U, ID_ALL_MASK, "Adaptec 3944 Ultra SCSI adapter", ahc_aha394XU_setup }, { ID_AHA_398XU, ID_ALL_MASK, "Adaptec 398X Ultra SCSI RAID adapter", ahc_aha398XU_setup }, { /* XXX Don't know the slot numbers so can't identify channels */ ID_AHA_4944U, ID_ALL_MASK, "Adaptec 4944 Ultra SCSI adapter", ahc_aic7880_setup }, { ID_AHA_2940UB, ID_ALL_MASK, "Adaptec 2940B Ultra SCSI adapter", ahc_aic7880_setup }, { ID_AHA_2930U, ID_ALL_MASK, "Adaptec 2930 Ultra SCSI adapter", ahc_aic7880_setup }, { ID_AHA_2940U_PRO, ID_ALL_MASK, "Adaptec 2940 Pro Ultra SCSI adapter", ahc_aic7880_setup }, { ID_AHA_2940U_CN, ID_ALL_MASK, "Adaptec 2940/CN Ultra SCSI adapter", ahc_aic7880_setup }, /* aic7890 based controllers */ { ID_AHA_2930U2, ID_ALL_MASK, "Adaptec 2930 Ultra2 SCSI adapter", ahc_aic7890_setup }, { ID_AHA_2940U2B, ID_ALL_MASK, "Adaptec 2940B Ultra2 SCSI adapter", ahc_aic7890_setup }, { ID_AHA_2940U2_OEM, ID_ALL_MASK, "Adaptec 2940 Ultra2 SCSI adapter (OEM)", ahc_aic7890_setup }, { ID_AHA_2940U2, ID_ALL_MASK, "Adaptec 2940 Ultra2 SCSI adapter", ahc_aic7890_setup }, { ID_AHA_2950U2B, ID_ALL_MASK, "Adaptec 2950 Ultra2 SCSI adapter", ahc_aic7890_setup }, /* aic7895 based controllers */ { ID_AHA_2940U_DUAL, ID_ALL_MASK, "Adaptec 2940/DUAL Ultra SCSI adapter", ahc_aic7895_setup }, { ID_AHA_3940AU, ID_ALL_MASK, "Adaptec 3940A Ultra SCSI adapter", ahc_aic7895_setup }, { ID_AHA_3944AU, ID_ALL_MASK, "Adaptec 3944A Ultra SCSI adapter", ahc_aic7895_setup }, /* aic7896/97 based controllers */ { ID_AHA_3950U2B_0, ID_ALL_MASK, "Adaptec 3950B Ultra2 SCSI adapter", ahc_aic7896_setup }, { ID_AHA_3950U2B_1, ID_ALL_MASK, "Adaptec 3950B Ultra2 SCSI adapter", ahc_aic7896_setup }, { ID_AHA_3950U2D_0, ID_ALL_MASK, "Adaptec 3950D Ultra2 SCSI adapter", ahc_aic7896_setup }, { ID_AHA_3950U2D_1, ID_ALL_MASK, "Adaptec 3950D Ultra2 SCSI adapter", ahc_aic7896_setup }, /* Generic chip probes for devices we don't know 'exactly' */ { ID_AIC7850 & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec aic7850 SCSI adapter", ahc_aic7850_setup }, { ID_AIC7855 & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec aic7855 SCSI adapter", ahc_aic7850_setup }, { ID_AIC7860 & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec aic7860 SCSI adapter", ahc_aic7860_setup }, { ID_AIC7870 & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec aic7870 SCSI adapter", ahc_aic7870_setup }, { ID_AIC7880 & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec aic7880 Ultra SCSI adapter", ahc_aic7880_setup }, { ID_AIC7890 & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec aic7890/91 Ultra2 SCSI adapter", ahc_aic7890_setup }, { ID_AIC7895 & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec aic7895 Ultra SCSI adapter", ahc_aic7895_setup }, { ID_AIC7895_RAID_PORT & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec aic7895 Ultra SCSI adapter (RAID PORT)", ahc_aic7895_setup }, { ID_AIC7896 & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec aic7896/97 Ultra2 SCSI adapter", ahc_aic7896_setup }, { ID_AIC7810 & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec aic7810 RAID memory controller", ahc_raid_setup }, { ID_AIC7815 & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec aic7815 RAID memory controller", ahc_raid_setup }};static const int ahc_num_pci_devs = sizeof(ahc_pci_ident_table) / sizeof(*ahc_pci_ident_table); #define AHC_394X_SLOT_CHANNEL_A 4#define AHC_394X_SLOT_CHANNEL_B 5#define AHC_398X_SLOT_CHANNEL_A 4#define AHC_398X_SLOT_CHANNEL_B 8#define AHC_398X_SLOT_CHANNEL_C 12#define DEVCONFIG 0x40#define SCBSIZE32 0x00010000ul /* aic789X only */#define MPORTMODE 0x00000400ul /* aic7870 only */#define RAMPSM 0x00000200ul /* aic7870 only */#define VOLSENSE 0x00000100ul#define SCBRAMSEL 0x00000080ul#define MRDCEN 0x00000040ul#define EXTSCBTIME 0x00000020ul /* aic7870 only */#define EXTSCBPEN 0x00000010ul /* aic7870 only */#define BERREN 0x00000008ul#define DACEN 0x00000004ul#define STPWLEVEL 0x00000002ul#define DIFACTNEGEN 0x00000001ul /* aic7870 only */#define CSIZE_LATTIME 0x0c#define CACHESIZE 0x0000003ful /* only 5 bits */#define LATTIME 0x0000ff00ulstatic struct ahc_pci_identity *ahc_find_pci_device(pcici_t tag);static void check_extport(struct ahc_softc *ahc, u_int *sxfrctl1);static void configure_termination(struct ahc_softc *ahc, struct seeprom_config *sc, struct seeprom_descriptor *sd, u_int *sxfrctl1);static void ahc_ultra2_term_detect(struct ahc_softc *ahc, int *enableSEC_low, int *enableSEC_high, int *enablePRI_low, int *enablePRI_high, int *eeprom_present);static void aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present, int *internal68_present, int *externalcable_present, int *eeprom_present);static void aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present, int *externalcable_present, int *eeprom_present);static int acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd);static void release_seeprom(struct seeprom_descriptor *sd);static void write_brdctl(struct ahc_softc *ahc, u_int8_t value);static u_int8_t read_brdctl(struct ahc_softc *ahc);static struct ahc_softc *first_398X;static const char* ahc_pci_probe(pcici_t tag, pcidi_t type);static void ahc_pci_attach(pcici_t config_id, int unit);/* Exported for use in the ahc_intr routine */void ahc_pci_intr(struct ahc_softc *ahc);static struct pci_device ahc_pci_driver = { "ahc", ahc_pci_probe, ahc_pci_attach, &ahc_unit, NULL}; DATA_SET (pcidevice_set, ahc_pci_driver);static struct ahc_pci_identity *ahc_find_pci_device(pcici_t tag){ u_int64_t full_id; struct ahc_pci_identity *entry; u_int deviceid; u_int vendorid; u_int subdeviceid; u_int subvendorid; u_int i; deviceid = pci_cfgread(tag, PCIR_DEVICE, /*bytes*/2); vendorid = pci_cfgread(tag, PCIR_VENDOR, /*bytes*/2); subdeviceid = pci_cfgread(tag, PCIR_SUBDEV_0, /*bytes*/2); subvendorid = pci_cfgread(tag, PCIR_SUBVEND_0, /*bytes*/2); full_id = ahc_compose_id(deviceid, vendorid, subdeviceid, subvendorid); for (i = 0; i < ahc_num_pci_devs; i++) { entry = &ahc_pci_ident_table[i]; if (entry->full_id == (full_id & entry->id_mask)) return (entry); } return (NULL);}static const char*ahc_pci_probe(pcici_t tag, pcidi_t type){ struct ahc_pci_identity *entry; entry = ahc_find_pci_device(tag); if (entry != NULL) return (entry->name); return (NULL);}static void
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?