mfivar.h revision 233711
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: head/sys/dev/mfi/mfivar.h 233711 2012-03-30 23:05:48Z ambrisko $"); 58157114Sscottl 59171821Sjhb#include <sys/lock.h> 60171821Sjhb#include <sys/sx.h> 61171821Sjhb 62233711Sambrisko#include <sys/types.h> 63233711Sambrisko#include <sys/taskqueue.h> 64233711Sambrisko#include <machine/atomic.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) 105157114Sscottl#define MFI_ON_MFIQ_FREE (1<<5) 106157114Sscottl#define MFI_ON_MFIQ_READY (1<<6) 107157114Sscottl#define MFI_ON_MFIQ_BUSY (1<<7) 108157114Sscottl#define MFI_ON_MFIQ_MASK ((1<<5)|(1<<6)|(1<<7)) 109158737Sambrisko int cm_aen_abort; 110233711Sambrisko uint8_t retry_for_fw_reset; 111157114Sscottl void (* cm_complete)(struct mfi_command *cm); 112157114Sscottl void *cm_private; 113162619Sscottl int cm_index; 114170284Sambrisko int cm_error; 115157114Sscottl}; 116157114Sscottl 117169451Sscottlstruct mfi_disk { 118169451Sscottl TAILQ_ENTRY(mfi_disk) ld_link; 119169451Sscottl device_t ld_dev; 120169451Sscottl int ld_id; 121169451Sscottl int ld_unit; 122169451Sscottl struct mfi_softc *ld_controller; 123159811Sps struct mfi_ld_info *ld_info; 124169451Sscottl struct disk *ld_disk; 125169451Sscottl int ld_flags; 126169451Sscottl#define MFI_DISK_FLAGS_OPEN 0x01 127171821Sjhb#define MFI_DISK_FLAGS_DISABLED 0x02 128157114Sscottl}; 129157114Sscottl 130233711Sambriskostruct mfi_system_pd { 131233711Sambrisko TAILQ_ENTRY(mfi_system_pd) pd_link; 132233711Sambrisko device_t pd_dev; 133233711Sambrisko int pd_id; 134233711Sambrisko int pd_unit; 135233711Sambrisko struct mfi_softc *pd_controller; 136233711Sambrisko struct mfi_pd_info *pd_info; 137233711Sambrisko struct disk *pd_disk; 138233711Sambrisko int pd_flags; 139233711Sambrisko}; 140233711Sambrisko 141233711Sambriskostruct mfi_evt_queue_elm { 142233711Sambrisko TAILQ_ENTRY(mfi_evt_queue_elm) link; 143233711Sambrisko struct mfi_evt_detail detail; 144233711Sambrisko}; 145233711Sambrisko 146158737Sambriskostruct mfi_aen { 147158737Sambrisko TAILQ_ENTRY(mfi_aen) aen_link; 148158737Sambrisko struct proc *p; 149158737Sambrisko}; 150158737Sambrisko 151233711Sambriskostruct mfi_skinny_dma_info { 152233711Sambrisko bus_dma_tag_t dmat[514]; 153233711Sambrisko bus_dmamap_t dmamap[514]; 154233711Sambrisko uint32_t mem[514]; 155233711Sambrisko int noofmaps; 156233711Sambrisko}; 157233711Sambrisko 158233711Sambriskostruct mfi_cmd_tbolt; 159233711Sambriskotypedef struct { 160233711Sambrisko volatile unsigned int val; 161233711Sambrisko} atomic_t; 162233711Sambrisko 163233711Sambrisko#define atomic_read(v) ((v)->val) 164233711Sambrisko#define atomic_set(v,i) ((v)->val - (i)) 165233711Sambrisko 166157114Sscottlstruct mfi_softc { 167157114Sscottl device_t mfi_dev; 168157114Sscottl int mfi_flags; 169157114Sscottl#define MFI_FLAGS_SG64 (1<<0) 170157114Sscottl#define MFI_FLAGS_QFRZN (1<<1) 171157114Sscottl#define MFI_FLAGS_OPEN (1<<2) 172163398Sscottl#define MFI_FLAGS_STOP (1<<3) 173171980Sscottl#define MFI_FLAGS_1064R (1<<4) 174171980Sscottl#define MFI_FLAGS_1078 (1<<5) 175184897Sambrisko#define MFI_FLAGS_GEN2 (1<<6) 176233711Sambrisko#define MFI_FLAGS_SKINNY (1<<7) 177233711Sambrisko#define MFI_FLAGS_TBOLT (1<<8) 178233711Sambrisko // Start: LSIP200113393 179233711Sambrisko bus_dma_tag_t verbuf_h_dmat; 180233711Sambrisko bus_dmamap_t verbuf_h_dmamap; 181233711Sambrisko uint32_t verbuf_h_busaddr; 182233711Sambrisko uint32_t *verbuf; 183233711Sambrisko void *kbuff_arr[MAX_IOCTL_SGE]; 184233711Sambrisko bus_dma_tag_t mfi_kbuff_arr_dmat[2]; 185233711Sambrisko bus_dmamap_t mfi_kbuff_arr_dmamap[2]; 186233711Sambrisko bus_addr_t mfi_kbuff_arr_busaddr[2]; 187157114Sscottl 188157114Sscottl struct mfi_hwcomms *mfi_comms; 189157114Sscottl TAILQ_HEAD(,mfi_command) mfi_free; 190157114Sscottl TAILQ_HEAD(,mfi_command) mfi_ready; 191233711Sambrisko TAILQ_HEAD(BUSYQ,mfi_command) mfi_busy; 192157114Sscottl struct bio_queue_head mfi_bioq; 193157114Sscottl struct mfi_qstat mfi_qstat[MFIQ_COUNT]; 194157114Sscottl 195157114Sscottl struct resource *mfi_regs_resource; 196157114Sscottl bus_space_handle_t mfi_bhandle; 197157114Sscottl bus_space_tag_t mfi_btag; 198157114Sscottl int mfi_regs_rid; 199157114Sscottl 200157114Sscottl bus_dma_tag_t mfi_parent_dmat; 201157114Sscottl bus_dma_tag_t mfi_buffer_dmat; 202157114Sscottl 203157114Sscottl bus_dma_tag_t mfi_comms_dmat; 204157114Sscottl bus_dmamap_t mfi_comms_dmamap; 205233711Sambrisko bus_addr_t mfi_comms_busaddr; 206157114Sscottl 207157114Sscottl bus_dma_tag_t mfi_frames_dmat; 208157114Sscottl bus_dmamap_t mfi_frames_dmamap; 209233711Sambrisko bus_addr_t mfi_frames_busaddr; 210157114Sscottl union mfi_frame *mfi_frames; 211157114Sscottl 212233711Sambrisko bus_dma_tag_t mfi_tb_init_dmat; 213233711Sambrisko bus_dmamap_t mfi_tb_init_dmamap; 214233711Sambrisko bus_addr_t mfi_tb_init_busaddr; 215233711Sambrisko bus_addr_t mfi_tb_ioc_init_busaddr; 216233711Sambrisko union mfi_frame *mfi_tb_init; 217233711Sambrisko 218233711Sambrisko TAILQ_HEAD(,mfi_evt_queue_elm) mfi_evt_queue; 219233711Sambrisko struct task mfi_evt_task; 220158737Sambrisko TAILQ_HEAD(,mfi_aen) mfi_aen_pids; 221158737Sambrisko struct mfi_command *mfi_aen_cm; 222233711Sambrisko struct mfi_command *mfi_skinny_cm; 223158737Sambrisko uint32_t mfi_aen_triggered; 224158737Sambrisko uint32_t mfi_poll_waiting; 225233711Sambrisko uint32_t mfi_boot_seq_num; 226158737Sambrisko struct selinfo mfi_select; 227171821Sjhb int mfi_delete_busy_volumes; 228171821Sjhb int mfi_keep_deleted_volumes; 229171821Sjhb int mfi_detaching; 230158737Sambrisko 231157114Sscottl bus_dma_tag_t mfi_sense_dmat; 232157114Sscottl bus_dmamap_t mfi_sense_dmamap; 233157114Sscottl uint32_t mfi_sense_busaddr; 234157114Sscottl struct mfi_sense *mfi_sense; 235157114Sscottl 236157114Sscottl struct resource *mfi_irq; 237157114Sscottl void *mfi_intr; 238157114Sscottl int mfi_irq_rid; 239157114Sscottl 240157114Sscottl struct intr_config_hook mfi_ich; 241157114Sscottl eventhandler_tag eh; 242233711Sambrisko /* OCR flags */ 243233711Sambrisko atomic_t fw_reset_no_pci_access; 244233711Sambrisko uint8_t adpreset; 245233711Sambrisko uint8_t issuepend_done; 246233711Sambrisko uint8_t disableOnlineCtrlReset; 247233711Sambrisko uint32_t mfiStatus; 248233711Sambrisko uint32_t last_seq_num; 249233711Sambrisko uint32_t volatile hw_crit_error; 250157114Sscottl 251157114Sscottl /* 252157114Sscottl * Allocation for the command array. Used as an indexable array to 253157114Sscottl * recover completed commands. 254157114Sscottl */ 255157114Sscottl struct mfi_command *mfi_commands; 256157114Sscottl /* 257157114Sscottl * How many commands were actually allocated 258157114Sscottl */ 259157114Sscottl int mfi_total_cmds; 260157114Sscottl /* 261157114Sscottl * How many commands the firmware can handle. Also how big the reply 262157114Sscottl * queue is, minus 1. 263157114Sscottl */ 264157114Sscottl int mfi_max_fw_cmds; 265157114Sscottl /* 266233711Sambrisko * How many S/G elements we'll ever actually use 267157114Sscottl */ 268162458Sscottl int mfi_max_sge; 269157114Sscottl /* 270157114Sscottl * How many bytes a compound frame is, including all of the extra frames 271157114Sscottl * that are used for S/G elements. 272157114Sscottl */ 273162458Sscottl int mfi_cmd_size; 274157114Sscottl /* 275157114Sscottl * How large an S/G element is. Used to calculate the number of single 276157114Sscottl * frames in a command. 277157114Sscottl */ 278162458Sscottl int mfi_sge_size; 279157114Sscottl /* 280157114Sscottl * Max number of sectors that the firmware allows 281157114Sscottl */ 282157114Sscottl uint32_t mfi_max_io; 283157114Sscottl 284169451Sscottl TAILQ_HEAD(,mfi_disk) mfi_ld_tqh; 285233711Sambrisko TAILQ_HEAD(,mfi_system_pd) mfi_syspd_tqh; 286157114Sscottl eventhandler_tag mfi_eh; 287157114Sscottl struct cdev *mfi_cdev; 288157114Sscottl 289169611Sscottl TAILQ_HEAD(, ccb_hdr) mfi_cam_ccbq; 290169611Sscottl struct mfi_command * (* mfi_cam_start)(void *); 291162619Sscottl struct callout mfi_watchdog_callout; 292157114Sscottl struct mtx mfi_io_lock; 293171821Sjhb struct sx mfi_config_lock; 294171980Sscottl 295171980Sscottl /* Controller type specific interfaces */ 296171980Sscottl void (*mfi_enable_intr)(struct mfi_softc *sc); 297233711Sambrisko void (*mfi_disable_intr)(struct mfi_softc *sc); 298171980Sscottl int32_t (*mfi_read_fw_status)(struct mfi_softc *sc); 299171980Sscottl int (*mfi_check_clear_intr)(struct mfi_softc *sc); 300233711Sambrisko void (*mfi_issue_cmd)(struct mfi_softc *sc, bus_addr_t bus_add, 301233711Sambrisko uint32_t frame_cnt); 302233711Sambrisko int (*mfi_adp_reset)(struct mfi_softc *sc); 303233711Sambrisko int (*mfi_adp_check_reset)(struct mfi_softc *sc); 304233711Sambrisko 305233711Sambrisko /* ThunderBolt */ 306233711Sambrisko uint32_t mfi_tbolt; 307233711Sambrisko uint32_t MFA_enabled; 308233711Sambrisko uint64_t map_id; 309233711Sambrisko struct mfi_command *map_update_cmd; 310233711Sambrisko /* Single Reply structure size */ 311233711Sambrisko uint16_t reply_size; 312233711Sambrisko /* Singler message size. */ 313233711Sambrisko uint16_t raid_io_msg_size; 314233711Sambrisko TAILQ_HEAD(TB, mfi_cmd_tbolt) mfi_cmd_tbolt_tqh; 315233711Sambrisko /* ThunderBolt base contiguous memory mapping. */ 316233711Sambrisko bus_dma_tag_t mfi_tb_dmat; 317233711Sambrisko bus_dmamap_t mfi_tb_dmamap; 318233711Sambrisko bus_addr_t mfi_tb_busaddr; 319233711Sambrisko /* ThunderBolt Contiguous DMA memory Mapping */ 320233711Sambrisko uint8_t * request_message_pool; 321233711Sambrisko uint8_t * request_message_pool_align; 322233711Sambrisko uint8_t * request_desc_pool; 323233711Sambrisko //uint32_t request_desc_busaddr; 324233711Sambrisko bus_addr_t request_msg_busaddr; 325233711Sambrisko bus_addr_t reply_frame_busaddr; 326233711Sambrisko bus_addr_t sg_frame_busaddr; 327233711Sambrisko /* ThunderBolt IOC Init Descriptor */ 328233711Sambrisko bus_dma_tag_t mfi_tb_ioc_init_dmat; 329233711Sambrisko bus_dmamap_t mfi_tb_ioc_init_dmamap; 330233711Sambrisko uint8_t * mfi_tb_ioc_init_desc; 331233711Sambrisko struct mfi_cmd_tbolt **mfi_cmd_pool_tbolt; 332233711Sambrisko /* Virtual address of reply Frame Pool */ 333233711Sambrisko struct mfi_mpi2_reply_header* reply_frame_pool; 334233711Sambrisko struct mfi_mpi2_reply_header* reply_frame_pool_align; 335233711Sambrisko 336233711Sambrisko /* Last reply frame address */ 337233711Sambrisko uint8_t * reply_pool_limit; 338233711Sambrisko uint16_t last_reply_idx; 339233711Sambrisko uint8_t max_SGEs_in_chain_message; 340233711Sambrisko uint8_t max_SGEs_in_main_message; 341233711Sambrisko uint8_t chain_offset_value_for_main_message; 342233711Sambrisko uint8_t chain_offset_value_for_mpt_ptmsg; 343157114Sscottl}; 344157114Sscottl 345233711Sambriskounion desc_value { 346233711Sambrisko uint64_t word; 347233711Sambrisko struct { 348233711Sambrisko uint32_t low; 349233711Sambrisko uint32_t high; 350233711Sambrisko }u; 351233711Sambrisko}; 352233711Sambrisko 353233711Sambrisko// TODO find the right definition 354233711Sambrisko#define XXX_MFI_CMD_OP_INIT2 0x9 355233711Sambrisko/* 356233711Sambrisko * Request descriptor types 357233711Sambrisko */ 358233711Sambrisko#define MFI_REQ_DESCRIPT_FLAGS_LD_IO 0x7 359233711Sambrisko#define MFI_REQ_DESCRIPT_FLAGS_MFA 0x1 360233711Sambrisko#define MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT 0x1 361233711Sambrisko#define MFI_FUSION_FP_DEFAULT_TIMEOUT 0x14 362233711Sambrisko#define MFI_LOAD_BALANCE_FLAG 0x1 363233711Sambrisko#define MFI_DCMD_MBOX_PEND_FLAG 0x1 364233711Sambrisko 365233711Sambrisko//#define MR_PROT_INFO_TYPE_CONTROLLER 0x08 366233711Sambrisko#define MEGASAS_SCSI_VARIABLE_LENGTH_CMD 0x7f 367233711Sambrisko#define MEGASAS_SCSI_SERVICE_ACTION_READ32 0x9 368233711Sambrisko#define MEGASAS_SCSI_SERVICE_ACTION_WRITE32 0xB 369233711Sambrisko#define MEGASAS_SCSI_ADDL_CDB_LEN 0x18 370233711Sambrisko#define MEGASAS_RD_WR_PROTECT_CHECK_ALL 0x20 371233711Sambrisko#define MEGASAS_RD_WR_PROTECT_CHECK_NONE 0x60 372233711Sambrisko#define MEGASAS_EEDPBLOCKSIZE 512 373233711Sambriskostruct mfi_cmd_tbolt { 374233711Sambrisko union mfi_mpi2_request_descriptor *request_desc; 375233711Sambrisko struct mfi_mpi2_request_raid_scsi_io *io_request; 376233711Sambrisko bus_addr_t io_request_phys_addr; 377233711Sambrisko bus_addr_t sg_frame_phys_addr; 378233711Sambrisko bus_addr_t sense_phys_addr; 379233711Sambrisko MPI2_SGE_IO_UNION *sg_frame; 380233711Sambrisko uint8_t *sense; 381233711Sambrisko TAILQ_ENTRY(mfi_cmd_tbolt) next; 382233711Sambrisko /* 383233711Sambrisko * Context for a MFI frame. 384233711Sambrisko * Used to get the mfi cmd from list when a MFI cmd is completed 385233711Sambrisko */ 386233711Sambrisko uint32_t sync_cmd_idx; 387233711Sambrisko uint16_t index; 388233711Sambrisko uint8_t status; 389233711Sambrisko}; 390233711Sambrisko 391157114Sscottlextern int mfi_attach(struct mfi_softc *); 392157114Sscottlextern void mfi_free(struct mfi_softc *); 393157114Sscottlextern int mfi_shutdown(struct mfi_softc *); 394157114Sscottlextern void mfi_startio(struct mfi_softc *); 395157114Sscottlextern void mfi_disk_complete(struct bio *); 396171821Sjhbextern int mfi_disk_disable(struct mfi_disk *); 397171821Sjhbextern void mfi_disk_enable(struct mfi_disk *); 398157114Sscottlextern int mfi_dump_blocks(struct mfi_softc *, int id, uint64_t, void *, int); 399233711Sambriskoextern int mfi_syspd_disable(struct mfi_system_pd *); 400233711Sambriskoextern void mfi_syspd_enable(struct mfi_system_pd *); 401233711Sambriskoextern int mfi_dump_syspd_blocks(struct mfi_softc *, int id, uint64_t, void *, 402233711Sambrisko int); 403233711Sambriskoextern int mfi_transition_firmware(struct mfi_softc *sc); 404233711Sambriskoextern int mfi_aen_setup(struct mfi_softc *sc, uint32_t seq_start); 405233711Sambriskoextern void mfi_complete(struct mfi_softc *sc, struct mfi_command *cm); 406233711Sambriskoextern int mfi_mapcmd(struct mfi_softc *sc,struct mfi_command *cm); 407233711Sambriskoextern int mfi_wait_command(struct mfi_softc *sc, struct mfi_command *cm); 408233711Sambriskoextern void mfi_tbolt_enable_intr_ppc(struct mfi_softc *); 409233711Sambriskoextern void mfi_tbolt_disable_intr_ppc(struct mfi_softc *); 410233711Sambriskoextern int32_t mfi_tbolt_read_fw_status_ppc(struct mfi_softc *); 411233711Sambriskoextern int32_t mfi_tbolt_check_clear_intr_ppc(struct mfi_softc *); 412233711Sambriskoextern void mfi_tbolt_issue_cmd_ppc(struct mfi_softc *, bus_addr_t, uint32_t); 413233711Sambriskoextern void mfi_tbolt_init_globals(struct mfi_softc*); 414233711Sambriskoextern uint32_t mfi_tbolt_get_memory_requirement(struct mfi_softc *); 415233711Sambriskoextern int mfi_tbolt_init_desc_pool(struct mfi_softc *, uint8_t *, uint32_t); 416233711Sambriskoextern int mfi_tbolt_init_MFI_queue(struct mfi_softc *); 417233711Sambriskoextern void mfi_intr_tbolt(void *arg); 418233711Sambriskoextern int mfi_tbolt_alloc_cmd(struct mfi_softc *sc); 419233711Sambriskoextern int mfi_tbolt_send_frame(struct mfi_softc *sc, struct mfi_command *cm); 420233711Sambriskoextern int mfi_tbolt_adp_reset(struct mfi_softc *sc); 421233711Sambriskoextern int mfi_tbolt_reset(struct mfi_softc *sc); 422233711Sambriskoextern int mfi_tbolt_sync_map_info(struct mfi_softc *sc); 423157114Sscottl 424157114Sscottl#define MFIQ_ADD(sc, qname) \ 425157114Sscottl do { \ 426157114Sscottl struct mfi_qstat *qs; \ 427157114Sscottl \ 428157114Sscottl qs = &(sc)->mfi_qstat[qname]; \ 429157114Sscottl qs->q_length++; \ 430157114Sscottl if (qs->q_length > qs->q_max) \ 431157114Sscottl qs->q_max = qs->q_length; \ 432157114Sscottl } while (0) 433157114Sscottl 434157114Sscottl#define MFIQ_REMOVE(sc, qname) (sc)->mfi_qstat[qname].q_length-- 435157114Sscottl 436157114Sscottl#define MFIQ_INIT(sc, qname) \ 437157114Sscottl do { \ 438157114Sscottl sc->mfi_qstat[qname].q_length = 0; \ 439157114Sscottl sc->mfi_qstat[qname].q_max = 0; \ 440157114Sscottl } while (0) 441157114Sscottl 442157114Sscottl#define MFIQ_COMMAND_QUEUE(name, index) \ 443157114Sscottl static __inline void \ 444157114Sscottl mfi_initq_ ## name (struct mfi_softc *sc) \ 445157114Sscottl { \ 446157114Sscottl TAILQ_INIT(&sc->mfi_ ## name); \ 447157114Sscottl MFIQ_INIT(sc, index); \ 448157114Sscottl } \ 449157114Sscottl static __inline void \ 450157114Sscottl mfi_enqueue_ ## name (struct mfi_command *cm) \ 451157114Sscottl { \ 452157114Sscottl if ((cm->cm_flags & MFI_ON_MFIQ_MASK) != 0) { \ 453157114Sscottl printf("command %p is on another queue, " \ 454157114Sscottl "flags = %#x\n", cm, cm->cm_flags); \ 455157114Sscottl panic("command is on another queue"); \ 456157114Sscottl } \ 457157114Sscottl TAILQ_INSERT_TAIL(&cm->cm_sc->mfi_ ## name, cm, cm_link); \ 458157114Sscottl cm->cm_flags |= MFI_ON_ ## index; \ 459157114Sscottl MFIQ_ADD(cm->cm_sc, index); \ 460157114Sscottl } \ 461157114Sscottl static __inline void \ 462157114Sscottl mfi_requeue_ ## name (struct mfi_command *cm) \ 463157114Sscottl { \ 464157114Sscottl if ((cm->cm_flags & MFI_ON_MFIQ_MASK) != 0) { \ 465157114Sscottl printf("command %p is on another queue, " \ 466157114Sscottl "flags = %#x\n", cm, cm->cm_flags); \ 467157114Sscottl panic("command is on another queue"); \ 468157114Sscottl } \ 469157114Sscottl TAILQ_INSERT_HEAD(&cm->cm_sc->mfi_ ## name, cm, cm_link); \ 470157114Sscottl cm->cm_flags |= MFI_ON_ ## index; \ 471157114Sscottl MFIQ_ADD(cm->cm_sc, index); \ 472157114Sscottl } \ 473157114Sscottl static __inline struct mfi_command * \ 474157114Sscottl mfi_dequeue_ ## name (struct mfi_softc *sc) \ 475157114Sscottl { \ 476157114Sscottl struct mfi_command *cm; \ 477157114Sscottl \ 478157114Sscottl if ((cm = TAILQ_FIRST(&sc->mfi_ ## name)) != NULL) { \ 479157114Sscottl if ((cm->cm_flags & MFI_ON_ ## index) == 0) { \ 480157114Sscottl printf("command %p not in queue, " \ 481157114Sscottl "flags = %#x, bit = %#x\n", cm, \ 482157114Sscottl cm->cm_flags, MFI_ON_ ## index); \ 483157114Sscottl panic("command not in queue"); \ 484157114Sscottl } \ 485157114Sscottl TAILQ_REMOVE(&sc->mfi_ ## name, cm, cm_link); \ 486157114Sscottl cm->cm_flags &= ~MFI_ON_ ## index; \ 487157114Sscottl MFIQ_REMOVE(sc, index); \ 488157114Sscottl } \ 489157114Sscottl return (cm); \ 490157114Sscottl } \ 491157114Sscottl static __inline void \ 492157114Sscottl mfi_remove_ ## name (struct mfi_command *cm) \ 493157114Sscottl { \ 494157114Sscottl if ((cm->cm_flags & MFI_ON_ ## index) == 0) { \ 495157114Sscottl printf("command %p not in queue, flags = %#x, " \ 496157114Sscottl "bit = %#x\n", cm, cm->cm_flags, \ 497157114Sscottl MFI_ON_ ## index); \ 498157114Sscottl panic("command not in queue"); \ 499157114Sscottl } \ 500157114Sscottl TAILQ_REMOVE(&cm->cm_sc->mfi_ ## name, cm, cm_link); \ 501157114Sscottl cm->cm_flags &= ~MFI_ON_ ## index; \ 502157114Sscottl MFIQ_REMOVE(cm->cm_sc, index); \ 503157114Sscottl } \ 504157114Sscottlstruct hack 505157114Sscottl 506157114SscottlMFIQ_COMMAND_QUEUE(free, MFIQ_FREE); 507157114SscottlMFIQ_COMMAND_QUEUE(ready, MFIQ_READY); 508157114SscottlMFIQ_COMMAND_QUEUE(busy, MFIQ_BUSY); 509157114Sscottl 510157114Sscottlstatic __inline void 511157114Sscottlmfi_initq_bio(struct mfi_softc *sc) 512157114Sscottl{ 513157114Sscottl bioq_init(&sc->mfi_bioq); 514157114Sscottl MFIQ_INIT(sc, MFIQ_BIO); 515157114Sscottl} 516157114Sscottl 517157114Sscottlstatic __inline void 518157114Sscottlmfi_enqueue_bio(struct mfi_softc *sc, struct bio *bp) 519157114Sscottl{ 520157114Sscottl bioq_insert_tail(&sc->mfi_bioq, bp); 521157114Sscottl MFIQ_ADD(sc, MFIQ_BIO); 522157114Sscottl} 523157114Sscottl 524157114Sscottlstatic __inline struct bio * 525157114Sscottlmfi_dequeue_bio(struct mfi_softc *sc) 526157114Sscottl{ 527157114Sscottl struct bio *bp; 528157114Sscottl 529157114Sscottl if ((bp = bioq_first(&sc->mfi_bioq)) != NULL) { 530157114Sscottl bioq_remove(&sc->mfi_bioq, bp); 531157114Sscottl MFIQ_REMOVE(sc, MFIQ_BIO); 532157114Sscottl } 533157114Sscottl return (bp); 534157114Sscottl} 535157114Sscottl 536226896Sscottl/* 537226896Sscottl * This is from the original scsi_extract_sense() in CAM. It's copied 538226896Sscottl * here because CAM now uses a non-inline version that follows more complex 539226896Sscottl * additions to the SPC spec, and we don't want to force a dependency on 540226896Sscottl * the CAM module for such a trivial action. 541226896Sscottl */ 542157114Sscottlstatic __inline void 543226896Sscottlmfi_extract_sense(struct scsi_sense_data_fixed *sense, 544226896Sscottl int *error_code, int *sense_key, int *asc, int *ascq) 545226896Sscottl{ 546226896Sscottl 547226896Sscottl *error_code = sense->error_code & SSD_ERRCODE; 548226896Sscottl *sense_key = sense->flags & SSD_KEY; 549226896Sscottl *asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0; 550226896Sscottl *ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0; 551226896Sscottl} 552226896Sscottl 553226896Sscottlstatic __inline void 554157114Sscottlmfi_print_sense(struct mfi_softc *sc, void *sense) 555157114Sscottl{ 556157114Sscottl int error, key, asc, ascq; 557157114Sscottl 558226896Sscottl mfi_extract_sense((struct scsi_sense_data_fixed *)sense, 559157114Sscottl &error, &key, &asc, &ascq); 560157114Sscottl device_printf(sc->mfi_dev, "sense error %d, sense_key %d, " 561157114Sscottl "asc %d, ascq %d\n", error, key, asc, ascq); 562157114Sscottl} 563157114Sscottl 564157114Sscottl 565157114Sscottl#define MFI_WRITE4(sc, reg, val) bus_space_write_4((sc)->mfi_btag, \ 566157114Sscottl sc->mfi_bhandle, (reg), (val)) 567157114Sscottl#define MFI_READ4(sc, reg) bus_space_read_4((sc)->mfi_btag, \ 568157114Sscottl (sc)->mfi_bhandle, (reg)) 569157114Sscottl#define MFI_WRITE2(sc, reg, val) bus_space_write_2((sc)->mfi_btag, \ 570157114Sscottl sc->mfi_bhandle, (reg), (val)) 571157114Sscottl#define MFI_READ2(sc, reg) bus_space_read_2((sc)->mfi_btag, \ 572157114Sscottl (sc)->mfi_bhandle, (reg)) 573157114Sscottl#define MFI_WRITE1(sc, reg, val) bus_space_write_1((sc)->mfi_btag, \ 574157114Sscottl sc->mfi_bhandle, (reg), (val)) 575157114Sscottl#define MFI_READ1(sc, reg) bus_space_read_1((sc)->mfi_btag, \ 576157114Sscottl (sc)->mfi_bhandle, (reg)) 577157114Sscottl 578157114SscottlMALLOC_DECLARE(M_MFIBUF); 579227562SjhbSYSCTL_DECL(_hw_mfi); 580157114Sscottl 581233711Sambrisko#define MFI_RESET_WAIT_TIME 180 582162619Sscottl#define MFI_CMD_TIMEOUT 30 583233711Sambrisko#define MFI_SYS_PD_IO 0 584233711Sambrisko#define MFI_LD_IO 1 585233711Sambrisko#define SKINNY_MEMORY 0x02000000 586195534Sscottl#define MFI_MAXPHYS (128 * 1024) 587162619Sscottl 588162619Sscottl#ifdef MFI_DEBUG 589162619Sscottlextern void mfi_print_cmd(struct mfi_command *cm); 590162619Sscottlextern void mfi_dump_cmds(struct mfi_softc *sc); 591163398Sscottlextern void mfi_validate_sg(struct mfi_softc *, struct mfi_command *, const char *, int ); 592162619Sscottl#define MFI_PRINT_CMD(cm) mfi_print_cmd(cm) 593163398Sscottl#define MFI_DUMP_CMDS(sc) mfi_dump_cmds(sc) 594163398Sscottl#define MFI_VALIDATE_CMD(sc, cm) mfi_validate_sg(sc, cm, __FUNCTION__, __LINE__) 595162619Sscottl#else 596162619Sscottl#define MFI_PRINT_CMD(cm) 597162619Sscottl#define MFI_DUMP_CMDS(sc) 598163398Sscottl#define MFI_VALIDATE_CMD(sc, cm) 599162619Sscottl#endif 600162619Sscottl 601169611Sscottlextern void mfi_release_command(struct mfi_command *cm); 602169611Sscottl 603157114Sscottl#endif /* _MFIVAR_H */ 604