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

📄 ray_cs.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 5 页
字号:
    link->irq.Handler = &ray_interrupt;    /* General socket configuration */    link->conf.Attributes = CONF_ENABLE_IRQ;    link->conf.Vcc = 50;    link->conf.IntType = INT_MEMORY_AND_IO;    link->conf.ConfigIndex = 1;    link->conf.Present = PRESENT_OPTION;    /* Allocate space for private device-specific data */    dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);    if (dev == NULL) {	kfree(link);	return NULL;    }    memset(dev, 0, sizeof(struct net_device));    link->priv = dev;    link->irq.Instance = dev;        local = kmalloc(sizeof(ray_dev_t), GFP_KERNEL);    if (local == NULL) {	kfree(dev);	kfree(link);	return NULL;    }    memset(local, 0, sizeof(ray_dev_t));    dev->priv = local;    local->finder = link;    local->card_status = CARD_INSERTED;    local->authentication_state = UNAUTHENTICATED;    local->num_multi = 0;    spin_lock_init(&local->ray_lock);    DEBUG(2,"ray_attach link = %p,  dev = %p,  local = %p, intr = %p\n",          link,dev,local,&ray_interrupt);    /* Raylink entries in the device structure */    dev->hard_start_xmit = &ray_dev_start_xmit;    dev->set_config = &ray_dev_config;    dev->get_stats  = &ray_get_stats;    dev->do_ioctl = &ray_dev_ioctl;#if WIRELESS_EXT > 7	/* If wireless extension exist in the kernel */    dev->get_wireless_stats = ray_get_wireless_stats;#endif    dev->set_multicast_list = &set_multicast_list;    DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n");    ether_setup(dev);    /*    dev->mtu = 1468; */    init_dev_name(dev, local->node);    dev->init = &ray_dev_init;    dev->open = &ray_open;    dev->stop = &ray_dev_close;    /* Register with Card Services */    link->next = dev_list;    dev_list = link;    client_reg.dev_info = &dev_info;    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;    client_reg.EventMask =        CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |        CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |        CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;    client_reg.event_handler = &ray_event;    client_reg.Version = 0x0210;    client_reg.event_callback_args.client_data = link;    DEBUG(2,"ray_cs ray_attach calling CardServices(RegisterClient...)\n");    init_timer(&local->timer);    ret = CardServices(RegisterClient, &link->handle, &client_reg);    if (ret != 0) {        printk("ray_cs ray_attach RegisterClient unhappy - detaching\n");        cs_error(link->handle, RegisterClient, ret);        ray_detach(link);        return NULL;    }    DEBUG(2,"ray_cs ray_attach ending\n");    return link;} /* ray_attach *//*=============================================================================    This deletes a driver "instance".  The device is de-registered    with Card Services.  If it has been released, all local data    structures are freed.  Otherwise, the structures will be freed    when the device is released.=============================================================================*/static void ray_detach(dev_link_t *link){    dev_link_t **linkp;    DEBUG(1, "ray_detach(0x%p)\n", link);        /* Locate device structure */    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)        if (*linkp == link) break;    if (*linkp == NULL)        return;    /* If the device is currently configured and active, we won't      actually delete it yet.  Instead, it is marked so that when      the release() function is called, that will trigger a proper      detach().    */    del_timer(&link->release);    if (link->state & DEV_CONFIG) {        ray_release((u_long)link);        if(link->state & DEV_STALE_CONFIG) {            link->state |= DEV_STALE_LINK;            return;        }    }    /* Break the link with Card Services */    if (link->handle)        CardServices(DeregisterClient, link->handle);        /* Unlink device structure, free pieces */    *linkp = link->next;    if (link->priv) {	struct net_device *dev = link->priv;	if (link->dev) unregister_netdev(dev);        if (dev->priv)            kfree(dev->priv);        kfree(dev);    }    kfree(link);    DEBUG(2,"ray_cs ray_detach ending\n");} /* ray_detach *//*=============================================================================    ray_config() is run after a CARD_INSERTION event    is received, to configure the PCMCIA socket, and to make the    ethernet device available to the system.=============================================================================*/#define CS_CHECK(fn, args...) \while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed#define MAX_TUPLE_SIZE 128static void ray_config(dev_link_t *link){    client_handle_t handle = link->handle;    tuple_t tuple;    cisparse_t parse;    int last_fn, last_ret;    int i;    u_char buf[MAX_TUPLE_SIZE];    win_req_t req;    memreq_t mem;    struct net_device *dev = (struct net_device *)link->priv;    ray_dev_t *local = (ray_dev_t *)dev->priv;    DEBUG(1, "ray_config(0x%p)\n", link);    /* This reads the card's CONFIG tuple to find its configuration regs */    tuple.DesiredTuple = CISTPL_CONFIG;    CS_CHECK(GetFirstTuple, handle, &tuple);    tuple.TupleData = buf;    tuple.TupleDataMax = MAX_TUPLE_SIZE;    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];    /* Determine card type and firmware version */    buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0;    tuple.DesiredTuple = CISTPL_VERS_1;    CS_CHECK(GetFirstTuple, handle, &tuple);    tuple.TupleData = buf;    tuple.TupleDataMax = MAX_TUPLE_SIZE;    tuple.TupleOffset = 2;    CS_CHECK(GetTupleData, handle, &tuple);    for (i=0; i<tuple.TupleDataLen - 4; i++)         if (buf[i] == 0) buf[i] = ' ';    printk(KERN_INFO "ray_cs Detected: %s\n",buf);    /* Configure card */    link->state |= DEV_CONFIG;    /* Now allocate an interrupt line.  Note that this does not       actually assign a handler to the interrupt.    */    CS_CHECK(RequestIRQ, link->handle, &link->irq);    dev->irq = link->irq.AssignedIRQ;        /* This actually configures the PCMCIA socket -- setting up       the I/O windows and the interrupt mapping.    */    CS_CHECK(RequestConfiguration, link->handle, &link->conf);/*** Set up 32k window for shared memory (transmit and control) ************/    req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;    req.Base = 0;    req.Size = 0x8000;    req.AccessSpeed = ray_mem_speed;    link->win = (window_handle_t)link->handle;    CS_CHECK(RequestWindow, &link->win, &req);    mem.CardOffset = 0x0000; mem.Page = 0;    CS_CHECK(MapMemPage, link->win, &mem);    local->sram = (UCHAR *)(ioremap(req.Base,req.Size));/*** Set up 16k window for shared memory (receive buffer) ***************/    req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;    req.Base = 0;    req.Size = 0x4000;    req.AccessSpeed = ray_mem_speed;    local->rmem_handle = (window_handle_t)link->handle;    CS_CHECK(RequestWindow, &local->rmem_handle, &req);    mem.CardOffset = 0x8000; mem.Page = 0;    CS_CHECK(MapMemPage, local->rmem_handle, &mem);    local->rmem = (UCHAR *)(ioremap(req.Base,req.Size));/*** Set up window for attribute memory ***********************************/    req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT;    req.Base = 0;    req.Size = 0x1000;    req.AccessSpeed = ray_mem_speed;    local->amem_handle = (window_handle_t)link->handle;    CS_CHECK(RequestWindow, &local->amem_handle, &req);    mem.CardOffset = 0x0000; mem.Page = 0;    CS_CHECK(MapMemPage, local->amem_handle, &mem);    local->amem = (UCHAR *)(ioremap(req.Base,req.Size));    DEBUG(3,"ray_config sram=%p\n",local->sram);    DEBUG(3,"ray_config rmem=%p\n",local->rmem);    DEBUG(3,"ray_config amem=%p\n",local->amem);    if (ray_init(dev) < 0)	goto config_failed;    i = register_netdev(dev);    if (i != 0) {        printk(KERN_INFO "ray_config register_netdev() failed\n");	goto config_failed;    }    copy_dev_name(local->node, dev);    link->dev = &local->node;    local->card_status = CARD_AWAITING_PARAM;    clear_interrupt(local); /* Clear any interrupt from the card */    printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ",       dev->name, dev->irq);    for (i = 0; i < 6; i++)    printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));    link->state &= ~DEV_CONFIG_PENDING;    return;cs_failed:    cs_error(link->handle, last_fn, last_ret);config_failed:    ray_release((u_long)link);    link->state &= ~DEV_CONFIG_PENDING;} /* ray_config *//*===========================================================================*/static int ray_init(struct net_device *dev){    int i;    UCHAR *p;    struct ccs *pccs;    ray_dev_t *local = (ray_dev_t *)dev->priv;    dev_link_t *link = local->finder;    DEBUG(1, "ray_init(0x%p)\n", dev);    if (!(link->state & DEV_PRESENT)) {        printk(KERN_INFO "ray_init - device not present\n");        return -1;    }    local->net_type = net_type;    local->sta_type = TYPE_STA;    spin_lock(&local->ray_lock);    /* Copy the startup results to local memory */    memcpy_fromio(&local->startup_res, local->sram + ECF_TO_HOST_BASE,\           sizeof(struct startup_res_6));    /* Check Power up test status and get mac address from card */    if (local->startup_res.startup_word != 0x80) {    printk(KERN_INFO "ray_init ERROR card status = %2x\n",           local->startup_res.startup_word);        local->card_status = CARD_INIT_ERROR;        spin_unlock(&local->ray_lock);        return -1;    }    local->fw_ver = local->startup_res.firmware_version[0];    local->fw_bld = local->startup_res.firmware_version[1];    local->fw_var = local->startup_res.firmware_version[2];    DEBUG(1,"ray_init firmware version %d.%d \n",local->fw_ver, local->fw_bld);    local->tib_length = 0x20;    if ((local->fw_ver == 5) && (local->fw_bld >= 30))        local->tib_length = local->startup_res.tib_length;    DEBUG(2,"ray_init tib_length = 0x%02x\n", local->tib_length);    /* Initialize CCS's to buffer free state */    pccs = (struct ccs *)(local->sram + CCS_BASE);    for (i=0;  i<NUMBER_OF_CCS;  i++) {        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);    }    init_startup_params(local);    /* copy mac address to startup parameters */    if (parse_addr(phy_addr, local->sparm.b4.a_mac_addr))    {        p = local->sparm.b4.a_mac_addr;    }    else    {        memcpy(&local->sparm.b4.a_mac_addr,               &local->startup_res.station_addr, ADDRLEN);        p = local->sparm.b4.a_mac_addr;    }    local->card_status = CARD_AWAITING_PARAM;    spin_unlock(&local->ray_lock);    DEBUG(2,"ray_init ending\n");    return 0;} /* ray_init *//*===========================================================================*//* Download startup parameters to the card and command it to read them       */static int dl_startup_params(struct net_device *dev){    int ccsindex;    ray_dev_t *local = (ray_dev_t *)dev->priv;    struct ccs *pccs;    dev_link_t *link = local->finder;    DEBUG(1,"dl_startup_params entered\n");    if (!(link->state & DEV_PRESENT)) {        DEBUG(2,"ray_cs dl_startup_params - device not present\n");        return -1;    }        /* Copy parameters to host to ECF area */    if (local->fw_ver == 0x55)         memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b4,               sizeof(struct b4_startup_params));    else        memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b5,               sizeof(struct b5_startup_params));        /* Fill in the CCS fields for the ECF */    if ((ccsindex = get_free_ccs(local)) < 0) return -1;    local->dl_param_ccs = ccsindex;    pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;    writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd);    DEBUG(2,"dl_startup_params start ccsindex = %d\n", local->dl_param_ccs);    /* Interrupt the firmware to process the command */    if (interrupt_ecf(local, ccsindex)) {        printk(KERN_INFO "ray dl_startup_params failed - "           "ECF not ready for intr\n");        local->card_status = CARD_DL_PARAM_ERROR;        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);        return -2;    }    local->card_status = CARD_DL_PARAM;    /* Start kernel timer to wait for dl startup to complete. */    del_timer(&local->timer);   /* If already exist, remove */    local->timer.expires = jiffies + HZ/2;    local->timer.data = (long)local;    local->timer.function = &verify_dl_startup;    add_timer(&local->timer);    /* Parameters changed, so we need to re-authenticate */    local->authentication_state = UNAUTHENTICATED;    DEBUG(2,"ray_cs dl_startup_params started timer for verify_dl_startup\n");    return 0;} /* dl_startup_params *//*===========================================================================*/static void init_startup_params(ray_dev_t *local){    int i;     if (country > JAPAN_TEST) country = USA;    else        if (country < USA) country = USA;    /* structure for hop time and beacon period is defined here using 

⌨️ 快捷键说明

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