1e351b826SPaolo Bonzini /* 2e351b826SPaolo Bonzini * QEMU LSI SAS1068 Host Bus Adapter emulation 3e351b826SPaolo Bonzini * Endianness conversion for MPI data structures 4e351b826SPaolo Bonzini * 5e351b826SPaolo Bonzini * Copyright (c) 2016 Red Hat, Inc. 6e351b826SPaolo Bonzini * 7e351b826SPaolo Bonzini * Authors: Paolo Bonzini <pbonzini@redhat.com> 8e351b826SPaolo Bonzini * 9e351b826SPaolo Bonzini * This library is free software; you can redistribute it and/or 10e351b826SPaolo Bonzini * modify it under the terms of the GNU Lesser General Public 11e351b826SPaolo Bonzini * License as published by the Free Software Foundation; either 12*61f3c91aSChetan Pant * version 2.1 of the License, or (at your option) any later version. 13e351b826SPaolo Bonzini * 14e351b826SPaolo Bonzini * This library is distributed in the hope that it will be useful, 15e351b826SPaolo Bonzini * but WITHOUT ANY WARRANTY; without even the implied warranty of 16e351b826SPaolo Bonzini * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17e351b826SPaolo Bonzini * Lesser General Public License for more details. 18e351b826SPaolo Bonzini * 19e351b826SPaolo Bonzini * You should have received a copy of the GNU Lesser General Public 20e351b826SPaolo Bonzini * License along with this library; if not, see <http://www.gnu.org/licenses/>. 21e351b826SPaolo Bonzini */ 22e351b826SPaolo Bonzini 23e351b826SPaolo Bonzini #include "qemu/osdep.h" 24e351b826SPaolo Bonzini #include "hw/pci/pci.h" 25e351b826SPaolo Bonzini #include "sysemu/dma.h" 26e351b826SPaolo Bonzini #include "hw/pci/msi.h" 27e351b826SPaolo Bonzini #include "qemu/iov.h" 28e351b826SPaolo Bonzini #include "hw/scsi/scsi.h" 2908e2c9f1SPaolo Bonzini #include "scsi/constants.h" 30e351b826SPaolo Bonzini #include "trace.h" 31e351b826SPaolo Bonzini 32e351b826SPaolo Bonzini #include "mptsas.h" 33e351b826SPaolo Bonzini #include "mpi.h" 34e351b826SPaolo Bonzini mptsas_fix_sgentry_endianness(MPISGEntry * sge)35e351b826SPaolo Bonzinistatic void mptsas_fix_sgentry_endianness(MPISGEntry *sge) 36e351b826SPaolo Bonzini { 3797866508SPeter Maydell sge->FlagsLength = le32_to_cpu(sge->FlagsLength); 38e351b826SPaolo Bonzini if (sge->FlagsLength & MPI_SGE_FLAGS_64_BIT_ADDRESSING) { 3997866508SPeter Maydell sge->u.Address64 = le64_to_cpu(sge->u.Address64); 40e351b826SPaolo Bonzini } else { 4197866508SPeter Maydell sge->u.Address32 = le32_to_cpu(sge->u.Address32); 42e351b826SPaolo Bonzini } 43e351b826SPaolo Bonzini } 44e351b826SPaolo Bonzini mptsas_fix_sgentry_endianness_reply(MPISGEntry * sge)45e351b826SPaolo Bonzinistatic void mptsas_fix_sgentry_endianness_reply(MPISGEntry *sge) 46e351b826SPaolo Bonzini { 47e351b826SPaolo Bonzini if (sge->FlagsLength & MPI_SGE_FLAGS_64_BIT_ADDRESSING) { 4897866508SPeter Maydell sge->u.Address64 = cpu_to_le64(sge->u.Address64); 49e351b826SPaolo Bonzini } else { 5097866508SPeter Maydell sge->u.Address32 = cpu_to_le32(sge->u.Address32); 51e351b826SPaolo Bonzini } 5297866508SPeter Maydell sge->FlagsLength = cpu_to_le32(sge->FlagsLength); 53e351b826SPaolo Bonzini } 54e351b826SPaolo Bonzini mptsas_fix_scsi_io_endianness(MPIMsgSCSIIORequest * req)55e351b826SPaolo Bonzinivoid mptsas_fix_scsi_io_endianness(MPIMsgSCSIIORequest *req) 56e351b826SPaolo Bonzini { 5797866508SPeter Maydell req->MsgContext = le32_to_cpu(req->MsgContext); 5897866508SPeter Maydell req->Control = le32_to_cpu(req->Control); 5997866508SPeter Maydell req->DataLength = le32_to_cpu(req->DataLength); 6097866508SPeter Maydell req->SenseBufferLowAddr = le32_to_cpu(req->SenseBufferLowAddr); 61e351b826SPaolo Bonzini } 62e351b826SPaolo Bonzini mptsas_fix_scsi_io_reply_endianness(MPIMsgSCSIIOReply * reply)63e351b826SPaolo Bonzinivoid mptsas_fix_scsi_io_reply_endianness(MPIMsgSCSIIOReply *reply) 64e351b826SPaolo Bonzini { 6597866508SPeter Maydell reply->MsgContext = cpu_to_le32(reply->MsgContext); 6697866508SPeter Maydell reply->IOCStatus = cpu_to_le16(reply->IOCStatus); 6797866508SPeter Maydell reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo); 6897866508SPeter Maydell reply->TransferCount = cpu_to_le32(reply->TransferCount); 6997866508SPeter Maydell reply->SenseCount = cpu_to_le32(reply->SenseCount); 7097866508SPeter Maydell reply->ResponseInfo = cpu_to_le32(reply->ResponseInfo); 7197866508SPeter Maydell reply->TaskTag = cpu_to_le16(reply->TaskTag); 72e351b826SPaolo Bonzini } 73e351b826SPaolo Bonzini mptsas_fix_scsi_task_mgmt_endianness(MPIMsgSCSITaskMgmt * req)74e351b826SPaolo Bonzinivoid mptsas_fix_scsi_task_mgmt_endianness(MPIMsgSCSITaskMgmt *req) 75e351b826SPaolo Bonzini { 7697866508SPeter Maydell req->MsgContext = le32_to_cpu(req->MsgContext); 7797866508SPeter Maydell req->TaskMsgContext = le32_to_cpu(req->TaskMsgContext); 78e351b826SPaolo Bonzini } 79e351b826SPaolo Bonzini mptsas_fix_scsi_task_mgmt_reply_endianness(MPIMsgSCSITaskMgmtReply * reply)80e351b826SPaolo Bonzinivoid mptsas_fix_scsi_task_mgmt_reply_endianness(MPIMsgSCSITaskMgmtReply *reply) 81e351b826SPaolo Bonzini { 8297866508SPeter Maydell reply->MsgContext = cpu_to_le32(reply->MsgContext); 8397866508SPeter Maydell reply->IOCStatus = cpu_to_le16(reply->IOCStatus); 8497866508SPeter Maydell reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo); 8597866508SPeter Maydell reply->TerminationCount = cpu_to_le32(reply->TerminationCount); 86e351b826SPaolo Bonzini } 87e351b826SPaolo Bonzini mptsas_fix_ioc_init_endianness(MPIMsgIOCInit * req)88e351b826SPaolo Bonzinivoid mptsas_fix_ioc_init_endianness(MPIMsgIOCInit *req) 89e351b826SPaolo Bonzini { 9097866508SPeter Maydell req->MsgContext = le32_to_cpu(req->MsgContext); 9197866508SPeter Maydell req->ReplyFrameSize = le16_to_cpu(req->ReplyFrameSize); 9297866508SPeter Maydell req->HostMfaHighAddr = le32_to_cpu(req->HostMfaHighAddr); 9397866508SPeter Maydell req->SenseBufferHighAddr = le32_to_cpu(req->SenseBufferHighAddr); 9497866508SPeter Maydell req->ReplyFifoHostSignalingAddr = 9597866508SPeter Maydell le32_to_cpu(req->ReplyFifoHostSignalingAddr); 96e351b826SPaolo Bonzini mptsas_fix_sgentry_endianness(&req->HostPageBufferSGE); 9797866508SPeter Maydell req->MsgVersion = le16_to_cpu(req->MsgVersion); 9897866508SPeter Maydell req->HeaderVersion = le16_to_cpu(req->HeaderVersion); 99e351b826SPaolo Bonzini } 100e351b826SPaolo Bonzini mptsas_fix_ioc_init_reply_endianness(MPIMsgIOCInitReply * reply)101e351b826SPaolo Bonzinivoid mptsas_fix_ioc_init_reply_endianness(MPIMsgIOCInitReply *reply) 102e351b826SPaolo Bonzini { 10397866508SPeter Maydell reply->MsgContext = cpu_to_le32(reply->MsgContext); 10497866508SPeter Maydell reply->IOCStatus = cpu_to_le16(reply->IOCStatus); 10597866508SPeter Maydell reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo); 106e351b826SPaolo Bonzini } 107e351b826SPaolo Bonzini mptsas_fix_ioc_facts_endianness(MPIMsgIOCFacts * req)108e351b826SPaolo Bonzinivoid mptsas_fix_ioc_facts_endianness(MPIMsgIOCFacts *req) 109e351b826SPaolo Bonzini { 11097866508SPeter Maydell req->MsgContext = le32_to_cpu(req->MsgContext); 111e351b826SPaolo Bonzini } 112e351b826SPaolo Bonzini mptsas_fix_ioc_facts_reply_endianness(MPIMsgIOCFactsReply * reply)113e351b826SPaolo Bonzinivoid mptsas_fix_ioc_facts_reply_endianness(MPIMsgIOCFactsReply *reply) 114e351b826SPaolo Bonzini { 11597866508SPeter Maydell reply->MsgVersion = cpu_to_le16(reply->MsgVersion); 11697866508SPeter Maydell reply->HeaderVersion = cpu_to_le16(reply->HeaderVersion); 11797866508SPeter Maydell reply->MsgContext = cpu_to_le32(reply->MsgContext); 11897866508SPeter Maydell reply->IOCExceptions = cpu_to_le16(reply->IOCExceptions); 11997866508SPeter Maydell reply->IOCStatus = cpu_to_le16(reply->IOCStatus); 12097866508SPeter Maydell reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo); 12197866508SPeter Maydell reply->ReplyQueueDepth = cpu_to_le16(reply->ReplyQueueDepth); 12297866508SPeter Maydell reply->RequestFrameSize = cpu_to_le16(reply->RequestFrameSize); 12397866508SPeter Maydell reply->ProductID = cpu_to_le16(reply->ProductID); 12497866508SPeter Maydell reply->CurrentHostMfaHighAddr = cpu_to_le32(reply->CurrentHostMfaHighAddr); 12597866508SPeter Maydell reply->GlobalCredits = cpu_to_le16(reply->GlobalCredits); 12697866508SPeter Maydell reply->CurrentSenseBufferHighAddr = 12797866508SPeter Maydell cpu_to_le32(reply->CurrentSenseBufferHighAddr); 12897866508SPeter Maydell reply->CurReplyFrameSize = cpu_to_le16(reply->CurReplyFrameSize); 12997866508SPeter Maydell reply->FWImageSize = cpu_to_le32(reply->FWImageSize); 13097866508SPeter Maydell reply->IOCCapabilities = cpu_to_le32(reply->IOCCapabilities); 13197866508SPeter Maydell reply->HighPriorityQueueDepth = cpu_to_le16(reply->HighPriorityQueueDepth); 132e351b826SPaolo Bonzini mptsas_fix_sgentry_endianness_reply(&reply->HostPageBufferSGE); 13397866508SPeter Maydell reply->ReplyFifoHostSignalingAddr = 13497866508SPeter Maydell cpu_to_le32(reply->ReplyFifoHostSignalingAddr); 135e351b826SPaolo Bonzini } 136e351b826SPaolo Bonzini mptsas_fix_config_endianness(MPIMsgConfig * req)137e351b826SPaolo Bonzinivoid mptsas_fix_config_endianness(MPIMsgConfig *req) 138e351b826SPaolo Bonzini { 13997866508SPeter Maydell req->ExtPageLength = le16_to_cpu(req->ExtPageLength); 14097866508SPeter Maydell req->MsgContext = le32_to_cpu(req->MsgContext); 14197866508SPeter Maydell req->PageAddress = le32_to_cpu(req->PageAddress); 142e351b826SPaolo Bonzini mptsas_fix_sgentry_endianness(&req->PageBufferSGE); 143e351b826SPaolo Bonzini } 144e351b826SPaolo Bonzini mptsas_fix_config_reply_endianness(MPIMsgConfigReply * reply)145e351b826SPaolo Bonzinivoid mptsas_fix_config_reply_endianness(MPIMsgConfigReply *reply) 146e351b826SPaolo Bonzini { 14797866508SPeter Maydell reply->ExtPageLength = cpu_to_le16(reply->ExtPageLength); 14897866508SPeter Maydell reply->MsgContext = cpu_to_le32(reply->MsgContext); 14997866508SPeter Maydell reply->IOCStatus = cpu_to_le16(reply->IOCStatus); 15097866508SPeter Maydell reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo); 151e351b826SPaolo Bonzini } 152e351b826SPaolo Bonzini mptsas_fix_port_facts_endianness(MPIMsgPortFacts * req)153e351b826SPaolo Bonzinivoid mptsas_fix_port_facts_endianness(MPIMsgPortFacts *req) 154e351b826SPaolo Bonzini { 15597866508SPeter Maydell req->MsgContext = le32_to_cpu(req->MsgContext); 156e351b826SPaolo Bonzini } 157e351b826SPaolo Bonzini mptsas_fix_port_facts_reply_endianness(MPIMsgPortFactsReply * reply)158e351b826SPaolo Bonzinivoid mptsas_fix_port_facts_reply_endianness(MPIMsgPortFactsReply *reply) 159e351b826SPaolo Bonzini { 16097866508SPeter Maydell reply->MsgContext = cpu_to_le32(reply->MsgContext); 16197866508SPeter Maydell reply->IOCStatus = cpu_to_le16(reply->IOCStatus); 16297866508SPeter Maydell reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo); 16397866508SPeter Maydell reply->MaxDevices = cpu_to_le16(reply->MaxDevices); 16497866508SPeter Maydell reply->PortSCSIID = cpu_to_le16(reply->PortSCSIID); 16597866508SPeter Maydell reply->ProtocolFlags = cpu_to_le16(reply->ProtocolFlags); 16697866508SPeter Maydell reply->MaxPostedCmdBuffers = cpu_to_le16(reply->MaxPostedCmdBuffers); 16797866508SPeter Maydell reply->MaxPersistentIDs = cpu_to_le16(reply->MaxPersistentIDs); 16897866508SPeter Maydell reply->MaxLanBuckets = cpu_to_le16(reply->MaxLanBuckets); 169e351b826SPaolo Bonzini } 170e351b826SPaolo Bonzini mptsas_fix_port_enable_endianness(MPIMsgPortEnable * req)171e351b826SPaolo Bonzinivoid mptsas_fix_port_enable_endianness(MPIMsgPortEnable *req) 172e351b826SPaolo Bonzini { 17397866508SPeter Maydell req->MsgContext = le32_to_cpu(req->MsgContext); 174e351b826SPaolo Bonzini } 175e351b826SPaolo Bonzini mptsas_fix_port_enable_reply_endianness(MPIMsgPortEnableReply * reply)176e351b826SPaolo Bonzinivoid mptsas_fix_port_enable_reply_endianness(MPIMsgPortEnableReply *reply) 177e351b826SPaolo Bonzini { 17897866508SPeter Maydell reply->MsgContext = cpu_to_le32(reply->MsgContext); 17997866508SPeter Maydell reply->IOCStatus = cpu_to_le16(reply->IOCStatus); 18097866508SPeter Maydell reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo); 181e351b826SPaolo Bonzini } 182e351b826SPaolo Bonzini mptsas_fix_event_notification_endianness(MPIMsgEventNotify * req)183e351b826SPaolo Bonzinivoid mptsas_fix_event_notification_endianness(MPIMsgEventNotify *req) 184e351b826SPaolo Bonzini { 18597866508SPeter Maydell req->MsgContext = le32_to_cpu(req->MsgContext); 186e351b826SPaolo Bonzini } 187e351b826SPaolo Bonzini mptsas_fix_event_notification_reply_endianness(MPIMsgEventNotifyReply * reply)188e351b826SPaolo Bonzinivoid mptsas_fix_event_notification_reply_endianness(MPIMsgEventNotifyReply *reply) 189e351b826SPaolo Bonzini { 190e351b826SPaolo Bonzini int length = reply->EventDataLength; 191e351b826SPaolo Bonzini int i; 192e351b826SPaolo Bonzini 19397866508SPeter Maydell reply->EventDataLength = cpu_to_le16(reply->EventDataLength); 19497866508SPeter Maydell reply->MsgContext = cpu_to_le32(reply->MsgContext); 19597866508SPeter Maydell reply->IOCStatus = cpu_to_le16(reply->IOCStatus); 19697866508SPeter Maydell reply->IOCLogInfo = cpu_to_le32(reply->IOCLogInfo); 19797866508SPeter Maydell reply->Event = cpu_to_le32(reply->Event); 19897866508SPeter Maydell reply->EventContext = cpu_to_le32(reply->EventContext); 199e351b826SPaolo Bonzini 200e351b826SPaolo Bonzini /* Really depends on the event kind. This will do for now. */ 201e351b826SPaolo Bonzini for (i = 0; i < length; i++) { 20297866508SPeter Maydell reply->Data[i] = cpu_to_le32(reply->Data[i]); 203e351b826SPaolo Bonzini } 204e351b826SPaolo Bonzini } 205e351b826SPaolo Bonzini 206