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

📄 am930di.c

📁 Linux Wireless LAN Project 的目标是开发一个完整的
💻 C
📖 第 1 页 / 共 2 页
字号:
/* am930_di.c : Handles the PCMCIA "device instance" functions*	--------------------------------------------------------------------**   Linux WLAN **   The contents of this file are subject to the Mozilla Public*   License Version 1.0 (the "License"); you may not use this file*   except in compliance with the License. You may obtain a copy of*   the License at http://www.mozilla.org/MPL/**   Software distributed under the License is distributed on an "AS*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or*   implied. See the License for the specific language governing*   rights and limitations under the License.**   The initial developer of the original code is Mark S. Mathews*   <mark@absoval.com>.  Portions created by Mark S. Mathews*   are Copyright (C) 1998 AbsoluteValue Software, Inc.  All Rights Reserved.*   *	--------------------------------------------------------------------**	The author may be reached as mark@absoval.com, or C/O AbsoluteValue*	Software Inc., P.O. Box 941149, Maitland, FL, 32794-1149**	Thanks to David Hinds, Donald Becker, and the rest of the Linux*	developers worldwide for making all of this possible.**	--------------------------------------------------------------------**	PCMCIA "device Instance" **	The functions in this file are responsible for dealing with the*	life of a PCMCIA card. This involves dealing with the PCMCIA elements*	of the card itself and dealing with socket, driver, and card services.**/#if defined(__LINUX_WLAN__)/* The following prevents "kernel_version" from being set in this file. */#define __NO_VERSION__/* PCMCIA headers generated during PCMCIA package installation */#include <pcmcia/config.h>#include <pcmcia/k_compat.h>/* Module related headers, non-module drivers should not include */#include <linux/version.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>/* Ethernet and network includes */#include <linux/if_ether.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/if_arp.h>#include <linux/ioport.h>/* Standard driver includes */#include <linux/delay.h>#include <linux/types.h>#include <linux/fcntl.h>#include <asm/system.h>#include <asm/io.h>#include <linux/ptrace.h>#include <linux/interrupt.h>#include <linux/ioport.h>#include <linux/in.h>#include <linux/malloc.h>#include <linux/string.h>#include <linux/timer.h>#include <asm/bitops.h>#include <linux/errno.h>/* Card and Driver services includes */#include <pcmcia/version.h>#include <pcmcia/cs_types.h>#include <pcmcia/cs.h>#include <pcmcia/cistpl.h>#include <pcmcia/ds.h>#include <pcmcia/cisreg.h>#endif/* Local Includes */#include <wlan/version.h>#include <wlan/wlan_compat.h>#include <wlan/p80211hdr.h>#include <wlan/p80211mgmt.h>#include "am930di.h"#include "am930llc.h"#include "am930mac.h"#include "am930hw.h"#if (LINUX_VERSION_CODE < VERSION(2,2,0))#				define ioremap_nocache ioremap#endif/*================================================================*//* Local macros *//*================================================================*//* Local prototypes */static void am930DI_interrupt (int irq, void * dev_id, struct pt_regs *regs );static int am930DI_config(dev_link_t *instance, UINT32 *pMemBase);static int am930DI_deconfig(dev_link_t *instance);/*================================================================*//* Local statics (lifetime not scope) *//* Driver name, must match the name in the PCMCIA database */dev_info_t	am930_driver_name = "am930_cs";/*----------------------------------------------------------------*	am930DI_construct**	Device constructor, contains alot of the code commonly found *	in other pcmcia driver's "attach" function.**	The function first allocates an "instance" structure, then *	zeros it. Then the RegisterClient Card Services call is *	set up and done. Note that we register for ALL of the *	Card Services events at this point. Therefore, the event*	handler must be coded to deal with ALL of them.**	returns: nothing----------------------------------------------------------------*/dev_link_t* am930DI_construct(void){    dev_link_t		*instance;    client_reg_t	client_reg;    int 			ret = 0;   	DBFENTER;    /* Allocate the instance */    instance = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);	if ( instance != NULL )	{		/* zero the instance members */	    memset(instance, 0, sizeof(struct dev_link_t));	    /* remaining initialization of instance will be done */	    /*  in the config function */			/*---------- Register with Card Services ---------------------*/		/* Set up the client registration function */	    client_reg.dev_info = &am930_driver_name;	    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;	    client_reg.EventMask =	    	/* client services */				CS_EVENT_REGISTRATION_COMPLETE | 			/* host battery */				CS_EVENT_BATTERY_LOW |				CS_EVENT_BATTERY_DEAD |	    	/* insertion/removal */				CS_EVENT_CARD_INSERTION | 				CS_EVENT_CARD_REMOVAL |			/* reset */				CS_EVENT_RESET_REQUEST | 				CS_EVENT_RESET_PHYSICAL |				CS_EVENT_CARD_RESET |				CS_EVENT_RESET_COMPLETE |			/* power management */				CS_EVENT_PM_SUSPEND | 				CS_EVENT_PM_RESUME ;	    client_reg.event_handler = &am930DI_event;	    client_reg.Version = 0x0210;	    client_reg.event_callback_args.client_data = instance;		/* allocate the device node */	    instance->dev = kmalloc( sizeof(dev_node_t), GFP_KERNEL );	    if ( instance->dev == NULL )	    {	    	WLAN_LOG_ERROR0("dev_node_t allocation failed!\n");	    	am930DI_destruct( instance );	    	instance = NULL;	    }	    else	    {	    	memset( instance->dev, 0, sizeof(dev_node_t) );		    ret = CardServices(RegisterClient, &instance->handle, &client_reg);			    if (ret != 0) 		    {				am930_drvr_cs_error(instance->handle, RegisterClient, ret);				kfree_s( instance->dev, sizeof(struct dev_node_t));				kfree_s( instance, sizeof(struct dev_link_t));				instance = NULL;		    }		}	}	DBFEXIT;    return instance;} /*----------------------------------------------------------------*	am930DI_destruct**	Destructor for the device instance object. This function *	roughly corresponds to the "xxx_release" function described for*	pcmcia drivers.**	This function first check to see if the Linux device corresponding*	to this pcmcia device instance is still open,*	if so, then we mark the instance as having a STALE configuration*	and bail, hoping that this function will be called again later.*	If the device is not open (closed? ;-) ), 1st we call the*	call the destructors of the subobjects, then we call the *	deconfig method to release all of the resources allocated when*	this instance was configured. Then, we check to see if the*	driver object's detach function wants to be called (indicated*	by STALE_LINK) and if so, call it. After the detach function is*	called, the structure representing this instance no longer exists*	and should not be referenced.**	returns: nothing----------------------------------------------------------------*/void am930DI_destruct(dev_link_t *instance){    	DBFENTER;	if ( instance->open )	{		WLAN_LOG_DEBUG1(2, "inst 0x%x still open, destruct (release) deferred.\n", 					(UINT)instance);		instance->state |= DEV_STALE_CONFIG;	}	else	{		am930mac_t	*mac;		/* Destroy the subobjects */		mac = (am930mac_t*)instance->priv;		if ( mac != NULL )		{			am930mac_destruct(mac);		}		am930DI_deconfig(instance);		/* check to see if drvr_detach has been called previously and			expects to be called again.		*/		if ( instance->state & DEV_STALE_LINK )		{			am930_drvr_detach(instance);		}		if (instance->dev != NULL )		{			kfree_s( instance->dev, sizeof(dev_node_t));			instance->dev = NULL;		}		/* instance memory is kfree'd in am930cs_detach */	}	DBFEXIT;	return;}/*----------------------------------------------------------------*	am930DI_event**	Responsible for dispatching and/or scheduling the handling of*	PCMCIA events. *	Events and the responses:*		CS_EVENT_REGISTRATION_COMPLETE*			in debug, log the event, otherwise nothing.*		CS_EVENT_BATTERY_LOW*			currently unsupported.*		CS_EVENT_BATTERY_DEAD*			currently unsupported.*		CS_EVENT_CARD_INSERTION*			call the DI_config method to configure the interface*			to the device and get the ball rolling on the *			OS interface.*		CS_EVENT_CARD_REMOVAL*			schedule a delayed run of the destructor, delayed*			because the event handler can't wait for the destructor*			to complete, we must return immediately.*		CS_EVENT_RESET_REQUEST *		CS_EVENT_RESET_PHYSICAL*		CS_EVENT_CARD_RESET*		CS_EVENT_RESET_COMPLETE*		CS_EVENT_PM_SUSPEND *		CS_EVENT_PM_RESUME*			all unsupported, but logged in debug**	returns: zero----------------------------------------------------------------*/int am930DI_event( event_t event, int priority,                        	event_callback_args_t *args){    dev_link_t		*instance = args->client_data;    	DBFENTER;        switch (event)    {		case CS_EVENT_REGISTRATION_COMPLETE:			WLAN_LOG_DEBUG1(2, 				"CS_EVENT_REGISTRATION_COMPLETE event, instance %x\n", 				(UINT)instance);			break;		case CS_EVENT_CARD_INSERTION:			WLAN_LOG_DEBUG1(2,				"CS_EVENT_CARD_INSERTION event, instance %x\n", 				(UINT)instance);			instance->state |= DEV_PRESENT | DEV_CONFIG_PENDING;			{				UINT32 membase = 0;  /* temp to hold membase from config */				if ( am930DI_config(instance, &membase) == AM930DI_SUCCESS)

⌨️ 快捷键说明

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