Deleted Added
full compact
pccard_cis.c (86272) pccard_cis.c (87352)
1/* $NetBSD: pcmcia_cis.c,v 1.10 1998/12/29 09:03:15 marc Exp $ */
1/* $NetBSD: pcmcia_cis.c,v 1.10 1998/12/29 09:03:15 marc Exp $ */
2/* $FreeBSD: head/sys/dev/pccard/pccard_cis.c 86272 2001-11-11 20:15:47Z imp $ */
2/* $FreeBSD: head/sys/dev/pccard/pccard_cis.c 87352 2001-12-04 13:48:16Z 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
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Marc Horowitz.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/malloc.h>
36#include <sys/module.h>
37#include <sys/kernel.h>
38#include <sys/queue.h>
39#include <sys/types.h>
40
41#include <sys/bus.h>
42#include <machine/bus.h>
43#include <sys/rman.h>
44#include <machine/resource.h>
45
46#include <dev/pccard/pccardreg.h>
47#include <dev/pccard/pccardvar.h>
48
49#include "card_if.h"
50
51#define PCCARDCISDEBUG
52#ifdef PCCARDCISDEBUG
53int pccardcis_debug = 1;
54#define DPRINTF(arg) if (pccardcis_debug) printf arg
55#define DEVPRINTF(arg) if (pccardcis_debug) device_printf arg
56#else
57#define DPRINTF(arg)
58#define DEVPRINTF(arg)
59#endif
60
61#define PCCARD_CIS_SIZE 1024
62
63struct cis_state {
64 int count;
65 int gotmfc;
66 struct pccard_config_entry temp_cfe;
67 struct pccard_config_entry *default_cfe;
68 struct pccard_card *card;
69 struct pccard_function *pf;
70};
71
72int pccard_parse_cis_tuple(struct pccard_tuple *, void *);
73static int decode_funce(struct pccard_tuple *, struct pccard_function *);
74
75void
76pccard_read_cis(struct pccard_softc *sc)
77{
78 struct cis_state state;
79
80 state.count = 0;
81 state.gotmfc = 0;
82
83 state.card = &sc->card;
84
85 state.card->error = 0;
86 state.card->cis1_major = -1;
87 state.card->cis1_minor = -1;
88 state.card->cis1_info[0] = NULL;
89 state.card->cis1_info[1] = NULL;
90 state.card->cis1_info[2] = NULL;
91 state.card->cis1_info[3] = NULL;
92 state.card->manufacturer = PCMCIA_VENDOR_INVALID;
93 state.card->product = PCMCIA_PRODUCT_INVALID;
94 STAILQ_INIT(&state.card->pf_head);
95
96 state.pf = NULL;
97
98 if (pccard_scan_cis(sc->dev, pccard_parse_cis_tuple,
99 &state) == -1)
100 state.card->error++;
101}
102
103int
104pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *),
105 void *arg)
106{
107 struct resource *res;
108 int rid;
109 struct pccard_tuple tuple;
110 int longlink_present;
111 int longlink_common;
112 u_long longlink_addr;
113 int mfc_count;
114 int mfc_index;
115 struct {
116 int common;
117 u_long addr;
118 } mfc[256 / 5];
119 int ret;
120
121 ret = 0;
122
123 /* allocate some memory */
124
125 rid = 0;
126 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0,
127 PCCARD_CIS_SIZE, RF_ACTIVE);
128 if (res == NULL) {
129 device_printf(dev, "can't alloc memory to read attributes\n");
130 return -1;
131 }
132 CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY,
133 rid, PCCARD_A_MEM_ATTR);
134 tuple.memt = rman_get_bustag(res);
135 tuple.memh = rman_get_bushandle(res);
136 tuple.ptr = 0;
137
138 DPRINTF(("cis mem map %x\n", (unsigned int) tuple.memh));
139
140 tuple.mult = 2;
141
142 longlink_present = 1;
143 longlink_common = 1;
144 longlink_addr = 0;
145
146 mfc_count = 0;
147 mfc_index = 0;
148
149 DEVPRINTF((dev, "CIS tuple chain:\n"));
150
151 while (1) {
152 while (1) {
153 /* get the tuple code */
154
155 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
156
157 /* two special-case tuples */
158
159 if (tuple.code == PCCARD_CISTPL_NULL) {
160 DPRINTF(("CISTPL_NONE\n 00\n"));
161 tuple.ptr++;
162 continue;
163 } else if (tuple.code == PCCARD_CISTPL_END) {
164 DPRINTF(("CISTPL_END\n ff\n"));
165 /* Call the function for the END tuple, since
166 the CIS semantics depend on it */
167 if ((*fct) (&tuple, arg)) {
168 ret = 1;
169 goto done;
170 }
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
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Marc Horowitz.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/malloc.h>
36#include <sys/module.h>
37#include <sys/kernel.h>
38#include <sys/queue.h>
39#include <sys/types.h>
40
41#include <sys/bus.h>
42#include <machine/bus.h>
43#include <sys/rman.h>
44#include <machine/resource.h>
45
46#include <dev/pccard/pccardreg.h>
47#include <dev/pccard/pccardvar.h>
48
49#include "card_if.h"
50
51#define PCCARDCISDEBUG
52#ifdef PCCARDCISDEBUG
53int pccardcis_debug = 1;
54#define DPRINTF(arg) if (pccardcis_debug) printf arg
55#define DEVPRINTF(arg) if (pccardcis_debug) device_printf arg
56#else
57#define DPRINTF(arg)
58#define DEVPRINTF(arg)
59#endif
60
61#define PCCARD_CIS_SIZE 1024
62
63struct cis_state {
64 int count;
65 int gotmfc;
66 struct pccard_config_entry temp_cfe;
67 struct pccard_config_entry *default_cfe;
68 struct pccard_card *card;
69 struct pccard_function *pf;
70};
71
72int pccard_parse_cis_tuple(struct pccard_tuple *, void *);
73static int decode_funce(struct pccard_tuple *, struct pccard_function *);
74
75void
76pccard_read_cis(struct pccard_softc *sc)
77{
78 struct cis_state state;
79
80 state.count = 0;
81 state.gotmfc = 0;
82
83 state.card = &sc->card;
84
85 state.card->error = 0;
86 state.card->cis1_major = -1;
87 state.card->cis1_minor = -1;
88 state.card->cis1_info[0] = NULL;
89 state.card->cis1_info[1] = NULL;
90 state.card->cis1_info[2] = NULL;
91 state.card->cis1_info[3] = NULL;
92 state.card->manufacturer = PCMCIA_VENDOR_INVALID;
93 state.card->product = PCMCIA_PRODUCT_INVALID;
94 STAILQ_INIT(&state.card->pf_head);
95
96 state.pf = NULL;
97
98 if (pccard_scan_cis(sc->dev, pccard_parse_cis_tuple,
99 &state) == -1)
100 state.card->error++;
101}
102
103int
104pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *),
105 void *arg)
106{
107 struct resource *res;
108 int rid;
109 struct pccard_tuple tuple;
110 int longlink_present;
111 int longlink_common;
112 u_long longlink_addr;
113 int mfc_count;
114 int mfc_index;
115 struct {
116 int common;
117 u_long addr;
118 } mfc[256 / 5];
119 int ret;
120
121 ret = 0;
122
123 /* allocate some memory */
124
125 rid = 0;
126 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0,
127 PCCARD_CIS_SIZE, RF_ACTIVE);
128 if (res == NULL) {
129 device_printf(dev, "can't alloc memory to read attributes\n");
130 return -1;
131 }
132 CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY,
133 rid, PCCARD_A_MEM_ATTR);
134 tuple.memt = rman_get_bustag(res);
135 tuple.memh = rman_get_bushandle(res);
136 tuple.ptr = 0;
137
138 DPRINTF(("cis mem map %x\n", (unsigned int) tuple.memh));
139
140 tuple.mult = 2;
141
142 longlink_present = 1;
143 longlink_common = 1;
144 longlink_addr = 0;
145
146 mfc_count = 0;
147 mfc_index = 0;
148
149 DEVPRINTF((dev, "CIS tuple chain:\n"));
150
151 while (1) {
152 while (1) {
153 /* get the tuple code */
154
155 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
156
157 /* two special-case tuples */
158
159 if (tuple.code == PCCARD_CISTPL_NULL) {
160 DPRINTF(("CISTPL_NONE\n 00\n"));
161 tuple.ptr++;
162 continue;
163 } else if (tuple.code == PCCARD_CISTPL_END) {
164 DPRINTF(("CISTPL_END\n ff\n"));
165 /* Call the function for the END tuple, since
166 the CIS semantics depend on it */
167 if ((*fct) (&tuple, arg)) {
168 ret = 1;
169 goto done;
170 }
171 ret = 1; goto done; /* XXX IMP XXX */
172 tuple.ptr++;
173 break;
174 }
175 /* now all the normal tuples */
176
177 tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
178 switch (tuple.code) {
179 case PCCARD_CISTPL_LONGLINK_A:
180 case PCCARD_CISTPL_LONGLINK_C:
181 if (tuple.length < 4) {
182 DPRINTF(("CISTPL_LONGLINK_%s too "
183 "short %d\n",
184 longlink_common ? "C" : "A",
185 tuple.length));
186 break;
187 }
188 longlink_present = 1;
189 longlink_common = (tuple.code ==
190 PCCARD_CISTPL_LONGLINK_C) ? 1 : 0;
191 longlink_addr = pccard_tuple_read_4(&tuple, 0);
192 DPRINTF(("CISTPL_LONGLINK_%s %lx\n",
193 longlink_common ? "C" : "A",
194 longlink_addr));
195 break;
196 case PCCARD_CISTPL_NO_LINK:
197 longlink_present = 0;
198 DPRINTF(("CISTPL_NO_LINK\n"));
199 break;
200 case PCCARD_CISTPL_CHECKSUM:
201 if (tuple.length < 5) {
202 DPRINTF(("CISTPL_CHECKSUM too "
203 "short %d\n", tuple.length));
204 break;
205 } {
206 int16_t offset;
207 u_long addr, length;
208 u_int cksum, sum;
209 int i;
210
211 *((u_int16_t *) & offset) =
212 pccard_tuple_read_2(&tuple, 0);
213 length = pccard_tuple_read_2(&tuple, 2);
214 cksum = pccard_tuple_read_1(&tuple, 4);
215
216 addr = tuple.ptr + offset;
217
218 DPRINTF(("CISTPL_CHECKSUM addr=%lx "
219 "len=%lx cksum=%x",
220 addr, length, cksum));
221
222 /*
223 * XXX do more work to deal with
224 * distant regions
225 */
226 if ((addr >= PCCARD_CIS_SIZE) ||
227 ((addr + length) < 0) ||
228 ((addr + length) >=
229 PCCARD_CIS_SIZE)) {
230 DPRINTF((" skipped, "
231 "too distant\n"));
232 break;
233 }
234 sum = 0;
235 for (i = 0; i < length; i++)
236 sum +=
237 bus_space_read_1(tuple.memt,
238 tuple.memh,
239 addr + tuple.mult * i);
240 if (cksum != (sum & 0xff)) {
241 DPRINTF((" failed sum=%x\n",
242 sum));
243 device_printf(dev,
244 "CIS checksum failed\n");
245#if 0
246 /*
247 * XXX Some working cards have
248 * XXX bad checksums!!
249 */
250 ret = -1;
251#endif
252 } else {
253 DPRINTF((" ok\n"));
254 }
255 }
256 break;
257 case PCCARD_CISTPL_LONGLINK_MFC:
258 if (tuple.length < 1) {
259 DPRINTF(("CISTPL_LONGLINK_MFC too "
260 "short %d\n", tuple.length));
261 break;
262 }
263 /*
264 * this is kind of ad hoc, as I don't have
265 * any real documentation
266 */
267 {
268 int i;
269
270 mfc_count =
271 pccard_tuple_read_1(&tuple, 0);
272 DPRINTF(("CISTPL_LONGLINK_MFC %d",
273 mfc_count));
274 for (i = 0; i < mfc_count; i++) {
275 mfc[i].common =
276 (pccard_tuple_read_1(&tuple,
277 1 + 5 * i) ==
278 PCCARD_MFC_MEM_COMMON) ?
279 1 : 0;
280 mfc[i].addr =
281 pccard_tuple_read_4(&tuple,
282 1 + 5 * i + 1);
283 DPRINTF((" %s:%lx",
284 mfc[i].common ? "common" :
285 "attr", mfc[i].addr));
286 }
287 DPRINTF(("\n"));
288 }
289 /*
290 * for LONGLINK_MFC, fall through to the
291 * function. This tuple has structural and
292 * semantic content.
293 */
294 default:
295 {
296 if ((*fct) (&tuple, arg)) {
297 ret = 1;
298 goto done;
299 }
300 }
301 break;
302 } /* switch */
303#ifdef PCCARDCISDEBUG
304 /* print the tuple */
305 {
306 int i;
307
308 DPRINTF((" %02x %02x", tuple.code,
309 tuple.length));
310
311 for (i = 0; i < tuple.length; i++) {
312 DPRINTF((" %02x",
313 pccard_tuple_read_1(&tuple, i)));
314 if ((i % 16) == 13)
315 DPRINTF(("\n"));
316 }
171 tuple.ptr++;
172 break;
173 }
174 /* now all the normal tuples */
175
176 tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
177 switch (tuple.code) {
178 case PCCARD_CISTPL_LONGLINK_A:
179 case PCCARD_CISTPL_LONGLINK_C:
180 if (tuple.length < 4) {
181 DPRINTF(("CISTPL_LONGLINK_%s too "
182 "short %d\n",
183 longlink_common ? "C" : "A",
184 tuple.length));
185 break;
186 }
187 longlink_present = 1;
188 longlink_common = (tuple.code ==
189 PCCARD_CISTPL_LONGLINK_C) ? 1 : 0;
190 longlink_addr = pccard_tuple_read_4(&tuple, 0);
191 DPRINTF(("CISTPL_LONGLINK_%s %lx\n",
192 longlink_common ? "C" : "A",
193 longlink_addr));
194 break;
195 case PCCARD_CISTPL_NO_LINK:
196 longlink_present = 0;
197 DPRINTF(("CISTPL_NO_LINK\n"));
198 break;
199 case PCCARD_CISTPL_CHECKSUM:
200 if (tuple.length < 5) {
201 DPRINTF(("CISTPL_CHECKSUM too "
202 "short %d\n", tuple.length));
203 break;
204 } {
205 int16_t offset;
206 u_long addr, length;
207 u_int cksum, sum;
208 int i;
209
210 *((u_int16_t *) & offset) =
211 pccard_tuple_read_2(&tuple, 0);
212 length = pccard_tuple_read_2(&tuple, 2);
213 cksum = pccard_tuple_read_1(&tuple, 4);
214
215 addr = tuple.ptr + offset;
216
217 DPRINTF(("CISTPL_CHECKSUM addr=%lx "
218 "len=%lx cksum=%x",
219 addr, length, cksum));
220
221 /*
222 * XXX do more work to deal with
223 * distant regions
224 */
225 if ((addr >= PCCARD_CIS_SIZE) ||
226 ((addr + length) < 0) ||
227 ((addr + length) >=
228 PCCARD_CIS_SIZE)) {
229 DPRINTF((" skipped, "
230 "too distant\n"));
231 break;
232 }
233 sum = 0;
234 for (i = 0; i < length; i++)
235 sum +=
236 bus_space_read_1(tuple.memt,
237 tuple.memh,
238 addr + tuple.mult * i);
239 if (cksum != (sum & 0xff)) {
240 DPRINTF((" failed sum=%x\n",
241 sum));
242 device_printf(dev,
243 "CIS checksum failed\n");
244#if 0
245 /*
246 * XXX Some working cards have
247 * XXX bad checksums!!
248 */
249 ret = -1;
250#endif
251 } else {
252 DPRINTF((" ok\n"));
253 }
254 }
255 break;
256 case PCCARD_CISTPL_LONGLINK_MFC:
257 if (tuple.length < 1) {
258 DPRINTF(("CISTPL_LONGLINK_MFC too "
259 "short %d\n", tuple.length));
260 break;
261 }
262 /*
263 * this is kind of ad hoc, as I don't have
264 * any real documentation
265 */
266 {
267 int i;
268
269 mfc_count =
270 pccard_tuple_read_1(&tuple, 0);
271 DPRINTF(("CISTPL_LONGLINK_MFC %d",
272 mfc_count));
273 for (i = 0; i < mfc_count; i++) {
274 mfc[i].common =
275 (pccard_tuple_read_1(&tuple,
276 1 + 5 * i) ==
277 PCCARD_MFC_MEM_COMMON) ?
278 1 : 0;
279 mfc[i].addr =
280 pccard_tuple_read_4(&tuple,
281 1 + 5 * i + 1);
282 DPRINTF((" %s:%lx",
283 mfc[i].common ? "common" :
284 "attr", mfc[i].addr));
285 }
286 DPRINTF(("\n"));
287 }
288 /*
289 * for LONGLINK_MFC, fall through to the
290 * function. This tuple has structural and
291 * semantic content.
292 */
293 default:
294 {
295 if ((*fct) (&tuple, arg)) {
296 ret = 1;
297 goto done;
298 }
299 }
300 break;
301 } /* switch */
302#ifdef PCCARDCISDEBUG
303 /* print the tuple */
304 {
305 int i;
306
307 DPRINTF((" %02x %02x", tuple.code,
308 tuple.length));
309
310 for (i = 0; i < tuple.length; i++) {
311 DPRINTF((" %02x",
312 pccard_tuple_read_1(&tuple, i)));
313 if ((i % 16) == 13)
314 DPRINTF(("\n"));
315 }
316
317 if ((i % 16) != 14)
318 DPRINTF(("\n"));
319 }
320#endif
321 /* skip to the next tuple */
322 tuple.ptr += 2 + tuple.length;
323 }
324
317 if ((i % 16) != 14)
318 DPRINTF(("\n"));
319 }
320#endif
321 /* skip to the next tuple */
322 tuple.ptr += 2 + tuple.length;
323 }
324
325#ifdef XXX /* I'm not up to this tonight, need to implement new API */
326 /* to deal with moving windows and such. At least that's */
327 /* what it appears at this instant */
328
329 /*
330 * the chain is done. Clean up and move onto the next one,
331 * if any. The loop is here in the case that there is an MFC
332 * card with no longlink (which defaults to existing, == 0).
333 * In general, this means that if one pointer fails, it will
334 * try the next one, instead of just bailing.
335 */
336
337 while (1) {
325 /*
326 * the chain is done. Clean up and move onto the next one,
327 * if any. The loop is here in the case that there is an MFC
328 * card with no longlink (which defaults to existing, == 0).
329 * In general, this means that if one pointer fails, it will
330 * try the next one, instead of just bailing.
331 */
332
333 while (1) {
338 pccard_chip_mem_unmap(pct, pch, window);
339
340 if (longlink_present) {
334 if (longlink_present) {
341 /*
342 * if the longlink is to attribute memory,
343 * then it is unindexed. That is, if the
344 * link value is 0x100, then the actual
345 * memory address is 0x200. This means that
346 * we need to multiply by 2 before calling
347 * mem_map, and then divide the resulting ptr
348 * by 2 after.
349 */
350
351 if (!longlink_common)
352 longlink_addr *= 2;
353
354 pccard_chip_mem_map(pct, pch, longlink_common ?
355 PCCARD_MEM_COMMON : PCCARD_MEM_ATTR,
356 longlink_addr, PCCARD_CIS_SIZE,
357 &pcmh, &tuple.ptr, &window);
358
359 if (!longlink_common)
360 tuple.ptr /= 2;
335 CARD_SET_RES_FLAGS(device_get_parent(dev), dev,
336 SYS_RES_MEMORY, rid, longlink_common ?
337 PCCARD_A_MEM_ATTR : PCCARD_A_MEM_ATTR);
361 DPRINTF(("cis mem map %x\n",
362 (unsigned int) tuple.memh));
363 tuple.mult = longlink_common ? 1 : 2;
364 longlink_present = 0;
365 longlink_common = 1;
366 longlink_addr = 0;
367 } else if (mfc_count && (mfc_index < mfc_count)) {
338 DPRINTF(("cis mem map %x\n",
339 (unsigned int) tuple.memh));
340 tuple.mult = longlink_common ? 1 : 2;
341 longlink_present = 0;
342 longlink_common = 1;
343 longlink_addr = 0;
344 } else if (mfc_count && (mfc_index < mfc_count)) {
368 if (!mfc[mfc_index].common)
369 mfc[mfc_index].addr *= 2;
370
371 pccard_chip_mem_map(pct, pch,
372 mfc[mfc_index].common ?
373 PCCARD_MEM_COMMON : PCCARD_MEM_ATTR,
374 mfc[mfc_index].addr, PCCARD_CIS_SIZE,
375 &pcmh, &tuple.ptr, &window);
376
377 if (!mfc[mfc_index].common)
378 tuple.ptr /= 2;
345 CARD_SET_RES_FLAGS(device_get_parent(dev), dev,
346 SYS_RES_MEMORY, rid, mfc[mfc_index].common
347 ? PCCARD_A_MEM_ATTR : PCCARD_A_MEM_ATTR);
379 DPRINTF(("cis mem map %x\n",
380 (unsigned int) tuple.memh));
381 /* set parse state, and point at the next one */
348 DPRINTF(("cis mem map %x\n",
349 (unsigned int) tuple.memh));
350 /* set parse state, and point at the next one */
382
383 tuple.mult = mfc[mfc_index].common ? 1 : 2;
351 tuple.mult = mfc[mfc_index].common ? 1 : 2;
384
385 mfc_index++;
386 } else {
387 goto done;
388 }
389
390 /* make sure that the link is valid */
391 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
392 if (tuple.code != PCCARD_CISTPL_LINKTARGET) {
393 DPRINTF(("CISTPL_LINKTARGET expected, "
394 "code %02x observed\n", tuple.code));
395 continue;
396 }
397 tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
398 if (tuple.length < 3) {
399 DPRINTF(("CISTPL_LINKTARGET too short %d\n",
400 tuple.length));
401 continue;
402 }
403 if ((pccard_tuple_read_1(&tuple, 0) != 'C') ||
404 (pccard_tuple_read_1(&tuple, 1) != 'I') ||
405 (pccard_tuple_read_1(&tuple, 2) != 'S')) {
406 DPRINTF(("CISTPL_LINKTARGET magic "
407 "%02x%02x%02x incorrect\n",
408 pccard_tuple_read_1(&tuple, 0),
409 pccard_tuple_read_1(&tuple, 1),
410 pccard_tuple_read_1(&tuple, 2)));
411 continue;
412 }
413 tuple.ptr += 2 + tuple.length;
352 mfc_index++;
353 } else {
354 goto done;
355 }
356
357 /* make sure that the link is valid */
358 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr);
359 if (tuple.code != PCCARD_CISTPL_LINKTARGET) {
360 DPRINTF(("CISTPL_LINKTARGET expected, "
361 "code %02x observed\n", tuple.code));
362 continue;
363 }
364 tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1);
365 if (tuple.length < 3) {
366 DPRINTF(("CISTPL_LINKTARGET too short %d\n",
367 tuple.length));
368 continue;
369 }
370 if ((pccard_tuple_read_1(&tuple, 0) != 'C') ||
371 (pccard_tuple_read_1(&tuple, 1) != 'I') ||
372 (pccard_tuple_read_1(&tuple, 2) != 'S')) {
373 DPRINTF(("CISTPL_LINKTARGET magic "
374 "%02x%02x%02x incorrect\n",
375 pccard_tuple_read_1(&tuple, 0),
376 pccard_tuple_read_1(&tuple, 1),
377 pccard_tuple_read_1(&tuple, 2)));
378 continue;
379 }
380 tuple.ptr += 2 + tuple.length;
414
415 break;
416 }
381 break;
382 }
417#endif /* XXX */
418 }
419
420done:
421 bus_release_resource(dev, SYS_RES_MEMORY, rid, res);
422
423 return (ret);
424}
425
426/* XXX this is incredibly verbose. Not sure what trt is */
427
428void
429pccard_print_cis(device_t dev)
430{
431 struct pccard_softc *sc = PCCARD_SOFTC(dev);
432 struct pccard_card *card = &sc->card;
433 struct pccard_function *pf;
434 struct pccard_config_entry *cfe;
435 int i;
436
437 device_printf(dev, "CIS version ");
438 if (card->cis1_major == 4) {
439 if (card->cis1_minor == 0)
440 printf("PCCARD 1.0\n");
441 else if (card->cis1_minor == 1)
442 printf("PCCARD 2.0 or 2.1\n");
443 } else if (card->cis1_major >= 5)
444 printf("PC Card Standard %d.%d\n", card->cis1_major, card->cis1_minor);
445 else
446 printf("unknown (major=%d, minor=%d)\n",
447 card->cis1_major, card->cis1_minor);
448
449 device_printf(dev, "CIS info: ");
450 for (i = 0; i < 4; i++) {
451 if (card->cis1_info[i] == NULL)
452 break;
453 if (i)
454 printf(", ");
455 printf("%s", card->cis1_info[i]);
456 }
457 printf("\n");
458
459 device_printf(dev, "Manufacturer code 0x%x, product 0x%x\n",
460 card->manufacturer, card->product);
461
462 STAILQ_FOREACH(pf, &card->pf_head, pf_list) {
463 device_printf(dev, "function %d: ", pf->number);
464
465 switch (pf->function) {
466 case PCCARD_FUNCTION_UNSPEC:
467 printf("unspecified");
468 break;
469 case PCCARD_FUNCTION_MULTIFUNCTION:
470 printf("multi-function");
471 break;
472 case PCCARD_FUNCTION_MEMORY:
473 printf("memory");
474 break;
475 case PCCARD_FUNCTION_SERIAL:
476 printf("serial port");
477 break;
478 case PCCARD_FUNCTION_PARALLEL:
479 printf("parallel port");
480 break;
481 case PCCARD_FUNCTION_DISK:
482 printf("fixed disk");
483 break;
484 case PCCARD_FUNCTION_VIDEO:
485 printf("video adapter");
486 break;
487 case PCCARD_FUNCTION_NETWORK:
488 printf("network adapter");
489 break;
490 case PCCARD_FUNCTION_AIMS:
491 printf("auto incrementing mass storage");
492 break;
493 case PCCARD_FUNCTION_SCSI:
494 printf("SCSI bridge");
495 break;
496 case PCCARD_FUNCTION_SECURITY:
497 printf("Security services");
498 break;
499 case PCCARD_FUNCTION_INSTRUMENT:
500 printf("Instrument");
501 break;
502 default:
503 printf("unknown (%d)", pf->function);
504 break;
505 }
506
507 printf(", ccr addr %lx mask %lx\n", pf->ccr_base, pf->ccr_mask);
508
509 STAILQ_FOREACH(cfe, &pf->cfe_head, cfe_list) {
510 device_printf(dev, "function %d, config table entry "
511 "%d: ", pf->number, cfe->number);
512
513 switch (cfe->iftype) {
514 case PCCARD_IFTYPE_MEMORY:
515 printf("memory card");
516 break;
517 case PCCARD_IFTYPE_IO:
518 printf("I/O card");
519 break;
520 default:
521 printf("card type unknown");
522 break;
523 }
524
525 printf("; irq mask %x", cfe->irqmask);
526
527 if (cfe->num_iospace) {
528 printf("; iomask %lx, iospace", cfe->iomask);
529
530 for (i = 0; i < cfe->num_iospace; i++) {
531 printf(" %lx", cfe->iospace[i].start);
532 if (cfe->iospace[i].length)
533 printf("-%lx",
534 cfe->iospace[i].start +
535 cfe->iospace[i].length - 1);
536 }
537 }
538 if (cfe->num_memspace) {
539 printf("; memspace");
540
541 for (i = 0; i < cfe->num_memspace; i++) {
542 printf(" %lx",
543 cfe->memspace[i].cardaddr);
544 if (cfe->memspace[i].length)
545 printf("-%lx",
546 cfe->memspace[i].cardaddr +
547 cfe->memspace[i].length - 1);
548 if (cfe->memspace[i].hostaddr)
549 printf("@%lx",
550 cfe->memspace[i].hostaddr);
551 }
552 }
553 if (cfe->maxtwins)
554 printf("; maxtwins %d", cfe->maxtwins);
555
556 printf(";");
557
558 if (cfe->flags & PCCARD_CFE_MWAIT_REQUIRED)
559 printf(" mwait_required");
560 if (cfe->flags & PCCARD_CFE_RDYBSY_ACTIVE)
561 printf(" rdybsy_active");
562 if (cfe->flags & PCCARD_CFE_WP_ACTIVE)
563 printf(" wp_active");
564 if (cfe->flags & PCCARD_CFE_BVD_ACTIVE)
565 printf(" bvd_active");
566 if (cfe->flags & PCCARD_CFE_IO8)
567 printf(" io8");
568 if (cfe->flags & PCCARD_CFE_IO16)
569 printf(" io16");
570 if (cfe->flags & PCCARD_CFE_IRQSHARE)
571 printf(" irqshare");
572 if (cfe->flags & PCCARD_CFE_IRQPULSE)
573 printf(" irqpulse");
574 if (cfe->flags & PCCARD_CFE_IRQLEVEL)
575 printf(" irqlevel");
576 if (cfe->flags & PCCARD_CFE_POWERDOWN)
577 printf(" powerdown");
578 if (cfe->flags & PCCARD_CFE_READONLY)
579 printf(" readonly");
580 if (cfe->flags & PCCARD_CFE_AUDIO)
581 printf(" audio");
582
583 printf("\n");
584 }
585 }
586
587 if (card->error)
588 device_printf(dev, "%d errors found while parsing CIS\n",
589 card->error);
590}
591
592int
593pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg)
594{
595 /* most of these are educated guesses */
596 static struct pccard_config_entry init_cfe = {
597 -1, PCCARD_CFE_RDYBSY_ACTIVE | PCCARD_CFE_WP_ACTIVE |
598 PCCARD_CFE_BVD_ACTIVE, PCCARD_IFTYPE_MEMORY,
599 };
600
601 struct cis_state *state = arg;
602
603 switch (tuple->code) {
604 case PCCARD_CISTPL_END:
605 /* if we've seen a LONGLINK_MFC, and this is the first
606 * END after it, reset the function list.
607 *
608 * XXX This might also be the right place to start a
609 * new function, but that assumes that a function
610 * definition never crosses any longlink, and I'm not
611 * sure about that. This is probably safe for MFC
612 * cards, but what we have now isn't broken, so I'd
613 * rather not change it.
614 */
615 if (state->gotmfc == 1) {
616 struct pccard_function *pf, *pfnext;
617
618 for (pf = STAILQ_FIRST(&state->card->pf_head);
619 pf != NULL; pf = pfnext) {
620 pfnext = STAILQ_NEXT(pf, pf_list);
621 free(pf, M_DEVBUF);
622 }
623
624 STAILQ_INIT(&state->card->pf_head);
625
626 state->count = 0;
627 state->gotmfc = 2;
628 state->pf = NULL;
629 }
630 break;
631 case PCCARD_CISTPL_LONGLINK_MFC:
632 /*
633 * this tuple's structure was dealt with in scan_cis. here,
634 * record the fact that the MFC tuple was seen, so that
635 * functions declared before the MFC link can be cleaned
636 * up.
637 */
638 state->gotmfc = 1;
639 break;
640#ifdef PCCARDCISDEBUG
641 case PCCARD_CISTPL_DEVICE:
642 case PCCARD_CISTPL_DEVICE_A:
643 {
644 u_int reg, dtype, dspeed;
645
646 reg = pccard_tuple_read_1(tuple, 0);
647 dtype = reg & PCCARD_DTYPE_MASK;
648 dspeed = reg & PCCARD_DSPEED_MASK;
649
650 DPRINTF(("CISTPL_DEVICE%s type=",
651 (tuple->code == PCCARD_CISTPL_DEVICE) ? "" : "_A"));
652 switch (dtype) {
653 case PCCARD_DTYPE_NULL:
654 DPRINTF(("null"));
655 break;
656 case PCCARD_DTYPE_ROM:
657 DPRINTF(("rom"));
658 break;
659 case PCCARD_DTYPE_OTPROM:
660 DPRINTF(("otprom"));
661 break;
662 case PCCARD_DTYPE_EPROM:
663 DPRINTF(("eprom"));
664 break;
665 case PCCARD_DTYPE_EEPROM:
666 DPRINTF(("eeprom"));
667 break;
668 case PCCARD_DTYPE_FLASH:
669 DPRINTF(("flash"));
670 break;
671 case PCCARD_DTYPE_SRAM:
672 DPRINTF(("sram"));
673 break;
674 case PCCARD_DTYPE_DRAM:
675 DPRINTF(("dram"));
676 break;
677 case PCCARD_DTYPE_FUNCSPEC:
678 DPRINTF(("funcspec"));
679 break;
680 case PCCARD_DTYPE_EXTEND:
681 DPRINTF(("extend"));
682 break;
683 default:
684 DPRINTF(("reserved"));
685 break;
686 }
687 DPRINTF((" speed="));
688 switch (dspeed) {
689 case PCCARD_DSPEED_NULL:
690 DPRINTF(("null"));
691 break;
692 case PCCARD_DSPEED_250NS:
693 DPRINTF(("250ns"));
694 break;
695 case PCCARD_DSPEED_200NS:
696 DPRINTF(("200ns"));
697 break;
698 case PCCARD_DSPEED_150NS:
699 DPRINTF(("150ns"));
700 break;
701 case PCCARD_DSPEED_100NS:
702 DPRINTF(("100ns"));
703 break;
704 case PCCARD_DSPEED_EXT:
705 DPRINTF(("ext"));
706 break;
707 default:
708 DPRINTF(("reserved"));
709 break;
710 }
711 }
712 DPRINTF(("\n"));
713 break;
714#endif
715 case PCCARD_CISTPL_VERS_1:
716 if (tuple->length < 6) {
717 DPRINTF(("CISTPL_VERS_1 too short %d\n",
718 tuple->length));
719 break;
720 } {
721 int start, i, ch, count;
722
723 state->card->cis1_major = pccard_tuple_read_1(tuple, 0);
724 state->card->cis1_minor = pccard_tuple_read_1(tuple, 1);
725
726 for (count = 0, start = 0, i = 0;
727 (count < 4) && ((i + 4) < 256); i++) {
728 ch = pccard_tuple_read_1(tuple, 2 + i);
729 if (ch == 0xff)
730 break;
731 state->card->cis1_info_buf[i] = ch;
732 if (ch == 0) {
733 state->card->cis1_info[count] =
734 state->card->cis1_info_buf + start;
735 start = i + 1;
736 count++;
737 }
738 }
739 DPRINTF(("CISTPL_VERS_1\n"));
740 }
741 break;
742 case PCCARD_CISTPL_MANFID:
743 if (tuple->length < 4) {
744 DPRINTF(("CISTPL_MANFID too short %d\n",
745 tuple->length));
746 break;
747 }
748 state->card->manufacturer = pccard_tuple_read_2(tuple, 0);
749 state->card->product = pccard_tuple_read_2(tuple, 2);
750 DPRINTF(("CISTPL_MANFID\n"));
751 break;
752 case PCCARD_CISTPL_FUNCID:
753 if (tuple->length < 1) {
754 DPRINTF(("CISTPL_FUNCID too short %d\n",
755 tuple->length));
756 break;
757 }
758 if ((state->pf == NULL) || (state->gotmfc == 2)) {
759 state->pf = malloc(sizeof(*state->pf), M_DEVBUF,
760 M_NOWAIT | M_ZERO);
761 state->pf->number = state->count++;
762 state->pf->last_config_index = -1;
763 STAILQ_INIT(&state->pf->cfe_head);
764
765 STAILQ_INSERT_TAIL(&state->card->pf_head, state->pf,
766 pf_list);
767 }
768 state->pf->function = pccard_tuple_read_1(tuple, 0);
769
770 DPRINTF(("CISTPL_FUNCID\n"));
771 break;
772 case PCCARD_CISTPL_FUNCE:
773 if (state->pf == NULL || state->pf->function <= 0) {
774 DPRINTF(("CISTPL_FUNCE is not followed by "
775 "valid CISTPL_FUNCID\n"));
776 break;
777 }
778 if (tuple->length >= 2) {
779 decode_funce(tuple, state->pf);
780 }
781 DPRINTF(("CISTPL_FUNCE\n"));
782 break;
783 case PCCARD_CISTPL_CONFIG:
784 if (tuple->length < 3) {
785 DPRINTF(("CISTPL_CONFIG too short %d\n",
786 tuple->length));
787 break;
788 } {
789 u_int reg, rasz, rmsz, rfsz;
790 int i;
791
792 reg = pccard_tuple_read_1(tuple, 0);
793 rasz = 1 + ((reg & PCCARD_TPCC_RASZ_MASK) >>
794 PCCARD_TPCC_RASZ_SHIFT);
795 rmsz = 1 + ((reg & PCCARD_TPCC_RMSZ_MASK) >>
796 PCCARD_TPCC_RMSZ_SHIFT);
797 rfsz = ((reg & PCCARD_TPCC_RFSZ_MASK) >>
798 PCCARD_TPCC_RFSZ_SHIFT);
799
800 if (tuple->length < (rasz + rmsz + rfsz)) {
801 DPRINTF(("CISTPL_CONFIG (%d,%d,%d) too "
802 "short %d\n", rasz, rmsz, rfsz,
803 tuple->length));
804 break;
805 }
806 if (state->pf == NULL) {
807 state->pf = malloc(sizeof(*state->pf),
808 M_DEVBUF, M_NOWAIT | M_ZERO);
809 state->pf->number = state->count++;
810 state->pf->last_config_index = -1;
811 STAILQ_INIT(&state->pf->cfe_head);
812
813 STAILQ_INSERT_TAIL(&state->card->pf_head,
814 state->pf, pf_list);
815
816 state->pf->function = PCCARD_FUNCTION_UNSPEC;
817 }
818 state->pf->last_config_index =
819 pccard_tuple_read_1(tuple, 1);
820
821 state->pf->ccr_base = 0;
822 for (i = 0; i < rasz; i++)
823 state->pf->ccr_base |=
824 ((pccard_tuple_read_1(tuple, 2 + i)) <<
825 (i * 8));
826
827 state->pf->ccr_mask = 0;
828 for (i = 0; i < rmsz; i++)
829 state->pf->ccr_mask |=
830 ((pccard_tuple_read_1(tuple,
831 2 + rasz + i)) << (i * 8));
832
833 /* skip the reserved area and subtuples */
834
835 /* reset the default cfe for each cfe list */
836 state->temp_cfe = init_cfe;
837 state->default_cfe = &state->temp_cfe;
838 }
839 DPRINTF(("CISTPL_CONFIG\n"));
840 break;
841 case PCCARD_CISTPL_CFTABLE_ENTRY:
842 {
843 int idx, i, j;
844 u_int reg, reg2;
845 u_int intface, def, num;
846 u_int power, timing, iospace, irq, memspace, misc;
847 struct pccard_config_entry *cfe;
848
849 idx = 0;
850
851 reg = pccard_tuple_read_1(tuple, idx);
852 idx++;
853 intface = reg & PCCARD_TPCE_INDX_INTFACE;
854 def = reg & PCCARD_TPCE_INDX_DEFAULT;
855 num = reg & PCCARD_TPCE_INDX_NUM_MASK;
856
857 /*
858 * this is a little messy. Some cards have only a
859 * cfentry with the default bit set. So, as we go
860 * through the list, we add new indexes to the queue,
861 * and keep a pointer to the last one with the
862 * default bit set. if we see a record with the same
863 * index, as the default, we stash the default and
864 * replace the queue entry. otherwise, we just add
865 * new entries to the queue, pointing the default ptr
866 * at them if the default bit is set. if we get to
867 * the end with the default pointer pointing at a
868 * record which hasn't had a matching index, that's
869 * ok; it just becomes a cfentry like any other.
870 */
871
872 /*
873 * if the index in the cis differs from the default
874 * cis, create new entry in the queue and start it
875 * with the current default
876 */
877 if (num != state->default_cfe->number) {
878 cfe = (struct pccard_config_entry *)
879 malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
880
881 *cfe = *state->default_cfe;
882
883 STAILQ_INSERT_TAIL(&state->pf->cfe_head,
884 cfe, cfe_list);
885
886 cfe->number = num;
887
888 /*
889 * if the default bit is set in the cis, then
890 * point the new default at whatever is being
891 * filled in
892 */
893 if (def)
894 state->default_cfe = cfe;
895 } else {
896 /*
897 * the cis index matches the default index,
898 * fill in the default cfentry. It is
899 * assumed that the cfdefault index is in the
900 * queue. For it to be otherwise, the cis
901 * index would have to be -1 (initial
902 * condition) which is not possible, or there
903 * would have to be a preceding cis entry
904 * which had the same cis index and had the
905 * default bit unset. Neither condition
906 * should happen. If it does, this cfentry
907 * is lost (written into temp space), which
908 * is an acceptable failure mode.
909 */
910
911 cfe = state->default_cfe;
912
913 /*
914 * if the cis entry does not have the default
915 * bit set, copy the default out of the way
916 * first.
917 */
918 if (!def) {
919 state->temp_cfe = *state->default_cfe;
920 state->default_cfe = &state->temp_cfe;
921 }
922 }
923
924 if (intface) {
925 reg = pccard_tuple_read_1(tuple, idx);
926 idx++;
927 if (reg & PCCARD_TPCE_IF_MWAIT)
928 cfe->flags |= PCCARD_CFE_MWAIT_REQUIRED;
929 if (reg & PCCARD_TPCE_IF_RDYBSY)
930 cfe->flags |= PCCARD_CFE_RDYBSY_ACTIVE;
931 if (reg & PCCARD_TPCE_IF_WP)
932 cfe->flags |= PCCARD_CFE_WP_ACTIVE;
933 if (reg & PCCARD_TPCE_IF_BVD)
934 cfe->flags |= PCCARD_CFE_BVD_ACTIVE;
935 cfe->iftype = reg & PCCARD_TPCE_IF_IFTYPE;
936 }
937 reg = pccard_tuple_read_1(tuple, idx);
938 idx++;
939
940 power = reg & PCCARD_TPCE_FS_POWER_MASK;
941 timing = reg & PCCARD_TPCE_FS_TIMING;
942 iospace = reg & PCCARD_TPCE_FS_IOSPACE;
943 irq = reg & PCCARD_TPCE_FS_IRQ;
944 memspace = reg & PCCARD_TPCE_FS_MEMSPACE_MASK;
945 misc = reg & PCCARD_TPCE_FS_MISC;
946
947 if (power) {
948 /* skip over power, don't save */
949 /* for each parameter selection byte */
950 for (i = 0; i < power; i++) {
951 reg = pccard_tuple_read_1(tuple, idx);
952 idx++;
953 /* for each bit */
954 for (j = 0; j < 7; j++) {
955 /* if the bit is set */
956 if ((reg >> j) & 0x01) {
957 /* skip over bytes */
958 do {
959 reg2 = pccard_tuple_read_1(tuple, idx);
960 idx++;
961 /*
962 * until
963 * non-extensi
964 * on byte
965 */
966 } while (reg2 & 0x80);
967 }
968 }
969 }
970 }
971 if (timing) {
972 /* skip over timing, don't save */
973 reg = pccard_tuple_read_1(tuple, idx);
974 idx++;
975
976 if ((reg & PCCARD_TPCE_TD_RESERVED_MASK) !=
977 PCCARD_TPCE_TD_RESERVED_MASK)
978 idx++;
979 if ((reg & PCCARD_TPCE_TD_RDYBSY_MASK) !=
980 PCCARD_TPCE_TD_RDYBSY_MASK)
981 idx++;
982 if ((reg & PCCARD_TPCE_TD_WAIT_MASK) !=
983 PCCARD_TPCE_TD_WAIT_MASK)
984 idx++;
985 }
986 if (iospace) {
987 if (tuple->length <= idx) {
988 DPRINTF(("ran out of space before TCPE_IO\n"));
989 goto abort_cfe;
990 }
991
992 reg = pccard_tuple_read_1(tuple, idx);
993 idx++;
994
995 if (reg & PCCARD_TPCE_IO_BUSWIDTH_8BIT)
996 cfe->flags |= PCCARD_CFE_IO8;
997 if (reg & PCCARD_TPCE_IO_BUSWIDTH_16BIT)
998 cfe->flags |= PCCARD_CFE_IO16;
999 cfe->iomask =
1000 reg & PCCARD_TPCE_IO_IOADDRLINES_MASK;
1001
1002 if (reg & PCCARD_TPCE_IO_HASRANGE) {
1003 reg = pccard_tuple_read_1(tuple, idx);
1004 idx++;
1005
1006 cfe->num_iospace = 1 + (reg &
1007 PCCARD_TPCE_IO_RANGE_COUNT);
1008
1009 if (cfe->num_iospace >
1010 (sizeof(cfe->iospace) /
1011 sizeof(cfe->iospace[0]))) {
1012 DPRINTF(("too many io "
1013 "spaces %d",
1014 cfe->num_iospace));
1015 state->card->error++;
1016 break;
1017 }
1018 for (i = 0; i < cfe->num_iospace; i++) {
1019 switch (reg & PCCARD_TPCE_IO_RANGE_ADDRSIZE_MASK) {
1020 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_ONE:
1021 cfe->iospace[i].start =
1022 pccard_tuple_read_1(tuple, idx);
1023 idx++;
1024 break;
1025 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_TWO:
1026 cfe->iospace[i].start =
1027 pccard_tuple_read_2(tuple, idx);
1028 idx += 2;
1029 break;
1030 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_FOUR:
1031 cfe->iospace[i].start =
1032 pccard_tuple_read_4(tuple, idx);
1033 idx += 4;
1034 break;
1035 }
1036 switch (reg &
1037 PCCARD_TPCE_IO_RANGE_LENGTHSIZE_MASK) {
1038 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_ONE:
1039 cfe->iospace[i].length =
1040 pccard_tuple_read_1(tuple, idx);
1041 idx++;
1042 break;
1043 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_TWO:
1044 cfe->iospace[i].length =
1045 pccard_tuple_read_2(tuple, idx);
1046 idx += 2;
1047 break;
1048 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_FOUR:
1049 cfe->iospace[i].length =
1050 pccard_tuple_read_4(tuple, idx);
1051 idx += 4;
1052 break;
1053 }
1054 cfe->iospace[i].length++;
1055 }
1056 } else {
1057 cfe->num_iospace = 1;
1058 cfe->iospace[0].start = 0;
1059 cfe->iospace[0].length =
1060 (1 << cfe->iomask);
1061 }
1062 }
1063 if (irq) {
1064 if (tuple->length <= idx) {
1065 DPRINTF(("ran out of space before TCPE_IR\n"));
1066 goto abort_cfe;
1067 }
1068
1069 reg = pccard_tuple_read_1(tuple, idx);
1070 idx++;
1071
1072 if (reg & PCCARD_TPCE_IR_SHARE)
1073 cfe->flags |= PCCARD_CFE_IRQSHARE;
1074 if (reg & PCCARD_TPCE_IR_PULSE)
1075 cfe->flags |= PCCARD_CFE_IRQPULSE;
1076 if (reg & PCCARD_TPCE_IR_LEVEL)
1077 cfe->flags |= PCCARD_CFE_IRQLEVEL;
1078
1079 if (reg & PCCARD_TPCE_IR_HASMASK) {
1080 /*
1081 * it's legal to ignore the
1082 * special-interrupt bits, so I will
1083 */
1084
1085 cfe->irqmask =
1086 pccard_tuple_read_2(tuple, idx);
1087 idx += 2;
1088 } else {
1089 cfe->irqmask =
1090 (1 << (reg & PCCARD_TPCE_IR_IRQ));
1091 }
1092 }
1093 if (memspace) {
1094 if (tuple->length <= idx) {
1095 DPRINTF(("ran out of space before TCPE_MS\n"));
1096 goto abort_cfe;
1097 }
1098
1099 if (memspace == PCCARD_TPCE_FS_MEMSPACE_NONE) {
1100 cfe->num_memspace = 0;
1101 } else if (memspace == PCCARD_TPCE_FS_MEMSPACE_LENGTH) {
1102 cfe->num_memspace = 1;
1103 cfe->memspace[0].length = 256 *
1104 pccard_tuple_read_2(tuple, idx);
1105 idx += 2;
1106 cfe->memspace[0].cardaddr = 0;
1107 cfe->memspace[0].hostaddr = 0;
1108 } else if (memspace ==
1109 PCCARD_TPCE_FS_MEMSPACE_LENGTHADDR) {
1110 cfe->num_memspace = 1;
1111 cfe->memspace[0].length = 256 *
1112 pccard_tuple_read_2(tuple, idx);
1113 idx += 2;
1114 cfe->memspace[0].cardaddr = 256 *
1115 pccard_tuple_read_2(tuple, idx);
1116 idx += 2;
1117 cfe->memspace[0].hostaddr = cfe->memspace[0].cardaddr;
1118 } else {
1119 int lengthsize;
1120 int cardaddrsize;
1121 int hostaddrsize;
1122
1123 reg = pccard_tuple_read_1(tuple, idx);
1124 idx++;
1125
1126 cfe->num_memspace = (reg &
1127 PCCARD_TPCE_MS_COUNT) + 1;
1128
1129 if (cfe->num_memspace >
1130 (sizeof(cfe->memspace) /
1131 sizeof(cfe->memspace[0]))) {
1132 DPRINTF(("too many mem "
1133 "spaces %d",
1134 cfe->num_memspace));
1135 state->card->error++;
1136 break;
1137 }
1138 lengthsize =
1139 ((reg & PCCARD_TPCE_MS_LENGTH_SIZE_MASK) >>
1140 PCCARD_TPCE_MS_LENGTH_SIZE_SHIFT);
1141 cardaddrsize =
1142 ((reg & PCCARD_TPCE_MS_CARDADDR_SIZE_MASK) >>
1143 PCCARD_TPCE_MS_CARDADDR_SIZE_SHIFT);
1144 hostaddrsize =
1145 (reg & PCCARD_TPCE_MS_HOSTADDR) ? cardaddrsize : 0;
1146
1147 if (lengthsize == 0) {
1148 DPRINTF(("cfe memspace "
1149 "lengthsize == 0"));
1150 state->card->error++;
1151 }
1152 for (i = 0; i < cfe->num_memspace; i++) {
1153 if (lengthsize) {
1154 cfe->memspace[i].length =
1155 256 * pccard_tuple_read_n(tuple, lengthsize,
1156 idx);
1157 idx += lengthsize;
1158 } else {
1159 cfe->memspace[i].length = 0;
1160 }
1161 if (cfe->memspace[i].length == 0) {
1162 DPRINTF(("cfe->memspace[%d].length == 0",
1163 i));
1164 state->card->error++;
1165 }
1166 if (cardaddrsize) {
1167 cfe->memspace[i].cardaddr =
1168 256 * pccard_tuple_read_n(tuple, cardaddrsize,
1169 idx);
1170 idx += cardaddrsize;
1171 } else {
1172 cfe->memspace[i].cardaddr = 0;
1173 }
1174 if (hostaddrsize) {
1175 cfe->memspace[i].hostaddr =
1176 256 * pccard_tuple_read_n(tuple, hostaddrsize,
1177 idx);
1178 idx += hostaddrsize;
1179 } else {
1180 cfe->memspace[i].hostaddr = 0;
1181 }
1182 }
1183 }
1184 }
1185 if (misc) {
1186 if (tuple->length <= idx) {
1187 DPRINTF(("ran out of space before TCPE_MI\n"));
1188 goto abort_cfe;
1189 }
1190
1191 reg = pccard_tuple_read_1(tuple, idx);
1192 idx++;
1193
1194 if (reg & PCCARD_TPCE_MI_PWRDOWN)
1195 cfe->flags = PCCARD_CFE_POWERDOWN;
1196 if (reg & PCCARD_TPCE_MI_READONLY)
1197 cfe->flags = PCCARD_CFE_READONLY;
1198 if (reg & PCCARD_TPCE_MI_AUDIO)
1199 cfe->flags = PCCARD_CFE_AUDIO;
1200 cfe->maxtwins = reg & PCCARD_TPCE_MI_MAXTWINS;
1201
1202 while (reg & PCCARD_TPCE_MI_EXT) {
1203 reg = pccard_tuple_read_1(tuple, idx);
1204 idx++;
1205 }
1206 }
1207 /* skip all the subtuples */
1208 }
1209
1210 abort_cfe:
1211 DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
1212 break;
1213 default:
1214 DPRINTF(("unhandled CISTPL %x\n", tuple->code));
1215 break;
1216 }
1217
1218 return (0);
1219}
1220
1221static int
1222decode_funce(struct pccard_tuple *tuple, struct pccard_function *pf)
1223{
1224 int type = pccard_tuple_read_1(tuple, 0);
1225
1226 switch (pf->function) {
1227 case PCCARD_FUNCTION_DISK:
1228 if (type == PCCARD_TPLFE_TYPE_DISK_DEVICE_INTERFACE) {
1229 pf->pf_funce_disk_interface
1230 = pccard_tuple_read_1(tuple, 1);
1231 }
1232 break;
1233 case PCCARD_FUNCTION_NETWORK:
1234 if (type == PCCARD_TPLFE_TYPE_LAN_NID) {
1235 int i;
1236 int len = pccard_tuple_read_1(tuple, 1);
1237 if (tuple->length < 2 + len || len > 8) {
1238 /* tuple length not enough or nid too long */
1239 break;
1240 }
1241 for (i = 0; i < len; i++) {
1242 pf->pf_funce_lan_nid[i]
1243 = pccard_tuple_read_1(tuple, i + 2);
1244 }
1245 pf->pf_funce_lan_nidlen = len;
1246 }
1247 break;
1248 default:
1249 break;
1250 }
1251 return 0;
1252}
383 }
384
385done:
386 bus_release_resource(dev, SYS_RES_MEMORY, rid, res);
387
388 return (ret);
389}
390
391/* XXX this is incredibly verbose. Not sure what trt is */
392
393void
394pccard_print_cis(device_t dev)
395{
396 struct pccard_softc *sc = PCCARD_SOFTC(dev);
397 struct pccard_card *card = &sc->card;
398 struct pccard_function *pf;
399 struct pccard_config_entry *cfe;
400 int i;
401
402 device_printf(dev, "CIS version ");
403 if (card->cis1_major == 4) {
404 if (card->cis1_minor == 0)
405 printf("PCCARD 1.0\n");
406 else if (card->cis1_minor == 1)
407 printf("PCCARD 2.0 or 2.1\n");
408 } else if (card->cis1_major >= 5)
409 printf("PC Card Standard %d.%d\n", card->cis1_major, card->cis1_minor);
410 else
411 printf("unknown (major=%d, minor=%d)\n",
412 card->cis1_major, card->cis1_minor);
413
414 device_printf(dev, "CIS info: ");
415 for (i = 0; i < 4; i++) {
416 if (card->cis1_info[i] == NULL)
417 break;
418 if (i)
419 printf(", ");
420 printf("%s", card->cis1_info[i]);
421 }
422 printf("\n");
423
424 device_printf(dev, "Manufacturer code 0x%x, product 0x%x\n",
425 card->manufacturer, card->product);
426
427 STAILQ_FOREACH(pf, &card->pf_head, pf_list) {
428 device_printf(dev, "function %d: ", pf->number);
429
430 switch (pf->function) {
431 case PCCARD_FUNCTION_UNSPEC:
432 printf("unspecified");
433 break;
434 case PCCARD_FUNCTION_MULTIFUNCTION:
435 printf("multi-function");
436 break;
437 case PCCARD_FUNCTION_MEMORY:
438 printf("memory");
439 break;
440 case PCCARD_FUNCTION_SERIAL:
441 printf("serial port");
442 break;
443 case PCCARD_FUNCTION_PARALLEL:
444 printf("parallel port");
445 break;
446 case PCCARD_FUNCTION_DISK:
447 printf("fixed disk");
448 break;
449 case PCCARD_FUNCTION_VIDEO:
450 printf("video adapter");
451 break;
452 case PCCARD_FUNCTION_NETWORK:
453 printf("network adapter");
454 break;
455 case PCCARD_FUNCTION_AIMS:
456 printf("auto incrementing mass storage");
457 break;
458 case PCCARD_FUNCTION_SCSI:
459 printf("SCSI bridge");
460 break;
461 case PCCARD_FUNCTION_SECURITY:
462 printf("Security services");
463 break;
464 case PCCARD_FUNCTION_INSTRUMENT:
465 printf("Instrument");
466 break;
467 default:
468 printf("unknown (%d)", pf->function);
469 break;
470 }
471
472 printf(", ccr addr %lx mask %lx\n", pf->ccr_base, pf->ccr_mask);
473
474 STAILQ_FOREACH(cfe, &pf->cfe_head, cfe_list) {
475 device_printf(dev, "function %d, config table entry "
476 "%d: ", pf->number, cfe->number);
477
478 switch (cfe->iftype) {
479 case PCCARD_IFTYPE_MEMORY:
480 printf("memory card");
481 break;
482 case PCCARD_IFTYPE_IO:
483 printf("I/O card");
484 break;
485 default:
486 printf("card type unknown");
487 break;
488 }
489
490 printf("; irq mask %x", cfe->irqmask);
491
492 if (cfe->num_iospace) {
493 printf("; iomask %lx, iospace", cfe->iomask);
494
495 for (i = 0; i < cfe->num_iospace; i++) {
496 printf(" %lx", cfe->iospace[i].start);
497 if (cfe->iospace[i].length)
498 printf("-%lx",
499 cfe->iospace[i].start +
500 cfe->iospace[i].length - 1);
501 }
502 }
503 if (cfe->num_memspace) {
504 printf("; memspace");
505
506 for (i = 0; i < cfe->num_memspace; i++) {
507 printf(" %lx",
508 cfe->memspace[i].cardaddr);
509 if (cfe->memspace[i].length)
510 printf("-%lx",
511 cfe->memspace[i].cardaddr +
512 cfe->memspace[i].length - 1);
513 if (cfe->memspace[i].hostaddr)
514 printf("@%lx",
515 cfe->memspace[i].hostaddr);
516 }
517 }
518 if (cfe->maxtwins)
519 printf("; maxtwins %d", cfe->maxtwins);
520
521 printf(";");
522
523 if (cfe->flags & PCCARD_CFE_MWAIT_REQUIRED)
524 printf(" mwait_required");
525 if (cfe->flags & PCCARD_CFE_RDYBSY_ACTIVE)
526 printf(" rdybsy_active");
527 if (cfe->flags & PCCARD_CFE_WP_ACTIVE)
528 printf(" wp_active");
529 if (cfe->flags & PCCARD_CFE_BVD_ACTIVE)
530 printf(" bvd_active");
531 if (cfe->flags & PCCARD_CFE_IO8)
532 printf(" io8");
533 if (cfe->flags & PCCARD_CFE_IO16)
534 printf(" io16");
535 if (cfe->flags & PCCARD_CFE_IRQSHARE)
536 printf(" irqshare");
537 if (cfe->flags & PCCARD_CFE_IRQPULSE)
538 printf(" irqpulse");
539 if (cfe->flags & PCCARD_CFE_IRQLEVEL)
540 printf(" irqlevel");
541 if (cfe->flags & PCCARD_CFE_POWERDOWN)
542 printf(" powerdown");
543 if (cfe->flags & PCCARD_CFE_READONLY)
544 printf(" readonly");
545 if (cfe->flags & PCCARD_CFE_AUDIO)
546 printf(" audio");
547
548 printf("\n");
549 }
550 }
551
552 if (card->error)
553 device_printf(dev, "%d errors found while parsing CIS\n",
554 card->error);
555}
556
557int
558pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg)
559{
560 /* most of these are educated guesses */
561 static struct pccard_config_entry init_cfe = {
562 -1, PCCARD_CFE_RDYBSY_ACTIVE | PCCARD_CFE_WP_ACTIVE |
563 PCCARD_CFE_BVD_ACTIVE, PCCARD_IFTYPE_MEMORY,
564 };
565
566 struct cis_state *state = arg;
567
568 switch (tuple->code) {
569 case PCCARD_CISTPL_END:
570 /* if we've seen a LONGLINK_MFC, and this is the first
571 * END after it, reset the function list.
572 *
573 * XXX This might also be the right place to start a
574 * new function, but that assumes that a function
575 * definition never crosses any longlink, and I'm not
576 * sure about that. This is probably safe for MFC
577 * cards, but what we have now isn't broken, so I'd
578 * rather not change it.
579 */
580 if (state->gotmfc == 1) {
581 struct pccard_function *pf, *pfnext;
582
583 for (pf = STAILQ_FIRST(&state->card->pf_head);
584 pf != NULL; pf = pfnext) {
585 pfnext = STAILQ_NEXT(pf, pf_list);
586 free(pf, M_DEVBUF);
587 }
588
589 STAILQ_INIT(&state->card->pf_head);
590
591 state->count = 0;
592 state->gotmfc = 2;
593 state->pf = NULL;
594 }
595 break;
596 case PCCARD_CISTPL_LONGLINK_MFC:
597 /*
598 * this tuple's structure was dealt with in scan_cis. here,
599 * record the fact that the MFC tuple was seen, so that
600 * functions declared before the MFC link can be cleaned
601 * up.
602 */
603 state->gotmfc = 1;
604 break;
605#ifdef PCCARDCISDEBUG
606 case PCCARD_CISTPL_DEVICE:
607 case PCCARD_CISTPL_DEVICE_A:
608 {
609 u_int reg, dtype, dspeed;
610
611 reg = pccard_tuple_read_1(tuple, 0);
612 dtype = reg & PCCARD_DTYPE_MASK;
613 dspeed = reg & PCCARD_DSPEED_MASK;
614
615 DPRINTF(("CISTPL_DEVICE%s type=",
616 (tuple->code == PCCARD_CISTPL_DEVICE) ? "" : "_A"));
617 switch (dtype) {
618 case PCCARD_DTYPE_NULL:
619 DPRINTF(("null"));
620 break;
621 case PCCARD_DTYPE_ROM:
622 DPRINTF(("rom"));
623 break;
624 case PCCARD_DTYPE_OTPROM:
625 DPRINTF(("otprom"));
626 break;
627 case PCCARD_DTYPE_EPROM:
628 DPRINTF(("eprom"));
629 break;
630 case PCCARD_DTYPE_EEPROM:
631 DPRINTF(("eeprom"));
632 break;
633 case PCCARD_DTYPE_FLASH:
634 DPRINTF(("flash"));
635 break;
636 case PCCARD_DTYPE_SRAM:
637 DPRINTF(("sram"));
638 break;
639 case PCCARD_DTYPE_DRAM:
640 DPRINTF(("dram"));
641 break;
642 case PCCARD_DTYPE_FUNCSPEC:
643 DPRINTF(("funcspec"));
644 break;
645 case PCCARD_DTYPE_EXTEND:
646 DPRINTF(("extend"));
647 break;
648 default:
649 DPRINTF(("reserved"));
650 break;
651 }
652 DPRINTF((" speed="));
653 switch (dspeed) {
654 case PCCARD_DSPEED_NULL:
655 DPRINTF(("null"));
656 break;
657 case PCCARD_DSPEED_250NS:
658 DPRINTF(("250ns"));
659 break;
660 case PCCARD_DSPEED_200NS:
661 DPRINTF(("200ns"));
662 break;
663 case PCCARD_DSPEED_150NS:
664 DPRINTF(("150ns"));
665 break;
666 case PCCARD_DSPEED_100NS:
667 DPRINTF(("100ns"));
668 break;
669 case PCCARD_DSPEED_EXT:
670 DPRINTF(("ext"));
671 break;
672 default:
673 DPRINTF(("reserved"));
674 break;
675 }
676 }
677 DPRINTF(("\n"));
678 break;
679#endif
680 case PCCARD_CISTPL_VERS_1:
681 if (tuple->length < 6) {
682 DPRINTF(("CISTPL_VERS_1 too short %d\n",
683 tuple->length));
684 break;
685 } {
686 int start, i, ch, count;
687
688 state->card->cis1_major = pccard_tuple_read_1(tuple, 0);
689 state->card->cis1_minor = pccard_tuple_read_1(tuple, 1);
690
691 for (count = 0, start = 0, i = 0;
692 (count < 4) && ((i + 4) < 256); i++) {
693 ch = pccard_tuple_read_1(tuple, 2 + i);
694 if (ch == 0xff)
695 break;
696 state->card->cis1_info_buf[i] = ch;
697 if (ch == 0) {
698 state->card->cis1_info[count] =
699 state->card->cis1_info_buf + start;
700 start = i + 1;
701 count++;
702 }
703 }
704 DPRINTF(("CISTPL_VERS_1\n"));
705 }
706 break;
707 case PCCARD_CISTPL_MANFID:
708 if (tuple->length < 4) {
709 DPRINTF(("CISTPL_MANFID too short %d\n",
710 tuple->length));
711 break;
712 }
713 state->card->manufacturer = pccard_tuple_read_2(tuple, 0);
714 state->card->product = pccard_tuple_read_2(tuple, 2);
715 DPRINTF(("CISTPL_MANFID\n"));
716 break;
717 case PCCARD_CISTPL_FUNCID:
718 if (tuple->length < 1) {
719 DPRINTF(("CISTPL_FUNCID too short %d\n",
720 tuple->length));
721 break;
722 }
723 if ((state->pf == NULL) || (state->gotmfc == 2)) {
724 state->pf = malloc(sizeof(*state->pf), M_DEVBUF,
725 M_NOWAIT | M_ZERO);
726 state->pf->number = state->count++;
727 state->pf->last_config_index = -1;
728 STAILQ_INIT(&state->pf->cfe_head);
729
730 STAILQ_INSERT_TAIL(&state->card->pf_head, state->pf,
731 pf_list);
732 }
733 state->pf->function = pccard_tuple_read_1(tuple, 0);
734
735 DPRINTF(("CISTPL_FUNCID\n"));
736 break;
737 case PCCARD_CISTPL_FUNCE:
738 if (state->pf == NULL || state->pf->function <= 0) {
739 DPRINTF(("CISTPL_FUNCE is not followed by "
740 "valid CISTPL_FUNCID\n"));
741 break;
742 }
743 if (tuple->length >= 2) {
744 decode_funce(tuple, state->pf);
745 }
746 DPRINTF(("CISTPL_FUNCE\n"));
747 break;
748 case PCCARD_CISTPL_CONFIG:
749 if (tuple->length < 3) {
750 DPRINTF(("CISTPL_CONFIG too short %d\n",
751 tuple->length));
752 break;
753 } {
754 u_int reg, rasz, rmsz, rfsz;
755 int i;
756
757 reg = pccard_tuple_read_1(tuple, 0);
758 rasz = 1 + ((reg & PCCARD_TPCC_RASZ_MASK) >>
759 PCCARD_TPCC_RASZ_SHIFT);
760 rmsz = 1 + ((reg & PCCARD_TPCC_RMSZ_MASK) >>
761 PCCARD_TPCC_RMSZ_SHIFT);
762 rfsz = ((reg & PCCARD_TPCC_RFSZ_MASK) >>
763 PCCARD_TPCC_RFSZ_SHIFT);
764
765 if (tuple->length < (rasz + rmsz + rfsz)) {
766 DPRINTF(("CISTPL_CONFIG (%d,%d,%d) too "
767 "short %d\n", rasz, rmsz, rfsz,
768 tuple->length));
769 break;
770 }
771 if (state->pf == NULL) {
772 state->pf = malloc(sizeof(*state->pf),
773 M_DEVBUF, M_NOWAIT | M_ZERO);
774 state->pf->number = state->count++;
775 state->pf->last_config_index = -1;
776 STAILQ_INIT(&state->pf->cfe_head);
777
778 STAILQ_INSERT_TAIL(&state->card->pf_head,
779 state->pf, pf_list);
780
781 state->pf->function = PCCARD_FUNCTION_UNSPEC;
782 }
783 state->pf->last_config_index =
784 pccard_tuple_read_1(tuple, 1);
785
786 state->pf->ccr_base = 0;
787 for (i = 0; i < rasz; i++)
788 state->pf->ccr_base |=
789 ((pccard_tuple_read_1(tuple, 2 + i)) <<
790 (i * 8));
791
792 state->pf->ccr_mask = 0;
793 for (i = 0; i < rmsz; i++)
794 state->pf->ccr_mask |=
795 ((pccard_tuple_read_1(tuple,
796 2 + rasz + i)) << (i * 8));
797
798 /* skip the reserved area and subtuples */
799
800 /* reset the default cfe for each cfe list */
801 state->temp_cfe = init_cfe;
802 state->default_cfe = &state->temp_cfe;
803 }
804 DPRINTF(("CISTPL_CONFIG\n"));
805 break;
806 case PCCARD_CISTPL_CFTABLE_ENTRY:
807 {
808 int idx, i, j;
809 u_int reg, reg2;
810 u_int intface, def, num;
811 u_int power, timing, iospace, irq, memspace, misc;
812 struct pccard_config_entry *cfe;
813
814 idx = 0;
815
816 reg = pccard_tuple_read_1(tuple, idx);
817 idx++;
818 intface = reg & PCCARD_TPCE_INDX_INTFACE;
819 def = reg & PCCARD_TPCE_INDX_DEFAULT;
820 num = reg & PCCARD_TPCE_INDX_NUM_MASK;
821
822 /*
823 * this is a little messy. Some cards have only a
824 * cfentry with the default bit set. So, as we go
825 * through the list, we add new indexes to the queue,
826 * and keep a pointer to the last one with the
827 * default bit set. if we see a record with the same
828 * index, as the default, we stash the default and
829 * replace the queue entry. otherwise, we just add
830 * new entries to the queue, pointing the default ptr
831 * at them if the default bit is set. if we get to
832 * the end with the default pointer pointing at a
833 * record which hasn't had a matching index, that's
834 * ok; it just becomes a cfentry like any other.
835 */
836
837 /*
838 * if the index in the cis differs from the default
839 * cis, create new entry in the queue and start it
840 * with the current default
841 */
842 if (num != state->default_cfe->number) {
843 cfe = (struct pccard_config_entry *)
844 malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
845
846 *cfe = *state->default_cfe;
847
848 STAILQ_INSERT_TAIL(&state->pf->cfe_head,
849 cfe, cfe_list);
850
851 cfe->number = num;
852
853 /*
854 * if the default bit is set in the cis, then
855 * point the new default at whatever is being
856 * filled in
857 */
858 if (def)
859 state->default_cfe = cfe;
860 } else {
861 /*
862 * the cis index matches the default index,
863 * fill in the default cfentry. It is
864 * assumed that the cfdefault index is in the
865 * queue. For it to be otherwise, the cis
866 * index would have to be -1 (initial
867 * condition) which is not possible, or there
868 * would have to be a preceding cis entry
869 * which had the same cis index and had the
870 * default bit unset. Neither condition
871 * should happen. If it does, this cfentry
872 * is lost (written into temp space), which
873 * is an acceptable failure mode.
874 */
875
876 cfe = state->default_cfe;
877
878 /*
879 * if the cis entry does not have the default
880 * bit set, copy the default out of the way
881 * first.
882 */
883 if (!def) {
884 state->temp_cfe = *state->default_cfe;
885 state->default_cfe = &state->temp_cfe;
886 }
887 }
888
889 if (intface) {
890 reg = pccard_tuple_read_1(tuple, idx);
891 idx++;
892 if (reg & PCCARD_TPCE_IF_MWAIT)
893 cfe->flags |= PCCARD_CFE_MWAIT_REQUIRED;
894 if (reg & PCCARD_TPCE_IF_RDYBSY)
895 cfe->flags |= PCCARD_CFE_RDYBSY_ACTIVE;
896 if (reg & PCCARD_TPCE_IF_WP)
897 cfe->flags |= PCCARD_CFE_WP_ACTIVE;
898 if (reg & PCCARD_TPCE_IF_BVD)
899 cfe->flags |= PCCARD_CFE_BVD_ACTIVE;
900 cfe->iftype = reg & PCCARD_TPCE_IF_IFTYPE;
901 }
902 reg = pccard_tuple_read_1(tuple, idx);
903 idx++;
904
905 power = reg & PCCARD_TPCE_FS_POWER_MASK;
906 timing = reg & PCCARD_TPCE_FS_TIMING;
907 iospace = reg & PCCARD_TPCE_FS_IOSPACE;
908 irq = reg & PCCARD_TPCE_FS_IRQ;
909 memspace = reg & PCCARD_TPCE_FS_MEMSPACE_MASK;
910 misc = reg & PCCARD_TPCE_FS_MISC;
911
912 if (power) {
913 /* skip over power, don't save */
914 /* for each parameter selection byte */
915 for (i = 0; i < power; i++) {
916 reg = pccard_tuple_read_1(tuple, idx);
917 idx++;
918 /* for each bit */
919 for (j = 0; j < 7; j++) {
920 /* if the bit is set */
921 if ((reg >> j) & 0x01) {
922 /* skip over bytes */
923 do {
924 reg2 = pccard_tuple_read_1(tuple, idx);
925 idx++;
926 /*
927 * until
928 * non-extensi
929 * on byte
930 */
931 } while (reg2 & 0x80);
932 }
933 }
934 }
935 }
936 if (timing) {
937 /* skip over timing, don't save */
938 reg = pccard_tuple_read_1(tuple, idx);
939 idx++;
940
941 if ((reg & PCCARD_TPCE_TD_RESERVED_MASK) !=
942 PCCARD_TPCE_TD_RESERVED_MASK)
943 idx++;
944 if ((reg & PCCARD_TPCE_TD_RDYBSY_MASK) !=
945 PCCARD_TPCE_TD_RDYBSY_MASK)
946 idx++;
947 if ((reg & PCCARD_TPCE_TD_WAIT_MASK) !=
948 PCCARD_TPCE_TD_WAIT_MASK)
949 idx++;
950 }
951 if (iospace) {
952 if (tuple->length <= idx) {
953 DPRINTF(("ran out of space before TCPE_IO\n"));
954 goto abort_cfe;
955 }
956
957 reg = pccard_tuple_read_1(tuple, idx);
958 idx++;
959
960 if (reg & PCCARD_TPCE_IO_BUSWIDTH_8BIT)
961 cfe->flags |= PCCARD_CFE_IO8;
962 if (reg & PCCARD_TPCE_IO_BUSWIDTH_16BIT)
963 cfe->flags |= PCCARD_CFE_IO16;
964 cfe->iomask =
965 reg & PCCARD_TPCE_IO_IOADDRLINES_MASK;
966
967 if (reg & PCCARD_TPCE_IO_HASRANGE) {
968 reg = pccard_tuple_read_1(tuple, idx);
969 idx++;
970
971 cfe->num_iospace = 1 + (reg &
972 PCCARD_TPCE_IO_RANGE_COUNT);
973
974 if (cfe->num_iospace >
975 (sizeof(cfe->iospace) /
976 sizeof(cfe->iospace[0]))) {
977 DPRINTF(("too many io "
978 "spaces %d",
979 cfe->num_iospace));
980 state->card->error++;
981 break;
982 }
983 for (i = 0; i < cfe->num_iospace; i++) {
984 switch (reg & PCCARD_TPCE_IO_RANGE_ADDRSIZE_MASK) {
985 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_ONE:
986 cfe->iospace[i].start =
987 pccard_tuple_read_1(tuple, idx);
988 idx++;
989 break;
990 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_TWO:
991 cfe->iospace[i].start =
992 pccard_tuple_read_2(tuple, idx);
993 idx += 2;
994 break;
995 case PCCARD_TPCE_IO_RANGE_ADDRSIZE_FOUR:
996 cfe->iospace[i].start =
997 pccard_tuple_read_4(tuple, idx);
998 idx += 4;
999 break;
1000 }
1001 switch (reg &
1002 PCCARD_TPCE_IO_RANGE_LENGTHSIZE_MASK) {
1003 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_ONE:
1004 cfe->iospace[i].length =
1005 pccard_tuple_read_1(tuple, idx);
1006 idx++;
1007 break;
1008 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_TWO:
1009 cfe->iospace[i].length =
1010 pccard_tuple_read_2(tuple, idx);
1011 idx += 2;
1012 break;
1013 case PCCARD_TPCE_IO_RANGE_LENGTHSIZE_FOUR:
1014 cfe->iospace[i].length =
1015 pccard_tuple_read_4(tuple, idx);
1016 idx += 4;
1017 break;
1018 }
1019 cfe->iospace[i].length++;
1020 }
1021 } else {
1022 cfe->num_iospace = 1;
1023 cfe->iospace[0].start = 0;
1024 cfe->iospace[0].length =
1025 (1 << cfe->iomask);
1026 }
1027 }
1028 if (irq) {
1029 if (tuple->length <= idx) {
1030 DPRINTF(("ran out of space before TCPE_IR\n"));
1031 goto abort_cfe;
1032 }
1033
1034 reg = pccard_tuple_read_1(tuple, idx);
1035 idx++;
1036
1037 if (reg & PCCARD_TPCE_IR_SHARE)
1038 cfe->flags |= PCCARD_CFE_IRQSHARE;
1039 if (reg & PCCARD_TPCE_IR_PULSE)
1040 cfe->flags |= PCCARD_CFE_IRQPULSE;
1041 if (reg & PCCARD_TPCE_IR_LEVEL)
1042 cfe->flags |= PCCARD_CFE_IRQLEVEL;
1043
1044 if (reg & PCCARD_TPCE_IR_HASMASK) {
1045 /*
1046 * it's legal to ignore the
1047 * special-interrupt bits, so I will
1048 */
1049
1050 cfe->irqmask =
1051 pccard_tuple_read_2(tuple, idx);
1052 idx += 2;
1053 } else {
1054 cfe->irqmask =
1055 (1 << (reg & PCCARD_TPCE_IR_IRQ));
1056 }
1057 }
1058 if (memspace) {
1059 if (tuple->length <= idx) {
1060 DPRINTF(("ran out of space before TCPE_MS\n"));
1061 goto abort_cfe;
1062 }
1063
1064 if (memspace == PCCARD_TPCE_FS_MEMSPACE_NONE) {
1065 cfe->num_memspace = 0;
1066 } else if (memspace == PCCARD_TPCE_FS_MEMSPACE_LENGTH) {
1067 cfe->num_memspace = 1;
1068 cfe->memspace[0].length = 256 *
1069 pccard_tuple_read_2(tuple, idx);
1070 idx += 2;
1071 cfe->memspace[0].cardaddr = 0;
1072 cfe->memspace[0].hostaddr = 0;
1073 } else if (memspace ==
1074 PCCARD_TPCE_FS_MEMSPACE_LENGTHADDR) {
1075 cfe->num_memspace = 1;
1076 cfe->memspace[0].length = 256 *
1077 pccard_tuple_read_2(tuple, idx);
1078 idx += 2;
1079 cfe->memspace[0].cardaddr = 256 *
1080 pccard_tuple_read_2(tuple, idx);
1081 idx += 2;
1082 cfe->memspace[0].hostaddr = cfe->memspace[0].cardaddr;
1083 } else {
1084 int lengthsize;
1085 int cardaddrsize;
1086 int hostaddrsize;
1087
1088 reg = pccard_tuple_read_1(tuple, idx);
1089 idx++;
1090
1091 cfe->num_memspace = (reg &
1092 PCCARD_TPCE_MS_COUNT) + 1;
1093
1094 if (cfe->num_memspace >
1095 (sizeof(cfe->memspace) /
1096 sizeof(cfe->memspace[0]))) {
1097 DPRINTF(("too many mem "
1098 "spaces %d",
1099 cfe->num_memspace));
1100 state->card->error++;
1101 break;
1102 }
1103 lengthsize =
1104 ((reg & PCCARD_TPCE_MS_LENGTH_SIZE_MASK) >>
1105 PCCARD_TPCE_MS_LENGTH_SIZE_SHIFT);
1106 cardaddrsize =
1107 ((reg & PCCARD_TPCE_MS_CARDADDR_SIZE_MASK) >>
1108 PCCARD_TPCE_MS_CARDADDR_SIZE_SHIFT);
1109 hostaddrsize =
1110 (reg & PCCARD_TPCE_MS_HOSTADDR) ? cardaddrsize : 0;
1111
1112 if (lengthsize == 0) {
1113 DPRINTF(("cfe memspace "
1114 "lengthsize == 0"));
1115 state->card->error++;
1116 }
1117 for (i = 0; i < cfe->num_memspace; i++) {
1118 if (lengthsize) {
1119 cfe->memspace[i].length =
1120 256 * pccard_tuple_read_n(tuple, lengthsize,
1121 idx);
1122 idx += lengthsize;
1123 } else {
1124 cfe->memspace[i].length = 0;
1125 }
1126 if (cfe->memspace[i].length == 0) {
1127 DPRINTF(("cfe->memspace[%d].length == 0",
1128 i));
1129 state->card->error++;
1130 }
1131 if (cardaddrsize) {
1132 cfe->memspace[i].cardaddr =
1133 256 * pccard_tuple_read_n(tuple, cardaddrsize,
1134 idx);
1135 idx += cardaddrsize;
1136 } else {
1137 cfe->memspace[i].cardaddr = 0;
1138 }
1139 if (hostaddrsize) {
1140 cfe->memspace[i].hostaddr =
1141 256 * pccard_tuple_read_n(tuple, hostaddrsize,
1142 idx);
1143 idx += hostaddrsize;
1144 } else {
1145 cfe->memspace[i].hostaddr = 0;
1146 }
1147 }
1148 }
1149 }
1150 if (misc) {
1151 if (tuple->length <= idx) {
1152 DPRINTF(("ran out of space before TCPE_MI\n"));
1153 goto abort_cfe;
1154 }
1155
1156 reg = pccard_tuple_read_1(tuple, idx);
1157 idx++;
1158
1159 if (reg & PCCARD_TPCE_MI_PWRDOWN)
1160 cfe->flags = PCCARD_CFE_POWERDOWN;
1161 if (reg & PCCARD_TPCE_MI_READONLY)
1162 cfe->flags = PCCARD_CFE_READONLY;
1163 if (reg & PCCARD_TPCE_MI_AUDIO)
1164 cfe->flags = PCCARD_CFE_AUDIO;
1165 cfe->maxtwins = reg & PCCARD_TPCE_MI_MAXTWINS;
1166
1167 while (reg & PCCARD_TPCE_MI_EXT) {
1168 reg = pccard_tuple_read_1(tuple, idx);
1169 idx++;
1170 }
1171 }
1172 /* skip all the subtuples */
1173 }
1174
1175 abort_cfe:
1176 DPRINTF(("CISTPL_CFTABLE_ENTRY\n"));
1177 break;
1178 default:
1179 DPRINTF(("unhandled CISTPL %x\n", tuple->code));
1180 break;
1181 }
1182
1183 return (0);
1184}
1185
1186static int
1187decode_funce(struct pccard_tuple *tuple, struct pccard_function *pf)
1188{
1189 int type = pccard_tuple_read_1(tuple, 0);
1190
1191 switch (pf->function) {
1192 case PCCARD_FUNCTION_DISK:
1193 if (type == PCCARD_TPLFE_TYPE_DISK_DEVICE_INTERFACE) {
1194 pf->pf_funce_disk_interface
1195 = pccard_tuple_read_1(tuple, 1);
1196 }
1197 break;
1198 case PCCARD_FUNCTION_NETWORK:
1199 if (type == PCCARD_TPLFE_TYPE_LAN_NID) {
1200 int i;
1201 int len = pccard_tuple_read_1(tuple, 1);
1202 if (tuple->length < 2 + len || len > 8) {
1203 /* tuple length not enough or nid too long */
1204 break;
1205 }
1206 for (i = 0; i < len; i++) {
1207 pf->pf_funce_lan_nid[i]
1208 = pccard_tuple_read_1(tuple, i + 2);
1209 }
1210 pf->pf_funce_lan_nidlen = len;
1211 }
1212 break;
1213 default:
1214 break;
1215 }
1216 return 0;
1217}