Index: head/sys/pci/aic7870.c =================================================================== --- head/sys/pci/aic7870.c (revision 10569) +++ head/sys/pci/aic7870.c (revision 10570) @@ -1,140 +1,171 @@ /* * Product specific probe and attach routines for: - * 2940, aic7870, and aic7850 motherboard SCSI controllers + * 3940, 2940, aic7870, and aic7850 SCSI controllers * * Copyright (c) 1995 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 immediately at the beginning of the file, without modification, * 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. Absolutely no warranty of function or purpose is made by the author * Justin T. Gibbs. * 4. Modifications may be freely made to this file if the above conditions * are met. * - * $Id: aic7870.c,v 1.12 1995/07/04 21:21:33 gibbs Exp $ + * $Id: aic7870.c,v 1.13 1995/08/20 03:18:09 gibbs Exp $ */ #include #if NPCI > 0 #include #include #include #include #include #include #include #include #include #define PCI_BASEADR0 PCI_MAP_REG_START #define PCI_DEVICE_ID_ADAPTEC_3940 0x72789004ul #define PCI_DEVICE_ID_ADAPTEC_2940 0x71789004ul #define PCI_DEVICE_ID_ADAPTEC_AIC7870 0x70789004ul #define PCI_DEVICE_ID_ADAPTEC_AIC7850 0x50789004ul +#define DEVCONFIG 0x40 +#define MPORTMODE 0x00000400ul /* aic7870 only */ +#define RAMPSM 0x00000200ul /* aic7870 only */ +#define VOLSENSE 0x00000100ul +#define DEVCONFIG7 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 */ + static char* aic7870_probe __P((pcici_t tag, pcidi_t type)); void aic7870_attach __P((pcici_t config_id, int unit)); static u_long aic7870_count; +static u_char aic3940_count; struct pci_device ahc_device = { "ahc", aic7870_probe, aic7870_attach, &aic7870_count, NULL }; DATA_SET (pcidevice_set, ahc_device); static char* aic7870_probe (pcici_t tag, pcidi_t type) { switch(type) { case PCI_DEVICE_ID_ADAPTEC_3940: return ("Adaptec 3940 SCSI host adapter"); break; case PCI_DEVICE_ID_ADAPTEC_2940: return ("Adaptec 2940 SCSI host adapter"); break; case PCI_DEVICE_ID_ADAPTEC_AIC7870: return ("Adaptec aic7870 SCSI host adapter"); break; case PCI_DEVICE_ID_ADAPTEC_AIC7850: return ("Adaptec aic7850 SCSI host adapter"); break; default: break; } return (0); } void aic7870_attach(config_id, unit) pcici_t config_id; int unit; { u_long io_port; unsigned opri = 0; ahc_type ahc_t = AHC_NONE; + ahc_flag ahc_f = AHC_FNONE; if(!(io_port = pci_conf_read(config_id, PCI_BASEADR0))) return; /* * Make the offsets the same as for EISA * The first bit of PCI_BASEADR0 is always * set hence we subtract 0xc01 instead of the * 0xc00 that you would expect. */ io_port -= 0xc01ul; - switch (pci_conf_read (config_id, PCI_ID_REG)) { + switch (pci_conf_read(config_id, PCI_ID_REG)) { case PCI_DEVICE_ID_ADAPTEC_3940: ahc_t = AHC_394; + aic3940_count++; + if(!(aic3940_count & 0x01)) + /* Even count implies second channel */ + ahc_f |= AHC_CHNLB; break; case PCI_DEVICE_ID_ADAPTEC_2940: ahc_t = AHC_294; break; case PCI_DEVICE_ID_ADAPTEC_AIC7870: ahc_t = AHC_AIC7870; break; case PCI_DEVICE_ID_ADAPTEC_AIC7850: ahc_t = AHC_AIC7850; break; default: break; } - if(ahcprobe(unit, io_port, ahc_t)){ + if(ahc_t & AHC_AIC7870){ + u_long devconfig = pci_conf_read(config_id, DEVCONFIG); + if(devconfig & RAMPSM) { + /* + * External SRAM present. Have the probe walk + * the SCBs to see how much SRAM we have and set + * the number of SCBs accordingly. + */ + ahc_f |= AHC_EXTSCB; + } + } + + if(ahcprobe(unit, io_port, ahc_t, ahc_f)){ ahc_unit++; /* * To be compatible with the isa style of * interrupt handler, we pass the unit number * not a pointer to our per device structure. */ if(!(pci_map_int(config_id, ahcintr, (void *)unit, &bio_imask))) { free(ahcdata[unit], M_TEMP); ahcdata[unit] = NULL; return; } /* * Since ahc_attach will poll, protect ourself * from the registered interrupt handler. */ opri = splbio(); ahc_attach(unit); splx(opri); } return; } #endif /* NPCI > 0 */