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

📄 ibmtr_cs.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
    struct tok_info *ti = netdev_priv(dev);    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, pcmcia_get_first_tuple(handle, &tuple));    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));    CS_CHECK(ParseTuple, pcmcia_parse_tuple(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 = pcmcia_request_io(link->handle, &link->io);    if (i != CS_SUCCESS) {	/* Couldn't get 0xA20-0xA23.  Try ALTERNATE at 0xA24-0xA27. */	link->io.BasePort1 = 0xA24;	CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));    }    dev->base_addr = link->io.BasePort1;    CS_CHECK(RequestIRQ, pcmcia_request_irq(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;    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));    mem.CardOffset = mmiobase;    mem.Page = 0;    CS_CHECK(MapMemPage, pcmcia_map_mem_page(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;    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &info->sram_win_handle));    mem.CardOffset = srambase;    mem.Page = 0;    CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));    ti->sram_base = mem.CardOffset >> 12;    ti->sram_virt = ioremap(req.Base, req.Size);    ti->sram_phys = req.Base;    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(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);    link->dev = &info->node;    link->state &= ~DEV_CONFIG_PENDING;    SET_NETDEV_DEV(dev, &handle_to_dev(handle));    i = ibmtr_probe_card(dev);    if (i != 0) {	printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");	link->dev = NULL;	goto failed;    }    strcpy(info->node.dev_name, dev->name);    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(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(dev_link_t *link){    ibmtr_dev_t *info = link->priv;    struct net_device *dev = info->dev;    DEBUG(0, "ibmtr_release(0x%p)\n", link);    pcmcia_release_configuration(link->handle);    pcmcia_release_io(link->handle, &link->io);    pcmcia_release_irq(link->handle, &link->irq);    if (link->win) {	struct tok_info *ti = netdev_priv(dev);	iounmap(ti->mmio);	pcmcia_release_window(link->win);	pcmcia_release_window(info->sram_win_handle);    }    link->state &= ~DEV_CONFIG;}/*======================================================================    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 *priv = netdev_priv(dev);	    priv->sram_phys |= 1;	    netif_device_detach(dev);        }        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);            pcmcia_release_configuration(link->handle);        }        break;    case CS_EVENT_PM_RESUME:        link->state &= ~DEV_SUSPEND;        /* Fall through... */    case CS_EVENT_CARD_RESET:        if (link->state & DEV_CONFIG) {            pcmcia_request_configuration(link->handle, &link->conf);            if (link->open) {		ibmtr_probe(dev);	/* really? */		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 struct pcmcia_device_id ibmtr_ids[] = {	PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e),	PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47),	PCMCIA_DEVICE_NULL,};MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids);static struct pcmcia_driver ibmtr_cs_driver = {	.owner		= THIS_MODULE,	.drv		= {		.name	= "ibmtr_cs",	},	.attach		= ibmtr_attach,	.event		= ibmtr_event,	.detach		= ibmtr_detach,	.id_table       = ibmtr_ids,};static int __init init_ibmtr_cs(void){	return pcmcia_register_driver(&ibmtr_cs_driver);}static void __exit exit_ibmtr_cs(void){	pcmcia_unregister_driver(&ibmtr_cs_driver);	BUG_ON(dev_list != NULL);}module_init(init_ibmtr_cs);module_exit(exit_ibmtr_cs);

⌨️ 快捷键说明

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