diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 21:57:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 21:57:35 -0400 |
commit | 97d41e90fe61399b99d74820cb7f2d6e0fbac91d (patch) | |
tree | f759371424a26963b04badbb4433e360be4e8750 /drivers/scsi/qla2xxx | |
parent | 3bdc9d0b408e01c4e556daba0035ba37f603e920 (diff) | |
parent | afaf5a2d341d33b66b47c2716a263ce593460a08 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (54 commits)
[SCSI] Initial Commit of qla4xxx
[SCSI] raid class: handle component-add errors
[SCSI] SCSI megaraid_sas: handle thrown errors
[SCSI] SCSI aic94xx: handle sysfs errors
[SCSI] SCSI st: fix error handling in module init, sysfs
[SCSI] SCSI sd: fix module init/exit error handling
[SCSI] SCSI osst: add error handling to module init, sysfs
[SCSI] scsi: remove hosts.h
[SCSI] scsi: Scsi_Cmnd convertion in aic7xxx_old.c
[SCSI] megaraid_sas: sets ioctl timeout and updates version,changelog
[SCSI] megaraid_sas: adds tasklet for cmd completion
[SCSI] megaraid_sas: prints pending cmds before setting hw_crit_error
[SCSI] megaraid_sas: function pointer for disable interrupt
[SCSI] megaraid_sas: frame count optimization
[SCSI] megaraid_sas: FW transition and q size changes
[SCSI] qla2xxx: Update version number to 8.01.07-k2.
[SCSI] qla2xxx: Stall mid-layer error handlers while rport is blocked.
[SCSI] qla2xxx: Add MODULE_FIRMWARE tags.
[SCSI] qla2xxx: Add support for host port state FC transport attribute.
[SCSI] qla2xxx: Add support for fabric name FC transport attribute.
...
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 57 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 40 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 9 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gs.c | 228 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 84 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 86 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 48 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_version.h | 2 |
9 files changed, 524 insertions, 34 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 87f90c4f08e9..ee75a71f3c66 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -691,13 +691,13 @@ qla2x00_get_host_speed(struct Scsi_Host *shost) | |||
691 | uint32_t speed = 0; | 691 | uint32_t speed = 0; |
692 | 692 | ||
693 | switch (ha->link_data_rate) { | 693 | switch (ha->link_data_rate) { |
694 | case LDR_1GB: | 694 | case PORT_SPEED_1GB: |
695 | speed = 1; | 695 | speed = 1; |
696 | break; | 696 | break; |
697 | case LDR_2GB: | 697 | case PORT_SPEED_2GB: |
698 | speed = 2; | 698 | speed = 2; |
699 | break; | 699 | break; |
700 | case LDR_4GB: | 700 | case PORT_SPEED_4GB: |
701 | speed = 4; | 701 | speed = 4; |
702 | break; | 702 | break; |
703 | } | 703 | } |
@@ -849,6 +849,49 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | |||
849 | return pfc_host_stat; | 849 | return pfc_host_stat; |
850 | } | 850 | } |
851 | 851 | ||
852 | static void | ||
853 | qla2x00_get_host_symbolic_name(struct Scsi_Host *shost) | ||
854 | { | ||
855 | scsi_qla_host_t *ha = to_qla_host(shost); | ||
856 | |||
857 | qla2x00_get_sym_node_name(ha, fc_host_symbolic_name(shost)); | ||
858 | } | ||
859 | |||
860 | static void | ||
861 | qla2x00_set_host_system_hostname(struct Scsi_Host *shost) | ||
862 | { | ||
863 | scsi_qla_host_t *ha = to_qla_host(shost); | ||
864 | |||
865 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | ||
866 | } | ||
867 | |||
868 | static void | ||
869 | qla2x00_get_host_fabric_name(struct Scsi_Host *shost) | ||
870 | { | ||
871 | scsi_qla_host_t *ha = to_qla_host(shost); | ||
872 | u64 node_name; | ||
873 | |||
874 | if (ha->device_flags & SWITCH_FOUND) | ||
875 | node_name = wwn_to_u64(ha->fabric_node_name); | ||
876 | else | ||
877 | node_name = wwn_to_u64(ha->node_name); | ||
878 | |||
879 | fc_host_fabric_name(shost) = node_name; | ||
880 | } | ||
881 | |||
882 | static void | ||
883 | qla2x00_get_host_port_state(struct Scsi_Host *shost) | ||
884 | { | ||
885 | scsi_qla_host_t *ha = to_qla_host(shost); | ||
886 | |||
887 | if (!ha->flags.online) | ||
888 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; | ||
889 | else if (atomic_read(&ha->loop_state) == LOOP_TIMEOUT) | ||
890 | fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; | ||
891 | else | ||
892 | fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; | ||
893 | } | ||
894 | |||
852 | struct fc_function_template qla2xxx_transport_functions = { | 895 | struct fc_function_template qla2xxx_transport_functions = { |
853 | 896 | ||
854 | .show_host_node_name = 1, | 897 | .show_host_node_name = 1, |
@@ -861,6 +904,14 @@ struct fc_function_template qla2xxx_transport_functions = { | |||
861 | .show_host_speed = 1, | 904 | .show_host_speed = 1, |
862 | .get_host_port_type = qla2x00_get_host_port_type, | 905 | .get_host_port_type = qla2x00_get_host_port_type, |
863 | .show_host_port_type = 1, | 906 | .show_host_port_type = 1, |
907 | .get_host_symbolic_name = qla2x00_get_host_symbolic_name, | ||
908 | .show_host_symbolic_name = 1, | ||
909 | .set_host_system_hostname = qla2x00_set_host_system_hostname, | ||
910 | .show_host_system_hostname = 1, | ||
911 | .get_host_fabric_name = qla2x00_get_host_fabric_name, | ||
912 | .show_host_fabric_name = 1, | ||
913 | .get_host_port_state = qla2x00_get_host_port_state, | ||
914 | .show_host_port_state = 1, | ||
864 | 915 | ||
865 | .dd_fcrport_size = sizeof(struct fc_port *), | 916 | .dd_fcrport_size = sizeof(struct fc_port *), |
866 | .show_rport_supported_classes = 1, | 917 | .show_rport_supported_classes = 1, |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 0930260aec2c..c37a30aa2146 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -608,6 +608,7 @@ typedef struct { | |||
608 | */ | 608 | */ |
609 | #define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */ | 609 | #define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */ |
610 | #define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */ | 610 | #define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */ |
611 | #define MBC_PORT_PARAMS 0x1A /* Port iDMA Parameters. */ | ||
611 | #define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ | 612 | #define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ |
612 | #define MBC_TRACE_CONTROL 0x27 /* Trace control command. */ | 613 | #define MBC_TRACE_CONTROL 0x27 /* Trace control command. */ |
613 | #define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ | 614 | #define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ |
@@ -1497,6 +1498,9 @@ typedef struct { | |||
1497 | port_id_t d_id; | 1498 | port_id_t d_id; |
1498 | uint8_t node_name[WWN_SIZE]; | 1499 | uint8_t node_name[WWN_SIZE]; |
1499 | uint8_t port_name[WWN_SIZE]; | 1500 | uint8_t port_name[WWN_SIZE]; |
1501 | uint8_t fabric_port_name[WWN_SIZE]; | ||
1502 | uint16_t fp_speeds; | ||
1503 | uint16_t fp_speed; | ||
1500 | } sw_info_t; | 1504 | } sw_info_t; |
1501 | 1505 | ||
1502 | /* | 1506 | /* |
@@ -1524,6 +1528,9 @@ typedef struct fc_port { | |||
1524 | uint16_t loop_id; | 1528 | uint16_t loop_id; |
1525 | uint16_t old_loop_id; | 1529 | uint16_t old_loop_id; |
1526 | 1530 | ||
1531 | uint8_t fabric_port_name[WWN_SIZE]; | ||
1532 | uint16_t fp_speed; | ||
1533 | |||
1527 | fc_port_type_t port_type; | 1534 | fc_port_type_t port_type; |
1528 | 1535 | ||
1529 | atomic_t state; | 1536 | atomic_t state; |
@@ -1635,6 +1642,15 @@ typedef struct fc_port { | |||
1635 | #define RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255) | 1642 | #define RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255) |
1636 | #define RSNN_NN_RSP_SIZE 16 | 1643 | #define RSNN_NN_RSP_SIZE 16 |
1637 | 1644 | ||
1645 | #define GFPN_ID_CMD 0x11C | ||
1646 | #define GFPN_ID_REQ_SIZE (16 + 4) | ||
1647 | #define GFPN_ID_RSP_SIZE (16 + 8) | ||
1648 | |||
1649 | #define GPSC_CMD 0x127 | ||
1650 | #define GPSC_REQ_SIZE (16 + 8) | ||
1651 | #define GPSC_RSP_SIZE (16 + 2 + 2) | ||
1652 | |||
1653 | |||
1638 | /* | 1654 | /* |
1639 | * HBA attribute types. | 1655 | * HBA attribute types. |
1640 | */ | 1656 | */ |
@@ -1748,7 +1764,7 @@ struct ct_sns_req { | |||
1748 | uint8_t reserved[3]; | 1764 | uint8_t reserved[3]; |
1749 | 1765 | ||
1750 | union { | 1766 | union { |
1751 | /* GA_NXT, GPN_ID, GNN_ID, GFT_ID */ | 1767 | /* GA_NXT, GPN_ID, GNN_ID, GFT_ID, GFPN_ID */ |
1752 | struct { | 1768 | struct { |
1753 | uint8_t reserved; | 1769 | uint8_t reserved; |
1754 | uint8_t port_id[3]; | 1770 | uint8_t port_id[3]; |
@@ -1823,6 +1839,10 @@ struct ct_sns_req { | |||
1823 | struct { | 1839 | struct { |
1824 | uint8_t port_name[8]; | 1840 | uint8_t port_name[8]; |
1825 | } dpa; | 1841 | } dpa; |
1842 | |||
1843 | struct { | ||
1844 | uint8_t port_name[8]; | ||
1845 | } gpsc; | ||
1826 | } req; | 1846 | } req; |
1827 | }; | 1847 | }; |
1828 | 1848 | ||
@@ -1886,6 +1906,15 @@ struct ct_sns_rsp { | |||
1886 | uint8_t port_name[8]; | 1906 | uint8_t port_name[8]; |
1887 | struct ct_fdmi_hba_attributes attrs; | 1907 | struct ct_fdmi_hba_attributes attrs; |
1888 | } ghat; | 1908 | } ghat; |
1909 | |||
1910 | struct { | ||
1911 | uint8_t port_name[8]; | ||
1912 | } gfpn_id; | ||
1913 | |||
1914 | struct { | ||
1915 | uint16_t speeds; | ||
1916 | uint16_t speed; | ||
1917 | } gpsc; | ||
1889 | } rsp; | 1918 | } rsp; |
1890 | }; | 1919 | }; |
1891 | 1920 | ||
@@ -2182,11 +2211,11 @@ typedef struct scsi_qla_host { | |||
2182 | uint16_t max_public_loop_ids; | 2211 | uint16_t max_public_loop_ids; |
2183 | uint16_t min_external_loopid; /* First external loop Id */ | 2212 | uint16_t min_external_loopid; /* First external loop Id */ |
2184 | 2213 | ||
2214 | #define PORT_SPEED_UNKNOWN 0xFFFF | ||
2215 | #define PORT_SPEED_1GB 0x00 | ||
2216 | #define PORT_SPEED_2GB 0x01 | ||
2217 | #define PORT_SPEED_4GB 0x03 | ||
2185 | uint16_t link_data_rate; /* F/W operating speed */ | 2218 | uint16_t link_data_rate; /* F/W operating speed */ |
2186 | #define LDR_1GB 0 | ||
2187 | #define LDR_2GB 1 | ||
2188 | #define LDR_4GB 3 | ||
2189 | #define LDR_UNKNOWN 0xFFFF | ||
2190 | 2219 | ||
2191 | uint8_t current_topology; | 2220 | uint8_t current_topology; |
2192 | uint8_t prev_topology; | 2221 | uint8_t prev_topology; |
@@ -2333,6 +2362,7 @@ typedef struct scsi_qla_host { | |||
2333 | 2362 | ||
2334 | uint8_t *node_name; | 2363 | uint8_t *node_name; |
2335 | uint8_t *port_name; | 2364 | uint8_t *port_name; |
2365 | uint8_t fabric_node_name[WWN_SIZE]; | ||
2336 | uint32_t isp_abort_cnt; | 2366 | uint32_t isp_abort_cnt; |
2337 | 2367 | ||
2338 | /* Option ROM information. */ | 2368 | /* Option ROM information. */ |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 8311ac2b93a8..bef7011378c6 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -208,6 +208,12 @@ qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t); | |||
208 | extern int | 208 | extern int |
209 | qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); | 209 | qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); |
210 | 210 | ||
211 | extern int | ||
212 | qla2x00_get_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t *, uint16_t *); | ||
213 | |||
214 | extern int | ||
215 | qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *); | ||
216 | |||
211 | /* | 217 | /* |
212 | * Global Function Prototypes in qla_isr.c source file. | 218 | * Global Function Prototypes in qla_isr.c source file. |
213 | */ | 219 | */ |
@@ -279,6 +285,9 @@ extern int qla2x00_rsnn_nn(scsi_qla_host_t *); | |||
279 | extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); | 285 | extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); |
280 | extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); | 286 | extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); |
281 | extern int qla2x00_fdmi_register(scsi_qla_host_t *); | 287 | extern int qla2x00_fdmi_register(scsi_qla_host_t *); |
288 | extern int qla2x00_gfpn_id(scsi_qla_host_t *, sw_info_t *); | ||
289 | extern int qla2x00_gpsc(scsi_qla_host_t *, sw_info_t *); | ||
290 | extern void qla2x00_get_sym_node_name(scsi_qla_host_t *, uint8_t *); | ||
282 | 291 | ||
283 | /* | 292 | /* |
284 | * Global Function Prototypes in qla_attr.c source file. | 293 | * Global Function Prototypes in qla_attr.c source file. |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 2ebf259fccb2..97fbc62ec669 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
@@ -612,6 +612,14 @@ qla2x00_rnn_id(scsi_qla_host_t *ha) | |||
612 | return (rval); | 612 | return (rval); |
613 | } | 613 | } |
614 | 614 | ||
615 | void | ||
616 | qla2x00_get_sym_node_name(scsi_qla_host_t *ha, uint8_t *snn) | ||
617 | { | ||
618 | sprintf(snn, "%s FW:v%d.%02d.%02d DVR:v%s",ha->model_number, | ||
619 | ha->fw_major_version, ha->fw_minor_version, | ||
620 | ha->fw_subminor_version, qla2x00_version_str); | ||
621 | } | ||
622 | |||
615 | /** | 623 | /** |
616 | * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA. | 624 | * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA. |
617 | * @ha: HA context | 625 | * @ha: HA context |
@@ -622,9 +630,6 @@ int | |||
622 | qla2x00_rsnn_nn(scsi_qla_host_t *ha) | 630 | qla2x00_rsnn_nn(scsi_qla_host_t *ha) |
623 | { | 631 | { |
624 | int rval; | 632 | int rval; |
625 | uint8_t *snn; | ||
626 | uint8_t version[20]; | ||
627 | |||
628 | ms_iocb_entry_t *ms_pkt; | 633 | ms_iocb_entry_t *ms_pkt; |
629 | struct ct_sns_req *ct_req; | 634 | struct ct_sns_req *ct_req; |
630 | struct ct_sns_rsp *ct_rsp; | 635 | struct ct_sns_rsp *ct_rsp; |
@@ -649,20 +654,11 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha) | |||
649 | memcpy(ct_req->req.rsnn_nn.node_name, ha->node_name, WWN_SIZE); | 654 | memcpy(ct_req->req.rsnn_nn.node_name, ha->node_name, WWN_SIZE); |
650 | 655 | ||
651 | /* Prepare the Symbolic Node Name */ | 656 | /* Prepare the Symbolic Node Name */ |
652 | /* Board type */ | 657 | qla2x00_get_sym_node_name(ha, ct_req->req.rsnn_nn.sym_node_name); |
653 | snn = ct_req->req.rsnn_nn.sym_node_name; | ||
654 | strcpy(snn, ha->model_number); | ||
655 | /* Firmware version */ | ||
656 | strcat(snn, " FW:v"); | ||
657 | sprintf(version, "%d.%02d.%02d", ha->fw_major_version, | ||
658 | ha->fw_minor_version, ha->fw_subminor_version); | ||
659 | strcat(snn, version); | ||
660 | /* Driver version */ | ||
661 | strcat(snn, " DVR:v"); | ||
662 | strcat(snn, qla2x00_version_str); | ||
663 | 658 | ||
664 | /* Calculate SNN length */ | 659 | /* Calculate SNN length */ |
665 | ct_req->req.rsnn_nn.name_len = (uint8_t)strlen(snn); | 660 | ct_req->req.rsnn_nn.name_len = |
661 | (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name); | ||
666 | 662 | ||
667 | /* Update MS IOCB request */ | 663 | /* Update MS IOCB request */ |
668 | ms_pkt->req_bytecount = | 664 | ms_pkt->req_bytecount = |
@@ -687,7 +683,6 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha) | |||
687 | return (rval); | 683 | return (rval); |
688 | } | 684 | } |
689 | 685 | ||
690 | |||
691 | /** | 686 | /** |
692 | * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query. | 687 | * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query. |
693 | * @ha: HA context | 688 | * @ha: HA context |
@@ -1585,6 +1580,21 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) | |||
1585 | DEBUG13(printk("%s(%ld): OS_DEVICE_NAME=%s.\n", __func__, ha->host_no, | 1580 | DEBUG13(printk("%s(%ld): OS_DEVICE_NAME=%s.\n", __func__, ha->host_no, |
1586 | eiter->a.os_dev_name)); | 1581 | eiter->a.os_dev_name)); |
1587 | 1582 | ||
1583 | /* Hostname. */ | ||
1584 | if (strlen(fc_host_system_hostname(ha->host))) { | ||
1585 | eiter = (struct ct_fdmi_port_attr *) (entries + size); | ||
1586 | eiter->type = __constant_cpu_to_be16(FDMI_PORT_HOST_NAME); | ||
1587 | snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), | ||
1588 | "%s", fc_host_system_hostname(ha->host)); | ||
1589 | alen = strlen(eiter->a.host_name); | ||
1590 | alen += (alen & 3) ? (4 - (alen & 3)) : 4; | ||
1591 | eiter->len = cpu_to_be16(4 + alen); | ||
1592 | size += 4 + alen; | ||
1593 | |||
1594 | DEBUG13(printk("%s(%ld): HOSTNAME=%s.\n", __func__, | ||
1595 | ha->host_no, eiter->a.host_name)); | ||
1596 | } | ||
1597 | |||
1588 | /* Update MS request size. */ | 1598 | /* Update MS request size. */ |
1589 | qla2x00_update_ms_fdmi_iocb(ha, size + 16); | 1599 | qla2x00_update_ms_fdmi_iocb(ha, size + 16); |
1590 | 1600 | ||
@@ -1647,3 +1657,189 @@ qla2x00_fdmi_register(scsi_qla_host_t *ha) | |||
1647 | 1657 | ||
1648 | return rval; | 1658 | return rval; |
1649 | } | 1659 | } |
1660 | |||
1661 | /** | ||
1662 | * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query. | ||
1663 | * @ha: HA context | ||
1664 | * @list: switch info entries to populate | ||
1665 | * | ||
1666 | * Returns 0 on success. | ||
1667 | */ | ||
1668 | int | ||
1669 | qla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list) | ||
1670 | { | ||
1671 | int rval; | ||
1672 | uint16_t i; | ||
1673 | |||
1674 | ms_iocb_entry_t *ms_pkt; | ||
1675 | struct ct_sns_req *ct_req; | ||
1676 | struct ct_sns_rsp *ct_rsp; | ||
1677 | |||
1678 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
1679 | return QLA_FUNCTION_FAILED; | ||
1680 | |||
1681 | for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | ||
1682 | /* Issue GFPN_ID */ | ||
1683 | memset(list[i].fabric_port_name, 0, WWN_SIZE); | ||
1684 | |||
1685 | /* Prepare common MS IOCB */ | ||
1686 | ms_pkt = qla2x00_prep_ms_iocb(ha, GFPN_ID_REQ_SIZE, | ||
1687 | GFPN_ID_RSP_SIZE); | ||
1688 | |||
1689 | /* Prepare CT request */ | ||
1690 | ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD, | ||
1691 | GFPN_ID_RSP_SIZE); | ||
1692 | ct_rsp = &ha->ct_sns->p.rsp; | ||
1693 | |||
1694 | /* Prepare CT arguments -- port_id */ | ||
1695 | ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; | ||
1696 | ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; | ||
1697 | ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; | ||
1698 | |||
1699 | /* Execute MS IOCB */ | ||
1700 | rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, | ||
1701 | sizeof(ms_iocb_entry_t)); | ||
1702 | if (rval != QLA_SUCCESS) { | ||
1703 | /*EMPTY*/ | ||
1704 | DEBUG2_3(printk("scsi(%ld): GFPN_ID issue IOCB " | ||
1705 | "failed (%d).\n", ha->host_no, rval)); | ||
1706 | } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, | ||
1707 | "GFPN_ID") != QLA_SUCCESS) { | ||
1708 | rval = QLA_FUNCTION_FAILED; | ||
1709 | } else { | ||
1710 | /* Save fabric portname */ | ||
1711 | memcpy(list[i].fabric_port_name, | ||
1712 | ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE); | ||
1713 | } | ||
1714 | |||
1715 | /* Last device exit. */ | ||
1716 | if (list[i].d_id.b.rsvd_1 != 0) | ||
1717 | break; | ||
1718 | } | ||
1719 | |||
1720 | return (rval); | ||
1721 | } | ||
1722 | |||
1723 | static inline void * | ||
1724 | qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *ha, uint32_t req_size, | ||
1725 | uint32_t rsp_size) | ||
1726 | { | ||
1727 | struct ct_entry_24xx *ct_pkt; | ||
1728 | |||
1729 | ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; | ||
1730 | memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); | ||
1731 | |||
1732 | ct_pkt->entry_type = CT_IOCB_TYPE; | ||
1733 | ct_pkt->entry_count = 1; | ||
1734 | ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id); | ||
1735 | ct_pkt->timeout = __constant_cpu_to_le16(59); | ||
1736 | ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); | ||
1737 | ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); | ||
1738 | ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); | ||
1739 | ct_pkt->cmd_byte_count = cpu_to_le32(req_size); | ||
1740 | |||
1741 | ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | ||
1742 | ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | ||
1743 | ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; | ||
1744 | |||
1745 | ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | ||
1746 | ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | ||
1747 | ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; | ||
1748 | |||
1749 | return ct_pkt; | ||
1750 | } | ||
1751 | |||
1752 | |||
1753 | static inline struct ct_sns_req * | ||
1754 | qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd, | ||
1755 | uint16_t rsp_size) | ||
1756 | { | ||
1757 | memset(ct_req, 0, sizeof(struct ct_sns_pkt)); | ||
1758 | |||
1759 | ct_req->header.revision = 0x01; | ||
1760 | ct_req->header.gs_type = 0xFA; | ||
1761 | ct_req->header.gs_subtype = 0x01; | ||
1762 | ct_req->command = cpu_to_be16(cmd); | ||
1763 | ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); | ||
1764 | |||
1765 | return ct_req; | ||
1766 | } | ||
1767 | |||
1768 | /** | ||
1769 | * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query. | ||
1770 | * @ha: HA context | ||
1771 | * @list: switch info entries to populate | ||
1772 | * | ||
1773 | * Returns 0 on success. | ||
1774 | */ | ||
1775 | int | ||
1776 | qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list) | ||
1777 | { | ||
1778 | int rval; | ||
1779 | uint16_t i; | ||
1780 | |||
1781 | ms_iocb_entry_t *ms_pkt; | ||
1782 | struct ct_sns_req *ct_req; | ||
1783 | struct ct_sns_rsp *ct_rsp; | ||
1784 | |||
1785 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
1786 | return QLA_FUNCTION_FAILED; | ||
1787 | |||
1788 | rval = qla2x00_mgmt_svr_login(ha); | ||
1789 | if (rval) | ||
1790 | return rval; | ||
1791 | |||
1792 | for (i = 0; i < MAX_FIBRE_DEVICES; i++) { | ||
1793 | /* Issue GFPN_ID */ | ||
1794 | list[i].fp_speeds = list[i].fp_speed = 0; | ||
1795 | |||
1796 | /* Prepare common MS IOCB */ | ||
1797 | ms_pkt = qla24xx_prep_ms_fm_iocb(ha, GPSC_REQ_SIZE, | ||
1798 | GPSC_RSP_SIZE); | ||
1799 | |||
1800 | /* Prepare CT request */ | ||
1801 | ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req, | ||
1802 | GPSC_CMD, GPSC_RSP_SIZE); | ||
1803 | ct_rsp = &ha->ct_sns->p.rsp; | ||
1804 | |||
1805 | /* Prepare CT arguments -- port_name */ | ||
1806 | memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name, | ||
1807 | WWN_SIZE); | ||
1808 | |||
1809 | /* Execute MS IOCB */ | ||
1810 | rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, | ||
1811 | sizeof(ms_iocb_entry_t)); | ||
1812 | if (rval != QLA_SUCCESS) { | ||
1813 | /*EMPTY*/ | ||
1814 | DEBUG2_3(printk("scsi(%ld): GPSC issue IOCB " | ||
1815 | "failed (%d).\n", ha->host_no, rval)); | ||
1816 | } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, | ||
1817 | "GPSC") != QLA_SUCCESS) { | ||
1818 | rval = QLA_FUNCTION_FAILED; | ||
1819 | } else { | ||
1820 | /* Save portname */ | ||
1821 | list[i].fp_speeds = ct_rsp->rsp.gpsc.speeds; | ||
1822 | list[i].fp_speed = ct_rsp->rsp.gpsc.speed; | ||
1823 | |||
1824 | DEBUG2_3(printk("scsi(%ld): GPSC ext entry - " | ||
1825 | "fpn %02x%02x%02x%02x%02x%02x%02x%02x speeds=%04x " | ||
1826 | "speed=%04x.\n", ha->host_no, | ||
1827 | list[i].fabric_port_name[0], | ||
1828 | list[i].fabric_port_name[1], | ||
1829 | list[i].fabric_port_name[2], | ||
1830 | list[i].fabric_port_name[3], | ||
1831 | list[i].fabric_port_name[4], | ||
1832 | list[i].fabric_port_name[5], | ||
1833 | list[i].fabric_port_name[6], | ||
1834 | list[i].fabric_port_name[7], | ||
1835 | be16_to_cpu(list[i].fp_speeds), | ||
1836 | be16_to_cpu(list[i].fp_speed))); | ||
1837 | } | ||
1838 | |||
1839 | /* Last device exit. */ | ||
1840 | if (list[i].d_id.b.rsvd_1 != 0) | ||
1841 | break; | ||
1842 | } | ||
1843 | |||
1844 | return (rval); | ||
1845 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 859649160caa..d5d26273c04e 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -2074,6 +2074,19 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha) | |||
2074 | new_fcport->flags &= ~FCF_FABRIC_DEVICE; | 2074 | new_fcport->flags &= ~FCF_FABRIC_DEVICE; |
2075 | } | 2075 | } |
2076 | 2076 | ||
2077 | /* Base iIDMA settings on HBA port speed. */ | ||
2078 | switch (ha->link_data_rate) { | ||
2079 | case PORT_SPEED_1GB: | ||
2080 | fcport->fp_speed = cpu_to_be16(BIT_15); | ||
2081 | break; | ||
2082 | case PORT_SPEED_2GB: | ||
2083 | fcport->fp_speed = cpu_to_be16(BIT_14); | ||
2084 | break; | ||
2085 | case PORT_SPEED_4GB: | ||
2086 | fcport->fp_speed = cpu_to_be16(BIT_13); | ||
2087 | break; | ||
2088 | } | ||
2089 | |||
2077 | qla2x00_update_fcport(ha, fcport); | 2090 | qla2x00_update_fcport(ha, fcport); |
2078 | 2091 | ||
2079 | found_devs++; | 2092 | found_devs++; |
@@ -2109,6 +2122,62 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha) | |||
2109 | } | 2122 | } |
2110 | } | 2123 | } |
2111 | 2124 | ||
2125 | static void | ||
2126 | qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) | ||
2127 | { | ||
2128 | #define LS_UNKNOWN 2 | ||
2129 | static char *link_speeds[5] = { "1", "2", "?", "4" }; | ||
2130 | int rval; | ||
2131 | uint16_t port_speed, mb[6]; | ||
2132 | |||
2133 | if (!IS_QLA24XX(ha)) | ||
2134 | return; | ||
2135 | |||
2136 | switch (be16_to_cpu(fcport->fp_speed)) { | ||
2137 | case BIT_15: | ||
2138 | port_speed = PORT_SPEED_1GB; | ||
2139 | break; | ||
2140 | case BIT_14: | ||
2141 | port_speed = PORT_SPEED_2GB; | ||
2142 | break; | ||
2143 | case BIT_13: | ||
2144 | port_speed = PORT_SPEED_4GB; | ||
2145 | break; | ||
2146 | default: | ||
2147 | DEBUG2(printk("scsi(%ld): %02x%02x%02x%02x%02x%02x%02x%02x -- " | ||
2148 | "unsupported FM port operating speed (%04x).\n", | ||
2149 | ha->host_no, fcport->port_name[0], fcport->port_name[1], | ||
2150 | fcport->port_name[2], fcport->port_name[3], | ||
2151 | fcport->port_name[4], fcport->port_name[5], | ||
2152 | fcport->port_name[6], fcport->port_name[7], | ||
2153 | be16_to_cpu(fcport->fp_speed))); | ||
2154 | port_speed = PORT_SPEED_UNKNOWN; | ||
2155 | break; | ||
2156 | } | ||
2157 | if (port_speed == PORT_SPEED_UNKNOWN) | ||
2158 | return; | ||
2159 | |||
2160 | rval = qla2x00_set_idma_speed(ha, fcport->loop_id, port_speed, mb); | ||
2161 | if (rval != QLA_SUCCESS) { | ||
2162 | DEBUG2(printk("scsi(%ld): Unable to adjust iIDMA " | ||
2163 | "%02x%02x%02x%02x%02x%02x%02x%02x -- %04x %x %04x %04x.\n", | ||
2164 | ha->host_no, fcport->port_name[0], fcport->port_name[1], | ||
2165 | fcport->port_name[2], fcport->port_name[3], | ||
2166 | fcport->port_name[4], fcport->port_name[5], | ||
2167 | fcport->port_name[6], fcport->port_name[7], rval, | ||
2168 | port_speed, mb[0], mb[1])); | ||
2169 | } else { | ||
2170 | DEBUG2(qla_printk(KERN_INFO, ha, | ||
2171 | "iIDMA adjusted to %s GB/s on " | ||
2172 | "%02x%02x%02x%02x%02x%02x%02x%02x.\n", | ||
2173 | link_speeds[port_speed], fcport->port_name[0], | ||
2174 | fcport->port_name[1], fcport->port_name[2], | ||
2175 | fcport->port_name[3], fcport->port_name[4], | ||
2176 | fcport->port_name[5], fcport->port_name[6], | ||
2177 | fcport->port_name[7])); | ||
2178 | } | ||
2179 | } | ||
2180 | |||
2112 | /* | 2181 | /* |
2113 | * qla2x00_update_fcport | 2182 | * qla2x00_update_fcport |
2114 | * Updates device on list. | 2183 | * Updates device on list. |
@@ -2135,6 +2204,8 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
2135 | PORT_RETRY_TIME); | 2204 | PORT_RETRY_TIME); |
2136 | fcport->flags &= ~FCF_LOGIN_NEEDED; | 2205 | fcport->flags &= ~FCF_LOGIN_NEEDED; |
2137 | 2206 | ||
2207 | qla2x00_iidma_fcport(ha, fcport); | ||
2208 | |||
2138 | atomic_set(&fcport->state, FCS_ONLINE); | 2209 | atomic_set(&fcport->state, FCS_ONLINE); |
2139 | 2210 | ||
2140 | if (ha->flags.init_done) | 2211 | if (ha->flags.init_done) |
@@ -2209,7 +2280,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) | |||
2209 | loop_id = NPH_F_PORT; | 2280 | loop_id = NPH_F_PORT; |
2210 | else | 2281 | else |
2211 | loop_id = SNS_FL_PORT; | 2282 | loop_id = SNS_FL_PORT; |
2212 | rval = qla2x00_get_port_name(ha, loop_id, NULL, 0); | 2283 | rval = qla2x00_get_port_name(ha, loop_id, ha->fabric_node_name, 1); |
2213 | if (rval != QLA_SUCCESS) { | 2284 | if (rval != QLA_SUCCESS) { |
2214 | DEBUG2(printk("scsi(%ld): MBC_GET_PORT_NAME Failed, No FL " | 2285 | DEBUG2(printk("scsi(%ld): MBC_GET_PORT_NAME Failed, No FL " |
2215 | "Port\n", ha->host_no)); | 2286 | "Port\n", ha->host_no)); |
@@ -2217,6 +2288,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) | |||
2217 | ha->device_flags &= ~SWITCH_FOUND; | 2288 | ha->device_flags &= ~SWITCH_FOUND; |
2218 | return (QLA_SUCCESS); | 2289 | return (QLA_SUCCESS); |
2219 | } | 2290 | } |
2291 | ha->device_flags |= SWITCH_FOUND; | ||
2220 | 2292 | ||
2221 | /* Mark devices that need re-synchronization. */ | 2293 | /* Mark devices that need re-synchronization. */ |
2222 | rval2 = qla2x00_device_resync(ha); | 2294 | rval2 = qla2x00_device_resync(ha); |
@@ -2416,6 +2488,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
2416 | } else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) { | 2488 | } else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) { |
2417 | kfree(swl); | 2489 | kfree(swl); |
2418 | swl = NULL; | 2490 | swl = NULL; |
2491 | } else if (qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) { | ||
2492 | qla2x00_gpsc(ha, swl); | ||
2419 | } | 2493 | } |
2420 | } | 2494 | } |
2421 | swl_idx = 0; | 2495 | swl_idx = 0; |
@@ -2450,6 +2524,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
2450 | swl[swl_idx].node_name, WWN_SIZE); | 2524 | swl[swl_idx].node_name, WWN_SIZE); |
2451 | memcpy(new_fcport->port_name, | 2525 | memcpy(new_fcport->port_name, |
2452 | swl[swl_idx].port_name, WWN_SIZE); | 2526 | swl[swl_idx].port_name, WWN_SIZE); |
2527 | memcpy(new_fcport->fabric_port_name, | ||
2528 | swl[swl_idx].fabric_port_name, WWN_SIZE); | ||
2529 | new_fcport->fp_speed = swl[swl_idx].fp_speed; | ||
2453 | 2530 | ||
2454 | if (swl[swl_idx].d_id.b.rsvd_1 != 0) { | 2531 | if (swl[swl_idx].d_id.b.rsvd_1 != 0) { |
2455 | last_dev = 1; | 2532 | last_dev = 1; |
@@ -2507,6 +2584,11 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
2507 | 2584 | ||
2508 | found++; | 2585 | found++; |
2509 | 2586 | ||
2587 | /* Update port state. */ | ||
2588 | memcpy(fcport->fabric_port_name, | ||
2589 | new_fcport->fabric_port_name, WWN_SIZE); | ||
2590 | fcport->fp_speed = new_fcport->fp_speed; | ||
2591 | |||
2510 | /* | 2592 | /* |
2511 | * If address the same and state FCS_ONLINE, nothing | 2593 | * If address the same and state FCS_ONLINE, nothing |
2512 | * changed. | 2594 | * changed. |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index de0613135f70..5fa933cda992 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -400,7 +400,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
400 | case MBA_LOOP_UP: /* Loop Up Event */ | 400 | case MBA_LOOP_UP: /* Loop Up Event */ |
401 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | 401 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { |
402 | link_speed = link_speeds[0]; | 402 | link_speed = link_speeds[0]; |
403 | ha->link_data_rate = LDR_1GB; | 403 | ha->link_data_rate = PORT_SPEED_1GB; |
404 | } else { | 404 | } else { |
405 | link_speed = link_speeds[LS_UNKNOWN]; | 405 | link_speed = link_speeds[LS_UNKNOWN]; |
406 | if (mb[1] < 5) | 406 | if (mb[1] < 5) |
@@ -429,7 +429,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
429 | } | 429 | } |
430 | 430 | ||
431 | ha->flags.management_server_logged_in = 0; | 431 | ha->flags.management_server_logged_in = 0; |
432 | ha->link_data_rate = LDR_UNKNOWN; | 432 | ha->link_data_rate = PORT_SPEED_UNKNOWN; |
433 | if (ql2xfdmienable) | 433 | if (ql2xfdmienable) |
434 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 434 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); |
435 | break; | 435 | break; |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 879f281e2ea2..4cde76c85cb3 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -2540,3 +2540,89 @@ qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr, | |||
2540 | 2540 | ||
2541 | return rval; | 2541 | return rval; |
2542 | } | 2542 | } |
2543 | |||
2544 | int | ||
2545 | qla2x00_get_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id, | ||
2546 | uint16_t *port_speed, uint16_t *mb) | ||
2547 | { | ||
2548 | int rval; | ||
2549 | mbx_cmd_t mc; | ||
2550 | mbx_cmd_t *mcp = &mc; | ||
2551 | |||
2552 | if (!IS_QLA24XX(ha)) | ||
2553 | return QLA_FUNCTION_FAILED; | ||
2554 | |||
2555 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
2556 | |||
2557 | mcp->mb[0] = MBC_PORT_PARAMS; | ||
2558 | mcp->mb[1] = loop_id; | ||
2559 | mcp->mb[2] = mcp->mb[3] = mcp->mb[4] = mcp->mb[5] = 0; | ||
2560 | mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | ||
2561 | mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; | ||
2562 | mcp->tov = 30; | ||
2563 | mcp->flags = 0; | ||
2564 | rval = qla2x00_mailbox_command(ha, mcp); | ||
2565 | |||
2566 | /* Return mailbox statuses. */ | ||
2567 | if (mb != NULL) { | ||
2568 | mb[0] = mcp->mb[0]; | ||
2569 | mb[1] = mcp->mb[1]; | ||
2570 | mb[3] = mcp->mb[3]; | ||
2571 | mb[4] = mcp->mb[4]; | ||
2572 | mb[5] = mcp->mb[5]; | ||
2573 | } | ||
2574 | |||
2575 | if (rval != QLA_SUCCESS) { | ||
2576 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, | ||
2577 | ha->host_no, rval)); | ||
2578 | } else { | ||
2579 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
2580 | if (port_speed) | ||
2581 | *port_speed = mcp->mb[3]; | ||
2582 | } | ||
2583 | |||
2584 | return rval; | ||
2585 | } | ||
2586 | |||
2587 | int | ||
2588 | qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id, | ||
2589 | uint16_t port_speed, uint16_t *mb) | ||
2590 | { | ||
2591 | int rval; | ||
2592 | mbx_cmd_t mc; | ||
2593 | mbx_cmd_t *mcp = &mc; | ||
2594 | |||
2595 | if (!IS_QLA24XX(ha)) | ||
2596 | return QLA_FUNCTION_FAILED; | ||
2597 | |||
2598 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
2599 | |||
2600 | mcp->mb[0] = MBC_PORT_PARAMS; | ||
2601 | mcp->mb[1] = loop_id; | ||
2602 | mcp->mb[2] = BIT_0; | ||
2603 | mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0); | ||
2604 | mcp->mb[4] = mcp->mb[5] = 0; | ||
2605 | mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | ||
2606 | mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; | ||
2607 | mcp->tov = 30; | ||
2608 | mcp->flags = 0; | ||
2609 | rval = qla2x00_mailbox_command(ha, mcp); | ||
2610 | |||
2611 | /* Return mailbox statuses. */ | ||
2612 | if (mb != NULL) { | ||
2613 | mb[0] = mcp->mb[0]; | ||
2614 | mb[1] = mcp->mb[1]; | ||
2615 | mb[3] = mcp->mb[3]; | ||
2616 | mb[4] = mcp->mb[4]; | ||
2617 | mb[5] = mcp->mb[5]; | ||
2618 | } | ||
2619 | |||
2620 | if (rval != QLA_SUCCESS) { | ||
2621 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, | ||
2622 | ha->host_no, rval)); | ||
2623 | } else { | ||
2624 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
2625 | } | ||
2626 | |||
2627 | return rval; | ||
2628 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 65cbe2f5eea2..3ba8c239f171 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -589,6 +589,23 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha) | |||
589 | return (return_status); | 589 | return (return_status); |
590 | } | 590 | } |
591 | 591 | ||
592 | static void | ||
593 | qla2x00_block_error_handler(struct scsi_cmnd *cmnd) | ||
594 | { | ||
595 | struct Scsi_Host *shost = cmnd->device->host; | ||
596 | struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); | ||
597 | unsigned long flags; | ||
598 | |||
599 | spin_lock_irqsave(shost->host_lock, flags); | ||
600 | while (rport->port_state == FC_PORTSTATE_BLOCKED) { | ||
601 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
602 | msleep(1000); | ||
603 | spin_lock_irqsave(shost->host_lock, flags); | ||
604 | } | ||
605 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
606 | return; | ||
607 | } | ||
608 | |||
592 | /************************************************************************** | 609 | /************************************************************************** |
593 | * qla2xxx_eh_abort | 610 | * qla2xxx_eh_abort |
594 | * | 611 | * |
@@ -615,6 +632,8 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
615 | unsigned long flags; | 632 | unsigned long flags; |
616 | int wait = 0; | 633 | int wait = 0; |
617 | 634 | ||
635 | qla2x00_block_error_handler(cmd); | ||
636 | |||
618 | if (!CMD_SP(cmd)) | 637 | if (!CMD_SP(cmd)) |
619 | return SUCCESS; | 638 | return SUCCESS; |
620 | 639 | ||
@@ -748,6 +767,8 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | |||
748 | unsigned int id, lun; | 767 | unsigned int id, lun; |
749 | unsigned long serial; | 768 | unsigned long serial; |
750 | 769 | ||
770 | qla2x00_block_error_handler(cmd); | ||
771 | |||
751 | ret = FAILED; | 772 | ret = FAILED; |
752 | 773 | ||
753 | id = cmd->device->id; | 774 | id = cmd->device->id; |
@@ -877,6 +898,8 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | |||
877 | unsigned int id, lun; | 898 | unsigned int id, lun; |
878 | unsigned long serial; | 899 | unsigned long serial; |
879 | 900 | ||
901 | qla2x00_block_error_handler(cmd); | ||
902 | |||
880 | ret = FAILED; | 903 | ret = FAILED; |
881 | 904 | ||
882 | id = cmd->device->id; | 905 | id = cmd->device->id; |
@@ -936,6 +959,8 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
936 | unsigned int id, lun; | 959 | unsigned int id, lun; |
937 | unsigned long serial; | 960 | unsigned long serial; |
938 | 961 | ||
962 | qla2x00_block_error_handler(cmd); | ||
963 | |||
939 | ret = FAILED; | 964 | ret = FAILED; |
940 | 965 | ||
941 | id = cmd->device->id; | 966 | id = cmd->device->id; |
@@ -1385,7 +1410,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1385 | ha->prev_topology = 0; | 1410 | ha->prev_topology = 0; |
1386 | ha->init_cb_size = sizeof(init_cb_t); | 1411 | ha->init_cb_size = sizeof(init_cb_t); |
1387 | ha->mgmt_svr_loop_id = MANAGEMENT_SERVER; | 1412 | ha->mgmt_svr_loop_id = MANAGEMENT_SERVER; |
1388 | ha->link_data_rate = LDR_UNKNOWN; | 1413 | ha->link_data_rate = PORT_SPEED_UNKNOWN; |
1389 | ha->optrom_size = OPTROM_SIZE_2300; | 1414 | ha->optrom_size = OPTROM_SIZE_2300; |
1390 | 1415 | ||
1391 | /* Assign ISP specific operations. */ | 1416 | /* Assign ISP specific operations. */ |
@@ -2564,14 +2589,20 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout) | |||
2564 | #define FW_ISP2322 3 | 2589 | #define FW_ISP2322 3 |
2565 | #define FW_ISP24XX 4 | 2590 | #define FW_ISP24XX 4 |
2566 | 2591 | ||
2592 | #define FW_FILE_ISP21XX "ql2100_fw.bin" | ||
2593 | #define FW_FILE_ISP22XX "ql2200_fw.bin" | ||
2594 | #define FW_FILE_ISP2300 "ql2300_fw.bin" | ||
2595 | #define FW_FILE_ISP2322 "ql2322_fw.bin" | ||
2596 | #define FW_FILE_ISP24XX "ql2400_fw.bin" | ||
2597 | |||
2567 | static DECLARE_MUTEX(qla_fw_lock); | 2598 | static DECLARE_MUTEX(qla_fw_lock); |
2568 | 2599 | ||
2569 | static struct fw_blob qla_fw_blobs[FW_BLOBS] = { | 2600 | static struct fw_blob qla_fw_blobs[FW_BLOBS] = { |
2570 | { .name = "ql2100_fw.bin", .segs = { 0x1000, 0 }, }, | 2601 | { .name = FW_FILE_ISP21XX, .segs = { 0x1000, 0 }, }, |
2571 | { .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, }, | 2602 | { .name = FW_FILE_ISP22XX, .segs = { 0x1000, 0 }, }, |
2572 | { .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, }, | 2603 | { .name = FW_FILE_ISP2300, .segs = { 0x800, 0 }, }, |
2573 | { .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, }, | 2604 | { .name = FW_FILE_ISP2322, .segs = { 0x800, 0x1c000, 0x1e000, 0 }, }, |
2574 | { .name = "ql2400_fw.bin", }, | 2605 | { .name = FW_FILE_ISP24XX, }, |
2575 | }; | 2606 | }; |
2576 | 2607 | ||
2577 | struct fw_blob * | 2608 | struct fw_blob * |
@@ -2702,3 +2733,8 @@ MODULE_AUTHOR("QLogic Corporation"); | |||
2702 | MODULE_DESCRIPTION("QLogic Fibre Channel HBA Driver"); | 2733 | MODULE_DESCRIPTION("QLogic Fibre Channel HBA Driver"); |
2703 | MODULE_LICENSE("GPL"); | 2734 | MODULE_LICENSE("GPL"); |
2704 | MODULE_VERSION(QLA2XXX_VERSION); | 2735 | MODULE_VERSION(QLA2XXX_VERSION); |
2736 | MODULE_FIRMWARE(FW_FILE_ISP21XX); | ||
2737 | MODULE_FIRMWARE(FW_FILE_ISP22XX); | ||
2738 | MODULE_FIRMWARE(FW_FILE_ISP2300); | ||
2739 | MODULE_FIRMWARE(FW_FILE_ISP2322); | ||
2740 | MODULE_FIRMWARE(FW_FILE_ISP24XX); | ||
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 971259032ef7..e57bf45a3393 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.01.07-k1" | 10 | #define QLA2XXX_VERSION "8.01.07-k2" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 1 | 13 | #define QLA_DRIVER_MINOR_VER 1 |