⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aic7xxx_pci.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* Now see if we can do parity */	ahc_scbram_config(ahc, enable, /*pcheck*/TRUE, fast, large);	num_scbs = ahc_probe_scbs(ahc);	if ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0	 || (ahc_inb(ahc, ERROR) & MPARERR) == 0)		pcheck = TRUE;	/* Clear any resulting parity error */	ahc_outb(ahc, CLRINT, CLRPARERR);	ahc_outb(ahc, CLRINT, CLRBRKADRINT);	/* Now see if we can do fast timing */	ahc_scbram_config(ahc, enable, pcheck, /*fast*/TRUE, large);	test_num_scbs = ahc_probe_scbs(ahc);	if (test_num_scbs == num_scbs	 && ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0	  || (ahc_inb(ahc, ERROR) & MPARERR) == 0))		fast = TRUE;	/*	 * See if we can use large SCBs and still maintain	 * the same overall count of SCBs.	 */	if ((ahc->features & AHC_LARGE_SCBS) != 0) {		ahc_scbram_config(ahc, enable, pcheck, fast, /*large*/TRUE);		test_num_scbs = ahc_probe_scbs(ahc);		if (test_num_scbs >= num_scbs) {			large = TRUE;			num_scbs = test_num_scbs;	 		if (num_scbs >= 64) {				/*				 * We have enough space to move the				 * "busy targets table" into SCB space				 * and make it qualify all the way to the				 * lun level.				 */				ahc->flags |= AHC_SCB_BTT;			}		}	}done:	/*	 * Disable parity error reporting until we	 * can load instruction ram.	 */	ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS);	/* Clear any latched parity error */	ahc_outb(ahc, CLRINT, CLRPARERR);	ahc_outb(ahc, CLRINT, CLRBRKADRINT);	if (bootverbose && enable) {		printf("%s: External SRAM, %s access%s, %dbytes/SCB\n",		       ahc_name(ahc), fast ? "fast" : "slow", 		       pcheck ? ", parity checking enabled" : "",		       large ? 64 : 32);	}	ahc_scbram_config(ahc, enable, pcheck, fast, large);}/* * Check the external port logic for a serial eeprom * and termination/cable detection contrls. */static voidcheck_extport(struct ahc_softc *ahc, u_int *sxfrctl1){	struct	seeprom_descriptor sd;	struct	seeprom_config sc;	u_int	scsi_conf;	u_int	adapter_control;	int	have_seeprom;	int	have_autoterm;	sd.sd_ahc = ahc;	sd.sd_control_offset = SEECTL;			sd.sd_status_offset = SEECTL;			sd.sd_dataout_offset = SEECTL;			/*	 * For some multi-channel devices, the c46 is simply too	 * small to work.  For the other controller types, we can	 * get our information from either SEEPROM type.  Set the	 * type to start our probe with accordingly.	 */	if (ahc->flags & AHC_LARGE_SEEPROM)		sd.sd_chip = C56_66;	else		sd.sd_chip = C46;	sd.sd_MS = SEEMS;	sd.sd_RDY = SEERDY;	sd.sd_CS = SEECS;	sd.sd_CK = SEECK;	sd.sd_DO = SEEDO;	sd.sd_DI = SEEDI;	have_seeprom = acquire_seeprom(ahc, &sd);	if (have_seeprom) {		if (bootverbose) 			printf("%s: Reading SEEPROM...", ahc_name(ahc));		for (;;) {			u_int start_addr;			start_addr = 32 * (ahc->channel - 'A');			have_seeprom = read_seeprom(&sd, (uint16_t *)&sc,						    start_addr, sizeof(sc)/2);			if (have_seeprom)				have_seeprom = verify_cksum(&sc);			if (have_seeprom != 0 || sd.sd_chip == C56_66) {				if (bootverbose) {					if (have_seeprom == 0)						printf ("checksum error\n");					else						printf ("done.\n");				}				break;			}			sd.sd_chip = C56_66;		}		release_seeprom(&sd);	}	if (!have_seeprom) {		/*		 * Pull scratch ram settings and treat them as		 * if they are the contents of an seeprom if		 * the 'ADPT' signature is found in SCB2.		 * We manually compose the data as 16bit values		 * to avoid endian issues.		 */		ahc_outb(ahc, SCBPTR, 2);		if (ahc_inb(ahc, SCB_BASE) == 'A'		 && ahc_inb(ahc, SCB_BASE + 1) == 'D'		 && ahc_inb(ahc, SCB_BASE + 2) == 'P'		 && ahc_inb(ahc, SCB_BASE + 3) == 'T') {			uint16_t *sc_data;			int	  i;			sc_data = (uint16_t *)&sc;			for (i = 0; i < 32; i++) {				uint16_t val;				int	 j;				j = i * 2;				val = ahc_inb(ahc, SRAM_BASE + j)				    | ahc_inb(ahc, SRAM_BASE + j + 1) << 8;			}			have_seeprom = verify_cksum(&sc);		}	}	if (!have_seeprom) {		if (bootverbose)			printf("%s: No SEEPROM available.\n", ahc_name(ahc));		ahc->flags |= AHC_USEDEFAULTS;	} else {		/*		 * Put the data we've collected down into SRAM		 * where ahc_init will find it.		 */		int i;		int max_targ = sc.max_targets & CFMAXTARG;		uint16_t discenable;		uint16_t ultraenb;		discenable = 0;		ultraenb = 0;		if ((sc.adapter_control & CFULTRAEN) != 0) {			/*			 * Determine if this adapter has a "newstyle"			 * SEEPROM format.			 */			for (i = 0; i < max_targ; i++) {				if ((sc.device_flags[i] & CFSYNCHISULTRA) != 0){					ahc->flags |= AHC_NEWEEPROM_FMT;					break;				}			}		}		for (i = 0; i < max_targ; i++) {			u_int     scsirate;			uint16_t target_mask;			target_mask = 0x01 << i;			if (sc.device_flags[i] & CFDISC)				discenable |= target_mask;			if ((ahc->flags & AHC_NEWEEPROM_FMT) != 0) {				if ((sc.device_flags[i] & CFSYNCHISULTRA) != 0)					ultraenb |= target_mask;			} else if ((sc.adapter_control & CFULTRAEN) != 0) {				ultraenb |= target_mask;			}			if ((sc.device_flags[i] & CFXFER) == 0x04			 && (ultraenb & target_mask) != 0) {				/* Treat 10MHz as a non-ultra speed */				sc.device_flags[i] &= ~CFXFER;			 	ultraenb &= ~target_mask;			}			if ((ahc->features & AHC_ULTRA2) != 0) {				u_int offset;				if (sc.device_flags[i] & CFSYNCH)					offset = MAX_OFFSET_ULTRA2;				else 					offset = 0;				ahc_outb(ahc, TARG_OFFSET + i, offset);				/*				 * The ultra enable bits contain the				 * high bit of the ultra2 sync rate				 * field.				 */				scsirate = (sc.device_flags[i] & CFXFER)					 | ((ultraenb & target_mask)					    ? 0x8 : 0x0);				if (sc.device_flags[i] & CFWIDEB)					scsirate |= WIDEXFER;			} else {				scsirate = (sc.device_flags[i] & CFXFER) << 4;				if (sc.device_flags[i] & CFSYNCH)					scsirate |= SOFS;				if (sc.device_flags[i] & CFWIDEB)					scsirate |= WIDEXFER;			}			ahc_outb(ahc, TARG_SCSIRATE + i, scsirate);		}		ahc->our_id = sc.brtime_id & CFSCSIID;		scsi_conf = (ahc->our_id & 0x7);		if (sc.adapter_control & CFSPARITY)			scsi_conf |= ENSPCHK;		if (sc.adapter_control & CFRESETB)			scsi_conf |= RESET_SCSI;		ahc->flags |=		    (sc.adapter_control & CFBOOTCHAN) >> CFBOOTCHANSHIFT;		if (sc.bios_control & CFEXTEND)			ahc->flags |= AHC_EXTENDED_TRANS_A;		if (sc.bios_control & CFBIOSEN)			ahc->flags |= AHC_BIOS_ENABLED;		if (ahc->features & AHC_ULTRA		 && (ahc->flags & AHC_NEWEEPROM_FMT) == 0) {			/* Should we enable Ultra mode? */			if (!(sc.adapter_control & CFULTRAEN))				/* Treat us as a non-ultra card */				ultraenb = 0;		}		if (sc.signature == CFSIGNATURE		 || sc.signature == CFSIGNATURE2) {			uint32_t devconfig;			/* Honor the STPWLEVEL settings */			devconfig = ahc_pci_read_config(ahc->dev_softc,							DEVCONFIG, /*bytes*/4);			devconfig &= ~STPWLEVEL;			if ((sc.bios_control & CFSTPWLEVEL) != 0)				devconfig |= STPWLEVEL;			ahc_pci_write_config(ahc->dev_softc, DEVCONFIG,					     devconfig, /*bytes*/4);		}		/* Set SCSICONF info */		ahc_outb(ahc, SCSICONF, scsi_conf);		ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));		ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));		ahc_outb(ahc, ULTRA_ENB, ultraenb & 0xff);		ahc_outb(ahc, ULTRA_ENB + 1, (ultraenb >> 8) & 0xff);	}	/*	 * Cards that have the external logic necessary to talk to	 * a SEEPROM, are almost certain to have the remaining logic	 * necessary for auto-termination control.  This assumption	 * hasn't failed yet...	 */	have_autoterm = have_seeprom;	if (have_seeprom)		adapter_control = sc.adapter_control;	else		adapter_control = CFAUTOTERM;	/*	 * Some low-cost chips have SEEPROM and auto-term control built	 * in, instead of using a GAL.  They can tell us directly	 * if the termination logic is enabled.	 */	if ((ahc->features & AHC_SPIOCAP) != 0) {		if ((ahc_inb(ahc, SPIOCAP) & SSPIOCPS) != 0)			have_autoterm = TRUE;		else			have_autoterm = FALSE;	}	if (have_autoterm) {		acquire_seeprom(ahc, &sd);		configure_termination(ahc, &sd, adapter_control, sxfrctl1);		release_seeprom(&sd);	}}static voidconfigure_termination(struct ahc_softc *ahc,		      struct seeprom_descriptor *sd,		      u_int adapter_control,		      u_int *sxfrctl1){	uint8_t brddat;		brddat = 0;	/*	 * Update the settings in sxfrctl1 to match the	 * termination settings 	 */	*sxfrctl1 = 0;		/*	 * SEECS must be on for the GALS to latch	 * the data properly.  Be sure to leave MS	 * on or we will release the seeprom.	 */	SEEPROM_OUTB(sd, sd->sd_MS | sd->sd_CS);	if ((adapter_control & CFAUTOTERM) != 0	 || (ahc->features & AHC_NEW_TERMCTL) != 0) {		int internal50_present;		int internal68_present;		int externalcable_present;		int eeprom_present;		int enableSEC_low;		int enableSEC_high;		int enablePRI_low;		int enablePRI_high;		int sum;		enableSEC_low = 0;		enableSEC_high = 0;		enablePRI_low = 0;		enablePRI_high = 0;		if ((ahc->features & AHC_NEW_TERMCTL) != 0) {			ahc_new_term_detect(ahc, &enableSEC_low,					       &enableSEC_high,					       &enablePRI_low,					       &enablePRI_high,					       &eeprom_present);			if ((adapter_control & CFSEAUTOTERM) == 0) {				if (bootverbose)					printf("%s: Manual SE Termination\n",					       ahc_name(ahc));				enableSEC_low = (adapter_control & CFSELOWTERM);				enableSEC_high =				    (adapter_control & CFSEHIGHTERM);			}			if ((adapter_control & CFAUTOTERM) == 0) {				if (bootverbose)					printf("%s: Manual LVD Termination\n",					       ahc_name(ahc));				enablePRI_low = (adapter_control & CFSTERM);				enablePRI_high = (adapter_control & CFWSTERM);			}			/* Make the table calculations below happy */			internal50_present = 0;			internal68_present = 1;			externalcable_present = 1;		} else if ((ahc->features & AHC_SPIOCAP) != 0) {			aic785X_cable_detect(ahc, &internal50_present,					     &externalcable_present,					     &eeprom_present);		} else {			aic787X_cable_detect(ahc, &internal50_present,					     &internal68_present,					     &externalcable_present,					     &eeprom_present);		}		if ((ahc->features & AHC_WIDE) == 0)			internal68_present = 0;		if (bootverbose		 && (ahc->features & AHC_ULTRA2) == 0) {			printf("%s: internal 50 cable %s present",			       ahc_name(ahc),			       internal50_present ? "is":"not");			if ((ahc->features & AHC_WIDE) != 0)				printf(", internal 68 cable %s present",				       internal68_present ? "is":"not");			printf("\n%s: external cable %s present\n",			       ahc_name(ahc),			       externalcable_present ? "is":"not");		}		if (bootverbose)			printf("%s: BIOS eeprom %s present\n",			       ahc_name(ahc), eeprom_present ? "is" : "not");		if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) {			/*			 * The 50 pin connector is a separate bus,			 * so force it to always be terminated.			 * In the future, perform current sensing			 * to determine if we are in the middle of			 * a properly terminated bus.			 */			internal50_present = 0;		}		/*		 * Now set the termination based on what		 * we found.		 * Flash Enable = BRDDAT7		 * Secondary High Term Enable = BRDDAT6		 * Secondary Low Term Enable = BRDDAT5 (7890)		 * Primary High Term Enable = BRDDAT4 (7890)		 */		if ((ahc->features & AHC_ULTRA2) == 0		 && (internal50_present != 0)		 && (internal68_present != 0)		 && (externalcable_present != 0)) {			printf("%s: Illegal cable configuration!!. "			       "Only two connectors on the "			       "adapter may be used at a "			       "time!\n", ahc_name(ahc));		}		if ((ahc->features & AHC_WIDE) != 0		 && ((externalcable_present == 0)		  || (internal68_present == 0)		  || (enableSEC_high != 0))) {			brddat |= BRDDAT6;			if (bootverbose) {				if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0)					printf("%s: 68 pin termination "					       "Enabled\n", ahc_name(ahc));				else					printf("%s: %sHigh byte termination "					       "Enabled\n", ahc_name(ahc),					       enableSEC_high ? "Secondary "							      : "");			}		}		sum = internal50_present + internal68_present		    + externalcable_present;		if (sum < 2 || (enableSEC_low != 0)) {			if ((ahc->features & AHC_ULTRA2) != 0)				brddat |= BRDDAT5;			else				*sxfrctl1 |= STPWEN;			if (bootverbose) {				if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0)					printf("%s: 50 pin termination "					       "Enabled\n", ahc_name(ahc));				else					printf("%s: %sLow byte termination "					       "Enabled\n", ahc_name(ahc),					       enableSEC_low ? "Secondary "							     : "");			}		}		if (enablePRI_low != 0) {			*sxfrctl1 |= STPWEN;			if (bootverbose)				printf("%s: Primary Low Byte termination "				       "Enabled\n", ahc_name(ahc));		}		/*		 * Setup STPWEN before setting up the rest of		 * the termination per the tech note on the U160 cards.		 */		ahc_outb(ahc, SXFRCTL1, *sxfrctl1);		if (enablePRI_high != 0) {			brddat |= BRDDAT4;			if (bootverbose)				printf("%s: Primary High Byte "				       "termination Enabled\n",				       ahc_name(ahc));		}				write_brdctl(ahc, brddat);	} else {		if ((adapter_control & CFSTERM) != 0) {			*sxfrctl1 |= STPWEN;			if (bootverbose)				printf("%s: %sLow byte termination Enabled\n",				       ahc_name(ahc),				       (ahc->features & AHC_ULTRA2) ? "Primary "								    : "");		}		if ((adapter_control & CFWSTERM) != 0		 && (ahc->features & AHC_WIDE) != 0) {			brddat |= BRDDAT6;			if (bootverbose)				printf("%s: %sHigh byte termination Enabled\n",				       ahc_name(ahc),				       (ahc->features & AHC_ULTRA2)				     ? "Secondary " : "");		}		/*		 * Setup STPWEN before setting up the rest of		 * the termination per the tech note on the U160 cards.		 */		ahc_outb(ahc, SXFRCTL1, *sxfrctl1);		if ((ahc->features & AHC_WIDE) != 0)			write_brdctl(ahc, brddat);	}	SEEPROM_OUTB(sd, sd->sd_MS); /* Clear CS */}static voidahc_new_term_detect(struct ahc_softc *ahc, int *enableSEC_low,		    int *enableSEC_high, int *enablePRI_low,		    int *enablePRI_high, int *eeprom_present){	uint8_t brdctl;	/*	 * BRDDAT7 = Eeprom	 * BRDDAT6 = Enable Secondary High Byte termination	 * BRDDAT5 = Enable Secondary Low Byte termination	 * BRDDAT4 = Enable Primary high byte termination	 * BRDDAT3 = Enable Primary low byte termination	 */	brdctl = read_brdctl(ahc);	*eeprom_present = brdctl & BRDDAT7;	*enableSEC_high = (brdctl & BRDDAT6);	*enableSEC_low = (brdctl & BRDDAT5);	*enablePRI_high = (brdctl & BRDDAT4);	*enablePRI_low = (brdctl & BRDDAT3);}static voidaic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present,		     int *internal68_present, int *externalcable_present,		     int *eeprom_present){	uint8_t brdctl;	/*	 * First read the status of our cables.	 * Set the rom bank to 0 since the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -