aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_attr.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2006-08-18 17:47:08 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-09-04 22:25:21 -0400
commitc01f32087960edd60a302ad62ad6b8b525e4aeec (patch)
treeabefc5afc051d379802de42175e14df37d79b4ae /drivers/scsi/lpfc/lpfc_attr.c
parent0f29b966d60e9a4f5ecff9f3832257b38aea4f13 (diff)
[SCSI] lpfc 8.1.10 : Add support for dev_loss_tmo_callbk and fast_io_fail_tmo_callbk
Add support for new dev_loss_tmo callback Goodness is that it removes code for a parallel nodev timer that existed in the driver Add support for the new fast_io_fail callback Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_attr.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c155
1 files changed, 127 insertions, 28 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index c6d683d86cff..0de69324212e 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -39,6 +39,9 @@
39#include "lpfc_compat.h" 39#include "lpfc_compat.h"
40#include "lpfc_crtn.h" 40#include "lpfc_crtn.h"
41 41
42#define LPFC_DEF_DEVLOSS_TMO 30
43#define LPFC_MIN_DEVLOSS_TMO 1
44#define LPFC_MAX_DEVLOSS_TMO 255
42 45
43static void 46static void
44lpfc_jedec_to_ascii(int incr, char hdw[]) 47lpfc_jedec_to_ascii(int incr, char hdw[])
@@ -559,6 +562,123 @@ static CLASS_DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR,
559 lpfc_poll_show, lpfc_poll_store); 562 lpfc_poll_show, lpfc_poll_store);
560 563
561/* 564/*
565# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
566# until the timer expires. Value range is [0,255]. Default value is 30.
567*/
568static int lpfc_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
569static int lpfc_devloss_tmo = LPFC_DEF_DEVLOSS_TMO;
570module_param(lpfc_nodev_tmo, int, 0);
571MODULE_PARM_DESC(lpfc_nodev_tmo,
572 "Seconds driver will hold I/O waiting "
573 "for a device to come back");
574static ssize_t
575lpfc_nodev_tmo_show(struct class_device *cdev, char *buf)
576{
577 struct Scsi_Host *host = class_to_shost(cdev);
578 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
579 int val = 0;
580 val = phba->cfg_devloss_tmo;
581 return snprintf(buf, PAGE_SIZE, "%d\n",
582 phba->cfg_devloss_tmo);
583}
584
585static int
586lpfc_nodev_tmo_init(struct lpfc_hba *phba, int val)
587{
588 static int warned;
589 if (phba->cfg_devloss_tmo != LPFC_DEF_DEVLOSS_TMO) {
590 phba->cfg_nodev_tmo = phba->cfg_devloss_tmo;
591 if (!warned && val != LPFC_DEF_DEVLOSS_TMO) {
592 warned = 1;
593 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
594 "%d:0402 Ignoring nodev_tmo module "
595 "parameter because devloss_tmo is"
596 " set.\n",
597 phba->brd_no);
598 }
599 return 0;
600 }
601
602 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
603 phba->cfg_nodev_tmo = val;
604 phba->cfg_devloss_tmo = val;
605 return 0;
606 }
607 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
608 "%d:0400 lpfc_nodev_tmo attribute cannot be set to %d, "
609 "allowed range is [%d, %d]\n",
610 phba->brd_no, val,
611 LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
612 phba->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
613 return -EINVAL;
614}
615
616static int
617lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val)
618{
619 if (phba->dev_loss_tmo_changed ||
620 (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) {
621 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
622 "%d:0401 Ignoring change to nodev_tmo "
623 "because devloss_tmo is set.\n",
624 phba->brd_no);
625 return 0;
626 }
627
628 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
629 phba->cfg_nodev_tmo = val;
630 phba->cfg_devloss_tmo = val;
631 return 0;
632 }
633
634 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
635 "%d:0403 lpfc_nodev_tmo attribute cannot be set to %d, "
636 "allowed range is [%d, %d]\n",
637 phba->brd_no, val, LPFC_MIN_DEVLOSS_TMO,
638 LPFC_MAX_DEVLOSS_TMO);
639 return -EINVAL;
640}
641
642lpfc_param_store(nodev_tmo)
643
644static CLASS_DEVICE_ATTR(lpfc_nodev_tmo, S_IRUGO | S_IWUSR,
645 lpfc_nodev_tmo_show, lpfc_nodev_tmo_store);
646
647/*
648# lpfc_devloss_tmo: If set, it will hold all I/O errors on devices that
649# disappear until the timer expires. Value range is [0,255]. Default
650# value is 30.
651*/
652module_param(lpfc_devloss_tmo, int, 0);
653MODULE_PARM_DESC(lpfc_devloss_tmo,
654 "Seconds driver will hold I/O waiting "
655 "for a device to come back");
656lpfc_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO,
657 LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO)
658lpfc_param_show(devloss_tmo)
659static int
660lpfc_devloss_tmo_set(struct lpfc_hba *phba, int val)
661{
662 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
663 phba->cfg_nodev_tmo = val;
664 phba->cfg_devloss_tmo = val;
665 phba->dev_loss_tmo_changed = 1;
666 return 0;
667 }
668
669 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
670 "%d:0404 lpfc_devloss_tmo attribute cannot be set to"
671 " %d, allowed range is [%d, %d]\n",
672 phba->brd_no, val, LPFC_MIN_DEVLOSS_TMO,
673 LPFC_MAX_DEVLOSS_TMO);
674 return -EINVAL;
675}
676
677lpfc_param_store(devloss_tmo)
678static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR,
679 lpfc_devloss_tmo_show, lpfc_devloss_tmo_store);
680
681/*
562# lpfc_log_verbose: Only turn this flag on if you are willing to risk being 682# lpfc_log_verbose: Only turn this flag on if you are willing to risk being
563# deluged with LOTS of information. 683# deluged with LOTS of information.
564# You can set a bit mask to record specific types of verbose messages: 684# You can set a bit mask to record specific types of verbose messages:
@@ -617,14 +737,6 @@ LPFC_ATTR_R(scan_down, 1, 0, 1,
617 "Start scanning for devices from highest ALPA to lowest"); 737 "Start scanning for devices from highest ALPA to lowest");
618 738
619/* 739/*
620# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
621# until the timer expires. Value range is [0,255]. Default value is 30.
622# NOTE: this MUST be less then the SCSI Layer command timeout - 1.
623*/
624LPFC_ATTR_RW(nodev_tmo, 30, 0, 255,
625 "Seconds driver will hold I/O waiting for a device to come back");
626
627/*
628# lpfc_topology: link topology for init link 740# lpfc_topology: link topology for init link
629# 0x0 = attempt loop mode then point-to-point 741# 0x0 = attempt loop mode then point-to-point
630# 0x01 = internal loopback mode 742# 0x01 = internal loopback mode
@@ -737,6 +849,7 @@ struct class_device_attribute *lpfc_host_attrs[] = {
737 &class_device_attr_lpfc_lun_queue_depth, 849 &class_device_attr_lpfc_lun_queue_depth,
738 &class_device_attr_lpfc_hba_queue_depth, 850 &class_device_attr_lpfc_hba_queue_depth,
739 &class_device_attr_lpfc_nodev_tmo, 851 &class_device_attr_lpfc_nodev_tmo,
852 &class_device_attr_lpfc_devloss_tmo,
740 &class_device_attr_lpfc_fcp_class, 853 &class_device_attr_lpfc_fcp_class,
741 &class_device_attr_lpfc_use_adisc, 854 &class_device_attr_lpfc_use_adisc,
742 &class_device_attr_lpfc_ack0, 855 &class_device_attr_lpfc_ack0,
@@ -1450,27 +1563,12 @@ lpfc_get_starget_port_name(struct scsi_target *starget)
1450} 1563}
1451 1564
1452static void 1565static void
1453lpfc_get_rport_loss_tmo(struct fc_rport *rport)
1454{
1455 /*
1456 * Return the driver's global value for device loss timeout plus
1457 * five seconds to allow the driver's nodev timer to run.
1458 */
1459 rport->dev_loss_tmo = lpfc_nodev_tmo + 5;
1460}
1461
1462static void
1463lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) 1566lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
1464{ 1567{
1465 /*
1466 * The driver doesn't have a per-target timeout setting. Set
1467 * this value globally. lpfc_nodev_tmo should be greater then 0.
1468 */
1469 if (timeout) 1568 if (timeout)
1470 lpfc_nodev_tmo = timeout; 1569 rport->dev_loss_tmo = timeout;
1471 else 1570 else
1472 lpfc_nodev_tmo = 1; 1571 rport->dev_loss_tmo = 1;
1473 rport->dev_loss_tmo = lpfc_nodev_tmo + 5;
1474} 1572}
1475 1573
1476 1574
@@ -1532,7 +1630,6 @@ struct fc_function_template lpfc_transport_functions = {
1532 .show_rport_maxframe_size = 1, 1630 .show_rport_maxframe_size = 1,
1533 .show_rport_supported_classes = 1, 1631 .show_rport_supported_classes = 1,
1534 1632
1535 .get_rport_dev_loss_tmo = lpfc_get_rport_loss_tmo,
1536 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo, 1633 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
1537 .show_rport_dev_loss_tmo = 1, 1634 .show_rport_dev_loss_tmo = 1,
1538 1635
@@ -1546,6 +1643,8 @@ struct fc_function_template lpfc_transport_functions = {
1546 .show_starget_port_name = 1, 1643 .show_starget_port_name = 1,
1547 1644
1548 .issue_fc_host_lip = lpfc_issue_lip, 1645 .issue_fc_host_lip = lpfc_issue_lip,
1646 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
1647 .terminate_rport_io = lpfc_terminate_rport_io,
1549}; 1648};
1550 1649
1551void 1650void
@@ -1561,13 +1660,13 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
1561 lpfc_ack0_init(phba, lpfc_ack0); 1660 lpfc_ack0_init(phba, lpfc_ack0);
1562 lpfc_topology_init(phba, lpfc_topology); 1661 lpfc_topology_init(phba, lpfc_topology);
1563 lpfc_scan_down_init(phba, lpfc_scan_down); 1662 lpfc_scan_down_init(phba, lpfc_scan_down);
1564 lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo);
1565 lpfc_link_speed_init(phba, lpfc_link_speed); 1663 lpfc_link_speed_init(phba, lpfc_link_speed);
1566 lpfc_fdmi_on_init(phba, lpfc_fdmi_on); 1664 lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
1567 lpfc_discovery_threads_init(phba, lpfc_discovery_threads); 1665 lpfc_discovery_threads_init(phba, lpfc_discovery_threads);
1568 lpfc_max_luns_init(phba, lpfc_max_luns); 1666 lpfc_max_luns_init(phba, lpfc_max_luns);
1569 lpfc_poll_tmo_init(phba, lpfc_poll_tmo); 1667 lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
1570 1668 lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo);
1669 lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo);
1571 phba->cfg_poll = lpfc_poll; 1670 phba->cfg_poll = lpfc_poll;
1572 1671
1573 /* 1672 /*