/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_SCSI_ADAPTERS_SFVAR_H #define _SYS_SCSI_ADAPTERS_SFVAR_H #pragma ident "%Z%%M% %I% %E% SMI" /* * FC-AL FCP driver definitions */ #ifdef __cplusplus extern "C" { #endif /* * this is to generate unique minor numbers for each minor * node type being created. because of the limitations by SCSA, * we have to use minor number values from 32 to 63 for the HBA * drivers use */ #define SF_BASE_MINOR 32 #define SF_DEVCTL_MINOR (SF_BASE_MINOR + 1) #define SF_FC_MINOR (SF_BASE_MINOR + 2) #define SF_INST_SHIFT4MINOR 6 #define SF_INST2DEVCTL_MINOR(x) (((x) << SF_INST_SHIFT4MINOR) | SF_DEVCTL_MINOR) #define SF_INST2FC_MINOR(x) (((x) << SF_INST_SHIFT4MINOR) | SF_FC_MINOR) #define SF_MINOR2INST(x) ((x) >> SF_INST_SHIFT4MINOR) #define SF_INIT_ITEMS 5 #define SF_MAX_TARGETS 126 #define SF_MAX_LILP_ENTRIES 126 #define SF_NUM_HASH_QUEUES 32 #define SF_HASH(x, y) ((x[0]+x[1]+x[2]+x[3]+x[4]+x[5]+x[6]+x[7]) &\ (SF_NUM_HASH_QUEUES-1)) /* * sf driver needs to be sanitized for exporting some of its * macros/variables to userland programs. */ #ifdef _KERNEL /* * sf instance structure */ struct sf { struct scsi_hba_tran *sf_tran; dev_info_t *sf_dip; struct sf *sf_next; struct sf *sf_sibling; kmutex_t sf_mutex; kmutex_t sf_cr_mutex; uint_t sf_state; int64_t sf_reset_time; /* reset/lip init time for bus_config */ struct sf_target *sf_targets[SF_MAX_TARGETS]; struct sf_target *sf_wwn_lists[SF_NUM_HASH_QUEUES]; void *sf_socp; /* pointer to socal state */ struct fcal_transport *sf_sochandle; kmutex_t sf_cmd_mutex; int sf_throttle; int sf_ncmds; int sf_ncmds_exp_avg; int sf_device_count; uint_t sf_use_lock; uint_t sf_timer; uint_t sf_online_timer; int sf_take_core; struct kmem_cache *sf_pkt_cache; struct sf_pkt *sf_pkt_head; /* packet queue */ struct sf_pkt *sf_pkt_tail; struct sf_els_hdr *sf_els_list; struct sf_reset_list *sf_reset_list; kcondvar_t sf_cr_cv; uint_t sf_cr_pool_cnt; struct sf_cr_pool *sf_cr_pool; /* list of command/response pools */ uchar_t sf_al_pa; uchar_t sf_busy; uchar_t sf_flag; uchar_t sf_cr_flag; /* synchronize creation of new cr pools */ uint_t sf_lip_cnt; struct scsi_reset_notify_entry *sf_reset_notify_listf; struct fcal_lilp_map *sf_lilp_map; ddi_dma_handle_t sf_lilp_dmahandle; ddi_acc_handle_t sf_lilp_acchandle; ddi_dma_cookie_t sf_lilp_dmacookie; kstat_t *sf_ksp; kmutex_t sf_hp_daemon_mutex; kcondvar_t sf_hp_daemon_cv; struct sf_hp_elem *sf_hp_elem_head; struct sf_hp_elem *sf_hp_elem_tail; /* * Event handling */ ndi_event_definition_t *sf_event_defs; ndi_event_hdl_t sf_event_hdl; ndi_event_set_t sf_events; struct sf_stats sf_stats; uchar_t sf_hp_exit; /* hotplugging thread exit flag */ uchar_t sf_check_n_close; /* check if unopened sf is being closed */ kt_did_t sf_hp_tid; /* hotplug thread id */ }; #define SF_STATE_INIT 0x01 #define SF_STATE_OFFLINE 0x02 #define SF_STATE_ONLINE 0x04 #define SF_STATE_ONLINING 0x08 #define SF_STATE_SUSPENDED 0x10 /* driver has been suspended */ #define SF_EVENT_TAG_INSERT 0 #define SF_EVENT_TAG_REMOVE 1 /* * pool of sf command response blocks */ struct sf_cr_pool { struct sf_cr_pool *next; struct sf_cr_free_elem *free; struct sf *sf; caddr_t cmd_base; /* start addr of this chunk */ ddi_dma_handle_t cmd_dma_handle; /* dma mapping for this chunk */ ddi_acc_handle_t cmd_acc_handle; caddr_t rsp_base; ddi_dma_handle_t rsp_dma_handle; ddi_acc_handle_t rsp_acc_handle; uint_t nfree; uint_t ntot; }; #define SF_CR_POOL_MAX 32 /* allows 4096 outstanding packets */ #define SF_ELEMS_IN_POOL 128 #define SF_LOG2_ELEMS_IN_POOL 7 /* LOG2 SF_ELEMS_IN_POOL */ #define SF_FREE_CR_EPSILON 64 /* SF_ELEMS_IN_POOL /2 */ /* * sf command/response free structure which is overlaid on fcp_cmd */ struct sf_cr_free_elem { struct sf_cr_free_elem *next; caddr_t rsp; /* ptr to corresponding rsp */ uint_t cmd_dmac; /* dmac_address for cmd */ uint_t rsp_dmac; /* dmac_address for rsp */ }; /* * list of targets for reset delay handling */ struct sf_reset_list { struct sf_reset_list *next; struct sf_target *target; clock_t timeout; uint_t lip_cnt; }; /* * structure used to store hotplug event callback info */ struct sf_hp_event { int (*callback)(); void *arg; }; /* * sf per target structure */ struct sf_target { struct sf_pkt *sft_pkt_head; /* queue of active commands */ struct sf_pkt *sft_pkt_tail; kmutex_t sft_mutex; kcondvar_t sft_cv; kmutex_t sft_pkt_mutex; dev_info_t *sft_dip; uchar_t sft_node_wwn[FC_WWN_SIZE]; uchar_t sft_port_wwn[FC_WWN_SIZE]; union { /* It's easier to shove around an int64 than a byte array */ uchar_t b[FCP_LUN_SIZE]; int64_t l; } sft_lun; /* XXXX The RAID LUN field is used to implement FCP Annex C */ #ifdef RAID_LUNS uint_t sft_raid_lun; #define SCSA_LUN(t) (int64_t)(t)->sft_raid_lun #else #define SCSA_LUN(t) (t)->sft_lun.l #endif uchar_t sft_hard_address; uchar_t sft_al_pa; uchar_t sft_device_type; uchar_t sft_scan_count; uint_t sft_alive; uint_t sft_state; uint_t sft_lip_cnt; struct scsi_hba_tran *sft_tran; struct sf_target *sft_next; struct sf_target *sft_next_lun; struct sf_hp_event sft_insert_ev; struct sf_hp_event sft_remove_ev; struct scsi_inquiry sft_inq; }; #define SF_TARGET_INIT_DONE 0x1 #define SF_TARGET_BUSY 0x2 #define SF_TARGET_OFFLINE 0x4 #define SF_TARGET_MARK 0x8 /* * sf packet */ #define PKT2CMD(pkt) ((struct sf_pkt *)pkt->pkt_ha_private) #define CMD2PKT(cmd) ((cmd)->cmd_pkt) #ifdef _LP64 #define PKT_PRIV_SIZE 2 #define PKT_PRIV_LEN 16 #else /* _ILP32 */ #define PKT_PRIV_SIZE 1 #define PKT_PRIV_LEN 8 #endif struct sf_pkt { struct sf_pkt *cmd_forw; struct sf_pkt *cmd_back; struct sf_pkt *cmd_next; struct scsi_pkt *cmd_pkt; fcal_packet_t *cmd_fp_pkt; uint_t cmd_state; uint_t cmd_timeout; char cmd_scsi_scb[sizeof (struct scsi_arq_status)]; uint32_t cmd_dmacount; ddi_dma_handle_t cmd_dmahandle; /* dma handle */ ddi_dma_cookie_t cmd_dmacookie; /* current dma cookie */ uint_t cmd_flags; /* private flags */ /* needs ZEROING */ uint_t cmd_cdblen; /* length of cdb */ /* needs to be INITialized */ uint_t cmd_scblen; /* length of scb */ /* needs to be INITialized */ uint_t cmd_privlen; /* length of tgt private */ /* needs to be INITialized */ struct sf_cr_pool *cmd_cr_pool; /* pool to which cmd/rsp belong */ struct fcp_cmd *cmd_block; struct fcp_rsp *cmd_rsp_block; kmutex_t cmd_abort_mutex; /* packet abort mutex */ uint_t cmd_dmac; uint_t cmd_rsp_dmac; uint64_t cmd_pkt_private[PKT_PRIV_LEN]; /* default target private area */ }; #define SF_STATE_IDLE 0x1 #define SF_STATE_ISSUED 0x2 #define SF_STATE_ABORTING 0x4 /* * Define size of extended scsi cmd pkt (ie. includes ARQ) */ #define EXTCMDS_STATUS_SIZE (sizeof (struct scsi_arq_status)) /* * These are the defined flags for this structure. */ #define CFLAG_DMAVALID 0x0010 /* dma mapping valid */ #define CFLAG_DMASEND 0x0020 /* data is going 'out' */ #define CFLAG_CMDIOPB 0x0040 /* this is an 'iopb' packet */ #define CFLAG_CDBEXTERN 0x0100 /* cdb kmem_alloc'd */ #define CFLAG_SCBEXTERN 0x0200 /* scb kmem_alloc'd */ #define CFLAG_FREE 0x0400 /* packet is on free list */ #define CFLAG_PRIVEXTERN 0x1000 /* target private was */ /* kmem_alloc'd */ #define CFLAG_IN_QUEUE 0x2000 /* command in sf queue */ struct sf_els_hdr { struct sf *sf; caddr_t cmd; caddr_t rsp; uchar_t els_code; uchar_t delayed_retry; ddi_dma_handle_t cmd_dma_handle; ddi_dma_handle_t rsp_dma_handle; ddi_acc_handle_t cmd_acc_handle; ddi_acc_handle_t rsp_acc_handle; uint_t dest_nport_id; struct sf_els_hdr *next; struct sf_els_hdr *prev; uint_t size; uint_t timeout; uint_t retries; struct fcal_packet *fpkt; uint_t lip_cnt; uchar_t port_wwn[FC_WWN_SIZE]; uchar_t node_wwn[FC_WWN_SIZE]; struct sf_target *target; ddi_dma_handle_t data_dma_handle; ddi_acc_handle_t data_acc_handle; caddr_t data_buf; }; union sf_els_cmd { struct la_els_logi logi; struct la_els_logo logo; struct la_els_prli prli; struct la_els_adisc adisc; struct fcp_cmd cmd; }; union sf_els_rsp { struct la_els_logi logi; struct la_els_logo logo; struct la_els_prli prli; struct la_els_adisc adisc; uchar_t rsp[FCP_MAX_RSP_IU_SIZE]; }; struct sf_hp_elem { struct sf_hp_elem *next; dev_info_t *dip; int what; struct sf_target *target; struct sf *sf; }; #define SF_ONLINE 0 #define SF_OFFLINE 1 #define ADDR2SF(ap) (struct sf *)((ap)->a_hba_tran->tran_hba_private) #define ADDR2TARGET(ap) (struct sf_target *)((ap)->a_hba_tran->\ tran_tgt_private) #define SF_ONLINE_TIMEOUT 180 #define SF_OFFLINE_TIMEOUT 45 #define SF_RESET_TIMEOUT 10 #define SF_ELS_TIMEOUT 5 #define SF_INVALID_TIMEOUT 0x7fffffff #define SF_FCP_TIMEOUT 30 #define SF_BSY_TIMEOUT 10 #define SF_ABORT_TIMEOUT 10000000 /* in usec */ #define SF_POLL_TIMEOUT 60 #define SF_TARGET_RESET_DELAY 250000 /* in usec */ #define SF_DECR_DELTA 5 #define SF_INCR_DELTA 5 #define SF_LO_CMD_DELTA 512 #define SF_HI_CMD_DELTA 256 #define SF_ELS_RETRIES 4 #define SF_BSY_RETRIES 7 #define SF_INIT_WAIT_TIMEOUT 60000000 #define SF_CORE_CMD_TIMEOUT 0x01 #define SF_CORE_BAD_ABORT 0x02 #define SF_CORE_ABORT_TIMEOUT 0x04 #define SF_CORE_ELS_TIMEOUT 0x08 #define SF_CORE_ELS_FAILED 0x10 #define SF_CORE_LILP_FAILED 0x20 #define SF_CORE_OFFLINE_TIMEOUT 0x40 #define SF_CORE_LIP_FAILED 0x80 #define SF_CORE_OFFLINE_TARGET 0x100 #define SF_CORE_INCOMPLETE_DMA 0x200 #define SF_CORE_REPORTLUN_TIMEOUT 0x400 #define SF_CORE_INQUIRY_TIMEOUT 0x800 #define SF_CORE_BAD_DMA 0x1000 #define SF_BAD_DMA_MAGIC 0xdeafbead #define TRUE 1 #define FALSE 0 #define UNDEFINED -1 /* * The initiator must allocate a minimum of 16 bytes for the response * to the REPORT_LUNS command. Since there is 8 bytes of overhead and * each LUN is 4 bytes, this means that the minimum size is 2 LUNs. We * will define the structure that way to prevent any spurious check * conditions. * * There is no maximum size for the response. * * By default we support 256 LUNs for the moment, which means 256*8+16 * or 2064 bytes total size. */ #define REPORT_LUNS_MIN_LUNS 2 #define REPORT_LUNS_DEFAULT 256 #define REPORT_LUNS_SIZE ((REPORT_LUNS_DEFAULT)*sizeof (uint32_t) \ +2*sizeof (uint32_t)) /* * SCSI Report_Luns Data * * Format of data returned as a result of an REPORT_LUNS command. * */ struct scsi_report_luns { /* Number of bytes of data the target has available to send. */ uint32_t lun_list_len; uint32_t reserved; uint64_t lun[REPORT_LUNS_MIN_LUNS]; }; #endif /* _KERNEL */ #ifdef __cplusplus } #endif #endif /* _SYS_SCSI_ADAPTERS_SFVAR_H */