xref: /illumos-gate/usr/src/uts/i86pc/sys/dr.h (revision d5ebc493)
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 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /*
26  * Copyright (c) 2010, Intel Corporation.
27  * All rights reserved.
28  */
29 
30 /*
31  * Copyright 2023 Oxide Computer Company
32  */
33 
34 #ifndef _SYS_DR_H
35 #define	_SYS_DR_H
36 #include <sys/types.h>
37 #include <sys/note.h>
38 #include <sys/processor.h>
39 #include <sys/obpdefs.h>
40 #include <sys/memlist.h>
41 #include <sys/mem_config.h>
42 #include <sys/param.h>			/* for MAXPATHLEN */
43 #include <sys/varargs.h>
44 #include <sys/sbd_ioctl.h>
45 #include <sys/dr_util.h>
46 #include <sys/drmach.h>
47 
48 #ifdef	__cplusplus
49 extern "C" {
50 #endif
51 
52 /*
53  * helper macros for constructing and reporting internal error messages.
54  * NOTE: each module which uses one or more this these macros is expected
55  * to supply a char *dr_ie_fmt string containing the SCCS filename
56  * expansion macro (percent M percent) and a sprintf %d to render the
57  * line number argument.
58  */
59 #define	DR_INTERNAL_ERROR(hp)				\
60 	drerr_new(1, ESBD_INTERNAL, dr_ie_fmt, __LINE__)
61 
62 #define	DR_OP_INTERNAL_ERROR(hp)			\
63 	drerr_set_c(CE_WARN, &(hp)->h_err,		\
64 		ESBD_INTERNAL, dr_ie_fmt, __LINE__)
65 
66 #define	DR_DEV_INTERNAL_ERROR(cp)			\
67 	drerr_set_c(CE_WARN, &(cp)->sbdev_error,	\
68 		ESBD_INTERNAL, dr_ie_fmt, __LINE__)
69 
70 /*
71  * Macros for keeping an error code and an associated list of integers.
72  */
73 #define	DR_MAX_ERR_INT		(32)
74 #define	DR_GET_E_CODE(sep)	((sep)->e_code)
75 #define	DR_SET_E_CODE(sep, en)	((sep)->e_code = (en))
76 #define	DR_GET_E_RSC(sep)	((sep)->e_rsc)
77 
78 /* Number of device node types. */
79 #define	DR_MAXNUM_NT		3
80 
81 /* used to map sbd_comp_type_t to array index */
82 #define	DEVSET_NIX(t)					\
83 	(((t) == SBD_COMP_CPU) ? 0 :			\
84 	((t) == SBD_COMP_MEM) ? 1 :			\
85 	((t) == SBD_COMP_IO) ? 2 :			\
86 	((t) == SBD_COMP_CMP) ? 0 : DR_MAXNUM_NT)
87 
88 /*
89  * Format of dr_devset_t bit masks:
90  *
91  * 64    56        48        40        32        24        16        8         0
92  *  |....|IIII|IIII|IIII|IIII|MMMM|MMMM|CCCC|CCCC|CCCC|CCCC|CCCC|CCCC|CCCC|CCCC|
93  *
94  * 1 = indicates respective component present/attached.
95  * I = I/O, M = Memory, C = CPU.
96  */
97 #define	DEVSET_CPU_OFFSET	0
98 #define	DEVSET_CPU_NUMBER	32
99 #define	DEVSET_MEM_OFFSET	(DEVSET_CPU_OFFSET + DEVSET_CPU_NUMBER)
100 #define	DEVSET_MEM_NUMBER	8
101 #define	DEVSET_IO_OFFSET	(DEVSET_MEM_OFFSET + DEVSET_MEM_NUMBER)
102 #define	DEVSET_IO_NUMBER	16
103 #define	DEVSET_MAX_BITS		(DEVSET_IO_OFFSET + DEVSET_IO_NUMBER)
104 
105 #define	DEVSET_BIX(t)					\
106 	(((t) == SBD_COMP_CPU) ? DEVSET_CPU_OFFSET :	\
107 	((t) == SBD_COMP_MEM) ? DEVSET_MEM_OFFSET :	\
108 	((t) == SBD_COMP_IO) ? DEVSET_IO_OFFSET :	\
109 	((t) == SBD_COMP_CMP) ? DEVSET_CPU_OFFSET : 0)
110 
111 #define	DEVSET_NT2DEVPOS(t, u)	(((t) == SBD_COMP_CMP) ?\
112 	(DEVSET_BIX(t) + (u) * MAX_CORES_PER_CMP) : DEVSET_BIX(t) + (u))
113 
114 #if (DEVSET_MAX_BITS <= 64)
115 typedef uint64_t		dr_devset_t;
116 
117 #define	DEVSET_ONEUNIT		((dr_devset_t)1)
118 #define	DEVSET_ANYUNIT		((dr_devset_t)(-1))
119 #define	DEVSET_CPU_NMASK	((dr_devset_t)((1ULL << DEVSET_CPU_NUMBER) - 1))
120 #define	DEVSET_MEM_NMASK	((dr_devset_t)((1ULL << DEVSET_MEM_NUMBER) - 1))
121 #define	DEVSET_IO_NMASK		((dr_devset_t)((1ULL << DEVSET_IO_NUMBER) - 1))
122 #define	DEVSET_CMP_NMASK	((dr_devset_t)((1ULL << MAX_CORES_PER_CMP) - 1))
123 
124 #define	DEVSET_NMASK(t)					\
125 	(((t) == SBD_COMP_CPU) ? DEVSET_CPU_NMASK :	\
126 	((t) == SBD_COMP_MEM) ? DEVSET_MEM_NMASK :	\
127 	((t) == SBD_COMP_IO) ? DEVSET_IO_NMASK :	\
128 	((t) == SBD_COMP_CMP) ? DEVSET_CPU_NMASK : 0)
129 
130 #define	DEVSET_MASK					\
131 	((DEVSET_CPU_NMASK << DEVSET_CPU_OFFSET) |	\
132 	(DEVSET_MEM_NMASK << DEVSET_MEM_OFFSET) |	\
133 	(DEVSET_IO_NMASK << DEVSET_IO_OFFSET))
134 
135 #define	DEVSET(t, u) \
136 	(((u) == DEVSET_ANYUNIT) ? \
137 		((DEVSET_NMASK(t) << DEVSET_NT2DEVPOS((t), 0)) & \
138 		DEVSET_MASK) : \
139 	((t) == SBD_COMP_CMP) ? \
140 		(DEVSET_CMP_NMASK << DEVSET_NT2DEVPOS((t), (u))) : \
141 		(DEVSET_ONEUNIT << DEVSET_NT2DEVPOS((t), (u))))
142 
143 #define	DEVSET_IS_NULL(ds)	((ds) == 0)
144 #define	DEVSET_IN_SET(ds, t, u)	(((ds) & DEVSET((t), (u))) != 0)
145 #define	DEVSET_ADD(ds, t, u)	((ds) |= DEVSET((t), (u)))
146 #define	DEVSET_DEL(ds, t, u)	((ds) &= ~DEVSET((t), (u)))
147 #define	DEVSET_AND(ds1, ds2)	((ds1) & (ds2))
148 #define	DEVSET_OR(ds1, ds2)	((ds1) | (ds2))
149 #define	DEVSET_NAND(ds1, ds2)	((ds1) & ~(ds2))
150 #define	DEVSET_GET_UNITSET(ds, t) \
151 	(((ds) & DEVSET((t), DEVSET_ANYUNIT)) >> DEVSET_NT2DEVPOS((t), 0))
152 #define	DEVSET_FMT_STR		"0x%" PRIx64 ""
153 #define	DEVSET_FMT_ARG(ds)	(ds)
154 #else	/* DEVSET_MAX_BITS <= 64 */
155 #error please implement devset with bitmap to support more 64 devices
156 #endif	/* DEVSET_MAX_BITS <= 64 */
157 
158 /*
159  * Ops for dr_board_t.b_dev_*
160  */
161 #define	DR_DEV_IS(ds, cp)	DEVSET_IN_SET( \
162 					(cp)->sbdev_bp->b_dev_##ds, \
163 					(cp)->sbdev_type, \
164 					(cp)->sbdev_unum)
165 
166 #define	DR_DEV_ADD(ds, cp)	DEVSET_ADD( \
167 					(cp)->sbdev_bp->b_dev_##ds, \
168 					(cp)->sbdev_type, \
169 					(cp)->sbdev_unum)
170 
171 #define	DR_DEV_DEL(ds, cp)	DEVSET_DEL( \
172 					(cp)->sbdev_bp->b_dev_##ds, \
173 					(cp)->sbdev_type, \
174 					(cp)->sbdev_unum)
175 
176 /*
177  * Ops for dr_board_t.b_dev_present
178  */
179 #define	DR_DEV_IS_PRESENT(cp)		DR_DEV_IS(present, cp)
180 #define	DR_DEV_SET_PRESENT(cp)		DR_DEV_ADD(present, cp)
181 #define	DR_DEV_CLR_PRESENT(cp)		DR_DEV_DEL(present, cp)
182 
183 /*
184  * Ops for dr_board_t.b_dev_attached
185  */
186 #define	DR_DEV_IS_ATTACHED(cp)		DR_DEV_IS(attached, cp)
187 #define	DR_DEV_SET_ATTACHED(cp)		DR_DEV_ADD(attached, cp)
188 #define	DR_DEV_CLR_ATTACHED(cp)		DR_DEV_DEL(attached, cp)
189 
190 /*
191  * Ops for dr_board_t.b_dev_released
192  */
193 #define	DR_DEV_IS_RELEASED(cp)		DR_DEV_IS(released, cp)
194 #define	DR_DEV_SET_RELEASED(cp)		DR_DEV_ADD(released, cp)
195 #define	DR_DEV_CLR_RELEASED(cp)		DR_DEV_DEL(released, cp)
196 
197 /*
198  * Ops for dr_board_t.b_dev_unreferenced
199  */
200 #define	DR_DEV_IS_UNREFERENCED(cp)	DR_DEV_IS(unreferenced, cp)
201 #define	DR_DEV_SET_UNREFERENCED(cp)	DR_DEV_ADD(unreferenced, cp)
202 #define	DR_DEV_CLR_UNREFERENCED(cp)	DR_DEV_DEL(unreferenced, cp)
203 
204 #define	DR_DEVS_PRESENT(bp) \
205 			((bp)->b_dev_present)
206 #define	DR_DEVS_ATTACHED(bp) \
207 			((bp)->b_dev_attached)
208 #define	DR_DEVS_RELEASED(bp) \
209 			((bp)->b_dev_released)
210 #define	DR_DEVS_UNREFERENCED(bp) \
211 			((bp)->b_dev_unreferenced)
212 #define	DR_DEVS_UNATTACHED(bp) \
213 			((bp)->b_dev_present & ~(bp)->b_dev_attached)
214 #define	DR_DEVS_CONFIGURE(bp, devs) \
215 			((bp)->b_dev_attached = (devs))
216 #define	DR_DEVS_DISCONNECT(bp, devs) \
217 			((bp)->b_dev_present &= ~(devs))
218 #define	DR_DEVS_CANCEL(bp, devs) \
219 			((bp)->b_dev_released &= ~(devs), \
220 			(bp)->b_dev_unreferenced &= ~(devs))
221 
222 /*
223  * CMP Specific Helpers
224  */
225 #define	DR_CMP_CORE_UNUM(cmp, core)	((cmp) * MAX_CORES_PER_CMP + (core))
226 
227 /*
228  * For CPU and CMP devices, DR_UNUM2SBD_UNUM is used to extract the physical
229  * CPU/CMP id from the device id.
230  */
231 #define	DR_UNUM2SBD_UNUM(n, d)		\
232 	((d) == SBD_COMP_CPU ? ((n) / MAX_CORES_PER_CMP) : \
233 	(d) == SBD_COMP_CMP ? ((n) / MAX_CORES_PER_CMP) : (n))
234 
235 /*
236  * Some stuff to assist in debug.
237  */
238 #ifdef DEBUG
239 #define	DRDBG_STATE	0x00000001
240 #define	DRDBG_QR	0x00000002
241 #define	DRDBG_CPU	0x00000004
242 #define	DRDBG_MEM	0x00000008
243 #define	DRDBG_IO	0x00000010
244 
245 #define	PR_ALL		if (dr_debug)			printf
246 #define	PR_STATE	if (dr_debug & DRDBG_STATE)	printf
247 #define	PR_QR		if (dr_debug & DRDBG_QR)	prom_printf
248 #define	PR_CPU		if (dr_debug & DRDBG_CPU)	printf
249 #define	PR_MEM		if (dr_debug & DRDBG_MEM)	printf
250 #define	PR_IO		if (dr_debug & DRDBG_IO)	printf
251 #define	PR_MEMLIST_DUMP	if (dr_debug & DRDBG_MEM)	MEMLIST_DUMP
252 
253 extern uint_t	dr_debug;
254 #else /* DEBUG */
255 #define	PR_ALL		_NOTE(CONSTANTCONDITION) if (0) printf
256 #define	PR_STATE	PR_ALL
257 #define	PR_QR		PR_ALL
258 #define	PR_CPU		PR_ALL
259 #define	PR_MEM		PR_ALL
260 #define	PR_IO		PR_ALL
261 #define	PR_MEMLIST_DUMP	_NOTE(CONSTANTCONDITION) if (0) MEMLIST_DUMP
262 
263 #endif /* DEBUG */
264 
265 /*
266  * dr_board_t b_sflags.
267  */
268 #define	DR_BSLOCK	0x01	/* for blocking status (protected by b_slock) */
269 
270 typedef const char	*fn_t;
271 
272 /*
273  * Unsafe devices based on dr.conf prop "unsupported-io-drivers"
274  */
275 typedef struct {
276 	char	**devnames;
277 	uint_t	ndevs;
278 } dr_unsafe_devs_t;
279 
280 /*
281  * Device states.
282  * PARTIAL state is really only relevant for board state.
283  */
284 typedef enum {
285 	DR_STATE_EMPTY = 0,
286 	DR_STATE_OCCUPIED,
287 	DR_STATE_CONNECTED,
288 	DR_STATE_UNCONFIGURED,
289 	DR_STATE_PARTIAL,		/* part connected, part configured */
290 	DR_STATE_CONFIGURED,
291 	DR_STATE_RELEASE,
292 	DR_STATE_UNREFERENCED,
293 	DR_STATE_FATAL,
294 	DR_STATE_MAX
295 } dr_state_t;
296 
297 typedef struct dr_handle {
298 	struct dr_board	*h_bd;
299 	sbd_error_t	*h_err;
300 	int		h_op_intr;	/* nz if op interrupted */
301 	dev_t		h_dev;		/* dev_t of opened device */
302 	int		h_cmd;		/* PIM ioctl argument */
303 	int		h_mode;		/* device open mode */
304 	sbd_cmd_t	h_sbdcmd;	/* copied-in ioctl cmd struct */
305 	sbd_ioctl_arg_t	*h_iap;		/* ptr to caller-space cmd struct */
306 	dr_devset_t	h_devset;	/* based on h_dev */
307 	drmach_opts_t	h_opts;		/* command-line platform options */
308 } dr_handle_t;
309 
310 typedef struct dr_common_unit {
311 	dr_state_t		sbdev_state;
312 	sbd_state_t		sbdev_ostate;
313 	sbd_cond_t		sbdev_cond;
314 	time_t			sbdev_time;
315 	int			sbdev_busy;
316 	struct dr_board		*sbdev_bp;
317 	int			sbdev_unum;
318 	sbd_comp_type_t		sbdev_type;
319 	drmachid_t		sbdev_id;
320 	char			sbdev_path[MAXNAMELEN];
321 	sbd_error_t		*sbdev_error;
322 } dr_common_unit_t;
323 
324 typedef struct dr_mem_unit {
325 	dr_common_unit_t	sbm_cm;		/* mem-unit state */
326 	uint_t			sbm_flags;
327 	pfn_t			sbm_basepfn;
328 	pgcnt_t			sbm_npages;
329 	pgcnt_t			sbm_pageslost;
330 	struct memlist		*sbm_dyn_segs;	/* kphysm_add_dynamic segs */
331 	/*
332 	 * The following fields are used during
333 	 * the memory detach process only. sbm_mlist
334 	 * will be used to store the board memlist
335 	 * following a detach.  The memlist will be
336 	 * used to re-attach the board when configuring
337 	 * the unit directly after an unconfigure.
338 	 */
339 	struct dr_mem_unit	*sbm_peer;
340 	struct memlist		*sbm_mlist;
341 	struct memlist		*sbm_del_mlist;
342 	memhandle_t		sbm_memhandle;
343 	uint64_t		sbm_alignment_mask;
344 	uint64_t		sbm_slice_base;
345 	uint64_t		sbm_slice_top;
346 	uint64_t		sbm_slice_size;
347 } dr_mem_unit_t;
348 
349 /*
350  * Currently only maintain state information for individual
351  * components.
352  */
353 typedef struct dr_cpu_unit {
354 	dr_common_unit_t	sbc_cm;		/* cpu-unit state */
355 	processorid_t		sbc_cpu_id;
356 	cpu_flag_t		sbc_cpu_flags;	/* snapshot of CPU flags */
357 	ushort_t		sbc_pad1;	/* padded for compatibility */
358 	int			sbc_speed;
359 	int			sbc_ecache;
360 	int			sbc_cpu_impl;
361 } dr_cpu_unit_t;
362 
363 typedef struct dr_io_unit {
364 	dr_common_unit_t	sbi_cm;		/* io-unit state */
365 } dr_io_unit_t;
366 
367 typedef union {
368 	dr_common_unit_t	du_common;
369 	dr_mem_unit_t		du_mem;
370 	dr_cpu_unit_t		du_cpu;
371 	dr_io_unit_t		du_io;
372 } dr_dev_unit_t;
373 
374 typedef struct dr_board {
375 	kmutex_t	b_lock;		/* lock for this board struct */
376 	kmutex_t	b_slock;	/* lock for status on the board */
377 	kcondvar_t	b_scv;		/* condvar for status on the board */
378 	int		b_sflags;	/* for serializing status */
379 	sbd_state_t	b_rstate;	/* board's cfgadm receptacle state */
380 	sbd_state_t	b_ostate;	/* board's cfgadm occupant state */
381 	sbd_cond_t	b_cond;		/* cfgadm condition */
382 	int		b_busy;
383 	int		b_assigned;
384 	time_t		b_time;		/* time of last board operation */
385 	char		b_type[MAXNAMELEN];
386 	drmachid_t	b_id;
387 	int		b_num;			/* board number */
388 	int		b_ndev;			/* # of devices on board */
389 	dev_info_t	*b_dip;			/* dip for make-nodes */
390 	dr_state_t	b_state;		/* board DR state */
391 	dr_devset_t	b_dev_present;		/* present mask */
392 	dr_devset_t	b_dev_attached;		/* attached mask */
393 	dr_devset_t	b_dev_released;		/* released mask */
394 	dr_devset_t	b_dev_unreferenced;	/* unreferenced mask */
395 	char		b_path[MAXNAMELEN];
396 	dr_dev_unit_t	*b_dev[DR_MAXNUM_NT];
397 } dr_board_t;
398 
399 /*
400  * dr_quiesce.c interfaces
401  */
402 struct dr_sr_handle;
403 typedef struct dr_sr_handle dr_sr_handle_t;
404 
405 extern dr_sr_handle_t	*dr_get_sr_handle(dr_handle_t *handle);
406 extern void		dr_release_sr_handle(dr_sr_handle_t *srh);
407 extern int		dr_suspend(dr_sr_handle_t *srh);
408 extern void		dr_resume(dr_sr_handle_t *srh);
409 extern void		dr_check_devices(dev_info_t *dip, int *refcount,
410 			    dr_handle_t *handle, uint64_t *arr, int *idx,
411 			    int len, int *refcount_non_gldv3);
412 extern int		dr_pt_test_suspend(dr_handle_t *hp);
413 
414 /*
415  * dr_cpu.c interface
416  */
417 extern void		dr_init_cpu_unit(dr_cpu_unit_t *cp);
418 extern int		dr_pre_attach_cpu(dr_handle_t *hp,
419 				dr_common_unit_t **devlist, int devnum);
420 extern void		dr_attach_cpu(dr_handle_t *hp, dr_common_unit_t *cp);
421 extern int		dr_post_attach_cpu(dr_handle_t *hp,
422 				dr_common_unit_t **devlist, int devnum);
423 extern int		dr_pre_release_cpu(dr_handle_t *hp,
424 				dr_common_unit_t **devlist, int devnum);
425 extern int		dr_pre_detach_cpu(dr_handle_t *hp,
426 				dr_common_unit_t **devlist, int devnum);
427 extern void		dr_detach_cpu(dr_handle_t *hp, dr_common_unit_t *cp);
428 extern int		dr_post_detach_cpu(dr_handle_t *hp,
429 				dr_common_unit_t **devlist, int devnum);
430 extern int		dr_cpu_status(dr_handle_t *hp, dr_devset_t devset,
431 					sbd_dev_stat_t *dsp);
432 extern int		dr_cancel_cpu(dr_cpu_unit_t *cp);
433 extern int		dr_disconnect_cpu(dr_cpu_unit_t *cp);
434 
435 
436 /*
437  * dr_mem.c interface
438  */
439 extern void		dr_init_mem_unit(dr_mem_unit_t *mp);
440 extern int		dr_pre_attach_mem(dr_handle_t *hp,
441 				dr_common_unit_t **devlist, int devnum);
442 extern void		dr_attach_mem(dr_handle_t *hp, dr_common_unit_t *cp);
443 extern int		dr_post_attach_mem(dr_handle_t *hp,
444 				dr_common_unit_t **devlist, int devnum);
445 extern int		dr_pre_release_mem(dr_handle_t *hp,
446 				dr_common_unit_t **devlist, int devnum);
447 extern void		dr_release_mem(dr_common_unit_t *cp);
448 extern void		dr_release_mem_done(dr_common_unit_t *cp);
449 extern int		dr_pre_detach_mem(dr_handle_t *hp,
450 				dr_common_unit_t **devlist, int devnum);
451 extern void		dr_detach_mem(dr_handle_t *, dr_common_unit_t *);
452 extern int		dr_post_detach_mem(dr_handle_t *hp,
453 				dr_common_unit_t **devlist, int devnum);
454 extern int		dr_mem_status(dr_handle_t *hp, dr_devset_t devset,
455 					sbd_dev_stat_t *dsp);
456 extern int		dr_cancel_mem(dr_mem_unit_t *mp);
457 extern int		dr_disconnect_mem(dr_mem_unit_t *mp);
458 
459 /*
460  * dr_io.c interface
461  */
462 extern void		dr_init_io_unit(dr_io_unit_t *io);
463 extern int		dr_pre_attach_io(dr_handle_t *hp,
464 				dr_common_unit_t **devlist, int devnum);
465 extern void		dr_attach_io(dr_handle_t *hp, dr_common_unit_t *cp);
466 extern int		dr_post_attach_io(dr_handle_t *hp,
467 				dr_common_unit_t **devlist, int devnum);
468 extern int		dr_pre_release_io(dr_handle_t *hp,
469 				dr_common_unit_t **devlist, int devnum);
470 extern int		dr_pre_detach_io(dr_handle_t *hp,
471 				dr_common_unit_t **devlist, int devnum);
472 extern void		dr_detach_io(dr_handle_t *hp, dr_common_unit_t *cp);
473 extern int		dr_post_detach_io(dr_handle_t *hp,
474 				dr_common_unit_t **devlist, int devnum);
475 extern int		dr_io_status(dr_handle_t *hp, dr_devset_t devset,
476 					sbd_dev_stat_t *dsp);
477 extern int		dr_disconnect_io(dr_io_unit_t *ip);
478 
479 
480 /*
481  * dr.c interface
482  */
483 extern void dr_op_err(int ce, dr_handle_t *hp, int code, char *fmt, ...);
484 extern void dr_dev_err(int ce, dr_common_unit_t *cp, int code);
485 
486 extern dr_cpu_unit_t	*dr_get_cpu_unit(dr_board_t *bp, int unit_num);
487 extern dr_mem_unit_t	*dr_get_mem_unit(dr_board_t *bp, int unit_num);
488 extern dr_io_unit_t	*dr_get_io_unit(dr_board_t *bp, int unit_num);
489 
490 extern dr_board_t	*dr_lookup_board(int board_num);
491 extern int		dr_release_dev_done(dr_common_unit_t *cp);
492 extern char		*dr_nt_to_dev_type(int type);
493 extern void		dr_device_transition(dr_common_unit_t *cp,
494 				dr_state_t new_state);
495 extern void		dr_lock_status(dr_board_t *bp);
496 extern void		dr_unlock_status(dr_board_t *bp);
497 extern int		dr_cmd_flags(dr_handle_t *hp);
498 
499 #ifdef	__cplusplus
500 }
501 #endif
502 
503 #endif /* _SYS_DR_H */
504