/*
* QEMU LSI SAS1068 Host Bus Adapter emulation
* Based on the QEMU Megaraid emulator
*
* Copyright (c) 2009-2012 Hannes Reinecke, SUSE Labs
* Copyright (c) 2012 Verizon, Inc.
* Copyright (c) 2016 Red Hat, Inc.
*
* Authors: Don Slutz, Paolo Bonzini
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see .
*/
#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/pci/pci.h"
#include "sysemu/dma.h"
#include "sysemu/block-backend.h"
#include "hw/pci/msi.h"
#include "qemu/iov.h"
#include "hw/scsi/scsi.h"
#include "block/scsi.h"
#include "trace.h"
#include "mptsas.h"
#include "mpi.h"
#define NAA_LOCALLY_ASSIGNED_ID 0x3ULL
#define IEEE_COMPANY_LOCALLY_ASSIGNED 0x525400
#define TYPE_MPTSAS1068 "mptsas1068"
#define MPT_SAS(obj) \
OBJECT_CHECK(MPTSASState, (obj), TYPE_MPTSAS1068)
#define MPTSAS1068_PRODUCT_ID \
(MPI_FW_HEADER_PID_FAMILY_1068_SAS | \
MPI_FW_HEADER_PID_PROD_INITIATOR_SCSI | \
MPI_FW_HEADER_PID_TYPE_SAS)
struct MPTSASRequest {
MPIMsgSCSIIORequest scsi_io;
SCSIRequest *sreq;
QEMUSGList qsg;
MPTSASState *dev;
QTAILQ_ENTRY(MPTSASRequest) next;
};
static void mptsas_update_interrupt(MPTSASState *s)
{
PCIDevice *pci = (PCIDevice *) s;
uint32_t state = s->intr_status & ~(s->intr_mask | MPI_HIS_IOP_DOORBELL_STATUS);
if (s->msi_in_use && msi_enabled(pci)) {
if (state) {
trace_mptsas_irq_msi(s);
msi_notify(pci, 0);
}
}
trace_mptsas_irq_intx(s, !!state);
pci_set_irq(pci, !!state);
}
static void mptsas_set_fault(MPTSASState *s, uint32_t code)
{
if ((s->state & MPI_IOC_STATE_FAULT) == 0) {
s->state = MPI_IOC_STATE_FAULT | code;
}
}
#define MPTSAS_FIFO_INVALID(s, name) \
((s)->name##_head > ARRAY_SIZE((s)->name) || \
(s)->name##_tail > ARRAY_SIZE((s)->name))
#define MPTSAS_FIFO_EMPTY(s, name) \
((s)->name##_head == (s)->name##_tail)
#define MPTSAS_FIFO_FULL(s, name) \
((s)->name##_head == ((s)->name##_tail + 1) % ARRAY_SIZE((s)->name))
#define MPTSAS_FIFO_GET(s, name) ({ \
uint32_t _val = (s)->name[(s)->name##_head++]; \
(s)->name##_head %= ARRAY_SIZE((s)->name); \
_val; \
})
#define MPTSAS_FIFO_PUT(s, name, val) do { \
(s)->name[(s)->name##_tail++] = (val); \
(s)->name##_tail %= ARRAY_SIZE((s)->name); \
} while(0)
static void mptsas_post_reply(MPTSASState *s, MPIDefaultReply *reply)
{
PCIDevice *pci = (PCIDevice *) s;
uint32_t addr_lo;
if (MPTSAS_FIFO_EMPTY(s, reply_free) || MPTSAS_FIFO_FULL(s, reply_post)) {
mptsas_set_fault(s, MPI_IOCSTATUS_INSUFFICIENT_RESOURCES);
return;
}
addr_lo = MPTSAS_FIFO_GET(s, reply_free);
pci_dma_write(pci, addr_lo | s->host_mfa_high_addr, reply,
MIN(s->reply_frame_size, 4 * reply->MsgLength));
MPTSAS_FIFO_PUT(s, reply_post, MPI_ADDRESS_REPLY_A_BIT | (addr_lo >> 1));
s->intr_status |= MPI_HIS_REPLY_MESSAGE_INTERRUPT;
if (s->doorbell_state == DOORBELL_WRITE) {
s->doorbell_state = DOORBELL_NONE;
s->intr_status |= MPI_HIS_DOORBELL_INTERRUPT;
}
mptsas_update_interrupt(s);
}
void mptsas_reply(MPTSASState *s, MPIDefaultReply *reply)
{
if (s->doorbell_state == DOORBELL_WRITE) {
/* The reply is sent out in 16 bit chunks, while the size
* in the reply is in 32 bit units.
*/
s->doorbell_sta
Copyright 2015 Open Platform for NFV Project, Inc. and its contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.