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