diff options
| -rw-r--r-- | drivers/pcmcia/Makefile | 2 | ||||
| -rw-r--r-- | drivers/pcmcia/cistpl.c | 100 | ||||
| -rw-r--r-- | drivers/pcmcia/pcmcia_cis.c | 355 | ||||
| -rw-r--r-- | drivers/pcmcia/pcmcia_resource.c | 229 |
4 files changed, 356 insertions, 330 deletions
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 381b031d9d75..8122b03e2ae5 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile | |||
| @@ -6,7 +6,7 @@ pcmcia_core-y += cs.o rsrc_mgr.o socket_sysfs.o | |||
| 6 | pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o | 6 | pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o |
| 7 | obj-$(CONFIG_PCCARD) += pcmcia_core.o | 7 | obj-$(CONFIG_PCCARD) += pcmcia_core.o |
| 8 | 8 | ||
| 9 | pcmcia-y += ds.o pcmcia_resource.o cistpl.o | 9 | pcmcia-y += ds.o pcmcia_resource.o cistpl.o pcmcia_cis.o |
| 10 | pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o | 10 | pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o |
| 11 | obj-$(CONFIG_PCMCIA) += pcmcia.o | 11 | obj-$(CONFIG_PCMCIA) += pcmcia.o |
| 12 | 12 | ||
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 854959cada3a..e0b09e71d5c0 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c | |||
| @@ -1362,106 +1362,6 @@ EXPORT_SYMBOL(pcmcia_parse_tuple); | |||
| 1362 | 1362 | ||
| 1363 | 1363 | ||
| 1364 | /** | 1364 | /** |
| 1365 | * pccard_read_tuple() - internal CIS tuple access | ||
| 1366 | * @s: the struct pcmcia_socket where the card is inserted | ||
| 1367 | * @function: the device function we loop for | ||
| 1368 | * @code: which CIS code shall we look for? | ||
| 1369 | * @parse: buffer where the tuple shall be parsed (or NULL, if no parse) | ||
| 1370 | * | ||
| 1371 | * pccard_read_tuple() reads out one tuple and attempts to parse it | ||
| 1372 | */ | ||
| 1373 | int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, | ||
| 1374 | cisdata_t code, void *parse) | ||
| 1375 | { | ||
| 1376 | tuple_t tuple; | ||
| 1377 | cisdata_t *buf; | ||
| 1378 | int ret; | ||
| 1379 | |||
| 1380 | buf = kmalloc(256, GFP_KERNEL); | ||
| 1381 | if (buf == NULL) { | ||
| 1382 | dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); | ||
| 1383 | return -ENOMEM; | ||
| 1384 | } | ||
| 1385 | tuple.DesiredTuple = code; | ||
| 1386 | tuple.Attributes = 0; | ||
| 1387 | if (function == BIND_FN_ALL) | ||
| 1388 | tuple.Attributes = TUPLE_RETURN_COMMON; | ||
| 1389 | ret = pccard_get_first_tuple(s, function, &tuple); | ||
| 1390 | if (ret != 0) | ||
| 1391 | goto done; | ||
| 1392 | tuple.TupleData = buf; | ||
| 1393 | tuple.TupleOffset = 0; | ||
| 1394 | tuple.TupleDataMax = 255; | ||
| 1395 | ret = pccard_get_tuple_data(s, &tuple); | ||
| 1396 | if (ret != 0) | ||
| 1397 | goto done; | ||
| 1398 | ret = pcmcia_parse_tuple(&tuple, parse); | ||
| 1399 | done: | ||
| 1400 | kfree(buf); | ||
| 1401 | return ret; | ||
| 1402 | } | ||
| 1403 | |||
| 1404 | |||
| 1405 | /** | ||
| 1406 | * pccard_loop_tuple() - loop over tuples in the CIS | ||
| 1407 | * @s: the struct pcmcia_socket where the card is inserted | ||
| 1408 | * @function: the device function we loop for | ||
| 1409 | * @code: which CIS code shall we look for? | ||
| 1410 | * @parse: buffer where the tuple shall be parsed (or NULL, if no parse) | ||
| 1411 | * @priv_data: private data to be passed to the loop_tuple function. | ||
| 1412 | * @loop_tuple: function to call for each CIS entry of type @function. IT | ||
| 1413 | * gets passed the raw tuple, the paresed tuple (if @parse is | ||
| 1414 | * set) and @priv_data. | ||
| 1415 | * | ||
| 1416 | * pccard_loop_tuple() loops over all CIS entries of type @function, and | ||
| 1417 | * calls the @loop_tuple function for each entry. If the call to @loop_tuple | ||
| 1418 | * returns 0, the loop exits. Returns 0 on success or errorcode otherwise. | ||
| 1419 | */ | ||
| 1420 | int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function, | ||
| 1421 | cisdata_t code, cisparse_t *parse, void *priv_data, | ||
| 1422 | int (*loop_tuple) (tuple_t *tuple, | ||
| 1423 | cisparse_t *parse, | ||
| 1424 | void *priv_data)) | ||
| 1425 | { | ||
| 1426 | tuple_t tuple; | ||
| 1427 | cisdata_t *buf; | ||
| 1428 | int ret; | ||
| 1429 | |||
| 1430 | buf = kzalloc(256, GFP_KERNEL); | ||
| 1431 | if (buf == NULL) { | ||
| 1432 | dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); | ||
| 1433 | return -ENOMEM; | ||
| 1434 | } | ||
| 1435 | |||
| 1436 | tuple.TupleData = buf; | ||
| 1437 | tuple.TupleDataMax = 255; | ||
| 1438 | tuple.TupleOffset = 0; | ||
| 1439 | tuple.DesiredTuple = code; | ||
| 1440 | tuple.Attributes = 0; | ||
| 1441 | |||
| 1442 | ret = pccard_get_first_tuple(s, function, &tuple); | ||
| 1443 | while (!ret) { | ||
| 1444 | if (pccard_get_tuple_data(s, &tuple)) | ||
| 1445 | goto next_entry; | ||
| 1446 | |||
| 1447 | if (parse) | ||
| 1448 | if (pcmcia_parse_tuple(&tuple, parse)) | ||
| 1449 | goto next_entry; | ||
| 1450 | |||
| 1451 | ret = loop_tuple(&tuple, parse, priv_data); | ||
| 1452 | if (!ret) | ||
| 1453 | break; | ||
| 1454 | |||
| 1455 | next_entry: | ||
| 1456 | ret = pccard_get_next_tuple(s, function, &tuple); | ||
| 1457 | } | ||
| 1458 | |||
| 1459 | kfree(buf); | ||
| 1460 | return ret; | ||
| 1461 | } | ||
| 1462 | |||
| 1463 | |||
| 1464 | /** | ||
| 1465 | * pccard_validate_cis() - check whether card has a sensible CIS | 1365 | * pccard_validate_cis() - check whether card has a sensible CIS |
| 1466 | * @s: the struct pcmcia_socket we are to check | 1366 | * @s: the struct pcmcia_socket we are to check |
| 1467 | * @info: returns the number of tuples in the (valid) CIS, or 0 | 1367 | * @info: returns the number of tuples in the (valid) CIS, or 0 |
diff --git a/drivers/pcmcia/pcmcia_cis.c b/drivers/pcmcia/pcmcia_cis.c new file mode 100644 index 000000000000..7406387f1f5e --- /dev/null +++ b/drivers/pcmcia/pcmcia_cis.c | |||
| @@ -0,0 +1,355 @@ | |||
| 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/module.h> | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/netdevice.h> | ||
| 20 | |||
| 21 | #include <pcmcia/cs_types.h> | ||
| 22 | #include <pcmcia/cisreg.h> | ||
| 23 | #include <pcmcia/cistpl.h> | ||
| 24 | #include <pcmcia/ss.h> | ||
| 25 | #include <pcmcia/cs.h> | ||
| 26 | #include <pcmcia/ds.h> | ||
| 27 | #include "cs_internal.h" | ||
| 28 | |||
| 29 | |||
| 30 | /** | ||
| 31 | * pccard_read_tuple() - internal CIS tuple access | ||
| 32 | * @s: the struct pcmcia_socket where the card is inserted | ||
| 33 | * @function: the device function we loop for | ||
| 34 | * @code: which CIS code shall we look for? | ||
| 35 | * @parse: buffer where the tuple shall be parsed (or NULL, if no parse) | ||
| 36 | * | ||
| 37 | * pccard_read_tuple() reads out one tuple and attempts to parse it | ||
| 38 | */ | ||
| 39 | int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, | ||
| 40 | cisdata_t code, void *parse) | ||
| 41 | { | ||
| 42 | tuple_t tuple; | ||
| 43 | cisdata_t *buf; | ||
| 44 | int ret; | ||
| 45 | |||
| 46 | buf = kmalloc(256, GFP_KERNEL); | ||
| 47 | if (buf == NULL) { | ||
| 48 | dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); | ||
| 49 | return -ENOMEM; | ||
| 50 | } | ||
| 51 | tuple.DesiredTuple = code; | ||
| 52 | tuple.Attributes = 0; | ||
| 53 | if (function == BIND_FN_ALL) | ||
| 54 | tuple.Attributes = TUPLE_RETURN_COMMON; | ||
| 55 | ret = pccard_get_first_tuple(s, function, &tuple); | ||
| 56 | if (ret != 0) | ||
| 57 | goto done; | ||
| 58 | tuple.TupleData = buf; | ||
| 59 | tuple.TupleOffset = 0; | ||
| 60 | tuple.TupleDataMax = 255; | ||
| 61 | ret = pccard_get_tuple_data(s, &tuple); | ||
| 62 | if (ret != 0) | ||
| 63 | goto done; | ||
| 64 | ret = pcmcia_parse_tuple(&tuple, parse); | ||
| 65 | done: | ||
| 66 | kfree(buf); | ||
| 67 | return ret; | ||
| 68 | } | ||
| 69 | |||
| 70 | |||
| 71 | /** | ||
| 72 | * pccard_loop_tuple() - loop over tuples in the CIS | ||
| 73 | * @s: the struct pcmcia_socket where the card is inserted | ||
| 74 | * @function: the device function we loop for | ||
| 75 | * @code: which CIS code shall we look for? | ||
| 76 | * @parse: buffer where the tuple shall be parsed (or NULL, if no parse) | ||
| 77 | * @priv_data: private data to be passed to the loop_tuple function. | ||
| 78 | * @loop_tuple: function to call for each CIS entry of type @function. IT | ||
| 79 | * gets passed the raw tuple, the paresed tuple (if @parse is | ||
| 80 | * set) and @priv_data. | ||
| 81 | * | ||
| 82 | * pccard_loop_tuple() loops over all CIS entries of type @function, and | ||
| 83 | * calls the @loop_tuple function for each entry. If the call to @loop_tuple | ||
| 84 | * returns 0, the loop exits. Returns 0 on success or errorcode otherwise. | ||
| 85 | */ | ||
| 86 | int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function, | ||
| 87 | cisdata_t code, cisparse_t *parse, void *priv_data, | ||
| 88 | int (*loop_tuple) (tuple_t *tuple, | ||
| 89 | cisparse_t *parse, | ||
| 90 | void *priv_data)) | ||
| 91 | { | ||
| 92 | tuple_t tuple; | ||
| 93 | cisdata_t *buf; | ||
| 94 | int ret; | ||
| 95 | |||
| 96 | buf = kzalloc(256, GFP_KERNEL); | ||
| 97 | if (buf == NULL) { | ||
| 98 | dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); | ||
| 99 | return -ENOMEM; | ||
| 100 | } | ||
| 101 | |||
| 102 | tuple.TupleData = buf; | ||
| 103 | tuple.TupleDataMax = 255; | ||
| 104 | tuple.TupleOffset = 0; | ||
| 105 | tuple.DesiredTuple = code; | ||
| 106 | tuple.Attributes = 0; | ||
| 107 | |||
| 108 | ret = pccard_get_first_tuple(s, function, &tuple); | ||
| 109 | while (!ret) { | ||
| 110 | if (pccard_get_tuple_data(s, &tuple)) | ||
| 111 | goto next_entry; | ||
| 112 | |||
| 113 | if (parse) | ||
| 114 | if (pcmcia_parse_tuple(&tuple, parse)) | ||
| 115 | goto next_entry; | ||
| 116 | |||
| 117 | ret = loop_tuple(&tuple, parse, priv_data); | ||
| 118 | if (!ret) | ||
| 119 | break; | ||
| 120 | |||
| 121 | next_entry: | ||
| 122 | ret = pccard_get_next_tuple(s, function, &tuple); | ||
| 123 | } | ||
| 124 | |||
| 125 | kfree(buf); | ||
| 126 | return ret; | ||
| 127 | } | ||
| 128 | |||
| 129 | struct pcmcia_cfg_mem { | ||
| 130 | struct pcmcia_device *p_dev; | ||
| 131 | void *priv_data; | ||
| 132 | int (*conf_check) (struct pcmcia_device *p_dev, | ||
| 133 | cistpl_cftable_entry_t *cfg, | ||
| 134 | cistpl_cftable_entry_t *dflt, | ||
| 135 | unsigned int vcc, | ||
| 136 | void *priv_data); | ||
| 137 | cisparse_t parse; | ||
| 138 | cistpl_cftable_entry_t dflt; | ||
| 139 | }; | ||
| 140 | |||
| 141 | /** | ||
| 142 | * pcmcia_do_loop_config() - internal helper for pcmcia_loop_config() | ||
| 143 | * | ||
| 144 | * pcmcia_do_loop_config() is the internal callback for the call from | ||
| 145 | * pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred | ||
| 146 | * by a struct pcmcia_cfg_mem. | ||
| 147 | */ | ||
| 148 | static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv) | ||
| 149 | { | ||
| 150 | cistpl_cftable_entry_t *cfg = &parse->cftable_entry; | ||
| 151 | struct pcmcia_cfg_mem *cfg_mem = priv; | ||
| 152 | |||
| 153 | /* default values */ | ||
| 154 | cfg_mem->p_dev->conf.ConfigIndex = cfg->index; | ||
| 155 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) | ||
| 156 | cfg_mem->dflt = *cfg; | ||
| 157 | |||
| 158 | return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt, | ||
| 159 | cfg_mem->p_dev->socket->socket.Vcc, | ||
| 160 | cfg_mem->priv_data); | ||
| 161 | } | ||
| 162 | |||
| 163 | /** | ||
| 164 | * pcmcia_loop_config() - loop over configuration options | ||
| 165 | * @p_dev: the struct pcmcia_device which we need to loop for. | ||
| 166 | * @conf_check: function to call for each configuration option. | ||
| 167 | * It gets passed the struct pcmcia_device, the CIS data | ||
| 168 | * describing the configuration option, and private data | ||
| 169 | * being passed to pcmcia_loop_config() | ||
| 170 | * @priv_data: private data to be passed to the conf_check function. | ||
| 171 | * | ||
| 172 | * pcmcia_loop_config() loops over all configuration options, and calls | ||
| 173 | * the driver-specific conf_check() for each one, checking whether | ||
| 174 | * it is a valid one. Returns 0 on success or errorcode otherwise. | ||
| 175 | */ | ||
| 176 | int pcmcia_loop_config(struct pcmcia_device *p_dev, | ||
| 177 | int (*conf_check) (struct pcmcia_device *p_dev, | ||
| 178 | cistpl_cftable_entry_t *cfg, | ||
| 179 | cistpl_cftable_entry_t *dflt, | ||
| 180 | unsigned int vcc, | ||
| 181 | void *priv_data), | ||
| 182 | void *priv_data) | ||
| 183 | { | ||
| 184 | struct pcmcia_cfg_mem *cfg_mem; | ||
| 185 | int ret; | ||
| 186 | |||
| 187 | cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL); | ||
| 188 | if (cfg_mem == NULL) | ||
| 189 | return -ENOMEM; | ||
| 190 | |||
| 191 | cfg_mem->p_dev = p_dev; | ||
| 192 | cfg_mem->conf_check = conf_check; | ||
| 193 | cfg_mem->priv_data = priv_data; | ||
| 194 | |||
| 195 | ret = pccard_loop_tuple(p_dev->socket, p_dev->func, | ||
| 196 | CISTPL_CFTABLE_ENTRY, &cfg_mem->parse, | ||
| 197 | cfg_mem, pcmcia_do_loop_config); | ||
| 198 | |||
| 199 | kfree(cfg_mem); | ||
| 200 | return ret; | ||
| 201 | } | ||
| 202 | EXPORT_SYMBOL(pcmcia_loop_config); | ||
| 203 | |||
| 204 | |||
| 205 | struct pcmcia_loop_mem { | ||
| 206 | struct pcmcia_device *p_dev; | ||
| 207 | void *priv_data; | ||
| 208 | int (*loop_tuple) (struct pcmcia_device *p_dev, | ||
| 209 | tuple_t *tuple, | ||
| 210 | void *priv_data); | ||
| 211 | }; | ||
| 212 | |||
| 213 | /** | ||
| 214 | * pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config() | ||
| 215 | * | ||
| 216 | * pcmcia_do_loop_tuple() is the internal callback for the call from | ||
| 217 | * pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred | ||
| 218 | * by a struct pcmcia_cfg_mem. | ||
| 219 | */ | ||
| 220 | static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv) | ||
| 221 | { | ||
| 222 | struct pcmcia_loop_mem *loop = priv; | ||
| 223 | |||
| 224 | return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data); | ||
| 225 | }; | ||
| 226 | |||
| 227 | /** | ||
| 228 | * pcmcia_loop_tuple() - loop over tuples in the CIS | ||
| 229 | * @p_dev: the struct pcmcia_device which we need to loop for. | ||
| 230 | * @code: which CIS code shall we look for? | ||
| 231 | * @priv_data: private data to be passed to the loop_tuple function. | ||
| 232 | * @loop_tuple: function to call for each CIS entry of type @function. IT | ||
| 233 | * gets passed the raw tuple and @priv_data. | ||
| 234 | * | ||
| 235 | * pcmcia_loop_tuple() loops over all CIS entries of type @function, and | ||
| 236 | * calls the @loop_tuple function for each entry. If the call to @loop_tuple | ||
| 237 | * returns 0, the loop exits. Returns 0 on success or errorcode otherwise. | ||
| 238 | */ | ||
| 239 | int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code, | ||
| 240 | int (*loop_tuple) (struct pcmcia_device *p_dev, | ||
| 241 | tuple_t *tuple, | ||
| 242 | void *priv_data), | ||
| 243 | void *priv_data) | ||
| 244 | { | ||
| 245 | struct pcmcia_loop_mem loop = { | ||
| 246 | .p_dev = p_dev, | ||
| 247 | .loop_tuple = loop_tuple, | ||
| 248 | .priv_data = priv_data}; | ||
| 249 | |||
| 250 | return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL, | ||
| 251 | &loop, pcmcia_do_loop_tuple); | ||
| 252 | } | ||
| 253 | EXPORT_SYMBOL(pcmcia_loop_tuple); | ||
| 254 | |||
| 255 | |||
| 256 | struct pcmcia_loop_get { | ||
| 257 | size_t len; | ||
| 258 | cisdata_t **buf; | ||
| 259 | }; | ||
| 260 | |||
| 261 | /** | ||
| 262 | * pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple() | ||
| 263 | * | ||
| 264 | * pcmcia_do_get_tuple() is the internal callback for the call from | ||
| 265 | * pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in | ||
| 266 | * the first tuple, return 0 unconditionally. Create a memory buffer large | ||
| 267 | * enough to hold the content of the tuple, and fill it with the tuple data. | ||
| 268 | * The caller is responsible to free the buffer. | ||
| 269 | */ | ||
| 270 | static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple, | ||
| 271 | void *priv) | ||
| 272 | { | ||
| 273 | struct pcmcia_loop_get *get = priv; | ||
| 274 | |||
| 275 | *get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL); | ||
| 276 | if (*get->buf) { | ||
| 277 | get->len = tuple->TupleDataLen; | ||
| 278 | memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen); | ||
| 279 | } else | ||
| 280 | dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n"); | ||
| 281 | return 0; | ||
| 282 | } | ||
| 283 | |||
| 284 | /** | ||
| 285 | * pcmcia_get_tuple() - get first tuple from CIS | ||
| 286 | * @p_dev: the struct pcmcia_device which we need to loop for. | ||
| 287 | * @code: which CIS code shall we look for? | ||
| 288 | * @buf: pointer to store the buffer to. | ||
| 289 | * | ||
| 290 | * pcmcia_get_tuple() gets the content of the first CIS entry of type @code. | ||
| 291 | * It returns the buffer length (or zero). The caller is responsible to free | ||
| 292 | * the buffer passed in @buf. | ||
| 293 | */ | ||
| 294 | size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code, | ||
| 295 | unsigned char **buf) | ||
| 296 | { | ||
| 297 | struct pcmcia_loop_get get = { | ||
| 298 | .len = 0, | ||
| 299 | .buf = buf, | ||
| 300 | }; | ||
| 301 | |||
| 302 | *get.buf = NULL; | ||
| 303 | pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get); | ||
| 304 | |||
| 305 | return get.len; | ||
| 306 | } | ||
| 307 | EXPORT_SYMBOL(pcmcia_get_tuple); | ||
| 308 | |||
| 309 | |||
| 310 | /** | ||
| 311 | * pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis() | ||
| 312 | * | ||
| 313 | * pcmcia_do_get_mac() is the internal callback for the call from | ||
| 314 | * pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the | ||
| 315 | * tuple contains a proper LAN_NODE_ID of length 6, and copy the data | ||
| 316 | * to struct net_device->dev_addr[i]. | ||
| 317 | */ | ||
| 318 | static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple, | ||
| 319 | void *priv) | ||
| 320 | { | ||
| 321 | struct net_device *dev = priv; | ||
| 322 | int i; | ||
| 323 | |||
| 324 | if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID) | ||
| 325 | return -EINVAL; | ||
| 326 | if (tuple->TupleDataLen < ETH_ALEN + 2) { | ||
| 327 | dev_warn(&p_dev->dev, "Invalid CIS tuple length for " | ||
| 328 | "LAN_NODE_ID\n"); | ||
| 329 | return -EINVAL; | ||
| 330 | } | ||
| 331 | |||
| 332 | if (tuple->TupleData[1] != ETH_ALEN) { | ||
| 333 | dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n"); | ||
| 334 | return -EINVAL; | ||
| 335 | } | ||
| 336 | for (i = 0; i < 6; i++) | ||
| 337 | dev->dev_addr[i] = tuple->TupleData[i+2]; | ||
| 338 | return 0; | ||
| 339 | } | ||
| 340 | |||
| 341 | /** | ||
| 342 | * pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE | ||
| 343 | * @p_dev: the struct pcmcia_device for which we want the address. | ||
| 344 | * @dev: a properly prepared struct net_device to store the info to. | ||
| 345 | * | ||
| 346 | * pcmcia_get_mac_from_cis() reads out the hardware MAC address from | ||
| 347 | * CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which | ||
| 348 | * must be set up properly by the driver (see examples!). | ||
| 349 | */ | ||
| 350 | int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev) | ||
| 351 | { | ||
| 352 | return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev); | ||
| 353 | } | ||
| 354 | EXPORT_SYMBOL(pcmcia_get_mac_from_cis); | ||
| 355 | |||
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index f355c5ac407b..9c5f9cd5e03d 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
| @@ -923,232 +923,3 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) | |||
| 923 | pcmcia_release_window(p_dev, p_dev->win); | 923 | pcmcia_release_window(p_dev, p_dev->win); |
| 924 | } | 924 | } |
| 925 | EXPORT_SYMBOL(pcmcia_disable_device); | 925 | EXPORT_SYMBOL(pcmcia_disable_device); |
| 926 | |||
| 927 | |||
| 928 | struct pcmcia_cfg_mem { | ||
| 929 | struct pcmcia_device *p_dev; | ||
| 930 | void *priv_data; | ||
| 931 | int (*conf_check) (struct pcmcia_device *p_dev, | ||
| 932 | cistpl_cftable_entry_t *cfg, | ||
| 933 | cistpl_cftable_entry_t *dflt, | ||
| 934 | unsigned int vcc, | ||
| 935 | void *priv_data); | ||
| 936 | cisparse_t parse; | ||
| 937 | cistpl_cftable_entry_t dflt; | ||
| 938 | }; | ||
| 939 | |||
| 940 | /** | ||
| 941 | * pcmcia_do_loop_config() - internal helper for pcmcia_loop_config() | ||
| 942 | * | ||
| 943 | * pcmcia_do_loop_config() is the internal callback for the call from | ||
| 944 | * pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred | ||
| 945 | * by a struct pcmcia_cfg_mem. | ||
| 946 | */ | ||
| 947 | static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv) | ||
| 948 | { | ||
| 949 | cistpl_cftable_entry_t *cfg = &parse->cftable_entry; | ||
| 950 | struct pcmcia_cfg_mem *cfg_mem = priv; | ||
| 951 | |||
| 952 | /* default values */ | ||
| 953 | cfg_mem->p_dev->conf.ConfigIndex = cfg->index; | ||
| 954 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) | ||
| 955 | cfg_mem->dflt = *cfg; | ||
| 956 | |||
| 957 | return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt, | ||
| 958 | cfg_mem->p_dev->socket->socket.Vcc, | ||
| 959 | cfg_mem->priv_data); | ||
| 960 | } | ||
| 961 | |||
| 962 | /** | ||
| 963 | * pcmcia_loop_config() - loop over configuration options | ||
| 964 | * @p_dev: the struct pcmcia_device which we need to loop for. | ||
| 965 | * @conf_check: function to call for each configuration option. | ||
| 966 | * It gets passed the struct pcmcia_device, the CIS data | ||
| 967 | * describing the configuration option, and private data | ||
| 968 | * being passed to pcmcia_loop_config() | ||
| 969 | * @priv_data: private data to be passed to the conf_check function. | ||
| 970 | * | ||
| 971 | * pcmcia_loop_config() loops over all configuration options, and calls | ||
| 972 | * the driver-specific conf_check() for each one, checking whether | ||
| 973 | * it is a valid one. Returns 0 on success or errorcode otherwise. | ||
| 974 | */ | ||
| 975 | int pcmcia_loop_config(struct pcmcia_device *p_dev, | ||
| 976 | int (*conf_check) (struct pcmcia_device *p_dev, | ||
| 977 | cistpl_cftable_entry_t *cfg, | ||
| 978 | cistpl_cftable_entry_t *dflt, | ||
| 979 | unsigned int vcc, | ||
| 980 | void *priv_data), | ||
| 981 | void *priv_data) | ||
| 982 | { | ||
| 983 | struct pcmcia_cfg_mem *cfg_mem; | ||
| 984 | int ret; | ||
| 985 | |||
| 986 | cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL); | ||
| 987 | if (cfg_mem == NULL) | ||
| 988 | return -ENOMEM; | ||
| 989 | |||
| 990 | cfg_mem->p_dev = p_dev; | ||
| 991 | cfg_mem->conf_check = conf_check; | ||
| 992 | cfg_mem->priv_data = priv_data; | ||
| 993 | |||
| 994 | ret = pccard_loop_tuple(p_dev->socket, p_dev->func, | ||
| 995 | CISTPL_CFTABLE_ENTRY, &cfg_mem->parse, | ||
| 996 | cfg_mem, pcmcia_do_loop_config); | ||
| 997 | |||
| 998 | kfree(cfg_mem); | ||
| 999 | return ret; | ||
| 1000 | } | ||
| 1001 | EXPORT_SYMBOL(pcmcia_loop_config); | ||
| 1002 | |||
| 1003 | |||
| 1004 | struct pcmcia_loop_mem { | ||
| 1005 | struct pcmcia_device *p_dev; | ||
| 1006 | void *priv_data; | ||
| 1007 | int (*loop_tuple) (struct pcmcia_device *p_dev, | ||
| 1008 | tuple_t *tuple, | ||
| 1009 | void *priv_data); | ||
| 1010 | }; | ||
| 1011 | |||
| 1012 | /** | ||
| 1013 | * pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config() | ||
| 1014 | * | ||
| 1015 | * pcmcia_do_loop_tuple() is the internal callback for the call from | ||
| 1016 | * pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred | ||
| 1017 | * by a struct pcmcia_cfg_mem. | ||
| 1018 | */ | ||
| 1019 | static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv) | ||
| 1020 | { | ||
| 1021 | struct pcmcia_loop_mem *loop = priv; | ||
| 1022 | |||
| 1023 | return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data); | ||
| 1024 | }; | ||
| 1025 | |||
| 1026 | /** | ||
| 1027 | * pcmcia_loop_tuple() - loop over tuples in the CIS | ||
| 1028 | * @p_dev: the struct pcmcia_device which we need to loop for. | ||
| 1029 | * @code: which CIS code shall we look for? | ||
| 1030 | * @priv_data: private data to be passed to the loop_tuple function. | ||
| 1031 | * @loop_tuple: function to call for each CIS entry of type @function. IT | ||
| 1032 | * gets passed the raw tuple and @priv_data. | ||
| 1033 | * | ||
| 1034 | * pcmcia_loop_tuple() loops over all CIS entries of type @function, and | ||
| 1035 | * calls the @loop_tuple function for each entry. If the call to @loop_tuple | ||
| 1036 | * returns 0, the loop exits. Returns 0 on success or errorcode otherwise. | ||
| 1037 | */ | ||
| 1038 | int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code, | ||
| 1039 | int (*loop_tuple) (struct pcmcia_device *p_dev, | ||
| 1040 | tuple_t *tuple, | ||
| 1041 | void *priv_data), | ||
| 1042 | void *priv_data) | ||
| 1043 | { | ||
| 1044 | struct pcmcia_loop_mem loop = { | ||
| 1045 | .p_dev = p_dev, | ||
| 1046 | .loop_tuple = loop_tuple, | ||
| 1047 | .priv_data = priv_data}; | ||
| 1048 | |||
| 1049 | return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL, | ||
| 1050 | &loop, pcmcia_do_loop_tuple); | ||
| 1051 | } | ||
| 1052 | EXPORT_SYMBOL(pcmcia_loop_tuple); | ||
| 1053 | |||
| 1054 | |||
| 1055 | struct pcmcia_loop_get { | ||
| 1056 | size_t len; | ||
| 1057 | cisdata_t **buf; | ||
| 1058 | }; | ||
| 1059 | |||
| 1060 | /** | ||
| 1061 | * pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple() | ||
| 1062 | * | ||
| 1063 | * pcmcia_do_get_tuple() is the internal callback for the call from | ||
| 1064 | * pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in | ||
| 1065 | * the first tuple, return 0 unconditionally. Create a memory buffer large | ||
| 1066 | * enough to hold the content of the tuple, and fill it with the tuple data. | ||
| 1067 | * The caller is responsible to free the buffer. | ||
| 1068 | */ | ||
| 1069 | static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple, | ||
| 1070 | void *priv) | ||
| 1071 | { | ||
| 1072 | struct pcmcia_loop_get *get = priv; | ||
| 1073 | |||
| 1074 | *get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL); | ||
| 1075 | if (*get->buf) { | ||
| 1076 | get->len = tuple->TupleDataLen; | ||
| 1077 | memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen); | ||
| 1078 | } else | ||
| 1079 | dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n"); | ||
| 1080 | return 0; | ||
| 1081 | } | ||
| 1082 | |||
| 1083 | /** | ||
| 1084 | * pcmcia_get_tuple() - get first tuple from CIS | ||
| 1085 | * @p_dev: the struct pcmcia_device which we need to loop for. | ||
| 1086 | * @code: which CIS code shall we look for? | ||
| 1087 | * @buf: pointer to store the buffer to. | ||
| 1088 | * | ||
| 1089 | * pcmcia_get_tuple() gets the content of the first CIS entry of type @code. | ||
| 1090 | * It returns the buffer length (or zero). The caller is responsible to free | ||
| 1091 | * the buffer passed in @buf. | ||
| 1092 | */ | ||
| 1093 | size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code, | ||
| 1094 | unsigned char **buf) | ||
| 1095 | { | ||
| 1096 | struct pcmcia_loop_get get = { | ||
| 1097 | .len = 0, | ||
| 1098 | .buf = buf, | ||
| 1099 | }; | ||
| 1100 | |||
| 1101 | *get.buf = NULL; | ||
| 1102 | pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get); | ||
| 1103 | |||
| 1104 | return get.len; | ||
| 1105 | } | ||
| 1106 | EXPORT_SYMBOL(pcmcia_get_tuple); | ||
| 1107 | |||
| 1108 | |||
| 1109 | /** | ||
| 1110 | * pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis() | ||
| 1111 | * | ||
| 1112 | * pcmcia_do_get_mac() is the internal callback for the call from | ||
| 1113 | * pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the | ||
| 1114 | * tuple contains a proper LAN_NODE_ID of length 6, and copy the data | ||
| 1115 | * to struct net_device->dev_addr[i]. | ||
| 1116 | */ | ||
| 1117 | static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple, | ||
| 1118 | void *priv) | ||
| 1119 | { | ||
| 1120 | struct net_device *dev = priv; | ||
| 1121 | int i; | ||
| 1122 | |||
| 1123 | if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID) | ||
| 1124 | return -EINVAL; | ||
| 1125 | if (tuple->TupleDataLen < ETH_ALEN + 2) { | ||
| 1126 | dev_warn(&p_dev->dev, "Invalid CIS tuple length for " | ||
| 1127 | "LAN_NODE_ID\n"); | ||
| 1128 | return -EINVAL; | ||
| 1129 | } | ||
| 1130 | |||
| 1131 | if (tuple->TupleData[1] != ETH_ALEN) { | ||
| 1132 | dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n"); | ||
| 1133 | return -EINVAL; | ||
| 1134 | } | ||
| 1135 | for (i = 0; i < 6; i++) | ||
| 1136 | dev->dev_addr[i] = tuple->TupleData[i+2]; | ||
| 1137 | return 0; | ||
| 1138 | } | ||
| 1139 | |||
| 1140 | /** | ||
| 1141 | * pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE | ||
| 1142 | * @p_dev: the struct pcmcia_device for which we want the address. | ||
| 1143 | * @dev: a properly prepared struct net_device to store the info to. | ||
| 1144 | * | ||
| 1145 | * pcmcia_get_mac_from_cis() reads out the hardware MAC address from | ||
| 1146 | * CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which | ||
| 1147 | * must be set up properly by the driver (see examples!). | ||
| 1148 | */ | ||
| 1149 | int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev) | ||
| 1150 | { | ||
| 1151 | return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev); | ||
| 1152 | } | ||
| 1153 | EXPORT_SYMBOL(pcmcia_get_mac_from_cis); | ||
| 1154 | |||
