megasas: LSI Megaraid SAS HBA emulation

This patch adds an emulation for the LSI Megaraid SAS 8708EM2 HBA.
I've tested it to work with Linux, Windows Vista, and Windows7.

Signed-off-by: Hannes Reinecke <hare@suse.de>
[ Squashed trivial changes from Andreas Faerber, rebased over IOMMU
  and QBus changes - Paolo ]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Hannes Reinecke 2012-05-29 13:51:17 +02:00 committed by Paolo Bonzini
parent 7430d0f5a7
commit e8f943c3bc
5 changed files with 2281 additions and 0 deletions

View File

@ -10,6 +10,7 @@ CONFIG_EEPRO100_PCI=y
CONFIG_PCNET_PCI=y
CONFIG_PCNET_COMMON=y
CONFIG_LSI_SCSI_PCI=y
CONFIG_MEGASAS_SCSI_PCI=y
CONFIG_RTL8139_PCI=y
CONFIG_E1000_PCI=y
CONFIG_IDE_CORE=y

View File

@ -86,6 +86,7 @@ hw-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o
# SCSI layer
hw-obj-$(CONFIG_LSI_SCSI_PCI) += lsi53c895a.o
hw-obj-$(CONFIG_MEGASAS_SCSI_PCI) += megasas.o
hw-obj-$(CONFIG_ESP) += esp.o
hw-obj-y += sysbus.o isa-bus.o

2198
hw/megasas.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@
#define PCI_CLASS_STORAGE_SCSI 0x0100
#define PCI_CLASS_STORAGE_IDE 0x0101
#define PCI_CLASS_STORAGE_RAID 0x0104
#define PCI_CLASS_STORAGE_SATA 0x0106
#define PCI_CLASS_STORAGE_OTHER 0x0180
@ -47,6 +48,7 @@
#define PCI_VENDOR_ID_LSI_LOGIC 0x1000
#define PCI_DEVICE_ID_LSI_53C895A 0x0012
#define PCI_DEVICE_ID_LSI_SAS1078 0x0060
#define PCI_VENDOR_ID_DEC 0x1011
#define PCI_DEVICE_ID_DEC_21154 0x0026

View File

