From 0f624c391ecbf18e69b20d681f7e3c52b4ef02c1 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Fri, 12 Sep 2014 15:35:26 +0530 Subject: 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: Sreekanth Reddy Reviewed-by: Martin K. Petersen Signed-off-by: Christoph Hellwig --- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 67 ++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 10 deletions(-) (limited to 'drivers/scsi/mpt3sas/mpt3sas_scsih.c') diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 135f12c20ecf..77a5bfa100f8 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -159,7 +159,7 @@ struct sense_info { }; #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_ABRT_TASK_SET (0xFFFE) #define MPT3SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF) @@ -3885,7 +3885,7 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, #endif /** - * _scsih_turn_on_fault_led - illuminate Fault LED + * _scsih_turn_on_pfa_led - illuminate PFA LED * @ioc: per adapter object * @handle: device handle * Context: process @@ -3893,10 +3893,15 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, * Return nothing. */ 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; 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)); mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; @@ -3911,6 +3916,7 @@ _scsih_turn_on_fault_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) __FILE__, __LINE__, __func__); return; } + sas_device->pfa_led_on = 1; if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) { dewtprintk(ioc, pr_info(MPT3SAS_FMT @@ -3920,9 +3926,46 @@ _scsih_turn_on_fault_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) 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 * @handle: device handle * Context: interrupt. @@ -3930,14 +3973,14 @@ _scsih_turn_on_fault_led(struct MPT3SAS_ADAPTER *ioc, u16 handle) * Return nothing. */ 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; fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); if (!fw_event) return; - fw_event->event = MPT3SAS_TURN_ON_FAULT_LED; + fw_event->event = MPT3SAS_TURN_ON_PFA_LED; fw_event->device_handle = handle; fw_event->ioc = ioc; _scsih_fw_event_add(ioc, fw_event); @@ -3981,7 +4024,7 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle) spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 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 */ sz = offsetof(Mpi2EventNotificationReply_t, EventData) + @@ -4911,7 +4954,11 @@ _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc, { 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 "%s: enter: handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, @@ -7065,8 +7112,8 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) "port enable: complete from worker thread\n", ioc->name)); break; - case MPT3SAS_TURN_ON_FAULT_LED: - _scsih_turn_on_fault_led(ioc, fw_event->device_handle); + case MPT3SAS_TURN_ON_PFA_LED: + _scsih_turn_on_pfa_led(ioc, fw_event->device_handle); break; case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: _scsih_sas_topology_change_event(ioc, fw_event); -- cgit v1.2.3 From a4ffce0d63e0683060fee6bc269f7b0b12c9700a Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Fri, 12 Sep 2014 15:35:29 +0530 Subject: mpt3sas: Copyright in driver sources is updated for year the 2014. Copyright in driver sources is updated for year the 2014. Signed-off-by: Sreekanth Reddy Reviewed-by: Martin K. Petersen Signed-off-by: Christoph Hellwig --- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/scsi/mpt3sas/mpt3sas_scsih.c') diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 77a5bfa100f8..95a1049472f0 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -2,7 +2,7 @@ * Scsi Host Layer for MPT (Message Passing Technology) based controllers * * This code is based on drivers/scsi/mpt3sas/mpt3sas_scsih.c - * Copyright (C) 2012-2013 LSI Corporation + * Copyright (C) 2012-2014 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or -- cgit v1.2.3 From b65f1d4da7df44835bd0a2452332e253a5c66d9b Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Fri, 12 Sep 2014 15:35:33 +0530 Subject: mpt3sas, mpt2sas: fix scsi_add_host error handling problems in _scsih_probe In _scsih_probe, propagate the return value from scsi_add_host. In mpt3sas, avoid calling list_del twice if that returns an error, which causes list_del corruption warnings if an error is returned. Tested with blk-mq and scsi-mq patches to properly cleanup from and propagate blk_mq_init_rq_map errors. Signed-off-by: Robert Elliott Acked-by: Sreekanth Reddy Signed-off-by: Christoph Hellwig --- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/scsi/mpt3sas/mpt3sas_scsih.c') diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 95a1049472f0..857276b8880f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -7781,6 +7781,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct MPT3SAS_ADAPTER *ioc; struct Scsi_Host *shost; + int rv; shost = scsi_host_alloc(&scsih_driver_template, sizeof(struct MPT3SAS_ADAPTER)); @@ -7873,6 +7874,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (!ioc->firmware_event_thread) { pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); + rv = -ENODEV; goto out_thread_fail; } @@ -7880,12 +7882,13 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) if ((mpt3sas_base_attach(ioc))) { pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); + rv = -ENODEV; goto out_attach_fail; } - if ((scsi_add_host(shost, &pdev->dev))) { + rv = scsi_add_host(shost, &pdev->dev); + if (rv) { pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); - list_del(&ioc->list); goto out_add_shost_fail; } @@ -7898,7 +7901,7 @@ out_add_shost_fail: out_thread_fail: list_del(&ioc->list); scsi_host_put(shost); - return -ENODEV; + return rv; } #ifdef CONFIG_PM -- cgit v1.2.3