diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_attr.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 118 |
1 files changed, 106 insertions, 12 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 2a4e02e7a392..f247e786af99 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -552,10 +552,10 @@ static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, | |||
552 | static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); | 552 | static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); |
553 | 553 | ||
554 | 554 | ||
555 | static char *lpfc_soft_wwpn_key = "C99G71SL8032A"; | 555 | static char *lpfc_soft_wwn_key = "C99G71SL8032A"; |
556 | 556 | ||
557 | static ssize_t | 557 | static ssize_t |
558 | lpfc_soft_wwpn_enable_store(struct class_device *cdev, const char *buf, | 558 | lpfc_soft_wwn_enable_store(struct class_device *cdev, const char *buf, |
559 | size_t count) | 559 | size_t count) |
560 | { | 560 | { |
561 | struct Scsi_Host *host = class_to_shost(cdev); | 561 | struct Scsi_Host *host = class_to_shost(cdev); |
@@ -579,15 +579,15 @@ lpfc_soft_wwpn_enable_store(struct class_device *cdev, const char *buf, | |||
579 | if (buf[cnt-1] == '\n') | 579 | if (buf[cnt-1] == '\n') |
580 | cnt--; | 580 | cnt--; |
581 | 581 | ||
582 | if ((cnt != strlen(lpfc_soft_wwpn_key)) || | 582 | if ((cnt != strlen(lpfc_soft_wwn_key)) || |
583 | (strncmp(buf, lpfc_soft_wwpn_key, strlen(lpfc_soft_wwpn_key)) != 0)) | 583 | (strncmp(buf, lpfc_soft_wwn_key, strlen(lpfc_soft_wwn_key)) != 0)) |
584 | return -EINVAL; | 584 | return -EINVAL; |
585 | 585 | ||
586 | phba->soft_wwpn_enable = 1; | 586 | phba->soft_wwn_enable = 1; |
587 | return count; | 587 | return count; |
588 | } | 588 | } |
589 | static CLASS_DEVICE_ATTR(lpfc_soft_wwpn_enable, S_IWUSR, NULL, | 589 | static CLASS_DEVICE_ATTR(lpfc_soft_wwn_enable, S_IWUSR, NULL, |
590 | lpfc_soft_wwpn_enable_store); | 590 | lpfc_soft_wwn_enable_store); |
591 | 591 | ||
592 | static ssize_t | 592 | static ssize_t |
593 | lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) | 593 | lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) |
@@ -613,12 +613,12 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) | |||
613 | if (buf[cnt-1] == '\n') | 613 | if (buf[cnt-1] == '\n') |
614 | cnt--; | 614 | cnt--; |
615 | 615 | ||
616 | if (!phba->soft_wwpn_enable || (cnt < 16) || (cnt > 18) || | 616 | if (!phba->soft_wwn_enable || (cnt < 16) || (cnt > 18) || |
617 | ((cnt == 17) && (*buf++ != 'x')) || | 617 | ((cnt == 17) && (*buf++ != 'x')) || |
618 | ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x')))) | 618 | ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x')))) |
619 | return -EINVAL; | 619 | return -EINVAL; |
620 | 620 | ||
621 | phba->soft_wwpn_enable = 0; | 621 | phba->soft_wwn_enable = 0; |
622 | 622 | ||
623 | memset(wwpn, 0, sizeof(wwpn)); | 623 | memset(wwpn, 0, sizeof(wwpn)); |
624 | 624 | ||
@@ -639,6 +639,8 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) | |||
639 | } | 639 | } |
640 | phba->cfg_soft_wwpn = wwn_to_u64(wwpn); | 640 | phba->cfg_soft_wwpn = wwn_to_u64(wwpn); |
641 | fc_host_port_name(host) = phba->cfg_soft_wwpn; | 641 | fc_host_port_name(host) = phba->cfg_soft_wwpn; |
642 | if (phba->cfg_soft_wwnn) | ||
643 | fc_host_node_name(host) = phba->cfg_soft_wwnn; | ||
642 | 644 | ||
643 | dev_printk(KERN_NOTICE, &phba->pcidev->dev, | 645 | dev_printk(KERN_NOTICE, &phba->pcidev->dev, |
644 | "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no); | 646 | "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no); |
@@ -664,6 +666,66 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) | |||
664 | static CLASS_DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\ | 666 | static CLASS_DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\ |
665 | lpfc_soft_wwpn_show, lpfc_soft_wwpn_store); | 667 | lpfc_soft_wwpn_show, lpfc_soft_wwpn_store); |
666 | 668 | ||
669 | static ssize_t | ||
670 | lpfc_soft_wwnn_show(struct class_device *cdev, char *buf) | ||
671 | { | ||
672 | struct Scsi_Host *host = class_to_shost(cdev); | ||
673 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | ||
674 | return snprintf(buf, PAGE_SIZE, "0x%llx\n", | ||
675 | (unsigned long long)phba->cfg_soft_wwnn); | ||
676 | } | ||
677 | |||
678 | |||
679 | static ssize_t | ||
680 | lpfc_soft_wwnn_store(struct class_device *cdev, const char *buf, size_t count) | ||
681 | { | ||
682 | struct Scsi_Host *host = class_to_shost(cdev); | ||
683 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | ||
684 | unsigned int i, j, cnt=count; | ||
685 | u8 wwnn[8]; | ||
686 | |||
687 | /* count may include a LF at end of string */ | ||
688 | if (buf[cnt-1] == '\n') | ||
689 | cnt--; | ||
690 | |||
691 | if (!phba->soft_wwn_enable || (cnt < 16) || (cnt > 18) || | ||
692 | ((cnt == 17) && (*buf++ != 'x')) || | ||
693 | ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x')))) | ||
694 | return -EINVAL; | ||
695 | |||
696 | /* | ||
697 | * Allow wwnn to be set many times, as long as the enable is set. | ||
698 | * However, once the wwpn is set, everything locks. | ||
699 | */ | ||
700 | |||
701 | memset(wwnn, 0, sizeof(wwnn)); | ||
702 | |||
703 | /* Validate and store the new name */ | ||
704 | for (i=0, j=0; i < 16; i++) { | ||
705 | if ((*buf >= 'a') && (*buf <= 'f')) | ||
706 | j = ((j << 4) | ((*buf++ -'a') + 10)); | ||
707 | else if ((*buf >= 'A') && (*buf <= 'F')) | ||
708 | j = ((j << 4) | ((*buf++ -'A') + 10)); | ||
709 | else if ((*buf >= '0') && (*buf <= '9')) | ||
710 | j = ((j << 4) | (*buf++ -'0')); | ||
711 | else | ||
712 | return -EINVAL; | ||
713 | if (i % 2) { | ||
714 | wwnn[i/2] = j & 0xff; | ||
715 | j = 0; | ||
716 | } | ||
717 | } | ||
718 | phba->cfg_soft_wwnn = wwn_to_u64(wwnn); | ||
719 | |||
720 | dev_printk(KERN_NOTICE, &phba->pcidev->dev, | ||
721 | "lpfc%d: soft_wwnn set. Value will take effect upon " | ||
722 | "setting of the soft_wwpn\n", phba->brd_no); | ||
723 | |||
724 | return count; | ||
725 | } | ||
726 | static CLASS_DEVICE_ATTR(lpfc_soft_wwnn, S_IRUGO | S_IWUSR,\ | ||
727 | lpfc_soft_wwnn_show, lpfc_soft_wwnn_store); | ||
728 | |||
667 | 729 | ||
668 | static int lpfc_poll = 0; | 730 | static int lpfc_poll = 0; |
669 | module_param(lpfc_poll, int, 0); | 731 | module_param(lpfc_poll, int, 0); |
@@ -802,12 +864,11 @@ static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR, | |||
802 | # LOG_MBOX 0x4 Mailbox events | 864 | # LOG_MBOX 0x4 Mailbox events |
803 | # LOG_INIT 0x8 Initialization events | 865 | # LOG_INIT 0x8 Initialization events |
804 | # LOG_LINK_EVENT 0x10 Link events | 866 | # LOG_LINK_EVENT 0x10 Link events |
805 | # LOG_IP 0x20 IP traffic history | ||
806 | # LOG_FCP 0x40 FCP traffic history | 867 | # LOG_FCP 0x40 FCP traffic history |
807 | # LOG_NODE 0x80 Node table events | 868 | # LOG_NODE 0x80 Node table events |
808 | # LOG_MISC 0x400 Miscellaneous events | 869 | # LOG_MISC 0x400 Miscellaneous events |
809 | # LOG_SLI 0x800 SLI events | 870 | # LOG_SLI 0x800 SLI events |
810 | # LOG_CHK_COND 0x1000 FCP Check condition flag | 871 | # LOG_FCP_ERROR 0x1000 Only log FCP errors |
811 | # LOG_LIBDFC 0x2000 LIBDFC events | 872 | # LOG_LIBDFC 0x2000 LIBDFC events |
812 | # LOG_ALL_MSG 0xffff LOG all messages | 873 | # LOG_ALL_MSG 0xffff LOG all messages |
813 | */ | 874 | */ |
@@ -916,6 +977,22 @@ LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary " | |||
916 | "SLI rings to spread IOCB entries across"); | 977 | "SLI rings to spread IOCB entries across"); |
917 | 978 | ||
918 | /* | 979 | /* |
980 | # lpfc_multi_ring_rctl: If lpfc_multi_ring_support is enabled, this | ||
981 | # identifies what rctl value to configure the additional ring for. | ||
982 | # Value range is [1,0xff]. Default value is 4 (Unsolicated Data). | ||
983 | */ | ||
984 | LPFC_ATTR_R(multi_ring_rctl, FC_UNSOL_DATA, 1, | ||
985 | 255, "Identifies RCTL for additional ring configuration"); | ||
986 | |||
987 | /* | ||
988 | # lpfc_multi_ring_type: If lpfc_multi_ring_support is enabled, this | ||
989 | # identifies what type value to configure the additional ring for. | ||
990 | # Value range is [1,0xff]. Default value is 5 (LLC/SNAP). | ||
991 | */ | ||
992 | LPFC_ATTR_R(multi_ring_type, FC_LLC_SNAP, 1, | ||
993 | 255, "Identifies TYPE for additional ring configuration"); | ||
994 | |||
995 | /* | ||
919 | # lpfc_fdmi_on: controls FDMI support. | 996 | # lpfc_fdmi_on: controls FDMI support. |
920 | # 0 = no FDMI support | 997 | # 0 = no FDMI support |
921 | # 1 = support FDMI without attribute of hostname | 998 | # 1 = support FDMI without attribute of hostname |
@@ -946,6 +1023,15 @@ LPFC_ATTR_R(max_luns, 255, 0, 65535, | |||
946 | LPFC_ATTR_RW(poll_tmo, 10, 1, 255, | 1023 | LPFC_ATTR_RW(poll_tmo, 10, 1, 255, |
947 | "Milliseconds driver will wait between polling FCP ring"); | 1024 | "Milliseconds driver will wait between polling FCP ring"); |
948 | 1025 | ||
1026 | /* | ||
1027 | # lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that | ||
1028 | # support this feature | ||
1029 | # 0 = MSI disabled (default) | ||
1030 | # 1 = MSI enabled | ||
1031 | # Value range is [0,1]. Default value is 0. | ||
1032 | */ | ||
1033 | LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible"); | ||
1034 | |||
949 | 1035 | ||
950 | struct class_device_attribute *lpfc_host_attrs[] = { | 1036 | struct class_device_attribute *lpfc_host_attrs[] = { |
951 | &class_device_attr_info, | 1037 | &class_device_attr_info, |
@@ -974,6 +1060,8 @@ struct class_device_attribute *lpfc_host_attrs[] = { | |||
974 | &class_device_attr_lpfc_cr_delay, | 1060 | &class_device_attr_lpfc_cr_delay, |
975 | &class_device_attr_lpfc_cr_count, | 1061 | &class_device_attr_lpfc_cr_count, |
976 | &class_device_attr_lpfc_multi_ring_support, | 1062 | &class_device_attr_lpfc_multi_ring_support, |
1063 | &class_device_attr_lpfc_multi_ring_rctl, | ||
1064 | &class_device_attr_lpfc_multi_ring_type, | ||
977 | &class_device_attr_lpfc_fdmi_on, | 1065 | &class_device_attr_lpfc_fdmi_on, |
978 | &class_device_attr_lpfc_max_luns, | 1066 | &class_device_attr_lpfc_max_luns, |
979 | &class_device_attr_nport_evt_cnt, | 1067 | &class_device_attr_nport_evt_cnt, |
@@ -982,8 +1070,10 @@ struct class_device_attribute *lpfc_host_attrs[] = { | |||
982 | &class_device_attr_issue_reset, | 1070 | &class_device_attr_issue_reset, |
983 | &class_device_attr_lpfc_poll, | 1071 | &class_device_attr_lpfc_poll, |
984 | &class_device_attr_lpfc_poll_tmo, | 1072 | &class_device_attr_lpfc_poll_tmo, |
1073 | &class_device_attr_lpfc_use_msi, | ||
1074 | &class_device_attr_lpfc_soft_wwnn, | ||
985 | &class_device_attr_lpfc_soft_wwpn, | 1075 | &class_device_attr_lpfc_soft_wwpn, |
986 | &class_device_attr_lpfc_soft_wwpn_enable, | 1076 | &class_device_attr_lpfc_soft_wwn_enable, |
987 | NULL, | 1077 | NULL, |
988 | }; | 1078 | }; |
989 | 1079 | ||
@@ -1771,6 +1861,8 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
1771 | lpfc_cr_delay_init(phba, lpfc_cr_delay); | 1861 | lpfc_cr_delay_init(phba, lpfc_cr_delay); |
1772 | lpfc_cr_count_init(phba, lpfc_cr_count); | 1862 | lpfc_cr_count_init(phba, lpfc_cr_count); |
1773 | lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support); | 1863 | lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support); |
1864 | lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl); | ||
1865 | lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type); | ||
1774 | lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth); | 1866 | lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth); |
1775 | lpfc_fcp_class_init(phba, lpfc_fcp_class); | 1867 | lpfc_fcp_class_init(phba, lpfc_fcp_class); |
1776 | lpfc_use_adisc_init(phba, lpfc_use_adisc); | 1868 | lpfc_use_adisc_init(phba, lpfc_use_adisc); |
@@ -1782,9 +1874,11 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
1782 | lpfc_discovery_threads_init(phba, lpfc_discovery_threads); | 1874 | lpfc_discovery_threads_init(phba, lpfc_discovery_threads); |
1783 | lpfc_max_luns_init(phba, lpfc_max_luns); | 1875 | lpfc_max_luns_init(phba, lpfc_max_luns); |
1784 | lpfc_poll_tmo_init(phba, lpfc_poll_tmo); | 1876 | lpfc_poll_tmo_init(phba, lpfc_poll_tmo); |
1877 | lpfc_use_msi_init(phba, lpfc_use_msi); | ||
1785 | lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo); | 1878 | lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo); |
1786 | lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo); | 1879 | lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo); |
1787 | phba->cfg_poll = lpfc_poll; | 1880 | phba->cfg_poll = lpfc_poll; |
1881 | phba->cfg_soft_wwnn = 0L; | ||
1788 | phba->cfg_soft_wwpn = 0L; | 1882 | phba->cfg_soft_wwpn = 0L; |
1789 | 1883 | ||
1790 | /* | 1884 | /* |