1*12004Sjiang.liu@intel.com /*
2*12004Sjiang.liu@intel.com * CDDL HEADER START
3*12004Sjiang.liu@intel.com *
4*12004Sjiang.liu@intel.com * The contents of this file are subject to the terms of the
5*12004Sjiang.liu@intel.com * Common Development and Distribution License (the "License").
6*12004Sjiang.liu@intel.com * You may not use this file except in compliance with the License.
7*12004Sjiang.liu@intel.com *
8*12004Sjiang.liu@intel.com * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12004Sjiang.liu@intel.com * or http://www.opensolaris.org/os/licensing.
10*12004Sjiang.liu@intel.com * See the License for the specific language governing permissions
11*12004Sjiang.liu@intel.com * and limitations under the License.
12*12004Sjiang.liu@intel.com *
13*12004Sjiang.liu@intel.com * When distributing Covered Code, include this CDDL HEADER in each
14*12004Sjiang.liu@intel.com * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12004Sjiang.liu@intel.com * If applicable, add the following below this CDDL HEADER, with the
16*12004Sjiang.liu@intel.com * fields enclosed by brackets "[]" replaced with your own identifying
17*12004Sjiang.liu@intel.com * information: Portions Copyright [yyyy] [name of copyright owner]
18*12004Sjiang.liu@intel.com *
19*12004Sjiang.liu@intel.com * CDDL HEADER END
20*12004Sjiang.liu@intel.com */
21*12004Sjiang.liu@intel.com
22*12004Sjiang.liu@intel.com /*
23*12004Sjiang.liu@intel.com * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24*12004Sjiang.liu@intel.com * Use is subject to license terms.
25*12004Sjiang.liu@intel.com */
26*12004Sjiang.liu@intel.com
27*12004Sjiang.liu@intel.com /*
28*12004Sjiang.liu@intel.com * I/O support routines for DR
29*12004Sjiang.liu@intel.com */
30*12004Sjiang.liu@intel.com
31*12004Sjiang.liu@intel.com #include <sys/types.h>
32*12004Sjiang.liu@intel.com #include <sys/cmn_err.h>
33*12004Sjiang.liu@intel.com #include <sys/debug.h>
34*12004Sjiang.liu@intel.com #include <sys/errno.h>
35*12004Sjiang.liu@intel.com #include <sys/dditypes.h>
36*12004Sjiang.liu@intel.com #include <sys/ddi.h>
37*12004Sjiang.liu@intel.com #include <sys/sunddi.h>
38*12004Sjiang.liu@intel.com #include <sys/sunndi.h>
39*12004Sjiang.liu@intel.com #include <sys/ndi_impldefs.h>
40*12004Sjiang.liu@intel.com #include <sys/kmem.h>
41*12004Sjiang.liu@intel.com #include <sys/promif.h>
42*12004Sjiang.liu@intel.com #include <sys/sysmacros.h>
43*12004Sjiang.liu@intel.com #include <sys/archsystm.h>
44*12004Sjiang.liu@intel.com #include <sys/machsystm.h>
45*12004Sjiang.liu@intel.com
46*12004Sjiang.liu@intel.com #include <sys/dr.h>
47*12004Sjiang.liu@intel.com #include <sys/dr_util.h>
48*12004Sjiang.liu@intel.com #include <sys/drmach.h>
49*12004Sjiang.liu@intel.com
50*12004Sjiang.liu@intel.com void
dr_init_io_unit(dr_io_unit_t * ip)51*12004Sjiang.liu@intel.com dr_init_io_unit(dr_io_unit_t *ip)
52*12004Sjiang.liu@intel.com {
53*12004Sjiang.liu@intel.com dr_state_t new_state;
54*12004Sjiang.liu@intel.com
55*12004Sjiang.liu@intel.com if (DR_DEV_IS_ATTACHED(&ip->sbi_cm)) {
56*12004Sjiang.liu@intel.com new_state = DR_STATE_CONFIGURED;
57*12004Sjiang.liu@intel.com ip->sbi_cm.sbdev_cond = SBD_COND_OK;
58*12004Sjiang.liu@intel.com } else if (DR_DEV_IS_PRESENT(&ip->sbi_cm)) {
59*12004Sjiang.liu@intel.com new_state = DR_STATE_CONNECTED;
60*12004Sjiang.liu@intel.com ip->sbi_cm.sbdev_cond = SBD_COND_OK;
61*12004Sjiang.liu@intel.com } else {
62*12004Sjiang.liu@intel.com new_state = DR_STATE_EMPTY;
63*12004Sjiang.liu@intel.com }
64*12004Sjiang.liu@intel.com dr_device_transition(&ip->sbi_cm, new_state);
65*12004Sjiang.liu@intel.com }
66*12004Sjiang.liu@intel.com
67*12004Sjiang.liu@intel.com /*ARGSUSED*/
68*12004Sjiang.liu@intel.com void
dr_attach_io(dr_handle_t * hp,dr_common_unit_t * cp)69*12004Sjiang.liu@intel.com dr_attach_io(dr_handle_t *hp, dr_common_unit_t *cp)
70*12004Sjiang.liu@intel.com {
71*12004Sjiang.liu@intel.com sbd_error_t *err;
72*12004Sjiang.liu@intel.com
73*12004Sjiang.liu@intel.com dr_lock_status(hp->h_bd);
74*12004Sjiang.liu@intel.com err = drmach_configure(cp->sbdev_id, 0);
75*12004Sjiang.liu@intel.com dr_unlock_status(hp->h_bd);
76*12004Sjiang.liu@intel.com
77*12004Sjiang.liu@intel.com if (!err)
78*12004Sjiang.liu@intel.com err = drmach_io_post_attach(cp->sbdev_id);
79*12004Sjiang.liu@intel.com
80*12004Sjiang.liu@intel.com if (err)
81*12004Sjiang.liu@intel.com DRERR_SET_C(&cp->sbdev_error, &err);
82*12004Sjiang.liu@intel.com }
83*12004Sjiang.liu@intel.com
84*12004Sjiang.liu@intel.com /*
85*12004Sjiang.liu@intel.com * remove device nodes for the branch indicated by cp
86*12004Sjiang.liu@intel.com */
87*12004Sjiang.liu@intel.com /*ARGSUSED*/
88*12004Sjiang.liu@intel.com void
dr_detach_io(dr_handle_t * hp,dr_common_unit_t * cp)89*12004Sjiang.liu@intel.com dr_detach_io(dr_handle_t *hp, dr_common_unit_t *cp)
90*12004Sjiang.liu@intel.com {
91*12004Sjiang.liu@intel.com sbd_error_t *err;
92*12004Sjiang.liu@intel.com
93*12004Sjiang.liu@intel.com err = drmach_unconfigure(cp->sbdev_id, 0);
94*12004Sjiang.liu@intel.com
95*12004Sjiang.liu@intel.com if (!err)
96*12004Sjiang.liu@intel.com err = drmach_unconfigure(cp->sbdev_id, DEVI_BRANCH_DESTROY);
97*12004Sjiang.liu@intel.com
98*12004Sjiang.liu@intel.com if (!err)
99*12004Sjiang.liu@intel.com err = drmach_io_post_release(cp->sbdev_id);
100*12004Sjiang.liu@intel.com
101*12004Sjiang.liu@intel.com if (err) {
102*12004Sjiang.liu@intel.com dr_device_transition(cp, DR_STATE_CONFIGURED);
103*12004Sjiang.liu@intel.com DRERR_SET_C(&cp->sbdev_error, &err);
104*12004Sjiang.liu@intel.com }
105*12004Sjiang.liu@intel.com }
106*12004Sjiang.liu@intel.com
107*12004Sjiang.liu@intel.com /*ARGSUSED*/
108*12004Sjiang.liu@intel.com int
dr_disconnect_io(dr_io_unit_t * ip)109*12004Sjiang.liu@intel.com dr_disconnect_io(dr_io_unit_t *ip)
110*12004Sjiang.liu@intel.com {
111*12004Sjiang.liu@intel.com return (0);
112*12004Sjiang.liu@intel.com }
113*12004Sjiang.liu@intel.com
114*12004Sjiang.liu@intel.com /*ARGSUSED*/
115*12004Sjiang.liu@intel.com int
dr_pre_attach_io(dr_handle_t * hp,dr_common_unit_t ** devlist,int devnum)116*12004Sjiang.liu@intel.com dr_pre_attach_io(dr_handle_t *hp,
117*12004Sjiang.liu@intel.com dr_common_unit_t **devlist, int devnum)
118*12004Sjiang.liu@intel.com {
119*12004Sjiang.liu@intel.com int d;
120*12004Sjiang.liu@intel.com
121*12004Sjiang.liu@intel.com for (d = 0; d < devnum; d++) {
122*12004Sjiang.liu@intel.com dr_common_unit_t *cp = devlist[d];
123*12004Sjiang.liu@intel.com
124*12004Sjiang.liu@intel.com cmn_err(CE_CONT, "OS configure %s", cp->sbdev_path);
125*12004Sjiang.liu@intel.com }
126*12004Sjiang.liu@intel.com
127*12004Sjiang.liu@intel.com return (0);
128*12004Sjiang.liu@intel.com }
129*12004Sjiang.liu@intel.com
130*12004Sjiang.liu@intel.com /*ARGSUSED*/
131*12004Sjiang.liu@intel.com int
dr_post_attach_io(dr_handle_t * hp,dr_common_unit_t ** devlist,int devnum)132*12004Sjiang.liu@intel.com dr_post_attach_io(dr_handle_t *hp,
133*12004Sjiang.liu@intel.com dr_common_unit_t **devlist, int devnum)
134*12004Sjiang.liu@intel.com {
135*12004Sjiang.liu@intel.com return (0);
136*12004Sjiang.liu@intel.com }
137*12004Sjiang.liu@intel.com
138*12004Sjiang.liu@intel.com static int
dr_check_io_refs(dr_handle_t * hp,dr_common_unit_t ** devlist,int devnum)139*12004Sjiang.liu@intel.com dr_check_io_refs(dr_handle_t *hp, dr_common_unit_t **devlist, int devnum)
140*12004Sjiang.liu@intel.com {
141*12004Sjiang.liu@intel.com register int i, reftotal = 0;
142*12004Sjiang.liu@intel.com static fn_t f = "dr_check_io_refs";
143*12004Sjiang.liu@intel.com
144*12004Sjiang.liu@intel.com for (i = 0; i < devnum; i++) {
145*12004Sjiang.liu@intel.com dr_io_unit_t *ip = (dr_io_unit_t *)devlist[i];
146*12004Sjiang.liu@intel.com dev_info_t *dip;
147*12004Sjiang.liu@intel.com int ref;
148*12004Sjiang.liu@intel.com int refcount_non_gldv3;
149*12004Sjiang.liu@intel.com sbd_error_t *err;
150*12004Sjiang.liu@intel.com
151*12004Sjiang.liu@intel.com err = drmach_get_dip(ip->sbi_cm.sbdev_id, &dip);
152*12004Sjiang.liu@intel.com if (err)
153*12004Sjiang.liu@intel.com DRERR_SET_C(&ip->sbi_cm.sbdev_error, &err);
154*12004Sjiang.liu@intel.com else if (dip != NULL) {
155*12004Sjiang.liu@intel.com ref = 0;
156*12004Sjiang.liu@intel.com refcount_non_gldv3 = 0;
157*12004Sjiang.liu@intel.com ASSERT(e_ddi_branch_held(dip));
158*12004Sjiang.liu@intel.com dr_check_devices(dip, &ref, hp, NULL, NULL,
159*12004Sjiang.liu@intel.com 0, &refcount_non_gldv3);
160*12004Sjiang.liu@intel.com ASSERT(refcount_non_gldv3 >= 0);
161*12004Sjiang.liu@intel.com ASSERT(ref >= refcount_non_gldv3);
162*12004Sjiang.liu@intel.com /*
163*12004Sjiang.liu@intel.com * Ignore reference counts of non-gldv3 network devices
164*12004Sjiang.liu@intel.com * as Crossbow creates reference counts for non-active
165*12004Sjiang.liu@intel.com * (unplumbed) instances. Reference count check in
166*12004Sjiang.liu@intel.com * detach() known to prevent device from detaching
167*12004Sjiang.liu@intel.com * as necessary.
168*12004Sjiang.liu@intel.com */
169*12004Sjiang.liu@intel.com ref -= refcount_non_gldv3;
170*12004Sjiang.liu@intel.com hp->h_err = NULL;
171*12004Sjiang.liu@intel.com if (ref) {
172*12004Sjiang.liu@intel.com dr_dev_err(CE_WARN, &ip->sbi_cm, ESBD_BUSY);
173*12004Sjiang.liu@intel.com }
174*12004Sjiang.liu@intel.com PR_IO("%s: dip(%s) ref = %d\n",
175*12004Sjiang.liu@intel.com f, ddi_get_name(dip), ref);
176*12004Sjiang.liu@intel.com reftotal += ref;
177*12004Sjiang.liu@intel.com } else {
178*12004Sjiang.liu@intel.com PR_IO("%s: NO dip for id (0x%x)\n",
179*12004Sjiang.liu@intel.com f, (uint_t)(uintptr_t)ip->sbi_cm.sbdev_id);
180*12004Sjiang.liu@intel.com }
181*12004Sjiang.liu@intel.com }
182*12004Sjiang.liu@intel.com
183*12004Sjiang.liu@intel.com return (reftotal);
184*12004Sjiang.liu@intel.com }
185*12004Sjiang.liu@intel.com
186*12004Sjiang.liu@intel.com int
dr_pre_release_io(dr_handle_t * hp,dr_common_unit_t ** devlist,int devnum)187*12004Sjiang.liu@intel.com dr_pre_release_io(dr_handle_t *hp,
188*12004Sjiang.liu@intel.com dr_common_unit_t **devlist, int devnum)
189*12004Sjiang.liu@intel.com {
190*12004Sjiang.liu@intel.com static fn_t f = "dr_pre_release_io";
191*12004Sjiang.liu@intel.com int d;
192*12004Sjiang.liu@intel.com
193*12004Sjiang.liu@intel.com ASSERT(devnum > 0);
194*12004Sjiang.liu@intel.com
195*12004Sjiang.liu@intel.com /* fail if any I/O device pre-release fails */
196*12004Sjiang.liu@intel.com for (d = 0; d < devnum; d++) {
197*12004Sjiang.liu@intel.com dr_io_unit_t *ip = (dr_io_unit_t *)devlist[d];
198*12004Sjiang.liu@intel.com
199*12004Sjiang.liu@intel.com if ((hp->h_err = drmach_io_pre_release(
200*12004Sjiang.liu@intel.com ip->sbi_cm.sbdev_id)) != 0) {
201*12004Sjiang.liu@intel.com return (-1);
202*12004Sjiang.liu@intel.com }
203*12004Sjiang.liu@intel.com }
204*12004Sjiang.liu@intel.com
205*12004Sjiang.liu@intel.com for (d = 0; d < devnum; d++) {
206*12004Sjiang.liu@intel.com dr_io_unit_t *ip = (dr_io_unit_t *)devlist[d];
207*12004Sjiang.liu@intel.com sbd_error_t *err;
208*12004Sjiang.liu@intel.com
209*12004Sjiang.liu@intel.com err = drmach_release(ip->sbi_cm.sbdev_id);
210*12004Sjiang.liu@intel.com if (err) {
211*12004Sjiang.liu@intel.com DRERR_SET_C(&ip->sbi_cm.sbdev_error,
212*12004Sjiang.liu@intel.com &err);
213*12004Sjiang.liu@intel.com return (-1);
214*12004Sjiang.liu@intel.com }
215*12004Sjiang.liu@intel.com }
216*12004Sjiang.liu@intel.com
217*12004Sjiang.liu@intel.com /* fail if any I/O devices are still referenced */
218*12004Sjiang.liu@intel.com if (dr_check_io_refs(hp, devlist, devnum) > 0) {
219*12004Sjiang.liu@intel.com PR_IO("%s: failed - I/O devices ref'd\n", f);
220*12004Sjiang.liu@intel.com
221*12004Sjiang.liu@intel.com /* recover before return error */
222*12004Sjiang.liu@intel.com for (d = 0; d < devnum; d++) {
223*12004Sjiang.liu@intel.com dr_io_unit_t *ip = (dr_io_unit_t *)devlist[d];
224*12004Sjiang.liu@intel.com sbd_error_t *err;
225*12004Sjiang.liu@intel.com err = drmach_io_unrelease(ip->sbi_cm.sbdev_id);
226*12004Sjiang.liu@intel.com if (err) {
227*12004Sjiang.liu@intel.com DRERR_SET_C(&ip->sbi_cm.sbdev_error, &err);
228*12004Sjiang.liu@intel.com return (-1);
229*12004Sjiang.liu@intel.com }
230*12004Sjiang.liu@intel.com }
231*12004Sjiang.liu@intel.com return (-1);
232*12004Sjiang.liu@intel.com }
233*12004Sjiang.liu@intel.com return (0);
234*12004Sjiang.liu@intel.com }
235*12004Sjiang.liu@intel.com
236*12004Sjiang.liu@intel.com /*ARGSUSED*/
237*12004Sjiang.liu@intel.com int
dr_pre_detach_io(dr_handle_t * hp,dr_common_unit_t ** devlist,int devnum)238*12004Sjiang.liu@intel.com dr_pre_detach_io(dr_handle_t *hp,
239*12004Sjiang.liu@intel.com dr_common_unit_t **devlist, int devnum)
240*12004Sjiang.liu@intel.com {
241*12004Sjiang.liu@intel.com int d;
242*12004Sjiang.liu@intel.com
243*12004Sjiang.liu@intel.com ASSERT(devnum > 0);
244*12004Sjiang.liu@intel.com
245*12004Sjiang.liu@intel.com for (d = 0; d < devnum; d++) {
246*12004Sjiang.liu@intel.com dr_common_unit_t *cp = devlist[d];
247*12004Sjiang.liu@intel.com
248*12004Sjiang.liu@intel.com cmn_err(CE_CONT, "OS unconfigure %s", cp->sbdev_path);
249*12004Sjiang.liu@intel.com }
250*12004Sjiang.liu@intel.com
251*12004Sjiang.liu@intel.com return (0);
252*12004Sjiang.liu@intel.com }
253*12004Sjiang.liu@intel.com
254*12004Sjiang.liu@intel.com /*ARGSUSED*/
255*12004Sjiang.liu@intel.com int
dr_post_detach_io(dr_handle_t * hp,dr_common_unit_t ** devlist,int devnum)256*12004Sjiang.liu@intel.com dr_post_detach_io(dr_handle_t *hp, dr_common_unit_t **devlist, int devnum)
257*12004Sjiang.liu@intel.com {
258*12004Sjiang.liu@intel.com register int i;
259*12004Sjiang.liu@intel.com int rv = 0;
260*12004Sjiang.liu@intel.com static fn_t f = "dr_post_detach_io";
261*12004Sjiang.liu@intel.com
262*12004Sjiang.liu@intel.com ASSERT(devnum > 0);
263*12004Sjiang.liu@intel.com for (i = 0; i < devnum; i++) {
264*12004Sjiang.liu@intel.com dr_common_unit_t *cp = devlist[i];
265*12004Sjiang.liu@intel.com if (cp->sbdev_error != NULL) {
266*12004Sjiang.liu@intel.com PR_IO("%s: Failed\n", f);
267*12004Sjiang.liu@intel.com rv = -1;
268*12004Sjiang.liu@intel.com break;
269*12004Sjiang.liu@intel.com }
270*12004Sjiang.liu@intel.com }
271*12004Sjiang.liu@intel.com return (rv);
272*12004Sjiang.liu@intel.com }
273*12004Sjiang.liu@intel.com
274*12004Sjiang.liu@intel.com static void
dr_get_comp_cond(dr_io_unit_t * ip,dev_info_t * dip)275*12004Sjiang.liu@intel.com dr_get_comp_cond(dr_io_unit_t *ip, dev_info_t *dip)
276*12004Sjiang.liu@intel.com {
277*12004Sjiang.liu@intel.com if (dip == NULL) {
278*12004Sjiang.liu@intel.com ip->sbi_cm.sbdev_cond = SBD_COND_UNKNOWN;
279*12004Sjiang.liu@intel.com return;
280*12004Sjiang.liu@intel.com }
281*12004Sjiang.liu@intel.com
282*12004Sjiang.liu@intel.com if (DEVI(dip)->devi_flags & DEVI_RETIRED) {
283*12004Sjiang.liu@intel.com ip->sbi_cm.sbdev_cond = SBD_COND_FAILED;
284*12004Sjiang.liu@intel.com return;
285*12004Sjiang.liu@intel.com }
286*12004Sjiang.liu@intel.com
287*12004Sjiang.liu@intel.com if (DR_DEV_IS_ATTACHED(&ip->sbi_cm)) {
288*12004Sjiang.liu@intel.com ip->sbi_cm.sbdev_cond = SBD_COND_OK;
289*12004Sjiang.liu@intel.com } else if (DR_DEV_IS_PRESENT(&ip->sbi_cm)) {
290*12004Sjiang.liu@intel.com ip->sbi_cm.sbdev_cond = SBD_COND_OK;
291*12004Sjiang.liu@intel.com }
292*12004Sjiang.liu@intel.com }
293*12004Sjiang.liu@intel.com
294*12004Sjiang.liu@intel.com int
dr_io_status(dr_handle_t * hp,dr_devset_t devset,sbd_dev_stat_t * dsp)295*12004Sjiang.liu@intel.com dr_io_status(dr_handle_t *hp, dr_devset_t devset, sbd_dev_stat_t *dsp)
296*12004Sjiang.liu@intel.com {
297*12004Sjiang.liu@intel.com int i, ix;
298*12004Sjiang.liu@intel.com dr_board_t *bp;
299*12004Sjiang.liu@intel.com sbd_io_stat_t *isp;
300*12004Sjiang.liu@intel.com dr_io_unit_t *ip;
301*12004Sjiang.liu@intel.com
302*12004Sjiang.liu@intel.com bp = hp->h_bd;
303*12004Sjiang.liu@intel.com
304*12004Sjiang.liu@intel.com /*
305*12004Sjiang.liu@intel.com * Only look for requested devices that are actually present.
306*12004Sjiang.liu@intel.com */
307*12004Sjiang.liu@intel.com devset &= DR_DEVS_PRESENT(bp);
308*12004Sjiang.liu@intel.com
309*12004Sjiang.liu@intel.com for (i = ix = 0; i < MAX_IO_UNITS_PER_BOARD; i++) {
310*12004Sjiang.liu@intel.com drmachid_t id;
311*12004Sjiang.liu@intel.com dev_info_t *dip;
312*12004Sjiang.liu@intel.com sbd_error_t *err;
313*12004Sjiang.liu@intel.com drmach_status_t pstat;
314*12004Sjiang.liu@intel.com
315*12004Sjiang.liu@intel.com if (DEVSET_IN_SET(devset, SBD_COMP_IO, i) == 0)
316*12004Sjiang.liu@intel.com continue;
317*12004Sjiang.liu@intel.com
318*12004Sjiang.liu@intel.com ip = dr_get_io_unit(bp, i);
319*12004Sjiang.liu@intel.com
320*12004Sjiang.liu@intel.com if (ip->sbi_cm.sbdev_state == DR_STATE_EMPTY) {
321*12004Sjiang.liu@intel.com /* present, but not fully initialized */
322*12004Sjiang.liu@intel.com continue;
323*12004Sjiang.liu@intel.com }
324*12004Sjiang.liu@intel.com
325*12004Sjiang.liu@intel.com id = ip->sbi_cm.sbdev_id;
326*12004Sjiang.liu@intel.com if (id == (drmachid_t)0)
327*12004Sjiang.liu@intel.com continue;
328*12004Sjiang.liu@intel.com
329*12004Sjiang.liu@intel.com err = drmach_status(ip->sbi_cm.sbdev_id, &pstat);
330*12004Sjiang.liu@intel.com if (err) {
331*12004Sjiang.liu@intel.com DRERR_SET_C(&ip->sbi_cm.sbdev_error, &err);
332*12004Sjiang.liu@intel.com return (-1);
333*12004Sjiang.liu@intel.com }
334*12004Sjiang.liu@intel.com
335*12004Sjiang.liu@intel.com dip = NULL;
336*12004Sjiang.liu@intel.com err = drmach_get_dip(id, &dip);
337*12004Sjiang.liu@intel.com if (err) {
338*12004Sjiang.liu@intel.com /* catch this in debug kernels */
339*12004Sjiang.liu@intel.com ASSERT(0);
340*12004Sjiang.liu@intel.com
341*12004Sjiang.liu@intel.com sbd_err_clear(&err);
342*12004Sjiang.liu@intel.com continue;
343*12004Sjiang.liu@intel.com }
344*12004Sjiang.liu@intel.com
345*12004Sjiang.liu@intel.com isp = &dsp->d_io;
346*12004Sjiang.liu@intel.com bzero((caddr_t)isp, sizeof (*isp));
347*12004Sjiang.liu@intel.com
348*12004Sjiang.liu@intel.com isp->is_cm.c_id.c_type = ip->sbi_cm.sbdev_type;
349*12004Sjiang.liu@intel.com isp->is_cm.c_id.c_unit = ip->sbi_cm.sbdev_unum;
350*12004Sjiang.liu@intel.com (void) strlcpy(isp->is_cm.c_id.c_name, pstat.type,
351*12004Sjiang.liu@intel.com sizeof (isp->is_cm.c_id.c_name));
352*12004Sjiang.liu@intel.com
353*12004Sjiang.liu@intel.com dr_get_comp_cond(ip, dip);
354*12004Sjiang.liu@intel.com isp->is_cm.c_cond = ip->sbi_cm.sbdev_cond;
355*12004Sjiang.liu@intel.com isp->is_cm.c_busy = ip->sbi_cm.sbdev_busy | pstat.busy;
356*12004Sjiang.liu@intel.com isp->is_cm.c_time = ip->sbi_cm.sbdev_time;
357*12004Sjiang.liu@intel.com isp->is_cm.c_ostate = ip->sbi_cm.sbdev_ostate;
358*12004Sjiang.liu@intel.com isp->is_cm.c_sflags = 0;
359*12004Sjiang.liu@intel.com
360*12004Sjiang.liu@intel.com if (dip == NULL) {
361*12004Sjiang.liu@intel.com isp->is_pathname[0] = '\0';
362*12004Sjiang.liu@intel.com isp->is_referenced = 0;
363*12004Sjiang.liu@intel.com isp->is_unsafe_count = 0;
364*12004Sjiang.liu@intel.com } else {
365*12004Sjiang.liu@intel.com int refcount = 0, idx = 0;
366*12004Sjiang.liu@intel.com uint64_t unsafe_devs[SBD_MAX_UNSAFE];
367*12004Sjiang.liu@intel.com
368*12004Sjiang.liu@intel.com ASSERT(e_ddi_branch_held(dip));
369*12004Sjiang.liu@intel.com (void) ddi_pathname(dip, isp->is_pathname);
370*12004Sjiang.liu@intel.com
371*12004Sjiang.liu@intel.com /* check reference and unsafe counts on devices */
372*12004Sjiang.liu@intel.com isp->is_unsafe_count = 0;
373*12004Sjiang.liu@intel.com dr_check_devices(dip, &refcount, hp, unsafe_devs,
374*12004Sjiang.liu@intel.com &idx, SBD_MAX_UNSAFE, NULL);
375*12004Sjiang.liu@intel.com while (idx > 0) {
376*12004Sjiang.liu@intel.com isp->is_unsafe_list[idx-1] = unsafe_devs[idx-1];
377*12004Sjiang.liu@intel.com --idx;
378*12004Sjiang.liu@intel.com }
379*12004Sjiang.liu@intel.com
380*12004Sjiang.liu@intel.com isp->is_referenced = (refcount == 0) ? 0 : 1;
381*12004Sjiang.liu@intel.com
382*12004Sjiang.liu@intel.com hp->h_err = NULL;
383*12004Sjiang.liu@intel.com }
384*12004Sjiang.liu@intel.com ix++;
385*12004Sjiang.liu@intel.com dsp++;
386*12004Sjiang.liu@intel.com }
387*12004Sjiang.liu@intel.com
388*12004Sjiang.liu@intel.com return (ix);
389*12004Sjiang.liu@intel.com }
390