diff options
Diffstat (limited to 'drivers/pcmcia/cistpl.c')
-rw-r--r-- | drivers/pcmcia/cistpl.c | 181 |
1 files changed, 107 insertions, 74 deletions
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 8c1b73cf021b..25b1cd219e37 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/pci.h> | 24 | #include <linux/pci.h> |
25 | #include <linux/ioport.h> | 25 | #include <linux/ioport.h> |
26 | #include <asm/io.h> | 26 | #include <linux/io.h> |
27 | #include <asm/byteorder.h> | 27 | #include <asm/byteorder.h> |
28 | #include <asm/unaligned.h> | 28 | #include <asm/unaligned.h> |
29 | 29 | ||
@@ -125,7 +125,7 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag | |||
125 | 125 | ||
126 | Low-level functions to read and write CIS memory. I think the | 126 | Low-level functions to read and write CIS memory. I think the |
127 | write routine is only useful for writing one-byte registers. | 127 | write routine is only useful for writing one-byte registers. |
128 | 128 | ||
129 | ======================================================================*/ | 129 | ======================================================================*/ |
130 | 130 | ||
131 | /* Bits in attr field */ | 131 | /* Bits in attr field */ |
@@ -137,7 +137,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
137 | { | 137 | { |
138 | void __iomem *sys, *end; | 138 | void __iomem *sys, *end; |
139 | unsigned char *buf = ptr; | 139 | unsigned char *buf = ptr; |
140 | 140 | ||
141 | 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); |
142 | 142 | ||
143 | if (attr & IS_INDIRECT) { | 143 | if (attr & IS_INDIRECT) { |
@@ -203,7 +203,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
203 | { | 203 | { |
204 | void __iomem *sys, *end; | 204 | void __iomem *sys, *end; |
205 | unsigned char *buf = ptr; | 205 | unsigned char *buf = ptr; |
206 | 206 | ||
207 | dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); | 207 | dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); |
208 | 208 | ||
209 | if (attr & IS_INDIRECT) { | 209 | if (attr & IS_INDIRECT) { |
@@ -262,7 +262,7 @@ EXPORT_SYMBOL(pcmcia_write_cis_mem); | |||
262 | This is a wrapper around read_cis_mem, with the same interface, | 262 | This is a wrapper around read_cis_mem, with the same interface, |
263 | but which caches information, for cards whose CIS may not be | 263 | but which caches information, for cards whose CIS may not be |
264 | readable all the time. | 264 | readable all the time. |
265 | 265 | ||
266 | ======================================================================*/ | 266 | ======================================================================*/ |
267 | 267 | ||
268 | static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, | 268 | static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, |
@@ -342,7 +342,7 @@ EXPORT_SYMBOL(destroy_cis_cache); | |||
342 | 342 | ||
343 | This verifies if the CIS of a card matches what is in the CIS | 343 | This verifies if the CIS of a card matches what is in the CIS |
344 | cache. | 344 | cache. |
345 | 345 | ||
346 | ======================================================================*/ | 346 | ======================================================================*/ |
347 | 347 | ||
348 | int verify_cis_cache(struct pcmcia_socket *s) | 348 | int verify_cis_cache(struct pcmcia_socket *s) |
@@ -381,7 +381,7 @@ int verify_cis_cache(struct pcmcia_socket *s) | |||
381 | 381 | ||
382 | For really bad cards, we provide a facility for uploading a | 382 | For really bad cards, we provide a facility for uploading a |
383 | replacement CIS. | 383 | replacement CIS. |
384 | 384 | ||
385 | ======================================================================*/ | 385 | ======================================================================*/ |
386 | 386 | ||
387 | int pcmcia_replace_cis(struct pcmcia_socket *s, | 387 | int pcmcia_replace_cis(struct pcmcia_socket *s, |
@@ -406,7 +406,7 @@ EXPORT_SYMBOL(pcmcia_replace_cis); | |||
406 | /*====================================================================== | 406 | /*====================================================================== |
407 | 407 | ||
408 | The high-level CIS tuple services | 408 | The high-level CIS tuple services |
409 | 409 | ||
410 | ======================================================================*/ | 410 | ======================================================================*/ |
411 | 411 | ||
412 | typedef struct tuple_flags { | 412 | typedef struct tuple_flags { |
@@ -421,8 +421,6 @@ typedef struct tuple_flags { | |||
421 | #define MFC_FN(f) (((tuple_flags *)(&(f)))->mfc_fn) | 421 | #define MFC_FN(f) (((tuple_flags *)(&(f)))->mfc_fn) |
422 | #define SPACE(f) (((tuple_flags *)(&(f)))->space) | 422 | #define SPACE(f) (((tuple_flags *)(&(f)))->space) |
423 | 423 | ||
424 | int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *tuple); | ||
425 | |||
426 | int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple) | 424 | int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple) |
427 | { | 425 | { |
428 | if (!s) | 426 | if (!s) |
@@ -523,10 +521,11 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ | |||
523 | ofs++; continue; | 521 | ofs++; continue; |
524 | } | 522 | } |
525 | } | 523 | } |
526 | 524 | ||
527 | /* End of chain? Follow long link if possible */ | 525 | /* End of chain? Follow long link if possible */ |
528 | if (link[0] == CISTPL_END) { | 526 | if (link[0] == CISTPL_END) { |
529 | if ((ofs = follow_link(s, tuple)) < 0) | 527 | ofs = follow_link(s, tuple); |
528 | if (ofs < 0) | ||
530 | return -ENOSPC; | 529 | return -ENOSPC; |
531 | attr = SPACE(tuple->Flags); | 530 | attr = SPACE(tuple->Flags); |
532 | read_cis_cache(s, attr, ofs, 2, link); | 531 | read_cis_cache(s, attr, ofs, 2, link); |
@@ -578,7 +577,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ | |||
578 | } else | 577 | } else |
579 | if (tuple->DesiredTuple == RETURN_FIRST_TUPLE) | 578 | if (tuple->DesiredTuple == RETURN_FIRST_TUPLE) |
580 | break; | 579 | break; |
581 | 580 | ||
582 | if (link[0] == tuple->DesiredTuple) | 581 | if (link[0] == tuple->DesiredTuple) |
583 | break; | 582 | break; |
584 | ofs += link[1] + 2; | 583 | ofs += link[1] + 2; |
@@ -587,7 +586,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ | |||
587 | dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n"); | 586 | dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n"); |
588 | return -ENOSPC; | 587 | return -ENOSPC; |
589 | } | 588 | } |
590 | 589 | ||
591 | tuple->TupleCode = link[0]; | 590 | tuple->TupleCode = link[0]; |
592 | tuple->TupleLink = link[1]; | 591 | tuple->TupleLink = link[1]; |
593 | tuple->CISOffset = ofs + 2; | 592 | tuple->CISOffset = ofs + 2; |
@@ -623,7 +622,7 @@ EXPORT_SYMBOL(pccard_get_tuple_data); | |||
623 | /*====================================================================== | 622 | /*====================================================================== |
624 | 623 | ||
625 | Parsing routines for individual tuples | 624 | Parsing routines for individual tuples |
626 | 625 | ||
627 | ======================================================================*/ | 626 | ======================================================================*/ |
628 | 627 | ||
629 | static int parse_device(tuple_t *tuple, cistpl_device_t *device) | 628 | static int parse_device(tuple_t *tuple, cistpl_device_t *device) |
@@ -637,26 +636,37 @@ static int parse_device(tuple_t *tuple, cistpl_device_t *device) | |||
637 | 636 | ||
638 | device->ndev = 0; | 637 | device->ndev = 0; |
639 | for (i = 0; i < CISTPL_MAX_DEVICES; i++) { | 638 | for (i = 0; i < CISTPL_MAX_DEVICES; i++) { |
640 | 639 | ||
641 | if (*p == 0xff) break; | 640 | if (*p == 0xff) |
641 | break; | ||
642 | device->dev[i].type = (*p >> 4); | 642 | device->dev[i].type = (*p >> 4); |
643 | device->dev[i].wp = (*p & 0x08) ? 1 : 0; | 643 | device->dev[i].wp = (*p & 0x08) ? 1 : 0; |
644 | switch (*p & 0x07) { | 644 | switch (*p & 0x07) { |
645 | case 0: device->dev[i].speed = 0; break; | 645 | case 0: |
646 | case 1: device->dev[i].speed = 250; break; | 646 | device->dev[i].speed = 0; |
647 | case 2: device->dev[i].speed = 200; break; | 647 | break; |
648 | case 3: device->dev[i].speed = 150; break; | 648 | case 1: |
649 | case 4: device->dev[i].speed = 100; break; | 649 | device->dev[i].speed = 250; |
650 | break; | ||
651 | case 2: | ||
652 | device->dev[i].speed = 200; | ||
653 | break; | ||
654 | case 3: | ||
655 | device->dev[i].speed = 150; | ||
656 | break; | ||
657 | case 4: | ||
658 | device->dev[i].speed = 100; | ||
659 | break; | ||
650 | case 7: | 660 | case 7: |
651 | if (++p == q) | ||
652 | return -EINVAL; | ||
653 | device->dev[i].speed = SPEED_CVT(*p); | ||
654 | while (*p & 0x80) | ||
655 | if (++p == q) | 661 | if (++p == q) |
656 | return -EINVAL; | 662 | return -EINVAL; |
657 | break; | 663 | device->dev[i].speed = SPEED_CVT(*p); |
664 | while (*p & 0x80) | ||
665 | if (++p == q) | ||
666 | return -EINVAL; | ||
667 | break; | ||
658 | default: | 668 | default: |
659 | return -EINVAL; | 669 | return -EINVAL; |
660 | } | 670 | } |
661 | 671 | ||
662 | if (++p == q) | 672 | if (++p == q) |
@@ -671,7 +681,7 @@ static int parse_device(tuple_t *tuple, cistpl_device_t *device) | |||
671 | if (++p == q) | 681 | if (++p == q) |
672 | break; | 682 | break; |
673 | } | 683 | } |
674 | 684 | ||
675 | return 0; | 685 | return 0; |
676 | } | 686 | } |
677 | 687 | ||
@@ -706,9 +716,9 @@ static int parse_longlink_mfc(tuple_t *tuple, | |||
706 | { | 716 | { |
707 | u_char *p; | 717 | u_char *p; |
708 | int i; | 718 | int i; |
709 | 719 | ||
710 | p = (u_char *)tuple->TupleData; | 720 | p = (u_char *)tuple->TupleData; |
711 | 721 | ||
712 | link->nfn = *p; p++; | 722 | link->nfn = *p; p++; |
713 | if (tuple->TupleDataLen <= link->nfn*5) | 723 | if (tuple->TupleDataLen <= link->nfn*5) |
714 | return -EINVAL; | 724 | return -EINVAL; |
@@ -737,11 +747,13 @@ static int parse_strings(u_char *p, u_char *q, int max, | |||
737 | ns++; | 747 | ns++; |
738 | for (;;) { | 748 | for (;;) { |
739 | s[j++] = (*p == 0xff) ? '\0' : *p; | 749 | s[j++] = (*p == 0xff) ? '\0' : *p; |
740 | if ((*p == '\0') || (*p == 0xff)) break; | 750 | if ((*p == '\0') || (*p == 0xff)) |
751 | break; | ||
741 | if (++p == q) | 752 | if (++p == q) |
742 | return -EINVAL; | 753 | return -EINVAL; |
743 | } | 754 | } |
744 | if ((*p == 0xff) || (++p == q)) break; | 755 | if ((*p == 0xff) || (++p == q)) |
756 | break; | ||
745 | } | 757 | } |
746 | if (found) { | 758 | if (found) { |
747 | *found = ns; | 759 | *found = ns; |
@@ -756,10 +768,10 @@ static int parse_strings(u_char *p, u_char *q, int max, | |||
756 | static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1) | 768 | static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1) |
757 | { | 769 | { |
758 | u_char *p, *q; | 770 | u_char *p, *q; |
759 | 771 | ||
760 | p = (u_char *)tuple->TupleData; | 772 | p = (u_char *)tuple->TupleData; |
761 | q = p + tuple->TupleDataLen; | 773 | q = p + tuple->TupleDataLen; |
762 | 774 | ||
763 | vers_1->major = *p; p++; | 775 | vers_1->major = *p; p++; |
764 | vers_1->minor = *p; p++; | 776 | vers_1->minor = *p; p++; |
765 | if (p >= q) | 777 | if (p >= q) |
@@ -774,10 +786,10 @@ static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1) | |||
774 | static int parse_altstr(tuple_t *tuple, cistpl_altstr_t *altstr) | 786 | static int parse_altstr(tuple_t *tuple, cistpl_altstr_t *altstr) |
775 | { | 787 | { |
776 | u_char *p, *q; | 788 | u_char *p, *q; |
777 | 789 | ||
778 | p = (u_char *)tuple->TupleData; | 790 | p = (u_char *)tuple->TupleData; |
779 | q = p + tuple->TupleDataLen; | 791 | q = p + tuple->TupleDataLen; |
780 | 792 | ||
781 | return parse_strings(p, q, CISTPL_MAX_ALTSTR_STRINGS, | 793 | return parse_strings(p, q, CISTPL_MAX_ALTSTR_STRINGS, |
782 | altstr->str, altstr->ofs, &altstr->ns); | 794 | altstr->str, altstr->ofs, &altstr->ns); |
783 | } | 795 | } |
@@ -793,7 +805,8 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec) | |||
793 | q = p + tuple->TupleDataLen; | 805 | q = p + tuple->TupleDataLen; |
794 | 806 | ||
795 | for (nid = 0; nid < CISTPL_MAX_DEVICES; nid++) { | 807 | for (nid = 0; nid < CISTPL_MAX_DEVICES; nid++) { |
796 | if (p > q-2) break; | 808 | if (p > q-2) |
809 | break; | ||
797 | jedec->id[nid].mfr = p[0]; | 810 | jedec->id[nid].mfr = p[0]; |
798 | jedec->id[nid].info = p[1]; | 811 | jedec->id[nid].info = p[1]; |
799 | p += 2; | 812 | p += 2; |
@@ -871,7 +884,7 @@ static int parse_config(tuple_t *tuple, cistpl_config_t *config) | |||
871 | 884 | ||
872 | The following routines are all used to parse the nightmarish | 885 | The following routines are all used to parse the nightmarish |
873 | config table entries. | 886 | config table entries. |
874 | 887 | ||
875 | ======================================================================*/ | 888 | ======================================================================*/ |
876 | 889 | ||
877 | static u_char *parse_power(u_char *p, u_char *q, | 890 | static u_char *parse_power(u_char *p, u_char *q, |
@@ -880,17 +893,20 @@ static u_char *parse_power(u_char *p, u_char *q, | |||
880 | int i; | 893 | int i; |
881 | u_int scale; | 894 | u_int scale; |
882 | 895 | ||
883 | if (p == q) return NULL; | 896 | if (p == q) |
897 | return NULL; | ||
884 | pwr->present = *p; | 898 | pwr->present = *p; |
885 | pwr->flags = 0; | 899 | pwr->flags = 0; |
886 | p++; | 900 | p++; |
887 | for (i = 0; i < 7; i++) | 901 | for (i = 0; i < 7; i++) |
888 | if (pwr->present & (1<<i)) { | 902 | if (pwr->present & (1<<i)) { |
889 | if (p == q) return NULL; | 903 | if (p == q) |
904 | return NULL; | ||
890 | pwr->param[i] = POWER_CVT(*p); | 905 | pwr->param[i] = POWER_CVT(*p); |
891 | scale = POWER_SCALE(*p); | 906 | scale = POWER_SCALE(*p); |
892 | while (*p & 0x80) { | 907 | while (*p & 0x80) { |
893 | if (++p == q) return NULL; | 908 | if (++p == q) |
909 | return NULL; | ||
894 | if ((*p & 0x7f) < 100) | 910 | if ((*p & 0x7f) < 100) |
895 | pwr->param[i] += (*p & 0x7f) * scale / 100; | 911 | pwr->param[i] += (*p & 0x7f) * scale / 100; |
896 | else if (*p == 0x7d) | 912 | else if (*p == 0x7d) |
@@ -914,24 +930,28 @@ static u_char *parse_timing(u_char *p, u_char *q, | |||
914 | { | 930 | { |
915 | u_char scale; | 931 | u_char scale; |
916 | 932 | ||
917 | if (p == q) return NULL; | 933 | if (p == q) |
934 | return NULL; | ||
918 | scale = *p; | 935 | scale = *p; |
919 | if ((scale & 3) != 3) { | 936 | if ((scale & 3) != 3) { |
920 | if (++p == q) return NULL; | 937 | if (++p == q) |
938 | return NULL; | ||
921 | timing->wait = SPEED_CVT(*p); | 939 | timing->wait = SPEED_CVT(*p); |
922 | timing->waitscale = exponent[scale & 3]; | 940 | timing->waitscale = exponent[scale & 3]; |
923 | } else | 941 | } else |
924 | timing->wait = 0; | 942 | timing->wait = 0; |
925 | scale >>= 2; | 943 | scale >>= 2; |
926 | if ((scale & 7) != 7) { | 944 | if ((scale & 7) != 7) { |
927 | if (++p == q) return NULL; | 945 | if (++p == q) |
946 | return NULL; | ||
928 | timing->ready = SPEED_CVT(*p); | 947 | timing->ready = SPEED_CVT(*p); |
929 | timing->rdyscale = exponent[scale & 7]; | 948 | timing->rdyscale = exponent[scale & 7]; |
930 | } else | 949 | } else |
931 | timing->ready = 0; | 950 | timing->ready = 0; |
932 | scale >>= 3; | 951 | scale >>= 3; |
933 | if (scale != 7) { | 952 | if (scale != 7) { |
934 | if (++p == q) return NULL; | 953 | if (++p == q) |
954 | return NULL; | ||
935 | timing->reserved = SPEED_CVT(*p); | 955 | timing->reserved = SPEED_CVT(*p); |
936 | timing->rsvscale = exponent[scale]; | 956 | timing->rsvscale = exponent[scale]; |
937 | } else | 957 | } else |
@@ -946,7 +966,8 @@ static u_char *parse_io(u_char *p, u_char *q, cistpl_io_t *io) | |||
946 | { | 966 | { |
947 | int i, j, bsz, lsz; | 967 | int i, j, bsz, lsz; |
948 | 968 | ||
949 | if (p == q) return NULL; | 969 | if (p == q) |
970 | return NULL; | ||
950 | io->flags = *p; | 971 | io->flags = *p; |
951 | 972 | ||
952 | if (!(*p & 0x80)) { | 973 | if (!(*p & 0x80)) { |
@@ -955,24 +976,29 @@ static u_char *parse_io(u_char *p, u_char *q, cistpl_io_t *io) | |||
955 | io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK)); | 976 | io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK)); |
956 | return p+1; | 977 | return p+1; |
957 | } | 978 | } |
958 | 979 | ||
959 | if (++p == q) return NULL; | 980 | if (++p == q) |
981 | return NULL; | ||
960 | io->nwin = (*p & 0x0f) + 1; | 982 | io->nwin = (*p & 0x0f) + 1; |
961 | bsz = (*p & 0x30) >> 4; | 983 | bsz = (*p & 0x30) >> 4; |
962 | if (bsz == 3) bsz++; | 984 | if (bsz == 3) |
985 | bsz++; | ||
963 | lsz = (*p & 0xc0) >> 6; | 986 | lsz = (*p & 0xc0) >> 6; |
964 | if (lsz == 3) lsz++; | 987 | if (lsz == 3) |
988 | lsz++; | ||
965 | p++; | 989 | p++; |
966 | 990 | ||
967 | for (i = 0; i < io->nwin; i++) { | 991 | for (i = 0; i < io->nwin; i++) { |
968 | io->win[i].base = 0; | 992 | io->win[i].base = 0; |
969 | io->win[i].len = 1; | 993 | io->win[i].len = 1; |
970 | for (j = 0; j < bsz; j++, p++) { | 994 | for (j = 0; j < bsz; j++, p++) { |
971 | if (p == q) return NULL; | 995 | if (p == q) |
996 | return NULL; | ||
972 | io->win[i].base += *p << (j*8); | 997 | io->win[i].base += *p << (j*8); |
973 | } | 998 | } |
974 | for (j = 0; j < lsz; j++, p++) { | 999 | for (j = 0; j < lsz; j++, p++) { |
975 | if (p == q) return NULL; | 1000 | if (p == q) |
1001 | return NULL; | ||
976 | io->win[i].len += *p << (j*8); | 1002 | io->win[i].len += *p << (j*8); |
977 | } | 1003 | } |
978 | } | 1004 | } |
@@ -986,27 +1012,32 @@ static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem) | |||
986 | int i, j, asz, lsz, has_ha; | 1012 | int i, j, asz, lsz, has_ha; |
987 | u_int len, ca, ha; | 1013 | u_int len, ca, ha; |
988 | 1014 | ||
989 | if (p == q) return NULL; | 1015 | if (p == q) |
1016 | return NULL; | ||
990 | 1017 | ||
991 | mem->nwin = (*p & 0x07) + 1; | 1018 | mem->nwin = (*p & 0x07) + 1; |
992 | lsz = (*p & 0x18) >> 3; | 1019 | lsz = (*p & 0x18) >> 3; |
993 | asz = (*p & 0x60) >> 5; | 1020 | asz = (*p & 0x60) >> 5; |
994 | has_ha = (*p & 0x80); | 1021 | has_ha = (*p & 0x80); |
995 | if (++p == q) return NULL; | 1022 | if (++p == q) |
996 | 1023 | return NULL; | |
1024 | |||
997 | for (i = 0; i < mem->nwin; i++) { | 1025 | for (i = 0; i < mem->nwin; i++) { |
998 | len = ca = ha = 0; | 1026 | len = ca = ha = 0; |
999 | for (j = 0; j < lsz; j++, p++) { | 1027 | for (j = 0; j < lsz; j++, p++) { |
1000 | if (p == q) return NULL; | 1028 | if (p == q) |
1029 | return NULL; | ||
1001 | len += *p << (j*8); | 1030 | len += *p << (j*8); |
1002 | } | 1031 | } |
1003 | for (j = 0; j < asz; j++, p++) { | 1032 | for (j = 0; j < asz; j++, p++) { |
1004 | if (p == q) return NULL; | 1033 | if (p == q) |
1034 | return NULL; | ||
1005 | ca += *p << (j*8); | 1035 | ca += *p << (j*8); |
1006 | } | 1036 | } |
1007 | if (has_ha) | 1037 | if (has_ha) |
1008 | for (j = 0; j < asz; j++, p++) { | 1038 | for (j = 0; j < asz; j++, p++) { |
1009 | if (p == q) return NULL; | 1039 | if (p == q) |
1040 | return NULL; | ||
1010 | ha += *p << (j*8); | 1041 | ha += *p << (j*8); |
1011 | } | 1042 | } |
1012 | mem->win[i].len = len << 8; | 1043 | mem->win[i].len = len << 8; |
@@ -1095,7 +1126,7 @@ static int parse_cftable_entry(tuple_t *tuple, | |||
1095 | entry->timing.ready = 0; | 1126 | entry->timing.ready = 0; |
1096 | entry->timing.reserved = 0; | 1127 | entry->timing.reserved = 0; |
1097 | } | 1128 | } |
1098 | 1129 | ||
1099 | /* I/O window options */ | 1130 | /* I/O window options */ |
1100 | if (features & 0x08) { | 1131 | if (features & 0x08) { |
1101 | p = parse_io(p, q, &entry->io); | 1132 | p = parse_io(p, q, &entry->io); |
@@ -1103,7 +1134,7 @@ static int parse_cftable_entry(tuple_t *tuple, | |||
1103 | return -EINVAL; | 1134 | return -EINVAL; |
1104 | } else | 1135 | } else |
1105 | entry->io.nwin = 0; | 1136 | entry->io.nwin = 0; |
1106 | 1137 | ||
1107 | /* Interrupt options */ | 1138 | /* Interrupt options */ |
1108 | if (features & 0x10) { | 1139 | if (features & 0x10) { |
1109 | p = parse_irq(p, q, &entry->irq); | 1140 | p = parse_irq(p, q, &entry->irq); |
@@ -1153,7 +1184,7 @@ static int parse_cftable_entry(tuple_t *tuple, | |||
1153 | } | 1184 | } |
1154 | 1185 | ||
1155 | entry->subtuples = q-p; | 1186 | entry->subtuples = q-p; |
1156 | 1187 | ||
1157 | return 0; | 1188 | return 0; |
1158 | } | 1189 | } |
1159 | 1190 | ||
@@ -1176,7 +1207,7 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar) | |||
1176 | static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config) | 1207 | static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config) |
1177 | { | 1208 | { |
1178 | u_char *p; | 1209 | u_char *p; |
1179 | 1210 | ||
1180 | p = (u_char *)tuple->TupleData; | 1211 | p = (u_char *)tuple->TupleData; |
1181 | if ((*p != 3) || (tuple->TupleDataLen < 6)) | 1212 | if ((*p != 3) || (tuple->TupleDataLen < 6)) |
1182 | return -EINVAL; | 1213 | return -EINVAL; |
@@ -1231,7 +1262,7 @@ static int parse_cftable_entry_cb(tuple_t *tuple, | |||
1231 | entry->io = *p; p++; | 1262 | entry->io = *p; p++; |
1232 | } else | 1263 | } else |
1233 | entry->io = 0; | 1264 | entry->io = 0; |
1234 | 1265 | ||
1235 | /* Interrupt options */ | 1266 | /* Interrupt options */ |
1236 | if (features & 0x10) { | 1267 | if (features & 0x10) { |
1237 | p = parse_irq(p, q, &entry->irq); | 1268 | p = parse_irq(p, q, &entry->irq); |
@@ -1264,7 +1295,7 @@ static int parse_cftable_entry_cb(tuple_t *tuple, | |||
1264 | } | 1295 | } |
1265 | 1296 | ||
1266 | entry->subtuples = q-p; | 1297 | entry->subtuples = q-p; |
1267 | 1298 | ||
1268 | return 0; | 1299 | return 0; |
1269 | } | 1300 | } |
1270 | 1301 | ||
@@ -1281,7 +1312,8 @@ static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo) | |||
1281 | q = p + tuple->TupleDataLen; | 1312 | q = p + tuple->TupleDataLen; |
1282 | 1313 | ||
1283 | for (n = 0; n < CISTPL_MAX_DEVICES; n++) { | 1314 | for (n = 0; n < CISTPL_MAX_DEVICES; n++) { |
1284 | if (p > q-6) break; | 1315 | if (p > q-6) |
1316 | break; | ||
1285 | geo->geo[n].buswidth = p[0]; | 1317 | geo->geo[n].buswidth = p[0]; |
1286 | geo->geo[n].erase_block = 1 << (p[1]-1); | 1318 | geo->geo[n].erase_block = 1 << (p[1]-1); |
1287 | geo->geo[n].read_block = 1 << (p[2]-1); | 1319 | geo->geo[n].read_block = 1 << (p[2]-1); |
@@ -1302,13 +1334,13 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2) | |||
1302 | 1334 | ||
1303 | if (tuple->TupleDataLen < 10) | 1335 | if (tuple->TupleDataLen < 10) |
1304 | return -EINVAL; | 1336 | return -EINVAL; |
1305 | 1337 | ||
1306 | p = tuple->TupleData; | 1338 | p = tuple->TupleData; |
1307 | q = p + tuple->TupleDataLen; | 1339 | q = p + tuple->TupleDataLen; |
1308 | 1340 | ||
1309 | v2->vers = p[0]; | 1341 | v2->vers = p[0]; |
1310 | v2->comply = p[1]; | 1342 | v2->comply = p[1]; |
1311 | v2->dindex = get_unaligned_le16(p +2 ); | 1343 | v2->dindex = get_unaligned_le16(p + 2); |
1312 | v2->vspec8 = p[6]; | 1344 | v2->vspec8 = p[6]; |
1313 | v2->vspec9 = p[7]; | 1345 | v2->vspec9 = p[7]; |
1314 | v2->nhdr = p[8]; | 1346 | v2->nhdr = p[8]; |
@@ -1322,7 +1354,7 @@ static int parse_org(tuple_t *tuple, cistpl_org_t *org) | |||
1322 | { | 1354 | { |
1323 | u_char *p, *q; | 1355 | u_char *p, *q; |
1324 | int i; | 1356 | int i; |
1325 | 1357 | ||
1326 | p = tuple->TupleData; | 1358 | p = tuple->TupleData; |
1327 | q = p + tuple->TupleDataLen; | 1359 | q = p + tuple->TupleDataLen; |
1328 | if (p == q) | 1360 | if (p == q) |
@@ -1332,7 +1364,8 @@ static int parse_org(tuple_t *tuple, cistpl_org_t *org) | |||
1332 | return -EINVAL; | 1364 | return -EINVAL; |
1333 | for (i = 0; i < 30; i++) { | 1365 | for (i = 0; i < 30; i++) { |
1334 | org->desc[i] = *p; | 1366 | org->desc[i] = *p; |
1335 | if (*p == '\0') break; | 1367 | if (*p == '\0') |
1368 | break; | ||
1336 | if (++p == q) | 1369 | if (++p == q) |
1337 | return -EINVAL; | 1370 | return -EINVAL; |
1338 | } | 1371 | } |
@@ -1363,7 +1396,7 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt) | |||
1363 | int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse) | 1396 | int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse) |
1364 | { | 1397 | { |
1365 | int ret = 0; | 1398 | int ret = 0; |
1366 | 1399 | ||
1367 | if (tuple->TupleDataLen > tuple->TupleDataMax) | 1400 | if (tuple->TupleDataLen > tuple->TupleDataMax) |
1368 | return -EINVAL; | 1401 | return -EINVAL; |
1369 | switch (tuple->TupleCode) { | 1402 | switch (tuple->TupleCode) { |
@@ -1448,7 +1481,7 @@ EXPORT_SYMBOL(pcmcia_parse_tuple); | |||
1448 | /*====================================================================== | 1481 | /*====================================================================== |
1449 | 1482 | ||
1450 | This is used internally by Card Services to look up CIS stuff. | 1483 | This is used internally by Card Services to look up CIS stuff. |
1451 | 1484 | ||
1452 | ======================================================================*/ | 1485 | ======================================================================*/ |
1453 | 1486 | ||
1454 | int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse) | 1487 | int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse) |
@@ -1550,7 +1583,7 @@ EXPORT_SYMBOL(pccard_loop_tuple); | |||
1550 | checks include making sure several critical tuples are present and | 1583 | checks include making sure several critical tuples are present and |
1551 | valid; seeing if the total number of tuples is reasonable; and | 1584 | valid; seeing if the total number of tuples is reasonable; and |
1552 | looking for tuples that use reserved codes. | 1585 | looking for tuples that use reserved codes. |
1553 | 1586 | ||
1554 | ======================================================================*/ | 1587 | ======================================================================*/ |
1555 | 1588 | ||
1556 | int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info) | 1589 | int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info) |