aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2011-05-04 07:05:58 -0400
committerJames Bottomley <jbottomley@parallels.com>2011-05-24 12:33:01 -0400
commit3ace8e052be5293ebb3e00f819effccc64108a38 (patch)
treed53bbc6d6088e73356c411b06873e1788cfa0da8
parentd762f4383100c2a87b1a3f2d678cd3b5425655b4 (diff)
[SCSI] mpt2sas: move even handling of MPT2SAS_TURN_ON_FAULT_LED into process context
Driver was a sending a SEP request during interrupt context which required to go to sleep. The fix is to rearrange the code so a fake event MPT2SAS_TURN_ON_FAULT_LED is fired from interrupt context, then later during the kernel worker threads processing, the SEP request is issued to firmware. Cc: stable@kernel.org Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: James Bottomley <jbottomley@parallels.com>
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c94
1 files changed, 68 insertions, 26 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index f12e02358d6d..e97363c75074 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -113,6 +113,7 @@ struct sense_info {
113}; 113};
114 114
115 115
116#define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC)
116#define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF) 117#define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF)
117 118
118/** 119/**
@@ -121,6 +122,7 @@ struct sense_info {
121 * @work: work object (ioc->fault_reset_work_q) 122 * @work: work object (ioc->fault_reset_work_q)
122 * @cancel_pending_work: flag set during reset handling 123 * @cancel_pending_work: flag set during reset handling
123 * @ioc: per adapter object 124 * @ioc: per adapter object
125 * @device_handle: device handle
124 * @VF_ID: virtual function id 126 * @VF_ID: virtual function id
125 * @VP_ID: virtual port id 127 * @VP_ID: virtual port id
126 * @ignore: flag meaning this event has been marked to ignore 128 * @ignore: flag meaning this event has been marked to ignore
@@ -134,6 +136,7 @@ struct fw_event_work {
134 u8 cancel_pending_work; 136 u8 cancel_pending_work;
135 struct delayed_work delayed_work; 137 struct delayed_work delayed_work;
136 struct MPT2SAS_ADAPTER *ioc; 138 struct MPT2SAS_ADAPTER *ioc;
139 u16 device_handle;
137 u8 VF_ID; 140 u8 VF_ID;
138 u8 VP_ID; 141 u8 VP_ID;
139 u8 ignore; 142 u8 ignore;
@@ -4047,17 +4050,75 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
4047#endif 4050#endif
4048 4051
4049/** 4052/**
4050 * _scsih_smart_predicted_fault - illuminate Fault LED 4053 * _scsih_turn_on_fault_led - illuminate Fault LED
4051 * @ioc: per adapter object 4054 * @ioc: per adapter object
4052 * @handle: device handle 4055 * @handle: device handle
4056 * Context: process
4053 * 4057 *
4054 * Return nothing. 4058 * Return nothing.
4055 */ 4059 */
4056static void 4060static void
4057_scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) 4061_scsih_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle)
4058{ 4062{
4059 Mpi2SepReply_t mpi_reply; 4063 Mpi2SepReply_t mpi_reply;
4060 Mpi2SepRequest_t mpi_request; 4064 Mpi2SepRequest_t mpi_request;
4065
4066 memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t));
4067 mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
4068 mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
4069 mpi_request.SlotStatus =
4070 cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
4071 mpi_request.DevHandle = cpu_to_le16(handle);
4072 mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS;
4073 if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply,
4074 &mpi_request)) != 0) {
4075 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name,
4076 __FILE__, __LINE__, __func__);
4077 return;
4078 }
4079
4080 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) {
4081 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "enclosure_processor: "
4082 "ioc_status (0x%04x), loginfo(0x%08x)\n", ioc->name,
4083 le16_to_cpu(mpi_reply.IOCStatus),
4084 le32_to_cpu(mpi_reply.IOCLogInfo)));
4085 return;
4086 }
4087}
4088
4089/**
4090 * _scsih_send_event_to_turn_on_fault_led - fire delayed event
4091 * @ioc: per adapter object
4092 * @handle: device handle
4093 * Context: interrupt.
4094 *
4095 * Return nothing.
4096 */
4097static void
4098_scsih_send_event_to_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle)
4099{
4100 struct fw_event_work *fw_event;
4101
4102 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
4103 if (!fw_event)
4104 return;
4105 fw_event->event = MPT2SAS_TURN_ON_FAULT_LED;
4106 fw_event->device_handle = handle;
4107 fw_event->ioc = ioc;
4108 _scsih_fw_event_add(ioc, fw_event);
4109}
4110
4111/**
4112 * _scsih_smart_predicted_fault - process smart errors
4113 * @ioc: per adapter object
4114 * @handle: device handle
4115 * Context: interrupt.
4116 *
4117 * Return nothing.
4118 */
4119static void
4120_scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle)
4121{
4061 struct scsi_target *starget; 4122 struct scsi_target *starget;
4062 struct MPT2SAS_TARGET *sas_target_priv_data; 4123 struct MPT2SAS_TARGET *sas_target_priv_data;
4063 Mpi2EventNotificationReply_t *event_reply; 4124 Mpi2EventNotificationReply_t *event_reply;
@@ -4084,30 +4145,8 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle)
4084 starget_printk(KERN_WARNING, starget, "predicted fault\n"); 4145 starget_printk(KERN_WARNING, starget, "predicted fault\n");
4085 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 4146 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4086 4147
4087 if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) { 4148 if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM)
4088 memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); 4149 _scsih_send_event_to_turn_on_fault_led(ioc, handle);
4089 mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
4090 mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
4091 mpi_request.SlotStatus =
4092 cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
4093 mpi_request.DevHandle = cpu_to_le16(handle);
4094 mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS;
4095 if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply,
4096 &mpi_request)) != 0) {
4097 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
4098 ioc->name, __FILE__, __LINE__, __func__);
4099 return;
4100 }
4101
4102 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) {
4103 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
4104 "enclosure_processor: ioc_status (0x%04x), "
4105 "loginfo(0x%08x)\n", ioc->name,
4106 le16_to_cpu(mpi_reply.IOCStatus),
4107 le32_to_cpu(mpi_reply.IOCLogInfo)));
4108 return;
4109 }
4110 }
4111 4150
4112 /* insert into event log */ 4151 /* insert into event log */
4113 sz = offsetof(Mpi2EventNotificationReply_t, EventData) + 4152 sz = offsetof(Mpi2EventNotificationReply_t, EventData) +
@@ -6753,6 +6792,9 @@ _firmware_event_work(struct work_struct *work)
6753 } 6792 }
6754 6793
6755 switch (fw_event->event) { 6794 switch (fw_event->event) {
6795 case MPT2SAS_TURN_ON_FAULT_LED:
6796 _scsih_turn_on_fault_led(ioc, fw_event->device_handle);
6797 break;
6756 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 6798 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
6757 _scsih_sas_topology_change_event(ioc, fw_event); 6799 _scsih_sas_topology_change_event(ioc, fw_event);
6758 break; 6800 break;