summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2010-04-09 15:50:15 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2010-04-09 15:50:15 +0000
commit958dd985e92981e7ac7757cb4100104c144f9260 (patch)
tree28b8499fe06b8cc48f9a091ff8d6b8766ef40693
parent5d832de2cdac67e45e972d0817e7d454aae81005 (diff)
- event handling rewrite (while preserving original logic);
- support additional volume events; - track volume rebuild progress; - support for drive hotplug; - log when volume state changes and when we start to resync; - mpii_device handling rewrite (r/b tree is no more); - improvements in mpii_ioctl_* functions; - use internal disk_phys_num again as phy port number based scheme was proven to be unreliable; - fixup ioc_status check in mpii_scsi_cmd_done; - change Offline state to Invalid when drive is gone; - fixup recognition of the rebuilding state; - don't leak ccb if poll fails; - make use of the MPII_F_RAID flag and register with bio only if there are RAID capabilities (idea from mpi); - EVENT_UNMASK macro improvement from Kai Doernemann; - use proper endianness when setting ccb_dev_handle; - lower a polling delay in the mpii_complete; - improve readability and debugging output in several places; - change semantics of the SAS discovery event handler; - start of the event cleanup; - start of the whitespace cleanup; - start of the KNF cleanup; from Mike Belopuhov <mkb@crypt.org.ru>
-rw-r--r--sys/dev/pci/mpii.c1444
1 files changed, 698 insertions, 746 deletions
diff --git a/sys/dev/pci/mpii.c b/sys/dev/pci/mpii.c
index 56cdf96fc89..85d9f354271 100644
--- a/sys/dev/pci/mpii.c
+++ b/sys/dev/pci/mpii.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpii.c,v 1.13 2010/04/06 22:28:07 tedu Exp $ */
+/* $OpenBSD: mpii.c,v 1.14 2010/04/09 15:50:14 marco Exp $ */
/*
* Copyright (c) 2010 Mike Belopuhov <mkb@crypt.org.ru>
* Copyright (c) 2009 James Giannoules
@@ -81,7 +81,7 @@
#define MPII_WRITESEQ_3 (0x0b)
#define MPII_WRITESEQ_4 (0x02)
#define MPII_WRITESEQ_5 (0x07)
-#define MPII_WRITESEQ_6 (0x0d)
+#define MPII_WRITESEQ_6 (0x0d)
#define MPII_HOSTDIAG (0x08)
#define MPII_HOSTDIAG_BDS_MASK (0x00001800) /* boot device select */
@@ -128,8 +128,8 @@
#define MPII_HCB_ADDRESS_LOW (0x78)
#define MPII_HCB_ADDRESS_HIGH (0x7c)
-#define MPII_REQ_DESC_POST_LOW (0xc0)
-#define MPII_REQ_DESC_POST_HIGH (0xc4)
+#define MPII_REQ_DESCR_POST_LOW (0xc0)
+#define MPII_REQ_DESCR_POST_HIGH (0xc4)
/*
* Scatter Gather Lists
@@ -211,24 +211,8 @@ struct mpii_fw_tce {
#define MPII_FUNCTION_IO_UNIT_RESET (0x41)
#define MPII_FUNCTION_HANDSHAKE (0x42)
-/* request flags fields for request descriptors */
-#define MPII_REQ_DESCRIPTOR_FLAGS_TYPE_SHIFT (0x01)
-#define MPII_REQ_DESCRIPTOR_FLAGS_TYPE_MASK (0x07 << \
- MPII_REQ_DESCRIPTOR_FLAGS_TYPE_SHIFT)
-#define MPII_REQ_DESCRIPTOR_FLAGS_SCSI_IO (0x00)
-#define MPII_REQ_DESCRIPTOR_FLAGS_SCSI_TARGET (0x02)
-#define MPII_REQ_DESCRIPTOR_FLAGS_HIGH_PRIORITY (0x06)
-#define MPII_REQ_DESCRIPTOR_FLAGS_DEFAULT (0x08)
-
-#define MPII_REQ_DESCRIPTOR_FLAGS_IOC_FIFO_MARKER (0x01)
-
-/* reply flags */
-#define MPII_REP_FLAGS_CONT (1<<7) /* continuation reply */
-
-#define MPII_REP_IOCSTATUS_AVAIL (1<<15) /* log info available */
-#define MPII_REP_IOCSTATUS (0x7fff) /* status */
-
/* Common IOCStatus values for all replies */
+#define MPII_IOCSTATUS_MASK (0x7fff)
#define MPII_IOCSTATUS_SUCCESS (0x0000)
#define MPII_IOCSTATUS_INVALID_FUNCTION (0x0001)
#define MPII_IOCSTATUS_BUSY (0x0002)
@@ -642,56 +626,6 @@ struct mpii_msg_event_reply {
/* event data follows */
} __packed;
-/* XXX JPG */
-struct mpii_evt_change {
- u_int8_t event_state;
- u_int8_t reserved[3];
-} __packed;
-
-/* XXX JPG */
-struct mpii_evt_sas_phy {
- u_int8_t phy_num;
- u_int8_t link_rates;
-#define MPII_EVT_SASPHY_LINK_CUR(x) ((x) & 0xf0) >> 4
-#define MPII_EVT_SASPHY_LINK_PREV(x) (x) & 0x0f
-#define MPII_EVT_SASPHY_LINK_ENABLED (0x0)
-#define MPII_EVT_SASPHY_LINK_DISABLED (0x1)
-#define MPII_EVT_SASPHY_LINK_NEGFAIL (0x2)
-#define MPII_EVT_SASPHY_LINK_SATAOOB (0x3)
-#define MPII_EVT_SASPHY_LINK_1_5GBPS (0x8)
-#define MPII_EVT_SASPHY_LINK_3_0GBPS (0x9)
- u_int16_t dev_handle;
-
- u_int64_t sas_addr;
-} __packed;
-
-struct mpii_evt_sas_change {
- u_int16_t task_tag;
- u_int8_t reason;
-#define MPII_EVT_SASCH_REASON_SMART_DATA (0x05)
-#define MPII_EVT_SASCH_REASON_UNSUPPORTED (0x07)
-#define MPII_EVT_SASCH_REASON_INTERNAL_RESET (0x08)
-#define MPII_EVT_SASCH_REASON_TASK_ABORT_INTERVAL (0x09)
-#define MPII_EVT_SASCH_REASON_ABORT_TASK_SET_INTERVAL (0x0a)
-#define MPII_EVT_SASCH_REASON_CLEAR_TASK_SET_INTERVAL (0x0b)
-#define MPII_EVT_SASCH_REASON_QUERY_TASK_INTERVAL (0x0c)
-#define MPII_EVT_SASCH_REASON_ASYNC_NOTIFICATION (0x0d)
-#define MPII_EVT_SASCH_REASON_CMP_INTERNAL_DEV_RESET (0x0e)
-#define MPII_EVT_SASCH_REASON_CMP_TASK_ABORT_INTERNAL (0x0f)
-#define MPII_EVT_SASCH_REASON_SATA_INIT_FAILURE (0x10)
- u_int8_t reserved1;
-
- u_int8_t asc;
- u_int8_t ascq;
- u_int16_t dev_handle;
-
- u_int32_t reserved2;
-
- u_int64_t sas_addr;
-
- u_int16_t lun[4];
-} __packed;
-
struct mpii_msg_eventack_request {
u_int16_t reserved1;
u_int8_t chain_offset;
@@ -896,45 +830,35 @@ struct mpii_msg_scsi_io_error {
u_int32_t reserved6;
} __packed;
-struct mpii_request_descriptor {
+struct mpii_request_descr {
u_int8_t request_flags;
+#define MPII_REQ_DESCR_TYPE_MASK (0x0e)
+#define MPII_REQ_DESCR_SCSI_IO (0x00)
+#define MPII_REQ_DESCR_SCSI_TARGET (0x02)
+#define MPII_REQ_DESCR_HIGH_PRIORITY (0x06)
+#define MPII_REQ_DESCR_DEFAULT (0x08)
u_int8_t vf_id;
u_int16_t smid;
u_int16_t lmid;
- /*
- * the following field is descriptor type dependent
- * default - undefined
- * scsi io - device handle
- * high priority - reserved
- */
- u_int16_t type_dependent;
+ u_int16_t dev_handle;
} __packed;
-struct mpii_reply_descriptor {
+struct mpii_reply_descr {
u_int8_t reply_flags;
-#define MPII_REPLY_DESCR_FLAGS_TYPE_MASK (0x0f)
-#define MPII_REPLY_DESCR_FLAGS_SCSI_IO_SUCCESS (0x00)
-#define MPII_REPLY_DESCR_FLAGS_ADDRESS_REPLY (0x01)
-#define MPII_REPLY_DESCR_FLAGS_TARGETASSIST_SUCCESS (0x02)
-#define MPII_REPLY_DESCR_FLAGS_TARGET_COMMAND_BUFFER (0x03)
-#define MPII_REPLY_DESCR_FLAGS_UNUSED (0x0f)
+#define MPII_REPLY_DESCR_TYPE_MASK (0x0f)
+#define MPII_REPLY_DESCR_SCSI_IO_SUCCESS (0x00)
+#define MPII_REPLY_DESCR_ADDRESS_REPLY (0x01)
+#define MPII_REPLY_DESCR_TARGET_ASSIST_SUCCESS (0x02)
+#define MPII_REPLY_DESCR_TARGET_COMMAND_BUFFER (0x03)
+#define MPII_REPLY_DESCR_UNUSED (0x0f)
u_int8_t vf_id;
- /*
- * the following field is reply descriptor type dependent
- * default - undefined
- * scsi io success - smid
- * address reply - smid
- */
- u_int16_t type_dependent1;
+ u_int16_t smid;
- /*
- * the following field is reply descriptor type dependent
- * default - undefined
- * scsi io success - bottom 16 bits is task tag
- * address reply - reply frame address
- */
- u_int32_t type_dependent2;
+ union {
+ u_int32_t data;
+ u_int32_t frame_addr; /* Address Reply */
+ };
} __packed;
struct mpii_request_header {
@@ -951,36 +875,35 @@ struct mpii_request_header {
u_int16_t reserved;
} __packed;
-/* XXX JPG delete this? */
struct mpii_msg_scsi_task_request {
- u_int8_t target_id;
- u_int8_t bus;
+ u_int16_t dev_handle;
u_int8_t chain_offset;
u_int8_t function;
u_int8_t reserved1;
u_int8_t task_type;
-#define MPII_MSG_SCSI_TASK_TYPE_ABORT_TASK (0x01)
-#define MPII_MSG_SCSI_TASK_TYPE_ABRT_TASK_SET (0x02)
-#define MPII_MSG_SCSI_TASK_TYPE_TARGET_RESET (0x03)
-#define MPII_MSG_SCSI_TASK_TYPE_RESET_BUS (0x04)
-#define MPII_MSG_SCSI_TASK_TYPE_LOGICAL_UNIT_RESET (0x05)
+#define MPII_SCSI_TASK_ABORT_TASK (0x01)
+#define MPII_SCSI_TASK_ABRT_TASK_SET (0x02)
+#define MPII_SCSI_TASK_TARGET_RESET (0x03)
+#define MPII_SCSI_TASK_RESET_BUS (0x04)
+#define MPII_SCSI_TASK_LOGICAL_UNIT_RESET (0x05)
u_int8_t reserved2;
u_int8_t msg_flags;
- u_int32_t msg_context;
+ u_int8_t vp_id;
+ u_int8_t vf_id;
+ u_int16_t reserved3;
u_int16_t lun[4];
- u_int32_t reserved3[7];
+ u_int32_t reserved4[7];
- u_int32_t target_msg_context;
+ u_int16_t task_mid;
+ u_int16_t reserved5;
} __packed;
-/* XXX JPG delete this? */
struct mpii_msg_scsi_task_reply {
- u_int8_t target_id;
- u_int8_t bus;
+ u_int16_t dev_handle;
u_int8_t msg_length;
u_int8_t function;
@@ -989,9 +912,11 @@ struct mpii_msg_scsi_task_reply {
u_int8_t reserved1;
u_int8_t msg_flags;
- u_int32_t msg_context;
-
+ u_int8_t vp_id;
+ u_int8_t vf_id;
u_int16_t reserved2;
+
+ u_int16_t reserved3;
u_int16_t ioc_status;
u_int32_t ioc_loginfo;
@@ -999,6 +924,70 @@ struct mpii_msg_scsi_task_reply {
u_int32_t termination_count;
} __packed;
+struct mpii_msg_sas_oper_request {
+ u_int8_t operation;
+#define MPII_SAS_OP_CLEAR_PERSISTENT (0x02)
+#define MPII_SAS_OP_PHY_LINK_RESET (0x06)
+#define MPII_SAS_OP_PHY_HARD_RESET (0x07)
+#define MPII_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08)
+#define MPII_SAS_OP_SEND_PRIMITIVE (0x0a)
+#define MPII_SAS_OP_FORCE_FULL_DISCOVERY (0x0b)
+#define MPII_SAS_OP_TRANSMIT_PORT_SELECT (0x0c)
+#define MPII_SAS_OP_REMOVE_DEVICE (0x0d)
+#define MPII_SAS_OP_LOOKUP_MAPPING (0x0e)
+#define MPII_SAS_OP_SET_IOC_PARAM (0x0f)
+ u_int8_t reserved1;
+ u_int8_t chain_offset;
+ u_int8_t function;
+
+ u_int16_t dev_handle;
+ u_int8_t ioc_param;
+ u_int8_t msg_flags;
+
+ u_int8_t vp_id;
+ u_int8_t vf_id;
+ u_int16_t reserved2;
+
+ u_int16_t reserved3;
+ u_int8_t phy_num;
+ u_int8_t prim_flags;
+
+ u_int32_t primitive;
+
+ u_int8_t lookup_method;
+#define MPII_SAS_LOOKUP_METHOD_SAS_ADDR (0x01)
+#define MPII_SAS_LOOKUP_METHOD_SAS_ENCL (0x02)
+#define MPII_SAS_LOOKUP_METHOD_SAS_DEVNAME (0x03)
+ u_int8_t reserved4;
+ u_int16_t slot_num;
+
+ u_int64_t lookup_addr;
+
+ u_int32_t ioc_param_value;
+
+ u_int64_t reserved5;
+} __packed;
+
+struct mpii_msg_sas_oper_reply {
+ u_int8_t operation;
+ u_int8_t reserved1;
+ u_int8_t chain_offset;
+ u_int8_t function;
+
+ u_int16_t dev_handle;
+ u_int8_t ioc_param;
+ u_int8_t msg_flags;
+
+ u_int8_t vp_id;
+ u_int8_t vf_id;
+ u_int16_t reserved2;
+
+ u_int16_t reserved3;
+ u_int16_t ioc_status;
+
+ u_int32_t ioc_loginfo;
+} __packed;
+
struct mpii_cfg_hdr {
u_int8_t page_version;
u_int8_t page_length;
@@ -1557,7 +1546,34 @@ struct mpii_evt_sas_discovery {
u_int8_t reserved1;
u_int32_t discovery_status;
-/* lots of defines go in here */
+} __packed;
+
+struct mpii_evt_ir_status {
+ u_int16_t vol_dev_handle;
+ u_int16_t reserved1;
+
+ u_int8_t operation;
+#define MPII_EVENT_IR_RAIDOP_RESYNC (0x00)
+#define MPII_EVENT_IR_RAIDOP_OCE (0x01)
+#define MPII_EVENT_IR_RAIDOP_CONS_CHECK (0x02)
+#define MPII_EVENT_IR_RAIDOP_BG_INIT (0x03)
+#define MPII_EVENT_IR_RAIDOP_MAKE_CONS (0x04)
+ u_int8_t percent;
+ u_int16_t reserved2;
+
+ u_int32_t reserved3;
+};
+
+struct mpii_evt_ir_volume {
+ u_int16_t vol_dev_handle;
+ u_int8_t reason_code;
+#define MPII_EVENT_IR_VOL_RC_SETTINGS_CHANGED (0x01)
+#define MPII_EVENT_IR_VOL_RC_STATUS_CHANGED (0x02)
+#define MPII_EVENT_IR_VOL_RC_STATE_CHANGED (0x03)
+ u_int8_t reserved1;
+
+ u_int32_t new_value;
+ u_int32_t prev_value;
} __packed;
struct mpii_evt_ir_physical_disk {
@@ -1578,16 +1594,16 @@ struct mpii_evt_ir_physical_disk {
u_int32_t previous_value;
} __packed;
-struct mpii_evt_sas_topo_change_list {
+struct mpii_evt_sas_tcl {
u_int16_t enclosure_handle;
- u_int16_t expander_dev_handle;
+ u_int16_t expander_handle;
u_int8_t num_phys;
u_int8_t reserved1[3];
u_int8_t num_entries;
u_int8_t start_phy_num;
- u_int8_t exp_status;
+ u_int8_t expn_status;
#define MPII_EVENT_SAS_TOPO_ES_ADDED (0x01)
#define MPII_EVENT_SAS_TOPO_ES_NOT_RESPONDING (0x02)
#define MPII_EVENT_SAS_TOPO_ES_RESPONDING (0x03)
@@ -1598,30 +1614,12 @@ struct mpii_evt_sas_topo_change_list {
} __packed;
struct mpii_evt_phy_entry {
- u_int16_t attached_dev_handle;
+ u_int16_t dev_handle;
u_int8_t link_rate;
-#define MPII_EVENT_SAS_TOPO_LR_CURRENT_LINK_RATE_MASK (0xf0)
-#define MPII_EVENT_SAS_TOPO_LR_CURRENT_LINK_RATE_SHIFT (4)
-#define MPII_EVENT_SAS_TOPO_LR_PREVIOUS_LINK_RATE_MASK (0x0f)
-#define MPII_EVENT_SAS_TOPO_LR_PHY_EN_UNKNOWN_RATE (0x0)
-#define MPII_EVENT_SAS_TOPO_LR_PHY_DISABLE (0x1)
-#define MPII_EVENT_SAS_TOPO_LR_PHY_EN_FAIL_SPEED_NEG (0x2)
-#define MPII_EVENT_SAS_TOPO_LR_PHY_EN_SATA_OOB_COMPLETE (0x3)
-#define MPII_EVENT_SAS_TOPO_LR_PHY_EN_SATA_PORT_SEL (0x4)
-#define MPII_EVENT_SAS_TOPO_LR_PHY_EN_SMP_RESET_IN_PROG (0x5)
-#define MPII_EVENT_SAS_TOPO_LR_PHY_EN_1_5_GBPS (0x8)
-#define MPII_EVENT_SAS_TOPO_LR_PHY_EN_3_0_GBPS (0x9)
-#define MPII_EVENT_SAS_TOPO_LR_PHY_EN_6_0_GBPS (0xa)
u_int8_t phy_status;
#define MPII_EVENT_SAS_TOPO_PS_RC_MASK (0x0f)
-#define MPII_EVENT_SAS_TOPO_PS_RC_TARG_ADDED (0x01)
-#define MPII_EVENT_SAS_TOPO_PS_RC_TARG_NO_RESPOND_MISS (0x02)
-#define MPII_EVENT_SAS_TOPO_PS_RC_PHY_LINK_STATE_CHANGE (0x03)
-#define MPII_EVENT_SAS_TOPO_PS_RC_PHY_LINK_STATE_NOCHNG (0x04)
-#define MPII_EVENT_SAS_TOPO_PS_RC_WITHIN_DELAY_TIMER (0x05)
-#define MPII_EVENT_SAS_TOPO_PS_PHY_VACANT_MASK (0x80)
-#define MPII_EVENT_SAS_TOPO_PS_PHY_VACANT_NOT_VACANT (0x00)
-#define MPII_EVENT_SAS_TOOP_PS_PHY_VACANT_ACCESS_DENIED (0x80)
+#define MPII_EVENT_SAS_TOPO_PS_RC_ADDED (0x01)
+#define MPII_EVENT_SAS_TOPO_PS_RC_MISSING (0x02)
} __packed;
struct mpii_evt_ir_cfg_change_list {
@@ -1630,19 +1628,17 @@ struct mpii_evt_ir_cfg_change_list {
u_int8_t config_num;
u_int32_t flags;
-#define MPII_EVT_IR_CFG_CHANGE_LIST_FLAGS_CFG_MASK (0x1)
-#define MPII_EVT_IR_CFG_CHANGE_LIST_FLAGS_CFG_NATIVE (0)
-#define MPII_EVT_IR_CFG_CHANGE_LIST_FLAGS_CFG_FOREIGN (1)
-
+#define MPII_EVT_IR_CFG_CHANGE_LIST_FOREIGN (0x1)
+
/* followed by num_elements struct mpii_evt_ir_cfg_elements */
} __packed;
struct mpii_evt_ir_cfg_element {
u_int16_t element_flags;
-#define MPII_EVT_IR_CFG_ELEMENT_EF_ELEMENT_TYPE_MASK (0xf)
-#define MPII_EVT_IR_CFG_ELEMENT_EF_ELEMENT_TYPE_VOLUME (0x0)
-#define MPII_EVT_IR_CFG_ELEMENT_EF_ELEMENT_TYPE_VOL_PD (0x1)
-#define MPII_EVT_IR_CFG_ELEMENT_EF_ELEMENT_TYPE_HSP_PD (0x2)
+#define MPII_EVT_IR_CFG_ELEMENT_TYPE_MASK (0xf)
+#define MPII_EVT_IR_CFG_ELEMENT_TYPE_VOLUME (0x0)
+#define MPII_EVT_IR_CFG_ELEMENT_TYPE_VOLUME_DISK (0x1)
+#define MPII_EVT_IR_CFG_ELEMENT_TYPE_HOT_SPARE (0x2)
u_int16_t vol_dev_handle;
u_int8_t reason_code;
@@ -1688,7 +1684,7 @@ uint32_t mpii_debug = 0
| MPII_D_CCB
| MPII_D_PPR
| MPII_D_RAID
- | MPII_D_EVT
+ | MPII_D_EVT
| MPII_D_CFG
| MPII_D_MAP
;
@@ -1733,45 +1729,23 @@ struct mpii_rcb {
};
struct mpii_device {
-
- RB_ENTRY(mpii_device) rb_entry;
-
+ int flags;
+#define MPII_DF_ATTACH (0x0001)
+#define MPII_DF_DETACH (0x0002)
+#define MPII_DF_HIDDEN (0x0004)
+#define MPII_DF_UNUSED (0x0008)
+#define MPII_DF_VOLUME (0x0010)
+#define MPII_DF_VOLUME_DISK (0x0020)
+#define MPII_DF_HOT_SPARE (0x0040)
+ short slot;
+ short percent;
u_int16_t dev_handle;
+ u_int16_t enclosure;
+ u_int16_t expander;
u_int8_t phy_num;
- u_int8_t type;
-#define MPII_DEV_TYPE_PD (0x00)
-#define MPII_DEV_TYPE_VD_PD (0x01)
-#define MPII_DEV_TYPE_VD (0x02)
-
- u_int16_t enclosure_handle;
-
- u_int16_t expander_dev_handle;
u_int8_t physical_port;
-
- u_int32_t wwid;
-
- u_int32_t flags;
-#define MPII_DEV_HIDDEN (1<<0)
-#define MPII_DEV_INTERFACE_SAS (1<<4)
-#define MPII_DEV_INTERFACE_SATA (1<<5)
-#define MPII_DEV_SCSI_ML_ATTACH (1<<8)
-#define MPII_DEV_UNUSED (1<<31)
};
-int mpii_dev_cmp(struct mpii_device *, struct mpii_device *);
-
-int
-mpii_dev_cmp(struct mpii_device *a, struct mpii_device *b)
-{
- return (a->dev_handle < b->dev_handle ? -1 :
- a->dev_handle > b->dev_handle);
-}
-
-RB_HEAD(mpii_dev_tree, mpii_device) mpii_dev_head =
- RB_INITIALIZER(&mpii_dev_head);
-RB_PROTOTYPE(mpii_dev_tree, mpii_device, rb_entry, mpii_dev_cmp)
-RB_GENERATE(mpii_dev_tree, mpii_device, rb_entry, mpii_dev_cmp)
-
struct mpii_ccb {
struct mpii_softc *ccb_sc;
int ccb_smid;
@@ -1807,7 +1781,7 @@ struct mpii_softc {
struct scsibus_softc *sc_scsibus;
- struct mpii_device **sc_mpii_dev;
+ struct mpii_device **sc_devs;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
@@ -1823,8 +1797,7 @@ struct mpii_softc {
int sc_first_sgl_len;
int sc_chain_len;
int sc_max_sgl_len;
-
- u_int8_t sc_ir_firmware;
+
u_int8_t sc_ioc_event_replay;
u_int16_t sc_max_enclosures;
u_int16_t sc_max_expanders;
@@ -1834,18 +1807,11 @@ struct mpii_softc {
u_int8_t sc_dpm_enabled;
u_int8_t sc_num_reserved_entries;
u_int8_t sc_reserve_tid0;
+ u_int16_t sc_vd_count;
u_int16_t sc_vd_id_low;
u_int16_t sc_vd_id_hi;
u_int16_t sc_pd_id_start;
- u_int16_t sc_pd_count;
- u_int16_t sc_vd_count;
u_int8_t sc_num_channels;
- /* XXX not sure these below will stay */
- u_int8_t sc_num_enclosure_table_entries;
- u_int32_t sc_pending_map_events;
- u_int8_t sc_tracking_map_events;
- int sc_discovery_in_progress;
- /* end list of likely to be cut entries */
int sc_target;
int sc_ioc_number;
u_int8_t sc_vf_id;
@@ -1860,17 +1826,18 @@ struct mpii_softc {
struct mpii_rcb *sc_rcbs;
struct mpii_dmamem *sc_reply_postq;
- struct mpii_reply_descriptor *sc_reply_postq_kva;
+ struct mpii_reply_descr *sc_reply_postq_kva;
int sc_reply_post_host_index;
struct mpii_dmamem *sc_reply_freeq;
int sc_reply_free_host_index;
-
+
/* scsi ioctl from sd device */
int (*sc_ioctl)(struct device *, u_long, caddr_t);
struct rwlock sc_lock;
+ int sc_nsensors;
struct ksensor *sc_sensors;
struct ksensordev sc_sensordev;
};
@@ -1901,7 +1868,7 @@ struct cfattach mpii_pci_ca = {
#define PWRITE(s, r, v) pci_conf_write((s)->psc_pc, (s)->psc_tag, (r), (v))
static const struct pci_matchid mpii_devices[] = {
- { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS2008 }
+ { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS2008 }
};
int
@@ -1966,7 +1933,7 @@ mpii_pci_attach(struct device *parent, struct device *self, void *aux)
goto unmap;
}
printf(": %s", intrstr);
-
+
#ifdef __sparc64__
/*
* Walk up the Open Firmware device tree until we find a
@@ -1979,8 +1946,9 @@ mpii_pci_attach(struct device *parent, struct device *self, void *aux)
sizeof(sc->sc_target))
break;
node = OF_parent(node);
+ }
#endif
-
+
if (mpii_attach(sc) != 0) {
/* error printed by mpii_attach */
goto deintr;
@@ -2031,8 +1999,8 @@ int mpii_scsi_ioctl(struct scsi_link *, u_long, caddr_t,
struct scsi_adapter mpii_switch = {
mpii_scsi_cmd,
- mpii_minphys,
- mpii_scsi_probe, /* XXX JPG scsi_probe may prove useful for mapping nonsense */
+ mpii_minphys,
+ mpii_scsi_probe,
NULL,
mpii_scsi_ioctl
};
@@ -2052,15 +2020,18 @@ struct mpii_ccb *mpii_get_ccb(struct mpii_softc *);
void mpii_put_ccb(struct mpii_softc *, struct mpii_ccb *);
int mpii_alloc_replies(struct mpii_softc *);
int mpii_alloc_queues(struct mpii_softc *);
-int mpii_alloc_dev(struct mpii_softc *);
void mpii_push_reply(struct mpii_softc *, u_int32_t);
void mpii_push_replies(struct mpii_softc *);
+int mpii_alloc_dev(struct mpii_softc *);
+int mpii_insert_dev(struct mpii_softc *, struct mpii_device *);
+int mpii_remove_dev(struct mpii_softc *, struct mpii_device *);
+struct mpii_device *mpii_find_dev(struct mpii_softc *, u_int16_t);
+
void mpii_start(struct mpii_softc *, struct mpii_ccb *);
int mpii_complete(struct mpii_softc *, struct mpii_ccb *, int);
int mpii_poll(struct mpii_softc *, struct mpii_ccb *, int);
-int mpii_reply(struct mpii_softc *,
- struct mpii_reply_descriptor *);
+int mpii_reply(struct mpii_softc *, struct mpii_reply_descr *);
void mpii_init_queues(struct mpii_softc *);
@@ -2089,26 +2060,23 @@ int mpii_iocinit(struct mpii_softc *);
int mpii_iocfacts(struct mpii_softc *);
int mpii_portfacts(struct mpii_softc *);
int mpii_portenable(struct mpii_softc *);
-int mpii_cfg_coalescing(struct mpii_softc *);
+int mpii_cfg_coalescing(struct mpii_softc *);
int mpii_eventnotify(struct mpii_softc *);
void mpii_eventnotify_done(struct mpii_ccb *);
void mpii_eventack(struct mpii_softc *,
struct mpii_msg_event_reply *);
void mpii_eventack_done(struct mpii_ccb *);
-void mpii_event_process(struct mpii_softc *,
+void mpii_event_process(struct mpii_softc *,
struct mpii_msg_reply *);
-void mpii_event_process_sas_discovery(struct mpii_softc *,
+void mpii_event_sas(struct mpii_softc *,
struct mpii_msg_event_reply *);
-void mpii_event_process_sas_topo_change(struct mpii_softc *,
+void mpii_event_raid(struct mpii_softc *,
struct mpii_msg_event_reply *);
-void mpii_event_process_ir_cfg_change_list(struct mpii_softc *,
- struct mpii_msg_event_reply *);
-void mpii_event_process_ir_phys_disk(struct mpii_softc *,
- struct mpii_msg_event_reply *);
-/*
-void mpii_evt_sas(void *, void *);
-*/
+void mpii_event_defer(void *, void *);
+
+void mpii_sas_remove_device(struct mpii_softc *, u_int16_t);
+
int mpii_req_cfg_header(struct mpii_softc *, u_int8_t,
u_int8_t, u_int32_t, int, void *);
int mpii_req_cfg_page(struct mpii_softc *, u_int32_t, int,
@@ -2125,7 +2093,7 @@ int mpii_bio_hs(struct mpii_softc *, struct bioc_disk *, int,
u_int8_t, int *);
int mpii_bio_disk(struct mpii_softc *, struct bioc_disk *,
u_int8_t);
-int mpii_bio_getphy(struct mpii_softc *, u_int16_t, u_int16_t *);
+struct mpii_device *mpii_find_vol(struct mpii_softc *, int);
#ifndef SMALL_KERNEL
int mpii_bio_volstate(struct mpii_softc *, struct bioc_vol *);
int mpii_create_sensors(struct mpii_softc *);
@@ -2186,7 +2154,7 @@ mpii_attach(struct mpii_softc *sc)
printf("\n");
/* disable interrupts */
- mpii_write(sc, MPII_INTR_MASK,
+ mpii_write(sc, MPII_INTR_MASK,
MPII_INTR_MASK_RESET | MPII_INTR_MASK_REPLY
| MPII_INTR_MASK_DOORBELL);
@@ -2247,7 +2215,7 @@ mpii_attach(struct mpii_softc *sc)
}
/* XXX bail on unsupported porttype? */
- if ((sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_SAS_PHYSICAL) ||
+ if ((sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_SAS_PHYSICAL) ||
(sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL)) {
if (mpii_eventnotify(sc) != 0) {
printf("%s: unable to enable events\n", DEVNAME(sc));
@@ -2256,7 +2224,7 @@ mpii_attach(struct mpii_softc *sc)
}
if (mpii_alloc_dev(sc) != 0) {
- printf("%s: unable to allocate memory for mpii_dev\n",
+ printf("%s: unable to allocate memory for mpii_dev\n",
DEVNAME(sc));
goto free_queues;
}
@@ -2264,8 +2232,7 @@ mpii_attach(struct mpii_softc *sc)
if (mpii_portenable(sc) != 0) {
printf("%s: unable to enable port\n", DEVNAME(sc));
goto free_dev;
- } /* assume all discovery events are complete by now */
-
+ }
rw_init(&sc->sc_lock, "mpii_lock");
@@ -2282,29 +2249,32 @@ mpii_attach(struct mpii_softc *sc)
/* config_found() returns the scsibus attached to us */
sc->sc_scsibus = (struct scsibus_softc *) config_found(&sc->sc_dev,
- &saa, scsiprint);
+ &saa, scsiprint);
/* enable interrupts */
- mpii_write(sc, MPII_INTR_MASK, MPII_INTR_MASK_DOORBELL
+ mpii_write(sc, MPII_INTR_MASK, MPII_INTR_MASK_DOORBELL
| MPII_INTR_MASK_RESET);
#if NBIO > 0
- if (bio_register(&sc->sc_dev, mpii_ioctl) != 0)
- panic("%s: controller registration failed", DEVNAME(sc));
- else
- sc->sc_ioctl = mpii_ioctl;
+ if (ISSET(sc->sc_flags, MPII_F_RAID)) {
+ if (bio_register(&sc->sc_dev, mpii_ioctl) != 0)
+ panic("%s: controller registration failed",
+ DEVNAME(sc));
+ else
+ sc->sc_ioctl = mpii_ioctl;
#ifndef SMALL_KERNEL
- if (mpii_create_sensors(sc) != 0)
- printf("%s: unable to create sensors\n", DEVNAME(sc));
+ if (mpii_create_sensors(sc) != 0)
+ printf("%s: unable to create sensors\n", DEVNAME(sc));
#endif
+ }
#endif
return (0);
free_dev:
- if (sc->sc_mpii_dev)
- free(sc->sc_mpii_dev, M_DEVBUF);
+ if (sc->sc_devs)
+ free(sc->sc_devs, M_DEVBUF);
free_queues:
bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_freeq),
@@ -2339,8 +2309,7 @@ int
mpii_intr(void *arg)
{
struct mpii_softc *sc = arg;
- struct mpii_reply_descriptor *rdp;
- u_int8_t reply_flags;
+ struct mpii_reply_descr *rdp;
int rv = 0;
do {
@@ -2348,16 +2317,17 @@ mpii_intr(void *arg)
0, 8 * sc->sc_reply_post_qdepth, BUS_DMASYNC_POSTWRITE);
rdp = &sc->sc_reply_postq_kva[sc->sc_reply_post_host_index];
- reply_flags = (u_int8_t)(rdp->reply_flags) &
- MPII_REPLY_DESCR_FLAGS_TYPE_MASK;
- if ((reply_flags == MPII_REPLY_DESCR_FLAGS_UNUSED))
+ if ((rdp->reply_flags & MPII_REPLY_DESCR_TYPE_MASK) ==
+ MPII_REPLY_DESCR_UNUSED)
break;
- if (rdp->type_dependent2 == 0xffffffff) {
+ if (rdp->data == 0xffffffff) {
/*
* ioc is still writing to the reply post queue
* race condition - bail!
*/
- printf("%s: ioc is writing a reply\n", DEVNAME(sc));
+ printf("%s: ioc is writing a reply @ %d/%d (kva %p)\n",
+ DEVNAME(sc), sc->sc_reply_post_host_index,
+ sc->sc_reply_post_qdepth, rdp);
break;
}
mpii_reply(sc, rdp);
@@ -2376,11 +2346,7 @@ mpii_intr(void *arg)
void
mpii_timeout_xs(void *arg)
{
- struct mpii_ccb *ccb = arg;
- struct mpii_softc *sc = ccb->ccb_sc;
-
- printf("%s: xfer timeout, ccb %d state %d\n", DEVNAME(sc),
- ccb->ccb_smid, ccb->ccb_state);
+ /* nothing smart could be done here */
}
int
@@ -2425,7 +2391,6 @@ mpii_load_xs(struct mpii_ccb *ccb)
}
for (i = 0; i < dmap->dm_nsegs; i++) {
-
if (nsge == ce) {
nsge++;
sge->sg_hdr |= htole32(MPII_SGE_FL_LAST);
@@ -2503,22 +2468,18 @@ int
mpii_scsi_probe(struct scsi_link *link)
{
struct mpii_softc *sc = link->adapter_softc;
- struct mpii_device *device;
- u_int8_t flags;
+ int flags;
- if ((sc->sc_porttype != MPII_PORTFACTS_PORTTYPE_SAS_PHYSICAL) &&
- (sc->sc_porttype != MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL))
+ if ((sc->sc_porttype != MPII_PORTFACTS_PORTTYPE_SAS_PHYSICAL) &&
+ (sc->sc_porttype != MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL))
return (1);
- if (sc->sc_mpii_dev[link->target] == NULL)
- return (1);
-
- device = (struct mpii_device *)sc->sc_mpii_dev[link->target];
- flags = device->flags;
- if ((flags & MPII_DEV_UNUSED) || (flags & MPII_DEV_HIDDEN))
+ if (sc->sc_devs[link->target] == NULL)
return (1);
- sc->sc_mpii_dev[link->target]->flags |= MPII_DEV_SCSI_ML_ATTACH;
+ flags = sc->sc_devs[link->target]->flags;
+ if (ISSET(flags, MPII_DF_HIDDEN) || ISSET(flags, MPII_DF_UNUSED))
+ return (1);
return (0);
}
@@ -2902,10 +2863,8 @@ mpii_iocfacts(struct mpii_softc *sc)
sc->sc_maxchdepth = ifp.max_chain_depth;
sc->sc_ioc_number = ifp.ioc_number;
sc->sc_vf_id = ifp.vf_id;
-
+
sc->sc_num_ports = ifp.number_of_ports;
- sc->sc_ir_firmware = (letoh32(ifp.ioc_capabilities) &
- MPII_IOCFACTS_CAPABILITY_INTEGRATED_RAID) ? 1 : 0;
sc->sc_ioc_event_replay = (letoh32(ifp.ioc_capabilities) &
MPII_IOCFACTS_CAPABILITY_EVENT_REPLAY) ? 1 : 0;
sc->sc_max_enclosures = letoh16(ifp.max_enclosures);
@@ -2913,25 +2872,29 @@ mpii_iocfacts(struct mpii_softc *sc)
sc->sc_max_volumes = ifp.max_volumes;
sc->sc_max_devices = ifp.max_volumes + letoh16(ifp.max_targets);
sc->sc_num_channels = 1;
-
+
+ if (ISSET(letoh32(ifp.ioc_capabilities),
+ MPII_IOCFACTS_CAPABILITY_INTEGRATED_RAID))
+ SET(sc->sc_flags, MPII_F_RAID);
+
sc->sc_request_depth = MIN(letoh16(ifp.request_credit),
MPII_MAX_REQUEST_CREDIT);
- /* should not be multiple of 16 */
+ /* should not be multiple of 16 */
sc->sc_num_reply_frames = sc->sc_request_depth + 32;
if (!(sc->sc_num_reply_frames % 16))
sc->sc_num_reply_frames--;
/* must be multiple of 16 */
- sc->sc_reply_free_qdepth = sc->sc_num_reply_frames +
+ sc->sc_reply_free_qdepth = sc->sc_num_reply_frames +
(16 - (sc->sc_num_reply_frames % 16));
sc->sc_reply_post_qdepth = sc->sc_request_depth +
sc->sc_num_reply_frames + 1;
- if (sc->sc_reply_post_qdepth >
+ if (sc->sc_reply_post_qdepth >
ifp.max_reply_descriptor_post_queue_depth)
- sc->sc_reply_post_qdepth =
+ sc->sc_reply_post_qdepth =
ifp.max_reply_descriptor_post_queue_depth;
DNPRINTF(MPII_D_MISC, "%s: sc_request_depth: %d "
@@ -3066,8 +3029,8 @@ mpii_portfacts(struct mpii_softc *sc)
{
struct mpii_msg_portfacts_request *pfq;
struct mpii_msg_portfacts_reply *pfp;
- int rv = 1, s;
- struct mpii_ccb *ccb;
+ int rv = 1, s;
+ struct mpii_ccb *ccb;
DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts\n", DEVNAME(sc));
@@ -3082,8 +3045,8 @@ mpii_portfacts(struct mpii_softc *sc)
ccb->ccb_done = mpii_empty_done;
pfq = ccb->ccb_cmd;
-
- bzero(pfq, sizeof(struct mpii_msg_portfacts_request));
+
+ bzero(pfq, sizeof(*pfq));
pfq->function = MPII_FUNCTION_PORT_FACTS;
pfq->chain_offset = 0;
@@ -3102,7 +3065,7 @@ mpii_portfacts(struct mpii_softc *sc)
DEVNAME(sc));
goto err;
}
-
+
pfp = ccb->ccb_rcb->rcb_reply;
DNPRINTF(MPII_D_MISC, "%s pfp: 0x%04x\n", DEVNAME(sc), pfp);
@@ -3116,17 +3079,12 @@ mpii_portfacts(struct mpii_softc *sc)
letoh16(pfp->ioc_status));
DNPRINTF(MPII_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc),
letoh32(pfp->ioc_loginfo));
- DNPRINTF(MPII_D_MISC, "%s: port_type: 0x%02x\n", DEVNAME(sc),
+ DNPRINTF(MPII_D_MISC, "%s: port_type: 0x%02x\n", DEVNAME(sc),
pfp->port_type);
DNPRINTF(MPII_D_MISC, "%s: max_posted_cmd_buffers: %d\n", DEVNAME(sc),
letoh16(pfp->max_posted_cmd_buffers));
sc->sc_porttype = pfp->port_type;
- /* XXX JPG no such field in MPI2 .... but the dilemma is what
- * to return to sc_link.adapter_target ... is -1 acceptable? fake 255?
- if (sc->sc_target == -1)
- sc->sc_target = letoh16(pfp->port_scsi_id);
- */
mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
rv = 0;
@@ -3220,13 +3178,14 @@ mpii_cfg_coalescing(struct mpii_softc *sc)
struct mpii_cfg_hdr hdr;
struct mpii_cfg_ioc_pg1 pg;
u_int32_t flags;
-
- if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_IOC, 1, 0, &hdr) != 0) {
+
+ if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_IOC, 1, 0,
+ &hdr) != 0) {
DNPRINTF(MPII_D_MISC, "%s: unable to fetch IOC page 1 header\n",
DEVNAME(sc));
return (1);
}
-
+
if (mpii_cfg_page(sc, 0, &hdr, 1, &pg, sizeof(pg)) != 0) {
DNPRINTF(MPII_D_MISC, "%s: unable to fetch IOC page 1\n"
"page 1\n", DEVNAME(sc));
@@ -3256,21 +3215,15 @@ mpii_cfg_coalescing(struct mpii_softc *sc)
}
#define MPII_EVENT_MASKALL(enq) do { \
- int i; \
- \
- for (i = 0; i < 4; i++) \
- enq->event_masks[i] = 0xffffffff; \
+ enq->event_masks[0] = 0xffffffff; \
+ enq->event_masks[1] = 0xffffffff; \
+ enq->event_masks[2] = 0xffffffff; \
+ enq->event_masks[3] = 0xffffffff; \
} while (0)
-#define MPII_EVENT_UNMASK(enq, evt) do { \
- int i; \
- \
- for (i = 0; i < 4; i++) \
- if (evt < 32 * (i + 1)) { \
- enq->event_masks[i] &= \
- htole32(~(1 << (evt - 32 * i))); \
- break; \
- } \
+#define MPII_EVENT_UNMASK(enq, evt) do { \
+ enq->event_masks[evt / 32] &= \
+ htole32(~(1 << (evt % 32))); \
} while (0)
int
@@ -3317,7 +3270,7 @@ mpii_eventnotify(struct mpii_softc *sc)
MPII_EVENT_UNMASK(enq, MPII_EVENT_IR_PHYSICAL_DISK);
MPII_EVENT_UNMASK(enq, MPII_EVENT_IR_OPERATION_STATUS);
- s = splbio();
+ s = splbio();
mpii_start(sc, ccb);
splx(s);
@@ -3325,346 +3278,344 @@ mpii_eventnotify(struct mpii_softc *sc)
}
void
-mpii_event_process_ir_cfg_change_list(struct mpii_softc *sc,
- struct mpii_msg_event_reply *enp)
+mpii_eventnotify_done(struct mpii_ccb *ccb)
{
- struct mpii_evt_ir_cfg_change_list *ccl;
- struct mpii_evt_ir_cfg_element *ce;
- struct mpii_device *device; //, n;
- u_int16_t type;
- u_int32_t flags;
- int i, volid;
+ struct mpii_softc *sc = ccb->ccb_sc;
- ccl = (struct mpii_evt_ir_cfg_change_list *)(enp + 1);
+ DNPRINTF(MPII_D_EVT, "%s: mpii_eventnotify_done\n", DEVNAME(sc));
- flags = letoh32(ccl->flags);
+ mpii_event_process(sc, ccb->ccb_rcb->rcb_reply);
- DNPRINTF(MPII_D_MAP, "%s: mpii_event_process_ir_cfg_change\n",
- DEVNAME(sc));
- DNPRINTF(MPII_D_MAP," %s: flags: 0x%08x num_elements: %d\n",
- DEVNAME(sc), flags, ccl->num_elements);
+ mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
+ mpii_put_ccb(sc, ccb);
+}
- if ((flags & MPII_EVT_IR_CFG_CHANGE_LIST_FLAGS_CFG_MASK) ==
- MPII_EVT_IR_CFG_CHANGE_LIST_FLAGS_CFG_FOREIGN)
- /* bail on foreign configurations */
- return;
+void
+mpii_event_raid(struct mpii_softc *sc, struct mpii_msg_event_reply *enp)
+{
+ struct mpii_evt_ir_cfg_change_list *ccl;
+ struct mpii_evt_ir_cfg_element *ce;
+ struct mpii_device *dev;
+ u_int16_t type;
+ int i;
+
+ ccl = (struct mpii_evt_ir_cfg_change_list *)(enp + 1);
if (ccl->num_elements == 0)
return;
+ if (ISSET(letoh32(ccl->flags), MPII_EVT_IR_CFG_CHANGE_LIST_FOREIGN))
+ /* bail on foreign configurations */
+ return;
ce = (struct mpii_evt_ir_cfg_element *)(ccl + 1);
for (i = 0; i < ccl->num_elements; i++, ce++) {
- type = (letoh16(ce->element_flags) &
- MPII_EVT_IR_CFG_ELEMENT_EF_ELEMENT_TYPE_MASK);
-
+ type = (letoh16(ce->element_flags) &
+ MPII_EVT_IR_CFG_ELEMENT_TYPE_MASK);
+
switch (type) {
- case MPII_EVT_IR_CFG_ELEMENT_EF_ELEMENT_TYPE_VOLUME:
+ case MPII_EVT_IR_CFG_ELEMENT_TYPE_VOLUME:
switch (ce->reason_code) {
case MPII_EVT_IR_CFG_ELEMENT_RC_ADDED:
case MPII_EVT_IR_CFG_ELEMENT_RC_VOLUME_CREATED:
- /* XXX check for exceeding boundaries */
- volid = sc->sc_vd_id_low + sc->sc_vd_count;
-
- /* do magic to map vol dev_handle to TID */
- DNPRINTF(MPII_D_MAP, "%s: mapping: attaching "
- "vol_dev_handle: 0x%04x to volid %d\n",
- DEVNAME(sc), letoh16(ce->vol_dev_handle),
- volid);
-
- if (sc->sc_mpii_dev[volid] == NULL) {
- device = malloc(sizeof(struct mpii_device),
- M_DEVBUF, M_NOWAIT | M_ZERO);
- if (device == NULL) {
- printf("%s: mpii_event_ir_cfg_change_list "
- "unable to allocate mpii_device\n",
- DEVNAME(sc));
- continue;
- }
-
- sc->sc_vd_count++;
- device->type = MPII_DEV_TYPE_VD;
- device->dev_handle = letoh16(ce->vol_dev_handle);
- /* XXX bunch more fields */
-
- sc->sc_mpii_dev[volid] = device;
- RB_INSERT(mpii_dev_tree, &mpii_dev_head, sc->sc_mpii_dev[volid]);
- } else {
- if (!(sc->sc_mpii_dev[volid]->flags & MPII_DEV_UNUSED)) {
- printf("%s: mpii_evt_ir_cfg_change_list "
- "volume id collision - volid %d\n",
- DEVNAME(sc), volid);
- continue;
- } else {
- /* sc->sc_mpii_dev[volid] already
- * exists and is not flagged as
- * UNUSED so we gracefully (sic)
- * do nothing at this time.
- */
- }
+ if (mpii_find_dev(sc,
+ letoh16(ce->vol_dev_handle))) {
+ printf("%s: device %#x is already "
+ "configured\n", DEVNAME(sc),
+ letoh16(ce->vol_dev_handle));
+ break;
+ }
+ dev = malloc(sizeof(*dev), M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+ if (!dev) {
+ printf("%s: failed to allocate a "
+ "device structure\n", DEVNAME(sc));
+ break;
}
+ SET(dev->flags, MPII_DF_VOLUME);
+ dev->slot = sc->sc_vd_id_low + sc->sc_vd_count;
+ dev->dev_handle = letoh16(ce->vol_dev_handle);
+ if (mpii_insert_dev(sc, dev)) {
+ free(dev, M_DEVBUF);
+ break;
+ }
+ sc->sc_vd_count++;
break;
-
case MPII_EVT_IR_CFG_ELEMENT_RC_REMOVED:
case MPII_EVT_IR_CFG_ELEMENT_RC_VOLUME_DELETED:
- /* do magic to remove volume */
- break;
-
- case MPII_EVT_IR_CFG_ELEMENT_RC_NO_CHANGE:
- default:
+ if (!(dev = mpii_find_dev(sc,
+ letoh16(ce->vol_dev_handle))))
+ break;
+ mpii_remove_dev(sc, dev);
+ sc->sc_vd_count--;
break;
}
break;
-
- case MPII_EVT_IR_CFG_ELEMENT_EF_ELEMENT_TYPE_VOL_PD:
- switch (ce->reason_code) {
- case MPII_EVT_IR_CFG_ELEMENT_RC_HIDE:
- case MPII_EVT_IR_CFG_ELEMENT_RC_PD_CREATED:
- /* do magic to hide/tag from OS view */
- //DNPRINTF(MPII_D_MAP, "%s: mapping: hiding "
- // "pd_dev_handle: 0x%04x\n", DEVNAME(sc),
- // letoh16(ce->phys_disk_dev_handle));
- // n.dev_handle = letoh16(ce->phys_disk_dev_handle);
- // device = RB_FIND(mpii_dev_tree, &mpii_dev_head, &n);
- //device = NULL;
- //if (device)
- // device->flags |= MPII_DEV_HIDDEN;
- break;
-
- case MPII_EVT_IR_CFG_ELEMENT_RC_UNHIDE:
- case MPII_EVT_IR_CFG_ELEMENT_RC_PD_DELETED:
- /*
- * XXX remove evidence of this disk (and no longer
- * bother to hide it
- */
- break;
-
- case MPII_EVT_IR_CFG_ELEMENT_RC_NO_CHANGE:
- default:
- break;
-
+ case MPII_EVT_IR_CFG_ELEMENT_TYPE_VOLUME_DISK:
+ if (ce->reason_code ==
+ MPII_EVT_IR_CFG_ELEMENT_RC_PD_CREATED ||
+ ce->reason_code ==
+ MPII_EVT_IR_CFG_ELEMENT_RC_HIDE) {
+ /* there should be an underlying sas drive */
+ if (!(dev = mpii_find_dev(sc,
+ letoh16(ce->phys_disk_dev_handle))))
+ break;
+ /* promoted from a hot spare? */
+ CLR(dev->flags, MPII_DF_HOT_SPARE);
+ SET(dev->flags, MPII_DF_VOLUME_DISK |
+ MPII_DF_HIDDEN);
}
break;
-
- case MPII_EVT_IR_CFG_ELEMENT_EF_ELEMENT_TYPE_HSP_PD:
- break;
-
- default:
- /* XXX oops */
+ case MPII_EVT_IR_CFG_ELEMENT_TYPE_HOT_SPARE:
+ if (ce->reason_code ==
+ MPII_EVT_IR_CFG_ELEMENT_RC_HIDE) {
+ /* there should be an underlying sas drive */
+ if (!(dev = mpii_find_dev(sc,
+ letoh16(ce->phys_disk_dev_handle))))
+ break;
+ SET(dev->flags, MPII_DF_HOT_SPARE |
+ MPII_DF_HIDDEN);
+ }
break;
}
}
}
void
-mpii_event_process_sas_topo_change(struct mpii_softc *sc,
- struct mpii_msg_event_reply *enp)
+mpii_event_sas(struct mpii_softc *sc, struct mpii_msg_event_reply *enp)
{
- struct mpii_evt_sas_topo_change_list *tcl;
+ struct mpii_evt_sas_tcl *tcl;
struct mpii_evt_phy_entry *pe;
- u_int8_t reason_code;
- struct mpii_device *device;
- int i, slotid;
-
- tcl = (struct mpii_evt_sas_topo_change_list *)(enp + 1);
+ struct mpii_device *dev;
+ int i;
- DNPRINTF(MPII_D_MAP, "%s: sas_topo_change: start_phy_num: %d "
- "num_entries: %d physical_port %d\n", DEVNAME(sc),
- tcl->start_phy_num, tcl->num_entries, tcl->physical_port);
+ tcl = (struct mpii_evt_sas_tcl *)(enp + 1);
- if (tcl->num_entries <= 0)
+ if (tcl->num_entries == 0)
return;
pe = (struct mpii_evt_phy_entry *)(tcl + 1);
for (i = 0; i < tcl->num_entries; i++, pe++) {
- reason_code = (pe->phy_status & MPII_EVENT_SAS_TOPO_PS_RC_MASK);
-
- switch (reason_code) {
- case MPII_EVENT_SAS_TOPO_PS_RC_TARG_ADDED:
- /* XXX begging to move this into a f() */
- DNPRINTF(MPII_D_MAP, "%s: mapping: attached_dev_handle: "
- "0x%04x link_rate: 0x%02x phy_status: 0x%02x\n",
- DEVNAME(sc), letoh16(pe->attached_dev_handle),
- pe->link_rate, pe->phy_status);
-
- /* XXX check for exceeding boundaries */
- slotid = sc->sc_pd_id_start + tcl->start_phy_num + i;
-
- if (sc->sc_mpii_dev[slotid])
- if (!(sc->sc_mpii_dev[slotid]->flags & MPII_DEV_UNUSED)) {
- printf("%s: mpii_evt_sas_topo_change "
- "slot id collision - slot %d\n",
- DEVNAME(sc), slotid);
- continue;
- }
-
- device = malloc(sizeof(struct mpii_device),
- M_DEVBUF, M_NOWAIT | M_ZERO);
- if (device == NULL) {
- printf("%s: mpii_event_ir_cfg_change_list "
- "unable to allocate mpii_device\n",
- DEVNAME(sc));
+ switch (pe->phy_status & MPII_EVENT_SAS_TOPO_PS_RC_MASK) {
+ case MPII_EVENT_SAS_TOPO_PS_RC_ADDED:
+ if (mpii_find_dev(sc, letoh16(pe->dev_handle))) {
+ printf("%s: device %#x is already "
+ "configured\n", DEVNAME(sc),
+ letoh16(pe->dev_handle));
break;
}
-
- sc->sc_pd_count++;
- device->dev_handle = letoh16(pe->attached_dev_handle);
- device->phy_num = tcl->start_phy_num + i;
- device->type = MPII_DEV_TYPE_PD;
+ dev = malloc(sizeof(*dev), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (!dev) {
+ printf("%s: failed to allocate a "
+ "device structure\n", DEVNAME(sc));
+ break;
+ }
+ dev->slot = sc->sc_pd_id_start + tcl->start_phy_num + i;
+ dev->dev_handle = letoh16(pe->dev_handle);
+ dev->phy_num = tcl->start_phy_num + i;
if (tcl->enclosure_handle)
- device->physical_port = tcl->physical_port;
- device->enclosure_handle = letoh16(tcl->enclosure_handle);
- device->expander_dev_handle = letoh16(tcl->expander_dev_handle);
- /* XXX
- device->wwid =
- device->flags =
- */
- sc->sc_mpii_dev[slotid] = device;
- RB_INSERT(mpii_dev_tree, &mpii_dev_head, device);
+ dev->physical_port = tcl->physical_port;
+ dev->enclosure = letoh16(tcl->enclosure_handle);
+ dev->expander = letoh16(tcl->expander_handle);
+ if (mpii_insert_dev(sc, dev)) {
+ free(dev, M_DEVBUF);
+ break;
+ }
+ if (sc->sc_scsibus) {
+ SET(dev->flags, MPII_DF_ATTACH);
+ if (scsi_task(mpii_event_defer, sc,
+ dev, 0) != 0)
+ printf("%s: unable to run device "
+ "attachment routine\n",
+ DEVNAME(sc));
+ }
break;
-
- case MPII_EVENT_SAS_TOPO_PS_RC_TARG_NO_RESPOND_MISS:
- /* according to MPI2 we need to:
- * a. abort all outstanding I/O operations
- * b. send a SAS IO unit control request w/ operation
- * set to MPII_SAS_OP_REMOVE_DEVICE to remove all IOC
- * resources associated with the device.
- */
- case MPII_EVENT_SAS_TOPO_PS_RC_PHY_LINK_STATE_CHANGE:
- case MPII_EVENT_SAS_TOPO_PS_RC_PHY_LINK_STATE_NOCHNG:
- case MPII_EVENT_SAS_TOPO_PS_RC_WITHIN_DELAY_TIMER:
- default:
- DNPRINTF(MPII_D_EVT, "%s: unhandled "
- "mpii_event_sas_topo_change reason code\n",
- DEVNAME(sc));
+ case MPII_EVENT_SAS_TOPO_PS_RC_MISSING:
+ if (!(dev = mpii_find_dev(sc,
+ letoh16(pe->dev_handle)))) {
+ printf("%s: nothing known about drive %#x\n",
+ DEVNAME(sc));
+ break;
+ }
+ mpii_remove_dev(sc, dev);
+ if (sc->sc_scsibus) {
+ SET(dev->flags, MPII_DF_DETACH);
+ if (scsi_task(mpii_event_defer, sc,
+ dev, 0) != 0)
+ printf("%s: unable to run device "
+ "detachment routine\n",
+ DEVNAME(sc));
+ }
break;
}
}
}
void
-mpii_event_process_sas_discovery(struct mpii_softc *sc, struct mpii_msg_event_reply *enp)
-{
- struct mpii_evt_sas_discovery *ds;
-
- ds = (struct mpii_evt_sas_discovery *)(enp + 1);
-
- if ((ds->flags & MPII_EVENT_SAS_DISC_FLAGS_DISC_IN_PROG_MASK) ==
- MPII_EVENT_SAS_DISC_FLAGS_DISC_IN_PROGRESS)
- sc->sc_discovery_in_progress = 1;
- else
- sc->sc_discovery_in_progress = 0;
-
- switch (ds->reason_code) {
- case MPII_EVENT_SAS_DISC_REASON_CODE_STARTED:
- break;
- case MPII_EVENT_SAS_DISC_REASON_CODE_COMPLETED:
- /* XXX look at ds->discovery_status */
- break;
- default:
- DNPRINTF(MPII_D_EVT, "%s: unknown reason for SAS device status "
- "change: 0x%02x\n", DEVNAME(sc), ds->reason_code);
- break;
- }
-}
-
-void
-mpii_event_process_ir_phys_disk(struct mpii_softc *sc, struct mpii_msg_event_reply *enp)
+mpii_event_process(struct mpii_softc *sc, struct mpii_msg_reply *prm)
{
- struct mpii_evt_ir_physical_disk *ipd;
-
- ipd = (struct mpii_evt_ir_physical_disk *)(enp + 1);
+ struct mpii_msg_event_reply *enp;
- /* XXX TODO:
- * process the event fully
- * understand that this is necesarily a IR_PD
- */
-}
+ enp = (struct mpii_msg_event_reply *)prm;
-void
-mpii_event_process(struct mpii_softc *sc, struct mpii_msg_reply *prm)
-{
- struct mpii_msg_event_reply *enp = (struct mpii_msg_event_reply *)prm;
-
- DNPRINTF(MPII_D_EVT, "%s: mpii_event_process\n", DEVNAME(sc));
-
- DNPRINTF(MPII_D_EVT, "%s: function: 0x%02x msg_length: %d "
- "event_data_length: %d\n", DEVNAME(sc), enp->function,
- enp->msg_length, letoh16(enp->event_data_length));
- DNPRINTF(MPII_D_EVT, "%s: ack_required: %d msg_flags 0x%02x\n",
- DEVNAME(sc), enp->ack_required, enp->msg_flags);
- DNPRINTF(MPII_D_EVT, "%s: ioc_status: 0x%04x\n", DEVNAME(sc),
- letoh16(enp->ioc_status));
- DNPRINTF(MPII_D_EVT, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc),
- letoh32(enp->ioc_loginfo));
- DNPRINTF(MPII_D_EVT, "%s: event: 0x%08x\n", DEVNAME(sc),
+ DNPRINTF(MPII_D_EVT, "%s: mpii_event_process: %#x\n", DEVNAME(sc),
letoh32(enp->event));
- DNPRINTF(MPII_D_EVT, "%s: event_context: 0x%08x\n", DEVNAME(sc),
- letoh32(enp->event_context));
-
+
switch (letoh32(enp->event)) {
- case MPII_EVENT_SAS_DISCOVERY:
- mpii_event_process_sas_discovery(sc, enp);
+ case MPII_EVENT_EVENT_CHANGE:
+ /* should be properly ignored */
+ break;
+ case MPII_EVENT_SAS_DISCOVERY: {
+ struct mpii_evt_sas_discovery *esd =
+ (struct mpii_evt_sas_discovery *)(enp + 1);
+
+ if (esd->reason_code ==
+ MPII_EVENT_SAS_DISC_REASON_CODE_COMPLETED &&
+ esd->discovery_status != 0)
+ printf("%s: sas discovery completed with status %#x\n",
+ esd->discovery_status);
+ }
break;
-
case MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
- mpii_event_process_sas_topo_change(sc, enp);
+ mpii_event_sas(sc, enp);
break;
-
case MPII_EVENT_SAS_DEVICE_STATUS_CHANGE:
- /* XXX */
break;
-
case MPII_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
- /* XXX track enclosures coming/going */
break;
+ case MPII_EVENT_IR_VOLUME: {
+ struct mpii_evt_ir_volume *evd =
+ (struct mpii_evt_ir_volume *)(enp + 1);
+ struct mpii_device *dev;
+#if NBIO > 0
+ const char *vol_states[] = {
+ BIOC_SVINVALID_S,
+ BIOC_SVOFFLINE_S,
+ BIOC_SVBUILDING_S,
+ BIOC_SVONLINE_S,
+ BIOC_SVDEGRADED_S,
+ BIOC_SVONLINE_S,
+ };
+#endif
- case MPII_EVENT_IR_VOLUME:
- /* XXX */
+ if (cold)
+ break;
+ if (!(dev = mpii_find_dev(sc, letoh16(evd->vol_dev_handle))))
+ break;
+#if NBIO > 0
+ if (evd->reason_code == MPII_EVENT_IR_VOL_RC_STATE_CHANGED)
+ printf("%s: volume %d state changed from %s to %s\n",
+ DEVNAME(sc), dev->slot - sc->sc_vd_id_low,
+ vol_states[evd->prev_value],
+ vol_states[evd->new_value]);
+#endif
+ if (evd->reason_code == MPII_EVENT_IR_VOL_RC_STATUS_CHANGED &&
+ ISSET(evd->new_value, MPII_CFG_RAID_VOL_0_STATUS_RESYNC) &&
+ !ISSET(evd->prev_value, MPII_CFG_RAID_VOL_0_STATUS_RESYNC))
+ printf("%s: started resync on a volume %d\n",
+ DEVNAME(sc), dev->slot - sc->sc_vd_id_low);
+ }
break;
-
case MPII_EVENT_IR_PHYSICAL_DISK:
- mpii_event_process_ir_phys_disk(sc, enp);
break;
-
case MPII_EVENT_IR_CONFIGURATION_CHANGE_LIST:
- mpii_event_process_ir_cfg_change_list(sc, enp);
+ mpii_event_raid(sc, enp);
break;
+ case MPII_EVENT_IR_OPERATION_STATUS: {
+ struct mpii_evt_ir_status *evs =
+ (struct mpii_evt_ir_status *)(enp + 1);
+ struct mpii_device *dev;
- case MPII_EVENT_IR_OPERATION_STATUS:
- case MPII_EVENT_TASK_SET_FULL:
- case MPII_EVENT_LOG_ENTRY_ADDED:
-
+ if (!(dev = mpii_find_dev(sc, letoh16(evs->vol_dev_handle))))
+ break;
+ if (evs->operation == MPII_EVENT_IR_RAIDOP_RESYNC)
+ dev->percent = evs->percent;
+ break;
+ }
default:
DNPRINTF(MPII_D_EVT, "%s: unhandled event 0x%02x\n",
DEVNAME(sc), letoh32(enp->event));
- break;
- }
-
-#ifdef MPII_DEBUG
- int i;
- for (i = 0; i < enp->event_data_length; i++) {
- DNPRINTF(MPII_D_EVT, "%s: event_data: 0x%08x\n", DEVNAME(sc),
- dwordn((enp+1), i));
}
-#endif /* MPII_DEBUG */
if (enp->ack_required)
mpii_eventack(sc, enp);
-}
+}
void
-mpii_eventnotify_done(struct mpii_ccb *ccb)
+mpii_event_defer(void *xsc, void *arg)
{
- struct mpii_softc *sc = ccb->ccb_sc;
+ struct mpii_softc *sc = xsc;
+ struct mpii_device *dev = arg;
- DNPRINTF(MPII_D_EVT, "%s: mpii_eventnotify_done\n", DEVNAME(sc));
+ /*
+ * SAS and IR events are delivered separately, so it won't hurt
+ * to wait for a second.
+ */
+ tsleep(sc, PRIBIO, "mpiipause", hz);
+
+ if (!ISSET(dev->flags, MPII_DF_HIDDEN)) {
+ if (ISSET(dev->flags, MPII_DF_ATTACH))
+ scsi_probe_target(sc->sc_scsibus, dev->slot);
+ else if (ISSET(dev->flags, MPII_DF_DETACH))
+ scsi_detach_target(sc->sc_scsibus, dev->slot,
+ DETACH_FORCE);
+ }
- mpii_event_process(sc, ccb->ccb_rcb->rcb_reply);
+ if (ISSET(dev->flags, MPII_DF_DETACH)) {
+ mpii_sas_remove_device(sc, dev->dev_handle);
+ free(dev, M_DEVBUF);
+ }
- mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
- mpii_put_ccb(sc, ccb);
+ CLR(dev->flags, MPII_DF_ATTACH | MPII_DF_DETACH);
+}
+
+void
+mpii_sas_remove_device(struct mpii_softc *sc, u_int16_t handle)
+{
+ struct mpii_msg_scsi_task_request *stq;
+ struct mpii_msg_sas_oper_request *soq;
+ struct mpii_ccb *ccb;
+ int s;
+
+ s = splbio();
+ ccb = mpii_get_ccb(sc);
+ splx(s);
+ if (ccb == NULL)
+ return;
+
+ stq = ccb->ccb_cmd;
+ stq->function = MPII_FUNCTION_SCSI_TASK_MGMT;
+ stq->task_type = MPII_SCSI_TASK_TARGET_RESET;
+ stq->dev_handle = htole16(handle);
+
+ ccb->ccb_done = (void (*)(struct mpii_ccb *))wakeup;
+ s = splbio();
+ mpii_start(sc, ccb);
+ while (ccb->ccb_state != MPII_CCB_READY)
+ tsleep(ccb, PRIBIO, "mpiitskmgmt", 0);
+ if (ccb->ccb_rcb != NULL)
+ mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
+ splx(s);
+
+ /* reuse a ccb */
+ ccb->ccb_state = MPII_CCB_READY;
+ ccb->ccb_rcb = NULL;
+
+ soq = ccb->ccb_cmd;
+ bzero(soq, sizeof(*soq));
+ soq->function = MPII_FUNCTION_SAS_IO_UNIT_CONTROL;
+ soq->operation = MPII_SAS_OP_REMOVE_DEVICE;
+ soq->dev_handle = htole16(handle);
+
+ ccb->ccb_done = (void (*)(struct mpii_ccb *))wakeup;
+ s = splbio();
+ mpii_start(sc, ccb);
+ while (ccb->ccb_state != MPII_CCB_READY)
+ tsleep(ccb, PRIBIO, "mpiisasop", 0);
+ if (ccb->ccb_rcb != NULL)
+ mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
+ splx(s);
}
int
@@ -3685,8 +3636,8 @@ mpii_get_ioc_pg8(struct mpii_softc *sc)
}
pagelen = hdr.page_length * 4; /* dwords to bytes */
-
- page = malloc(pagelen, M_TEMP, M_NOWAIT | M_CANFAIL);
+
+ page = malloc(pagelen, M_TEMP, M_NOWAIT);
if (page == NULL) {
DNPRINTF(MPII_D_CFG, "%s: mpii_get_ioc_pg8 unable to allocate "
"space for ioc config page 8\n", DEVNAME(sc));
@@ -3720,9 +3671,9 @@ mpii_get_ioc_pg8(struct mpii_softc *sc)
} else
sc->sc_num_reserved_entries = 0;
- flags = page->ir_volume_mapping_flags &&
+ flags = page->ir_volume_mapping_flags &&
MPII_IOC_PG8_IRFLAGS_VOLUME_MAPPING_MODE_MASK;
- if (sc->sc_ir_firmware) {
+ if (ISSET(sc->sc_flags, MPII_F_RAID)) {
if (flags == MPII_IOC_PG8_IRFLAGS_LOW_VOLUME_MAPPING) {
sc->sc_num_reserved_entries += sc->sc_max_volumes;
sc->sc_vd_id_low = 0;
@@ -3977,56 +3928,40 @@ mpii_req_cfg_page(struct mpii_softc *sc, u_int32_t address, int flags,
}
int
-mpii_reply(struct mpii_softc *sc, struct mpii_reply_descriptor *rdp)
+mpii_reply(struct mpii_softc *sc, struct mpii_reply_descr *rdp)
{
struct mpii_ccb *ccb = NULL;
struct mpii_rcb *rcb = NULL;
- u_int8_t reply_flags;
- u_int32_t i;
+ u_int32_t rfid;
int smid;
-
DNPRINTF(MPII_D_INTR, "%s: mpii_reply\n", DEVNAME(sc));
- DNPRINTF(MPII_D_INTR, "%s: dword[0]: 0x%08x\n", DEVNAME(sc),
- letoh32(dwordn(rdp, 0)));
- DNPRINTF(MPII_D_INTR, "%s: dword[1]: 0x%08x\n", DEVNAME(sc),
- letoh32(dwordn(rdp, 1)));
-
- reply_flags = (u_int8_t)(rdp->reply_flags) &
- MPII_REPLY_DESCR_FLAGS_TYPE_MASK;
-
- /* smid */
- smid = letoh16(rdp->type_dependent1);
-
- if (reply_flags == MPII_REPLY_DESCR_FLAGS_ADDRESS_REPLY) {
- /* reply frame address */
- i = (letoh32(rdp->type_dependent2) -
+ smid = letoh16(rdp->smid);
+ if ((rdp->reply_flags & MPII_REPLY_DESCR_TYPE_MASK) ==
+ MPII_REPLY_DESCR_ADDRESS_REPLY) {
+ rfid = (letoh32(rdp->frame_addr) -
(u_int32_t)MPII_DMA_DVA(sc->sc_replies)) / MPII_REPLY_SIZE;
bus_dmamap_sync(sc->sc_dmat,
- MPII_DMA_MAP(sc->sc_replies), MPII_REPLY_SIZE * i,
+ MPII_DMA_MAP(sc->sc_replies), MPII_REPLY_SIZE * rfid,
MPII_REPLY_SIZE, BUS_DMASYNC_POSTREAD);
- rcb = &sc->sc_rcbs[i];
+ rcb = &sc->sc_rcbs[rfid];
}
- DNPRINTF(MPII_D_INTR, "%s: mpii_reply reply_flags: %d smid: %d reply: %p\n",
- DEVNAME(sc), reply_flags, smid, rcb->rcb_reply);
+ DNPRINTF(MPII_D_INTR, "%s: mpii_reply reply_flags: %d smid: %d "
+ "reply: %p\n", DEVNAME(sc), rdp->reply_flags, smid,
+ rcb->rcb_reply);
memset(rdp, 0xff, sizeof(*rdp));
- bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_postq),
- 8 * sc->sc_reply_post_host_index, 8,
+ bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_postq),
+ 8 * sc->sc_reply_post_host_index, 8,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
if (smid) {
ccb = &sc->sc_ccbs[smid - 1];
- if (ccb->ccb_state != MPII_CCB_QUEUED) {
- printf("%s: orphaned ccb %d state %d\n", DEVNAME(sc),
- smid, ccb->ccb_state);
- return (smid);
- }
ccb->ccb_state = MPII_CCB_READY;
ccb->ccb_rcb = rcb;
ccb->ccb_done(ccb);
@@ -4044,7 +3979,7 @@ mpii_dmamem_alloc(struct mpii_softc *sc, size_t size)
struct mpii_dmamem *mdm;
int nsegs;
- mdm = malloc(sizeof(struct mpii_dmamem), M_DEVBUF, M_NOWAIT | M_ZERO);
+ mdm = malloc(sizeof(*mdm), M_DEVBUF, M_NOWAIT | M_ZERO);
if (mdm == NULL)
return (NULL);
@@ -4101,18 +4036,52 @@ mpii_dmamem_free(struct mpii_softc *sc, struct mpii_dmamem *mdm)
int
mpii_alloc_dev(struct mpii_softc *sc)
{
- DNPRINTF(MPII_D_MEM, "%s: mpii_alloc_dev: sc_max_devices: %d "
- "sizeof(sc_mpii_dev): %d\n", DEVNAME(sc), sc->sc_max_devices,
- sizeof(struct mpii_device *) * sc->sc_max_devices);
+ sc->sc_devs = malloc(sc->sc_max_devices *
+ sizeof(struct mpii_device *), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (sc->sc_devs == NULL)
+ return (1);
+ return (0);
+}
- sc->sc_mpii_dev = malloc(sc->sc_max_devices *
- sizeof(struct mpii_device *), M_DEVBUF,
- M_NOWAIT | M_CANFAIL | M_ZERO);
+int
+mpii_insert_dev(struct mpii_softc *sc, struct mpii_device *dev)
+{
+ if (!dev || dev->slot < 0 || dev->slot >= sc->sc_max_devices)
+ return (1);
+ if (sc->sc_devs[dev->slot]) {
+ printf("%s: slot %d is occupied by the dev %p\n", DEVNAME(sc),
+ dev->slot, sc->sc_devs[dev->slot]);
+ return (1);
+ }
+ sc->sc_devs[dev->slot] = dev;
+ return (0);
+}
- if (sc->sc_mpii_dev == NULL)
+int
+mpii_remove_dev(struct mpii_softc *sc, struct mpii_device *dev)
+{
+ int i;
+
+ if (!dev)
return (1);
+ for (i = 0; i < sc->sc_max_devices; i++)
+ if (sc->sc_devs[i] &&
+ sc->sc_devs[i]->dev_handle == dev->dev_handle) {
+ sc->sc_devs[i] = NULL;
+ return (0);
+ }
+ return (1);
+}
- return (0);
+struct mpii_device *
+mpii_find_dev(struct mpii_softc *sc, u_int16_t handle)
+{
+ int i;
+
+ for (i = 0; i < sc->sc_max_devices; i++)
+ if (sc->sc_devs[i] && sc->sc_devs[i]->dev_handle == handle)
+ return (sc->sc_devs[i]);
+ return (NULL);
}
int
@@ -4124,8 +4093,8 @@ mpii_alloc_ccbs(struct mpii_softc *sc)
TAILQ_INIT(&sc->sc_ccb_free);
- sc->sc_ccbs = malloc(sizeof(struct mpii_ccb) * (sc->sc_request_depth-1),
- M_DEVBUF, M_NOWAIT | M_CANFAIL | M_ZERO);
+ sc->sc_ccbs = malloc(sizeof(*ccb) * (sc->sc_request_depth-1),
+ M_DEVBUF, M_NOWAIT | M_ZERO);
if (sc->sc_ccbs == NULL) {
printf("%s: unable to allocate ccbs\n", DEVNAME(sc));
return (1);
@@ -4140,9 +4109,9 @@ mpii_alloc_ccbs(struct mpii_softc *sc)
cmd = MPII_DMA_KVA(sc->sc_requests);
bzero(cmd, MPII_REQUEST_SIZE * sc->sc_request_depth);
- /*
- * we have sc->sc_request_depth system request message
- * frames, but smid zero cannot be used. so we then
+ /*
+ * we have sc->sc_request_depth system request message
+ * frames, but smid zero cannot be used. so we then
* have (sc->sc_request_depth - 1) number of ccbs
*/
for (i = 1; i < sc->sc_request_depth; i++) {
@@ -4225,12 +4194,12 @@ mpii_alloc_replies(struct mpii_softc *sc)
DNPRINTF(MPII_D_MISC, "%s: mpii_alloc_replies\n", DEVNAME(sc));
sc->sc_rcbs = malloc(sc->sc_num_reply_frames * sizeof(struct mpii_rcb),
- M_DEVBUF, M_NOWAIT | M_CANFAIL);
+ M_DEVBUF, M_NOWAIT);
if (sc->sc_rcbs == NULL)
return (1);
- sc->sc_replies = mpii_dmamem_alloc(sc,
- MPII_REPLY_SIZE * sc->sc_num_reply_frames);
+ sc->sc_replies = mpii_dmamem_alloc(sc, MPII_REPLY_SIZE *
+ sc->sc_num_reply_frames);
if (sc->sc_replies == NULL) {
free(sc->sc_rcbs, M_DEVBUF);
return (1);
@@ -4259,39 +4228,34 @@ mpii_push_replies(struct mpii_softc *sc)
}
}
-void
+void
mpii_start(struct mpii_softc *sc, struct mpii_ccb *ccb)
-{
+{
struct mpii_request_header *rhp;
- struct mpii_request_descriptor descriptor;
- u_int32_t *rdp = (uint32_t *)&descriptor;
+ struct mpii_request_descr descr;
+ u_int32_t *rdp = (uint32_t *)&descr;
DNPRINTF(MPII_D_RW, "%s: mpii_start %#x\n", DEVNAME(sc),
ccb->ccb_cmd_dva);
rhp = ccb->ccb_cmd;
- bzero(&descriptor, sizeof(struct mpii_request_descriptor));
+ bzero(&descr, sizeof(descr));
switch (rhp->function) {
- case MPII_FUNCTION_SCSI_IO_REQUEST:
- descriptor.request_flags =
- MPII_REQ_DESCRIPTOR_FLAGS_SCSI_IO;
- /* device handle */
- descriptor.type_dependent =
- htole16(ccb->ccb_dev_handle);
- break;
- case MPII_FUNCTION_SCSI_TASK_MGMT:
- descriptor.request_flags =
- MPII_REQ_DESCRIPTOR_FLAGS_HIGH_PRIORITY;
- break;
+ case MPII_FUNCTION_SCSI_IO_REQUEST:
+ descr.request_flags = MPII_REQ_DESCR_SCSI_IO;
+ descr.dev_handle = htole16(ccb->ccb_dev_handle);
+ break;
+ case MPII_FUNCTION_SCSI_TASK_MGMT:
+ descr.request_flags = MPII_REQ_DESCR_HIGH_PRIORITY;
+ break;
default:
- descriptor.request_flags =
- MPII_REQ_DESCRIPTOR_FLAGS_DEFAULT;
+ descr.request_flags = MPII_REQ_DESCR_DEFAULT;
}
- descriptor.vf_id = sc->sc_vf_id;
- descriptor.smid = htole16(ccb->ccb_smid);
+ descr.vf_id = sc->sc_vf_id;
+ descr.smid = htole16(ccb->ccb_smid);
bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_requests),
ccb->ccb_offset, MPII_REQUEST_SIZE,
@@ -4299,33 +4263,33 @@ mpii_start(struct mpii_softc *sc, struct mpii_ccb *ccb)
ccb->ccb_state = MPII_CCB_QUEUED;
- DNPRINTF(MPII_D_RW, "%s: MPII_REQ_DESC_POST_LOW (0x%08x) write "
- "0x%08x\n", DEVNAME(sc), MPII_REQ_DESC_POST_LOW, *rdp);
+ DNPRINTF(MPII_D_RW, "%s: MPII_REQ_DESCR_POST_LOW (0x%08x) write "
+ "0x%08x\n", DEVNAME(sc), MPII_REQ_DESCR_POST_LOW, *rdp);
- DNPRINTF(MPII_D_RW, "%s: MPII_REQ_DESC_POST_HIGH (0x%08x) write "
- "0x%08x\n", DEVNAME(sc), MPII_REQ_DESC_POST_HIGH, *(rdp+1));
+ DNPRINTF(MPII_D_RW, "%s: MPII_REQ_DESCR_POST_HIGH (0x%08x) write "
+ "0x%08x\n", DEVNAME(sc), MPII_REQ_DESCR_POST_HIGH, *(rdp+1));
- mpii_write(sc, MPII_REQ_DESC_POST_LOW, htole32(*rdp));
- mpii_write(sc, MPII_REQ_DESC_POST_HIGH, htole32(*(rdp+1)));
+ mpii_write(sc, MPII_REQ_DESCR_POST_LOW, htole32(*rdp));
+ mpii_write(sc, MPII_REQ_DESCR_POST_HIGH, htole32(*(rdp+1)));
}
int
mpii_complete(struct mpii_softc *sc, struct mpii_ccb *ccb, int timeout)
{
- struct mpii_reply_descriptor *rdp;
- u_int8_t reply_flags;
+ struct mpii_reply_descr *rdp;
int smid = -1;
DNPRINTF(MPII_D_INTR, "%s: mpii_complete timeout %d\n", DEVNAME(sc),
- timeout);
-
+ timeout);
+
+ timeout *= 100;
+
do {
/* avoid excessive polling */
if (!mpii_reply_waiting(sc)) {
if (timeout-- == 0)
return (1);
-
- delay(1000);
+ delay(10);
continue;
}
@@ -4333,11 +4297,10 @@ mpii_complete(struct mpii_softc *sc, struct mpii_ccb *ccb, int timeout)
0, 8 * sc->sc_reply_post_qdepth, BUS_DMASYNC_POSTWRITE);
rdp = &sc->sc_reply_postq_kva[sc->sc_reply_post_host_index];
- reply_flags = (u_int8_t)(rdp->reply_flags) &
- MPII_REPLY_DESCR_FLAGS_TYPE_MASK;
- if ((reply_flags == MPII_REPLY_DESCR_FLAGS_UNUSED))
+ if ((rdp->reply_flags & MPII_REPLY_DESCR_TYPE_MASK) ==
+ MPII_REPLY_DESCR_UNUSED)
continue;
- if (rdp->type_dependent2 == 0xffffffff) {
+ if (rdp->data == 0xffffffff) {
/*
* ioc is still writing to the reply post queue
* race condition - bail!
@@ -4425,9 +4388,9 @@ mpii_poll(struct mpii_softc *sc, struct mpii_ccb *ccb, int timeout)
int error;
int s;
- DNPRINTF(MPII_D_CMD, "%s: mpii_poll\n", DEVNAME(sc));
+ DNPRINTF(MPII_D_CMD, "%s: mpii_poll: ccb %p cmd 0x%08x\n",
+ DEVNAME(sc), ccb, ccb->ccb_cmd);
- DNPRINTF(MPII_D_CMD, " ccb->ccb_cmd: 0x%08x\n", DEVNAME(sc), ccb->ccb_cmd);
s = splbio();
mpii_start(sc, ccb);
error = mpii_complete(sc, ccb, timeout);
@@ -4444,6 +4407,7 @@ mpii_scsi_cmd(struct scsi_xfer *xs)
struct mpii_ccb *ccb;
struct mpii_ccb_bundle *mcb;
struct mpii_msg_scsi_io *io;
+ struct mpii_device *dev;
int s;
DNPRINTF(MPII_D_CMD, "%s: mpii_scsi_cmd\n", DEVNAME(sc));
@@ -4462,6 +4426,15 @@ mpii_scsi_cmd(struct scsi_xfer *xs)
return;
}
+ if ((dev = sc->sc_devs[link->target]) == NULL) {
+ /* device no longer exists */
+ xs->error = XS_SELTIMEOUT;
+ s = splbio();
+ scsi_done(xs);
+ splx(s);
+ return;
+ }
+
s = splbio();
ccb = mpii_get_ccb(sc);
splx(s);
@@ -4472,12 +4445,13 @@ mpii_scsi_cmd(struct scsi_xfer *xs)
splx(s);
return;
}
-
+
DNPRINTF(MPII_D_CMD, "%s: ccb_smid: %d xs->flags: 0x%x\n",
DEVNAME(sc), ccb->ccb_smid, xs->flags);
ccb->ccb_xs = xs;
ccb->ccb_done = mpii_scsi_cmd_done;
+ ccb->ccb_dev_handle = dev->dev_handle;
mcb = ccb->ccb_cmd;
io = &mcb->mcb_io;
@@ -4486,8 +4460,7 @@ mpii_scsi_cmd(struct scsi_xfer *xs)
io->sense_buffer_length = sizeof(xs->sense);
io->sgl_offset0 = 24; /* XXX fix this */
io->io_flags = htole16(xs->cmdlen);
- ccb->ccb_dev_handle = io->dev_handle =
- htole16(sc->sc_mpii_dev[link->target]->dev_handle);
+ io->dev_handle = htole16(ccb->ccb_dev_handle);
io->lun[0] = htobe16(link->lun);
switch (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
@@ -4499,7 +4472,6 @@ mpii_scsi_cmd(struct scsi_xfer *xs)
break;
default:
io->direction = MPII_SCSIIO_DIR_NONE;
- break;
}
io->tagging = MPII_SCSIIO_ATTR_SIMPLE_Q;
@@ -4523,20 +4495,21 @@ mpii_scsi_cmd(struct scsi_xfer *xs)
DNPRINTF(MPII_D_CMD, "%s: sizeof(mpii_msg_scsi_io): %d "
"sizeof(mpii_ccb_bundle): %d sge offset: 0x%02x\n",
DEVNAME(sc), sizeof(struct mpii_msg_scsi_io),
- sizeof(struct mpii_ccb_bundle),
+ sizeof(struct mpii_ccb_bundle),
(u_int8_t *)&mcb->mcb_sgl[0] - (u_int8_t *)mcb);
-
+
DNPRINTF(MPII_D_CMD, "%s sgl[0]: 0x%04x 0%04x 0x%04x\n",
DEVNAME(sc), mcb->mcb_sgl[0].sg_hdr, mcb->mcb_sgl[0].sg_lo_addr,
mcb->mcb_sgl[0].sg_hi_addr);
DNPRINTF(MPII_D_CMD, "%s: Offset0: 0x%02x\n", DEVNAME(sc),
- io->sgl_offset0);
+ io->sgl_offset0);
if (xs->flags & SCSI_POLL) {
if (mpii_poll(sc, ccb, xs->timeout) != 0) {
xs->error = XS_DRIVER_STUFFUP;
s = splbio();
+ mpii_put_ccb(sc, ccb);
scsi_done(xs);
splx(s);
}
@@ -4544,7 +4517,7 @@ mpii_scsi_cmd(struct scsi_xfer *xs)
}
timeout_set(&xs->stimeout, mpii_timeout_xs, ccb);
- timeout_add(&xs->stimeout, (xs->timeout * 1000) / hz);
+ timeout_add_msec(&xs->stimeout, xs->timeout);
DNPRINTF(MPII_D_CMD, "%s: mpii_scsi_cmd(): opcode: %02x datalen: %d "
"req_sense_len: %d\n", DEVNAME(sc), xs->cmd->opcode,
@@ -4591,7 +4564,7 @@ mpii_scsi_cmd_done(struct mpii_ccb *ccb)
"flags 0x%x\n", DEVNAME(sc), xs->cmd->opcode, xs->datalen,
xs->flags);
DNPRINTF(MPII_D_CMD, "%s: dev_handle: %d msg_length: %d "
- "function: 0x%02x\n", DEVNAME(sc), letoh16(sie->dev_handle),
+ "function: 0x%02x\n", DEVNAME(sc), letoh16(sie->dev_handle),
sie->msg_length, sie->function);
DNPRINTF(MPII_D_CMD, "%s: vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
sie->vp_id, sie->vf_id);
@@ -4610,9 +4583,9 @@ mpii_scsi_cmd_done(struct mpii_ccb *ccb)
letoh16(sie->task_tag));
DNPRINTF(MPII_D_CMD, "%s: bidirectional_transfer_count: 0x%08x\n",
DEVNAME(sc), letoh32(sie->bidirectional_transfer_count));
-
+
xs->status = sie->scsi_status;
- switch (letoh16(sie->ioc_status)) {
+ switch (letoh16(sie->ioc_status) & MPII_IOCSTATUS_MASK) {
case MPII_IOCSTATUS_SCSI_DATA_UNDERRUN:
xs->resid = xs->datalen - letoh32(sie->transfer_count);
if (sie->scsi_state & MPII_SCSIIO_ERR_STATE_NO_SCSI_STATUS) {
@@ -4638,7 +4611,6 @@ mpii_scsi_cmd_done(struct mpii_ccb *ccb)
default:
xs->error = XS_DRIVER_STUFFUP;
- break;
}
break;
@@ -4656,7 +4628,6 @@ mpii_scsi_cmd_done(struct mpii_ccb *ccb)
default:
xs->error = XS_DRIVER_STUFFUP;
- break;
}
if (sie->scsi_state & MPII_SCSIIO_ERR_STATE_AUTOSENSE_VALID)
@@ -4698,17 +4669,14 @@ mpii_ioctl(struct device *dev, u_long cmd, caddr_t addr)
DNPRINTF(MPII_D_IOCTL, "inq\n");
error = mpii_ioctl_inq(sc, (struct bioc_inq *)addr);
break;
-
case BIOCVOL:
DNPRINTF(MPII_D_IOCTL, "vol\n");
error = mpii_ioctl_vol(sc, (struct bioc_vol *)addr);
break;
-
case BIOCDISK:
DNPRINTF(MPII_D_IOCTL, "disk\n");
error = mpii_ioctl_disk(sc, (struct bioc_disk *)addr);
break;
-
default:
DNPRINTF(MPII_D_IOCTL, " invalid ioctl\n");
error = EINVAL;
@@ -4720,13 +4688,15 @@ mpii_ioctl(struct device *dev, u_long cmd, caddr_t addr)
int
mpii_ioctl_inq(struct mpii_softc *sc, struct bioc_inq *bi)
{
+ int i;
+
DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl_inq\n", DEVNAME(sc));
strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev));
-
- bi->bi_nodisk = sc->sc_pd_count;
- bi->bi_novol = sc->sc_vd_count;
-
+ for (i = 0; i < sc->sc_max_devices; i++)
+ if (sc->sc_devs[i] &&
+ ISSET(sc->sc_devs[i]->flags, MPII_DF_VOLUME))
+ bi->bi_novol++;
return (0);
}
@@ -4735,8 +4705,9 @@ mpii_ioctl_vol(struct mpii_softc *sc, struct bioc_vol *bv)
{
struct mpii_cfg_raid_vol_pg0 *vpg;
struct mpii_cfg_hdr hdr;
+ struct mpii_device *dev;
struct scsi_link *lnk;
- struct device *dev;
+ struct device *scdev;
size_t pagelen;
u_int16_t volh;
int rv, hcnt = 0;
@@ -4744,10 +4715,9 @@ mpii_ioctl_vol(struct mpii_softc *sc, struct bioc_vol *bv)
DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl_vol %d\n",
DEVNAME(sc), bv->bv_volid);
- if (bv->bv_volid > sc->sc_vd_count)
+ if ((dev = mpii_find_vol(sc, bv->bv_volid)) == NULL)
return (ENODEV);
-
- volh = sc->sc_mpii_dev[sc->sc_vd_id_low + bv->bv_volid]->dev_handle;
+ volh = dev->dev_handle;
if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, 0, &hdr) != 0) {
@@ -4772,27 +4742,18 @@ mpii_ioctl_vol(struct mpii_softc *sc, struct bioc_vol *bv)
return (EINVAL);
}
- bv->bv_percent = -1;
-
switch (vpg->volume_state) {
case MPII_CFG_RAID_VOL_0_STATE_ONLINE:
- switch (letoh32(vpg->volume_status)) {
- case MPII_CFG_RAID_VOL_0_STATUS_SCRUB:
- bv->bv_status = BIOC_SVSCRUB;
- break;
- case MPII_CFG_RAID_VOL_0_STATUS_RESYNC:
- bv->bv_status = BIOC_SVREBUILD;
- break;
- default:
- bv->bv_status = BIOC_SVONLINE;
- break;
- }
- break;
case MPII_CFG_RAID_VOL_0_STATE_OPTIMAL:
bv->bv_status = BIOC_SVONLINE;
break;
case MPII_CFG_RAID_VOL_0_STATE_DEGRADED:
- bv->bv_status = BIOC_SVDEGRADED;
+ if (ISSET(letoh32(vpg->volume_status),
+ MPII_CFG_RAID_VOL_0_STATUS_RESYNC)) {
+ bv->bv_status = BIOC_SVREBUILD;
+ bv->bv_percent = dev->percent;
+ } else
+ bv->bv_status = BIOC_SVDEGRADED;
break;
case MPII_CFG_RAID_VOL_0_STATE_FAILED:
bv->bv_status = BIOC_SVOFFLINE;
@@ -4818,7 +4779,6 @@ mpii_ioctl_vol(struct mpii_softc *sc, struct bioc_vol *bv)
break;
default:
bv->bv_level = -1;
- break;
}
if ((rv = mpii_bio_hs(sc, NULL, 0, vpg->hot_spare_pool, &hcnt)) != 0) {
@@ -4832,8 +4792,8 @@ mpii_ioctl_vol(struct mpii_softc *sc, struct bioc_vol *bv)
lnk = sc->sc_scsibus->sc_link[bv->bv_volid][0];
if (lnk != NULL) {
- dev = lnk->device_softc;
- strlcpy(bv->bv_dev, dev->dv_xname, sizeof(bv->bv_dev));
+ scdev = lnk->device_softc;
+ strlcpy(bv->bv_dev, scdev->dv_xname, sizeof(bv->bv_dev));
}
free(vpg, M_TEMP);
@@ -4846,6 +4806,7 @@ mpii_ioctl_disk(struct mpii_softc *sc, struct bioc_disk *bd)
struct mpii_cfg_raid_vol_pg0 *vpg;
struct mpii_cfg_raid_vol_pg0_physdisk *pd;
struct mpii_cfg_hdr hdr;
+ struct mpii_device *dev;
size_t pagelen;
u_int16_t volh;
u_int8_t dn;
@@ -4853,10 +4814,9 @@ mpii_ioctl_disk(struct mpii_softc *sc, struct bioc_disk *bd)
DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl_disk %d/%d\n",
DEVNAME(sc), bd->bd_volid, bd->bd_diskid);
- if (bd->bd_volid > sc->sc_vd_count)
+ if ((dev = mpii_find_vol(sc, bd->bd_volid)) == NULL)
return (ENODEV);
-
- volh = sc->sc_mpii_dev[sc->sc_vd_id_low + bd->bd_volid]->dev_handle;
+ volh = dev->dev_handle;
if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, 0, &hdr) != 0) {
@@ -4967,40 +4927,49 @@ mpii_bio_hs(struct mpii_softc *sc, struct bioc_disk *bd, int nvdsk,
int
mpii_bio_disk(struct mpii_softc *sc, struct bioc_disk *bd, u_int8_t dn)
{
- struct mpii_cfg_raid_physdisk_pg0 ppg;
+ struct mpii_cfg_raid_physdisk_pg0 *ppg;
struct mpii_cfg_hdr hdr;
+ struct mpii_device *dev;
int len;
- DNPRINTF(MPII_D_IOCTL, "%s: mpii_bio_disk %d\n",
- DEVNAME(sc), bd->bd_diskid);
+ DNPRINTF(MPII_D_IOCTL, "%s: mpii_bio_disk %d\n", DEVNAME(sc),
+ bd->bd_diskid);
- if (bd->bd_volid > sc->sc_vd_count)
- return (ENODEV);
+ ppg = malloc(sizeof(*ppg), M_TEMP, M_WAITOK | M_CANFAIL | M_ZERO);
+ if (ppg == NULL) {
+ printf("%s: unable to allocate space for raid physical disk "
+ "page 0\n", DEVNAME(sc));
+ return (ENOMEM);
+ }
hdr.page_version = 0;
- hdr.page_length = sizeof(ppg) / 4;
+ hdr.page_length = sizeof(*ppg) / 4;
hdr.page_number = 0;
hdr.page_type = MPII_CONFIG_REQ_PAGE_TYPE_RAID_PD;
if (mpii_req_cfg_page(sc, MPII_CFG_RAID_PHYS_DISK_ADDR_NUMBER | dn, 0,
- &hdr, 1, &ppg, sizeof(ppg)) != 0) {
+ &hdr, 1, ppg, sizeof(*ppg)) != 0) {
printf("%s: unable to fetch raid drive page 0\n",
DEVNAME(sc));
return (EINVAL);
}
- if (mpii_bio_getphy(sc, letoh16(ppg.dev_handle), &bd->bd_target))
- bd->bd_target = letoh16(ppg.phys_disk_num);
+ bd->bd_target = ppg->phys_disk_num;
+
+ if ((dev = mpii_find_dev(sc, letoh16(ppg->dev_handle))) == NULL) {
+ bd->bd_status = BIOC_SDINVALID;
+ return (0);
+ }
- switch (ppg.phys_disk_state) {
+ switch (ppg->phys_disk_state) {
case MPII_CFG_RAID_PHYDISK_0_STATE_ONLINE:
case MPII_CFG_RAID_PHYDISK_0_STATE_OPTIMAL:
bd->bd_status = BIOC_SDONLINE;
break;
case MPII_CFG_RAID_PHYDISK_0_STATE_OFFLINE:
- if (ppg.offline_reason ==
+ if (ppg->offline_reason ==
MPII_CFG_RAID_PHYDISK_0_OFFLINE_FAILED ||
- ppg.offline_reason ==
+ ppg->offline_reason ==
MPII_CFG_RAID_PHYDISK_0_OFFLINE_FAILEDREQ)
bd->bd_status = BIOC_SDFAILED;
else
@@ -5023,57 +4992,47 @@ mpii_bio_disk(struct mpii_softc *sc, struct bioc_disk *bd, u_int8_t dn)
break;
}
- bd->bd_size = letoh64(ppg.dev_max_lba) * letoh16(ppg.block_size);
+ bd->bd_size = letoh64(ppg->dev_max_lba) * letoh16(ppg->block_size);
- scsi_strvis(bd->bd_vendor, ppg.vendor_id, sizeof(ppg.vendor_id));
+ scsi_strvis(bd->bd_vendor, ppg->vendor_id, sizeof(ppg->vendor_id));
len = strlen(bd->bd_vendor);
bd->bd_vendor[len] = ' ';
- scsi_strvis(&bd->bd_vendor[len + 1], ppg.product_id,
- sizeof(ppg.product_id));
- scsi_strvis(bd->bd_serial, ppg.serial, sizeof(ppg.serial));
+ scsi_strvis(&bd->bd_vendor[len + 1], ppg->product_id,
+ sizeof(ppg->product_id));
+ scsi_strvis(bd->bd_serial, ppg->serial, sizeof(ppg->serial));
return (0);
}
-int
-mpii_bio_getphy(struct mpii_softc *sc, u_int16_t dh, u_int16_t *port)
+struct mpii_device *
+mpii_find_vol(struct mpii_softc *sc, int volid)
{
- struct mpii_cfg_sas_dev_pg0 spg;
- struct mpii_ecfg_hdr ehdr;
-
- if (!port)
- return (EINVAL);
-
- bzero(&ehdr, sizeof(ehdr));
- ehdr.page_type = MPII_CONFIG_REQ_PAGE_TYPE_EXTENDED;
- ehdr.ext_page_length = htole16(sizeof(spg) / 4);
- ehdr.ext_page_type = MPII_CONFIG_REQ_PAGE_TYPE_SAS_DEVICE;
+ struct mpii_device *dev = NULL;
- if (mpii_req_cfg_page(sc, MPII_CFG_SAS_DEV_ADDR_HANDLE | dh,
- MPII_PG_EXTENDED, &ehdr, 1, &spg, sizeof(spg)) != 0) {
- printf("%s: unable to fetch sas device page 0\n",
- DEVNAME(sc));
- return (EINVAL);
- }
-
- *port = spg.phy_num;
-
- return (0);
+ if (sc->sc_vd_id_low + volid >= sc->sc_max_devices)
+ return (NULL);
+ dev = sc->sc_devs[sc->sc_vd_id_low + volid];
+ if (dev && ISSET(dev->flags, MPII_DF_VOLUME))
+ return (dev);
+ return (NULL);
}
#ifndef SMALL_KERNEL
+/*
+ * Non-sleeping lightweight version of the mpii_ioctl_vol
+ */
int
mpii_bio_volstate(struct mpii_softc *sc, struct bioc_vol *bv)
{
struct mpii_cfg_raid_vol_pg0 *vpg;
struct mpii_cfg_hdr hdr;
+ struct mpii_device *dev = NULL;
size_t pagelen;
u_int16_t volh;
- if (bv->bv_volid > sc->sc_vd_count)
+ if ((dev = mpii_find_vol(sc, bv->bv_volid)) == NULL)
return (ENODEV);
-
- volh = sc->sc_mpii_dev[sc->sc_vd_id_low + bv->bv_volid]->dev_handle;
+ volh = dev->dev_handle;
if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, &hdr) != 0) {
@@ -5083,7 +5042,7 @@ mpii_bio_volstate(struct mpii_softc *sc, struct bioc_vol *bv)
}
pagelen = hdr.page_length * 4;
- vpg = malloc(pagelen, M_TEMP, M_NOWAIT | M_CANFAIL | M_ZERO);
+ vpg = malloc(pagelen, M_TEMP, M_NOWAIT | M_ZERO);
if (vpg == NULL) {
DNPRINTF(MPII_D_MISC, "%s: unable to allocate space for raid "
"volume page 0\n", DEVNAME(sc));
@@ -5100,23 +5059,15 @@ mpii_bio_volstate(struct mpii_softc *sc, struct bioc_vol *bv)
switch (vpg->volume_state) {
case MPII_CFG_RAID_VOL_0_STATE_ONLINE:
- switch (letoh32(vpg->volume_status)) {
- case MPII_CFG_RAID_VOL_0_STATUS_SCRUB:
- bv->bv_status = BIOC_SVSCRUB;
- break;
- case MPII_CFG_RAID_VOL_0_STATUS_RESYNC:
- bv->bv_status = BIOC_SVREBUILD;
- break;
- default:
- bv->bv_status = BIOC_SVONLINE;
- break;
- }
- break;
case MPII_CFG_RAID_VOL_0_STATE_OPTIMAL:
bv->bv_status = BIOC_SVONLINE;
break;
case MPII_CFG_RAID_VOL_0_STATE_DEGRADED:
- bv->bv_status = BIOC_SVDEGRADED;
+ if (ISSET(letoh32(vpg->volume_status),
+ MPII_CFG_RAID_VOL_0_STATUS_RESYNC))
+ bv->bv_status = BIOC_SVREBUILD;
+ else
+ bv->bv_status = BIOC_SVDEGRADED;
break;
case MPII_CFG_RAID_VOL_0_STATE_FAILED:
bv->bv_status = BIOC_SVOFFLINE;
@@ -5144,11 +5095,13 @@ mpii_create_sensors(struct mpii_softc *sc)
M_DEVBUF, M_WAITOK | M_ZERO);
if (sc->sc_sensors == NULL)
return (1);
+ sc->sc_nsensors = sc->sc_vd_count;
strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
sizeof(sc->sc_sensordev.xname));
- for (i = 0; i < sc->sc_vd_count; i++) {
+ for (i = sc->sc_vd_id_low; i < sc->sc_vd_id_low + sc->sc_vd_count;
+ i++) {
if (ssc->sc_link[i][0] == NULL)
goto bad;
@@ -5183,29 +5136,28 @@ mpii_refresh_sensors(void *arg)
struct bioc_vol bv;
int i;
- for (i = 0; i < sc->sc_vd_count; i++) {
+ for (i = 0; i < sc->sc_nsensors; i++) {
bzero(&bv, sizeof(bv));
bv.bv_volid = i;
if (mpii_bio_volstate(sc, &bv))
return;
-
switch(bv.bv_status) {
case BIOC_SVOFFLINE:
sc->sc_sensors[i].value = SENSOR_DRIVE_FAIL;
sc->sc_sensors[i].status = SENSOR_S_CRIT;
break;
-
case BIOC_SVDEGRADED:
sc->sc_sensors[i].value = SENSOR_DRIVE_PFAIL;
sc->sc_sensors[i].status = SENSOR_S_WARN;
break;
-
- case BIOC_SVSCRUB:
+ case BIOC_SVREBUILD:
+ sc->sc_sensors[i].value = SENSOR_DRIVE_REBUILD;
+ sc->sc_sensors[i].status = SENSOR_S_WARN;
+ break;
case BIOC_SVONLINE:
sc->sc_sensors[i].value = SENSOR_DRIVE_ONLINE;
sc->sc_sensors[i].status = SENSOR_S_OK;
break;
-
case BIOC_SVINVALID:
/* FALLTRHOUGH */
default: