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

📄 nsp_cs.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	nsp_dbg(NSP_DEBUG_INIT, "in");	tuple.DesiredTuple    = CISTPL_CONFIG;	tuple.Attributes      = 0;	tuple.TupleData	      = tuple_data;	tuple.TupleDataMax    = sizeof(tuple_data);	tuple.TupleOffset     = 0;	CS_CHECK(GetFirstTuple, handle, &tuple);	CS_CHECK(GetTupleData,	handle, &tuple);	CS_CHECK(ParseTuple,	handle, &tuple, &parse);	link->conf.ConfigBase = parse.config.base;	link->conf.Present    = parse.config.rmask[0];	/* Configure card */	link->state	      |= DEV_CONFIG;	/* Look up the current Vcc */	CS_CHECK(GetConfigurationInfo, handle, &conf);	link->conf.Vcc = conf.Vcc;	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;	CS_CHECK(GetFirstTuple, handle, &tuple);	while (1) {		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);		CFG_CHECK(GetTupleData, handle, &tuple);		CFG_CHECK(ParseTuple,	handle, &tuple, &parse);		if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }		if (cfg->index == 0) { goto next_entry; }		link->conf.ConfigIndex = cfg->index;		/* Does this card need audio output? */		if (cfg->flags & CISTPL_CFTABLE_AUDIO) {			link->conf.Attributes |= CONF_ENABLE_SPKR;			link->conf.Status = CCSR_AUDIO_ENA;		}		/* Use power settings for Vcc and Vpp if present */		/*  Note that the CIS values need to be rescaled */		if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {			if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {				goto next_entry;			}		} else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {			if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {				goto next_entry;			}		}		if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {			link->conf.Vpp1 = link->conf.Vpp2 =				cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;		} else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {			link->conf.Vpp1 = link->conf.Vpp2 =				dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;		}		/* Do we need to allocate an interrupt? */		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {			link->conf.Attributes |= CONF_ENABLE_IRQ;		}		/* IO window settings */		link->io.NumPorts1 = link->io.NumPorts2 = 0;		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;			if (!(io->flags & CISTPL_IO_8BIT))				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;			if (!(io->flags & CISTPL_IO_16BIT))				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;			link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;			link->io.BasePort1 = io->win[0].base;			link->io.NumPorts1 = io->win[0].len;			if (io->nwin > 1) {				link->io.Attributes2 = link->io.Attributes1;				link->io.BasePort2 = io->win[1].base;				link->io.NumPorts2 = io->win[1].len;			}			/* This reserves IO space but doesn't actually enable it */			CFG_CHECK(RequestIO, link->handle, &link->io);		}		if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {			cistpl_mem_t *mem =				(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;			req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;			req.Attributes |= WIN_ENABLE;			req.Base = mem->win[0].host_addr;			req.Size = mem->win[0].len;			if (req.Size < 0x1000) {				req.Size = 0x1000;			}			req.AccessSpeed = 0;			link->win = (window_handle_t)link->handle;			CFG_CHECK(RequestWindow, &link->win, &req);			map.Page = 0; map.CardOffset = mem->win[0].card_addr;			CFG_CHECK(MapMemPage, link->win, &map);			data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);			data->MmioLength  = req.Size;		}		/* If we got this far, we're cool! */		break;	next_entry:		nsp_dbg(NSP_DEBUG_INIT, "next");		if (link->io.NumPorts1) {			CardServices(ReleaseIO, link->handle, &link->io);		}		CS_CHECK(GetNextTuple, handle, &tuple);	}	if (link->conf.Attributes & CONF_ENABLE_IRQ) {		CS_CHECK(RequestIRQ, link->handle, &link->irq);	}	CS_CHECK(RequestConfiguration, handle, &link->conf);	if (free_ports) {		if (link->io.BasePort1) {			release_region(link->io.BasePort1, link->io.NumPorts1);		}		if (link->io.BasePort2) {			release_region(link->io.BasePort2, link->io.NumPorts2);		}	}	/* Set port and IRQ */	data->BaseAddress = link->io.BasePort1;	data->NumAddress  = link->io.NumPorts1;	data->IrqNumber   = link->irq.AssignedIRQ;	nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",		data->BaseAddress, data->NumAddress, data->IrqNumber);	if(nsphw_init(data) == FALSE) {		goto cs_failed;	}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))	host = nsp_detect(&nsp_driver_template);#else	scsi_register_host(&nsp_driver_template);	for (host = scsi_host_get_next(NULL); host != NULL;	     host = scsi_host_get_next(host)) {		if (host->hostt == &nsp_driver_template) {			break;		}	}#endif	if (host == NULL) {		nsp_dbg(NSP_DEBUG_INIT, "detect failed");		goto cs_failed;	}#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))	scsi_add_host (host, NULL);	scsi_scan_host(host);	snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);	link->dev  = &info->node;	info->host = host;#else	nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO");	tail = &link->dev;	info->ndev = 0;	nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);	for (dev = host->host_queue; dev != NULL; dev = dev->next) {		unsigned long arg[2], id;		kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);		id = (arg[0] & 0x0f) + ((arg[0] >> 4) & 0xf0) +			((arg[0] >> 8) & 0xf00) + ((arg[0] >> 12) & 0xf000);		node = &info->node[info->ndev];		node->minor = 0;		switch (dev->type) {		case TYPE_TAPE:			node->major = SCSI_TAPE_MAJOR;			snprintf(node->dev_name, sizeof(node->dev_name), "st#%04lx", id);			break;		case TYPE_DISK:		case TYPE_MOD:			node->major = SCSI_DISK0_MAJOR;			snprintf(node->dev_name, sizeof(node->dev_name), "sd#%04lx", id);			break;		case TYPE_ROM:		case TYPE_WORM:			node->major = SCSI_CDROM_MAJOR;			snprintf(node->dev_name, sizeof(node->dev_name), "sr#%04lx", id);			break;		default:			node->major = SCSI_GENERIC_MAJOR;			snprintf(node->dev_name, sizeof(node->dev_name), "sg#%04lx", id);			break;		}		*tail = node; tail = &node->next;		info->ndev++;		info->host = dev->host;	}	*tail = NULL;	if (info->ndev == 0) {		nsp_msg(KERN_INFO, "no SCSI devices found");	}	nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);#endif	/* Finally, report what we've done */	printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d",	       link->conf.ConfigIndex,	       link->conf.Vcc/10, link->conf.Vcc%10);	if (link->conf.Vpp1) {		printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);	}	if (link->conf.Attributes & CONF_ENABLE_IRQ) {		printk(", irq %d", link->irq.AssignedIRQ);	}	if (link->io.NumPorts1) {		printk(", io 0x%04x-0x%04x", link->io.BasePort1,		       link->io.BasePort1+link->io.NumPorts1-1);	}	if (link->io.NumPorts2)		printk(" & 0x%04x-0x%04x", link->io.BasePort2,		       link->io.BasePort2+link->io.NumPorts2-1);	if (link->win)		printk(", mem 0x%06lx-0x%06lx", req.Base,		       req.Base+req.Size-1);	printk("\n");	link->state &= ~DEV_CONFIG_PENDING;	return; cs_failed:	nsp_dbg(NSP_DEBUG_INIT, "config fail");	cs_error(link->handle, last_fn, last_ret);	nsp_cs_release(link);	return;} /* nsp_cs_config */#undef CS_CHECK#undef CFG_CHECK/*======================================================================    After a card is removed, nsp_cs_release() will unregister the net    device, and release the PCMCIA configuration.  If the device is    still open, this will be postponed until it is closed.======================================================================*/static void nsp_cs_release(dev_link_t *link){	scsi_info_t *info = link->priv;	nsp_hw_data *data = NULL;	if (info->host == NULL) {		nsp_msg(KERN_DEBUG, "unexpected card release call.");	} else {		data = (nsp_hw_data *)info->host->hostdata;	}	nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);	/* Unlink the device chain */#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))	if (info->host != NULL) {		scsi_remove_host(info->host);	}#else	scsi_unregister_host(&nsp_driver_template);#endif	link->dev = NULL;	if (link->win) {		if (data != NULL) {			iounmap((void *)(data->MmioAddress));		}		CardServices(ReleaseWindow, link->win);	}	CardServices(ReleaseConfiguration,  link->handle);	if (link->io.NumPorts1) {		CardServices(ReleaseIO,     link->handle, &link->io);	}	if (link->irq.AssignedIRQ) {		CardServices(ReleaseIRQ,    link->handle, &link->irq);	}	link->state &= ~DEV_CONFIG;#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))	if (info->host != NULL) {		scsi_host_put(info->host);	}#endif} /* nsp_cs_release *//*======================================================================    The card status event handler.  Mostly, this schedules other    stuff to run after an event is received.  A CARD_REMOVAL event    also sets some flags to discourage the net drivers from trying    to talk to the card any more.    When a CARD_REMOVAL event is received, we immediately set a flag    to block future accesses to this device.  All the functions that    actually access the device should check this flag to make sure    the card is still present.======================================================================*/static int nsp_cs_event(event_t		       event,			int		       priority,			event_callback_args_t *args){	dev_link_t  *link = args->client_data;	scsi_info_t *info = link->priv;	nsp_hw_data *data;	nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);	switch (event) {	case CS_EVENT_CARD_REMOVAL:		nsp_dbg(NSP_DEBUG_INIT, "event: remove");		link->state &= ~DEV_PRESENT;		if (link->state & DEV_CONFIG) {			((scsi_info_t *)link->priv)->stop = 1;			nsp_cs_release(link);		}		break;	case CS_EVENT_CARD_INSERTION:		nsp_dbg(NSP_DEBUG_INIT, "event: insert");		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))		info->bus    =  args->bus;#endif		nsp_cs_config(link);		break;	case CS_EVENT_PM_SUSPEND:		nsp_dbg(NSP_DEBUG_INIT, "event: suspend");		link->state |= DEV_SUSPEND;		/* Fall through... */	case CS_EVENT_RESET_PHYSICAL:		/* Mark the device as stopped, to block IO until later */		nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");		if (info->host != NULL) {			nsp_msg(KERN_INFO, "clear SDTR status");			data = (nsp_hw_data *)info->host->hostdata;			nsphw_init_sync(data);		}		info->stop = 1;		if (link->state & DEV_CONFIG) {			CardServices(ReleaseConfiguration, link->handle);		}		break;	case CS_EVENT_PM_RESUME:		nsp_dbg(NSP_DEBUG_INIT, "event: resume");		link->state &= ~DEV_SUSPEND;		/* Fall through... */	case CS_EVENT_CARD_RESET:		nsp_dbg(NSP_DEBUG_INIT, "event: reset");		if (link->state & DEV_CONFIG) {			CardServices(RequestConfiguration, link->handle, &link->conf);		}		info->stop = 0;		if (info->host != NULL) {			nsp_msg(KERN_INFO, "reset host and bus");			data = (nsp_hw_data *)info->host->hostdata;			nsphw_init   (data);			nsp_bus_reset(data);		}		break;	default:		nsp_dbg(NSP_DEBUG_INIT, "event: unknown");		break;	}	nsp_dbg(NSP_DEBUG_INIT, "end");	return 0;} /* nsp_cs_event *//*======================================================================* *	module entry point *====================================================================*/#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))static struct pcmcia_driver nsp_driver = {	.owner          = THIS_MODULE,	.drv            = {		.name   = "nsp_cs",	},	.attach         = nsp_cs_attach,	.detach         = nsp_cs_detach,};#endifstatic int __init nsp_cs_init(void){#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))	nsp_msg(KERN_INFO, "loading...");	return pcmcia_register_driver(&nsp_driver);#else	servinfo_t serv;	nsp_msg(KERN_INFO, "loading...");	CardServices(GetCardServicesInfo, &serv);	if (serv.Revision != CS_RELEASE_CODE) {		nsp_msg(KERN_DEBUG, "Card Services release does not match!");		return -EINVAL;	}	register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);	nsp_dbg(NSP_DEBUG_INIT, "out");	return 0;#endif}static void __exit nsp_cs_exit(void){	nsp_msg(KERN_INFO, "unloading...");#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))	pcmcia_unregister_driver(&nsp_driver);#else	unregister_pcmcia_driver(&dev_info);#endif	/* XXX: this really needs to move into generic code.. */	while (dev_list != NULL) {		if (dev_list->state & DEV_CONFIG) {			nsp_cs_release(dev_list);		}		nsp_cs_detach(dev_list);	}}module_init(nsp_cs_init)module_exit(nsp_cs_exit)/* end */

⌨️ 快捷键说明

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