platform_set_drvdata 和 platform_get_drvdata

来源:互联网 发布:access vba编程入门 编辑:程序博客网 时间:2024/06/15 14:19

原文地址:http://blog.chinaunix.net/uid-25932176-id-3063323.html

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  93.     dm9000_reset(db);

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

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

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

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

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

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

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

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

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

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

  137.     mac_src = "eeprom";

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

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

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

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

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

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

  166.     dm9000_release_board(pdev, db);
  167.     free_netdev(ndev);

  168.     return ret;
  169. }

原创粉丝点击