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