Chinaunix首页 | 论坛 | 博客
  • 博客访问: 70765
  • 博文数量: 11
  • 博客积分: 210
  • 博客等级: 入伍新兵
  • 技术积分: 94
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-19 18:13
文章分类
文章存档

2013年(4)

2012年(2)

2011年(5)

分类: 嵌入式

2013-06-04 08:49:20

首先是平台设备的register和unregister. 点击(此处)折叠或打开 /* * Search DM9000 board, allocate space and register it */static int __devinitdm9000_probe(struct platform_device *pdev){    struct dm9000_plat_data *pdata = pdev->dev.platform_data;    struct board_info *db;    /* Point a board information structure */    struct net_device *ndev;    const unsigned char *mac_src;    int ret = 0;    int iosize;    int i;    u32 id_val;    /* Init network device */    ndev = alloc_etherdev(sizeof(struct board_info));    if (!ndev) {        dev_err(&pdev->dev, "could not allocate device.n");        return -ENOMEM;    }    SET_NETDEV_DEV(ndev, &pdev->dev);    dev_dbg(&pdev->dev, "dm9000_probe()n");    /* setup board info structure */    db = netdev_priv(ndev);    db->dev = &pdev->dev;    db->ndev = ndev;    spin_lock_init(&db->lock);    mutex_init(&db->addr_lock);    INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);    db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);    db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);    db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);    if (db->addr_res == NULL || db->data_res == NULL ||     db->irq_res == NULL) {        dev_err(db->dev, "insufficient resourcesn");        ret = -ENOENT;        goto out;    }    iosize = resource_size(db->addr_res);    db->addr_req = request_mem_region(db->addr_res->start, iosize,                     pdev->name);    if (db->addr_req == NULL) {        dev_err(db->dev, "cannot claim address reg arean");        ret = -EIO;        goto out;    }    db->io_addr = ioremap(db->addr_res->start, iosize);    if (db->io_addr == NULL) {        dev_err(db->dev, "failed to ioremap address regn");        ret = -EINVAL;        goto out;    }    iosize = resource_size(db->data_res);    db->data_req = request_mem_region(db->data_res->start, iosize,                     pdev->name);    if (db->data_req == NULL) {        dev_err(db->dev, "cannot claim data reg arean");        ret = -EIO;        goto out;    }    db->io_data = ioremap(db->data_res->start, iosize);    if (db->io_data == NULL) {        dev_err(db->dev, "failed to ioremap data regn");        ret = -EINVAL;        goto out;    }    /* fill in parameters for net-dev structure */    ndev->base_addr = (unsigned long)db->io_addr;    ndev->irq    = db->irq_res->start;    /* ensure at least we have a default set of IO routines */    dm9000_set_io(db, iosize);    /* check to see if anything is being over-ridden */    if (pdata != NULL) {        /* check to see if the driver wants to over-ride the         * default IO width */        if (pdata->flags & DM9000_PLATF_8BITONLY)            dm9000_set_io(db, 1);        if (pdata->flags & DM9000_PLATF_16BITONLY)            dm9000_set_io(db, 2);        if (pdata->flags & DM9000_PLATF_32BITONLY)            dm9000_set_io(db, 4);        /* check to see if there are any IO routine         * over-rides */        if (pdata->inblk != NULL)            db->inblk = pdata->inblk;        if (pdata->outblk != NULL)            db->outblk = pdata->outblk;        if (pdata->dumpblk != NULL)            db->dumpblk = pdata->dumpblk;        db->flags = pdata->flags;    }#ifdef CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL    db->flags |= DM9000_PLATF_SIMPLE_PHY;#endif    dm9000_reset(db);    /* try multiple times, DM9000 sometimes gets the read wrong */    for (i = 0; i < 8; i++) {        id_val = ior(db, DM9000_VIDL);        id_val |= (u32)ior(db, DM9000_VIDH) << 8;        id_val |= (u32)ior(db, DM9000_PIDL) << 16;        id_val |= (u32)ior(db, DM9000_PIDH) << 24;        if (id_val == DM9000_ID)            break;        dev_err(db->dev, "read wrong id 0x%08xn", id_val);    }    if (id_val != DM9000_ID) {        dev_err(db->dev, "wrong id: 0x%08xn", id_val);        ret = -ENODEV;        goto out;    }    /* Identify what type of DM9000 we are working on */    id_val = ior(db, DM9000_CHIPR);    dev_dbg(db->dev, "dm9000 revision 0x%02xn", id_val);    switch (id_val) {    case CHIPR_DM9000A:        db->type = TYPE_DM9000A;        break;    case CHIPR_DM9000B:        db->type = TYPE_DM9000B;        break;    default:        dev_dbg(db->dev, "ID %02x => defaulting to DM9000En", id_val);        db->type = TYPE_DM9000E;    }    /* dm9000a/b are capable of hardware checksum offload */    if (db->type == TYPE_DM9000A || db->type == TYPE_DM9000B) {        db->can_csum = 1;        db->rx_csum = 1;        ndev->features |= NETIF_F_IP_CSUM;    }    /* from this point we assume that we have found a DM9000 */    /* driver system function */    ether_setup(ndev);    ndev->netdev_ops    = &dm9000_netdev_ops;    ndev->watchdog_timeo    = msecs_to_jiffies(watchdog);    ndev->ethtool_ops    = &dm9000_ethtool_ops;//    db->msg_enable = NETIF_MSG_LINK;    db->msg_enable = 0xffff;    db->mii.phy_id_mask = 0x1f;    db->mii.reg_num_mask = 0x1f;    db->mii.force_media = 0;    db->mii.full_duplex = 0;    db->mii.dev     = ndev;    db->mii.mdio_read = dm9000_phy_read;    db->mii.mdio_write = dm9000_phy_write;    mac_src = "eeprom";    /* try reading the node address from the attached EEPROM */    for (i = 0; i < 6; i += 2)        dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);    if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {        mac_src = "platform data";        memcpy(ndev->dev_addr, pdata->dev_addr, 6);    }    if (!is_valid_ether_addr(ndev->dev_addr)) {        /* try reading from mac */                mac_src = "chip";        for (i = 0; i < 6; i++)            ndev->dev_addr[i] = ior(db, i+DM9000_PAR);    }    memcpy(ndev->dev_addr, "x08x90x90x90x90x90", 6);    if (!is_valid_ether_addr(ndev->dev_addr))        dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "             "set using ifconfign", ndev->name);    platform_set_drvdata(pdev, ndev);    ret = register_netdev(ndev);    if (ret == 0)        printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %pM (%s)n",         ndev->name, dm9000_type_to_char(db->type),         db->io_addr, db->io_data, ndev->irq,         ndev->dev_addr, mac_src);    return 0;out:    dev_err(db->dev, "not found (%d).n", ret);    dm9000_release_board(pdev, db);    free_netdev(ndev);    return ret;}  
阅读(1663) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~