Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1416346
  • 博文数量: 1334
  • 博客积分: 645
  • 博客等级: 上士
  • 技术积分: 5762
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-25 16:56
文章分类

全部博文(1334)

文章存档

2014年(108)

2013年(1059)

2012年(169)

分类: 嵌入式

2013-10-17 14:44:55

    ndev是我们在probe函数中定义的局部变量,如果我想在其他地方使用它怎么办呢? 这就需要把它保存起来。内核提供了这个方法,使用函数platform_set_drvdata()可以将ndev保存成平台总线设备的私有数据。以后再要使用它时只需调用platform_get_drvdata()就可以了。
 
  1. static int __devinit
  2. dm9000_probe(struct platform_device *pdev)
  3. {
  4.     struct dm9000_plat_data *pdata = pdev->dev.platform_data;
  5.     struct board_info *db;    /* Point a board information structure */
  6.     struct net_device *ndev;
  7.     const unsigned char *mac_src;
  8.     int ret = 0;
  9.     int iosize;
  10.     int i;
  11.     u32 id_val;

  12.     /* Init network device */
  13.         /*使用alloc_etherdev()来生成一个net_device结构体,并对其公有成员赋值*/
  14.     ndev = alloc_etherdev(sizeof(struct board_info));
  15.     if (!ndev) {
  16.         dev_err(&pdev->dev, "could not allocate device./n");
  17.         return -ENOMEM;
  18.     }

  19.     SET_NETDEV_DEV(ndev, &pdev->dev);

  20.     dev_dbg(&pdev->dev, "dm9000_probe()/n");

  21.     /* setup board info structure */
  22.     db = netdev_priv(ndev);
  23.     memset(db, 0, sizeof(*db));

  24.     db->dev = &pdev->dev;
  25.     db->ndev = ndev;

  26.     spin_lock_init(&db->lock);
  27.     mutex_init(&db->addr_lock);

  28.     INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);

  29.     db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  30.     db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  31.     db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);

  32.     if (db->addr_res == NULL || db->data_res == NULL ||
  33.      db->irq_res == NULL) {
  34.         dev_err(db->dev, "insufficient resources/n");
  35.         ret = -ENOENT;
  36.         goto out;
  37.     }

  38.     iosize = res_size(db->addr_res);
  39.     db->addr_req = request_mem_region(db->addr_res->start, iosize,
  40.                      pdev->name);

  41.     if (db->addr_req == NULL) {
  42.         dev_err(db->dev, "cannot claim address reg area/n");
  43.         ret = -EIO;
  44.         goto out;
  45.     }

  46.     db->io_addr = ioremap(db->addr_res->start, iosize);

  47.     if (db->io_addr == NULL) {
  48.         dev_err(db->dev, "failed to ioremap address reg/n");
  49.         ret = -EINVAL;
  50.         goto out;
  51.     }

  52.     iosize = res_size(db->data_res);
  53.     db->data_req = request_mem_region(db->data_res->start, iosize,
  54.                      pdev->name);

  55.     if (db->data_req == NULL) {
  56.         dev_err(db->dev, "cannot claim data reg area/n");
  57.         ret = -EIO;
  58.         goto out;
  59.     }

  60.     db->io_data = ioremap(db->data_res->start, iosize);

  61.     if (db->io_data == NULL) {
  62.         dev_err(db->dev, "failed to ioremap data reg/n");
  63.         ret = -EINVAL;
  64.         goto out;
  65.     }

  66.     /* fill in parameters for net-dev structure */
  67.     ndev->base_addr = (unsigned long)db->io_addr;
  68.     ndev->irq    = db->irq_res->start;

  69.     /* ensure at least we have a default set of IO routines */
  70.     dm9000_set_io(db, iosize);

  71.     /* check to see if anything is being over-ridden */
  72.     if (pdata != NULL) {
  73.         /* check to see if the driver wants to over-ride the
  74.          * default IO width */

  75.         if (pdata->flags & DM9000_PLATF_8BITONLY)
  76.             dm9000_set_io(db, 1);

  77.         if (pdata->flags & DM9000_PLATF_16BITONLY)
  78.             dm9000_set_io(db, 2);

  79.         if (pdata->flags & DM9000_PLATF_32BITONLY)
  80.             dm9000_set_io(db, 4);

  81.         /* check to see if there are any IO routine
  82.          * over-rides */

  83.         if (pdata->inblk != NULL)
  84.             db->inblk = pdata->inblk;

  85.         if (pdata->outblk != NULL)
  86.             db->outblk = pdata->outblk;

  87.         if (pdata->dumpblk != NULL)
  88.             db->dumpblk = pdata->dumpblk;

  89.         db->flags = pdata->flags;
  90.     }

  91. #ifdef CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL
  92.     db->flags |= DM9000_PLATF_SIMPLE_PHY;
  93. #endif

  94.     dm9000_reset(db);

  95.     /* try multiple times, DM9000 sometimes gets the read wrong */
  96.     for (i = 0; i < 8; i++) {
  97.         id_val = ior(db, DM9000_VIDL);
  98.         id_val |= (u32)ior(db, DM9000_VIDH) << 8;
  99.         id_val |= (u32)ior(db, DM9000_PIDL) << 16;
  100.         id_val |= (u32)ior(db, DM9000_PIDH) << 24;

  101.         if (id_val == DM9000_ID)
  102.             break;
  103.         dev_err(db->dev, "read wrong id 0x%08x/n", id_val);
  104.     }

  105.     if (id_val != DM9000_ID) {
  106.         dev_err(db->dev, "wrong id: 0x%08x/n", id_val);
  107.         ret = -ENODEV;
  108.         goto out;
  109.     }

  110.     /* Identify what type of DM9000 we are working on */

  111.     id_val = ior(db, DM9000_CHIPR);
  112.     dev_dbg(db->dev, "dm9000 revision 0x%02x/n", id_val);

  113.     switch (id_val) {
  114.     case CHIPR_DM9000A:
  115.         db->type = TYPE_DM9000A;
  116.         break;
  117.     case CHIPR_DM9000B:
  118.         db->type = TYPE_DM9000B;
  119.         break;
  120.     default:
  121.         dev_dbg(db->dev, "ID %02x => defaulting to DM9000E/n", id_val);
  122.         db->type = TYPE_DM9000E;
  123.     }

  124.     /* from this point we assume that we have found a DM9000 */

  125.     /* driver system function */
  126.     ether_setup(ndev);

  127.     ndev->netdev_ops    = &dm9000_netdev_ops;
  128.     ndev->watchdog_timeo    = msecs_to_jiffies(watchdog);
  129.     ndev->ethtool_ops    = &dm9000_ethtool_ops;

  130.     db->msg_enable = NETIF_MSG_LINK;
  131.     db->mii.phy_id_mask = 0x1f;
  132.     db->mii.reg_num_mask = 0x1f;
  133.     db->mii.force_media = 0;
  134.     db->mii.full_duplex = 0;
  135.     db->mii.dev     = ndev;
  136.     db->mii.mdio_read = dm9000_phy_read;
  137.     db->mii.mdio_write = dm9000_phy_write;

  138.     mac_src = "eeprom";

  139.     /* try reading the node address from the attached EEPROM */
  140.     for (i = 0; i < 6; i += 2)
  141.         dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);

  142.     if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {
  143.         mac_src = "platform data";
  144.         memcpy(ndev->dev_addr, pdata->dev_addr, 6);
  145.     }

  146.     if (!is_valid_ether_addr(ndev->dev_addr)) {
  147.         /* try reading from mac */
  148.         
  149.         mac_src = "chip";
  150.         for (i = 0; i < 6; i++)
  151.             ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
  152.     }

  153.     if (!is_valid_ether_addr(ndev->dev_addr))
  154.         dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
  155.              "set using ifconfig/n", ndev->name);
  156.     //platform_set_drvdata()可以将ndev保存成平台总线设备的私有数据。以后再要使用它时只需调用
  157.     //platform_get_drvdata()就可以了
  158.     platform_set_drvdata(pdev, ndev);
  159.     ret = register_netdev(ndev);

  160.     if (ret == 0)
  161.         printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %pM (%s)/n",
  162.          ndev->name, dm9000_type_to_char(db->type),
  163.          db->io_addr, db->io_data, ndev->irq,
  164.          ndev->dev_addr, mac_src);
  165.     return 0;

  166. out:
  167.     dev_err(db->dev, "not found (%d)./n", ret);

  168.     dm9000_release_board(pdev, db);
  169.     free_netdev(ndev);

  170.     return ret;
  171. }

 

 

阅读(547) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~