diff options
author | James Smart <james.smart@emulex.com> | 2011-12-13 13:20:45 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-12-15 01:57:43 -0500 |
commit | 026abb87a5586c838a47aca7198d78e356b6351e (patch) | |
tree | 39c99398f8aab41fd7623f1d9a79197565a8f2e2 /drivers/scsi | |
parent | 2cb6fc8c014b9b00c4487a79b8f6ed0da4121f45 (diff) |
[SCSI] lpfc 8.3.28: Miscellaneous fixes in sysfs and mgmt interfaces
Miscellaneous fixes in sysfs and mgmt interfaces:
- Added SLI4 INTF_TYPE and SLI_FAMILY as sub-field to the fwrev sysfs
attribute (CR 124103)
- Added a sysfs attribute "protocol" to report SLI4 port link protocol
type (CR 124102)
- Increment mix-and-match minor number by 1 for added "protocol" sysfs
attribute. (124102)
- Move the link speed check into the generic sli3/sli4 code
path. (CR 124185, 124122)
- Deleted check for inExtWLen (CR 122523)
- Add the word "offline" to message 2889 (CR 124385)
- Conditionalize the firmware upgrade/downgrade so that it is only
attempted for SLI4 type 2 boards (CR 124406)
- Return an error if the mbox sysfs is called. (CR 124210)
- When port_state is less than LPFC_VPORT_READY, report
FC_PORTSTATE_BYPASSED (CR 120018)
- Added driver support for performing persistent linkdown based on
configure region 23 (CR 124534)
- Added restore state and error log when sysfs board_mode attribute
access failed (CR 124158)
- Added support for SLI4_CONFIG non-embedded COMN_GET_CNTL_ADDL_ATTR
pass-through (CR 124466)
- Rejecting un-supported multi-buffer mailbox commands (CR 124771)
- Byte swap the extended data request and response data for extended
mailbox data (CR 125081)
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 14 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 413 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_bsg.c | 74 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_bsg.h | 3 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 84 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mbox.c | 13 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 149 |
9 files changed, 356 insertions, 398 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index bb4c8e0584e2..825f9307417a 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -247,18 +247,6 @@ struct lpfc_stats { | |||
247 | uint32_t fcpLocalErr; | 247 | uint32_t fcpLocalErr; |
248 | }; | 248 | }; |
249 | 249 | ||
250 | enum sysfs_mbox_state { | ||
251 | SMBOX_IDLE, | ||
252 | SMBOX_WRITING, | ||
253 | SMBOX_READING | ||
254 | }; | ||
255 | |||
256 | struct lpfc_sysfs_mbox { | ||
257 | enum sysfs_mbox_state state; | ||
258 | size_t offset; | ||
259 | struct lpfcMboxq * mbox; | ||
260 | }; | ||
261 | |||
262 | struct lpfc_hba; | 250 | struct lpfc_hba; |
263 | 251 | ||
264 | 252 | ||
@@ -783,8 +771,6 @@ struct lpfc_hba { | |||
783 | uint64_t bg_apptag_err_cnt; | 771 | uint64_t bg_apptag_err_cnt; |
784 | uint64_t bg_reftag_err_cnt; | 772 | uint64_t bg_reftag_err_cnt; |
785 | 773 | ||
786 | struct lpfc_sysfs_mbox sysfs_mbox; | ||
787 | |||
788 | /* fastpath list. */ | 774 | /* fastpath list. */ |
789 | spinlock_t scsi_buf_list_lock; | 775 | spinlock_t scsi_buf_list_lock; |
790 | struct list_head lpfc_scsi_buf_list; | 776 | struct list_head lpfc_scsi_buf_list; |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index d0ebaeb7ef60..7bf492e156d9 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -351,10 +351,23 @@ lpfc_fwrev_show(struct device *dev, struct device_attribute *attr, | |||
351 | struct Scsi_Host *shost = class_to_shost(dev); | 351 | struct Scsi_Host *shost = class_to_shost(dev); |
352 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 352 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
353 | struct lpfc_hba *phba = vport->phba; | 353 | struct lpfc_hba *phba = vport->phba; |
354 | uint32_t if_type; | ||
355 | uint8_t sli_family; | ||
354 | char fwrev[32]; | 356 | char fwrev[32]; |
357 | int len; | ||
355 | 358 | ||
356 | lpfc_decode_firmware_rev(phba, fwrev, 1); | 359 | lpfc_decode_firmware_rev(phba, fwrev, 1); |
357 | return snprintf(buf, PAGE_SIZE, "%s, sli-%d\n", fwrev, phba->sli_rev); | 360 | if_type = phba->sli4_hba.pc_sli4_params.if_type; |
361 | sli_family = phba->sli4_hba.pc_sli4_params.sli_family; | ||
362 | |||
363 | if (phba->sli_rev < LPFC_SLI_REV4) | ||
364 | len = snprintf(buf, PAGE_SIZE, "%s, sli-%d\n", | ||
365 | fwrev, phba->sli_rev); | ||
366 | else | ||
367 | len = snprintf(buf, PAGE_SIZE, "%s, sli-%d:%d:%x\n", | ||
368 | fwrev, phba->sli_rev, if_type, sli_family); | ||
369 | |||
370 | return len; | ||
358 | } | 371 | } |
359 | 372 | ||
360 | /** | 373 | /** |
@@ -488,6 +501,34 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr, | |||
488 | } | 501 | } |
489 | 502 | ||
490 | /** | 503 | /** |
504 | * lpfc_sli4_protocol_show - Return the fip mode of the HBA | ||
505 | * @dev: class unused variable. | ||
506 | * @attr: device attribute, not used. | ||
507 | * @buf: on return contains the module description text. | ||
508 | * | ||
509 | * Returns: size of formatted string. | ||
510 | **/ | ||
511 | static ssize_t | ||
512 | lpfc_sli4_protocol_show(struct device *dev, struct device_attribute *attr, | ||
513 | char *buf) | ||
514 | { | ||
515 | struct Scsi_Host *shost = class_to_shost(dev); | ||
516 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
517 | struct lpfc_hba *phba = vport->phba; | ||
518 | |||
519 | if (phba->sli_rev < LPFC_SLI_REV4) | ||
520 | return snprintf(buf, PAGE_SIZE, "fc\n"); | ||
521 | |||
522 | if (phba->sli4_hba.lnk_info.lnk_dv == LPFC_LNK_DAT_VAL) { | ||
523 | if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_GE) | ||
524 | return snprintf(buf, PAGE_SIZE, "fcoe\n"); | ||
525 | if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) | ||
526 | return snprintf(buf, PAGE_SIZE, "fc\n"); | ||
527 | } | ||
528 | return snprintf(buf, PAGE_SIZE, "unknown\n"); | ||
529 | } | ||
530 | |||
531 | /** | ||
491 | * lpfc_link_state_store - Transition the link_state on an HBA port | 532 | * lpfc_link_state_store - Transition the link_state on an HBA port |
492 | * @dev: class device that is converted into a Scsi_host. | 533 | * @dev: class device that is converted into a Scsi_host. |
493 | * @attr: device attribute, not used. | 534 | * @attr: device attribute, not used. |
@@ -773,7 +814,12 @@ lpfc_issue_reset(struct device *dev, struct device_attribute *attr, | |||
773 | * the readyness after performing a firmware reset. | 814 | * the readyness after performing a firmware reset. |
774 | * | 815 | * |
775 | * Returns: | 816 | * Returns: |
776 | * zero for success | 817 | * zero for success, -EPERM when port does not have privilage to perform the |
818 | * reset, -EIO when port timeout from recovering from the reset. | ||
819 | * | ||
820 | * Note: | ||
821 | * As the caller will interpret the return code by value, be careful in making | ||
822 | * change or addition to return codes. | ||
777 | **/ | 823 | **/ |
778 | int | 824 | int |
779 | lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba) | 825 | lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba) |
@@ -826,9 +872,11 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) | |||
826 | { | 872 | { |
827 | struct completion online_compl; | 873 | struct completion online_compl; |
828 | struct pci_dev *pdev = phba->pcidev; | 874 | struct pci_dev *pdev = phba->pcidev; |
875 | uint32_t before_fc_flag; | ||
876 | uint32_t sriov_nr_virtfn; | ||
829 | uint32_t reg_val; | 877 | uint32_t reg_val; |
830 | int status = 0; | 878 | int status = 0, rc = 0; |
831 | int rc; | 879 | int job_posted = 1, sriov_err; |
832 | 880 | ||
833 | if (!phba->cfg_enable_hba_reset) | 881 | if (!phba->cfg_enable_hba_reset) |
834 | return -EACCES; | 882 | return -EACCES; |
@@ -838,6 +886,10 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) | |||
838 | LPFC_SLI_INTF_IF_TYPE_2)) | 886 | LPFC_SLI_INTF_IF_TYPE_2)) |
839 | return -EPERM; | 887 | return -EPERM; |
840 | 888 | ||
889 | /* Keep state if we need to restore back */ | ||
890 | before_fc_flag = phba->pport->fc_flag; | ||
891 | sriov_nr_virtfn = phba->cfg_sriov_nr_virtfn; | ||
892 | |||
841 | /* Disable SR-IOV virtual functions if enabled */ | 893 | /* Disable SR-IOV virtual functions if enabled */ |
842 | if (phba->cfg_sriov_nr_virtfn) { | 894 | if (phba->cfg_sriov_nr_virtfn) { |
843 | pci_disable_sriov(pdev); | 895 | pci_disable_sriov(pdev); |
@@ -869,21 +921,44 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) | |||
869 | /* delay driver action following IF_TYPE_2 reset */ | 921 | /* delay driver action following IF_TYPE_2 reset */ |
870 | rc = lpfc_sli4_pdev_status_reg_wait(phba); | 922 | rc = lpfc_sli4_pdev_status_reg_wait(phba); |
871 | 923 | ||
872 | if (rc) | 924 | if (rc == -EPERM) { |
925 | /* no privilage for reset, restore if needed */ | ||
926 | if (before_fc_flag & FC_OFFLINE_MODE) | ||
927 | goto out; | ||
928 | } else if (rc == -EIO) { | ||
929 | /* reset failed, there is nothing more we can do */ | ||
873 | return rc; | 930 | return rc; |
931 | } | ||
932 | |||
933 | /* keep the original port state */ | ||
934 | if (before_fc_flag & FC_OFFLINE_MODE) | ||
935 | goto out; | ||
874 | 936 | ||
875 | init_completion(&online_compl); | 937 | init_completion(&online_compl); |
876 | rc = lpfc_workq_post_event(phba, &status, &online_compl, | 938 | job_posted = lpfc_workq_post_event(phba, &status, &online_compl, |
877 | LPFC_EVT_ONLINE); | 939 | LPFC_EVT_ONLINE); |
878 | if (rc == 0) | 940 | if (!job_posted) |
879 | return -ENOMEM; | 941 | goto out; |
880 | 942 | ||
881 | wait_for_completion(&online_compl); | 943 | wait_for_completion(&online_compl); |
882 | 944 | ||
883 | if (status != 0) | 945 | out: |
884 | return -EIO; | 946 | /* in any case, restore the virtual functions enabled as before */ |
947 | if (sriov_nr_virtfn) { | ||
948 | sriov_err = | ||
949 | lpfc_sli_probe_sriov_nr_virtfn(phba, sriov_nr_virtfn); | ||
950 | if (!sriov_err) | ||
951 | phba->cfg_sriov_nr_virtfn = sriov_nr_virtfn; | ||
952 | } | ||
885 | 953 | ||
886 | return 0; | 954 | /* return proper error code */ |
955 | if (!rc) { | ||
956 | if (!job_posted) | ||
957 | rc = -ENOMEM; | ||
958 | else if (status) | ||
959 | rc = -EIO; | ||
960 | } | ||
961 | return rc; | ||
887 | } | 962 | } |
888 | 963 | ||
889 | /** | 964 | /** |
@@ -955,33 +1030,38 @@ lpfc_board_mode_store(struct device *dev, struct device_attribute *attr, | |||
955 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 1030 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
956 | struct lpfc_hba *phba = vport->phba; | 1031 | struct lpfc_hba *phba = vport->phba; |
957 | struct completion online_compl; | 1032 | struct completion online_compl; |
958 | int status=0; | 1033 | char *board_mode_str = NULL; |
1034 | int status = 0; | ||
959 | int rc; | 1035 | int rc; |
960 | 1036 | ||
961 | if (!phba->cfg_enable_hba_reset) | 1037 | if (!phba->cfg_enable_hba_reset) { |
962 | return -EACCES; | 1038 | status = -EACCES; |
1039 | goto board_mode_out; | ||
1040 | } | ||
963 | 1041 | ||
964 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | 1042 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, |
965 | "3050 lpfc_board_mode set to %s\n", buf); | 1043 | "3050 lpfc_board_mode set to %s\n", buf); |
966 | 1044 | ||
967 | init_completion(&online_compl); | 1045 | init_completion(&online_compl); |
968 | 1046 | ||
969 | if(strncmp(buf, "online", sizeof("online") - 1) == 0) { | 1047 | if(strncmp(buf, "online", sizeof("online") - 1) == 0) { |
970 | rc = lpfc_workq_post_event(phba, &status, &online_compl, | 1048 | rc = lpfc_workq_post_event(phba, &status, &online_compl, |
971 | LPFC_EVT_ONLINE); | 1049 | LPFC_EVT_ONLINE); |
972 | if (rc == 0) | 1050 | if (rc == 0) { |
973 | return -ENOMEM; | 1051 | status = -ENOMEM; |
1052 | goto board_mode_out; | ||
1053 | } | ||
974 | wait_for_completion(&online_compl); | 1054 | wait_for_completion(&online_compl); |
975 | } else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0) | 1055 | } else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0) |
976 | status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); | 1056 | status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); |
977 | else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0) | 1057 | else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0) |
978 | if (phba->sli_rev == LPFC_SLI_REV4) | 1058 | if (phba->sli_rev == LPFC_SLI_REV4) |
979 | return -EINVAL; | 1059 | status = -EINVAL; |
980 | else | 1060 | else |
981 | status = lpfc_do_offline(phba, LPFC_EVT_WARM_START); | 1061 | status = lpfc_do_offline(phba, LPFC_EVT_WARM_START); |
982 | else if (strncmp(buf, "error", sizeof("error") - 1) == 0) | 1062 | else if (strncmp(buf, "error", sizeof("error") - 1) == 0) |
983 | if (phba->sli_rev == LPFC_SLI_REV4) | 1063 | if (phba->sli_rev == LPFC_SLI_REV4) |
984 | return -EINVAL; | 1064 | status = -EINVAL; |
985 | else | 1065 | else |
986 | status = lpfc_do_offline(phba, LPFC_EVT_KILL); | 1066 | status = lpfc_do_offline(phba, LPFC_EVT_KILL); |
987 | else if (strncmp(buf, "dump", sizeof("dump") - 1) == 0) | 1067 | else if (strncmp(buf, "dump", sizeof("dump") - 1) == 0) |
@@ -991,12 +1071,21 @@ lpfc_board_mode_store(struct device *dev, struct device_attribute *attr, | |||
991 | else if (strncmp(buf, "dv_reset", sizeof("dv_reset") - 1) == 0) | 1071 | else if (strncmp(buf, "dv_reset", sizeof("dv_reset") - 1) == 0) |
992 | status = lpfc_sli4_pdev_reg_request(phba, LPFC_DV_RESET); | 1072 | status = lpfc_sli4_pdev_reg_request(phba, LPFC_DV_RESET); |
993 | else | 1073 | else |
994 | return -EINVAL; | 1074 | status = -EINVAL; |
995 | 1075 | ||
1076 | board_mode_out: | ||
996 | if (!status) | 1077 | if (!status) |
997 | return strlen(buf); | 1078 | return strlen(buf); |
998 | else | 1079 | else { |
1080 | board_mode_str = strchr(buf, '\n'); | ||
1081 | if (board_mode_str) | ||
1082 | *board_mode_str = '\0'; | ||
1083 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | ||
1084 | "3097 Failed \"%s\", status(%d), " | ||
1085 | "fc_flag(x%x)\n", | ||
1086 | buf, status, phba->pport->fc_flag); | ||
999 | return status; | 1087 | return status; |
1088 | } | ||
1000 | } | 1089 | } |
1001 | 1090 | ||
1002 | /** | 1091 | /** |
@@ -1942,6 +2031,7 @@ static DEVICE_ATTR(lpfc_fips_rev, S_IRUGO, lpfc_fips_rev_show, NULL); | |||
1942 | static DEVICE_ATTR(lpfc_dss, S_IRUGO, lpfc_dss_show, NULL); | 2031 | static DEVICE_ATTR(lpfc_dss, S_IRUGO, lpfc_dss_show, NULL); |
1943 | static DEVICE_ATTR(lpfc_sriov_hw_max_virtfn, S_IRUGO, | 2032 | static DEVICE_ATTR(lpfc_sriov_hw_max_virtfn, S_IRUGO, |
1944 | lpfc_sriov_hw_max_virtfn_show, NULL); | 2033 | lpfc_sriov_hw_max_virtfn_show, NULL); |
2034 | static DEVICE_ATTR(protocol, S_IRUGO, lpfc_sli4_protocol_show, NULL); | ||
1945 | 2035 | ||
1946 | static char *lpfc_soft_wwn_key = "C99G71SL8032A"; | 2036 | static char *lpfc_soft_wwn_key = "C99G71SL8032A"; |
1947 | 2037 | ||
@@ -3830,6 +3920,7 @@ struct device_attribute *lpfc_hba_attrs[] = { | |||
3830 | &dev_attr_lpfc_fips_rev, | 3920 | &dev_attr_lpfc_fips_rev, |
3831 | &dev_attr_lpfc_dss, | 3921 | &dev_attr_lpfc_dss, |
3832 | &dev_attr_lpfc_sriov_hw_max_virtfn, | 3922 | &dev_attr_lpfc_sriov_hw_max_virtfn, |
3923 | &dev_attr_protocol, | ||
3833 | NULL, | 3924 | NULL, |
3834 | }; | 3925 | }; |
3835 | 3926 | ||
@@ -3988,23 +4079,6 @@ static struct bin_attribute sysfs_ctlreg_attr = { | |||
3988 | }; | 4079 | }; |
3989 | 4080 | ||
3990 | /** | 4081 | /** |
3991 | * sysfs_mbox_idle - frees the sysfs mailbox | ||
3992 | * @phba: lpfc_hba pointer | ||
3993 | **/ | ||
3994 | static void | ||
3995 | sysfs_mbox_idle(struct lpfc_hba *phba) | ||
3996 | { | ||
3997 | phba->sysfs_mbox.state = SMBOX_IDLE; | ||
3998 | phba->sysfs_mbox.offset = 0; | ||
3999 | |||
4000 | if (phba->sysfs_mbox.mbox) { | ||
4001 | mempool_free(phba->sysfs_mbox.mbox, | ||
4002 | phba->mbox_mem_pool); | ||
4003 | phba->sysfs_mbox.mbox = NULL; | ||
4004 | } | ||
4005 | } | ||
4006 | |||
4007 | /** | ||
4008 | * sysfs_mbox_write - Write method for writing information via mbox | 4082 | * sysfs_mbox_write - Write method for writing information via mbox |
4009 | * @filp: open sysfs file | 4083 | * @filp: open sysfs file |
4010 | * @kobj: kernel kobject that contains the kernel class device. | 4084 | * @kobj: kernel kobject that contains the kernel class device. |
@@ -4014,71 +4088,18 @@ sysfs_mbox_idle(struct lpfc_hba *phba) | |||
4014 | * @count: bytes to transfer. | 4088 | * @count: bytes to transfer. |
4015 | * | 4089 | * |
4016 | * Description: | 4090 | * Description: |
4017 | * Accessed via /sys/class/scsi_host/hostxxx/mbox. | 4091 | * Deprecated function. All mailbox access from user space is performed via the |
4018 | * Uses the sysfs mbox to send buf contents to the adapter. | 4092 | * bsg interface. |
4019 | * | 4093 | * |
4020 | * Returns: | 4094 | * Returns: |
4021 | * -ERANGE off and count combo out of range | 4095 | * -EPERM operation not permitted |
4022 | * -EINVAL off, count or buff address invalid | ||
4023 | * zero if count is zero | ||
4024 | * -EPERM adapter is offline | ||
4025 | * -ENOMEM failed to allocate memory for the mail box | ||
4026 | * -EAGAIN offset, state or mbox is NULL | ||
4027 | * count number of bytes transferred | ||
4028 | **/ | 4096 | **/ |
4029 | static ssize_t | 4097 | static ssize_t |
4030 | sysfs_mbox_write(struct file *filp, struct kobject *kobj, | 4098 | sysfs_mbox_write(struct file *filp, struct kobject *kobj, |
4031 | struct bin_attribute *bin_attr, | 4099 | struct bin_attribute *bin_attr, |
4032 | char *buf, loff_t off, size_t count) | 4100 | char *buf, loff_t off, size_t count) |
4033 | { | 4101 | { |
4034 | struct device *dev = container_of(kobj, struct device, kobj); | 4102 | return -EPERM; |
4035 | struct Scsi_Host *shost = class_to_shost(dev); | ||
4036 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
4037 | struct lpfc_hba *phba = vport->phba; | ||
4038 | struct lpfcMboxq *mbox = NULL; | ||
4039 | |||
4040 | if ((count + off) > MAILBOX_CMD_SIZE) | ||
4041 | return -ERANGE; | ||
4042 | |||
4043 | if (off % 4 || count % 4 || (unsigned long)buf % 4) | ||
4044 | return -EINVAL; | ||
4045 | |||
4046 | if (count == 0) | ||
4047 | return 0; | ||
4048 | |||
4049 | if (off == 0) { | ||
4050 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
4051 | if (!mbox) | ||
4052 | return -ENOMEM; | ||
4053 | memset(mbox, 0, sizeof (LPFC_MBOXQ_t)); | ||
4054 | } | ||
4055 | |||
4056 | spin_lock_irq(&phba->hbalock); | ||
4057 | |||
4058 | if (off == 0) { | ||
4059 | if (phba->sysfs_mbox.mbox) | ||
4060 | mempool_free(mbox, phba->mbox_mem_pool); | ||
4061 | else | ||
4062 | phba->sysfs_mbox.mbox = mbox; | ||
4063 | phba->sysfs_mbox.state = SMBOX_WRITING; | ||
4064 | } else { | ||
4065 | if (phba->sysfs_mbox.state != SMBOX_WRITING || | ||
4066 | phba->sysfs_mbox.offset != off || | ||
4067 | phba->sysfs_mbox.mbox == NULL) { | ||
4068 | sysfs_mbox_idle(phba); | ||
4069 | spin_unlock_irq(&phba->hbalock); | ||
4070 | return -EAGAIN; | ||
4071 | } | ||
4072 | } | ||
4073 | |||
4074 | memcpy((uint8_t *) &phba->sysfs_mbox.mbox->u.mb + off, | ||
4075 | buf, count); | ||
4076 | |||
4077 | phba->sysfs_mbox.offset = off + count; | ||
4078 | |||
4079 | spin_unlock_irq(&phba->hbalock); | ||
4080 | |||
4081 | return count; | ||
4082 | } | 4103 | } |
4083 | 4104 | ||
4084 | /** | 4105 | /** |
@@ -4091,201 +4112,18 @@ sysfs_mbox_write(struct file *filp, struct kobject *kobj, | |||
4091 | * @count: bytes to transfer. | 4112 | * @count: bytes to transfer. |
4092 | * | 4113 | * |
4093 | * Description: | 4114 | * Description: |
4094 | * Accessed via /sys/class/scsi_host/hostxxx/mbox. | 4115 | * Deprecated function. All mailbox access from user space is performed via the |
4095 | * Uses the sysfs mbox to receive data from to the adapter. | 4116 | * bsg interface. |
4096 | * | 4117 | * |
4097 | * Returns: | 4118 | * Returns: |
4098 | * -ERANGE off greater than mailbox command size | 4119 | * -EPERM operation not permitted |
4099 | * -EINVAL off, count or buff address invalid | ||
4100 | * zero if off and count are zero | ||
4101 | * -EACCES adapter over temp | ||
4102 | * -EPERM garbage can value to catch a multitude of errors | ||
4103 | * -EAGAIN management IO not permitted, state or off error | ||
4104 | * -ETIME mailbox timeout | ||
4105 | * -ENODEV mailbox error | ||
4106 | * count number of bytes transferred | ||
4107 | **/ | 4120 | **/ |
4108 | static ssize_t | 4121 | static ssize_t |
4109 | sysfs_mbox_read(struct file *filp, struct kobject *kobj, | 4122 | sysfs_mbox_read(struct file *filp, struct kobject *kobj, |
4110 | struct bin_attribute *bin_attr, | 4123 | struct bin_attribute *bin_attr, |
4111 | char *buf, loff_t off, size_t count) | 4124 | char *buf, loff_t off, size_t count) |
4112 | { | 4125 | { |
4113 | struct device *dev = container_of(kobj, struct device, kobj); | 4126 | return -EPERM; |
4114 | struct Scsi_Host *shost = class_to_shost(dev); | ||
4115 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
4116 | struct lpfc_hba *phba = vport->phba; | ||
4117 | LPFC_MBOXQ_t *mboxq; | ||
4118 | MAILBOX_t *pmb; | ||
4119 | uint32_t mbox_tmo; | ||
4120 | int rc; | ||
4121 | |||
4122 | if (off > MAILBOX_CMD_SIZE) | ||
4123 | return -ERANGE; | ||
4124 | |||
4125 | if ((count + off) > MAILBOX_CMD_SIZE) | ||
4126 | count = MAILBOX_CMD_SIZE - off; | ||
4127 | |||
4128 | if (off % 4 || count % 4 || (unsigned long)buf % 4) | ||
4129 | return -EINVAL; | ||
4130 | |||
4131 | if (off && count == 0) | ||
4132 | return 0; | ||
4133 | |||
4134 | spin_lock_irq(&phba->hbalock); | ||
4135 | |||
4136 | if (phba->over_temp_state == HBA_OVER_TEMP) { | ||
4137 | sysfs_mbox_idle(phba); | ||
4138 | spin_unlock_irq(&phba->hbalock); | ||
4139 | return -EACCES; | ||
4140 | } | ||
4141 | |||
4142 | if (off == 0 && | ||
4143 | phba->sysfs_mbox.state == SMBOX_WRITING && | ||
4144 | phba->sysfs_mbox.offset >= 2 * sizeof(uint32_t)) { | ||
4145 | mboxq = (LPFC_MBOXQ_t *)&phba->sysfs_mbox.mbox; | ||
4146 | pmb = &mboxq->u.mb; | ||
4147 | switch (pmb->mbxCommand) { | ||
4148 | /* Offline only */ | ||
4149 | case MBX_INIT_LINK: | ||
4150 | case MBX_DOWN_LINK: | ||
4151 | case MBX_CONFIG_LINK: | ||
4152 | case MBX_CONFIG_RING: | ||
4153 | case MBX_RESET_RING: | ||
4154 | case MBX_UNREG_LOGIN: | ||
4155 | case MBX_CLEAR_LA: | ||
4156 | case MBX_DUMP_CONTEXT: | ||
4157 | case MBX_RUN_DIAGS: | ||
4158 | case MBX_RESTART: | ||
4159 | case MBX_SET_MASK: | ||
4160 | case MBX_SET_DEBUG: | ||
4161 | if (!(vport->fc_flag & FC_OFFLINE_MODE)) { | ||
4162 | printk(KERN_WARNING "mbox_read:Command 0x%x " | ||
4163 | "is illegal in on-line state\n", | ||
4164 | pmb->mbxCommand); | ||
4165 | sysfs_mbox_idle(phba); | ||
4166 | spin_unlock_irq(&phba->hbalock); | ||
4167 | return -EPERM; | ||
4168 | } | ||
4169 | case MBX_WRITE_NV: | ||
4170 | case MBX_WRITE_VPARMS: | ||
4171 | case MBX_LOAD_SM: | ||
4172 | case MBX_READ_NV: | ||
4173 | case MBX_READ_CONFIG: | ||
4174 | case MBX_READ_RCONFIG: | ||
4175 | case MBX_READ_STATUS: | ||
4176 | case MBX_READ_XRI: | ||
4177 | case MBX_READ_REV: | ||
4178 | case MBX_READ_LNK_STAT: | ||
4179 | case MBX_DUMP_MEMORY: | ||
4180 | case MBX_DOWN_LOAD: | ||
4181 | case MBX_UPDATE_CFG: | ||
4182 | case MBX_KILL_BOARD: | ||
4183 | case MBX_LOAD_AREA: | ||
4184 | case MBX_LOAD_EXP_ROM: | ||
4185 | case MBX_BEACON: | ||
4186 | case MBX_DEL_LD_ENTRY: | ||
4187 | case MBX_SET_VARIABLE: | ||
4188 | case MBX_WRITE_WWN: | ||
4189 | case MBX_PORT_CAPABILITIES: | ||
4190 | case MBX_PORT_IOV_CONTROL: | ||
4191 | break; | ||
4192 | case MBX_SECURITY_MGMT: | ||
4193 | case MBX_AUTH_PORT: | ||
4194 | if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) { | ||
4195 | printk(KERN_WARNING "mbox_read:Command 0x%x " | ||
4196 | "is not permitted\n", pmb->mbxCommand); | ||
4197 | sysfs_mbox_idle(phba); | ||
4198 | spin_unlock_irq(&phba->hbalock); | ||
4199 | return -EPERM; | ||
4200 | } | ||
4201 | break; | ||
4202 | case MBX_READ_SPARM64: | ||
4203 | case MBX_READ_TOPOLOGY: | ||
4204 | case MBX_REG_LOGIN: | ||
4205 | case MBX_REG_LOGIN64: | ||
4206 | case MBX_CONFIG_PORT: | ||
4207 | case MBX_RUN_BIU_DIAG: | ||
4208 | printk(KERN_WARNING "mbox_read: Illegal Command 0x%x\n", | ||
4209 | pmb->mbxCommand); | ||
4210 | sysfs_mbox_idle(phba); | ||
4211 | spin_unlock_irq(&phba->hbalock); | ||
4212 | return -EPERM; | ||
4213 | default: | ||
4214 | printk(KERN_WARNING "mbox_read: Unknown Command 0x%x\n", | ||
4215 | pmb->mbxCommand); | ||
4216 | sysfs_mbox_idle(phba); | ||
4217 | spin_unlock_irq(&phba->hbalock); | ||
4218 | return -EPERM; | ||
4219 | } | ||
4220 | |||
4221 | /* If HBA encountered an error attention, allow only DUMP | ||
4222 | * or RESTART mailbox commands until the HBA is restarted. | ||
4223 | */ | ||
4224 | if (phba->pport->stopped && | ||
4225 | pmb->mbxCommand != MBX_DUMP_MEMORY && | ||
4226 | pmb->mbxCommand != MBX_RESTART && | ||
4227 | pmb->mbxCommand != MBX_WRITE_VPARMS && | ||
4228 | pmb->mbxCommand != MBX_WRITE_WWN) | ||
4229 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, | ||
4230 | "1259 mbox: Issued mailbox cmd " | ||
4231 | "0x%x while in stopped state.\n", | ||
4232 | pmb->mbxCommand); | ||
4233 | |||
4234 | phba->sysfs_mbox.mbox->vport = vport; | ||
4235 | |||
4236 | /* Don't allow mailbox commands to be sent when blocked | ||
4237 | * or when in the middle of discovery | ||
4238 | */ | ||
4239 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { | ||
4240 | sysfs_mbox_idle(phba); | ||
4241 | spin_unlock_irq(&phba->hbalock); | ||
4242 | return -EAGAIN; | ||
4243 | } | ||
4244 | |||
4245 | if ((vport->fc_flag & FC_OFFLINE_MODE) || | ||
4246 | (!(phba->sli.sli_flag & LPFC_SLI_ACTIVE))) { | ||
4247 | |||
4248 | spin_unlock_irq(&phba->hbalock); | ||
4249 | rc = lpfc_sli_issue_mbox (phba, | ||
4250 | phba->sysfs_mbox.mbox, | ||
4251 | MBX_POLL); | ||
4252 | spin_lock_irq(&phba->hbalock); | ||
4253 | |||
4254 | } else { | ||
4255 | spin_unlock_irq(&phba->hbalock); | ||
4256 | mbox_tmo = lpfc_mbox_tmo_val(phba, mboxq); | ||
4257 | rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo); | ||
4258 | spin_lock_irq(&phba->hbalock); | ||
4259 | } | ||
4260 | |||
4261 | if (rc != MBX_SUCCESS) { | ||
4262 | if (rc == MBX_TIMEOUT) { | ||
4263 | phba->sysfs_mbox.mbox = NULL; | ||
4264 | } | ||
4265 | sysfs_mbox_idle(phba); | ||
4266 | spin_unlock_irq(&phba->hbalock); | ||
4267 | return (rc == MBX_TIMEOUT) ? -ETIME : -ENODEV; | ||
4268 | } | ||
4269 | phba->sysfs_mbox.state = SMBOX_READING; | ||
4270 | } | ||
4271 | else if (phba->sysfs_mbox.offset != off || | ||
4272 | phba->sysfs_mbox.state != SMBOX_READING) { | ||
4273 | printk(KERN_WARNING "mbox_read: Bad State\n"); | ||
4274 | sysfs_mbox_idle(phba); | ||
4275 | spin_unlock_irq(&phba->hbalock); | ||
4276 | return -EAGAIN; | ||
4277 | } | ||
4278 | |||
4279 | memcpy(buf, (uint8_t *) &pmb + off, count); | ||
4280 | |||
4281 | phba->sysfs_mbox.offset = off + count; | ||
4282 | |||
4283 | if (phba->sysfs_mbox.offset == MAILBOX_CMD_SIZE) | ||
4284 | sysfs_mbox_idle(phba); | ||
4285 | |||
4286 | spin_unlock_irq(&phba->hbalock); | ||
4287 | |||
4288 | return count; | ||
4289 | } | 4127 | } |
4290 | 4128 | ||
4291 | static struct bin_attribute sysfs_mbox_attr = { | 4129 | static struct bin_attribute sysfs_mbox_attr = { |
@@ -4429,8 +4267,13 @@ lpfc_get_host_port_state(struct Scsi_Host *shost) | |||
4429 | case LPFC_LINK_UP: | 4267 | case LPFC_LINK_UP: |
4430 | case LPFC_CLEAR_LA: | 4268 | case LPFC_CLEAR_LA: |
4431 | case LPFC_HBA_READY: | 4269 | case LPFC_HBA_READY: |
4432 | /* Links up, beyond this port_type reports state */ | 4270 | /* Links up, reports port state accordingly */ |
4433 | fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; | 4271 | if (vport->port_state < LPFC_VPORT_READY) |
4272 | fc_host_port_state(shost) = | ||
4273 | FC_PORTSTATE_BYPASSED; | ||
4274 | else | ||
4275 | fc_host_port_state(shost) = | ||
4276 | FC_PORTSTATE_ONLINE; | ||
4434 | break; | 4277 | break; |
4435 | case LPFC_HBA_ERROR: | 4278 | case LPFC_HBA_ERROR: |
4436 | fc_host_port_state(shost) = FC_PORTSTATE_ERROR; | 4279 | fc_host_port_state(shost) = FC_PORTSTATE_ERROR; |
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 6760c69f5253..c13e54760cb1 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c | |||
@@ -3140,6 +3140,9 @@ lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | |||
3140 | unsigned long flags; | 3140 | unsigned long flags; |
3141 | uint32_t size; | 3141 | uint32_t size; |
3142 | int rc = 0; | 3142 | int rc = 0; |
3143 | struct lpfc_dmabuf *dmabuf; | ||
3144 | struct lpfc_sli_config_mbox *sli_cfg_mbx; | ||
3145 | uint8_t *pmbx; | ||
3143 | 3146 | ||
3144 | spin_lock_irqsave(&phba->ct_ev_lock, flags); | 3147 | spin_lock_irqsave(&phba->ct_ev_lock, flags); |
3145 | dd_data = pmboxq->context1; | 3148 | dd_data = pmboxq->context1; |
@@ -3156,7 +3159,19 @@ lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | |||
3156 | */ | 3159 | */ |
3157 | pmb = (uint8_t *)&pmboxq->u.mb; | 3160 | pmb = (uint8_t *)&pmboxq->u.mb; |
3158 | pmb_buf = (uint8_t *)dd_data->context_un.mbox.mb; | 3161 | pmb_buf = (uint8_t *)dd_data->context_un.mbox.mb; |
3162 | /* Copy the byte swapped response mailbox back to the user */ | ||
3159 | memcpy(pmb_buf, pmb, sizeof(MAILBOX_t)); | 3163 | memcpy(pmb_buf, pmb, sizeof(MAILBOX_t)); |
3164 | /* if there is any non-embedded extended data copy that too */ | ||
3165 | dmabuf = phba->mbox_ext_buf_ctx.mbx_dmabuf; | ||
3166 | sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt; | ||
3167 | if (!bsg_bf_get(lpfc_mbox_hdr_emb, | ||
3168 | &sli_cfg_mbx->un.sli_config_emb0_subsys.sli_config_hdr)) { | ||
3169 | pmbx = (uint8_t *)dmabuf->virt; | ||
3170 | /* byte swap the extended data following the mailbox command */ | ||
3171 | lpfc_sli_pcimem_bcopy(&pmbx[sizeof(MAILBOX_t)], | ||
3172 | &pmbx[sizeof(MAILBOX_t)], | ||
3173 | sli_cfg_mbx->un.sli_config_emb0_subsys.mse[0].buf_len); | ||
3174 | } | ||
3160 | 3175 | ||
3161 | job = dd_data->context_un.mbox.set_job; | 3176 | job = dd_data->context_un.mbox.set_job; |
3162 | if (job) { | 3177 | if (job) { |
@@ -3519,6 +3534,18 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
3519 | /* state change */ | 3534 | /* state change */ |
3520 | phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_PORT; | 3535 | phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_PORT; |
3521 | 3536 | ||
3537 | /* | ||
3538 | * Non-embedded mailbox subcommand data gets byte swapped here because | ||
3539 | * the lower level driver code only does the first 64 mailbox words. | ||
3540 | */ | ||
3541 | if ((!bsg_bf_get(lpfc_mbox_hdr_emb, | ||
3542 | &sli_cfg_mbx->un.sli_config_emb0_subsys.sli_config_hdr)) && | ||
3543 | (nemb_tp == nemb_mse)) | ||
3544 | lpfc_sli_pcimem_bcopy(&pmbx[sizeof(MAILBOX_t)], | ||
3545 | &pmbx[sizeof(MAILBOX_t)], | ||
3546 | sli_cfg_mbx->un.sli_config_emb0_subsys. | ||
3547 | mse[0].buf_len); | ||
3548 | |||
3522 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); | 3549 | rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); |
3523 | if ((rc == MBX_SUCCESS) || (rc == MBX_BUSY)) { | 3550 | if ((rc == MBX_SUCCESS) || (rc == MBX_BUSY)) { |
3524 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | 3551 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, |
@@ -3575,7 +3602,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
3575 | &sli_cfg_mbx->un.sli_config_emb0_subsys.sli_config_hdr); | 3602 | &sli_cfg_mbx->un.sli_config_emb0_subsys.sli_config_hdr); |
3576 | if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_MSE) { | 3603 | if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_MSE) { |
3577 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | 3604 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, |
3578 | "2953 Handled SLI_CONFIG(mse) wr, " | 3605 | "2953 Failed SLI_CONFIG(mse) wr, " |
3579 | "ext_buf_cnt(%d) out of range(%d)\n", | 3606 | "ext_buf_cnt(%d) out of range(%d)\n", |
3580 | ext_buf_cnt, | 3607 | ext_buf_cnt, |
3581 | LPFC_MBX_SLI_CONFIG_MAX_MSE); | 3608 | LPFC_MBX_SLI_CONFIG_MAX_MSE); |
@@ -3593,7 +3620,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
3593 | ext_buf_cnt = sli_cfg_mbx->un.sli_config_emb1_subsys.hbd_count; | 3620 | ext_buf_cnt = sli_cfg_mbx->un.sli_config_emb1_subsys.hbd_count; |
3594 | if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_HBD) { | 3621 | if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_HBD) { |
3595 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | 3622 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, |
3596 | "2954 Handled SLI_CONFIG(hbd) wr, " | 3623 | "2954 Failed SLI_CONFIG(hbd) wr, " |
3597 | "ext_buf_cnt(%d) out of range(%d)\n", | 3624 | "ext_buf_cnt(%d) out of range(%d)\n", |
3598 | ext_buf_cnt, | 3625 | ext_buf_cnt, |
3599 | LPFC_MBX_SLI_CONFIG_MAX_HBD); | 3626 | LPFC_MBX_SLI_CONFIG_MAX_HBD); |
@@ -3687,6 +3714,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
3687 | "2956 Failed to issue SLI_CONFIG ext-buffer " | 3714 | "2956 Failed to issue SLI_CONFIG ext-buffer " |
3688 | "maibox command, rc:x%x\n", rc); | 3715 | "maibox command, rc:x%x\n", rc); |
3689 | rc = -EPIPE; | 3716 | rc = -EPIPE; |
3717 | goto job_error; | ||
3690 | } | 3718 | } |
3691 | 3719 | ||
3692 | /* wait for additoinal external buffers */ | 3720 | /* wait for additoinal external buffers */ |
@@ -3721,7 +3749,7 @@ lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
3721 | uint32_t opcode; | 3749 | uint32_t opcode; |
3722 | int rc = SLI_CONFIG_NOT_HANDLED; | 3750 | int rc = SLI_CONFIG_NOT_HANDLED; |
3723 | 3751 | ||
3724 | /* state change */ | 3752 | /* state change on new multi-buffer pass-through mailbox command */ |
3725 | phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_HOST; | 3753 | phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_HOST; |
3726 | 3754 | ||
3727 | sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt; | 3755 | sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt; |
@@ -3752,18 +3780,36 @@ lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
3752 | break; | 3780 | break; |
3753 | default: | 3781 | default: |
3754 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | 3782 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, |
3755 | "2959 Not handled SLI_CONFIG " | 3783 | "2959 Reject SLI_CONFIG " |
3756 | "subsys_fcoe, opcode:x%x\n", | 3784 | "subsys_fcoe, opcode:x%x\n", |
3757 | opcode); | 3785 | opcode); |
3758 | rc = SLI_CONFIG_NOT_HANDLED; | 3786 | rc = -EPERM; |
3787 | break; | ||
3788 | } | ||
3789 | } else if (subsys == SLI_CONFIG_SUBSYS_COMN) { | ||
3790 | switch (opcode) { | ||
3791 | case COMN_OPCODE_GET_CNTL_ADDL_ATTRIBUTES: | ||
3792 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3793 | "3106 Handled SLI_CONFIG " | ||
3794 | "subsys_fcoe, opcode:x%x\n", | ||
3795 | opcode); | ||
3796 | rc = lpfc_bsg_sli_cfg_read_cmd_ext(phba, job, | ||
3797 | nemb_mse, dmabuf); | ||
3798 | break; | ||
3799 | default: | ||
3800 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | ||
3801 | "3107 Reject SLI_CONFIG " | ||
3802 | "subsys_fcoe, opcode:x%x\n", | ||
3803 | opcode); | ||
3804 | rc = -EPERM; | ||
3759 | break; | 3805 | break; |
3760 | } | 3806 | } |
3761 | } else { | 3807 | } else { |
3762 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | 3808 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, |
3763 | "2977 Handled SLI_CONFIG " | 3809 | "2977 Reject SLI_CONFIG " |
3764 | "subsys:x%d, opcode:x%x\n", | 3810 | "subsys:x%d, opcode:x%x\n", |
3765 | subsys, opcode); | 3811 | subsys, opcode); |
3766 | rc = SLI_CONFIG_NOT_HANDLED; | 3812 | rc = -EPERM; |
3767 | } | 3813 | } |
3768 | } else { | 3814 | } else { |
3769 | subsys = bsg_bf_get(lpfc_emb1_subcmnd_subsys, | 3815 | subsys = bsg_bf_get(lpfc_emb1_subcmnd_subsys, |
@@ -3799,12 +3845,17 @@ lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
3799 | } | 3845 | } |
3800 | } else { | 3846 | } else { |
3801 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | 3847 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, |
3802 | "2978 Handled SLI_CONFIG " | 3848 | "2978 Not handled SLI_CONFIG " |
3803 | "subsys:x%d, opcode:x%x\n", | 3849 | "subsys:x%d, opcode:x%x\n", |
3804 | subsys, opcode); | 3850 | subsys, opcode); |
3805 | rc = SLI_CONFIG_NOT_HANDLED; | 3851 | rc = SLI_CONFIG_NOT_HANDLED; |
3806 | } | 3852 | } |
3807 | } | 3853 | } |
3854 | |||
3855 | /* state reset on not handled new multi-buffer mailbox command */ | ||
3856 | if (rc != SLI_CONFIG_HANDLED) | ||
3857 | phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_IDLE; | ||
3858 | |||
3808 | return rc; | 3859 | return rc; |
3809 | } | 3860 | } |
3810 | 3861 | ||
@@ -4262,11 +4313,8 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job, | |||
4262 | 4313 | ||
4263 | /* extended mailbox commands will need an extended buffer */ | 4314 | /* extended mailbox commands will need an extended buffer */ |
4264 | if (mbox_req->inExtWLen || mbox_req->outExtWLen) { | 4315 | if (mbox_req->inExtWLen || mbox_req->outExtWLen) { |
4265 | /* any data for the device? */ | 4316 | from = pmbx; |
4266 | if (mbox_req->inExtWLen) { | 4317 | ext = from + sizeof(MAILBOX_t); |
4267 | from = pmbx; | ||
4268 | ext = from + sizeof(MAILBOX_t); | ||
4269 | } | ||
4270 | pmboxq->context2 = ext; | 4318 | pmboxq->context2 = ext; |
4271 | pmboxq->in_ext_byte_len = | 4319 | pmboxq->in_ext_byte_len = |
4272 | mbox_req->inExtWLen * sizeof(uint32_t); | 4320 | mbox_req->inExtWLen * sizeof(uint32_t); |
diff --git a/drivers/scsi/lpfc/lpfc_bsg.h b/drivers/scsi/lpfc/lpfc_bsg.h index c8c2b47ea886..edfe61fc52b1 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.h +++ b/drivers/scsi/lpfc/lpfc_bsg.h | |||
@@ -96,7 +96,7 @@ struct get_mgmt_rev { | |||
96 | }; | 96 | }; |
97 | 97 | ||
98 | #define MANAGEMENT_MAJOR_REV 1 | 98 | #define MANAGEMENT_MAJOR_REV 1 |
99 | #define MANAGEMENT_MINOR_REV 0 | 99 | #define MANAGEMENT_MINOR_REV 1 |
100 | 100 | ||
101 | /* the MgmtRevInfo structure */ | 101 | /* the MgmtRevInfo structure */ |
102 | struct MgmtRevInfo { | 102 | struct MgmtRevInfo { |
@@ -248,6 +248,7 @@ struct lpfc_sli_config_emb1_subsys { | |||
248 | #define COMN_OPCODE_WRITE_OBJECT 0xAC | 248 | #define COMN_OPCODE_WRITE_OBJECT 0xAC |
249 | #define COMN_OPCODE_READ_OBJECT_LIST 0xAD | 249 | #define COMN_OPCODE_READ_OBJECT_LIST 0xAD |
250 | #define COMN_OPCODE_DELETE_OBJECT 0xAE | 250 | #define COMN_OPCODE_DELETE_OBJECT 0xAE |
251 | #define COMN_OPCODE_GET_CNTL_ADDL_ATTRIBUTES 0x79 | ||
251 | uint32_t timeout; | 252 | uint32_t timeout; |
252 | uint32_t request_length; | 253 | uint32_t request_length; |
253 | uint32_t word9; | 254 | uint32_t word9; |
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 60f95347babf..f74afa23e0dd 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -26,7 +26,7 @@ void lpfc_sli_read_link_ste(struct lpfc_hba *); | |||
26 | void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t, uint16_t); | 26 | void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t, uint16_t); |
27 | void lpfc_dump_wakeup_param(struct lpfc_hba *, LPFC_MBOXQ_t *); | 27 | void lpfc_dump_wakeup_param(struct lpfc_hba *, LPFC_MBOXQ_t *); |
28 | int lpfc_dump_static_vport(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); | 28 | int lpfc_dump_static_vport(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); |
29 | int lpfc_dump_fcoe_param(struct lpfc_hba *, struct lpfcMboxq *); | 29 | int lpfc_sli4_dump_cfg_rg23(struct lpfc_hba *, struct lpfcMboxq *); |
30 | void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); | 30 | void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); |
31 | void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); | 31 | void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); |
32 | 32 | ||
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 98d21521f539..447da2a546ae 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
@@ -2104,6 +2104,8 @@ struct lpfc_mbx_read_config { | |||
2104 | #define lpfc_mbx_rd_conf_lnk_type_SHIFT 6 | 2104 | #define lpfc_mbx_rd_conf_lnk_type_SHIFT 6 |
2105 | #define lpfc_mbx_rd_conf_lnk_type_MASK 0x00000003 | 2105 | #define lpfc_mbx_rd_conf_lnk_type_MASK 0x00000003 |
2106 | #define lpfc_mbx_rd_conf_lnk_type_WORD word2 | 2106 | #define lpfc_mbx_rd_conf_lnk_type_WORD word2 |
2107 | #define LPFC_LNK_TYPE_GE 0 | ||
2108 | #define LPFC_LNK_TYPE_FC 1 | ||
2107 | #define lpfc_mbx_rd_conf_lnk_ldv_SHIFT 8 | 2109 | #define lpfc_mbx_rd_conf_lnk_ldv_SHIFT 8 |
2108 | #define lpfc_mbx_rd_conf_lnk_ldv_MASK 0x00000001 | 2110 | #define lpfc_mbx_rd_conf_lnk_ldv_MASK 0x00000001 |
2109 | #define lpfc_mbx_rd_conf_lnk_ldv_WORD word2 | 2111 | #define lpfc_mbx_rd_conf_lnk_ldv_WORD word2 |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 55bc4fc7376f..d247eb015526 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -475,27 +475,6 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
475 | /* Get the default values for Model Name and Description */ | 475 | /* Get the default values for Model Name and Description */ |
476 | lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc); | 476 | lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc); |
477 | 477 | ||
478 | if ((phba->cfg_link_speed > LPFC_USER_LINK_SPEED_16G) | ||
479 | || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_1G) | ||
480 | && !(phba->lmt & LMT_1Gb)) | ||
481 | || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_2G) | ||
482 | && !(phba->lmt & LMT_2Gb)) | ||
483 | || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_4G) | ||
484 | && !(phba->lmt & LMT_4Gb)) | ||
485 | || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_8G) | ||
486 | && !(phba->lmt & LMT_8Gb)) | ||
487 | || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_10G) | ||
488 | && !(phba->lmt & LMT_10Gb)) | ||
489 | || ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G) | ||
490 | && !(phba->lmt & LMT_16Gb))) { | ||
491 | /* Reset link speed to auto */ | ||
492 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | ||
493 | "1302 Invalid speed for this board: " | ||
494 | "Reset link speed to auto: x%x\n", | ||
495 | phba->cfg_link_speed); | ||
496 | phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO; | ||
497 | } | ||
498 | |||
499 | phba->link_state = LPFC_LINK_DOWN; | 478 | phba->link_state = LPFC_LINK_DOWN; |
500 | 479 | ||
501 | /* Only process IOCBs on ELS ring till hba_state is READY */ | 480 | /* Only process IOCBs on ELS ring till hba_state is READY */ |
@@ -585,28 +564,10 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
585 | return -EIO; | 564 | return -EIO; |
586 | } | 565 | } |
587 | } else if (phba->cfg_suppress_link_up == LPFC_INITIALIZE_LINK) { | 566 | } else if (phba->cfg_suppress_link_up == LPFC_INITIALIZE_LINK) { |
588 | lpfc_init_link(phba, pmb, phba->cfg_topology, | 567 | mempool_free(pmb, phba->mbox_mem_pool); |
589 | phba->cfg_link_speed); | 568 | rc = phba->lpfc_hba_init_link(phba, MBX_NOWAIT); |
590 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 569 | if (rc) |
591 | lpfc_set_loopback_flag(phba); | 570 | return rc; |
592 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | ||
593 | if (rc != MBX_SUCCESS) { | ||
594 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
595 | "0454 Adapter failed to init, mbxCmd x%x " | ||
596 | "INIT_LINK, mbxStatus x%x\n", | ||
597 | mb->mbxCommand, mb->mbxStatus); | ||
598 | |||
599 | /* Clear all interrupt enable conditions */ | ||
600 | writel(0, phba->HCregaddr); | ||
601 | readl(phba->HCregaddr); /* flush */ | ||
602 | /* Clear all pending interrupts */ | ||
603 | writel(0xffffffff, phba->HAregaddr); | ||
604 | readl(phba->HAregaddr); /* flush */ | ||
605 | phba->link_state = LPFC_HBA_ERROR; | ||
606 | if (rc != MBX_BUSY) | ||
607 | mempool_free(pmb, phba->mbox_mem_pool); | ||
608 | return -EIO; | ||
609 | } | ||
610 | } | 571 | } |
611 | /* MBOX buffer will be freed in mbox compl */ | 572 | /* MBOX buffer will be freed in mbox compl */ |
612 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 573 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
@@ -681,6 +642,26 @@ lpfc_hba_init_link(struct lpfc_hba *phba, uint32_t flag) | |||
681 | mb = &pmb->u.mb; | 642 | mb = &pmb->u.mb; |
682 | pmb->vport = vport; | 643 | pmb->vport = vport; |
683 | 644 | ||
645 | if ((phba->cfg_link_speed > LPFC_USER_LINK_SPEED_MAX) || | ||
646 | ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_1G) && | ||
647 | !(phba->lmt & LMT_1Gb)) || | ||
648 | ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_2G) && | ||
649 | !(phba->lmt & LMT_2Gb)) || | ||
650 | ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_4G) && | ||
651 | !(phba->lmt & LMT_4Gb)) || | ||
652 | ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_8G) && | ||
653 | !(phba->lmt & LMT_8Gb)) || | ||
654 | ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_10G) && | ||
655 | !(phba->lmt & LMT_10Gb)) || | ||
656 | ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G) && | ||
657 | !(phba->lmt & LMT_16Gb))) { | ||
658 | /* Reset link speed to auto */ | ||
659 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | ||
660 | "1302 Invalid speed for this board:%d " | ||
661 | "Reset link speed to auto.\n", | ||
662 | phba->cfg_link_speed); | ||
663 | phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO; | ||
664 | } | ||
684 | lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); | 665 | lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); |
685 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 666 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
686 | lpfc_set_loopback_flag(phba); | 667 | lpfc_set_loopback_flag(phba); |
@@ -1474,7 +1455,7 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) | |||
1474 | /* TODO: Register for Overtemp async events. */ | 1455 | /* TODO: Register for Overtemp async events. */ |
1475 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1456 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
1476 | "2889 Port Overtemperature event, " | 1457 | "2889 Port Overtemperature event, " |
1477 | "taking port\n"); | 1458 | "taking port offline\n"); |
1478 | spin_lock_irq(&phba->hbalock); | 1459 | spin_lock_irq(&phba->hbalock); |
1479 | phba->over_temp_state = HBA_OVER_TEMP; | 1460 | phba->over_temp_state = HBA_OVER_TEMP; |
1480 | spin_unlock_irq(&phba->hbalock); | 1461 | spin_unlock_irq(&phba->hbalock); |
@@ -9198,12 +9179,15 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
9198 | /* Perform post initialization setup */ | 9179 | /* Perform post initialization setup */ |
9199 | lpfc_post_init_setup(phba); | 9180 | lpfc_post_init_setup(phba); |
9200 | 9181 | ||
9201 | /* check for firmware upgrade or downgrade */ | 9182 | /* check for firmware upgrade or downgrade (if_type 2 only) */ |
9202 | snprintf(file_name, 16, "%s.grp", phba->ModelName); | 9183 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == |
9203 | error = request_firmware(&fw, file_name, &phba->pcidev->dev); | 9184 | LPFC_SLI_INTF_IF_TYPE_2) { |
9204 | if (!error) { | 9185 | snprintf(file_name, 16, "%s.grp", phba->ModelName); |
9205 | lpfc_write_firmware(phba, fw); | 9186 | error = request_firmware(&fw, file_name, &phba->pcidev->dev); |
9206 | release_firmware(fw); | 9187 | if (!error) { |
9188 | lpfc_write_firmware(phba, fw); | ||
9189 | release_firmware(fw); | ||
9190 | } | ||
9207 | } | 9191 | } |
9208 | 9192 | ||
9209 | /* Check if there are static vports to be created. */ | 9193 | /* Check if there are static vports to be created. */ |
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 2ebc7d2540c0..0228f04061da 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -2175,16 +2175,15 @@ lpfc_unreg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport) | |||
2175 | } | 2175 | } |
2176 | 2176 | ||
2177 | /** | 2177 | /** |
2178 | * lpfc_dump_fcoe_param - Dump config region 23 to get FCoe parameters. | 2178 | * lpfc_sli4_dump_cfg_rg23 - Dump sli4 port config region 23 |
2179 | * @phba: pointer to the hba structure containing. | 2179 | * @phba: pointer to the hba structure containing. |
2180 | * @mbox: pointer to lpfc mbox command to initialize. | 2180 | * @mbox: pointer to lpfc mbox command to initialize. |
2181 | * | 2181 | * |
2182 | * This function create a SLI4 dump mailbox command to dump FCoE | 2182 | * This function create a SLI4 dump mailbox command to dump configure |
2183 | * parameters stored in region 23. | 2183 | * region 23. |
2184 | **/ | 2184 | **/ |
2185 | int | 2185 | int |
2186 | lpfc_dump_fcoe_param(struct lpfc_hba *phba, | 2186 | lpfc_sli4_dump_cfg_rg23(struct lpfc_hba *phba, struct lpfcMboxq *mbox) |
2187 | struct lpfcMboxq *mbox) | ||
2188 | { | 2187 | { |
2189 | struct lpfc_dmabuf *mp = NULL; | 2188 | struct lpfc_dmabuf *mp = NULL; |
2190 | MAILBOX_t *mb; | 2189 | MAILBOX_t *mb; |
@@ -2198,9 +2197,9 @@ lpfc_dump_fcoe_param(struct lpfc_hba *phba, | |||
2198 | 2197 | ||
2199 | if (!mp || !mp->virt) { | 2198 | if (!mp || !mp->virt) { |
2200 | kfree(mp); | 2199 | kfree(mp); |
2201 | /* dump_fcoe_param failed to allocate memory */ | 2200 | /* dump config region 23 failed to allocate memory */ |
2202 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, | 2201 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, |
2203 | "2569 lpfc_dump_fcoe_param: memory" | 2202 | "2569 lpfc dump config region 23: memory" |
2204 | " allocation failed\n"); | 2203 | " allocation failed\n"); |
2205 | return 1; | 2204 | return 1; |
2206 | } | 2205 | } |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 4d4104f38c98..1be13e757eda 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -4566,7 +4566,7 @@ lpfc_sli4_read_fcoe_params(struct lpfc_hba *phba, | |||
4566 | phba->fc_map[2] = LPFC_FCOE_FCF_MAP2; | 4566 | phba->fc_map[2] = LPFC_FCOE_FCF_MAP2; |
4567 | 4567 | ||
4568 | mqe = &mboxq->u.mqe; | 4568 | mqe = &mboxq->u.mqe; |
4569 | if (lpfc_dump_fcoe_param(phba, mboxq)) | 4569 | if (lpfc_sli4_dump_cfg_rg23(phba, mboxq)) |
4570 | return -ENOMEM; | 4570 | return -ENOMEM; |
4571 | 4571 | ||
4572 | mp = (struct lpfc_dmabuf *) mboxq->context1; | 4572 | mp = (struct lpfc_dmabuf *) mboxq->context1; |
@@ -6205,7 +6205,11 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
6205 | rc = 0; | 6205 | rc = 0; |
6206 | phba->fcf.fcfi = bf_get(lpfc_reg_fcfi_fcfi, | 6206 | phba->fcf.fcfi = bf_get(lpfc_reg_fcfi_fcfi, |
6207 | &mboxq->u.mqe.un.reg_fcfi); | 6207 | &mboxq->u.mqe.un.reg_fcfi); |
6208 | |||
6209 | /* Check if the port is configured to be disabled */ | ||
6210 | lpfc_sli_read_link_ste(phba); | ||
6208 | } | 6211 | } |
6212 | |||
6209 | /* | 6213 | /* |
6210 | * The port is ready, set the host's link state to LINK_DOWN | 6214 | * The port is ready, set the host's link state to LINK_DOWN |
6211 | * in preparation for link interrupts. | 6215 | * in preparation for link interrupts. |
@@ -6213,7 +6217,19 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
6213 | spin_lock_irq(&phba->hbalock); | 6217 | spin_lock_irq(&phba->hbalock); |
6214 | phba->link_state = LPFC_LINK_DOWN; | 6218 | phba->link_state = LPFC_LINK_DOWN; |
6215 | spin_unlock_irq(&phba->hbalock); | 6219 | spin_unlock_irq(&phba->hbalock); |
6216 | if (phba->cfg_suppress_link_up == LPFC_INITIALIZE_LINK) { | 6220 | if (!(phba->hba_flag & HBA_FCOE_MODE) && |
6221 | (phba->hba_flag & LINK_DISABLED)) { | ||
6222 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_SLI, | ||
6223 | "3103 Adapter Link is disabled.\n"); | ||
6224 | lpfc_down_link(phba, mboxq); | ||
6225 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
6226 | if (rc != MBX_SUCCESS) { | ||
6227 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_SLI, | ||
6228 | "3104 Adapter failed to issue " | ||
6229 | "DOWN_LINK mbox cmd, rc:x%x\n", rc); | ||
6230 | goto out_unset_queue; | ||
6231 | } | ||
6232 | } else if (phba->cfg_suppress_link_up == LPFC_INITIALIZE_LINK) { | ||
6217 | rc = phba->lpfc_hba_init_link(phba, MBX_NOWAIT); | 6233 | rc = phba->lpfc_hba_init_link(phba, MBX_NOWAIT); |
6218 | if (rc) | 6234 | if (rc) |
6219 | goto out_unset_queue; | 6235 | goto out_unset_queue; |
@@ -15252,45 +15268,42 @@ lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *phba) | |||
15252 | } | 15268 | } |
15253 | 15269 | ||
15254 | /** | 15270 | /** |
15255 | * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled. | 15271 | * lpfc_sli_get_config_region23 - Get sli3 port region 23 data. |
15256 | * @phba: pointer to lpfc hba data structure. | 15272 | * @phba: pointer to lpfc hba data structure. |
15273 | * @rgn23_data: pointer to configure region 23 data. | ||
15257 | * | 15274 | * |
15258 | * This function read region 23 and parse TLV for port status to | 15275 | * This function gets SLI3 port configure region 23 data through memory dump |
15259 | * decide if the user disaled the port. If the TLV indicates the | 15276 | * mailbox command. When it successfully retrieves data, the size of the data |
15260 | * port is disabled, the hba_flag is set accordingly. | 15277 | * will be returned, otherwise, 0 will be returned. |
15261 | **/ | 15278 | **/ |
15262 | void | 15279 | static uint32_t |
15263 | lpfc_sli_read_link_ste(struct lpfc_hba *phba) | 15280 | lpfc_sli_get_config_region23(struct lpfc_hba *phba, char *rgn23_data) |
15264 | { | 15281 | { |
15265 | LPFC_MBOXQ_t *pmb = NULL; | 15282 | LPFC_MBOXQ_t *pmb = NULL; |
15266 | MAILBOX_t *mb; | 15283 | MAILBOX_t *mb; |
15267 | uint8_t *rgn23_data = NULL; | 15284 | uint32_t offset = 0; |
15268 | uint32_t offset = 0, data_size, sub_tlv_len, tlv_offset; | ||
15269 | int rc; | 15285 | int rc; |
15270 | 15286 | ||
15287 | if (!rgn23_data) | ||
15288 | return 0; | ||
15289 | |||
15271 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 15290 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
15272 | if (!pmb) { | 15291 | if (!pmb) { |
15273 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 15292 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
15274 | "2600 lpfc_sli_read_serdes_param failed to" | 15293 | "2600 failed to allocate mailbox memory\n"); |
15275 | " allocate mailbox memory\n"); | 15294 | return 0; |
15276 | goto out; | ||
15277 | } | 15295 | } |
15278 | mb = &pmb->u.mb; | 15296 | mb = &pmb->u.mb; |
15279 | 15297 | ||
15280 | /* Get adapter Region 23 data */ | ||
15281 | rgn23_data = kzalloc(DMP_RGN23_SIZE, GFP_KERNEL); | ||
15282 | if (!rgn23_data) | ||
15283 | goto out; | ||
15284 | |||
15285 | do { | 15298 | do { |
15286 | lpfc_dump_mem(phba, pmb, offset, DMP_REGION_23); | 15299 | lpfc_dump_mem(phba, pmb, offset, DMP_REGION_23); |
15287 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); | 15300 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); |
15288 | 15301 | ||
15289 | if (rc != MBX_SUCCESS) { | 15302 | if (rc != MBX_SUCCESS) { |
15290 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | 15303 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, |
15291 | "2601 lpfc_sli_read_link_ste failed to" | 15304 | "2601 failed to read config " |
15292 | " read config region 23 rc 0x%x Status 0x%x\n", | 15305 | "region 23, rc 0x%x Status 0x%x\n", |
15293 | rc, mb->mbxStatus); | 15306 | rc, mb->mbxStatus); |
15294 | mb->un.varDmp.word_cnt = 0; | 15307 | mb->un.varDmp.word_cnt = 0; |
15295 | } | 15308 | } |
15296 | /* | 15309 | /* |
@@ -15303,13 +15316,96 @@ lpfc_sli_read_link_ste(struct lpfc_hba *phba) | |||
15303 | mb->un.varDmp.word_cnt = DMP_RGN23_SIZE - offset; | 15316 | mb->un.varDmp.word_cnt = DMP_RGN23_SIZE - offset; |
15304 | 15317 | ||
15305 | lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET, | 15318 | lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET, |
15306 | rgn23_data + offset, | 15319 | rgn23_data + offset, |
15307 | mb->un.varDmp.word_cnt); | 15320 | mb->un.varDmp.word_cnt); |
15308 | offset += mb->un.varDmp.word_cnt; | 15321 | offset += mb->un.varDmp.word_cnt; |
15309 | } while (mb->un.varDmp.word_cnt && offset < DMP_RGN23_SIZE); | 15322 | } while (mb->un.varDmp.word_cnt && offset < DMP_RGN23_SIZE); |
15310 | 15323 | ||
15311 | data_size = offset; | 15324 | mempool_free(pmb, phba->mbox_mem_pool); |
15312 | offset = 0; | 15325 | return offset; |
15326 | } | ||
15327 | |||
15328 | /** | ||
15329 | * lpfc_sli4_get_config_region23 - Get sli4 port region 23 data. | ||
15330 | * @phba: pointer to lpfc hba data structure. | ||
15331 | * @rgn23_data: pointer to configure region 23 data. | ||
15332 | * | ||
15333 | * This function gets SLI4 port configure region 23 data through memory dump | ||
15334 | * mailbox command. When it successfully retrieves data, the size of the data | ||
15335 | * will be returned, otherwise, 0 will be returned. | ||
15336 | **/ | ||
15337 | static uint32_t | ||
15338 | lpfc_sli4_get_config_region23(struct lpfc_hba *phba, char *rgn23_data) | ||
15339 | { | ||
15340 | LPFC_MBOXQ_t *mboxq = NULL; | ||
15341 | struct lpfc_dmabuf *mp = NULL; | ||
15342 | struct lpfc_mqe *mqe; | ||
15343 | uint32_t data_length = 0; | ||
15344 | int rc; | ||
15345 | |||
15346 | if (!rgn23_data) | ||
15347 | return 0; | ||
15348 | |||
15349 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
15350 | if (!mboxq) { | ||
15351 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
15352 | "3105 failed to allocate mailbox memory\n"); | ||
15353 | return 0; | ||
15354 | } | ||
15355 | |||
15356 | if (lpfc_sli4_dump_cfg_rg23(phba, mboxq)) | ||
15357 | goto out; | ||
15358 | mqe = &mboxq->u.mqe; | ||
15359 | mp = (struct lpfc_dmabuf *) mboxq->context1; | ||
15360 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
15361 | if (rc) | ||
15362 | goto out; | ||
15363 | data_length = mqe->un.mb_words[5]; | ||
15364 | if (data_length == 0) | ||
15365 | goto out; | ||
15366 | if (data_length > DMP_RGN23_SIZE) { | ||
15367 | data_length = 0; | ||
15368 | goto out; | ||
15369 | } | ||
15370 | lpfc_sli_pcimem_bcopy((char *)mp->virt, rgn23_data, data_length); | ||
15371 | out: | ||
15372 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
15373 | if (mp) { | ||
15374 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
15375 | kfree(mp); | ||
15376 | } | ||
15377 | return data_length; | ||
15378 | } | ||
15379 | |||
15380 | /** | ||
15381 | * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled. | ||
15382 | * @phba: pointer to lpfc hba data structure. | ||
15383 | * | ||
15384 | * This function read region 23 and parse TLV for port status to | ||
15385 | * decide if the user disaled the port. If the TLV indicates the | ||
15386 | * port is disabled, the hba_flag is set accordingly. | ||
15387 | **/ | ||
15388 | void | ||
15389 | lpfc_sli_read_link_ste(struct lpfc_hba *phba) | ||
15390 | { | ||
15391 | uint8_t *rgn23_data = NULL; | ||
15392 | uint32_t if_type, data_size, sub_tlv_len, tlv_offset; | ||
15393 | uint32_t offset = 0; | ||
15394 | |||
15395 | /* Get adapter Region 23 data */ | ||
15396 | rgn23_data = kzalloc(DMP_RGN23_SIZE, GFP_KERNEL); | ||
15397 | if (!rgn23_data) | ||
15398 | goto out; | ||
15399 | |||
15400 | if (phba->sli_rev < LPFC_SLI_REV4) | ||
15401 | data_size = lpfc_sli_get_config_region23(phba, rgn23_data); | ||
15402 | else { | ||
15403 | if_type = bf_get(lpfc_sli_intf_if_type, | ||
15404 | &phba->sli4_hba.sli_intf); | ||
15405 | if (if_type == LPFC_SLI_INTF_IF_TYPE_0) | ||
15406 | goto out; | ||
15407 | data_size = lpfc_sli4_get_config_region23(phba, rgn23_data); | ||
15408 | } | ||
15313 | 15409 | ||
15314 | if (!data_size) | 15410 | if (!data_size) |
15315 | goto out; | 15411 | goto out; |
@@ -15373,9 +15469,8 @@ lpfc_sli_read_link_ste(struct lpfc_hba *phba) | |||
15373 | goto out; | 15469 | goto out; |
15374 | } | 15470 | } |
15375 | } | 15471 | } |
15472 | |||
15376 | out: | 15473 | out: |
15377 | if (pmb) | ||
15378 | mempool_free(pmb, phba->mbox_mem_pool); | ||
15379 | kfree(rgn23_data); | 15474 | kfree(rgn23_data); |
15380 | return; | 15475 | return; |
15381 | } | 15476 | } |