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 "sysemu/block-backend.h"
  28#include "hw/pci/msi.h"
  29#include "qemu/iov.h"
  30#include "hw/scsi/scsi.h"
  31#include "block/scsi.h"
  32#include "trace.h"
  33
  34#include "mptsas.h"
  35#include "mpi.h"
  36
  37static void mptsas_fix_sgentry_endianness(MPISGEntry *sge)
  38{
  39    le32_to_cpus(&sge->FlagsLength);
  40    if (sge->FlagsLength & MPI_SGE_FLAGS_64_BIT_ADDRESSING) {
  41       le64_to_cpus(&sge->u.Address64);
  42    } else {
  43       le32_to_cpus(&sge->u.Address32);
  44    }
  45}
  46
  47static void mptsas_fix_sgentry_endianness_reply(MPISGEntry *sge)
  48{
  49    if (sge->FlagsLength & MPI_SGE_FLAGS_64_BIT_ADDRESSING) {
  50       cpu_to_le64s(&sge->u.Address64);
  51    } else {
  52       cpu_to_le32s(&sge->u.Address32);
  53    }
  54    cpu_to_le32s(&sge->FlagsLength);
  55}
  56
  57void mptsas_fix_scsi_io_endianness(MPIMsgSCSIIORequest *req)
  58{
  59    le32_to_cpus(&req->MsgContext);
  60    le32_to_cpus(&req->Control);
  61    le32_to_cpus(&req->DataLength);
  62    le32_to_cpus(&req->SenseBufferLowAddr);
  63}
  64
  65void mptsas_fix_scsi_io_reply_endianness(MPIMsgSCSIIOReply *reply)
  66{
  67    cpu_to_le32s(&reply->MsgContext);
  68    cpu_to_le16s(&reply->IOCStatus);
  69    cpu_to_le32s(&reply->IOCLogInfo);
  70    cpu_to_le32s(&reply->TransferCount);
  71    cpu_to_le32s(&reply->SenseCount);
  72    cpu_to_le32s(&reply->ResponseInfo);
  73    cpu_to_le16s(&reply->TaskTag);
  74}
  75
  76void mptsas_fix_scsi_task_mgmt_endianness(MPIMsgSCSITaskMgmt *req)
  77{
  78    le32_to_cpus(&req->MsgContext);
  79    le32_to_cpus(&req->TaskMsgContext);
  80}
  81
  82void mptsas_fix_scsi_task_mgmt_reply_endianness(MPIMsgSCSITaskMgmtReply *reply)
  83{
  84    cpu_to_le32s(&reply->MsgContext);
  85    cpu_to_le16s(&reply->IOCStatus);
  86    cpu_to_le32s(&reply->IOCLogInfo);
  87    cpu_to_le32s(&reply->TerminationCount);
  88}
  89
  90void mptsas_fix_ioc_init_endianness(MPIMsgIOCInit *req)
  91{
  92    le32_to_cpus(&req->MsgContext);
  93    le16_to_cpus(&req->ReplyFrameSize);
  94    le32_to_cpus(&req->HostMfaHighAddr);
  95    le32_to_cpus(&req->SenseBufferHighAddr);
  96    le32_to_cpus(&req->ReplyFifoHostSignalingAddr);
  97    mptsas_fix_sgentry_endianness(&req->HostPageBufferSGE);
  98    le16_to_cpus(&req->MsgVersion);
  99    le16_to_cpus(&req->HeaderVersion);
 100}
 101
 102void mptsas_fix_ioc_init_reply_endianness(MPIMsgIOCInitReply *reply)
 103{
 104    cpu_to_le32s(&reply->MsgContext);
 105    cpu_to_le16s(&reply->IOCStatus);
 106    cpu_to_le32s(&reply->IOCLogInfo);
 107}
 108
 109void mptsas_fix_ioc_facts_endianness(MPIMsgIOCFacts *req)
 110{
 111    le32_to_cpus(&req->MsgContext);
 112}
 113
 114void mptsas_fix_ioc_facts_reply_endianness(MPIMsgIOCFactsReply *reply)
 115{
 116    cpu_to_le16s(&reply->MsgVersion);
 117    cpu_to_le16s(&reply->HeaderVersion);
 118    cpu_to_le32s(&reply->MsgContext);
 119    cpu_to_le16s(&reply->IOCExceptions);
 120    cpu_to_le16s(&reply->IOCStatus);
 121    cpu_to_le32s(&reply->IOCLogInfo);
 122    cpu_to_le16s(&reply->ReplyQueueDepth);
 123    cpu_to_le16s(&reply->RequestFrameSize);
 124    cpu_to_le16s(&reply->ProductID);
 125    cpu_to_le32s(&reply->CurrentHostMfaHighAddr);
 126    cpu_to_le16s(&reply->GlobalCredits);
 127    cpu_to_le32s(&reply->CurrentSenseBufferHighAddr);
 128    cpu_to_le16s(&reply->CurReplyFrameSize);
 129    cpu_to_le32s(&reply->FWImageSize);
 130    cpu_to_le32s(&reply->IOCCapabilities);
 131    cpu_to_le16s(&reply->HighPriorityQueueDepth);
 132    mptsas_fix_sgentry_endianness_reply(&reply->HostPageBufferSGE);
 133    cpu_to_le32s(&reply->ReplyFifoHostSignalingAddr);
 134}
 135
 136void mptsas_fix_config_endianness(MPIMsgConfig *req)
 137{
 138    le16_to_cpus(&req->ExtPageLength);
 139    le32_to_cpus(&req->MsgContext);
 140    le32_to_cpus(&req->PageAddress);
 141    mptsas_fix_sgentry_endianness(&req->PageBufferSGE);
 142}
 143
 144void mptsas_fix_config_reply_endianness(MPIMsgConfigReply *reply)
 145{
 146    cpu_to_le16s(&reply->ExtPageLength);
 147    cpu_to_le32s(&reply->MsgContext);
 148    cpu_to_le16s(&reply->IOCStatus);
 149    cpu_to_le32s(&reply->IOCLogInfo);
 150}
 151
 152void mptsas_fix_port_facts_endianness(MPIMsgPortFacts *req)
 153{
 154    le32_to_cpus(&req->MsgContext);
 155}
 156
 157void mptsas_fix_port_facts_reply_endianness(MPIMsgPortFactsReply *reply)
 158{
 159    cpu_to_le32s(&reply->MsgContext);
 160    cpu_to_le16s(&reply->IOCStatus);
 161    cpu_to_le32s(&reply->IOCLogInfo);
 162    cpu_to_le16s(&reply->MaxDevices);
 163    cpu_to_le16s(&reply->PortSCSIID);
 164    cpu_to_le16s(&reply->ProtocolFlags);
 165    cpu_to_le16s(&reply->MaxPostedCmdBuffers);
 166    cpu_to_le16s(&reply->MaxPersistentIDs);
 167    cpu_to_le16s(&reply->MaxLanBuckets);
 168}
 169
 170void mptsas_fix_port_enable_endianness(MPIMsgPortEnable *req)
 171{
 172    le32_to_cpus(&req->MsgContext);
 173}
 174
 175void mptsas_fix_port_enable_reply_endianness(MPIMsgPortEnableReply *reply)
 176{
 177    cpu_to_le32s(&reply->MsgContext);
 178    cpu_to_le16s(&reply->IOCStatus);
 179    cpu_to_le32s(&reply->IOCLogInfo);
 180}
 181
 182void mptsas_fix_event_notification_endianness(MPIMsgEventNotify *req)
 183{
 184    le32_to_cpus(&req->MsgContext);
 185}
 186
 187void mptsas_fix_event_notification_reply_endianness(MPIMsgEventNotifyReply *reply)
 188{
 189    int length = reply->EventDataLength;
 190    int i;
 191
 192    cpu_to_le16s(&reply->EventDataLength);
 193    cpu_to_le32s(&reply->MsgContext);
 194    cpu_to_le16s(&reply->IOCStatus);
 195    cpu_to_le32s(&reply->IOCLogInfo);
 196    cpu_to_le32s(&reply->Event);
 197    cpu_to_le32s(&reply->EventContext);
 198
 199    /* Really depends on the event kind.  This will do for now.  */
 200    for (i = 0; i < length; i++) {
 201        cpu_to_le32s(&reply->Data[i]);
 202    }
 203}
 204
 205