1157114Sscottl/*- 2157114Sscottl * Copyright (c) 2006 IronPort Systems 3157114Sscottl * All rights reserved. 4157114Sscottl * 5157114Sscottl * Redistribution and use in source and binary forms, with or without 6157114Sscottl * modification, are permitted provided that the following conditions 7157114Sscottl * are met: 8157114Sscottl * 1. Redistributions of source code must retain the above copyright 9157114Sscottl * notice, this list of conditions and the following disclaimer. 10157114Sscottl * 2. Redistributions in binary form must reproduce the above copyright 11157114Sscottl * notice, this list of conditions and the following disclaimer in the 12157114Sscottl * documentation and/or other materials provided with the distribution. 13157114Sscottl * 14157114Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15157114Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16157114Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17157114Sscottl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18157114Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19157114Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20157114Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21157114Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22157114Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23157114Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24157114Sscottl * SUCH DAMAGE. 25157114Sscottl */ 26171980Sscottl/*- 27171980Sscottl * Copyright (c) 2007 LSI Corp. 28171980Sscottl * Copyright (c) 2007 Rajesh Prabhakaran. 29171980Sscottl * All rights reserved. 30171980Sscottl * 31171980Sscottl * Redistribution and use in source and binary forms, with or without 32171980Sscottl * modification, are permitted provided that the following conditions 33171980Sscottl * are met: 34171980Sscottl * 1. Redistributions of source code must retain the above copyright 35171980Sscottl * notice, this list of conditions and the following disclaimer. 36171980Sscottl * 2. Redistributions in binary form must reproduce the above copyright 37171980Sscottl * notice, this list of conditions and the following disclaimer in the 38171980Sscottl * documentation and/or other materials provided with the distribution. 39171980Sscottl * 40171980Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 41171980Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42171980Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43171980Sscottl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44171980Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45171980Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46171980Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47171980Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48171980Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49171980Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50171980Sscottl * SUCH DAMAGE. 51171980Sscottl */ 52157114Sscottl 53157114Sscottl#ifndef _MFIVAR_H 54157114Sscottl#define _MFIVAR_H 55157114Sscottl 56157114Sscottl#include <sys/cdefs.h> 57157114Sscottl__FBSDID("$FreeBSD$"); 58157114Sscottl 59171821Sjhb#include <sys/lock.h> 60171821Sjhb#include <sys/sx.h> 61171821Sjhb 62234429Sambrisko#include <sys/types.h> 63234429Sambrisko#include <sys/taskqueue.h> 64240867Ssbruno#include "opt_mfi.h" 65234429Sambrisko 66157114Sscottl/* 67157114Sscottl * SCSI structures and definitions are used from here, but no linking 68157114Sscottl * requirements are made to CAM. 69157114Sscottl */ 70157114Sscottl#include <cam/scsi/scsi_all.h> 71157114Sscottl 72157114Sscottlstruct mfi_hwcomms { 73157114Sscottl uint32_t hw_pi; 74157114Sscottl uint32_t hw_ci; 75157114Sscottl uint32_t hw_reply_q[1]; 76157114Sscottl}; 77234429Sambrisko#define MEGASAS_MAX_NAME 32 78234429Sambrisko#define MEGASAS_VERSION "4.23" 79157114Sscottl 80157114Sscottlstruct mfi_softc; 81169451Sscottlstruct disk; 82169611Sscottlstruct ccb_hdr; 83157114Sscottl 84157114Sscottlstruct mfi_command { 85157114Sscottl TAILQ_ENTRY(mfi_command) cm_link; 86162619Sscottl time_t cm_timestamp; 87157114Sscottl struct mfi_softc *cm_sc; 88157114Sscottl union mfi_frame *cm_frame; 89234429Sambrisko bus_addr_t cm_frame_busaddr; 90157114Sscottl struct mfi_sense *cm_sense; 91234429Sambrisko bus_addr_t cm_sense_busaddr; 92157114Sscottl bus_dmamap_t cm_dmamap; 93157114Sscottl union mfi_sgl *cm_sg; 94157114Sscottl void *cm_data; 95157114Sscottl int cm_len; 96225918Smav int cm_stp_len; 97157114Sscottl int cm_total_frame_size; 98157114Sscottl int cm_extra_frames; 99157114Sscottl int cm_flags; 100157114Sscottl#define MFI_CMD_MAPPED (1<<0) 101157114Sscottl#define MFI_CMD_DATAIN (1<<1) 102157114Sscottl#define MFI_CMD_DATAOUT (1<<2) 103157114Sscottl#define MFI_CMD_COMPLETED (1<<3) 104157114Sscottl#define MFI_CMD_POLLED (1<<4) 105250496Ssmh#define MFI_CMD_SCSI (1<<5) 106250496Ssmh#define MFI_CMD_CCB (1<<6) 107250496Ssmh#define MFI_CMD_TBOLT (1<<7) 108250496Ssmh#define MFI_ON_MFIQ_FREE (1<<8) 109252038Sjkim#define MFI_ON_MFIQ_READY (1<<9) 110252038Sjkim#define MFI_ON_MFIQ_BUSY (1<<10) 111250496Ssmh#define MFI_ON_MFIQ_MASK (MFI_ON_MFIQ_FREE | MFI_ON_MFIQ_READY| \ 112250496Ssmh MFI_ON_MFIQ_BUSY) 113250496Ssmh#define MFI_CMD_FLAGS_FMT "\20" \ 114250496Ssmh "\1MAPPED" \ 115250496Ssmh "\2DATAIN" \ 116250496Ssmh "\3DATAOUT" \ 117250496Ssmh "\4COMPLETED" \ 118250496Ssmh "\5POLLED" \ 119250496Ssmh "\6SCSI" \ 120250496Ssmh "\7TBOLT" \ 121250496Ssmh "\10Q_FREE" \ 122250496Ssmh "\11Q_READY" \ 123250496Ssmh "\12Q_BUSY" 124234429Sambrisko uint8_t retry_for_fw_reset; 125157114Sscottl void (* cm_complete)(struct mfi_command *cm); 126157114Sscottl void *cm_private; 127162619Sscottl int cm_index; 128170284Sambrisko int cm_error; 129157114Sscottl}; 130157114Sscottl 131169451Sscottlstruct mfi_disk { 132169451Sscottl TAILQ_ENTRY(mfi_disk) ld_link; 133169451Sscottl device_t ld_dev; 134169451Sscottl int ld_id; 135169451Sscottl int ld_unit; 136169451Sscottl struct mfi_softc *ld_controller; 137159811Sps struct mfi_ld_info *ld_info; 138169451Sscottl struct disk *ld_disk; 139169451Sscottl int ld_flags; 140169451Sscottl#define MFI_DISK_FLAGS_OPEN 0x01 141171821Sjhb#define MFI_DISK_FLAGS_DISABLED 0x02 142157114Sscottl}; 143157114Sscottl 144243824Sdelphijstruct mfi_disk_pending { 145243824Sdelphij TAILQ_ENTRY(mfi_disk_pending) ld_link; 146243824Sdelphij int ld_id; 147243824Sdelphij}; 148243824Sdelphij 149234429Sambriskostruct mfi_system_pd { 150234429Sambrisko TAILQ_ENTRY(mfi_system_pd) pd_link; 151234429Sambrisko device_t pd_dev; 152234429Sambrisko int pd_id; 153234429Sambrisko int pd_unit; 154234429Sambrisko struct mfi_softc *pd_controller; 155234429Sambrisko struct mfi_pd_info *pd_info; 156234429Sambrisko struct disk *pd_disk; 157234429Sambrisko int pd_flags; 158234429Sambrisko}; 159234429Sambrisko 160243824Sdelphijstruct mfi_system_pending { 161243824Sdelphij TAILQ_ENTRY(mfi_system_pending) pd_link; 162243824Sdelphij int pd_id; 163243824Sdelphij}; 164243824Sdelphij 165234429Sambriskostruct mfi_evt_queue_elm { 166234429Sambrisko TAILQ_ENTRY(mfi_evt_queue_elm) link; 167234429Sambrisko struct mfi_evt_detail detail; 168234429Sambrisko}; 169234429Sambrisko 170158737Sambriskostruct mfi_aen { 171158737Sambrisko TAILQ_ENTRY(mfi_aen) aen_link; 172158737Sambrisko struct proc *p; 173158737Sambrisko}; 174158737Sambrisko 175234429Sambriskostruct mfi_skinny_dma_info { 176234429Sambrisko bus_dma_tag_t dmat[514]; 177234429Sambrisko bus_dmamap_t dmamap[514]; 178234429Sambrisko uint32_t mem[514]; 179234429Sambrisko int noofmaps; 180234429Sambrisko}; 181234429Sambrisko 182234429Sambriskostruct megasas_sge 183234429Sambrisko{ 184234429Sambrisko bus_addr_t phys_addr; 185234429Sambrisko uint32_t length; 186234429Sambrisko}; 187234429Sambrisko 188234429Sambriskostruct mfi_cmd_tbolt; 189234429Sambrisko 190157114Sscottlstruct mfi_softc { 191157114Sscottl device_t mfi_dev; 192157114Sscottl int mfi_flags; 193157114Sscottl#define MFI_FLAGS_SG64 (1<<0) 194157114Sscottl#define MFI_FLAGS_QFRZN (1<<1) 195157114Sscottl#define MFI_FLAGS_OPEN (1<<2) 196163398Sscottl#define MFI_FLAGS_STOP (1<<3) 197171980Sscottl#define MFI_FLAGS_1064R (1<<4) 198171980Sscottl#define MFI_FLAGS_1078 (1<<5) 199184897Sambrisko#define MFI_FLAGS_GEN2 (1<<6) 200234429Sambrisko#define MFI_FLAGS_SKINNY (1<<7) 201234429Sambrisko#define MFI_FLAGS_TBOLT (1<<8) 202262968Smarkj#define MFI_FLAGS_INVADER (1<<10) 203262968Smarkj#define MFI_FLAGS_FURY (1<<11) 204234429Sambrisko // Start: LSIP200113393 205234429Sambrisko bus_dma_tag_t verbuf_h_dmat; 206234429Sambrisko bus_dmamap_t verbuf_h_dmamap; 207235525Ssbruno bus_addr_t verbuf_h_busaddr; 208234429Sambrisko uint32_t *verbuf; 209234429Sambrisko void *kbuff_arr[MAX_IOCTL_SGE]; 210234429Sambrisko bus_dma_tag_t mfi_kbuff_arr_dmat[2]; 211234429Sambrisko bus_dmamap_t mfi_kbuff_arr_dmamap[2]; 212234429Sambrisko bus_addr_t mfi_kbuff_arr_busaddr[2]; 213157114Sscottl 214157114Sscottl struct mfi_hwcomms *mfi_comms; 215157114Sscottl TAILQ_HEAD(,mfi_command) mfi_free; 216157114Sscottl TAILQ_HEAD(,mfi_command) mfi_ready; 217234429Sambrisko TAILQ_HEAD(BUSYQ,mfi_command) mfi_busy; 218157114Sscottl struct bio_queue_head mfi_bioq; 219157114Sscottl struct mfi_qstat mfi_qstat[MFIQ_COUNT]; 220157114Sscottl 221157114Sscottl struct resource *mfi_regs_resource; 222157114Sscottl bus_space_handle_t mfi_bhandle; 223157114Sscottl bus_space_tag_t mfi_btag; 224157114Sscottl int mfi_regs_rid; 225157114Sscottl 226157114Sscottl bus_dma_tag_t mfi_parent_dmat; 227157114Sscottl bus_dma_tag_t mfi_buffer_dmat; 228157114Sscottl 229157114Sscottl bus_dma_tag_t mfi_comms_dmat; 230157114Sscottl bus_dmamap_t mfi_comms_dmamap; 231234429Sambrisko bus_addr_t mfi_comms_busaddr; 232157114Sscottl 233157114Sscottl bus_dma_tag_t mfi_frames_dmat; 234157114Sscottl bus_dmamap_t mfi_frames_dmamap; 235234429Sambrisko bus_addr_t mfi_frames_busaddr; 236157114Sscottl union mfi_frame *mfi_frames; 237157114Sscottl 238234429Sambrisko bus_dma_tag_t mfi_tb_init_dmat; 239234429Sambrisko bus_dmamap_t mfi_tb_init_dmamap; 240234429Sambrisko bus_addr_t mfi_tb_init_busaddr; 241234429Sambrisko bus_addr_t mfi_tb_ioc_init_busaddr; 242234429Sambrisko union mfi_frame *mfi_tb_init; 243234429Sambrisko 244234429Sambrisko TAILQ_HEAD(,mfi_evt_queue_elm) mfi_evt_queue; 245234429Sambrisko struct task mfi_evt_task; 246235135Sambrisko struct task mfi_map_sync_task; 247158737Sambrisko TAILQ_HEAD(,mfi_aen) mfi_aen_pids; 248158737Sambrisko struct mfi_command *mfi_aen_cm; 249234429Sambrisko struct mfi_command *mfi_skinny_cm; 250235135Sambrisko struct mfi_command *mfi_map_sync_cm; 251235135Sambrisko int cm_aen_abort; 252235135Sambrisko int cm_map_abort; 253158737Sambrisko uint32_t mfi_aen_triggered; 254158737Sambrisko uint32_t mfi_poll_waiting; 255234429Sambrisko uint32_t mfi_boot_seq_num; 256158737Sambrisko struct selinfo mfi_select; 257171821Sjhb int mfi_delete_busy_volumes; 258171821Sjhb int mfi_keep_deleted_volumes; 259171821Sjhb int mfi_detaching; 260158737Sambrisko 261157114Sscottl bus_dma_tag_t mfi_sense_dmat; 262157114Sscottl bus_dmamap_t mfi_sense_dmamap; 263235525Ssbruno bus_addr_t mfi_sense_busaddr; 264157114Sscottl struct mfi_sense *mfi_sense; 265157114Sscottl 266157114Sscottl struct resource *mfi_irq; 267157114Sscottl void *mfi_intr; 268157114Sscottl int mfi_irq_rid; 269157114Sscottl 270157114Sscottl struct intr_config_hook mfi_ich; 271157114Sscottl eventhandler_tag eh; 272234429Sambrisko /* OCR flags */ 273234429Sambrisko uint8_t adpreset; 274234429Sambrisko uint8_t issuepend_done; 275234429Sambrisko uint8_t disableOnlineCtrlReset; 276234429Sambrisko uint32_t mfiStatus; 277234429Sambrisko uint32_t last_seq_num; 278234429Sambrisko uint32_t volatile hw_crit_error; 279157114Sscottl 280157114Sscottl /* 281157114Sscottl * Allocation for the command array. Used as an indexable array to 282157114Sscottl * recover completed commands. 283157114Sscottl */ 284157114Sscottl struct mfi_command *mfi_commands; 285157114Sscottl /* 286157114Sscottl * How many commands the firmware can handle. Also how big the reply 287157114Sscottl * queue is, minus 1. 288157114Sscottl */ 289157114Sscottl int mfi_max_fw_cmds; 290157114Sscottl /* 291234429Sambrisko * How many S/G elements we'll ever actually use 292157114Sscottl */ 293162458Sscottl int mfi_max_sge; 294157114Sscottl /* 295157114Sscottl * How many bytes a compound frame is, including all of the extra frames 296157114Sscottl * that are used for S/G elements. 297157114Sscottl */ 298162458Sscottl int mfi_cmd_size; 299157114Sscottl /* 300157114Sscottl * How large an S/G element is. Used to calculate the number of single 301157114Sscottl * frames in a command. 302157114Sscottl */ 303162458Sscottl int mfi_sge_size; 304157114Sscottl /* 305157114Sscottl * Max number of sectors that the firmware allows 306157114Sscottl */ 307157114Sscottl uint32_t mfi_max_io; 308157114Sscottl 309169451Sscottl TAILQ_HEAD(,mfi_disk) mfi_ld_tqh; 310234429Sambrisko TAILQ_HEAD(,mfi_system_pd) mfi_syspd_tqh; 311243824Sdelphij TAILQ_HEAD(,mfi_disk_pending) mfi_ld_pend_tqh; 312243824Sdelphij TAILQ_HEAD(,mfi_system_pending) mfi_syspd_pend_tqh; 313157114Sscottl eventhandler_tag mfi_eh; 314157114Sscottl struct cdev *mfi_cdev; 315157114Sscottl 316169611Sscottl TAILQ_HEAD(, ccb_hdr) mfi_cam_ccbq; 317169611Sscottl struct mfi_command * (* mfi_cam_start)(void *); 318252643Smarkj void (*mfi_cam_rescan_cb)(struct mfi_softc *, 319252643Smarkj uint32_t); 320162619Sscottl struct callout mfi_watchdog_callout; 321157114Sscottl struct mtx mfi_io_lock; 322171821Sjhb struct sx mfi_config_lock; 323171980Sscottl 324171980Sscottl /* Controller type specific interfaces */ 325171980Sscottl void (*mfi_enable_intr)(struct mfi_softc *sc); 326234429Sambrisko void (*mfi_disable_intr)(struct mfi_softc *sc); 327171980Sscottl int32_t (*mfi_read_fw_status)(struct mfi_softc *sc); 328171980Sscottl int (*mfi_check_clear_intr)(struct mfi_softc *sc); 329234429Sambrisko void (*mfi_issue_cmd)(struct mfi_softc *sc, bus_addr_t bus_add, 330234429Sambrisko uint32_t frame_cnt); 331234429Sambrisko int (*mfi_adp_reset)(struct mfi_softc *sc); 332234429Sambrisko int (*mfi_adp_check_reset)(struct mfi_softc *sc); 333243824Sdelphij void (*mfi_intr_ptr)(void *sc); 334234429Sambrisko 335234429Sambrisko /* ThunderBolt */ 336234429Sambrisko uint32_t mfi_tbolt; 337234429Sambrisko uint32_t MFA_enabled; 338234429Sambrisko /* Single Reply structure size */ 339234429Sambrisko uint16_t reply_size; 340234429Sambrisko /* Singler message size. */ 341234429Sambrisko uint16_t raid_io_msg_size; 342234429Sambrisko TAILQ_HEAD(TB, mfi_cmd_tbolt) mfi_cmd_tbolt_tqh; 343234429Sambrisko /* ThunderBolt base contiguous memory mapping. */ 344234429Sambrisko bus_dma_tag_t mfi_tb_dmat; 345234429Sambrisko bus_dmamap_t mfi_tb_dmamap; 346234429Sambrisko bus_addr_t mfi_tb_busaddr; 347234429Sambrisko /* ThunderBolt Contiguous DMA memory Mapping */ 348234429Sambrisko uint8_t * request_message_pool; 349234429Sambrisko uint8_t * request_message_pool_align; 350234429Sambrisko uint8_t * request_desc_pool; 351234429Sambrisko bus_addr_t request_msg_busaddr; 352234429Sambrisko bus_addr_t reply_frame_busaddr; 353234429Sambrisko bus_addr_t sg_frame_busaddr; 354234429Sambrisko /* ThunderBolt IOC Init Descriptor */ 355234429Sambrisko bus_dma_tag_t mfi_tb_ioc_init_dmat; 356234429Sambrisko bus_dmamap_t mfi_tb_ioc_init_dmamap; 357234429Sambrisko uint8_t * mfi_tb_ioc_init_desc; 358234429Sambrisko struct mfi_cmd_tbolt **mfi_cmd_pool_tbolt; 359234429Sambrisko /* Virtual address of reply Frame Pool */ 360234429Sambrisko struct mfi_mpi2_reply_header* reply_frame_pool; 361234429Sambrisko struct mfi_mpi2_reply_header* reply_frame_pool_align; 362234429Sambrisko 363234429Sambrisko /* Last reply frame address */ 364234429Sambrisko uint8_t * reply_pool_limit; 365234429Sambrisko uint16_t last_reply_idx; 366234429Sambrisko uint8_t max_SGEs_in_chain_message; 367234429Sambrisko uint8_t max_SGEs_in_main_message; 368234429Sambrisko uint8_t chain_offset_value_for_main_message; 369234429Sambrisko uint8_t chain_offset_value_for_mpt_ptmsg; 370157114Sscottl}; 371157114Sscottl 372234429Sambriskounion desc_value { 373234429Sambrisko uint64_t word; 374234429Sambrisko struct { 375234429Sambrisko uint32_t low; 376234429Sambrisko uint32_t high; 377234429Sambrisko }u; 378234429Sambrisko}; 379234429Sambrisko 380234429Sambrisko// TODO find the right definition 381234429Sambrisko#define XXX_MFI_CMD_OP_INIT2 0x9 382234429Sambrisko/* 383234429Sambrisko * Request descriptor types 384234429Sambrisko */ 385234429Sambrisko#define MFI_REQ_DESCRIPT_FLAGS_LD_IO 0x7 386234429Sambrisko#define MFI_REQ_DESCRIPT_FLAGS_MFA 0x1 387234429Sambrisko#define MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT 0x1 388234429Sambrisko#define MFI_FUSION_FP_DEFAULT_TIMEOUT 0x14 389234429Sambrisko#define MFI_LOAD_BALANCE_FLAG 0x1 390234429Sambrisko#define MFI_DCMD_MBOX_PEND_FLAG 0x1 391234429Sambrisko 392234429Sambrisko//#define MR_PROT_INFO_TYPE_CONTROLLER 0x08 393234429Sambrisko#define MEGASAS_SCSI_VARIABLE_LENGTH_CMD 0x7f 394234429Sambrisko#define MEGASAS_SCSI_SERVICE_ACTION_READ32 0x9 395234429Sambrisko#define MEGASAS_SCSI_SERVICE_ACTION_WRITE32 0xB 396234429Sambrisko#define MEGASAS_SCSI_ADDL_CDB_LEN 0x18 397234429Sambrisko#define MEGASAS_RD_WR_PROTECT_CHECK_ALL 0x20 398234429Sambrisko#define MEGASAS_RD_WR_PROTECT_CHECK_NONE 0x60 399234429Sambrisko#define MEGASAS_EEDPBLOCKSIZE 512 400234429Sambriskostruct mfi_cmd_tbolt { 401234429Sambrisko union mfi_mpi2_request_descriptor *request_desc; 402234429Sambrisko struct mfi_mpi2_request_raid_scsi_io *io_request; 403234429Sambrisko bus_addr_t io_request_phys_addr; 404234429Sambrisko bus_addr_t sg_frame_phys_addr; 405234429Sambrisko bus_addr_t sense_phys_addr; 406234429Sambrisko MPI2_SGE_IO_UNION *sg_frame; 407234429Sambrisko uint8_t *sense; 408234429Sambrisko TAILQ_ENTRY(mfi_cmd_tbolt) next; 409234429Sambrisko /* 410234429Sambrisko * Context for a MFI frame. 411234429Sambrisko * Used to get the mfi cmd from list when a MFI cmd is completed 412234429Sambrisko */ 413234429Sambrisko uint32_t sync_cmd_idx; 414234429Sambrisko uint16_t index; 415234429Sambrisko uint8_t status; 416234429Sambrisko}; 417234429Sambrisko 418157114Sscottlextern int mfi_attach(struct mfi_softc *); 419157114Sscottlextern void mfi_free(struct mfi_softc *); 420157114Sscottlextern int mfi_shutdown(struct mfi_softc *); 421157114Sscottlextern void mfi_startio(struct mfi_softc *); 422157114Sscottlextern void mfi_disk_complete(struct bio *); 423171821Sjhbextern int mfi_disk_disable(struct mfi_disk *); 424171821Sjhbextern void mfi_disk_enable(struct mfi_disk *); 425157114Sscottlextern int mfi_dump_blocks(struct mfi_softc *, int id, uint64_t, void *, int); 426234429Sambriskoextern int mfi_syspd_disable(struct mfi_system_pd *); 427234429Sambriskoextern void mfi_syspd_enable(struct mfi_system_pd *); 428234429Sambriskoextern int mfi_dump_syspd_blocks(struct mfi_softc *, int id, uint64_t, void *, 429234429Sambrisko int); 430234429Sambriskoextern int mfi_transition_firmware(struct mfi_softc *sc); 431234429Sambriskoextern int mfi_aen_setup(struct mfi_softc *sc, uint32_t seq_start); 432234429Sambriskoextern void mfi_complete(struct mfi_softc *sc, struct mfi_command *cm); 433234429Sambriskoextern int mfi_mapcmd(struct mfi_softc *sc,struct mfi_command *cm); 434234429Sambriskoextern int mfi_wait_command(struct mfi_softc *sc, struct mfi_command *cm); 435234429Sambriskoextern void mfi_tbolt_enable_intr_ppc(struct mfi_softc *); 436234429Sambriskoextern void mfi_tbolt_disable_intr_ppc(struct mfi_softc *); 437234429Sambriskoextern int32_t mfi_tbolt_read_fw_status_ppc(struct mfi_softc *); 438234429Sambriskoextern int32_t mfi_tbolt_check_clear_intr_ppc(struct mfi_softc *); 439234429Sambriskoextern void mfi_tbolt_issue_cmd_ppc(struct mfi_softc *, bus_addr_t, uint32_t); 440234429Sambriskoextern void mfi_tbolt_init_globals(struct mfi_softc*); 441234429Sambriskoextern uint32_t mfi_tbolt_get_memory_requirement(struct mfi_softc *); 442234429Sambriskoextern int mfi_tbolt_init_desc_pool(struct mfi_softc *, uint8_t *, uint32_t); 443234429Sambriskoextern int mfi_tbolt_init_MFI_queue(struct mfi_softc *); 444234429Sambriskoextern void mfi_intr_tbolt(void *arg); 445234429Sambriskoextern int mfi_tbolt_alloc_cmd(struct mfi_softc *sc); 446234429Sambriskoextern int mfi_tbolt_send_frame(struct mfi_softc *sc, struct mfi_command *cm); 447234429Sambriskoextern int mfi_tbolt_adp_reset(struct mfi_softc *sc); 448234429Sambriskoextern int mfi_tbolt_reset(struct mfi_softc *sc); 449235135Sambriskoextern void mfi_tbolt_sync_map_info(struct mfi_softc *sc); 450235135Sambriskoextern void mfi_handle_map_sync(void *context, int pending); 451235135Sambriskoextern int mfi_dcmd_command(struct mfi_softc *, struct mfi_command **, 452243824Sdelphij uint32_t, void **, size_t); 453243824Sdelphijextern int mfi_build_cdb(int, uint8_t, u_int64_t, u_int32_t, uint8_t *); 454157114Sscottl 455157114Sscottl#define MFIQ_ADD(sc, qname) \ 456157114Sscottl do { \ 457157114Sscottl struct mfi_qstat *qs; \ 458157114Sscottl \ 459157114Sscottl qs = &(sc)->mfi_qstat[qname]; \ 460157114Sscottl qs->q_length++; \ 461157114Sscottl if (qs->q_length > qs->q_max) \ 462157114Sscottl qs->q_max = qs->q_length; \ 463157114Sscottl } while (0) 464157114Sscottl 465157114Sscottl#define MFIQ_REMOVE(sc, qname) (sc)->mfi_qstat[qname].q_length-- 466157114Sscottl 467157114Sscottl#define MFIQ_INIT(sc, qname) \ 468157114Sscottl do { \ 469157114Sscottl sc->mfi_qstat[qname].q_length = 0; \ 470157114Sscottl sc->mfi_qstat[qname].q_max = 0; \ 471157114Sscottl } while (0) 472157114Sscottl 473157114Sscottl#define MFIQ_COMMAND_QUEUE(name, index) \ 474157114Sscottl static __inline void \ 475157114Sscottl mfi_initq_ ## name (struct mfi_softc *sc) \ 476157114Sscottl { \ 477157114Sscottl TAILQ_INIT(&sc->mfi_ ## name); \ 478157114Sscottl MFIQ_INIT(sc, index); \ 479157114Sscottl } \ 480157114Sscottl static __inline void \ 481157114Sscottl mfi_enqueue_ ## name (struct mfi_command *cm) \ 482157114Sscottl { \ 483157114Sscottl if ((cm->cm_flags & MFI_ON_MFIQ_MASK) != 0) { \ 484250496Ssmh panic("command %p is on another queue, " \ 485157114Sscottl "flags = %#x\n", cm, cm->cm_flags); \ 486157114Sscottl } \ 487157114Sscottl TAILQ_INSERT_TAIL(&cm->cm_sc->mfi_ ## name, cm, cm_link); \ 488157114Sscottl cm->cm_flags |= MFI_ON_ ## index; \ 489157114Sscottl MFIQ_ADD(cm->cm_sc, index); \ 490157114Sscottl } \ 491157114Sscottl static __inline void \ 492157114Sscottl mfi_requeue_ ## name (struct mfi_command *cm) \ 493157114Sscottl { \ 494157114Sscottl if ((cm->cm_flags & MFI_ON_MFIQ_MASK) != 0) { \ 495250496Ssmh panic("command %p is on another queue, " \ 496157114Sscottl "flags = %#x\n", cm, cm->cm_flags); \ 497157114Sscottl } \ 498157114Sscottl TAILQ_INSERT_HEAD(&cm->cm_sc->mfi_ ## name, cm, cm_link); \ 499157114Sscottl cm->cm_flags |= MFI_ON_ ## index; \ 500157114Sscottl MFIQ_ADD(cm->cm_sc, index); \ 501157114Sscottl } \ 502157114Sscottl static __inline struct mfi_command * \ 503157114Sscottl mfi_dequeue_ ## name (struct mfi_softc *sc) \ 504157114Sscottl { \ 505157114Sscottl struct mfi_command *cm; \ 506157114Sscottl \ 507157114Sscottl if ((cm = TAILQ_FIRST(&sc->mfi_ ## name)) != NULL) { \ 508157114Sscottl if ((cm->cm_flags & MFI_ON_ ## index) == 0) { \ 509250496Ssmh panic("command %p not in queue, " \ 510157114Sscottl "flags = %#x, bit = %#x\n", cm, \ 511157114Sscottl cm->cm_flags, MFI_ON_ ## index); \ 512157114Sscottl } \ 513157114Sscottl TAILQ_REMOVE(&sc->mfi_ ## name, cm, cm_link); \ 514157114Sscottl cm->cm_flags &= ~MFI_ON_ ## index; \ 515157114Sscottl MFIQ_REMOVE(sc, index); \ 516157114Sscottl } \ 517157114Sscottl return (cm); \ 518157114Sscottl } \ 519157114Sscottl static __inline void \ 520157114Sscottl mfi_remove_ ## name (struct mfi_command *cm) \ 521157114Sscottl { \ 522157114Sscottl if ((cm->cm_flags & MFI_ON_ ## index) == 0) { \ 523250496Ssmh panic("command %p not in queue, flags = %#x, " \ 524157114Sscottl "bit = %#x\n", cm, cm->cm_flags, \ 525157114Sscottl MFI_ON_ ## index); \ 526157114Sscottl } \ 527157114Sscottl TAILQ_REMOVE(&cm->cm_sc->mfi_ ## name, cm, cm_link); \ 528157114Sscottl cm->cm_flags &= ~MFI_ON_ ## index; \ 529157114Sscottl MFIQ_REMOVE(cm->cm_sc, index); \ 530157114Sscottl } \ 531157114Sscottlstruct hack 532157114Sscottl 533157114SscottlMFIQ_COMMAND_QUEUE(free, MFIQ_FREE); 534157114SscottlMFIQ_COMMAND_QUEUE(ready, MFIQ_READY); 535157114SscottlMFIQ_COMMAND_QUEUE(busy, MFIQ_BUSY); 536157114Sscottl 537157114Sscottlstatic __inline void 538157114Sscottlmfi_initq_bio(struct mfi_softc *sc) 539157114Sscottl{ 540157114Sscottl bioq_init(&sc->mfi_bioq); 541157114Sscottl MFIQ_INIT(sc, MFIQ_BIO); 542157114Sscottl} 543157114Sscottl 544157114Sscottlstatic __inline void 545157114Sscottlmfi_enqueue_bio(struct mfi_softc *sc, struct bio *bp) 546157114Sscottl{ 547157114Sscottl bioq_insert_tail(&sc->mfi_bioq, bp); 548157114Sscottl MFIQ_ADD(sc, MFIQ_BIO); 549157114Sscottl} 550157114Sscottl 551157114Sscottlstatic __inline struct bio * 552157114Sscottlmfi_dequeue_bio(struct mfi_softc *sc) 553157114Sscottl{ 554157114Sscottl struct bio *bp; 555157114Sscottl 556157114Sscottl if ((bp = bioq_first(&sc->mfi_bioq)) != NULL) { 557157114Sscottl bioq_remove(&sc->mfi_bioq, bp); 558157114Sscottl MFIQ_REMOVE(sc, MFIQ_BIO); 559157114Sscottl } 560157114Sscottl return (bp); 561157114Sscottl} 562157114Sscottl 563227117Skib/* 564227117Skib * This is from the original scsi_extract_sense() in CAM. It's copied 565227117Skib * here because CAM now uses a non-inline version that follows more complex 566227117Skib * additions to the SPC spec, and we don't want to force a dependency on 567227117Skib * the CAM module for such a trivial action. 568227117Skib */ 569157114Sscottlstatic __inline void 570227117Skibmfi_extract_sense(struct scsi_sense_data_fixed *sense, 571227117Skib int *error_code, int *sense_key, int *asc, int *ascq) 572227117Skib{ 573227117Skib 574227117Skib *error_code = sense->error_code & SSD_ERRCODE; 575227117Skib *sense_key = sense->flags & SSD_KEY; 576227117Skib *asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0; 577227117Skib *ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0; 578227117Skib} 579227117Skib 580227117Skibstatic __inline void 581157114Sscottlmfi_print_sense(struct mfi_softc *sc, void *sense) 582157114Sscottl{ 583157114Sscottl int error, key, asc, ascq; 584157114Sscottl 585227117Skib mfi_extract_sense((struct scsi_sense_data_fixed *)sense, 586157114Sscottl &error, &key, &asc, &ascq); 587157114Sscottl device_printf(sc->mfi_dev, "sense error %d, sense_key %d, " 588157114Sscottl "asc %d, ascq %d\n", error, key, asc, ascq); 589157114Sscottl} 590157114Sscottl 591157114Sscottl 592157114Sscottl#define MFI_WRITE4(sc, reg, val) bus_space_write_4((sc)->mfi_btag, \ 593157114Sscottl sc->mfi_bhandle, (reg), (val)) 594157114Sscottl#define MFI_READ4(sc, reg) bus_space_read_4((sc)->mfi_btag, \ 595157114Sscottl (sc)->mfi_bhandle, (reg)) 596157114Sscottl#define MFI_WRITE2(sc, reg, val) bus_space_write_2((sc)->mfi_btag, \ 597157114Sscottl sc->mfi_bhandle, (reg), (val)) 598157114Sscottl#define MFI_READ2(sc, reg) bus_space_read_2((sc)->mfi_btag, \ 599157114Sscottl (sc)->mfi_bhandle, (reg)) 600157114Sscottl#define MFI_WRITE1(sc, reg, val) bus_space_write_1((sc)->mfi_btag, \ 601157114Sscottl sc->mfi_bhandle, (reg), (val)) 602157114Sscottl#define MFI_READ1(sc, reg) bus_space_read_1((sc)->mfi_btag, \ 603157114Sscottl (sc)->mfi_bhandle, (reg)) 604157114Sscottl 605157114SscottlMALLOC_DECLARE(M_MFIBUF); 606229611SjhbSYSCTL_DECL(_hw_mfi); 607157114Sscottl 608234429Sambrisko#define MFI_RESET_WAIT_TIME 180 609162619Sscottl#define MFI_CMD_TIMEOUT 30 610234429Sambrisko#define MFI_SYS_PD_IO 0 611234429Sambrisko#define MFI_LD_IO 1 612234429Sambrisko#define MFI_SKINNY_MEMORY 0x02000000 613195534Sscottl#define MFI_MAXPHYS (128 * 1024) 614162619Sscottl 615162619Sscottl#ifdef MFI_DEBUG 616162619Sscottlextern void mfi_print_cmd(struct mfi_command *cm); 617162619Sscottlextern void mfi_dump_cmds(struct mfi_softc *sc); 618250496Ssmhextern void mfi_validate_sg(struct mfi_softc *, struct mfi_command *, 619250496Ssmh const char *, int); 620162619Sscottl#define MFI_PRINT_CMD(cm) mfi_print_cmd(cm) 621163398Sscottl#define MFI_DUMP_CMDS(sc) mfi_dump_cmds(sc) 622163398Sscottl#define MFI_VALIDATE_CMD(sc, cm) mfi_validate_sg(sc, cm, __FUNCTION__, __LINE__) 623162619Sscottl#else 624162619Sscottl#define MFI_PRINT_CMD(cm) 625162619Sscottl#define MFI_DUMP_CMDS(sc) 626163398Sscottl#define MFI_VALIDATE_CMD(sc, cm) 627162619Sscottl#endif 628162619Sscottl 629250496Ssmhextern void mfi_release_command(struct mfi_command *); 630250496Ssmhextern void mfi_tbolt_return_cmd(struct mfi_softc *, 631250496Ssmh struct mfi_cmd_tbolt *, struct mfi_command *); 632169611Sscottl 633157114Sscottl#endif /* _MFIVAR_H */ 634