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

📄 prism2_cs.c

📁 这是基于hfa3841、hfa3842的无线网卡linux驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				link->io.BasePort1 );				link->io.BasePort1 = 0;			}			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, pcmcia_request_io(link->handle, &link->io));		/* If we got this far, we're cool! */		break;next_entry:		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)			dflt = *cfg;		CS_CHECK(GetNextTuple,                         pcmcia_get_next_tuple(handle, &tuple));	}	/* Allocate an interrupt line.  Note that this does not assign a */	/* handler to the interrupt, unless the 'Handler' member of the */	/* irq structure is initialized. */	if (link->conf.Attributes & CONF_ENABLE_IRQ)	{		link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;		link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;		if (irq_list[0] == -1)			link->irq.IRQInfo2 = irq_mask;		else			for (i=0; i<4; i++)				link->irq.IRQInfo2 |= 1 << irq_list[i];		link->irq.Handler = hfa384x_interrupt;		link->irq.Instance = wlandev;		CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));	}	/* This actually configures the PCMCIA socket -- setting up */	/* the I/O windows and the interrupt mapping, and putting the */	/* card and host interface into "Memory and IO" mode. */	CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));	/* Fill the netdevice with this info */	wlandev->netdev->irq = link->irq.AssignedIRQ;	wlandev->netdev->base_addr = link->io.BasePort1;	/* Report what we've done */	WLAN_LOG_INFO("%s: index 0x%02x: Vcc %d.%d", 		dev_info, 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);	printk("\n");	link->state &= ~DEV_CONFIG_PENDING;	/* Let pcmcia know the device name */	link->dev = &hw->node;	/* Register the network device and get assigned a name */	SET_MODULE_OWNER(wlandev->netdev);	if (register_wlandev(wlandev) != 0) {		WLAN_LOG_NOTICE("prism2sta_cs: register_wlandev() failed.\n");		goto failed;	}	strcpy(hw->node.dev_name, wlandev->name);	/* Any device custom config/query stuff should be done here */	/* For a netdevice, we should at least grab the mac address */	return;cs_failed:	cs_error(link->handle, last_fn, last_ret);	WLAN_LOG_ERROR("NextTuple failure? It's probably a Vcc mismatch.\n");failed:	prism2sta_release((UINT32)link);	return;}/*----------------------------------------------------------------* prism2sta_release** Half of the config/release pair.  Usually called in response to * a card ejection event.  Checks to make sure no higher layers* are still (or think they are) using the card via the link->open* field.  ** NOTE: Don't forget to increment the link->open variable in the *  device_open method, and decrement it in the device_close *  method.** Arguments:*	arg	a generic 32 bit variable.  It's the value that*		we assigned to link->release.data in sta_attach().** Returns: *	nothing** Side effects:*	All resources should be released after this function*	executes and finds the device !open.** Call context:*	Possibly in a timer context.  Don't do anything that'll*	block.----------------------------------------------------------------*/void prism2sta_release(UINT32 arg){        dev_link_t	*link = (dev_link_t *)arg;	DBFENTER;	/* First thing we should do is get the MSD back to the	 * HWPRESENT state.  I.e. everything quiescent.	 */	prism2sta_ifstate(link->priv, P80211ENUM_ifstate_disable);        if (link->open) {		/* TODO: I don't think we're even using this bit of code		 * and I don't think it's hurting us at the moment.		 */                WLAN_LOG_DEBUG(1, 			"prism2sta_cs: release postponed, '%s' still open\n",			link->dev->dev_name);                link->state |= DEV_STALE_CONFIG;                return;        }        pcmcia_release_configuration(link->handle);        pcmcia_release_io(link->handle, &link->io);        pcmcia_release_irq(link->handle, &link->irq);        link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);	DBFEXIT;}/*----------------------------------------------------------------* prism2sta_event** Handler for card services events.** Arguments:*	event		The event code*	priority	hi/low - REMOVAL is the only hi*	args		ptr to card services struct containing info about*			pcmcia status** Returns: *	Zero on success, non-zero otherwise** Side effects:*	** Call context:*	Both interrupt and process thread, depends on the event.----------------------------------------------------------------*/static int prism2sta_event (	event_t event, 	int priority, 	event_callback_args_t *args){	int			result = 0;	dev_link_t		*link = (dev_link_t *) args->client_data;	wlandevice_t		*wlandev = (wlandevice_t*)link->priv;	hfa384x_t		*hw = NULL;	DBFENTER;	if (wlandev) hw = wlandev->priv;	switch (event)	{	case CS_EVENT_CARD_INSERTION:		WLAN_LOG_DEBUG(5,"event is INSERTION\n");		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;		prism2sta_config(link);		if (!(link->state & DEV_CONFIG)) {			wlandev->netdev->irq = 0;			WLAN_LOG_ERROR(				"%s: Initialization failed!\n", dev_info);			wlandev->msdstate = WLAN_MSD_HWFAIL;			break;		}		/* Fill in the rest of the hw struct */		hw->irq = wlandev->netdev->irq;		hw->iobase = wlandev->netdev->base_addr;		hw->membase = (UINT8*) link;		if (prism2_doreset) {			result = hfa384x_corereset(hw, 					prism2_reset_holdtime, 					prism2_reset_settletime, 0);			if ( result ) {				WLAN_LOG_ERROR(					"corereset() failed, result=%d.\n", 					result);				wlandev->msdstate = WLAN_MSD_HWFAIL;				break;			}		}#if 0		/*		 * TODO: test_hostif() not implemented yet.		 */		result = hfa384x_test_hostif(hw);		if (result) {			WLAN_LOG_ERROR(			"test_hostif() failed, result=%d.\n", result);			wlandev->msdstate = WLAN_MSD_HWFAIL;			break;		}#endif		wlandev->msdstate = WLAN_MSD_HWPRESENT;		break;	case CS_EVENT_CARD_REMOVAL:		WLAN_LOG_DEBUG(5,"event is REMOVAL\n");		link->state &= ~DEV_PRESENT;		if (wlandev) {			p80211netdev_hwremoved(wlandev);		}#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))		if (link->state & DEV_CONFIG)		{			link->release.expires = jiffies + (HZ/20);			add_timer(&link->release);		}#endif		break;	case CS_EVENT_RESET_REQUEST:		WLAN_LOG_DEBUG(5,"event is RESET_REQUEST\n");		WLAN_LOG_NOTICE(			"prism2 card reset not supported "			"due to post-reset user mode configuration "			"requirements.\n");		WLAN_LOG_NOTICE(			"  From user mode, use "			"'cardctl suspend;cardctl resume' "			"instead.\n");		break;	case CS_EVENT_RESET_PHYSICAL:	case CS_EVENT_CARD_RESET:		WLAN_LOG_WARNING("Rx'd CS_EVENT_RESET_xxx, should not "			"be possible since RESET_REQUEST was denied.\n");		break;	case CS_EVENT_PM_SUSPEND:		WLAN_LOG_DEBUG(5,"event is SUSPEND\n");		link->state |= DEV_SUSPEND;		if (link->state & DEV_CONFIG)		{			prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);			pcmcia_release_configuration(link->handle);		}		break;	case CS_EVENT_PM_RESUME:		WLAN_LOG_DEBUG(5,"event is RESUME\n");		link->state &= ~DEV_SUSPEND;		if (link->state & DEV_CONFIG) {			pcmcia_request_configuration(link->handle, &link->conf);		}		break;	}	DBFEXIT;	return 0;  /* noone else does anthing with the return value */}#ifdef MODULEstatic int __init prism2cs_init(void){#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))	servinfo_t	serv;#endif	DBFENTER;        WLAN_LOG_NOTICE("%s Loaded\n", version);        WLAN_LOG_NOTICE("dev_info is: %s\n", dev_info);#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))	pcmcia_get_card_services_info(&serv);	if ( serv.Revision != CS_RELEASE_CODE )	{		printk(KERN_NOTICE"%s: CardServices release does not match!\n", dev_info);		return -1;	}	/* This call will result in a call to prism2sta_attach */	/*   and eventually prism2sta_detach */	register_pccard_driver( &dev_info, &prism2sta_attach, &prism2sta_detach);#else	pcmcia_register_driver(&prism2_cs_driver);#endif	DBFEXIT;	return 0;}static void __exit prism2cs_cleanup(void){#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))        dev_link_t *link = dev_list;        dev_link_t *nlink;        DBFENTER;	for (link=dev_list; link != NULL; link = nlink) {		nlink = link->next;		if ( link->state & DEV_CONFIG ) {			prism2sta_release((u_long)link);		}		prism2sta_detach(link); /* remember detach() frees link */	}	unregister_pccard_driver( &dev_info);#else	pcmcia_unregister_driver(&prism2_cs_driver);#endif        printk(KERN_NOTICE "%s Unloaded\n", version);        DBFEXIT;        return;}module_init(prism2cs_init);module_exit(prism2cs_cleanup);#endif // MODULEint hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis){	int		result = 0;	conf_reg_t	reg;	UINT8		corsave;	DBFENTER;	WLAN_LOG_DEBUG(3, "Doing reset via CardServices().\n");	/* Collect COR */	reg.Function = 0; 	reg.Action = CS_READ; 	reg.Offset = CISREG_COR;	result = pcmcia_access_configuration_register(			((dev_link_t*)hw->membase)->handle,			&reg);	if (result != CS_SUCCESS ) {		WLAN_LOG_ERROR(			":0: AccessConfigurationRegister(CS_READ) failed,"			"result=%d.\n", result); 		result = -EIO;	}	corsave = reg.Value;	/* Write reset bit (BIT7) */	reg.Value |= BIT7;	reg.Action = CS_WRITE;	reg.Offset = CISREG_COR;	result = pcmcia_access_configuration_register(			((dev_link_t*)hw->membase)->handle,			&reg);	if (result != CS_SUCCESS ) {		WLAN_LOG_ERROR(			":1: AccessConfigurationRegister(CS_WRITE) failed,"			"result=%d.\n", result); 		result = -EIO;	}	/* Hold for holdtime */	mdelay(holdtime);	if (genesis) {		reg.Value = genesis;		reg.Action = CS_WRITE;		reg.Offset = CISREG_CCSR;		result = pcmcia_access_configuration_register(			((dev_link_t*)hw->membase)->handle,			&reg);		if (result != CS_SUCCESS ) {			WLAN_LOG_ERROR(				":1: AccessConfigurationRegister(CS_WRITE) failed,"				"result=%d.\n", result); 			result = -EIO;		}	}	/* Hold for holdtime */	mdelay(holdtime);	/* Clear reset bit */	reg.Value &= ~BIT7;	reg.Action = CS_WRITE;	reg.Offset = CISREG_COR;	result = pcmcia_access_configuration_register(		((dev_link_t*)hw->membase)->handle,		&reg);	if (result != CS_SUCCESS ) {		WLAN_LOG_ERROR(			":2: AccessConfigurationRegister(CS_WRITE) failed,"			"result=%d.\n", result); 		result = -EIO;		goto done;	}	/* Wait for settletime */	mdelay(settletime);	/* Set non-reset bits back what they were */	reg.Value = corsave;	reg.Action = CS_WRITE;	reg.Offset = CISREG_COR;	result = pcmcia_access_configuration_register(		((dev_link_t*)hw->membase)->handle,		&reg);	if (result != CS_SUCCESS ) {		WLAN_LOG_ERROR(			":2: AccessConfigurationRegister(CS_WRITE) failed,"			"result=%d.\n", result); 		result = -EIO;		goto done;	}done:	DBFEXIT;	return result;}

⌨️ 快捷键说明

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