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