Print this page
13026 SMB and NFS use the global zone's IDMAP when they shouldn't
Change-Id: I3b5f7bc68bb77764aa7cb59a48dd1740a8387ccf


   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 




  27 #include <sys/file.h>
  28 #include <sys/sunndi.h>
  29 #include <sys/sunddi.h>
  30 #include <sys/sunldi.h>
  31 #include <io/px/px_regs.h>
  32 #include <sys/pci_tools.h>
  33 #include <fpc.h>
  34 #include <fpc-impl.h>
  35 
  36 #define CHIP_COMPATIBLE_NAME    "pciex108e,80f0"
  37 #define BANK_ADDR_MASK          0x7FFFFF
  38 
  39 #define OPEN_FLAGS (FREAD | FWRITE)
  40 
  41 #define PCIE_BANK       0
  42 #define JBUS_BANK       1
  43 
  44 typedef struct px_regs {
  45         uint32_t addr_hi;
  46         uint32_t addr_lo;


  84         TLU_PERFORMANCE_COUNTER_ONE,
  85         TLU_PERFORMANCE_COUNTER_TWO,
  86         LPU_LINK_PERFORMANCE_COUNTER1,
  87         LPU_LINK_PERFORMANCE_COUNTER2
  88 };
  89 
  90 /*
  91  * Add the following to one of the LPU_LINK_PERFORMANCE_COUNTERx offsets to
  92  * write a value to that counter.
  93  */
  94 #define LPU_LINK_PERFCTR_WRITE_OFFSET   0x8
  95 
  96 /*
  97  * Note that LPU_LINK_PERFORMANCE_COUNTER_CONTROL register is hard-reset to
  98  * zeros and this is the value we want.  This register isn't touched by this
  99  * module, and as long as it remains untouched by other modules we're OK.
 100  */
 101 
 102 static ldi_ident_t ldi_identifier;
 103 static boolean_t ldi_identifier_valid = B_FALSE;
 104 static cred_t *credentials = NULL;
 105 
 106 /* Called by _init to determine if it is OK to install driver. */
 107 int
 108 fpc_platform_check()
 109 {
 110         return (SUCCESS);
 111 }
 112 
 113 /* Called during attach to do module-wide initialization. */
 114 int
 115 fpc_platform_module_init(dev_info_t *dip)
 116 {
 117         int status;
 118 
 119         credentials = crget();
 120         status = ldi_ident_from_dip(dip, &ldi_identifier);
 121         if (status == 0)
 122                 ldi_identifier_valid = B_TRUE;
 123         return ((status == 0) ? DDI_SUCCESS : DDI_FAILURE);
 124 }
 125 
 126 int
 127 fpc_platform_node_init(dev_info_t *dip, int *avail)
 128 {
 129         int index;
 130         char *name;
 131         int nodename_size;
 132         char *nodename = NULL;
 133         fire4u_specific_t *platform_specific_data = NULL;
 134         char *compatible = NULL;
 135         px_regs_t *regs_p = NULL;
 136         int regs_length = 0;
 137 
 138         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
 139             "compatible", &compatible) != DDI_PROP_SUCCESS)


 194         return (DDI_FAILURE);
 195 }
 196 
 197 void
 198 fpc_platform_node_fini(void *arg)
 199 {
 200         fire4u_specific_t *plat_arg = (fire4u_specific_t *)arg;
 201         if (plat_arg == NULL)
 202                 return;
 203         if (plat_arg->nodename)
 204                 kmem_free(plat_arg->nodename, strlen(plat_arg->nodename)+1);
 205         kmem_free(plat_arg, sizeof (fire4u_specific_t));
 206 }
 207 
 208 /*ARGSUSED*/
 209 void
 210 fpc_platform_module_fini(dev_info_t *dip)
 211 {
 212         if (ldi_identifier_valid)
 213                 ldi_ident_release(ldi_identifier);
 214         if (credentials)
 215                 crfree(credentials);
 216 }
 217 
 218 fire_perfreg_handle_t
 219 fpc_get_perfreg_handle(int devnum)
 220 {
 221         int rval = EINVAL;
 222 
 223         fire_counter_handle_impl_t *handle_impl =
 224             kmem_zalloc(sizeof (fire_counter_handle_impl_t), KM_SLEEP);
 225 
 226         if ((handle_impl->devspec =
 227             fpc_get_platform_data_by_number(devnum)) != NULL) {
 228                 rval = ldi_open_by_name(handle_impl->devspec->nodename,
 229                     OPEN_FLAGS, credentials, &handle_impl->devhandle,
 230                     ldi_identifier);
 231         }
 232 
 233         if (rval != SUCCESS) {
 234                 kmem_free(handle_impl, sizeof (fire_counter_handle_impl_t));
 235                 return ((fire_perfreg_handle_t)-1);
 236         } else {
 237                 return ((fire_perfreg_handle_t)handle_impl);
 238         }
 239 }
 240 
 241 int
 242 fpc_free_counter_handle(fire_perfreg_handle_t handle)
 243 {
 244         fire_counter_handle_impl_t *handle_impl =
 245             (fire_counter_handle_impl_t *)handle;
 246         (void) ldi_close(handle_impl->devhandle, OPEN_FLAGS, credentials);
 247         kmem_free(handle_impl, sizeof (fire_counter_handle_impl_t));
 248         return (SUCCESS);
 249 }
 250 
 251 int
 252 fpc_event_io(fire_perfreg_handle_t handle, fire_perfcnt_t group,
 253     uint64_t *reg_data, boolean_t is_write)
 254 {
 255         int rval;
 256         int ioctl_rval;
 257         pcitool_reg_t prg;
 258         fire_counter_handle_impl_t *handle_impl =
 259             (fire_counter_handle_impl_t *)handle;
 260         int cmd = is_write ? PCITOOL_NEXUS_SET_REG : PCITOOL_NEXUS_GET_REG;
 261 
 262         prg.user_version = PCITOOL_VERSION;
 263 
 264         if (group == jbc) {
 265                 prg.barnum = JBUS_BANK;
 266                 prg.offset = counter_select_offsets[group] -
 267                     handle_impl->devspec->jbus_bank_base;
 268         } else {
 269                 prg.barnum = PCIE_BANK;
 270 
 271                 /*
 272                  * Note that a pcie_bank_base isn't needed.  Pcie register
 273                  * offsets are already relative to the start of their bank.  No
 274                  * base needs to be subtracted to get the relative offset that
 275                  * pcitool ioctls want.
 276                  */
 277                 prg.offset = counter_select_offsets[group];
 278         }
 279         prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_8 | PCITOOL_ACC_ATTR_ENDN_BIG;
 280         prg.data = *reg_data;
 281 
 282         /* Read original value. */
 283         if (((rval = ldi_ioctl(handle_impl->devhandle, cmd, (intptr_t)&prg,
 284             FKIOCTL, credentials, &ioctl_rval)) == SUCCESS) && (!is_write)) {
 285                 *reg_data = prg.data;
 286         }
 287 
 288         return (rval);
 289 }
 290 
 291 int
 292 fpc_counter_io(fire_perfreg_handle_t handle, fire_perfcnt_t group,
 293     int counter_index, uint64_t *value, boolean_t is_write)
 294 {
 295         int rval;
 296         int ioctl_rval;
 297         pcitool_reg_t prg;
 298         fire_counter_handle_impl_t *handle_impl =
 299             (fire_counter_handle_impl_t *)handle;
 300         int command =
 301             (is_write) ? PCITOOL_NEXUS_SET_REG : PCITOOL_NEXUS_GET_REG;
 302 
 303         prg.user_version = PCITOOL_VERSION;
 304         /*
 305          * Note that stated PCIE offsets are relative to the beginning of their
 306          * register bank, while JBUS offsets are absolute.
 307          */
 308         if (group == jbc) {
 309                 prg.barnum = JBUS_BANK;
 310                 prg.offset = counter_reg_offsets[counter_index] -
 311                     handle_impl->devspec->jbus_bank_base;
 312         } else {
 313                 prg.barnum = PCIE_BANK;
 314                 prg.offset = counter_reg_offsets[counter_index];
 315         }
 316 
 317         if ((group == lpu) && (is_write)) {
 318                 prg.offset += LPU_LINK_PERFCTR_WRITE_OFFSET;
 319         }
 320 
 321         prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_8 | PCITOOL_ACC_ATTR_ENDN_BIG;
 322         prg.data = *value;
 323 
 324         if (((rval = ldi_ioctl(handle_impl->devhandle, command, (intptr_t)&prg,
 325             FKIOCTL, credentials, &ioctl_rval)) == SUCCESS) && (!is_write)) {
 326                 *value = prg.data;
 327         }
 328 
 329         return (rval);
 330 }


   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2020 Nexenta by DDN, Inc. All rights reserved.
  29  */
  30 
  31 #include <sys/file.h>
  32 #include <sys/sunndi.h>
  33 #include <sys/sunddi.h>
  34 #include <sys/sunldi.h>
  35 #include <io/px/px_regs.h>
  36 #include <sys/pci_tools.h>
  37 #include <fpc.h>
  38 #include <fpc-impl.h>
  39 
  40 #define CHIP_COMPATIBLE_NAME    "pciex108e,80f0"
  41 #define BANK_ADDR_MASK          0x7FFFFF
  42 
  43 #define OPEN_FLAGS (FREAD | FWRITE)
  44 
  45 #define PCIE_BANK       0
  46 #define JBUS_BANK       1
  47 
  48 typedef struct px_regs {
  49         uint32_t addr_hi;
  50         uint32_t addr_lo;


  88         TLU_PERFORMANCE_COUNTER_ONE,
  89         TLU_PERFORMANCE_COUNTER_TWO,
  90         LPU_LINK_PERFORMANCE_COUNTER1,
  91         LPU_LINK_PERFORMANCE_COUNTER2
  92 };
  93 
  94 /*
  95  * Add the following to one of the LPU_LINK_PERFORMANCE_COUNTERx offsets to
  96  * write a value to that counter.
  97  */
  98 #define LPU_LINK_PERFCTR_WRITE_OFFSET   0x8
  99 
 100 /*
 101  * Note that LPU_LINK_PERFORMANCE_COUNTER_CONTROL register is hard-reset to
 102  * zeros and this is the value we want.  This register isn't touched by this
 103  * module, and as long as it remains untouched by other modules we're OK.
 104  */
 105 
 106 static ldi_ident_t ldi_identifier;
 107 static boolean_t ldi_identifier_valid = B_FALSE;

 108 
 109 /* Called by _init to determine if it is OK to install driver. */
 110 int
 111 fpc_platform_check()
 112 {
 113         return (SUCCESS);
 114 }
 115 
 116 /* Called during attach to do module-wide initialization. */
 117 int
 118 fpc_platform_module_init(dev_info_t *dip)
 119 {
 120         int status;
 121 

 122         status = ldi_ident_from_dip(dip, &ldi_identifier);
 123         if (status == 0)
 124                 ldi_identifier_valid = B_TRUE;
 125         return ((status == 0) ? DDI_SUCCESS : DDI_FAILURE);
 126 }
 127 
 128 int
 129 fpc_platform_node_init(dev_info_t *dip, int *avail)
 130 {
 131         int index;
 132         char *name;
 133         int nodename_size;
 134         char *nodename = NULL;
 135         fire4u_specific_t *platform_specific_data = NULL;
 136         char *compatible = NULL;
 137         px_regs_t *regs_p = NULL;
 138         int regs_length = 0;
 139 
 140         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
 141             "compatible", &compatible) != DDI_PROP_SUCCESS)


 196         return (DDI_FAILURE);
 197 }
 198 
 199 void
 200 fpc_platform_node_fini(void *arg)
 201 {
 202         fire4u_specific_t *plat_arg = (fire4u_specific_t *)arg;
 203         if (plat_arg == NULL)
 204                 return;
 205         if (plat_arg->nodename)
 206                 kmem_free(plat_arg->nodename, strlen(plat_arg->nodename)+1);
 207         kmem_free(plat_arg, sizeof (fire4u_specific_t));
 208 }
 209 
 210 /*ARGSUSED*/
 211 void
 212 fpc_platform_module_fini(dev_info_t *dip)
 213 {
 214         if (ldi_identifier_valid)
 215                 ldi_ident_release(ldi_identifier);


 216 }
 217 
 218 fire_perfreg_handle_t
 219 fpc_get_perfreg_handle(int devnum)
 220 {
 221         int rval = EINVAL;
 222 
 223         fire_counter_handle_impl_t *handle_impl =
 224             kmem_zalloc(sizeof (fire_counter_handle_impl_t), KM_SLEEP);
 225 
 226         if ((handle_impl->devspec =
 227             fpc_get_platform_data_by_number(devnum)) != NULL) {
 228                 rval = ldi_open_by_name(handle_impl->devspec->nodename,
 229                     OPEN_FLAGS, kcred, &handle_impl->devhandle,
 230                     ldi_identifier);
 231         }
 232 
 233         if (rval != SUCCESS) {
 234                 kmem_free(handle_impl, sizeof (fire_counter_handle_impl_t));
 235                 return ((fire_perfreg_handle_t)-1);
 236         } else {
 237                 return ((fire_perfreg_handle_t)handle_impl);
 238         }
 239 }
 240 
 241 int
 242 fpc_free_counter_handle(fire_perfreg_handle_t handle)
 243 {
 244         fire_counter_handle_impl_t *handle_impl =
 245             (fire_counter_handle_impl_t *)handle;
 246         (void) ldi_close(handle_impl->devhandle, OPEN_FLAGS, kcred);
 247         kmem_free(handle_impl, sizeof (fire_counter_handle_impl_t));
 248         return (SUCCESS);
 249 }
 250 
 251 int
 252 fpc_event_io(fire_perfreg_handle_t handle, fire_perfcnt_t group,
 253     uint64_t *reg_data, boolean_t is_write)
 254 {
 255         int rval;
 256         int ioctl_rval;
 257         pcitool_reg_t prg;
 258         fire_counter_handle_impl_t *handle_impl =
 259             (fire_counter_handle_impl_t *)handle;
 260         int cmd = is_write ? PCITOOL_NEXUS_SET_REG : PCITOOL_NEXUS_GET_REG;
 261 
 262         prg.user_version = PCITOOL_VERSION;
 263 
 264         if (group == jbc) {
 265                 prg.barnum = JBUS_BANK;
 266                 prg.offset = counter_select_offsets[group] -
 267                     handle_impl->devspec->jbus_bank_base;
 268         } else {
 269                 prg.barnum = PCIE_BANK;
 270 
 271                 /*
 272                  * Note that a pcie_bank_base isn't needed.  Pcie register
 273                  * offsets are already relative to the start of their bank.  No
 274                  * base needs to be subtracted to get the relative offset that
 275                  * pcitool ioctls want.
 276                  */
 277                 prg.offset = counter_select_offsets[group];
 278         }
 279         prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_8 | PCITOOL_ACC_ATTR_ENDN_BIG;
 280         prg.data = *reg_data;
 281 
 282         /* Read original value. */
 283         if (((rval = ldi_ioctl(handle_impl->devhandle, cmd, (intptr_t)&prg,
 284             FKIOCTL, kcred, &ioctl_rval)) == SUCCESS) && (!is_write)) {
 285                 *reg_data = prg.data;
 286         }
 287 
 288         return (rval);
 289 }
 290 
 291 int
 292 fpc_counter_io(fire_perfreg_handle_t handle, fire_perfcnt_t group,
 293     int counter_index, uint64_t *value, boolean_t is_write)
 294 {
 295         int rval;
 296         int ioctl_rval;
 297         pcitool_reg_t prg;
 298         fire_counter_handle_impl_t *handle_impl =
 299             (fire_counter_handle_impl_t *)handle;
 300         int command =
 301             (is_write) ? PCITOOL_NEXUS_SET_REG : PCITOOL_NEXUS_GET_REG;
 302 
 303         prg.user_version = PCITOOL_VERSION;
 304         /*
 305          * Note that stated PCIE offsets are relative to the beginning of their
 306          * register bank, while JBUS offsets are absolute.
 307          */
 308         if (group == jbc) {
 309                 prg.barnum = JBUS_BANK;
 310                 prg.offset = counter_reg_offsets[counter_index] -
 311                     handle_impl->devspec->jbus_bank_base;
 312         } else {
 313                 prg.barnum = PCIE_BANK;
 314                 prg.offset = counter_reg_offsets[counter_index];
 315         }
 316 
 317         if ((group == lpu) && (is_write)) {
 318                 prg.offset += LPU_LINK_PERFCTR_WRITE_OFFSET;
 319         }
 320 
 321         prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_8 | PCITOOL_ACC_ATTR_ENDN_BIG;
 322         prg.data = *value;
 323 
 324         if (((rval = ldi_ioctl(handle_impl->devhandle, command, (intptr_t)&prg,
 325             FKIOCTL, kcred, &ioctl_rval)) == SUCCESS) && (!is_write)) {
 326                 *value = prg.data;
 327         }
 328 
 329         return (rval);
 330 }