skeleton.c

来自「Linux的无线局域网方案是一个Linux设备驱动程序和子系统 一揽子方案的用」· C语言 代码 · 共 696 行 · 第 1/2 页

C
696
字号
** Remove one of the device instances managed by this driver.*   Search the list for the given instance, *   check our flags for a waiting timer'd release call*   call release*   Deregister the instance with Card Services*   (netdevice) unregister the network device.*   unlink the instance from the list*   free the link, priv, and priv->priv memory* Note: the dev_list variable is a driver scoped static used to*	maintain a list of device instances managed by this*	driver.** Arguments:*	link	ptr to the instance to detach** Returns: *	nothing** Side effects:*	the link structure is gone, the netdevice is gone** Call context:*	Might be interrupt, don't block.----------------------------------------------------------------*/#if 0void wlanskel_detach(dev_link_t *link){	dev_link_t	**linkp;	UINT32		flags;	wlandevice_t	*wlandev;	DBFENTER;	/* Locate device structure */	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {		if (*linkp == link) break;	}	if (*linkp != NULL) {		/* Get rid of any timer'd release call */			save_flags(flags);		cli();		if (link->state & DEV_RELEASE_PENDING) {			del_timer(&link->release);			link->state &= ~DEV_RELEASE_PENDING;		}		restore_flags(flags);				/* If link says we're still config'd, call release */		if (link->state & DEV_CONFIG) {			wlanskel_release((u_long)link);			if (link->state & DEV_STALE_CONFIG) {				link->state |= DEV_STALE_LINK;				return;			}		}				/* Tell Card Services we're not around any more */		if (link->handle) {			CardServices(DeregisterClient, link->handle);		}			/* Unlink device structure, free bits */		*linkp = link->next;		if ( link->priv != NULL ) {			wlandev = (wlandevice_t*)link->priv;			if (link->dev != NULL) {				unregister_wlandev(wlandev);			}			wlan_unsetup(wlandev);			if (wlandev->priv) {				kfree_s(wlandev->priv, sizeof(skelpriv_t));			}			kfree_s(link->priv, sizeof(wlandevice_t));		}		kfree_s(link, sizeof(struct dev_link_t));	}	DBFEXIT;	return;}#endif/*----------------------------------------------------------------* wlanskel_config** Half of the config/release pair.  Usually called in response to* a card insertion event.  At this point, we _know_ there's some* physical device present.  That means we can start poking around* at the CIS and at any device specific config data we want.** Note the gotos and the macros.  I recoded this once without* them, and it got incredibly ugly.  It's actually simpler with* them.** Arguments:*	link	the dev_link_t structure created in attach that *		represents this device instance.** Returns: *	nothing** Side effects:*	Resources (irq, io, mem) are allocated*	The pcmcia dev_link->node->name is set*	(For netcards) The device structure is finished and,*	  most importantly, registered.  This means that there*	  is now a _named_ device that can be configured from*	  userland.** Call context:*	May be called from a timer.  Don't block!----------------------------------------------------------------*/#define CS_CHECK(fn, args...) \while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failedvoid wlanskel_config(dev_link_t *link){	client_handle_t	handle;	wlandevice_t	*wlandev;	skelpriv_t	*skelpriv;	#if 0	int		last_fn;	int		last_ret;	tuple_t		tuple;	cisparse_t	parse;	UINT16		buf[32];	int		i;	int		j;	int		ioaddr;	char		*cardname;	#endif	DBFENTER;	handle = link->handle;	wlandev = (wlandevice_t*)link->priv;	/* Initialize the CIS parse */	#if 0	tuple.Attributes = 0;	tuple.DesiredTuple = CISTPL_CONFIG;	CS_CHECK(GetFirstTuple, handle, &tuple);	tuple.TupleData = (cisdata_t *)buf;	tuple.TupleDataMax = 64;	tuple.TupleOffset = 0;	CS_CHECK(GetTupleData, handle, &tuple);	CS_CHECK(ParseTuple, handle, &tuple, &parse);	link->conf.ConfigBase = parse.config.base;	link->conf.Present = parse.config.rmask[0];	#endif	/* Configure card */	link->state |= DEV_CONFIG;		#if 0	for (i = j = 0; j < 0x400; j += 0x20) {		link->io.BasePort1 = j ^ 0x300;		i = CardServices(RequestIO, link->handle, &link->io);		if (i == CS_SUCCESS) break;	}	if (i != CS_SUCCESS) {		cs_error(link->handle, RequestIO, i);		goto failed;	}	CS_CHECK(RequestIRQ, link->handle, &link->irq);	CS_CHECK(RequestConfiguration, link->handle, &link->conf);	#endif	wlandev->irq = 0;	/* link->irq.AssignedIRQ; */	wlandev->iobase = 0;	/* link->io.BasePort1; */	/* Register the network device and get assigned a name */	if (register_wlandev(wlandev) != 0) {		WLAN_LOG_NOTICE0("wlanskel_cs: register_wlandev() failed.\n");		goto failed;	}	link->state &= ~DEV_CONFIG_PENDING;	skelpriv = (skelpriv_t*)wlandev->priv;	/* collect the device priv ptr */	link->dev = &skelpriv->node;		/* now pcmcia knows the device name */	/* Any device custom config/query stuff should be done here */	/* For a netdevice, we should at least grab the mac address */	return;#if 0cs_failed:	cs_error(link->handle, last_fn, last_ret);#endiffailed:	wlanskel_release((UINT32)link);	return;}/*----------------------------------------------------------------* wlanskel_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...we assume it's a *               ptr to a dev_link.** 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 wlanskel_release(UINT32 arg){        dev_link_t	*link = (dev_link_t *)arg;	DBFENTER;        if (link->open) {                WLAN_LOG_DEBUG1(1, "wlanskel_cs: release postponed, '%s' still open\n",                          link->dev->dev_name);                link->state |= DEV_STALE_CONFIG;                return;        }	/*        CardServices(ReleaseConfiguration, link->handle);        CardServices(ReleaseIO, link->handle, &link->io);        CardServices(ReleaseIRQ, link->handle, &link->irq);        if (link->win) {                iounmap((void *)(dev->mem_start - 0x800));                CardServices(ReleaseWindow, link->win);        }	*/        link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);	DBFEXIT;}/*----------------------------------------------------------------* init_module** Module initialization routine, called once at module load time.* This one simulates some of the pcmcia calls.** Arguments:*	none** Returns: *	0	- success *	~0	- failure, module is unloaded.** Side effects:*	TODO: define** Call context:*	process thread (insmod or modprobe)----------------------------------------------------------------*/int init_module(void){	int		result = 0;	dev_link_t 	*link;        DBFENTER;        WLAN_LOG_NOTICE1("%s Loaded\n", version);        WLAN_LOG_NOTICE1("dev_info is: %s\n", dev_info);	/* register_driver( &dev_info, &wlanskel_attach, &wlanskel_detach  */	/*  simulated with call to wlanskel_attach */	if ((link = wlanskel_attach()) == NULL ) {		result = 1;	} else {		/* After attach finishes, pcmcia-cs usually calls    */		/* the wlanskel_event function signaling an INSERT   */		/* event This results in a call to the driver defined*/		/* wlanskel_config function.  We'll just call it.    */		wlanskel_config(link);	}	        DBFEXIT;        return result;}/*----------------------------------------------------------------* cleanup_module** Called at module unload time.  This is our last chance to* clean up after ourselves.** Arguments:*	none** Returns: *	nothing** Side effects:*	TODO: define** Call context:*	process thread*----------------------------------------------------------------*/void cleanup_module(void){	dev_link_t *link = dev_list;	wlandevice_t *wlandev = (wlandevice_t *)link->priv;        DBFENTER;		if (link->dev != NULL) {		unregister_wlandev(wlandev);	}	wlan_unsetup(wlandev);	if (wlandev->priv) {		kfree_s(wlandev->priv, sizeof(skelpriv_t));	}	kfree_s(wlandev, sizeof(wlandevice_t));	kfree_s(link, sizeof(struct dev_link_t));        printk(KERN_NOTICE "%s Unloaded\n", version);        DBFEXIT;        return;}

⌨️ 快捷键说明

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