#define SSP_SENSE_LEN_VALID (1<<1) #define SSP_RSP_LEN_VALID (1<<0) #ifdef ARAPAHO_TARGET_MODE #define DEFAULT_NUM_LUNS 1 #else #define DEFAULT_NUM_LUNS 2 #endif #define MAX_NUM_LUNS 511 /* 1 to 511, due to ReportLUNs */ /* SAS frame types */ #define SSP_CMD_FRAME 0x06 #define SSP_TASK_FRAME 0x16 /* task managment defines */ #define TM_ABORT_TASK (0x01) #define TM_ABORT_TASK_SET (0x02) #define TM_CLEAR_TASK_SET (0x04) #define TM_LOGICAL_UNIT_RESET (0x08) #define TM_TARGET_RESET (0x10) #define TM_CLEAR_ACA (0x40) #define TM_QUERY_TASK (0x80) /* ECHO_BYTES : is for inquires, report_luns, * rw buffer, etc. */ #define ECHO_BYTES 4096 #define BLOCK_LENGTH 512 #define BLOCK_BYTES_MIN 512 #define BLOCK_BYTES_MAX 520 /* BLOCKS_PER_SLICE : specifies the number of blocks for each sg element */ /* setup 4K scatter gather elements */ //#define BLOCKS_PER_SLICE 8 /* 4k sgel size */ //#define MPT3STM_SG_DEPTH 128 /* 512k transfers */ /* setup 16K scatter gather elements */ #define BLOCKS_PER_SLICE 32 /* 16k sgel size */ #define MPT3STM_SG_DEPTH 33 /* 512k transfers */ #define BYTES_PER_SLICE (BLOCKS_PER_SLICE * BLOCK_LENGTH) #define NUM_BLOCKS 2048 /* ramdisk size = 1MB */ #define NUM_BLOCKS_MIN BLOCKS_PER_SLICE #define NUM_BLOCKS_MAX 0x400000 /* 2GB max */ #define STM_NO_RESERVATIONS 0xFFFF /** * struct MPT_SGE - */ struct MPT_SGE { u32 length; dma_addr_t address; }; /** * struct MPT_SGL - * @data_direction: DMA_TO_DEVICE, DMA_FROM_DEVICE, DMA_BIDIRECTIONAL * @num_sges: number entries in this list * @length: total data length of this transfer * @sge: the sg elements * * The num_sges must be equal to or smaller than ioc->shost->sg_tablesize. */ struct MPT_SGL { enum dma_data_direction data_direction; u32 num_sges; u32 length; struct MPT_SGE sge[MPT3STM_SG_DEPTH]; }; /* io_state defines */ #define IO_STATE_POSTED (0x0001) #define IO_STATE_ABORTED (0x0002) #define IO_STATE_ABORT_IMM (0x0004) #define IO_STATE_TARGET_ASSIST_DATA_PEND (0x0008) #define IO_STATE_TARGET_ASSIST_STATUS_PEND (0x0010) #define IO_STATE_RESET (0x0020) #define INVALID_TAG (0xFFFF) #define ALL_TAG (0xFFFF) #define ALL_LUN (0xFFFFFFFF) #define ALL_INITIATOR (0xFFFF) /** * struct dma_access * @va: virtual address * @pa: physical address */ struct dma_access { void *va; dma_addr_t pa; }; #define CMD_IU_SIZE 64 #define CMD_RESPONSE_SIZE 64 /** * struct CMD - per command buffer private area */ struct CMD { struct MPT_SGL sgl; u64 lun; u16 tag; u16 tm_tag; /* task managment tag */ u16 tm_count; struct task_struct *cmd_thread; u16 initiator_handle; u8 phy_number; u8 msix_index; struct MPT3SAS_ADAPTER *ioc; u16 io_index; struct completion done; u16 status; spinlock_t status_lock; u16 smid; u8 out_of_order_cmp; u8 ta_wait_count; void *reply; u8 *cmd; struct dma_access response; u16 io_state; spinlock_t io_state_lock; #if defined(STMAPP_DELAY) int delay; #endif }; #define STM_DISK(x) (priv->luns[x]) #define STM_SAS_ADDR (ioc->sas_hba.sas_address) /** * struct DISK - per disk data */ struct DISK { struct dma_access *slice; /* ramdisk */ u64 max_slices; u8 is_initialized; #if defined(STMAPP_DELAY) int read_delay; int write_delay; #endif u8 ua_asc; u8 ua_ascq; u8 cache_control; u8 exception_control; u8 exception_method; u16 reservations_handle; /* p_disk->data : is for inquires, report_luns, * rw buffer, etc. * Please use the semaphore to lock access */ u16 io_index_locked_for_xfer; struct mutex data_mutex; struct dma_access data; u16 block_size; u16 new_block_size; u64 blk_cnt; u32 bytes_per_slice; u16 blocks_per_slice; ulong pages; }; struct change_event { Mpi2EventDataSasInitDevStatusChange_t event_data; struct MPT3SAS_ADAPTER *ioc; struct work_struct work; }; /** * struct MPT_STM_PRIV - per host data */ struct MPT_STM_PRIV { /* parameters for busy_emu */ struct timer_list return_busy_sense_timer; u8 return_busy_sense; #if defined(STM_RING_BUFFER) /* ring buffer debug */ struct stm_rb_element *ring_buffer; ulong rb_pages; u16 rb_head; #endif int num_cmd_buffers; /* per command buffer private area */ struct CMD *cmd_buffer; ulong cmd_buffer_pages; spinlock_t cmd_buffer_lock; /* command buffer dma'ble memory */ struct dma_access cmd; int cmd_sz; /* response buffer dma'ble memory */ struct dma_access response; int response_sz; /* memory for reply's*/ void *reply; /* host sas address */ u64 sas_address; u8 stopping_threads; struct DISK *luns[MAX_NUM_LUNS]; }; static inline void putlun(u8 *x, u16 y, u64 z) { if (z > 255) x[y] = (z >> 8) + 0x40; else x[y] = 0; x[y+1] = (u8)z; } #define getlun(x, y) (((x[y] << 8) + x[y+1]) & 0x3fff) #define get2bytes(x, y) (((x[y] << 8) + x[y+1]) & 0xffff) #define get3bytes(x, y) (((x[y] << 16) + (x[y+1] << 8) + x[y+2]) & 0xffffff) #define get4bytes(x, y) (((x[y] << 24) + (x[y+1] << 16) + \ (x[y+2] << 8) + x[y+3]) & 0xffffffff) #define get8bytes(x, y) (((u64)get4bytes(x, y) << 32) + get4bytes(x, y+4)) /****************************************************************************/ #if defined(STM_RING_BUFFER) /* STM Ring Buffer Define Types */ #define STM_RB_CMD_BUFFER (0x01) /* command buffer */ #define STM_RB_TA_DATA (0x02) /* target assist with data */ #define STM_RB_TA_STATUS (0x03) /* target assist with status */ #define STM_RB_TA_REPLY_SUCCESS (0x04) /* target assist success reply */ #define STM_RB_TA_REPLY_ERROR (0x05) /* target assist error reply */ #define STM_RB_ABORT_REQ (0x06) /* abort request */ #define STM_RB_ABORT_REPLY (0x07) /* abort reply */ #define STM_RB_POST_SINGLE (0x08) /* post single command buffer */ #define STM_RB_POST_ALL (0x09) /* post all command buffers */ #define STM_RB_POST_ALL_REPLY (0x0A) /* post all replies */ /* max ring buffer size */ #define STM_RB_MAXSIZE (1000) /** * struct stm_rb_element - circular ring buffer entry description * @type: set to `STM_RB_XXX defined above` * @abort_type: EXACT_IO_REQUEST, IO_REQUEST_AND_IO, EXACT_IO, ALL_IO * @io_index: io_index associated to the command buffer * @frame_type: either SSP_CMD_FRAME or SSP_TASK_FRAME * @opcode: task management function or SSP CDB[0] * @smid: system message id * @tag: tag assoicated to this request * * ring buffer used for debugging target mode issues */ struct stm_rb_element { u8 type; u8 abort_type; u16 io_index; union { struct { u8 frame_type; u8 opcode; } a; u16 smid; } request_info; u16 tag; }; #endif /* STM_RING_BUFFER */ /* these MPI header structs need to be big endian */ struct ssp_cmd_buffer { u8 FrameType; /* 0x00 */ u8 Reserved1; /* 0x01 */ __be16 InitiatorConnectionTag; /* 0x02 */ __be32 HashedSourceSASAddress; /* 0x04 */ __be16 Reserved2; /* 0x08 */ __be16 Flags; /* 0x0A */ __be32 Reserved3; /* 0x0C */ __be16 Tag; /* 0x10 */ __be16 TargetPortTransferTag; /* 0x12 */ __be32 DataOffset; /* 0x14 */ /* COMMAND information unit starts here */ u8 LogicalUnitNumber[8]; /* 0x18 */ u8 Reserved4; /* 0x20 */ u8 TaskAttribute; /* lower 3 bits */ /* 0x21 */ u8 Reserved5; /* 0x22 */ u8 AdditionalCDBLength; /* upper 5 bits */ /* 0x23 */ u8 CDB[16]; /* 0x24 */ /* Additional CDB bytes extend past the CDB field */ }; struct ssp_task_buffer { u8 FrameType; /* 0x00 */ u8 Reserved1; /* 0x01 */ __be16 InitiatorConnectionTag; /* 0x02 */ __be32 HashedSourceSASAddress; /* 0x04 */ __be16 Reserved2; /* 0x08 */ __be16 Flags; /* 0x0A */ __be32 Reserved3; /* 0x0C */ __be16 Tag; /* 0x10 */ __be16 TargetPortTransferTag; /* 0x12 */ __be32 DataOffset; /* 0x14 */ /* TASK information unit starts here */ u8 LogicalUnitNumber[8]; /* 0x18 */ __be16 Reserved4; /* 0x20 */ u8 TaskManagementFunction; /* 0x22 */ u8 Reserved5; /* 0x23 */ __be16 ManagedTaskTag; /* 0x24 */ __be16 Reserved6; /* 0x26 */ __be32 Reserved7; /* 0x28 */ __be32 Reserved8; /* 0x2C */ __be32 Reserved9; /* 0x30 */ }; struct ssp_rsp_iu { __be32 Reserved0[6]; /* reserved for SSP header */ /* 0x00 */ /* start of RESPONSE information unit */ __be32 Reserved1; /* 0x18 */ __be32 Reserved2; /* 0x1C */ __be16 Reserved3; /* 0x20 */ u8 DataPres; /* lower 2 bits */ /* 0x22 */ u8 Status; /* 0x23 */ __be32 Reserved4; /* 0x24 */ __be32 SenseDataLength; /* 0x28 */ __be32 ResponseDataLength; /* 0x2C */ /* start of Response or Sense Data (size may vary dynamically) */ u8 ResponseSenseData[4]; /* 0x30 */ }; extern void mpt3sas_base_stm_register_callback_handler( struct STM_CALLBACK stm_funcs); extern void mpt3sas_base_stm_release_callback_handler(void); extern void mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid); extern int mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, enum reset_type type); extern int mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER *ioc, Mpi2SasIoUnitControlReply_t *mpi_reply, Mpi2SasIoUnitControlRequest_t *mpi_request); extern u32 mpt3sas_base_get_iocstate(struct MPT3SAS_ADAPTER *ioc, int cooked); extern void mpt3sas_stm_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid); extern u16 mpt3sas_stm_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx, struct scsi_cmnd *scmd); extern u16 mpt3sas_base_get_smid(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx); extern u16 mpt3sas_base_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx, struct scsi_cmnd *scmd); extern void *mpt3sas_base_get_reply_virt_addr(struct MPT3SAS_ADAPTER *ioc, u32 phys_addr); extern void *mpt3sas_base_get_msg_frame(struct MPT3SAS_ADAPTER *ioc, u16 smid); extern void mpt3sas_base_put_smid_target_assist(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 io_index); extern int mpt3sas_config_get_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page); extern int mpt3sas_config_set_sas_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz);