Some more functions. Signed-off-by: Hannes Reinecke <h...@suse.de> --- hw/megasas.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 64 insertions(+), 9 deletions(-)
diff --git a/hw/megasas.c b/hw/megasas.c index 8f95596..c3b74ef 100644 --- a/hw/megasas.c +++ b/hw/megasas.c @@ -6,7 +6,7 @@ * This code is licenced under the LGPL. */ - +#include <time.h> #include <assert.h> #include "hw.h" @@ -210,6 +210,26 @@ static int megasas_get_inq(SCSIDevice *sdev, int pg, uint8_t *buf, int buflen) } /* + * Utility functions + */ +static uint64_t megasas_fw_time(void) +{ + const time_t now = time(NULL); + struct tm *curtime; + uint64_t bcd_time; + + curtime = gmtime(&now); + bcd_time = ((uint64_t)curtime->tm_sec & 0xff) << 48 | + ((uint64_t)curtime->tm_min & 0xff) << 40 | + ((uint64_t)curtime->tm_hour & 0xff) << 32 | + ((uint64_t)curtime->tm_mday & 0xff) << 24 | + ((uint64_t)curtime->tm_mon & 0xff) << 16 | + ((uint64_t)(curtime->tm_year + 1900) & 0xffff); + + return bcd_time; +} + +/* * Frame handling */ @@ -462,6 +482,8 @@ static int megasas_ctrl_get_info(MPTState *s, struct megasas_cmd_t *cmd) info.device.port_count = 2; memcpy(info.product_name,"MegaRAID SAS 8708EM2", 20); + sprintf(info.package_version,"%s-QEMU", QEMU_VERSION); + info.current_fw_time = megasas_fw_time(); info.max_arms = 32; info.max_spans = 8; info.max_arrays = MEGASAS_MAX_LUNS; @@ -477,14 +499,16 @@ static int megasas_ctrl_get_info(MPTState *s, struct megasas_cmd_t *cmd) info.nvram_size = 32; info.flash_size = 16; info.raid_levels = MFI_INFO_RAID_0; - info.adapter_ops = MFI_INFO_AOPS_RBLD_RATE | MFI_INFO_AOPS_SELF_DIAGNOSTIC | MFI_INFO_AOPS_MIXED_ARRAY; + info.adapter_ops = MFI_INFO_AOPS_RBLD_RATE | + MFI_INFO_AOPS_SELF_DIAGNOSTIC | + MFI_INFO_AOPS_MIXED_ARRAY; info.ld_ops = MFI_INFO_LDOPS_DISK_CACHE_POLICY | MFI_INFO_LDOPS_ACCESS_POLICY | MFI_INFO_LDOPS_IO_POLICY | MFI_INFO_LDOPS_WRITE_POLICY | MFI_INFO_LDOPS_READ_POLICY; info.max_strips_per_io = 42; - info.stripe_sz_ops.min = 6; + info.stripe_sz_ops.min = 4; info.stripe_sz_ops.max = 0xf; info.properties.pred_fail_poll_interval = 300; info.properties.intr_throttle_cnt = 16; @@ -513,17 +537,41 @@ static int megasas_mfc_get_defaults(MPTState *s, struct megasas_cmd_t *cmd) memset(&info, 0x0, sizeof(info)); - info.stripe_size = 64; + info.stripe_size = 8; info.flush_time = 4; + info.background_rate = 30; info.allow_mix_in_enclosure = 1; info.allow_mix_in_ld = 1; info.direct_pd_mapping = 1; info.bios_enumerate_lds = 1; + info.disable_ctrl_r = 1; memcpy(cmd->iov_buf, (uint8_t *)&info, sizeof(info)); return sizeof(info); } +static int megasas_dcmd_get_bios_info(MPTState *d, struct megasas_cmd_t *cmd) +{ + struct mfi_bios_data info; + + memset(&info, 0x0, sizeof(info)); + info.continue_on_error = 1; + info.do_not_int_13 = 1; + memcpy(cmd->iov_buf, (uint8_t *)&info, sizeof(info)); + + return sizeof(info); +} + +static int megasas_dcmd_get_fw_time(MPTState *d, struct megasas_cmd_t *cmd) +{ + uint64_t fw_time; + + fw_time = megasas_fw_time(); + memcpy(cmd->iov_buf, (uint8_t *)&fw_time, sizeof(fw_time)); + + return sizeof(fw_time); +} + static int megasas_dcmd_pd_get_list(MPTState *s, struct megasas_cmd_t *cmd) { struct mfi_pd_list info; @@ -732,11 +780,11 @@ static int megasas_dcmd_dummy(MPTState *s, struct megasas_cmd_t *cmd) static int megasas_handle_dcmd(MPTState *s, struct megasas_cmd_t *cmd) { - int opcode, size = 0; + int opcode, size = 0, len; int retval = 0; opcode = le32_to_cpu(cmd->frame->dcmd.opcode); - megasas_map_dcmd(cmd); + len = megasas_map_dcmd(cmd); #ifdef DEBUG_MEGASAS_MFI DPRINTF("MFI DCMD opcode %x\n", opcode); #endif @@ -830,16 +878,23 @@ static int megasas_handle_dcmd(MPTState *s, struct megasas_cmd_t *cmd) #endif retval = MFI_STAT_INVALID_DCMD; break; + case MFI_DCMD_CTRL_GET_BIOS_INFO: + size = megasas_dcmd_get_bios_info(s, cmd); + retval = MFI_STAT_OK; + break; + case MFI_DCMD_CTRL_GET_TIME: + size = megasas_dcmd_get_fw_time(s, cmd); + retval = MFI_STAT_OK; + break; case 0x010e0301: case 0x010e0302: case 0x010e8481: - case MFI_DCMD_CTRL_GET_TIME: - DPRINTF("MFI DCMD %x dummy return\n", opcode); + DPRINTF("MFI DCMD %x dummy return %d bytes\n", opcode, len); size = megasas_dcmd_dummy(s, cmd); retval = MFI_STAT_OK; break; default: - DPRINTF("MFI DCMD %x unhandled\n", opcode); + DPRINTF("MFI DCMD %x unhandled (len %d)\n", opcode, len); retval = MFI_STAT_INVALID_DCMD; break; } -- 1.6.0.2