aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSreekanth Reddy <sreekanth.reddy@avagotech.com>2014-09-12 06:05:19 -0400
committerChristoph Hellwig <hch@lst.de>2014-09-16 12:14:14 -0400
commitbd58ea3c25dbee16857733f3176dba23c34b64e5 (patch)
treea08c268f65f93d7c9d6ff79ef368268841293c92
parente9edbe310dbb745067f7c5761ba91005fb9d60af (diff)
mpt2sas: Clear PFA Status on SGPIO when PFA Drive is Removed or Replaced
Added code to send a 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 the SEP message to turn off the respective Predictive Failure LED. Signed-off-by: Sreekanth Reddy <Sreekanth.Reddy@avagotech.com> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c70
2 files changed, 63 insertions, 9 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index 89f944ac0028..6ce7020afa52 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -355,6 +355,7 @@ struct _internal_cmd {
355 * @slot: number number 355 * @slot: number number
356 * @phy: phy identifier provided in sas device page 0 356 * @phy: phy identifier provided in sas device page 0
357 * @responding: used in _scsih_sas_device_mark_responding 357 * @responding: used in _scsih_sas_device_mark_responding
358 * @pfa_led_on: flag for PFA LED status
358 */ 359 */
359struct _sas_device { 360struct _sas_device {
360 struct list_head list; 361 struct list_head list;
@@ -373,6 +374,7 @@ struct _sas_device {
373 u16 slot; 374 u16 slot;
374 u8 phy; 375 u8 phy;
375 u8 responding; 376 u8 responding;
377 u8 pfa_led_on;
376}; 378};
377 379
378/** 380/**
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index db71b60e8a87..e7303edc3d8e 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -145,7 +145,7 @@ struct sense_info {
145}; 145};
146 146
147 147
148#define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC) 148#define MPT2SAS_TURN_ON_PFA_LED (0xFFFC)
149#define MPT2SAS_PORT_ENABLE_COMPLETE (0xFFFD) 149#define MPT2SAS_PORT_ENABLE_COMPLETE (0xFFFD)
150#define MPT2SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF) 150#define MPT2SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF)
151/** 151/**
@@ -4308,7 +4308,7 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
4308#endif 4308#endif
4309 4309
4310/** 4310/**
4311 * _scsih_turn_on_fault_led - illuminate Fault LED 4311 * _scsih_turn_on_pfa_led - illuminate PFA LED
4312 * @ioc: per adapter object 4312 * @ioc: per adapter object
4313 * @handle: device handle 4313 * @handle: device handle
4314 * Context: process 4314 * Context: process
@@ -4316,10 +4316,15 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
4316 * Return nothing. 4316 * Return nothing.
4317 */ 4317 */
4318static void 4318static void
4319_scsih_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) 4319_scsih_turn_on_pfa_led(struct MPT2SAS_ADAPTER *ioc, u16 handle)
4320{ 4320{
4321 Mpi2SepReply_t mpi_reply; 4321 Mpi2SepReply_t mpi_reply;
4322 Mpi2SepRequest_t mpi_request; 4322 Mpi2SepRequest_t mpi_request;
4323 struct _sas_device *sas_device;
4324
4325 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
4326 if (!sas_device)
4327 return;
4323 4328
4324 memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t)); 4329 memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t));
4325 mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; 4330 mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
@@ -4334,6 +4339,47 @@ _scsih_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle)
4334 __FILE__, __LINE__, __func__); 4339 __FILE__, __LINE__, __func__);
4335 return; 4340 return;
4336 } 4341 }
4342 sas_device->pfa_led_on = 1;
4343
4344
4345 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) {
4346 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
4347 "enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n",
4348 ioc->name, le16_to_cpu(mpi_reply.IOCStatus),
4349 le32_to_cpu(mpi_reply.IOCLogInfo)));
4350 return;
4351 }
4352}
4353
4354/**
4355 * _scsih_turn_off_pfa_led - turn off PFA LED
4356 * @ioc: per adapter object
4357 * @sas_device: sas device whose PFA LED has to turned off
4358 * Context: process
4359 *
4360 * Return nothing.
4361 */
4362static void
4363_scsih_turn_off_pfa_led(struct MPT2SAS_ADAPTER *ioc,
4364 struct _sas_device *sas_device)
4365{
4366 Mpi2SepReply_t mpi_reply;
4367 Mpi2SepRequest_t mpi_request;
4368
4369 memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t));
4370 mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
4371 mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
4372 mpi_request.SlotStatus = 0;
4373 mpi_request.Slot = cpu_to_le16(sas_device->slot);
4374 mpi_request.DevHandle = 0;
4375 mpi_request.EnclosureHandle = cpu_to_le16(sas_device->enclosure_handle);
4376 mpi_request.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS;
4377 if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply,
4378 &mpi_request)) != 0) {
4379 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name,
4380 __FILE__, __LINE__, __func__);
4381 return;
4382 }
4337 4383
4338 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { 4384 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) {
4339 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "enclosure_processor: " 4385 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "enclosure_processor: "
@@ -4345,7 +4391,7 @@ _scsih_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle)
4345} 4391}
4346 4392
4347/** 4393/**
4348 * _scsih_send_event_to_turn_on_fault_led - fire delayed event 4394 * _scsih_send_event_to_turn_on_pfa_led - fire delayed event
4349 * @ioc: per adapter object 4395 * @ioc: per adapter object
4350 * @handle: device handle 4396 * @handle: device handle
4351 * Context: interrupt. 4397 * Context: interrupt.
@@ -4353,14 +4399,14 @@ _scsih_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle)
4353 * Return nothing. 4399 * Return nothing.
4354 */ 4400 */
4355static void 4401static void
4356_scsih_send_event_to_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) 4402_scsih_send_event_to_turn_on_pfa_led(struct MPT2SAS_ADAPTER *ioc, u16 handle)
4357{ 4403{
4358 struct fw_event_work *fw_event; 4404 struct fw_event_work *fw_event;
4359 4405
4360 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); 4406 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
4361 if (!fw_event) 4407 if (!fw_event)
4362 return; 4408 return;
4363 fw_event->event = MPT2SAS_TURN_ON_FAULT_LED; 4409 fw_event->event = MPT2SAS_TURN_ON_PFA_LED;
4364 fw_event->device_handle = handle; 4410 fw_event->device_handle = handle;
4365 fw_event->ioc = ioc; 4411 fw_event->ioc = ioc;
4366 _scsih_fw_event_add(ioc, fw_event); 4412 _scsih_fw_event_add(ioc, fw_event);
@@ -4404,7 +4450,7 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle)
4404 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 4450 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
4405 4451
4406 if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) 4452 if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM)
4407 _scsih_send_event_to_turn_on_fault_led(ioc, handle); 4453 _scsih_send_event_to_turn_on_pfa_led(ioc, handle);
4408 4454
4409 /* insert into event log */ 4455 /* insert into event log */
4410 sz = offsetof(Mpi2EventNotificationReply_t, EventData) + 4456 sz = offsetof(Mpi2EventNotificationReply_t, EventData) +
@@ -5325,6 +5371,12 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc,
5325{ 5371{
5326 struct MPT2SAS_TARGET *sas_target_priv_data; 5372 struct MPT2SAS_TARGET *sas_target_priv_data;
5327 5373
5374 if ((ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) &&
5375 (sas_device->pfa_led_on)) {
5376 _scsih_turn_off_pfa_led(ioc, sas_device);
5377 sas_device->pfa_led_on = 0;
5378 }
5379
5328 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: " 5380 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: "
5329 "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, 5381 "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__,
5330 sas_device->handle, (unsigned long long) 5382 sas_device->handle, (unsigned long long)
@@ -7441,8 +7493,8 @@ _firmware_event_work(struct work_struct *work)
7441 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "port enable: complete " 7493 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "port enable: complete "
7442 "from worker thread\n", ioc->name)); 7494 "from worker thread\n", ioc->name));
7443 break; 7495 break;
7444 case MPT2SAS_TURN_ON_FAULT_LED: 7496 case MPT2SAS_TURN_ON_PFA_LED:
7445 _scsih_turn_on_fault_led(ioc, fw_event->device_handle); 7497 _scsih_turn_on_pfa_led(ioc, fw_event->device_handle);
7446 break; 7498 break;
7447 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 7499 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
7448 _scsih_sas_topology_change_event(ioc, fw_event); 7500 _scsih_sas_topology_change_event(ioc, fw_event);