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 #ifndef _SD_SAFESTORE_IMPL_H
  27 #define _SD_SAFESTORE_IMPL_H
  28 
  29 #ifdef __cplusplus
  30 extern "C" {
  31 #endif
  32 
  33 #ifdef _KERNEL
  34 
  35 /* ss config stages */
  36 #define SD_WR_SLP_Q_MAX 256
  37 
  38 /*
  39  * Global fields for cache LRU entry. Fault tolerant structure in RMS.
  40  */
  41 
  42 #define INCX(x) (x = (x + 1 + SD_WR_SLP_Q_MAX) % SD_WR_SLP_Q_MAX)
  43 #define DECX(x) (x = (x - 1 + SD_WR_SLP_Q_MAX) % SD_WR_SLP_Q_MAX)
  44 
  45 typedef struct _sd_wr_slp_queue {
  46         kcondvar_t      slp_wqcv;
  47         int     slp_wqneed;
  48 } _sd_wr_slp_queue_t;
  49 
  50 typedef struct _sd_wr_queue {
  51         struct ss_wr_cctl *wq_qtop;     /* Top of write control blocks */
  52         kmutex_t   wq_qlock;            /* allocation spinlock */
  53         int     wq_inq;         /* number of write blocks available in q */
  54         int     wq_nentries;    /* total Number of write blocks in q */
  55         unsigned int    wq_slp_top;
  56         unsigned int    wq_slp_index;
  57         unsigned int    wq_slp_inq;
  58         _sd_wr_slp_queue_t wq_slp[SD_WR_SLP_Q_MAX];
  59 } _sd_writeq_t;
  60 
  61 #define WQ_SET_NEED(q, need, i) {                       \
  62         (q->wq_slp[i].slp_wqneed = need);                    \
  63 }
  64 
  65 #define WQ_SVWAIT_BOTTOM(q, need)                               \
  66 {                                                               \
  67         int ix = q->wq_slp_index;                            \
  68         INCX(q->wq_slp_index);                                       \
  69         WQ_SET_NEED(q, need, ix);                               \
  70         cv_wait(&q->wq_slp[ix].slp_wqcv, &q->wq_qlock);   \
  71         mutex_exit(&q->wq_qlock); \
  72 }
  73 
  74 #define WQ_SVWAIT_TOP(q, need)                                  \
  75 {                                                                       \
  76         DECX(q->wq_slp_top);                                         \
  77         WQ_SET_NEED(q, need, q->wq_slp_top);                 \
  78         cv_wait(&q->wq_slp[q->wq_slp_top].slp_wqcv, &q->wq_qlock);\
  79         mutex_exit(&q->wq_qlock); \
  80 }
  81 
  82 #define WQ_NEED_SIG(q) \
  83         (q->wq_slp_inq && (q->wq_slp[q->wq_slp_top].slp_wqneed <= q->wq_inq))
  84 
  85 #define WQ_SVSIG(q)                                             \
  86 {                                                               \
  87         int tp = q->wq_slp_top;                                      \
  88         INCX(q->wq_slp_top);                                 \
  89         q->wq_slp[tp].slp_wqneed = 0;                                \
  90         cv_signal(&q->wq_slp[tp].slp_wqcv);                      \
  91 }
  92 
  93 /*
  94  * cache entry information
  95  * note -- this structure is a identical to the first 4 words of
  96  * the exported ss_centry_info_t.  internal copies depened on this
  97  * fact.  changes to this structure may require changes to the
  98  * *getcentry() and *setcentry() functions.
  99  *
 100  */
 101 typedef struct ss_centry_info_impl_s {
 102         int sci_cd;             /* Cache descriptor */
 103         nsc_off_t sci_fpos;     /* File position    */
 104         int sci_dirty;          /* Dirty mask       */
 105         int sci_flag;           /* CC_PINNABLE | CC_PINNED */
 106 } ss_centry_info_impl_t;
 107 
 108 /*
 109  * The write control structure has information about the remote page that
 110  * will mirror a write.
 111  */
 112 typedef struct ss_wr_cctl {
 113         struct ss_wr_cctl       *wc_next;       /* chaining queue entries */
 114         caddr_t                 wc_addr;        /* points to data address */
 115         ss_centry_info_impl_t   *wc_gl_info;    /* information for the page */
 116         unsigned char           wc_flag;        /* flag */
 117 } ss_wr_cctl_t;
 118 
 119 /* volume information */
 120 typedef struct ss_voldata_impl_s {
 121         char svi_volname[NSC_MAXPATH];  /* Filename in RMS for failover */
 122         int  svi_cd;                    /* NOTE may need dual node map info */
 123         int  svi_pinned;                /* Device has failed/pinned blocks */
 124         int  svi_attached;              /* Node which has device attached */
 125         int  svi_devidsz;               /* unique dev id length */
 126         uchar_t svi_devid[NSC_MAXPATH]; /* wwn id - physical devs only */
 127         int  svi_reserved[13];          /* Reserved global space */
 128 } ss_voldata_impl_t;
 129 
 130 extern int _sd_fill_pattern(caddr_t addr, uint_t pat, uint_t size);
 131 extern int _sdbc_writeq_configure(_sd_writeq_t *);
 132 extern void _sdbc_writeq_deconfigure(_sd_writeq_t *);
 133 extern void ss_release_write(ss_wr_cctl_t *, _sd_writeq_t *);
 134 extern ss_wr_cctl_t *ss_alloc_write(int, int *, _sd_writeq_t *);
 135 
 136 #endif /* _KERNEL */
 137 
 138 #ifdef __cplusplus
 139 }
 140 #endif
 141 
 142 #endif  /* _SD_SAFESTORE_IMPL_H */