📄 core_ses.c
字号:
MV_PRINT("MakeSesEnclosureStatusRequest failed, 0x%x scratch memory is needed.\n", (PageLength+4)); return; } MV_CopyMemory(pDevice->SesControlBuffer, pReq->Data_Buffer, PageLength+4);}void SES_InternalReqCallback( IN MV_PVOID This, IN PMV_Request pReq){ PCore_Driver_Extension pCore = (PCore_Driver_Extension)This; PDomain_Port pPort; PDomain_Device pDevice = NULL; pPort = &pCore->Ports[MapPortEntry(pCore,MapPortId(pCore, pReq->Device_Id))]; pDevice = &pCore->Devices[MapDeviceId(pCore, pReq->Device_Id)]; if(pReq->Scsi_Status==REQ_STATUS_SUCCESS) { if(pReq->Cdb[0]==SCSI_CMD_RCV_DIAG_RSLT) { switch( pReq->Cdb[2] ) { case SES_PG_CONFIGURATION: PostMakeSesConfigurationRequest(pDevice, pReq); break; case SES_PG_DEVICE_ELEMENT_STATUS: PostMakeSesElementStatusRequest(pDevice, pReq); break; case SES_PG_ELEMENT_DESCRIPTOR: PostMakeSesElementDescriptorRequest(pDevice, pReq); break; case SES_PG_ENCLOSURE_STATUS: PostMakeSesEnclosureStatusRequest(pDevice, pReq); break; } } else if(pReq->Cdb[0]==SCSI_CMD_SND_DIAG) { switch( pReq->Cdb[2] ) { case SES_PG_ENCLOSURE_CONTROL: MV_PRINT("SES_PG_ENCLOSURE_CONTROL is completed\n"); break; } } } if( pReq->Scratch_Buffer ) FreeSATAScratchToPool(pCore, (PSATA_Scratch_Buffer *) &pReq->Scratch_Buffer); FreeInternalReqToPool( pCore, pReq );}void Device_MakeSesRcvDiagRequest( PDomain_Device pDevice, MV_U8 PageCode){ PCore_Driver_Extension pCore = pDevice->pPort->Core_Extension; PMV_Request pReq = GetInternalReqFromPool(pCore); PSATA_Scratch_Buffer pSATASB; PMV_SG_Table pSGTable = &pReq->SG_Table; if( pReq == NULL ) { MV_DPRINT(("ERROR: No more free internal requests. Request aborted.\n")); return; } pSATASB = GetSATAScratchFromPool(pCore); if( pSATASB == NULL ) { FreeInternalReqToPool(pCore, pReq); MV_DPRINT(("ERROR: No more free SATA scratch buffer. Request aborted.\n")); return; } pReq->Tag = 0xac; pReq->Device_Id = pDevice->Id; //pReq->Req_Flag; pReq->Cmd_Initiator = pCore; pReq->Data_Transfer_Length = SATA_SCRATCH_BUFFER_SIZE; pReq->Cmd_Flag = CMD_FLAG_DATA_IN; pReq->Data_Buffer = pSATASB->Scratch_Vir; pReq->Scratch_Buffer = pSATASB; pReq->Completion = (void(*)(MV_PVOID,PMV_Request))SES_InternalReqCallback; /* Prepare read receive diagnostic result */ pReq->Cdb[0] = SCSI_CMD_RCV_DIAG_RSLT; pReq->Cdb[1] = 0x01; /* PCV */ pReq->Cdb[2] = PageCode; pReq->Cdb[3] = (MV_U8)((pReq->Data_Transfer_Length&0xff00)>>8); pReq->Cdb[4] = (MV_U8)(pReq->Data_Transfer_Length&0xff); /* Make the SG table. */ SGTable_Init(pSGTable, 0); SGTable_Append( pSGTable, pSATASB->Scratch_DMA.parts.low, pSATASB->Scratch_DMA.parts.high, pReq->Data_Transfer_Length); /* Send this internal request */#ifdef SUPPORT_I2C if(pDevice->pPort->Type&PORT_TYPE_I2C) I2C_PrepareAndSendCommand(pCore, pReq); else#endif Core_ModuleSendRequest(pCore, pReq);}void FillEnclosureElementStatus( PDomain_Device pSesDevice, MV_U8 OverallElementIndex, PSesEnclosureElement pStatus, MV_BOOLEAN ToSesControlBuffer){ PCore_Driver_Extension pCore = pSesDevice->pPort->Core_Extension; MV_U8 i; for(i=0; i<MAX_DEVICE_ID; i++) { MV_U8 index; index=pCore->Device_Map[i]; if(index!=ID_NOT_MAPPED) { if( (pCore->Devices[index].pSesDevice==pSesDevice)&& (pCore->Devices[index].SesOverallElementIndex==OverallElementIndex) ) { if(ToSesControlBuffer) *pStatus=pCore->Devices[index].SesEnclosureStatus; else pCore->Devices[index].SesEnclosureStatus=*pStatus; break; } } }}void UpdateStatusVsSesControlBuffer( PDomain_Device pSesDevice, MV_BOOLEAN ToSesControlBuffer){ PEnclosureStatusPage pEnclosureStatusPage; PSesEnclosureElement pElementStatus; MV_U16 PageLength; MV_U8 ElementCount; pEnclosureStatusPage = (PEnclosureStatusPage)pSesDevice->SesControlBuffer; PageLength= (pEnclosureStatusPage->PageLength[0]<<8) + pEnclosureStatusPage->PageLength[1]; if ( (PageLength+4)> SES_CONTROL_BUFFER_SIZE) { MV_PRINT("UpdateStatusVsSesControlBuffer failed, 0x%x memory is needed.\n", (PageLength+4)); return; } if(ToSesControlBuffer) pEnclosureStatusPage->Status = pSesDevice->SesOverallEnclosureStatus; /* status page and control page are compatible in size and major fields */ else pSesDevice->SesOverallEnclosureStatus = pEnclosureStatusPage->Status; pElementStatus = (PSesEnclosureElement) ((MV_PTR_INTEGER)pEnclosureStatusPage + sizeof(EnclosureStatusPage)); ElementCount=0; while((MV_PTR_INTEGER)pElementStatus< ((MV_PTR_INTEGER)pEnclosureStatusPage+ PageLength + 4)) { FillEnclosureElementStatus(pSesDevice, ElementCount, pElementStatus, ToSesControlBuffer); ElementCount++; pElementStatus = (PSesEnclosureElement) ((MV_PTR_INTEGER)pElementStatus + sizeof(SesEnclosureElement)); }}void Device_WriteSesControlDiag( PDomain_Device pSesDevice){ PCore_Driver_Extension pCore = pSesDevice->pPort->Core_Extension; PEnclosureControlPage pEnclosureControlPage; MV_U16 PageLength; PMV_Request pReq=NULL; PSATA_Scratch_Buffer pSATASB=NULL; PMV_SG_Table pSGTable=NULL; pEnclosureControlPage = (PEnclosureControlPage)pSesDevice->SesControlBuffer; PageLength= (pEnclosureControlPage->PageLength[0]<<8) + pEnclosureControlPage->PageLength[1]; if ( (PageLength+4)> SES_CONTROL_BUFFER_SIZE) { MV_PRINT("Device_WriteSesControlDiag failed, 0x%x memory is needed.\n", (PageLength+4)); return; } pReq = GetInternalReqFromPool(pCore); if( pReq == NULL ) { MV_DPRINT(("ERROR: No more free internal requests. Request aborted.\n")); return; } pSATASB = GetSATAScratchFromPool(pCore); if( pSATASB == NULL ) { FreeInternalReqToPool(pCore, pReq); MV_DPRINT(("ERROR: No more free SATA scratch buffer. Request aborted.\n")); return; } pSGTable = &pReq->SG_Table; MV_CopyMemory(pSATASB->Scratch_Vir, pSesDevice->SesControlBuffer, PageLength+4); pReq->Tag = 0xac; pReq->Device_Id = pSesDevice->Id; //pReq->Req_Flag; pReq->Cmd_Initiator = pCore; pReq->Data_Transfer_Length = PageLength+4; pReq->Cmd_Flag &= ~CMD_FLAG_DATA_IN; pReq->Data_Buffer = pSATASB->Scratch_Vir; pReq->Scratch_Buffer = pSATASB; pReq->Completion = (void(*)(MV_PVOID,PMV_Request))SES_InternalReqCallback; /* Prepare send diagnostic */ pReq->Cdb[0] = SCSI_CMD_SND_DIAG; pReq->Cdb[1] = 0x0; /* PCV */ pReq->Cdb[2] = SES_PG_ENCLOSURE_CONTROL; pReq->Cdb[3] = (MV_U8)((pReq->Data_Transfer_Length&0xff00)>>8); pReq->Cdb[4] = (MV_U8)(pReq->Data_Transfer_Length&0xff); /* Make the SG table. */ SGTable_Init(pSGTable, 0); SGTable_Append( pSGTable, pSATASB->Scratch_DMA.parts.low, pSATASB->Scratch_DMA.parts.high, pReq->Data_Transfer_Length); /* Send this internal request */#ifdef SUPPORT_I2C if(pSesDevice->pPort->Type&PORT_TYPE_I2C) I2C_PrepareAndSendCommand(pCore, pReq); else#endif Core_ModuleSendRequest(pCore, pReq);}#endif //#ifdef SUPPORT_SES/* Note on using SES calls:[ Get SAS-address/Enclosure-Slot mapping ]Call Device_MakeSesElementStatusRequest(). [ Control the enclosure's LED ]There are three objects,STATUS: used by the driver for disk drive's setting, LED settings, for example. SesOverallEnclosureStatus of the SES Device, SesEnclosureStatus of the element devices managed by the SES deviceBUFFER: used by the driver to store current Ses Page of a SES device.ENCLOSURE PAGE: used by the Enclosure.Example:A. Get Current Element Disk drive Status in an Enclosure 1. Read Enclosure Page into Buffer, Device_MakeSesRcvDiagRequest(), for example, Device_MakeSesEnclosureStatusRequest(). Page->Buffer 2. Update STATUS by the Buffer, UpdateStatusVsSesControlBuffer(a ,MV_FALSE). Buffer->StatusB. Change the Enclosure by Current Driver's Setting 1. Change Current Driver's Setting, STATUS, as Desired. 2. Read Enclosure Page into Buffer, Device_MakeSesRcvDiagRequest(), for example, Device_MakeSesEnclosureStatusRequest(). Page->Buffer 3. Update the Buffer by STATUS, UpdateStatusVsSesControlBuffer(a ,MV_TRUE). Status->Buffer 4. Send to Enclosure, Device_WriteSesControlDiag(). Buffer->Page*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -