]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/stg/tmc18c30_subr.c
MFV r337195: 9454 ::zfs_blkstats should count embedded blocks
[FreeBSD/FreeBSD.git] / sys / dev / stg / tmc18c30_subr.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * [Ported for FreeBSD]
5  *  Copyright (c) 2000
6  *      Noriaki Mitsunaga, Mitsuru Iwasaki and Takanori Watanabe.
7  *      All rights reserved.
8  * [NetBSD for NEC PC-98 series]
9  *  Copyright (c) 1996, 1997, 1998
10  *      NetBSD/pc98 porting staff. All rights reserved.
11  *  Copyright (c) 1996, 1997, 1998
12  *      Naofumi HONDA. All rights reserved.
13  *  Copyright (c) 1996, 1997, 1998
14  *      Kouichi Matsuda. All rights reserved.
15  * 
16  *  Redistribution and use in source and binary forms, with or without
17  *  modification, are permitted provided that the following conditions
18  *  are met:
19  *  1. Redistributions of source code must retain the above copyright
20  *     notice, this list of conditions and the following disclaimer.
21  *  2. Redistributions in binary form must reproduce the above copyright
22  *     notice, this list of conditions and the following disclaimer in the
23  *     documentation and/or other materials provided with the distribution.
24  *  3. The name of the author may not be used to endorse or promote products
25  *     derived from this software without specific prior written permission.
26  * 
27  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
28  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
31  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
36  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  *
39  */
40
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/socket.h>
48
49 #include <sys/module.h>
50 #include <sys/bus.h>
51
52 #include <machine/bus.h>
53 #include <machine/resource.h>
54 #include <sys/rman.h> 
55
56 #include <cam/scsi/scsi_low.h>
57
58 #include <dev/stg/tmc18c30reg.h>
59 #include <dev/stg/tmc18c30var.h>
60 #include <dev/stg/tmc18c30.h>
61
62 #define STG_HOSTID      7
63
64 devclass_t stg_devclass;
65
66 int
67 stg_alloc_resource(device_t dev)
68 {
69         struct stg_softc *      sc = device_get_softc(dev);
70         rman_res_t              maddr, msize;
71         int                     error;
72
73         mtx_init(&sc->sc_sclow.sl_lock, "stg", NULL, MTX_DEF);
74         sc->port_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, 
75                                               &sc->port_rid, RF_ACTIVE);
76         if (sc->port_res == NULL) {
77                 stg_release_resource(dev);
78                 return(ENOMEM);
79         }
80
81         sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
82                                              RF_ACTIVE);
83         if (sc->irq_res == NULL) {
84                 stg_release_resource(dev);
85                 return(ENOMEM);
86         }
87         error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &maddr, &msize);
88         if (error) {
89                 return(0);      /* XXX */
90         }
91
92         /* no need to allocate memory if not configured */
93         if (maddr == 0 || msize == 0) {
94                 return(0);
95         }
96
97         sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
98                                              RF_ACTIVE);
99         if (sc->mem_res == NULL) {
100                 stg_release_resource(dev);
101                 return(ENOMEM);
102         }
103
104         return(0);
105 }
106
107 void
108 stg_release_resource(device_t dev)
109 {
110         struct stg_softc        *sc = device_get_softc(dev);
111
112         if (sc->stg_intrhand)
113                 bus_teardown_intr(dev, sc->irq_res, sc->stg_intrhand);
114         if (sc->port_res)
115                 bus_release_resource(dev, SYS_RES_IOPORT,
116                                      sc->port_rid, sc->port_res);
117         if (sc->irq_res)
118                 bus_release_resource(dev, SYS_RES_IRQ,
119                                      sc->irq_rid, sc->irq_res);
120         if (sc->mem_res)
121                 bus_release_resource(dev, SYS_RES_MEMORY,
122                                      sc->mem_rid, sc->mem_res);
123         mtx_destroy(&sc->sc_sclow.sl_lock);
124 }
125
126 int
127 stg_probe(device_t dev)
128 {
129         int rv;
130         struct stg_softc *sc = device_get_softc(dev);
131
132         rv = stgprobesubr(sc->port_res,
133                           device_get_flags(dev));
134
135         return rv;
136 }
137
138 int
139 stg_attach(device_t dev)
140 {
141         struct stg_softc *sc;
142         struct scsi_low_softc *slp;
143         u_int32_t flags = device_get_flags(dev);
144
145         sc = device_get_softc(dev);
146
147         slp = &sc->sc_sclow;
148         slp->sl_dev = dev;
149
150         slp->sl_hostid = STG_HOSTID;
151         slp->sl_cfgflags = flags;
152
153         stgattachsubr(sc);
154
155         return(STGIOSZ);
156 }
157
158 int
159 stg_detach(device_t dev)
160 {
161         struct stg_softc *sc = device_get_softc(dev);
162
163         scsi_low_deactivate(&sc->sc_sclow);
164         scsi_low_detach(&sc->sc_sclow);
165         stg_release_resource(dev);
166         return (0);
167 }
168
169 void
170 stg_intr(void *arg)
171 {
172         struct stg_softc *sc;
173
174         sc = arg;
175         SCSI_LOW_LOCK(&sc->sc_sclow);
176         stgintr(sc);
177         SCSI_LOW_UNLOCK(&sc->sc_sclow);
178 }