FreeBSD/Linux Kernel Cross Reference
sys/dev/puc/puc_cfg.c
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2006 Marcel Moolenaar
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 *
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 ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/rman.h>
36 #include <sys/sysctl.h>
37
38 #include <dev/puc/puc_bus.h>
39 #include <dev/puc/puc_cfg.h>
40 #include <dev/puc/puc_bfe.h>
41
42 int
43 puc_config(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, intptr_t *r)
44 {
45 const struct puc_cfg *cfg = sc->sc_cfg;
46 int error;
47
48 if (cfg->config_function != NULL) {
49 error = cfg->config_function(sc, cmd, port, r);
50 if (!error)
51 return (0);
52 } else
53 error = EDOOFUS;
54
55 switch (cmd) {
56 case PUC_CFG_GET_CLOCK:
57 if (cfg->clock < 0)
58 return (error);
59 *r = cfg->clock;
60 return (0);
61 case PUC_CFG_GET_DESC:
62 if (cfg->desc == NULL)
63 return (error);
64 *r = (intptr_t)cfg->desc;
65 return (0);
66 case PUC_CFG_GET_ILR:
67 *r = PUC_ILR_NONE;
68 return (0);
69 case PUC_CFG_GET_LEN:
70 /* The length of bus space needed by the port. */
71 *r = 8;
72 return (0);
73 case PUC_CFG_GET_NPORTS:
74 /* The number of ports on this card. */
75 switch (cfg->ports) {
76 case PUC_PORT_NONSTANDARD:
77 return (error);
78 case PUC_PORT_1P:
79 case PUC_PORT_1S:
80 *r = 1;
81 return (0);
82 case PUC_PORT_1S1P:
83 case PUC_PORT_2P:
84 case PUC_PORT_2S:
85 *r = 2;
86 return (0);
87 case PUC_PORT_1S2P:
88 case PUC_PORT_2S1P:
89 case PUC_PORT_3S:
90 *r = 3;
91 return (0);
92 case PUC_PORT_4S:
93 *r = 4;
94 return (0);
95 case PUC_PORT_4S1P:
96 *r = 5;
97 return (0);
98 case PUC_PORT_6S:
99 *r = 6;
100 return (0);
101 case PUC_PORT_8S:
102 *r = 8;
103 return (0);
104 case PUC_PORT_12S:
105 *r = 12;
106 return (0);
107 case PUC_PORT_16S:
108 *r = 16;
109 return (0);
110 }
111 break;
112 case PUC_CFG_GET_OFS:
113 /* The offset relative to the RID. */
114 if (cfg->d_ofs < 0)
115 return (error);
116 *r = port * cfg->d_ofs;
117 return (0);
118 case PUC_CFG_GET_RID:
119 /* The RID for this port. */
120 if (port == 0) {
121 if (cfg->rid < 0)
122 return (error);
123 *r = cfg->rid;
124 return (0);
125 }
126 if (cfg->d_rid < 0)
127 return (error);
128 if (cfg->rid < 0) {
129 error = puc_config(sc, PUC_CFG_GET_RID, 0, r);
130 if (error)
131 return (error);
132 } else
133 *r = cfg->rid;
134 *r += port * cfg->d_rid;
135 return (0);
136 case PUC_CFG_GET_TYPE:
137 /* The type of this port. */
138 if (cfg->ports == PUC_PORT_NONSTANDARD)
139 return (error);
140 switch (port) {
141 case 0:
142 if (cfg->ports == PUC_PORT_1P ||
143 cfg->ports == PUC_PORT_2P)
144 *r = PUC_TYPE_PARALLEL;
145 else
146 *r = PUC_TYPE_SERIAL;
147 return (0);
148 case 1:
149 if (cfg->ports == PUC_PORT_1S1P ||
150 cfg->ports == PUC_PORT_1S2P ||
151 cfg->ports == PUC_PORT_2P)
152 *r = PUC_TYPE_PARALLEL;
153 else
154 *r = PUC_TYPE_SERIAL;
155 return (0);
156 case 2:
157 if (cfg->ports == PUC_PORT_1S2P ||
158 cfg->ports == PUC_PORT_2S1P)
159 *r = PUC_TYPE_PARALLEL;
160 else
161 *r = PUC_TYPE_SERIAL;
162 return (0);
163 case 4:
164 if (cfg->ports == PUC_PORT_4S1P)
165 *r = PUC_TYPE_PARALLEL;
166 else
167 *r = PUC_TYPE_SERIAL;
168 return (0);
169 }
170 *r = PUC_TYPE_SERIAL;
171 return (0);
172 case PUC_CFG_SETUP:
173 *r = ENXIO;
174 return (0);
175 }
176
177 return (ENXIO);
178 }
Cache object: 5e2dfaf09b8e130d54750837e1818c07
|