1 /* 2 * Copyright (c) 2000,2001 Jonathan Chen. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions, and the following disclaimer, 10 * without modification, immediately at the beginning of the file. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 */ 30 31 /* 32 * Driver for PCI to Cardbus Bridge chips 33 * 34 * References: 35 * TI Datasheets: 36 * http://www-s.ti.com/cgi-bin/sc/generic2.cgi?family=PCI+CARDBUS+CONTROLLERS 37 * Much of the 16-bit PC Card compatibility code stolen from dev/pcic/i82365.c 38 * XXX and should be cleaned up to share as much as possible. 39 * 40 * Written by Jonathan Chen <jon@freebsd.org> 41 * The author would like to acknowledge: 42 * * HAYAKAWA Koichi: Author of the NetBSD code for the same thing 43 * * Warner Losh: Newbus/newcard guru and author of the pccard side of things 44 * * YAMAMOTO Shigeru: Author of another FreeBSD cardbus driver 45 * * David Cross: Author of the initial ugly hack for a specific cardbus card 46 */ 47 48 #define CBB_DEBUG 49 50 #include <sys/param.h> 51 #include <sys/systm.h> 52 #include <sys/errno.h> 53 #include <sys/kernel.h> 54 #include <sys/kthread.h> 55 #include <sys/malloc.h> 56 57 #include <sys/bus.h> 58 #include <machine/bus.h> 59 #include <sys/rman.h> 60 #include <machine/resource.h> 61 62 #include <pci/pcireg.h> 63 #include <pci/pcivar.h> 64 #include <machine/clock.h> 65 66 #include <dev/pccard/pccardreg.h> 67 #include <dev/pccard/pccardvar.h> 68 #include <dev/pcic/i82365reg.h> 69 70 #include <dev/pccbb/pccbbreg.h> 71 #include <dev/pccbb/pccbbvar.h> 72 73 #include "power_if.h" 74 #include "card_if.h" 75 #include "pccbb_if.h" 76 #include "pcib_if.h" 77 78 #if defined CBB_DEBUG 79 #define DPRINTF(x) printf x 80 #define DEVPRINTF(x) device_printf x 81 #else 82 #define DPRINTF(x) 83 #define DEVPRINTF(x) 84 #endif 85 86 #define PCI_MASK_CONFIG(DEV,REG,MASK,SIZE) \ 87 pci_write_config(DEV, REG, pci_read_config(DEV, REG, SIZE) MASK, SIZE) 88 #define PCI_MASK2_CONFIG(DEV,REG,MASK1,MASK2,SIZE) \ 89 pci_write_config(DEV, REG, ( \ 90 pci_read_config(DEV, REG, SIZE) MASK1) MASK2, SIZE) 91 92 #define PCIC_READ(SC,REG) \ 93 (((u_int8_t*)((SC)->sc_socketreg))[0x800+(REG)]) 94 #define PCIC_WRITE(SC,REG,val) \ 95 (((u_int8_t*)((SC)->sc_socketreg))[0x800+(REG)]) = (val) 96 #define PCIC_MASK(SC,REG,MASK) \ 97 PCIC_WRITE(SC,REG,PCIC_READ(SC,REG) MASK) 98 #define PCIC_MASK2(SC,REG,MASK,MASK2) \ 99 PCIC_WRITE(SC,REG,(PCIC_READ(SC,REG) MASK) MASK2) 100 101 #define DETACH_FORCE 0x1 102 103 struct pccbb_sclist { 104 struct pccbb_softc *sc; 105 STAILQ_ENTRY(pccbb_sclist) entries; 106 }; 107 108 static STAILQ_HEAD(, pccbb_sclist) softcs; 109 static int softcs_init = 0; 110 111 112 struct yenta_chipinfo { 113 u_int32_t yc_id; 114 const char *yc_name; 115 int yc_chiptype; 116 int yc_flags; 117 } yc_chipsets[] = { 118 /* Texas Instruments chips */ 119 {PCI_DEVICE_ID_PCIC_TI1130, "TI1130 PCI-CardBus Bridge", CB_TI113X, 120 PCCBB_PCIC_IO_RELOC | PCCBB_PCIC_MEM_32}, 121 {PCI_DEVICE_ID_PCIC_TI1131, "TI1131 PCI-CardBus Bridge", CB_TI113X, 122 PCCBB_PCIC_IO_RELOC | PCCBB_PCIC_MEM_32}, 123 124 {PCI_DEVICE_ID_PCIC_TI1211, "TI1211 PCI-CardBus Bridge", CB_TI12XX, 125 PCCBB_PCIC_IO_RELOC | PCCBB_PCIC_MEM_32}, 126 {PCI_DEVICE_ID_PCIC_TI1220, "TI1220 PCI-CardBus Bridge", CB_TI12XX, 127 PCCBB_PCIC_IO_RELOC | PCCBB_PCIC_MEM_32}, 128 {PCI_DEVICE_ID_PCIC_TI1221, "TI1221 PCI-CardBus Bridge", CB_TI12XX, 129 PCCBB_PCIC_IO_RELOC | PCCBB_PCIC_MEM_32}, 130 {PCI_DEVICE_ID_PCIC_TI1225, "TI1225 PCI-CardBus Bridge", CB_TI12XX, 131 PCCBB_PCIC_IO_RELOC | PCCBB_PCIC_MEM_32}, 132 {PCI_DEVICE_ID_PCIC_TI1250, "TI1250 PCI-CardBus Bridge", CB_TI12XX, 133 PCCBB_PCIC_IO_RELOC | PCCBB_PCIC_MEM_32}, 134 {PCI_DEVICE_ID_PCIC_TI1251, "TI1251 PCI-CardBus Bridge", CB_TI12XX, 135 PCCBB_PCIC_IO_RELOC | PCCBB_PCIC_MEM_32}, 136 {PCI_DEVICE_ID_PCIC_TI1251B,"TI1251B PCI-CardBus Bridge",CB_TI12XX, 137 PCCBB_PCIC_IO_RELOC | PCCBB_PCIC_MEM_32}, 138 {PCI_DEVICE_ID_PCIC_TI1410, "TI1410 PCI-CardBus Bridge", CB_TI12XX, 139 PCCBB_PCIC_IO_RELOC | PCCBB_PCIC_MEM_32}, 140 {PCI_DEVICE_ID_PCIC_TI1420, "TI1420 PCI-CardBus Bridge", CB_TI12XX, 141 PCCBB_PCIC_IO_RELOC | PCCBB_PCIC_MEM_32}, 142 {PCI_DEVICE_ID_PCIC_TI1450, "TI1450 PCI-CardBus Bridge", CB_TI12XX, 143 PCCBB_PCIC_IO_RELOC | PCCBB_PCIC_MEM_32}, 144 {PCI_DEVICE_ID_PCIC_TI1451, "TI1451 PCI-CardBus Bridge", CB_TI12XX, 145 PCCBB_PCIC_IO_RELOC | PCCBB_PCIC_MEM_32}, 146 147 /* Ricoh chips */ 148 {PCI_DEVICE_ID_RICOH_RL5C465, "RF5C465 PCI-CardBus Bridge", 149 CB_RF5C46X, PCCBB_PCIC_MEM_32}, 150 {PCI_DEVICE_ID_RICOH_RL5C466, "RF5C466 PCI-CardBus Bridge", 151 CB_RF5C46X, PCCBB_PCIC_MEM_32}, 152 {PCI_DEVICE_ID_RICOH_RL5C475, "RF5C475 PCI-CardBus Bridge", 153 CB_RF5C47X, PCCBB_PCIC_MEM_32}, 154 {PCI_DEVICE_ID_RICOH_RL5C476, "RF5C476 PCI-CardBus Bridge", 155 CB_RF5C47X, PCCBB_PCIC_MEM_32}, 156 {PCI_DEVICE_ID_RICOH_RL5C478, "RF5C478 PCI-CardBus Bridge", 157 CB_RF5C47X, PCCBB_PCIC_MEM_32}, 158 159 /* Toshiba products */ 160 {PCI_DEVICE_ID_TOSHIBA_TOPIC95, "ToPIC95 PCI-CardBus Bridge", 161 CB_TOPIC95, PCCBB_PCIC_MEM_32}, 162 {PCI_DEVICE_ID_TOSHIBA_TOPIC95B, "ToPIC95B PCI-CardBus Bridge", 163 CB_TOPIC95B, PCCBB_PCIC_MEM_32}, 164 {PCI_DEVICE_ID_TOSHIBA_TOPIC97, "ToPIC97 PCI-CardBus Bridge", 165 CB_TOPIC97, PCCBB_PCIC_MEM_32}, 166 {PCI_DEVICE_ID_TOSHIBA_TOPIC100, "ToPIC100 PCI-CardBus Bridge", 167 CB_TOPIC97, PCCBB_PCIC_MEM_32}, 168 169 /* Cirrus Logic */ 170 {PCI_DEVICE_ID_PCIC_CLPD6832, "CLPD6832 PCI-CardBus Bridge", 171 CB_CIRRUS, PCCBB_PCIC_MEM_32}, 172 {PCI_DEVICE_ID_PCIC_CLPD6833, "CLPD6833 PCI-CardBus Bridge", 173 CB_CIRRUS, PCCBB_PCIC_MEM_32}, 174 175 /* sentinel */ 176 {0 /* null id */, "unknown", 177 CB_UNKNOWN, 0}, 178 }; 179 180 181 static int cb_chipset(u_int32_t pci_id, const char** namep, int* flagp); 182 static int pccbb_probe(device_t dev); 183 static void pccbb_chipinit(struct pccbb_softc* sc); 184 static int pccbb_attach(device_t dev); 185 static void pccbb_event_thread (void *arg); 186 static void pccbb_create_event_thread (struct pccbb_softc *sc); 187 static void pccbb_start_threads(void *arg); 188 static void pccbb_insert (struct pccbb_softc *sc); 189 static void pccbb_removal (struct pccbb_softc *sc); 190 static void pccbb_intr(void* arg); 191 static int pccbb_detect_voltage(struct pccbb_softc *sc); 192 static int pccbb_power(device_t dev, int volts); 193 static int pccbb_cardbus_detect_card(device_t dev); 194 static int pccbb_cardbus_reset(device_t dev); 195 static int pccbb_cardbus_io_open(device_t dev, int win, 196 u_int32_t start, u_int32_t end); 197 static int pccbb_cardbus_mem_open(device_t dev, int win, 198 u_int32_t start, u_int32_t end); 199 static void pccbb_cardbus_auto_open(struct pccbb_softc *sc, int type); 200 static int pccbb_cardbus_activate_resource(device_t self, device_t child, 201 int type, int rid, 202 struct resource *r); 203 static int pccbb_cardbus_deactivate_resource(device_t self, device_t child, 204 int type, int rid, 205 struct resource *r); 206 static struct resource* pccbb_cardbus_alloc_resource(device_t self, 207 device_t child, int type, int* rid, 208 u_long start, u_long end, u_long count, 209 u_int flags); 210 static int pccbb_cardbus_release_resource(device_t self, device_t child, 211 int type,int rid, 212 struct resource *r); 213 static void pccbb_pcic_wait_ready(struct pccbb_softc *sc); 214 static void pccbb_pcic_do_mem_map(struct pccbb_softc *sc, int win); 215 static int pccbb_pcic_mem_map(struct pccbb_softc *sc, int kind, 216 struct resource *r, bus_addr_t card_addr, 217 int *win); 218 static void pccbb_pcic_mem_unmap(struct pccbb_softc *sc, int window); 219 static void pccbb_pcic_do_io_map(struct pccbb_softc *sc, int win); 220 static int pccbb_pcic_io_map(struct pccbb_softc *sc, int width, 221 struct resource *r, bus_addr_t card_addr, 222 int *win); 223 static void pccbb_pcic_io_unmap(struct pccbb_softc *sc, int window); 224 static int pccbb_pcic_activate_resource(device_t self, device_t child, 225 int type, int rid, struct resource *r); 226 static int pccbb_pcic_deactivate_resource(device_t self, device_t child, 227 int type,int rid, struct resource *r); 228 static struct resource* pccbb_pcic_alloc_resource(device_t self,device_t child, 229 int type, int* rid, u_long start, 230 u_long end, u_long count, u_int flags); 231 static int pccbb_pcic_release_resource(device_t self, device_t child, int type, 232 int rid, struct resource *res); 233 static int pccbb_pcic_set_res_flags(device_t self, device_t child, int type, 234 int rid, u_int32_t flags); 235 static int pccbb_pcic_set_memory_offset(device_t self, device_t child, int rid, 236 u_int32_t offset); 237 static int pccbb_pcic_enable_socket(device_t self, device_t child); 238 static void pccbb_pcic_disable_socket(device_t self, device_t child); 239 static int pccbb_activate_resource(device_t self, device_t child, int type, 240 int rid, struct resource *r); 241 static int pccbb_deactivate_resource(device_t self, device_t child, int type, 242 int rid, struct resource *r); 243 static struct resource* pccbb_alloc_resource(device_t self, device_t child, 244 int type, int* rid, u_long start, 245 u_long end, u_long count, 246 u_int flags); 247 static int pccbb_release_resource(device_t self, device_t child, 248 int type, int rid, struct resource *r); 249 250 251 /************************************************************************/ 252 /* Probe/Attach */ 253 /************************************************************************/ 254 255 static int 256 cb_chipset(u_int32_t pci_id, const char** namep, int* flagp) 257 { 258 int loopend = sizeof(yc_chipsets)/sizeof(yc_chipsets[0]); 259 struct yenta_chipinfo *ycp, *ycend; 260 ycend = yc_chipsets + loopend; 261 262 for (ycp = yc_chipsets; ycp < ycend && pci_id != ycp->yc_id; ++ycp); 263 if (ycp == ycend) { 264 /* not found */ 265 ycp = yc_chipsets + loopend - 1; /* to point the sentinel */ 266 } 267 if (namep != NULL) { 268 *namep = ycp->yc_name; 269 } 270 if (flagp != NULL) { 271 *flagp = ycp->yc_flags; 272 } 273 return ycp->yc_chiptype; 274 } 275 276 static int 277 pccbb_probe(device_t dev) 278 { 279 const char *name; 280 281 if (cb_chipset(pci_get_devid(dev), &name, NULL) == CB_UNKNOWN) 282 return ENXIO; 283 device_set_desc(dev, name); 284 return 0; 285 } 286 287 static void 288 pccbb_chipinit(struct pccbb_softc* sc) 289 { 290 /* Set CardBus latency timer */ 291 if (pci_read_config(sc->sc_dev, PCIR_SECLAT_1, 1) < 0x20) 292 pci_write_config(sc->sc_dev, PCIR_SECLAT_1, 0x20, 1); 293 294 /* Set PCI latency timer */ 295 if (pci_read_config(sc->sc_dev, PCIR_LATTIMER, 1) < 0x20) 296 pci_write_config(sc->sc_dev, PCIR_LATTIMER, 0x20, 1); 297 298 /* Enable memory access */ 299 PCI_MASK_CONFIG(sc->sc_dev, PCIR_COMMAND, 300 | PCIM_CMD_MEMEN 301 | PCIM_CMD_PORTEN 302 | PCIM_CMD_BUSMASTEREN, 2); 303 304 /* disable Legacy IO */ 305 switch (sc->sc_chipset) { 306 case CB_RF5C46X: 307 case CB_RF5C47X: 308 PCI_MASK_CONFIG(sc->sc_dev, PCCBBR_BRIDGECTRL, 309 & ~(PCCBBM_BRIDGECTRL_RL_3E0_EN| 310 PCCBBM_BRIDGECTRL_RL_3E2_EN), 2); 311 break; 312 default: 313 pci_write_config(sc->sc_dev, PCCBBR_LEGACY, 0x0, 4); 314 break; 315 } 316 317 /* Use PCI interrupt for interrupt routing */ 318 PCI_MASK2_CONFIG(sc->sc_dev, PCCBBR_BRIDGECTRL, 319 & ~(PCCBBM_BRIDGECTRL_MASTER_ABORT | 320 PCCBBM_BRIDGECTRL_INTR_IREQ_EN), 321 | PCCBBM_BRIDGECTRL_WRITE_POST_EN, 322 2); 323 324 switch (sc->sc_chipset) { 325 case CB_TI113X: 326 PCI_MASK2_CONFIG(sc->sc_dev, PCCBBR_CBCTRL, 327 & ~PCCBBM_CBCTRL_113X_PCI_INTR, 328 | PCCBBM_CBCTRL_113X_PCI_CSC 329 | PCCBBM_CBCTRL_113X_PCI_IRQ_EN, 1); 330 PCI_MASK_CONFIG(sc->sc_dev, PCCBBR_DEVCTRL, 331 & ~(PCCBBM_DEVCTRL_INT_SERIAL| 332 PCCBBM_DEVCTRL_INT_PCI), 1); 333 PCIC_WRITE(sc, PCIC_INTR, PCIC_INTR_ENABLE); 334 PCIC_WRITE(sc, PCIC_CSC_INTR, 0); 335 break; 336 case CB_TI12XX: 337 PCIC_WRITE(sc, PCIC_INTR, PCIC_INTR_ENABLE); 338 PCIC_WRITE(sc, PCIC_CSC_INTR, 0); 339 break; 340 case CB_TOPIC95B: 341 PCI_MASK_CONFIG(sc->sc_dev, PCCBBR_TOPIC_SOCKETCTRL, 342 | PCCBBM_TOPIC_SOCKETCTRL_SCR_IRQSEL, 4); 343 PCI_MASK2_CONFIG(sc->sc_dev, PCCBBR_TOPIC_SLOTCTRL, 344 | PCCBBM_TOPIC_SLOTCTRL_SLOTON 345 | PCCBBM_TOPIC_SLOTCTRL_SLOTEN 346 | PCCBBM_TOPIC_SLOTCTRL_ID_LOCK 347 | PCCBBM_TOPIC_SLOTCTRL_CARDBUS, 348 & ~PCCBBM_TOPIC_SLOTCTRL_SWDETECT, 4); 349 break; 350 } 351 352 /* close all memory and io windows */ 353 pci_write_config(sc->sc_dev, PCCBBR_MEMBASE0, 0xffffffff, 4); 354 pci_write_config(sc->sc_dev, PCCBBR_MEMLIMIT0, 0, 4); 355 pci_write_config(sc->sc_dev, PCCBBR_MEMBASE1, 0xffffffff, 4); 356 pci_write_config(sc->sc_dev, PCCBBR_MEMLIMIT1, 0, 4); 357 pci_write_config(sc->sc_dev, PCCBBR_IOBASE0, 0xffffffff, 4); 358 pci_write_config(sc->sc_dev, PCCBBR_IOLIMIT0, 0, 4); 359 pci_write_config(sc->sc_dev, PCCBBR_IOBASE1, 0xffffffff, 4); 360 pci_write_config(sc->sc_dev, PCCBBR_IOLIMIT1, 0, 4); 361 } 362 363 static int 364 pccbb_attach(device_t dev) 365 { 366 struct pccbb_softc *sc = (struct pccbb_softc *)device_get_softc(dev); 367 int flags; 368 int rid; 369 u_int32_t tmp; 370 371 if (!softcs_init) { 372 softcs_init = 1; 373 STAILQ_INIT(&softcs); 374 } 375 sc->sc_chipset = cb_chipset(pci_get_devid(dev), NULL, &flags); 376 sc->sc_dev = dev; 377 sc->sc_flags = 0; 378 sc->sc_cbdev = NULL; 379 sc->sc_pccarddev = NULL; 380 sc->memalloc = 0; 381 sc->ioalloc = 0; 382 SLIST_INIT(&sc->rl); 383 384 /* Ths PCI bus should have given me memory... right? */ 385 rid=PCCBBR_SOCKBASE; 386 sc->sc_base_res=bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 387 0,~0,1, RF_ACTIVE); 388 if (!sc->sc_base_res) { 389 /* 390 * XXX eVILE HACK BAD THING! XXX 391 * The pci bus device should do this for us. 392 * Some BIOSes doesn't assign a memory space properly. 393 * So we try to manually put one in... 394 */ 395 u_int32_t sockbase; 396 397 sockbase = pci_read_config(dev, rid, 4); 398 if (sockbase < 0x100000 || sockbase >= 0xfffffff0) { 399 pci_write_config(dev, rid, 0xffffffff, 4); 400 sockbase = pci_read_config(dev, rid, 4); 401 sockbase = (sockbase & 0xfffffff0) & 402 -(sockbase & 0xfffffff0); 403 sc->sc_base_res = bus_generic_alloc_resource( 404 device_get_parent(dev), dev, SYS_RES_MEMORY, 405 &rid, CARDBUS_SYS_RES_MEMORY_START, 406 CARDBUS_SYS_RES_MEMORY_END, sockbase, 407 RF_ACTIVE|rman_make_alignment_flags(sockbase)); 408 if (!sc->sc_base_res){ 409 device_printf(dev, 410 "Could not grab register memory\n"); 411 return ENOMEM; 412 } 413 pci_write_config(dev, PCCBBR_SOCKBASE, 414 rman_get_start(sc->sc_base_res), 4); 415 DEVPRINTF((dev, "PCI Memory allocated: %08lx\n", 416 rman_get_start(sc->sc_base_res))); 417 } else { 418 device_printf(dev, "Could not map register memory\n"); 419 return ENOMEM; 420 } 421 } 422 423 sc->sc_socketreg = 424 (struct pccbb_socketreg *)rman_get_virtual(sc->sc_base_res); 425 pccbb_chipinit(sc); 426 427 /* CSC Interrupt: Card detect interrupt on */ 428 sc->sc_socketreg->socket_mask |= PCCBB_SOCKET_MASK_CD; 429 430 /* reset interrupt */ 431 tmp = sc->sc_socketreg->socket_event; 432 sc->sc_socketreg->socket_event = tmp; 433 434 /* Map and establish the interrupt. */ 435 rid=0; 436 sc->sc_irq_res=bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 437 RF_SHAREABLE | RF_ACTIVE); 438 if (sc->sc_irq_res == NULL) { 439 printf("pccbb: Unable to map IRQ...\n"); 440 return ENOMEM; 441 } 442 443 if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO, pccbb_intr, sc, 444 &(sc->sc_intrhand))) { 445 device_printf(dev, "couldn't establish interrupt"); 446 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); 447 bus_release_resource(dev, SYS_RES_MEMORY, PCCBBR_SOCKBASE, 448 sc->sc_base_res); 449 return ENOMEM; 450 } 451 452 /* attach children */ 453 sc->sc_cbdev = device_add_child(dev, "cardbus", -1); 454 if (sc->sc_cbdev == NULL) 455 DEVPRINTF((dev, "Cannot add cardbus bus!\n")); 456 else if (device_probe_and_attach(sc->sc_cbdev) != 0) { 457 DEVPRINTF((dev, "Cannot attach cardbus bus!\n")); 458 sc->sc_cbdev = NULL; 459 } 460 461 sc->sc_pccarddev = device_add_child(dev, "pccard", -1); 462 if (sc->sc_pccarddev == NULL) 463 DEVPRINTF((dev, "Cannot add pccard bus!\n")); 464 else if (device_probe_and_attach(sc->sc_pccarddev) != 0) { 465 DEVPRINTF((dev, "Cannot attach pccard bus!\n")); 466 sc->sc_pccarddev = NULL; 467 } 468 469 if (sc->sc_cbdev == NULL && sc->sc_pccarddev == NULL) { 470 device_printf(dev, "Failed to attach cardbus/pccard bus!\n"); 471 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand); 472 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); 473 bus_release_resource(dev, SYS_RES_MEMORY, PCCBBR_SOCKBASE, 474 sc->sc_base_res); 475 return ENOMEM; 476 } 477 478 { 479 struct pccbb_sclist *sclist; 480 sclist = malloc(sizeof(struct pccbb_sclist), M_DEVBUF, 481 M_WAITOK); 482 sclist->sc = sc; 483 STAILQ_INSERT_TAIL(&softcs, sclist, entries); 484 } 485 return 0; 486 } 487 488 /************************************************************************/ 489 /* Kthreads */ 490 /************************************************************************/ 491 492 static void 493 pccbb_event_thread (void *arg) 494 { 495 struct pccbb_softc *sc = arg; 496 int s; 497 u_int32_t status; 498 499 s = splhigh(); 500 for(;;) { 501 if (sc->sc_flags & PCCBB_INITIALCARD) 502 sc->sc_flags &= ~PCCBB_INITIALCARD; 503 else { 504 splx (s); 505 tsleep (sc, PWAIT, "pccbbev", 0); 506 /* 507 * Delay some time, make sure the user is done with 508 * whatever he is doing. 509 */ 510 DELAY(1000*1000); 511 s = splhigh(); 512 } 513 514 sc->sc_flags |= PCCBB_CARDSTATUS_BUSY; 515 status = sc->sc_socketreg->socket_state; 516 if ((status & PCCBB_SOCKET_STAT_CD) == 0) { 517 if (!(sc->sc_flags & PCCBB_CARDATTACHED)) 518 pccbb_insert(sc); 519 else 520 device_printf(sc->sc_dev, 521 "duplicate card insert\n"); 522 } else { 523 if (!(sc->sc_flags & PCCBB_CARDATTACHED)) 524 DEVPRINTF((sc->sc_dev, 525 "removal of nonexistant card!\n")); 526 else 527 pccbb_removal(sc); 528 } 529 sc->sc_flags &= ~PCCBB_CARDSTATUS_BUSY; 530 splx (s); 531 } 532 /* NOTREACHED */ 533 kthread_exit(0); 534 } 535 536 static void 537 pccbb_create_event_thread (struct pccbb_softc *sc) 538 { 539 if (kthread_create(pccbb_event_thread, sc, &sc->event_thread, 540 0, "%s%d", device_get_name(sc->sc_dev), 541 device_get_unit(sc->sc_dev))) { 542 device_printf (sc->sc_dev, "unable to create event thread.\n"); 543 panic ("pccbb_create_event_thread"); 544 } 545 } 546 547 static void 548 pccbb_start_threads(void *arg) 549 { 550 struct pccbb_sclist *sclist; 551 552 STAILQ_FOREACH(sclist, &softcs, entries) { 553 if (0 == (sclist->sc->sc_socketreg->socket_state & 554 PCCBB_SOCKET_STAT_CD)) { 555 sclist->sc->sc_flags |= PCCBB_INITIALCARD; 556 } 557 pccbb_create_event_thread(sclist->sc); 558 } 559 } 560 561 /************************************************************************/ 562 /* Insert/removal */ 563 /************************************************************************/ 564 565 static void 566 pccbb_insert (struct pccbb_softc *sc) 567 { 568 u_int32_t sockevent, sockstate; 569 int timeout = 30; 570 571 do { 572 sockevent = sc->sc_socketreg->socket_event; 573 sockstate = sc->sc_socketreg->socket_state; 574 } while (sockstate & PCCBB_SOCKET_STAT_CD && --timeout > 0); 575 576 if (timeout < 0) { 577 device_printf (sc->sc_dev, "insert timeout"); 578 return; 579 } 580 581 DEVPRINTF((sc->sc_dev, "card inserted: event=0x%08x, state=%08x\n", 582 sockevent, sockstate)); 583 584 if (sockstate & PCCBB_SOCKET_STAT_16BIT && sc->sc_pccarddev != NULL) { 585 sc->sc_flags |= PCCBB_CARDATTACHED | PCCBB_16BIT_CARD; 586 if (CARD_ATTACH_CARD(sc->sc_pccarddev) != 0) { 587 device_printf(sc->sc_dev, "card activation failed\n"); 588 sc->sc_flags &= ~PCCBB_CARDATTACHED; 589 } 590 } else if (sockstate & PCCBB_SOCKET_STAT_CB && sc->sc_cbdev != NULL) { 591 sc->sc_flags |= PCCBB_CARDATTACHED; 592 sc->sc_flags &= ~PCCBB_16BIT_CARD; 593 if (CARD_ATTACH_CARD(sc->sc_cbdev) != 0) { 594 device_printf(sc->sc_dev, "card activation failed\n"); 595 sc->sc_flags &= ~PCCBB_CARDATTACHED; 596 } 597 } else { 598 device_printf (sc->sc_dev, "Unsupported card type detected\n"); 599 } 600 } 601 602 static void 603 pccbb_removal (struct pccbb_softc *sc) 604 { 605 u_int32_t sockstate; 606 struct pccbb_reslist *rle; 607 608 sockstate = sc->sc_socketreg->socket_state; 609 610 sc->sc_flags &= ~PCCBB_CARDATTACHED; 611 if (sockstate & PCCBB_16BIT_CARD) 612 CARD_DETACH_CARD(sc->sc_pccarddev, DETACH_FORCE); 613 else 614 CARD_DETACH_CARD(sc->sc_cbdev, DETACH_FORCE); 615 616 while (NULL != (rle = SLIST_FIRST(&sc->rl))) { 617 device_printf(sc->sc_dev, "WARNING: Resource left allocated! " 618 "This is a bug... (rid=%x, type=%d, addr=%x)\n", 619 rle->rid, rle->type, rle->start); 620 SLIST_REMOVE_HEAD(&sc->rl, entries); 621 } 622 } 623 624 /************************************************************************/ 625 /* Interrupt Handler */ 626 /************************************************************************/ 627 628 static void 629 pccbb_intr(void* arg) 630 { 631 struct pccbb_softc *sc = arg; 632 u_int32_t sockevent; 633 int tmp; 634 635 if (!(sockevent = sc->sc_socketreg->socket_event)) { 636 /* not for me. */ 637 return; 638 } 639 640 /* reset bit */ 641 sc->sc_socketreg->socket_event = sockevent | 0x01; 642 643 if (sockevent & PCCBB_SOCKET_EVENT_CD) { 644 for (tmp = 0; tmp <= 100 && 645 (sc->sc_flags & PCCBB_CARDSTATUS_BUSY); tmp++) { 646 if (tmp == 0) 647 DEVPRINTF((sc->sc_dev, "(pccbbintr): busy!")); 648 else 649 DPRINTF((".")); 650 DELAY(1); 651 } 652 if (sc->sc_flags & PCCBB_CARDSTATUS_BUSY) { 653 DPRINTF(("failed! Going ahead anyway...")); 654 sc->sc_flags &= ~PCCBB_CARDSTATUS_BUSY; 655 } 656 wakeup(sc); 657 } else { 658 if (sockevent & PCCBB_SOCKET_EVENT_CSTS) { 659 DPRINTF((" cstsevent occures, 0x%08x\n", 660 sc->sc_socketreg->socket_state)); 661 } 662 if (sockevent & PCCBB_SOCKET_EVENT_POWER) { 663 DPRINTF((" pwrevent occures, 0x%08x\n", 664 sc->sc_socketreg->socket_state)); 665 } 666 } 667 668 return; 669 } 670 671 /************************************************************************/ 672 /* Power functions */ 673 /************************************************************************/ 674 675 static int 676 pccbb_detect_voltage(struct pccbb_softc *sc) 677 { 678 u_int32_t psr; 679 int vol = CARD_UKN_CARD; 680 681 psr = sc->sc_socketreg->socket_state; 682 683 if (psr & PCCBB_SOCKET_STAT_5VCARD) { 684 vol |= CARD_5V_CARD; 685 } 686 if (psr & PCCBB_SOCKET_STAT_3VCARD) { 687 vol |= CARD_3V_CARD; 688 } 689 if (psr & PCCBB_SOCKET_STAT_XVCARD) { 690 vol |= CARD_XV_CARD; 691 } 692 if (psr & PCCBB_SOCKET_STAT_YVCARD) { 693 vol |= CARD_YV_CARD; 694 } 695 696 return vol; 697 } 698 699 static int 700 pccbb_power(device_t dev, int volts) 701 { 702 u_int32_t status, sock_ctrl; 703 struct pccbb_softc *sc = device_get_softc(dev); 704 705 DEVPRINTF((sc->sc_dev, "pccbb_power: %s and %s [%x]\n", 706 (volts & CARD_VCCMASK) == CARD_VCC_UC ? "CARD_VCC_UC" : 707 (volts & CARD_VCCMASK) == CARD_VCC_5V ? "CARD_VCC_5V" : 708 (volts & CARD_VCCMASK) == CARD_VCC_3V ? "CARD_VCC_3V" : 709 (volts & CARD_VCCMASK) == CARD_VCC_XV ? "CARD_VCC_XV" : 710 (volts & CARD_VCCMASK) == CARD_VCC_YV ? "CARD_VCC_YV" : 711 (volts & CARD_VCCMASK) == CARD_VCC_0V ? "CARD_VCC_0V" : 712 "VCC-UNKNOWN", 713 (volts & CARD_VPPMASK) == CARD_VPP_UC ? "CARD_VPP_UC" : 714 (volts & CARD_VPPMASK) == CARD_VPP_12V ? "CARD_VPP_12V" : 715 (volts & CARD_VPPMASK) == CARD_VPP_VCC ? "CARD_VPP_VCC" : 716 (volts & CARD_VPPMASK) == CARD_VPP_0V ? "CARD_VPP_0V" : 717 "VPP-UNKNOWN", 718 volts)); 719 720 status = sc->sc_socketreg->socket_state; 721 sock_ctrl = sc->sc_socketreg->socket_control; 722 723 switch (volts & CARD_VCCMASK) { 724 case CARD_VCC_UC: 725 break; 726 case CARD_VCC_5V: 727 if (PCCBB_SOCKET_STAT_5VCARD & status) { /* check 5 V card */ 728 sock_ctrl &= ~PCCBB_SOCKET_CTRL_VCCMASK; 729 sock_ctrl |= PCCBB_SOCKET_CTRL_VCC_5V; 730 } else { 731 device_printf(sc->sc_dev, 732 "BAD voltage request: no 5 V card\n"); 733 } 734 break; 735 case CARD_VCC_3V: 736 if (PCCBB_SOCKET_STAT_3VCARD & status) { 737 sock_ctrl &= ~PCCBB_SOCKET_CTRL_VCCMASK; 738 sock_ctrl |= PCCBB_SOCKET_CTRL_VCC_3V; 739 } else { 740 device_printf(sc->sc_dev, 741 "BAD voltage request: no 3.3 V card\n"); 742 } 743 break; 744 case CARD_VCC_0V: 745 sock_ctrl &= ~PCCBB_SOCKET_CTRL_VCCMASK; 746 break; 747 default: 748 return 0; /* power NEVER changed */ 749 break; 750 } 751 752 switch (volts & CARD_VPPMASK) { 753 case CARD_VPP_UC: 754 break; 755 case CARD_VPP_0V: 756 sock_ctrl &= ~PCCBB_SOCKET_CTRL_VPPMASK; 757 break; 758 case CARD_VPP_VCC: 759 sock_ctrl &= ~PCCBB_SOCKET_CTRL_VPPMASK; 760 sock_ctrl |= ((sock_ctrl >> 4) & 0x07); 761 break; 762 case CARD_VPP_12V: 763 sock_ctrl &= ~PCCBB_SOCKET_CTRL_VPPMASK; 764 sock_ctrl |= PCCBB_SOCKET_CTRL_VPP_12V; 765 break; 766 } 767 768 sc->sc_socketreg->socket_control = sock_ctrl; 769 status = sc->sc_socketreg->socket_state; 770 771 { 772 int timeout = 20; 773 u_int32_t sockevent; 774 do { 775 DELAY(20*1000); 776 sockevent = sc->sc_socketreg->socket_event; 777 } while (!(sockevent & PCCBB_SOCKET_EVENT_POWER) && 778 --timeout > 0); 779 /* reset event status */ 780 sc->sc_socketreg->socket_event = sockevent; 781 if ( timeout < 0 ) { 782 printf ("VCC supply failed.\n"); 783 return 0; 784 } 785 } 786 /* XXX 787 * delay 400 ms: thgough the standard defines that the Vcc set-up time 788 * is 20 ms, some PC-Card bridge requires longer duration. 789 */ 790 DELAY(400*1000); 791 792 if (status & PCCBB_SOCKET_STAT_BADVCC) { 793 device_printf(sc->sc_dev, 794 "bad Vcc request. ctrl=0x%x, status=0x%x\n", 795 sock_ctrl ,status); 796 printf("pccbb_power: %s and %s [%x]\n", 797 (volts & CARD_VCCMASK) == CARD_VCC_UC ? "CARD_VCC_UC" : 798 (volts & CARD_VCCMASK) == CARD_VCC_5V ? "CARD_VCC_5V" : 799 (volts & CARD_VCCMASK) == CARD_VCC_3V ? "CARD_VCC_3V" : 800 (volts & CARD_VCCMASK) == CARD_VCC_XV ? "CARD_VCC_XV" : 801 (volts & CARD_VCCMASK) == CARD_VCC_YV ? "CARD_VCC_YV" : 802 (volts & CARD_VCCMASK) == CARD_VCC_0V ? "CARD_VCC_0V" : 803 "VCC-UNKNOWN", 804 (volts & CARD_VPPMASK) == CARD_VPP_UC ? "CARD_VPP_UC" : 805 (volts & CARD_VPPMASK) == CARD_VPP_12V ? "CARD_VPP_12V": 806 (volts & CARD_VPPMASK) == CARD_VPP_VCC ? "CARD_VPP_VCC": 807 (volts & CARD_VPPMASK) == CARD_VPP_0V ? "CARD_VPP_0V" : 808 "VPP-UNKNOWN", 809 volts); 810 return 0; 811 } 812 return 1; /* power changed correctly */ 813 } 814 815 /************************************************************************/ 816 /* PCCBB methods */ 817 /************************************************************************/ 818 819 static int 820 pccbb_cardbus_detect_card(device_t dev) 821 { 822 struct pccbb_softc *sc = device_get_softc(dev); 823 u_int32_t sockstat = sc->sc_socketreg->socket_state; 824 825 if (sockstat & PCCBB_SOCKET_STAT_CB) 826 return pccbb_detect_voltage(sc); 827 return 0; 828 } 829 830 static int 831 pccbb_cardbus_reset(device_t dev) 832 { 833 struct pccbb_softc *sc = device_get_softc(dev); 834 u_int32_t bcr = pci_read_config(dev, PCCBBR_BRIDGECTRL, 2); 835 int delay_us; 836 837 delay_us = sc->sc_chipset == CB_RF5C47X ? 400*1000 : 20*1000; 838 839 bcr |= PCCBBM_BRIDGECTRL_RESET; 840 pci_write_config(dev, PCCBBR_BRIDGECTRL, bcr, 2); 841 842 DELAY(delay_us); 843 844 /* If a card exists, unreset it! */ 845 if (sc->sc_flags & PCCBB_CARDATTACHED) { 846 bcr &= ~PCCBBM_BRIDGECTRL_RESET; 847 pci_write_config(dev, PCCBBR_BRIDGECTRL, bcr, 2); 848 DELAY(delay_us); 849 } 850 return 1; 851 } 852 853 854 /************************************************************************/ 855 /* Cardbus Resource */ 856 /************************************************************************/ 857 858 static int 859 pccbb_cardbus_io_open(device_t dev, int win, u_int32_t start, u_int32_t end) 860 { 861 int basereg; 862 int limitreg; 863 864 if ((win < 0) || (win > 1)) { 865 DEVPRINTF((dev, 866 "pccbb_cardbus_io_open: window out of range %d\n", 867 win)); 868 return EINVAL; 869 } 870 871 basereg = win*8 + PCCBBR_IOBASE0; 872 limitreg = win*8 + PCCBBR_IOLIMIT0; 873 874 pci_write_config(dev, basereg, start, 4); 875 pci_write_config(dev, limitreg, end, 4); 876 return 0; 877 } 878 879 static int 880 pccbb_cardbus_mem_open(device_t dev, int win, u_int32_t start, u_int32_t end) 881 { 882 int basereg; 883 int limitreg; 884 885 if ((win < 0) || (win > 1)) { 886 DEVPRINTF((dev, 887 "pccbb_cardbus_mem_open: window out of range %d\n", 888 win)); 889 return EINVAL; 890 } 891 892 basereg = win*8 + PCCBBR_MEMBASE0; 893 limitreg = win*8 + PCCBBR_MEMLIMIT0; 894 895 pci_write_config(dev, basereg, start, 4); 896 pci_write_config(dev, limitreg, end, 4); 897 return 0; 898 } 899 900 static void 901 pccbb_cardbus_auto_open(struct pccbb_softc *sc, int type) 902 { 903 u_int32_t starts[2]; 904 u_int32_t ends[2]; 905 struct pccbb_reslist *rle; 906 int align; 907 908 starts[0] = starts[1] = 0xffffffff; 909 ends[0] = ends[1] = 0; 910 911 SLIST_FOREACH(rle, &sc->rl, entries) { 912 if (rle->type != type) 913 ; 914 else if (starts[0] == 0xffffffff) { 915 starts[0] = rle->start; 916 ends[0] = rle->end; 917 rle->win = 0; 918 } else if (rle->end > ends[0] && 919 rle->start - ends[0] < PCCBB_AUTO_OPEN_SMALLHOLE) { 920 ends[0] = rle->end; 921 rle->win = 0; 922 } else if (rle->start < starts[0] && 923 starts[0] - rle->end < PCCBB_AUTO_OPEN_SMALLHOLE) { 924 starts[0] = rle->start; 925 rle->win = 0; 926 } else if (starts[1] == 0xffffffff) { 927 starts[1] = rle->start; 928 ends[1] = rle->end; 929 rle->win = 1; 930 } else if (rle->end > ends[1] && 931 rle->start - ends[1] < PCCBB_AUTO_OPEN_SMALLHOLE) { 932 ends[1] = rle->end; 933 rle->win = 1; 934 } else if (rle->start < starts[1] && 935 starts[1] - rle->end < PCCBB_AUTO_OPEN_SMALLHOLE) { 936 starts[1] = rle->start; 937 rle->win = 1; 938 } else { 939 u_int32_t diffs[2]; 940 941 diffs[0] = diffs[1] = 0xffffffff; 942 if (rle->start > ends[0]) 943 diffs[0] = rle->start - ends[0]; 944 else if (rle->end < starts[0]) 945 diffs[0] = starts[0] - rle->end; 946 if (rle->start > ends[1]) 947 diffs[1] = rle->start - ends[1]; 948 else if (rle->end < starts[1]) 949 diffs[1] = starts[1] - rle->end; 950 951 rle->win = (diffs[0] <= diffs[1])?0:1; 952 if (rle->start > ends[rle->win]) 953 ends[rle->win] = rle->end; 954 else if (rle->end < starts[rle->win]) 955 starts[rle->win] = rle->start; 956 else 957 panic("pccbb_auto_open: Weird condition!\n"); 958 } 959 } 960 961 if (type == SYS_RES_MEMORY) 962 align = PCCBB_MEMALIGN; 963 else if (type == SYS_RES_IOPORT) 964 align = PCCBB_IOALIGN; 965 else 966 align = 1; 967 968 if (starts[0] != 0xffffffff) 969 starts[0] -= starts[0] % align; 970 if (starts[1] != 0xffffffff) 971 starts[1] -= starts[1] % align; 972 if (ends[0] % align != 0) 973 ends[0] += align - ends[0]%align; 974 if (ends[1] % align != 0) 975 ends[1] += align - ends[1]%align; 976 977 if (type == SYS_RES_MEMORY) { 978 pccbb_cardbus_mem_open(sc->sc_dev, 0, starts[0], ends[0]); 979 pccbb_cardbus_mem_open(sc->sc_dev, 1, starts[1], ends[1]); 980 } else if (type == SYS_RES_IOPORT) { 981 pccbb_cardbus_io_open(sc->sc_dev, 0, starts[0], ends[0]); 982 pccbb_cardbus_io_open(sc->sc_dev, 1, starts[1], ends[1]); 983 } 984 } 985 986 static int 987 pccbb_cardbus_activate_resource(device_t self, device_t child, int type, 988 int rid, struct resource *r) 989 { 990 struct pccbb_softc *sc = device_get_softc(self); 991 struct pccbb_reslist *rle; 992 993 if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { 994 SLIST_FOREACH(rle, &sc->rl, entries) { 995 if (type == rle->type && rid == rle->rid && 996 child == rle->odev) 997 return bus_generic_activate_resource( 998 self, child, type, rid, r); 999 } 1000 rle = malloc(sizeof(struct pccbb_reslist), M_DEVBUF, M_WAITOK); 1001 rle->type = type; 1002 rle->rid = rid; 1003 rle->start = rman_get_start(r); 1004 rle->end = rman_get_end(r); 1005 rle->odev = child; 1006 rle->win = -1; 1007 SLIST_INSERT_HEAD(&sc->rl, rle, entries); 1008 1009 pccbb_cardbus_auto_open(sc, type); 1010 } 1011 1012 return bus_generic_activate_resource(self, child, type, rid, r); 1013 } 1014 1015 static int 1016 pccbb_cardbus_deactivate_resource(device_t self, device_t child, int type, 1017 int rid, struct resource *r) 1018 { 1019 struct pccbb_softc *sc = device_get_softc(self); 1020 struct pccbb_reslist *rle; 1021 1022 SLIST_FOREACH(rle, &sc->rl, entries) { 1023 if (type == rle->type && rid == rle->rid && 1024 child == rle->odev) { 1025 SLIST_REMOVE(&sc->rl, rle, pccbb_reslist, entries); 1026 if (type == SYS_RES_IOPORT || 1027 type == SYS_RES_MEMORY) 1028 pccbb_cardbus_auto_open(sc, type); 1029 free(rle, M_DEVBUF); 1030 break; 1031 } 1032 } 1033 return bus_generic_deactivate_resource(self, child, type, rid, r); 1034 } 1035 1036 static struct resource* 1037 pccbb_cardbus_alloc_resource(device_t self, device_t child, int type, int* rid, 1038 u_long start, u_long end, u_long count, 1039 u_int flags) 1040 { 1041 if (type == SYS_RES_IRQ) { 1042 struct pccbb_softc *sc = device_get_softc(self); 1043 if (start == 0) { 1044 start = end = rman_get_start(sc->sc_irq_res); 1045 } 1046 return bus_generic_alloc_resource(self, child, type, rid, 1047 start, end, count, flags); 1048 } else { 1049 if (type == SYS_RES_MEMORY && start == 0 && end == ~0) { 1050 start = CARDBUS_SYS_RES_MEMORY_START; 1051 end = CARDBUS_SYS_RES_MEMORY_END; 1052 } else if (type == SYS_RES_IOPORT && start == 0 && end == ~0) { 1053 start = CARDBUS_SYS_RES_IOPORT_START; 1054 end = CARDBUS_SYS_RES_IOPORT_END; 1055 } 1056 return bus_generic_alloc_resource(self, child, type, rid, 1057 start, end, count, flags); 1058 } 1059 } 1060 1061 static int 1062 pccbb_cardbus_release_resource(device_t self, device_t child, int type, 1063 int rid, struct resource *r) 1064 { 1065 return bus_generic_release_resource(self, child, type, rid, r); 1066 } 1067 1068 /************************************************************************/ 1069 /* PC Card Resources */ 1070 /************************************************************************/ 1071 1072 static void 1073 pccbb_pcic_wait_ready(struct pccbb_softc *sc) 1074 { 1075 int i; 1076 DEVPRINTF((sc->sc_dev, "pccbb_pcic_wait_ready: status 0x%02x\n", 1077 PCIC_READ(sc, PCIC_IF_STATUS))); 1078 for (i = 0; i < 10000; i++) { 1079 if (PCIC_READ(sc, PCIC_IF_STATUS) & PCIC_IF_STATUS_READY) { 1080 return; 1081 } 1082 DELAY(500); 1083 } 1084 device_printf(sc->sc_dev, "ready never happened, status = %02x\n", 1085 PCIC_READ(sc, PCIC_IF_STATUS)); 1086 } 1087 1088 #define PCIC_MEMINFO(NUM) { \ 1089 PCIC_SYSMEM_ADDR ## NUM ## _START_LSB, \ 1090 PCIC_SYSMEM_ADDR ## NUM ## _START_MSB, \ 1091 PCIC_SYSMEM_ADDR ## NUM ## _STOP_LSB, \ 1092 PCIC_SYSMEM_ADDR ## NUM ## _STOP_MSB, \ 1093 PCIC_CARDMEM_ADDR ## NUM ## _LSB, \ 1094 PCIC_CARDMEM_ADDR ## NUM ## _MSB, \ 1095 PCIC_ADDRWIN_ENABLE_MEM ## NUM ## , \ 1096 } 1097 1098 static struct mem_map_index_st { 1099 int sysmem_start_lsb; 1100 int sysmem_start_msb; 1101 int sysmem_stop_lsb; 1102 int sysmem_stop_msb; 1103 int cardmem_lsb; 1104 int cardmem_msb; 1105 int memenable; 1106 } mem_map_index[] = { 1107 PCIC_MEMINFO(0), 1108 PCIC_MEMINFO(1), 1109 PCIC_MEMINFO(2), 1110 PCIC_MEMINFO(3), 1111 PCIC_MEMINFO(4), 1112 }; 1113 #undef PCIC_MEMINFO 1114 1115 static void 1116 pccbb_pcic_do_mem_map(struct pccbb_softc *sc, int win) 1117 { 1118 PCIC_WRITE(sc, mem_map_index[win].sysmem_start_lsb, 1119 (sc->mem[win].addr >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff); 1120 PCIC_WRITE(sc, mem_map_index[win].sysmem_start_msb, 1121 ((sc->mem[win].addr >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) & 1122 PCIC_SYSMEM_ADDRX_START_MSB_ADDR_MASK)); 1123 1124 PCIC_WRITE(sc, mem_map_index[win].sysmem_stop_lsb, 1125 ((sc->mem[win].addr + sc->mem[win].realsize - 1) >> 1126 PCIC_SYSMEM_ADDRX_SHIFT) & 0xff); 1127 PCIC_WRITE(sc, mem_map_index[win].sysmem_stop_msb, 1128 (((sc->mem[win].addr + sc->mem[win].realsize - 1) >> 1129 (PCIC_SYSMEM_ADDRX_SHIFT + 8)) & 1130 PCIC_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) | 1131 PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2); 1132 1133 PCIC_WRITE(sc, mem_map_index[win].cardmem_lsb, 1134 (sc->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff); 1135 PCIC_WRITE(sc, mem_map_index[win].cardmem_msb, 1136 ((sc->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8)) & 1137 PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK) | 1138 ((sc->mem[win].kind == PCCARD_MEM_ATTR) ? 1139 PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0)); 1140 1141 PCIC_MASK(sc, PCIC_ADDRWIN_ENABLE, | PCIC_ADDRWIN_ENABLE_MEMCS16 1142 | mem_map_index[win].memenable); 1143 1144 DELAY(100); 1145 1146 #ifdef CBB_DEBUG 1147 { 1148 int r1, r2, r3, r4, r5, r6; 1149 r1 = PCIC_READ(sc, mem_map_index[win].sysmem_start_msb); 1150 r2 = PCIC_READ(sc, mem_map_index[win].sysmem_start_lsb); 1151 r3 = PCIC_READ(sc, mem_map_index[win].sysmem_stop_msb); 1152 r4 = PCIC_READ(sc, mem_map_index[win].sysmem_stop_lsb); 1153 r5 = PCIC_READ(sc, mem_map_index[win].cardmem_msb); 1154 r6 = PCIC_READ(sc, mem_map_index[win].cardmem_lsb); 1155 DPRINTF(("pccbb_pcic_do_mem_map window %d: %02x%02x %02x%02x " 1156 "%02x%02x\n", win, r1, r2, r3, r4, r5, r6)); 1157 } 1158 #endif 1159 } 1160 1161 static int 1162 pccbb_pcic_mem_map(struct pccbb_softc *sc, int kind, 1163 struct resource *r, bus_addr_t card_addr, int *win) 1164 { 1165 int i; 1166 1167 *win = -1; 1168 for (i = 0; i < PCIC_MEM_WINS; i++) { 1169 if ((sc->memalloc & (1 << i)) == 0) { 1170 *win = i; 1171 sc->memalloc |= (1 << i); 1172 break; 1173 } 1174 } 1175 if (*win == -1) 1176 return (1); 1177 1178 card_addr = card_addr - card_addr % PCIC_MEM_PAGESIZE; 1179 1180 sc->mem[*win].memt = rman_get_bustag(r); 1181 sc->mem[*win].memh = rman_get_bushandle(r); 1182 sc->mem[*win].addr = rman_get_start(r); 1183 sc->mem[*win].size = rman_get_end(r) - sc->mem[*win].addr + 1; 1184 sc->mem[*win].realsize = sc->mem[*win].size + PCIC_MEM_PAGESIZE - 1; 1185 sc->mem[*win].realsize = sc->mem[*win].realsize - 1186 (sc->mem[*win].realsize % PCIC_MEM_PAGESIZE); 1187 sc->mem[*win].offset = ((long)card_addr) - 1188 ((long)(sc->mem[*win].addr)); 1189 sc->mem[*win].kind = kind; 1190 1191 DPRINTF(("pccbb_pcic_mem_map window %d bus %x+%x+%lx card addr %x\n", 1192 *win, sc->mem[*win].addr, sc->mem[*win].size, 1193 sc->mem[*win].offset, card_addr)); 1194 1195 pccbb_pcic_do_mem_map(sc, *win); 1196 1197 return (0); 1198 } 1199 1200 static void 1201 pccbb_pcic_mem_unmap(struct pccbb_softc *sc, int window) 1202 { 1203 if (window >= PCIC_MEM_WINS) 1204 panic("pccbb_pcic_mem_unmap: window out of range"); 1205 1206 PCIC_MASK(sc, PCIC_ADDRWIN_ENABLE, & ~mem_map_index[window].memenable); 1207 1208 sc->memalloc &= ~(1 << window); 1209 } 1210 1211 #define PCIC_IOINFO(NUM) { \ 1212 PCIC_IOADDR ## NUM ## _START_LSB, \ 1213 PCIC_IOADDR ## NUM ## _START_MSB, \ 1214 PCIC_IOADDR ## NUM ## _STOP_LSB, \ 1215 PCIC_IOADDR ## NUM ## _STOP_MSB, \ 1216 PCIC_ADDRWIN_ENABLE_IO ## NUM ## , \ 1217 PCIC_IOCTL_IO ## NUM ## _WAITSTATE \ 1218 | PCIC_IOCTL_IO ## NUM ## _ZEROWAIT \ 1219 | PCIC_IOCTL_IO ## NUM ## _IOCS16SRC_MASK \ 1220 | PCIC_IOCTL_IO ## NUM ## _DATASIZE_MASK, \ 1221 { \ 1222 PCIC_IOCTL_IO ## NUM ## _IOCS16SRC_CARD, \ 1223 PCIC_IOCTL_IO ## NUM ## _IOCS16SRC_DATASIZE \ 1224 | PCIC_IOCTL_IO ## NUM ## _DATASIZE_8BIT, \ 1225 PCIC_IOCTL_IO ## NUM ## _IOCS16SRC_DATASIZE \ 1226 | PCIC_IOCTL_IO ## NUM ## _DATASIZE_16BIT, \ 1227 } \ 1228 } 1229 1230 static struct io_map_index_st { 1231 int start_lsb; 1232 int start_msb; 1233 int stop_lsb; 1234 int stop_msb; 1235 int ioenable; 1236 int ioctlmask; 1237 int ioctlbits[3]; /* indexed by PCCARD_WIDTH_* */ 1238 } io_map_index[] = { 1239 PCIC_IOINFO(0), 1240 PCIC_IOINFO(1), 1241 }; 1242 #undef PCIC_IOINFO 1243 1244 static void pccbb_pcic_do_io_map(struct pccbb_softc *sc, int win) 1245 { 1246 PCIC_WRITE(sc, io_map_index[win].start_lsb, sc->io[win].addr & 0xff); 1247 PCIC_WRITE(sc, io_map_index[win].start_msb, 1248 (sc->io[win].addr >> 8) & 0xff); 1249 1250 PCIC_WRITE(sc, io_map_index[win].stop_lsb, 1251 (sc->io[win].addr + sc->io[win].size - 1) & 0xff); 1252 PCIC_WRITE(sc, io_map_index[win].stop_msb, 1253 ((sc->io[win].addr + sc->io[win].size - 1) >> 8) & 0xff); 1254 1255 PCIC_MASK2(sc, PCIC_IOCTL, 1256 & ~io_map_index[win].ioctlmask, 1257 | io_map_index[win].ioctlbits[sc->io[win].width]); 1258 1259 PCIC_MASK(sc, PCIC_ADDRWIN_ENABLE, | io_map_index[win].ioenable); 1260 } 1261 1262 static int 1263 pccbb_pcic_io_map(struct pccbb_softc *sc, int width, 1264 struct resource *r, bus_addr_t card_addr, int *win) 1265 { 1266 int i; 1267 #ifdef CBB_DEBUG 1268 static char *width_names[] = { "auto", "io8", "io16"}; 1269 #endif 1270 1271 *win = -1; 1272 for (i=0; i < PCIC_IO_WINS; i++) { 1273 if ((sc->ioalloc & (1 << i)) == 0) { 1274 *win = i; 1275 sc->ioalloc |= (1 << i); 1276 break; 1277 } 1278 } 1279 if (*win == -1) 1280 return (1); 1281 1282 sc->io[*win].iot = rman_get_bustag(r); 1283 sc->io[*win].ioh = rman_get_bushandle(r); 1284 sc->io[*win].addr = rman_get_start(r); 1285 sc->io[*win].size = rman_get_end(r) - sc->io[*win].addr + 1; 1286 sc->io[*win].flags = 0; 1287 sc->io[*win].width = width; 1288 1289 DPRINTF(("pccbb_pcic_io_map window %d %s port %x+%x\n", 1290 *win, width_names[width], sc->io[*win].addr, 1291 sc->io[*win].size)); 1292 1293 pccbb_pcic_do_io_map(sc, *win); 1294 1295 return (0); 1296 } 1297 1298 static void 1299 pccbb_pcic_io_unmap(struct pccbb_softc *sc, int window) 1300 { 1301 if (window >= PCIC_IO_WINS) 1302 panic("pccbb_pcic_io_unmap: window out of range"); 1303 1304 PCIC_MASK(sc, PCIC_ADDRWIN_ENABLE, & ~io_map_index[window].ioenable); 1305 1306 sc->ioalloc &= ~(1 << window); 1307 1308 sc->io[window].iot = 0; 1309 sc->io[window].ioh = 0; 1310 sc->io[window].addr = 0; 1311 sc->io[window].size = 0; 1312 sc->io[window].flags = 0; 1313 sc->io[window].width = 0; 1314 } 1315 1316 static int 1317 pccbb_pcic_activate_resource(device_t self, device_t child, int type, int rid, 1318 struct resource *r) 1319 { 1320 int err; 1321 int win; 1322 struct pccbb_reslist *rle; 1323 struct pccbb_softc *sc = device_get_softc(self); 1324 1325 switch (type) { 1326 case SYS_RES_IOPORT: 1327 err = pccbb_pcic_io_map(sc, 0, r, 0, &win); 1328 if (err) 1329 return err; 1330 break; 1331 case SYS_RES_MEMORY: 1332 err = pccbb_pcic_mem_map(sc, 0, r, 0, &win); 1333 if (err) 1334 return err; 1335 break; 1336 default: 1337 break; 1338 } 1339 SLIST_FOREACH(rle, &sc->rl, entries) { 1340 if (type == rle->type && rid == rle->rid && 1341 child == rle->odev) { 1342 rle->win = win; 1343 break; 1344 } 1345 } 1346 err = bus_generic_activate_resource(self, child, type, rid, r); 1347 return (err); 1348 } 1349 1350 static int 1351 pccbb_pcic_deactivate_resource(device_t self, device_t child, int type, 1352 int rid, struct resource *r) 1353 { 1354 struct pccbb_softc *sc = device_get_softc(self); 1355 int win; 1356 struct pccbb_reslist *rle; 1357 1358 win = -1; 1359 SLIST_FOREACH(rle, &sc->rl, entries) { 1360 if (type == rle->type && rid == rle->rid && 1361 child == rle->odev) { 1362 win = rle->win; 1363 break; 1364 } 1365 } 1366 if (win == -1) 1367 return 1; 1368 1369 switch (type) { 1370 case SYS_RES_IOPORT: 1371 pccbb_pcic_io_unmap(sc, win); 1372 break; 1373 case SYS_RES_MEMORY: 1374 pccbb_pcic_mem_unmap(sc, win); 1375 break; 1376 default: 1377 break; 1378 } 1379 return bus_generic_deactivate_resource(self, child, type, rid, r); 1380 } 1381 1382 static struct resource* 1383 pccbb_pcic_alloc_resource(device_t self, device_t child, int type, int* rid, 1384 u_long start, u_long end, u_long count, u_int flags) 1385 { 1386 struct resource *r = NULL; 1387 struct pccbb_softc *sc = device_get_softc(self); 1388 struct pccbb_reslist *rle; 1389 1390 switch (type) { 1391 case SYS_RES_MEMORY: 1392 /* Nearly default */ 1393 if (start == 0 && end == ~0 && count != 1) { 1394 start = 0xd0000; /* XXX -- should be tweakable*/ 1395 end = 0xdffff; 1396 } 1397 flags = (flags & ~RF_ALIGNMENT_MASK) 1398 | rman_make_alignment_flags(PCCBB_MEMALIGN); 1399 break; 1400 case SYS_RES_IOPORT: 1401 if (start < 0x100) 1402 start = 0x100; /* XXX tweakable? */ 1403 if (end < start) 1404 end = start; 1405 break; 1406 case SYS_RES_IRQ: 1407 flags |= RF_SHAREABLE; 1408 start = end = rman_get_start(sc->sc_irq_res); 1409 break; 1410 } 1411 r = bus_generic_alloc_resource(self, child, type, rid, start, end, 1412 count, flags & ~RF_ACTIVE); 1413 if (r == NULL) 1414 return NULL; 1415 1416 rle = malloc(sizeof(struct pccbb_reslist), M_DEVBUF, M_WAITOK); 1417 rle->type = type; 1418 rle->rid = *rid; 1419 rle->start = rman_get_start(r); 1420 rle->end = rman_get_end(r); 1421 rle->odev = child; 1422 rle->win = -1; 1423 SLIST_INSERT_HEAD(&sc->rl, rle, entries); 1424 1425 if (flags & RF_ACTIVE) { 1426 if (bus_activate_resource(child, type, *rid, r) != 0) { 1427 BUS_RELEASE_RESOURCE(self, child, type, *rid, r); 1428 return NULL; 1429 } 1430 } 1431 1432 return r; 1433 } 1434 1435 static int 1436 pccbb_pcic_release_resource(device_t self, device_t child, int type, 1437 int rid, struct resource *res) 1438 { 1439 struct pccbb_softc *sc = device_get_softc(self); 1440 struct pccbb_reslist *rle; 1441 1442 SLIST_FOREACH(rle, &sc->rl, entries) { 1443 if (type == rle->type && rid == rle->rid && 1444 child == rle->odev) { 1445 SLIST_REMOVE(&sc->rl, rle, pccbb_reslist, entries); 1446 free(rle, M_DEVBUF); 1447 break; 1448 } 1449 } 1450 1451 return bus_generic_release_resource(self, child, type, rid, res); 1452 } 1453 1454 /************************************************************************/ 1455 /* PC Card methods */ 1456 /************************************************************************/ 1457 1458 static int 1459 pccbb_pcic_set_res_flags(device_t self, device_t child, int type, int rid, 1460 u_int32_t flags) 1461 { 1462 struct pccbb_softc *sc = device_get_softc(self); 1463 1464 if (type != SYS_RES_MEMORY) 1465 return (EINVAL); 1466 sc->mem[rid].kind = PCCARD_MEM_ATTR; 1467 pccbb_pcic_do_mem_map(sc, rid); 1468 return 0; 1469 } 1470 1471 static int 1472 pccbb_pcic_set_memory_offset(device_t self, device_t child, int rid, 1473 u_int32_t offset) 1474 { 1475 struct pccbb_softc *sc = device_get_softc(self); 1476 int win; 1477 struct pccbb_reslist *rle; 1478 1479 win = -1; 1480 SLIST_FOREACH(rle, &sc->rl, entries) { 1481 if (SYS_RES_MEMORY == rle->type && rid == rle->rid && 1482 child == rle->odev) { 1483 win = rle->win; 1484 break; 1485 } 1486 } 1487 if (win == -1) 1488 return 1; 1489 1490 offset = offset - offset % PCIC_MEM_PAGESIZE; 1491 sc->mem[win].offset = ((long)offset) - 1492 ((long)(sc->mem[win].addr)); 1493 1494 pccbb_pcic_do_mem_map(sc, win); 1495 1496 return 0; 1497 } 1498 1499 static int 1500 pccbb_pcic_enable_socket(device_t self, device_t child) 1501 { 1502 struct pccbb_softc *sc = device_get_softc(self); 1503 1504 DPRINTF(("pccbb_pcic_socket_enable:\n")); 1505 1506 /* power down/up the socket to reset */ 1507 { 1508 int voltage = pccbb_detect_voltage(sc); 1509 1510 pccbb_power(self, CARD_VCC_0V | CARD_VPP_0V); 1511 if (voltage & CARD_5V_CARD) 1512 pccbb_power(self, CARD_VCC_5V | CARD_VPP_VCC); 1513 else if (voltage & CARD_3V_CARD) 1514 pccbb_power(self, CARD_VCC_3V | CARD_VPP_VCC); 1515 else { 1516 device_printf(self, "Unknown card voltage\n"); 1517 return ENXIO; 1518 } 1519 } 1520 1521 /* enable socket i/o */ 1522 PCIC_MASK(sc, PCIC_PWRCTL, | PCIC_PWRCTL_OE); 1523 1524 PCIC_WRITE(sc, PCIC_INTR, PCIC_INTR_ENABLE); 1525 /* hold reset for 30ms */ 1526 DELAY(30*1000); 1527 /* clear the reset flag */ 1528 PCIC_MASK(sc, PCIC_INTR, | PCIC_INTR_RESET); 1529 /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */ 1530 DELAY(20*1000); 1531 1532 pccbb_pcic_wait_ready(sc); 1533 1534 /* disable all address windows */ 1535 PCIC_WRITE(sc, PCIC_ADDRWIN_ENABLE, 0); 1536 1537 { 1538 int cardtype; 1539 CARD_GET_TYPE(child, &cardtype); 1540 PCIC_MASK(sc, PCIC_INTR, | ((cardtype == PCCARD_IFTYPE_IO) ? 1541 PCIC_INTR_CARDTYPE_IO : 1542 PCIC_INTR_CARDTYPE_MEM)); 1543 DEVPRINTF((sc->sc_dev, "card type is %s\n", 1544 (cardtype == PCCARD_IFTYPE_IO) ? "io" : "mem")); 1545 } 1546 1547 /* reinstall all the memory and io mappings */ 1548 { 1549 int win; 1550 1551 for (win = 0; win < PCIC_MEM_WINS; ++win) { 1552 if (sc->memalloc & (1 << win)) { 1553 pccbb_pcic_do_mem_map(sc, win); 1554 } 1555 } 1556 for (win = 0; win < PCIC_IO_WINS; ++win) { 1557 if (sc->ioalloc & (1 << win)) { 1558 pccbb_pcic_do_io_map(sc, win); 1559 } 1560 } 1561 } 1562 return 0; 1563 } 1564 1565 static void 1566 pccbb_pcic_disable_socket(device_t self, device_t child) 1567 { 1568 struct pccbb_softc *sc = device_get_softc(self); 1569 1570 DPRINTF(("pccbb_pcic_socket_disable\n")); 1571 1572 /* reset signal asserting... */ 1573 PCIC_MASK(sc, PCIC_INTR, & ~PCIC_INTR_RESET); 1574 DELAY(2*1000); 1575 1576 /* power down the socket */ 1577 PCIC_MASK(sc, PCIC_PWRCTL, &~PCIC_PWRCTL_OE); 1578 pccbb_power(self, CARD_VCC_0V | CARD_VPP_0V); 1579 1580 /* wait 300ms until power fails (Tpf). */ 1581 DELAY(300 * 1000); 1582 } 1583 1584 /************************************************************************/ 1585 /* Methods */ 1586 /************************************************************************/ 1587 1588 1589 static int 1590 pccbb_activate_resource(device_t self, device_t child, int type, int rid, 1591 struct resource *r) 1592 { 1593 struct pccbb_softc *sc = device_get_softc(self); 1594 1595 if (sc->sc_flags & PCCBB_16BIT_CARD) 1596 return pccbb_pcic_activate_resource(self, child, type, rid, r); 1597 else 1598 return pccbb_cardbus_activate_resource(self, child, type, rid, 1599 r); 1600 } 1601 1602 static int 1603 pccbb_deactivate_resource(device_t self, device_t child, int type, 1604 int rid, struct resource *r) 1605 { 1606 struct pccbb_softc *sc = device_get_softc(self); 1607 1608 if (sc->sc_flags & PCCBB_16BIT_CARD) 1609 return pccbb_pcic_deactivate_resource(self, child, type, 1610 rid, r); 1611 else 1612 return pccbb_cardbus_deactivate_resource(self, child, type, 1613 rid, r); 1614 } 1615 1616 static struct resource* 1617 pccbb_alloc_resource(device_t self, device_t child, int type, int* rid, 1618 u_long start, u_long end, u_long count, u_int flags) 1619 { 1620 struct pccbb_softc *sc = device_get_softc(self); 1621 1622 if (sc->sc_flags & PCCBB_16BIT_CARD) 1623 return pccbb_pcic_alloc_resource(self, child, type, rid, 1624 start, end, count, flags); 1625 else 1626 return pccbb_cardbus_alloc_resource(self, child, type, rid, 1627 start, end, count, flags); 1628 } 1629 1630 static int 1631 pccbb_release_resource(device_t self, device_t child, int type, int rid, 1632 struct resource *r) 1633 { 1634 struct pccbb_softc *sc = device_get_softc(self); 1635 1636 if (sc->sc_flags & PCCBB_16BIT_CARD) 1637 return pccbb_pcic_release_resource(self, child, type, 1638 rid, r); 1639 else 1640 return pccbb_cardbus_release_resource(self, child, type, 1641 rid, r); 1642 } 1643 1644 static int 1645 pccbb_maxslots(device_t dev) 1646 { 1647 return 0; 1648 } 1649 1650 static u_int32_t 1651 pccbb_read_config(device_t dev, int b, int s, int f, 1652 int reg, int width) 1653 { 1654 /* 1655 * Pass through to the next ppb up the chain (i.e. our grandparent). 1656 */ 1657 return PCIB_READ_CONFIG(device_get_parent(device_get_parent(dev)), 1658 b, s, f, reg, width); 1659 } 1660 1661 static void 1662 pccbb_write_config(device_t dev, int b, int s, int f, 1663 int reg, u_int32_t val, int width) 1664 { 1665 /* 1666 * Pass through to the next ppb up the chain (i.e. our grandparent). 1667 */ 1668 PCIB_WRITE_CONFIG(device_get_parent(device_get_parent(dev)), 1669 b, s, f, reg, val, width); 1670 } 1671 1672 static device_method_t pccbb_methods[] = { 1673 /* Device interface */ 1674 DEVMETHOD(device_probe, pccbb_probe), 1675 DEVMETHOD(device_attach, pccbb_attach), 1676 DEVMETHOD(device_detach, bus_generic_detach), 1677 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1678 DEVMETHOD(device_suspend, bus_generic_suspend), 1679 DEVMETHOD(device_resume, bus_generic_resume), 1680 1681 /* bus methods */ 1682 DEVMETHOD(bus_print_child, bus_generic_print_child), 1683 DEVMETHOD(bus_alloc_resource, pccbb_alloc_resource), 1684 DEVMETHOD(bus_release_resource, pccbb_release_resource), 1685 DEVMETHOD(bus_activate_resource, pccbb_activate_resource), 1686 DEVMETHOD(bus_deactivate_resource, pccbb_deactivate_resource), 1687 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 1688 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 1689 1690 /* pcib compatibility interface */ 1691 DEVMETHOD(pcib_maxslots, pccbb_maxslots), 1692 DEVMETHOD(pcib_read_config, pccbb_read_config), 1693 DEVMETHOD(pcib_write_config, pccbb_write_config), 1694 1695 DEVMETHOD(pccbb_power_socket, pccbb_power), 1696 DEVMETHOD(pccbb_detect_card, pccbb_cardbus_detect_card), 1697 DEVMETHOD(pccbb_reset, pccbb_cardbus_reset), 1698 1699 DEVMETHOD(card_set_res_flags, pccbb_pcic_set_res_flags), 1700 DEVMETHOD(card_set_memory_offset, pccbb_pcic_set_memory_offset), 1701 1702 DEVMETHOD(power_enable_socket, pccbb_pcic_enable_socket), 1703 DEVMETHOD(power_disable_socket, pccbb_pcic_disable_socket), 1704 1705 {0,0} 1706 }; 1707 1708 static driver_t pccbb_driver = { 1709 "pccbb", 1710 pccbb_methods, 1711 sizeof(struct pccbb_softc) 1712 }; 1713 static devclass_t pccbb_devclass = { 1714 }; 1715 DRIVER_MODULE(pccbb, pci, pccbb_driver, pccbb_devclass, 0, 0); 1716 1717 1718 SYSINIT(pccbb, SI_SUB_KTHREAD_IDLE, SI_ORDER_ANY, pccbb_start_threads, 0); 1719