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