📄 mptbase.c
字号:
facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth); facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize); facts->FWVersion = le16_to_cpu(facts->FWVersion); facts->ProductID = le16_to_cpu(facts->ProductID); facts->CurrentHostMfaHighAddr = le32_to_cpu(facts->CurrentHostMfaHighAddr); facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits); facts->CurrentSenseBufferHighAddr = le32_to_cpu(facts->CurrentSenseBufferHighAddr); facts->CurReplyFrameSize = le16_to_cpu(facts->CurReplyFrameSize); /* * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx * Older MPI-1.00.xx struct had 13 dwords, and enlarged * to 14 in MPI-1.01.0x. */ if (facts->MsgLength >= sizeof(IOCFactsReply_t)/sizeof(u32) && facts->MsgVersion > 0x0100) { facts->FWImageSize = le32_to_cpu(facts->FWImageSize); facts->DataImageSize = le32_to_cpu(facts->DataImageSize); } if (facts->RequestFrameSize) { /* * Set values for this IOC's REQUEST queue size & depth... */ ioc->req_sz = MIN(MPT_REQ_SIZE, facts->RequestFrameSize * 4); /* * Set values for this IOC's REPLY queue size & depth... * * BUG? FIX? 20000516 -nromer & sralston * GRRR... The following did not translate well from MPI v0.09: * ioc->reply_sz = MIN(MPT_REPLY_SIZE, facts->ReplySize * 4); * to 0.10: * ioc->reply_sz = MIN(MPT_REPLY_SIZE, facts->BlockSize * 4); * Was trying to minimally optimize to smallest possible reply size * (and greatly reduce kmalloc size). But LAN may need larger reply? * * So for now, just set reply size to request size. FIXME? */ ioc->reply_sz = ioc->req_sz; } else { /* Something is wrong! */ printk(KERN_ERR MYNAM ": %s: ERROR - IOC reported invalid 0 request size!\n", ioc->name); ioc->req_sz = MPT_REQ_SIZE; ioc->reply_sz = MPT_REPLY_SIZE; return -55; } ioc->req_depth = MIN(MPT_REQ_DEPTH, facts->GlobalCredits); ioc->reply_depth = MIN(MPT_REPLY_DEPTH, facts->ReplyQueueDepth); dprintk((KERN_INFO MYNAM ": %s: reply_sz=%3d, reply_depth=%4d\n", ioc->name, ioc->reply_sz, ioc->reply_depth)); dprintk((KERN_INFO MYNAM ": %s: req_sz =%3d, req_depth =%4d\n", ioc->name, ioc->req_sz, ioc->req_depth)); /* Get port facts! */ if ( (r = GetPortFacts(ioc, 0)) != 0 ) return r; } else { printk(KERN_ERR MYNAM ": %s: ERROR - Invalid IOC facts reply!\n", ioc->name); return -66; } return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* * GetPortFacts - Send PortFacts request to MPT adapter. * @ioc: Pointer to MPT_ADAPTER structure * @portnum: Port number * * Returns 0 for success, non-zero for failure. */static intGetPortFacts(MPT_ADAPTER *ioc, int portnum){ PortFacts_t get_pfacts; PortFactsReply_t *pfacts; int i; int req_sz; int reply_sz; /* IOC *must* NOT be in RESET state! */ if (ioc->last_state == MPI_IOC_STATE_RESET) { printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n", ioc->name, ioc->last_state ); return -4; } pfacts = &ioc->pfacts[portnum]; /* Destination (reply area)... */ reply_sz = sizeof(*pfacts); memset(pfacts, 0, reply_sz); /* Request area (get_pfacts on the stack right now!) */ req_sz = sizeof(get_pfacts); memset(&get_pfacts, 0, req_sz); get_pfacts.Function = MPI_FUNCTION_PORT_FACTS; get_pfacts.PortNumber = portnum; /* Assert: All other get_pfacts fields are zero! */ dprintk((KERN_INFO MYNAM ": %s: Sending get PortFacts(%d) request\n", ioc->name, portnum)); /* No non-zero fields in the get_pfacts request are greater than * 1 byte in size, so we can just fire it off as is. */ i = HandShakeReqAndReply(ioc, req_sz, (u32*)&get_pfacts, reply_sz, (u16*)pfacts, 3); if (i != 0) return i; /* Did we get a valid reply? */ /* Now byte swap the necessary fields in the response. */ pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext); pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus); pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo); pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices); pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID); pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags); pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers); pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs); pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets); return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* * SendIocInit - Send IOCInit request to MPT adapter. * @ioc: Pointer to MPT_ADAPTER structure * * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state. * * Returns 0 for success, non-zero for failure. */static intSendIocInit(MPT_ADAPTER *ioc){ IOCInit_t ioc_init; MPIDefaultReply_t init_reply; u32 state; int r; int count; int cntdn; memset(&ioc_init, 0, sizeof(ioc_init)); memset(&init_reply, 0, sizeof(init_reply)); ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;/* ioc_init.ChainOffset = 0; */ ioc_init.Function = MPI_FUNCTION_IOC_INIT;/* ioc_init.Flags = 0; */ /*ioc_init.MaxDevices = 16;*/ ioc_init.MaxDevices = 255;/* ioc_init.MaxBuses = 16; */ ioc_init.MaxBuses = 1;/* ioc_init.MsgFlags = 0; *//* ioc_init.MsgContext = cpu_to_le32(0x00000000); */ ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */ ioc_init.HostMfaHighAddr = cpu_to_le32(0); /* Say we 32-bit! for now */ dprintk((KERN_INFO MYNAM ": %s: Sending IOCInit (req @ %p)\n", ioc->name, &ioc_init)); r = HandShakeReqAndReply(ioc, sizeof(IOCInit_t), (u32*)&ioc_init, sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10); if (r != 0) return r; /* No need to byte swap the multibyte fields in the reply * since we don't even look at it's contents. */ if ((r = SendPortEnable(ioc, 0)) != 0) return r; /* YIKES! SUPER IMPORTANT!!! * Poll IocState until _OPERATIONAL while IOC is doing * LoopInit and TargetDiscovery! */ count = 0; cntdn = HZ * 60; /* chg'd from 30 to 60 seconds */ state = GetIocState(ioc, 1); while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) { current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); if (!cntdn) { printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_OP state timeout(%d)!\n", ioc->name, (count+5)/HZ); return -9; } state = GetIocState(ioc, 1); count++; } dhsprintk((KERN_INFO MYNAM ": %s: INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n", ioc->name, count)); return r;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* * SendPortEnable - Send PortEnable request to MPT adapter port. * @ioc: Pointer to MPT_ADAPTER structure * @portnum: Port number to enable * * Send PortEnable to bring IOC to OPERATIONAL state. * * Returns 0 for success, non-zero for failure. */static intSendPortEnable(MPT_ADAPTER *ioc, int portnum){ PortEnable_t port_enable; MPIDefaultReply_t reply_buf; int i; int req_sz; int reply_sz; /* Destination... */ reply_sz = sizeof(MPIDefaultReply_t); memset(&reply_buf, 0, reply_sz); req_sz = sizeof(PortEnable_t); memset(&port_enable, 0, req_sz); port_enable.Function = MPI_FUNCTION_PORT_ENABLE; port_enable.PortNumber = portnum;/* port_enable.ChainOffset = 0; *//* port_enable.MsgFlags = 0; *//* port_enable.MsgContext = 0; */ dprintk((KERN_INFO MYNAM ": %s: Sending Port(%d)Enable (req @ %p)\n", ioc->name, portnum, &port_enable)); i = HandShakeReqAndReply(ioc, req_sz, (u32*)&port_enable, reply_sz, (u16*)&reply_buf, 65); if (i != 0) return i; /* We do not even look at the reply, so we need not * swap the multi-byte fields. */ return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* * KickStart - Perform hard reset of MPT adapter. * @ioc: Pointer to MPT_ADAPTER structure * @force: Force hard reset * * This routine places MPT adapter in diagnostic mode via the * WriteSequence register, and then performs a hard reset of adapter * via the Diagnostic register. * * Returns 0 for soft reset success, 1 for hard reset success, * else a negative value for failure. */static intKickStart(MPT_ADAPTER *ioc, int force){ int hard_reset_done = 0; u32 ioc_state; int cnt = 0; dprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name)); hard_reset_done = mpt_fc9x9_reset(ioc, force);#if 0 if (ioc->chip_type == FC909 || ioc->chip-type == FC919) { hard_reset_done = mpt_fc9x9_reset(ioc, force); } else if (ioc->chip_type == FC929) { unsigned long delta; delta = jiffies - ioc->last_kickstart; dprintk((KERN_INFO MYNAM ": %s: 929 KickStart, last=%ld, delta = %ld\n", ioc->name, ioc->last_kickstart, delta)); if ((ioc->sod_reset == 0) || (delta >= 10*HZ)) hard_reset_done = mpt_fc9x9_reset(ioc, ignore); else { dprintk((KERN_INFO MYNAM ": %s: Skipping KickStart (delta=%ld)!\n", ioc->name, delta)); return 0; } /* TODO! Add C1030! } else if (ioc->chip_type == C1030) { */ } else { printk(KERN_ERR MYNAM ": %s: ERROR - Bad chip_type (0x%x)\n", ioc->name, ioc->chip_type); return -5; }#endif if (hard_reset_done < 0) return hard_reset_done; dprintk((KERN_INFO MYNAM ": %s: Diagnostic reset successful\n", ioc->name)); for (cnt=0; cnt<HZ*20; cnt++) { if ((ioc_state = GetIocState(ioc, 1)) == MPI_IOC_STATE_READY) { dprintk((KERN_INFO MYNAM ": %s: KickStart successful! (cnt=%d)\n", ioc->name, cnt)); return hard_reset_done; } /* udelay(10000) ? */ current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); } printk(KERN_ERR MYNAM ": %s: ERROR - Failed to come READY after reset!\n", ioc->name); return -1;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* * mpt_fc9x9_reset - Perform hard reset of FC9x9 adapter. * @ioc: Pointer to MPT_ADAPTER structure * * This routine places FC9x9 adapter in diagnostic mode via the * WriteSequence register, and then performs a hard reset of adapter * via the Diagnostic register. * * Returns 0 for success, non-zero for failure. */static intmpt_fc9x9_reset(MPT_ADAPTER *ioc, int ignore){ u32 diag0val; int hard_reset_done = 0; /* Use "Diagnostic reset" method! (only thing available!) */ diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);#ifdef MPT_DEBUG{ u32 diag1val = 0; if (ioc->alt_ioc) diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); dprintk((KERN_INFO MYNAM ": %s: DBG1: diag0=%08x, diag1=%08x\n", ioc->name, diag0val, diag1val));}#endif if (diag0val & MPI_DIAG_DRWE) { dprintk((KERN_INFO MYNAM ": %s: DiagWriteEn bit already set\n", ioc->name)); } else { /* Write magic sequence to WriteSequence register */ CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE); CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE); dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence [spot#1]\n", ioc->name)); } diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);#ifdef MPT_DEBUG{ u32 diag1val = 0; if (ioc->alt_ioc) diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); dprintk((KERN_INFO MYNAM ": %s: DbG2: diag0=%08x, diag1=%08x\n", ioc->name, diag0val, diag1val));}#endif if (!ignore && (diag0val & MPI_DIAG_RESET_HISTORY)) { dprintk((KERN_INFO MYNAM ": %s: Skipping due to ResetHistory bit set!\n", ioc->name)); } else { /* * Now hit the reset bit in the Diagnostic register * (THE BIG HAMMER!) */ CHIPREG_WRITE32(&ioc->chip->Diagnostic, MPI_DIAG_RESET_ADAPTER); hard_reset_done = 1; dprintk((KERN_INFO MYNAM ": %s: Diagnostic reset performed\n", ioc->name)); /* want udelay(100) */ current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); /* Write magic sequence to WriteSequence register */ CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE); CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE); dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence [spot#2]\n", ioc->name)); } /* Clear RESET_HISTORY bit! */ CHIPREG_WRITE32(&ioc->chip->Diagnostic, 0x0); diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);#ifdef MPT_DEBUG{ u32 diag1val = 0; if (ioc->alt_ioc) diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); dprintk((KERN_INFO MYNAM ": %s: DbG3: diag0=%08x, diag1=%08x\n", ioc->name, diag0val, diag1val));}#endif if (diag0val & MPI_DIAG_RESET_HISTORY) { printk(KERN_WARNING MYNAM ": %s: WARNING - ResetHistory bit failed to clear!\n", ioc->name); } diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);#ifdef MPT_DEBUG{ u32 diag1val = 0; if (ioc->alt_ioc) diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); dprintk((KERN_INFO MYNAM ": %s: DbG4: diag0=%08x, diag1=%08x\n", ioc->name, diag0val, diag1val));}#endif if (diag0val & (MPI_DIAG_FLASH_BAD_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -