mfivar.h revision 233877
119370Spst/*- 298948Sobrien * Copyright (c) 2006 IronPort Systems 398948Sobrien * All rights reserved. 4130809Smarcel * 519370Spst * Redistribution and use in source and binary forms, with or without 619370Spst * modification, are permitted provided that the following conditions 798948Sobrien * are met: 819370Spst * 1. Redistributions of source code must retain the above copyright 998948Sobrien * notice, this list of conditions and the following disclaimer. 1098948Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1198948Sobrien * notice, this list of conditions and the following disclaimer in the 1298948Sobrien * documentation and/or other materials provided with the distribution. 1319370Spst * 1498948Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1598948Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1698948Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1798948Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1819370Spst * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1998948Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2098948Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2198948Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2298948Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2319370Spst * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2419370Spst * SUCH DAMAGE. 2519370Spst */ 2619370Spst/*- 2798948Sobrien * Copyright (c) 2007 LSI Corp. 2898948Sobrien * Copyright (c) 2007 Rajesh Prabhakaran. 2998948Sobrien * All rights reserved. 30130809Smarcel * 3119370Spst * Redistribution and use in source and binary forms, with or without 3219370Spst * modification, are permitted provided that the following conditions 3398948Sobrien * are met: 3419370Spst * 1. Redistributions of source code must retain the above copyright 3519370Spst * notice, this list of conditions and the following disclaimer. 3619370Spst * 2. Redistributions in binary form must reproduce the above copyright 3719370Spst * notice, this list of conditions and the following disclaimer in the 3819370Spst * documentation and/or other materials provided with the distribution. 3919370Spst * 4098948Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 4119370Spst * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4298948Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4319370Spst * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4498948Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4598948Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4698948Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4798948Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4819370Spst * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 4919370Spst * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50130809Smarcel * SUCH DAMAGE. 51130809Smarcel */ 5219370Spst 5319370Spst#ifndef _MFIVAR_H 5419370Spst#define _MFIVAR_H 5519370Spst 5619370Spst#include <sys/cdefs.h> 5719370Spst__FBSDID("$FreeBSD: head/sys/dev/mfi/mfivar.h 233877 2012-04-04 16:15:40Z jkim $"); 5898948Sobrien 5998948Sobrien#include <sys/lock.h> 6098948Sobrien#include <sys/sx.h> 6119370Spst 6219370Spst#include <sys/types.h> 6319370Spst#include <sys/taskqueue.h> 6498948Sobrien 6598948Sobrien/* 6619370Spst * SCSI structures and definitions are used from here, but no linking 6798948Sobrien * requirements are made to CAM. 6819370Spst */ 6998948Sobrien#include <cam/scsi/scsi_all.h> 7098948Sobrien 7146283Sdfrstruct mfi_hwcomms { 7246283Sdfr uint32_t hw_pi; 7319370Spst uint32_t hw_ci; 7419370Spst uint32_t hw_reply_q[1]; 7519370Spst}; 7619370Spst#define MEGASAS_MAX_NAME 32 7719370Spst#define MEGASAS_VERSION "4.23" 7819370Spst 7919370Spststruct mfi_softc; 8019370Spststruct disk; 8119370Spststruct ccb_hdr; 8219370Spst 8319370Spststruct mfi_command { 8419370Spst TAILQ_ENTRY(mfi_command) cm_link; 85130809Smarcel time_t cm_timestamp; 8619370Spst struct mfi_softc *cm_sc; 8719370Spst union mfi_frame *cm_frame; 8819370Spst bus_addr_t cm_frame_busaddr; 8919370Spst struct mfi_sense *cm_sense; 9019370Spst bus_addr_t cm_sense_busaddr; 9198948Sobrien bus_dmamap_t cm_dmamap; 9219370Spst union mfi_sgl *cm_sg; 9319370Spst void *cm_data; 9419370Spst int cm_len; 9546283Sdfr int cm_stp_len; 9619370Spst int cm_total_frame_size; 9719370Spst int cm_extra_frames; 9819370Spst int cm_flags; 9919370Spst#define MFI_CMD_MAPPED (1<<0) 10019370Spst#define MFI_CMD_DATAIN (1<<1) 10119370Spst#define MFI_CMD_DATAOUT (1<<2) 10219370Spst#define MFI_CMD_COMPLETED (1<<3) 10319370Spst#define MFI_CMD_POLLED (1<<4) 10419370Spst#define MFI_ON_MFIQ_FREE (1<<5) 10519370Spst#define MFI_ON_MFIQ_READY (1<<6) 10619370Spst#define MFI_ON_MFIQ_BUSY (1<<7) 10719370Spst#define MFI_ON_MFIQ_MASK ((1<<5)|(1<<6)|(1<<7)) 10819370Spst int cm_aen_abort; 10919370Spst uint8_t retry_for_fw_reset; 11098948Sobrien void (* cm_complete)(struct mfi_command *cm); 11119370Spst void *cm_private; 11219370Spst int cm_index; 11319370Spst int cm_error; 11419370Spst}; 11519370Spst 11698948Sobrienstruct mfi_disk { 11719370Spst TAILQ_ENTRY(mfi_disk) ld_link; 11819370Spst device_t ld_dev; 11919370Spst int ld_id; 12019370Spst int ld_unit; 12119370Spst struct mfi_softc *ld_controller; 12219370Spst struct mfi_ld_info *ld_info; 12319370Spst struct disk *ld_disk; 12419370Spst int ld_flags; 12598948Sobrien#define MFI_DISK_FLAGS_OPEN 0x01 12619370Spst#define MFI_DISK_FLAGS_DISABLED 0x02 12719370Spst}; 12819370Spst 12919370Spststruct mfi_system_pd { 13019370Spst TAILQ_ENTRY(mfi_system_pd) pd_link; 13119370Spst device_t pd_dev; 13219370Spst int pd_id; 13319370Spst int pd_unit; 13419370Spst struct mfi_softc *pd_controller; 13519370Spst struct mfi_pd_info *pd_info; 13619370Spst struct disk *pd_disk; 13719370Spst int pd_flags; 13819370Spst}; 13946283Sdfr 14046283Sdfrstruct mfi_evt_queue_elm { 14198948Sobrien TAILQ_ENTRY(mfi_evt_queue_elm) link; 14298948Sobrien struct mfi_evt_detail detail; 14398948Sobrien}; 14498948Sobrien 14598948Sobrienstruct mfi_aen { 14646283Sdfr TAILQ_ENTRY(mfi_aen) aen_link; 14798948Sobrien struct proc *p; 14898948Sobrien}; 14998948Sobrien 150130809Smarcelstruct mfi_skinny_dma_info { 15198948Sobrien bus_dma_tag_t dmat[514]; 15298948Sobrien bus_dmamap_t dmamap[514]; 15398948Sobrien uint32_t mem[514]; 15498948Sobrien int noofmaps; 15598948Sobrien}; 15698948Sobrien 15798948Sobrienstruct megasas_sge 15898948Sobrien{ 15998948Sobrien bus_addr_t phys_addr; 16098948Sobrien uint32_t length; 16119370Spst}; 16219370Spst 16319370Spststruct mfi_cmd_tbolt; 16419370Spst 16598948Sobrienstruct mfi_softc { 16698948Sobrien device_t mfi_dev; 16798948Sobrien int mfi_flags; 16898948Sobrien#define MFI_FLAGS_SG64 (1<<0) 16998948Sobrien#define MFI_FLAGS_QFRZN (1<<1) 17098948Sobrien#define MFI_FLAGS_OPEN (1<<2) 17119370Spst#define MFI_FLAGS_STOP (1<<3) 17219370Spst#define MFI_FLAGS_1064R (1<<4) 17319370Spst#define MFI_FLAGS_1078 (1<<5) 174130809Smarcel#define MFI_FLAGS_GEN2 (1<<6) 175130809Smarcel#define MFI_FLAGS_SKINNY (1<<7) 176130809Smarcel#define MFI_FLAGS_TBOLT (1<<8) 177130809Smarcel // Start: LSIP200113393 178130809Smarcel bus_dma_tag_t verbuf_h_dmat; 17919370Spst bus_dmamap_t verbuf_h_dmamap; 18019370Spst uint32_t verbuf_h_busaddr; 18119370Spst uint32_t *verbuf; 18219370Spst void *kbuff_arr[MAX_IOCTL_SGE]; 18319370Spst bus_dma_tag_t mfi_kbuff_arr_dmat[2]; 18498948Sobrien bus_dmamap_t mfi_kbuff_arr_dmamap[2]; 18519370Spst bus_addr_t mfi_kbuff_arr_busaddr[2]; 18619370Spst 18719370Spst struct mfi_hwcomms *mfi_comms; 18819370Spst TAILQ_HEAD(,mfi_command) mfi_free; 18919370Spst TAILQ_HEAD(,mfi_command) mfi_ready; 19019370Spst TAILQ_HEAD(BUSYQ,mfi_command) mfi_busy; 19198948Sobrien struct bio_queue_head mfi_bioq; 19219370Spst struct mfi_qstat mfi_qstat[MFIQ_COUNT]; 19398948Sobrien 19498948Sobrien struct resource *mfi_regs_resource; 19519370Spst bus_space_handle_t mfi_bhandle; 19698948Sobrien bus_space_tag_t mfi_btag; 19719370Spst int mfi_regs_rid; 19898948Sobrien 19998948Sobrien bus_dma_tag_t mfi_parent_dmat; 20098948Sobrien bus_dma_tag_t mfi_buffer_dmat; 20119370Spst 20298948Sobrien bus_dma_tag_t mfi_comms_dmat; 20319370Spst bus_dmamap_t mfi_comms_dmamap; 20498948Sobrien bus_addr_t mfi_comms_busaddr; 20598948Sobrien 20619370Spst bus_dma_tag_t mfi_frames_dmat; 20798948Sobrien bus_dmamap_t mfi_frames_dmamap; 20819370Spst bus_addr_t mfi_frames_busaddr; 20919370Spst union mfi_frame *mfi_frames; 21019370Spst 21119370Spst bus_dma_tag_t mfi_tb_init_dmat; 21298948Sobrien bus_dmamap_t mfi_tb_init_dmamap; 21398948Sobrien bus_addr_t mfi_tb_init_busaddr; 21419370Spst bus_addr_t mfi_tb_ioc_init_busaddr; 21519370Spst union mfi_frame *mfi_tb_init; 21698948Sobrien 21719370Spst TAILQ_HEAD(,mfi_evt_queue_elm) mfi_evt_queue; 21846283Sdfr struct task mfi_evt_task; 21946283Sdfr TAILQ_HEAD(,mfi_aen) mfi_aen_pids; 22098948Sobrien struct mfi_command *mfi_aen_cm; 22146283Sdfr struct mfi_command *mfi_skinny_cm; 22246283Sdfr uint32_t mfi_aen_triggered; 22346283Sdfr uint32_t mfi_poll_waiting; 22446283Sdfr uint32_t mfi_boot_seq_num; 22546283Sdfr struct selinfo mfi_select; 22646283Sdfr int mfi_delete_busy_volumes; 22746283Sdfr int mfi_keep_deleted_volumes; 22846283Sdfr int mfi_detaching; 22946283Sdfr 23046283Sdfr bus_dma_tag_t mfi_sense_dmat; 23146283Sdfr bus_dmamap_t mfi_sense_dmamap; 23246283Sdfr uint32_t mfi_sense_busaddr; 23398948Sobrien struct mfi_sense *mfi_sense; 23498948Sobrien 23598948Sobrien struct resource *mfi_irq; 23646283Sdfr void *mfi_intr; 23719370Spst int mfi_irq_rid; 23819370Spst 23919370Spst struct intr_config_hook mfi_ich; 24098948Sobrien eventhandler_tag eh; 24198948Sobrien /* OCR flags */ 24298948Sobrien uint8_t adpreset; 24319370Spst uint8_t issuepend_done; 24498948Sobrien uint8_t disableOnlineCtrlReset; 24598948Sobrien uint32_t mfiStatus; 24698948Sobrien uint32_t last_seq_num; 24798948Sobrien uint32_t volatile hw_crit_error; 24898948Sobrien 24998948Sobrien /* 25019370Spst * Allocation for the command array. Used as an indexable array to 25119370Spst * recover completed commands. 25219370Spst */ 25398948Sobrien struct mfi_command *mfi_commands; 25419370Spst /* 25519370Spst * How many commands were actually allocated 25619370Spst */ 25719370Spst int mfi_total_cmds; 25898948Sobrien /* 25919370Spst * How many commands the firmware can handle. Also how big the reply 26046283Sdfr * queue is, minus 1. 26146283Sdfr */ 26298948Sobrien int mfi_max_fw_cmds; 26398948Sobrien /* 26446283Sdfr * How many S/G elements we'll ever actually use 26546283Sdfr */ 26698948Sobrien int mfi_max_sge; 26746283Sdfr /* 26819370Spst * How many bytes a compound frame is, including all of the extra frames 26919370Spst * that are used for S/G elements. 27019370Spst */ 27198948Sobrien int mfi_cmd_size; 27298948Sobrien /* 27319370Spst * How large an S/G element is. Used to calculate the number of single 27419370Spst * frames in a command. 27519370Spst */ 27619370Spst int mfi_sge_size; 27798948Sobrien /* 27898948Sobrien * Max number of sectors that the firmware allows 27919370Spst */ 28098948Sobrien uint32_t mfi_max_io; 28198948Sobrien 28298948Sobrien TAILQ_HEAD(,mfi_disk) mfi_ld_tqh; 28398948Sobrien TAILQ_HEAD(,mfi_system_pd) mfi_syspd_tqh; 28498948Sobrien eventhandler_tag mfi_eh; 28546283Sdfr struct cdev *mfi_cdev; 28619370Spst 28798948Sobrien TAILQ_HEAD(, ccb_hdr) mfi_cam_ccbq; 28846283Sdfr struct mfi_command * (* mfi_cam_start)(void *); 28919370Spst struct callout mfi_watchdog_callout; 29019370Spst struct mtx mfi_io_lock; 29119370Spst struct sx mfi_config_lock; 29298948Sobrien 29319370Spst /* Controller type specific interfaces */ 29419370Spst void (*mfi_enable_intr)(struct mfi_softc *sc); 29598948Sobrien void (*mfi_disable_intr)(struct mfi_softc *sc); 29698948Sobrien int32_t (*mfi_read_fw_status)(struct mfi_softc *sc); 29798948Sobrien int (*mfi_check_clear_intr)(struct mfi_softc *sc); 29898948Sobrien void (*mfi_issue_cmd)(struct mfi_softc *sc, bus_addr_t bus_add, 29998948Sobrien uint32_t frame_cnt); 30098948Sobrien int (*mfi_adp_reset)(struct mfi_softc *sc); 30198948Sobrien int (*mfi_adp_check_reset)(struct mfi_softc *sc); 30298948Sobrien 30398948Sobrien /* ThunderBolt */ 30498948Sobrien uint32_t mfi_tbolt; 30598948Sobrien uint32_t MFA_enabled; 30619370Spst uint64_t map_id; 30798948Sobrien struct mfi_command *map_update_cmd; 30898948Sobrien /* Single Reply structure size */ 30998948Sobrien uint16_t reply_size; 31098948Sobrien /* Singler message size. */ 31198948Sobrien uint16_t raid_io_msg_size; 31219370Spst TAILQ_HEAD(TB, mfi_cmd_tbolt) mfi_cmd_tbolt_tqh; 31398948Sobrien /* ThunderBolt base contiguous memory mapping. */ 31419370Spst bus_dma_tag_t mfi_tb_dmat; 31519370Spst bus_dmamap_t mfi_tb_dmamap; 31619370Spst bus_addr_t mfi_tb_busaddr; 31719370Spst /* ThunderBolt Contiguous DMA memory Mapping */ 31819370Spst uint8_t * request_message_pool; 31919370Spst uint8_t * request_message_pool_align; 32098948Sobrien uint8_t * request_desc_pool; 32119370Spst //uint32_t request_desc_busaddr; 32219370Spst bus_addr_t request_msg_busaddr; 32319370Spst bus_addr_t reply_frame_busaddr; 32498948Sobrien bus_addr_t sg_frame_busaddr; 32598948Sobrien /* ThunderBolt IOC Init Descriptor */ 32698948Sobrien bus_dma_tag_t mfi_tb_ioc_init_dmat; 32798948Sobrien bus_dmamap_t mfi_tb_ioc_init_dmamap; 32819370Spst uint8_t * mfi_tb_ioc_init_desc; 32919370Spst struct mfi_cmd_tbolt **mfi_cmd_pool_tbolt; 33019370Spst /* Virtual address of reply Frame Pool */ 33119370Spst struct mfi_mpi2_reply_header* reply_frame_pool; 33219370Spst struct mfi_mpi2_reply_header* reply_frame_pool_align; 33319370Spst 33419370Spst /* Last reply frame address */ 33519370Spst uint8_t * reply_pool_limit; 33619370Spst uint16_t last_reply_idx; 33719370Spst uint8_t max_SGEs_in_chain_message; 33819370Spst uint8_t max_SGEs_in_main_message; 33919370Spst uint8_t chain_offset_value_for_main_message; 34098948Sobrien uint8_t chain_offset_value_for_mpt_ptmsg; 34198948Sobrien}; 34298948Sobrien 34398948Sobrienunion desc_value { 34498948Sobrien uint64_t word; 34519370Spst struct { 34619370Spst uint32_t low; 34798948Sobrien uint32_t high; 34898948Sobrien }u; 34998948Sobrien}; 35098948Sobrien 35198948Sobrien// TODO find the right definition 35219370Spst#define XXX_MFI_CMD_OP_INIT2 0x9 35319370Spst/* 35419370Spst * Request descriptor types 35519370Spst */ 35619370Spst#define MFI_REQ_DESCRIPT_FLAGS_LD_IO 0x7 35719370Spst#define MFI_REQ_DESCRIPT_FLAGS_MFA 0x1 35819370Spst#define MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT 0x1 35919370Spst#define MFI_FUSION_FP_DEFAULT_TIMEOUT 0x14 36019370Spst#define MFI_LOAD_BALANCE_FLAG 0x1 36119370Spst#define MFI_DCMD_MBOX_PEND_FLAG 0x1 36219370Spst 36319370Spst//#define MR_PROT_INFO_TYPE_CONTROLLER 0x08 36419370Spst#define MEGASAS_SCSI_VARIABLE_LENGTH_CMD 0x7f 36519370Spst#define MEGASAS_SCSI_SERVICE_ACTION_READ32 0x9 36619370Spst#define MEGASAS_SCSI_SERVICE_ACTION_WRITE32 0xB 36798948Sobrien#define MEGASAS_SCSI_ADDL_CDB_LEN 0x18 36898948Sobrien#define MEGASAS_RD_WR_PROTECT_CHECK_ALL 0x20 36998948Sobrien#define MEGASAS_RD_WR_PROTECT_CHECK_NONE 0x60 37098948Sobrien#define MEGASAS_EEDPBLOCKSIZE 512 37198948Sobrienstruct mfi_cmd_tbolt { 37298948Sobrien union mfi_mpi2_request_descriptor *request_desc; 37398948Sobrien struct mfi_mpi2_request_raid_scsi_io *io_request; 37498948Sobrien bus_addr_t io_request_phys_addr; 37598948Sobrien bus_addr_t sg_frame_phys_addr; 37698948Sobrien bus_addr_t sense_phys_addr; 37798948Sobrien MPI2_SGE_IO_UNION *sg_frame; 37898948Sobrien uint8_t *sense; 37998948Sobrien TAILQ_ENTRY(mfi_cmd_tbolt) next; 38098948Sobrien /* 38198948Sobrien * Context for a MFI frame. 38298948Sobrien * Used to get the mfi cmd from list when a MFI cmd is completed 38398948Sobrien */ 38498948Sobrien uint32_t sync_cmd_idx; 38598948Sobrien uint16_t index; 386130809Smarcel uint8_t status; 38798948Sobrien}; 38819370Spst 38998948Sobrienextern int mfi_attach(struct mfi_softc *); 39098948Sobrienextern void mfi_free(struct mfi_softc *); 39119370Spstextern int mfi_shutdown(struct mfi_softc *); 39219370Spstextern void mfi_startio(struct mfi_softc *); 39319370Spstextern void mfi_disk_complete(struct bio *); 39498948Sobrienextern int mfi_disk_disable(struct mfi_disk *); 39519370Spstextern void mfi_disk_enable(struct mfi_disk *); 39698948Sobrienextern int mfi_dump_blocks(struct mfi_softc *, int id, uint64_t, void *, int); 39798948Sobrienextern int mfi_syspd_disable(struct mfi_system_pd *); 39898948Sobrienextern void mfi_syspd_enable(struct mfi_system_pd *); 39919370Spstextern int mfi_dump_syspd_blocks(struct mfi_softc *, int id, uint64_t, void *, 40098948Sobrien int); 40198948Sobrienextern int mfi_transition_firmware(struct mfi_softc *sc); 40298948Sobrienextern int mfi_aen_setup(struct mfi_softc *sc, uint32_t seq_start); 40319370Spstextern void mfi_complete(struct mfi_softc *sc, struct mfi_command *cm); 40498948Sobrienextern int mfi_mapcmd(struct mfi_softc *sc,struct mfi_command *cm); 40519370Spstextern int mfi_wait_command(struct mfi_softc *sc, struct mfi_command *cm); 40698948Sobrienextern void mfi_tbolt_enable_intr_ppc(struct mfi_softc *); 40798948Sobrienextern void mfi_tbolt_disable_intr_ppc(struct mfi_softc *); 40819370Spstextern int32_t mfi_tbolt_read_fw_status_ppc(struct mfi_softc *); 40919370Spstextern int32_t mfi_tbolt_check_clear_intr_ppc(struct mfi_softc *); 41098948Sobrienextern void mfi_tbolt_issue_cmd_ppc(struct mfi_softc *, bus_addr_t, uint32_t); 41119370Spstextern void mfi_tbolt_init_globals(struct mfi_softc*); 41298948Sobrienextern uint32_t mfi_tbolt_get_memory_requirement(struct mfi_softc *); 41319370Spstextern int mfi_tbolt_init_desc_pool(struct mfi_softc *, uint8_t *, uint32_t); 41498948Sobrienextern int mfi_tbolt_init_MFI_queue(struct mfi_softc *); 41519370Spstextern void mfi_intr_tbolt(void *arg); 41698948Sobrienextern int mfi_tbolt_alloc_cmd(struct mfi_softc *sc); 41798948Sobrienextern int mfi_tbolt_send_frame(struct mfi_softc *sc, struct mfi_command *cm); 41819370Spstextern int mfi_tbolt_adp_reset(struct mfi_softc *sc); 41998948Sobrienextern int mfi_tbolt_reset(struct mfi_softc *sc); 42098948Sobrienextern int mfi_tbolt_sync_map_info(struct mfi_softc *sc); 42119370Spst 42298948Sobrien#define MFIQ_ADD(sc, qname) \ 42319370Spst do { \ 42498948Sobrien struct mfi_qstat *qs; \ 42519370Spst \ 42698948Sobrien qs = &(sc)->mfi_qstat[qname]; \ 42798948Sobrien qs->q_length++; \ 42898948Sobrien if (qs->q_length > qs->q_max) \ 42998948Sobrien qs->q_max = qs->q_length; \ 43098948Sobrien } while (0) 43198948Sobrien 432130809Smarcel#define MFIQ_REMOVE(sc, qname) (sc)->mfi_qstat[qname].q_length-- 433130809Smarcel 434130809Smarcel#define MFIQ_INIT(sc, qname) \ 435130809Smarcel do { \ 436130809Smarcel sc->mfi_qstat[qname].q_length = 0; \ 437130809Smarcel sc->mfi_qstat[qname].q_max = 0; \ 438130809Smarcel } while (0) 439130809Smarcel 44098948Sobrien#define MFIQ_COMMAND_QUEUE(name, index) \ 44119370Spst static __inline void \ 44298948Sobrien mfi_initq_ ## name (struct mfi_softc *sc) \ 44398948Sobrien { \ 44498948Sobrien TAILQ_INIT(&sc->mfi_ ## name); \ 44598948Sobrien MFIQ_INIT(sc, index); \ 44698948Sobrien } \ 44798948Sobrien static __inline void \ 44819370Spst mfi_enqueue_ ## name (struct mfi_command *cm) \ 44998948Sobrien { \ 45098948Sobrien if ((cm->cm_flags & MFI_ON_MFIQ_MASK) != 0) { \ 45119370Spst printf("command %p is on another queue, " \ 45298948Sobrien "flags = %#x\n", cm, cm->cm_flags); \ 45319370Spst panic("command is on another queue"); \ 45498948Sobrien } \ 45519370Spst TAILQ_INSERT_TAIL(&cm->cm_sc->mfi_ ## name, cm, cm_link); \ 45698948Sobrien cm->cm_flags |= MFI_ON_ ## index; \ 45798948Sobrien MFIQ_ADD(cm->cm_sc, index); \ 45898948Sobrien } \ 45998948Sobrien static __inline void \ 46019370Spst mfi_requeue_ ## name (struct mfi_command *cm) \ 46198948Sobrien { \ 46298948Sobrien if ((cm->cm_flags & MFI_ON_MFIQ_MASK) != 0) { \ 46398948Sobrien printf("command %p is on another queue, " \ 46419370Spst "flags = %#x\n", cm, cm->cm_flags); \ 46598948Sobrien panic("command is on another queue"); \ 46698948Sobrien } \ 46798948Sobrien TAILQ_INSERT_HEAD(&cm->cm_sc->mfi_ ## name, cm, cm_link); \ 46898948Sobrien cm->cm_flags |= MFI_ON_ ## index; \ 46998948Sobrien MFIQ_ADD(cm->cm_sc, index); \ 47098948Sobrien } \ 47119370Spst static __inline struct mfi_command * \ 47298948Sobrien mfi_dequeue_ ## name (struct mfi_softc *sc) \ 47398948Sobrien { \ 47419370Spst struct mfi_command *cm; \ 47598948Sobrien \ 47619370Spst if ((cm = TAILQ_FIRST(&sc->mfi_ ## name)) != NULL) { \ 47719370Spst if ((cm->cm_flags & MFI_ON_ ## index) == 0) { \ 47898948Sobrien printf("command %p not in queue, " \ 47998948Sobrien "flags = %#x, bit = %#x\n", cm, \ 48098948Sobrien cm->cm_flags, MFI_ON_ ## index); \ 48198948Sobrien panic("command not in queue"); \ 48298948Sobrien } \ 48398948Sobrien TAILQ_REMOVE(&sc->mfi_ ## name, cm, cm_link); \ 48419370Spst cm->cm_flags &= ~MFI_ON_ ## index; \ 48598948Sobrien MFIQ_REMOVE(sc, index); \ 48698948Sobrien } \ 487130809Smarcel return (cm); \ 48898948Sobrien } \ 48998948Sobrien static __inline void \ 49098948Sobrien mfi_remove_ ## name (struct mfi_command *cm) \ 49198948Sobrien { \ 49298948Sobrien if ((cm->cm_flags & MFI_ON_ ## index) == 0) { \ 49319370Spst printf("command %p not in queue, flags = %#x, " \ 49419370Spst "bit = %#x\n", cm, cm->cm_flags, \ 495130809Smarcel MFI_ON_ ## index); \ 496130809Smarcel panic("command not in queue"); \ 497130809Smarcel } \ 498130809Smarcel TAILQ_REMOVE(&cm->cm_sc->mfi_ ## name, cm, cm_link); \ 499130809Smarcel cm->cm_flags &= ~MFI_ON_ ## index; \ 500130809Smarcel MFIQ_REMOVE(cm->cm_sc, index); \ 501130809Smarcel } \ 502130809Smarcelstruct hack 503130809Smarcel 504130809SmarcelMFIQ_COMMAND_QUEUE(free, MFIQ_FREE); 505130809SmarcelMFIQ_COMMAND_QUEUE(ready, MFIQ_READY); 506130809SmarcelMFIQ_COMMAND_QUEUE(busy, MFIQ_BUSY); 507130809Smarcel 508130809Smarcelstatic __inline void 509130809Smarcelmfi_initq_bio(struct mfi_softc *sc) 510130809Smarcel{ 511130809Smarcel bioq_init(&sc->mfi_bioq); 512130809Smarcel MFIQ_INIT(sc, MFIQ_BIO); 51398948Sobrien} 51498948Sobrien 51598948Sobrienstatic __inline void 51698948Sobrienmfi_enqueue_bio(struct mfi_softc *sc, struct bio *bp) 51798948Sobrien{ 51819370Spst bioq_insert_tail(&sc->mfi_bioq, bp); 519130809Smarcel MFIQ_ADD(sc, MFIQ_BIO); 52098948Sobrien} 52119370Spst 52298948Sobrienstatic __inline struct bio * 52398948Sobrienmfi_dequeue_bio(struct mfi_softc *sc) 52419370Spst{ 52519370Spst struct bio *bp; 52698948Sobrien 52798948Sobrien if ((bp = bioq_first(&sc->mfi_bioq)) != NULL) { 52898948Sobrien bioq_remove(&sc->mfi_bioq, bp); 52919370Spst MFIQ_REMOVE(sc, MFIQ_BIO); 53098948Sobrien } 53198948Sobrien return (bp); 53298948Sobrien} 53398948Sobrien 53498948Sobrien/* 535130809Smarcel * This is from the original scsi_extract_sense() in CAM. It's copied 536130809Smarcel * here because CAM now uses a non-inline version that follows more complex 53798948Sobrien * additions to the SPC spec, and we don't want to force a dependency on 53898948Sobrien * the CAM module for such a trivial action. 53998948Sobrien */ 54019370Spststatic __inline void 54119370Spstmfi_extract_sense(struct scsi_sense_data_fixed *sense, 54298948Sobrien int *error_code, int *sense_key, int *asc, int *ascq) 54398948Sobrien{ 54498948Sobrien 54598948Sobrien *error_code = sense->error_code & SSD_ERRCODE; 54698948Sobrien *sense_key = sense->flags & SSD_KEY; 54798948Sobrien *asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0; 54819370Spst *ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0; 54998948Sobrien} 55098948Sobrien 55119370Spststatic __inline void 55298948Sobrienmfi_print_sense(struct mfi_softc *sc, void *sense) 55398948Sobrien{ 55498948Sobrien int error, key, asc, ascq; 55598948Sobrien 55698948Sobrien mfi_extract_sense((struct scsi_sense_data_fixed *)sense, 55798948Sobrien &error, &key, &asc, &ascq); 55898948Sobrien device_printf(sc->mfi_dev, "sense error %d, sense_key %d, " 55998948Sobrien "asc %d, ascq %d\n", error, key, asc, ascq); 56098948Sobrien} 56198948Sobrien 56298948Sobrien 56319370Spst#define MFI_WRITE4(sc, reg, val) bus_space_write_4((sc)->mfi_btag, \ 56419370Spst sc->mfi_bhandle, (reg), (val)) 56598948Sobrien#define MFI_READ4(sc, reg) bus_space_read_4((sc)->mfi_btag, \ 56698948Sobrien (sc)->mfi_bhandle, (reg)) 56798948Sobrien#define MFI_WRITE2(sc, reg, val) bus_space_write_2((sc)->mfi_btag, \ 56819370Spst sc->mfi_bhandle, (reg), (val)) 56998948Sobrien#define MFI_READ2(sc, reg) bus_space_read_2((sc)->mfi_btag, \ 57098948Sobrien (sc)->mfi_bhandle, (reg)) 57198948Sobrien#define MFI_WRITE1(sc, reg, val) bus_space_write_1((sc)->mfi_btag, \ 57298948Sobrien sc->mfi_bhandle, (reg), (val)) 57398948Sobrien#define MFI_READ1(sc, reg) bus_space_read_1((sc)->mfi_btag, \ 57498948Sobrien (sc)->mfi_bhandle, (reg)) 57519370Spst 57619370SpstMALLOC_DECLARE(M_MFIBUF); 57798948SobrienSYSCTL_DECL(_hw_mfi); 57819370Spst 57998948Sobrien#define MFI_RESET_WAIT_TIME 180 58098948Sobrien#define MFI_CMD_TIMEOUT 30 58119370Spst#define MFI_SYS_PD_IO 0 58298948Sobrien#define MFI_LD_IO 1 58398948Sobrien#define MFI_SKINNY_MEMORY 0x02000000 58498948Sobrien#define MFI_MAXPHYS (128 * 1024) 58598948Sobrien 58698948Sobrien#ifdef MFI_DEBUG 58719370Spstextern void mfi_print_cmd(struct mfi_command *cm); 58898948Sobrienextern void mfi_dump_cmds(struct mfi_softc *sc); 58998948Sobrienextern void mfi_validate_sg(struct mfi_softc *, struct mfi_command *, const char *, int ); 59098948Sobrien#define MFI_PRINT_CMD(cm) mfi_print_cmd(cm) 59198948Sobrien#define MFI_DUMP_CMDS(sc) mfi_dump_cmds(sc) 59219370Spst#define MFI_VALIDATE_CMD(sc, cm) mfi_validate_sg(sc, cm, __FUNCTION__, __LINE__) 59319370Spst#else 59419370Spst#define MFI_PRINT_CMD(cm) 59598948Sobrien#define MFI_DUMP_CMDS(sc) 59619370Spst#define MFI_VALIDATE_CMD(sc, cm) 59798948Sobrien#endif 59898948Sobrien 59998948Sobrienextern void mfi_release_command(struct mfi_command *cm); 60098948Sobrien 60119370Spst#endif /* _MFIVAR_H */ 60298948Sobrien