]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/pccbb/pccbb.c
Use a cv rather than tsleep and friends to do the sleep/wakeup
[FreeBSD/FreeBSD.git] / sys / dev / pccbb / pccbb.c
1 /*
2  * Copyright (c) 2000,2001 Jonathan Chen.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions, and the following disclaimer,
10  *    without modification, immediately at the beginning of the file.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in
13  *    the documentation and/or other materials provided with the
14  *    distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30
31 /*
32  * Copyright (c) 1998, 1999 and 2000
33  *      HAYAKAWA Koichi.  All rights reserved.
34  *
35  * Redistribution and use in source and binary forms, with or without
36  * modification, are permitted provided that the following conditions
37  * are met:
38  * 1. Redistributions of source code must retain the above copyright
39  *    notice, this list of conditions and the following disclaimer.
40  * 2. Redistributions in binary form must reproduce the above copyright
41  *    notice, this list of conditions and the following disclaimer in the
42  *    documentation and/or other materials provided with the distribution.
43  * 3. All advertising materials mentioning features or use of this software
44  *    must display the following acknowledgement:
45  *      This product includes software developed by HAYAKAWA Koichi.
46  * 4. The name of the author may not be used to endorse or promote products
47  *    derived from this software without specific prior written permission.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
50  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
51  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
52  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
53  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
54  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
55  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
56  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
57  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
58  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59  */
60
61 /*
62  * Driver for PCI to Cardbus Bridge chips
63  *
64  * References:
65  *  TI Datasheets:
66  *   http://www-s.ti.com/cgi-bin/sc/generic2.cgi?family=PCI+CARDBUS+CONTROLLERS
67  *
68  * Written by Jonathan Chen <jon@freebsd.org>
69  * The author would like to acknowledge:
70  *  * HAYAKAWA Koichi: Author of the NetBSD code for the same thing
71  *  * Warner Losh: Newbus/newcard guru and author of the pccard side of things
72  *  * YAMAMOTO Shigeru: Author of another FreeBSD cardbus driver
73  *  * David Cross: Author of the initial ugly hack for a specific cardbus card
74  */
75
76 #include <sys/param.h>
77 #include <sys/systm.h>
78 #include <sys/proc.h>
79 #include <sys/condvar.h>
80 #include <sys/errno.h>
81 #include <sys/kernel.h>
82 #include <sys/lock.h>
83 #include <sys/malloc.h>
84 #include <sys/mutex.h>
85 #include <sys/sysctl.h>
86 #include <sys/kthread.h>
87 #include <sys/bus.h>
88 #include <machine/bus.h>
89 #include <sys/rman.h>
90 #include <machine/resource.h>
91
92 #include <pci/pcireg.h>
93 #include <pci/pcivar.h>
94 #include <machine/clock.h>
95
96 #include <dev/pccard/pccardreg.h>
97 #include <dev/pccard/pccardvar.h>
98
99 #include <dev/exca/excareg.h>
100 #include <dev/exca/excavar.h>
101
102 #include <dev/pccbb/pccbbreg.h>
103 #include <dev/pccbb/pccbbvar.h>
104
105 #include "power_if.h"
106 #include "card_if.h"
107 #include "pcib_if.h"
108
109 #define DPRINTF(x) do { if (cbb_debug) printf x; } while (0)
110 #define DEVPRINTF(x) do { if (cbb_debug) device_printf x; } while (0)
111
112 #define PCI_MASK_CONFIG(DEV,REG,MASK,SIZE)                              \
113         pci_write_config(DEV, REG, pci_read_config(DEV, REG, SIZE) MASK, SIZE)
114 #define PCI_MASK2_CONFIG(DEV,REG,MASK1,MASK2,SIZE)                      \
115         pci_write_config(DEV, REG, (                                    \
116                 pci_read_config(DEV, REG, SIZE) MASK1) MASK2, SIZE)
117
118 #define PCCBB_START_MEM 0x84000000
119 #define PCCBB_START_32_IO 0x1000
120 #define PCCBB_START_16_IO 0x100
121
122 struct yenta_chipinfo {
123         uint32_t yc_id;
124         const   char *yc_name;
125         int     yc_chiptype;
126 } yc_chipsets[] = {
127         /* Texas Instruments chips */
128         {PCI_DEVICE_ID_PCIC_TI1031, "TI1031 PCI-PC Card Bridge", CB_TI113X},
129         {PCI_DEVICE_ID_PCIC_TI1130, "TI1130 PCI-CardBus Bridge", CB_TI113X},
130         {PCI_DEVICE_ID_PCIC_TI1131, "TI1131 PCI-CardBus Bridge", CB_TI113X},
131
132         {PCI_DEVICE_ID_PCIC_TI1210, "TI1210 PCI-CardBus Bridge", CB_TI12XX},
133         {PCI_DEVICE_ID_PCIC_TI1211, "TI1211 PCI-CardBus Bridge", CB_TI12XX},
134         {PCI_DEVICE_ID_PCIC_TI1220, "TI1220 PCI-CardBus Bridge", CB_TI12XX},
135         {PCI_DEVICE_ID_PCIC_TI1221, "TI1221 PCI-CardBus Bridge", CB_TI12XX},
136         {PCI_DEVICE_ID_PCIC_TI1225, "TI1225 PCI-CardBus Bridge", CB_TI12XX},
137         {PCI_DEVICE_ID_PCIC_TI1250, "TI1250 PCI-CardBus Bridge", CB_TI12XX},
138         {PCI_DEVICE_ID_PCIC_TI1251, "TI1251 PCI-CardBus Bridge", CB_TI12XX},
139         {PCI_DEVICE_ID_PCIC_TI1251B,"TI1251B PCI-CardBus Bridge",CB_TI12XX},
140         {PCI_DEVICE_ID_PCIC_TI1260, "TI1260 PCI-CardBus Bridge", CB_TI12XX},
141         {PCI_DEVICE_ID_PCIC_TI1260B,"TI1260B PCI-CardBus Bridge",CB_TI12XX},
142         {PCI_DEVICE_ID_PCIC_TI1410, "TI1410 PCI-CardBus Bridge", CB_TI12XX},
143         {PCI_DEVICE_ID_PCIC_TI1420, "TI1420 PCI-CardBus Bridge", CB_TI12XX},
144         {PCI_DEVICE_ID_PCIC_TI1421, "TI1421 PCI-CardBus Bridge", CB_TI12XX},
145         {PCI_DEVICE_ID_PCIC_TI1450, "TI1450 PCI-CardBus Bridge", CB_TI12XX},
146         {PCI_DEVICE_ID_PCIC_TI1451, "TI1451 PCI-CardBus Bridge", CB_TI12XX},
147         {PCI_DEVICE_ID_PCIC_TI4410, "TI4410 PCI-CardBus Bridge", CB_TI12XX},
148         {PCI_DEVICE_ID_PCIC_TI4450, "TI4450 PCI-CardBus Bridge", CB_TI12XX},
149         {PCI_DEVICE_ID_PCIC_TI4451, "TI4451 PCI-CardBus Bridge", CB_TI12XX},
150
151         /* Ricoh chips */
152         {PCI_DEVICE_ID_RICOH_RL5C465, "RF5C465 PCI-CardBus Bridge",
153             CB_RF5C46X},
154         {PCI_DEVICE_ID_RICOH_RL5C466, "RF5C466 PCI-CardBus Bridge",
155             CB_RF5C46X},
156         {PCI_DEVICE_ID_RICOH_RL5C475, "RF5C475 PCI-CardBus Bridge",
157             CB_RF5C47X},
158         {PCI_DEVICE_ID_RICOH_RL5C476, "RF5C476 PCI-CardBus Bridge",
159             CB_RF5C47X},
160         {PCI_DEVICE_ID_RICOH_RL5C477, "RF5C477 PCI-CardBus Bridge",
161             CB_RF5C47X},
162         {PCI_DEVICE_ID_RICOH_RL5C478, "RF5C478 PCI-CardBus Bridge",
163             CB_RF5C47X},
164
165         /* Toshiba products */
166         {PCI_DEVICE_ID_TOSHIBA_TOPIC95, "ToPIC95 PCI-CardBus Bridge",
167             CB_TOPIC95},
168         {PCI_DEVICE_ID_TOSHIBA_TOPIC95B, "ToPIC95B PCI-CardBus Bridge",
169             CB_TOPIC95},
170         {PCI_DEVICE_ID_TOSHIBA_TOPIC97, "ToPIC97 PCI-CardBus Bridge",
171             CB_TOPIC97},
172         {PCI_DEVICE_ID_TOSHIBA_TOPIC100, "ToPIC100 PCI-CardBus Bridge",
173             CB_TOPIC97},
174
175         /* Cirrus Logic */
176         {PCI_DEVICE_ID_PCIC_CLPD6832, "CLPD6832 PCI-CardBus Bridge",
177             CB_CIRRUS},
178         {PCI_DEVICE_ID_PCIC_CLPD6833, "CLPD6833 PCI-CardBus Bridge",
179             CB_CIRRUS},
180         {PCI_DEVICE_ID_PCIC_CLPD6834, "CLPD6834 PCI-CardBus Bridge",
181             CB_CIRRUS},
182
183         /* 02Micro */
184         {PCI_DEVICE_ID_PCIC_OZ6832, "O2Mirco OZ6832/6833 PCI-CardBus Bridge",
185             CB_CIRRUS},
186         {PCI_DEVICE_ID_PCIC_OZ6860, "O2Mirco OZ6836/6860 PCI-CardBus Bridge",
187             CB_CIRRUS},
188         {PCI_DEVICE_ID_PCIC_OZ6872, "O2Mirco OZ6812/6872 PCI-CardBus Bridge",
189             CB_CIRRUS},
190         {PCI_DEVICE_ID_PCIC_OZ6912, "O2Mirco OZ6912/6972 PCI-CardBus Bridge",
191             CB_CIRRUS},
192         {PCI_DEVICE_ID_PCIC_OZ6922, "O2Mirco OZ6822 PCI-CardBus Bridge",
193             CB_CIRRUS},
194         {PCI_DEVICE_ID_PCIC_OZ6933, "O2Mirco OZ6833 PCI-CardBus Bridge",
195             CB_CIRRUS},
196
197         /* sentinel */
198         {0 /* null id */, "unknown", CB_UNKNOWN},
199 };
200
201 /* sysctl vars */
202 SYSCTL_NODE(_hw, OID_AUTO, cbb, CTLFLAG_RD, 0, "CBB parameters");
203
204 /* There's no way to say TUNEABLE_LONG to get the right types */
205 u_long pccbb_start_mem = PCCBB_START_MEM;
206 TUNABLE_INT("hw.cbb.start_memory", (int *)&pccbb_start_mem);
207 SYSCTL_ULONG(_hw_cbb, OID_AUTO, start_memory, CTLFLAG_RW,
208     &pccbb_start_mem, PCCBB_START_MEM,
209     "Starting address for memory allocations");
210
211 u_long pccbb_start_16_io = PCCBB_START_16_IO;
212 TUNABLE_INT("hw.cbb.start_16_io", (int *)&pccbb_start_16_io);
213 SYSCTL_ULONG(_hw_cbb, OID_AUTO, start_16_io, CTLFLAG_RW,
214     &pccbb_start_16_io, PCCBB_START_16_IO,
215     "Starting ioport for 16-bit cards");
216
217 u_long pccbb_start_32_io = PCCBB_START_32_IO;
218 TUNABLE_INT("hw.cbb.start_32_io", (int *)&pccbb_start_32_io);
219 SYSCTL_ULONG(_hw_cbb, OID_AUTO, start_32_io, CTLFLAG_RW,
220     &pccbb_start_32_io, PCCBB_START_32_IO,
221     "Starting ioport for 32-bit cards");
222
223 int cbb_debug = 0;
224 TUNABLE_INT("hw.cbb.debug", &cbb_debug);
225 SYSCTL_ULONG(_hw_cbb, OID_AUTO, debug, CTLFLAG_RW, &cbb_debug, 0,
226     "Verbose cardbus bridge debugging");
227
228 static int      pccbb_chipset(uint32_t pci_id, const char **namep);
229 static int      pccbb_probe(device_t brdev);
230 static void     pccbb_chipinit(struct pccbb_softc *sc);
231 static int      pccbb_attach(device_t brdev);
232 static int      pccbb_detach(device_t brdev);
233 static int      pccbb_shutdown(device_t brdev);
234 static void     pccbb_driver_added(device_t brdev, driver_t *driver);
235 static void     pccbb_child_detached(device_t brdev, device_t child);
236 static int      pccbb_card_reprobe(device_t brdev, device_t busdev);
237 static void     pccbb_event_thread(void *arg);
238 static void     pccbb_insert(struct pccbb_softc *sc);
239 static void     pccbb_removal(struct pccbb_softc *sc);
240 static void     pccbb_intr(void *arg);
241 static int      pccbb_detect_voltage(device_t brdev);
242 static int      pccbb_power(device_t brdev, int volts);
243 static void     pccbb_cardbus_reset(device_t brdev);
244 static int      pccbb_cardbus_power_enable_socket(device_t brdev,
245                     device_t child);
246 static void     pccbb_cardbus_power_disable_socket(device_t brdev,
247                     device_t child);
248 static int      pccbb_cardbus_io_open(device_t brdev, int win, uint32_t start,
249                     uint32_t end);
250 static int      pccbb_cardbus_mem_open(device_t brdev, int win,
251                     uint32_t start, uint32_t end);
252 static void     pccbb_cardbus_auto_open(struct pccbb_softc *sc, int type);
253 static int      pccbb_cardbus_activate_resource(device_t brdev, device_t child,
254                     int type, int rid, struct resource *res);
255 static int      pccbb_cardbus_deactivate_resource(device_t brdev,
256                     device_t child, int type, int rid, struct resource *res);
257 static struct resource  *pccbb_cardbus_alloc_resource(device_t brdev,
258                     device_t child, int type, int *rid, u_long start,
259                     u_long end, u_long count, uint flags);
260 static int      pccbb_cardbus_release_resource(device_t brdev, device_t child,
261                     int type, int rid, struct resource *res);
262 static int      pccbb_power_enable_socket(device_t brdev, device_t child);
263 static void     pccbb_power_disable_socket(device_t brdev, device_t child);
264 static int      pccbb_activate_resource(device_t brdev, device_t child,
265                     int type, int rid, struct resource *r);
266 static int      pccbb_deactivate_resource(device_t brdev, device_t child,
267                     int type, int rid, struct resource *r);
268 static struct resource  *pccbb_alloc_resource(device_t brdev, device_t child,
269                     int type, int *rid, u_long start, u_long end, u_long count,
270                     uint flags);
271 static int      pccbb_release_resource(device_t brdev, device_t child,
272                     int type, int rid, struct resource *r);
273 static int      pccbb_read_ivar(device_t brdev, device_t child, int which,
274                     uintptr_t *result);
275 static int      pccbb_write_ivar(device_t brdev, device_t child, int which,
276                     uintptr_t value);
277 static int      pccbb_maxslots(device_t brdev);
278 static uint32_t pccbb_read_config(device_t brdev, int b, int s, int f,
279                     int reg, int width);
280 static void     pccbb_write_config(device_t brdev, int b, int s, int f,
281                     int reg, uint32_t val, int width);
282
283 /*
284  */
285 static __inline void
286 pccbb_set(struct pccbb_softc *sc, uint32_t reg, uint32_t val)
287 {
288         bus_space_write_4(sc->bst, sc->bsh, reg, val);
289 }
290
291 static __inline uint32_t
292 pccbb_get(struct pccbb_softc *sc, uint32_t reg)
293 {
294         return (bus_space_read_4(sc->bst, sc->bsh, reg));
295 }
296
297 static __inline void
298 pccbb_setb(struct pccbb_softc *sc, uint32_t reg, uint32_t bits)
299 {
300         pccbb_set(sc, reg, pccbb_get(sc, reg) | bits);
301 }
302
303 static __inline void
304 pccbb_clrb(struct pccbb_softc *sc, uint32_t reg, uint32_t bits)
305 {
306         pccbb_set(sc, reg, pccbb_get(sc, reg) & ~bits);
307 }
308
309 static __inline uint8_t
310 pccbb_pcic_read(struct exca_softc *sc, int reg)
311 {
312         return (bus_space_read_1(sc->bst, sc->bsh, sc->offset + reg));
313 }
314
315 static __inline void
316 pccbb_pcic_write(struct exca_softc *sc, int reg, uint8_t val)
317 {
318         return (bus_space_write_1(sc->bst, sc->bsh, sc->offset + reg, val));
319 }
320
321 static void
322 pccbb_remove_res(struct pccbb_softc *sc, struct resource *res)
323 {
324         struct pccbb_reslist *rle;
325
326         SLIST_FOREACH(rle, &sc->rl, link) {
327                 if (rle->res == res) {
328                         SLIST_REMOVE(&sc->rl, rle, pccbb_reslist, link);
329                         free(rle, M_DEVBUF);
330                         return;
331                 }
332         }
333 }
334
335 static struct resource *
336 pccbb_find_res(struct pccbb_softc *sc, int type, int rid)
337 {
338         struct pccbb_reslist *rle;
339         
340         SLIST_FOREACH(rle, &sc->rl, link)
341                 if (SYS_RES_MEMORY == rle->type && rid == rle->rid)
342                         return (rle->res);
343         return (NULL);
344 }
345
346 static void
347 pccbb_insert_res(struct pccbb_softc *sc, struct resource *res, int type,
348     int rid)
349 {
350         struct pccbb_reslist *rle;
351
352         /*
353          * Need to record allocated resource so we can iterate through
354          * it later.
355          */
356         rle = malloc(sizeof(struct pccbb_reslist), M_DEVBUF, M_NOWAIT);
357         if (!res)
358                 panic("pccbb_cardbus_alloc_resource: can't record entry!");
359         rle->res = res;
360         rle->type = type;
361         rle->rid = rid;
362         SLIST_INSERT_HEAD(&sc->rl, rle, link);
363 }
364
365 static void
366 pccbb_destroy_res(struct pccbb_softc *sc)
367 {
368         struct pccbb_reslist *rle;
369
370         while ((rle = SLIST_FIRST(&sc->rl)) != NULL) {
371                 device_printf(sc->dev, "Danger Will Robinson: Resource "
372                     "left allocated!  This is a bug... "
373                     "(rid=%x, type=%d, addr=%lx)\n", rle->rid, rle->type,
374                     rman_get_start(rle->res));
375                 SLIST_REMOVE_HEAD(&sc->rl, link);
376                 free(rle, M_DEVBUF);
377         }
378 }
379
380 /************************************************************************/
381 /* Probe/Attach                                                         */
382 /************************************************************************/
383
384 static int
385 pccbb_chipset(uint32_t pci_id, const char **namep)
386 {
387         struct yenta_chipinfo *ycp;
388
389         for (ycp = yc_chipsets; ycp->yc_id != 0 && pci_id != ycp->yc_id; ++ycp)
390             continue;
391         if (namep != NULL)
392                 *namep = ycp->yc_name;
393         return (ycp->yc_chiptype);
394 }
395
396 static int
397 pccbb_probe(device_t brdev)
398 {
399         const char *name;
400         uint32_t progif;
401         uint32_t subclass;
402
403         /*
404          * Do we know that we support the chipset?  If so, then we
405          * accept the device.
406          */
407         if (pccbb_chipset(pci_get_devid(brdev), &name) != CB_UNKNOWN) {
408                 device_set_desc(brdev, name);
409                 return (0);
410         }
411
412         /*
413          * We do support generic CardBus bridges.  All that we've seen
414          * to date have progif 0 (the Yenta spec, and successors mandate
415          * this).  We do not support PCI PCMCIA bridges (with one exception)
416          * with this driver since they generally are I/O mapped.  Those
417          * are supported by the pcic driver.  This should help us be more
418          * future proof.
419          */
420         subclass = pci_get_subclass(brdev);
421         progif = pci_get_progif(brdev);
422         if (subclass == PCIS_BRIDGE_CARDBUS && progif == 0) {
423                 device_set_desc(brdev, "PCI-CardBus Bridge");
424                 return (0);
425         }
426         return (ENXIO);
427 }
428
429
430 static void
431 pccbb_chipinit(struct pccbb_softc *sc)
432 {
433         /* Set CardBus latency timer */
434         if (pci_read_config(sc->dev, PCIR_SECLAT_1, 1) < 0x20)
435                 pci_write_config(sc->dev, PCIR_SECLAT_1, 0x20, 1);
436
437         /* Set PCI latency timer */
438         if (pci_read_config(sc->dev, PCIR_LATTIMER, 1) < 0x20)
439                 pci_write_config(sc->dev, PCIR_LATTIMER, 0x20, 1);
440
441         /* Enable memory access */
442         PCI_MASK_CONFIG(sc->dev, PCIR_COMMAND,
443             | PCIM_CMD_MEMEN
444             | PCIM_CMD_PORTEN
445             | PCIM_CMD_BUSMASTEREN, 2);
446
447         /* disable Legacy IO */
448         switch (sc->chipset) {
449         case CB_RF5C46X:
450                 PCI_MASK_CONFIG(sc->dev, CBBR_BRIDGECTRL,
451                     & ~(CBBM_BRIDGECTRL_RL_3E0_EN |
452                     CBBM_BRIDGECTRL_RL_3E2_EN), 2);
453                 break;
454         default:
455                 pci_write_config(sc->dev, CBBR_LEGACY, 0x0, 4);
456                 break;
457         }
458
459         /* Use PCI interrupt for interrupt routing */
460         PCI_MASK2_CONFIG(sc->dev, CBBR_BRIDGECTRL,
461             & ~(CBBM_BRIDGECTRL_MASTER_ABORT |
462             CBBM_BRIDGECTRL_INTR_IREQ_EN),
463             | CBBM_BRIDGECTRL_WRITE_POST_EN,
464             2);
465
466         /*
467          * XXX this should be a function table, ala OLDCARD.  This means
468          * that we could more easily support ISA interrupts for pccard
469          * cards if we had to.
470          */
471         switch (sc->chipset) {
472         case CB_TI113X:
473                 /*
474                  * The TI 1031, TI 1130 and TI 1131 all require another bit
475                  * be set to enable PCI routing of interrupts, and then
476                  * a bit for each of the CSC and Function interrupts we
477                  * want routed.
478                  */
479                 PCI_MASK_CONFIG(sc->dev, CBBR_CBCTRL,
480                     | CBBM_CBCTRL_113X_PCI_INTR |
481                     CBBM_CBCTRL_113X_PCI_CSC | CBBM_CBCTRL_113X_PCI_IRQ_EN,
482                     1);
483                 PCI_MASK_CONFIG(sc->dev, CBBR_DEVCTRL,
484                     & ~(CBBM_DEVCTRL_INT_SERIAL |
485                     CBBM_DEVCTRL_INT_PCI), 1);
486                 break;
487         case CB_TOPIC97:
488                 /*
489                  * Disable Zoom Video, ToPIC 97, 100.
490                  */
491                 pci_write_config(sc->dev, CBBR_TOPIC_ZV_CONTROL, 0, 1);
492                 /*
493                  * ToPIC 97, 100
494                  * At offset 0xa1: INTERRUPT CONTROL register
495                  * 0x1: Turn on INT interrupts.
496                  */
497                 PCI_MASK_CONFIG(sc->dev, CBBR_TOPIC_INTCTRL,
498                     | CBBM_TOPIC_INTCTRL_INTIRQSEL, 1);
499                 goto topic_common;
500         case CB_TOPIC95:
501                 /*
502                  * SOCKETCTRL appears to be TOPIC 95/B specific
503                  */
504                 PCI_MASK_CONFIG(sc->dev, CBBR_TOPIC_SOCKETCTRL,
505                     | CBBM_TOPIC_SOCKETCTRL_SCR_IRQSEL, 4);
506
507         topic_common:;
508                 /*
509                  * At offset 0xa0: SLOT CONTROL
510                  * 0x80 Enable Cardbus Functionality
511                  * 0x40 Enable Cardbus and PC Card registers
512                  * 0x20 Lock ID in exca regs
513                  * 0x10 Write protect ID in config regs
514                  * Clear the rest of the bits, which defaults the slot
515                  * in legacy mode to 0x3e0 and offset 0. (legacy
516                  * mode is determined elsewhere)
517                  */
518                 pci_write_config(sc->dev, CBBR_TOPIC_SLOTCTRL,
519                     CBBM_TOPIC_SLOTCTRL_SLOTON |
520                     CBBM_TOPIC_SLOTCTRL_SLOTEN |
521                     CBBM_TOPIC_SLOTCTRL_ID_LOCK |
522                     CBBM_TOPIC_SLOTCTRL_ID_WP, 1);
523
524                 /*
525                  * At offset 0xa3 Card Detect Control Register
526                  * 0x80 CARDBUS enbale
527                  * 0x01 Cleared for hardware change detect
528                  */
529                 PCI_MASK2_CONFIG(sc->dev, CBBR_TOPIC_CDC,
530                     | CBBM_TOPIC_CDC_CARDBUS,
531                     & ~CBBM_TOPIC_CDC_SWDETECT, 4);
532                 break;
533         }
534
535         /*
536          * Need to tell ExCA registers to route via PCI interrupts.  There
537          * are two ways to do this.  Once is to set INTR_ENABLE and the
538          * other is to set CSC to 0.  Since both methods are mutually
539          * compatible, we do both.
540          */
541         exca_write(&sc->exca, EXCA_INTR, EXCA_INTR_ENABLE);
542         exca_write(&sc->exca, EXCA_CSC_INTR, 0);
543
544         /* close all memory and io windows */
545         pci_write_config(sc->dev, CBBR_MEMBASE0, 0xffffffff, 4);
546         pci_write_config(sc->dev, CBBR_MEMLIMIT0, 0, 4);
547         pci_write_config(sc->dev, CBBR_MEMBASE1, 0xffffffff, 4);
548         pci_write_config(sc->dev, CBBR_MEMLIMIT1, 0, 4);
549         pci_write_config(sc->dev, CBBR_IOBASE0, 0xffffffff, 4);
550         pci_write_config(sc->dev, CBBR_IOLIMIT0, 0, 4);
551         pci_write_config(sc->dev, CBBR_IOBASE1, 0xffffffff, 4);
552         pci_write_config(sc->dev, CBBR_IOLIMIT1, 0, 4);
553 }
554
555 static int
556 pccbb_attach(device_t brdev)
557 {
558         struct pccbb_softc *sc = (struct pccbb_softc *)device_get_softc(brdev);
559         int rid;
560         uint32_t sockbase;
561
562         mtx_init(&sc->mtx, device_get_nameunit(brdev), "pccbb", MTX_DEF);
563         cv_init(&sc->cv, "pccbb cv");
564         sc->chipset = pccbb_chipset(pci_get_devid(brdev), NULL);
565         sc->dev = brdev;
566         sc->cbdev = NULL;
567         sc->pccarddev = NULL;
568         sc->secbus = pci_read_config(brdev, PCIR_SECBUS_2, 1);
569         sc->subbus = pci_read_config(brdev, PCIR_SUBBUS_2, 1);
570         SLIST_INIT(&sc->rl);
571
572         /*
573          * The PCI bus code should assign us memory in the absense
574          * of the BIOS doing so.  However, 'should' isn't 'is,' so we kludge
575          * up something here until the PCI/acpi code properly assigns the
576          * resource.
577          */
578         rid = CBBR_SOCKBASE;
579         sc->base_res = bus_alloc_resource(brdev, SYS_RES_MEMORY, &rid,
580             0, ~0, 1, RF_ACTIVE);
581         if (!sc->base_res) {
582                 /*
583                  * Generally, the BIOS will assign this memory for us.
584                  * However, newer BIOSes do not because the MS design
585                  * documents have mandated that this is for the OS
586                  * to assign rather than the BIOS.  This driver shouldn't
587                  * be doing this, but until the pci bus code (or acpi)
588                  * does this, we allow CardBus bridges to work on more
589                  * machines.
590                  */
591                 sockbase = pci_read_config(brdev, rid, 4);
592                 if (sockbase < 0x100000 || sockbase >= 0xfffffff0) {
593                         pci_write_config(brdev, rid, 0xffffffff, 4);
594                         sockbase = pci_read_config(brdev, rid, 4);
595                         sockbase = (sockbase & 0xfffffff0) &
596                             -(sockbase & 0xfffffff0);
597                         sc->base_res = bus_generic_alloc_resource(
598                             device_get_parent(brdev), brdev, SYS_RES_MEMORY,
599                             &rid, pccbb_start_mem, ~0, sockbase,
600                             RF_ACTIVE|rman_make_alignment_flags(sockbase));
601                         if (!sc->base_res) {
602                                 device_printf(brdev,
603                                     "Could not grab register memory\n");
604                                 mtx_destroy(&sc->mtx);
605                                 cv_destroy(&sc->cv);
606                                 return (ENOMEM);
607                         }
608                         pci_write_config(brdev, CBBR_SOCKBASE,
609                             rman_get_start(sc->base_res), 4);
610                         DEVPRINTF((brdev, "PCI Memory allocated: %08lx\n",
611                             rman_get_start(sc->base_res)));
612                 } else {
613                         device_printf(brdev, "Could not map register memory\n");
614                         mtx_destroy(&sc->mtx);
615                         cv_destroy(&sc->cv);
616                         return (ENOMEM);
617                 }
618         }
619
620         sc->bst = rman_get_bustag(sc->base_res);
621         sc->bsh = rman_get_bushandle(sc->base_res);
622         exca_init(&sc->exca, brdev, &pccbb_pcic_write, &pccbb_pcic_read,
623           sc->bst, sc->bsh, 0x800);
624         pccbb_chipinit(sc);
625
626         /* attach children */
627         sc->cbdev = device_add_child(brdev, "cardbus", -1);
628         if (sc->cbdev == NULL)
629                 DEVPRINTF((brdev, "WARNING: cannot add cardbus bus.\n"));
630         else if (device_probe_and_attach(sc->cbdev) != 0) {
631                 DEVPRINTF((brdev, "WARNING: cannot attach cardbus bus!\n"));
632                 sc->cbdev = NULL;
633         }
634
635         sc->pccarddev = device_add_child(brdev, "pccard", -1);
636         if (sc->pccarddev == NULL)
637                 DEVPRINTF((brdev, "WARNING: cannot add pccard bus.\n"));
638         else if (device_probe_and_attach(sc->pccarddev) != 0) {
639                 DEVPRINTF((brdev, "WARNING: cannot attach pccard bus.\n"));
640                 sc->pccarddev = NULL;
641         }
642
643         /* Map and establish the interrupt. */
644         rid = 0;
645         sc->irq_res = bus_alloc_resource(brdev, SYS_RES_IRQ, &rid, 0, ~0, 1,
646             RF_SHAREABLE | RF_ACTIVE);
647         if (sc->irq_res == NULL) {
648                 printf("pccbb: Unable to map IRQ...\n");
649                 bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE,
650                     sc->base_res);
651                 mtx_destroy(&sc->mtx);
652                 cv_destroy(&sc->cv);
653                 return (ENOMEM);
654         }
655
656         if (bus_setup_intr(brdev, sc->irq_res, INTR_TYPE_AV, pccbb_intr, sc,
657             &sc->intrhand)) {
658                 device_printf(brdev, "couldn't establish interrupt");
659                 bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->irq_res);
660                 bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE,
661                     sc->base_res);
662                 mtx_destroy(&sc->mtx);
663                 cv_destroy(&sc->cv);
664                 return (ENOMEM);
665         }
666
667         /* CSC Interrupt: Card detect interrupt on */
668         pccbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD);
669
670         /* reset interrupt */
671         pccbb_set(sc, CBB_SOCKET_EVENT, pccbb_get(sc, CBB_SOCKET_EVENT));
672
673         /* Start the thread */
674         if (kthread_create(pccbb_event_thread, sc, &sc->event_thread, 0,
675                 "%s%d", device_get_name(sc->dev), device_get_unit(sc->dev))) {
676                 device_printf (sc->dev, "unable to create event thread.\n");
677                 panic ("pccbb_create_event_thread");
678         }
679
680         return (0);
681 }
682
683 static int
684 pccbb_detach(device_t brdev)
685 {
686         struct pccbb_softc *sc = device_get_softc(brdev);
687         int numdevs;
688         device_t *devlist;
689         int tmp;
690         int error;
691
692         device_get_children(brdev, &devlist, &numdevs);
693
694         error = 0;
695         for (tmp = 0; tmp < numdevs; tmp++) {
696                 if (device_detach(devlist[tmp]) == 0)
697                         device_delete_child(brdev, devlist[tmp]);
698                 else
699                         error++;
700         }
701         free(devlist, M_TEMP);
702         if (error > 0)
703                 return (ENXIO);
704
705         mtx_lock(&sc->mtx);
706         bus_teardown_intr(brdev, sc->irq_res, sc->intrhand);
707         sc->flags |= PCCBB_KTHREAD_DONE;
708         if (sc->flags & PCCBB_KTHREAD_RUNNING) {
709                 wakeup(sc);
710                 mtx_unlock(&sc->mtx);
711                 DEVPRINTF((brdev, "waiting for kthread exit..."));
712                 error = tsleep(sc, PWAIT, "pccbb-detach-wait", 60 * hz);
713                 if (error)
714                         DPRINTF(("timeout\n"));
715                 else
716                         DPRINTF(("done\n"));
717         } else {
718                 mtx_unlock(&sc->mtx);
719         }
720
721         bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->irq_res);
722         bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE,
723             sc->base_res);
724         mtx_destroy(&sc->mtx);
725         cv_destroy(&sc->cv);
726         return (0);
727 }
728
729 static int
730 pccbb_shutdown(device_t brdev)
731 {
732         struct pccbb_softc *sc = (struct pccbb_softc *)device_get_softc(brdev);
733         /* properly reset everything at shutdown */
734
735         PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL, |CBBM_BRIDGECTRL_RESET, 2);
736         exca_clrb(&sc->exca, EXCA_INTR, EXCA_INTR_RESET);
737
738         pccbb_set(sc, CBB_SOCKET_MASK, 0);
739
740         pccbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V);
741
742         exca_write(&sc->exca, EXCA_ADDRWIN_ENABLE, 0);
743         pci_write_config(brdev, CBBR_MEMBASE0, 0, 4);
744         pci_write_config(brdev, CBBR_MEMLIMIT0, 0, 4);
745         pci_write_config(brdev, CBBR_MEMBASE1, 0, 4);
746         pci_write_config(brdev, CBBR_MEMLIMIT1, 0, 4);
747         pci_write_config(brdev, CBBR_IOBASE0, 0, 4);
748         pci_write_config(brdev, CBBR_IOLIMIT0, 0, 4);
749         pci_write_config(brdev, CBBR_IOBASE1, 0, 4);
750         pci_write_config(brdev, CBBR_IOLIMIT1, 0, 4);
751         pci_write_config(brdev, PCIR_COMMAND, 0, 2);
752         return (0);
753 }
754
755 static int
756 pccbb_setup_intr(device_t dev, device_t child, struct resource *irq,
757   int flags, driver_intr_t *intr, void *arg, void **cookiep)
758 {
759         int err;
760
761         /*
762          * You aren't allowed to have fast interrupts for pccard/cardbus
763          * things since those interrupts are PCI and shared.  Since we use
764          * the PCI interrupt for the status change interrupts, it can't be
765          * free for use by the driver.  Fast interrupts must not be shared.
766          */
767         if ((flags & INTR_FAST) != 0)
768                 return (EINVAL);
769         err = bus_generic_setup_intr(dev, child, irq, flags, intr, arg,
770             cookiep);
771         /*
772          * XXX need to turn on ISA interrupts, if we ever support them, but
773          * XXX for now that's all we need to do.
774          */
775         return (err);
776 }
777
778 static int
779 pccbb_teardown_intr(device_t dev, device_t child, struct resource *irq,
780     void *cookie)
781 {
782         /* XXX Need to do different things for ISA interrupts. */
783         return (bus_generic_teardown_intr(dev, child, irq, cookie));
784 }
785
786
787 static void
788 pccbb_driver_added(device_t brdev, driver_t *driver)
789 {
790         struct pccbb_softc *sc = device_get_softc(brdev);
791         device_t *devlist;
792         int tmp;
793         int numdevs;
794         int wake;
795         uint32_t sockstate;
796
797         DEVICE_IDENTIFY(driver, brdev);
798         device_get_children(brdev, &devlist, &numdevs);
799         wake = 0;
800         sockstate = pccbb_get(sc, CBB_SOCKET_STATE);
801         for (tmp = 0; tmp < numdevs; tmp++) {
802                 if (device_get_state(devlist[tmp]) == DS_NOTPRESENT &&
803                     device_probe_and_attach(devlist[tmp]) == 0) {
804                         if (devlist[tmp] == NULL)
805                                 /* NOTHING */;
806                         else if (strcmp(driver->name, "cardbus") == 0) {
807                                 sc->cbdev = devlist[tmp];
808                                 if (((sockstate & CBB_SOCKET_STAT_CD) == 0) &&
809                                     (sockstate & CBB_SOCKET_STAT_CB))
810                                         wake++;
811                         } else if (strcmp(driver->name, "pccard") == 0) {
812                                 sc->pccarddev = devlist[tmp];
813                                 if (((sockstate & CBB_SOCKET_STAT_CD) == 0) &&
814                                     (sockstate & CBB_SOCKET_STAT_16BIT))
815                                         wake++;
816                         } else
817                                 device_printf(brdev,
818                                     "Unsupported child bus: %s\n",
819                                     driver->name);
820                 }
821         }
822         free(devlist, M_TEMP);
823
824         if (wake > 0) {
825                 if ((pccbb_get(sc, CBB_SOCKET_STATE) & CBB_SOCKET_STAT_CD)
826                     == 0) {
827                         mtx_lock(&sc->mtx);
828                         wakeup(sc);
829                         mtx_unlock(&sc->mtx);
830                 }
831         }
832 }
833
834 static void
835 pccbb_child_detached(device_t brdev, device_t child)
836 {
837         struct pccbb_softc *sc = device_get_softc(brdev);
838
839         if (child == sc->cbdev)
840                 sc->cbdev = NULL;
841         else if (child == sc->pccarddev)
842                 sc->pccarddev = NULL;
843         else
844                 device_printf(brdev, "Unknown child detached: %s %p/%p\n",
845                     device_get_nameunit(child), sc->cbdev, sc->pccarddev);
846 }
847
848 static int
849 pccbb_card_reprobe(device_t brdev, device_t busdev)
850 {
851         struct pccbb_softc *sc = device_get_softc(brdev);
852         int wake = 0;
853         uint32_t sockstate;
854
855         sockstate = pccbb_get(sc, CBB_SOCKET_STATE);
856
857         if ((sockstate & CBB_SOCKET_STAT_CD) == 0) {
858                 if (busdev == sc->cbdev &&
859                     (sockstate & CBB_SOCKET_STAT_CB))
860                         wake++;
861                 else if (busdev == sc->pccarddev &&
862                     (sockstate & CBB_SOCKET_STAT_16BIT))
863                         wake++;
864
865                 if (wake > 0) {
866                         mtx_lock(&sc->mtx);
867                         wakeup(sc);
868                         mtx_unlock(&sc->mtx);
869                         return (0);
870                 }
871                 return (EBUSY);
872         }
873         return (ENOENT);
874 }
875
876 /************************************************************************/
877 /* Kthreads                                                             */
878 /************************************************************************/
879
880 static void
881 pccbb_event_thread(void *arg)
882 {
883         struct pccbb_softc *sc = arg;
884         uint32_t status;
885         int err;
886
887         /*
888          * We take out Giant here because we drop it in tsleep
889          * and need it for kthread_exit, which drops it.
890          */
891         mtx_lock(&Giant);
892         sc->flags |= PCCBB_KTHREAD_RUNNING;
893         while (1) {
894                 /*
895                  * Check to see if we have anything first so that
896                  * if there's a card already inserted, we do the
897                  * right thing.
898                  */
899                 if (sc->flags & PCCBB_KTHREAD_DONE)
900                         break;
901
902                 status = pccbb_get(sc, CBB_SOCKET_STATE);
903                 if ((status & CBB_SOCKET_STAT_CD) == 0)
904                         pccbb_insert(sc);
905                 else
906                         pccbb_removal(sc);
907                 /*
908                  * Wait until it has been 1s since the last time we
909                  * get an interrupt.  We handle the rest of the interrupt
910                  * at the top of the loop.
911                  */
912                 mtx_lock(&sc->mtx);
913                 cv_wait(&sc->cv, &sc->mtx);
914                 do {
915                         err = cv_timedwait(&sc->cv, &sc->mtx, 1 * hz);
916                 } while (err != EWOULDBLOCK &&
917                     (sc->flags & PCCBB_KTHREAD_DONE) == 0);
918                 mtx_unlock(&sc->mtx);
919         }
920         sc->flags &= ~PCCBB_KTHREAD_RUNNING;
921         /*
922          * XXX I think there's a race here.  If we wakeup in the other
923          * thread before kthread_exit is called and this routine returns,
924          * and that thread causes us to be unmapped, then we are setting
925          * ourselves up for a panic.  Make sure that I check out
926          * jhb's crash.c for a fix.
927          */
928         wakeup(sc);
929         kthread_exit(0);
930 }
931
932 /************************************************************************/
933 /* Insert/removal                                                       */
934 /************************************************************************/
935
936 static void
937 pccbb_insert(struct pccbb_softc *sc)
938 {
939         uint32_t sockevent, sockstate;
940         int timeout = 30;
941
942         /*
943          * Debounce interrupt.  However, most of the debounce
944          * is done in the thread's timeout routines.
945          */
946         do {
947                 sockevent = pccbb_get(sc, CBB_SOCKET_EVENT);
948                 sockstate = pccbb_get(sc, CBB_SOCKET_STATE);
949         } while (sockstate & CBB_SOCKET_STAT_CD && --timeout > 0);
950
951         if (timeout < 0) {
952                 device_printf (sc->dev, "insert timeout");
953                 return;
954         }
955
956         DEVPRINTF((sc->dev, "card inserted: event=0x%08x, state=%08x\n",
957             sockevent, sockstate));
958
959         if (sockstate & CBB_SOCKET_STAT_16BIT) {
960                 if (sc->pccarddev != NULL) {
961                         sc->flags |= PCCBB_16BIT_CARD;
962                         if (CARD_ATTACH_CARD(sc->pccarddev) != 0)
963                                 device_printf(sc->dev,
964                                     "PC Card card activation failed\n");
965                 } else {
966                         device_printf(sc->dev,
967                             "PC Card inserted, but no pccard bus.\n");
968                 }
969         } else if (sockstate & CBB_SOCKET_STAT_CB) {
970                 if (sc->cbdev != NULL) {
971                         sc->flags &= ~PCCBB_16BIT_CARD;
972                         if (CARD_ATTACH_CARD(sc->cbdev) != 0)
973                                 device_printf(sc->dev,
974                                     "CardBus card activation failed\n");
975                 } else {
976                         device_printf(sc->dev,
977                             "CardBUS card inserted, but no cardbus bus.\n");
978                 }
979         } else {
980                 /*
981                  * We should power the card down, and try again a couple of
982                  * times if this happens. XXX
983                  */
984                 device_printf (sc->dev, "Unsupported card type detected\n");
985         }
986 }
987
988 static void
989 pccbb_removal(struct pccbb_softc *sc)
990 {
991         if (sc->flags & PCCBB_16BIT_CARD && sc->pccarddev != NULL)
992                 CARD_DETACH_CARD(sc->pccarddev, DETACH_FORCE);
993         else if ((!(sc->flags & PCCBB_16BIT_CARD)) && sc->cbdev != NULL)
994                 CARD_DETACH_CARD(sc->cbdev, DETACH_FORCE);
995         pccbb_destroy_res(sc);
996 }
997
998 /************************************************************************/
999 /* Interrupt Handler                                                    */
1000 /************************************************************************/
1001
1002 static void
1003 pccbb_intr(void *arg)
1004 {
1005         struct pccbb_softc *sc = arg;
1006         uint32_t sockevent;
1007
1008         /*
1009          * This ISR needs work XXX
1010          */
1011         sockevent = pccbb_get(sc, CBB_SOCKET_EVENT);
1012         if (sockevent) {
1013                 /* ack the interrupt */
1014                 pccbb_setb(sc, CBB_SOCKET_EVENT, sockevent);
1015
1016                 if (sockevent & CBB_SOCKET_EVENT_CD) {
1017                         mtx_lock(&sc->mtx);
1018                         cv_signal(&sc->cv);
1019                         mtx_unlock(&sc->mtx);
1020                 }
1021                 if (sockevent & CBB_SOCKET_EVENT_CSTS) {
1022                         DPRINTF((" cstsevent occured: 0x%08x\n",
1023                             pccbb_get(sc, CBB_SOCKET_STATE)));
1024                 }
1025                 if (sockevent & CBB_SOCKET_EVENT_POWER) {
1026                         DPRINTF((" pwrevent occured: 0x%08x\n",
1027                             pccbb_get(sc, CBB_SOCKET_STATE)));
1028                 }
1029                 /* Other bits? */
1030         }
1031
1032         /* Call the interrupt if we still have the card */
1033 }
1034
1035 /************************************************************************/
1036 /* Generic Power functions                                              */
1037 /************************************************************************/
1038
1039 static int
1040 pccbb_detect_voltage(device_t brdev)
1041 {
1042         struct pccbb_softc *sc = device_get_softc(brdev);
1043         uint32_t psr;
1044         int vol = CARD_UKN_CARD;
1045
1046         psr = pccbb_get(sc, CBB_SOCKET_STATE);
1047
1048         if (psr & CBB_SOCKET_STAT_5VCARD)
1049                 vol |= CARD_5V_CARD;
1050         if (psr & CBB_SOCKET_STAT_3VCARD)
1051                 vol |= CARD_3V_CARD;
1052         if (psr & CBB_SOCKET_STAT_XVCARD)
1053                 vol |= CARD_XV_CARD;
1054         if (psr & CBB_SOCKET_STAT_YVCARD)
1055                 vol |= CARD_YV_CARD;
1056
1057         return (vol);
1058 }
1059
1060 static int
1061 pccbb_power(device_t brdev, int volts)
1062 {
1063         uint32_t status, sock_ctrl;
1064         struct pccbb_softc *sc = device_get_softc(brdev);
1065         int timeout;
1066         uint32_t sockevent;
1067
1068         DEVPRINTF((sc->dev, "pccbb_power: %s and %s [%x]\n",
1069             (volts & CARD_VCCMASK) == CARD_VCC_UC ? "CARD_VCC_UC" :
1070             (volts & CARD_VCCMASK) == CARD_VCC_5V ? "CARD_VCC_5V" :
1071             (volts & CARD_VCCMASK) == CARD_VCC_3V ? "CARD_VCC_3V" :
1072             (volts & CARD_VCCMASK) == CARD_VCC_XV ? "CARD_VCC_XV" :
1073             (volts & CARD_VCCMASK) == CARD_VCC_YV ? "CARD_VCC_YV" :
1074             (volts & CARD_VCCMASK) == CARD_VCC_0V ? "CARD_VCC_0V" :
1075             "VCC-UNKNOWN",
1076             (volts & CARD_VPPMASK) == CARD_VPP_UC ? "CARD_VPP_UC" :
1077             (volts & CARD_VPPMASK) == CARD_VPP_12V ? "CARD_VPP_12V" :
1078             (volts & CARD_VPPMASK) == CARD_VPP_VCC ? "CARD_VPP_VCC" :
1079             (volts & CARD_VPPMASK) == CARD_VPP_0V ? "CARD_VPP_0V" :
1080             "VPP-UNKNOWN",
1081             volts));
1082
1083         status = pccbb_get(sc, CBB_SOCKET_STATE);
1084         sock_ctrl = pccbb_get(sc, CBB_SOCKET_CONTROL);
1085
1086         switch (volts & CARD_VCCMASK) {
1087         case CARD_VCC_UC:
1088                 break;
1089         case CARD_VCC_5V:
1090                 if (CBB_SOCKET_STAT_5VCARD & status) { /* check 5 V card */
1091                         sock_ctrl &= ~CBB_SOCKET_CTRL_VCCMASK;
1092                         sock_ctrl |= CBB_SOCKET_CTRL_VCC_5V;
1093                 } else {
1094                         device_printf(sc->dev,
1095                             "BAD voltage request: no 5 V card\n");
1096                 }
1097                 break;
1098         case CARD_VCC_3V:
1099                 if (CBB_SOCKET_STAT_3VCARD & status) {
1100                         sock_ctrl &= ~CBB_SOCKET_CTRL_VCCMASK;
1101                         sock_ctrl |= CBB_SOCKET_CTRL_VCC_3V;
1102                 } else {
1103                         device_printf(sc->dev,
1104                             "BAD voltage request: no 3.3 V card\n");
1105                 }
1106                 break;
1107         case CARD_VCC_0V:
1108                 sock_ctrl &= ~CBB_SOCKET_CTRL_VCCMASK;
1109                 break;
1110         default:
1111                 return (0);                     /* power NEVER changed */
1112                 break;
1113         }
1114
1115         switch (volts & CARD_VPPMASK) {
1116         case CARD_VPP_UC:
1117                 break;
1118         case CARD_VPP_0V:
1119                 sock_ctrl &= ~CBB_SOCKET_CTRL_VPPMASK;
1120                 break;
1121         case CARD_VPP_VCC:
1122                 sock_ctrl &= ~CBB_SOCKET_CTRL_VPPMASK;
1123                 sock_ctrl |= ((sock_ctrl >> 4) & 0x07);
1124                 break;
1125         case CARD_VPP_12V:
1126                 sock_ctrl &= ~CBB_SOCKET_CTRL_VPPMASK;
1127                 sock_ctrl |= CBB_SOCKET_CTRL_VPP_12V;
1128                 break;
1129         }
1130
1131         if (pccbb_get(sc, CBB_SOCKET_CONTROL) == sock_ctrl)
1132                 return (1); /* no change necessary */
1133
1134         pccbb_set(sc, CBB_SOCKET_CONTROL, sock_ctrl);
1135         status = pccbb_get(sc, CBB_SOCKET_STATE);
1136
1137         /* 
1138          * XXX This busy wait is bogus.  We should wait for a power
1139          * interrupt and then whine if the status is bad.  If we're
1140          * worried about the card not coming up, then we should also
1141          * schedule a timeout which we can cacel in the power interrupt.
1142          */
1143         timeout = 20;
1144         do {
1145                 DELAY(20*1000);
1146                 sockevent = pccbb_get(sc, CBB_SOCKET_EVENT);
1147         } while (!(sockevent & CBB_SOCKET_EVENT_POWER) && --timeout > 0);
1148         /* reset event status */
1149         /* XXX should only reset EVENT_POWER */
1150         pccbb_set(sc, CBB_SOCKET_EVENT, sockevent);
1151         if (timeout < 0) {
1152                 printf ("VCC supply failed.\n");
1153                 return (0);
1154         }
1155
1156         /* XXX
1157          * delay 400 ms: thgough the standard defines that the Vcc set-up time
1158          * is 20 ms, some PC-Card bridge requires longer duration.
1159          * XXX Note: We should check the stutus AFTER the delay to give time
1160          * for things to stabilize.
1161          */
1162         DELAY(400*1000);
1163
1164         if (status & CBB_SOCKET_STAT_BADVCC) {
1165                 device_printf(sc->dev,
1166                     "bad Vcc request. ctrl=0x%x, status=0x%x\n",
1167                     sock_ctrl ,status);
1168                 printf("pccbb_power: %s and %s [%x]\n",
1169                     (volts & CARD_VCCMASK) == CARD_VCC_UC ? "CARD_VCC_UC" :
1170                     (volts & CARD_VCCMASK) == CARD_VCC_5V ? "CARD_VCC_5V" :
1171                     (volts & CARD_VCCMASK) == CARD_VCC_3V ? "CARD_VCC_3V" :
1172                     (volts & CARD_VCCMASK) == CARD_VCC_XV ? "CARD_VCC_XV" :
1173                     (volts & CARD_VCCMASK) == CARD_VCC_YV ? "CARD_VCC_YV" :
1174                     (volts & CARD_VCCMASK) == CARD_VCC_0V ? "CARD_VCC_0V" :
1175                     "VCC-UNKNOWN",
1176                     (volts & CARD_VPPMASK) == CARD_VPP_UC ? "CARD_VPP_UC" :
1177                     (volts & CARD_VPPMASK) == CARD_VPP_12V ? "CARD_VPP_12V":
1178                     (volts & CARD_VPPMASK) == CARD_VPP_VCC ? "CARD_VPP_VCC":
1179                     (volts & CARD_VPPMASK) == CARD_VPP_0V ? "CARD_VPP_0V" :
1180                     "VPP-UNKNOWN",
1181                     volts);
1182                 return (0);
1183         }
1184         return (1);             /* power changed correctly */
1185 }
1186
1187 /*
1188  * detect the voltage for the card, and set it.  Since the power
1189  * used is the square of the voltage, lower voltages is a big win
1190  * and what Windows does (and what Microsoft prefers).  The MS paper
1191  * also talks about preferring the CIS entry as well.
1192  */
1193 static int
1194 pccbb_do_power(device_t brdev)
1195 {
1196         int voltage;
1197
1198         /* Prefer lowest voltage supported */
1199         voltage = pccbb_detect_voltage(brdev);
1200         pccbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V);
1201         if (voltage & CARD_YV_CARD)
1202                 pccbb_power(brdev, CARD_VCC_YV | CARD_VPP_VCC);
1203         else if (voltage & CARD_XV_CARD)
1204                 pccbb_power(brdev, CARD_VCC_XV | CARD_VPP_VCC);
1205         else if (voltage & CARD_3V_CARD)
1206                 pccbb_power(brdev, CARD_VCC_3V | CARD_VPP_VCC);
1207         else if (voltage & CARD_5V_CARD)
1208                 pccbb_power(brdev, CARD_VCC_5V | CARD_VPP_VCC);
1209         else {
1210                 device_printf(brdev, "Unknown card voltage\n");
1211                 return (ENXIO);
1212         }
1213         return (0);
1214 }
1215
1216 /************************************************************************/
1217 /* Cardbus power functions                                              */
1218 /************************************************************************/
1219
1220 static void
1221 pccbb_cardbus_reset(device_t brdev)
1222 {
1223         struct pccbb_softc *sc = device_get_softc(brdev);
1224         int delay_us;
1225
1226         delay_us = sc->chipset == CB_RF5C47X ? 400*1000 : 20*1000;
1227
1228         PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL, |CBBM_BRIDGECTRL_RESET, 2);
1229
1230         DELAY(delay_us);
1231
1232         /* If a card exists, unreset it! */
1233         if ((pccbb_get(sc, CBB_SOCKET_STATE) & CBB_SOCKET_STAT_CD) == 0) {
1234                 PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL,
1235                     &~CBBM_BRIDGECTRL_RESET, 2);
1236                 DELAY(delay_us);
1237         }
1238 }
1239
1240 static int
1241 pccbb_cardbus_power_enable_socket(device_t brdev, device_t child)
1242 {
1243         struct pccbb_softc *sc = device_get_softc(brdev);
1244         int err;
1245
1246         if ((pccbb_get(sc, CBB_SOCKET_STATE) & CBB_SOCKET_STAT_CD) ==
1247             CBB_SOCKET_STAT_CD)
1248                 return (ENODEV);
1249
1250         err = pccbb_do_power(brdev);
1251         if (err)
1252                 return (err);
1253         pccbb_cardbus_reset(brdev);
1254         return (0);
1255 }
1256
1257 static void
1258 pccbb_cardbus_power_disable_socket(device_t brdev, device_t child)
1259 {
1260         pccbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V);
1261         pccbb_cardbus_reset(brdev);
1262 }
1263
1264 /************************************************************************/
1265 /* Cardbus Resource                                                     */
1266 /************************************************************************/
1267
1268 static int
1269 pccbb_cardbus_io_open(device_t brdev, int win, uint32_t start, uint32_t end)
1270 {
1271         int basereg;
1272         int limitreg;
1273
1274         if ((win < 0) || (win > 1)) {
1275                 DEVPRINTF((brdev,
1276                     "pccbb_cardbus_io_open: window out of range %d\n", win));
1277                 return (EINVAL);
1278         }
1279
1280         basereg = win * 8 + CBBR_IOBASE0;
1281         limitreg = win * 8 + CBBR_IOLIMIT0;
1282
1283         pci_write_config(brdev, basereg, start, 4);
1284         pci_write_config(brdev, limitreg, end, 4);
1285         return (0);
1286 }
1287
1288 static int
1289 pccbb_cardbus_mem_open(device_t brdev, int win, uint32_t start, uint32_t end)
1290 {
1291         int basereg;
1292         int limitreg;
1293
1294         if ((win < 0) || (win > 1)) {
1295                 DEVPRINTF((brdev,
1296                     "pccbb_cardbus_mem_open: window out of range %d\n", win));
1297                 return (EINVAL);
1298         }
1299
1300         basereg = win*8 + CBBR_MEMBASE0;
1301         limitreg = win*8 + CBBR_MEMLIMIT0;
1302
1303         pci_write_config(brdev, basereg, start, 4);
1304         pci_write_config(brdev, limitreg, end, 4);
1305         return (0);
1306 }
1307
1308 /*
1309  * XXX The following function belongs in the pci bus layer.
1310  */
1311 static void
1312 pccbb_cardbus_auto_open(struct pccbb_softc *sc, int type)
1313 {
1314         uint32_t starts[2];
1315         uint32_t ends[2];
1316         struct pccbb_reslist *rle;
1317         int align;
1318         int prefetchable[2];
1319         uint32_t reg;
1320
1321         starts[0] = starts[1] = 0xffffffff;
1322         ends[0] = ends[1] = 0;
1323
1324         if (type == SYS_RES_MEMORY)
1325                 align = CBB_MEMALIGN;
1326         else if (type == SYS_RES_IOPORT)
1327                 align = CBB_IOALIGN;
1328         else
1329                 align = 1;
1330
1331         SLIST_FOREACH(rle, &sc->rl, link) {
1332                 if (rle->type != type)
1333                         ;
1334                 else if (rle->res == NULL) {
1335                         device_printf(sc->dev, "WARNING: Resource not reserved?  "
1336                             "(type=%d, addr=%lx)\n",
1337                             rle->type, rman_get_start(rle->res));
1338                 } else if (!(rman_get_flags(rle->res) & RF_ACTIVE)) {
1339                         /* XXX */
1340                 } else if (starts[0] == 0xffffffff) {
1341                         starts[0] = rman_get_start(rle->res);
1342                         ends[0] = rman_get_end(rle->res);
1343                         prefetchable[0] =
1344                             rman_get_flags(rle->res) & RF_PREFETCHABLE;
1345                 } else if (rman_get_end(rle->res) > ends[0] &&
1346                     rman_get_start(rle->res) - ends[0] <
1347                     PCCBB_AUTO_OPEN_SMALLHOLE && prefetchable[0] ==
1348                     (rman_get_flags(rle->res) & RF_PREFETCHABLE)) {
1349                         ends[0] = rman_get_end(rle->res);
1350                 } else if (rman_get_start(rle->res) < starts[0] &&
1351                     starts[0] - rman_get_end(rle->res) <
1352                     PCCBB_AUTO_OPEN_SMALLHOLE && prefetchable[0] ==
1353                     (rman_get_flags(rle->res) & RF_PREFETCHABLE)) {
1354                         starts[0] = rman_get_start(rle->res);
1355                 } else if (starts[1] == 0xffffffff) {
1356                         starts[1] = rman_get_start(rle->res);
1357                         ends[1] = rman_get_end(rle->res);
1358                         prefetchable[1] =
1359                             rman_get_flags(rle->res) & RF_PREFETCHABLE;
1360                 } else if (rman_get_end(rle->res) > ends[1] &&
1361                     rman_get_start(rle->res) - ends[1] <
1362                     PCCBB_AUTO_OPEN_SMALLHOLE && prefetchable[1] ==
1363                     (rman_get_flags(rle->res) & RF_PREFETCHABLE)) {
1364                         ends[1] = rman_get_end(rle->res);
1365                 } else if (rman_get_start(rle->res) < starts[1] &&
1366                     starts[1] - rman_get_end(rle->res) <
1367                     PCCBB_AUTO_OPEN_SMALLHOLE && prefetchable[1] ==
1368                     (rman_get_flags(rle->res) & RF_PREFETCHABLE)) {
1369                         starts[1] = rman_get_start(rle->res);
1370                 } else {
1371                         uint32_t diffs[2];
1372                         int win;
1373
1374                         diffs[0] = diffs[1] = 0xffffffff;
1375                         if (rman_get_start(rle->res) > ends[0])
1376                                 diffs[0] = rman_get_start(rle->res) - ends[0];
1377                         else if (rman_get_end(rle->res) < starts[0])
1378                                 diffs[0] = starts[0] - rman_get_end(rle->res);
1379                         if (rman_get_start(rle->res) > ends[1])
1380                                 diffs[1] = rman_get_start(rle->res) - ends[1];
1381                         else if (rman_get_end(rle->res) < starts[1])
1382                                 diffs[1] = starts[1] - rman_get_end(rle->res);
1383
1384                         win = (diffs[0] <= diffs[1])?0:1;
1385                         if (rman_get_start(rle->res) > ends[win])
1386                                 ends[win] = rman_get_end(rle->res);
1387                         else if (rman_get_end(rle->res) < starts[win])
1388                                 starts[win] = rman_get_start(rle->res);
1389                         if (!(rman_get_flags(rle->res) & RF_PREFETCHABLE))
1390                                 prefetchable[win] = 0;
1391                 }
1392
1393                 if (starts[0] != 0xffffffff)
1394                         starts[0] -= starts[0] % align;
1395                 if (starts[1] != 0xffffffff)
1396                         starts[1] -= starts[1] % align;
1397                 if (ends[0] % align != 0)
1398                         ends[0] += align - ends[0]%align - 1;
1399                 if (ends[1] % align != 0)
1400                         ends[1] += align - ends[1]%align - 1;
1401         }
1402
1403         if (type == SYS_RES_MEMORY) {
1404                 pccbb_cardbus_mem_open(sc->dev, 0, starts[0], ends[0]);
1405                 pccbb_cardbus_mem_open(sc->dev, 1, starts[1], ends[1]);
1406                 reg = pci_read_config(sc->dev, CBBR_BRIDGECTRL, 2);
1407                 reg &= ~(CBBM_BRIDGECTRL_PREFETCH_0|
1408                     CBBM_BRIDGECTRL_PREFETCH_1);
1409                 reg |= (prefetchable[0]?CBBM_BRIDGECTRL_PREFETCH_0:0)|
1410                     (prefetchable[1]?CBBM_BRIDGECTRL_PREFETCH_1:0);
1411                 pci_write_config(sc->dev, CBBR_BRIDGECTRL, reg, 2);
1412         } else if (type == SYS_RES_IOPORT) {
1413                 pccbb_cardbus_io_open(sc->dev, 0, starts[0], ends[0]);
1414                 pccbb_cardbus_io_open(sc->dev, 1, starts[1], ends[1]);
1415         }
1416 }
1417
1418 static int
1419 pccbb_cardbus_activate_resource(device_t brdev, device_t child, int type,
1420     int rid, struct resource *res)
1421 {
1422         int ret;
1423
1424         ret = BUS_ACTIVATE_RESOURCE(device_get_parent(brdev), child,
1425             type, rid, res);
1426         if (ret != 0)
1427                 return (ret);
1428         pccbb_cardbus_auto_open(device_get_softc(brdev), type);
1429         return (0);
1430 }
1431
1432 static int
1433 pccbb_cardbus_deactivate_resource(device_t brdev, device_t child, int type,
1434     int rid, struct resource *res)
1435 {
1436         int ret;
1437
1438         ret = BUS_DEACTIVATE_RESOURCE(device_get_parent(brdev), child,
1439             type, rid, res);
1440         if (ret != 0)
1441                 return (ret);
1442         pccbb_cardbus_auto_open(device_get_softc(brdev), type);
1443         return (0);
1444 }
1445
1446 static struct resource *
1447 pccbb_cardbus_alloc_resource(device_t brdev, device_t child, int type,
1448     int *rid, u_long start, u_long end, u_long count, uint flags)
1449 {
1450         struct pccbb_softc *sc = device_get_softc(brdev);
1451         int tmp;
1452         struct resource *res;
1453
1454         switch (type) {
1455         case SYS_RES_IRQ:
1456                 tmp = rman_get_start(sc->irq_res);
1457                 if (start > tmp || end < tmp || count != 1) {
1458                         device_printf(child, "requested interrupt %ld-%ld,"
1459                             "count = %ld not supported by pccbb\n",
1460                             start, end, count);
1461                         return (NULL);
1462                 }
1463                 start = end = tmp;
1464                 break;
1465         case SYS_RES_IOPORT:
1466                 if (start <= pccbb_start_32_io)
1467                         start = pccbb_start_32_io;
1468                 if (end < start)
1469                         end = start;
1470                 break;
1471         case SYS_RES_MEMORY:
1472                 if (start <= pccbb_start_mem)
1473                         start = pccbb_start_mem;
1474                 if (end < start)
1475                         end = start;
1476                 break;
1477         }
1478
1479         res = BUS_ALLOC_RESOURCE(device_get_parent(brdev), child, type, rid,
1480             start, end, count, flags & ~RF_ACTIVE);
1481         if (res == NULL) {
1482                 printf("pccbb alloc res fail\n");
1483                 return (NULL);
1484         }
1485         pccbb_insert_res(sc, res, type, *rid);
1486         if (flags & RF_ACTIVE)
1487                 if (bus_activate_resource(child, type, *rid, res) != 0) {
1488                         bus_release_resource(child, type, *rid, res);
1489                         return (NULL);
1490                 }
1491
1492         return (res);
1493 }
1494
1495 static int
1496 pccbb_cardbus_release_resource(device_t brdev, device_t child, int type,
1497     int rid, struct resource *res)
1498 {
1499         struct pccbb_softc *sc = device_get_softc(brdev);
1500         int error;
1501
1502         if (rman_get_flags(res) & RF_ACTIVE) {
1503                 error = bus_deactivate_resource(child, type, rid, res);
1504                 if (error != 0)
1505                         return (error);
1506         }
1507         pccbb_remove_res(sc, res);
1508         return (BUS_RELEASE_RESOURCE(device_get_parent(brdev), child,
1509             type, rid, res));
1510 }
1511
1512 /************************************************************************/
1513 /* PC Card Power Functions                                              */
1514 /************************************************************************/
1515
1516 static int
1517 pccbb_pcic_power_enable_socket(device_t brdev, device_t child)
1518 {
1519         struct pccbb_softc *sc = device_get_softc(brdev);
1520         int err;
1521
1522         DPRINTF(("pccbb_pcic_socket_enable:\n"));
1523
1524         /* power down/up the socket to reset */
1525         err = pccbb_do_power(brdev);
1526         if (err)
1527                 return (err);
1528         exca_reset(&sc->exca, child);
1529
1530         return (0);
1531 }
1532
1533 static void
1534 pccbb_pcic_power_disable_socket(device_t brdev, device_t child)
1535 {
1536         struct pccbb_softc *sc = device_get_softc(brdev);
1537
1538         DPRINTF(("pccbb_pcic_socket_disable\n"));
1539
1540         /* reset signal asserting... */
1541         exca_clrb(&sc->exca, EXCA_INTR, EXCA_INTR_RESET);
1542         DELAY(2*1000);
1543
1544         /* power down the socket */
1545         pccbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V);
1546         exca_clrb(&sc->exca, EXCA_PWRCTL, EXCA_PWRCTL_OE);
1547
1548         /* wait 300ms until power fails (Tpf). */
1549         DELAY(300 * 1000);
1550 }
1551
1552 /************************************************************************/
1553 /* POWER methods                                                        */
1554 /************************************************************************/
1555
1556 static int
1557 pccbb_power_enable_socket(device_t brdev, device_t child)
1558 {
1559         struct pccbb_softc *sc = device_get_softc(brdev);
1560
1561         if (sc->flags & PCCBB_16BIT_CARD)
1562                 return (pccbb_pcic_power_enable_socket(brdev, child));
1563         else
1564                 return (pccbb_cardbus_power_enable_socket(brdev, child));
1565 }
1566
1567 static void
1568 pccbb_power_disable_socket(device_t brdev, device_t child)
1569 {
1570         struct pccbb_softc *sc = device_get_softc(brdev);
1571         if (sc->flags & PCCBB_16BIT_CARD)
1572                 pccbb_pcic_power_disable_socket(brdev, child);
1573         else
1574                 pccbb_cardbus_power_disable_socket(brdev, child);
1575 }
1576 static int
1577 pccbb_pcic_activate_resource(device_t brdev, device_t child, int type, int rid,
1578     struct resource *res)
1579 {
1580         int err;
1581         struct pccbb_softc *sc = device_get_softc(brdev);
1582         if (!(rman_get_flags(res) & RF_ACTIVE)) { /* not already activated */
1583                 switch (type) {
1584                 case SYS_RES_IOPORT:
1585                         err = exca_io_map(&sc->exca, 0, res);
1586                         break;
1587                 case SYS_RES_MEMORY:
1588                         err = exca_mem_map(&sc->exca, 0, res);
1589                         break;
1590                 default:
1591                         err = 0;
1592                         break;
1593                 }
1594                 if (err)
1595                         return (err);
1596
1597         }
1598         return (BUS_ACTIVATE_RESOURCE(device_get_parent(brdev), child,
1599             type, rid, res));
1600 }
1601
1602 static int
1603 pccbb_pcic_deactivate_resource(device_t brdev, device_t child, int type,
1604     int rid, struct resource *res)
1605 {
1606         struct pccbb_softc *sc = device_get_softc(brdev);
1607
1608         if (rman_get_flags(res) & RF_ACTIVE) { /* if activated */
1609                 switch (type) {
1610                 case SYS_RES_IOPORT:
1611                         if (exca_io_unmap_res(&sc->exca, res))
1612                                 return (ENOENT);
1613                         break;
1614                 case SYS_RES_MEMORY:
1615                         if (exca_mem_unmap_res(&sc->exca, res))
1616                                 return (ENOENT);
1617                         break;
1618                 }
1619         }
1620         return (BUS_DEACTIVATE_RESOURCE(device_get_parent(brdev), child,
1621             type, rid, res));
1622 }
1623
1624 static struct resource *
1625 pccbb_pcic_alloc_resource(device_t brdev, device_t child, int type, int *rid,
1626     u_long start, u_long end, u_long count, uint flags)
1627 {
1628         struct resource *res = NULL;
1629         struct pccbb_softc *sc = device_get_softc(brdev);
1630         int tmp;
1631
1632         switch (type) {
1633         case SYS_RES_MEMORY:
1634                 if (start < pccbb_start_mem)
1635                         start = pccbb_start_mem;
1636                 if (end < start)
1637                         end = start;
1638                 flags = (flags & ~RF_ALIGNMENT_MASK) |
1639                     rman_make_alignment_flags(CBB_MEMALIGN);
1640                 break;
1641         case SYS_RES_IOPORT:
1642                 if (start < pccbb_start_16_io)
1643                         start = pccbb_start_16_io;
1644                 if (end < start)
1645                         end = start;
1646                 break;
1647         case SYS_RES_IRQ:
1648                 tmp = rman_get_start(sc->irq_res);
1649                 if (start > tmp || end < tmp || count != 1) {
1650                         device_printf(child, "requested interrupt %ld-%ld,"
1651                             "count = %ld not supported by pccbb\n",
1652                             start, end, count);
1653                         return (NULL);
1654                 }
1655                 flags |= RF_SHAREABLE;
1656                 start = end = rman_get_start(sc->irq_res);
1657                 break;
1658         }
1659         res = BUS_ALLOC_RESOURCE(device_get_parent(brdev), child, type, rid,
1660             start, end, count, flags & ~RF_ACTIVE);
1661         if (res == NULL)
1662                 return (NULL);
1663         pccbb_insert_res(sc, res, type, *rid);
1664         if (flags & RF_ACTIVE) {
1665                 if (bus_activate_resource(child, type, *rid, res) != 0) {
1666                         bus_release_resource(child, type, *rid, res);
1667                         return (NULL);
1668                 }
1669         }
1670
1671         return (res);
1672 }
1673
1674 static int
1675 pccbb_pcic_release_resource(device_t brdev, device_t child, int type,
1676     int rid, struct resource *res)
1677 {
1678         struct pccbb_softc *sc = device_get_softc(brdev);
1679         int error;
1680
1681         if (rman_get_flags(res) & RF_ACTIVE) {
1682                 error = bus_deactivate_resource(child, type, rid, res);
1683                 if (error != 0)
1684                         return (error);
1685         }
1686         pccbb_remove_res(sc, res);
1687         return (BUS_RELEASE_RESOURCE(device_get_parent(brdev), child,
1688             type, rid, res));
1689 }
1690
1691 /************************************************************************/
1692 /* PC Card methods                                                      */
1693 /************************************************************************/
1694
1695 static int
1696 pccbb_pcic_set_res_flags(device_t brdev, device_t child, int type, int rid,
1697     uint32_t flags)
1698 {
1699         struct pccbb_softc *sc = device_get_softc(brdev);
1700         struct resource *res;
1701
1702         if (type != SYS_RES_MEMORY)
1703                 return (EINVAL);
1704         res = pccbb_find_res(sc, type, rid);
1705         if (res == NULL) {
1706                 device_printf(brdev,
1707                     "set_res_flags: specified rid not found\n");
1708                 return (ENOENT);
1709         }
1710         return (exca_mem_set_flags(&sc->exca, res, flags));
1711 }
1712
1713 static int
1714 pccbb_pcic_set_memory_offset(device_t brdev, device_t child, int rid,
1715     uint32_t cardaddr, uint32_t *deltap)
1716 {
1717         struct pccbb_softc *sc = device_get_softc(brdev);
1718         struct resource *res;
1719
1720         res = pccbb_find_res(sc, SYS_RES_MEMORY, rid);
1721         if (res == NULL) {
1722                 device_printf(brdev,
1723                     "set_memory_offset: specified rid not found\n");
1724                 return (ENOENT);
1725         }
1726         return (exca_mem_set_offset(&sc->exca, res, cardaddr, deltap));
1727 }
1728
1729 /************************************************************************/
1730 /* BUS Methods                                                          */
1731 /************************************************************************/
1732
1733
1734 static int
1735 pccbb_activate_resource(device_t brdev, device_t child, int type, int rid,
1736     struct resource *r)
1737 {
1738         struct pccbb_softc *sc = device_get_softc(brdev);
1739
1740         if (sc->flags & PCCBB_16BIT_CARD)
1741                 return (pccbb_pcic_activate_resource(brdev, child, type, rid, r));
1742         else
1743                 return (pccbb_cardbus_activate_resource(brdev, child, type, rid,
1744                     r));
1745 }
1746
1747 static int
1748 pccbb_deactivate_resource(device_t brdev, device_t child, int type,
1749     int rid, struct resource *r)
1750 {
1751         struct pccbb_softc *sc = device_get_softc(brdev);
1752
1753         if (sc->flags & PCCBB_16BIT_CARD)
1754                 return (pccbb_pcic_deactivate_resource(brdev, child, type,
1755                     rid, r));
1756         else
1757                 return (pccbb_cardbus_deactivate_resource(brdev, child, type,
1758                     rid, r));
1759 }
1760
1761 static struct resource *
1762 pccbb_alloc_resource(device_t brdev, device_t child, int type, int *rid,
1763     u_long start, u_long end, u_long count, uint flags)
1764 {
1765         struct pccbb_softc *sc = device_get_softc(brdev);
1766
1767         if (sc->flags & PCCBB_16BIT_CARD)
1768                 return (pccbb_pcic_alloc_resource(brdev, child, type, rid,
1769                     start, end, count, flags));
1770         else
1771                 return (pccbb_cardbus_alloc_resource(brdev, child, type, rid,
1772                     start, end, count, flags));
1773 }
1774
1775 static int
1776 pccbb_release_resource(device_t brdev, device_t child, int type, int rid,
1777     struct resource *r)
1778 {
1779         struct pccbb_softc *sc = device_get_softc(brdev);
1780
1781         if (sc->flags & PCCBB_16BIT_CARD)
1782                 return (pccbb_pcic_release_resource(brdev, child, type,
1783                     rid, r));
1784         else
1785                 return (pccbb_cardbus_release_resource(brdev, child, type,
1786                     rid, r));
1787 }
1788
1789 static int
1790 pccbb_read_ivar(device_t brdev, device_t child, int which, uintptr_t *result)
1791 {
1792         struct pccbb_softc *sc = device_get_softc(brdev);
1793
1794         switch (which) {
1795         case PCIB_IVAR_BUS:
1796                 *result = sc->secbus;
1797                 return (0);
1798         }
1799         return (ENOENT);
1800 }
1801
1802 static int
1803 pccbb_write_ivar(device_t brdev, device_t child, int which, uintptr_t value)
1804 {
1805         struct pccbb_softc *sc = device_get_softc(brdev);
1806
1807         switch (which) {
1808         case PCIB_IVAR_BUS:
1809                 sc->secbus = value;
1810                 break;
1811         }
1812         return (ENOENT);
1813 }
1814
1815 /************************************************************************/
1816 /* PCI compat methods                                                   */
1817 /************************************************************************/
1818
1819 static int
1820 pccbb_maxslots(device_t brdev)
1821 {
1822         return (0);
1823 }
1824
1825 static uint32_t
1826 pccbb_read_config(device_t brdev, int b, int s, int f, int reg, int width)
1827 {
1828         /*
1829          * Pass through to the next ppb up the chain (i.e. our grandparent).
1830          */
1831         return (PCIB_READ_CONFIG(device_get_parent(device_get_parent(brdev)),
1832             b, s, f, reg, width));
1833 }
1834
1835 static void
1836 pccbb_write_config(device_t brdev, int b, int s, int f, int reg, uint32_t val,
1837     int width)
1838 {
1839         /*
1840          * Pass through to the next ppb up the chain (i.e. our grandparent).
1841          */
1842         PCIB_WRITE_CONFIG(device_get_parent(device_get_parent(brdev)),
1843             b, s, f, reg, val, width);
1844 }
1845
1846 static int
1847 pccbb_suspend(device_t self)
1848 {
1849         int                     error = 0;
1850         struct pccbb_softc*     sc = device_get_softc(self);
1851
1852         bus_teardown_intr(self, sc->irq_res, sc->intrhand);
1853         error = bus_generic_suspend(self);
1854         return (error);
1855 }
1856
1857 static int
1858 pccbb_resume(device_t self)
1859 {
1860         int     error = 0;
1861         struct pccbb_softc *sc = (struct pccbb_softc *)device_get_softc(self);
1862         uint32_t tmp;
1863
1864         pci_write_config(self, CBBR_SOCKBASE, rman_get_start(sc->base_res), 4);
1865         DEVPRINTF((self, "PCI Memory allocated: %08lx\n",
1866             rman_get_start(sc->base_res)));
1867
1868         pccbb_chipinit(sc);
1869
1870         /* re-establish the interrupt. */
1871         if (bus_setup_intr(self, sc->irq_res, INTR_TYPE_AV, pccbb_intr, sc,
1872             &sc->intrhand)) {
1873                 device_printf(self, "couldn't re-establish interrupt");
1874                 bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
1875                 bus_release_resource(self, SYS_RES_MEMORY, CBBR_SOCKBASE,
1876                     sc->base_res);
1877                 sc->irq_res = NULL;
1878                 sc->base_res = NULL;
1879                 return (ENOMEM);
1880         }
1881
1882         /* CSC Interrupt: Card detect interrupt on */
1883         pccbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD);
1884
1885         /* reset interrupt */
1886         tmp = pccbb_get(sc, CBB_SOCKET_EVENT);
1887         pccbb_set(sc, CBB_SOCKET_EVENT, tmp);
1888
1889         /*
1890          * Some BIOSes will not save the BARs for the pci chips, so we
1891          * must do it ourselves.  If the BAR is reset to 0 for an I/O
1892          * device, it will read back as 0x1, so no explicit test for
1893          * memory devices are needed.
1894          *
1895          * Note: The PCI bus code should do this automatically for us on
1896          * suspend/resume, but until it does, we have to cope.
1897          */
1898         if (pci_read_config(self, CBBR_SOCKBASE, 4) == 0)
1899                 pci_write_config(self, CBBR_SOCKBASE,
1900                     rman_get_start(sc->base_res), 4);
1901
1902         error = bus_generic_resume(self);
1903
1904         return (error);
1905 }
1906
1907 static device_method_t pccbb_methods[] = {
1908         /* Device interface */
1909         DEVMETHOD(device_probe,                 pccbb_probe),
1910         DEVMETHOD(device_attach,                pccbb_attach),
1911         DEVMETHOD(device_detach,                pccbb_detach),
1912         DEVMETHOD(device_shutdown,              pccbb_shutdown),
1913         DEVMETHOD(device_suspend,               pccbb_suspend),
1914         DEVMETHOD(device_resume,                pccbb_resume),
1915
1916         /* bus methods */
1917         DEVMETHOD(bus_print_child,              bus_generic_print_child),
1918         DEVMETHOD(bus_read_ivar,                pccbb_read_ivar),
1919         DEVMETHOD(bus_write_ivar,               pccbb_write_ivar),
1920         DEVMETHOD(bus_alloc_resource,           pccbb_alloc_resource),
1921         DEVMETHOD(bus_release_resource,         pccbb_release_resource),
1922         DEVMETHOD(bus_activate_resource,        pccbb_activate_resource),
1923         DEVMETHOD(bus_deactivate_resource,      pccbb_deactivate_resource),
1924         DEVMETHOD(bus_driver_added,             pccbb_driver_added),
1925         DEVMETHOD(bus_child_detached,           pccbb_child_detached),
1926         DEVMETHOD(bus_setup_intr,               pccbb_setup_intr),
1927         DEVMETHOD(bus_teardown_intr,            pccbb_teardown_intr),
1928
1929         /* 16-bit card interface */
1930         DEVMETHOD(card_set_res_flags,           pccbb_pcic_set_res_flags),
1931         DEVMETHOD(card_set_memory_offset,       pccbb_pcic_set_memory_offset),
1932         DEVMETHOD(card_reprobe_card,            pccbb_card_reprobe),
1933
1934         /* power interface */
1935         DEVMETHOD(power_enable_socket,          pccbb_power_enable_socket),
1936         DEVMETHOD(power_disable_socket,         pccbb_power_disable_socket),
1937
1938         /* pcib compatibility interface */
1939         DEVMETHOD(pcib_maxslots,                pccbb_maxslots),
1940         DEVMETHOD(pcib_read_config,             pccbb_read_config),
1941         DEVMETHOD(pcib_write_config,            pccbb_write_config),
1942         {0,0}
1943 };
1944
1945 static driver_t pccbb_driver = {
1946         "pccbb",
1947         pccbb_methods,
1948         sizeof(struct pccbb_softc)
1949 };
1950
1951 static devclass_t pccbb_devclass;
1952
1953 DRIVER_MODULE(pccbb, pci, pccbb_driver, pccbb_devclass, 0, 0);
1954 MODULE_VERSION(pccbb, 1);
1955 MODULE_DEPEND(pccbb, exca, 1, 1, 1);
1956 MODULE_DEPEND(pccbb, pccard, 1, 1, 1);
1957 MODULE_DEPEND(pccbb, cardbus, 1, 1, 1);