Mercurial > illumos > illumos-gate
changeset 10604:4dab88fc294c
6870264 Resets can timeout during heavy I/O
6873580 prtconf -v shows stale firmware revision after flashing controller firmware
6873602 Unknown events into mpt_sas driver should not be reported
6878420 MPTIOCTL_GET_ADAPTER_DATA does not fill in some values correctly
6878430 Commands sent using MPTIOCTL_PASS_THRU can timeout before they should
6878545 New MPT Events are not seen after the initial 50 events
author | Yong-Feng Du <Yongfeng.Du@Sun.COM> |
---|---|
date | Tue, 22 Sep 2009 14:06:23 +0800 |
parents | f9779f6db716 |
children | 4086dd59e147 |
files | usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_impl.c usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h |
diffstat | 3 files changed, 235 insertions(+), 189 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c Tue Sep 22 12:05:08 2009 +0800 +++ b/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c Tue Sep 22 14:06:23 2009 +0800 @@ -490,7 +490,7 @@ }; -#define MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.17" +#define MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.18" #define CDATE "MPTSAS was compiled on "__DATE__ /* LINTED E_STATIC_UNUSED */ static char *MPTWASCOMPILEDON = CDATE; @@ -3229,6 +3229,14 @@ } cmd->cmd_active_timeout = cmd->cmd_pkt->pkt_time; + /* + * If initial timout is less than or equal to one tick, bump + * the timeout by a tick so that command doesn't timeout before + * its allotted time. + */ + if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) { + cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick; + } return (TRUE); } else { int i; @@ -4503,18 +4511,29 @@ mptsas_wait_intr(mptsas_t *mpt, int polltime) { int cnt; - uint32_t reply_index; pMpi2ReplyDescriptorsUnion_t reply_desc_union; + uint32_t int_mask; NDBG5(("mptsas_wait_intr")); + mpt->m_polled_intr = 1; + + /* + * Get the current interrupt mask. When re-enabling ints, set mask to + * saved value. + */ + int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask); + MPTSAS_DISABLE_INTR(mpt); + /* * Keep polling for at least (polltime * 1000) seconds */ - reply_index = mpt->m_post_index; for (cnt = 0; cnt < polltime; cnt++) { + (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, + DDI_DMA_SYNC_FORCPU); + reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) - MPTSAS_GET_NEXT_REPLY(mpt, reply_index); + MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); if (ddi_get32(mpt->m_acc_post_queue_hdl, &reply_desc_union->Words.Low) == 0xFFFFFFFF || @@ -4523,27 +4542,34 @@ drv_usecwait(1000); continue; } - mpt->m_polled_intr = 1; /* * The reply is valid, process it according to its - * type. Also, set a flag for updated the reply index - * after they've all been processed. + * type. */ mptsas_process_intr(mpt, reply_desc_union); - if (++reply_index == mpt->m_post_queue_depth) { - reply_index = 0; - } - /* - * Update the global reply index - */ - mpt->m_post_index = reply_index; + if (++mpt->m_post_index == mpt->m_post_queue_depth) { + mpt->m_post_index = 0; + } + ddi_put32(mpt->m_datap, - &mpt->m_reg->ReplyPostHostIndex, reply_index); - + &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); + + mpt->m_polled_intr = 0; + /* + * Re-enable interrupts and quit. + */ + ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, + int_mask); return (TRUE); } + + /* + * Clear polling flag, re-enable interrupts and quit. + */ + mpt->m_polled_intr = 0; + ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask); return (FALSE); } @@ -4623,7 +4649,7 @@ { pMpi2AddressReplyDescriptor_t address_reply; pMPI2DefaultReply_t reply; - uint32_t reply_addr, reply_index; + uint32_t reply_addr; uint16_t SMID; mptsas_slots_t *slots = mpt->m_active; mptsas_cmd_t *cmd = NULL; @@ -4746,19 +4772,17 @@ /* * Return the reply frame to the free queue. */ - reply_index = mpt->m_free_index; ddi_put32(mpt->m_acc_free_queue_hdl, &((uint32_t *)(void *) - mpt->m_free_queue)[reply_index], reply_addr); + mpt->m_free_queue)[mpt->m_free_index], reply_addr); (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); - if (++reply_index == mpt->m_free_queue_depth) { - reply_index = 0; - } - mpt->m_free_index = reply_index; + if (++mpt->m_free_index == mpt->m_free_queue_depth) { + mpt->m_free_index = 0; + } ddi_put32(mpt->m_datap, - &mpt->m_reg->ReplyFreeHostIndex, reply_index); + &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index); } return; default: @@ -4769,17 +4793,16 @@ /* * Return the reply frame to the free queue. */ - reply_index = mpt->m_free_index; ddi_put32(mpt->m_acc_free_queue_hdl, - &((uint32_t *)(void *)mpt->m_free_queue)[reply_index], + &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], reply_addr); (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); - if (++reply_index == mpt->m_free_queue_depth) { - reply_index = 0; - } - mpt->m_free_index = reply_index; - ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, reply_index); + 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_flags & CFLAG_FW_CMD) return; @@ -4796,19 +4819,7 @@ */ cmd->cmd_flags &= ~CFLAG_RETRY; } else { - struct scsi_pkt *pkt = CMD2PKT(cmd); - - ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0); - cmd->cmd_linkp = NULL; - cmd->cmd_flags |= CFLAG_FINISHED; - cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT; - - if (pkt && pkt->pkt_comp) { - cmd->cmd_flags |= CFLAG_COMPLETED; - mutex_exit(&mpt->m_mutex); - mptsas_pkt_comp(pkt, cmd); - mutex_enter(&mpt->m_mutex); - } + mptsas_doneq_add(mpt, cmd); } } @@ -5136,7 +5147,6 @@ mptsas_intr(caddr_t arg1, caddr_t arg2) { mptsas_t *mpt = (void *)arg1; - uint32_t reply_index; pMpi2ReplyDescriptorsUnion_t reply_desc_union; uchar_t did_reply = FALSE; @@ -5157,9 +5167,16 @@ } /* - * Save the current reply post host index value. - */ - reply_index = mpt->m_post_index; + * If polling, interrupt was triggered by some shared interrupt because + * IOC interrupts are disabled during polling, so polling routine will + * handle any replies. Considering this, if polling is happening, + * return with interrupt unclaimed. + */ + if (mpt->m_polled_intr) { + mutex_exit(&mpt->m_mutex); + mptsas_log(mpt, CE_WARN, "mpt_sas: Unclaimed interrupt"); + return (DDI_INTR_UNCLAIMED); + } /* * Read the istat register. @@ -5168,14 +5185,14 @@ /* * read fifo until empty. */ - (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, - DDI_DMA_SYNC_FORCPU); #ifndef __lock_lint _NOTE(CONSTCOND) #endif while (TRUE) { + (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, + DDI_DMA_SYNC_FORCPU); reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) - MPTSAS_GET_NEXT_REPLY(mpt, reply_index); + MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); if (ddi_get32(mpt->m_acc_post_queue_hdl, &reply_desc_union->Words.Low) == 0xFFFFFFFF || @@ -5193,10 +5210,9 @@ mptsas_process_intr(mpt, reply_desc_union); - if (++reply_index == mpt->m_post_queue_depth) { - reply_index = 0; - } - mpt->m_post_index = reply_index; + if (++mpt->m_post_index == mpt->m_post_queue_depth) { + mpt->m_post_index = 0; + } } /* @@ -5205,14 +5221,9 @@ */ if (did_reply) { ddi_put32(mpt->m_datap, - &mpt->m_reg->ReplyPostHostIndex, reply_index); + &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); } } else { - if (mpt->m_polled_intr) { - mpt->m_polled_intr = 0; - mutex_exit(&mpt->m_mutex); - return (DDI_INTR_CLAIMED); - } mutex_exit(&mpt->m_mutex); return (DDI_INTR_UNCLAIMED); } @@ -5243,10 +5254,6 @@ mptsas_restart_waitq(mpt); } - if (mpt->m_polled_intr) { - mpt->m_polled_intr = 0; - } - mutex_exit(&mpt->m_mutex); return (DDI_INTR_CLAIMED); } @@ -5999,7 +6006,7 @@ i = (uint8_t)(event / 32); j = (uint8_t)(event % 32); if ((i < 4) && ((1 << j) & mpt->m_event_mask[i])) { - i = mpt->m_event_number; + i = mpt->m_event_index; mpt->m_events[i].Type = event; mpt->m_events[i].Number = ++mpt->m_event_number; bzero(mpt->m_events[i].Data, MPTSAS_MAX_EVENT_DATA_LENGTH * 4); @@ -6025,7 +6032,7 @@ if (++i == MPTSAS_EVENT_QUEUE_SIZE) { i = 0; } - mpt->m_event_number = i; + mpt->m_event_index = (uint8_t)i; /* * Set flag to send the event. @@ -6686,7 +6693,7 @@ m_replyh_arg_t *replyh_arg; pMpi2EventNotificationReply_t eventreply; uint32_t event, iocloginfo, rfm; - uint32_t status, reply_index; + uint32_t status; uint8_t port; mptsas_t *mpt; uint_t iocstatus; @@ -7146,24 +7153,23 @@ break; } default: - mptsas_log(mpt, CE_NOTE, "mptsas%d: unknown event %x received", - mpt->m_instance, event); + NDBG20(("mptsas%d: unknown event %x received", + mpt->m_instance, event)); break; } /* * Return the reply frame to the free queue. */ - reply_index = mpt->m_free_index; ddi_put32(mpt->m_acc_free_queue_hdl, - &((uint32_t *)(void *)mpt->m_free_queue)[reply_index], rfm); + &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], rfm); (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); - if (++reply_index == mpt->m_free_queue_depth) { - reply_index = 0; - } - mpt->m_free_index = reply_index; - ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, reply_index); + 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); mutex_exit(&mpt->m_mutex); } @@ -7766,18 +7772,11 @@ /* * only add scsi pkts that have completion routines to * the doneq. no intr cmds do not have callbacks. - * run the callback on an ARQ pkt immediately. This - * frees the ARQ for other check conditions. - */ - if (pkt->pkt_comp && !(cmd->cmd_flags & CFLAG_CMDARQ)) { + */ + if (pkt && (pkt->pkt_comp)) { *mpt->m_donetail = cmd; mpt->m_donetail = &cmd->cmd_linkp; mpt->m_doneq_len++; - } else if (pkt->pkt_comp && (cmd->cmd_flags & CFLAG_CMDARQ)) { - cmd->cmd_flags |= CFLAG_COMPLETED; - mutex_exit(&mpt->m_mutex); - mptsas_pkt_comp(pkt, cmd); - mutex_enter(&mpt->m_mutex); } } @@ -9308,7 +9307,6 @@ Mpi2SCSIIOReply_t rep_msg; int i, status = 0, pt_flags = 0, rv = 0; int rvalue; - uint32_t reply_index; uint8_t function; ASSERT(mutex_owned(&mpt->m_mutex)); @@ -9551,18 +9549,16 @@ * if this reply is an ADDRESS reply. */ if (pt_flags & MPTSAS_ADDRESS_REPLY) { - reply_index = mpt->m_free_index; ddi_put32(mpt->m_acc_free_queue_hdl, - &((uint32_t *)(void *)mpt->m_free_queue)[reply_index], + &((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 (++reply_index == mpt->m_free_queue_depth) { - reply_index = 0; - } - mpt->m_free_index = reply_index; + if (++mpt->m_free_index == mpt->m_free_queue_depth) { + mpt->m_free_index = 0; + } ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, - reply_index); + mpt->m_free_index); } if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { mptsas_remove_cmd(mpt, cmd); @@ -9745,7 +9741,6 @@ { int *reg_data; uint_t reglen; - char *fw_rev; /* * Lookup the 'reg' property and extract the other data @@ -9782,24 +9777,9 @@ } /* - * Lookup the 'firmware-version' property and extract the data - */ - if (ddi_prop_lookup_string(DDI_DEV_T_ANY, mpt->m_dip, - DDI_PROP_DONTPASS, "firmware-version", &fw_rev) == - DDI_PROP_SUCCESS) { - /* - * Version is a string of 4 bytes which fits into the DWORD - */ - (void) strcpy((char *)&adapter_data->MpiFirmwareVersion, - fw_rev); - ddi_prop_free(fw_rev); - } else { - /* - * If we can't determine the PCI data then we fill in FF's for - * the data to indicate this. - */ - adapter_data->MpiFirmwareVersion = 0xFFFFFFFF; - } + * Saved in the mpt->m_fwversion + */ + adapter_data->MpiFirmwareVersion = mpt->m_fwversion; } static void @@ -9810,9 +9790,12 @@ mptsas_lookup_pci_data(mpt, adapter_data); adapter_data->AdapterType = MPTIOCTL_ADAPTER_TYPE_SAS2; adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid; + adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid; adapter_data->SubSystemId = (uint32_t)mpt->m_ssid; adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid; (void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr); + adapter_data->BiosVersion = 0; + (void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion); } static void @@ -10138,9 +10121,16 @@ { ddi_dma_cookie_t cookie; 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) { @@ -10164,53 +10154,78 @@ */ if (mptsas_ioc_reset(mpt) == MPTSAS_RESET_FAIL) { mptsas_log(mpt, CE_WARN, "hard reset failed!"); - return (DDI_FAILURE); - } - /* - * Do some initilization only needed during attach - */ - if (first_time) { - /* - * Get ioc facts from adapter - */ - if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) { - mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts " - "failed"); - goto fail; - } - - /* - * Allocate request message frames - */ - if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) { - 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 " + 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"); + goto fail; + } + /* + * Re-allocate active slots here if not the first reset. Since + * m_active could have a different number of slots allocated after a + * reset, just de-allocate the old m_active structure and re-allocate a + * new one. Save the tables and IR info from the old m_active. + */ + if (first_time == FALSE) { + new_active = kmem_zalloc(MPTSAS_SLOTS_SIZE(mpt), KM_SLEEP); + if (new_active == NULL) { + mptsas_log(mpt, CE_WARN, "Re-alloc of active slots " "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!"); - goto fail; - } - /* - * Allocate reply message frames - */ - if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) { - mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames " - "failed!"); - goto fail; - } + } else { + new_active->m_n_slots = (mpt->m_max_requests - 2); + new_active->m_size = MPTSAS_SLOTS_SIZE(mpt); + new_active->m_tags = 1; + new_active->m_tgttbl = mpt->m_active->m_tgttbl; + new_active->m_smptbl = mpt->m_active->m_smptbl; + new_active->m_num_raid_configs = + mpt->m_active->m_num_raid_configs; + for (i = 0; i < new_active->m_num_raid_configs; i++) { + new_active->m_raidconfig[i] = + mpt->m_active->m_raidconfig[i]; + } + kmem_free(mpt->m_active, mpt->m_active->m_size); + mpt->m_active = new_active; + } + } + + /* + * Allocate request message frames + */ + if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) { + 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!"); + 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!"); + goto fail; + } + /* + * Allocate reply message frames + */ + if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) { + mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames " + "failed!"); + goto fail; } /* @@ -10226,14 +10241,9 @@ /* * Initialize reply post index and request index. Reply free index is - * initialized after the next loop. m_tags must only be initialized if - * this is not the first time because m_active is not allocated if this - * is the first time. + * initialized after the next loop. */ mpt->m_post_index = 0; - if (!first_time) { - mpt->m_active->m_tags = 1; - } /* * Initialize the Reply Free Queue with the physical addresses of our @@ -10280,7 +10290,7 @@ * is complete, get the base WWID. */ - if (first_time) { + if (first_time == TRUE) { if (mptsas_set_initiator_mode(mpt)) { mptsas_log(mpt, CE_WARN, "mptsas_set_initiator_mode " "failed!"); @@ -10297,7 +10307,7 @@ /* * enable events */ - if (first_time != TRUE) { + if (first_time == FALSE) { if (mptsas_ioc_enable_event_notification(mpt)) { goto fail; }
--- a/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_impl.c Tue Sep 22 12:05:08 2009 +0800 +++ b/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_impl.c Tue Sep 22 14:06:23 2009 +0800 @@ -304,7 +304,6 @@ int rval = DDI_SUCCESS, config_flags = 0; mptsas_cmd_t *cmd; struct scsi_pkt *pkt; - uint32_t reply_index; pMpi2ConfigReply_t reply; uint16_t iocstatus = 0; uint32_t iocloginfo; @@ -429,18 +428,16 @@ * if this reply is an ADDRESS reply. */ if (config_flags & MPTSAS_ADDRESS_REPLY) { - reply_index = mpt->m_free_index; ddi_put32(mpt->m_acc_free_queue_hdl, - &((uint32_t *)(void *)mpt->m_free_queue)[reply_index], + &((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 (++reply_index == mpt->m_free_queue_depth) { - reply_index = 0; + if (++mpt->m_free_index == mpt->m_free_queue_depth) { + mpt->m_free_index = 0; } - mpt->m_free_index = reply_index; ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, - reply_index); + mpt->m_free_index); config_flags &= (~MPTSAS_ADDRESS_REPLY); } @@ -578,18 +575,16 @@ * if this reply is an ADDRESS reply. */ if (config_flags & MPTSAS_ADDRESS_REPLY) { - reply_index = mpt->m_free_index; ddi_put32(mpt->m_acc_free_queue_hdl, - &((uint32_t *)(void *)mpt->m_free_queue)[reply_index], + &((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 (++reply_index == mpt->m_free_queue_depth) { - reply_index = 0; + if (++mpt->m_free_index == mpt->m_free_queue_depth) { + mpt->m_free_index = 0; } - mpt->m_free_index = reply_index; ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, - reply_index); + mpt->m_free_index); } if (cmd->cmd_dmahandle != NULL) { @@ -1086,7 +1081,7 @@ mptsas_cmd_t *cmd; struct scsi_pkt *pkt; mptsas_slots_t *slots = mpt->m_active; - uint32_t request_desc_low, int_mask; + uint32_t request_desc_low; /* * Can't start another task management routine. @@ -1137,22 +1132,14 @@ ddi_put8(mpt->m_acc_req_frame_hdl, &task->TaskType, task_type); /* - * Get the current interrupt mask. When re-enabling ints, set mask to - * saved value. - */ - int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask); - - /* * Send TM request using High Priority Queue. */ - MPTSAS_DISABLE_INTR(mpt); (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); - ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask); if (pkt->pkt_reason == CMD_INCOMPLETE) rval = FALSE; @@ -1755,6 +1742,54 @@ return (rval); } +static int +mptsas_biospage_3_cb(mptsas_t *mpt, caddr_t page_memp, + ddi_acc_handle_t accessp, uint16_t iocstatus, uint32_t iocloginfo, + va_list ap) +{ +#ifndef __lock_lint + _NOTE(ARGUNUSED(ap)) +#endif + pMpi2BiosPage3_t sasbiospage; + int rval = DDI_SUCCESS; + uint32_t *bios_version; + + if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) && + (iocstatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)) { + mptsas_log(mpt, CE_WARN, "mptsas_get_bios_page3 header: " + "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, iocloginfo); + rval = DDI_FAILURE; + return (rval); + } + bios_version = va_arg(ap, uint32_t *); + sasbiospage = (pMpi2BiosPage3_t)page_memp; + *bios_version = ddi_get32(accessp, &sasbiospage->BiosVersion); + + return (rval); +} + +/* + * Request MPI configuration page BIOS page 3 to get BIOS version. Since all + * other information in this page is not needed, just ignore it. + */ +int +mptsas_get_bios_page3(mptsas_t *mpt, uint32_t *bios_version) +{ + int rval = DDI_SUCCESS; + + ASSERT(mutex_owned(&mpt->m_mutex)); + + /* + * Get the header and config page. reply contains the reply frame, + * which holds status info for the request. + */ + rval = mptsas_access_config_page(mpt, + MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, MPI2_CONFIG_PAGETYPE_BIOS, 3, + 0, mptsas_biospage_3_cb, bios_version); + + return (rval); +} + /* * Read IO unit page 0 to get information for each PHY. If needed, Read IO Unit * page1 to update the PHY information. This is the handshaking version of
--- a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h Tue Sep 22 12:05:08 2009 +0800 +++ b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mptsas_var.h Tue Sep 22 14:06:23 2009 +0800 @@ -407,7 +407,6 @@ m_raidconfig_t m_raidconfig[MPTSAS_MAX_RAIDCONFIGS]; uint8_t m_num_raid_configs; uint16_t m_tags; - uint32_t m_buffer; size_t m_size; uint16_t m_n_slots; mptsas_cmd_t *m_slot[1]; @@ -791,6 +790,7 @@ /* * Event recording */ + uint8_t m_event_index; uint32_t m_event_number; uint32_t m_event_mask[4]; mptsas_event_entry_t m_events[MPTSAS_EVENT_QUEUE_SIZE]; @@ -1237,6 +1237,7 @@ int mptsas_get_manufacture_page5(mptsas_t *mpt); int mptsas_get_sas_port_page0(mptsas_t *mpt, uint32_t page_address, uint64_t *sas_wwn, uint8_t *portwidth); +int mptsas_get_bios_page3(mptsas_t *mpt, uint32_t *bios_version); /* * RAID functions