2 * QEMU MegaRAID SAS 8708EM2 Host Bus Adapter emulation
3 * Based on the linux driver code at drivers/scsi/megaraid
5 * Copyright (c) 2009-2012 Hannes Reinecke, SUSE Labs
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
27 #include "scsi-defs.h"
28 #include "block_int.h"
33 #define MEGASAS_VERSION "1.70"
34 #define MEGASAS_MAX_FRAMES 2048 /* Firmware limit at 65535 */
35 #define MEGASAS_DEFAULT_FRAMES 1000 /* Windows requires this */
36 #define MEGASAS_MAX_SGE 128 /* Firmware limit */
37 #define MEGASAS_DEFAULT_SGE 80
38 #define MEGASAS_MAX_SECTORS 0xFFFF /* No real limit */
39 #define MEGASAS_MAX_ARRAYS 128
41 #define MEGASAS_FLAG_USE_JBOD 0
42 #define MEGASAS_MASK_USE_JBOD (1 << MEGASAS_FLAG_USE_JBOD)
43 #define MEGASAS_FLAG_USE_MSIX 1
44 #define MEGASAS_MASK_USE_MSIX (1 << MEGASAS_FLAG_USE_MSIX)
45 #define MEGASAS_FLAG_USE_QUEUE64 2
46 #define MEGASAS_MASK_USE_QUEUE64 (1 << MEGASAS_FLAG_USE_QUEUE64)
48 const char *mfi_frame_desc
[] = {
49 "MFI init", "LD Read", "LD Write", "LD SCSI", "PD SCSI",
50 "MFI Doorbell", "MFI Abort", "MFI SMP", "MFI Stop"};
52 typedef struct MegasasCmd
{
58 target_phys_addr_t pa
;
59 target_phys_addr_t pa_size
;
60 union mfi_frame
*frame
;
66 struct MegasasState
*state
;
69 typedef struct MegasasState
{
73 MemoryRegion queue_io
;
85 MegasasCmd
*event_cmd
;
92 uint64_t reply_queue_pa
;
100 MegasasCmd frames
[MEGASAS_MAX_FRAMES
];
105 #define MEGASAS_INTR_DISABLED_MASK 0xFFFFFFFF
107 static bool megasas_intr_enabled(MegasasState
*s
)
109 if ((s
->intr_mask
& MEGASAS_INTR_DISABLED_MASK
) !=
110 MEGASAS_INTR_DISABLED_MASK
) {
116 static bool megasas_use_queue64(MegasasState
*s
)
118 return s
->flags
& MEGASAS_MASK_USE_QUEUE64
;
121 static bool megasas_use_msix(MegasasState
*s
)
123 return s
->flags
& MEGASAS_MASK_USE_MSIX
;
126 static bool megasas_is_jbod(MegasasState
*s
)
128 return s
->flags
& MEGASAS_MASK_USE_JBOD
;
131 static void megasas_frame_set_cmd_status(unsigned long frame
, uint8_t v
)
133 stb_phys(frame
+ offsetof(struct mfi_frame_header
, cmd_status
), v
);
136 static void megasas_frame_set_scsi_status(unsigned long frame
, uint8_t v
)
138 stb_phys(frame
+ offsetof(struct mfi_frame_header
, scsi_status
), v
);
142 * Context is considered opaque, but the HBA firmware is running
143 * in little endian mode. So convert it to little endian, too.
145 static uint64_t megasas_frame_get_context(unsigned long frame
)
147 return ldq_le_phys(frame
+ offsetof(struct mfi_frame_header
, context
));
150 static bool megasas_frame_is_ieee_sgl(MegasasCmd
*cmd
)
152 return cmd
->flags
& MFI_FRAME_IEEE_SGL
;
155 static bool megasas_frame_is_sgl64(MegasasCmd
*cmd
)
157 return cmd
->flags
& MFI_FRAME_SGL64
;
160 static bool megasas_frame_is_sense64(MegasasCmd
*cmd
)
162 return cmd
->flags
& MFI_FRAME_SENSE64
;
165 static uint64_t megasas_sgl_get_addr(MegasasCmd
*cmd
,
170 if (megasas_frame_is_ieee_sgl(cmd
)) {
171 addr
= le64_to_cpu(sgl
->sg_skinny
->addr
);
172 } else if (megasas_frame_is_sgl64(cmd
)) {
173 addr
= le64_to_cpu(sgl
->sg64
->addr
);
175 addr
= le32_to_cpu(sgl
->sg32
->addr
);
180 static uint32_t megasas_sgl_get_len(MegasasCmd
*cmd
,
185 if (megasas_frame_is_ieee_sgl(cmd
)) {
186 len
= le32_to_cpu(sgl
->sg_skinny
->len
);
187 } else if (megasas_frame_is_sgl64(cmd
)) {
188 len
= le32_to_cpu(sgl
->sg64
->len
);
190 len
= le32_to_cpu(sgl
->sg32
->len
);
195 static union mfi_sgl
*megasas_sgl_next(MegasasCmd
*cmd
,
198 uint8_t *next
= (uint8_t *)sgl
;
200 if (megasas_frame_is_ieee_sgl(cmd
)) {
201 next
+= sizeof(struct mfi_sg_skinny
);
202 } else if (megasas_frame_is_sgl64(cmd
)) {
203 next
+= sizeof(struct mfi_sg64
);
205 next
+= sizeof(struct mfi_sg32
);
208 if (next
>= (uint8_t *)cmd
->frame
+ cmd
->pa_size
) {
211 return (union mfi_sgl
*)next
;
214 static void megasas_soft_reset(MegasasState
*s
);
216 static int megasas_map_sgl(MegasasState
*s
, MegasasCmd
*cmd
, union mfi_sgl
*sgl
)
222 cmd
->flags
= le16_to_cpu(cmd
->frame
->header
.flags
);
223 iov_count
= cmd
->frame
->header
.sge_count
;
224 if (iov_count
> MEGASAS_MAX_SGE
) {
225 trace_megasas_iovec_sgl_overflow(cmd
->index
, iov_count
,
229 qemu_sglist_init(&cmd
->qsg
, iov_count
, pci_dma_context(&s
->dev
));
230 for (i
= 0; i
< iov_count
; i
++) {
231 dma_addr_t iov_pa
, iov_size_p
;
234 trace_megasas_iovec_sgl_underflow(cmd
->index
, i
);
237 iov_pa
= megasas_sgl_get_addr(cmd
, sgl
);
238 iov_size_p
= megasas_sgl_get_len(cmd
, sgl
);
239 if (!iov_pa
|| !iov_size_p
) {
240 trace_megasas_iovec_sgl_invalid(cmd
->index
, i
,
244 qemu_sglist_add(&cmd
->qsg
, iov_pa
, iov_size_p
);
245 sgl
= megasas_sgl_next(cmd
, sgl
);
246 iov_size
+= (size_t)iov_size_p
;
248 if (cmd
->iov_size
> iov_size
) {
249 trace_megasas_iovec_overflow(cmd
->index
, iov_size
, cmd
->iov_size
);
250 } else if (cmd
->iov_size
< iov_size
) {
251 trace_megasas_iovec_underflow(cmd
->iov_size
, iov_size
, cmd
->iov_size
);
256 qemu_sglist_destroy(&cmd
->qsg
);
257 return iov_count
- i
;
260 static void megasas_unmap_sgl(MegasasCmd
*cmd
)
262 qemu_sglist_destroy(&cmd
->qsg
);
267 * passthrough sense and io sense are at the same offset
269 static int megasas_build_sense(MegasasCmd
*cmd
, uint8_t *sense_ptr
,
272 uint32_t pa_hi
= 0, pa_lo
;
273 target_phys_addr_t pa
;
275 if (sense_len
> cmd
->frame
->header
.sense_len
) {
276 sense_len
= cmd
->frame
->header
.sense_len
;
279 pa_lo
= le32_to_cpu(cmd
->frame
->pass
.sense_addr_lo
);
280 if (megasas_frame_is_sense64(cmd
)) {
281 pa_hi
= le32_to_cpu(cmd
->frame
->pass
.sense_addr_hi
);
283 pa
= ((uint64_t) pa_hi
<< 32) | pa_lo
;
284 cpu_physical_memory_write(pa
, sense_ptr
, sense_len
);
285 cmd
->frame
->header
.sense_len
= sense_len
;
290 static void megasas_write_sense(MegasasCmd
*cmd
, SCSISense sense
)
292 uint8_t sense_buf
[SCSI_SENSE_BUF_SIZE
];
293 uint8_t sense_len
= 18;
295 memset(sense_buf
, 0, sense_len
);
297 sense_buf
[2] = sense
.key
;
299 sense_buf
[12] = sense
.asc
;
300 sense_buf
[13] = sense
.ascq
;
301 megasas_build_sense(cmd
, sense_buf
, sense_len
);
304 static void megasas_copy_sense(MegasasCmd
*cmd
)
306 uint8_t sense_buf
[SCSI_SENSE_BUF_SIZE
];
309 sense_len
= scsi_req_get_sense(cmd
->req
, sense_buf
,
310 SCSI_SENSE_BUF_SIZE
);
311 megasas_build_sense(cmd
, sense_buf
, sense_len
);
315 * Format an INQUIRY CDB
317 static int megasas_setup_inquiry(uint8_t *cdb
, int pg
, int len
)
325 cdb
[3] = (len
>> 8) & 0xff;
326 cdb
[4] = (len
& 0xff);
331 * Encode lba and len into a READ_16/WRITE_16 CDB
333 static void megasas_encode_lba(uint8_t *cdb
, uint64_t lba
,
334 uint32_t len
, bool is_write
)
336 memset(cdb
, 0x0, 16);
342 cdb
[2] = (lba
>> 56) & 0xff;
343 cdb
[3] = (lba
>> 48) & 0xff;
344 cdb
[4] = (lba
>> 40) & 0xff;
345 cdb
[5] = (lba
>> 32) & 0xff;
346 cdb
[6] = (lba
>> 24) & 0xff;
347 cdb
[7] = (lba
>> 16) & 0xff;
348 cdb
[8] = (lba
>> 8) & 0xff;
349 cdb
[9] = (lba
) & 0xff;
350 cdb
[10] = (len
>> 24) & 0xff;
351 cdb
[11] = (len
>> 16) & 0xff;
352 cdb
[12] = (len
>> 8) & 0xff;
353 cdb
[13] = (len
) & 0xff;
359 static uint64_t megasas_fw_time(void)
364 qemu_get_timedate(&curtime
, 0);
365 bcd_time
= ((uint64_t)curtime
.tm_sec
& 0xff) << 48 |
366 ((uint64_t)curtime
.tm_min
& 0xff) << 40 |
367 ((uint64_t)curtime
.tm_hour
& 0xff) << 32 |
368 ((uint64_t)curtime
.tm_mday
& 0xff) << 24 |
369 ((uint64_t)curtime
.tm_mon
& 0xff) << 16 |
370 ((uint64_t)(curtime
.tm_year
+ 1900) & 0xffff);
375 static uint64_t megasas_gen_sas_addr(uint64_t id
)
379 addr
= 0x5001a4aULL
<< 36;
380 addr
|= id
& 0xfffffffff;
388 static int megasas_next_index(MegasasState
*s
, int index
, int limit
)
391 if (index
== limit
) {
397 static MegasasCmd
*megasas_lookup_frame(MegasasState
*s
,
398 target_phys_addr_t frame
)
400 MegasasCmd
*cmd
= NULL
;
403 index
= s
->reply_queue_head
;
405 while (num
< s
->fw_cmds
) {
406 if (s
->frames
[index
].pa
&& s
->frames
[index
].pa
== frame
) {
407 cmd
= &s
->frames
[index
];
410 index
= megasas_next_index(s
, index
, s
->fw_cmds
);
417 static MegasasCmd
*megasas_next_frame(MegasasState
*s
,
418 target_phys_addr_t frame
)
420 MegasasCmd
*cmd
= NULL
;
423 cmd
= megasas_lookup_frame(s
, frame
);
425 trace_megasas_qf_found(cmd
->index
, cmd
->pa
);
428 index
= s
->reply_queue_head
;
430 while (num
< s
->fw_cmds
) {
431 if (!s
->frames
[index
].pa
) {
432 cmd
= &s
->frames
[index
];
435 index
= megasas_next_index(s
, index
, s
->fw_cmds
);
439 trace_megasas_qf_failed(frame
);
441 trace_megasas_qf_new(index
, cmd
);
445 static MegasasCmd
*megasas_enqueue_frame(MegasasState
*s
,
446 target_phys_addr_t frame
, uint64_t context
, int count
)
448 MegasasCmd
*cmd
= NULL
;
449 int frame_size
= MFI_FRAME_SIZE
* 16;
450 target_phys_addr_t frame_size_p
= frame_size
;
452 cmd
= megasas_next_frame(s
, frame
);
453 /* All frames busy */
459 /* Map all possible frames */
460 cmd
->frame
= cpu_physical_memory_map(frame
, &frame_size_p
, 0);
461 if (frame_size_p
!= frame_size
) {
462 trace_megasas_qf_map_failed(cmd
->index
, (unsigned long)frame
);
464 cpu_physical_memory_unmap(cmd
->frame
, frame_size_p
, 0, 0);
471 cmd
->pa_size
= frame_size_p
;
472 cmd
->context
= context
;
473 if (!megasas_use_queue64(s
)) {
474 cmd
->context
&= (uint64_t)0xFFFFFFFF;
480 trace_megasas_qf_enqueue(cmd
->index
, cmd
->count
, cmd
->context
,
481 s
->reply_queue_head
, s
->busy
);
486 static void megasas_complete_frame(MegasasState
*s
, uint64_t context
)
488 int tail
, queue_offset
;
490 /* Decrement busy count */
493 if (s
->reply_queue_pa
) {
495 * Put command on the reply queue.
496 * Context is opaque, but emulation is running in
497 * little endian. So convert it.
499 tail
= s
->reply_queue_head
;
500 if (megasas_use_queue64(s
)) {
501 queue_offset
= tail
* sizeof(uint64_t);
502 stq_le_phys(s
->reply_queue_pa
+ queue_offset
, context
);
504 queue_offset
= tail
* sizeof(uint32_t);
505 stl_le_phys(s
->reply_queue_pa
+ queue_offset
, context
);
507 s
->reply_queue_head
= megasas_next_index(s
, tail
, s
->fw_cmds
);
508 trace_megasas_qf_complete(context
, tail
, queue_offset
,
509 s
->busy
, s
->doorbell
);
512 if (megasas_intr_enabled(s
)) {
515 if (s
->doorbell
== 1) {
516 if (msix_enabled(&s
->dev
)) {
517 trace_megasas_msix_raise(0);
518 msix_notify(&s
->dev
, 0);
520 trace_megasas_irq_raise();
521 qemu_irq_raise(s
->dev
.irq
[0]);
525 trace_megasas_qf_complete_noirq(context
);
529 static void megasas_reset_frames(MegasasState
*s
)
534 for (i
= 0; i
< s
->fw_cmds
; i
++) {
537 cpu_physical_memory_unmap(cmd
->frame
, cmd
->pa_size
, 0, 0);
544 static void megasas_abort_command(MegasasCmd
*cmd
)
547 scsi_req_abort(cmd
->req
, ABORTED_COMMAND
);
552 static int megasas_init_firmware(MegasasState
*s
, MegasasCmd
*cmd
)
554 uint32_t pa_hi
, pa_lo
;
555 target_phys_addr_t iq_pa
, initq_size
;
556 struct mfi_init_qinfo
*initq
;
558 int ret
= MFI_STAT_OK
;
560 pa_lo
= le32_to_cpu(cmd
->frame
->init
.qinfo_new_addr_lo
);
561 pa_hi
= le32_to_cpu(cmd
->frame
->init
.qinfo_new_addr_hi
);
562 iq_pa
= (((uint64_t) pa_hi
<< 32) | pa_lo
);
563 trace_megasas_init_firmware((uint64_t)iq_pa
);
564 initq_size
= sizeof(*initq
);
565 initq
= cpu_physical_memory_map(iq_pa
, &initq_size
, 0);
566 if (!initq
|| initq_size
!= sizeof(*initq
)) {
567 trace_megasas_initq_map_failed(cmd
->index
);
569 ret
= MFI_STAT_MEMORY_NOT_AVAILABLE
;
572 s
->reply_queue_len
= le32_to_cpu(initq
->rq_entries
) & 0xFFFF;
573 if (s
->reply_queue_len
> s
->fw_cmds
) {
574 trace_megasas_initq_mismatch(s
->reply_queue_len
, s
->fw_cmds
);
576 ret
= MFI_STAT_INVALID_PARAMETER
;
579 pa_lo
= le32_to_cpu(initq
->rq_addr_lo
);
580 pa_hi
= le32_to_cpu(initq
->rq_addr_hi
);
581 s
->reply_queue_pa
= ((uint64_t) pa_hi
<< 32) | pa_lo
;
582 pa_lo
= le32_to_cpu(initq
->ci_addr_lo
);
583 pa_hi
= le32_to_cpu(initq
->ci_addr_hi
);
584 s
->consumer_pa
= ((uint64_t) pa_hi
<< 32) | pa_lo
;
585 pa_lo
= le32_to_cpu(initq
->pi_addr_lo
);
586 pa_hi
= le32_to_cpu(initq
->pi_addr_hi
);
587 s
->producer_pa
= ((uint64_t) pa_hi
<< 32) | pa_lo
;
588 s
->reply_queue_head
= ldl_le_phys(s
->producer_pa
);
589 s
->reply_queue_tail
= ldl_le_phys(s
->consumer_pa
);
590 flags
= le32_to_cpu(initq
->flags
);
591 if (flags
& MFI_QUEUE_FLAG_CONTEXT64
) {
592 s
->flags
|= MEGASAS_MASK_USE_QUEUE64
;
594 trace_megasas_init_queue((unsigned long)s
->reply_queue_pa
,
595 s
->reply_queue_len
, s
->reply_queue_head
,
596 s
->reply_queue_tail
, flags
);
597 megasas_reset_frames(s
);
598 s
->fw_state
= MFI_FWSTATE_OPERATIONAL
;
601 cpu_physical_memory_unmap(initq
, initq_size
, 0, 0);
606 static int megasas_map_dcmd(MegasasState
*s
, MegasasCmd
*cmd
)
608 dma_addr_t iov_pa
, iov_size
;
610 cmd
->flags
= le16_to_cpu(cmd
->frame
->header
.flags
);
611 if (!cmd
->frame
->header
.sge_count
) {
612 trace_megasas_dcmd_zero_sge(cmd
->index
);
615 } else if (cmd
->frame
->header
.sge_count
> 1) {
616 trace_megasas_dcmd_invalid_sge(cmd
->index
,
617 cmd
->frame
->header
.sge_count
);
621 iov_pa
= megasas_sgl_get_addr(cmd
, &cmd
->frame
->dcmd
.sgl
);
622 iov_size
= megasas_sgl_get_len(cmd
, &cmd
->frame
->dcmd
.sgl
);
623 qemu_sglist_init(&cmd
->qsg
, 1, pci_dma_context(&s
->dev
));
624 qemu_sglist_add(&cmd
->qsg
, iov_pa
, iov_size
);
625 cmd
->iov_size
= iov_size
;
626 return cmd
->iov_size
;
629 static void megasas_finish_dcmd(MegasasCmd
*cmd
, uint32_t iov_size
)
631 trace_megasas_finish_dcmd(cmd
->index
, iov_size
);
633 if (cmd
->frame
->header
.sge_count
) {
634 qemu_sglist_destroy(&cmd
->qsg
);
636 if (iov_size
> cmd
->iov_size
) {
637 if (megasas_frame_is_ieee_sgl(cmd
)) {
638 cmd
->frame
->dcmd
.sgl
.sg_skinny
->len
= cpu_to_le32(iov_size
);
639 } else if (megasas_frame_is_sgl64(cmd
)) {
640 cmd
->frame
->dcmd
.sgl
.sg64
->len
= cpu_to_le32(iov_size
);
642 cmd
->frame
->dcmd
.sgl
.sg32
->len
= cpu_to_le32(iov_size
);
649 static int megasas_ctrl_get_info(MegasasState
*s
, MegasasCmd
*cmd
)
651 struct mfi_ctrl_info info
;
652 size_t dcmd_size
= sizeof(info
);
654 int num_ld_disks
= 0;
656 QTAILQ_FOREACH(kid
, &s
->bus
.qbus
.children
, sibling
) {
660 memset(&info
, 0x0, cmd
->iov_size
);
661 if (cmd
->iov_size
< dcmd_size
) {
662 trace_megasas_dcmd_invalid_xfer_len(cmd
->index
, cmd
->iov_size
,
664 return MFI_STAT_INVALID_PARAMETER
;
667 info
.pci
.vendor
= cpu_to_le16(PCI_VENDOR_ID_LSI_LOGIC
);
668 info
.pci
.device
= cpu_to_le16(PCI_DEVICE_ID_LSI_SAS1078
);
669 info
.pci
.subvendor
= cpu_to_le16(PCI_VENDOR_ID_LSI_LOGIC
);
670 info
.pci
.subdevice
= cpu_to_le16(0x1013);
672 info
.host
.type
= MFI_INFO_HOST_PCIX
;
673 info
.device
.type
= MFI_INFO_DEV_SAS3G
;
674 info
.device
.port_count
= 2;
675 info
.device
.port_addr
[0] = cpu_to_le64(megasas_gen_sas_addr((uint64_t)s
));
677 memcpy(info
.product_name
, "MegaRAID SAS 8708EM2", 20);
678 snprintf(info
.serial_number
, 32, "QEMU%08lx",
679 (unsigned long)s
& 0xFFFFFFFF);
680 snprintf(info
.package_version
, 0x60, "%s-QEMU", QEMU_VERSION
);
681 memcpy(info
.image_component
[0].name
, "APP", 3);
682 memcpy(info
.image_component
[0].version
, MEGASAS_VERSION
"-QEMU", 9);
683 memcpy(info
.image_component
[0].build_date
, __DATE__
, 11);
684 memcpy(info
.image_component
[0].build_time
, __TIME__
, 8);
685 info
.image_component_count
= 1;
686 if (s
->dev
.has_rom
) {
690 ptr
= memory_region_get_ram_ptr(&s
->dev
.rom
);
691 memcpy(biosver
, ptr
+ 0x41, 31);
692 qemu_put_ram_ptr(ptr
);
693 memcpy(info
.image_component
[1].name
, "BIOS", 4);
694 memcpy(info
.image_component
[1].version
, biosver
,
695 strlen((const char *)biosver
));
696 info
.image_component_count
++;
698 info
.current_fw_time
= cpu_to_le32(megasas_fw_time());
701 info
.max_arrays
= MEGASAS_MAX_ARRAYS
;
702 info
.max_lds
= s
->fw_luns
;
703 info
.max_cmds
= cpu_to_le16(s
->fw_cmds
);
704 info
.max_sg_elements
= cpu_to_le16(s
->fw_sge
);
705 info
.max_request_size
= cpu_to_le32(MEGASAS_MAX_SECTORS
);
706 info
.lds_present
= cpu_to_le16(num_ld_disks
);
707 info
.pd_present
= cpu_to_le16(num_ld_disks
);
708 info
.pd_disks_present
= cpu_to_le16(num_ld_disks
);
709 info
.hw_present
= cpu_to_le32(MFI_INFO_HW_NVRAM
|
712 info
.memory_size
= cpu_to_le16(512);
713 info
.nvram_size
= cpu_to_le16(32);
714 info
.flash_size
= cpu_to_le16(16);
715 info
.raid_levels
= cpu_to_le32(MFI_INFO_RAID_0
);
716 info
.adapter_ops
= cpu_to_le32(MFI_INFO_AOPS_RBLD_RATE
|
717 MFI_INFO_AOPS_SELF_DIAGNOSTIC
|
718 MFI_INFO_AOPS_MIXED_ARRAY
);
719 info
.ld_ops
= cpu_to_le32(MFI_INFO_LDOPS_DISK_CACHE_POLICY
|
720 MFI_INFO_LDOPS_ACCESS_POLICY
|
721 MFI_INFO_LDOPS_IO_POLICY
|
722 MFI_INFO_LDOPS_WRITE_POLICY
|
723 MFI_INFO_LDOPS_READ_POLICY
);
724 info
.max_strips_per_io
= cpu_to_le16(s
->fw_sge
);
725 info
.stripe_sz_ops
.min
= 3;
726 info
.stripe_sz_ops
.max
= ffs(MEGASAS_MAX_SECTORS
+ 1) - 1;
727 info
.properties
.pred_fail_poll_interval
= cpu_to_le16(300);
728 info
.properties
.intr_throttle_cnt
= cpu_to_le16(16);
729 info
.properties
.intr_throttle_timeout
= cpu_to_le16(50);
730 info
.properties
.rebuild_rate
= 30;
731 info
.properties
.patrol_read_rate
= 30;
732 info
.properties
.bgi_rate
= 30;
733 info
.properties
.cc_rate
= 30;
734 info
.properties
.recon_rate
= 30;
735 info
.properties
.cache_flush_interval
= 4;
736 info
.properties
.spinup_drv_cnt
= 2;
737 info
.properties
.spinup_delay
= 6;
738 info
.properties
.ecc_bucket_size
= 15;
739 info
.properties
.ecc_bucket_leak_rate
= cpu_to_le16(1440);
740 info
.properties
.expose_encl_devices
= 1;
741 info
.properties
.OnOffProperties
= cpu_to_le32(MFI_CTRL_PROP_EnableJBOD
);
742 info
.pd_ops
= cpu_to_le32(MFI_INFO_PDOPS_FORCE_ONLINE
|
743 MFI_INFO_PDOPS_FORCE_OFFLINE
);
744 info
.pd_mix_support
= cpu_to_le32(MFI_INFO_PDMIX_SAS
|
745 MFI_INFO_PDMIX_SATA
|
748 cmd
->iov_size
-= dma_buf_read((uint8_t *)&info
, dcmd_size
, &cmd
->qsg
);
752 static int megasas_mfc_get_defaults(MegasasState
*s
, MegasasCmd
*cmd
)
754 struct mfi_defaults info
;
755 size_t dcmd_size
= sizeof(struct mfi_defaults
);
757 memset(&info
, 0x0, dcmd_size
);
758 if (cmd
->iov_size
< dcmd_size
) {
759 trace_megasas_dcmd_invalid_xfer_len(cmd
->index
, cmd
->iov_size
,
761 return MFI_STAT_INVALID_PARAMETER
;
764 info
.sas_addr
= cpu_to_le64(megasas_gen_sas_addr((uint64_t)s
));
765 info
.stripe_size
= 3;
767 info
.background_rate
= 30;
768 info
.allow_mix_in_enclosure
= 1;
769 info
.allow_mix_in_ld
= 1;
770 info
.direct_pd_mapping
= 1;
771 /* Enable for BIOS support */
772 info
.bios_enumerate_lds
= 1;
773 info
.disable_ctrl_r
= 1;
774 info
.expose_enclosure_devices
= 1;
775 info
.disable_preboot_cli
= 1;
776 info
.cluster_disable
= 1;
778 cmd
->iov_size
-= dma_buf_read((uint8_t *)&info
, dcmd_size
, &cmd
->qsg
);
782 static int megasas_dcmd_get_bios_info(MegasasState
*s
, MegasasCmd
*cmd
)
784 struct mfi_bios_data info
;
785 size_t dcmd_size
= sizeof(info
);
787 memset(&info
, 0x0, dcmd_size
);
788 if (cmd
->iov_size
< dcmd_size
) {
789 trace_megasas_dcmd_invalid_xfer_len(cmd
->index
, cmd
->iov_size
,
791 return MFI_STAT_INVALID_PARAMETER
;
793 info
.continue_on_error
= 1;
795 if (megasas_is_jbod(s
)) {
796 info
.expose_all_drives
= 1;
799 cmd
->iov_size
-= dma_buf_read((uint8_t *)&info
, dcmd_size
, &cmd
->qsg
);
803 static int megasas_dcmd_get_fw_time(MegasasState
*s
, MegasasCmd
*cmd
)
806 size_t dcmd_size
= sizeof(fw_time
);
808 fw_time
= cpu_to_le64(megasas_fw_time());
810 cmd
->iov_size
-= dma_buf_read((uint8_t *)&fw_time
, dcmd_size
, &cmd
->qsg
);
814 static int megasas_dcmd_set_fw_time(MegasasState
*s
, MegasasCmd
*cmd
)
818 /* This is a dummy; setting of firmware time is not allowed */
819 memcpy(&fw_time
, cmd
->frame
->dcmd
.mbox
, sizeof(fw_time
));
821 trace_megasas_dcmd_set_fw_time(cmd
->index
, fw_time
);
822 fw_time
= cpu_to_le64(megasas_fw_time());
826 static int megasas_event_info(MegasasState
*s
, MegasasCmd
*cmd
)
828 struct mfi_evt_log_state info
;
829 size_t dcmd_size
= sizeof(info
);
831 memset(&info
, 0, dcmd_size
);
833 info
.newest_seq_num
= cpu_to_le32(s
->event_count
);
834 info
.shutdown_seq_num
= cpu_to_le32(s
->shutdown_event
);
835 info
.boot_seq_num
= cpu_to_le32(s
->boot_event
);
837 cmd
->iov_size
-= dma_buf_read((uint8_t *)&info
, dcmd_size
, &cmd
->qsg
);
841 static int megasas_event_wait(MegasasState
*s
, MegasasCmd
*cmd
)
845 if (cmd
->iov_size
< sizeof(struct mfi_evt_detail
)) {
846 trace_megasas_dcmd_invalid_xfer_len(cmd
->index
, cmd
->iov_size
,
847 sizeof(struct mfi_evt_detail
));
848 return MFI_STAT_INVALID_PARAMETER
;
850 s
->event_count
= cpu_to_le32(cmd
->frame
->dcmd
.mbox
[0]);
851 event
.word
= cpu_to_le32(cmd
->frame
->dcmd
.mbox
[4]);
852 s
->event_locale
= event
.members
.locale
;
853 s
->event_class
= event
.members
.class;
855 /* Decrease busy count; event frame doesn't count here */
857 cmd
->iov_size
= sizeof(struct mfi_evt_detail
);
858 return MFI_STAT_INVALID_STATUS
;
861 static int megasas_dcmd_pd_get_list(MegasasState
*s
, MegasasCmd
*cmd
)
863 struct mfi_pd_list info
;
864 size_t dcmd_size
= sizeof(info
);
866 uint32_t offset
, dcmd_limit
, num_pd_disks
= 0, max_pd_disks
;
869 memset(&info
, 0, dcmd_size
);
871 dcmd_limit
= offset
+ sizeof(struct mfi_pd_address
);
872 if (cmd
->iov_size
< dcmd_limit
) {
873 trace_megasas_dcmd_invalid_xfer_len(cmd
->index
, cmd
->iov_size
,
875 return MFI_STAT_INVALID_PARAMETER
;
878 max_pd_disks
= (cmd
->iov_size
- offset
) / sizeof(struct mfi_pd_address
);
879 if (max_pd_disks
> s
->fw_luns
) {
880 max_pd_disks
= s
->fw_luns
;
883 QTAILQ_FOREACH(kid
, &s
->bus
.qbus
.children
, sibling
) {
884 SCSIDevice
*sdev
= DO_UPCAST(SCSIDevice
, qdev
, kid
->child
);
886 sdev_id
= ((sdev
->id
& 0xFF) >> 8) | (sdev
->lun
& 0xFF);
887 info
.addr
[num_pd_disks
].device_id
= cpu_to_le16(sdev_id
);
888 info
.addr
[num_pd_disks
].encl_device_id
= 0xFFFF;
889 info
.addr
[num_pd_disks
].encl_index
= 0;
890 info
.addr
[num_pd_disks
].slot_number
= (sdev
->id
& 0xFF);
891 info
.addr
[num_pd_disks
].scsi_dev_type
= sdev
->type
;
892 info
.addr
[num_pd_disks
].connect_port_bitmap
= 0x1;
893 info
.addr
[num_pd_disks
].sas_addr
[0] =
894 cpu_to_le64(megasas_gen_sas_addr((uint64_t)sdev
));
896 offset
+= sizeof(struct mfi_pd_address
);
898 trace_megasas_dcmd_pd_get_list(cmd
->index
, num_pd_disks
,
899 max_pd_disks
, offset
);
901 info
.size
= cpu_to_le32(offset
);
902 info
.count
= cpu_to_le32(num_pd_disks
);
904 cmd
->iov_size
-= dma_buf_read((uint8_t *)&info
, offset
, &cmd
->qsg
);
908 static int megasas_dcmd_pd_list_query(MegasasState
*s
, MegasasCmd
*cmd
)
912 /* mbox0 contains flags */
913 flags
= le16_to_cpu(cmd
->frame
->dcmd
.mbox
[0]);
914 trace_megasas_dcmd_pd_list_query(cmd
->index
, flags
);
915 if (flags
== MR_PD_QUERY_TYPE_ALL
||
916 megasas_is_jbod(s
)) {
917 return megasas_dcmd_pd_get_list(s
, cmd
);
923 static int megasas_pd_get_info_submit(SCSIDevice
*sdev
, int lun
,
926 struct mfi_pd_info
*info
= cmd
->iov_buf
;
927 size_t dcmd_size
= sizeof(struct mfi_pd_info
);
928 BlockConf
*conf
= &sdev
->conf
;
930 uint16_t sdev_id
= ((sdev
->id
& 0xFF) >> 8) | (lun
& 0xFF);
936 cmd
->iov_buf
= g_malloc(dcmd_size
);
937 memset(cmd
->iov_buf
, 0, dcmd_size
);
939 info
->inquiry_data
[0] = 0x7f; /* Force PQual 0x3, PType 0x1f */
940 info
->vpd_page83
[0] = 0x7f;
941 megasas_setup_inquiry(cmdbuf
, 0, sizeof(info
->inquiry_data
));
942 req
= scsi_req_new(sdev
, cmd
->index
, lun
, cmdbuf
, cmd
);
944 trace_megasas_dcmd_req_alloc_failed(cmd
->index
,
945 "PD get info std inquiry");
946 g_free(cmd
->iov_buf
);
948 return MFI_STAT_FLASH_ALLOC_FAIL
;
950 trace_megasas_dcmd_internal_submit(cmd
->index
,
951 "PD get info std inquiry", lun
);
952 len
= scsi_req_enqueue(req
);
955 scsi_req_continue(req
);
957 return MFI_STAT_INVALID_STATUS
;
958 } else if (info
->inquiry_data
[0] != 0x7f && info
->vpd_page83
[0] == 0x7f) {
959 megasas_setup_inquiry(cmdbuf
, 0x83, sizeof(info
->vpd_page83
));
960 req
= scsi_req_new(sdev
, cmd
->index
, lun
, cmdbuf
, cmd
);
962 trace_megasas_dcmd_req_alloc_failed(cmd
->index
,
963 "PD get info vpd inquiry");
964 return MFI_STAT_FLASH_ALLOC_FAIL
;
966 trace_megasas_dcmd_internal_submit(cmd
->index
,
967 "PD get info vpd inquiry", lun
);
968 len
= scsi_req_enqueue(req
);
971 scsi_req_continue(req
);
973 return MFI_STAT_INVALID_STATUS
;
975 /* Finished, set FW state */
976 if ((info
->inquiry_data
[0] >> 5) == 0) {
977 if (megasas_is_jbod(cmd
->state
)) {
978 info
->fw_state
= cpu_to_le16(MFI_PD_STATE_SYSTEM
);
980 info
->fw_state
= cpu_to_le16(MFI_PD_STATE_ONLINE
);
983 info
->fw_state
= cpu_to_le16(MFI_PD_STATE_OFFLINE
);
986 info
->ref
.v
.device_id
= cpu_to_le16(sdev_id
);
987 info
->state
.ddf
.pd_type
= cpu_to_le16(MFI_PD_DDF_TYPE_IN_VD
|
988 MFI_PD_DDF_TYPE_INTF_SAS
);
989 bdrv_get_geometry(conf
->bs
, &pd_size
);
990 info
->raw_size
= cpu_to_le64(pd_size
);
991 info
->non_coerced_size
= cpu_to_le64(pd_size
);
992 info
->coerced_size
= cpu_to_le64(pd_size
);
993 info
->encl_device_id
= 0xFFFF;
994 info
->slot_number
= (sdev
->id
& 0xFF);
995 info
->path_info
.count
= 1;
996 info
->path_info
.sas_addr
[0] =
997 cpu_to_le64(megasas_gen_sas_addr((uint64_t)sdev
));
998 info
->connected_port_bitmap
= 0x1;
999 info
->device_speed
= 1;
1000 info
->link_speed
= 1;
1001 resid
= dma_buf_read(cmd
->iov_buf
, dcmd_size
, &cmd
->qsg
);
1002 g_free(cmd
->iov_buf
);
1003 cmd
->iov_size
= dcmd_size
- resid
;
1004 cmd
->iov_buf
= NULL
;
1008 static int megasas_dcmd_pd_get_info(MegasasState
*s
, MegasasCmd
*cmd
)
1010 size_t dcmd_size
= sizeof(struct mfi_pd_info
);
1012 SCSIDevice
*sdev
= NULL
;
1013 int retval
= MFI_STAT_DEVICE_NOT_FOUND
;
1015 if (cmd
->iov_size
< dcmd_size
) {
1016 return MFI_STAT_INVALID_PARAMETER
;
1019 /* mbox0 has the ID */
1020 pd_id
= le16_to_cpu(cmd
->frame
->dcmd
.mbox
[0]);
1021 sdev
= scsi_device_find(&s
->bus
, 0, pd_id
, 0);
1022 trace_megasas_dcmd_pd_get_info(cmd
->index
, pd_id
);
1025 /* Submit inquiry */
1026 retval
= megasas_pd_get_info_submit(sdev
, pd_id
, cmd
);
1032 static int megasas_dcmd_ld_get_list(MegasasState
*s
, MegasasCmd
*cmd
)
1034 struct mfi_ld_list info
;
1035 size_t dcmd_size
= sizeof(info
), resid
;
1036 uint32_t num_ld_disks
= 0, max_ld_disks
= s
->fw_luns
;
1040 memset(&info
, 0, dcmd_size
);
1041 if (cmd
->iov_size
< dcmd_size
) {
1042 trace_megasas_dcmd_invalid_xfer_len(cmd
->index
, cmd
->iov_size
,
1044 return MFI_STAT_INVALID_PARAMETER
;
1047 if (megasas_is_jbod(s
)) {
1050 QTAILQ_FOREACH(kid
, &s
->bus
.qbus
.children
, sibling
) {
1051 SCSIDevice
*sdev
= DO_UPCAST(SCSIDevice
, qdev
, kid
->child
);
1052 BlockConf
*conf
= &sdev
->conf
;
1054 if (num_ld_disks
>= max_ld_disks
) {
1057 /* Logical device size is in blocks */
1058 bdrv_get_geometry(conf
->bs
, &ld_size
);
1059 info
.ld_list
[num_ld_disks
].ld
.v
.target_id
= sdev
->id
;
1060 info
.ld_list
[num_ld_disks
].state
= MFI_LD_STATE_OPTIMAL
;
1061 info
.ld_list
[num_ld_disks
].size
= cpu_to_le64(ld_size
);
1064 info
.ld_count
= cpu_to_le32(num_ld_disks
);
1065 trace_megasas_dcmd_ld_get_list(cmd
->index
, num_ld_disks
, max_ld_disks
);
1067 resid
= dma_buf_read((uint8_t *)&info
, dcmd_size
, &cmd
->qsg
);
1068 cmd
->iov_size
= dcmd_size
- resid
;
1072 static int megasas_ld_get_info_submit(SCSIDevice
*sdev
, int lun
,
1075 struct mfi_ld_info
*info
= cmd
->iov_buf
;
1076 size_t dcmd_size
= sizeof(struct mfi_ld_info
);
1080 BlockConf
*conf
= &sdev
->conf
;
1081 uint16_t sdev_id
= ((sdev
->id
& 0xFF) >> 8) | (lun
& 0xFF);
1084 if (!cmd
->iov_buf
) {
1085 cmd
->iov_buf
= g_malloc(dcmd_size
);
1086 memset(cmd
->iov_buf
, 0x0, dcmd_size
);
1087 info
= cmd
->iov_buf
;
1088 megasas_setup_inquiry(cdb
, 0x83, sizeof(info
->vpd_page83
));
1089 req
= scsi_req_new(sdev
, cmd
->index
, lun
, cdb
, cmd
);
1091 trace_megasas_dcmd_req_alloc_failed(cmd
->index
,
1092 "LD get info vpd inquiry");
1093 g_free(cmd
->iov_buf
);
1094 cmd
->iov_buf
= NULL
;
1095 return MFI_STAT_FLASH_ALLOC_FAIL
;
1097 trace_megasas_dcmd_internal_submit(cmd
->index
,
1098 "LD get info vpd inquiry", lun
);
1099 len
= scsi_req_enqueue(req
);
1101 cmd
->iov_size
= len
;
1102 scsi_req_continue(req
);
1104 return MFI_STAT_INVALID_STATUS
;
1107 info
->ld_config
.params
.state
= MFI_LD_STATE_OPTIMAL
;
1108 info
->ld_config
.properties
.ld
.v
.target_id
= lun
;
1109 info
->ld_config
.params
.stripe_size
= 3;
1110 info
->ld_config
.params
.num_drives
= 1;
1111 info
->ld_config
.params
.is_consistent
= 1;
1112 /* Logical device size is in blocks */
1113 bdrv_get_geometry(conf
->bs
, &ld_size
);
1114 info
->size
= cpu_to_le64(ld_size
);
1115 memset(info
->ld_config
.span
, 0, sizeof(info
->ld_config
.span
));
1116 info
->ld_config
.span
[0].start_block
= 0;
1117 info
->ld_config
.span
[0].num_blocks
= info
->size
;
1118 info
->ld_config
.span
[0].array_ref
= cpu_to_le16(sdev_id
);
1120 resid
= dma_buf_read(cmd
->iov_buf
, dcmd_size
, &cmd
->qsg
);
1121 g_free(cmd
->iov_buf
);
1122 cmd
->iov_size
= dcmd_size
- resid
;
1123 cmd
->iov_buf
= NULL
;
1127 static int megasas_dcmd_ld_get_info(MegasasState
*s
, MegasasCmd
*cmd
)
1129 struct mfi_ld_info info
;
1130 size_t dcmd_size
= sizeof(info
);
1132 uint32_t max_ld_disks
= s
->fw_luns
;
1133 SCSIDevice
*sdev
= NULL
;
1134 int retval
= MFI_STAT_DEVICE_NOT_FOUND
;
1136 if (cmd
->iov_size
< dcmd_size
) {
1137 return MFI_STAT_INVALID_PARAMETER
;
1140 /* mbox0 has the ID */
1141 ld_id
= le16_to_cpu(cmd
->frame
->dcmd
.mbox
[0]);
1142 trace_megasas_dcmd_ld_get_info(cmd
->index
, ld_id
);
1144 if (megasas_is_jbod(s
)) {
1145 return MFI_STAT_DEVICE_NOT_FOUND
;
1148 if (ld_id
< max_ld_disks
) {
1149 sdev
= scsi_device_find(&s
->bus
, 0, ld_id
, 0);
1153 retval
= megasas_ld_get_info_submit(sdev
, ld_id
, cmd
);
1159 static int megasas_dcmd_cfg_read(MegasasState
*s
, MegasasCmd
*cmd
)
1162 struct mfi_config_data
*info
;
1163 int num_pd_disks
= 0, array_offset
, ld_offset
;
1166 if (cmd
->iov_size
> 4096) {
1167 return MFI_STAT_INVALID_PARAMETER
;
1170 QTAILQ_FOREACH(kid
, &s
->bus
.qbus
.children
, sibling
) {
1173 info
= (struct mfi_config_data
*)&data
;
1176 * - One array per SCSI device
1177 * - One logical drive per SCSI device
1178 * spanning the entire device
1180 info
->array_count
= num_pd_disks
;
1181 info
->array_size
= sizeof(struct mfi_array
) * num_pd_disks
;
1182 info
->log_drv_count
= num_pd_disks
;
1183 info
->log_drv_size
= sizeof(struct mfi_ld_config
) * num_pd_disks
;
1184 info
->spares_count
= 0;
1185 info
->spares_size
= sizeof(struct mfi_spare
);
1186 info
->size
= sizeof(struct mfi_config_data
) + info
->array_size
+
1188 if (info
->size
> 4096) {
1189 return MFI_STAT_INVALID_PARAMETER
;
1192 array_offset
= sizeof(struct mfi_config_data
);
1193 ld_offset
= array_offset
+ sizeof(struct mfi_array
) * num_pd_disks
;
1195 QTAILQ_FOREACH(kid
, &s
->bus
.qbus
.children
, sibling
) {
1196 SCSIDevice
*sdev
= DO_UPCAST(SCSIDevice
, qdev
, kid
->child
);
1197 BlockConf
*conf
= &sdev
->conf
;
1198 uint16_t sdev_id
= ((sdev
->id
& 0xFF) >> 8) | (sdev
->lun
& 0xFF);
1199 struct mfi_array
*array
;
1200 struct mfi_ld_config
*ld
;
1204 array
= (struct mfi_array
*)(data
+ array_offset
);
1205 bdrv_get_geometry(conf
->bs
, &pd_size
);
1206 array
->size
= cpu_to_le64(pd_size
);
1207 array
->num_drives
= 1;
1208 array
->array_ref
= cpu_to_le16(sdev_id
);
1209 array
->pd
[0].ref
.v
.device_id
= cpu_to_le16(sdev_id
);
1210 array
->pd
[0].ref
.v
.seq_num
= 0;
1211 array
->pd
[0].fw_state
= MFI_PD_STATE_ONLINE
;
1212 array
->pd
[0].encl
.pd
= 0xFF;
1213 array
->pd
[0].encl
.slot
= (sdev
->id
& 0xFF);
1214 for (i
= 1; i
< MFI_MAX_ROW_SIZE
; i
++) {
1215 array
->pd
[i
].ref
.v
.device_id
= 0xFFFF;
1216 array
->pd
[i
].ref
.v
.seq_num
= 0;
1217 array
->pd
[i
].fw_state
= MFI_PD_STATE_UNCONFIGURED_GOOD
;
1218 array
->pd
[i
].encl
.pd
= 0xFF;
1219 array
->pd
[i
].encl
.slot
= 0xFF;
1221 array_offset
+= sizeof(struct mfi_array
);
1222 ld
= (struct mfi_ld_config
*)(data
+ ld_offset
);
1223 memset(ld
, 0, sizeof(struct mfi_ld_config
));
1224 ld
->properties
.ld
.v
.target_id
= (sdev
->id
& 0xFF);
1225 ld
->properties
.default_cache_policy
= MR_LD_CACHE_READ_AHEAD
|
1226 MR_LD_CACHE_READ_ADAPTIVE
;
1227 ld
->properties
.current_cache_policy
= MR_LD_CACHE_READ_AHEAD
|
1228 MR_LD_CACHE_READ_ADAPTIVE
;
1229 ld
->params
.state
= MFI_LD_STATE_OPTIMAL
;
1230 ld
->params
.stripe_size
= 3;
1231 ld
->params
.num_drives
= 1;
1232 ld
->params
.span_depth
= 1;
1233 ld
->params
.is_consistent
= 1;
1234 ld
->span
[0].start_block
= 0;
1235 ld
->span
[0].num_blocks
= cpu_to_le64(pd_size
);
1236 ld
->span
[0].array_ref
= cpu_to_le16(sdev_id
);
1237 ld_offset
+= sizeof(struct mfi_ld_config
);
1240 cmd
->iov_size
-= dma_buf_read((uint8_t *)data
, info
->size
, &cmd
->qsg
);
1244 static int megasas_dcmd_get_properties(MegasasState
*s
, MegasasCmd
*cmd
)
1246 struct mfi_ctrl_props info
;
1247 size_t dcmd_size
= sizeof(info
);
1249 memset(&info
, 0x0, dcmd_size
);
1250 if (cmd
->iov_size
< dcmd_size
) {
1251 trace_megasas_dcmd_invalid_xfer_len(cmd
->index
, cmd
->iov_size
,
1253 return MFI_STAT_INVALID_PARAMETER
;
1255 info
.pred_fail_poll_interval
= cpu_to_le16(300);
1256 info
.intr_throttle_cnt
= cpu_to_le16(16);
1257 info
.intr_throttle_timeout
= cpu_to_le16(50);
1258 info
.rebuild_rate
= 30;
1259 info
.patrol_read_rate
= 30;
1262 info
.recon_rate
= 30;
1263 info
.cache_flush_interval
= 4;
1264 info
.spinup_drv_cnt
= 2;
1265 info
.spinup_delay
= 6;
1266 info
.ecc_bucket_size
= 15;
1267 info
.ecc_bucket_leak_rate
= cpu_to_le16(1440);
1268 info
.expose_encl_devices
= 1;
1270 cmd
->iov_size
-= dma_buf_read((uint8_t *)&info
, dcmd_size
, &cmd
->qsg
);
1274 static int megasas_cache_flush(MegasasState
*s
, MegasasCmd
*cmd
)
1280 static int megasas_ctrl_shutdown(MegasasState
*s
, MegasasCmd
*cmd
)
1282 s
->fw_state
= MFI_FWSTATE_READY
;
1286 static int megasas_cluster_reset_ld(MegasasState
*s
, MegasasCmd
*cmd
)
1288 return MFI_STAT_INVALID_DCMD
;
1291 static int megasas_dcmd_set_properties(MegasasState
*s
, MegasasCmd
*cmd
)
1293 uint8_t *dummy
= g_malloc(cmd
->iov_size
);
1295 dma_buf_write(dummy
, cmd
->iov_size
, &cmd
->qsg
);
1297 trace_megasas_dcmd_dump_frame(0,
1298 dummy
[0x00], dummy
[0x01], dummy
[0x02], dummy
[0x03],
1299 dummy
[0x04], dummy
[0x05], dummy
[0x06], dummy
[0x07]);
1300 trace_megasas_dcmd_dump_frame(1,
1301 dummy
[0x08], dummy
[0x09], dummy
[0x0a], dummy
[0x0b],
1302 dummy
[0x0c], dummy
[0x0d], dummy
[0x0e], dummy
[0x0f]);
1303 trace_megasas_dcmd_dump_frame(2,
1304 dummy
[0x10], dummy
[0x11], dummy
[0x12], dummy
[0x13],
1305 dummy
[0x14], dummy
[0x15], dummy
[0x16], dummy
[0x17]);
1306 trace_megasas_dcmd_dump_frame(3,
1307 dummy
[0x18], dummy
[0x19], dummy
[0x1a], dummy
[0x1b],
1308 dummy
[0x1c], dummy
[0x1d], dummy
[0x1e], dummy
[0x1f]);
1309 trace_megasas_dcmd_dump_frame(4,
1310 dummy
[0x20], dummy
[0x21], dummy
[0x22], dummy
[0x23],
1311 dummy
[0x24], dummy
[0x25], dummy
[0x26], dummy
[0x27]);
1312 trace_megasas_dcmd_dump_frame(5,
1313 dummy
[0x28], dummy
[0x29], dummy
[0x2a], dummy
[0x2b],
1314 dummy
[0x2c], dummy
[0x2d], dummy
[0x2e], dummy
[0x2f]);
1315 trace_megasas_dcmd_dump_frame(6,
1316 dummy
[0x30], dummy
[0x31], dummy
[0x32], dummy
[0x33],
1317 dummy
[0x34], dummy
[0x35], dummy
[0x36], dummy
[0x37]);
1318 trace_megasas_dcmd_dump_frame(7,
1319 dummy
[0x38], dummy
[0x39], dummy
[0x3a], dummy
[0x3b],
1320 dummy
[0x3c], dummy
[0x3d], dummy
[0x3e], dummy
[0x3f]);
1325 static int megasas_dcmd_dummy(MegasasState
*s
, MegasasCmd
*cmd
)
1327 trace_megasas_dcmd_dummy(cmd
->index
, cmd
->iov_size
);
1331 static const struct dcmd_cmd_tbl_t
{
1334 int (*func
)(MegasasState
*s
, MegasasCmd
*cmd
);
1335 } dcmd_cmd_tbl
[] = {
1336 { MFI_DCMD_CTRL_MFI_HOST_MEM_ALLOC
, "CTRL_HOST_MEM_ALLOC",
1337 megasas_dcmd_dummy
},
1338 { MFI_DCMD_CTRL_GET_INFO
, "CTRL_GET_INFO",
1339 megasas_ctrl_get_info
},
1340 { MFI_DCMD_CTRL_GET_PROPERTIES
, "CTRL_GET_PROPERTIES",
1341 megasas_dcmd_get_properties
},
1342 { MFI_DCMD_CTRL_SET_PROPERTIES
, "CTRL_SET_PROPERTIES",
1343 megasas_dcmd_set_properties
},
1344 { MFI_DCMD_CTRL_ALARM_GET
, "CTRL_ALARM_GET",
1345 megasas_dcmd_dummy
},
1346 { MFI_DCMD_CTRL_ALARM_ENABLE
, "CTRL_ALARM_ENABLE",
1347 megasas_dcmd_dummy
},
1348 { MFI_DCMD_CTRL_ALARM_DISABLE
, "CTRL_ALARM_DISABLE",
1349 megasas_dcmd_dummy
},
1350 { MFI_DCMD_CTRL_ALARM_SILENCE
, "CTRL_ALARM_SILENCE",
1351 megasas_dcmd_dummy
},
1352 { MFI_DCMD_CTRL_ALARM_TEST
, "CTRL_ALARM_TEST",
1353 megasas_dcmd_dummy
},
1354 { MFI_DCMD_CTRL_EVENT_GETINFO
, "CTRL_EVENT_GETINFO",
1355 megasas_event_info
},
1356 { MFI_DCMD_CTRL_EVENT_GET
, "CTRL_EVENT_GET",
1357 megasas_dcmd_dummy
},
1358 { MFI_DCMD_CTRL_EVENT_WAIT
, "CTRL_EVENT_WAIT",
1359 megasas_event_wait
},
1360 { MFI_DCMD_CTRL_SHUTDOWN
, "CTRL_SHUTDOWN",
1361 megasas_ctrl_shutdown
},
1362 { MFI_DCMD_HIBERNATE_STANDBY
, "CTRL_STANDBY",
1363 megasas_dcmd_dummy
},
1364 { MFI_DCMD_CTRL_GET_TIME
, "CTRL_GET_TIME",
1365 megasas_dcmd_get_fw_time
},
1366 { MFI_DCMD_CTRL_SET_TIME
, "CTRL_SET_TIME",
1367 megasas_dcmd_set_fw_time
},
1368 { MFI_DCMD_CTRL_BIOS_DATA_GET
, "CTRL_BIOS_DATA_GET",
1369 megasas_dcmd_get_bios_info
},
1370 { MFI_DCMD_CTRL_FACTORY_DEFAULTS
, "CTRL_FACTORY_DEFAULTS",
1371 megasas_dcmd_dummy
},
1372 { MFI_DCMD_CTRL_MFC_DEFAULTS_GET
, "CTRL_MFC_DEFAULTS_GET",
1373 megasas_mfc_get_defaults
},
1374 { MFI_DCMD_CTRL_MFC_DEFAULTS_SET
, "CTRL_MFC_DEFAULTS_SET",
1375 megasas_dcmd_dummy
},
1376 { MFI_DCMD_CTRL_CACHE_FLUSH
, "CTRL_CACHE_FLUSH",
1377 megasas_cache_flush
},
1378 { MFI_DCMD_PD_GET_LIST
, "PD_GET_LIST",
1379 megasas_dcmd_pd_get_list
},
1380 { MFI_DCMD_PD_LIST_QUERY
, "PD_LIST_QUERY",
1381 megasas_dcmd_pd_list_query
},
1382 { MFI_DCMD_PD_GET_INFO
, "PD_GET_INFO",
1383 megasas_dcmd_pd_get_info
},
1384 { MFI_DCMD_PD_STATE_SET
, "PD_STATE_SET",
1385 megasas_dcmd_dummy
},
1386 { MFI_DCMD_PD_REBUILD
, "PD_REBUILD",
1387 megasas_dcmd_dummy
},
1388 { MFI_DCMD_PD_BLINK
, "PD_BLINK",
1389 megasas_dcmd_dummy
},
1390 { MFI_DCMD_PD_UNBLINK
, "PD_UNBLINK",
1391 megasas_dcmd_dummy
},
1392 { MFI_DCMD_LD_GET_LIST
, "LD_GET_LIST",
1393 megasas_dcmd_ld_get_list
},
1394 { MFI_DCMD_LD_GET_INFO
, "LD_GET_INFO",
1395 megasas_dcmd_ld_get_info
},
1396 { MFI_DCMD_LD_GET_PROP
, "LD_GET_PROP",
1397 megasas_dcmd_dummy
},
1398 { MFI_DCMD_LD_SET_PROP
, "LD_SET_PROP",
1399 megasas_dcmd_dummy
},
1400 { MFI_DCMD_LD_DELETE
, "LD_DELETE",
1401 megasas_dcmd_dummy
},
1402 { MFI_DCMD_CFG_READ
, "CFG_READ",
1403 megasas_dcmd_cfg_read
},
1404 { MFI_DCMD_CFG_ADD
, "CFG_ADD",
1405 megasas_dcmd_dummy
},
1406 { MFI_DCMD_CFG_CLEAR
, "CFG_CLEAR",
1407 megasas_dcmd_dummy
},
1408 { MFI_DCMD_CFG_FOREIGN_READ
, "CFG_FOREIGN_READ",
1409 megasas_dcmd_dummy
},
1410 { MFI_DCMD_CFG_FOREIGN_IMPORT
, "CFG_FOREIGN_IMPORT",
1411 megasas_dcmd_dummy
},
1412 { MFI_DCMD_BBU_STATUS
, "BBU_STATUS",
1413 megasas_dcmd_dummy
},
1414 { MFI_DCMD_BBU_CAPACITY_INFO
, "BBU_CAPACITY_INFO",
1415 megasas_dcmd_dummy
},
1416 { MFI_DCMD_BBU_DESIGN_INFO
, "BBU_DESIGN_INFO",
1417 megasas_dcmd_dummy
},
1418 { MFI_DCMD_BBU_PROP_GET
, "BBU_PROP_GET",
1419 megasas_dcmd_dummy
},
1420 { MFI_DCMD_CLUSTER
, "CLUSTER",
1421 megasas_dcmd_dummy
},
1422 { MFI_DCMD_CLUSTER_RESET_ALL
, "CLUSTER_RESET_ALL",
1423 megasas_dcmd_dummy
},
1424 { MFI_DCMD_CLUSTER_RESET_LD
, "CLUSTER_RESET_LD",
1425 megasas_cluster_reset_ld
},
1429 static int megasas_handle_dcmd(MegasasState
*s
, MegasasCmd
*cmd
)
1433 const struct dcmd_cmd_tbl_t
*cmdptr
= dcmd_cmd_tbl
;
1435 opcode
= le32_to_cpu(cmd
->frame
->dcmd
.opcode
);
1436 trace_megasas_handle_dcmd(cmd
->index
, opcode
);
1437 len
= megasas_map_dcmd(s
, cmd
);
1439 return MFI_STAT_MEMORY_NOT_AVAILABLE
;
1441 while (cmdptr
->opcode
!= -1 && cmdptr
->opcode
!= opcode
) {
1444 if (cmdptr
->opcode
== -1) {
1445 trace_megasas_dcmd_unhandled(cmd
->index
, opcode
, len
);
1446 retval
= megasas_dcmd_dummy(s
, cmd
);
1448 trace_megasas_dcmd_enter(cmd
->index
, cmdptr
->desc
, len
);
1449 retval
= cmdptr
->func(s
, cmd
);
1451 if (retval
!= MFI_STAT_INVALID_STATUS
) {
1452 megasas_finish_dcmd(cmd
, len
);
1457 static int megasas_finish_internal_dcmd(MegasasCmd
*cmd
,
1461 int retval
= MFI_STAT_OK
;
1464 opcode
= le32_to_cpu(cmd
->frame
->dcmd
.opcode
);
1465 scsi_req_unref(req
);
1466 trace_megasas_dcmd_internal_finish(cmd
->index
, opcode
, lun
);
1468 case MFI_DCMD_PD_GET_INFO
:
1469 retval
= megasas_pd_get_info_submit(req
->dev
, lun
, cmd
);
1471 case MFI_DCMD_LD_GET_INFO
:
1472 retval
= megasas_ld_get_info_submit(req
->dev
, lun
, cmd
);
1475 trace_megasas_dcmd_internal_invalid(cmd
->index
, opcode
);
1476 retval
= MFI_STAT_INVALID_DCMD
;
1479 if (retval
!= MFI_STAT_INVALID_STATUS
) {
1480 megasas_finish_dcmd(cmd
, cmd
->iov_size
);
1485 static int megasas_enqueue_req(MegasasCmd
*cmd
, bool is_write
)
1489 len
= scsi_req_enqueue(cmd
->req
);
1494 if (len
> cmd
->iov_size
) {
1496 trace_megasas_iov_write_overflow(cmd
->index
, len
,
1499 trace_megasas_iov_read_overflow(cmd
->index
, len
,
1503 if (len
< cmd
->iov_size
) {
1505 trace_megasas_iov_write_underflow(cmd
->index
, len
,
1508 trace_megasas_iov_read_underflow(cmd
->index
, len
,
1511 cmd
->iov_size
= len
;
1513 scsi_req_continue(cmd
->req
);
1518 static int megasas_handle_scsi(MegasasState
*s
, MegasasCmd
*cmd
,
1524 struct SCSIDevice
*sdev
= NULL
;
1526 cdb
= cmd
->frame
->pass
.cdb
;
1528 if (cmd
->frame
->header
.target_id
< s
->fw_luns
) {
1529 sdev
= scsi_device_find(&s
->bus
, 0, cmd
->frame
->header
.target_id
,
1530 cmd
->frame
->header
.lun_id
);
1532 cmd
->iov_size
= le32_to_cpu(cmd
->frame
->header
.data_len
);
1533 trace_megasas_handle_scsi(mfi_frame_desc
[cmd
->frame
->header
.frame_cmd
],
1534 is_logical
, cmd
->frame
->header
.target_id
,
1535 cmd
->frame
->header
.lun_id
, sdev
, cmd
->iov_size
);
1537 if (!sdev
|| (megasas_is_jbod(s
) && is_logical
)) {
1538 trace_megasas_scsi_target_not_present(
1539 mfi_frame_desc
[cmd
->frame
->header
.frame_cmd
], is_logical
,
1540 cmd
->frame
->header
.target_id
, cmd
->frame
->header
.lun_id
);
1541 return MFI_STAT_DEVICE_NOT_FOUND
;
1544 if (cmd
->frame
->header
.cdb_len
> 16) {
1545 trace_megasas_scsi_invalid_cdb_len(
1546 mfi_frame_desc
[cmd
->frame
->header
.frame_cmd
], is_logical
,
1547 cmd
->frame
->header
.target_id
, cmd
->frame
->header
.lun_id
,
1548 cmd
->frame
->header
.cdb_len
);
1549 megasas_write_sense(cmd
, SENSE_CODE(INVALID_OPCODE
));
1550 cmd
->frame
->header
.scsi_status
= CHECK_CONDITION
;
1552 return MFI_STAT_SCSI_DONE_WITH_ERROR
;
1555 if (megasas_map_sgl(s
, cmd
, &cmd
->frame
->pass
.sgl
)) {
1556 megasas_write_sense(cmd
, SENSE_CODE(TARGET_FAILURE
));
1557 cmd
->frame
->header
.scsi_status
= CHECK_CONDITION
;
1559 return MFI_STAT_SCSI_DONE_WITH_ERROR
;
1562 cmd
->req
= scsi_req_new(sdev
, cmd
->index
,
1563 cmd
->frame
->header
.lun_id
, cdb
, cmd
);
1565 trace_megasas_scsi_req_alloc_failed(
1566 mfi_frame_desc
[cmd
->frame
->header
.frame_cmd
],
1567 cmd
->frame
->header
.target_id
, cmd
->frame
->header
.lun_id
);
1568 megasas_write_sense(cmd
, SENSE_CODE(NO_SENSE
));
1569 cmd
->frame
->header
.scsi_status
= BUSY
;
1571 return MFI_STAT_SCSI_DONE_WITH_ERROR
;
1574 is_write
= (cmd
->req
->cmd
.mode
== SCSI_XFER_TO_DEV
);
1575 len
= megasas_enqueue_req(cmd
, is_write
);
1578 trace_megasas_scsi_write_start(cmd
->index
, len
);
1580 trace_megasas_scsi_read_start(cmd
->index
, len
);
1583 trace_megasas_scsi_nodata(cmd
->index
);
1585 return MFI_STAT_INVALID_STATUS
;
1588 static int megasas_handle_io(MegasasState
*s
, MegasasCmd
*cmd
)
1590 uint32_t lba_count
, lba_start_hi
, lba_start_lo
;
1592 bool is_write
= (cmd
->frame
->header
.frame_cmd
== MFI_CMD_LD_WRITE
);
1595 struct SCSIDevice
*sdev
= NULL
;
1597 lba_count
= le32_to_cpu(cmd
->frame
->io
.header
.data_len
);
1598 lba_start_lo
= le32_to_cpu(cmd
->frame
->io
.lba_lo
);
1599 lba_start_hi
= le32_to_cpu(cmd
->frame
->io
.lba_hi
);
1600 lba_start
= ((uint64_t)lba_start_hi
<< 32) | lba_start_lo
;
1602 if (cmd
->frame
->header
.target_id
< s
->fw_luns
) {
1603 sdev
= scsi_device_find(&s
->bus
, 0, cmd
->frame
->header
.target_id
,
1604 cmd
->frame
->header
.lun_id
);
1607 trace_megasas_handle_io(cmd
->index
,
1608 mfi_frame_desc
[cmd
->frame
->header
.frame_cmd
],
1609 cmd
->frame
->header
.target_id
,
1610 cmd
->frame
->header
.lun_id
,
1611 (unsigned long)lba_start
, (unsigned long)lba_count
);
1613 trace_megasas_io_target_not_present(cmd
->index
,
1614 mfi_frame_desc
[cmd
->frame
->header
.frame_cmd
],
1615 cmd
->frame
->header
.target_id
, cmd
->frame
->header
.lun_id
);
1616 return MFI_STAT_DEVICE_NOT_FOUND
;
1619 if (cmd
->frame
->header
.cdb_len
> 16) {
1620 trace_megasas_scsi_invalid_cdb_len(
1621 mfi_frame_desc
[cmd
->frame
->header
.frame_cmd
], 1,
1622 cmd
->frame
->header
.target_id
, cmd
->frame
->header
.lun_id
,
1623 cmd
->frame
->header
.cdb_len
);
1624 megasas_write_sense(cmd
, SENSE_CODE(INVALID_OPCODE
));
1625 cmd
->frame
->header
.scsi_status
= CHECK_CONDITION
;
1627 return MFI_STAT_SCSI_DONE_WITH_ERROR
;
1630 cmd
->iov_size
= lba_count
* sdev
->blocksize
;
1631 if (megasas_map_sgl(s
, cmd
, &cmd
->frame
->io
.sgl
)) {
1632 megasas_write_sense(cmd
, SENSE_CODE(TARGET_FAILURE
));
1633 cmd
->frame
->header
.scsi_status
= CHECK_CONDITION
;
1635 return MFI_STAT_SCSI_DONE_WITH_ERROR
;
1638 megasas_encode_lba(cdb
, lba_start
, lba_count
, is_write
);
1639 cmd
->req
= scsi_req_new(sdev
, cmd
->index
,
1640 cmd
->frame
->header
.lun_id
, cdb
, cmd
);
1642 trace_megasas_scsi_req_alloc_failed(
1643 mfi_frame_desc
[cmd
->frame
->header
.frame_cmd
],
1644 cmd
->frame
->header
.target_id
, cmd
->frame
->header
.lun_id
);
1645 megasas_write_sense(cmd
, SENSE_CODE(NO_SENSE
));
1646 cmd
->frame
->header
.scsi_status
= BUSY
;
1648 return MFI_STAT_SCSI_DONE_WITH_ERROR
;
1650 len
= megasas_enqueue_req(cmd
, is_write
);
1653 trace_megasas_io_write_start(cmd
->index
, lba_start
, lba_count
, len
);
1655 trace_megasas_io_read_start(cmd
->index
, lba_start
, lba_count
, len
);
1658 return MFI_STAT_INVALID_STATUS
;
1661 static int megasas_finish_internal_command(MegasasCmd
*cmd
,
1662 SCSIRequest
*req
, size_t resid
)
1664 int retval
= MFI_STAT_INVALID_CMD
;
1666 if (cmd
->frame
->header
.frame_cmd
== MFI_CMD_DCMD
) {
1667 cmd
->iov_size
-= resid
;
1668 retval
= megasas_finish_internal_dcmd(cmd
, req
);
1673 static QEMUSGList
*megasas_get_sg_list(SCSIRequest
*req
)
1675 MegasasCmd
*cmd
= req
->hba_private
;
1677 if (cmd
->frame
->header
.frame_cmd
== MFI_CMD_DCMD
) {
1684 static void megasas_xfer_complete(SCSIRequest
*req
, uint32_t len
)
1686 MegasasCmd
*cmd
= req
->hba_private
;
1690 trace_megasas_io_complete(cmd
->index
, len
);
1692 if (cmd
->frame
->header
.frame_cmd
!= MFI_CMD_DCMD
) {
1693 scsi_req_continue(req
);
1697 buf
= scsi_req_get_buf(req
);
1698 opcode
= le32_to_cpu(cmd
->frame
->dcmd
.opcode
);
1699 if (opcode
== MFI_DCMD_PD_GET_INFO
&& cmd
->iov_buf
) {
1700 struct mfi_pd_info
*info
= cmd
->iov_buf
;
1702 if (info
->inquiry_data
[0] == 0x7f) {
1703 memset(info
->inquiry_data
, 0, sizeof(info
->inquiry_data
));
1704 memcpy(info
->inquiry_data
, buf
, len
);
1705 } else if (info
->vpd_page83
[0] == 0x7f) {
1706 memset(info
->vpd_page83
, 0, sizeof(info
->vpd_page83
));
1707 memcpy(info
->vpd_page83
, buf
, len
);
1709 scsi_req_continue(req
);
1710 } else if (opcode
== MFI_DCMD_LD_GET_INFO
) {
1711 struct mfi_ld_info
*info
= cmd
->iov_buf
;
1714 memcpy(info
->vpd_page83
, buf
, sizeof(info
->vpd_page83
));
1715 scsi_req_continue(req
);
1720 static void megasas_command_complete(SCSIRequest
*req
, uint32_t status
,
1723 MegasasCmd
*cmd
= req
->hba_private
;
1724 uint8_t cmd_status
= MFI_STAT_OK
;
1726 trace_megasas_command_complete(cmd
->index
, status
, resid
);
1728 if (cmd
->req
!= req
) {
1730 * Internal command complete
1732 cmd_status
= megasas_finish_internal_command(cmd
, req
, resid
);
1733 if (cmd_status
== MFI_STAT_INVALID_STATUS
) {
1737 req
->status
= status
;
1738 trace_megasas_scsi_complete(cmd
->index
, req
->status
,
1739 cmd
->iov_size
, req
->cmd
.xfer
);
1740 if (req
->status
!= GOOD
) {
1741 cmd_status
= MFI_STAT_SCSI_DONE_WITH_ERROR
;
1743 if (req
->status
== CHECK_CONDITION
) {
1744 megasas_copy_sense(cmd
);
1747 megasas_unmap_sgl(cmd
);
1748 cmd
->frame
->header
.scsi_status
= req
->status
;
1749 scsi_req_unref(cmd
->req
);
1752 cmd
->frame
->header
.cmd_status
= cmd_status
;
1753 megasas_complete_frame(cmd
->state
, cmd
->context
);
1756 static void megasas_command_cancel(SCSIRequest
*req
)
1758 MegasasCmd
*cmd
= req
->hba_private
;
1761 megasas_abort_command(cmd
);
1763 scsi_req_unref(req
);
1767 static int megasas_handle_abort(MegasasState
*s
, MegasasCmd
*cmd
)
1769 uint64_t abort_ctx
= le64_to_cpu(cmd
->frame
->abort
.abort_context
);
1770 target_phys_addr_t abort_addr
, addr_hi
, addr_lo
;
1771 MegasasCmd
*abort_cmd
;
1773 addr_hi
= le32_to_cpu(cmd
->frame
->abort
.abort_mfi_addr_hi
);
1774 addr_lo
= le32_to_cpu(cmd
->frame
->abort
.abort_mfi_addr_lo
);
1775 abort_addr
= ((uint64_t)addr_hi
<< 32) | addr_lo
;
1777 abort_cmd
= megasas_lookup_frame(s
, abort_addr
);
1779 trace_megasas_abort_no_cmd(cmd
->index
, abort_ctx
);
1783 if (!megasas_use_queue64(s
)) {
1784 abort_ctx
&= (uint64_t)0xFFFFFFFF;
1786 if (abort_cmd
->context
!= abort_ctx
) {
1787 trace_megasas_abort_invalid_context(cmd
->index
, abort_cmd
->index
,
1788 abort_cmd
->context
);
1790 return MFI_STAT_ABORT_NOT_POSSIBLE
;
1792 trace_megasas_abort_frame(cmd
->index
, abort_cmd
->index
);
1793 megasas_abort_command(abort_cmd
);
1794 if (!s
->event_cmd
|| abort_cmd
!= s
->event_cmd
) {
1795 s
->event_cmd
= NULL
;
1801 static void megasas_handle_frame(MegasasState
*s
, uint64_t frame_addr
,
1802 uint32_t frame_count
)
1804 uint8_t frame_status
= MFI_STAT_INVALID_CMD
;
1805 uint64_t frame_context
;
1809 * Always read 64bit context, top bits will be
1810 * masked out if required in megasas_enqueue_frame()
1812 frame_context
= megasas_frame_get_context(frame_addr
);
1814 cmd
= megasas_enqueue_frame(s
, frame_addr
, frame_context
, frame_count
);
1816 /* reply queue full */
1817 trace_megasas_frame_busy(frame_addr
);
1818 megasas_frame_set_scsi_status(frame_addr
, BUSY
);
1819 megasas_frame_set_cmd_status(frame_addr
, MFI_STAT_SCSI_DONE_WITH_ERROR
);
1820 megasas_complete_frame(s
, frame_context
);
1824 switch (cmd
->frame
->header
.frame_cmd
) {
1826 frame_status
= megasas_init_firmware(s
, cmd
);
1829 frame_status
= megasas_handle_dcmd(s
, cmd
);
1832 frame_status
= megasas_handle_abort(s
, cmd
);
1834 case MFI_CMD_PD_SCSI_IO
:
1835 frame_status
= megasas_handle_scsi(s
, cmd
, 0);
1837 case MFI_CMD_LD_SCSI_IO
:
1838 frame_status
= megasas_handle_scsi(s
, cmd
, 1);
1840 case MFI_CMD_LD_READ
:
1841 case MFI_CMD_LD_WRITE
:
1842 frame_status
= megasas_handle_io(s
, cmd
);
1845 trace_megasas_unhandled_frame_cmd(cmd
->index
,
1846 cmd
->frame
->header
.frame_cmd
);
1850 if (frame_status
!= MFI_STAT_INVALID_STATUS
) {
1852 cmd
->frame
->header
.cmd_status
= frame_status
;
1854 megasas_frame_set_cmd_status(frame_addr
, frame_status
);
1856 megasas_complete_frame(s
, cmd
->context
);
1860 static uint64_t megasas_mmio_read(void *opaque
, target_phys_addr_t addr
,
1863 MegasasState
*s
= opaque
;
1864 uint32_t retval
= 0;
1872 retval
= (megasas_use_msix(s
) ? MFI_FWSTATE_MSIX_SUPPORTED
: 0) |
1873 (s
->fw_state
& MFI_FWSTATE_MASK
) |
1874 ((s
->fw_sge
& 0xff) << 16) |
1875 (s
->fw_cmds
& 0xFFFF);
1878 if (megasas_intr_enabled(s
) && s
->doorbell
) {
1879 retval
= MFI_1078_RM
| 1;
1883 retval
= s
->intr_mask
;
1886 retval
= s
->doorbell
;
1889 trace_megasas_mmio_invalid_readl(addr
);
1892 trace_megasas_mmio_readl(addr
, retval
);
1896 static void megasas_mmio_write(void *opaque
, target_phys_addr_t addr
,
1897 uint64_t val
, unsigned size
)
1899 MegasasState
*s
= opaque
;
1900 uint64_t frame_addr
;
1901 uint32_t frame_count
;
1904 trace_megasas_mmio_writel(addr
, val
);
1907 if (val
& MFI_FWINIT_ABORT
) {
1908 /* Abort all pending cmds */
1909 for (i
= 0; i
< s
->fw_cmds
; i
++) {
1910 megasas_abort_command(&s
->frames
[i
]);
1913 if (val
& MFI_FWINIT_READY
) {
1914 /* move to FW READY */
1915 megasas_soft_reset(s
);
1917 if (val
& MFI_FWINIT_MFIMODE
) {
1923 if (!megasas_intr_enabled(s
) && !msix_enabled(&s
->dev
)) {
1924 trace_megasas_irq_lower();
1925 qemu_irq_lower(s
->dev
.irq
[0]);
1927 if (megasas_intr_enabled(s
)) {
1928 trace_megasas_intr_enabled();
1930 trace_megasas_intr_disabled();
1935 if (s
->producer_pa
&& megasas_intr_enabled(s
)) {
1936 /* Update reply queue pointer */
1937 trace_megasas_qf_update(s
->reply_queue_head
, s
->busy
);
1938 stl_le_phys(s
->producer_pa
, s
->reply_queue_head
);
1939 if (!msix_enabled(&s
->dev
)) {
1940 trace_megasas_irq_lower();
1941 qemu_irq_lower(s
->dev
.irq
[0]);
1946 /* Received high 32 bits of a 64 bit MFI frame address */
1950 /* Received low 32 bits of a 64 bit MFI frame address */
1952 /* Received 32 bit MFI frame address */
1953 frame_addr
= (val
& ~0x1F);
1954 /* Add possible 64 bit offset */
1955 frame_addr
|= ((uint64_t)s
->frame_hi
<< 32);
1957 frame_count
= (val
>> 1) & 0xF;
1958 megasas_handle_frame(s
, frame_addr
, frame_count
);
1961 trace_megasas_mmio_invalid_writel(addr
, val
);
1966 static const MemoryRegionOps megasas_mmio_ops
= {
1967 .read
= megasas_mmio_read
,
1968 .write
= megasas_mmio_write
,
1969 .endianness
= DEVICE_LITTLE_ENDIAN
,
1971 .min_access_size
= 8,
1972 .max_access_size
= 8,
1976 static uint64_t megasas_port_read(void *opaque
, target_phys_addr_t addr
,
1979 return megasas_mmio_read(opaque
, addr
& 0xff, size
);
1982 static void megasas_port_write(void *opaque
, target_phys_addr_t addr
,
1983 uint64_t val
, unsigned size
)
1985 megasas_mmio_write(opaque
, addr
& 0xff, val
, size
);
1988 static const MemoryRegionOps megasas_port_ops
= {
1989 .read
= megasas_port_read
,
1990 .write
= megasas_port_write
,
1991 .endianness
= DEVICE_LITTLE_ENDIAN
,
1993 .min_access_size
= 4,
1994 .max_access_size
= 4,
1998 static uint64_t megasas_queue_read(void *opaque
, target_phys_addr_t addr
,
2004 static const MemoryRegionOps megasas_queue_ops
= {
2005 .read
= megasas_queue_read
,
2006 .endianness
= DEVICE_LITTLE_ENDIAN
,
2008 .min_access_size
= 8,
2009 .max_access_size
= 8,
2013 static void megasas_soft_reset(MegasasState
*s
)
2018 trace_megasas_reset();
2019 for (i
= 0; i
< s
->fw_cmds
; i
++) {
2020 cmd
= &s
->frames
[i
];
2021 megasas_abort_command(cmd
);
2023 megasas_reset_frames(s
);
2024 s
->reply_queue_len
= s
->fw_cmds
;
2025 s
->reply_queue_pa
= 0;
2028 s
->fw_state
= MFI_FWSTATE_READY
;
2030 s
->intr_mask
= MEGASAS_INTR_DISABLED_MASK
;
2032 s
->flags
&= ~MEGASAS_MASK_USE_QUEUE64
;
2034 s
->boot_event
= s
->event_count
;
2037 static void megasas_scsi_reset(DeviceState
*dev
)
2039 MegasasState
*s
= DO_UPCAST(MegasasState
, dev
.qdev
, dev
);
2041 megasas_soft_reset(s
);
2044 static const VMStateDescription vmstate_megasas
= {
2047 .minimum_version_id
= 0,
2048 .minimum_version_id_old
= 0,
2049 .fields
= (VMStateField
[]) {
2050 VMSTATE_PCI_DEVICE(dev
, MegasasState
),
2052 VMSTATE_INT32(fw_state
, MegasasState
),
2053 VMSTATE_INT32(intr_mask
, MegasasState
),
2054 VMSTATE_INT32(doorbell
, MegasasState
),
2055 VMSTATE_UINT64(reply_queue_pa
, MegasasState
),
2056 VMSTATE_UINT64(consumer_pa
, MegasasState
),
2057 VMSTATE_UINT64(producer_pa
, MegasasState
),
2058 VMSTATE_END_OF_LIST()
2062 static int megasas_scsi_uninit(PCIDevice
*d
)
2064 MegasasState
*s
= DO_UPCAST(MegasasState
, dev
, d
);
2067 msix_uninit(&s
->dev
, &s
->mmio_io
);
2069 memory_region_destroy(&s
->mmio_io
);
2070 memory_region_destroy(&s
->port_io
);
2071 memory_region_destroy(&s
->queue_io
);
2075 static const struct SCSIBusInfo megasas_scsi_info
= {
2077 .max_target
= MFI_MAX_LD
,
2080 .transfer_data
= megasas_xfer_complete
,
2081 .get_sg_list
= megasas_get_sg_list
,
2082 .complete
= megasas_command_complete
,
2083 .cancel
= megasas_command_cancel
,
2086 static int megasas_scsi_init(PCIDevice
*dev
)
2088 MegasasState
*s
= DO_UPCAST(MegasasState
, dev
, dev
);
2092 pci_conf
= s
->dev
.config
;
2094 /* PCI latency timer = 0 */
2095 pci_conf
[PCI_LATENCY_TIMER
] = 0;
2096 /* Interrupt pin 1 */
2097 pci_conf
[PCI_INTERRUPT_PIN
] = 0x01;
2099 memory_region_init_io(&s
->mmio_io
, &megasas_mmio_ops
, s
,
2100 "megasas-mmio", 0x4000);
2101 memory_region_init_io(&s
->port_io
, &megasas_port_ops
, s
,
2103 memory_region_init_io(&s
->queue_io
, &megasas_queue_ops
, s
,
2104 "megasas-queue", 0x40000);
2107 /* MSI-X support is currently broken */
2108 if (megasas_use_msix(s
) &&
2109 msix_init(&s
->dev
, 15, &s
->mmio_io
, 0, 0x2000)) {
2110 s
->flags
&= ~MEGASAS_MASK_USE_MSIX
;
2113 s
->flags
&= ~MEGASAS_MASK_USE_MSIX
;
2116 bar_type
= PCI_BASE_ADDRESS_SPACE_MEMORY
| PCI_BASE_ADDRESS_MEM_TYPE_64
;
2117 pci_register_bar(&s
->dev
, 0, bar_type
, &s
->mmio_io
);
2118 pci_register_bar(&s
->dev
, 2, PCI_BASE_ADDRESS_SPACE_IO
, &s
->port_io
);
2119 pci_register_bar(&s
->dev
, 3, bar_type
, &s
->queue_io
);
2121 if (megasas_use_msix(s
)) {
2122 msix_vector_use(&s
->dev
, 0);
2125 if (s
->fw_sge
>= MEGASAS_MAX_SGE
- MFI_PASS_FRAME_SIZE
) {
2126 s
->fw_sge
= MEGASAS_MAX_SGE
- MFI_PASS_FRAME_SIZE
;
2127 } else if (s
->fw_sge
>= 128 - MFI_PASS_FRAME_SIZE
) {
2128 s
->fw_sge
= 128 - MFI_PASS_FRAME_SIZE
;
2130 s
->fw_sge
= 64 - MFI_PASS_FRAME_SIZE
;
2132 if (s
->fw_cmds
> MEGASAS_MAX_FRAMES
) {
2133 s
->fw_cmds
= MEGASAS_MAX_FRAMES
;
2135 trace_megasas_init(s
->fw_sge
, s
->fw_cmds
,
2136 megasas_use_msix(s
) ? "MSI-X" : "INTx",
2137 megasas_is_jbod(s
) ? "jbod" : "raid");
2138 s
->fw_luns
= (MFI_MAX_LD
> MAX_SCSI_DEVS
) ?
2139 MAX_SCSI_DEVS
: MFI_MAX_LD
;
2142 for (i
= 0; i
< s
->fw_cmds
; i
++) {
2143 s
->frames
[i
].index
= i
;
2144 s
->frames
[i
].context
= -1;
2145 s
->frames
[i
].pa
= 0;
2146 s
->frames
[i
].state
= s
;
2149 scsi_bus_new(&s
->bus
, &dev
->qdev
, &megasas_scsi_info
);
2150 scsi_bus_legacy_handle_cmdline(&s
->bus
);
2154 static Property megasas_properties
[] = {
2155 DEFINE_PROP_UINT32("max_sge", MegasasState
, fw_sge
,
2156 MEGASAS_DEFAULT_SGE
),
2157 DEFINE_PROP_UINT32("max_cmds", MegasasState
, fw_cmds
,
2158 MEGASAS_DEFAULT_FRAMES
),
2160 DEFINE_PROP_BIT("use_msix", MegasasState
, flags
,
2161 MEGASAS_FLAG_USE_MSIX
, false),
2163 DEFINE_PROP_BIT("use_jbod", MegasasState
, flags
,
2164 MEGASAS_FLAG_USE_JBOD
, false),
2165 DEFINE_PROP_END_OF_LIST(),
2168 static void megasas_class_init(ObjectClass
*oc
, void *data
)
2170 DeviceClass
*dc
= DEVICE_CLASS(oc
);
2171 PCIDeviceClass
*pc
= PCI_DEVICE_CLASS(oc
);
2173 pc
->init
= megasas_scsi_init
;
2174 pc
->exit
= megasas_scsi_uninit
;
2175 pc
->vendor_id
= PCI_VENDOR_ID_LSI_LOGIC
;
2176 pc
->device_id
= PCI_DEVICE_ID_LSI_SAS1078
;
2177 pc
->subsystem_vendor_id
= PCI_VENDOR_ID_LSI_LOGIC
;
2178 pc
->subsystem_id
= 0x1013;
2179 pc
->class_id
= PCI_CLASS_STORAGE_RAID
;
2180 dc
->props
= megasas_properties
;
2181 dc
->reset
= megasas_scsi_reset
;
2182 dc
->vmsd
= &vmstate_megasas
;
2183 dc
->desc
= "LSI MegaRAID SAS 1078";
2186 static const TypeInfo megasas_info
= {
2188 .parent
= TYPE_PCI_DEVICE
,
2189 .instance_size
= sizeof(MegasasState
),
2190 .class_init
= megasas_class_init
,
2193 static void megasas_register_types(void)
2195 type_register_static(&megasas_info
);
2198 type_init(megasas_register_types
)