From b36b7d853f95bfe6f793629fb2e45ba61ecb8089 Mon Sep 17 00:00:00 2001 From: "Justin T. Gibbs" Date: Mon, 28 Oct 1996 06:10:33 +0000 Subject: [PATCH] Add basic support for the 398X cards as multi-channel SCSI host adapters. This involves expanding the support of the SEEPROM routines to deal with the larger SEEPROMs on these cards and providing a mechanism to share SCB arrays between multiple controllers. Most of the 398X support came from Dan Eischer. ahc_data -> ahc_softc Clean up some more type bogons I missed from the last pass. --- sys/pci/aic7870.c | 129 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 106 insertions(+), 23 deletions(-) diff --git a/sys/pci/aic7870.c b/sys/pci/aic7870.c index 71db22ced89c..3a224100500f 100644 --- a/sys/pci/aic7870.c +++ b/sys/pci/aic7870.c @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: aic7870.c,v 1.11.2.18 1996/10/06 16:42:35 gibbs Exp $ + * $Id: aic7870.c,v 1.40 1996/10/25 06:43:10 gibbs Exp $ */ #if defined(__FreeBSD__) @@ -80,10 +80,12 @@ #endif /* defined(__NetBSD__) */ +#define PCI_DEVICE_ID_ADAPTEC_398XU 0x83789004ul #define PCI_DEVICE_ID_ADAPTEC_3940U 0x82789004ul #define PCI_DEVICE_ID_ADAPTEC_2944U 0x84789004ul #define PCI_DEVICE_ID_ADAPTEC_2940U 0x81789004ul #define PCI_DEVICE_ID_ADAPTEC_2940AU 0x61789004ul +#define PCI_DEVICE_ID_ADAPTEC_398X 0x73789004ul #define PCI_DEVICE_ID_ADAPTEC_3940 0x72789004ul #define PCI_DEVICE_ID_ADAPTEC_2944 0x74789004ul #define PCI_DEVICE_ID_ADAPTEC_2940 0x71789004ul @@ -92,6 +94,7 @@ #define PCI_DEVICE_ID_ADAPTEC_AIC7860 0x60789004ul #define PCI_DEVICE_ID_ADAPTEC_AIC7855 0x55789004ul #define PCI_DEVICE_ID_ADAPTEC_AIC7850 0x50789004ul +#define PCI_DEVICE_ID_ADAPTEC_AIC7810 0x10789004ul #define DEVCONFIG 0x40 #define MPORTMODE 0x00000400ul /* aic7870 only */ @@ -176,11 +179,13 @@ struct seeprom_config { u_int16_t checksum; /* word 31 */ }; -static void load_seeprom __P((struct ahc_data *ahc)); +static void load_seeprom __P((struct ahc_softc *ahc)); static int acquire_seeprom __P((struct seeprom_descriptor *sd)); static void release_seeprom __P((struct seeprom_descriptor *sd)); -static u_char aic3940_count; +static int aic3940_count; +static int aic398X_count; +static struct ahc_softc *first_398X; #if defined(__FreeBSD__) @@ -201,9 +206,15 @@ static char* aic7870_probe (pcici_t tag, pcidi_t type) { switch (type) { + case PCI_DEVICE_ID_ADAPTEC_398XU: + return ("Adaptec 398X Ultra SCSI RAID adapter"); + break; case PCI_DEVICE_ID_ADAPTEC_3940U: return ("Adaptec 3940 Ultra SCSI host adapter"); break; + case PCI_DEVICE_ID_ADAPTEC_398X: + return ("Adaptec 398X SCSI RAID adapter"); + break; case PCI_DEVICE_ID_ADAPTEC_3940: return ("Adaptec 3940 SCSI host adapter"); break; @@ -237,6 +248,9 @@ aic7870_probe (pcici_t tag, pcidi_t type) case PCI_DEVICE_ID_ADAPTEC_AIC7850: return ("Adaptec aic7850 SCSI host adapter"); break; + case PCI_DEVICE_ID_ADAPTEC_AIC7810: + return ("Adaptec aic7810 RAID memory controller"); + break; default: break; } @@ -250,7 +264,7 @@ int ahc_pci_probe __P((struct device *, void *, void *)); void ahc_pci_attach __P((struct device *, struct device *, void *)); struct cfattach ahc_pci_ca = { - sizeof(struct ahc_data), ahc_pci_probe, ahc_pci_attach + sizeof(struct ahc_softc), ahc_pci_probe, ahc_pci_attach }; int @@ -261,10 +275,12 @@ ahc_pci_probe(parent, match, aux) struct pci_attach_args *pa = aux; switch (pa->pa_id) { + case PCI_DEVICE_ID_ADAPTEC_398XU: case PCI_DEVICE_ID_ADAPTEC_3940U: case PCI_DEVICE_ID_ADAPTEC_2944U: case PCI_DEVICE_ID_ADAPTEC_2940U: case PCI_DEVICE_ID_ADAPTEC_2940AU: + case PCI_DEVICE_ID_ADAPTEC_398X: case PCI_DEVICE_ID_ADAPTEC_3940: case PCI_DEVICE_ID_ADAPTEC_2944: case PCI_DEVICE_ID_ADAPTEC_2940: @@ -273,6 +289,7 @@ ahc_pci_probe(parent, match, aux) case PCI_DEVICE_ID_ADAPTEC_AIC7860: case PCI_DEVICE_ID_ADAPTEC_AIC7855: case PCI_DEVICE_ID_ADAPTEC_AIC7850: + case PCI_DEVICE_ID_ADAPTEC_AIC7810: return 1; } return 0; @@ -293,10 +310,10 @@ ahc_pci_attach(parent, self, aux) { #if defined(__FreeBSD__) u_int16_t io_port; - struct ahc_data *ahc; + struct ahc_softc *ahc; #elif defined(__NetBSD__) struct pci_attach_args *pa = aux; - struct ahc_data *ahc = (void *)self; + struct ahc_softc *ahc = (void *)self; int unit = ahc->sc_dev.dv_unit; bus_io_addr_t iobase; bus_io_size_t iosize; @@ -305,6 +322,7 @@ ahc_pci_attach(parent, self, aux) const char *intrstr; #endif u_int32_t id; + struct scb_data *shared_scb_data; int opri = 0; ahc_type ahc_t = AHC_NONE; ahc_flag ahc_f = AHC_FNONE; @@ -313,12 +331,17 @@ ahc_pci_attach(parent, self, aux) u_int8_t ultra_enb = 0; u_int8_t our_id = 0; + shared_scb_data = NULL; #if defined(__FreeBSD__) if (pci_map_port(config_id, PCI_BASEADR0, &io_port) == 0) return; - +#ifdef AHC_FORCE_PIO + vaddr = NULL; + paddr = NULL; +#else if (pci_map_mem(config_id, PCI_BASEADR1, &vaddr, &paddr) == 0) return; +#endif #elif defined(__NetBSD__) if (pci_io_find(pa->pa_pc, pa->pa_tag, PCI_BASEADR0, &iobase, &iosize)) return; @@ -331,16 +354,40 @@ ahc_pci_attach(parent, self, aux) #elif defined(__NetBSD__) switch (id = pa->pa_id) { #endif + case PCI_DEVICE_ID_ADAPTEC_398XU: + case PCI_DEVICE_ID_ADAPTEC_398X: + if (id == PCI_DEVICE_ID_ADAPTEC_398XU) + ahc_t = AHC_398U; + else + ahc_t = AHC_398; + switch (aic398X_count) { + case 0: + break; + case 1: + ahc_f |= AHC_CHNLB; + break; + case 2: + ahc_f |= AHC_CHNLC; + break; + default: + break; + } + aic398X_count++; + if (first_398X != NULL) +#ifdef AHC_SHARE_SCBS + shared_scb_data = first_398X->scb_data; +#endif + break; case PCI_DEVICE_ID_ADAPTEC_3940U: case PCI_DEVICE_ID_ADAPTEC_3940: if (id == PCI_DEVICE_ID_ADAPTEC_3940U) ahc_t = AHC_394U; else ahc_t = AHC_394; - aic3940_count++; - if ((aic3940_count & 0x01) == 0) - /* Even count implies second channel */ + if ((aic3940_count & 0x01) != 0) + /* Odd count implies second channel */ ahc_f |= AHC_CHNLB; + aic3940_count++; break; case PCI_DEVICE_ID_ADAPTEC_2944U: case PCI_DEVICE_ID_ADAPTEC_2940U: @@ -366,6 +413,15 @@ ahc_pci_attach(parent, self, aux) case PCI_DEVICE_ID_ADAPTEC_AIC7850: ahc_t = AHC_AIC7850; break; + case PCI_DEVICE_ID_ADAPTEC_AIC7810: + /* + * This is the first device probed on a RAID + * controller, so reset our counts. + */ + aic398X_count = 0; + first_398X = NULL; + printf("RAID functionality unsupported\n"); + return; default: break; } @@ -399,11 +455,19 @@ ahc_pci_attach(parent, self, aux) pci_conf_read(pa->pa_pc, pa->pa_tag, DEVCONFIG); #endif +#ifdef AHC_SHARE_SCBS if (devconfig & (RAMPSM)) { - /* - * XXX What about EXTSCBTIME and EXTSCBPEN??? - * They are probably card dependant. + /* XXX Assume 9bit SRAM and enable parity checking */ + devconfig |= EXTSCBPEN; + + /* XXX Assume fast SRAM and only enable 2 cycle + * access if we are sharing the SRAM across mutiple + * adapters (398X adapter). */ + if ((devconfig & MPORTMODE) == 0) + /* Multi-user mode */ + devconfig |= EXTSCBTIME; + devconfig &= ~SCBRAMSEL; #if defined(__FreeBSD__) pci_conf_write(config_id, DEVCONFIG, devconfig); @@ -412,10 +476,12 @@ ahc_pci_attach(parent, self, aux) DEVCONFIG, devconfig); #endif } +#endif } #if defined(__FreeBSD__) - if ((ahc = ahc_alloc(unit, io_port, vaddr, ahc_t, ahc_f)) == NULL) + if ((ahc = ahc_alloc(unit, io_port, vaddr, ahc_t, ahc_f, + shared_scb_data)) == NULL) return; /* XXX PCI code should take return status */ if (!(pci_map_int(config_id, ahc_intr, (void *)ahc, &bio_imask))) { @@ -465,12 +531,14 @@ ahc_pci_attach(parent, self, aux) char *id_string; switch(ahc->type) { + case AHC_398U: case AHC_394U: case AHC_294U: case AHC_AIC7880: id_string = "aic7880 "; load_seeprom(ahc); break; + case AHC_398: case AHC_394: case AHC_294: case AHC_AIC7870: @@ -560,6 +628,12 @@ ahc_pci_attach(parent, self, aux) splx(opri); return; /* XXX PCI code should take return status */ } + + if ((ahc->type & AHC_398) == AHC_398) { + /* Only set this once we've successfully probed */ + if (shared_scb_data == NULL) + first_398X = ahc; + } splx(opri); ahc_attach(ahc); @@ -570,23 +644,32 @@ ahc_pci_attach(parent, self, aux) */ void load_seeprom(ahc) - struct ahc_data *ahc; + struct ahc_softc *ahc; { - struct seeprom_descriptor sd; - struct seeprom_config sc; - u_short *scarray = (u_short *)≻ - u_short checksum = 0; - u_char scsi_conf; - u_char host_id; - int have_seeprom; + struct seeprom_descriptor sd; + struct seeprom_config sc; + u_int16_t *scarray = (u_int16_t *)≻ + u_int16_t checksum = 0; + u_int8_t scsi_conf; + u_int8_t host_id; + int have_seeprom; #if defined(__FreeBSD__) +#ifdef AHC_FORCE_PIO + sd.sd_maddr = NULL; +#else sd.sd_maddr = ahc->maddr + SEECTL; +#endif + sd.sd_iobase = ahc->baseport + SEECTL; #elif defined(__NetBSD__) sd.sd_bc = ahc->sc_bc; sd.sd_ioh = ahc->sc_ioh; sd.sd_offset = SEECTL; #endif + if ((ahc->type & AHC_398) == AHC_398) + sd.sd_chip = C56_66; + else + sd.sd_chip = C46; sd.sd_MS = SEEMS; sd.sd_RDY = SEERDY; sd.sd_CS = SEECS; @@ -600,7 +683,7 @@ load_seeprom(ahc) if (have_seeprom) { have_seeprom = read_seeprom(&sd, (u_int16_t *)&sc, - ahc->flags & AHC_CHNLB, + ahc->flags & (AHC_CHNLB|AHC_CHNLC), sizeof(sc)/2); release_seeprom(&sd); if (have_seeprom) {