Bug Summary

File:dev/pci/pccbb.c
Warning:line 983, column 2
Value stored to 'sockevent' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name pccbb.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/pci/pccbb.c
1/* $OpenBSD: pccbb.c,v 1.101 2021/03/05 12:40:13 jsg Exp $ */
2/* $NetBSD: pccbb.c,v 1.96 2004/03/28 09:49:31 nakayama Exp $ */
3
4/*
5 * Copyright (c) 1998, 1999 and 2000
6 * HAYAKAWA Koichi. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30#define CBB_DEBUG
31#define SHOW_REGS
32#define PCCBB_PCMCIA_POLL
33*/
34
35/*
36#define CB_PCMCIA_POLL
37#define CB_PCMCIA_POLL_ONLY
38#define LEVEL2
39*/
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/kernel.h>
44#include <sys/evcount.h>
45#include <sys/ioctl.h>
46#include <sys/syslog.h>
47#include <sys/device.h>
48#include <sys/malloc.h>
49#include <sys/task.h>
50#include <sys/time.h>
51#include <sys/timeout.h>
52
53#include <machine/intr.h>
54#include <machine/bus.h>
55
56#include <dev/pci/pcivar.h>
57#include <dev/pci/pcireg.h>
58#include <dev/pci/pcidevs.h>
59
60#include <dev/pci/pccbbreg.h>
61
62#include <dev/cardbus/cardslotvar.h>
63
64#include <dev/cardbus/cardbusvar.h>
65
66#include <dev/pcmcia/pcmciareg.h>
67#include <dev/pcmcia/pcmciavar.h>
68
69#include <dev/ic/i82365reg.h>
70#include <dev/ic/i82365var.h>
71#include <dev/pci/pccbbvar.h>
72
73#ifndef __NetBSD_Version__
74struct cfdriver cbb_cd = {
75 NULL((void *)0), "cbb", DV_DULL
76};
77#endif
78
79#if defined CBB_DEBUG
80#define DPRINTF(x) printf x
81#else
82#define DPRINTF(x)
83#endif
84
85int pcicbbmatch(struct device *, void *, void *);
86void pccbbattach(struct device *, struct device *, void *);
87int pccbbactivate(struct device *, int);
88int pccbbintr(void *);
89void pccbb_shutdown(void *);
90void pci113x_insert(void *);
91int pccbbintr_function(struct pccbb_softc *);
92
93int pccbb_checksockstat(struct pccbb_softc *);
94int pccbb_detect_card(struct pccbb_softc *);
95
96void pccbb_pcmcia_write(struct pcic_handle *, int, int);
97u_int8_t pccbb_pcmcia_read(struct pcic_handle *, int);
98#define Pcic_read(ph, reg)((ph)->ph_read((ph), (reg))) ((ph)->ph_read((ph), (reg)))
99#define Pcic_write(ph, reg, val)((ph)->ph_write((ph), (reg), (val))) ((ph)->ph_write((ph), (reg), (val)))
100
101int cb_reset(struct pccbb_softc *);
102int cb_detect_voltage(struct pccbb_softc *);
103int cbbprint(void *, const char *);
104
105int cb_chipset(u_int32_t, int *);
106void pccbb_pcmcia_attach_setup(struct pccbb_softc *,
107 struct pcmciabus_attach_args *);
108#if 0
109void pccbb_pcmcia_attach_card(struct pcic_handle *);
110void pccbb_pcmcia_detach_card(struct pcic_handle *, int);
111void pccbb_pcmcia_deactivate_card(struct pcic_handle *);
112#endif
113
114int pccbb_ctrl(cardbus_chipset_tag_t, int);
115int pccbb_power(cardbus_chipset_tag_t, int);
116int pccbb_cardenable(struct pccbb_softc * sc, int function);
117void *pccbb_intr_establish(struct pccbb_softc *, int irq, int level,
118 int (*ih) (void *), void *sc, const char *);
119void pccbb_intr_disestablish(struct pccbb_softc *, void *ih);
120
121void *pccbb_cb_intr_establish(cardbus_chipset_tag_t, int irq, int level,
122 int (*ih) (void *), void *sc, const char *);
123void pccbb_cb_intr_disestablish(cardbus_chipset_tag_t ct, void *ih);
124
125void pccbb_legacy_disable(struct pccbb_softc *sc);
126void pccbb_chipinit(struct pccbb_softc *);
127
128int pccbb_pcmcia_mem_alloc(pcmcia_chipset_handle_t, bus_size_t,
129 struct pcmcia_mem_handle *);
130void pccbb_pcmcia_mem_free(pcmcia_chipset_handle_t,
131 struct pcmcia_mem_handle *);
132int pccbb_pcmcia_mem_map(pcmcia_chipset_handle_t, int, bus_addr_t,
133 bus_size_t, struct pcmcia_mem_handle *, bus_size_t *, int *);
134void pccbb_pcmcia_mem_unmap(pcmcia_chipset_handle_t, int);
135int pccbb_pcmcia_io_alloc(pcmcia_chipset_handle_t, bus_addr_t,
136 bus_size_t, bus_size_t, struct pcmcia_io_handle *);
137void pccbb_pcmcia_io_free(pcmcia_chipset_handle_t,
138 struct pcmcia_io_handle *);
139int pccbb_pcmcia_io_map(pcmcia_chipset_handle_t, int, bus_addr_t,
140 bus_size_t, struct pcmcia_io_handle *, int *);
141void pccbb_pcmcia_io_unmap(pcmcia_chipset_handle_t, int);
142void *pccbb_pcmcia_intr_establish(pcmcia_chipset_handle_t,
143 struct pcmcia_function *, int, int (*)(void *), void *, char *);
144void pccbb_pcmcia_intr_disestablish(pcmcia_chipset_handle_t, void *);
145const char *pccbb_pcmcia_intr_string(pcmcia_chipset_handle_t, void *);
146void pccbb_pcmcia_socket_enable(pcmcia_chipset_handle_t);
147void pccbb_pcmcia_socket_disable(pcmcia_chipset_handle_t);
148int pccbb_pcmcia_card_detect(pcmcia_chipset_handle_t pch);
149
150void pccbb_pcmcia_do_io_map(struct pcic_handle *, int);
151void pccbb_pcmcia_wait_ready(struct pcic_handle *);
152void pccbb_pcmcia_do_mem_map(struct pcic_handle *, int);
153
154/* bus-space allocation and deallocation functions */
155int pccbb_rbus_cb_space_alloc(cardbus_chipset_tag_t, rbus_tag_t,
156 bus_addr_t addr, bus_size_t size, bus_addr_t mask, bus_size_t align,
157 int flags, bus_addr_t * addrp, bus_space_handle_t * bshp);
158int pccbb_rbus_cb_space_free(cardbus_chipset_tag_t, rbus_tag_t,
159 bus_space_handle_t, bus_size_t);
160
161int pccbb_open_win(struct pccbb_softc *, bus_space_tag_t,
162 bus_addr_t, bus_size_t, bus_space_handle_t, int flags);
163int pccbb_close_win(struct pccbb_softc *, bus_space_tag_t,
164 bus_space_handle_t, bus_size_t);
165int pccbb_winlist_insert(struct pccbb_win_chain_head *, bus_addr_t,
166 bus_size_t, bus_space_handle_t, int);
167int pccbb_winlist_delete(struct pccbb_win_chain_head *,
168 bus_space_handle_t, bus_size_t);
169void pccbb_winset(bus_addr_t align, struct pccbb_softc *,
170 bus_space_tag_t);
171void pccbb_winlist_show(struct pccbb_win_chain *);
172
173/* for config_defer */
174void pccbb_pci_callback(struct device *);
175
176#if defined SHOW_REGS
177void cb_show_regs(pci_chipset_tag_t, pcitag_t, bus_space_tag_t,
178 bus_space_handle_t memh);
179#endif
180
181struct cfattach cbb_pci_ca = {
182 sizeof(struct pccbb_softc), pcicbbmatch, pccbbattach, NULL((void *)0),
183 pccbbactivate
184};
185
186static struct pcmcia_chip_functions pccbb_pcmcia_funcs = {
187 pccbb_pcmcia_mem_alloc,
188 pccbb_pcmcia_mem_free,
189 pccbb_pcmcia_mem_map,
190 pccbb_pcmcia_mem_unmap,
191 pccbb_pcmcia_io_alloc,
192 pccbb_pcmcia_io_free,
193 pccbb_pcmcia_io_map,
194 pccbb_pcmcia_io_unmap,
195 pccbb_pcmcia_intr_establish,
196 pccbb_pcmcia_intr_disestablish,
197 pccbb_pcmcia_intr_string,
198 pccbb_pcmcia_socket_enable,
199 pccbb_pcmcia_socket_disable,
200 pccbb_pcmcia_card_detect
201};
202
203static struct cardbus_functions pccbb_funcs = {
204 pccbb_rbus_cb_space_alloc,
205 pccbb_rbus_cb_space_free,
206 pccbb_cb_intr_establish,
207 pccbb_cb_intr_disestablish,
208 pccbb_ctrl,
209 pccbb_power,
210};
211
212/*
213 * delay_ms() is wait in milliseconds. It should be used instead
214 * of delay() if you want to wait more than 1 ms.
215 */
216static inline void
217delay_ms(int millis, void *param)
218{
219 if (cold)
220 delay(millis * 1000)(*delay_func)(millis * 1000);
221 else
222 tsleep_nsec(param, PWAIT32, "pccbb", MSEC_TO_NSEC(millis));
223}
224
225int
226pcicbbmatch(struct device *parent, void *match, void *aux)
227{
228 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
229
230 if (PCI_CLASS(pa->pa_class)(((pa->pa_class) >> 24) & 0xff) == PCI_CLASS_BRIDGE0x06 &&
231 PCI_SUBCLASS(pa->pa_class)(((pa->pa_class) >> 16) & 0xff) == PCI_SUBCLASS_BRIDGE_CARDBUS0x07 &&
232 PCI_INTERFACE(pa->pa_class)(((pa->pa_class) >> 8) & 0xff) == 0) {
233 return 1;
234 }
235
236 return 0;
237}
238
239#define MAKEID(vendor, prod)(((vendor) << 0) | ((prod) << 16)) (((vendor) << PCI_VENDOR_SHIFT0) \
240 | ((prod) << PCI_PRODUCT_SHIFT16))
241
242struct yenta_chipinfo {
243 pcireg_t yc_id; /* vendor tag | product tag */
244 int yc_chiptype;
245 int yc_flags;
246} yc_chipsets[] = {
247 /* Texas Instruments chips */
248 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1130)(((0x104c) << 0) | ((0xac12) << 16)), CB_TI113X1,
249 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
250 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1131)(((0x104c) << 0) | ((0xac15) << 16)), CB_TI113X1,
251 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
252 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1250)(((0x104c) << 0) | ((0xac16) << 16)), CB_TI125X9,
253 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
254 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1220)(((0x104c) << 0) | ((0xac17) << 16)), CB_TI12XX2,
255 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
256 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1221)(((0x104c) << 0) | ((0xac19) << 16)), CB_TI12XX2,
257 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
258 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1225)(((0x104c) << 0) | ((0xac1c) << 16)), CB_TI12XX2,
259 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
260 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1251)(((0x104c) << 0) | ((0xac1d) << 16)), CB_TI125X9,
261 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
262 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1251B)(((0x104c) << 0) | ((0xac1f) << 16)), CB_TI125X9,
263 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
264 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1211)(((0x104c) << 0) | ((0xac1e) << 16)), CB_TI12XX2,
265 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
266 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1410)(((0x104c) << 0) | ((0xac50) << 16)), CB_TI12XX2,
267 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
268 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1420)(((0x104c) << 0) | ((0xac51) << 16)), CB_TI12XX2,
269 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
270 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1450)(((0x104c) << 0) | ((0xac1b) << 16)), CB_TI125X9,
271 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
272 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1451)(((0x104c) << 0) | ((0xac52) << 16)), CB_TI12XX2,
273 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
274 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1510)(((0x104c) << 0) | ((0xac56) << 16)), CB_TI12XX2,
275 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
276 { MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI7XX1)(((0x104c) << 0) | ((0x8031) << 16)), CB_TI12XX2,
277 PCCBB_PCMCIA_IO_RELOC0x01 | PCCBB_PCMCIA_MEM_320x02},
278
279 /* Ricoh chips */
280 { MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RF5C475)(((0x1180) << 0) | ((0x0475) << 16)), CB_RX5C47X3,
281 PCCBB_PCMCIA_MEM_320x02},
282 { MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RF5C476)(((0x1180) << 0) | ((0x0476) << 16)), CB_RX5C47X3,
283 PCCBB_PCMCIA_MEM_320x02},
284 { MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RF5C477)(((0x1180) << 0) | ((0x0477) << 16)), CB_RX5C47X3,
285 PCCBB_PCMCIA_MEM_320x02},
286 { MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RF5C478)(((0x1180) << 0) | ((0x0478) << 16)), CB_RX5C47X3,
287 PCCBB_PCMCIA_MEM_320x02},
288 { MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RF5C465)(((0x1180) << 0) | ((0x0465) << 16)), CB_RX5C46X4,
289 PCCBB_PCMCIA_MEM_320x02},
290 { MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RF5C466)(((0x1180) << 0) | ((0x0466) << 16)), CB_RX5C46X4,
291 PCCBB_PCMCIA_MEM_320x02},
292
293 /* Toshiba products */
294 { MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_TOPIC95)(((0x1179) << 0) | ((0x0603) << 16)),
295 CB_TOPIC955, PCCBB_PCMCIA_MEM_320x02},
296 { MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_TOPIC95B)(((0x1179) << 0) | ((0x060a) << 16)),
297 CB_TOPIC95B6, PCCBB_PCMCIA_MEM_320x02},
298 { MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_TOPIC97)(((0x1179) << 0) | ((0x060f) << 16)),
299 CB_TOPIC977, PCCBB_PCMCIA_MEM_320x02},
300 { MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_TOPIC100)(((0x1179) << 0) | ((0x0617) << 16)),
301 CB_TOPIC977, PCCBB_PCMCIA_MEM_320x02},
302
303 /* Cirrus Logic products */
304 { MAKEID(PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CL_PD6832)(((0x1013) << 0) | ((0x1110) << 16)),
305 CB_CIRRUS8, PCCBB_PCMCIA_MEM_320x02},
306 { MAKEID(PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CL_PD6833)(((0x1013) << 0) | ((0x1113) << 16)),
307 CB_CIRRUS8, PCCBB_PCMCIA_MEM_320x02},
308
309 /* older O2Micro bridges */
310 { MAKEID(PCI_VENDOR_O2MICRO, PCI_PRODUCT_O2MICRO_OZ6729)(((0x1217) << 0) | ((0x6729) << 16)),
311 CB_OLDO2MICRO10, PCCBB_PCMCIA_MEM_320x02},
312 { MAKEID(PCI_VENDOR_O2MICRO, PCI_PRODUCT_O2MICRO_OZ6730)(((0x1217) << 0) | ((0x673a) << 16)),
313 CB_OLDO2MICRO10, PCCBB_PCMCIA_MEM_320x02},
314 { MAKEID(PCI_VENDOR_O2MICRO, PCI_PRODUCT_O2MICRO_OZ6872)(((0x1217) << 0) | ((0x6872) << 16)), /* 68[71]2 */
315 CB_OLDO2MICRO10, PCCBB_PCMCIA_MEM_320x02},
316 { MAKEID(PCI_VENDOR_O2MICRO, PCI_PRODUCT_O2MICRO_OZ6832)(((0x1217) << 0) | ((0x6832) << 16)),
317 CB_OLDO2MICRO10, PCCBB_PCMCIA_MEM_320x02},
318 { MAKEID(PCI_VENDOR_O2MICRO, PCI_PRODUCT_O2MICRO_OZ6836)(((0x1217) << 0) | ((0x6836) << 16)),
319 CB_OLDO2MICRO10, PCCBB_PCMCIA_MEM_320x02},
320
321 /* sentinel, or Generic chip */
322 { 0 /* null id */ , CB_UNKNOWN0, PCCBB_PCMCIA_MEM_320x02},
323};
324
325int
326cb_chipset(u_int32_t pci_id, int *flagp)
327{
328 struct yenta_chipinfo *yc;
329
330 /* Loop over except the last default entry. */
331 for (yc = yc_chipsets; yc < yc_chipsets +
332 sizeof(yc_chipsets) / sizeof(yc_chipsets[0]) - 1; yc++)
333 if (pci_id == yc->yc_id)
334 break;
335
336 if (flagp != NULL((void *)0))
337 *flagp = yc->yc_flags;
338
339 return (yc->yc_chiptype);
340}
341
342void
343pccbb_shutdown(void *arg)
344{
345 struct pccbb_softc *sc = arg;
346 pcireg_t command;
347
348 DPRINTF(("%s: shutdown\n", sc->sc_dev.dv_xname));
349
350 /* turn off power */
351 pccbb_power((cardbus_chipset_tag_t)sc, CARDBUS_VCC_0V0x0004 | CARDBUS_VPP_0V0x0040);
352
353 bus_space_write_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_MASK,((sc->sc_base_memt)->write_4((sc->sc_base_memh), (0x04
), (0)))
354 0)((sc->sc_base_memt)->write_4((sc->sc_base_memh), (0x04
), (0)))
;
355
356 command = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG0x04);
357
358 command &= ~(PCI_COMMAND_IO_ENABLE0x00000001 | PCI_COMMAND_MEM_ENABLE0x00000002 |
359 PCI_COMMAND_MASTER_ENABLE0x00000004);
360 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG0x04, command);
361}
362
363void
364pccbbattach(struct device *parent, struct device *self, void *aux)
365{
366 struct pccbb_softc *sc = (void *)self;
367 struct pci_attach_args *pa = aux;
368 pci_chipset_tag_t pc = pa->pa_pc;
369 pci_intr_handle_t ih;
370 const char *intrstr = NULL((void *)0);
371 u_long busnum;
372 int flags;
373
374 pccbb_attach_hook(parent, self, pa);
375
376 sc->sc_chipset = cb_chipset(pa->pa_id, &flags);
377 sc->sc_id = pa->pa_id;
378
379#ifdef CBB_DEBUG
380 printf(" (chipflags %x)", flags);
381#endif
382
383 TAILQ_INIT(&sc->sc_memwindow)do { (&sc->sc_memwindow)->tqh_first = ((void *)0); (
&sc->sc_memwindow)->tqh_last = &(&sc->sc_memwindow
)->tqh_first; } while (0)
;
384 TAILQ_INIT(&sc->sc_iowindow)do { (&sc->sc_iowindow)->tqh_first = ((void *)0); (
&sc->sc_iowindow)->tqh_last = &(&sc->sc_iowindow
)->tqh_first; } while (0)
;
385
386 sc->sc_rbus_iot = rbus_pccbb_parent_io(self, pa);
387 sc->sc_rbus_memt = rbus_pccbb_parent_mem(self, pa);
388
389 /*
390 * MAP socket registers and ExCA registers on memory-space
391 */
392 if (pci_mapreg_map(pa, PCI_SOCKBASE0x10, PCI_MAPREG_TYPE_MEM0x00000000, 0,
393 &sc->sc_base_memt, &sc->sc_base_memh, NULL((void *)0), NULL((void *)0), 0)) {
394 printf("can't map registers\n");
395 return;
396 }
397
398 sc->sc_busnum = pci_conf_read(pc, pa->pa_tag, PCI_BUSNUM0x18);
399
400#if defined CBB_DEBUG
401 {
402 static char *intrname[5] = { "NON", "A", "B", "C", "D" };
403 printf(": intrpin %s, line %d\n",
404 intrname[pa->pa_intrpin], pa->pa_intrline);
405 }
406#endif
407
408 /* setup softc */
409 sc->sc_pc = pc;
410 sc->sc_iot = pa->pa_iot;
411 sc->sc_memt = pa->pa_memt;
412 sc->sc_dmat = pa->pa_dmat;
413 sc->sc_tag = pa->pa_tag;
414 sc->sc_function = pa->pa_function;
415 sc->sc_intrtag = pa->pa_intrtag;
416 sc->sc_intrpin = pa->pa_intrpin;
417
418 sc->sc_pcmcia_flags = flags; /* set PCMCIA facility */
419
420 /* Map and establish the interrupt. */
421 if (pci_intr_map(pa, &ih)) {
422 printf(": couldn't map interrupt\n");
423 return;
424 }
425 intrstr = pci_intr_string(pc, ih);
426 /* must do this after intr is mapped and established */
427 sc->sc_intrline = pci_intr_line(pc, ih)((ih.line) & 0xff);
428
429 /*
430 * XXX pccbbintr should be called under the priority lower
431 * than any other hard interrupts.
432 */
433 sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO0x6, pccbbintr, sc,
434 sc->sc_dev.dv_xname);
435
436 if (sc->sc_ih == NULL((void *)0)) {
437 printf(": couldn't establish interrupt");
438 if (intrstr != NULL((void *)0)) {
439 printf(" at %s", intrstr);
440 }
441 printf("\n");
442 return;
443 }
444 printf(": %s", intrstr);
445
446 /*
447 * When the bus number isn't configured, try to allocate one
448 * ourselves.
449 */
450 if ((sc->sc_busnum & 0x00ffff00) == 0 && pa->pa_busex &&
451 extent_alloc(pa->pa_busex, 1, 1, 0, 0, EX_NOWAIT, &busnum)extent_alloc_subregion((pa->pa_busex), (pa->pa_busex)->
ex_start, (pa->pa_busex)->ex_end, (1), (1), (0), (0), (
0x0000), (&busnum))
== 0) {
452 sc->sc_busnum |= (busnum << 8);
453 sc->sc_busnum |= (busnum << 16);
454 pci_conf_write(pc, pa->pa_tag, PCI_BUSNUM0x18, sc->sc_busnum);
455 }
456
457 /*
458 * When the bus number still isn't set correctly, give up
459 * using 32-bit CardBus mode.
460 */
461 if (((sc->sc_busnum >> 8) & 0xff) == 0) {
462 printf(", CardBus support disabled");
463 sc->sc_pcmcia_flags |= PCCBB_PCMCIA_16BITONLY0x04;
464 }
465
466 printf("\n");
467
468 /* Disable legacy register mapping. */
469 pccbb_legacy_disable(sc);
470
471 timeout_set(&sc->sc_ins_tmo, pci113x_insert, sc);
472 config_defer(self, pccbb_pci_callback);
473}
474
475/*
476 * void pccbb_pci_callback(struct device *self)
477 *
478 * The actual attach routine: get memory space for YENTA register
479 * space, setup YENTA register and route interrupt.
480 *
481 * This function should be deferred because this device may obtain
482 * memory space dynamically. This function must avoid obtaining
483 * memory area which has already kept for another device. Also,
484 * this function MUST be done before ISA attach process because this
485 * function kills pcic compatible port used by ISA pcic.
486 */
487void
488pccbb_pci_callback(struct device *self)
489{
490 struct pccbb_softc *sc = (void *)self;
491 pci_chipset_tag_t pc = sc->sc_pc;
492 bus_space_tag_t base_memt;
493 bus_space_handle_t base_memh;
494 u_int32_t maskreg;
495 struct cbslot_attach_args cba;
496 struct pcmciabus_attach_args paa;
497 struct cardslot_attach_args caa;
498 struct cardslot_softc *csc;
499 u_int32_t sockstat;
500
501 base_memt = sc->sc_base_memt; /* socket regs memory tag */
502 base_memh = sc->sc_base_memh; /* socket regs memory handle */
503
504 /* bus bridge initialization */
505 pccbb_chipinit(sc);
506
507 /* clear data structure for child device interrupt handlers */
508 sc->sc_pil = NULL((void *)0);
509 sc->sc_pil_intr_enable = 1;
510
511 sockstat = bus_space_read_4(base_memt, base_memh, CB_SOCKET_STAT)((base_memt)->read_4((base_memh), (0x08)));
512 if ((sockstat & CB_SOCKET_STAT_CD0x00000006) == 0)
513 sc->sc_flags |= CBB_CARDEXIST0x01;
514
515 /*
516 * attach cardbus
517 */
518 if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_16BITONLY0x04)) {
519 pcireg_t busreg = pci_conf_read(pc, sc->sc_tag, PCI_BUSNUM0x18);
520 pcireg_t bhlc = pci_conf_read(pc, sc->sc_tag, PCI_BHLC_REG0x0c);
521
522 /* initialize cbslot_attach */
523 cba.cba_busname = "cardbus";
524 cba.cba_iot = sc->sc_iot;
525 cba.cba_memt = sc->sc_memt;
526 cba.cba_dmat = sc->sc_dmat;
527 cba.cba_bus = (busreg >> 8) & 0x0ff;
528 cba.cba_cc = (void *)sc;
529 cba.cba_pc = sc->sc_pc;
530 cba.cba_cf = &pccbb_funcs;
531 cba.cba_intrline = sc->sc_intrline;
532
533 cba.cba_rbus_iot = sc->sc_rbus_iot;
534 cba.cba_rbus_memt = sc->sc_rbus_memt;
535
536 cba.cba_cacheline = PCI_CACHELINE(bhlc)(((bhlc) >> 0) & 0xff);
537 cba.cba_lattimer = PCI_CB_LATENCY(busreg)( ((busreg) >> 24) & 0xFF);
538
539#if defined CBB_DEBUG
540 printf("%s: cacheline 0x%x lattimer 0x%x\n",
541 sc->sc_dev.dv_xname, cba.cba_cacheline, cba.cba_lattimer);
542 printf("%s: bhlc 0x%x lscp 0x%x\n", sc->sc_dev.dv_xname, bhlc,
543 busreg);
544#endif
545#if defined SHOW_REGS
546 cb_show_regs(sc->sc_pc, sc->sc_tag, sc->sc_base_memt,
547 sc->sc_base_memh);
548#endif
549 }
550
551 pccbb_pcmcia_attach_setup(sc, &paa);
552 caa.caa_cb_attach = NULL((void *)0);
553 if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_16BITONLY0x04)) {
554 caa.caa_cb_attach = &cba;
555 }
556 caa.caa_16_attach = &paa;
557 caa.caa_ph = &sc->sc_pcmcia_h;
558
559 if (NULL((void *)0) != (csc = (void *)config_found(self, &caa, cbbprint)config_found_sm((self), (&caa), (cbbprint), ((void *)0)))) {
560 DPRINTF(("pccbbattach: found cardslot\n"));
561 sc->sc_csc = csc;
562 }
563
564 sc->sc_ints_on = 1;
565
566 /* CSC Interrupt: Card detect interrupt on */
567 maskreg = bus_space_read_4(base_memt, base_memh, CB_SOCKET_MASK)((base_memt)->read_4((base_memh), (0x04)));
568 maskreg |= CB_SOCKET_MASK_CD0x06; /* Card detect intr is turned on. */
569 bus_space_write_4(base_memt, base_memh, CB_SOCKET_MASK, maskreg)((base_memt)->write_4((base_memh), (0x04), (maskreg)));
570 /* reset interrupt */
571 bus_space_write_4(base_memt, base_memh, CB_SOCKET_EVENT,((base_memt)->write_4((base_memh), (0x00), (((base_memt)->
read_4((base_memh), (0x00))))))
572 bus_space_read_4(base_memt, base_memh, CB_SOCKET_EVENT))((base_memt)->write_4((base_memh), (0x00), (((base_memt)->
read_4((base_memh), (0x00))))))
;
573
574 return;
575}
576
577void
578pccbb_legacy_disable(struct pccbb_softc *sc)
579{
580 pcireg_t reg;
581
582 switch (sc->sc_chipset) {
583 case CB_RX5C46X4:
584 /*
585 * The legacy pcic io-port on Ricoh RX5C46X CardBus bridges
586 * cannot be disabled by substituting 0 into PCI_LEGACY
587 * register. Ricoh CardBus bridges have special bits on Bridge
588 * control reg (addr 0x3e on PCI config space).
589 */
590 reg = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR0x3C);
591 reg &= ~(CB_BCRI_RL_3E0_ENA0x08000000 | CB_BCRI_RL_3E2_ENA0x10000000);
592 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR0x3C, reg);
593 break;
594
595 default:
596 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_LEGACY0x44, 0x0);
597 break;
598 }
599}
600
601/*
602 * void pccbb_chipinit(struct pccbb_softc *sc)
603 *
604 * This function initialize YENTA chip registers listed below:
605 * 1) PCI command reg,
606 * 2) PCI and CardBus latency timer,
607 * 3) route PCI interrupt,
608 * 4) close all memory and io windows.
609 */
610void
611pccbb_chipinit(struct pccbb_softc *sc)
612{
613 pci_chipset_tag_t pc = sc->sc_pc;
614 pcitag_t tag = sc->sc_tag;
615 pcireg_t reg;
616
617 /* Power on the controller if the BIOS didn't */
618 pci_set_powerstate(pc, tag, PCI_PMCSR_STATE_D00x0000);
619
620 /*
621 * Set PCI command reg.
622 * Some laptop's BIOSes (i.e. TICO) do not enable CardBus chip.
623 */
624 reg = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG0x04);
625 /* I believe it is harmless. */
626 reg |= (PCI_COMMAND_IO_ENABLE0x00000001 | PCI_COMMAND_MEM_ENABLE0x00000002 |
627 PCI_COMMAND_MASTER_ENABLE0x00000004);
628 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG0x04, reg);
629
630 /*
631 * Set CardBus latency timer.
632 */
633 reg = pci_conf_read(pc, tag, PCI_CB_LSCP_REG0x18);
634 if (PCI_CB_LATENCY(reg)( ((reg) >> 24) & 0xFF) < 0x20) {
635 reg &= ~(PCI_CB_LATENCY_MASK0xFF << PCI_CB_LATENCY_SHIFT24);
636 reg |= (0x20 << PCI_CB_LATENCY_SHIFT24);
637 pci_conf_write(pc, tag, PCI_CB_LSCP_REG0x18, reg);
638 }
639 DPRINTF(("CardBus latency timer 0x%x (%x)\n",
640 PCI_CB_LATENCY(reg), pci_conf_read(pc, tag, PCI_CB_LSCP_REG)));
641
642 /*
643 * Set PCI latency timer.
644 */
645 reg = pci_conf_read(pc, tag, PCI_BHLC_REG0x0c);
646 if (PCI_LATTIMER(reg)(((reg) >> 8) & 0xff) < 0x10) {
647 reg &= ~(PCI_LATTIMER_MASK0xff << PCI_LATTIMER_SHIFT8);
648 reg |= (0x10 << PCI_LATTIMER_SHIFT8);
649 pci_conf_write(pc, tag, PCI_BHLC_REG0x0c, reg);
650 }
651 DPRINTF(("PCI latency timer 0x%x (%x)\n",
652 PCI_LATTIMER(reg), pci_conf_read(pc, tag, PCI_BHLC_REG)));
653
654 /* Route functional interrupts to PCI. */
655 reg = pci_conf_read(pc, tag, PCI_BCR_INTR0x3C);
656 reg |= CB_BCR_INTR_IREQ_ENABLE0x00800000; /* disable PCI Intr */
657 reg |= CB_BCR_WRITE_POST_ENABLE0x04000000; /* enable write post */
658 reg |= CB_BCR_RESET_ENABLE0x00400000; /* assert reset */
659 pci_conf_write(pc, tag, PCI_BCR_INTR0x3C, reg);
660
661 switch (sc->sc_chipset) {
662 case CB_TI113X1:
663 reg = pci_conf_read(pc, tag, PCI_CBCTRL0x90);
664 /* This bit is shared, but may read as 0 on some chips, so set
665 it explicitly on both functions. */
666 reg |= PCI113X_CBCTRL_PCI_IRQ_ENA0x002000;
667 /* CSC intr enable */
668 reg |= PCI113X_CBCTRL_PCI_CSC0x000800;
669 /* functional intr prohibit | prohibit ISA routing */
670 reg &= ~(PCI113X_CBCTRL_PCI_INTR0x001000 | PCI113X_CBCTRL_INT_MASK0x060000);
671 pci_conf_write(pc, tag, PCI_CBCTRL0x90, reg);
672 break;
673
674 case CB_TI12XX2:
675 /*
676 * Some TI 12xx (and [14][45]xx) based pci cards
677 * sometimes have issues with the MFUNC register not
678 * being initialized due to a bad EEPROM on board.
679 * Laptops that this matters on have this register
680 * properly initialized.
681 *
682 * The TI125X parts have a different register.
683 */
684 reg = pci_conf_read(pc, tag, PCI12XX_MFUNC0x8c);
685 if (reg == PCI12XX_MFUNC_DEFAULT0x00001000) {
686 reg &= ~PCI12XX_MFUNC_PIN00x0000000F;
687 reg |= PCI12XX_MFUNC_PIN0_INTA0x02;
688 if ((pci_conf_read(pc, tag, PCI_SYSCTRL0x80) &
689 PCI12XX_SYSCTRL_INTRTIE0x20000000u) == 0) {
690 reg &= ~PCI12XX_MFUNC_PIN10x000000F0;
691 reg |= PCI12XX_MFUNC_PIN1_INTB0x20;
692 }
693 pci_conf_write(pc, tag, PCI12XX_MFUNC0x8c, reg);
694 }
695 /* FALLTHROUGH */
696
697 case CB_TI125X9:
698 /*
699 * Disable zoom video. Some machines initialize this
700 * improperly and experience has shown that this helps
701 * prevent strange behavior.
702 */
703 pci_conf_write(pc, tag, PCI12XX_MMCTRL0x84, 0);
704
705 reg = pci_conf_read(pc, tag, PCI_SYSCTRL0x80);
706 reg |= PCI12XX_SYSCTRL_VCCPROT0x200000;
707 pci_conf_write(pc, tag, PCI_SYSCTRL0x80, reg);
708 reg = pci_conf_read(pc, tag, PCI_CBCTRL0x90);
709 reg |= PCI12XX_CBCTRL_CSC0x20000000u;
710 pci_conf_write(pc, tag, PCI_CBCTRL0x90, reg);
711 break;
712
713 case CB_TOPIC95B6:
714 reg = pci_conf_read(pc, tag, TOPIC_SOCKET_CTRL0x90);
715 reg |= TOPIC_SOCKET_CTRL_SCR_IRQSEL0x00000001;
716 pci_conf_write(pc, tag, TOPIC_SOCKET_CTRL0x90, reg);
717
718 reg = pci_conf_read(pc, tag, TOPIC_SLOT_CTRL0xA0);
719 DPRINTF(("%s: topic slot ctrl reg 0x%x -> ",
720 sc->sc_dev.dv_xname, reg));
721 reg |= (TOPIC_SLOT_CTRL_SLOTON0x00000080 | TOPIC_SLOT_CTRL_SLOTEN0x00000040 |
722 TOPIC_SLOT_CTRL_ID_LOCK0x00000020 | TOPIC_SLOT_CTRL_CARDBUS0x80000000);
723 reg &= ~TOPIC_SLOT_CTRL_SWDETECT0x01000000;
724 DPRINTF(("0x%x\n", reg));
725 pci_conf_write(pc, tag, TOPIC_SLOT_CTRL0xA0, reg);
726 break;
727
728 case CB_TOPIC977:
729 reg = pci_conf_read(pc, tag, TOPIC_SLOT_CTRL0xA0);
730 DPRINTF(("%s: topic slot ctrl reg 0x%x -> ",
731 sc->sc_dev.dv_xname, reg));
732 reg |= (TOPIC_SLOT_CTRL_SLOTON0x00000080 | TOPIC_SLOT_CTRL_SLOTEN0x00000040 |
733 TOPIC_SLOT_CTRL_ID_LOCK0x00000020 | TOPIC_SLOT_CTRL_CARDBUS0x80000000);
734 reg &= ~TOPIC_SLOT_CTRL_SWDETECT0x01000000;
735 reg |= TOPIC97_SLOT_CTRL_PCIINT0x00000100;
736 reg &= ~(TOPIC97_SLOT_CTRL_STSIRQP0x00000400 | TOPIC97_SLOT_CTRL_IRQP0x00000200);
737 DPRINTF(("0x%x\n", reg));
738 pci_conf_write(pc, tag, TOPIC_SLOT_CTRL0xA0, reg);
739
740 /* make sure to assert LV card support bits */
741 bus_space_write_1(sc->sc_base_memt, sc->sc_base_memh,((sc->sc_base_memt)->write_1((sc->sc_base_memh), (0x800
+ 0x3e), (((sc->sc_base_memt)->read_1((sc->sc_base_memh
), (0x800 + 0x3e))) | 0x03)))
742 0x800 + 0x3e, bus_space_read_1(sc->sc_base_memt,((sc->sc_base_memt)->write_1((sc->sc_base_memh), (0x800
+ 0x3e), (((sc->sc_base_memt)->read_1((sc->sc_base_memh
), (0x800 + 0x3e))) | 0x03)))
743 sc->sc_base_memh, 0x800 + 0x3e) | 0x03)((sc->sc_base_memt)->write_1((sc->sc_base_memh), (0x800
+ 0x3e), (((sc->sc_base_memt)->read_1((sc->sc_base_memh
), (0x800 + 0x3e))) | 0x03)))
;
744 break;
745
746 case CB_OLDO2MICRO10:
747 /*
748 * older bridges have problems with both read prefetch and
749 * write bursting depending on the combination of the chipset,
750 * bridge and the cardbus card. so disable them to be on the
751 * safe side. One example is O2Micro 6812 with Atheros AR5012
752 * chipsets
753 */
754 DPRINTF(("%s: old O2Micro bridge found\n",
755 sc->sc_dev.dv_xname, reg));
756 reg = pci_conf_read(pc, tag, O2MICRO_RESERVED10x94);
757 pci_conf_write(pc, tag, O2MICRO_RESERVED10x94, reg &
758 ~(O2MICRO_RES_READ_PREFETCH0x02 | O2MICRO_RES_WRITE_BURST0x08));
759 reg = pci_conf_read(pc, tag, O2MICRO_RESERVED20xD4);
760 pci_conf_write(pc, tag, O2MICRO_RESERVED20xD4, reg &
761 ~(O2MICRO_RES_READ_PREFETCH0x02 | O2MICRO_RES_WRITE_BURST0x08));
762 break;
763 }
764
765 /* Close all memory and I/O windows. */
766 pci_conf_write(pc, tag, PCI_CB_MEMBASE00x1C, 0xffffffff);
767 pci_conf_write(pc, tag, PCI_CB_MEMLIMIT00x20, 0);
768 pci_conf_write(pc, tag, PCI_CB_MEMBASE10x24, 0xffffffff);
769 pci_conf_write(pc, tag, PCI_CB_MEMLIMIT10x28, 0);
770 pci_conf_write(pc, tag, PCI_CB_IOBASE00x2C, 0xffffffff);
771 pci_conf_write(pc, tag, PCI_CB_IOLIMIT00x30, 0);
772 pci_conf_write(pc, tag, PCI_CB_IOBASE10x34, 0xffffffff);
773 pci_conf_write(pc, tag, PCI_CB_IOLIMIT10x38, 0);
774
775 /* reset 16-bit pcmcia bus */
776 bus_space_write_1(sc->sc_base_memt, sc->sc_base_memh,((sc->sc_base_memt)->write_1((sc->sc_base_memh), (0x800
+ 0x03), (((sc->sc_base_memt)->read_1((sc->sc_base_memh
), (0x800 + 0x03))) & ~0x40)))
777 0x800 + PCIC_INTR,((sc->sc_base_memt)->write_1((sc->sc_base_memh), (0x800
+ 0x03), (((sc->sc_base_memt)->read_1((sc->sc_base_memh
), (0x800 + 0x03))) & ~0x40)))
778 bus_space_read_1(sc->sc_base_memt, sc->sc_base_memh,((sc->sc_base_memt)->write_1((sc->sc_base_memh), (0x800
+ 0x03), (((sc->sc_base_memt)->read_1((sc->sc_base_memh
), (0x800 + 0x03))) & ~0x40)))
779 0x800 + PCIC_INTR) & ~PCIC_INTR_RESET)((sc->sc_base_memt)->write_1((sc->sc_base_memh), (0x800
+ 0x03), (((sc->sc_base_memt)->read_1((sc->sc_base_memh
), (0x800 + 0x03))) & ~0x40)))
;
780
781 /* turn off power */
782 pccbb_power((cardbus_chipset_tag_t)sc, CARDBUS_VCC_0V0x0004 | CARDBUS_VPP_0V0x0040);
783}
784
785
786
787
788/*
789 * void pccbb_pcmcia_attach_setup(struct pccbb_softc *sc,
790 * struct pcmciabus_attach_args *paa)
791 *
792 * This function attaches 16-bit PCcard bus.
793 */
794void
795pccbb_pcmcia_attach_setup(struct pccbb_softc *sc,
796 struct pcmciabus_attach_args *paa)
797{
798 struct pcic_handle *ph = &sc->sc_pcmcia_h;
799 rbus_tag_t rb;
800
801 /* initialize pcmcia part in pccbb_softc */
802 ph->ph_parent = (struct device *)sc;
803 ph->sock = sc->sc_function;
804 ph->flags = 0;
805 ph->shutdown = 0;
806 ph->ih_irq = sc->sc_intrline;
807 ph->ph_bus_t = sc->sc_base_memt;
808 ph->ph_bus_h = sc->sc_base_memh;
809 ph->ph_read = pccbb_pcmcia_read;
810 ph->ph_write = pccbb_pcmcia_write;
811 sc->sc_pct = &pccbb_pcmcia_funcs;
812
813 /*
814 * We need to do a few things here:
815 * 1) Disable routing of CSC and functional interrupts to ISA IRQs by
816 * setting the IRQ numbers to 0.
817 * 2) Set bit 4 of PCIC_INTR, which is needed on some chips to enable
818 * routing of CSC interrupts (e.g. card removal) to PCI while in
819 * PCMCIA mode. We just leave this set all the time.
820 * 3) Enable card insertion/removal interrupts in case the chip also
821 * needs that while in PCMCIA mode.
822 * 4) Clear any pending CSC interrupt.
823 */
824 Pcic_write(ph, PCIC_INTR, PCIC_INTR_ENABLE | PCIC_INTR_RESET)((ph)->ph_write((ph), (0x03), (0x10 | 0x40)));
825 if (sc->sc_chipset == CB_TI113X1) {
826 Pcic_write(ph, PCIC_CSC_INTR, 0)((ph)->ph_write((ph), (0x05), (0)));
827 } else {
828 Pcic_write(ph, PCIC_CSC_INTR, PCIC_CSC_INTR_CD_ENABLE)((ph)->ph_write((ph), (0x05), (0x08)));
829 Pcic_read(ph, PCIC_CSC)((ph)->ph_read((ph), (0x04)));
830 }
831
832 /* initialize pcmcia bus attachment */
833 paa->paa_busname = "pcmcia";
834 paa->pct = sc->sc_pct;
835 paa->pch = ph;
836 paa->iobase = 0; /* I don't use them */
837 paa->iosize = 0;
838 rb = ((struct pccbb_softc *)(ph->ph_parent))->sc_rbus_iot;
839 paa->iobase = rb->rb_start + rb->rb_offset;
840 paa->iosize = rb->rb_end - rb->rb_start;
841
842 return;
843}
844
845#if 0
846void
847pccbb_pcmcia_attach_card(struct pcic_handle *ph)
848{
849 if (ph->flags & PCIC_FLAG_CARDP0x0002) {
850 panic("pccbb_pcmcia_attach_card: already attached");
851 }
852
853 /* call the MI attach function */
854 pcmcia_card_attach(ph->pcmcia);
855
856 ph->flags |= PCIC_FLAG_CARDP0x0002;
857}
858
859void
860pccbb_pcmcia_detach_card(struct pcic_handle *ph, int flags)
861{
862 if (!(ph->flags & PCIC_FLAG_CARDP0x0002)) {
863 panic("pccbb_pcmcia_detach_card: already detached");
864 }
865
866 ph->flags &= ~PCIC_FLAG_CARDP0x0002;
867
868 /* call the MI detach function */
869 pcmcia_card_detach(ph->pcmcia, flags);
870}
871#endif
872
873int
874pccbb_checksockstat(struct pccbb_softc *sc)
875{
876 u_int32_t sockstate;
877
878 sockstate = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,((sc->sc_base_memt)->read_4((sc->sc_base_memh), (0x08
)))
879 CB_SOCKET_STAT)((sc->sc_base_memt)->read_4((sc->sc_base_memh), (0x08
)))
;
880
881 if ((sockstate & CB_SOCKET_STAT_CD0x00000006) != 0) {
882 /* A card should be removed. */
883 if (sc->sc_flags & CBB_CARDEXIST0x01) {
884 DPRINTF(("%s: card removed, 0x%08x\n",
885 sc->sc_dev.dv_xname, sockstate));
886 sc->sc_flags &= ~CBB_CARDEXIST0x01;
887 if (sc->sc_csc->sc_status & CARDSLOT_STATUS_CARD_160x01) {
888#if 0
889 struct pcic_handle *ph =
890 &sc->sc_pcmcia_h;
891
892 pcmcia_card_deactivate(ph->pcmcia);
893 pccbb_pcmcia_socket_disable(ph);
894 pccbb_pcmcia_detach_card(ph,
895 DETACH_FORCE0x01);
896#endif
897 cardslot_event_throw(sc->sc_csc,
898 CARDSLOT_EVENT_REMOVAL_161);
899 } else if (sc->sc_csc->sc_status &
900 CARDSLOT_STATUS_CARD_CB0x02) {
901 /* Cardbus intr removed */
902 cardslot_event_throw(sc->sc_csc,
903 CARDSLOT_EVENT_REMOVAL_CB3);
904 }
905 }
906 return (1);
907 } else if ((sockstate & CB_SOCKET_STAT_CD0x00000006) == 0 &&
908 (sc->sc_flags & CBB_CARDEXIST0x01) == 0) {
909 timeout_add_msec(&sc->sc_ins_tmo, 100);
910 sc->sc_flags |= CBB_INSERTING0x01000000;
911 return (1);
912 }
913 return (0);
914}
915
916/*
917 * int pccbbintr(arg)
918 * void *arg;
919 * This routine handles the interrupt from Yenta PCI-CardBus bridge
920 * itself.
921 */
922int
923pccbbintr(void *arg)
924{
925 struct pccbb_softc *sc = (struct pccbb_softc *)arg;
926 u_int32_t sockevent;
927 struct pcic_handle *ph = &sc->sc_pcmcia_h;
928
929 if (!sc->sc_ints_on)
930 return 0;
931
932 sockevent = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,((sc->sc_base_memt)->read_4((sc->sc_base_memh), (0x00
)))
933 CB_SOCKET_EVENT)((sc->sc_base_memt)->read_4((sc->sc_base_memh), (0x00
)))
;
934 bus_space_write_4(sc->sc_base_memt, sc->sc_base_memh,((sc->sc_base_memt)->write_4((sc->sc_base_memh), (0x00
), (sockevent)))
935 CB_SOCKET_EVENT, sockevent)((sc->sc_base_memt)->write_4((sc->sc_base_memh), (0x00
), (sockevent)))
;
936 Pcic_read(ph, PCIC_CSC)((ph)->ph_read((ph), (0x04)));
937
938 if (sockevent & CB_SOCKET_EVENT_CD0x06) {
939 if (pccbb_checksockstat(sc))
940 return (1);
941 }
942
943 if (sc->sc_pil_intr_enable)
944 return pccbbintr_function(sc);
945 return (0);
946}
947
948/*
949 * int pccbbintr_function(struct pccbb_softc *sc)
950 *
951 * This function calls each interrupt handler registered at the
952 * bridge. The interrupt handlers are called in registered order.
953 */
954int
955pccbbintr_function(struct pccbb_softc *sc)
956{
957 int retval = 0, val;
958 struct pccbb_intrhand_list *pil;
959 int s;
960
961 for (pil = sc->sc_pil; pil != NULL((void *)0); pil = pil->pil_next) {
962 s = splraise(pil->pil_level);
963
964 val = (*pil->pil_func)(pil->pil_arg);
965 if (val != 0)
966 pil->pil_count.ec_count++;
967
968 splx(s)spllower(s);
969
970 if (retval == 0 || val != 0)
971 retval = val;
972 }
973
974 return retval;
975}
976
977void
978pci113x_insert(void *arg)
979{
980 struct pccbb_softc *sc = (struct pccbb_softc *)arg;
981 u_int32_t sockevent, sockstate;
982
983 sockevent = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,((sc->sc_base_memt)->read_4((sc->sc_base_memh), (0x00
)))
Value stored to 'sockevent' is never read
984 CB_SOCKET_EVENT)((sc->sc_base_memt)->read_4((sc->sc_base_memh), (0x00
)))
;
985 sockstate = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,((sc->sc_base_memt)->read_4((sc->sc_base_memh), (0x08
)))
986 CB_SOCKET_STAT)((sc->sc_base_memt)->read_4((sc->sc_base_memh), (0x08
)))
;
987
988 if (0 == (sockstate & CB_SOCKET_STAT_CD0x00000006)) { /* card exist */
989 DPRINTF(("%s: 0x%08x", sc->sc_dev.dv_xname, sockevent));
990 DPRINTF((" card inserted, 0x%08x\n", sockstate));
991 sc->sc_flags |= CBB_CARDEXIST0x01;
992 /* call pccard interrupt handler here */
993 if (sockstate & CB_SOCKET_STAT_16BIT0x00000010) {
994 /* 16-bit card found */
995/* pccbb_pcmcia_attach_card(&sc->sc_pcmcia_h); */
996 cardslot_event_throw(sc->sc_csc,
997 CARDSLOT_EVENT_INSERTION_160);
998 } else if (sockstate & CB_SOCKET_STAT_CB0x00000020) {
999 /* cardbus card found */
1000/* cardbus_attach_card(sc->sc_csc); */
1001 cardslot_event_throw(sc->sc_csc,
1002 CARDSLOT_EVENT_INSERTION_CB2);
1003 } else {
1004 /* who are you? */
1005 }
1006 } else {
1007 timeout_add_msec(&sc->sc_ins_tmo, 100);
1008 }
1009}
1010
1011#define PCCBB_PCMCIA_OFFSET0x800 0x800
1012u_int8_t
1013pccbb_pcmcia_read(struct pcic_handle *ph, int reg)
1014{
1015 bus_space_barrier(ph->ph_bus_t, ph->ph_bus_h,
1016 PCCBB_PCMCIA_OFFSET0x800 + reg, 1, BUS_SPACE_BARRIER_READ0x01);
1017
1018 return bus_space_read_1(ph->ph_bus_t, ph->ph_bus_h,((ph->ph_bus_t)->read_1((ph->ph_bus_h), (0x800 + reg
)))
1019 PCCBB_PCMCIA_OFFSET + reg)((ph->ph_bus_t)->read_1((ph->ph_bus_h), (0x800 + reg
)))
;
1020}
1021
1022void
1023pccbb_pcmcia_write(struct pcic_handle *ph, int reg, int val)
1024{
1025 bus_space_barrier(ph->ph_bus_t, ph->ph_bus_h,
1026 PCCBB_PCMCIA_OFFSET0x800 + reg, 1, BUS_SPACE_BARRIER_WRITE0x02);
1027
1028 bus_space_write_1(ph->ph_bus_t, ph->ph_bus_h, PCCBB_PCMCIA_OFFSET + reg,((ph->ph_bus_t)->write_1((ph->ph_bus_h), (0x800 + reg
), (val)))
1029 val)((ph->ph_bus_t)->write_1((ph->ph_bus_h), (0x800 + reg
), (val)))
;
1030}
1031
1032/*
1033 * int pccbb_ctrl(cardbus_chipset_tag_t, int)
1034 */
1035int
1036pccbb_ctrl(cardbus_chipset_tag_t ct, int command)
1037{
1038 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1039
1040 switch (command) {
1041 case CARDBUS_CD7:
1042 if (2 == pccbb_detect_card(sc)) {
1043 int retval = 0;
1044 int status = cb_detect_voltage(sc);
1045 if (PCCARD_VCC_5V0x01 & status) {
1046 retval |= CARDBUS_5V_CARD0x01;
1047 }
1048 if (PCCARD_VCC_3V0x02 & status) {
1049 retval |= CARDBUS_3V_CARD0x02;
1050 }
1051 if (PCCARD_VCC_XV0x04 & status) {
1052 retval |= CARDBUS_XV_CARD0x04;
1053 }
1054 if (PCCARD_VCC_YV0x08 & status) {
1055 retval |= CARDBUS_YV_CARD0x08;
1056 }
1057 return retval;
1058 } else {
1059 return 0;
1060 }
1061 break;
1062 case CARDBUS_RESET4:
1063 return cb_reset(sc);
1064 break;
1065 case CARDBUS_IO_ENABLE100: /* fallthrough */
1066 case CARDBUS_IO_DISABLE101: /* fallthrough */
1067 case CARDBUS_MEM_ENABLE102: /* fallthrough */
1068 case CARDBUS_MEM_DISABLE103: /* fallthrough */
1069 case CARDBUS_BM_ENABLE104: /* fallthrough */
1070 case CARDBUS_BM_DISABLE105: /* fallthrough */
1071 return pccbb_cardenable(sc, command);
1072 break;
1073 }
1074
1075 return 0;
1076}
1077
1078/*
1079 * int pccbb_power(cardbus_chipset_tag_t, int)
1080 * This function returns true when it succeeds and returns false when
1081 * it fails.
1082 */
1083int
1084pccbb_power(cardbus_chipset_tag_t ct, int command)
1085{
1086 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1087
1088 u_int32_t status, sock_ctrl;
1089 bus_space_tag_t memt = sc->sc_base_memt;
1090 bus_space_handle_t memh = sc->sc_base_memh;
1091
1092 DPRINTF(("pccbb_power: %s and %s [%x]\n",
1093 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_UC ? "CARDBUS_VCC_UC" :
1094 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_5V ? "CARDBUS_VCC_5V" :
1095 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_3V ? "CARDBUS_VCC_3V" :
1096 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_XV ? "CARDBUS_VCC_XV" :
1097 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_YV ? "CARDBUS_VCC_YV" :
1098 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_0V ? "CARDBUS_VCC_0V" :
1099 "UNKNOWN",
1100 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_UC ? "CARDBUS_VPP_UC" :
1101 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_12V ? "CARDBUS_VPP_12V" :
1102 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_VCC ? "CARDBUS_VPP_VCC" :
1103 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_0V ? "CARDBUS_VPP_0V" :
1104 "UNKNOWN", command));
1105
1106 status = bus_space_read_4(memt, memh, CB_SOCKET_STAT)((memt)->read_4((memh), (0x08)));
1107 sock_ctrl = bus_space_read_4(memt, memh, CB_SOCKET_CTRL)((memt)->read_4((memh), (0x10)));
1108
1109 switch (command & CARDBUS_VCCMASK0x000f) {
1110 case CARDBUS_VCC_UC0x0000:
1111 break;
1112 case CARDBUS_VCC_5V0x0005:
1113 if (CB_SOCKET_STAT_5VCARD0x00000400 & status) { /* check 5 V card */
1114 sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK0x070;
1115 sock_ctrl |= CB_SOCKET_CTRL_VCC_5V0x020;
1116 } else {
1117 printf("%s: BAD voltage request: no 5 V card\n",
1118 sc->sc_dev.dv_xname);
1119 }
1120 break;
1121 case CARDBUS_VCC_3V0x0001:
1122 if (CB_SOCKET_STAT_3VCARD0x00000800 & status) {
1123 sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK0x070;
1124 sock_ctrl |= CB_SOCKET_CTRL_VCC_3V0x030;
1125 } else {
1126 printf("%s: BAD voltage request: no 3.3 V card\n",
1127 sc->sc_dev.dv_xname);
1128 }
1129 break;
1130 case CARDBUS_VCC_0V0x0004:
1131 sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK0x070;
1132 break;
1133 default:
1134 return 0; /* power NEVER changed */
1135 break;
1136 }
1137
1138 switch (command & CARDBUS_VPPMASK0x00f0) {
1139 case CARDBUS_VPP_UC0x0000:
1140 break;
1141 case CARDBUS_VPP_0V0x0040:
1142 sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK0x007;
1143 break;
1144 case CARDBUS_VPP_VCC0x0010:
1145 sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK0x007;
1146 sock_ctrl |= ((sock_ctrl >> 4) & 0x07);
1147 break;
1148 case CARDBUS_VPP_12V0x0030:
1149 sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK0x007;
1150 sock_ctrl |= CB_SOCKET_CTRL_VPP_12V0x001;
1151 break;
1152 }
1153
1154#if 0
1155 DPRINTF(("sock_ctrl: %x\n", sock_ctrl));
1156#endif
1157 bus_space_write_4(memt, memh, CB_SOCKET_CTRL, sock_ctrl)((memt)->write_4((memh), (0x10), (sock_ctrl)));
1158 status = bus_space_read_4(memt, memh, CB_SOCKET_STAT)((memt)->read_4((memh), (0x08)));
1159
1160 if (status & CB_SOCKET_STAT_BADVCC0x00000200) { /* bad Vcc request */
1161 printf
1162 ("%s: bad Vcc request. sock_ctrl 0x%x, sock_status 0x%x\n",
1163 sc->sc_dev.dv_xname, sock_ctrl, status);
1164 DPRINTF(("pccbb_power: %s and %s [%x]\n",
1165 (command & CARDBUS_VCCMASK) ==
1166 CARDBUS_VCC_UC ? "CARDBUS_VCC_UC" : (command &
1167 CARDBUS_VCCMASK) ==
1168 CARDBUS_VCC_5V ? "CARDBUS_VCC_5V" : (command &
1169 CARDBUS_VCCMASK) ==
1170 CARDBUS_VCC_3V ? "CARDBUS_VCC_3V" : (command &
1171 CARDBUS_VCCMASK) ==
1172 CARDBUS_VCC_XV ? "CARDBUS_VCC_XV" : (command &
1173 CARDBUS_VCCMASK) ==
1174 CARDBUS_VCC_YV ? "CARDBUS_VCC_YV" : (command &
1175 CARDBUS_VCCMASK) ==
1176 CARDBUS_VCC_0V ? "CARDBUS_VCC_0V" : "UNKNOWN",
1177 (command & CARDBUS_VPPMASK) ==
1178 CARDBUS_VPP_UC ? "CARDBUS_VPP_UC" : (command &
1179 CARDBUS_VPPMASK) ==
1180 CARDBUS_VPP_12V ? "CARDBUS_VPP_12V" : (command &
1181 CARDBUS_VPPMASK) ==
1182 CARDBUS_VPP_VCC ? "CARDBUS_VPP_VCC" : (command &
1183 CARDBUS_VPPMASK) ==
1184 CARDBUS_VPP_0V ? "CARDBUS_VPP_0V" : "UNKNOWN", command));
1185#if 0
1186 if (command == (CARDBUS_VCC_0V0x0004 | CARDBUS_VPP_0V0x0040)) {
1187 u_int32_t force =
1188 bus_space_read_4(memt, memh, CB_SOCKET_FORCE)((memt)->read_4((memh), (0x0C)));
1189 /* Reset Bad Vcc request */
1190 force &= ~CB_SOCKET_FORCE_BADVCC0x0200;
1191 bus_space_write_4(memt, memh, CB_SOCKET_FORCE, force)((memt)->write_4((memh), (0x0C), (force)));
1192 printf("new status 0x%x\n", bus_space_read_4(memt, memh,((memt)->read_4((memh), (0x08)))
1193 CB_SOCKET_STAT)((memt)->read_4((memh), (0x08))));
1194 return 1;
1195 }
1196#endif
1197 return 0;
1198 }
1199
1200 /*
1201 * XXX delay 300 ms: though the standard defines that the Vcc set-up
1202 * time is 20 ms, some PC-Card bridge requires longer duration.
1203 */
1204 delay(300 * 1000)(*delay_func)(300 * 1000);
1205
1206 return 1; /* power changed correctly */
1207}
1208
1209#if defined CB_PCMCIA_POLL
1210struct cb_poll_str {
1211 void *arg;
1212 int (*func)(void *);
1213 int level;
1214 pccard_chipset_tag_t ct;
1215 int count;
1216};
1217
1218static struct cb_poll_str cb_poll[10];
1219static int cb_poll_n = 0;
1220static struct timeout cb_poll_timeout;
1221
1222void cb_pcmcia_poll(void *arg);
1223
1224void
1225cb_pcmcia_poll(void *arg)
1226{
1227 struct cb_poll_str *poll = arg;
1228 struct cbb_pcmcia_softc *psc = (void *)poll->ct->v;
1229 struct pccbb_softc *sc = psc->cpc_parent;
1230 int s;
1231 u_int32_t spsr; /* socket present-state reg */
1232
1233 timeout_set(&cb_poll_timeout, cb_pcmcia_poll, arg);
1234 timeout_add_msec(&cb_poll_timeout, 1000 / 10);
1235 switch (poll->level) {
1236 case IPL_NET0x7:
1237 s = splnet()splraise(0x7);
1238 break;
1239 case IPL_BIO0x6:
1240 s = splbio()splraise(0x6);
1241 break;
1242 case IPL_TTY0x9: /* fallthrough */
1243 default:
1244 s = spltty()splraise(0x9);
1245 break;
1246 }
1247
1248 spsr =
1249 bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,((sc->sc_base_memt)->read_4((sc->sc_base_memh), (0x08
)))
1250 CB_SOCKET_STAT)((sc->sc_base_memt)->read_4((sc->sc_base_memh), (0x08
)))
;
1251
1252#if defined CB_PCMCIA_POLL_ONLY && defined LEVEL2
1253 if (!(spsr & 0x40)) { /* CINT low */
1254#else
1255 if (1) {
1256#endif
1257 if ((*poll->func) (poll->arg) == 1) {
1258 ++poll->count;
1259 printf("intr: reported from poller, 0x%x\n", spsr);
1260#if defined LEVEL2
1261 } else {
1262 printf("intr: miss! 0x%x\n", spsr);
1263#endif
1264 }
1265 }
1266 splx(s)spllower(s);
1267}
1268#endif /* defined CB_PCMCIA_POLL */
1269
1270/*
1271 * int pccbb_detect_card(struct pccbb_softc *sc)
1272 * return value: 0 if no card exists.
1273 * 1 if 16-bit card exists.
1274 * 2 if cardbus card exists.
1275 */
1276int
1277pccbb_detect_card(struct pccbb_softc *sc)
1278{
1279 bus_space_handle_t base_memh = sc->sc_base_memh;
1280 bus_space_tag_t base_memt = sc->sc_base_memt;
1281 u_int32_t sockstat =
1282 bus_space_read_4(base_memt, base_memh, CB_SOCKET_STAT)((base_memt)->read_4((base_memh), (0x08)));
1283 int retval = 0;
1284
1285 /*
1286 * The SCM Microsystems TI1225-based PCI-CardBus dock card that
1287 * ships with some Lucent WaveLAN cards has only one physical slot
1288 * but OpenBSD probes two. The phantom card in the second slot can
1289 * be ignored by punting on unsupported voltages.
1290 */
1291 if (sockstat & CB_SOCKET_STAT_XVCARD0x00001000)
1292 return 0;
1293
1294 /* CD1 and CD2 asserted */
1295 if (0x00 == (sockstat & CB_SOCKET_STAT_CD0x00000006)) {
1296 /* card must be present */
1297 if (!(CB_SOCKET_STAT_NOTCARD0x00000080 & sockstat)) {
1298 /* NOTACARD DEASSERTED */
1299 if (CB_SOCKET_STAT_CB0x00000020 & sockstat) {
1300 /* CardBus mode */
1301 retval = 2;
1302 } else if (CB_SOCKET_STAT_16BIT0x00000010 & sockstat) {
1303 /* 16-bit mode */
1304 retval = 1;
1305 }
1306 }
1307 }
1308 return retval;
1309}
1310
1311/*
1312 * int cb_reset(struct pccbb_softc *sc)
1313 * This function resets CardBus card.
1314 */
1315int
1316cb_reset(struct pccbb_softc *sc)
1317{
1318 /*
1319 * Reset Assert at least 20 ms
1320 * Some machines request longer duration.
1321 */
1322 int reset_duration = (sc->sc_chipset == CB_RX5C47X3 ? 400 : 50);
1323 u_int32_t bcr = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR0x3C);
1324
1325 /* Reset bit Assert (bit 6 at 0x3E) */
1326 bcr |= CB_BCR_RESET_ENABLE0x00400000;
1327 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR0x3C, bcr);
1328 delay_ms(reset_duration, sc);
1329
1330 if (CBB_CARDEXIST0x01 & sc->sc_flags) { /* A card exists. Reset it! */
1331 /* Reset bit Deassert (bit 6 at 0x3E) */
1332 bcr &= ~CB_BCR_RESET_ENABLE0x00400000;
1333 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR0x3C, bcr);
1334 delay_ms(reset_duration, sc);
1335 }
1336 /* No card found on the slot. Keep Reset. */
1337 return 1;
1338}
1339
1340/*
1341 * int cb_detect_voltage(struct pccbb_softc *sc)
1342 * This function detect card Voltage.
1343 */
1344int
1345cb_detect_voltage(struct pccbb_softc *sc)
1346{
1347 u_int32_t psr; /* socket present-state reg */
1348 bus_space_tag_t iot = sc->sc_base_memt;
1349 bus_space_handle_t ioh = sc->sc_base_memh;
1350 int vol = PCCARD_VCC_UKN0x00; /* set 0 */
1351
1352 psr = bus_space_read_4(iot, ioh, CB_SOCKET_STAT)((iot)->read_4((ioh), (0x08)));
1353
1354 if (0x400u & psr) {
1355 vol |= PCCARD_VCC_5V0x01;
1356 }
1357 if (0x800u & psr) {
1358 vol |= PCCARD_VCC_3V0x02;
1359 }
1360
1361 return vol;
1362}
1363
1364int
1365cbbprint(void *aux, const char *pcic)
1366{
1367/*
1368 struct cbslot_attach_args *cba = aux;
1369
1370 if (cba->cba_slot >= 0) {
1371 printf(" slot %d", cba->cba_slot);
1372 }
1373*/
1374 return UNCONF1;
1375}
1376
1377/*
1378 * int pccbb_cardenable(struct pccbb_softc *sc, int function)
1379 * This function enables and disables the card
1380 */
1381int
1382pccbb_cardenable(struct pccbb_softc *sc, int function)
1383{
1384 u_int32_t command =
1385 pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG0x04);
1386
1387 DPRINTF(("pccbb_cardenable:"));
1388 switch (function) {
1389 case CARDBUS_IO_ENABLE100:
1390 command |= PCI_COMMAND_IO_ENABLE0x00000001;
1391 break;
1392 case CARDBUS_IO_DISABLE101:
1393 command &= ~PCI_COMMAND_IO_ENABLE0x00000001;
1394 break;
1395 case CARDBUS_MEM_ENABLE102:
1396 command |= PCI_COMMAND_MEM_ENABLE0x00000002;
1397 break;
1398 case CARDBUS_MEM_DISABLE103:
1399 command &= ~PCI_COMMAND_MEM_ENABLE0x00000002;
1400 break;
1401 case CARDBUS_BM_ENABLE104:
1402 command |= PCI_COMMAND_MASTER_ENABLE0x00000004;
1403 break;
1404 case CARDBUS_BM_DISABLE105:
1405 command &= ~PCI_COMMAND_MASTER_ENABLE0x00000004;
1406 break;
1407 default:
1408 return 0;
1409 }
1410
1411 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG0x04, command);
1412 DPRINTF((" command reg 0x%x\n", command));
1413 return 1;
1414}
1415
1416/*
1417 * void *pccbb_cb_intr_establish(cardbus_chipset_tag_t ct,
1418 * int irq,
1419 * int level,
1420 * int (* func)(void *),
1421 * void *arg,
1422 * const char *name)
1423 *
1424 * This function registers an interrupt handler at the bridge, in
1425 * order not to call the interrupt handlers of child devices when
1426 * a card-deletion interrupt occurs.
1427 *
1428 * The arguments irq is not used because pccbb selects intr vector.
1429 */
1430void *
1431pccbb_cb_intr_establish(cardbus_chipset_tag_t ct, int irq, int level,
1432 int (*func)(void *), void *arg, const char *name)
1433{
1434 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1435
1436 return pccbb_intr_establish(sc, irq, level, func, arg, name);
1437}
1438
1439
1440/*
1441 * void *pccbb_cb_intr_disestablish(cardbus_chipset_tag_t ct,
1442 * void *ih)
1443 *
1444 * This function removes an interrupt handler pointed by ih.
1445 */
1446void
1447pccbb_cb_intr_disestablish(cardbus_chipset_tag_t ct, void *ih)
1448{
1449 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1450
1451 pccbb_intr_disestablish(sc, ih);
1452}
1453
1454
1455/*
1456 * void *pccbb_intr_establish(struct pccbb_softc *sc,
1457 * int irq,
1458 * int level,
1459 * int (* func)(void *),
1460 * void *arg,
1461 * const char *name)
1462 *
1463 * This function registers an interrupt handler at the bridge, in
1464 * order not to call the interrupt handlers of child devices when
1465 * a card-deletion interrupt occurs.
1466 *
1467 * The arguments irq and level are not used.
1468 */
1469void *
1470pccbb_intr_establish(struct pccbb_softc *sc, int irq, int level,
1471 int (*func)(void *), void *arg, const char *name)
1472{
1473 struct pccbb_intrhand_list *pil, *newpil;
1474 pcireg_t reg;
1475
1476 DPRINTF(("pccbb_intr_establish start. %p\n", sc->sc_pil));
1477
1478 if (sc->sc_pil == NULL((void *)0)) {
1479 /* initialize bridge intr routing */
1480 reg = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR0x3C);
1481 reg &= ~CB_BCR_INTR_IREQ_ENABLE0x00800000;
1482 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR0x3C, reg);
1483
1484 switch (sc->sc_chipset) {
1485 case CB_TI113X1:
1486 reg = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL0x90);
1487 /* functional intr enabled */
1488 reg |= PCI113X_CBCTRL_PCI_INTR0x001000;
1489 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL0x90, reg);
1490 break;
1491 default:
1492 break;
1493 }
1494 }
1495
1496 /*
1497 * Allocate a room for interrupt handler structure.
1498 */
1499 newpil = (struct pccbb_intrhand_list *)
1500 malloc(sizeof(struct pccbb_intrhand_list), M_DEVBUF2, M_WAITOK0x0001);
1501
1502 newpil->pil_func = func;
1503 newpil->pil_arg = arg;
1504 newpil->pil_level = level;
1505 evcount_attach(&newpil->pil_count, name, &sc->sc_intrline);
1506 newpil->pil_next = NULL((void *)0);
1507
1508 if (sc->sc_pil == NULL((void *)0)) {
1509 sc->sc_pil = newpil;
1510 } else {
1511 for (pil = sc->sc_pil; pil->pil_next != NULL((void *)0);
1512 pil = pil->pil_next);
1513 pil->pil_next = newpil;
1514 }
1515
1516 DPRINTF(("pccbb_intr_establish add pil. %p\n", sc->sc_pil));
1517
1518 return newpil;
1519}
1520
1521/*
1522 * void *pccbb_intr_disestablish(struct pccbb_softc *sc,
1523 * void *ih)
1524 *
1525 * This function removes an interrupt handler pointed by ih.
1526 */
1527void
1528pccbb_intr_disestablish(struct pccbb_softc *sc, void *ih)
1529{
1530 struct pccbb_intrhand_list *pil, **pil_prev;
1531 pcireg_t reg;
1532
1533 DPRINTF(("pccbb_intr_disestablish start. %p\n", sc->sc_pil));
1534
1535 pil_prev = &sc->sc_pil;
1536
1537 for (pil = sc->sc_pil; pil != NULL((void *)0); pil = pil->pil_next) {
1538 if (pil == ih) {
1539 evcount_detach(&pil->pil_count);
1540 *pil_prev = pil->pil_next;
1541 free(pil, M_DEVBUF2, sizeof *pil);
1542 DPRINTF(("pccbb_intr_disestablish frees one pil\n"));
1543 break;
1544 }
1545 pil_prev = &pil->pil_next;
1546 }
1547
1548 if (sc->sc_pil == NULL((void *)0)) {
1549 /* No interrupt handlers */
1550
1551 DPRINTF(("pccbb_intr_disestablish: no interrupt handler\n"));
1552
1553 /* stop routing PCI intr */
1554 reg = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR0x3C);
1555 reg |= CB_BCR_INTR_IREQ_ENABLE0x00800000;
1556 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR0x3C, reg);
1557
1558 switch (sc->sc_chipset) {
1559 case CB_TI113X1:
1560 reg = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL0x90);
1561 /* functional intr disabled */
1562 reg &= ~PCI113X_CBCTRL_PCI_INTR0x001000;
1563 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL0x90, reg);
1564 break;
1565 default:
1566 break;
1567 }
1568 }
1569}
1570
1571#if defined SHOW_REGS
1572void
1573cb_show_regs(pci_chipset_tag_t pc, pcitag_t tag, bus_space_tag_t memt,
1574 bus_space_handle_t memh)
1575{
1576 int i;
1577 printf("PCI config regs:");
1578 for (i = 0; i < 0x50; i += 4) {
1579 if (i % 16 == 0) {
1580 printf("\n 0x%02x:", i);
1581 }
1582 printf(" %08x", pci_conf_read(pc, tag, i));
1583 }
1584 for (i = 0x80; i < 0xb0; i += 4) {
1585 if (i % 16 == 0) {
1586 printf("\n 0x%02x:", i);
1587 }
1588 printf(" %08x", pci_conf_read(pc, tag, i));
1589 }
1590
1591 if (memh == 0) {
1592 printf("\n");
1593 return;
1594 }
1595
1596 printf("\nsocket regs:");
1597 for (i = 0; i <= 0x10; i += 0x04) {
1598 printf(" %08x", bus_space_read_4(memt, memh, i)((memt)->read_4((memh), (i))));
1599 }
1600 printf("\nExCA regs:");
1601 for (i = 0; i < 0x08; ++i) {
1602 printf(" %02x", bus_space_read_1(memt, memh, 0x800 + i)((memt)->read_1((memh), (0x800 + i))));
1603 }
1604 printf("\n");
1605 return;
1606}
1607#endif
1608
1609/*
1610 * int pccbb_pcmcia_io_alloc(pcmcia_chipset_handle_t pch,
1611 * bus_addr_t start, bus_size_t size,
1612 * bus_size_t align,
1613 * struct pcmcia_io_handle *pcihp
1614 *
1615 * This function only allocates I/O region for pccard. This function
1616 * never maps the allocated region to pccard I/O area.
1617 *
1618 * XXX: The interface of this function is not very good, I believe.
1619 */
1620int
1621pccbb_pcmcia_io_alloc(pcmcia_chipset_handle_t pch, bus_addr_t start,
1622 bus_size_t size, bus_size_t align, struct pcmcia_io_handle *pcihp)
1623{
1624 struct pcic_handle *ph = (struct pcic_handle *)pch;
1625 bus_addr_t ioaddr;
1626 int flags = 0;
1627 bus_space_tag_t iot;
1628 bus_space_handle_t ioh;
1629 bus_addr_t mask;
1630 rbus_tag_t rb;
1631
1632 if (align == 0) {
1633 align = size; /* XXX: funny??? */
1634 }
1635
1636 if (start != 0) {
1637 /* XXX: assume all card decode lower 10 bits by its hardware */
1638 mask = 0x3ff;
1639 /* enforce to use only masked address */
1640 start &= mask;
1641 } else {
1642 /*
1643 * calculate mask:
1644 * 1. get the most significant bit of size (call it msb).
1645 * 2. compare msb with the value of size.
1646 * 3. if size is larger, shift msb left once.
1647 * 4. obtain mask value to decrement msb.
1648 */
1649 bus_size_t size_tmp = size;
1650 int shifts = 0;
1651
1652 while (size_tmp) {
1653 ++shifts;
1654 size_tmp >>= 1;
1655 }
1656 mask = (1 << shifts);
1657 if (mask < size) {
1658 mask <<= 1;
1659 }
1660 mask--;
1661 }
1662
1663 /*
1664 * Allocate some arbitrary I/O space.
1665 */
1666
1667 iot = ((struct pccbb_softc *)(ph->ph_parent))->sc_iot;
1668
1669 rb = ((struct pccbb_softc *)(ph->ph_parent))->sc_rbus_iot;
1670 if (rbus_space_alloc(rb, start, size, mask, align, 0, &ioaddr, &ioh)) {
1671 return 1;
1672 }
1673
1674 pcihp->iot = iot;
1675 pcihp->ioh = ioh;
1676 pcihp->addr = ioaddr;
1677 pcihp->size = size;
1678 pcihp->flags = flags;
1679
1680 return 0;
1681}
1682
1683/*
1684 * int pccbb_pcmcia_io_free(pcmcia_chipset_handle_t pch,
1685 * struct pcmcia_io_handle *pcihp)
1686 *
1687 * This function only frees I/O region for pccard.
1688 *
1689 * XXX: The interface of this function is not very good, I believe.
1690 */
1691void
1692pccbb_pcmcia_io_free(pcmcia_chipset_handle_t pch,
1693 struct pcmcia_io_handle *pcihp)
1694{
1695 bus_space_handle_t ioh = pcihp->ioh;
1696 bus_size_t size = pcihp->size;
1697
1698 struct pccbb_softc *sc =
1699 (struct pccbb_softc *)((struct pcic_handle *)pch)->ph_parent;
1700 rbus_tag_t rb = sc->sc_rbus_iot;
1701
1702 rbus_space_free(rb, ioh, size, NULL((void *)0));
1703}
1704
1705/*
1706 * int pccbb_pcmcia_io_map(pcmcia_chipset_handle_t pch, int width,
1707 * bus_addr_t offset, bus_size_t size,
1708 * struct pcmcia_io_handle *pcihp,
1709 * int *windowp)
1710 *
1711 * This function maps the allocated I/O region to pccard. This function
1712 * never allocates any I/O region for pccard I/O area. I don't
1713 * understand why the original authors of pcmciabus separated alloc and
1714 * map. I believe the two must be unite.
1715 *
1716 * XXX: no wait timing control?
1717 */
1718int
1719pccbb_pcmcia_io_map(pcmcia_chipset_handle_t pch, int width, bus_addr_t offset,
1720 bus_size_t size, struct pcmcia_io_handle *pcihp, int *windowp)
1721{
1722 struct pcic_handle *ph = (struct pcic_handle *)pch;
1723 bus_addr_t ioaddr = pcihp->addr + offset;
1724 int i, win;
1725#if defined CBB_DEBUG
1726 static char *width_names[] = { "dynamic", "io8", "io16" };
1727#endif
1728
1729 /* Sanity check I/O handle. */
1730
1731 if (((struct pccbb_softc *)ph->ph_parent)->sc_iot != pcihp->iot) {
1732 panic("pccbb_pcmcia_io_map iot is bogus");
1733 }
1734
1735 /* XXX Sanity check offset/size. */
1736
1737 win = -1;
1738 for (i = 0; i < PCIC_IO_WINS2; i++) {
1739 if ((ph->ioalloc & (1 << i)) == 0) {
1740 win = i;
1741 ph->ioalloc |= (1 << i);
1742 break;
1743 }
1744 }
1745
1746 if (win == -1) {
1747 return 1;
1748 }
1749
1750 *windowp = win;
1751
1752 /* XXX this is pretty gross */
1753
1754 DPRINTF(("pccbb_pcmcia_io_map window %d %s port %lx+%lx\n",
1755 win, width_names[width], (u_long) ioaddr, (u_long) size));
1756
1757 /* XXX wtf is this doing here? */
1758
1759#if 0
1760 printf(" port 0x%lx", (u_long) ioaddr);
1761 if (size > 1) {
1762 printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1);
1763 }
1764#endif
1765
1766 ph->io[win].addr = ioaddr;
1767 ph->io[win].size = size;
1768 ph->io[win].width = width;
1769
1770 /* actual dirty register-value changing in the function below. */
1771 pccbb_pcmcia_do_io_map(ph, win);
1772
1773 return 0;
1774}
1775
1776/*
1777 * void pccbb_pcmcia_do_io_map(struct pcic_handle *h, int win)
1778 *
1779 * This function changes register-value to map I/O region for pccard.
1780 */
1781void
1782pccbb_pcmcia_do_io_map(struct pcic_handle *ph, int win)
1783{
1784 static u_int8_t pcic_iowidth[3] = {
1785 PCIC_IOCTL_IO0_IOCS16SRC_CARD0x02,
1786 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE0x00 |
1787 PCIC_IOCTL_IO0_DATASIZE_8BIT0x00,
1788 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE0x00 |
1789 PCIC_IOCTL_IO0_DATASIZE_16BIT0x01,
1790 };
1791
1792#define PCIC_SIA_START_LOW0 0
1793#define PCIC_SIA_START_HIGH1 1
1794#define PCIC_SIA_STOP_LOW2 2
1795#define PCIC_SIA_STOP_HIGH3 3
1796
1797 int regbase_win = 0x8 + win * 0x04;
1798 u_int8_t ioctl, enable;
1799
1800 DPRINTF(
1801 ("pccbb_pcmcia_do_io_map win %d addr 0x%lx size 0x%lx width %d\n",
1802 win, (long)ph->io[win].addr, (long)ph->io[win].size,
1803 ph->io[win].width * 8));
1804
1805 Pcic_write(ph, regbase_win + PCIC_SIA_START_LOW,((ph)->ph_write((ph), (regbase_win + 0), (ph->io[win].addr
& 0xff)))
1806 ph->io[win].addr & 0xff)((ph)->ph_write((ph), (regbase_win + 0), (ph->io[win].addr
& 0xff)))
;
1807 Pcic_write(ph, regbase_win + PCIC_SIA_START_HIGH,((ph)->ph_write((ph), (regbase_win + 1), ((ph->io[win].
addr >> 8) & 0xff)))
1808 (ph->io[win].addr >> 8) & 0xff)((ph)->ph_write((ph), (regbase_win + 1), ((ph->io[win].
addr >> 8) & 0xff)))
;
1809
1810 Pcic_write(ph, regbase_win + PCIC_SIA_STOP_LOW,((ph)->ph_write((ph), (regbase_win + 2), ((ph->io[win].
addr + ph->io[win].size - 1) & 0xff)))
1811 (ph->io[win].addr + ph->io[win].size - 1) & 0xff)((ph)->ph_write((ph), (regbase_win + 2), ((ph->io[win].
addr + ph->io[win].size - 1) & 0xff)))
;
1812 Pcic_write(ph, regbase_win + PCIC_SIA_STOP_HIGH,((ph)->ph_write((ph), (regbase_win + 3), (((ph->io[win]
.addr + ph->io[win].size - 1) >> 8) & 0xff)))
1813 ((ph->io[win].addr + ph->io[win].size - 1) >> 8) & 0xff)((ph)->ph_write((ph), (regbase_win + 3), (((ph->io[win]
.addr + ph->io[win].size - 1) >> 8) & 0xff)))
;
1814
1815 ioctl = Pcic_read(ph, PCIC_IOCTL)((ph)->ph_read((ph), (0x07)));
1816 enable = Pcic_read(ph, PCIC_ADDRWIN_ENABLE)((ph)->ph_read((ph), (0x06)));
1817 switch (win) {
1818 case 0:
1819 ioctl &= ~(PCIC_IOCTL_IO0_WAITSTATE0x08 | PCIC_IOCTL_IO0_ZEROWAIT0x04 |
1820 PCIC_IOCTL_IO0_IOCS16SRC_MASK0x02 |
1821 PCIC_IOCTL_IO0_DATASIZE_MASK0x01);
1822 ioctl |= pcic_iowidth[ph->io[win].width];
1823 enable |= PCIC_ADDRWIN_ENABLE_IO00x40;
1824 break;
1825 case 1:
1826 ioctl &= ~(PCIC_IOCTL_IO1_WAITSTATE0x80 | PCIC_IOCTL_IO1_ZEROWAIT0x40 |
1827 PCIC_IOCTL_IO1_IOCS16SRC_MASK0x20 |
1828 PCIC_IOCTL_IO1_DATASIZE_MASK0x10);
1829 ioctl |= (pcic_iowidth[ph->io[win].width] << 4);
1830 enable |= PCIC_ADDRWIN_ENABLE_IO10x80;
1831 break;
1832 }
1833 Pcic_write(ph, PCIC_IOCTL, ioctl)((ph)->ph_write((ph), (0x07), (ioctl)));
1834 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, enable)((ph)->ph_write((ph), (0x06), (enable)));
1835#if defined CBB_DEBUG
1836 {
1837 u_int8_t start_low =
1838 Pcic_read(ph, regbase_win + PCIC_SIA_START_LOW)((ph)->ph_read((ph), (regbase_win + 0)));
1839 u_int8_t start_high =
1840 Pcic_read(ph, regbase_win + PCIC_SIA_START_HIGH)((ph)->ph_read((ph), (regbase_win + 1)));
1841 u_int8_t stop_low =
1842 Pcic_read(ph, regbase_win + PCIC_SIA_STOP_LOW)((ph)->ph_read((ph), (regbase_win + 2)));
1843 u_int8_t stop_high =
1844 Pcic_read(ph, regbase_win + PCIC_SIA_STOP_HIGH)((ph)->ph_read((ph), (regbase_win + 3)));
1845 printf
1846 (" start %02x %02x, stop %02x %02x, ioctl %02x enable %02x\n",
1847 start_low, start_high, stop_low, stop_high, ioctl, enable);
1848 }
1849#endif
1850}
1851
1852/*
1853 * void pccbb_pcmcia_io_unmap(pcmcia_chipset_handle_t *h, int win)
1854 *
1855 * This function unmaps I/O region. No return value.
1856 */
1857void
1858pccbb_pcmcia_io_unmap(pcmcia_chipset_handle_t pch, int win)
1859{
1860 struct pcic_handle *ph = (struct pcic_handle *)pch;
1861 int reg;
1862
1863 if (win >= PCIC_IO_WINS2 || win < 0) {
1864 panic("pccbb_pcmcia_io_unmap: window out of range");
1865 }
1866
1867 reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE)((ph)->ph_read((ph), (0x06)));
1868 switch (win) {
1869 case 0:
1870 reg &= ~PCIC_ADDRWIN_ENABLE_IO00x40;
1871 break;
1872 case 1:
1873 reg &= ~PCIC_ADDRWIN_ENABLE_IO10x80;
1874 break;
1875 }
1876 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg)((ph)->ph_write((ph), (0x06), (reg)));
1877
1878 ph->ioalloc &= ~(1 << win);
1879}
1880
1881/*
1882 * void pccbb_pcmcia_wait_ready(struct pcic_handle *ph)
1883 *
1884 * This function enables the card. All information is stored in
1885 * the first argument, pcmcia_chipset_handle_t.
1886 */
1887void
1888pccbb_pcmcia_wait_ready(struct pcic_handle *ph)
1889{
1890 int i;
1891
1892 DPRINTF(("pccbb_pcmcia_wait_ready: status 0x%02x\n",
1893 Pcic_read(ph, PCIC_IF_STATUS)));
1894
1895 for (i = 0; i < 10000; i++) {
1896 if (Pcic_read(ph, PCIC_IF_STATUS)((ph)->ph_read((ph), (0x01))) & PCIC_IF_STATUS_READY0x20) {
1897 return;
1898 }
1899 delay(500)(*delay_func)(500);
1900#ifdef CBB_DEBUG
1901 if ((i > 5000) && (i % 100 == 99))
1902 printf(".");
1903#endif
1904 }
1905
1906#ifdef DIAGNOSTIC1
1907 printf("pcic_wait_ready: ready never happened, status = %02x\n",
1908 Pcic_read(ph, PCIC_IF_STATUS)((ph)->ph_read((ph), (0x01))));
1909#endif
1910}
1911
1912/*
1913 * void pccbb_pcmcia_socket_enable(pcmcia_chipset_handle_t pch)
1914 *
1915 * This function enables the card. All information is stored in
1916 * the first argument, pcmcia_chipset_handle_t.
1917 */
1918void
1919pccbb_pcmcia_socket_enable(pcmcia_chipset_handle_t pch)
1920{
1921 struct pcic_handle *ph = (struct pcic_handle *)pch;
1922 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
1923 int cardtype, win;
1924 u_int8_t power, intr;
1925 pcireg_t spsr;
1926 int voltage;
1927
1928 /* this bit is mostly stolen from pcic_attach_card */
1929
1930 DPRINTF(("pccbb_pcmcia_socket_enable: "));
1931
1932 /* get card Vcc info */
1933
1934 spsr =
1935 bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,((sc->sc_base_memt)->read_4((sc->sc_base_memh), (0x08
)))
1936 CB_SOCKET_STAT)((sc->sc_base_memt)->read_4((sc->sc_base_memh), (0x08
)))
;
1937 if (spsr & CB_SOCKET_STAT_5VCARD0x00000400) {
1938 DPRINTF(("5V card\n"));
1939 voltage = CARDBUS_VCC_5V0x0005 | CARDBUS_VPP_VCC0x0010;
1940 } else if (spsr & CB_SOCKET_STAT_3VCARD0x00000800) {
1941 DPRINTF(("3V card\n"));
1942 voltage = CARDBUS_VCC_3V0x0001 | CARDBUS_VPP_VCC0x0010;
1943 } else {
1944 DPRINTF(("?V card, 0x%x\n", spsr)); /* XXX */
1945 return;
1946 }
1947
1948 /* disable socket i/o: negate output enable bit */
1949
1950 power = 0;
1951 Pcic_write(ph, PCIC_PWRCTL, power)((ph)->ph_write((ph), (0x02), (power)));
1952
1953 /* power down the socket to reset it, clear the card reset pin */
1954
1955 pccbb_power((cardbus_chipset_tag_t)sc, CARDBUS_VCC_0V0x0004 | CARDBUS_VPP_0V0x0040);
1956
1957 /*
1958 * wait 200ms until power fails (Tpf). Then, wait 100ms since
1959 * we are changing Vcc (Toff).
1960 */
1961 /* delay(300*1000); too much */
1962
1963 /* assert reset bit */
1964 intr = Pcic_read(ph, PCIC_INTR)((ph)->ph_read((ph), (0x03)));
1965 intr &= ~(PCIC_INTR_RESET0x40 | PCIC_INTR_CARDTYPE_MASK0x20);
1966 Pcic_write(ph, PCIC_INTR, intr)((ph)->ph_write((ph), (0x03), (intr)));
1967
1968 /* Power up the socket. */
1969 power = Pcic_read(ph, PCIC_PWRCTL)((ph)->ph_read((ph), (0x02)));
1970 Pcic_write(ph, PCIC_PWRCTL, (power & ~PCIC_PWRCTL_OE))((ph)->ph_write((ph), (0x02), ((power & ~0x80))));
1971 pccbb_power((cardbus_chipset_tag_t)sc, voltage);
1972
1973 /* Now output enable */
1974 power = Pcic_read(ph, PCIC_PWRCTL)((ph)->ph_read((ph), (0x02)));
1975 Pcic_write(ph, PCIC_PWRCTL, power | PCIC_PWRCTL_OE)((ph)->ph_write((ph), (0x02), (power | 0x80)));
1976
1977 /*
1978 * hold RESET at least 10us.
1979 */
1980 delay(10)(*delay_func)(10);
1981 delay(2 * 1000)(*delay_func)(2 * 1000); /* XXX: TI1130 requires it. */
1982 delay(20 * 1000)(*delay_func)(20 * 1000); /* XXX: TI1130 requires it. */
1983
1984 /* clear the reset flag */
1985
1986 intr |= PCIC_INTR_RESET0x40;
1987 Pcic_write(ph, PCIC_INTR, intr)((ph)->ph_write((ph), (0x03), (intr)));
1988
1989 /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
1990
1991 delay(20000)(*delay_func)(20000);
1992
1993 /* wait for the chip to finish initializing */
1994
1995 pccbb_pcmcia_wait_ready(ph);
1996
1997 /* zero out the address windows */
1998
1999 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, 0)((ph)->ph_write((ph), (0x06), (0)));
2000
2001 /* set the card type */
2002
2003 cardtype = pcmcia_card_gettype(ph->pcmcia);
2004
2005 intr |= ((cardtype == PCMCIA_IFTYPE_IO1) ?
2006 PCIC_INTR_CARDTYPE_IO0x20 : PCIC_INTR_CARDTYPE_MEM0x00);
2007 Pcic_write(ph, PCIC_INTR, intr)((ph)->ph_write((ph), (0x03), (intr)));
2008
2009 DPRINTF(("%s: pccbb_pcmcia_socket_enable %02x cardtype %s %02x\n",
2010 ph->ph_parent->dv_xname, ph->sock,
2011 ((cardtype == PCMCIA_IFTYPE_IO) ? "io" : "mem"), intr));
2012
2013 /* reinstall all the memory and io mappings */
2014
2015 for (win = 0; win < PCIC_MEM_WINS5; ++win) {
2016 if (ph->memalloc & (1 << win)) {
2017 pccbb_pcmcia_do_mem_map(ph, win);
2018 }
2019 }
2020
2021 for (win = 0; win < PCIC_IO_WINS2; ++win) {
2022 if (ph->ioalloc & (1 << win)) {
2023 pccbb_pcmcia_do_io_map(ph, win);
2024 }
2025 }
2026}
2027
2028/*
2029 * void pccbb_pcmcia_socket_disable(pcmcia_chipset_handle_t *ph)
2030 *
2031 * This function disables the card. All information is stored in
2032 * the first argument, pcmcia_chipset_handle_t.
2033 */
2034void
2035pccbb_pcmcia_socket_disable(pcmcia_chipset_handle_t pch)
2036{
2037 struct pcic_handle *ph = (struct pcic_handle *)pch;
2038 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2039 u_int8_t power, intr;
2040
2041 DPRINTF(("pccbb_pcmcia_socket_disable\n"));
2042
2043 /* reset signal asserting... */
2044
2045 intr = Pcic_read(ph, PCIC_INTR)((ph)->ph_read((ph), (0x03)));
2046 intr &= ~(PCIC_INTR_CARDTYPE_MASK0x20);
2047 Pcic_write(ph, PCIC_INTR, intr)((ph)->ph_write((ph), (0x03), (intr)));
2048 delay(2 * 1000)(*delay_func)(2 * 1000);
2049
2050 /* power down the socket */
2051 power = Pcic_read(ph, PCIC_PWRCTL)((ph)->ph_read((ph), (0x02)));
2052 power &= ~PCIC_PWRCTL_OE0x80;
2053 Pcic_write(ph, PCIC_PWRCTL, power)((ph)->ph_write((ph), (0x02), (power)));
2054 pccbb_power((cardbus_chipset_tag_t)sc, CARDBUS_VCC_0V0x0004 | CARDBUS_VPP_0V0x0040);
2055 /*
2056 * wait 300ms until power fails (Tpf).
2057 */
2058 delay(300 * 1000)(*delay_func)(300 * 1000);
2059}
2060
2061/*
2062 * int pccbb_pcmcia_card_detect(pcmcia_chipset_handle_t *ph)
2063 *
2064 * This function detects whether a card is in the slot or not.
2065 * If a card is inserted, return 1. Otherwise, return 0.
2066 */
2067int
2068pccbb_pcmcia_card_detect(pcmcia_chipset_handle_t pch)
2069{
2070 struct pcic_handle *ph = (struct pcic_handle *)pch;
2071 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2072
2073 DPRINTF(("pccbb_pcmcia_card_detect\n"));
2074 return pccbb_detect_card(sc) == 1 ? 1 : 0;
2075}
2076
2077/*
2078 * int pccbb_pcmcia_mem_alloc(pcmcia_chipset_handle_t pch,
2079 * bus_size_t size,
2080 * struct pcmcia_mem_handle *pcmhp)
2081 *
2082 * This function only allocates memory region for pccard. This
2083 * function never maps the allocated region to pccard memory area.
2084 *
2085 * XXX: Why the argument of start address is not in?
2086 */
2087int
2088pccbb_pcmcia_mem_alloc(pcmcia_chipset_handle_t pch, bus_size_t size,
2089 struct pcmcia_mem_handle *pcmhp)
2090{
2091 struct pcic_handle *ph = (struct pcic_handle *)pch;
2092 bus_space_handle_t memh;
2093 bus_addr_t addr;
2094 bus_size_t sizepg;
2095 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2096 rbus_tag_t rb;
2097
2098 /* out of sc->memh, allocate as many pages as necessary */
2099
2100 /* convert size to PCIC pages */
2101 /*
2102 * This is not enough; when the requested region is on the page
2103 * boundaries, this may calculate wrong result.
2104 */
2105 sizepg = (size + (PCIC_MEM_PAGESIZE(1<<12) - 1)) / PCIC_MEM_PAGESIZE(1<<12);
2106#if 0
2107 if (sizepg > PCIC_MAX_MEM_PAGES(8 * sizeof(int))) {
2108 return 1;
2109 }
2110#endif
2111
2112 if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_320x02)) {
2113 return 1;
2114 }
2115
2116 addr = 0; /* XXX gcc -Wuninitialized */
2117
2118 rb = sc->sc_rbus_memt;
2119 if (rbus_space_alloc(rb, 0, sizepg * PCIC_MEM_PAGESIZE(1<<12),
2120 sizepg * PCIC_MEM_PAGESIZE(1<<12) - 1, PCIC_MEM_PAGESIZE(1<<12), 0,
2121 &addr, &memh)) {
2122 return 1;
2123 }
2124
2125 DPRINTF(
2126 ("pccbb_pcmcia_alloc_mem: addr 0x%lx size 0x%lx, realsize 0x%lx\n",
2127 addr, size, sizepg * PCIC_MEM_PAGESIZE));
2128
2129 pcmhp->memt = sc->sc_memt;
2130 pcmhp->memh = memh;
2131 pcmhp->addr = addr;
2132 pcmhp->size = size;
2133 pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE(1<<12);
2134 /* What is mhandle? I feel it is very dirty and it must go trush. */
2135 pcmhp->mhandle = 0;
2136 /* No offset??? Funny. */
2137
2138 return 0;
2139}
2140
2141/*
2142 * void pccbb_pcmcia_mem_free(pcmcia_chipset_handle_t pch,
2143 * struct pcmcia_mem_handle *pcmhp)
2144 *
2145 * This function release the memory space allocated by the function
2146 * pccbb_pcmcia_mem_alloc().
2147 */
2148void
2149pccbb_pcmcia_mem_free(pcmcia_chipset_handle_t pch,
2150 struct pcmcia_mem_handle *pcmhp)
2151{
2152 struct pcic_handle *ph = (struct pcic_handle *)pch;
2153 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2154
2155 rbus_space_free(sc->sc_rbus_memt, pcmhp->memh, pcmhp->realsize, NULL((void *)0));
2156}
2157
2158/*
2159 * void pccbb_pcmcia_do_mem_map(struct pcic_handle *ph, int win)
2160 *
2161 * This function release the memory space allocated by the function
2162 * pccbb_pcmcia_mem_alloc().
2163 */
2164void
2165pccbb_pcmcia_do_mem_map(struct pcic_handle *ph, int win)
2166{
2167 int regbase_win;
2168 bus_addr_t phys_addr;
2169 bus_addr_t phys_end;
2170
2171#define PCIC_SMM_START_LOW0 0
2172#define PCIC_SMM_START_HIGH1 1
2173#define PCIC_SMM_STOP_LOW2 2
2174#define PCIC_SMM_STOP_HIGH3 3
2175#define PCIC_CMA_LOW4 4
2176#define PCIC_CMA_HIGH5 5
2177
2178 u_int8_t start_low, start_high = 0;
2179 u_int8_t stop_low, stop_high;
2180 u_int8_t off_low, off_high;
2181 u_int8_t mem_window;
2182 int reg;
2183
2184 regbase_win = 0x10 + win * 0x08;
2185
2186 phys_addr = ph->mem[win].addr;
2187 phys_end = phys_addr + ph->mem[win].size;
2188
2189 DPRINTF(("pccbb_pcmcia_do_mem_map: start 0x%lx end 0x%lx off 0x%lx\n",
2190 phys_addr, phys_end, ph->mem[win].offset));
2191
2192#define PCIC_MEMREG_LSB_SHIFT12 PCIC_SYSMEM_ADDRX_SHIFT12
2193#define PCIC_MEMREG_MSB_SHIFT(12 + 8) (PCIC_SYSMEM_ADDRX_SHIFT12 + 8)
2194#define PCIC_MEMREG_WIN_SHIFT(12 + 12) (PCIC_SYSMEM_ADDRX_SHIFT12 + 12)
2195
2196 /* bit 19:12 */
2197 start_low = (phys_addr >> PCIC_MEMREG_LSB_SHIFT12) & 0xff;
2198 /* bit 23:20 and bit 7 on */
2199 start_high = ((phys_addr >> PCIC_MEMREG_MSB_SHIFT(12 + 8)) & 0x0f)
2200 | PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT0x80; /* bit 7 on */
2201 /* bit 31:24, for 32-bit address */
2202 mem_window = (phys_addr >> PCIC_MEMREG_WIN_SHIFT(12 + 12)) & 0xff;
2203
2204 Pcic_write(ph, regbase_win + PCIC_SMM_START_LOW, start_low)((ph)->ph_write((ph), (regbase_win + 0), (start_low)));
2205 Pcic_write(ph, regbase_win + PCIC_SMM_START_HIGH, start_high)((ph)->ph_write((ph), (regbase_win + 1), (start_high)));
2206
2207 if (((struct pccbb_softc *)ph->
2208 ph_parent)->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_320x02) {
2209 Pcic_write(ph, 0x40 + win, mem_window)((ph)->ph_write((ph), (0x40 + win), (mem_window)));
2210 }
2211
2212 stop_low = (phys_end >> PCIC_MEMREG_LSB_SHIFT12) & 0xff;
2213 stop_high = ((phys_end >> PCIC_MEMREG_MSB_SHIFT(12 + 8)) & 0x0f)
2214 | PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT20x80; /* wait 2 cycles */
2215 /* XXX Geee, WAIT2!! Crazy!! I must rewrite this routine. */
2216
2217 Pcic_write(ph, regbase_win + PCIC_SMM_STOP_LOW, stop_low)((ph)->ph_write((ph), (regbase_win + 2), (stop_low)));
2218 Pcic_write(ph, regbase_win + PCIC_SMM_STOP_HIGH, stop_high)((ph)->ph_write((ph), (regbase_win + 3), (stop_high)));
2219
2220 off_low = (ph->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT12) & 0xff;
2221 off_high = ((ph->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT12 + 8))
2222 & PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK0x3F)
2223 | ((ph->mem[win].kind == PCMCIA_MEM_ATTR1) ?
2224 PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR0x40 : 0);
2225
2226 Pcic_write(ph, regbase_win + PCIC_CMA_LOW, off_low)((ph)->ph_write((ph), (regbase_win + 4), (off_low)));
2227 Pcic_write(ph, regbase_win + PCIC_CMA_HIGH, off_high)((ph)->ph_write((ph), (regbase_win + 5), (off_high)));
2228
2229 reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE)((ph)->ph_read((ph), (0x06)));
2230 reg |= ((1 << win) | PCIC_ADDRWIN_ENABLE_MEMCS160x20);
2231 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg)((ph)->ph_write((ph), (0x06), (reg)));
2232
2233#if defined CBB_DEBUG
2234 {
2235 int r1, r2, r3, r4, r5, r6, r7 = 0;
2236
2237 r1 = Pcic_read(ph, regbase_win + PCIC_SMM_START_LOW)((ph)->ph_read((ph), (regbase_win + 0)));
2238 r2 = Pcic_read(ph, regbase_win + PCIC_SMM_START_HIGH)((ph)->ph_read((ph), (regbase_win + 1)));
2239 r3 = Pcic_read(ph, regbase_win + PCIC_SMM_STOP_LOW)((ph)->ph_read((ph), (regbase_win + 2)));
2240 r4 = Pcic_read(ph, regbase_win + PCIC_SMM_STOP_HIGH)((ph)->ph_read((ph), (regbase_win + 3)));
2241 r5 = Pcic_read(ph, regbase_win + PCIC_CMA_LOW)((ph)->ph_read((ph), (regbase_win + 4)));
2242 r6 = Pcic_read(ph, regbase_win + PCIC_CMA_HIGH)((ph)->ph_read((ph), (regbase_win + 5)));
2243 if (((struct pccbb_softc *)(ph->
2244 ph_parent))->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_320x02) {
2245 r7 = Pcic_read(ph, 0x40 + win)((ph)->ph_read((ph), (0x40 + win)));
2246 }
2247
2248 DPRINTF(("pccbb_pcmcia_do_mem_map window %d: %02x%02x %02x%02x "
2249 "%02x%02x", win, r1, r2, r3, r4, r5, r6));
2250 if (((struct pccbb_softc *)(ph->
2251 ph_parent))->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_320x02) {
2252 DPRINTF((" %02x", r7));
2253 }
2254 DPRINTF(("\n"));
2255 }
2256#endif
2257}
2258
2259/*
2260 * int pccbb_pcmcia_mem_map(pcmcia_chipset_handle_t pch, int kind,
2261 * bus_addr_t card_addr, bus_size_t size,
2262 * struct pcmcia_mem_handle *pcmhp,
2263 * bus_size_t *offsetp, int *windowp)
2264 *
2265 * This function maps memory space allocated by the function
2266 * pccbb_pcmcia_mem_alloc().
2267 */
2268int
2269pccbb_pcmcia_mem_map(pcmcia_chipset_handle_t pch, int kind,
2270 bus_addr_t card_addr, bus_size_t size, struct pcmcia_mem_handle *pcmhp,
2271 bus_size_t *offsetp, int *windowp)
2272{
2273 struct pcic_handle *ph = (struct pcic_handle *)pch;
2274 bus_addr_t busaddr;
2275 long card_offset;
2276 int win;
2277
2278 for (win = 0; win < PCIC_MEM_WINS5; ++win) {
2279 if ((ph->memalloc & (1 << win)) == 0) {
2280 ph->memalloc |= (1 << win);
2281 break;
2282 }
2283 }
2284
2285 if (win == PCIC_MEM_WINS5) {
2286 return 1;
2287 }
2288
2289 *windowp = win;
2290
2291 /* XXX this is pretty gross */
2292
2293 if (((struct pccbb_softc *)ph->ph_parent)->sc_memt != pcmhp->memt) {
2294 panic("pccbb_pcmcia_mem_map memt is bogus");
2295 }
2296
2297 busaddr = pcmhp->addr;
2298
2299 /*
2300 * compute the address offset to the pcmcia address space for the
2301 * pcic. this is intentionally signed. The masks and shifts below
2302 * will cause TRT to happen in the pcic registers. Deal with making
2303 * sure the address is aligned, and return the alignment offset.
2304 */
2305
2306 *offsetp = card_addr % PCIC_MEM_PAGESIZE(1<<12);
2307 card_addr -= *offsetp;
2308
2309 DPRINTF(("pccbb_pcmcia_mem_map window %d bus %lx+%lx+%lx at card addr "
2310 "%lx\n", win, (u_long) busaddr, (u_long) * offsetp, (u_long) size,
2311 (u_long) card_addr));
2312
2313 /*
2314 * include the offset in the size, and decrement size by one, since
2315 * the hw wants start/stop
2316 */
2317 size += *offsetp - 1;
2318
2319 card_offset = (((long)card_addr) - ((long)busaddr));
2320
2321 ph->mem[win].addr = busaddr;
2322 ph->mem[win].size = size;
2323 ph->mem[win].offset = card_offset;
2324 ph->mem[win].kind = kind;
2325
2326 pccbb_pcmcia_do_mem_map(ph, win);
2327
2328 return 0;
2329}
2330
2331/*
2332 * int pccbb_pcmcia_mem_unmap(pcmcia_chipset_handle_t pch,
2333 * int window)
2334 *
2335 * This function unmaps memory space which mapped by the function
2336 * pccbb_pcmcia_mem_map().
2337 */
2338void
2339pccbb_pcmcia_mem_unmap(pcmcia_chipset_handle_t pch, int window)
2340{
2341 struct pcic_handle *ph = (struct pcic_handle *)pch;
2342 int reg;
2343
2344 if (window >= PCIC_MEM_WINS5) {
2345 panic("pccbb_pcmcia_mem_unmap: window out of range");
2346 }
2347
2348 reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE)((ph)->ph_read((ph), (0x06)));
2349 reg &= ~(1 << window);
2350 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg)((ph)->ph_write((ph), (0x06), (reg)));
2351
2352 ph->memalloc &= ~(1 << window);
2353}
2354
2355#if defined PCCBB_PCMCIA_POLL
2356struct pccbb_poll_str {
2357 void *arg;
2358 int (*func)(void *);
2359 int level;
2360 struct pcic_handle *ph;
2361 int count;
2362 int num;
2363};
2364
2365static struct pccbb_poll_str pccbb_poll[10];
2366static int pccbb_poll_n = 0;
2367static struct timeout pccbb_poll_timeout;
2368
2369void pccbb_pcmcia_poll(void *arg);
2370
2371void
2372pccbb_pcmcia_poll(void *arg)
2373{
2374 struct pccbb_poll_str *poll = arg;
2375 struct pcic_handle *ph = poll->ph;
2376 struct pccbb_softc *sc = ph->sc;
2377 int s;
2378 u_int32_t spsr; /* socket present-state reg */
2379
2380 timeout_set(&pccbb_poll_timeout, pccbb_pcmcia_poll, arg);
2381 timeout_add_sec(&pccbb_poll_timeout, 2);
2382 switch (poll->level) {
2383 case IPL_NET0x7:
2384 s = splnet()splraise(0x7);
2385 break;
2386 case IPL_BIO0x6:
2387 s = splbio()splraise(0x6);
2388 break;
2389 case IPL_TTY0x9: /* fallthrough */
2390 default:
2391 s = spltty()splraise(0x9);
2392 break;
2393 }
2394
2395 spsr =
2396 bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,((sc->sc_base_memt)->read_4((sc->sc_base_memh), (0x08
)))
2397 CB_SOCKET_STAT)((sc->sc_base_memt)->read_4((sc->sc_base_memh), (0x08
)))
;
2398
2399#if defined PCCBB_PCMCIA_POLL_ONLY && defined LEVEL2
2400 if (!(spsr & 0x40)) /* CINT low */
2401#else
2402 if (1)
2403#endif
2404 {
2405 if ((*poll->func) (poll->arg) > 0) {
2406 ++poll->count;
2407 /* printf("intr: reported from poller, 0x%x\n", spsr); */
2408#if defined LEVEL2
2409 } else {
2410 printf("intr: miss! 0x%x\n", spsr);
2411#endif
2412 }
2413 }
2414 splx(s)spllower(s);
2415}
2416#endif /* defined CB_PCMCIA_POLL */
2417
2418/*
2419 * void *pccbb_pcmcia_intr_establish(pcmcia_chipset_handle_t pch,
2420 * struct pcmcia_function *pf,
2421 * int ipl,
2422 * int (*func)(void *),
2423 * void *arg);
2424 *
2425 * This function enables PC-Card interrupt. PCCBB uses PCI interrupt line.
2426 */
2427void *
2428pccbb_pcmcia_intr_establish(pcmcia_chipset_handle_t pch,
2429 struct pcmcia_function *pf, int ipl, int (*func)(void *), void *arg,
2430 char *xname)
2431{
2432 struct pcic_handle *ph = (struct pcic_handle *)pch;
2433 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2434
2435 if (!(pf->cfe->flags & PCMCIA_CFE_IRQLEVEL0x0100)) {
2436 /* what should I do? */
2437 if ((pf->cfe->flags & PCMCIA_CFE_IRQLEVEL0x0100)) {
2438 DPRINTF(
2439 ("%s does not provide edge nor pulse interrupt\n",
2440 sc->sc_dev.dv_xname));
2441 return NULL((void *)0);
2442 }
2443 /*
2444 * XXX Noooooo! The interrupt flag must set properly!!
2445 * dumb pcmcia driver!!
2446 */
2447 }
2448
2449 return pccbb_intr_establish(sc, -1, ipl, func, arg, xname);
2450}
2451
2452/*
2453 * void pccbb_pcmcia_intr_disestablish(pcmcia_chipset_handle_t pch,
2454 * void *ih)
2455 *
2456 * This function disables PC-Card interrupt.
2457 */
2458void
2459pccbb_pcmcia_intr_disestablish(pcmcia_chipset_handle_t pch, void *ih)
2460{
2461 struct pcic_handle *ph = (struct pcic_handle *)pch;
2462 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2463
2464 pccbb_intr_disestablish(sc, ih);
2465}
2466
2467const char *
2468pccbb_pcmcia_intr_string(pcmcia_chipset_handle_t pch, void *ih)
2469{
2470 if (ih == NULL((void *)0))
2471 return "couldn't establish interrupt";
2472 else
2473 return ""; /* card shares interrupt of the bridge */
2474}
2475
2476/*
2477 * int
2478 * pccbb_rbus_cb_space_alloc(cardbus_chipset_tag_t ct, rbus_tag_t rb,
2479 * bus_addr_t addr, bus_size_t size,
2480 * bus_addr_t mask, bus_size_t align,
2481 * int flags, bus_addr_t *addrp;
2482 * bus_space_handle_t *bshp)
2483 *
2484 * This function allocates a portion of memory or io space for
2485 * clients. This function is called from CardBus card drivers.
2486 */
2487int
2488pccbb_rbus_cb_space_alloc(cardbus_chipset_tag_t ct, rbus_tag_t rb,
2489 bus_addr_t addr, bus_size_t size, bus_addr_t mask, bus_size_t align,
2490 int flags, bus_addr_t *addrp, bus_space_handle_t *bshp)
2491{
2492 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
2493
2494 DPRINTF(
2495 ("pccbb_rbus_cb_space_alloc: adr %lx, size %lx, mask %lx, align %lx\n",
2496 addr, size, mask, align));
2497
2498 align = max(align, 4);
2499 mask = max(mask, (4 - 1));
2500 if (rb->rb_bt == sc->sc_memt) {
2501 align = max(align, 0x1000);
2502 mask = max(mask, (0x1000 - 1));
2503 }
2504
2505 if (rb->rb_bt == sc->sc_iot) {
2506 /* XXX: hack for avoiding ISA image */
2507 if (mask < 0x0100) {
2508 mask = 0x3ff;
2509 addr = 0x300;
2510 }
2511 }
2512
2513 if (rbus_space_alloc(rb, addr, size, mask, align, flags, addrp, bshp)) {
2514 printf("%s: <rbus> no bus space\n", sc->sc_dev.dv_xname);
2515 return 1;
2516 }
2517
2518 pccbb_open_win(sc, rb->rb_bt, *addrp, size, *bshp, 0);
2519
2520 return 0;
2521}
2522
2523/*
2524 * int
2525 * pccbb_rbus_cb_space_free(cardbus_chipset_tag_t *ct, rbus_tag_t rb,
2526 * bus_space_handle_t *bshp, bus_size_t size);
2527 *
2528 * This function is called from CardBus card drivers.
2529 */
2530int
2531pccbb_rbus_cb_space_free(cardbus_chipset_tag_t ct, rbus_tag_t rb,
2532 bus_space_handle_t bsh, bus_size_t size)
2533{
2534 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
2535 bus_space_tag_t bt = rb->rb_bt;
2536
2537 pccbb_close_win(sc, bt, bsh, size);
2538
2539 if (bt == sc->sc_memt) {
2540 } else if (bt == sc->sc_iot) {
2541 } else {
2542 return 1;
2543 /* XXX: panic here? */
2544 }
2545
2546 return rbus_space_free(rb, bsh, size, NULL((void *)0));
2547}
2548
2549int
2550pccbb_open_win(struct pccbb_softc *sc, bus_space_tag_t bst, bus_addr_t addr,
2551 bus_size_t size, bus_space_handle_t bsh, int flags)
2552{
2553 struct pccbb_win_chain_head *head;
2554 bus_addr_t align;
2555
2556 head = &sc->sc_iowindow;
2557 align = 0x04;
2558 if (sc->sc_memt == bst) {
2559 head = &sc->sc_memwindow;
2560 align = 0x1000;
2561 DPRINTF(("using memory window, %x %x %x\n\n",
2562 sc->sc_iot, sc->sc_memt, bst));
2563 }
2564
2565 if (pccbb_winlist_insert(head, addr, size, bsh, flags)) {
2566 printf("%s: pccbb_open_win: %s winlist insert failed\n",
2567 sc->sc_dev.dv_xname,
2568 (head == &sc->sc_memwindow) ? "mem" : "io");
2569 }
2570 pccbb_winset(align, sc, bst);
2571
2572 return 0;
2573}
2574
2575int
2576pccbb_close_win(struct pccbb_softc *sc, bus_space_tag_t bst,
2577 bus_space_handle_t bsh, bus_size_t size)
2578{
2579 struct pccbb_win_chain_head *head;
2580 bus_addr_t align;
2581
2582 head = &sc->sc_iowindow;
2583 align = 0x04;
2584 if (sc->sc_memt == bst) {
2585 head = &sc->sc_memwindow;
2586 align = 0x1000;
2587 }
2588
2589 if (pccbb_winlist_delete(head, bsh, size)) {
2590 printf("%s: pccbb_close_win: %s winlist delete failed\n",
2591 sc->sc_dev.dv_xname,
2592 (head == &sc->sc_memwindow) ? "mem" : "io");
2593 }
2594 pccbb_winset(align, sc, bst);
2595
2596 return 0;
2597}
2598
2599int
2600pccbb_winlist_insert(struct pccbb_win_chain_head *head, bus_addr_t start,
2601 bus_size_t size, bus_space_handle_t bsh, int flags)
2602{
2603 struct pccbb_win_chain *chainp, *elem;
2604
2605 if ((elem = malloc(sizeof(struct pccbb_win_chain), M_DEVBUF2,
2606 M_NOWAIT0x0002)) == NULL((void *)0))
2607 return (1); /* fail */
2608
2609 elem->wc_start = start;
2610 elem->wc_end = start + (size - 1);
2611 elem->wc_handle = bsh;
2612 elem->wc_flags = flags;
2613
2614 for (chainp = TAILQ_FIRST(head)((head)->tqh_first); chainp != NULL((void *)0);
2615 chainp = TAILQ_NEXT(chainp, wc_list)((chainp)->wc_list.tqe_next)) {
2616 if (chainp->wc_end < start)
2617 continue;
2618 TAILQ_INSERT_AFTER(head, chainp, elem, wc_list)do { if (((elem)->wc_list.tqe_next = (chainp)->wc_list.
tqe_next) != ((void *)0)) (elem)->wc_list.tqe_next->wc_list
.tqe_prev = &(elem)->wc_list.tqe_next; else (head)->
tqh_last = &(elem)->wc_list.tqe_next; (chainp)->wc_list
.tqe_next = (elem); (elem)->wc_list.tqe_prev = &(chainp
)->wc_list.tqe_next; } while (0)
;
2619 return (0);
2620 }
2621
2622 TAILQ_INSERT_TAIL(head, elem, wc_list)do { (elem)->wc_list.tqe_next = ((void *)0); (elem)->wc_list
.tqe_prev = (head)->tqh_last; *(head)->tqh_last = (elem
); (head)->tqh_last = &(elem)->wc_list.tqe_next; } while
(0)
;
2623 return (0);
2624}
2625
2626int
2627pccbb_winlist_delete(struct pccbb_win_chain_head *head, bus_space_handle_t bsh,
2628 bus_size_t size)
2629{
2630 struct pccbb_win_chain *chainp;
2631
2632 for (chainp = TAILQ_FIRST(head)((head)->tqh_first); chainp != NULL((void *)0);
2633 chainp = TAILQ_NEXT(chainp, wc_list)((chainp)->wc_list.tqe_next)) {
2634 if (memcmp(&chainp->wc_handle, &bsh, sizeof(bsh))__builtin_memcmp((&chainp->wc_handle), (&bsh), (sizeof
(bsh)))
)
2635 continue;
2636 if ((chainp->wc_end - chainp->wc_start) != (size - 1)) {
2637 printf("pccbb_winlist_delete: window 0x%lx size "
2638 "inconsistent: 0x%lx, 0x%lx\n",
2639 chainp->wc_start,
2640 chainp->wc_end - chainp->wc_start,
2641 size - 1);
2642 return 1;
2643 }
2644
2645 TAILQ_REMOVE(head, chainp, wc_list)do { if (((chainp)->wc_list.tqe_next) != ((void *)0)) (chainp
)->wc_list.tqe_next->wc_list.tqe_prev = (chainp)->wc_list
.tqe_prev; else (head)->tqh_last = (chainp)->wc_list.tqe_prev
; *(chainp)->wc_list.tqe_prev = (chainp)->wc_list.tqe_next
; ((chainp)->wc_list.tqe_prev) = ((void *)-1); ((chainp)->
wc_list.tqe_next) = ((void *)-1); } while (0)
;
2646 free(chainp, M_DEVBUF2, sizeof *chainp);
2647
2648 return 0;
2649 }
2650
2651 return 1; /* fail: no candidate to remove */
2652}
2653
2654void
2655pccbb_winset(bus_addr_t align, struct pccbb_softc *sc, bus_space_tag_t bst)
2656{
2657 pci_chipset_tag_t pc;
2658 pcitag_t tag;
2659 bus_addr_t mask = ~(align - 1);
2660 struct {
2661 pcireg_t win_start;
2662 pcireg_t win_limit;
2663 int win_flags;
2664 } win[2];
2665 struct pccbb_win_chain *chainp;
2666 int offs;
2667
2668 win[0].win_start = win[1].win_start = 0xffffffff;
2669 win[0].win_limit = win[1].win_limit = 0;
2670 win[0].win_flags = win[1].win_flags = 0;
2671
2672 chainp = TAILQ_FIRST(&sc->sc_iowindow)((&sc->sc_iowindow)->tqh_first);
2673 offs = PCI_CB_IOBASE00x2C;
2674 if (sc->sc_memt == bst) {
2675 chainp = TAILQ_FIRST(&sc->sc_memwindow)((&sc->sc_memwindow)->tqh_first);
2676 offs = PCI_CB_MEMBASE00x1C;
2677 }
2678
2679 if (chainp != NULL((void *)0)) {
2680 win[0].win_start = chainp->wc_start & mask;
2681 win[0].win_limit = chainp->wc_end & mask;
2682 win[0].win_flags = chainp->wc_flags;
2683 chainp = TAILQ_NEXT(chainp, wc_list)((chainp)->wc_list.tqe_next);
2684 }
2685
2686 for (; chainp != NULL((void *)0); chainp = TAILQ_NEXT(chainp, wc_list)((chainp)->wc_list.tqe_next)) {
2687 if (win[1].win_start == 0xffffffff) {
2688 /* window 1 is not used */
2689 if ((win[0].win_flags == chainp->wc_flags) &&
2690 (win[0].win_limit + align >=
2691 (chainp->wc_start & mask))) {
2692 /* concatenate */
2693 win[0].win_limit = chainp->wc_end & mask;
2694 } else {
2695 /* make new window */
2696 win[1].win_start = chainp->wc_start & mask;
2697 win[1].win_limit = chainp->wc_end & mask;
2698 win[1].win_flags = chainp->wc_flags;
2699 }
2700 continue;
2701 }
2702
2703 /* Both windows are engaged. */
2704 if (win[0].win_flags == win[1].win_flags) {
2705 /* same flags */
2706 if (win[0].win_flags == chainp->wc_flags) {
2707 if (win[1].win_start - (win[0].win_limit +
2708 align) <
2709 (chainp->wc_start & mask) -
2710 ((chainp->wc_end & mask) + align)) {
2711 /*
2712 * merge window 0 and 1, and set win1
2713 * to chainp
2714 */
2715 win[0].win_limit = win[1].win_limit;
2716 win[1].win_start =
2717 chainp->wc_start & mask;
2718 win[1].win_limit =
2719 chainp->wc_end & mask;
2720 } else {
2721 win[1].win_limit =
2722 chainp->wc_end & mask;
2723 }
2724 } else {
2725 /* different flags */
2726
2727 /* concatenate win0 and win1 */
2728 win[0].win_limit = win[1].win_limit;
2729 /* allocate win[1] to new space */
2730 win[1].win_start = chainp->wc_start & mask;
2731 win[1].win_limit = chainp->wc_end & mask;
2732 win[1].win_flags = chainp->wc_flags;
2733 }
2734 } else {
2735 /* the flags of win[0] and win[1] are different */
2736 if (win[0].win_flags == chainp->wc_flags) {
2737 win[0].win_limit = chainp->wc_end & mask;
2738 /*
2739 * XXX this creates overlapping windows, so
2740 * what should the poor bridge do if one is
2741 * cachable, and the other is not?
2742 */
2743 printf("%s: overlapping windows\n",
2744 sc->sc_dev.dv_xname);
2745 } else {
2746 win[1].win_limit = chainp->wc_end & mask;
2747 }
2748 }
2749 }
2750
2751 pc = sc->sc_pc;
2752 tag = sc->sc_tag;
2753 pci_conf_write(pc, tag, offs, win[0].win_start);
2754 pci_conf_write(pc, tag, offs + 4, win[0].win_limit);
2755 pci_conf_write(pc, tag, offs + 8, win[1].win_start);
2756 pci_conf_write(pc, tag, offs + 12, win[1].win_limit);
2757 DPRINTF(("--pccbb_winset: win0 [%x, %lx), win1 [%x, %lx)\n",
2758 pci_conf_read(pc, tag, offs),
2759 pci_conf_read(pc, tag, offs + 4) + align,
2760 pci_conf_read(pc, tag, offs + 8),
2761 pci_conf_read(pc, tag, offs + 12) + align));
2762
2763 if (bst == sc->sc_memt) {
2764 pcireg_t bcr = pci_conf_read(pc, tag, PCI_BCR_INTR0x3C);
2765
2766 bcr &= ~(CB_BCR_PREFETCH_MEMWIN00x01000000 | CB_BCR_PREFETCH_MEMWIN10x02000000);
2767 if (win[0].win_flags & PCCBB_MEM_CACHABLE1)
2768 bcr |= CB_BCR_PREFETCH_MEMWIN00x01000000;
2769 if (win[1].win_flags & PCCBB_MEM_CACHABLE1)
2770 bcr |= CB_BCR_PREFETCH_MEMWIN10x02000000;
2771 pci_conf_write(pc, tag, PCI_BCR_INTR0x3C, bcr);
2772 }
2773}
2774
2775int
2776pccbbactivate(struct device *self, int act)
2777{
2778 struct pccbb_softc *sc = (struct pccbb_softc *)self;
2779 pci_chipset_tag_t pc = sc->sc_pc;
2780 pcitag_t tag = sc->sc_tag;
2781 pcireg_t csr;
2782 u_int32_t reg;
2783 bus_space_tag_t base_memt = sc->sc_base_memt; /* socket regs memory */
2784 bus_space_handle_t base_memh = sc->sc_base_memh;
2785 int rv = 0;
2786
2787 switch (act) {
2788 case DVACT_SUSPEND3:
2789 rv = config_activate_children(self, act);
2790
2791 sc->sc_pil_intr_enable = 0;
2792
2793 /* Save registers that may get lost. */
2794 sc->sc_csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG0x04);
2795 sc->sc_bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG0x0c);
2796 sc->sc_int = pci_conf_read(pc, tag, PCI_INTERRUPT_REG0x3c);
2797
2798 sc->sc_sockbase = pci_conf_read(pc, tag, PCI_SOCKBASE0x10);
2799 sc->sc_busnum = pci_conf_read(pc, tag, PCI_BUSNUM0x18);
2800
2801 sc->sc_membase[0] = pci_conf_read(pc, tag, PCI_CB_MEMBASE00x1C);
2802 sc->sc_memlimit[0] = pci_conf_read(pc, tag, PCI_CB_MEMLIMIT00x20);
2803 sc->sc_membase[1] = pci_conf_read(pc, tag, PCI_CB_MEMBASE10x24);
2804 sc->sc_memlimit[1] = pci_conf_read(pc, tag, PCI_CB_MEMLIMIT10x28);
2805 sc->sc_iobase[0] = pci_conf_read(pc, tag, PCI_CB_IOBASE00x2C);
2806 sc->sc_iolimit[0] = pci_conf_read(pc, tag, PCI_CB_IOLIMIT00x30);
2807 sc->sc_iobase[1] = pci_conf_read(pc, tag, PCI_CB_IOBASE10x34);
2808 sc->sc_iolimit[1] = pci_conf_read(pc, tag, PCI_CB_IOLIMIT10x38);
2809 break;
2810 case DVACT_RESUME4:
2811 /* Restore the registers saved above. */
2812 pci_conf_write(pc, tag, PCI_BHLC_REG0x0c, sc->sc_bhlcr);
2813 pci_conf_write(pc, tag, PCI_INTERRUPT_REG0x3c, sc->sc_int);
2814
2815 pci_conf_write(pc, tag, PCI_SOCKBASE0x10, sc->sc_sockbase);
2816 pci_conf_write(pc, tag, PCI_BUSNUM0x18, sc->sc_busnum);
2817
2818 pci_conf_write(pc, tag, PCI_CB_MEMBASE00x1C, sc->sc_membase[0]);
2819 pci_conf_write(pc, tag, PCI_CB_MEMLIMIT00x20, sc->sc_memlimit[0]);
2820 pci_conf_write(pc, tag, PCI_CB_MEMBASE10x24, sc->sc_membase[1]);
2821 pci_conf_write(pc, tag, PCI_CB_MEMLIMIT10x28, sc->sc_memlimit[1]);
2822 pci_conf_write(pc, tag, PCI_CB_IOBASE00x2C, sc->sc_iobase[0]);
2823 pci_conf_write(pc, tag, PCI_CB_IOLIMIT00x30, sc->sc_iolimit[0]);
2824 pci_conf_write(pc, tag, PCI_CB_IOBASE10x34, sc->sc_iobase[1]);
2825 pci_conf_write(pc, tag, PCI_CB_IOLIMIT10x38, sc->sc_iolimit[1]);
2826
2827 /* Disable legacy register mapping. */
2828 pccbb_legacy_disable(sc);
2829
2830 /*
2831 * Restore command register last to avoid exposing
2832 * uninitialised windows.
2833 */
2834 csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG0x04);
2835 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG0x04,
2836 (csr & 0xffff0000) | (sc->sc_csr & 0x0000ffff));
2837
2838 /* CSC Interrupt: Card detect interrupt on */
2839 reg = bus_space_read_4(base_memt, base_memh, CB_SOCKET_MASK)((base_memt)->read_4((base_memh), (0x04)));
2840 /* Card detect intr is turned on. */
2841 reg |= CB_SOCKET_MASK_CD0x06;
2842 bus_space_write_4(base_memt, base_memh, CB_SOCKET_MASK, reg)((base_memt)->write_4((base_memh), (0x04), (reg)));
2843
2844 /* reset interrupt */
2845 reg = bus_space_read_4(base_memt, base_memh, CB_SOCKET_EVENT)((base_memt)->read_4((base_memh), (0x00)));
2846 bus_space_write_4(base_memt, base_memh, CB_SOCKET_EVENT, reg)((base_memt)->write_4((base_memh), (0x00), (reg)));
2847
2848 /* re-check all cards */
2849 pccbb_checksockstat(sc);
2850
2851 /*
2852 * XXX Because the cardslot stuff is so obfuscated with threads,
2853 * here we are activating children which may have been
2854 * ejected while we were asleep. This needs to be solved.
2855 */
2856 rv = config_activate_children(self, act);
2857
2858 sc->sc_pil_intr_enable = 1;
2859 break;
2860 case DVACT_POWERDOWN6:
2861 rv = config_activate_children(self, act);
2862 pccbb_shutdown(self);
2863 break;
2864 default:
2865 rv = config_activate_children(self, act);
2866 break;
2867 }
2868 return (rv);
2869}