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