10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51106Smrj * Common Development and Distribution License (the "License"). 61106Smrj * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 21*1127Smrj 220Sstevel@tonic-gate /* 231106Smrj * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #ifndef _GHD_H 280Sstevel@tonic-gate #define _GHD_H 290Sstevel@tonic-gate 300Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 310Sstevel@tonic-gate 320Sstevel@tonic-gate #ifdef __cplusplus 330Sstevel@tonic-gate extern "C" { 340Sstevel@tonic-gate #endif 350Sstevel@tonic-gate 360Sstevel@tonic-gate #include <sys/types.h> 370Sstevel@tonic-gate #include <sys/conf.h> 380Sstevel@tonic-gate #include <sys/kmem.h> 390Sstevel@tonic-gate #include <sys/ddi.h> 400Sstevel@tonic-gate #include <sys/sunddi.h> 410Sstevel@tonic-gate #include <sys/debug.h> 420Sstevel@tonic-gate #include <sys/scsi/scsi.h> 430Sstevel@tonic-gate 440Sstevel@tonic-gate #include "ghd_queue.h" /* linked list structures */ 450Sstevel@tonic-gate #include "ghd_scsi.h" 460Sstevel@tonic-gate #include "ghd_waitq.h" 470Sstevel@tonic-gate #include "ghd_debug.h" 480Sstevel@tonic-gate 490Sstevel@tonic-gate #ifndef TRUE 500Sstevel@tonic-gate #define TRUE 1 510Sstevel@tonic-gate #endif 520Sstevel@tonic-gate 530Sstevel@tonic-gate #ifndef FALSE 540Sstevel@tonic-gate #define FALSE 0 550Sstevel@tonic-gate #endif 560Sstevel@tonic-gate 570Sstevel@tonic-gate /* 580Sstevel@tonic-gate * values for cmd_state: 590Sstevel@tonic-gate */ 600Sstevel@tonic-gate 610Sstevel@tonic-gate typedef enum { 620Sstevel@tonic-gate GCMD_STATE_IDLE = 0, 630Sstevel@tonic-gate GCMD_STATE_WAITQ, 640Sstevel@tonic-gate GCMD_STATE_ACTIVE, 650Sstevel@tonic-gate GCMD_STATE_DONEQ, 660Sstevel@tonic-gate GCMD_STATE_ABORTING_CMD, 670Sstevel@tonic-gate GCMD_STATE_ABORTING_DEV, 680Sstevel@tonic-gate GCMD_STATE_RESETTING_DEV, 690Sstevel@tonic-gate GCMD_STATE_RESETTING_BUS, 700Sstevel@tonic-gate GCMD_STATE_HUNG, 710Sstevel@tonic-gate GCMD_NSTATES 720Sstevel@tonic-gate } cmdstate_t; 730Sstevel@tonic-gate 740Sstevel@tonic-gate /* 750Sstevel@tonic-gate * action codes for the HBA timeout function 760Sstevel@tonic-gate */ 770Sstevel@tonic-gate 780Sstevel@tonic-gate typedef enum { 790Sstevel@tonic-gate GACTION_EARLY_TIMEOUT = 0, /* timed-out before started */ 800Sstevel@tonic-gate GACTION_EARLY_ABORT, /* scsi_abort() before started */ 810Sstevel@tonic-gate GACTION_ABORT_CMD, /* abort a specific request */ 820Sstevel@tonic-gate GACTION_ABORT_DEV, /* abort everything on specifici dev */ 830Sstevel@tonic-gate GACTION_RESET_TARGET, /* reset a specific dev */ 840Sstevel@tonic-gate GACTION_RESET_BUS, /* reset the whole bus */ 850Sstevel@tonic-gate GACTION_INCOMPLETE /* giving up on incomplete request */ 860Sstevel@tonic-gate } gact_t; 870Sstevel@tonic-gate 880Sstevel@tonic-gate 890Sstevel@tonic-gate /* 900Sstevel@tonic-gate * the common portion of the Command Control Block 910Sstevel@tonic-gate */ 920Sstevel@tonic-gate 930Sstevel@tonic-gate typedef struct ghd_cmd { 940Sstevel@tonic-gate L2el_t cmd_q; /* link for for done/active CCB Qs */ 950Sstevel@tonic-gate cmdstate_t cmd_state; /* request's current state */ 960Sstevel@tonic-gate uint32_t cmd_waitq_level; /* which wait Q this request is on */ 970Sstevel@tonic-gate 980Sstevel@tonic-gate L2el_t cmd_timer_link; /* ccb timer doubly linked list */ 990Sstevel@tonic-gate clock_t cmd_start_time; /* lbolt at start of request */ 1000Sstevel@tonic-gate clock_t cmd_timeout; /* how long to wait */ 1010Sstevel@tonic-gate 1020Sstevel@tonic-gate opaque_t cmd_private; /* used by the HBA driver */ 1030Sstevel@tonic-gate void *cmd_pktp; /* request packet */ 1040Sstevel@tonic-gate gtgt_t *cmd_gtgtp; /* dev instance for this request */ 1050Sstevel@tonic-gate 1060Sstevel@tonic-gate ddi_dma_handle_t cmd_dma_handle; 1070Sstevel@tonic-gate ddi_dma_win_t cmd_dmawin; 1080Sstevel@tonic-gate ddi_dma_seg_t cmd_dmaseg; 1090Sstevel@tonic-gate int cmd_dma_flags; 1100Sstevel@tonic-gate long cmd_totxfer; 1110Sstevel@tonic-gate long cmd_resid; 1120Sstevel@tonic-gate } gcmd_t; 1130Sstevel@tonic-gate 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate /* 1180Sstevel@tonic-gate * Initialize the gcmd_t structure 1190Sstevel@tonic-gate */ 1200Sstevel@tonic-gate 1210Sstevel@tonic-gate #define GHD_GCMD_INIT(gcmdp, cmdp, gtgtp) \ 1220Sstevel@tonic-gate (L2_INIT(&(gcmdp)->cmd_q), \ 1230Sstevel@tonic-gate L2_INIT(&(gcmdp)->cmd_timer_link), \ 1240Sstevel@tonic-gate (gcmdp)->cmd_private = (cmdp), \ 1250Sstevel@tonic-gate (gcmdp)->cmd_gtgtp = (gtgtp) \ 1260Sstevel@tonic-gate ) 1270Sstevel@tonic-gate 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate /* 1300Sstevel@tonic-gate * CMD/CCB timer config structure - one per HBA driver module 1310Sstevel@tonic-gate */ 1320Sstevel@tonic-gate typedef struct tmr_conf { 1330Sstevel@tonic-gate kmutex_t t_mutex; /* mutex to protect t_ccc_listp */ 1340Sstevel@tonic-gate timeout_id_t t_timeout_id; /* handle for timeout() function */ 1350Sstevel@tonic-gate clock_t t_ticks; /* periodic timeout in clock ticks */ 1360Sstevel@tonic-gate int t_refs; /* reference count */ 1370Sstevel@tonic-gate struct cmd_ctl *t_ccc_listp; /* control struct list, one per HBA */ 1380Sstevel@tonic-gate } tmr_t; 139*1127Smrj _NOTE(MUTEX_PROTECTS_DATA(tmr_t::t_mutex, tmr_t::t_ccc_listp)) 140*1127Smrj _NOTE(MUTEX_PROTECTS_DATA(tmr_t::t_mutex, tmr_t::t_timeout_id)) 141*1127Smrj _NOTE(MUTEX_PROTECTS_DATA(tmr_t::t_mutex, tmr_t::t_refs)) 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate 1440Sstevel@tonic-gate 1450Sstevel@tonic-gate /* 1460Sstevel@tonic-gate * CMD/CCB timer control structure - one per HBA instance (per board) 1470Sstevel@tonic-gate */ 1480Sstevel@tonic-gate typedef struct cmd_ctl { 1490Sstevel@tonic-gate struct cmd_ctl *ccc_nextp; /* list of control structs */ 1500Sstevel@tonic-gate struct tmr_conf *ccc_tmrp; /* back ptr to config struct */ 1510Sstevel@tonic-gate char *ccc_label; /* name of this HBA driver */ 1520Sstevel@tonic-gate int ccc_chno; /* Channle number */ 1530Sstevel@tonic-gate 1540Sstevel@tonic-gate kmutex_t ccc_activel_mutex; /* mutex to protect list ... */ 1550Sstevel@tonic-gate L2el_t ccc_activel; /* ... list of active CMD/CCBs */ 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate dev_info_t *ccc_hba_dip; 1580Sstevel@tonic-gate ddi_iblock_cookie_t ccc_iblock; 1590Sstevel@tonic-gate ddi_softintr_t ccc_soft_id; /* ID for timeout softintr */ 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate kmutex_t ccc_hba_mutex; /* mutex for HBA soft-state */ 1620Sstevel@tonic-gate int ccc_hba_pollmode; /* FLAG_NOINTR mode active? */ 1630Sstevel@tonic-gate 1640Sstevel@tonic-gate L1_t ccc_devs; /* unsorted list of attached devs */ 1650Sstevel@tonic-gate kmutex_t ccc_waitq_mutex; /* mutex to protect device wait Qs */ 1660Sstevel@tonic-gate Q_t ccc_waitq; /* the HBA's wait queue */ 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate ddi_softintr_t ccc_doneq_softid; /* ID for doneq softintr */ 1690Sstevel@tonic-gate kmutex_t ccc_doneq_mutex; /* mutex to protect the doneq */ 1700Sstevel@tonic-gate L2el_t ccc_doneq; /* completed cmd_t's */ 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate void *ccc_hba_handle; 1730Sstevel@tonic-gate int (*ccc_ccballoc)(); /* alloc/init gcmd and ccb */ 1740Sstevel@tonic-gate void (*ccc_ccbfree)(); 1750Sstevel@tonic-gate void (*ccc_sg_func)(); 1760Sstevel@tonic-gate int (*ccc_hba_start)(void *handle, gcmd_t *); 1770Sstevel@tonic-gate void (*ccc_hba_complete)(void *handle, gcmd_t *, int); 1780Sstevel@tonic-gate void (*ccc_process_intr)(void *handle, void *intr_status, int chno); 1790Sstevel@tonic-gate int (*ccc_get_status)(void *handle, void *intr_status, int chno); 1800Sstevel@tonic-gate int (*ccc_timeout_func)(void *handle, gcmd_t *cmdp, gtgt_t *gtgtp, 1810Sstevel@tonic-gate gact_t action, int calltype); 1820Sstevel@tonic-gate } ccc_t; 183*1127Smrj _NOTE(MUTEX_PROTECTS_DATA(cmd_ctl::ccc_activel_mutex, cmd_ctl::ccc_activel)) 184*1127Smrj _NOTE(MUTEX_PROTECTS_DATA(cmd_ctl::ccc_hba_mutex, cmd_ctl::ccc_hba_dip)) 185*1127Smrj _NOTE(DATA_READABLE_WITHOUT_LOCK(cmd_ctl::ccc_hba_dip)) 186*1127Smrj _NOTE(MUTEX_PROTECTS_DATA(cmd_ctl::ccc_waitq_mutex, cmd_ctl::ccc_waitq)) 187*1127Smrj _NOTE(MUTEX_PROTECTS_DATA(cmd_ctl::ccc_doneq_mutex, cmd_ctl::ccc_doneq)) 188*1127Smrj 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate #define GHBA_QHEAD(cccp) ((cccp)->ccc_waitq.Q_qhead) 1910Sstevel@tonic-gate #define GHBA_MAXACTIVE(cccp) ((cccp)->ccc_waitq.Q_maxactive) 1920Sstevel@tonic-gate #define GHBA_NACTIVE(cccp) ((cccp)->ccc_waitq.Q_nactive) 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate /* Initialize the HBA's list headers */ 1950Sstevel@tonic-gate #define CCCP_INIT(cccp) { \ 1960Sstevel@tonic-gate L1HEADER_INIT(&(cccp)->ccc_devs); \ 1970Sstevel@tonic-gate L2_INIT(&(cccp)->ccc_doneq); \ 1980Sstevel@tonic-gate } 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate 2010Sstevel@tonic-gate #define CCCP2GDEVP(cccp) \ 2020Sstevel@tonic-gate (L1_EMPTY(&(cccp)->ccc_devs) \ 2030Sstevel@tonic-gate ? (gdev_t *)NULL \ 2040Sstevel@tonic-gate : (gdev_t *)((cccp)->ccc_devs.l1_headp->le_datap)) 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate /* ******************************************************************* */ 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate #include "ghd_scsa.h" 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate /* 2110Sstevel@tonic-gate * GHD Entry Points 2120Sstevel@tonic-gate */ 2130Sstevel@tonic-gate void ghd_complete(ccc_t *cccp, gcmd_t *cmdp); 2140Sstevel@tonic-gate void ghd_async_complete(ccc_t *cccp, gcmd_t *cmdp); 2150Sstevel@tonic-gate void ghd_doneq_put(ccc_t *cccp, gcmd_t *cmdp); 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate int ghd_intr(ccc_t *cccp, void *status, int chno); 2180Sstevel@tonic-gate int ghd_register(char *, ccc_t *, dev_info_t *, int, void *hba_handle, 2190Sstevel@tonic-gate int (*ccc_ccballoc)(gtgt_t *, gcmd_t *, int, int, 2200Sstevel@tonic-gate int, int), 2210Sstevel@tonic-gate void (*ccc_ccbfree)(gcmd_t *), 2220Sstevel@tonic-gate void (*ccc_sg_func)(gcmd_t *, ddi_dma_cookie_t *, 2230Sstevel@tonic-gate int, int), 2240Sstevel@tonic-gate int (*hba_start)(void *, gcmd_t *), 2250Sstevel@tonic-gate void (*hba_complete)(void *, gcmd_t *, int), 2260Sstevel@tonic-gate uint_t (*int_handler)(caddr_t), 2270Sstevel@tonic-gate int (*get_status)(void *, void *, int), 2280Sstevel@tonic-gate void (*process_intr)(void *, void *, int), 2290Sstevel@tonic-gate int (*timeout_func)(void *, gcmd_t *, gtgt_t *, 2300Sstevel@tonic-gate gact_t, int calltype), 2310Sstevel@tonic-gate tmr_t *tmrp, 2320Sstevel@tonic-gate ddi_iblock_cookie_t iblock, 2330Sstevel@tonic-gate int chno); 2340Sstevel@tonic-gate void ghd_unregister(ccc_t *cccp); 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate int ghd_transport(ccc_t *cccp, gcmd_t *cmdp, gtgt_t *gtgtp, 2370Sstevel@tonic-gate uint32_t timeout, int polled, void *intr_status); 2380Sstevel@tonic-gate 2390Sstevel@tonic-gate int ghd_tran_abort(ccc_t *cccp, gcmd_t *cmdp, gtgt_t *gtgtp, 2400Sstevel@tonic-gate void *intr_status); 2410Sstevel@tonic-gate int ghd_tran_abort_lun(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status); 2420Sstevel@tonic-gate int ghd_tran_reset_target(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status); 2430Sstevel@tonic-gate int ghd_tran_reset_bus(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status); 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate 2460Sstevel@tonic-gate /* 2470Sstevel@tonic-gate * Allocate a gcmd_t wrapper and HBA private area 2480Sstevel@tonic-gate */ 2490Sstevel@tonic-gate gcmd_t *ghd_gcmd_alloc(gtgt_t *gtgtp, int ccblen, int sleep); 2500Sstevel@tonic-gate 2510Sstevel@tonic-gate /* 2520Sstevel@tonic-gate * Free the gcmd_t wrapper and HBA private area 2530Sstevel@tonic-gate */ 2540Sstevel@tonic-gate void ghd_gcmd_free(gcmd_t *gcmdp); 2550Sstevel@tonic-gate 2560Sstevel@tonic-gate 2570Sstevel@tonic-gate /* 2580Sstevel@tonic-gate * GHD CMD/CCB timer Entry points 2590Sstevel@tonic-gate */ 2600Sstevel@tonic-gate 2610Sstevel@tonic-gate int ghd_timer_attach(ccc_t *cccp, tmr_t *tmrp, 2620Sstevel@tonic-gate int (*timeout_func)(void *handle, gcmd_t *, gtgt_t *, 2630Sstevel@tonic-gate gact_t, int)); 2640Sstevel@tonic-gate void ghd_timer_detach(ccc_t *cccp); 2650Sstevel@tonic-gate void ghd_timer_fini(tmr_t *tmrp); 2660Sstevel@tonic-gate void ghd_timer_init(tmr_t *tmrp, clock_t ticks); 2670Sstevel@tonic-gate void ghd_timer_newstate(ccc_t *cccp, gcmd_t *cmdp, gtgt_t *gtgtp, 2680Sstevel@tonic-gate gact_t action, int calltype); 2690Sstevel@tonic-gate void ghd_timer_poll(ccc_t *cccp); 2700Sstevel@tonic-gate void ghd_timer_start(ccc_t *cccp, gcmd_t *cmdp, uint32_t cmd_timeout); 2710Sstevel@tonic-gate void ghd_timer_stop(ccc_t *cccp, gcmd_t *cmdp); 2720Sstevel@tonic-gate 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate /* 2750Sstevel@tonic-gate * Wait queue utility routines 2760Sstevel@tonic-gate */ 2770Sstevel@tonic-gate 2780Sstevel@tonic-gate gtgt_t *ghd_target_init(dev_info_t *, dev_info_t *, ccc_t *, size_t, 2790Sstevel@tonic-gate void *, uint32_t, uint32_t); 2800Sstevel@tonic-gate void ghd_target_free(dev_info_t *, dev_info_t *, ccc_t *, gtgt_t *); 2810Sstevel@tonic-gate void ghd_waitq_shuffle_up(ccc_t *, gdev_t *); 2820Sstevel@tonic-gate void ghd_waitq_delete(ccc_t *, gcmd_t *); 2830Sstevel@tonic-gate int ghd_waitq_process_and_mutex_hold(ccc_t *); 2840Sstevel@tonic-gate void ghd_waitq_process_and_mutex_exit(ccc_t *); 2850Sstevel@tonic-gate 2860Sstevel@tonic-gate 2870Sstevel@tonic-gate /* 2880Sstevel@tonic-gate * The values for the calltype arg for the ghd_timer_newstate() function 2890Sstevel@tonic-gate */ 2900Sstevel@tonic-gate 2910Sstevel@tonic-gate #define GHD_NEWSTATE_TGTREQ 0 2920Sstevel@tonic-gate #define GHD_NEWSTATE_TIMEOUT 1 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate /* ******************************************************************* */ 2950Sstevel@tonic-gate 2960Sstevel@tonic-gate /* 2970Sstevel@tonic-gate * specify GHD_INLINE to get optimized versions 2980Sstevel@tonic-gate */ 2990Sstevel@tonic-gate #define GHD_INLINE 1 3000Sstevel@tonic-gate #if defined(GHD_DEBUG) || defined(DEBUG) || defined(__lint) 3010Sstevel@tonic-gate #undef GHD_INLINE 3020Sstevel@tonic-gate #endif 3030Sstevel@tonic-gate 3040Sstevel@tonic-gate #if defined(GHD_INLINE) 3050Sstevel@tonic-gate #define GHD_COMPLETE(cccp, gcmpd) GHD_COMPLETE_INLINE(cccp, gcmdp) 3060Sstevel@tonic-gate #define GHD_TIMER_STOP(cccp, gcmdp) GHD_TIMER_STOP_INLINE(cccp, gcmdp) 3070Sstevel@tonic-gate #define GHD_DONEQ_PUT(cccp, gcmdp) GHD_DONEQ_PUT_INLINE(cccp, gcmdp) 3080Sstevel@tonic-gate #else 3090Sstevel@tonic-gate #define GHD_COMPLETE(cccp, gcmpd) ghd_complete(cccp, gcmdp) 3100Sstevel@tonic-gate #define GHD_TIMER_STOP(cccp, gcmdp) ghd_timer_stop(cccp, gcmdp) 3110Sstevel@tonic-gate #define GHD_DONEQ_PUT(cccp, gcmdp) ghd_doneq_put(cccp, gcmdp) 3120Sstevel@tonic-gate #endif 3130Sstevel@tonic-gate 3140Sstevel@tonic-gate /* 3150Sstevel@tonic-gate * request is complete, stop the request timer and add to doneq 3160Sstevel@tonic-gate */ 3170Sstevel@tonic-gate #define GHD_COMPLETE_INLINE(cccp, gcmdp) \ 3180Sstevel@tonic-gate { \ 3190Sstevel@tonic-gate ghd_waitq_delete(cccp, gcmdp); \ 3200Sstevel@tonic-gate (gcmdp)->cmd_state = GCMD_STATE_DONEQ; \ 3210Sstevel@tonic-gate GHD_TIMER_STOP((cccp), (gcmdp)); \ 3220Sstevel@tonic-gate GHD_DONEQ_PUT((cccp), (gcmdp)); \ 3230Sstevel@tonic-gate } 3240Sstevel@tonic-gate 3250Sstevel@tonic-gate #define GHD_TIMER_STOP_INLINE(cccp, gcmdp) \ 3260Sstevel@tonic-gate { \ 3270Sstevel@tonic-gate mutex_enter(&(cccp)->ccc_activel_mutex); \ 3280Sstevel@tonic-gate L2_delete(&(gcmdp)->cmd_timer_link); \ 3290Sstevel@tonic-gate mutex_exit(&(cccp)->ccc_activel_mutex); \ 3300Sstevel@tonic-gate } 3310Sstevel@tonic-gate 3320Sstevel@tonic-gate /* 3330Sstevel@tonic-gate * mark the request done and append it to the doneq 3340Sstevel@tonic-gate */ 3350Sstevel@tonic-gate #define GHD_DONEQ_PUT_INLINE(cccp, gcmdp) \ 3360Sstevel@tonic-gate { \ 3370Sstevel@tonic-gate \ 3380Sstevel@tonic-gate mutex_enter(&(cccp)->ccc_doneq_mutex); \ 3390Sstevel@tonic-gate (gcmdp)->cmd_state = GCMD_STATE_DONEQ; \ 3400Sstevel@tonic-gate L2_add(&(cccp)->ccc_doneq, &(gcmdp)->cmd_q, (gcmdp)); \ 3410Sstevel@tonic-gate if (!(cccp)->ccc_hba_pollmode) \ 3420Sstevel@tonic-gate ddi_trigger_softintr((cccp)->ccc_doneq_softid); \ 3430Sstevel@tonic-gate mutex_exit(&(cccp)->ccc_doneq_mutex); \ 3440Sstevel@tonic-gate } 3450Sstevel@tonic-gate 3460Sstevel@tonic-gate 3470Sstevel@tonic-gate /* ******************************************************************* */ 3480Sstevel@tonic-gate 3490Sstevel@tonic-gate /* 3500Sstevel@tonic-gate * These are shortcut macros for linkages setup by GHD 3510Sstevel@tonic-gate */ 3520Sstevel@tonic-gate 3530Sstevel@tonic-gate /* 3540Sstevel@tonic-gate * (gcmd_t *) to (struct scsi_pkt *) 3550Sstevel@tonic-gate */ 3560Sstevel@tonic-gate #define GCMDP2PKTP(gcmdp) ((gcmdp)->cmd_pktp) 3570Sstevel@tonic-gate 3580Sstevel@tonic-gate /* 3590Sstevel@tonic-gate * (gcmd_t *) to (gtgt_t *) 3600Sstevel@tonic-gate */ 3610Sstevel@tonic-gate #define GCMDP2GTGTP(gcmdp) ((gcmdp)->cmd_gtgtp) 3620Sstevel@tonic-gate 3630Sstevel@tonic-gate /* 3640Sstevel@tonic-gate * (struct scsi_pkt *) to (gcmd_t *) 3650Sstevel@tonic-gate */ 3660Sstevel@tonic-gate #define PKTP2GCMDP(pktp) ((gcmd_t *)(pktp)->pkt_ha_private) 3670Sstevel@tonic-gate 3680Sstevel@tonic-gate 3690Sstevel@tonic-gate /* These are shortcut macros for linkages setup by SCSA */ 3700Sstevel@tonic-gate 3710Sstevel@tonic-gate /* 3720Sstevel@tonic-gate * (struct scsi_address *) to (scsi_hba_tran *) 3730Sstevel@tonic-gate */ 3740Sstevel@tonic-gate #define ADDR2TRAN(ap) ((ap)->a_hba_tran) 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate /* 3770Sstevel@tonic-gate * (struct scsi_device *) to (scsi_address *) 3780Sstevel@tonic-gate */ 3790Sstevel@tonic-gate #define SDEV2ADDR(sdp) (&(sdp)->sd_address) 3800Sstevel@tonic-gate 3810Sstevel@tonic-gate /* 3820Sstevel@tonic-gate * (struct scsi_device *) to (scsi_hba_tran *) 3830Sstevel@tonic-gate */ 3840Sstevel@tonic-gate #define SDEV2TRAN(sdp) ADDR2TRAN(SDEV2ADDR(sdp)) 3850Sstevel@tonic-gate 3860Sstevel@tonic-gate /* 3870Sstevel@tonic-gate * (struct scsi_pkt *) to (scsi_hba_tran *) 3880Sstevel@tonic-gate */ 3890Sstevel@tonic-gate #define PKTP2TRAN(pktp) ADDR2TRAN(&(pktp)->pkt_address) 3900Sstevel@tonic-gate 3910Sstevel@tonic-gate /* 3920Sstevel@tonic-gate * (scsi_hba_tran_t *) to (per-target-soft-state *) 3930Sstevel@tonic-gate */ 3940Sstevel@tonic-gate #define TRAN2GTGTP(tranp) ((gtgt_t *)((tranp)->tran_tgt_private)) 3950Sstevel@tonic-gate 3960Sstevel@tonic-gate /* 3970Sstevel@tonic-gate * (struct scsi_device *) to (per-target-soft-state *) 3980Sstevel@tonic-gate */ 3990Sstevel@tonic-gate #define SDEV2GTGTP(sd) TRAN2GTGTP(SDEV2TRAN(sd)) 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate /* 4020Sstevel@tonic-gate * (struct scsi_pkt *) to (per-target-soft-state *) 4030Sstevel@tonic-gate */ 4040Sstevel@tonic-gate #define PKTP2GTGTP(pktp) TRAN2GTGTP(PKTP2TRAN(pktp)) 4050Sstevel@tonic-gate 4060Sstevel@tonic-gate 4070Sstevel@tonic-gate /* 4080Sstevel@tonic-gate * (scsi_hba_tran_t *) to (per-HBA-soft-state *) 4090Sstevel@tonic-gate */ 4100Sstevel@tonic-gate #define TRAN2HBA(tranp) ((tranp)->tran_hba_private) 4110Sstevel@tonic-gate 4120Sstevel@tonic-gate 4130Sstevel@tonic-gate /* 4140Sstevel@tonic-gate * (struct scsi_device *) to (per-HBA-soft-state *) 4150Sstevel@tonic-gate */ 4160Sstevel@tonic-gate #define SDEV2HBA(sd) TRAN2HBA(SDEV2TRAN(sd)) 4170Sstevel@tonic-gate 4180Sstevel@tonic-gate /* 4190Sstevel@tonic-gate * (struct scsi_address *) to (per-target-soft-state *) 4200Sstevel@tonic-gate */ 4210Sstevel@tonic-gate #define ADDR2GTGTP(ap) TRAN2GTGTP(ADDR2TRAN(ap)) 4220Sstevel@tonic-gate 4230Sstevel@tonic-gate /* ******************************************************************* */ 4240Sstevel@tonic-gate 4250Sstevel@tonic-gate 4260Sstevel@tonic-gate #ifdef __cplusplus 4270Sstevel@tonic-gate } 4280Sstevel@tonic-gate #endif 4290Sstevel@tonic-gate 4300Sstevel@tonic-gate #endif /* _GHD_H */ 431