xref: /illumos-gate/usr/src/uts/intel/io/cpunex.c (revision cd964fce751ca752af4158842063a9579a2d4331)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 
27 /*
28  * CPU nexus driver
29  */
30 
31 #include	<sys/types.h>
32 #include	<sys/param.h>
33 #include	<sys/conf.h>
34 #include	<sys/devops.h>
35 #include	<sys/modctl.h>
36 #include	<sys/cmn_err.h>
37 #include	<sys/ddi.h>
38 #include	<sys/sunddi.h>
39 #include	<sys/sunndi.h>
40 
41 static int cpunex_attach(dev_info_t *, ddi_attach_cmd_t);
42 static int cpunex_detach(dev_info_t *, ddi_detach_cmd_t);
43 static int cpunex_bus_ctl(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
44     void *, void *);
45 
46 static struct bus_ops cpunex_bus_ops = {
47 	BUSO_REV,
48 	nullbusmap,
49 	NULL,
50 	NULL,
51 	NULL,
52 	i_ddi_map_fault,
53 	ddi_no_dma_map,
54 	ddi_no_dma_allochdl,
55 	ddi_no_dma_freehdl,
56 	ddi_no_dma_bindhdl,
57 	ddi_no_dma_unbindhdl,
58 	ddi_no_dma_flush,
59 	ddi_no_dma_win,
60 	ddi_no_dma_mctl,
61 	cpunex_bus_ctl,
62 	ddi_bus_prop_op,
63 };
64 
65 static struct dev_ops cpunex_ops = {
66 	DEVO_REV,
67 	0,
68 	ddi_no_info,
69 	nulldev,
70 	nulldev,
71 	cpunex_attach,
72 	cpunex_detach,
73 	nodev,
74 	NULL,
75 	&cpunex_bus_ops,
76 	NULL,
77 	ddi_quiesce_not_needed,		/* quiesce */
78 };
79 
80 static struct modldrv modldrv = {
81 	&mod_driverops,
82 	"cpu nexus driver",
83 	&cpunex_ops
84 };
85 
86 static struct modlinkage modlinkage = {
87 	MODREV_1,
88 	&modldrv,
89 	NULL
90 };
91 
92 /*
93  * cpunex_bus_ctl()
94  *    This routine implements nexus bus ctl operations. Of importance are
95  *    DDI_CTLOPS_REPORTDEV, DDI_CTLOPS_INITCHILD, DDI_CTLOPS_UNINITCHILD
96  *    and DDI_CTLOPS_POWER. For DDI_CTLOPS_INITCHILD, it tries to lookup
97  *    reg property on the child node and builds and sets the name.
98  */
99 static int
100 cpunex_bus_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t op, void *arg,
101     void *result)
102 {
103 	switch (op) {
104 		case DDI_CTLOPS_REPORTDEV: {
105 			dev_info_t *pdip = ddi_get_parent(rdip);
106 			cmn_err(CE_CONT, "?%s%d at %s%d",
107 			    ddi_node_name(rdip), ddi_get_instance(rdip),
108 			    ddi_node_name(pdip), ddi_get_instance(pdip));
109 			return (DDI_SUCCESS);
110 		}
111 
112 		case DDI_CTLOPS_INITCHILD: {
113 			dev_info_t *cdip = (dev_info_t *)arg;
114 			int i;
115 			char caddr[MAXNAMELEN];
116 
117 			i = ddi_prop_get_int(DDI_DEV_T_ANY, cdip,
118 			    DDI_PROP_DONTPASS, "reg", -1);
119 
120 			if (i == -1) {
121 				cmn_err(CE_NOTE, "!%s(%d): \"reg\" property "
122 				    "not found", ddi_node_name(cdip),
123 				    ddi_get_instance(cdip));
124 				return (DDI_NOT_WELL_FORMED);
125 			}
126 
127 			(void) sprintf(caddr, "%d", i);
128 			ddi_set_name_addr(cdip, caddr);
129 
130 			return (DDI_SUCCESS);
131 		}
132 
133 		case DDI_CTLOPS_UNINITCHILD: {
134 			ddi_prop_remove_all((dev_info_t *)arg);
135 			ddi_set_name_addr((dev_info_t *)arg, NULL);
136 			return (DDI_SUCCESS);
137 		}
138 
139 		default: {
140 			return (ddi_ctlops(dip, rdip, op, arg, result));
141 		}
142 	}
143 }
144 
145 /*ARGSUSED*/
146 static int
147 cpunex_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
148 {
149 	switch (cmd) {
150 	case DDI_ATTACH:
151 	case DDI_RESUME:
152 		break;
153 	default:
154 		return (DDI_FAILURE);
155 	}
156 
157 	return (DDI_SUCCESS);
158 }
159 
160 /*ARGSUSED*/
161 static int
162 cpunex_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
163 {
164 	switch (cmd) {
165 	case DDI_DETACH:
166 	case DDI_SUSPEND:
167 		break;
168 	default:
169 		return (DDI_FAILURE);
170 	}
171 
172 	return (DDI_SUCCESS);
173 }
174 
175 int
176 _init(void)
177 {
178 	int error;
179 
180 	error = mod_install(&modlinkage);
181 	return (error);
182 }
183 
184 int
185 _fini(void)
186 {
187 	int error;
188 
189 	error = mod_remove(&modlinkage);
190 	return (error);
191 }
192 
193 int
194 _info(struct modinfo *modinfop)
195 {
196 	return (mod_info(&modlinkage, modinfop));
197 }
198