On Tue, 2010-05-18 at 08:57 +0200, Hannes Reinecke wrote: > 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; > }
Commited with a bit of FUZZ around megasas_ctrl_get_info() and megasas_mfc_get_defaults() as d852f3782524. Best, --nab