Hey,

On Sun, Oct 25, 2009 at 07:44:09PM +0900, Komuro wrote:
> CISTPL_FUNCE_LAN_NODE_ID format is
>    04 06 yy yy yy yy yy yy ff.
> yy is mac address.
> so the length is 9.

Thanks for the clarification.

> but I want to add warning messeage.

Good idea. See code snippet below -- patch is unchanged otherwise.

Best,
        Dominik

From: Dominik Brodowski <[email protected]>
Date: Sun, 18 Oct 2009 23:32:33 +0200
Subject: [PATCH 06/10] pcmcia: add new CIS access helpers

As a replacement to pcmcia_get_{first,next}_tuple() and
pcmcia_get_tuple_data(), three new -- and easier to use --
functions are added:

- pcmcia_get_tuple() to get the very first CIS entry of one
  type.

- pcmcia_loop_tuple() to loop over all CIS entries of one type.

- pcmcia_get_mac_from_cis() to read out the hardware MAC address
  from CISTPL_FUNCE.

Only a handful of drivers need these functions anyway, as most
CIS access is already handled by pcmcia_loop_config(), which
now shares the same backed (pccard_loop_tuple()) with
pcmcia_loop_tuple().

A pcmcia_get_mac_from_cis() bug noted by Komuro
<[email protected]> has been fixed in this revision.

Signed-off-by: Dominik Brodowski <[email protected]>
---
 Documentation/pcmcia/driver-changes.txt |    7 +
 drivers/pcmcia/cistpl.c                 |   61 +++++++++
 drivers/pcmcia/cs_internal.h            |    7 +
 drivers/pcmcia/pcmcia_resource.c        |  218 ++++++++++++++++++++++++++-----
 drivers/pcmcia/rsrc_mgr.c               |    1 +
 include/pcmcia/ds.h                     |   57 ++++++--
 6 files changed, 305 insertions(+), 46 deletions(-)


...

+/**
+ * pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis()
+ *
+ * pcmcia_do_get_mac() is the internal callback for the call from
+ * pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the
+ * tuple contains a proper LAN_NODE_ID of length 6, and copy the data
+ * to struct net_device->dev_addr[i].
+ */
+static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple,
+                            void *priv)
+{
+       struct net_device *dev = priv;
+       int i;
+
+       if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
+               return -EINVAL;
+       if ((tuple->TupleDataLen < ETH_ALEN + 2) || 
+           (tuple->TupleDataLen > ETH_ALEN + 3)) {
+               dev_warn(&p_dev->dev, "Invalid CIS tuple length for "
+                       "LAN_NODE_ID\n");
+               return -EINVAL;
+       }
+
+       if (tuple->TupleData[1] != ETH_ALEN) {
+               dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n");
+               return -EINVAL;
+       }
+       for (i = 0; i < 6; i++)
+               dev->dev_addr[i] = tuple->TupleData[i+2];
+       return 0;
+};
+
+/**
+ * pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE
+ * @p_dev:     the struct pcmcia_device for which we want the address.
+ * @dev:       a properly prepared struct net_device to store the info to.
+ *
+ * pcmcia_get_mac_from_cis() reads out the hardware MAC address from
+ * CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which
+ * must be set up properly by the driver (see examples!).
+ */
+int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device 
*dev)
+{
+       return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev);
+};
+EXPORT_SYMBOL(pcmcia_get_mac_from_cis);

_______________________________________________
Linux PCMCIA reimplementation list
http://lists.infradead.org/mailman/listinfo/linux-pcmcia

Reply via email to