diff options
| -rw-r--r-- | drivers/pcmcia/cistpl.c | 144 | ||||
| -rw-r--r-- | drivers/pcmcia/cs_internal.h | 6 | ||||
| -rw-r--r-- | drivers/pcmcia/ds.c | 1 | ||||
| -rw-r--r-- | drivers/pcmcia/pcmcia_ioctl.c | 2 | ||||
| -rw-r--r-- | include/pcmcia/cs.h | 2 |
5 files changed, 99 insertions, 56 deletions
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index a59e09dd8557..772fc96d5ec3 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c | |||
| @@ -647,22 +647,28 @@ static int parse_device(tuple_t *tuple, cistpl_device_t *device) | |||
| 647 | case 3: device->dev[i].speed = 150; break; | 647 | case 3: device->dev[i].speed = 150; break; |
| 648 | case 4: device->dev[i].speed = 100; break; | 648 | case 4: device->dev[i].speed = 100; break; |
| 649 | case 7: | 649 | case 7: |
| 650 | if (++p == q) return CS_BAD_TUPLE; | 650 | if (++p == q) |
| 651 | return -EINVAL; | ||
| 651 | device->dev[i].speed = SPEED_CVT(*p); | 652 | device->dev[i].speed = SPEED_CVT(*p); |
| 652 | while (*p & 0x80) | 653 | while (*p & 0x80) |
| 653 | if (++p == q) return CS_BAD_TUPLE; | 654 | if (++p == q) |
| 655 | return -EINVAL; | ||
| 654 | break; | 656 | break; |
| 655 | default: | 657 | default: |
| 656 | return CS_BAD_TUPLE; | 658 | return -EINVAL; |
| 657 | } | 659 | } |
| 658 | 660 | ||
| 659 | if (++p == q) return CS_BAD_TUPLE; | 661 | if (++p == q) |
| 660 | if (*p == 0xff) break; | 662 | return -EINVAL; |
| 663 | if (*p == 0xff) | ||
| 664 | break; | ||
| 661 | scale = *p & 7; | 665 | scale = *p & 7; |
| 662 | if (scale == 7) return CS_BAD_TUPLE; | 666 | if (scale == 7) |
| 667 | return -EINVAL; | ||
| 663 | device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2)); | 668 | device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2)); |
| 664 | device->ndev++; | 669 | device->ndev++; |
| 665 | if (++p == q) break; | 670 | if (++p == q) |
| 671 | break; | ||
| 666 | } | 672 | } |
| 667 | 673 | ||
| 668 | return 0; | 674 | return 0; |
| @@ -674,7 +680,7 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum) | |||
| 674 | { | 680 | { |
| 675 | u_char *p; | 681 | u_char *p; |
| 676 | if (tuple->TupleDataLen < 5) | 682 | if (tuple->TupleDataLen < 5) |
| 677 | return CS_BAD_TUPLE; | 683 | return -EINVAL; |
| 678 | p = (u_char *) tuple->TupleData; | 684 | p = (u_char *) tuple->TupleData; |
| 679 | csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2; | 685 | csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2; |
| 680 | csum->len = get_unaligned_le16(p + 2); | 686 | csum->len = get_unaligned_le16(p + 2); |
| @@ -687,7 +693,7 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum) | |||
| 687 | static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link) | 693 | static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link) |
| 688 | { | 694 | { |
| 689 | if (tuple->TupleDataLen < 4) | 695 | if (tuple->TupleDataLen < 4) |
| 690 | return CS_BAD_TUPLE; | 696 | return -EINVAL; |
| 691 | link->addr = get_unaligned_le32(tuple->TupleData); | 697 | link->addr = get_unaligned_le32(tuple->TupleData); |
| 692 | return 0; | 698 | return 0; |
| 693 | } | 699 | } |
| @@ -704,7 +710,7 @@ static int parse_longlink_mfc(tuple_t *tuple, | |||
| 704 | 710 | ||
| 705 | link->nfn = *p; p++; | 711 | link->nfn = *p; p++; |
| 706 | if (tuple->TupleDataLen <= link->nfn*5) | 712 | if (tuple->TupleDataLen <= link->nfn*5) |
| 707 | return CS_BAD_TUPLE; | 713 | return -EINVAL; |
| 708 | for (i = 0; i < link->nfn; i++) { | 714 | for (i = 0; i < link->nfn; i++) { |
| 709 | link->fn[i].space = *p; p++; | 715 | link->fn[i].space = *p; p++; |
| 710 | link->fn[i].addr = get_unaligned_le32(p); | 716 | link->fn[i].addr = get_unaligned_le32(p); |
| @@ -720,16 +726,19 @@ static int parse_strings(u_char *p, u_char *q, int max, | |||
| 720 | { | 726 | { |
| 721 | int i, j, ns; | 727 | int i, j, ns; |
| 722 | 728 | ||
| 723 | if (p == q) return CS_BAD_TUPLE; | 729 | if (p == q) |
| 730 | return -EINVAL; | ||
| 724 | ns = 0; j = 0; | 731 | ns = 0; j = 0; |
| 725 | for (i = 0; i < max; i++) { | 732 | for (i = 0; i < max; i++) { |
| 726 | if (*p == 0xff) break; | 733 | if (*p == 0xff) |
| 734 | break; | ||
| 727 | ofs[i] = j; | 735 | ofs[i] = j; |
| 728 | ns++; | 736 | ns++; |
| 729 | for (;;) { | 737 | for (;;) { |
| 730 | s[j++] = (*p == 0xff) ? '\0' : *p; | 738 | s[j++] = (*p == 0xff) ? '\0' : *p; |
| 731 | if ((*p == '\0') || (*p == 0xff)) break; | 739 | if ((*p == '\0') || (*p == 0xff)) break; |
| 732 | if (++p == q) return CS_BAD_TUPLE; | 740 | if (++p == q) |
| 741 | return -EINVAL; | ||
| 733 | } | 742 | } |
| 734 | if ((*p == 0xff) || (++p == q)) break; | 743 | if ((*p == 0xff) || (++p == q)) break; |
| 735 | } | 744 | } |
| @@ -737,7 +746,7 @@ static int parse_strings(u_char *p, u_char *q, int max, | |||
| 737 | *found = ns; | 746 | *found = ns; |
| 738 | return 0; | 747 | return 0; |
| 739 | } else { | 748 | } else { |
| 740 | return (ns == max) ? 0 : CS_BAD_TUPLE; | 749 | return (ns == max) ? 0 : -EINVAL; |
| 741 | } | 750 | } |
| 742 | } | 751 | } |
| 743 | 752 | ||
| @@ -752,7 +761,8 @@ static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1) | |||
| 752 | 761 | ||
| 753 | vers_1->major = *p; p++; | 762 | vers_1->major = *p; p++; |
| 754 | vers_1->minor = *p; p++; | 763 | vers_1->minor = *p; p++; |
| 755 | if (p >= q) return CS_BAD_TUPLE; | 764 | if (p >= q) |
| 765 | return -EINVAL; | ||
| 756 | 766 | ||
| 757 | return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS, | 767 | return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS, |
| 758 | vers_1->str, vers_1->ofs, &vers_1->ns); | 768 | vers_1->str, vers_1->ofs, &vers_1->ns); |
| @@ -796,7 +806,7 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec) | |||
| 796 | static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m) | 806 | static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m) |
| 797 | { | 807 | { |
| 798 | if (tuple->TupleDataLen < 4) | 808 | if (tuple->TupleDataLen < 4) |
| 799 | return CS_BAD_TUPLE; | 809 | return -EINVAL; |
| 800 | m->manf = get_unaligned_le16(tuple->TupleData); | 810 | m->manf = get_unaligned_le16(tuple->TupleData); |
| 801 | m->card = get_unaligned_le16(tuple->TupleData + 2); | 811 | m->card = get_unaligned_le16(tuple->TupleData + 2); |
| 802 | return 0; | 812 | return 0; |
| @@ -808,7 +818,7 @@ static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f) | |||
| 808 | { | 818 | { |
| 809 | u_char *p; | 819 | u_char *p; |
| 810 | if (tuple->TupleDataLen < 2) | 820 | if (tuple->TupleDataLen < 2) |
| 811 | return CS_BAD_TUPLE; | 821 | return -EINVAL; |
| 812 | p = (u_char *)tuple->TupleData; | 822 | p = (u_char *)tuple->TupleData; |
| 813 | f->func = p[0]; | 823 | f->func = p[0]; |
| 814 | f->sysinit = p[1]; | 824 | f->sysinit = p[1]; |
| @@ -822,7 +832,7 @@ static int parse_funce(tuple_t *tuple, cistpl_funce_t *f) | |||
| 822 | u_char *p; | 832 | u_char *p; |
| 823 | int i; | 833 | int i; |
| 824 | if (tuple->TupleDataLen < 1) | 834 | if (tuple->TupleDataLen < 1) |
| 825 | return CS_BAD_TUPLE; | 835 | return -EINVAL; |
| 826 | p = (u_char *)tuple->TupleData; | 836 | p = (u_char *)tuple->TupleData; |
| 827 | f->type = p[0]; | 837 | f->type = p[0]; |
| 828 | for (i = 1; i < tuple->TupleDataLen; i++) | 838 | for (i = 1; i < tuple->TupleDataLen; i++) |
| @@ -841,7 +851,7 @@ static int parse_config(tuple_t *tuple, cistpl_config_t *config) | |||
| 841 | rasz = *p & 0x03; | 851 | rasz = *p & 0x03; |
| 842 | rmsz = (*p & 0x3c) >> 2; | 852 | rmsz = (*p & 0x3c) >> 2; |
| 843 | if (tuple->TupleDataLen < rasz+rmsz+4) | 853 | if (tuple->TupleDataLen < rasz+rmsz+4) |
| 844 | return CS_BAD_TUPLE; | 854 | return -EINVAL; |
| 845 | config->last_idx = *(++p); | 855 | config->last_idx = *(++p); |
| 846 | p++; | 856 | p++; |
| 847 | config->base = 0; | 857 | config->base = 0; |
| @@ -1009,10 +1019,12 @@ static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem) | |||
| 1009 | 1019 | ||
| 1010 | static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq) | 1020 | static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq) |
| 1011 | { | 1021 | { |
| 1012 | if (p == q) return NULL; | 1022 | if (p == q) |
| 1023 | return NULL; | ||
| 1013 | irq->IRQInfo1 = *p; p++; | 1024 | irq->IRQInfo1 = *p; p++; |
| 1014 | if (irq->IRQInfo1 & IRQ_INFO2_VALID) { | 1025 | if (irq->IRQInfo1 & IRQ_INFO2_VALID) { |
| 1015 | if (p+2 > q) return NULL; | 1026 | if (p+2 > q) |
| 1027 | return NULL; | ||
| 1016 | irq->IRQInfo2 = (p[1]<<8) + p[0]; | 1028 | irq->IRQInfo2 = (p[1]<<8) + p[0]; |
| 1017 | p += 2; | 1029 | p += 2; |
| 1018 | } | 1030 | } |
| @@ -1033,7 +1045,8 @@ static int parse_cftable_entry(tuple_t *tuple, | |||
| 1033 | if (*p & 0x40) | 1045 | if (*p & 0x40) |
| 1034 | entry->flags |= CISTPL_CFTABLE_DEFAULT; | 1046 | entry->flags |= CISTPL_CFTABLE_DEFAULT; |
| 1035 | if (*p & 0x80) { | 1047 | if (*p & 0x80) { |
| 1036 | if (++p == q) return CS_BAD_TUPLE; | 1048 | if (++p == q) |
| 1049 | return -EINVAL; | ||
| 1037 | if (*p & 0x10) | 1050 | if (*p & 0x10) |
| 1038 | entry->flags |= CISTPL_CFTABLE_BVDS; | 1051 | entry->flags |= CISTPL_CFTABLE_BVDS; |
| 1039 | if (*p & 0x20) | 1052 | if (*p & 0x20) |
| @@ -1047,30 +1060,35 @@ static int parse_cftable_entry(tuple_t *tuple, | |||
| 1047 | entry->interface = 0; | 1060 | entry->interface = 0; |
| 1048 | 1061 | ||
| 1049 | /* Process optional features */ | 1062 | /* Process optional features */ |
| 1050 | if (++p == q) return CS_BAD_TUPLE; | 1063 | if (++p == q) |
| 1064 | return -EINVAL; | ||
| 1051 | features = *p; p++; | 1065 | features = *p; p++; |
| 1052 | 1066 | ||
| 1053 | /* Power options */ | 1067 | /* Power options */ |
| 1054 | if ((features & 3) > 0) { | 1068 | if ((features & 3) > 0) { |
| 1055 | p = parse_power(p, q, &entry->vcc); | 1069 | p = parse_power(p, q, &entry->vcc); |
| 1056 | if (p == NULL) return CS_BAD_TUPLE; | 1070 | if (p == NULL) |
| 1071 | return -EINVAL; | ||
| 1057 | } else | 1072 | } else |
| 1058 | entry->vcc.present = 0; | 1073 | entry->vcc.present = 0; |
| 1059 | if ((features & 3) > 1) { | 1074 | if ((features & 3) > 1) { |
| 1060 | p = parse_power(p, q, &entry->vpp1); | 1075 | p = parse_power(p, q, &entry->vpp1); |
| 1061 | if (p == NULL) return CS_BAD_TUPLE; | 1076 | if (p == NULL) |
| 1077 | return -EINVAL; | ||
| 1062 | } else | 1078 | } else |
| 1063 | entry->vpp1.present = 0; | 1079 | entry->vpp1.present = 0; |
| 1064 | if ((features & 3) > 2) { | 1080 | if ((features & 3) > 2) { |
| 1065 | p = parse_power(p, q, &entry->vpp2); | 1081 | p = parse_power(p, q, &entry->vpp2); |
| 1066 | if (p == NULL) return CS_BAD_TUPLE; | 1082 | if (p == NULL) |
| 1083 | return -EINVAL; | ||
| 1067 | } else | 1084 | } else |
| 1068 | entry->vpp2.present = 0; | 1085 | entry->vpp2.present = 0; |
| 1069 | 1086 | ||
| 1070 | /* Timing options */ | 1087 | /* Timing options */ |
| 1071 | if (features & 0x04) { | 1088 | if (features & 0x04) { |
| 1072 | p = parse_timing(p, q, &entry->timing); | 1089 | p = parse_timing(p, q, &entry->timing); |
| 1073 | if (p == NULL) return CS_BAD_TUPLE; | 1090 | if (p == NULL) |
| 1091 | return -EINVAL; | ||
| 1074 | } else { | 1092 | } else { |
| 1075 | entry->timing.wait = 0; | 1093 | entry->timing.wait = 0; |
| 1076 | entry->timing.ready = 0; | 1094 | entry->timing.ready = 0; |
| @@ -1080,14 +1098,16 @@ static int parse_cftable_entry(tuple_t *tuple, | |||
| 1080 | /* I/O window options */ | 1098 | /* I/O window options */ |
| 1081 | if (features & 0x08) { | 1099 | if (features & 0x08) { |
| 1082 | p = parse_io(p, q, &entry->io); | 1100 | p = parse_io(p, q, &entry->io); |
| 1083 | if (p == NULL) return CS_BAD_TUPLE; | 1101 | if (p == NULL) |
| 1102 | return -EINVAL; | ||
| 1084 | } else | 1103 | } else |
| 1085 | entry->io.nwin = 0; | 1104 | entry->io.nwin = 0; |
| 1086 | 1105 | ||
| 1087 | /* Interrupt options */ | 1106 | /* Interrupt options */ |
| 1088 | if (features & 0x10) { | 1107 | if (features & 0x10) { |
| 1089 | p = parse_irq(p, q, &entry->irq); | 1108 | p = parse_irq(p, q, &entry->irq); |
| 1090 | if (p == NULL) return CS_BAD_TUPLE; | 1109 | if (p == NULL) |
| 1110 | return -EINVAL; | ||
| 1091 | } else | 1111 | } else |
| 1092 | entry->irq.IRQInfo1 = 0; | 1112 | entry->irq.IRQInfo1 = 0; |
| 1093 | 1113 | ||
| @@ -1101,7 +1121,8 @@ static int parse_cftable_entry(tuple_t *tuple, | |||
| 1101 | entry->mem.win[0].card_addr = 0; | 1121 | entry->mem.win[0].card_addr = 0; |
| 1102 | entry->mem.win[0].host_addr = 0; | 1122 | entry->mem.win[0].host_addr = 0; |
| 1103 | p += 2; | 1123 | p += 2; |
| 1104 | if (p > q) return CS_BAD_TUPLE; | 1124 | if (p > q) |
| 1125 | return -EINVAL; | ||
| 1105 | break; | 1126 | break; |
| 1106 | case 0x40: | 1127 | case 0x40: |
| 1107 | entry->mem.nwin = 1; | 1128 | entry->mem.nwin = 1; |
| @@ -1109,20 +1130,24 @@ static int parse_cftable_entry(tuple_t *tuple, | |||
| 1109 | entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8; | 1130 | entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8; |
| 1110 | entry->mem.win[0].host_addr = 0; | 1131 | entry->mem.win[0].host_addr = 0; |
| 1111 | p += 4; | 1132 | p += 4; |
| 1112 | if (p > q) return CS_BAD_TUPLE; | 1133 | if (p > q) |
| 1134 | return -EINVAL; | ||
| 1113 | break; | 1135 | break; |
| 1114 | case 0x60: | 1136 | case 0x60: |
| 1115 | p = parse_mem(p, q, &entry->mem); | 1137 | p = parse_mem(p, q, &entry->mem); |
| 1116 | if (p == NULL) return CS_BAD_TUPLE; | 1138 | if (p == NULL) |
| 1139 | return -EINVAL; | ||
| 1117 | break; | 1140 | break; |
| 1118 | } | 1141 | } |
| 1119 | 1142 | ||
| 1120 | /* Misc features */ | 1143 | /* Misc features */ |
| 1121 | if (features & 0x80) { | 1144 | if (features & 0x80) { |
| 1122 | if (p == q) return CS_BAD_TUPLE; | 1145 | if (p == q) |
| 1146 | return -EINVAL; | ||
| 1123 | entry->flags |= (*p << 8); | 1147 | entry->flags |= (*p << 8); |
| 1124 | while (*p & 0x80) | 1148 | while (*p & 0x80) |
| 1125 | if (++p == q) return CS_BAD_TUPLE; | 1149 | if (++p == q) |
| 1150 | return -EINVAL; | ||
| 1126 | p++; | 1151 | p++; |
| 1127 | } | 1152 | } |
| 1128 | 1153 | ||
| @@ -1139,7 +1164,7 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar) | |||
| 1139 | { | 1164 | { |
| 1140 | u_char *p; | 1165 | u_char *p; |
| 1141 | if (tuple->TupleDataLen < 6) | 1166 | if (tuple->TupleDataLen < 6) |
| 1142 | return CS_BAD_TUPLE; | 1167 | return -EINVAL; |
| 1143 | p = (u_char *)tuple->TupleData; | 1168 | p = (u_char *)tuple->TupleData; |
| 1144 | bar->attr = *p; | 1169 | bar->attr = *p; |
| 1145 | p += 2; | 1170 | p += 2; |
| @@ -1153,7 +1178,7 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config) | |||
| 1153 | 1178 | ||
| 1154 | p = (u_char *)tuple->TupleData; | 1179 | p = (u_char *)tuple->TupleData; |
| 1155 | if ((*p != 3) || (tuple->TupleDataLen < 6)) | 1180 | if ((*p != 3) || (tuple->TupleDataLen < 6)) |
| 1156 | return CS_BAD_TUPLE; | 1181 | return -EINVAL; |
| 1157 | config->last_idx = *(++p); | 1182 | config->last_idx = *(++p); |
| 1158 | p++; | 1183 | p++; |
| 1159 | config->base = get_unaligned_le32(p); | 1184 | config->base = get_unaligned_le32(p); |
| @@ -1174,29 +1199,34 @@ static int parse_cftable_entry_cb(tuple_t *tuple, | |||
| 1174 | entry->flags |= CISTPL_CFTABLE_DEFAULT; | 1199 | entry->flags |= CISTPL_CFTABLE_DEFAULT; |
| 1175 | 1200 | ||
| 1176 | /* Process optional features */ | 1201 | /* Process optional features */ |
| 1177 | if (++p == q) return CS_BAD_TUPLE; | 1202 | if (++p == q) |
| 1203 | return -EINVAL; | ||
| 1178 | features = *p; p++; | 1204 | features = *p; p++; |
| 1179 | 1205 | ||
| 1180 | /* Power options */ | 1206 | /* Power options */ |
| 1181 | if ((features & 3) > 0) { | 1207 | if ((features & 3) > 0) { |
| 1182 | p = parse_power(p, q, &entry->vcc); | 1208 | p = parse_power(p, q, &entry->vcc); |
| 1183 | if (p == NULL) return CS_BAD_TUPLE; | 1209 | if (p == NULL) |
| 1210 | return -EINVAL; | ||
| 1184 | } else | 1211 | } else |
| 1185 | entry->vcc.present = 0; | 1212 | entry->vcc.present = 0; |
| 1186 | if ((features & 3) > 1) { | 1213 | if ((features & 3) > 1) { |
| 1187 | p = parse_power(p, q, &entry->vpp1); | 1214 | p = parse_power(p, q, &entry->vpp1); |
| 1188 | if (p == NULL) return CS_BAD_TUPLE; | 1215 | if (p == NULL) |
| 1216 | return -EINVAL; | ||
| 1189 | } else | 1217 | } else |
| 1190 | entry->vpp1.present = 0; | 1218 | entry->vpp1.present = 0; |
| 1191 | if ((features & 3) > 2) { | 1219 | if ((features & 3) > 2) { |
| 1192 | p = parse_power(p, q, &entry->vpp2); | 1220 | p = parse_power(p, q, &entry->vpp2); |
| 1193 | if (p == NULL) return CS_BAD_TUPLE; | 1221 | if (p == NULL) |
| 1222 | return -EINVAL; | ||
| 1194 | } else | 1223 | } else |
| 1195 | entry->vpp2.present = 0; | 1224 | entry->vpp2.present = 0; |
| 1196 | 1225 | ||
| 1197 | /* I/O window options */ | 1226 | /* I/O window options */ |
| 1198 | if (features & 0x08) { | 1227 | if (features & 0x08) { |
| 1199 | if (p == q) return CS_BAD_TUPLE; | 1228 | if (p == q) |
| 1229 | return -EINVAL; | ||
| 1200 | entry->io = *p; p++; | 1230 | entry->io = *p; p++; |
| 1201 | } else | 1231 | } else |
| 1202 | entry->io = 0; | 1232 | entry->io = 0; |
| @@ -1204,26 +1234,31 @@ static int parse_cftable_entry_cb(tuple_t *tuple, | |||
| 1204 | /* Interrupt options */ | 1234 | /* Interrupt options */ |
| 1205 | if (features & 0x10) { | 1235 | if (features & 0x10) { |
| 1206 | p = parse_irq(p, q, &entry->irq); | 1236 | p = parse_irq(p, q, &entry->irq); |
| 1207 | if (p == NULL) return CS_BAD_TUPLE; | 1237 | if (p == NULL) |
| 1238 | return -EINVAL; | ||
| 1208 | } else | 1239 | } else |
| 1209 | entry->irq.IRQInfo1 = 0; | 1240 | entry->irq.IRQInfo1 = 0; |
| 1210 | 1241 | ||
| 1211 | if (features & 0x20) { | 1242 | if (features & 0x20) { |
| 1212 | if (p == q) return CS_BAD_TUPLE; | 1243 | if (p == q) |
| 1244 | return -EINVAL; | ||
| 1213 | entry->mem = *p; p++; | 1245 | entry->mem = *p; p++; |
| 1214 | } else | 1246 | } else |
| 1215 | entry->mem = 0; | 1247 | entry->mem = 0; |
| 1216 | 1248 | ||
| 1217 | /* Misc features */ | 1249 | /* Misc features */ |
| 1218 | if (features & 0x80) { | 1250 | if (features & 0x80) { |
| 1219 | if (p == q) return CS_BAD_TUPLE; | 1251 | if (p == q) |
| 1252 | return -EINVAL; | ||
| 1220 | entry->flags |= (*p << 8); | 1253 | entry->flags |= (*p << 8); |
| 1221 | if (*p & 0x80) { | 1254 | if (*p & 0x80) { |
| 1222 | if (++p == q) return CS_BAD_TUPLE; | 1255 | if (++p == q) |
| 1256 | return -EINVAL; | ||
| 1223 | entry->flags |= (*p << 16); | 1257 | entry->flags |= (*p << 16); |
| 1224 | } | 1258 | } |
| 1225 | while (*p & 0x80) | 1259 | while (*p & 0x80) |
| 1226 | if (++p == q) return CS_BAD_TUPLE; | 1260 | if (++p == q) |
| 1261 | return -EINVAL; | ||
| 1227 | p++; | 1262 | p++; |
| 1228 | } | 1263 | } |
| 1229 | 1264 | ||
| @@ -1265,7 +1300,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2) | |||
| 1265 | u_char *p, *q; | 1300 | u_char *p, *q; |
| 1266 | 1301 | ||
| 1267 | if (tuple->TupleDataLen < 10) | 1302 | if (tuple->TupleDataLen < 10) |
| 1268 | return CS_BAD_TUPLE; | 1303 | return -EINVAL; |
| 1269 | 1304 | ||
| 1270 | p = tuple->TupleData; | 1305 | p = tuple->TupleData; |
| 1271 | q = p + tuple->TupleDataLen; | 1306 | q = p + tuple->TupleDataLen; |
| @@ -1289,13 +1324,16 @@ static int parse_org(tuple_t *tuple, cistpl_org_t *org) | |||
| 1289 | 1324 | ||
| 1290 | p = tuple->TupleData; | 1325 | p = tuple->TupleData; |
| 1291 | q = p + tuple->TupleDataLen; | 1326 | q = p + tuple->TupleDataLen; |
| 1292 | if (p == q) return CS_BAD_TUPLE; | 1327 | if (p == q) |
| 1328 | return -EINVAL; | ||
| 1293 | org->data_org = *p; | 1329 | org->data_org = *p; |
| 1294 | if (++p == q) return CS_BAD_TUPLE; | 1330 | if (++p == q) |
| 1331 | return -EINVAL; | ||
| 1295 | for (i = 0; i < 30; i++) { | 1332 | for (i = 0; i < 30; i++) { |
| 1296 | org->desc[i] = *p; | 1333 | org->desc[i] = *p; |
| 1297 | if (*p == '\0') break; | 1334 | if (*p == '\0') break; |
| 1298 | if (++p == q) return CS_BAD_TUPLE; | 1335 | if (++p == q) |
| 1336 | return -EINVAL; | ||
| 1299 | } | 1337 | } |
| 1300 | return 0; | 1338 | return 0; |
| 1301 | } | 1339 | } |
| @@ -1307,7 +1345,7 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt) | |||
| 1307 | u_char *p; | 1345 | u_char *p; |
| 1308 | 1346 | ||
| 1309 | if (tuple->TupleDataLen < 10) | 1347 | if (tuple->TupleDataLen < 10) |
| 1310 | return CS_BAD_TUPLE; | 1348 | return -EINVAL; |
| 1311 | 1349 | ||
| 1312 | p = tuple->TupleData; | 1350 | p = tuple->TupleData; |
| 1313 | 1351 | ||
| @@ -1326,7 +1364,7 @@ int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse) | |||
| 1326 | int ret = 0; | 1364 | int ret = 0; |
| 1327 | 1365 | ||
| 1328 | if (tuple->TupleDataLen > tuple->TupleDataMax) | 1366 | if (tuple->TupleDataLen > tuple->TupleDataMax) |
| 1329 | return CS_BAD_TUPLE; | 1367 | return -EINVAL; |
| 1330 | switch (tuple->TupleCode) { | 1368 | switch (tuple->TupleCode) { |
| 1331 | case CISTPL_DEVICE: | 1369 | case CISTPL_DEVICE: |
| 1332 | case CISTPL_DEVICE_A: | 1370 | case CISTPL_DEVICE_A: |
| @@ -1400,6 +1438,8 @@ int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse) | |||
| 1400 | ret = -EINVAL; | 1438 | ret = -EINVAL; |
| 1401 | break; | 1439 | break; |
| 1402 | } | 1440 | } |
| 1441 | if (ret) | ||
| 1442 | __cs_dbg(0, "parse_tuple failed %d\n", ret); | ||
| 1403 | return ret; | 1443 | return ret; |
| 1404 | } | 1444 | } |
| 1405 | EXPORT_SYMBOL(pccard_parse_tuple); | 1445 | EXPORT_SYMBOL(pccard_parse_tuple); |
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 384a76bd38eb..3fcdf4fbca0e 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h | |||
| @@ -137,9 +137,15 @@ extern int cs_debug_level(int); | |||
| 137 | dev_printk(KERN_DEBUG, &skt->dev, \ | 137 | dev_printk(KERN_DEBUG, &skt->dev, \ |
| 138 | "cs: " fmt, ## arg); \ | 138 | "cs: " fmt, ## arg); \ |
| 139 | } while (0) | 139 | } while (0) |
| 140 | #define __cs_dbg(lvl, fmt, arg...) do { \ | ||
| 141 | if (cs_debug_level(lvl)) \ | ||
| 142 | printk(KERN_DEBUG \ | ||
| 143 | "cs: " fmt, ## arg); \ | ||
| 144 | } while (0) | ||
| 140 | 145 | ||
| 141 | #else | 146 | #else |
| 142 | #define cs_dbg(skt, lvl, fmt, arg...) do { } while (0) | 147 | #define cs_dbg(skt, lvl, fmt, arg...) do { } while (0) |
| 148 | #define __cs_dbg(lvl, fmt, arg...) do { } while (0) | ||
| 143 | #endif | 149 | #endif |
| 144 | 150 | ||
| 145 | #define cs_err(skt, fmt, arg...) \ | 151 | #define cs_err(skt, fmt, arg...) \ |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 5b24938ca154..55a46af33ca4 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
| @@ -82,7 +82,6 @@ static const lookup_t error_table[] = { | |||
| 82 | { -EBUSY, "Resource in use" }, | 82 | { -EBUSY, "Resource in use" }, |
| 83 | { -ENOSPC, "No more items" }, | 83 | { -ENOSPC, "No more items" }, |
| 84 | { -ENOMEM, "Out of resource" }, | 84 | { -ENOMEM, "Out of resource" }, |
| 85 | { CS_BAD_TUPLE, "Bad CIS tuple" } | ||
| 86 | }; | 85 | }; |
| 87 | 86 | ||
| 88 | 87 | ||
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index f2352c227570..d4c3f9aa3d83 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c | |||
| @@ -970,8 +970,6 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
| 970 | case -ENOSYS: | 970 | case -ENOSYS: |
| 971 | err = ret; | 971 | err = ret; |
| 972 | break; | 972 | break; |
| 973 | case CS_BAD_TUPLE: | ||
| 974 | err = -EINVAL; break; | ||
| 975 | case -ENOMEM: | 973 | case -ENOMEM: |
| 976 | err = -ENOSPC; break; | 974 | err = -ENOSPC; break; |
| 977 | case -ENOSPC: | 975 | case -ENOSPC: |
diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h index 56f94e297500..d672fdefdf22 100644 --- a/include/pcmcia/cs.h +++ b/include/pcmcia/cs.h | |||
| @@ -319,7 +319,7 @@ typedef struct error_info_t { | |||
| 319 | #define CS_OUT_OF_RESOURCE -ENOMEM | 319 | #define CS_OUT_OF_RESOURCE -ENOMEM |
| 320 | #define CS_BAD_HANDLE -EINVAL | 320 | #define CS_BAD_HANDLE -EINVAL |
| 321 | 321 | ||
| 322 | #define CS_BAD_TUPLE 0x40 | 322 | #define CS_BAD_TUPLE -EINVAL |
| 323 | 323 | ||
| 324 | #ifdef __KERNEL__ | 324 | #ifdef __KERNEL__ |
| 325 | 325 | ||
