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

📄 aic7xxx_pci.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		 * 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);}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);			/* Can never support a wide connector. */			internal68_present = 0;		} 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));			/*			 * Pretend there are no cables in the hope			 * that having all of the termination on			 * gives us a more stable bus.			 */		 	internal50_present = 0;			internal68_present = 0;			externalcable_present = 0;		}		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	 * bank setting serves as a multiplexor	 * for the cable detection logic.	 * BRDDAT5 controls the bank switch.	 */	write_brdctl(ahc, 0);	/*	 * Now read the state of the internal	 * connectors.  BRDDAT6 is INT50 and	 * BRDDAT7 is INT68.	 */	brdctl = read_brdctl(ahc);	*internal50_present = (brdctl & BRDDAT6) ? 0 : 1;	*internal68_present = (brdctl & BRDDAT7) ? 0 : 1;	/*	 * Set the rom bank to 1 and determine	 * the other signals.	 */	write_brdctl(ahc, BRDDAT5);	/*	 * Now read the state of the external	 * connectors.  BRDDAT6 is EXT68 and	 * BRDDAT7 is EPROMPS.	 */	brdctl = read_brdctl(ahc);	*externalcable_present = (brdctl & BRDDAT6) ? 0 : 1;	*eeprom_present = (brdctl & BRDDAT7) ? 1 : 0;}static voidaic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present,		     int *externalcable_present, int *eeprom_present){	uint8_t brdctl;	uint8_t spiocap;	spiocap = ahc_inb(ahc, SPIOCAP);	spiocap &= ~SOFTCMDEN;	spiocap |= EXT_BRDCTL;	ahc_outb(ahc, SPIOCAP, spiocap);	ahc_outb(ahc, BRDCTL, BRDRW|BRDCS);	ahc_flush_device_writes(ahc);	ahc_delay(500);	ahc_outb(ahc, BRDCTL, 0);	ahc_flush_device_writes(ahc);	ahc_delay(500);	brdctl = ahc_inb(ahc, BRDCTL);	*internal50_present = (brdctl & BRDDAT5) ? 0 : 1;	*externalcable_present = (brdctl & BRDDAT6) ? 0 : 1;	*eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) ? 1 : 0;}	intahc_acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd){	int wait;	if ((ahc->features & AHC_SPIOCAP) != 0	 && (ahc_inb(ahc, SPIOCAP) & SEEPROM) == 0)		return (0);	/*	 * Request access of the memory port.  When access is	 * granted, SEERDY will go high.  We use a 1 second	 * timeout which should be near 1 second more than	 * is needed.  Reason: after the chip reset, there	 * should be no contention.	 */	SEEPROM_OUTB(sd, sd->sd_MS);	wait = 1000;  /* 1 second timeout in msec */	while (--wait && ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0)) {		ahc_delay(1000);  /* delay 1 msec */	}	if ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0) {		SEEPROM_OUTB(sd, 0); 		return (0);	}	return(1);}voidahc_release_seeprom(struct seeprom_descriptor *sd){	/* Release access to the memory port and the serial EEPROM. */	SEEPROM_OUTB(sd, 0);}static voidwrite_brdctl(struct ahc_softc *ahc, uint8_t value){	uint8_t brdctl;	if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {		brdctl = BRDSTB;	 	if (ahc->channel == 'B')			brdctl |= BRDCS;	} else if ((ahc->features & AHC_ULTRA2) != 0) {		brdctl = 0;	} else {		brdctl = BRDSTB|BRDCS;	}	ahc_outb(ahc, BRDCTL, brdctl);	ahc_flush_device_writes(ahc);	brdctl |= value;	ahc_outb(ahc, BRDCTL, brdctl);	ahc_flush_device_writes(ahc);	if ((ahc->features & AHC_ULTRA2) != 0)		brdctl |= BRDSTB_ULTRA2;	else		brdctl &= ~BRDSTB;	ahc_outb(ahc, BRDCTL, brdctl);	ahc_flush_device_writes(ahc);	if ((ahc->features & AHC_ULTRA2) != 0)		brdctl = 0;	else		brdctl &= ~BRDCS;	ahc_outb(ahc, BRDCTL, brdctl);}static uint8_tread_brdctl(struct ahc_softc *ahc){	uint8_t brdctl;	uint8_t value;	if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {		brdctl = BRDRW;	 	if (ahc->channel == 'B')			brdctl |= BRDCS;	} else if ((ahc->features & AHC_ULTRA2) != 0) {		brdctl = BRDRW_ULTRA2;	} else {		brdctl = BRDRW|BRDCS;	}	ahc_outb(ahc, BRDCTL, brdctl);	ahc_flush_device_writes(ahc);	value = ahc_inb(ahc, BRDCTL);

⌨️ 快捷键说明

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