1/* $NetBSD: pcmcia_cis.c,v 1.17 2000/02/10 09:01:52 chopps Exp $ */
2/* $FreeBSD: head/sys/dev/pccard/pccard_cis.c 167086 2007-02-27 17:23:29Z jhb $ */
3
4/*-
5 * Copyright (c) 1997 Marc Horowitz. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
--- 882 unchanged lines hidden (view full) ---
893 /* reset the default cfe for each cfe list */
894 state->temp_cfe = init_cfe;
895 state->default_cfe = &state->temp_cfe;
896 }
897 DPRINTF(("CISTPL_CONFIG\n"));
898 break;
899 case CISTPL_CFTABLE_ENTRY:
900 {
901 int idx, i, j;
902 u_int reg, reg2;
903 u_int intface, def, num;
904 u_int power, timing, iospace, irq, memspace, misc;
905 struct pccard_config_entry *cfe;
906
907 idx = 0;
908
909 reg = pccard_tuple_read_1(tuple, idx);
910 idx++;
911 intface = reg & PCCARD_TPCE_INDX_INTFACE;
912 def = reg & PCCARD_TPCE_INDX_DEFAULT;
913 num = reg & PCCARD_TPCE_INDX_NUM_MASK;
914
915 /*
916 * this is a little messy. Some cards have only a
917 * cfentry with the default bit set. So, as we go
918 * through the list, we add new indexes to the queue,
--- 59 unchanged lines hidden (view full) ---
978 */
979 if (!def) {
980 state->temp_cfe = *state->default_cfe;
981 state->default_cfe = &state->temp_cfe;
982 }
983 }
984
985 if (intface) {
986 reg = pccard_tuple_read_1(tuple, idx);
987 idx++;
988 cfe->flags &= ~(PCCARD_CFE_MWAIT_REQUIRED
989 | PCCARD_CFE_RDYBSY_ACTIVE
990 | PCCARD_CFE_WP_ACTIVE
991 | PCCARD_CFE_BVD_ACTIVE);
992 if (reg & PCCARD_TPCE_IF_MWAIT)
993 cfe->flags |= PCCARD_CFE_MWAIT_REQUIRED;
994 if (reg & PCCARD_TPCE_IF_RDYBSY)
995 cfe->flags |= PCCARD_CFE_RDYBSY_ACTIVE;
996 if (reg & PCCARD_TPCE_IF_WP)
997 cfe->flags |= PCCARD_CFE_WP_ACTIVE;
998 if (reg & PCCARD_TPCE_IF_BVD)
999 cfe->flags |= PCCARD_CFE_BVD_ACTIVE;
1000 cfe->iftype = reg & PCCARD_TPCE_IF_IFTYPE;
1001 }
1002 reg = pccard_tuple_read_1(tuple, idx);
1003 idx++;
1004
1005 power = reg & PCCARD_TPCE_FS_POWER_MASK;
1006 timing = reg & PCCARD_TPCE_FS_TIMING;
1007 iospace = reg & PCCARD_TPCE_FS_IOSPACE;
1008 irq = reg & PCCARD_TPCE_FS_IRQ;
1009 memspace = reg & PCCARD_TPCE_FS_MEMSPACE_MASK;
1010 misc = reg & PCCARD_TPCE_FS_MISC;
1011
1012 if (power) {
1013 /* skip over power, don't save */
1014 /* for each parameter selection byte */
1015 for (i = 0; i < power; i++) {
1016 reg = pccard_tuple_read_1(tuple, idx);
1017 idx++;
1018 /* for each bit */
1019 for (j = 0; j < 7; j++) {
1020 /* if the bit is set */
1021 if ((reg >> j) & 0x01) {
1022 /* skip over bytes */
1023 do {
1024 reg2 = pccard_tuple_read_1(tuple, idx);
1025 idx++;
1026 /*
1027 * until
1028 * non-extensi
1029 * on byte
1030 */
1031 } while (reg2 & 0x80);
1032 }
1033 }
1034 }
1035 }
1036 if (timing) {
1037 /* skip over timing, don't save */
1038 reg = pccard_tuple_read_1(tuple, idx);
1039 idx++;
1040
1041 if ((reg & PCCARD_TPCE_TD_RESERVED_MASK) !=
1042 PCCARD_TPCE_TD_RESERVED_MASK)
1043 idx++;
1044 if ((reg & PCCARD_TPCE_TD_RDYBSY_MASK) !=
1045 PCCARD_TPCE_TD_RDYBSY_MASK)
1046 idx++;
1047 if ((reg & PCCARD_TPCE_TD_WAIT_MASK) !=
1048 PCCARD_TPCE_TD_WAIT_MASK)
1049 idx++;
1050 }
1051 if (iospace) {
1052 if (tuple->length <= idx) {
1053 DPRINTF(("ran out of space before TCPE_IO\n"));
1054 goto abort_cfe;
1055 }
1056
1057 reg = pccard_tuple_read_1(tuple, idx);
1058 idx++;
1059 cfe->flags &=
1060 ~(PCCARD_CFE_IO8 | PCCARD_CFE_IO16);
1061 if (reg & PCCARD_TPCE_IO_BUSWIDTH_8BIT)
1062 cfe->flags |= PCCARD_CFE_IO8;
1063 if (reg & PCCARD_TPCE_IO_BUSWIDTH_16BIT)
1064 cfe->flags |= PCCARD_CFE_IO16;
1065 cfe->iomask =
1066 reg & PCCARD_TPCE_IO_IOADDRLINES_MASK;
1067
1068 if (reg & PCCARD_TPCE_IO_HASRANGE) {
1069 reg = pccard_tuple_read_1(tuple, idx);
1070 idx++;
1071
1072 cfe->num_iospace = 1 + (reg &
1073 PCCARD_TPCE_IO_RANGE_COUNT);
1074
1075 if (cfe->num_iospace >
1076 (sizeof(cfe->iospace) /
1077 sizeof(cfe->iospace[0]))) {
1078 DPRINTF(("too many io "
1079 "spaces %d",
1080 cfe->num_iospace));
1081 state->card->error++;
1082 break;
1083 }
1084 for (i = 0; i < cfe->num_iospace; i++) {
1085 switch (reg & PCCARD_TPCE_IO_RANGE_ADDRSIZE_MASK) {
1086 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_ONE:
1087 cfe->iospace[i].start =
1088 pccard_tuple_read_1(tuple, idx);
1089 idx++;
1090 break;
1091 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_TWO:
1092 cfe->iospace[i].start =
1093 pccard_tuple_read_2(tuple, idx);
1094 idx += 2;
1095 break;
1096 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_FOUR:
1097 cfe->iospace[i].start =
1098 pccard_tuple_read_4(tuple, idx);
1099 idx += 4;
1100 break;
1101 }
1102 switch (reg &
1103 PCCARD_TPCE_IO_RANGE_LENGTHSIZE_MASK) {
1104 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_ONE:
1105 cfe->iospace[i].length =
1106 pccard_tuple_read_1(tuple, idx);
1107 idx++;
1108 break;
1109 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_TWO:
1110 cfe->iospace[i].length =
1111 pccard_tuple_read_2(tuple, idx);
1112 idx += 2;
1113 break;
1114 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_FOUR:
1115 cfe->iospace[i].length =
--- 11 unchanged lines hidden (view full) ---
1127 }
1128 }
1129 if (irq) {
1130 if (tuple->length <= idx) {
1131 DPRINTF(("ran out of space before TCPE_IR\n"));
1132 goto abort_cfe;
1133 }
1134
1135 reg = pccard_tuple_read_1(tuple, idx);
1136 idx++;
1137 cfe->flags &= ~(PCCARD_CFE_IRQSHARE
1138 | PCCARD_CFE_IRQPULSE
1139 | PCCARD_CFE_IRQLEVEL);
1140 if (reg & PCCARD_TPCE_IR_SHARE)
1141 cfe->flags |= PCCARD_CFE_IRQSHARE;
1142 if (reg & PCCARD_TPCE_IR_PULSE)
1143 cfe->flags |= PCCARD_CFE_IRQPULSE;
1144 if (reg & PCCARD_TPCE_IR_LEVEL)
--- 36 unchanged lines hidden (view full) ---
1181 pccard_tuple_read_2(tuple, idx);
1182 idx += 2;
1183 cfe->memspace[0].hostaddr = cfe->memspace[0].cardaddr;
1184 } else {
1185 int lengthsize;
1186 int cardaddrsize;
1187 int hostaddrsize;
1188
1189 reg = pccard_tuple_read_1(tuple, idx);
1190 idx++;
1191
1192 cfe->num_memspace = (reg &
1193 PCCARD_TPCE_MS_COUNT) + 1;
1194
1195 if (cfe->num_memspace >
1196 (sizeof(cfe->memspace) /
1197 sizeof(cfe->memspace[0]))) {
1198 DPRINTF(("too many mem "
1199 "spaces %d",
1200 cfe->num_memspace));
1201 state->card->error++;
1202 break;
--- 47 unchanged lines hidden (view full) ---
1250 } else
1251 cfe->num_memspace = 0;
1252 if (misc) {
1253 if (tuple->length <= idx) {
1254 DPRINTF(("ran out of space before TCPE_MI\n"));
1255 goto abort_cfe;
1256 }
1257
1258 reg = pccard_tuple_read_1(tuple, idx);
1259 idx++;
1260 cfe->flags &= ~(PCCARD_CFE_POWERDOWN
1261 | PCCARD_CFE_READONLY
1262 | PCCARD_CFE_AUDIO);
1263 if (reg & PCCARD_TPCE_MI_PWRDOWN)
1264 cfe->flags |= PCCARD_CFE_POWERDOWN;
1265 if (reg & PCCARD_TPCE_MI_READONLY)
1266 cfe->flags |= PCCARD_CFE_READONLY;
1267 if (reg & PCCARD_TPCE_MI_AUDIO)
1268 cfe->flags |= PCCARD_CFE_AUDIO;
1269 cfe->maxtwins = reg & PCCARD_TPCE_MI_MAXTWINS;
1270
1271 while (reg & PCCARD_TPCE_MI_EXT) {
1272 reg = pccard_tuple_read_1(tuple, idx);
1273 idx++;
1274 }
1275 }
1276 /* skip all the subtuples */
1277 }
1278
1279 abort_cfe:
1280 DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
1281 break;
--- 41 unchanged lines hidden ---
2/* $FreeBSD: head/sys/dev/pccard/pccard_cis.c 167086 2007-02-27 17:23:29Z jhb $ */
3
4/*-
5 * Copyright (c) 1997 Marc Horowitz. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
--- 882 unchanged lines hidden (view full) ---
893 /* reset the default cfe for each cfe list */
894 state->temp_cfe = init_cfe;
895 state->default_cfe = &state->temp_cfe;
896 }
897 DPRINTF(("CISTPL_CONFIG\n"));
898 break;
899 case CISTPL_CFTABLE_ENTRY:
900 {
901 int idx, i, j;
902 u_int reg, reg2;
903 u_int intface, def, num;
904 u_int power, timing, iospace, irq, memspace, misc;
905 struct pccard_config_entry *cfe;
906
907 idx = 0;
908
909 reg = pccard_tuple_read_1(tuple, idx);
910 idx++;
911 intface = reg & PCCARD_TPCE_INDX_INTFACE;
912 def = reg & PCCARD_TPCE_INDX_DEFAULT;
913 num = reg & PCCARD_TPCE_INDX_NUM_MASK;
914
915 /*
916 * this is a little messy. Some cards have only a
917 * cfentry with the default bit set. So, as we go
918 * through the list, we add new indexes to the queue,
--- 59 unchanged lines hidden (view full) ---
978 */
979 if (!def) {
980 state->temp_cfe = *state->default_cfe;
981 state->default_cfe = &state->temp_cfe;
982 }
983 }
984
985 if (intface) {
986 reg = pccard_tuple_read_1(tuple, idx);
987 idx++;
988 cfe->flags &= ~(PCCARD_CFE_MWAIT_REQUIRED
989 | PCCARD_CFE_RDYBSY_ACTIVE
990 | PCCARD_CFE_WP_ACTIVE
991 | PCCARD_CFE_BVD_ACTIVE);
992 if (reg & PCCARD_TPCE_IF_MWAIT)
993 cfe->flags |= PCCARD_CFE_MWAIT_REQUIRED;
994 if (reg & PCCARD_TPCE_IF_RDYBSY)
995 cfe->flags |= PCCARD_CFE_RDYBSY_ACTIVE;
996 if (reg & PCCARD_TPCE_IF_WP)
997 cfe->flags |= PCCARD_CFE_WP_ACTIVE;
998 if (reg & PCCARD_TPCE_IF_BVD)
999 cfe->flags |= PCCARD_CFE_BVD_ACTIVE;
1000 cfe->iftype = reg & PCCARD_TPCE_IF_IFTYPE;
1001 }
1002 reg = pccard_tuple_read_1(tuple, idx);
1003 idx++;
1004
1005 power = reg & PCCARD_TPCE_FS_POWER_MASK;
1006 timing = reg & PCCARD_TPCE_FS_TIMING;
1007 iospace = reg & PCCARD_TPCE_FS_IOSPACE;
1008 irq = reg & PCCARD_TPCE_FS_IRQ;
1009 memspace = reg & PCCARD_TPCE_FS_MEMSPACE_MASK;
1010 misc = reg & PCCARD_TPCE_FS_MISC;
1011
1012 if (power) {
1013 /* skip over power, don't save */
1014 /* for each parameter selection byte */
1015 for (i = 0; i < power; i++) {
1016 reg = pccard_tuple_read_1(tuple, idx);
1017 idx++;
1018 /* for each bit */
1019 for (j = 0; j < 7; j++) {
1020 /* if the bit is set */
1021 if ((reg >> j) & 0x01) {
1022 /* skip over bytes */
1023 do {
1024 reg2 = pccard_tuple_read_1(tuple, idx);
1025 idx++;
1026 /*
1027 * until
1028 * non-extensi
1029 * on byte
1030 */
1031 } while (reg2 & 0x80);
1032 }
1033 }
1034 }
1035 }
1036 if (timing) {
1037 /* skip over timing, don't save */
1038 reg = pccard_tuple_read_1(tuple, idx);
1039 idx++;
1040
1041 if ((reg & PCCARD_TPCE_TD_RESERVED_MASK) !=
1042 PCCARD_TPCE_TD_RESERVED_MASK)
1043 idx++;
1044 if ((reg & PCCARD_TPCE_TD_RDYBSY_MASK) !=
1045 PCCARD_TPCE_TD_RDYBSY_MASK)
1046 idx++;
1047 if ((reg & PCCARD_TPCE_TD_WAIT_MASK) !=
1048 PCCARD_TPCE_TD_WAIT_MASK)
1049 idx++;
1050 }
1051 if (iospace) {
1052 if (tuple->length <= idx) {
1053 DPRINTF(("ran out of space before TCPE_IO\n"));
1054 goto abort_cfe;
1055 }
1056
1057 reg = pccard_tuple_read_1(tuple, idx);
1058 idx++;
1059 cfe->flags &=
1060 ~(PCCARD_CFE_IO8 | PCCARD_CFE_IO16);
1061 if (reg & PCCARD_TPCE_IO_BUSWIDTH_8BIT)
1062 cfe->flags |= PCCARD_CFE_IO8;
1063 if (reg & PCCARD_TPCE_IO_BUSWIDTH_16BIT)
1064 cfe->flags |= PCCARD_CFE_IO16;
1065 cfe->iomask =
1066 reg & PCCARD_TPCE_IO_IOADDRLINES_MASK;
1067
1068 if (reg & PCCARD_TPCE_IO_HASRANGE) {
1069 reg = pccard_tuple_read_1(tuple, idx);
1070 idx++;
1071
1072 cfe->num_iospace = 1 + (reg &
1073 PCCARD_TPCE_IO_RANGE_COUNT);
1074
1075 if (cfe->num_iospace >
1076 (sizeof(cfe->iospace) /
1077 sizeof(cfe->iospace[0]))) {
1078 DPRINTF(("too many io "
1079 "spaces %d",
1080 cfe->num_iospace));
1081 state->card->error++;
1082 break;
1083 }
1084 for (i = 0; i < cfe->num_iospace; i++) {
1085 switch (reg & PCCARD_TPCE_IO_RANGE_ADDRSIZE_MASK) {
1086 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_ONE:
1087 cfe->iospace[i].start =
1088 pccard_tuple_read_1(tuple, idx);
1089 idx++;
1090 break;
1091 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_TWO:
1092 cfe->iospace[i].start =
1093 pccard_tuple_read_2(tuple, idx);
1094 idx += 2;
1095 break;
1096 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_FOUR:
1097 cfe->iospace[i].start =
1098 pccard_tuple_read_4(tuple, idx);
1099 idx += 4;
1100 break;
1101 }
1102 switch (reg &
1103 PCCARD_TPCE_IO_RANGE_LENGTHSIZE_MASK) {
1104 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_ONE:
1105 cfe->iospace[i].length =
1106 pccard_tuple_read_1(tuple, idx);
1107 idx++;
1108 break;
1109 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_TWO:
1110 cfe->iospace[i].length =
1111 pccard_tuple_read_2(tuple, idx);
1112 idx += 2;
1113 break;
1114 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_FOUR:
1115 cfe->iospace[i].length =
--- 11 unchanged lines hidden (view full) ---
1127 }
1128 }
1129 if (irq) {
1130 if (tuple->length <= idx) {
1131 DPRINTF(("ran out of space before TCPE_IR\n"));
1132 goto abort_cfe;
1133 }
1134
1135 reg = pccard_tuple_read_1(tuple, idx);
1136 idx++;
1137 cfe->flags &= ~(PCCARD_CFE_IRQSHARE
1138 | PCCARD_CFE_IRQPULSE
1139 | PCCARD_CFE_IRQLEVEL);
1140 if (reg & PCCARD_TPCE_IR_SHARE)
1141 cfe->flags |= PCCARD_CFE_IRQSHARE;
1142 if (reg & PCCARD_TPCE_IR_PULSE)
1143 cfe->flags |= PCCARD_CFE_IRQPULSE;
1144 if (reg & PCCARD_TPCE_IR_LEVEL)
--- 36 unchanged lines hidden (view full) ---
1181 pccard_tuple_read_2(tuple, idx);
1182 idx += 2;
1183 cfe->memspace[0].hostaddr = cfe->memspace[0].cardaddr;
1184 } else {
1185 int lengthsize;
1186 int cardaddrsize;
1187 int hostaddrsize;
1188
1189 reg = pccard_tuple_read_1(tuple, idx);
1190 idx++;
1191
1192 cfe->num_memspace = (reg &
1193 PCCARD_TPCE_MS_COUNT) + 1;
1194
1195 if (cfe->num_memspace >
1196 (sizeof(cfe->memspace) /
1197 sizeof(cfe->memspace[0]))) {
1198 DPRINTF(("too many mem "
1199 "spaces %d",
1200 cfe->num_memspace));
1201 state->card->error++;
1202 break;
--- 47 unchanged lines hidden (view full) ---
1250 } else
1251 cfe->num_memspace = 0;
1252 if (misc) {
1253 if (tuple->length <= idx) {
1254 DPRINTF(("ran out of space before TCPE_MI\n"));
1255 goto abort_cfe;
1256 }
1257
1258 reg = pccard_tuple_read_1(tuple, idx);
1259 idx++;
1260 cfe->flags &= ~(PCCARD_CFE_POWERDOWN
1261 | PCCARD_CFE_READONLY
1262 | PCCARD_CFE_AUDIO);
1263 if (reg & PCCARD_TPCE_MI_PWRDOWN)
1264 cfe->flags |= PCCARD_CFE_POWERDOWN;
1265 if (reg & PCCARD_TPCE_MI_READONLY)
1266 cfe->flags |= PCCARD_CFE_READONLY;
1267 if (reg & PCCARD_TPCE_MI_AUDIO)
1268 cfe->flags |= PCCARD_CFE_AUDIO;
1269 cfe->maxtwins = reg & PCCARD_TPCE_MI_MAXTWINS;
1270
1271 while (reg & PCCARD_TPCE_MI_EXT) {
1272 reg = pccard_tuple_read_1(tuple, idx);
1273 idx++;
1274 }
1275 }
1276 /* skip all the subtuples */
1277 }
1278
1279 abort_cfe:
1280 DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
1281 break;
--- 41 unchanged lines hidden ---