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 2007 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #ifndef _SYS_SUNLDI_IMPL_H
  27 #define _SYS_SUNLDI_IMPL_H
  28 
  29 #pragma ident   "%Z%%M% %I%     %E% SMI"
  30 
  31 #ifdef __cplusplus
  32 extern "C" {
  33 #endif
  34 
  35 #include <sys/dditypes.h>
  36 #include <sys/vnode.h>
  37 
  38 /*
  39  * NOTE
  40  *
  41  * The contents of this file are private to this implementation
  42  * of Solaris and are subject to change at any time without notice.
  43  *
  44  * Applications and drivers using these interfaces will fail
  45  * to run on future releases.
  46  */
  47 
  48 /*
  49  * LDI hash definitions
  50  */
  51 #define LH_HASH_SZ      32
  52 #define LI_HASH_SZ      32
  53 
  54 /*
  55  * Obsolete LDI event interfaces are available for now but are deprecated and a
  56  * warning will be issued to consumers.
  57  */
  58 #define LDI_OBSOLETE_EVENT      1
  59 
  60 /*
  61  * Flag for LDI handle's lh_flags field
  62  */
  63 #define LH_FLAGS_NOTIFY 0x0001          /* invoked in context of a notify */
  64 
  65 /*
  66  * LDI initialization function
  67  */
  68 void ldi_init(void);
  69 
  70 /*
  71  * LDI streams linking interfaces
  72  */
  73 extern int ldi_mlink_lh(vnode_t *, int, intptr_t, cred_t *, int *);
  74 extern void ldi_mlink_fp(struct stdata *, struct file *, int, int);
  75 extern void ldi_munlink_fp(struct stdata *, struct file *, int);
  76 
  77 /*
  78  * LDI module identifier
  79  */
  80 struct ldi_ident {
  81         /* protected by ldi_ident_hash_lock */
  82         struct ldi_ident                *li_next;
  83         uint_t                          li_ref;
  84 
  85         /* unique/static fields in the ident */
  86         char                            li_modname[MODMAXNAMELEN];
  87         modid_t                         li_modid;
  88         major_t                         li_major;
  89         dev_info_t                      *li_dip;
  90         dev_t                           li_dev;
  91 };
  92 
  93 /*
  94  * LDI handle
  95  */
  96 struct ldi_handle {
  97         /* protected by ldi_handle_hash_lock */
  98         struct ldi_handle               *lh_next;
  99         uint_t                          lh_ref;
 100         uint_t                          lh_flags;
 101 
 102         /* unique/static fields in the handle */
 103         uint_t                          lh_type;
 104         struct ldi_ident                *lh_ident;
 105         vnode_t                         *lh_vp;
 106 
 107 #ifdef  LDI_OBSOLETE_EVENT
 108         /* fields protected by lh_lock */
 109         kmutex_t                        lh_lock[1];
 110         struct ldi_event                *lh_events;
 111 #endif
 112 };
 113 
 114 /*
 115  * LDI event information
 116  */
 117 #ifdef  LDI_OBSOLETE_EVENT
 118 typedef struct ldi_event {
 119         /* fields protected by le_lhp->lh_lock */
 120         struct ldi_event        *le_next;
 121         struct ldi_event        *le_prev;
 122 
 123         /* unique/static fields in the handle */
 124         struct ldi_handle       *le_lhp;
 125         void                    (*le_handler)();
 126         void                    *le_arg;
 127         ddi_callback_id_t       le_id;
 128 } ldi_event_t;
 129 #endif
 130 
 131 typedef struct ldi_ev_callback_impl {
 132         struct ldi_handle       *lec_lhp;
 133         dev_info_t              *lec_dip;
 134         dev_t                   lec_dev;
 135         int                     lec_spec;
 136         int                     (*lec_notify)();
 137         void                    (*lec_finalize)();
 138         void                    *lec_arg;
 139         void                    *lec_cookie;
 140         void                    *lec_id;
 141         list_node_t             lec_list;
 142 } ldi_ev_callback_impl_t;
 143 
 144 struct ldi_ev_callback_list {
 145         kmutex_t        le_lock;
 146         kcondvar_t      le_cv;
 147         int             le_busy;
 148         void            *le_thread;
 149         list_t          le_head;
 150 };
 151 
 152 int ldi_invoke_notify(dev_info_t *dip, dev_t dev, int spec_type, char *event,
 153     void *ev_data);
 154 void ldi_invoke_finalize(dev_info_t *dip, dev_t dev, int spec_type, char *event,
 155     int ldi_result, void *ev_data);
 156 int e_ddi_offline_notify(dev_info_t *dip);
 157 void e_ddi_offline_finalize(dev_info_t *dip, int result);
 158 
 159 
 160 /*
 161  * LDI device usage interfaces
 162  *
 163  * ldi_usage_count(), ldi_usage_walker(), and ldi_usage_t
 164  *
 165  * These functions are used by the devinfo driver and fuser to get a
 166  * device usage information from the LDI. These functions along with
 167  * the ldi_usage_t data structure allow these other subsystems to have
 168  * no knowledge of how the LDI stores it's internal state.
 169  *
 170  * ldi_usage_count() provides an count of how many kernel
 171  *      device clients currently exist.
 172  *
 173  * ldi_usage_walker() reports all kernel device usage information.
 174  */
 175 #define LDI_USAGE_CONTINUE      0
 176 #define LDI_USAGE_TERMINATE     1
 177 
 178 typedef struct ldi_usage {
 179         /*
 180          * information about the kernel subsystem that is accessing
 181          * the target device
 182          */
 183         modid_t         src_modid;
 184         char            *src_name;
 185         dev_info_t      *src_dip;
 186         dev_t           src_devt;
 187 
 188         /*
 189          * information about the target device that is open
 190          */
 191         modid_t         tgt_modid;
 192         char            *tgt_name;
 193         dev_info_t      *tgt_dip;
 194         dev_t           tgt_devt;
 195         int             tgt_spec_type;
 196 } ldi_usage_t;
 197 
 198 int ldi_usage_count();
 199 void ldi_usage_walker(void *arg,
 200     int (*callback)(const ldi_usage_t *ldi_usage, void *arg));
 201 
 202 #ifdef __cplusplus
 203 }
 204 #endif
 205 
 206 #endif  /* _SYS_SUNLDI_IMPL_H */