1*1709Smlf /* 2*1709Smlf * CDDL HEADER START 3*1709Smlf * 4*1709Smlf * The contents of this file are subject to the terms of the 5*1709Smlf * Common Development and Distribution License (the "License"). 6*1709Smlf * You may not use this file except in compliance with the License. 7*1709Smlf * 8*1709Smlf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*1709Smlf * or http://www.opensolaris.org/os/licensing. 10*1709Smlf * See the License for the specific language governing permissions 11*1709Smlf * and limitations under the License. 12*1709Smlf * 13*1709Smlf * When distributing Covered Code, include this CDDL HEADER in each 14*1709Smlf * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*1709Smlf * If applicable, add the following below this CDDL HEADER, with the 16*1709Smlf * fields enclosed by brackets "[]" replaced with your own identifying 17*1709Smlf * information: Portions Copyright [yyyy] [name of copyright owner] 18*1709Smlf * 19*1709Smlf * CDDL HEADER END 20*1709Smlf */ 21*1709Smlf 22*1709Smlf /* 23*1709Smlf * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*1709Smlf * Use is subject to license terms. 25*1709Smlf */ 26*1709Smlf 27*1709Smlf #ifndef _GHD_H 28*1709Smlf #define _GHD_H 29*1709Smlf 30*1709Smlf #pragma ident "%Z%%M% %I% %E% SMI" 31*1709Smlf 32*1709Smlf #ifdef __cplusplus 33*1709Smlf extern "C" { 34*1709Smlf #endif 35*1709Smlf 36*1709Smlf #include <sys/types.h> 37*1709Smlf #include <sys/conf.h> 38*1709Smlf #include <sys/kmem.h> 39*1709Smlf #include <sys/ddi.h> 40*1709Smlf #include <sys/sunddi.h> 41*1709Smlf #include <sys/debug.h> 42*1709Smlf #include <sys/scsi/scsi.h> 43*1709Smlf 44*1709Smlf #include "ghd_queue.h" /* linked list structures */ 45*1709Smlf #include "ghd_scsi.h" 46*1709Smlf #include "ghd_waitq.h" 47*1709Smlf #include "ghd_debug.h" 48*1709Smlf 49*1709Smlf #ifndef TRUE 50*1709Smlf #define TRUE 1 51*1709Smlf #endif 52*1709Smlf 53*1709Smlf #ifndef FALSE 54*1709Smlf #define FALSE 0 55*1709Smlf #endif 56*1709Smlf 57*1709Smlf /* 58*1709Smlf * values for cmd_state: 59*1709Smlf */ 60*1709Smlf 61*1709Smlf typedef enum { 62*1709Smlf GCMD_STATE_IDLE = 0, 63*1709Smlf GCMD_STATE_WAITQ, 64*1709Smlf GCMD_STATE_ACTIVE, 65*1709Smlf GCMD_STATE_DONEQ, 66*1709Smlf GCMD_STATE_ABORTING_CMD, 67*1709Smlf GCMD_STATE_ABORTING_DEV, 68*1709Smlf GCMD_STATE_RESETTING_DEV, 69*1709Smlf GCMD_STATE_RESETTING_BUS, 70*1709Smlf GCMD_STATE_HUNG, 71*1709Smlf GCMD_NSTATES 72*1709Smlf } cmdstate_t; 73*1709Smlf 74*1709Smlf /* 75*1709Smlf * action codes for the HBA timeout function 76*1709Smlf */ 77*1709Smlf 78*1709Smlf typedef enum { 79*1709Smlf GACTION_EARLY_TIMEOUT = 0, /* timed-out before started */ 80*1709Smlf GACTION_EARLY_ABORT, /* scsi_abort() before started */ 81*1709Smlf GACTION_ABORT_CMD, /* abort a specific request */ 82*1709Smlf GACTION_ABORT_DEV, /* abort everything on specifici dev */ 83*1709Smlf GACTION_RESET_TARGET, /* reset a specific dev */ 84*1709Smlf GACTION_RESET_BUS, /* reset the whole bus */ 85*1709Smlf GACTION_INCOMPLETE /* giving up on incomplete request */ 86*1709Smlf } gact_t; 87*1709Smlf 88*1709Smlf /* 89*1709Smlf * types of ghd_timer_poll() invocations 90*1709Smlf */ 91*1709Smlf 92*1709Smlf typedef enum { 93*1709Smlf GHD_TIMER_POLL_ALL = 0, /* time out all expired commands */ 94*1709Smlf GHD_TIMER_POLL_ONE /* time out one, let caller loop */ 95*1709Smlf } gtimer_poll_t; 96*1709Smlf 97*1709Smlf /* 98*1709Smlf * the common portion of the Command Control Block 99*1709Smlf */ 100*1709Smlf 101*1709Smlf typedef struct ghd_cmd { 102*1709Smlf L2el_t cmd_q; /* link for for done/active CCB Qs */ 103*1709Smlf cmdstate_t cmd_state; /* request's current state */ 104*1709Smlf ulong_t cmd_waitq_level; /* which wait Q this request is on */ 105*1709Smlf int cmd_flags; /* generic magic info */ 106*1709Smlf 107*1709Smlf L2el_t cmd_timer_link; /* ccb timer doubly linked list */ 108*1709Smlf ulong_t cmd_start_time; /* lbolt at start of request */ 109*1709Smlf ulong_t cmd_timeout; /* how long to wait */ 110*1709Smlf 111*1709Smlf opaque_t cmd_private; /* used by the HBA driver */ 112*1709Smlf void *cmd_pktp; /* request packet */ 113*1709Smlf gtgt_t *cmd_gtgtp; /* dev instance for this request */ 114*1709Smlf 115*1709Smlf int cmd_dma_flags; 116*1709Smlf ddi_dma_handle_t cmd_dma_handle; 117*1709Smlf ddi_dma_win_t cmd_dmawin; 118*1709Smlf ddi_dma_seg_t cmd_dmaseg; 119*1709Smlf 120*1709Smlf uint_t cmd_wcount; /* ddi_dma_attr: window count */ 121*1709Smlf uint_t cmd_windex; /* ddi_dma_attr: current window */ 122*1709Smlf uint_t cmd_ccount; /* ddi_dma_attr: cookie count */ 123*1709Smlf uint_t cmd_cindex; /* ddi_dma_attr: current cookie */ 124*1709Smlf 125*1709Smlf long cmd_totxfer; /* # bytes transferred so far */ 126*1709Smlf ddi_dma_cookie_t cmd_first_cookie; 127*1709Smlf int use_first; 128*1709Smlf } gcmd_t; 129*1709Smlf 130*1709Smlf 131*1709Smlf /* definitions for cmd_flags */ 132*1709Smlf #define GCMDFLG_RESET_NOTIFY 1 /* command is a reset notification */ 133*1709Smlf 134*1709Smlf /* 135*1709Smlf * Initialize the gcmd_t structure 136*1709Smlf */ 137*1709Smlf 138*1709Smlf #define GHD_GCMD_INIT(gcmdp, cmdp, gtgtp) \ 139*1709Smlf (L2_INIT(&(gcmdp)->cmd_q), \ 140*1709Smlf L2_INIT(&(gcmdp)->cmd_timer_link), \ 141*1709Smlf (gcmdp)->cmd_private = (cmdp), \ 142*1709Smlf (gcmdp)->cmd_gtgtp = (gtgtp) \ 143*1709Smlf ) 144*1709Smlf 145*1709Smlf 146*1709Smlf /* 147*1709Smlf * CMD/CCB timer config structure - one per HBA driver module 148*1709Smlf */ 149*1709Smlf typedef struct tmr_conf { 150*1709Smlf kmutex_t t_mutex; /* mutex to protect t_ccc_listp */ 151*1709Smlf timeout_id_t t_timeout_id; /* handle for timeout() function */ 152*1709Smlf long t_ticks; /* periodic timeout in clock ticks */ 153*1709Smlf int t_refs; /* reference count */ 154*1709Smlf struct cmd_ctl *t_ccc_listp; /* control struct list, one per HBA */ 155*1709Smlf } tmr_t; 156*1709Smlf 157*1709Smlf 158*1709Smlf 159*1709Smlf /* 160*1709Smlf * CMD/CCB timer control structure - one per HBA instance (per board) 161*1709Smlf */ 162*1709Smlf typedef struct cmd_ctl { 163*1709Smlf struct cmd_ctl *ccc_nextp; /* list of control structs */ 164*1709Smlf struct tmr_conf *ccc_tmrp; /* back ptr to config struct */ 165*1709Smlf char *ccc_label; /* name of this HBA driver */ 166*1709Smlf 167*1709Smlf kmutex_t ccc_activel_mutex; /* mutex to protect list ... */ 168*1709Smlf L2el_t ccc_activel; /* ... list of active CMD/CCBs */ 169*1709Smlf 170*1709Smlf dev_info_t *ccc_hba_dip; 171*1709Smlf ddi_iblock_cookie_t ccc_iblock; 172*1709Smlf ddi_softintr_t ccc_soft_id; /* ID for timeout softintr */ 173*1709Smlf 174*1709Smlf kmutex_t ccc_hba_mutex; /* mutex for HBA soft-state */ 175*1709Smlf int ccc_hba_pollmode; /* FLAG_NOINTR mode active? */ 176*1709Smlf 177*1709Smlf L1_t ccc_devs; /* unsorted list of attached devs */ 178*1709Smlf kmutex_t ccc_waitq_mutex; /* mutex to protect device wait Qs */ 179*1709Smlf Q_t ccc_waitq; /* the HBA's wait queue */ 180*1709Smlf clock_t ccc_waitq_freezetime; /* time the waitq was frozen, ticks */ 181*1709Smlf uint_t ccc_waitq_freezedelay; /* delta time until waitq thaws, ms */ 182*1709Smlf 183*1709Smlf ddi_softintr_t ccc_doneq_softid; /* ID for doneq softintr */ 184*1709Smlf kmutex_t ccc_doneq_mutex; /* mutex to protect the doneq */ 185*1709Smlf L2el_t ccc_doneq; /* completed cmd_t's */ 186*1709Smlf 187*1709Smlf void *ccc_hba_handle; 188*1709Smlf int (*ccc_ccballoc)(); /* alloc/init gcmd and ccb */ 189*1709Smlf void (*ccc_ccbfree)(); 190*1709Smlf void (*ccc_sg_func)(); 191*1709Smlf int (*ccc_hba_start)(void *handle, gcmd_t *); 192*1709Smlf void (*ccc_hba_complete)(void *handle, gcmd_t *, int); 193*1709Smlf void (*ccc_process_intr)(void *handle, void *intr_status); 194*1709Smlf int (*ccc_get_status)(void *handle, void *intr_status); 195*1709Smlf int (*ccc_timeout_func)(void *handle, gcmd_t *cmdp, gtgt_t *gtgtp, 196*1709Smlf gact_t action, int calltype); 197*1709Smlf void (*ccc_hba_reset_notify_callback)(gtgt_t *gtgtp, 198*1709Smlf void (*callback)(caddr_t), 199*1709Smlf caddr_t arg); 200*1709Smlf L2el_t ccc_reset_notify_list; /* list of reset notifications */ 201*1709Smlf kmutex_t ccc_reset_notify_mutex; /* and a mutex to protect it */ 202*1709Smlf char ccc_timeout_pending; /* timeout Q's softintr is triggered */ 203*1709Smlf char ccc_waitq_frozen; /* ccc_waitq_freezetime non-null */ 204*1709Smlf char ccc_waitq_held; /* frozen, but no freezetime */ 205*1709Smlf } ccc_t; 206*1709Smlf 207*1709Smlf #define GHBA_QHEAD(cccp) ((cccp)->ccc_waitq.Q_qhead) 208*1709Smlf #define GHBA_MAXACTIVE(cccp) ((cccp)->ccc_waitq.Q_maxactive) 209*1709Smlf #define GHBA_NACTIVE(cccp) ((cccp)->ccc_waitq.Q_nactive) 210*1709Smlf 211*1709Smlf /* Initialize the HBA's list headers */ 212*1709Smlf #define CCCP_INIT(cccp) { \ 213*1709Smlf L1HEADER_INIT(&(cccp)->ccc_devs); \ 214*1709Smlf L2_INIT(&(cccp)->ccc_doneq); \ 215*1709Smlf L2_INIT(&(cccp)->ccc_reset_notify_list); \ 216*1709Smlf } 217*1709Smlf 218*1709Smlf 219*1709Smlf #define CCCP2GDEVP(cccp) \ 220*1709Smlf (L1_EMPTY(&(cccp)->ccc_devs) \ 221*1709Smlf ? (gdev_t *)NULL \ 222*1709Smlf : (gdev_t *)((cccp)->ccc_devs.l1_headp->le_datap)) 223*1709Smlf 224*1709Smlf 225*1709Smlf /* 226*1709Smlf * reset_notify handling: these elements are on the ccc_t's 227*1709Smlf * reset_notify_list, one for each notification requested. The 228*1709Smlf * gtgtp isn't needed except for debug. 229*1709Smlf */ 230*1709Smlf 231*1709Smlf typedef struct ghd_reset_notify_list { 232*1709Smlf gtgt_t *gtgtp; 233*1709Smlf void (*callback)(caddr_t); 234*1709Smlf caddr_t arg; 235*1709Smlf L2el_t l2_link; 236*1709Smlf } ghd_reset_notify_list_t; 237*1709Smlf 238*1709Smlf /* ******************************************************************* */ 239*1709Smlf 240*1709Smlf #include "ghd_scsa.h" 241*1709Smlf #include "ghd_dma.h" 242*1709Smlf 243*1709Smlf /* 244*1709Smlf * GHD Entry Points 245*1709Smlf */ 246*1709Smlf void ghd_complete(ccc_t *cccp, gcmd_t *cmdp); 247*1709Smlf void ghd_doneq_put_head(ccc_t *cccp, gcmd_t *cmdp); 248*1709Smlf void ghd_doneq_put_tail(ccc_t *cccp, gcmd_t *cmdp); 249*1709Smlf 250*1709Smlf int ghd_intr(ccc_t *cccp, void *status); 251*1709Smlf int ghd_register(char *, ccc_t *, dev_info_t *, int, void *hba_handle, 252*1709Smlf int (*ccc_ccballoc)(gtgt_t *, gcmd_t *, int, int, 253*1709Smlf int, int), 254*1709Smlf void (*ccc_ccbfree)(gcmd_t *), 255*1709Smlf void (*ccc_sg_func)(gcmd_t *, ddi_dma_cookie_t *, 256*1709Smlf int, int), 257*1709Smlf int (*hba_start)(void *, gcmd_t *), 258*1709Smlf void (*hba_complete)(void *, gcmd_t *, int), 259*1709Smlf uint_t (*int_handler)(caddr_t), 260*1709Smlf int (*get_status)(void *, void *), 261*1709Smlf void (*process_intr)(void *, void *), 262*1709Smlf int (*timeout_func)(void *, gcmd_t *, gtgt_t *, 263*1709Smlf gact_t, int), 264*1709Smlf tmr_t *tmrp, 265*1709Smlf void (*hba_reset_notify_callback)(gtgt_t *, 266*1709Smlf void (*)(caddr_t), caddr_t)); 267*1709Smlf void ghd_unregister(ccc_t *cccp); 268*1709Smlf 269*1709Smlf int ghd_transport(ccc_t *cccp, gcmd_t *cmdp, gtgt_t *gtgtp, 270*1709Smlf ulong_t timeout, int polled, void *intr_status); 271*1709Smlf 272*1709Smlf int ghd_tran_abort(ccc_t *cccp, gcmd_t *cmdp, gtgt_t *gtgtp, 273*1709Smlf void *intr_status); 274*1709Smlf int ghd_tran_abort_lun(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status); 275*1709Smlf int ghd_tran_reset_target(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status); 276*1709Smlf int ghd_tran_reset_bus(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status); 277*1709Smlf int ghd_reset_notify(ccc_t *cccp, gtgt_t *gtgtp, int flag, 278*1709Smlf void (*callback)(caddr_t), caddr_t arg); 279*1709Smlf void ghd_freeze_waitq(ccc_t *cccp, int delay); 280*1709Smlf void ghd_trigger_reset_notify(ccc_t *cccp); 281*1709Smlf 282*1709Smlf void ghd_queue_hold(ccc_t *cccp); 283*1709Smlf void ghd_queue_unhold(ccc_t *cccp); 284*1709Smlf 285*1709Smlf /* 286*1709Smlf * Allocate a gcmd_t wrapper and HBA private area 287*1709Smlf */ 288*1709Smlf gcmd_t *ghd_gcmd_alloc(gtgt_t *gtgtp, int ccblen, int sleep); 289*1709Smlf 290*1709Smlf /* 291*1709Smlf * Free the gcmd_t wrapper and HBA private area 292*1709Smlf */ 293*1709Smlf void ghd_gcmd_free(gcmd_t *gcmdp); 294*1709Smlf 295*1709Smlf 296*1709Smlf /* 297*1709Smlf * GHD CMD/CCB timer Entry points 298*1709Smlf */ 299*1709Smlf 300*1709Smlf int ghd_timer_attach(ccc_t *cccp, tmr_t *tmrp, 301*1709Smlf int (*timeout_func)(void *handle, gcmd_t *, gtgt_t *, 302*1709Smlf gact_t, int)); 303*1709Smlf void ghd_timer_detach(ccc_t *cccp); 304*1709Smlf void ghd_timer_fini(tmr_t *tmrp); 305*1709Smlf void ghd_timer_init(tmr_t *tmrp, long ticks); 306*1709Smlf void ghd_timer_newstate(ccc_t *cccp, gcmd_t *cmdp, gtgt_t *gtgtp, 307*1709Smlf gact_t action, int calltype); 308*1709Smlf void ghd_timer_poll(ccc_t *cccp, gtimer_poll_t calltype); 309*1709Smlf void ghd_timer_start(ccc_t *cccp, gcmd_t *cmdp, long cmd_timeout); 310*1709Smlf void ghd_timer_stop(ccc_t *cccp, gcmd_t *cmdp); 311*1709Smlf 312*1709Smlf 313*1709Smlf /* 314*1709Smlf * Wait queue utility routines 315*1709Smlf */ 316*1709Smlf 317*1709Smlf gtgt_t *ghd_target_init(dev_info_t *, dev_info_t *, ccc_t *, size_t, 318*1709Smlf void *, ushort_t, uchar_t); 319*1709Smlf void ghd_target_free(dev_info_t *, dev_info_t *, ccc_t *, gtgt_t *); 320*1709Smlf void ghd_waitq_shuffle_up(ccc_t *, gdev_t *); 321*1709Smlf void ghd_waitq_delete(ccc_t *, gcmd_t *); 322*1709Smlf int ghd_waitq_process_and_mutex_hold(ccc_t *); 323*1709Smlf void ghd_waitq_process_and_mutex_exit(ccc_t *); 324*1709Smlf 325*1709Smlf 326*1709Smlf /* 327*1709Smlf * The values for the calltype arg for the ghd_timer_newstate() function, 328*1709Smlf * and the HBA timeout-action function (ccc_timeout_func) 329*1709Smlf */ 330*1709Smlf 331*1709Smlf #define GHD_TGTREQ 0 332*1709Smlf #define GHD_TIMEOUT 1 333*1709Smlf 334*1709Smlf /* ******************************************************************* */ 335*1709Smlf 336*1709Smlf /* 337*1709Smlf * specify GHD_INLINE to get optimized versions 338*1709Smlf */ 339*1709Smlf #define GHD_INLINE 1 340*1709Smlf #if defined(GHD_DEBUG) || defined(DEBUG) || defined(__lint) 341*1709Smlf #undef GHD_INLINE 342*1709Smlf #endif 343*1709Smlf 344*1709Smlf #if defined(GHD_INLINE) 345*1709Smlf #define GHD_COMPLETE(cccp, gcmpd) GHD_COMPLETE_INLINE(cccp, gcmdp) 346*1709Smlf #define GHD_TIMER_STOP(cccp, gcmdp) GHD_TIMER_STOP_INLINE(cccp, gcmdp) 347*1709Smlf #define GHD_DONEQ_PUT_HEAD(cccp, gcmdp) GHD_DONEQ_PUT_HEAD_INLINE(cccp, gcmdp) 348*1709Smlf #define GHD_DONEQ_PUT_TAIL(cccp, gcmdp) GHD_DONEQ_PUT_TAIL_INLINE(cccp, gcmdp) 349*1709Smlf #else 350*1709Smlf #define GHD_COMPLETE(cccp, gcmpd) ghd_complete(cccp, gcmdp) 351*1709Smlf #define GHD_TIMER_STOP(cccp, gcmdp) ghd_timer_stop(cccp, gcmdp) 352*1709Smlf #define GHD_DONEQ_PUT_HEAD(cccp, gcmdp) ghd_doneq_put_head(cccp, gcmdp) 353*1709Smlf #define GHD_DONEQ_PUT_TAIL(cccp, gcmdp) ghd_doneq_put_tail(cccp, gcmdp) 354*1709Smlf #endif 355*1709Smlf 356*1709Smlf /* 357*1709Smlf * request is complete, stop the request timer and add to doneq 358*1709Smlf */ 359*1709Smlf #define GHD_COMPLETE_INLINE(cccp, gcmdp) \ 360*1709Smlf { \ 361*1709Smlf ghd_waitq_delete(cccp, gcmdp); \ 362*1709Smlf (gcmdp)->cmd_state = GCMD_STATE_DONEQ; \ 363*1709Smlf GHD_TIMER_STOP((cccp), (gcmdp)); \ 364*1709Smlf GHD_DONEQ_PUT_TAIL((cccp), (gcmdp)); \ 365*1709Smlf } 366*1709Smlf 367*1709Smlf #define GHD_TIMER_STOP_INLINE(cccp, gcmdp) \ 368*1709Smlf { \ 369*1709Smlf mutex_enter(&(cccp)->ccc_activel_mutex);\ 370*1709Smlf L2_delete(&(gcmdp)->cmd_timer_link); \ 371*1709Smlf mutex_exit(&(cccp)->ccc_activel_mutex); \ 372*1709Smlf } 373*1709Smlf 374*1709Smlf /* 375*1709Smlf * mark the request done and append it to the head of the doneq 376*1709Smlf */ 377*1709Smlf #define GHD_DONEQ_PUT_HEAD_INLINE(cccp, gcmdp) \ 378*1709Smlf { \ 379*1709Smlf kmutex_t *doneq_mutexp = &(cccp)->ccc_doneq_mutex; \ 380*1709Smlf \ 381*1709Smlf mutex_enter(doneq_mutexp); \ 382*1709Smlf (gcmdp)->cmd_state = GCMD_STATE_DONEQ; \ 383*1709Smlf L2_add_head(&(cccp)->ccc_doneq, &(gcmdp)->cmd_q, (gcmdp)); \ 384*1709Smlf if (!(cccp)->ccc_hba_pollmode) \ 385*1709Smlf ddi_trigger_softintr((cccp)->ccc_doneq_softid); \ 386*1709Smlf mutex_exit(doneq_mutexp); \ 387*1709Smlf } 388*1709Smlf 389*1709Smlf /* 390*1709Smlf * mark the request done and append it to the tail of the doneq 391*1709Smlf */ 392*1709Smlf #define GHD_DONEQ_PUT_TAIL_INLINE(cccp, gcmdp) \ 393*1709Smlf { \ 394*1709Smlf kmutex_t *doneq_mutexp = &(cccp)->ccc_doneq_mutex; \ 395*1709Smlf \ 396*1709Smlf mutex_enter(doneq_mutexp); \ 397*1709Smlf (gcmdp)->cmd_state = GCMD_STATE_DONEQ; \ 398*1709Smlf L2_add(&(cccp)->ccc_doneq, &(gcmdp)->cmd_q, (gcmdp)); \ 399*1709Smlf if (!(cccp)->ccc_hba_pollmode) \ 400*1709Smlf ddi_trigger_softintr((cccp)->ccc_doneq_softid); \ 401*1709Smlf mutex_exit(doneq_mutexp); \ 402*1709Smlf } 403*1709Smlf 404*1709Smlf /* ******************************************************************* */ 405*1709Smlf 406*1709Smlf /* 407*1709Smlf * These are shortcut macros for linkages setup by GHD 408*1709Smlf */ 409*1709Smlf 410*1709Smlf /* 411*1709Smlf * (gcmd_t *) to (struct scsi_pkt *) 412*1709Smlf */ 413*1709Smlf #define GCMDP2PKTP(gcmdp) ((gcmdp)->cmd_pktp) 414*1709Smlf 415*1709Smlf /* 416*1709Smlf * (gcmd_t *) to (gtgt_t *) 417*1709Smlf */ 418*1709Smlf #define GCMDP2GTGTP(gcmdp) ((gcmdp)->cmd_gtgtp) 419*1709Smlf 420*1709Smlf /* 421*1709Smlf * (gcmd_t *) to (gdev_t *) 422*1709Smlf */ 423*1709Smlf #define GCMDP2GDEVP(gcmdp) ((gcmdp)->cmd_gtgtp->gt_gdevp) 424*1709Smlf 425*1709Smlf /* 426*1709Smlf * (gcmd_t *) to (ccc_t *) 427*1709Smlf */ 428*1709Smlf #define GCMDP2CCCP(gcmdp) (GCMDP2GTGTP(gcmdp)->gt_ccc) 429*1709Smlf 430*1709Smlf /* 431*1709Smlf * (struct scsi_pkt *) to (gcmd_t *) 432*1709Smlf */ 433*1709Smlf #define PKTP2GCMDP(pktp) ((gcmd_t *)(pktp)->pkt_ha_private) 434*1709Smlf 435*1709Smlf 436*1709Smlf /* These are shortcut macros for linkages setup by SCSA */ 437*1709Smlf 438*1709Smlf /* 439*1709Smlf * (struct scsi_address *) to (scsi_hba_tran *) 440*1709Smlf */ 441*1709Smlf #define ADDR2TRAN(ap) ((ap)->a_hba_tran) 442*1709Smlf 443*1709Smlf /* 444*1709Smlf * (struct scsi_device *) to (scsi_address *) 445*1709Smlf */ 446*1709Smlf #define SDEV2ADDR(sdp) (&(sdp)->sd_address) 447*1709Smlf 448*1709Smlf /* 449*1709Smlf * (struct scsi_device *) to (scsi_hba_tran *) 450*1709Smlf */ 451*1709Smlf #define SDEV2TRAN(sdp) ADDR2TRAN(SDEV2ADDR(sdp)) 452*1709Smlf 453*1709Smlf /* 454*1709Smlf * (struct scsi_pkt *) to (scsi_hba_tran *) 455*1709Smlf */ 456*1709Smlf #define PKTP2TRAN(pktp) ADDR2TRAN(&(pktp)->pkt_address) 457*1709Smlf 458*1709Smlf /* 459*1709Smlf * (scsi_hba_tran_t *) to (per-target-soft-state *) 460*1709Smlf */ 461*1709Smlf #define TRAN2GTGTP(tranp) ((gtgt_t *)((tranp)->tran_tgt_private)) 462*1709Smlf 463*1709Smlf /* 464*1709Smlf * (struct scsi_device *) to (per-target-soft-state *) 465*1709Smlf */ 466*1709Smlf #define SDEV2GTGTP(sd) TRAN2GTGTP(SDEV2TRAN(sd)) 467*1709Smlf 468*1709Smlf /* 469*1709Smlf * (struct scsi_pkt *) to (per-target-soft-state *) 470*1709Smlf */ 471*1709Smlf #define PKTP2GTGTP(pktp) TRAN2GTGTP(PKTP2TRAN(pktp)) 472*1709Smlf 473*1709Smlf 474*1709Smlf /* 475*1709Smlf * (scsi_hba_tran_t *) to (per-HBA-soft-state *) 476*1709Smlf */ 477*1709Smlf #define TRAN2HBA(tranp) ((tranp)->tran_hba_private) 478*1709Smlf 479*1709Smlf 480*1709Smlf /* 481*1709Smlf * (struct scsi_device *) to (per-HBA-soft-state *) 482*1709Smlf */ 483*1709Smlf #define SDEV2HBA(sd) TRAN2HBA(SDEV2TRAN(sd)) 484*1709Smlf 485*1709Smlf /* 486*1709Smlf * (struct scsi_address *) to (per-target-soft-state *) 487*1709Smlf */ 488*1709Smlf #define ADDR2GTGTP(ap) TRAN2GTGTP(ADDR2TRAN(ap)) 489*1709Smlf 490*1709Smlf /* ******************************************************************* */ 491*1709Smlf 492*1709Smlf 493*1709Smlf #ifdef __cplusplus 494*1709Smlf } 495*1709Smlf #endif 496*1709Smlf 497*1709Smlf #endif /* _GHD_H */ 498