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: releng/10.3/sys/dev/mfi/mfivar.h 270732 2014-08-27 21:11:19Z markj $"); 58157114Sscottl 59171821Sjhb#include <sys/lock.h> 60171821Sjhb#include <sys/sx.h> 61171821Sjhb 62233711Sambrisko#include <sys/types.h> 63233711Sambrisko#include <sys/taskqueue.h> 64238373Ssbruno#include "opt_mfi.h" 65233711Sambrisko 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}; 77233711Sambrisko#define MEGASAS_MAX_NAME 32 78233711Sambrisko#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; 89233711Sambrisko bus_addr_t cm_frame_busaddr; 90157114Sscottl struct mfi_sense *cm_sense; 91233711Sambrisko 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; 96225869Smav 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) 105247369Ssmh#define MFI_CMD_SCSI (1<<5) 106247369Ssmh#define MFI_CMD_CCB (1<<6) 107267084Skib#define MFI_CMD_BIO (1<<7) 108267084Skib#define MFI_CMD_TBOLT (1<<8) 109267084Skib#define MFI_ON_MFIQ_FREE (1<<9) 110267084Skib#define MFI_ON_MFIQ_READY (1<<10) 111267084Skib#define MFI_ON_MFIQ_BUSY (1<<11) 112247369Ssmh#define MFI_ON_MFIQ_MASK (MFI_ON_MFIQ_FREE | MFI_ON_MFIQ_READY| \ 113247369Ssmh MFI_ON_MFIQ_BUSY) 114247369Ssmh#define MFI_CMD_FLAGS_FMT "\20" \ 115247369Ssmh "\1MAPPED" \ 116247369Ssmh "\2DATAIN" \ 117247369Ssmh "\3DATAOUT" \ 118247369Ssmh "\4COMPLETED" \ 119247369Ssmh "\5POLLED" \ 120247369Ssmh "\6SCSI" \ 121267084Skib "\7BIO" \ 122267084Skib "\10TBOLT" \ 123267084Skib "\11Q_FREE" \ 124267084Skib "\12Q_READY" \ 125267084Skib "\13Q_BUSY" 126233711Sambrisko uint8_t retry_for_fw_reset; 127157114Sscottl void (* cm_complete)(struct mfi_command *cm); 128157114Sscottl void *cm_private; 129162619Sscottl int cm_index; 130170284Sambrisko int cm_error; 131157114Sscottl}; 132157114Sscottl 133169451Sscottlstruct mfi_disk { 134169451Sscottl TAILQ_ENTRY(mfi_disk) ld_link; 135169451Sscottl device_t ld_dev; 136169451Sscottl int ld_id; 137169451Sscottl int ld_unit; 138169451Sscottl struct mfi_softc *ld_controller; 139159811Sps struct mfi_ld_info *ld_info; 140169451Sscottl struct disk *ld_disk; 141169451Sscottl int ld_flags; 142169451Sscottl#define MFI_DISK_FLAGS_OPEN 0x01 143171821Sjhb#define MFI_DISK_FLAGS_DISABLED 0x02 144157114Sscottl}; 145157114Sscottl 146242681Sambriskostruct mfi_disk_pending { 147242681Sambrisko TAILQ_ENTRY(mfi_disk_pending) ld_link; 148242681Sambrisko int ld_id; 149242681Sambrisko}; 150242681Sambrisko 151233711Sambriskostruct mfi_system_pd { 152233711Sambrisko TAILQ_ENTRY(mfi_system_pd) pd_link; 153233711Sambrisko device_t pd_dev; 154233711Sambrisko int pd_id; 155233711Sambrisko int pd_unit; 156233711Sambrisko struct mfi_softc *pd_controller; 157233711Sambrisko struct mfi_pd_info *pd_info; 158233711Sambrisko struct disk *pd_disk; 159233711Sambrisko int pd_flags; 160233711Sambrisko}; 161233711Sambrisko 162242681Sambriskostruct mfi_system_pending { 163242681Sambrisko TAILQ_ENTRY(mfi_system_pending) pd_link; 164242681Sambrisko int pd_id; 165242681Sambrisko}; 166242681Sambrisko 167233711Sambriskostruct mfi_evt_queue_elm { 168233711Sambrisko TAILQ_ENTRY(mfi_evt_queue_elm) link; 169233711Sambrisko struct mfi_evt_detail detail; 170233711Sambrisko}; 171233711Sambrisko 172158737Sambriskostruct mfi_aen { 173158737Sambrisko TAILQ_ENTRY(mfi_aen) aen_link; 174158737Sambrisko struct proc *p; 175158737Sambrisko}; 176158737Sambrisko 177233711Sambriskostruct mfi_skinny_dma_info { 178233768Sambrisko bus_dma_tag_t dmat[514]; 179233768Sambrisko bus_dmamap_t dmamap[514]; 180233768Sambrisko uint32_t mem[514]; 181233768Sambrisko int noofmaps; 182233711Sambrisko}; 183233711Sambrisko 184233805Sambriskostruct megasas_sge 185233805Sambrisko{ 186233805Sambrisko bus_addr_t phys_addr; 187233805Sambrisko uint32_t length; 188233805Sambrisko}; 189233805Sambrisko 190233711Sambriskostruct mfi_cmd_tbolt; 191233711Sambrisko 192157114Sscottlstruct mfi_softc { 193157114Sscottl device_t mfi_dev; 194157114Sscottl int mfi_flags; 195157114Sscottl#define MFI_FLAGS_SG64 (1<<0) 196157114Sscottl#define MFI_FLAGS_QFRZN (1<<1) 197157114Sscottl#define MFI_FLAGS_OPEN (1<<2) 198163398Sscottl#define MFI_FLAGS_STOP (1<<3) 199171980Sscottl#define MFI_FLAGS_1064R (1<<4) 200171980Sscottl#define MFI_FLAGS_1078 (1<<5) 201184897Sambrisko#define MFI_FLAGS_GEN2 (1<<6) 202233711Sambrisko#define MFI_FLAGS_SKINNY (1<<7) 203233711Sambrisko#define MFI_FLAGS_TBOLT (1<<8) 204270732Smarkj#define MFI_FLAGS_MRSAS (1<<9) 205262967Smarkj#define MFI_FLAGS_INVADER (1<<10) 206262967Smarkj#define MFI_FLAGS_FURY (1<<11) 207233711Sambrisko // Start: LSIP200113393 208233711Sambrisko bus_dma_tag_t verbuf_h_dmat; 209233711Sambrisko bus_dmamap_t verbuf_h_dmamap; 210235321Ssbruno bus_addr_t verbuf_h_busaddr; 211233711Sambrisko uint32_t *verbuf; 212233711Sambrisko void *kbuff_arr[MAX_IOCTL_SGE]; 213233711Sambrisko bus_dma_tag_t mfi_kbuff_arr_dmat[2]; 214233711Sambrisko bus_dmamap_t mfi_kbuff_arr_dmamap[2]; 215233711Sambrisko bus_addr_t mfi_kbuff_arr_busaddr[2]; 216157114Sscottl 217157114Sscottl struct mfi_hwcomms *mfi_comms; 218157114Sscottl TAILQ_HEAD(,mfi_command) mfi_free; 219157114Sscottl TAILQ_HEAD(,mfi_command) mfi_ready; 220233711Sambrisko TAILQ_HEAD(BUSYQ,mfi_command) mfi_busy; 221157114Sscottl struct bio_queue_head mfi_bioq; 222157114Sscottl struct mfi_qstat mfi_qstat[MFIQ_COUNT]; 223157114Sscottl 224157114Sscottl struct resource *mfi_regs_resource; 225157114Sscottl bus_space_handle_t mfi_bhandle; 226157114Sscottl bus_space_tag_t mfi_btag; 227157114Sscottl int mfi_regs_rid; 228157114Sscottl 229157114Sscottl bus_dma_tag_t mfi_parent_dmat; 230157114Sscottl bus_dma_tag_t mfi_buffer_dmat; 231157114Sscottl 232157114Sscottl bus_dma_tag_t mfi_comms_dmat; 233157114Sscottl bus_dmamap_t mfi_comms_dmamap; 234233711Sambrisko bus_addr_t mfi_comms_busaddr; 235157114Sscottl 236157114Sscottl bus_dma_tag_t mfi_frames_dmat; 237157114Sscottl bus_dmamap_t mfi_frames_dmamap; 238233711Sambrisko bus_addr_t mfi_frames_busaddr; 239157114Sscottl union mfi_frame *mfi_frames; 240157114Sscottl 241233711Sambrisko bus_dma_tag_t mfi_tb_init_dmat; 242233711Sambrisko bus_dmamap_t mfi_tb_init_dmamap; 243233711Sambrisko bus_addr_t mfi_tb_init_busaddr; 244233711Sambrisko bus_addr_t mfi_tb_ioc_init_busaddr; 245233711Sambrisko union mfi_frame *mfi_tb_init; 246233711Sambrisko 247233711Sambrisko TAILQ_HEAD(,mfi_evt_queue_elm) mfi_evt_queue; 248233711Sambrisko struct task mfi_evt_task; 249235014Sambrisko struct task mfi_map_sync_task; 250158737Sambrisko TAILQ_HEAD(,mfi_aen) mfi_aen_pids; 251158737Sambrisko struct mfi_command *mfi_aen_cm; 252233711Sambrisko struct mfi_command *mfi_skinny_cm; 253235014Sambrisko struct mfi_command *mfi_map_sync_cm; 254235014Sambrisko int cm_aen_abort; 255235014Sambrisko int cm_map_abort; 256158737Sambrisko uint32_t mfi_aen_triggered; 257158737Sambrisko uint32_t mfi_poll_waiting; 258233711Sambrisko uint32_t mfi_boot_seq_num; 259158737Sambrisko struct selinfo mfi_select; 260171821Sjhb int mfi_delete_busy_volumes; 261171821Sjhb int mfi_keep_deleted_volumes; 262171821Sjhb int mfi_detaching; 263158737Sambrisko 264157114Sscottl bus_dma_tag_t mfi_sense_dmat; 265157114Sscottl bus_dmamap_t mfi_sense_dmamap; 266235321Ssbruno bus_addr_t mfi_sense_busaddr; 267157114Sscottl struct mfi_sense *mfi_sense; 268157114Sscottl 269157114Sscottl struct resource *mfi_irq; 270157114Sscottl void *mfi_intr; 271157114Sscottl int mfi_irq_rid; 272157114Sscottl 273157114Sscottl struct intr_config_hook mfi_ich; 274157114Sscottl eventhandler_tag eh; 275233711Sambrisko /* OCR flags */ 276233711Sambrisko uint8_t adpreset; 277233711Sambrisko uint8_t issuepend_done; 278233711Sambrisko uint8_t disableOnlineCtrlReset; 279233711Sambrisko uint32_t mfiStatus; 280233711Sambrisko uint32_t last_seq_num; 281233711Sambrisko uint32_t volatile hw_crit_error; 282157114Sscottl 283157114Sscottl /* 284157114Sscottl * Allocation for the command array. Used as an indexable array to 285157114Sscottl * recover completed commands. 286157114Sscottl */ 287157114Sscottl struct mfi_command *mfi_commands; 288157114Sscottl /* 289157114Sscottl * How many commands the firmware can handle. Also how big the reply 290157114Sscottl * queue is, minus 1. 291157114Sscottl */ 292157114Sscottl int mfi_max_fw_cmds; 293157114Sscottl /* 294233711Sambrisko * How many S/G elements we'll ever actually use 295157114Sscottl */ 296162458Sscottl int mfi_max_sge; 297157114Sscottl /* 298157114Sscottl * How many bytes a compound frame is, including all of the extra frames 299157114Sscottl * that are used for S/G elements. 300157114Sscottl */ 301162458Sscottl int mfi_cmd_size; 302157114Sscottl /* 303157114Sscottl * How large an S/G element is. Used to calculate the number of single 304157114Sscottl * frames in a command. 305157114Sscottl */ 306162458Sscottl int mfi_sge_size; 307157114Sscottl /* 308157114Sscottl * Max number of sectors that the firmware allows 309157114Sscottl */ 310157114Sscottl uint32_t mfi_max_io; 311157114Sscottl 312169451Sscottl TAILQ_HEAD(,mfi_disk) mfi_ld_tqh; 313233711Sambrisko TAILQ_HEAD(,mfi_system_pd) mfi_syspd_tqh; 314242681Sambrisko TAILQ_HEAD(,mfi_disk_pending) mfi_ld_pend_tqh; 315242681Sambrisko TAILQ_HEAD(,mfi_system_pending) mfi_syspd_pend_tqh; 316157114Sscottl eventhandler_tag mfi_eh; 317157114Sscottl struct cdev *mfi_cdev; 318157114Sscottl 319169611Sscottl TAILQ_HEAD(, ccb_hdr) mfi_cam_ccbq; 320169611Sscottl struct mfi_command * (* mfi_cam_start)(void *); 321242726Sambrisko void (*mfi_cam_rescan_cb)(struct mfi_softc *, 322242726Sambrisko uint32_t); 323162619Sscottl struct callout mfi_watchdog_callout; 324157114Sscottl struct mtx mfi_io_lock; 325171821Sjhb struct sx mfi_config_lock; 326171980Sscottl 327171980Sscottl /* Controller type specific interfaces */ 328171980Sscottl void (*mfi_enable_intr)(struct mfi_softc *sc); 329233711Sambrisko void (*mfi_disable_intr)(struct mfi_softc *sc); 330171980Sscottl int32_t (*mfi_read_fw_status)(struct mfi_softc *sc); 331171980Sscottl int (*mfi_check_clear_intr)(struct mfi_softc *sc); 332233711Sambrisko void (*mfi_issue_cmd)(struct mfi_softc *sc, bus_addr_t bus_add, 333233711Sambrisko uint32_t frame_cnt); 334233711Sambrisko int (*mfi_adp_reset)(struct mfi_softc *sc); 335233711Sambrisko int (*mfi_adp_check_reset)(struct mfi_softc *sc); 336242681Sambrisko void (*mfi_intr_ptr)(void *sc); 337233711Sambrisko 338233711Sambrisko /* ThunderBolt */ 339233711Sambrisko uint32_t mfi_tbolt; 340233711Sambrisko uint32_t MFA_enabled; 341233711Sambrisko /* Single Reply structure size */ 342233711Sambrisko uint16_t reply_size; 343233711Sambrisko /* Singler message size. */ 344233711Sambrisko uint16_t raid_io_msg_size; 345233711Sambrisko TAILQ_HEAD(TB, mfi_cmd_tbolt) mfi_cmd_tbolt_tqh; 346233711Sambrisko /* ThunderBolt base contiguous memory mapping. */ 347233711Sambrisko bus_dma_tag_t mfi_tb_dmat; 348233711Sambrisko bus_dmamap_t mfi_tb_dmamap; 349233711Sambrisko bus_addr_t mfi_tb_busaddr; 350233711Sambrisko /* ThunderBolt Contiguous DMA memory Mapping */ 351233711Sambrisko uint8_t * request_message_pool; 352233711Sambrisko uint8_t * request_message_pool_align; 353233711Sambrisko uint8_t * request_desc_pool; 354233711Sambrisko bus_addr_t request_msg_busaddr; 355233711Sambrisko bus_addr_t reply_frame_busaddr; 356233711Sambrisko bus_addr_t sg_frame_busaddr; 357233711Sambrisko /* ThunderBolt IOC Init Descriptor */ 358233711Sambrisko bus_dma_tag_t mfi_tb_ioc_init_dmat; 359233711Sambrisko bus_dmamap_t mfi_tb_ioc_init_dmamap; 360233711Sambrisko uint8_t * mfi_tb_ioc_init_desc; 361233711Sambrisko struct mfi_cmd_tbolt **mfi_cmd_pool_tbolt; 362233711Sambrisko /* Virtual address of reply Frame Pool */ 363233711Sambrisko struct mfi_mpi2_reply_header* reply_frame_pool; 364233711Sambrisko struct mfi_mpi2_reply_header* reply_frame_pool_align; 365233711Sambrisko 366233711Sambrisko /* Last reply frame address */ 367233711Sambrisko uint8_t * reply_pool_limit; 368233711Sambrisko uint16_t last_reply_idx; 369233711Sambrisko uint8_t max_SGEs_in_chain_message; 370233711Sambrisko uint8_t max_SGEs_in_main_message; 371233711Sambrisko uint8_t chain_offset_value_for_main_message; 372233711Sambrisko uint8_t chain_offset_value_for_mpt_ptmsg; 373157114Sscottl}; 374157114Sscottl 375233711Sambriskounion desc_value { 376233711Sambrisko uint64_t word; 377233711Sambrisko struct { 378233711Sambrisko uint32_t low; 379233711Sambrisko uint32_t high; 380233711Sambrisko }u; 381233711Sambrisko}; 382233711Sambrisko 383233711Sambrisko// TODO find the right definition 384233711Sambrisko#define XXX_MFI_CMD_OP_INIT2 0x9 385233711Sambrisko/* 386233711Sambrisko * Request descriptor types 387233711Sambrisko */ 388233711Sambrisko#define MFI_REQ_DESCRIPT_FLAGS_LD_IO 0x7 389233711Sambrisko#define MFI_REQ_DESCRIPT_FLAGS_MFA 0x1 390233711Sambrisko#define MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT 0x1 391233711Sambrisko#define MFI_FUSION_FP_DEFAULT_TIMEOUT 0x14 392233711Sambrisko#define MFI_LOAD_BALANCE_FLAG 0x1 393233711Sambrisko#define MFI_DCMD_MBOX_PEND_FLAG 0x1 394233711Sambrisko 395233711Sambrisko//#define MR_PROT_INFO_TYPE_CONTROLLER 0x08 396233711Sambrisko#define MEGASAS_SCSI_VARIABLE_LENGTH_CMD 0x7f 397233711Sambrisko#define MEGASAS_SCSI_SERVICE_ACTION_READ32 0x9 398233711Sambrisko#define MEGASAS_SCSI_SERVICE_ACTION_WRITE32 0xB 399233711Sambrisko#define MEGASAS_SCSI_ADDL_CDB_LEN 0x18 400233711Sambrisko#define MEGASAS_RD_WR_PROTECT_CHECK_ALL 0x20 401233711Sambrisko#define MEGASAS_RD_WR_PROTECT_CHECK_NONE 0x60 402233711Sambrisko#define MEGASAS_EEDPBLOCKSIZE 512 403233711Sambriskostruct mfi_cmd_tbolt { 404233711Sambrisko union mfi_mpi2_request_descriptor *request_desc; 405233711Sambrisko struct mfi_mpi2_request_raid_scsi_io *io_request; 406233711Sambrisko bus_addr_t io_request_phys_addr; 407233711Sambrisko bus_addr_t sg_frame_phys_addr; 408233711Sambrisko bus_addr_t sense_phys_addr; 409233711Sambrisko MPI2_SGE_IO_UNION *sg_frame; 410233711Sambrisko uint8_t *sense; 411233711Sambrisko TAILQ_ENTRY(mfi_cmd_tbolt) next; 412233711Sambrisko /* 413233711Sambrisko * Context for a MFI frame. 414233711Sambrisko * Used to get the mfi cmd from list when a MFI cmd is completed 415233711Sambrisko */ 416233711Sambrisko uint32_t sync_cmd_idx; 417233711Sambrisko uint16_t index; 418233711Sambrisko uint8_t status; 419233711Sambrisko}; 420233711Sambrisko 421157114Sscottlextern int mfi_attach(struct mfi_softc *); 422157114Sscottlextern void mfi_free(struct mfi_softc *); 423157114Sscottlextern int mfi_shutdown(struct mfi_softc *); 424157114Sscottlextern void mfi_startio(struct mfi_softc *); 425157114Sscottlextern void mfi_disk_complete(struct bio *); 426171821Sjhbextern int mfi_disk_disable(struct mfi_disk *); 427171821Sjhbextern void mfi_disk_enable(struct mfi_disk *); 428157114Sscottlextern int mfi_dump_blocks(struct mfi_softc *, int id, uint64_t, void *, int); 429233711Sambriskoextern int mfi_syspd_disable(struct mfi_system_pd *); 430233711Sambriskoextern void mfi_syspd_enable(struct mfi_system_pd *); 431233711Sambriskoextern int mfi_dump_syspd_blocks(struct mfi_softc *, int id, uint64_t, void *, 432233711Sambrisko int); 433233711Sambriskoextern int mfi_transition_firmware(struct mfi_softc *sc); 434233711Sambriskoextern int mfi_aen_setup(struct mfi_softc *sc, uint32_t seq_start); 435233711Sambriskoextern void mfi_complete(struct mfi_softc *sc, struct mfi_command *cm); 436233711Sambriskoextern int mfi_mapcmd(struct mfi_softc *sc,struct mfi_command *cm); 437233711Sambriskoextern int mfi_wait_command(struct mfi_softc *sc, struct mfi_command *cm); 438233711Sambriskoextern void mfi_tbolt_enable_intr_ppc(struct mfi_softc *); 439233711Sambriskoextern void mfi_tbolt_disable_intr_ppc(struct mfi_softc *); 440233711Sambriskoextern int32_t mfi_tbolt_read_fw_status_ppc(struct mfi_softc *); 441233711Sambriskoextern int32_t mfi_tbolt_check_clear_intr_ppc(struct mfi_softc *); 442233711Sambriskoextern void mfi_tbolt_issue_cmd_ppc(struct mfi_softc *, bus_addr_t, uint32_t); 443233711Sambriskoextern void mfi_tbolt_init_globals(struct mfi_softc*); 444233711Sambriskoextern uint32_t mfi_tbolt_get_memory_requirement(struct mfi_softc *); 445233711Sambriskoextern int mfi_tbolt_init_desc_pool(struct mfi_softc *, uint8_t *, uint32_t); 446233711Sambriskoextern int mfi_tbolt_init_MFI_queue(struct mfi_softc *); 447233711Sambriskoextern void mfi_intr_tbolt(void *arg); 448233711Sambriskoextern int mfi_tbolt_alloc_cmd(struct mfi_softc *sc); 449233711Sambriskoextern int mfi_tbolt_send_frame(struct mfi_softc *sc, struct mfi_command *cm); 450233711Sambriskoextern int mfi_tbolt_adp_reset(struct mfi_softc *sc); 451233711Sambriskoextern int mfi_tbolt_reset(struct mfi_softc *sc); 452235014Sambriskoextern void mfi_tbolt_sync_map_info(struct mfi_softc *sc); 453235014Sambriskoextern void mfi_handle_map_sync(void *context, int pending); 454235014Sambriskoextern int mfi_dcmd_command(struct mfi_softc *, struct mfi_command **, 455242681Sambrisko uint32_t, void **, size_t); 456242681Sambriskoextern int mfi_build_cdb(int, uint8_t, u_int64_t, u_int32_t, uint8_t *); 457157114Sscottl 458157114Sscottl#define MFIQ_ADD(sc, qname) \ 459157114Sscottl do { \ 460157114Sscottl struct mfi_qstat *qs; \ 461157114Sscottl \ 462157114Sscottl qs = &(sc)->mfi_qstat[qname]; \ 463157114Sscottl qs->q_length++; \ 464157114Sscottl if (qs->q_length > qs->q_max) \ 465157114Sscottl qs->q_max = qs->q_length; \ 466157114Sscottl } while (0) 467157114Sscottl 468157114Sscottl#define MFIQ_REMOVE(sc, qname) (sc)->mfi_qstat[qname].q_length-- 469157114Sscottl 470157114Sscottl#define MFIQ_INIT(sc, qname) \ 471157114Sscottl do { \ 472157114Sscottl sc->mfi_qstat[qname].q_length = 0; \ 473157114Sscottl sc->mfi_qstat[qname].q_max = 0; \ 474157114Sscottl } while (0) 475157114Sscottl 476157114Sscottl#define MFIQ_COMMAND_QUEUE(name, index) \ 477157114Sscottl static __inline void \ 478157114Sscottl mfi_initq_ ## name (struct mfi_softc *sc) \ 479157114Sscottl { \ 480157114Sscottl TAILQ_INIT(&sc->mfi_ ## name); \ 481157114Sscottl MFIQ_INIT(sc, index); \ 482157114Sscottl } \ 483157114Sscottl static __inline void \ 484157114Sscottl mfi_enqueue_ ## name (struct mfi_command *cm) \ 485157114Sscottl { \ 486157114Sscottl if ((cm->cm_flags & MFI_ON_MFIQ_MASK) != 0) { \ 487247369Ssmh panic("command %p is on another queue, " \ 488157114Sscottl "flags = %#x\n", cm, cm->cm_flags); \ 489157114Sscottl } \ 490157114Sscottl TAILQ_INSERT_TAIL(&cm->cm_sc->mfi_ ## name, cm, cm_link); \ 491157114Sscottl cm->cm_flags |= MFI_ON_ ## index; \ 492157114Sscottl MFIQ_ADD(cm->cm_sc, index); \ 493157114Sscottl } \ 494157114Sscottl static __inline void \ 495157114Sscottl mfi_requeue_ ## name (struct mfi_command *cm) \ 496157114Sscottl { \ 497157114Sscottl if ((cm->cm_flags & MFI_ON_MFIQ_MASK) != 0) { \ 498247369Ssmh panic("command %p is on another queue, " \ 499157114Sscottl "flags = %#x\n", cm, cm->cm_flags); \ 500157114Sscottl } \ 501157114Sscottl TAILQ_INSERT_HEAD(&cm->cm_sc->mfi_ ## name, cm, cm_link); \ 502157114Sscottl cm->cm_flags |= MFI_ON_ ## index; \ 503157114Sscottl MFIQ_ADD(cm->cm_sc, index); \ 504157114Sscottl } \ 505157114Sscottl static __inline struct mfi_command * \ 506157114Sscottl mfi_dequeue_ ## name (struct mfi_softc *sc) \ 507157114Sscottl { \ 508157114Sscottl struct mfi_command *cm; \ 509157114Sscottl \ 510157114Sscottl if ((cm = TAILQ_FIRST(&sc->mfi_ ## name)) != NULL) { \ 511157114Sscottl if ((cm->cm_flags & MFI_ON_ ## index) == 0) { \ 512247369Ssmh panic("command %p not in queue, " \ 513157114Sscottl "flags = %#x, bit = %#x\n", cm, \ 514157114Sscottl cm->cm_flags, MFI_ON_ ## index); \ 515157114Sscottl } \ 516157114Sscottl TAILQ_REMOVE(&sc->mfi_ ## name, cm, cm_link); \ 517157114Sscottl cm->cm_flags &= ~MFI_ON_ ## index; \ 518157114Sscottl MFIQ_REMOVE(sc, index); \ 519157114Sscottl } \ 520157114Sscottl return (cm); \ 521157114Sscottl } \ 522157114Sscottl static __inline void \ 523157114Sscottl mfi_remove_ ## name (struct mfi_command *cm) \ 524157114Sscottl { \ 525157114Sscottl if ((cm->cm_flags & MFI_ON_ ## index) == 0) { \ 526247369Ssmh panic("command %p not in queue, flags = %#x, " \ 527157114Sscottl "bit = %#x\n", cm, cm->cm_flags, \ 528157114Sscottl MFI_ON_ ## index); \ 529157114Sscottl } \ 530157114Sscottl TAILQ_REMOVE(&cm->cm_sc->mfi_ ## name, cm, cm_link); \ 531157114Sscottl cm->cm_flags &= ~MFI_ON_ ## index; \ 532157114Sscottl MFIQ_REMOVE(cm->cm_sc, index); \ 533157114Sscottl } \ 534157114Sscottlstruct hack 535157114Sscottl 536157114SscottlMFIQ_COMMAND_QUEUE(free, MFIQ_FREE); 537157114SscottlMFIQ_COMMAND_QUEUE(ready, MFIQ_READY); 538157114SscottlMFIQ_COMMAND_QUEUE(busy, MFIQ_BUSY); 539157114Sscottl 540157114Sscottlstatic __inline void 541157114Sscottlmfi_initq_bio(struct mfi_softc *sc) 542157114Sscottl{ 543157114Sscottl bioq_init(&sc->mfi_bioq); 544157114Sscottl MFIQ_INIT(sc, MFIQ_BIO); 545157114Sscottl} 546157114Sscottl 547157114Sscottlstatic __inline void 548157114Sscottlmfi_enqueue_bio(struct mfi_softc *sc, struct bio *bp) 549157114Sscottl{ 550157114Sscottl bioq_insert_tail(&sc->mfi_bioq, bp); 551157114Sscottl MFIQ_ADD(sc, MFIQ_BIO); 552157114Sscottl} 553157114Sscottl 554157114Sscottlstatic __inline struct bio * 555157114Sscottlmfi_dequeue_bio(struct mfi_softc *sc) 556157114Sscottl{ 557157114Sscottl struct bio *bp; 558157114Sscottl 559157114Sscottl if ((bp = bioq_first(&sc->mfi_bioq)) != NULL) { 560157114Sscottl bioq_remove(&sc->mfi_bioq, bp); 561157114Sscottl MFIQ_REMOVE(sc, MFIQ_BIO); 562157114Sscottl } 563157114Sscottl return (bp); 564157114Sscottl} 565157114Sscottl 566226896Sscottl/* 567226896Sscottl * This is from the original scsi_extract_sense() in CAM. It's copied 568226896Sscottl * here because CAM now uses a non-inline version that follows more complex 569226896Sscottl * additions to the SPC spec, and we don't want to force a dependency on 570226896Sscottl * the CAM module for such a trivial action. 571226896Sscottl */ 572157114Sscottlstatic __inline void 573226896Sscottlmfi_extract_sense(struct scsi_sense_data_fixed *sense, 574226896Sscottl int *error_code, int *sense_key, int *asc, int *ascq) 575226896Sscottl{ 576226896Sscottl 577226896Sscottl *error_code = sense->error_code & SSD_ERRCODE; 578226896Sscottl *sense_key = sense->flags & SSD_KEY; 579226896Sscottl *asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0; 580226896Sscottl *ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0; 581226896Sscottl} 582226896Sscottl 583226896Sscottlstatic __inline void 584157114Sscottlmfi_print_sense(struct mfi_softc *sc, void *sense) 585157114Sscottl{ 586157114Sscottl int error, key, asc, ascq; 587157114Sscottl 588226896Sscottl mfi_extract_sense((struct scsi_sense_data_fixed *)sense, 589157114Sscottl &error, &key, &asc, &ascq); 590157114Sscottl device_printf(sc->mfi_dev, "sense error %d, sense_key %d, " 591157114Sscottl "asc %d, ascq %d\n", error, key, asc, ascq); 592157114Sscottl} 593157114Sscottl 594157114Sscottl 595157114Sscottl#define MFI_WRITE4(sc, reg, val) bus_space_write_4((sc)->mfi_btag, \ 596157114Sscottl sc->mfi_bhandle, (reg), (val)) 597157114Sscottl#define MFI_READ4(sc, reg) bus_space_read_4((sc)->mfi_btag, \ 598157114Sscottl (sc)->mfi_bhandle, (reg)) 599157114Sscottl#define MFI_WRITE2(sc, reg, val) bus_space_write_2((sc)->mfi_btag, \ 600157114Sscottl sc->mfi_bhandle, (reg), (val)) 601157114Sscottl#define MFI_READ2(sc, reg) bus_space_read_2((sc)->mfi_btag, \ 602157114Sscottl (sc)->mfi_bhandle, (reg)) 603157114Sscottl#define MFI_WRITE1(sc, reg, val) bus_space_write_1((sc)->mfi_btag, \ 604157114Sscottl sc->mfi_bhandle, (reg), (val)) 605157114Sscottl#define MFI_READ1(sc, reg) bus_space_read_1((sc)->mfi_btag, \ 606157114Sscottl (sc)->mfi_bhandle, (reg)) 607157114Sscottl 608157114SscottlMALLOC_DECLARE(M_MFIBUF); 609227562SjhbSYSCTL_DECL(_hw_mfi); 610157114Sscottl 611233711Sambrisko#define MFI_RESET_WAIT_TIME 180 612162619Sscottl#define MFI_CMD_TIMEOUT 30 613233711Sambrisko#define MFI_SYS_PD_IO 0 614233711Sambrisko#define MFI_LD_IO 1 615233805Sambrisko#define MFI_SKINNY_MEMORY 0x02000000 616195534Sscottl#define MFI_MAXPHYS (128 * 1024) 617162619Sscottl 618162619Sscottl#ifdef MFI_DEBUG 619162619Sscottlextern void mfi_print_cmd(struct mfi_command *cm); 620162619Sscottlextern void mfi_dump_cmds(struct mfi_softc *sc); 621247369Ssmhextern void mfi_validate_sg(struct mfi_softc *, struct mfi_command *, 622247369Ssmh const char *, int); 623162619Sscottl#define MFI_PRINT_CMD(cm) mfi_print_cmd(cm) 624163398Sscottl#define MFI_DUMP_CMDS(sc) mfi_dump_cmds(sc) 625163398Sscottl#define MFI_VALIDATE_CMD(sc, cm) mfi_validate_sg(sc, cm, __FUNCTION__, __LINE__) 626162619Sscottl#else 627162619Sscottl#define MFI_PRINT_CMD(cm) 628162619Sscottl#define MFI_DUMP_CMDS(sc) 629163398Sscottl#define MFI_VALIDATE_CMD(sc, cm) 630162619Sscottl#endif 631162619Sscottl 632247369Ssmhextern void mfi_release_command(struct mfi_command *); 633247369Ssmhextern void mfi_tbolt_return_cmd(struct mfi_softc *, 634247369Ssmh struct mfi_cmd_tbolt *, struct mfi_command *); 635169611Sscottl 636157114Sscottl#endif /* _MFIVAR_H */ 637