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