xref: /openbsd/sys/dev/cardbus/cardbus_map.c (revision 09467b48)
1 /*	$OpenBSD: cardbus_map.c,v 1.15 2015/03/14 03:38:47 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 
35 #include <machine/bus.h>
36 
37 #include <dev/cardbus/cardbusvar.h>
38 
39 #include <dev/pci/pcireg.h>	/* XXX */
40 
41 #if defined DEBUG && !defined CARDBUS_MAP_DEBUG
42 #define CARDBUS_MAP_DEBUG
43 #endif
44 
45 #if defined CARDBUS_MAP_DEBUG
46 #define STATIC
47 #define DPRINTF(a) printf a
48 #else
49 #ifdef DDB
50 #define STATIC
51 #else
52 #define STATIC static
53 #endif
54 #define DPRINTF(a)
55 #endif
56 
57 /*
58  * int cardbus_mapreg_map(struct cardbus_softc *, int, int, pcireg_t,
59  *			  int bus_space_tag_t *, bus_space_handle_t *,
60  *			  bus_addr_t *, bus_size_t *)
61  *    This function maps bus-space on the value of Base Address
62  *   Register (BAR) indexed by the argument `reg' (the second argument).
63  *   When the value of the BAR is not valid, such as 0x00000000, a new
64  *   address should be allocated for the BAR and new address values is
65  *   written on the BAR.
66  */
67 int
68 cardbus_mapreg_map(struct cardbus_softc *sc, int func, int reg,
69     pcireg_t type, int busflags, bus_space_tag_t *tagp,
70     bus_space_handle_t *handlep, bus_addr_t *basep, bus_size_t *sizep)
71 {
72 	cardbus_chipset_tag_t cc = sc->sc_cc;
73 	pci_chipset_tag_t pc = sc->sc_pc;
74 	cardbus_function_tag_t cf = sc->sc_cf;
75 	bus_space_tag_t bustag;
76 	rbus_tag_t rbustag;
77 	bus_space_handle_t handle;
78 	bus_addr_t base;
79 	bus_size_t size;
80 	int flags;
81 	int status = 0;
82 
83 	pcitag_t tag = pci_make_tag(pc, sc->sc_bus,
84 	    sc->sc_device, func);
85 
86 	DPRINTF(("cardbus_mapreg_map called: %s %x\n", sc->sc_dev.dv_xname,
87 	   type));
88 
89 	if (pci_mapreg_info(pc, tag, reg, type, &base, &size, &flags))
90 		status = 1;
91 
92 	if (PCI_MAPREG_TYPE(type) == PCI_MAPREG_TYPE_IO) {
93 		bustag = sc->sc_iot;
94 		rbustag = sc->sc_rbus_iot;
95 	} else {
96 		bustag = sc->sc_memt;
97 		rbustag = sc->sc_rbus_memt;
98 	}
99 	if (status == 0) {
100 		bus_addr_t mask = size - 1;
101 		if (base != 0)
102 			mask = 0xffffffff;
103 		if ((*cf->cardbus_space_alloc)(cc, rbustag, base, size, mask,
104 		    size, busflags | flags, &base, &handle)) {
105 			panic("io alloc");
106 		}
107 	}
108 	pci_conf_write(pc, tag, reg, base);
109 
110 	DPRINTF(("cardbus_mapreg_map: physaddr %lx\n", (unsigned long)base));
111 
112 	if (tagp != 0)
113 		*tagp = bustag;
114 	if (handlep != 0)
115 		*handlep = handle;
116 	if (basep != 0)
117 		*basep = base;
118 	if (sizep != 0)
119 		*sizep = size;
120 
121 	return (0);
122 }
123 
124 /*
125  * int cardbus_mapreg_unmap(struct cardbus_softc *sc, int func, int reg,
126  *			    bus_space_tag_t tag, bus_space_handle_t handle,
127  *			    bus_size_t size)
128  *
129  *   This function releases bus-space region and close memory or io
130  *   window on the bridge.
131  *
132  *  Arguments:
133  *   struct cardbus_softc *sc; the pointer to the device structure of cardbus.
134  *   int func; the number of function on the device.
135  *   int reg; the offset of BAR register.
136  */
137 int
138 cardbus_mapreg_unmap(struct cardbus_softc *sc, int func, int reg,
139     bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t size)
140 {
141 	cardbus_chipset_tag_t cc = sc->sc_cc;
142 	pci_chipset_tag_t pc = sc->sc_pc;
143 	cardbus_function_tag_t cf = sc->sc_cf;
144 	int st = 1;
145 	pcitag_t cardbustag;
146 	rbus_tag_t rbustag;
147 
148 	if (sc->sc_iot == tag) {
149 		/* bus space is io space */
150 		DPRINTF(("%s: unmap i/o space\n", sc->sc_dev.dv_xname));
151 		rbustag = sc->sc_rbus_iot;
152 	} else if (sc->sc_memt == tag) {
153 		/* bus space is memory space */
154 		DPRINTF(("%s: unmap mem space\n", sc->sc_dev.dv_xname));
155 		rbustag = sc->sc_rbus_memt;
156 	} else
157 		return (1);
158 
159 	cardbustag = pci_make_tag(pc, sc->sc_bus, sc->sc_device, func);
160 
161 	pci_conf_write(pc, cardbustag, reg, 0);
162 
163 	(*cf->cardbus_space_free)(cc, rbustag, handle, size);
164 
165 	return (st);
166 }
167