Home | History | Annotate | Line # | Download | only in pci
ahc_pci.c revision 1.15.4.1
      1  1.15.4.1   thorpej /*	$NetBSD: ahc_pci.c,v 1.15.4.1 1997/08/27 23:32:24 thorpej Exp $	*/
      2       1.2   thorpej 
      3       1.1   mycroft /*
      4       1.1   mycroft  * Product specific probe and attach routines for:
      5       1.1   mycroft  *      3940, 2940, aic7880, aic7870, aic7860 and aic7850 SCSI controllers
      6       1.1   mycroft  *
      7       1.1   mycroft  * Copyright (c) 1995, 1996 Justin T. Gibbs.
      8       1.1   mycroft  * All rights reserved.
      9       1.1   mycroft  *
     10       1.1   mycroft  * Redistribution and use in source and binary forms, with or without
     11       1.1   mycroft  * modification, are permitted provided that the following conditions
     12       1.1   mycroft  * are met:
     13       1.1   mycroft  * 1. Redistributions of source code must retain the above copyright
     14       1.1   mycroft  *    notice immediately at the beginning of the file, without modification,
     15       1.1   mycroft  *    this list of conditions, and the following disclaimer.
     16       1.1   mycroft  * 2. Redistributions in binary form must reproduce the above copyright
     17       1.1   mycroft  *    notice, this list of conditions and the following disclaimer in the
     18       1.1   mycroft  *    documentation and/or other materials provided with the distribution.
     19       1.1   mycroft  * 3. The name of the author may not be used to endorse or promote products
     20       1.1   mycroft  *    derived from this software without specific prior written permission.
     21       1.1   mycroft  *
     22       1.1   mycroft  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     23       1.1   mycroft  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24       1.1   mycroft  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25       1.1   mycroft  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
     26       1.1   mycroft  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27       1.1   mycroft  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28       1.1   mycroft  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29       1.1   mycroft  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30       1.1   mycroft  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31       1.1   mycroft  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32       1.1   mycroft  * SUCH DAMAGE.
     33       1.3  explorer  *
     34       1.3  explorer  * from	Id: aic7870.c,v 1.37 1996/06/08 06:55:55 gibbs Exp
     35       1.1   mycroft  */
     36       1.1   mycroft 
     37       1.1   mycroft #if defined(__FreeBSD__)
     38       1.1   mycroft #include <pci.h>
     39       1.1   mycroft #endif
     40       1.1   mycroft #if NPCI > 0 || defined(__NetBSD__)
     41       1.1   mycroft #include <sys/param.h>
     42       1.1   mycroft #include <sys/systm.h>
     43       1.1   mycroft #include <sys/malloc.h>
     44       1.1   mycroft #include <sys/kernel.h>
     45       1.1   mycroft #include <sys/queue.h>
     46       1.1   mycroft #if defined(__NetBSD__)
     47       1.1   mycroft #include <sys/device.h>
     48       1.1   mycroft #include <machine/bus.h>
     49       1.1   mycroft #include <machine/intr.h>
     50       1.1   mycroft #endif /* defined(__NetBSD__) */
     51       1.1   mycroft 
     52  1.15.4.1   thorpej #include <dev/scsipi/scsi_all.h>
     53  1.15.4.1   thorpej #include <dev/scsipi/scsipi_all.h>
     54  1.15.4.1   thorpej #if defined (__NetBSD__)
     55  1.15.4.1   thorpej #endif
     56  1.15.4.1   thorpej #include <dev/scsipi/scsiconf.h>
     57       1.1   mycroft 
     58       1.1   mycroft #if defined(__FreeBSD__)
     59       1.1   mycroft 
     60       1.1   mycroft #include <pci/pcireg.h>
     61       1.1   mycroft #include <pci/pcivar.h>
     62       1.1   mycroft 
     63       1.1   mycroft #include <machine/clock.h>
     64       1.1   mycroft 
     65       1.1   mycroft #include <i386/scsi/aic7xxx.h>
     66       1.1   mycroft #include <i386/scsi/93cx6.h>
     67       1.1   mycroft 
     68       1.1   mycroft #include <dev/aic7xxx/aic7xxx_reg.h>
     69       1.1   mycroft 
     70       1.1   mycroft #define PCI_BASEADR0	PCI_MAP_REG_START
     71       1.1   mycroft 
     72       1.1   mycroft #elif defined(__NetBSD__)
     73       1.1   mycroft 
     74       1.1   mycroft #include <dev/pci/pcireg.h>
     75       1.1   mycroft #include <dev/pci/pcivar.h>
     76       1.1   mycroft 
     77       1.1   mycroft #include <dev/ic/aic7xxxreg.h>
     78       1.1   mycroft #include <dev/ic/aic7xxxvar.h>
     79       1.1   mycroft #include <dev/ic/smc93cx6var.h>
     80       1.1   mycroft 
     81       1.5   thorpej /*
     82       1.5   thorpej  * Under normal circumstances, these messages are unnecessary
     83       1.5   thorpej  * and not terribly cosmetic.
     84       1.5   thorpej  */
     85       1.5   thorpej #ifdef DEBUG
     86       1.1   mycroft #define bootverbose	1
     87       1.5   thorpej #else
     88       1.5   thorpej #define bootverbose	0
     89       1.5   thorpej #endif
     90       1.5   thorpej 
     91      1.12       cgd #define PCI_BASEADR_IO	0x10
     92      1.12       cgd #define PCI_BASEADR_MEM	0x14
     93      1.12       cgd 
     94       1.1   mycroft #endif /* defined(__NetBSD__) */
     95       1.1   mycroft 
     96       1.1   mycroft #define PCI_DEVICE_ID_ADAPTEC_3940U	0x82789004ul
     97       1.1   mycroft #define PCI_DEVICE_ID_ADAPTEC_2944U	0x84789004ul
     98       1.1   mycroft #define PCI_DEVICE_ID_ADAPTEC_2940U	0x81789004ul
     99       1.6     gibbs #define PCI_DEVICE_ID_ADAPTEC_2940AU	0x61789004ul
    100       1.1   mycroft #define PCI_DEVICE_ID_ADAPTEC_3940	0x72789004ul
    101       1.1   mycroft #define PCI_DEVICE_ID_ADAPTEC_2944	0x74789004ul
    102       1.1   mycroft #define PCI_DEVICE_ID_ADAPTEC_2940	0x71789004ul
    103       1.1   mycroft #define PCI_DEVICE_ID_ADAPTEC_AIC7880	0x80789004ul
    104       1.1   mycroft #define PCI_DEVICE_ID_ADAPTEC_AIC7870	0x70789004ul
    105       1.1   mycroft #define PCI_DEVICE_ID_ADAPTEC_AIC7860	0x60789004ul
    106       1.1   mycroft #define PCI_DEVICE_ID_ADAPTEC_AIC7855	0x55789004ul
    107       1.1   mycroft #define PCI_DEVICE_ID_ADAPTEC_AIC7850	0x50789004ul
    108       1.1   mycroft 
    109       1.1   mycroft #define	DEVCONFIG		0x40
    110       1.1   mycroft #define		MPORTMODE	0x00000400ul	/* aic7870 only */
    111       1.1   mycroft #define		RAMPSM		0x00000200ul	/* aic7870 only */
    112       1.1   mycroft #define		VOLSENSE	0x00000100ul
    113       1.1   mycroft #define		SCBRAMSEL	0x00000080ul
    114       1.1   mycroft #define		MRDCEN		0x00000040ul
    115       1.1   mycroft #define		EXTSCBTIME	0x00000020ul	/* aic7870 only */
    116       1.1   mycroft #define		EXTSCBPEN	0x00000010ul	/* aic7870 only */
    117       1.1   mycroft #define		BERREN		0x00000008ul
    118       1.1   mycroft #define		DACEN		0x00000004ul
    119       1.1   mycroft #define		STPWLEVEL	0x00000002ul
    120       1.1   mycroft #define		DIFACTNEGEN	0x00000001ul	/* aic7870 only */
    121       1.1   mycroft 
    122       1.1   mycroft #define	CSIZE_LATTIME		0x0c
    123       1.1   mycroft #define		CACHESIZE	0x0000003ful	/* only 5 bits */
    124       1.1   mycroft #define		LATTIME		0x0000ff00ul
    125       1.1   mycroft 
    126       1.1   mycroft /*
    127       1.1   mycroft  * Define the format of the aic78X0 SEEPROM registers (16 bits).
    128       1.1   mycroft  *
    129       1.1   mycroft  */
    130       1.1   mycroft 
    131       1.1   mycroft struct seeprom_config {
    132       1.1   mycroft 
    133       1.1   mycroft /*
    134       1.1   mycroft  * SCSI ID Configuration Flags
    135       1.1   mycroft  */
    136       1.1   mycroft #define CFXFER		0x0007		/* synchronous transfer rate */
    137       1.1   mycroft #define CFSYNCH		0x0008		/* enable synchronous transfer */
    138       1.1   mycroft #define CFDISC		0x0010		/* enable disconnection */
    139       1.1   mycroft #define CFWIDEB		0x0020		/* wide bus device */
    140       1.1   mycroft /* UNUSED		0x00C0 */
    141       1.1   mycroft #define CFSTART		0x0100		/* send start unit SCSI command */
    142       1.1   mycroft #define CFINCBIOS	0x0200		/* include in BIOS scan */
    143       1.1   mycroft #define CFRNFOUND	0x0400		/* report even if not found */
    144       1.1   mycroft /* UNUSED		0xf800 */
    145       1.1   mycroft   u_int16_t device_flags[16];	/* words 0-15 */
    146       1.1   mycroft 
    147       1.1   mycroft /*
    148       1.1   mycroft  * BIOS Control Bits
    149       1.1   mycroft  */
    150       1.1   mycroft #define CFSUPREM	0x0001		/* support all removeable drives */
    151       1.1   mycroft #define CFSUPREMB	0x0002		/* support removeable drives for boot only */
    152       1.1   mycroft #define CFBIOSEN	0x0004		/* BIOS enabled */
    153       1.1   mycroft /* UNUSED		0x0008 */
    154       1.1   mycroft #define CFSM2DRV	0x0010		/* support more than two drives */
    155       1.1   mycroft /* UNUSED		0x0060 */
    156       1.1   mycroft #define CFEXTEND	0x0080		/* extended translation enabled */
    157       1.1   mycroft /* UNUSED		0xff00 */
    158       1.1   mycroft   u_int16_t bios_control;		/* word 16 */
    159       1.1   mycroft 
    160       1.1   mycroft /*
    161       1.1   mycroft  * Host Adapter Control Bits
    162       1.1   mycroft  */
    163       1.1   mycroft /* UNUSED		0x0001 */
    164       1.1   mycroft #define CFULTRAEN       0x0002          /* Ultra SCSI speed enable (Ultra cards) */
    165       1.1   mycroft #define CFSTERM		0x0004		/* SCSI low byte termination (non-wide cards) */
    166       1.1   mycroft #define CFWSTERM	0x0008		/* SCSI high byte termination (wide card) */
    167       1.1   mycroft #define CFSPARITY	0x0010		/* SCSI parity */
    168       1.1   mycroft /* UNUSED		0x0020 */
    169       1.1   mycroft #define CFRESETB	0x0040		/* reset SCSI bus at IC initialization */
    170       1.1   mycroft /* UNUSED		0xff80 */
    171       1.1   mycroft   u_int16_t adapter_control;	/* word 17 */
    172       1.1   mycroft 
    173       1.1   mycroft /*
    174       1.1   mycroft  * Bus Release, Host Adapter ID
    175       1.1   mycroft  */
    176       1.1   mycroft #define CFSCSIID	0x000f		/* host adapter SCSI ID */
    177       1.1   mycroft /* UNUSED		0x00f0 */
    178       1.1   mycroft #define CFBRTIME	0xff00		/* bus release time */
    179       1.1   mycroft  u_int16_t brtime_id;		/* word 18 */
    180       1.1   mycroft 
    181       1.1   mycroft /*
    182       1.1   mycroft  * Maximum targets
    183       1.1   mycroft  */
    184       1.1   mycroft #define CFMAXTARG	0x00ff	/* maximum targets */
    185       1.1   mycroft /* UNUSED		0xff00 */
    186       1.1   mycroft   u_int16_t max_targets;		/* word 19 */
    187       1.1   mycroft 
    188       1.1   mycroft   u_int16_t res_1[11];		/* words 20-30 */
    189       1.1   mycroft   u_int16_t checksum;		/* word 31 */
    190       1.1   mycroft };
    191       1.1   mycroft 
    192       1.1   mycroft static void load_seeprom __P((struct ahc_data *ahc));
    193       1.3  explorer static int acquire_seeprom __P((struct seeprom_descriptor *sd));
    194       1.3  explorer static void release_seeprom __P((struct seeprom_descriptor *sd));
    195       1.1   mycroft 
    196       1.1   mycroft static u_char aic3940_count;
    197       1.1   mycroft 
    198       1.1   mycroft #if defined(__FreeBSD__)
    199       1.1   mycroft 
    200       1.1   mycroft static char* aic7870_probe __P((pcici_t tag, pcidi_t type));
    201       1.1   mycroft static void aic7870_attach __P((pcici_t config_id, int unit));
    202       1.1   mycroft 
    203       1.1   mycroft static struct  pci_device ahc_pci_driver = {
    204       1.1   mycroft 	"ahc",
    205       1.1   mycroft         aic7870_probe,
    206       1.1   mycroft         aic7870_attach,
    207       1.1   mycroft         &ahc_unit,
    208       1.1   mycroft 	NULL
    209       1.1   mycroft };
    210       1.1   mycroft 
    211       1.1   mycroft DATA_SET (pcidevice_set, ahc_pci_driver);
    212       1.1   mycroft 
    213       1.1   mycroft static  char*
    214       1.1   mycroft aic7870_probe (pcici_t tag, pcidi_t type)
    215       1.1   mycroft {
    216       1.1   mycroft 	switch(type) {
    217       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_3940U:
    218       1.1   mycroft 			return ("Adaptec 3940 Ultra SCSI host adapter");
    219       1.1   mycroft 			break;
    220       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_3940:
    221       1.1   mycroft 			return ("Adaptec 3940 SCSI host adapter");
    222       1.1   mycroft 			break;
    223       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_2944U:
    224       1.1   mycroft 			return ("Adaptec 2944 Ultra SCSI host adapter");
    225       1.1   mycroft 			break;
    226       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_2940U:
    227       1.1   mycroft 			return ("Adaptec 2940 Ultra SCSI host adapter");
    228       1.1   mycroft 			break;
    229       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_2944:
    230       1.1   mycroft 			return ("Adaptec 2944 SCSI host adapter");
    231       1.1   mycroft 			break;
    232       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_2940:
    233       1.1   mycroft 			return ("Adaptec 2940 SCSI host adapter");
    234       1.1   mycroft 			break;
    235       1.6     gibbs 		case PCI_DEVICE_ID_ADAPTEC_2940AU:
    236       1.6     gibbs 			return ("Adaptec 2940A Ultra SCSI host adapter");
    237       1.6     gibbs 			break;
    238       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_AIC7880:
    239       1.1   mycroft 			return ("Adaptec aic7880 Ultra SCSI host adapter");
    240       1.1   mycroft 			break;
    241       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_AIC7870:
    242       1.1   mycroft 			return ("Adaptec aic7870 SCSI host adapter");
    243       1.1   mycroft 			break;
    244       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_AIC7860:
    245       1.1   mycroft 			return ("Adaptec aic7860 SCSI host adapter");
    246       1.1   mycroft 			break;
    247       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_AIC7855:
    248       1.1   mycroft 			return ("Adaptec aic7855 SCSI host adapter");
    249       1.1   mycroft 			break;
    250       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_AIC7850:
    251       1.1   mycroft 			return ("Adaptec aic7850 SCSI host adapter");
    252       1.1   mycroft 			break;
    253       1.1   mycroft 		default:
    254       1.1   mycroft 			break;
    255       1.1   mycroft 	}
    256       1.1   mycroft 	return (0);
    257       1.1   mycroft 
    258       1.1   mycroft }
    259       1.1   mycroft 
    260       1.1   mycroft #elif defined(__NetBSD__)
    261       1.1   mycroft 
    262      1.10       cgd #ifdef	__BROKEN_INDIRECT_CONFIG
    263       1.1   mycroft int ahc_pci_probe __P((struct device *, void *, void *));
    264      1.10       cgd #else
    265      1.10       cgd int ahc_pci_probe __P((struct device *, struct cfdata *, void *));
    266      1.10       cgd #endif
    267       1.1   mycroft void ahc_pci_attach __P((struct device *, struct device *, void *));
    268       1.1   mycroft 
    269       1.1   mycroft struct cfattach ahc_pci_ca = {
    270       1.1   mycroft 	sizeof(struct ahc_data), ahc_pci_probe, ahc_pci_attach
    271       1.1   mycroft };
    272       1.1   mycroft 
    273       1.1   mycroft int
    274       1.1   mycroft ahc_pci_probe(parent, match, aux)
    275       1.1   mycroft         struct device *parent;
    276      1.10       cgd #ifdef	__BROKEN_INDIRECT_CONFIG
    277      1.11       cgd         void *match;
    278      1.10       cgd #else
    279      1.11       cgd         struct cfdata *match;
    280      1.10       cgd #endif
    281      1.11       cgd         void *aux;
    282       1.1   mycroft {
    283       1.1   mycroft         struct pci_attach_args *pa = aux;
    284       1.1   mycroft 
    285       1.1   mycroft 	switch (pa->pa_id) {
    286       1.1   mycroft 	case PCI_DEVICE_ID_ADAPTEC_3940U:
    287       1.1   mycroft 	case PCI_DEVICE_ID_ADAPTEC_2944U:
    288       1.1   mycroft 	case PCI_DEVICE_ID_ADAPTEC_2940U:
    289       1.6     gibbs 	case PCI_DEVICE_ID_ADAPTEC_2940AU:
    290       1.1   mycroft 	case PCI_DEVICE_ID_ADAPTEC_3940:
    291       1.1   mycroft 	case PCI_DEVICE_ID_ADAPTEC_2944:
    292       1.1   mycroft 	case PCI_DEVICE_ID_ADAPTEC_2940:
    293       1.1   mycroft 	case PCI_DEVICE_ID_ADAPTEC_AIC7880:
    294       1.1   mycroft 	case PCI_DEVICE_ID_ADAPTEC_AIC7870:
    295       1.1   mycroft 	case PCI_DEVICE_ID_ADAPTEC_AIC7860:
    296       1.1   mycroft 	case PCI_DEVICE_ID_ADAPTEC_AIC7855:
    297       1.1   mycroft 	case PCI_DEVICE_ID_ADAPTEC_AIC7850:
    298       1.1   mycroft 		return 1;
    299       1.1   mycroft 	}
    300       1.1   mycroft 	return 0;
    301       1.1   mycroft }
    302       1.1   mycroft #endif /* defined(__NetBSD__) */
    303       1.1   mycroft 
    304       1.1   mycroft #if defined(__FreeBSD__)
    305       1.1   mycroft static void
    306       1.1   mycroft aic7870_attach(config_id, unit)
    307       1.1   mycroft 	pcici_t config_id;
    308       1.1   mycroft 	int	unit;
    309       1.1   mycroft #elif defined(__NetBSD__)
    310       1.1   mycroft void
    311       1.1   mycroft ahc_pci_attach(parent, self, aux)
    312       1.1   mycroft         struct device *parent, *self;
    313       1.1   mycroft         void *aux;
    314       1.1   mycroft #endif
    315       1.1   mycroft {
    316       1.1   mycroft #if defined(__FreeBSD__)
    317       1.1   mycroft 	u_long io_port;
    318       1.7  christos 	int unit = ahc->sc_dev.dv_unit;
    319       1.1   mycroft #elif defined(__NetBSD__)
    320       1.1   mycroft 	struct pci_attach_args *pa = aux;
    321       1.1   mycroft 	struct ahc_data *ahc = (void *)self;
    322      1.13       cgd 	bus_space_tag_t st, iot, memt;
    323      1.13       cgd 	bus_space_handle_t sh, ioh, memh;
    324      1.13       cgd 	int ioh_valid, memh_valid;
    325       1.1   mycroft 	pci_intr_handle_t ih;
    326       1.1   mycroft 	const char *intrstr;
    327       1.1   mycroft #endif
    328       1.1   mycroft 	u_long id;
    329       1.1   mycroft 	unsigned opri = 0;
    330       1.1   mycroft 	ahc_type ahc_t = AHC_NONE;
    331       1.1   mycroft 	ahc_flag ahc_f = AHC_FNONE;
    332       1.1   mycroft #if defined(__FreeBSD__)
    333       1.1   mycroft 	struct ahc_data *ahc;
    334       1.1   mycroft #endif
    335       1.1   mycroft 	u_char ultra_enb = 0;
    336       1.1   mycroft 	u_char our_id = 0;
    337       1.1   mycroft 
    338       1.1   mycroft #if defined(__FreeBSD__)
    339       1.1   mycroft         if(!(io_port = pci_conf_read(config_id, PCI_BASEADR0)))
    340       1.1   mycroft 		return;
    341       1.1   mycroft 	/*
    342       1.1   mycroft 	 * The first bit of PCI_BASEADR0 is always
    343       1.1   mycroft 	 * set hence we mask it off.
    344       1.1   mycroft 	 */
    345       1.1   mycroft 	io_port &= 0xfffffffe;
    346       1.1   mycroft #elif defined(__NetBSD__)
    347      1.14       cgd 	ioh_valid = (pci_mapreg_map(pa, PCI_BASEADR_IO,
    348      1.13       cgd 	    PCI_MAPREG_TYPE_IO, 0,
    349      1.13       cgd 	    &iot, &ioh, NULL, NULL) == 0);
    350      1.14       cgd 	memh_valid = (pci_mapreg_map(pa, PCI_BASEADR_MEM,
    351      1.13       cgd 	    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
    352      1.13       cgd 	    &memt, &memh, NULL, NULL) == 0);
    353      1.13       cgd 
    354      1.13       cgd 	if (memh_valid) {
    355      1.13       cgd 		st = memt;
    356      1.13       cgd 		sh = memh;
    357      1.13       cgd 	} else if (ioh_valid) {
    358      1.13       cgd 		st = iot;
    359      1.13       cgd 		sh = ioh;
    360      1.12       cgd 	} else {
    361      1.13       cgd 		printf(": unable to map registers\n");
    362       1.1   mycroft 		return;
    363      1.12       cgd 	}
    364      1.12       cgd 	printf("\n");
    365       1.1   mycroft #endif
    366       1.1   mycroft 
    367       1.1   mycroft #if defined(__FreeBSD__)
    368       1.1   mycroft 	switch ((id = pci_conf_read(config_id, PCI_ID_REG))) {
    369       1.1   mycroft #elif defined(__NetBSD__)
    370       1.1   mycroft 	switch (id = pa->pa_id) {
    371       1.1   mycroft #endif
    372       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_3940U:
    373       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_3940:
    374       1.1   mycroft 			if (id == PCI_DEVICE_ID_ADAPTEC_3940U)
    375       1.1   mycroft 				ahc_t = AHC_394U;
    376       1.1   mycroft 			else
    377       1.1   mycroft 				ahc_t = AHC_394;
    378       1.1   mycroft 			aic3940_count++;
    379       1.1   mycroft 			if(!(aic3940_count & 0x01))
    380       1.1   mycroft 				/* Even count implies second channel */
    381       1.1   mycroft 				ahc_f |= AHC_CHNLB;
    382       1.1   mycroft 			break;
    383       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_2944U:
    384       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_2940U:
    385       1.1   mycroft 			ahc_t = AHC_294U;
    386       1.1   mycroft 			break;
    387       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_2944:
    388       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_2940:
    389       1.1   mycroft 			ahc_t = AHC_294;
    390       1.1   mycroft 			break;
    391       1.6     gibbs 		case PCI_DEVICE_ID_ADAPTEC_2940AU:
    392       1.6     gibbs 			ahc_t = AHC_294AU;
    393       1.6     gibbs 			break;
    394       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_AIC7880:
    395       1.1   mycroft 			ahc_t = AHC_AIC7880;
    396       1.1   mycroft 			break;
    397       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_AIC7870:
    398       1.1   mycroft 			ahc_t = AHC_AIC7870;
    399       1.1   mycroft 			break;
    400       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_AIC7860:
    401       1.1   mycroft 			ahc_t = AHC_AIC7860;
    402       1.1   mycroft 			break;
    403       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_AIC7855:
    404       1.1   mycroft 		case PCI_DEVICE_ID_ADAPTEC_AIC7850:
    405       1.1   mycroft 			ahc_t = AHC_AIC7850;
    406       1.1   mycroft 			break;
    407       1.1   mycroft 		default:
    408       1.1   mycroft 			break;
    409       1.1   mycroft 	}
    410       1.1   mycroft 
    411       1.1   mycroft 	/* On all PCI adapters, we allow SCB paging */
    412       1.1   mycroft 	ahc_f |= AHC_PAGESCBS;
    413       1.1   mycroft 
    414       1.1   mycroft 	/* Remeber how the card was setup in case there is no SEEPROM */
    415       1.1   mycroft #if defined(__FreeBSD__)
    416       1.1   mycroft 	our_id = inb(SCSIID + io_port) & OID;
    417       1.1   mycroft 	if(ahc_t & AHC_ULTRA)
    418       1.1   mycroft 		ultra_enb = inb(SXFRCTL0 + io_port) & ULTRAEN;
    419       1.1   mycroft #else
    420      1.12       cgd 	our_id = bus_space_read_1(st, sh, SCSIID) & OID;
    421       1.1   mycroft 	if(ahc_t & AHC_ULTRA)
    422      1.12       cgd 		ultra_enb = bus_space_read_1(st, sh, SXFRCTL0) & ULTRAEN;
    423       1.1   mycroft #endif
    424       1.1   mycroft 
    425       1.1   mycroft #if defined(__FreeBSD__)
    426       1.1   mycroft 	ahc_reset(io_port);
    427       1.1   mycroft #elif defined(__NetBSD__)
    428      1.12       cgd 	ahc_reset(ahc->sc_dev.dv_xname, st, sh);
    429       1.1   mycroft #endif
    430       1.1   mycroft 
    431       1.1   mycroft 	if(ahc_t & AHC_AIC7870){
    432       1.1   mycroft #if defined(__FreeBSD__)
    433       1.1   mycroft 		u_long devconfig = pci_conf_read(config_id, DEVCONFIG);
    434       1.1   mycroft #elif defined(__NetBSD__)
    435       1.1   mycroft 		u_long devconfig =
    436       1.1   mycroft 			pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG);
    437       1.1   mycroft #endif
    438       1.1   mycroft 
    439       1.1   mycroft 		if(devconfig & (RAMPSM)) {
    440       1.1   mycroft 			/*
    441       1.1   mycroft 			 * External SRAM present.  Have the probe walk
    442       1.1   mycroft 			 * the SCBs to see how much SRAM we have and set
    443       1.1   mycroft 			 * the number of SCBs accordingly.  We have to
    444       1.1   mycroft 			 * turn off SCBRAMSEL to access the external
    445       1.1   mycroft 			 * SCB SRAM.
    446       1.1   mycroft 			 *
    447       1.1   mycroft 			 * It seems that early versions of the aic7870
    448       1.1   mycroft 			 * didn't use these bits, hence the hack for the
    449       1.1   mycroft 			 * 3940 above.  I would guess that recent 3940s
    450       1.1   mycroft 			 * using later aic7870 or aic7880 chips do
    451       1.1   mycroft 			 * actually set RAMPSM.
    452       1.1   mycroft 			 *
    453       1.1   mycroft 			 * The documentation isn't clear, but it sounds
    454       1.1   mycroft 			 * like the value written to devconfig must not
    455       1.1   mycroft 			 * have RAMPSM set.  The second sixteen bits of
    456       1.1   mycroft 			 * the register are R/O anyway, so it shouldn't
    457       1.1   mycroft 			 * affect RAMPSM either way.
    458       1.1   mycroft 			 */
    459       1.1   mycroft 			devconfig &= ~(RAMPSM|SCBRAMSEL);
    460       1.1   mycroft #if defined(__FreeBSD__)
    461       1.1   mycroft 			pci_conf_write(config_id, DEVCONFIG, devconfig);
    462       1.1   mycroft #elif defined(__NetBSD__)
    463       1.1   mycroft 			pci_conf_write(pa->pa_pc, pa->pa_tag,
    464       1.1   mycroft 				       DEVCONFIG, devconfig);
    465       1.1   mycroft #endif
    466       1.1   mycroft 		}
    467       1.1   mycroft 	}
    468       1.1   mycroft 
    469       1.1   mycroft #if defined(__FreeBSD__)
    470       1.1   mycroft 	if(!(ahc = ahc_alloc(unit, io_port, ahc_t, ahc_f)))
    471       1.1   mycroft 		return;  /* XXX PCI code should take return status */
    472       1.1   mycroft 
    473       1.1   mycroft 	if(!(pci_map_int(config_id, ahc_intr, (void *)ahc, &bio_imask))) {
    474       1.1   mycroft 		ahc_free(ahc);
    475       1.1   mycroft 		return;
    476       1.1   mycroft 	}
    477       1.1   mycroft #elif defined(__NetBSD__)
    478      1.12       cgd 	ahc_construct(ahc, st, sh, ahc_t, ahc_f);
    479       1.1   mycroft 
    480       1.1   mycroft 	if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
    481       1.1   mycroft 			 pa->pa_intrline, &ih)) {
    482       1.8  christos 		printf("%s: couldn't map interrupt\n", ahc->sc_dev.dv_xname);
    483       1.1   mycroft 		ahc_free(ahc);
    484       1.1   mycroft 		return;
    485       1.1   mycroft 	}
    486       1.1   mycroft 	intrstr = pci_intr_string(pa->pa_pc, ih);
    487       1.4       cgd 	ahc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ahc_intr, ahc);
    488       1.1   mycroft 	if (ahc->sc_ih == NULL) {
    489       1.8  christos 		printf("%s: couldn't establish interrupt",
    490       1.1   mycroft 		       ahc->sc_dev.dv_xname);
    491       1.1   mycroft 		if (intrstr != NULL)
    492       1.8  christos 			printf(" at %s", intrstr);
    493       1.8  christos 		printf("\n");
    494       1.1   mycroft 		ahc_free(ahc);
    495       1.1   mycroft 		return;
    496       1.1   mycroft 	}
    497       1.1   mycroft 	if (intrstr != NULL)
    498       1.8  christos 		printf("%s: interrupting at %s\n", ahc->sc_dev.dv_xname,
    499       1.1   mycroft 		       intrstr);
    500       1.1   mycroft #endif
    501       1.1   mycroft 	/*
    502       1.1   mycroft 	 * Protect ourself from spurrious interrupts during
    503       1.1   mycroft 	 * intialization.
    504       1.1   mycroft 	 */
    505       1.1   mycroft 	opri = splbio();
    506       1.1   mycroft 
    507       1.1   mycroft 	/*
    508       1.1   mycroft 	 * Do aic7870/aic7880/aic7850 specific initialization
    509       1.1   mycroft 	 */
    510       1.1   mycroft 	{
    511       1.1   mycroft 		u_char	sblkctl;
    512       1.1   mycroft 		char	*id_string;
    513       1.1   mycroft 
    514       1.1   mycroft 		switch(ahc->type) {
    515       1.1   mycroft 		   case AHC_394U:
    516       1.1   mycroft 		   case AHC_294U:
    517       1.1   mycroft 		   case AHC_AIC7880:
    518       1.1   mycroft 		   {
    519       1.1   mycroft 			id_string = "aic7880 ";
    520       1.1   mycroft 			load_seeprom(ahc);
    521       1.1   mycroft 			break;
    522       1.1   mycroft 		   }
    523       1.1   mycroft 		   case AHC_394:
    524       1.1   mycroft 		   case AHC_294:
    525       1.1   mycroft 		   case AHC_AIC7870:
    526       1.1   mycroft 		   {
    527       1.1   mycroft 			id_string = "aic7870 ";
    528       1.1   mycroft 			load_seeprom(ahc);
    529       1.1   mycroft 			break;
    530       1.1   mycroft 		   }
    531       1.6     gibbs 		   case AHC_294AU:
    532       1.1   mycroft 		   case AHC_AIC7860:
    533       1.1   mycroft 		   {
    534       1.1   mycroft 			id_string = "aic7860 ";
    535       1.6     gibbs 			load_seeprom(ahc);
    536       1.1   mycroft 			break;
    537       1.1   mycroft 		   }
    538       1.1   mycroft 		   case AHC_AIC7850:
    539       1.1   mycroft 		   {
    540       1.1   mycroft 			id_string = "aic7850 ";
    541       1.1   mycroft 			/*
    542       1.1   mycroft 			 * Use defaults, if the chip wasn't initialized by
    543       1.1   mycroft 			 * a BIOS.
    544       1.1   mycroft 			 */
    545       1.1   mycroft 			ahc->flags |= AHC_USEDEFAULTS;
    546       1.1   mycroft 			break;
    547       1.1   mycroft 		   }
    548       1.1   mycroft 		   default:
    549       1.1   mycroft 		   {
    550       1.8  christos 			printf("ahc: Unknown controller type.  Ignoring.\n");
    551       1.1   mycroft 			ahc_free(ahc);
    552       1.1   mycroft 			splx(opri);
    553       1.1   mycroft 			return;
    554       1.1   mycroft 		   }
    555       1.1   mycroft 		}
    556       1.1   mycroft 
    557       1.1   mycroft 		/*
    558       1.1   mycroft 		 * Take the LED out of diagnostic mode
    559       1.1   mycroft 		 */
    560       1.1   mycroft 		sblkctl = AHC_INB(ahc, SBLKCTL);
    561       1.1   mycroft 		AHC_OUTB(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON)));
    562       1.1   mycroft 
    563       1.1   mycroft 		/*
    564       1.1   mycroft 		 * I don't know where this is set in the SEEPROM or by the
    565       1.1   mycroft 		 * BIOS, so we default to 100%.
    566       1.1   mycroft 		 */
    567       1.1   mycroft 		AHC_OUTB(ahc, DSPCISTATUS, DFTHRSH_100);
    568       1.1   mycroft 
    569       1.1   mycroft 		if(ahc->flags & AHC_USEDEFAULTS) {
    570       1.1   mycroft 			/*
    571       1.1   mycroft 			 * PCI Adapter default setup
    572       1.1   mycroft 			 * Should only be used if the adapter does not have
    573       1.1   mycroft 			 * an SEEPROM.
    574       1.1   mycroft 			 */
    575       1.1   mycroft 			/* See if someone else set us up already */
    576       1.1   mycroft 			u_long i;
    577       1.1   mycroft 		        for(i = TARG_SCRATCH; i < 0x60; i++) {
    578       1.3  explorer                         	if(AHC_INB(ahc, i) != 0x00)
    579       1.1   mycroft 					break;
    580       1.1   mycroft 			}
    581       1.3  explorer 			if(i == TARG_SCRATCH) {
    582       1.3  explorer 				/*
    583       1.3  explorer 				 * Try looking for all ones.  You can get
    584       1.3  explorer 				 * either.
    585       1.3  explorer 				 */
    586       1.3  explorer 		        	for (i = TARG_SCRATCH; i < 0x60; i++) {
    587       1.3  explorer                         		if(AHC_INB(ahc, i) != 0xff)
    588       1.3  explorer 						break;
    589       1.3  explorer 				}
    590       1.3  explorer 			}
    591       1.3  explorer 			if((i != 0x60) && (our_id != 0)) {
    592       1.8  christos 				printf("%s: Using left over BIOS settings\n",
    593       1.1   mycroft 					ahc_name(ahc));
    594       1.1   mycroft 				ahc->flags &= ~AHC_USEDEFAULTS;
    595       1.1   mycroft 			}
    596       1.1   mycroft 			else
    597       1.1   mycroft 				our_id = 0x07;
    598       1.1   mycroft 			AHC_OUTB(ahc, SCSICONF,
    599       1.1   mycroft 				 (our_id & 0x07)|ENSPCHK|RESET_SCSI);
    600       1.1   mycroft 			/* In case we are a wide card */
    601       1.1   mycroft 			AHC_OUTB(ahc, SCSICONF + 1, our_id);
    602       1.1   mycroft 
    603       1.1   mycroft 			if(!ultra_enb || (ahc->flags & AHC_USEDEFAULTS)) {
    604       1.1   mycroft 				/*
    605       1.1   mycroft 				 * If there wasn't a BIOS or the board
    606       1.1   mycroft 				 * wasn't in this mode to begin with,
    607       1.1   mycroft 				 * turn off ultra.
    608       1.1   mycroft 				 */
    609       1.1   mycroft 				ahc->type &= ~AHC_ULTRA;
    610       1.1   mycroft 			}
    611       1.1   mycroft 		}
    612       1.1   mycroft 
    613       1.8  christos 		printf("%s: %s", ahc_name(ahc), id_string);
    614       1.1   mycroft 	}
    615       1.1   mycroft 
    616       1.1   mycroft 	if(ahc_init(ahc)){
    617       1.1   mycroft 		ahc_free(ahc);
    618       1.1   mycroft 		splx(opri);
    619       1.1   mycroft 		return; /* XXX PCI code should take return status */
    620       1.1   mycroft 	}
    621       1.1   mycroft 	splx(opri);
    622       1.1   mycroft 
    623       1.1   mycroft 	ahc_attach(ahc);
    624       1.1   mycroft }
    625       1.1   mycroft 
    626       1.1   mycroft /*
    627       1.1   mycroft  * Read the SEEPROM.  Return 0 on failure
    628       1.1   mycroft  */
    629       1.1   mycroft void
    630       1.1   mycroft load_seeprom(ahc)
    631       1.1   mycroft 	struct	ahc_data *ahc;
    632       1.1   mycroft {
    633       1.1   mycroft 	struct	seeprom_descriptor sd;
    634       1.1   mycroft 	struct	seeprom_config sc;
    635       1.1   mycroft 	u_short *scarray = (u_short *)&sc;
    636       1.1   mycroft 	u_short	checksum = 0;
    637       1.1   mycroft 	u_char	scsi_conf;
    638       1.1   mycroft 	u_char	host_id;
    639       1.1   mycroft 	int	have_seeprom;
    640       1.1   mycroft 
    641       1.1   mycroft #if defined(__FreeBSD__)
    642       1.1   mycroft 	sd.sd_iobase = ahc->baseport + SEECTL;
    643       1.1   mycroft #elif defined(__NetBSD__)
    644      1.12       cgd 	sd.sd_st = ahc->sc_st;
    645      1.12       cgd 	sd.sd_sh = ahc->sc_sh;
    646       1.1   mycroft 	sd.sd_offset = SEECTL;
    647       1.1   mycroft #endif
    648       1.1   mycroft 	sd.sd_MS = SEEMS;
    649       1.1   mycroft 	sd.sd_RDY = SEERDY;
    650       1.1   mycroft 	sd.sd_CS = SEECS;
    651       1.1   mycroft 	sd.sd_CK = SEECK;
    652       1.1   mycroft 	sd.sd_DO = SEEDO;
    653       1.1   mycroft 	sd.sd_DI = SEEDI;
    654       1.1   mycroft 
    655       1.1   mycroft 	if(bootverbose)
    656       1.8  christos 		printf("%s: Reading SEEPROM...", ahc_name(ahc));
    657       1.1   mycroft 	have_seeprom = acquire_seeprom(&sd);
    658       1.1   mycroft 	if (have_seeprom) {
    659       1.1   mycroft 		have_seeprom = read_seeprom(&sd,
    660       1.1   mycroft 					    (u_int16_t *)&sc,
    661       1.1   mycroft 					    ahc->flags & AHC_CHNLB,
    662       1.1   mycroft 					    sizeof(sc)/2);
    663       1.1   mycroft 		release_seeprom(&sd);
    664       1.1   mycroft 		if (have_seeprom) {
    665       1.1   mycroft 			/* Check checksum */
    666       1.1   mycroft 			int i;
    667       1.1   mycroft 
    668       1.1   mycroft 			for (i = 0;i < (sizeof(sc)/2 - 1);i = i + 1)
    669       1.1   mycroft 				checksum = checksum + scarray[i];
    670       1.1   mycroft 			if (checksum != sc.checksum) {
    671       1.1   mycroft 				if(bootverbose)
    672       1.8  christos 					printf ("checksum error");
    673       1.1   mycroft 				have_seeprom = 0;
    674       1.1   mycroft 			}
    675       1.1   mycroft 			else if(bootverbose)
    676       1.8  christos 				printf("done.\n");
    677       1.1   mycroft 		}
    678       1.1   mycroft 	}
    679       1.1   mycroft 	if (!have_seeprom) {
    680       1.1   mycroft 		if(bootverbose)
    681       1.8  christos 			printf("\n%s: No SEEPROM availible\n", ahc_name(ahc));
    682       1.1   mycroft 		ahc->flags |= AHC_USEDEFAULTS;
    683       1.1   mycroft 	}
    684       1.1   mycroft 	else {
    685       1.1   mycroft 		/*
    686       1.1   mycroft 		 * Put the data we've collected down into SRAM
    687       1.1   mycroft 		 * where ahc_init will find it.
    688       1.1   mycroft 		 */
    689       1.1   mycroft 		int i;
    690       1.1   mycroft 		int max_targ = sc.max_targets & CFMAXTARG;
    691       1.1   mycroft 
    692       1.3  explorer 	        for(i = 0; i < max_targ; i++){
    693       1.1   mycroft 	                u_char target_settings;
    694       1.1   mycroft 			target_settings = (sc.device_flags[i] & CFXFER) << 4;
    695       1.1   mycroft 			if (sc.device_flags[i] & CFSYNCH)
    696       1.1   mycroft 				target_settings |= SOFS;
    697       1.1   mycroft 			if (sc.device_flags[i] & CFWIDEB)
    698       1.1   mycroft 				target_settings |= WIDEXFER;
    699       1.1   mycroft 			if (sc.device_flags[i] & CFDISC)
    700       1.1   mycroft 				ahc->discenable |= (0x01 << i);
    701       1.1   mycroft 			AHC_OUTB(ahc, TARG_SCRATCH+i, target_settings);
    702       1.1   mycroft 		}
    703       1.1   mycroft 		AHC_OUTB(ahc, DISC_DSB, ~(ahc->discenable & 0xff));
    704       1.1   mycroft 		AHC_OUTB(ahc, DISC_DSB + 1, ~((ahc->discenable >> 8) & 0xff));
    705       1.1   mycroft 
    706       1.1   mycroft 		host_id = sc.brtime_id & CFSCSIID;
    707       1.1   mycroft 
    708       1.1   mycroft 		scsi_conf = (host_id & 0x7);
    709       1.1   mycroft 		if(sc.adapter_control & CFSPARITY)
    710       1.1   mycroft 			scsi_conf |= ENSPCHK;
    711       1.1   mycroft 		if(sc.adapter_control & CFRESETB)
    712       1.1   mycroft 			scsi_conf |= RESET_SCSI;
    713       1.1   mycroft 
    714       1.1   mycroft 		if(ahc->type & AHC_ULTRA) {
    715       1.1   mycroft 			/* Should we enable Ultra mode? */
    716       1.1   mycroft 			if(!(sc.adapter_control & CFULTRAEN))
    717       1.1   mycroft 				/* Treat us as a non-ultra card */
    718       1.1   mycroft 				ahc->type &= ~AHC_ULTRA;
    719       1.1   mycroft 		}
    720       1.1   mycroft 		/* Set the host ID */
    721       1.1   mycroft 		AHC_OUTB(ahc, SCSICONF, scsi_conf);
    722       1.1   mycroft 		/* In case we are a wide card */
    723       1.1   mycroft 		AHC_OUTB(ahc, SCSICONF + 1, host_id);
    724       1.1   mycroft 	}
    725       1.3  explorer }
    726       1.3  explorer 
    727       1.3  explorer static int
    728       1.3  explorer acquire_seeprom(sd)
    729       1.3  explorer 	struct seeprom_descriptor *sd;
    730       1.3  explorer {
    731       1.3  explorer 	int wait;
    732       1.3  explorer 
    733       1.3  explorer 	/*
    734       1.3  explorer 	 * Request access of the memory port.  When access is
    735       1.3  explorer 	 * granted, SEERDY will go high.  We use a 1 second
    736       1.3  explorer 	 * timeout which should be near 1 second more than
    737       1.3  explorer 	 * is needed.  Reason: after the chip reset, there
    738       1.3  explorer 	 * should be no contention.
    739       1.3  explorer 	 */
    740       1.3  explorer 	SEEPROM_OUTB(sd, sd->sd_MS);
    741       1.3  explorer 	wait = 1000;  /* 1 second timeout in msec */
    742       1.3  explorer 	while (--wait && ((SEEPROM_INB(sd) & sd->sd_RDY) == 0)) {
    743       1.3  explorer 		DELAY (1000);  /* delay 1 msec */
    744       1.3  explorer         }
    745       1.3  explorer 	if ((SEEPROM_INB(sd) & sd->sd_RDY) == 0) {
    746       1.3  explorer 		SEEPROM_OUTB(sd, 0);
    747       1.3  explorer 		return (0);
    748       1.3  explorer 	}
    749       1.3  explorer 	return(1);
    750       1.3  explorer }
    751       1.3  explorer 
    752       1.3  explorer static void
    753       1.3  explorer release_seeprom(sd)
    754       1.3  explorer 	struct seeprom_descriptor *sd;
    755       1.3  explorer {
    756       1.3  explorer 	/* Release access to the memory port and the serial EEPROM. */
    757       1.3  explorer 	SEEPROM_OUTB(sd, 0);
    758       1.1   mycroft }
    759       1.1   mycroft 
    760       1.1   mycroft #endif /* NPCI > 0 */
    761