ncr53c8xx.c

来自「linux 内核源代码」· C语言 代码 · 共 2,376 行 · 第 1/5 页

C
2,376
字号
	return m;}static void __m_free_dma(m_bush_t bush, void *m, int size, char *name){	u_long flags;	struct m_pool *mp;	spin_lock_irqsave(&ncr53c8xx_lock, flags);	mp = ___get_dma_pool(bush);	if (mp)		__m_free(mp, m, size, name);	if (mp && !mp->nump)		___del_dma_pool(mp);	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);}static m_addr_t __vtobus(m_bush_t bush, void *m){	u_long flags;	m_pool_s *mp;	int hc = VTOB_HASH_CODE(m);	m_vtob_s *vp = NULL;	m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK;	spin_lock_irqsave(&ncr53c8xx_lock, flags);	mp = ___get_dma_pool(bush);	if (mp) {		vp = mp->vtob[hc];		while (vp && (m_addr_t) vp->vaddr != a)			vp = vp->next;	}	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);	return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;}#define _m_calloc_dma(np, s, n)		__m_calloc_dma(np->dev, s, n)#define _m_free_dma(np, p, s, n)	__m_free_dma(np->dev, p, s, n)#define m_calloc_dma(s, n)		_m_calloc_dma(np, s, n)#define m_free_dma(p, s, n)		_m_free_dma(np, p, s, n)#define _vtobus(np, p)			__vtobus(np->dev, p)#define vtobus(p)			_vtobus(np, p)/* *  Deal with DMA mapping/unmapping. *//* To keep track of the dma mapping (sg/single) that has been set */#define __data_mapped	SCp.phase#define __data_mapping	SCp.have_data_instatic void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd){	switch(cmd->__data_mapped) {	case 2:		scsi_dma_unmap(cmd);		break;	}	cmd->__data_mapped = 0;}static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd){	int use_sg;	use_sg = scsi_dma_map(cmd);	if (!use_sg)		return 0;	cmd->__data_mapped = 2;	cmd->__data_mapping = use_sg;	return use_sg;}#define unmap_scsi_data(np, cmd)	__unmap_scsi_data(np->dev, cmd)#define map_scsi_sg_data(np, cmd)	__map_scsi_sg_data(np->dev, cmd)/*==========================================================****	Driver setup.****	This structure is initialized from linux config **	options. It can be overridden at boot-up by the boot **	command line.****==========================================================*/static struct ncr_driver_setup	driver_setup			= SCSI_NCR_DRIVER_SETUP;#ifndef MODULE#ifdef	SCSI_NCR_BOOT_COMMAND_LINE_SUPPORTstatic struct ncr_driver_setup	driver_safe_setup __initdata	= SCSI_NCR_DRIVER_SAFE_SETUP;#endif#endif /* !MODULE */#define initverbose (driver_setup.verbose)#define bootverbose (np->verbose)/*===================================================================****	Driver setup from the boot command line****===================================================================*/#ifdef MODULE#define	ARG_SEP	' '#else#define	ARG_SEP	','#endif#define OPT_TAGS		1#define OPT_MASTER_PARITY	2#define OPT_SCSI_PARITY		3#define OPT_DISCONNECTION	4#define OPT_SPECIAL_FEATURES	5#define OPT_UNUSED_1		6#define OPT_FORCE_SYNC_NEGO	7#define OPT_REVERSE_PROBE	8#define OPT_DEFAULT_SYNC	9#define OPT_VERBOSE		10#define OPT_DEBUG		11#define OPT_BURST_MAX		12#define OPT_LED_PIN		13#define OPT_MAX_WIDE		14#define OPT_SETTLE_DELAY	15#define OPT_DIFF_SUPPORT	16#define OPT_IRQM		17#define OPT_PCI_FIX_UP		18#define OPT_BUS_CHECK		19#define OPT_OPTIMIZE		20#define OPT_RECOVERY		21#define OPT_SAFE_SETUP		22#define OPT_USE_NVRAM		23#define OPT_EXCLUDE		24#define OPT_HOST_ID		25#ifdef SCSI_NCR_IARB_SUPPORT#define OPT_IARB		26#endif#ifdef MODULE#define	ARG_SEP	' '#else#define	ARG_SEP	','#endif#ifndef MODULEstatic char setup_token[] __initdata = 	"tags:"   "mpar:"	"spar:"   "disc:"	"specf:"  "ultra:"	"fsn:"    "revprob:"	"sync:"   "verb:"	"debug:"  "burst:"	"led:"    "wide:"	"settle:" "diff:"	"irqm:"   "pcifix:"	"buschk:" "optim:"	"recovery:"	"safe:"   "nvram:"	"excl:"   "hostid:"#ifdef SCSI_NCR_IARB_SUPPORT	"iarb:"#endif	;	/* DONNOT REMOVE THIS ';' */static int __init get_setup_token(char *p){	char *cur = setup_token;	char *pc;	int i = 0;	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {		++pc;		++i;		if (!strncmp(p, cur, pc - cur))			return i;		cur = pc;	}	return 0;}static int __init sym53c8xx__setup(char *str){#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT	char *cur = str;	char *pc, *pv;	int i, val, c;	int xi = 0;	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {		char *pe;		val = 0;		pv = pc;		c = *++pv;		if	(c == 'n')			val = 0;		else if	(c == 'y')			val = 1;		else			val = (int) simple_strtoul(pv, &pe, 0);		switch (get_setup_token(cur)) {		case OPT_TAGS:			driver_setup.default_tags = val;			if (pe && *pe == '/') {				i = 0;				while (*pe && *pe != ARG_SEP && 					i < sizeof(driver_setup.tag_ctrl)-1) {					driver_setup.tag_ctrl[i++] = *pe++;				}				driver_setup.tag_ctrl[i] = '\0';			}			break;		case OPT_MASTER_PARITY:			driver_setup.master_parity = val;			break;		case OPT_SCSI_PARITY:			driver_setup.scsi_parity = val;			break;		case OPT_DISCONNECTION:			driver_setup.disconnection = val;			break;		case OPT_SPECIAL_FEATURES:			driver_setup.special_features = val;			break;		case OPT_FORCE_SYNC_NEGO:			driver_setup.force_sync_nego = val;			break;		case OPT_REVERSE_PROBE:			driver_setup.reverse_probe = val;			break;		case OPT_DEFAULT_SYNC:			driver_setup.default_sync = val;			break;		case OPT_VERBOSE:			driver_setup.verbose = val;			break;		case OPT_DEBUG:			driver_setup.debug = val;			break;		case OPT_BURST_MAX:			driver_setup.burst_max = val;			break;		case OPT_LED_PIN:			driver_setup.led_pin = val;			break;		case OPT_MAX_WIDE:			driver_setup.max_wide = val? 1:0;			break;		case OPT_SETTLE_DELAY:			driver_setup.settle_delay = val;			break;		case OPT_DIFF_SUPPORT:			driver_setup.diff_support = val;			break;		case OPT_IRQM:			driver_setup.irqm = val;			break;		case OPT_PCI_FIX_UP:			driver_setup.pci_fix_up	= val;			break;		case OPT_BUS_CHECK:			driver_setup.bus_check = val;			break;		case OPT_OPTIMIZE:			driver_setup.optimize = val;			break;		case OPT_RECOVERY:			driver_setup.recovery = val;			break;		case OPT_USE_NVRAM:			driver_setup.use_nvram = val;			break;		case OPT_SAFE_SETUP:			memcpy(&driver_setup, &driver_safe_setup,				sizeof(driver_setup));			break;		case OPT_EXCLUDE:			if (xi < SCSI_NCR_MAX_EXCLUDES)				driver_setup.excludes[xi++] = val;			break;		case OPT_HOST_ID:			driver_setup.host_id = val;			break;#ifdef SCSI_NCR_IARB_SUPPORT		case OPT_IARB:			driver_setup.iarb = val;			break;#endif		default:			printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);			break;		}		if ((cur = strchr(cur, ARG_SEP)) != NULL)			++cur;	}#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */	return 1;}#endif /* !MODULE *//*===================================================================****	Get device queue depth from boot command line.****===================================================================*/#define DEF_DEPTH	(driver_setup.default_tags)#define ALL_TARGETS	-2#define NO_TARGET	-1#define ALL_LUNS	-2#define NO_LUN		-1static int device_queue_depth(int unit, int target, int lun){	int c, h, t, u, v;	char *p = driver_setup.tag_ctrl;	char *ep;	h = -1;	t = NO_TARGET;	u = NO_LUN;	while ((c = *p++) != 0) {		v = simple_strtoul(p, &ep, 0);		switch(c) {		case '/':			++h;			t = ALL_TARGETS;			u = ALL_LUNS;			break;		case 't':			if (t != target)				t = (target == v) ? v : NO_TARGET;			u = ALL_LUNS;			break;		case 'u':			if (u != lun)				u = (lun == v) ? v : NO_LUN;			break;		case 'q':			if (h == unit &&				(t == ALL_TARGETS || t == target) &&				(u == ALL_LUNS    || u == lun))				return v;			break;		case '-':			t = ALL_TARGETS;			u = ALL_LUNS;			break;		default:			break;		}		p = ep;	}	return DEF_DEPTH;}/*==========================================================****	The CCB done queue uses an array of CCB virtual **	addresses. Empty entries are flagged using the bogus **	virtual address 0xffffffff.****	Since PCI ensures that only aligned DWORDs are accessed **	atomically, 64 bit little-endian architecture requires **	to test the high order DWORD of the entry to determine **	if it is empty or valid.****	BTW, I will make things differently as soon as I will **	have a better idea, but this is simple and should work.****==========================================================*/ #define SCSI_NCR_CCB_DONE_SUPPORT#ifdef  SCSI_NCR_CCB_DONE_SUPPORT#define MAX_DONE 24#define CCB_DONE_EMPTY 0xffffffffUL/* All 32 bit architectures */#if BITS_PER_LONG == 32#define CCB_DONE_VALID(cp)  (((u_long) cp) != CCB_DONE_EMPTY)/* All > 32 bit (64 bit) architectures regardless endian-ness */#else#define CCB_DONE_VALID(cp)  \	((((u_long) cp) & 0xffffffff00000000ul) && 	\	 (((u_long) cp) & 0xfffffffful) != CCB_DONE_EMPTY)#endif#endif /* SCSI_NCR_CCB_DONE_SUPPORT *//*==========================================================****	Configuration and Debugging****==========================================================*//***    SCSI address of this device.**    The boot routines should have set it.**    If not, use this.*/#ifndef SCSI_NCR_MYADDR#define SCSI_NCR_MYADDR      (7)#endif/***    The maximum number of tags per logic unit.**    Used only for disk devices that support tags.*/#ifndef SCSI_NCR_MAX_TAGS#define SCSI_NCR_MAX_TAGS    (8)#endif/***    TAGS are actually limited to 64 tags/lun.**    We need to deal with power of 2, for alignment constraints.*/#if	SCSI_NCR_MAX_TAGS > 64#define	MAX_TAGS (64)#else#define	MAX_TAGS SCSI_NCR_MAX_TAGS#endif#define NO_TAG	(255)/***	Choose appropriate type for tag bitmap.*/#if	MAX_TAGS > 32typedef u64 tagmap_t;#elsetypedef u32 tagmap_t;#endif/***    Number of targets supported by the driver.**    n permits target numbers 0..n-1.**    Default is 16, meaning targets #0..#15.**    #7 .. is myself.*/#ifdef SCSI_NCR_MAX_TARGET#define MAX_TARGET  (SCSI_NCR_MAX_TARGET)#else#define MAX_TARGET  (16)#endif/***    Number of logic units supported by the driver.**    n enables logic unit numbers 0..n-1.**    The common SCSI devices require only**    one lun, so take 1 as the default.*/#ifdef SCSI_NCR_MAX_LUN#define MAX_LUN    SCSI_NCR_MAX_LUN#else#define MAX_LUN    (1)#endif

⌨️ 快捷键说明

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