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

📄 sym_glue.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	 *  Now let the generic SCSI driver	 *  look for the SCSI devices on the bus ..	 */	return 0;attach_failed:	if (!instance) return -1;	printf_info("%s: giving up ...\n", sym_name(np));	if (np)		sym_free_resources(np);	scsi_unregister(instance);        return -1; }/* *    Detect and try to read SYMBIOS and TEKRAM NVRAM. */#if SYM_CONF_NVRAM_SUPPORTstatic void __init sym_get_nvram(sym_device *devp, sym_nvram *nvp){	if (!nvp)		return;	devp->nvram = nvp;	devp->device_id = devp->chip.device_id;	nvp->type = 0;	/*	 *  Get access to chip IO registers	 */#ifdef SYM_CONF_IOMAPPED	request_region(devp->s.io_port, 128, NAME53C8XX);#else	devp->s.mmio_va = pci_map_mem(devp->s.base_c, 128);	if (!devp->s.mmio_va)		return;#endif	/*	 *  Try to read SYMBIOS|TEKRAM nvram.	 */	(void) sym_read_nvram(devp, nvp);	/*	 *  Release access to chip IO registers	 */#ifdef SYM_CONF_IOMAPPED	release_region(devp->s.io_port, 128);#else	pci_unmap_mem((u_long) devp->s.mmio_va, 128ul);#endif}#endif	/* SYM_CONF_NVRAM_SUPPORT *//* *  Driver setup from the boot command line */#ifdef	SYM_LINUX_BOOT_COMMAND_LINE_SUPPORTstatic struct sym_driver_setup	sym_driver_safe_setup __initdata = SYM_LINUX_DRIVER_SAFE_SETUP;#ifdef	MODULEchar *sym53c8xx = 0;	/* command line passed by insmod */MODULE_PARM(sym53c8xx, "s");#endifstatic void __init sym53c8xx_print_driver_setup(void){	printf_info (NAME53C8XX ": setup="		"mpar:%d,spar:%d,tags:%d,sync:%d,burst:%d,"		"led:%d,wide:%d,diff:%d,irqm:%d, buschk:%d\n",		sym_driver_setup.pci_parity,		sym_driver_setup.scsi_parity,		sym_driver_setup.max_tag,		sym_driver_setup.min_sync,		sym_driver_setup.burst_order,		sym_driver_setup.scsi_led,		sym_driver_setup.max_wide,		sym_driver_setup.scsi_diff,		sym_driver_setup.irq_mode,		sym_driver_setup.scsi_bus_check);	printf_info (NAME53C8XX ": setup="		"hostid:%d,offs:%d,luns:%d,pcifix:%d,revprob:%d,"		"verb:%d,debug:0x%x,setlle_delay:%d\n",		sym_driver_setup.host_id,		sym_driver_setup.max_offs,		sym_driver_setup.max_lun,		sym_driver_setup.pci_fix_up,		sym_driver_setup.reverse_probe,		sym_driver_setup.verbose,		sym_driver_setup.debug,		sym_driver_setup.settle_delay);#ifdef DEBUG_2_0_XMDELAY(5000);#endif};#define OPT_PCI_PARITY		1#define	OPT_SCSI_PARITY		2#define OPT_MAX_TAG		3#define OPT_MIN_SYNC		4#define OPT_BURST_ORDER		5#define OPT_SCSI_LED		6#define OPT_MAX_WIDE		7#define OPT_SCSI_DIFF		8#define OPT_IRQ_MODE		9#define OPT_SCSI_BUS_CHECK	10#define	OPT_HOST_ID		11#define OPT_MAX_OFFS		12#define OPT_MAX_LUN		13#define OPT_PCI_FIX_UP		14#define OPT_REVERSE_PROBE	15#define OPT_VERBOSE		16#define OPT_DEBUG		17#define OPT_SETTLE_DELAY	18#define OPT_USE_NVRAM		19#define OPT_EXCLUDE		20#define OPT_SAFE_SETUP		21static char setup_token[] __initdata =	"mpar:"		"spar:"	"tags:"		"sync:"	"burst:"	"led:"	"wide:"		"diff:"	"irqm:"		"buschk:"	"hostid:"	"offset:"	"luns:"		"pcifix:"	"revprob:"	"verb:"	"debug:"	"settle:"	"nvram:"	"excl:"	"safe:"	;#ifdef MODULE#define	ARG_SEP	' '#else#define	ARG_SEP	','#endifstatic 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;}#endif	/* SYM_LINUX_BOOT_COMMAND_LINE_SUPPORT */int __init sym53c8xx_setup(char *str){#ifdef	SYM_LINUX_BOOT_COMMAND_LINE_SUPPORT	char *cur = str;	char *pc, *pv;	unsigned long val;	int i,  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_MAX_TAG:			sym_driver_setup.max_tag = val;			if (!(pe && *pe == '/'))				break;			i = 0;			while (*pe && *pe != ARG_SEP && 				i < sizeof(sym_driver_setup.tag_ctrl)-1) {				sym_driver_setup.tag_ctrl[i++] = *pe++;			}			sym_driver_setup.tag_ctrl[i] = '\0';			break;		case OPT_SAFE_SETUP:			memcpy(&sym_driver_setup, &sym_driver_safe_setup,				sizeof(sym_driver_setup));			break;		case OPT_EXCLUDE:			if (xi < 8)				sym_driver_setup.excludes[xi++] = val;			break;#define __SIMPLE_OPTION(NAME, name) \		case OPT_ ## NAME :		\			sym_driver_setup.name = val;\			break;		__SIMPLE_OPTION(PCI_PARITY, pci_parity)		__SIMPLE_OPTION(SCSI_PARITY, scsi_parity)		__SIMPLE_OPTION(MIN_SYNC, min_sync)		__SIMPLE_OPTION(BURST_ORDER, burst_order)		__SIMPLE_OPTION(SCSI_LED, scsi_led)		__SIMPLE_OPTION(MAX_WIDE, max_wide)		__SIMPLE_OPTION(SCSI_DIFF, scsi_diff)		__SIMPLE_OPTION(IRQ_MODE, irq_mode)		__SIMPLE_OPTION(SCSI_BUS_CHECK, scsi_bus_check)		__SIMPLE_OPTION(HOST_ID, host_id)		__SIMPLE_OPTION(MAX_OFFS, max_offs)		__SIMPLE_OPTION(MAX_LUN, max_lun)		__SIMPLE_OPTION(PCI_FIX_UP, pci_fix_up)		__SIMPLE_OPTION(REVERSE_PROBE, reverse_probe)		__SIMPLE_OPTION(VERBOSE, verbose)		__SIMPLE_OPTION(DEBUG, debug)		__SIMPLE_OPTION(SETTLE_DELAY, settle_delay)		__SIMPLE_OPTION(USE_NVRAM, use_nvram)#undef __SIMPLE_OPTION		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	/* SYM_LINUX_BOOT_COMMAND_LINE_SUPPORT */	return 1;}#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)#ifndef MODULE__setup("sym53c8xx=", sym53c8xx_setup);#endif#endif#ifdef	SYM_CONF_PQS_PDS_SUPPORT/* *  Detect all NCR PQS/PDS boards and keep track of their bus nr. * *  The NCR PQS or PDS card is constructed as a DEC bridge *  behind which sit a proprietary NCR memory controller and *  four or two 53c875s as separate devices.  In its usual mode *  of operation, the 875s are slaved to the memory controller *  for all transfers.  We can tell if an 875 is part of a *  PQS/PDS or not since if it is, it will be on the same bus *  as the memory controller.  To operate with the Linux *  driver, the memory controller is disabled and the 875s *  freed to function independently.  The only wrinkle is that *  the preset SCSI ID (which may be zero) must be read in from *  a special configuration space register of the 875 */#ifndef SYM_CONF_MAX_PQS_BUS#define SYM_CONF_MAX_PQS_BUS 16#endifstatic int pqs_bus[SYM_CONF_MAX_PQS_BUS] __initdata = { 0 };static void __init sym_detect_pqs_pds(void){	short index;	pcidev_t dev = PCIDEV_NULL;	for(index=0; index < SYM_CONF_MAX_PQS_BUS; index++) {		u_char tmp;		dev = pci_find_device(0x101a, 0x0009, dev);		if (dev == PCIDEV_NULL) {			pqs_bus[index] = -1;			break;		}		printf_info(NAME53C8XX ": NCR PQS/PDS memory controller detected on bus %d\n", PciBusNumber(dev));		pci_read_config_byte(dev, 0x44, &tmp);		/* bit 1: allow individual 875 configuration */		tmp |= 0x2;		pci_write_config_byte(dev, 0x44, tmp);		pci_read_config_byte(dev, 0x45, &tmp);		/* bit 2: drive individual 875 interrupts to the bus */		tmp |= 0x4;		pci_write_config_byte(dev, 0x45, tmp);		pqs_bus[index] = PciBusNumber(dev);	}}#endif /* SYM_CONF_PQS_PDS_SUPPORT *//* *  Read and check the PCI configuration for any detected NCR  *  boards and save data for attaching after all boards have  *  been detected. */static int __initsym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, sym_device *device){	u_short vendor_id, device_id, command, status_reg;	u_char cache_line_size;	u_char suggested_cache_line_size = 0;	u_char pci_fix_up = SYM_SETUP_PCI_FIX_UP;	u_char revision;	u_int irq;	u_long base, base_2, base_io; 	u_long base_c, base_2_c, io_port; 	int i;	sym_chip *chip;	/* Choose some short name for this device */	sprintf(device->s.inst_name, "sym.%d.%d.%d",		PciBusNumber(pdev),		(int) (PciDeviceFn(pdev) & 0xf8) >> 3,		(int) (PciDeviceFn(pdev) & 7));	/*	 *  Read needed minimal info from the PCI config space.	 */	vendor_id = PciVendorId(pdev);	device_id = PciDeviceId(pdev);	irq	  = PciIrqLine(pdev);	i = pci_get_base_address(pdev, 0, &base_io);	io_port = pci_get_base_cookie(pdev, 0);	base_c = pci_get_base_cookie(pdev, i);	i = pci_get_base_address(pdev, i, &base);	base_2_c = pci_get_base_cookie(pdev, i);	(void) pci_get_base_address(pdev, i, &base_2);	io_port &= PCI_BASE_ADDRESS_IO_MASK;	base	&= PCI_BASE_ADDRESS_MEM_MASK;	base_2	&= PCI_BASE_ADDRESS_MEM_MASK;	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);	/*	 *  If user excluded this chip, donnot initialize it.	 */	if (base_io) {		for (i = 0 ; i < 8 ; i++) {			if (sym_driver_setup.excludes[i] == base_io)				return -1;		}	}	/*	 *  Leave here if another driver attached the chip.	 */	if (io_port && check_region (io_port, 128)) {		printf_info("%s: IO region 0x%lx[0..127] is in use\n",		            sym_name(device), (long) io_port);		return -1;	}	/*	 *  Check if the chip is supported.	 */	chip = sym_lookup_pci_chip_table(device_id, revision);	if (!chip) {		printf_info("%s: device not supported\n", sym_name(device));		return -1;	}	/*	 *  Check if the chip has been assigned resources we need.	 */#ifdef SYM_CONF_IOMAPPED	if (!io_port) {		printf_info("%s: IO base address disabled.\n",		            sym_name(device));		return -1;	}#else	if (!base) {		printf_info("%s: MMIO base address disabled.\n",		            sym_name(device));		return -1;	}#endif	/*	 *  Ignore Symbios chips controlled by various RAID controllers.	 *  These controllers set value 0x52414944 at RAM end - 16.	 */#if defined(__i386__) && !defined(SYM_OPT_NO_BUS_MEMORY_MAPPING)	if (base_2_c) {		unsigned int ram_size, ram_val;		u_long ram_ptr;		if (chip->features & FE_RAM8K)			ram_size = 8192;		else			ram_size = 4096;		ram_ptr = pci_map_mem(base_2_c, ram_size);		if (ram_ptr) {			ram_val = readl_raw(ram_ptr + ram_size - 16);			pci_unmap_mem(ram_ptr, ram_size);			if (ram_val == 0x52414944) {				printf_info("%s: not initializing, "				            "driven by RAID controller.\n",				            sym_name(device));				return -1;			}		}	}#endif /* i386 and PCI MEMORY accessible */	/*	 *  Copy the chip description to our device structure, 	 *  so we can make it match the actual device and options.	 */	bcopy(chip, &device->chip, sizeof(device->chip));	device->chip.revision_id = revision;	/*	 *  Read additionnal info from the configuration space.	 */	pci_read_config_word(pdev, PCI_COMMAND,		&command);	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE,	&cache_line_size);	/*	 * Enable missing capabilities in the PCI COMMAND register.	 */#ifdef SYM_CONF_IOMAPPED#define	PCI_COMMAND_BITS_TO_ENABLE (PCI_COMMAND_IO | \	PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_PARITY)#else#define	PCI_COMMAND_BITS_TO_ENABLE \	(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_PARITY)#endif	if ((command & PCI_COMMAND_BITS_TO_ENABLE)		    != PCI_COMMAND_BITS_TO_ENABLE) {		printf_info("%s: setting%s%s%s%s...\n", sym_name(device),		(command & PCI_COMMAND_IO)     ? "" : " PCI_COMMAND_IO",		(command & PCI_COMMAND_MEMORY) ? "" : " PCI_COMMAND_MEMORY",		(command & PCI_COMMAND_MASTER) ? "" : " PCI_COMMAND_MASTER",		(command & PCI_COMMAND_PARITY) ? "" : " PCI_COMMAND_PARITY");		command |= PCI_COMMAND_BITS_TO_ENABLE;		pci_write_config_word(pdev, PCI_COMMAND, command);	}#undef	PCI_COMMAND_BITS_TO_ENABLE	/*	 *  If cache line size is not configured, suggest	 *  a value for well known CPUs.	 */#if defined(__i386__) && !defined(MODULE)	if (!cache_line_size && boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {		switch(boot_cpu_data.x86) {		case 4:	suggested_cache_line_size = 4;   break;		case 6: if (boot_cpu_data.x86_model > 8) break;		case 5:	suggested_cache_line_size = 8;   break;		}	}#endif	/* __i386__ */	/*	 *  Some features are required to be enabled in order to 	 *  work around some chip problems. :) ;)	 *  (ITEM 12 of a DEL about the 896 I haven't yet).	 *  We must ensure the chip will use WRITE AND INVALIDATE.	 *  The revision number limit is for now arbitrary.	 */	if (device_id == PCI_DEVICE_ID_NCR_53C896 && revision < 0x4) {		chip->features	|= (FE_WRIE | FE_CLSE);		pci_fix_up	|=  3;	/* Force appropriate PCI fix-up */	}#ifdef	SYM_CONF_PCI_FIX_UP	/*	 *  Try to fix up PCI config according to wished features.	 */	if ((pci_fix_up & 1) && (chip->features & FE_CLSE) && 	    !cache_line_size && suggested_cache_line_size) {		cache_line_size = suggested_cache_line_size;		pci_write_config_byte(pdev,				      PCI_CACHE_LINE_SIZE, cache_line_size);		printf_info("%s: PCI_CACHE_LINE_SIZE set to %d.\n",		            sym_name(device), cache_line_size);	}	if ((pci_fix_up & 2) && cache_line_size &&	    (chip->features & FE_WRIE) && !(command & PCI_COMMAND_INVALIDATE)) {		printf_info("%s: setting PCI_COMMAND_INVALIDATE.\n",		            sym_name(device));		command |= PCI_COMMAND_INVALIDATE;		pci_write_config_word(pdev, PCI_COMMAND, command);	}#endif	/* SYM_CONF_PCI_FIX_UP */	/*	 *  Work around for errant bit in 895A. The 66Mhz	 *  capable bit is set erroneously. Clear this bit.	 *  (Item 1 DEL 533)	 *	 *  Make sure Config space and Features agree.	 *	 *  Recall: writes are not normal to status register -	 *  write a 1 to clear and a 0 to leave unchanged.	 *  Can only reset bits.	 */	pci_read_config_word(pdev, PCI_STATUS, &status_reg);	if (chip->features & FE_66MHZ) {		if (!(status_reg & PCI_STATUS_66MHZ))			chip->features &= ~FE_66MHZ;	}	else {		if (status_reg & PCI_STATUS_66MHZ) {			status_reg = PCI_STATUS_66MHZ;			pci_write_config_word(pdev, PCI_STATUS, status_reg);			pci_read_config_word(pdev, PCI_STATUS, &status_reg);		}	} 	/*	 *  Initialise device structure with items required by sym_attach.	 */	device->pdev		= pdev;	device->s.bus		= PciBusNumber(pdev);	device->s.device_fn	= PciDeviceFn(pdev);	device->s.base		= base;	device->s.base_2	= base_2;	device->s.base_c	= base_c;	device->s.base_2_c	= base_2_c;	device->s.io_port	= io_port;	

⌨️ 快捷键说明

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