#include #include #include #include #include #include #include #include #include #include #include "../mpt3sas_base.h" #include "../mpi/mpi2_sasdiag.h" #include "inc/sasdiag.h" #include "inc/diag_mpt.h" #include "inc/diag_debug.h" /* * Extern Declaration */ extern int _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout, void *config_page, u16 config_page_sz); extern int _config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc, struct config_request *mem); extern void _config_free_config_dma_memory(struct MPT3SAS_ADAPTER *ioc, struct config_request *mem); extern int mpt3sas_config_get_phy_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number); extern struct MPT3SAS_ADAPTER *_scsih_get_ioc_address(int ioc_id); extern bool isIocNumValid(U8 ioc_num); #ifdef ARAPAHO_PLATFORM extern void mpt3sas_base_build_zero_len_sge(struct MPT3SAS_ADAPTER *ioc, void *paddr); #endif extern u8 g_sasdiag_cfg_page_default_timeout; extern u32 g_sasdiag_cfg_page_comn_write_sgl_flag; extern U32 g_sasdiag_cfg_page_comn_sgl_flag; /* Timeout for config page request (in seconds) */ #define MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT 15 int mpt3sas_config_get_iounit_pg7(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage7_t *config_page) { Mpi2ConfigRequest_t mpi_request; int r; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; mpi_request.Header.PageNumber = 7; mpi_request.Header.PageVersion = MPI2_IOUNITPAGE7_PAGEVERSION; ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; r = _config_request(ioc, &mpi_request, mpi_reply, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sizeof(*config_page)); out: return r; } int mpt3sas_config_get_iounit_pg9(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage9_t *config_page, u16 sz) { Mpi2ConfigRequest_t mpi_request; int r; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; mpi_request.Header.PageNumber = 9; mpi_request.Header.PageVersion = MPI2_IOUNITPAGE9_PAGEVERSION; ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; r = _config_request(ioc, &mpi_request, mpi_reply, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); out: return r; } int mpt3sas_config_set_iounit_pg8(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage8_t *config_page, u16 sz) { Mpi2ConfigRequest_t mpi_request; int r; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IO_UNIT; mpi_request.Header.PageNumber = 8; mpi_request.Header.PageVersion = MPI2_IOUNITPAGE8_PAGEVERSION; ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; r = _config_request(ioc, &mpi_request, mpi_reply, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); out: return r; } /** * mpt3sas_config_get_ioc_pg7 - obtain ioc page 7 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int mpt3sas_config_get_ioc_pg7(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage7_t *config_page) { Mpi2ConfigRequest_t mpi_request; int r; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; mpi_request.Header.PageNumber = 7; mpi_request.Header.PageVersion = MPI2_IOCPAGE7_PAGEVERSION; ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; r = _config_request(ioc, &mpi_request, mpi_reply, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sizeof(*config_page)); out: return r; } /** * mpt3sas_config_get_manufacturing_pg1 - obtain manufacturing page 1 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int mpt3sas_config_get_manufacturing_pg1(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage1_t *config_page) { Mpi2ConfigRequest_t mpi_request; int r; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; mpi_request.Header.PageNumber = 1; mpi_request.Header.PageVersion = MPI2_MANUFACTURING1_PAGEVERSION; ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; r = _config_request(ioc, &mpi_request, mpi_reply, MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sizeof(*config_page)); out: return r; } /** * config_get_manufacturing_pg3 - obtain manufacturing page 3 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int config_get_manufacturing_pg3(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2ConfigPageManPage3_t *config_page, U16 sz) { Mpi2ConfigRequest_t mpi_request; int r=0; struct config_request mem; DBG_PRINT(DBG_MPIPAGE, "get_manufacturing_pg3: IOC %d\n", ioc->id); memset(config_page, 0, sz); memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; mpi_request.Header.PageNumber = 3; mpi_request.Header.PageVersion = MPI2_MANUFACTURING5_PAGEVERSION; mpt3sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, g_sasdiag_cfg_page_default_timeout, NULL,0); if (r) goto out; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion; mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber; mpi_request.Header.PageType = mpi_reply->Header.PageType; mpi_request.Header.PageLength = mpi_reply->Header.PageLength; mem.sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4; if (mem.sz > ioc->config_page_sz) { if ((r = _config_alloc_config_dma_memory(ioc, &mem))) goto out; } else { mem.page_dma = ioc->config_page_dma; mem.page = ioc->config_page; } ioc->base_add_sg_single(&mpi_request.PageBufferSGE, g_sasdiag_cfg_page_comn_sgl_flag | mem.sz, mem.page_dma); r = _config_request(ioc, &mpi_request, mpi_reply, g_sasdiag_cfg_page_default_timeout, config_page, sizeof(*config_page)); if (!r) { //DBG_PRINT(DBG_ERR, "IOC %d get_manufacturing_pg3 FAILED\n", ioc->id); memcpy(config_page, mem.page, min_t(u16, sz, mem.sz)); } if (mem.sz > ioc->config_page_sz) _config_free_config_dma_memory(ioc, &mem); out: return r; } /** * config_set_manufacturing_pg5 - obtain manufacturing page 5 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int config_set_manufacturing_pg5(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage5_t *config_page, u16 sz) { Mpi2ConfigRequest_t mpi_request; int r; struct config_request mem; DBG_PRINT(DBG_MPIPAGE, "config_set_manufacturing_pg5: enter\n"); // mutex_lock(&ioc->config_cmds.mutex); //memset(config_page, 0, sz); memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; mpi_request.Header.PageNumber = 5; mpi_request.Header.PageVersion = MPI2_MANUFACTURING5_PAGEVERSION; mpt3sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, g_sasdiag_cfg_page_default_timeout, NULL,0); if (r) goto out; //mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion; mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber; mpi_request.Header.PageType = mpi_reply->Header.PageType; mpi_request.Header.PageLength = mpi_reply->Header.PageLength; mem.sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4; if (mem.sz > ioc->config_page_sz) { if ((r = _config_alloc_config_dma_memory(ioc, &mem))) goto out; } else { mem.page_dma = ioc->config_page_dma; mem.page = ioc->config_page; } memset(mem.page, 0, mem.sz); memcpy(mem.page, config_page, min_t(u16, sz, mem.sz)); ioc->base_add_sg_single(&mpi_request.PageBufferSGE, g_sasdiag_cfg_page_comn_write_sgl_flag | mem.sz, mem.page_dma); //r = _config_request(ioc, &mpi_request, mpi_reply, // MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT,NULL,0);//JIMMY r = _config_request(ioc, &mpi_request, mpi_reply, g_sasdiag_cfg_page_default_timeout,config_page,sz); if (!r){ DBG_PRINT(DBG_MPIPAGE, "config_set_manufacturing_pg5: exit ok\n"); //memcpy(config_page, mem.config_page, // min_t(u16, sz, mem.sz)); } if (mem.sz > ioc->config_page_sz) _config_free_config_dma_memory(ioc, &mem); out: //mutex_unlock(&ioc->config_cmds.mutex); return r; } /** * config_get_manufacturing_pg5 - obtain manufacturing page 5 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int config_get_manufacturing_pg5(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage5_t *config_page, u16 sz, U8 action) { Mpi2ConfigRequest_t mpi_request; int r=0; struct config_request mem; DBG_PRINT(DBG_MPIPAGE, "get_manufacturing_pg5: IOC %d\n", ioc->id); //mutex_lock(&ioc->config_cmds.mutex); memset(config_page, 0, sz); memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; mpi_request.Header.PageNumber = 5; mpi_request.Header.PageVersion = MPI2_MANUFACTURING5_PAGEVERSION; mpt3sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, g_sasdiag_cfg_page_default_timeout, NULL,0); if (r) goto out; mpi_request.Action = action; // MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion; mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber; mpi_request.Header.PageType = mpi_reply->Header.PageType; mpi_request.Header.PageLength = mpi_reply->Header.PageLength; mem.sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4; if (mem.sz > ioc->config_page_sz) { if ((r = _config_alloc_config_dma_memory(ioc, &mem))) goto out; } else { mem.page_dma = ioc->config_page_dma; mem.page = ioc->config_page; } ioc->base_add_sg_single(&mpi_request.PageBufferSGE, g_sasdiag_cfg_page_comn_sgl_flag | mem.sz, mem.page_dma); r = _config_request(ioc, &mpi_request, mpi_reply, g_sasdiag_cfg_page_default_timeout, config_page, sizeof(*config_page)); if (!r) { //DBG_PRINT(DBG_ERR, "IOC %d get_manufacturing_pg5 FAILED\n", ioc->id); memcpy(config_page, mem.page, min_t(u16, sz, mem.sz)); } if (mem.sz > ioc->config_page_sz) _config_free_config_dma_memory(ioc, &mem); out: //mutex_unlock(&ioc->config_cmds.mutex); return r; } #if 0 /** * config_get_manufacturing_pg5 - obtain manufacturing page 5 through HandShake * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int config_get_manufacturing_pg5(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage5_t *config_page, u16 sz) { Mpi2ConfigRequest_t mpi_request; int r; struct config_request mem; int mpi_reply_sz, mpi_request_sz; printk("[Debug Message] 1.config_get_manufacturing_pg5 through handshake!\n"); // mutex_lock(&ioc->config_cmds.mutex); mpi_reply_sz = sizeof(Mpi2ConfigReply_t); mpi_request_sz = sizeof(Mpi2ConfigRequest_t); memset(config_page, 0, sz); memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; mpi_request.Header.PageNumber = 5; mpi_request.Header.PageVersion = MPI2_MANUFACTURING5_PAGEVERSION; base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); printk("[Debug Message] 1.1 config_get_manufacturing_pg5 through handshake!\n"); r = base_handshake_req_reply_wait(ioc, mpi_request_sz, (u32 *)&mpi_request, mpi_reply_sz, (u16 *)mpi_reply, 5, CAN_SLEEP); printk("[Debug Message] 1.2 config_get_manufacturing_pg5 through handshake!\n"); if (r != 0) { printk(MPT3SAS_ERR_FMT "%s: handshake failed (r=%d)\n", ioc->name, __func__, r); goto out; } mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion; mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber; mpi_request.Header.PageType = mpi_reply->Header.PageType; mpi_request.Header.PageLength = mpi_reply->Header.PageLength; mem.sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4; if (mem.sz > ioc->config_page_sz) { if ((r = _config_alloc_config_dma_memory(ioc, &mem))) goto out; } else { mem.page_dma = ioc->config_page_dma; mem.config_page = ioc->config_page; } ioc->base_add_sg_single(&mpi_request.PageBufferSGE, MPT3_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma); r = base_handshake_req_reply_wait(ioc, mpi_request_sz, (u32 *)&mpi_request, mpi_reply_sz, (u16 *)mpi_reply, 5, CAN_SLEEP); if (!r){ printk("[Debug Message] 2.config_get_manufacturing_pg5 through handshake!\n"); memcpy(config_page, mem.config_page, min_t(u16, sz, mem.sz)); } if (mem.sz > ioc->config_page_sz) _config_free_config_dma_memory(ioc, &mem); out: // mutex_unlock(&ioc->config_cmds.mutex); return r; } #endif int config_get_manufacturing_pg6(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2ConfigPageManPage6_t *config_page, U16 sz) { Mpi2ConfigRequest_t mpi_request; int r=0; struct config_request mem; DBG_PRINT(DBG_MPIPAGE, "get_manufacturing_pg6: IOC %d\n", ioc->id); memset(config_page, 0, sz); memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; mpi_request.Header.PageNumber = 6; mpi_request.Header.PageVersion = MPI2_MANUFACTURING5_PAGEVERSION; mpt3sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, g_sasdiag_cfg_page_default_timeout, NULL,0); if (r) goto out; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion; mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber; mpi_request.Header.PageType = mpi_reply->Header.PageType; mpi_request.Header.PageLength = mpi_reply->Header.PageLength; mem.sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4; if (mem.sz > ioc->config_page_sz) { if ((r = _config_alloc_config_dma_memory(ioc, &mem))) goto out; } else { mem.page_dma = ioc->config_page_dma; mem.page = ioc->config_page; } ioc->base_add_sg_single(&mpi_request.PageBufferSGE, g_sasdiag_cfg_page_comn_sgl_flag | mem.sz, mem.page_dma); r = _config_request(ioc, &mpi_request, mpi_reply, g_sasdiag_cfg_page_default_timeout, config_page, sizeof(*config_page)); if (!r) { //DBG_PRINT(DBG_ERR, "IOC %d get_manufacturing_pg6 FAILED\n", ioc->id); memcpy(config_page, mem.page, min_t(u16, sz, mem.sz)); } if (mem.sz > ioc->config_page_sz) _config_free_config_dma_memory(ioc, &mem); out: return r; } void _scsih_dgIocPrintSasIoUnitPage0(Mpi2SasIOUnitPage0_t *p) { int i; printk("\n=============== SAS IO Unit Page 0 ================\n"); printk("NumPhys = 0x%02x\n", p->NumPhys); for ( i = 0; i < p->NumPhys; ++i ) { printk("PHY[%d]:\n", i); printk("\tPhyData.Port = 0x%02x\n", p->PhyData[i].Port); printk("\tPhyData.PortFlags = 0x%02x\n", p->PhyData[i].PortFlags); printk("\tPhyData.PhyFlags = 0x%02x\n", p->PhyData[i].PhyFlags); printk("\tPhyData.NegotiatedLinkRate = 0x%02x\n", p->PhyData[i].NegotiatedLinkRate); printk("\tPhyData.ControllerPhyDeviceInfo = 0x%08x\n", p->PhyData[i].ControllerPhyDeviceInfo); printk("\tPhyData.AttachedDevHandle = 0x%04x\n", p->PhyData[i].AttachedDevHandle); printk("\tPhyData.ControllerDevHandle = 0x%04x\n", p->PhyData[i].ControllerDevHandle); printk("\tPhyData.DiscoveryStatus = 0x%08x\n", p->PhyData[i].DiscoveryStatus); } printk("===================================================\n"); } void _scsih_dgIocPrintSasIoUnitPage1(Mpi2SasIOUnitPage1_t *p) { int i; printk("\n=============== SAS IO Unit Page 1 ================\n"); printk("ControlFlags = 0x%04x\n", p->ControlFlags); printk("SASNarrowMaxQueueDepth = 0x%04x\n", p->SASNarrowMaxQueueDepth); printk("AdditionalControlFlags = 0x%04x\n", p->AdditionalControlFlags); printk("SASWideMaxQueueDepth = 0x%04x\n", p->SASWideMaxQueueDepth); printk("NumPhys = 0x%02x\n", p->NumPhys); printk("SATAMaxQDepth = 0x%02x\n", p->SATAMaxQDepth); printk("ReportDevMissingDelay = 0x%02x\n", p->ReportDeviceMissingDelay); for ( i = 0; i < p->NumPhys; ++i ) { printk("PHY[%d]:\n", i); printk("\tPhyData.Port = 0x%02x\n", p->PhyData[i].Port); printk("\tPhyData.PortFlags = 0x%02x\n", p->PhyData[i].PortFlags); printk("\tPhyData.PhyFlags = 0x%02x\n", p->PhyData[i].PhyFlags); printk("\tPhyData.MaxMinLinkRate = 0x%02x\n", p->PhyData[i].MaxMinLinkRate); printk("\tPhyData.ControllerPhyDeviceInfo = 0x%08x\n", p->PhyData[i].ControllerPhyDeviceInfo); printk("\tPhyData.MaxTgtPortConnectTime = 0x%04x\n", p->PhyData[i].MaxTargetPortConnectTime); } printk("===================================================\n"); } void _scsih_dgIocPrintSasPhyPage0(Mpi2SasPhyPage0_t *p, U8 phy) { printk("PhyPage0 for PHY [%d]\n", phy); printk("\tOwnerDevHandle = 0x%04x\n", p->OwnerDevHandle); printk("\tAttachedDevHandle = 0x%04x\n", p->AttachedDevHandle); printk("\tAttachedPhyIdentifier= 0x%02x\n", p->AttachedPhyIdentifier); printk("\tAttachedDeviceInfo = 0x%08x\n", p->AttachedPhyInfo); printk("\tProgrammedLinkRate = 0x%02x\n", p->ProgrammedLinkRate); printk("\tHwLinkRate = 0x%02x\n", p->HwLinkRate); printk("\tChangeCount = 0x%02x\n", p->ChangeCount); printk("\tFlag = 0x%02x\n", p->Flags); printk("\tPhyInfo = 0x%08x\n", p->PhyInfo); printk("\tNegotiateLinkRate = 0x%02x\n", p->NegotiatedLinkRate); } void _scsih_dgIocPrintSasExpPage0(Mpi2ExpanderPage0_t *p) { printk("============ SAS Exp Page 0 ==============\n"); printk("PhysicalPort = 0x%02x\n", p->PhysicalPort); printk("ReportGenLen = 0x%02x\n", p->ReportGenLength); printk("EnclosureHandle = 0x%04x\n", p->EnclosureHandle); printk("SASAddress = 0x%08x%08x\n", (U32)(p->SASAddress >> 32), (U32)(p->SASAddress & 0xffffffffLL)); printk("DiscoveryStatus = 0x%08x\n", p->DiscoveryStatus); printk("DevHandle = 0x%04x\n", p->DevHandle); printk("ParentDevHandle = 0x%04x\n", p->ParentDevHandle); printk("ExpanderChangeCnt = 0x%04x\n", p->ExpanderChangeCount); printk("ExpanderRouteIdx = 0x%04x\n", p->ExpanderRouteIndexes); printk("NumPhys = 0x%02x\n", p->NumPhys); printk("SASLevel = 0x%02x\n", p->SASLevel); printk("Flags = 0x%04x\n", p->Flags); printk("STPBusInactTime = 0x%04x\n", p->STPBusInactivityTimeLimit); printk("STPMaxConnectTime = 0x%04x\n", p->STPMaxConnectTimeLimit); printk("STP_SMP_NexLostTime = 0x%04x\n", p->STP_SMP_NexusLossTime); printk("MaxNumRouteSasAddr = 0x%04x\n", p->MaxNumRoutedSasAddresses); printk("ActiveZoneMgrAddr = 0x%08x%08x\n", (U32)(p->ActiveZoneManagerSASAddress >> 32), (U32)(p->ActiveZoneManagerSASAddress & 0xffffffffLL)); printk("ZoneLockInactLimit = 0x%04x\n", p->ZoneLockInactivityLimit); printk("TimeToReduceFunc = 0x%02x\n", p->TimeToReducedFunc); printk("InitTimeToReduceFunc = 0x%02x\n", p->InitialTimeToReducedFunc); printk("MaxReduceFuncTime = 0x%02x\n", p->MaxReducedFuncTime); printk("===========================================\n"); } void _scsih_dgIocPrintSasExpPage1(Mpi2ExpanderPage1_t *p, U8 phy) { printk("ExpanderPage1 for PHY [%d]\n", phy); printk("\tPhysicalPort = 0x%02x\n", p->PhysicalPort); printk("\tNumPhys = 0x%02x\n", p->NumPhys); printk("\tPhy = 0x%02x\n", p->Phy); printk("\tNumTblEntryProg = 0x%04x\n", p->NumTableEntriesProgrammed); printk("\tProgrammedLinkRate = 0x%02x\n", p->ProgrammedLinkRate); printk("\tHwLinkRate = 0x%02x\n", p->HwLinkRate); printk("\tAttachedDevHandle = 0x%04x\n", p->AttachedDevHandle); printk("\tPhyInfo = 0x%08x\n", p->PhyInfo); printk("\tAttachedDeviceInfo = 0x%08x\n", p->AttachedDeviceInfo); printk("\tExpanderDevHandle = 0x%04x\n", p->ExpanderDevHandle); printk("\tChangeCount = 0x%02x\n", p->ChangeCount); printk("\tNegotiatedLinkRate = 0x%02x\n", p->NegotiatedLinkRate); printk("\tPhyIdentifier = 0x%02x\n", p->PhyIdentifier); printk("\tAttachedPhyIdentifier = 0x%x\n", p->AttachedPhyIdentifier); printk("\tDiscoveryInfo = 0x%02x\n", p->DiscoveryInfo); printk("\tAttachedPhyInfo = 0x%08x\n", p->AttachedPhyInfo); printk("\tZoneGroup = 0x%02x\n", p->ZoneGroup); printk("\tSelfConfigStatus = 0x%02x\n", p->SelfConfigStatus); printk("===========================================\n"); } void _scsih_dgIocPrintSasDevPage0(Mpi2SasDevicePage0_t *p) { printk("\n============ SAS Device Page 0 =============\n"); printk("Slot = 0x%02x\n", p->Slot); printk("EnclosureHandle = 0x%04x\n", p->EnclosureHandle); printk("SASAddress = 0x%08x%08x\n", (U32)(p->SASAddress >> 32), (U32)(p->SASAddress & 0xffffffffLL)); printk("ParentDevHandle = 0x%04x\n", p->ParentDevHandle); printk("PhyNum = 0x%02x\n", p->PhyNum); printk("AccessStatus = 0x%02x\n", p->AccessStatus); printk("DevHandle = 0x%04x\n", p->DevHandle); printk("AttachedPhyIden = 0x%02x\n", p->AttachedPhyIdentifier); printk("ZoneGroup = 0x%02x\n", p->ZoneGroup); printk("DeviceInfo = 0x%08x\n", p->DeviceInfo); printk("Flags = 0x%04x\n", p->Flags); printk("PhysicalPort = 0x%02x\n", p->PhysicalPort); printk("MaxPortConnect = 0x%02x\n", p->MaxPortConnections); printk("DeviceName = 0x%08x%08x\n", (U32)(p->DeviceName >> 32), (U32)(p->DeviceName & 0xffffffffLL)); printk("PortGroups = 0x%02x\n", p->PortGroups); printk("DmaGroups = 0x%02x\n", p->DmaGroup); printk("ControlGroups = 0x%02x\n", p->ControlGroup); printk("===============================================\n"); } int _scsih_dgIocShowSasIoUnitPage0(int ioc_id) { int failCnt = 0; u16 sz; u16 ioc_status; Mpi2ConfigReply_t mpi_reply; Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; struct MPT3SAS_ADAPTER *ioc = NULL; ioc = _scsih_get_ioc_address(ioc_id); if (!ioc) return -1; sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys * sizeof(Mpi2SasIOUnit0PhyData_t)); sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL); if (!sas_iounit_pg0) { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); return -1; } if (!(mpt3sas_config_get_sas_iounit_pg0(ioc, &mpi_reply, sas_iounit_pg0, sz))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS){ printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); failCnt++; goto out; } }else{ printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); failCnt++; goto out; } _scsih_dgIocPrintSasIoUnitPage0(sas_iounit_pg0); out: if (sas_iounit_pg0) kfree(sas_iounit_pg0); if (failCnt) return -1; else return 0; } int _scsih_dgIocShowSasIoUnitPage1(int ioc_id) { int failCnt = 0; u16 sz; u16 ioc_status; Mpi2ConfigReply_t mpi_reply; Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; struct MPT3SAS_ADAPTER *ioc = NULL; ioc = _scsih_get_ioc_address(ioc_id); if (!ioc) return -1; sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * sizeof(Mpi2SasIOUnit1PhyData_t)); sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); if (!sas_iounit_pg1) { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); return -1; } if (!(mpt3sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS){ printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); failCnt++; goto out; } }else{ printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); failCnt++; goto out; } _scsih_dgIocPrintSasIoUnitPage1(sas_iounit_pg1); out: if (sas_iounit_pg1) kfree(sas_iounit_pg1); if (failCnt) return -1; else return 0; } int config_get_manufacturing_pg2(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage2_t *config_page, U16 sz, U8 action) { Mpi2ConfigRequest_t mpi_request; int r=0; struct config_request mem; DBG_PRINT(DBG_MPIPAGE, "get_manufacturing_pg2: IOC %d\n", ioc->id); memset(config_page, 0, sz); memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; mpi_request.Header.PageNumber = 2; mpi_request.Header.PageVersion = MPI2_MANUFACTURING5_PAGEVERSION; mpt3sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, g_sasdiag_cfg_page_default_timeout, NULL,0); if (r) goto out; mpi_request.Action = action; // MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion; mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber; mpi_request.Header.PageType = mpi_reply->Header.PageType; mpi_request.Header.PageLength = mpi_reply->Header.PageLength; mem.sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4; if (mem.sz > ioc->config_page_sz) { if ((r = _config_alloc_config_dma_memory(ioc, &mem))) goto out; } else { mem.page_dma = ioc->config_page_dma; mem.page = ioc->config_page; } ioc->base_add_sg_single(&mpi_request.PageBufferSGE, g_sasdiag_cfg_page_comn_sgl_flag | mem.sz, mem.page_dma); r = _config_request(ioc, &mpi_request, mpi_reply, g_sasdiag_cfg_page_default_timeout, config_page, sizeof(*config_page)); if (!r) { //DBG_PRINT(DBG_ERR, "IOC %d get_manufacturing_pg2 FAILED\n", ioc->id); memcpy(config_page, mem.page, min_t(u16, sz, mem.sz)); } if (mem.sz > ioc->config_page_sz) _config_free_config_dma_memory(ioc, &mem); out: return r; } int config_set_manufacturing_pg2(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage2_t *config_page, u16 sz) { Mpi2ConfigRequest_t mpi_request; int r; struct config_request mem; DBG_PRINT(DBG_MPIPAGE, "set_manufacturing_pg2: IOC %d\n", ioc->id); memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING; mpi_request.Header.PageNumber = 2; mpi_request.Header.PageVersion = MPI2_MANUFACTURING2_PAGEVERSION; mpt3sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, g_sasdiag_cfg_page_default_timeout, NULL,0); if (r) return r; // Always write NVRAM to force update to the physical SBR (SEEPROM) mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion; mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber; mpi_request.Header.PageType = mpi_reply->Header.PageType; mpi_request.Header.PageLength = mpi_reply->Header.PageLength; mem.sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4; if (mem.sz > ioc->config_page_sz) { if ((r = _config_alloc_config_dma_memory(ioc, &mem))) goto out; } else { mem.page_dma = ioc->config_page_dma; mem.page = ioc->config_page; } memset(mem.page, 0, mem.sz); memcpy(mem.page, config_page, min_t(u16, sz, mem.sz)); ioc->base_add_sg_single(&mpi_request.PageBufferSGE, g_sasdiag_cfg_page_comn_write_sgl_flag | mem.sz, mem.page_dma); r = _config_request(ioc, &mpi_request, mpi_reply, g_sasdiag_cfg_page_default_timeout,config_page,sz); if (r) { DBG_PRINT(DBG_ERR, "set_manufacturing_pg2: IOC %d failed\n", ioc->id); } else { DBG_PRINT(DBG_MPIPAGE, "set_manufacturing_pg2: IOC %d successful\n", ioc->id); } out: if (mem.sz > ioc->config_page_sz) _config_free_config_dma_memory(ioc, &mem); return r; } int sasdiag_showManPage2(U8 ioc_num, U8 action) { struct MPT3SAS_ADAPTER *ioc; Mpi2ManufacturingPage2_t *manuf_page2; Mpi2ConfigReply_t mpi_reply; U16 sz, ioc_status; if (!isIocNumValid(ioc_num)) return IOC_NUM_INVALID; if ((ioc = _scsih_get_ioc_address(ioc_num)) == NULL) { DBG_PRINT(DBG_ERR, "showManPage2: IOC %d FAILED to get ioc addr!\n", ioc_num); return -1; } sz = sizeof(Mpi2ManufacturingPage2_t); manuf_page2 = kzalloc(sz, GFP_KERNEL); if (!manuf_page2) { DBG_PRINT(DBG_ERR, "showManPage2: IOC %d mem alloc failed\n", ioc_num); return -1; } if (!(config_get_manufacturing_pg2(ioc, &mpi_reply, manuf_page2, sz, action))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { DBG_PRINT(DBG_ERR, "showManPage2: IOC %d get man page2 status !ok\n", ioc_num); kfree(manuf_page2); return -1; } } else { DBG_PRINT(DBG_ERR, "showManPage2: IOC %d get man page2 failed\n", ioc_num); kfree(manuf_page2); return -1; } printk("\nPAGE FOR IOC %d", ioc_num); printk("\n============ Manufacture Page 2 =============\n"); printk("chipId.DeviceId = 0x%04x\n", manuf_page2->ChipId.DeviceID); printk("chipId.PCIRevisionID = 0x%02x\n", manuf_page2->ChipId.PCIRevisionID); printk("HwSettings (SBR content):\n"); kfree(manuf_page2); return 0; } int sasdiag_showManPage3(U8 ioc_num) { struct MPT3SAS_ADAPTER *ioc; Mpi2ConfigPageManPage3_t *manuf_page3; Mpi2ConfigReply_t mpi_reply; U16 sz, i, ioc_status; if (!isIocNumValid(ioc_num)) return IOC_NUM_INVALID; if ((ioc = _scsih_get_ioc_address(ioc_num)) == NULL) { DBG_PRINT(DBG_ERR, "showManPage3: IOC %d FAILED to get ioc addr!\n", ioc_num); return -1; } sz = sizeof(Mpi2ConfigPageManPage3_t); manuf_page3 = kzalloc(sz, GFP_KERNEL); if (!manuf_page3) { DBG_PRINT(DBG_ERR, "showManPage3: IOC %d mem alloc failed\n", ioc_num); return -1; } if (!(config_get_manufacturing_pg3(ioc, &mpi_reply, manuf_page3, sz))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { DBG_PRINT(DBG_ERR, "showManPage3: IOC %d get man page3 status !ok\n", ioc_num); kfree(manuf_page3); return -1; } } else { DBG_PRINT(DBG_ERR, "showManPage3: IOC %d get man page3 failed\n", ioc_num); kfree(manuf_page3); return -1; } printk("\nPAGE FOR IOC %d", ioc_num); printk("\n============ Manufacture Page 3 =============\n"); printk("ChipId.DeviceID = 0x%04x\n", manuf_page3->ChipId.DeviceID); printk("ChipId.PCIRevisionID = 0x%02x\n", manuf_page3->ChipId.PCIRevisionID); printk("ChipId.Reserve = 0x%02x\n", manuf_page3->ChipId.Reserved); for (i = 0; i < 4; i++) { printk("PhyGroup[%d]:\n", i); printk("\tMisc = 0x%08x\n", manuf_page3->PhyGroup[i].Misc); printk("\tSas1G1Low = 0x%08x\n", manuf_page3->PhyGroup[i].Sas1G1Low); printk("\tSas1G1High = 0x%08x\n", manuf_page3->PhyGroup[i].Sas1G1High); printk("\tSas1G2Low = 0x%08x\n", manuf_page3->PhyGroup[i].Sas1G2Low); printk("\tSas1G2High = 0x%08x\n", manuf_page3->PhyGroup[i].Sas1G2High); printk("\tSasOobLow = 0x%08x\n", manuf_page3->PhyGroup[i].SasOobLow); printk("\tSasOobHigh = 0x%08x\n", manuf_page3->PhyGroup[i].SasOobHigh); printk("\tSas2G1Low = 0x%08x\n", manuf_page3->PhyGroup[i].Sas2G1Low); printk("\tSas2G1High = 0x%08x\n", manuf_page3->PhyGroup[i].Sas2G1High); printk("\tSas2G2Low = 0x%08x\n", manuf_page3->PhyGroup[i].Sas2G2Low); printk("\tSas2G2High = 0x%08x\n", manuf_page3->PhyGroup[i].Sas2G2High); printk("\tSas2G3Low = 0x%08x\n", manuf_page3->PhyGroup[i].Sas2G3Low); printk("\tSas2G3High = 0x%08x\n", manuf_page3->PhyGroup[i].Sas2G3High); printk("\tSataG1Low = 0x%08x\n", manuf_page3->PhyGroup[i].SataG1Low); printk("\tSataG1High = 0x%08x\n", manuf_page3->PhyGroup[i].SataG1High); printk("\tSataG2Low = 0x%08x\n", manuf_page3->PhyGroup[i].SataG2Low); printk("\tSataG2High = 0x%08x\n", manuf_page3->PhyGroup[i].SataG2High); printk("\tSataG3Low = 0x%08x\n", manuf_page3->PhyGroup[i].SataG3Low); printk("\tSataG3High = 0x%08x\n", manuf_page3->PhyGroup[i].SataG3High); printk("\tSataOobLow = 0x%08x\n", manuf_page3->PhyGroup[i].SataOobLow); printk("\tSataOobHigh = 0x%08x\n", manuf_page3->PhyGroup[i].SataOobHigh); } printk("NumPhys = 0x%02x\n", manuf_page3->NumPhys); for (i = 0; i < MAX_IOC_PHYS; i++) printk("\tPhy[%d]: 0x%08x\n", i, manuf_page3->Phy[i]); kfree(manuf_page3); return 0; } int sasdiag_showManPage5(U8 ioc_num) { struct MPT3SAS_ADAPTER *ioc; Mpi2ManufacturingPage5_t *manuf_page5; Mpi2ConfigReply_t mpi_reply; U16 sz, i, ioc_status; U64 SASAddress; if (!isIocNumValid(ioc_num)) return IOC_NUM_INVALID; if ((ioc = _scsih_get_ioc_address(ioc_num)) == NULL) { DBG_PRINT(DBG_ERR, "showManPage5: IOC %d FAILED to get ioc addr!\n", ioc_num); return -1; } sz = offsetof(Mpi2ManufacturingPage5_t, Phy) + (MAX_IOC_PHYS * sizeof(Mpi2Manufacturing5Entry_t)); manuf_page5 = kzalloc(sz, GFP_KERNEL); if (!manuf_page5) { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); return -1; } if (!(config_get_manufacturing_pg5(ioc, &mpi_reply, manuf_page5, sz, MPI2_CONFIG_ACTION_PAGE_READ_CURRENT))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); return -1; kfree(manuf_page5); } } else { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); kfree(manuf_page5); return -1; } printk("\nPAGE FOR IOC %d", ioc_num); printk("\n============ Manufacture Page 5 =============\n"); for (i = 0; i < MAX_IOC_PHYS; ++i) { printk("\n"); memcpy(&SASAddress, &(manuf_page5->Phy[i].WWID), sizeof(U64)); printk("Phy[%d] WWID=0x%08x%08x\n", i, (u32)(SASAddress >> 32), (u32)(SASAddress & 0xffffffffLL)); memcpy(&SASAddress, &(manuf_page5->Phy[i].DeviceName), sizeof(U64)); printk("Phy[%d] DeviceName=0x%08x%08x\n", i, (u32)(SASAddress >> 32), (u32)(SASAddress & 0xffffffffLL)); } kfree(manuf_page5); return 0; } int sasdiag_showManPage6(U8 ioc_num) { struct MPT3SAS_ADAPTER *ioc; Mpi2ConfigPageManPage6_t *manuf_page6; Mpi2ConfigReply_t mpi_reply; U16 sz, i, ioc_status; if (!isIocNumValid(ioc_num)) return IOC_NUM_INVALID; if ((ioc = _scsih_get_ioc_address(ioc_num)) == NULL) { DBG_PRINT(DBG_ERR, "showManPage5: IOC %d FAILED to get ioc addr!\n", ioc_num); return -1; } sz = sizeof(Mpi2ConfigPageManPage6_t); manuf_page6 = kzalloc(sz, GFP_KERNEL); if (!manuf_page6) { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); return -1; } if (!(config_get_manufacturing_pg6(ioc, &mpi_reply, manuf_page6, sz))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); kfree(manuf_page6); return -1; } } else { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); kfree(manuf_page6); return -1; } printk("\nPAGE FOR IOC %d", ioc_num); printk("\n============ Manufacture Page 6 =============\n"); printk("NumGPIO = %d\n", manuf_page6->NumGPIO); for (i = 20; i < 24; i++) { // for now just support Glacier which uses only 4 GPIO printk("GPIODefinition[%d]:\n", i); printk("\tFunctionCode = 0x%02x\n", manuf_page6->GPIODefinition[i].FunctionCode); printk("\tFlags = 0x%02x\n", manuf_page6->GPIODefinition[i].Flags); printk("\tParam1 = 0x%02x\n", manuf_page6->GPIODefinition[i].Param1); printk("\tParam2 = 0x%02x\n", manuf_page6->GPIODefinition[i].Param2); printk("\tParam3 = 0x%02x\n", manuf_page6->GPIODefinition[i].Param3); } kfree(manuf_page6); return 0; } int sasdiag_showManPage8(U8 ioc_num) { printk("\nPAGE FOR IOC %d TO BE IMPLEMENTED ...", ioc_num); return 0; } int sasdiag_showIocPhyPage0(U8 ioc_num, U8 phy) { struct MPT3SAS_ADAPTER *ioc = NULL; Mpi2ConfigReply_t mpi_reply; Mpi2SasPhyPage0_t phy_pg0; U16 ioc_status = 0; U8 i, numToShow = 0; if (!isIocNumValid(ioc_num)) { DBG_PRINT(DBG_MPIPAGE, "showIocPhyPage0: IOC %d invalid\n", ioc_num); return IOC_NUM_INVALID; } if ((ioc = _scsih_get_ioc_address(ioc_num)) == NULL) { DBG_PRINT(DBG_ERR, "showIocPhyPage0: IOC %d FAILED to get ioc addr!\n", ioc_num); return -1; } if (phy == PHY_NUM_ALL) { i = 0; numToShow = MAX_IOC_PHYS; } else { i = phy; numToShow = 1; } printk("\nPAGE FOR IOC %d", ioc_num); printk("\n============ SAS PHY Page 0 =============\n"); do { if ((mpt3sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0, i))) { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); return -1; } ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { printk(MPT3SAS_ERR_FMT "failure at phy %d %s:%d/%s()!\n", ioc->name, i, __FILE__, __LINE__, __func__); return -1; } _scsih_dgIocPrintSasPhyPage0(&phy_pg0, i); i++; } while (--numToShow > 0); return 0; } int sasdiag_showDevicePage0(U8 ioc_num, U16 devHandle) { struct MPT3SAS_ADAPTER *ioc; Mpi2SasDevicePage0_t sas_device_pg0; Mpi2ConfigReply_t mpi_reply; U16 ioc_status; if (!isIocNumValid(ioc_num)) return IOC_NUM_INVALID; if ((ioc = _scsih_get_ioc_address(ioc_num)) == NULL) { DBG_PRINT(DBG_ERR, "showDevPage0: IOC %d FAILED to get ioc addr!\n", ioc_num); return -1; } if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, devHandle))) { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); return -1; } ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); return -1; } printk("\nPAGE FOR DEVHANDLE 0x%04x", devHandle); _scsih_dgIocPrintSasDevPage0(&sas_device_pg0); return 0; } int sasdiag_showExpPage0(U8 ioc_num, U16 devHandle) { struct MPT3SAS_ADAPTER *ioc; Mpi2ExpanderPage0_t expander_pg0; Mpi2ConfigReply_t mpi_reply; U16 ioc_status; if (!isIocNumValid(ioc_num)) return IOC_NUM_INVALID; if ((ioc = _scsih_get_ioc_address(ioc_num)) == NULL) { DBG_PRINT(DBG_ERR, "showDevPage0: IOC %d FAILED to get ioc addr!\n", ioc_num); return -1; } if ((mpt3sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0, MPI2_SAS_EXPAND_PGAD_FORM_HNDL, devHandle))) { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); return -1; } ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); return -1; } printk("\nPAGE FOR EXPANDER DEVHANDLE 0x%04x", devHandle); _scsih_dgIocPrintSasExpPage0(&expander_pg0); return 0; } int sasdiag_showExpPage1(U8 ioc_num, U16 devHandle, U8 phy) { struct MPT3SAS_ADAPTER *ioc; Mpi2ExpanderPage1_t expander_pg1; Mpi2ConfigReply_t mpi_reply; U16 ioc_status; U8 i, numToShow; if (!isIocNumValid(ioc_num)) return IOC_NUM_INVALID; if ((ioc = _scsih_get_ioc_address(ioc_num)) == NULL) { DBG_PRINT(DBG_ERR, "showDevPage0: IOC %d FAILED to get ioc addr!\n", ioc_num); return -1; } if (phy == PHY_NUM_ALL) { i = 0; numToShow = MAX_IOC_PHYS; } else { i = phy; numToShow = 1; } do { if ((mpt3sas_config_get_expander_pg1(ioc, &mpi_reply, &expander_pg1, MPI2_SAS_EXPAND_PGAD_FORM_HNDL, devHandle))) { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); return -1; } ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { printk(MPT3SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); return -1; } printk("\nPAGE FOR EXPANDER DEVHANDLE 0x%04x", devHandle); printk("\n============ Expander PHY Page 1 =============\n"); _scsih_dgIocPrintSasExpPage1(&expander_pg1, i); i++; } while (--numToShow > 0); return 0; } int sasdiag_initSbrFromManPage2(U8 ioc_num) { struct MPT3SAS_ADAPTER *ioc; Mpi2ManufacturingPage2_t *manuf_page2 = NULL, *page2_nvram = NULL; Mpi2ConfigReply_t mpi_reply; U16 sz, ioc_status; if (!isIocNumValid(ioc_num)) return IOC_NUM_INVALID; if ((ioc = _scsih_get_ioc_address(ioc_num)) == NULL) { DBG_PRINT(DBG_ERR, "initSbrFromManPage2: IOC %d FAILED to get ioc addr!\n", ioc_num); return -1; } sz = sizeof(Mpi2ManufacturingPage2_t); manuf_page2 = kzalloc(sz, GFP_KERNEL); page2_nvram = kzalloc(sz, GFP_KERNEL); if (!manuf_page2 || page2_nvram) { DBG_PRINT(DBG_ERR, "initSbrFromManPage2: IOC %d - mem alloc failed\n", ioc_num); return -1; } // // Follow steps specified by LSI SCD: // - Read current // - Read NVRAM // - if read NVRAM has eror ==> SBR is empty, write NVRAMA with the read current data // - if read NVRAM good, compare to the read current data // - if not matched ==> two SBR partitions not sync, write NVRAM with the the read current data // NOTE: after writing to SBR (write NVRAM), need to reset (pci reset, hardreset or power reset)to take effect // if (!(config_get_manufacturing_pg2(ioc, &mpi_reply, manuf_page2, sz, MPI2_CONFIG_ACTION_PAGE_READ_CURRENT))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { DBG_PRINT(DBG_ERR, "initSbrFromManPage2: IOC %d read current !ok\n", ioc_num); goto error_out; } } else { DBG_PRINT(DBG_MPIPAGE, "initSbrFromManPage2: IOC %d read current failed\n", ioc_num); goto error_out; } if (!(config_get_manufacturing_pg2(ioc, &mpi_reply, manuf_page2, sz, MPI2_CONFIG_ACTION_PAGE_READ_NVRAM))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { DBG_PRINT(DBG_MPIPAGE, "initSbrFromManPage2: IOC %d read nvram !ok, write current to sbr\n", ioc_num); goto write_sbr; } } else { DBG_PRINT(DBG_ERR, "initSbrFromManPage2: IOC %d read nvram failed, return err\n", ioc_num); goto error_out; } // here means successful read nvram, compare, if not match, write current data to sbr if (memcmp(manuf_page2, page2_nvram, sizeof(Mpi2ManufacturingPage2_t)) != 0) { DBG_PRINT(DBG_MPIPAGE, "initSbrFromManPage2: IOC %d nvram-current different, write current to sbr\n", ioc_num); goto write_sbr; } else { DBG_PRINT(DBG_MPIPAGE, "initSbrFromManPage2: IOC %d nvram matches current, return success\n", ioc_num); goto exit_ok; } write_sbr: // write NVRAM (which is SBR) the page data obtained form read current if (!(config_set_manufacturing_pg2(ioc, &mpi_reply, manuf_page2, sz))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { DBG_PRINT(DBG_ERR, "initSbrFromManPage2: IOC %d write to sbr !ok\n", ioc_num); goto error_out; } } else { DBG_PRINT(DBG_ERR, "initSbrFromManPage2: IOC %d write to sbr failed\n", ioc_num); goto error_out; } error_out: if (manuf_page2) kfree(manuf_page2); if (page2_nvram) kfree(page2_nvram); return -1; exit_ok: if (manuf_page2) kfree(manuf_page2); if (page2_nvram) kfree(page2_nvram); return 0; }