Mercurial > illumos > illumos-gate
changeset 11194:e429b4b36c3c
6873566 Core File Gathering/Firmware Diag Buffer support
6892600 Add support for IOC Fault Watchdog in Solaris SAS2 storage driver (mpt_sas)
6892609 Add support for REG_ACCESS IOCTL in Solaris SAS2 storage driver (mpt_sas)
6892984 Add support for "System Shutdown Initiated" RAID action
6892985 Add support for extended FW Diag Buffer in Solaris SAS2 storage driver (mpt_sas)
6892995 Add time stamp to IOC Init message for Solaris SAS2 storage driver (mpt_sas)
6870234 Erie: Upgrading Firmware of Erie HBA with Solaris sas2flash turns HBA inactive
6901371 IOCTL path locks if issued after forcing fault
line wrap: on
line diff
--- a/usr/src/cmd/mdb/common/modules/mpt_sas/mpt_sas.c Wed Nov 25 12:30:41 2009 +0800 +++ b/usr/src/cmd/mdb/common/modules/mpt_sas/mpt_sas.c Wed Nov 25 13:05:40 2009 +0800 @@ -36,6 +36,8 @@ #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h> #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h> #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h> +#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h> +#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h> #pragma pack() #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
--- a/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c Wed Nov 25 12:30:41 2009 +0800 +++ b/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c Wed Nov 25 13:05:40 2009 +0800 @@ -80,6 +80,8 @@ #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h> #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h> #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h> +#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h> +#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h> #pragma pack() /* @@ -224,6 +226,31 @@ uint32_t dataout_size, short timeout, int mode); static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl); +static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, + uint32_t unique_id); +static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd); +static int mptsas_post_fw_diag_buffer(mptsas_t *mpt, + mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code); +static int mptsas_release_fw_diag_buffer(mptsas_t *mpt, + mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, + uint32_t diag_type); +static int mptsas_diag_register(mptsas_t *mpt, + mptsas_fw_diag_register_t *diag_register, uint32_t *return_code); +static int mptsas_diag_unregister(mptsas_t *mpt, + mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code); +static int mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, + uint32_t *return_code); +static int mptsas_diag_read_buffer(mptsas_t *mpt, + mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, + uint32_t *return_code, int ioctl_mode); +static int mptsas_diag_release(mptsas_t *mpt, + mptsas_fw_diag_release_t *diag_release, uint32_t *return_code); +static int mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, + uint8_t *diag_action, uint32_t length, uint32_t *return_code, + int ioctl_mode); +static int mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *data, + int mode); + static int mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, int cmdlen, int tgtlen, int statuslen, int kf); static void mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd); @@ -344,6 +371,8 @@ static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, int mode, int *rval); static void mptsas_record_event(void *args); +static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, + int mode); static void mptsas_hash_init(mptsas_hash_table_t *hashtab); static void mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen); @@ -489,7 +518,7 @@ }; -#define MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.20" +#define MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.21" static struct modldrv modldrv = { &mod_driverops, /* Type of module. This one is a driver */ @@ -1089,6 +1118,7 @@ cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL); cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL); cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL); + cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL); mutex_init_done++; /* @@ -1460,6 +1490,7 @@ cv_destroy(&mpt->m_passthru_cv); cv_destroy(&mpt->m_fw_cv); cv_destroy(&mpt->m_config_cv); + cv_destroy(&mpt->m_fw_diag_cv); } mptsas_free_handshake_msg(mpt); mptsas_hba_fini(mpt); @@ -1504,6 +1535,11 @@ mutex_enter(&mpt->m_mutex); + /* + * Send RAID action system shutdown to sync IR + */ + mptsas_raid_action_system_shutdown(mpt); + if (mpt->m_suspended++) { mutex_exit(&mpt->m_mutex); return (DDI_SUCCESS); @@ -1719,6 +1755,11 @@ } mutex_enter(&mpt->m_mutex); + + /* + * Send RAID action system shutdown to sync IR + */ + mptsas_raid_action_system_shutdown(mpt); MPTSAS_DISABLE_INTR(mpt); mutex_exit(&mpt->m_mutex); mptsas_rem_intrs(mpt); @@ -1877,6 +1918,7 @@ cv_destroy(&mpt->m_passthru_cv); cv_destroy(&mpt->m_fw_cv); cv_destroy(&mpt->m_config_cv); + cv_destroy(&mpt->m_fw_diag_cv); pci_config_teardown(&mpt->m_config_handle); if (mpt->m_tran) { @@ -2167,13 +2209,13 @@ } int -mptsas_passthru_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep) +mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep) { ddi_dma_attr_t attrs; uint_t ncookie; size_t alloc_len; - attrs = mpt->m_msg_dma_attr; + attrs = mpt->m_io_dma_attr; attrs.dma_attr_sgllen = 1; ASSERT(dma_statep != NULL); @@ -2210,7 +2252,7 @@ } void -mptsas_passthru_dma_free(mptsas_dma_alloc_state_t *dma_statep) +mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep) { ASSERT(dma_statep != NULL); if (dma_statep->handle != NULL) { @@ -4515,8 +4557,8 @@ mpt->m_polled_intr = 1; /* - * Get the current interrupt mask. When re-enabling ints, set mask to - * saved value. + * Get the current interrupt mask and disable interrupts. When + * re-enabling ints, set mask to saved value. */ int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask); MPTSAS_DISABLE_INTR(mpt); @@ -4538,6 +4580,7 @@ drv_usecwait(1000); continue; } + /* * The reply is valid, process it according to its * type. @@ -4548,10 +4591,13 @@ mpt->m_post_index = 0; } + /* + * Update the global reply index + */ ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); - mpt->m_polled_intr = 0; + /* * Re-enable interrupts and quit. */ @@ -4645,11 +4691,12 @@ { pMpi2AddressReplyDescriptor_t address_reply; pMPI2DefaultReply_t reply; + mptsas_fw_diagnostic_buffer_t *pBuffer; uint32_t reply_addr; - uint16_t SMID; + uint16_t SMID, iocstatus, action; mptsas_slots_t *slots = mpt->m_active; mptsas_cmd_t *cmd = NULL; - uint8_t function; + uint8_t function, buffer_type; m_replyh_arg_t *args; int reply_frame_no; @@ -4685,7 +4732,24 @@ * don't get slot information and command for events since these values * don't exist */ - if (function != MPI2_FUNCTION_EVENT_NOTIFICATION) { + if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) && + (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) { + /* + * If this is a raid action reply for system shutdown just exit + * because the reply doesn't matter. Signal that we got the + * reply even though it's not really necessary since we're + * shutting down. + */ + if (function == MPI2_FUNCTION_RAID_ACTION) { + action = ddi_get16(mpt->m_acc_reply_frame_hdl, + &reply->FunctionDependent1); + if (action == + MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED) { + cv_broadcast(&mpt->m_fw_diag_cv); + return; + } + } + /* * This could be a TM reply, which use the last allocated SMID, * so allow for that. @@ -4709,11 +4773,13 @@ return; } if ((cmd->cmd_flags & CFLAG_PASSTHRU) || - (cmd->cmd_flags & CFLAG_CONFIG)) { + (cmd->cmd_flags & CFLAG_CONFIG) || + (cmd->cmd_flags & CFLAG_FW_DIAG)) { cmd->cmd_rfm = reply_addr; cmd->cmd_flags |= CFLAG_FINISHED; cv_broadcast(&mpt->m_passthru_cv); cv_broadcast(&mpt->m_config_cv); + cv_broadcast(&mpt->m_fw_diag_cv); return; } else if (!(cmd->cmd_flags & CFLAG_FW_CMD)) { mptsas_remove_cmd(mpt, cmd); @@ -4781,6 +4847,43 @@ &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index); } return; + case MPI2_FUNCTION_DIAG_BUFFER_POST: + /* + * If SMID is 0, this implies that the reply is due to a + * release function with a status that the buffer has been + * released. Set the buffer flags accordingly. + */ + if (SMID == 0) { + iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, + &reply->IOCStatus); + buffer_type = ddi_get8(mpt->m_acc_reply_frame_hdl, + &(((pMpi2DiagBufferPostReply_t)reply)->BufferType)); + if (iocstatus == MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED) { + pBuffer = + &mpt->m_fw_diag_buffer_list[buffer_type]; + pBuffer->valid_data = TRUE; + pBuffer->owned_by_firmware = FALSE; + pBuffer->immediate = FALSE; + } + } else { + /* + * Normal handling of diag post reply with SMID. + */ + cmd = slots->m_slot[SMID]; + + /* + * print warning and return if the slot is empty + */ + if (cmd == NULL) { + mptsas_log(mpt, CE_WARN, "?NULL command for " + "address reply in slot %d", SMID); + return; + } + cmd->cmd_rfm = reply_addr; + cmd->cmd_flags |= CFLAG_FINISHED; + cv_broadcast(&mpt->m_fw_diag_cv); + } + return; default: mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function); break; @@ -5163,10 +5266,9 @@ mutex_enter(&mpt->m_mutex); /* - * If interrupts are shared by two channels then - * check whether this interrupt is genuinely for this - * channel by making sure first the chip is in high - * power state. + * If interrupts are shared by two channels then check whether this + * interrupt is genuinely for this channel by making sure first the + * chip is in high power state. */ if ((mpt->m_options & MPTSAS_OPT_PM) && (mpt->m_power_level != PM_LEVEL_D0)) { @@ -5211,13 +5313,16 @@ /* * The reply is valid, process it according to its - * type. Also, set a flag for updated the reply index + * type. Also, set a flag for updating the reply index * after they've all been processed. */ did_reply = TRUE; mptsas_process_intr(mpt, reply_desc_union); + /* + * Increment post index and roll over if needed. + */ if (++mpt->m_post_index == mpt->m_post_queue_depth) { mpt->m_post_index = 0; } @@ -5238,16 +5343,13 @@ NDBG1(("mptsas_intr complete")); /* - * If no helper threads are created, process the doneq in ISR. - * If helpers are created, use the doneq length as a metric to - * measure the load on the interrupt CPU. If it is long enough, - * which indicates the load is heavy, then we deliver the IO - * completions to the helpers. - * this measurement has some limitations although, it is simple - * and straightforward and works well for most of the cases at - * present. - */ - + * If no helper threads are created, process the doneq in ISR. If + * helpers are created, use the doneq length as a metric to measure the + * load on the interrupt CPU. If it is long enough, which indicates the + * load is heavy, then we deliver the IO completions to the helpers. + * This measurement has some limitations, although it is simple and + * straightforward and works well for most of the cases at present. + */ if (!mpt->m_doneq_thread_n || (mpt->m_doneq_len <= mpt->m_doneq_length_threshold)) { mptsas_doneq_empty(mpt); @@ -7400,6 +7502,19 @@ cmd = next_cmd; continue; } + if (cmd->cmd_flags & CFLAG_FW_DIAG) { + if (mptsas_save_cmd(mpt, cmd) == TRUE) { + /* + * Send the FW Diag request and delete if from + * the waitq. + */ + cmd->cmd_flags |= CFLAG_PREPARED; + mptsas_waitq_delete(mpt, cmd); + mptsas_start_diag(mpt, cmd); + } + cmd = next_cmd; + continue; + } ptgt = cmd->cmd_tgt_addr; if (ptgt && (ptgt->m_t_throttle == DRAIN_THROTTLE) && @@ -8294,8 +8409,27 @@ if ((cmd = slots->m_slot[slot]) == NULL) continue; - if (cmd->cmd_flags & CFLAG_CMDIOC) + if (cmd->cmd_flags & CFLAG_CMDIOC) { + /* + * Need to make sure to tell everyone that might be + * waiting on this command that it's going to fail. If + * we get here, this command will never timeout because + * the active command table is going to be re-allocated, + * so there will be nothing to check against a time out. + * Instead, mark the command as failed due to reset. + */ + mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, + STAT_BUS_RESET); + if ((cmd->cmd_flags & CFLAG_PASSTHRU) || + (cmd->cmd_flags & CFLAG_CONFIG) || + (cmd->cmd_flags & CFLAG_FW_DIAG)) { + cmd->cmd_flags |= CFLAG_FINISHED; + cv_broadcast(&mpt->m_passthru_cv); + cv_broadcast(&mpt->m_config_cv); + cv_broadcast(&mpt->m_fw_diag_cv); + } continue; + } mptsas_log(mpt, CE_NOTE, "mptsas_flush_hba discovered non-NULL " "cmd in slot %d", slot); @@ -8312,10 +8446,12 @@ while ((cmd = mptsas_waitq_rm(mpt)) != NULL) { mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); if ((cmd->cmd_flags & CFLAG_PASSTHRU) || - (cmd->cmd_flags & CFLAG_CONFIG)) { + (cmd->cmd_flags & CFLAG_CONFIG) || + (cmd->cmd_flags & CFLAG_FW_DIAG)) { cmd->cmd_flags |= CFLAG_FINISHED; cv_broadcast(&mpt->m_passthru_cv); cv_broadcast(&mpt->m_config_cv); + cv_broadcast(&mpt->m_fw_diag_cv); } else { mptsas_doneq_add(mpt, cmd); } @@ -8854,6 +8990,7 @@ #endif mptsas_t *mpt; + uint32_t doorbell; NDBG30(("mptsas_watch")); @@ -8874,6 +9011,20 @@ } /* + * Check if controller is in a FAULT state. If so, reset it. + */ + doorbell = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell); + if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { + doorbell &= MPI2_DOORBELL_DATA_MASK; + mptsas_log(mpt, CE_WARN, "MPT Firmware Fault, " + "code: %04x", doorbell); + if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { + mptsas_log(mpt, CE_WARN, "Reset failed" + "after fault was detected"); + } + } + + /* * For now, always call mptsas_watchsubr. */ mptsas_watchsubr(mpt); @@ -8928,7 +9079,8 @@ } } if ((cmd->cmd_flags & CFLAG_PASSTHRU) || - (cmd->cmd_flags & CFLAG_CONFIG)) { + (cmd->cmd_flags & CFLAG_CONFIG) || + (cmd->cmd_flags & CFLAG_FW_DIAG)) { cmd->cmd_active_timeout -= mptsas_scsi_watchdog_tick; if (cmd->cmd_active_timeout <= 0) { @@ -8939,6 +9091,7 @@ CFLAG_TIMEOUT); cv_broadcast(&mpt->m_passthru_cv); cv_broadcast(&mpt->m_config_cv); + cv_broadcast(&mpt->m_fw_diag_cv); } } } @@ -9379,8 +9532,7 @@ if (data_size != 0) { data_dma_state.size = data_size; - if (mptsas_passthru_dma_alloc(mpt, &data_dma_state) != - DDI_SUCCESS) { + if (mptsas_dma_alloc(mpt, &data_dma_state) != DDI_SUCCESS) { status = ENOMEM; mptsas_log(mpt, CE_WARN, "failed to alloc DMA " "resource"); @@ -9405,8 +9557,7 @@ if (dataout_size != 0) { dataout_dma_state.size = dataout_size; - if (mptsas_passthru_dma_alloc(mpt, &dataout_dma_state) != - DDI_SUCCESS) { + if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) { status = ENOMEM; mptsas_log(mpt, CE_WARN, "failed to alloc DMA " "resource"); @@ -9607,7 +9758,7 @@ DDI_SERVICE_UNAFFECTED); status = EFAULT; } - mptsas_passthru_dma_free(&data_dma_state); + mptsas_dma_free(&data_dma_state); } if (pt_flags & MPTSAS_DATAOUT_ALLOCATED) { if (mptsas_check_dma_handle(dataout_dma_state.handle) != @@ -9616,7 +9767,7 @@ DDI_SERVICE_UNAFFECTED); status = EFAULT; } - mptsas_passthru_dma_free(&dataout_dma_state); + mptsas_dma_free(&dataout_dma_state); } if (pt_flags & MPTSAS_CMD_TIMEOUT) { if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { @@ -9667,6 +9818,928 @@ } } +static uint8_t +mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id) +{ + uint8_t index; + + for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) { + if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) { + return (index); + } + } + + return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND); +} + +static void +mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd) +{ + pMpi2DiagBufferPostRequest_t pDiag_post_msg; + pMpi2DiagReleaseRequest_t pDiag_release_msg; + struct scsi_pkt *pkt = cmd->cmd_pkt; + mptsas_diag_request_t *diag = pkt->pkt_ha_private; + uint32_t request_desc_low, i; + + ASSERT(mutex_owned(&mpt->m_mutex)); + + /* + * Form the diag message depending on the post or release function. + */ + if (diag->function == MPI2_FUNCTION_DIAG_BUFFER_POST) { + pDiag_post_msg = (pMpi2DiagBufferPostRequest_t) + (mpt->m_req_frame + (mpt->m_req_frame_size * + cmd->cmd_slot)); + bzero(pDiag_post_msg, mpt->m_req_frame_size); + ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->Function, + diag->function); + ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->BufferType, + diag->pBuffer->buffer_type); + ddi_put8(mpt->m_acc_req_frame_hdl, + &pDiag_post_msg->ExtendedType, + diag->pBuffer->extended_type); + ddi_put32(mpt->m_acc_req_frame_hdl, + &pDiag_post_msg->BufferLength, + diag->pBuffer->buffer_data.size); + for (i = 0; i < (sizeof (pDiag_post_msg->ProductSpecific) / 4); + i++) { + ddi_put32(mpt->m_acc_req_frame_hdl, + &pDiag_post_msg->ProductSpecific[i], + diag->pBuffer->product_specific[i]); + } + ddi_put32(mpt->m_acc_req_frame_hdl, + &pDiag_post_msg->BufferAddress.Low, + (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress + & 0xffffffffull)); + ddi_put32(mpt->m_acc_req_frame_hdl, + &pDiag_post_msg->BufferAddress.High, + (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress + >> 32)); + } else { + pDiag_release_msg = (pMpi2DiagReleaseRequest_t) + (mpt->m_req_frame + (mpt->m_req_frame_size * + cmd->cmd_slot)); + bzero(pDiag_release_msg, mpt->m_req_frame_size); + ddi_put8(mpt->m_acc_req_frame_hdl, + &pDiag_release_msg->Function, diag->function); + ddi_put8(mpt->m_acc_req_frame_hdl, + &pDiag_release_msg->BufferType, + diag->pBuffer->buffer_type); + } + + /* + * Send the message + */ + (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, + DDI_DMA_SYNC_FORDEV); + request_desc_low = (cmd->cmd_slot << 16) + + MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; + cmd->cmd_rfm = NULL; + MPTSAS_START_CMD(mpt, request_desc_low, 0); + if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != + DDI_SUCCESS) || + (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != + DDI_SUCCESS)) { + ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); + } +} + +static int +mptsas_post_fw_diag_buffer(mptsas_t *mpt, + mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code) +{ + mptsas_diag_request_t diag; + int status, slot_num, post_flags = 0; + mptsas_cmd_t *cmd = NULL; + struct scsi_pkt *pkt; + pMpi2DiagBufferPostReply_t reply; + uint16_t iocstatus; + uint32_t iocloginfo, transfer_length; + + /* + * If buffer is not enabled, just leave. + */ + *return_code = MPTSAS_FW_DIAG_ERROR_POST_FAILED; + if (!pBuffer->enabled) { + status = DDI_FAILURE; + goto out; + } + + /* + * Clear some flags initially. + */ + pBuffer->force_release = FALSE; + pBuffer->valid_data = FALSE; + pBuffer->owned_by_firmware = FALSE; + + /* + * Get a cmd buffer from the cmd buffer pool + */ + if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { + status = DDI_FAILURE; + mptsas_log(mpt, CE_NOTE, "command pool is full: Post FW Diag"); + goto out; + } + post_flags |= MPTSAS_REQUEST_POOL_CMD; + + bzero((caddr_t)cmd, sizeof (*cmd)); + bzero((caddr_t)pkt, scsi_pkt_size()); + + cmd->ioc_cmd_slot = (uint32_t)(slot_num); + + diag.pBuffer = pBuffer; + diag.function = MPI2_FUNCTION_DIAG_BUFFER_POST; + + /* + * Form a blank cmd/pkt to store the acknowledgement message + */ + pkt->pkt_ha_private = (opaque_t)&diag; + pkt->pkt_flags = FLAG_HEAD; + pkt->pkt_time = 60; + cmd->cmd_pkt = pkt; + cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; + + /* + * Save the command in a slot + */ + if (mptsas_save_cmd(mpt, cmd) == TRUE) { + /* + * Once passthru command get slot, set cmd_flags + * CFLAG_PREPARED. + */ + cmd->cmd_flags |= CFLAG_PREPARED; + mptsas_start_diag(mpt, cmd); + } else { + mptsas_waitq_add(mpt, cmd); + } + + while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { + cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); + } + + if (cmd->cmd_flags & CFLAG_TIMEOUT) { + status = DDI_FAILURE; + mptsas_log(mpt, CE_WARN, "Post FW Diag command timeout"); + goto out; + } + + /* + * cmd_rfm points to the reply message if a reply was given. Check the + * IOCStatus to make sure everything went OK with the FW diag request + * and set buffer flags. + */ + if (cmd->cmd_rfm) { + post_flags |= MPTSAS_ADDRESS_REPLY; + (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, + DDI_DMA_SYNC_FORCPU); + reply = (pMpi2DiagBufferPostReply_t)(mpt->m_reply_frame + + (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr)); + + /* + * Get the reply message data + */ + iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, + &reply->IOCStatus); + iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, + &reply->IOCLogInfo); + transfer_length = ddi_get32(mpt->m_acc_reply_frame_hdl, + &reply->TransferLength); + + /* + * If post failed quit. + */ + if (iocstatus != MPI2_IOCSTATUS_SUCCESS) { + status = DDI_FAILURE; + NDBG13(("post FW Diag Buffer failed: IOCStatus=0x%x, " + "IOCLogInfo=0x%x, TransferLength=0x%x", iocstatus, + iocloginfo, transfer_length)); + goto out; + } + + /* + * Post was successful. + */ + pBuffer->valid_data = TRUE; + pBuffer->owned_by_firmware = TRUE; + *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; + status = DDI_SUCCESS; + } + +out: + /* + * Put the reply frame back on the free queue, increment the free + * index, and write the new index to the free index register. But only + * if this reply is an ADDRESS reply. + */ + if (post_flags & MPTSAS_ADDRESS_REPLY) { + ddi_put32(mpt->m_acc_free_queue_hdl, + &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], + cmd->cmd_rfm); + (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, + DDI_DMA_SYNC_FORDEV); + if (++mpt->m_free_index == mpt->m_free_queue_depth) { + mpt->m_free_index = 0; + } + ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, + mpt->m_free_index); + } + if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { + mptsas_remove_cmd(mpt, cmd); + post_flags &= (~MPTSAS_REQUEST_POOL_CMD); + } + if (post_flags & MPTSAS_REQUEST_POOL_CMD) { + mptsas_return_to_pool(mpt, cmd); + } + + return (status); +} + +static int +mptsas_release_fw_diag_buffer(mptsas_t *mpt, + mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, + uint32_t diag_type) +{ + mptsas_diag_request_t diag; + int status, slot_num, rel_flags = 0; + mptsas_cmd_t *cmd = NULL; + struct scsi_pkt *pkt; + pMpi2DiagReleaseReply_t reply; + uint16_t iocstatus; + uint32_t iocloginfo; + + /* + * If buffer is not enabled, just leave. + */ + *return_code = MPTSAS_FW_DIAG_ERROR_RELEASE_FAILED; + if (!pBuffer->enabled) { + mptsas_log(mpt, CE_NOTE, "This buffer type is not supported " + "by the IOC"); + status = DDI_FAILURE; + goto out; + } + + /* + * Clear some flags initially. + */ + pBuffer->force_release = FALSE; + pBuffer->valid_data = FALSE; + pBuffer->owned_by_firmware = FALSE; + + /* + * Get a cmd buffer from the cmd buffer pool + */ + if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { + status = DDI_FAILURE; + mptsas_log(mpt, CE_NOTE, "command pool is full: Release FW " + "Diag"); + goto out; + } + rel_flags |= MPTSAS_REQUEST_POOL_CMD; + + bzero((caddr_t)cmd, sizeof (*cmd)); + bzero((caddr_t)pkt, scsi_pkt_size()); + + cmd->ioc_cmd_slot = (uint32_t)(slot_num); + + diag.pBuffer = pBuffer; + diag.function = MPI2_FUNCTION_DIAG_RELEASE; + + /* + * Form a blank cmd/pkt to store the acknowledgement message + */ + pkt->pkt_ha_private = (opaque_t)&diag; + pkt->pkt_flags = FLAG_HEAD; + pkt->pkt_time = 60; + cmd->cmd_pkt = pkt; + cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; + + /* + * Save the command in a slot + */ + if (mptsas_save_cmd(mpt, cmd) == TRUE) { + /* + * Once passthru command get slot, set cmd_flags + * CFLAG_PREPARED. + */ + cmd->cmd_flags |= CFLAG_PREPARED; + mptsas_start_diag(mpt, cmd); + } else { + mptsas_waitq_add(mpt, cmd); + } + + while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { + cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); + } + + if (cmd->cmd_flags & CFLAG_TIMEOUT) { + status = DDI_FAILURE; + mptsas_log(mpt, CE_WARN, "Release FW Diag command timeout"); + goto out; + } + + /* + * cmd_rfm points to the reply message if a reply was given. Check the + * IOCStatus to make sure everything went OK with the FW diag request + * and set buffer flags. + */ + if (cmd->cmd_rfm) { + rel_flags |= MPTSAS_ADDRESS_REPLY; + (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, + DDI_DMA_SYNC_FORCPU); + reply = (pMpi2DiagReleaseReply_t)(mpt->m_reply_frame + + (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr)); + + /* + * Get the reply message data + */ + iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, + &reply->IOCStatus); + iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, + &reply->IOCLogInfo); + + /* + * If release failed quit. + */ + if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) || + pBuffer->owned_by_firmware) { + status = DDI_FAILURE; + NDBG13(("release FW Diag Buffer failed: " + "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, + iocloginfo)); + goto out; + } + + /* + * Release was successful. + */ + *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; + status = DDI_SUCCESS; + + /* + * If this was for an UNREGISTER diag type command, clear the + * unique ID. + */ + if (diag_type == MPTSAS_FW_DIAG_TYPE_UNREGISTER) { + pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; + } + } + +out: + /* + * Put the reply frame back on the free queue, increment the free + * index, and write the new index to the free index register. But only + * if this reply is an ADDRESS reply. + */ + if (rel_flags & MPTSAS_ADDRESS_REPLY) { + ddi_put32(mpt->m_acc_free_queue_hdl, + &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], + cmd->cmd_rfm); + (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, + DDI_DMA_SYNC_FORDEV); + if (++mpt->m_free_index == mpt->m_free_queue_depth) { + mpt->m_free_index = 0; + } + ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, + mpt->m_free_index); + } + if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { + mptsas_remove_cmd(mpt, cmd); + rel_flags &= (~MPTSAS_REQUEST_POOL_CMD); + } + if (rel_flags & MPTSAS_REQUEST_POOL_CMD) { + mptsas_return_to_pool(mpt, cmd); + } + + return (status); +} + +static int +mptsas_diag_register(mptsas_t *mpt, mptsas_fw_diag_register_t *diag_register, + uint32_t *return_code) +{ + mptsas_fw_diagnostic_buffer_t *pBuffer; + uint8_t extended_type, buffer_type, i; + uint32_t buffer_size; + uint32_t unique_id; + int status; + + ASSERT(mutex_owned(&mpt->m_mutex)); + + extended_type = diag_register->ExtendedType; + buffer_type = diag_register->BufferType; + buffer_size = diag_register->RequestedBufferSize; + unique_id = diag_register->UniqueId; + + /* + * Check for valid buffer type + */ + if (buffer_type >= MPI2_DIAG_BUF_TYPE_COUNT) { + *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; + return (DDI_FAILURE); + } + + /* + * Get the current buffer and look up the unique ID. The unique ID + * should not be found. If it is, the ID is already in use. + */ + i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); + pBuffer = &mpt->m_fw_diag_buffer_list[buffer_type]; + if (i != MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { + *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; + return (DDI_FAILURE); + } + + /* + * The buffer's unique ID should not be registered yet, and the given + * unique ID cannot be 0. + */ + if ((pBuffer->unique_id != MPTSAS_FW_DIAG_INVALID_UID) || + (unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { + *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; + return (DDI_FAILURE); + } + + /* + * If this buffer is already posted as immediate, just change owner. + */ + if (pBuffer->immediate && pBuffer->owned_by_firmware && + (pBuffer->unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { + pBuffer->immediate = FALSE; + pBuffer->unique_id = unique_id; + return (DDI_SUCCESS); + } + + /* + * Post a new buffer after checking if it's enabled. The DMA buffer + * that is allocated will be contiguous (sgl_len = 1). + */ + if (!pBuffer->enabled) { + *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; + return (DDI_FAILURE); + } + bzero(&pBuffer->buffer_data, sizeof (mptsas_dma_alloc_state_t)); + pBuffer->buffer_data.size = buffer_size; + if (mptsas_dma_alloc(mpt, &pBuffer->buffer_data) != DDI_SUCCESS) { + mptsas_log(mpt, CE_WARN, "failed to alloc DMA resource for " + "diag buffer: size = %d bytes", buffer_size); + *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; + return (DDI_FAILURE); + } + + /* + * Copy the given info to the diag buffer and post the buffer. + */ + pBuffer->buffer_type = buffer_type; + pBuffer->immediate = FALSE; + if (buffer_type == MPI2_DIAG_BUF_TYPE_TRACE) { + for (i = 0; i < (sizeof (pBuffer->product_specific) / 4); + i++) { + pBuffer->product_specific[i] = + diag_register->ProductSpecific[i]; + } + } + pBuffer->extended_type = extended_type; + pBuffer->unique_id = unique_id; + status = mptsas_post_fw_diag_buffer(mpt, pBuffer, return_code); + + if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != + DDI_SUCCESS) { + mptsas_log(mpt, CE_WARN, "Check of DMA handle failed in " + "mptsas_diag_register."); + ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); + status = DDI_FAILURE; + } + + /* + * In case there was a failure, free the DMA buffer. + */ + if (status == DDI_FAILURE) { + mptsas_dma_free(&pBuffer->buffer_data); + } + + return (status); +} + +static int +mptsas_diag_unregister(mptsas_t *mpt, + mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code) +{ + mptsas_fw_diagnostic_buffer_t *pBuffer; + uint8_t i; + uint32_t unique_id; + int status; + + ASSERT(mutex_owned(&mpt->m_mutex)); + + unique_id = diag_unregister->UniqueId; + + /* + * Get the current buffer and look up the unique ID. The unique ID + * should be there. + */ + i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); + if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { + *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; + return (DDI_FAILURE); + } + + pBuffer = &mpt->m_fw_diag_buffer_list[i]; + + /* + * Try to release the buffer from FW before freeing it. If release + * fails, don't free the DMA buffer in case FW tries to access it + * later. If buffer is not owned by firmware, can't release it. + */ + if (!pBuffer->owned_by_firmware) { + status = DDI_SUCCESS; + } else { + status = mptsas_release_fw_diag_buffer(mpt, pBuffer, + return_code, MPTSAS_FW_DIAG_TYPE_UNREGISTER); + } + + /* + * At this point, return the current status no matter what happens with + * the DMA buffer. + */ + pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; + if (status == DDI_SUCCESS) { + if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != + DDI_SUCCESS) { + mptsas_log(mpt, CE_WARN, "Check of DMA handle failed " + "in mptsas_diag_unregister."); + ddi_fm_service_impact(mpt->m_dip, + DDI_SERVICE_UNAFFECTED); + } + mptsas_dma_free(&pBuffer->buffer_data); + } + + return (status); +} + +static int +mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, + uint32_t *return_code) +{ + mptsas_fw_diagnostic_buffer_t *pBuffer; + uint8_t i; + uint32_t unique_id; + + ASSERT(mutex_owned(&mpt->m_mutex)); + + unique_id = diag_query->UniqueId; + + /* + * If ID is valid, query on ID. + * If ID is invalid, query on buffer type. + */ + if (unique_id == MPTSAS_FW_DIAG_INVALID_UID) { + i = diag_query->BufferType; + if (i >= MPI2_DIAG_BUF_TYPE_COUNT) { + *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; + return (DDI_FAILURE); + } + } else { + i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); + if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { + *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; + return (DDI_FAILURE); + } + } + + /* + * Fill query structure with the diag buffer info. + */ + pBuffer = &mpt->m_fw_diag_buffer_list[i]; + diag_query->BufferType = pBuffer->buffer_type; + diag_query->ExtendedType = pBuffer->extended_type; + if (diag_query->BufferType == MPI2_DIAG_BUF_TYPE_TRACE) { + for (i = 0; i < (sizeof (diag_query->ProductSpecific) / 4); + i++) { + diag_query->ProductSpecific[i] = + pBuffer->product_specific[i]; + } + } + diag_query->TotalBufferSize = pBuffer->buffer_data.size; + diag_query->DriverAddedBufferSize = 0; + diag_query->UniqueId = pBuffer->unique_id; + diag_query->ApplicationFlags = 0; + diag_query->DiagnosticFlags = 0; + + /* + * Set/Clear application flags + */ + if (pBuffer->immediate) { + diag_query->ApplicationFlags &= ~MPTSAS_FW_DIAG_FLAG_APP_OWNED; + } else { + diag_query->ApplicationFlags |= MPTSAS_FW_DIAG_FLAG_APP_OWNED; + } + if (pBuffer->valid_data || pBuffer->owned_by_firmware) { + diag_query->ApplicationFlags |= + MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; + } else { + diag_query->ApplicationFlags &= + ~MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; + } + if (pBuffer->owned_by_firmware) { + diag_query->ApplicationFlags |= + MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; + } else { + diag_query->ApplicationFlags &= + ~MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; + } + + return (DDI_SUCCESS); +} + +static int +mptsas_diag_read_buffer(mptsas_t *mpt, + mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, + uint32_t *return_code, int ioctl_mode) +{ + mptsas_fw_diagnostic_buffer_t *pBuffer; + uint8_t i, *pData; + uint32_t unique_id, byte; + int status; + + ASSERT(mutex_owned(&mpt->m_mutex)); + + unique_id = diag_read_buffer->UniqueId; + + /* + * Get the current buffer and look up the unique ID. The unique ID + * should be there. + */ + i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); + if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { + *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; + return (DDI_FAILURE); + } + + pBuffer = &mpt->m_fw_diag_buffer_list[i]; + + /* + * Make sure requested read is within limits + */ + if (diag_read_buffer->StartingOffset + diag_read_buffer->BytesToRead > + pBuffer->buffer_data.size) { + *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; + return (DDI_FAILURE); + } + + /* + * Copy the requested data from DMA to the diag_read_buffer. The DMA + * buffer that was allocated is one contiguous buffer. + */ + pData = (uint8_t *)(pBuffer->buffer_data.memp + + diag_read_buffer->StartingOffset); + (void) ddi_dma_sync(pBuffer->buffer_data.handle, 0, 0, + DDI_DMA_SYNC_FORCPU); + for (byte = 0; byte < diag_read_buffer->BytesToRead; byte++) { + if (ddi_copyout(pData + byte, ioctl_buf + byte, 1, ioctl_mode) + != 0) { + return (DDI_FAILURE); + } + } + diag_read_buffer->Status = 0; + + /* + * Set or clear the Force Release flag. + */ + if (pBuffer->force_release) { + diag_read_buffer->Flags |= MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; + } else { + diag_read_buffer->Flags &= ~MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; + } + + /* + * If buffer is to be reregistered, make sure it's not already owned by + * firmware first. + */ + status = DDI_SUCCESS; + if (!pBuffer->owned_by_firmware) { + if (diag_read_buffer->Flags & MPTSAS_FW_DIAG_FLAG_REREGISTER) { + status = mptsas_post_fw_diag_buffer(mpt, pBuffer, + return_code); + } + } + + return (status); +} + +static int +mptsas_diag_release(mptsas_t *mpt, mptsas_fw_diag_release_t *diag_release, + uint32_t *return_code) +{ + mptsas_fw_diagnostic_buffer_t *pBuffer; + uint8_t i; + uint32_t unique_id; + int status; + + ASSERT(mutex_owned(&mpt->m_mutex)); + + unique_id = diag_release->UniqueId; + + /* + * Get the current buffer and look up the unique ID. The unique ID + * should be there. + */ + i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); + if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { + *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; + return (DDI_FAILURE); + } + + pBuffer = &mpt->m_fw_diag_buffer_list[i]; + + /* + * If buffer is not owned by firmware, it's already been released. + */ + if (!pBuffer->owned_by_firmware) { + *return_code = MPTSAS_FW_DIAG_ERROR_ALREADY_RELEASED; + return (DDI_FAILURE); + } + + /* + * Release the buffer. + */ + status = mptsas_release_fw_diag_buffer(mpt, pBuffer, return_code, + MPTSAS_FW_DIAG_TYPE_RELEASE); + return (status); +} + +static int +mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, uint8_t *diag_action, + uint32_t length, uint32_t *return_code, int ioctl_mode) +{ + mptsas_fw_diag_register_t diag_register; + mptsas_fw_diag_unregister_t diag_unregister; + mptsas_fw_diag_query_t diag_query; + mptsas_diag_read_buffer_t diag_read_buffer; + mptsas_fw_diag_release_t diag_release; + int status = DDI_SUCCESS; + uint32_t original_return_code, read_buf_len; + + ASSERT(mutex_owned(&mpt->m_mutex)); + + original_return_code = *return_code; + *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; + + switch (action) { + case MPTSAS_FW_DIAG_TYPE_REGISTER: + if (!length) { + *return_code = + MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; + status = DDI_FAILURE; + break; + } + if (ddi_copyin(diag_action, &diag_register, + sizeof (diag_register), ioctl_mode) != 0) { + return (DDI_FAILURE); + } + status = mptsas_diag_register(mpt, &diag_register, + return_code); + break; + + case MPTSAS_FW_DIAG_TYPE_UNREGISTER: + if (length < sizeof (diag_unregister)) { + *return_code = + MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; + status = DDI_FAILURE; + break; + } + if (ddi_copyin(diag_action, &diag_unregister, + sizeof (diag_unregister), ioctl_mode) != 0) { + return (DDI_FAILURE); + } + status = mptsas_diag_unregister(mpt, &diag_unregister, + return_code); + break; + + case MPTSAS_FW_DIAG_TYPE_QUERY: + if (length < sizeof (diag_query)) { + *return_code = + MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; + status = DDI_FAILURE; + break; + } + if (ddi_copyin(diag_action, &diag_query, + sizeof (diag_query), ioctl_mode) != 0) { + return (DDI_FAILURE); + } + status = mptsas_diag_query(mpt, &diag_query, + return_code); + if (status == DDI_SUCCESS) { + if (ddi_copyout(&diag_query, diag_action, + sizeof (diag_query), ioctl_mode) != 0) { + return (DDI_FAILURE); + } + } + break; + + case MPTSAS_FW_DIAG_TYPE_READ_BUFFER: + if (ddi_copyin(diag_action, &diag_read_buffer, + sizeof (diag_read_buffer) - 4, ioctl_mode) != 0) { + return (DDI_FAILURE); + } + read_buf_len = sizeof (diag_read_buffer) - + sizeof (diag_read_buffer.DataBuffer) + + diag_read_buffer.BytesToRead; + if (length < read_buf_len) { + *return_code = + MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; + status = DDI_FAILURE; + break; + } + status = mptsas_diag_read_buffer(mpt, + &diag_read_buffer, diag_action + + sizeof (diag_read_buffer) - 4, return_code, + ioctl_mode); + if (status == DDI_SUCCESS) { + if (ddi_copyout(&diag_read_buffer, diag_action, + sizeof (diag_read_buffer) - 4, ioctl_mode) + != 0) { + return (DDI_FAILURE); + } + } + break; + + case MPTSAS_FW_DIAG_TYPE_RELEASE: + if (length < sizeof (diag_release)) { + *return_code = + MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; + status = DDI_FAILURE; + break; + } + if (ddi_copyin(diag_action, &diag_release, + sizeof (diag_release), ioctl_mode) != 0) { + return (DDI_FAILURE); + } + status = mptsas_diag_release(mpt, &diag_release, + return_code); + break; + + default: + *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; + status = DDI_FAILURE; + break; + } + + if ((status == DDI_FAILURE) && + (original_return_code == MPTSAS_FW_DIAG_NEW) && + (*return_code != MPTSAS_FW_DIAG_ERROR_SUCCESS)) { + status = DDI_SUCCESS; + } + + return (status); +} + +static int +mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *user_data, int mode) +{ + int status; + mptsas_diag_action_t driver_data; + + ASSERT(mutex_owned(&mpt->m_mutex)); + + /* + * Copy the user data to a driver data buffer. + */ + if (ddi_copyin(user_data, &driver_data, sizeof (mptsas_diag_action_t), + mode) == 0) { + /* + * Send diag action request if Action is valid + */ + if (driver_data.Action == MPTSAS_FW_DIAG_TYPE_REGISTER || + driver_data.Action == MPTSAS_FW_DIAG_TYPE_UNREGISTER || + driver_data.Action == MPTSAS_FW_DIAG_TYPE_QUERY || + driver_data.Action == MPTSAS_FW_DIAG_TYPE_READ_BUFFER || + driver_data.Action == MPTSAS_FW_DIAG_TYPE_RELEASE) { + status = mptsas_do_diag_action(mpt, driver_data.Action, + (void *)(uintptr_t)driver_data.PtrDiagAction, + driver_data.Length, &driver_data.ReturnCode, + mode); + if (status == DDI_SUCCESS) { + if (ddi_copyout(&driver_data.ReturnCode, + &user_data->ReturnCode, + sizeof (user_data->ReturnCode), mode) + != 0) { + status = EFAULT; + } else { + status = 0; + } + } else { + status = EIO; + } + } else { + status = EINVAL; + } + } else { + status = EFAULT; + } + + return (status); +} + /* * This routine handles the "event query" ioctl. */ @@ -9879,6 +10952,57 @@ } static int +mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, int mode) +{ + int status = 0; + mptsas_reg_access_t driverdata; + + mutex_enter(&mpt->m_mutex); + if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { + switch (driverdata.Command) { + /* + * IO access is not supported. + */ + case REG_IO_READ: + case REG_IO_WRITE: + mptsas_log(mpt, CE_WARN, "IO access is not " + "supported. Use memory access."); + status = EINVAL; + break; + + case REG_MEM_READ: + driverdata.RegData = ddi_get32(mpt->m_datap, + (uint32_t *)(void *)mpt->m_reg + + driverdata.RegOffset); + if (ddi_copyout(&driverdata.RegData, + &data->RegData, + sizeof (driverdata.RegData), mode) != 0) { + mptsas_log(mpt, CE_WARN, "Register " + "Read Failed"); + status = EFAULT; + } + break; + + case REG_MEM_WRITE: + ddi_put32(mpt->m_datap, + (uint32_t *)(void *)mpt->m_reg + + driverdata.RegOffset, + driverdata.RegData); + break; + + default: + status = EINVAL; + break; + } + } else { + status = EFAULT; + } + + mutex_exit(&mpt->m_mutex); + return (status); +} + +static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, int *rval) { @@ -10020,6 +11144,23 @@ } mutex_exit(&mpt->m_mutex); break; + case MPTIOCTL_DIAG_ACTION: + /* + * The user has done a diag buffer action. Call our + * routine which does this. Only allow one diag action + * at one time. + */ + mutex_enter(&mpt->m_mutex); + if (mpt->m_diag_action_in_progress) { + mutex_exit(&mpt->m_mutex); + return (EBUSY); + } + mpt->m_diag_action_in_progress = 1; + status = mptsas_diag_action(mpt, + (mptsas_diag_action_t *)data, mode); + mpt->m_diag_action_in_progress = 0; + mutex_exit(&mpt->m_mutex); + break; case MPTIOCTL_EVENT_QUERY: /* * The user has done an event query. Call our routine @@ -10044,6 +11185,14 @@ status = mptsas_event_report(mpt, (mptsas_event_report_t *)data, mode, rval); break; + case MPTIOCTL_REG_ACCESS: + /* + * The user has requested register access. Call our + * routine which does this. + */ + status = mptsas_reg_access(mpt, + (mptsas_reg_access_t *)data, mode); + break; default: status = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval); @@ -10157,23 +11306,6 @@ uint32_t i; mptsas_slots_t *new_active; - if (first_time == FALSE) { - /* - * De-allocate buffers before re-allocating them using the - * latest IOC facts. - */ - mptsas_hba_fini(mpt); - - /* - * Setup configuration space - */ - if (mptsas_config_space_init(mpt) == FALSE) { - mptsas_log(mpt, CE_WARN, "mptsas_config_space_init " - "failed!"); - goto fail; - } - } - /* * Check to see if the firmware image is valid */ @@ -10190,14 +11322,31 @@ mptsas_log(mpt, CE_WARN, "hard reset failed!"); goto fail; } + + if (first_time == FALSE) { + /* + * De-allocate buffers before re-allocating them using the + * latest IOC facts. + */ + mptsas_hba_fini(mpt); + + /* + * Setup configuration space + */ + if (mptsas_config_space_init(mpt) == FALSE) { + mptsas_log(mpt, CE_WARN, "mptsas_config_space_init " + "failed!"); + goto fail; + } + } + /* * IOC facts can change after a diag reset so all buffers that are * based on these numbers must be de-allocated and re-allocated. Get * new IOC facts each time chip is initialized. */ if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) { - mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts " - "failed"); + mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed"); goto fail; } /* @@ -10230,35 +11379,23 @@ } /* - * Allocate request message frames + * Allocate request message frames, reply free queue, reply descriptor + * post queue, and reply message frames using latest IOC facts. */ if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) { - mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames " - "failed"); + mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed"); goto fail; } - /* - * Allocate reply free queue - */ if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) { - mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue " - "failed!"); + mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!"); goto fail; } - /* - * Allocate reply descriptor post queue - */ if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) { - mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue " - "failed!"); + mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!"); goto fail; } - /* - * Allocate reply message frames - */ if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) { - mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames " - "failed!"); + mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames failed!"); goto fail; } @@ -10274,8 +11411,8 @@ mpt->m_max_replies, KM_SLEEP); /* - * Initialize reply post index and request index. Reply free index is - * initialized after the next loop. + * Initialize reply post index. Reply free index is initialized after + * the next loop. */ mpt->m_post_index = 0; @@ -10870,6 +12007,7 @@ kmem_free(inq83, inq83_len); return (sata_guid); } + static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, uchar_t page, unsigned char *buf, int len, int *reallen, uchar_t evpd) @@ -11182,7 +12320,7 @@ } else { rval = DDI_FAILURE; } -out: + kmem_free(sd_inq, SUN_INQSIZE); return (rval); } @@ -11473,7 +12611,6 @@ rval = DDI_FAILURE; } -out: kmem_free(sd_inq, SUN_INQSIZE); return (rval); }
--- a/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_impl.c Wed Nov 25 12:30:41 2009 +0800 +++ b/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_impl.c Wed Nov 25 13:05:40 2009 +0800 @@ -74,6 +74,7 @@ #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h> #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h> #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h> +#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h> #pragma pack() /* @@ -871,11 +872,11 @@ saved_HCB_size = ddi_get32(mpt->m_datap, &mpt->m_reg->HCBSize); /* - * Set Reset Adapter bit and wait 30 mSeconds. + * Set Reset Adapter bit and wait 50 mSeconds. */ diag_reg |= MPI2_DIAG_RESET_ADAPTER; ddi_put32(mpt->m_datap, &mpt->m_reg->HostDiagnostic, diag_reg); - drv_usecwait(30000); + drv_usecwait(50000); /* * Poll, waiting for Reset Adapter bit to clear. 300 Seconds max @@ -931,9 +932,9 @@ MPI2_WRSEQ_FLUSH_KEY_VALUE); /* - * Wait 20 seconds max for FW to come to ready state. + * Wait 60 seconds max for FW to come to ready state. */ - for (polls = 0; polls < 20000; polls++) { + for (polls = 0; polls < 60000; polls++) { ioc_state = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell); if (ioc_state == 0xFFFFFFFF) { mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); @@ -946,7 +947,7 @@ } drv_usecwait(1000); } - if (polls == 20000) { + if (polls == 60000) { mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); return (DDI_FAILURE); @@ -996,12 +997,12 @@ } /* - * Wait for chip to become ready + * Wait no more than 60 seconds for chip to become ready. */ while ((ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell) & MPI2_IOC_STATE_READY) == 0x0) { drv_usecwait(1000); - if (polls++ > 20000) { + if (polls++ > 60000) { goto hard_reset; } }
--- a/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_init.c Wed Nov 25 12:30:41 2009 +0800 +++ b/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_init.c Wed Nov 25 13:05:40 2009 +0800 @@ -72,6 +72,7 @@ #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h> #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h> #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h> +#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h> #pragma pack() /* * private header files. @@ -174,6 +175,7 @@ uint16_t queueSize, queueDiff; int simple_sge_main; int simple_sge_next; + uint32_t capabilities; bzero(memp, sizeof (*factsreply)); factsreply = (void *)memp; @@ -263,7 +265,7 @@ mpt->m_post_queue_depth = queueSize; /* - * Set up other stuff. + * Set up max chain depth. */ mpt->m_max_chain_depth = ddi_get8(accessp, &factsreply->MaxChainDepth); @@ -273,7 +275,6 @@ /* * Calculate max frames per request based on DMA S/G length. */ - simple_sge_main = MPTSAS_MAX_FRAME_SGES64(mpt) - 1; simple_sge_next = mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64) - 1; @@ -285,6 +286,39 @@ mpt->m_max_request_frames++; } + /* + * Check if controller supports FW diag buffers and set flag to enable + * each type. + */ + capabilities = ddi_get32(accessp, &factsreply->IOCCapabilities); + if (capabilities & MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER) { + mpt->m_fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_TRACE].enabled = + TRUE; + } + if (capabilities & MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER) { + mpt->m_fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_SNAPSHOT]. + enabled = TRUE; + } + if (capabilities & MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER) { + mpt->m_fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_EXTENDED]. + enabled = TRUE; + } + + /* + * Check if controller supports replaying events when issuing Message + * Unit Reset and set flag to enable MUR. + */ + if (capabilities & MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY) { + mpt->m_event_replay = TRUE; + } + + /* + * Check if controller supports IR. + */ + if (capabilities & MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) { + mpt->m_ir_capable = TRUE; + } + return (DDI_SUCCESS); } @@ -560,6 +594,8 @@ pMpi2IOCInitRequest_t init; int numbytes; + timespec_t time; + uint64_t mSec; bzero(memp, sizeof (*init)); init = (void *)memp; @@ -594,6 +630,18 @@ ddi_put32(accessp, &init->ReplyFreeQueueAddress.Low, (uint32_t)mpt->m_free_queue_dma_addr); + /* + * Fill in the timestamp with the number of milliseconds since midnight + * of January 1, 1970 UT (Greenwich Mean Time). Time is returned in + * seconds and nanoseconds. Translate both to milliseconds and add + * them together to get total milliseconds. + */ + gethrestime(&time); + mSec = time.tv_sec * MILLISEC; + mSec += (time.tv_nsec / MICROSEC); + ddi_put32(accessp, &init->TimeStamp.High, (uint32_t)(mSec >> 32)); + ddi_put32(accessp, &init->TimeStamp.Low, (uint32_t)mSec); + numbytes = sizeof (*init); /*
--- a/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_raid.c Wed Nov 25 12:30:41 2009 +0800 +++ b/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_raid.c Wed Nov 25 13:05:40 2009 +0800 @@ -77,6 +77,8 @@ #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h> #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h> #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h> +#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h> +#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h> #pragma pack() @@ -557,6 +559,114 @@ return (rval); } +/* + * The only RAID Action needed throughout the driver is for System Shutdown. + * Since this is the only RAID Action and because this Action does not require + * waiting for a reply, make this a non-generic function. If it turns out that + * other RAID Actions are required later, a generic function should be used. + */ +void +mptsas_raid_action_system_shutdown(mptsas_t *mpt) +{ + pMpi2RaidActionRequest_t action; + uint8_t ir_active = FALSE; + mptsas_slots_t *slots = mpt->m_active; + int config, vol, action_flags = 0; + mptsas_cmd_t *cmd; + struct scsi_pkt *pkt; + uint32_t request_desc_low; + + ASSERT(mutex_owned(&mpt->m_mutex)); + + /* + * Before doing the system shutdown RAID Action, make sure that the IOC + * supports IR and make sure there is a valid volume for the request. + */ + if (mpt->m_ir_capable) { + for (config = 0; config < slots->m_num_raid_configs; + config++) { + for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { + if (slots->m_raidconfig[config].m_raidvol[vol]. + m_israid) { + ir_active = TRUE; + break; + } + } + } + } + if (!ir_active) { + return; + } + + /* + * Get a command from the pool. + */ + if (mptsas_request_from_pool(mpt, &cmd, &pkt) == -1) { + mptsas_log(mpt, CE_NOTE, "command pool is full for RAID " + "action request"); + return; + } + action_flags |= MPTSAS_REQUEST_POOL_CMD; + + bzero((caddr_t)cmd, sizeof (*cmd)); + bzero((caddr_t)pkt, scsi_pkt_size()); + + pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb[0]; + pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; + pkt->pkt_ha_private = (opaque_t)cmd; + pkt->pkt_flags = (FLAG_NOINTR | FLAG_HEAD); + pkt->pkt_time = 5; + cmd->cmd_pkt = pkt; + cmd->cmd_flags = CFLAG_CMDIOC; + + /* + * Send RAID Action. We don't care what the reply is so just exit + * after sending the request. This is just sent to the controller to + * keep the volume from having to resync the next time it starts. If + * the request doesn't work for whatever reason, we're not going to + * bother wondering why. + */ + if (mptsas_save_cmd(mpt, cmd) == TRUE) { + cmd->cmd_flags |= CFLAG_PREPARED; + /* + * Form message for raid action + */ + action = (pMpi2RaidActionRequest_t)(mpt->m_req_frame + + (mpt->m_req_frame_size * cmd->cmd_slot)); + bzero(action, mpt->m_req_frame_size); + action->Function = MPI2_FUNCTION_RAID_ACTION; + action->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; + + /* + * Send request + */ + (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, + DDI_DMA_SYNC_FORDEV); + request_desc_low = (cmd->cmd_slot << 16) + + MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; + MPTSAS_START_CMD(mpt, request_desc_low, 0); + + /* + * Even though reply does not matter, wait no more than 5 + * seconds here to get the reply just because we don't want to + * leave it hanging if it's coming. Use the FW diag cv. + */ + (void) cv_reltimedwait(&mpt->m_fw_diag_cv, &mpt->m_mutex, + drv_usectohz(5 * MICROSEC), TR_CLOCK_TICK); + } + + /* + * Be sure to deallocate cmd before leaving. + */ + if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { + mptsas_remove_cmd(mpt, cmd); + action_flags &= (~MPTSAS_REQUEST_POOL_CMD); + } + if (action_flags & MPTSAS_REQUEST_POOL_CMD) + mptsas_return_to_pool(mpt, cmd); + +} + int mptsas_delete_volume(mptsas_t *mpt, uint16_t volid) {
--- a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/mpi2.h Wed Nov 25 12:30:41 2009 +0800 +++ b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/mpi2.h Wed Nov 25 13:05:40 2009 +0800 @@ -53,7 +53,7 @@ * scatter/gather formats. * Creation Date: June 21, 2006 * - * mpi2.h Version: 02.00.11 + * mpi2.h Version: 02.00.13 * * Version History * --------------- @@ -90,6 +90,14 @@ * 10-02-08 02.00.10 Bumped MPI2_HEADER_VERSION_UNIT. * Moved LUN field defines from mpi2_init.h. * 01-19-09 02.00.11 Bumped MPI2_HEADER_VERSION_UNIT. + * 05-06-09 02.00.12 Bumped MPI2_HEADER_VERSION_UNIT. + * In all request and reply descriptors, replaced VF_ID + * field with MSIxIndex field. + * Removed DevHandle field from + * MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those + * bytes reserved. + * Added RAID Accelerator functionality. + * 07-30-09 02.00.13 Bumped MPI2_HEADER_VERSION_UNIT. * -------------------------------------------------------------------------- */ @@ -115,7 +123,7 @@ #define MPI2_VERSION_02_00 (0x0200) /* versioning for this MPI header set */ -#define MPI2_HEADER_VERSION_UNIT (0x0B) +#define MPI2_HEADER_VERSION_UNIT (0x0D) #define MPI2_HEADER_VERSION_DEV (0x00) #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI2_HEADER_VERSION_UNIT_SHIFT (8) @@ -302,7 +310,7 @@ typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR { U8 RequestFlags; /* 0x00 */ - U8 VF_ID; /* 0x01 */ + U8 MSIxIndex; /* 0x01 */ U16 SMID; /* 0x02 */ U16 LMID; /* 0x04 */ U16 DescriptorTypeDependent; /* 0x06 */ @@ -316,6 +324,7 @@ #define MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET (0x02) #define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY (0x06) #define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE (0x08) +#define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR (0x0A) #define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01) @@ -324,7 +333,7 @@ typedef struct _MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR { U8 RequestFlags; /* 0x00 */ - U8 VF_ID; /* 0x01 */ + U8 MSIxIndex; /* 0x01 */ U16 SMID; /* 0x02 */ U16 LMID; /* 0x04 */ U16 Reserved1; /* 0x06 */ @@ -338,7 +347,7 @@ typedef struct _MPI2_SCSI_IO_REQUEST_DESCRIPTOR { U8 RequestFlags; /* 0x00 */ - U8 VF_ID; /* 0x01 */ + U8 MSIxIndex; /* 0x01 */ U16 SMID; /* 0x02 */ U16 LMID; /* 0x04 */ U16 DevHandle; /* 0x06 */ @@ -351,7 +360,7 @@ typedef struct _MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR { U8 RequestFlags; /* 0x00 */ - U8 VF_ID; /* 0x01 */ + U8 MSIxIndex; /* 0x01 */ U16 SMID; /* 0x02 */ U16 LMID; /* 0x04 */ U16 IoIndex; /* 0x06 */ @@ -360,14 +369,30 @@ Mpi2SCSITargetRequestDescriptor_t, MPI2_POINTER pMpi2SCSITargetRequestDescriptor_t; + +/* RAID Accelerator Request Descriptor */ +typedef struct _MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR +{ + U8 RequestFlags; /* 0x00 */ + U8 MSIxIndex; /* 0x01 */ + U16 SMID; /* 0x02 */ + U16 LMID; /* 0x04 */ + U16 Reserved; /* 0x06 */ +} MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR, + MPI2_POINTER PTR_MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR, + Mpi2RAIDAcceleratorRequestDescriptor_t, + MPI2_POINTER pMpi2RAIDAcceleratorRequestDescriptor_t; + + /* union of Request Descriptors */ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION { - MPI2_DEFAULT_REQUEST_DESCRIPTOR Default; - MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR HighPriority; - MPI2_SCSI_IO_REQUEST_DESCRIPTOR SCSIIO; - MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget; - U64 Words; + MPI2_DEFAULT_REQUEST_DESCRIPTOR Default; + MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR HighPriority; + MPI2_SCSI_IO_REQUEST_DESCRIPTOR SCSIIO; + MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget; + MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator; + U64 Words; } MPI2_REQUEST_DESCRIPTOR_UNION, MPI2_POINTER PTR_MPI2_REQUEST_DESCRIPTOR_UNION, Mpi2RequestDescriptorUnion_t, MPI2_POINTER pMpi2RequestDescriptorUnion_t; @@ -378,19 +403,20 @@ typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR { U8 ReplyFlags; /* 0x00 */ - U8 VF_ID; /* 0x01 */ + U8 MSIxIndex; /* 0x01 */ U16 DescriptorTypeDependent1; /* 0x02 */ U32 DescriptorTypeDependent2; /* 0x04 */ } MPI2_DEFAULT_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_DEFAULT_REPLY_DESCRIPTOR, Mpi2DefaultReplyDescriptor_t, MPI2_POINTER pMpi2DefaultReplyDescriptor_t; /* defines for the ReplyFlags field */ -#define MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK (0x0F) -#define MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS (0x00) -#define MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY (0x01) -#define MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS (0x02) -#define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER (0x03) -#define MPI2_RPY_DESCRIPT_FLAGS_UNUSED (0x0F) +#define MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK (0x0F) +#define MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS (0x00) +#define MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY (0x01) +#define MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS (0x02) +#define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER (0x03) +#define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS (0x05) +#define MPI2_RPY_DESCRIPT_FLAGS_UNUSED (0x0F) /* values for marking a reply descriptor as unused */ #define MPI2_RPY_DESCRIPT_UNUSED_WORD0_MARK (0xFFFFFFFF) @@ -400,7 +426,7 @@ typedef struct _MPI2_ADDRESS_REPLY_DESCRIPTOR { U8 ReplyFlags; /* 0x00 */ - U8 VF_ID; /* 0x01 */ + U8 MSIxIndex; /* 0x01 */ U16 SMID; /* 0x02 */ U32 ReplyFrameAddress; /* 0x04 */ } MPI2_ADDRESS_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_ADDRESS_REPLY_DESCRIPTOR, @@ -413,10 +439,10 @@ typedef struct _MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR { U8 ReplyFlags; /* 0x00 */ - U8 VF_ID; /* 0x01 */ + U8 MSIxIndex; /* 0x01 */ U16 SMID; /* 0x02 */ U16 TaskTag; /* 0x04 */ - U16 DevHandle; /* 0x06 */ + U16 Reserved1; /* 0x06 */ } MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR, Mpi2SCSIIOSuccessReplyDescriptor_t, @@ -427,7 +453,7 @@ typedef struct _MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR { U8 ReplyFlags; /* 0x00 */ - U8 VF_ID; /* 0x01 */ + U8 MSIxIndex; /* 0x01 */ U16 SMID; /* 0x02 */ U8 SequenceNumber; /* 0x04 */ U8 Reserved1; /* 0x05 */ @@ -442,7 +468,7 @@ typedef struct _MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR { U8 ReplyFlags; /* 0x00 */ - U8 VF_ID; /* 0x01 */ + U8 MSIxIndex; /* 0x01 */ U8 VP_ID; /* 0x02 */ U8 Flags; /* 0x03 */ U16 InitiatorDevHandle; /* 0x04 */ @@ -456,15 +482,29 @@ #define MPI2_RPY_DESCRIPT_TCB_FLAGS_PHYNUM_MASK (0x3F) +/* RAID Accelerator Success Reply Descriptor */ +typedef struct _MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR +{ + U8 ReplyFlags; /* 0x00 */ + U8 MSIxIndex; /* 0x01 */ + U16 SMID; /* 0x02 */ + U32 Reserved; /* 0x04 */ +} MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR, + MPI2_POINTER PTR_MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR, + Mpi2RAIDAcceleratorSuccessReplyDescriptor_t, + MPI2_POINTER pMpi2RAIDAcceleratorSuccessReplyDescriptor_t; + + /* union of Reply Descriptors */ typedef union _MPI2_REPLY_DESCRIPTORS_UNION { - MPI2_DEFAULT_REPLY_DESCRIPTOR Default; - MPI2_ADDRESS_REPLY_DESCRIPTOR AddressReply; - MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR SCSIIOSuccess; - MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR TargetAssistSuccess; - MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer; - U64 Words; + MPI2_DEFAULT_REPLY_DESCRIPTOR Default; + MPI2_ADDRESS_REPLY_DESCRIPTOR AddressReply; + MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR SCSIIOSuccess; + MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR TargetAssistSuccess; + MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer; + MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR RAIDAcceleratorSuccess; + U64 Words; } MPI2_REPLY_DESCRIPTORS_UNION, MPI2_POINTER PTR_MPI2_REPLY_DESCRIPTORS_UNION, Mpi2ReplyDescriptorsUnion_t, MPI2_POINTER pMpi2ReplyDescriptorsUnion_t; @@ -503,6 +543,7 @@ #define MPI2_FUNCTION_DIAG_RELEASE (0x1E) /* Diagnostic Release */ #define MPI2_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24) /* Target Command Buffer Post Base */ #define MPI2_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25) /* Target Command Buffer Post List */ +#define MPI2_FUNCTION_RAID_ACCELERATOR (0x2C) /* RAID Accelerator */ @@ -600,12 +641,17 @@ #define MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED (0x00A0) +/**************************************************************************** +* RAID Accelerator values +****************************************************************************/ + +#define MPI2_IOCSTATUS_RAID_ACCEL_ERROR (0x00B0) /**************************************************************************** * IOCStatus flag to indicate that log info is available ****************************************************************************/ -#define MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE (0x8000) +#define MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE (0x8000) /**************************************************************************** * IOCLogInfo Types
--- a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h Wed Nov 25 12:30:41 2009 +0800 +++ b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h Wed Nov 25 13:05:40 2009 +0800 @@ -51,7 +51,7 @@ * Title: MPI Configuration messages and pages * Creation Date: November 10, 2006 * - * mpi2_cnfg.h Version: 02.00.10 + * mpi2_cnfg.h Version: 02.00.12 * * Version History * --------------- @@ -140,6 +140,18 @@ * Added MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED define. * Added PortGroups, DmaGroup, and ControlGroup fields to * SAS Device Page 0. + * 05-06-09 02.00.11 Added structures and defines for IO Unit Page 5 and IO + * Unit Page 6. + * Added expander reduced functionality data to SAS + * Expander Page 0. + * Added SAS PHY Page 2 and SAS PHY Page 3. + * 07-30-09 02.00.12 Added IO Unit Page 7. + * Added new device ids. + * Added SAS IO Unit Page 5. + * Added partial and slumber power management capable flags + * to SAS Device Page 0 Flags field. + * Added PhyInfo defines for power condition. + * Added Ethernet configuration pages. * -------------------------------------------------------------------------- */ @@ -222,6 +234,7 @@ #define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG (0x16) #define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING (0x17) #define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT (0x18) +#define MPI2_CONFIG_EXTPAGETYPE_ETHERNET (0x19) /***************************************************************************** @@ -308,6 +321,14 @@ #define MPI2_DPM_PGAD_START_ENTRY_MASK (0x0000FFFF) +/* Ethernet PageAddress format */ +#define MPI2_ETHERNET_PGAD_FORM_MASK (0xF0000000) +#define MPI2_ETHERNET_PGAD_FORM_IF_NUM (0x00000000) + +#define MPI2_ETHERNET_PGAD_IF_NUMBER_MASK (0x000000FF) + + + /**************************************************************************** * Configuration messages ****************************************************************************/ @@ -389,6 +410,15 @@ #define MPI2_MFGPAGE_DEVID_SAS2116_1 (0x0064) #define MPI2_MFGPAGE_DEVID_SAS2116_2 (0x0065) +#define MPI2_MFGPAGE_DEVID_SAS2208_1 (0x0080) +#define MPI2_MFGPAGE_DEVID_SAS2208_2 (0x0081) +#define MPI2_MFGPAGE_DEVID_SAS2208_3 (0x0082) +#define MPI2_MFGPAGE_DEVID_SAS2208_4 (0x0083) +#define MPI2_MFGPAGE_DEVID_SAS2208_5 (0x0084) +#define MPI2_MFGPAGE_DEVID_SAS2208_6 (0x0085) +#define MPI2_MFGPAGE_DEVID_SAS2208_7 (0x0086) +#define MPI2_MFGPAGE_DEVID_SAS2208_8 (0x0087) + /* Manufacturing Page 0 */ @@ -768,6 +798,117 @@ #define MPI2_IOUNITPAGE3_GPIO_SETTING_ON (0x0001) +/* IO Unit Page 5 */ + +/* + * Upper layer code (drivers, utilities, etc.) should leave this define set to + * one and check Header.PageLength or NumDmaEngines at runtime. + */ +#ifndef MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES +#define MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES (1) +#endif + +typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_5 +{ + MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */ + U64 RaidAcceleratorBufferBaseAddress; /* 0x04 */ + U64 RaidAcceleratorBufferSize; /* 0x0C */ + U64 RaidAcceleratorControlBaseAddress; /* 0x14 */ + U8 RAControlSize; /* 0x1C */ + U8 NumDmaEngines; /* 0x1D */ + U8 RAMinControlSize; /* 0x1E */ + U8 RAMaxControlSize; /* 0x1F */ + U32 Reserved1; /* 0x20 */ + U32 Reserved2; /* 0x24 */ + U32 Reserved3; /* 0x28 */ + U32 DmaEngineCapabilities[MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES]; /* 0x2C */ +} MPI2_CONFIG_PAGE_IO_UNIT_5, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_5, + Mpi2IOUnitPage5_t, MPI2_POINTER pMpi2IOUnitPage5_t; + +#define MPI2_IOUNITPAGE5_PAGEVERSION (0x00) + +/* defines for IO Unit Page 5 DmaEngineCapabilities field */ +#define MPI2_IOUNITPAGE5_DMA_CAP_MASK_MAX_REQUESTS (0xFF00) +#define MPI2_IOUNITPAGE5_DMA_CAP_SHIFT_MAX_REQUESTS (16) + +#define MPI2_IOUNITPAGE5_DMA_CAP_EEDP (0x0008) +#define MPI2_IOUNITPAGE5_DMA_CAP_PARITY_GENERATION (0x0004) +#define MPI2_IOUNITPAGE5_DMA_CAP_HASHING (0x0002) +#define MPI2_IOUNITPAGE5_DMA_CAP_ENCRYPTION (0x0001) + + +/* IO Unit Page 6 */ + +typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_6 +{ + MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */ + U16 Flags; /* 0x04 */ + U8 RAHostControlSize; /* 0x06 */ + U8 Reserved0; /* 0x07 */ + U64 RaidAcceleratorHostControlBaseAddress; /* 0x08 */ + U32 Reserved1; /* 0x10 */ + U32 Reserved2; /* 0x14 */ + U32 Reserved3; /* 0x18 */ +} MPI2_CONFIG_PAGE_IO_UNIT_6, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_6, + Mpi2IOUnitPage6_t, MPI2_POINTER pMpi2IOUnitPage6_t; + +#define MPI2_IOUNITPAGE6_PAGEVERSION (0x00) + +/* defines for IO Unit Page 6 Flags field */ +#define MPI2_IOUNITPAGE6_FLAGS_ENABLE_RAID_ACCELERATOR (0x0001) + + +/* IO Unit Page 7 */ + +typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 +{ + MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */ + U16 Reserved1; /* 0x04 */ + U8 PCIeWidth; /* 0x06 */ + U8 PCIeSpeed; /* 0x07 */ + U32 ProcessorState; /* 0x08 */ + U32 Reserved2; /* 0x0C */ + U16 IOCTemperature; /* 0x10 */ + U8 IOCTemperatureUnits; /* 0x12 */ + U8 IOCSpeed; /* 0x13 */ + U32 Reserved3; /* 0x14 */ +} MPI2_CONFIG_PAGE_IO_UNIT_7, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_7, + Mpi2IOUnitPage7_t, MPI2_POINTER pMpi2IOUnitPage7_t; + +#define MPI2_IOUNITPAGE7_PAGEVERSION (0x00) + +/* defines for IO Unit Page 7 PCIeWidth field */ +#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X1 (0x01) +#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X2 (0x02) +#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X4 (0x04) +#define MPI2_IOUNITPAGE7_PCIE_WIDTH_X8 (0x08) + +/* defines for IO Unit Page 7 PCIeSpeed field */ +#define MPI2_IOUNITPAGE7_PCIE_SPEED_2_5_GBPS (0x00) +#define MPI2_IOUNITPAGE7_PCIE_SPEED_5_0_GBPS (0x01) +#define MPI2_IOUNITPAGE7_PCIE_SPEED_8_0_GBPS (0x02) + +/* defines for IO Unit Page 7 ProcessorState field */ +#define MPI2_IOUNITPAGE7_PSTATE_MASK_SECOND (0x0000000F) +#define MPI2_IOUNITPAGE7_PSTATE_SHIFT_SECOND (0) + +#define MPI2_IOUNITPAGE7_PSTATE_NOT_PRESENT (0x00) +#define MPI2_IOUNITPAGE7_PSTATE_DISABLED (0x01) +#define MPI2_IOUNITPAGE7_PSTATE_ENABLED (0x02) + +/* defines for IO Unit Page 7 IOCTemperatureUnits field */ +#define MPI2_IOUNITPAGE7_IOC_TEMP_NOT_PRESENT (0x00) +#define MPI2_IOUNITPAGE7_IOC_TEMP_FAHRENHEIT (0x01) +#define MPI2_IOUNITPAGE7_IOC_TEMP_CELSIUS (0x02) + +/* defines for IO Unit Page 7 IOCSpeed field */ +#define MPI2_IOUNITPAGE7_IOC_SPEED_FULL (0x01) +#define MPI2_IOUNITPAGE7_IOC_SPEED_HALF (0x02) +#define MPI2_IOUNITPAGE7_IOC_SPEED_QUARTER (0x04) +#define MPI2_IOUNITPAGE7_IOC_SPEED_EIGHTH (0x08) + + + /**************************************************************************** * IOC Config Pages ****************************************************************************/ @@ -1451,6 +1592,12 @@ /* values for PhyInfo fields */ #define MPI2_SAS_PHYINFO_PHY_VACANT (0x80000000) + +#define MPI2_SAS_PHYINFO_PHY_POWER_CONDITION_MASK (0x18000000) +#define MPI2_SAS_PHYINFO_PHY_POWER_ACTIVE (0x00000000) +#define MPI2_SAS_PHYINFO_PHY_POWER_PARTIAL (0x08000000) +#define MPI2_SAS_PHYINFO_PHY_POWER_SLUMBER (0x10000000) + #define MPI2_SAS_PHYINFO_CHANGED_REQ_INSIDE_ZPSDS (0x04000000) #define MPI2_SAS_PHYINFO_INSIDE_ZPSDS_PERSISTENT (0x02000000) #define MPI2_SAS_PHYINFO_REQ_INSIDE_ZPSDS (0x01000000) @@ -1663,11 +1810,11 @@ /* values for SAS IO Unit Page 1 PortFlags */ #define MPI2_SASIOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01) -/* values for SAS IO Unit Page 2 PhyFlags */ +/* values for SAS IO Unit Page 1 PhyFlags */ #define MPI2_SASIOUNIT1_PHYFLAGS_ZONING_ENABLE (0x10) #define MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE (0x08) -/* values for SAS IO Unit Page 0 MaxMinLinkRate */ +/* values for SAS IO Unit Page 1 MaxMinLinkRate */ #define MPI2_SASIOUNIT1_MAX_RATE_MASK (0xF0) #define MPI2_SASIOUNIT1_MAX_RATE_1_5 (0x80) #define MPI2_SASIOUNIT1_MAX_RATE_3_0 (0x90) @@ -1726,6 +1873,75 @@ #define MPI2_SASIOUNIT4_PHY_SPINUP_GROUP_MASK (0x03) +/* SAS IO Unit Page 5 */ + +typedef struct _MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS +{ + U8 ControlFlags; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U16 InactivityTimerExponent; /* 0x02 */ + U8 SATAPartialTimeout; /* 0x04 */ + U8 Reserved2; /* 0x05 */ + U8 SATASlumberTimeout; /* 0x06 */ + U8 Reserved3; /* 0x07 */ + U8 SASPartialTimeout; /* 0x08 */ + U8 Reserved4; /* 0x09 */ + U8 SASSlumberTimeout; /* 0x0A */ + U8 Reserved5; /* 0x0B */ +} MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS, + MPI2_POINTER PTR_MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS, + Mpi2SasIOUnit5PhyPmSettings_t, MPI2_POINTER pMpi2SasIOUnit5PhyPmSettings_t; + +/* defines for ControlFlags field */ +#define MPI2_SASIOUNIT5_CONTROL_SAS_SLUMBER_ENABLE (0x08) +#define MPI2_SASIOUNIT5_CONTROL_SAS_PARTIAL_ENABLE (0x04) +#define MPI2_SASIOUNIT5_CONTROL_SATA_SLUMBER_ENABLE (0x02) +#define MPI2_SASIOUNIT5_CONTROL_SATA_PARTIAL_ENABLE (0x01) + +/* defines for InactivityTimerExponent field */ +#define MPI2_SASIOUNIT5_ITE_MASK_SAS_SLUMBER (0x7000) +#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_SLUMBER (12) +#define MPI2_SASIOUNIT5_ITE_MASK_SAS_PARTIAL (0x0700) +#define MPI2_SASIOUNIT5_ITE_SHIFT_SAS_PARTIAL (8) +#define MPI2_SASIOUNIT5_ITE_MASK_SATA_SLUMBER (0x0070) +#define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_SLUMBER (4) +#define MPI2_SASIOUNIT5_ITE_MASK_SATA_PARTIAL (0x0007) +#define MPI2_SASIOUNIT5_ITE_SHIFT_SATA_PARTIAL (0) + +#define MPI2_SASIOUNIT5_ITE_TEN_SECONDS (7) +#define MPI2_SASIOUNIT5_ITE_ONE_SECOND (6) +#define MPI2_SASIOUNIT5_ITE_HUNDRED_MILLISECONDS (5) +#define MPI2_SASIOUNIT5_ITE_TEN_MILLISECONDS (4) +#define MPI2_SASIOUNIT5_ITE_ONE_MILLISECOND (3) +#define MPI2_SASIOUNIT5_ITE_HUNDRED_MICROSECONDS (2) +#define MPI2_SASIOUNIT5_ITE_TEN_MICROSECONDS (1) +#define MPI2_SASIOUNIT5_ITE_ONE_MICROSECOND (0) + +/* + * Host code (drivers, BIOS, utilities, etc.) should leave this define set to + * one and check Header.ExtPageLength or NumPhys at runtime. + */ +#ifndef MPI2_SAS_IOUNIT5_PHY_MAX +#define MPI2_SAS_IOUNIT5_PHY_MAX (1) +#endif + +typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_5 +{ + MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */ + U8 NumPhys; /* 0x08 */ + U8 Reserved1; /* 0x09 */ + U16 Reserved2; /* 0x0A */ + U32 Reserved3; /* 0x0C */ + MPI2_SAS_IO_UNIT5_PHY_PM_SETTINGS SASPhyPowerManagementSettings[MPI2_SAS_IOUNIT5_PHY_MAX]; /* 0x10 */ +} MPI2_CONFIG_PAGE_SASIOUNIT_5, + MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SASIOUNIT_5, + Mpi2SasIOUnitPage5_t, MPI2_POINTER pMpi2SasIOUnitPage5_t; + +#define MPI2_SASIOUNITPAGE5_PAGEVERSION (0x00) + + + + /**************************************************************************** * SAS Expander Config Pages ****************************************************************************/ @@ -1754,10 +1970,14 @@ U64 ActiveZoneManagerSASAddress;/* 0x2C */ U16 ZoneLockInactivityLimit; /* 0x34 */ U16 Reserved1; /* 0x36 */ + U8 TimeToReducedFunc; /* 0x38 */ + U8 InitialTimeToReducedFunc; /* 0x39 */ + U8 MaxReducedFuncTime; /* 0x3A */ + U8 Reserved2; /* 0x3B */ } MPI2_CONFIG_PAGE_EXPANDER_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_EXPANDER_0, Mpi2ExpanderPage0_t, MPI2_POINTER pMpi2ExpanderPage0_t; -#define MPI2_SASEXPANDER0_PAGEVERSION (0x05) +#define MPI2_SASEXPANDER0_PAGEVERSION (0x06) /* values for SAS Expander Page 0 DiscoveryStatus field */ #define MPI2_SAS_EXPANDER0_DS_MAX_ENCLOSURES_EXCEED (0x80000000) @@ -1782,6 +2002,7 @@ #define MPI2_SAS_EXPANDER0_DS_LOOP_DETECTED (0x00000001) /* values for SAS Expander Page 0 Flags field */ +#define MPI2_SAS_EXPANDER0_FLAGS_REDUCED_FUNCTIONALITY (0x2000) #define MPI2_SAS_EXPANDER0_FLAGS_ZONE_LOCKED (0x1000) #define MPI2_SAS_EXPANDER0_FLAGS_SUPPORTED_PHYSICAL_PRES (0x0800) #define MPI2_SAS_EXPANDER0_FLAGS_ASSERTED_PHYSICAL_PRES (0x0400) @@ -1903,6 +2124,8 @@ /* see mpi2_sas.h for values for SAS Device Page 0 DeviceInfo values */ /* values for SAS Device Page 0 Flags field */ +#define MPI2_SAS_DEVICE0_FLAGS_SLUMBER_PM_CAPABLE (0x1000) +#define MPI2_SAS_DEVICE0_FLAGS_PARTIAL_PM_CAPABLE (0x0800) #define MPI2_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY (0x0400) #define MPI2_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE (0x0200) #define MPI2_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE (0x0100) @@ -1989,6 +2212,135 @@ #define MPI2_SASPHY1_PAGEVERSION (0x01) +/* SAS PHY Page 2 */ + +typedef struct _MPI2_SASPHY2_PHY_EVENT +{ + U8 PhyEventCode; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U16 Reserved2; /* 0x02 */ + U32 PhyEventInfo; /* 0x04 */ +} MPI2_SASPHY2_PHY_EVENT, MPI2_POINTER PTR_MPI2_SASPHY2_PHY_EVENT, + Mpi2SasPhy2PhyEvent_t, MPI2_POINTER pMpi2SasPhy2PhyEvent_t; + +/* use MPI2_SASPHY3_EVENT_CODE_ for the PhyEventCode field */ + + +/* + * Host code (drivers, BIOS, utilities, etc.) should leave this define set to + * one and check Header.ExtPageLength or NumPhyEvents at runtime. + */ +#ifndef MPI2_SASPHY2_PHY_EVENT_MAX +#define MPI2_SASPHY2_PHY_EVENT_MAX (1) +#endif + +typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_2 +{ + MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */ + U32 Reserved1; /* 0x08 */ + U8 NumPhyEvents; /* 0x0C */ + U8 Reserved2; /* 0x0D */ + U16 Reserved3; /* 0x0E */ + MPI2_SASPHY2_PHY_EVENT PhyEvent[MPI2_SASPHY2_PHY_EVENT_MAX]; /* 0x10 */ +} MPI2_CONFIG_PAGE_SAS_PHY_2, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PHY_2, + Mpi2SasPhyPage2_t, MPI2_POINTER pMpi2SasPhyPage2_t; + +#define MPI2_SASPHY2_PAGEVERSION (0x00) + + +/* SAS PHY Page 3 */ + +typedef struct _MPI2_SASPHY3_PHY_EVENT_CONFIG +{ + U8 PhyEventCode; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U16 Reserved2; /* 0x02 */ + U8 CounterType; /* 0x04 */ + U8 ThresholdWindow; /* 0x05 */ + U8 TimeUnits; /* 0x06 */ + U8 Reserved3; /* 0x07 */ + U32 EventThreshold; /* 0x08 */ + U16 ThresholdFlags; /* 0x0C */ + U16 Reserved4; /* 0x0E */ +} MPI2_SASPHY3_PHY_EVENT_CONFIG, MPI2_POINTER PTR_MPI2_SASPHY3_PHY_EVENT_CONFIG, + Mpi2SasPhy3PhyEventConfig_t, MPI2_POINTER pMpi2SasPhy3PhyEventConfig_t; + +/* values for PhyEventCode field */ +#define MPI2_SASPHY3_EVENT_CODE_NO_EVENT (0x00) +#define MPI2_SASPHY3_EVENT_CODE_INVALID_DWORD (0x01) +#define MPI2_SASPHY3_EVENT_CODE_RUNNING_DISPARITY_ERROR (0x02) +#define MPI2_SASPHY3_EVENT_CODE_LOSS_DWORD_SYNC (0x03) +#define MPI2_SASPHY3_EVENT_CODE_PHY_RESET_PROBLEM (0x04) +#define MPI2_SASPHY3_EVENT_CODE_ELASTICITY_BUF_OVERFLOW (0x05) +#define MPI2_SASPHY3_EVENT_CODE_RX_ERROR (0x06) +#define MPI2_SASPHY3_EVENT_CODE_RX_ADDR_FRAME_ERROR (0x20) +#define MPI2_SASPHY3_EVENT_CODE_TX_AC_OPEN_REJECT (0x21) +#define MPI2_SASPHY3_EVENT_CODE_RX_AC_OPEN_REJECT (0x22) +#define MPI2_SASPHY3_EVENT_CODE_TX_RC_OPEN_REJECT (0x23) +#define MPI2_SASPHY3_EVENT_CODE_RX_RC_OPEN_REJECT (0x24) +#define MPI2_SASPHY3_EVENT_CODE_RX_AIP_PARTIAL_WAITING_ON (0x25) +#define MPI2_SASPHY3_EVENT_CODE_RX_AIP_CONNECT_WAITING_ON (0x26) +#define MPI2_SASPHY3_EVENT_CODE_TX_BREAK (0x27) +#define MPI2_SASPHY3_EVENT_CODE_RX_BREAK (0x28) +#define MPI2_SASPHY3_EVENT_CODE_BREAK_TIMEOUT (0x29) +#define MPI2_SASPHY3_EVENT_CODE_CONNECTION (0x2A) +#define MPI2_SASPHY3_EVENT_CODE_PEAKTX_PATHWAY_BLOCKED (0x2B) +#define MPI2_SASPHY3_EVENT_CODE_PEAKTX_ARB_WAIT_TIME (0x2C) +#define MPI2_SASPHY3_EVENT_CODE_PEAK_ARB_WAIT_TIME (0x2D) +#define MPI2_SASPHY3_EVENT_CODE_PEAK_CONNECT_TIME (0x2E) +#define MPI2_SASPHY3_EVENT_CODE_TX_SSP_FRAMES (0x40) +#define MPI2_SASPHY3_EVENT_CODE_RX_SSP_FRAMES (0x41) +#define MPI2_SASPHY3_EVENT_CODE_TX_SSP_ERROR_FRAMES (0x42) +#define MPI2_SASPHY3_EVENT_CODE_RX_SSP_ERROR_FRAMES (0x43) +#define MPI2_SASPHY3_EVENT_CODE_TX_CREDIT_BLOCKED (0x44) +#define MPI2_SASPHY3_EVENT_CODE_RX_CREDIT_BLOCKED (0x45) +#define MPI2_SASPHY3_EVENT_CODE_TX_SATA_FRAMES (0x50) +#define MPI2_SASPHY3_EVENT_CODE_RX_SATA_FRAMES (0x51) +#define MPI2_SASPHY3_EVENT_CODE_SATA_OVERFLOW (0x52) +#define MPI2_SASPHY3_EVENT_CODE_TX_SMP_FRAMES (0x60) +#define MPI2_SASPHY3_EVENT_CODE_RX_SMP_FRAMES (0x61) +#define MPI2_SASPHY3_EVENT_CODE_RX_SMP_ERROR_FRAMES (0x63) +#define MPI2_SASPHY3_EVENT_CODE_HOTPLUG_TIMEOUT (0xD0) +#define MPI2_SASPHY3_EVENT_CODE_MISALIGNED_MUX_PRIMITIVE (0xD1) +#define MPI2_SASPHY3_EVENT_CODE_RX_AIP (0xD2) + +/* values for the CounterType field */ +#define MPI2_SASPHY3_COUNTER_TYPE_WRAPPING (0x00) +#define MPI2_SASPHY3_COUNTER_TYPE_SATURATING (0x01) +#define MPI2_SASPHY3_COUNTER_TYPE_PEAK_VALUE (0x02) + +/* values for the TimeUnits field */ +#define MPI2_SASPHY3_TIME_UNITS_10_MICROSECONDS (0x00) +#define MPI2_SASPHY3_TIME_UNITS_100_MICROSECONDS (0x01) +#define MPI2_SASPHY3_TIME_UNITS_1_MILLISECOND (0x02) +#define MPI2_SASPHY3_TIME_UNITS_10_MILLISECONDS (0x03) + +/* values for the ThresholdFlags field */ +#define MPI2_SASPHY3_TFLAGS_PHY_RESET (0x0002) +#define MPI2_SASPHY3_TFLAGS_EVENT_NOTIFY (0x0001) + +/* + * Host code (drivers, BIOS, utilities, etc.) should leave this define set to + * one and check Header.ExtPageLength or NumPhyEvents at runtime. + */ +#ifndef MPI2_SASPHY3_PHY_EVENT_MAX +#define MPI2_SASPHY3_PHY_EVENT_MAX (1) +#endif + +typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_3 +{ + MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */ + U32 Reserved1; /* 0x08 */ + U8 NumPhyEvents; /* 0x0C */ + U8 Reserved2; /* 0x0D */ + U16 Reserved3; /* 0x0E */ + MPI2_SASPHY3_PHY_EVENT_CONFIG PhyEventConfig[MPI2_SASPHY3_PHY_EVENT_MAX]; /* 0x10 */ +} MPI2_CONFIG_PAGE_SAS_PHY_3, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PHY_3, + Mpi2SasPhyPage3_t, MPI2_POINTER pMpi2SasPhyPage3_t; + +#define MPI2_SASPHY3_PAGEVERSION (0x00) + + /**************************************************************************** * SAS Port Config Pages ****************************************************************************/ @@ -2192,5 +2544,123 @@ #define MPI2_DRVMAP0_MAPINFO_MISSING_MASK (0x000F) +/**************************************************************************** +* Ethernet Config Pages +****************************************************************************/ + +/* Ethernet Page 0 */ + +/* IP address (union of IPv4 and IPv6) */ +typedef union _MPI2_ETHERNET_IP_ADDR +{ + U32 IPv4Addr; + U32 IPv6Addr[4]; +} MPI2_ETHERNET_IP_ADDR, MPI2_POINTER PTR_MPI2_ETHERNET_IP_ADDR, + Mpi2EthernetIpAddr_t, MPI2_POINTER pMpi2EthernetIpAddr_t; + +#define MPI2_ETHERNET_HOST_NAME_LENGTH (32) + +typedef struct _MPI2_CONFIG_PAGE_ETHERNET_0 +{ + MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */ + U8 NumInterfaces; /* 0x08 */ + U8 Reserved0; /* 0x09 */ + U16 Reserved1; /* 0x0A */ + U32 Status; /* 0x0C */ + U8 MediaState; /* 0x10 */ + U8 Reserved2; /* 0x11 */ + U16 Reserved3; /* 0x12 */ + U8 MacAddress[6]; /* 0x14 */ + U8 Reserved4; /* 0x1A */ + U8 Reserved5; /* 0x1B */ + MPI2_ETHERNET_IP_ADDR IpAddress; /* 0x1C */ + MPI2_ETHERNET_IP_ADDR SubnetMask; /* 0x2C */ + MPI2_ETHERNET_IP_ADDR GatewayIpAddress; /* 0x3C */ + MPI2_ETHERNET_IP_ADDR DNS1IpAddress; /* 0x4C */ + MPI2_ETHERNET_IP_ADDR DNS2IpAddress; /* 0x5C */ + MPI2_ETHERNET_IP_ADDR DhcpIpAddress; /* 0x6C */ + U8 HostName[MPI2_ETHERNET_HOST_NAME_LENGTH];/* 0x7C */ +} MPI2_CONFIG_PAGE_ETHERNET_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_ETHERNET_0, + Mpi2EthernetPage0_t, MPI2_POINTER pMpi2EthernetPage0_t; + +#define MPI2_ETHERNETPAGE0_PAGEVERSION (0x00) + +/* values for Ethernet Page 0 Status field */ +#define MPI2_ETHPG0_STATUS_IPV6_CAPABLE (0x80000000) +#define MPI2_ETHPG0_STATUS_IPV4_CAPABLE (0x40000000) +#define MPI2_ETHPG0_STATUS_CONSOLE_CONNECTED (0x20000000) +#define MPI2_ETHPG0_STATUS_DEFAULT_IF (0x00000100) +#define MPI2_ETHPG0_STATUS_FW_DWNLD_ENABLED (0x00000080) +#define MPI2_ETHPG0_STATUS_TELNET_ENABLED (0x00000040) +#define MPI2_ETHPG0_STATUS_SSH2_ENABLED (0x00000020) +#define MPI2_ETHPG0_STATUS_DHCP_CLIENT_ENABLED (0x00000010) +#define MPI2_ETHPG0_STATUS_IPV6_ENABLED (0x00000008) +#define MPI2_ETHPG0_STATUS_IPV4_ENABLED (0x00000004) +#define MPI2_ETHPG0_STATUS_IPV6_ADDRESSES (0x00000002) +#define MPI2_ETHPG0_STATUS_ETH_IF_ENABLED (0x00000001) + +/* values for Ethernet Page 0 MediaState field */ +#define MPI2_ETHPG0_MS_DUPLEX_MASK (0x80) +#define MPI2_ETHPG0_MS_HALF_DUPLEX (0x00) +#define MPI2_ETHPG0_MS_FULL_DUPLEX (0x80) + +#define MPI2_ETHPG0_MS_CONNECT_SPEED_MASK (0x07) +#define MPI2_ETHPG0_MS_NOT_CONNECTED (0x00) +#define MPI2_ETHPG0_MS_10MBIT (0x01) +#define MPI2_ETHPG0_MS_100MBIT (0x02) +#define MPI2_ETHPG0_MS_1GBIT (0x03) + + +/* Ethernet Page 1 */ + +typedef struct _MPI2_CONFIG_PAGE_ETHERNET_1 +{ + MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */ + U32 Reserved0; /* 0x08 */ + U32 Flags; /* 0x0C */ + U8 MediaState; /* 0x10 */ + U8 Reserved1; /* 0x11 */ + U16 Reserved2; /* 0x12 */ + U8 MacAddress[6]; /* 0x14 */ + U8 Reserved3; /* 0x1A */ + U8 Reserved4; /* 0x1B */ + MPI2_ETHERNET_IP_ADDR StaticIpAddress; /* 0x1C */ + MPI2_ETHERNET_IP_ADDR StaticSubnetMask; /* 0x2C */ + MPI2_ETHERNET_IP_ADDR StaticGatewayIpAddress; /* 0x3C */ + MPI2_ETHERNET_IP_ADDR StaticDNS1IpAddress; /* 0x4C */ + MPI2_ETHERNET_IP_ADDR StaticDNS2IpAddress; /* 0x5C */ + U32 Reserved5; /* 0x6C */ + U32 Reserved6; /* 0x70 */ + U32 Reserved7; /* 0x74 */ + U32 Reserved8; /* 0x78 */ + U8 HostName[MPI2_ETHERNET_HOST_NAME_LENGTH];/* 0x7C */ +} MPI2_CONFIG_PAGE_ETHERNET_1, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_ETHERNET_1, + Mpi2EthernetPage1_t, MPI2_POINTER pMpi2EthernetPage1_t; + +#define MPI2_ETHERNETPAGE1_PAGEVERSION (0x00) + +/* values for Ethernet Page 1 Flags field */ +#define MPI2_ETHPG1_FLAG_SET_DEFAULT_IF (0x00000100) +#define MPI2_ETHPG1_FLAG_ENABLE_FW_DOWNLOAD (0x00000080) +#define MPI2_ETHPG1_FLAG_ENABLE_TELNET (0x00000040) +#define MPI2_ETHPG1_FLAG_ENABLE_SSH2 (0x00000020) +#define MPI2_ETHPG1_FLAG_ENABLE_DHCP_CLIENT (0x00000010) +#define MPI2_ETHPG1_FLAG_ENABLE_IPV6 (0x00000008) +#define MPI2_ETHPG1_FLAG_ENABLE_IPV4 (0x00000004) +#define MPI2_ETHPG1_FLAG_USE_IPV6_ADDRESSES (0x00000002) +#define MPI2_ETHPG1_FLAG_ENABLE_ETH_IF (0x00000001) + +/* values for Ethernet Page 1 MediaState field */ +#define MPI2_ETHPG1_MS_DUPLEX_MASK (0x80) +#define MPI2_ETHPG1_MS_HALF_DUPLEX (0x00) +#define MPI2_ETHPG1_MS_FULL_DUPLEX (0x80) + +#define MPI2_ETHPG1_MS_DATA_RATE_MASK (0x07) +#define MPI2_ETHPG1_MS_DATA_RATE_AUTO (0x00) +#define MPI2_ETHPG1_MS_DATA_RATE_10MBIT (0x01) +#define MPI2_ETHPG1_MS_DATA_RATE_100MBIT (0x02) +#define MPI2_ETHPG1_MS_DATA_RATE_1GBIT (0x03) + + #endif
--- a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h Wed Nov 25 12:30:41 2009 +0800 +++ b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h Wed Nov 25 13:05:40 2009 +0800 @@ -51,7 +51,7 @@ * Title: MPI SCSI initiator mode messages and structures * Creation Date: June 23, 2006 * - * mpi2_init.h Version: 02.00.06 + * mpi2_init.h Version: 02.00.07 * * Version History * --------------- @@ -68,6 +68,10 @@ * Control field Task Attribute flags. * Moved LUN field defines to mpi2.h becasue they are * common to many structures. + * 05-06-09 02.00.07 Changed task management type of Query Unit Attention to + * Query Asynchronous Event. + * Defined two new bits in the SlotStatus field of the SCSI + * Enclosure Processor Request and Reply. * -------------------------------------------------------------------------- */ @@ -334,7 +338,10 @@ #define MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07) #define MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA (0x08) #define MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET (0x09) -#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION (0x0A) +#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT (0x0A) + +/* obsolete TaskType name */ +#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION (MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT) /* MsgFlags bits */ @@ -420,6 +427,8 @@ #define MPI2_SEP_REQ_SLOTSTATUS_HOT_SPARE (0x00000100) #define MPI2_SEP_REQ_SLOTSTATUS_UNCONFIGURED (0x00000080) #define MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT (0x00000040) +#define MPI2_SEP_REQ_SLOTSTATUS_IN_CRITICAL_ARRAY (0x00000010) +#define MPI2_SEP_REQ_SLOTSTATUS_IN_FAILED_ARRAY (0x00000008) #define MPI2_SEP_REQ_SLOTSTATUS_DEV_REBUILDING (0x00000004) #define MPI2_SEP_REQ_SLOTSTATUS_DEV_FAULTY (0x00000002) #define MPI2_SEP_REQ_SLOTSTATUS_NO_ERROR (0x00000001) @@ -455,6 +464,8 @@ #define MPI2_SEP_REPLY_SLOTSTATUS_HOT_SPARE (0x00000100) #define MPI2_SEP_REPLY_SLOTSTATUS_UNCONFIGURED (0x00000080) #define MPI2_SEP_REPLY_SLOTSTATUS_PREDICTED_FAULT (0x00000040) +#define MPI2_SEP_REPLY_SLOTSTATUS_IN_CRITICAL_ARRAY (0x00000010) +#define MPI2_SEP_REPLY_SLOTSTATUS_IN_FAILED_ARRAY (0x00000008) #define MPI2_SEP_REPLY_SLOTSTATUS_DEV_REBUILDING (0x00000004) #define MPI2_SEP_REPLY_SLOTSTATUS_DEV_FAULTY (0x00000002) #define MPI2_SEP_REPLY_SLOTSTATUS_NO_ERROR (0x00000001)
--- a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h Wed Nov 25 12:30:41 2009 +0800 +++ b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h Wed Nov 25 13:05:40 2009 +0800 @@ -25,7 +25,7 @@ * * Redistribution and use in source and binary forms of all code within * this file that is exclusively owned by LSI, with or without - * modification, is permitted provided that, in addition to the CDDL 1.0 + * modification, is permitted provided that, in addition to the CDDL 1.0 * License requirements, the following conditions are met: * * Neither the name of the author nor the names of its contributors may be @@ -51,7 +51,7 @@ * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages * Creation Date: October 11, 2006 * - * mpi2_ioc.h Version: 02.00.10 + * mpi2_ioc.h Version: 02.00.12 * * Version History * --------------- @@ -124,6 +124,14 @@ * Added MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE * define. * Removed MPI2_EVENT_SAS_DISC_DS_SATA_INIT_FAILURE define. + * 05-06-09 02.00.11 Added MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR define. + * Added MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX define. + * Added two new reason codes for SAS Device Status Change + * Event. + * Added new event: SAS PHY Counter. + * 07-30-09 02.00.12 Added GPIO Interrupt event define and structure. + * Added MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define. + * Added new product id family for 2208. * -------------------------------------------------------------------------- */ @@ -306,12 +314,15 @@ /* ProductID field uses MPI2_FW_HEADER_PID_ */ /* IOCCapabilities */ +#define MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX (0x00008000) +#define MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR (0x00004000) #define MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY (0x00002000) #define MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID (0x00001000) #define MPI2_IOCFACTS_CAPABILITY_TLR (0x00000800) #define MPI2_IOCFACTS_CAPABILITY_MULTICAST (0x00000100) #define MPI2_IOCFACTS_CAPABILITY_BIDIRECTIONAL_TARGET (0x00000080) #define MPI2_IOCFACTS_CAPABILITY_EEDP (0x00000040) +#define MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER (0x00000020) #define MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010) #define MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008) #define MPI2_IOCFACTS_CAPABILITY_TASK_SET_FULL_HANDLING (0x00000004) @@ -485,6 +496,8 @@ #define MPI2_EVENT_IR_PHYSICAL_DISK (0x001F) #define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST (0x0020) #define MPI2_EVENT_LOG_ENTRY_ADDED (0x0021) +#define MPI2_EVENT_SAS_PHY_COUNTER (0x0022) +#define MPI2_EVENT_GPIO_INTERRUPT (0x0023) /* Log Entry Added Event data */ @@ -506,6 +519,17 @@ MPI2_POINTER PTR_MPI2_EVENT_DATA_LOG_ENTRY_ADDED, Mpi2EventDataLogEntryAdded_t, MPI2_POINTER pMpi2EventDataLogEntryAdded_t; +/* GPIO Interrupt Event data */ + +typedef struct _MPI2_EVENT_DATA_GPIO_INTERRUPT +{ + U8 GPIONum; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U16 Reserved2; /* 0x02 */ +} MPI2_EVENT_DATA_GPIO_INTERRUPT, + MPI2_POINTER PTR_MPI2_EVENT_DATA_GPIO_INTERRUPT, + Mpi2EventDataGpioInterrupt_t, MPI2_POINTER pMpi2EventDataGpioInterrupt_t; + /* Hard Reset Received Event data */ typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED @@ -547,17 +571,19 @@ MPI2_POINTER pMpi2EventDataSasDeviceStatusChange_t; /* SAS Device Status Change Event data ReasonCode values */ -#define MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05) -#define MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07) -#define MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08) -#define MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL (0x09) -#define MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A) -#define MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B) -#define MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C) -#define MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION (0x0D) -#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET (0x0E) -#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL (0x0F) -#define MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE (0x10) +#define MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05) +#define MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07) +#define MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08) +#define MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL (0x09) +#define MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A) +#define MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B) +#define MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C) +#define MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION (0x0D) +#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET (0x0E) +#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL (0x0F) +#define MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE (0x10) +#define MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY (0x11) +#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY (0x12) /* Integrated RAID Operation Status Event data */ @@ -867,6 +893,36 @@ #define MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING (0x02) +/* SAS PHY Counter Event data */ + +typedef struct _MPI2_EVENT_DATA_SAS_PHY_COUNTER +{ + U64 TimeStamp; /* 0x00 */ + U32 Reserved1; /* 0x08 */ + U8 PhyEventCode; /* 0x0C */ + U8 PhyNum; /* 0x0D */ + U16 Reserved2; /* 0x0E */ + U32 PhyEventInfo; /* 0x10 */ + U8 CounterType; /* 0x14 */ + U8 ThresholdWindow; /* 0x15 */ + U8 TimeUnits; /* 0x16 */ + U8 Reserved3; /* 0x17 */ + U32 EventThreshold; /* 0x18 */ + U16 ThresholdFlags; /* 0x1C */ + U16 Reserved4; /* 0x1E */ +} MPI2_EVENT_DATA_SAS_PHY_COUNTER, + MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_PHY_COUNTER, + Mpi2EventDataSasPhyCounter_t, MPI2_POINTER pMpi2EventDataSasPhyCounter_t; + +/* use MPI2_SASPHY3_EVENT_CODE_ values from mpi2_cnfg.h for the PhyEventCode field */ + +/* use MPI2_SASPHY3_COUNTER_TYPE_ values from mpi2_cnfg.h for the CounterType field */ + +/* use MPI2_SASPHY3_TIME_UNITS_ values from mpi2_cnfg.h for the TimeUnits field */ + +/* use MPI2_SASPHY3_TFLAGS_ values from mpi2_cnfg.h for the ThresholdFlags field */ + + /**************************************************************************** * EventAck message ****************************************************************************/ @@ -1121,6 +1177,7 @@ #define MPI2_FW_HEADER_PID_FAMILY_MASK (0x00FF) /* SAS */ #define MPI2_FW_HEADER_PID_FAMILY_2108_SAS (0x0010) +#define MPI2_FW_HEADER_PID_FAMILY_2208_SAS (0x0011) /* use MPI2_IOCFACTS_PROTOCOL_ defines for ProtocolFlags field */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h Wed Nov 25 13:05:40 2009 +0800 @@ -0,0 +1,346 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2000 to 2009, LSI Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms of all code within + * this file that is exclusively owned by LSI, with or without + * modification, is permitted provided that, in addition to the CDDL 1.0 + * License requirements, the following conditions are met: + * + * Neither the name of the author nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +/* + * Name: mpi2_raid.h + * Title: MPI Integrated RAID messages and structures + * Creation Date: April 26, 2007 + * + * mpi2_raid.h Version: 02.00.04 + * + * Version History + * --------------- + * + * Date Version Description + * -------- -------- ------------------------------------------------------ + * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. + * 08-31-07 02.00.01 Modifications to RAID Action request and reply, + * including the Actions and ActionData. + * 02-29-08 02.00.02 Added MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD. + * 05-21-08 02.00.03 Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that + * the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT + * can be sized by the build environment. + * 07-30-09 02.00.04 Added proper define for the Use Default Settings bit of + * VolumeCreationFlags and marked the old one as obsolete. + * -------------------------------------------------------------------------- + */ + +#ifndef MPI2_RAID_H +#define MPI2_RAID_H + +/***************************************************************************** +* +* Integrated RAID Messages +* +*****************************************************************************/ + +/**************************************************************************** +* RAID Action messages +****************************************************************************/ + +/* ActionDataWord defines for use with MPI2_RAID_ACTION_DELETE_VOLUME action */ +#define MPI2_RAID_ACTION_ADATA_KEEP_LBA0 (0x00000000) +#define MPI2_RAID_ACTION_ADATA_ZERO_LBA0 (0x00000001) + +/* use MPI2_RAIDVOL0_SETTING_ defines from mpi2_cnfg.h for MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE action */ + +/* ActionDataWord defines for use with MPI2_RAID_ACTION_DISABLE_ALL_VOLUMES action */ +#define MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD (0x00000001) + +/* ActionDataWord for MPI2_RAID_ACTION_SET_RAID_FUNCTION_RATE Action */ +typedef struct _MPI2_RAID_ACTION_RATE_DATA +{ + U8 RateToChange; /* 0x00 */ + U8 RateOrMode; /* 0x01 */ + U16 DataScrubDuration; /* 0x02 */ +} MPI2_RAID_ACTION_RATE_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_RATE_DATA, + Mpi2RaidActionRateData_t, MPI2_POINTER pMpi2RaidActionRateData_t; + +#define MPI2_RAID_ACTION_SET_RATE_RESYNC (0x00) +#define MPI2_RAID_ACTION_SET_RATE_DATA_SCRUB (0x01) +#define MPI2_RAID_ACTION_SET_RATE_POWERSAVE_MODE (0x02) + +/* ActionDataWord for MPI2_RAID_ACTION_START_RAID_FUNCTION Action */ +typedef struct _MPI2_RAID_ACTION_START_RAID_FUNCTION +{ + U8 RAIDFunction; /* 0x00 */ + U8 Flags; /* 0x01 */ + U16 Reserved1; /* 0x02 */ +} MPI2_RAID_ACTION_START_RAID_FUNCTION, + MPI2_POINTER PTR_MPI2_RAID_ACTION_START_RAID_FUNCTION, + Mpi2RaidActionStartRaidFunction_t, + MPI2_POINTER pMpi2RaidActionStartRaidFunction_t; + +/* defines for the RAIDFunction field */ +#define MPI2_RAID_ACTION_START_BACKGROUND_INIT (0x00) +#define MPI2_RAID_ACTION_START_ONLINE_CAP_EXPANSION (0x01) +#define MPI2_RAID_ACTION_START_CONSISTENCY_CHECK (0x02) + +/* defines for the Flags field */ +#define MPI2_RAID_ACTION_START_NEW (0x00) +#define MPI2_RAID_ACTION_START_RESUME (0x01) + +/* ActionDataWord for MPI2_RAID_ACTION_STOP_RAID_FUNCTION Action */ +typedef struct _MPI2_RAID_ACTION_STOP_RAID_FUNCTION +{ + U8 RAIDFunction; /* 0x00 */ + U8 Flags; /* 0x01 */ + U16 Reserved1; /* 0x02 */ +} MPI2_RAID_ACTION_STOP_RAID_FUNCTION, + MPI2_POINTER PTR_MPI2_RAID_ACTION_STOP_RAID_FUNCTION, + Mpi2RaidActionStopRaidFunction_t, + MPI2_POINTER pMpi2RaidActionStopRaidFunction_t; + +/* defines for the RAIDFunction field */ +#define MPI2_RAID_ACTION_STOP_BACKGROUND_INIT (0x00) +#define MPI2_RAID_ACTION_STOP_ONLINE_CAP_EXPANSION (0x01) +#define MPI2_RAID_ACTION_STOP_CONSISTENCY_CHECK (0x02) + +/* defines for the Flags field */ +#define MPI2_RAID_ACTION_STOP_ABORT (0x00) +#define MPI2_RAID_ACTION_STOP_PAUSE (0x01) + +/* ActionDataWord for MPI2_RAID_ACTION_CREATE_HOT_SPARE Action */ +typedef struct _MPI2_RAID_ACTION_HOT_SPARE +{ + U8 HotSparePool; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U16 DevHandle; /* 0x02 */ +} MPI2_RAID_ACTION_HOT_SPARE, MPI2_POINTER PTR_MPI2_RAID_ACTION_HOT_SPARE, + Mpi2RaidActionHotSpare_t, MPI2_POINTER pMpi2RaidActionHotSpare_t; + +/* ActionDataWord for MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE Action */ +typedef struct _MPI2_RAID_ACTION_FW_UPDATE_MODE +{ + U8 Flags; /* 0x00 */ + U8 DeviceFirmwareUpdateModeTimeout; /* 0x01 */ + U16 Reserved1; /* 0x02 */ +} MPI2_RAID_ACTION_FW_UPDATE_MODE, + MPI2_POINTER PTR_MPI2_RAID_ACTION_FW_UPDATE_MODE, + Mpi2RaidActionFwUpdateMode_t, MPI2_POINTER pMpi2RaidActionFwUpdateMode_t; + +/* ActionDataWord defines for use with MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE action */ +#define MPI2_RAID_ACTION_ADATA_DISABLE_FW_UPDATE (0x00) +#define MPI2_RAID_ACTION_ADATA_ENABLE_FW_UPDATE (0x01) + +typedef union _MPI2_RAID_ACTION_DATA +{ + U32 Word; + MPI2_RAID_ACTION_RATE_DATA Rates; + MPI2_RAID_ACTION_START_RAID_FUNCTION StartRaidFunction; + MPI2_RAID_ACTION_STOP_RAID_FUNCTION StopRaidFunction; + MPI2_RAID_ACTION_HOT_SPARE HotSpare; + MPI2_RAID_ACTION_FW_UPDATE_MODE FwUpdateMode; +} MPI2_RAID_ACTION_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_DATA, + Mpi2RaidActionData_t, MPI2_POINTER pMpi2RaidActionData_t; + + +/* RAID Action Request Message */ +typedef struct _MPI2_RAID_ACTION_REQUEST +{ + U8 Action; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U8 ChainOffset; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 VolDevHandle; /* 0x04 */ + U8 PhysDiskNum; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved2; /* 0x0A */ + U32 Reserved3; /* 0x0C */ + MPI2_RAID_ACTION_DATA ActionDataWord; /* 0x10 */ + MPI2_SGE_SIMPLE_UNION ActionDataSGE; /* 0x14 */ +} MPI2_RAID_ACTION_REQUEST, MPI2_POINTER PTR_MPI2_RAID_ACTION_REQUEST, + Mpi2RaidActionRequest_t, MPI2_POINTER pMpi2RaidActionRequest_t; + +/* RAID Action request Action values */ + +#define MPI2_RAID_ACTION_INDICATOR_STRUCT (0x01) +#define MPI2_RAID_ACTION_CREATE_VOLUME (0x02) +#define MPI2_RAID_ACTION_DELETE_VOLUME (0x03) +#define MPI2_RAID_ACTION_DISABLE_ALL_VOLUMES (0x04) +#define MPI2_RAID_ACTION_ENABLE_ALL_VOLUMES (0x05) +#define MPI2_RAID_ACTION_PHYSDISK_OFFLINE (0x0A) +#define MPI2_RAID_ACTION_PHYSDISK_ONLINE (0x0B) +#define MPI2_RAID_ACTION_FAIL_PHYSDISK (0x0F) +#define MPI2_RAID_ACTION_ACTIVATE_VOLUME (0x11) +#define MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE (0x15) +#define MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE (0x17) +#define MPI2_RAID_ACTION_SET_VOLUME_NAME (0x18) +#define MPI2_RAID_ACTION_SET_RAID_FUNCTION_RATE (0x19) +#define MPI2_RAID_ACTION_ENABLE_FAILED_VOLUME (0x1C) +#define MPI2_RAID_ACTION_CREATE_HOT_SPARE (0x1D) +#define MPI2_RAID_ACTION_DELETE_HOT_SPARE (0x1E) +#define MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED (0x20) +#define MPI2_RAID_ACTION_START_RAID_FUNCTION (0x21) +#define MPI2_RAID_ACTION_STOP_RAID_FUNCTION (0x22) + + +/* RAID Volume Creation Structure */ + +/* + * The following define can be customized for the targeted product. + */ +#ifndef MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS +#define MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS (1) +#endif + +typedef struct _MPI2_RAID_VOLUME_PHYSDISK +{ + U8 RAIDSetNum; /* 0x00 */ + U8 PhysDiskMap; /* 0x01 */ + U16 PhysDiskDevHandle; /* 0x02 */ +} MPI2_RAID_VOLUME_PHYSDISK, MPI2_POINTER PTR_MPI2_RAID_VOLUME_PHYSDISK, + Mpi2RaidVolumePhysDisk_t, MPI2_POINTER pMpi2RaidVolumePhysDisk_t; + +/* defines for the PhysDiskMap field */ +#define MPI2_RAIDACTION_PHYSDISK_PRIMARY (0x01) +#define MPI2_RAIDACTION_PHYSDISK_SECONDARY (0x02) + +typedef struct _MPI2_RAID_VOLUME_CREATION_STRUCT +{ + U8 NumPhysDisks; /* 0x00 */ + U8 VolumeType; /* 0x01 */ + U16 Reserved1; /* 0x02 */ + U32 VolumeCreationFlags; /* 0x04 */ + U32 VolumeSettings; /* 0x08 */ + U8 Reserved2; /* 0x0C */ + U8 ResyncRate; /* 0x0D */ + U16 DataScrubDuration; /* 0x0E */ + U64 VolumeMaxLBA; /* 0x10 */ + U32 StripeSize; /* 0x18 */ + U8 Name[16]; /* 0x1C */ + MPI2_RAID_VOLUME_PHYSDISK PhysDisk[MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS];/* 0x2C */ +} MPI2_RAID_VOLUME_CREATION_STRUCT, + MPI2_POINTER PTR_MPI2_RAID_VOLUME_CREATION_STRUCT, + Mpi2RaidVolumeCreationStruct_t, MPI2_POINTER pMpi2RaidVolumeCreationStruct_t; + +/* use MPI2_RAID_VOL_TYPE_ defines from mpi2_cnfg.h for VolumeType */ + +/* defines for the VolumeCreationFlags field */ +#define MPI2_RAID_VOL_CREATION_DEFAULT_SETTINGS (0x80000000) +#define MPI2_RAID_VOL_CREATION_BACKGROUND_INIT (0x00000004) +#define MPI2_RAID_VOL_CREATION_LOW_LEVEL_INIT (0x00000002) +#define MPI2_RAID_VOL_CREATION_MIGRATE_DATA (0x00000001) +/* The following is an obsolete define. + * It must be shifted left 24 bits in order to set the proper bit. + */ +#define MPI2_RAID_VOL_CREATION_USE_DEFAULT_SETTINGS (0x80) + + +/* RAID Online Capacity Expansion Structure */ + +typedef struct _MPI2_RAID_ONLINE_CAPACITY_EXPANSION +{ + U32 Flags; /* 0x00 */ + U16 DevHandle0; /* 0x04 */ + U16 Reserved1; /* 0x06 */ + U16 DevHandle1; /* 0x08 */ + U16 Reserved2; /* 0x0A */ +} MPI2_RAID_ONLINE_CAPACITY_EXPANSION, + MPI2_POINTER PTR_MPI2_RAID_ONLINE_CAPACITY_EXPANSION, + Mpi2RaidOnlineCapacityExpansion_t, + MPI2_POINTER pMpi2RaidOnlineCapacityExpansion_t; + + +/* RAID Volume Indicator Structure */ + +typedef struct _MPI2_RAID_VOL_INDICATOR +{ + U64 TotalBlocks; /* 0x00 */ + U64 BlocksRemaining; /* 0x08 */ + U32 Flags; /* 0x10 */ +} MPI2_RAID_VOL_INDICATOR, MPI2_POINTER PTR_MPI2_RAID_VOL_INDICATOR, + Mpi2RaidVolIndicator_t, MPI2_POINTER pMpi2RaidVolIndicator_t; + +/* defines for RAID Volume Indicator Flags field */ +#define MPI2_RAID_VOL_FLAGS_OP_MASK (0x0000000F) +#define MPI2_RAID_VOL_FLAGS_OP_BACKGROUND_INIT (0x00000000) +#define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001) +#define MPI2_RAID_VOL_FLAGS_OP_CONSISTENCY_CHECK (0x00000002) +#define MPI2_RAID_VOL_FLAGS_OP_RESYNC (0x00000003) + + +/* RAID Action Reply ActionData union */ +typedef union _MPI2_RAID_ACTION_REPLY_DATA +{ + U32 Word[5]; + MPI2_RAID_VOL_INDICATOR RaidVolumeIndicator; + U16 VolDevHandle; + U8 VolumeState; + U8 PhysDiskNum; +} MPI2_RAID_ACTION_REPLY_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_REPLY_DATA, + Mpi2RaidActionReplyData_t, MPI2_POINTER pMpi2RaidActionReplyData_t; + +/* use MPI2_RAIDVOL0_SETTING_ defines from mpi2_cnfg.h for MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE action */ + + +/* RAID Action Reply Message */ +typedef struct _MPI2_RAID_ACTION_REPLY +{ + U8 Action; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U8 MsgLength; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 VolDevHandle; /* 0x04 */ + U8 PhysDiskNum; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved2; /* 0x0A */ + U16 Reserved3; /* 0x0C */ + U16 IOCStatus; /* 0x0E */ + U32 IOCLogInfo; /* 0x10 */ + MPI2_RAID_ACTION_REPLY_DATA ActionData; /* 0x14 */ +} MPI2_RAID_ACTION_REPLY, MPI2_POINTER PTR_MPI2_RAID_ACTION_REPLY, + Mpi2RaidActionReply_t, MPI2_POINTER pMpi2RaidActionReply_t; + + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h Wed Nov 25 13:05:40 2009 +0800 @@ -0,0 +1,435 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2000 to 2009, LSI Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms of all code within + * this file that is exclusively owned by LSI, with or without + * modification, is permitted provided that, in addition to the CDDL 1.0 + * License requirements, the following conditions are met: + * + * Neither the name of the author nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +/* + * Name: mpi2_tool.h + * Title: MPI diagnostic tool structures and definitions + * Creation Date: March 26, 2007 + * + * mpi2_tool.h Version: 02.00.04 + * + * Version History + * --------------- + * + * Date Version Description + * -------- -------- ------------------------------------------------------ + * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. + * 12-18-07 02.00.01 Added Diagnostic Buffer Post and Diagnostic Release + * structures and defines. + * 02-29-08 02.00.02 Modified various names to make them 32-character unique. + * 05-06-09 02.00.03 Added ISTWI Read Write Tool and Diagnostic CLI Tool. + * 07-30-09 02.00.04 Added ExtendedType field to DiagnosticBufferPost request + * and reply messages. + * Added MPI2_DIAG_BUF_TYPE_EXTENDED. + * Incremented MPI2_DIAG_BUF_TYPE_COUNT. + * -------------------------------------------------------------------------- + */ + +#ifndef MPI2_TOOL_H +#define MPI2_TOOL_H + +/***************************************************************************** +* +* Toolbox Messages +* +*****************************************************************************/ + +/* defines for the Tools */ +#define MPI2_TOOLBOX_CLEAN_TOOL (0x00) +#define MPI2_TOOLBOX_MEMORY_MOVE_TOOL (0x01) +#define MPI2_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03) +#define MPI2_TOOLBOX_BEACON_TOOL (0x05) +#define MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL (0x06) + + +/**************************************************************************** +* Toolbox reply +****************************************************************************/ + +typedef struct _MPI2_TOOLBOX_REPLY +{ + U8 Tool; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U8 MsgLength; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 Reserved2; /* 0x04 */ + U8 Reserved3; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved4; /* 0x0A */ + U16 Reserved5; /* 0x0C */ + U16 IOCStatus; /* 0x0E */ + U32 IOCLogInfo; /* 0x10 */ +} MPI2_TOOLBOX_REPLY, MPI2_POINTER PTR_MPI2_TOOLBOX_REPLY, + Mpi2ToolboxReply_t, MPI2_POINTER pMpi2ToolboxReply_t; + + +/**************************************************************************** +* Toolbox Clean Tool request +****************************************************************************/ + +typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST +{ + U8 Tool; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U8 ChainOffset; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 Reserved2; /* 0x04 */ + U8 Reserved3; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved4; /* 0x0A */ + U32 Flags; /* 0x0C */ + } MPI2_TOOLBOX_CLEAN_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_CLEAN_REQUEST, + Mpi2ToolboxCleanRequest_t, MPI2_POINTER pMpi2ToolboxCleanRequest_t; + +/* values for the Flags field */ +#define MPI2_TOOLBOX_CLEAN_BOOT_SERVICES (0x80000000) +#define MPI2_TOOLBOX_CLEAN_PERSIST_MANUFACT_PAGES (0x40000000) +#define MPI2_TOOLBOX_CLEAN_OTHER_PERSIST_PAGES (0x20000000) +#define MPI2_TOOLBOX_CLEAN_FW_CURRENT (0x10000000) +#define MPI2_TOOLBOX_CLEAN_FW_BACKUP (0x08000000) +#define MPI2_TOOLBOX_CLEAN_MEGARAID (0x02000000) +#define MPI2_TOOLBOX_CLEAN_INITIALIZATION (0x01000000) +#define MPI2_TOOLBOX_CLEAN_FLASH (0x00000004) +#define MPI2_TOOLBOX_CLEAN_SEEPROM (0x00000002) +#define MPI2_TOOLBOX_CLEAN_NVSRAM (0x00000001) + + +/**************************************************************************** +* Toolbox Memory Move request +****************************************************************************/ + +typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST +{ + U8 Tool; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U8 ChainOffset; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 Reserved2; /* 0x04 */ + U8 Reserved3; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved4; /* 0x0A */ + MPI2_SGE_SIMPLE_UNION SGL; /* 0x0C */ +} MPI2_TOOLBOX_MEM_MOVE_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_MEM_MOVE_REQUEST, + Mpi2ToolboxMemMoveRequest_t, MPI2_POINTER pMpi2ToolboxMemMoveRequest_t; + + +/**************************************************************************** +* Toolbox ISTWI Read Write Tool +****************************************************************************/ + +/* Toolbox ISTWI Read Write Tool request message */ +typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST +{ + U8 Tool; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U8 ChainOffset; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 Reserved2; /* 0x04 */ + U8 Reserved3; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved4; /* 0x0A */ + U32 Reserved5; /* 0x0C */ + U32 Reserved6; /* 0x10 */ + U8 DevIndex; /* 0x14 */ + U8 Action; /* 0x15 */ + U8 SGLFlags; /* 0x16 */ + U8 Reserved7; /* 0x17 */ + U16 TxDataLength; /* 0x18 */ + U16 RxDataLength; /* 0x1A */ + U32 Reserved8; /* 0x1C */ + U32 Reserved9; /* 0x20 */ + U32 Reserved10; /* 0x24 */ + U32 Reserved11; /* 0x28 */ + U32 Reserved12; /* 0x2C */ + MPI2_SGE_SIMPLE_UNION SGL; /* 0x30 */ +} MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST, + MPI2_POINTER PTR_MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST, + Mpi2ToolboxIstwiReadWriteRequest_t, + MPI2_POINTER pMpi2ToolboxIstwiReadWriteRequest_t; + +/* values for the Action field */ +#define MPI2_TOOL_ISTWI_ACTION_READ_DATA (0x01) +#define MPI2_TOOL_ISTWI_ACTION_WRITE_DATA (0x02) +#define MPI2_TOOL_ISTWI_ACTION_SEQUENCE (0x03) +#define MPI2_TOOL_ISTWI_ACTION_RESERVE_BUS (0x10) +#define MPI2_TOOL_ISTWI_ACTION_RELEASE_BUS (0x11) +#define MPI2_TOOL_ISTWI_ACTION_RESET (0x12) + +/* values for SGLFlags field are in the SGL section of mpi2.h */ + + +/* Toolbox ISTWI Read Write Tool reply message */ +typedef struct _MPI2_TOOLBOX_ISTWI_REPLY +{ + U8 Tool; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U8 MsgLength; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 Reserved2; /* 0x04 */ + U8 Reserved3; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved4; /* 0x0A */ + U16 Reserved5; /* 0x0C */ + U16 IOCStatus; /* 0x0E */ + U32 IOCLogInfo; /* 0x10 */ + U8 DevIndex; /* 0x14 */ + U8 Action; /* 0x15 */ + U8 IstwiStatus; /* 0x16 */ + U8 Reserved6; /* 0x17 */ + U16 TxDataCount; /* 0x18 */ + U16 RxDataCount; /* 0x1A */ +} MPI2_TOOLBOX_ISTWI_REPLY, MPI2_POINTER PTR_MPI2_TOOLBOX_ISTWI_REPLY, + Mpi2ToolboxIstwiReply_t, MPI2_POINTER pMpi2ToolboxIstwiReply_t; + + +/**************************************************************************** +* Toolbox Beacon Tool request +****************************************************************************/ + +typedef struct _MPI2_TOOLBOX_BEACON_REQUEST +{ + U8 Tool; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U8 ChainOffset; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 Reserved2; /* 0x04 */ + U8 Reserved3; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved4; /* 0x0A */ + U8 Reserved5; /* 0x0C */ + U8 PhysicalPort; /* 0x0D */ + U8 Reserved6; /* 0x0E */ + U8 Flags; /* 0x0F */ +} MPI2_TOOLBOX_BEACON_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_BEACON_REQUEST, + Mpi2ToolboxBeaconRequest_t, MPI2_POINTER pMpi2ToolboxBeaconRequest_t; + +/* values for the Flags field */ +#define MPI2_TOOLBOX_FLAGS_BEACONMODE_OFF (0x00) +#define MPI2_TOOLBOX_FLAGS_BEACONMODE_ON (0x01) + + +/**************************************************************************** +* Toolbox Diagnostic CLI Tool +****************************************************************************/ + +#define MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH (0x5C) + +/* Toolbox Diagnostic CLI Tool request message */ +typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST +{ + U8 Tool; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U8 ChainOffset; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 Reserved2; /* 0x04 */ + U8 Reserved3; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved4; /* 0x0A */ + U8 SGLFlags; /* 0x0C */ + U8 Reserved5; /* 0x0D */ + U16 Reserved6; /* 0x0E */ + U32 DataLength; /* 0x10 */ + U8 DiagnosticCliCommand[MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH]; /* 0x14 */ + MPI2_SGE_SIMPLE_UNION SGL; /* 0x70 */ +} MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, + MPI2_POINTER PTR_MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, + Mpi2ToolboxDiagnosticCliRequest_t, + MPI2_POINTER pMpi2ToolboxDiagnosticCliRequest_t; + +/* values for SGLFlags field are in the SGL section of mpi2.h */ + + +/* Toolbox Diagnostic CLI Tool reply message */ +typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY +{ + U8 Tool; /* 0x00 */ + U8 Reserved1; /* 0x01 */ + U8 MsgLength; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 Reserved2; /* 0x04 */ + U8 Reserved3; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved4; /* 0x0A */ + U16 Reserved5; /* 0x0C */ + U16 IOCStatus; /* 0x0E */ + U32 IOCLogInfo; /* 0x10 */ + U32 ReturnedDataLength; /* 0x14 */ +} MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY, + MPI2_POINTER PTR_MPI2_TOOLBOX_DIAG_CLI_REPLY, + Mpi2ToolboxDiagnosticCliReply_t, + MPI2_POINTER pMpi2ToolboxDiagnosticCliReply_t; + + +/***************************************************************************** +* +* Diagnostic Buffer Messages +* +*****************************************************************************/ + + +/**************************************************************************** +* Diagnostic Buffer Post request +****************************************************************************/ + +typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST +{ + U8 ExtendedType; /* 0x00 */ + U8 BufferType; /* 0x01 */ + U8 ChainOffset; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 Reserved2; /* 0x04 */ + U8 Reserved3; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved4; /* 0x0A */ + U64 BufferAddress; /* 0x0C */ + U32 BufferLength; /* 0x14 */ + U32 Reserved5; /* 0x18 */ + U32 Reserved6; /* 0x1C */ + U32 Flags; /* 0x20 */ + U32 ProductSpecific[23]; /* 0x24 */ +} MPI2_DIAG_BUFFER_POST_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REQUEST, + Mpi2DiagBufferPostRequest_t, MPI2_POINTER pMpi2DiagBufferPostRequest_t; + +/* values for the ExtendedType field */ +#define MPI2_DIAG_EXTENDED_TYPE_UTILIZATION (0x02) + +/* values for the BufferType field */ +#define MPI2_DIAG_BUF_TYPE_TRACE (0x00) +#define MPI2_DIAG_BUF_TYPE_SNAPSHOT (0x01) +#define MPI2_DIAG_BUF_TYPE_EXTENDED (0x02) +/* count of the number of buffer types */ +#define MPI2_DIAG_BUF_TYPE_COUNT (0x03) + + +/**************************************************************************** +* Diagnostic Buffer Post reply +****************************************************************************/ + +typedef struct _MPI2_DIAG_BUFFER_POST_REPLY +{ + U8 ExtendedType; /* 0x00 */ + U8 BufferType; /* 0x01 */ + U8 MsgLength; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 Reserved2; /* 0x04 */ + U8 Reserved3; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved4; /* 0x0A */ + U16 Reserved5; /* 0x0C */ + U16 IOCStatus; /* 0x0E */ + U32 IOCLogInfo; /* 0x10 */ + U32 TransferLength; /* 0x14 */ +} MPI2_DIAG_BUFFER_POST_REPLY, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REPLY, + Mpi2DiagBufferPostReply_t, MPI2_POINTER pMpi2DiagBufferPostReply_t; + + +/**************************************************************************** +* Diagnostic Release request +****************************************************************************/ + +typedef struct _MPI2_DIAG_RELEASE_REQUEST +{ + U8 Reserved1; /* 0x00 */ + U8 BufferType; /* 0x01 */ + U8 ChainOffset; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 Reserved2; /* 0x04 */ + U8 Reserved3; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved4; /* 0x0A */ +} MPI2_DIAG_RELEASE_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_RELEASE_REQUEST, + Mpi2DiagReleaseRequest_t, MPI2_POINTER pMpi2DiagReleaseRequest_t; + + +/**************************************************************************** +* Diagnostic Buffer Post reply +****************************************************************************/ + +typedef struct _MPI2_DIAG_RELEASE_REPLY +{ + U8 Reserved1; /* 0x00 */ + U8 BufferType; /* 0x01 */ + U8 MsgLength; /* 0x02 */ + U8 Function; /* 0x03 */ + U16 Reserved2; /* 0x04 */ + U8 Reserved3; /* 0x06 */ + U8 MsgFlags; /* 0x07 */ + U8 VP_ID; /* 0x08 */ + U8 VF_ID; /* 0x09 */ + U16 Reserved4; /* 0x0A */ + U16 Reserved5; /* 0x0C */ + U16 IOCStatus; /* 0x0E */ + U32 IOCLogInfo; /* 0x10 */ +} MPI2_DIAG_RELEASE_REPLY, MPI2_POINTER PTR_MPI2_DIAG_RELEASE_REPLY, + Mpi2DiagReleaseReply_t, MPI2_POINTER pMpi2DiagReleaseReply_t; + + +#endif +
--- a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_ioctl.h Wed Nov 25 12:30:41 2009 +0800 +++ b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_ioctl.h Wed Nov 25 13:05:40 2009 +0800 @@ -70,6 +70,7 @@ #define MPTIOCTL_EVENT_REPORT (MPTIOCTL | 7) #define MPTIOCTL_GET_PCI_INFO (MPTIOCTL | 8) #define MPTIOCTL_DIAG_ACTION (MPTIOCTL | 9) +#define MPTIOCTL_REG_ACCESS (MPTIOCTL | 10) /* * The following are our ioctl() return status values. If everything went @@ -196,7 +197,6 @@ uint32_t ReturnCode; } mptsas_diag_action_t; -#define MPTSAS_FW_DIAGNOSTIC_BUFFER_COUNT (3) #define MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND (0xFF) #define MPTSAS_FW_DIAG_NEW (0x806E6577) @@ -221,7 +221,7 @@ typedef struct mptsas_fw_diag_register { - uint8_t Reserved1; + uint8_t ExtendedType; uint8_t BufferType; uint16_t ApplicationFlags; uint32_t DiagnosticFlags; @@ -241,7 +241,7 @@ typedef struct mptsas_fw_diag_query { - uint8_t Reserved1; + uint8_t ExtendedType; uint8_t BufferType; uint16_t ApplicationFlags; uint32_t DiagnosticFlags; @@ -254,7 +254,7 @@ typedef struct mptsas_fw_diag_release { uint32_t UniqueId; -} mptsas_fw_diag_release; +} mptsas_fw_diag_release_t; #define MPTSAS_FW_DIAG_FLAG_REREGISTER (0x0001) #define MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE (0x0002) @@ -270,6 +270,21 @@ uint32_t DataBuffer[1]; } mptsas_diag_read_buffer_t; +/* + * Register Access + */ +#define REG_IO_READ 1 +#define REG_IO_WRITE 2 +#define REG_MEM_READ 3 +#define REG_MEM_WRITE 4 + +typedef struct mptsas_reg_access +{ + uint32_t Command; + uint32_t RegOffset; + uint32_t RegData; +} mptsas_reg_access_t; + #ifdef __cplusplus } #endif
--- a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h Wed Nov 25 12:30:41 2009 +0800 +++ b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h Wed Nov 25 13:05:40 2009 +0800 @@ -305,6 +305,7 @@ #define CFLAG_TXQ 0x10000000 /* cmd queued in the tx_waitq */ #define CFLAG_FW_CMD 0x20000000 /* cmd is a fw up/down command */ #define CFLAG_CONFIG 0x40000000 /* cmd is for config header/page */ +#define CFLAG_FW_DIAG 0x80000000 /* cmd is for FW diag buffers */ #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE 8 #define MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK 0xC0 @@ -326,6 +327,15 @@ #define MPTSAS_HASH_FIRST 0xffff #define MPTSAS_HASH_NEXT 0x0000 +typedef struct mptsas_dma_alloc_state +{ + ddi_dma_handle_t handle; + caddr_t memp; + size_t size; + ddi_acc_handle_t accessp; + ddi_dma_cookie_t cookie; +} mptsas_dma_alloc_state_t; + /* * passthrough request structure */ @@ -353,6 +363,27 @@ uint16_t ext_page_length; } mptsas_config_request_t; +typedef struct mptsas_fw_diagnostic_buffer { + mptsas_dma_alloc_state_t buffer_data; + uint8_t extended_type; + uint8_t buffer_type; + uint8_t force_release; + uint32_t product_specific[23]; + uint8_t immediate; + uint8_t enabled; + uint8_t valid_data; + uint8_t owned_by_firmware; + uint32_t unique_id; +} mptsas_fw_diagnostic_buffer_t; + +/* + * FW diag request structure + */ +typedef struct mptsas_diag_request { + mptsas_fw_diagnostic_buffer_t *pBuffer; + uint8_t function; +} mptsas_diag_request_t; + typedef struct mptsas_hash_node { void *data; struct mptsas_hash_node *next; @@ -591,6 +622,7 @@ kcondvar_t m_passthru_cv; kcondvar_t m_fw_cv; kcondvar_t m_config_cv; + kcondvar_t m_fw_diag_cv; dev_info_t *m_dip; /* @@ -785,6 +817,7 @@ uint8_t m_done_traverse_dev; uint8_t m_done_traverse_smp; int m_passthru_in_progress; + int m_diag_action_in_progress; uint16_t m_dev_handle; uint16_t m_smp_devhdl; @@ -797,6 +830,22 @@ mptsas_event_entry_t m_events[MPTSAS_EVENT_QUEUE_SIZE]; /* + * FW diag Buffer List + */ + mptsas_fw_diagnostic_buffer_t + m_fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_COUNT]; + + /* + * Event Replay flag (MUR support) + */ + uint8_t m_event_replay; + + /* + * IR Capable flag + */ + uint8_t m_ir_capable; + + /* * per instance cmd data structures for task management cmds */ m_event_struct_t m_event_task_mgmt; /* must be last */ @@ -830,15 +879,6 @@ _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_ntargets)) _NOTE(DATA_READABLE_WITHOUT_LOCK(mptsas::m_instance)) -typedef struct mptsas_dma_alloc_state -{ - ddi_dma_handle_t handle; - caddr_t memp; - size_t size; - ddi_acc_handle_t accessp; - ddi_dma_cookie_t cookie; -} mptsas_dma_alloc_state_t; - /* * These should eventually migrate into the mpt header files * that may become the /kernel/misc/mpt module... @@ -1165,9 +1205,8 @@ uint8_t type, int mode); int mptsas_download_firmware(); int mptsas_can_download_firmware(); -int mptsas_passthru_dma_alloc(mptsas_t *mpt, - mptsas_dma_alloc_state_t *dma_statep); -void mptsas_passthru_dma_free(mptsas_dma_alloc_state_t *dma_statep); +int mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep); +void mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep); uint8_t mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport); uint8_t mptsas_phymask_to_physport(mptsas_t *mpt, uint8_t phymask); void mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd); @@ -1246,6 +1285,7 @@ int mptsas_get_physdisk_settings(mptsas_t *mpt, mptsas_raidvol_t *raidvol, uint8_t physdisknum); int mptsas_delete_volume(mptsas_t *mpt, uint16_t volid); +void mptsas_raid_action_system_shutdown(mptsas_t *mpt); #define MPTSAS_IOCSTATUS(status) (status & MPI2_IOCSTATUS_MASK) /*