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 179483 2008-06-01 20:55:34Z imp $ */
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;
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 intface = reg & PCCARD_TPCE_INDX_INTFACE;
911 def = reg & PCCARD_TPCE_INDX_DEFAULT;
912 num = reg & PCCARD_TPCE_INDX_NUM_MASK;
913
914 /*
915 * this is a little messy. Some cards have only a
916 * cfentry with the default bit set. So, as we go
917 * through the list, we add new indexes to the queue,
--- 59 unchanged lines hidden (view full) ---
977 */
978 if (!def) {
979 state->temp_cfe = *state->default_cfe;
980 state->default_cfe = &state->temp_cfe;
981 }
982 }
983
984 if (intface) {
985 reg = pccard_tuple_read_1(tuple, idx++);
986 cfe->flags &= ~(PCCARD_CFE_MWAIT_REQUIRED
987 | PCCARD_CFE_RDYBSY_ACTIVE
988 | PCCARD_CFE_WP_ACTIVE
989 | PCCARD_CFE_BVD_ACTIVE);
990 if (reg & PCCARD_TPCE_IF_MWAIT)
991 cfe->flags |= PCCARD_CFE_MWAIT_REQUIRED;
992 if (reg & PCCARD_TPCE_IF_RDYBSY)
993 cfe->flags |= PCCARD_CFE_RDYBSY_ACTIVE;
994 if (reg & PCCARD_TPCE_IF_WP)
995 cfe->flags |= PCCARD_CFE_WP_ACTIVE;
996 if (reg & PCCARD_TPCE_IF_BVD)
997 cfe->flags |= PCCARD_CFE_BVD_ACTIVE;
998 cfe->iftype = reg & PCCARD_TPCE_IF_IFTYPE;
999 }
1000 reg = pccard_tuple_read_1(tuple, idx++);
1001
1002 power = reg & PCCARD_TPCE_FS_POWER_MASK;
1003 timing = reg & PCCARD_TPCE_FS_TIMING;
1004 iospace = reg & PCCARD_TPCE_FS_IOSPACE;
1005 irq = reg & PCCARD_TPCE_FS_IRQ;
1006 memspace = reg & PCCARD_TPCE_FS_MEMSPACE_MASK;
1007 misc = reg & PCCARD_TPCE_FS_MISC;
1008
1009 if (power) {
1010 /* skip over power, don't save */
1011 /* for each parameter selection byte */
1012 for (i = 0; i < power; i++) {
1013 reg = pccard_tuple_read_1(tuple, idx++);
1014 for (; reg; reg >>= 1)
1015 {
1016 /* set bit -> read */
1017 if ((reg & 1) == 0)
1018 continue;
1019 /* skip over bytes */
1020 do {
1021 reg2 = pccard_tuple_read_1(tuple, idx++);
1022 /*
1023 * until non-extension
1024 * byte
1025 */
1026 } while (reg2 & 0x80);
1027 }
1028 }
1029 }
1030 if (timing) {
1031 /* skip over timing, don't save */
1032 reg = pccard_tuple_read_1(tuple, idx++);
1033
1034 if ((reg & PCCARD_TPCE_TD_RESERVED_MASK) !=
1035 PCCARD_TPCE_TD_RESERVED_MASK)
1036 idx++;
1037 if ((reg & PCCARD_TPCE_TD_RDYBSY_MASK) !=
1038 PCCARD_TPCE_TD_RDYBSY_MASK)
1039 idx++;
1040 if ((reg & PCCARD_TPCE_TD_WAIT_MASK) !=
1041 PCCARD_TPCE_TD_WAIT_MASK)
1042 idx++;
1043 }
1044 if (iospace) {
1045 if (tuple->length <= idx) {
1046 DPRINTF(("ran out of space before TCPE_IO\n"));
1047 goto abort_cfe;
1048 }
1049
1050 reg = pccard_tuple_read_1(tuple, idx++);
1051 cfe->flags &=
1052 ~(PCCARD_CFE_IO8 | PCCARD_CFE_IO16);
1053 if (reg & PCCARD_TPCE_IO_BUSWIDTH_8BIT)
1054 cfe->flags |= PCCARD_CFE_IO8;
1055 if (reg & PCCARD_TPCE_IO_BUSWIDTH_16BIT)
1056 cfe->flags |= PCCARD_CFE_IO16;
1057 cfe->iomask =
1058 reg & PCCARD_TPCE_IO_IOADDRLINES_MASK;
1059
1060 if (reg & PCCARD_TPCE_IO_HASRANGE) {
1061 reg = pccard_tuple_read_1(tuple, idx++);
1062 cfe->num_iospace = 1 + (reg &
1063 PCCARD_TPCE_IO_RANGE_COUNT);
1064
1065 if (cfe->num_iospace >
1066 (sizeof(cfe->iospace) /
1067 sizeof(cfe->iospace[0]))) {
1068 DPRINTF(("too many io "
1069 "spaces %d",
1070 cfe->num_iospace));
1071 state->card->error++;
1072 break;
1073 }
1074 for (i = 0; i < cfe->num_iospace; i++) {
1075 switch (reg & PCCARD_TPCE_IO_RANGE_ADDRSIZE_MASK) {
1076 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_ONE:
1077 cfe->iospace[i].start =
1078 pccard_tuple_read_1(tuple, idx++);
1079 break;
1080 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_TWO:
1081 cfe->iospace[i].start =
1082 pccard_tuple_read_2(tuple, idx);
1083 idx += 2;
1084 break;
1085 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_FOUR:
1086 cfe->iospace[i].start =
1087 pccard_tuple_read_4(tuple, idx);
1088 idx += 4;
1089 break;
1090 }
1091 switch (reg &
1092 PCCARD_TPCE_IO_RANGE_LENGTHSIZE_MASK) {
1093 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_ONE:
1094 cfe->iospace[i].length =
1095 pccard_tuple_read_1(tuple, idx++);
1096 break;
1097 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_TWO:
1098 cfe->iospace[i].length =
1099 pccard_tuple_read_2(tuple, idx);
1100 idx += 2;
1101 break;
1102 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_FOUR:
1103 cfe->iospace[i].length =
--- 11 unchanged lines hidden (view full) ---
1115 }
1116 }
1117 if (irq) {
1118 if (tuple->length <= idx) {
1119 DPRINTF(("ran out of space before TCPE_IR\n"));
1120 goto abort_cfe;
1121 }
1122
1123 reg = pccard_tuple_read_1(tuple, idx++);
1124 cfe->flags &= ~(PCCARD_CFE_IRQSHARE
1125 | PCCARD_CFE_IRQPULSE
1126 | PCCARD_CFE_IRQLEVEL);
1127 if (reg & PCCARD_TPCE_IR_SHARE)
1128 cfe->flags |= PCCARD_CFE_IRQSHARE;
1129 if (reg & PCCARD_TPCE_IR_PULSE)
1130 cfe->flags |= PCCARD_CFE_IRQPULSE;
1131 if (reg & PCCARD_TPCE_IR_LEVEL)
--- 36 unchanged lines hidden (view full) ---
1168 pccard_tuple_read_2(tuple, idx);
1169 idx += 2;
1170 cfe->memspace[0].hostaddr = cfe->memspace[0].cardaddr;
1171 } else {
1172 int lengthsize;
1173 int cardaddrsize;
1174 int hostaddrsize;
1175
1176 reg = pccard_tuple_read_1(tuple, idx++);
1177 cfe->num_memspace = (reg &
1178 PCCARD_TPCE_MS_COUNT) + 1;
1179 if (cfe->num_memspace >
1180 (sizeof(cfe->memspace) /
1181 sizeof(cfe->memspace[0]))) {
1182 DPRINTF(("too many mem "
1183 "spaces %d",
1184 cfe->num_memspace));
1185 state->card->error++;
1186 break;
--- 47 unchanged lines hidden (view full) ---
1234 } else
1235 cfe->num_memspace = 0;
1236 if (misc) {
1237 if (tuple->length <= idx) {
1238 DPRINTF(("ran out of space before TCPE_MI\n"));
1239 goto abort_cfe;
1240 }
1241
1242 reg = pccard_tuple_read_1(tuple, idx++);
1243 cfe->flags &= ~(PCCARD_CFE_POWERDOWN
1244 | PCCARD_CFE_READONLY
1245 | PCCARD_CFE_AUDIO);
1246 if (reg & PCCARD_TPCE_MI_PWRDOWN)
1247 cfe->flags |= PCCARD_CFE_POWERDOWN;
1248 if (reg & PCCARD_TPCE_MI_READONLY)
1249 cfe->flags |= PCCARD_CFE_READONLY;
1250 if (reg & PCCARD_TPCE_MI_AUDIO)
1251 cfe->flags |= PCCARD_CFE_AUDIO;
1252 cfe->maxtwins = reg & PCCARD_TPCE_MI_MAXTWINS;
1253
1254 while (reg & PCCARD_TPCE_MI_EXT) {
1255 reg = pccard_tuple_read_1(tuple, idx++);
1256 }
1257 }
1258 /* skip all the subtuples */
1259 }
1260
1261 abort_cfe:
1262 DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
1263 break;
--- 41 unchanged lines hidden ---
2/* $FreeBSD: head/sys/dev/pccard/pccard_cis.c 179483 2008-06-01 20:55:34Z imp $ */
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;
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 intface = reg & PCCARD_TPCE_INDX_INTFACE;
911 def = reg & PCCARD_TPCE_INDX_DEFAULT;
912 num = reg & PCCARD_TPCE_INDX_NUM_MASK;
913
914 /*
915 * this is a little messy. Some cards have only a
916 * cfentry with the default bit set. So, as we go
917 * through the list, we add new indexes to the queue,
--- 59 unchanged lines hidden (view full) ---
977 */
978 if (!def) {
979 state->temp_cfe = *state->default_cfe;
980 state->default_cfe = &state->temp_cfe;
981 }
982 }
983
984 if (intface) {
985 reg = pccard_tuple_read_1(tuple, idx++);
986 cfe->flags &= ~(PCCARD_CFE_MWAIT_REQUIRED
987 | PCCARD_CFE_RDYBSY_ACTIVE
988 | PCCARD_CFE_WP_ACTIVE
989 | PCCARD_CFE_BVD_ACTIVE);
990 if (reg & PCCARD_TPCE_IF_MWAIT)
991 cfe->flags |= PCCARD_CFE_MWAIT_REQUIRED;
992 if (reg & PCCARD_TPCE_IF_RDYBSY)
993 cfe->flags |= PCCARD_CFE_RDYBSY_ACTIVE;
994 if (reg & PCCARD_TPCE_IF_WP)
995 cfe->flags |= PCCARD_CFE_WP_ACTIVE;
996 if (reg & PCCARD_TPCE_IF_BVD)
997 cfe->flags |= PCCARD_CFE_BVD_ACTIVE;
998 cfe->iftype = reg & PCCARD_TPCE_IF_IFTYPE;
999 }
1000 reg = pccard_tuple_read_1(tuple, idx++);
1001
1002 power = reg & PCCARD_TPCE_FS_POWER_MASK;
1003 timing = reg & PCCARD_TPCE_FS_TIMING;
1004 iospace = reg & PCCARD_TPCE_FS_IOSPACE;
1005 irq = reg & PCCARD_TPCE_FS_IRQ;
1006 memspace = reg & PCCARD_TPCE_FS_MEMSPACE_MASK;
1007 misc = reg & PCCARD_TPCE_FS_MISC;
1008
1009 if (power) {
1010 /* skip over power, don't save */
1011 /* for each parameter selection byte */
1012 for (i = 0; i < power; i++) {
1013 reg = pccard_tuple_read_1(tuple, idx++);
1014 for (; reg; reg >>= 1)
1015 {
1016 /* set bit -> read */
1017 if ((reg & 1) == 0)
1018 continue;
1019 /* skip over bytes */
1020 do {
1021 reg2 = pccard_tuple_read_1(tuple, idx++);
1022 /*
1023 * until non-extension
1024 * byte
1025 */
1026 } while (reg2 & 0x80);
1027 }
1028 }
1029 }
1030 if (timing) {
1031 /* skip over timing, don't save */
1032 reg = pccard_tuple_read_1(tuple, idx++);
1033
1034 if ((reg & PCCARD_TPCE_TD_RESERVED_MASK) !=
1035 PCCARD_TPCE_TD_RESERVED_MASK)
1036 idx++;
1037 if ((reg & PCCARD_TPCE_TD_RDYBSY_MASK) !=
1038 PCCARD_TPCE_TD_RDYBSY_MASK)
1039 idx++;
1040 if ((reg & PCCARD_TPCE_TD_WAIT_MASK) !=
1041 PCCARD_TPCE_TD_WAIT_MASK)
1042 idx++;
1043 }
1044 if (iospace) {
1045 if (tuple->length <= idx) {
1046 DPRINTF(("ran out of space before TCPE_IO\n"));
1047 goto abort_cfe;
1048 }
1049
1050 reg = pccard_tuple_read_1(tuple, idx++);
1051 cfe->flags &=
1052 ~(PCCARD_CFE_IO8 | PCCARD_CFE_IO16);
1053 if (reg & PCCARD_TPCE_IO_BUSWIDTH_8BIT)
1054 cfe->flags |= PCCARD_CFE_IO8;
1055 if (reg & PCCARD_TPCE_IO_BUSWIDTH_16BIT)
1056 cfe->flags |= PCCARD_CFE_IO16;
1057 cfe->iomask =
1058 reg & PCCARD_TPCE_IO_IOADDRLINES_MASK;
1059
1060 if (reg & PCCARD_TPCE_IO_HASRANGE) {
1061 reg = pccard_tuple_read_1(tuple, idx++);
1062 cfe->num_iospace = 1 + (reg &
1063 PCCARD_TPCE_IO_RANGE_COUNT);
1064
1065 if (cfe->num_iospace >
1066 (sizeof(cfe->iospace) /
1067 sizeof(cfe->iospace[0]))) {
1068 DPRINTF(("too many io "
1069 "spaces %d",
1070 cfe->num_iospace));
1071 state->card->error++;
1072 break;
1073 }
1074 for (i = 0; i < cfe->num_iospace; i++) {
1075 switch (reg & PCCARD_TPCE_IO_RANGE_ADDRSIZE_MASK) {
1076 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_ONE:
1077 cfe->iospace[i].start =
1078 pccard_tuple_read_1(tuple, idx++);
1079 break;
1080 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_TWO:
1081 cfe->iospace[i].start =
1082 pccard_tuple_read_2(tuple, idx);
1083 idx += 2;
1084 break;
1085 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_FOUR:
1086 cfe->iospace[i].start =
1087 pccard_tuple_read_4(tuple, idx);
1088 idx += 4;
1089 break;
1090 }
1091 switch (reg &
1092 PCCARD_TPCE_IO_RANGE_LENGTHSIZE_MASK) {
1093 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_ONE:
1094 cfe->iospace[i].length =
1095 pccard_tuple_read_1(tuple, idx++);
1096 break;
1097 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_TWO:
1098 cfe->iospace[i].length =
1099 pccard_tuple_read_2(tuple, idx);
1100 idx += 2;
1101 break;
1102 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_FOUR:
1103 cfe->iospace[i].length =
--- 11 unchanged lines hidden (view full) ---
1115 }
1116 }
1117 if (irq) {
1118 if (tuple->length <= idx) {
1119 DPRINTF(("ran out of space before TCPE_IR\n"));
1120 goto abort_cfe;
1121 }
1122
1123 reg = pccard_tuple_read_1(tuple, idx++);
1124 cfe->flags &= ~(PCCARD_CFE_IRQSHARE
1125 | PCCARD_CFE_IRQPULSE
1126 | PCCARD_CFE_IRQLEVEL);
1127 if (reg & PCCARD_TPCE_IR_SHARE)
1128 cfe->flags |= PCCARD_CFE_IRQSHARE;
1129 if (reg & PCCARD_TPCE_IR_PULSE)
1130 cfe->flags |= PCCARD_CFE_IRQPULSE;
1131 if (reg & PCCARD_TPCE_IR_LEVEL)
--- 36 unchanged lines hidden (view full) ---
1168 pccard_tuple_read_2(tuple, idx);
1169 idx += 2;
1170 cfe->memspace[0].hostaddr = cfe->memspace[0].cardaddr;
1171 } else {
1172 int lengthsize;
1173 int cardaddrsize;
1174 int hostaddrsize;
1175
1176 reg = pccard_tuple_read_1(tuple, idx++);
1177 cfe->num_memspace = (reg &
1178 PCCARD_TPCE_MS_COUNT) + 1;
1179 if (cfe->num_memspace >
1180 (sizeof(cfe->memspace) /
1181 sizeof(cfe->memspace[0]))) {
1182 DPRINTF(("too many mem "
1183 "spaces %d",
1184 cfe->num_memspace));
1185 state->card->error++;
1186 break;
--- 47 unchanged lines hidden (view full) ---
1234 } else
1235 cfe->num_memspace = 0;
1236 if (misc) {
1237 if (tuple->length <= idx) {
1238 DPRINTF(("ran out of space before TCPE_MI\n"));
1239 goto abort_cfe;
1240 }
1241
1242 reg = pccard_tuple_read_1(tuple, idx++);
1243 cfe->flags &= ~(PCCARD_CFE_POWERDOWN
1244 | PCCARD_CFE_READONLY
1245 | PCCARD_CFE_AUDIO);
1246 if (reg & PCCARD_TPCE_MI_PWRDOWN)
1247 cfe->flags |= PCCARD_CFE_POWERDOWN;
1248 if (reg & PCCARD_TPCE_MI_READONLY)
1249 cfe->flags |= PCCARD_CFE_READONLY;
1250 if (reg & PCCARD_TPCE_MI_AUDIO)
1251 cfe->flags |= PCCARD_CFE_AUDIO;
1252 cfe->maxtwins = reg & PCCARD_TPCE_MI_MAXTWINS;
1253
1254 while (reg & PCCARD_TPCE_MI_EXT) {
1255 reg = pccard_tuple_read_1(tuple, idx++);
1256 }
1257 }
1258 /* skip all the subtuples */
1259 }
1260
1261 abort_cfe:
1262 DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
1263 break;
--- 41 unchanged lines hidden ---