pccbb.c revision 1.21 1 /* $NetBSD: pccbb.c,v 1.21 2000/01/26 09:02:41 haya Exp $ */
2
3 /*
4 * Copyright (c) 1998, 1999 and 2000
5 * HAYAKAWA Koichi. 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 HAYAKAWA Koichi.
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 /*
34 #define CBB_DEBUG
35 #define SHOW_REGS
36 #define PCCBB_PCMCIA_POLL
37 */
38 /* #define CBB_DEBUG */
39
40 /*
41 #define CB_PCMCIA_POLL
42 #define CB_PCMCIA_POLL_ONLY
43 #define LEVEL2
44 */
45
46 #include <sys/types.h>
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/kernel.h>
50 #include <sys/errno.h>
51 #include <sys/ioctl.h>
52 #include <sys/syslog.h>
53 #include <sys/device.h>
54 #include <sys/malloc.h>
55
56 #include <machine/intr.h>
57 #include <machine/bus.h>
58
59 #include <dev/pci/pcivar.h>
60 #include <dev/pci/pcireg.h>
61 #include <dev/pci/pcidevs.h>
62
63 #include <dev/pci/pccbbreg.h>
64
65 #include <dev/cardbus/cardslotvar.h>
66
67 #include <dev/cardbus/cardbusvar.h>
68
69 #include <dev/pcmcia/pcmciareg.h>
70 #include <dev/pcmcia/pcmciavar.h>
71
72 #include <dev/ic/i82365reg.h>
73 #include <dev/ic/i82365var.h>
74 #include <dev/pci/pccbbvar.h>
75
76 #include "locators.h"
77
78
79 #ifndef __NetBSD_Version__
80 struct cfdriver cbb_cd = {
81 NULL, "cbb", DV_DULL
82 };
83 #endif
84
85 #if defined CBB_DEBUG
86 #define DPRINTF(x) printf x
87 #define STATIC
88 #else
89 #define DPRINTF(x)
90 #define STATIC static
91 #endif
92
93
94 #ifdef __BROKEN_INDIRECT_CONFIG
95 int pcicbbmatch __P((struct device *, void *, void *));
96 #else
97 int pcicbbmatch __P((struct device *, struct cfdata *, void *));
98 #endif
99 void pccbbattach __P((struct device *, struct device *, void *));
100 int pccbbintr __P((void *));
101 static void pci113x_insert __P((void *));
102 static int pccbbintr_function __P((struct pccbb_softc *));
103
104 static int pccbb_detect_card __P((struct pccbb_softc *));
105
106 static void pccbb_pcmcia_write __P((struct pcic_handle *, int, u_int8_t));
107 static u_int8_t pccbb_pcmcia_read __P((struct pcic_handle *, int));
108 #define Pcic_read(ph, reg) ((ph)->ph_read((ph), (reg)))
109 #define Pcic_write(ph, reg, val) ((ph)->ph_write((ph), (reg), (val)))
110
111
112 STATIC int cb_reset __P((struct pccbb_softc *));
113 STATIC int cb_detect_voltage __P((struct pccbb_softc *));
114 STATIC int cbbprint __P((void *, const char *));
115
116 static int cb_chipset __P((u_int32_t, int *));
117 STATIC void pccbb_pcmcia_attach_setup __P((struct pccbb_softc *, struct pcmciabus_attach_args *));
118 #if 0
119 STATIC void pccbb_pcmcia_attach_card __P((struct pcic_handle *));
120 STATIC void pccbb_pcmcia_detach_card __P((struct pcic_handle *, int));
121 STATIC void pccbb_pcmcia_deactivate_card __P((struct pcic_handle *));
122 #endif
123
124 STATIC int pccbb_ctrl __P((cardbus_chipset_tag_t, int));
125 STATIC int pccbb_power __P((cardbus_chipset_tag_t, int));
126 STATIC int pccbb_cardenable __P((struct pccbb_softc *sc, int function));
127 #if !rbus
128 static int pccbb_io_open __P((cardbus_chipset_tag_t, int, u_int32_t, u_int32_t));
129 static int pccbb_io_close __P((cardbus_chipset_tag_t, int));
130 static int pccbb_mem_open __P((cardbus_chipset_tag_t, int, u_int32_t, u_int32_t));
131 static int pccbb_mem_close __P((cardbus_chipset_tag_t, int));
132 #endif /* !rbus */
133 static void *pccbb_intr_establish __P((cardbus_chipset_tag_t, int irq, int level, int (* ih)(void *), void *sc));
134 static void pccbb_intr_disestablish __P((cardbus_chipset_tag_t ct, void *ih));
135
136 static cardbustag_t pccbb_make_tag __P((cardbus_chipset_tag_t, int, int, int));
137 static void pccbb_free_tag __P((cardbus_chipset_tag_t, cardbustag_t));
138 static cardbusreg_t pccbb_conf_read __P((cardbus_chipset_tag_t, cardbustag_t, int));
139 static void pccbb_conf_write __P((cardbus_chipset_tag_t, cardbustag_t, int, cardbusreg_t));
140 static void pccbb_chipinit __P((struct pccbb_softc *));
141
142
143 STATIC int pccbb_pcmcia_mem_alloc __P((pcmcia_chipset_handle_t, bus_size_t,
144 struct pcmcia_mem_handle *));
145 STATIC void pccbb_pcmcia_mem_free __P((pcmcia_chipset_handle_t,
146 struct pcmcia_mem_handle *));
147 STATIC int pccbb_pcmcia_mem_map __P((pcmcia_chipset_handle_t, int, bus_addr_t,
148 bus_size_t, struct pcmcia_mem_handle *, bus_addr_t *, int *));
149 STATIC void pccbb_pcmcia_mem_unmap __P((pcmcia_chipset_handle_t, int));
150 STATIC int pccbb_pcmcia_io_alloc __P((pcmcia_chipset_handle_t, bus_addr_t,
151 bus_size_t, bus_size_t, struct pcmcia_io_handle *));
152 STATIC void pccbb_pcmcia_io_free __P((pcmcia_chipset_handle_t,
153 struct pcmcia_io_handle *));
154 STATIC int pccbb_pcmcia_io_map __P((pcmcia_chipset_handle_t, int, bus_addr_t,
155 bus_size_t, struct pcmcia_io_handle *, int *));
156 STATIC void pccbb_pcmcia_io_unmap __P((pcmcia_chipset_handle_t, int));
157 STATIC void *pccbb_pcmcia_intr_establish __P((pcmcia_chipset_handle_t,
158 struct pcmcia_function *, int, int (*) (void *), void *));
159 STATIC void pccbb_pcmcia_intr_disestablish __P((pcmcia_chipset_handle_t, void *));
160 STATIC void pccbb_pcmcia_socket_enable __P((pcmcia_chipset_handle_t));
161 STATIC void pccbb_pcmcia_socket_disable __P((pcmcia_chipset_handle_t));
162 STATIC int pccbb_pcmcia_card_detect __P((pcmcia_chipset_handle_t pch));
163
164 static void pccbb_pcmcia_do_io_map __P((struct pcic_handle *, int));
165 static void pccbb_pcmcia_wait_ready __P((struct pcic_handle *));
166 static void pccbb_pcmcia_do_mem_map __P((struct pcic_handle *, int));
167
168 /* bus-space allocation and disallocation functions */
169 #if rbus
170
171 static int pccbb_rbus_cb_space_alloc __P((cardbus_chipset_tag_t, rbus_tag_t,
172 bus_addr_t addr, bus_size_t size,
173 bus_addr_t mask, bus_size_t align,
174 int flags, bus_addr_t *addrp,
175 bus_space_handle_t *bshp));
176 static int pccbb_rbus_cb_space_free __P((cardbus_chipset_tag_t, rbus_tag_t,
177 bus_space_handle_t, bus_size_t));
178
179 #endif /* rbus */
180
181 #if rbus
182
183 static int pccbb_open_win __P((struct pccbb_softc *, bus_space_tag_t, bus_addr_t, bus_size_t, bus_space_handle_t, int flags));
184 static int pccbb_close_win __P((struct pccbb_softc *, bus_space_tag_t, bus_space_handle_t, bus_size_t));
185 static int pccbb_winlist_insert __P((struct pccbb_win_chain **, bus_addr_t,
186 bus_size_t, bus_space_handle_t, int));
187 static int pccbb_winlist_delete __P((struct pccbb_win_chain **,
188 bus_space_handle_t, bus_size_t));
189 static void pccbb_winset __P((bus_addr_t align, struct pccbb_softc *,
190 bus_space_tag_t));
191 void pccbb_winlist_show(struct pccbb_win_chain *);
192
193 #endif /* rbus */
194
195 /* for config_defer */
196 static void pccbb_pci_callback __P((struct device *));
197
198
199 #if defined SHOW_REGS
200 static void cb_show_regs __P((pci_chipset_tag_t pc, pcitag_t tag, bus_space_tag_t memt, bus_space_handle_t memh));
201 #endif
202
203
204
205 struct cfattach cbb_pci_ca = {
206 sizeof(struct pccbb_softc), pcicbbmatch, pccbbattach
207 };
208
209
210 static struct pcmcia_chip_functions pccbb_pcmcia_funcs = {
211 pccbb_pcmcia_mem_alloc,
212 pccbb_pcmcia_mem_free,
213 pccbb_pcmcia_mem_map,
214 pccbb_pcmcia_mem_unmap,
215 pccbb_pcmcia_io_alloc,
216 pccbb_pcmcia_io_free,
217 pccbb_pcmcia_io_map,
218 pccbb_pcmcia_io_unmap,
219 pccbb_pcmcia_intr_establish,
220 pccbb_pcmcia_intr_disestablish,
221 pccbb_pcmcia_socket_enable,
222 pccbb_pcmcia_socket_disable,
223 pccbb_pcmcia_card_detect
224 };
225
226 #if rbus
227 static struct cardbus_functions pccbb_funcs = {
228 pccbb_rbus_cb_space_alloc,
229 pccbb_rbus_cb_space_free,
230 pccbb_intr_establish,
231 pccbb_intr_disestablish,
232 pccbb_ctrl,
233 pccbb_power,
234 pccbb_make_tag,
235 pccbb_free_tag,
236 pccbb_conf_read,
237 pccbb_conf_write,
238 };
239 #else
240 static struct cardbus_functions pccbb_funcs = {
241 pccbb_ctrl,
242 pccbb_power,
243 pccbb_mem_open,
244 pccbb_mem_close,
245 pccbb_io_open,
246 pccbb_io_close,
247 pccbb_intr_establish,
248 pccbb_intr_disestablish,
249 pccbb_make_tag,
250 pccbb_conf_read,
251 pccbb_conf_write,
252 };
253 #endif
254
255
256
257
258 int
259 pcicbbmatch(parent, match, aux)
260 struct device *parent;
261 #ifdef __BROKEN_INDIRECT_CONFIG
262 void *match;
263 #else
264 struct cfdata *match;
265 #endif
266 void *aux;
267 {
268 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
269
270 if(PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
271 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_CARDBUS &&
272 PCI_INTERFACE(pa->pa_class) == 0) {
273 return 1;
274 }
275
276 return 0;
277 }
278
279
280 #define MAKEID(vendor, prod) (((vendor) << PCI_VENDOR_SHIFT) \
281 | ((prod) << PCI_PRODUCT_SHIFT))
282
283
284 struct yenta_chipinfo {
285 pcireg_t yc_id; /* vendor tag | product tag */
286 int yc_chiptype;
287 int yc_flags;
288 } yc_chipsets[] = {
289 /* Texas Instruments chips */
290 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1130), CB_TI113X,
291 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
292 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1131), CB_TI113X,
293 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
294
295 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1250), CB_TI12XX,
296 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
297 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1220), CB_TI12XX,
298 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
299 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1221), CB_TI12XX,
300 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
301 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1225), CB_TI12XX,
302 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
303 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1251), CB_TI12XX,
304 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
305 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1251B), CB_TI12XX,
306 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
307 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1211), CB_TI12XX,
308 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
309 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1420), CB_TI12XX,
310 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
311 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1450), CB_TI12XX,
312 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
313 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1451), CB_TI12XX,
314 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
315
316 /* Ricoh chips */
317 {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C475), CB_RX5C47X,
318 PCCBB_PCMCIA_MEM_32},
319 {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RL5C476), CB_RX5C47X,
320 PCCBB_PCMCIA_MEM_32},
321 {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C477), CB_RX5C47X,
322 PCCBB_PCMCIA_MEM_32},
323 {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C478), CB_RX5C47X,
324 PCCBB_PCMCIA_MEM_32},
325
326 {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C465), CB_RX5C46X,
327 PCCBB_PCMCIA_MEM_32},
328 {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C466), CB_RX5C46X,
329 PCCBB_PCMCIA_MEM_32},
330
331 /* Toshiba products */
332 {MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC95), CB_TOPIC95,
333 PCCBB_PCMCIA_MEM_32},
334 {MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC95B), CB_TOPIC95B,
335 PCCBB_PCMCIA_MEM_32},
336 {MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC97), CB_TOPIC97,
337 PCCBB_PCMCIA_MEM_32},
338 {MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC100), CB_TOPIC97,
339 PCCBB_PCMCIA_MEM_32},
340
341 /* Cirrus Logic products */
342 {MAKEID(PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CL_PD6832), CB_CIRRUS,
343 PCCBB_PCMCIA_MEM_32},
344 {MAKEID(PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CL_PD6833), CB_CIRRUS,
345 PCCBB_PCMCIA_MEM_32},
346
347 /* sentinel, or Generic chip */
348 {0 /* null id */, CB_UNKNOWN, PCCBB_PCMCIA_MEM_32},
349 };
350
351
352
353 static int
354 cb_chipset(pci_id, flagp)
355 u_int32_t pci_id;
356 int *flagp;
357 {
358 int loopend = sizeof(yc_chipsets)/sizeof(yc_chipsets[0]);
359 struct yenta_chipinfo *ycp, *ycend;
360
361 ycend = yc_chipsets + loopend;
362
363 for (ycp =yc_chipsets; ycp < ycend && pci_id != ycp->yc_id; ++ycp);
364
365 if (ycp == ycend) {
366 /* not found */
367 ycp = yc_chipsets + loopend - 1; /* to point the sentinel */
368 }
369
370 if (flagp != NULL) {
371 *flagp = ycp->yc_flags;
372 }
373
374 return ycp->yc_chiptype;
375 }
376
377
378
379 static void
380 pccbb_shutdown(void *arg)
381 {
382 struct pccbb_softc *sc = arg;
383 pcireg_t command;
384
385 DPRINTF(("%s: shutdown\n", sc->sc_dev.dv_xname));
386 bus_space_write_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_MASK, 0);
387
388 command = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG);
389
390 command &= ~(PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
391 PCI_COMMAND_MASTER_ENABLE);
392 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, command);
393
394 }
395
396 void
397 pccbbattach(parent, self, aux)
398 struct device *parent;
399 struct device *self;
400 void *aux;
401 {
402 struct pccbb_softc *sc = (void *)self;
403 struct pci_attach_args *pa = aux;
404 pci_chipset_tag_t pc = pa->pa_pc;
405 pcireg_t sock_base, busreg;
406 bus_addr_t sockbase;
407 char devinfo[256];
408 int flags;
409
410 sc->sc_chipset = cb_chipset(pa->pa_id, &flags);
411
412 pci_devinfo(pa->pa_id, 0, 0, devinfo);
413 printf(": %s (rev. 0x%02x)", devinfo, PCI_REVISION(pa->pa_class));
414 #ifdef CBB_DEBUG
415 printf(" (chipflags %x)", flags);
416 #endif
417 printf("\n");
418
419 #if rbus
420 sc->sc_rbus_iot = rbus_pccbb_parent_io(pa);
421 sc->sc_rbus_memt = rbus_pccbb_parent_mem(pa);
422 #endif /* rbus */
423
424 sc->sc_base_memh = 0;
425
426 /*
427 * MAP socket registers and ExCA registers on memory-space
428 * When no valid address is set on socket base registers (on pci
429 * config space), get it not polite way.
430 */
431 sock_base = pci_conf_read(pc, pa->pa_tag, PCI_SOCKBASE);
432
433 if (PCI_MAPREG_MEM_ADDR(sock_base) >= 0x100000 &&
434 PCI_MAPREG_MEM_ADDR(sock_base) != 0xfffffff0) {
435 /* The address must be valid. */
436 if (pci_mapreg_map(pa, PCI_SOCKBASE, PCI_MAPREG_TYPE_MEM, 0,
437 &sc->sc_base_memt, &sc->sc_base_memh, &sockbase,
438 NULL)) {
439 printf("%s: can't map socket base address 0x%x\n", sc->sc_dev.dv_xname,
440 sock_base);
441 /* I think it's funny: socket base registers must be mapped on
442 memory space, but ... */
443 if (pci_mapreg_map(pa, PCI_SOCKBASE, PCI_MAPREG_TYPE_IO, 0,
444 &sc->sc_base_memt, &sc->sc_base_memh,
445 &sockbase, NULL)) {
446 printf("%s: can't map socket base address 0x%lx: io mode\n",
447 sc->sc_dev.dv_xname, sockbase);
448 /* give up... allocate register space via rbus. */
449 sc->sc_base_memh = 0;
450 pci_conf_write(pc, pa->pa_tag, PCI_SOCKBASE, 0);
451 }
452 } else {
453 DPRINTF(("%s: socket base address 0x%lx\n",
454 sc->sc_dev.dv_xname, sockbase));
455 }
456 }
457
458
459 sc->sc_mem_start = 0; /* XXX */
460 sc->sc_mem_end = 0xffffffff; /* XXX */
461
462 /*
463 * When interrupt isn't routed correctly, give up probing cbb and do
464 * not kill pcic-compatible port.
465 */
466 if ((0 == pa->pa_intrline) || (255 == pa->pa_intrline)) {
467 printf(" Do not use %s because of intr unconfig.\n", sc->sc_dev.dv_xname);
468 return;
469 }
470
471 /*
472 * When bus number isn't set correctly, give up using 32-bit CardBus
473 * mode.
474 */
475 busreg = pci_conf_read(pc, pa->pa_tag, PCI_BUSNUM);
476 #if notyet
477 if (((busreg >> 8) & 0xff) == 0) {
478 printf(" CardBus on %s will not be configured, because of bus no unconfig.\n", sc->sc_dev.dv_xname);
479 flags |= PCCBB_PCMCIA_16BITONLY;
480 }
481 #endif
482
483 /* pccbb_machdep.c end */
484
485
486 #if defined CBB_DEBUG
487 {
488 static char *intrname[5] = {"NON", "A", "B", "C", "D"};
489 printf(" intrpin %s, intrtag %d\n", intrname[pa->pa_intrpin],
490 pa->pa_intrline);
491 }
492 #endif
493
494
495 /* setup softc */
496 sc->sc_pc = pc;
497 sc->sc_iot = pa->pa_iot;
498 sc->sc_memt = pa->pa_memt;
499 sc->sc_dmat = pa->pa_dmat;
500 sc->sc_tag = pa->pa_tag;
501 sc->sc_function = pa->pa_function;
502
503 sc->sc_intrline = pa->pa_intrline;
504 sc->sc_intrtag = pa->pa_intrtag;
505 sc->sc_intrpin = pa->pa_intrpin;
506
507 sc->sc_pcmcia_flags = flags; /* set PCMCIA facility */
508
509 shutdownhook_establish(pccbb_shutdown, sc);
510
511 #if __NetBSD_Version__ > 103060000
512 config_defer(self, pccbb_pci_callback);
513 #else
514 pccbb_pci_callback(self);
515 #endif
516 }
517
518
519
520
521 static void
522 pccbb_pci_callback(self)
523 struct device *self;
524 {
525 struct pccbb_softc *sc = (void *)self;
526 pci_chipset_tag_t pc = sc->sc_pc;
527 bus_space_tag_t base_memt;
528 bus_space_handle_t base_memh;
529 u_int32_t maskreg;
530 pci_intr_handle_t ih;
531 const char *intrstr = NULL;
532 bus_addr_t sockbase;
533 struct cbslot_attach_args cba;
534 struct pcmciabus_attach_args paa;
535 struct cardslot_attach_args caa;
536 struct cardslot_softc *csc;
537
538 if (0 == sc->sc_base_memh) {
539 /* The socket registers aren't mapped correctly. */
540 #if rbus
541 if (rbus_space_alloc(sc->sc_rbus_memt,
542 0, /* address: I don't mind where it is mapped */
543 0x1000, /* size */
544 0x0fff, /* mask */
545 (sc->sc_chipset == CB_RX5C47X || sc->sc_chipset == CB_TI113X) ? 0x10000 : 0x1000, /* align */
546 0, /* flags */
547 &sockbase, &sc->sc_base_memh)) {
548 return;
549 }
550 sc->sc_base_memt = sc->sc_memt;
551 pci_conf_write(pc, sc->sc_tag, PCI_SOCKBASE, sockbase);
552 DPRINTF(("%s: CardBus resister address 0x%lx -> 0x%x\n",
553 sc->sc_dev.dv_xname, sockbase, pci_conf_read(pc, sc->sc_tag, PCI_SOCKBASE)));
554 #else
555 sc->sc_base_memt = sc->sc_memt;
556 #if !defined CBB_PCI_BASE
557 #define CBB_PCI_BASE 0x20000000
558 #endif
559 if (bus_space_alloc(sc->sc_base_memt, CBB_PCI_BASE, 0xffffffff,
560 0x1000, /* size */
561 0x1000, /* alignment */
562 0, /* boundary */
563 0, /* flags */
564 &sockbase, &sc->sc_base_memh)) {
565 /* cannot allocate memory space */
566 return;
567 }
568 pci_conf_write(pc, sc->sc_tag, PCI_SOCKBASE, sockbase);
569 DPRINTF(("%s: CardBus resister address 0x%x -> 0x%x\n",sc->sc_dev.dv_xname,
570 sock_base, pci_conf_read(pc, sc->sc_tag, PCI_SOCKBASE)));
571 #endif
572 }
573
574 /* bus bridge initialisation */
575 pccbb_chipinit(sc);
576
577 base_memt = sc->sc_base_memt; /* socket regs memory tag */
578 base_memh = sc->sc_base_memh; /* socket regs memory handle */
579
580
581 /* CSC Interrupt: Card detect interrupt on */
582 maskreg = bus_space_read_4(base_memt, base_memh, CB_SOCKET_MASK);
583 maskreg |= CB_SOCKET_MASK_CD; /* Card detect intr is turned on. */
584 bus_space_write_4(base_memt, base_memh, CB_SOCKET_MASK, maskreg);
585 /* reset interrupt */
586 bus_space_write_4(base_memt, base_memh, CB_SOCKET_EVENT,
587 bus_space_read_4(base_memt, base_memh, CB_SOCKET_EVENT));
588
589
590 /* Map and establish the interrupt. */
591 if (pci_intr_map(pc, sc->sc_intrtag, sc->sc_intrpin,
592 sc->sc_intrline, &ih)) {
593 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
594 return;
595 }
596 intrstr = pci_intr_string(pc, ih);
597 sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, pccbbintr, sc);
598
599 if (sc->sc_ih == NULL) {
600 printf("%s: couldn't establish interrupt", sc->sc_dev.dv_xname);
601 if (intrstr != NULL) {
602 printf(" at %s", intrstr);
603 }
604 printf("\n");
605 return;
606 }
607
608 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
609
610 {
611 u_int32_t sockstat = bus_space_read_4(base_memt,base_memh, CB_SOCKET_STAT);
612 if (0 == (sockstat & CB_SOCKET_STAT_CD)) { /* card exist */
613 sc->sc_flags |= CBB_CARDEXIST;
614 }
615 }
616
617 /*
618 * attach cardbus
619 */
620 if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_16BITONLY)) {
621 pcireg_t busreg = pci_conf_read(pc, sc->sc_tag, PCI_BUSNUM);
622 pcireg_t bhlc = pci_conf_read(pc, sc->sc_tag, PCI_BHLC_REG);
623
624 /* initialise cbslot_attach */
625 cba.cba_busname = "cardbus";
626 cba.cba_iot = sc->sc_iot;
627 cba.cba_memt = sc->sc_memt;
628 cba.cba_dmat = sc->sc_dmat;
629 cba.cba_function = 0;
630 cba.cba_bus = (busreg >> 8) & 0x0ff;
631 cba.cba_cc = (void *)sc;
632 cba.cba_cf = &pccbb_funcs;
633 cba.cba_intrline = sc->sc_intrline;
634
635 #if rbus
636 cba.cba_rbus_iot = sc->sc_rbus_iot;
637 cba.cba_rbus_memt = sc->sc_rbus_memt;
638 #endif
639
640 cba.cba_cacheline = PCI_CACHELINE(bhlc);
641 cba.cba_lattimer = PCI_CB_LATENCY(busreg);
642
643 printf("%s: cacheline 0x%x lattimer 0x%x\n", sc->sc_dev.dv_xname,
644 cba.cba_cacheline, cba.cba_lattimer);
645 printf("%s: bhlc 0x%x lscp 0x%x\n", sc->sc_dev.dv_xname,
646 bhlc, busreg);
647 #if defined SHOW_REGS
648 cb_show_regs(sc->sc_pc, sc->sc_tag, sc->sc_base_memt, sc->sc_base_memh);
649 #endif
650 }
651
652 pccbb_pcmcia_attach_setup(sc, &paa);
653 caa.caa_cb_attach = NULL;
654 if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_16BITONLY)) {
655 caa.caa_cb_attach = &cba;
656 }
657 caa.caa_16_attach = &paa;
658 caa.caa_ph = &sc->sc_pcmcia_h;
659
660 if (NULL != (csc = (void *)config_found(self, &caa, cbbprint))) {
661 DPRINTF(("pccbbattach: found cardslot\n"));
662 sc->sc_csc = csc;
663 }
664
665 return;
666 }
667
668
669
670 static void
671 pccbb_chipinit(sc)
672 struct pccbb_softc *sc;
673 {
674 pci_chipset_tag_t pc = sc->sc_pc;
675 pcitag_t tag = sc->sc_tag;
676 bus_space_tag_t base_memt = sc->sc_base_memt; /* socket regs memory tag */
677 bus_space_handle_t base_memh = sc->sc_base_memh; /* socket regs memory handle */
678 pcireg_t cbctrl;
679
680 /*
681 * Set PCI command reg.
682 * Some laptop's BIOSes (i.e. TICO) do not enable CardBus chip.
683 */
684 {
685 pcireg_t command = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
686
687 /* I believe it is harmless. */
688 command |= (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
689 PCI_COMMAND_MASTER_ENABLE);
690 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, command);
691 }
692
693 /*
694 * Set CardBus latency timer
695 */
696 {
697 pcireg_t pci_lscp = pci_conf_read(pc, tag, PCI_CB_LSCP_REG);
698 if (PCI_CB_LATENCY(pci_lscp) < 0x20) {
699 pci_lscp &= ~(PCI_CB_LATENCY_MASK << PCI_CB_LATENCY_SHIFT);
700 pci_lscp |= (0x20 << PCI_CB_LATENCY_SHIFT);
701 pci_conf_write(pc, tag, PCI_CB_LSCP_REG, pci_lscp);
702 }
703 DPRINTF(("CardBus latency timer 0x%x (%x)\n", PCI_CB_LATENCY(pci_lscp),
704 pci_conf_read(pc, tag, PCI_CB_LSCP_REG)));
705 }
706
707 /*
708 * Set PCI latency timer
709 */
710 {
711 pcireg_t pci_bhlc = pci_conf_read(pc, tag, PCI_BHLC_REG);
712 if (PCI_LATTIMER(pci_bhlc) < 0x10) {
713 pci_bhlc &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
714 pci_bhlc |= (0x10 << PCI_LATTIMER_SHIFT);
715 pci_conf_write(pc, tag, PCI_BHLC_REG, pci_bhlc);
716 }
717 DPRINTF(("PCI latency timer 0x%x (%x)\n", PCI_LATTIMER(pci_bhlc),
718 pci_conf_read(pc, tag, PCI_BHLC_REG)));
719 }
720
721 /* disable Legacy IO */
722
723 switch (sc->sc_chipset) {
724 case CB_RX5C46X: /* fallthrogh */
725 #if 0
726 case CB_RX5C47X:
727 #endif
728 /*
729 * The legacy pcic io-port on Ricoh CardBus bridges cannot be
730 * disabled by substituting 0 into PCI_LEGACY register. Ricoh
731 * CardBus bridges have special bits on Bridge control reg (addr
732 * 0x3e on PCI config space).
733 */
734 {
735 pcireg_t bcri = pci_conf_read(pc, tag, PCI_BCR_INTR);
736 bcri &= ~(CB_BCRI_RL_3E0_ENA | CB_BCRI_RL_3E2_ENA);
737 pci_conf_write(pc, tag, PCI_BCR_INTR, bcri);
738 }
739 break;
740 default:
741 /* XXX: I don't know proper way to kill Legacy IO properly. */
742 pci_conf_write(pc, tag, PCI_LEGACY, 0x0);
743 break;
744 }
745
746
747
748 /*
749 * Interrupt routing: use PCI interrupt
750 */
751 {
752 u_int32_t bcr = pci_conf_read(pc, tag, PCI_BCR_INTR);
753 bcr &= ~CB_BCR_INTR_IREQ_ENABLE; /* use PCI Intr */
754 bcr |= CB_BCR_WRITE_POST_ENABLE; /* enable write post */
755 pci_conf_write(pc, tag, PCI_BCR_INTR, bcr);
756 }
757
758 if (CB_TI113X == sc->sc_chipset) {
759 cbctrl = pci_conf_read(pc, tag, PCI_CBCTRL);
760 if (0 == sc->sc_function) {
761 cbctrl |= PCI113X_CBCTRL_PCI_IRQ_ENA;
762 }
763 cbctrl |= PCI113X_CBCTRL_PCI_IRQ_ENA; /* XXX: bug in PCI113X */
764 cbctrl |= PCI113X_CBCTRL_PCI_CSC; /* CSC intr enable */
765 cbctrl &= ~PCI113X_CBCTRL_PCI_INTR; /* functional intr prohibit */
766 cbctrl &= ~PCI113X_CBCTRL_INT_MASK; /* prohibit ISA routing */
767 pci_conf_write(pc, tag, PCI_CBCTRL, cbctrl);
768
769 /* set ExCA regs: PCI113X required to be set bit 4 at Interrupt
770 and General Register, which is IRQ Enable Register, and clear
771 bit 3:0 to zero in order to route CSC interrupt to PCI
772 interrupt pin. */
773 bus_space_write_1(base_memt, base_memh, 0x0803, 0x10);
774 /* set ExCA regs: prohibit all pcmcia-style CSC intr. */
775 bus_space_write_1(base_memt, base_memh, 0x0805, 0x00);
776 #if 1
777 DPRINTF(("ExCA regs:"));
778 DPRINTF((" 0x803: %02x", bus_space_read_1(base_memt, base_memh, 0x803)));
779 DPRINTF((" 0x805: %02x", bus_space_read_1(base_memt, base_memh, 0x805)));
780 DPRINTF((" 0x81e: %02x\n", bus_space_read_1(base_memt,base_memh,0x81e)));
781 #endif
782 } else if (sc->sc_chipset == CB_TI12XX) {
783 cbctrl = pci_conf_read(pc, tag, PCI_CBCTRL);
784 cbctrl &= ~PCI12XX_CBCTRL_INT_MASK; /* intr routing reset */
785 pci_conf_write(pc, tag, PCI_CBCTRL, cbctrl);
786 /*
787 * set ExCA regs: PCI12XX required to be set bit 4 at Interrupt
788 * and General Register, which is IRQ Enable Register, and clear
789 * bit 3:0 to zero in order to route CSC interrupt to PCI
790 * interrupt pin.
791 */
792 bus_space_write_1(base_memt, base_memh, 0x0803, 0x10);
793 /* set ExCA regs: prohibit all pcmcia-style CSC intr. */
794 bus_space_write_1(base_memt, base_memh, 0x0805, 0x00);
795 } else if (sc->sc_chipset == CB_TOPIC95B) {
796 cardbusreg_t sock_ctrl, slot_ctrl;
797
798 sock_ctrl = pci_conf_read(pc, tag, TOPIC_SOCKET_CTRL);
799 pci_conf_write(pc, tag, TOPIC_SOCKET_CTRL,
800 sock_ctrl | TOPIC_SOCKET_CTRL_SCR_IRQSEL);
801
802 slot_ctrl = pci_conf_read(pc, tag, TOPIC_SLOT_CTRL);
803 DPRINTF(("%s: topic slot ctrl reg 0x%x -> ", sc->sc_dev.dv_xname,
804 slot_ctrl));
805 slot_ctrl |= (TOPIC_SLOT_CTRL_SLOTON | TOPIC_SLOT_CTRL_SLOTEN |
806 TOPIC_SLOT_CTRL_ID_LOCK);
807 slot_ctrl |= TOPIC_SLOT_CTRL_CARDBUS;
808 slot_ctrl &= ~TOPIC_SLOT_CTRL_SWDETECT;
809 pci_conf_write(pc, tag, TOPIC_SLOT_CTRL, slot_ctrl);
810 DPRINTF(("0x%x\n", slot_ctrl));
811 }
812
813 /* close all memory and io windows */
814 pci_conf_write(pc, tag, PCI_CB_MEMBASE0, 0xffffffff);
815 pci_conf_write(pc, tag, PCI_CB_MEMLIMIT0, 0);
816 pci_conf_write(pc, tag, PCI_CB_MEMBASE1, 0xffffffff);
817 pci_conf_write(pc, tag, PCI_CB_MEMLIMIT1, 0);
818 pci_conf_write(pc, tag, PCI_CB_IOBASE0, 0xffffffff);
819 pci_conf_write(pc, tag, PCI_CB_IOLIMIT0, 0);
820 pci_conf_write(pc, tag, PCI_CB_IOBASE1, 0xffffffff);
821 pci_conf_write(pc, tag, PCI_CB_IOLIMIT1, 0);
822
823 return;
824 }
825
826
827
828 /*
829 * attach pccard bus
830 */
831 STATIC void
832 pccbb_pcmcia_attach_setup(sc, paa)
833 struct pccbb_softc *sc;
834 struct pcmciabus_attach_args *paa;
835 {
836 struct pcic_handle *ph = &sc->sc_pcmcia_h;
837 #if rbus
838 rbus_tag_t rb;
839 #endif
840
841 /* initialise pcmcia part in pccbb_softc */
842 ph->ph_parent = (struct device *)sc;
843 ph->sock = sc->sc_function;
844 ph->flags = 0;
845 ph->shutdown = 0;
846 ph->ih_irq = sc->sc_intrline;
847 ph->ph_bus_t = sc->sc_base_memt;
848 ph->ph_bus_h = sc->sc_base_memh;
849 ph->ph_read = pccbb_pcmcia_read;
850 ph->ph_write = pccbb_pcmcia_write;
851 sc->sc_pct = &pccbb_pcmcia_funcs;
852
853 Pcic_write(ph, PCIC_CSC_INTR, 0);
854 Pcic_read(ph, PCIC_CSC);
855
856 /* initialise pcmcia bus attachment */
857 paa->paa_busname = "pcmcia";
858 paa->pct = sc->sc_pct;
859 paa->pch = ph;
860 paa->iobase = 0; /* I don't use them */
861 paa->iosize = 0;
862 #if rbus
863 rb = ((struct pccbb_softc *)(ph->ph_parent))->sc_rbus_iot;
864 paa->iobase = rb->rb_start + rb->rb_offset;
865 paa->iosize = rb->rb_end - rb->rb_start;
866 #endif
867
868 return;
869 }
870
871
872 #if 0
873 STATIC void
874 pccbb_pcmcia_attach_card(ph)
875 struct pcic_handle *ph;
876 {
877 if (ph->flags & PCIC_FLAG_CARDP) {
878 panic("pccbb_pcmcia_attach_card: already attached");
879 }
880
881 /* call the MI attach function */
882 pcmcia_card_attach(ph->pcmcia);
883
884 ph->flags |= PCIC_FLAG_CARDP;
885 }
886
887
888 STATIC void
889 pccbb_pcmcia_detach_card(ph, flags)
890 struct pcic_handle *ph;
891 int flags;
892 {
893 if (!(ph->flags & PCIC_FLAG_CARDP)) {
894 panic("pccbb_pcmcia_detach_card: already detached");
895 }
896
897 ph->flags &= ~PCIC_FLAG_CARDP;
898
899 /* call the MI detach function */
900 pcmcia_card_detach(ph->pcmcia, flags);
901 }
902 #endif
903
904
905
906
907 /*
908 * int pccbbintr(arg)
909 * void *arg;
910 * This routine handles the interrupt from Yenta PCI-CardBus bridge
911 * itself.
912 */
913 int
914 pccbbintr(arg)
915 void *arg;
916 {
917 struct pccbb_softc *sc = (struct pccbb_softc *)arg;
918 u_int32_t sockevent;
919 bus_space_tag_t memt = sc->sc_base_memt;
920 bus_space_handle_t memh = sc->sc_base_memh;
921 u_int32_t sockstate;
922
923 sockevent = bus_space_read_4(memt, memh, CB_SOCKET_EVENT);
924 if (0 == sockevent) { /* not for me */
925 /* This interrupt is not for me: it may be for my child devices. */
926 return pccbbintr_function(sc);
927 } else {
928 bus_space_write_4(memt, memh, CB_SOCKET_EVENT, sockevent); /* reset bit */
929 }
930 sockstate = bus_space_read_4(memt, memh, CB_SOCKET_STAT);
931
932 if (sockevent & CB_SOCKET_EVENT_CD) {
933 if (CB_SOCKET_STAT_CD == (sockstate & CB_SOCKET_STAT_CD)) {
934 /* A card should be removed. */
935 if (sc->sc_flags & CBB_CARDEXIST) {
936 DPRINTF(("%s: 0x%08x", sc->sc_dev.dv_xname, sockevent));
937 DPRINTF((" card removed, 0x%08x\n", sockstate));
938 sc->sc_flags &= ~CBB_CARDEXIST;
939 if (sc->sc_csc->sc_status & CARDSLOT_STATUS_CARD_16) {
940 #if 0
941 struct pcic_handle *ph = &sc->sc_pcmcia_h;
942
943 pcmcia_card_deactivate(ph->pcmcia);
944 pccbb_pcmcia_socket_disable(ph);
945 pccbb_pcmcia_detach_card(ph, DETACH_FORCE);
946 #endif
947 cardslot_event_throw(sc->sc_csc, CARDSLOT_EVENT_REMOVAL_16);
948 } else if (sc->sc_csc->sc_status & CARDSLOT_STATUS_CARD_CB) {
949 /* Cardbus intr removed */
950 cardslot_event_throw(sc->sc_csc, CARDSLOT_EVENT_REMOVAL_CB);
951 }
952 }
953 } else if (0x00 == (sockstate & CB_SOCKET_STAT_CD)) {
954 if (sc->sc_flags & CBB_INSERTING) {
955 untimeout(pci113x_insert, sc);
956 }
957 timeout(pci113x_insert, sc, hz/10);
958 sc->sc_flags |= CBB_INSERTING;
959 }
960 } else {
961 DPRINTF(("%s: sockevent = %b\n",
962 sc->sc_dev.dv_xname, sockevent, PCCBB_SOCKEVENT_BITS));
963 DPRINTF(("%s: sockstate = %b\n",
964 sc->sc_dev.dv_xname,
965 sockstate, PCCBB_SOCKSTATE_BITS));
966 }
967
968 return 1;
969 }
970
971
972
973 /*
974 * static int pccbbintr_function(struct pccbb_softc *sc)
975 *
976 * This function calls each interrupt handler registered at the
977 * bridge. The interrupt handlers are called in registerd order.
978 */
979 static int
980 pccbbintr_function(sc)
981 struct pccbb_softc *sc;
982 {
983 int retval = 0, val;
984 struct pccbb_intrhand_list *pil;
985
986 for (pil = sc->sc_pil; pil != NULL; pil = pil->pil_next) {
987 val = (*pil->pil_func)(pil->pil_arg);
988 retval = retval == 1 ? 1 :
989 retval == 0 ? val :
990 val != 0 ? val : retval;
991 }
992
993 return retval;
994 }
995
996
997
998
999
1000 static void
1001 pci113x_insert(arg)
1002 void *arg;
1003 {
1004 struct pccbb_softc *sc = (struct pccbb_softc *)arg;
1005 u_int32_t sockevent, sockstate;
1006
1007 sockevent = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,
1008 CB_SOCKET_EVENT);
1009 sockstate = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,
1010 CB_SOCKET_STAT);
1011
1012 if (0 == (sockstate & CB_SOCKET_STAT_CD)) { /* card exist */
1013 DPRINTF(("%s: 0x%08x", sc->sc_dev.dv_xname, sockevent));
1014 DPRINTF((" card inserted, 0x%08x\n", sockstate));
1015 sc->sc_flags |= CBB_CARDEXIST;
1016 /* call pccard intterupt handler here */
1017 if (sockstate & CB_SOCKET_STAT_16BIT) {
1018 /* 16-bit card found */
1019 /* pccbb_pcmcia_attach_card(&sc->sc_pcmcia_h); */
1020 cardslot_event_throw(sc->sc_csc, CARDSLOT_EVENT_INSERTION_16);
1021 } else if (sockstate & CB_SOCKET_STAT_CB) {
1022 /* cardbus card fuond */
1023 /* cardbus_attach_card(sc->sc_csc); */
1024 cardslot_event_throw(sc->sc_csc, CARDSLOT_EVENT_INSERTION_CB);
1025 } else {
1026 /* who are you? */
1027 }
1028 } else {
1029 timeout(pci113x_insert, sc, hz/10);
1030 }
1031 }
1032
1033
1034
1035
1036 #define PCCBB_PCMCIA_OFFSET 0x800
1037 static u_int8_t
1038 pccbb_pcmcia_read(ph, reg)
1039 struct pcic_handle *ph;
1040 int reg;
1041 {
1042 return bus_space_read_1(ph->ph_bus_t, ph->ph_bus_h, PCCBB_PCMCIA_OFFSET + reg);
1043 }
1044
1045
1046
1047 static void
1048 pccbb_pcmcia_write(ph, reg, val)
1049 struct pcic_handle *ph;
1050 int reg;
1051 u_int8_t val;
1052 {
1053 bus_space_write_1(ph->ph_bus_t, ph->ph_bus_h, PCCBB_PCMCIA_OFFSET + reg, val);
1054 }
1055
1056
1057
1058
1059 /*
1060 * STATIC int pccbb_ctrl(cardbus_chipset_tag_t, int)
1061 */
1062 STATIC int
1063 pccbb_ctrl(ct, command)
1064 cardbus_chipset_tag_t ct;
1065 int command;
1066 {
1067 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1068
1069 switch(command) {
1070 case CARDBUS_CD:
1071 if (2 == pccbb_detect_card(sc)) {
1072 int retval = 0;
1073 int status = cb_detect_voltage(sc);
1074 if (PCCARD_VCC_5V & status) {
1075 retval |= CARDBUS_5V_CARD;
1076 }
1077 if (PCCARD_VCC_3V & status) {
1078 retval |= CARDBUS_3V_CARD;
1079 }
1080 if (PCCARD_VCC_XV & status) {
1081 retval |= CARDBUS_XV_CARD;
1082 }
1083 if (PCCARD_VCC_YV & status) {
1084 retval |= CARDBUS_YV_CARD;
1085 }
1086 return retval;
1087 } else {
1088 return 0;
1089 }
1090 break;
1091 case CARDBUS_RESET:
1092 return cb_reset(sc);
1093 break;
1094 case CARDBUS_IO_ENABLE: /* fallthrough */
1095 case CARDBUS_IO_DISABLE: /* fallthrough */
1096 case CARDBUS_MEM_ENABLE: /* fallthrough */
1097 case CARDBUS_MEM_DISABLE: /* fallthrough */
1098 case CARDBUS_BM_ENABLE: /* fallthrough */
1099 case CARDBUS_BM_DISABLE: /* fallthrough */
1100 return pccbb_cardenable(sc, command);
1101 break;
1102 }
1103
1104 return 0;
1105 }
1106
1107
1108
1109 /*
1110 * STATIC int pccbb_power(cardbus_chipset_tag_t, int)
1111 * This function returns true when it succeeds and returns false when
1112 * it fails.
1113 */
1114 STATIC int
1115 pccbb_power(ct, command)
1116 cardbus_chipset_tag_t ct;
1117 int command;
1118 {
1119 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1120
1121 u_int32_t status, sock_ctrl;
1122 bus_space_tag_t memt = sc->sc_base_memt;
1123 bus_space_handle_t memh = sc->sc_base_memh;
1124
1125 DPRINTF(("pccbb_power: %s and %s [%x]\n",
1126 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_UC ? "CARDBUS_VCC_UC" :
1127 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_5V ? "CARDBUS_VCC_5V" :
1128 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_3V ? "CARDBUS_VCC_3V" :
1129 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_XV ? "CARDBUS_VCC_XV" :
1130 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_YV ? "CARDBUS_VCC_YV" :
1131 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_0V ? "CARDBUS_VCC_0V" :
1132 "UNKNOWN",
1133 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_UC ? "CARDBUS_VPP_UC" :
1134 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_12V ? "CARDBUS_VPP_12V" :
1135 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_VCC ? "CARDBUS_VPP_VCC" :
1136 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_0V ? "CARDBUS_VPP_0V" :
1137 "UNKNOWN",
1138 command));
1139
1140 status = bus_space_read_4(memt, memh, CB_SOCKET_STAT);
1141 sock_ctrl = bus_space_read_4(memt, memh, CB_SOCKET_CTRL);
1142
1143 switch (command & CARDBUS_VCCMASK) {
1144 case CARDBUS_VCC_UC:
1145 break;
1146 case CARDBUS_VCC_5V:
1147 if (CB_SOCKET_STAT_5VCARD & status) { /* check 5 V card */
1148 sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK;
1149 sock_ctrl |= CB_SOCKET_CTRL_VCC_5V;
1150 } else {
1151 printf("%s: BAD voltage request: no 5 V card\n", sc->sc_dev.dv_xname);
1152 }
1153 break;
1154 case CARDBUS_VCC_3V:
1155 if (CB_SOCKET_STAT_3VCARD & status) {
1156 sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK;
1157 sock_ctrl |= CB_SOCKET_CTRL_VCC_3V;
1158 } else {
1159 printf("%s: BAD voltage request: no 3.3 V card\n", sc->sc_dev.dv_xname);
1160 }
1161 break;
1162 case CARDBUS_VCC_0V:
1163 sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK;
1164 break;
1165 default:
1166 return 0; /* power NEVER changed */
1167 break;
1168 }
1169
1170 switch (command & CARDBUS_VPPMASK) {
1171 case CARDBUS_VPP_UC:
1172 break;
1173 case CARDBUS_VPP_0V:
1174 sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK;
1175 break;
1176 case CARDBUS_VPP_VCC:
1177 sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK;
1178 sock_ctrl |= ((sock_ctrl >> 4) & 0x07);
1179 break;
1180 case CARDBUS_VPP_12V:
1181 sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK;
1182 sock_ctrl |= CB_SOCKET_CTRL_VPP_12V;
1183 break;
1184 }
1185
1186 #if 0
1187 DPRINTF(("sock_ctrl: %x\n", sock_ctrl));
1188 #endif
1189 bus_space_write_4(memt, memh, CB_SOCKET_CTRL, sock_ctrl);
1190 status = bus_space_read_4(memt, memh, CB_SOCKET_STAT);
1191
1192 delay(20*1000); /* wait 20 ms: Vcc setup time */
1193 /* XXX
1194 delay 200 ms: though the standard defines that the Vcc set-up time
1195 is 20 ms, some PC-Card bridge requires longer duration.
1196 */
1197 delay(200*1000);
1198
1199
1200 if (status & CB_SOCKET_STAT_BADVCC) { /* bad Vcc request */
1201 printf("%s: bad Vcc request. sock_ctrl 0x%x, sock_status 0x%x\n",
1202 sc->sc_dev.dv_xname, sock_ctrl ,status);
1203 DPRINTF(("pccbb_power: %s and %s [%x]\n",
1204 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_UC ? "CARDBUS_VCC_UC" :
1205 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_5V ? "CARDBUS_VCC_5V":
1206 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_3V ? "CARDBUS_VCC_3V":
1207 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_XV ? "CARDBUS_VCC_XV":
1208 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_YV ? "CARDBUS_VCC_YV":
1209 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_0V ? "CARDBUS_VCC_0V":
1210 "UNKNOWN",
1211 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_UC ? "CARDBUS_VPP_UC":
1212 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_12V ?"CARDBUS_VPP_12V":
1213 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_VCC ?"CARDBUS_VPP_VCC":
1214 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_0V ? "CARDBUS_VPP_0V" :
1215 "UNKNOWN",
1216 command));
1217 #if 0
1218 if (command == (CARDBUS_VCC_0V | CARDBUS_VPP_0V)) {
1219 u_int32_t force = bus_space_read_4(memt, memh, CB_SOCKET_FORCE);
1220 /* Reset Bad Vcc request */
1221 force &= ~CB_SOCKET_FORCE_BADVCC;
1222 bus_space_write_4(memt, memh, CB_SOCKET_FORCE, force);
1223 printf("new status 0x%x\n", bus_space_read_4(memt, memh,CB_SOCKET_STAT));
1224 return 1;
1225 }
1226 #endif
1227 return 0;
1228 }
1229 return 1; /* power changed correctly */
1230 }
1231
1232
1233
1234
1235
1236
1237 #if defined CB_PCMCIA_POLL
1238 struct cb_poll_str {
1239 void *arg;
1240 int (* func) __P((void *));
1241 int level;
1242 pccard_chipset_tag_t ct;
1243 int count;
1244 };
1245
1246 static struct cb_poll_str cb_poll[10];
1247 static int cb_poll_n = 0;
1248
1249 static void cb_pcmcia_poll __P((void *arg));
1250
1251 static void
1252 cb_pcmcia_poll(arg)
1253 void *arg;
1254 {
1255 struct cb_poll_str *poll = arg;
1256 struct cbb_pcmcia_softc *psc = (void *)poll->ct->v;
1257 struct pccbb_softc *sc = psc->cpc_parent;
1258 int s;
1259 u_int32_t spsr; /* socket present-state reg */
1260
1261 timeout(cb_pcmcia_poll, arg, hz/10);
1262 switch (poll->level) {
1263 case IPL_NET:
1264 s = splnet();
1265 break;
1266 case IPL_BIO:
1267 s = splbio();
1268 break;
1269 case IPL_TTY: /* fallthrough */
1270 default:
1271 s = spltty();
1272 break;
1273 }
1274
1275 spsr = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_STAT);
1276
1277 #if defined CB_PCMCIA_POLL_ONLY && defined LEVEL2
1278 if (!(spsr & 0x40)) { /* CINT low */
1279 #else
1280 if (1) {
1281 #endif
1282 if ((*poll->func)(poll->arg) == 1) {
1283 ++poll->count;
1284 printf("intr: reported from poller, 0x%x\n", spsr);
1285 #if defined LEVEL2
1286 } else {
1287 printf("intr: miss! 0x%x\n", spsr);
1288 #endif
1289 }
1290 }
1291 splx(s);
1292 }
1293 #endif /* defined CB_PCMCIA_POLL */
1294
1295
1296
1297
1298 /*
1299 * static int pccbb_detect_card(struct pccbb_softc *sc)
1300 * return value: 0 if no card exists.
1301 * 1 if 16-bit card exists.
1302 * 2 if cardbus card exists.
1303 */
1304 static int
1305 pccbb_detect_card(sc)
1306 struct pccbb_softc *sc;
1307 {
1308 bus_space_handle_t base_memh = sc->sc_base_memh;
1309 bus_space_tag_t base_memt = sc->sc_base_memt;
1310 u_int32_t sockstat = bus_space_read_4(base_memt,base_memh, CB_SOCKET_STAT);
1311 int retval = 0;
1312
1313 if (0x00 == (sockstat & CB_SOCKET_STAT_CD)) { /* CD1 and CD2 asserted */
1314 /* card must be present */
1315 if (!(CB_SOCKET_STAT_NOTCARD & sockstat)) { /* NOTACARD DEASSERTED */
1316 if (CB_SOCKET_STAT_CB & sockstat) { /* CardBus mode */
1317 retval = 2;
1318 } else if (CB_SOCKET_STAT_16BIT & sockstat) { /* 16-bit mode */
1319 retval = 1;
1320 }
1321 }
1322 }
1323 return retval;
1324 }
1325
1326
1327
1328
1329 /*
1330 * STATIC int cb_reset(struct pccbb_softc *sc)
1331 * This function resets CardBus card.
1332 */
1333 STATIC int
1334 cb_reset(sc)
1335 struct pccbb_softc *sc;
1336 {
1337 /*
1338 * Reset Assert at least 20 ms
1339 * Some machines request longer duration.
1340 */
1341 int reset_duration = (sc->sc_chipset == CB_RX5C47X ? 400*1000 : 40*1000);
1342 u_int32_t bcr = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR);
1343
1344 bcr |= (0x40 << 16); /* Reset bit Assert (bit 6 at 0x3E) */
1345 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR, bcr);
1346 delay(reset_duration);
1347
1348 if (CBB_CARDEXIST & sc->sc_flags) { /* A card exists. Reset it! */
1349 bcr &= ~(0x40 << 16); /* Reset bit Deassert (bit 6 at 0x3E) */
1350 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR, bcr);
1351 delay(reset_duration);
1352 }
1353 /* No card found on the slot. Keep Reset. */
1354 return 1;
1355 }
1356
1357
1358
1359
1360 /*
1361 * STATIC int cb_detect_voltage(struct pccbb_softc *sc)
1362 * This function detect card Voltage.
1363 */
1364 STATIC int
1365 cb_detect_voltage(sc)
1366 struct pccbb_softc *sc;
1367 {
1368 u_int32_t psr; /* socket present-state reg */
1369 bus_space_tag_t iot = sc->sc_base_memt;
1370 bus_space_handle_t ioh = sc->sc_base_memh;
1371 int vol = PCCARD_VCC_UKN; /* set 0 */
1372
1373 psr = bus_space_read_4(iot, ioh, CB_SOCKET_STAT);
1374
1375 if (0x400u & psr) {
1376 vol |= PCCARD_VCC_5V;
1377 }
1378 if (0x800u & psr) {
1379 vol |= PCCARD_VCC_3V;
1380 }
1381
1382 return vol;
1383 }
1384
1385
1386
1387
1388
1389
1390 STATIC int
1391 cbbprint(aux, pcic)
1392 void *aux;
1393 const char *pcic;
1394 {
1395 /*
1396 struct cbslot_attach_args *cba = aux;
1397
1398 if (cba->cba_slot >= 0) {
1399 printf(" slot %d", cba->cba_slot);
1400 }
1401 */
1402 return UNCONF;
1403 }
1404
1405
1406
1407
1408 /*
1409 * STATIC int pccbb_cardenable(struct pccbb_softc *sc, int function)
1410 * This function enables and disables the card
1411 */
1412 STATIC int
1413 pccbb_cardenable(sc, function)
1414 struct pccbb_softc *sc;
1415 int function;
1416 {
1417 u_int32_t command = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG);
1418
1419 DPRINTF(("pccbb_cardenable:"));
1420 switch (function) {
1421 case CARDBUS_IO_ENABLE:
1422 command |= PCI_COMMAND_IO_ENABLE;
1423 break;
1424 case CARDBUS_IO_DISABLE:
1425 command &= ~PCI_COMMAND_IO_ENABLE;
1426 break;
1427 case CARDBUS_MEM_ENABLE:
1428 command |= PCI_COMMAND_MEM_ENABLE;
1429 break;
1430 case CARDBUS_MEM_DISABLE:
1431 command &= ~PCI_COMMAND_MEM_ENABLE;
1432 break;
1433 case CARDBUS_BM_ENABLE:
1434 command |= PCI_COMMAND_MASTER_ENABLE;
1435 break;
1436 case CARDBUS_BM_DISABLE:
1437 command &= ~PCI_COMMAND_MASTER_ENABLE;
1438 break;
1439 default:
1440 return 0;
1441 }
1442
1443 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, command);
1444 DPRINTF((" command reg 0x%x\n", command));
1445 return 1;
1446 }
1447
1448
1449
1450
1451
1452
1453 #if !rbus
1454 /*
1455 * int pccbb_io_open(cardbus_chipset_tag_t, int, u_int32_t, u_int32_t)
1456 */
1457 static int
1458 pccbb_io_open(ct, win, start, end)
1459 cardbus_chipset_tag_t ct;
1460 int win;
1461 u_int32_t start, end;
1462 {
1463 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1464 int basereg;
1465 int limitreg;
1466
1467 if ((win < 0) || (win > 2)) {
1468 #if defined DIAGNOSTIC
1469 printf("cardbus_io_open: window out of range %d\n", win);
1470 #endif
1471 return 0;
1472 }
1473
1474 basereg = win*8 + 0x2c;
1475 limitreg = win*8 + 0x30;
1476
1477 DPRINTF(("pccbb_io_open: 0x%x[0x%x] - 0x%x[0x%x]\n",
1478 start, basereg, end, limitreg));
1479
1480 pci_conf_write(sc->sc_pc, sc->sc_tag, basereg, start);
1481 pci_conf_write(sc->sc_pc, sc->sc_tag, limitreg, end);
1482 return 1;
1483 }
1484
1485 /*
1486 * int pccbb_io_close(cardbus_chipset_tag_t, int)
1487 */
1488 static int
1489 pccbb_io_close(ct, win)
1490 cardbus_chipset_tag_t ct;
1491 int win;
1492 {
1493 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1494 int basereg;
1495 int limitreg;
1496
1497 if ((win < 0) || (win > 2)) {
1498 #if defined DIAGNOSTIC
1499 printf("cardbus_io_close: window out of range %d\n", win);
1500 #endif
1501 return 0;
1502 }
1503
1504 basereg = win*8 + 0x2c;
1505 limitreg = win*8 + 0x30;
1506
1507 pci_conf_write(sc->sc_pc, sc->sc_tag, basereg, 0);
1508 pci_conf_write(sc->sc_pc, sc->sc_tag, limitreg, 0);
1509 return 1;
1510 }
1511
1512 /*
1513 * int pccbb_mem_open(cardbus_chipset_tag_t, int, u_int32_t, u_int32_t)
1514 */
1515 static int
1516 pccbb_mem_open(ct, win, start, end)
1517 cardbus_chipset_tag_t ct;
1518 int win;
1519 u_int32_t start, end;
1520 {
1521 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1522 int basereg;
1523 int limitreg;
1524
1525 if ((win < 0) || (win > 2)) {
1526 #if defined DIAGNOSTIC
1527 printf("cardbus_mem_open: window out of range %d\n", win);
1528 #endif
1529 return 0;
1530 }
1531
1532 basereg = win*8 + 0x1c;
1533 limitreg = win*8 + 0x20;
1534
1535 pci_conf_write(sc->sc_pc, sc->sc_tag, basereg, start);
1536 pci_conf_write(sc->sc_pc, sc->sc_tag, limitreg, end);
1537 return 1;
1538 }
1539
1540
1541 /*
1542 * int pccbb_mem_close(cardbus_chipset_tag_t, int)
1543 */
1544 static int
1545 pccbb_mem_close(ct, win)
1546 cardbus_chipset_tag_t ct;
1547 int win;
1548 {
1549 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1550 int basereg;
1551 int limitreg;
1552
1553 if ((win < 0) || (win > 2)) {
1554 #if defined DIAGNOSTIC
1555 printf("cardbus_mem_close: window out of range %d\n", win);
1556 #endif
1557 return 0;
1558 }
1559
1560 basereg = win*8 + 0x1c;
1561 limitreg = win*8 + 0x20;
1562
1563 pci_conf_write(sc->sc_pc, sc->sc_tag, basereg, 0);
1564 pci_conf_write(sc->sc_pc, sc->sc_tag, limitreg, 0);
1565 return 1;
1566 }
1567 #endif
1568
1569
1570
1571 /*
1572 * static void *pccbb_intr_establish(cardbus_chipset_tag_t ct,
1573 * int irq,
1574 * int level,
1575 * int (* func) __P((void *)),
1576 * void *arg)
1577 *
1578 * This function registers an interrupt handler at the bridge, in
1579 * order not to call the interrput handlers of child devices when
1580 * a card-deletion interrput occurs.
1581 *
1582 * The arguments irq and level are not used.
1583 */
1584 static void *
1585 pccbb_intr_establish(ct, irq, level, func, arg)
1586 cardbus_chipset_tag_t ct;
1587 int irq, level;
1588 int (* func) __P((void *));
1589 void *arg;
1590 {
1591 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1592 struct pccbb_intrhand_list *pil, *newpil;
1593
1594 if (sc->sc_pil == NULL) {
1595 /* initialise bridge intr routing */
1596
1597 switch (sc->sc_chipset) {
1598 case CB_TI113X:
1599 {
1600 pcireg_t cbctrl = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL);
1601 cbctrl |= PCI113X_CBCTRL_PCI_INTR; /* functional intr enabled */
1602 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL, cbctrl);
1603 break;
1604 }
1605 default:
1606 break;
1607 }
1608 }
1609
1610 /*
1611 * Allocate a room for interrut handler structure.
1612 */
1613 if (NULL == (newpil = (struct pccbb_intrhand_list *)malloc(sizeof(struct pccbb_intrhand_list), M_DEVBUF, M_WAITOK))) {
1614 return NULL;
1615 }
1616
1617 newpil->pil_func = func;
1618 newpil->pil_arg = arg;
1619 newpil->pil_next = NULL;
1620
1621 if (sc->sc_pil == NULL) {
1622 sc->sc_pil = newpil;
1623 } else {
1624 for (pil = sc->sc_pil; pil->pil_next != NULL; pil = pil->pil_next);
1625 pil->pil_next = newpil;
1626 }
1627
1628 return newpil;
1629 }
1630
1631
1632
1633
1634 /*
1635 * static void *pccbb_intr_disestablish(cardbus_chipset_tag_t ct,
1636 * void *ih)
1637 *
1638 * This function removes an interrupt handler pointed by ih.
1639 */
1640 static void
1641 pccbb_intr_disestablish(ct, ih)
1642 cardbus_chipset_tag_t ct;
1643 void *ih;
1644 {
1645 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1646 struct pccbb_intrhand_list *pil, **pil_prev;
1647
1648 pil_prev = &sc->sc_pil;
1649
1650 for (pil = sc->sc_pil; pil != NULL; pil = pil->pil_next) {
1651 if (pil == ih) {
1652 *pil_prev = pil->pil_next;
1653 free(pil, M_DEVBUF);
1654 break;
1655 }
1656 pil_prev = &pil->pil_next;
1657 }
1658
1659 if (sc->sc_pil == NULL) {
1660 /* No interrupt handlers */
1661
1662 switch (sc->sc_chipset) {
1663 case CB_TI113X:
1664 {
1665 pcireg_t cbctrl = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL);
1666 cbctrl &= ~PCI113X_CBCTRL_PCI_INTR; /* functional intr disabled */
1667 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL, cbctrl);
1668 break;
1669 }
1670 default:
1671 break;
1672 }
1673 }
1674 }
1675
1676
1677
1678
1679
1680 #if defined SHOW_REGS
1681 static void
1682 cb_show_regs(pc, tag, memt, memh)
1683 pci_chipset_tag_t pc;
1684 pcitag_t tag;
1685 bus_space_tag_t memt;
1686 bus_space_handle_t memh;
1687 {
1688 int i;
1689 printf("PCI config regs:");
1690 for (i = 0; i < 0x50; i += 4) {
1691 if (i % 16 == 0) {
1692 printf("\n 0x%02x:", i);
1693 }
1694 printf(" %08x", pci_conf_read(pc, tag, i));
1695 }
1696 for (i = 0x80; i < 0xb0; i += 4) {
1697 if (i % 16 == 0) {
1698 printf("\n 0x%02x:", i);
1699 }
1700 printf(" %08x", pci_conf_read(pc, tag, i));
1701 }
1702
1703 if (memh == 0) {
1704 printf("\n");
1705 return;
1706 }
1707
1708 printf("\nsocket regs:");
1709 for (i = 0; i <= 0x10; i += 0x04) {
1710 printf(" %08x", bus_space_read_4(memt, memh, i));
1711 }
1712 printf("\nExCA regs:");
1713 for (i = 0; i < 0x08; ++i) {
1714 printf(" %02x", bus_space_read_1(memt, memh, 0x800 + i));
1715 }
1716 printf("\n");
1717 return;
1718 }
1719 #endif
1720
1721
1722
1723 /*
1724 * static cardbustag_t pccbb_make_tag(cardbus_chipset_tag_t cc,
1725 * int busno, int devno, int function)
1726 * This is the function to make a tag to access config space of
1727 * a CardBus Card. It works same as pci_conf_read.
1728 */
1729 static cardbustag_t
1730 pccbb_make_tag(cc, busno, devno, function)
1731 cardbus_chipset_tag_t cc;
1732 int busno, devno, function;
1733 {
1734 struct pccbb_softc *sc = (struct pccbb_softc *)cc;
1735
1736 return pci_make_tag(sc->sc_pc, busno, devno, function);
1737 }
1738
1739
1740 static void
1741 pccbb_free_tag(cc, tag)
1742 cardbus_chipset_tag_t cc;
1743 cardbustag_t tag;
1744 {
1745 }
1746
1747
1748 /*
1749 * static cardbusreg_t pccbb_conf_read(cardbus_chipset_tag_t cc,
1750 * cardbustag_t tag, int offset)
1751 * This is the function to read the config space of a CardBus Card.
1752 * It works same as pci_conf_read.
1753 */
1754 static cardbusreg_t
1755 pccbb_conf_read(cc, tag, offset)
1756 cardbus_chipset_tag_t cc;
1757 cardbustag_t tag;
1758 int offset; /* register offset */
1759 {
1760 struct pccbb_softc *sc = (struct pccbb_softc *)cc;
1761
1762 return pci_conf_read(sc->sc_pc, tag, offset);
1763 }
1764
1765
1766
1767 /*
1768 * static void pccbb_conf_write(cardbus_chipset_tag_t cc, cardbustag_t tag,
1769 * int offs, cardbusreg_t val)
1770 * This is the function to write the config space of a CardBus Card.
1771 * It works same as pci_conf_write.
1772 */
1773 static void
1774 pccbb_conf_write(cc, tag, reg, val)
1775 cardbus_chipset_tag_t cc;
1776 cardbustag_t tag;
1777 int reg; /* register offset */
1778 cardbusreg_t val;
1779 {
1780 struct pccbb_softc *sc = (struct pccbb_softc *)cc;
1781
1782 pci_conf_write(sc->sc_pc, tag, reg, val);
1783 }
1784
1785
1786
1787
1788
1789 #if 0
1790 STATIC int
1791 pccbb_new_pcmcia_io_alloc(pcmcia_chipset_handle_t pch,
1792 bus_addr_t start, bus_size_t size,
1793 bus_size_t align, bus_addr_t mask, /* address line width */
1794 int speed, int flags, /* bus width */
1795 bus_space_handle_t *iohp)
1796 #endif
1797
1798
1799 /*
1800 * STATIC int pccbb_pcmcia_io_alloc(pcmcia_chipset_handle_t pch,
1801 * bus_addr_t start, bus_size_t size,
1802 * bus_size_t align,
1803 * struct pcmcia_io_handle *pcihp
1804 *
1805 * This function only allocates I/O region for pccard. This function
1806 * never maps the allcated region to pccard I/O area.
1807 *
1808 * XXX: The interface of this function is not very good, I believe.
1809 */
1810 STATIC int
1811 pccbb_pcmcia_io_alloc(pch, start, size, align, pcihp)
1812 pcmcia_chipset_handle_t pch;
1813 bus_addr_t start; /* start address */
1814 bus_size_t size;
1815 bus_size_t align;
1816 struct pcmcia_io_handle *pcihp;
1817 {
1818 struct pcic_handle *ph = (struct pcic_handle *)pch;
1819 bus_addr_t ioaddr;
1820 int flags = 0;
1821 bus_space_tag_t iot;
1822 bus_space_handle_t ioh;
1823 #if rbus
1824 rbus_tag_t rb;
1825 #endif
1826 if (align == 0) {
1827 align = size; /* XXX: funny??? */
1828 }
1829
1830
1831 /*
1832 * Allocate some arbitrary I/O space.
1833 */
1834
1835 iot = ((struct pccbb_softc *)(ph->ph_parent))->sc_iot;
1836
1837 #if rbus
1838 rb = ((struct pccbb_softc *)(ph->ph_parent))->sc_rbus_iot;
1839 if (rbus_space_alloc(rb, start, size, 0x3ff /* XXX: I assume all card decode lower 10 bits by its hardware */,
1840 align, 0, &ioaddr, &ioh)) {
1841 return 1;
1842 }
1843 #else
1844 if (start) {
1845 ioaddr = start;
1846 if (bus_space_map(iot, start, size, 0, &ioh)) {
1847 return 1;
1848 }
1849 DPRINTF(("pccbb_pcmcia_io_alloc map port %lx+%lx\n",
1850 (u_long) ioaddr, (u_long) size));
1851 } else {
1852 flags |= PCMCIA_IO_ALLOCATED;
1853 if (bus_space_alloc(iot, 0x700/* ph->sc->sc_iobase */,
1854 0x800/* ph->sc->sc_iobase + ph->sc->sc_iosize*/,
1855 size, align, 0, 0, &ioaddr, &ioh)) {
1856 /* No room be able to be get. */
1857 return 1;
1858 }
1859 DPRINTF(("pccbb_pcmmcia_io_alloc alloc port 0x%lx+0x%lx\n",
1860 (u_long) ioaddr, (u_long) size));
1861 }
1862 #endif
1863
1864 pcihp->iot = iot;
1865 pcihp->ioh = ioh;
1866 pcihp->addr = ioaddr;
1867 pcihp->size = size;
1868 pcihp->flags = flags;
1869
1870 return 0;
1871 }
1872
1873
1874
1875
1876
1877 /*
1878 * STATIC int pccbb_pcmcia_io_free(pcmcia_chipset_handle_t pch,
1879 * struct pcmcia_io_handle *pcihp)
1880 *
1881 * This function only frees I/O region for pccard.
1882 *
1883 * XXX: The interface of this function is not very good, I believe.
1884 */
1885 void
1886 pccbb_pcmcia_io_free(pch, pcihp)
1887 pcmcia_chipset_handle_t pch;
1888 struct pcmcia_io_handle *pcihp;
1889 {
1890 #if !rbus
1891 bus_space_tag_t iot = pcihp->iot;
1892 #endif
1893 bus_space_handle_t ioh = pcihp->ioh;
1894 bus_size_t size = pcihp->size;
1895
1896 #if rbus
1897 struct pccbb_softc *sc = (struct pccbb_softc *)((struct pcic_handle *)pch)->ph_parent;
1898 rbus_tag_t rb = sc->sc_rbus_iot;
1899
1900 rbus_space_free(rb, ioh, size, NULL);
1901 #else
1902 if (pcihp->flags & PCMCIA_IO_ALLOCATED)
1903 bus_space_free(iot, ioh, size);
1904 else
1905 bus_space_unmap(iot, ioh, size);
1906 #endif
1907 }
1908
1909
1910
1911 /*
1912 * STATIC int pccbb_pcmcia_io_map(pcmcia_chipset_handle_t pch, int width,
1913 * bus_addr_t offset, bus_size_t size,
1914 * struct pcmcia_io_handle *pcihp,
1915 * int *windowp)
1916 *
1917 * This function maps the allocated I/O region to pccard. This function
1918 * never allocates any I/O region for pccard I/O area. I don't
1919 * understand why the original authors of pcmciabus separated alloc and
1920 * map. I believe the two must be unite.
1921 *
1922 * XXX: no wait timing control?
1923 */
1924 int
1925 pccbb_pcmcia_io_map(pch, width, offset, size, pcihp, windowp)
1926 pcmcia_chipset_handle_t pch;
1927 int width;
1928 bus_addr_t offset;
1929 bus_size_t size;
1930 struct pcmcia_io_handle *pcihp;
1931 int *windowp;
1932 {
1933 struct pcic_handle *ph = (struct pcic_handle *) pch;
1934 bus_addr_t ioaddr = pcihp->addr + offset;
1935 int i, win;
1936 #if defined CBB_DEBUG
1937 static char *width_names[] = { "dynamic", "io8", "io16" };
1938 #endif
1939
1940 /* Sanity check I/O handle. */
1941
1942 if (((struct pccbb_softc *)ph->ph_parent)->sc_iot != pcihp->iot) {
1943 panic("pccbb_pcmcia_io_map iot is bogus");
1944 }
1945
1946 /* XXX Sanity check offset/size. */
1947
1948 win = -1;
1949 for (i = 0; i < PCIC_IO_WINS; i++) {
1950 if ((ph->ioalloc & (1 << i)) == 0) {
1951 win = i;
1952 ph->ioalloc |= (1 << i);
1953 break;
1954 }
1955 }
1956
1957 if (win == -1) {
1958 return 1;
1959 }
1960
1961 *windowp = win;
1962
1963 /* XXX this is pretty gross */
1964
1965 DPRINTF(("pccbb_pcmcia_io_map window %d %s port %lx+%lx\n",
1966 win, width_names[width], (u_long) ioaddr, (u_long) size));
1967
1968 /* XXX wtf is this doing here? */
1969
1970 #if 0
1971 printf(" port 0x%lx", (u_long) ioaddr);
1972 if (size > 1) {
1973 printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1);
1974 }
1975 #endif
1976
1977 ph->io[win].addr = ioaddr;
1978 ph->io[win].size = size;
1979 ph->io[win].width = width;
1980
1981 /* actual dirty register-value changing in the function below. */
1982 pccbb_pcmcia_do_io_map(ph, win);
1983
1984 return 0;
1985 }
1986
1987
1988
1989 /*
1990 * STATIC void pccbb_pcmcia_do_io_map(struct pcic_handle *h, int win)
1991 *
1992 * This function changes register-value to map I/O region for pccard.
1993 */
1994 static void
1995 pccbb_pcmcia_do_io_map(ph, win)
1996 struct pcic_handle *ph;
1997 int win;
1998 {
1999 static u_int8_t pcic_iowidth[3] = {
2000 PCIC_IOCTL_IO0_IOCS16SRC_CARD,
2001 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO0_DATASIZE_8BIT,
2002 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO0_DATASIZE_16BIT,
2003 };
2004
2005 #define PCIC_SIA_START_LOW 0
2006 #define PCIC_SIA_START_HIGH 1
2007 #define PCIC_SIA_STOP_LOW 2
2008 #define PCIC_SIA_STOP_HIGH 3
2009
2010 int regbase_win = 0x8 + win*0x04;
2011 u_int8_t ioctl, enable;
2012
2013 DPRINTF(("pccbb_pcmcia_do_io_map win %d addr 0x%lx size 0x%lx width %d\n",
2014 win, (long) ph->io[win].addr, (long) ph->io[win].size,
2015 ph->io[win].width * 8));
2016
2017 Pcic_write(ph, regbase_win + PCIC_SIA_START_LOW,
2018 ph->io[win].addr & 0xff);
2019 Pcic_write(ph, regbase_win + PCIC_SIA_START_HIGH,
2020 (ph->io[win].addr >> 8) & 0xff);
2021
2022 Pcic_write(ph, regbase_win + PCIC_SIA_STOP_LOW,
2023 (ph->io[win].addr + ph->io[win].size - 1) & 0xff);
2024 Pcic_write(ph, regbase_win + PCIC_SIA_STOP_HIGH,
2025 ((ph->io[win].addr + ph->io[win].size - 1) >> 8) & 0xff);
2026
2027 ioctl = Pcic_read(ph, PCIC_IOCTL);
2028 enable = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
2029 switch (win) {
2030 case 0:
2031 ioctl &= ~(PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT |
2032 PCIC_IOCTL_IO0_IOCS16SRC_MASK | PCIC_IOCTL_IO0_DATASIZE_MASK);
2033 ioctl |= pcic_iowidth[ph->io[win].width];
2034 enable |= PCIC_ADDRWIN_ENABLE_IO0;
2035 break;
2036 case 1:
2037 ioctl &= ~(PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT |
2038 PCIC_IOCTL_IO1_IOCS16SRC_MASK | PCIC_IOCTL_IO1_DATASIZE_MASK);
2039 ioctl |= (pcic_iowidth[ph->io[win].width] << 4);
2040 enable |= PCIC_ADDRWIN_ENABLE_IO1;
2041 break;
2042 }
2043 Pcic_write(ph, PCIC_IOCTL, ioctl);
2044 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, enable);
2045 #if defined CBB_DEBUG
2046 {
2047 u_int8_t start_low = Pcic_read(ph, regbase_win + PCIC_SIA_START_LOW);
2048 u_int8_t start_high = Pcic_read(ph, regbase_win + PCIC_SIA_START_HIGH);
2049 u_int8_t stop_low = Pcic_read(ph, regbase_win + PCIC_SIA_STOP_LOW);
2050 u_int8_t stop_high = Pcic_read(ph, regbase_win + PCIC_SIA_STOP_HIGH);
2051 printf(" start %02x %02x, stop %02x %02x, ioctl %02x enable %02x\n",
2052 start_low, start_high, stop_low, stop_high, ioctl, enable);
2053 }
2054 #endif
2055 }
2056
2057
2058
2059 /*
2060 * STATIC void pccbb_pcmcia_io_unmap(pcmcia_chipset_handle_t *h, int win)
2061 *
2062 * This function unmapss I/O region. No return value.
2063 */
2064 STATIC void
2065 pccbb_pcmcia_io_unmap(pch, win)
2066 pcmcia_chipset_handle_t pch;
2067 int win;
2068 {
2069 struct pcic_handle *ph = (struct pcic_handle *)pch;
2070 int reg;
2071
2072 if (win >= PCIC_IO_WINS || win < 0) {
2073 panic("pccbb_pcmcia_io_unmap: window out of range");
2074 }
2075
2076 reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
2077 switch (win) {
2078 case 0:
2079 reg &= ~PCIC_ADDRWIN_ENABLE_IO0;
2080 break;
2081 case 1:
2082 reg &= ~PCIC_ADDRWIN_ENABLE_IO1;
2083 break;
2084 }
2085 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg);
2086
2087 ph->ioalloc &= ~(1 << win);
2088 }
2089
2090
2091
2092
2093
2094 /*
2095 * static void pccbb_pcmcia_wait_ready(struct pcic_handle *ph)
2096 *
2097 * This function enables the card. All information is stored in
2098 * the first argument, pcmcia_chipset_handle_t.
2099 */
2100 static void
2101 pccbb_pcmcia_wait_ready(ph)
2102 struct pcic_handle *ph;
2103 {
2104 int i;
2105
2106 DPRINTF(("pccbb_pcmcia_wait_ready: status 0x%02x\n",
2107 Pcic_read(ph, PCIC_IF_STATUS)));
2108
2109 for (i = 0; i < 10000; i++) {
2110 if (Pcic_read(ph, PCIC_IF_STATUS) & PCIC_IF_STATUS_READY) {
2111 return;
2112 }
2113 delay(500);
2114 #ifdef CBB_DEBUG
2115 if ((i > 5000) && (i%100 == 99))
2116 printf(".");
2117 #endif
2118 }
2119
2120 #ifdef DIAGNOSTIC
2121 printf("pcic_wait_ready: ready never happened, status = %02x\n",
2122 Pcic_read(ph, PCIC_IF_STATUS));
2123 #endif
2124 }
2125
2126
2127
2128 /*
2129 * STATIC void pccbb_pcmcia_socket_enable(pcmcia_chipset_handle_t pch)
2130 *
2131 * This function enables the card. All information is stored in
2132 * the first argument, pcmcia_chipset_handle_t.
2133 */
2134 STATIC void
2135 pccbb_pcmcia_socket_enable(pch)
2136 pcmcia_chipset_handle_t pch;
2137 {
2138 struct pcic_handle *ph = (struct pcic_handle *)pch;
2139 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2140 int cardtype, win;
2141 u_int8_t power, intr;
2142 pcireg_t spsr;
2143 int voltage;
2144 #define PCIC_INTR_PCI PCIC_INTR_ENABLE
2145
2146 /* this bit is mostly stolen from pcic_attach_card */
2147
2148 DPRINTF(("pccbb_pcmcia_socket_enable: "));
2149
2150 /* get card Vcc info */
2151
2152 spsr = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_STAT);
2153 if (spsr & CB_SOCKET_STAT_5VCARD) {
2154 DPRINTF(("5V card\n"));
2155 voltage = CARDBUS_VCC_5V | CARDBUS_VPP_VCC;
2156 } else if (spsr & CB_SOCKET_STAT_3VCARD) {
2157 DPRINTF(("3V card\n"));
2158 voltage = CARDBUS_VCC_3V | CARDBUS_VPP_VCC;
2159 } else {
2160 printf("?V card, 0x%x\n", spsr); /* XXX */
2161 return;
2162 }
2163
2164 /* assert reset bit */
2165 intr = Pcic_read(ph, PCIC_INTR);
2166 intr &= ~(PCIC_INTR_RESET|PCIC_INTR_ENABLE|PCIC_INTR_CARDTYPE_MASK);
2167 Pcic_write(ph, PCIC_INTR, intr);
2168
2169 /* disable socket i/o: negate output enable bit */
2170
2171 power = Pcic_read(ph, PCIC_PWRCTL);
2172 power &= ~PCIC_PWRCTL_OE;
2173 Pcic_write(ph, PCIC_PWRCTL, power);
2174
2175 /* power down the socket to reset it, clear the card reset pin */
2176
2177 pccbb_power(sc, CARDBUS_VCC_0V | CARDBUS_VPP_0V);
2178
2179 /*
2180 * wait 200ms until power fails (Tpf). Then, wait 100ms since
2181 * we are changing Vcc (Toff).
2182 */
2183 /* delay(300*1000); too much */
2184
2185 /* power up the socket */
2186 pccbb_power(sc, voltage);
2187
2188 /*
2189 * wait 100ms until power raise (Tpr) and 20ms to become
2190 * stable (Tsu(Vcc)).
2191 *
2192 * some machines require some more time to be settled
2193 * (another 200ms is added here).
2194 */
2195 /* delay((100 + 20 + 200)*1000); too much */
2196
2197 power = Pcic_read(ph, PCIC_PWRCTL);
2198 power |= PCIC_PWRCTL_OE;
2199 Pcic_write(ph, PCIC_PWRCTL, power);
2200
2201 /*
2202 * hold RESET at least 10us.
2203 */
2204 delay(10);
2205 delay(2*1000); /* XXX: TI1130 requires it. */
2206 delay(20*1000); /* XXX: TI1130 requires it. */
2207
2208 /* clear the reset flag */
2209
2210 intr |= PCIC_INTR_RESET;
2211 Pcic_write(ph, PCIC_INTR, intr);
2212
2213 /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
2214
2215 delay(20000);
2216
2217 /* wait for the chip to finish initializing */
2218
2219 pccbb_pcmcia_wait_ready(ph);
2220
2221 /* zero out the address windows */
2222
2223 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, 0);
2224
2225 /* set the card type */
2226
2227 cardtype = pcmcia_card_gettype(ph->pcmcia);
2228
2229 intr |= PCIC_INTR_PCI;
2230 intr |= ((cardtype == PCMCIA_IFTYPE_IO) ?
2231 PCIC_INTR_CARDTYPE_IO :
2232 PCIC_INTR_CARDTYPE_MEM);
2233 Pcic_write(ph, PCIC_INTR, intr);
2234
2235 DPRINTF(("%s: pccbb_pcmcia_socket_enable %02x cardtype %s %02x\n",
2236 ph->ph_parent->dv_xname, ph->sock,
2237 ((cardtype == PCMCIA_IFTYPE_IO) ? "io" : "mem"), intr));
2238
2239 /* reinstall all the memory and io mappings */
2240
2241 for (win = 0; win < PCIC_MEM_WINS; ++win) {
2242 if (ph->memalloc & (1 << win)) {
2243 pccbb_pcmcia_do_mem_map(ph, win);
2244 }
2245 }
2246
2247 for (win = 0; win < PCIC_IO_WINS; ++win) {
2248 if (ph->ioalloc & (1 << win)) {
2249 pccbb_pcmcia_do_io_map(ph, win);
2250 }
2251 }
2252 }
2253
2254
2255
2256 /*
2257 * STATIC void pccbb_pcmcia_socket_disable(pcmcia_chipset_handle_t *ph)
2258 *
2259 * This function disables the card. All information is stored in
2260 * the first argument, pcmcia_chipset_handle_t.
2261 */
2262 STATIC void
2263 pccbb_pcmcia_socket_disable(pch)
2264 pcmcia_chipset_handle_t pch;
2265 {
2266 struct pcic_handle *ph = (struct pcic_handle *)pch;
2267 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2268 u_int8_t power, intr;
2269
2270 DPRINTF(("pccbb_pcmcia_socket_disable\n"));
2271
2272 /* reset signal asserting... */
2273
2274 intr = Pcic_read(ph, PCIC_INTR);
2275 intr &= ~(PCIC_INTR_RESET|PCIC_INTR_ENABLE|PCIC_INTR_CARDTYPE_MASK);
2276 Pcic_write(ph, PCIC_INTR, intr);
2277 delay(2*1000);
2278
2279 /* power down the socket */
2280 power = Pcic_read(ph, PCIC_PWRCTL);
2281 power &= ~PCIC_PWRCTL_OE;
2282 Pcic_write(ph, PCIC_PWRCTL, power);
2283 pccbb_power(sc, CARDBUS_VCC_0V | CARDBUS_VPP_0V);
2284 /*
2285 * wait 300ms until power fails (Tpf).
2286 */
2287 delay(300 * 1000);
2288 }
2289
2290
2291
2292 /*
2293 * STATIC int pccbb_pcmcia_card_detect(pcmcia_chipset_handle_t *ph)
2294 *
2295 * This function detects whether a card is in the slot or not.
2296 * If a card is inserted, return 1. Otherwise, return 0.
2297 */
2298 STATIC int
2299 pccbb_pcmcia_card_detect(pch)
2300 pcmcia_chipset_handle_t pch;
2301 {
2302 struct pcic_handle *ph = (struct pcic_handle *)pch;
2303 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2304
2305 DPRINTF(("pccbb_pcmcia_card_detect\n"));
2306 return pccbb_detect_card(sc) == 1 ? 1 : 0;
2307 }
2308
2309
2310
2311 #if 0
2312 STATIC int
2313 pccbb_new_pcmcia_mem_alloc(pcmcia_chipset_handle_t pch,
2314 bus_addr_t start, bus_size_t size,
2315 bus_size_t align,
2316 int speed, int flags, /* bus width */
2317 bus_space_tag_t *memtp
2318 bus_space_handle_t *memhp)
2319 #endif
2320
2321
2322 /*
2323 * STATIC int pccbb_pcmcia_mem_alloc(pcmcia_chipset_handle_t pch,
2324 * bus_size_t size,
2325 * struct pcmcia_mem_handle *pcmhp)
2326 *
2327 * This function only allocates memory region for pccard. This
2328 * function never maps the allcated region to pccard memory area.
2329 *
2330 * XXX: Why the argument of start address is not in?
2331 */
2332 STATIC int
2333 pccbb_pcmcia_mem_alloc(pch, size, pcmhp)
2334 pcmcia_chipset_handle_t pch;
2335 bus_size_t size;
2336 struct pcmcia_mem_handle *pcmhp;
2337 {
2338 struct pcic_handle *ph = (struct pcic_handle *)pch;
2339 bus_space_handle_t memh;
2340 bus_addr_t addr;
2341 bus_size_t sizepg;
2342 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2343 #if rbus
2344 rbus_tag_t rb;
2345 #endif
2346
2347 /* out of sc->memh, allocate as many pages as necessary */
2348
2349 /* convert size to PCIC pages */
2350 /*
2351 This is not enough; when the requested region is on the
2352 page boundaries, this may calculate wrong result.
2353 */
2354 sizepg = (size + (PCIC_MEM_PAGESIZE - 1)) / PCIC_MEM_PAGESIZE;
2355 #if 0
2356 if (sizepg > PCIC_MAX_MEM_PAGES) {
2357 return 1;
2358 }
2359 #endif
2360
2361 if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32)) {
2362 return 1;
2363 }
2364
2365 addr = 0; /* XXX gcc -Wuninitialized */
2366
2367 #if rbus
2368 rb = sc->sc_rbus_memt;
2369 if (rbus_space_alloc(rb, 0, sizepg*PCIC_MEM_PAGESIZE,
2370 sizepg*PCIC_MEM_PAGESIZE - 1, PCIC_MEM_PAGESIZE,
2371 0, &addr, &memh)) {
2372 return 1;
2373 }
2374
2375 #else
2376 if (bus_space_alloc(sc->sc_memt, sc->sc_mem_start, sc->sc_mem_end,
2377 sizepg*PCIC_MEM_PAGESIZE, PCIC_MEM_PAGESIZE,
2378 0 /* boundary */, 0 /* flags */,
2379 &addr, &memh)) {
2380 return 1;
2381 }
2382 #endif
2383
2384 DPRINTF(("pccbb_pcmcia_alloc_mem: addr 0x%lx size 0x%lx, realsize 0x%lx\n",
2385 addr, size, sizepg*PCIC_MEM_PAGESIZE));
2386
2387 pcmhp->memt = sc->sc_memt;
2388 pcmhp->memh = memh;
2389 pcmhp->addr = addr;
2390 pcmhp->size = size;
2391 pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE;
2392 /* What is mhandle? I feel it is very dirty and it must go trush. */
2393 pcmhp->mhandle = 0;
2394 /* No offset??? Funny. */
2395
2396 return 0;
2397 }
2398
2399
2400
2401
2402 /*
2403 * STATIC void pccbb_pcmcia_mem_free(pcmcia_chipset_handle_t pch,
2404 * struct pcmcia_mem_handle *pcmhp)
2405 *
2406 * This function release the memory space allocated by the fuction
2407 * pccbb_pcmcia_mem_alloc().
2408 */
2409 STATIC void
2410 pccbb_pcmcia_mem_free(pch, pcmhp)
2411 pcmcia_chipset_handle_t pch;
2412 struct pcmcia_mem_handle *pcmhp;
2413 {
2414 #if rbus
2415 struct pcic_handle *ph = (struct pcic_handle *)pch;
2416 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2417
2418 rbus_space_free(sc->sc_rbus_memt, pcmhp->memh, pcmhp->realsize, NULL);
2419 #else
2420 bus_space_free(pcmhp->memt, pcmhp->memh, pcmhp->realsize);
2421 #endif
2422 }
2423
2424
2425
2426
2427 /*
2428 * STATIC void pccbb_pcmcia_do_mem_map(struct pcic_handle *ph, int win)
2429 *
2430 * This function release the memory space allocated by the fuction
2431 * pccbb_pcmcia_mem_alloc().
2432 */
2433 STATIC void
2434 pccbb_pcmcia_do_mem_map(ph, win)
2435 struct pcic_handle *ph;
2436 int win;
2437 {
2438 int regbase_win;
2439 bus_addr_t phys_addr;
2440 bus_addr_t phys_end;
2441
2442 #define PCIC_SMM_START_LOW 0
2443 #define PCIC_SMM_START_HIGH 1
2444 #define PCIC_SMM_STOP_LOW 2
2445 #define PCIC_SMM_STOP_HIGH 3
2446 #define PCIC_CMA_LOW 4
2447 #define PCIC_CMA_HIGH 5
2448
2449 u_int8_t start_low, start_high = 0;
2450 u_int8_t stop_low, stop_high;
2451 u_int8_t off_low, off_high;
2452 u_int8_t mem_window;
2453 int reg;
2454
2455 int kind = ph->mem[win].kind & ~PCMCIA_WIDTH_MEM_MASK;
2456 int mem8 = (ph->mem[win].kind & PCMCIA_WIDTH_MEM_MASK) == PCMCIA_WIDTH_MEM8;
2457
2458 regbase_win = 0x10 + win*0x08;
2459
2460 phys_addr = ph->mem[win].addr;
2461 phys_end = phys_addr + ph->mem[win].size;
2462
2463 DPRINTF(("pccbb_pcmcia_do_mem_map: start 0x%lx end 0x%lx off 0x%lx\n",
2464 phys_addr, phys_end, ph->mem[win].offset));
2465
2466 #define PCIC_MEMREG_LSB_SHIFT PCIC_SYSMEM_ADDRX_SHIFT
2467 #define PCIC_MEMREG_MSB_SHIFT (PCIC_SYSMEM_ADDRX_SHIFT + 8)
2468 #define PCIC_MEMREG_WIN_SHIFT (PCIC_SYSMEM_ADDRX_SHIFT + 12)
2469
2470 start_low = (phys_addr >> PCIC_MEMREG_LSB_SHIFT) & 0xff; /* bit 19:12 */
2471 start_high = ((phys_addr >> PCIC_MEMREG_MSB_SHIFT) & 0x0f) /* bit 23:20 */
2472 | (mem8 ? 0 : PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT); /* bit 7 on */
2473 /* bit 31:24, for 32-bit address */
2474 mem_window = (phys_addr >> PCIC_MEMREG_WIN_SHIFT) & 0xff; /* bit 31:24 */
2475
2476 Pcic_write(ph, regbase_win + PCIC_SMM_START_LOW, start_low);
2477 Pcic_write(ph, regbase_win + PCIC_SMM_START_HIGH, start_high);
2478
2479 if (((struct pccbb_softc *)ph->ph_parent)->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32) {
2480 Pcic_write(ph, 0x40 + win, mem_window);
2481 }
2482
2483 stop_low = (phys_end >> PCIC_MEMREG_LSB_SHIFT) & 0xff;
2484 stop_high = ((phys_end >> PCIC_MEMREG_MSB_SHIFT) & 0x0f)
2485 | PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2; /* wait 2 cycles */
2486 /* XXX Geee, WAIT2!! Crazy!! I must rewrite this routine. */
2487
2488 Pcic_write(ph, regbase_win + PCIC_SMM_STOP_LOW, stop_low);
2489 Pcic_write(ph, regbase_win + PCIC_SMM_STOP_HIGH, stop_high);
2490
2491 off_low = (ph->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff;
2492 off_high = ((ph->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8))
2493 & PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK)
2494 | ((kind == PCMCIA_MEM_ATTR) ?
2495 PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0);
2496
2497 Pcic_write(ph, regbase_win + PCIC_CMA_LOW, off_low);
2498 Pcic_write(ph, regbase_win + PCIC_CMA_HIGH, off_high);
2499
2500 reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
2501 reg |= ((1 << win) | PCIC_ADDRWIN_ENABLE_MEMCS16);
2502 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg);
2503
2504 #if defined CBB_DEBUG
2505 {
2506 int r1, r2, r3, r4, r5, r6, r7 = 0;
2507
2508 r1 = Pcic_read(ph, regbase_win + PCIC_SMM_START_LOW);
2509 r2 = Pcic_read(ph, regbase_win + PCIC_SMM_START_HIGH);
2510 r3 = Pcic_read(ph, regbase_win + PCIC_SMM_STOP_LOW);
2511 r4 = Pcic_read(ph, regbase_win + PCIC_SMM_STOP_HIGH);
2512 r5 = Pcic_read(ph, regbase_win + PCIC_CMA_LOW);
2513 r6 = Pcic_read(ph, regbase_win + PCIC_CMA_HIGH);
2514 if (((struct pccbb_softc *)(ph->ph_parent))->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32) {
2515 r7 = Pcic_read(ph, 0x40 + win);
2516 }
2517
2518 DPRINTF(("pccbb_pcmcia_do_mem_map window %d: %02x%02x %02x%02x "
2519 "%02x%02x", win, r1, r2, r3, r4, r5, r6));
2520 if (((struct pccbb_softc *)(ph->ph_parent))->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32) {
2521 DPRINTF((" %02x",r7));
2522 }
2523 DPRINTF(("\n"));
2524 }
2525 #endif
2526 }
2527
2528
2529
2530
2531 /*
2532 * STATIC int pccbb_pcmcia_mem_map(pcmcia_chipset_handle_t pch, int kind,
2533 * bus_addr_t card_addr, bus_size_t size,
2534 * struct pcmcia_mem_handle *pcmhp,
2535 * bus_addr_t *offsetp, int *windowp)
2536 *
2537 * This function maps memory space allocated by the fuction
2538 * pccbb_pcmcia_mem_alloc().
2539 */
2540 STATIC int
2541 pccbb_pcmcia_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
2542 pcmcia_chipset_handle_t pch;
2543 int kind;
2544 bus_addr_t card_addr;
2545 bus_size_t size;
2546 struct pcmcia_mem_handle *pcmhp;
2547 bus_addr_t *offsetp;
2548 int *windowp;
2549 {
2550 struct pcic_handle *ph = (struct pcic_handle *)pch;
2551 bus_addr_t busaddr;
2552 long card_offset;
2553 int win;
2554
2555 for (win = 0; win < PCIC_MEM_WINS; ++win) {
2556 if ((ph->memalloc & (1 << win)) == 0) {
2557 ph->memalloc |= (1 << win);
2558 break;
2559 }
2560 }
2561
2562 if (win == PCIC_MEM_WINS) {
2563 return 1;
2564 }
2565
2566 *windowp = win;
2567
2568 /* XXX this is pretty gross */
2569
2570 if (((struct pccbb_softc *)ph->ph_parent)->sc_memt != pcmhp->memt) {
2571 panic("pccbb_pcmcia_mem_map memt is bogus");
2572 }
2573
2574 busaddr = pcmhp->addr;
2575
2576 /*
2577 * compute the address offset to the pcmcia address space for the
2578 * pcic. this is intentionally signed. The masks and shifts below
2579 * will cause TRT to happen in the pcic registers. Deal with making
2580 * sure the address is aligned, and return the alignment offset.
2581 */
2582
2583 *offsetp = card_addr % PCIC_MEM_PAGESIZE;
2584 card_addr -= *offsetp;
2585
2586 DPRINTF(("pccbb_pcmcia_mem_map window %d bus %lx+%lx+%lx at card addr "
2587 "%lx\n", win, (u_long)busaddr, (u_long)*offsetp, (u_long)size,
2588 (u_long)card_addr));
2589
2590 /*
2591 * include the offset in the size, and decrement size by one, since
2592 * the hw wants start/stop
2593 */
2594 size += *offsetp - 1;
2595
2596 card_offset = (((long) card_addr) - ((long) busaddr));
2597
2598 ph->mem[win].addr = busaddr;
2599 ph->mem[win].size = size;
2600 ph->mem[win].offset = card_offset;
2601 ph->mem[win].kind = kind;
2602
2603 pccbb_pcmcia_do_mem_map(ph, win);
2604
2605 return 0;
2606 }
2607
2608
2609
2610 /*
2611 * STATIC int pccbb_pcmcia_mem_unmap(pcmcia_chipset_handle_t pch,
2612 * int window)
2613 *
2614 * This function unmaps memory space which mapped by the fuction
2615 * pccbb_pcmcia_mem_map().
2616 */
2617 STATIC void
2618 pccbb_pcmcia_mem_unmap(pch, window)
2619 pcmcia_chipset_handle_t pch;
2620 int window;
2621 {
2622 struct pcic_handle *ph = (struct pcic_handle *)pch;
2623 int reg;
2624
2625 if (window >= PCIC_MEM_WINS) {
2626 panic("pccbb_pcmcia_mem_unmap: window out of range");
2627 }
2628
2629 reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
2630 reg &= ~(1 << window);
2631 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg);
2632
2633 ph->memalloc &= ~(1 << window);
2634 }
2635
2636
2637
2638 #if defined PCCBB_PCMCIA_POLL
2639 struct pccbb_poll_str {
2640 void *arg;
2641 int (* func) __P((void *));
2642 int level;
2643 struct pcic_handle *ph;
2644 int count;
2645 int num;
2646 };
2647
2648 static struct pccbb_poll_str pccbb_poll[10];
2649 static int pccbb_poll_n = 0;
2650
2651 static void pccbb_pcmcia_poll __P((void *arg));
2652
2653 static void
2654 pccbb_pcmcia_poll(arg)
2655 void *arg;
2656 {
2657 struct pccbb_poll_str *poll = arg;
2658 struct pcic_handle *ph = poll->ph;
2659 struct pccbb_softc *sc = ph->sc;
2660 int s;
2661 u_int32_t spsr; /* socket present-state reg */
2662
2663 timeout(pccbb_pcmcia_poll, arg, hz*2);
2664 switch (poll->level) {
2665 case IPL_NET:
2666 s = splnet();
2667 break;
2668 case IPL_BIO:
2669 s = splbio();
2670 break;
2671 case IPL_TTY: /* fallthrough */
2672 default:
2673 s = spltty();
2674 break;
2675 }
2676
2677 spsr = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_STAT);
2678
2679 #if defined PCCBB_PCMCIA_POLL_ONLY && defined LEVEL2
2680 if (!(spsr & 0x40)) /* CINT low */
2681 #else
2682 if (1)
2683 #endif
2684 {
2685 if ((*poll->func)(poll->arg) > 0) {
2686 ++poll->count;
2687 // printf("intr: reported from poller, 0x%x\n", spsr);
2688 #if defined LEVEL2
2689 } else {
2690 printf("intr: miss! 0x%x\n", spsr);
2691 #endif
2692 }
2693 }
2694 splx(s);
2695 }
2696 #endif /* defined CB_PCMCIA_POLL */
2697
2698
2699
2700 /*
2701 * STATIC void *pccbb_pcmcia_intr_establish(pcmcia_chipset_handle_t pch,
2702 * struct pcmcia_function *pf,
2703 * int ipl,
2704 * int (*func)(void *),
2705 * void *arg);
2706 *
2707 * This function enables PC-Card interrupt. PCCBB uses PCI interrupt line.
2708 */
2709 STATIC void *
2710 pccbb_pcmcia_intr_establish(pch, pf, ipl, func, arg)
2711 pcmcia_chipset_handle_t pch;
2712 struct pcmcia_function *pf;
2713 int ipl;
2714 int (*func) __P((void *));
2715 void *arg;
2716 {
2717 struct pcic_handle *ph = (struct pcic_handle *)pch;
2718 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2719 pci_intr_handle_t handle;
2720 void *ih;
2721
2722 if (!(pf->cfe->flags & PCMCIA_CFE_IRQLEVEL)) {
2723 /* what should I do? */
2724 if ((pf->cfe->flags & PCMCIA_CFE_IRQLEVEL)) {
2725 DPRINTF(("%s does not provide edge nor pulse interrupt\n",
2726 sc->sc_dev.dv_xname));
2727 return NULL;
2728 }
2729 /*
2730 * XXX Noooooo! The interrupt flag must set properly!!
2731 * dumb pcmcia driver!!
2732 */
2733 }
2734
2735 if (pci_intr_map(sc->sc_pc, sc->sc_intrtag, sc->sc_intrpin,
2736 sc->sc_intrline, &handle)) {
2737 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
2738 return NULL;
2739 }
2740 DPRINTF(("pccbb_pcmcia_intr_establish: line %d, handle %d\n",
2741 sc->sc_intrline, handle));
2742
2743 if (NULL != (ih = pci_intr_establish(sc->sc_pc, handle, ipl, func, arg)))
2744 {
2745 u_int32_t cbctrl;
2746
2747 if ((CB_TI113X == sc->sc_chipset)) {
2748 cbctrl = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL);
2749 cbctrl |= PCI113X_CBCTRL_PCI_INTR; /* PCI functional intr req */
2750 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL, cbctrl);
2751 }
2752 }
2753 #if defined PCCBB_PCMCIA_POLL
2754 if (pccbb_poll_n < 10) {
2755 pccbb_poll[pccbb_poll_n].arg = arg;
2756 pccbb_poll[pccbb_poll_n].func = func;
2757 pccbb_poll[pccbb_poll_n].level = ipl;
2758 pccbb_poll[pccbb_poll_n].count = 0;
2759 pccbb_poll[pccbb_poll_n].num = pccbb_poll_n;
2760 pccbb_poll[pccbb_poll_n].ph = ph;
2761 timeout(pccbb_pcmcia_poll, &pccbb_poll[pccbb_poll_n++], hz*2);
2762 printf("polling set\n");
2763 }
2764 #endif
2765 #if defined SHOW_REGS
2766 cb_show_regs(sc->sc_pc, sc->sc_tag, sc->sc_base_memt, sc->sc_base_memh);
2767 #endif
2768
2769 return ih;
2770 }
2771
2772
2773
2774
2775 /*
2776 * STATIC void pccbb_pcmcia_intr_disestablish(pcmcia_chipset_handle_t pch,
2777 * void *ih)
2778 *
2779 * This function disables PC-Card interrupt.
2780 */
2781 STATIC void
2782 pccbb_pcmcia_intr_disestablish(pch, ih)
2783 pcmcia_chipset_handle_t pch;
2784 void *ih;
2785 {
2786 struct pcic_handle *ph = (struct pcic_handle *)pch;
2787 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2788
2789 pci_intr_disestablish(sc->sc_pc, ih);
2790 }
2791
2792
2793
2794
2795 #if rbus
2796 /*
2797 * static int
2798 * pccbb_rbus_cb_space_alloc(cardbus_chipset_tag_t ct, rbus_tag_t rb,
2799 * bus_addr_t addr, bus_size_t size,
2800 * bus_addr_t mask, bus_size_t align,
2801 * int flags, bus_addr_t *addrp;
2802 * bus_space_handle_t *bshp)
2803 *
2804 * This function allocates a portion of memory or io space for
2805 * clients. This function is called from CardBus card drivers.
2806 */
2807 static int
2808 pccbb_rbus_cb_space_alloc(ct, rb, addr, size, mask, align, flags, addrp, bshp)
2809 cardbus_chipset_tag_t ct;
2810 rbus_tag_t rb;
2811 bus_addr_t addr;
2812 bus_size_t size;
2813 bus_addr_t mask;
2814 bus_size_t align;
2815 int flags;
2816 bus_addr_t *addrp;
2817 bus_space_handle_t *bshp;
2818 {
2819 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
2820
2821 DPRINTF(("pccbb_rbus_cb_space_alloc: adr %lx, size %lx, mask %lx, align %lx\n", addr, size, mask, align));
2822
2823 if (align == 0) {
2824 align = size;
2825 }
2826
2827 if (rb->rb_bt == sc->sc_memt) {
2828 if (align < 16) {
2829 return 1;
2830 }
2831 } else if (rb->rb_bt == sc->sc_iot) {
2832 if (align < 4) {
2833 return 1;
2834 }
2835 } else {
2836 DPRINTF(("pccbb_rbus_cb_space_alloc: Bus space tag %x is NOT used.\n",
2837 rb->rb_bt));
2838 return 1;
2839 /* XXX: panic here? */
2840 }
2841
2842 /* XXX: hack for avoiding ISA image */
2843 if (mask < 0x3ff) {
2844 mask = 0x3ff;
2845 addr = 0x300;
2846 }
2847
2848 if (rbus_space_alloc(rb, addr, size, mask, align, flags, addrp, bshp)) {
2849 printf("%s: <rbus> no bus space\n", sc->sc_dev.dv_xname);
2850 return 1;
2851 }
2852
2853 pccbb_open_win(sc, rb->rb_bt, *addrp, size, *bshp, 0);
2854
2855 return 0;
2856 }
2857
2858
2859
2860
2861
2862 /*
2863 * static int
2864 * pccbb_rbus_cb_space_free(cardbus_chipset_tag_t *ct, rbus_tag_t rb,
2865 * bus_space_handle_t *bshp, bus_size_t size);
2866 *
2867 * This function is called from CardBus card drivers.
2868 */
2869 static int
2870 pccbb_rbus_cb_space_free(ct, rb, bsh, size)
2871 cardbus_chipset_tag_t ct;
2872 rbus_tag_t rb;
2873 bus_space_handle_t bsh;
2874 bus_size_t size;
2875 {
2876 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
2877 bus_space_tag_t bt = rb->rb_bt;
2878
2879 pccbb_close_win(sc, bt, bsh, size);
2880
2881 if (bt == sc->sc_memt) {
2882 } else if (bt == sc->sc_iot) {
2883 } else {
2884 return 1;
2885 /* XXX: panic here? */
2886 }
2887
2888 return rbus_space_free(rb, bsh, size, NULL);
2889 }
2890 #endif /* rbus */
2891
2892
2893 #if rbus
2894
2895 static int
2896 pccbb_open_win(sc, bst, addr, size, bsh, flags)
2897 struct pccbb_softc *sc;
2898 bus_space_tag_t bst;
2899 bus_addr_t addr;
2900 bus_size_t size;
2901 bus_space_handle_t bsh;
2902 int flags;
2903 {
2904 struct pccbb_win_chain **top;
2905 bus_addr_t align;
2906
2907 top = &sc->sc_iowindow;
2908 align = 0x04;
2909 if (sc->sc_memt == bst) {
2910 top = &sc->sc_memwindow;
2911 align = 0x1000;
2912 DPRINTF(("using memory window, %x %x %x\n\n",
2913 sc->sc_iot, sc->sc_memt, bst));
2914 }
2915
2916 if (pccbb_winlist_insert(top, addr, size, bsh, flags)) {
2917 printf("winlist insert fails:\n");
2918 }
2919 pccbb_winset(align, sc, bst);
2920
2921 return 0;
2922 }
2923
2924
2925
2926 static int
2927 pccbb_close_win(sc, bst, bsh, size)
2928 struct pccbb_softc *sc;
2929 bus_space_tag_t bst;
2930 bus_space_handle_t bsh;
2931 bus_size_t size;
2932 {
2933 struct pccbb_win_chain **top;
2934 bus_addr_t align;
2935
2936 top = &sc->sc_iowindow;
2937 align = 0x04;
2938 if (sc->sc_memt == bst) {
2939 top = &sc->sc_memwindow;
2940 align = 0x1000;
2941 }
2942
2943 if (pccbb_winlist_delete(top, bsh, size)) {
2944 printf("winlist delete fails:\n");
2945 }
2946 pccbb_winset(align, sc, bst);
2947
2948 return 0;
2949 }
2950
2951
2952 static int
2953 pccbb_winlist_insert(top, start, size, bsh, flags)
2954 struct pccbb_win_chain **top;
2955 bus_addr_t start;
2956 bus_size_t size;
2957 bus_space_handle_t bsh;
2958 int flags;
2959 {
2960 struct pccbb_win_chain *chainp = *top;
2961 struct pccbb_win_chain *before = *top;
2962 struct pccbb_win_chain *elem;
2963
2964 if (*top == NULL) {
2965 if (NULL == (elem = (struct pccbb_win_chain *)malloc(sizeof(struct pccbb_win_chain), M_DEVBUF, M_NOWAIT))) {
2966 return 1; /* fail */
2967 }
2968
2969 elem->wc_start = start;
2970 elem->wc_end = start + size - 1;
2971 elem->wc_handle = bsh;
2972 elem->wc_flags = flags;
2973
2974 *top = elem;
2975 elem->wc_next = NULL;
2976 return 0;
2977 }
2978
2979 for(; chainp && chainp->wc_start <= start; chainp = chainp->wc_next) {
2980 before = chainp;
2981 }
2982
2983 if (chainp != NULL) {
2984 if (chainp->wc_start < start + size) {
2985 printf("fatal! 0x%lx 0x%lx\n", chainp->wc_start, start+size);
2986 return 1;
2987 }
2988 }
2989 if ((before != *top) && (before->wc_end >= start)) {
2990 printf("fatal!! 0x%lx 0x%lx\n", before->wc_end, start);
2991 return 1;
2992 }
2993
2994 if (NULL == (elem = (struct pccbb_win_chain *)malloc(sizeof(struct pccbb_win_chain), M_DEVBUF, M_NOWAIT))) {
2995 return 1; /* fail */
2996 }
2997
2998 elem->wc_start = start;
2999 elem->wc_end = start + size - 1;
3000 elem->wc_handle = bsh;
3001 elem->wc_flags = flags;
3002
3003 elem->wc_next = chainp;
3004 if (chainp == *top) {
3005 *top = elem;
3006 } else {
3007 before->wc_next = elem;
3008 }
3009 return 0;
3010 }
3011
3012
3013
3014
3015 static int
3016 pccbb_winlist_delete(top, bsh, size)
3017 struct pccbb_win_chain **top;
3018 bus_space_handle_t bsh;
3019 bus_size_t size;
3020 {
3021 struct pccbb_win_chain *chainp = *top;
3022 struct pccbb_win_chain **before = top;
3023
3024 for (; chainp && chainp->wc_handle != bsh; chainp = chainp->wc_next) {
3025 before = &chainp->wc_next;
3026 }
3027
3028 if (chainp == NULL) {
3029 return 1; /* fail: no candidate to remove */
3030 }
3031
3032 if (chainp->wc_end - chainp->wc_start != size - 1) {
3033 printf("fatal!!! 0x%lx\n", chainp->wc_start);
3034 return 1; /* fail: no candidate to remove */
3035 }
3036
3037 *before = chainp->wc_next;
3038 free(chainp, M_DEVBUF);
3039
3040 return 0;
3041 }
3042
3043
3044
3045 static void
3046 pccbb_winset(align, sc, bst)
3047 bus_addr_t align;
3048 struct pccbb_softc *sc;
3049 bus_space_tag_t bst;
3050 {
3051 pci_chipset_tag_t pc;
3052 pcitag_t tag;
3053 bus_addr_t mask = ~(align - 1);
3054 struct {
3055 cardbusreg_t win_start;
3056 cardbusreg_t win_limit;
3057 int win_flags;
3058 } win[2];
3059 struct pccbb_win_chain *chainp;
3060 int offs;
3061
3062 win[0].win_start = 0xffffffff;
3063 win[0].win_limit = 0;
3064 win[1].win_start = 0xffffffff;
3065 win[1].win_limit = 0;
3066
3067 chainp = sc->sc_iowindow;
3068 offs = 0x2c;
3069 if (sc->sc_memt == bst) {
3070 chainp = sc->sc_memwindow;
3071 offs = 0x1c;
3072 }
3073
3074 if (chainp) {
3075 win[0].win_start = chainp->wc_start & mask;
3076 win[0].win_limit = chainp->wc_end & mask;
3077 win[0].win_flags = chainp->wc_flags;
3078 chainp = chainp->wc_next;
3079 }
3080
3081 for(; chainp; chainp = chainp->wc_next) {
3082 if (win[1].win_start == 0xffffffff) {
3083 /* window 1 is not used */
3084 if ((win[0].win_flags == chainp->wc_flags) &&
3085 (win[0].win_limit + align >= (chainp->wc_start & mask))) {
3086 /* concatinate */
3087 win[0].win_limit = chainp->wc_end & mask;
3088 } else {
3089 /* make new window */
3090 win[1].win_start = chainp->wc_start & mask;
3091 win[1].win_limit = chainp->wc_end & mask;
3092 win[1].win_flags = chainp->wc_flags;
3093 }
3094 continue;
3095 }
3096
3097 /* Both windows are engagad. */
3098 if (win[0].win_flags == win[1].win_flags) {
3099 /* same flags */
3100 if (win[0].win_flags == chainp->wc_flags) {
3101 if (win[1].win_start - (win[0].win_limit + align)
3102 < (chainp->wc_start & mask) - ((chainp->wc_end & mask) + align)) {
3103 /* merge window 0 and 1, and set win1 to chainp */
3104 win[0].win_limit = win[1].win_limit;
3105 win[1].win_start = chainp->wc_start & mask;
3106 win[1].win_limit = chainp->wc_end & mask;
3107 } else {
3108 win[1].win_limit = chainp->wc_end & mask;
3109 }
3110 } else {
3111 /* different flags */
3112
3113 /* concatinate win0 and win1 */
3114 win[0].win_limit = win[1].win_limit;
3115 /* allocate win[1] to new space */
3116 win[1].win_start = chainp->wc_start & mask;
3117 win[1].win_limit = chainp->wc_end & mask;
3118 win[1].win_flags = chainp->wc_flags;
3119 }
3120 } else {
3121 /* the flags of win[0] and win[1] is different */
3122 if (win[0].win_flags == chainp->wc_flags) {
3123 win[0].win_limit = chainp->wc_end & mask;
3124 /* XXX this creates overlapping windows, so what should the
3125 poor bridge do if one is cachable, and the other is not? */
3126 printf("%s: overlapping windows\n", sc->sc_dev.dv_xname);
3127 } else {
3128 win[1].win_limit = chainp->wc_end & mask;
3129 }
3130 }
3131 }
3132
3133 pc = sc->sc_pc;
3134 tag = sc->sc_tag;
3135 pci_conf_write(pc, tag, offs, win[0].win_start);
3136 pci_conf_write(pc, tag, offs+4, win[0].win_limit);
3137 pci_conf_write(pc, tag, offs+8, win[1].win_start);
3138 pci_conf_write(pc, tag, offs+12, win[1].win_limit);
3139 DPRINTF(("--pccbb_winset: win0 [%x, %lx), win1 [%x, %lx)\n",
3140 pci_conf_read(pc, tag, offs),
3141 pci_conf_read(pc, tag, offs+4) + align,
3142 pci_conf_read(pc, tag, offs+8),
3143 pci_conf_read(pc, tag, offs+12) + align));
3144
3145 if (bst == sc->sc_memt) {
3146 if (win[0].win_flags & PCCBB_MEM_CACHABLE) {
3147 pcireg_t bcr = pci_conf_read(pc, tag, PCI_BCR_INTR);
3148 bcr |= CB_BCR_PREFETCH_MEMWIN0;
3149 pci_conf_write(pc,tag, PCI_BCR_INTR, bcr);
3150 }
3151 if (win[1].win_flags & PCCBB_MEM_CACHABLE) {
3152 pcireg_t bcr = pci_conf_read(pc, tag, PCI_BCR_INTR);
3153 bcr |= CB_BCR_PREFETCH_MEMWIN1;
3154 pci_conf_write(pc,tag, PCI_BCR_INTR, bcr);
3155 }
3156 }
3157 }
3158
3159 #endif /* rbus */
3160