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

📄 sym_hipd.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	return 0;}/* *  Test the pci bus snoop logic :-( * *  Has to be called with interrupts disabled. */#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPEDstatic int sym_regtest (struct sym_hcb *np){	register volatile u32 data;	/*	 *  chip registers may NOT be cached.	 *  write 0xffffffff to a read only register area,	 *  and try to read it back.	 */	data = 0xffffffff;	OUTL(np, nc_dstat, data);	data = INL(np, nc_dstat);#if 1	if (data == 0xffffffff) {#else	if ((data & 0xe2f0fffd) != 0x02000080) {#endif		printf ("CACHE TEST FAILED: reg dstat-sstat2 readback %x.\n",			(unsigned) data);		return (0x10);	}	return (0);}#endifstatic int sym_snooptest (struct sym_hcb *np){	u32	sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat;	int	i, err=0;#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED	err |= sym_regtest (np);	if (err) return (err);#endifrestart_test:	/*	 *  Enable Master Parity Checking as we intend 	 *  to enable it for normal operations.	 */	OUTB(np, nc_ctest4, (np->rv_ctest4 & MPEE));	/*	 *  init	 */	pc  = SCRIPTZ_BA(np, snooptest);	host_wr = 1;	sym_wr  = 2;	/*	 *  Set memory and register.	 */	np->scratch = cpu_to_scr(host_wr);	OUTL(np, nc_temp, sym_wr);	/*	 *  Start script (exchange values)	 */	OUTL(np, nc_dsa, np->hcb_ba);	OUTL_DSP(np, pc);	/*	 *  Wait 'til done (with timeout)	 */	for (i=0; i<SYM_SNOOP_TIMEOUT; i++)		if (INB(np, nc_istat) & (INTF|SIP|DIP))			break;	if (i>=SYM_SNOOP_TIMEOUT) {		printf ("CACHE TEST FAILED: timeout.\n");		return (0x20);	}	/*	 *  Check for fatal DMA errors.	 */	dstat = INB(np, nc_dstat);#if 1	/* Band aiding for broken hardwares that fail PCI parity */	if ((dstat & MDPE) && (np->rv_ctest4 & MPEE)) {		printf ("%s: PCI DATA PARITY ERROR DETECTED - "			"DISABLING MASTER DATA PARITY CHECKING.\n",			sym_name(np));		np->rv_ctest4 &= ~MPEE;		goto restart_test;	}#endif	if (dstat & (MDPE|BF|IID)) {		printf ("CACHE TEST FAILED: DMA error (dstat=0x%02x).", dstat);		return (0x80);	}	/*	 *  Save termination position.	 */	pc = INL(np, nc_dsp);	/*	 *  Read memory and register.	 */	host_rd = scr_to_cpu(np->scratch);	sym_rd  = INL(np, nc_scratcha);	sym_bk  = INL(np, nc_temp);	/*	 *  Check termination position.	 */	if (pc != SCRIPTZ_BA(np, snoopend)+8) {		printf ("CACHE TEST FAILED: script execution failed.\n");		printf ("start=%08lx, pc=%08lx, end=%08lx\n", 			(u_long) SCRIPTZ_BA(np, snooptest), (u_long) pc,			(u_long) SCRIPTZ_BA(np, snoopend) +8);		return (0x40);	}	/*	 *  Show results.	 */	if (host_wr != sym_rd) {		printf ("CACHE TEST FAILED: host wrote %d, chip read %d.\n",			(int) host_wr, (int) sym_rd);		err |= 1;	}	if (host_rd != sym_wr) {		printf ("CACHE TEST FAILED: chip wrote %d, host read %d.\n",			(int) sym_wr, (int) host_rd);		err |= 2;	}	if (sym_bk != sym_wr) {		printf ("CACHE TEST FAILED: chip wrote %d, read back %d.\n",			(int) sym_wr, (int) sym_bk);		err |= 4;	}	return (err);}/* *  log message for real hard errors * *  sym0 targ 0?: ERROR (ds:si) (so-si-sd) (sx/s3/s4) @ name (dsp:dbc). *  	      reg: r0 r1 r2 r3 r4 r5 r6 ..... rf. * *  exception register: *  	ds:	dstat *  	si:	sist * *  SCSI bus lines: *  	so:	control lines as driven by chip. *  	si:	control lines as seen by chip. *  	sd:	scsi data lines as seen by chip. * *  wide/fastmode: *  	sx:	sxfer  (see the manual) *  	s3:	scntl3 (see the manual) *  	s4:	scntl4 (see the manual) * *  current script command: *  	dsp:	script address (relative to start of script). *  	dbc:	first word of script command. * *  First 24 register of the chip: *  	r0..rf */static void sym_log_hard_error(struct sym_hcb *np, u_short sist, u_char dstat){	u32	dsp;	int	script_ofs;	int	script_size;	char	*script_name;	u_char	*script_base;	int	i;	dsp	= INL(np, nc_dsp);	if	(dsp > np->scripta_ba &&		 dsp <= np->scripta_ba + np->scripta_sz) {		script_ofs	= dsp - np->scripta_ba;		script_size	= np->scripta_sz;		script_base	= (u_char *) np->scripta0;		script_name	= "scripta";	}	else if (np->scriptb_ba < dsp && 		 dsp <= np->scriptb_ba + np->scriptb_sz) {		script_ofs	= dsp - np->scriptb_ba;		script_size	= np->scriptb_sz;		script_base	= (u_char *) np->scriptb0;		script_name	= "scriptb";	} else {		script_ofs	= dsp;		script_size	= 0;		script_base	= NULL;		script_name	= "mem";	}	printf ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x/%x) @ (%s %x:%08x).\n",		sym_name(np), (unsigned)INB(np, nc_sdid)&0x0f, dstat, sist,		(unsigned)INB(np, nc_socl), (unsigned)INB(np, nc_sbcl),		(unsigned)INB(np, nc_sbdl), (unsigned)INB(np, nc_sxfer),		(unsigned)INB(np, nc_scntl3),		(np->features & FE_C10) ?  (unsigned)INB(np, nc_scntl4) : 0,		script_name, script_ofs,   (unsigned)INL(np, nc_dbc));	if (((script_ofs & 3) == 0) &&	    (unsigned)script_ofs < script_size) {		printf ("%s: script cmd = %08x\n", sym_name(np),			scr_to_cpu((int) *(u32 *)(script_base + script_ofs)));	}        printf ("%s: regdump:", sym_name(np));        for (i=0; i<24;i++)            printf (" %02x", (unsigned)INB_OFF(np, i));        printf (".\n");	/*	 *  PCI BUS error.	 */	if (dstat & (MDPE|BF))		sym_log_bus_error(np);}static struct sym_chip sym_dev_table[] = { {PCI_DEVICE_ID_NCR_53C810, 0x0f, "810", 4, 8, 4, 64, FE_ERL} ,#ifdef SYM_DEBUG_GENERIC_SUPPORT {PCI_DEVICE_ID_NCR_53C810, 0xff, "810a", 4,  8, 4, 1, FE_BOF} ,#else {PCI_DEVICE_ID_NCR_53C810, 0xff, "810a", 4,  8, 4, 1, FE_CACHE_SET|FE_LDSTR|FE_PFEN|FE_BOF} ,#endif {PCI_DEVICE_ID_NCR_53C815, 0xff, "815", 4,  8, 4, 64, FE_BOF|FE_ERL} , {PCI_DEVICE_ID_NCR_53C825, 0x0f, "825", 6,  8, 4, 64, FE_WIDE|FE_BOF|FE_ERL|FE_DIFF} , {PCI_DEVICE_ID_NCR_53C825, 0xff, "825a", 6,  8, 4, 2, FE_WIDE|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM|FE_DIFF} , {PCI_DEVICE_ID_NCR_53C860, 0xff, "860", 4,  8, 5, 1, FE_ULTRA|FE_CACHE_SET|FE_BOF|FE_LDSTR|FE_PFEN} , {PCI_DEVICE_ID_NCR_53C875, 0x01, "875", 6, 16, 5, 2, FE_WIDE|FE_ULTRA|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DIFF|FE_VARCLK} , {PCI_DEVICE_ID_NCR_53C875, 0xff, "875", 6, 16, 5, 2, FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DIFF|FE_VARCLK} , {PCI_DEVICE_ID_NCR_53C875J, 0xff, "875J", 6, 16, 5, 2, FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DIFF|FE_VARCLK} , {PCI_DEVICE_ID_NCR_53C885, 0xff, "885", 6, 16, 5, 2, FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DIFF|FE_VARCLK} ,#ifdef SYM_DEBUG_GENERIC_SUPPORT {PCI_DEVICE_ID_NCR_53C895, 0xff, "895", 6, 31, 7, 2, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS| FE_RAM|FE_LCKFRQ} ,#else {PCI_DEVICE_ID_NCR_53C895, 0xff, "895", 6, 31, 7, 2, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_LCKFRQ} ,#endif {PCI_DEVICE_ID_NCR_53C896, 0xff, "896", 6, 31, 7, 4, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ} , {PCI_DEVICE_ID_LSI_53C895A, 0xff, "895a", 6, 31, 7, 4, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ} , {PCI_DEVICE_ID_LSI_53C875A, 0xff, "875a", 6, 31, 7, 4, FE_WIDE|FE_ULTRA|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ} , {PCI_DEVICE_ID_LSI_53C1010_33, 0x00, "1010-33", 6, 31, 7, 8, FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC| FE_C10} , {PCI_DEVICE_ID_LSI_53C1010_33, 0xff, "1010-33", 6, 31, 7, 8, FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC| FE_C10|FE_U3EN} , {PCI_DEVICE_ID_LSI_53C1010_66, 0xff, "1010-66", 6, 31, 7, 8, FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_66MHZ|FE_CRC| FE_C10|FE_U3EN} , {PCI_DEVICE_ID_LSI_53C1510, 0xff, "1510d", 6, 31, 7, 4, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_IO256|FE_LEDC}};#define sym_num_devs \	(sizeof(sym_dev_table) / sizeof(sym_dev_table[0]))/* *  Look up the chip table. * *  Return a pointer to the chip entry if found,  *  zero otherwise. */struct sym_chip *sym_lookup_chip_table (u_short device_id, u_char revision){	struct	sym_chip *chip;	int	i;	for (i = 0; i < sym_num_devs; i++) {		chip = &sym_dev_table[i];		if (device_id != chip->device_id)			continue;		if (revision > chip->revision_id)			continue;		return chip;	}	return NULL;}#if SYM_CONF_DMA_ADDRESSING_MODE == 2/* *  Lookup the 64 bit DMA segments map. *  This is only used if the direct mapping  *  has been unsuccessful. */int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s){	int i;	if (!np->use_dac)		goto weird;	/* Look up existing mappings */	for (i = SYM_DMAP_SIZE-1; i > 0; i--) {		if (h == np->dmap_bah[i])			return i;	}	/* If direct mapping is free, get it */	if (!np->dmap_bah[s])		goto new;	/* Collision -> lookup free mappings */	for (s = SYM_DMAP_SIZE-1; s > 0; s--) {		if (!np->dmap_bah[s])			goto new;	}weird:	panic("sym: ran out of 64 bit DMA segment registers");	return -1;new:	np->dmap_bah[s] = h;	np->dmap_dirty = 1;	return s;}/* *  Update IO registers scratch C..R so they will be  *  in sync. with queued CCB expectations. */static void sym_update_dmap_regs(struct sym_hcb *np){	int o, i;	if (!np->dmap_dirty)		return;	o = offsetof(struct sym_reg, nc_scrx[0]);	for (i = 0; i < SYM_DMAP_SIZE; i++) {		OUTL_OFF(np, o, np->dmap_bah[i]);		o += 4;	}	np->dmap_dirty = 0;}#endif/* Enforce all the fiddly SPI rules and the chip limitations */static void sym_check_goals(struct sym_hcb *np, struct scsi_target *starget,		struct sym_trans *goal){	if (!spi_support_wide(starget))		goal->width = 0;	if (!spi_support_sync(starget)) {		goal->iu = 0;		goal->dt = 0;		goal->qas = 0;		goal->offset = 0;		return;	}	if (spi_support_dt(starget)) {		if (spi_support_dt_only(starget))			goal->dt = 1;		if (goal->offset == 0)			goal->dt = 0;	} else {		goal->dt = 0;	}	/* Some targets fail to properly negotiate DT in SE mode */	if ((np->scsi_mode != SMODE_LVD) || !(np->features & FE_U3EN))		goal->dt = 0;	if (goal->dt) {		/* all DT transfers must be wide */		goal->width = 1;		if (goal->offset > np->maxoffs_dt)			goal->offset = np->maxoffs_dt;		if (goal->period < np->minsync_dt)			goal->period = np->minsync_dt;		if (goal->period > np->maxsync_dt)			goal->period = np->maxsync_dt;	} else {		goal->iu = goal->qas = 0;		if (goal->offset > np->maxoffs)			goal->offset = np->maxoffs;		if (goal->period < np->minsync)			goal->period = np->minsync;		if (goal->period > np->maxsync)			goal->period = np->maxsync;	}}/* *  Prepare the next negotiation message if needed. * *  Fill in the part of message buffer that contains the  *  negotiation and the nego_status field of the CCB. *  Returns the size of the message in bytes. */static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgptr){	struct sym_tcb *tp = &np->target[cp->target];	struct scsi_target *starget = tp->starget;	struct sym_trans *goal = &tp->tgoal;	int msglen = 0;	int nego;	sym_check_goals(np, starget, goal);	/*	 * Many devices implement PPR in a buggy way, so only use it if we	 * really want to.	 */	if (goal->offset &&	    (goal->iu || goal->dt || goal->qas || (goal->period < 0xa))) {		nego = NS_PPR;	} else if (spi_width(starget) != goal->width) {		nego = NS_WIDE;	} else if (spi_period(starget) != goal->period ||		   spi_offset(starget) != goal->offset) {		nego = NS_SYNC;	} else {		goal->check_nego = 0;		nego = 0;	}	switch (nego) {	case NS_SYNC:		msgptr[msglen++] = M_EXTENDED;		msgptr[msglen++] = 3;		msgptr[msglen++] = M_X_SYNC_REQ;		msgptr[msglen++] = goal->period;		msgptr[msglen++] = goal->offset;		break;	case NS_WIDE:		msgptr[msglen++] = M_EXTENDED;		msgptr[msglen++] = 2;		msgptr[msglen++] = M_X_WIDE_REQ;		msgptr[msglen++] = goal->width;		break;	case NS_PPR:		msgptr[msglen++] = M_EXTENDED;		msgptr[msglen++] = 6;		msgptr[msglen++] = M_X_PPR_REQ;		msgptr[msglen++] = goal->period;		msgptr[msglen++] = 0;		msgptr[msglen++] = goal->offset;		msgptr[msglen++] = goal->width;		msgptr[msglen++] = (goal->iu ? PPR_OPT_IU : 0) |					(goal->dt ? PPR_OPT_DT : 0) |					(goal->qas ? PPR_OPT_QAS : 0);		break;	}	cp->nego_status = nego;	if (nego) {		tp->nego_cp = cp; /* Keep track a nego will be performed */		if (DEBUG_FLAGS & DEBUG_NEGO) {			sym_print_nego_msg(np, cp->target, 					  nego == NS_SYNC ? "sync msgout" :					  nego == NS_WIDE ? "wide msgout" :					  "ppr msgout", msgptr);		}	}	return msglen;}

⌨️ 快捷键说明

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