linux/drivers/pcmcia/pcmcia_cis.c
<<
>>
Prefs
   1/*
   2 * PCMCIA high-level CIS access functions
   3 *
   4 * The initial developer of the original code is David A. Hinds
   5 * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
   6 * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
   7 *
   8 * Copyright (C) 1999        David A. Hinds
   9 * Copyright (C) 2004-2009   Dominik Brodowski
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License version 2 as
  13 * published by the Free Software Foundation.
  14 *
  15 */
  16
  17#include <linux/slab.h>
  18#include <linux/module.h>
  19#include <linux/kernel.h>
  20#include <linux/netdevice.h>
  21
  22#include <pcmcia/cs_types.h>
  23#include <pcmcia/cisreg.h>
  24#include <pcmcia/cistpl.h>
  25#include <pcmcia/ss.h>
  26#include <pcmcia/cs.h>
  27#include <pcmcia/ds.h>
  28#include "cs_internal.h"
  29
  30
  31/**
  32 * pccard_read_tuple() - internal CIS tuple access
  33 * @s:          the struct pcmcia_socket where the card is inserted
  34 * @function:   the device function we loop for
  35 * @code:       which CIS code shall we look for?
  36 * @parse:      buffer where the tuple shall be parsed (or NULL, if no parse)
  37 *
  38 * pccard_read_tuple() reads out one tuple and attempts to parse it
  39 */
  40int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
  41                cisdata_t code, void *parse)
  42{
  43        tuple_t tuple;
  44        cisdata_t *buf;
  45        int ret;
  46
  47        buf = kmalloc(256, GFP_KERNEL);
  48        if (buf == NULL) {
  49                dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
  50                return -ENOMEM;
  51        }
  52        tuple.DesiredTuple = code;
  53        tuple.Attributes = 0;
  54        if (function == BIND_FN_ALL)
  55                tuple.Attributes = TUPLE_RETURN_COMMON;
  56        ret = pccard_get_first_tuple(s, function, &tuple);
  57        if (ret != 0)
  58                goto done;
  59        tuple.TupleData = buf;
  60        tuple.TupleOffset = 0;
  61        tuple.TupleDataMax = 255;
  62        ret = pccard_get_tuple_data(s, &tuple);
  63        if (ret != 0)
  64                goto done;
  65        ret = pcmcia_parse_tuple(&tuple, parse);
  66done:
  67        kfree(buf);
  68        return ret;
  69}
  70
  71
  72/**
  73 * pccard_loop_tuple() - loop over tuples in the CIS
  74 * @s:          the struct pcmcia_socket where the card is inserted
  75 * @function:   the device function we loop for
  76 * @code:       which CIS code shall we look for?
  77 * @parse:      buffer where the tuple shall be parsed (or NULL, if no parse)
  78 * @priv_data:  private data to be passed to the loop_tuple function.
  79 * @loop_tuple: function to call for each CIS entry of type @function. IT
  80 *              gets passed the raw tuple, the paresed tuple (if @parse is
  81 *              set) and @priv_data.
  82 *
  83 * pccard_loop_tuple() loops over all CIS entries of type @function, and
  84 * calls the @loop_tuple function for each entry. If the call to @loop_tuple
  85 * returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
  86 */
  87int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
  88                      cisdata_t code, cisparse_t *parse, void *priv_data,
  89                      int (*loop_tuple) (tuple_t *tuple,
  90                                         cisparse_t *parse,
  91                                         void *priv_data))
  92{
  93        tuple_t tuple;
  94        cisdata_t *buf;
  95        int ret;
  96
  97        buf = kzalloc(256, GFP_KERNEL);
  98        if (buf == NULL) {
  99                dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
 100                return -ENOMEM;
 101        }
 102
 103        tuple.TupleData = buf;
 104        tuple.TupleDataMax = 255;
 105        tuple.TupleOffset = 0;
 106        tuple.DesiredTuple = code;
 107        tuple.Attributes = 0;
 108
 109        ret = pccard_get_first_tuple(s, function, &tuple);
 110        while (!ret) {
 111                if (pccard_get_tuple_data(s, &tuple))
 112                        goto next_entry;
 113
 114                if (parse)
 115                        if (pcmcia_parse_tuple(&tuple, parse))
 116                                goto next_entry;
 117
 118                ret = loop_tuple(&tuple, parse, priv_data);
 119                if (!ret)
 120                        break;
 121
 122next_entry:
 123                ret = pccard_get_next_tuple(s, function, &tuple);
 124        }
 125
 126        kfree(buf);
 127        return ret;
 128}
 129
 130struct pcmcia_cfg_mem {
 131        struct pcmcia_device *p_dev;
 132        void *priv_data;
 133        int (*conf_check) (struct pcmcia_device *p_dev,
 134                           cistpl_cftable_entry_t *cfg,
 135                           cistpl_cftable_entry_t *dflt,
 136                           unsigned int vcc,
 137                           void *priv_data);
 138        cisparse_t parse;
 139        cistpl_cftable_entry_t dflt;
 140};
 141
 142/**
 143 * pcmcia_do_loop_config() - internal helper for pcmcia_loop_config()
 144 *
 145 * pcmcia_do_loop_config() is the internal callback for the call from
 146 * pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred
 147 * by a struct pcmcia_cfg_mem.
 148 */
 149static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
 150{
 151        cistpl_cftable_entry_t *cfg = &parse->cftable_entry;
 152        struct pcmcia_cfg_mem *cfg_mem = priv;
 153
 154        /* default values */
 155        cfg_mem->p_dev->conf.ConfigIndex = cfg->index;
 156        if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
 157                cfg_mem->dflt = *cfg;
 158
 159        return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt,
 160                                   cfg_mem->p_dev->socket->socket.Vcc,
 161                                   cfg_mem->priv_data);
 162}
 163
 164/**
 165 * pcmcia_loop_config() - loop over configuration options
 166 * @p_dev:      the struct pcmcia_device which we need to loop for.
 167 * @conf_check: function to call for each configuration option.
 168 *              It gets passed the struct pcmcia_device, the CIS data
 169 *              describing the configuration option, and private data
 170 *              being passed to pcmcia_loop_config()
 171 * @priv_data:  private data to be passed to the conf_check function.
 172 *
 173 * pcmcia_loop_config() loops over all configuration options, and calls
 174 * the driver-specific conf_check() for each one, checking whether
 175 * it is a valid one. Returns 0 on success or errorcode otherwise.
 176 */
 177int pcmcia_loop_config(struct pcmcia_device *p_dev,
 178                       int      (*conf_check)   (struct pcmcia_device *p_dev,
 179                                                 cistpl_cftable_entry_t *cfg,
 180                                                 cistpl_cftable_entry_t *dflt,
 181                                                 unsigned int vcc,
 182                                                 void *priv_data),
 183                       void *priv_data)
 184{
 185        struct pcmcia_cfg_mem *cfg_mem;
 186        int ret;
 187
 188        cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
 189        if (cfg_mem == NULL)
 190                return -ENOMEM;
 191
 192        cfg_mem->p_dev = p_dev;
 193        cfg_mem->conf_check = conf_check;
 194        cfg_mem->priv_data = priv_data;
 195
 196        ret = pccard_loop_tuple(p_dev->socket, p_dev->func,
 197                                CISTPL_CFTABLE_ENTRY, &cfg_mem->parse,
 198                                cfg_mem, pcmcia_do_loop_config);
 199
 200        kfree(cfg_mem);
 201        return ret;
 202}
 203EXPORT_SYMBOL(pcmcia_loop_config);
 204
 205
 206struct pcmcia_loop_mem {
 207        struct pcmcia_device *p_dev;
 208        void *priv_data;
 209        int (*loop_tuple) (struct pcmcia_device *p_dev,
 210                           tuple_t *tuple,
 211                           void *priv_data);
 212};
 213
 214/**
 215 * pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config()
 216 *
 217 * pcmcia_do_loop_tuple() is the internal callback for the call from
 218 * pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred
 219 * by a struct pcmcia_cfg_mem.
 220 */
 221static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv)
 222{
 223        struct pcmcia_loop_mem *loop = priv;
 224
 225        return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data);
 226};
 227
 228/**
 229 * pcmcia_loop_tuple() - loop over tuples in the CIS
 230 * @p_dev:      the struct pcmcia_device which we need to loop for.
 231 * @code:       which CIS code shall we look for?
 232 * @priv_data:  private data to be passed to the loop_tuple function.
 233 * @loop_tuple: function to call for each CIS entry of type @function. IT
 234 *              gets passed the raw tuple and @priv_data.
 235 *
 236 * pcmcia_loop_tuple() loops over all CIS entries of type @function, and
 237 * calls the @loop_tuple function for each entry. If the call to @loop_tuple
 238 * returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
 239 */
 240int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
 241                      int (*loop_tuple) (struct pcmcia_device *p_dev,
 242                                         tuple_t *tuple,
 243                                         void *priv_data),
 244                      void *priv_data)
 245{
 246        struct pcmcia_loop_mem loop = {
 247                .p_dev = p_dev,
 248                .loop_tuple = loop_tuple,
 249                .priv_data = priv_data};
 250
 251        return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL,
 252                                 &loop, pcmcia_do_loop_tuple);
 253}
 254EXPORT_SYMBOL(pcmcia_loop_tuple);
 255
 256
 257struct pcmcia_loop_get {
 258        size_t len;
 259        cisdata_t **buf;
 260};
 261
 262/**
 263 * pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple()
 264 *
 265 * pcmcia_do_get_tuple() is the internal callback for the call from
 266 * pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in
 267 * the first tuple, return 0 unconditionally. Create a memory buffer large
 268 * enough to hold the content of the tuple, and fill it with the tuple data.
 269 * The caller is responsible to free the buffer.
 270 */
 271static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple,
 272                               void *priv)
 273{
 274        struct pcmcia_loop_get *get = priv;
 275
 276        *get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL);
 277        if (*get->buf) {
 278                get->len = tuple->TupleDataLen;
 279                memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen);
 280        } else
 281                dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n");
 282        return 0;
 283}
 284
 285/**
 286 * pcmcia_get_tuple() - get first tuple from CIS
 287 * @p_dev:      the struct pcmcia_device which we need to loop for.
 288 * @code:       which CIS code shall we look for?
 289 * @buf:        pointer to store the buffer to.
 290 *
 291 * pcmcia_get_tuple() gets the content of the first CIS entry of type @code.
 292 * It returns the buffer length (or zero). The caller is responsible to free
 293 * the buffer passed in @buf.
 294 */
 295size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code,
 296                        unsigned char **buf)
 297{
 298        struct pcmcia_loop_get get = {
 299                .len = 0,
 300                .buf = buf,
 301        };
 302
 303        *get.buf = NULL;
 304        pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get);
 305
 306        return get.len;
 307}
 308EXPORT_SYMBOL(pcmcia_get_tuple);
 309
 310
 311/**
 312 * pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis()
 313 *
 314 * pcmcia_do_get_mac() is the internal callback for the call from
 315 * pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the
 316 * tuple contains a proper LAN_NODE_ID of length 6, and copy the data
 317 * to struct net_device->dev_addr[i].
 318 */
 319static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple,
 320                             void *priv)
 321{
 322        struct net_device *dev = priv;
 323        int i;
 324
 325        if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
 326                return -EINVAL;
 327        if (tuple->TupleDataLen < ETH_ALEN + 2) {
 328                dev_warn(&p_dev->dev, "Invalid CIS tuple length for "
 329                        "LAN_NODE_ID\n");
 330                return -EINVAL;
 331        }
 332
 333        if (tuple->TupleData[1] != ETH_ALEN) {
 334                dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n");
 335                return -EINVAL;
 336        }
 337        for (i = 0; i < 6; i++)
 338                dev->dev_addr[i] = tuple->TupleData[i+2];
 339        return 0;
 340}
 341
 342/**
 343 * pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE
 344 * @p_dev:      the struct pcmcia_device for which we want the address.
 345 * @dev:        a properly prepared struct net_device to store the info to.
 346 *
 347 * pcmcia_get_mac_from_cis() reads out the hardware MAC address from
 348 * CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which
 349 * must be set up properly by the driver (see examples!).
 350 */
 351int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev)
 352{
 353        return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev);
 354}
 355EXPORT_SYMBOL(pcmcia_get_mac_from_cis);
 356
 357
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.