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

📄 aic7xxx_pci.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	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);	ahc_outb(ahc, BRDCTL, 0);	return (value);}static voidahc_pci_intr(struct ahc_softc *ahc){	u_int error;	u_int status1;	error = ahc_inb(ahc, ERROR);	if ((error & PCIERRSTAT) == 0)		return;	status1 = ahc_pci_read_config(ahc->dev_softc,				      PCIR_STATUS + 1, /*bytes*/1);	printf("%s: PCI error Interrupt at seqaddr = 0x%x\n",	      ahc_name(ahc),	      ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));	if (status1 & DPE) {		ahc->pci_target_perr_count++;		printf("%s: Data Parity Error Detected during address "		       "or write data phase\n", ahc_name(ahc));	}	if (status1 & SSE) {		printf("%s: Signal System Error Detected\n", ahc_name(ahc));	}	if (status1 & RMA) {		printf("%s: Received a Master Abort\n", ahc_name(ahc));	}	if (status1 & RTA) {		printf("%s: Received a Target Abort\n", ahc_name(ahc));	}	if (status1 & STA) {		printf("%s: Signaled a Target Abort\n", ahc_name(ahc));	}	if (status1 & DPR) {		printf("%s: Data Parity Error has been reported via PERR#\n",		       ahc_name(ahc));	}	/* Clear latched errors. */	ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,			     status1, /*bytes*/1);	if ((status1 & (DPE|SSE|RMA|RTA|STA|DPR)) == 0) {		printf("%s: Latched PCIERR interrupt with "		       "no status bits set\n", ahc_name(ahc)); 	} else {		ahc_outb(ahc, CLRINT, CLRPARERR);	}	if (ahc->pci_target_perr_count > AHC_PCI_TARGET_PERR_THRESH) {		printf("%s: WARNING WARNING WARNING WARNING\n""%s: Too many PCI parity errors observed as a target.\n""%s: Some device on this bus is generating bad parity.\n""%s: This is an error *observed by*, not *generated by*, this controller.\n""%s: PCI parity error checking has been disabled.\n""%s: WARNING WARNING WARNING WARNING\n",		       ahc_name(ahc), ahc_name(ahc), ahc_name(ahc),		       ahc_name(ahc), ahc_name(ahc), ahc_name(ahc));		ahc->seqctl |= FAILDIS;		ahc_outb(ahc, SEQCTL, ahc->seqctl);	}	ahc_unpause(ahc);}static intahc_pci_chip_init(struct ahc_softc *ahc){	ahc_outb(ahc, DSCOMMAND0, ahc->bus_softc.pci_softc.dscommand0);	ahc_outb(ahc, DSPCISTATUS, ahc->bus_softc.pci_softc.dspcistatus);	if ((ahc->features & AHC_DT) != 0) {		u_int sfunct;		sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;		ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);		ahc_outb(ahc, OPTIONMODE, ahc->bus_softc.pci_softc.optionmode);		ahc_outw(ahc, TARGCRCCNT, ahc->bus_softc.pci_softc.targcrccnt);		ahc_outb(ahc, SFUNCT, sfunct);		ahc_outb(ahc, CRCCONTROL1,			 ahc->bus_softc.pci_softc.crccontrol1);	}	if ((ahc->features & AHC_MULTI_FUNC) != 0)		ahc_outb(ahc, SCBBADDR, ahc->bus_softc.pci_softc.scbbaddr);	if ((ahc->features & AHC_ULTRA2) != 0)		ahc_outb(ahc, DFF_THRSH, ahc->bus_softc.pci_softc.dff_thrsh);	return (ahc_chip_init(ahc));}static intahc_pci_suspend(struct ahc_softc *ahc){	return (ahc_suspend(ahc));}static intahc_pci_resume(struct ahc_softc *ahc){	pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0);	/*	 * We assume that the OS has restored our register	 * mappings, etc.  Just update the config space registers	 * that the OS doesn't know about and rely on our chip	 * reset handler to handle the rest.	 */	ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4,			     ahc->bus_softc.pci_softc.devconfig);	ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1,			     ahc->bus_softc.pci_softc.command);	ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1,			     ahc->bus_softc.pci_softc.csize_lattime);	if ((ahc->flags & AHC_HAS_TERM_LOGIC) != 0) {		struct	seeprom_descriptor sd;		u_int	sxfrctl1;		sd.sd_ahc = ahc;		sd.sd_control_offset = SEECTL;				sd.sd_status_offset = SEECTL;				sd.sd_dataout_offset = SEECTL;				ahc_acquire_seeprom(ahc, &sd);		configure_termination(ahc, &sd,				      ahc->seep_config->adapter_control,				      &sxfrctl1);		ahc_release_seeprom(&sd);	}	return (ahc_resume(ahc));}static intahc_aic785X_setup(struct ahc_softc *ahc){	ahc_dev_softc_t pci;	uint8_t rev;	pci = ahc->dev_softc;	ahc->channel = 'A';	ahc->chip = AHC_AIC7850;	ahc->features = AHC_AIC7850_FE;	ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;	rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);	if (rev >= 1)		ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;	ahc->instruction_ram_size = 512;	return (0);}static intahc_aic7860_setup(struct ahc_softc *ahc){	ahc_dev_softc_t pci;	uint8_t rev;	pci = ahc->dev_softc;	ahc->channel = 'A';	ahc->chip = AHC_AIC7860;	ahc->features = AHC_AIC7860_FE;	ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;	rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);	if (rev >= 1)		ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;	ahc->instruction_ram_size = 512;	return (0);}static intahc_apa1480_setup(struct ahc_softc *ahc){	int error;	error = ahc_aic7860_setup(ahc);	if (error != 0)		return (error);	ahc->features |= AHC_REMOVABLE;	return (0);}static intahc_aic7870_setup(struct ahc_softc *ahc){	ahc->channel = 'A';	ahc->chip = AHC_AIC7870;	ahc->features = AHC_AIC7870_FE;	ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;	ahc->instruction_ram_size = 512;	return (0);}static intahc_aha394X_setup(struct ahc_softc *ahc){	int error;	error = ahc_aic7870_setup(ahc);	if (error == 0)		error = ahc_aha394XX_setup(ahc);	return (error);}static intahc_aha398X_setup(struct ahc_softc *ahc){	int error;	error = ahc_aic7870_setup(ahc);	if (error == 0)		error = ahc_aha398XX_setup(ahc);	return (error);}static intahc_aha494X_setup(struct ahc_softc *ahc){	int error;	error = ahc_aic7870_setup(ahc);	if (error == 0)		error = ahc_aha494XX_setup(ahc);	return (error);}static intahc_aic7880_setup(struct ahc_softc *ahc){	ahc_dev_softc_t pci;	uint8_t rev;	pci = ahc->dev_softc;	ahc->channel = 'A';	ahc->chip = AHC_AIC7880;	ahc->features = AHC_AIC7880_FE;	ahc->bugs |= AHC_TMODE_WIDEODD_BUG;	rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);	if (rev >= 1) {		ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;	} else {		ahc->bugs |= AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;	}	ahc->instruction_ram_size = 512;	return (0);}static intahc_aha2940Pro_setup(struct ahc_softc *ahc){	ahc->flags |= AHC_INT50_SPEEDFLEX;	return (ahc_aic7880_setup(ahc));}static intahc_aha394XU_setup(struct ahc_softc *ahc){	int error;	error = ahc_aic7880_setup(ahc);	if (error == 0)		error = ahc_aha394XX_setup(ahc);	return (error);}static intahc_aha398XU_setup(struct ahc_softc *ahc){	int error;	error = ahc_aic7880_setup(ahc);	if (error == 0)		error = ahc_aha398XX_setup(ahc);	return (error);}static intahc_aic7890_setup(struct ahc_softc *ahc){	ahc_dev_softc_t pci;	uint8_t rev;	pci = ahc->dev_softc;	ahc->channel = 'A';	ahc->chip = AHC_AIC7890;	ahc->features = AHC_AIC7890_FE;	ahc->flags |= AHC_NEWEEPROM_FMT;	rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);	if (rev == 0)		ahc->bugs |= AHC_AUTOFLUSH_BUG|AHC_CACHETHEN_BUG;	ahc->instruction_ram_size = 768;	return (0);}static intahc_aic7892_setup(struct ahc_softc *ahc){	ahc->channel = 'A';	ahc->chip = AHC_AIC7892;	ahc->features = AHC_AIC7892_FE;	ahc->flags |= AHC_NEWEEPROM_FMT;	ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;	ahc->instruction_ram_size = 1024;	return (0);}static intahc_aic7895_setup(struct ahc_softc *ahc){	ahc_dev_softc_t pci;	uint8_t rev;	pci = ahc->dev_softc;	ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';	/*	 * The 'C' revision of the aic7895 has a few additional features.	 */	rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);	if (rev >= 4) {		ahc->chip = AHC_AIC7895C;		ahc->features = AHC_AIC7895C_FE;	} else  {		u_int command;		ahc->chip = AHC_AIC7895;		ahc->features = AHC_AIC7895_FE;		/*		 * The BIOS disables the use of MWI transactions		 * since it does not have the MWI bug work around		 * we have.  Disabling MWI reduces performance, so		 * turn it on again.		 */		command = ahc_pci_read_config(pci, PCIR_COMMAND, /*bytes*/1);		command |= PCIM_CMD_MWRICEN;		ahc_pci_write_config(pci, PCIR_COMMAND, command, /*bytes*/1);		ahc->bugs |= AHC_PCI_MWI_BUG;	}	/*	 * XXX Does CACHETHEN really not work???  What about PCI retry?	 * on C level chips.  Need to test, but for now, play it safe.	 */	ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_PCI_2_1_RETRY_BUG		  |  AHC_CACHETHEN_BUG;#if 0	uint32_t devconfig;	/*	 * Cachesize must also be zero due to stray DAC	 * problem when sitting behind some bridges.	 */	ahc_pci_write_config(pci, CSIZE_LATTIME, 0, /*bytes*/1);	devconfig = ahc_pci_read_config(pci, DEVCONFIG, /*bytes*/1);	devconfig |= MRDCEN;	ahc_pci_write_config(pci, DEVCONFIG, devconfig, /*bytes*/1);#endif	ahc->flags |= AHC_NEWEEPROM_FMT;	ahc->instruction_ram_size = 512;	return (0);}static intahc_aic7896_setup(struct ahc_softc *ahc){	ahc_dev_softc_t pci;	pci = ahc->dev_softc;	ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';	ahc->chip = AHC_AIC7896;	ahc->features = AHC_AIC7896_FE;	ahc->flags |= AHC_NEWEEPROM_FMT;	ahc->bugs |= AHC_CACHETHEN_DIS_BUG;	ahc->instruction_ram_size = 768;	return (0);}static intahc_aic7899_setup(struct ahc_softc *ahc){	ahc_dev_softc_t pci;	pci = ahc->dev_softc;	ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';	ahc->chip = AHC_AIC7899;	ahc->features = AHC_AIC7899_FE;	ahc->flags |= AHC_NEWEEPROM_FMT;	ahc->bugs |= AHC_SCBCHAN_UPLOAD_BUG;	ahc->instruction_ram_size = 1024;	return (0);}static intahc_aha29160C_setup(struct ahc_softc *ahc){	int error;	error = ahc_aic7899_setup(ahc);	if (error != 0)		return (error);	ahc->features |= AHC_REMOVABLE;	return (0);}static intahc_raid_setup(struct ahc_softc *ahc){	printf("RAID functionality unsupported\n");	return (ENXIO);}static intahc_aha394XX_setup(struct ahc_softc *ahc){	ahc_dev_softc_t pci;	pci = ahc->dev_softc;	switch (ahc_get_pci_slot(pci)) {	case AHC_394X_SLOT_CHANNEL_A:		ahc->channel = 'A';		break;	case AHC_394X_SLOT_CHANNEL_B:		ahc->channel = 'B';		break;	default:		printf("adapter at unexpected slot %d\n"		       "unable to map to a channel\n",		       ahc_get_pci_slot(pci));		ahc->channel = 'A';	}	return (0);}static intahc_aha398XX_setup(struct ahc_softc *ahc){	ahc_dev_softc_t pci;	pci = ahc->dev_softc;	switch (ahc_get_pci_slot(pci)) {	case AHC_398X_SLOT_CHANNEL_A:		ahc->channel = 'A';		break;	case AHC_398X_SLOT_CHANNEL_B:		ahc->channel = 'B';		break;	case AHC_398X_SLOT_CHANNEL_C:		ahc->channel = 'C';		break;	default:		printf("adapter at unexpected slot %d\n"		       "unable to map to a channel\n",		       ahc_get_pci_slot(pci));		ahc->channel = 'A';		break;	}	ahc->flags |= AHC_LARGE_SEEPROM;	return (0);}static intahc_aha494XX_setup(struct ahc_softc *ahc){	ahc_dev_softc_t pci;	pci = ahc->dev_softc;	switch (ahc_get_pci_slot(pci)) {	case AHC_494X_SLOT_CHANNEL_A:		ahc->channel = 'A';		break;	case AHC_494X_SLOT_CHANNEL_B:		ahc->channel = 'B';		break;	case AHC_494X_SLOT_CHANNEL_C:		ahc->channel = 'C';		break;	case AHC_494X_SLOT_CHANNEL_D:		ahc->channel = 'D';		break;	default:		printf("adapter at unexpected slot %d\n"		       "unable to map to a channel\n",		       ahc_get_pci_slot(pci));		ahc->channel = 'A';	}	ahc->flags |= AHC_LARGE_SEEPROM;	return (0);}

⌨️ 快捷键说明

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