xref: /openbsd/sys/dev/cardbus/cardbus_map.c (revision 891d7ab6)
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