2 * QEMU LSI SAS1068 Host Bus Adapter emulation
3 * Based on the QEMU Megaraid emulator
5 * Copyright (c) 2009-2012 Hannes Reinecke, SUSE Labs
6 * Copyright (c) 2012 Verizon, Inc.
7 * Copyright (c) 2016 Red Hat, Inc.
9 * Authors: Don Slutz, Paolo Bonzini
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include "qemu/osdep.h"
26 #include "hw/pci/pci.h"
27 #include "hw/qdev-properties.h"
28 #include "sysemu/dma.h"
29 #include "hw/pci/msi.h"
31 #include "qemu/main-loop.h"
32 #include "qemu/module.h"
33 #include "hw/scsi/scsi.h"
34 #include "scsi/constants.h"
36 #include "qapi/error.h"
38 #include "migration/qemu-file-types.h"
39 #include "migration/vmstate.h"
42 #define NAA_LOCALLY_ASSIGNED_ID 0x3ULL
43 #define IEEE_COMPANY_LOCALLY_ASSIGNED 0x525400
45 #define MPTSAS1068_PRODUCT_ID \
46 (MPI_FW_HEADER_PID_FAMILY_1068_SAS | \
47 MPI_FW_HEADER_PID_PROD_INITIATOR_SCSI | \
48 MPI_FW_HEADER_PID_TYPE_SAS)
50 struct MPTSASRequest
{
51 MPIMsgSCSIIORequest scsi_io
;
56 QTAILQ_ENTRY(MPTSASRequest
) next
;
59 static void mptsas_update_interrupt(MPTSASState
*s
)
61 PCIDevice
*pci
= (PCIDevice
*) s
;
62 uint32_t state
= s
->intr_status
& ~(s
->intr_mask
| MPI_HIS_IOP_DOORBELL_STATUS
);
64 if (msi_enabled(pci
)) {
66 trace_mptsas_irq_msi(s
);
71 trace_mptsas_irq_intx(s
, !!state
);
72 pci_set_irq(pci
, !!state
);
75 static void mptsas_set_fault(MPTSASState
*s
, uint32_t code
)
77 if ((s
->state
& MPI_IOC_STATE_FAULT
) == 0) {
78 s
->state
= MPI_IOC_STATE_FAULT
| code
;
82 #define MPTSAS_FIFO_INVALID(s, name) \
83 ((s)->name##_head > ARRAY_SIZE((s)->name) || \
84 (s)->name##_tail > ARRAY_SIZE((s)->name))
86 #define MPTSAS_FIFO_EMPTY(s, name) \
87 ((s)->name##_head == (s)->name##_tail)
89 #define MPTSAS_FIFO_FULL(s, name) \
90 ((s)->name##_head == ((s)->name##_tail + 1) % ARRAY_SIZE((s)->name))
92 #define MPTSAS_FIFO_GET(s, name) ({ \
93 uint32_t _val = (s)->name[(s)->name##_head++]; \
94 (s)->name##_head %= ARRAY_SIZE((s)->name); \
98 #define MPTSAS_FIFO_PUT(s, name, val) do { \
99 (s)->name[(s)->name##_tail++] = (val); \
100 (s)->name##_tail %= ARRAY_SIZE((s)->name); \
103 static void mptsas_post_reply(MPTSASState
*s
, MPIDefaultReply
*reply
)
105 PCIDevice
*pci
= (PCIDevice
*) s
;
108 if (MPTSAS_FIFO_EMPTY(s
, reply_free
) || MPTSAS_FIFO_FULL(s
, reply_post
)) {
109 mptsas_set_fault(s
, MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
);
113 addr_lo
= MPTSAS_FIFO_GET(s
, reply_free
);
115 pci_dma_write(pci
, addr_lo
| s
->host_mfa_high_addr
, reply
,
116 MIN(s
->reply_frame_size
, 4 * reply
->MsgLength
));
118 MPTSAS_FIFO_PUT(s
, reply_post
, MPI_ADDRESS_REPLY_A_BIT
| (addr_lo
>> 1));
120 s
->intr_status
|= MPI_HIS_REPLY_MESSAGE_INTERRUPT
;
121 if (s
->doorbell_state
== DOORBELL_WRITE
) {
122 s
->doorbell_state
= DOORBELL_NONE
;
123 s
->intr_status
|= MPI_HIS_DOORBELL_INTERRUPT
;
125 mptsas_update_interrupt(s
);
128 void mptsas_reply(MPTSASState
*s
, MPIDefaultReply
*reply
)
130 if (s
->doorbell_state
== DOORBELL_WRITE
) {
131 /* The reply is sent out in 16 bit chunks, while the size
132 * in the reply is in 32 bit units.
134 s
->doorbell_state
= DOORBELL_READ
;
135 s
->doorbell_reply_idx
= 0;
136 s
->doorbell_reply_size
= reply
->MsgLength
* 2;
137 memcpy(s
->doorbell_reply
, reply
, s
->doorbell_reply_size
* 2);
138 s
->intr_status
|= MPI_HIS_DOORBELL_INTERRUPT
;
139 mptsas_update_interrupt(s
);
141 mptsas_post_reply(s
, reply
);
145 static void mptsas_turbo_reply(MPTSASState
*s
, uint32_t msgctx
)
147 if (MPTSAS_FIFO_FULL(s
, reply_post
)) {
148 mptsas_set_fault(s
, MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
);
152 /* The reply is just the message context ID (bit 31 = clear). */
153 MPTSAS_FIFO_PUT(s
, reply_post
, msgctx
);
155 s
->intr_status
|= MPI_HIS_REPLY_MESSAGE_INTERRUPT
;
156 mptsas_update_interrupt(s
);
159 #define MPTSAS_MAX_REQUEST_SIZE 52
161 static const int mpi_request_sizes
[] = {
162 [MPI_FUNCTION_SCSI_IO_REQUEST
] = sizeof(MPIMsgSCSIIORequest
),
163 [MPI_FUNCTION_SCSI_TASK_MGMT
] = sizeof(MPIMsgSCSITaskMgmt
),
164 [MPI_FUNCTION_IOC_INIT
] = sizeof(MPIMsgIOCInit
),
165 [MPI_FUNCTION_IOC_FACTS
] = sizeof(MPIMsgIOCFacts
),
166 [MPI_FUNCTION_CONFIG
] = sizeof(MPIMsgConfig
),
167 [MPI_FUNCTION_PORT_FACTS
] = sizeof(MPIMsgPortFacts
),
168 [MPI_FUNCTION_PORT_ENABLE
] = sizeof(MPIMsgPortEnable
),
169 [MPI_FUNCTION_EVENT_NOTIFICATION
] = sizeof(MPIMsgEventNotify
),
172 static dma_addr_t
mptsas_ld_sg_base(MPTSASState
*s
, uint32_t flags_and_length
,
175 PCIDevice
*pci
= (PCIDevice
*) s
;
178 if (flags_and_length
& MPI_SGE_FLAGS_64_BIT_ADDRESSING
) {
179 addr
= ldq_le_pci_dma(pci
, *sgaddr
+ 4);
182 addr
= ldl_le_pci_dma(pci
, *sgaddr
+ 4);
188 static int mptsas_build_sgl(MPTSASState
*s
, MPTSASRequest
*req
, hwaddr addr
)
190 PCIDevice
*pci
= (PCIDevice
*) s
;
191 hwaddr next_chain_addr
;
194 uint32_t chain_offset
;
196 chain_offset
= req
->scsi_io
.ChainOffset
;
197 next_chain_addr
= addr
+ chain_offset
* sizeof(uint32_t);
198 sgaddr
= addr
+ sizeof(MPIMsgSCSIIORequest
);
199 pci_dma_sglist_init(&req
->qsg
, pci
, 4);
200 left
= req
->scsi_io
.DataLength
;
203 dma_addr_t addr
, len
;
204 uint32_t flags_and_length
;
206 flags_and_length
= ldl_le_pci_dma(pci
, sgaddr
);
207 len
= flags_and_length
& MPI_SGE_LENGTH_MASK
;
208 if ((flags_and_length
& MPI_SGE_FLAGS_ELEMENT_TYPE_MASK
)
209 != MPI_SGE_FLAGS_SIMPLE_ELEMENT
||
211 !(flags_and_length
& MPI_SGE_FLAGS_END_OF_LIST
) &&
212 !(flags_and_length
& MPI_SGE_FLAGS_END_OF_BUFFER
))) {
213 return MPI_IOCSTATUS_INVALID_SGL
;
216 len
= MIN(len
, left
);
218 /* We reached the desired transfer length, ignore extra
219 * elements of the s/g list.
224 addr
= mptsas_ld_sg_base(s
, flags_and_length
, &sgaddr
);
225 qemu_sglist_add(&req
->qsg
, addr
, len
);
228 if (flags_and_length
& MPI_SGE_FLAGS_END_OF_LIST
) {
232 if (flags_and_length
& MPI_SGE_FLAGS_LAST_ELEMENT
) {
237 flags_and_length
= ldl_le_pci_dma(pci
, next_chain_addr
);
238 if ((flags_and_length
& MPI_SGE_FLAGS_ELEMENT_TYPE_MASK
)
239 != MPI_SGE_FLAGS_CHAIN_ELEMENT
) {
240 return MPI_IOCSTATUS_INVALID_SGL
;
243 sgaddr
= mptsas_ld_sg_base(s
, flags_and_length
, &next_chain_addr
);
245 (flags_and_length
& MPI_SGE_CHAIN_OFFSET_MASK
) >> MPI_SGE_CHAIN_OFFSET_SHIFT
;
246 next_chain_addr
= sgaddr
+ chain_offset
* sizeof(uint32_t);
252 static void mptsas_free_request(MPTSASRequest
*req
)
254 MPTSASState
*s
= req
->dev
;
256 if (req
->sreq
!= NULL
) {
257 req
->sreq
->hba_private
= NULL
;
258 scsi_req_unref(req
->sreq
);
260 QTAILQ_REMOVE(&s
->pending
, req
, next
);
262 qemu_sglist_destroy(&req
->qsg
);
266 static int mptsas_scsi_device_find(MPTSASState
*s
, int bus
, int target
,
267 uint8_t *lun
, SCSIDevice
**sdev
)
270 return MPI_IOCSTATUS_SCSI_INVALID_BUS
;
273 if (target
>= s
->max_devices
) {
274 return MPI_IOCSTATUS_SCSI_INVALID_TARGETID
;
277 *sdev
= scsi_device_find(&s
->bus
, bus
, target
, lun
[1]);
279 return MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
;
285 static int mptsas_process_scsi_io_request(MPTSASState
*s
,
286 MPIMsgSCSIIORequest
*scsi_io
,
290 MPIMsgSCSIIOReply reply
;
294 mptsas_fix_scsi_io_endianness(scsi_io
);
296 trace_mptsas_process_scsi_io_request(s
, scsi_io
->Bus
, scsi_io
->TargetID
,
297 scsi_io
->LUN
[1], scsi_io
->DataLength
);
299 status
= mptsas_scsi_device_find(s
, scsi_io
->Bus
, scsi_io
->TargetID
,
300 scsi_io
->LUN
, &sdev
);
305 req
= g_new0(MPTSASRequest
, 1);
306 QTAILQ_INSERT_TAIL(&s
->pending
, req
, next
);
307 req
->scsi_io
= *scsi_io
;
310 status
= mptsas_build_sgl(s
, req
, addr
);
315 if (req
->qsg
.size
< scsi_io
->DataLength
) {
316 trace_mptsas_sgl_overflow(s
, scsi_io
->MsgContext
, scsi_io
->DataLength
,
318 status
= MPI_IOCSTATUS_INVALID_SGL
;
322 req
->sreq
= scsi_req_new(sdev
, scsi_io
->MsgContext
,
323 scsi_io
->LUN
[1], scsi_io
->CDB
, req
);
325 if (req
->sreq
->cmd
.xfer
> scsi_io
->DataLength
) {
328 switch (scsi_io
->Control
& MPI_SCSIIO_CONTROL_DATADIRECTION_MASK
) {
329 case MPI_SCSIIO_CONTROL_NODATATRANSFER
:
330 if (req
->sreq
->cmd
.mode
!= SCSI_XFER_NONE
) {
335 case MPI_SCSIIO_CONTROL_WRITE
:
336 if (req
->sreq
->cmd
.mode
!= SCSI_XFER_TO_DEV
) {
341 case MPI_SCSIIO_CONTROL_READ
:
342 if (req
->sreq
->cmd
.mode
!= SCSI_XFER_FROM_DEV
) {
348 if (scsi_req_enqueue(req
->sreq
)) {
349 scsi_req_continue(req
->sreq
);
354 trace_mptsas_scsi_overflow(s
, scsi_io
->MsgContext
, req
->sreq
->cmd
.xfer
,
355 scsi_io
->DataLength
);
356 status
= MPI_IOCSTATUS_SCSI_DATA_OVERRUN
;
358 mptsas_free_request(req
);
360 memset(&reply
, 0, sizeof(reply
));
361 reply
.TargetID
= scsi_io
->TargetID
;
362 reply
.Bus
= scsi_io
->Bus
;
363 reply
.MsgLength
= sizeof(reply
) / 4;
364 reply
.Function
= scsi_io
->Function
;
365 reply
.CDBLength
= scsi_io
->CDBLength
;
366 reply
.SenseBufferLength
= scsi_io
->SenseBufferLength
;
367 reply
.MsgContext
= scsi_io
->MsgContext
;
368 reply
.SCSIState
= MPI_SCSI_STATE_NO_SCSI_STATUS
;
369 reply
.IOCStatus
= status
;
371 mptsas_fix_scsi_io_reply_endianness(&reply
);
372 mptsas_reply(s
, (MPIDefaultReply
*)&reply
);
380 MPIMsgSCSITaskMgmtReply
*reply
;
381 } MPTSASCancelNotifier
;
383 static void mptsas_cancel_notify(Notifier
*notifier
, void *data
)
385 MPTSASCancelNotifier
*n
= container_of(notifier
,
386 MPTSASCancelNotifier
,
389 /* Abusing IOCLogInfo to store the expected number of requests... */
390 if (++n
->reply
->TerminationCount
== n
->reply
->IOCLogInfo
) {
391 n
->reply
->IOCLogInfo
= 0;
392 mptsas_fix_scsi_task_mgmt_reply_endianness(n
->reply
);
393 mptsas_post_reply(n
->s
, (MPIDefaultReply
*)n
->reply
);
399 static void mptsas_process_scsi_task_mgmt(MPTSASState
*s
, MPIMsgSCSITaskMgmt
*req
)
401 MPIMsgSCSITaskMgmtReply reply
;
402 MPIMsgSCSITaskMgmtReply
*reply_async
;
405 SCSIRequest
*r
, *next
;
408 mptsas_fix_scsi_task_mgmt_endianness(req
);
410 QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE
< sizeof(*req
));
411 QEMU_BUILD_BUG_ON(sizeof(s
->doorbell_msg
) < sizeof(*req
));
412 QEMU_BUILD_BUG_ON(sizeof(s
->doorbell_reply
) < sizeof(reply
));
414 memset(&reply
, 0, sizeof(reply
));
415 reply
.TargetID
= req
->TargetID
;
416 reply
.Bus
= req
->Bus
;
417 reply
.MsgLength
= sizeof(reply
) / 4;
418 reply
.Function
= req
->Function
;
419 reply
.TaskType
= req
->TaskType
;
420 reply
.MsgContext
= req
->MsgContext
;
422 switch (req
->TaskType
) {
423 case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK
:
424 case MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK
:
425 status
= mptsas_scsi_device_find(s
, req
->Bus
, req
->TargetID
,
428 reply
.IOCStatus
= status
;
431 if (sdev
->lun
!= req
->LUN
[1]) {
432 reply
.ResponseCode
= MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN
;
436 QTAILQ_FOREACH_SAFE(r
, &sdev
->requests
, next
, next
) {
437 MPTSASRequest
*cmd_req
= r
->hba_private
;
438 if (cmd_req
&& cmd_req
->scsi_io
.MsgContext
== req
->TaskMsgContext
) {
444 * Assert that the request has not been completed yet, we
445 * check for it in the loop above.
447 assert(r
->hba_private
);
448 if (req
->TaskType
== MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK
) {
449 /* "If the specified command is present in the task set, then
450 * return a service response set to FUNCTION SUCCEEDED".
452 reply
.ResponseCode
= MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED
;
454 MPTSASCancelNotifier
*notifier
;
456 reply_async
= g_memdup(&reply
, sizeof(MPIMsgSCSITaskMgmtReply
));
457 reply_async
->IOCLogInfo
= INT_MAX
;
460 notifier
= g_new(MPTSASCancelNotifier
, 1);
462 notifier
->reply
= reply_async
;
463 notifier
->notifier
.notify
= mptsas_cancel_notify
;
464 scsi_req_cancel_async(r
, ¬ifier
->notifier
);
465 goto reply_maybe_async
;
470 case MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET
:
471 case MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET
:
472 status
= mptsas_scsi_device_find(s
, req
->Bus
, req
->TargetID
,
475 reply
.IOCStatus
= status
;
478 if (sdev
->lun
!= req
->LUN
[1]) {
479 reply
.ResponseCode
= MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN
;
483 reply_async
= g_memdup(&reply
, sizeof(MPIMsgSCSITaskMgmtReply
));
484 reply_async
->IOCLogInfo
= INT_MAX
;
487 QTAILQ_FOREACH_SAFE(r
, &sdev
->requests
, next
, next
) {
488 if (r
->hba_private
) {
489 MPTSASCancelNotifier
*notifier
;
492 notifier
= g_new(MPTSASCancelNotifier
, 1);
494 notifier
->reply
= reply_async
;
495 notifier
->notifier
.notify
= mptsas_cancel_notify
;
496 scsi_req_cancel_async(r
, ¬ifier
->notifier
);
501 if (reply_async
->TerminationCount
< count
) {
502 reply_async
->IOCLogInfo
= count
;
506 reply
.TerminationCount
= count
;
509 case MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET
:
510 status
= mptsas_scsi_device_find(s
, req
->Bus
, req
->TargetID
,
513 reply
.IOCStatus
= status
;
516 if (sdev
->lun
!= req
->LUN
[1]) {
517 reply
.ResponseCode
= MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN
;
520 qdev_reset_all(&sdev
->qdev
);
523 case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET
:
525 reply
.IOCStatus
= MPI_IOCSTATUS_SCSI_INVALID_BUS
;
528 if (req
->TargetID
> s
->max_devices
) {
529 reply
.IOCStatus
= MPI_IOCSTATUS_SCSI_INVALID_TARGETID
;
533 QTAILQ_FOREACH(kid
, &s
->bus
.qbus
.children
, sibling
) {
534 sdev
= SCSI_DEVICE(kid
->child
);
535 if (sdev
->channel
== 0 && sdev
->id
== req
->TargetID
) {
536 qdev_reset_all(kid
->child
);
541 case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
:
542 qbus_reset_all(BUS(&s
->bus
));
546 reply
.ResponseCode
= MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED
;
551 mptsas_fix_scsi_task_mgmt_reply_endianness(&reply
);
552 mptsas_post_reply(s
, (MPIDefaultReply
*)&reply
);
555 static void mptsas_process_ioc_init(MPTSASState
*s
, MPIMsgIOCInit
*req
)
557 MPIMsgIOCInitReply reply
;
559 mptsas_fix_ioc_init_endianness(req
);
561 QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE
< sizeof(*req
));
562 QEMU_BUILD_BUG_ON(sizeof(s
->doorbell_msg
) < sizeof(*req
));
563 QEMU_BUILD_BUG_ON(sizeof(s
->doorbell_reply
) < sizeof(reply
));
565 s
->who_init
= req
->WhoInit
;
566 s
->reply_frame_size
= req
->ReplyFrameSize
;
567 s
->max_buses
= req
->MaxBuses
;
568 s
->max_devices
= req
->MaxDevices
? req
->MaxDevices
: 256;
569 s
->host_mfa_high_addr
= (hwaddr
)req
->HostMfaHighAddr
<< 32;
570 s
->sense_buffer_high_addr
= (hwaddr
)req
->SenseBufferHighAddr
<< 32;
572 if (s
->state
== MPI_IOC_STATE_READY
) {
573 s
->state
= MPI_IOC_STATE_OPERATIONAL
;
576 memset(&reply
, 0, sizeof(reply
));
577 reply
.WhoInit
= s
->who_init
;
578 reply
.MsgLength
= sizeof(reply
) / 4;
579 reply
.Function
= req
->Function
;
580 reply
.MaxDevices
= s
->max_devices
;
581 reply
.MaxBuses
= s
->max_buses
;
582 reply
.MsgContext
= req
->MsgContext
;
584 mptsas_fix_ioc_init_reply_endianness(&reply
);
585 mptsas_reply(s
, (MPIDefaultReply
*)&reply
);
588 static void mptsas_process_ioc_facts(MPTSASState
*s
,
591 MPIMsgIOCFactsReply reply
;
593 mptsas_fix_ioc_facts_endianness(req
);
595 QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE
< sizeof(*req
));
596 QEMU_BUILD_BUG_ON(sizeof(s
->doorbell_msg
) < sizeof(*req
));
597 QEMU_BUILD_BUG_ON(sizeof(s
->doorbell_reply
) < sizeof(reply
));
599 memset(&reply
, 0, sizeof(reply
));
600 reply
.MsgVersion
= 0x0105;
601 reply
.MsgLength
= sizeof(reply
) / 4;
602 reply
.Function
= req
->Function
;
603 reply
.MsgContext
= req
->MsgContext
;
604 reply
.MaxChainDepth
= MPTSAS_MAXIMUM_CHAIN_DEPTH
;
605 reply
.WhoInit
= s
->who_init
;
606 reply
.BlockSize
= MPTSAS_MAX_REQUEST_SIZE
/ sizeof(uint32_t);
607 reply
.ReplyQueueDepth
= ARRAY_SIZE(s
->reply_post
) - 1;
608 QEMU_BUILD_BUG_ON(ARRAY_SIZE(s
->reply_post
) != ARRAY_SIZE(s
->reply_free
));
610 reply
.RequestFrameSize
= 128;
611 reply
.ProductID
= MPTSAS1068_PRODUCT_ID
;
612 reply
.CurrentHostMfaHighAddr
= s
->host_mfa_high_addr
>> 32;
613 reply
.GlobalCredits
= ARRAY_SIZE(s
->request_post
) - 1;
614 reply
.NumberOfPorts
= MPTSAS_NUM_PORTS
;
615 reply
.CurrentSenseBufferHighAddr
= s
->sense_buffer_high_addr
>> 32;
616 reply
.CurReplyFrameSize
= s
->reply_frame_size
;
617 reply
.MaxDevices
= s
->max_devices
;
618 reply
.MaxBuses
= s
->max_buses
;
619 reply
.FWVersionDev
= 0;
620 reply
.FWVersionUnit
= 0x92;
621 reply
.FWVersionMinor
= 0x32;
622 reply
.FWVersionMajor
= 0x1;
624 mptsas_fix_ioc_facts_reply_endianness(&reply
);
625 mptsas_reply(s
, (MPIDefaultReply
*)&reply
);
628 static void mptsas_process_port_facts(MPTSASState
*s
,
629 MPIMsgPortFacts
*req
)
631 MPIMsgPortFactsReply reply
;
633 mptsas_fix_port_facts_endianness(req
);
635 QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE
< sizeof(*req
));
636 QEMU_BUILD_BUG_ON(sizeof(s
->doorbell_msg
) < sizeof(*req
));
637 QEMU_BUILD_BUG_ON(sizeof(s
->doorbell_reply
) < sizeof(reply
));
639 memset(&reply
, 0, sizeof(reply
));
640 reply
.MsgLength
= sizeof(reply
) / 4;
641 reply
.Function
= req
->Function
;
642 reply
.PortNumber
= req
->PortNumber
;
643 reply
.MsgContext
= req
->MsgContext
;
645 if (req
->PortNumber
< MPTSAS_NUM_PORTS
) {
646 reply
.PortType
= MPI_PORTFACTS_PORTTYPE_SAS
;
647 reply
.MaxDevices
= MPTSAS_NUM_PORTS
;
648 reply
.PortSCSIID
= MPTSAS_NUM_PORTS
;
649 reply
.ProtocolFlags
= MPI_PORTFACTS_PROTOCOL_LOGBUSADDR
| MPI_PORTFACTS_PROTOCOL_INITIATOR
;
652 mptsas_fix_port_facts_reply_endianness(&reply
);
653 mptsas_reply(s
, (MPIDefaultReply
*)&reply
);
656 static void mptsas_process_port_enable(MPTSASState
*s
,
657 MPIMsgPortEnable
*req
)
659 MPIMsgPortEnableReply reply
;
661 mptsas_fix_port_enable_endianness(req
);
663 QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE
< sizeof(*req
));
664 QEMU_BUILD_BUG_ON(sizeof(s
->doorbell_msg
) < sizeof(*req
));
665 QEMU_BUILD_BUG_ON(sizeof(s
->doorbell_reply
) < sizeof(reply
));
667 memset(&reply
, 0, sizeof(reply
));
668 reply
.MsgLength
= sizeof(reply
) / 4;
669 reply
.PortNumber
= req
->PortNumber
;
670 reply
.Function
= req
->Function
;
671 reply
.MsgContext
= req
->MsgContext
;
673 mptsas_fix_port_enable_reply_endianness(&reply
);
674 mptsas_reply(s
, (MPIDefaultReply
*)&reply
);
677 static void mptsas_process_event_notification(MPTSASState
*s
,
678 MPIMsgEventNotify
*req
)
680 MPIMsgEventNotifyReply reply
;
682 mptsas_fix_event_notification_endianness(req
);
684 QEMU_BUILD_BUG_ON(MPTSAS_MAX_REQUEST_SIZE
< sizeof(*req
));
685 QEMU_BUILD_BUG_ON(sizeof(s
->doorbell_msg
) < sizeof(*req
));
686 QEMU_BUILD_BUG_ON(sizeof(s
->doorbell_reply
) < sizeof(reply
));
688 /* Don't even bother storing whether event notification is enabled,
689 * since it is not accessible.
692 memset(&reply
, 0, sizeof(reply
));
693 reply
.EventDataLength
= sizeof(reply
.Data
) / 4;
694 reply
.MsgLength
= sizeof(reply
) / 4;
695 reply
.Function
= req
->Function
;
697 /* This is set because events are sent through the reply FIFOs. */
698 reply
.MsgFlags
= MPI_MSGFLAGS_CONTINUATION_REPLY
;
700 reply
.MsgContext
= req
->MsgContext
;
701 reply
.Event
= MPI_EVENT_EVENT_CHANGE
;
702 reply
.Data
[0] = !!req
->Switch
;
704 mptsas_fix_event_notification_reply_endianness(&reply
);
705 mptsas_reply(s
, (MPIDefaultReply
*)&reply
);
708 static void mptsas_process_message(MPTSASState
*s
, MPIRequestHeader
*req
)
710 trace_mptsas_process_message(s
, req
->Function
, req
->MsgContext
);
711 switch (req
->Function
) {
712 case MPI_FUNCTION_SCSI_TASK_MGMT
:
713 mptsas_process_scsi_task_mgmt(s
, (MPIMsgSCSITaskMgmt
*)req
);
716 case MPI_FUNCTION_IOC_INIT
:
717 mptsas_process_ioc_init(s
, (MPIMsgIOCInit
*)req
);
720 case MPI_FUNCTION_IOC_FACTS
:
721 mptsas_process_ioc_facts(s
, (MPIMsgIOCFacts
*)req
);
724 case MPI_FUNCTION_PORT_FACTS
:
725 mptsas_process_port_facts(s
, (MPIMsgPortFacts
*)req
);
728 case MPI_FUNCTION_PORT_ENABLE
:
729 mptsas_process_port_enable(s
, (MPIMsgPortEnable
*)req
);
732 case MPI_FUNCTION_EVENT_NOTIFICATION
:
733 mptsas_process_event_notification(s
, (MPIMsgEventNotify
*)req
);
736 case MPI_FUNCTION_CONFIG
:
737 mptsas_process_config(s
, (MPIMsgConfig
*)req
);
741 trace_mptsas_unhandled_cmd(s
, req
->Function
, 0);
742 mptsas_set_fault(s
, MPI_IOCSTATUS_INVALID_FUNCTION
);
747 static void mptsas_fetch_request(MPTSASState
*s
)
749 PCIDevice
*pci
= (PCIDevice
*) s
;
750 char req
[MPTSAS_MAX_REQUEST_SIZE
];
751 MPIRequestHeader
*hdr
= (MPIRequestHeader
*)req
;
755 /* Read the message header from the guest first. */
756 addr
= s
->host_mfa_high_addr
| MPTSAS_FIFO_GET(s
, request_post
);
757 pci_dma_read(pci
, addr
, req
, sizeof(*hdr
));
759 if (hdr
->Function
< ARRAY_SIZE(mpi_request_sizes
) &&
760 mpi_request_sizes
[hdr
->Function
]) {
761 /* Read the rest of the request based on the type. Do not
762 * reread everything, as that could cause a TOC/TOU mismatch
763 * and leak data from the QEMU stack.
765 size
= mpi_request_sizes
[hdr
->Function
];
766 assert(size
<= MPTSAS_MAX_REQUEST_SIZE
);
767 pci_dma_read(pci
, addr
+ sizeof(*hdr
), &req
[sizeof(*hdr
)],
768 size
- sizeof(*hdr
));
771 if (hdr
->Function
== MPI_FUNCTION_SCSI_IO_REQUEST
) {
772 /* SCSI I/O requests are separate from mptsas_process_message
773 * because they cannot be sent through the doorbell yet.
775 mptsas_process_scsi_io_request(s
, (MPIMsgSCSIIORequest
*)req
, addr
);
777 mptsas_process_message(s
, (MPIRequestHeader
*)req
);
781 static void mptsas_fetch_requests(void *opaque
)
783 MPTSASState
*s
= opaque
;
785 if (s
->state
!= MPI_IOC_STATE_OPERATIONAL
) {
786 mptsas_set_fault(s
, MPI_IOCSTATUS_INVALID_STATE
);
789 while (!MPTSAS_FIFO_EMPTY(s
, request_post
)) {
790 mptsas_fetch_request(s
);
794 static void mptsas_soft_reset(MPTSASState
*s
)
798 trace_mptsas_reset(s
);
800 /* Temporarily disable interrupts */
801 save_mask
= s
->intr_mask
;
802 s
->intr_mask
= MPI_HIM_DIM
| MPI_HIM_RIM
;
803 mptsas_update_interrupt(s
);
805 qbus_reset_all(BUS(&s
->bus
));
807 s
->intr_mask
= save_mask
;
809 s
->reply_free_tail
= 0;
810 s
->reply_free_head
= 0;
811 s
->reply_post_tail
= 0;
812 s
->reply_post_head
= 0;
813 s
->request_post_tail
= 0;
814 s
->request_post_head
= 0;
815 qemu_bh_cancel(s
->request_bh
);
817 s
->state
= MPI_IOC_STATE_READY
;
820 static uint32_t mptsas_doorbell_read(MPTSASState
*s
)
824 ret
= (s
->who_init
<< MPI_DOORBELL_WHO_INIT_SHIFT
) & MPI_DOORBELL_WHO_INIT_MASK
;
826 switch (s
->doorbell_state
) {
831 ret
|= MPI_DOORBELL_ACTIVE
;
835 /* Get rid of the IOC fault code. */
836 ret
&= ~MPI_DOORBELL_DATA_MASK
;
838 assert(s
->intr_status
& MPI_HIS_DOORBELL_INTERRUPT
);
839 assert(s
->doorbell_reply_idx
<= s
->doorbell_reply_size
);
841 ret
|= MPI_DOORBELL_ACTIVE
;
842 if (s
->doorbell_reply_idx
< s
->doorbell_reply_size
) {
843 /* For more information about this endian switch, see the
844 * commit message for commit 36b62ae ("fw_cfg: fix endianness in
845 * fw_cfg_data_mem_read() / _write()", 2015-01-16).
847 ret
|= le16_to_cpu(s
->doorbell_reply
[s
->doorbell_reply_idx
++]);
858 static void mptsas_doorbell_write(MPTSASState
*s
, uint32_t val
)
860 if (s
->doorbell_state
== DOORBELL_WRITE
) {
861 if (s
->doorbell_idx
< s
->doorbell_cnt
) {
862 /* For more information about this endian switch, see the
863 * commit message for commit 36b62ae ("fw_cfg: fix endianness in
864 * fw_cfg_data_mem_read() / _write()", 2015-01-16).
866 s
->doorbell_msg
[s
->doorbell_idx
++] = cpu_to_le32(val
);
867 if (s
->doorbell_idx
== s
->doorbell_cnt
) {
868 mptsas_process_message(s
, (MPIRequestHeader
*)s
->doorbell_msg
);
874 switch ((val
& MPI_DOORBELL_FUNCTION_MASK
) >> MPI_DOORBELL_FUNCTION_SHIFT
) {
875 case MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
:
876 mptsas_soft_reset(s
);
878 case MPI_FUNCTION_IO_UNIT_RESET
:
880 case MPI_FUNCTION_HANDSHAKE
:
881 s
->doorbell_state
= DOORBELL_WRITE
;
883 s
->doorbell_cnt
= (val
& MPI_DOORBELL_ADD_DWORDS_MASK
)
884 >> MPI_DOORBELL_ADD_DWORDS_SHIFT
;
885 s
->intr_status
|= MPI_HIS_DOORBELL_INTERRUPT
;
886 mptsas_update_interrupt(s
);
889 trace_mptsas_unhandled_doorbell_cmd(s
, val
);
894 static void mptsas_write_sequence_write(MPTSASState
*s
, uint32_t val
)
896 /* If the diagnostic register is enabled, any write to this register
897 * will disable it. Otherwise, the guest has to do a magic five-write
900 if (s
->diagnostic
& MPI_DIAG_DRWE
) {
904 switch (s
->diagnostic_idx
) {
906 if ((val
& MPI_WRSEQ_KEY_VALUE_MASK
) != MPI_WRSEQ_1ST_KEY_VALUE
) {
911 if ((val
& MPI_WRSEQ_KEY_VALUE_MASK
) != MPI_WRSEQ_2ND_KEY_VALUE
) {
916 if ((val
& MPI_WRSEQ_KEY_VALUE_MASK
) != MPI_WRSEQ_3RD_KEY_VALUE
) {
921 if ((val
& MPI_WRSEQ_KEY_VALUE_MASK
) != MPI_WRSEQ_4TH_KEY_VALUE
) {
926 if ((val
& MPI_WRSEQ_KEY_VALUE_MASK
) != MPI_WRSEQ_5TH_KEY_VALUE
) {
929 /* Prepare Spaceball One for departure, and change the
930 * combination on my luggage!
932 s
->diagnostic
|= MPI_DIAG_DRWE
;
939 s
->diagnostic
&= ~MPI_DIAG_DRWE
;
940 s
->diagnostic_idx
= 0;
943 static int mptsas_hard_reset(MPTSASState
*s
)
945 mptsas_soft_reset(s
);
947 s
->intr_mask
= MPI_HIM_DIM
| MPI_HIM_RIM
;
949 s
->host_mfa_high_addr
= 0;
950 s
->sense_buffer_high_addr
= 0;
951 s
->reply_frame_size
= 0;
952 s
->max_devices
= MPTSAS_NUM_PORTS
;
958 static void mptsas_interrupt_status_write(MPTSASState
*s
)
960 switch (s
->doorbell_state
) {
963 s
->intr_status
&= ~MPI_HIS_DOORBELL_INTERRUPT
;
967 /* The reply can be read continuously, so leave the interrupt up. */
968 assert(s
->intr_status
& MPI_HIS_DOORBELL_INTERRUPT
);
969 if (s
->doorbell_reply_idx
== s
->doorbell_reply_size
) {
970 s
->doorbell_state
= DOORBELL_NONE
;
977 mptsas_update_interrupt(s
);
980 static uint32_t mptsas_reply_post_read(MPTSASState
*s
)
984 if (!MPTSAS_FIFO_EMPTY(s
, reply_post
)) {
985 ret
= MPTSAS_FIFO_GET(s
, reply_post
);
988 s
->intr_status
&= ~MPI_HIS_REPLY_MESSAGE_INTERRUPT
;
989 mptsas_update_interrupt(s
);
995 static uint64_t mptsas_mmio_read(void *opaque
, hwaddr addr
,
998 MPTSASState
*s
= opaque
;
1001 switch (addr
& ~3) {
1002 case MPI_DOORBELL_OFFSET
:
1003 ret
= mptsas_doorbell_read(s
);
1006 case MPI_DIAGNOSTIC_OFFSET
:
1007 ret
= s
->diagnostic
;
1010 case MPI_HOST_INTERRUPT_STATUS_OFFSET
:
1011 ret
= s
->intr_status
;
1014 case MPI_HOST_INTERRUPT_MASK_OFFSET
:
1018 case MPI_REPLY_POST_FIFO_OFFSET
:
1019 ret
= mptsas_reply_post_read(s
);
1023 trace_mptsas_mmio_unhandled_read(s
, addr
);
1026 trace_mptsas_mmio_read(s
, addr
, ret
);
1030 static void mptsas_mmio_write(void *opaque
, hwaddr addr
,
1031 uint64_t val
, unsigned size
)
1033 MPTSASState
*s
= opaque
;
1035 trace_mptsas_mmio_write(s
, addr
, val
);
1037 case MPI_DOORBELL_OFFSET
:
1038 mptsas_doorbell_write(s
, val
);
1041 case MPI_WRITE_SEQUENCE_OFFSET
:
1042 mptsas_write_sequence_write(s
, val
);
1045 case MPI_DIAGNOSTIC_OFFSET
:
1046 if (val
& MPI_DIAG_RESET_ADAPTER
) {
1047 mptsas_hard_reset(s
);
1051 case MPI_HOST_INTERRUPT_STATUS_OFFSET
:
1052 mptsas_interrupt_status_write(s
);
1055 case MPI_HOST_INTERRUPT_MASK_OFFSET
:
1056 s
->intr_mask
= val
& (MPI_HIM_RIM
| MPI_HIM_DIM
);
1057 mptsas_update_interrupt(s
);
1060 case MPI_REQUEST_POST_FIFO_OFFSET
:
1061 if (MPTSAS_FIFO_FULL(s
, request_post
)) {
1062 mptsas_set_fault(s
, MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
);
1064 MPTSAS_FIFO_PUT(s
, request_post
, val
& ~0x03);
1065 qemu_bh_schedule(s
->request_bh
);
1069 case MPI_REPLY_FREE_FIFO_OFFSET
:
1070 if (MPTSAS_FIFO_FULL(s
, reply_free
)) {
1071 mptsas_set_fault(s
, MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
);
1073 MPTSAS_FIFO_PUT(s
, reply_free
, val
);
1078 trace_mptsas_mmio_unhandled_write(s
, addr
, val
);
1083 static const MemoryRegionOps mptsas_mmio_ops
= {
1084 .read
= mptsas_mmio_read
,
1085 .write
= mptsas_mmio_write
,
1086 .endianness
= DEVICE_LITTLE_ENDIAN
,
1088 .min_access_size
= 4,
1089 .max_access_size
= 4,
1093 static const MemoryRegionOps mptsas_port_ops
= {
1094 .read
= mptsas_mmio_read
,
1095 .write
= mptsas_mmio_write
,
1096 .endianness
= DEVICE_LITTLE_ENDIAN
,
1098 .min_access_size
= 4,
1099 .max_access_size
= 4,
1103 static uint64_t mptsas_diag_read(void *opaque
, hwaddr addr
,
1106 MPTSASState
*s
= opaque
;
1107 trace_mptsas_diag_read(s
, addr
, 0);
1111 static void mptsas_diag_write(void *opaque
, hwaddr addr
,
1112 uint64_t val
, unsigned size
)
1114 MPTSASState
*s
= opaque
;
1115 trace_mptsas_diag_write(s
, addr
, val
);
1118 static const MemoryRegionOps mptsas_diag_ops
= {
1119 .read
= mptsas_diag_read
,
1120 .write
= mptsas_diag_write
,
1121 .endianness
= DEVICE_LITTLE_ENDIAN
,
1123 .min_access_size
= 4,
1124 .max_access_size
= 4,
1128 static QEMUSGList
*mptsas_get_sg_list(SCSIRequest
*sreq
)
1130 MPTSASRequest
*req
= sreq
->hba_private
;
1135 static void mptsas_command_complete(SCSIRequest
*sreq
,
1138 MPTSASRequest
*req
= sreq
->hba_private
;
1139 MPTSASState
*s
= req
->dev
;
1140 uint8_t sense_buf
[SCSI_SENSE_BUF_SIZE
];
1143 hwaddr sense_buffer_addr
= req
->dev
->sense_buffer_high_addr
|
1144 req
->scsi_io
.SenseBufferLowAddr
;
1146 trace_mptsas_command_complete(s
, req
->scsi_io
.MsgContext
,
1147 sreq
->status
, resid
);
1149 sense_len
= scsi_req_get_sense(sreq
, sense_buf
, SCSI_SENSE_BUF_SIZE
);
1150 if (sense_len
> 0) {
1151 pci_dma_write(PCI_DEVICE(s
), sense_buffer_addr
, sense_buf
,
1152 MIN(req
->scsi_io
.SenseBufferLength
, sense_len
));
1155 if (sreq
->status
!= GOOD
|| resid
||
1156 req
->dev
->doorbell_state
== DOORBELL_WRITE
) {
1157 MPIMsgSCSIIOReply reply
;
1159 memset(&reply
, 0, sizeof(reply
));
1160 reply
.TargetID
= req
->scsi_io
.TargetID
;
1161 reply
.Bus
= req
->scsi_io
.Bus
;
1162 reply
.MsgLength
= sizeof(reply
) / 4;
1163 reply
.Function
= req
->scsi_io
.Function
;
1164 reply
.CDBLength
= req
->scsi_io
.CDBLength
;
1165 reply
.SenseBufferLength
= req
->scsi_io
.SenseBufferLength
;
1166 reply
.MsgFlags
= req
->scsi_io
.MsgFlags
;
1167 reply
.MsgContext
= req
->scsi_io
.MsgContext
;
1168 reply
.SCSIStatus
= sreq
->status
;
1169 if (sreq
->status
== GOOD
) {
1170 reply
.TransferCount
= req
->scsi_io
.DataLength
- resid
;
1172 reply
.IOCStatus
= MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
;
1175 reply
.SCSIState
= MPI_SCSI_STATE_AUTOSENSE_VALID
;
1176 reply
.SenseCount
= sense_len
;
1177 reply
.IOCStatus
= MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
;
1180 mptsas_fix_scsi_io_reply_endianness(&reply
);
1181 mptsas_post_reply(req
->dev
, (MPIDefaultReply
*)&reply
);
1183 mptsas_turbo_reply(req
->dev
, req
->scsi_io
.MsgContext
);
1186 mptsas_free_request(req
);
1189 static void mptsas_request_cancelled(SCSIRequest
*sreq
)
1191 MPTSASRequest
*req
= sreq
->hba_private
;
1192 MPIMsgSCSIIOReply reply
;
1194 memset(&reply
, 0, sizeof(reply
));
1195 reply
.TargetID
= req
->scsi_io
.TargetID
;
1196 reply
.Bus
= req
->scsi_io
.Bus
;
1197 reply
.MsgLength
= sizeof(reply
) / 4;
1198 reply
.Function
= req
->scsi_io
.Function
;
1199 reply
.CDBLength
= req
->scsi_io
.CDBLength
;
1200 reply
.SenseBufferLength
= req
->scsi_io
.SenseBufferLength
;
1201 reply
.MsgFlags
= req
->scsi_io
.MsgFlags
;
1202 reply
.MsgContext
= req
->scsi_io
.MsgContext
;
1203 reply
.SCSIState
= MPI_SCSI_STATE_NO_SCSI_STATUS
;
1204 reply
.IOCStatus
= MPI_IOCSTATUS_SCSI_TASK_TERMINATED
;
1206 mptsas_fix_scsi_io_reply_endianness(&reply
);
1207 mptsas_post_reply(req
->dev
, (MPIDefaultReply
*)&reply
);
1208 mptsas_free_request(req
);
1211 static void mptsas_save_request(QEMUFile
*f
, SCSIRequest
*sreq
)
1213 MPTSASRequest
*req
= sreq
->hba_private
;
1216 qemu_put_buffer(f
, (unsigned char *)&req
->scsi_io
, sizeof(req
->scsi_io
));
1217 qemu_put_be32(f
, req
->qsg
.nsg
);
1218 for (i
= 0; i
< req
->qsg
.nsg
; i
++) {
1219 qemu_put_be64(f
, req
->qsg
.sg
[i
].base
);
1220 qemu_put_be64(f
, req
->qsg
.sg
[i
].len
);
1224 static void *mptsas_load_request(QEMUFile
*f
, SCSIRequest
*sreq
)
1226 SCSIBus
*bus
= sreq
->bus
;
1227 MPTSASState
*s
= container_of(bus
, MPTSASState
, bus
);
1228 PCIDevice
*pci
= PCI_DEVICE(s
);
1232 req
= g_new(MPTSASRequest
, 1);
1233 qemu_get_buffer(f
, (unsigned char *)&req
->scsi_io
, sizeof(req
->scsi_io
));
1235 n
= qemu_get_be32(f
);
1236 /* TODO: add a way for SCSIBusInfo's load_request to fail,
1237 * and fail migration instead of asserting here.
1238 * This is just one thing (there are probably more) that must be
1239 * fixed before we can allow NDEBUG compilation.
1243 pci_dma_sglist_init(&req
->qsg
, pci
, n
);
1244 for (i
= 0; i
< n
; i
++) {
1245 uint64_t base
= qemu_get_be64(f
);
1246 uint64_t len
= qemu_get_be64(f
);
1247 qemu_sglist_add(&req
->qsg
, base
, len
);
1257 static const struct SCSIBusInfo mptsas_scsi_info
= {
1259 .max_target
= MPTSAS_NUM_PORTS
,
1262 .get_sg_list
= mptsas_get_sg_list
,
1263 .complete
= mptsas_command_complete
,
1264 .cancel
= mptsas_request_cancelled
,
1265 .save_request
= mptsas_save_request
,
1266 .load_request
= mptsas_load_request
,
1269 static void mptsas_scsi_realize(PCIDevice
*dev
, Error
**errp
)
1271 MPTSASState
*s
= MPT_SAS(dev
);
1275 dev
->config
[PCI_LATENCY_TIMER
] = 0;
1276 dev
->config
[PCI_INTERRUPT_PIN
] = 0x01;
1278 if (s
->msi
!= ON_OFF_AUTO_OFF
) {
1279 ret
= msi_init(dev
, 0, 1, true, false, &err
);
1280 /* Any error other than -ENOTSUP(board's MSI support is broken)
1281 * is a programming error */
1282 assert(!ret
|| ret
== -ENOTSUP
);
1283 if (ret
&& s
->msi
== ON_OFF_AUTO_ON
) {
1284 /* Can't satisfy user's explicit msi=on request, fail */
1285 error_append_hint(&err
, "You have to use msi=auto (default) or "
1286 "msi=off with this machine type.\n");
1287 error_propagate(errp
, err
);
1290 assert(!err
|| s
->msi
== ON_OFF_AUTO_AUTO
);
1291 /* With msi=auto, we fall back to MSI off silently */
1294 /* Only used for migration. */
1295 s
->msi_in_use
= (ret
== 0);
1298 memory_region_init_io(&s
->mmio_io
, OBJECT(s
), &mptsas_mmio_ops
, s
,
1299 "mptsas-mmio", 0x4000);
1300 memory_region_init_io(&s
->port_io
, OBJECT(s
), &mptsas_port_ops
, s
,
1302 memory_region_init_io(&s
->diag_io
, OBJECT(s
), &mptsas_diag_ops
, s
,
1303 "mptsas-diag", 0x10000);
1305 pci_register_bar(dev
, 0, PCI_BASE_ADDRESS_SPACE_IO
, &s
->port_io
);
1306 pci_register_bar(dev
, 1, PCI_BASE_ADDRESS_SPACE_MEMORY
|
1307 PCI_BASE_ADDRESS_MEM_TYPE_32
, &s
->mmio_io
);
1308 pci_register_bar(dev
, 2, PCI_BASE_ADDRESS_SPACE_MEMORY
|
1309 PCI_BASE_ADDRESS_MEM_TYPE_32
, &s
->diag_io
);
1312 s
->sas_addr
= ((NAA_LOCALLY_ASSIGNED_ID
<< 24) |
1313 IEEE_COMPANY_LOCALLY_ASSIGNED
) << 36;
1314 s
->sas_addr
|= (pci_dev_bus_num(dev
) << 16);
1315 s
->sas_addr
|= (PCI_SLOT(dev
->devfn
) << 8);
1316 s
->sas_addr
|= PCI_FUNC(dev
->devfn
);
1318 s
->max_devices
= MPTSAS_NUM_PORTS
;
1320 s
->request_bh
= qemu_bh_new(mptsas_fetch_requests
, s
);
1322 QTAILQ_INIT(&s
->pending
);
1324 scsi_bus_new(&s
->bus
, sizeof(s
->bus
), &dev
->qdev
, &mptsas_scsi_info
, NULL
);
1327 static void mptsas_scsi_uninit(PCIDevice
*dev
)
1329 MPTSASState
*s
= MPT_SAS(dev
);
1331 qemu_bh_delete(s
->request_bh
);
1335 static void mptsas_reset(DeviceState
*dev
)
1337 MPTSASState
*s
= MPT_SAS(dev
);
1339 mptsas_hard_reset(s
);
1342 static int mptsas_post_load(void *opaque
, int version_id
)
1344 MPTSASState
*s
= opaque
;
1346 if (s
->doorbell_idx
> s
->doorbell_cnt
||
1347 s
->doorbell_cnt
> ARRAY_SIZE(s
->doorbell_msg
) ||
1348 s
->doorbell_reply_idx
> s
->doorbell_reply_size
||
1349 s
->doorbell_reply_size
> ARRAY_SIZE(s
->doorbell_reply
) ||
1350 MPTSAS_FIFO_INVALID(s
, request_post
) ||
1351 MPTSAS_FIFO_INVALID(s
, reply_post
) ||
1352 MPTSAS_FIFO_INVALID(s
, reply_free
) ||
1353 s
->diagnostic_idx
> 4) {
1360 static const VMStateDescription vmstate_mptsas
= {
1363 .minimum_version_id
= 0,
1364 .minimum_version_id_old
= 0,
1365 .post_load
= mptsas_post_load
,
1366 .fields
= (VMStateField
[]) {
1367 VMSTATE_PCI_DEVICE(dev
, MPTSASState
),
1368 VMSTATE_BOOL(msi_in_use
, MPTSASState
),
1369 VMSTATE_UINT32(state
, MPTSASState
),
1370 VMSTATE_UINT8(who_init
, MPTSASState
),
1371 VMSTATE_UINT8(doorbell_state
, MPTSASState
),
1372 VMSTATE_UINT32_ARRAY(doorbell_msg
, MPTSASState
, 256),
1373 VMSTATE_INT32(doorbell_idx
, MPTSASState
),
1374 VMSTATE_INT32(doorbell_cnt
, MPTSASState
),
1376 VMSTATE_UINT16_ARRAY(doorbell_reply
, MPTSASState
, 256),
1377 VMSTATE_INT32(doorbell_reply_idx
, MPTSASState
),
1378 VMSTATE_INT32(doorbell_reply_size
, MPTSASState
),
1380 VMSTATE_UINT32(diagnostic
, MPTSASState
),
1381 VMSTATE_UINT8(diagnostic_idx
, MPTSASState
),
1383 VMSTATE_UINT32(intr_status
, MPTSASState
),
1384 VMSTATE_UINT32(intr_mask
, MPTSASState
),
1386 VMSTATE_UINT32_ARRAY(request_post
, MPTSASState
,
1387 MPTSAS_REQUEST_QUEUE_DEPTH
+ 1),
1388 VMSTATE_UINT16(request_post_head
, MPTSASState
),
1389 VMSTATE_UINT16(request_post_tail
, MPTSASState
),
1391 VMSTATE_UINT32_ARRAY(reply_post
, MPTSASState
,
1392 MPTSAS_REPLY_QUEUE_DEPTH
+ 1),
1393 VMSTATE_UINT16(reply_post_head
, MPTSASState
),
1394 VMSTATE_UINT16(reply_post_tail
, MPTSASState
),
1396 VMSTATE_UINT32_ARRAY(reply_free
, MPTSASState
,
1397 MPTSAS_REPLY_QUEUE_DEPTH
+ 1),
1398 VMSTATE_UINT16(reply_free_head
, MPTSASState
),
1399 VMSTATE_UINT16(reply_free_tail
, MPTSASState
),
1401 VMSTATE_UINT16(max_buses
, MPTSASState
),
1402 VMSTATE_UINT16(max_devices
, MPTSASState
),
1403 VMSTATE_UINT16(reply_frame_size
, MPTSASState
),
1404 VMSTATE_UINT64(host_mfa_high_addr
, MPTSASState
),
1405 VMSTATE_UINT64(sense_buffer_high_addr
, MPTSASState
),
1406 VMSTATE_END_OF_LIST()
1410 static Property mptsas_properties
[] = {
1411 DEFINE_PROP_UINT64("sas_address", MPTSASState
, sas_addr
, 0),
1412 /* TODO: test MSI support under Windows */
1413 DEFINE_PROP_ON_OFF_AUTO("msi", MPTSASState
, msi
, ON_OFF_AUTO_AUTO
),
1414 DEFINE_PROP_END_OF_LIST(),
1417 static void mptsas1068_class_init(ObjectClass
*oc
, void *data
)
1419 DeviceClass
*dc
= DEVICE_CLASS(oc
);
1420 PCIDeviceClass
*pc
= PCI_DEVICE_CLASS(oc
);
1422 pc
->realize
= mptsas_scsi_realize
;
1423 pc
->exit
= mptsas_scsi_uninit
;
1425 pc
->vendor_id
= PCI_VENDOR_ID_LSI_LOGIC
;
1426 pc
->device_id
= PCI_DEVICE_ID_LSI_SAS1068
;
1427 pc
->subsystem_vendor_id
= PCI_VENDOR_ID_LSI_LOGIC
;
1428 pc
->subsystem_id
= 0x8000;
1429 pc
->class_id
= PCI_CLASS_STORAGE_SCSI
;
1430 device_class_set_props(dc
, mptsas_properties
);
1431 dc
->reset
= mptsas_reset
;
1432 dc
->vmsd
= &vmstate_mptsas
;
1433 dc
->desc
= "LSI SAS 1068";
1434 set_bit(DEVICE_CATEGORY_STORAGE
, dc
->categories
);
1437 static const TypeInfo mptsas_info
= {
1438 .name
= TYPE_MPTSAS1068
,
1439 .parent
= TYPE_PCI_DEVICE
,
1440 .instance_size
= sizeof(MPTSASState
),
1441 .class_init
= mptsas1068_class_init
,
1442 .interfaces
= (InterfaceInfo
[]) {
1443 { INTERFACE_CONVENTIONAL_PCI_DEVICE
},
1448 static void mptsas_register_types(void)
1450 type_register(&mptsas_info
);
1453 type_init(mptsas_register_types
)