提交 0f624c39 编写于 作者: S Sreekanth Reddy 提交者: Christoph Hellwig

mpt3sas: Clear PFA Status on SGPIO when PFA Drive is Removed or Replaced

Added code to send an SEP message that turns off the Predictive
Failure LED when a drive is removed (if Predictive Failure LED was turned on).

Added a new flag 'pfa_led_on' per device that tracks the status of Predictive
Failure LED. When the drive is removed, this flag is checked and
sends an SEP message to turn off the respective Predictive Failure LED.
Signed-off-by: NSreekanth Reddy <Sreekanth.Reddy@avagotech.com>
Reviewed-by: NMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: NChristoph Hellwig <hch@lst.de>
上级 861ff736
...@@ -272,8 +272,10 @@ struct _internal_cmd { ...@@ -272,8 +272,10 @@ struct _internal_cmd {
* @channel: target channel * @channel: target channel
* @slot: number number * @slot: number number
* @phy: phy identifier provided in sas device page 0 * @phy: phy identifier provided in sas device page 0
* @fast_path: fast path feature enable bit
* @responding: used in _scsih_sas_device_mark_responding * @responding: used in _scsih_sas_device_mark_responding
* @fast_path: fast path feature enable bit
* @pfa_led_on: flag for PFA LED status
*
*/ */
struct _sas_device { struct _sas_device {
struct list_head list; struct list_head list;
...@@ -293,6 +295,7 @@ struct _sas_device { ...@@ -293,6 +295,7 @@ struct _sas_device {
u8 phy; u8 phy;
u8 responding; u8 responding;
u8 fast_path; u8 fast_path;
u8 pfa_led_on;
}; };
/** /**
......
...@@ -159,7 +159,7 @@ struct sense_info { ...@@ -159,7 +159,7 @@ struct sense_info {
}; };
#define MPT3SAS_PROCESS_TRIGGER_DIAG (0xFFFB) #define MPT3SAS_PROCESS_TRIGGER_DIAG (0xFFFB)
#define MPT3SAS_TURN_ON_FAULT_LED (0xFFFC) #define MPT3SAS_TURN_ON_PFA_LED (0xFFFC)
#define MPT3SAS_PORT_ENABLE_COMPLETE (0xFFFD) #define MPT3SAS_PORT_ENABLE_COMPLETE (0xFFFD)
#define MPT3SAS_ABRT_TASK_SET (0xFFFE) #define MPT3SAS_ABRT_TASK_SET (0xFFFE)
#define MPT3SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF) #define MPT3SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF)
...@@ -3885,7 +3885,7 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, ...@@ -3885,7 +3885,7 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
#endif #endif
/** /**
* _scsih_turn_on_fault_led - illuminate Fault LED * _scsih_turn_on_pfa_led - illuminate PFA LED
* @ioc: per adapter object * @ioc: per adapter object
* @handle: device handle * @handle: device handle
* Context: process * Context: process
...@@ -3893,10 +3893,15 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, ...@@ -3893,10 +3893,15 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
* Return nothing. * Return nothing.
*/ */
static void static void
_scsih_turn_on_fault_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) _scsih_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
{ {
Mpi2SepReply_t mpi_reply; Mpi2SepReply_t mpi_reply;
Mpi2SepRequest_t mpi_request; Mpi2SepRequest_t mpi_request;
struct _sas_device *sas_device;
sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
if (!sas_device)
return;
memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t));
mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
...@@ -3911,6 +3916,7 @@ _scsih_turn_on_fault_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -3911,6 +3916,7 @@ _scsih_turn_on_fault_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
__FILE__, __LINE__, __func__); __FILE__, __LINE__, __func__);
return; return;
} }
sas_device->pfa_led_on = 1;
if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) {
dewtprintk(ioc, pr_info(MPT3SAS_FMT dewtprintk(ioc, pr_info(MPT3SAS_FMT
...@@ -3920,9 +3926,46 @@ _scsih_turn_on_fault_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -3920,9 +3926,46 @@ _scsih_turn_on_fault_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
return; return;
} }
} }
/**
* _scsih_turn_off_pfa_led - turn off Fault LED
* @ioc: per adapter object
* @sas_device: sas device whose PFA LED has to turned off
* Context: process
*
* Return nothing.
*/
static void
_scsih_turn_off_pfa_led(struct MPT3SAS_ADAPTER *ioc,
struct _sas_device *sas_device)
{
Mpi2SepReply_t mpi_reply;
Mpi2SepRequest_t mpi_request;
memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t));
mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
mpi_request.SlotStatus = 0;
mpi_request.Slot = cpu_to_le16(sas_device->slot);
mpi_request.DevHandle = 0;
mpi_request.EnclosureHandle = cpu_to_le16(sas_device->enclosure_handle);
mpi_request.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS;
if ((mpt3sas_base_scsi_enclosure_processor(ioc, &mpi_reply,
&mpi_request)) != 0) {
printk(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name,
__FILE__, __LINE__, __func__);
return;
}
if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) {
dewtprintk(ioc, printk(MPT3SAS_FMT
"enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n",
ioc->name, le16_to_cpu(mpi_reply.IOCStatus),
le32_to_cpu(mpi_reply.IOCLogInfo)));
return;
}
}
/** /**
* _scsih_send_event_to_turn_on_fault_led - fire delayed event * _scsih_send_event_to_turn_on_pfa_led - fire delayed event
* @ioc: per adapter object * @ioc: per adapter object
* @handle: device handle * @handle: device handle
* Context: interrupt. * Context: interrupt.
...@@ -3930,14 +3973,14 @@ _scsih_turn_on_fault_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -3930,14 +3973,14 @@ _scsih_turn_on_fault_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
* Return nothing. * Return nothing.
*/ */
static void static void
_scsih_send_event_to_turn_on_fault_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) _scsih_send_event_to_turn_on_pfa_led(struct MPT3SAS_ADAPTER *ioc, u16 handle)
{ {
struct fw_event_work *fw_event; struct fw_event_work *fw_event;
fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
if (!fw_event) if (!fw_event)
return; return;
fw_event->event = MPT3SAS_TURN_ON_FAULT_LED; fw_event->event = MPT3SAS_TURN_ON_PFA_LED;
fw_event->device_handle = handle; fw_event->device_handle = handle;
fw_event->ioc = ioc; fw_event->ioc = ioc;
_scsih_fw_event_add(ioc, fw_event); _scsih_fw_event_add(ioc, fw_event);
...@@ -3981,7 +4024,7 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -3981,7 +4024,7 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle)
spin_unlock_irqrestore(&ioc->sas_device_lock, flags); spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM)
_scsih_send_event_to_turn_on_fault_led(ioc, handle); _scsih_send_event_to_turn_on_pfa_led(ioc, handle);
/* insert into event log */ /* insert into event log */
sz = offsetof(Mpi2EventNotificationReply_t, EventData) + sz = offsetof(Mpi2EventNotificationReply_t, EventData) +
...@@ -4911,7 +4954,11 @@ _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc, ...@@ -4911,7 +4954,11 @@ _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc,
{ {
struct MPT3SAS_TARGET *sas_target_priv_data; struct MPT3SAS_TARGET *sas_target_priv_data;
if ((ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) &&
(sas_device->pfa_led_on)) {
_scsih_turn_off_pfa_led(ioc, sas_device);
sas_device->pfa_led_on = 0;
}
dewtprintk(ioc, pr_info(MPT3SAS_FMT dewtprintk(ioc, pr_info(MPT3SAS_FMT
"%s: enter: handle(0x%04x), sas_addr(0x%016llx)\n", "%s: enter: handle(0x%04x), sas_addr(0x%016llx)\n",
ioc->name, __func__, ioc->name, __func__,
...@@ -7065,8 +7112,8 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) ...@@ -7065,8 +7112,8 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
"port enable: complete from worker thread\n", "port enable: complete from worker thread\n",
ioc->name)); ioc->name));
break; break;
case MPT3SAS_TURN_ON_FAULT_LED: case MPT3SAS_TURN_ON_PFA_LED:
_scsih_turn_on_fault_led(ioc, fw_event->device_handle); _scsih_turn_on_pfa_led(ioc, fw_event->device_handle);
break; break;
case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
_scsih_sas_topology_change_event(ioc, fw_event); _scsih_sas_topology_change_event(ioc, fw_event);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册