core_helper.c
来自「6440linuxDriver的源代码」· C语言 代码 · 共 2,385 行 · 第 1/5 页
C
2,385 行
#include "core_header.h"#include "core_exp.h"#include "core_helper.h"#include "core_init.h"void MV_DumpRegister(MV_PVOID This);#ifdef CORE_SAS_SUPPORT_ATA_COMMANDvoid CoreRestoreOriginalCDB(PCore_Driver_Extension pCore, PMV_Request pReq);#endifextern MV_BOOLEANSCSI_MakeSMARTReturnStatusCommand( PCore_Driver_Extension pCore, PMV_Request pReq );extern MV_VOIDSCSI_MakeSynchronizeCacheCommmand( PCore_Driver_Extension pCore, PMV_Request pReq );extern void Core_ResetCmdSlot(MV_PVOID Port, MV_U16 SlotNo);extern MV_BOOLEANSCSI_MakeCacheCommand( PCore_Driver_Extension pCore, PMV_Request pReq, MV_BOOLEAN writeCache, MV_BOOLEAN preread );extern MV_BOOLEAN mvChannelStateMachine( PCore_Driver_Extension pCore, PDomain_Port pPort );void Core_GetSupportedCounts( MV_U16 maxIo, MV_PU8 pDevCount, MV_PU8 pExpanderCount, MV_PU8 pPMCount, MV_PU8 pInternalReqCount, MV_PU8 pSGEntryCount, MV_PU16 pSGBufferCount, MV_PU8 pSATAScratchCount, MV_PU8 pSMPScratchCount, MV_PU16 pSlotCount, MV_PU16 pContextCount, MV_PU16 pSubReqCount ){ *pDevCount = MAX_DEVICE_SUPPORTED_PERFORMANCE; if (maxIo==1) { *pExpanderCount = MAX_EXPANDER_SUPPORTED_WHQL; *pInternalReqCount = MIN_INTERNAL_REQ_COUNT; *pSGEntryCount = MAX_SG_ENTRY_REDUCED; *pSATAScratchCount = MIN_SATA_SCRATCH_COUNT; *pSMPScratchCount = MIN_SMP_SCRATCH_COUNT; *pSGBufferCount = MIN_SG_BUFFER_COUNT; *pSlotCount = 4; *pPMCount = MAX_PM_SUPPORTED_PERFORMANCE; *pSubReqCount = 0; } else { *pExpanderCount = MAX_EXPANDER_SUPPORTED_PERFORMANCE; *pSlotCount = MAX_CORE_REQUEST_NUMBER_PERFORMANCE; *pInternalReqCount = *pDevCount; *pSGEntryCount = MAX_SG_ENTRY;#ifndef SOFTWARE_XOR *pSGBufferCount = MAX_SG_BUFFER_COUNT;#else *pSGBufferCount = MAX_SG_BUFFER_COUNT_NO_XOR;#endif#ifndef SUPPORT_LARGE_REQUEST *pSubReqCount = 0;#else /* SUPPORT_LARGE_REQUEST */ *pSubReqCount = (MV_MAX_TRANSFER_SIZE + CORE_MAX_TRANSFER_SIZE-1)/CORE_MAX_TRANSFER_SIZE * (*pDevCount);#endif /* SUPPORT_LARGE_REQUEST */ *pSATAScratchCount = *pDevCount; *pSMPScratchCount = *pDevCount; *pPMCount = MAX_PM_SUPPORTED_PERFORMANCE; } *pContextCount = *pInternalReqCount + *pSlotCount + *pSubReqCount;}void Port_AbortRequests( PDomain_Port pPort, MV_U8 ScsiStatus, PDomain_Device pDevice ){ PCore_Driver_Extension pCore = pPort->Core_Extension; MV_U16 i, count; PMV_Request pReq; List_Head *pPos; MV_U8 portId; /* Device is gone. Return the Running_Req */ for ( i=0; i<pCore->Slot_Count_Supported; i++ ) {/* if this command has been queued for return, don't do abort */ if(pCore->Completing_Slot[i>>5]&(1L<<(i%32))) { MV_DPRINT(("Verified Slot(0x%x) in completion while aborting \n",i)); continue; } pReq = pCore->Running_Req[i]; if ( pReq != NULL ) { PDomain_Device pReqDev=NULL; if ( IS_A_SMP_REQ(pReq) ) { if(pDevice != NULL) continue; portId=MapPortId(pCore, pReq->Device_Id); } else { portId=MapPortId(pCore, pReq->Device_Id); if(MapDeviceId(pCore,pReq->Device_Id)!=ID_NOT_MAPPED) pReqDev=&pCore->Devices[MapDeviceId(pCore,pReq->Device_Id)]; } if( portId == pPort->Id ) { if((pDevice != NULL)&&(pDevice->Id!=pReq->Device_Id)) continue; if((ScsiStatus != REQ_STATUS_NO_DEVICE)&& (!IS_A_SMP_REQ(pReq)) && (IS_SSP(pReqDev))&& (pReqDev->Error_Handling_State==EH_NONE) ) { if(!IS_A_TSK_REQ(pReq)) { pReq->Scsi_Status = ScsiStatus; Device_MakeRequestTaskRequest(pPort,pReq,ABORT_TASK_TMF); } } else { pReq->Scsi_Status = ScsiStatus; MV_DPRINT(("AbortReq: Reset pPort(0x%x) Req->Device_Id(0x%x) Slot(0x%x)\n",MapPortId(pCore, pReq->Device_Id),pReq->Device_Id, i )); Core_ResetCmdSlot( pPort, i ); } } } } if(ScsiStatus==REQ_STATUS_RETRY) return; /* Return the waiting request related to this device. */ //TBD: Do we have a better solution? count = 0; LIST_FOR_EACH(pPos, &pCore->Waiting_List) { count++; } while ( (count>0)&&(!List_Empty(&pCore->Waiting_List)) ) { pReq = (PMV_Request)List_GetFirstEntry(&pCore->Waiting_List, MV_Request, Queue_Pointer); if((pDevice!=NULL)&&(pDevice->Id!=pReq->Device_Id)) { List_AddTail(&pReq->Queue_Pointer, &pCore->Waiting_List); count--; continue; } portId=MapPortId(pCore, pReq->Device_Id);/* leave TASK requests on */ if( (portId==pPort->Id)&&(!IS_A_TSK_REQ(pReq)) ) { pReq->Scsi_Status = ScsiStatus; CompleteRequest(pCore, pReq, 0); } else { List_AddTail(&pReq->Queue_Pointer, &pCore->Waiting_List); } count--; }}/* this is mainly for SATA/STP (NCQ etc.) *//* do not count SAS/SMP, etc requests in it */MV_BOOLEAN Port_IsRequestRunning( PCore_Driver_Extension pCore, MV_U8 portId ){ PMV_Request pReq; struct _Domain_Device *pDevice = NULL; MV_U16 deviceId; MV_U16 i; for( i=0; i<pCore->Slot_Count_Supported; i++ ) { pReq = pCore->Running_Req[i]; if(pReq != NULL) { MV_U8 reqPortId; reqPortId=MapPortId(pCore,pReq->Device_Id); deviceId = MapDeviceId(pCore, pReq->Device_Id); pDevice= &pCore->Devices[deviceId]; if((reqPortId == portId)&&IS_STP_OR_SATA(pDevice)) return MV_TRUE; } } return MV_FALSE;}/* A memory-saving way to return an unique tag (return 32 if not found). Could be replaced by a tag pool if for performance regardless memory usage*/MV_U16 GetNCQTag( PDomain_Device pDevice){ PCore_Driver_Extension pCore = pDevice->pPort->Core_Extension; PMV_Command_Header pCmdHeader = (PMV_Command_Header)pCore->Cmd_List; MV_U16 Tag; MV_U16 i; for(Tag=0;Tag<32;Tag++) { for(i=0;i<pCore->Slot_Count_Supported;i++) { if(pCore->Running_Req[i]!=NULL) { if(IS_A_SMP_REQ(pCore->Running_Req[i])) continue; if((pDevice->Id==pCore->Running_Req[i]->Device_Id)&& (pCmdHeader[i].Tag==Tag)) break; } } if(i==pCore->Slot_Count_Supported) break; } return Tag;}MV_BOOLEAN Core_WaitingForIdle(MV_PVOID pExtension){ PCore_Driver_Extension pCore = (PCore_Driver_Extension)pExtension; MV_U8 i; for(i=0;i<16;i++) { if ( pCore->Running_Slot[i] != 0 ) return MV_FALSE; } return MV_TRUE;}void Core_FillSenseData(PMV_Request pReq, MV_U8 senseKey, MV_U8 adSenseCode){ if (pReq->Sense_Info_Buffer != NULL) { ((MV_PU8)pReq->Sense_Info_Buffer)[0] = 0x70; /* Current */ ((MV_PU8)pReq->Sense_Info_Buffer)[2] = senseKey; ((MV_PU8)pReq->Sense_Info_Buffer)[7] = 0; /* additional sense length */ ((MV_PU8)pReq->Sense_Info_Buffer)[12] = adSenseCode; /* additional sense code */ }}void MV_DumpRegister(MV_PVOID This){#ifndef _OS_BIOS PCore_Driver_Extension pCore = (PCore_Driver_Extension)This; MV_U32 reg; MV_PTR_INTEGER offset; MV_REG_WRITE_DWORD(pCore->Mmio_Base, COMMON_CMD_ADDR, CMD_PORT_ISS0); reg=MV_REG_READ_DWORD(pCore->Mmio_Base, COMMON_CMD_DATA); MV_PRINT("CMD_PORT_ISS0 =0x%x\n",reg); MV_REG_WRITE_DWORD(pCore->Mmio_Base, COMMON_CMD_ADDR, CMD_PORT_ACTIVE0); reg=MV_REG_READ_DWORD(pCore->Mmio_Base, COMMON_CMD_DATA); MV_PRINT("CMD_PORT_ACTIVE0 =0x%x\n",reg); reg=MV_REG_READ_DWORD(pCore->Mmio_Base, COMMON_CONTROL ); MV_PRINT("COMMON_CONTROL = 0x%x\n",reg); reg=MV_REG_READ_DWORD(pCore->Mmio_Base, PORT_PHY_CONTROL0 ); MV_PRINT("PORT_PHY_CONTROL0 = 0x%x\n",reg); reg=MV_REG_READ_DWORD(pCore->Mmio_Base, PORT_IRQ_STAT0 ); MV_PRINT("PORT_IRQ_STAT0 = 0x%x\n",reg); reg=MV_REG_READ_DWORD(pCore->Mmio_Base, HBA_CONTROL ); MV_PRINT("HBA_CONTROL = 0x%x\n",reg); reg=MV_REG_READ_DWORD(pCore->Mmio_Base, COMMON_IRQ_MASK ); MV_PRINT("COMMON_IRQ_MASK = 0x%x\n",reg); reg=MV_REG_READ_DWORD(pCore->Mmio_Base, COMMON_IRQ_STAT ); MV_PRINT("COMMON_IRQ_STAT = 0x%x\n",reg); reg=MV_REG_READ_DWORD(pCore->Mmio_Base, COMMON_DELV_Q_RD_PTR ); MV_PRINT("COMMON_DELV_Q_RD_PTR = 0x%x\n",reg); offset=COMMON_CMPL_Q_WR_PTR; reg=MV_REG_READ_DWORD(pCore->Mmio_Base, offset ); MV_PRINT("COMMON_CMPL_Q_WR_PTR = 0x%x\n",reg); MV_PRINT("CMPL_Q[0]= 0x%x\n",*(MV_U32 *)pCore->CMPL_Q);#endif}PMV_RequestFindRunningReqByTag( IN PCore_Driver_Extension pCore, IN MV_U16 Tag ){ MV_U16 SlotNo; SlotNo= Tag&0x1ff; if(pCore->Running_Req[SlotNo]!=NULL) { if((MV_U16)(pCore->Running_Req[SlotNo]->Tag<<pCore->MaxCmdSlotWidth)==(Tag&(0xffff<<pCore->MaxCmdSlotWidth))) return (pCore->Running_Req[SlotNo]); } return NULL;}#if defined(_OS_WINDOWS) && defined(SUPPORT_ERROR_HANDLING)MV_VOID Core_ReqTimeout (MV_PVOID This, MV_PVOID temp);MV_VOID __add_timer(IN PCore_Driver_Extension pCore, IN PMV_Request pReq){ MV_U32 mapped_id; PDomain_Device pDevice; mapped_id = MapDeviceId(pCore, pReq->Device_Id); pDevice = &pCore->Devices[mapped_id]; if (IS_A_SMP_REQ(pReq)) return; /* start timer for error handling */ if (pDevice->Timer_ID == NO_CURRENT_TIMER) { if (pReq->Time_Out != 0) pDevice->Timer_ID = Timer_AddRequest(pCore, pReq->Time_Out * 2, Core_ReqTimeout, pDevice, NULL); else pDevice->Timer_ID = Timer_AddRequest(pCore, REQUEST_TIME_OUT, Core_ReqTimeout, pDevice, NULL); }}MV_VOID __cancel_timer(IN PCore_Driver_Extension pCore, PDomain_Device pDevice, IN PMV_Request pReq){ if (pDevice->Timer_ID != NO_CURRENT_TIMER) { Timer_CancelRequest(pCore, pDevice->Timer_ID); pDevice->Timer_ID = NO_CURRENT_TIMER; }} MV_VOID __renew_timer(IN PCore_Driver_Extension pCore, IN PMV_Request pReq){ PMV_Request pOldReq; MV_U32 mapped_id; PDomain_Device pDevice; mapped_id = MapDeviceId(pCore, pReq->Device_Id); pDevice = &pCore->Devices[mapped_id]; if (!IS_A_SMP_REQ(pReq) && (mapped_id != ID_NOT_MAPPED)) { /* check if this is the oldest request */ MV_DASSERT(!List_Empty(&pDevice->Sent_Req_List)); pOldReq = (PMV_Request)List_GetFirstEntry(&pDevice->Sent_Req_List, MV_Request, Queue_Pointer); if (pOldReq == pReq) { __cancel_timer(pCore, pDevice, pReq); if (!List_Empty(&pDevice->Sent_Req_List)) { /* this should not happen on a ATAPI device */ MV_DASSERT(!IS_ATAPI(pDevice)); MV_DASSERT(!IS_TAPE(pDevice)); __add_timer(pCore, pOldReq); } } else { List_Add(&pOldReq->Queue_Pointer, &pDevice->Sent_Req_List); } }}#else /* defined(_OS_WINDOWS) && defined(SUPPORT_ERROR_HANDLING) */MV_VOID Core_ReqTimeout (MV_PVOID This);MV_VOID __cancel_timer(IN PCore_Driver_Extension pCore, IN PDomain_Device pDevice, IN PMV_Request pReq){// if (pReq)// ossw_del_timer(&pReq->timer);}/* renew for windows means cancel for linux */MV_VOID __renew_timer(IN PCore_Driver_Extension pCore, IN PMV_Request pReq){ __cancel_timer(pCore, NULL, pReq);}MV_VOID __add_timer(IN PCore_Driver_Extension pCore, IN PMV_Request pReq){ MV_U32 tm; if (IS_A_SMP_REQ(pReq)) return; if (pReq->Time_Out != 0) tm = pReq->Time_Out * 2; else tm = REQUEST_TIME_OUT; // ossw_add_timer(&pReq->timer, tm * 1000,// (OSSW_TIMER_FUNCTION) Core_ReqTimeout,// (OSSW_TIMER_DATA) pReq);}#endif /* defined(_OS_WINDOWS) && defined(SUPPORT_ERROR_HANDLING) */void FreeDeviceToPool( PCore_Driver_Extension pCore, PDomain_Device pDevice ){ MV_U16 index; index=pCore->Device_Map[pDevice->Id]; pCore->Device_Map[pDevice->Id] = ID_NOT_MAPPED; Tag_ReleaseOne(&pCore->Device_Pool, index);#ifdef USE_DYN_REGISTER_SET if(pCore->Devices[index].Register_Set!=ID_NOT_MAPPED) FreeRegisterSet(pCore,&pCore->Devices[index]);#endif /* USE_DYN_REGISTER_SET */ __cancel_timer(pCore, pDevice, NULL); pCore->Devices[index].State = DEVICE_STATE_IDLE;}void FreeExpanderToPool( PCore_Driver_Extension pCore, PDomain_Expander pExpander ){ MV_U16 index; index=pCore->Device_Map[pExpander->ExpId]; pCore->Device_Map[pExpander->ExpId] = ID_NOT_MAPPED; Tag_ReleaseOne(&pCore->Expander_Pool, index);}#ifdef SUPPORT_PMvoid FreePMToPool( PCore_Driver_Extension pCore, PDomain_PM pPM ){ MV_U16 index; index=pCore->Device_Map[pPM->Id]; pCore->Device_Map[pPM->Id] = ID_NOT_MAPPED; Tag_ReleaseOne(&pCore->PM_Pool, index);#ifdef USE_DYN_REGISTER_SET if (pCore->PMs[index].Register_Set!=ID_NOT_MAPPED) PM_FreeRegisterSet(pCore,&pCore->PMs[index]);#endif /* USE_DYN_REGISTER_SET */}void PreEmptyPM(PDomain_PM pPM){ MV_ZeroMemory((MV_U8 *)pPM,sizeof(Domain_PM));#ifdef SUPPORT_TIMER pPM->Timer_ID=NO_CURRENT_TIMER;#endif#ifdef USE_DYN_REGISTER_SET pPM->Register_Set=ID_NOT_MAPPED;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?