]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/vmd/vmd_bus.c
MFV r353608: 10165 libzpool: passing argument 1 to restrict-qualified parameter
[FreeBSD/FreeBSD.git] / sys / dev / vmd / vmd_bus.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright 2019 Cisco Systems, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the 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
20  * FOR 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
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/bus.h>
35 #include <sys/conf.h>
36 #include <sys/kernel.h>
37 #include <sys/module.h>
38 #include <sys/systm.h>
39 #include <sys/malloc.h>
40
41 #include <machine/bus.h>
42 #include <machine/resource.h>
43 #include <sys/rman.h>
44 #include <sys/taskqueue.h>
45
46 #include <sys/pciio.h>
47 #include <dev/pci/pcivar.h>
48 #include <dev/pci/pcireg.h>
49 #include <dev/pci/pci_private.h>
50 #include <dev/pci/pcib_private.h>
51 #include <dev/pci/pci_host_generic.h>
52 #include <dev/vmd/vmd.h>
53
54 #include "pcib_if.h"
55 #include "pci_if.h"
56
57 static int
58 vmd_bus_probe(device_t dev)
59 {
60         device_set_desc(dev, "VMD bus");
61
62         return (-1000);
63 }
64
65 /* PCI interface. */
66
67 static int
68 vmd_bus_attach(device_t dev)
69 {
70         struct vmd_softc *sc;
71         struct pci_devinfo *dinfo;
72         rman_res_t start, end;
73         int b, s, f;
74
75         sc = device_get_softc(device_get_parent(dev));
76
77         /* Start at max PCI vmd_domain and work down */
78         b = s = f = 0;
79         dinfo = pci_read_device(device_get_parent(dev), dev,
80              PCI_DOMAINMAX - device_get_unit(device_get_parent(dev)),
81              b, s, f);
82         if (dinfo == NULL) {
83                 device_printf(dev, "Cannot allocate dinfo!\n");
84                 return (ENOENT);
85         }
86
87         pci_add_child(dev, dinfo);
88
89         start = rman_get_start(sc->vmd_regs_resource[1]);
90         end = rman_get_end(sc->vmd_regs_resource[1]);
91         resource_list_add_next(&dinfo->resources, SYS_RES_MEMORY, start, end,
92             end - start + 1);
93
94         start = rman_get_start(sc->vmd_io_resource);
95         end = rman_get_end(sc->vmd_io_resource);
96         resource_list_add_next(&dinfo->resources, SYS_RES_IOPORT, start, end,
97             end - start + 1);
98  
99         bus_generic_attach(dev);
100
101         return (0);
102 }
103
104 static int
105 vmd_bus_detach(device_t dev)
106 {
107         struct pci_devinfo *dinfo;
108         int b, s, f;
109
110         device_delete_children(dev);
111
112         b = s = f = 0;
113         dinfo = pci_read_device(device_get_parent(dev), dev,
114             PCI_DOMAINMAX - device_get_unit(device_get_parent(dev)),
115             b, s, f);
116         if (dinfo == NULL) {
117                 resource_list_free(&dinfo->resources);
118         }
119         return (0);
120 }
121
122 static int
123 vmd_bus_adjust_resource(device_t dev, device_t child, int type,
124     struct resource *r, rman_res_t start, rman_res_t end)
125 {
126         struct resource *res = r;
127         if (type == SYS_RES_MEMORY) {
128                 /* VMD device controls this */
129                 return (0);
130         }
131
132         return (bus_generic_adjust_resource(dev, child, type, res, start, end));
133 }
134
135 static int
136 vmd_bus_release_resource(device_t dev, device_t child, int type, int rid,
137     struct resource *r)
138 {
139         if (type == SYS_RES_MEMORY) {
140                 /* VMD device controls this */
141                 return (0);
142         }
143
144         return (pci_release_resource(dev, child, type, rid, r));
145 }
146
147 static struct resource *
148 vmd_bus_alloc_resource(device_t dev, device_t child, int type, int *rid,
149     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
150 {
151         struct vmd_softc *sc;
152
153         sc = device_get_softc(device_get_parent(dev));
154
155         if (type == SYS_RES_MEMORY) {
156                 /* remap to VMD resources */
157                 if (*rid == PCIR_MEMBASE_1) {
158                         return (sc->vmd_regs_resource[1]);
159                 } else  if (*rid == PCIR_PMBASEL_1) {
160                         return (sc->vmd_regs_resource[2]);
161                 } else {
162                         return (sc->vmd_regs_resource[2]);
163                 }
164         }
165         return (pci_alloc_resource(dev, child, type, rid, start, end,
166            count, flags));
167 }
168
169 static int
170 vmd_bus_shutdown(device_t dev)
171 {
172         return (0);
173 }
174
175 static device_method_t vmd_bus_pci_methods[] = {
176         /* Device interface */
177         DEVMETHOD(device_probe,         vmd_bus_probe),
178         DEVMETHOD(device_attach,        vmd_bus_attach),
179         DEVMETHOD(device_detach,        vmd_bus_detach),
180         DEVMETHOD(device_shutdown,      vmd_bus_shutdown),
181
182         /* Bus interface */
183         DEVMETHOD(bus_alloc_resource,   vmd_bus_alloc_resource),
184         DEVMETHOD(bus_adjust_resource,  vmd_bus_adjust_resource),
185         DEVMETHOD(bus_release_resource, vmd_bus_release_resource),
186
187         /* pci interface */
188         DEVMETHOD(pci_read_config,      pci_read_config_method),
189         DEVMETHOD(pci_write_config,     pci_write_config_method),
190         DEVMETHOD(pci_alloc_devinfo,    pci_alloc_devinfo_method),
191
192         DEVMETHOD_END
193 };
194
195 static devclass_t vmd_bus_devclass;
196
197 DEFINE_CLASS_1(vmd_bus, vmd_bus_pci_driver, vmd_bus_pci_methods,
198     sizeof(struct pci_softc), pci_driver);
199
200 DRIVER_MODULE(vmd_bus, vmd, vmd_bus_pci_driver, vmd_bus_devclass, NULL, NULL);
201 MODULE_VERSION(vmd_bus, 1);