qemu/hw/scsi/mptendian.c
<<
>>
Prefs
   1/*
   2 * QEMU LSI SAS1068 Host Bus Adapter emulation
   3 * Endianness conversion for MPI data structures
   4 *
   5 * Copyright (c) 2016 Red Hat, Inc.
   6 *
   7 * Authors: Paolo Bonzini <pbonzini@redhat.com>
   8 *
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation; either
  12 * version 2 of the License, or (at your option) any later version.
  13 *
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  21 */
  22
  23#include "qemu/osdep.h"
  24#include "hw/hw.h"
  25#include "hw/pci/pci.h"
  26#include "sysemu/dma.h"
  27#include "hw/pci/msi.h"
  28#include "qemu/iov.h"
  29#include "hw/scsi/scsi.h"
  30#include "scsi/constants.h"
  31#include "trace.h"
  32
  33#include "mptsas.h"
  34#include "mpi.h"
  35
  36static void mptsas_fix_sgentry_endianness(MPISGEntry *sge)
  37{
  38    le32_to_cpus(&sge->FlagsLength);
  39    if (sge->FlagsLength & MPI_SGE_FLAGS_64_BIT_ADDRESSING) {
  40       le64_to_cpus(&sge->u.Address64);
  41    } else {
  42       le32_to_cpus(&sge->u.Address32);
  43    }
  44}
  45
  46static void mptsas_fix_sgentry_endianness_reply(MPISGEntry *sge)
  47{
  48    if (sge->FlagsLength & MPI_SGE_FLAGS_64_BIT_ADDRESSING) {
  49       cpu_to_le64s(&sge->u.Address64);
  50    } else {
  51       cpu_to_le32s(&sge->u.Address32);
  52    }
  53    cpu_to_le32s(&sge->FlagsLength);
  54}
  55
  56void mptsas_fix_scsi_io_endianness(MPIMsgSCSIIORequest *req)
  57{
  58    le32_to_cpus(&req->MsgContext);
  59    le32_to_cpus(&req->Control);
  60    le32_to_cpus(&req->DataLength);
  61    le32_to_cpus(&req->SenseBufferLowAddr);
  62}
  63
  64void mptsas_fix_scsi_io_reply_endianness(MPIMsgSCSIIOReply *reply)
  65{
  66    cpu_to_le32s(&reply->MsgContext);
  67    cpu_to_le16s(&reply->IOCStatus);
  68    cpu_to_le32s(&reply->IOCLogInfo);
  69    cpu_to_le32s(&reply->TransferCount);
  70    cpu_to_le32s(&reply->SenseCount);
  71    cpu_to_le32s(&reply->ResponseInfo);
  72    cpu_to_le16s(&reply->TaskTag);
  73}
  74
  75void mptsas_fix_scsi_task_mgmt_endianness(MPIMsgSCSITaskMgmt *req)
  76{
  77    le32_to_cpus(&req->MsgContext);
  78    le32_to_cpus(&req->TaskMsgContext);
  79}
  80
  81void mptsas_fix_scsi_task_mgmt_reply_endianness(MPIMsgSCSITaskMgmtReply *reply)
  82{
  83    cpu_to_le32s(&reply->MsgContext);
  84    cpu_to_le16s(&reply->IOCStatus);
  85    cpu_to_le32s(&reply->IOCLogInfo);
  86    cpu_to_le32s(&reply->TerminationCount);
  87}
  88
  89void mptsas_fix_ioc_init_endianness(MPIMsgIOCInit *req)
  90{
  91    le32_to_cpus(&req->MsgContext);
  92    le16_to_cpus(&req->ReplyFrameSize);
  93    le32_to_cpus(&req->HostMfaHighAddr);
  94    le32_to_cpus(&req->SenseBufferHighAddr);
  95    le32_to_cpus(&req->ReplyFifoHostSignalingAddr);
  96    mptsas_fix_sgentry_endianness(&req->HostPageBufferSGE);
  97    le16_to_cpus(&req->MsgVersion);
  98    le16_to_cpus(&req->HeaderVersion);
  99}
 100
 101void mptsas_fix_ioc_init_reply_endianness(MPIMsgIOCInitReply *reply)
 102{
 103    cpu_to_le32s(&reply->MsgContext);
 104    cpu_to_le16s(&reply->IOCStatus);
 105    cpu_to_le32s(&reply->IOCLogInfo);
 106}
 107
 108void mptsas_fix_ioc_facts_endianness(MPIMsgIOCFacts *req)
 109{
 110    le32_to_cpus(&req->MsgContext);
 111}
 112
 113void mptsas_fix_ioc_facts_reply_endianness(MPIMsgIOCFactsReply *reply)
 114{
 115    cpu_to_le16s(&reply->MsgVersion);
 116    cpu_to_le16s(&reply->HeaderVersion);
 117    cpu_to_le32s(&reply->MsgContext);
 118    cpu_to_le16s(&reply->IOCExceptions);
 119    cpu_to_le16s(&reply->IOCStatus);
 120    cpu_to_le32s(&reply->IOCLogInfo);
 121    cpu_to_le16s(&reply->ReplyQueueDepth);
 122    cpu_to_le16s(&reply->RequestFrameSize);
 123    cpu_to_le16s(&reply->ProductID);
 124    cpu_to_le32s(&reply->CurrentHostMfaHighAddr);
 125    cpu_to_le16s(&reply->GlobalCredits);
 126    cpu_to_le32s(&reply->CurrentSenseBufferHighAddr);
 127    cpu_to_le16s(&reply->CurReplyFrameSize);
 128    cpu_to_le32s(&reply->FWImageSize);
 129    cpu_to_le32s(&reply->IOCCapabilities);
 130    cpu_to_le16s(&reply->HighPriorityQueueDepth);
 131    mptsas_fix_sgentry_endianness_reply(&reply->HostPageBufferSGE);
 132    cpu_to_le32s(&reply->ReplyFifoHostSignalingAddr);
 133}
 134
 135void mptsas_fix_config_endianness(MPIMsgConfig *req)
 136{
 137    le16_to_cpus(&req->ExtPageLength);
 138    le32_to_cpus(&req->MsgContext);
 139    le32_to_cpus(&req->PageAddress);
 140    mptsas_fix_sgentry_endianness(&req->PageBufferSGE);
 141}
 142
 143void mptsas_fix_config_reply_endianness(MPIMsgConfigReply *reply)
 144{
 145    cpu_to_le16s(&reply->ExtPageLength);
 146    cpu_to_le32s(&reply->MsgContext);
 147    cpu_to_le16s(&reply->IOCStatus);
 148    cpu_to_le32s(&reply->IOCLogInfo);
 149}
 150
 151void mptsas_fix_port_facts_endianness(MPIMsgPortFacts *req)
 152{
 153    le32_to_cpus(&req->MsgContext);
 154}
 155
 156void mptsas_fix_port_facts_reply_endianness(MPIMsgPortFactsReply *reply)
 157{
 158    cpu_to_le32s(&reply->MsgContext);
 159    cpu_to_le16s(&reply->IOCStatus);
 160    cpu_to_le32s(&reply->IOCLogInfo);
 161    cpu_to_le16s(&reply->MaxDevices);
 162    cpu_to_le16s(&reply->PortSCSIID);
 163    cpu_to_le16s(&reply->ProtocolFlags);
 164    cpu_to_le16s(&reply->MaxPostedCmdBuffers);
 165    cpu_to_le16s(&reply->MaxPersistentIDs);
 166    cpu_to_le16s(&reply->MaxLanBuckets);
 167}
 168
 169void mptsas_fix_port_enable_endianness(MPIMsgPortEnable *req)
 170{
 171    le32_to_cpus(&req->MsgContext);
 172}
 173
 174void mptsas_fix_port_enable_reply_endianness(MPIMsgPortEnableReply *reply)
 175{
 176    cpu_to_le32s(&reply->MsgContext);
 177    cpu_to_le16s(&reply->IOCStatus);
 178    cpu_to_le32s(&reply->IOCLogInfo);
 179}
 180
 181void mptsas_fix_event_notification_endianness(MPIMsgEventNotify *req)
 182{
 183    le32_to_cpus(&req->MsgContext);
 184}
 185
 186void mptsas_fix_event_notification_reply_endianness(MPIMsgEventNotifyReply *reply)
 187{
 188    int length = reply->EventDataLength;
 189    int i;
 190
 191    cpu_to_le16s(&reply->EventDataLength);
 192    cpu_to_le32s(&reply->MsgContext);
 193    cpu_to_le16s(&reply->IOCStatus);
 194    cpu_to_le32s(&reply->IOCLogInfo);
 195    cpu_to_le32s(&reply->Event);
 196    cpu_to_le32s(&reply->EventContext);
 197
 198    /* Really depends on the event kind.  This will do for now.  */
 199    for (i = 0; i < length; i++) {
 200        cpu_to_le32s(&reply->Data[i]);
 201    }
 202}
 203
 204