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 + -
显示快捷键?