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

📄 sym_glue.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	switch(uc->cmd) {	case UC_SETSYNC:	case UC_SETTAGS:	case UC_SETWIDE:	case UC_SETFLAG:	case UC_RESETDEV:	case UC_CLEARDEV:		SKIP_SPACES(1);		if ((arg_len = is_keyword(ptr, len, "all")) != 0) {			ptr += arg_len; len -= arg_len;			uc->target = ~0;		} else {			GET_INT_ARG(target);			uc->target = (1<<target);#ifdef DEBUG_PROC_INFOprintk("sym_user_command: target=%ld\n", target);#endif		}		break;	}	switch(uc->cmd) {	case UC_SETVERBOSE:	case UC_SETSYNC:	case UC_SETTAGS:	case UC_SETWIDE:		SKIP_SPACES(1);		GET_INT_ARG(uc->data);#ifdef DEBUG_PROC_INFOprintk("sym_user_command: data=%ld\n", uc->data);#endif		break;#ifdef SYM_LINUX_DEBUG_CONTROL_SUPPORT	case UC_SETDEBUG:		while (len > 0) {			SKIP_SPACES(1);			if	((arg_len = is_keyword(ptr, len, "alloc")))				uc->data |= DEBUG_ALLOC;			else if	((arg_len = is_keyword(ptr, len, "phase")))				uc->data |= DEBUG_PHASE;			else if	((arg_len = is_keyword(ptr, len, "queue")))				uc->data |= DEBUG_QUEUE;			else if	((arg_len = is_keyword(ptr, len, "result")))				uc->data |= DEBUG_RESULT;			else if	((arg_len = is_keyword(ptr, len, "scatter")))				uc->data |= DEBUG_SCATTER;			else if	((arg_len = is_keyword(ptr, len, "script")))				uc->data |= DEBUG_SCRIPT;			else if	((arg_len = is_keyword(ptr, len, "tiny")))				uc->data |= DEBUG_TINY;			else if	((arg_len = is_keyword(ptr, len, "timing")))				uc->data |= DEBUG_TIMING;			else if	((arg_len = is_keyword(ptr, len, "nego")))				uc->data |= DEBUG_NEGO;			else if	((arg_len = is_keyword(ptr, len, "tags")))				uc->data |= DEBUG_TAGS;			else if	((arg_len = is_keyword(ptr, len, "pointer")))				uc->data |= DEBUG_POINTER;			else				return -EINVAL;			ptr += arg_len; len -= arg_len;		}#ifdef DEBUG_PROC_INFOprintk("sym_user_command: data=%ld\n", uc->data);#endif		break;#endif /* SYM_LINUX_DEBUG_CONTROL_SUPPORT */	case UC_SETFLAG:		while (len > 0) {			SKIP_SPACES(1);			if	((arg_len = is_keyword(ptr, len, "no_disc")))				uc->data &= ~SYM_DISC_ENABLED;			else				return -EINVAL;			ptr += arg_len; len -= arg_len;		}		break;	default:		break;	}	if (len)		return -EINVAL;	else {		long flags;		SYM_LOCK_HCB(np, flags);		sym_exec_user_command (np, uc);		SYM_UNLOCK_HCB(np, flags);	}	return length;}#endif	/* SYM_LINUX_USER_COMMAND_SUPPORT */#ifdef SYM_LINUX_USER_INFO_SUPPORT/* *  Informations through the proc file system. */struct info_str {	char *buffer;	int length;	int offset;	int pos;};static void copy_mem_info(struct info_str *info, char *data, int len){	if (info->pos + len > info->length)		len = info->length - info->pos;	if (info->pos + len < info->offset) {		info->pos += len;		return;	}	if (info->pos < info->offset) {		data += (info->offset - info->pos);		len  -= (info->offset - info->pos);	}	if (len > 0) {		memcpy(info->buffer + info->pos, data, len);		info->pos += len;	}}static int copy_info(struct info_str *info, char *fmt, ...){	va_list args;	char buf[81];	int len;	va_start(args, fmt);	len = vsprintf(buf, fmt, args);	va_end(args);	copy_mem_info(info, buf, len);	return len;}/* *  Copy formatted information into the input buffer. */static int sym_host_info(hcb_p np, char *ptr, off_t offset, int len){	struct info_str info;	info.buffer	= ptr;	info.length	= len;	info.offset	= offset;	info.pos	= 0;	copy_info(&info, "Chip " NAME53C "%s, device id 0x%x, "			 "revision id 0x%x\n",			 np->s.chip_name, np->device_id, np->revision_id);	copy_info(&info, "On PCI bus %d, device %d, function %d, "#ifdef __sparc__		"IRQ %s\n",#else		"IRQ %d\n",#endif		np->s.bus, (np->s.device_fn & 0xf8) >> 3, np->s.device_fn & 7,#ifdef __sparc__		__irq_itoa(np->s.irq));#else		(int) np->s.irq);#endif	copy_info(&info, "Min. period factor %d, %s SCSI BUS%s\n",			 (int) (np->minsync_dt ? np->minsync_dt : np->minsync),			 np->maxwide ? "Wide" : "Narrow",			 np->minsync_dt ? ", DT capable" : "");	copy_info(&info, "Max. started commands %d, "			 "max. commands per LUN %d\n",			 SYM_CONF_MAX_START, SYM_CONF_MAX_TAG);	return info.pos > info.offset? info.pos - info.offset : 0;}#endif /* SYM_LINUX_USER_INFO_SUPPORT *//* *  Entry point of the scsi proc fs of the driver. *  - func = 0 means read  (returns adapter infos) *  - func = 1 means write (not yet merget from sym53c8xx) */static int sym53c8xx_proc_info(char *buffer, char **start, off_t offset,			int length, int hostno, int func){	struct Scsi_Host *host;	struct host_data *host_data;	hcb_p np = 0;	int retv;	for (host = first_host; host; host = host->next) {		if (host->hostt != first_host->hostt)			continue;		if (host->host_no == hostno) {			host_data = (struct host_data *) host->hostdata;			np = host_data->ncb;			break;		}	}	if (!np)		return -EINVAL;	if (func) {#ifdef	SYM_LINUX_USER_COMMAND_SUPPORT		retv = sym_user_command(np, buffer, length);#else		retv = -EINVAL;#endif	}	else {		if (start)			*start = buffer;#ifdef SYM_LINUX_USER_INFO_SUPPORT		retv = sym_host_info(np, buffer, offset, length);#else		retv = -EINVAL;#endif	}	return retv;}#endif /* SYM_LINUX_PROC_INFO_SUPPORT *//* *	Free controller resources. */static void sym_free_resources(hcb_p np){	/*	 *  Free O/S specific resources.	 */	if (np->s.irq)		free_irq(np->s.irq, np);	if (np->s.io_port)		release_region(np->s.io_port, np->s.io_ws);#ifndef SYM_OPT_NO_BUS_MEMORY_MAPPING	if (np->s.mmio_va)		pci_unmap_mem(np->s.mmio_va, np->s.io_ws);	if (np->s.ram_va)		pci_unmap_mem(np->s.ram_va, np->ram_ws);#endif	/*	 *  Free O/S independant resources.	 */	sym_hcb_free(np);	sym_mfree_dma(np, sizeof(*np), "HCB");}/* *  Ask/tell the system about DMA addressing. */#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPINGstatic int sym_setup_bus_dma_mask(hcb_p np){#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,3)	if (!pci_dma_supported(np->s.device, 0xffffffffUL))		goto out_err32;#else#if   SYM_CONF_DMA_ADDRESSING_MODE == 0	if (pci_set_dma_mask(np->s.device, 0xffffffffUL))		goto out_err32;#else#if   SYM_CONF_DMA_ADDRESSING_MODE == 1#define	PciDmaMask	0xffffffffff#elif SYM_CONF_DMA_ADDRESSING_MODE == 2#define	PciDmaMask	0xffffffffffffffff#endif	if (np->features & FE_DAC) {		if (!pci_set_dma_mask(np->s.device, PciDmaMask)) {			np->use_dac = 1;			printf_info("%s: using 64 bit DMA addressing\n",					sym_name(np));		}		else {			if (!pci_set_dma_mask(np->s.device, 0xffffffffUL))				goto out_err32;		}	}#undef	PciDmaMask#endif#endif	return 0;out_err32:	printf_warning("%s: 32 BIT DMA ADDRESSING NOT SUPPORTED\n",			sym_name(np));	return -1;}#endif /* SYM_LINUX_DYNAMIC_DMA_MAPPING *//* *  Host attach and initialisations. * *  Allocate host data and ncb structure. *  Request IO region and remap MMIO region. *  Do chip initialization. *  If all is OK, install interrupt handling and *  start the timer daemon. */static int __init sym_attach (Scsi_Host_Template *tpnt, int unit, sym_device *dev){        struct host_data *host_data;	hcb_p np = 0;        struct Scsi_Host *instance = 0;	u_long flags = 0;	sym_nvram *nvram = dev->nvram;	struct sym_fw *fw;	printk(KERN_INFO		"sym%d: <%s> rev 0x%x on pci bus %d device %d function %d "#ifdef __sparc__		"irq %s\n",#else		"irq %d\n",#endif		unit, dev->chip.name, dev->chip.revision_id,		dev->s.bus, (dev->s.device_fn & 0xf8) >> 3,		dev->s.device_fn & 7,#ifdef __sparc__		__irq_itoa(dev->s.irq));#else		dev->s.irq);#endif	/*	 *  Get the firmware for this chip.	 */	fw = sym_find_firmware(&dev->chip);	if (!fw)		goto attach_failed;	/*	 *	Allocate host_data structure	 */        if (!(instance = scsi_register(tpnt, sizeof(*host_data))))	        goto attach_failed;	host_data = (struct host_data *) instance->hostdata;	/*	 *  Allocate immediately the host control block, 	 *  since we are only expecting to succeed. :)	 *  We keep track in the HCB of all the resources that 	 *  are to be released on error.	 */#ifdef	SYM_LINUX_DYNAMIC_DMA_MAPPING	np = __sym_calloc_dma(dev->pdev, sizeof(*np), "HCB");	if (np) {		np->s.device = dev->pdev;		np->bus_dmat = dev->pdev; /* Result in 1 DMA pool per HBA */	}	else		goto attach_failed;#else	np = sym_calloc_dma(sizeof(*np), "HCB");	if (!np)		goto attach_failed;#endif	host_data->ncb = np;	SYM_INIT_LOCK_HCB(np);	/*	 *  Copy some useful infos to the HCB.	 */	np->hcb_ba	= vtobus(np);	np->verbose	= sym_driver_setup.verbose;	np->s.device	= dev->pdev;	np->s.unit	= unit;	np->device_id	= dev->chip.device_id;	np->revision_id	= dev->chip.revision_id;	np->s.bus	= dev->s.bus;	np->s.device_fn	= dev->s.device_fn;	np->features	= dev->chip.features;	np->clock_divn	= dev->chip.nr_divisor;	np->maxoffs	= dev->chip.offset_max;	np->maxburst	= dev->chip.burst_max;	np->myaddr	= dev->host_id;	/*	 *  Edit its name.	 */	strncpy(np->s.chip_name, dev->chip.name, sizeof(np->s.chip_name)-1);	sprintf(np->s.inst_name, "sym%d", np->s.unit);	/*	 *  Ask/tell the system about DMA addressing.	 */#ifdef SYM_LINUX_DYNAMIC_DMA_MAPPING	if (sym_setup_bus_dma_mask(np))		goto attach_failed;#endif	/*	 *  Try to map the controller chip to	 *  virtual and physical memory.	 */	np->mmio_ba	= (u32)dev->s.base;	np->s.io_ws	= (np->features & FE_IO256)? 256 : 128;#ifndef SYM_CONF_IOMAPPED	np->s.mmio_va = pci_map_mem(dev->s.base_c, np->s.io_ws);	if (!np->s.mmio_va) {		printf_err("%s: can't map PCI MMIO region\n", sym_name(np));		goto attach_failed;	}	else if (sym_verbose > 1)		printf_info("%s: using memory mapped IO\n", sym_name(np));#endif /* !defined SYM_CONF_IOMAPPED */	/*	 *  Try to map the controller chip into iospace.	 */	if (dev->s.io_port) {		request_region(dev->s.io_port, np->s.io_ws, NAME53C8XX);		np->s.io_port = dev->s.io_port;	}	/*	 *  Map on-chip RAM if present and supported.	 */	if (!(np->features & FE_RAM))		dev->s.base_2 = 0;	if (dev->s.base_2) {		np->ram_ba = (u32)dev->s.base_2;		if (np->features & FE_RAM8K)			np->ram_ws = 8192;		else			np->ram_ws = 4096;#ifndef SYM_OPT_NO_BUS_MEMORY_MAPPING		np->s.ram_va = pci_map_mem(dev->s.base_2_c, np->ram_ws);		if (!np->s.ram_va) {			printf_err("%s: can't map PCI MEMORY region\n",			       sym_name(np));			goto attach_failed;		}#endif	}	/*	 *  Perform O/S independant stuff.	 */	if (sym_hcb_attach(np, fw, nvram))		goto attach_failed;	/*	 *  Install the interrupt handler.	 *  If we synchonize the C code with SCRIPTS on interrupt, 	 *  we donnot want to share the INTR line at all.	 */	if (request_irq(dev->s.irq, sym53c8xx_intr, SA_SHIRQ,			NAME53C8XX, np)) {		printf_err("%s: request irq %d failure\n",			sym_name(np), dev->s.irq);		goto attach_failed;	}	np->s.irq = dev->s.irq;	/*	 *  After SCSI devices have been opened, we cannot	 *  reset the bus safely, so we do it here.	 */	SYM_LOCK_HCB(np, flags);	if (sym_reset_scsi_bus(np, 0)) {		printf_err("%s: FATAL ERROR: CHECK SCSI BUS - CABLES, "		           "TERMINATION, DEVICE POWER etc.!\n", sym_name(np));		SYM_UNLOCK_HCB(np, flags);		goto attach_failed;	}	/*	 *  Initialize some queue headers.	 */	sym_que_init(&np->s.wait_cmdq);	sym_que_init(&np->s.busy_cmdq);	/*	 *  Start the SCRIPTS.	 */	sym_start_up (np, 1);	/*	 *  Start the timer daemon	 */	init_timer(&np->s.timer);	np->s.timer.data     = (unsigned long) np;	np->s.timer.function = sym53c8xx_timer;	np->s.lasttime=0;	sym_timer (np);	/*	 *  Done.	 */        if (!first_host)        	first_host = instance;	/*	 *  Fill Linux host instance structure	 *  and return success.	 */	instance->max_channel	= 0;	instance->this_id	= np->myaddr;	instance->max_id	= np->maxwide ? 16 : 8;	instance->max_lun	= SYM_CONF_MAX_LUN;#ifndef SYM_CONF_IOMAPPED#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,29)	instance->base		= (unsigned long) np->s.mmio_va;#else	instance->base		= (char *) np->s.mmio_va;#endif#endif	instance->irq		= np->s.irq;	instance->unique_id	= np->s.io_port;	instance->io_port	= np->s.io_port;	instance->n_io_port	= np->s.io_ws;	instance->dma_channel	= 0;	instance->cmd_per_lun	= SYM_CONF_MAX_TAG;	instance->can_queue	= (SYM_CONF_MAX_START-2);	instance->sg_tablesize	= SYM_CONF_MAX_SG;#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)	instance->max_cmd_len	= 16;#endif	instance->select_queue_depths = sym53c8xx_select_queue_depths;	SYM_UNLOCK_HCB(np, flags);	scsi_set_pci_device(instance, dev->pdev);	/*

⌨️ 快捷键说明

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