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.
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.
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]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * nulldriver - null device driver
29 * The nulldriver is used to associate a solaris driver with a specific
30 * device without enabling external device access.
32 * The driver can be used to:
34 * o Prevent external access to specific devices/hardware by associating a
35 * high-precedence 'compatible' binding, including a path-oriented alias,
38 * o Enable a nexus bus_config implementation to perform dynamic child
39 * discovery by creating a child 'probe' devinfo node, bound to
40 * nulldriver, at the specific child @unit-addresses associated with
41 * discovery. With a nulldriver bound 'probe' node, nexus driver
42 * bus_config discovery code can use the same devinfo node oriented
43 * transport services for both discovery and normal-operation: which
44 * is a significant simplification. While nulldriver prevents external
45 * device access, a nexus driver can still internally use the transport
48 * A scsi(4) example of this type of use is SCSA enumeration services
49 * issuing a scsi REPORT_LUN command to a lun-0 'probe' node bound to
50 * nulldriver in order to discover all luns supported by a target.
53 #include <sys/modctl.h>
56 #include <sys/sunddi.h>
57 #include <sys/cmn_err.h>
59 static int nulldriver_getinfo(dev_info_t
*, ddi_info_cmd_t
, void *, void **);
60 static int nulldriver_probe(dev_info_t
*);
61 static int nulldriver_attach(dev_info_t
*, ddi_attach_cmd_t
);
62 static int nulldriver_detach(dev_info_t
*, ddi_detach_cmd_t
);
64 static struct cb_ops nulldriver_cb_ops
= {
77 ddi_prop_op
, /* cb_prop_op */
79 D_MP
| D_NEW
| D_HOTPLUG
/* Driver compatibility flag */
82 static struct dev_ops nulldriver_dev_ops
= {
83 DEVO_REV
, /* devo_rev, */
85 nulldriver_getinfo
, /* info */
87 nulldriver_probe
, /* probe */
88 nulldriver_attach
, /* attach */
89 nulldriver_detach
, /* detach */
91 &nulldriver_cb_ops
, /* driver operations */
92 NULL
, /* bus operations */
94 ddi_quiesce_not_needed
, /* quiesce */
97 static struct modldrv modldrv
= {
98 &mod_driverops
, "nulldriver 1.1", &nulldriver_dev_ops
101 static struct modlinkage modlinkage
= {
102 MODREV_1
, &modldrv
, NULL
108 return (mod_install(&modlinkage
));
114 return (mod_remove(&modlinkage
));
118 _info(struct modinfo
*modinfop
)
120 return (mod_info(&modlinkage
, modinfop
));
125 nulldriver_getinfo(dev_info_t
*dip
, ddi_info_cmd_t infocmd
,
126 void *arg
, void **result
)
128 return (DDI_FAILURE
);
133 nulldriver_probe(dev_info_t
*dip
)
136 * We want to succeed probe so that the node gets assigned a unit
139 if (ddi_dev_is_sid(dip
) == DDI_SUCCESS
)
140 return (DDI_PROBE_DONTCARE
);
141 return (DDI_PROBE_DONTCARE
);
145 * nulldriver_attach()
146 * attach(9e) entrypoint.
150 nulldriver_attach(dev_info_t
*dip
, ddi_attach_cmd_t cmd
)
155 return (DDI_SUCCESS
);
159 return (DDI_FAILURE
);
164 * nulldriver_detach()
165 * detach(9E) entrypoint
169 nulldriver_detach(dev_info_t
*dip
, ddi_detach_cmd_t cmd
)
174 return (DDI_SUCCESS
);
178 return (DDI_FAILURE
);