diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-02-17 12:01:31 -0500 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-02-17 12:01:31 -0500 |
commit | d700518a0e4d17a47321414e5e487ed53f4ae752 (patch) | |
tree | d50a2a1e225f09161a7a879f7013ad7bae1f4934 | |
parent | a78621bb11fbad32a3ef968c65f9b93858b3341a (diff) |
pcmcia: use read_cis_mem return value
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r-- | drivers/pcmcia/cistpl.c | 63 |
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 | ||
286 | static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, | 286 | static 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 | ||
331 | static void | 334 | static 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_ | |||
616 | int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple) | 638 | int 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 | ||