diff options
author | Kashyap, Desai <kashyap.desai@lsi.com> | 2011-05-04 07:05:58 -0400 |
---|---|---|
committer | James Bottomley <jbottomley@parallels.com> | 2011-05-24 12:33:01 -0400 |
commit | 3ace8e052be5293ebb3e00f819effccc64108a38 (patch) | |
tree | d53bbc6d6088e73356c411b06873e1788cfa0da8 | |
parent | d762f4383100c2a87b1a3f2d678cd3b5425655b4 (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.c | 94 |
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 | */ |
4056 | static void | 4060 | static 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 | */ | ||
4097 | static 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 | */ | ||
4119 | static 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; |