aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_attr.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c285
1 files changed, 256 insertions, 29 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index d384c16f4a87..9496e87c135e 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[])
@@ -548,6 +551,119 @@ static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
548 lpfc_board_mode_show, lpfc_board_mode_store); 551 lpfc_board_mode_show, lpfc_board_mode_store);
549static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); 552static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);
550 553
554
555static char *lpfc_soft_wwpn_key = "C99G71SL8032A";
556
557static ssize_t
558lpfc_soft_wwpn_enable_store(struct class_device *cdev, const char *buf,
559 size_t count)
560{
561 struct Scsi_Host *host = class_to_shost(cdev);
562 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
563 unsigned int cnt = count;
564
565 /*
566 * We're doing a simple sanity check for soft_wwpn setting.
567 * We require that the user write a specific key to enable
568 * the soft_wwpn attribute to be settable. Once the attribute
569 * is written, the enable key resets. If further updates are
570 * desired, the key must be written again to re-enable the
571 * attribute.
572 *
573 * The "key" is not secret - it is a hardcoded string shown
574 * here. The intent is to protect against the random user or
575 * application that is just writing attributes.
576 */
577
578 /* count may include a LF at end of string */
579 if (buf[cnt-1] == '\n')
580 cnt--;
581
582 if ((cnt != strlen(lpfc_soft_wwpn_key)) ||
583 (strncmp(buf, lpfc_soft_wwpn_key, strlen(lpfc_soft_wwpn_key)) != 0))
584 return -EINVAL;
585
586 phba->soft_wwpn_enable = 1;
587 return count;
588}
589static CLASS_DEVICE_ATTR(lpfc_soft_wwpn_enable, S_IWUSR, NULL,
590 lpfc_soft_wwpn_enable_store);
591
592static ssize_t
593lpfc_soft_wwpn_show(struct class_device *cdev, char *buf)
594{
595 struct Scsi_Host *host = class_to_shost(cdev);
596 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
597 return snprintf(buf, PAGE_SIZE, "0x%llx\n", phba->cfg_soft_wwpn);
598}
599
600
601static ssize_t
602lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count)
603{
604 struct Scsi_Host *host = class_to_shost(cdev);
605 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
606 struct completion online_compl;
607 int stat1=0, stat2=0;
608 unsigned int i, j, cnt=count;
609 u8 wwpn[8];
610
611 /* count may include a LF at end of string */
612 if (buf[cnt-1] == '\n')
613 cnt--;
614
615 if (!phba->soft_wwpn_enable || (cnt < 16) || (cnt > 18) ||
616 ((cnt == 17) && (*buf++ != 'x')) ||
617 ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x'))))
618 return -EINVAL;
619
620 phba->soft_wwpn_enable = 0;
621
622 memset(wwpn, 0, sizeof(wwpn));
623
624 /* Validate and store the new name */
625 for (i=0, j=0; i < 16; i++) {
626 if ((*buf >= 'a') && (*buf <= 'f'))
627 j = ((j << 4) | ((*buf++ -'a') + 10));
628 else if ((*buf >= 'A') && (*buf <= 'F'))
629 j = ((j << 4) | ((*buf++ -'A') + 10));
630 else if ((*buf >= '0') && (*buf <= '9'))
631 j = ((j << 4) | (*buf++ -'0'));
632 else
633 return -EINVAL;
634 if (i % 2) {
635 wwpn[i/2] = j & 0xff;
636 j = 0;
637 }
638 }
639 phba->cfg_soft_wwpn = wwn_to_u64(wwpn);
640 fc_host_port_name(host) = phba->cfg_soft_wwpn;
641
642 dev_printk(KERN_NOTICE, &phba->pcidev->dev,
643 "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no);
644
645 init_completion(&online_compl);
646 lpfc_workq_post_event(phba, &stat1, &online_compl, LPFC_EVT_OFFLINE);
647 wait_for_completion(&online_compl);
648 if (stat1)
649 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
650 "%d:0463 lpfc_soft_wwpn attribute set failed to reinit "
651 "adapter - %d\n", phba->brd_no, stat1);
652
653 init_completion(&online_compl);
654 lpfc_workq_post_event(phba, &stat2, &online_compl, LPFC_EVT_ONLINE);
655 wait_for_completion(&online_compl);
656 if (stat2)
657 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
658 "%d:0464 lpfc_soft_wwpn attribute set failed to reinit "
659 "adapter - %d\n", phba->brd_no, stat2);
660
661 return (stat1 || stat2) ? -EIO : count;
662}
663static CLASS_DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\
664 lpfc_soft_wwpn_show, lpfc_soft_wwpn_store);
665
666
551static int lpfc_poll = 0; 667static int lpfc_poll = 0;
552module_param(lpfc_poll, int, 0); 668module_param(lpfc_poll, int, 0);
553MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:" 669MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:"
@@ -559,6 +675,123 @@ static CLASS_DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR,
559 lpfc_poll_show, lpfc_poll_store); 675 lpfc_poll_show, lpfc_poll_store);
560 676
561/* 677/*
678# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
679# until the timer expires. Value range is [0,255]. Default value is 30.
680*/
681static int lpfc_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
682static int lpfc_devloss_tmo = LPFC_DEF_DEVLOSS_TMO;
683module_param(lpfc_nodev_tmo, int, 0);
684MODULE_PARM_DESC(lpfc_nodev_tmo,
685 "Seconds driver will hold I/O waiting "
686 "for a device to come back");
687static ssize_t
688lpfc_nodev_tmo_show(struct class_device *cdev, char *buf)
689{
690 struct Scsi_Host *host = class_to_shost(cdev);
691 struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
692 int val = 0;
693 val = phba->cfg_devloss_tmo;
694 return snprintf(buf, PAGE_SIZE, "%d\n",
695 phba->cfg_devloss_tmo);
696}
697
698static int
699lpfc_nodev_tmo_init(struct lpfc_hba *phba, int val)
700{
701 static int warned;
702 if (phba->cfg_devloss_tmo != LPFC_DEF_DEVLOSS_TMO) {
703 phba->cfg_nodev_tmo = phba->cfg_devloss_tmo;
704 if (!warned && val != LPFC_DEF_DEVLOSS_TMO) {
705 warned = 1;
706 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
707 "%d:0402 Ignoring nodev_tmo module "
708 "parameter because devloss_tmo is"
709 " set.\n",
710 phba->brd_no);
711 }
712 return 0;
713 }
714
715 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
716 phba->cfg_nodev_tmo = val;
717 phba->cfg_devloss_tmo = val;
718 return 0;
719 }
720 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
721 "%d:0400 lpfc_nodev_tmo attribute cannot be set to %d, "
722 "allowed range is [%d, %d]\n",
723 phba->brd_no, val,
724 LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
725 phba->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
726 return -EINVAL;
727}
728
729static int
730lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val)
731{
732 if (phba->dev_loss_tmo_changed ||
733 (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) {
734 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
735 "%d:0401 Ignoring change to nodev_tmo "
736 "because devloss_tmo is set.\n",
737 phba->brd_no);
738 return 0;
739 }
740
741 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
742 phba->cfg_nodev_tmo = val;
743 phba->cfg_devloss_tmo = val;
744 return 0;
745 }
746
747 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
748 "%d:0403 lpfc_nodev_tmo attribute cannot be set to %d, "
749 "allowed range is [%d, %d]\n",
750 phba->brd_no, val, LPFC_MIN_DEVLOSS_TMO,
751 LPFC_MAX_DEVLOSS_TMO);
752 return -EINVAL;
753}
754
755lpfc_param_store(nodev_tmo)
756
757static CLASS_DEVICE_ATTR(lpfc_nodev_tmo, S_IRUGO | S_IWUSR,
758 lpfc_nodev_tmo_show, lpfc_nodev_tmo_store);
759
760/*
761# lpfc_devloss_tmo: If set, it will hold all I/O errors on devices that
762# disappear until the timer expires. Value range is [0,255]. Default
763# value is 30.
764*/
765module_param(lpfc_devloss_tmo, int, 0);
766MODULE_PARM_DESC(lpfc_devloss_tmo,
767 "Seconds driver will hold I/O waiting "
768 "for a device to come back");
769lpfc_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO,
770 LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO)
771lpfc_param_show(devloss_tmo)
772static int
773lpfc_devloss_tmo_set(struct lpfc_hba *phba, int val)
774{
775 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
776 phba->cfg_nodev_tmo = val;
777 phba->cfg_devloss_tmo = val;
778 phba->dev_loss_tmo_changed = 1;
779 return 0;
780 }
781
782 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
783 "%d:0404 lpfc_devloss_tmo attribute cannot be set to"
784 " %d, allowed range is [%d, %d]\n",
785 phba->brd_no, val, LPFC_MIN_DEVLOSS_TMO,
786 LPFC_MAX_DEVLOSS_TMO);
787 return -EINVAL;
788}
789
790lpfc_param_store(devloss_tmo)
791static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR,
792 lpfc_devloss_tmo_show, lpfc_devloss_tmo_store);
793
794/*
562# lpfc_log_verbose: Only turn this flag on if you are willing to risk being 795# lpfc_log_verbose: Only turn this flag on if you are willing to risk being
563# deluged with LOTS of information. 796# deluged with LOTS of information.
564# You can set a bit mask to record specific types of verbose messages: 797# You can set a bit mask to record specific types of verbose messages:
@@ -617,14 +850,6 @@ LPFC_ATTR_R(scan_down, 1, 0, 1,
617 "Start scanning for devices from highest ALPA to lowest"); 850 "Start scanning for devices from highest ALPA to lowest");
618 851
619/* 852/*
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 853# lpfc_topology: link topology for init link
629# 0x0 = attempt loop mode then point-to-point 854# 0x0 = attempt loop mode then point-to-point
630# 0x01 = internal loopback mode 855# 0x01 = internal loopback mode
@@ -720,6 +945,7 @@ LPFC_ATTR_R(max_luns, 255, 0, 65535,
720LPFC_ATTR_RW(poll_tmo, 10, 1, 255, 945LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
721 "Milliseconds driver will wait between polling FCP ring"); 946 "Milliseconds driver will wait between polling FCP ring");
722 947
948
723struct class_device_attribute *lpfc_host_attrs[] = { 949struct class_device_attribute *lpfc_host_attrs[] = {
724 &class_device_attr_info, 950 &class_device_attr_info,
725 &class_device_attr_serialnum, 951 &class_device_attr_serialnum,
@@ -737,6 +963,7 @@ struct class_device_attribute *lpfc_host_attrs[] = {
737 &class_device_attr_lpfc_lun_queue_depth, 963 &class_device_attr_lpfc_lun_queue_depth,
738 &class_device_attr_lpfc_hba_queue_depth, 964 &class_device_attr_lpfc_hba_queue_depth,
739 &class_device_attr_lpfc_nodev_tmo, 965 &class_device_attr_lpfc_nodev_tmo,
966 &class_device_attr_lpfc_devloss_tmo,
740 &class_device_attr_lpfc_fcp_class, 967 &class_device_attr_lpfc_fcp_class,
741 &class_device_attr_lpfc_use_adisc, 968 &class_device_attr_lpfc_use_adisc,
742 &class_device_attr_lpfc_ack0, 969 &class_device_attr_lpfc_ack0,
@@ -754,6 +981,8 @@ struct class_device_attribute *lpfc_host_attrs[] = {
754 &class_device_attr_issue_reset, 981 &class_device_attr_issue_reset,
755 &class_device_attr_lpfc_poll, 982 &class_device_attr_lpfc_poll,
756 &class_device_attr_lpfc_poll_tmo, 983 &class_device_attr_lpfc_poll_tmo,
984 &class_device_attr_lpfc_soft_wwpn,
985 &class_device_attr_lpfc_soft_wwpn_enable,
757 NULL, 986 NULL,
758}; 987};
759 988
@@ -1204,6 +1433,15 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost)
1204 fc_host_fabric_name(shost) = node_name; 1433 fc_host_fabric_name(shost) = node_name;
1205} 1434}
1206 1435
1436static void
1437lpfc_get_host_symbolic_name (struct Scsi_Host *shost)
1438{
1439 struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata;
1440
1441 spin_lock_irq(shost->host_lock);
1442 lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(shost));
1443 spin_unlock_irq(shost->host_lock);
1444}
1207 1445
1208static struct fc_host_statistics * 1446static struct fc_host_statistics *
1209lpfc_get_stats(struct Scsi_Host *shost) 1447lpfc_get_stats(struct Scsi_Host *shost)
@@ -1441,27 +1679,12 @@ lpfc_get_starget_port_name(struct scsi_target *starget)
1441} 1679}
1442 1680
1443static void 1681static void
1444lpfc_get_rport_loss_tmo(struct fc_rport *rport)
1445{
1446 /*
1447 * Return the driver's global value for device loss timeout plus
1448 * five seconds to allow the driver's nodev timer to run.
1449 */
1450 rport->dev_loss_tmo = lpfc_nodev_tmo + 5;
1451}
1452
1453static void
1454lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) 1682lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
1455{ 1683{
1456 /*
1457 * The driver doesn't have a per-target timeout setting. Set
1458 * this value globally. lpfc_nodev_tmo should be greater then 0.
1459 */
1460 if (timeout) 1684 if (timeout)
1461 lpfc_nodev_tmo = timeout; 1685 rport->dev_loss_tmo = timeout;
1462 else 1686 else
1463 lpfc_nodev_tmo = 1; 1687 rport->dev_loss_tmo = 1;
1464 rport->dev_loss_tmo = lpfc_nodev_tmo + 5;
1465} 1688}
1466 1689
1467 1690
@@ -1486,7 +1709,6 @@ struct fc_function_template lpfc_transport_functions = {
1486 .show_host_port_name = 1, 1709 .show_host_port_name = 1,
1487 .show_host_supported_classes = 1, 1710 .show_host_supported_classes = 1,
1488 .show_host_supported_fc4s = 1, 1711 .show_host_supported_fc4s = 1,
1489 .show_host_symbolic_name = 1,
1490 .show_host_supported_speeds = 1, 1712 .show_host_supported_speeds = 1,
1491 .show_host_maxframe_size = 1, 1713 .show_host_maxframe_size = 1,
1492 1714
@@ -1509,6 +1731,9 @@ struct fc_function_template lpfc_transport_functions = {
1509 .get_host_fabric_name = lpfc_get_host_fabric_name, 1731 .get_host_fabric_name = lpfc_get_host_fabric_name,
1510 .show_host_fabric_name = 1, 1732 .show_host_fabric_name = 1,
1511 1733
1734 .get_host_symbolic_name = lpfc_get_host_symbolic_name,
1735 .show_host_symbolic_name = 1,
1736
1512 /* 1737 /*
1513 * The LPFC driver treats linkdown handling as target loss events 1738 * The LPFC driver treats linkdown handling as target loss events
1514 * so there are no sysfs handlers for link_down_tmo. 1739 * so there are no sysfs handlers for link_down_tmo.
@@ -1521,7 +1746,6 @@ struct fc_function_template lpfc_transport_functions = {
1521 .show_rport_maxframe_size = 1, 1746 .show_rport_maxframe_size = 1,
1522 .show_rport_supported_classes = 1, 1747 .show_rport_supported_classes = 1,
1523 1748
1524 .get_rport_dev_loss_tmo = lpfc_get_rport_loss_tmo,
1525 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo, 1749 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
1526 .show_rport_dev_loss_tmo = 1, 1750 .show_rport_dev_loss_tmo = 1,
1527 1751
@@ -1535,6 +1759,8 @@ struct fc_function_template lpfc_transport_functions = {
1535 .show_starget_port_name = 1, 1759 .show_starget_port_name = 1,
1536 1760
1537 .issue_fc_host_lip = lpfc_issue_lip, 1761 .issue_fc_host_lip = lpfc_issue_lip,
1762 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
1763 .terminate_rport_io = lpfc_terminate_rport_io,
1538}; 1764};
1539 1765
1540void 1766void
@@ -1550,14 +1776,15 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
1550 lpfc_ack0_init(phba, lpfc_ack0); 1776 lpfc_ack0_init(phba, lpfc_ack0);
1551 lpfc_topology_init(phba, lpfc_topology); 1777 lpfc_topology_init(phba, lpfc_topology);
1552 lpfc_scan_down_init(phba, lpfc_scan_down); 1778 lpfc_scan_down_init(phba, lpfc_scan_down);
1553 lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo);
1554 lpfc_link_speed_init(phba, lpfc_link_speed); 1779 lpfc_link_speed_init(phba, lpfc_link_speed);
1555 lpfc_fdmi_on_init(phba, lpfc_fdmi_on); 1780 lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
1556 lpfc_discovery_threads_init(phba, lpfc_discovery_threads); 1781 lpfc_discovery_threads_init(phba, lpfc_discovery_threads);
1557 lpfc_max_luns_init(phba, lpfc_max_luns); 1782 lpfc_max_luns_init(phba, lpfc_max_luns);
1558 lpfc_poll_tmo_init(phba, lpfc_poll_tmo); 1783 lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
1559 1784 lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo);
1785 lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo);
1560 phba->cfg_poll = lpfc_poll; 1786 phba->cfg_poll = lpfc_poll;
1787 phba->cfg_soft_wwpn = 0L;
1561 1788
1562 /* 1789 /*
1563 * The total number of segments is the configuration value plus 2 1790 * The total number of segments is the configuration value plus 2