Print this page
13026 SMB and NFS use the global zone's IDMAP when they shouldn't
Change-Id: I3b5f7bc68bb77764aa7cb59a48dd1740a8387ccf
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/sun4u/chicago/io/fpc/fpc-impl-4u.c
+++ new/usr/src/uts/sun4u/chicago/io/fpc/fpc-impl-4u.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
|
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 +/*
28 + * Copyright 2020 Nexenta by DDN, Inc. All rights reserved.
29 + */
30 +
27 31 #include <sys/file.h>
28 32 #include <sys/sunndi.h>
29 33 #include <sys/sunddi.h>
30 34 #include <sys/sunldi.h>
31 35 #include <io/px/px_regs.h>
32 36 #include <sys/pci_tools.h>
33 37 #include <fpc.h>
34 38 #include <fpc-impl.h>
35 39
36 40 #define CHIP_COMPATIBLE_NAME "pciex108e,80f0"
37 41 #define BANK_ADDR_MASK 0x7FFFFF
38 42
39 43 #define OPEN_FLAGS (FREAD | FWRITE)
40 44
41 45 #define PCIE_BANK 0
42 46 #define JBUS_BANK 1
43 47
44 48 typedef struct px_regs {
45 49 uint32_t addr_hi;
46 50 uint32_t addr_lo;
47 51 uint32_t size_hi;
48 52 uint32_t size_lo;
49 53 } px_regs_t;
50 54
51 55 /* There is one of these for every root nexus device found */
52 56 typedef struct fire4u_specific {
53 57 char *nodename;
54 58 uintptr_t jbus_bank_base;
55 59 } fire4u_specific_t;
56 60
57 61 typedef struct fire_counter_handle_impl {
58 62 ldi_handle_t devhandle;
59 63 fire4u_specific_t *devspec; /* Points to proper one for specific dev. */
60 64 } fire_counter_handle_impl_t;
61 65
62 66 static uint64_t counter_select_offsets[] = {
63 67 JBC_PERFORMANCE_COUNTER_SELECT,
64 68 IMU_PERFORMANCE_COUNTER_SELECT,
65 69 MMU_PERFORMANCE_COUNTER_SELECT,
66 70 TLU_PERFORMANCE_COUNTER_SELECT,
67 71 LPU_LINK_PERFORMANCE_COUNTER_SELECT
68 72 };
69 73
70 74 /*
71 75 * The following event and offset arrays is organized by grouping in major
72 76 * order the fire_perfcnt_t register types, and in minor order the register
73 77 * numbers within that type.
74 78 */
75 79
76 80 static uint64_t counter_reg_offsets[] = {
77 81 JBC_PERFORMANCE_COUNTER_ZERO,
78 82 JBC_PERFORMANCE_COUNTER_ONE,
79 83 IMU_PERFORMANCE_COUNTER_ZERO,
80 84 IMU_PERFORMANCE_COUNTER_ONE,
81 85 MMU_PERFORMANCE_COUNTER_ZERO,
82 86 MMU_PERFORMANCE_COUNTER_ONE,
83 87 TLU_PERFORMANCE_COUNTER_ZERO,
84 88 TLU_PERFORMANCE_COUNTER_ONE,
85 89 TLU_PERFORMANCE_COUNTER_TWO,
86 90 LPU_LINK_PERFORMANCE_COUNTER1,
87 91 LPU_LINK_PERFORMANCE_COUNTER2
88 92 };
89 93
90 94 /*
91 95 * Add the following to one of the LPU_LINK_PERFORMANCE_COUNTERx offsets to
92 96 * write a value to that counter.
93 97 */
|
↓ open down ↓ |
57 lines elided |
↑ open up ↑ |
94 98 #define LPU_LINK_PERFCTR_WRITE_OFFSET 0x8
95 99
96 100 /*
97 101 * Note that LPU_LINK_PERFORMANCE_COUNTER_CONTROL register is hard-reset to
98 102 * zeros and this is the value we want. This register isn't touched by this
99 103 * module, and as long as it remains untouched by other modules we're OK.
100 104 */
101 105
102 106 static ldi_ident_t ldi_identifier;
103 107 static boolean_t ldi_identifier_valid = B_FALSE;
104 -static cred_t *credentials = NULL;
105 108
106 109 /* Called by _init to determine if it is OK to install driver. */
107 110 int
108 111 fpc_platform_check()
109 112 {
110 113 return (SUCCESS);
111 114 }
112 115
113 116 /* Called during attach to do module-wide initialization. */
114 117 int
115 118 fpc_platform_module_init(dev_info_t *dip)
116 119 {
117 120 int status;
118 121
119 - credentials = crget();
120 122 status = ldi_ident_from_dip(dip, &ldi_identifier);
121 123 if (status == 0)
122 124 ldi_identifier_valid = B_TRUE;
123 125 return ((status == 0) ? DDI_SUCCESS : DDI_FAILURE);
124 126 }
125 127
126 128 int
127 129 fpc_platform_node_init(dev_info_t *dip, int *avail)
128 130 {
129 131 int index;
130 132 char *name;
131 133 int nodename_size;
132 134 char *nodename = NULL;
133 135 fire4u_specific_t *platform_specific_data = NULL;
134 136 char *compatible = NULL;
135 137 px_regs_t *regs_p = NULL;
136 138 int regs_length = 0;
137 139
138 140 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
139 141 "compatible", &compatible) != DDI_PROP_SUCCESS)
140 142 return (DDI_SUCCESS);
141 143
142 144 if (strcmp(compatible, CHIP_COMPATIBLE_NAME) != 0) {
143 145 ddi_prop_free(compatible);
144 146 return (DDI_SUCCESS);
145 147 }
146 148 ddi_prop_free(compatible);
147 149
148 150 fpc_common_node_setup(dip, &index);
149 151
150 152 name = fpc_get_dev_name_by_number(index);
151 153 nodename_size = strlen(name) + strlen(PCI_MINOR_REG) + 2;
152 154 nodename = kmem_zalloc(nodename_size, KM_SLEEP);
153 155
154 156 platform_specific_data =
155 157 kmem_zalloc(sizeof (fire4u_specific_t), KM_SLEEP);
156 158
157 159 (void) strcpy(nodename, name);
158 160 (void) strcat(nodename, ":");
159 161 (void) strcat(nodename, PCI_MINOR_REG);
160 162 platform_specific_data->nodename = nodename;
161 163
162 164 /* Get register banks. */
163 165 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
164 166 "reg", (caddr_t)®s_p, ®s_length) != DDI_SUCCESS) {
165 167 goto bad_regs_p;
166 168 }
167 169
168 170 if ((regs_length / sizeof (px_regs_t)) < 2) {
169 171 goto bad_regs_length;
170 172 }
171 173
172 174 platform_specific_data->jbus_bank_base =
173 175 regs_p[JBUS_BANK].addr_lo & BANK_ADDR_MASK;
174 176
175 177 kmem_free(regs_p, regs_length);
176 178
177 179 if (index == 0)
178 180 *avail |= (PCIE_A_REGS_AVAIL | JBUS_REGS_AVAIL);
179 181 else
180 182 *avail |= PCIE_B_REGS_AVAIL;
181 183
182 184 (void) fpc_set_platform_data_by_number(index, platform_specific_data);
183 185
184 186 return (DDI_SUCCESS);
185 187
186 188 bad_regs_length:
187 189 if (regs_p)
188 190 kmem_free(regs_p, regs_length);
189 191 bad_regs_p:
190 192 kmem_free(platform_specific_data, sizeof (fire4u_specific_t));
191 193 if (nodename)
192 194 kmem_free(nodename, nodename_size);
193 195
194 196 return (DDI_FAILURE);
195 197 }
196 198
197 199 void
198 200 fpc_platform_node_fini(void *arg)
199 201 {
200 202 fire4u_specific_t *plat_arg = (fire4u_specific_t *)arg;
201 203 if (plat_arg == NULL)
202 204 return;
203 205 if (plat_arg->nodename)
|
↓ open down ↓ |
74 lines elided |
↑ open up ↑ |
204 206 kmem_free(plat_arg->nodename, strlen(plat_arg->nodename)+1);
205 207 kmem_free(plat_arg, sizeof (fire4u_specific_t));
206 208 }
207 209
208 210 /*ARGSUSED*/
209 211 void
210 212 fpc_platform_module_fini(dev_info_t *dip)
211 213 {
212 214 if (ldi_identifier_valid)
213 215 ldi_ident_release(ldi_identifier);
214 - if (credentials)
215 - crfree(credentials);
216 216 }
217 217
218 218 fire_perfreg_handle_t
219 219 fpc_get_perfreg_handle(int devnum)
220 220 {
221 221 int rval = EINVAL;
222 222
223 223 fire_counter_handle_impl_t *handle_impl =
224 224 kmem_zalloc(sizeof (fire_counter_handle_impl_t), KM_SLEEP);
225 225
226 226 if ((handle_impl->devspec =
227 227 fpc_get_platform_data_by_number(devnum)) != NULL) {
228 228 rval = ldi_open_by_name(handle_impl->devspec->nodename,
229 - OPEN_FLAGS, credentials, &handle_impl->devhandle,
229 + OPEN_FLAGS, kcred, &handle_impl->devhandle,
230 230 ldi_identifier);
231 231 }
232 232
233 233 if (rval != SUCCESS) {
234 234 kmem_free(handle_impl, sizeof (fire_counter_handle_impl_t));
235 235 return ((fire_perfreg_handle_t)-1);
236 236 } else {
237 237 return ((fire_perfreg_handle_t)handle_impl);
238 238 }
239 239 }
240 240
241 241 int
242 242 fpc_free_counter_handle(fire_perfreg_handle_t handle)
243 243 {
244 244 fire_counter_handle_impl_t *handle_impl =
245 245 (fire_counter_handle_impl_t *)handle;
246 - (void) ldi_close(handle_impl->devhandle, OPEN_FLAGS, credentials);
246 + (void) ldi_close(handle_impl->devhandle, OPEN_FLAGS, kcred);
247 247 kmem_free(handle_impl, sizeof (fire_counter_handle_impl_t));
248 248 return (SUCCESS);
249 249 }
250 250
251 251 int
252 252 fpc_event_io(fire_perfreg_handle_t handle, fire_perfcnt_t group,
253 253 uint64_t *reg_data, boolean_t is_write)
254 254 {
255 255 int rval;
256 256 int ioctl_rval;
257 257 pcitool_reg_t prg;
258 258 fire_counter_handle_impl_t *handle_impl =
259 259 (fire_counter_handle_impl_t *)handle;
260 260 int cmd = is_write ? PCITOOL_NEXUS_SET_REG : PCITOOL_NEXUS_GET_REG;
261 261
262 262 prg.user_version = PCITOOL_VERSION;
263 263
264 264 if (group == jbc) {
265 265 prg.barnum = JBUS_BANK;
266 266 prg.offset = counter_select_offsets[group] -
267 267 handle_impl->devspec->jbus_bank_base;
268 268 } else {
269 269 prg.barnum = PCIE_BANK;
270 270
271 271 /*
272 272 * Note that a pcie_bank_base isn't needed. Pcie register
273 273 * offsets are already relative to the start of their bank. No
|
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
274 274 * base needs to be subtracted to get the relative offset that
275 275 * pcitool ioctls want.
276 276 */
277 277 prg.offset = counter_select_offsets[group];
278 278 }
279 279 prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_8 | PCITOOL_ACC_ATTR_ENDN_BIG;
280 280 prg.data = *reg_data;
281 281
282 282 /* Read original value. */
283 283 if (((rval = ldi_ioctl(handle_impl->devhandle, cmd, (intptr_t)&prg,
284 - FKIOCTL, credentials, &ioctl_rval)) == SUCCESS) && (!is_write)) {
284 + FKIOCTL, kcred, &ioctl_rval)) == SUCCESS) && (!is_write)) {
285 285 *reg_data = prg.data;
286 286 }
287 287
288 288 return (rval);
289 289 }
290 290
291 291 int
292 292 fpc_counter_io(fire_perfreg_handle_t handle, fire_perfcnt_t group,
293 293 int counter_index, uint64_t *value, boolean_t is_write)
294 294 {
295 295 int rval;
296 296 int ioctl_rval;
297 297 pcitool_reg_t prg;
298 298 fire_counter_handle_impl_t *handle_impl =
299 299 (fire_counter_handle_impl_t *)handle;
300 300 int command =
301 301 (is_write) ? PCITOOL_NEXUS_SET_REG : PCITOOL_NEXUS_GET_REG;
302 302
303 303 prg.user_version = PCITOOL_VERSION;
304 304 /*
305 305 * Note that stated PCIE offsets are relative to the beginning of their
306 306 * register bank, while JBUS offsets are absolute.
307 307 */
308 308 if (group == jbc) {
309 309 prg.barnum = JBUS_BANK;
310 310 prg.offset = counter_reg_offsets[counter_index] -
311 311 handle_impl->devspec->jbus_bank_base;
312 312 } else {
313 313 prg.barnum = PCIE_BANK;
314 314 prg.offset = counter_reg_offsets[counter_index];
|
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
315 315 }
316 316
317 317 if ((group == lpu) && (is_write)) {
318 318 prg.offset += LPU_LINK_PERFCTR_WRITE_OFFSET;
319 319 }
320 320
321 321 prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_8 | PCITOOL_ACC_ATTR_ENDN_BIG;
322 322 prg.data = *value;
323 323
324 324 if (((rval = ldi_ioctl(handle_impl->devhandle, command, (intptr_t)&prg,
325 - FKIOCTL, credentials, &ioctl_rval)) == SUCCESS) && (!is_write)) {
325 + FKIOCTL, kcred, &ioctl_rval)) == SUCCESS) && (!is_write)) {
326 326 *value = prg.data;
327 327 }
328 328
329 329 return (rval);
330 330 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX