aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-02-17 12:01:31 -0500
committerDominik Brodowski <linux@dominikbrodowski.net>2010-02-17 12:01:31 -0500
commitd700518a0e4d17a47321414e5e487ed53f4ae752 (patch)
treed50a2a1e225f09161a7a879f7013ad7bae1f4934 /drivers
parenta78621bb11fbad32a3ef968c65f9b93858b3341a (diff)
pcmcia: use read_cis_mem return value
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pcmcia/cistpl.c63
1 files changed, 44 insertions, 19 deletions
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 602f574898dc..2f3622dd4b69 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -283,30 +283,32 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
283 283
284======================================================================*/ 284======================================================================*/
285 285
286static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, 286static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
287 size_t len, void *ptr) 287 size_t len, void *ptr)
288{ 288{
289 struct cis_cache_entry *cis; 289 struct cis_cache_entry *cis;
290 int ret; 290 int ret = 0;
291 291
292 if (s->state & SOCKET_CARDBUS) 292 if (s->state & SOCKET_CARDBUS)
293 return; 293 return -EINVAL;
294 294
295 mutex_lock(&s->ops_mutex); 295 mutex_lock(&s->ops_mutex);
296 if (s->fake_cis) { 296 if (s->fake_cis) {
297 if (s->fake_cis_len >= addr+len) 297 if (s->fake_cis_len >= addr+len)
298 memcpy(ptr, s->fake_cis+addr, len); 298 memcpy(ptr, s->fake_cis+addr, len);
299 else 299 else {
300 memset(ptr, 0xff, len); 300 memset(ptr, 0xff, len);
301 ret = -EINVAL;
302 }
301 mutex_unlock(&s->ops_mutex); 303 mutex_unlock(&s->ops_mutex);
302 return; 304 return ret;
303 } 305 }
304 306
305 list_for_each_entry(cis, &s->cis_cache, node) { 307 list_for_each_entry(cis, &s->cis_cache, node) {
306 if (cis->addr == addr && cis->len == len && cis->attr == attr) { 308 if (cis->addr == addr && cis->len == len && cis->attr == attr) {
307 memcpy(ptr, cis->cache, len); 309 memcpy(ptr, cis->cache, len);
308 mutex_unlock(&s->ops_mutex); 310 mutex_unlock(&s->ops_mutex);
309 return; 311 return 0;
310 } 312 }
311 } 313 }
312 mutex_unlock(&s->ops_mutex); 314 mutex_unlock(&s->ops_mutex);
@@ -326,6 +328,7 @@ static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
326 mutex_unlock(&s->ops_mutex); 328 mutex_unlock(&s->ops_mutex);
327 } 329 }
328 } 330 }
331 return ret;
329} 332}
330 333
331static void 334static void
@@ -374,6 +377,7 @@ int verify_cis_cache(struct pcmcia_socket *s)
374{ 377{
375 struct cis_cache_entry *cis; 378 struct cis_cache_entry *cis;
376 char *buf; 379 char *buf;
380 int ret;
377 381
378 if (s->state & SOCKET_CARDBUS) 382 if (s->state & SOCKET_CARDBUS)
379 return -EINVAL; 383 return -EINVAL;
@@ -390,9 +394,8 @@ int verify_cis_cache(struct pcmcia_socket *s)
390 if (len > 256) 394 if (len > 256)
391 len = 256; 395 len = 256;
392 396
393 pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf); 397 ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
394 398 if (ret || memcmp(buf, cis->cache, len) != 0) {
395 if (memcmp(buf, cis->cache, len) != 0) {
396 kfree(buf); 399 kfree(buf);
397 return -1; 400 return -1;
398 } 401 }
@@ -425,6 +428,7 @@ int pcmcia_replace_cis(struct pcmcia_socket *s,
425 } 428 }
426 s->fake_cis_len = len; 429 s->fake_cis_len = len;
427 memcpy(s->fake_cis, data, len); 430 memcpy(s->fake_cis, data, len);
431 dev_info(&s->dev, "Using replacement CIS\n");
428 mutex_unlock(&s->ops_mutex); 432 mutex_unlock(&s->ops_mutex);
429 return 0; 433 return 0;
430} 434}
@@ -478,11 +482,14 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
478{ 482{
479 u_char link[5]; 483 u_char link[5];
480 u_int ofs; 484 u_int ofs;
485 int ret;
481 486
482 if (MFC_FN(tuple->Flags)) { 487 if (MFC_FN(tuple->Flags)) {
483 /* Get indirect link from the MFC tuple */ 488 /* Get indirect link from the MFC tuple */
484 read_cis_cache(s, LINK_SPACE(tuple->Flags), 489 ret = read_cis_cache(s, LINK_SPACE(tuple->Flags),
485 tuple->LinkOffset, 5, link); 490 tuple->LinkOffset, 5, link);
491 if (ret)
492 return -1;
486 ofs = get_unaligned_le32(link + 1); 493 ofs = get_unaligned_le32(link + 1);
487 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR); 494 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
488 /* Move to the next indirect link */ 495 /* Move to the next indirect link */
@@ -498,7 +505,9 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
498 if (SPACE(tuple->Flags)) { 505 if (SPACE(tuple->Flags)) {
499 /* This is ugly, but a common CIS error is to code the long 506 /* This is ugly, but a common CIS error is to code the long
500 link offset incorrectly, so we check the right spot... */ 507 link offset incorrectly, so we check the right spot... */
501 read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link); 508 ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
509 if (ret)
510 return -1;
502 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) && 511 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
503 (strncmp(link+2, "CIS", 3) == 0)) 512 (strncmp(link+2, "CIS", 3) == 0))
504 return ofs; 513 return ofs;
@@ -506,7 +515,9 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
506 /* Then, we try the wrong spot... */ 515 /* Then, we try the wrong spot... */
507 ofs = ofs >> 1; 516 ofs = ofs >> 1;
508 } 517 }
509 read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link); 518 ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
519 if (ret)
520 return -1;
510 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) && 521 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
511 (strncmp(link+2, "CIS", 3) == 0)) 522 (strncmp(link+2, "CIS", 3) == 0))
512 return ofs; 523 return ofs;
@@ -518,6 +529,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
518{ 529{
519 u_char link[2], tmp; 530 u_char link[2], tmp;
520 int ofs, i, attr; 531 int ofs, i, attr;
532 int ret;
521 533
522 if (!s) 534 if (!s)
523 return -EINVAL; 535 return -EINVAL;
@@ -532,7 +544,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
532 if (link[1] == 0xff) { 544 if (link[1] == 0xff) {
533 link[0] = CISTPL_END; 545 link[0] = CISTPL_END;
534 } else { 546 } else {
535 read_cis_cache(s, attr, ofs, 2, link); 547 ret = read_cis_cache(s, attr, ofs, 2, link);
548 if (ret)
549 return -1;
536 if (link[0] == CISTPL_NULL) { 550 if (link[0] == CISTPL_NULL) {
537 ofs++; continue; 551 ofs++; continue;
538 } 552 }
@@ -544,7 +558,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
544 if (ofs < 0) 558 if (ofs < 0)
545 return -ENOSPC; 559 return -ENOSPC;
546 attr = SPACE(tuple->Flags); 560 attr = SPACE(tuple->Flags);
547 read_cis_cache(s, attr, ofs, 2, link); 561 ret = read_cis_cache(s, attr, ofs, 2, link);
562 if (ret)
563 return -1;
548 } 564 }
549 565
550 /* Is this a link tuple? Make a note of it */ 566 /* Is this a link tuple? Make a note of it */
@@ -558,12 +574,16 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
558 case CISTPL_LONGLINK_A: 574 case CISTPL_LONGLINK_A:
559 HAS_LINK(tuple->Flags) = 1; 575 HAS_LINK(tuple->Flags) = 1;
560 LINK_SPACE(tuple->Flags) = attr | IS_ATTR; 576 LINK_SPACE(tuple->Flags) = attr | IS_ATTR;
561 read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset); 577 ret = read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset);
578 if (ret)
579 return -1;
562 break; 580 break;
563 case CISTPL_LONGLINK_C: 581 case CISTPL_LONGLINK_C:
564 HAS_LINK(tuple->Flags) = 1; 582 HAS_LINK(tuple->Flags) = 1;
565 LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR; 583 LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR;
566 read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset); 584 ret = read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset);
585 if (ret)
586 return -1;
567 break; 587 break;
568 case CISTPL_INDIRECT: 588 case CISTPL_INDIRECT:
569 HAS_LINK(tuple->Flags) = 1; 589 HAS_LINK(tuple->Flags) = 1;
@@ -575,7 +595,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
575 LINK_SPACE(tuple->Flags) = attr; 595 LINK_SPACE(tuple->Flags) = attr;
576 if (function == BIND_FN_ALL) { 596 if (function == BIND_FN_ALL) {
577 /* Follow all the MFC links */ 597 /* Follow all the MFC links */
578 read_cis_cache(s, attr, ofs+2, 1, &tmp); 598 ret = read_cis_cache(s, attr, ofs+2, 1, &tmp);
599 if (ret)
600 return -1;
579 MFC_FN(tuple->Flags) = tmp; 601 MFC_FN(tuple->Flags) = tmp;
580 } else { 602 } else {
581 /* Follow exactly one of the links */ 603 /* Follow exactly one of the links */
@@ -616,6 +638,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
616int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple) 638int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
617{ 639{
618 u_int len; 640 u_int len;
641 int ret;
619 642
620 if (!s) 643 if (!s)
621 return -EINVAL; 644 return -EINVAL;
@@ -626,9 +649,11 @@ int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
626 tuple->TupleDataLen = tuple->TupleLink; 649 tuple->TupleDataLen = tuple->TupleLink;
627 if (len == 0) 650 if (len == 0)
628 return 0; 651 return 0;
629 read_cis_cache(s, SPACE(tuple->Flags), 652 ret = read_cis_cache(s, SPACE(tuple->Flags),
630 tuple->CISOffset + tuple->TupleOffset, 653 tuple->CISOffset + tuple->TupleOffset,
631 _MIN(len, tuple->TupleDataMax), tuple->TupleData); 654 _MIN(len, tuple->TupleDataMax), tuple->TupleData);
655 if (ret)
656 return -1;
632 return 0; 657 return 0;
633} 658}
634 659