patch-2.4.19 linux-2.4.19/drivers/scsi/aic7xxx/aic7770.c

Next file: linux-2.4.19/drivers/scsi/aic7xxx/aic7770_linux.c
Previous file: linux-2.4.19/drivers/scsi/aic7xxx/Makefile
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/drivers/scsi/aic7xxx/aic7770.c linux-2.4.19/drivers/scsi/aic7xxx/aic7770.c
@@ -37,21 +37,27 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#14 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#21 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7770.c,v 1.1 2000/09/16 20:02:27 gibbs Exp $
  */
 
+#ifdef __linux__
 #include "aic7xxx_osm.h"
 #include "aic7xxx_inline.h"
 #include "aic7xxx_93cx6.h"
+#else
+#include <dev/aic7xxx/aic7xxx_osm.h>
+#include <dev/aic7xxx/aic7xxx_inline.h>
+#include <dev/aic7xxx/aic7xxx_93cx6.h>
+#endif
 
 #define ID_AIC7770	0x04907770
 #define ID_AHA_274x	0x04907771
 #define ID_AHA_284xB	0x04907756 /* BIOS enabled */
 #define ID_AHA_284x	0x04907757 /* BIOS disabled*/
 
-static void aha2840_load_seeprom(struct ahc_softc *ahc);
+static int aha2840_load_seeprom(struct ahc_softc *ahc);
 static ahc_device_setup_t ahc_aic7770_VL_setup;
 static ahc_device_setup_t ahc_aic7770_EISA_setup;;
 static ahc_device_setup_t ahc_aic7770_setup;
@@ -96,21 +102,33 @@
 }
 
 int
-aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry)
+aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
 {
+	u_long	l;
+	u_long	s;
 	int	error;
+	int	have_seeprom;
 	u_int	hostconf;
 	u_int   irq;
 	u_int	intdef;
 
 	error = entry->setup(ahc);
+	have_seeprom = 0;
 	if (error != 0)
 		return (error);
 
-	error = aic7770_map_registers(ahc);
+	error = aic7770_map_registers(ahc, io);
 	if (error != 0)
 		return (error);
 
+	/*
+	 * Before we continue probing the card, ensure that
+	 * its interrupts are *disabled*.  We don't want
+	 * a misstep to hang the machine in an interrupt
+	 * storm.
+	 */
+	ahc_intr_enable(ahc, FALSE);
+
 	ahc->description = entry->name;
 	error = ahc_softc_init(ahc);
 
@@ -168,21 +186,22 @@
 					ahc->flags |= AHC_TERM_ENB_B;
 			}
 		}
-		/*
-		 * We have no way to tell, so assume extended
-		 * translation is enabled.
-		 */
-		ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B;
+		if ((ahc_inb(ahc, HA_274_BIOSGLOBAL) & HA_274_EXTENDED_TRANS))
+			ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B;
 		break;
 	}
 	case AHC_VL:
 	{
-		aha2840_load_seeprom(ahc);
+		have_seeprom = aha2840_load_seeprom(ahc);
 		break;
 	}
 	default:
 		break;
 	}
+	if (have_seeprom == 0) {
+		free(ahc->seep_config, M_DEVBUF);
+		ahc->seep_config = NULL;
+	}
 
 	/*
 	 * Ensure autoflush is enabled
@@ -201,15 +220,16 @@
 	if (error != 0)
 		return (error);
 
+	error = aic7770_map_int(ahc, irq);
+	if (error != 0)
+		return (error);
+
+	ahc_list_lock(&l);
 	/*
 	 * Link this softc in with all other ahc instances.
 	 */
 	ahc_softc_insert(ahc);
 
-	error = aic7770_map_int(ahc, irq);
-	if (error != 0)
-		return (error);
-
 	/*
 	 * Enable the board's BUS drivers
 	 */
@@ -218,7 +238,11 @@
 	/*
 	 * Allow interrupts.
 	 */
+	ahc_lock(ahc, &s);
 	ahc_intr_enable(ahc, TRUE);
