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

📄 ibmtr_cs.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
/*======================================================================    ibmtr_config() is scheduled to run after a CARD_INSERTION event    is received, to configure the PCMCIA socket, and to make the    token-ring device available to the system.======================================================================*/#define CS_CHECK(fn, args...) \while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failedstatic void ibmtr_config(dev_link_t *link){    client_handle_t handle = link->handle;    ibmtr_dev_t *info = link->priv;    struct net_device *dev = info->dev;    struct tok_info *ti = dev->priv;    tuple_t tuple;    cisparse_t parse;    win_req_t req;    memreq_t mem;    int i, last_ret, last_fn;    u_char buf[64];    DEBUG(0, "ibmtr_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;    link->conf.ConfigIndex = 0x61;    /* Determine if this is PRIMARY or ALTERNATE. */    /* Try PRIMARY card at 0xA20-0xA23 */    link->io.BasePort1 = 0xA20;    i = CardServices(RequestIO, link->handle, &link->io);    if (i == CS_SUCCESS) {	memcpy(info->node.dev_name, "tr0\0", 4);    } else {	/* Couldn't get 0xA20-0xA23.  Try ALTERNATE at 0xA24-0xA27. */	link->io.BasePort1 = 0xA24;	CS_CHECK(RequestIO, link->handle, &link->io);	memcpy(info->node.dev_name, "tr1\0", 4);    }    dev->base_addr = link->io.BasePort1;    CS_CHECK(RequestIRQ, link->handle, &link->irq);    dev->irq = link->irq.AssignedIRQ;    ti->irq = link->irq.AssignedIRQ;    ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);    /* Allocate the MMIO memory window */    req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;    req.Attributes |= WIN_USE_WAIT;    req.Base = 0;     req.Size = 0x2000;    req.AccessSpeed = 250;    link->win = (window_handle_t)link->handle;    CS_CHECK(RequestWindow, &link->win, &req);    mem.CardOffset = mmiobase;    mem.Page = 0;    CS_CHECK(MapMemPage, link->win, &mem);    ti->mmio = ioremap(req.Base, req.Size);    /* Allocate the SRAM memory window */    req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;    req.Attributes |= WIN_USE_WAIT;    req.Base = 0;    req.Size = sramsize * 1024;    req.AccessSpeed = 250;    info->sram_win_handle = (window_handle_t)link->handle;    CS_CHECK(RequestWindow, &info->sram_win_handle, &req);    mem.CardOffset = srambase;    mem.Page = 0;    CS_CHECK(MapMemPage, info->sram_win_handle, &mem);    ti->sram_base = mem.CardOffset >> 12;    ti->sram_virt = (u_long)ioremap(req.Base, req.Size);    CS_CHECK(RequestConfiguration, link->handle, &link->conf);    /*  Set up the Token-Ring Controller Configuration Register and        turn on the card.  Check the "Local Area Network Credit Card        Adapters Technical Reference"  SC30-3585 for this info.  */    ibmtr_hw_setup(dev, mmiobase);    i = register_trdev(dev);        if (i != 0) {	printk(KERN_NOTICE "ibmtr_cs: register_trdev() failed\n");	goto failed;    }    link->dev = &info->node;    link->state &= ~DEV_CONFIG_PENDING;    printk(KERN_INFO "%s: port %#3lx, irq %d,",           dev->name, dev->base_addr, dev->irq);    printk (" mmio %#5lx,", (u_long)ti->mmio);    printk (" sram %#5lx,", (u_long)ti->sram_base << 12);    printk ("\n" KERN_INFO "  hwaddr=");    for (i = 0; i < TR_ALEN; i++)        printk("%02X", dev->dev_addr[i]);    printk("\n");    return;cs_failed:    cs_error(link->handle, last_fn, last_ret);failed:    ibmtr_release((u_long)link);} /* ibmtr_config *//*======================================================================    After a card is removed, ibmtr_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 ibmtr_release(u_long arg){    dev_link_t *link = (dev_link_t *)arg;    ibmtr_dev_t *info = link->priv;    struct net_device *dev = info->dev;    DEBUG(0, "ibmtr_release(0x%p)\n", link);    if (link->open) {	DEBUG(1, "ibmtr_cs: release postponed, '%s' "	      "still open\n", info->node.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) {	struct tok_info *ti = dev->priv;	iounmap((void *)ti->mmio);	CardServices(ReleaseWindow, link->win);	CardServices(ReleaseWindow, info->sram_win_handle);    }    link->state &= ~DEV_CONFIG;} /* ibmtr_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 ibmtr_event(event_t event, int priority,                       event_callback_args_t *args){    dev_link_t *link = args->client_data;    ibmtr_dev_t *info = link->priv;    struct net_device *dev = info->dev;    DEBUG(1, "ibmtr_event(0x%06x)\n", event);    switch (event) {    case CS_EVENT_CARD_REMOVAL:        link->state &= ~DEV_PRESENT;        if (link->state & DEV_CONFIG) {	    /* set flag to bypass normal interrupt code */	    ((struct tok_info *)dev->priv)->sram_virt |= 1;	    netif_device_detach(dev);	    mod_timer(&link->release, jiffies + HZ/20);        }        break;    case CS_EVENT_CARD_INSERTION:        link->state |= DEV_PRESENT;	ibmtr_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) {		(dev->init)(dev);		netif_device_attach(dev);            }        }        break;    }    return 0;} /* ibmtr_event *//*====================================================================*/static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase){    int i;    /* Bizarre IBM behavior, there are 16 bits of information we       need to set, but the card only allows us to send 4 bits at a        time.  For each byte sent to base_addr, bits 7-4 tell the       card which part of the 16 bits we are setting, bits 3-0 contain        the actual information */    /* First nibble provides 4 bits of mmio */    i = (mmiobase >> 16) & 0x0F;    outb(i, dev->base_addr);    /* Second nibble provides 3 bits of mmio */    i = 0x10 | ((mmiobase >> 12) & 0x0E);    outb(i, dev->base_addr);    /* Third nibble, hard-coded values */    i = 0x26;    outb(i, dev->base_addr);    /* Fourth nibble sets shared ram page size */    /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */              i = (sramsize >> 4) & 0x07;    i = ((i == 4) ? 3 : i) << 2;    i |= 0x30;    if (ringspeed == 16)	i |= 2;    if (dev->base_addr == 0xA24)	i |= 1;    outb(i, dev->base_addr);    /* 0x40 will release the card for use */    outb(0x40, dev->base_addr);    return;}/*====================================================================*/static int __init init_ibmtr_cs(void){    servinfo_t serv;    DEBUG(0, "%s", version);    CardServices(GetCardServicesInfo, &serv);    if (serv.Revision != CS_RELEASE_CODE) {        printk(KERN_NOTICE "ibmtr_cs: Card Services release "	       "does not match!\n");        return -1;    }    register_pccard_driver(&dev_info, &ibmtr_attach, &ibmtr_detach);    return 0;}static void __exit exit_ibmtr_cs(void){    DEBUG(0, "ibmtr_cs: unloading\n");    unregister_pccard_driver(&dev_info);    while (dev_list != NULL)        ibmtr_detach(dev_list);}module_init(init_ibmtr_cs);module_exit(exit_ibmtr_cs);

⌨️ 快捷键说明

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