Print this page
Update tx waitq's code.
Create 2 threads, divide the workflow and deliver
to the hardware from the threads.
Enable Fast Path for capable devices.
Lint and cstyle fixes.
Fix problem with running against 64bit msgaddr attributes for DMA.
Default is now to run like this.
Major rework of mutexes.
During normal operation do not grab m_mutex during interrupt.
Use reply post queues instead.
Fixes to some address arithmetic using 32bit values.
Merge fixes for "4403 mpt_sas panic when pulling a drive", commit f7d0d869a9ae78d
Initial modifications using the code changes present between
the LSI source code for FreeBSD drivers. Specifically the changes
between from mpslsi-source-17.00.00.00 -> mpslsi-source-03.00.00.00.
This mainly involves using a different scatter/gather element in
frame setup.
Changes to enable driver to compile.
Header paths, object lists, etc.

*** 20,29 **** --- 20,31 ---- */ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2012 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2014, Tegile Systems Inc. All rights reserved. + * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved. */ /* * Copyright (c) 2000 to 2010, LSI Corporation. * All rights reserved.
*** 66,97 **** #include <sys/note.h> #include <sys/scsi/scsi.h> #include <sys/pci.h> #pragma pack(1) ! #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h> ! #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h> ! #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_sas.h> ! #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h> #pragma pack() /* * private header files. */ ! #include <sys/scsi/adapters/mpt_sas/mptsas_var.h> ! #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h> /* * FMA header files. */ #include <sys/fm/io/ddi.h> #if defined(MPTSAS_DEBUG) extern uint32_t mptsas_debug_flags; #endif /* * prototypes */ --- 68,100 ---- #include <sys/note.h> #include <sys/scsi/scsi.h> #include <sys/pci.h> #pragma pack(1) ! #include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_type.h> ! #include <sys/scsi/adapters/mpt_sas3/mpi/mpi2.h> ! #include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_cnfg.h> ! #include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_init.h> ! #include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_ioc.h> ! #include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_sas.h> ! #include <sys/scsi/adapters/mpt_sas3/mpi/mpi2_tool.h> #pragma pack() /* * private header files. */ ! #include <sys/scsi/adapters/mpt_sas3/mptsas3_var.h> ! #include <sys/scsi/adapters/mpt_sas3/mptsas3_smhba.h> /* * FMA header files. */ #include <sys/fm/io/ddi.h> #if defined(MPTSAS_DEBUG) extern uint32_t mptsas_debug_flags; + extern uint32_t mptsas_dbglog_imask; #endif /* * prototypes */
*** 203,213 **** pMpi2ConfigRequest_t request; pMpi2SGESimple64_t sge; struct scsi_pkt *pkt = cmd->cmd_pkt; mptsas_config_request_t *config = pkt->pkt_ha_private; uint8_t direction; ! uint32_t length, flagslength, request_desc_low; ASSERT(mutex_owned(&mpt->m_mutex)); /* * Point to the correct message and clear it as well as the global --- 206,217 ---- pMpi2ConfigRequest_t request; pMpi2SGESimple64_t sge; struct scsi_pkt *pkt = cmd->cmd_pkt; mptsas_config_request_t *config = pkt->pkt_ha_private; uint8_t direction; ! uint32_t length, flagslength; ! uint64_t request_desc; ASSERT(mutex_owned(&mpt->m_mutex)); /* * Point to the correct message and clear it as well as the global
*** 257,267 **** if (config->action == MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) { direction = MPI2_SGE_FLAGS_HOST_TO_IOC; } ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.Low, ! (uint32_t)cmd->cmd_dma_addr); ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.High, (uint32_t)(cmd->cmd_dma_addr >> 32)); } ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageNumber, config->page_number); --- 261,271 ---- if (config->action == MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) { direction = MPI2_SGE_FLAGS_HOST_TO_IOC; } ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.Low, ! (uint32_t)(cmd->cmd_dma_addr&0xfffffffful)); ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.High, (uint32_t)(cmd->cmd_dma_addr >> 32)); } ddi_put8(mpt->m_acc_req_frame_hdl, &request->Header.PageNumber, config->page_number);
*** 277,290 **** flagslength |= length; ddi_put32(mpt->m_acc_req_frame_hdl, &sge->FlagsLength, flagslength); (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); --- 281,294 ---- flagslength |= length; ddi_put32(mpt->m_acc_req_frame_hdl, &sge->FlagsLength, flagslength); (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); ! request_desc = (cmd->cmd_slot << 16) + MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cmd->cmd_rfm = NULL; ! MPTSAS_START_CMD(mpt, request_desc); 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);
*** 307,316 **** --- 311,321 ---- struct scsi_pkt *pkt; pMpi2ConfigReply_t reply; uint16_t iocstatus = 0; uint32_t iocloginfo; caddr_t page_memp; + boolean_t free_dma = B_FALSE; va_start(ap, callback); ASSERT(mutex_owned(&mpt->m_mutex)); /*
*** 389,399 **** if (cmd->cmd_rfm) { config_flags |= MPTSAS_ADDRESS_REPLY; (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, DDI_DMA_SYNC_FORCPU); reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm ! - mpt->m_reply_frame_dma_addr)); config.page_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Header.PageType); config.page_number = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Header.PageNumber); config.page_length = ddi_get8(mpt->m_acc_reply_frame_hdl, --- 394,404 ---- if (cmd->cmd_rfm) { config_flags |= MPTSAS_ADDRESS_REPLY; (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, DDI_DMA_SYNC_FORCPU); reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm ! - (mpt->m_reply_frame_dma_addr&0xfffffffful))); config.page_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Header.PageType); config.page_number = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Header.PageNumber); config.page_length = ddi_get8(mpt->m_acc_reply_frame_hdl,
*** 463,474 **** --- 468,485 ---- attrs.dma_attr_granular = (uint32_t)len; if (mptsas_dma_addr_create(mpt, attrs, &cmd->cmd_dmahandle, &accessp, &page_memp, len, &cookie) == FALSE) { + mptsas_log(mpt, CE_WARN, + "mptsas_dma_addr_create(len=0x%x) failed", (int)len); + rval = DDI_FAILURE; goto page_done; } + /* NOW we can safely call mptsas_dma_addr_destroy(). */ + free_dma = B_TRUE; + cmd->cmd_dma_addr = cookie.dmac_laddress; bzero(page_memp, len); /* * Save the data for this request to be used in the call to start the
*** 528,538 **** (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, DDI_DMA_SYNC_FORCPU); (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, DDI_DMA_SYNC_FORCPU); reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm ! - mpt->m_reply_frame_dma_addr)); iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); iocstatus = MPTSAS_IOCSTATUS(iocstatus); iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo); --- 539,549 ---- (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, DDI_DMA_SYNC_FORCPU); (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, DDI_DMA_SYNC_FORCPU); reply = (pMpi2ConfigReply_t)(mpt->m_reply_frame + (cmd->cmd_rfm ! - (mpt->m_reply_frame_dma_addr&0xfffffffful))); iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); iocstatus = MPTSAS_IOCSTATUS(iocstatus); iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo);
*** 582,591 **** --- 593,603 ---- } ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index); } + if (free_dma) mptsas_dma_addr_destroy(&cmd->cmd_dmahandle, &accessp); if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { mptsas_remove_cmd(mpt, cmd); config_flags &= (~MPTSAS_REQUEST_POOL_CMD);
*** 604,614 **** } int mptsas_send_config_request_msg(mptsas_t *mpt, uint8_t action, uint8_t pagetype, uint32_t pageaddress, uint8_t pagenumber, uint8_t pageversion, ! uint8_t pagelength, uint32_t SGEflagslength, uint32_t SGEaddress32) { pMpi2ConfigRequest_t config; int send_numbytes; bzero(mpt->m_hshk_memp, sizeof (MPI2_CONFIG_REQUEST)); --- 616,626 ---- } int mptsas_send_config_request_msg(mptsas_t *mpt, uint8_t action, uint8_t pagetype, uint32_t pageaddress, uint8_t pagenumber, uint8_t pageversion, ! uint8_t pagelength, uint32_t SGEflagslength, uint64_t SGEaddress) { pMpi2ConfigRequest_t config; int send_numbytes; bzero(mpt->m_hshk_memp, sizeof (MPI2_CONFIG_REQUEST));
*** 621,631 **** ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageVersion, pageversion); ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageLength, pagelength); ddi_put32(mpt->m_hshk_acc_hdl, &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength); ddi_put32(mpt->m_hshk_acc_hdl, ! &config->PageBufferSGE.MpiSimple.u.Address32, SGEaddress32); send_numbytes = sizeof (MPI2_CONFIG_REQUEST); /* * Post message via handshake */ --- 633,647 ---- ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageVersion, pageversion); ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageLength, pagelength); ddi_put32(mpt->m_hshk_acc_hdl, &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength); ddi_put32(mpt->m_hshk_acc_hdl, ! &config->PageBufferSGE.MpiSimple.u.Address64.Low, ! SGEaddress&0xfffffffful); ! ddi_put32(mpt->m_hshk_acc_hdl, ! &config->PageBufferSGE.MpiSimple.u.Address64.High, ! SGEaddress >> 32); send_numbytes = sizeof (MPI2_CONFIG_REQUEST); /* * Post message via handshake */
*** 638,648 **** int mptsas_send_extended_config_request_msg(mptsas_t *mpt, uint8_t action, uint8_t extpagetype, uint32_t pageaddress, uint8_t pagenumber, uint8_t pageversion, uint16_t extpagelength, ! uint32_t SGEflagslength, uint32_t SGEaddress32) { pMpi2ConfigRequest_t config; int send_numbytes; bzero(mpt->m_hshk_memp, sizeof (MPI2_CONFIG_REQUEST)); --- 654,664 ---- int mptsas_send_extended_config_request_msg(mptsas_t *mpt, uint8_t action, uint8_t extpagetype, uint32_t pageaddress, uint8_t pagenumber, uint8_t pageversion, uint16_t extpagelength, ! uint32_t SGEflagslength, uint64_t SGEaddress) { pMpi2ConfigRequest_t config; int send_numbytes; bzero(mpt->m_hshk_memp, sizeof (MPI2_CONFIG_REQUEST));
*** 657,667 **** ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageVersion, pageversion); ddi_put16(mpt->m_hshk_acc_hdl, &config->ExtPageLength, extpagelength); ddi_put32(mpt->m_hshk_acc_hdl, &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength); ddi_put32(mpt->m_hshk_acc_hdl, ! &config->PageBufferSGE.MpiSimple.u.Address32, SGEaddress32); send_numbytes = sizeof (MPI2_CONFIG_REQUEST); /* * Post message via handshake */ --- 673,687 ---- ddi_put8(mpt->m_hshk_acc_hdl, &config->Header.PageVersion, pageversion); ddi_put16(mpt->m_hshk_acc_hdl, &config->ExtPageLength, extpagelength); ddi_put32(mpt->m_hshk_acc_hdl, &config->PageBufferSGE.MpiSimple.FlagsLength, SGEflagslength); ddi_put32(mpt->m_hshk_acc_hdl, ! &config->PageBufferSGE.MpiSimple.u.Address64.Low, ! SGEaddress&0xfffffffful); ! ddi_put32(mpt->m_hshk_acc_hdl, ! &config->PageBufferSGE.MpiSimple.u.Address64.High, ! SGEaddress >> 32); send_numbytes = sizeof (MPI2_CONFIG_REQUEST); /* * Post message via handshake */
*** 1085,1095 **** pMpi2SCSITaskManagementRequest_t task; int rval = FALSE; mptsas_cmd_t *cmd; struct scsi_pkt *pkt; mptsas_slots_t *slots = mpt->m_active; ! uint32_t request_desc_low, i; pMPI2DefaultReply_t reply_msg; /* * Can't start another task management routine. */ --- 1105,1116 ---- pMpi2SCSITaskManagementRequest_t task; int rval = FALSE; mptsas_cmd_t *cmd; struct scsi_pkt *pkt; mptsas_slots_t *slots = mpt->m_active; ! uint32_t i; ! uint64_t request_desc; pMPI2DefaultReply_t reply_msg; /* * Can't start another task management routine. */
*** 1141,1153 **** /* * Send TM request using High Priority Queue. */ (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_HIGH_PRIORITY; ! MPTSAS_START_CMD(mpt, request_desc_low, 0); rval = mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME); if (pkt->pkt_reason == CMD_INCOMPLETE) rval = FALSE; --- 1162,1174 ---- /* * Send TM request using High Priority Queue. */ (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); ! request_desc = (cmd->cmd_slot << 16) + MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; ! MPTSAS_START_CMD(mpt, request_desc); rval = mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME); if (pkt->pkt_reason == CMD_INCOMPLETE) rval = FALSE;
*** 1159,1169 **** if (cmd->cmd_rfm && reply) { (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, DDI_DMA_SYNC_FORCPU); reply_msg = (pMPI2DefaultReply_t) (mpt->m_reply_frame + (cmd->cmd_rfm - ! mpt->m_reply_frame_dma_addr)); if (reply_size > sizeof (MPI2_SCSI_TASK_MANAGE_REPLY)) { reply_size = sizeof (MPI2_SCSI_TASK_MANAGE_REPLY); } mutex_exit(&mpt->m_mutex); for (i = 0; i < reply_size; i++) { --- 1180,1190 ---- if (cmd->cmd_rfm && reply) { (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, DDI_DMA_SYNC_FORCPU); reply_msg = (pMPI2DefaultReply_t) (mpt->m_reply_frame + (cmd->cmd_rfm - ! (mpt->m_reply_frame_dma_addr&0xfffffffful))); if (reply_size > sizeof (MPI2_SCSI_TASK_MANAGE_REPLY)) { reply_size = sizeof (MPI2_SCSI_TASK_MANAGE_REPLY); } mutex_exit(&mpt->m_mutex); for (i = 0; i < reply_size; i++) {
*** 1197,1206 **** --- 1218,1304 ---- } return (rval); } + /* + * Complete firmware download frame for v2.0 cards. + */ + static void + mptsas_uflash2(pMpi2FWDownloadRequest fwdownload, + ddi_acc_handle_t acc_hdl, uint32_t size, uint8_t type, + ddi_dma_cookie_t flsh_cookie) + { + pMpi2FWDownloadTCSGE_t tcsge; + pMpi2SGESimple64_t sge; + uint32_t flagslength; + + ddi_put8(acc_hdl, &fwdownload->Function, + MPI2_FUNCTION_FW_DOWNLOAD); + ddi_put8(acc_hdl, &fwdownload->ImageType, type); + ddi_put8(acc_hdl, &fwdownload->MsgFlags, + MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT); + ddi_put32(acc_hdl, &fwdownload->TotalImageSize, size); + + tcsge = (pMpi2FWDownloadTCSGE_t)&fwdownload->SGL; + ddi_put8(acc_hdl, &tcsge->ContextSize, 0); + ddi_put8(acc_hdl, &tcsge->DetailsLength, 12); + ddi_put8(acc_hdl, &tcsge->Flags, 0); + ddi_put32(acc_hdl, &tcsge->ImageOffset, 0); + ddi_put32(acc_hdl, &tcsge->ImageSize, size); + + sge = (pMpi2SGESimple64_t)(tcsge + 1); + flagslength = size; + flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT | + MPI2_SGE_FLAGS_END_OF_BUFFER | + MPI2_SGE_FLAGS_SIMPLE_ELEMENT | + MPI2_SGE_FLAGS_SYSTEM_ADDRESS | + MPI2_SGE_FLAGS_64_BIT_ADDRESSING | + MPI2_SGE_FLAGS_HOST_TO_IOC | + MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); + ddi_put32(acc_hdl, &sge->FlagsLength, flagslength); + ddi_put32(acc_hdl, &sge->Address.Low, + flsh_cookie.dmac_address); + ddi_put32(acc_hdl, &sge->Address.High, + (uint32_t)(flsh_cookie.dmac_laddress >> 32)); + } + + /* + * Complete firmware download frame for v2.5 cards. + */ + static void + mptsas_uflash25(pMpi25FWDownloadRequest fwdownload, + ddi_acc_handle_t acc_hdl, uint32_t size, uint8_t type, + ddi_dma_cookie_t flsh_cookie) + { + pMpi2IeeeSgeSimple64_t sge; + uint8_t flags; + + ddi_put8(acc_hdl, &fwdownload->Function, + MPI2_FUNCTION_FW_DOWNLOAD); + ddi_put8(acc_hdl, &fwdownload->ImageType, type); + ddi_put8(acc_hdl, &fwdownload->MsgFlags, + MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT); + ddi_put32(acc_hdl, &fwdownload->TotalImageSize, size); + + ddi_put32(acc_hdl, &fwdownload->ImageOffset, 0); + ddi_put32(acc_hdl, &fwdownload->ImageSize, size); + + sge = (pMpi2IeeeSgeSimple64_t)&fwdownload->SGL; + flags = MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | + MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR | + MPI25_IEEE_SGE_FLAGS_END_OF_LIST; + ddi_put8(acc_hdl, &sge->Flags, flags); + ddi_put32(acc_hdl, &sge->Length, size); + ddi_put32(acc_hdl, &sge->Address.Low, + flsh_cookie.dmac_address); + ddi_put32(acc_hdl, &sge->Address.High, + (uint32_t)(flsh_cookie.dmac_laddress >> 32)); + } + + static int mptsas_enable_mpi25_flashupdate = 0; + int mptsas_update_flash(mptsas_t *mpt, caddr_t ptrbuffer, uint32_t size, uint8_t type, int mode) {
*** 1214,1232 **** ddi_dma_attr_t flsh_dma_attrs; ddi_dma_cookie_t flsh_cookie; ddi_dma_handle_t flsh_dma_handle; ddi_acc_handle_t flsh_accessp; caddr_t memp, flsh_memp; - uint32_t flagslength; - pMpi2FWDownloadRequest fwdownload; - pMpi2FWDownloadTCSGE_t tcsge; - pMpi2SGESimple64_t sge; mptsas_cmd_t *cmd; struct scsi_pkt *pkt; int i; int rvalue = 0; ! uint32_t request_desc_low; if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { mptsas_log(mpt, CE_WARN, "mptsas_update_flash(): allocation " "failed. event ack command pool is full\n"); return (rvalue); --- 1312,1339 ---- ddi_dma_attr_t flsh_dma_attrs; ddi_dma_cookie_t flsh_cookie; ddi_dma_handle_t flsh_dma_handle; ddi_acc_handle_t flsh_accessp; caddr_t memp, flsh_memp; mptsas_cmd_t *cmd; struct scsi_pkt *pkt; int i; int rvalue = 0; ! uint64_t request_desc; ! ! if (mpt->m_MPI25) { ! /* ! * The code is there but not tested yet. ! * User has to know there are risks here. ! */ ! mptsas_log(mpt, CE_WARN, "mptsas_update_flash(): " ! "Updating firmware through MPI 2.5 has not been " ! "tested yet!\n" ! "To enable set mptsas_enable_mpi25_flashupdate to 1\n"); ! if (!mptsas_enable_mpi25_flashupdate) ! return (-1); ! } if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { mptsas_log(mpt, CE_WARN, "mptsas_update_flash(): allocation " "failed. event ack command pool is full\n"); return (rvalue);
*** 1283,1331 **** * Fill in fw download message */ ASSERT(cmd->cmd_slot != 0); memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot); bzero(memp, mpt->m_req_frame_size); - fwdownload = (void *)memp; - ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->Function, - MPI2_FUNCTION_FW_DOWNLOAD); - ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->ImageType, type); - ddi_put8(mpt->m_acc_req_frame_hdl, &fwdownload->MsgFlags, - MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT); - ddi_put32(mpt->m_acc_req_frame_hdl, &fwdownload->TotalImageSize, size); ! tcsge = (pMpi2FWDownloadTCSGE_t)&fwdownload->SGL; ! ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->ContextSize, 0); ! ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->DetailsLength, 12); ! ddi_put8(mpt->m_acc_req_frame_hdl, &tcsge->Flags, 0); ! ddi_put32(mpt->m_acc_req_frame_hdl, &tcsge->ImageOffset, 0); ! ddi_put32(mpt->m_acc_req_frame_hdl, &tcsge->ImageSize, size); ! ! sge = (pMpi2SGESimple64_t)(tcsge + 1); ! flagslength = size; ! flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT | ! MPI2_SGE_FLAGS_END_OF_BUFFER | ! MPI2_SGE_FLAGS_SIMPLE_ELEMENT | ! MPI2_SGE_FLAGS_SYSTEM_ADDRESS | ! MPI2_SGE_FLAGS_64_BIT_ADDRESSING | ! MPI2_SGE_FLAGS_HOST_TO_IOC | ! MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); ! ddi_put32(mpt->m_acc_req_frame_hdl, &sge->FlagsLength, flagslength); ! ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.Low, ! flsh_cookie.dmac_address); ! ddi_put32(mpt->m_acc_req_frame_hdl, &sge->Address.High, ! (uint32_t)(flsh_cookie.dmac_laddress >> 32)); /* * Start command */ (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); rvalue = 0; (void) cv_reltimedwait(&mpt->m_fw_cv, &mpt->m_mutex, drv_usectohz(60 * MICROSEC), TR_CLOCK_TICK); if (!(cmd->cmd_flags & CFLAG_FINISHED)) { --- 1390,1416 ---- * Fill in fw download message */ ASSERT(cmd->cmd_slot != 0); memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot); bzero(memp, mpt->m_req_frame_size); ! if (mpt->m_MPI25) ! mptsas_uflash25((pMpi25FWDownloadRequest)memp, ! mpt->m_acc_req_frame_hdl, size, type, flsh_cookie); ! else ! mptsas_uflash2((pMpi2FWDownloadRequest)memp, ! mpt->m_acc_req_frame_hdl, size, type, flsh_cookie); /* * Start command */ (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); ! request_desc = (cmd->cmd_slot << 16) + MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cmd->cmd_rfm = NULL; ! MPTSAS_START_CMD(mpt, request_desc); rvalue = 0; (void) cv_reltimedwait(&mpt->m_fw_cv, &mpt->m_mutex, drv_usectohz(60 * MICROSEC), TR_CLOCK_TICK); if (!(cmd->cmd_flags & CFLAG_FINISHED)) {
*** 1355,1365 **** uint8_t tmp_sas_wwn[SAS_WWN_BYTE_SIZE]; uint16_t *devhdl, *bay_num, *enclosure; uint64_t *sas_wwn; uint32_t *dev_info; uint8_t *physport, *phynum; ! uint16_t *pdevhdl; uint32_t page_address; if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) && (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) { mptsas_log(mpt, CE_WARN, "mptsas_get_sas_device_page0 " --- 1440,1450 ---- uint8_t tmp_sas_wwn[SAS_WWN_BYTE_SIZE]; uint16_t *devhdl, *bay_num, *enclosure; uint64_t *sas_wwn; uint32_t *dev_info; uint8_t *physport, *phynum; ! uint16_t *pdevhdl, *io_flags; uint32_t page_address; if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) && (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) { mptsas_log(mpt, CE_WARN, "mptsas_get_sas_device_page0 "
*** 1389,1399 **** physport = va_arg(ap, uint8_t *); phynum = va_arg(ap, uint8_t *); pdevhdl = va_arg(ap, uint16_t *); bay_num = va_arg(ap, uint16_t *); enclosure = va_arg(ap, uint16_t *); ! sasdevpage = (pMpi2SasDevicePage0_t)page_memp; *dev_info = ddi_get32(accessp, &sasdevpage->DeviceInfo); *devhdl = ddi_get16(accessp, &sasdevpage->DevHandle); --- 1474,1484 ---- physport = va_arg(ap, uint8_t *); phynum = va_arg(ap, uint8_t *); pdevhdl = va_arg(ap, uint16_t *); bay_num = va_arg(ap, uint16_t *); enclosure = va_arg(ap, uint16_t *); ! io_flags = va_arg(ap, uint16_t *); sasdevpage = (pMpi2SasDevicePage0_t)page_memp; *dev_info = ddi_get32(accessp, &sasdevpage->DeviceInfo); *devhdl = ddi_get16(accessp, &sasdevpage->DevHandle);
*** 1406,1415 **** --- 1491,1513 ---- *physport = ddi_get8(accessp, &sasdevpage->PhysicalPort); *phynum = ddi_get8(accessp, &sasdevpage->PhyNum); *pdevhdl = ddi_get16(accessp, &sasdevpage->ParentDevHandle); *bay_num = ddi_get16(accessp, &sasdevpage->Slot); *enclosure = ddi_get16(accessp, &sasdevpage->EnclosureHandle); + *io_flags = ddi_get16(accessp, &sasdevpage->Flags); + + if (*io_flags & MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) { + /* + * Leave a messages about FP cabability in the log. + */ + mptsas_log(mpt, CE_CONT, + "!w%016"PRIx64" FastPath Capable%s", *sas_wwn, + (*io_flags & + MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH)? + " and Enabled":" but Disabled"); + } + return (rval); } /* * Request MPI configuration page SAS device page 0 to get DevHandle, device
*** 1417,1427 **** */ int mptsas_get_sas_device_page0(mptsas_t *mpt, uint32_t page_address, uint16_t *dev_handle, uint64_t *sas_wwn, uint32_t *dev_info, uint8_t *physport, uint8_t *phynum, uint16_t *pdev_handle, ! uint16_t *bay_num, uint16_t *enclosure) { int rval = DDI_SUCCESS; ASSERT(mutex_owned(&mpt->m_mutex)); --- 1515,1525 ---- */ int mptsas_get_sas_device_page0(mptsas_t *mpt, uint32_t page_address, uint16_t *dev_handle, uint64_t *sas_wwn, uint32_t *dev_info, uint8_t *physport, uint8_t *phynum, uint16_t *pdev_handle, ! uint16_t *bay_num, uint16_t *enclosure, uint16_t *io_flags) { int rval = DDI_SUCCESS; ASSERT(mutex_owned(&mpt->m_mutex));
*** 1432,1442 **** rval = mptsas_access_config_page(mpt, MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0, page_address, mptsas_sasdevpage_0_cb, page_address, dev_handle, sas_wwn, dev_info, physport, phynum, pdev_handle, ! bay_num, enclosure); return (rval); } static int --- 1530,1540 ---- rval = mptsas_access_config_page(mpt, MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE, 0, page_address, mptsas_sasdevpage_0_cb, page_address, dev_handle, sas_wwn, dev_info, physport, phynum, pdev_handle, ! bay_num, enclosure, io_flags); return (rval); } static int
*** 1855,1864 **** --- 1953,1963 ---- uint16_t iocstatus; uint8_t port_flags, page_number, action; uint32_t reply_size = 256; /* Big enough for any page */ uint_t state; int rval = DDI_FAILURE; + boolean_t free_recv = B_FALSE, free_page = B_FALSE; /* * Initialize our "state machine". This is a bit convoluted, * but it keeps us from having to do the ddi allocations numerous * times.
*** 1881,1890 **** --- 1980,1991 ---- (sizeof (MPI2_CONFIG_REPLY)), NULL) == FALSE) { mptsas_log(mpt, CE_WARN, "mptsas_get_sas_io_unit_page_hndshk: recv dma failed"); goto cleanup; } + /* Now safe to call mptsas_dma_addr_destroy(recv_dma_handle). */ + free_recv = B_TRUE; page_dma_attrs = mpt->m_msg_dma_attr; page_dma_attrs.dma_attr_sgllen = 1; page_dma_attrs.dma_attr_granular = reply_size;
*** 1893,1902 **** --- 1994,2005 ---- reply_size, &page_cookie) == FALSE) { mptsas_log(mpt, CE_WARN, "mptsas_get_sas_io_unit_page_hndshk: page dma failed"); goto cleanup; } + /* Now safe to call mptsas_dma_addr_destroy(page_dma_handle). */ + free_page = B_TRUE; /* * Now we cycle through the state machine. Here's what happens: * 1. Read IO unit page 0 and set phy information * 2. See if Read IO unit page1 is needed because of port configuration
*** 1915,1925 **** flags_length |= ((uint32_t)( MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT | MPI2_SGE_FLAGS_SYSTEM_ADDRESS | ! MPI2_SGE_FLAGS_32_BIT_ADDRESSING | MPI2_SGE_FLAGS_IOC_TO_HOST | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); break; --- 2018,2028 ---- flags_length |= ((uint32_t)( MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT | MPI2_SGE_FLAGS_SYSTEM_ADDRESS | ! MPI2_SGE_FLAGS_64_BIT_ADDRESSING | MPI2_SGE_FLAGS_IOC_TO_HOST | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); break;
*** 1931,1941 **** flags_length |= ((uint32_t)( MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT | MPI2_SGE_FLAGS_SYSTEM_ADDRESS | ! MPI2_SGE_FLAGS_32_BIT_ADDRESSING | MPI2_SGE_FLAGS_IOC_TO_HOST | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); break; --- 2034,2044 ---- flags_length |= ((uint32_t)( MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT | MPI2_SGE_FLAGS_SYSTEM_ADDRESS | ! MPI2_SGE_FLAGS_64_BIT_ADDRESSING | MPI2_SGE_FLAGS_IOC_TO_HOST | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); break;
*** 1975,1985 **** if (mptsas_send_extended_config_request_msg(mpt, action, MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0, page_number, ddi_get8(recv_accessp, &configreply->Header.PageVersion), ddi_get16(recv_accessp, &configreply->ExtPageLength), ! flags_length, page_cookie.dmac_address)) { goto cleanup; } if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes, recv_accessp)) { --- 2078,2088 ---- if (mptsas_send_extended_config_request_msg(mpt, action, MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT, 0, page_number, ddi_get8(recv_accessp, &configreply->Header.PageVersion), ddi_get16(recv_accessp, &configreply->ExtPageLength), ! flags_length, page_cookie.dmac_laddress)) { goto cleanup; } if (mptsas_get_handshake_msg(mpt, recv_memp, recv_numbytes, recv_accessp)) {
*** 2128,2138 **** --- 2231,2243 ---- rval = DDI_FAILURE; goto cleanup; } cleanup: + if (free_recv) mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp); + if (free_page) mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp); if (rval != DDI_SUCCESS) { mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); }
*** 2157,2166 **** --- 2262,2272 ---- int recv_numbytes; pMpi2ManufacturingPage5_t m5; uint32_t flagslength; int rval = DDI_SUCCESS; uint_t iocstatus; + boolean_t free_recv = B_FALSE, free_page = B_FALSE; MPTSAS_DISABLE_INTR(mpt); if (mptsas_send_config_request_msg(mpt, MPI2_CONFIG_ACTION_PAGE_HEADER, MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 5, 0, 0, 0, 0)) {
*** 2177,2188 **** --- 2283,2297 ---- recv_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_REPLY)); if (mptsas_dma_addr_create(mpt, recv_dma_attrs, &recv_dma_handle, &recv_accessp, &recv_memp, (sizeof (MPI2_CONFIG_REPLY)), NULL) == FALSE) { + rval = DDI_FAILURE; goto done; } + /* Now safe to call mptsas_dma_addr_destroy(recv_dma_handle). */ + free_recv = B_TRUE; bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY)); configreply = (pMpi2ConfigReply_t)recv_memp; recv_numbytes = sizeof (MPI2_CONFIG_REPLY);
*** 2211,2243 **** page_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_PAGE_MAN_5)); if (mptsas_dma_addr_create(mpt, page_dma_attrs, &page_dma_handle, &page_accessp, &page_memp, (sizeof (MPI2_CONFIG_PAGE_MAN_5)), &page_cookie) == FALSE) { goto done; } bzero(page_memp, sizeof (MPI2_CONFIG_PAGE_MAN_5)); m5 = (pMpi2ManufacturingPage5_t)page_memp; /* * Give reply address to IOC to store config page in and send * config request out. */ flagslength = sizeof (MPI2_CONFIG_PAGE_MAN_5); flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT | ! MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_32_BIT_ADDRESSING | MPI2_SGE_FLAGS_IOC_TO_HOST | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); if (mptsas_send_config_request_msg(mpt, MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 5, ddi_get8(recv_accessp, &configreply->Header.PageVersion), ddi_get8(recv_accessp, &configreply->Header.PageLength), ! flagslength, page_cookie.dmac_address)) { rval = DDI_FAILURE; goto done; } /* --- 2320,2359 ---- page_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_PAGE_MAN_5)); if (mptsas_dma_addr_create(mpt, page_dma_attrs, &page_dma_handle, &page_accessp, &page_memp, (sizeof (MPI2_CONFIG_PAGE_MAN_5)), &page_cookie) == FALSE) { + rval = DDI_FAILURE; goto done; } + /* Now safe to call mptsas_dma_addr_destroy(page_dma_handle). */ + free_page = B_TRUE; + bzero(page_memp, sizeof (MPI2_CONFIG_PAGE_MAN_5)); m5 = (pMpi2ManufacturingPage5_t)page_memp; + NDBG20(("mptsas_get_manufacture_page5: paddr 0x%x%08x", + (uint32_t)(page_cookie.dmac_laddress>>32), + (uint32_t)(page_cookie.dmac_laddress&0xfffffffful))); /* * Give reply address to IOC to store config page in and send * config request out. */ flagslength = sizeof (MPI2_CONFIG_PAGE_MAN_5); flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT | ! MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_64_BIT_ADDRESSING | MPI2_SGE_FLAGS_IOC_TO_HOST | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); if (mptsas_send_config_request_msg(mpt, MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 5, ddi_get8(recv_accessp, &configreply->Header.PageVersion), ddi_get8(recv_accessp, &configreply->Header.PageLength), ! flagslength, page_cookie.dmac_laddress)) { rval = DDI_FAILURE; goto done; } /*
*** 2301,2311 **** --- 2417,2429 ---- } done: /* * free up memory */ + if (free_recv) mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp); + if (free_page) mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp); MPTSAS_ENABLE_INTR(mpt); return (rval); }
*** 2523,2532 **** --- 2641,2651 ---- pMpi2ManufacturingPage0_t m0; uint32_t flagslength; int rval = DDI_SUCCESS; uint_t iocstatus; uint8_t i = 0; + boolean_t free_recv = B_FALSE, free_page = B_FALSE; MPTSAS_DISABLE_INTR(mpt); if (mptsas_send_config_request_msg(mpt, MPI2_CONFIG_ACTION_PAGE_HEADER, MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 0, 0, 0, 0, 0)) {
*** 2543,2554 **** --- 2662,2677 ---- recv_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_REPLY)); if (mptsas_dma_addr_create(mpt, recv_dma_attrs, &recv_dma_handle, &recv_accessp, &recv_memp, (sizeof (MPI2_CONFIG_REPLY)), NULL) == FALSE) { + rval = DDI_FAILURE; goto done; } + /* Now safe to call mptsas_dma_addr_destroy(recv_dma_handle). */ + free_recv = B_TRUE; + bzero(recv_memp, sizeof (MPI2_CONFIG_REPLY)); configreply = (pMpi2ConfigReply_t)recv_memp; recv_numbytes = sizeof (MPI2_CONFIG_REPLY); /*
*** 2576,2587 **** --- 2699,2714 ---- page_dma_attrs.dma_attr_granular = (sizeof (MPI2_CONFIG_PAGE_MAN_0)); if (mptsas_dma_addr_create(mpt, page_dma_attrs, &page_dma_handle, &page_accessp, &page_memp, (sizeof (MPI2_CONFIG_PAGE_MAN_0)), &page_cookie) == FALSE) { + rval = DDI_FAILURE; goto done; } + /* Now safe to call mptsas_dma_addr_destroy(page_dma_handle). */ + free_page = B_TRUE; + bzero(page_memp, sizeof (MPI2_CONFIG_PAGE_MAN_0)); m0 = (pMpi2ManufacturingPage0_t)page_memp; /* * Give reply address to IOC to store config page in and send
*** 2589,2608 **** */ flagslength = sizeof (MPI2_CONFIG_PAGE_MAN_0); flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT | ! MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_32_BIT_ADDRESSING | MPI2_SGE_FLAGS_IOC_TO_HOST | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); if (mptsas_send_config_request_msg(mpt, MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 0, ddi_get8(recv_accessp, &configreply->Header.PageVersion), ddi_get8(recv_accessp, &configreply->Header.PageLength), ! flagslength, page_cookie.dmac_address)) { rval = DDI_FAILURE; goto done; } /* --- 2716,2735 ---- */ flagslength = sizeof (MPI2_CONFIG_PAGE_MAN_0); flagslength |= ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_SIMPLE_ELEMENT | ! MPI2_SGE_FLAGS_SYSTEM_ADDRESS | MPI2_SGE_FLAGS_64_BIT_ADDRESSING | MPI2_SGE_FLAGS_IOC_TO_HOST | MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); if (mptsas_send_config_request_msg(mpt, MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, MPI2_CONFIG_PAGETYPE_MANUFACTURING, 0, 0, ddi_get8(recv_accessp, &configreply->Header.PageVersion), ddi_get8(recv_accessp, &configreply->Header.PageLength), ! flagslength, page_cookie.dmac_laddress)) { rval = DDI_FAILURE; goto done; } /*
*** 2671,2681 **** --- 2798,2810 ---- } done: /* * free up memory */ + if (free_recv) mptsas_dma_addr_destroy(&recv_dma_handle, &recv_accessp); + if (free_page) mptsas_dma_addr_destroy(&page_dma_handle, &page_accessp); MPTSAS_ENABLE_INTR(mpt); return (rval); }