+	ahc_unlock(ahc, &s);
+
+	ahc_list_unlock(&l);
 
 	return (0);
 }
@@ -226,14 +250,13 @@
 /*
  * Read the 284x SEEPROM.
  */
-static void
+static int
 aha2840_load_seeprom(struct ahc_softc *ahc)
 {
-	struct	  seeprom_descriptor sd;
-	struct	  seeprom_config sc;
-	uint16_t  checksum = 0;
-	uint8_t   scsi_conf;
-	int	  have_seeprom;
+	struct	seeprom_descriptor sd;
+	struct	seeprom_config *sc;
+	int	have_seeprom;
+	uint8_t scsi_conf;
 
 	sd.sd_ahc = ahc;
 	sd.sd_control_offset = SEECTL_2840;
@@ -246,23 +269,16 @@
 	sd.sd_CK = CK_2840;
 	sd.sd_DO = DO_2840;
 	sd.sd_DI = DI_2840;
+	sc = ahc->seep_config;
 
 	if (bootverbose)
 		printf("%s: Reading SEEPROM...", ahc_name(ahc));
-	have_seeprom = read_seeprom(&sd,
-				    (uint16_t *)&sc,
-				    /*start_addr*/0,
-				    sizeof(sc)/2);
+	have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)&sc,
+					/*start_addr*/0, sizeof(sc)/2);
 
 	if (have_seeprom) {
-		/* Check checksum */
-		int i;
-		int maxaddr = (sizeof(sc)/2) - 1;
-		uint16_t *scarray = (uint16_t *)&sc;
-
-		for (i = 0; i < maxaddr; i++)
-			checksum = checksum + scarray[i];
-		if (checksum != sc.checksum) {
+
+		if (ahc_verify_cksum(sc) == 0) {
 			if(bootverbose)
 				printf ("checksum error\n");
 			have_seeprom = 0;
@@ -280,41 +296,44 @@
 		 * Put the data we've collected down into SRAM
 		 * where ahc_init will find it.
 		 */
-		int i;
-		int max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8;
+		int	 i;
+		int	 max_targ;
 		uint16_t discenable;
 
+		max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8;
 		discenable = 0;
 		for (i = 0; i < max_targ; i++){
-	                uint8_t target_settings;
-			target_settings = (sc.device_flags[i] & CFXFER) << 4;
-			if (sc.device_flags[i] & CFSYNCH)
+			uint8_t target_settings;
+
+			target_settings = (sc->device_flags[i] & CFXFER) << 4;
+			if (sc->device_flags[i] & CFSYNCH)
 				target_settings |= SOFS;
-			if (sc.device_flags[i] & CFWIDEB)
+			if (sc->device_flags[i] & CFWIDEB)
 				target_settings |= WIDEXFER;
-			if (sc.device_flags[i] & CFDISC)
+			if (sc->device_flags[i] & CFDISC)
 				discenable |= (0x01 << i);
 			ahc_outb(ahc, TARG_SCSIRATE + i, target_settings);
 		}
 		ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));
 		ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));
 
-		ahc->our_id = sc.brtime_id & CFSCSIID;
+		ahc->our_id = sc->brtime_id & CFSCSIID;
 
 		scsi_conf = (ahc->our_id & 0x7);
-		if (sc.adapter_control & CFSPARITY)
+		if (sc->adapter_control & CFSPARITY)
 			scsi_conf |= ENSPCHK;
-		if (sc.adapter_control & CFRESETB)
+		if (sc->adapter_control & CFRESETB)
 			scsi_conf |= RESET_SCSI;
 
-		if (sc.bios_control & CF284XEXTEND)		
+		if (sc->bios_control & CF284XEXTEND)		
 			ahc->flags |= AHC_EXTENDED_TRANS_A;
 		/* Set SCSICONF info */
 		ahc_outb(ahc, SCSICONF, scsi_conf);
 
-		if (sc.adapter_control & CF284XSTERM)
+		if (sc->adapter_control & CF284XSTERM)
 			ahc->flags |= AHC_TERM_ENB_A;
 	}
+	return (have_seeprom);
 }
 
 static int

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)