summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-10-27 13:38:11 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-11 18:22:33 -0600
commit7af670510df343db55752a2210dcf4fc09f59fbb (patch)
tree59baacb490afb7dcd955ad8daca734eae7d8cef8 /drivers/scsi/lpfc
parent76bb24efdc5de8eead0ccc07ec7e3b59a4ca0f15 (diff)
[SCSI] lpfc 8.2.3 : Temperature handling fix
Temperature handling fix - return proper error code indicator for applications Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc.h6
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c12
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c12
3 files changed, 30 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 46ccdffb46a..1ddfd688fea 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -386,6 +386,11 @@ struct hbq_s {
#define LPFC_ELS_HBQ 0
#define LPFC_EXTRA_HBQ 1
+enum hba_temp_state {
+ HBA_NORMAL_TEMP,
+ HBA_OVER_TEMP
+};
+
struct lpfc_hba {
struct lpfc_sli sli;
uint32_t sli_rev; /* SLI2 or SLI3 */
@@ -589,6 +594,7 @@ struct lpfc_hba {
*/
#define QUE_BUFTAG_BIT (1<<31)
uint32_t buffer_tag_count;
+ enum hba_temp_state over_temp_state;
};
static inline struct Scsi_Host *
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 4e9e890449a..e1b041d8f6d 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -979,6 +979,12 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count)
unsigned int i, j, cnt=count;
u8 wwpn[8];
+ spin_lock_irq(&phba->hbalock);
+ if (phba->over_temp_state == HBA_OVER_TEMP) {
+ spin_unlock_irq(&phba->hbalock);
+ return -EPERM;
+ }
+ spin_unlock_irq(&phba->hbalock);
/* count may include a LF at end of string */
if (buf[cnt-1] == '\n')
cnt--;
@@ -1750,6 +1756,12 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
spin_lock_irq(&phba->hbalock);
+ if (phba->over_temp_state == HBA_OVER_TEMP) {
+ sysfs_mbox_idle(phba);
+ spin_unlock_irq(&phba->hbalock);
+ return -EPERM;
+ }
+
if (off == 0 &&
phba->sysfs_mbox.state == SMBOX_WRITING &&
phba->sysfs_mbox.offset >= 2 * sizeof(uint32_t)) {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index db96f7504a1..0615af41c7b 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -246,6 +246,15 @@ lpfc_config_port_post(struct lpfc_hba *phba)
int i, j;
int rc;
+ spin_lock_irq(&phba->hbalock);
+ /*
+ * If the Config port completed correctly the HBA is not
+ * over heated any more.
+ */
+ if (phba->over_temp_state == HBA_OVER_TEMP)
+ phba->over_temp_state = HBA_NORMAL_TEMP;
+ spin_unlock_irq(&phba->hbalock);
+
pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!pmb) {
phba->link_state = LPFC_HBA_ERROR;
@@ -703,7 +712,10 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
SCSI_NL_VID_TYPE_PCI
| PCI_VENDOR_ID_EMULEX);
+ spin_lock_irq(&phba->hbalock);
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
+ phba->over_temp_state = HBA_OVER_TEMP;
+ spin_unlock_irq(&phba->hbalock);
lpfc_offline_prep(phba);
lpfc_offline(phba);
lpfc_unblock_mgmt_io(phba);