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

📄 com20020_cs.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
    DEBUG(0, "com20020_detach(0x%p)\n", link);    /* Locate device structure */    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)        if (*linkp == link) break;    if (*linkp == NULL)        return;    dev = info->dev;    if (link->state & DEV_CONFIG) {        com20020_release((u_long)link);        if (link->state & DEV_STALE_CONFIG) {            link->state |= DEV_STALE_LINK;            return;        }    }    if (link->handle)        CardServices(DeregisterClient, link->handle);    /* Unlink device structure, free bits */    DEBUG(1,"unlinking...\n");    *linkp = link->next;    if (link->priv)    {	dev = info->dev;	if (dev)	{	    if (info->dev_configured)	    {		DEBUG(1,"unregister...\n");		if (netif_running(dev))		    dev->stop(dev);	    		/*		 * this is necessary because we register our IRQ separately		 * from card services.		 */		if (dev->irq)		    free_irq(dev->irq, dev);				/* ...but I/O ports are done automatically by card services */				unregister_netdev(dev);		MOD_DEC_USE_COUNT;	    }	    	    DEBUG(1,"kfree...\n");	    kfree(dev->priv);	    kfree(dev);	}	DEBUG(1,"kfree2...\n");	kfree(info);    }    DEBUG(1,"kfree3...\n");    kfree(link);} /* com20020_detach *//*======================================================================    com20020_config() is scheduled to run after a CARD_INSERTION event    is received, to configure the PCMCIA socket, and to make the    device available to the system.======================================================================*/#define CS_CHECK(fn, args...) \while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failedstatic void com20020_config(dev_link_t *link){    struct arcnet_local *lp;    client_handle_t handle;    tuple_t tuple;    cisparse_t parse;    com20020_dev_t *info;    struct net_device *dev;    int i, last_ret, last_fn;    u_char buf[64];    int ioaddr;    handle = link->handle;    info = link->priv;    dev = info->dev;    DEBUG(1,"config...\n");    DEBUG(0, "com20020_config(0x%p)\n", link);    tuple.Attributes = 0;    tuple.TupleData = buf;    tuple.TupleDataMax = 64;    tuple.TupleOffset = 0;    tuple.DesiredTuple = CISTPL_CONFIG;    CS_CHECK(GetFirstTuple, handle, &tuple);    CS_CHECK(GetTupleData, handle, &tuple);    CS_CHECK(ParseTuple, handle, &tuple, &parse);    link->conf.ConfigBase = parse.config.base;    /* Configure card */    link->state |= DEV_CONFIG;    strcpy(info->node.dev_name, dev->name);    DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1);    i = !CS_SUCCESS;    if (!link->io.BasePort1)    {	for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10)	{	    link->io.BasePort1 = ioaddr;	    i = CardServices(RequestIO, link->handle, &link->io);	    if (i == CS_SUCCESS)		break;	}    }    else	i = CardServices(RequestIO, link->handle, &link->io);        if (i != CS_SUCCESS)    {	DEBUG(1,"arcnet: requestIO failed totally!\n");	goto failed;    }	    ioaddr = dev->base_addr = link->io.BasePort1;    DEBUG(1,"arcnet: got ioaddr %Xh\n", ioaddr);    DEBUG(1,"arcnet: request IRQ %d (%Xh/%Xh)\n",	   link->irq.AssignedIRQ,	   link->irq.IRQInfo1, link->irq.IRQInfo2);    i = CardServices(RequestIRQ, link->handle, &link->irq);    if (i != CS_SUCCESS)    {	DEBUG(1,"arcnet: requestIRQ failed totally!\n");	goto failed;    }    dev->irq = link->irq.AssignedIRQ;    CS_CHECK(RequestConfiguration, link->handle, &link->conf);    if (com20020_check(dev))    {	regdump(dev);	goto failed;    }        MOD_INC_USE_COUNT;    lp = dev->priv;    lp->card_name = "PCMCIA COM20020";    lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */    i = com20020_found(dev, 0);        if (i != 0) {	DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n");	goto failed;    }    info->dev_configured = 1;    link->dev = &info->node;    link->state &= ~DEV_CONFIG_PENDING;    DEBUG(1,KERN_INFO "%s: port %#3lx, irq %d\n",           dev->name, dev->base_addr, dev->irq);    return;cs_failed:    cs_error(link->handle, last_fn, last_ret);failed:    DEBUG(1,"com20020_config failed...\n");    com20020_release((u_long)link);} /* com20020_config *//*======================================================================    After a card is removed, com20020_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 com20020_release(u_long arg){    dev_link_t *link = (dev_link_t *)arg;    DEBUG(1,"release...\n");    DEBUG(0, "com20020_release(0x%p)\n", link);    if (link->open) {	DEBUG(1,"postpone...\n");	DEBUG(1, "com20020_cs: release postponed, device stll open\n");        link->state |= DEV_STALE_CONFIG;        return;    }    CardServices(ReleaseConfiguration, link->handle);    CardServices(ReleaseIO, link->handle, &link->io);    CardServices(ReleaseIRQ, link->handle, &link->irq);    link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);} /* com20020_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.======================================================================*/static int com20020_event(event_t event, int priority,			  event_callback_args_t *args){    dev_link_t *link = args->client_data;    com20020_dev_t *info = link->priv;    struct net_device *dev = info->dev;    DEBUG(1, "com20020_event(0x%06x)\n", event);        switch (event) {    case CS_EVENT_CARD_REMOVAL:        link->state &= ~DEV_PRESENT;        if (link->state & DEV_CONFIG) {            netif_device_detach(dev);            link->release.expires = jiffies + HZ/20;            link->state |= DEV_RELEASE_PENDING;            add_timer(&link->release);        }        break;    case CS_EVENT_CARD_INSERTION:        link->state |= DEV_PRESENT;	com20020_config(link); 	break;    case CS_EVENT_PM_SUSPEND:        link->state |= DEV_SUSPEND;        /* Fall through... */    case CS_EVENT_RESET_PHYSICAL:        if (link->state & DEV_CONFIG) {            if (link->open) {                netif_device_detach(dev);            }            CardServices(ReleaseConfiguration, link->handle);        }        break;    case CS_EVENT_PM_RESUME:        link->state &= ~DEV_SUSPEND;        /* Fall through... */    case CS_EVENT_CARD_RESET:        if (link->state & DEV_CONFIG) {            CardServices(RequestConfiguration, link->handle, &link->conf);            if (link->open) {		int ioaddr = dev->base_addr;		struct arcnet_local *lp = (struct arcnet_local *)dev->priv;		ARCRESET;            }        }        break;    }    return 0;} /* com20020_event *//*====================================================================*/static int __init init_com20020_cs(void){    servinfo_t serv;    DEBUG(0, "%s\n", VERSION);    CardServices(GetCardServicesInfo, &serv);    if (serv.Revision != CS_RELEASE_CODE) {	printk(KERN_NOTICE "com20020_cs: Card Services release "	       "does not match!\n");        return -1;    }    register_pccard_driver(&dev_info, &com20020_attach, &com20020_detach);    return 0;}static void __exit exit_com20020_cs(void){    DEBUG(0, "com20020_cs: unloading\n");    unregister_pccard_driver(&dev_info);    while (dev_list != NULL)        com20020_detach(dev_list);}module_init(init_com20020_cs);module_exit(exit_com20020_cs);

⌨️ 快捷键说明

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