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