17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 54ab75253Smrj * Common Development and Distribution License (the "License"). 64ab75253Smrj * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21*0400f3c0Smrj 227c478bd9Sstevel@tonic-gate /* 234ab75253Smrj * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #ifndef _GHD_H 287c478bd9Sstevel@tonic-gate #define _GHD_H 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #ifdef __cplusplus 337c478bd9Sstevel@tonic-gate extern "C" { 347c478bd9Sstevel@tonic-gate #endif 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include <sys/types.h> 377c478bd9Sstevel@tonic-gate #include <sys/conf.h> 387c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 397c478bd9Sstevel@tonic-gate #include <sys/ddi.h> 407c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 417c478bd9Sstevel@tonic-gate #include <sys/debug.h> 427c478bd9Sstevel@tonic-gate #include <sys/scsi/scsi.h> 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate #include "ghd_queue.h" /* linked list structures */ 457c478bd9Sstevel@tonic-gate #include "ghd_scsi.h" 467c478bd9Sstevel@tonic-gate #include "ghd_waitq.h" 477c478bd9Sstevel@tonic-gate #include "ghd_debug.h" 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate #ifndef TRUE 507c478bd9Sstevel@tonic-gate #define TRUE 1 517c478bd9Sstevel@tonic-gate #endif 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate #ifndef FALSE 547c478bd9Sstevel@tonic-gate #define FALSE 0 557c478bd9Sstevel@tonic-gate #endif 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate /* 587c478bd9Sstevel@tonic-gate * values for cmd_state: 597c478bd9Sstevel@tonic-gate */ 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate typedef enum { 627c478bd9Sstevel@tonic-gate GCMD_STATE_IDLE = 0, 637c478bd9Sstevel@tonic-gate GCMD_STATE_WAITQ, 647c478bd9Sstevel@tonic-gate GCMD_STATE_ACTIVE, 657c478bd9Sstevel@tonic-gate GCMD_STATE_DONEQ, 667c478bd9Sstevel@tonic-gate GCMD_STATE_ABORTING_CMD, 677c478bd9Sstevel@tonic-gate GCMD_STATE_ABORTING_DEV, 687c478bd9Sstevel@tonic-gate GCMD_STATE_RESETTING_DEV, 697c478bd9Sstevel@tonic-gate GCMD_STATE_RESETTING_BUS, 707c478bd9Sstevel@tonic-gate GCMD_STATE_HUNG, 717c478bd9Sstevel@tonic-gate GCMD_NSTATES 727c478bd9Sstevel@tonic-gate } cmdstate_t; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate /* 757c478bd9Sstevel@tonic-gate * action codes for the HBA timeout function 767c478bd9Sstevel@tonic-gate */ 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate typedef enum { 797c478bd9Sstevel@tonic-gate GACTION_EARLY_TIMEOUT = 0, /* timed-out before started */ 807c478bd9Sstevel@tonic-gate GACTION_EARLY_ABORT, /* scsi_abort() before started */ 817c478bd9Sstevel@tonic-gate GACTION_ABORT_CMD, /* abort a specific request */ 827c478bd9Sstevel@tonic-gate GACTION_ABORT_DEV, /* abort everything on specifici dev */ 837c478bd9Sstevel@tonic-gate GACTION_RESET_TARGET, /* reset a specific dev */ 847c478bd9Sstevel@tonic-gate GACTION_RESET_BUS, /* reset the whole bus */ 857c478bd9Sstevel@tonic-gate GACTION_INCOMPLETE /* giving up on incomplete request */ 867c478bd9Sstevel@tonic-gate } gact_t; 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate /* 907c478bd9Sstevel@tonic-gate * the common portion of the Command Control Block 917c478bd9Sstevel@tonic-gate */ 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate typedef struct ghd_cmd { 947c478bd9Sstevel@tonic-gate L2el_t cmd_q; /* link for for done/active CCB Qs */ 957c478bd9Sstevel@tonic-gate cmdstate_t cmd_state; /* request's current state */ 967c478bd9Sstevel@tonic-gate uint32_t cmd_waitq_level; /* which wait Q this request is on */ 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate L2el_t cmd_timer_link; /* ccb timer doubly linked list */ 997c478bd9Sstevel@tonic-gate clock_t cmd_start_time; /* lbolt at start of request */ 1007c478bd9Sstevel@tonic-gate clock_t cmd_timeout; /* how long to wait */ 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate opaque_t cmd_private; /* used by the HBA driver */ 1037c478bd9Sstevel@tonic-gate void *cmd_pktp; /* request packet */ 1047c478bd9Sstevel@tonic-gate gtgt_t *cmd_gtgtp; /* dev instance for this request */ 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate ddi_dma_handle_t cmd_dma_handle; 1077c478bd9Sstevel@tonic-gate ddi_dma_win_t cmd_dmawin; 1087c478bd9Sstevel@tonic-gate ddi_dma_seg_t cmd_dmaseg; 1097c478bd9Sstevel@tonic-gate int cmd_dma_flags; 1107c478bd9Sstevel@tonic-gate long cmd_totxfer; 1117c478bd9Sstevel@tonic-gate long cmd_resid; 1127c478bd9Sstevel@tonic-gate } gcmd_t; 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate /* 1187c478bd9Sstevel@tonic-gate * Initialize the gcmd_t structure 1197c478bd9Sstevel@tonic-gate */ 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate #define GHD_GCMD_INIT(gcmdp, cmdp, gtgtp) \ 1227c478bd9Sstevel@tonic-gate (L2_INIT(&(gcmdp)->cmd_q), \ 1237c478bd9Sstevel@tonic-gate L2_INIT(&(gcmdp)->cmd_timer_link), \ 1247c478bd9Sstevel@tonic-gate (gcmdp)->cmd_private = (cmdp), \ 1257c478bd9Sstevel@tonic-gate (gcmdp)->cmd_gtgtp = (gtgtp) \ 1267c478bd9Sstevel@tonic-gate ) 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate /* 1307c478bd9Sstevel@tonic-gate * CMD/CCB timer config structure - one per HBA driver module 1317c478bd9Sstevel@tonic-gate */ 1327c478bd9Sstevel@tonic-gate typedef struct tmr_conf { 1337c478bd9Sstevel@tonic-gate kmutex_t t_mutex; /* mutex to protect t_ccc_listp */ 1347c478bd9Sstevel@tonic-gate timeout_id_t t_timeout_id; /* handle for timeout() function */ 1357c478bd9Sstevel@tonic-gate clock_t t_ticks; /* periodic timeout in clock ticks */ 1367c478bd9Sstevel@tonic-gate int t_refs; /* reference count */ 1377c478bd9Sstevel@tonic-gate struct cmd_ctl *t_ccc_listp; /* control struct list, one per HBA */ 1387c478bd9Sstevel@tonic-gate } tmr_t; 139*0400f3c0Smrj _NOTE(MUTEX_PROTECTS_DATA(tmr_t::t_mutex, tmr_t::t_ccc_listp)) 140*0400f3c0Smrj _NOTE(MUTEX_PROTECTS_DATA(tmr_t::t_mutex, tmr_t::t_timeout_id)) 141*0400f3c0Smrj _NOTE(MUTEX_PROTECTS_DATA(tmr_t::t_mutex, tmr_t::t_refs)) 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate /* 1467c478bd9Sstevel@tonic-gate * CMD/CCB timer control structure - one per HBA instance (per board) 1477c478bd9Sstevel@tonic-gate */ 1487c478bd9Sstevel@tonic-gate typedef struct cmd_ctl { 1497c478bd9Sstevel@tonic-gate struct cmd_ctl *ccc_nextp; /* list of control structs */ 1507c478bd9Sstevel@tonic-gate struct tmr_conf *ccc_tmrp; /* back ptr to config struct */ 1517c478bd9Sstevel@tonic-gate char *ccc_label; /* name of this HBA driver */ 1527c478bd9Sstevel@tonic-gate int ccc_chno; /* Channle number */ 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate kmutex_t ccc_activel_mutex; /* mutex to protect list ... */ 1557c478bd9Sstevel@tonic-gate L2el_t ccc_activel; /* ... list of active CMD/CCBs */ 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate dev_info_t *ccc_hba_dip; 1587c478bd9Sstevel@tonic-gate ddi_iblock_cookie_t ccc_iblock; 1597c478bd9Sstevel@tonic-gate ddi_softintr_t ccc_soft_id; /* ID for timeout softintr */ 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate kmutex_t ccc_hba_mutex; /* mutex for HBA soft-state */ 1627c478bd9Sstevel@tonic-gate int ccc_hba_pollmode; /* FLAG_NOINTR mode active? */ 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate L1_t ccc_devs; /* unsorted list of attached devs */ 1657c478bd9Sstevel@tonic-gate kmutex_t ccc_waitq_mutex; /* mutex to protect device wait Qs */ 1667c478bd9Sstevel@tonic-gate Q_t ccc_waitq; /* the HBA's wait queue */ 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate ddi_softintr_t ccc_doneq_softid; /* ID for doneq softintr */ 1697c478bd9Sstevel@tonic-gate kmutex_t ccc_doneq_mutex; /* mutex to protect the doneq */ 1707c478bd9Sstevel@tonic-gate L2el_t ccc_doneq; /* completed cmd_t's */ 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate void *ccc_hba_handle; 1737c478bd9Sstevel@tonic-gate int (*ccc_ccballoc)(); /* alloc/init gcmd and ccb */ 1747c478bd9Sstevel@tonic-gate void (*ccc_ccbfree)(); 1757c478bd9Sstevel@tonic-gate void (*ccc_sg_func)(); 1767c478bd9Sstevel@tonic-gate int (*ccc_hba_start)(void *handle, gcmd_t *); 1777c478bd9Sstevel@tonic-gate void (*ccc_hba_complete)(void *handle, gcmd_t *, int); 1787c478bd9Sstevel@tonic-gate void (*ccc_process_intr)(void *handle, void *intr_status, int chno); 1797c478bd9Sstevel@tonic-gate int (*ccc_get_status)(void *handle, void *intr_status, int chno); 1807c478bd9Sstevel@tonic-gate int (*ccc_timeout_func)(void *handle, gcmd_t *cmdp, gtgt_t *gtgtp, 1817c478bd9Sstevel@tonic-gate gact_t action, int calltype); 1827c478bd9Sstevel@tonic-gate } ccc_t; 183*0400f3c0Smrj _NOTE(MUTEX_PROTECTS_DATA(cmd_ctl::ccc_activel_mutex, cmd_ctl::ccc_activel)) 184*0400f3c0Smrj _NOTE(MUTEX_PROTECTS_DATA(cmd_ctl::ccc_hba_mutex, cmd_ctl::ccc_hba_dip)) 185*0400f3c0Smrj _NOTE(DATA_READABLE_WITHOUT_LOCK(cmd_ctl::ccc_hba_dip)) 186*0400f3c0Smrj _NOTE(MUTEX_PROTECTS_DATA(cmd_ctl::ccc_waitq_mutex, cmd_ctl::ccc_waitq)) 187*0400f3c0Smrj _NOTE(MUTEX_PROTECTS_DATA(cmd_ctl::ccc_doneq_mutex, cmd_ctl::ccc_doneq)) 188*0400f3c0Smrj 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate #define GHBA_QHEAD(cccp) ((cccp)->ccc_waitq.Q_qhead) 1917c478bd9Sstevel@tonic-gate #define GHBA_MAXACTIVE(cccp) ((cccp)->ccc_waitq.Q_maxactive) 1927c478bd9Sstevel@tonic-gate #define GHBA_NACTIVE(cccp) ((cccp)->ccc_waitq.Q_nactive) 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate /* Initialize the HBA's list headers */ 1957c478bd9Sstevel@tonic-gate #define CCCP_INIT(cccp) { \ 1967c478bd9Sstevel@tonic-gate L1HEADER_INIT(&(cccp)->ccc_devs); \ 1977c478bd9Sstevel@tonic-gate L2_INIT(&(cccp)->ccc_doneq); \ 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate #define CCCP2GDEVP(cccp) \ 2027c478bd9Sstevel@tonic-gate (L1_EMPTY(&(cccp)->ccc_devs) \ 2037c478bd9Sstevel@tonic-gate ? (gdev_t *)NULL \ 2047c478bd9Sstevel@tonic-gate : (gdev_t *)((cccp)->ccc_devs.l1_headp->le_datap)) 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate /* ******************************************************************* */ 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate #include "ghd_scsa.h" 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate /* 2117c478bd9Sstevel@tonic-gate * GHD Entry Points 2127c478bd9Sstevel@tonic-gate */ 2137c478bd9Sstevel@tonic-gate void ghd_complete(ccc_t *cccp, gcmd_t *cmdp); 2147c478bd9Sstevel@tonic-gate void ghd_async_complete(ccc_t *cccp, gcmd_t *cmdp); 2157c478bd9Sstevel@tonic-gate void ghd_doneq_put(ccc_t *cccp, gcmd_t *cmdp); 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate int ghd_intr(ccc_t *cccp, void *status, int chno); 2187c478bd9Sstevel@tonic-gate int ghd_register(char *, ccc_t *, dev_info_t *, int, void *hba_handle, 2197c478bd9Sstevel@tonic-gate int (*ccc_ccballoc)(gtgt_t *, gcmd_t *, int, int, 2207c478bd9Sstevel@tonic-gate int, int), 2217c478bd9Sstevel@tonic-gate void (*ccc_ccbfree)(gcmd_t *), 2227c478bd9Sstevel@tonic-gate void (*ccc_sg_func)(gcmd_t *, ddi_dma_cookie_t *, 2237c478bd9Sstevel@tonic-gate int, int), 2247c478bd9Sstevel@tonic-gate int (*hba_start)(void *, gcmd_t *), 2257c478bd9Sstevel@tonic-gate void (*hba_complete)(void *, gcmd_t *, int), 2267c478bd9Sstevel@tonic-gate uint_t (*int_handler)(caddr_t), 2277c478bd9Sstevel@tonic-gate int (*get_status)(void *, void *, int), 2287c478bd9Sstevel@tonic-gate void (*process_intr)(void *, void *, int), 2297c478bd9Sstevel@tonic-gate int (*timeout_func)(void *, gcmd_t *, gtgt_t *, 2307c478bd9Sstevel@tonic-gate gact_t, int calltype), 2317c478bd9Sstevel@tonic-gate tmr_t *tmrp, 2327c478bd9Sstevel@tonic-gate ddi_iblock_cookie_t iblock, 2337c478bd9Sstevel@tonic-gate int chno); 2347c478bd9Sstevel@tonic-gate void ghd_unregister(ccc_t *cccp); 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate int ghd_transport(ccc_t *cccp, gcmd_t *cmdp, gtgt_t *gtgtp, 2377c478bd9Sstevel@tonic-gate uint32_t timeout, int polled, void *intr_status); 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate int ghd_tran_abort(ccc_t *cccp, gcmd_t *cmdp, gtgt_t *gtgtp, 2407c478bd9Sstevel@tonic-gate void *intr_status); 2417c478bd9Sstevel@tonic-gate int ghd_tran_abort_lun(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status); 2427c478bd9Sstevel@tonic-gate int ghd_tran_reset_target(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status); 2437c478bd9Sstevel@tonic-gate int ghd_tran_reset_bus(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status); 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate /* 2477c478bd9Sstevel@tonic-gate * Allocate a gcmd_t wrapper and HBA private area 2487c478bd9Sstevel@tonic-gate */ 2497c478bd9Sstevel@tonic-gate gcmd_t *ghd_gcmd_alloc(gtgt_t *gtgtp, int ccblen, int sleep); 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate /* 2527c478bd9Sstevel@tonic-gate * Free the gcmd_t wrapper and HBA private area 2537c478bd9Sstevel@tonic-gate */ 2547c478bd9Sstevel@tonic-gate void ghd_gcmd_free(gcmd_t *gcmdp); 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate /* 2587c478bd9Sstevel@tonic-gate * GHD CMD/CCB timer Entry points 2597c478bd9Sstevel@tonic-gate */ 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate int ghd_timer_attach(ccc_t *cccp, tmr_t *tmrp, 2627c478bd9Sstevel@tonic-gate int (*timeout_func)(void *handle, gcmd_t *, gtgt_t *, 2637c478bd9Sstevel@tonic-gate gact_t, int)); 2647c478bd9Sstevel@tonic-gate void ghd_timer_detach(ccc_t *cccp); 2657c478bd9Sstevel@tonic-gate void ghd_timer_fini(tmr_t *tmrp); 2667c478bd9Sstevel@tonic-gate void ghd_timer_init(tmr_t *tmrp, clock_t ticks); 2677c478bd9Sstevel@tonic-gate void ghd_timer_newstate(ccc_t *cccp, gcmd_t *cmdp, gtgt_t *gtgtp, 2687c478bd9Sstevel@tonic-gate gact_t action, int calltype); 2697c478bd9Sstevel@tonic-gate void ghd_timer_poll(ccc_t *cccp); 2707c478bd9Sstevel@tonic-gate void ghd_timer_start(ccc_t *cccp, gcmd_t *cmdp, uint32_t cmd_timeout); 2717c478bd9Sstevel@tonic-gate void ghd_timer_stop(ccc_t *cccp, gcmd_t *cmdp); 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate /* 2757c478bd9Sstevel@tonic-gate * Wait queue utility routines 2767c478bd9Sstevel@tonic-gate */ 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate gtgt_t *ghd_target_init(dev_info_t *, dev_info_t *, ccc_t *, size_t, 2797c478bd9Sstevel@tonic-gate void *, uint32_t, uint32_t); 2807c478bd9Sstevel@tonic-gate void ghd_target_free(dev_info_t *, dev_info_t *, ccc_t *, gtgt_t *); 2817c478bd9Sstevel@tonic-gate void ghd_waitq_shuffle_up(ccc_t *, gdev_t *); 2827c478bd9Sstevel@tonic-gate void ghd_waitq_delete(ccc_t *, gcmd_t *); 2837c478bd9Sstevel@tonic-gate int ghd_waitq_process_and_mutex_hold(ccc_t *); 2847c478bd9Sstevel@tonic-gate void ghd_waitq_process_and_mutex_exit(ccc_t *); 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate /* 2887c478bd9Sstevel@tonic-gate * The values for the calltype arg for the ghd_timer_newstate() function 2897c478bd9Sstevel@tonic-gate */ 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate #define GHD_NEWSTATE_TGTREQ 0 2927c478bd9Sstevel@tonic-gate #define GHD_NEWSTATE_TIMEOUT 1 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate /* ******************************************************************* */ 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate /* 2977c478bd9Sstevel@tonic-gate * specify GHD_INLINE to get optimized versions 2987c478bd9Sstevel@tonic-gate */ 2997c478bd9Sstevel@tonic-gate #define GHD_INLINE 1 3007c478bd9Sstevel@tonic-gate #if defined(GHD_DEBUG) || defined(DEBUG) || defined(__lint) 3017c478bd9Sstevel@tonic-gate #undef GHD_INLINE 3027c478bd9Sstevel@tonic-gate #endif 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate #if defined(GHD_INLINE) 3057c478bd9Sstevel@tonic-gate #define GHD_COMPLETE(cccp, gcmpd) GHD_COMPLETE_INLINE(cccp, gcmdp) 3067c478bd9Sstevel@tonic-gate #define GHD_TIMER_STOP(cccp, gcmdp) GHD_TIMER_STOP_INLINE(cccp, gcmdp) 3077c478bd9Sstevel@tonic-gate #define GHD_DONEQ_PUT(cccp, gcmdp) GHD_DONEQ_PUT_INLINE(cccp, gcmdp) 3087c478bd9Sstevel@tonic-gate #else 3097c478bd9Sstevel@tonic-gate #define GHD_COMPLETE(cccp, gcmpd) ghd_complete(cccp, gcmdp) 3107c478bd9Sstevel@tonic-gate #define GHD_TIMER_STOP(cccp, gcmdp) ghd_timer_stop(cccp, gcmdp) 3117c478bd9Sstevel@tonic-gate #define GHD_DONEQ_PUT(cccp, gcmdp) ghd_doneq_put(cccp, gcmdp) 3127c478bd9Sstevel@tonic-gate #endif 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate /* 3157c478bd9Sstevel@tonic-gate * request is complete, stop the request timer and add to doneq 3167c478bd9Sstevel@tonic-gate */ 3177c478bd9Sstevel@tonic-gate #define GHD_COMPLETE_INLINE(cccp, gcmdp) \ 3187c478bd9Sstevel@tonic-gate { \ 3197c478bd9Sstevel@tonic-gate ghd_waitq_delete(cccp, gcmdp); \ 3207c478bd9Sstevel@tonic-gate (gcmdp)->cmd_state = GCMD_STATE_DONEQ; \ 3217c478bd9Sstevel@tonic-gate GHD_TIMER_STOP((cccp), (gcmdp)); \ 3227c478bd9Sstevel@tonic-gate GHD_DONEQ_PUT((cccp), (gcmdp)); \ 3237c478bd9Sstevel@tonic-gate } 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate #define GHD_TIMER_STOP_INLINE(cccp, gcmdp) \ 3267c478bd9Sstevel@tonic-gate { \ 3277c478bd9Sstevel@tonic-gate mutex_enter(&(cccp)->ccc_activel_mutex); \ 3287c478bd9Sstevel@tonic-gate L2_delete(&(gcmdp)->cmd_timer_link); \ 3297c478bd9Sstevel@tonic-gate mutex_exit(&(cccp)->ccc_activel_mutex); \ 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate /* 3337c478bd9Sstevel@tonic-gate * mark the request done and append it to the doneq 3347c478bd9Sstevel@tonic-gate */ 3357c478bd9Sstevel@tonic-gate #define GHD_DONEQ_PUT_INLINE(cccp, gcmdp) \ 3367c478bd9Sstevel@tonic-gate { \ 3377c478bd9Sstevel@tonic-gate \ 3387c478bd9Sstevel@tonic-gate mutex_enter(&(cccp)->ccc_doneq_mutex); \ 3397c478bd9Sstevel@tonic-gate (gcmdp)->cmd_state = GCMD_STATE_DONEQ; \ 3407c478bd9Sstevel@tonic-gate L2_add(&(cccp)->ccc_doneq, &(gcmdp)->cmd_q, (gcmdp)); \ 3417c478bd9Sstevel@tonic-gate if (!(cccp)->ccc_hba_pollmode) \ 3427c478bd9Sstevel@tonic-gate ddi_trigger_softintr((cccp)->ccc_doneq_softid); \ 3437c478bd9Sstevel@tonic-gate mutex_exit(&(cccp)->ccc_doneq_mutex); \ 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate /* ******************************************************************* */ 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate /* 3507c478bd9Sstevel@tonic-gate * These are shortcut macros for linkages setup by GHD 3517c478bd9Sstevel@tonic-gate */ 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate /* 3547c478bd9Sstevel@tonic-gate * (gcmd_t *) to (struct scsi_pkt *) 3557c478bd9Sstevel@tonic-gate */ 3567c478bd9Sstevel@tonic-gate #define GCMDP2PKTP(gcmdp) ((gcmdp)->cmd_pktp) 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate /* 3597c478bd9Sstevel@tonic-gate * (gcmd_t *) to (gtgt_t *) 3607c478bd9Sstevel@tonic-gate */ 3617c478bd9Sstevel@tonic-gate #define GCMDP2GTGTP(gcmdp) ((gcmdp)->cmd_gtgtp) 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate /* 3647c478bd9Sstevel@tonic-gate * (struct scsi_pkt *) to (gcmd_t *) 3657c478bd9Sstevel@tonic-gate */ 3667c478bd9Sstevel@tonic-gate #define PKTP2GCMDP(pktp) ((gcmd_t *)(pktp)->pkt_ha_private) 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate /* These are shortcut macros for linkages setup by SCSA */ 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate /* 3727c478bd9Sstevel@tonic-gate * (struct scsi_address *) to (scsi_hba_tran *) 3737c478bd9Sstevel@tonic-gate */ 3747c478bd9Sstevel@tonic-gate #define ADDR2TRAN(ap) ((ap)->a_hba_tran) 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate /* 3777c478bd9Sstevel@tonic-gate * (struct scsi_device *) to (scsi_address *) 3787c478bd9Sstevel@tonic-gate */ 3797c478bd9Sstevel@tonic-gate #define SDEV2ADDR(sdp) (&(sdp)->sd_address) 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate /* 3827c478bd9Sstevel@tonic-gate * (struct scsi_device *) to (scsi_hba_tran *) 3837c478bd9Sstevel@tonic-gate */ 3847c478bd9Sstevel@tonic-gate #define SDEV2TRAN(sdp) ADDR2TRAN(SDEV2ADDR(sdp)) 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate /* 3877c478bd9Sstevel@tonic-gate * (struct scsi_pkt *) to (scsi_hba_tran *) 3887c478bd9Sstevel@tonic-gate */ 3897c478bd9Sstevel@tonic-gate #define PKTP2TRAN(pktp) ADDR2TRAN(&(pktp)->pkt_address) 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate /* 3927c478bd9Sstevel@tonic-gate * (scsi_hba_tran_t *) to (per-target-soft-state *) 3937c478bd9Sstevel@tonic-gate */ 3947c478bd9Sstevel@tonic-gate #define TRAN2GTGTP(tranp) ((gtgt_t *)((tranp)->tran_tgt_private)) 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate /* 3977c478bd9Sstevel@tonic-gate * (struct scsi_device *) to (per-target-soft-state *) 3987c478bd9Sstevel@tonic-gate */ 3997c478bd9Sstevel@tonic-gate #define SDEV2GTGTP(sd) TRAN2GTGTP(SDEV2TRAN(sd)) 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate /* 4027c478bd9Sstevel@tonic-gate * (struct scsi_pkt *) to (per-target-soft-state *) 4037c478bd9Sstevel@tonic-gate */ 4047c478bd9Sstevel@tonic-gate #define PKTP2GTGTP(pktp) TRAN2GTGTP(PKTP2TRAN(pktp)) 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate /* 4087c478bd9Sstevel@tonic-gate * (scsi_hba_tran_t *) to (per-HBA-soft-state *) 4097c478bd9Sstevel@tonic-gate */ 4107c478bd9Sstevel@tonic-gate #define TRAN2HBA(tranp) ((tranp)->tran_hba_private) 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate /* 4147c478bd9Sstevel@tonic-gate * (struct scsi_device *) to (per-HBA-soft-state *) 4157c478bd9Sstevel@tonic-gate */ 4167c478bd9Sstevel@tonic-gate #define SDEV2HBA(sd) TRAN2HBA(SDEV2TRAN(sd)) 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate /* 4197c478bd9Sstevel@tonic-gate * (struct scsi_address *) to (per-target-soft-state *) 4207c478bd9Sstevel@tonic-gate */ 4217c478bd9Sstevel@tonic-gate #define ADDR2GTGTP(ap) TRAN2GTGTP(ADDR2TRAN(ap)) 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate /* ******************************************************************* */ 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate #ifdef __cplusplus 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate #endif 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate #endif /* _GHD_H */ 431