Commit 7188c03f authored by Sreekanth Reddy's avatar Sreekanth Reddy Committed by Martin K. Petersen

scsi: mpi3mr: Enable Enclosure device add event

Enable and process the Enclosure device add event.

Link: https://lore.kernel.org/r/20220804131226.16653-5-sreekanth.reddy@broadcom.comReviewed-by: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: default avatarSreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 64a8d931
...@@ -461,6 +461,16 @@ struct mpi3mr_throttle_group_info { ...@@ -461,6 +461,16 @@ struct mpi3mr_throttle_group_info {
atomic_t pend_large_data_sz; atomic_t pend_large_data_sz;
}; };
/**
* struct mpi3mr_enclosure_node - enclosure information
* @list: List of enclosures
* @pg0: Enclosure page 0;
*/
struct mpi3mr_enclosure_node {
struct list_head list;
struct mpi3_enclosure_page0 pg0;
};
/** /**
* struct tgt_dev_sas_sata - SAS/SATA device specific * struct tgt_dev_sas_sata - SAS/SATA device specific
* information cached from firmware given data * information cached from firmware given data
...@@ -535,12 +545,14 @@ union _form_spec_inf { ...@@ -535,12 +545,14 @@ union _form_spec_inf {
* @slot: Slot number * @slot: Slot number
* @encl_handle: FW enclosure handle * @encl_handle: FW enclosure handle
* @perst_id: FW assigned Persistent ID * @perst_id: FW assigned Persistent ID
* @devpg0_flag: Device Page0 flag
* @dev_type: SAS/SATA/PCIE device type * @dev_type: SAS/SATA/PCIE device type
* @is_hidden: Should be exposed to upper layers or not * @is_hidden: Should be exposed to upper layers or not
* @host_exposed: Already exposed to host or not * @host_exposed: Already exposed to host or not
* @io_throttle_enabled: I/O throttling needed or not * @io_throttle_enabled: I/O throttling needed or not
* @q_depth: Device specific Queue Depth * @q_depth: Device specific Queue Depth
* @wwid: World wide ID * @wwid: World wide ID
* @enclosure_logical_id: Enclosure logical identifier
* @dev_spec: Device type specific information * @dev_spec: Device type specific information
* @ref_count: Reference count * @ref_count: Reference count
*/ */
...@@ -552,12 +564,14 @@ struct mpi3mr_tgt_dev { ...@@ -552,12 +564,14 @@ struct mpi3mr_tgt_dev {
u16 slot; u16 slot;
u16 encl_handle; u16 encl_handle;
u16 perst_id; u16 perst_id;
u16 devpg0_flag;
u8 dev_type; u8 dev_type;
u8 is_hidden; u8 is_hidden;
u8 host_exposed; u8 host_exposed;
u8 io_throttle_enabled; u8 io_throttle_enabled;
u16 q_depth; u16 q_depth;
u64 wwid; u64 wwid;
u64 enclosure_logical_id;
union _form_spec_inf dev_spec; union _form_spec_inf dev_spec;
struct kref ref_count; struct kref ref_count;
}; };
...@@ -877,6 +891,7 @@ struct scmd_priv { ...@@ -877,6 +891,7 @@ struct scmd_priv {
* @cfg_page: Default memory for configuration pages * @cfg_page: Default memory for configuration pages
* @cfg_page_dma: Configuration page DMA address * @cfg_page_dma: Configuration page DMA address
* @cfg_page_sz: Default configuration page memory size * @cfg_page_sz: Default configuration page memory size
* @enclosure_list: List of Enclosure objects
*/ */
struct mpi3mr_ioc { struct mpi3mr_ioc {
struct list_head list; struct list_head list;
...@@ -1053,6 +1068,8 @@ struct mpi3mr_ioc { ...@@ -1053,6 +1068,8 @@ struct mpi3mr_ioc {
void *cfg_page; void *cfg_page;
dma_addr_t cfg_page_dma; dma_addr_t cfg_page_dma;
u16 cfg_page_sz; u16 cfg_page_sz;
struct list_head enclosure_list;
}; };
/** /**
...@@ -1177,6 +1194,8 @@ int mpi3mr_pel_get_seqnum_post(struct mpi3mr_ioc *mrioc, ...@@ -1177,6 +1194,8 @@ int mpi3mr_pel_get_seqnum_post(struct mpi3mr_ioc *mrioc,
struct mpi3mr_drv_cmd *drv_cmd); struct mpi3mr_drv_cmd *drv_cmd);
void mpi3mr_app_save_logdata(struct mpi3mr_ioc *mrioc, char *event_data, void mpi3mr_app_save_logdata(struct mpi3mr_ioc *mrioc, char *event_data,
u16 event_data_size); u16 event_data_size);
struct mpi3mr_enclosure_node *mpi3mr_enclosure_find_by_handle(
struct mpi3mr_ioc *mrioc, u16 handle);
extern const struct attribute_group *mpi3mr_host_groups[]; extern const struct attribute_group *mpi3mr_host_groups[];
extern const struct attribute_group *mpi3mr_dev_groups[]; extern const struct attribute_group *mpi3mr_dev_groups[];
......
...@@ -244,6 +244,9 @@ static void mpi3mr_print_event_data(struct mpi3mr_ioc *mrioc, ...@@ -244,6 +244,9 @@ static void mpi3mr_print_event_data(struct mpi3mr_ioc *mrioc,
case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE: case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE:
desc = "Enclosure Device Status Change"; desc = "Enclosure Device Status Change";
break; break;
case MPI3_EVENT_ENCL_DEVICE_ADDED:
desc = "Enclosure Added";
break;
case MPI3_EVENT_HARD_RESET_RECEIVED: case MPI3_EVENT_HARD_RESET_RECEIVED:
desc = "Hard Reset Received"; desc = "Hard Reset Received";
break; break;
...@@ -3660,6 +3663,7 @@ static int mpi3mr_enable_events(struct mpi3mr_ioc *mrioc) ...@@ -3660,6 +3663,7 @@ static int mpi3mr_enable_events(struct mpi3mr_ioc *mrioc)
mpi3mr_unmask_events(mrioc, MPI3_EVENT_DEVICE_INFO_CHANGED); mpi3mr_unmask_events(mrioc, MPI3_EVENT_DEVICE_INFO_CHANGED);
mpi3mr_unmask_events(mrioc, MPI3_EVENT_DEVICE_STATUS_CHANGE); mpi3mr_unmask_events(mrioc, MPI3_EVENT_DEVICE_STATUS_CHANGE);
mpi3mr_unmask_events(mrioc, MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE); mpi3mr_unmask_events(mrioc, MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE);
mpi3mr_unmask_events(mrioc, MPI3_EVENT_ENCL_DEVICE_ADDED);
mpi3mr_unmask_events(mrioc, MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST); mpi3mr_unmask_events(mrioc, MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST);
mpi3mr_unmask_events(mrioc, MPI3_EVENT_SAS_DISCOVERY); mpi3mr_unmask_events(mrioc, MPI3_EVENT_SAS_DISCOVERY);
mpi3mr_unmask_events(mrioc, MPI3_EVENT_SAS_DEVICE_DISCOVERY_ERROR); mpi3mr_unmask_events(mrioc, MPI3_EVENT_SAS_DEVICE_DISCOVERY_ERROR);
......
...@@ -1018,6 +1018,7 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc, ...@@ -1018,6 +1018,7 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
{ {
u16 flags = 0; u16 flags = 0;
struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data = NULL; struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data = NULL;
struct mpi3mr_enclosure_node *enclosure_dev = NULL;
u8 prot_mask = 0; u8 prot_mask = 0;
tgtdev->perst_id = le16_to_cpu(dev_pg0->persistent_id); tgtdev->perst_id = le16_to_cpu(dev_pg0->persistent_id);
...@@ -1028,8 +1029,17 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc, ...@@ -1028,8 +1029,17 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
tgtdev->slot = le16_to_cpu(dev_pg0->slot); tgtdev->slot = le16_to_cpu(dev_pg0->slot);
tgtdev->q_depth = le16_to_cpu(dev_pg0->queue_depth); tgtdev->q_depth = le16_to_cpu(dev_pg0->queue_depth);
tgtdev->wwid = le64_to_cpu(dev_pg0->wwid); tgtdev->wwid = le64_to_cpu(dev_pg0->wwid);
tgtdev->devpg0_flag = le16_to_cpu(dev_pg0->flags);
if (tgtdev->encl_handle)
enclosure_dev = mpi3mr_enclosure_find_by_handle(mrioc,
tgtdev->encl_handle);
if (enclosure_dev)
tgtdev->enclosure_logical_id = le64_to_cpu(
enclosure_dev->pg0.enclosure_logical_id);
flags = tgtdev->devpg0_flag;
flags = le16_to_cpu(dev_pg0->flags);
tgtdev->is_hidden = (flags & MPI3_DEVICE0_FLAGS_HIDDEN); tgtdev->is_hidden = (flags & MPI3_DEVICE0_FLAGS_HIDDEN);
if (is_added == true) if (is_added == true)
...@@ -1257,6 +1267,116 @@ static void mpi3mr_devinfochg_evt_bh(struct mpi3mr_ioc *mrioc, ...@@ -1257,6 +1267,116 @@ static void mpi3mr_devinfochg_evt_bh(struct mpi3mr_ioc *mrioc,
mpi3mr_tgtdev_put(tgtdev); mpi3mr_tgtdev_put(tgtdev);
} }
/**
* mpi3mr_enclosure_find_by_handle - enclosure search by handle
* @mrioc: Adapter instance reference
* @handle: Firmware device handle of the enclosure
*
* This searches for enclosure device based on handle, then returns the
* enclosure object.
*
* Return: Enclosure object reference or NULL
*/
struct mpi3mr_enclosure_node *mpi3mr_enclosure_find_by_handle(
struct mpi3mr_ioc *mrioc, u16 handle)
{
struct mpi3mr_enclosure_node *enclosure_dev, *r = NULL;
list_for_each_entry(enclosure_dev, &mrioc->enclosure_list, list) {
if (le16_to_cpu(enclosure_dev->pg0.enclosure_handle) != handle)
continue;
r = enclosure_dev;
goto out;
}
out:
return r;
}
/**
* mpi3mr_encldev_add_chg_evt_debug - debug for enclosure event
* @mrioc: Adapter instance reference
* @encl_pg0: Enclosure page 0.
* @is_added: Added event or not
*
* Return nothing.
*/
static void mpi3mr_encldev_add_chg_evt_debug(struct mpi3mr_ioc *mrioc,
struct mpi3_enclosure_page0 *encl_pg0, u8 is_added)
{
char *reason_str = NULL;
if (!(mrioc->logging_level & MPI3_DEBUG_EVENT_WORK_TASK))
return;
if (is_added)
reason_str = "enclosure added";
else
reason_str = "enclosure dev status changed";
ioc_info(mrioc,
"%s: handle(0x%04x), enclosure logical id(0x%016llx)\n",
reason_str, le16_to_cpu(encl_pg0->enclosure_handle),
(unsigned long long)le64_to_cpu(encl_pg0->enclosure_logical_id));
ioc_info(mrioc,
"number of slots(%d), port(%d), flags(0x%04x), present(%d)\n",
le16_to_cpu(encl_pg0->num_slots), encl_pg0->io_unit_port,
le16_to_cpu(encl_pg0->flags),
((le16_to_cpu(encl_pg0->flags) &
MPI3_ENCLS0_FLAGS_ENCL_DEV_PRESENT_MASK) >> 4));
}
/**
* mpi3mr_encldev_add_chg_evt_bh - Enclosure evt bottomhalf
* @mrioc: Adapter instance reference
* @fwevt: Firmware event reference
*
* Prints information about the Enclosure device status or
* Enclosure add events if logging is enabled and add or remove
* the enclosure from the controller's internal list of
* enclosures.
*
* Return: Nothing.
*/
static void mpi3mr_encldev_add_chg_evt_bh(struct mpi3mr_ioc *mrioc,
struct mpi3mr_fwevt *fwevt)
{
struct mpi3mr_enclosure_node *enclosure_dev = NULL;
struct mpi3_enclosure_page0 *encl_pg0;
u16 encl_handle;
u8 added, present;
encl_pg0 = (struct mpi3_enclosure_page0 *) fwevt->event_data;
added = (fwevt->event_id == MPI3_EVENT_ENCL_DEVICE_ADDED) ? 1 : 0;
mpi3mr_encldev_add_chg_evt_debug(mrioc, encl_pg0, added);
encl_handle = le16_to_cpu(encl_pg0->enclosure_handle);
present = ((le16_to_cpu(encl_pg0->flags) &
MPI3_ENCLS0_FLAGS_ENCL_DEV_PRESENT_MASK) >> 4);
if (encl_handle)
enclosure_dev = mpi3mr_enclosure_find_by_handle(mrioc,
encl_handle);
if (!enclosure_dev && present) {
enclosure_dev =
kzalloc(sizeof(struct mpi3mr_enclosure_node),
GFP_KERNEL);
if (!enclosure_dev)
return;
list_add_tail(&enclosure_dev->list,
&mrioc->enclosure_list);
}
if (enclosure_dev) {
if (!present) {
list_del(&enclosure_dev->list);
kfree(enclosure_dev);
} else
memcpy(&enclosure_dev->pg0, encl_pg0,
sizeof(enclosure_dev->pg0));
}
}
/** /**
* mpi3mr_sastopochg_evt_debug - SASTopoChange details * mpi3mr_sastopochg_evt_debug - SASTopoChange details
* @mrioc: Adapter instance reference * @mrioc: Adapter instance reference
...@@ -1633,6 +1753,13 @@ static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc, ...@@ -1633,6 +1753,13 @@ static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc,
mpi3mr_devstatuschg_evt_bh(mrioc, fwevt); mpi3mr_devstatuschg_evt_bh(mrioc, fwevt);
break; break;
} }
case MPI3_EVENT_ENCL_DEVICE_ADDED:
case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE:
{
mpi3mr_encldev_add_chg_evt_bh(mrioc, fwevt);
break;
}
case MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST: case MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
{ {
mpi3mr_sastopochg_evt_bh(mrioc, fwevt); mpi3mr_sastopochg_evt_bh(mrioc, fwevt);
...@@ -2494,6 +2621,8 @@ void mpi3mr_os_handle_events(struct mpi3mr_ioc *mrioc, ...@@ -2494,6 +2621,8 @@ void mpi3mr_os_handle_events(struct mpi3mr_ioc *mrioc,
} }
case MPI3_EVENT_DEVICE_INFO_CHANGED: case MPI3_EVENT_DEVICE_INFO_CHANGED:
case MPI3_EVENT_LOG_DATA: case MPI3_EVENT_LOG_DATA:
case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE:
case MPI3_EVENT_ENCL_DEVICE_ADDED:
{ {
process_evt_bh = 1; process_evt_bh = 1;
break; break;
...@@ -2508,7 +2637,6 @@ void mpi3mr_os_handle_events(struct mpi3mr_ioc *mrioc, ...@@ -2508,7 +2637,6 @@ void mpi3mr_os_handle_events(struct mpi3mr_ioc *mrioc,
mpi3mr_cablemgmt_evt_th(mrioc, event_reply); mpi3mr_cablemgmt_evt_th(mrioc, event_reply);
break; break;
} }
case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE:
case MPI3_EVENT_SAS_DISCOVERY: case MPI3_EVENT_SAS_DISCOVERY:
case MPI3_EVENT_SAS_DEVICE_DISCOVERY_ERROR: case MPI3_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
case MPI3_EVENT_SAS_BROADCAST_PRIMITIVE: case MPI3_EVENT_SAS_BROADCAST_PRIMITIVE:
...@@ -4561,6 +4689,7 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -4561,6 +4689,7 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
INIT_LIST_HEAD(&mrioc->tgtdev_list); INIT_LIST_HEAD(&mrioc->tgtdev_list);
INIT_LIST_HEAD(&mrioc->delayed_rmhs_list); INIT_LIST_HEAD(&mrioc->delayed_rmhs_list);
INIT_LIST_HEAD(&mrioc->delayed_evtack_cmds_list); INIT_LIST_HEAD(&mrioc->delayed_evtack_cmds_list);
INIT_LIST_HEAD(&mrioc->enclosure_list);
mutex_init(&mrioc->reset_mutex); mutex_init(&mrioc->reset_mutex);
mpi3mr_init_drv_cmd(&mrioc->init_cmds, MPI3MR_HOSTTAG_INITCMDS); mpi3mr_init_drv_cmd(&mrioc->init_cmds, MPI3MR_HOSTTAG_INITCMDS);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment