Unleashed v1.4
[unleashed.git] / usr / src / uts / common / io / nulldriver.c
blob8e1ba7f3290f9dc72e4c2a5778cf7adbdcd4c224
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
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,
36 * with nulldriver.
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
46 * services.
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>
54 #include <sys/conf.h>
55 #include <sys/ddi.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 = {
65 nodev, /* open */
66 nodev, /* close */
67 nodev, /* strategy */
68 nodev, /* print */
69 nodev, /* dump */
70 nodev, /* read */
71 nodev, /* write */
72 nodev, /* ioctl */
73 nodev, /* devmap */
74 nodev, /* mmap */
75 nodev, /* segmap */
76 nochpoll, /* poll */
77 ddi_prop_op, /* cb_prop_op */
78 0, /* streamtab */
79 D_MP | D_NEW | D_HOTPLUG /* Driver compatibility flag */
82 static struct dev_ops nulldriver_dev_ops = {
83 DEVO_REV, /* devo_rev, */
84 0, /* refcnt */
85 nulldriver_getinfo, /* info */
86 nodev, /* identify */
87 nulldriver_probe, /* probe */
88 nulldriver_attach, /* attach */
89 nulldriver_detach, /* detach */
90 nodev, /* reset */
91 &nulldriver_cb_ops, /* driver operations */
92 NULL, /* bus operations */
93 NULL, /* power */
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
106 _init(void)
108 return (mod_install(&modlinkage));
112 _fini(void)
114 return (mod_remove(&modlinkage));
118 _info(struct modinfo *modinfop)
120 return (mod_info(&modlinkage, modinfop));
123 /*ARGSUSED*/
124 static int
125 nulldriver_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd,
126 void *arg, void **result)
128 return (DDI_FAILURE);
131 /*ARGSUSED*/
132 static int
133 nulldriver_probe(dev_info_t *dip)
136 * We want to succeed probe so that the node gets assigned a unit
137 * address "@addr".
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.
148 /* ARGSUSED */
149 static int
150 nulldriver_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
152 switch (cmd) {
153 case DDI_ATTACH:
154 case DDI_RESUME:
155 return (DDI_SUCCESS);
157 case DDI_PM_RESUME:
158 default:
159 return (DDI_FAILURE);
164 * nulldriver_detach()
165 * detach(9E) entrypoint
167 /* ARGSUSED */
168 static int
169 nulldriver_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
171 switch (cmd) {
172 case DDI_DETACH:
173 case DDI_SUSPEND:
174 return (DDI_SUCCESS);
176 case DDI_PM_SUSPEND:
177 default:
178 return (DDI_FAILURE);