aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/cistpl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/cistpl.c')
-rw-r--r--drivers/pcmcia/cistpl.c134
1 files changed, 18 insertions, 116 deletions
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index f230f6543bff..8844bc3e3118 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -129,6 +129,8 @@ static void __iomem *set_cis_map(struct pcmcia_socket *s,
129 129
130/** 130/**
131 * pcmcia_read_cis_mem() - low-level function to read CIS memory 131 * pcmcia_read_cis_mem() - low-level function to read CIS memory
132 *
133 * must be called with ops_mutex held
132 */ 134 */
133int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, 135int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
134 u_int len, void *ptr) 136 u_int len, void *ptr)
@@ -138,7 +140,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
138 140
139 dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len); 141 dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
140 142
141 mutex_lock(&s->ops_mutex);
142 if (attr & IS_INDIRECT) { 143 if (attr & IS_INDIRECT) {
143 /* Indirect accesses use a bunch of special registers at fixed 144 /* Indirect accesses use a bunch of special registers at fixed
144 locations in common memory */ 145 locations in common memory */
@@ -153,7 +154,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
153 if (!sys) { 154 if (!sys) {
154 dev_dbg(&s->dev, "could not map memory\n"); 155 dev_dbg(&s->dev, "could not map memory\n");
155 memset(ptr, 0xff, len); 156 memset(ptr, 0xff, len);
156 mutex_unlock(&s->ops_mutex);
157 return -1; 157 return -1;
158 } 158 }
159 159
@@ -184,7 +184,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
184 if (!sys) { 184 if (!sys) {
185 dev_dbg(&s->dev, "could not map memory\n"); 185 dev_dbg(&s->dev, "could not map memory\n");
186 memset(ptr, 0xff, len); 186 memset(ptr, 0xff, len);
187 mutex_unlock(&s->ops_mutex);
188 return -1; 187 return -1;
189 } 188 }
190 end = sys + s->map_size; 189 end = sys + s->map_size;
@@ -198,7 +197,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
198 addr = 0; 197 addr = 0;
199 } 198 }
200 } 199 }
201 mutex_unlock(&s->ops_mutex);
202 dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", 200 dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
203 *(u_char *)(ptr+0), *(u_char *)(ptr+1), 201 *(u_char *)(ptr+0), *(u_char *)(ptr+1),
204 *(u_char *)(ptr+2), *(u_char *)(ptr+3)); 202 *(u_char *)(ptr+2), *(u_char *)(ptr+3));
@@ -209,7 +207,8 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
209/** 207/**
210 * pcmcia_write_cis_mem() - low-level function to write CIS memory 208 * pcmcia_write_cis_mem() - low-level function to write CIS memory
211 * 209 *
212 * Probably only useful for writing one-byte registers. 210 * Probably only useful for writing one-byte registers. Must be called
211 * with ops_mutex held.
213 */ 212 */
214void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, 213void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
215 u_int len, void *ptr) 214 u_int len, void *ptr)
@@ -220,7 +219,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
220 dev_dbg(&s->dev, 219 dev_dbg(&s->dev,
221 "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); 220 "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
222 221
223 mutex_lock(&s->ops_mutex);
224 if (attr & IS_INDIRECT) { 222 if (attr & IS_INDIRECT) {
225 /* Indirect accesses use a bunch of special registers at fixed 223 /* Indirect accesses use a bunch of special registers at fixed
226 locations in common memory */ 224 locations in common memory */
@@ -234,7 +232,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
234 ((cis_width) ? MAP_16BIT : 0)); 232 ((cis_width) ? MAP_16BIT : 0));
235 if (!sys) { 233 if (!sys) {
236 dev_dbg(&s->dev, "could not map memory\n"); 234 dev_dbg(&s->dev, "could not map memory\n");
237 mutex_unlock(&s->ops_mutex);
238 return; /* FIXME: Error */ 235 return; /* FIXME: Error */
239 } 236 }
240 237
@@ -260,7 +257,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
260 sys = set_cis_map(s, card_offset, flags); 257 sys = set_cis_map(s, card_offset, flags);
261 if (!sys) { 258 if (!sys) {
262 dev_dbg(&s->dev, "could not map memory\n"); 259 dev_dbg(&s->dev, "could not map memory\n");
263 mutex_unlock(&s->ops_mutex);
264 return; /* FIXME: error */ 260 return; /* FIXME: error */
265 } 261 }
266 262
@@ -275,7 +271,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
275 addr = 0; 271 addr = 0;
276 } 272 }
277 } 273 }
278 mutex_unlock(&s->ops_mutex);
279} 274}
280 275
281 276
@@ -314,7 +309,6 @@ static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
314 return 0; 309 return 0;
315 } 310 }
316 } 311 }
317 mutex_unlock(&s->ops_mutex);
318 312
319 ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr); 313 ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);
320 314
@@ -326,11 +320,11 @@ static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
326 cis->len = len; 320 cis->len = len;
327 cis->attr = attr; 321 cis->attr = attr;
328 memcpy(cis->cache, ptr, len); 322 memcpy(cis->cache, ptr, len);
329 mutex_lock(&s->ops_mutex);
330 list_add(&cis->node, &s->cis_cache); 323 list_add(&cis->node, &s->cis_cache);
331 mutex_unlock(&s->ops_mutex);
332 } 324 }
333 } 325 }
326 mutex_unlock(&s->ops_mutex);
327
334 return ret; 328 return ret;
335} 329}
336 330
@@ -386,6 +380,7 @@ int verify_cis_cache(struct pcmcia_socket *s)
386 "no memory for verifying CIS\n"); 380 "no memory for verifying CIS\n");
387 return -ENOMEM; 381 return -ENOMEM;
388 } 382 }
383 mutex_lock(&s->ops_mutex);
389 list_for_each_entry(cis, &s->cis_cache, node) { 384 list_for_each_entry(cis, &s->cis_cache, node) {
390 int len = cis->len; 385 int len = cis->len;
391 386
@@ -395,10 +390,12 @@ int verify_cis_cache(struct pcmcia_socket *s)
395 ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf); 390 ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
396 if (ret || memcmp(buf, cis->cache, len) != 0) { 391 if (ret || memcmp(buf, cis->cache, len) != 0) {
397 kfree(buf); 392 kfree(buf);
393 mutex_unlock(&s->ops_mutex);
398 return -1; 394 return -1;
399 } 395 }
400 } 396 }
401 kfree(buf); 397 kfree(buf);
398 mutex_unlock(&s->ops_mutex);
402 return 0; 399 return 0;
403} 400}
404 401
@@ -1362,106 +1359,6 @@ EXPORT_SYMBOL(pcmcia_parse_tuple);
1362 1359
1363 1360
1364/** 1361/**
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 */
1373int 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);
1399done:
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 */
1420int 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
1455next_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 1362 * pccard_validate_cis() - check whether card has a sensible CIS
1466 * @s: the struct pcmcia_socket we are to check 1363 * @s: the struct pcmcia_socket we are to check
1467 * @info: returns the number of tuples in the (valid) CIS, or 0 1364 * @info: returns the number of tuples in the (valid) CIS, or 0
@@ -1484,6 +1381,11 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
1484 if (!s) 1381 if (!s)
1485 return -EINVAL; 1382 return -EINVAL;
1486 1383
1384 if (s->functions) {
1385 WARN_ON(1);
1386 return -EINVAL;
1387 }
1388
1487 /* We do not want to validate the CIS cache... */ 1389 /* We do not want to validate the CIS cache... */
1488 mutex_lock(&s->ops_mutex); 1390 mutex_lock(&s->ops_mutex);
1489 destroy_cis_cache(s); 1391 destroy_cis_cache(s);
@@ -1629,7 +1531,7 @@ static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf,
1629} 1531}
1630 1532
1631 1533
1632static ssize_t pccard_show_cis(struct kobject *kobj, 1534static ssize_t pccard_show_cis(struct file *filp, struct kobject *kobj,
1633 struct bin_attribute *bin_attr, 1535 struct bin_attribute *bin_attr,
1634 char *buf, loff_t off, size_t count) 1536 char *buf, loff_t off, size_t count)
1635{ 1537{
@@ -1639,7 +1541,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
1639 count = 0; 1541 count = 0;
1640 else { 1542 else {
1641 struct pcmcia_socket *s; 1543 struct pcmcia_socket *s;
1642 unsigned int chains; 1544 unsigned int chains = 1;
1643 1545
1644 if (off + count > size) 1546 if (off + count > size)
1645 count = size - off; 1547 count = size - off;
@@ -1648,7 +1550,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
1648 1550
1649 if (!(s->state & SOCKET_PRESENT)) 1551 if (!(s->state & SOCKET_PRESENT))
1650 return -ENODEV; 1552 return -ENODEV;
1651 if (pccard_validate_cis(s, &chains)) 1553 if (!s->functions && pccard_validate_cis(s, &chains))
1652 return -EIO; 1554 return -EIO;
1653 if (!chains) 1555 if (!chains)
1654 return -ENODATA; 1556 return -ENODATA;
@@ -1660,7 +1562,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
1660} 1562}
1661 1563
1662 1564
1663static ssize_t pccard_store_cis(struct kobject *kobj, 1565static ssize_t pccard_store_cis(struct file *filp, struct kobject *kobj,
1664 struct bin_attribute *bin_attr, 1566 struct bin_attribute *bin_attr,
1665 char *buf, loff_t off, size_t count) 1567 char *buf, loff_t off, size_t count)
1666{ 1568{