1 /* $OpenBSD: cardbus_map.c,v 1.14 2010/03/27 23:36:36 jsg Exp $ */ 2 /* $NetBSD: cardbus_map.c,v 1.10 2000/03/07 00:31:46 mycroft Exp $ */ 3 4 /* 5 * Copyright (c) 1999 and 2000 6 * HAYAKAWA Koichi. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/device.h> 35 36 #include <machine/bus.h> 37 38 #include <dev/cardbus/cardbusvar.h> 39 40 #include <dev/pci/pcireg.h> /* XXX */ 41 42 #if defined DEBUG && !defined CARDBUS_MAP_DEBUG 43 #define CARDBUS_MAP_DEBUG 44 #endif 45 46 #if defined CARDBUS_MAP_DEBUG 47 #define STATIC 48 #define DPRINTF(a) printf a 49 #else 50 #ifdef DDB 51 #define STATIC 52 #else 53 #define STATIC static 54 #endif 55 #define DPRINTF(a) 56 #endif 57 58 /* 59 * int cardbus_mapreg_map(struct cardbus_softc *, int, int, pcireg_t, 60 * int bus_space_tag_t *, bus_space_handle_t *, 61 * bus_addr_t *, bus_size_t *) 62 * This function maps bus-space on the value of Base Address 63 * Register (BAR) indexed by the argument `reg' (the second argument). 64 * When the value of the BAR is not valid, such as 0x00000000, a new 65 * address should be allocated for the BAR and new address values is 66 * written on the BAR. 67 */ 68 int 69 cardbus_mapreg_map(struct cardbus_softc *sc, int func, int reg, 70 pcireg_t type, int busflags, bus_space_tag_t *tagp, 71 bus_space_handle_t *handlep, bus_addr_t *basep, bus_size_t *sizep) 72 { 73 cardbus_chipset_tag_t cc = sc->sc_cc; 74 pci_chipset_tag_t pc = sc->sc_pc; 75 cardbus_function_tag_t cf = sc->sc_cf; 76 bus_space_tag_t bustag; 77 rbus_tag_t rbustag; 78 bus_space_handle_t handle; 79 bus_addr_t base; 80 bus_size_t size; 81 int flags; 82 int status = 0; 83 84 pcitag_t tag = pci_make_tag(pc, sc->sc_bus, 85 sc->sc_device, func); 86 87 DPRINTF(("cardbus_mapreg_map called: %s %x\n", sc->sc_dev.dv_xname, 88 type)); 89 90 if (pci_mapreg_info(pc, tag, reg, type, &base, &size, &flags)) 91 status = 1; 92 93 if (PCI_MAPREG_TYPE(type) == PCI_MAPREG_TYPE_IO) { 94 bustag = sc->sc_iot; 95 rbustag = sc->sc_rbus_iot; 96 } else { 97 bustag = sc->sc_memt; 98 rbustag = sc->sc_rbus_memt; 99 } 100 if (status == 0) { 101 bus_addr_t mask = size - 1; 102 if (base != 0) 103 mask = 0xffffffff; 104 if ((*cf->cardbus_space_alloc)(cc, rbustag, base, size, mask, 105 size, busflags | flags, &base, &handle)) { 106 panic("io alloc"); 107 } 108 } 109 pci_conf_write(pc, tag, reg, base); 110 111 DPRINTF(("cardbus_mapreg_map: physaddr %lx\n", (unsigned long)base)); 112 113 if (tagp != 0) 114 *tagp = bustag; 115 if (handlep != 0) 116 *handlep = handle; 117 if (basep != 0) 118 *basep = base; 119 if (sizep != 0) 120 *sizep = size; 121 122 return (0); 123 } 124 125 /* 126 * int cardbus_mapreg_unmap(struct cardbus_softc *sc, int func, int reg, 127 * bus_space_tag_t tag, bus_space_handle_t handle, 128 * bus_size_t size) 129 * 130 * This function releases bus-space region and close memory or io 131 * window on the bridge. 132 * 133 * Arguments: 134 * struct cardbus_softc *sc; the pointer to the device structure of cardbus. 135 * int func; the number of function on the device. 136 * int reg; the offset of BAR register. 137 */ 138 int 139 cardbus_mapreg_unmap(struct cardbus_softc *sc, int func, int reg, 140 bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t size) 141 { 142 cardbus_chipset_tag_t cc = sc->sc_cc; 143 pci_chipset_tag_t pc = sc->sc_pc; 144 cardbus_function_tag_t cf = sc->sc_cf; 145 int st = 1; 146 pcitag_t cardbustag; 147 rbus_tag_t rbustag; 148 149 if (sc->sc_iot == tag) { 150 /* bus space is io space */ 151 DPRINTF(("%s: unmap i/o space\n", sc->sc_dev.dv_xname)); 152 rbustag = sc->sc_rbus_iot; 153 } else if (sc->sc_memt == tag) { 154 /* bus space is memory space */ 155 DPRINTF(("%s: unmap mem space\n", sc->sc_dev.dv_xname)); 156 rbustag = sc->sc_rbus_memt; 157 } else 158 return (1); 159 160 cardbustag = pci_make_tag(pc, sc->sc_bus, sc->sc_device, func); 161 162 pci_conf_write(pc, cardbustag, reg, 0); 163 164 (*cf->cardbus_space_free)(cc, rbustag, handle, size); 165 166 return (st); 167 } 168