Commit 3eb0822c authored by Kashyap, Desai's avatar Kashyap, Desai Committed by James Bottomley
Browse files

[SCSI] mpt fusion: Firmware event implementation using seperate WorkQueue



Now Firmware events are handled by firmware event queue.
Previously it was handled in interrupt context/WorkQueue of Linux.
Firmware Event handling is restructured and optimized.

Signed-off-by: default avatarKashyap Desai <kadesai@lsi.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent ea2a788d
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1931,6 +1931,11 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
	 */
	mpt_detect_bound_ports(ioc, pdev);

	INIT_LIST_HEAD(&ioc->fw_event_list);
	spin_lock_init(&ioc->fw_event_lock);
	snprintf(ioc->fw_event_q_name, 20, "mpt/%d", ioc->id);
	ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);

	if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
	    CAN_SLEEP)) != 0){
		printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
@@ -2010,6 +2015,11 @@ mpt_detach(struct pci_dev *pdev)
	cancel_delayed_work(&ioc->fault_reset_work);
	destroy_workqueue(wq);

	spin_lock_irqsave(&ioc->fw_event_lock, flags);
	wq = ioc->fw_event_q;
	ioc->fw_event_q = NULL;
	spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
	destroy_workqueue(wq);

	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
	remove_proc_entry(pname, NULL);
+9 −0
Original line number Diff line number Diff line
@@ -694,9 +694,18 @@ typedef struct _MPT_ADAPTER
	struct net_device	*netdev;
	struct list_head	 sas_topology;
	struct mutex		 sas_topology_mutex;

	struct workqueue_struct	*fw_event_q;
	struct list_head	 fw_event_list;
	spinlock_t		 fw_event_lock;
	u8			 fw_events_off; /* if '1', then ignore events */
	char 			 fw_event_q_name[20];

	struct mutex		 sas_discovery_mutex;
	u8			 sas_discovery_runtime;
	u8			 sas_discovery_ignore_events;
	struct list_head	 sas_device_info_list;
	struct mutex		 sas_device_info_mutex;
	u8			 sas_discovery_quiesce_io;
	int			 sas_index; /* index refrencing */
	MPT_MGMT		 sas_mgmt;
+936 −442

File changed.

Preview size limit exceeded, changes collapsed.

+29 −4
Original line number Diff line number Diff line
@@ -61,12 +61,30 @@ enum mptsas_hotplug_action {
	MPTSAS_DEL_DEVICE,
	MPTSAS_ADD_RAID,
	MPTSAS_DEL_RAID,
	MPTSAS_ADD_PHYSDISK,
	MPTSAS_ADD_PHYSDISK_REPROBE,
	MPTSAS_DEL_PHYSDISK,
	MPTSAS_DEL_PHYSDISK_REPROBE,
	MPTSAS_ADD_INACTIVE_VOLUME,
	MPTSAS_IGNORE_EVENT,
};

struct mptsas_mapping{
	u8			id;
	u8			channel;
};

struct mptsas_device_info {
	struct list_head 	list;
	struct mptsas_mapping	os;	/* operating system mapping*/
	struct mptsas_mapping	fw;	/* firmware mapping */
	u64			sas_address;
	u32			device_info; /* specific bits for devices */
	u16			slot;		/* enclosure slot id */
	u64			enclosure_logical_id; /*enclosure address */
};

struct mptsas_hotplug_event {
	struct work_struct	work;
	MPT_ADAPTER		*ioc;
	enum mptsas_hotplug_action event_type;
	u64			sas_address;
@@ -74,11 +92,18 @@ struct mptsas_hotplug_event {
	u8			id;
	u32			device_info;
	u16			handle;
	u16			parent_handle;
	u8			phy_id;
	u8			phys_disk_num_valid;	/* hrc (hidden raid component) */
	u8			phys_disk_num;		/* hrc - unique index*/
	u8			hidden_raid_component;	/* hrc - don't expose*/
	struct scsi_device	*sdev;
};

struct fw_event_work {
	struct list_head 	list;
	struct delayed_work	 work;
	MPT_ADAPTER	*ioc;
	u32			event;
	u8			retries;
	u8			event_data[1];
};

struct mptsas_discovery_event {