Deleted Added
full compact
uss820dci_atmelarm.c (184610) uss820dci_atmelarm.c (184824)
1#include <sys/cdefs.h>
1#include <sys/cdefs.h>
2__FBSDID("$FreeBSD: head/sys/dev/usb2/controller/uss820dci_atmelarm.c 184610 2008-11-04 02:31:03Z alfred $");
2__FBSDID("$FreeBSD: head/sys/dev/usb2/controller/uss820dci_atmelarm.c 184824 2008-11-10 20:54:31Z thompsa $");
3
4/*-
5 * Copyright (c) 2008 Hans Petter Selasky <hselasky@freebsd.org>
6 * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <dev/usb2/include/usb2_mfunc.h>
31#include <dev/usb2/include/usb2_defs.h>
32#include <dev/usb2/include/usb2_standard.h>
33
34#include <dev/usb2/core/usb2_core.h>
35#include <dev/usb2/core/usb2_busdma.h>
36#include <dev/usb2/core/usb2_process.h>
37#include <dev/usb2/core/usb2_config_td.h>
38#include <dev/usb2/core/usb2_sw_transfer.h>
39#include <dev/usb2/core/usb2_util.h>
40
41#include <dev/usb2/controller/usb2_controller.h>
42#include <dev/usb2/controller/usb2_bus.h>
43#include <dev/usb2/controller/uss820dci.h>
44
45#include <sys/rman.h>
46
47static device_probe_t uss820_atmelarm_probe;
48static device_attach_t uss820_atmelarm_attach;
49static device_detach_t uss820_atmelarm_detach;
50static device_suspend_t uss820_atmelarm_suspend;
51static device_resume_t uss820_atmelarm_resume;
52static device_shutdown_t uss820_atmelarm_shutdown;
53
54static device_method_t uss820dci_methods[] = {
55 /* Device interface */
56 DEVMETHOD(device_probe, uss820_atmelarm_probe),
57 DEVMETHOD(device_attach, uss820_atmelarm_attach),
58 DEVMETHOD(device_detach, uss820_atmelarm_detach),
59 DEVMETHOD(device_suspend, uss820_atmelarm_suspend),
60 DEVMETHOD(device_resume, uss820_atmelarm_resume),
61 DEVMETHOD(device_shutdown, uss820_atmelarm_shutdown),
62
63 /* Bus interface */
64 DEVMETHOD(bus_print_child, bus_generic_print_child),
65
66 {0, 0}
67};
68
69static driver_t uss820dci_driver = {
70 .name = "uss820",
71 .methods = uss820dci_methods,
72 .size = sizeof(struct uss820dci_softc),
73};
74
75static devclass_t uss820dci_devclass;
76
77DRIVER_MODULE(uss820, atmelarm, uss820dci_driver, uss820dci_devclass, 0, 0);
78MODULE_DEPEND(uss820, usb2_controller, 1, 1, 1);
79MODULE_DEPEND(uss820, usb2_core, 1, 1, 1);
80
81static const char *const uss820_desc = "USS820 USB Device Controller";
82
83static int
84uss820_atmelarm_suspend(device_t dev)
85{
86 struct uss820dci_softc *sc = device_get_softc(dev);
87 int err;
88
89 err = bus_generic_suspend(dev);
90 if (err == 0) {
91 uss820dci_suspend(sc);
92 }
93 return (err);
94}
95
96static int
97uss820_atmelarm_resume(device_t dev)
98{
99 struct uss820dci_softc *sc = device_get_softc(dev);
100 int err;
101
102 uss820dci_resume(sc);
103
104 err = bus_generic_resume(dev);
105
106 return (err);
107}
108
109static int
110uss820_atmelarm_shutdown(device_t dev)
111{
112 struct uss820dci_softc *sc = device_get_softc(dev);
113 int err;
114
115 err = bus_generic_shutdown(dev);
116 if (err)
117 return (err);
118
119 uss820dci_uninit(sc);
120
121 return (0);
122}
123
124static int
125uss820_atmelarm_probe(device_t dev)
126{
127 device_set_desc(dev, uss820_desc);
128 return (0); /* success */
129}
130
131static int
132uss820_atmelarm_attach(device_t dev)
133{
134 struct uss820dci_softc *sc = device_get_softc(dev);
135 int err;
136 int rid;
137
138 if (sc == NULL) {
139 return (ENXIO);
140 }
141 /* get all DMA memory */
142
143 if (usb2_bus_mem_alloc_all(&sc->sc_bus,
144 USB_GET_DMA_TAG(dev), NULL)) {
145 return (ENOMEM);
146 }
147 rid = 0;
148 sc->sc_io_res =
149 bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
150
151 if (!sc->sc_io_res) {
152 goto error;
153 }
154 sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
155 sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
156 sc->sc_io_size = rman_get_size(sc->sc_io_res);
157
158 /* multiply all addresses by 4 */
159 sc->sc_reg_shift = 2;
160
161 rid = 0;
162 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
163 RF_SHAREABLE | RF_ACTIVE);
164 if (sc->sc_irq_res == NULL) {
165 goto error;
166 }
167 sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
168 if (!(sc->sc_bus.bdev)) {
169 goto error;
170 }
171 device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
172
173 err = usb2_config_td_setup(&sc->sc_config_td, sc,
3
4/*-
5 * Copyright (c) 2008 Hans Petter Selasky <hselasky@freebsd.org>
6 * 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <dev/usb2/include/usb2_mfunc.h>
31#include <dev/usb2/include/usb2_defs.h>
32#include <dev/usb2/include/usb2_standard.h>
33
34#include <dev/usb2/core/usb2_core.h>
35#include <dev/usb2/core/usb2_busdma.h>
36#include <dev/usb2/core/usb2_process.h>
37#include <dev/usb2/core/usb2_config_td.h>
38#include <dev/usb2/core/usb2_sw_transfer.h>
39#include <dev/usb2/core/usb2_util.h>
40
41#include <dev/usb2/controller/usb2_controller.h>
42#include <dev/usb2/controller/usb2_bus.h>
43#include <dev/usb2/controller/uss820dci.h>
44
45#include <sys/rman.h>
46
47static device_probe_t uss820_atmelarm_probe;
48static device_attach_t uss820_atmelarm_attach;
49static device_detach_t uss820_atmelarm_detach;
50static device_suspend_t uss820_atmelarm_suspend;
51static device_resume_t uss820_atmelarm_resume;
52static device_shutdown_t uss820_atmelarm_shutdown;
53
54static device_method_t uss820dci_methods[] = {
55 /* Device interface */
56 DEVMETHOD(device_probe, uss820_atmelarm_probe),
57 DEVMETHOD(device_attach, uss820_atmelarm_attach),
58 DEVMETHOD(device_detach, uss820_atmelarm_detach),
59 DEVMETHOD(device_suspend, uss820_atmelarm_suspend),
60 DEVMETHOD(device_resume, uss820_atmelarm_resume),
61 DEVMETHOD(device_shutdown, uss820_atmelarm_shutdown),
62
63 /* Bus interface */
64 DEVMETHOD(bus_print_child, bus_generic_print_child),
65
66 {0, 0}
67};
68
69static driver_t uss820dci_driver = {
70 .name = "uss820",
71 .methods = uss820dci_methods,
72 .size = sizeof(struct uss820dci_softc),
73};
74
75static devclass_t uss820dci_devclass;
76
77DRIVER_MODULE(uss820, atmelarm, uss820dci_driver, uss820dci_devclass, 0, 0);
78MODULE_DEPEND(uss820, usb2_controller, 1, 1, 1);
79MODULE_DEPEND(uss820, usb2_core, 1, 1, 1);
80
81static const char *const uss820_desc = "USS820 USB Device Controller";
82
83static int
84uss820_atmelarm_suspend(device_t dev)
85{
86 struct uss820dci_softc *sc = device_get_softc(dev);
87 int err;
88
89 err = bus_generic_suspend(dev);
90 if (err == 0) {
91 uss820dci_suspend(sc);
92 }
93 return (err);
94}
95
96static int
97uss820_atmelarm_resume(device_t dev)
98{
99 struct uss820dci_softc *sc = device_get_softc(dev);
100 int err;
101
102 uss820dci_resume(sc);
103
104 err = bus_generic_resume(dev);
105
106 return (err);
107}
108
109static int
110uss820_atmelarm_shutdown(device_t dev)
111{
112 struct uss820dci_softc *sc = device_get_softc(dev);
113 int err;
114
115 err = bus_generic_shutdown(dev);
116 if (err)
117 return (err);
118
119 uss820dci_uninit(sc);
120
121 return (0);
122}
123
124static int
125uss820_atmelarm_probe(device_t dev)
126{
127 device_set_desc(dev, uss820_desc);
128 return (0); /* success */
129}
130
131static int
132uss820_atmelarm_attach(device_t dev)
133{
134 struct uss820dci_softc *sc = device_get_softc(dev);
135 int err;
136 int rid;
137
138 if (sc == NULL) {
139 return (ENXIO);
140 }
141 /* get all DMA memory */
142
143 if (usb2_bus_mem_alloc_all(&sc->sc_bus,
144 USB_GET_DMA_TAG(dev), NULL)) {
145 return (ENOMEM);
146 }
147 rid = 0;
148 sc->sc_io_res =
149 bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
150
151 if (!sc->sc_io_res) {
152 goto error;
153 }
154 sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
155 sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
156 sc->sc_io_size = rman_get_size(sc->sc_io_res);
157
158 /* multiply all addresses by 4 */
159 sc->sc_reg_shift = 2;
160
161 rid = 0;
162 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
163 RF_SHAREABLE | RF_ACTIVE);
164 if (sc->sc_irq_res == NULL) {
165 goto error;
166 }
167 sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
168 if (!(sc->sc_bus.bdev)) {
169 goto error;
170 }
171 device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
172
173 err = usb2_config_td_setup(&sc->sc_config_td, sc,
174 &sc->sc_bus.mtx, NULL, 0, 4);
174 &sc->sc_bus.bus_mtx, NULL, 0, 4);
175 if (err) {
176 device_printf(dev, "could not setup config thread!\n");
177 goto error;
178 }
179#if (__FreeBSD_version >= 700031)
180 err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
181 NULL, (void *)uss820dci_interrupt, sc, &sc->sc_intr_hdl);
182#else
183 err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
184 (void *)uss820dci_interrupt, sc, &sc->sc_intr_hdl);
185#endif
186 if (err) {
187 sc->sc_intr_hdl = NULL;
188 goto error;
189 }
190 err = uss820dci_init(sc);
191 if (err) {
192 device_printf(dev, "Init failed\n");
193 goto error;
194 }
195 err = device_probe_and_attach(sc->sc_bus.bdev);
196 if (err) {
197 device_printf(dev, "USB probe and attach failed\n");
198 goto error;
199 }
200 return (0);
201
202error:
203 uss820_atmelarm_detach(dev);
204 return (ENXIO);
205}
206
207static int
208uss820_atmelarm_detach(device_t dev)
209{
210 struct uss820dci_softc *sc = device_get_softc(dev);
211 device_t bdev;
212 int err;
213
214 if (sc->sc_bus.bdev) {
215 bdev = sc->sc_bus.bdev;
216 device_detach(bdev);
217 device_delete_child(dev, bdev);
218 }
219 /* during module unload there are lots of children leftover */
220 device_delete_all_children(dev);
221
222 if (sc->sc_irq_res && sc->sc_intr_hdl) {
223 /*
224 * only call at91_udp_uninit() after at91_udp_init()
225 */
226 uss820dci_uninit(sc);
227
228 err = bus_teardown_intr(dev, sc->sc_irq_res,
229 sc->sc_intr_hdl);
230 sc->sc_intr_hdl = NULL;
231 }
232 if (sc->sc_irq_res) {
233 bus_release_resource(dev, SYS_RES_IRQ, 0,
234 sc->sc_irq_res);
235 sc->sc_irq_res = NULL;
236 }
237 if (sc->sc_io_res) {
238 bus_release_resource(dev, SYS_RES_IOPORT, 0,
239 sc->sc_io_res);
240 sc->sc_io_res = NULL;
241 }
242 usb2_config_td_unsetup(&sc->sc_config_td);
243
244 usb2_bus_mem_free_all(&sc->sc_bus, NULL);
245
246 return (0);
247}
175 if (err) {
176 device_printf(dev, "could not setup config thread!\n");
177 goto error;
178 }
179#if (__FreeBSD_version >= 700031)
180 err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
181 NULL, (void *)uss820dci_interrupt, sc, &sc->sc_intr_hdl);
182#else
183 err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
184 (void *)uss820dci_interrupt, sc, &sc->sc_intr_hdl);
185#endif
186 if (err) {
187 sc->sc_intr_hdl = NULL;
188 goto error;
189 }
190 err = uss820dci_init(sc);
191 if (err) {
192 device_printf(dev, "Init failed\n");
193 goto error;
194 }
195 err = device_probe_and_attach(sc->sc_bus.bdev);
196 if (err) {
197 device_printf(dev, "USB probe and attach failed\n");
198 goto error;
199 }
200 return (0);
201
202error:
203 uss820_atmelarm_detach(dev);
204 return (ENXIO);
205}
206
207static int
208uss820_atmelarm_detach(device_t dev)
209{
210 struct uss820dci_softc *sc = device_get_softc(dev);
211 device_t bdev;
212 int err;
213
214 if (sc->sc_bus.bdev) {
215 bdev = sc->sc_bus.bdev;
216 device_detach(bdev);
217 device_delete_child(dev, bdev);
218 }
219 /* during module unload there are lots of children leftover */
220 device_delete_all_children(dev);
221
222 if (sc->sc_irq_res && sc->sc_intr_hdl) {
223 /*
224 * only call at91_udp_uninit() after at91_udp_init()
225 */
226 uss820dci_uninit(sc);
227
228 err = bus_teardown_intr(dev, sc->sc_irq_res,
229 sc->sc_intr_hdl);
230 sc->sc_intr_hdl = NULL;
231 }
232 if (sc->sc_irq_res) {
233 bus_release_resource(dev, SYS_RES_IRQ, 0,
234 sc->sc_irq_res);
235 sc->sc_irq_res = NULL;
236 }
237 if (sc->sc_io_res) {
238 bus_release_resource(dev, SYS_RES_IOPORT, 0,
239 sc->sc_io_res);
240 sc->sc_io_res = NULL;
241 }
242 usb2_config_td_unsetup(&sc->sc_config_td);
243
244 usb2_bus_mem_free_all(&sc->sc_bus, NULL);
245
246 return (0);
247}