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