@ -512,6 +512,85 @@ lm32_uart_irq_state(int level) "irq state %d"
# hw/lm32_sys.c
lm32_sys_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
# hw/megasas.c
megasas_init_firmware(uint64_t pa) "pa %" PRIx64 " "
megasas_init_queue(uint64_t queue_pa, int queue_len, uint64_t head, uint64_t tail, uint32_t flags) "queue at %" PRIx64 " len %d head %" PRIx64 " tail %" PRIx64 " flags %x"
megasas_initq_map_failed(int frame) "scmd %d: failed to map queue"
megasas_initq_mismatch(int queue_len, int fw_cmds) "queue size %d max fw cmds %d"
megasas_qf_found(unsigned int index, uint64_t pa) "found mapped frame %x pa %" PRIx64 ""
megasas_qf_new(unsigned int index, void *cmd) "return new frame %x cmd %p"
megasas_qf_failed(unsigned long pa) "all frames busy for frame %lx"
megasas_qf_enqueue(unsigned int index, unsigned int count, uint64_t context, unsigned int tail, int busy) "enqueue frame %x count %d context %" PRIx64 " tail %x busy %d"
megasas_qf_update(unsigned int head, unsigned int busy) "update reply queue head %x busy %d"
megasas_qf_dequeue(unsigned int index) "dequeue frame %x"
megasas_qf_map_failed(int cmd, unsigned long frame) "scmd %d: frame %lu"
megasas_qf_complete_noirq(uint64_t context) "context %" PRIx64 " "
megasas_qf_complete(uint64_t context, unsigned int tail, unsigned int offset, int busy, unsigned int doorbell) "context %" PRIx64 " tail %x offset %d busy %d doorbell %x"
megasas_handle_frame(const char *cmd, uint64_t addr, uint64_t context, uint32_t count) "MFI cmd %s addr %" PRIx64 " context %" PRIx64 " count %d"
megasas_frame_busy(uint64_t addr) "frame %" PRIx64 " busy"
megasas_unhandled_frame_cmd(int cmd, uint8_t frame_cmd) "scmd %d: Unhandled MFI cmd %x"
megasas_handle_scsi(const char *frame, int bus, int dev, int lun, void *sdev, unsigned long size) "%s dev %x/%x/%x sdev %p xfer %lu"
megasas_scsi_target_not_present(const char *frame, int bus, int dev, int lun) "%s dev %x/%x/%x target not present"
megasas_scsi_invalid_cdb_len(const char *frame, int bus, int dev, int lun, int len) "%s dev %x/%x/%x invalid cdb len %d"
megasas_iov_read_overflow(int cmd, int bytes, int len) "scmd %d: %d/%d bytes"
megasas_iov_write_overflow(int cmd, int bytes, int len) "scmd %d: %d/%d bytes"
megasas_iov_read_underflow(int cmd, int bytes, int len) "scmd %d: %d/%d bytes"
megasas_iov_write_underflow(int cmd, int bytes, int len) "scmd %d: %d/%d bytes"
megasas_scsi_req_alloc_failed(const char *frame, int dev, int lun) "%s dev %x/%x req allocation failed"
megasas_scsi_read_start(int cmd, int len) "scmd %d: transfer %d bytes of data"
megasas_scsi_write_start(int cmd, int len) "scmd %d: transfer %d bytes of data"
megasas_scsi_nodata(int cmd) "scmd %d: no data to be transferred"
megasas_scsi_complete(int cmd, uint32_t status, int len, int xfer) "scmd %d: finished with status %x, len %u/%u"
megasas_command_complete(int cmd, uint32_t status, uint32_t resid) "scmd %d: command completed, status %x, residual %d"
megasas_handle_io(int cmd, const char *frame, int dev, int lun, unsigned long lba, unsigned long count) "scmd %d: %s dev %x/%x lba %lx count %lu"
megasas_io_target_not_present(int cmd, const char *frame, int dev, int lun) "scmd %d: %s dev 1/%x/%x LUN not present"
megasas_io_read_start(int cmd, unsigned long lba, unsigned long count, unsigned long len) "scmd %d: start LBA %lx %lu blocks (%lu bytes)"
megasas_io_write_start(int cmd, unsigned long lba, unsigned long count, unsigned long len) "scmd %d: start LBA %lx %lu blocks (%lu bytes)"
megasas_io_complete(int cmd, uint32_t len) "scmd %d: %d bytes completed"
megasas_io_read(int cmd, int bytes, int len, unsigned long offset) "scmd %d: %d/%d bytes, iov offset %lu"
megasas_io_write(int cmd, int bytes, int len, unsigned long offset) "scmd %d: %d/%d bytes, iov offset %lu"
megasas_io_continue(int cmd, int bytes) "scmd %d: %d bytes left"
megasas_iovec_map_failed(int cmd, int index, unsigned long iov_size) "scmd %d: iovec %d size %lu"
megasas_iovec_sgl_overflow(int cmd, int index, int limit) "scmd %d: iovec count %d limit %d"
megasas_iovec_sgl_underflow(int cmd, int index) "scmd %d: iovec count %d"
megasas_iovec_sgl_invalid(int cmd, int index, uint64_t pa, uint32_t len) "scmd %d: element %d pa %" PRIx64 " len %u"
megasas_iovec_overflow(int cmd, int len, int limit) "scmd %d: len %d limit %d"
megasas_iovec_underflow(int cmd, int len, int limit) "scmd %d: len %d limit %d"
megasas_handle_dcmd(int cmd, int opcode) "scmd %d: MFI DCMD opcode %x"
megasas_finish_dcmd(int cmd, int size) "scmd %d: MFI DCMD wrote %d bytes"
megasas_dcmd_req_alloc_failed(int cmd, const char *desc) "scmd %d: %s alloc failed"
megasas_dcmd_internal_submit(int cmd, const char *desc, int dev) "scmd %d: %s to dev %d"
megasas_dcmd_internal_finish(int cmd, int opcode, int lun) "scmd %d: DCMD finish internal cmd %x lun %d"
megasas_dcmd_internal_invalid(int cmd, int opcode) "scmd %d: Invalid internal DCMD %x"
megasas_dcmd_unhandled(int cmd, int opcode, int len) "scmd %d: opcode %x, len %d"
megasas_dcmd_zero_sge(int cmd) "scmd %d: zero DCMD sge count"
megasas_dcmd_invalid_sge(int cmd, int count) "scmd %d: invalid DCMD sge count %d"
megasas_dcmd_map_failed(int cmd) "scmd %d: Failed to map DCMD buffer"
megasas_dcmd_invalid_xfer_len(int cmd, unsigned long size, unsigned long max) "scmd %d: invalid xfer len %ld, max %ld"
megasas_dcmd_enter(int cmd, const char *dcmd, int len) "scmd %d: DCMD %s len %d"
megasas_dcmd_dummy(int cmd, unsigned long size) "scmd %d: DCMD dummy xfer len %ld"
megasas_dcmd_set_fw_time(int cmd, unsigned long time) "scmd %d: Set FW time %lx"
megasas_dcmd_pd_get_list(int cmd, int num, int max, int offset) "scmd %d: DCMD PD get list: %d / %d PDs, size %d"
megasas_dcmd_ld_get_list(int cmd, int num, int max) "scmd %d: DCMD LD get list: found %d / %d LDs"
megasas_dcmd_ld_get_info(int cmd, int ld_id) "scmd %d: DCMD LD get info for dev %d"
megasas_dcmd_pd_get_info(int cmd, int pd_id) "scmd %d: DCMD PD get info for dev %d"
megasas_dcmd_pd_list_query(int cmd, int flags) "scmd %d: DCMD PD list query flags %x"
megasas_dcmd_dump_frame(int offset, char f0, char f1, char f2, char f3, char f4, char f5, char f6, char f7) "0x%x: %02x %02x %02x %02x %02x %02x %02x %02x"
megasas_abort_frame(int cmd, int abort_cmd) "scmd %d: aborting frame %x"
megasas_abort_no_cmd(int cmd, uint64_t context) "scmd %d: no active command for frame context %" PRIx64 ""
megasas_abort_invalid_context(int cmd, uint64_t context, int abort_cmd) "scmd %d: invalid frame context %" PRIx64 " for abort frame %x"
megasas_reset(void) "Reset"
megasas_init(int sges, int cmds, const char *intr, const char *mode) "Using %d sges, %d cmds, %s, %s mode"
megasas_msix_raise(int vector) "vector %d"
megasas_irq_lower(void) "INTx"
megasas_irq_raise(void) "INTx"
megasas_intr_enabled(void) "Interrupts enabled"
megasas_intr_disabled(void) "Interrupts disabled"
megasas_mmio_readl(unsigned long addr, uint32_t val) "addr 0x%lx: 0x%x"
megasas_mmio_invalid_readl(unsigned long addr) "addr 0x%lx"
megasas_mmio_writel(uint32_t addr, uint32_t val) "addr 0x%x: 0x%x"
megasas_mmio_invalid_writel(uint32_t addr, uint32_t val) "addr 0x%x: 0x%x"
# hw/milkymist-ac97.c
milkymist_ac97_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
milkymist_ac97_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"