Print this page
XXXX don't fail device detach when it's physically removed
   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   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  * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
  24  * Copyright 2012 Garrett D'Amore <garrett@damore.org>.  All rights reserved.
  25  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  26  * Copyright (c) 2016 by Delphix. All rights reserved.
  27  */
  28 
  29 #include <sys/note.h>
  30 #include <sys/t_lock.h>
  31 #include <sys/cmn_err.h>
  32 #include <sys/instance.h>
  33 #include <sys/conf.h>
  34 #include <sys/stat.h>
  35 #include <sys/ddi.h>
  36 #include <sys/hwconf.h>
  37 #include <sys/sunddi.h>
  38 #include <sys/sunndi.h>
  39 #include <sys/ddi_impldefs.h>
  40 #include <sys/ndi_impldefs.h>
  41 #include <sys/modctl.h>
  42 #include <sys/contract/device_impl.h>
  43 #include <sys/dacf.h>


1343                 mutex_exit(&DEVI(dip)->devi_lock);
1344 
1345         /* successful attach, return with driver held */
1346 
1347         return (DDI_SUCCESS);
1348 }
1349 
1350 /*
1351  * Detach devinfo node.
1352  * Per-driver list must be held busy.
1353  */
1354 static int
1355 detach_node(dev_info_t *dip, uint_t flag)
1356 {
1357         struct devnames *dnp;
1358         int             rv;
1359 
1360         ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip)));
1361         ASSERT(i_ddi_node_state(dip) == DS_ATTACHED);
1362 
1363         /* check references */
1364         if (DEVI(dip)->devi_ref)
1365                 return (DDI_FAILURE);
1366 
1367         NDI_CONFIG_DEBUG((CE_CONT, "detach_node: 0x%p(%s%d)\n",
1368             (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip)));
1369 
1370         /*
1371          * NOTE: If we are processing a pHCI node then the calling code
1372          * must detect this and ndi_devi_enter() in (vHCI, parent(pHCI))
1373          * order unless pHCI and vHCI are siblings.  Code paths leading
1374          * here that must ensure this ordering include:
1375          * unconfig_immediate_children(), devi_unconfig_one(),
1376          * ndi_devi_unconfig_one(), ndi_devi_offline().
1377          */
1378         ASSERT(!MDI_PHCI(dip) ||
1379             (ddi_get_parent(mdi_devi_get_vdip(dip)) == ddi_get_parent(dip)) ||
1380             DEVI_BUSY_OWNED(mdi_devi_get_vdip(dip)));
1381 
1382         /* Offline the device node with the mpxio framework. */
1383         if (mdi_devi_offline(dip, flag) != NDI_SUCCESS) {
1384                 return (DDI_FAILURE);


3804  * (3) if neither exists, a dev_t is faked with minor number = instance.
3805  * As of S9 FCS, no instance of #1 exists. #2 is used by several platforms
3806  * to default the boot partition to :a possibly by other OBP definitions.
3807  * #3 is used for booting off network interfaces, most SPARC network
3808  * drivers support Style-2 only, so only DDM_ALIAS minor exists.
3809  *
3810  * It is possible for OBP to present device args at the end of the path as
3811  * well as in the middle. For example, with IB the following strings are
3812  * valid boot paths.
3813  *      a /pci@8,700000/ib@1,2:port=1,pkey=ff,dhcp,...
3814  *      b /pci@8,700000/ib@1,1:port=1/ioc@xxxxxx,yyyyyyy:dhcp
3815  * Case (a), we first look for minor node "port=1,pkey...".
3816  * Failing that, we will pass "port=1,pkey..." to the bus_config
3817  * entry point of ib (HCA) driver.
3818  * Case (b), configure ib@1,1 as usual. Then invoke ib's bus_config
3819  * with argument "ioc@xxxxxxx,yyyyyyy:port=1". After configuring
3820  * the ioc, look for minor node dhcp. If not found, pass ":dhcp"
3821  * to ioc's bus_config entry point.
3822  */
3823 int
3824 resolve_pathname(char *pathname,
3825         dev_info_t **dipp, dev_t *devtp, int *spectypep)
3826 {
3827         int                     error;
3828         dev_info_t              *parent, *child;
3829         struct pathname         pn;
3830         char                    *component, *config_name;
3831         char                    *minorname = NULL;
3832         char                    *prev_minor = NULL;
3833         dev_t                   devt = NODEV;
3834         int                     spectype;
3835         struct ddi_minor_data   *dmn;
3836         int                     circ;
3837 
3838         if (*pathname != '/')
3839                 return (EINVAL);
3840         parent = ddi_root_node();       /* Begin at the top of the tree */
3841 
3842         if (error = pn_get(pathname, UIO_SYSSPACE, &pn))
3843                 return (error);
3844         pn_skipslash(&pn);
3845 


   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   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 (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2018 Nexenta Systems, Inc.
  25  * Copyright 2012 Garrett D'Amore <garrett@damore.org>.  All rights reserved.
  26  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  27  * Copyright (c) 2016 by Delphix. All rights reserved.
  28  */
  29 
  30 #include <sys/note.h>
  31 #include <sys/t_lock.h>
  32 #include <sys/cmn_err.h>
  33 #include <sys/instance.h>
  34 #include <sys/conf.h>
  35 #include <sys/stat.h>
  36 #include <sys/ddi.h>
  37 #include <sys/hwconf.h>
  38 #include <sys/sunddi.h>
  39 #include <sys/sunndi.h>
  40 #include <sys/ddi_impldefs.h>
  41 #include <sys/ndi_impldefs.h>
  42 #include <sys/modctl.h>
  43 #include <sys/contract/device_impl.h>
  44 #include <sys/dacf.h>


1344                 mutex_exit(&DEVI(dip)->devi_lock);
1345 
1346         /* successful attach, return with driver held */
1347 
1348         return (DDI_SUCCESS);
1349 }
1350 
1351 /*
1352  * Detach devinfo node.
1353  * Per-driver list must be held busy.
1354  */
1355 static int
1356 detach_node(dev_info_t *dip, uint_t flag)
1357 {
1358         struct devnames *dnp;
1359         int             rv;
1360 
1361         ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip)));
1362         ASSERT(i_ddi_node_state(dip) == DS_ATTACHED);
1363 
1364         /* Check references */
1365         if (DEVI(dip)->devi_ref != 0 && !DEVI(dip)->devi_gone)
1366                 return (DDI_FAILURE);
1367 
1368         NDI_CONFIG_DEBUG((CE_CONT, "detach_node: 0x%p(%s%d)\n",
1369             (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip)));
1370 
1371         /*
1372          * NOTE: If we are processing a pHCI node then the calling code
1373          * must detect this and ndi_devi_enter() in (vHCI, parent(pHCI))
1374          * order unless pHCI and vHCI are siblings.  Code paths leading
1375          * here that must ensure this ordering include:
1376          * unconfig_immediate_children(), devi_unconfig_one(),
1377          * ndi_devi_unconfig_one(), ndi_devi_offline().
1378          */
1379         ASSERT(!MDI_PHCI(dip) ||
1380             (ddi_get_parent(mdi_devi_get_vdip(dip)) == ddi_get_parent(dip)) ||
1381             DEVI_BUSY_OWNED(mdi_devi_get_vdip(dip)));
1382 
1383         /* Offline the device node with the mpxio framework. */
1384         if (mdi_devi_offline(dip, flag) != NDI_SUCCESS) {
1385                 return (DDI_FAILURE);


3805  * (3) if neither exists, a dev_t is faked with minor number = instance.
3806  * As of S9 FCS, no instance of #1 exists. #2 is used by several platforms
3807  * to default the boot partition to :a possibly by other OBP definitions.
3808  * #3 is used for booting off network interfaces, most SPARC network
3809  * drivers support Style-2 only, so only DDM_ALIAS minor exists.
3810  *
3811  * It is possible for OBP to present device args at the end of the path as
3812  * well as in the middle. For example, with IB the following strings are
3813  * valid boot paths.
3814  *      a /pci@8,700000/ib@1,2:port=1,pkey=ff,dhcp,...
3815  *      b /pci@8,700000/ib@1,1:port=1/ioc@xxxxxx,yyyyyyy:dhcp
3816  * Case (a), we first look for minor node "port=1,pkey...".
3817  * Failing that, we will pass "port=1,pkey..." to the bus_config
3818  * entry point of ib (HCA) driver.
3819  * Case (b), configure ib@1,1 as usual. Then invoke ib's bus_config
3820  * with argument "ioc@xxxxxxx,yyyyyyy:port=1". After configuring
3821  * the ioc, look for minor node dhcp. If not found, pass ":dhcp"
3822  * to ioc's bus_config entry point.
3823  */
3824 int
3825 resolve_pathname(char *pathname, dev_info_t **dipp, dev_t *devtp,
3826     int *spectypep)
3827 {
3828         int                     error;
3829         dev_info_t              *parent, *child;
3830         struct pathname         pn;
3831         char                    *component, *config_name;
3832         char                    *minorname = NULL;
3833         char                    *prev_minor = NULL;
3834         dev_t                   devt = NODEV;
3835         int                     spectype;
3836         struct ddi_minor_data   *dmn;
3837         int                     circ;
3838 
3839         if (*pathname != '/')
3840                 return (EINVAL);
3841         parent = ddi_root_node();       /* Begin at the top of the tree */
3842 
3843         if (error = pn_get(pathname, UIO_SYSSPACE, &pn))
3844                 return (error);
3845         pn_skipslash(&pn);
3846