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 * 38 * Written by Jonathan Chen <jon@freebsd.org> 39 * The author would like to acknowledge: 40 * * HAYAKAWA Koichi: Author of the NetBSD code for the same thing 41 * * Warner Losh: Newbus/newcard guru and author of the pccard side of things 42 * * YAMAMOTO Shigeru: Author of another FreeBSD cardbus driver 43 * * David Cross: Author of the initial ugly hack for a specific cardbus card 44 */ 45 46 #include <sys/param.h> 47 #include <sys/systm.h> 48 #include <sys/errno.h> 49 #include <sys/kernel.h> 50 #include <sys/kthread.h> 51 #include <sys/lock.h> 52 #include <sys/malloc.h> 53 #include <sys/mutex.h> 54 #include <sys/sysctl.h> 55 56 #include <sys/bus.h> 57 #include <machine/bus.h> 58 #include <sys/rman.h> 59 #include <machine/resource.h> 60 61 #include <pci/pcireg.h> 62 #include <pci/pcivar.h> 63 #include <machine/clock.h> 64 65 #include <dev/pccard/pccardreg.h> 66 #include <dev/pccard/pccardvar.h> 67 68 #include <dev/exca/excareg.h> 69 #include <dev/exca/excavar.h> 70 71 #include <dev/pccbb/pccbbreg.h> 72 #include <dev/pccbb/pccbbvar.h> 73 74 #include "power_if.h" 75 #include "card_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 PCCBB_START_MEM 0x84000000 93 #define PCCBB_START_IO 0x1000 94 95 struct pccbb_sclist { 96 struct pccbb_softc *sc; 97 STAILQ_ENTRY(pccbb_sclist) entries; 98 }; 99 100 static STAILQ_HEAD(, pccbb_sclist) softcs; 101 static int softcs_init = 0; 102 103 struct yenta_chipinfo { 104 uint32_t yc_id; 105 const char *yc_name; 106 int yc_chiptype; 107 int yc_flags; 108 } yc_chipsets[] = { 109 /* Texas Instruments chips */ 110 {PCI_DEVICE_ID_PCIC_TI1031, "TI1031 PCI-PCCard Bridge", CB_TI113X, 0}, 111 {PCI_DEVICE_ID_PCIC_TI1130, "TI1130 PCI-CardBus Bridge", CB_TI113X, 0}, 112 {PCI_DEVICE_ID_PCIC_TI1131, "TI1131 PCI-CardBus Bridge", CB_TI113X, 0}, 113 114 {PCI_DEVICE_ID_PCIC_TI1210, "TI1210 PCI-CardBus Bridge", CB_TI12XX, 0}, 115 {PCI_DEVICE_ID_PCIC_TI1211, "TI1211 PCI-CardBus Bridge", CB_TI12XX, 0}, 116 {PCI_DEVICE_ID_PCIC_TI1220, "TI1220 PCI-CardBus Bridge", CB_TI12XX, 0}, 117 {PCI_DEVICE_ID_PCIC_TI1221, "TI1221 PCI-CardBus Bridge", CB_TI12XX, 0}, 118 {PCI_DEVICE_ID_PCIC_TI1225, "TI1225 PCI-CardBus Bridge", CB_TI12XX, 0}, 119 {PCI_DEVICE_ID_PCIC_TI1250, "TI1250 PCI-CardBus Bridge", CB_TI12XX, 0}, 120 {PCI_DEVICE_ID_PCIC_TI1251, "TI1251 PCI-CardBus Bridge", CB_TI12XX, 0}, 121 {PCI_DEVICE_ID_PCIC_TI1251B,"TI1251B PCI-CardBus Bridge",CB_TI12XX, 0}, 122 {PCI_DEVICE_ID_PCIC_TI1260, "TI1260 PCI-CardBus Bridge", CB_TI12XX, 0}, 123 {PCI_DEVICE_ID_PCIC_TI1260B, "TI1260B PCI-CardBus Bridge", CB_TI12XX, 124 0}, 125 {PCI_DEVICE_ID_PCIC_TI1410, "TI1410 PCI-CardBus Bridge", CB_TI12XX, 0}, 126 {PCI_DEVICE_ID_PCIC_TI1420, "TI1420 PCI-CardBus Bridge", CB_TI12XX, 0}, 127 {PCI_DEVICE_ID_PCIC_TI1421, "TI1421 PCI-CardBus Bridge", CB_TI12XX, 0}, 128 {PCI_DEVICE_ID_PCIC_TI1450, "TI1450 PCI-CardBus Bridge", CB_TI12XX, 0}, 129 {PCI_DEVICE_ID_PCIC_TI1451, "TI1451 PCI-CardBus Bridge", CB_TI12XX, 0}, 130 {PCI_DEVICE_ID_PCIC_TI4410, "TI4410 PCI-CardBus Bridge", CB_TI12XX, 0}, 131 {PCI_DEVICE_ID_PCIC_TI4450, "TI4450 PCI-CardBus Bridge", CB_TI12XX, 0}, 132 {PCI_DEVICE_ID_PCIC_TI4451, "TI4451 PCI-CardBus Bridge", CB_TI12XX, 0}, 133 134 /* Ricoh chips */ 135 {PCI_DEVICE_ID_RICOH_RL5C465, "RF5C465 PCI-CardBus Bridge", 136 CB_RF5C46X, 0}, 137 {PCI_DEVICE_ID_RICOH_RL5C466, "RF5C466 PCI-CardBus Bridge", 138 CB_RF5C46X, 0}, 139 {PCI_DEVICE_ID_RICOH_RL5C475, "RF5C475 PCI-CardBus Bridge", 140 CB_RF5C47X, 0}, 141 {PCI_DEVICE_ID_RICOH_RL5C476, "RF5C476 PCI-CardBus Bridge", 142 CB_RF5C47X, 0}, 143 {PCI_DEVICE_ID_RICOH_RL5C478, "RF5C478 PCI-CardBus Bridge", 144 CB_RF5C47X, 0}, 145 146 /* Toshiba products */ 147 {PCI_DEVICE_ID_TOSHIBA_TOPIC95, "ToPIC95 PCI-CardBus Bridge", 148 CB_TOPIC95, 0}, 149 {PCI_DEVICE_ID_TOSHIBA_TOPIC95B, "ToPIC95B PCI-CardBus Bridge", 150 CB_TOPIC95B, 0}, 151 {PCI_DEVICE_ID_TOSHIBA_TOPIC97, "ToPIC97 PCI-CardBus Bridge", 152 CB_TOPIC97, 0}, 153 {PCI_DEVICE_ID_TOSHIBA_TOPIC100, "ToPIC100 PCI-CardBus Bridge", 154 CB_TOPIC97, 0}, 155 156 /* Cirrus Logic */ 157 {PCI_DEVICE_ID_PCIC_CLPD6832, "CLPD6832 PCI-CardBus Bridge", 158 CB_CIRRUS, 0}, 159 {PCI_DEVICE_ID_PCIC_CLPD6833, "CLPD6833 PCI-CardBus Bridge", 160 CB_CIRRUS, 0}, 161 {PCI_DEVICE_ID_PCIC_CLPD6834, "CLPD6834 PCI-CardBus Bridge", 162 CB_CIRRUS, 0}, 163 164 /* 02Micro */ 165 {PCI_DEVICE_ID_PCIC_OZ6832, "O2Mirco OZ6832/6833 PCI-CardBus Bridge", 166 CB_CIRRUS, 0}, 167 {PCI_DEVICE_ID_PCIC_OZ6860, "O2Mirco OZ6836/6860 PCI-CardBus Bridge", 168 CB_CIRRUS, 0}, 169 {PCI_DEVICE_ID_PCIC_OZ6872, "O2Mirco OZ6812/6872 PCI-CardBus Bridge", 170 CB_CIRRUS, 0}, 171 {PCI_DEVICE_ID_PCIC_OZ6912, "O2Mirco OZ6912/6972 PCI-CardBus Bridge", 172 CB_CIRRUS, 0}, 173 {PCI_DEVICE_ID_PCIC_OZ6922, "O2Mirco OZ6822 PCI-CardBus Bridge", 174 CB_CIRRUS, 0}, 175 {PCI_DEVICE_ID_PCIC_OZ6933, "O2Mirco OZ6833 PCI-CardBus Bridge", 176 CB_CIRRUS, 0}, 177 178 /* sentinel */ 179 {0 /* null id */, "unknown", 180 CB_UNKNOWN, 0}, 181 }; 182 183 /* sysctl vars */ 184 SYSCTL_NODE(_hw, OID_AUTO, pccbb, CTLFLAG_RD, 0, "PCCBB parameters"); 185 186 /* There's no way to say TUNEABLE_LONG to get the right types */ 187 u_long pccbb_start_mem = PCCBB_START_MEM; 188 TUNABLE_INT("hw.pccbb.start_memory", (int *)&pccbb_start_mem); 189 SYSCTL_ULONG(_hw_pccbb, OID_AUTO, start_mem, CTLFLAG_RD, 190 &pccbb_start_mem, PCCBB_START_MEM, 191 "Starting address for memory allocations"); 192 193 static int pccbb_chipset(uint32_t pci_id, const char **namep, int *flagp); 194 static int pccbb_probe(device_t brdev); 195 static void pccbb_chipinit(struct pccbb_softc *sc); 196 static int pccbb_attach(device_t brdev); 197 static int pccbb_detach(device_t brdev); 198 static int pccbb_shutdown(device_t brdev); 199 static void pccbb_driver_added(device_t brdev, driver_t *driver); 200 static void pccbb_child_detached(device_t brdev, device_t child); 201 static int pccbb_card_reprobe(device_t brdev, device_t busdev); 202 static void pccbb_event_thread(void *arg); 203 static void pccbb_create_event_thread(struct pccbb_softc *sc); 204 static void pccbb_start_threads(void *arg); 205 static void pccbb_insert(struct pccbb_softc *sc); 206 static void pccbb_removal(struct pccbb_softc *sc); 207 static void pccbb_intr(void *arg); 208 static int pccbb_detect_voltage(device_t brdev); 209 static int pccbb_power(device_t brdev, int volts); 210 static void pccbb_cardbus_reset(device_t brdev); 211 static int pccbb_cardbus_power_enable_socket(device_t brdev, 212 device_t child); 213 static void pccbb_cardbus_power_disable_socket(device_t brdev, 214 device_t child); 215 static int pccbb_cardbus_io_open(device_t brdev, int win, uint32_t start, 216 uint32_t end); 217 static int pccbb_cardbus_mem_open(device_t brdev, int win, 218 uint32_t start, uint32_t end); 219 static void pccbb_cardbus_auto_open(struct pccbb_softc *sc, int type); 220 static int pccbb_cardbus_activate_resource(device_t brdev, device_t child, 221 int type, int rid, struct resource *res); 222 static int pccbb_cardbus_deactivate_resource(device_t brdev, 223 device_t child, int type, int rid, struct resource *res); 224 static struct resource *pccbb_cardbus_alloc_resource(device_t brdev, 225 device_t child, int type, int *rid, u_long start, 226 u_long end, u_long count, uint flags); 227 static int pccbb_cardbus_release_resource(device_t brdev, device_t child, 228 int type, int rid, struct resource *res); 229 static int pccbb_power_enable_socket(device_t brdev, device_t child); 230 static void pccbb_power_disable_socket(device_t brdev, device_t child); 231 static int pccbb_activate_resource(device_t brdev, device_t child, 232 int type, int rid, struct resource *r); 233 static int pccbb_deactivate_resource(device_t brdev, device_t child, 234 int type, int rid, struct resource *r); 235 static struct resource *pccbb_alloc_resource(device_t brdev, device_t child, 236 int type, int *rid, u_long start, u_long end, u_long count, 237 uint flags); 238 static int pccbb_release_resource(device_t brdev, device_t child, 239 int type, int rid, struct resource *r); 240 static int pccbb_read_ivar(device_t brdev, device_t child, int which, 241 uintptr_t *result); 242 static int pccbb_write_ivar(device_t brdev, device_t child, int which, 243 uintptr_t value); 244 static int pccbb_maxslots(device_t brdev); 245 static uint32_t pccbb_read_config(device_t brdev, int b, int s, int f, 246 int reg, int width); 247 static void pccbb_write_config(device_t brdev, int b, int s, int f, 248 int reg, uint32_t val, int width); 249 250 /* 251 */ 252 static __inline void 253 pccbb_set(struct pccbb_softc *sc, uint32_t reg, uint32_t val) 254 { 255 bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, val); 256 } 257 258 static __inline uint32_t 259 pccbb_get(struct pccbb_softc *sc, uint32_t reg) 260 { 261 return (bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg)); 262 } 263 264 static __inline void 265 pccbb_setb(struct pccbb_softc *sc, uint32_t reg, uint32_t bits) 266 { 267 pccbb_set(sc, reg, pccbb_get(sc, reg) | bits); 268 } 269 270 static __inline void 271 pccbb_clrb(struct pccbb_softc *sc, uint32_t reg, uint32_t bits) 272 { 273 pccbb_set(sc, reg, pccbb_get(sc, reg) & ~bits); 274 } 275 276 static __inline uint8_t 277 pccbb_pcic_read(struct exca_softc *sc, int reg) 278 { 279 return (bus_space_read_1(sc->bst, sc->bsh, sc->offset + reg)); 280 } 281 282 static __inline void 283 pccbb_pcic_write(struct exca_softc *sc, int reg, uint8_t val) 284 { 285 return (bus_space_write_1(sc->bst, sc->bsh, sc->offset + reg, val)); 286 } 287 288 static void 289 pccbb_remove_res(struct pccbb_softc *sc, struct resource *res) 290 { 291 struct pccbb_reslist *rle; 292 293 SLIST_FOREACH(rle, &sc->rl, link) { 294 if (rle->res == res) { 295 SLIST_REMOVE(&sc->rl, rle, pccbb_reslist, link); 296 free(rle, M_DEVBUF); 297 return; 298 } 299 } 300 } 301 302 static struct resource * 303 pccbb_find_res(struct pccbb_softc *sc, int type, int rid) 304 { 305 struct pccbb_reslist *rle; 306 307 SLIST_FOREACH(rle, &sc->rl, link) 308 if (SYS_RES_MEMORY == rle->type && rid == rle->rid) 309 return (rle->res); 310 return (NULL); 311 } 312 313 static void 314 pccbb_insert_res(struct pccbb_softc *sc, struct resource *res, int type, 315 int rid) 316 { 317 struct pccbb_reslist *rle; 318 319 /* 320 * Need to record allocated resource so we can iterate through 321 * it later. 322 */ 323 rle = malloc(sizeof(struct pccbb_reslist), M_DEVBUF, M_NOWAIT); 324 if (!res) 325 panic("pccbb_cardbus_alloc_resource: can't record entry!"); 326 rle->res = res; 327 rle->type = type; 328 rle->rid = rid; 329 SLIST_INSERT_HEAD(&sc->rl, rle, link); 330 } 331 332 static void 333 pccbb_destroy_res(struct pccbb_softc *sc) 334 { 335 struct pccbb_reslist *rle; 336 337 while ((rle = SLIST_FIRST(&sc->rl)) != NULL) { 338 device_printf(sc->sc_dev, "Danger Will Robinson: Resource " 339 "left allocated! This is a bug... " 340 "(rid=%x, type=%d, addr=%lx)\n", rle->rid, rle->type, 341 rman_get_start(rle->res)); 342 SLIST_REMOVE_HEAD(&sc->rl, link); 343 free(rle, M_DEVBUF); 344 } 345 } 346 347 /************************************************************************/ 348 /* Probe/Attach */ 349 /************************************************************************/ 350 351 static int 352 pccbb_chipset(uint32_t pci_id, const char **namep, int *flagp) 353 { 354 int loopend = sizeof(yc_chipsets)/sizeof(yc_chipsets[0]); 355 struct yenta_chipinfo *ycp, *ycend; 356 ycend = yc_chipsets + loopend; 357 358 for (ycp = yc_chipsets; ycp < ycend && pci_id != ycp->yc_id; ++ycp) 359 continue; 360 if (ycp == ycend) 361 /* not found */ 362 ycp = yc_chipsets + loopend - 1; /* to point the sentinel */ 363 if (namep != NULL) 364 *namep = ycp->yc_name; 365 if (flagp != NULL) 366 *flagp = ycp->yc_flags; 367 return (ycp->yc_chiptype); 368 } 369 370 static int 371 pccbb_probe(device_t brdev) 372 { 373 const char *name; 374 375 if (pccbb_chipset(pci_get_devid(brdev), &name, NULL) == CB_UNKNOWN) 376 return (ENXIO); 377 device_set_desc(brdev, name); 378 return (0); 379 } 380 381 static void 382 pccbb_chipinit(struct pccbb_softc *sc) 383 { 384 /* Set CardBus latency timer */ 385 if (pci_read_config(sc->sc_dev, PCIR_SECLAT_1, 1) < 0x20) 386 pci_write_config(sc->sc_dev, PCIR_SECLAT_1, 0x20, 1); 387 388 /* Set PCI latency timer */ 389 if (pci_read_config(sc->sc_dev, PCIR_LATTIMER, 1) < 0x20) 390 pci_write_config(sc->sc_dev, PCIR_LATTIMER, 0x20, 1); 391 392 /* Enable memory access */ 393 PCI_MASK_CONFIG(sc->sc_dev, PCIR_COMMAND, 394 | PCIM_CMD_MEMEN 395 | PCIM_CMD_PORTEN 396 | PCIM_CMD_BUSMASTEREN, 2); 397 398 /* disable Legacy IO */ 399 switch (sc->sc_chipset) { 400 case CB_RF5C46X: 401 PCI_MASK_CONFIG(sc->sc_dev, PCCBBR_BRIDGECTRL, 402 & ~(PCCBBM_BRIDGECTRL_RL_3E0_EN | 403 PCCBBM_BRIDGECTRL_RL_3E2_EN), 2); 404 break; 405 default: 406 pci_write_config(sc->sc_dev, PCCBBR_LEGACY, 0x0, 4); 407 break; 408 } 409 410 /* Use PCI interrupt for interrupt routing */ 411 PCI_MASK2_CONFIG(sc->sc_dev, PCCBBR_BRIDGECTRL, 412 & ~(PCCBBM_BRIDGECTRL_MASTER_ABORT | 413 PCCBBM_BRIDGECTRL_INTR_IREQ_EN), 414 | PCCBBM_BRIDGECTRL_WRITE_POST_EN, 415 2); 416 417 /* XXX this should be a function table, ala OLDCARD. */ 418 switch (sc->sc_chipset) { 419 case CB_TI113X: 420 /* 421 * The TI 1031, TI 1130 and TI 1131 all require another bit 422 * be set to enable PCI routing of interrupts, and then 423 * a bit for each of the CSC and Function interrupts we 424 * want routed. 425 */ 426 PCI_MASK_CONFIG(sc->sc_dev, PCCBBR_CBCTRL, 427 | PCCBBM_CBCTRL_113X_PCI_INTR | 428 PCCBBM_CBCTRL_113X_PCI_CSC | PCCBBM_CBCTRL_113X_PCI_IRQ_EN, 429 1); 430 PCI_MASK_CONFIG(sc->sc_dev, PCCBBR_DEVCTRL, 431 & ~(PCCBBM_DEVCTRL_INT_SERIAL | 432 PCCBBM_DEVCTRL_INT_PCI), 1); 433 exca_write(&sc->exca, EXCA_INTR, EXCA_INTR_ENABLE); 434 exca_write(&sc->exca, EXCA_CSC_INTR, 0); 435 break; 436 case CB_TI12XX: 437 exca_write(&sc->exca, EXCA_INTR, EXCA_INTR_ENABLE); 438 exca_write(&sc->exca, EXCA_CSC_INTR, 0); 439 break; 440 case CB_TOPIC95B: 441 PCI_MASK_CONFIG(sc->sc_dev, PCCBBR_TOPIC_SOCKETCTRL, 442 | PCCBBM_TOPIC_SOCKETCTRL_SCR_IRQSEL, 4); 443 PCI_MASK2_CONFIG(sc->sc_dev, PCCBBR_TOPIC_SLOTCTRL, 444 | PCCBBM_TOPIC_SLOTCTRL_SLOTON | 445 PCCBBM_TOPIC_SLOTCTRL_SLOTEN | 446 PCCBBM_TOPIC_SLOTCTRL_ID_LOCK | 447 PCCBBM_TOPIC_SLOTCTRL_CARDBUS, 448 & ~PCCBBM_TOPIC_SLOTCTRL_SWDETECT, 4); 449 break; 450 } 451 452 /* close all memory and io windows */ 453 pci_write_config(sc->sc_dev, PCCBBR_MEMBASE0, 0xffffffff, 4); 454 pci_write_config(sc->sc_dev, PCCBBR_MEMLIMIT0, 0, 4); 455 pci_write_config(sc->sc_dev, PCCBBR_MEMBASE1, 0xffffffff, 4); 456 pci_write_config(sc->sc_dev, PCCBBR_MEMLIMIT1, 0, 4); 457 pci_write_config(sc->sc_dev, PCCBBR_IOBASE0, 0xffffffff, 4); 458 pci_write_config(sc->sc_dev, PCCBBR_IOLIMIT0, 0, 4); 459 pci_write_config(sc->sc_dev, PCCBBR_IOBASE1, 0xffffffff, 4); 460 pci_write_config(sc->sc_dev, PCCBBR_IOLIMIT1, 0, 4); 461 } 462 463 static int 464 pccbb_attach(device_t brdev) 465 { 466 struct pccbb_softc *sc = (struct pccbb_softc *)device_get_softc(brdev); 467 int rid; 468 uint32_t sockbase; 469 struct pccbb_sclist *sclist; 470 471 if (!softcs_init) { 472 softcs_init = 1; 473 STAILQ_INIT(&softcs); 474 } 475 mtx_init(&sc->sc_mtx, device_get_nameunit(brdev), MTX_DEF); 476 sc->sc_chipset = pccbb_chipset(pci_get_devid(brdev), NULL, &sc->sc_flags); 477 sc->sc_dev = brdev; 478 sc->sc_cbdev = NULL; 479 sc->sc_pccarddev = NULL; 480 sc->sc_secbus = pci_read_config(brdev, PCIR_SECBUS_2, 1); 481 sc->sc_subbus = pci_read_config(brdev, PCIR_SUBBUS_2, 1); 482 SLIST_INIT(&sc->rl); 483 484 /* 485 * The PCI bus code should assign us memory in the absense 486 * of the BIOS doing so. However, 'should' isn't 'is,' so we hack 487 * up something here until the PCI code is up to snuff. 488 */ 489 rid = PCCBBR_SOCKBASE; 490 sc->sc_base_res = bus_alloc_resource(brdev, SYS_RES_MEMORY, &rid, 491 0, ~0, 1, RF_ACTIVE); 492 if (!sc->sc_base_res) { 493 /* 494 * XXX EVILE HACK BAD THING! XXX 495 * The pci bus device should do this for us. 496 * Some BIOSes doesn't assign a memory space properly. 497 * So we try to manually put one in... 498 */ 499 sockbase = pci_read_config(brdev, rid, 4); 500 if (sockbase < 0x100000 || sockbase >= 0xfffffff0) { 501 pci_write_config(brdev, rid, 0xffffffff, 4); 502 sockbase = pci_read_config(brdev, rid, 4); 503 sockbase = (sockbase & 0xfffffff0) & 504 -(sockbase & 0xfffffff0); 505 sc->sc_base_res = bus_generic_alloc_resource( 506 device_get_parent(brdev), brdev, SYS_RES_MEMORY, 507 &rid, pccbb_start_mem, ~0, sockbase, 508 RF_ACTIVE|rman_make_alignment_flags(sockbase)); 509 if (!sc->sc_base_res){ 510 device_printf(brdev, 511 "Could not grab register memory\n"); 512 mtx_destroy(&sc->sc_mtx); 513 return (ENOMEM); 514 } 515 pci_write_config(brdev, PCCBBR_SOCKBASE, 516 rman_get_start(sc->sc_base_res), 4); 517 DEVPRINTF((brdev, "PCI Memory allocated: %08lx\n", 518 rman_get_start(sc->sc_base_res))); 519 } else { 520 device_printf(brdev, "Could not map register memory\n"); 521 mtx_destroy(&sc->sc_mtx); 522 return (ENOMEM); 523 } 524 } 525 526 sc->sc_bst = rman_get_bustag(sc->sc_base_res); 527 sc->sc_bsh = rman_get_bushandle(sc->sc_base_res); 528 exca_init(&sc->exca, brdev, &pccbb_pcic_write, &pccbb_pcic_read, 529 sc->sc_bst, sc->sc_bsh, 0x800); 530 pccbb_chipinit(sc); 531 532 /* CSC Interrupt: Card detect interrupt on */ 533 pccbb_setb(sc, PCCBB_SOCKET_MASK, PCCBB_SOCKET_MASK_CD); 534 535 /* reset interrupt */ 536 pccbb_set(sc, PCCBB_SOCKET_EVENT, pccbb_get(sc, PCCBB_SOCKET_EVENT)); 537 538 /* Map and establish the interrupt. */ 539 rid = 0; 540 sc->sc_irq_res = bus_alloc_resource(brdev, SYS_RES_IRQ, &rid, 0, ~0, 1, 541 RF_SHAREABLE | RF_ACTIVE); 542 if (sc->sc_irq_res == NULL) { 543 printf("pccbb: Unable to map IRQ...\n"); 544 bus_release_resource(brdev, SYS_RES_MEMORY, PCCBBR_SOCKBASE, 545 sc->sc_base_res); 546 mtx_destroy(&sc->sc_mtx); 547 return (ENOMEM); 548 } 549 550 /* XXX INTR_TYPE_BIO IS WRONG here */ 551 if (bus_setup_intr(brdev, sc->sc_irq_res, INTR_TYPE_BIO, pccbb_intr, sc, 552 &sc->sc_intrhand)) { 553 device_printf(brdev, "couldn't establish interrupt"); 554 bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->sc_irq_res); 555 bus_release_resource(brdev, SYS_RES_MEMORY, PCCBBR_SOCKBASE, 556 sc->sc_base_res); 557 mtx_destroy(&sc->sc_mtx); 558 return (ENOMEM); 559 } 560 561 /* attach children */ 562 sc->sc_cbdev = device_add_child(brdev, "cardbus", -1); 563 if (sc->sc_cbdev == NULL) 564 DEVPRINTF((brdev, "WARNING: cannot add cardbus bus.\n")); 565 else if (device_probe_and_attach(sc->sc_cbdev) != 0) { 566 DEVPRINTF((brdev, "WARNING: cannot attach cardbus bus!\n")); 567 sc->sc_cbdev = NULL; 568 } 569 570 sc->sc_pccarddev = device_add_child(brdev, "pccard", -1); 571 if (sc->sc_pccarddev == NULL) 572 DEVPRINTF((brdev, "WARNING: cannot add pccard bus.\n")); 573 else if (device_probe_and_attach(sc->sc_pccarddev) != 0) { 574 DEVPRINTF((brdev, "WARNING: cannot attach pccard bus.\n")); 575 sc->sc_pccarddev = NULL; 576 } 577 578 sclist = malloc(sizeof(struct pccbb_sclist), M_DEVBUF, M_WAITOK); 579 sclist->sc = sc; 580 STAILQ_INSERT_TAIL(&softcs, sclist, entries); 581 return (0); 582 } 583 584 static int 585 pccbb_detach(device_t brdev) 586 { 587 struct pccbb_softc *sc = device_get_softc(brdev); 588 int numdevs; 589 device_t *devlist; 590 int tmp; 591 int error; 592 593 device_get_children(brdev, &devlist, &numdevs); 594 595 error = 0; 596 for (tmp = 0; tmp < numdevs; tmp++) { 597 if (device_detach(devlist[tmp]) == 0) 598 device_delete_child(brdev, devlist[tmp]); 599 else 600 error++; 601 } 602 free(devlist, M_TEMP); 603 if (error > 0) 604 return (ENXIO); 605 606 mtx_lock(&sc->sc_mtx); 607 bus_teardown_intr(brdev, sc->sc_irq_res, sc->sc_intrhand); 608 609 sc->sc_flags |= PCCBB_KTHREAD_DONE; 610 if (sc->sc_flags & PCCBB_KTHREAD_RUNNING) { 611 wakeup(sc); 612 mtx_unlock(&sc->sc_mtx); 613 DEVPRINTF((brdev, "waiting for kthread exit...")); 614 error = tsleep(sc, PWAIT, "pccbb-detach-wait", 60 * hz); 615 if (error) 616 DPRINTF(("timeout\n")); 617 else 618 DPRINTF(("done\n")); 619 } else { 620 mtx_unlock(&sc->sc_mtx); 621 } 622 623 bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->sc_irq_res); 624 bus_release_resource(brdev, SYS_RES_MEMORY, PCCBBR_SOCKBASE, 625 sc->sc_base_res); 626 mtx_destroy(&sc->sc_mtx); 627 return (0); 628 } 629 630 static int 631 pccbb_shutdown(device_t brdev) 632 { 633 struct pccbb_softc *sc = (struct pccbb_softc *)device_get_softc(brdev); 634 /* properly reset everything at shutdown */ 635 636 PCI_MASK_CONFIG(brdev, PCCBBR_BRIDGECTRL, |PCCBBM_BRIDGECTRL_RESET, 2); 637 exca_clrb(&sc->exca, EXCA_INTR, EXCA_INTR_RESET); 638 639 pccbb_set(sc, PCCBB_SOCKET_MASK, 0); 640 641 pccbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V); 642 643 exca_write(&sc->exca, EXCA_ADDRWIN_ENABLE, 0); 644 pci_write_config(brdev, PCCBBR_MEMBASE0, 0, 4); 645 pci_write_config(brdev, PCCBBR_MEMLIMIT0, 0, 4); 646 pci_write_config(brdev, PCCBBR_MEMBASE1, 0, 4); 647 pci_write_config(brdev, PCCBBR_MEMLIMIT1, 0, 4); 648 pci_write_config(brdev, PCCBBR_IOBASE0, 0, 4); 649 pci_write_config(brdev, PCCBBR_IOLIMIT0, 0, 4); 650 pci_write_config(brdev, PCCBBR_IOBASE1, 0, 4); 651 pci_write_config(brdev, PCCBBR_IOLIMIT1, 0, 4); 652 pci_write_config(brdev, PCIR_COMMAND, 0, 2); 653 return (0); 654 } 655 656 static void 657 pccbb_driver_added(device_t brdev, driver_t *driver) 658 { 659 struct pccbb_softc *sc = device_get_softc(brdev); 660 device_t *devlist; 661 int tmp; 662 int numdevs; 663 int wake; 664 uint32_t sockstate; 665 666 DEVICE_IDENTIFY(driver, brdev); 667 device_get_children(brdev, &devlist, &numdevs); 668 wake = 0; 669 sockstate = pccbb_get(sc, PCCBB_SOCKET_STATE); 670 for (tmp = 0; tmp < numdevs; tmp++) { 671 if (device_get_state(devlist[tmp]) == DS_NOTPRESENT && 672 device_probe_and_attach(devlist[tmp]) == 0) { 673 if (devlist[tmp] == NULL) 674 /* NOTHING */; 675 else if (strcmp(driver->name, "cardbus") == 0) { 676 sc->sc_cbdev = devlist[tmp]; 677 if (((sockstate & PCCBB_SOCKET_STAT_CD) == 0) && 678 (sockstate & PCCBB_SOCKET_STAT_CB)) 679 wake++; 680 } else if (strcmp(driver->name, "pccard") == 0) { 681 sc->sc_pccarddev = devlist[tmp]; 682 if (((sockstate & PCCBB_SOCKET_STAT_CD) == 0) && 683 (sockstate & PCCBB_SOCKET_STAT_16BIT)) 684 wake++; 685 } else 686 device_printf(brdev, 687 "Unsupported child bus: %s\n", 688 driver->name); 689 } 690 } 691 free(devlist, M_TEMP); 692 693 if (wake > 0) { 694 if ((pccbb_get(sc, PCCBB_SOCKET_STATE) & PCCBB_SOCKET_STAT_CD) 695 == 0) { 696 mtx_lock(&sc->sc_mtx); 697 wakeup(sc); 698 mtx_unlock(&sc->sc_mtx); 699 } 700 } 701 } 702 703 static void 704 pccbb_child_detached(device_t brdev, device_t child) 705 { 706 struct pccbb_softc *sc = device_get_softc(brdev); 707 708 if (child == sc->sc_cbdev) 709 sc->sc_cbdev = NULL; 710 else if (child == sc->sc_pccarddev) 711 sc->sc_pccarddev = NULL; 712 else 713 device_printf(brdev, "Unknown child detached: %s %p/%p\n", 714 device_get_nameunit(child), sc->sc_cbdev, sc->sc_pccarddev); 715 } 716 717 static int 718 pccbb_card_reprobe(device_t brdev, device_t busdev) 719 { 720 struct pccbb_softc *sc = device_get_softc(brdev); 721 int wake = 0; 722 uint32_t sockstate; 723 724 sockstate = pccbb_get(sc, PCCBB_SOCKET_STATE); 725 726 if ((sockstate & PCCBB_SOCKET_STAT_CD) == 0) { 727 if (busdev == sc->sc_cbdev && 728 (sockstate & PCCBB_SOCKET_STAT_CB)) 729 wake++; 730 else if (busdev == sc->sc_pccarddev && 731 (sockstate & PCCBB_SOCKET_STAT_16BIT)) 732 wake++; 733 734 if (wake > 0) { 735 mtx_lock(&sc->sc_mtx); 736 wakeup(sc); 737 mtx_unlock(&sc->sc_mtx); 738 return (0); 739 } 740 return (EBUSY); 741 } 742 return (ENOENT); 743 } 744 745 /************************************************************************/ 746 /* Kthreads */ 747 /************************************************************************/ 748 749 static void 750 pccbb_event_thread(void *arg) 751 { 752 struct pccbb_softc *sc = arg; 753 uint32_t status; 754 755 mtx_lock(&Giant); 756 for(;;) { 757 if (!(sc->sc_flags & PCCBB_KTHREAD_RUNNING)) { 758 sc->sc_flags |= PCCBB_KTHREAD_RUNNING; 759 } else { 760 tsleep (sc, PWAIT, "pccbbev", 0); 761 /* 762 * Delay 1 second, make sure the user is done with 763 * whatever he is doing. We tsleep on sc->sc_flags, 764 * which should never be woken up. 765 * 766 * XXX Note: This can cause problems on card 767 * removal. See OLDCARD's ISR for how you may 768 * have to deal with the debouncing problem. The 769 * crux of the issue is interrupts delivered to 770 * the card after eject are unstable. 771 */ 772 tsleep (&sc->sc_flags, PWAIT, "pccbbev", 1*hz); 773 } 774 mtx_lock(&sc->sc_mtx); 775 if (sc->sc_flags & PCCBB_KTHREAD_DONE) 776 break; 777 778 status = pccbb_get(sc, PCCBB_SOCKET_STATE); 779 if ((status & PCCBB_SOCKET_STAT_CD) == 0) { 780 pccbb_insert(sc); 781 } else { 782 pccbb_removal(sc); 783 } 784 mtx_unlock(&sc->sc_mtx); 785 } 786 mtx_unlock(&sc->sc_mtx); 787 sc->sc_flags &= ~PCCBB_KTHREAD_RUNNING; 788 wakeup(sc); 789 kthread_exit(0); 790 } 791 792 static void 793 pccbb_create_event_thread(struct pccbb_softc *sc) 794 { 795 if (kthread_create(pccbb_event_thread, sc, &sc->event_thread, 796 0, "%s%d", device_get_name(sc->sc_dev), 797 device_get_unit(sc->sc_dev))) { 798 device_printf (sc->sc_dev, "unable to create event thread.\n"); 799 panic ("pccbb_create_event_thread"); 800 } 801 } 802 803 static void 804 pccbb_start_threads(void *arg) 805 { 806 struct pccbb_sclist *sclist; 807 808 STAILQ_FOREACH(sclist, &softcs, entries) { 809 pccbb_create_event_thread(sclist->sc); 810 } 811 } 812 813 /************************************************************************/ 814 /* Insert/removal */ 815 /************************************************************************/ 816 817 static void 818 pccbb_insert(struct pccbb_softc *sc) 819 { 820 uint32_t sockevent, sockstate; 821 int timeout = 30; 822 823 do { 824 sockevent = pccbb_get(sc, PCCBB_SOCKET_EVENT); 825 sockstate = pccbb_get(sc, PCCBB_SOCKET_STATE); 826 } while (sockstate & PCCBB_SOCKET_STAT_CD && --timeout > 0); 827 828 if (timeout < 0) { 829 device_printf (sc->sc_dev, "insert timeout"); 830 return; 831 } 832 833 DEVPRINTF((sc->sc_dev, "card inserted: event=0x%08x, state=%08x\n", 834 sockevent, sockstate)); 835 836 if (sockstate & PCCBB_SOCKET_STAT_16BIT && sc->sc_pccarddev != NULL) { 837 sc->sc_flags |= PCCBB_16BIT_CARD; 838 if (CARD_ATTACH_CARD(sc->sc_pccarddev) != 0) 839 device_printf(sc->sc_dev, "card activation failed\n"); 840 } else if (sockstate & PCCBB_SOCKET_STAT_CB && sc->sc_cbdev != NULL) { 841 sc->sc_flags &= ~PCCBB_16BIT_CARD; 842 if (CARD_ATTACH_CARD(sc->sc_cbdev) != 0) 843 device_printf(sc->sc_dev, "card activation failed\n"); 844 } else { 845 device_printf (sc->sc_dev, "Unsupported card type detected\n"); 846 } 847 } 848 849 static void 850 pccbb_removal(struct pccbb_softc *sc) 851 { 852 if (sc->sc_flags & PCCBB_16BIT_CARD && sc->sc_pccarddev != NULL) 853 CARD_DETACH_CARD(sc->sc_pccarddev, DETACH_FORCE); 854 else if ((!(sc->sc_flags & PCCBB_16BIT_CARD)) && sc->sc_cbdev != NULL) 855 CARD_DETACH_CARD(sc->sc_cbdev, DETACH_FORCE); 856 pccbb_destroy_res(sc); 857 } 858 859 /************************************************************************/ 860 /* Interrupt Handler */ 861 /************************************************************************/ 862 863 static void 864 pccbb_intr(void *arg) 865 { 866 struct pccbb_softc *sc = arg; 867 uint32_t sockevent; 868 869 if (!(sockevent = pccbb_get(sc, PCCBB_SOCKET_EVENT))) { 870 /* not for me. */ 871 return; 872 } 873 874 /* reset bit */ 875 pccbb_setb(sc, PCCBB_SOCKET_EVENT, 0x01); /* XXXmagic */ 876 877 if (sockevent & PCCBB_SOCKET_EVENT_CD) { 878 mtx_lock(&sc->sc_mtx); 879 wakeup(sc); 880 mtx_unlock(&sc->sc_mtx); 881 } else { 882 if (sockevent & PCCBB_SOCKET_EVENT_CSTS) { 883 DPRINTF((" cstsevent occures, 0x%08x\n", 884 pccbb_get(sc, PCCBB_SOCKET_STATE))); 885 } 886 if (sockevent & PCCBB_SOCKET_EVENT_POWER) { 887 DPRINTF((" pwrevent occures, 0x%08x\n", 888 pccbb_get(sc, PCCBB_SOCKET_STATE))); 889 } 890 } 891 } 892 893 /************************************************************************/ 894 /* Generic Power functions */ 895 /************************************************************************/ 896 897 static int 898 pccbb_detect_voltage(device_t brdev) 899 { 900 struct pccbb_softc *sc = device_get_softc(brdev); 901 uint32_t psr; 902 int vol = CARD_UKN_CARD; 903 904 psr = pccbb_get(sc, PCCBB_SOCKET_STATE); 905 906 if (psr & PCCBB_SOCKET_STAT_5VCARD) 907 vol |= CARD_5V_CARD; 908 if (psr & PCCBB_SOCKET_STAT_3VCARD) 909 vol |= CARD_3V_CARD; 910 if (psr & PCCBB_SOCKET_STAT_XVCARD) 911 vol |= CARD_XV_CARD; 912 if (psr & PCCBB_SOCKET_STAT_YVCARD) 913 vol |= CARD_YV_CARD; 914 915 return (vol); 916 } 917 918 static int 919 pccbb_power(device_t brdev, int volts) 920 { 921 uint32_t status, sock_ctrl; 922 struct pccbb_softc *sc = device_get_softc(brdev); 923 int timeout; 924 uint32_t sockevent; 925 926 DEVPRINTF((sc->sc_dev, "pccbb_power: %s and %s [%x]\n", 927 (volts & CARD_VCCMASK) == CARD_VCC_UC ? "CARD_VCC_UC" : 928 (volts & CARD_VCCMASK) == CARD_VCC_5V ? "CARD_VCC_5V" : 929 (volts & CARD_VCCMASK) == CARD_VCC_3V ? "CARD_VCC_3V" : 930 (volts & CARD_VCCMASK) == CARD_VCC_XV ? "CARD_VCC_XV" : 931 (volts & CARD_VCCMASK) == CARD_VCC_YV ? "CARD_VCC_YV" : 932 (volts & CARD_VCCMASK) == CARD_VCC_0V ? "CARD_VCC_0V" : 933 "VCC-UNKNOWN", 934 (volts & CARD_VPPMASK) == CARD_VPP_UC ? "CARD_VPP_UC" : 935 (volts & CARD_VPPMASK) == CARD_VPP_12V ? "CARD_VPP_12V" : 936 (volts & CARD_VPPMASK) == CARD_VPP_VCC ? "CARD_VPP_VCC" : 937 (volts & CARD_VPPMASK) == CARD_VPP_0V ? "CARD_VPP_0V" : 938 "VPP-UNKNOWN", 939 volts)); 940 941 status = pccbb_get(sc, PCCBB_SOCKET_STATE); 942 sock_ctrl = pccbb_get(sc, PCCBB_SOCKET_CONTROL); 943 944 switch (volts & CARD_VCCMASK) { 945 case CARD_VCC_UC: 946 break; 947 case CARD_VCC_5V: 948 if (PCCBB_SOCKET_STAT_5VCARD & status) { /* check 5 V card */ 949 sock_ctrl &= ~PCCBB_SOCKET_CTRL_VCCMASK; 950 sock_ctrl |= PCCBB_SOCKET_CTRL_VCC_5V; 951 } else { 952 device_printf(sc->sc_dev, 953 "BAD voltage request: no 5 V card\n"); 954 } 955 break; 956 case CARD_VCC_3V: 957 if (PCCBB_SOCKET_STAT_3VCARD & status) { 958 sock_ctrl &= ~PCCBB_SOCKET_CTRL_VCCMASK; 959 sock_ctrl |= PCCBB_SOCKET_CTRL_VCC_3V; 960 } else { 961 device_printf(sc->sc_dev, 962 "BAD voltage request: no 3.3 V card\n"); 963 } 964 break; 965 case CARD_VCC_0V: 966 sock_ctrl &= ~PCCBB_SOCKET_CTRL_VCCMASK; 967 break; 968 default: 969 return (0); /* power NEVER changed */ 970 break; 971 } 972 973 switch (volts & CARD_VPPMASK) { 974 case CARD_VPP_UC: 975 break; 976 case CARD_VPP_0V: 977 sock_ctrl &= ~PCCBB_SOCKET_CTRL_VPPMASK; 978 break; 979 case CARD_VPP_VCC: 980 sock_ctrl &= ~PCCBB_SOCKET_CTRL_VPPMASK; 981 sock_ctrl |= ((sock_ctrl >> 4) & 0x07); 982 break; 983 case CARD_VPP_12V: 984 sock_ctrl &= ~PCCBB_SOCKET_CTRL_VPPMASK; 985 sock_ctrl |= PCCBB_SOCKET_CTRL_VPP_12V; 986 break; 987 } 988 989 if (pccbb_get(sc, PCCBB_SOCKET_CONTROL) == sock_ctrl) 990 return (1); /* no change necessary */ 991 992 pccbb_set(sc, PCCBB_SOCKET_CONTROL, sock_ctrl); 993 status = pccbb_get(sc, PCCBB_SOCKET_STATE); 994 995 /* 996 * XXX This busy wait is bogus. We should wait for a power 997 * interrupt and then whine if the status is bad. If we're 998 * worried about the card not coming up, then we should also 999 * schedule a timeout which we can cacel in the power interrupt. 1000 */ 1001 timeout = 20; 1002 do { 1003 DELAY(20*1000); 1004 sockevent = pccbb_get(sc, PCCBB_SOCKET_EVENT); 1005 } while (!(sockevent & PCCBB_SOCKET_EVENT_POWER) && --timeout > 0); 1006 /* reset event status */ 1007 /* XXX should only reset EVENT_POWER */ 1008 pccbb_set(sc, PCCBB_SOCKET_EVENT, sockevent); 1009 if (timeout < 0) { 1010 printf ("VCC supply failed.\n"); 1011 return (0); 1012 } 1013 1014 /* XXX 1015 * delay 400 ms: thgough the standard defines that the Vcc set-up time 1016 * is 20 ms, some PC-Card bridge requires longer duration. 1017 * XXX Note: We should check the stutus AFTER the delay to give time 1018 * for things to stabilize. 1019 */ 1020 DELAY(400*1000); 1021 1022 if (status & PCCBB_SOCKET_STAT_BADVCC) { 1023 device_printf(sc->sc_dev, 1024 "bad Vcc request. ctrl=0x%x, status=0x%x\n", 1025 sock_ctrl ,status); 1026 printf("pccbb_power: %s and %s [%x]\n", 1027 (volts & CARD_VCCMASK) == CARD_VCC_UC ? "CARD_VCC_UC" : 1028 (volts & CARD_VCCMASK) == CARD_VCC_5V ? "CARD_VCC_5V" : 1029 (volts & CARD_VCCMASK) == CARD_VCC_3V ? "CARD_VCC_3V" : 1030 (volts & CARD_VCCMASK) == CARD_VCC_XV ? "CARD_VCC_XV" : 1031 (volts & CARD_VCCMASK) == CARD_VCC_YV ? "CARD_VCC_YV" : 1032 (volts & CARD_VCCMASK) == CARD_VCC_0V ? "CARD_VCC_0V" : 1033 "VCC-UNKNOWN", 1034 (volts & CARD_VPPMASK) == CARD_VPP_UC ? "CARD_VPP_UC" : 1035 (volts & CARD_VPPMASK) == CARD_VPP_12V ? "CARD_VPP_12V": 1036 (volts & CARD_VPPMASK) == CARD_VPP_VCC ? "CARD_VPP_VCC": 1037 (volts & CARD_VPPMASK) == CARD_VPP_0V ? "CARD_VPP_0V" : 1038 "VPP-UNKNOWN", 1039 volts); 1040 return (0); 1041 } 1042 return (1); /* power changed correctly */ 1043 } 1044 1045 /************************************************************************/ 1046 /* Cardbus power functions */ 1047 /************************************************************************/ 1048 1049 static void 1050 pccbb_cardbus_reset(device_t brdev) 1051 { 1052 struct pccbb_softc *sc = device_get_softc(brdev); 1053 int delay_us; 1054 1055 delay_us = sc->sc_chipset == CB_RF5C47X ? 400*1000 : 20*1000; 1056 1057 PCI_MASK_CONFIG(brdev, PCCBBR_BRIDGECTRL, |PCCBBM_BRIDGECTRL_RESET, 2); 1058 1059 DELAY(delay_us); 1060 1061 /* If a card exists, unreset it! */ 1062 if ((pccbb_get(sc, PCCBB_SOCKET_STATE) & PCCBB_SOCKET_STAT_CD) == 0) { 1063 PCI_MASK_CONFIG(brdev, PCCBBR_BRIDGECTRL, 1064 &~PCCBBM_BRIDGECTRL_RESET, 2); 1065 DELAY(delay_us); 1066 } 1067 } 1068 1069 static int 1070 pccbb_cardbus_power_enable_socket(device_t brdev, device_t child) 1071 { 1072 struct pccbb_softc *sc = device_get_softc(brdev); 1073 int voltage; 1074 1075 if ((pccbb_get(sc, PCCBB_SOCKET_STATE) & PCCBB_SOCKET_STAT_CD) == 1076 PCCBB_SOCKET_STAT_CD) 1077 return (ENODEV); 1078 1079 voltage = pccbb_detect_voltage(brdev); 1080 1081 pccbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V); 1082 if (voltage & CARD_5V_CARD) 1083 pccbb_power(brdev, CARD_VCC_5V | CARD_VPP_VCC); 1084 else if (voltage & CARD_3V_CARD) 1085 pccbb_power(brdev, CARD_VCC_3V | CARD_VPP_VCC); 1086 else { 1087 device_printf(brdev, "Unknown card voltage\n"); 1088 return (ENXIO); 1089 } 1090 1091 pccbb_cardbus_reset(brdev); 1092 return (0); 1093 } 1094 1095 static void 1096 pccbb_cardbus_power_disable_socket(device_t brdev, device_t child) 1097 { 1098 pccbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V); 1099 pccbb_cardbus_reset(brdev); 1100 } 1101 1102 /************************************************************************/ 1103 /* Cardbus Resource */ 1104 /************************************************************************/ 1105 1106 static int 1107 pccbb_cardbus_io_open(device_t brdev, int win, uint32_t start, uint32_t end) 1108 { 1109 int basereg; 1110 int limitreg; 1111 1112 if ((win < 0) || (win > 1)) { 1113 DEVPRINTF((brdev, 1114 "pccbb_cardbus_io_open: window out of range %d\n", win)); 1115 return (EINVAL); 1116 } 1117 1118 basereg = win*8 + PCCBBR_IOBASE0; 1119 limitreg = win*8 + PCCBBR_IOLIMIT0; 1120 1121 pci_write_config(brdev, basereg, start, 4); 1122 pci_write_config(brdev, limitreg, end, 4); 1123 return (0); 1124 } 1125 1126 static int 1127 pccbb_cardbus_mem_open(device_t brdev, int win, uint32_t start, uint32_t end) 1128 { 1129 int basereg; 1130 int limitreg; 1131 1132 if ((win < 0) || (win > 1)) { 1133 DEVPRINTF((brdev, 1134 "pccbb_cardbus_mem_open: window out of range %d\n", win)); 1135 return (EINVAL); 1136 } 1137 1138 basereg = win*8 + PCCBBR_MEMBASE0; 1139 limitreg = win*8 + PCCBBR_MEMLIMIT0; 1140 1141 pci_write_config(brdev, basereg, start, 4); 1142 pci_write_config(brdev, limitreg, end, 4); 1143 return (0); 1144 } 1145 1146 /* 1147 * XXX The following function belongs in the pci bus layer. 1148 */ 1149 static void 1150 pccbb_cardbus_auto_open(struct pccbb_softc *sc, int type) 1151 { 1152 uint32_t starts[2]; 1153 uint32_t ends[2]; 1154 struct pccbb_reslist *rle; 1155 int align; 1156 int prefetchable[2]; 1157 uint32_t reg; 1158 1159 starts[0] = starts[1] = 0xffffffff; 1160 ends[0] = ends[1] = 0; 1161 1162 if (type == SYS_RES_MEMORY) 1163 align = PCCBB_MEMALIGN; 1164 else if (type == SYS_RES_IOPORT) 1165 align = PCCBB_IOALIGN; 1166 else 1167 align = 1; 1168 1169 SLIST_FOREACH(rle, &sc->rl, link) { 1170 if (rle->type != type) 1171 ; 1172 else if (rle->res == NULL) { 1173 device_printf(sc->sc_dev, "WARNING: Resource not reserved? " 1174 "(type=%d, addr=%lx)\n", 1175 rle->type, rman_get_start(rle->res)); 1176 } else if (!(rman_get_flags(rle->res) & RF_ACTIVE)) { 1177 /* XXX */ 1178 } else if (starts[0] == 0xffffffff) { 1179 starts[0] = rman_get_start(rle->res); 1180 ends[0] = rman_get_end(rle->res); 1181 prefetchable[0] = 1182 rman_get_flags(rle->res) & RF_PREFETCHABLE; 1183 } else if (rman_get_end(rle->res) > ends[0] && 1184 rman_get_start(rle->res) - ends[0] < 1185 PCCBB_AUTO_OPEN_SMALLHOLE && prefetchable[0] == 1186 (rman_get_flags(rle->res) & RF_PREFETCHABLE)) { 1187 ends[0] = rman_get_end(rle->res); 1188 } else if (rman_get_start(rle->res) < starts[0] && 1189 starts[0] - rman_get_end(rle->res) < 1190 PCCBB_AUTO_OPEN_SMALLHOLE && prefetchable[0] == 1191 (rman_get_flags(rle->res) & RF_PREFETCHABLE)) { 1192 starts[0] = rman_get_start(rle->res); 1193 } else if (starts[1] == 0xffffffff) { 1194 starts[1] = rman_get_start(rle->res); 1195 ends[1] = rman_get_end(rle->res); 1196 prefetchable[1] = 1197 rman_get_flags(rle->res) & RF_PREFETCHABLE; 1198 } else if (rman_get_end(rle->res) > ends[1] && 1199 rman_get_start(rle->res) - ends[1] < 1200 PCCBB_AUTO_OPEN_SMALLHOLE && prefetchable[1] == 1201 (rman_get_flags(rle->res) & RF_PREFETCHABLE)) { 1202 ends[1] = rman_get_end(rle->res); 1203 } else if (rman_get_start(rle->res) < starts[1] && 1204 starts[1] - rman_get_end(rle->res) < 1205 PCCBB_AUTO_OPEN_SMALLHOLE && prefetchable[1] == 1206 (rman_get_flags(rle->res) & RF_PREFETCHABLE)) { 1207 starts[1] = rman_get_start(rle->res); 1208 } else { 1209 uint32_t diffs[2]; 1210 int win; 1211 1212 diffs[0] = diffs[1] = 0xffffffff; 1213 if (rman_get_start(rle->res) > ends[0]) 1214 diffs[0] = rman_get_start(rle->res) - ends[0]; 1215 else if (rman_get_end(rle->res) < starts[0]) 1216 diffs[0] = starts[0] - rman_get_end(rle->res); 1217 if (rman_get_start(rle->res) > ends[1]) 1218 diffs[1] = rman_get_start(rle->res) - ends[1]; 1219 else if (rman_get_end(rle->res) < starts[1]) 1220 diffs[1] = starts[1] - rman_get_end(rle->res); 1221 1222 win = (diffs[0] <= diffs[1])?0:1; 1223 if (rman_get_start(rle->res) > ends[win]) 1224 ends[win] = rman_get_end(rle->res); 1225 else if (rman_get_end(rle->res) < starts[win]) 1226 starts[win] = rman_get_start(rle->res); 1227 if (!(rman_get_flags(rle->res) & RF_PREFETCHABLE)) 1228 prefetchable[win] = 0; 1229 } 1230 1231 if (starts[0] != 0xffffffff) 1232 starts[0] -= starts[0] % align; 1233 if (starts[1] != 0xffffffff) 1234 starts[1] -= starts[1] % align; 1235 if (ends[0] % align != 0) 1236 ends[0] += align - ends[0]%align - 1; 1237 if (ends[1] % align != 0) 1238 ends[1] += align - ends[1]%align - 1; 1239 } 1240 1241 if (type == SYS_RES_MEMORY) { 1242 pccbb_cardbus_mem_open(sc->sc_dev, 0, starts[0], ends[0]); 1243 pccbb_cardbus_mem_open(sc->sc_dev, 1, starts[1], ends[1]); 1244 reg = pci_read_config(sc->sc_dev, PCCBBR_BRIDGECTRL, 2); 1245 reg &= ~(PCCBBM_BRIDGECTRL_PREFETCH_0| 1246 PCCBBM_BRIDGECTRL_PREFETCH_1); 1247 reg |= (prefetchable[0]?PCCBBM_BRIDGECTRL_PREFETCH_0:0)| 1248 (prefetchable[1]?PCCBBM_BRIDGECTRL_PREFETCH_1:0); 1249 pci_write_config(sc->sc_dev, PCCBBR_BRIDGECTRL, reg, 2); 1250 } else if (type == SYS_RES_IOPORT) { 1251 pccbb_cardbus_io_open(sc->sc_dev, 0, starts[0], ends[0]); 1252 pccbb_cardbus_io_open(sc->sc_dev, 1, starts[1], ends[1]); 1253 } 1254 } 1255 1256 static int 1257 pccbb_cardbus_activate_resource(device_t brdev, device_t child, int type, 1258 int rid, struct resource *res) 1259 { 1260 int ret; 1261 1262 ret = BUS_ACTIVATE_RESOURCE(device_get_parent(brdev), child, 1263 type, rid, res); 1264 if (ret != 0) 1265 return (ret); 1266 pccbb_cardbus_auto_open(device_get_softc(brdev), type); 1267 return (0); 1268 } 1269 1270 static int 1271 pccbb_cardbus_deactivate_resource(device_t brdev, device_t child, int type, 1272 int rid, struct resource *res) 1273 { 1274 int ret; 1275 1276 ret = BUS_DEACTIVATE_RESOURCE(device_get_parent(brdev), child, 1277 type, rid, res); 1278 if (ret != 0) 1279 return (ret); 1280 pccbb_cardbus_auto_open(device_get_softc(brdev), type); 1281 return (0); 1282 } 1283 1284 static struct resource * 1285 pccbb_cardbus_alloc_resource(device_t brdev, device_t child, int type, int *rid, 1286 u_long start, u_long end, u_long count, uint flags) 1287 { 1288 struct pccbb_softc *sc = device_get_softc(brdev); 1289 int tmp; 1290 struct resource *res; 1291 1292 switch (type) { 1293 case SYS_RES_IRQ: 1294 tmp = rman_get_start(sc->sc_irq_res); 1295 if (start > tmp || end < tmp || count != 1) { 1296 device_printf(child, "requested interrupt %ld-%ld," 1297 "count = %ld not supported by pccbb\n", 1298 start, end, count); 1299 return (NULL); 1300 } 1301 start = end = tmp; 1302 break; 1303 case SYS_RES_IOPORT: 1304 if (start <= PCCBB_START_IO) 1305 start = PCCBB_START_IO; 1306 if (end < start) 1307 end = start; 1308 break; 1309 case SYS_RES_MEMORY: 1310 if (start <= pccbb_start_mem) 1311 start = pccbb_start_mem; 1312 if (end < start) 1313 end = start; 1314 break; 1315 } 1316 1317 res = BUS_ALLOC_RESOURCE(device_get_parent(brdev), child, type, rid, 1318 start, end, count, flags & ~RF_ACTIVE); 1319 if (res == NULL) { 1320 printf("pccbb alloc res fail\n"); 1321 return (NULL); 1322 } 1323 pccbb_insert_res(sc, res, type, *rid); 1324 if (flags & RF_ACTIVE) 1325 if (bus_activate_resource(child, type, *rid, res) != 0) { 1326 bus_release_resource(child, type, *rid, res); 1327 return (NULL); 1328 } 1329 1330 return (res); 1331 } 1332 1333 static int 1334 pccbb_cardbus_release_resource(device_t brdev, device_t child, int type, 1335 int rid, struct resource *res) 1336 { 1337 struct pccbb_softc *sc = device_get_softc(brdev); 1338 int error; 1339 1340 if (rman_get_flags(res) & RF_ACTIVE) { 1341 error = bus_deactivate_resource(child, type, rid, res); 1342 if (error != 0) 1343 return (error); 1344 } 1345 pccbb_remove_res(sc, res); 1346 return (BUS_RELEASE_RESOURCE(device_get_parent(brdev), child, 1347 type, rid, res)); 1348 } 1349 1350 /************************************************************************/ 1351 /* PC Card Power Functions */ 1352 /************************************************************************/ 1353 1354 static int 1355 pccbb_pcic_power_enable_socket(device_t brdev, device_t child) 1356 { 1357 struct pccbb_softc *sc = device_get_softc(brdev); 1358 int voltage; 1359 1360 DPRINTF(("pccbb_pcic_socket_enable:\n")); 1361 1362 /* power down/up the socket to reset */ 1363 voltage = pccbb_detect_voltage(brdev); 1364 pccbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V); 1365 if (voltage & CARD_5V_CARD) 1366 pccbb_power(brdev, CARD_VCC_5V | CARD_VPP_VCC); 1367 else if (voltage & CARD_3V_CARD) 1368 pccbb_power(brdev, CARD_VCC_3V | CARD_VPP_VCC); 1369 else { 1370 device_printf(brdev, "Unknown card voltage\n"); 1371 return (ENXIO); 1372 } 1373 exca_reset(&sc->exca, child); 1374 1375 return (0); 1376 } 1377 1378 static void 1379 pccbb_pcic_power_disable_socket(device_t brdev, device_t child) 1380 { 1381 struct pccbb_softc *sc = device_get_softc(brdev); 1382 1383 DPRINTF(("pccbb_pcic_socket_disable\n")); 1384 1385 /* reset signal asserting... */ 1386 exca_clrb(&sc->exca, EXCA_INTR, EXCA_INTR_RESET); 1387 DELAY(2*1000); 1388 1389 /* power down the socket */ 1390 pccbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V); 1391 exca_clrb(&sc->exca, EXCA_PWRCTL, EXCA_PWRCTL_OE); 1392 1393 /* wait 300ms until power fails (Tpf). */ 1394 DELAY(300 * 1000); 1395 } 1396 1397 /************************************************************************/ 1398 /* POWER methods */ 1399 /************************************************************************/ 1400 1401 static int 1402 pccbb_power_enable_socket(device_t brdev, device_t child) 1403 { 1404 struct pccbb_softc *sc = device_get_softc(brdev); 1405 1406 if (sc->sc_flags & PCCBB_16BIT_CARD) 1407 return (pccbb_pcic_power_enable_socket(brdev, child)); 1408 else 1409 return (pccbb_cardbus_power_enable_socket(brdev, child)); 1410 } 1411 1412 static void 1413 pccbb_power_disable_socket(device_t brdev, device_t child) 1414 { 1415 struct pccbb_softc *sc = device_get_softc(brdev); 1416 if (sc->sc_flags & PCCBB_16BIT_CARD) 1417 pccbb_pcic_power_disable_socket(brdev, child); 1418 else 1419 pccbb_cardbus_power_disable_socket(brdev, child); 1420 } 1421 static int 1422 pccbb_pcic_activate_resource(device_t brdev, device_t child, int type, int rid, 1423 struct resource *res) 1424 { 1425 int err; 1426 struct pccbb_softc *sc = device_get_softc(brdev); 1427 if (!(rman_get_flags(res) & RF_ACTIVE)) { /* not already activated */ 1428 switch (type) { 1429 case SYS_RES_IOPORT: 1430 err = exca_io_map(&sc->exca, 0, res); 1431 break; 1432 case SYS_RES_MEMORY: 1433 err = exca_mem_map(&sc->exca, 0, res); 1434 break; 1435 default: 1436 err = 0; 1437 break; 1438 } 1439 if (err) 1440 return (err); 1441 1442 } 1443 return (BUS_ACTIVATE_RESOURCE(device_get_parent(brdev), child, 1444 type, rid, res)); 1445 } 1446 1447 static int 1448 pccbb_pcic_deactivate_resource(device_t brdev, device_t child, int type, 1449 int rid, struct resource *res) 1450 { 1451 struct pccbb_softc *sc = device_get_softc(brdev); 1452 1453 if (rman_get_flags(res) & RF_ACTIVE) { /* if activated */ 1454 switch (type) { 1455 case SYS_RES_IOPORT: 1456 if (exca_io_unmap_res(&sc->exca, res)) 1457 return (ENOENT); 1458 break; 1459 case SYS_RES_MEMORY: 1460 if (exca_mem_unmap_res(&sc->exca, res)) 1461 return (ENOENT); 1462 break; 1463 } 1464 } 1465 return (BUS_DEACTIVATE_RESOURCE(device_get_parent(brdev), child, 1466 type, rid, res)); 1467 } 1468 1469 static struct resource * 1470 pccbb_pcic_alloc_resource(device_t brdev, device_t child, int type, int *rid, 1471 u_long start, u_long end, u_long count, uint flags) 1472 { 1473 struct resource *res = NULL; 1474 struct pccbb_softc *sc = device_get_softc(brdev); 1475 int tmp; 1476 1477 switch (type) { 1478 case SYS_RES_MEMORY: 1479 if (start < pccbb_start_mem) 1480 start = pccbb_start_mem; 1481 if (end < start) 1482 end = start; 1483 flags = (flags & ~RF_ALIGNMENT_MASK) | 1484 rman_make_alignment_flags(PCCBB_MEMALIGN); 1485 break; 1486 case SYS_RES_IOPORT: 1487 if (start < 0x100) 1488 start = 0x100; /* XXX tweakable? */ 1489 if (end < start) 1490 end = start; 1491 break; 1492 case SYS_RES_IRQ: 1493 tmp = rman_get_start(sc->sc_irq_res); 1494 if (start > tmp || end < tmp || count != 1) { 1495 device_printf(child, "requested interrupt %ld-%ld," 1496 "count = %ld not supported by pccbb\n", 1497 start, end, count); 1498 return (NULL); 1499 } 1500 flags |= RF_SHAREABLE; 1501 start = end = rman_get_start(sc->sc_irq_res); 1502 break; 1503 } 1504 res = BUS_ALLOC_RESOURCE(device_get_parent(brdev), child, type, rid, 1505 start, end, count, flags & ~RF_ACTIVE); 1506 if (res == NULL) 1507 return (NULL); 1508 pccbb_insert_res(sc, res, type, *rid); 1509 if (flags & RF_ACTIVE) { 1510 if (bus_activate_resource(child, type, *rid, res) != 0) { 1511 bus_release_resource(child, type, *rid, res); 1512 return (NULL); 1513 } 1514 } 1515 1516 return (res); 1517 } 1518 1519 static int 1520 pccbb_pcic_release_resource(device_t brdev, device_t child, int type, 1521 int rid, struct resource *res) 1522 { 1523 struct pccbb_softc *sc = device_get_softc(brdev); 1524 int error; 1525 1526 if (rman_get_flags(res) & RF_ACTIVE) { 1527 error = bus_deactivate_resource(child, type, rid, res); 1528 if (error != 0) 1529 return (error); 1530 } 1531 pccbb_remove_res(sc, res); 1532 return (BUS_RELEASE_RESOURCE(device_get_parent(brdev), child, 1533 type, rid, res)); 1534 } 1535 1536 /************************************************************************/ 1537 /* PC Card methods */ 1538 /************************************************************************/ 1539 1540 static int 1541 pccbb_pcic_set_res_flags(device_t brdev, device_t child, int type, int rid, 1542 uint32_t flags) 1543 { 1544 struct pccbb_softc *sc = device_get_softc(brdev); 1545 struct resource *res; 1546 1547 if (type != SYS_RES_MEMORY) 1548 return (EINVAL); 1549 res = pccbb_find_res(sc, type, rid); 1550 if (res == NULL) { 1551 device_printf(brdev, 1552 "set_res_flags: specified rid not found\n"); 1553 return (ENOENT); 1554 } 1555 return (exca_mem_set_flags(&sc->exca, res, flags)); 1556 } 1557 1558 static int 1559 pccbb_pcic_set_memory_offset(device_t brdev, device_t child, int rid, 1560 uint32_t cardaddr, uint32_t *deltap) 1561 { 1562 struct pccbb_softc *sc = device_get_softc(brdev); 1563 struct resource *res; 1564 1565 res = pccbb_find_res(sc, SYS_RES_MEMORY, rid); 1566 if (res == NULL) { 1567 device_printf(brdev, 1568 "set_memory_offset: specified rid not found\n"); 1569 return (ENOENT); 1570 } 1571 return (exca_mem_set_offset(&sc->exca, res, cardaddr, deltap)); 1572 } 1573 1574 /************************************************************************/ 1575 /* BUS Methods */ 1576 /************************************************************************/ 1577 1578 1579 static int 1580 pccbb_activate_resource(device_t brdev, device_t child, int type, int rid, 1581 struct resource *r) 1582 { 1583 struct pccbb_softc *sc = device_get_softc(brdev); 1584 1585 if (sc->sc_flags & PCCBB_16BIT_CARD) 1586 return (pccbb_pcic_activate_resource(brdev, child, type, rid, r)); 1587 else 1588 return (pccbb_cardbus_activate_resource(brdev, child, type, rid, 1589 r)); 1590 } 1591 1592 static int 1593 pccbb_deactivate_resource(device_t brdev, device_t child, int type, 1594 int rid, struct resource *r) 1595 { 1596 struct pccbb_softc *sc = device_get_softc(brdev); 1597 1598 if (sc->sc_flags & PCCBB_16BIT_CARD) 1599 return (pccbb_pcic_deactivate_resource(brdev, child, type, 1600 rid, r)); 1601 else 1602 return (pccbb_cardbus_deactivate_resource(brdev, child, type, 1603 rid, r)); 1604 } 1605 1606 static struct resource * 1607 pccbb_alloc_resource(device_t brdev, device_t child, int type, int *rid, 1608 u_long start, u_long end, u_long count, uint flags) 1609 { 1610 struct pccbb_softc *sc = device_get_softc(brdev); 1611 1612 if (sc->sc_flags & PCCBB_16BIT_CARD) 1613 return (pccbb_pcic_alloc_resource(brdev, child, type, rid, 1614 start, end, count, flags)); 1615 else 1616 return (pccbb_cardbus_alloc_resource(brdev, child, type, rid, 1617 start, end, count, flags)); 1618 } 1619 1620 static int 1621 pccbb_release_resource(device_t brdev, device_t child, int type, int rid, 1622 struct resource *r) 1623 { 1624 struct pccbb_softc *sc = device_get_softc(brdev); 1625 1626 if (sc->sc_flags & PCCBB_16BIT_CARD) 1627 return (pccbb_pcic_release_resource(brdev, child, type, 1628 rid, r)); 1629 else 1630 return (pccbb_cardbus_release_resource(brdev, child, type, 1631 rid, r)); 1632 } 1633 1634 static int 1635 pccbb_read_ivar(device_t brdev, device_t child, int which, uintptr_t *result) 1636 { 1637 struct pccbb_softc *sc = device_get_softc(brdev); 1638 1639 switch (which) { 1640 case PCIB_IVAR_BUS: 1641 *result = sc->sc_secbus; 1642 return (0); 1643 } 1644 return (ENOENT); 1645 } 1646 1647 static int 1648 pccbb_write_ivar(device_t brdev, device_t child, int which, uintptr_t value) 1649 { 1650 struct pccbb_softc *sc = device_get_softc(brdev); 1651 1652 switch (which) { 1653 case PCIB_IVAR_BUS: 1654 sc->sc_secbus = value; 1655 break; 1656 } 1657 return (ENOENT); 1658 } 1659 1660 /************************************************************************/ 1661 /* PCI compat methods */ 1662 /************************************************************************/ 1663 1664 static int 1665 pccbb_maxslots(device_t brdev) 1666 { 1667 return (0); 1668 } 1669 1670 static uint32_t 1671 pccbb_read_config(device_t brdev, int b, int s, int f, int reg, int width) 1672 { 1673 /* 1674 * Pass through to the next ppb up the chain (i.e. our grandparent). 1675 */ 1676 return (PCIB_READ_CONFIG(device_get_parent(device_get_parent(brdev)), 1677 b, s, f, reg, width)); 1678 } 1679 1680 static void 1681 pccbb_write_config(device_t brdev, int b, int s, int f, int reg, uint32_t val, 1682 int width) 1683 { 1684 /* 1685 * Pass through to the next ppb up the chain (i.e. our grandparent). 1686 */ 1687 PCIB_WRITE_CONFIG(device_get_parent(device_get_parent(brdev)), 1688 b, s, f, reg, val, width); 1689 } 1690 1691 static int 1692 pccbb_suspend(device_t self) 1693 { 1694 int error = 0; 1695 struct pccbb_softc* sc = device_get_softc(self); 1696 1697 bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intrhand); 1698 error = bus_generic_suspend(self); 1699 return (error); 1700 } 1701 1702 static int 1703 pccbb_resume(device_t self) 1704 { 1705 int error = 0; 1706 struct pccbb_softc *sc = (struct pccbb_softc *)device_get_softc(self); 1707 uint32_t tmp; 1708 1709 pci_write_config(self, PCCBBR_SOCKBASE, 1710 rman_get_start(sc->sc_base_res), 4); 1711 DEVPRINTF((self, "PCI Memory allocated: %08lx\n", 1712 rman_get_start(sc->sc_base_res))); 1713 1714 pccbb_chipinit(sc); 1715 1716 /* CSC Interrupt: Card detect interrupt on */ 1717 pccbb_setb(sc, PCCBB_SOCKET_MASK, PCCBB_SOCKET_MASK_CD); 1718 1719 /* reset interrupt */ 1720 tmp = pccbb_get(sc, PCCBB_SOCKET_EVENT); 1721 pccbb_set(sc, PCCBB_SOCKET_EVENT, tmp); 1722 1723 /* re-establish the interrupt. */ 1724 /* XXX INTR_TYPE_BIOS IS WRONG here */ 1725 if (bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO, pccbb_intr, sc, 1726 &sc->sc_intrhand)) { 1727 device_printf(self, "couldn't re-establish interrupt"); 1728 bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res); 1729 bus_release_resource(self, SYS_RES_MEMORY, PCCBBR_SOCKBASE, 1730 sc->sc_base_res); 1731 mtx_destroy(&sc->sc_mtx); 1732 error = ENOMEM; 1733 } 1734 bus_generic_resume(self); 1735 1736 /* wakeup thread */ 1737 if (!error) { 1738 mtx_lock(&sc->sc_mtx); 1739 wakeup(sc); 1740 mtx_unlock(&sc->sc_mtx); 1741 } 1742 return (error); 1743 } 1744 1745 static device_method_t pccbb_methods[] = { 1746 /* Device interface */ 1747 DEVMETHOD(device_probe, pccbb_probe), 1748 DEVMETHOD(device_attach, pccbb_attach), 1749 DEVMETHOD(device_detach, pccbb_detach), 1750 DEVMETHOD(device_shutdown, pccbb_shutdown), 1751 DEVMETHOD(device_suspend, pccbb_suspend), 1752 DEVMETHOD(device_resume, pccbb_resume), 1753 1754 /* bus methods */ 1755 DEVMETHOD(bus_print_child, bus_generic_print_child), 1756 DEVMETHOD(bus_read_ivar, pccbb_read_ivar), 1757 DEVMETHOD(bus_write_ivar, pccbb_write_ivar), 1758 DEVMETHOD(bus_alloc_resource, pccbb_alloc_resource), 1759 DEVMETHOD(bus_release_resource, pccbb_release_resource), 1760 DEVMETHOD(bus_activate_resource, pccbb_activate_resource), 1761 DEVMETHOD(bus_deactivate_resource, pccbb_deactivate_resource), 1762 DEVMETHOD(bus_driver_added, pccbb_driver_added), 1763 DEVMETHOD(bus_child_detached, pccbb_child_detached), 1764 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 1765 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 1766 1767 /* 16-bit card interface */ 1768 DEVMETHOD(card_set_res_flags, pccbb_pcic_set_res_flags), 1769 DEVMETHOD(card_set_memory_offset, pccbb_pcic_set_memory_offset), 1770 DEVMETHOD(card_reprobe_card, pccbb_card_reprobe), 1771 1772 /* power interface */ 1773 DEVMETHOD(power_enable_socket, pccbb_power_enable_socket), 1774 DEVMETHOD(power_disable_socket, pccbb_power_disable_socket), 1775 1776 /* pcib compatibility interface */ 1777 DEVMETHOD(pcib_maxslots, pccbb_maxslots), 1778 DEVMETHOD(pcib_read_config, pccbb_read_config), 1779 DEVMETHOD(pcib_write_config, pccbb_write_config), 1780 {0,0} 1781 }; 1782 1783 static driver_t pccbb_driver = { 1784 "pccbb", 1785 pccbb_methods, 1786 sizeof(struct pccbb_softc) 1787 }; 1788 1789 static devclass_t pccbb_devclass; 1790 1791 DRIVER_MODULE(pccbb, pci, pccbb_driver, pccbb_devclass, 0, 0); 1792 1793 SYSINIT(pccbb, SI_SUB_KTHREAD_IDLE, SI_ORDER_ANY, pccbb_start_threads, 0); 1794