Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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