1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/file.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/errno.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/open.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/cred.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/conf.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/modctl.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/ddi.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/policy.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/pool.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/pool_impl.h> 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate /* 44*7c478bd9Sstevel@tonic-gate * The kernel pools subsystem is accessed and manipulated through the pool 45*7c478bd9Sstevel@tonic-gate * device, which has two minor nodes /dev/pool, and /dev/poolctl. User 46*7c478bd9Sstevel@tonic-gate * processes can comminicate with pools through ioctls on these devices. 47*7c478bd9Sstevel@tonic-gate * 48*7c478bd9Sstevel@tonic-gate * The poolctl device (POOL_CTL_PARENT) can be used to modify and take 49*7c478bd9Sstevel@tonic-gate * snapshot of the current configuration. Only one process on the system 50*7c478bd9Sstevel@tonic-gate * can have it open at any given time. This device is also used to enable 51*7c478bd9Sstevel@tonic-gate * or disable pools. If pools are disabled, the pool driver can be unloaded 52*7c478bd9Sstevel@tonic-gate * and completely removed from the system. 53*7c478bd9Sstevel@tonic-gate * 54*7c478bd9Sstevel@tonic-gate * The pool "info" device (POOL_INFO_PARENT) can only be used to obtain 55*7c478bd9Sstevel@tonic-gate * snapshots of the current configuration and change/query pool bindings. 56*7c478bd9Sstevel@tonic-gate * While some reconfiguration transaction via the poolctl device is in 57*7c478bd9Sstevel@tonic-gate * progress, all processes using this "info" device will be provided with 58*7c478bd9Sstevel@tonic-gate * the snapshot taken at the beginning of that transaction. 59*7c478bd9Sstevel@tonic-gate */ 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate #define POOL_CTL_PARENT 0 62*7c478bd9Sstevel@tonic-gate #define POOL_INFO_PARENT 1 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate static dev_info_t *pool_devi; /* pool device information */ 65*7c478bd9Sstevel@tonic-gate static int pool_openctl; /* poolctl device is already open */ 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 68*7c478bd9Sstevel@tonic-gate static int 69*7c478bd9Sstevel@tonic-gate pool_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 70*7c478bd9Sstevel@tonic-gate { 71*7c478bd9Sstevel@tonic-gate int error = DDI_FAILURE; 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate switch (infocmd) { 74*7c478bd9Sstevel@tonic-gate case DDI_INFO_DEVT2DEVINFO: 75*7c478bd9Sstevel@tonic-gate *result = pool_devi; 76*7c478bd9Sstevel@tonic-gate error = DDI_SUCCESS; 77*7c478bd9Sstevel@tonic-gate break; 78*7c478bd9Sstevel@tonic-gate case DDI_INFO_DEVT2INSTANCE: 79*7c478bd9Sstevel@tonic-gate /* 80*7c478bd9Sstevel@tonic-gate * All dev_t's map to the same, single instance. 81*7c478bd9Sstevel@tonic-gate */ 82*7c478bd9Sstevel@tonic-gate *result = NULL; 83*7c478bd9Sstevel@tonic-gate error = DDI_SUCCESS; 84*7c478bd9Sstevel@tonic-gate break; 85*7c478bd9Sstevel@tonic-gate default: 86*7c478bd9Sstevel@tonic-gate break; 87*7c478bd9Sstevel@tonic-gate } 88*7c478bd9Sstevel@tonic-gate return (error); 89*7c478bd9Sstevel@tonic-gate } 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate static int 92*7c478bd9Sstevel@tonic-gate pool_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 93*7c478bd9Sstevel@tonic-gate { 94*7c478bd9Sstevel@tonic-gate int ret = DDI_SUCCESS; 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate switch (cmd) { 97*7c478bd9Sstevel@tonic-gate case DDI_DETACH: 98*7c478bd9Sstevel@tonic-gate pool_lock(); 99*7c478bd9Sstevel@tonic-gate if (pool_state == POOL_ENABLED) { 100*7c478bd9Sstevel@tonic-gate ret = DDI_FAILURE; 101*7c478bd9Sstevel@tonic-gate pool_unlock(); 102*7c478bd9Sstevel@tonic-gate break; 103*7c478bd9Sstevel@tonic-gate } 104*7c478bd9Sstevel@tonic-gate ddi_remove_minor_node(devi, NULL); 105*7c478bd9Sstevel@tonic-gate pool_devi = NULL; 106*7c478bd9Sstevel@tonic-gate pool_unlock(); 107*7c478bd9Sstevel@tonic-gate break; 108*7c478bd9Sstevel@tonic-gate default: 109*7c478bd9Sstevel@tonic-gate ret = DDI_FAILURE; 110*7c478bd9Sstevel@tonic-gate } 111*7c478bd9Sstevel@tonic-gate return (ret); 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate static int 115*7c478bd9Sstevel@tonic-gate pool_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 116*7c478bd9Sstevel@tonic-gate { 117*7c478bd9Sstevel@tonic-gate switch (cmd) { 118*7c478bd9Sstevel@tonic-gate case DDI_ATTACH: 119*7c478bd9Sstevel@tonic-gate if (pool_devi != NULL) 120*7c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 121*7c478bd9Sstevel@tonic-gate if (ddi_create_minor_node(devi, "poolctl", S_IFCHR, 122*7c478bd9Sstevel@tonic-gate POOL_CTL_PARENT, DDI_PSEUDO, 0) == DDI_FAILURE || 123*7c478bd9Sstevel@tonic-gate ddi_create_minor_node(devi, "pool", S_IFCHR, 124*7c478bd9Sstevel@tonic-gate POOL_INFO_PARENT, DDI_PSEUDO, 0) == DDI_FAILURE) { 125*7c478bd9Sstevel@tonic-gate ddi_remove_minor_node(devi, NULL); 126*7c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 127*7c478bd9Sstevel@tonic-gate } 128*7c478bd9Sstevel@tonic-gate pool_devi = devi; 129*7c478bd9Sstevel@tonic-gate ddi_report_dev(devi); 130*7c478bd9Sstevel@tonic-gate break; 131*7c478bd9Sstevel@tonic-gate case DDI_RESUME: 132*7c478bd9Sstevel@tonic-gate break; 133*7c478bd9Sstevel@tonic-gate default: 134*7c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 135*7c478bd9Sstevel@tonic-gate } 136*7c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate } 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate /* 141*7c478bd9Sstevel@tonic-gate * There is only one instance of the pool control device, poolctl, 142*7c478bd9Sstevel@tonic-gate * and multiple instances of the pool info device, pool. 143*7c478bd9Sstevel@tonic-gate */ 144*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 145*7c478bd9Sstevel@tonic-gate static int 146*7c478bd9Sstevel@tonic-gate pool_open(dev_t *devp, int flag, int otype, cred_t *credp) 147*7c478bd9Sstevel@tonic-gate { 148*7c478bd9Sstevel@tonic-gate minor_t minor = getminor(*devp); 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate if (otype != OTYP_CHR) 151*7c478bd9Sstevel@tonic-gate return (EINVAL); 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate switch (minor) { 154*7c478bd9Sstevel@tonic-gate case POOL_CTL_PARENT: 155*7c478bd9Sstevel@tonic-gate if (secpolicy_pool(CRED()) != 0) 156*7c478bd9Sstevel@tonic-gate return (EPERM); 157*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) 158*7c478bd9Sstevel@tonic-gate return (EINTR); 159*7c478bd9Sstevel@tonic-gate if (pool_openctl == 1) { 160*7c478bd9Sstevel@tonic-gate pool_unlock(); 161*7c478bd9Sstevel@tonic-gate return (EBUSY); 162*7c478bd9Sstevel@tonic-gate } 163*7c478bd9Sstevel@tonic-gate pool_openctl = 1; 164*7c478bd9Sstevel@tonic-gate pool_unlock(); 165*7c478bd9Sstevel@tonic-gate break; 166*7c478bd9Sstevel@tonic-gate case POOL_INFO_PARENT: 167*7c478bd9Sstevel@tonic-gate break; 168*7c478bd9Sstevel@tonic-gate default: 169*7c478bd9Sstevel@tonic-gate return (ENXIO); 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate return (0); 172*7c478bd9Sstevel@tonic-gate } 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 175*7c478bd9Sstevel@tonic-gate static int 176*7c478bd9Sstevel@tonic-gate pool_close(dev_t dev, int flag, int otype, cred_t *credp) 177*7c478bd9Sstevel@tonic-gate { 178*7c478bd9Sstevel@tonic-gate if (otype != OTYP_CHR) 179*7c478bd9Sstevel@tonic-gate return (EINVAL); 180*7c478bd9Sstevel@tonic-gate if (getminor(dev) == 0) { 181*7c478bd9Sstevel@tonic-gate /* 182*7c478bd9Sstevel@tonic-gate * We could be closing the poolctl device without finishing 183*7c478bd9Sstevel@tonic-gate * the commit transaction first, so do that now. 184*7c478bd9Sstevel@tonic-gate */ 185*7c478bd9Sstevel@tonic-gate pool_lock(); 186*7c478bd9Sstevel@tonic-gate (void) pool_commit(0); /* cannot fail since arg is 0 */ 187*7c478bd9Sstevel@tonic-gate pool_openctl = 0; 188*7c478bd9Sstevel@tonic-gate pool_unlock(); 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate return (0); 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate /* 194*7c478bd9Sstevel@tonic-gate * Main pool interface. 195*7c478bd9Sstevel@tonic-gate */ 196*7c478bd9Sstevel@tonic-gate /* ARGSUSED4 */ 197*7c478bd9Sstevel@tonic-gate static int 198*7c478bd9Sstevel@tonic-gate pool_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, 199*7c478bd9Sstevel@tonic-gate int *rvalp) 200*7c478bd9Sstevel@tonic-gate { 201*7c478bd9Sstevel@tonic-gate pool_xtransfer_t xtransfer; 202*7c478bd9Sstevel@tonic-gate pool_transfer_t transfer; 203*7c478bd9Sstevel@tonic-gate pool_destroy_t destroy; 204*7c478bd9Sstevel@tonic-gate pool_propget_t propget; 205*7c478bd9Sstevel@tonic-gate pool_propput_t propput; 206*7c478bd9Sstevel@tonic-gate pool_proprm_t proprm; 207*7c478bd9Sstevel@tonic-gate pool_status_t status; 208*7c478bd9Sstevel@tonic-gate pool_dissoc_t dissoc; 209*7c478bd9Sstevel@tonic-gate pool_create_t create; 210*7c478bd9Sstevel@tonic-gate pool_assoc_t assoc; 211*7c478bd9Sstevel@tonic-gate pool_bindq_t bindq; 212*7c478bd9Sstevel@tonic-gate pool_query_t query; 213*7c478bd9Sstevel@tonic-gate pool_bind_t bind; 214*7c478bd9Sstevel@tonic-gate #ifdef _MULTI_DATAMODEL 215*7c478bd9Sstevel@tonic-gate pool_xtransfer32_t xtransfer32; 216*7c478bd9Sstevel@tonic-gate pool_propput32_t propput32; 217*7c478bd9Sstevel@tonic-gate pool_propget32_t propget32; 218*7c478bd9Sstevel@tonic-gate pool_proprm32_t proprm32; 219*7c478bd9Sstevel@tonic-gate pool_query32_t query32; 220*7c478bd9Sstevel@tonic-gate #endif /* _MULTI_DATAMODEL */ 221*7c478bd9Sstevel@tonic-gate char *kbuf = NULL; 222*7c478bd9Sstevel@tonic-gate size_t kbufsz = 0; 223*7c478bd9Sstevel@tonic-gate int snapshot = 0; 224*7c478bd9Sstevel@tonic-gate char *prop_name; 225*7c478bd9Sstevel@tonic-gate size_t size = 0; 226*7c478bd9Sstevel@tonic-gate nvlist_t *list; 227*7c478bd9Sstevel@tonic-gate nvpair_t *pair; 228*7c478bd9Sstevel@tonic-gate char *listbuf; 229*7c478bd9Sstevel@tonic-gate minor_t minor; 230*7c478bd9Sstevel@tonic-gate uint_t model; 231*7c478bd9Sstevel@tonic-gate id_t *id_buf; 232*7c478bd9Sstevel@tonic-gate int ret = 0; 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate model = ddi_model_convert_from(mode & FMODELS); 235*7c478bd9Sstevel@tonic-gate minor = getminor(dev); 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate /* 238*7c478bd9Sstevel@tonic-gate * Check basic permissions first. 239*7c478bd9Sstevel@tonic-gate */ 240*7c478bd9Sstevel@tonic-gate switch (cmd) { 241*7c478bd9Sstevel@tonic-gate case POOL_STATUS: 242*7c478bd9Sstevel@tonic-gate case POOL_CREATE: 243*7c478bd9Sstevel@tonic-gate case POOL_ASSOC: 244*7c478bd9Sstevel@tonic-gate case POOL_DISSOC: 245*7c478bd9Sstevel@tonic-gate case POOL_DESTROY: 246*7c478bd9Sstevel@tonic-gate case POOL_TRANSFER: 247*7c478bd9Sstevel@tonic-gate case POOL_XTRANSFER: 248*7c478bd9Sstevel@tonic-gate case POOL_PROPPUT: 249*7c478bd9Sstevel@tonic-gate case POOL_PROPRM: 250*7c478bd9Sstevel@tonic-gate case POOL_COMMIT: 251*7c478bd9Sstevel@tonic-gate if (minor != POOL_CTL_PARENT) 252*7c478bd9Sstevel@tonic-gate return (EINVAL); 253*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 254*7c478bd9Sstevel@tonic-gate case POOL_BIND: 255*7c478bd9Sstevel@tonic-gate if (secpolicy_pool(CRED()) != 0) 256*7c478bd9Sstevel@tonic-gate return (EPERM); 257*7c478bd9Sstevel@tonic-gate break; 258*7c478bd9Sstevel@tonic-gate } 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate switch (cmd) { 261*7c478bd9Sstevel@tonic-gate case POOL_STATUS: 262*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &status, 263*7c478bd9Sstevel@tonic-gate sizeof (pool_status_t), mode) != 0) 264*7c478bd9Sstevel@tonic-gate return (EFAULT); 265*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) 266*7c478bd9Sstevel@tonic-gate return (EINTR); 267*7c478bd9Sstevel@tonic-gate ret = pool_status(status.ps_io_state); 268*7c478bd9Sstevel@tonic-gate pool_unlock(); 269*7c478bd9Sstevel@tonic-gate break; 270*7c478bd9Sstevel@tonic-gate case POOL_STATUSQ: 271*7c478bd9Sstevel@tonic-gate /* 272*7c478bd9Sstevel@tonic-gate * No need to grab pool_lock() to look at the current state. 273*7c478bd9Sstevel@tonic-gate */ 274*7c478bd9Sstevel@tonic-gate status.ps_io_state = pool_state; 275*7c478bd9Sstevel@tonic-gate if (ddi_copyout(&status, (void *)arg, 276*7c478bd9Sstevel@tonic-gate sizeof (pool_status_t), mode) != 0) 277*7c478bd9Sstevel@tonic-gate return (EFAULT); 278*7c478bd9Sstevel@tonic-gate break; 279*7c478bd9Sstevel@tonic-gate case POOL_QUERY: 280*7c478bd9Sstevel@tonic-gate switch (model) { 281*7c478bd9Sstevel@tonic-gate #ifdef _MULTI_DATAMODEL 282*7c478bd9Sstevel@tonic-gate case DDI_MODEL_ILP32: 283*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &query32, 284*7c478bd9Sstevel@tonic-gate sizeof (pool_query32_t), mode) != 0) 285*7c478bd9Sstevel@tonic-gate return (EFAULT); 286*7c478bd9Sstevel@tonic-gate query.pq_io_bufsize = query32.pq_io_bufsize; 287*7c478bd9Sstevel@tonic-gate query.pq_io_buf = (char *)(uintptr_t)query32.pq_io_buf; 288*7c478bd9Sstevel@tonic-gate break; 289*7c478bd9Sstevel@tonic-gate #endif /* _MULTI_DATAMODEL */ 290*7c478bd9Sstevel@tonic-gate default: 291*7c478bd9Sstevel@tonic-gate case DDI_MODEL_NONE: 292*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &query, 293*7c478bd9Sstevel@tonic-gate sizeof (pool_query_t), mode) != 0) 294*7c478bd9Sstevel@tonic-gate return (EFAULT); 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) 297*7c478bd9Sstevel@tonic-gate return (EINTR); 298*7c478bd9Sstevel@tonic-gate if (pool_state == POOL_DISABLED) { 299*7c478bd9Sstevel@tonic-gate pool_unlock(); 300*7c478bd9Sstevel@tonic-gate return (ENOTACTIVE); 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate if (minor != 0 && pool_buf != NULL) { 303*7c478bd9Sstevel@tonic-gate /* 304*7c478bd9Sstevel@tonic-gate * Return last snapshot if some 305*7c478bd9Sstevel@tonic-gate * transaction is still in progress 306*7c478bd9Sstevel@tonic-gate */ 307*7c478bd9Sstevel@tonic-gate if (kbufsz != 0 && pool_bufsz > kbufsz) { 308*7c478bd9Sstevel@tonic-gate pool_unlock(); 309*7c478bd9Sstevel@tonic-gate return (ENOMEM); 310*7c478bd9Sstevel@tonic-gate } 311*7c478bd9Sstevel@tonic-gate kbuf = pool_buf; 312*7c478bd9Sstevel@tonic-gate kbufsz = size = pool_bufsz; 313*7c478bd9Sstevel@tonic-gate snapshot = 1; 314*7c478bd9Sstevel@tonic-gate } else if (query.pq_io_bufsize != 0) { 315*7c478bd9Sstevel@tonic-gate kbufsz = query.pq_io_bufsize; 316*7c478bd9Sstevel@tonic-gate kbuf = kmem_alloc(kbufsz, KM_NOSLEEP); 317*7c478bd9Sstevel@tonic-gate if (kbuf == NULL) { 318*7c478bd9Sstevel@tonic-gate pool_unlock(); 319*7c478bd9Sstevel@tonic-gate return (ENOMEM); 320*7c478bd9Sstevel@tonic-gate } 321*7c478bd9Sstevel@tonic-gate ret = pool_pack_conf(kbuf, kbufsz, &size); 322*7c478bd9Sstevel@tonic-gate } else { 323*7c478bd9Sstevel@tonic-gate ret = pool_pack_conf(NULL, 0, &size); 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate if (ret == 0) { 326*7c478bd9Sstevel@tonic-gate switch (model) { 327*7c478bd9Sstevel@tonic-gate #ifdef _MULTI_DATAMODEL 328*7c478bd9Sstevel@tonic-gate case DDI_MODEL_ILP32: 329*7c478bd9Sstevel@tonic-gate query32.pq_io_bufsize = size; 330*7c478bd9Sstevel@tonic-gate if (ddi_copyout((caddr_t)&query32, (void *)arg, 331*7c478bd9Sstevel@tonic-gate sizeof (pool_query32_t), mode) != 0) 332*7c478bd9Sstevel@tonic-gate ret = EFAULT; 333*7c478bd9Sstevel@tonic-gate break; 334*7c478bd9Sstevel@tonic-gate #endif /* _MULTI_DATAMODEL */ 335*7c478bd9Sstevel@tonic-gate default: 336*7c478bd9Sstevel@tonic-gate case DDI_MODEL_NONE: 337*7c478bd9Sstevel@tonic-gate query.pq_io_bufsize = size; 338*7c478bd9Sstevel@tonic-gate if (ddi_copyout(&query, (void *)arg, 339*7c478bd9Sstevel@tonic-gate sizeof (pool_query_t), mode) != 0) 340*7c478bd9Sstevel@tonic-gate ret = EFAULT; 341*7c478bd9Sstevel@tonic-gate } 342*7c478bd9Sstevel@tonic-gate if (ret == 0 && query.pq_io_buf != NULL && 343*7c478bd9Sstevel@tonic-gate ddi_copyout(kbuf, query.pq_io_buf, size, mode) != 0) 344*7c478bd9Sstevel@tonic-gate ret = EFAULT; 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate pool_unlock(); 347*7c478bd9Sstevel@tonic-gate if (snapshot == 0) 348*7c478bd9Sstevel@tonic-gate kmem_free(kbuf, kbufsz); 349*7c478bd9Sstevel@tonic-gate break; 350*7c478bd9Sstevel@tonic-gate case POOL_CREATE: 351*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, 352*7c478bd9Sstevel@tonic-gate &create, sizeof (pool_create_t), mode) != 0) 353*7c478bd9Sstevel@tonic-gate return (EFAULT); 354*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) 355*7c478bd9Sstevel@tonic-gate return (EINTR); 356*7c478bd9Sstevel@tonic-gate ret = pool_create(create.pc_o_type, 357*7c478bd9Sstevel@tonic-gate create.pc_o_sub_type, &create.pc_i_id); 358*7c478bd9Sstevel@tonic-gate pool_unlock(); 359*7c478bd9Sstevel@tonic-gate if (ret == 0 && ddi_copyout(&create, (void *)arg, 360*7c478bd9Sstevel@tonic-gate sizeof (pool_create_t), mode) != 0) 361*7c478bd9Sstevel@tonic-gate ret = EFAULT; 362*7c478bd9Sstevel@tonic-gate break; 363*7c478bd9Sstevel@tonic-gate case POOL_ASSOC: 364*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &assoc, 365*7c478bd9Sstevel@tonic-gate sizeof (pool_assoc_t), mode) != 0) 366*7c478bd9Sstevel@tonic-gate return (EFAULT); 367*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) 368*7c478bd9Sstevel@tonic-gate return (EINTR); 369*7c478bd9Sstevel@tonic-gate ret = pool_assoc(assoc.pa_o_pool_id, 370*7c478bd9Sstevel@tonic-gate assoc.pa_o_id_type, assoc.pa_o_res_id); 371*7c478bd9Sstevel@tonic-gate pool_unlock(); 372*7c478bd9Sstevel@tonic-gate break; 373*7c478bd9Sstevel@tonic-gate case POOL_DISSOC: 374*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &dissoc, 375*7c478bd9Sstevel@tonic-gate sizeof (pool_dissoc_t), mode) != 0) 376*7c478bd9Sstevel@tonic-gate return (EFAULT); 377*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) 378*7c478bd9Sstevel@tonic-gate return (EINTR); 379*7c478bd9Sstevel@tonic-gate ret = pool_dissoc(dissoc.pd_o_pool_id, dissoc.pd_o_id_type); 380*7c478bd9Sstevel@tonic-gate pool_unlock(); 381*7c478bd9Sstevel@tonic-gate break; 382*7c478bd9Sstevel@tonic-gate case POOL_DESTROY: 383*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &destroy, 384*7c478bd9Sstevel@tonic-gate sizeof (pool_destroy_t), mode) != 0) 385*7c478bd9Sstevel@tonic-gate return (EFAULT); 386*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) 387*7c478bd9Sstevel@tonic-gate return (EINTR); 388*7c478bd9Sstevel@tonic-gate ret = pool_destroy(destroy.pd_o_type, destroy.pd_o_sub_type, 389*7c478bd9Sstevel@tonic-gate destroy.pd_o_id); 390*7c478bd9Sstevel@tonic-gate pool_unlock(); 391*7c478bd9Sstevel@tonic-gate break; 392*7c478bd9Sstevel@tonic-gate case POOL_TRANSFER: 393*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &transfer, 394*7c478bd9Sstevel@tonic-gate sizeof (pool_transfer_t), mode) != 0) 395*7c478bd9Sstevel@tonic-gate return (EFAULT); 396*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) 397*7c478bd9Sstevel@tonic-gate return (EINTR); 398*7c478bd9Sstevel@tonic-gate ret = pool_transfer(transfer.pt_o_id_type, transfer.pt_o_src_id, 399*7c478bd9Sstevel@tonic-gate transfer.pt_o_tgt_id, transfer.pt_o_qty); 400*7c478bd9Sstevel@tonic-gate pool_unlock(); 401*7c478bd9Sstevel@tonic-gate break; 402*7c478bd9Sstevel@tonic-gate case POOL_XTRANSFER: 403*7c478bd9Sstevel@tonic-gate switch (model) { 404*7c478bd9Sstevel@tonic-gate #ifdef _MULTI_DATAMODEL 405*7c478bd9Sstevel@tonic-gate case DDI_MODEL_ILP32: 406*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &xtransfer32, 407*7c478bd9Sstevel@tonic-gate sizeof (pool_xtransfer32_t), mode) != 0) 408*7c478bd9Sstevel@tonic-gate return (EFAULT); 409*7c478bd9Sstevel@tonic-gate xtransfer.px_o_id_type = xtransfer32.px_o_id_type; 410*7c478bd9Sstevel@tonic-gate xtransfer.px_o_src_id = xtransfer32.px_o_src_id; 411*7c478bd9Sstevel@tonic-gate xtransfer.px_o_tgt_id = xtransfer32.px_o_tgt_id; 412*7c478bd9Sstevel@tonic-gate xtransfer.px_o_complist_size = 413*7c478bd9Sstevel@tonic-gate xtransfer32.px_o_complist_size; 414*7c478bd9Sstevel@tonic-gate xtransfer.px_o_comp_list = 415*7c478bd9Sstevel@tonic-gate (id_t *)(uintptr_t)xtransfer32.px_o_comp_list; 416*7c478bd9Sstevel@tonic-gate break; 417*7c478bd9Sstevel@tonic-gate #endif /* _MULTI_DATAMODEL */ 418*7c478bd9Sstevel@tonic-gate default: 419*7c478bd9Sstevel@tonic-gate case DDI_MODEL_NONE: 420*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &xtransfer, 421*7c478bd9Sstevel@tonic-gate sizeof (pool_xtransfer_t), mode) != 0) 422*7c478bd9Sstevel@tonic-gate return (EFAULT); 423*7c478bd9Sstevel@tonic-gate } 424*7c478bd9Sstevel@tonic-gate /* 425*7c478bd9Sstevel@tonic-gate * Copy in IDs to transfer from the userland 426*7c478bd9Sstevel@tonic-gate */ 427*7c478bd9Sstevel@tonic-gate if (xtransfer.px_o_complist_size > POOL_IDLIST_SIZE) 428*7c478bd9Sstevel@tonic-gate return (EINVAL); 429*7c478bd9Sstevel@tonic-gate id_buf = kmem_alloc(xtransfer.px_o_complist_size * 430*7c478bd9Sstevel@tonic-gate sizeof (id_t), KM_SLEEP); 431*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)xtransfer.px_o_comp_list, id_buf, 432*7c478bd9Sstevel@tonic-gate xtransfer.px_o_complist_size * sizeof (id_t), mode) != 0) { 433*7c478bd9Sstevel@tonic-gate kmem_free(id_buf, xtransfer.px_o_complist_size * 434*7c478bd9Sstevel@tonic-gate sizeof (id_t)); 435*7c478bd9Sstevel@tonic-gate return (EFAULT); 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) { 438*7c478bd9Sstevel@tonic-gate kmem_free(id_buf, xtransfer.px_o_complist_size * 439*7c478bd9Sstevel@tonic-gate sizeof (id_t)); 440*7c478bd9Sstevel@tonic-gate return (EINTR); 441*7c478bd9Sstevel@tonic-gate } 442*7c478bd9Sstevel@tonic-gate ret = pool_xtransfer(xtransfer.px_o_id_type, 443*7c478bd9Sstevel@tonic-gate xtransfer.px_o_src_id, xtransfer.px_o_tgt_id, 444*7c478bd9Sstevel@tonic-gate xtransfer.px_o_complist_size, id_buf); 445*7c478bd9Sstevel@tonic-gate pool_unlock(); 446*7c478bd9Sstevel@tonic-gate kmem_free(id_buf, xtransfer.px_o_complist_size * 447*7c478bd9Sstevel@tonic-gate sizeof (id_t)); 448*7c478bd9Sstevel@tonic-gate break; 449*7c478bd9Sstevel@tonic-gate case POOL_BIND: 450*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &bind, 451*7c478bd9Sstevel@tonic-gate sizeof (pool_bind_t), mode) != 0) 452*7c478bd9Sstevel@tonic-gate return (EFAULT); 453*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) 454*7c478bd9Sstevel@tonic-gate return (EINTR); 455*7c478bd9Sstevel@tonic-gate ret = pool_bind(bind.pb_o_pool_id, bind.pb_o_id_type, 456*7c478bd9Sstevel@tonic-gate bind.pb_o_id); 457*7c478bd9Sstevel@tonic-gate pool_unlock(); 458*7c478bd9Sstevel@tonic-gate break; 459*7c478bd9Sstevel@tonic-gate case POOL_BINDQ: 460*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &bindq, 461*7c478bd9Sstevel@tonic-gate sizeof (pool_bindq_t), mode) != 0) { 462*7c478bd9Sstevel@tonic-gate return (EFAULT); 463*7c478bd9Sstevel@tonic-gate } 464*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) 465*7c478bd9Sstevel@tonic-gate return (EINTR); 466*7c478bd9Sstevel@tonic-gate if ((ret = pool_query_binding(bindq.pb_o_id_type, 467*7c478bd9Sstevel@tonic-gate bindq.pb_o_id, &bindq.pb_i_id)) == 0 && 468*7c478bd9Sstevel@tonic-gate ddi_copyout(&bindq, (void *)arg, 469*7c478bd9Sstevel@tonic-gate sizeof (pool_bindq_t), mode) != 0) 470*7c478bd9Sstevel@tonic-gate ret = EFAULT; 471*7c478bd9Sstevel@tonic-gate pool_unlock(); 472*7c478bd9Sstevel@tonic-gate break; 473*7c478bd9Sstevel@tonic-gate case POOL_PROPGET: 474*7c478bd9Sstevel@tonic-gate switch (model) { 475*7c478bd9Sstevel@tonic-gate #ifdef _MULTI_DATAMODEL 476*7c478bd9Sstevel@tonic-gate case DDI_MODEL_ILP32: 477*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &propget32, 478*7c478bd9Sstevel@tonic-gate sizeof (pool_propget32_t), mode) != 0) 479*7c478bd9Sstevel@tonic-gate return (EFAULT); 480*7c478bd9Sstevel@tonic-gate propget.pp_o_id = propget32.pp_o_id; 481*7c478bd9Sstevel@tonic-gate propget.pp_o_id_type = propget32.pp_o_id_type; 482*7c478bd9Sstevel@tonic-gate propget.pp_o_id_subtype = propget32.pp_o_id_subtype; 483*7c478bd9Sstevel@tonic-gate propget.pp_o_prop_name = 484*7c478bd9Sstevel@tonic-gate (char *)(uintptr_t)propget32.pp_o_prop_name; 485*7c478bd9Sstevel@tonic-gate propget.pp_o_prop_name_size = 486*7c478bd9Sstevel@tonic-gate propget32.pp_o_prop_name_size; 487*7c478bd9Sstevel@tonic-gate propget.pp_i_buf = 488*7c478bd9Sstevel@tonic-gate (char *)(uintptr_t)propget32.pp_i_buf; 489*7c478bd9Sstevel@tonic-gate propget.pp_i_bufsize = propget32.pp_i_bufsize; 490*7c478bd9Sstevel@tonic-gate break; 491*7c478bd9Sstevel@tonic-gate #endif /* _MULTI_DATAMODEL */ 492*7c478bd9Sstevel@tonic-gate default: 493*7c478bd9Sstevel@tonic-gate case DDI_MODEL_NONE: 494*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &propget, 495*7c478bd9Sstevel@tonic-gate sizeof (pool_propget_t), mode) != 0) 496*7c478bd9Sstevel@tonic-gate return (EFAULT); 497*7c478bd9Sstevel@tonic-gate } 498*7c478bd9Sstevel@tonic-gate if (propget.pp_o_prop_name_size + 1 > POOL_PROPNAME_SIZE) 499*7c478bd9Sstevel@tonic-gate return (EINVAL); 500*7c478bd9Sstevel@tonic-gate prop_name = kmem_alloc(propget.pp_o_prop_name_size + 1, 501*7c478bd9Sstevel@tonic-gate KM_SLEEP); 502*7c478bd9Sstevel@tonic-gate if (ddi_copyin(propget.pp_o_prop_name, prop_name, 503*7c478bd9Sstevel@tonic-gate propget.pp_o_prop_name_size + 1, mode) != 0) { 504*7c478bd9Sstevel@tonic-gate kmem_free(prop_name, propget.pp_o_prop_name_size + 1); 505*7c478bd9Sstevel@tonic-gate return (EFAULT); 506*7c478bd9Sstevel@tonic-gate } 507*7c478bd9Sstevel@tonic-gate list = NULL; 508*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) { 509*7c478bd9Sstevel@tonic-gate kmem_free(prop_name, propget.pp_o_prop_name_size + 1); 510*7c478bd9Sstevel@tonic-gate return (EINTR); 511*7c478bd9Sstevel@tonic-gate } 512*7c478bd9Sstevel@tonic-gate ret = pool_propget(prop_name, propget.pp_o_id_type, 513*7c478bd9Sstevel@tonic-gate propget.pp_o_id_subtype, propget.pp_o_id, &list); 514*7c478bd9Sstevel@tonic-gate pool_unlock(); 515*7c478bd9Sstevel@tonic-gate kmem_free(prop_name, propget.pp_o_prop_name_size + 1); 516*7c478bd9Sstevel@tonic-gate if (ret != 0) 517*7c478bd9Sstevel@tonic-gate return (ret); 518*7c478bd9Sstevel@tonic-gate ret = nvlist_pack(list, &kbuf, &kbufsz, NV_ENCODE_NATIVE, 0); 519*7c478bd9Sstevel@tonic-gate if (ret != 0) { 520*7c478bd9Sstevel@tonic-gate nvlist_free(list); 521*7c478bd9Sstevel@tonic-gate return (ret); 522*7c478bd9Sstevel@tonic-gate } 523*7c478bd9Sstevel@tonic-gate switch (model) { 524*7c478bd9Sstevel@tonic-gate #ifdef _MULTI_DATAMODEL 525*7c478bd9Sstevel@tonic-gate case DDI_MODEL_ILP32: 526*7c478bd9Sstevel@tonic-gate propget32.pp_i_bufsize = kbufsz; 527*7c478bd9Sstevel@tonic-gate if (ddi_copyout((caddr_t)&propget32, (void *)arg, 528*7c478bd9Sstevel@tonic-gate sizeof (pool_propget32_t), mode) != 0) 529*7c478bd9Sstevel@tonic-gate ret = EFAULT; 530*7c478bd9Sstevel@tonic-gate break; 531*7c478bd9Sstevel@tonic-gate #endif /* _MULTI_DATAMODEL */ 532*7c478bd9Sstevel@tonic-gate default: 533*7c478bd9Sstevel@tonic-gate case DDI_MODEL_NONE: 534*7c478bd9Sstevel@tonic-gate if (ddi_copyout(&propget, (void *)arg, 535*7c478bd9Sstevel@tonic-gate sizeof (pool_propget_t), mode) != 0) 536*7c478bd9Sstevel@tonic-gate ret = EFAULT; 537*7c478bd9Sstevel@tonic-gate } 538*7c478bd9Sstevel@tonic-gate if (ret == 0) { 539*7c478bd9Sstevel@tonic-gate if (propget.pp_i_buf == NULL) { 540*7c478bd9Sstevel@tonic-gate ret = 0; 541*7c478bd9Sstevel@tonic-gate } else if (propget.pp_i_bufsize >= kbufsz) { 542*7c478bd9Sstevel@tonic-gate if (ddi_copyout(kbuf, propget.pp_i_buf, 543*7c478bd9Sstevel@tonic-gate kbufsz, mode) != 0) 544*7c478bd9Sstevel@tonic-gate ret = EFAULT; 545*7c478bd9Sstevel@tonic-gate } else { 546*7c478bd9Sstevel@tonic-gate ret = ENOMEM; 547*7c478bd9Sstevel@tonic-gate } 548*7c478bd9Sstevel@tonic-gate } 549*7c478bd9Sstevel@tonic-gate kmem_free(kbuf, kbufsz); 550*7c478bd9Sstevel@tonic-gate nvlist_free(list); 551*7c478bd9Sstevel@tonic-gate break; 552*7c478bd9Sstevel@tonic-gate case POOL_PROPPUT: 553*7c478bd9Sstevel@tonic-gate switch (model) { 554*7c478bd9Sstevel@tonic-gate #ifdef _MULTI_DATAMODEL 555*7c478bd9Sstevel@tonic-gate case DDI_MODEL_ILP32: 556*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &propput32, 557*7c478bd9Sstevel@tonic-gate sizeof (pool_propput32_t), mode) != 0) 558*7c478bd9Sstevel@tonic-gate return (EFAULT); 559*7c478bd9Sstevel@tonic-gate propput.pp_o_id_type = propput32.pp_o_id_type; 560*7c478bd9Sstevel@tonic-gate propput.pp_o_id_sub_type = propput32.pp_o_id_sub_type; 561*7c478bd9Sstevel@tonic-gate propput.pp_o_id = propput32.pp_o_id; 562*7c478bd9Sstevel@tonic-gate propput.pp_o_bufsize = propput32.pp_o_bufsize; 563*7c478bd9Sstevel@tonic-gate propput.pp_o_buf = 564*7c478bd9Sstevel@tonic-gate (char *)(uintptr_t)propput32.pp_o_buf; 565*7c478bd9Sstevel@tonic-gate break; 566*7c478bd9Sstevel@tonic-gate #endif /* _MULTI_DATAMODEL */ 567*7c478bd9Sstevel@tonic-gate default: 568*7c478bd9Sstevel@tonic-gate case DDI_MODEL_NONE: 569*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &propput, 570*7c478bd9Sstevel@tonic-gate sizeof (pool_propput_t), mode) != 0) 571*7c478bd9Sstevel@tonic-gate return (EFAULT); 572*7c478bd9Sstevel@tonic-gate } 573*7c478bd9Sstevel@tonic-gate if (propput.pp_o_bufsize > POOL_PROPBUF_SIZE) 574*7c478bd9Sstevel@tonic-gate return (EINVAL); 575*7c478bd9Sstevel@tonic-gate listbuf = kmem_alloc(propput.pp_o_bufsize, KM_SLEEP); 576*7c478bd9Sstevel@tonic-gate if (ddi_copyin(propput.pp_o_buf, listbuf, 577*7c478bd9Sstevel@tonic-gate propput.pp_o_bufsize, mode) != 0) { 578*7c478bd9Sstevel@tonic-gate kmem_free(listbuf, propput.pp_o_bufsize); 579*7c478bd9Sstevel@tonic-gate return (EFAULT); 580*7c478bd9Sstevel@tonic-gate } 581*7c478bd9Sstevel@tonic-gate if (nvlist_unpack(listbuf, propput.pp_o_bufsize, 582*7c478bd9Sstevel@tonic-gate &list, KM_SLEEP) != 0) { 583*7c478bd9Sstevel@tonic-gate kmem_free(listbuf, propput.pp_o_bufsize); 584*7c478bd9Sstevel@tonic-gate return (EFAULT); 585*7c478bd9Sstevel@tonic-gate } 586*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) { 587*7c478bd9Sstevel@tonic-gate nvlist_free(list); 588*7c478bd9Sstevel@tonic-gate kmem_free(listbuf, propput.pp_o_bufsize); 589*7c478bd9Sstevel@tonic-gate return (EINTR); 590*7c478bd9Sstevel@tonic-gate } 591*7c478bd9Sstevel@tonic-gate /* 592*7c478bd9Sstevel@tonic-gate * Extract the nvpair from the list. The list may 593*7c478bd9Sstevel@tonic-gate * contain multiple properties. 594*7c478bd9Sstevel@tonic-gate */ 595*7c478bd9Sstevel@tonic-gate for (pair = nvlist_next_nvpair(list, NULL); pair != NULL; 596*7c478bd9Sstevel@tonic-gate pair = nvlist_next_nvpair(list, pair)) { 597*7c478bd9Sstevel@tonic-gate if ((ret = pool_propput(propput.pp_o_id_type, 598*7c478bd9Sstevel@tonic-gate propput.pp_o_id_sub_type, 599*7c478bd9Sstevel@tonic-gate propput.pp_o_id, pair)) != 0) 600*7c478bd9Sstevel@tonic-gate break; 601*7c478bd9Sstevel@tonic-gate } 602*7c478bd9Sstevel@tonic-gate pool_unlock(); 603*7c478bd9Sstevel@tonic-gate nvlist_free(list); 604*7c478bd9Sstevel@tonic-gate kmem_free(listbuf, propput.pp_o_bufsize); 605*7c478bd9Sstevel@tonic-gate break; 606*7c478bd9Sstevel@tonic-gate case POOL_PROPRM: 607*7c478bd9Sstevel@tonic-gate switch (model) { 608*7c478bd9Sstevel@tonic-gate #ifdef _MULTI_DATAMODEL 609*7c478bd9Sstevel@tonic-gate case DDI_MODEL_ILP32: 610*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &proprm32, 611*7c478bd9Sstevel@tonic-gate sizeof (pool_proprm32_t), mode) != 0) 612*7c478bd9Sstevel@tonic-gate return (EFAULT); 613*7c478bd9Sstevel@tonic-gate proprm.pp_o_id_type = proprm32.pp_o_id_type; 614*7c478bd9Sstevel@tonic-gate proprm.pp_o_id_sub_type = proprm32.pp_o_id_sub_type; 615*7c478bd9Sstevel@tonic-gate proprm.pp_o_id = proprm32.pp_o_id; 616*7c478bd9Sstevel@tonic-gate proprm.pp_o_prop_name_size = 617*7c478bd9Sstevel@tonic-gate proprm32.pp_o_prop_name_size; 618*7c478bd9Sstevel@tonic-gate proprm.pp_o_prop_name = 619*7c478bd9Sstevel@tonic-gate (void *)(uintptr_t)proprm32.pp_o_prop_name; 620*7c478bd9Sstevel@tonic-gate break; 621*7c478bd9Sstevel@tonic-gate #endif /* _MULTI_DATAMODEL */ 622*7c478bd9Sstevel@tonic-gate default: 623*7c478bd9Sstevel@tonic-gate case DDI_MODEL_NONE: 624*7c478bd9Sstevel@tonic-gate if (ddi_copyin((void *)arg, &proprm, 625*7c478bd9Sstevel@tonic-gate sizeof (pool_proprm_t), mode) != 0) 626*7c478bd9Sstevel@tonic-gate return (EFAULT); 627*7c478bd9Sstevel@tonic-gate } 628*7c478bd9Sstevel@tonic-gate if (proprm.pp_o_prop_name_size + 1 > POOL_PROPNAME_SIZE) 629*7c478bd9Sstevel@tonic-gate return (EINVAL); 630*7c478bd9Sstevel@tonic-gate prop_name = kmem_alloc(proprm.pp_o_prop_name_size + 1, 631*7c478bd9Sstevel@tonic-gate KM_SLEEP); 632*7c478bd9Sstevel@tonic-gate if (ddi_copyin(proprm.pp_o_prop_name, prop_name, 633*7c478bd9Sstevel@tonic-gate proprm.pp_o_prop_name_size + 1, mode) != 0) { 634*7c478bd9Sstevel@tonic-gate kmem_free(prop_name, proprm.pp_o_prop_name_size + 1); 635*7c478bd9Sstevel@tonic-gate return (EFAULT); 636*7c478bd9Sstevel@tonic-gate } 637*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) { 638*7c478bd9Sstevel@tonic-gate kmem_free(prop_name, proprm.pp_o_prop_name_size + 1); 639*7c478bd9Sstevel@tonic-gate return (EINTR); 640*7c478bd9Sstevel@tonic-gate } 641*7c478bd9Sstevel@tonic-gate ret = pool_proprm(proprm.pp_o_id_type, 642*7c478bd9Sstevel@tonic-gate proprm.pp_o_id_sub_type, proprm.pp_o_id, prop_name); 643*7c478bd9Sstevel@tonic-gate pool_unlock(); 644*7c478bd9Sstevel@tonic-gate kmem_free(prop_name, proprm.pp_o_prop_name_size + 1); 645*7c478bd9Sstevel@tonic-gate break; 646*7c478bd9Sstevel@tonic-gate case POOL_COMMIT: 647*7c478bd9Sstevel@tonic-gate if (pool_lock_intr() != 0) 648*7c478bd9Sstevel@tonic-gate return (EINTR); 649*7c478bd9Sstevel@tonic-gate ret = pool_commit((int)arg); 650*7c478bd9Sstevel@tonic-gate pool_unlock(); 651*7c478bd9Sstevel@tonic-gate break; 652*7c478bd9Sstevel@tonic-gate default: 653*7c478bd9Sstevel@tonic-gate return (EINVAL); 654*7c478bd9Sstevel@tonic-gate } 655*7c478bd9Sstevel@tonic-gate return (ret); 656*7c478bd9Sstevel@tonic-gate } 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate static struct cb_ops pool_cb_ops = { 659*7c478bd9Sstevel@tonic-gate pool_open, /* open */ 660*7c478bd9Sstevel@tonic-gate pool_close, /* close */ 661*7c478bd9Sstevel@tonic-gate nodev, /* strategy */ 662*7c478bd9Sstevel@tonic-gate nodev, /* print */ 663*7c478bd9Sstevel@tonic-gate nodev, /* dump */ 664*7c478bd9Sstevel@tonic-gate nodev, /* read */ 665*7c478bd9Sstevel@tonic-gate nodev, /* write */ 666*7c478bd9Sstevel@tonic-gate pool_ioctl, /* ioctl */ 667*7c478bd9Sstevel@tonic-gate nodev, /* devmap */ 668*7c478bd9Sstevel@tonic-gate nodev, /* mmap */ 669*7c478bd9Sstevel@tonic-gate nodev, /* segmap */ 670*7c478bd9Sstevel@tonic-gate nochpoll, /* poll */ 671*7c478bd9Sstevel@tonic-gate nodev, /* cb_prop_op */ 672*7c478bd9Sstevel@tonic-gate (struct streamtab *)0, /* streamtab */ 673*7c478bd9Sstevel@tonic-gate D_NEW | D_MP /* driver compatibility flags */ 674*7c478bd9Sstevel@tonic-gate }; 675*7c478bd9Sstevel@tonic-gate 676*7c478bd9Sstevel@tonic-gate static struct dev_ops pool_ops = { 677*7c478bd9Sstevel@tonic-gate DEVO_REV, /* devo_rev */ 678*7c478bd9Sstevel@tonic-gate 0, /* refcnt */ 679*7c478bd9Sstevel@tonic-gate pool_info, /* info */ 680*7c478bd9Sstevel@tonic-gate nulldev, /* identify */ 681*7c478bd9Sstevel@tonic-gate nulldev, /* probe */ 682*7c478bd9Sstevel@tonic-gate pool_attach, /* attach */ 683*7c478bd9Sstevel@tonic-gate pool_detach, /* detach */ 684*7c478bd9Sstevel@tonic-gate nodev, /* reset */ 685*7c478bd9Sstevel@tonic-gate &pool_cb_ops, /* cb_ops */ 686*7c478bd9Sstevel@tonic-gate (struct bus_ops *)NULL, /* bus_ops */ 687*7c478bd9Sstevel@tonic-gate nulldev /* power */ 688*7c478bd9Sstevel@tonic-gate }; 689*7c478bd9Sstevel@tonic-gate 690*7c478bd9Sstevel@tonic-gate /* 691*7c478bd9Sstevel@tonic-gate * Module linkage information for the kernel 692*7c478bd9Sstevel@tonic-gate */ 693*7c478bd9Sstevel@tonic-gate static struct modldrv modldrv = { 694*7c478bd9Sstevel@tonic-gate &mod_driverops, /* this one is a pseudo driver */ 695*7c478bd9Sstevel@tonic-gate "pool driver %I%", 696*7c478bd9Sstevel@tonic-gate &pool_ops 697*7c478bd9Sstevel@tonic-gate }; 698*7c478bd9Sstevel@tonic-gate 699*7c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = { 700*7c478bd9Sstevel@tonic-gate MODREV_1, 701*7c478bd9Sstevel@tonic-gate &modldrv, 702*7c478bd9Sstevel@tonic-gate NULL 703*7c478bd9Sstevel@tonic-gate }; 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate int 706*7c478bd9Sstevel@tonic-gate _init(void) 707*7c478bd9Sstevel@tonic-gate { 708*7c478bd9Sstevel@tonic-gate return (mod_install(&modlinkage)); 709*7c478bd9Sstevel@tonic-gate } 710*7c478bd9Sstevel@tonic-gate 711*7c478bd9Sstevel@tonic-gate int 712*7c478bd9Sstevel@tonic-gate _fini(void) 713*7c478bd9Sstevel@tonic-gate { 714*7c478bd9Sstevel@tonic-gate return (mod_remove(&modlinkage)); 715*7c478bd9Sstevel@tonic-gate } 716*7c478bd9Sstevel@tonic-gate 717*7c478bd9Sstevel@tonic-gate int 718*7c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop) 719*7c478bd9Sstevel@tonic-gate { 720*7c478bd9Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 721*7c478bd9Sstevel@tonic-gate } 722