0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/slab.h>
0014 #include <linux/module.h>
0015 #include <linux/kernel.h>
0016 #include <linux/netdevice.h>
0017 #include <linux/etherdevice.h>
0018
0019 #include <pcmcia/cisreg.h>
0020 #include <pcmcia/cistpl.h>
0021 #include <pcmcia/ss.h>
0022 #include <pcmcia/ds.h>
0023 #include "cs_internal.h"
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
0036 cisdata_t code, void *parse)
0037 {
0038 tuple_t tuple;
0039 cisdata_t *buf;
0040 int ret;
0041
0042 buf = kmalloc(256, GFP_KERNEL);
0043 if (buf == NULL) {
0044 dev_warn(&s->dev, "no memory to read tuple\n");
0045 return -ENOMEM;
0046 }
0047 tuple.DesiredTuple = code;
0048 tuple.Attributes = 0;
0049 if (function == BIND_FN_ALL)
0050 tuple.Attributes = TUPLE_RETURN_COMMON;
0051 ret = pccard_get_first_tuple(s, function, &tuple);
0052 if (ret != 0)
0053 goto done;
0054 tuple.TupleData = buf;
0055 tuple.TupleOffset = 0;
0056 tuple.TupleDataMax = 255;
0057 ret = pccard_get_tuple_data(s, &tuple);
0058 if (ret != 0)
0059 goto done;
0060 ret = pcmcia_parse_tuple(&tuple, parse);
0061 done:
0062 kfree(buf);
0063 return ret;
0064 }
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 static int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
0083 cisdata_t code, cisparse_t *parse, void *priv_data,
0084 int (*loop_tuple) (tuple_t *tuple,
0085 cisparse_t *parse,
0086 void *priv_data))
0087 {
0088 tuple_t tuple;
0089 cisdata_t *buf;
0090 int ret;
0091
0092 buf = kzalloc(256, GFP_KERNEL);
0093 if (buf == NULL) {
0094 dev_warn(&s->dev, "no memory to read tuple\n");
0095 return -ENOMEM;
0096 }
0097
0098 tuple.TupleData = buf;
0099 tuple.TupleDataMax = 255;
0100 tuple.TupleOffset = 0;
0101 tuple.DesiredTuple = code;
0102 tuple.Attributes = 0;
0103
0104 ret = pccard_get_first_tuple(s, function, &tuple);
0105 while (!ret) {
0106 if (pccard_get_tuple_data(s, &tuple))
0107 goto next_entry;
0108
0109 if (parse)
0110 if (pcmcia_parse_tuple(&tuple, parse))
0111 goto next_entry;
0112
0113 ret = loop_tuple(&tuple, parse, priv_data);
0114 if (!ret)
0115 break;
0116
0117 next_entry:
0118 ret = pccard_get_next_tuple(s, function, &tuple);
0119 }
0120
0121 kfree(buf);
0122 return ret;
0123 }
0124
0125
0126
0127
0128
0129 static int pcmcia_io_cfg_data_width(unsigned int flags)
0130 {
0131 if (!(flags & CISTPL_IO_8BIT))
0132 return IO_DATA_PATH_WIDTH_16;
0133 if (!(flags & CISTPL_IO_16BIT))
0134 return IO_DATA_PATH_WIDTH_8;
0135 return IO_DATA_PATH_WIDTH_AUTO;
0136 }
0137
0138
0139 struct pcmcia_cfg_mem {
0140 struct pcmcia_device *p_dev;
0141 int (*conf_check) (struct pcmcia_device *p_dev, void *priv_data);
0142 void *priv_data;
0143 cisparse_t parse;
0144 cistpl_cftable_entry_t dflt;
0145 };
0146
0147
0148
0149
0150
0151
0152
0153
0154 static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
0155 {
0156 struct pcmcia_cfg_mem *cfg_mem = priv;
0157 struct pcmcia_device *p_dev = cfg_mem->p_dev;
0158 cistpl_cftable_entry_t *cfg = &parse->cftable_entry;
0159 cistpl_cftable_entry_t *dflt = &cfg_mem->dflt;
0160 unsigned int flags = p_dev->config_flags;
0161 unsigned int vcc = p_dev->socket->socket.Vcc;
0162
0163 dev_dbg(&p_dev->dev, "testing configuration %x, autoconf %x\n",
0164 cfg->index, flags);
0165
0166
0167 cfg_mem->p_dev->config_index = cfg->index;
0168 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
0169 cfg_mem->dflt = *cfg;
0170
0171
0172 if (flags & CONF_AUTO_CHECK_VCC) {
0173 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
0174 if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
0175 return -ENODEV;
0176 } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
0177 if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
0178 return -ENODEV;
0179 }
0180 }
0181
0182
0183 if (flags & CONF_AUTO_SET_VPP) {
0184 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
0185 p_dev->vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
0186 else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
0187 p_dev->vpp =
0188 dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
0189 }
0190
0191
0192 if ((flags & CONF_AUTO_AUDIO) && (cfg->flags & CISTPL_CFTABLE_AUDIO))
0193 p_dev->config_flags |= CONF_ENABLE_SPKR;
0194
0195
0196
0197 if (flags & CONF_AUTO_SET_IO) {
0198 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
0199 int i = 0;
0200
0201 p_dev->resource[0]->start = p_dev->resource[0]->end = 0;
0202 p_dev->resource[1]->start = p_dev->resource[1]->end = 0;
0203 if (io->nwin == 0)
0204 return -ENODEV;
0205
0206 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
0207 p_dev->resource[0]->flags |=
0208 pcmcia_io_cfg_data_width(io->flags);
0209 if (io->nwin > 1) {
0210
0211
0212
0213 i = (io->win[1].len > io->win[0].len);
0214 p_dev->resource[1]->flags = p_dev->resource[0]->flags;
0215 p_dev->resource[1]->start = io->win[1-i].base;
0216 p_dev->resource[1]->end = io->win[1-i].len;
0217 }
0218 p_dev->resource[0]->start = io->win[i].base;
0219 p_dev->resource[0]->end = io->win[i].len;
0220 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
0221 }
0222
0223
0224 if (flags & CONF_AUTO_SET_IOMEM) {
0225
0226 cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
0227
0228 p_dev->resource[2]->start = p_dev->resource[2]->end = 0;
0229 if (mem->nwin == 0)
0230 return -ENODEV;
0231
0232 p_dev->resource[2]->start = mem->win[0].host_addr;
0233 p_dev->resource[2]->end = mem->win[0].len;
0234 if (p_dev->resource[2]->end < 0x1000)
0235 p_dev->resource[2]->end = 0x1000;
0236 p_dev->card_addr = mem->win[0].card_addr;
0237 }
0238
0239 dev_dbg(&p_dev->dev,
0240 "checking configuration %x: %pr %pr %pr (%d lines)\n",
0241 p_dev->config_index, p_dev->resource[0], p_dev->resource[1],
0242 p_dev->resource[2], p_dev->io_lines);
0243
0244 return cfg_mem->conf_check(p_dev, cfg_mem->priv_data);
0245 }
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259 int pcmcia_loop_config(struct pcmcia_device *p_dev,
0260 int (*conf_check) (struct pcmcia_device *p_dev,
0261 void *priv_data),
0262 void *priv_data)
0263 {
0264 struct pcmcia_cfg_mem *cfg_mem;
0265 int ret;
0266
0267 cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
0268 if (cfg_mem == NULL)
0269 return -ENOMEM;
0270
0271 cfg_mem->p_dev = p_dev;
0272 cfg_mem->conf_check = conf_check;
0273 cfg_mem->priv_data = priv_data;
0274
0275 ret = pccard_loop_tuple(p_dev->socket, p_dev->func,
0276 CISTPL_CFTABLE_ENTRY, &cfg_mem->parse,
0277 cfg_mem, pcmcia_do_loop_config);
0278
0279 kfree(cfg_mem);
0280 return ret;
0281 }
0282 EXPORT_SYMBOL(pcmcia_loop_config);
0283
0284
0285 struct pcmcia_loop_mem {
0286 struct pcmcia_device *p_dev;
0287 void *priv_data;
0288 int (*loop_tuple) (struct pcmcia_device *p_dev,
0289 tuple_t *tuple,
0290 void *priv_data);
0291 };
0292
0293
0294
0295
0296
0297
0298
0299
0300 static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv)
0301 {
0302 struct pcmcia_loop_mem *loop = priv;
0303
0304 return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data);
0305 };
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319 int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
0320 int (*loop_tuple) (struct pcmcia_device *p_dev,
0321 tuple_t *tuple,
0322 void *priv_data),
0323 void *priv_data)
0324 {
0325 struct pcmcia_loop_mem loop = {
0326 .p_dev = p_dev,
0327 .loop_tuple = loop_tuple,
0328 .priv_data = priv_data};
0329
0330 return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL,
0331 &loop, pcmcia_do_loop_tuple);
0332 }
0333 EXPORT_SYMBOL(pcmcia_loop_tuple);
0334
0335
0336 struct pcmcia_loop_get {
0337 size_t len;
0338 cisdata_t **buf;
0339 };
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350 static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple,
0351 void *priv)
0352 {
0353 struct pcmcia_loop_get *get = priv;
0354
0355 *get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL);
0356 if (*get->buf) {
0357 get->len = tuple->TupleDataLen;
0358 memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen);
0359 } else
0360 dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n");
0361 return 0;
0362 }
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374 size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code,
0375 unsigned char **buf)
0376 {
0377 struct pcmcia_loop_get get = {
0378 .len = 0,
0379 .buf = buf,
0380 };
0381
0382 *get.buf = NULL;
0383 pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get);
0384
0385 return get.len;
0386 }
0387 EXPORT_SYMBOL(pcmcia_get_tuple);
0388
0389 #ifdef CONFIG_NET
0390
0391
0392
0393
0394
0395
0396
0397
0398 static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple,
0399 void *priv)
0400 {
0401 struct net_device *dev = priv;
0402
0403 if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
0404 return -EINVAL;
0405 if (tuple->TupleDataLen < ETH_ALEN + 2) {
0406 dev_warn(&p_dev->dev, "Invalid CIS tuple length for "
0407 "LAN_NODE_ID\n");
0408 return -EINVAL;
0409 }
0410
0411 if (tuple->TupleData[1] != ETH_ALEN) {
0412 dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n");
0413 return -EINVAL;
0414 }
0415 eth_hw_addr_set(dev, &tuple->TupleData[2]);
0416 return 0;
0417 }
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428 int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev)
0429 {
0430 return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev);
0431 }
0432 EXPORT_SYMBOL(pcmcia_get_mac_from_cis);
0433
0434 #endif