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

📄 sym_hipd.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	u32	kpc;			/* (per * clk)			*/	int	ret;	/*	 *  Compute the synchronous period in tenths of nano-seconds	 */	if (dt && sfac <= 9)	per = 125;	else if	(sfac <= 10)	per = 250;	else if	(sfac == 11)	per = 303;	else if	(sfac == 12)	per = 500;	else			per = 40 * sfac;	ret = per;	kpc = per * clk;	if (dt)		kpc <<= 1;	/*	 *  For earliest C10 revision 0, we cannot use extra 	 *  clocks for the setting of the SCSI clocking.	 *  Note that this limits the lowest sync data transfer 	 *  to 5 Mega-transfers per second and may result in	 *  using higher clock divisors.	 */#if 1	if ((np->features & (FE_C10|FE_U3EN)) == FE_C10) {		/*		 *  Look for the lowest clock divisor that allows an 		 *  output speed not faster than the period.		 */		while (div > 0) {			--div;			if (kpc > (div_10M[div] << 2)) {				++div;				break;			}		}		fak = 0;			/* No extra clocks */		if (div == np->clock_divn) {	/* Are we too fast ? */			ret = -1;		}		*divp = div;		*fakp = fak;		return ret;	}#endif	/*	 *  Look for the greatest clock divisor that allows an 	 *  input speed faster than the period.	 */	while (div-- > 0)		if (kpc >= (div_10M[div] << 2)) break;	/*	 *  Calculate the lowest clock factor that allows an output 	 *  speed not faster than the period, and the max output speed.	 *  If fak >= 1 we will set both XCLKH_ST and XCLKH_DT.	 *  If fak >= 2 we will also set XCLKS_ST and XCLKS_DT.	 */	if (dt) {		fak = (kpc - 1) / (div_10M[div] << 1) + 1 - 2;		/* ret = ((2+fak)*div_10M[div])/np->clock_khz; */	} else {		fak = (kpc - 1) / div_10M[div] + 1 - 4;		/* ret = ((4+fak)*div_10M[div])/np->clock_khz; */	}	/*	 *  Check against our hardware limits, or bugs :).	 */	if (fak > 2) {		fak = 2;		ret = -1;	}	/*	 *  Compute and return sync parameters.	 */	*divp = div;	*fakp = fak;	return ret;}/* *  SYMBIOS chips allow burst lengths of 2, 4, 8, 16, 32, 64, *  128 transfers. All chips support at least 16 transfers  *  bursts. The 825A, 875 and 895 chips support bursts of up  *  to 128 transfers and the 895A and 896 support bursts of up *  to 64 transfers. All other chips support up to 16  *  transfers bursts. * *  For PCI 32 bit data transfers each transfer is a DWORD. *  It is a QUADWORD (8 bytes) for PCI 64 bit data transfers. * *  We use log base 2 (burst length) as internal code, with  *  value 0 meaning "burst disabled". *//* *  Burst length from burst code. */#define burst_length(bc) (!(bc))? 0 : 1 << (bc)/* *  Burst code from io register bits. */#define burst_code(dmode, ctest4, ctest5) \	(ctest4) & 0x80? 0 : (((dmode) & 0xc0) >> 6) + ((ctest5) & 0x04) + 1/* *  Set initial io register bits from burst code. */static __inline void sym_init_burst(struct sym_hcb *np, u_char bc){	np->rv_ctest4	&= ~0x80;	np->rv_dmode	&= ~(0x3 << 6);	np->rv_ctest5	&= ~0x4;	if (!bc) {		np->rv_ctest4	|= 0x80;	}	else {		--bc;		np->rv_dmode	|= ((bc & 0x3) << 6);		np->rv_ctest5	|= (bc & 0x4);	}}/* * Print out the list of targets that have some flag disabled by user. */static void sym_print_targets_flag(struct sym_hcb *np, int mask, char *msg){	int cnt;	int i;	for (cnt = 0, i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) {		if (i == np->myaddr)			continue;		if (np->target[i].usrflags & mask) {			if (!cnt++)				printf("%s: %s disabled for targets",					sym_name(np), msg);			printf(" %d", i);		}	}	if (cnt)		printf(".\n");}/* *  Save initial settings of some IO registers. *  Assumed to have been set by BIOS. *  We cannot reset the chip prior to reading the  *  IO registers, since informations will be lost. *  Since the SCRIPTS processor may be running, this  *  is not safe on paper, but it seems to work quite  *  well. :) */static void sym_save_initial_setting (struct sym_hcb *np){	np->sv_scntl0	= INB(np, nc_scntl0) & 0x0a;	np->sv_scntl3	= INB(np, nc_scntl3) & 0x07;	np->sv_dmode	= INB(np, nc_dmode)  & 0xce;	np->sv_dcntl	= INB(np, nc_dcntl)  & 0xa8;	np->sv_ctest3	= INB(np, nc_ctest3) & 0x01;	np->sv_ctest4	= INB(np, nc_ctest4) & 0x80;	np->sv_gpcntl	= INB(np, nc_gpcntl);	np->sv_stest1	= INB(np, nc_stest1);	np->sv_stest2	= INB(np, nc_stest2) & 0x20;	np->sv_stest4	= INB(np, nc_stest4);	if (np->features & FE_C10) {	/* Always large DMA fifo + ultra3 */		np->sv_scntl4	= INB(np, nc_scntl4);		np->sv_ctest5	= INB(np, nc_ctest5) & 0x04;	}	else		np->sv_ctest5	= INB(np, nc_ctest5) & 0x24;}/* *  Prepare io register values used by sym_start_up()  *  according to selected and supported features. */static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram){	u_char	burst_max;	u32	period;	int i;	/*	 *  Wide ?	 */	np->maxwide	= (np->features & FE_WIDE)? 1 : 0;	/*	 *  Guess the frequency of the chip's clock.	 */	if	(np->features & (FE_ULTRA3 | FE_ULTRA2))		np->clock_khz = 160000;	else if	(np->features & FE_ULTRA)		np->clock_khz = 80000;	else		np->clock_khz = 40000;	/*	 *  Get the clock multiplier factor. 	 */	if	(np->features & FE_QUAD)		np->multiplier	= 4;	else if	(np->features & FE_DBLR)		np->multiplier	= 2;	else		np->multiplier	= 1;	/*	 *  Measure SCSI clock frequency for chips 	 *  it may vary from assumed one.	 */	if (np->features & FE_VARCLK)		sym_getclock(np, np->multiplier);	/*	 * Divisor to be used for async (timer pre-scaler).	 */	i = np->clock_divn - 1;	while (--i >= 0) {		if (10ul * SYM_CONF_MIN_ASYNC * np->clock_khz > div_10M[i]) {			++i;			break;		}	}	np->rv_scntl3 = i+1;	/*	 * The C1010 uses hardwired divisors for async.	 * So, we just throw away, the async. divisor.:-)	 */	if (np->features & FE_C10)		np->rv_scntl3 = 0;	/*	 * Minimum synchronous period factor supported by the chip.	 * Btw, 'period' is in tenths of nanoseconds.	 */	period = (4 * div_10M[0] + np->clock_khz - 1) / np->clock_khz;	if	(period <= 250)		np->minsync = 10;	else if	(period <= 303)		np->minsync = 11;	else if	(period <= 500)		np->minsync = 12;	else				np->minsync = (period + 40 - 1) / 40;	/*	 * Check against chip SCSI standard support (SCSI-2,ULTRA,ULTRA2).	 */	if	(np->minsync < 25 &&		 !(np->features & (FE_ULTRA|FE_ULTRA2|FE_ULTRA3)))		np->minsync = 25;	else if	(np->minsync < 12 &&		 !(np->features & (FE_ULTRA2|FE_ULTRA3)))		np->minsync = 12;	/*	 * Maximum synchronous period factor supported by the chip.	 */	period = (11 * div_10M[np->clock_divn - 1]) / (4 * np->clock_khz);	np->maxsync = period > 2540 ? 254 : period / 10;	/*	 * If chip is a C1010, guess the sync limits in DT mode.	 */	if ((np->features & (FE_C10|FE_ULTRA3)) == (FE_C10|FE_ULTRA3)) {		if (np->clock_khz == 160000) {			np->minsync_dt = 9;			np->maxsync_dt = 50;			np->maxoffs_dt = nvram->type ? 62 : 31;		}	}		/*	 *  64 bit addressing  (895A/896/1010) ?	 */	if (np->features & FE_DAC) {#if   SYM_CONF_DMA_ADDRESSING_MODE == 0		np->rv_ccntl1	|= (DDAC);#elif SYM_CONF_DMA_ADDRESSING_MODE == 1		if (!np->use_dac)			np->rv_ccntl1	|= (DDAC);		else			np->rv_ccntl1	|= (XTIMOD | EXTIBMV);#elif SYM_CONF_DMA_ADDRESSING_MODE == 2		if (!np->use_dac)			np->rv_ccntl1	|= (DDAC);		else			np->rv_ccntl1	|= (0 | EXTIBMV);#endif	}	/*	 *  Phase mismatch handled by SCRIPTS (895A/896/1010) ?  	 */	if (np->features & FE_NOPM)		np->rv_ccntl0	|= (ENPMJ); 	/*	 *  C1010-33 Errata: Part Number:609-039638 (rev. 1) is fixed.	 *  In dual channel mode, contention occurs if internal cycles	 *  are used. Disable internal cycles.	 */	if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 &&	    np->revision_id < 0x1)		np->rv_ccntl0	|=  DILS;	/*	 *  Select burst length (dwords)	 */	burst_max	= SYM_SETUP_BURST_ORDER;	if (burst_max == 255)		burst_max = burst_code(np->sv_dmode, np->sv_ctest4,				       np->sv_ctest5);	if (burst_max > 7)		burst_max = 7;	if (burst_max > np->maxburst)		burst_max = np->maxburst;	/*	 *  DEL 352 - 53C810 Rev x11 - Part Number 609-0392140 - ITEM 2.	 *  This chip and the 860 Rev 1 may wrongly use PCI cache line 	 *  based transactions on LOAD/STORE instructions. So we have 	 *  to prevent these chips from using such PCI transactions in 	 *  this driver. The generic ncr driver that does not use 	 *  LOAD/STORE instructions does not need this work-around.	 */	if ((np->device_id == PCI_DEVICE_ID_NCR_53C810 &&	     np->revision_id >= 0x10 && np->revision_id <= 0x11) ||	    (np->device_id == PCI_DEVICE_ID_NCR_53C860 &&	     np->revision_id <= 0x1))		np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP);	/*	 *  Select all supported special features.	 *  If we are using on-board RAM for scripts, prefetch (PFEN) 	 *  does not help, but burst op fetch (BOF) does.	 *  Disabling PFEN makes sure BOF will be used.	 */	if (np->features & FE_ERL)		np->rv_dmode	|= ERL;		/* Enable Read Line */	if (np->features & FE_BOF)		np->rv_dmode	|= BOF;		/* Burst Opcode Fetch */	if (np->features & FE_ERMP)		np->rv_dmode	|= ERMP;	/* Enable Read Multiple */#if 1	if ((np->features & FE_PFEN) && !np->ram_ba)#else	if (np->features & FE_PFEN)#endif		np->rv_dcntl	|= PFEN;	/* Prefetch Enable */	if (np->features & FE_CLSE)		np->rv_dcntl	|= CLSE;	/* Cache Line Size Enable */	if (np->features & FE_WRIE)		np->rv_ctest3	|= WRIE;	/* Write and Invalidate */	if (np->features & FE_DFS)		np->rv_ctest5	|= DFS;		/* Dma Fifo Size */	/*	 *  Select some other	 */	np->rv_ctest4	|= MPEE; /* Master parity checking */	np->rv_scntl0	|= 0x0a; /*  full arb., ena parity, par->ATN  */	/*	 *  Get parity checking, host ID and verbose mode from NVRAM	 */	np->myaddr = 255;	sym_nvram_setup_host(shost, np, nvram);	/*	 *  Get SCSI addr of host adapter (set by bios?).	 */	if (np->myaddr == 255) {		np->myaddr = INB(np, nc_scid) & 0x07;		if (!np->myaddr)			np->myaddr = SYM_SETUP_HOST_ID;	}	/*	 *  Prepare initial io register bits for burst length	 */	sym_init_burst(np, burst_max);	/*	 *  Set SCSI BUS mode.	 *  - LVD capable chips (895/895A/896/1010) report the 	 *    current BUS mode through the STEST4 IO register.	 *  - For previous generation chips (825/825A/875), 	 *    user has to tell us how to check against HVD, 	 *    since a 100% safe algorithm is not possible.	 */	np->scsi_mode = SMODE_SE;	if (np->features & (FE_ULTRA2|FE_ULTRA3))		np->scsi_mode = (np->sv_stest4 & SMODE);	else if	(np->features & FE_DIFF) {		if (SYM_SETUP_SCSI_DIFF == 1) {			if (np->sv_scntl3) {				if (np->sv_stest2 & 0x20)					np->scsi_mode = SMODE_HVD;			}			else if (nvram->type == SYM_SYMBIOS_NVRAM) {				if (!(INB(np, nc_gpreg) & 0x08))					np->scsi_mode = SMODE_HVD;			}		}		else if	(SYM_SETUP_SCSI_DIFF == 2)			np->scsi_mode = SMODE_HVD;	}	if (np->scsi_mode == SMODE_HVD)		np->rv_stest2 |= 0x20;	/*	 *  Set LED support from SCRIPTS.	 *  Ignore this feature for boards known to use a 	 *  specific GPIO wiring and for the 895A, 896 	 *  and 1010 that drive the LED directly.	 */	if ((SYM_SETUP_SCSI_LED || 	     (nvram->type == SYM_SYMBIOS_NVRAM ||	      (nvram->type == SYM_TEKRAM_NVRAM &&	       np->device_id == PCI_DEVICE_ID_NCR_53C895))) &&	    !(np->features & FE_LEDC) && !(np->sv_gpcntl & 0x01))		np->features |= FE_LED0;	/*	 *  Set irq mode.	 */	switch(SYM_SETUP_IRQ_MODE & 3) {	case 2:		np->rv_dcntl	|= IRQM;		break;	case 1:		np->rv_dcntl	|= (np->sv_dcntl & IRQM);		break;	default:		break;	}	/*	 *  Configure targets according to driver setup.	 *  If NVRAM present get targets setup from NVRAM.	 */	for (i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) {		struct sym_tcb *tp = &np->target[i];		tp->usrflags |= (SYM_DISC_ENABLED | SYM_TAGS_ENABLED);		tp->usrtags = SYM_SETUP_MAX_TAG;		sym_nvram_setup_target(np, i, nvram);		if (!tp->usrtags)			tp->usrflags &= ~SYM_TAGS_ENABLED;	}	/*	 *  Let user know about the settings.	 */	printf("%s: %s, ID %d, Fast-%d, %s, %s\n", sym_name(np),		sym_nvram_type(nvram), np->myaddr,		(np->features & FE_ULTRA3) ? 80 : 		(np->features & FE_ULTRA2) ? 40 : 		(np->features & FE_ULTRA)  ? 20 : 10,		sym_scsi_bus_mode(np->scsi_mode),		(np->rv_scntl0 & 0xa)	? "parity checking" : "NO parity");	/*	 *  Tell him more on demand.	 */	if (sym_verbose) {		printf("%s: %s IRQ line driver%s\n",			sym_name(np),			np->rv_dcntl & IRQM ? "totem pole" : "open drain",			np->ram_ba ? ", using on-chip SRAM" : "");		printf("%s: using %s firmware.\n", sym_name(np), np->fw_name);		if (np->features & FE_NOPM)			printf("%s: handling phase mismatch from SCRIPTS.\n", 			       sym_name(np));	}	/*	 *  And still more.	 */	if (sym_verbose >= 2) {		printf ("%s: initial SCNTL3/DMODE/DCNTL/CTEST3/4/5 = "			"(hex) %02x/%02x/%02x/%02x/%02x/%02x\n",			sym_name(np), np->sv_scntl3, np->sv_dmode, np->sv_dcntl,			np->sv_ctest3, np->sv_ctest4, np->sv_ctest5);		printf ("%s: final   SCNTL3/DMODE/DCNTL/CTEST3/4/5 = "			"(hex) %02x/%02x/%02x/%02x/%02x/%02x\n",			sym_name(np), np->rv_scntl3, np->rv_dmode, np->rv_dcntl,			np->rv_ctest3, np->rv_ctest4, np->rv_ctest5);	}	/*	 *  Let user be aware of targets that have some disable flags set.	 */	sym_print_targets_flag(np, SYM_SCAN_BOOT_DISABLED, "SCAN AT BOOT");	if (sym_verbose)		sym_print_targets_flag(np, SYM_SCAN_LUNS_DISABLED,				       "SCAN FOR LUNS");

⌨️ 快捷键说明

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