summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2006-05-17 21:50:22 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2006-05-17 21:50:22 +0000
commit597a67a702e713bb4d13f5adf5cb2f1302168212 (patch)
tree3b685e34e4e760dbe38e65078d49fb1523715f75
parent7b787b16b6c11def3a5d7de01e6c50e9f6eb2063 (diff)
Add mfi_get_info to obtain all kinds of fun information from the fw.
Print out whole info structure when debug is enabled. Add a nice print with useful info during attach.
-rw-r--r--sys/dev/ic/mfi.c219
-rw-r--r--sys/dev/ic/mfireg.h3
-rw-r--r--sys/dev/ic/mfivar.h5
3 files changed, 209 insertions, 18 deletions
diff --git a/sys/dev/ic/mfi.c b/sys/dev/ic/mfi.c
index 0730b058bf2..b1e62f23759 100644
--- a/sys/dev/ic/mfi.c
+++ b/sys/dev/ic/mfi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfi.c,v 1.36 2006/05/17 16:00:52 marco Exp $ */
+/* $OpenBSD: mfi.c,v 1.37 2006/05/17 21:50:21 marco Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -78,6 +78,7 @@ void mfi_freemem(struct mfi_softc *, struct mfi_mem *);
int mfi_transition_firmware(struct mfi_softc *);
int mfi_initialize_firmware(struct mfi_softc *);
+int mfi_get_info(struct mfi_softc *);
u_int32_t mfi_read(struct mfi_softc *, bus_size_t);
void mfi_write(struct mfi_softc *, bus_size_t, u_int32_t);
int mfi_poll(struct mfi_ccb *);
@@ -393,6 +394,190 @@ mfi_initialize_firmware(struct mfi_softc *sc)
return (0);
}
+int
+mfi_get_info(struct mfi_softc *sc)
+{
+ struct mfi_ccb *ccb;
+ struct mfi_dcmd_frame *dcmd;
+ int rv = 1;
+
+ DNPRINTF(MFI_D_MISC, "%s: mfi_get_info\n", DEVNAME(sc));
+
+ if ((ccb = mfi_get_ccb(sc)) == NULL)
+ return (rv);
+
+ dcmd = &ccb->ccb_frame->mfr_dcmd;
+ memset(dcmd->mdf_mbox, 0, MFI_MBOX_SIZE);
+ dcmd->mdf_header.mfh_cmd = MFI_CMD_DCMD;
+ dcmd->mdf_header.mfh_timeout = 0;
+ dcmd->mdf_header.mfh_data_len = sizeof(struct mfi_ctrl_info);
+
+ dcmd->mdf_opcode = MR_DCMD_CTRL_GET_INFO;
+
+ ccb->ccb_data = &sc->sc_info;
+ ccb->ccb_len = sizeof(struct mfi_ctrl_info);
+ ccb->ccb_frame_size = MFI_DCMD_FRAME_SIZE;
+ ccb->ccb_direction = MFI_DATA_IN;
+ ccb->ccb_sgl = &dcmd->mdf_sgl;
+
+ if (mfi_create_sgl(ccb, BUS_DMA_NOWAIT))
+ goto done;
+
+ if (mfi_poll(ccb))
+ goto done;
+
+ rv = 0;
+
+#ifdef MFI_DEBUG
+ int i;
+
+ for (i = 0; i < sc->sc_info.mci_image_component_count; i++) {
+ printf("%s: active FW %s Version %s date %s time %s\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_image_component[i].mic_name,
+ sc->sc_info.mci_image_component[i].mic_version,
+ sc->sc_info.mci_image_component[i].mic_build_date,
+ sc->sc_info.mci_image_component[i].mic_build_time);
+ }
+
+ for (i = 0; i < sc->sc_info.mci_pending_image_component_count; i++) {
+ printf("%s: pending FW %s Version %s date %s time %s\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_pending_image_component[i].mic_name,
+ sc->sc_info.mci_pending_image_component[i].mic_version,
+ sc->sc_info.mci_pending_image_component[i].mic_build_date,
+ sc->sc_info.mci_pending_image_component[i].mic_build_time);
+ }
+
+ printf("%s: max_arms %d max_spans %d max_arrs %d max_lds %d name %s\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_max_arms,
+ sc->sc_info.mci_max_spans,
+ sc->sc_info.mci_max_arrays,
+ sc->sc_info.mci_max_lds,
+ sc->sc_info.mci_product_name);
+
+ printf("%s: serial %s present %.x fw time %d max_cmds %d max_sg %d\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_serial_number,
+ sc->sc_info.mci_hw_present,
+ sc->sc_info.mci_current_fw_time,
+ sc->sc_info.mci_max_cmds,
+ sc->sc_info.mci_max_sg_elements);
+
+ printf("%s: max_rq %d lds_pres %d lds_deg %d lds_off %d pd_pres %d\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_max_request_size,
+ sc->sc_info.mci_lds_present,
+ sc->sc_info.mci_lds_degraded,
+ sc->sc_info.mci_lds_offline,
+ sc->sc_info.mci_pd_present);
+
+ printf("%s: pd_dsk_prs %d pd_dsk_pred_fail %d pd_dsk_fail %d\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_pd_disks_present,
+ sc->sc_info.mci_pd_disks_pred_failure,
+ sc->sc_info.mci_pd_disks_failed);
+
+ printf("%s: nvram %d mem %d flash %d\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_nvram_size,
+ sc->sc_info.mci_memory_size,
+ sc->sc_info.mci_flash_size);
+
+ printf("%s: ram_cor %d ram_uncor %d clus_all %d clus_act %d\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_ram_correctable_errors,
+ sc->sc_info.mci_ram_uncorrectable_errors,
+ sc->sc_info.mci_cluster_allowed,
+ sc->sc_info.mci_cluster_active);
+
+ printf("%s: max_strps_io %d raid_lvl %.x adapt_ops %.x ld_ops %.x\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_max_strips_per_io,
+ sc->sc_info.mci_raid_levels,
+ sc->sc_info.mci_adapter_ops,
+ sc->sc_info.mci_ld_ops);
+
+ printf("%s: strp_sz_min %d strp_sz_max %d pd_ops %.x pd_mix %.x\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_stripe_sz_ops.min,
+ sc->sc_info.mci_stripe_sz_ops.max,
+ sc->sc_info.mci_pd_ops,
+ sc->sc_info.mci_pd_mix_support);
+
+ printf("%s: ecc_bucket %d pckg_prop %s\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_ecc_bucket_count,
+ sc->sc_info.mci_package_version);
+
+ printf("%s: sq_nm %d prd_fail_poll %d intr_thrtl %d intr_thrtl_to %d\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_properties.mcp_seq_num,
+ sc->sc_info.mci_properties.mcp_pred_fail_poll_interval,
+ sc->sc_info.mci_properties.mcp_intr_throttle_cnt,
+ sc->sc_info.mci_properties.mcp_intr_throttle_timeout);
+
+ printf("%s: rbld_rate %d patr_rd_rate %d bgi_rate %d cc_rate %d\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_properties.mcp_rebuild_rate,
+ sc->sc_info.mci_properties.mcp_patrol_read_rate,
+ sc->sc_info.mci_properties.mcp_bgi_rate,
+ sc->sc_info.mci_properties.mcp_cc_rate);
+
+ printf("%s: rc_rate %d ch_flsh %d spin_cnt %d spin_dly %d clus_en %d\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_properties.mcp_recon_rate,
+ sc->sc_info.mci_properties.mcp_cache_flush_interval,
+ sc->sc_info.mci_properties.mcp_spinup_drv_cnt,
+ sc->sc_info.mci_properties.mcp_spinup_delay,
+ sc->sc_info.mci_properties.mcp_cluster_enable);
+
+ printf("%s: coerc %d alarm %d dis_auto_rbld %d dis_bat_wrn %d ecc %d\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_properties.mcp_coercion_mode,
+ sc->sc_info.mci_properties.mcp_alarm_enable,
+ sc->sc_info.mci_properties.mcp_disable_auto_rebuild,
+ sc->sc_info.mci_properties.mcp_disable_battery_warn,
+ sc->sc_info.mci_properties.mcp_ecc_bucket_size);
+
+ printf("%s: ecc_leak %d rest_hs %d exp_encl_dev %d\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_properties.mcp_ecc_bucket_leak_rate,
+ sc->sc_info.mci_properties.mcp_restore_hotspare_on_insertion,
+ sc->sc_info.mci_properties.mcp_expose_encl_devices);
+
+ printf("%s: vendor %.x device %.x subvendor %.x subdevice %.x\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_pci.mip_vendor,
+ sc->sc_info.mci_pci.mip_device,
+ sc->sc_info.mci_pci.mip_subvendor,
+ sc->sc_info.mci_pci.mip_subdevice);
+
+ printf("%s: type %.x port_count %d port_addr ",
+ DEVNAME(sc),
+ sc->sc_info.mci_host.mih_type,
+ sc->sc_info.mci_host.mih_port_count);
+
+ for (i = 0; i < 8; i++)
+ printf("%.0llx ", sc->sc_info.mci_host.mih_port_addr[i]);
+ printf("\n");
+
+ printf("%s: type %.x port_count %d port_addr ",
+ DEVNAME(sc),
+ sc->sc_info.mci_device.mid_type,
+ sc->sc_info.mci_device.mid_port_count);
+
+ for (i = 0; i < 8; i++)
+ printf("%.0llx ", sc->sc_info.mci_device.mid_port_addr[i]);
+ printf("\n");
+#endif /* MFI_DEBUG */
+
+done:
+ mfi_put_ccb(ccb);
+ return (rv);
+}
+
void
mfiminphys(struct buf *bp)
{
@@ -408,6 +593,7 @@ int
mfi_attach(struct mfi_softc *sc)
{
uint32_t status, frames;
+ int i;
DNPRINTF(MFI_D_MISC, "%s: mfi_attach\n", DEVNAME(sc));
@@ -474,13 +660,21 @@ mfi_attach(struct mfi_softc *sc)
sc->sc_ioctl = mfi_ioctl;
#endif /* NBIO > 0 */
- sc->sc_max_ld = MFI_MAX_LD;
+ if (mfi_get_info(sc)) {
+ printf("%s: could not retrieve controller information\n");
+ goto noinit;
+ }
+
+ printf("%s: logical drives %d version %s RAM %dMB\n",
+ DEVNAME(sc),
+ sc->sc_info.mci_lds_present,
+ sc->sc_info.mci_package_version,
+ sc->sc_info.mci_memory_size);
- /* XXX fake two lds for now */
- sc->sc_ld_cnt = 2;
- sc->sc_ld[0].ld_present = 1;
- sc->sc_ld[1].ld_present = 1;
- sc->sc_max_ld = 2;
+ sc->sc_ld_cnt = sc->sc_info.mci_lds_present;
+ sc->sc_max_ld = sc->sc_ld_cnt;
+ for (i = 0; i < sc->sc_ld_cnt; i++)
+ sc->sc_ld[i].ld_present = 1;
if (sc->sc_ld_cnt)
sc->sc_link.openings = sc->sc_max_cmds / sc->sc_ld_cnt;
@@ -492,12 +686,6 @@ mfi_attach(struct mfi_softc *sc)
sc->sc_link.adapter = &mfi_switch;
sc->sc_link.adapter_target = MFI_MAX_LD;
sc->sc_link.adapter_buswidth = sc->sc_max_ld;
-#if 0
- printf(", FW %s, BIOS v%s, %dMB RAM\n"
- "%s: %d channels, %d %ss, %d logical drives\n",
- sc->sc_fwver, sc->sc_biosver, sc->sc_memory, DEVNAME(sc),
- sc->sc_channels, sc->sc_targets, p, sc->sc_ld_cnt);
-#endif
config_found(&sc->sc_dev, &sc->sc_link, scsiprint);
@@ -643,7 +831,7 @@ mfi_scsi_ld(struct mfi_ccb *ccb, struct scsi_xfer *xs)
ccb->ccb_direction = xs->flags & SCSI_DATA_IN ?
MFI_DATA_IN : MFI_DATA_OUT;
else
- ccb->ccb_direction = 0;
+ ccb->ccb_direction = MFI_DATA_NONE;
if (xs->data) {
ccb->ccb_data = xs->data;
@@ -753,7 +941,8 @@ mfi_create_sgl(struct mfi_ccb *ccb, int flags)
union mfi_sgl *sgl;
int error, i;
- DNPRINTF(MFI_D_DMA, "%s: mfi_create_sgl\n", DEVNAME(sc));
+ DNPRINTF(MFI_D_DMA, "%s: mfi_create_sgl %x\n", DEVNAME(sc),
+ ccb->ccb_data);
if (!ccb->ccb_data)
return (1);
diff --git a/sys/dev/ic/mfireg.h b/sys/dev/ic/mfireg.h
index 1d4dfb3bb16..354b22ac3ff 100644
--- a/sys/dev/ic/mfireg.h
+++ b/sys/dev/ic/mfireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfireg.h,v 1.11 2006/05/15 23:20:57 marco Exp $ */
+/* $OpenBSD: mfireg.h,v 1.12 2006/05/17 21:50:21 marco Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -300,6 +300,7 @@ struct mfi_pass_frame {
union mfi_sgl mpf_sgl;
} __packed;
+#define MFI_DCMD_FRAME_SIZE 40
struct mfi_dcmd_frame {
struct mfi_frame_header mdf_header;
uint32_t mdf_opcode;
diff --git a/sys/dev/ic/mfivar.h b/sys/dev/ic/mfivar.h
index a2f6e4b9ba0..5b0ab0b68d8 100644
--- a/sys/dev/ic/mfivar.h
+++ b/sys/dev/ic/mfivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfivar.h,v 1.17 2006/05/17 16:00:53 marco Exp $ */
+/* $OpenBSD: mfivar.h,v 1.18 2006/05/17 21:50:21 marco Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -114,11 +114,12 @@ struct mfi_softc {
/* scsi ioctl from sd device */
int (*sc_ioctl)(struct device *, u_long, caddr_t);
- /* firmware determined max and totals */
+ /* firmware determined max, totals and other information*/
uint32_t sc_max_cmds;
uint32_t sc_max_sgl;
uint32_t sc_max_ld;
uint32_t sc_ld_cnt;
+ struct mfi_ctrl_info sc_info;
/* all commands */
struct mfi_ccb *sc_ccb;