diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-08 13:12:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-08 13:12:46 -0400 |
commit | d1cd7c85f9e29740fddec6f25d8bf061937bf58d (patch) | |
tree | 6d1f8e555d3a416442856724b57dc414eac5d5a4 | |
parent | b3a5e648f5917ea508ecab9a629028b186d38eae (diff) | |
parent | d4023db71108375e4194e92730ba0d32d7f07813 (diff) |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This is mostly update of the usual drivers: qla2xxx, qedf, smartpqi,
hpsa, lpfc, ufs, mpt3sas, ibmvfc and hisi_sas. Plus number of minor
changes, spelling fixes and other trivia"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (298 commits)
scsi: qla2xxx: Avoid that lockdep complains about unsafe locking in tcm_qla2xxx_close_session()
scsi: qla2xxx: Avoid that qlt_send_resp_ctio() corrupts memory
scsi: qla2xxx: Fix hardirq-unsafe locking
scsi: qla2xxx: Complain loudly about reference count underflow
scsi: qla2xxx: Use __le64 instead of uint32_t[2] for sending DMA addresses to firmware
scsi: qla2xxx: Introduce the dsd32 and dsd64 data structures
scsi: qla2xxx: Check the size of firmware data structures at compile time
scsi: qla2xxx: Pass little-endian values to the firmware
scsi: qla2xxx: Fix race conditions in the code for aborting SCSI commands
scsi: qla2xxx: Use an on-stack completion in qla24xx_control_vp()
scsi: qla2xxx: Make qla24xx_async_abort_cmd() static
scsi: qla2xxx: Remove unnecessary locking from the target code
scsi: qla2xxx: Remove qla_tgt_cmd.released
scsi: qla2xxx: Complain if a command is released that is owned by the firmware
scsi: qla2xxx: target: Fix offline port handling and host reset handling
scsi: qla2xxx: Fix abort handling in tcm_qla2xxx_write_pending()
scsi: qla2xxx: Fix error handling in qlt_alloc_qfull_cmd()
scsi: qla2xxx: Simplify qlt_send_term_imm_notif()
scsi: qla2xxx: Fix use-after-free issues in qla2xxx_qpair_sp_free_dma()
scsi: qla2xxx: Fix a qla24xx_enable_msix() error path
...
158 files changed, 7540 insertions, 6428 deletions
diff --git a/Documentation/devicetree/bindings/ufs/cdns,ufshc.txt b/Documentation/devicetree/bindings/ufs/cdns,ufshc.txt index a04a4989ec7f..02347b017abd 100644 --- a/Documentation/devicetree/bindings/ufs/cdns,ufshc.txt +++ b/Documentation/devicetree/bindings/ufs/cdns,ufshc.txt | |||
@@ -5,8 +5,9 @@ Each UFS controller instance should have its own node. | |||
5 | Please see the ufshcd-pltfrm.txt for a list of all available properties. | 5 | Please see the ufshcd-pltfrm.txt for a list of all available properties. |
6 | 6 | ||
7 | Required properties: | 7 | Required properties: |
8 | - compatible : Compatible list, contains the following controller: | 8 | - compatible : Compatible list, contains one of the following controllers: |
9 | "cdns,ufshc" | 9 | "cdns,ufshc" - Generic CDNS HCI, |
10 | "cdns,ufshc-m31-16nm" - CDNS UFS HC + M31 16nm PHY | ||
10 | complemented with the JEDEC version: | 11 | complemented with the JEDEC version: |
11 | "jedec,ufs-2.0" | 12 | "jedec,ufs-2.0" |
12 | 13 | ||
diff --git a/Documentation/devicetree/bindings/ufs/ufs-mediatek.txt b/Documentation/devicetree/bindings/ufs/ufs-mediatek.txt new file mode 100644 index 000000000000..72aab8547308 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufs-mediatek.txt | |||
@@ -0,0 +1,43 @@ | |||
1 | * Mediatek Universal Flash Storage (UFS) Host Controller | ||
2 | |||
3 | UFS nodes are defined to describe on-chip UFS hardware macro. | ||
4 | Each UFS Host Controller should have its own node. | ||
5 | |||
6 | To bind UFS PHY with UFS host controller, the controller node should | ||
7 | contain a phandle reference to UFS M-PHY node. | ||
8 | |||
9 | Required properties for UFS nodes: | ||
10 | - compatible : Compatible list, contains the following controller: | ||
11 | "mediatek,mt8183-ufshci" for MediaTek UFS host controller | ||
12 | present on MT81xx chipsets. | ||
13 | - reg : Address and length of the UFS register set. | ||
14 | - phys : phandle to m-phy. | ||
15 | - clocks : List of phandle and clock specifier pairs. | ||
16 | - clock-names : List of clock input name strings sorted in the same | ||
17 | order as the clocks property. "ufs" is mandatory. | ||
18 | "ufs": ufshci core control clock. | ||
19 | - freq-table-hz : Array of <min max> operating frequencies stored in the same | ||
20 | order as the clocks property. If this property is not | ||
21 | defined or a value in the array is "0" then it is assumed | ||
22 | that the frequency is set by the parent clock or a | ||
23 | fixed rate clock source. | ||
24 | - vcc-supply : phandle to VCC supply regulator node. | ||
25 | |||
26 | Example: | ||
27 | |||
28 | ufsphy: phy@11fa0000 { | ||
29 | ... | ||
30 | }; | ||
31 | |||
32 | ufshci@11270000 { | ||
33 | compatible = "mediatek,mt8183-ufshci"; | ||
34 | reg = <0 0x11270000 0 0x2300>; | ||
35 | interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>; | ||
36 | phys = <&ufsphy>; | ||
37 | |||
38 | clocks = <&infracfg_ao INFRACFG_AO_UFS_CG>; | ||
39 | clock-names = "ufs"; | ||
40 | freq-table-hz = <0 0>; | ||
41 | |||
42 | vcc-supply = <&mt_pmic_vemc_ldo_reg>; | ||
43 | }; | ||
diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt index f647c09bc62a..56bccde9953a 100644 --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt | |||
@@ -31,7 +31,6 @@ Optional properties: | |||
31 | - vcc-max-microamp : specifies max. load that can be drawn from vcc supply | 31 | - vcc-max-microamp : specifies max. load that can be drawn from vcc supply |
32 | - vccq-max-microamp : specifies max. load that can be drawn from vccq supply | 32 | - vccq-max-microamp : specifies max. load that can be drawn from vccq supply |
33 | - vccq2-max-microamp : specifies max. load that can be drawn from vccq2 supply | 33 | - vccq2-max-microamp : specifies max. load that can be drawn from vccq2 supply |
34 | - <name>-fixed-regulator : boolean property specifying that <name>-supply is a fixed regulator | ||
35 | 34 | ||
36 | - clocks : List of phandle and clock specifier pairs | 35 | - clocks : List of phandle and clock specifier pairs |
37 | - clock-names : List of clock input name strings sorted in the same | 36 | - clock-names : List of clock input name strings sorted in the same |
@@ -65,7 +64,6 @@ Example: | |||
65 | interrupts = <0 28 0>; | 64 | interrupts = <0 28 0>; |
66 | 65 | ||
67 | vdd-hba-supply = <&xxx_reg0>; | 66 | vdd-hba-supply = <&xxx_reg0>; |
68 | vdd-hba-fixed-regulator; | ||
69 | vcc-supply = <&xxx_reg1>; | 67 | vcc-supply = <&xxx_reg1>; |
70 | vcc-supply-1p8; | 68 | vcc-supply-1p8; |
71 | vccq-supply = <&xxx_reg2>; | 69 | vccq-supply = <&xxx_reg2>; |
diff --git a/MAINTAINERS b/MAINTAINERS index 5a2b78ec8670..ee134110a502 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -16057,6 +16057,13 @@ L: linux-scsi@vger.kernel.org | |||
16057 | S: Supported | 16057 | S: Supported |
16058 | F: drivers/scsi/ufs/*dwc* | 16058 | F: drivers/scsi/ufs/*dwc* |
16059 | 16059 | ||
16060 | UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER MEDIATEK HOOKS | ||
16061 | M: Stanley Chu <stanley.chu@mediatek.com> | ||
16062 | L: linux-scsi@vger.kernel.org | ||
16063 | L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) | ||
16064 | S: Maintained | ||
16065 | F: drivers/scsi/ufs/ufs-mediatek* | ||
16066 | |||
16060 | UNSORTED BLOCK IMAGES (UBI) | 16067 | UNSORTED BLOCK IMAGES (UBI) |
16061 | M: Artem Bityutskiy <dedekind1@gmail.com> | 16068 | M: Artem Bityutskiy <dedekind1@gmail.com> |
16062 | M: Richard Weinberger <richard@nod.at> | 16069 | M: Richard Weinberger <richard@nod.at> |
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index ba551d8dfba4..d8882b0a1338 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -642,7 +642,7 @@ mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply) | |||
642 | freereq = 0; | 642 | freereq = 0; |
643 | if (event != MPI_EVENT_EVENT_CHANGE) | 643 | if (event != MPI_EVENT_EVENT_CHANGE) |
644 | break; | 644 | break; |
645 | /* else: fall through */ | 645 | /* fall through */ |
646 | case MPI_FUNCTION_CONFIG: | 646 | case MPI_FUNCTION_CONFIG: |
647 | case MPI_FUNCTION_SAS_IO_UNIT_CONTROL: | 647 | case MPI_FUNCTION_SAS_IO_UNIT_CONTROL: |
648 | ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD; | 648 | ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD; |
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 8d22d6134a89..f9ac22413000 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
@@ -565,7 +565,7 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
565 | * TODO - this define is not in MPI spec yet, | 565 | * TODO - this define is not in MPI spec yet, |
566 | * but they plan to set it to 0x21 | 566 | * but they plan to set it to 0x21 |
567 | */ | 567 | */ |
568 | if (event == 0x21 ) { | 568 | if (event == 0x21) { |
569 | ioc->aen_event_read_flag=1; | 569 | ioc->aen_event_read_flag=1; |
570 | dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Raised SIGIO to application\n", | 570 | dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Raised SIGIO to application\n", |
571 | ioc->name)); | 571 | ioc->name)); |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 612cb5bc1333..6a79cd0ebe2b 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -2928,27 +2928,27 @@ mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc, | |||
2928 | if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) { | 2928 | if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) { |
2929 | u8 *tmp; | 2929 | u8 *tmp; |
2930 | 2930 | ||
2931 | smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply; | 2931 | smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply; |
2932 | if (le16_to_cpu(smprep->ResponseDataLength) != | 2932 | if (le16_to_cpu(smprep->ResponseDataLength) != |
2933 | sizeof(struct rep_manu_reply)) | 2933 | sizeof(struct rep_manu_reply)) |
2934 | goto out_free; | 2934 | goto out_free; |
2935 | 2935 | ||
2936 | manufacture_reply = data_out + sizeof(struct rep_manu_request); | 2936 | manufacture_reply = data_out + sizeof(struct rep_manu_request); |
2937 | strncpy(edev->vendor_id, manufacture_reply->vendor_id, | 2937 | strncpy(edev->vendor_id, manufacture_reply->vendor_id, |
2938 | SAS_EXPANDER_VENDOR_ID_LEN); | 2938 | SAS_EXPANDER_VENDOR_ID_LEN); |
2939 | strncpy(edev->product_id, manufacture_reply->product_id, | 2939 | strncpy(edev->product_id, manufacture_reply->product_id, |
2940 | SAS_EXPANDER_PRODUCT_ID_LEN); | 2940 | SAS_EXPANDER_PRODUCT_ID_LEN); |
2941 | strncpy(edev->product_rev, manufacture_reply->product_rev, | 2941 | strncpy(edev->product_rev, manufacture_reply->product_rev, |
2942 | SAS_EXPANDER_PRODUCT_REV_LEN); | 2942 | SAS_EXPANDER_PRODUCT_REV_LEN); |
2943 | edev->level = manufacture_reply->sas_format; | 2943 | edev->level = manufacture_reply->sas_format; |
2944 | if (manufacture_reply->sas_format) { | 2944 | if (manufacture_reply->sas_format) { |
2945 | strncpy(edev->component_vendor_id, | 2945 | strncpy(edev->component_vendor_id, |
2946 | manufacture_reply->component_vendor_id, | 2946 | manufacture_reply->component_vendor_id, |
2947 | SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN); | 2947 | SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN); |
2948 | tmp = (u8 *)&manufacture_reply->component_id; | 2948 | tmp = (u8 *)&manufacture_reply->component_id; |
2949 | edev->component_id = tmp[0] << 8 | tmp[1]; | 2949 | edev->component_id = tmp[0] << 8 | tmp[1]; |
2950 | edev->component_revision_id = | 2950 | edev->component_revision_id = |
2951 | manufacture_reply->component_revision_id; | 2951 | manufacture_reply->component_revision_id; |
2952 | } | 2952 | } |
2953 | } else { | 2953 | } else { |
2954 | printk(MYIOC_s_ERR_FMT | 2954 | printk(MYIOC_s_ERR_FMT |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 6ba07c7feb92..f0737c57ed5f 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -786,6 +786,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
786 | /* | 786 | /* |
787 | * Allow non-SAS & non-NEXUS_LOSS to drop into below code | 787 | * Allow non-SAS & non-NEXUS_LOSS to drop into below code |
788 | */ | 788 | */ |
789 | /* Fall through */ | ||
789 | 790 | ||
790 | case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ | 791 | case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ |
791 | /* Linux handles an unsolicited DID_RESET better | 792 | /* Linux handles an unsolicited DID_RESET better |
@@ -882,6 +883,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
882 | 883 | ||
883 | case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ | 884 | case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ |
884 | scsi_set_resid(sc, 0); | 885 | scsi_set_resid(sc, 0); |
886 | /* Fall through */ | ||
885 | case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ | 887 | case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ |
886 | case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */ | 888 | case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */ |
887 | sc->result = (DID_OK << 16) | scsi_status; | 889 | sc->result = (DID_OK << 16) | scsi_status; |
@@ -1934,7 +1936,7 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt) | |||
1934 | /* If our attempts to reset the host failed, then return a failed | 1936 | /* If our attempts to reset the host failed, then return a failed |
1935 | * status. The host will be taken off line by the SCSI mid-layer. | 1937 | * status. The host will be taken off line by the SCSI mid-layer. |
1936 | */ | 1938 | */ |
1937 | retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); | 1939 | retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); |
1938 | if (retval < 0) | 1940 | if (retval < 0) |
1939 | status = FAILED; | 1941 | status = FAILED; |
1940 | else | 1942 | else |
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 7172b0b16bdd..eabc4de5816c 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c | |||
@@ -258,8 +258,6 @@ mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, u8 channel , u8 id) | |||
258 | IOCPage4_t *IOCPage4Ptr; | 258 | IOCPage4_t *IOCPage4Ptr; |
259 | MPT_FRAME_HDR *mf; | 259 | MPT_FRAME_HDR *mf; |
260 | dma_addr_t dataDma; | 260 | dma_addr_t dataDma; |
261 | u16 req_idx; | ||
262 | u32 frameOffset; | ||
263 | u32 flagsLength; | 261 | u32 flagsLength; |
264 | int ii; | 262 | int ii; |
265 | 263 | ||
@@ -276,9 +274,6 @@ mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, u8 channel , u8 id) | |||
276 | */ | 274 | */ |
277 | pReq = (Config_t *)mf; | 275 | pReq = (Config_t *)mf; |
278 | 276 | ||
279 | req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); | ||
280 | frameOffset = ioc->req_sz - sizeof(IOCPage4_t); | ||
281 | |||
282 | /* Complete the request frame (same for all requests). | 277 | /* Complete the request frame (same for all requests). |
283 | */ | 278 | */ |
284 | pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; | 279 | pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; |
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 6d8451356eac..9544eb60f725 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include "fabrics.h" | 14 | #include "fabrics.h" |
15 | #include <linux/nvme-fc-driver.h> | 15 | #include <linux/nvme-fc-driver.h> |
16 | #include <linux/nvme-fc.h> | 16 | #include <linux/nvme-fc.h> |
17 | 17 | #include <scsi/scsi_transport_fc.h> | |
18 | 18 | ||
19 | /* *************************** Data Structures/Defines ****************** */ | 19 | /* *************************** Data Structures/Defines ****************** */ |
20 | 20 | ||
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 01c23d27f290..fe0535affc14 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c | |||
@@ -272,9 +272,8 @@ mrs[] = { | |||
272 | static void NCR5380_print(struct Scsi_Host *instance) | 272 | static void NCR5380_print(struct Scsi_Host *instance) |
273 | { | 273 | { |
274 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | 274 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
275 | unsigned char status, data, basr, mr, icr, i; | 275 | unsigned char status, basr, mr, icr, i; |
276 | 276 | ||
277 | data = NCR5380_read(CURRENT_SCSI_DATA_REG); | ||
278 | status = NCR5380_read(STATUS_REG); | 277 | status = NCR5380_read(STATUS_REG); |
279 | mr = NCR5380_read(MODE_REG); | 278 | mr = NCR5380_read(MODE_REG); |
280 | icr = NCR5380_read(INITIATOR_COMMAND_REG); | 279 | icr = NCR5380_read(INITIATOR_COMMAND_REG); |
@@ -1933,13 +1932,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
1933 | if (!hostdata->connected) | 1932 | if (!hostdata->connected) |
1934 | return; | 1933 | return; |
1935 | 1934 | ||
1936 | /* Fall through to reject message */ | 1935 | /* Reject message */ |
1937 | 1936 | /* Fall through */ | |
1937 | default: | ||
1938 | /* | 1938 | /* |
1939 | * If we get something weird that we aren't expecting, | 1939 | * If we get something weird that we aren't expecting, |
1940 | * reject it. | 1940 | * log it. |
1941 | */ | 1941 | */ |
1942 | default: | ||
1943 | if (tmp == EXTENDED_MESSAGE) | 1942 | if (tmp == EXTENDED_MESSAGE) |
1944 | scmd_printk(KERN_INFO, cmd, | 1943 | scmd_printk(KERN_INFO, cmd, |
1945 | "rejecting unknown extended message code %02x, length %d\n", | 1944 | "rejecting unknown extended message code %02x, length %d\n", |
diff --git a/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/drivers/scsi/aic7xxx/Kconfig.aic7xxx index 55ac55ee6068..40fe08a64535 100644 --- a/drivers/scsi/aic7xxx/Kconfig.aic7xxx +++ b/drivers/scsi/aic7xxx/Kconfig.aic7xxx | |||
@@ -3,7 +3,7 @@ | |||
3 | # $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic7xxx#7 $ | 3 | # $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic7xxx#7 $ |
4 | # | 4 | # |
5 | config SCSI_AIC7XXX | 5 | config SCSI_AIC7XXX |
6 | tristate "Adaptec AIC7xxx Fast -> U160 support (New Driver)" | 6 | tristate "Adaptec AIC7xxx Fast -> U160 support" |
7 | depends on (PCI || EISA) && SCSI | 7 | depends on (PCI || EISA) && SCSI |
8 | select SCSI_SPI_ATTRS | 8 | select SCSI_SPI_ATTRS |
9 | ---help--- | 9 | ---help--- |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c index d4a7263e4b8f..a9d40d3b90ef 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c | |||
@@ -1666,7 +1666,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat) | |||
1666 | printk("\tCRC Value Mismatch\n"); | 1666 | printk("\tCRC Value Mismatch\n"); |
1667 | if ((sstat2 & CRCENDERR) != 0) | 1667 | if ((sstat2 & CRCENDERR) != 0) |
1668 | printk("\tNo terminal CRC packet " | 1668 | printk("\tNo terminal CRC packet " |
1669 | "recevied\n"); | 1669 | "received\n"); |
1670 | if ((sstat2 & CRCREQERR) != 0) | 1670 | if ((sstat2 & CRCREQERR) != 0) |
1671 | printk("\tIllegal CRC packet " | 1671 | printk("\tIllegal CRC packet " |
1672 | "request\n"); | 1672 | "request\n"); |
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 1267200380f8..446a789cdaf5 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c | |||
@@ -194,12 +194,11 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) | |||
194 | ((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12); | 194 | ((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12); |
195 | ((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13); | 195 | ((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13); |
196 | ((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14); | 196 | ((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14); |
197 | if (dev->id[c][target_id].last_len != adrcnt) | 197 | if (dev->id[c][target_id].last_len != adrcnt) { |
198 | { | 198 | k = dev->id[c][target_id].last_len; |
199 | k = dev->id[c][target_id].last_len; | ||
200 | k -= adrcnt; | 199 | k -= adrcnt; |
201 | dev->id[c][target_id].tran_len = k; | 200 | dev->id[c][target_id].tran_len = k; |
202 | dev->id[c][target_id].last_len = adrcnt; | 201 | dev->id[c][target_id].last_len = adrcnt; |
203 | } | 202 | } |
204 | #ifdef ED_DBGP | 203 | #ifdef ED_DBGP |
205 | printk("dev->id[c][target_id].last_len = %d dev->id[c][target_id].tran_len = %d\n",dev->id[c][target_id].last_len,dev->id[c][target_id].tran_len); | 204 | printk("dev->id[c][target_id].last_len = %d dev->id[c][target_id].tran_len = %d\n",dev->id[c][target_id].last_len,dev->id[c][target_id].tran_len); |
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 0a6972ee94d7..ea042c1fc70d 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c | |||
@@ -963,7 +963,7 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, | |||
963 | * @ctrl: ptr to ctrl_info | 963 | * @ctrl: ptr to ctrl_info |
964 | * @cq: Completion Queue | 964 | * @cq: Completion Queue |
965 | * @dq: Default Queue | 965 | * @dq: Default Queue |
966 | * @lenght: ring size | 966 | * @length: ring size |
967 | * @entry_size: size of each entry in DEFQ | 967 | * @entry_size: size of each entry in DEFQ |
968 | * @is_header: Header or Data DEFQ | 968 | * @is_header: Header or Data DEFQ |
969 | * @ulp_num: Bind to which ULP | 969 | * @ulp_num: Bind to which ULP |
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index bc9f2a2365f4..8def63c0755f 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c | |||
@@ -1083,7 +1083,6 @@ int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd) | |||
1083 | static int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req) | 1083 | static int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req) |
1084 | { | 1084 | { |
1085 | struct bnx2fc_rport *tgt = io_req->tgt; | 1085 | struct bnx2fc_rport *tgt = io_req->tgt; |
1086 | int rc = SUCCESS; | ||
1087 | unsigned int time_left; | 1086 | unsigned int time_left; |
1088 | 1087 | ||
1089 | io_req->wait_for_comp = 1; | 1088 | io_req->wait_for_comp = 1; |
@@ -1110,7 +1109,7 @@ static int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req) | |||
1110 | kref_put(&io_req->refcount, bnx2fc_cmd_release); | 1109 | kref_put(&io_req->refcount, bnx2fc_cmd_release); |
1111 | 1110 | ||
1112 | spin_lock_bh(&tgt->tgt_lock); | 1111 | spin_lock_bh(&tgt->tgt_lock); |
1113 | return rc; | 1112 | return SUCCESS; |
1114 | } | 1113 | } |
1115 | 1114 | ||
1116 | /** | 1115 | /** |
diff --git a/drivers/scsi/csiostor/csio_isr.c b/drivers/scsi/csiostor/csio_isr.c index 7c8814715711..b2540402fafc 100644 --- a/drivers/scsi/csiostor/csio_isr.c +++ b/drivers/scsi/csiostor/csio_isr.c | |||
@@ -474,13 +474,39 @@ csio_reduce_sqsets(struct csio_hw *hw, int cnt) | |||
474 | csio_dbg(hw, "Reduced sqsets to %d\n", hw->num_sqsets); | 474 | csio_dbg(hw, "Reduced sqsets to %d\n", hw->num_sqsets); |
475 | } | 475 | } |
476 | 476 | ||
477 | static void csio_calc_sets(struct irq_affinity *affd, unsigned int nvecs) | ||
478 | { | ||
479 | struct csio_hw *hw = affd->priv; | ||
480 | u8 i; | ||
481 | |||
482 | if (!nvecs) | ||
483 | return; | ||
484 | |||
485 | if (nvecs < hw->num_pports) { | ||
486 | affd->nr_sets = 1; | ||
487 | affd->set_size[0] = nvecs; | ||
488 | return; | ||
489 | } | ||
490 | |||
491 | affd->nr_sets = hw->num_pports; | ||
492 | for (i = 0; i < hw->num_pports; i++) | ||
493 | affd->set_size[i] = nvecs / hw->num_pports; | ||
494 | } | ||
495 | |||
477 | static int | 496 | static int |
478 | csio_enable_msix(struct csio_hw *hw) | 497 | csio_enable_msix(struct csio_hw *hw) |
479 | { | 498 | { |
480 | int i, j, k, n, min, cnt; | 499 | int i, j, k, n, min, cnt; |
481 | int extra = CSIO_EXTRA_VECS; | 500 | int extra = CSIO_EXTRA_VECS; |
482 | struct csio_scsi_cpu_info *info; | 501 | struct csio_scsi_cpu_info *info; |
483 | struct irq_affinity desc = { .pre_vectors = 2 }; | 502 | struct irq_affinity desc = { |
503 | .pre_vectors = CSIO_EXTRA_VECS, | ||
504 | .calc_sets = csio_calc_sets, | ||
505 | .priv = hw, | ||
506 | }; | ||
507 | |||
508 | if (hw->num_pports > IRQ_AFFINITY_MAX_SETS) | ||
509 | return -ENOSPC; | ||
484 | 510 | ||
485 | min = hw->num_pports + extra; | 511 | min = hw->num_pports + extra; |
486 | cnt = hw->num_sqsets + extra; | 512 | cnt = hw->num_sqsets + extra; |
diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c index 75e1273a44b3..b8dd9e648dd0 100644 --- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c +++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | |||
@@ -979,14 +979,17 @@ static int init_act_open(struct cxgbi_sock *csk) | |||
979 | csk->atid = cxgb3_alloc_atid(t3dev, &t3_client, csk); | 979 | csk->atid = cxgb3_alloc_atid(t3dev, &t3_client, csk); |
980 | if (csk->atid < 0) { | 980 | if (csk->atid < 0) { |
981 | pr_err("NO atid available.\n"); | 981 | pr_err("NO atid available.\n"); |
982 | goto rel_resource; | 982 | return -EINVAL; |
983 | } | 983 | } |
984 | cxgbi_sock_set_flag(csk, CTPF_HAS_ATID); | 984 | cxgbi_sock_set_flag(csk, CTPF_HAS_ATID); |
985 | cxgbi_sock_get(csk); | 985 | cxgbi_sock_get(csk); |
986 | 986 | ||
987 | skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_KERNEL); | 987 | skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_KERNEL); |
988 | if (!skb) | 988 | if (!skb) { |
989 | goto rel_resource; | 989 | cxgb3_free_atid(t3dev, csk->atid); |
990 | cxgbi_sock_put(csk); | ||
991 | return -ENOMEM; | ||
992 | } | ||
990 | skb->sk = (struct sock *)csk; | 993 | skb->sk = (struct sock *)csk; |
991 | set_arp_failure_handler(skb, act_open_arp_failure); | 994 | set_arp_failure_handler(skb, act_open_arp_failure); |
992 | csk->snd_win = cxgb3i_snd_win; | 995 | csk->snd_win = cxgb3i_snd_win; |
@@ -1007,11 +1010,6 @@ static int init_act_open(struct cxgbi_sock *csk) | |||
1007 | cxgbi_sock_set_state(csk, CTP_ACTIVE_OPEN); | 1010 | cxgbi_sock_set_state(csk, CTP_ACTIVE_OPEN); |
1008 | send_act_open_req(csk, skb, csk->l2t); | 1011 | send_act_open_req(csk, skb, csk->l2t); |
1009 | return 0; | 1012 | return 0; |
1010 | |||
1011 | rel_resource: | ||
1012 | if (skb) | ||
1013 | __kfree_skb(skb); | ||
1014 | return -EINVAL; | ||
1015 | } | 1013 | } |
1016 | 1014 | ||
1017 | cxgb3_cpl_handler_func cxgb3i_cpl_handlers[NUM_CPL_CMDS] = { | 1015 | cxgb3_cpl_handler_func cxgb3i_cpl_handlers[NUM_CPL_CMDS] = { |
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c index d44914e5e415..124f3345420f 100644 --- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c +++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | |||
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(dbg_level, "Debug flag (default=0)"); | |||
60 | #define CXGB4I_DEFAULT_10G_RCV_WIN (256 * 1024) | 60 | #define CXGB4I_DEFAULT_10G_RCV_WIN (256 * 1024) |
61 | static int cxgb4i_rcv_win = -1; | 61 | static int cxgb4i_rcv_win = -1; |
62 | module_param(cxgb4i_rcv_win, int, 0644); | 62 | module_param(cxgb4i_rcv_win, int, 0644); |
63 | MODULE_PARM_DESC(cxgb4i_rcv_win, "TCP reveive window in bytes"); | 63 | MODULE_PARM_DESC(cxgb4i_rcv_win, "TCP receive window in bytes"); |
64 | 64 | ||
65 | #define CXGB4I_DEFAULT_10G_SND_WIN (128 * 1024) | 65 | #define CXGB4I_DEFAULT_10G_SND_WIN (128 * 1024) |
66 | static int cxgb4i_snd_win = -1; | 66 | static int cxgb4i_snd_win = -1; |
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index 006372b3fba2..8b915d4ed98d 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c | |||
@@ -282,7 +282,6 @@ struct cxgbi_device *cxgbi_device_find_by_netdev_rcu(struct net_device *ndev, | |||
282 | } | 282 | } |
283 | EXPORT_SYMBOL_GPL(cxgbi_device_find_by_netdev_rcu); | 283 | EXPORT_SYMBOL_GPL(cxgbi_device_find_by_netdev_rcu); |
284 | 284 | ||
285 | #if IS_ENABLED(CONFIG_IPV6) | ||
286 | static struct cxgbi_device *cxgbi_device_find_by_mac(struct net_device *ndev, | 285 | static struct cxgbi_device *cxgbi_device_find_by_mac(struct net_device *ndev, |
287 | int *port) | 286 | int *port) |
288 | { | 287 | { |
@@ -315,7 +314,6 @@ static struct cxgbi_device *cxgbi_device_find_by_mac(struct net_device *ndev, | |||
315 | ndev, ndev->name); | 314 | ndev, ndev->name); |
316 | return NULL; | 315 | return NULL; |
317 | } | 316 | } |
318 | #endif | ||
319 | 317 | ||
320 | void cxgbi_hbas_remove(struct cxgbi_device *cdev) | 318 | void cxgbi_hbas_remove(struct cxgbi_device *cdev) |
321 | { | 319 | { |
@@ -653,6 +651,8 @@ cxgbi_check_route(struct sockaddr *dst_addr, int ifindex) | |||
653 | } | 651 | } |
654 | 652 | ||
655 | cdev = cxgbi_device_find_by_netdev(ndev, &port); | 653 | cdev = cxgbi_device_find_by_netdev(ndev, &port); |
654 | if (!cdev) | ||
655 | cdev = cxgbi_device_find_by_mac(ndev, &port); | ||
656 | if (!cdev) { | 656 | if (!cdev) { |
657 | pr_info("dst %pI4, %s, NOT cxgbi device.\n", | 657 | pr_info("dst %pI4, %s, NOT cxgbi device.\n", |
658 | &daddr->sin_addr.s_addr, ndev->name); | 658 | &daddr->sin_addr.s_addr, ndev->name); |
@@ -2310,7 +2310,6 @@ int cxgbi_get_ep_param(struct iscsi_endpoint *ep, enum iscsi_param param, | |||
2310 | { | 2310 | { |
2311 | struct cxgbi_endpoint *cep = ep->dd_data; | 2311 | struct cxgbi_endpoint *cep = ep->dd_data; |
2312 | struct cxgbi_sock *csk; | 2312 | struct cxgbi_sock *csk; |
2313 | int len; | ||
2314 | 2313 | ||
2315 | log_debug(1 << CXGBI_DBG_ISCSI, | 2314 | log_debug(1 << CXGBI_DBG_ISCSI, |
2316 | "cls_conn 0x%p, param %d.\n", ep, param); | 2315 | "cls_conn 0x%p, param %d.\n", ep, param); |
@@ -2328,9 +2327,9 @@ int cxgbi_get_ep_param(struct iscsi_endpoint *ep, enum iscsi_param param, | |||
2328 | return iscsi_conn_get_addr_param((struct sockaddr_storage *) | 2327 | return iscsi_conn_get_addr_param((struct sockaddr_storage *) |
2329 | &csk->daddr, param, buf); | 2328 | &csk->daddr, param, buf); |
2330 | default: | 2329 | default: |
2331 | return -ENOSYS; | 2330 | break; |
2332 | } | 2331 | } |
2333 | return len; | 2332 | return -ENOSYS; |
2334 | } | 2333 | } |
2335 | EXPORT_SYMBOL_GPL(cxgbi_get_ep_param); | 2334 | EXPORT_SYMBOL_GPL(cxgbi_get_ep_param); |
2336 | 2335 | ||
@@ -2563,13 +2562,9 @@ struct iscsi_endpoint *cxgbi_ep_connect(struct Scsi_Host *shost, | |||
2563 | pr_info("shost 0x%p, priv NULL.\n", shost); | 2562 | pr_info("shost 0x%p, priv NULL.\n", shost); |
2564 | goto err_out; | 2563 | goto err_out; |
2565 | } | 2564 | } |
2566 | |||
2567 | rtnl_lock(); | ||
2568 | if (!vlan_uses_dev(hba->ndev)) | ||
2569 | ifindex = hba->ndev->ifindex; | ||
2570 | rtnl_unlock(); | ||
2571 | } | 2565 | } |
2572 | 2566 | ||
2567 | check_route: | ||
2573 | if (dst_addr->sa_family == AF_INET) { | 2568 | if (dst_addr->sa_family == AF_INET) { |
2574 | csk = cxgbi_check_route(dst_addr, ifindex); | 2569 | csk = cxgbi_check_route(dst_addr, ifindex); |
2575 | #if IS_ENABLED(CONFIG_IPV6) | 2570 | #if IS_ENABLED(CONFIG_IPV6) |
@@ -2590,6 +2585,13 @@ struct iscsi_endpoint *cxgbi_ep_connect(struct Scsi_Host *shost, | |||
2590 | if (!hba) | 2585 | if (!hba) |
2591 | hba = csk->cdev->hbas[csk->port_id]; | 2586 | hba = csk->cdev->hbas[csk->port_id]; |
2592 | else if (hba != csk->cdev->hbas[csk->port_id]) { | 2587 | else if (hba != csk->cdev->hbas[csk->port_id]) { |
2588 | if (ifindex != hba->ndev->ifindex) { | ||
2589 | cxgbi_sock_put(csk); | ||
2590 | cxgbi_sock_closed(csk); | ||
2591 | ifindex = hba->ndev->ifindex; | ||
2592 | goto check_route; | ||
2593 | } | ||
2594 | |||
2593 | pr_info("Could not connect through requested host %u" | 2595 | pr_info("Could not connect through requested host %u" |
2594 | "hba 0x%p != 0x%p (%u).\n", | 2596 | "hba 0x%p != 0x%p (%u).\n", |
2595 | shost->host_no, hba, | 2597 | shost->host_no, hba, |
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index abdc34affdf6..a3afd1478ab6 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c | |||
@@ -835,8 +835,8 @@ static void adpt_i2o_sys_shutdown(void) | |||
835 | adpt_hba *pHba, *pNext; | 835 | adpt_hba *pHba, *pNext; |
836 | struct adpt_i2o_post_wait_data *p1, *old; | 836 | struct adpt_i2o_post_wait_data *p1, *old; |
837 | 837 | ||
838 | printk(KERN_INFO"Shutting down Adaptec I2O controllers.\n"); | 838 | printk(KERN_INFO "Shutting down Adaptec I2O controllers.\n"); |
839 | printk(KERN_INFO" This could take a few minutes if there are many devices attached\n"); | 839 | printk(KERN_INFO " This could take a few minutes if there are many devices attached\n"); |
840 | /* Delete all IOPs from the controller chain */ | 840 | /* Delete all IOPs from the controller chain */ |
841 | /* They should have already been released by the | 841 | /* They should have already been released by the |
842 | * scsi-core | 842 | * scsi-core |
@@ -859,7 +859,7 @@ static void adpt_i2o_sys_shutdown(void) | |||
859 | // spin_unlock_irqrestore(&adpt_post_wait_lock, flags); | 859 | // spin_unlock_irqrestore(&adpt_post_wait_lock, flags); |
860 | adpt_post_wait_queue = NULL; | 860 | adpt_post_wait_queue = NULL; |
861 | 861 | ||
862 | printk(KERN_INFO "Adaptec I2O controllers down.\n"); | 862 | printk(KERN_INFO "Adaptec I2O controllers down.\n"); |
863 | } | 863 | } |
864 | 864 | ||
865 | static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) | 865 | static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) |
@@ -3390,7 +3390,7 @@ static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, | |||
3390 | return -((res[1] >> 16) & 0xFF); /* -BlockStatus */ | 3390 | return -((res[1] >> 16) & 0xFF); /* -BlockStatus */ |
3391 | } | 3391 | } |
3392 | 3392 | ||
3393 | return 4 + ((res[1] & 0x0000FFFF) << 2); /* bytes used in resblk */ | 3393 | return 4 + ((res[1] & 0x0000FFFF) << 2); /* bytes used in resblk */ |
3394 | } | 3394 | } |
3395 | 3395 | ||
3396 | 3396 | ||
@@ -3463,8 +3463,8 @@ static int adpt_i2o_enable_hba(adpt_hba* pHba) | |||
3463 | 3463 | ||
3464 | static int adpt_i2o_systab_send(adpt_hba* pHba) | 3464 | static int adpt_i2o_systab_send(adpt_hba* pHba) |
3465 | { | 3465 | { |
3466 | u32 msg[12]; | 3466 | u32 msg[12]; |
3467 | int ret; | 3467 | int ret; |
3468 | 3468 | ||
3469 | msg[0] = I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6; | 3469 | msg[0] = I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6; |
3470 | msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID; | 3470 | msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID; |
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index e7f1dd4f3b66..0ca9b4393770 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c | |||
@@ -3697,8 +3697,9 @@ static int ioc_general(void __user *arg, char *cmnd) | |||
3697 | 3697 | ||
3698 | rval = 0; | 3698 | rval = 0; |
3699 | out_free_buf: | 3699 | out_free_buf: |
3700 | dma_free_coherent(&ha->pdev->dev, gen.data_len + gen.sense_len, buf, | 3700 | if (buf) |
3701 | paddr); | 3701 | dma_free_coherent(&ha->pdev->dev, gen.data_len + gen.sense_len, |
3702 | buf, paddr); | ||
3702 | return rval; | 3703 | return rval; |
3703 | } | 3704 | } |
3704 | 3705 | ||
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 9bfa9f12d81e..fc87994b5d73 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h | |||
@@ -170,6 +170,7 @@ struct hisi_sas_phy { | |||
170 | u32 code_violation_err_count; | 170 | u32 code_violation_err_count; |
171 | enum sas_linkrate minimum_linkrate; | 171 | enum sas_linkrate minimum_linkrate; |
172 | enum sas_linkrate maximum_linkrate; | 172 | enum sas_linkrate maximum_linkrate; |
173 | int enable; | ||
173 | }; | 174 | }; |
174 | 175 | ||
175 | struct hisi_sas_port { | 176 | struct hisi_sas_port { |
@@ -551,6 +552,8 @@ extern int hisi_sas_slave_configure(struct scsi_device *sdev); | |||
551 | extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time); | 552 | extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time); |
552 | extern void hisi_sas_scan_start(struct Scsi_Host *shost); | 553 | extern void hisi_sas_scan_start(struct Scsi_Host *shost); |
553 | extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type); | 554 | extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type); |
555 | extern void hisi_sas_phy_enable(struct hisi_hba *hisi_hba, int phy_no, | ||
556 | int enable); | ||
554 | extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy); | 557 | extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy); |
555 | extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, | 558 | extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, |
556 | struct sas_task *task, | 559 | struct sas_task *task, |
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 14bac4966c87..8a7feb8ed8d6 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c | |||
@@ -10,7 +10,6 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include "hisi_sas.h" | 12 | #include "hisi_sas.h" |
13 | #include "../libsas/sas_internal.h" | ||
14 | #define DRV_NAME "hisi_sas" | 13 | #define DRV_NAME "hisi_sas" |
15 | 14 | ||
16 | #define DEV_IS_GONE(dev) \ | 15 | #define DEV_IS_GONE(dev) \ |
@@ -171,7 +170,7 @@ void hisi_sas_stop_phys(struct hisi_hba *hisi_hba) | |||
171 | int phy_no; | 170 | int phy_no; |
172 | 171 | ||
173 | for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) | 172 | for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) |
174 | hisi_hba->hw->phy_disable(hisi_hba, phy_no); | 173 | hisi_sas_phy_enable(hisi_hba, phy_no, 0); |
175 | } | 174 | } |
176 | EXPORT_SYMBOL_GPL(hisi_sas_stop_phys); | 175 | EXPORT_SYMBOL_GPL(hisi_sas_stop_phys); |
177 | 176 | ||
@@ -684,7 +683,7 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no) | |||
684 | id->initiator_bits = SAS_PROTOCOL_ALL; | 683 | id->initiator_bits = SAS_PROTOCOL_ALL; |
685 | id->target_bits = phy->identify.target_port_protocols; | 684 | id->target_bits = phy->identify.target_port_protocols; |
686 | } else if (phy->phy_type & PORT_TYPE_SATA) { | 685 | } else if (phy->phy_type & PORT_TYPE_SATA) { |
687 | /*Nothing*/ | 686 | /* Nothing */ |
688 | } | 687 | } |
689 | 688 | ||
690 | sas_phy->frame_rcvd_size = phy->frame_rcvd_size; | 689 | sas_phy->frame_rcvd_size = phy->frame_rcvd_size; |
@@ -755,7 +754,8 @@ static int hisi_sas_init_device(struct domain_device *device) | |||
755 | * STP target port | 754 | * STP target port |
756 | */ | 755 | */ |
757 | local_phy = sas_get_local_phy(device); | 756 | local_phy = sas_get_local_phy(device); |
758 | if (!scsi_is_sas_phy_local(local_phy)) { | 757 | if (!scsi_is_sas_phy_local(local_phy) && |
758 | !test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) { | ||
759 | unsigned long deadline = ata_deadline(jiffies, 20000); | 759 | unsigned long deadline = ata_deadline(jiffies, 20000); |
760 | struct sata_device *sata_dev = &device->sata_dev; | 760 | struct sata_device *sata_dev = &device->sata_dev; |
761 | struct ata_host *ata_host = sata_dev->ata_host; | 761 | struct ata_host *ata_host = sata_dev->ata_host; |
@@ -770,8 +770,7 @@ static int hisi_sas_init_device(struct domain_device *device) | |||
770 | } | 770 | } |
771 | sas_put_local_phy(local_phy); | 771 | sas_put_local_phy(local_phy); |
772 | if (rc) { | 772 | if (rc) { |
773 | dev_warn(dev, "SATA disk hardreset fail: 0x%x\n", | 773 | dev_warn(dev, "SATA disk hardreset fail: %d\n", rc); |
774 | rc); | ||
775 | return rc; | 774 | return rc; |
776 | } | 775 | } |
777 | 776 | ||
@@ -976,6 +975,30 @@ static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) | |||
976 | timer_setup(&phy->timer, hisi_sas_wait_phyup_timedout, 0); | 975 | timer_setup(&phy->timer, hisi_sas_wait_phyup_timedout, 0); |
977 | } | 976 | } |
978 | 977 | ||
978 | /* Wrapper to ensure we track hisi_sas_phy.enable properly */ | ||
979 | void hisi_sas_phy_enable(struct hisi_hba *hisi_hba, int phy_no, int enable) | ||
980 | { | ||
981 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; | ||
982 | struct asd_sas_phy *aphy = &phy->sas_phy; | ||
983 | struct sas_phy *sphy = aphy->phy; | ||
984 | unsigned long flags; | ||
985 | |||
986 | spin_lock_irqsave(&phy->lock, flags); | ||
987 | |||
988 | if (enable) { | ||
989 | /* We may have been enabled already; if so, don't touch */ | ||
990 | if (!phy->enable) | ||
991 | sphy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN; | ||
992 | hisi_hba->hw->phy_start(hisi_hba, phy_no); | ||
993 | } else { | ||
994 | sphy->negotiated_linkrate = SAS_PHY_DISABLED; | ||
995 | hisi_hba->hw->phy_disable(hisi_hba, phy_no); | ||
996 | } | ||
997 | phy->enable = enable; | ||
998 | spin_unlock_irqrestore(&phy->lock, flags); | ||
999 | } | ||
1000 | EXPORT_SYMBOL_GPL(hisi_sas_phy_enable); | ||
1001 | |||
979 | static void hisi_sas_port_notify_formed(struct asd_sas_phy *sas_phy) | 1002 | static void hisi_sas_port_notify_formed(struct asd_sas_phy *sas_phy) |
980 | { | 1003 | { |
981 | struct sas_ha_struct *sas_ha = sas_phy->ha; | 1004 | struct sas_ha_struct *sas_ha = sas_phy->ha; |
@@ -1112,10 +1135,10 @@ static int hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no, | |||
1112 | sas_phy->phy->maximum_linkrate = max; | 1135 | sas_phy->phy->maximum_linkrate = max; |
1113 | sas_phy->phy->minimum_linkrate = min; | 1136 | sas_phy->phy->minimum_linkrate = min; |
1114 | 1137 | ||
1115 | hisi_hba->hw->phy_disable(hisi_hba, phy_no); | 1138 | hisi_sas_phy_enable(hisi_hba, phy_no, 0); |
1116 | msleep(100); | 1139 | msleep(100); |
1117 | hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, &_r); | 1140 | hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, &_r); |
1118 | hisi_hba->hw->phy_start(hisi_hba, phy_no); | 1141 | hisi_sas_phy_enable(hisi_hba, phy_no, 1); |
1119 | 1142 | ||
1120 | return 0; | 1143 | return 0; |
1121 | } | 1144 | } |
@@ -1133,13 +1156,13 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, | |||
1133 | break; | 1156 | break; |
1134 | 1157 | ||
1135 | case PHY_FUNC_LINK_RESET: | 1158 | case PHY_FUNC_LINK_RESET: |
1136 | hisi_hba->hw->phy_disable(hisi_hba, phy_no); | 1159 | hisi_sas_phy_enable(hisi_hba, phy_no, 0); |
1137 | msleep(100); | 1160 | msleep(100); |
1138 | hisi_hba->hw->phy_start(hisi_hba, phy_no); | 1161 | hisi_sas_phy_enable(hisi_hba, phy_no, 1); |
1139 | break; | 1162 | break; |
1140 | 1163 | ||
1141 | case PHY_FUNC_DISABLE: | 1164 | case PHY_FUNC_DISABLE: |
1142 | hisi_hba->hw->phy_disable(hisi_hba, phy_no); | 1165 | hisi_sas_phy_enable(hisi_hba, phy_no, 0); |
1143 | break; | 1166 | break; |
1144 | 1167 | ||
1145 | case PHY_FUNC_SET_LINK_RATE: | 1168 | case PHY_FUNC_SET_LINK_RATE: |
@@ -1264,8 +1287,7 @@ static int hisi_sas_exec_internal_tmf_task(struct domain_device *device, | |||
1264 | /* no error, but return the number of bytes of | 1287 | /* no error, but return the number of bytes of |
1265 | * underrun | 1288 | * underrun |
1266 | */ | 1289 | */ |
1267 | dev_warn(dev, "abort tmf: task to dev %016llx " | 1290 | dev_warn(dev, "abort tmf: task to dev %016llx resp: 0x%x sts 0x%x underrun\n", |
1268 | "resp: 0x%x sts 0x%x underrun\n", | ||
1269 | SAS_ADDR(device->sas_addr), | 1291 | SAS_ADDR(device->sas_addr), |
1270 | task->task_status.resp, | 1292 | task->task_status.resp, |
1271 | task->task_status.stat); | 1293 | task->task_status.stat); |
@@ -1280,10 +1302,16 @@ static int hisi_sas_exec_internal_tmf_task(struct domain_device *device, | |||
1280 | break; | 1302 | break; |
1281 | } | 1303 | } |
1282 | 1304 | ||
1283 | dev_warn(dev, "abort tmf: task to dev " | 1305 | if (task->task_status.resp == SAS_TASK_COMPLETE && |
1284 | "%016llx resp: 0x%x status 0x%x\n", | 1306 | task->task_status.stat == SAS_OPEN_REJECT) { |
1285 | SAS_ADDR(device->sas_addr), task->task_status.resp, | 1307 | dev_warn(dev, "abort tmf: open reject failed\n"); |
1286 | task->task_status.stat); | 1308 | res = -EIO; |
1309 | } else { | ||
1310 | dev_warn(dev, "abort tmf: task to dev %016llx resp: 0x%x status 0x%x\n", | ||
1311 | SAS_ADDR(device->sas_addr), | ||
1312 | task->task_status.resp, | ||
1313 | task->task_status.stat); | ||
1314 | } | ||
1287 | sas_free_task(task); | 1315 | sas_free_task(task); |
1288 | task = NULL; | 1316 | task = NULL; |
1289 | } | 1317 | } |
@@ -1427,9 +1455,9 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 old_state, | |||
1427 | sas_ha->notify_port_event(sas_phy, | 1455 | sas_ha->notify_port_event(sas_phy, |
1428 | PORTE_BROADCAST_RCVD); | 1456 | PORTE_BROADCAST_RCVD); |
1429 | } | 1457 | } |
1430 | } else if (old_state & (1 << phy_no)) | 1458 | } else { |
1431 | /* PHY down but was up before */ | ||
1432 | hisi_sas_phy_down(hisi_hba, phy_no, 0); | 1459 | hisi_sas_phy_down(hisi_hba, phy_no, 0); |
1460 | } | ||
1433 | 1461 | ||
1434 | } | 1462 | } |
1435 | } | 1463 | } |
@@ -1711,7 +1739,7 @@ static int hisi_sas_abort_task_set(struct domain_device *device, u8 *lun) | |||
1711 | struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); | 1739 | struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); |
1712 | struct device *dev = hisi_hba->dev; | 1740 | struct device *dev = hisi_hba->dev; |
1713 | struct hisi_sas_tmf_task tmf_task; | 1741 | struct hisi_sas_tmf_task tmf_task; |
1714 | int rc = TMF_RESP_FUNC_FAILED; | 1742 | int rc; |
1715 | 1743 | ||
1716 | rc = hisi_sas_internal_task_abort(hisi_hba, device, | 1744 | rc = hisi_sas_internal_task_abort(hisi_hba, device, |
1717 | HISI_SAS_INT_ABT_DEV, 0); | 1745 | HISI_SAS_INT_ABT_DEV, 0); |
@@ -1803,7 +1831,7 @@ static int hisi_sas_I_T_nexus_reset(struct domain_device *device) | |||
1803 | 1831 | ||
1804 | if (dev_is_sata(device)) { | 1832 | if (dev_is_sata(device)) { |
1805 | rc = hisi_sas_softreset_ata_disk(device); | 1833 | rc = hisi_sas_softreset_ata_disk(device); |
1806 | if (rc) | 1834 | if (rc == TMF_RESP_FUNC_FAILED) |
1807 | return TMF_RESP_FUNC_FAILED; | 1835 | return TMF_RESP_FUNC_FAILED; |
1808 | } | 1836 | } |
1809 | 1837 | ||
@@ -2100,10 +2128,8 @@ _hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, | |||
2100 | } | 2128 | } |
2101 | 2129 | ||
2102 | exit: | 2130 | exit: |
2103 | dev_dbg(dev, "internal task abort: task to dev %016llx task=%p " | 2131 | dev_dbg(dev, "internal task abort: task to dev %016llx task=%p resp: 0x%x sts 0x%x\n", |
2104 | "resp: 0x%x sts 0x%x\n", | 2132 | SAS_ADDR(device->sas_addr), task, |
2105 | SAS_ADDR(device->sas_addr), | ||
2106 | task, | ||
2107 | task->task_status.resp, /* 0 is complete, -1 is undelivered */ | 2133 | task->task_status.resp, /* 0 is complete, -1 is undelivered */ |
2108 | task->task_status.stat); | 2134 | task->task_status.stat); |
2109 | sas_free_task(task); | 2135 | sas_free_task(task); |
@@ -2172,16 +2198,18 @@ static void hisi_sas_phy_disconnected(struct hisi_sas_phy *phy) | |||
2172 | { | 2198 | { |
2173 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | 2199 | struct asd_sas_phy *sas_phy = &phy->sas_phy; |
2174 | struct sas_phy *sphy = sas_phy->phy; | 2200 | struct sas_phy *sphy = sas_phy->phy; |
2175 | struct sas_phy_data *d = sphy->hostdata; | 2201 | unsigned long flags; |
2176 | 2202 | ||
2177 | phy->phy_attached = 0; | 2203 | phy->phy_attached = 0; |
2178 | phy->phy_type = 0; | 2204 | phy->phy_type = 0; |
2179 | phy->port = NULL; | 2205 | phy->port = NULL; |
2180 | 2206 | ||
2181 | if (d->enable) | 2207 | spin_lock_irqsave(&phy->lock, flags); |
2208 | if (phy->enable) | ||
2182 | sphy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN; | 2209 | sphy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN; |
2183 | else | 2210 | else |
2184 | sphy->negotiated_linkrate = SAS_PHY_DISABLED; | 2211 | sphy->negotiated_linkrate = SAS_PHY_DISABLED; |
2212 | spin_unlock_irqrestore(&phy->lock, flags); | ||
2185 | } | 2213 | } |
2186 | 2214 | ||
2187 | void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy) | 2215 | void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy) |
@@ -2234,6 +2262,19 @@ void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba) | |||
2234 | } | 2262 | } |
2235 | EXPORT_SYMBOL_GPL(hisi_sas_kill_tasklets); | 2263 | EXPORT_SYMBOL_GPL(hisi_sas_kill_tasklets); |
2236 | 2264 | ||
2265 | int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type) | ||
2266 | { | ||
2267 | struct hisi_hba *hisi_hba = shost_priv(shost); | ||
2268 | |||
2269 | if (reset_type != SCSI_ADAPTER_RESET) | ||
2270 | return -EOPNOTSUPP; | ||
2271 | |||
2272 | queue_work(hisi_hba->wq, &hisi_hba->rst_work); | ||
2273 | |||
2274 | return 0; | ||
2275 | } | ||
2276 | EXPORT_SYMBOL_GPL(hisi_sas_host_reset); | ||
2277 | |||
2237 | struct scsi_transport_template *hisi_sas_stt; | 2278 | struct scsi_transport_template *hisi_sas_stt; |
2238 | EXPORT_SYMBOL_GPL(hisi_sas_stt); | 2279 | EXPORT_SYMBOL_GPL(hisi_sas_stt); |
2239 | 2280 | ||
@@ -2491,22 +2532,19 @@ int hisi_sas_get_fw_info(struct hisi_hba *hisi_hba) | |||
2491 | 2532 | ||
2492 | if (device_property_read_u32(dev, "ctrl-reset-reg", | 2533 | if (device_property_read_u32(dev, "ctrl-reset-reg", |
2493 | &hisi_hba->ctrl_reset_reg)) { | 2534 | &hisi_hba->ctrl_reset_reg)) { |
2494 | dev_err(dev, | 2535 | dev_err(dev, "could not get property ctrl-reset-reg\n"); |
2495 | "could not get property ctrl-reset-reg\n"); | ||
2496 | return -ENOENT; | 2536 | return -ENOENT; |
2497 | } | 2537 | } |
2498 | 2538 | ||
2499 | if (device_property_read_u32(dev, "ctrl-reset-sts-reg", | 2539 | if (device_property_read_u32(dev, "ctrl-reset-sts-reg", |
2500 | &hisi_hba->ctrl_reset_sts_reg)) { | 2540 | &hisi_hba->ctrl_reset_sts_reg)) { |
2501 | dev_err(dev, | 2541 | dev_err(dev, "could not get property ctrl-reset-sts-reg\n"); |
2502 | "could not get property ctrl-reset-sts-reg\n"); | ||
2503 | return -ENOENT; | 2542 | return -ENOENT; |
2504 | } | 2543 | } |
2505 | 2544 | ||
2506 | if (device_property_read_u32(dev, "ctrl-clock-ena-reg", | 2545 | if (device_property_read_u32(dev, "ctrl-clock-ena-reg", |
2507 | &hisi_hba->ctrl_clock_ena_reg)) { | 2546 | &hisi_hba->ctrl_clock_ena_reg)) { |
2508 | dev_err(dev, | 2547 | dev_err(dev, "could not get property ctrl-clock-ena-reg\n"); |
2509 | "could not get property ctrl-clock-ena-reg\n"); | ||
2510 | return -ENOENT; | 2548 | return -ENOENT; |
2511 | } | 2549 | } |
2512 | } | 2550 | } |
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 293807443480..78fe7d344848 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | |||
@@ -798,16 +798,11 @@ static void start_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) | |||
798 | enable_phy_v1_hw(hisi_hba, phy_no); | 798 | enable_phy_v1_hw(hisi_hba, phy_no); |
799 | } | 799 | } |
800 | 800 | ||
801 | static void stop_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) | ||
802 | { | ||
803 | disable_phy_v1_hw(hisi_hba, phy_no); | ||
804 | } | ||
805 | |||
806 | static void phy_hard_reset_v1_hw(struct hisi_hba *hisi_hba, int phy_no) | 801 | static void phy_hard_reset_v1_hw(struct hisi_hba *hisi_hba, int phy_no) |
807 | { | 802 | { |
808 | stop_phy_v1_hw(hisi_hba, phy_no); | 803 | hisi_sas_phy_enable(hisi_hba, phy_no, 0); |
809 | msleep(100); | 804 | msleep(100); |
810 | start_phy_v1_hw(hisi_hba, phy_no); | 805 | hisi_sas_phy_enable(hisi_hba, phy_no, 1); |
811 | } | 806 | } |
812 | 807 | ||
813 | static void start_phys_v1_hw(struct timer_list *t) | 808 | static void start_phys_v1_hw(struct timer_list *t) |
@@ -817,7 +812,7 @@ static void start_phys_v1_hw(struct timer_list *t) | |||
817 | 812 | ||
818 | for (i = 0; i < hisi_hba->n_phy; i++) { | 813 | for (i = 0; i < hisi_hba->n_phy; i++) { |
819 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x12a); | 814 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0x12a); |
820 | start_phy_v1_hw(hisi_hba, i); | 815 | hisi_sas_phy_enable(hisi_hba, i, 1); |
821 | } | 816 | } |
822 | } | 817 | } |
823 | 818 | ||
@@ -1695,8 +1690,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) | |||
1695 | for (j = 0; j < HISI_SAS_PHY_INT_NR; j++, idx++) { | 1690 | for (j = 0; j < HISI_SAS_PHY_INT_NR; j++, idx++) { |
1696 | irq = platform_get_irq(pdev, idx); | 1691 | irq = platform_get_irq(pdev, idx); |
1697 | if (!irq) { | 1692 | if (!irq) { |
1698 | dev_err(dev, | 1693 | dev_err(dev, "irq init: fail map phy interrupt %d\n", |
1699 | "irq init: fail map phy interrupt %d\n", | ||
1700 | idx); | 1694 | idx); |
1701 | return -ENOENT; | 1695 | return -ENOENT; |
1702 | } | 1696 | } |
@@ -1704,8 +1698,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) | |||
1704 | rc = devm_request_irq(dev, irq, phy_interrupts[j], 0, | 1698 | rc = devm_request_irq(dev, irq, phy_interrupts[j], 0, |
1705 | DRV_NAME " phy", phy); | 1699 | DRV_NAME " phy", phy); |
1706 | if (rc) { | 1700 | if (rc) { |
1707 | dev_err(dev, "irq init: could not request " | 1701 | dev_err(dev, "irq init: could not request phy interrupt %d, rc=%d\n", |
1708 | "phy interrupt %d, rc=%d\n", | ||
1709 | irq, rc); | 1702 | irq, rc); |
1710 | return -ENOENT; | 1703 | return -ENOENT; |
1711 | } | 1704 | } |
@@ -1742,8 +1735,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) | |||
1742 | rc = devm_request_irq(dev, irq, fatal_interrupts[i], 0, | 1735 | rc = devm_request_irq(dev, irq, fatal_interrupts[i], 0, |
1743 | DRV_NAME " fatal", hisi_hba); | 1736 | DRV_NAME " fatal", hisi_hba); |
1744 | if (rc) { | 1737 | if (rc) { |
1745 | dev_err(dev, | 1738 | dev_err(dev, "irq init: could not request fatal interrupt %d, rc=%d\n", |
1746 | "irq init: could not request fatal interrupt %d, rc=%d\n", | ||
1747 | irq, rc); | 1739 | irq, rc); |
1748 | return -ENOENT; | 1740 | return -ENOENT; |
1749 | } | 1741 | } |
@@ -1823,6 +1815,7 @@ static struct scsi_host_template sht_v1_hw = { | |||
1823 | .target_destroy = sas_target_destroy, | 1815 | .target_destroy = sas_target_destroy, |
1824 | .ioctl = sas_ioctl, | 1816 | .ioctl = sas_ioctl, |
1825 | .shost_attrs = host_attrs_v1_hw, | 1817 | .shost_attrs = host_attrs_v1_hw, |
1818 | .host_reset = hisi_sas_host_reset, | ||
1826 | }; | 1819 | }; |
1827 | 1820 | ||
1828 | static const struct hisi_sas_hw hisi_sas_v1_hw = { | 1821 | static const struct hisi_sas_hw hisi_sas_v1_hw = { |
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 89160ab3efb0..d4650bed8274 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | |||
@@ -1546,14 +1546,14 @@ static void phy_hard_reset_v2_hw(struct hisi_hba *hisi_hba, int phy_no) | |||
1546 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; | 1546 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
1547 | u32 txid_auto; | 1547 | u32 txid_auto; |
1548 | 1548 | ||
1549 | disable_phy_v2_hw(hisi_hba, phy_no); | 1549 | hisi_sas_phy_enable(hisi_hba, phy_no, 0); |
1550 | if (phy->identify.device_type == SAS_END_DEVICE) { | 1550 | if (phy->identify.device_type == SAS_END_DEVICE) { |
1551 | txid_auto = hisi_sas_phy_read32(hisi_hba, phy_no, TXID_AUTO); | 1551 | txid_auto = hisi_sas_phy_read32(hisi_hba, phy_no, TXID_AUTO); |
1552 | hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO, | 1552 | hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO, |
1553 | txid_auto | TX_HARDRST_MSK); | 1553 | txid_auto | TX_HARDRST_MSK); |
1554 | } | 1554 | } |
1555 | msleep(100); | 1555 | msleep(100); |
1556 | start_phy_v2_hw(hisi_hba, phy_no); | 1556 | hisi_sas_phy_enable(hisi_hba, phy_no, 1); |
1557 | } | 1557 | } |
1558 | 1558 | ||
1559 | static void phy_get_events_v2_hw(struct hisi_hba *hisi_hba, int phy_no) | 1559 | static void phy_get_events_v2_hw(struct hisi_hba *hisi_hba, int phy_no) |
@@ -1586,7 +1586,7 @@ static void phys_init_v2_hw(struct hisi_hba *hisi_hba) | |||
1586 | if (!sas_phy->phy->enabled) | 1586 | if (!sas_phy->phy->enabled) |
1587 | continue; | 1587 | continue; |
1588 | 1588 | ||
1589 | start_phy_v2_hw(hisi_hba, i); | 1589 | hisi_sas_phy_enable(hisi_hba, i, 1); |
1590 | } | 1590 | } |
1591 | } | 1591 | } |
1592 | 1592 | ||
@@ -2423,14 +2423,12 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) | |||
2423 | slot_err_v2_hw(hisi_hba, task, slot, 2); | 2423 | slot_err_v2_hw(hisi_hba, task, slot, 2); |
2424 | 2424 | ||
2425 | if (ts->stat != SAS_DATA_UNDERRUN) | 2425 | if (ts->stat != SAS_DATA_UNDERRUN) |
2426 | dev_info(dev, "erroneous completion iptt=%d task=%p dev id=%d " | 2426 | dev_info(dev, "erroneous completion iptt=%d task=%p dev id=%d CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", |
2427 | "CQ hdr: 0x%x 0x%x 0x%x 0x%x " | 2427 | slot->idx, task, sas_dev->device_id, |
2428 | "Error info: 0x%x 0x%x 0x%x 0x%x\n", | 2428 | complete_hdr->dw0, complete_hdr->dw1, |
2429 | slot->idx, task, sas_dev->device_id, | 2429 | complete_hdr->act, complete_hdr->dw3, |
2430 | complete_hdr->dw0, complete_hdr->dw1, | 2430 | error_info[0], error_info[1], |
2431 | complete_hdr->act, complete_hdr->dw3, | 2431 | error_info[2], error_info[3]); |
2432 | error_info[0], error_info[1], | ||
2433 | error_info[2], error_info[3]); | ||
2434 | 2432 | ||
2435 | if (unlikely(slot->abort)) | 2433 | if (unlikely(slot->abort)) |
2436 | return ts->stat; | 2434 | return ts->stat; |
@@ -2502,7 +2500,7 @@ out: | |||
2502 | spin_lock_irqsave(&device->done_lock, flags); | 2500 | spin_lock_irqsave(&device->done_lock, flags); |
2503 | if (test_bit(SAS_HA_FROZEN, &ha->state)) { | 2501 | if (test_bit(SAS_HA_FROZEN, &ha->state)) { |
2504 | spin_unlock_irqrestore(&device->done_lock, flags); | 2502 | spin_unlock_irqrestore(&device->done_lock, flags); |
2505 | dev_info(dev, "slot complete: task(%p) ignored\n ", | 2503 | dev_info(dev, "slot complete: task(%p) ignored\n", |
2506 | task); | 2504 | task); |
2507 | return sts; | 2505 | return sts; |
2508 | } | 2506 | } |
@@ -2935,7 +2933,7 @@ static irqreturn_t int_chnl_int_v2_hw(int irq_no, void *p) | |||
2935 | 2933 | ||
2936 | if (irq_value2 & BIT(CHL_INT2_SL_IDAF_TOUT_CONF_OFF)) { | 2934 | if (irq_value2 & BIT(CHL_INT2_SL_IDAF_TOUT_CONF_OFF)) { |
2937 | dev_warn(dev, "phy%d identify timeout\n", | 2935 | dev_warn(dev, "phy%d identify timeout\n", |
2938 | phy_no); | 2936 | phy_no); |
2939 | hisi_sas_notify_phy_event(phy, | 2937 | hisi_sas_notify_phy_event(phy, |
2940 | HISI_PHYE_LINK_RESET); | 2938 | HISI_PHYE_LINK_RESET); |
2941 | } | 2939 | } |
@@ -3036,7 +3034,7 @@ static const struct hisi_sas_hw_error axi_error[] = { | |||
3036 | { .msk = BIT(5), .msg = "SATA_AXI_R_ERR" }, | 3034 | { .msk = BIT(5), .msg = "SATA_AXI_R_ERR" }, |
3037 | { .msk = BIT(6), .msg = "DQE_AXI_R_ERR" }, | 3035 | { .msk = BIT(6), .msg = "DQE_AXI_R_ERR" }, |
3038 | { .msk = BIT(7), .msg = "CQE_AXI_W_ERR" }, | 3036 | { .msk = BIT(7), .msg = "CQE_AXI_W_ERR" }, |
3039 | {}, | 3037 | {} |
3040 | }; | 3038 | }; |
3041 | 3039 | ||
3042 | static const struct hisi_sas_hw_error fifo_error[] = { | 3040 | static const struct hisi_sas_hw_error fifo_error[] = { |
@@ -3045,7 +3043,7 @@ static const struct hisi_sas_hw_error fifo_error[] = { | |||
3045 | { .msk = BIT(10), .msg = "GETDQE_FIFO" }, | 3043 | { .msk = BIT(10), .msg = "GETDQE_FIFO" }, |
3046 | { .msk = BIT(11), .msg = "CMDP_FIFO" }, | 3044 | { .msk = BIT(11), .msg = "CMDP_FIFO" }, |
3047 | { .msk = BIT(12), .msg = "AWTCTRL_FIFO" }, | 3045 | { .msk = BIT(12), .msg = "AWTCTRL_FIFO" }, |
3048 | {}, | 3046 | {} |
3049 | }; | 3047 | }; |
3050 | 3048 | ||
3051 | static const struct hisi_sas_hw_error fatal_axi_errors[] = { | 3049 | static const struct hisi_sas_hw_error fatal_axi_errors[] = { |
@@ -3109,12 +3107,12 @@ static irqreturn_t fatal_axi_int_v2_hw(int irq_no, void *p) | |||
3109 | if (!(err_value & sub->msk)) | 3107 | if (!(err_value & sub->msk)) |
3110 | continue; | 3108 | continue; |
3111 | dev_err(dev, "%s (0x%x) found!\n", | 3109 | dev_err(dev, "%s (0x%x) found!\n", |
3112 | sub->msg, irq_value); | 3110 | sub->msg, irq_value); |
3113 | queue_work(hisi_hba->wq, &hisi_hba->rst_work); | 3111 | queue_work(hisi_hba->wq, &hisi_hba->rst_work); |
3114 | } | 3112 | } |
3115 | } else { | 3113 | } else { |
3116 | dev_err(dev, "%s (0x%x) found!\n", | 3114 | dev_err(dev, "%s (0x%x) found!\n", |
3117 | axi_error->msg, irq_value); | 3115 | axi_error->msg, irq_value); |
3118 | queue_work(hisi_hba->wq, &hisi_hba->rst_work); | 3116 | queue_work(hisi_hba->wq, &hisi_hba->rst_work); |
3119 | } | 3117 | } |
3120 | } | 3118 | } |
@@ -3258,7 +3256,7 @@ static irqreturn_t sata_int_v2_hw(int irq_no, void *p) | |||
3258 | /* check ERR bit of Status Register */ | 3256 | /* check ERR bit of Status Register */ |
3259 | if (fis->status & ATA_ERR) { | 3257 | if (fis->status & ATA_ERR) { |
3260 | dev_warn(dev, "sata int: phy%d FIS status: 0x%x\n", phy_no, | 3258 | dev_warn(dev, "sata int: phy%d FIS status: 0x%x\n", phy_no, |
3261 | fis->status); | 3259 | fis->status); |
3262 | hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); | 3260 | hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); |
3263 | res = IRQ_NONE; | 3261 | res = IRQ_NONE; |
3264 | goto end; | 3262 | goto end; |
@@ -3349,8 +3347,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) | |||
3349 | rc = devm_request_irq(dev, irq, phy_interrupts[i], 0, | 3347 | rc = devm_request_irq(dev, irq, phy_interrupts[i], 0, |
3350 | DRV_NAME " phy", hisi_hba); | 3348 | DRV_NAME " phy", hisi_hba); |
3351 | if (rc) { | 3349 | if (rc) { |
3352 | dev_err(dev, "irq init: could not request " | 3350 | dev_err(dev, "irq init: could not request phy interrupt %d, rc=%d\n", |
3353 | "phy interrupt %d, rc=%d\n", | ||
3354 | irq, rc); | 3351 | irq, rc); |
3355 | rc = -ENOENT; | 3352 | rc = -ENOENT; |
3356 | goto free_phy_int_irqs; | 3353 | goto free_phy_int_irqs; |
@@ -3364,8 +3361,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) | |||
3364 | rc = devm_request_irq(dev, irq, sata_int_v2_hw, 0, | 3361 | rc = devm_request_irq(dev, irq, sata_int_v2_hw, 0, |
3365 | DRV_NAME " sata", phy); | 3362 | DRV_NAME " sata", phy); |
3366 | if (rc) { | 3363 | if (rc) { |
3367 | dev_err(dev, "irq init: could not request " | 3364 | dev_err(dev, "irq init: could not request sata interrupt %d, rc=%d\n", |
3368 | "sata interrupt %d, rc=%d\n", | ||
3369 | irq, rc); | 3365 | irq, rc); |
3370 | rc = -ENOENT; | 3366 | rc = -ENOENT; |
3371 | goto free_sata_int_irqs; | 3367 | goto free_sata_int_irqs; |
@@ -3377,8 +3373,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) | |||
3377 | rc = devm_request_irq(dev, irq, fatal_interrupts[fatal_no], 0, | 3373 | rc = devm_request_irq(dev, irq, fatal_interrupts[fatal_no], 0, |
3378 | DRV_NAME " fatal", hisi_hba); | 3374 | DRV_NAME " fatal", hisi_hba); |
3379 | if (rc) { | 3375 | if (rc) { |
3380 | dev_err(dev, | 3376 | dev_err(dev, "irq init: could not request fatal interrupt %d, rc=%d\n", |
3381 | "irq init: could not request fatal interrupt %d, rc=%d\n", | ||
3382 | irq, rc); | 3377 | irq, rc); |
3383 | rc = -ENOENT; | 3378 | rc = -ENOENT; |
3384 | goto free_fatal_int_irqs; | 3379 | goto free_fatal_int_irqs; |
@@ -3393,8 +3388,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba) | |||
3393 | rc = devm_request_irq(dev, irq, cq_interrupt_v2_hw, 0, | 3388 | rc = devm_request_irq(dev, irq, cq_interrupt_v2_hw, 0, |
3394 | DRV_NAME " cq", cq); | 3389 | DRV_NAME " cq", cq); |
3395 | if (rc) { | 3390 | if (rc) { |
3396 | dev_err(dev, | 3391 | dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", |
3397 | "irq init: could not request cq interrupt %d, rc=%d\n", | ||
3398 | irq, rc); | 3392 | irq, rc); |
3399 | rc = -ENOENT; | 3393 | rc = -ENOENT; |
3400 | goto free_cq_int_irqs; | 3394 | goto free_cq_int_irqs; |
@@ -3546,7 +3540,7 @@ static int write_gpio_v2_hw(struct hisi_hba *hisi_hba, u8 reg_type, | |||
3546 | break; | 3540 | break; |
3547 | default: | 3541 | default: |
3548 | dev_err(dev, "write gpio: unsupported or bad reg type %d\n", | 3542 | dev_err(dev, "write gpio: unsupported or bad reg type %d\n", |
3549 | reg_type); | 3543 | reg_type); |
3550 | return -EINVAL; | 3544 | return -EINVAL; |
3551 | } | 3545 | } |
3552 | 3546 | ||
@@ -3599,6 +3593,7 @@ static struct scsi_host_template sht_v2_hw = { | |||
3599 | .target_destroy = sas_target_destroy, | 3593 | .target_destroy = sas_target_destroy, |
3600 | .ioctl = sas_ioctl, | 3594 | .ioctl = sas_ioctl, |
3601 | .shost_attrs = host_attrs_v2_hw, | 3595 | .shost_attrs = host_attrs_v2_hw, |
3596 | .host_reset = hisi_sas_host_reset, | ||
3602 | }; | 3597 | }; |
3603 | 3598 | ||
3604 | static const struct hisi_sas_hw hisi_sas_v2_hw = { | 3599 | static const struct hisi_sas_hw hisi_sas_v2_hw = { |
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 086695a4099f..49620c2411df 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | |||
@@ -52,7 +52,36 @@ | |||
52 | #define CFG_ABT_SET_IPTT_DONE 0xd8 | 52 | #define CFG_ABT_SET_IPTT_DONE 0xd8 |
53 | #define CFG_ABT_SET_IPTT_DONE_OFF 0 | 53 | #define CFG_ABT_SET_IPTT_DONE_OFF 0 |
54 | #define HGC_IOMB_PROC1_STATUS 0x104 | 54 | #define HGC_IOMB_PROC1_STATUS 0x104 |
55 | #define HGC_LM_DFX_STATUS2 0x128 | ||
56 | #define HGC_LM_DFX_STATUS2_IOSTLIST_OFF 0 | ||
57 | #define HGC_LM_DFX_STATUS2_IOSTLIST_MSK (0xfff << \ | ||
58 | HGC_LM_DFX_STATUS2_IOSTLIST_OFF) | ||
59 | #define HGC_LM_DFX_STATUS2_ITCTLIST_OFF 12 | ||
60 | #define HGC_LM_DFX_STATUS2_ITCTLIST_MSK (0x7ff << \ | ||
61 | HGC_LM_DFX_STATUS2_ITCTLIST_OFF) | ||
62 | #define HGC_CQE_ECC_ADDR 0x13c | ||
63 | #define HGC_CQE_ECC_1B_ADDR_OFF 0 | ||
64 | #define HGC_CQE_ECC_1B_ADDR_MSK (0x3f << HGC_CQE_ECC_1B_ADDR_OFF) | ||
65 | #define HGC_CQE_ECC_MB_ADDR_OFF 8 | ||
66 | #define HGC_CQE_ECC_MB_ADDR_MSK (0x3f << HGC_CQE_ECC_MB_ADDR_OFF) | ||
67 | #define HGC_IOST_ECC_ADDR 0x140 | ||
68 | #define HGC_IOST_ECC_1B_ADDR_OFF 0 | ||
69 | #define HGC_IOST_ECC_1B_ADDR_MSK (0x3ff << HGC_IOST_ECC_1B_ADDR_OFF) | ||
70 | #define HGC_IOST_ECC_MB_ADDR_OFF 16 | ||
71 | #define HGC_IOST_ECC_MB_ADDR_MSK (0x3ff << HGC_IOST_ECC_MB_ADDR_OFF) | ||
72 | #define HGC_DQE_ECC_ADDR 0x144 | ||
73 | #define HGC_DQE_ECC_1B_ADDR_OFF 0 | ||
74 | #define HGC_DQE_ECC_1B_ADDR_MSK (0xfff << HGC_DQE_ECC_1B_ADDR_OFF) | ||
75 | #define HGC_DQE_ECC_MB_ADDR_OFF 16 | ||
76 | #define HGC_DQE_ECC_MB_ADDR_MSK (0xfff << HGC_DQE_ECC_MB_ADDR_OFF) | ||
55 | #define CHNL_INT_STATUS 0x148 | 77 | #define CHNL_INT_STATUS 0x148 |
78 | #define HGC_ITCT_ECC_ADDR 0x150 | ||
79 | #define HGC_ITCT_ECC_1B_ADDR_OFF 0 | ||
80 | #define HGC_ITCT_ECC_1B_ADDR_MSK (0x3ff << \ | ||
81 | HGC_ITCT_ECC_1B_ADDR_OFF) | ||
82 | #define HGC_ITCT_ECC_MB_ADDR_OFF 16 | ||
83 | #define HGC_ITCT_ECC_MB_ADDR_MSK (0x3ff << \ | ||
84 | HGC_ITCT_ECC_MB_ADDR_OFF) | ||
56 | #define HGC_AXI_FIFO_ERR_INFO 0x154 | 85 | #define HGC_AXI_FIFO_ERR_INFO 0x154 |
57 | #define AXI_ERR_INFO_OFF 0 | 86 | #define AXI_ERR_INFO_OFF 0 |
58 | #define AXI_ERR_INFO_MSK (0xff << AXI_ERR_INFO_OFF) | 87 | #define AXI_ERR_INFO_MSK (0xff << AXI_ERR_INFO_OFF) |
@@ -81,6 +110,10 @@ | |||
81 | #define ENT_INT_SRC3_ITC_INT_OFF 15 | 110 | #define ENT_INT_SRC3_ITC_INT_OFF 15 |
82 | #define ENT_INT_SRC3_ITC_INT_MSK (0x1 << ENT_INT_SRC3_ITC_INT_OFF) | 111 | #define ENT_INT_SRC3_ITC_INT_MSK (0x1 << ENT_INT_SRC3_ITC_INT_OFF) |
83 | #define ENT_INT_SRC3_ABT_OFF 16 | 112 | #define ENT_INT_SRC3_ABT_OFF 16 |
113 | #define ENT_INT_SRC3_DQE_POISON_OFF 18 | ||
114 | #define ENT_INT_SRC3_IOST_POISON_OFF 19 | ||
115 | #define ENT_INT_SRC3_ITCT_POISON_OFF 20 | ||
116 | #define ENT_INT_SRC3_ITCT_NCQ_POISON_OFF 21 | ||
84 | #define ENT_INT_SRC_MSK1 0x1c4 | 117 | #define ENT_INT_SRC_MSK1 0x1c4 |
85 | #define ENT_INT_SRC_MSK2 0x1c8 | 118 | #define ENT_INT_SRC_MSK2 0x1c8 |
86 | #define ENT_INT_SRC_MSK3 0x1cc | 119 | #define ENT_INT_SRC_MSK3 0x1cc |
@@ -90,6 +123,28 @@ | |||
90 | #define HGC_COM_INT_MSK 0x1d8 | 123 | #define HGC_COM_INT_MSK 0x1d8 |
91 | #define ENT_INT_SRC_MSK3_ENT95_MSK_MSK (0x1 << ENT_INT_SRC_MSK3_ENT95_MSK_OFF) | 124 | #define ENT_INT_SRC_MSK3_ENT95_MSK_MSK (0x1 << ENT_INT_SRC_MSK3_ENT95_MSK_OFF) |
92 | #define SAS_ECC_INTR 0x1e8 | 125 | #define SAS_ECC_INTR 0x1e8 |
126 | #define SAS_ECC_INTR_DQE_ECC_1B_OFF 0 | ||
127 | #define SAS_ECC_INTR_DQE_ECC_MB_OFF 1 | ||
128 | #define SAS_ECC_INTR_IOST_ECC_1B_OFF 2 | ||
129 | #define SAS_ECC_INTR_IOST_ECC_MB_OFF 3 | ||
130 | #define SAS_ECC_INTR_ITCT_ECC_1B_OFF 4 | ||
131 | #define SAS_ECC_INTR_ITCT_ECC_MB_OFF 5 | ||
132 | #define SAS_ECC_INTR_ITCTLIST_ECC_1B_OFF 6 | ||
133 | #define SAS_ECC_INTR_ITCTLIST_ECC_MB_OFF 7 | ||
134 | #define SAS_ECC_INTR_IOSTLIST_ECC_1B_OFF 8 | ||
135 | #define SAS_ECC_INTR_IOSTLIST_ECC_MB_OFF 9 | ||
136 | #define SAS_ECC_INTR_CQE_ECC_1B_OFF 10 | ||
137 | #define SAS_ECC_INTR_CQE_ECC_MB_OFF 11 | ||
138 | #define SAS_ECC_INTR_NCQ_MEM0_ECC_1B_OFF 12 | ||
139 | #define SAS_ECC_INTR_NCQ_MEM0_ECC_MB_OFF 13 | ||
140 | #define SAS_ECC_INTR_NCQ_MEM1_ECC_1B_OFF 14 | ||
141 | #define SAS_ECC_INTR_NCQ_MEM1_ECC_MB_OFF 15 | ||
142 | #define SAS_ECC_INTR_NCQ_MEM2_ECC_1B_OFF 16 | ||
143 | #define SAS_ECC_INTR_NCQ_MEM2_ECC_MB_OFF 17 | ||
144 | #define SAS_ECC_INTR_NCQ_MEM3_ECC_1B_OFF 18 | ||
145 | #define SAS_ECC_INTR_NCQ_MEM3_ECC_MB_OFF 19 | ||
146 | #define SAS_ECC_INTR_OOO_RAM_ECC_1B_OFF 20 | ||
147 | #define SAS_ECC_INTR_OOO_RAM_ECC_MB_OFF 21 | ||
93 | #define SAS_ECC_INTR_MSK 0x1ec | 148 | #define SAS_ECC_INTR_MSK 0x1ec |
94 | #define HGC_ERR_STAT_EN 0x238 | 149 | #define HGC_ERR_STAT_EN 0x238 |
95 | #define CQE_SEND_CNT 0x248 | 150 | #define CQE_SEND_CNT 0x248 |
@@ -105,6 +160,20 @@ | |||
105 | #define COMPL_Q_0_DEPTH 0x4e8 | 160 | #define COMPL_Q_0_DEPTH 0x4e8 |
106 | #define COMPL_Q_0_WR_PTR 0x4ec | 161 | #define COMPL_Q_0_WR_PTR 0x4ec |
107 | #define COMPL_Q_0_RD_PTR 0x4f0 | 162 | #define COMPL_Q_0_RD_PTR 0x4f0 |
163 | #define HGC_RXM_DFX_STATUS14 0xae8 | ||
164 | #define HGC_RXM_DFX_STATUS14_MEM0_OFF 0 | ||
165 | #define HGC_RXM_DFX_STATUS14_MEM0_MSK (0x1ff << \ | ||
166 | HGC_RXM_DFX_STATUS14_MEM0_OFF) | ||
167 | #define HGC_RXM_DFX_STATUS14_MEM1_OFF 9 | ||
168 | #define HGC_RXM_DFX_STATUS14_MEM1_MSK (0x1ff << \ | ||
169 | HGC_RXM_DFX_STATUS14_MEM1_OFF) | ||
170 | #define HGC_RXM_DFX_STATUS14_MEM2_OFF 18 | ||
171 | #define HGC_RXM_DFX_STATUS14_MEM2_MSK (0x1ff << \ | ||
172 | HGC_RXM_DFX_STATUS14_MEM2_OFF) | ||
173 | #define HGC_RXM_DFX_STATUS15 0xaec | ||
174 | #define HGC_RXM_DFX_STATUS15_MEM3_OFF 0 | ||
175 | #define HGC_RXM_DFX_STATUS15_MEM3_MSK (0x1ff << \ | ||
176 | HGC_RXM_DFX_STATUS15_MEM3_OFF) | ||
108 | #define AWQOS_AWCACHE_CFG 0xc84 | 177 | #define AWQOS_AWCACHE_CFG 0xc84 |
109 | #define ARQOS_ARCACHE_CFG 0xc88 | 178 | #define ARQOS_ARCACHE_CFG 0xc88 |
110 | #define HILINK_ERR_DFX 0xe04 | 179 | #define HILINK_ERR_DFX 0xe04 |
@@ -172,14 +241,18 @@ | |||
172 | #define CHL_INT0_PHY_RDY_OFF 5 | 241 | #define CHL_INT0_PHY_RDY_OFF 5 |
173 | #define CHL_INT0_PHY_RDY_MSK (0x1 << CHL_INT0_PHY_RDY_OFF) | 242 | #define CHL_INT0_PHY_RDY_MSK (0x1 << CHL_INT0_PHY_RDY_OFF) |
174 | #define CHL_INT1 (PORT_BASE + 0x1b8) | 243 | #define CHL_INT1 (PORT_BASE + 0x1b8) |
175 | #define CHL_INT1_DMAC_TX_ECC_ERR_OFF 15 | 244 | #define CHL_INT1_DMAC_TX_ECC_MB_ERR_OFF 15 |
176 | #define CHL_INT1_DMAC_TX_ECC_ERR_MSK (0x1 << CHL_INT1_DMAC_TX_ECC_ERR_OFF) | 245 | #define CHL_INT1_DMAC_TX_ECC_1B_ERR_OFF 16 |
177 | #define CHL_INT1_DMAC_RX_ECC_ERR_OFF 17 | 246 | #define CHL_INT1_DMAC_RX_ECC_MB_ERR_OFF 17 |
178 | #define CHL_INT1_DMAC_RX_ECC_ERR_MSK (0x1 << CHL_INT1_DMAC_RX_ECC_ERR_OFF) | 247 | #define CHL_INT1_DMAC_RX_ECC_1B_ERR_OFF 18 |
179 | #define CHL_INT1_DMAC_TX_AXI_WR_ERR_OFF 19 | 248 | #define CHL_INT1_DMAC_TX_AXI_WR_ERR_OFF 19 |
180 | #define CHL_INT1_DMAC_TX_AXI_RD_ERR_OFF 20 | 249 | #define CHL_INT1_DMAC_TX_AXI_RD_ERR_OFF 20 |
181 | #define CHL_INT1_DMAC_RX_AXI_WR_ERR_OFF 21 | 250 | #define CHL_INT1_DMAC_RX_AXI_WR_ERR_OFF 21 |
182 | #define CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF 22 | 251 | #define CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF 22 |
252 | #define CHL_INT1_DMAC_TX_FIFO_ERR_OFF 23 | ||
253 | #define CHL_INT1_DMAC_RX_FIFO_ERR_OFF 24 | ||
254 | #define CHL_INT1_DMAC_TX_AXI_RUSER_ERR_OFF 26 | ||
255 | #define CHL_INT1_DMAC_RX_AXI_RUSER_ERR_OFF 27 | ||
183 | #define CHL_INT2 (PORT_BASE + 0x1bc) | 256 | #define CHL_INT2 (PORT_BASE + 0x1bc) |
184 | #define CHL_INT2_SL_IDAF_TOUT_CONF_OFF 0 | 257 | #define CHL_INT2_SL_IDAF_TOUT_CONF_OFF 0 |
185 | #define CHL_INT2_RX_DISP_ERR_OFF 28 | 258 | #define CHL_INT2_RX_DISP_ERR_OFF 28 |
@@ -227,10 +300,8 @@ | |||
227 | #define AM_CFG_SINGLE_PORT_MAX_TRANS (0x5014) | 300 | #define AM_CFG_SINGLE_PORT_MAX_TRANS (0x5014) |
228 | #define AXI_CFG (0x5100) | 301 | #define AXI_CFG (0x5100) |
229 | #define AM_ROB_ECC_ERR_ADDR (0x510c) | 302 | #define AM_ROB_ECC_ERR_ADDR (0x510c) |
230 | #define AM_ROB_ECC_ONEBIT_ERR_ADDR_OFF 0 | 303 | #define AM_ROB_ECC_ERR_ADDR_OFF 0 |
231 | #define AM_ROB_ECC_ONEBIT_ERR_ADDR_MSK (0xff << AM_ROB_ECC_ONEBIT_ERR_ADDR_OFF) | 304 | #define AM_ROB_ECC_ERR_ADDR_MSK 0xffffffff |
232 | #define AM_ROB_ECC_MULBIT_ERR_ADDR_OFF 8 | ||
233 | #define AM_ROB_ECC_MULBIT_ERR_ADDR_MSK (0xff << AM_ROB_ECC_MULBIT_ERR_ADDR_OFF) | ||
234 | 305 | ||
235 | /* RAS registers need init */ | 306 | /* RAS registers need init */ |
236 | #define RAS_BASE (0x6000) | 307 | #define RAS_BASE (0x6000) |
@@ -408,6 +479,10 @@ struct hisi_sas_err_record_v3 { | |||
408 | #define BASE_VECTORS_V3_HW 16 | 479 | #define BASE_VECTORS_V3_HW 16 |
409 | #define MIN_AFFINE_VECTORS_V3_HW (BASE_VECTORS_V3_HW + 1) | 480 | #define MIN_AFFINE_VECTORS_V3_HW (BASE_VECTORS_V3_HW + 1) |
410 | 481 | ||
482 | enum { | ||
483 | DSM_FUNC_ERR_HANDLE_MSI = 0, | ||
484 | }; | ||
485 | |||
411 | static bool hisi_sas_intr_conv; | 486 | static bool hisi_sas_intr_conv; |
412 | MODULE_PARM_DESC(intr_conv, "interrupt converge enable (0-1)"); | 487 | MODULE_PARM_DESC(intr_conv, "interrupt converge enable (0-1)"); |
413 | 488 | ||
@@ -474,7 +549,6 @@ static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba, | |||
474 | 549 | ||
475 | static void init_reg_v3_hw(struct hisi_hba *hisi_hba) | 550 | static void init_reg_v3_hw(struct hisi_hba *hisi_hba) |
476 | { | 551 | { |
477 | struct pci_dev *pdev = hisi_hba->pci_dev; | ||
478 | int i; | 552 | int i; |
479 | 553 | ||
480 | /* Global registers init */ | 554 | /* Global registers init */ |
@@ -494,14 +568,11 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) | |||
494 | hisi_sas_write32(hisi_hba, ENT_INT_SRC3, 0xffffffff); | 568 | hisi_sas_write32(hisi_hba, ENT_INT_SRC3, 0xffffffff); |
495 | hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe); | 569 | hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe); |
496 | hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe); | 570 | hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe); |
497 | if (pdev->revision >= 0x21) | 571 | hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffc220ff); |
498 | hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffff7aff); | ||
499 | else | ||
500 | hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xfffe20ff); | ||
501 | hisi_sas_write32(hisi_hba, CHNL_PHYUPDOWN_INT_MSK, 0x0); | 572 | hisi_sas_write32(hisi_hba, CHNL_PHYUPDOWN_INT_MSK, 0x0); |
502 | hisi_sas_write32(hisi_hba, CHNL_ENT_INT_MSK, 0x0); | 573 | hisi_sas_write32(hisi_hba, CHNL_ENT_INT_MSK, 0x0); |
503 | hisi_sas_write32(hisi_hba, HGC_COM_INT_MSK, 0x0); | 574 | hisi_sas_write32(hisi_hba, HGC_COM_INT_MSK, 0x0); |
504 | hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0x0); | 575 | hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0x155555); |
505 | hisi_sas_write32(hisi_hba, AWQOS_AWCACHE_CFG, 0xf0f0); | 576 | hisi_sas_write32(hisi_hba, AWQOS_AWCACHE_CFG, 0xf0f0); |
506 | hisi_sas_write32(hisi_hba, ARQOS_ARCACHE_CFG, 0xf0f0); | 577 | hisi_sas_write32(hisi_hba, ARQOS_ARCACHE_CFG, 0xf0f0); |
507 | for (i = 0; i < hisi_hba->queue_count; i++) | 578 | for (i = 0; i < hisi_hba->queue_count; i++) |
@@ -532,12 +603,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) | |||
532 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff); | 603 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff); |
533 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff); | 604 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff); |
534 | hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000); | 605 | hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000); |
535 | if (pdev->revision >= 0x21) | 606 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xf2057fff); |
536 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, | ||
537 | 0xffffffff); | ||
538 | else | ||
539 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, | ||
540 | 0xff87ffff); | ||
541 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffbfe); | 607 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffbfe); |
542 | hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0); | 608 | hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0); |
543 | hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0); | 609 | hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0); |
@@ -804,6 +870,8 @@ static int reset_hw_v3_hw(struct hisi_hba *hisi_hba) | |||
804 | static int hw_init_v3_hw(struct hisi_hba *hisi_hba) | 870 | static int hw_init_v3_hw(struct hisi_hba *hisi_hba) |
805 | { | 871 | { |
806 | struct device *dev = hisi_hba->dev; | 872 | struct device *dev = hisi_hba->dev; |
873 | union acpi_object *obj; | ||
874 | guid_t guid; | ||
807 | int rc; | 875 | int rc; |
808 | 876 | ||
809 | rc = reset_hw_v3_hw(hisi_hba); | 877 | rc = reset_hw_v3_hw(hisi_hba); |
@@ -815,6 +883,19 @@ static int hw_init_v3_hw(struct hisi_hba *hisi_hba) | |||
815 | msleep(100); | 883 | msleep(100); |
816 | init_reg_v3_hw(hisi_hba); | 884 | init_reg_v3_hw(hisi_hba); |
817 | 885 | ||
886 | if (guid_parse("D5918B4B-37AE-4E10-A99F-E5E8A6EF4C1F", &guid)) { | ||
887 | dev_err(dev, "Parse GUID failed\n"); | ||
888 | return -EINVAL; | ||
889 | } | ||
890 | |||
891 | /* Switch over to MSI handling , from PCI AER default */ | ||
892 | obj = acpi_evaluate_dsm(ACPI_HANDLE(dev), &guid, 0, | ||
893 | DSM_FUNC_ERR_HANDLE_MSI, NULL); | ||
894 | if (!obj) | ||
895 | dev_warn(dev, "Switch over to MSI handling failed\n"); | ||
896 | else | ||
897 | ACPI_FREE(obj); | ||
898 | |||
818 | return 0; | 899 | return 0; |
819 | } | 900 | } |
820 | 901 | ||
@@ -856,14 +937,14 @@ static void phy_hard_reset_v3_hw(struct hisi_hba *hisi_hba, int phy_no) | |||
856 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; | 937 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
857 | u32 txid_auto; | 938 | u32 txid_auto; |
858 | 939 | ||
859 | disable_phy_v3_hw(hisi_hba, phy_no); | 940 | hisi_sas_phy_enable(hisi_hba, phy_no, 0); |
860 | if (phy->identify.device_type == SAS_END_DEVICE) { | 941 | if (phy->identify.device_type == SAS_END_DEVICE) { |
861 | txid_auto = hisi_sas_phy_read32(hisi_hba, phy_no, TXID_AUTO); | 942 | txid_auto = hisi_sas_phy_read32(hisi_hba, phy_no, TXID_AUTO); |
862 | hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO, | 943 | hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO, |
863 | txid_auto | TX_HARDRST_MSK); | 944 | txid_auto | TX_HARDRST_MSK); |
864 | } | 945 | } |
865 | msleep(100); | 946 | msleep(100); |
866 | start_phy_v3_hw(hisi_hba, phy_no); | 947 | hisi_sas_phy_enable(hisi_hba, phy_no, 1); |
867 | } | 948 | } |
868 | 949 | ||
869 | static enum sas_linkrate phy_get_max_linkrate_v3_hw(void) | 950 | static enum sas_linkrate phy_get_max_linkrate_v3_hw(void) |
@@ -882,7 +963,7 @@ static void phys_init_v3_hw(struct hisi_hba *hisi_hba) | |||
882 | if (!sas_phy->phy->enabled) | 963 | if (!sas_phy->phy->enabled) |
883 | continue; | 964 | continue; |
884 | 965 | ||
885 | start_phy_v3_hw(hisi_hba, i); | 966 | hisi_sas_phy_enable(hisi_hba, i, 1); |
886 | } | 967 | } |
887 | } | 968 | } |
888 | 969 | ||
@@ -929,7 +1010,7 @@ get_free_slot_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq) | |||
929 | DLVRY_Q_0_RD_PTR + (queue * 0x14)); | 1010 | DLVRY_Q_0_RD_PTR + (queue * 0x14)); |
930 | if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) { | 1011 | if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) { |
931 | dev_warn(dev, "full queue=%d r=%d w=%d\n", | 1012 | dev_warn(dev, "full queue=%d r=%d w=%d\n", |
932 | queue, r, w); | 1013 | queue, r, w); |
933 | return -EAGAIN; | 1014 | return -EAGAIN; |
934 | } | 1015 | } |
935 | 1016 | ||
@@ -1380,6 +1461,7 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) | |||
1380 | struct hisi_sas_initial_fis *initial_fis; | 1461 | struct hisi_sas_initial_fis *initial_fis; |
1381 | struct dev_to_host_fis *fis; | 1462 | struct dev_to_host_fis *fis; |
1382 | u8 attached_sas_addr[SAS_ADDR_SIZE] = {0}; | 1463 | u8 attached_sas_addr[SAS_ADDR_SIZE] = {0}; |
1464 | struct Scsi_Host *shost = hisi_hba->shost; | ||
1383 | 1465 | ||
1384 | dev_info(dev, "phyup: phy%d link_rate=%d(sata)\n", phy_no, link_rate); | 1466 | dev_info(dev, "phyup: phy%d link_rate=%d(sata)\n", phy_no, link_rate); |
1385 | initial_fis = &hisi_hba->initial_fis[phy_no]; | 1467 | initial_fis = &hisi_hba->initial_fis[phy_no]; |
@@ -1396,6 +1478,7 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) | |||
1396 | 1478 | ||
1397 | sas_phy->oob_mode = SATA_OOB_MODE; | 1479 | sas_phy->oob_mode = SATA_OOB_MODE; |
1398 | attached_sas_addr[0] = 0x50; | 1480 | attached_sas_addr[0] = 0x50; |
1481 | attached_sas_addr[6] = shost->host_no; | ||
1399 | attached_sas_addr[7] = phy_no; | 1482 | attached_sas_addr[7] = phy_no; |
1400 | memcpy(sas_phy->attached_sas_addr, | 1483 | memcpy(sas_phy->attached_sas_addr, |
1401 | attached_sas_addr, | 1484 | attached_sas_addr, |
@@ -1540,6 +1623,14 @@ static irqreturn_t int_phy_up_down_bcast_v3_hw(int irq_no, void *p) | |||
1540 | 1623 | ||
1541 | static const struct hisi_sas_hw_error port_axi_error[] = { | 1624 | static const struct hisi_sas_hw_error port_axi_error[] = { |
1542 | { | 1625 | { |
1626 | .irq_msk = BIT(CHL_INT1_DMAC_TX_ECC_MB_ERR_OFF), | ||
1627 | .msg = "dmac_tx_ecc_bad_err", | ||
1628 | }, | ||
1629 | { | ||
1630 | .irq_msk = BIT(CHL_INT1_DMAC_RX_ECC_MB_ERR_OFF), | ||
1631 | .msg = "dmac_rx_ecc_bad_err", | ||
1632 | }, | ||
1633 | { | ||
1543 | .irq_msk = BIT(CHL_INT1_DMAC_TX_AXI_WR_ERR_OFF), | 1634 | .irq_msk = BIT(CHL_INT1_DMAC_TX_AXI_WR_ERR_OFF), |
1544 | .msg = "dma_tx_axi_wr_err", | 1635 | .msg = "dma_tx_axi_wr_err", |
1545 | }, | 1636 | }, |
@@ -1555,6 +1646,22 @@ static const struct hisi_sas_hw_error port_axi_error[] = { | |||
1555 | .irq_msk = BIT(CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF), | 1646 | .irq_msk = BIT(CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF), |
1556 | .msg = "dma_rx_axi_rd_err", | 1647 | .msg = "dma_rx_axi_rd_err", |
1557 | }, | 1648 | }, |
1649 | { | ||
1650 | .irq_msk = BIT(CHL_INT1_DMAC_TX_FIFO_ERR_OFF), | ||
1651 | .msg = "dma_tx_fifo_err", | ||
1652 | }, | ||
1653 | { | ||
1654 | .irq_msk = BIT(CHL_INT1_DMAC_RX_FIFO_ERR_OFF), | ||
1655 | .msg = "dma_rx_fifo_err", | ||
1656 | }, | ||
1657 | { | ||
1658 | .irq_msk = BIT(CHL_INT1_DMAC_TX_AXI_RUSER_ERR_OFF), | ||
1659 | .msg = "dma_tx_axi_ruser_err", | ||
1660 | }, | ||
1661 | { | ||
1662 | .irq_msk = BIT(CHL_INT1_DMAC_RX_AXI_RUSER_ERR_OFF), | ||
1663 | .msg = "dma_rx_axi_ruser_err", | ||
1664 | }, | ||
1558 | }; | 1665 | }; |
1559 | 1666 | ||
1560 | static void handle_chl_int1_v3_hw(struct hisi_hba *hisi_hba, int phy_no) | 1667 | static void handle_chl_int1_v3_hw(struct hisi_hba *hisi_hba, int phy_no) |
@@ -1719,6 +1826,121 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p) | |||
1719 | return IRQ_HANDLED; | 1826 | return IRQ_HANDLED; |
1720 | } | 1827 | } |
1721 | 1828 | ||
1829 | static const struct hisi_sas_hw_error multi_bit_ecc_errors[] = { | ||
1830 | { | ||
1831 | .irq_msk = BIT(SAS_ECC_INTR_DQE_ECC_MB_OFF), | ||
1832 | .msk = HGC_DQE_ECC_MB_ADDR_MSK, | ||
1833 | .shift = HGC_DQE_ECC_MB_ADDR_OFF, | ||
1834 | .msg = "hgc_dqe_eccbad_intr found: ram addr is 0x%08X\n", | ||
1835 | .reg = HGC_DQE_ECC_ADDR, | ||
1836 | }, | ||
1837 | { | ||
1838 | .irq_msk = BIT(SAS_ECC_INTR_IOST_ECC_MB_OFF), | ||
1839 | .msk = HGC_IOST_ECC_MB_ADDR_MSK, | ||
1840 | .shift = HGC_IOST_ECC_MB_ADDR_OFF, | ||
1841 | .msg = "hgc_iost_eccbad_intr found: ram addr is 0x%08X\n", | ||
1842 | .reg = HGC_IOST_ECC_ADDR, | ||
1843 | }, | ||
1844 | { | ||
1845 | .irq_msk = BIT(SAS_ECC_INTR_ITCT_ECC_MB_OFF), | ||
1846 | .msk = HGC_ITCT_ECC_MB_ADDR_MSK, | ||
1847 | .shift = HGC_ITCT_ECC_MB_ADDR_OFF, | ||
1848 | .msg = "hgc_itct_eccbad_intr found: ram addr is 0x%08X\n", | ||
1849 | .reg = HGC_ITCT_ECC_ADDR, | ||
1850 | }, | ||
1851 | { | ||
1852 | .irq_msk = BIT(SAS_ECC_INTR_IOSTLIST_ECC_MB_OFF), | ||
1853 | .msk = HGC_LM_DFX_STATUS2_IOSTLIST_MSK, | ||
1854 | .shift = HGC_LM_DFX_STATUS2_IOSTLIST_OFF, | ||
1855 | .msg = "hgc_iostl_eccbad_intr found: mem addr is 0x%08X\n", | ||
1856 | .reg = HGC_LM_DFX_STATUS2, | ||
1857 | }, | ||
1858 | { | ||
1859 | .irq_msk = BIT(SAS_ECC_INTR_ITCTLIST_ECC_MB_OFF), | ||
1860 | .msk = HGC_LM_DFX_STATUS2_ITCTLIST_MSK, | ||
1861 | .shift = HGC_LM_DFX_STATUS2_ITCTLIST_OFF, | ||
1862 | .msg = "hgc_itctl_eccbad_intr found: mem addr is 0x%08X\n", | ||
1863 | .reg = HGC_LM_DFX_STATUS2, | ||
1864 | }, | ||
1865 | { | ||
1866 | .irq_msk = BIT(SAS_ECC_INTR_CQE_ECC_MB_OFF), | ||
1867 | .msk = HGC_CQE_ECC_MB_ADDR_MSK, | ||
1868 | .shift = HGC_CQE_ECC_MB_ADDR_OFF, | ||
1869 | .msg = "hgc_cqe_eccbad_intr found: ram address is 0x%08X\n", | ||
1870 | .reg = HGC_CQE_ECC_ADDR, | ||
1871 | }, | ||
1872 | { | ||
1873 | .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM0_ECC_MB_OFF), | ||
1874 | .msk = HGC_RXM_DFX_STATUS14_MEM0_MSK, | ||
1875 | .shift = HGC_RXM_DFX_STATUS14_MEM0_OFF, | ||
1876 | .msg = "rxm_mem0_eccbad_intr found: mem addr is 0x%08X\n", | ||
1877 | .reg = HGC_RXM_DFX_STATUS14, | ||
1878 | }, | ||
1879 | { | ||
1880 | .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM1_ECC_MB_OFF), | ||
1881 | .msk = HGC_RXM_DFX_STATUS14_MEM1_MSK, | ||
1882 | .shift = HGC_RXM_DFX_STATUS14_MEM1_OFF, | ||
1883 | .msg = "rxm_mem1_eccbad_intr found: mem addr is 0x%08X\n", | ||
1884 | .reg = HGC_RXM_DFX_STATUS14, | ||
1885 | }, | ||
1886 | { | ||
1887 | .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM2_ECC_MB_OFF), | ||
1888 | .msk = HGC_RXM_DFX_STATUS14_MEM2_MSK, | ||
1889 | .shift = HGC_RXM_DFX_STATUS14_MEM2_OFF, | ||
1890 | .msg = "rxm_mem2_eccbad_intr found: mem addr is 0x%08X\n", | ||
1891 | .reg = HGC_RXM_DFX_STATUS14, | ||
1892 | }, | ||
1893 | { | ||
1894 | .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM3_ECC_MB_OFF), | ||
1895 | .msk = HGC_RXM_DFX_STATUS15_MEM3_MSK, | ||
1896 | .shift = HGC_RXM_DFX_STATUS15_MEM3_OFF, | ||
1897 | .msg = "rxm_mem3_eccbad_intr found: mem addr is 0x%08X\n", | ||
1898 | .reg = HGC_RXM_DFX_STATUS15, | ||
1899 | }, | ||
1900 | { | ||
1901 | .irq_msk = BIT(SAS_ECC_INTR_OOO_RAM_ECC_MB_OFF), | ||
1902 | .msk = AM_ROB_ECC_ERR_ADDR_MSK, | ||
1903 | .shift = AM_ROB_ECC_ERR_ADDR_OFF, | ||
1904 | .msg = "ooo_ram_eccbad_intr found: ROB_ECC_ERR_ADDR=0x%08X\n", | ||
1905 | .reg = AM_ROB_ECC_ERR_ADDR, | ||
1906 | }, | ||
1907 | }; | ||
1908 | |||
1909 | static void multi_bit_ecc_error_process_v3_hw(struct hisi_hba *hisi_hba, | ||
1910 | u32 irq_value) | ||
1911 | { | ||
1912 | struct device *dev = hisi_hba->dev; | ||
1913 | const struct hisi_sas_hw_error *ecc_error; | ||
1914 | u32 val; | ||
1915 | int i; | ||
1916 | |||
1917 | for (i = 0; i < ARRAY_SIZE(multi_bit_ecc_errors); i++) { | ||
1918 | ecc_error = &multi_bit_ecc_errors[i]; | ||
1919 | if (irq_value & ecc_error->irq_msk) { | ||
1920 | val = hisi_sas_read32(hisi_hba, ecc_error->reg); | ||
1921 | val &= ecc_error->msk; | ||
1922 | val >>= ecc_error->shift; | ||
1923 | dev_err(dev, ecc_error->msg, irq_value, val); | ||
1924 | queue_work(hisi_hba->wq, &hisi_hba->rst_work); | ||
1925 | } | ||
1926 | } | ||
1927 | } | ||
1928 | |||
1929 | static void fatal_ecc_int_v3_hw(struct hisi_hba *hisi_hba) | ||
1930 | { | ||
1931 | u32 irq_value, irq_msk; | ||
1932 | |||
1933 | irq_msk = hisi_sas_read32(hisi_hba, SAS_ECC_INTR_MSK); | ||
1934 | hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, irq_msk | 0xffffffff); | ||
1935 | |||
1936 | irq_value = hisi_sas_read32(hisi_hba, SAS_ECC_INTR); | ||
1937 | if (irq_value) | ||
1938 | multi_bit_ecc_error_process_v3_hw(hisi_hba, irq_value); | ||
1939 | |||
1940 | hisi_sas_write32(hisi_hba, SAS_ECC_INTR, irq_value); | ||
1941 | hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, irq_msk); | ||
1942 | } | ||
1943 | |||
1722 | static const struct hisi_sas_hw_error axi_error[] = { | 1944 | static const struct hisi_sas_hw_error axi_error[] = { |
1723 | { .msk = BIT(0), .msg = "IOST_AXI_W_ERR" }, | 1945 | { .msk = BIT(0), .msg = "IOST_AXI_W_ERR" }, |
1724 | { .msk = BIT(1), .msg = "IOST_AXI_R_ERR" }, | 1946 | { .msk = BIT(1), .msg = "IOST_AXI_R_ERR" }, |
@@ -1728,7 +1950,7 @@ static const struct hisi_sas_hw_error axi_error[] = { | |||
1728 | { .msk = BIT(5), .msg = "SATA_AXI_R_ERR" }, | 1950 | { .msk = BIT(5), .msg = "SATA_AXI_R_ERR" }, |
1729 | { .msk = BIT(6), .msg = "DQE_AXI_R_ERR" }, | 1951 | { .msk = BIT(6), .msg = "DQE_AXI_R_ERR" }, |
1730 | { .msk = BIT(7), .msg = "CQE_AXI_W_ERR" }, | 1952 | { .msk = BIT(7), .msg = "CQE_AXI_W_ERR" }, |
1731 | {}, | 1953 | {} |
1732 | }; | 1954 | }; |
1733 | 1955 | ||
1734 | static const struct hisi_sas_hw_error fifo_error[] = { | 1956 | static const struct hisi_sas_hw_error fifo_error[] = { |
@@ -1737,7 +1959,7 @@ static const struct hisi_sas_hw_error fifo_error[] = { | |||
1737 | { .msk = BIT(10), .msg = "GETDQE_FIFO" }, | 1959 | { .msk = BIT(10), .msg = "GETDQE_FIFO" }, |
1738 | { .msk = BIT(11), .msg = "CMDP_FIFO" }, | 1960 | { .msk = BIT(11), .msg = "CMDP_FIFO" }, |
1739 | { .msk = BIT(12), .msg = "AWTCTRL_FIFO" }, | 1961 | { .msk = BIT(12), .msg = "AWTCTRL_FIFO" }, |
1740 | {}, | 1962 | {} |
1741 | }; | 1963 | }; |
1742 | 1964 | ||
1743 | static const struct hisi_sas_hw_error fatal_axi_error[] = { | 1965 | static const struct hisi_sas_hw_error fatal_axi_error[] = { |
@@ -1771,6 +1993,23 @@ static const struct hisi_sas_hw_error fatal_axi_error[] = { | |||
1771 | .irq_msk = BIT(ENT_INT_SRC3_ABT_OFF), | 1993 | .irq_msk = BIT(ENT_INT_SRC3_ABT_OFF), |
1772 | .msg = "SAS_HGC_ABT fetch LM list", | 1994 | .msg = "SAS_HGC_ABT fetch LM list", |
1773 | }, | 1995 | }, |
1996 | { | ||
1997 | .irq_msk = BIT(ENT_INT_SRC3_DQE_POISON_OFF), | ||
1998 | .msg = "read dqe poison", | ||
1999 | }, | ||
2000 | { | ||
2001 | .irq_msk = BIT(ENT_INT_SRC3_IOST_POISON_OFF), | ||
2002 | .msg = "read iost poison", | ||
2003 | }, | ||
2004 | { | ||
2005 | .irq_msk = BIT(ENT_INT_SRC3_ITCT_POISON_OFF), | ||
2006 | .msg = "read itct poison", | ||
2007 | }, | ||
2008 | { | ||
2009 | .irq_msk = BIT(ENT_INT_SRC3_ITCT_NCQ_POISON_OFF), | ||
2010 | .msg = "read itct ncq poison", | ||
2011 | }, | ||
2012 | |||
1774 | }; | 2013 | }; |
1775 | 2014 | ||
1776 | static irqreturn_t fatal_axi_int_v3_hw(int irq_no, void *p) | 2015 | static irqreturn_t fatal_axi_int_v3_hw(int irq_no, void *p) |
@@ -1823,6 +2062,8 @@ static irqreturn_t fatal_axi_int_v3_hw(int irq_no, void *p) | |||
1823 | } | 2062 | } |
1824 | } | 2063 | } |
1825 | 2064 | ||
2065 | fatal_ecc_int_v3_hw(hisi_hba); | ||
2066 | |||
1826 | if (irq_value & BIT(ENT_INT_SRC3_ITC_INT_OFF)) { | 2067 | if (irq_value & BIT(ENT_INT_SRC3_ITC_INT_OFF)) { |
1827 | u32 reg_val = hisi_sas_read32(hisi_hba, ITCT_CLR); | 2068 | u32 reg_val = hisi_sas_read32(hisi_hba, ITCT_CLR); |
1828 | u32 dev_id = reg_val & ITCT_DEV_MSK; | 2069 | u32 dev_id = reg_val & ITCT_DEV_MSK; |
@@ -1966,13 +2207,11 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) | |||
1966 | 2207 | ||
1967 | slot_err_v3_hw(hisi_hba, task, slot); | 2208 | slot_err_v3_hw(hisi_hba, task, slot); |
1968 | if (ts->stat != SAS_DATA_UNDERRUN) | 2209 | if (ts->stat != SAS_DATA_UNDERRUN) |
1969 | dev_info(dev, "erroneous completion iptt=%d task=%p dev id=%d " | 2210 | dev_info(dev, "erroneous completion iptt=%d task=%p dev id=%d CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", |
1970 | "CQ hdr: 0x%x 0x%x 0x%x 0x%x " | 2211 | slot->idx, task, sas_dev->device_id, |
1971 | "Error info: 0x%x 0x%x 0x%x 0x%x\n", | 2212 | dw0, dw1, complete_hdr->act, dw3, |
1972 | slot->idx, task, sas_dev->device_id, | 2213 | error_info[0], error_info[1], |
1973 | dw0, dw1, complete_hdr->act, dw3, | 2214 | error_info[2], error_info[3]); |
1974 | error_info[0], error_info[1], | ||
1975 | error_info[2], error_info[3]); | ||
1976 | if (unlikely(slot->abort)) | 2215 | if (unlikely(slot->abort)) |
1977 | return ts->stat; | 2216 | return ts->stat; |
1978 | goto out; | 2217 | goto out; |
@@ -2205,8 +2444,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) | |||
2205 | cq_interrupt_v3_hw, irqflags, | 2444 | cq_interrupt_v3_hw, irqflags, |
2206 | DRV_NAME " cq", cq); | 2445 | DRV_NAME " cq", cq); |
2207 | if (rc) { | 2446 | if (rc) { |
2208 | dev_err(dev, | 2447 | dev_err(dev, "could not request cq%d interrupt, rc=%d\n", |
2209 | "could not request cq%d interrupt, rc=%d\n", | ||
2210 | i, rc); | 2448 | i, rc); |
2211 | rc = -ENOENT; | 2449 | rc = -ENOENT; |
2212 | goto free_cq_irqs; | 2450 | goto free_cq_irqs; |
@@ -2362,7 +2600,7 @@ static int write_gpio_v3_hw(struct hisi_hba *hisi_hba, u8 reg_type, | |||
2362 | break; | 2600 | break; |
2363 | default: | 2601 | default: |
2364 | dev_err(dev, "write gpio: unsupported or bad reg type %d\n", | 2602 | dev_err(dev, "write gpio: unsupported or bad reg type %d\n", |
2365 | reg_type); | 2603 | reg_type); |
2366 | return -EINVAL; | 2604 | return -EINVAL; |
2367 | } | 2605 | } |
2368 | 2606 | ||
@@ -2678,6 +2916,7 @@ static struct scsi_host_template sht_v3_hw = { | |||
2678 | .ioctl = sas_ioctl, | 2916 | .ioctl = sas_ioctl, |
2679 | .shost_attrs = host_attrs_v3_hw, | 2917 | .shost_attrs = host_attrs_v3_hw, |
2680 | .tag_alloc_policy = BLK_TAG_ALLOC_RR, | 2918 | .tag_alloc_policy = BLK_TAG_ALLOC_RR, |
2919 | .host_reset = hisi_sas_host_reset, | ||
2681 | }; | 2920 | }; |
2682 | 2921 | ||
2683 | static const struct hisi_sas_hw hisi_sas_v3_hw = { | 2922 | static const struct hisi_sas_hw hisi_sas_v3_hw = { |
@@ -2800,7 +3039,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2800 | 3039 | ||
2801 | hisi_hba->regs = pcim_iomap(pdev, 5, 0); | 3040 | hisi_hba->regs = pcim_iomap(pdev, 5, 0); |
2802 | if (!hisi_hba->regs) { | 3041 | if (!hisi_hba->regs) { |
2803 | dev_err(dev, "cannot map register.\n"); | 3042 | dev_err(dev, "cannot map register\n"); |
2804 | rc = -ENOMEM; | 3043 | rc = -ENOMEM; |
2805 | goto err_out_ha; | 3044 | goto err_out_ha; |
2806 | } | 3045 | } |
@@ -2921,161 +3160,6 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev) | |||
2921 | scsi_host_put(shost); | 3160 | scsi_host_put(shost); |
2922 | } | 3161 | } |
2923 | 3162 | ||
2924 | static const struct hisi_sas_hw_error sas_ras_intr0_nfe[] = { | ||
2925 | { .irq_msk = BIT(19), .msg = "HILINK_INT" }, | ||
2926 | { .irq_msk = BIT(20), .msg = "HILINK_PLL0_OUT_OF_LOCK" }, | ||
2927 | { .irq_msk = BIT(21), .msg = "HILINK_PLL1_OUT_OF_LOCK" }, | ||
2928 | { .irq_msk = BIT(22), .msg = "HILINK_LOSS_OF_REFCLK0" }, | ||
2929 | { .irq_msk = BIT(23), .msg = "HILINK_LOSS_OF_REFCLK1" }, | ||
2930 | { .irq_msk = BIT(24), .msg = "DMAC0_TX_POISON" }, | ||
2931 | { .irq_msk = BIT(25), .msg = "DMAC1_TX_POISON" }, | ||
2932 | { .irq_msk = BIT(26), .msg = "DMAC2_TX_POISON" }, | ||
2933 | { .irq_msk = BIT(27), .msg = "DMAC3_TX_POISON" }, | ||
2934 | { .irq_msk = BIT(28), .msg = "DMAC4_TX_POISON" }, | ||
2935 | { .irq_msk = BIT(29), .msg = "DMAC5_TX_POISON" }, | ||
2936 | { .irq_msk = BIT(30), .msg = "DMAC6_TX_POISON" }, | ||
2937 | { .irq_msk = BIT(31), .msg = "DMAC7_TX_POISON" }, | ||
2938 | }; | ||
2939 | |||
2940 | static const struct hisi_sas_hw_error sas_ras_intr1_nfe[] = { | ||
2941 | { .irq_msk = BIT(0), .msg = "RXM_CFG_MEM3_ECC2B_INTR" }, | ||
2942 | { .irq_msk = BIT(1), .msg = "RXM_CFG_MEM2_ECC2B_INTR" }, | ||
2943 | { .irq_msk = BIT(2), .msg = "RXM_CFG_MEM1_ECC2B_INTR" }, | ||
2944 | { .irq_msk = BIT(3), .msg = "RXM_CFG_MEM0_ECC2B_INTR" }, | ||
2945 | { .irq_msk = BIT(4), .msg = "HGC_CQE_ECC2B_INTR" }, | ||
2946 | { .irq_msk = BIT(5), .msg = "LM_CFG_IOSTL_ECC2B_INTR" }, | ||
2947 | { .irq_msk = BIT(6), .msg = "LM_CFG_ITCTL_ECC2B_INTR" }, | ||
2948 | { .irq_msk = BIT(7), .msg = "HGC_ITCT_ECC2B_INTR" }, | ||
2949 | { .irq_msk = BIT(8), .msg = "HGC_IOST_ECC2B_INTR" }, | ||
2950 | { .irq_msk = BIT(9), .msg = "HGC_DQE_ECC2B_INTR" }, | ||
2951 | { .irq_msk = BIT(10), .msg = "DMAC0_RAM_ECC2B_INTR" }, | ||
2952 | { .irq_msk = BIT(11), .msg = "DMAC1_RAM_ECC2B_INTR" }, | ||
2953 | { .irq_msk = BIT(12), .msg = "DMAC2_RAM_ECC2B_INTR" }, | ||
2954 | { .irq_msk = BIT(13), .msg = "DMAC3_RAM_ECC2B_INTR" }, | ||
2955 | { .irq_msk = BIT(14), .msg = "DMAC4_RAM_ECC2B_INTR" }, | ||
2956 | { .irq_msk = BIT(15), .msg = "DMAC5_RAM_ECC2B_INTR" }, | ||
2957 | { .irq_msk = BIT(16), .msg = "DMAC6_RAM_ECC2B_INTR" }, | ||
2958 | { .irq_msk = BIT(17), .msg = "DMAC7_RAM_ECC2B_INTR" }, | ||
2959 | { .irq_msk = BIT(18), .msg = "OOO_RAM_ECC2B_INTR" }, | ||
2960 | { .irq_msk = BIT(20), .msg = "HGC_DQE_POISON_INTR" }, | ||
2961 | { .irq_msk = BIT(21), .msg = "HGC_IOST_POISON_INTR" }, | ||
2962 | { .irq_msk = BIT(22), .msg = "HGC_ITCT_POISON_INTR" }, | ||
2963 | { .irq_msk = BIT(23), .msg = "HGC_ITCT_NCQ_POISON_INTR" }, | ||
2964 | { .irq_msk = BIT(24), .msg = "DMAC0_RX_POISON" }, | ||
2965 | { .irq_msk = BIT(25), .msg = "DMAC1_RX_POISON" }, | ||
2966 | { .irq_msk = BIT(26), .msg = "DMAC2_RX_POISON" }, | ||
2967 | { .irq_msk = BIT(27), .msg = "DMAC3_RX_POISON" }, | ||
2968 | { .irq_msk = BIT(28), .msg = "DMAC4_RX_POISON" }, | ||
2969 | { .irq_msk = BIT(29), .msg = "DMAC5_RX_POISON" }, | ||
2970 | { .irq_msk = BIT(30), .msg = "DMAC6_RX_POISON" }, | ||
2971 | { .irq_msk = BIT(31), .msg = "DMAC7_RX_POISON" }, | ||
2972 | }; | ||
2973 | |||
2974 | static const struct hisi_sas_hw_error sas_ras_intr2_nfe[] = { | ||
2975 | { .irq_msk = BIT(0), .msg = "DMAC0_AXI_BUS_ERR" }, | ||
2976 | { .irq_msk = BIT(1), .msg = "DMAC1_AXI_BUS_ERR" }, | ||
2977 | { .irq_msk = BIT(2), .msg = "DMAC2_AXI_BUS_ERR" }, | ||
2978 | { .irq_msk = BIT(3), .msg = "DMAC3_AXI_BUS_ERR" }, | ||
2979 | { .irq_msk = BIT(4), .msg = "DMAC4_AXI_BUS_ERR" }, | ||
2980 | { .irq_msk = BIT(5), .msg = "DMAC5_AXI_BUS_ERR" }, | ||
2981 | { .irq_msk = BIT(6), .msg = "DMAC6_AXI_BUS_ERR" }, | ||
2982 | { .irq_msk = BIT(7), .msg = "DMAC7_AXI_BUS_ERR" }, | ||
2983 | { .irq_msk = BIT(8), .msg = "DMAC0_FIFO_OMIT_ERR" }, | ||
2984 | { .irq_msk = BIT(9), .msg = "DMAC1_FIFO_OMIT_ERR" }, | ||
2985 | { .irq_msk = BIT(10), .msg = "DMAC2_FIFO_OMIT_ERR" }, | ||
2986 | { .irq_msk = BIT(11), .msg = "DMAC3_FIFO_OMIT_ERR" }, | ||
2987 | { .irq_msk = BIT(12), .msg = "DMAC4_FIFO_OMIT_ERR" }, | ||
2988 | { .irq_msk = BIT(13), .msg = "DMAC5_FIFO_OMIT_ERR" }, | ||
2989 | { .irq_msk = BIT(14), .msg = "DMAC6_FIFO_OMIT_ERR" }, | ||
2990 | { .irq_msk = BIT(15), .msg = "DMAC7_FIFO_OMIT_ERR" }, | ||
2991 | { .irq_msk = BIT(16), .msg = "HGC_RLSE_SLOT_UNMATCH" }, | ||
2992 | { .irq_msk = BIT(17), .msg = "HGC_LM_ADD_FCH_LIST_ERR" }, | ||
2993 | { .irq_msk = BIT(18), .msg = "HGC_AXI_BUS_ERR" }, | ||
2994 | { .irq_msk = BIT(19), .msg = "HGC_FIFO_OMIT_ERR" }, | ||
2995 | }; | ||
2996 | |||
2997 | static bool process_non_fatal_error_v3_hw(struct hisi_hba *hisi_hba) | ||
2998 | { | ||
2999 | struct device *dev = hisi_hba->dev; | ||
3000 | const struct hisi_sas_hw_error *ras_error; | ||
3001 | bool need_reset = false; | ||
3002 | u32 irq_value; | ||
3003 | int i; | ||
3004 | |||
3005 | irq_value = hisi_sas_read32(hisi_hba, SAS_RAS_INTR0); | ||
3006 | for (i = 0; i < ARRAY_SIZE(sas_ras_intr0_nfe); i++) { | ||
3007 | ras_error = &sas_ras_intr0_nfe[i]; | ||
3008 | if (ras_error->irq_msk & irq_value) { | ||
3009 | dev_warn(dev, "SAS_RAS_INTR0: %s(irq_value=0x%x) found.\n", | ||
3010 | ras_error->msg, irq_value); | ||
3011 | need_reset = true; | ||
3012 | } | ||
3013 | } | ||
3014 | hisi_sas_write32(hisi_hba, SAS_RAS_INTR0, irq_value); | ||
3015 | |||
3016 | irq_value = hisi_sas_read32(hisi_hba, SAS_RAS_INTR1); | ||
3017 | for (i = 0; i < ARRAY_SIZE(sas_ras_intr1_nfe); i++) { | ||
3018 | ras_error = &sas_ras_intr1_nfe[i]; | ||
3019 | if (ras_error->irq_msk & irq_value) { | ||
3020 | dev_warn(dev, "SAS_RAS_INTR1: %s(irq_value=0x%x) found.\n", | ||
3021 | ras_error->msg, irq_value); | ||
3022 | need_reset = true; | ||
3023 | } | ||
3024 | } | ||
3025 | hisi_sas_write32(hisi_hba, SAS_RAS_INTR1, irq_value); | ||
3026 | |||
3027 | irq_value = hisi_sas_read32(hisi_hba, SAS_RAS_INTR2); | ||
3028 | for (i = 0; i < ARRAY_SIZE(sas_ras_intr2_nfe); i++) { | ||
3029 | ras_error = &sas_ras_intr2_nfe[i]; | ||
3030 | if (ras_error->irq_msk & irq_value) { | ||
3031 | dev_warn(dev, "SAS_RAS_INTR2: %s(irq_value=0x%x) found.\n", | ||
3032 | ras_error->msg, irq_value); | ||
3033 | need_reset = true; | ||
3034 | } | ||
3035 | } | ||
3036 | hisi_sas_write32(hisi_hba, SAS_RAS_INTR2, irq_value); | ||
3037 | |||
3038 | return need_reset; | ||
3039 | } | ||
3040 | |||
3041 | static pci_ers_result_t hisi_sas_error_detected_v3_hw(struct pci_dev *pdev, | ||
3042 | pci_channel_state_t state) | ||
3043 | { | ||
3044 | struct sas_ha_struct *sha = pci_get_drvdata(pdev); | ||
3045 | struct hisi_hba *hisi_hba = sha->lldd_ha; | ||
3046 | struct device *dev = hisi_hba->dev; | ||
3047 | |||
3048 | dev_info(dev, "PCI error: detected callback, state(%d)!!\n", state); | ||
3049 | if (state == pci_channel_io_perm_failure) | ||
3050 | return PCI_ERS_RESULT_DISCONNECT; | ||
3051 | |||
3052 | if (process_non_fatal_error_v3_hw(hisi_hba)) | ||
3053 | return PCI_ERS_RESULT_NEED_RESET; | ||
3054 | |||
3055 | return PCI_ERS_RESULT_CAN_RECOVER; | ||
3056 | } | ||
3057 | |||
3058 | static pci_ers_result_t hisi_sas_mmio_enabled_v3_hw(struct pci_dev *pdev) | ||
3059 | { | ||
3060 | return PCI_ERS_RESULT_RECOVERED; | ||
3061 | } | ||
3062 | |||
3063 | static pci_ers_result_t hisi_sas_slot_reset_v3_hw(struct pci_dev *pdev) | ||
3064 | { | ||
3065 | struct sas_ha_struct *sha = pci_get_drvdata(pdev); | ||
3066 | struct hisi_hba *hisi_hba = sha->lldd_ha; | ||
3067 | struct device *dev = hisi_hba->dev; | ||
3068 | HISI_SAS_DECLARE_RST_WORK_ON_STACK(r); | ||
3069 | |||
3070 | dev_info(dev, "PCI error: slot reset callback!!\n"); | ||
3071 | queue_work(hisi_hba->wq, &r.work); | ||
3072 | wait_for_completion(r.completion); | ||
3073 | if (r.done) | ||
3074 | return PCI_ERS_RESULT_RECOVERED; | ||
3075 | |||
3076 | return PCI_ERS_RESULT_DISCONNECT; | ||
3077 | } | ||
3078 | |||
3079 | static void hisi_sas_reset_prepare_v3_hw(struct pci_dev *pdev) | 3163 | static void hisi_sas_reset_prepare_v3_hw(struct pci_dev *pdev) |
3080 | { | 3164 | { |
3081 | struct sas_ha_struct *sha = pci_get_drvdata(pdev); | 3165 | struct sas_ha_struct *sha = pci_get_drvdata(pdev); |
@@ -3171,7 +3255,7 @@ static int hisi_sas_v3_resume(struct pci_dev *pdev) | |||
3171 | pci_power_t device_state = pdev->current_state; | 3255 | pci_power_t device_state = pdev->current_state; |
3172 | 3256 | ||
3173 | dev_warn(dev, "resuming from operating state [D%d]\n", | 3257 | dev_warn(dev, "resuming from operating state [D%d]\n", |
3174 | device_state); | 3258 | device_state); |
3175 | pci_set_power_state(pdev, PCI_D0); | 3259 | pci_set_power_state(pdev, PCI_D0); |
3176 | pci_enable_wake(pdev, PCI_D0, 0); | 3260 | pci_enable_wake(pdev, PCI_D0, 0); |
3177 | pci_restore_state(pdev); | 3261 | pci_restore_state(pdev); |
@@ -3199,9 +3283,6 @@ static const struct pci_device_id sas_v3_pci_table[] = { | |||
3199 | MODULE_DEVICE_TABLE(pci, sas_v3_pci_table); | 3283 | MODULE_DEVICE_TABLE(pci, sas_v3_pci_table); |
3200 | 3284 | ||
3201 | static const struct pci_error_handlers hisi_sas_err_handler = { | 3285 | static const struct pci_error_handlers hisi_sas_err_handler = { |
3202 | .error_detected = hisi_sas_error_detected_v3_hw, | ||
3203 | .mmio_enabled = hisi_sas_mmio_enabled_v3_hw, | ||
3204 | .slot_reset = hisi_sas_slot_reset_v3_hw, | ||
3205 | .reset_prepare = hisi_sas_reset_prepare_v3_hw, | 3286 | .reset_prepare = hisi_sas_reset_prepare_v3_hw, |
3206 | .reset_done = hisi_sas_reset_done_v3_hw, | 3287 | .reset_done = hisi_sas_reset_done_v3_hw, |
3207 | }; | 3288 | }; |
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index f044e7d10d63..1bef1da273c2 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -60,7 +60,7 @@ | |||
60 | * HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' | 60 | * HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' |
61 | * with an optional trailing '-' followed by a byte value (0-255). | 61 | * with an optional trailing '-' followed by a byte value (0-255). |
62 | */ | 62 | */ |
63 | #define HPSA_DRIVER_VERSION "3.4.20-125" | 63 | #define HPSA_DRIVER_VERSION "3.4.20-160" |
64 | #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")" | 64 | #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")" |
65 | #define HPSA "hpsa" | 65 | #define HPSA "hpsa" |
66 | 66 | ||
@@ -2647,9 +2647,20 @@ static void complete_scsi_command(struct CommandList *cp) | |||
2647 | decode_sense_data(ei->SenseInfo, sense_data_size, | 2647 | decode_sense_data(ei->SenseInfo, sense_data_size, |
2648 | &sense_key, &asc, &ascq); | 2648 | &sense_key, &asc, &ascq); |
2649 | if (ei->ScsiStatus == SAM_STAT_CHECK_CONDITION) { | 2649 | if (ei->ScsiStatus == SAM_STAT_CHECK_CONDITION) { |
2650 | if (sense_key == ABORTED_COMMAND) { | 2650 | switch (sense_key) { |
2651 | case ABORTED_COMMAND: | ||
2651 | cmd->result |= DID_SOFT_ERROR << 16; | 2652 | cmd->result |= DID_SOFT_ERROR << 16; |
2652 | break; | 2653 | break; |
2654 | case UNIT_ATTENTION: | ||
2655 | if (asc == 0x3F && ascq == 0x0E) | ||
2656 | h->drv_req_rescan = 1; | ||
2657 | break; | ||
2658 | case ILLEGAL_REQUEST: | ||
2659 | if (asc == 0x25 && ascq == 0x00) { | ||
2660 | dev->removed = 1; | ||
2661 | cmd->result = DID_NO_CONNECT << 16; | ||
2662 | } | ||
2663 | break; | ||
2653 | } | 2664 | } |
2654 | break; | 2665 | break; |
2655 | } | 2666 | } |
@@ -3956,14 +3967,18 @@ static int hpsa_update_device_info(struct ctlr_info *h, | |||
3956 | memset(this_device->device_id, 0, | 3967 | memset(this_device->device_id, 0, |
3957 | sizeof(this_device->device_id)); | 3968 | sizeof(this_device->device_id)); |
3958 | if (hpsa_get_device_id(h, scsi3addr, this_device->device_id, 8, | 3969 | if (hpsa_get_device_id(h, scsi3addr, this_device->device_id, 8, |
3959 | sizeof(this_device->device_id)) < 0) | 3970 | sizeof(this_device->device_id)) < 0) { |
3960 | dev_err(&h->pdev->dev, | 3971 | dev_err(&h->pdev->dev, |
3961 | "hpsa%d: %s: can't get device id for host %d:C0:T%d:L%d\t%s\t%.16s\n", | 3972 | "hpsa%d: %s: can't get device id for [%d:%d:%d:%d]\t%s\t%.16s\n", |
3962 | h->ctlr, __func__, | 3973 | h->ctlr, __func__, |
3963 | h->scsi_host->host_no, | 3974 | h->scsi_host->host_no, |
3964 | this_device->target, this_device->lun, | 3975 | this_device->bus, this_device->target, |
3976 | this_device->lun, | ||
3965 | scsi_device_type(this_device->devtype), | 3977 | scsi_device_type(this_device->devtype), |
3966 | this_device->model); | 3978 | this_device->model); |
3979 | rc = HPSA_LV_FAILED; | ||
3980 | goto bail_out; | ||
3981 | } | ||
3967 | 3982 | ||
3968 | if ((this_device->devtype == TYPE_DISK || | 3983 | if ((this_device->devtype == TYPE_DISK || |
3969 | this_device->devtype == TYPE_ZBC) && | 3984 | this_device->devtype == TYPE_ZBC) && |
@@ -5809,7 +5824,7 @@ static int hpsa_send_test_unit_ready(struct ctlr_info *h, | |||
5809 | /* Send the Test Unit Ready, fill_cmd can't fail, no mapping */ | 5824 | /* Send the Test Unit Ready, fill_cmd can't fail, no mapping */ |
5810 | (void) fill_cmd(c, TEST_UNIT_READY, h, | 5825 | (void) fill_cmd(c, TEST_UNIT_READY, h, |
5811 | NULL, 0, 0, lunaddr, TYPE_CMD); | 5826 | NULL, 0, 0, lunaddr, TYPE_CMD); |
5812 | rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, DEFAULT_TIMEOUT); | 5827 | rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT); |
5813 | if (rc) | 5828 | if (rc) |
5814 | return rc; | 5829 | return rc; |
5815 | /* no unmap needed here because no data xfer. */ | 5830 | /* no unmap needed here because no data xfer. */ |
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 6f93fee2b21b..1ecca71df8b5 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -281,7 +281,7 @@ int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy) | |||
281 | res = sas_get_report_phy_sata(dev->parent, phy->phy_id, | 281 | res = sas_get_report_phy_sata(dev->parent, phy->phy_id, |
282 | &dev->sata_dev.rps_resp); | 282 | &dev->sata_dev.rps_resp); |
283 | if (res) { | 283 | if (res) { |
284 | pr_debug("report phy sata to %016llx:0x%x returned 0x%x\n", | 284 | pr_debug("report phy sata to %016llx:%02d returned 0x%x\n", |
285 | SAS_ADDR(dev->parent->sas_addr), | 285 | SAS_ADDR(dev->parent->sas_addr), |
286 | phy->phy_id, res); | 286 | phy->phy_id, res); |
287 | return res; | 287 | return res; |
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 17b45a0c7bc3..83f2fd70ce76 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
@@ -826,9 +826,14 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
826 | #ifdef CONFIG_SCSI_SAS_ATA | 826 | #ifdef CONFIG_SCSI_SAS_ATA |
827 | if ((phy->attached_tproto & SAS_PROTOCOL_STP) || phy->attached_sata_dev) { | 827 | if ((phy->attached_tproto & SAS_PROTOCOL_STP) || phy->attached_sata_dev) { |
828 | if (child->linkrate > parent->min_linkrate) { | 828 | if (child->linkrate > parent->min_linkrate) { |
829 | struct sas_phy *cphy = child->phy; | ||
830 | enum sas_linkrate min_prate = cphy->minimum_linkrate, | ||
831 | parent_min_lrate = parent->min_linkrate, | ||
832 | min_linkrate = (min_prate > parent_min_lrate) ? | ||
833 | parent_min_lrate : 0; | ||
829 | struct sas_phy_linkrates rates = { | 834 | struct sas_phy_linkrates rates = { |
830 | .maximum_linkrate = parent->min_linkrate, | 835 | .maximum_linkrate = parent->min_linkrate, |
831 | .minimum_linkrate = parent->min_linkrate, | 836 | .minimum_linkrate = min_linkrate, |
832 | }; | 837 | }; |
833 | int ret; | 838 | int ret; |
834 | 839 | ||
@@ -865,7 +870,7 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
865 | 870 | ||
866 | res = sas_discover_sata(child); | 871 | res = sas_discover_sata(child); |
867 | if (res) { | 872 | if (res) { |
868 | pr_notice("sas_discover_sata() for device %16llx at %016llx:0x%x returned 0x%x\n", | 873 | pr_notice("sas_discover_sata() for device %16llx at %016llx:%02d returned 0x%x\n", |
869 | SAS_ADDR(child->sas_addr), | 874 | SAS_ADDR(child->sas_addr), |
870 | SAS_ADDR(parent->sas_addr), phy_id, res); | 875 | SAS_ADDR(parent->sas_addr), phy_id, res); |
871 | goto out_list_del; | 876 | goto out_list_del; |
@@ -890,7 +895,7 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
890 | 895 | ||
891 | res = sas_discover_end_dev(child); | 896 | res = sas_discover_end_dev(child); |
892 | if (res) { | 897 | if (res) { |
893 | pr_notice("sas_discover_end_dev() for device %16llx at %016llx:0x%x returned 0x%x\n", | 898 | pr_notice("sas_discover_end_dev() for device %16llx at %016llx:%02d returned 0x%x\n", |
894 | SAS_ADDR(child->sas_addr), | 899 | SAS_ADDR(child->sas_addr), |
895 | SAS_ADDR(parent->sas_addr), phy_id, res); | 900 | SAS_ADDR(parent->sas_addr), phy_id, res); |
896 | goto out_list_del; | 901 | goto out_list_del; |
@@ -955,7 +960,7 @@ static struct domain_device *sas_ex_discover_expander( | |||
955 | int res; | 960 | int res; |
956 | 961 | ||
957 | if (phy->routing_attr == DIRECT_ROUTING) { | 962 | if (phy->routing_attr == DIRECT_ROUTING) { |
958 | pr_warn("ex %016llx:0x%x:D <--> ex %016llx:0x%x is not allowed\n", | 963 | pr_warn("ex %016llx:%02d:D <--> ex %016llx:0x%x is not allowed\n", |
959 | SAS_ADDR(parent->sas_addr), phy_id, | 964 | SAS_ADDR(parent->sas_addr), phy_id, |
960 | SAS_ADDR(phy->attached_sas_addr), | 965 | SAS_ADDR(phy->attached_sas_addr), |
961 | phy->attached_phy_id); | 966 | phy->attached_phy_id); |
@@ -1065,7 +1070,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) | |||
1065 | ex_phy->attached_dev_type != SAS_FANOUT_EXPANDER_DEVICE && | 1070 | ex_phy->attached_dev_type != SAS_FANOUT_EXPANDER_DEVICE && |
1066 | ex_phy->attached_dev_type != SAS_EDGE_EXPANDER_DEVICE && | 1071 | ex_phy->attached_dev_type != SAS_EDGE_EXPANDER_DEVICE && |
1067 | ex_phy->attached_dev_type != SAS_SATA_PENDING) { | 1072 | ex_phy->attached_dev_type != SAS_SATA_PENDING) { |
1068 | pr_warn("unknown device type(0x%x) attached to ex %016llx phy 0x%x\n", | 1073 | pr_warn("unknown device type(0x%x) attached to ex %016llx phy%02d\n", |
1069 | ex_phy->attached_dev_type, | 1074 | ex_phy->attached_dev_type, |
1070 | SAS_ADDR(dev->sas_addr), | 1075 | SAS_ADDR(dev->sas_addr), |
1071 | phy_id); | 1076 | phy_id); |
@@ -1081,7 +1086,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) | |||
1081 | } | 1086 | } |
1082 | 1087 | ||
1083 | if (sas_ex_join_wide_port(dev, phy_id)) { | 1088 | if (sas_ex_join_wide_port(dev, phy_id)) { |
1084 | pr_debug("Attaching ex phy%d to wide port %016llx\n", | 1089 | pr_debug("Attaching ex phy%02d to wide port %016llx\n", |
1085 | phy_id, SAS_ADDR(ex_phy->attached_sas_addr)); | 1090 | phy_id, SAS_ADDR(ex_phy->attached_sas_addr)); |
1086 | return res; | 1091 | return res; |
1087 | } | 1092 | } |
@@ -1093,7 +1098,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) | |||
1093 | break; | 1098 | break; |
1094 | case SAS_FANOUT_EXPANDER_DEVICE: | 1099 | case SAS_FANOUT_EXPANDER_DEVICE: |
1095 | if (SAS_ADDR(dev->port->disc.fanout_sas_addr)) { | 1100 | if (SAS_ADDR(dev->port->disc.fanout_sas_addr)) { |
1096 | pr_debug("second fanout expander %016llx phy 0x%x attached to ex %016llx phy 0x%x\n", | 1101 | pr_debug("second fanout expander %016llx phy%02d attached to ex %016llx phy%02d\n", |
1097 | SAS_ADDR(ex_phy->attached_sas_addr), | 1102 | SAS_ADDR(ex_phy->attached_sas_addr), |
1098 | ex_phy->attached_phy_id, | 1103 | ex_phy->attached_phy_id, |
1099 | SAS_ADDR(dev->sas_addr), | 1104 | SAS_ADDR(dev->sas_addr), |
@@ -1126,7 +1131,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) | |||
1126 | SAS_ADDR(child->sas_addr)) { | 1131 | SAS_ADDR(child->sas_addr)) { |
1127 | ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED; | 1132 | ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED; |
1128 | if (sas_ex_join_wide_port(dev, i)) | 1133 | if (sas_ex_join_wide_port(dev, i)) |
1129 | pr_debug("Attaching ex phy%d to wide port %016llx\n", | 1134 | pr_debug("Attaching ex phy%02d to wide port %016llx\n", |
1130 | i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr)); | 1135 | i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr)); |
1131 | } | 1136 | } |
1132 | } | 1137 | } |
@@ -1151,7 +1156,7 @@ static int sas_find_sub_addr(struct domain_device *dev, u8 *sub_addr) | |||
1151 | phy->attached_dev_type == SAS_FANOUT_EXPANDER_DEVICE) && | 1156 | phy->attached_dev_type == SAS_FANOUT_EXPANDER_DEVICE) && |
1152 | phy->routing_attr == SUBTRACTIVE_ROUTING) { | 1157 | phy->routing_attr == SUBTRACTIVE_ROUTING) { |
1153 | 1158 | ||
1154 | memcpy(sub_addr, phy->attached_sas_addr,SAS_ADDR_SIZE); | 1159 | memcpy(sub_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); |
1155 | 1160 | ||
1156 | return 1; | 1161 | return 1; |
1157 | } | 1162 | } |
@@ -1163,7 +1168,7 @@ static int sas_check_level_subtractive_boundary(struct domain_device *dev) | |||
1163 | { | 1168 | { |
1164 | struct expander_device *ex = &dev->ex_dev; | 1169 | struct expander_device *ex = &dev->ex_dev; |
1165 | struct domain_device *child; | 1170 | struct domain_device *child; |
1166 | u8 sub_addr[8] = {0, }; | 1171 | u8 sub_addr[SAS_ADDR_SIZE] = {0, }; |
1167 | 1172 | ||
1168 | list_for_each_entry(child, &ex->children, siblings) { | 1173 | list_for_each_entry(child, &ex->children, siblings) { |
1169 | if (child->dev_type != SAS_EDGE_EXPANDER_DEVICE && | 1174 | if (child->dev_type != SAS_EDGE_EXPANDER_DEVICE && |
@@ -1173,7 +1178,7 @@ static int sas_check_level_subtractive_boundary(struct domain_device *dev) | |||
1173 | sas_find_sub_addr(child, sub_addr); | 1178 | sas_find_sub_addr(child, sub_addr); |
1174 | continue; | 1179 | continue; |
1175 | } else { | 1180 | } else { |
1176 | u8 s2[8]; | 1181 | u8 s2[SAS_ADDR_SIZE]; |
1177 | 1182 | ||
1178 | if (sas_find_sub_addr(child, s2) && | 1183 | if (sas_find_sub_addr(child, s2) && |
1179 | (SAS_ADDR(sub_addr) != SAS_ADDR(s2))) { | 1184 | (SAS_ADDR(sub_addr) != SAS_ADDR(s2))) { |
@@ -1261,7 +1266,7 @@ static int sas_check_ex_subtractive_boundary(struct domain_device *dev) | |||
1261 | else if (SAS_ADDR(sub_sas_addr) != | 1266 | else if (SAS_ADDR(sub_sas_addr) != |
1262 | SAS_ADDR(phy->attached_sas_addr)) { | 1267 | SAS_ADDR(phy->attached_sas_addr)) { |
1263 | 1268 | ||
1264 | pr_notice("ex %016llx phy 0x%x diverges(%016llx) on subtractive boundary(%016llx). Disabled\n", | 1269 | pr_notice("ex %016llx phy%02d diverges(%016llx) on subtractive boundary(%016llx). Disabled\n", |
1265 | SAS_ADDR(dev->sas_addr), i, | 1270 | SAS_ADDR(dev->sas_addr), i, |
1266 | SAS_ADDR(phy->attached_sas_addr), | 1271 | SAS_ADDR(phy->attached_sas_addr), |
1267 | SAS_ADDR(sub_sas_addr)); | 1272 | SAS_ADDR(sub_sas_addr)); |
@@ -1282,7 +1287,7 @@ static void sas_print_parent_topology_bug(struct domain_device *child, | |||
1282 | }; | 1287 | }; |
1283 | struct domain_device *parent = child->parent; | 1288 | struct domain_device *parent = child->parent; |
1284 | 1289 | ||
1285 | pr_notice("%s ex %016llx phy 0x%x <--> %s ex %016llx phy 0x%x has %c:%c routing link!\n", | 1290 | pr_notice("%s ex %016llx phy%02d <--> %s ex %016llx phy%02d has %c:%c routing link!\n", |
1286 | ex_type[parent->dev_type], | 1291 | ex_type[parent->dev_type], |
1287 | SAS_ADDR(parent->sas_addr), | 1292 | SAS_ADDR(parent->sas_addr), |
1288 | parent_phy->phy_id, | 1293 | parent_phy->phy_id, |
@@ -1304,7 +1309,7 @@ static int sas_check_eeds(struct domain_device *child, | |||
1304 | 1309 | ||
1305 | if (SAS_ADDR(parent->port->disc.fanout_sas_addr) != 0) { | 1310 | if (SAS_ADDR(parent->port->disc.fanout_sas_addr) != 0) { |
1306 | res = -ENODEV; | 1311 | res = -ENODEV; |
1307 | pr_warn("edge ex %016llx phy S:0x%x <--> edge ex %016llx phy S:0x%x, while there is a fanout ex %016llx\n", | 1312 | pr_warn("edge ex %016llx phy S:%02d <--> edge ex %016llx phy S:%02d, while there is a fanout ex %016llx\n", |
1308 | SAS_ADDR(parent->sas_addr), | 1313 | SAS_ADDR(parent->sas_addr), |
1309 | parent_phy->phy_id, | 1314 | parent_phy->phy_id, |
1310 | SAS_ADDR(child->sas_addr), | 1315 | SAS_ADDR(child->sas_addr), |
@@ -1327,7 +1332,7 @@ static int sas_check_eeds(struct domain_device *child, | |||
1327 | ; | 1332 | ; |
1328 | else { | 1333 | else { |
1329 | res = -ENODEV; | 1334 | res = -ENODEV; |
1330 | pr_warn("edge ex %016llx phy 0x%x <--> edge ex %016llx phy 0x%x link forms a third EEDS!\n", | 1335 | pr_warn("edge ex %016llx phy%02d <--> edge ex %016llx phy%02d link forms a third EEDS!\n", |
1331 | SAS_ADDR(parent->sas_addr), | 1336 | SAS_ADDR(parent->sas_addr), |
1332 | parent_phy->phy_id, | 1337 | parent_phy->phy_id, |
1333 | SAS_ADDR(child->sas_addr), | 1338 | SAS_ADDR(child->sas_addr), |
@@ -1445,11 +1450,11 @@ static int sas_configure_present(struct domain_device *dev, int phy_id, | |||
1445 | goto out; | 1450 | goto out; |
1446 | res = rri_resp[2]; | 1451 | res = rri_resp[2]; |
1447 | if (res == SMP_RESP_NO_INDEX) { | 1452 | if (res == SMP_RESP_NO_INDEX) { |
1448 | pr_warn("overflow of indexes: dev %016llx phy 0x%x index 0x%x\n", | 1453 | pr_warn("overflow of indexes: dev %016llx phy%02d index 0x%x\n", |
1449 | SAS_ADDR(dev->sas_addr), phy_id, i); | 1454 | SAS_ADDR(dev->sas_addr), phy_id, i); |
1450 | goto out; | 1455 | goto out; |
1451 | } else if (res != SMP_RESP_FUNC_ACC) { | 1456 | } else if (res != SMP_RESP_FUNC_ACC) { |
1452 | pr_notice("%s: dev %016llx phy 0x%x index 0x%x result 0x%x\n", | 1457 | pr_notice("%s: dev %016llx phy%02d index 0x%x result 0x%x\n", |
1453 | __func__, SAS_ADDR(dev->sas_addr), phy_id, | 1458 | __func__, SAS_ADDR(dev->sas_addr), phy_id, |
1454 | i, res); | 1459 | i, res); |
1455 | goto out; | 1460 | goto out; |
@@ -1515,7 +1520,7 @@ static int sas_configure_set(struct domain_device *dev, int phy_id, | |||
1515 | goto out; | 1520 | goto out; |
1516 | res = cri_resp[2]; | 1521 | res = cri_resp[2]; |
1517 | if (res == SMP_RESP_NO_INDEX) { | 1522 | if (res == SMP_RESP_NO_INDEX) { |
1518 | pr_warn("overflow of indexes: dev %016llx phy 0x%x index 0x%x\n", | 1523 | pr_warn("overflow of indexes: dev %016llx phy%02d index 0x%x\n", |
1519 | SAS_ADDR(dev->sas_addr), phy_id, index); | 1524 | SAS_ADDR(dev->sas_addr), phy_id, index); |
1520 | } | 1525 | } |
1521 | out: | 1526 | out: |
@@ -1760,10 +1765,11 @@ static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id, | |||
1760 | 1765 | ||
1761 | res = sas_get_phy_discover(dev, phy_id, disc_resp); | 1766 | res = sas_get_phy_discover(dev, phy_id, disc_resp); |
1762 | if (res == 0) { | 1767 | if (res == 0) { |
1763 | memcpy(sas_addr, disc_resp->disc.attached_sas_addr, 8); | 1768 | memcpy(sas_addr, disc_resp->disc.attached_sas_addr, |
1769 | SAS_ADDR_SIZE); | ||
1764 | *type = to_dev_type(dr); | 1770 | *type = to_dev_type(dr); |
1765 | if (*type == 0) | 1771 | if (*type == 0) |
1766 | memset(sas_addr, 0, 8); | 1772 | memset(sas_addr, 0, SAS_ADDR_SIZE); |
1767 | } | 1773 | } |
1768 | kfree(disc_resp); | 1774 | kfree(disc_resp); |
1769 | return res; | 1775 | return res; |
@@ -1870,10 +1876,12 @@ static int sas_find_bcast_dev(struct domain_device *dev, | |||
1870 | if (phy_id != -1) { | 1876 | if (phy_id != -1) { |
1871 | *src_dev = dev; | 1877 | *src_dev = dev; |
1872 | ex->ex_change_count = ex_change_count; | 1878 | ex->ex_change_count = ex_change_count; |
1873 | pr_info("Expander phy change count has changed\n"); | 1879 | pr_info("ex %016llx phy%02d change count has changed\n", |
1880 | SAS_ADDR(dev->sas_addr), phy_id); | ||
1874 | return res; | 1881 | return res; |
1875 | } else | 1882 | } else |
1876 | pr_info("Expander phys DID NOT change\n"); | 1883 | pr_info("ex %016llx phys DID NOT change\n", |
1884 | SAS_ADDR(dev->sas_addr)); | ||
1877 | } | 1885 | } |
1878 | list_for_each_entry(ch, &ex->children, siblings) { | 1886 | list_for_each_entry(ch, &ex->children, siblings) { |
1879 | if (ch->dev_type == SAS_EDGE_EXPANDER_DEVICE || ch->dev_type == SAS_FANOUT_EXPANDER_DEVICE) { | 1887 | if (ch->dev_type == SAS_EDGE_EXPANDER_DEVICE || ch->dev_type == SAS_FANOUT_EXPANDER_DEVICE) { |
@@ -1983,7 +1991,7 @@ static int sas_discover_new(struct domain_device *dev, int phy_id) | |||
1983 | struct domain_device *child; | 1991 | struct domain_device *child; |
1984 | int res; | 1992 | int res; |
1985 | 1993 | ||
1986 | pr_debug("ex %016llx phy%d new device attached\n", | 1994 | pr_debug("ex %016llx phy%02d new device attached\n", |
1987 | SAS_ADDR(dev->sas_addr), phy_id); | 1995 | SAS_ADDR(dev->sas_addr), phy_id); |
1988 | res = sas_ex_phy_discover(dev, phy_id); | 1996 | res = sas_ex_phy_discover(dev, phy_id); |
1989 | if (res) | 1997 | if (res) |
@@ -2022,15 +2030,23 @@ static bool dev_type_flutter(enum sas_device_type new, enum sas_device_type old) | |||
2022 | return false; | 2030 | return false; |
2023 | } | 2031 | } |
2024 | 2032 | ||
2025 | static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) | 2033 | static int sas_rediscover_dev(struct domain_device *dev, int phy_id, |
2034 | bool last, int sibling) | ||
2026 | { | 2035 | { |
2027 | struct expander_device *ex = &dev->ex_dev; | 2036 | struct expander_device *ex = &dev->ex_dev; |
2028 | struct ex_phy *phy = &ex->ex_phy[phy_id]; | 2037 | struct ex_phy *phy = &ex->ex_phy[phy_id]; |
2029 | enum sas_device_type type = SAS_PHY_UNUSED; | 2038 | enum sas_device_type type = SAS_PHY_UNUSED; |
2030 | u8 sas_addr[8]; | 2039 | u8 sas_addr[SAS_ADDR_SIZE]; |
2040 | char msg[80] = ""; | ||
2031 | int res; | 2041 | int res; |
2032 | 2042 | ||
2033 | memset(sas_addr, 0, 8); | 2043 | if (!last) |
2044 | sprintf(msg, ", part of a wide port with phy%02d", sibling); | ||
2045 | |||
2046 | pr_debug("ex %016llx rediscovering phy%02d%s\n", | ||
2047 | SAS_ADDR(dev->sas_addr), phy_id, msg); | ||
2048 | |||
2049 | memset(sas_addr, 0, SAS_ADDR_SIZE); | ||
2034 | res = sas_get_phy_attached_dev(dev, phy_id, sas_addr, &type); | 2050 | res = sas_get_phy_attached_dev(dev, phy_id, sas_addr, &type); |
2035 | switch (res) { | 2051 | switch (res) { |
2036 | case SMP_RESP_NO_PHY: | 2052 | case SMP_RESP_NO_PHY: |
@@ -2052,6 +2068,11 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) | |||
2052 | if ((SAS_ADDR(sas_addr) == 0) || (res == -ECOMM)) { | 2068 | if ((SAS_ADDR(sas_addr) == 0) || (res == -ECOMM)) { |
2053 | phy->phy_state = PHY_EMPTY; | 2069 | phy->phy_state = PHY_EMPTY; |
2054 | sas_unregister_devs_sas_addr(dev, phy_id, last); | 2070 | sas_unregister_devs_sas_addr(dev, phy_id, last); |
2071 | /* | ||
2072 | * Even though the PHY is empty, for convenience we discover | ||
2073 | * the PHY to update the PHY info, like negotiated linkrate. | ||
2074 | */ | ||
2075 | sas_ex_phy_discover(dev, phy_id); | ||
2055 | return res; | 2076 | return res; |
2056 | } else if (SAS_ADDR(sas_addr) == SAS_ADDR(phy->attached_sas_addr) && | 2077 | } else if (SAS_ADDR(sas_addr) == SAS_ADDR(phy->attached_sas_addr) && |
2057 | dev_type_flutter(type, phy->attached_dev_type)) { | 2078 | dev_type_flutter(type, phy->attached_dev_type)) { |
@@ -2062,13 +2083,13 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) | |||
2062 | 2083 | ||
2063 | if (ata_dev && phy->attached_dev_type == SAS_SATA_PENDING) | 2084 | if (ata_dev && phy->attached_dev_type == SAS_SATA_PENDING) |
2064 | action = ", needs recovery"; | 2085 | action = ", needs recovery"; |
2065 | pr_debug("ex %016llx phy 0x%x broadcast flutter%s\n", | 2086 | pr_debug("ex %016llx phy%02d broadcast flutter%s\n", |
2066 | SAS_ADDR(dev->sas_addr), phy_id, action); | 2087 | SAS_ADDR(dev->sas_addr), phy_id, action); |
2067 | return res; | 2088 | return res; |
2068 | } | 2089 | } |
2069 | 2090 | ||
2070 | /* we always have to delete the old device when we went here */ | 2091 | /* we always have to delete the old device when we went here */ |
2071 | pr_info("ex %016llx phy 0x%x replace %016llx\n", | 2092 | pr_info("ex %016llx phy%02d replace %016llx\n", |
2072 | SAS_ADDR(dev->sas_addr), phy_id, | 2093 | SAS_ADDR(dev->sas_addr), phy_id, |
2073 | SAS_ADDR(phy->attached_sas_addr)); | 2094 | SAS_ADDR(phy->attached_sas_addr)); |
2074 | sas_unregister_devs_sas_addr(dev, phy_id, last); | 2095 | sas_unregister_devs_sas_addr(dev, phy_id, last); |
@@ -2098,7 +2119,7 @@ static int sas_rediscover(struct domain_device *dev, const int phy_id) | |||
2098 | int i; | 2119 | int i; |
2099 | bool last = true; /* is this the last phy of the port */ | 2120 | bool last = true; /* is this the last phy of the port */ |
2100 | 2121 | ||
2101 | pr_debug("ex %016llx phy%d originated BROADCAST(CHANGE)\n", | 2122 | pr_debug("ex %016llx phy%02d originated BROADCAST(CHANGE)\n", |
2102 | SAS_ADDR(dev->sas_addr), phy_id); | 2123 | SAS_ADDR(dev->sas_addr), phy_id); |
2103 | 2124 | ||
2104 | if (SAS_ADDR(changed_phy->attached_sas_addr) != 0) { | 2125 | if (SAS_ADDR(changed_phy->attached_sas_addr) != 0) { |
@@ -2109,13 +2130,11 @@ static int sas_rediscover(struct domain_device *dev, const int phy_id) | |||
2109 | continue; | 2130 | continue; |
2110 | if (SAS_ADDR(phy->attached_sas_addr) == | 2131 | if (SAS_ADDR(phy->attached_sas_addr) == |
2111 | SAS_ADDR(changed_phy->attached_sas_addr)) { | 2132 | SAS_ADDR(changed_phy->attached_sas_addr)) { |
2112 | pr_debug("phy%d part of wide port with phy%d\n", | ||
2113 | phy_id, i); | ||
2114 | last = false; | 2133 | last = false; |
2115 | break; | 2134 | break; |
2116 | } | 2135 | } |
2117 | } | 2136 | } |
2118 | res = sas_rediscover_dev(dev, phy_id, last); | 2137 | res = sas_rediscover_dev(dev, phy_id, last, i); |
2119 | } else | 2138 | } else |
2120 | res = sas_discover_new(dev, phy_id); | 2139 | res = sas_discover_new(dev, phy_id); |
2121 | return res; | 2140 | return res; |
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 221340ee8651..28a460c36c0b 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c | |||
@@ -87,25 +87,27 @@ EXPORT_SYMBOL_GPL(sas_free_task); | |||
87 | /*------------ SAS addr hash -----------*/ | 87 | /*------------ SAS addr hash -----------*/ |
88 | void sas_hash_addr(u8 *hashed, const u8 *sas_addr) | 88 | void sas_hash_addr(u8 *hashed, const u8 *sas_addr) |
89 | { | 89 | { |
90 | const u32 poly = 0x00DB2777; | 90 | const u32 poly = 0x00DB2777; |
91 | u32 r = 0; | 91 | u32 r = 0; |
92 | int i; | 92 | int i; |
93 | 93 | ||
94 | for (i = 0; i < 8; i++) { | 94 | for (i = 0; i < SAS_ADDR_SIZE; i++) { |
95 | int b; | 95 | int b; |
96 | for (b = 7; b >= 0; b--) { | 96 | |
97 | r <<= 1; | 97 | for (b = (SAS_ADDR_SIZE - 1); b >= 0; b--) { |
98 | if ((1 << b) & sas_addr[i]) { | 98 | r <<= 1; |
99 | if (!(r & 0x01000000)) | 99 | if ((1 << b) & sas_addr[i]) { |
100 | r ^= poly; | 100 | if (!(r & 0x01000000)) |
101 | } else if (r & 0x01000000) | 101 | r ^= poly; |
102 | r ^= poly; | 102 | } else if (r & 0x01000000) { |
103 | } | 103 | r ^= poly; |
104 | } | 104 | } |
105 | 105 | } | |
106 | hashed[0] = (r >> 16) & 0xFF; | 106 | } |
107 | hashed[1] = (r >> 8) & 0xFF ; | 107 | |
108 | hashed[2] = r & 0xFF; | 108 | hashed[0] = (r >> 16) & 0xFF; |
109 | hashed[1] = (r >> 8) & 0xFF; | ||
110 | hashed[2] = r & 0xFF; | ||
109 | } | 111 | } |
110 | 112 | ||
111 | int sas_register_ha(struct sas_ha_struct *sas_ha) | 113 | int sas_register_ha(struct sas_ha_struct *sas_ha) |
@@ -623,7 +625,7 @@ struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy) | |||
623 | if (atomic_read(&phy->event_nr) > phy->ha->event_thres) { | 625 | if (atomic_read(&phy->event_nr) > phy->ha->event_thres) { |
624 | if (i->dft->lldd_control_phy) { | 626 | if (i->dft->lldd_control_phy) { |
625 | if (cmpxchg(&phy->in_shutdown, 0, 1) == 0) { | 627 | if (cmpxchg(&phy->in_shutdown, 0, 1) == 0) { |
626 | pr_notice("The phy%02d bursting events, shut it down.\n", | 628 | pr_notice("The phy%d bursting events, shut it down.\n", |
627 | phy->id); | 629 | phy->id); |
628 | sas_notify_phy_event(phy, PHYE_SHUTDOWN); | 630 | sas_notify_phy_event(phy, PHYE_SHUTDOWN); |
629 | } | 631 | } |
diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c index 0374243c85d0..e030e1452136 100644 --- a/drivers/scsi/libsas/sas_phy.c +++ b/drivers/scsi/libsas/sas_phy.c | |||
@@ -122,11 +122,10 @@ static void sas_phye_shutdown(struct work_struct *work) | |||
122 | phy->enabled = 0; | 122 | phy->enabled = 0; |
123 | ret = i->dft->lldd_control_phy(phy, PHY_FUNC_DISABLE, NULL); | 123 | ret = i->dft->lldd_control_phy(phy, PHY_FUNC_DISABLE, NULL); |
124 | if (ret) | 124 | if (ret) |
125 | pr_notice("lldd disable phy%02d returned %d\n", | 125 | pr_notice("lldd disable phy%d returned %d\n", phy->id, |
126 | phy->id, ret); | 126 | ret); |
127 | } else | 127 | } else |
128 | pr_notice("phy%02d is not enabled, cannot shutdown\n", | 128 | pr_notice("phy%d is not enabled, cannot shutdown\n", phy->id); |
129 | phy->id); | ||
130 | } | 129 | } |
131 | 130 | ||
132 | /* ---------- Phy class registration ---------- */ | 131 | /* ---------- Phy class registration ---------- */ |
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c index 03fe479359b6..38a10478605c 100644 --- a/drivers/scsi/libsas/sas_port.c +++ b/drivers/scsi/libsas/sas_port.c | |||
@@ -95,6 +95,7 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
95 | int i; | 95 | int i; |
96 | struct sas_ha_struct *sas_ha = phy->ha; | 96 | struct sas_ha_struct *sas_ha = phy->ha; |
97 | struct asd_sas_port *port = phy->port; | 97 | struct asd_sas_port *port = phy->port; |
98 | struct domain_device *port_dev; | ||
98 | struct sas_internal *si = | 99 | struct sas_internal *si = |
99 | to_sas_internal(sas_ha->core.shost->transportt); | 100 | to_sas_internal(sas_ha->core.shost->transportt); |
100 | unsigned long flags; | 101 | unsigned long flags; |
@@ -153,8 +154,9 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
153 | } | 154 | } |
154 | 155 | ||
155 | /* add the phy to the port */ | 156 | /* add the phy to the port */ |
157 | port_dev = port->port_dev; | ||
156 | list_add_tail(&phy->port_phy_el, &port->phy_list); | 158 | list_add_tail(&phy->port_phy_el, &port->phy_list); |
157 | sas_phy_set_target(phy, port->port_dev); | 159 | sas_phy_set_target(phy, port_dev); |
158 | phy->port = port; | 160 | phy->port = port; |
159 | port->num_phys++; | 161 | port->num_phys++; |
160 | port->phy_mask |= (1U << phy->id); | 162 | port->phy_mask |= (1U << phy->id); |
@@ -184,14 +186,21 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
184 | port->phy_mask, | 186 | port->phy_mask, |
185 | SAS_ADDR(port->attached_sas_addr)); | 187 | SAS_ADDR(port->attached_sas_addr)); |
186 | 188 | ||
187 | if (port->port_dev) | 189 | if (port_dev) |
188 | port->port_dev->pathways = port->num_phys; | 190 | port_dev->pathways = port->num_phys; |
189 | 191 | ||
190 | /* Tell the LLDD about this port formation. */ | 192 | /* Tell the LLDD about this port formation. */ |
191 | if (si->dft->lldd_port_formed) | 193 | if (si->dft->lldd_port_formed) |
192 | si->dft->lldd_port_formed(phy); | 194 | si->dft->lldd_port_formed(phy); |
193 | 195 | ||
194 | sas_discover_event(phy->port, DISCE_DISCOVER_DOMAIN); | 196 | sas_discover_event(phy->port, DISCE_DISCOVER_DOMAIN); |
197 | /* Only insert a revalidate event after initial discovery */ | ||
198 | if (port_dev && sas_dev_type_is_expander(port_dev->dev_type)) { | ||
199 | struct expander_device *ex_dev = &port_dev->ex_dev; | ||
200 | |||
201 | ex_dev->ex_change_count = -1; | ||
202 | sas_discover_event(port, DISCE_REVALIDATE_DOMAIN); | ||
203 | } | ||
195 | flush_workqueue(sas_ha->disco_q); | 204 | flush_workqueue(sas_ha->disco_q); |
196 | } | 205 | } |
197 | 206 | ||
@@ -254,6 +263,15 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone) | |||
254 | spin_unlock(&port->phy_list_lock); | 263 | spin_unlock(&port->phy_list_lock); |
255 | spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags); | 264 | spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags); |
256 | 265 | ||
266 | /* Only insert revalidate event if the port still has members */ | ||
267 | if (port->port && dev && sas_dev_type_is_expander(dev->dev_type)) { | ||
268 | struct expander_device *ex_dev = &dev->ex_dev; | ||
269 | |||
270 | ex_dev->ex_change_count = -1; | ||
271 | sas_discover_event(port, DISCE_REVALIDATE_DOMAIN); | ||
272 | } | ||
273 | flush_workqueue(sas_ha->disco_q); | ||
274 | |||
257 | return; | 275 | return; |
258 | } | 276 | } |
259 | 277 | ||
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 41d849f283f6..aafcffaa25f7 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -942,6 +942,7 @@ struct lpfc_hba { | |||
942 | int brd_no; /* FC board number */ | 942 | int brd_no; /* FC board number */ |
943 | char SerialNumber[32]; /* adapter Serial Number */ | 943 | char SerialNumber[32]; /* adapter Serial Number */ |
944 | char OptionROMVersion[32]; /* adapter BIOS / Fcode version */ | 944 | char OptionROMVersion[32]; /* adapter BIOS / Fcode version */ |
945 | char BIOSVersion[16]; /* Boot BIOS version */ | ||
945 | char ModelDesc[256]; /* Model Description */ | 946 | char ModelDesc[256]; /* Model Description */ |
946 | char ModelName[80]; /* Model Name */ | 947 | char ModelName[80]; /* Model Name */ |
947 | char ProgramType[256]; /* Program Type */ | 948 | char ProgramType[256]; /* Program Type */ |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index ce3e541434dc..e9adb3f1961d 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -71,6 +71,23 @@ | |||
71 | #define LPFC_REG_WRITE_KEY_SIZE 4 | 71 | #define LPFC_REG_WRITE_KEY_SIZE 4 |
72 | #define LPFC_REG_WRITE_KEY "EMLX" | 72 | #define LPFC_REG_WRITE_KEY "EMLX" |
73 | 73 | ||
74 | const char *const trunk_errmsg[] = { /* map errcode */ | ||
75 | "", /* There is no such error code at index 0*/ | ||
76 | "link negotiated speed does not match existing" | ||
77 | " trunk - link was \"low\" speed", | ||
78 | "link negotiated speed does not match" | ||
79 | " existing trunk - link was \"middle\" speed", | ||
80 | "link negotiated speed does not match existing" | ||
81 | " trunk - link was \"high\" speed", | ||
82 | "Attached to non-trunking port - F_Port", | ||
83 | "Attached to non-trunking port - N_Port", | ||
84 | "FLOGI response timeout", | ||
85 | "non-FLOGI frame received", | ||
86 | "Invalid FLOGI response", | ||
87 | "Trunking initialization protocol", | ||
88 | "Trunk peer device mismatch", | ||
89 | }; | ||
90 | |||
74 | /** | 91 | /** |
75 | * lpfc_jedec_to_ascii - Hex to ascii convertor according to JEDEC rules | 92 | * lpfc_jedec_to_ascii - Hex to ascii convertor according to JEDEC rules |
76 | * @incr: integer to convert. | 93 | * @incr: integer to convert. |
@@ -114,7 +131,7 @@ static ssize_t | |||
114 | lpfc_drvr_version_show(struct device *dev, struct device_attribute *attr, | 131 | lpfc_drvr_version_show(struct device *dev, struct device_attribute *attr, |
115 | char *buf) | 132 | char *buf) |
116 | { | 133 | { |
117 | return snprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n"); | 134 | return scnprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n"); |
118 | } | 135 | } |
119 | 136 | ||
120 | /** | 137 | /** |
@@ -134,9 +151,9 @@ lpfc_enable_fip_show(struct device *dev, struct device_attribute *attr, | |||
134 | struct lpfc_hba *phba = vport->phba; | 151 | struct lpfc_hba *phba = vport->phba; |
135 | 152 | ||
136 | if (phba->hba_flag & HBA_FIP_SUPPORT) | 153 | if (phba->hba_flag & HBA_FIP_SUPPORT) |
137 | return snprintf(buf, PAGE_SIZE, "1\n"); | 154 | return scnprintf(buf, PAGE_SIZE, "1\n"); |
138 | else | 155 | else |
139 | return snprintf(buf, PAGE_SIZE, "0\n"); | 156 | return scnprintf(buf, PAGE_SIZE, "0\n"); |
140 | } | 157 | } |
141 | 158 | ||
142 | static ssize_t | 159 | static ssize_t |
@@ -564,14 +581,15 @@ lpfc_bg_info_show(struct device *dev, struct device_attribute *attr, | |||
564 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 581 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
565 | struct lpfc_hba *phba = vport->phba; | 582 | struct lpfc_hba *phba = vport->phba; |
566 | 583 | ||
567 | if (phba->cfg_enable_bg) | 584 | if (phba->cfg_enable_bg) { |
568 | if (phba->sli3_options & LPFC_SLI3_BG_ENABLED) | 585 | if (phba->sli3_options & LPFC_SLI3_BG_ENABLED) |
569 | return snprintf(buf, PAGE_SIZE, "BlockGuard Enabled\n"); | 586 | return scnprintf(buf, PAGE_SIZE, |
587 | "BlockGuard Enabled\n"); | ||
570 | else | 588 | else |
571 | return snprintf(buf, PAGE_SIZE, | 589 | return scnprintf(buf, PAGE_SIZE, |
572 | "BlockGuard Not Supported\n"); | 590 | "BlockGuard Not Supported\n"); |
573 | else | 591 | } else |
574 | return snprintf(buf, PAGE_SIZE, | 592 | return scnprintf(buf, PAGE_SIZE, |
575 | "BlockGuard Disabled\n"); | 593 | "BlockGuard Disabled\n"); |
576 | } | 594 | } |
577 | 595 | ||
@@ -583,7 +601,7 @@ lpfc_bg_guard_err_show(struct device *dev, struct device_attribute *attr, | |||
583 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 601 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
584 | struct lpfc_hba *phba = vport->phba; | 602 | struct lpfc_hba *phba = vport->phba; |
585 | 603 | ||
586 | return snprintf(buf, PAGE_SIZE, "%llu\n", | 604 | return scnprintf(buf, PAGE_SIZE, "%llu\n", |
587 | (unsigned long long)phba->bg_guard_err_cnt); | 605 | (unsigned long long)phba->bg_guard_err_cnt); |
588 | } | 606 | } |
589 | 607 | ||
@@ -595,7 +613,7 @@ lpfc_bg_apptag_err_show(struct device *dev, struct device_attribute *attr, | |||
595 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 613 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
596 | struct lpfc_hba *phba = vport->phba; | 614 | struct lpfc_hba *phba = vport->phba; |
597 | 615 | ||
598 | return snprintf(buf, PAGE_SIZE, "%llu\n", | 616 | return scnprintf(buf, PAGE_SIZE, "%llu\n", |
599 | (unsigned long long)phba->bg_apptag_err_cnt); | 617 | (unsigned long long)phba->bg_apptag_err_cnt); |
600 | } | 618 | } |
601 | 619 | ||
@@ -607,7 +625,7 @@ lpfc_bg_reftag_err_show(struct device *dev, struct device_attribute *attr, | |||
607 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 625 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
608 | struct lpfc_hba *phba = vport->phba; | 626 | struct lpfc_hba *phba = vport->phba; |
609 | 627 | ||
610 | return snprintf(buf, PAGE_SIZE, "%llu\n", | 628 | return scnprintf(buf, PAGE_SIZE, "%llu\n", |
611 | (unsigned long long)phba->bg_reftag_err_cnt); | 629 | (unsigned long long)phba->bg_reftag_err_cnt); |
612 | } | 630 | } |
613 | 631 | ||
@@ -625,7 +643,7 @@ lpfc_info_show(struct device *dev, struct device_attribute *attr, | |||
625 | { | 643 | { |
626 | struct Scsi_Host *host = class_to_shost(dev); | 644 | struct Scsi_Host *host = class_to_shost(dev); |
627 | 645 | ||
628 | return snprintf(buf, PAGE_SIZE, "%s\n",lpfc_info(host)); | 646 | return scnprintf(buf, PAGE_SIZE, "%s\n", lpfc_info(host)); |
629 | } | 647 | } |
630 | 648 | ||
631 | /** | 649 | /** |
@@ -644,7 +662,7 @@ lpfc_serialnum_show(struct device *dev, struct device_attribute *attr, | |||
644 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 662 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
645 | struct lpfc_hba *phba = vport->phba; | 663 | struct lpfc_hba *phba = vport->phba; |
646 | 664 | ||
647 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber); | 665 | return scnprintf(buf, PAGE_SIZE, "%s\n", phba->SerialNumber); |
648 | } | 666 | } |
649 | 667 | ||
650 | /** | 668 | /** |
@@ -666,7 +684,7 @@ lpfc_temp_sensor_show(struct device *dev, struct device_attribute *attr, | |||
666 | struct Scsi_Host *shost = class_to_shost(dev); | 684 | struct Scsi_Host *shost = class_to_shost(dev); |
667 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 685 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
668 | struct lpfc_hba *phba = vport->phba; | 686 | struct lpfc_hba *phba = vport->phba; |
669 | return snprintf(buf, PAGE_SIZE, "%d\n",phba->temp_sensor_support); | 687 | return scnprintf(buf, PAGE_SIZE, "%d\n", phba->temp_sensor_support); |
670 | } | 688 | } |
671 | 689 | ||
672 | /** | 690 | /** |
@@ -685,7 +703,7 @@ lpfc_modeldesc_show(struct device *dev, struct device_attribute *attr, | |||
685 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 703 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
686 | struct lpfc_hba *phba = vport->phba; | 704 | struct lpfc_hba *phba = vport->phba; |
687 | 705 | ||
688 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc); | 706 | return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ModelDesc); |
689 | } | 707 | } |
690 | 708 | ||
691 | /** | 709 | /** |
@@ -704,7 +722,7 @@ lpfc_modelname_show(struct device *dev, struct device_attribute *attr, | |||
704 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 722 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
705 | struct lpfc_hba *phba = vport->phba; | 723 | struct lpfc_hba *phba = vport->phba; |
706 | 724 | ||
707 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName); | 725 | return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ModelName); |
708 | } | 726 | } |
709 | 727 | ||
710 | /** | 728 | /** |
@@ -723,7 +741,7 @@ lpfc_programtype_show(struct device *dev, struct device_attribute *attr, | |||
723 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 741 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
724 | struct lpfc_hba *phba = vport->phba; | 742 | struct lpfc_hba *phba = vport->phba; |
725 | 743 | ||
726 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType); | 744 | return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ProgramType); |
727 | } | 745 | } |
728 | 746 | ||
729 | /** | 747 | /** |
@@ -741,7 +759,7 @@ lpfc_mlomgmt_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
741 | struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; | 759 | struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; |
742 | struct lpfc_hba *phba = vport->phba; | 760 | struct lpfc_hba *phba = vport->phba; |
743 | 761 | ||
744 | return snprintf(buf, PAGE_SIZE, "%d\n", | 762 | return scnprintf(buf, PAGE_SIZE, "%d\n", |
745 | (phba->sli.sli_flag & LPFC_MENLO_MAINT)); | 763 | (phba->sli.sli_flag & LPFC_MENLO_MAINT)); |
746 | } | 764 | } |
747 | 765 | ||
@@ -761,7 +779,7 @@ lpfc_vportnum_show(struct device *dev, struct device_attribute *attr, | |||
761 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 779 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
762 | struct lpfc_hba *phba = vport->phba; | 780 | struct lpfc_hba *phba = vport->phba; |
763 | 781 | ||
764 | return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port); | 782 | return scnprintf(buf, PAGE_SIZE, "%s\n", phba->Port); |
765 | } | 783 | } |
766 | 784 | ||
767 | /** | 785 | /** |
@@ -789,10 +807,10 @@ lpfc_fwrev_show(struct device *dev, struct device_attribute *attr, | |||
789 | sli_family = phba->sli4_hba.pc_sli4_params.sli_family; | 807 | sli_family = phba->sli4_hba.pc_sli4_params.sli_family; |
790 | 808 | ||
791 | if (phba->sli_rev < LPFC_SLI_REV4) | 809 | if (phba->sli_rev < LPFC_SLI_REV4) |
792 | len = snprintf(buf, PAGE_SIZE, "%s, sli-%d\n", | 810 | len = scnprintf(buf, PAGE_SIZE, "%s, sli-%d\n", |
793 | fwrev, phba->sli_rev); | 811 | fwrev, phba->sli_rev); |
794 | else | 812 | else |
795 | len = snprintf(buf, PAGE_SIZE, "%s, sli-%d:%d:%x\n", | 813 | len = scnprintf(buf, PAGE_SIZE, "%s, sli-%d:%d:%x\n", |
796 | fwrev, phba->sli_rev, if_type, sli_family); | 814 | fwrev, phba->sli_rev, if_type, sli_family); |
797 | 815 | ||
798 | return len; | 816 | return len; |
@@ -816,7 +834,7 @@ lpfc_hdw_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
816 | lpfc_vpd_t *vp = &phba->vpd; | 834 | lpfc_vpd_t *vp = &phba->vpd; |
817 | 835 | ||
818 | lpfc_jedec_to_ascii(vp->rev.biuRev, hdw); | 836 | lpfc_jedec_to_ascii(vp->rev.biuRev, hdw); |
819 | return snprintf(buf, PAGE_SIZE, "%s\n", hdw); | 837 | return scnprintf(buf, PAGE_SIZE, "%s\n", hdw); |
820 | } | 838 | } |
821 | 839 | ||
822 | /** | 840 | /** |
@@ -837,10 +855,11 @@ lpfc_option_rom_version_show(struct device *dev, struct device_attribute *attr, | |||
837 | char fwrev[FW_REV_STR_SIZE]; | 855 | char fwrev[FW_REV_STR_SIZE]; |
838 | 856 | ||
839 | if (phba->sli_rev < LPFC_SLI_REV4) | 857 | if (phba->sli_rev < LPFC_SLI_REV4) |
840 | return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion); | 858 | return scnprintf(buf, PAGE_SIZE, "%s\n", |
859 | phba->OptionROMVersion); | ||
841 | 860 | ||
842 | lpfc_decode_firmware_rev(phba, fwrev, 1); | 861 | lpfc_decode_firmware_rev(phba, fwrev, 1); |
843 | return snprintf(buf, PAGE_SIZE, "%s\n", fwrev); | 862 | return scnprintf(buf, PAGE_SIZE, "%s\n", fwrev); |
844 | } | 863 | } |
845 | 864 | ||
846 | /** | 865 | /** |
@@ -871,20 +890,20 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr, | |||
871 | case LPFC_LINK_DOWN: | 890 | case LPFC_LINK_DOWN: |
872 | case LPFC_HBA_ERROR: | 891 | case LPFC_HBA_ERROR: |
873 | if (phba->hba_flag & LINK_DISABLED) | 892 | if (phba->hba_flag & LINK_DISABLED) |
874 | len += snprintf(buf + len, PAGE_SIZE-len, | 893 | len += scnprintf(buf + len, PAGE_SIZE-len, |
875 | "Link Down - User disabled\n"); | 894 | "Link Down - User disabled\n"); |
876 | else | 895 | else |
877 | len += snprintf(buf + len, PAGE_SIZE-len, | 896 | len += scnprintf(buf + len, PAGE_SIZE-len, |
878 | "Link Down\n"); | 897 | "Link Down\n"); |
879 | break; | 898 | break; |
880 | case LPFC_LINK_UP: | 899 | case LPFC_LINK_UP: |
881 | case LPFC_CLEAR_LA: | 900 | case LPFC_CLEAR_LA: |
882 | case LPFC_HBA_READY: | 901 | case LPFC_HBA_READY: |
883 | len += snprintf(buf + len, PAGE_SIZE-len, "Link Up - "); | 902 | len += scnprintf(buf + len, PAGE_SIZE-len, "Link Up - "); |
884 | 903 | ||
885 | switch (vport->port_state) { | 904 | switch (vport->port_state) { |
886 | case LPFC_LOCAL_CFG_LINK: | 905 | case LPFC_LOCAL_CFG_LINK: |
887 | len += snprintf(buf + len, PAGE_SIZE-len, | 906 | len += scnprintf(buf + len, PAGE_SIZE-len, |
888 | "Configuring Link\n"); | 907 | "Configuring Link\n"); |
889 | break; | 908 | break; |
890 | case LPFC_FDISC: | 909 | case LPFC_FDISC: |
@@ -894,38 +913,40 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr, | |||
894 | case LPFC_NS_QRY: | 913 | case LPFC_NS_QRY: |
895 | case LPFC_BUILD_DISC_LIST: | 914 | case LPFC_BUILD_DISC_LIST: |
896 | case LPFC_DISC_AUTH: | 915 | case LPFC_DISC_AUTH: |
897 | len += snprintf(buf + len, PAGE_SIZE - len, | 916 | len += scnprintf(buf + len, PAGE_SIZE - len, |
898 | "Discovery\n"); | 917 | "Discovery\n"); |
899 | break; | 918 | break; |
900 | case LPFC_VPORT_READY: | 919 | case LPFC_VPORT_READY: |
901 | len += snprintf(buf + len, PAGE_SIZE - len, "Ready\n"); | 920 | len += scnprintf(buf + len, PAGE_SIZE - len, |
921 | "Ready\n"); | ||
902 | break; | 922 | break; |
903 | 923 | ||
904 | case LPFC_VPORT_FAILED: | 924 | case LPFC_VPORT_FAILED: |
905 | len += snprintf(buf + len, PAGE_SIZE - len, "Failed\n"); | 925 | len += scnprintf(buf + len, PAGE_SIZE - len, |
926 | "Failed\n"); | ||
906 | break; | 927 | break; |
907 | 928 | ||
908 | case LPFC_VPORT_UNKNOWN: | 929 | case LPFC_VPORT_UNKNOWN: |
909 | len += snprintf(buf + len, PAGE_SIZE - len, | 930 | len += scnprintf(buf + len, PAGE_SIZE - len, |
910 | "Unknown\n"); | 931 | "Unknown\n"); |
911 | break; | 932 | break; |
912 | } | 933 | } |
913 | if (phba->sli.sli_flag & LPFC_MENLO_MAINT) | 934 | if (phba->sli.sli_flag & LPFC_MENLO_MAINT) |
914 | len += snprintf(buf + len, PAGE_SIZE-len, | 935 | len += scnprintf(buf + len, PAGE_SIZE-len, |
915 | " Menlo Maint Mode\n"); | 936 | " Menlo Maint Mode\n"); |
916 | else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) { | 937 | else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) { |
917 | if (vport->fc_flag & FC_PUBLIC_LOOP) | 938 | if (vport->fc_flag & FC_PUBLIC_LOOP) |
918 | len += snprintf(buf + len, PAGE_SIZE-len, | 939 | len += scnprintf(buf + len, PAGE_SIZE-len, |
919 | " Public Loop\n"); | 940 | " Public Loop\n"); |
920 | else | 941 | else |
921 | len += snprintf(buf + len, PAGE_SIZE-len, | 942 | len += scnprintf(buf + len, PAGE_SIZE-len, |
922 | " Private Loop\n"); | 943 | " Private Loop\n"); |
923 | } else { | 944 | } else { |
924 | if (vport->fc_flag & FC_FABRIC) | 945 | if (vport->fc_flag & FC_FABRIC) |
925 | len += snprintf(buf + len, PAGE_SIZE-len, | 946 | len += scnprintf(buf + len, PAGE_SIZE-len, |
926 | " Fabric\n"); | 947 | " Fabric\n"); |
927 | else | 948 | else |
928 | len += snprintf(buf + len, PAGE_SIZE-len, | 949 | len += scnprintf(buf + len, PAGE_SIZE-len, |
929 | " Point-2-Point\n"); | 950 | " Point-2-Point\n"); |
930 | } | 951 | } |
931 | } | 952 | } |
@@ -937,28 +958,28 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr, | |||
937 | struct lpfc_trunk_link link = phba->trunk_link; | 958 | struct lpfc_trunk_link link = phba->trunk_link; |
938 | 959 | ||
939 | if (bf_get(lpfc_conf_trunk_port0, &phba->sli4_hba)) | 960 | if (bf_get(lpfc_conf_trunk_port0, &phba->sli4_hba)) |
940 | len += snprintf(buf + len, PAGE_SIZE - len, | 961 | len += scnprintf(buf + len, PAGE_SIZE - len, |
941 | "Trunk port 0: Link %s %s\n", | 962 | "Trunk port 0: Link %s %s\n", |
942 | (link.link0.state == LPFC_LINK_UP) ? | 963 | (link.link0.state == LPFC_LINK_UP) ? |
943 | "Up" : "Down. ", | 964 | "Up" : "Down. ", |
944 | trunk_errmsg[link.link0.fault]); | 965 | trunk_errmsg[link.link0.fault]); |
945 | 966 | ||
946 | if (bf_get(lpfc_conf_trunk_port1, &phba->sli4_hba)) | 967 | if (bf_get(lpfc_conf_trunk_port1, &phba->sli4_hba)) |
947 | len += snprintf(buf + len, PAGE_SIZE - len, | 968 | len += scnprintf(buf + len, PAGE_SIZE - len, |
948 | "Trunk port 1: Link %s %s\n", | 969 | "Trunk port 1: Link %s %s\n", |
949 | (link.link1.state == LPFC_LINK_UP) ? | 970 | (link.link1.state == LPFC_LINK_UP) ? |
950 | "Up" : "Down. ", | 971 | "Up" : "Down. ", |
951 | trunk_errmsg[link.link1.fault]); | 972 | trunk_errmsg[link.link1.fault]); |
952 | 973 | ||
953 | if (bf_get(lpfc_conf_trunk_port2, &phba->sli4_hba)) | 974 | if (bf_get(lpfc_conf_trunk_port2, &phba->sli4_hba)) |
954 | len += snprintf(buf + len, PAGE_SIZE - len, | 975 | len += scnprintf(buf + len, PAGE_SIZE - len, |
955 | "Trunk port 2: Link %s %s\n", | 976 | "Trunk port 2: Link %s %s\n", |
956 | (link.link2.state == LPFC_LINK_UP) ? | 977 | (link.link2.state == LPFC_LINK_UP) ? |
957 | "Up" : "Down. ", | 978 | "Up" : "Down. ", |
958 | trunk_errmsg[link.link2.fault]); | 979 | trunk_errmsg[link.link2.fault]); |
959 | 980 | ||
960 | if (bf_get(lpfc_conf_trunk_port3, &phba->sli4_hba)) | 981 | if (bf_get(lpfc_conf_trunk_port3, &phba->sli4_hba)) |
961 | len += snprintf(buf + len, PAGE_SIZE - len, | 982 | len += scnprintf(buf + len, PAGE_SIZE - len, |
962 | "Trunk port 3: Link %s %s\n", | 983 | "Trunk port 3: Link %s %s\n", |
963 | (link.link3.state == LPFC_LINK_UP) ? | 984 | (link.link3.state == LPFC_LINK_UP) ? |
964 | "Up" : "Down. ", | 985 | "Up" : "Down. ", |
@@ -986,15 +1007,15 @@ lpfc_sli4_protocol_show(struct device *dev, struct device_attribute *attr, | |||
986 | struct lpfc_hba *phba = vport->phba; | 1007 | struct lpfc_hba *phba = vport->phba; |
987 | 1008 | ||
988 | if (phba->sli_rev < LPFC_SLI_REV4) | 1009 | if (phba->sli_rev < LPFC_SLI_REV4) |
989 | return snprintf(buf, PAGE_SIZE, "fc\n"); | 1010 | return scnprintf(buf, PAGE_SIZE, "fc\n"); |
990 | 1011 | ||
991 | if (phba->sli4_hba.lnk_info.lnk_dv == LPFC_LNK_DAT_VAL) { | 1012 | if (phba->sli4_hba.lnk_info.lnk_dv == LPFC_LNK_DAT_VAL) { |
992 | if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_GE) | 1013 | if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_GE) |
993 | return snprintf(buf, PAGE_SIZE, "fcoe\n"); | 1014 | return scnprintf(buf, PAGE_SIZE, "fcoe\n"); |
994 | if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) | 1015 | if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) |
995 | return snprintf(buf, PAGE_SIZE, "fc\n"); | 1016 | return scnprintf(buf, PAGE_SIZE, "fc\n"); |
996 | } | 1017 | } |
997 | return snprintf(buf, PAGE_SIZE, "unknown\n"); | 1018 | return scnprintf(buf, PAGE_SIZE, "unknown\n"); |
998 | } | 1019 | } |
999 | 1020 | ||
1000 | /** | 1021 | /** |
@@ -1014,7 +1035,7 @@ lpfc_oas_supported_show(struct device *dev, struct device_attribute *attr, | |||
1014 | struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; | 1035 | struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; |
1015 | struct lpfc_hba *phba = vport->phba; | 1036 | struct lpfc_hba *phba = vport->phba; |
1016 | 1037 | ||
1017 | return snprintf(buf, PAGE_SIZE, "%d\n", | 1038 | return scnprintf(buf, PAGE_SIZE, "%d\n", |
1018 | phba->sli4_hba.pc_sli4_params.oas_supported); | 1039 | phba->sli4_hba.pc_sli4_params.oas_supported); |
1019 | } | 1040 | } |
1020 | 1041 | ||
@@ -1072,7 +1093,7 @@ lpfc_num_discovered_ports_show(struct device *dev, | |||
1072 | struct Scsi_Host *shost = class_to_shost(dev); | 1093 | struct Scsi_Host *shost = class_to_shost(dev); |
1073 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 1094 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1074 | 1095 | ||
1075 | return snprintf(buf, PAGE_SIZE, "%d\n", | 1096 | return scnprintf(buf, PAGE_SIZE, "%d\n", |
1076 | vport->fc_map_cnt + vport->fc_unmap_cnt); | 1097 | vport->fc_map_cnt + vport->fc_unmap_cnt); |
1077 | } | 1098 | } |
1078 | 1099 | ||
@@ -1204,6 +1225,20 @@ lpfc_do_offline(struct lpfc_hba *phba, uint32_t type) | |||
1204 | 1225 | ||
1205 | psli = &phba->sli; | 1226 | psli = &phba->sli; |
1206 | 1227 | ||
1228 | /* | ||
1229 | * If freeing the queues have already started, don't access them. | ||
1230 | * Otherwise set FREE_WAIT to indicate that queues are being used | ||
1231 | * to hold the freeing process until we finish. | ||
1232 | */ | ||
1233 | spin_lock_irq(&phba->hbalock); | ||
1234 | if (!(psli->sli_flag & LPFC_QUEUE_FREE_INIT)) { | ||
1235 | psli->sli_flag |= LPFC_QUEUE_FREE_WAIT; | ||
1236 | } else { | ||
1237 | spin_unlock_irq(&phba->hbalock); | ||
1238 | goto skip_wait; | ||
1239 | } | ||
1240 | spin_unlock_irq(&phba->hbalock); | ||
1241 | |||
1207 | /* Wait a little for things to settle down, but not | 1242 | /* Wait a little for things to settle down, but not |
1208 | * long enough for dev loss timeout to expire. | 1243 | * long enough for dev loss timeout to expire. |
1209 | */ | 1244 | */ |
@@ -1225,6 +1260,11 @@ lpfc_do_offline(struct lpfc_hba *phba, uint32_t type) | |||
1225 | } | 1260 | } |
1226 | } | 1261 | } |
1227 | out: | 1262 | out: |
1263 | spin_lock_irq(&phba->hbalock); | ||
1264 | psli->sli_flag &= ~LPFC_QUEUE_FREE_WAIT; | ||
1265 | spin_unlock_irq(&phba->hbalock); | ||
1266 | |||
1267 | skip_wait: | ||
1228 | init_completion(&online_compl); | 1268 | init_completion(&online_compl); |
1229 | rc = lpfc_workq_post_event(phba, &status, &online_compl, type); | 1269 | rc = lpfc_workq_post_event(phba, &status, &online_compl, type); |
1230 | if (rc == 0) | 1270 | if (rc == 0) |
@@ -1258,7 +1298,7 @@ out: | |||
1258 | * -EBUSY, port is not in offline state | 1298 | * -EBUSY, port is not in offline state |
1259 | * 0, successful | 1299 | * 0, successful |
1260 | */ | 1300 | */ |
1261 | int | 1301 | static int |
1262 | lpfc_reset_pci_bus(struct lpfc_hba *phba) | 1302 | lpfc_reset_pci_bus(struct lpfc_hba *phba) |
1263 | { | 1303 | { |
1264 | struct pci_dev *pdev = phba->pcidev; | 1304 | struct pci_dev *pdev = phba->pcidev; |
@@ -1586,10 +1626,10 @@ lpfc_nport_evt_cnt_show(struct device *dev, struct device_attribute *attr, | |||
1586 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 1626 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1587 | struct lpfc_hba *phba = vport->phba; | 1627 | struct lpfc_hba *phba = vport->phba; |
1588 | 1628 | ||
1589 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); | 1629 | return scnprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); |
1590 | } | 1630 | } |
1591 | 1631 | ||
1592 | int | 1632 | static int |
1593 | lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out) | 1633 | lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out) |
1594 | { | 1634 | { |
1595 | LPFC_MBOXQ_t *mbox = NULL; | 1635 | LPFC_MBOXQ_t *mbox = NULL; |
@@ -1675,7 +1715,7 @@ lpfc_board_mode_show(struct device *dev, struct device_attribute *attr, | |||
1675 | else | 1715 | else |
1676 | state = "online"; | 1716 | state = "online"; |
1677 | 1717 | ||
1678 | return snprintf(buf, PAGE_SIZE, "%s\n", state); | 1718 | return scnprintf(buf, PAGE_SIZE, "%s\n", state); |
1679 | } | 1719 | } |
1680 | 1720 | ||
1681 | /** | 1721 | /** |
@@ -1901,8 +1941,8 @@ lpfc_max_rpi_show(struct device *dev, struct device_attribute *attr, | |||
1901 | uint32_t cnt; | 1941 | uint32_t cnt; |
1902 | 1942 | ||
1903 | if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, NULL, NULL, NULL)) | 1943 | if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, NULL, NULL, NULL)) |
1904 | return snprintf(buf, PAGE_SIZE, "%d\n", cnt); | 1944 | return scnprintf(buf, PAGE_SIZE, "%d\n", cnt); |
1905 | return snprintf(buf, PAGE_SIZE, "Unknown\n"); | 1945 | return scnprintf(buf, PAGE_SIZE, "Unknown\n"); |
1906 | } | 1946 | } |
1907 | 1947 | ||
1908 | /** | 1948 | /** |
@@ -1929,8 +1969,8 @@ lpfc_used_rpi_show(struct device *dev, struct device_attribute *attr, | |||
1929 | uint32_t cnt, acnt; | 1969 | uint32_t cnt, acnt; |
1930 | 1970 | ||
1931 | if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, &acnt, NULL, NULL)) | 1971 | if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, &acnt, NULL, NULL)) |
1932 | return snprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt)); | 1972 | return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt)); |
1933 | return snprintf(buf, PAGE_SIZE, "Unknown\n"); | 1973 | return scnprintf(buf, PAGE_SIZE, "Unknown\n"); |
1934 | } | 1974 | } |
1935 | 1975 | ||
1936 | /** | 1976 | /** |
@@ -1957,8 +1997,8 @@ lpfc_max_xri_show(struct device *dev, struct device_attribute *attr, | |||
1957 | uint32_t cnt; | 1997 | uint32_t cnt; |
1958 | 1998 | ||
1959 | if (lpfc_get_hba_info(phba, &cnt, NULL, NULL, NULL, NULL, NULL)) | 1999 | if (lpfc_get_hba_info(phba, &cnt, NULL, NULL, NULL, NULL, NULL)) |
1960 | return snprintf(buf, PAGE_SIZE, "%d\n", cnt); | 2000 | return scnprintf(buf, PAGE_SIZE, "%d\n", cnt); |
1961 | return snprintf(buf, PAGE_SIZE, "Unknown\n"); | 2001 | return scnprintf(buf, PAGE_SIZE, "Unknown\n"); |
1962 | } | 2002 | } |
1963 | 2003 | ||
1964 | /** | 2004 | /** |
@@ -1985,8 +2025,8 @@ lpfc_used_xri_show(struct device *dev, struct device_attribute *attr, | |||
1985 | uint32_t cnt, acnt; | 2025 | uint32_t cnt, acnt; |
1986 | 2026 | ||
1987 | if (lpfc_get_hba_info(phba, &cnt, &acnt, NULL, NULL, NULL, NULL)) | 2027 | if (lpfc_get_hba_info(phba, &cnt, &acnt, NULL, NULL, NULL, NULL)) |
1988 | return snprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt)); | 2028 | return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt)); |
1989 | return snprintf(buf, PAGE_SIZE, "Unknown\n"); | 2029 | return scnprintf(buf, PAGE_SIZE, "Unknown\n"); |
1990 | } | 2030 | } |
1991 | 2031 | ||
1992 | /** | 2032 | /** |
@@ -2013,8 +2053,8 @@ lpfc_max_vpi_show(struct device *dev, struct device_attribute *attr, | |||
2013 | uint32_t cnt; | 2053 | uint32_t cnt; |
2014 | 2054 | ||
2015 | if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, NULL)) | 2055 | if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, NULL)) |
2016 | return snprintf(buf, PAGE_SIZE, "%d\n", cnt); | 2056 | return scnprintf(buf, PAGE_SIZE, "%d\n", cnt); |
2017 | return snprintf(buf, PAGE_SIZE, "Unknown\n"); | 2057 | return scnprintf(buf, PAGE_SIZE, "Unknown\n"); |
2018 | } | 2058 | } |
2019 | 2059 | ||
2020 | /** | 2060 | /** |
@@ -2041,8 +2081,8 @@ lpfc_used_vpi_show(struct device *dev, struct device_attribute *attr, | |||
2041 | uint32_t cnt, acnt; | 2081 | uint32_t cnt, acnt; |
2042 | 2082 | ||
2043 | if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, &acnt)) | 2083 | if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, &acnt)) |
2044 | return snprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt)); | 2084 | return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt)); |
2045 | return snprintf(buf, PAGE_SIZE, "Unknown\n"); | 2085 | return scnprintf(buf, PAGE_SIZE, "Unknown\n"); |
2046 | } | 2086 | } |
2047 | 2087 | ||
2048 | /** | 2088 | /** |
@@ -2067,10 +2107,10 @@ lpfc_npiv_info_show(struct device *dev, struct device_attribute *attr, | |||
2067 | struct lpfc_hba *phba = vport->phba; | 2107 | struct lpfc_hba *phba = vport->phba; |
2068 | 2108 | ||
2069 | if (!(phba->max_vpi)) | 2109 | if (!(phba->max_vpi)) |
2070 | return snprintf(buf, PAGE_SIZE, "NPIV Not Supported\n"); | 2110 | return scnprintf(buf, PAGE_SIZE, "NPIV Not Supported\n"); |
2071 | if (vport->port_type == LPFC_PHYSICAL_PORT) | 2111 | if (vport->port_type == LPFC_PHYSICAL_PORT) |
2072 | return snprintf(buf, PAGE_SIZE, "NPIV Physical\n"); | 2112 | return scnprintf(buf, PAGE_SIZE, "NPIV Physical\n"); |
2073 | return snprintf(buf, PAGE_SIZE, "NPIV Virtual (VPI %d)\n", vport->vpi); | 2113 | return scnprintf(buf, PAGE_SIZE, "NPIV Virtual (VPI %d)\n", vport->vpi); |
2074 | } | 2114 | } |
2075 | 2115 | ||
2076 | /** | 2116 | /** |
@@ -2092,7 +2132,7 @@ lpfc_poll_show(struct device *dev, struct device_attribute *attr, | |||
2092 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 2132 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
2093 | struct lpfc_hba *phba = vport->phba; | 2133 | struct lpfc_hba *phba = vport->phba; |
2094 | 2134 | ||
2095 | return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll); | 2135 | return scnprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll); |
2096 | } | 2136 | } |
2097 | 2137 | ||
2098 | /** | 2138 | /** |
@@ -2196,7 +2236,7 @@ lpfc_fips_level_show(struct device *dev, struct device_attribute *attr, | |||
2196 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 2236 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
2197 | struct lpfc_hba *phba = vport->phba; | 2237 | struct lpfc_hba *phba = vport->phba; |
2198 | 2238 | ||
2199 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->fips_level); | 2239 | return scnprintf(buf, PAGE_SIZE, "%d\n", phba->fips_level); |
2200 | } | 2240 | } |
2201 | 2241 | ||
2202 | /** | 2242 | /** |
@@ -2215,7 +2255,7 @@ lpfc_fips_rev_show(struct device *dev, struct device_attribute *attr, | |||
2215 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 2255 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
2216 | struct lpfc_hba *phba = vport->phba; | 2256 | struct lpfc_hba *phba = vport->phba; |
2217 | 2257 | ||
2218 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->fips_spec_rev); | 2258 | return scnprintf(buf, PAGE_SIZE, "%d\n", phba->fips_spec_rev); |
2219 | } | 2259 | } |
2220 | 2260 | ||
2221 | /** | 2261 | /** |
@@ -2234,7 +2274,7 @@ lpfc_dss_show(struct device *dev, struct device_attribute *attr, | |||
2234 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 2274 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
2235 | struct lpfc_hba *phba = vport->phba; | 2275 | struct lpfc_hba *phba = vport->phba; |
2236 | 2276 | ||
2237 | return snprintf(buf, PAGE_SIZE, "%s - %sOperational\n", | 2277 | return scnprintf(buf, PAGE_SIZE, "%s - %sOperational\n", |
2238 | (phba->cfg_enable_dss) ? "Enabled" : "Disabled", | 2278 | (phba->cfg_enable_dss) ? "Enabled" : "Disabled", |
2239 | (phba->sli3_options & LPFC_SLI3_DSS_ENABLED) ? | 2279 | (phba->sli3_options & LPFC_SLI3_DSS_ENABLED) ? |
2240 | "" : "Not "); | 2280 | "" : "Not "); |
@@ -2263,7 +2303,7 @@ lpfc_sriov_hw_max_virtfn_show(struct device *dev, | |||
2263 | uint16_t max_nr_virtfn; | 2303 | uint16_t max_nr_virtfn; |
2264 | 2304 | ||
2265 | max_nr_virtfn = lpfc_sli_sriov_nr_virtfn_get(phba); | 2305 | max_nr_virtfn = lpfc_sli_sriov_nr_virtfn_get(phba); |
2266 | return snprintf(buf, PAGE_SIZE, "%d\n", max_nr_virtfn); | 2306 | return scnprintf(buf, PAGE_SIZE, "%d\n", max_nr_virtfn); |
2267 | } | 2307 | } |
2268 | 2308 | ||
2269 | static inline bool lpfc_rangecheck(uint val, uint min, uint max) | 2309 | static inline bool lpfc_rangecheck(uint val, uint min, uint max) |
@@ -2323,7 +2363,7 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ | |||
2323 | struct Scsi_Host *shost = class_to_shost(dev);\ | 2363 | struct Scsi_Host *shost = class_to_shost(dev);\ |
2324 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ | 2364 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ |
2325 | struct lpfc_hba *phba = vport->phba;\ | 2365 | struct lpfc_hba *phba = vport->phba;\ |
2326 | return snprintf(buf, PAGE_SIZE, "%d\n",\ | 2366 | return scnprintf(buf, PAGE_SIZE, "%d\n",\ |
2327 | phba->cfg_##attr);\ | 2367 | phba->cfg_##attr);\ |
2328 | } | 2368 | } |
2329 | 2369 | ||
@@ -2351,7 +2391,7 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ | |||
2351 | struct lpfc_hba *phba = vport->phba;\ | 2391 | struct lpfc_hba *phba = vport->phba;\ |
2352 | uint val = 0;\ | 2392 | uint val = 0;\ |
2353 | val = phba->cfg_##attr;\ | 2393 | val = phba->cfg_##attr;\ |
2354 | return snprintf(buf, PAGE_SIZE, "%#x\n",\ | 2394 | return scnprintf(buf, PAGE_SIZE, "%#x\n",\ |
2355 | phba->cfg_##attr);\ | 2395 | phba->cfg_##attr);\ |
2356 | } | 2396 | } |
2357 | 2397 | ||
@@ -2487,7 +2527,7 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ | |||
2487 | { \ | 2527 | { \ |
2488 | struct Scsi_Host *shost = class_to_shost(dev);\ | 2528 | struct Scsi_Host *shost = class_to_shost(dev);\ |
2489 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ | 2529 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ |
2490 | return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\ | 2530 | return scnprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\ |
2491 | } | 2531 | } |
2492 | 2532 | ||
2493 | /** | 2533 | /** |
@@ -2512,7 +2552,7 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ | |||
2512 | { \ | 2552 | { \ |
2513 | struct Scsi_Host *shost = class_to_shost(dev);\ | 2553 | struct Scsi_Host *shost = class_to_shost(dev);\ |
2514 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ | 2554 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ |
2515 | return snprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\ | 2555 | return scnprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\ |
2516 | } | 2556 | } |
2517 | 2557 | ||
2518 | /** | 2558 | /** |
@@ -2784,7 +2824,7 @@ lpfc_soft_wwpn_show(struct device *dev, struct device_attribute *attr, | |||
2784 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 2824 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
2785 | struct lpfc_hba *phba = vport->phba; | 2825 | struct lpfc_hba *phba = vport->phba; |
2786 | 2826 | ||
2787 | return snprintf(buf, PAGE_SIZE, "0x%llx\n", | 2827 | return scnprintf(buf, PAGE_SIZE, "0x%llx\n", |
2788 | (unsigned long long)phba->cfg_soft_wwpn); | 2828 | (unsigned long long)phba->cfg_soft_wwpn); |
2789 | } | 2829 | } |
2790 | 2830 | ||
@@ -2881,7 +2921,7 @@ lpfc_soft_wwnn_show(struct device *dev, struct device_attribute *attr, | |||
2881 | { | 2921 | { |
2882 | struct Scsi_Host *shost = class_to_shost(dev); | 2922 | struct Scsi_Host *shost = class_to_shost(dev); |
2883 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 2923 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
2884 | return snprintf(buf, PAGE_SIZE, "0x%llx\n", | 2924 | return scnprintf(buf, PAGE_SIZE, "0x%llx\n", |
2885 | (unsigned long long)phba->cfg_soft_wwnn); | 2925 | (unsigned long long)phba->cfg_soft_wwnn); |
2886 | } | 2926 | } |
2887 | 2927 | ||
@@ -2947,7 +2987,7 @@ lpfc_oas_tgt_show(struct device *dev, struct device_attribute *attr, | |||
2947 | struct Scsi_Host *shost = class_to_shost(dev); | 2987 | struct Scsi_Host *shost = class_to_shost(dev); |
2948 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 2988 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
2949 | 2989 | ||
2950 | return snprintf(buf, PAGE_SIZE, "0x%llx\n", | 2990 | return scnprintf(buf, PAGE_SIZE, "0x%llx\n", |
2951 | wwn_to_u64(phba->cfg_oas_tgt_wwpn)); | 2991 | wwn_to_u64(phba->cfg_oas_tgt_wwpn)); |
2952 | } | 2992 | } |
2953 | 2993 | ||
@@ -3015,7 +3055,7 @@ lpfc_oas_priority_show(struct device *dev, struct device_attribute *attr, | |||
3015 | struct Scsi_Host *shost = class_to_shost(dev); | 3055 | struct Scsi_Host *shost = class_to_shost(dev); |
3016 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 3056 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
3017 | 3057 | ||
3018 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_priority); | 3058 | return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_priority); |
3019 | } | 3059 | } |
3020 | 3060 | ||
3021 | /** | 3061 | /** |
@@ -3078,7 +3118,7 @@ lpfc_oas_vpt_show(struct device *dev, struct device_attribute *attr, | |||
3078 | struct Scsi_Host *shost = class_to_shost(dev); | 3118 | struct Scsi_Host *shost = class_to_shost(dev); |
3079 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 3119 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
3080 | 3120 | ||
3081 | return snprintf(buf, PAGE_SIZE, "0x%llx\n", | 3121 | return scnprintf(buf, PAGE_SIZE, "0x%llx\n", |
3082 | wwn_to_u64(phba->cfg_oas_vpt_wwpn)); | 3122 | wwn_to_u64(phba->cfg_oas_vpt_wwpn)); |
3083 | } | 3123 | } |
3084 | 3124 | ||
@@ -3149,7 +3189,7 @@ lpfc_oas_lun_state_show(struct device *dev, struct device_attribute *attr, | |||
3149 | struct Scsi_Host *shost = class_to_shost(dev); | 3189 | struct Scsi_Host *shost = class_to_shost(dev); |
3150 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 3190 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
3151 | 3191 | ||
3152 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_lun_state); | 3192 | return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_lun_state); |
3153 | } | 3193 | } |
3154 | 3194 | ||
3155 | /** | 3195 | /** |
@@ -3213,7 +3253,7 @@ lpfc_oas_lun_status_show(struct device *dev, struct device_attribute *attr, | |||
3213 | if (!(phba->cfg_oas_flags & OAS_LUN_VALID)) | 3253 | if (!(phba->cfg_oas_flags & OAS_LUN_VALID)) |
3214 | return -EFAULT; | 3254 | return -EFAULT; |
3215 | 3255 | ||
3216 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_lun_status); | 3256 | return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_lun_status); |
3217 | } | 3257 | } |
3218 | static DEVICE_ATTR(lpfc_xlane_lun_status, S_IRUGO, | 3258 | static DEVICE_ATTR(lpfc_xlane_lun_status, S_IRUGO, |
3219 | lpfc_oas_lun_status_show, NULL); | 3259 | lpfc_oas_lun_status_show, NULL); |
@@ -3365,7 +3405,7 @@ lpfc_oas_lun_show(struct device *dev, struct device_attribute *attr, | |||
3365 | if (oas_lun != NOT_OAS_ENABLED_LUN) | 3405 | if (oas_lun != NOT_OAS_ENABLED_LUN) |
3366 | phba->cfg_oas_flags |= OAS_LUN_VALID; | 3406 | phba->cfg_oas_flags |= OAS_LUN_VALID; |
3367 | 3407 | ||
3368 | len += snprintf(buf + len, PAGE_SIZE-len, "0x%llx", oas_lun); | 3408 | len += scnprintf(buf + len, PAGE_SIZE-len, "0x%llx", oas_lun); |
3369 | 3409 | ||
3370 | return len; | 3410 | return len; |
3371 | } | 3411 | } |
@@ -3499,7 +3539,7 @@ lpfc_iocb_hw_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
3499 | struct Scsi_Host *shost = class_to_shost(dev); | 3539 | struct Scsi_Host *shost = class_to_shost(dev); |
3500 | struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba; | 3540 | struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba; |
3501 | 3541 | ||
3502 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->iocb_max); | 3542 | return scnprintf(buf, PAGE_SIZE, "%d\n", phba->iocb_max); |
3503 | } | 3543 | } |
3504 | 3544 | ||
3505 | static DEVICE_ATTR(iocb_hw, S_IRUGO, | 3545 | static DEVICE_ATTR(iocb_hw, S_IRUGO, |
@@ -3511,7 +3551,7 @@ lpfc_txq_hw_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
3511 | struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba; | 3551 | struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba; |
3512 | struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba); | 3552 | struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba); |
3513 | 3553 | ||
3514 | return snprintf(buf, PAGE_SIZE, "%d\n", | 3554 | return scnprintf(buf, PAGE_SIZE, "%d\n", |
3515 | pring ? pring->txq_max : 0); | 3555 | pring ? pring->txq_max : 0); |
3516 | } | 3556 | } |
3517 | 3557 | ||
@@ -3525,7 +3565,7 @@ lpfc_txcmplq_hw_show(struct device *dev, struct device_attribute *attr, | |||
3525 | struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba; | 3565 | struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba; |
3526 | struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba); | 3566 | struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba); |
3527 | 3567 | ||
3528 | return snprintf(buf, PAGE_SIZE, "%d\n", | 3568 | return scnprintf(buf, PAGE_SIZE, "%d\n", |
3529 | pring ? pring->txcmplq_max : 0); | 3569 | pring ? pring->txcmplq_max : 0); |
3530 | } | 3570 | } |
3531 | 3571 | ||
@@ -3561,7 +3601,7 @@ lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr, | |||
3561 | struct Scsi_Host *shost = class_to_shost(dev); | 3601 | struct Scsi_Host *shost = class_to_shost(dev); |
3562 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 3602 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
3563 | 3603 | ||
3564 | return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo); | 3604 | return scnprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo); |
3565 | } | 3605 | } |
3566 | 3606 | ||
3567 | /** | 3607 | /** |
@@ -4050,9 +4090,9 @@ lpfc_topology_store(struct device *dev, struct device_attribute *attr, | |||
4050 | } | 4090 | } |
4051 | if ((phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC || | 4091 | if ((phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC || |
4052 | phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC) && | 4092 | phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC) && |
4053 | val == 4) { | 4093 | val != FLAGS_TOPOLOGY_MODE_PT_PT) { |
4054 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | 4094 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, |
4055 | "3114 Loop mode not supported\n"); | 4095 | "3114 Only non-FC-AL mode is supported\n"); |
4056 | return -EINVAL; | 4096 | return -EINVAL; |
4057 | } | 4097 | } |
4058 | phba->cfg_topology = val; | 4098 | phba->cfg_topology = val; |
@@ -5169,12 +5209,12 @@ lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr, | |||
5169 | 5209 | ||
5170 | switch (phba->cfg_fcp_cpu_map) { | 5210 | switch (phba->cfg_fcp_cpu_map) { |
5171 | case 0: | 5211 | case 0: |
5172 | len += snprintf(buf + len, PAGE_SIZE-len, | 5212 | len += scnprintf(buf + len, PAGE_SIZE-len, |
5173 | "fcp_cpu_map: No mapping (%d)\n", | 5213 | "fcp_cpu_map: No mapping (%d)\n", |
5174 | phba->cfg_fcp_cpu_map); | 5214 | phba->cfg_fcp_cpu_map); |
5175 | return len; | 5215 | return len; |
5176 | case 1: | 5216 | case 1: |
5177 | len += snprintf(buf + len, PAGE_SIZE-len, | 5217 | len += scnprintf(buf + len, PAGE_SIZE-len, |
5178 | "fcp_cpu_map: HBA centric mapping (%d): " | 5218 | "fcp_cpu_map: HBA centric mapping (%d): " |
5179 | "%d of %d CPUs online from %d possible CPUs\n", | 5219 | "%d of %d CPUs online from %d possible CPUs\n", |
5180 | phba->cfg_fcp_cpu_map, num_online_cpus(), | 5220 | phba->cfg_fcp_cpu_map, num_online_cpus(), |
@@ -5188,12 +5228,12 @@ lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr, | |||
5188 | cpup = &phba->sli4_hba.cpu_map[phba->sli4_hba.curr_disp_cpu]; | 5228 | cpup = &phba->sli4_hba.cpu_map[phba->sli4_hba.curr_disp_cpu]; |
5189 | 5229 | ||
5190 | if (!cpu_present(phba->sli4_hba.curr_disp_cpu)) | 5230 | if (!cpu_present(phba->sli4_hba.curr_disp_cpu)) |
5191 | len += snprintf(buf + len, PAGE_SIZE - len, | 5231 | len += scnprintf(buf + len, PAGE_SIZE - len, |
5192 | "CPU %02d not present\n", | 5232 | "CPU %02d not present\n", |
5193 | phba->sli4_hba.curr_disp_cpu); | 5233 | phba->sli4_hba.curr_disp_cpu); |
5194 | else if (cpup->irq == LPFC_VECTOR_MAP_EMPTY) { | 5234 | else if (cpup->irq == LPFC_VECTOR_MAP_EMPTY) { |
5195 | if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY) | 5235 | if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY) |
5196 | len += snprintf( | 5236 | len += scnprintf( |
5197 | buf + len, PAGE_SIZE - len, | 5237 | buf + len, PAGE_SIZE - len, |
5198 | "CPU %02d hdwq None " | 5238 | "CPU %02d hdwq None " |
5199 | "physid %d coreid %d ht %d\n", | 5239 | "physid %d coreid %d ht %d\n", |
@@ -5201,7 +5241,7 @@ lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr, | |||
5201 | cpup->phys_id, | 5241 | cpup->phys_id, |
5202 | cpup->core_id, cpup->hyper); | 5242 | cpup->core_id, cpup->hyper); |
5203 | else | 5243 | else |
5204 | len += snprintf( | 5244 | len += scnprintf( |
5205 | buf + len, PAGE_SIZE - len, | 5245 | buf + len, PAGE_SIZE - len, |
5206 | "CPU %02d EQ %04d hdwq %04d " | 5246 | "CPU %02d EQ %04d hdwq %04d " |
5207 | "physid %d coreid %d ht %d\n", | 5247 | "physid %d coreid %d ht %d\n", |
@@ -5210,7 +5250,7 @@ lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr, | |||
5210 | cpup->core_id, cpup->hyper); | 5250 | cpup->core_id, cpup->hyper); |
5211 | } else { | 5251 | } else { |
5212 | if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY) | 5252 | if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY) |
5213 | len += snprintf( | 5253 | len += scnprintf( |
5214 | buf + len, PAGE_SIZE - len, | 5254 | buf + len, PAGE_SIZE - len, |
5215 | "CPU %02d hdwq None " | 5255 | "CPU %02d hdwq None " |
5216 | "physid %d coreid %d ht %d IRQ %d\n", | 5256 | "physid %d coreid %d ht %d IRQ %d\n", |
@@ -5218,7 +5258,7 @@ lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr, | |||
5218 | cpup->phys_id, | 5258 | cpup->phys_id, |
5219 | cpup->core_id, cpup->hyper, cpup->irq); | 5259 | cpup->core_id, cpup->hyper, cpup->irq); |
5220 | else | 5260 | else |
5221 | len += snprintf( | 5261 | len += scnprintf( |
5222 | buf + len, PAGE_SIZE - len, | 5262 | buf + len, PAGE_SIZE - len, |
5223 | "CPU %02d EQ %04d hdwq %04d " | 5263 | "CPU %02d EQ %04d hdwq %04d " |
5224 | "physid %d coreid %d ht %d IRQ %d\n", | 5264 | "physid %d coreid %d ht %d IRQ %d\n", |
@@ -5233,7 +5273,7 @@ lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr, | |||
5233 | if (phba->sli4_hba.curr_disp_cpu < | 5273 | if (phba->sli4_hba.curr_disp_cpu < |
5234 | phba->sli4_hba.num_possible_cpu && | 5274 | phba->sli4_hba.num_possible_cpu && |
5235 | (len >= (PAGE_SIZE - 64))) { | 5275 | (len >= (PAGE_SIZE - 64))) { |
5236 | len += snprintf(buf + len, | 5276 | len += scnprintf(buf + len, |
5237 | PAGE_SIZE - len, "more...\n"); | 5277 | PAGE_SIZE - len, "more...\n"); |
5238 | break; | 5278 | break; |
5239 | } | 5279 | } |
@@ -5753,10 +5793,10 @@ lpfc_sg_seg_cnt_show(struct device *dev, struct device_attribute *attr, | |||
5753 | struct lpfc_hba *phba = vport->phba; | 5793 | struct lpfc_hba *phba = vport->phba; |
5754 | int len; | 5794 | int len; |
5755 | 5795 | ||
5756 | len = snprintf(buf, PAGE_SIZE, "SGL sz: %d total SGEs: %d\n", | 5796 | len = scnprintf(buf, PAGE_SIZE, "SGL sz: %d total SGEs: %d\n", |
5757 | phba->cfg_sg_dma_buf_size, phba->cfg_total_seg_cnt); | 5797 | phba->cfg_sg_dma_buf_size, phba->cfg_total_seg_cnt); |
5758 | 5798 | ||
5759 | len += snprintf(buf + len, PAGE_SIZE, "Cfg: %d SCSI: %d NVME: %d\n", | 5799 | len += scnprintf(buf + len, PAGE_SIZE, "Cfg: %d SCSI: %d NVME: %d\n", |
5760 | phba->cfg_sg_seg_cnt, phba->cfg_scsi_seg_cnt, | 5800 | phba->cfg_sg_seg_cnt, phba->cfg_scsi_seg_cnt, |
5761 | phba->cfg_nvme_seg_cnt); | 5801 | phba->cfg_nvme_seg_cnt); |
5762 | return len; | 5802 | return len; |
@@ -6755,7 +6795,7 @@ lpfc_show_rport_##field (struct device *dev, \ | |||
6755 | { \ | 6795 | { \ |
6756 | struct fc_rport *rport = transport_class_to_rport(dev); \ | 6796 | struct fc_rport *rport = transport_class_to_rport(dev); \ |
6757 | struct lpfc_rport_data *rdata = rport->hostdata; \ | 6797 | struct lpfc_rport_data *rdata = rport->hostdata; \ |
6758 | return snprintf(buf, sz, format_string, \ | 6798 | return scnprintf(buf, sz, format_string, \ |
6759 | (rdata->target) ? cast rdata->target->field : 0); \ | 6799 | (rdata->target) ? cast rdata->target->field : 0); \ |
6760 | } | 6800 | } |
6761 | 6801 | ||
@@ -7003,6 +7043,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
7003 | if (phba->sli_rev != LPFC_SLI_REV4) { | 7043 | if (phba->sli_rev != LPFC_SLI_REV4) { |
7004 | /* NVME only supported on SLI4 */ | 7044 | /* NVME only supported on SLI4 */ |
7005 | phba->nvmet_support = 0; | 7045 | phba->nvmet_support = 0; |
7046 | phba->cfg_nvmet_mrq = 0; | ||
7006 | phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP; | 7047 | phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP; |
7007 | phba->cfg_enable_bbcr = 0; | 7048 | phba->cfg_enable_bbcr = 0; |
7008 | phba->cfg_xri_rebalancing = 0; | 7049 | phba->cfg_xri_rebalancing = 0; |
@@ -7104,7 +7145,7 @@ lpfc_nvme_mod_param_dep(struct lpfc_hba *phba) | |||
7104 | } else { | 7145 | } else { |
7105 | /* Not NVME Target mode. Turn off Target parameters. */ | 7146 | /* Not NVME Target mode. Turn off Target parameters. */ |
7106 | phba->nvmet_support = 0; | 7147 | phba->nvmet_support = 0; |
7107 | phba->cfg_nvmet_mrq = LPFC_NVMET_MRQ_OFF; | 7148 | phba->cfg_nvmet_mrq = 0; |
7108 | phba->cfg_nvmet_fb_size = 0; | 7149 | phba->cfg_nvmet_fb_size = 0; |
7109 | } | 7150 | } |
7110 | } | 7151 | } |
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index f2494d3b365c..b0202bc0aa62 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * |
5 | * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * |
6 | * Copyright (C) 2009-2015 Emulex. All rights reserved. * | 6 | * Copyright (C) 2009-2015 Emulex. All rights reserved. * |
7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
@@ -1968,14 +1968,17 @@ link_diag_state_set_out: | |||
1968 | } | 1968 | } |
1969 | 1969 | ||
1970 | /** | 1970 | /** |
1971 | * lpfc_sli4_bsg_set_internal_loopback - set sli4 internal loopback diagnostic | 1971 | * lpfc_sli4_bsg_set_loopback_mode - set sli4 internal loopback diagnostic |
1972 | * @phba: Pointer to HBA context object. | 1972 | * @phba: Pointer to HBA context object. |
1973 | * @mode: loopback mode to set | ||
1974 | * @link_no: link number for loopback mode to set | ||
1973 | * | 1975 | * |
1974 | * This function is responsible for issuing a sli4 mailbox command for setting | 1976 | * This function is responsible for issuing a sli4 mailbox command for setting |
1975 | * up internal loopback diagnostic. | 1977 | * up loopback diagnostic for a link. |
1976 | */ | 1978 | */ |
1977 | static int | 1979 | static int |
1978 | lpfc_sli4_bsg_set_internal_loopback(struct lpfc_hba *phba) | 1980 | lpfc_sli4_bsg_set_loopback_mode(struct lpfc_hba *phba, int mode, |
1981 | uint32_t link_no) | ||
1979 | { | 1982 | { |
1980 | LPFC_MBOXQ_t *pmboxq; | 1983 | LPFC_MBOXQ_t *pmboxq; |
1981 | uint32_t req_len, alloc_len; | 1984 | uint32_t req_len, alloc_len; |
@@ -1996,11 +1999,19 @@ lpfc_sli4_bsg_set_internal_loopback(struct lpfc_hba *phba) | |||
1996 | } | 1999 | } |
1997 | link_diag_loopback = &pmboxq->u.mqe.un.link_diag_loopback; | 2000 | link_diag_loopback = &pmboxq->u.mqe.un.link_diag_loopback; |
1998 | bf_set(lpfc_mbx_set_diag_state_link_num, | 2001 | bf_set(lpfc_mbx_set_diag_state_link_num, |
1999 | &link_diag_loopback->u.req, phba->sli4_hba.lnk_info.lnk_no); | 2002 | &link_diag_loopback->u.req, link_no); |
2000 | bf_set(lpfc_mbx_set_diag_state_link_type, | 2003 | |
2001 | &link_diag_loopback->u.req, phba->sli4_hba.lnk_info.lnk_tp); | 2004 | if (phba->sli4_hba.conf_trunk & (1 << link_no)) { |
2005 | bf_set(lpfc_mbx_set_diag_state_link_type, | ||
2006 | &link_diag_loopback->u.req, LPFC_LNK_FC_TRUNKED); | ||
2007 | } else { | ||
2008 | bf_set(lpfc_mbx_set_diag_state_link_type, | ||
2009 | &link_diag_loopback->u.req, | ||
2010 | phba->sli4_hba.lnk_info.lnk_tp); | ||
2011 | } | ||
2012 | |||
2002 | bf_set(lpfc_mbx_set_diag_lpbk_type, &link_diag_loopback->u.req, | 2013 | bf_set(lpfc_mbx_set_diag_lpbk_type, &link_diag_loopback->u.req, |
2003 | LPFC_DIAG_LOOPBACK_TYPE_INTERNAL); | 2014 | mode); |
2004 | 2015 | ||
2005 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO); | 2016 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO); |
2006 | if ((mbxstatus != MBX_SUCCESS) || (pmboxq->u.mb.mbxStatus)) { | 2017 | if ((mbxstatus != MBX_SUCCESS) || (pmboxq->u.mb.mbxStatus)) { |
@@ -2054,7 +2065,7 @@ lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct bsg_job *job) | |||
2054 | struct fc_bsg_request *bsg_request = job->request; | 2065 | struct fc_bsg_request *bsg_request = job->request; |
2055 | struct fc_bsg_reply *bsg_reply = job->reply; | 2066 | struct fc_bsg_reply *bsg_reply = job->reply; |
2056 | struct diag_mode_set *loopback_mode; | 2067 | struct diag_mode_set *loopback_mode; |
2057 | uint32_t link_flags, timeout; | 2068 | uint32_t link_flags, timeout, link_no; |
2058 | int i, rc = 0; | 2069 | int i, rc = 0; |
2059 | 2070 | ||
2060 | /* no data to return just the return code */ | 2071 | /* no data to return just the return code */ |
@@ -2069,12 +2080,39 @@ lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct bsg_job *job) | |||
2069 | (int)(sizeof(struct fc_bsg_request) + | 2080 | (int)(sizeof(struct fc_bsg_request) + |
2070 | sizeof(struct diag_mode_set))); | 2081 | sizeof(struct diag_mode_set))); |
2071 | rc = -EINVAL; | 2082 | rc = -EINVAL; |
2072 | goto job_error; | 2083 | goto job_done; |
2084 | } | ||
2085 | |||
2086 | loopback_mode = (struct diag_mode_set *) | ||
2087 | bsg_request->rqst_data.h_vendor.vendor_cmd; | ||
2088 | link_flags = loopback_mode->type; | ||
2089 | timeout = loopback_mode->timeout * 100; | ||
2090 | |||
2091 | if (loopback_mode->physical_link == -1) | ||
2092 | link_no = phba->sli4_hba.lnk_info.lnk_no; | ||
2093 | else | ||
2094 | link_no = loopback_mode->physical_link; | ||
2095 | |||
2096 | if (link_flags == DISABLE_LOOP_BACK) { | ||
2097 | rc = lpfc_sli4_bsg_set_loopback_mode(phba, | ||
2098 | LPFC_DIAG_LOOPBACK_TYPE_DISABLE, | ||
2099 | link_no); | ||
2100 | if (!rc) { | ||
2101 | /* Unset the need disable bit */ | ||
2102 | phba->sli4_hba.conf_trunk &= ~((1 << link_no) << 4); | ||
2103 | } | ||
2104 | goto job_done; | ||
2105 | } else { | ||
2106 | /* Check if we need to disable the loopback state */ | ||
2107 | if (phba->sli4_hba.conf_trunk & ((1 << link_no) << 4)) { | ||
2108 | rc = -EPERM; | ||
2109 | goto job_done; | ||
2110 | } | ||
2073 | } | 2111 | } |
2074 | 2112 | ||
2075 | rc = lpfc_bsg_diag_mode_enter(phba); | 2113 | rc = lpfc_bsg_diag_mode_enter(phba); |
2076 | if (rc) | 2114 | if (rc) |
2077 | goto job_error; | 2115 | goto job_done; |
2078 | 2116 | ||
2079 | /* indicate we are in loobpack diagnostic mode */ | 2117 | /* indicate we are in loobpack diagnostic mode */ |
2080 | spin_lock_irq(&phba->hbalock); | 2118 | spin_lock_irq(&phba->hbalock); |
@@ -2084,15 +2122,11 @@ lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct bsg_job *job) | |||
2084 | /* reset port to start frome scratch */ | 2122 | /* reset port to start frome scratch */ |
2085 | rc = lpfc_selective_reset(phba); | 2123 | rc = lpfc_selective_reset(phba); |
2086 | if (rc) | 2124 | if (rc) |
2087 | goto job_error; | 2125 | goto job_done; |
2088 | 2126 | ||
2089 | /* bring the link to diagnostic mode */ | 2127 | /* bring the link to diagnostic mode */ |
2090 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | 2128 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, |
2091 | "3129 Bring link to diagnostic state.\n"); | 2129 | "3129 Bring link to diagnostic state.\n"); |
2092 | loopback_mode = (struct diag_mode_set *) | ||
2093 | bsg_request->rqst_data.h_vendor.vendor_cmd; | ||
2094 | link_flags = loopback_mode->type; | ||
2095 | timeout = loopback_mode->timeout * 100; | ||
2096 | 2130 | ||
2097 | rc = lpfc_sli4_bsg_set_link_diag_state(phba, 1); | 2131 | rc = lpfc_sli4_bsg_set_link_diag_state(phba, 1); |
2098 | if (rc) { | 2132 | if (rc) { |
@@ -2120,13 +2154,54 @@ lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct bsg_job *job) | |||
2120 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, | 2154 | lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, |
2121 | "3132 Set up loopback mode:x%x\n", link_flags); | 2155 | "3132 Set up loopback mode:x%x\n", link_flags); |
2122 | 2156 | ||
2123 | if (link_flags == INTERNAL_LOOP_BACK) | 2157 | switch (link_flags) { |
2124 | rc = lpfc_sli4_bsg_set_internal_loopback(phba); | 2158 | case INTERNAL_LOOP_BACK: |
2125 | else if (link_flags == EXTERNAL_LOOP_BACK) | 2159 | if (phba->sli4_hba.conf_trunk & (1 << link_no)) { |
2126 | rc = lpfc_hba_init_link_fc_topology(phba, | 2160 | rc = lpfc_sli4_bsg_set_loopback_mode(phba, |
2127 | FLAGS_TOPOLOGY_MODE_PT_PT, | 2161 | LPFC_DIAG_LOOPBACK_TYPE_INTERNAL, |
2128 | MBX_NOWAIT); | 2162 | link_no); |
2129 | else { | 2163 | } else { |
2164 | /* Trunk is configured, but link is not in this trunk */ | ||
2165 | if (phba->sli4_hba.conf_trunk) { | ||
2166 | rc = -ELNRNG; | ||
2167 | goto loopback_mode_exit; | ||
2168 | } | ||
2169 | |||
2170 | rc = lpfc_sli4_bsg_set_loopback_mode(phba, | ||
2171 | LPFC_DIAG_LOOPBACK_TYPE_INTERNAL, | ||
2172 | link_no); | ||
2173 | } | ||
2174 | |||
2175 | if (!rc) { | ||
2176 | /* Set the need disable bit */ | ||
2177 | phba->sli4_hba.conf_trunk |= (1 << link_no) << 4; | ||
2178 | } | ||
2179 | |||
2180 | break; | ||
2181 | case EXTERNAL_LOOP_BACK: | ||
2182 | if (phba->sli4_hba.conf_trunk & (1 << link_no)) { | ||
2183 | rc = lpfc_sli4_bsg_set_loopback_mode(phba, | ||
2184 | LPFC_DIAG_LOOPBACK_TYPE_EXTERNAL_TRUNKED, | ||
2185 | link_no); | ||
2186 | } else { | ||
2187 | /* Trunk is configured, but link is not in this trunk */ | ||
2188 | if (phba->sli4_hba.conf_trunk) { | ||
2189 | rc = -ELNRNG; | ||
2190 | goto loopback_mode_exit; | ||
2191 | } | ||
2192 | |||
2193 | rc = lpfc_sli4_bsg_set_loopback_mode(phba, | ||
2194 | LPFC_DIAG_LOOPBACK_TYPE_SERDES, | ||
2195 | link_no); | ||
2196 | } | ||
2197 | |||
2198 | if (!rc) { | ||
2199 | /* Set the need disable bit */ | ||
2200 | phba->sli4_hba.conf_trunk |= (1 << link_no) << 4; | ||
2201 | } | ||
2202 | |||
2203 | break; | ||
2204 | default: | ||
2130 | rc = -EINVAL; | 2205 | rc = -EINVAL; |
2131 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | 2206 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, |
2132 | "3141 Loopback mode:x%x not supported\n", | 2207 | "3141 Loopback mode:x%x not supported\n", |
@@ -2185,7 +2260,7 @@ loopback_mode_exit: | |||
2185 | } | 2260 | } |
2186 | lpfc_bsg_diag_mode_exit(phba); | 2261 | lpfc_bsg_diag_mode_exit(phba); |
2187 | 2262 | ||
2188 | job_error: | 2263 | job_done: |
2189 | /* make error code available to userspace */ | 2264 | /* make error code available to userspace */ |
2190 | bsg_reply->result = rc; | 2265 | bsg_reply->result = rc; |
2191 | /* complete the job back to userspace if no error */ | 2266 | /* complete the job back to userspace if no error */ |
diff --git a/drivers/scsi/lpfc/lpfc_bsg.h b/drivers/scsi/lpfc/lpfc_bsg.h index 9151824beea4..d1708133fd54 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.h +++ b/drivers/scsi/lpfc/lpfc_bsg.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * |
5 | * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * |
6 | * Copyright (C) 2010-2015 Emulex. All rights reserved. * | 6 | * Copyright (C) 2010-2015 Emulex. All rights reserved. * |
7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
@@ -68,6 +68,7 @@ struct send_mgmt_resp { | |||
68 | }; | 68 | }; |
69 | 69 | ||
70 | 70 | ||
71 | #define DISABLE_LOOP_BACK 0x0 /* disables loop back */ | ||
71 | #define INTERNAL_LOOP_BACK 0x1 /* adapter short cuts the loop internally */ | 72 | #define INTERNAL_LOOP_BACK 0x1 /* adapter short cuts the loop internally */ |
72 | #define EXTERNAL_LOOP_BACK 0x2 /* requires an external loopback plug */ | 73 | #define EXTERNAL_LOOP_BACK 0x2 /* requires an external loopback plug */ |
73 | 74 | ||
@@ -75,6 +76,7 @@ struct diag_mode_set { | |||
75 | uint32_t command; | 76 | uint32_t command; |
76 | uint32_t type; | 77 | uint32_t type; |
77 | uint32_t timeout; | 78 | uint32_t timeout; |
79 | uint32_t physical_link; | ||
78 | }; | 80 | }; |
79 | 81 | ||
80 | struct sli4_link_diag { | 82 | struct sli4_link_diag { |
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 44f426347d4f..4812bbbf43cc 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -886,7 +886,7 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
886 | } | 886 | } |
887 | if (lpfc_error_lost_link(irsp)) { | 887 | if (lpfc_error_lost_link(irsp)) { |
888 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 888 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
889 | "4101 NS query failed due to link event\n"); | 889 | "4166 NS query failed due to link event\n"); |
890 | if (vport->fc_flag & FC_RSCN_MODE) | 890 | if (vport->fc_flag & FC_RSCN_MODE) |
891 | lpfc_els_flush_rscn(vport); | 891 | lpfc_els_flush_rscn(vport); |
892 | goto out; | 892 | goto out; |
@@ -907,7 +907,7 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
907 | * Re-issue the NS cmd | 907 | * Re-issue the NS cmd |
908 | */ | 908 | */ |
909 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, | 909 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, |
910 | "4102 Process Deferred RSCN Data: x%x x%x\n", | 910 | "4167 Process Deferred RSCN Data: x%x x%x\n", |
911 | vport->fc_flag, vport->fc_rscn_id_cnt); | 911 | vport->fc_flag, vport->fc_rscn_id_cnt); |
912 | lpfc_els_handle_rscn(vport); | 912 | lpfc_els_handle_rscn(vport); |
913 | 913 | ||
@@ -1430,7 +1430,7 @@ lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol, | |||
1430 | * Name object. NPIV is not in play so this integer | 1430 | * Name object. NPIV is not in play so this integer |
1431 | * value is sufficient and unique per FC-ID. | 1431 | * value is sufficient and unique per FC-ID. |
1432 | */ | 1432 | */ |
1433 | n = snprintf(symbol, size, "%d", vport->phba->brd_no); | 1433 | n = scnprintf(symbol, size, "%d", vport->phba->brd_no); |
1434 | return n; | 1434 | return n; |
1435 | } | 1435 | } |
1436 | 1436 | ||
@@ -1444,26 +1444,26 @@ lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol, | |||
1444 | 1444 | ||
1445 | lpfc_decode_firmware_rev(vport->phba, fwrev, 0); | 1445 | lpfc_decode_firmware_rev(vport->phba, fwrev, 0); |
1446 | 1446 | ||
1447 | n = snprintf(symbol, size, "Emulex %s", vport->phba->ModelName); | 1447 | n = scnprintf(symbol, size, "Emulex %s", vport->phba->ModelName); |
1448 | if (size < n) | 1448 | if (size < n) |
1449 | return n; | 1449 | return n; |
1450 | 1450 | ||
1451 | n += snprintf(symbol + n, size - n, " FV%s", fwrev); | 1451 | n += scnprintf(symbol + n, size - n, " FV%s", fwrev); |
1452 | if (size < n) | 1452 | if (size < n) |
1453 | return n; | 1453 | return n; |
1454 | 1454 | ||
1455 | n += snprintf(symbol + n, size - n, " DV%s.", | 1455 | n += scnprintf(symbol + n, size - n, " DV%s.", |
1456 | lpfc_release_version); | 1456 | lpfc_release_version); |
1457 | if (size < n) | 1457 | if (size < n) |
1458 | return n; | 1458 | return n; |
1459 | 1459 | ||
1460 | n += snprintf(symbol + n, size - n, " HN:%s.", | 1460 | n += scnprintf(symbol + n, size - n, " HN:%s.", |
1461 | init_utsname()->nodename); | 1461 | init_utsname()->nodename); |
1462 | if (size < n) | 1462 | if (size < n) |
1463 | return n; | 1463 | return n; |
1464 | 1464 | ||
1465 | /* Note :- OS name is "Linux" */ | 1465 | /* Note :- OS name is "Linux" */ |
1466 | n += snprintf(symbol + n, size - n, " OS:%s\n", | 1466 | n += scnprintf(symbol + n, size - n, " OS:%s", |
1467 | init_utsname()->sysname); | 1467 | init_utsname()->sysname); |
1468 | return n; | 1468 | return n; |
1469 | } | 1469 | } |
@@ -2005,8 +2005,11 @@ lpfc_fdmi_hba_attr_manufacturer(struct lpfc_vport *vport, | |||
2005 | ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; | 2005 | ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; |
2006 | memset(ae, 0, 256); | 2006 | memset(ae, 0, 256); |
2007 | 2007 | ||
2008 | /* This string MUST be consistent with other FC platforms | ||
2009 | * supported by Broadcom. | ||
2010 | */ | ||
2008 | strncpy(ae->un.AttrString, | 2011 | strncpy(ae->un.AttrString, |
2009 | "Broadcom Inc.", | 2012 | "Emulex Corporation", |
2010 | sizeof(ae->un.AttrString)); | 2013 | sizeof(ae->un.AttrString)); |
2011 | len = strnlen(ae->un.AttrString, | 2014 | len = strnlen(ae->un.AttrString, |
2012 | sizeof(ae->un.AttrString)); | 2015 | sizeof(ae->un.AttrString)); |
@@ -2301,7 +2304,8 @@ lpfc_fdmi_hba_attr_bios_ver(struct lpfc_vport *vport, | |||
2301 | ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; | 2304 | ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; |
2302 | memset(ae, 0, 256); | 2305 | memset(ae, 0, 256); |
2303 | 2306 | ||
2304 | lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); | 2307 | strlcat(ae->un.AttrString, phba->BIOSVersion, |
2308 | sizeof(ae->un.AttrString)); | ||
2305 | len = strnlen(ae->un.AttrString, | 2309 | len = strnlen(ae->un.AttrString, |
2306 | sizeof(ae->un.AttrString)); | 2310 | sizeof(ae->un.AttrString)); |
2307 | len += (len & 3) ? (4 - (len & 3)) : 4; | 2311 | len += (len & 3) ? (4 - (len & 3)) : 4; |
@@ -2360,10 +2364,11 @@ lpfc_fdmi_port_attr_fc4type(struct lpfc_vport *vport, | |||
2360 | ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; | 2364 | ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; |
2361 | memset(ae, 0, 32); | 2365 | memset(ae, 0, 32); |
2362 | 2366 | ||
2363 | ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */ | 2367 | ae->un.AttrTypes[3] = 0x02; /* Type 0x1 - ELS */ |
2364 | ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */ | 2368 | ae->un.AttrTypes[2] = 0x01; /* Type 0x8 - FCP */ |
2365 | ae->un.AttrTypes[6] = 0x01; /* Type 40 - NVME */ | 2369 | if (vport->nvmei_support || vport->phba->nvmet_support) |
2366 | ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */ | 2370 | ae->un.AttrTypes[6] = 0x01; /* Type 0x28 - NVME */ |
2371 | ae->un.AttrTypes[7] = 0x01; /* Type 0x20 - CT */ | ||
2367 | size = FOURBYTES + 32; | 2372 | size = FOURBYTES + 32; |
2368 | ad->AttrLen = cpu_to_be16(size); | 2373 | ad->AttrLen = cpu_to_be16(size); |
2369 | ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES); | 2374 | ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES); |
@@ -2673,9 +2678,11 @@ lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport, | |||
2673 | ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; | 2678 | ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; |
2674 | memset(ae, 0, 32); | 2679 | memset(ae, 0, 32); |
2675 | 2680 | ||
2676 | ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */ | 2681 | ae->un.AttrTypes[3] = 0x02; /* Type 0x1 - ELS */ |
2677 | ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */ | 2682 | ae->un.AttrTypes[2] = 0x01; /* Type 0x8 - FCP */ |
2678 | ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */ | 2683 | if (vport->phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) |
2684 | ae->un.AttrTypes[6] = 0x1; /* Type 0x28 - NVME */ | ||
2685 | ae->un.AttrTypes[7] = 0x01; /* Type 0x20 - CT */ | ||
2679 | size = FOURBYTES + 32; | 2686 | size = FOURBYTES + 32; |
2680 | ad->AttrLen = cpu_to_be16(size); | 2687 | ad->AttrLen = cpu_to_be16(size); |
2681 | ad->AttrType = cpu_to_be16(RPRT_ACTIVE_FC4_TYPES); | 2688 | ad->AttrType = cpu_to_be16(RPRT_ACTIVE_FC4_TYPES); |
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 1215eaa530db..1ee857d9d165 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c | |||
@@ -170,7 +170,7 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) | |||
170 | snprintf(buffer, | 170 | snprintf(buffer, |
171 | LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", | 171 | LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", |
172 | dtp->seq_cnt, ms, dtp->fmt); | 172 | dtp->seq_cnt, ms, dtp->fmt); |
173 | len += snprintf(buf+len, size-len, buffer, | 173 | len += scnprintf(buf+len, size-len, buffer, |
174 | dtp->data1, dtp->data2, dtp->data3); | 174 | dtp->data1, dtp->data2, dtp->data3); |
175 | } | 175 | } |
176 | for (i = 0; i < index; i++) { | 176 | for (i = 0; i < index; i++) { |
@@ -181,7 +181,7 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) | |||
181 | snprintf(buffer, | 181 | snprintf(buffer, |
182 | LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", | 182 | LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", |
183 | dtp->seq_cnt, ms, dtp->fmt); | 183 | dtp->seq_cnt, ms, dtp->fmt); |
184 | len += snprintf(buf+len, size-len, buffer, | 184 | len += scnprintf(buf+len, size-len, buffer, |
185 | dtp->data1, dtp->data2, dtp->data3); | 185 | dtp->data1, dtp->data2, dtp->data3); |
186 | } | 186 | } |
187 | 187 | ||
@@ -236,7 +236,7 @@ lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size) | |||
236 | snprintf(buffer, | 236 | snprintf(buffer, |
237 | LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", | 237 | LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", |
238 | dtp->seq_cnt, ms, dtp->fmt); | 238 | dtp->seq_cnt, ms, dtp->fmt); |
239 | len += snprintf(buf+len, size-len, buffer, | 239 | len += scnprintf(buf+len, size-len, buffer, |
240 | dtp->data1, dtp->data2, dtp->data3); | 240 | dtp->data1, dtp->data2, dtp->data3); |
241 | } | 241 | } |
242 | for (i = 0; i < index; i++) { | 242 | for (i = 0; i < index; i++) { |
@@ -247,7 +247,7 @@ lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size) | |||
247 | snprintf(buffer, | 247 | snprintf(buffer, |
248 | LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", | 248 | LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", |
249 | dtp->seq_cnt, ms, dtp->fmt); | 249 | dtp->seq_cnt, ms, dtp->fmt); |
250 | len += snprintf(buf+len, size-len, buffer, | 250 | len += scnprintf(buf+len, size-len, buffer, |
251 | dtp->data1, dtp->data2, dtp->data3); | 251 | dtp->data1, dtp->data2, dtp->data3); |
252 | } | 252 | } |
253 | 253 | ||
@@ -307,7 +307,7 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) | |||
307 | 307 | ||
308 | i = lpfc_debugfs_last_hbq; | 308 | i = lpfc_debugfs_last_hbq; |
309 | 309 | ||
310 | len += snprintf(buf+len, size-len, "HBQ %d Info\n", i); | 310 | len += scnprintf(buf+len, size-len, "HBQ %d Info\n", i); |
311 | 311 | ||
312 | hbqs = &phba->hbqs[i]; | 312 | hbqs = &phba->hbqs[i]; |
313 | posted = 0; | 313 | posted = 0; |
@@ -315,21 +315,21 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) | |||
315 | posted++; | 315 | posted++; |
316 | 316 | ||
317 | hip = lpfc_hbq_defs[i]; | 317 | hip = lpfc_hbq_defs[i]; |
318 | len += snprintf(buf+len, size-len, | 318 | len += scnprintf(buf+len, size-len, |
319 | "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n", | 319 | "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n", |
320 | hip->hbq_index, hip->profile, hip->rn, | 320 | hip->hbq_index, hip->profile, hip->rn, |
321 | hip->buffer_count, hip->init_count, hip->add_count, posted); | 321 | hip->buffer_count, hip->init_count, hip->add_count, posted); |
322 | 322 | ||
323 | raw_index = phba->hbq_get[i]; | 323 | raw_index = phba->hbq_get[i]; |
324 | getidx = le32_to_cpu(raw_index); | 324 | getidx = le32_to_cpu(raw_index); |
325 | len += snprintf(buf+len, size-len, | 325 | len += scnprintf(buf+len, size-len, |
326 | "entries:%d bufcnt:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n", | 326 | "entries:%d bufcnt:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n", |
327 | hbqs->entry_count, hbqs->buffer_count, hbqs->hbqPutIdx, | 327 | hbqs->entry_count, hbqs->buffer_count, hbqs->hbqPutIdx, |
328 | hbqs->next_hbqPutIdx, hbqs->local_hbqGetIdx, getidx); | 328 | hbqs->next_hbqPutIdx, hbqs->local_hbqGetIdx, getidx); |
329 | 329 | ||
330 | hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt; | 330 | hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt; |
331 | for (j=0; j<hbqs->entry_count; j++) { | 331 | for (j=0; j<hbqs->entry_count; j++) { |
332 | len += snprintf(buf+len, size-len, | 332 | len += scnprintf(buf+len, size-len, |
333 | "%03d: %08x %04x %05x ", j, | 333 | "%03d: %08x %04x %05x ", j, |
334 | le32_to_cpu(hbqe->bde.addrLow), | 334 | le32_to_cpu(hbqe->bde.addrLow), |
335 | le32_to_cpu(hbqe->bde.tus.w), | 335 | le32_to_cpu(hbqe->bde.tus.w), |
@@ -341,14 +341,16 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) | |||
341 | low = hbqs->hbqPutIdx - posted; | 341 | low = hbqs->hbqPutIdx - posted; |
342 | if (low >= 0) { | 342 | if (low >= 0) { |
343 | if ((j >= hbqs->hbqPutIdx) || (j < low)) { | 343 | if ((j >= hbqs->hbqPutIdx) || (j < low)) { |
344 | len += snprintf(buf+len, size-len, "Unused\n"); | 344 | len += scnprintf(buf + len, size - len, |
345 | "Unused\n"); | ||
345 | goto skipit; | 346 | goto skipit; |
346 | } | 347 | } |
347 | } | 348 | } |
348 | else { | 349 | else { |
349 | if ((j >= hbqs->hbqPutIdx) && | 350 | if ((j >= hbqs->hbqPutIdx) && |
350 | (j < (hbqs->entry_count+low))) { | 351 | (j < (hbqs->entry_count+low))) { |
351 | len += snprintf(buf+len, size-len, "Unused\n"); | 352 | len += scnprintf(buf + len, size - len, |
353 | "Unused\n"); | ||
352 | goto skipit; | 354 | goto skipit; |
353 | } | 355 | } |
354 | } | 356 | } |
@@ -358,7 +360,7 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) | |||
358 | hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf); | 360 | hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf); |
359 | phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff); | 361 | phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff); |
360 | if (phys == le32_to_cpu(hbqe->bde.addrLow)) { | 362 | if (phys == le32_to_cpu(hbqe->bde.addrLow)) { |
361 | len += snprintf(buf+len, size-len, | 363 | len += scnprintf(buf+len, size-len, |
362 | "Buf%d: %p %06x\n", i, | 364 | "Buf%d: %p %06x\n", i, |
363 | hbq_buf->dbuf.virt, hbq_buf->tag); | 365 | hbq_buf->dbuf.virt, hbq_buf->tag); |
364 | found = 1; | 366 | found = 1; |
@@ -367,7 +369,7 @@ lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) | |||
367 | i++; | 369 | i++; |
368 | } | 370 | } |
369 | if (!found) { | 371 | if (!found) { |
370 | len += snprintf(buf+len, size-len, "No DMAinfo?\n"); | 372 | len += scnprintf(buf+len, size-len, "No DMAinfo?\n"); |
371 | } | 373 | } |
372 | skipit: | 374 | skipit: |
373 | hbqe++; | 375 | hbqe++; |
@@ -413,14 +415,14 @@ lpfc_debugfs_commonxripools_data(struct lpfc_hba *phba, char *buf, int size) | |||
413 | break; | 415 | break; |
414 | qp = &phba->sli4_hba.hdwq[lpfc_debugfs_last_xripool]; | 416 | qp = &phba->sli4_hba.hdwq[lpfc_debugfs_last_xripool]; |
415 | 417 | ||
416 | len += snprintf(buf + len, size - len, "HdwQ %d Info ", i); | 418 | len += scnprintf(buf + len, size - len, "HdwQ %d Info ", i); |
417 | spin_lock_irqsave(&qp->abts_scsi_buf_list_lock, iflag); | 419 | spin_lock_irqsave(&qp->abts_scsi_buf_list_lock, iflag); |
418 | spin_lock(&qp->abts_nvme_buf_list_lock); | 420 | spin_lock(&qp->abts_nvme_buf_list_lock); |
419 | spin_lock(&qp->io_buf_list_get_lock); | 421 | spin_lock(&qp->io_buf_list_get_lock); |
420 | spin_lock(&qp->io_buf_list_put_lock); | 422 | spin_lock(&qp->io_buf_list_put_lock); |
421 | out = qp->total_io_bufs - (qp->get_io_bufs + qp->put_io_bufs + | 423 | out = qp->total_io_bufs - (qp->get_io_bufs + qp->put_io_bufs + |
422 | qp->abts_scsi_io_bufs + qp->abts_nvme_io_bufs); | 424 | qp->abts_scsi_io_bufs + qp->abts_nvme_io_bufs); |
423 | len += snprintf(buf + len, size - len, | 425 | len += scnprintf(buf + len, size - len, |
424 | "tot:%d get:%d put:%d mt:%d " | 426 | "tot:%d get:%d put:%d mt:%d " |
425 | "ABTS scsi:%d nvme:%d Out:%d\n", | 427 | "ABTS scsi:%d nvme:%d Out:%d\n", |
426 | qp->total_io_bufs, qp->get_io_bufs, qp->put_io_bufs, | 428 | qp->total_io_bufs, qp->get_io_bufs, qp->put_io_bufs, |
@@ -612,9 +614,9 @@ lpfc_debugfs_lockstat_data(struct lpfc_hba *phba, char *buf, int size) | |||
612 | break; | 614 | break; |
613 | qp = &phba->sli4_hba.hdwq[lpfc_debugfs_last_lock]; | 615 | qp = &phba->sli4_hba.hdwq[lpfc_debugfs_last_lock]; |
614 | 616 | ||
615 | len += snprintf(buf + len, size - len, "HdwQ %03d Lock ", i); | 617 | len += scnprintf(buf + len, size - len, "HdwQ %03d Lock ", i); |
616 | if (phba->cfg_xri_rebalancing) { | 618 | if (phba->cfg_xri_rebalancing) { |
617 | len += snprintf(buf + len, size - len, | 619 | len += scnprintf(buf + len, size - len, |
618 | "get_pvt:%d mv_pvt:%d " | 620 | "get_pvt:%d mv_pvt:%d " |
619 | "mv2pub:%d mv2pvt:%d " | 621 | "mv2pub:%d mv2pvt:%d " |
620 | "put_pvt:%d put_pub:%d wq:%d\n", | 622 | "put_pvt:%d put_pub:%d wq:%d\n", |
@@ -626,7 +628,7 @@ lpfc_debugfs_lockstat_data(struct lpfc_hba *phba, char *buf, int size) | |||
626 | qp->lock_conflict.free_pub_pool, | 628 | qp->lock_conflict.free_pub_pool, |
627 | qp->lock_conflict.wq_access); | 629 | qp->lock_conflict.wq_access); |
628 | } else { | 630 | } else { |
629 | len += snprintf(buf + len, size - len, | 631 | len += scnprintf(buf + len, size - len, |
630 | "get:%d put:%d free:%d wq:%d\n", | 632 | "get:%d put:%d free:%d wq:%d\n", |
631 | qp->lock_conflict.alloc_xri_get, | 633 | qp->lock_conflict.alloc_xri_get, |
632 | qp->lock_conflict.alloc_xri_put, | 634 | qp->lock_conflict.alloc_xri_put, |
@@ -678,7 +680,7 @@ lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size) | |||
678 | off = 0; | 680 | off = 0; |
679 | spin_lock_irq(&phba->hbalock); | 681 | spin_lock_irq(&phba->hbalock); |
680 | 682 | ||
681 | len += snprintf(buf+len, size-len, "HBA SLIM\n"); | 683 | len += scnprintf(buf+len, size-len, "HBA SLIM\n"); |
682 | lpfc_memcpy_from_slim(buffer, | 684 | lpfc_memcpy_from_slim(buffer, |
683 | phba->MBslimaddr + lpfc_debugfs_last_hba_slim_off, 1024); | 685 | phba->MBslimaddr + lpfc_debugfs_last_hba_slim_off, 1024); |
684 | 686 | ||
@@ -692,7 +694,7 @@ lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size) | |||
692 | 694 | ||
693 | i = 1024; | 695 | i = 1024; |
694 | while (i > 0) { | 696 | while (i > 0) { |
695 | len += snprintf(buf+len, size-len, | 697 | len += scnprintf(buf+len, size-len, |
696 | "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", | 698 | "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", |
697 | off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), | 699 | off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), |
698 | *(ptr+5), *(ptr+6), *(ptr+7)); | 700 | *(ptr+5), *(ptr+6), *(ptr+7)); |
@@ -736,11 +738,11 @@ lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size) | |||
736 | off = 0; | 738 | off = 0; |
737 | spin_lock_irq(&phba->hbalock); | 739 | spin_lock_irq(&phba->hbalock); |
738 | 740 | ||
739 | len += snprintf(buf+len, size-len, "SLIM Mailbox\n"); | 741 | len += scnprintf(buf+len, size-len, "SLIM Mailbox\n"); |
740 | ptr = (uint32_t *)phba->slim2p.virt; | 742 | ptr = (uint32_t *)phba->slim2p.virt; |
741 | i = sizeof(MAILBOX_t); | 743 | i = sizeof(MAILBOX_t); |
742 | while (i > 0) { | 744 | while (i > 0) { |
743 | len += snprintf(buf+len, size-len, | 745 | len += scnprintf(buf+len, size-len, |
744 | "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", | 746 | "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", |
745 | off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), | 747 | off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), |
746 | *(ptr+5), *(ptr+6), *(ptr+7)); | 748 | *(ptr+5), *(ptr+6), *(ptr+7)); |
@@ -749,11 +751,11 @@ lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size) | |||
749 | off += (8 * sizeof(uint32_t)); | 751 | off += (8 * sizeof(uint32_t)); |
750 | } | 752 | } |
751 | 753 | ||
752 | len += snprintf(buf+len, size-len, "SLIM PCB\n"); | 754 | len += scnprintf(buf+len, size-len, "SLIM PCB\n"); |
753 | ptr = (uint32_t *)phba->pcb; | 755 | ptr = (uint32_t *)phba->pcb; |
754 | i = sizeof(PCB_t); | 756 | i = sizeof(PCB_t); |
755 | while (i > 0) { | 757 | while (i > 0) { |
756 | len += snprintf(buf+len, size-len, | 758 | len += scnprintf(buf+len, size-len, |
757 | "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", | 759 | "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", |
758 | off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), | 760 | off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), |
759 | *(ptr+5), *(ptr+6), *(ptr+7)); | 761 | *(ptr+5), *(ptr+6), *(ptr+7)); |
@@ -766,7 +768,7 @@ lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size) | |||
766 | for (i = 0; i < 4; i++) { | 768 | for (i = 0; i < 4; i++) { |
767 | pgpp = &phba->port_gp[i]; | 769 | pgpp = &phba->port_gp[i]; |
768 | pring = &psli->sli3_ring[i]; | 770 | pring = &psli->sli3_ring[i]; |
769 | len += snprintf(buf+len, size-len, | 771 | len += scnprintf(buf+len, size-len, |
770 | "Ring %d: CMD GetInx:%d " | 772 | "Ring %d: CMD GetInx:%d " |
771 | "(Max:%d Next:%d " | 773 | "(Max:%d Next:%d " |
772 | "Local:%d flg:x%x) " | 774 | "Local:%d flg:x%x) " |
@@ -783,7 +785,7 @@ lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size) | |||
783 | word1 = readl(phba->CAregaddr); | 785 | word1 = readl(phba->CAregaddr); |
784 | word2 = readl(phba->HSregaddr); | 786 | word2 = readl(phba->HSregaddr); |
785 | word3 = readl(phba->HCregaddr); | 787 | word3 = readl(phba->HCregaddr); |
786 | len += snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x " | 788 | len += scnprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x " |
787 | "HC:%08x\n", word0, word1, word2, word3); | 789 | "HC:%08x\n", word0, word1, word2, word3); |
788 | } | 790 | } |
789 | spin_unlock_irq(&phba->hbalock); | 791 | spin_unlock_irq(&phba->hbalock); |
@@ -821,12 +823,12 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) | |||
821 | cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE); | 823 | cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE); |
822 | outio = 0; | 824 | outio = 0; |
823 | 825 | ||
824 | len += snprintf(buf+len, size-len, "\nFCP Nodelist Entries ...\n"); | 826 | len += scnprintf(buf+len, size-len, "\nFCP Nodelist Entries ...\n"); |
825 | spin_lock_irq(shost->host_lock); | 827 | spin_lock_irq(shost->host_lock); |
826 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { | 828 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
827 | iocnt = 0; | 829 | iocnt = 0; |
828 | if (!cnt) { | 830 | if (!cnt) { |
829 | len += snprintf(buf+len, size-len, | 831 | len += scnprintf(buf+len, size-len, |
830 | "Missing Nodelist Entries\n"); | 832 | "Missing Nodelist Entries\n"); |
831 | break; | 833 | break; |
832 | } | 834 | } |
@@ -864,63 +866,63 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) | |||
864 | default: | 866 | default: |
865 | statep = "UNKNOWN"; | 867 | statep = "UNKNOWN"; |
866 | } | 868 | } |
867 | len += snprintf(buf+len, size-len, "%s DID:x%06x ", | 869 | len += scnprintf(buf+len, size-len, "%s DID:x%06x ", |
868 | statep, ndlp->nlp_DID); | 870 | statep, ndlp->nlp_DID); |
869 | len += snprintf(buf+len, size-len, | 871 | len += scnprintf(buf+len, size-len, |
870 | "WWPN x%llx ", | 872 | "WWPN x%llx ", |
871 | wwn_to_u64(ndlp->nlp_portname.u.wwn)); | 873 | wwn_to_u64(ndlp->nlp_portname.u.wwn)); |
872 | len += snprintf(buf+len, size-len, | 874 | len += scnprintf(buf+len, size-len, |
873 | "WWNN x%llx ", | 875 | "WWNN x%llx ", |
874 | wwn_to_u64(ndlp->nlp_nodename.u.wwn)); | 876 | wwn_to_u64(ndlp->nlp_nodename.u.wwn)); |
875 | if (ndlp->nlp_flag & NLP_RPI_REGISTERED) | 877 | if (ndlp->nlp_flag & NLP_RPI_REGISTERED) |
876 | len += snprintf(buf+len, size-len, "RPI:%03d ", | 878 | len += scnprintf(buf+len, size-len, "RPI:%03d ", |
877 | ndlp->nlp_rpi); | 879 | ndlp->nlp_rpi); |
878 | else | 880 | else |
879 | len += snprintf(buf+len, size-len, "RPI:none "); | 881 | len += scnprintf(buf+len, size-len, "RPI:none "); |
880 | len += snprintf(buf+len, size-len, "flag:x%08x ", | 882 | len += scnprintf(buf+len, size-len, "flag:x%08x ", |
881 | ndlp->nlp_flag); | 883 | ndlp->nlp_flag); |
882 | if (!ndlp->nlp_type) | 884 | if (!ndlp->nlp_type) |
883 | len += snprintf(buf+len, size-len, "UNKNOWN_TYPE "); | 885 | len += scnprintf(buf+len, size-len, "UNKNOWN_TYPE "); |
884 | if (ndlp->nlp_type & NLP_FC_NODE) | 886 | if (ndlp->nlp_type & NLP_FC_NODE) |
885 | len += snprintf(buf+len, size-len, "FC_NODE "); | 887 | len += scnprintf(buf+len, size-len, "FC_NODE "); |
886 | if (ndlp->nlp_type & NLP_FABRIC) { | 888 | if (ndlp->nlp_type & NLP_FABRIC) { |
887 | len += snprintf(buf+len, size-len, "FABRIC "); | 889 | len += scnprintf(buf+len, size-len, "FABRIC "); |
888 | iocnt = 0; | 890 | iocnt = 0; |
889 | } | 891 | } |
890 | if (ndlp->nlp_type & NLP_FCP_TARGET) | 892 | if (ndlp->nlp_type & NLP_FCP_TARGET) |
891 | len += snprintf(buf+len, size-len, "FCP_TGT sid:%d ", | 893 | len += scnprintf(buf+len, size-len, "FCP_TGT sid:%d ", |
892 | ndlp->nlp_sid); | 894 | ndlp->nlp_sid); |
893 | if (ndlp->nlp_type & NLP_FCP_INITIATOR) | 895 | if (ndlp->nlp_type & NLP_FCP_INITIATOR) |
894 | len += snprintf(buf+len, size-len, "FCP_INITIATOR "); | 896 | len += scnprintf(buf+len, size-len, "FCP_INITIATOR "); |
895 | if (ndlp->nlp_type & NLP_NVME_TARGET) | 897 | if (ndlp->nlp_type & NLP_NVME_TARGET) |
896 | len += snprintf(buf + len, | 898 | len += scnprintf(buf + len, |
897 | size - len, "NVME_TGT sid:%d ", | 899 | size - len, "NVME_TGT sid:%d ", |
898 | NLP_NO_SID); | 900 | NLP_NO_SID); |
899 | if (ndlp->nlp_type & NLP_NVME_INITIATOR) | 901 | if (ndlp->nlp_type & NLP_NVME_INITIATOR) |
900 | len += snprintf(buf + len, | 902 | len += scnprintf(buf + len, |
901 | size - len, "NVME_INITIATOR "); | 903 | size - len, "NVME_INITIATOR "); |
902 | len += snprintf(buf+len, size-len, "usgmap:%x ", | 904 | len += scnprintf(buf+len, size-len, "usgmap:%x ", |
903 | ndlp->nlp_usg_map); | 905 | ndlp->nlp_usg_map); |
904 | len += snprintf(buf+len, size-len, "refcnt:%x", | 906 | len += scnprintf(buf+len, size-len, "refcnt:%x", |
905 | kref_read(&ndlp->kref)); | 907 | kref_read(&ndlp->kref)); |
906 | if (iocnt) { | 908 | if (iocnt) { |
907 | i = atomic_read(&ndlp->cmd_pending); | 909 | i = atomic_read(&ndlp->cmd_pending); |
908 | len += snprintf(buf + len, size - len, | 910 | len += scnprintf(buf + len, size - len, |
909 | " OutIO:x%x Qdepth x%x", | 911 | " OutIO:x%x Qdepth x%x", |
910 | i, ndlp->cmd_qdepth); | 912 | i, ndlp->cmd_qdepth); |
911 | outio += i; | 913 | outio += i; |
912 | } | 914 | } |
913 | len += snprintf(buf + len, size - len, "defer:%x ", | 915 | len += scnprintf(buf + len, size - len, "defer:%x ", |
914 | ndlp->nlp_defer_did); | 916 | ndlp->nlp_defer_did); |
915 | len += snprintf(buf+len, size-len, "\n"); | 917 | len += scnprintf(buf+len, size-len, "\n"); |
916 | } | 918 | } |
917 | spin_unlock_irq(shost->host_lock); | 919 | spin_unlock_irq(shost->host_lock); |
918 | 920 | ||
919 | len += snprintf(buf + len, size - len, | 921 | len += scnprintf(buf + len, size - len, |
920 | "\nOutstanding IO x%x\n", outio); | 922 | "\nOutstanding IO x%x\n", outio); |
921 | 923 | ||
922 | if (phba->nvmet_support && phba->targetport && (vport == phba->pport)) { | 924 | if (phba->nvmet_support && phba->targetport && (vport == phba->pport)) { |
923 | len += snprintf(buf + len, size - len, | 925 | len += scnprintf(buf + len, size - len, |
924 | "\nNVME Targetport Entry ...\n"); | 926 | "\nNVME Targetport Entry ...\n"); |
925 | 927 | ||
926 | /* Port state is only one of two values for now. */ | 928 | /* Port state is only one of two values for now. */ |
@@ -928,18 +930,18 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) | |||
928 | statep = "REGISTERED"; | 930 | statep = "REGISTERED"; |
929 | else | 931 | else |
930 | statep = "INIT"; | 932 | statep = "INIT"; |
931 | len += snprintf(buf + len, size - len, | 933 | len += scnprintf(buf + len, size - len, |
932 | "TGT WWNN x%llx WWPN x%llx State %s\n", | 934 | "TGT WWNN x%llx WWPN x%llx State %s\n", |
933 | wwn_to_u64(vport->fc_nodename.u.wwn), | 935 | wwn_to_u64(vport->fc_nodename.u.wwn), |
934 | wwn_to_u64(vport->fc_portname.u.wwn), | 936 | wwn_to_u64(vport->fc_portname.u.wwn), |
935 | statep); | 937 | statep); |
936 | len += snprintf(buf + len, size - len, | 938 | len += scnprintf(buf + len, size - len, |
937 | " Targetport DID x%06x\n", | 939 | " Targetport DID x%06x\n", |
938 | phba->targetport->port_id); | 940 | phba->targetport->port_id); |
939 | goto out_exit; | 941 | goto out_exit; |
940 | } | 942 | } |
941 | 943 | ||
942 | len += snprintf(buf + len, size - len, | 944 | len += scnprintf(buf + len, size - len, |
943 | "\nNVME Lport/Rport Entries ...\n"); | 945 | "\nNVME Lport/Rport Entries ...\n"); |
944 | 946 | ||
945 | localport = vport->localport; | 947 | localport = vport->localport; |
@@ -954,11 +956,11 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) | |||
954 | else | 956 | else |
955 | statep = "UNKNOWN "; | 957 | statep = "UNKNOWN "; |
956 | 958 | ||
957 | len += snprintf(buf + len, size - len, | 959 | len += scnprintf(buf + len, size - len, |
958 | "Lport DID x%06x PortState %s\n", | 960 | "Lport DID x%06x PortState %s\n", |
959 | localport->port_id, statep); | 961 | localport->port_id, statep); |
960 | 962 | ||
961 | len += snprintf(buf + len, size - len, "\tRport List:\n"); | 963 | len += scnprintf(buf + len, size - len, "\tRport List:\n"); |
962 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { | 964 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
963 | /* local short-hand pointer. */ | 965 | /* local short-hand pointer. */ |
964 | spin_lock(&phba->hbalock); | 966 | spin_lock(&phba->hbalock); |
@@ -985,32 +987,32 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) | |||
985 | } | 987 | } |
986 | 988 | ||
987 | /* Tab in to show lport ownership. */ | 989 | /* Tab in to show lport ownership. */ |
988 | len += snprintf(buf + len, size - len, | 990 | len += scnprintf(buf + len, size - len, |
989 | "\t%s Port ID:x%06x ", | 991 | "\t%s Port ID:x%06x ", |
990 | statep, nrport->port_id); | 992 | statep, nrport->port_id); |
991 | len += snprintf(buf + len, size - len, "WWPN x%llx ", | 993 | len += scnprintf(buf + len, size - len, "WWPN x%llx ", |
992 | nrport->port_name); | 994 | nrport->port_name); |
993 | len += snprintf(buf + len, size - len, "WWNN x%llx ", | 995 | len += scnprintf(buf + len, size - len, "WWNN x%llx ", |
994 | nrport->node_name); | 996 | nrport->node_name); |
995 | 997 | ||
996 | /* An NVME rport can have multiple roles. */ | 998 | /* An NVME rport can have multiple roles. */ |
997 | if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) | 999 | if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) |
998 | len += snprintf(buf + len, size - len, | 1000 | len += scnprintf(buf + len, size - len, |
999 | "INITIATOR "); | 1001 | "INITIATOR "); |
1000 | if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) | 1002 | if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) |
1001 | len += snprintf(buf + len, size - len, | 1003 | len += scnprintf(buf + len, size - len, |
1002 | "TARGET "); | 1004 | "TARGET "); |
1003 | if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY) | 1005 | if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY) |
1004 | len += snprintf(buf + len, size - len, | 1006 | len += scnprintf(buf + len, size - len, |
1005 | "DISCSRVC "); | 1007 | "DISCSRVC "); |
1006 | if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR | | 1008 | if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR | |
1007 | FC_PORT_ROLE_NVME_TARGET | | 1009 | FC_PORT_ROLE_NVME_TARGET | |
1008 | FC_PORT_ROLE_NVME_DISCOVERY)) | 1010 | FC_PORT_ROLE_NVME_DISCOVERY)) |
1009 | len += snprintf(buf + len, size - len, | 1011 | len += scnprintf(buf + len, size - len, |
1010 | "UNKNOWN ROLE x%x", | 1012 | "UNKNOWN ROLE x%x", |
1011 | nrport->port_role); | 1013 | nrport->port_role); |
1012 | /* Terminate the string. */ | 1014 | /* Terminate the string. */ |
1013 | len += snprintf(buf + len, size - len, "\n"); | 1015 | len += scnprintf(buf + len, size - len, "\n"); |
1014 | } | 1016 | } |
1015 | 1017 | ||
1016 | spin_unlock_irq(shost->host_lock); | 1018 | spin_unlock_irq(shost->host_lock); |
@@ -1049,35 +1051,35 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size) | |||
1049 | if (!phba->targetport) | 1051 | if (!phba->targetport) |
1050 | return len; | 1052 | return len; |
1051 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; | 1053 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; |
1052 | len += snprintf(buf + len, size - len, | 1054 | len += scnprintf(buf + len, size - len, |
1053 | "\nNVME Targetport Statistics\n"); | 1055 | "\nNVME Targetport Statistics\n"); |
1054 | 1056 | ||
1055 | len += snprintf(buf + len, size - len, | 1057 | len += scnprintf(buf + len, size - len, |
1056 | "LS: Rcv %08x Drop %08x Abort %08x\n", | 1058 | "LS: Rcv %08x Drop %08x Abort %08x\n", |
1057 | atomic_read(&tgtp->rcv_ls_req_in), | 1059 | atomic_read(&tgtp->rcv_ls_req_in), |
1058 | atomic_read(&tgtp->rcv_ls_req_drop), | 1060 | atomic_read(&tgtp->rcv_ls_req_drop), |
1059 | atomic_read(&tgtp->xmt_ls_abort)); | 1061 | atomic_read(&tgtp->xmt_ls_abort)); |
1060 | if (atomic_read(&tgtp->rcv_ls_req_in) != | 1062 | if (atomic_read(&tgtp->rcv_ls_req_in) != |
1061 | atomic_read(&tgtp->rcv_ls_req_out)) { | 1063 | atomic_read(&tgtp->rcv_ls_req_out)) { |
1062 | len += snprintf(buf + len, size - len, | 1064 | len += scnprintf(buf + len, size - len, |
1063 | "Rcv LS: in %08x != out %08x\n", | 1065 | "Rcv LS: in %08x != out %08x\n", |
1064 | atomic_read(&tgtp->rcv_ls_req_in), | 1066 | atomic_read(&tgtp->rcv_ls_req_in), |
1065 | atomic_read(&tgtp->rcv_ls_req_out)); | 1067 | atomic_read(&tgtp->rcv_ls_req_out)); |
1066 | } | 1068 | } |
1067 | 1069 | ||
1068 | len += snprintf(buf + len, size - len, | 1070 | len += scnprintf(buf + len, size - len, |
1069 | "LS: Xmt %08x Drop %08x Cmpl %08x\n", | 1071 | "LS: Xmt %08x Drop %08x Cmpl %08x\n", |
1070 | atomic_read(&tgtp->xmt_ls_rsp), | 1072 | atomic_read(&tgtp->xmt_ls_rsp), |
1071 | atomic_read(&tgtp->xmt_ls_drop), | 1073 | atomic_read(&tgtp->xmt_ls_drop), |
1072 | atomic_read(&tgtp->xmt_ls_rsp_cmpl)); | 1074 | atomic_read(&tgtp->xmt_ls_rsp_cmpl)); |
1073 | 1075 | ||
1074 | len += snprintf(buf + len, size - len, | 1076 | len += scnprintf(buf + len, size - len, |
1075 | "LS: RSP Abort %08x xb %08x Err %08x\n", | 1077 | "LS: RSP Abort %08x xb %08x Err %08x\n", |
1076 | atomic_read(&tgtp->xmt_ls_rsp_aborted), | 1078 | atomic_read(&tgtp->xmt_ls_rsp_aborted), |
1077 | atomic_read(&tgtp->xmt_ls_rsp_xb_set), | 1079 | atomic_read(&tgtp->xmt_ls_rsp_xb_set), |
1078 | atomic_read(&tgtp->xmt_ls_rsp_error)); | 1080 | atomic_read(&tgtp->xmt_ls_rsp_error)); |
1079 | 1081 | ||
1080 | len += snprintf(buf + len, size - len, | 1082 | len += scnprintf(buf + len, size - len, |
1081 | "FCP: Rcv %08x Defer %08x Release %08x " | 1083 | "FCP: Rcv %08x Defer %08x Release %08x " |
1082 | "Drop %08x\n", | 1084 | "Drop %08x\n", |
1083 | atomic_read(&tgtp->rcv_fcp_cmd_in), | 1085 | atomic_read(&tgtp->rcv_fcp_cmd_in), |
@@ -1087,13 +1089,13 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size) | |||
1087 | 1089 | ||
1088 | if (atomic_read(&tgtp->rcv_fcp_cmd_in) != | 1090 | if (atomic_read(&tgtp->rcv_fcp_cmd_in) != |
1089 | atomic_read(&tgtp->rcv_fcp_cmd_out)) { | 1091 | atomic_read(&tgtp->rcv_fcp_cmd_out)) { |
1090 | len += snprintf(buf + len, size - len, | 1092 | len += scnprintf(buf + len, size - len, |
1091 | "Rcv FCP: in %08x != out %08x\n", | 1093 | "Rcv FCP: in %08x != out %08x\n", |
1092 | atomic_read(&tgtp->rcv_fcp_cmd_in), | 1094 | atomic_read(&tgtp->rcv_fcp_cmd_in), |
1093 | atomic_read(&tgtp->rcv_fcp_cmd_out)); | 1095 | atomic_read(&tgtp->rcv_fcp_cmd_out)); |
1094 | } | 1096 | } |
1095 | 1097 | ||
1096 | len += snprintf(buf + len, size - len, | 1098 | len += scnprintf(buf + len, size - len, |
1097 | "FCP Rsp: read %08x readrsp %08x " | 1099 | "FCP Rsp: read %08x readrsp %08x " |
1098 | "write %08x rsp %08x\n", | 1100 | "write %08x rsp %08x\n", |
1099 | atomic_read(&tgtp->xmt_fcp_read), | 1101 | atomic_read(&tgtp->xmt_fcp_read), |
@@ -1101,31 +1103,31 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size) | |||
1101 | atomic_read(&tgtp->xmt_fcp_write), | 1103 | atomic_read(&tgtp->xmt_fcp_write), |
1102 | atomic_read(&tgtp->xmt_fcp_rsp)); | 1104 | atomic_read(&tgtp->xmt_fcp_rsp)); |
1103 | 1105 | ||
1104 | len += snprintf(buf + len, size - len, | 1106 | len += scnprintf(buf + len, size - len, |
1105 | "FCP Rsp Cmpl: %08x err %08x drop %08x\n", | 1107 | "FCP Rsp Cmpl: %08x err %08x drop %08x\n", |
1106 | atomic_read(&tgtp->xmt_fcp_rsp_cmpl), | 1108 | atomic_read(&tgtp->xmt_fcp_rsp_cmpl), |
1107 | atomic_read(&tgtp->xmt_fcp_rsp_error), | 1109 | atomic_read(&tgtp->xmt_fcp_rsp_error), |
1108 | atomic_read(&tgtp->xmt_fcp_rsp_drop)); | 1110 | atomic_read(&tgtp->xmt_fcp_rsp_drop)); |
1109 | 1111 | ||
1110 | len += snprintf(buf + len, size - len, | 1112 | len += scnprintf(buf + len, size - len, |
1111 | "FCP Rsp Abort: %08x xb %08x xricqe %08x\n", | 1113 | "FCP Rsp Abort: %08x xb %08x xricqe %08x\n", |
1112 | atomic_read(&tgtp->xmt_fcp_rsp_aborted), | 1114 | atomic_read(&tgtp->xmt_fcp_rsp_aborted), |
1113 | atomic_read(&tgtp->xmt_fcp_rsp_xb_set), | 1115 | atomic_read(&tgtp->xmt_fcp_rsp_xb_set), |
1114 | atomic_read(&tgtp->xmt_fcp_xri_abort_cqe)); | 1116 | atomic_read(&tgtp->xmt_fcp_xri_abort_cqe)); |
1115 | 1117 | ||
1116 | len += snprintf(buf + len, size - len, | 1118 | len += scnprintf(buf + len, size - len, |
1117 | "ABORT: Xmt %08x Cmpl %08x\n", | 1119 | "ABORT: Xmt %08x Cmpl %08x\n", |
1118 | atomic_read(&tgtp->xmt_fcp_abort), | 1120 | atomic_read(&tgtp->xmt_fcp_abort), |
1119 | atomic_read(&tgtp->xmt_fcp_abort_cmpl)); | 1121 | atomic_read(&tgtp->xmt_fcp_abort_cmpl)); |
1120 | 1122 | ||
1121 | len += snprintf(buf + len, size - len, | 1123 | len += scnprintf(buf + len, size - len, |
1122 | "ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x", | 1124 | "ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x", |
1123 | atomic_read(&tgtp->xmt_abort_sol), | 1125 | atomic_read(&tgtp->xmt_abort_sol), |
1124 | atomic_read(&tgtp->xmt_abort_unsol), | 1126 | atomic_read(&tgtp->xmt_abort_unsol), |
1125 | atomic_read(&tgtp->xmt_abort_rsp), | 1127 | atomic_read(&tgtp->xmt_abort_rsp), |
1126 | atomic_read(&tgtp->xmt_abort_rsp_error)); | 1128 | atomic_read(&tgtp->xmt_abort_rsp_error)); |
1127 | 1129 | ||
1128 | len += snprintf(buf + len, size - len, "\n"); | 1130 | len += scnprintf(buf + len, size - len, "\n"); |
1129 | 1131 | ||
1130 | cnt = 0; | 1132 | cnt = 0; |
1131 | spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock); | 1133 | spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock); |
@@ -1136,7 +1138,7 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size) | |||
1136 | } | 1138 | } |
1137 | spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock); | 1139 | spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock); |
1138 | if (cnt) { | 1140 | if (cnt) { |
1139 | len += snprintf(buf + len, size - len, | 1141 | len += scnprintf(buf + len, size - len, |
1140 | "ABORT: %d ctx entries\n", cnt); | 1142 | "ABORT: %d ctx entries\n", cnt); |
1141 | spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock); | 1143 | spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock); |
1142 | list_for_each_entry_safe(ctxp, next_ctxp, | 1144 | list_for_each_entry_safe(ctxp, next_ctxp, |
@@ -1144,7 +1146,7 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size) | |||
1144 | list) { | 1146 | list) { |
1145 | if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) | 1147 | if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) |
1146 | break; | 1148 | break; |
1147 | len += snprintf(buf + len, size - len, | 1149 | len += scnprintf(buf + len, size - len, |
1148 | "Entry: oxid %x state %x " | 1150 | "Entry: oxid %x state %x " |
1149 | "flag %x\n", | 1151 | "flag %x\n", |
1150 | ctxp->oxid, ctxp->state, | 1152 | ctxp->oxid, ctxp->state, |
@@ -1158,7 +1160,7 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size) | |||
1158 | tot += atomic_read(&tgtp->xmt_fcp_release); | 1160 | tot += atomic_read(&tgtp->xmt_fcp_release); |
1159 | tot = atomic_read(&tgtp->rcv_fcp_cmd_in) - tot; | 1161 | tot = atomic_read(&tgtp->rcv_fcp_cmd_in) - tot; |
1160 | 1162 | ||
1161 | len += snprintf(buf + len, size - len, | 1163 | len += scnprintf(buf + len, size - len, |
1162 | "IO_CTX: %08x WAIT: cur %08x tot %08x\n" | 1164 | "IO_CTX: %08x WAIT: cur %08x tot %08x\n" |
1163 | "CTX Outstanding %08llx\n", | 1165 | "CTX Outstanding %08llx\n", |
1164 | phba->sli4_hba.nvmet_xri_cnt, | 1166 | phba->sli4_hba.nvmet_xri_cnt, |
@@ -1176,10 +1178,10 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size) | |||
1176 | if (!lport) | 1178 | if (!lport) |
1177 | return len; | 1179 | return len; |
1178 | 1180 | ||
1179 | len += snprintf(buf + len, size - len, | 1181 | len += scnprintf(buf + len, size - len, |
1180 | "\nNVME HDWQ Statistics\n"); | 1182 | "\nNVME HDWQ Statistics\n"); |
1181 | 1183 | ||
1182 | len += snprintf(buf + len, size - len, | 1184 | len += scnprintf(buf + len, size - len, |
1183 | "LS: Xmt %016x Cmpl %016x\n", | 1185 | "LS: Xmt %016x Cmpl %016x\n", |
1184 | atomic_read(&lport->fc4NvmeLsRequests), | 1186 | atomic_read(&lport->fc4NvmeLsRequests), |
1185 | atomic_read(&lport->fc4NvmeLsCmpls)); | 1187 | atomic_read(&lport->fc4NvmeLsCmpls)); |
@@ -1199,20 +1201,20 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size) | |||
1199 | if (i >= 32) | 1201 | if (i >= 32) |
1200 | continue; | 1202 | continue; |
1201 | 1203 | ||
1202 | len += snprintf(buf + len, PAGE_SIZE - len, | 1204 | len += scnprintf(buf + len, PAGE_SIZE - len, |
1203 | "HDWQ (%d): Rd %016llx Wr %016llx " | 1205 | "HDWQ (%d): Rd %016llx Wr %016llx " |
1204 | "IO %016llx ", | 1206 | "IO %016llx ", |
1205 | i, data1, data2, data3); | 1207 | i, data1, data2, data3); |
1206 | len += snprintf(buf + len, PAGE_SIZE - len, | 1208 | len += scnprintf(buf + len, PAGE_SIZE - len, |
1207 | "Cmpl %016llx OutIO %016llx\n", | 1209 | "Cmpl %016llx OutIO %016llx\n", |
1208 | tot, ((data1 + data2 + data3) - tot)); | 1210 | tot, ((data1 + data2 + data3) - tot)); |
1209 | } | 1211 | } |
1210 | len += snprintf(buf + len, PAGE_SIZE - len, | 1212 | len += scnprintf(buf + len, PAGE_SIZE - len, |
1211 | "Total FCP Cmpl %016llx Issue %016llx " | 1213 | "Total FCP Cmpl %016llx Issue %016llx " |
1212 | "OutIO %016llx\n", | 1214 | "OutIO %016llx\n", |
1213 | totin, totout, totout - totin); | 1215 | totin, totout, totout - totin); |
1214 | 1216 | ||
1215 | len += snprintf(buf + len, size - len, | 1217 | len += scnprintf(buf + len, size - len, |
1216 | "LS Xmt Err: Abrt %08x Err %08x " | 1218 | "LS Xmt Err: Abrt %08x Err %08x " |
1217 | "Cmpl Err: xb %08x Err %08x\n", | 1219 | "Cmpl Err: xb %08x Err %08x\n", |
1218 | atomic_read(&lport->xmt_ls_abort), | 1220 | atomic_read(&lport->xmt_ls_abort), |
@@ -1220,7 +1222,7 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size) | |||
1220 | atomic_read(&lport->cmpl_ls_xb), | 1222 | atomic_read(&lport->cmpl_ls_xb), |
1221 | atomic_read(&lport->cmpl_ls_err)); | 1223 | atomic_read(&lport->cmpl_ls_err)); |
1222 | 1224 | ||
1223 | len += snprintf(buf + len, size - len, | 1225 | len += scnprintf(buf + len, size - len, |
1224 | "FCP Xmt Err: noxri %06x nondlp %06x " | 1226 | "FCP Xmt Err: noxri %06x nondlp %06x " |
1225 | "qdepth %06x wqerr %06x err %06x Abrt %06x\n", | 1227 | "qdepth %06x wqerr %06x err %06x Abrt %06x\n", |
1226 | atomic_read(&lport->xmt_fcp_noxri), | 1228 | atomic_read(&lport->xmt_fcp_noxri), |
@@ -1230,7 +1232,7 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size) | |||
1230 | atomic_read(&lport->xmt_fcp_err), | 1232 | atomic_read(&lport->xmt_fcp_err), |
1231 | atomic_read(&lport->xmt_fcp_abort)); | 1233 | atomic_read(&lport->xmt_fcp_abort)); |
1232 | 1234 | ||
1233 | len += snprintf(buf + len, size - len, | 1235 | len += scnprintf(buf + len, size - len, |
1234 | "FCP Cmpl Err: xb %08x Err %08x\n", | 1236 | "FCP Cmpl Err: xb %08x Err %08x\n", |
1235 | atomic_read(&lport->cmpl_fcp_xb), | 1237 | atomic_read(&lport->cmpl_fcp_xb), |
1236 | atomic_read(&lport->cmpl_fcp_err)); | 1238 | atomic_read(&lport->cmpl_fcp_err)); |
@@ -1322,58 +1324,58 @@ lpfc_debugfs_nvmektime_data(struct lpfc_vport *vport, char *buf, int size) | |||
1322 | 1324 | ||
1323 | if (phba->nvmet_support == 0) { | 1325 | if (phba->nvmet_support == 0) { |
1324 | /* NVME Initiator */ | 1326 | /* NVME Initiator */ |
1325 | len += snprintf(buf + len, PAGE_SIZE - len, | 1327 | len += scnprintf(buf + len, PAGE_SIZE - len, |
1326 | "ktime %s: Total Samples: %lld\n", | 1328 | "ktime %s: Total Samples: %lld\n", |
1327 | (phba->ktime_on ? "Enabled" : "Disabled"), | 1329 | (phba->ktime_on ? "Enabled" : "Disabled"), |
1328 | phba->ktime_data_samples); | 1330 | phba->ktime_data_samples); |
1329 | if (phba->ktime_data_samples == 0) | 1331 | if (phba->ktime_data_samples == 0) |
1330 | return len; | 1332 | return len; |
1331 | 1333 | ||
1332 | len += snprintf( | 1334 | len += scnprintf( |
1333 | buf + len, PAGE_SIZE - len, | 1335 | buf + len, PAGE_SIZE - len, |
1334 | "Segment 1: Last NVME Cmd cmpl " | 1336 | "Segment 1: Last NVME Cmd cmpl " |
1335 | "done -to- Start of next NVME cnd (in driver)\n"); | 1337 | "done -to- Start of next NVME cnd (in driver)\n"); |
1336 | len += snprintf( | 1338 | len += scnprintf( |
1337 | buf + len, PAGE_SIZE - len, | 1339 | buf + len, PAGE_SIZE - len, |
1338 | "avg:%08lld min:%08lld max %08lld\n", | 1340 | "avg:%08lld min:%08lld max %08lld\n", |
1339 | div_u64(phba->ktime_seg1_total, | 1341 | div_u64(phba->ktime_seg1_total, |
1340 | phba->ktime_data_samples), | 1342 | phba->ktime_data_samples), |
1341 | phba->ktime_seg1_min, | 1343 | phba->ktime_seg1_min, |
1342 | phba->ktime_seg1_max); | 1344 | phba->ktime_seg1_max); |
1343 | len += snprintf( | 1345 | len += scnprintf( |
1344 | buf + len, PAGE_SIZE - len, | 1346 | buf + len, PAGE_SIZE - len, |
1345 | "Segment 2: Driver start of NVME cmd " | 1347 | "Segment 2: Driver start of NVME cmd " |
1346 | "-to- Firmware WQ doorbell\n"); | 1348 | "-to- Firmware WQ doorbell\n"); |
1347 | len += snprintf( | 1349 | len += scnprintf( |
1348 | buf + len, PAGE_SIZE - len, | 1350 | buf + len, PAGE_SIZE - len, |
1349 | "avg:%08lld min:%08lld max %08lld\n", | 1351 | "avg:%08lld min:%08lld max %08lld\n", |
1350 | div_u64(phba->ktime_seg2_total, | 1352 | div_u64(phba->ktime_seg2_total, |
1351 | phba->ktime_data_samples), | 1353 | phba->ktime_data_samples), |
1352 | phba->ktime_seg2_min, | 1354 | phba->ktime_seg2_min, |
1353 | phba->ktime_seg2_max); | 1355 | phba->ktime_seg2_max); |
1354 | len += snprintf( | 1356 | len += scnprintf( |
1355 | buf + len, PAGE_SIZE - len, | 1357 | buf + len, PAGE_SIZE - len, |
1356 | "Segment 3: Firmware WQ doorbell -to- " | 1358 | "Segment 3: Firmware WQ doorbell -to- " |
1357 | "MSI-X ISR cmpl\n"); | 1359 | "MSI-X ISR cmpl\n"); |
1358 | len += snprintf( | 1360 | len += scnprintf( |
1359 | buf + len, PAGE_SIZE - len, | 1361 | buf + len, PAGE_SIZE - len, |
1360 | "avg:%08lld min:%08lld max %08lld\n", | 1362 | "avg:%08lld min:%08lld max %08lld\n", |
1361 | div_u64(phba->ktime_seg3_total, | 1363 | div_u64(phba->ktime_seg3_total, |
1362 | phba->ktime_data_samples), | 1364 | phba->ktime_data_samples), |
1363 | phba->ktime_seg3_min, | 1365 | phba->ktime_seg3_min, |
1364 | phba->ktime_seg3_max); | 1366 | phba->ktime_seg3_max); |
1365 | len += snprintf( | 1367 | len += scnprintf( |
1366 | buf + len, PAGE_SIZE - len, | 1368 | buf + len, PAGE_SIZE - len, |
1367 | "Segment 4: MSI-X ISR cmpl -to- " | 1369 | "Segment 4: MSI-X ISR cmpl -to- " |
1368 | "NVME cmpl done\n"); | 1370 | "NVME cmpl done\n"); |
1369 | len += snprintf( | 1371 | len += scnprintf( |
1370 | buf + len, PAGE_SIZE - len, | 1372 | buf + len, PAGE_SIZE - len, |
1371 | "avg:%08lld min:%08lld max %08lld\n", | 1373 | "avg:%08lld min:%08lld max %08lld\n", |
1372 | div_u64(phba->ktime_seg4_total, | 1374 | div_u64(phba->ktime_seg4_total, |
1373 | phba->ktime_data_samples), | 1375 | phba->ktime_data_samples), |
1374 | phba->ktime_seg4_min, | 1376 | phba->ktime_seg4_min, |
1375 | phba->ktime_seg4_max); | 1377 | phba->ktime_seg4_max); |
1376 | len += snprintf( | 1378 | len += scnprintf( |
1377 | buf + len, PAGE_SIZE - len, | 1379 | buf + len, PAGE_SIZE - len, |
1378 | "Total IO avg time: %08lld\n", | 1380 | "Total IO avg time: %08lld\n", |
1379 | div_u64(phba->ktime_seg1_total + | 1381 | div_u64(phba->ktime_seg1_total + |
@@ -1385,7 +1387,7 @@ lpfc_debugfs_nvmektime_data(struct lpfc_vport *vport, char *buf, int size) | |||
1385 | } | 1387 | } |
1386 | 1388 | ||
1387 | /* NVME Target */ | 1389 | /* NVME Target */ |
1388 | len += snprintf(buf + len, PAGE_SIZE-len, | 1390 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1389 | "ktime %s: Total Samples: %lld %lld\n", | 1391 | "ktime %s: Total Samples: %lld %lld\n", |
1390 | (phba->ktime_on ? "Enabled" : "Disabled"), | 1392 | (phba->ktime_on ? "Enabled" : "Disabled"), |
1391 | phba->ktime_data_samples, | 1393 | phba->ktime_data_samples, |
@@ -1393,46 +1395,46 @@ lpfc_debugfs_nvmektime_data(struct lpfc_vport *vport, char *buf, int size) | |||
1393 | if (phba->ktime_data_samples == 0) | 1395 | if (phba->ktime_data_samples == 0) |
1394 | return len; | 1396 | return len; |
1395 | 1397 | ||
1396 | len += snprintf(buf + len, PAGE_SIZE-len, | 1398 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1397 | "Segment 1: MSI-X ISR Rcv cmd -to- " | 1399 | "Segment 1: MSI-X ISR Rcv cmd -to- " |
1398 | "cmd pass to NVME Layer\n"); | 1400 | "cmd pass to NVME Layer\n"); |
1399 | len += snprintf(buf + len, PAGE_SIZE-len, | 1401 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1400 | "avg:%08lld min:%08lld max %08lld\n", | 1402 | "avg:%08lld min:%08lld max %08lld\n", |
1401 | div_u64(phba->ktime_seg1_total, | 1403 | div_u64(phba->ktime_seg1_total, |
1402 | phba->ktime_data_samples), | 1404 | phba->ktime_data_samples), |
1403 | phba->ktime_seg1_min, | 1405 | phba->ktime_seg1_min, |
1404 | phba->ktime_seg1_max); | 1406 | phba->ktime_seg1_max); |
1405 | len += snprintf(buf + len, PAGE_SIZE-len, | 1407 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1406 | "Segment 2: cmd pass to NVME Layer- " | 1408 | "Segment 2: cmd pass to NVME Layer- " |
1407 | "-to- Driver rcv cmd OP (action)\n"); | 1409 | "-to- Driver rcv cmd OP (action)\n"); |
1408 | len += snprintf(buf + len, PAGE_SIZE-len, | 1410 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1409 | "avg:%08lld min:%08lld max %08lld\n", | 1411 | "avg:%08lld min:%08lld max %08lld\n", |
1410 | div_u64(phba->ktime_seg2_total, | 1412 | div_u64(phba->ktime_seg2_total, |
1411 | phba->ktime_data_samples), | 1413 | phba->ktime_data_samples), |
1412 | phba->ktime_seg2_min, | 1414 | phba->ktime_seg2_min, |
1413 | phba->ktime_seg2_max); | 1415 | phba->ktime_seg2_max); |
1414 | len += snprintf(buf + len, PAGE_SIZE-len, | 1416 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1415 | "Segment 3: Driver rcv cmd OP -to- " | 1417 | "Segment 3: Driver rcv cmd OP -to- " |
1416 | "Firmware WQ doorbell: cmd\n"); | 1418 | "Firmware WQ doorbell: cmd\n"); |
1417 | len += snprintf(buf + len, PAGE_SIZE-len, | 1419 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1418 | "avg:%08lld min:%08lld max %08lld\n", | 1420 | "avg:%08lld min:%08lld max %08lld\n", |
1419 | div_u64(phba->ktime_seg3_total, | 1421 | div_u64(phba->ktime_seg3_total, |
1420 | phba->ktime_data_samples), | 1422 | phba->ktime_data_samples), |
1421 | phba->ktime_seg3_min, | 1423 | phba->ktime_seg3_min, |
1422 | phba->ktime_seg3_max); | 1424 | phba->ktime_seg3_max); |
1423 | len += snprintf(buf + len, PAGE_SIZE-len, | 1425 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1424 | "Segment 4: Firmware WQ doorbell: cmd " | 1426 | "Segment 4: Firmware WQ doorbell: cmd " |
1425 | "-to- MSI-X ISR for cmd cmpl\n"); | 1427 | "-to- MSI-X ISR for cmd cmpl\n"); |
1426 | len += snprintf(buf + len, PAGE_SIZE-len, | 1428 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1427 | "avg:%08lld min:%08lld max %08lld\n", | 1429 | "avg:%08lld min:%08lld max %08lld\n", |
1428 | div_u64(phba->ktime_seg4_total, | 1430 | div_u64(phba->ktime_seg4_total, |
1429 | phba->ktime_data_samples), | 1431 | phba->ktime_data_samples), |
1430 | phba->ktime_seg4_min, | 1432 | phba->ktime_seg4_min, |
1431 | phba->ktime_seg4_max); | 1433 | phba->ktime_seg4_max); |
1432 | len += snprintf(buf + len, PAGE_SIZE-len, | 1434 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1433 | "Segment 5: MSI-X ISR for cmd cmpl " | 1435 | "Segment 5: MSI-X ISR for cmd cmpl " |
1434 | "-to- NVME layer passed cmd done\n"); | 1436 | "-to- NVME layer passed cmd done\n"); |
1435 | len += snprintf(buf + len, PAGE_SIZE-len, | 1437 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1436 | "avg:%08lld min:%08lld max %08lld\n", | 1438 | "avg:%08lld min:%08lld max %08lld\n", |
1437 | div_u64(phba->ktime_seg5_total, | 1439 | div_u64(phba->ktime_seg5_total, |
1438 | phba->ktime_data_samples), | 1440 | phba->ktime_data_samples), |
@@ -1440,10 +1442,10 @@ lpfc_debugfs_nvmektime_data(struct lpfc_vport *vport, char *buf, int size) | |||
1440 | phba->ktime_seg5_max); | 1442 | phba->ktime_seg5_max); |
1441 | 1443 | ||
1442 | if (phba->ktime_status_samples == 0) { | 1444 | if (phba->ktime_status_samples == 0) { |
1443 | len += snprintf(buf + len, PAGE_SIZE-len, | 1445 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1444 | "Total: cmd received by MSI-X ISR " | 1446 | "Total: cmd received by MSI-X ISR " |
1445 | "-to- cmd completed on wire\n"); | 1447 | "-to- cmd completed on wire\n"); |
1446 | len += snprintf(buf + len, PAGE_SIZE-len, | 1448 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1447 | "avg:%08lld min:%08lld " | 1449 | "avg:%08lld min:%08lld " |
1448 | "max %08lld\n", | 1450 | "max %08lld\n", |
1449 | div_u64(phba->ktime_seg10_total, | 1451 | div_u64(phba->ktime_seg10_total, |
@@ -1453,46 +1455,46 @@ lpfc_debugfs_nvmektime_data(struct lpfc_vport *vport, char *buf, int size) | |||
1453 | return len; | 1455 | return len; |
1454 | } | 1456 | } |
1455 | 1457 | ||
1456 | len += snprintf(buf + len, PAGE_SIZE-len, | 1458 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1457 | "Segment 6: NVME layer passed cmd done " | 1459 | "Segment 6: NVME layer passed cmd done " |
1458 | "-to- Driver rcv rsp status OP\n"); | 1460 | "-to- Driver rcv rsp status OP\n"); |
1459 | len += snprintf(buf + len, PAGE_SIZE-len, | 1461 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1460 | "avg:%08lld min:%08lld max %08lld\n", | 1462 | "avg:%08lld min:%08lld max %08lld\n", |
1461 | div_u64(phba->ktime_seg6_total, | 1463 | div_u64(phba->ktime_seg6_total, |
1462 | phba->ktime_status_samples), | 1464 | phba->ktime_status_samples), |
1463 | phba->ktime_seg6_min, | 1465 | phba->ktime_seg6_min, |
1464 | phba->ktime_seg6_max); | 1466 | phba->ktime_seg6_max); |
1465 | len += snprintf(buf + len, PAGE_SIZE-len, | 1467 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1466 | "Segment 7: Driver rcv rsp status OP " | 1468 | "Segment 7: Driver rcv rsp status OP " |
1467 | "-to- Firmware WQ doorbell: status\n"); | 1469 | "-to- Firmware WQ doorbell: status\n"); |
1468 | len += snprintf(buf + len, PAGE_SIZE-len, | 1470 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1469 | "avg:%08lld min:%08lld max %08lld\n", | 1471 | "avg:%08lld min:%08lld max %08lld\n", |
1470 | div_u64(phba->ktime_seg7_total, | 1472 | div_u64(phba->ktime_seg7_total, |
1471 | phba->ktime_status_samples), | 1473 | phba->ktime_status_samples), |
1472 | phba->ktime_seg7_min, | 1474 | phba->ktime_seg7_min, |
1473 | phba->ktime_seg7_max); | 1475 | phba->ktime_seg7_max); |
1474 | len += snprintf(buf + len, PAGE_SIZE-len, | 1476 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1475 | "Segment 8: Firmware WQ doorbell: status" | 1477 | "Segment 8: Firmware WQ doorbell: status" |
1476 | " -to- MSI-X ISR for status cmpl\n"); | 1478 | " -to- MSI-X ISR for status cmpl\n"); |
1477 | len += snprintf(buf + len, PAGE_SIZE-len, | 1479 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1478 | "avg:%08lld min:%08lld max %08lld\n", | 1480 | "avg:%08lld min:%08lld max %08lld\n", |
1479 | div_u64(phba->ktime_seg8_total, | 1481 | div_u64(phba->ktime_seg8_total, |
1480 | phba->ktime_status_samples), | 1482 | phba->ktime_status_samples), |
1481 | phba->ktime_seg8_min, | 1483 | phba->ktime_seg8_min, |
1482 | phba->ktime_seg8_max); | 1484 | phba->ktime_seg8_max); |
1483 | len += snprintf(buf + len, PAGE_SIZE-len, | 1485 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1484 | "Segment 9: MSI-X ISR for status cmpl " | 1486 | "Segment 9: MSI-X ISR for status cmpl " |
1485 | "-to- NVME layer passed status done\n"); | 1487 | "-to- NVME layer passed status done\n"); |
1486 | len += snprintf(buf + len, PAGE_SIZE-len, | 1488 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1487 | "avg:%08lld min:%08lld max %08lld\n", | 1489 | "avg:%08lld min:%08lld max %08lld\n", |
1488 | div_u64(phba->ktime_seg9_total, | 1490 | div_u64(phba->ktime_seg9_total, |
1489 | phba->ktime_status_samples), | 1491 | phba->ktime_status_samples), |
1490 | phba->ktime_seg9_min, | 1492 | phba->ktime_seg9_min, |
1491 | phba->ktime_seg9_max); | 1493 | phba->ktime_seg9_max); |
1492 | len += snprintf(buf + len, PAGE_SIZE-len, | 1494 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1493 | "Total: cmd received by MSI-X ISR -to- " | 1495 | "Total: cmd received by MSI-X ISR -to- " |
1494 | "cmd completed on wire\n"); | 1496 | "cmd completed on wire\n"); |
1495 | len += snprintf(buf + len, PAGE_SIZE-len, | 1497 | len += scnprintf(buf + len, PAGE_SIZE-len, |
1496 | "avg:%08lld min:%08lld max %08lld\n", | 1498 | "avg:%08lld min:%08lld max %08lld\n", |
1497 | div_u64(phba->ktime_seg10_total, | 1499 | div_u64(phba->ktime_seg10_total, |
1498 | phba->ktime_status_samples), | 1500 | phba->ktime_status_samples), |
@@ -1527,7 +1529,7 @@ lpfc_debugfs_nvmeio_trc_data(struct lpfc_hba *phba, char *buf, int size) | |||
1527 | (phba->nvmeio_trc_size - 1); | 1529 | (phba->nvmeio_trc_size - 1); |
1528 | skip = phba->nvmeio_trc_output_idx; | 1530 | skip = phba->nvmeio_trc_output_idx; |
1529 | 1531 | ||
1530 | len += snprintf(buf + len, size - len, | 1532 | len += scnprintf(buf + len, size - len, |
1531 | "%s IO Trace %s: next_idx %d skip %d size %d\n", | 1533 | "%s IO Trace %s: next_idx %d skip %d size %d\n", |
1532 | (phba->nvmet_support ? "NVME" : "NVMET"), | 1534 | (phba->nvmet_support ? "NVME" : "NVMET"), |
1533 | (state ? "Enabled" : "Disabled"), | 1535 | (state ? "Enabled" : "Disabled"), |
@@ -1549,18 +1551,18 @@ lpfc_debugfs_nvmeio_trc_data(struct lpfc_hba *phba, char *buf, int size) | |||
1549 | if (!dtp->fmt) | 1551 | if (!dtp->fmt) |
1550 | continue; | 1552 | continue; |
1551 | 1553 | ||
1552 | len += snprintf(buf + len, size - len, dtp->fmt, | 1554 | len += scnprintf(buf + len, size - len, dtp->fmt, |
1553 | dtp->data1, dtp->data2, dtp->data3); | 1555 | dtp->data1, dtp->data2, dtp->data3); |
1554 | 1556 | ||
1555 | if (phba->nvmeio_trc_output_idx >= phba->nvmeio_trc_size) { | 1557 | if (phba->nvmeio_trc_output_idx >= phba->nvmeio_trc_size) { |
1556 | phba->nvmeio_trc_output_idx = 0; | 1558 | phba->nvmeio_trc_output_idx = 0; |
1557 | len += snprintf(buf + len, size - len, | 1559 | len += scnprintf(buf + len, size - len, |
1558 | "Trace Complete\n"); | 1560 | "Trace Complete\n"); |
1559 | goto out; | 1561 | goto out; |
1560 | } | 1562 | } |
1561 | 1563 | ||
1562 | if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) { | 1564 | if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) { |
1563 | len += snprintf(buf + len, size - len, | 1565 | len += scnprintf(buf + len, size - len, |
1564 | "Trace Continue (%d of %d)\n", | 1566 | "Trace Continue (%d of %d)\n", |
1565 | phba->nvmeio_trc_output_idx, | 1567 | phba->nvmeio_trc_output_idx, |
1566 | phba->nvmeio_trc_size); | 1568 | phba->nvmeio_trc_size); |
@@ -1578,18 +1580,18 @@ lpfc_debugfs_nvmeio_trc_data(struct lpfc_hba *phba, char *buf, int size) | |||
1578 | if (!dtp->fmt) | 1580 | if (!dtp->fmt) |
1579 | continue; | 1581 | continue; |
1580 | 1582 | ||
1581 | len += snprintf(buf + len, size - len, dtp->fmt, | 1583 | len += scnprintf(buf + len, size - len, dtp->fmt, |
1582 | dtp->data1, dtp->data2, dtp->data3); | 1584 | dtp->data1, dtp->data2, dtp->data3); |
1583 | 1585 | ||
1584 | if (phba->nvmeio_trc_output_idx >= phba->nvmeio_trc_size) { | 1586 | if (phba->nvmeio_trc_output_idx >= phba->nvmeio_trc_size) { |
1585 | phba->nvmeio_trc_output_idx = 0; | 1587 | phba->nvmeio_trc_output_idx = 0; |
1586 | len += snprintf(buf + len, size - len, | 1588 | len += scnprintf(buf + len, size - len, |
1587 | "Trace Complete\n"); | 1589 | "Trace Complete\n"); |
1588 | goto out; | 1590 | goto out; |
1589 | } | 1591 | } |
1590 | 1592 | ||
1591 | if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) { | 1593 | if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) { |
1592 | len += snprintf(buf + len, size - len, | 1594 | len += scnprintf(buf + len, size - len, |
1593 | "Trace Continue (%d of %d)\n", | 1595 | "Trace Continue (%d of %d)\n", |
1594 | phba->nvmeio_trc_output_idx, | 1596 | phba->nvmeio_trc_output_idx, |
1595 | phba->nvmeio_trc_size); | 1597 | phba->nvmeio_trc_size); |
@@ -1597,7 +1599,7 @@ lpfc_debugfs_nvmeio_trc_data(struct lpfc_hba *phba, char *buf, int size) | |||
1597 | } | 1599 | } |
1598 | } | 1600 | } |
1599 | 1601 | ||
1600 | len += snprintf(buf + len, size - len, | 1602 | len += scnprintf(buf + len, size - len, |
1601 | "Trace Done\n"); | 1603 | "Trace Done\n"); |
1602 | out: | 1604 | out: |
1603 | return len; | 1605 | return len; |
@@ -1627,17 +1629,17 @@ lpfc_debugfs_cpucheck_data(struct lpfc_vport *vport, char *buf, int size) | |||
1627 | uint32_t tot_rcv; | 1629 | uint32_t tot_rcv; |
1628 | uint32_t tot_cmpl; | 1630 | uint32_t tot_cmpl; |
1629 | 1631 | ||
1630 | len += snprintf(buf + len, PAGE_SIZE - len, | 1632 | len += scnprintf(buf + len, PAGE_SIZE - len, |
1631 | "CPUcheck %s ", | 1633 | "CPUcheck %s ", |
1632 | (phba->cpucheck_on & LPFC_CHECK_NVME_IO ? | 1634 | (phba->cpucheck_on & LPFC_CHECK_NVME_IO ? |
1633 | "Enabled" : "Disabled")); | 1635 | "Enabled" : "Disabled")); |
1634 | if (phba->nvmet_support) { | 1636 | if (phba->nvmet_support) { |
1635 | len += snprintf(buf + len, PAGE_SIZE - len, | 1637 | len += scnprintf(buf + len, PAGE_SIZE - len, |
1636 | "%s\n", | 1638 | "%s\n", |
1637 | (phba->cpucheck_on & LPFC_CHECK_NVMET_RCV ? | 1639 | (phba->cpucheck_on & LPFC_CHECK_NVMET_RCV ? |
1638 | "Rcv Enabled\n" : "Rcv Disabled\n")); | 1640 | "Rcv Enabled\n" : "Rcv Disabled\n")); |
1639 | } else { | 1641 | } else { |
1640 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); | 1642 | len += scnprintf(buf + len, PAGE_SIZE - len, "\n"); |
1641 | } | 1643 | } |
1642 | max_cnt = size - LPFC_DEBUG_OUT_LINE_SZ; | 1644 | max_cnt = size - LPFC_DEBUG_OUT_LINE_SZ; |
1643 | 1645 | ||
@@ -1658,7 +1660,7 @@ lpfc_debugfs_cpucheck_data(struct lpfc_vport *vport, char *buf, int size) | |||
1658 | if (!tot_xmt && !tot_cmpl && !tot_rcv) | 1660 | if (!tot_xmt && !tot_cmpl && !tot_rcv) |
1659 | continue; | 1661 | continue; |
1660 | 1662 | ||
1661 | len += snprintf(buf + len, PAGE_SIZE - len, | 1663 | len += scnprintf(buf + len, PAGE_SIZE - len, |
1662 | "HDWQ %03d: ", i); | 1664 | "HDWQ %03d: ", i); |
1663 | for (j = 0; j < LPFC_CHECK_CPU_CNT; j++) { | 1665 | for (j = 0; j < LPFC_CHECK_CPU_CNT; j++) { |
1664 | /* Only display non-zero counters */ | 1666 | /* Only display non-zero counters */ |
@@ -1667,22 +1669,22 @@ lpfc_debugfs_cpucheck_data(struct lpfc_vport *vport, char *buf, int size) | |||
1667 | !qp->cpucheck_rcv_io[j]) | 1669 | !qp->cpucheck_rcv_io[j]) |
1668 | continue; | 1670 | continue; |
1669 | if (phba->nvmet_support) { | 1671 | if (phba->nvmet_support) { |
1670 | len += snprintf(buf + len, PAGE_SIZE - len, | 1672 | len += scnprintf(buf + len, PAGE_SIZE - len, |
1671 | "CPU %03d: %x/%x/%x ", j, | 1673 | "CPU %03d: %x/%x/%x ", j, |
1672 | qp->cpucheck_rcv_io[j], | 1674 | qp->cpucheck_rcv_io[j], |
1673 | qp->cpucheck_xmt_io[j], | 1675 | qp->cpucheck_xmt_io[j], |
1674 | qp->cpucheck_cmpl_io[j]); | 1676 | qp->cpucheck_cmpl_io[j]); |
1675 | } else { | 1677 | } else { |
1676 | len += snprintf(buf + len, PAGE_SIZE - len, | 1678 | len += scnprintf(buf + len, PAGE_SIZE - len, |
1677 | "CPU %03d: %x/%x ", j, | 1679 | "CPU %03d: %x/%x ", j, |
1678 | qp->cpucheck_xmt_io[j], | 1680 | qp->cpucheck_xmt_io[j], |
1679 | qp->cpucheck_cmpl_io[j]); | 1681 | qp->cpucheck_cmpl_io[j]); |
1680 | } | 1682 | } |
1681 | } | 1683 | } |
1682 | len += snprintf(buf + len, PAGE_SIZE - len, | 1684 | len += scnprintf(buf + len, PAGE_SIZE - len, |
1683 | "Total: %x\n", tot_xmt); | 1685 | "Total: %x\n", tot_xmt); |
1684 | if (len >= max_cnt) { | 1686 | if (len >= max_cnt) { |
1685 | len += snprintf(buf + len, PAGE_SIZE - len, | 1687 | len += scnprintf(buf + len, PAGE_SIZE - len, |
1686 | "Truncated ...\n"); | 1688 | "Truncated ...\n"); |
1687 | return len; | 1689 | return len; |
1688 | } | 1690 | } |
@@ -2258,28 +2260,29 @@ lpfc_debugfs_dif_err_read(struct file *file, char __user *buf, | |||
2258 | int cnt = 0; | 2260 | int cnt = 0; |
2259 | 2261 | ||
2260 | if (dent == phba->debug_writeGuard) | 2262 | if (dent == phba->debug_writeGuard) |
2261 | cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wgrd_cnt); | 2263 | cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wgrd_cnt); |
2262 | else if (dent == phba->debug_writeApp) | 2264 | else if (dent == phba->debug_writeApp) |
2263 | cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wapp_cnt); | 2265 | cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wapp_cnt); |
2264 | else if (dent == phba->debug_writeRef) | 2266 | else if (dent == phba->debug_writeRef) |
2265 | cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wref_cnt); | 2267 | cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wref_cnt); |
2266 | else if (dent == phba->debug_readGuard) | 2268 | else if (dent == phba->debug_readGuard) |
2267 | cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rgrd_cnt); | 2269 | cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rgrd_cnt); |
2268 | else if (dent == phba->debug_readApp) | 2270 | else if (dent == phba->debug_readApp) |
2269 | cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rapp_cnt); | 2271 | cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rapp_cnt); |
2270 | else if (dent == phba->debug_readRef) | 2272 | else if (dent == phba->debug_readRef) |
2271 | cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rref_cnt); | 2273 | cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rref_cnt); |
2272 | else if (dent == phba->debug_InjErrNPortID) | 2274 | else if (dent == phba->debug_InjErrNPortID) |
2273 | cnt = snprintf(cbuf, 32, "0x%06x\n", phba->lpfc_injerr_nportid); | 2275 | cnt = scnprintf(cbuf, 32, "0x%06x\n", |
2276 | phba->lpfc_injerr_nportid); | ||
2274 | else if (dent == phba->debug_InjErrWWPN) { | 2277 | else if (dent == phba->debug_InjErrWWPN) { |
2275 | memcpy(&tmp, &phba->lpfc_injerr_wwpn, sizeof(struct lpfc_name)); | 2278 | memcpy(&tmp, &phba->lpfc_injerr_wwpn, sizeof(struct lpfc_name)); |
2276 | tmp = cpu_to_be64(tmp); | 2279 | tmp = cpu_to_be64(tmp); |
2277 | cnt = snprintf(cbuf, 32, "0x%016llx\n", tmp); | 2280 | cnt = scnprintf(cbuf, 32, "0x%016llx\n", tmp); |
2278 | } else if (dent == phba->debug_InjErrLBA) { | 2281 | } else if (dent == phba->debug_InjErrLBA) { |
2279 | if (phba->lpfc_injerr_lba == (sector_t)(-1)) | 2282 | if (phba->lpfc_injerr_lba == (sector_t)(-1)) |
2280 | cnt = snprintf(cbuf, 32, "off\n"); | 2283 | cnt = scnprintf(cbuf, 32, "off\n"); |
2281 | else | 2284 | else |
2282 | cnt = snprintf(cbuf, 32, "0x%llx\n", | 2285 | cnt = scnprintf(cbuf, 32, "0x%llx\n", |
2283 | (uint64_t) phba->lpfc_injerr_lba); | 2286 | (uint64_t) phba->lpfc_injerr_lba); |
2284 | } else | 2287 | } else |
2285 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2288 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
@@ -3224,17 +3227,17 @@ lpfc_idiag_pcicfg_read(struct file *file, char __user *buf, size_t nbytes, | |||
3224 | switch (count) { | 3227 | switch (count) { |
3225 | case SIZE_U8: /* byte (8 bits) */ | 3228 | case SIZE_U8: /* byte (8 bits) */ |
3226 | pci_read_config_byte(pdev, where, &u8val); | 3229 | pci_read_config_byte(pdev, where, &u8val); |
3227 | len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, | 3230 | len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, |
3228 | "%03x: %02x\n", where, u8val); | 3231 | "%03x: %02x\n", where, u8val); |
3229 | break; | 3232 | break; |
3230 | case SIZE_U16: /* word (16 bits) */ | 3233 | case SIZE_U16: /* word (16 bits) */ |
3231 | pci_read_config_word(pdev, where, &u16val); | 3234 | pci_read_config_word(pdev, where, &u16val); |
3232 | len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, | 3235 | len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, |
3233 | "%03x: %04x\n", where, u16val); | 3236 | "%03x: %04x\n", where, u16val); |
3234 | break; | 3237 | break; |
3235 | case SIZE_U32: /* double word (32 bits) */ | 3238 | case SIZE_U32: /* double word (32 bits) */ |
3236 | pci_read_config_dword(pdev, where, &u32val); | 3239 | pci_read_config_dword(pdev, where, &u32val); |
3237 | len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, | 3240 | len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, |
3238 | "%03x: %08x\n", where, u32val); | 3241 | "%03x: %08x\n", where, u32val); |
3239 | break; | 3242 | break; |
3240 | case LPFC_PCI_CFG_BROWSE: /* browse all */ | 3243 | case LPFC_PCI_CFG_BROWSE: /* browse all */ |
@@ -3254,25 +3257,25 @@ pcicfg_browse: | |||
3254 | offset = offset_label; | 3257 | offset = offset_label; |
3255 | 3258 | ||
3256 | /* Read PCI config space */ | 3259 | /* Read PCI config space */ |
3257 | len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, | 3260 | len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, |
3258 | "%03x: ", offset_label); | 3261 | "%03x: ", offset_label); |
3259 | while (index > 0) { | 3262 | while (index > 0) { |
3260 | pci_read_config_dword(pdev, offset, &u32val); | 3263 | pci_read_config_dword(pdev, offset, &u32val); |
3261 | len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, | 3264 | len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, |
3262 | "%08x ", u32val); | 3265 | "%08x ", u32val); |
3263 | offset += sizeof(uint32_t); | 3266 | offset += sizeof(uint32_t); |
3264 | if (offset >= LPFC_PCI_CFG_SIZE) { | 3267 | if (offset >= LPFC_PCI_CFG_SIZE) { |
3265 | len += snprintf(pbuffer+len, | 3268 | len += scnprintf(pbuffer+len, |
3266 | LPFC_PCI_CFG_SIZE-len, "\n"); | 3269 | LPFC_PCI_CFG_SIZE-len, "\n"); |
3267 | break; | 3270 | break; |
3268 | } | 3271 | } |
3269 | index -= sizeof(uint32_t); | 3272 | index -= sizeof(uint32_t); |
3270 | if (!index) | 3273 | if (!index) |
3271 | len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, | 3274 | len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, |
3272 | "\n"); | 3275 | "\n"); |
3273 | else if (!(index % (8 * sizeof(uint32_t)))) { | 3276 | else if (!(index % (8 * sizeof(uint32_t)))) { |
3274 | offset_label += (8 * sizeof(uint32_t)); | 3277 | offset_label += (8 * sizeof(uint32_t)); |
3275 | len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, | 3278 | len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, |
3276 | "\n%03x: ", offset_label); | 3279 | "\n%03x: ", offset_label); |
3277 | } | 3280 | } |
3278 | } | 3281 | } |
@@ -3543,7 +3546,7 @@ lpfc_idiag_baracc_read(struct file *file, char __user *buf, size_t nbytes, | |||
3543 | if (acc_range == SINGLE_WORD) { | 3546 | if (acc_range == SINGLE_WORD) { |
3544 | offset_run = offset; | 3547 | offset_run = offset; |
3545 | u32val = readl(mem_mapped_bar + offset_run); | 3548 | u32val = readl(mem_mapped_bar + offset_run); |
3546 | len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len, | 3549 | len += scnprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len, |
3547 | "%05x: %08x\n", offset_run, u32val); | 3550 | "%05x: %08x\n", offset_run, u32val); |
3548 | } else | 3551 | } else |
3549 | goto baracc_browse; | 3552 | goto baracc_browse; |
@@ -3557,35 +3560,35 @@ baracc_browse: | |||
3557 | offset_run = offset_label; | 3560 | offset_run = offset_label; |
3558 | 3561 | ||
3559 | /* Read PCI bar memory mapped space */ | 3562 | /* Read PCI bar memory mapped space */ |
3560 | len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len, | 3563 | len += scnprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len, |
3561 | "%05x: ", offset_label); | 3564 | "%05x: ", offset_label); |
3562 | index = LPFC_PCI_BAR_RD_SIZE; | 3565 | index = LPFC_PCI_BAR_RD_SIZE; |
3563 | while (index > 0) { | 3566 | while (index > 0) { |
3564 | u32val = readl(mem_mapped_bar + offset_run); | 3567 | u32val = readl(mem_mapped_bar + offset_run); |
3565 | len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len, | 3568 | len += scnprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len, |
3566 | "%08x ", u32val); | 3569 | "%08x ", u32val); |
3567 | offset_run += sizeof(uint32_t); | 3570 | offset_run += sizeof(uint32_t); |
3568 | if (acc_range == LPFC_PCI_BAR_BROWSE) { | 3571 | if (acc_range == LPFC_PCI_BAR_BROWSE) { |
3569 | if (offset_run >= bar_size) { | 3572 | if (offset_run >= bar_size) { |
3570 | len += snprintf(pbuffer+len, | 3573 | len += scnprintf(pbuffer+len, |
3571 | LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n"); | 3574 | LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n"); |
3572 | break; | 3575 | break; |
3573 | } | 3576 | } |
3574 | } else { | 3577 | } else { |
3575 | if (offset_run >= offset + | 3578 | if (offset_run >= offset + |
3576 | (acc_range * sizeof(uint32_t))) { | 3579 | (acc_range * sizeof(uint32_t))) { |
3577 | len += snprintf(pbuffer+len, | 3580 | len += scnprintf(pbuffer+len, |
3578 | LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n"); | 3581 | LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n"); |
3579 | break; | 3582 | break; |
3580 | } | 3583 | } |
3581 | } | 3584 | } |
3582 | index -= sizeof(uint32_t); | 3585 | index -= sizeof(uint32_t); |
3583 | if (!index) | 3586 | if (!index) |
3584 | len += snprintf(pbuffer+len, | 3587 | len += scnprintf(pbuffer+len, |
3585 | LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n"); | 3588 | LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n"); |
3586 | else if (!(index % (8 * sizeof(uint32_t)))) { | 3589 | else if (!(index % (8 * sizeof(uint32_t)))) { |
3587 | offset_label += (8 * sizeof(uint32_t)); | 3590 | offset_label += (8 * sizeof(uint32_t)); |
3588 | len += snprintf(pbuffer+len, | 3591 | len += scnprintf(pbuffer+len, |
3589 | LPFC_PCI_BAR_RD_BUF_SIZE-len, | 3592 | LPFC_PCI_BAR_RD_BUF_SIZE-len, |
3590 | "\n%05x: ", offset_label); | 3593 | "\n%05x: ", offset_label); |
3591 | } | 3594 | } |
@@ -3758,19 +3761,19 @@ __lpfc_idiag_print_wq(struct lpfc_queue *qp, char *wqtype, | |||
3758 | if (!qp) | 3761 | if (!qp) |
3759 | return len; | 3762 | return len; |
3760 | 3763 | ||
3761 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, | 3764 | len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3762 | "\t\t%s WQ info: ", wqtype); | 3765 | "\t\t%s WQ info: ", wqtype); |
3763 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, | 3766 | len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3764 | "AssocCQID[%04d]: WQ-STAT[oflow:x%x posted:x%llx]\n", | 3767 | "AssocCQID[%04d]: WQ-STAT[oflow:x%x posted:x%llx]\n", |
3765 | qp->assoc_qid, qp->q_cnt_1, | 3768 | qp->assoc_qid, qp->q_cnt_1, |
3766 | (unsigned long long)qp->q_cnt_4); | 3769 | (unsigned long long)qp->q_cnt_4); |
3767 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, | 3770 | len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3768 | "\t\tWQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " | 3771 | "\t\tWQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " |
3769 | "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]", | 3772 | "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]", |
3770 | qp->queue_id, qp->entry_count, | 3773 | qp->queue_id, qp->entry_count, |
3771 | qp->entry_size, qp->host_index, | 3774 | qp->entry_size, qp->host_index, |
3772 | qp->hba_index, qp->notify_interval); | 3775 | qp->hba_index, qp->notify_interval); |
3773 | len += snprintf(pbuffer + len, | 3776 | len += scnprintf(pbuffer + len, |
3774 | LPFC_QUE_INFO_GET_BUF_SIZE - len, "\n"); | 3777 | LPFC_QUE_INFO_GET_BUF_SIZE - len, "\n"); |
3775 | return len; | 3778 | return len; |
3776 | } | 3779 | } |
@@ -3810,21 +3813,22 @@ __lpfc_idiag_print_cq(struct lpfc_queue *qp, char *cqtype, | |||
3810 | if (!qp) | 3813 | if (!qp) |
3811 | return len; | 3814 | return len; |
3812 | 3815 | ||
3813 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, | 3816 | len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3814 | "\t%s CQ info: ", cqtype); | 3817 | "\t%s CQ info: ", cqtype); |
3815 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, | 3818 | len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3816 | "AssocEQID[%02d]: CQ STAT[max:x%x relw:x%x " | 3819 | "AssocEQID[%02d]: CQ STAT[max:x%x relw:x%x " |
3817 | "xabt:x%x wq:x%llx]\n", | 3820 | "xabt:x%x wq:x%llx]\n", |
3818 | qp->assoc_qid, qp->q_cnt_1, qp->q_cnt_2, | 3821 | qp->assoc_qid, qp->q_cnt_1, qp->q_cnt_2, |
3819 | qp->q_cnt_3, (unsigned long long)qp->q_cnt_4); | 3822 | qp->q_cnt_3, (unsigned long long)qp->q_cnt_4); |
3820 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, | 3823 | len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3821 | "\tCQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " | 3824 | "\tCQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " |
3822 | "HST-IDX[%04d], NTFI[%03d], PLMT[%03d]", | 3825 | "HST-IDX[%04d], NTFI[%03d], PLMT[%03d]", |
3823 | qp->queue_id, qp->entry_count, | 3826 | qp->queue_id, qp->entry_count, |
3824 | qp->entry_size, qp->host_index, | 3827 | qp->entry_size, qp->host_index, |
3825 | qp->notify_interval, qp->max_proc_limit); | 3828 | qp->notify_interval, qp->max_proc_limit); |
3826 | 3829 | ||
3827 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, "\n"); | 3830 | len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3831 | "\n"); | ||
3828 | 3832 | ||
3829 | return len; | 3833 | return len; |
3830 | } | 3834 | } |
@@ -3836,19 +3840,19 @@ __lpfc_idiag_print_rqpair(struct lpfc_queue *qp, struct lpfc_queue *datqp, | |||
3836 | if (!qp || !datqp) | 3840 | if (!qp || !datqp) |
3837 | return len; | 3841 | return len; |
3838 | 3842 | ||
3839 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, | 3843 | len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3840 | "\t\t%s RQ info: ", rqtype); | 3844 | "\t\t%s RQ info: ", rqtype); |
3841 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, | 3845 | len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3842 | "AssocCQID[%02d]: RQ-STAT[nopost:x%x nobuf:x%x " | 3846 | "AssocCQID[%02d]: RQ-STAT[nopost:x%x nobuf:x%x " |
3843 | "posted:x%x rcv:x%llx]\n", | 3847 | "posted:x%x rcv:x%llx]\n", |
3844 | qp->assoc_qid, qp->q_cnt_1, qp->q_cnt_2, | 3848 | qp->assoc_qid, qp->q_cnt_1, qp->q_cnt_2, |
3845 | qp->q_cnt_3, (unsigned long long)qp->q_cnt_4); | 3849 | qp->q_cnt_3, (unsigned long long)qp->q_cnt_4); |
3846 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, | 3850 | len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3847 | "\t\tHQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " | 3851 | "\t\tHQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " |
3848 | "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]\n", | 3852 | "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]\n", |
3849 | qp->queue_id, qp->entry_count, qp->entry_size, | 3853 | qp->queue_id, qp->entry_count, qp->entry_size, |
3850 | qp->host_index, qp->hba_index, qp->notify_interval); | 3854 | qp->host_index, qp->hba_index, qp->notify_interval); |
3851 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, | 3855 | len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3852 | "\t\tDQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " | 3856 | "\t\tDQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " |
3853 | "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]\n", | 3857 | "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]\n", |
3854 | datqp->queue_id, datqp->entry_count, | 3858 | datqp->queue_id, datqp->entry_count, |
@@ -3927,18 +3931,19 @@ __lpfc_idiag_print_eq(struct lpfc_queue *qp, char *eqtype, | |||
3927 | if (!qp) | 3931 | if (!qp) |
3928 | return len; | 3932 | return len; |
3929 | 3933 | ||
3930 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, | 3934 | len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3931 | "\n%s EQ info: EQ-STAT[max:x%x noE:x%x " | 3935 | "\n%s EQ info: EQ-STAT[max:x%x noE:x%x " |
3932 | "cqe_proc:x%x eqe_proc:x%llx eqd %d]\n", | 3936 | "cqe_proc:x%x eqe_proc:x%llx eqd %d]\n", |
3933 | eqtype, qp->q_cnt_1, qp->q_cnt_2, qp->q_cnt_3, | 3937 | eqtype, qp->q_cnt_1, qp->q_cnt_2, qp->q_cnt_3, |
3934 | (unsigned long long)qp->q_cnt_4, qp->q_mode); | 3938 | (unsigned long long)qp->q_cnt_4, qp->q_mode); |
3935 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, | 3939 | len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3936 | "EQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " | 3940 | "EQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " |
3937 | "HST-IDX[%04d], NTFI[%03d], PLMT[%03d], AFFIN[%03d]", | 3941 | "HST-IDX[%04d], NTFI[%03d], PLMT[%03d], AFFIN[%03d]", |
3938 | qp->queue_id, qp->entry_count, qp->entry_size, | 3942 | qp->queue_id, qp->entry_count, qp->entry_size, |
3939 | qp->host_index, qp->notify_interval, | 3943 | qp->host_index, qp->notify_interval, |
3940 | qp->max_proc_limit, qp->chann); | 3944 | qp->max_proc_limit, qp->chann); |
3941 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, "\n"); | 3945 | len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3946 | "\n"); | ||
3942 | 3947 | ||
3943 | return len; | 3948 | return len; |
3944 | } | 3949 | } |
@@ -3991,9 +3996,10 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, | |||
3991 | if (phba->lpfc_idiag_last_eq >= phba->cfg_hdw_queue) | 3996 | if (phba->lpfc_idiag_last_eq >= phba->cfg_hdw_queue) |
3992 | phba->lpfc_idiag_last_eq = 0; | 3997 | phba->lpfc_idiag_last_eq = 0; |
3993 | 3998 | ||
3994 | len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, | 3999 | len += scnprintf(pbuffer + len, |
3995 | "HDWQ %d out of %d HBA HDWQs\n", | 4000 | LPFC_QUE_INFO_GET_BUF_SIZE - len, |
3996 | x, phba->cfg_hdw_queue); | 4001 | "HDWQ %d out of %d HBA HDWQs\n", |
4002 | x, phba->cfg_hdw_queue); | ||
3997 | 4003 | ||
3998 | /* Fast-path EQ */ | 4004 | /* Fast-path EQ */ |
3999 | qp = phba->sli4_hba.hdwq[x].hba_eq; | 4005 | qp = phba->sli4_hba.hdwq[x].hba_eq; |
@@ -4075,7 +4081,7 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, | |||
4075 | return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); | 4081 | return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); |
4076 | 4082 | ||
4077 | too_big: | 4083 | too_big: |
4078 | len += snprintf(pbuffer + len, | 4084 | len += scnprintf(pbuffer + len, |
4079 | LPFC_QUE_INFO_GET_BUF_SIZE - len, "Truncated ...\n"); | 4085 | LPFC_QUE_INFO_GET_BUF_SIZE - len, "Truncated ...\n"); |
4080 | out: | 4086 | out: |
4081 | spin_unlock_irq(&phba->hbalock); | 4087 | spin_unlock_irq(&phba->hbalock); |
@@ -4131,22 +4137,22 @@ lpfc_idiag_queacc_read_qe(char *pbuffer, int len, struct lpfc_queue *pque, | |||
4131 | return 0; | 4137 | return 0; |
4132 | 4138 | ||
4133 | esize = pque->entry_size; | 4139 | esize = pque->entry_size; |
4134 | len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, | 4140 | len += scnprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, |
4135 | "QE-INDEX[%04d]:\n", index); | 4141 | "QE-INDEX[%04d]:\n", index); |
4136 | 4142 | ||
4137 | offset = 0; | 4143 | offset = 0; |
4138 | pentry = pque->qe[index].address; | 4144 | pentry = lpfc_sli4_qe(pque, index); |
4139 | while (esize > 0) { | 4145 | while (esize > 0) { |
4140 | len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, | 4146 | len += scnprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, |
4141 | "%08x ", *pentry); | 4147 | "%08x ", *pentry); |
4142 | pentry++; | 4148 | pentry++; |
4143 | offset += sizeof(uint32_t); | 4149 | offset += sizeof(uint32_t); |
4144 | esize -= sizeof(uint32_t); | 4150 | esize -= sizeof(uint32_t); |
4145 | if (esize > 0 && !(offset % (4 * sizeof(uint32_t)))) | 4151 | if (esize > 0 && !(offset % (4 * sizeof(uint32_t)))) |
4146 | len += snprintf(pbuffer+len, | 4152 | len += scnprintf(pbuffer+len, |
4147 | LPFC_QUE_ACC_BUF_SIZE-len, "\n"); | 4153 | LPFC_QUE_ACC_BUF_SIZE-len, "\n"); |
4148 | } | 4154 | } |
4149 | len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, "\n"); | 4155 | len += scnprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, "\n"); |
4150 | 4156 | ||
4151 | return len; | 4157 | return len; |
4152 | } | 4158 | } |
@@ -4485,7 +4491,7 @@ pass_check: | |||
4485 | pque = (struct lpfc_queue *)idiag.ptr_private; | 4491 | pque = (struct lpfc_queue *)idiag.ptr_private; |
4486 | if (offset > pque->entry_size/sizeof(uint32_t) - 1) | 4492 | if (offset > pque->entry_size/sizeof(uint32_t) - 1) |
4487 | goto error_out; | 4493 | goto error_out; |
4488 | pentry = pque->qe[index].address; | 4494 | pentry = lpfc_sli4_qe(pque, index); |
4489 | pentry += offset; | 4495 | pentry += offset; |
4490 | if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR) | 4496 | if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR) |
4491 | *pentry = value; | 4497 | *pentry = value; |
@@ -4506,7 +4512,7 @@ error_out: | |||
4506 | * lpfc_idiag_drbacc_read_reg - idiag debugfs read a doorbell register | 4512 | * lpfc_idiag_drbacc_read_reg - idiag debugfs read a doorbell register |
4507 | * @phba: The pointer to hba structure. | 4513 | * @phba: The pointer to hba structure. |
4508 | * @pbuffer: The pointer to the buffer to copy the data to. | 4514 | * @pbuffer: The pointer to the buffer to copy the data to. |
4509 | * @len: The lenght of bytes to copied. | 4515 | * @len: The length of bytes to copied. |
4510 | * @drbregid: The id to doorbell registers. | 4516 | * @drbregid: The id to doorbell registers. |
4511 | * | 4517 | * |
4512 | * Description: | 4518 | * Description: |
@@ -4526,27 +4532,27 @@ lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char *pbuffer, | |||
4526 | 4532 | ||
4527 | switch (drbregid) { | 4533 | switch (drbregid) { |
4528 | case LPFC_DRB_EQ: | 4534 | case LPFC_DRB_EQ: |
4529 | len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE-len, | 4535 | len += scnprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE-len, |
4530 | "EQ-DRB-REG: 0x%08x\n", | 4536 | "EQ-DRB-REG: 0x%08x\n", |
4531 | readl(phba->sli4_hba.EQDBregaddr)); | 4537 | readl(phba->sli4_hba.EQDBregaddr)); |
4532 | break; | 4538 | break; |
4533 | case LPFC_DRB_CQ: | 4539 | case LPFC_DRB_CQ: |
4534 | len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE - len, | 4540 | len += scnprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE - len, |
4535 | "CQ-DRB-REG: 0x%08x\n", | 4541 | "CQ-DRB-REG: 0x%08x\n", |
4536 | readl(phba->sli4_hba.CQDBregaddr)); | 4542 | readl(phba->sli4_hba.CQDBregaddr)); |
4537 | break; | 4543 | break; |
4538 | case LPFC_DRB_MQ: | 4544 | case LPFC_DRB_MQ: |
4539 | len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len, | 4545 | len += scnprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len, |
4540 | "MQ-DRB-REG: 0x%08x\n", | 4546 | "MQ-DRB-REG: 0x%08x\n", |
4541 | readl(phba->sli4_hba.MQDBregaddr)); | 4547 | readl(phba->sli4_hba.MQDBregaddr)); |
4542 | break; | 4548 | break; |
4543 | case LPFC_DRB_WQ: | 4549 | case LPFC_DRB_WQ: |
4544 | len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len, | 4550 | len += scnprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len, |
4545 | "WQ-DRB-REG: 0x%08x\n", | 4551 | "WQ-DRB-REG: 0x%08x\n", |
4546 | readl(phba->sli4_hba.WQDBregaddr)); | 4552 | readl(phba->sli4_hba.WQDBregaddr)); |
4547 | break; | 4553 | break; |
4548 | case LPFC_DRB_RQ: | 4554 | case LPFC_DRB_RQ: |
4549 | len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len, | 4555 | len += scnprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len, |
4550 | "RQ-DRB-REG: 0x%08x\n", | 4556 | "RQ-DRB-REG: 0x%08x\n", |
4551 | readl(phba->sli4_hba.RQDBregaddr)); | 4557 | readl(phba->sli4_hba.RQDBregaddr)); |
4552 | break; | 4558 | break; |
@@ -4716,7 +4722,7 @@ error_out: | |||
4716 | * lpfc_idiag_ctlacc_read_reg - idiag debugfs read a control registers | 4722 | * lpfc_idiag_ctlacc_read_reg - idiag debugfs read a control registers |
4717 | * @phba: The pointer to hba structure. | 4723 | * @phba: The pointer to hba structure. |
4718 | * @pbuffer: The pointer to the buffer to copy the data to. | 4724 | * @pbuffer: The pointer to the buffer to copy the data to. |
4719 | * @len: The lenght of bytes to copied. | 4725 | * @len: The length of bytes to copied. |
4720 | * @drbregid: The id to doorbell registers. | 4726 | * @drbregid: The id to doorbell registers. |
4721 | * | 4727 | * |
4722 | * Description: | 4728 | * Description: |
@@ -4736,37 +4742,37 @@ lpfc_idiag_ctlacc_read_reg(struct lpfc_hba *phba, char *pbuffer, | |||
4736 | 4742 | ||
4737 | switch (ctlregid) { | 4743 | switch (ctlregid) { |
4738 | case LPFC_CTL_PORT_SEM: | 4744 | case LPFC_CTL_PORT_SEM: |
4739 | len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, | 4745 | len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, |
4740 | "Port SemReg: 0x%08x\n", | 4746 | "Port SemReg: 0x%08x\n", |
4741 | readl(phba->sli4_hba.conf_regs_memmap_p + | 4747 | readl(phba->sli4_hba.conf_regs_memmap_p + |
4742 | LPFC_CTL_PORT_SEM_OFFSET)); | 4748 | LPFC_CTL_PORT_SEM_OFFSET)); |
4743 | break; | 4749 | break; |
4744 | case LPFC_CTL_PORT_STA: | 4750 | case LPFC_CTL_PORT_STA: |
4745 | len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, | 4751 | len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, |
4746 | "Port StaReg: 0x%08x\n", | 4752 | "Port StaReg: 0x%08x\n", |
4747 | readl(phba->sli4_hba.conf_regs_memmap_p + | 4753 | readl(phba->sli4_hba.conf_regs_memmap_p + |
4748 | LPFC_CTL_PORT_STA_OFFSET)); | 4754 | LPFC_CTL_PORT_STA_OFFSET)); |
4749 | break; | 4755 | break; |
4750 | case LPFC_CTL_PORT_CTL: | 4756 | case LPFC_CTL_PORT_CTL: |
4751 | len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, | 4757 | len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, |
4752 | "Port CtlReg: 0x%08x\n", | 4758 | "Port CtlReg: 0x%08x\n", |
4753 | readl(phba->sli4_hba.conf_regs_memmap_p + | 4759 | readl(phba->sli4_hba.conf_regs_memmap_p + |
4754 | LPFC_CTL_PORT_CTL_OFFSET)); | 4760 | LPFC_CTL_PORT_CTL_OFFSET)); |
4755 | break; | 4761 | break; |
4756 | case LPFC_CTL_PORT_ER1: | 4762 | case LPFC_CTL_PORT_ER1: |
4757 | len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, | 4763 | len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, |
4758 | "Port Er1Reg: 0x%08x\n", | 4764 | "Port Er1Reg: 0x%08x\n", |
4759 | readl(phba->sli4_hba.conf_regs_memmap_p + | 4765 | readl(phba->sli4_hba.conf_regs_memmap_p + |
4760 | LPFC_CTL_PORT_ER1_OFFSET)); | 4766 | LPFC_CTL_PORT_ER1_OFFSET)); |
4761 | break; | 4767 | break; |
4762 | case LPFC_CTL_PORT_ER2: | 4768 | case LPFC_CTL_PORT_ER2: |
4763 | len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, | 4769 | len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, |
4764 | "Port Er2Reg: 0x%08x\n", | 4770 | "Port Er2Reg: 0x%08x\n", |
4765 | readl(phba->sli4_hba.conf_regs_memmap_p + | 4771 | readl(phba->sli4_hba.conf_regs_memmap_p + |
4766 | LPFC_CTL_PORT_ER2_OFFSET)); | 4772 | LPFC_CTL_PORT_ER2_OFFSET)); |
4767 | break; | 4773 | break; |
4768 | case LPFC_CTL_PDEV_CTL: | 4774 | case LPFC_CTL_PDEV_CTL: |
4769 | len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, | 4775 | len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, |
4770 | "PDev CtlReg: 0x%08x\n", | 4776 | "PDev CtlReg: 0x%08x\n", |
4771 | readl(phba->sli4_hba.conf_regs_memmap_p + | 4777 | readl(phba->sli4_hba.conf_regs_memmap_p + |
4772 | LPFC_CTL_PDEV_CTL_OFFSET)); | 4778 | LPFC_CTL_PDEV_CTL_OFFSET)); |
@@ -4959,13 +4965,13 @@ lpfc_idiag_mbxacc_get_setup(struct lpfc_hba *phba, char *pbuffer) | |||
4959 | mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX]; | 4965 | mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX]; |
4960 | mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX]; | 4966 | mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX]; |
4961 | 4967 | ||
4962 | len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len, | 4968 | len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len, |
4963 | "mbx_dump_map: 0x%08x\n", mbx_dump_map); | 4969 | "mbx_dump_map: 0x%08x\n", mbx_dump_map); |
4964 | len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len, | 4970 | len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len, |
4965 | "mbx_dump_cnt: %04d\n", mbx_dump_cnt); | 4971 | "mbx_dump_cnt: %04d\n", mbx_dump_cnt); |
4966 | len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len, | 4972 | len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len, |
4967 | "mbx_word_cnt: %04d\n", mbx_word_cnt); | 4973 | "mbx_word_cnt: %04d\n", mbx_word_cnt); |
4968 | len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len, | 4974 | len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len, |
4969 | "mbx_mbox_cmd: 0x%02x\n", mbx_mbox_cmd); | 4975 | "mbx_mbox_cmd: 0x%02x\n", mbx_mbox_cmd); |
4970 | 4976 | ||
4971 | return len; | 4977 | return len; |
@@ -5114,35 +5120,35 @@ lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len) | |||
5114 | { | 5120 | { |
5115 | uint16_t ext_cnt, ext_size; | 5121 | uint16_t ext_cnt, ext_size; |
5116 | 5122 | ||
5117 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5123 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5118 | "\nAvailable Extents Information:\n"); | 5124 | "\nAvailable Extents Information:\n"); |
5119 | 5125 | ||
5120 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5126 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5121 | "\tPort Available VPI extents: "); | 5127 | "\tPort Available VPI extents: "); |
5122 | lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VPI, | 5128 | lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VPI, |
5123 | &ext_cnt, &ext_size); | 5129 | &ext_cnt, &ext_size); |
5124 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5130 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5125 | "Count %3d, Size %3d\n", ext_cnt, ext_size); | 5131 | "Count %3d, Size %3d\n", ext_cnt, ext_size); |
5126 | 5132 | ||
5127 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5133 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5128 | "\tPort Available VFI extents: "); | 5134 | "\tPort Available VFI extents: "); |
5129 | lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VFI, | 5135 | lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VFI, |
5130 | &ext_cnt, &ext_size); | 5136 | &ext_cnt, &ext_size); |
5131 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5137 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5132 | "Count %3d, Size %3d\n", ext_cnt, ext_size); | 5138 | "Count %3d, Size %3d\n", ext_cnt, ext_size); |
5133 | 5139 | ||
5134 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5140 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5135 | "\tPort Available RPI extents: "); | 5141 | "\tPort Available RPI extents: "); |
5136 | lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_RPI, | 5142 | lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_RPI, |
5137 | &ext_cnt, &ext_size); | 5143 | &ext_cnt, &ext_size); |
5138 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5144 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5139 | "Count %3d, Size %3d\n", ext_cnt, ext_size); | 5145 | "Count %3d, Size %3d\n", ext_cnt, ext_size); |
5140 | 5146 | ||
5141 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5147 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5142 | "\tPort Available XRI extents: "); | 5148 | "\tPort Available XRI extents: "); |
5143 | lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_XRI, | 5149 | lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_XRI, |
5144 | &ext_cnt, &ext_size); | 5150 | &ext_cnt, &ext_size); |
5145 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5151 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5146 | "Count %3d, Size %3d\n", ext_cnt, ext_size); | 5152 | "Count %3d, Size %3d\n", ext_cnt, ext_size); |
5147 | 5153 | ||
5148 | return len; | 5154 | return len; |
@@ -5166,55 +5172,55 @@ lpfc_idiag_extacc_alloc_get(struct lpfc_hba *phba, char *pbuffer, int len) | |||
5166 | uint16_t ext_cnt, ext_size; | 5172 | uint16_t ext_cnt, ext_size; |
5167 | int rc; | 5173 | int rc; |
5168 | 5174 | ||
5169 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5175 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5170 | "\nAllocated Extents Information:\n"); | 5176 | "\nAllocated Extents Information:\n"); |
5171 | 5177 | ||
5172 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5178 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5173 | "\tHost Allocated VPI extents: "); | 5179 | "\tHost Allocated VPI extents: "); |
5174 | rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VPI, | 5180 | rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VPI, |
5175 | &ext_cnt, &ext_size); | 5181 | &ext_cnt, &ext_size); |
5176 | if (!rc) | 5182 | if (!rc) |
5177 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5183 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5178 | "Port %d Extent %3d, Size %3d\n", | 5184 | "Port %d Extent %3d, Size %3d\n", |
5179 | phba->brd_no, ext_cnt, ext_size); | 5185 | phba->brd_no, ext_cnt, ext_size); |
5180 | else | 5186 | else |
5181 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5187 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5182 | "N/A\n"); | 5188 | "N/A\n"); |
5183 | 5189 | ||
5184 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5190 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5185 | "\tHost Allocated VFI extents: "); | 5191 | "\tHost Allocated VFI extents: "); |
5186 | rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VFI, | 5192 | rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VFI, |
5187 | &ext_cnt, &ext_size); | 5193 | &ext_cnt, &ext_size); |
5188 | if (!rc) | 5194 | if (!rc) |
5189 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5195 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5190 | "Port %d Extent %3d, Size %3d\n", | 5196 | "Port %d Extent %3d, Size %3d\n", |
5191 | phba->brd_no, ext_cnt, ext_size); | 5197 | phba->brd_no, ext_cnt, ext_size); |
5192 | else | 5198 | else |
5193 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5199 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5194 | "N/A\n"); | 5200 | "N/A\n"); |
5195 | 5201 | ||
5196 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5202 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5197 | "\tHost Allocated RPI extents: "); | 5203 | "\tHost Allocated RPI extents: "); |
5198 | rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_RPI, | 5204 | rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_RPI, |
5199 | &ext_cnt, &ext_size); | 5205 | &ext_cnt, &ext_size); |
5200 | if (!rc) | 5206 | if (!rc) |
5201 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5207 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5202 | "Port %d Extent %3d, Size %3d\n", | 5208 | "Port %d Extent %3d, Size %3d\n", |
5203 | phba->brd_no, ext_cnt, ext_size); | 5209 | phba->brd_no, ext_cnt, ext_size); |
5204 | else | 5210 | else |
5205 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5211 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5206 | "N/A\n"); | 5212 | "N/A\n"); |
5207 | 5213 | ||
5208 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5214 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5209 | "\tHost Allocated XRI extents: "); | 5215 | "\tHost Allocated XRI extents: "); |
5210 | rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_XRI, | 5216 | rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_XRI, |
5211 | &ext_cnt, &ext_size); | 5217 | &ext_cnt, &ext_size); |
5212 | if (!rc) | 5218 | if (!rc) |
5213 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5219 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5214 | "Port %d Extent %3d, Size %3d\n", | 5220 | "Port %d Extent %3d, Size %3d\n", |
5215 | phba->brd_no, ext_cnt, ext_size); | 5221 | phba->brd_no, ext_cnt, ext_size); |
5216 | else | 5222 | else |
5217 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5223 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5218 | "N/A\n"); | 5224 | "N/A\n"); |
5219 | 5225 | ||
5220 | return len; | 5226 | return len; |
@@ -5238,49 +5244,49 @@ lpfc_idiag_extacc_drivr_get(struct lpfc_hba *phba, char *pbuffer, int len) | |||
5238 | struct lpfc_rsrc_blks *rsrc_blks; | 5244 | struct lpfc_rsrc_blks *rsrc_blks; |
5239 | int index; | 5245 | int index; |
5240 | 5246 | ||
5241 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5247 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5242 | "\nDriver Extents Information:\n"); | 5248 | "\nDriver Extents Information:\n"); |
5243 | 5249 | ||
5244 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5250 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5245 | "\tVPI extents:\n"); | 5251 | "\tVPI extents:\n"); |
5246 | index = 0; | 5252 | index = 0; |
5247 | list_for_each_entry(rsrc_blks, &phba->lpfc_vpi_blk_list, list) { | 5253 | list_for_each_entry(rsrc_blks, &phba->lpfc_vpi_blk_list, list) { |
5248 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5254 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5249 | "\t\tBlock %3d: Start %4d, Count %4d\n", | 5255 | "\t\tBlock %3d: Start %4d, Count %4d\n", |
5250 | index, rsrc_blks->rsrc_start, | 5256 | index, rsrc_blks->rsrc_start, |
5251 | rsrc_blks->rsrc_size); | 5257 | rsrc_blks->rsrc_size); |
5252 | index++; | 5258 | index++; |
5253 | } | 5259 | } |
5254 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5260 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5255 | "\tVFI extents:\n"); | 5261 | "\tVFI extents:\n"); |
5256 | index = 0; | 5262 | index = 0; |
5257 | list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_vfi_blk_list, | 5263 | list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_vfi_blk_list, |
5258 | list) { | 5264 | list) { |
5259 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5265 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5260 | "\t\tBlock %3d: Start %4d, Count %4d\n", | 5266 | "\t\tBlock %3d: Start %4d, Count %4d\n", |
5261 | index, rsrc_blks->rsrc_start, | 5267 | index, rsrc_blks->rsrc_start, |
5262 | rsrc_blks->rsrc_size); | 5268 | rsrc_blks->rsrc_size); |
5263 | index++; | 5269 | index++; |
5264 | } | 5270 | } |
5265 | 5271 | ||
5266 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5272 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5267 | "\tRPI extents:\n"); | 5273 | "\tRPI extents:\n"); |
5268 | index = 0; | 5274 | index = 0; |
5269 | list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_rpi_blk_list, | 5275 | list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_rpi_blk_list, |
5270 | list) { | 5276 | list) { |
5271 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5277 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5272 | "\t\tBlock %3d: Start %4d, Count %4d\n", | 5278 | "\t\tBlock %3d: Start %4d, Count %4d\n", |
5273 | index, rsrc_blks->rsrc_start, | 5279 | index, rsrc_blks->rsrc_start, |
5274 | rsrc_blks->rsrc_size); | 5280 | rsrc_blks->rsrc_size); |
5275 | index++; | 5281 | index++; |
5276 | } | 5282 | } |
5277 | 5283 | ||
5278 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5284 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5279 | "\tXRI extents:\n"); | 5285 | "\tXRI extents:\n"); |
5280 | index = 0; | 5286 | index = 0; |
5281 | list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_xri_blk_list, | 5287 | list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_xri_blk_list, |
5282 | list) { | 5288 | list) { |
5283 | len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, | 5289 | len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, |
5284 | "\t\tBlock %3d: Start %4d, Count %4d\n", | 5290 | "\t\tBlock %3d: Start %4d, Count %4d\n", |
5285 | index, rsrc_blks->rsrc_start, | 5291 | index, rsrc_blks->rsrc_start, |
5286 | rsrc_blks->rsrc_size); | 5292 | rsrc_blks->rsrc_size); |
@@ -5706,11 +5712,11 @@ lpfc_idiag_mbxacc_dump_bsg_mbox(struct lpfc_hba *phba, enum nemb_type nemb_tp, | |||
5706 | if (i != 0) | 5712 | if (i != 0) |
5707 | pr_err("%s\n", line_buf); | 5713 | pr_err("%s\n", line_buf); |
5708 | len = 0; | 5714 | len = 0; |
5709 | len += snprintf(line_buf+len, | 5715 | len += scnprintf(line_buf+len, |
5710 | LPFC_MBX_ACC_LBUF_SZ-len, | 5716 | LPFC_MBX_ACC_LBUF_SZ-len, |
5711 | "%03d: ", i); | 5717 | "%03d: ", i); |
5712 | } | 5718 | } |
5713 | len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len, | 5719 | len += scnprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len, |
5714 | "%08x ", (uint32_t)*pword); | 5720 | "%08x ", (uint32_t)*pword); |
5715 | pword++; | 5721 | pword++; |
5716 | } | 5722 | } |
@@ -5773,11 +5779,11 @@ lpfc_idiag_mbxacc_dump_issue_mbox(struct lpfc_hba *phba, MAILBOX_t *pmbox) | |||
5773 | pr_err("%s\n", line_buf); | 5779 | pr_err("%s\n", line_buf); |
5774 | len = 0; | 5780 | len = 0; |
5775 | memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ); | 5781 | memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ); |
5776 | len += snprintf(line_buf+len, | 5782 | len += scnprintf(line_buf+len, |
5777 | LPFC_MBX_ACC_LBUF_SZ-len, | 5783 | LPFC_MBX_ACC_LBUF_SZ-len, |
5778 | "%03d: ", i); | 5784 | "%03d: ", i); |
5779 | } | 5785 | } |
5780 | len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len, | 5786 | len += scnprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len, |
5781 | "%08x ", | 5787 | "%08x ", |
5782 | ((uint32_t)*pword) & 0xffffffff); | 5788 | ((uint32_t)*pword) & 0xffffffff); |
5783 | pword++; | 5789 | pword++; |
@@ -5796,18 +5802,18 @@ lpfc_idiag_mbxacc_dump_issue_mbox(struct lpfc_hba *phba, MAILBOX_t *pmbox) | |||
5796 | pr_err("%s\n", line_buf); | 5802 | pr_err("%s\n", line_buf); |
5797 | len = 0; | 5803 | len = 0; |
5798 | memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ); | 5804 | memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ); |
5799 | len += snprintf(line_buf+len, | 5805 | len += scnprintf(line_buf+len, |
5800 | LPFC_MBX_ACC_LBUF_SZ-len, | 5806 | LPFC_MBX_ACC_LBUF_SZ-len, |
5801 | "%03d: ", i); | 5807 | "%03d: ", i); |
5802 | } | 5808 | } |
5803 | for (j = 0; j < 4; j++) { | 5809 | for (j = 0; j < 4; j++) { |
5804 | len += snprintf(line_buf+len, | 5810 | len += scnprintf(line_buf+len, |
5805 | LPFC_MBX_ACC_LBUF_SZ-len, | 5811 | LPFC_MBX_ACC_LBUF_SZ-len, |
5806 | "%02x", | 5812 | "%02x", |
5807 | ((uint8_t)*pbyte) & 0xff); | 5813 | ((uint8_t)*pbyte) & 0xff); |
5808 | pbyte++; | 5814 | pbyte++; |
5809 | } | 5815 | } |
5810 | len += snprintf(line_buf+len, | 5816 | len += scnprintf(line_buf+len, |
5811 | LPFC_MBX_ACC_LBUF_SZ-len, " "); | 5817 | LPFC_MBX_ACC_LBUF_SZ-len, " "); |
5812 | } | 5818 | } |
5813 | if ((i - 1) % 8) | 5819 | if ((i - 1) % 8) |
@@ -5891,7 +5897,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) | |||
5891 | phba, &lpfc_debugfs_op_lockstat); | 5897 | phba, &lpfc_debugfs_op_lockstat); |
5892 | if (!phba->debug_lockstat) { | 5898 | if (!phba->debug_lockstat) { |
5893 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | 5899 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, |
5894 | "0913 Cant create debugfs lockstat\n"); | 5900 | "4610 Cant create debugfs lockstat\n"); |
5895 | goto debug_failed; | 5901 | goto debug_failed; |
5896 | } | 5902 | } |
5897 | #endif | 5903 | #endif |
@@ -6134,7 +6140,7 @@ nvmeio_off: | |||
6134 | vport, &lpfc_debugfs_op_scsistat); | 6140 | vport, &lpfc_debugfs_op_scsistat); |
6135 | if (!vport->debug_scsistat) { | 6141 | if (!vport->debug_scsistat) { |
6136 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | 6142 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, |
6137 | "0914 Cannot create debugfs scsistat\n"); | 6143 | "4611 Cannot create debugfs scsistat\n"); |
6138 | goto debug_failed; | 6144 | goto debug_failed; |
6139 | } | 6145 | } |
6140 | 6146 | ||
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h index 93ab7dfb8ee0..2322ddb085c0 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.h +++ b/drivers/scsi/lpfc/lpfc_debugfs.h | |||
@@ -345,10 +345,10 @@ lpfc_debug_dump_qe(struct lpfc_queue *q, uint32_t idx) | |||
345 | 345 | ||
346 | esize = q->entry_size; | 346 | esize = q->entry_size; |
347 | qe_word_cnt = esize / sizeof(uint32_t); | 347 | qe_word_cnt = esize / sizeof(uint32_t); |
348 | pword = q->qe[idx].address; | 348 | pword = lpfc_sli4_qe(q, idx); |
349 | 349 | ||
350 | len = 0; | 350 | len = 0; |
351 | len += snprintf(line_buf+len, LPFC_LBUF_SZ-len, "QE[%04d]: ", idx); | 351 | len += scnprintf(line_buf+len, LPFC_LBUF_SZ-len, "QE[%04d]: ", idx); |
352 | if (qe_word_cnt > 8) | 352 | if (qe_word_cnt > 8) |
353 | printk(KERN_ERR "%s\n", line_buf); | 353 | printk(KERN_ERR "%s\n", line_buf); |
354 | 354 | ||
@@ -359,11 +359,11 @@ lpfc_debug_dump_qe(struct lpfc_queue *q, uint32_t idx) | |||
359 | if (qe_word_cnt > 8) { | 359 | if (qe_word_cnt > 8) { |
360 | len = 0; | 360 | len = 0; |
361 | memset(line_buf, 0, LPFC_LBUF_SZ); | 361 | memset(line_buf, 0, LPFC_LBUF_SZ); |
362 | len += snprintf(line_buf+len, LPFC_LBUF_SZ-len, | 362 | len += scnprintf(line_buf+len, LPFC_LBUF_SZ-len, |
363 | "%03d: ", i); | 363 | "%03d: ", i); |
364 | } | 364 | } |
365 | } | 365 | } |
366 | len += snprintf(line_buf+len, LPFC_LBUF_SZ-len, "%08x ", | 366 | len += scnprintf(line_buf+len, LPFC_LBUF_SZ-len, "%08x ", |
367 | ((uint32_t)*pword) & 0xffffffff); | 367 | ((uint32_t)*pword) & 0xffffffff); |
368 | pword++; | 368 | pword++; |
369 | } | 369 | } |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 7b0755e3527d..c8fb0b455f2a 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -1961,7 +1961,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1961 | IOCB_t *irsp; | 1961 | IOCB_t *irsp; |
1962 | struct lpfc_nodelist *ndlp; | 1962 | struct lpfc_nodelist *ndlp; |
1963 | struct lpfc_dmabuf *prsp; | 1963 | struct lpfc_dmabuf *prsp; |
1964 | int disc, rc; | 1964 | int disc; |
1965 | 1965 | ||
1966 | /* we pass cmdiocb to state machine which needs rspiocb as well */ | 1966 | /* we pass cmdiocb to state machine which needs rspiocb as well */ |
1967 | cmdiocb->context_un.rsp_iocb = rspiocb; | 1967 | cmdiocb->context_un.rsp_iocb = rspiocb; |
@@ -1990,7 +1990,6 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1990 | disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); | 1990 | disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); |
1991 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1991 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
1992 | spin_unlock_irq(shost->host_lock); | 1992 | spin_unlock_irq(shost->host_lock); |
1993 | rc = 0; | ||
1994 | 1993 | ||
1995 | /* PLOGI completes to NPort <nlp_DID> */ | 1994 | /* PLOGI completes to NPort <nlp_DID> */ |
1996 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, | 1995 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, |
@@ -2029,18 +2028,16 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2029 | ndlp->nlp_DID, irsp->ulpStatus, | 2028 | ndlp->nlp_DID, irsp->ulpStatus, |
2030 | irsp->un.ulpWord[4]); | 2029 | irsp->un.ulpWord[4]); |
2031 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 2030 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
2032 | if (lpfc_error_lost_link(irsp)) | 2031 | if (!lpfc_error_lost_link(irsp)) |
2033 | rc = NLP_STE_FREED_NODE; | 2032 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
2034 | else | 2033 | NLP_EVT_CMPL_PLOGI); |
2035 | rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb, | ||
2036 | NLP_EVT_CMPL_PLOGI); | ||
2037 | } else { | 2034 | } else { |
2038 | /* Good status, call state machine */ | 2035 | /* Good status, call state machine */ |
2039 | prsp = list_entry(((struct lpfc_dmabuf *) | 2036 | prsp = list_entry(((struct lpfc_dmabuf *) |
2040 | cmdiocb->context2)->list.next, | 2037 | cmdiocb->context2)->list.next, |
2041 | struct lpfc_dmabuf, list); | 2038 | struct lpfc_dmabuf, list); |
2042 | ndlp = lpfc_plogi_confirm_nport(phba, prsp->virt, ndlp); | 2039 | ndlp = lpfc_plogi_confirm_nport(phba, prsp->virt, ndlp); |
2043 | rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb, | 2040 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
2044 | NLP_EVT_CMPL_PLOGI); | 2041 | NLP_EVT_CMPL_PLOGI); |
2045 | } | 2042 | } |
2046 | 2043 | ||
@@ -6744,12 +6741,11 @@ lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
6744 | uint32_t *lp; | 6741 | uint32_t *lp; |
6745 | RNID *rn; | 6742 | RNID *rn; |
6746 | struct ls_rjt stat; | 6743 | struct ls_rjt stat; |
6747 | uint32_t cmd; | ||
6748 | 6744 | ||
6749 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 6745 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
6750 | lp = (uint32_t *) pcmd->virt; | 6746 | lp = (uint32_t *) pcmd->virt; |
6751 | 6747 | ||
6752 | cmd = *lp++; | 6748 | lp++; |
6753 | rn = (RNID *) lp; | 6749 | rn = (RNID *) lp; |
6754 | 6750 | ||
6755 | /* RNID received */ | 6751 | /* RNID received */ |
@@ -7508,14 +7504,14 @@ lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
7508 | uint32_t *lp; | 7504 | uint32_t *lp; |
7509 | IOCB_t *icmd; | 7505 | IOCB_t *icmd; |
7510 | FARP *fp; | 7506 | FARP *fp; |
7511 | uint32_t cmd, cnt, did; | 7507 | uint32_t cnt, did; |
7512 | 7508 | ||
7513 | icmd = &cmdiocb->iocb; | 7509 | icmd = &cmdiocb->iocb; |
7514 | did = icmd->un.elsreq64.remoteID; | 7510 | did = icmd->un.elsreq64.remoteID; |
7515 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 7511 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
7516 | lp = (uint32_t *) pcmd->virt; | 7512 | lp = (uint32_t *) pcmd->virt; |
7517 | 7513 | ||
7518 | cmd = *lp++; | 7514 | lp++; |
7519 | fp = (FARP *) lp; | 7515 | fp = (FARP *) lp; |
7520 | /* FARP-REQ received from DID <did> */ | 7516 | /* FARP-REQ received from DID <did> */ |
7521 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, | 7517 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, |
@@ -7580,14 +7576,14 @@ lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
7580 | struct lpfc_dmabuf *pcmd; | 7576 | struct lpfc_dmabuf *pcmd; |
7581 | uint32_t *lp; | 7577 | uint32_t *lp; |
7582 | IOCB_t *icmd; | 7578 | IOCB_t *icmd; |
7583 | uint32_t cmd, did; | 7579 | uint32_t did; |
7584 | 7580 | ||
7585 | icmd = &cmdiocb->iocb; | 7581 | icmd = &cmdiocb->iocb; |
7586 | did = icmd->un.elsreq64.remoteID; | 7582 | did = icmd->un.elsreq64.remoteID; |
7587 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 7583 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
7588 | lp = (uint32_t *) pcmd->virt; | 7584 | lp = (uint32_t *) pcmd->virt; |
7589 | 7585 | ||
7590 | cmd = *lp++; | 7586 | lp++; |
7591 | /* FARP-RSP received from DID <did> */ | 7587 | /* FARP-RSP received from DID <did> */ |
7592 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, | 7588 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, |
7593 | "0600 FARP-RSP received from DID x%x\n", did); | 7589 | "0600 FARP-RSP received from DID x%x\n", did); |
@@ -8454,6 +8450,14 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
8454 | rjt_err = LSRJT_UNABLE_TPC; | 8450 | rjt_err = LSRJT_UNABLE_TPC; |
8455 | rjt_exp = LSEXP_INVALID_OX_RX; | 8451 | rjt_exp = LSEXP_INVALID_OX_RX; |
8456 | break; | 8452 | break; |
8453 | case ELS_CMD_FPIN: | ||
8454 | /* | ||
8455 | * Received FPIN from fabric - pass it to the | ||
8456 | * transport FPIN handler. | ||
8457 | */ | ||
8458 | fc_host_fpin_rcv(shost, elsiocb->iocb.unsli3.rcvsli3.acc_len, | ||
8459 | (char *)payload); | ||
8460 | break; | ||
8457 | default: | 8461 | default: |
8458 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 8462 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
8459 | "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x", | 8463 | "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x", |
@@ -8776,7 +8780,6 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
8776 | return; | 8780 | return; |
8777 | } | 8781 | } |
8778 | /* fall through */ | 8782 | /* fall through */ |
8779 | |||
8780 | default: | 8783 | default: |
8781 | /* Try to recover from this error */ | 8784 | /* Try to recover from this error */ |
8782 | if (phba->sli_rev == LPFC_SLI_REV4) | 8785 | if (phba->sli_rev == LPFC_SLI_REV4) |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 14fffbebbbb5..c43852f97f25 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -885,15 +885,9 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
885 | LPFC_MBOXQ_t *mb; | 885 | LPFC_MBOXQ_t *mb; |
886 | int i; | 886 | int i; |
887 | 887 | ||
888 | if (phba->link_state == LPFC_LINK_DOWN) { | 888 | if (phba->link_state == LPFC_LINK_DOWN) |
889 | if (phba->sli4_hba.conf_trunk) { | ||
890 | phba->trunk_link.link0.state = 0; | ||
891 | phba->trunk_link.link1.state = 0; | ||
892 | phba->trunk_link.link2.state = 0; | ||
893 | phba->trunk_link.link3.state = 0; | ||
894 | } | ||
895 | return 0; | 889 | return 0; |
896 | } | 890 | |
897 | /* Block all SCSI stack I/Os */ | 891 | /* Block all SCSI stack I/Os */ |
898 | lpfc_scsi_dev_block(phba); | 892 | lpfc_scsi_dev_block(phba); |
899 | 893 | ||
@@ -932,7 +926,11 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
932 | } | 926 | } |
933 | } | 927 | } |
934 | lpfc_destroy_vport_work_array(phba, vports); | 928 | lpfc_destroy_vport_work_array(phba, vports); |
935 | /* Clean up any firmware default rpi's */ | 929 | |
930 | /* Clean up any SLI3 firmware default rpi's */ | ||
931 | if (phba->sli_rev > LPFC_SLI_REV3) | ||
932 | goto skip_unreg_did; | ||
933 | |||
936 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 934 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
937 | if (mb) { | 935 | if (mb) { |
938 | lpfc_unreg_did(phba, 0xffff, LPFC_UNREG_ALL_DFLT_RPIS, mb); | 936 | lpfc_unreg_did(phba, 0xffff, LPFC_UNREG_ALL_DFLT_RPIS, mb); |
@@ -944,6 +942,7 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
944 | } | 942 | } |
945 | } | 943 | } |
946 | 944 | ||
945 | skip_unreg_did: | ||
947 | /* Setup myDID for link up if we are in pt2pt mode */ | 946 | /* Setup myDID for link up if we are in pt2pt mode */ |
948 | if (phba->pport->fc_flag & FC_PT2PT) { | 947 | if (phba->pport->fc_flag & FC_PT2PT) { |
949 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 948 | mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
@@ -4147,9 +4146,15 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4147 | rdata->pnode = lpfc_nlp_get(ndlp); | 4146 | rdata->pnode = lpfc_nlp_get(ndlp); |
4148 | 4147 | ||
4149 | if (ndlp->nlp_type & NLP_FCP_TARGET) | 4148 | if (ndlp->nlp_type & NLP_FCP_TARGET) |
4150 | rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; | 4149 | rport_ids.roles |= FC_PORT_ROLE_FCP_TARGET; |
4151 | if (ndlp->nlp_type & NLP_FCP_INITIATOR) | 4150 | if (ndlp->nlp_type & NLP_FCP_INITIATOR) |
4152 | rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR; | 4151 | rport_ids.roles |= FC_PORT_ROLE_FCP_INITIATOR; |
4152 | if (ndlp->nlp_type & NLP_NVME_INITIATOR) | ||
4153 | rport_ids.roles |= FC_PORT_ROLE_NVME_INITIATOR; | ||
4154 | if (ndlp->nlp_type & NLP_NVME_TARGET) | ||
4155 | rport_ids.roles |= FC_PORT_ROLE_NVME_TARGET; | ||
4156 | if (ndlp->nlp_type & NLP_NVME_DISCOVERY) | ||
4157 | rport_ids.roles |= FC_PORT_ROLE_NVME_DISCOVERY; | ||
4153 | 4158 | ||
4154 | if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN) | 4159 | if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN) |
4155 | fc_remote_port_rolechg(rport, rport_ids.roles); | 4160 | fc_remote_port_rolechg(rport, rport_ids.roles); |
@@ -4675,6 +4680,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba *phba, | |||
4675 | case CMD_XMIT_ELS_RSP64_CX: | 4680 | case CMD_XMIT_ELS_RSP64_CX: |
4676 | if (iocb->context1 == (uint8_t *) ndlp) | 4681 | if (iocb->context1 == (uint8_t *) ndlp) |
4677 | return 1; | 4682 | return 1; |
4683 | /* fall through */ | ||
4678 | } | 4684 | } |
4679 | } else if (pring->ringno == LPFC_FCP_RING) { | 4685 | } else if (pring->ringno == LPFC_FCP_RING) { |
4680 | /* Skip match check if waiting to relogin to FCP target */ | 4686 | /* Skip match check if waiting to relogin to FCP target */ |
@@ -4870,6 +4876,10 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4870 | * accept PLOGIs after unreg_rpi_cmpl | 4876 | * accept PLOGIs after unreg_rpi_cmpl |
4871 | */ | 4877 | */ |
4872 | acc_plogi = 0; | 4878 | acc_plogi = 0; |
4879 | } else if (vport->load_flag & FC_UNLOADING) { | ||
4880 | mbox->ctx_ndlp = NULL; | ||
4881 | mbox->mbox_cmpl = | ||
4882 | lpfc_sli_def_mbox_cmpl; | ||
4873 | } else { | 4883 | } else { |
4874 | mbox->ctx_ndlp = ndlp; | 4884 | mbox->ctx_ndlp = ndlp; |
4875 | mbox->mbox_cmpl = | 4885 | mbox->mbox_cmpl = |
@@ -4981,6 +4991,10 @@ lpfc_unreg_default_rpis(struct lpfc_vport *vport) | |||
4981 | LPFC_MBOXQ_t *mbox; | 4991 | LPFC_MBOXQ_t *mbox; |
4982 | int rc; | 4992 | int rc; |
4983 | 4993 | ||
4994 | /* Unreg DID is an SLI3 operation. */ | ||
4995 | if (phba->sli_rev > LPFC_SLI_REV3) | ||
4996 | return; | ||
4997 | |||
4984 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 4998 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
4985 | if (mbox) { | 4999 | if (mbox) { |
4986 | lpfc_unreg_did(phba, vport->vpi, LPFC_UNREG_ALL_DFLT_RPIS, | 5000 | lpfc_unreg_did(phba, vport->vpi, LPFC_UNREG_ALL_DFLT_RPIS, |
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index ec1227018913..edd8f3982023 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
@@ -560,6 +560,8 @@ struct fc_vft_header { | |||
560 | #define fc_vft_hdr_hopct_WORD word1 | 560 | #define fc_vft_hdr_hopct_WORD word1 |
561 | }; | 561 | }; |
562 | 562 | ||
563 | #include <uapi/scsi/fc/fc_els.h> | ||
564 | |||
563 | /* | 565 | /* |
564 | * Extended Link Service LS_COMMAND codes (Payload Word 0) | 566 | * Extended Link Service LS_COMMAND codes (Payload Word 0) |
565 | */ | 567 | */ |
@@ -603,6 +605,7 @@ struct fc_vft_header { | |||
603 | #define ELS_CMD_RNID 0x78000000 | 605 | #define ELS_CMD_RNID 0x78000000 |
604 | #define ELS_CMD_LIRR 0x7A000000 | 606 | #define ELS_CMD_LIRR 0x7A000000 |
605 | #define ELS_CMD_LCB 0x81000000 | 607 | #define ELS_CMD_LCB 0x81000000 |
608 | #define ELS_CMD_FPIN 0x16000000 | ||
606 | #else /* __LITTLE_ENDIAN_BITFIELD */ | 609 | #else /* __LITTLE_ENDIAN_BITFIELD */ |
607 | #define ELS_CMD_MASK 0xffff | 610 | #define ELS_CMD_MASK 0xffff |
608 | #define ELS_RSP_MASK 0xff | 611 | #define ELS_RSP_MASK 0xff |
@@ -643,6 +646,7 @@ struct fc_vft_header { | |||
643 | #define ELS_CMD_RNID 0x78 | 646 | #define ELS_CMD_RNID 0x78 |
644 | #define ELS_CMD_LIRR 0x7A | 647 | #define ELS_CMD_LIRR 0x7A |
645 | #define ELS_CMD_LCB 0x81 | 648 | #define ELS_CMD_LCB 0x81 |
649 | #define ELS_CMD_FPIN ELS_FPIN | ||
646 | #endif | 650 | #endif |
647 | 651 | ||
648 | /* | 652 | /* |
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index ff875b833192..77f9a55a3f54 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
@@ -1894,18 +1894,19 @@ struct lpfc_mbx_set_link_diag_loopback { | |||
1894 | union { | 1894 | union { |
1895 | struct { | 1895 | struct { |
1896 | uint32_t word0; | 1896 | uint32_t word0; |
1897 | #define lpfc_mbx_set_diag_lpbk_type_SHIFT 0 | 1897 | #define lpfc_mbx_set_diag_lpbk_type_SHIFT 0 |
1898 | #define lpfc_mbx_set_diag_lpbk_type_MASK 0x00000003 | 1898 | #define lpfc_mbx_set_diag_lpbk_type_MASK 0x00000003 |
1899 | #define lpfc_mbx_set_diag_lpbk_type_WORD word0 | 1899 | #define lpfc_mbx_set_diag_lpbk_type_WORD word0 |
1900 | #define LPFC_DIAG_LOOPBACK_TYPE_DISABLE 0x0 | 1900 | #define LPFC_DIAG_LOOPBACK_TYPE_DISABLE 0x0 |
1901 | #define LPFC_DIAG_LOOPBACK_TYPE_INTERNAL 0x1 | 1901 | #define LPFC_DIAG_LOOPBACK_TYPE_INTERNAL 0x1 |
1902 | #define LPFC_DIAG_LOOPBACK_TYPE_SERDES 0x2 | 1902 | #define LPFC_DIAG_LOOPBACK_TYPE_SERDES 0x2 |
1903 | #define lpfc_mbx_set_diag_lpbk_link_num_SHIFT 16 | 1903 | #define LPFC_DIAG_LOOPBACK_TYPE_EXTERNAL_TRUNKED 0x3 |
1904 | #define lpfc_mbx_set_diag_lpbk_link_num_MASK 0x0000003F | 1904 | #define lpfc_mbx_set_diag_lpbk_link_num_SHIFT 16 |
1905 | #define lpfc_mbx_set_diag_lpbk_link_num_WORD word0 | 1905 | #define lpfc_mbx_set_diag_lpbk_link_num_MASK 0x0000003F |
1906 | #define lpfc_mbx_set_diag_lpbk_link_type_SHIFT 22 | 1906 | #define lpfc_mbx_set_diag_lpbk_link_num_WORD word0 |
1907 | #define lpfc_mbx_set_diag_lpbk_link_type_MASK 0x00000003 | 1907 | #define lpfc_mbx_set_diag_lpbk_link_type_SHIFT 22 |
1908 | #define lpfc_mbx_set_diag_lpbk_link_type_WORD word0 | 1908 | #define lpfc_mbx_set_diag_lpbk_link_type_MASK 0x00000003 |
1909 | #define lpfc_mbx_set_diag_lpbk_link_type_WORD word0 | ||
1909 | } req; | 1910 | } req; |
1910 | struct { | 1911 | struct { |
1911 | uint32_t word0; | 1912 | uint32_t word0; |
@@ -4083,22 +4084,7 @@ struct lpfc_acqe_grp5 { | |||
4083 | uint32_t trailer; | 4084 | uint32_t trailer; |
4084 | }; | 4085 | }; |
4085 | 4086 | ||
4086 | static char *const trunk_errmsg[] = { /* map errcode */ | 4087 | extern const char *const trunk_errmsg[]; |
4087 | "", /* There is no such error code at index 0*/ | ||
4088 | "link negotiated speed does not match existing" | ||
4089 | " trunk - link was \"low\" speed", | ||
4090 | "link negotiated speed does not match" | ||
4091 | " existing trunk - link was \"middle\" speed", | ||
4092 | "link negotiated speed does not match existing" | ||
4093 | " trunk - link was \"high\" speed", | ||
4094 | "Attached to non-trunking port - F_Port", | ||
4095 | "Attached to non-trunking port - N_Port", | ||
4096 | "FLOGI response timeout", | ||
4097 | "non-FLOGI frame received", | ||
4098 | "Invalid FLOGI response", | ||
4099 | "Trunking initialization protocol", | ||
4100 | "Trunk peer device mismatch", | ||
4101 | }; | ||
4102 | 4088 | ||
4103 | struct lpfc_acqe_fc_la { | 4089 | struct lpfc_acqe_fc_la { |
4104 | uint32_t word0; | 4090 | uint32_t word0; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 7fcdaed3fa94..eaaef682de25 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -1117,19 +1117,19 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) | |||
1117 | 1117 | ||
1118 | } | 1118 | } |
1119 | } | 1119 | } |
1120 | spin_unlock_irq(&phba->hbalock); | ||
1120 | 1121 | ||
1121 | if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { | 1122 | if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { |
1122 | spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock); | 1123 | spin_lock_irq(&phba->sli4_hba.abts_nvmet_buf_list_lock); |
1123 | list_splice_init(&phba->sli4_hba.lpfc_abts_nvmet_ctx_list, | 1124 | list_splice_init(&phba->sli4_hba.lpfc_abts_nvmet_ctx_list, |
1124 | &nvmet_aborts); | 1125 | &nvmet_aborts); |
1125 | spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock); | 1126 | spin_unlock_irq(&phba->sli4_hba.abts_nvmet_buf_list_lock); |
1126 | list_for_each_entry_safe(ctxp, ctxp_next, &nvmet_aborts, list) { | 1127 | list_for_each_entry_safe(ctxp, ctxp_next, &nvmet_aborts, list) { |
1127 | ctxp->flag &= ~(LPFC_NVMET_XBUSY | LPFC_NVMET_ABORT_OP); | 1128 | ctxp->flag &= ~(LPFC_NVMET_XBUSY | LPFC_NVMET_ABORT_OP); |
1128 | lpfc_nvmet_ctxbuf_post(phba, ctxp->ctxbuf); | 1129 | lpfc_nvmet_ctxbuf_post(phba, ctxp->ctxbuf); |
1129 | } | 1130 | } |
1130 | } | 1131 | } |
1131 | 1132 | ||
1132 | spin_unlock_irq(&phba->hbalock); | ||
1133 | lpfc_sli4_free_sp_events(phba); | 1133 | lpfc_sli4_free_sp_events(phba); |
1134 | return cnt; | 1134 | return cnt; |
1135 | } | 1135 | } |
@@ -1844,8 +1844,12 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) | |||
1844 | /* If the pci channel is offline, ignore possible errors, since | 1844 | /* If the pci channel is offline, ignore possible errors, since |
1845 | * we cannot communicate with the pci card anyway. | 1845 | * we cannot communicate with the pci card anyway. |
1846 | */ | 1846 | */ |
1847 | if (pci_channel_offline(phba->pcidev)) | 1847 | if (pci_channel_offline(phba->pcidev)) { |
1848 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1849 | "3166 pci channel is offline\n"); | ||
1850 | lpfc_sli4_offline_eratt(phba); | ||
1848 | return; | 1851 | return; |
1852 | } | ||
1849 | 1853 | ||
1850 | memset(&portsmphr_reg, 0, sizeof(portsmphr_reg)); | 1854 | memset(&portsmphr_reg, 0, sizeof(portsmphr_reg)); |
1851 | if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); | 1855 | if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); |
@@ -1922,6 +1926,7 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) | |||
1922 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1926 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
1923 | "3151 PCI bus read access failure: x%x\n", | 1927 | "3151 PCI bus read access failure: x%x\n", |
1924 | readl(phba->sli4_hba.u.if_type2.STATUSregaddr)); | 1928 | readl(phba->sli4_hba.u.if_type2.STATUSregaddr)); |
1929 | lpfc_sli4_offline_eratt(phba); | ||
1925 | return; | 1930 | return; |
1926 | } | 1931 | } |
1927 | reg_err1 = readl(phba->sli4_hba.u.if_type2.ERR1regaddr); | 1932 | reg_err1 = readl(phba->sli4_hba.u.if_type2.ERR1regaddr); |
@@ -3075,7 +3080,7 @@ lpfc_sli4_node_prep(struct lpfc_hba *phba) | |||
3075 | * This routine moves a batch of XRIs from lpfc_io_buf_list_put of HWQ 0 | 3080 | * This routine moves a batch of XRIs from lpfc_io_buf_list_put of HWQ 0 |
3076 | * to expedite pool. Mark them as expedite. | 3081 | * to expedite pool. Mark them as expedite. |
3077 | **/ | 3082 | **/ |
3078 | void lpfc_create_expedite_pool(struct lpfc_hba *phba) | 3083 | static void lpfc_create_expedite_pool(struct lpfc_hba *phba) |
3079 | { | 3084 | { |
3080 | struct lpfc_sli4_hdw_queue *qp; | 3085 | struct lpfc_sli4_hdw_queue *qp; |
3081 | struct lpfc_io_buf *lpfc_ncmd; | 3086 | struct lpfc_io_buf *lpfc_ncmd; |
@@ -3110,7 +3115,7 @@ void lpfc_create_expedite_pool(struct lpfc_hba *phba) | |||
3110 | * This routine returns XRIs from expedite pool to lpfc_io_buf_list_put | 3115 | * This routine returns XRIs from expedite pool to lpfc_io_buf_list_put |
3111 | * of HWQ 0. Clear the mark. | 3116 | * of HWQ 0. Clear the mark. |
3112 | **/ | 3117 | **/ |
3113 | void lpfc_destroy_expedite_pool(struct lpfc_hba *phba) | 3118 | static void lpfc_destroy_expedite_pool(struct lpfc_hba *phba) |
3114 | { | 3119 | { |
3115 | struct lpfc_sli4_hdw_queue *qp; | 3120 | struct lpfc_sli4_hdw_queue *qp; |
3116 | struct lpfc_io_buf *lpfc_ncmd; | 3121 | struct lpfc_io_buf *lpfc_ncmd; |
@@ -3230,7 +3235,7 @@ void lpfc_create_multixri_pools(struct lpfc_hba *phba) | |||
3230 | * | 3235 | * |
3231 | * This routine returns XRIs from public/private to lpfc_io_buf_list_put. | 3236 | * This routine returns XRIs from public/private to lpfc_io_buf_list_put. |
3232 | **/ | 3237 | **/ |
3233 | void lpfc_destroy_multixri_pools(struct lpfc_hba *phba) | 3238 | static void lpfc_destroy_multixri_pools(struct lpfc_hba *phba) |
3234 | { | 3239 | { |
3235 | u32 i; | 3240 | u32 i; |
3236 | u32 hwq_count; | 3241 | u32 hwq_count; |
@@ -3245,6 +3250,13 @@ void lpfc_destroy_multixri_pools(struct lpfc_hba *phba) | |||
3245 | if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) | 3250 | if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) |
3246 | lpfc_destroy_expedite_pool(phba); | 3251 | lpfc_destroy_expedite_pool(phba); |
3247 | 3252 | ||
3253 | if (!(phba->pport->load_flag & FC_UNLOADING)) { | ||
3254 | lpfc_sli_flush_fcp_rings(phba); | ||
3255 | |||
3256 | if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) | ||
3257 | lpfc_sli_flush_nvme_rings(phba); | ||
3258 | } | ||
3259 | |||
3248 | hwq_count = phba->cfg_hdw_queue; | 3260 | hwq_count = phba->cfg_hdw_queue; |
3249 | 3261 | ||
3250 | for (i = 0; i < hwq_count; i++) { | 3262 | for (i = 0; i < hwq_count; i++) { |
@@ -3611,8 +3623,6 @@ lpfc_io_free(struct lpfc_hba *phba) | |||
3611 | struct lpfc_sli4_hdw_queue *qp; | 3623 | struct lpfc_sli4_hdw_queue *qp; |
3612 | int idx; | 3624 | int idx; |
3613 | 3625 | ||
3614 | spin_lock_irq(&phba->hbalock); | ||
3615 | |||
3616 | for (idx = 0; idx < phba->cfg_hdw_queue; idx++) { | 3626 | for (idx = 0; idx < phba->cfg_hdw_queue; idx++) { |
3617 | qp = &phba->sli4_hba.hdwq[idx]; | 3627 | qp = &phba->sli4_hba.hdwq[idx]; |
3618 | /* Release all the lpfc_nvme_bufs maintained by this host. */ | 3628 | /* Release all the lpfc_nvme_bufs maintained by this host. */ |
@@ -3642,8 +3652,6 @@ lpfc_io_free(struct lpfc_hba *phba) | |||
3642 | } | 3652 | } |
3643 | spin_unlock(&qp->io_buf_list_get_lock); | 3653 | spin_unlock(&qp->io_buf_list_get_lock); |
3644 | } | 3654 | } |
3645 | |||
3646 | spin_unlock_irq(&phba->hbalock); | ||
3647 | } | 3655 | } |
3648 | 3656 | ||
3649 | /** | 3657 | /** |
@@ -4457,7 +4465,7 @@ finished: | |||
4457 | return stat; | 4465 | return stat; |
4458 | } | 4466 | } |
4459 | 4467 | ||
4460 | void lpfc_host_supported_speeds_set(struct Scsi_Host *shost) | 4468 | static void lpfc_host_supported_speeds_set(struct Scsi_Host *shost) |
4461 | { | 4469 | { |
4462 | struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; | 4470 | struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; |
4463 | struct lpfc_hba *phba = vport->phba; | 4471 | struct lpfc_hba *phba = vport->phba; |
@@ -8603,9 +8611,9 @@ lpfc_sli4_queue_verify(struct lpfc_hba *phba) | |||
8603 | if (phba->nvmet_support) { | 8611 | if (phba->nvmet_support) { |
8604 | if (phba->cfg_irq_chann < phba->cfg_nvmet_mrq) | 8612 | if (phba->cfg_irq_chann < phba->cfg_nvmet_mrq) |
8605 | phba->cfg_nvmet_mrq = phba->cfg_irq_chann; | 8613 | phba->cfg_nvmet_mrq = phba->cfg_irq_chann; |
8614 | if (phba->cfg_nvmet_mrq > LPFC_NVMET_MRQ_MAX) | ||
8615 | phba->cfg_nvmet_mrq = LPFC_NVMET_MRQ_MAX; | ||
8606 | } | 8616 | } |
8607 | if (phba->cfg_nvmet_mrq > LPFC_NVMET_MRQ_MAX) | ||
8608 | phba->cfg_nvmet_mrq = LPFC_NVMET_MRQ_MAX; | ||
8609 | 8617 | ||
8610 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8618 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8611 | "2574 IO channels: hdwQ %d IRQ %d MRQ: %d\n", | 8619 | "2574 IO channels: hdwQ %d IRQ %d MRQ: %d\n", |
@@ -8626,10 +8634,12 @@ static int | |||
8626 | lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx) | 8634 | lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx) |
8627 | { | 8635 | { |
8628 | struct lpfc_queue *qdesc; | 8636 | struct lpfc_queue *qdesc; |
8637 | int cpu; | ||
8629 | 8638 | ||
8639 | cpu = lpfc_find_cpu_handle(phba, wqidx, LPFC_FIND_BY_HDWQ); | ||
8630 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, | 8640 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, |
8631 | phba->sli4_hba.cq_esize, | 8641 | phba->sli4_hba.cq_esize, |
8632 | LPFC_CQE_EXP_COUNT); | 8642 | LPFC_CQE_EXP_COUNT, cpu); |
8633 | if (!qdesc) { | 8643 | if (!qdesc) { |
8634 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8644 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8635 | "0508 Failed allocate fast-path NVME CQ (%d)\n", | 8645 | "0508 Failed allocate fast-path NVME CQ (%d)\n", |
@@ -8638,11 +8648,12 @@ lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx) | |||
8638 | } | 8648 | } |
8639 | qdesc->qe_valid = 1; | 8649 | qdesc->qe_valid = 1; |
8640 | qdesc->hdwq = wqidx; | 8650 | qdesc->hdwq = wqidx; |
8641 | qdesc->chann = lpfc_find_cpu_handle(phba, wqidx, LPFC_FIND_BY_HDWQ); | 8651 | qdesc->chann = cpu; |
8642 | phba->sli4_hba.hdwq[wqidx].nvme_cq = qdesc; | 8652 | phba->sli4_hba.hdwq[wqidx].nvme_cq = qdesc; |
8643 | 8653 | ||
8644 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, | 8654 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, |
8645 | LPFC_WQE128_SIZE, LPFC_WQE_EXP_COUNT); | 8655 | LPFC_WQE128_SIZE, LPFC_WQE_EXP_COUNT, |
8656 | cpu); | ||
8646 | if (!qdesc) { | 8657 | if (!qdesc) { |
8647 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8658 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8648 | "0509 Failed allocate fast-path NVME WQ (%d)\n", | 8659 | "0509 Failed allocate fast-path NVME WQ (%d)\n", |
@@ -8661,18 +8672,20 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx) | |||
8661 | { | 8672 | { |
8662 | struct lpfc_queue *qdesc; | 8673 | struct lpfc_queue *qdesc; |
8663 | uint32_t wqesize; | 8674 | uint32_t wqesize; |
8675 | int cpu; | ||
8664 | 8676 | ||
8677 | cpu = lpfc_find_cpu_handle(phba, wqidx, LPFC_FIND_BY_HDWQ); | ||
8665 | /* Create Fast Path FCP CQs */ | 8678 | /* Create Fast Path FCP CQs */ |
8666 | if (phba->enab_exp_wqcq_pages) | 8679 | if (phba->enab_exp_wqcq_pages) |
8667 | /* Increase the CQ size when WQEs contain an embedded cdb */ | 8680 | /* Increase the CQ size when WQEs contain an embedded cdb */ |
8668 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, | 8681 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, |
8669 | phba->sli4_hba.cq_esize, | 8682 | phba->sli4_hba.cq_esize, |
8670 | LPFC_CQE_EXP_COUNT); | 8683 | LPFC_CQE_EXP_COUNT, cpu); |
8671 | 8684 | ||
8672 | else | 8685 | else |
8673 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, | 8686 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, |
8674 | phba->sli4_hba.cq_esize, | 8687 | phba->sli4_hba.cq_esize, |
8675 | phba->sli4_hba.cq_ecount); | 8688 | phba->sli4_hba.cq_ecount, cpu); |
8676 | if (!qdesc) { | 8689 | if (!qdesc) { |
8677 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8690 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8678 | "0499 Failed allocate fast-path FCP CQ (%d)\n", wqidx); | 8691 | "0499 Failed allocate fast-path FCP CQ (%d)\n", wqidx); |
@@ -8680,7 +8693,7 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx) | |||
8680 | } | 8693 | } |
8681 | qdesc->qe_valid = 1; | 8694 | qdesc->qe_valid = 1; |
8682 | qdesc->hdwq = wqidx; | 8695 | qdesc->hdwq = wqidx; |
8683 | qdesc->chann = lpfc_find_cpu_handle(phba, wqidx, LPFC_FIND_BY_HDWQ); | 8696 | qdesc->chann = cpu; |
8684 | phba->sli4_hba.hdwq[wqidx].fcp_cq = qdesc; | 8697 | phba->sli4_hba.hdwq[wqidx].fcp_cq = qdesc; |
8685 | 8698 | ||
8686 | /* Create Fast Path FCP WQs */ | 8699 | /* Create Fast Path FCP WQs */ |
@@ -8690,11 +8703,11 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx) | |||
8690 | LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize; | 8703 | LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize; |
8691 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, | 8704 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, |
8692 | wqesize, | 8705 | wqesize, |
8693 | LPFC_WQE_EXP_COUNT); | 8706 | LPFC_WQE_EXP_COUNT, cpu); |
8694 | } else | 8707 | } else |
8695 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, | 8708 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, |
8696 | phba->sli4_hba.wq_esize, | 8709 | phba->sli4_hba.wq_esize, |
8697 | phba->sli4_hba.wq_ecount); | 8710 | phba->sli4_hba.wq_ecount, cpu); |
8698 | 8711 | ||
8699 | if (!qdesc) { | 8712 | if (!qdesc) { |
8700 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8713 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
@@ -8727,7 +8740,7 @@ int | |||
8727 | lpfc_sli4_queue_create(struct lpfc_hba *phba) | 8740 | lpfc_sli4_queue_create(struct lpfc_hba *phba) |
8728 | { | 8741 | { |
8729 | struct lpfc_queue *qdesc; | 8742 | struct lpfc_queue *qdesc; |
8730 | int idx, eqidx; | 8743 | int idx, eqidx, cpu; |
8731 | struct lpfc_sli4_hdw_queue *qp; | 8744 | struct lpfc_sli4_hdw_queue *qp; |
8732 | struct lpfc_eq_intr_info *eqi; | 8745 | struct lpfc_eq_intr_info *eqi; |
8733 | 8746 | ||
@@ -8814,13 +8827,15 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
8814 | 8827 | ||
8815 | /* Create HBA Event Queues (EQs) */ | 8828 | /* Create HBA Event Queues (EQs) */ |
8816 | for (idx = 0; idx < phba->cfg_hdw_queue; idx++) { | 8829 | for (idx = 0; idx < phba->cfg_hdw_queue; idx++) { |
8830 | /* determine EQ affinity */ | ||
8831 | eqidx = lpfc_find_eq_handle(phba, idx); | ||
8832 | cpu = lpfc_find_cpu_handle(phba, eqidx, LPFC_FIND_BY_EQ); | ||
8817 | /* | 8833 | /* |
8818 | * If there are more Hardware Queues than available | 8834 | * If there are more Hardware Queues than available |
8819 | * CQs, multiple Hardware Queues may share a common EQ. | 8835 | * EQs, multiple Hardware Queues may share a common EQ. |
8820 | */ | 8836 | */ |
8821 | if (idx >= phba->cfg_irq_chann) { | 8837 | if (idx >= phba->cfg_irq_chann) { |
8822 | /* Share an existing EQ */ | 8838 | /* Share an existing EQ */ |
8823 | eqidx = lpfc_find_eq_handle(phba, idx); | ||
8824 | phba->sli4_hba.hdwq[idx].hba_eq = | 8839 | phba->sli4_hba.hdwq[idx].hba_eq = |
8825 | phba->sli4_hba.hdwq[eqidx].hba_eq; | 8840 | phba->sli4_hba.hdwq[eqidx].hba_eq; |
8826 | continue; | 8841 | continue; |
@@ -8828,7 +8843,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
8828 | /* Create an EQ */ | 8843 | /* Create an EQ */ |
8829 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, | 8844 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, |
8830 | phba->sli4_hba.eq_esize, | 8845 | phba->sli4_hba.eq_esize, |
8831 | phba->sli4_hba.eq_ecount); | 8846 | phba->sli4_hba.eq_ecount, cpu); |
8832 | if (!qdesc) { | 8847 | if (!qdesc) { |
8833 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8848 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8834 | "0497 Failed allocate EQ (%d)\n", idx); | 8849 | "0497 Failed allocate EQ (%d)\n", idx); |
@@ -8838,9 +8853,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
8838 | qdesc->hdwq = idx; | 8853 | qdesc->hdwq = idx; |
8839 | 8854 | ||
8840 | /* Save the CPU this EQ is affinitised to */ | 8855 | /* Save the CPU this EQ is affinitised to */ |
8841 | eqidx = lpfc_find_eq_handle(phba, idx); | 8856 | qdesc->chann = cpu; |
8842 | qdesc->chann = lpfc_find_cpu_handle(phba, eqidx, | ||
8843 | LPFC_FIND_BY_EQ); | ||
8844 | phba->sli4_hba.hdwq[idx].hba_eq = qdesc; | 8857 | phba->sli4_hba.hdwq[idx].hba_eq = qdesc; |
8845 | qdesc->last_cpu = qdesc->chann; | 8858 | qdesc->last_cpu = qdesc->chann; |
8846 | eqi = per_cpu_ptr(phba->sli4_hba.eq_info, qdesc->last_cpu); | 8859 | eqi = per_cpu_ptr(phba->sli4_hba.eq_info, qdesc->last_cpu); |
@@ -8863,11 +8876,14 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
8863 | 8876 | ||
8864 | if (phba->nvmet_support) { | 8877 | if (phba->nvmet_support) { |
8865 | for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) { | 8878 | for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) { |
8879 | cpu = lpfc_find_cpu_handle(phba, idx, | ||
8880 | LPFC_FIND_BY_HDWQ); | ||
8866 | qdesc = lpfc_sli4_queue_alloc( | 8881 | qdesc = lpfc_sli4_queue_alloc( |
8867 | phba, | 8882 | phba, |
8868 | LPFC_DEFAULT_PAGE_SIZE, | 8883 | LPFC_DEFAULT_PAGE_SIZE, |
8869 | phba->sli4_hba.cq_esize, | 8884 | phba->sli4_hba.cq_esize, |
8870 | phba->sli4_hba.cq_ecount); | 8885 | phba->sli4_hba.cq_ecount, |
8886 | cpu); | ||
8871 | if (!qdesc) { | 8887 | if (!qdesc) { |
8872 | lpfc_printf_log( | 8888 | lpfc_printf_log( |
8873 | phba, KERN_ERR, LOG_INIT, | 8889 | phba, KERN_ERR, LOG_INIT, |
@@ -8877,7 +8893,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
8877 | } | 8893 | } |
8878 | qdesc->qe_valid = 1; | 8894 | qdesc->qe_valid = 1; |
8879 | qdesc->hdwq = idx; | 8895 | qdesc->hdwq = idx; |
8880 | qdesc->chann = idx; | 8896 | qdesc->chann = cpu; |
8881 | phba->sli4_hba.nvmet_cqset[idx] = qdesc; | 8897 | phba->sli4_hba.nvmet_cqset[idx] = qdesc; |
8882 | } | 8898 | } |
8883 | } | 8899 | } |
@@ -8887,10 +8903,11 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
8887 | * Create Slow Path Completion Queues (CQs) | 8903 | * Create Slow Path Completion Queues (CQs) |
8888 | */ | 8904 | */ |
8889 | 8905 | ||
8906 | cpu = lpfc_find_cpu_handle(phba, 0, LPFC_FIND_BY_EQ); | ||
8890 | /* Create slow-path Mailbox Command Complete Queue */ | 8907 | /* Create slow-path Mailbox Command Complete Queue */ |
8891 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, | 8908 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, |
8892 | phba->sli4_hba.cq_esize, | 8909 | phba->sli4_hba.cq_esize, |
8893 | phba->sli4_hba.cq_ecount); | 8910 | phba->sli4_hba.cq_ecount, cpu); |
8894 | if (!qdesc) { | 8911 | if (!qdesc) { |
8895 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8912 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8896 | "0500 Failed allocate slow-path mailbox CQ\n"); | 8913 | "0500 Failed allocate slow-path mailbox CQ\n"); |
@@ -8902,7 +8919,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
8902 | /* Create slow-path ELS Complete Queue */ | 8919 | /* Create slow-path ELS Complete Queue */ |
8903 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, | 8920 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, |
8904 | phba->sli4_hba.cq_esize, | 8921 | phba->sli4_hba.cq_esize, |
8905 | phba->sli4_hba.cq_ecount); | 8922 | phba->sli4_hba.cq_ecount, cpu); |
8906 | if (!qdesc) { | 8923 | if (!qdesc) { |
8907 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8924 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8908 | "0501 Failed allocate slow-path ELS CQ\n"); | 8925 | "0501 Failed allocate slow-path ELS CQ\n"); |
@@ -8921,7 +8938,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
8921 | 8938 | ||
8922 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, | 8939 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, |
8923 | phba->sli4_hba.mq_esize, | 8940 | phba->sli4_hba.mq_esize, |
8924 | phba->sli4_hba.mq_ecount); | 8941 | phba->sli4_hba.mq_ecount, cpu); |
8925 | if (!qdesc) { | 8942 | if (!qdesc) { |
8926 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8943 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8927 | "0505 Failed allocate slow-path MQ\n"); | 8944 | "0505 Failed allocate slow-path MQ\n"); |
@@ -8937,7 +8954,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
8937 | /* Create slow-path ELS Work Queue */ | 8954 | /* Create slow-path ELS Work Queue */ |
8938 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, | 8955 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, |
8939 | phba->sli4_hba.wq_esize, | 8956 | phba->sli4_hba.wq_esize, |
8940 | phba->sli4_hba.wq_ecount); | 8957 | phba->sli4_hba.wq_ecount, cpu); |
8941 | if (!qdesc) { | 8958 | if (!qdesc) { |
8942 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8959 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8943 | "0504 Failed allocate slow-path ELS WQ\n"); | 8960 | "0504 Failed allocate slow-path ELS WQ\n"); |
@@ -8951,7 +8968,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
8951 | /* Create NVME LS Complete Queue */ | 8968 | /* Create NVME LS Complete Queue */ |
8952 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, | 8969 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, |
8953 | phba->sli4_hba.cq_esize, | 8970 | phba->sli4_hba.cq_esize, |
8954 | phba->sli4_hba.cq_ecount); | 8971 | phba->sli4_hba.cq_ecount, cpu); |
8955 | if (!qdesc) { | 8972 | if (!qdesc) { |
8956 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8973 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8957 | "6079 Failed allocate NVME LS CQ\n"); | 8974 | "6079 Failed allocate NVME LS CQ\n"); |
@@ -8964,7 +8981,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
8964 | /* Create NVME LS Work Queue */ | 8981 | /* Create NVME LS Work Queue */ |
8965 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, | 8982 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, |
8966 | phba->sli4_hba.wq_esize, | 8983 | phba->sli4_hba.wq_esize, |
8967 | phba->sli4_hba.wq_ecount); | 8984 | phba->sli4_hba.wq_ecount, cpu); |
8968 | if (!qdesc) { | 8985 | if (!qdesc) { |
8969 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8986 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8970 | "6080 Failed allocate NVME LS WQ\n"); | 8987 | "6080 Failed allocate NVME LS WQ\n"); |
@@ -8982,7 +8999,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
8982 | /* Create Receive Queue for header */ | 8999 | /* Create Receive Queue for header */ |
8983 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, | 9000 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, |
8984 | phba->sli4_hba.rq_esize, | 9001 | phba->sli4_hba.rq_esize, |
8985 | phba->sli4_hba.rq_ecount); | 9002 | phba->sli4_hba.rq_ecount, cpu); |
8986 | if (!qdesc) { | 9003 | if (!qdesc) { |
8987 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 9004 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8988 | "0506 Failed allocate receive HRQ\n"); | 9005 | "0506 Failed allocate receive HRQ\n"); |
@@ -8993,7 +9010,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
8993 | /* Create Receive Queue for data */ | 9010 | /* Create Receive Queue for data */ |
8994 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, | 9011 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, |
8995 | phba->sli4_hba.rq_esize, | 9012 | phba->sli4_hba.rq_esize, |
8996 | phba->sli4_hba.rq_ecount); | 9013 | phba->sli4_hba.rq_ecount, cpu); |
8997 | if (!qdesc) { | 9014 | if (!qdesc) { |
8998 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 9015 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8999 | "0507 Failed allocate receive DRQ\n"); | 9016 | "0507 Failed allocate receive DRQ\n"); |
@@ -9004,11 +9021,14 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
9004 | if ((phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) && | 9021 | if ((phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) && |
9005 | phba->nvmet_support) { | 9022 | phba->nvmet_support) { |
9006 | for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) { | 9023 | for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) { |
9024 | cpu = lpfc_find_cpu_handle(phba, idx, | ||
9025 | LPFC_FIND_BY_HDWQ); | ||
9007 | /* Create NVMET Receive Queue for header */ | 9026 | /* Create NVMET Receive Queue for header */ |
9008 | qdesc = lpfc_sli4_queue_alloc(phba, | 9027 | qdesc = lpfc_sli4_queue_alloc(phba, |
9009 | LPFC_DEFAULT_PAGE_SIZE, | 9028 | LPFC_DEFAULT_PAGE_SIZE, |
9010 | phba->sli4_hba.rq_esize, | 9029 | phba->sli4_hba.rq_esize, |
9011 | LPFC_NVMET_RQE_DEF_COUNT); | 9030 | LPFC_NVMET_RQE_DEF_COUNT, |
9031 | cpu); | ||
9012 | if (!qdesc) { | 9032 | if (!qdesc) { |
9013 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 9033 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
9014 | "3146 Failed allocate " | 9034 | "3146 Failed allocate " |
@@ -9019,8 +9039,9 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
9019 | phba->sli4_hba.nvmet_mrq_hdr[idx] = qdesc; | 9039 | phba->sli4_hba.nvmet_mrq_hdr[idx] = qdesc; |
9020 | 9040 | ||
9021 | /* Only needed for header of RQ pair */ | 9041 | /* Only needed for header of RQ pair */ |
9022 | qdesc->rqbp = kzalloc(sizeof(struct lpfc_rqb), | 9042 | qdesc->rqbp = kzalloc_node(sizeof(*qdesc->rqbp), |
9023 | GFP_KERNEL); | 9043 | GFP_KERNEL, |
9044 | cpu_to_node(cpu)); | ||
9024 | if (qdesc->rqbp == NULL) { | 9045 | if (qdesc->rqbp == NULL) { |
9025 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 9046 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
9026 | "6131 Failed allocate " | 9047 | "6131 Failed allocate " |
@@ -9035,7 +9056,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
9035 | qdesc = lpfc_sli4_queue_alloc(phba, | 9056 | qdesc = lpfc_sli4_queue_alloc(phba, |
9036 | LPFC_DEFAULT_PAGE_SIZE, | 9057 | LPFC_DEFAULT_PAGE_SIZE, |
9037 | phba->sli4_hba.rq_esize, | 9058 | phba->sli4_hba.rq_esize, |
9038 | LPFC_NVMET_RQE_DEF_COUNT); | 9059 | LPFC_NVMET_RQE_DEF_COUNT, |
9060 | cpu); | ||
9039 | if (!qdesc) { | 9061 | if (!qdesc) { |
9040 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 9062 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
9041 | "3156 Failed allocate " | 9063 | "3156 Failed allocate " |
@@ -9134,6 +9156,20 @@ lpfc_sli4_release_hdwq(struct lpfc_hba *phba) | |||
9134 | void | 9156 | void |
9135 | lpfc_sli4_queue_destroy(struct lpfc_hba *phba) | 9157 | lpfc_sli4_queue_destroy(struct lpfc_hba *phba) |
9136 | { | 9158 | { |
9159 | /* | ||
9160 | * Set FREE_INIT before beginning to free the queues. | ||
9161 | * Wait until the users of queues to acknowledge to | ||
9162 | * release queues by clearing FREE_WAIT. | ||
9163 | */ | ||
9164 | spin_lock_irq(&phba->hbalock); | ||
9165 | phba->sli.sli_flag |= LPFC_QUEUE_FREE_INIT; | ||
9166 | while (phba->sli.sli_flag & LPFC_QUEUE_FREE_WAIT) { | ||
9167 | spin_unlock_irq(&phba->hbalock); | ||
9168 | msleep(20); | ||
9169 | spin_lock_irq(&phba->hbalock); | ||
9170 | } | ||
9171 | spin_unlock_irq(&phba->hbalock); | ||
9172 | |||
9137 | /* Release HBA eqs */ | 9173 | /* Release HBA eqs */ |
9138 | if (phba->sli4_hba.hdwq) | 9174 | if (phba->sli4_hba.hdwq) |
9139 | lpfc_sli4_release_hdwq(phba); | 9175 | lpfc_sli4_release_hdwq(phba); |
@@ -9172,6 +9208,11 @@ lpfc_sli4_queue_destroy(struct lpfc_hba *phba) | |||
9172 | 9208 | ||
9173 | /* Everything on this list has been freed */ | 9209 | /* Everything on this list has been freed */ |
9174 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_wq_list); | 9210 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_wq_list); |
9211 | |||
9212 | /* Done with freeing the queues */ | ||
9213 | spin_lock_irq(&phba->hbalock); | ||
9214 | phba->sli.sli_flag &= ~LPFC_QUEUE_FREE_INIT; | ||
9215 | spin_unlock_irq(&phba->hbalock); | ||
9175 | } | 9216 | } |
9176 | 9217 | ||
9177 | int | 9218 | int |
@@ -9231,7 +9272,7 @@ lpfc_create_wq_cq(struct lpfc_hba *phba, struct lpfc_queue *eq, | |||
9231 | rc = lpfc_wq_create(phba, wq, cq, qtype); | 9272 | rc = lpfc_wq_create(phba, wq, cq, qtype); |
9232 | if (rc) { | 9273 | if (rc) { |
9233 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 9274 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
9234 | "6123 Fail setup fastpath WQ (%d), rc = 0x%x\n", | 9275 | "4618 Fail setup fastpath WQ (%d), rc = 0x%x\n", |
9235 | qidx, (uint32_t)rc); | 9276 | qidx, (uint32_t)rc); |
9236 | /* no need to tear down cq - caller will do so */ | 9277 | /* no need to tear down cq - caller will do so */ |
9237 | return rc; | 9278 | return rc; |
@@ -9271,7 +9312,7 @@ lpfc_create_wq_cq(struct lpfc_hba *phba, struct lpfc_queue *eq, | |||
9271 | * This routine will populate the cq_lookup table by all | 9312 | * This routine will populate the cq_lookup table by all |
9272 | * available CQ queue_id's. | 9313 | * available CQ queue_id's. |
9273 | **/ | 9314 | **/ |
9274 | void | 9315 | static void |
9275 | lpfc_setup_cq_lookup(struct lpfc_hba *phba) | 9316 | lpfc_setup_cq_lookup(struct lpfc_hba *phba) |
9276 | { | 9317 | { |
9277 | struct lpfc_queue *eq, *childq; | 9318 | struct lpfc_queue *eq, *childq; |
@@ -10740,7 +10781,7 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) | |||
10740 | phba->cfg_irq_chann, vectors); | 10781 | phba->cfg_irq_chann, vectors); |
10741 | if (phba->cfg_irq_chann > vectors) | 10782 | if (phba->cfg_irq_chann > vectors) |
10742 | phba->cfg_irq_chann = vectors; | 10783 | phba->cfg_irq_chann = vectors; |
10743 | if (phba->cfg_nvmet_mrq > vectors) | 10784 | if (phba->nvmet_support && (phba->cfg_nvmet_mrq > vectors)) |
10744 | phba->cfg_nvmet_mrq = vectors; | 10785 | phba->cfg_nvmet_mrq = vectors; |
10745 | } | 10786 | } |
10746 | 10787 | ||
@@ -11297,7 +11338,7 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
11297 | !phba->nvme_support) { | 11338 | !phba->nvme_support) { |
11298 | phba->nvme_support = 0; | 11339 | phba->nvme_support = 0; |
11299 | phba->nvmet_support = 0; | 11340 | phba->nvmet_support = 0; |
11300 | phba->cfg_nvmet_mrq = LPFC_NVMET_MRQ_OFF; | 11341 | phba->cfg_nvmet_mrq = 0; |
11301 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_NVME, | 11342 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_NVME, |
11302 | "6101 Disabling NVME support: " | 11343 | "6101 Disabling NVME support: " |
11303 | "Not supported by firmware: %d %d\n", | 11344 | "Not supported by firmware: %d %d\n", |
@@ -13046,7 +13087,7 @@ lpfc_io_resume(struct pci_dev *pdev) | |||
13046 | * is destroyed. | 13087 | * is destroyed. |
13047 | * | 13088 | * |
13048 | **/ | 13089 | **/ |
13049 | void | 13090 | static void |
13050 | lpfc_sli4_oas_verify(struct lpfc_hba *phba) | 13091 | lpfc_sli4_oas_verify(struct lpfc_hba *phba) |
13051 | { | 13092 | { |
13052 | 13093 | ||
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 11d284c5486e..59252bfca14e 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -871,7 +871,7 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
871 | * This function will send a unreg_login mailbox command to the firmware | 871 | * This function will send a unreg_login mailbox command to the firmware |
872 | * to release a rpi. | 872 | * to release a rpi. |
873 | **/ | 873 | **/ |
874 | void | 874 | static void |
875 | lpfc_release_rpi(struct lpfc_hba *phba, struct lpfc_vport *vport, | 875 | lpfc_release_rpi(struct lpfc_hba *phba, struct lpfc_vport *vport, |
876 | struct lpfc_nodelist *ndlp, uint16_t rpi) | 876 | struct lpfc_nodelist *ndlp, uint16_t rpi) |
877 | { | 877 | { |
@@ -1733,7 +1733,6 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, | |||
1733 | LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg; | 1733 | LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg; |
1734 | MAILBOX_t *mb = &pmb->u.mb; | 1734 | MAILBOX_t *mb = &pmb->u.mb; |
1735 | uint32_t did = mb->un.varWords[1]; | 1735 | uint32_t did = mb->un.varWords[1]; |
1736 | int rc = 0; | ||
1737 | 1736 | ||
1738 | if (mb->mbxStatus) { | 1737 | if (mb->mbxStatus) { |
1739 | /* RegLogin failed */ | 1738 | /* RegLogin failed */ |
@@ -1806,8 +1805,8 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, | |||
1806 | * GFT_ID to determine if remote port supports NVME. | 1805 | * GFT_ID to determine if remote port supports NVME. |
1807 | */ | 1806 | */ |
1808 | if (vport->cfg_enable_fc4_type != LPFC_ENABLE_FCP) { | 1807 | if (vport->cfg_enable_fc4_type != LPFC_ENABLE_FCP) { |
1809 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GFT_ID, | 1808 | lpfc_ns_cmd(vport, SLI_CTNS_GFT_ID, 0, |
1810 | 0, ndlp->nlp_DID); | 1809 | ndlp->nlp_DID); |
1811 | return ndlp->nlp_state; | 1810 | return ndlp->nlp_state; |
1812 | } | 1811 | } |
1813 | ndlp->nlp_fc4_type = NLP_FC4_FCP; | 1812 | ndlp->nlp_fc4_type = NLP_FC4_FCP; |
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index d16ca413110d..9d99cb915390 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c | |||
@@ -229,7 +229,7 @@ lpfc_nvme_create_queue(struct nvme_fc_local_port *pnvme_lport, | |||
229 | if (qhandle == NULL) | 229 | if (qhandle == NULL) |
230 | return -ENOMEM; | 230 | return -ENOMEM; |
231 | 231 | ||
232 | qhandle->cpu_id = smp_processor_id(); | 232 | qhandle->cpu_id = raw_smp_processor_id(); |
233 | qhandle->qidx = qidx; | 233 | qhandle->qidx = qidx; |
234 | /* | 234 | /* |
235 | * NVME qidx == 0 is the admin queue, so both admin queue | 235 | * NVME qidx == 0 is the admin queue, so both admin queue |
@@ -312,7 +312,7 @@ lpfc_nvme_localport_delete(struct nvme_fc_local_port *localport) | |||
312 | * Return value : | 312 | * Return value : |
313 | * None | 313 | * None |
314 | */ | 314 | */ |
315 | void | 315 | static void |
316 | lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport) | 316 | lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport) |
317 | { | 317 | { |
318 | struct lpfc_nvme_rport *rport = remoteport->private; | 318 | struct lpfc_nvme_rport *rport = remoteport->private; |
@@ -1111,9 +1111,11 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, | |||
1111 | out_err: | 1111 | out_err: |
1112 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR, | 1112 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR, |
1113 | "6072 NVME Completion Error: xri %x " | 1113 | "6072 NVME Completion Error: xri %x " |
1114 | "status x%x result x%x placed x%x\n", | 1114 | "status x%x result x%x [x%x] " |
1115 | "placed x%x\n", | ||
1115 | lpfc_ncmd->cur_iocbq.sli4_xritag, | 1116 | lpfc_ncmd->cur_iocbq.sli4_xritag, |
1116 | lpfc_ncmd->status, lpfc_ncmd->result, | 1117 | lpfc_ncmd->status, lpfc_ncmd->result, |
1118 | wcqe->parameter, | ||
1117 | wcqe->total_data_placed); | 1119 | wcqe->total_data_placed); |
1118 | nCmd->transferred_length = 0; | 1120 | nCmd->transferred_length = 0; |
1119 | nCmd->rcv_rsplen = 0; | 1121 | nCmd->rcv_rsplen = 0; |
@@ -1141,7 +1143,7 @@ out_err: | |||
1141 | if (phba->cpucheck_on & LPFC_CHECK_NVME_IO) { | 1143 | if (phba->cpucheck_on & LPFC_CHECK_NVME_IO) { |
1142 | uint32_t cpu; | 1144 | uint32_t cpu; |
1143 | idx = lpfc_ncmd->cur_iocbq.hba_wqidx; | 1145 | idx = lpfc_ncmd->cur_iocbq.hba_wqidx; |
1144 | cpu = smp_processor_id(); | 1146 | cpu = raw_smp_processor_id(); |
1145 | if (cpu < LPFC_CHECK_CPU_CNT) { | 1147 | if (cpu < LPFC_CHECK_CPU_CNT) { |
1146 | if (lpfc_ncmd->cpu != cpu) | 1148 | if (lpfc_ncmd->cpu != cpu) |
1147 | lpfc_printf_vlog(vport, | 1149 | lpfc_printf_vlog(vport, |
@@ -1559,7 +1561,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, | |||
1559 | if (phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_HDWQ) { | 1561 | if (phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_HDWQ) { |
1560 | idx = lpfc_queue_info->index; | 1562 | idx = lpfc_queue_info->index; |
1561 | } else { | 1563 | } else { |
1562 | cpu = smp_processor_id(); | 1564 | cpu = raw_smp_processor_id(); |
1563 | idx = phba->sli4_hba.cpu_map[cpu].hdwq; | 1565 | idx = phba->sli4_hba.cpu_map[cpu].hdwq; |
1564 | } | 1566 | } |
1565 | 1567 | ||
@@ -1639,7 +1641,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, | |||
1639 | lpfc_ncmd->ts_cmd_wqput = ktime_get_ns(); | 1641 | lpfc_ncmd->ts_cmd_wqput = ktime_get_ns(); |
1640 | 1642 | ||
1641 | if (phba->cpucheck_on & LPFC_CHECK_NVME_IO) { | 1643 | if (phba->cpucheck_on & LPFC_CHECK_NVME_IO) { |
1642 | cpu = smp_processor_id(); | 1644 | cpu = raw_smp_processor_id(); |
1643 | if (cpu < LPFC_CHECK_CPU_CNT) { | 1645 | if (cpu < LPFC_CHECK_CPU_CNT) { |
1644 | lpfc_ncmd->cpu = cpu; | 1646 | lpfc_ncmd->cpu = cpu; |
1645 | if (idx != cpu) | 1647 | if (idx != cpu) |
@@ -2081,15 +2083,15 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport) | |||
2081 | lpfc_nvme_template.max_hw_queues = | 2083 | lpfc_nvme_template.max_hw_queues = |
2082 | phba->sli4_hba.num_present_cpu; | 2084 | phba->sli4_hba.num_present_cpu; |
2083 | 2085 | ||
2086 | if (!IS_ENABLED(CONFIG_NVME_FC)) | ||
2087 | return ret; | ||
2088 | |||
2084 | /* localport is allocated from the stack, but the registration | 2089 | /* localport is allocated from the stack, but the registration |
2085 | * call allocates heap memory as well as the private area. | 2090 | * call allocates heap memory as well as the private area. |
2086 | */ | 2091 | */ |
2087 | #if (IS_ENABLED(CONFIG_NVME_FC)) | 2092 | |
2088 | ret = nvme_fc_register_localport(&nfcp_info, &lpfc_nvme_template, | 2093 | ret = nvme_fc_register_localport(&nfcp_info, &lpfc_nvme_template, |
2089 | &vport->phba->pcidev->dev, &localport); | 2094 | &vport->phba->pcidev->dev, &localport); |
2090 | #else | ||
2091 | ret = -ENOMEM; | ||
2092 | #endif | ||
2093 | if (!ret) { | 2095 | if (!ret) { |
2094 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME | LOG_NVME_DISC, | 2096 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME | LOG_NVME_DISC, |
2095 | "6005 Successfully registered local " | 2097 | "6005 Successfully registered local " |
@@ -2124,6 +2126,7 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport) | |||
2124 | return ret; | 2126 | return ret; |
2125 | } | 2127 | } |
2126 | 2128 | ||
2129 | #if (IS_ENABLED(CONFIG_NVME_FC)) | ||
2127 | /* lpfc_nvme_lport_unreg_wait - Wait for the host to complete an lport unreg. | 2130 | /* lpfc_nvme_lport_unreg_wait - Wait for the host to complete an lport unreg. |
2128 | * | 2131 | * |
2129 | * The driver has to wait for the host nvme transport to callback | 2132 | * The driver has to wait for the host nvme transport to callback |
@@ -2134,12 +2137,11 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport) | |||
2134 | * An uninterruptible wait is used because of the risk of transport-to- | 2137 | * An uninterruptible wait is used because of the risk of transport-to- |
2135 | * driver state mismatch. | 2138 | * driver state mismatch. |
2136 | */ | 2139 | */ |
2137 | void | 2140 | static void |
2138 | lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport, | 2141 | lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport, |
2139 | struct lpfc_nvme_lport *lport, | 2142 | struct lpfc_nvme_lport *lport, |
2140 | struct completion *lport_unreg_cmp) | 2143 | struct completion *lport_unreg_cmp) |
2141 | { | 2144 | { |
2142 | #if (IS_ENABLED(CONFIG_NVME_FC)) | ||
2143 | u32 wait_tmo; | 2145 | u32 wait_tmo; |
2144 | int ret; | 2146 | int ret; |
2145 | 2147 | ||
@@ -2162,8 +2164,8 @@ lpfc_nvme_lport_unreg_wait(struct lpfc_vport *vport, | |||
2162 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR, | 2164 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR, |
2163 | "6177 Lport %p Localport %p Complete Success\n", | 2165 | "6177 Lport %p Localport %p Complete Success\n", |
2164 | lport, vport->localport); | 2166 | lport, vport->localport); |
2165 | #endif | ||
2166 | } | 2167 | } |
2168 | #endif | ||
2167 | 2169 | ||
2168 | /** | 2170 | /** |
2169 | * lpfc_nvme_destroy_localport - Destroy lpfc_nvme bound to nvme transport. | 2171 | * lpfc_nvme_destroy_localport - Destroy lpfc_nvme bound to nvme transport. |
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index 361e2b103648..d74bfd264495 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c | |||
@@ -220,7 +220,7 @@ lpfc_nvmet_cmd_template(void) | |||
220 | /* Word 12, 13, 14, 15 - is zero */ | 220 | /* Word 12, 13, 14, 15 - is zero */ |
221 | } | 221 | } |
222 | 222 | ||
223 | void | 223 | static void |
224 | lpfc_nvmet_defer_release(struct lpfc_hba *phba, struct lpfc_nvmet_rcv_ctx *ctxp) | 224 | lpfc_nvmet_defer_release(struct lpfc_hba *phba, struct lpfc_nvmet_rcv_ctx *ctxp) |
225 | { | 225 | { |
226 | lockdep_assert_held(&ctxp->ctxlock); | 226 | lockdep_assert_held(&ctxp->ctxlock); |
@@ -325,7 +325,6 @@ lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba, struct lpfc_nvmet_ctxbuf *ctx_buf) | |||
325 | struct fc_frame_header *fc_hdr; | 325 | struct fc_frame_header *fc_hdr; |
326 | struct rqb_dmabuf *nvmebuf; | 326 | struct rqb_dmabuf *nvmebuf; |
327 | struct lpfc_nvmet_ctx_info *infop; | 327 | struct lpfc_nvmet_ctx_info *infop; |
328 | uint32_t *payload; | ||
329 | uint32_t size, oxid, sid; | 328 | uint32_t size, oxid, sid; |
330 | int cpu; | 329 | int cpu; |
331 | unsigned long iflag; | 330 | unsigned long iflag; |
@@ -370,7 +369,6 @@ lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba, struct lpfc_nvmet_ctxbuf *ctx_buf) | |||
370 | fc_hdr = (struct fc_frame_header *)(nvmebuf->hbuf.virt); | 369 | fc_hdr = (struct fc_frame_header *)(nvmebuf->hbuf.virt); |
371 | oxid = be16_to_cpu(fc_hdr->fh_ox_id); | 370 | oxid = be16_to_cpu(fc_hdr->fh_ox_id); |
372 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; | 371 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; |
373 | payload = (uint32_t *)(nvmebuf->dbuf.virt); | ||
374 | size = nvmebuf->bytes_recv; | 372 | size = nvmebuf->bytes_recv; |
375 | sid = sli4_sid_from_fc_hdr(fc_hdr); | 373 | sid = sli4_sid_from_fc_hdr(fc_hdr); |
376 | 374 | ||
@@ -435,7 +433,7 @@ lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba, struct lpfc_nvmet_ctxbuf *ctx_buf) | |||
435 | * Use the CPU context list, from the MRQ the IO was received on | 433 | * Use the CPU context list, from the MRQ the IO was received on |
436 | * (ctxp->idx), to save context structure. | 434 | * (ctxp->idx), to save context structure. |
437 | */ | 435 | */ |
438 | cpu = smp_processor_id(); | 436 | cpu = raw_smp_processor_id(); |
439 | infop = lpfc_get_ctx_list(phba, cpu, ctxp->idx); | 437 | infop = lpfc_get_ctx_list(phba, cpu, ctxp->idx); |
440 | spin_lock_irqsave(&infop->nvmet_ctx_list_lock, iflag); | 438 | spin_lock_irqsave(&infop->nvmet_ctx_list_lock, iflag); |
441 | list_add_tail(&ctx_buf->list, &infop->nvmet_ctx_list); | 439 | list_add_tail(&ctx_buf->list, &infop->nvmet_ctx_list); |
@@ -765,7 +763,7 @@ lpfc_nvmet_xmt_fcp_op_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe, | |||
765 | } | 763 | } |
766 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS | 764 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS |
767 | if (phba->cpucheck_on & LPFC_CHECK_NVMET_IO) { | 765 | if (phba->cpucheck_on & LPFC_CHECK_NVMET_IO) { |
768 | id = smp_processor_id(); | 766 | id = raw_smp_processor_id(); |
769 | if (id < LPFC_CHECK_CPU_CNT) { | 767 | if (id < LPFC_CHECK_CPU_CNT) { |
770 | if (ctxp->cpu != id) | 768 | if (ctxp->cpu != id) |
771 | lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR, | 769 | lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR, |
@@ -906,7 +904,7 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport, | |||
906 | ctxp->hdwq = &phba->sli4_hba.hdwq[rsp->hwqid]; | 904 | ctxp->hdwq = &phba->sli4_hba.hdwq[rsp->hwqid]; |
907 | 905 | ||
908 | if (phba->cpucheck_on & LPFC_CHECK_NVMET_IO) { | 906 | if (phba->cpucheck_on & LPFC_CHECK_NVMET_IO) { |
909 | int id = smp_processor_id(); | 907 | int id = raw_smp_processor_id(); |
910 | if (id < LPFC_CHECK_CPU_CNT) { | 908 | if (id < LPFC_CHECK_CPU_CNT) { |
911 | if (rsp->hwqid != id) | 909 | if (rsp->hwqid != id) |
912 | lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR, | 910 | lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR, |
@@ -1120,7 +1118,7 @@ lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport, | |||
1120 | 1118 | ||
1121 | 1119 | ||
1122 | lpfc_nvmeio_data(phba, "NVMET DEFERRCV: xri x%x sz %d CPU %02x\n", | 1120 | lpfc_nvmeio_data(phba, "NVMET DEFERRCV: xri x%x sz %d CPU %02x\n", |
1123 | ctxp->oxid, ctxp->size, smp_processor_id()); | 1121 | ctxp->oxid, ctxp->size, raw_smp_processor_id()); |
1124 | 1122 | ||
1125 | if (!nvmebuf) { | 1123 | if (!nvmebuf) { |
1126 | lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR, | 1124 | lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR, |
@@ -1596,7 +1594,7 @@ lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport, | |||
1596 | 1594 | ||
1597 | lpfc_nvmeio_data(phba, | 1595 | lpfc_nvmeio_data(phba, |
1598 | "NVMET ABTS RCV: xri x%x CPU %02x rjt %d\n", | 1596 | "NVMET ABTS RCV: xri x%x CPU %02x rjt %d\n", |
1599 | xri, smp_processor_id(), 0); | 1597 | xri, raw_smp_processor_id(), 0); |
1600 | 1598 | ||
1601 | lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, | 1599 | lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, |
1602 | "6319 NVMET Rcv ABTS:acc xri x%x\n", xri); | 1600 | "6319 NVMET Rcv ABTS:acc xri x%x\n", xri); |
@@ -1612,7 +1610,7 @@ lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport, | |||
1612 | spin_unlock_irqrestore(&phba->hbalock, iflag); | 1610 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1613 | 1611 | ||
1614 | lpfc_nvmeio_data(phba, "NVMET ABTS RCV: xri x%x CPU %02x rjt %d\n", | 1612 | lpfc_nvmeio_data(phba, "NVMET ABTS RCV: xri x%x CPU %02x rjt %d\n", |
1615 | xri, smp_processor_id(), 1); | 1613 | xri, raw_smp_processor_id(), 1); |
1616 | 1614 | ||
1617 | lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, | 1615 | lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, |
1618 | "6320 NVMET Rcv ABTS:rjt xri x%x\n", xri); | 1616 | "6320 NVMET Rcv ABTS:rjt xri x%x\n", xri); |
@@ -1725,7 +1723,11 @@ lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba) | |||
1725 | } | 1723 | } |
1726 | tgtp->tport_unreg_cmp = &tport_unreg_cmp; | 1724 | tgtp->tport_unreg_cmp = &tport_unreg_cmp; |
1727 | nvmet_fc_unregister_targetport(phba->targetport); | 1725 | nvmet_fc_unregister_targetport(phba->targetport); |
1728 | wait_for_completion_timeout(&tport_unreg_cmp, 5); | 1726 | if (!wait_for_completion_timeout(tgtp->tport_unreg_cmp, |
1727 | msecs_to_jiffies(LPFC_NVMET_WAIT_TMO))) | ||
1728 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME, | ||
1729 | "6179 Unreg targetport %p timeout " | ||
1730 | "reached.\n", phba->targetport); | ||
1729 | lpfc_nvmet_cleanup_io_context(phba); | 1731 | lpfc_nvmet_cleanup_io_context(phba); |
1730 | } | 1732 | } |
1731 | phba->targetport = NULL; | 1733 | phba->targetport = NULL; |
@@ -1843,7 +1845,7 @@ lpfc_nvmet_process_rcv_fcp_req(struct lpfc_nvmet_ctxbuf *ctx_buf) | |||
1843 | struct lpfc_hba *phba = ctxp->phba; | 1845 | struct lpfc_hba *phba = ctxp->phba; |
1844 | struct rqb_dmabuf *nvmebuf = ctxp->rqb_buffer; | 1846 | struct rqb_dmabuf *nvmebuf = ctxp->rqb_buffer; |
1845 | struct lpfc_nvmet_tgtport *tgtp; | 1847 | struct lpfc_nvmet_tgtport *tgtp; |
1846 | uint32_t *payload; | 1848 | uint32_t *payload, qno; |
1847 | uint32_t rc; | 1849 | uint32_t rc; |
1848 | unsigned long iflags; | 1850 | unsigned long iflags; |
1849 | 1851 | ||
@@ -1876,6 +1878,15 @@ lpfc_nvmet_process_rcv_fcp_req(struct lpfc_nvmet_ctxbuf *ctx_buf) | |||
1876 | /* Process FCP command */ | 1878 | /* Process FCP command */ |
1877 | if (rc == 0) { | 1879 | if (rc == 0) { |
1878 | atomic_inc(&tgtp->rcv_fcp_cmd_out); | 1880 | atomic_inc(&tgtp->rcv_fcp_cmd_out); |
1881 | spin_lock_irqsave(&ctxp->ctxlock, iflags); | ||
1882 | if ((ctxp->flag & LPFC_NVMET_CTX_REUSE_WQ) || | ||
1883 | (nvmebuf != ctxp->rqb_buffer)) { | ||
1884 | spin_unlock_irqrestore(&ctxp->ctxlock, iflags); | ||
1885 | return; | ||
1886 | } | ||
1887 | ctxp->rqb_buffer = NULL; | ||
1888 | spin_unlock_irqrestore(&ctxp->ctxlock, iflags); | ||
1889 | lpfc_rq_buf_free(phba, &nvmebuf->hbuf); /* repost */ | ||
1879 | return; | 1890 | return; |
1880 | } | 1891 | } |
1881 | 1892 | ||
@@ -1886,6 +1897,20 @@ lpfc_nvmet_process_rcv_fcp_req(struct lpfc_nvmet_ctxbuf *ctx_buf) | |||
1886 | ctxp->oxid, ctxp->size, ctxp->sid); | 1897 | ctxp->oxid, ctxp->size, ctxp->sid); |
1887 | atomic_inc(&tgtp->rcv_fcp_cmd_out); | 1898 | atomic_inc(&tgtp->rcv_fcp_cmd_out); |
1888 | atomic_inc(&tgtp->defer_fod); | 1899 | atomic_inc(&tgtp->defer_fod); |
1900 | spin_lock_irqsave(&ctxp->ctxlock, iflags); | ||
1901 | if (ctxp->flag & LPFC_NVMET_CTX_REUSE_WQ) { | ||
1902 | spin_unlock_irqrestore(&ctxp->ctxlock, iflags); | ||
1903 | return; | ||
1904 | } | ||
1905 | spin_unlock_irqrestore(&ctxp->ctxlock, iflags); | ||
1906 | /* | ||
1907 | * Post a replacement DMA buffer to RQ and defer | ||
1908 | * freeing rcv buffer till .defer_rcv callback | ||
1909 | */ | ||
1910 | qno = nvmebuf->idx; | ||
1911 | lpfc_post_rq_buffer( | ||
1912 | phba, phba->sli4_hba.nvmet_mrq_hdr[qno], | ||
1913 | phba->sli4_hba.nvmet_mrq_data[qno], 1, qno); | ||
1889 | return; | 1914 | return; |
1890 | } | 1915 | } |
1891 | atomic_inc(&tgtp->rcv_fcp_cmd_drop); | 1916 | atomic_inc(&tgtp->rcv_fcp_cmd_drop); |
@@ -1996,7 +2021,6 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba, | |||
1996 | struct fc_frame_header *fc_hdr; | 2021 | struct fc_frame_header *fc_hdr; |
1997 | struct lpfc_nvmet_ctxbuf *ctx_buf; | 2022 | struct lpfc_nvmet_ctxbuf *ctx_buf; |
1998 | struct lpfc_nvmet_ctx_info *current_infop; | 2023 | struct lpfc_nvmet_ctx_info *current_infop; |
1999 | uint32_t *payload; | ||
2000 | uint32_t size, oxid, sid, qno; | 2024 | uint32_t size, oxid, sid, qno; |
2001 | unsigned long iflag; | 2025 | unsigned long iflag; |
2002 | int current_cpu; | 2026 | int current_cpu; |
@@ -2020,7 +2044,7 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba, | |||
2020 | * be empty, thus it would need to be replenished with the | 2044 | * be empty, thus it would need to be replenished with the |
2021 | * context list from another CPU for this MRQ. | 2045 | * context list from another CPU for this MRQ. |
2022 | */ | 2046 | */ |
2023 | current_cpu = smp_processor_id(); | 2047 | current_cpu = raw_smp_processor_id(); |
2024 | current_infop = lpfc_get_ctx_list(phba, current_cpu, idx); | 2048 | current_infop = lpfc_get_ctx_list(phba, current_cpu, idx); |
2025 | spin_lock_irqsave(¤t_infop->nvmet_ctx_list_lock, iflag); | 2049 | spin_lock_irqsave(¤t_infop->nvmet_ctx_list_lock, iflag); |
2026 | if (current_infop->nvmet_ctx_list_cnt) { | 2050 | if (current_infop->nvmet_ctx_list_cnt) { |
@@ -2050,7 +2074,7 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba, | |||
2050 | #endif | 2074 | #endif |
2051 | 2075 | ||
2052 | lpfc_nvmeio_data(phba, "NVMET FCP RCV: xri x%x sz %d CPU %02x\n", | 2076 | lpfc_nvmeio_data(phba, "NVMET FCP RCV: xri x%x sz %d CPU %02x\n", |
2053 | oxid, size, smp_processor_id()); | 2077 | oxid, size, raw_smp_processor_id()); |
2054 | 2078 | ||
2055 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; | 2079 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; |
2056 | 2080 | ||
@@ -2074,7 +2098,6 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba, | |||
2074 | return; | 2098 | return; |
2075 | } | 2099 | } |
2076 | 2100 | ||
2077 | payload = (uint32_t *)(nvmebuf->dbuf.virt); | ||
2078 | sid = sli4_sid_from_fc_hdr(fc_hdr); | 2101 | sid = sli4_sid_from_fc_hdr(fc_hdr); |
2079 | 2102 | ||
2080 | ctxp = (struct lpfc_nvmet_rcv_ctx *)ctx_buf->context; | 2103 | ctxp = (struct lpfc_nvmet_rcv_ctx *)ctx_buf->context; |
@@ -2690,12 +2713,11 @@ lpfc_nvmet_sol_fcp_abort_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe, | |||
2690 | { | 2713 | { |
2691 | struct lpfc_nvmet_rcv_ctx *ctxp; | 2714 | struct lpfc_nvmet_rcv_ctx *ctxp; |
2692 | struct lpfc_nvmet_tgtport *tgtp; | 2715 | struct lpfc_nvmet_tgtport *tgtp; |
2693 | uint32_t status, result; | 2716 | uint32_t result; |
2694 | unsigned long flags; | 2717 | unsigned long flags; |
2695 | bool released = false; | 2718 | bool released = false; |
2696 | 2719 | ||
2697 | ctxp = cmdwqe->context2; | 2720 | ctxp = cmdwqe->context2; |
2698 | status = bf_get(lpfc_wcqe_c_status, wcqe); | ||
2699 | result = wcqe->parameter; | 2721 | result = wcqe->parameter; |
2700 | 2722 | ||
2701 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; | 2723 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; |
@@ -2761,11 +2783,10 @@ lpfc_nvmet_unsol_fcp_abort_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe, | |||
2761 | struct lpfc_nvmet_rcv_ctx *ctxp; | 2783 | struct lpfc_nvmet_rcv_ctx *ctxp; |
2762 | struct lpfc_nvmet_tgtport *tgtp; | 2784 | struct lpfc_nvmet_tgtport *tgtp; |
2763 | unsigned long flags; | 2785 | unsigned long flags; |
2764 | uint32_t status, result; | 2786 | uint32_t result; |
2765 | bool released = false; | 2787 | bool released = false; |
2766 | 2788 | ||
2767 | ctxp = cmdwqe->context2; | 2789 | ctxp = cmdwqe->context2; |
2768 | status = bf_get(lpfc_wcqe_c_status, wcqe); | ||
2769 | result = wcqe->parameter; | 2790 | result = wcqe->parameter; |
2770 | 2791 | ||
2771 | if (!ctxp) { | 2792 | if (!ctxp) { |
@@ -2842,10 +2863,9 @@ lpfc_nvmet_xmt_ls_abort_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe, | |||
2842 | { | 2863 | { |
2843 | struct lpfc_nvmet_rcv_ctx *ctxp; | 2864 | struct lpfc_nvmet_rcv_ctx *ctxp; |
2844 | struct lpfc_nvmet_tgtport *tgtp; | 2865 | struct lpfc_nvmet_tgtport *tgtp; |
2845 | uint32_t status, result; | 2866 | uint32_t result; |
2846 | 2867 | ||
2847 | ctxp = cmdwqe->context2; | 2868 | ctxp = cmdwqe->context2; |
2848 | status = bf_get(lpfc_wcqe_c_status, wcqe); | ||
2849 | result = wcqe->parameter; | 2869 | result = wcqe->parameter; |
2850 | 2870 | ||
2851 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; | 2871 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; |
@@ -3200,7 +3220,6 @@ lpfc_nvmet_unsol_ls_issue_abort(struct lpfc_hba *phba, | |||
3200 | { | 3220 | { |
3201 | struct lpfc_nvmet_tgtport *tgtp; | 3221 | struct lpfc_nvmet_tgtport *tgtp; |
3202 | struct lpfc_iocbq *abts_wqeq; | 3222 | struct lpfc_iocbq *abts_wqeq; |
3203 | union lpfc_wqe128 *wqe_abts; | ||
3204 | unsigned long flags; | 3223 | unsigned long flags; |
3205 | int rc; | 3224 | int rc; |
3206 | 3225 | ||
@@ -3230,7 +3249,6 @@ lpfc_nvmet_unsol_ls_issue_abort(struct lpfc_hba *phba, | |||
3230 | } | 3249 | } |
3231 | } | 3250 | } |
3232 | abts_wqeq = ctxp->wqeq; | 3251 | abts_wqeq = ctxp->wqeq; |
3233 | wqe_abts = &abts_wqeq->wqe; | ||
3234 | 3252 | ||
3235 | if (lpfc_nvmet_unsol_issue_abort(phba, ctxp, sid, xri) == 0) { | 3253 | if (lpfc_nvmet_unsol_issue_abort(phba, ctxp, sid, xri) == 0) { |
3236 | rc = WQE_BUSY; | 3254 | rc = WQE_BUSY; |
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.h b/drivers/scsi/lpfc/lpfc_nvmet.h index 368deea2bcf8..2f3f603d94c4 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.h +++ b/drivers/scsi/lpfc/lpfc_nvmet.h | |||
@@ -27,10 +27,11 @@ | |||
27 | #define LPFC_NVMET_RQE_DEF_COUNT 2048 | 27 | #define LPFC_NVMET_RQE_DEF_COUNT 2048 |
28 | #define LPFC_NVMET_SUCCESS_LEN 12 | 28 | #define LPFC_NVMET_SUCCESS_LEN 12 |
29 | 29 | ||
30 | #define LPFC_NVMET_MRQ_OFF 0xffff | ||
31 | #define LPFC_NVMET_MRQ_AUTO 0 | 30 | #define LPFC_NVMET_MRQ_AUTO 0 |
32 | #define LPFC_NVMET_MRQ_MAX 16 | 31 | #define LPFC_NVMET_MRQ_MAX 16 |
33 | 32 | ||
33 | #define LPFC_NVMET_WAIT_TMO (5 * MSEC_PER_SEC) | ||
34 | |||
34 | /* Used for NVME Target */ | 35 | /* Used for NVME Target */ |
35 | struct lpfc_nvmet_tgtport { | 36 | struct lpfc_nvmet_tgtport { |
36 | struct lpfc_hba *phba; | 37 | struct lpfc_hba *phba; |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index ff3c5e0f4e2b..ba996fbde89b 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -688,7 +688,7 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
688 | uint32_t sgl_size, cpu, idx; | 688 | uint32_t sgl_size, cpu, idx; |
689 | int tag; | 689 | int tag; |
690 | 690 | ||
691 | cpu = smp_processor_id(); | 691 | cpu = raw_smp_processor_id(); |
692 | if (cmnd && phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_HDWQ) { | 692 | if (cmnd && phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_HDWQ) { |
693 | tag = blk_mq_unique_tag(cmnd->request); | 693 | tag = blk_mq_unique_tag(cmnd->request); |
694 | idx = blk_mq_unique_tag_to_hwq(tag); | 694 | idx = blk_mq_unique_tag_to_hwq(tag); |
@@ -3669,8 +3669,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
3669 | 3669 | ||
3670 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS | 3670 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS |
3671 | if (phba->cpucheck_on & LPFC_CHECK_SCSI_IO) { | 3671 | if (phba->cpucheck_on & LPFC_CHECK_SCSI_IO) { |
3672 | cpu = smp_processor_id(); | 3672 | cpu = raw_smp_processor_id(); |
3673 | if (cpu < LPFC_CHECK_CPU_CNT) | 3673 | if (cpu < LPFC_CHECK_CPU_CNT && phba->sli4_hba.hdwq) |
3674 | phba->sli4_hba.hdwq[idx].cpucheck_cmpl_io[cpu]++; | 3674 | phba->sli4_hba.hdwq[idx].cpucheck_cmpl_io[cpu]++; |
3675 | } | 3675 | } |
3676 | #endif | 3676 | #endif |
@@ -4463,7 +4463,7 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) | |||
4463 | 4463 | ||
4464 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS | 4464 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS |
4465 | if (phba->cpucheck_on & LPFC_CHECK_SCSI_IO) { | 4465 | if (phba->cpucheck_on & LPFC_CHECK_SCSI_IO) { |
4466 | cpu = smp_processor_id(); | 4466 | cpu = raw_smp_processor_id(); |
4467 | if (cpu < LPFC_CHECK_CPU_CNT) { | 4467 | if (cpu < LPFC_CHECK_CPU_CNT) { |
4468 | struct lpfc_sli4_hdw_queue *hdwq = | 4468 | struct lpfc_sli4_hdw_queue *hdwq = |
4469 | &phba->sli4_hba.hdwq[lpfc_cmd->hdwq_no]; | 4469 | &phba->sli4_hba.hdwq[lpfc_cmd->hdwq_no]; |
@@ -5048,7 +5048,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) | |||
5048 | rdata = lpfc_rport_data_from_scsi_device(cmnd->device); | 5048 | rdata = lpfc_rport_data_from_scsi_device(cmnd->device); |
5049 | if (!rdata || !rdata->pnode) { | 5049 | if (!rdata || !rdata->pnode) { |
5050 | lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, | 5050 | lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, |
5051 | "0798 Device Reset rport failure: rdata x%p\n", | 5051 | "0798 Device Reset rdata failure: rdata x%p\n", |
5052 | rdata); | 5052 | rdata); |
5053 | return FAILED; | 5053 | return FAILED; |
5054 | } | 5054 | } |
@@ -5117,9 +5117,10 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd) | |||
5117 | int status; | 5117 | int status; |
5118 | 5118 | ||
5119 | rdata = lpfc_rport_data_from_scsi_device(cmnd->device); | 5119 | rdata = lpfc_rport_data_from_scsi_device(cmnd->device); |
5120 | if (!rdata) { | 5120 | if (!rdata || !rdata->pnode) { |
5121 | lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, | 5121 | lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, |
5122 | "0799 Target Reset rport failure: rdata x%p\n", rdata); | 5122 | "0799 Target Reset rdata failure: rdata x%p\n", |
5123 | rdata); | ||
5123 | return FAILED; | 5124 | return FAILED; |
5124 | } | 5125 | } |
5125 | pnode = rdata->pnode; | 5126 | pnode = rdata->pnode; |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 57b4a463b589..2acda188b0dc 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -87,9 +87,6 @@ static void lpfc_sli4_hba_handle_eqe(struct lpfc_hba *phba, | |||
87 | struct lpfc_eqe *eqe); | 87 | struct lpfc_eqe *eqe); |
88 | static bool lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba); | 88 | static bool lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba); |
89 | static bool lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba); | 89 | static bool lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba); |
90 | static int lpfc_sli4_abort_nvme_io(struct lpfc_hba *phba, | ||
91 | struct lpfc_sli_ring *pring, | ||
92 | struct lpfc_iocbq *cmdiocb); | ||
93 | 90 | ||
94 | static IOCB_t * | 91 | static IOCB_t * |
95 | lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq) | 92 | lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq) |
@@ -151,7 +148,7 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe128 *wqe) | |||
151 | /* sanity check on queue memory */ | 148 | /* sanity check on queue memory */ |
152 | if (unlikely(!q)) | 149 | if (unlikely(!q)) |
153 | return -ENOMEM; | 150 | return -ENOMEM; |
154 | temp_wqe = q->qe[q->host_index].wqe; | 151 | temp_wqe = lpfc_sli4_qe(q, q->host_index); |
155 | 152 | ||
156 | /* If the host has not yet processed the next entry then we are done */ | 153 | /* If the host has not yet processed the next entry then we are done */ |
157 | idx = ((q->host_index + 1) % q->entry_count); | 154 | idx = ((q->host_index + 1) % q->entry_count); |
@@ -271,7 +268,7 @@ lpfc_sli4_mq_put(struct lpfc_queue *q, struct lpfc_mqe *mqe) | |||
271 | /* sanity check on queue memory */ | 268 | /* sanity check on queue memory */ |
272 | if (unlikely(!q)) | 269 | if (unlikely(!q)) |
273 | return -ENOMEM; | 270 | return -ENOMEM; |
274 | temp_mqe = q->qe[q->host_index].mqe; | 271 | temp_mqe = lpfc_sli4_qe(q, q->host_index); |
275 | 272 | ||
276 | /* If the host has not yet processed the next entry then we are done */ | 273 | /* If the host has not yet processed the next entry then we are done */ |
277 | if (((q->host_index + 1) % q->entry_count) == q->hba_index) | 274 | if (((q->host_index + 1) % q->entry_count) == q->hba_index) |
@@ -331,7 +328,7 @@ lpfc_sli4_eq_get(struct lpfc_queue *q) | |||
331 | /* sanity check on queue memory */ | 328 | /* sanity check on queue memory */ |
332 | if (unlikely(!q)) | 329 | if (unlikely(!q)) |
333 | return NULL; | 330 | return NULL; |
334 | eqe = q->qe[q->host_index].eqe; | 331 | eqe = lpfc_sli4_qe(q, q->host_index); |
335 | 332 | ||
336 | /* If the next EQE is not valid then we are done */ | 333 | /* If the next EQE is not valid then we are done */ |
337 | if (bf_get_le32(lpfc_eqe_valid, eqe) != q->qe_valid) | 334 | if (bf_get_le32(lpfc_eqe_valid, eqe) != q->qe_valid) |
@@ -355,7 +352,7 @@ lpfc_sli4_eq_get(struct lpfc_queue *q) | |||
355 | * @q: The Event Queue to disable interrupts | 352 | * @q: The Event Queue to disable interrupts |
356 | * | 353 | * |
357 | **/ | 354 | **/ |
358 | inline void | 355 | void |
359 | lpfc_sli4_eq_clr_intr(struct lpfc_queue *q) | 356 | lpfc_sli4_eq_clr_intr(struct lpfc_queue *q) |
360 | { | 357 | { |
361 | struct lpfc_register doorbell; | 358 | struct lpfc_register doorbell; |
@@ -374,7 +371,7 @@ lpfc_sli4_eq_clr_intr(struct lpfc_queue *q) | |||
374 | * @q: The Event Queue to disable interrupts | 371 | * @q: The Event Queue to disable interrupts |
375 | * | 372 | * |
376 | **/ | 373 | **/ |
377 | inline void | 374 | void |
378 | lpfc_sli4_if6_eq_clr_intr(struct lpfc_queue *q) | 375 | lpfc_sli4_if6_eq_clr_intr(struct lpfc_queue *q) |
379 | { | 376 | { |
380 | struct lpfc_register doorbell; | 377 | struct lpfc_register doorbell; |
@@ -545,7 +542,7 @@ lpfc_sli4_cq_get(struct lpfc_queue *q) | |||
545 | /* sanity check on queue memory */ | 542 | /* sanity check on queue memory */ |
546 | if (unlikely(!q)) | 543 | if (unlikely(!q)) |
547 | return NULL; | 544 | return NULL; |
548 | cqe = q->qe[q->host_index].cqe; | 545 | cqe = lpfc_sli4_qe(q, q->host_index); |
549 | 546 | ||
550 | /* If the next CQE is not valid then we are done */ | 547 | /* If the next CQE is not valid then we are done */ |
551 | if (bf_get_le32(lpfc_cqe_valid, cqe) != q->qe_valid) | 548 | if (bf_get_le32(lpfc_cqe_valid, cqe) != q->qe_valid) |
@@ -667,8 +664,8 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq, | |||
667 | return -ENOMEM; | 664 | return -ENOMEM; |
668 | hq_put_index = hq->host_index; | 665 | hq_put_index = hq->host_index; |
669 | dq_put_index = dq->host_index; | 666 | dq_put_index = dq->host_index; |
670 | temp_hrqe = hq->qe[hq_put_index].rqe; | 667 | temp_hrqe = lpfc_sli4_qe(hq, hq_put_index); |
671 | temp_drqe = dq->qe[dq_put_index].rqe; | 668 | temp_drqe = lpfc_sli4_qe(dq, dq_put_index); |
672 | 669 | ||
673 | if (hq->type != LPFC_HRQ || dq->type != LPFC_DRQ) | 670 | if (hq->type != LPFC_HRQ || dq->type != LPFC_DRQ) |
674 | return -EINVAL; | 671 | return -EINVAL; |
@@ -907,10 +904,10 @@ lpfc_handle_rrq_active(struct lpfc_hba *phba) | |||
907 | mod_timer(&phba->rrq_tmr, next_time); | 904 | mod_timer(&phba->rrq_tmr, next_time); |
908 | list_for_each_entry_safe(rrq, nextrrq, &send_rrq, list) { | 905 | list_for_each_entry_safe(rrq, nextrrq, &send_rrq, list) { |
909 | list_del(&rrq->list); | 906 | list_del(&rrq->list); |
910 | if (!rrq->send_rrq) | 907 | if (!rrq->send_rrq) { |
911 | /* this call will free the rrq */ | 908 | /* this call will free the rrq */ |
912 | lpfc_clr_rrq_active(phba, rrq->xritag, rrq); | 909 | lpfc_clr_rrq_active(phba, rrq->xritag, rrq); |
913 | else if (lpfc_send_rrq(phba, rrq)) { | 910 | } else if (lpfc_send_rrq(phba, rrq)) { |
914 | /* if we send the rrq then the completion handler | 911 | /* if we send the rrq then the completion handler |
915 | * will clear the bit in the xribitmap. | 912 | * will clear the bit in the xribitmap. |
916 | */ | 913 | */ |
@@ -2502,8 +2499,8 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2502 | } else { | 2499 | } else { |
2503 | ndlp->nlp_flag &= ~NLP_UNREG_INP; | 2500 | ndlp->nlp_flag &= ~NLP_UNREG_INP; |
2504 | } | 2501 | } |
2502 | pmb->ctx_ndlp = NULL; | ||
2505 | } | 2503 | } |
2506 | pmb->ctx_ndlp = NULL; | ||
2507 | } | 2504 | } |
2508 | 2505 | ||
2509 | /* Check security permission status on INIT_LINK mailbox command */ | 2506 | /* Check security permission status on INIT_LINK mailbox command */ |
@@ -3922,33 +3919,6 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | |||
3922 | } | 3919 | } |
3923 | 3920 | ||
3924 | /** | 3921 | /** |
3925 | * lpfc_sli_abort_wqe_ring - Abort all iocbs in the ring | ||
3926 | * @phba: Pointer to HBA context object. | ||
3927 | * @pring: Pointer to driver SLI ring object. | ||
3928 | * | ||
3929 | * This function aborts all iocbs in the given ring and frees all the iocb | ||
3930 | * objects in txq. This function issues an abort iocb for all the iocb commands | ||
3931 | * in txcmplq. The iocbs in the txcmplq is not guaranteed to complete before | ||
3932 | * the return of this function. The caller is not required to hold any locks. | ||
3933 | **/ | ||
3934 | void | ||
3935 | lpfc_sli_abort_wqe_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) | ||
3936 | { | ||
3937 | LIST_HEAD(completions); | ||
3938 | struct lpfc_iocbq *iocb, *next_iocb; | ||
3939 | |||
3940 | if (pring->ringno == LPFC_ELS_RING) | ||
3941 | lpfc_fabric_abort_hba(phba); | ||
3942 | |||
3943 | spin_lock_irq(&phba->hbalock); | ||
3944 | /* Next issue ABTS for everything on the txcmplq */ | ||
3945 | list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) | ||
3946 | lpfc_sli4_abort_nvme_io(phba, pring, iocb); | ||
3947 | spin_unlock_irq(&phba->hbalock); | ||
3948 | } | ||
3949 | |||
3950 | |||
3951 | /** | ||
3952 | * lpfc_sli_abort_fcp_rings - Abort all iocbs in all FCP rings | 3922 | * lpfc_sli_abort_fcp_rings - Abort all iocbs in all FCP rings |
3953 | * @phba: Pointer to HBA context object. | 3923 | * @phba: Pointer to HBA context object. |
3954 | * @pring: Pointer to driver SLI ring object. | 3924 | * @pring: Pointer to driver SLI ring object. |
@@ -3978,33 +3948,6 @@ lpfc_sli_abort_fcp_rings(struct lpfc_hba *phba) | |||
3978 | } | 3948 | } |
3979 | 3949 | ||
3980 | /** | 3950 | /** |
3981 | * lpfc_sli_abort_nvme_rings - Abort all wqes in all NVME rings | ||
3982 | * @phba: Pointer to HBA context object. | ||
3983 | * | ||
3984 | * This function aborts all wqes in NVME rings. This function issues an | ||
3985 | * abort wqe for all the outstanding IO commands in txcmplq. The iocbs in | ||
3986 | * the txcmplq is not guaranteed to complete before the return of this | ||
3987 | * function. The caller is not required to hold any locks. | ||
3988 | **/ | ||
3989 | void | ||
3990 | lpfc_sli_abort_nvme_rings(struct lpfc_hba *phba) | ||
3991 | { | ||
3992 | struct lpfc_sli_ring *pring; | ||
3993 | uint32_t i; | ||
3994 | |||
3995 | if ((phba->sli_rev < LPFC_SLI_REV4) || | ||
3996 | !(phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) | ||
3997 | return; | ||
3998 | |||
3999 | /* Abort all IO on each NVME ring. */ | ||
4000 | for (i = 0; i < phba->cfg_hdw_queue; i++) { | ||
4001 | pring = phba->sli4_hba.hdwq[i].nvme_wq->pring; | ||
4002 | lpfc_sli_abort_wqe_ring(phba, pring); | ||
4003 | } | ||
4004 | } | ||
4005 | |||
4006 | |||
4007 | /** | ||
4008 | * lpfc_sli_flush_fcp_rings - flush all iocbs in the fcp ring | 3951 | * lpfc_sli_flush_fcp_rings - flush all iocbs in the fcp ring |
4009 | * @phba: Pointer to HBA context object. | 3952 | * @phba: Pointer to HBA context object. |
4010 | * | 3953 | * |
@@ -4487,7 +4430,9 @@ lpfc_sli_brdreset(struct lpfc_hba *phba) | |||
4487 | } | 4430 | } |
4488 | 4431 | ||
4489 | /* Turn off parity checking and serr during the physical reset */ | 4432 | /* Turn off parity checking and serr during the physical reset */ |
4490 | pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value); | 4433 | if (pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value)) |
4434 | return -EIO; | ||
4435 | |||
4491 | pci_write_config_word(phba->pcidev, PCI_COMMAND, | 4436 | pci_write_config_word(phba->pcidev, PCI_COMMAND, |
4492 | (cfg_value & | 4437 | (cfg_value & |
4493 | ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR))); | 4438 | ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR))); |
@@ -4564,7 +4509,12 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba) | |||
4564 | "0389 Performing PCI function reset!\n"); | 4509 | "0389 Performing PCI function reset!\n"); |
4565 | 4510 | ||
4566 | /* Turn off parity checking and serr during the physical reset */ | 4511 | /* Turn off parity checking and serr during the physical reset */ |
4567 | pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value); | 4512 | if (pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value)) { |
4513 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
4514 | "3205 PCI read Config failed\n"); | ||
4515 | return -EIO; | ||
4516 | } | ||
4517 | |||
4568 | pci_write_config_word(phba->pcidev, PCI_COMMAND, (cfg_value & | 4518 | pci_write_config_word(phba->pcidev, PCI_COMMAND, (cfg_value & |
4569 | ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR))); | 4519 | ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR))); |
4570 | 4520 | ||
@@ -5395,7 +5345,7 @@ lpfc_sli4_read_rev(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
5395 | } | 5345 | } |
5396 | 5346 | ||
5397 | /** | 5347 | /** |
5398 | * lpfc_sli4_retrieve_pport_name - Retrieve SLI4 device physical port name | 5348 | * lpfc_sli4_get_ctl_attr - Retrieve SLI4 device controller attributes |
5399 | * @phba: pointer to lpfc hba data structure. | 5349 | * @phba: pointer to lpfc hba data structure. |
5400 | * | 5350 | * |
5401 | * This routine retrieves SLI4 device physical port name this PCI function | 5351 | * This routine retrieves SLI4 device physical port name this PCI function |
@@ -5403,40 +5353,30 @@ lpfc_sli4_read_rev(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
5403 | * | 5353 | * |
5404 | * Return codes | 5354 | * Return codes |
5405 | * 0 - successful | 5355 | * 0 - successful |
5406 | * otherwise - failed to retrieve physical port name | 5356 | * otherwise - failed to retrieve controller attributes |
5407 | **/ | 5357 | **/ |
5408 | static int | 5358 | static int |
5409 | lpfc_sli4_retrieve_pport_name(struct lpfc_hba *phba) | 5359 | lpfc_sli4_get_ctl_attr(struct lpfc_hba *phba) |
5410 | { | 5360 | { |
5411 | LPFC_MBOXQ_t *mboxq; | 5361 | LPFC_MBOXQ_t *mboxq; |
5412 | struct lpfc_mbx_get_cntl_attributes *mbx_cntl_attr; | 5362 | struct lpfc_mbx_get_cntl_attributes *mbx_cntl_attr; |
5413 | struct lpfc_controller_attribute *cntl_attr; | 5363 | struct lpfc_controller_attribute *cntl_attr; |
5414 | struct lpfc_mbx_get_port_name *get_port_name; | ||
5415 | void *virtaddr = NULL; | 5364 | void *virtaddr = NULL; |
5416 | uint32_t alloclen, reqlen; | 5365 | uint32_t alloclen, reqlen; |
5417 | uint32_t shdr_status, shdr_add_status; | 5366 | uint32_t shdr_status, shdr_add_status; |
5418 | union lpfc_sli4_cfg_shdr *shdr; | 5367 | union lpfc_sli4_cfg_shdr *shdr; |
5419 | char cport_name = 0; | ||
5420 | int rc; | 5368 | int rc; |
5421 | 5369 | ||
5422 | /* We assume nothing at this point */ | ||
5423 | phba->sli4_hba.lnk_info.lnk_dv = LPFC_LNK_DAT_INVAL; | ||
5424 | phba->sli4_hba.pport_name_sta = LPFC_SLI4_PPNAME_NON; | ||
5425 | |||
5426 | mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 5370 | mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
5427 | if (!mboxq) | 5371 | if (!mboxq) |
5428 | return -ENOMEM; | 5372 | return -ENOMEM; |
5429 | /* obtain link type and link number via READ_CONFIG */ | ||
5430 | phba->sli4_hba.lnk_info.lnk_dv = LPFC_LNK_DAT_INVAL; | ||
5431 | lpfc_sli4_read_config(phba); | ||
5432 | if (phba->sli4_hba.lnk_info.lnk_dv == LPFC_LNK_DAT_VAL) | ||
5433 | goto retrieve_ppname; | ||
5434 | 5373 | ||
5435 | /* obtain link type and link number via COMMON_GET_CNTL_ATTRIBUTES */ | 5374 | /* Send COMMON_GET_CNTL_ATTRIBUTES mbox cmd */ |
5436 | reqlen = sizeof(struct lpfc_mbx_get_cntl_attributes); | 5375 | reqlen = sizeof(struct lpfc_mbx_get_cntl_attributes); |
5437 | alloclen = lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, | 5376 | alloclen = lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, |
5438 | LPFC_MBOX_OPCODE_GET_CNTL_ATTRIBUTES, reqlen, | 5377 | LPFC_MBOX_OPCODE_GET_CNTL_ATTRIBUTES, reqlen, |
5439 | LPFC_SLI4_MBX_NEMBED); | 5378 | LPFC_SLI4_MBX_NEMBED); |
5379 | |||
5440 | if (alloclen < reqlen) { | 5380 | if (alloclen < reqlen) { |
5441 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 5381 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
5442 | "3084 Allocated DMA memory size (%d) is " | 5382 | "3084 Allocated DMA memory size (%d) is " |
@@ -5462,16 +5402,71 @@ lpfc_sli4_retrieve_pport_name(struct lpfc_hba *phba) | |||
5462 | rc = -ENXIO; | 5402 | rc = -ENXIO; |
5463 | goto out_free_mboxq; | 5403 | goto out_free_mboxq; |
5464 | } | 5404 | } |
5405 | |||
5465 | cntl_attr = &mbx_cntl_attr->cntl_attr; | 5406 | cntl_attr = &mbx_cntl_attr->cntl_attr; |
5466 | phba->sli4_hba.lnk_info.lnk_dv = LPFC_LNK_DAT_VAL; | 5407 | phba->sli4_hba.lnk_info.lnk_dv = LPFC_LNK_DAT_VAL; |
5467 | phba->sli4_hba.lnk_info.lnk_tp = | 5408 | phba->sli4_hba.lnk_info.lnk_tp = |
5468 | bf_get(lpfc_cntl_attr_lnk_type, cntl_attr); | 5409 | bf_get(lpfc_cntl_attr_lnk_type, cntl_attr); |
5469 | phba->sli4_hba.lnk_info.lnk_no = | 5410 | phba->sli4_hba.lnk_info.lnk_no = |
5470 | bf_get(lpfc_cntl_attr_lnk_numb, cntl_attr); | 5411 | bf_get(lpfc_cntl_attr_lnk_numb, cntl_attr); |
5412 | |||
5413 | memset(phba->BIOSVersion, 0, sizeof(phba->BIOSVersion)); | ||
5414 | strlcat(phba->BIOSVersion, (char *)cntl_attr->bios_ver_str, | ||
5415 | sizeof(phba->BIOSVersion)); | ||
5416 | |||
5471 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | 5417 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, |
5472 | "3086 lnk_type:%d, lnk_numb:%d\n", | 5418 | "3086 lnk_type:%d, lnk_numb:%d, bios_ver:%s\n", |
5473 | phba->sli4_hba.lnk_info.lnk_tp, | 5419 | phba->sli4_hba.lnk_info.lnk_tp, |
5474 | phba->sli4_hba.lnk_info.lnk_no); | 5420 | phba->sli4_hba.lnk_info.lnk_no, |
5421 | phba->BIOSVersion); | ||
5422 | out_free_mboxq: | ||
5423 | if (rc != MBX_TIMEOUT) { | ||
5424 | if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) | ||
5425 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
5426 | else | ||
5427 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
5428 | } | ||
5429 | return rc; | ||
5430 | } | ||
5431 | |||
5432 | /** | ||
5433 | * lpfc_sli4_retrieve_pport_name - Retrieve SLI4 device physical port name | ||
5434 | * @phba: pointer to lpfc hba data structure. | ||
5435 | * | ||
5436 | * This routine retrieves SLI4 device physical port name this PCI function | ||
5437 | * is attached to. | ||
5438 | * | ||
5439 | * Return codes | ||
5440 | * 0 - successful | ||
5441 | * otherwise - failed to retrieve physical port name | ||
5442 | **/ | ||
5443 | static int | ||
5444 | lpfc_sli4_retrieve_pport_name(struct lpfc_hba *phba) | ||
5445 | { | ||
5446 | LPFC_MBOXQ_t *mboxq; | ||
5447 | struct lpfc_mbx_get_port_name *get_port_name; | ||
5448 | uint32_t shdr_status, shdr_add_status; | ||
5449 | union lpfc_sli4_cfg_shdr *shdr; | ||
5450 | char cport_name = 0; | ||
5451 | int rc; | ||
5452 | |||
5453 | /* We assume nothing at this point */ | ||
5454 | phba->sli4_hba.lnk_info.lnk_dv = LPFC_LNK_DAT_INVAL; | ||
5455 | phba->sli4_hba.pport_name_sta = LPFC_SLI4_PPNAME_NON; | ||
5456 | |||
5457 | mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
5458 | if (!mboxq) | ||
5459 | return -ENOMEM; | ||
5460 | /* obtain link type and link number via READ_CONFIG */ | ||
5461 | phba->sli4_hba.lnk_info.lnk_dv = LPFC_LNK_DAT_INVAL; | ||
5462 | lpfc_sli4_read_config(phba); | ||
5463 | if (phba->sli4_hba.lnk_info.lnk_dv == LPFC_LNK_DAT_VAL) | ||
5464 | goto retrieve_ppname; | ||
5465 | |||
5466 | /* obtain link type and link number via COMMON_GET_CNTL_ATTRIBUTES */ | ||
5467 | rc = lpfc_sli4_get_ctl_attr(phba); | ||
5468 | if (rc) | ||
5469 | goto out_free_mboxq; | ||
5475 | 5470 | ||
5476 | retrieve_ppname: | 5471 | retrieve_ppname: |
5477 | lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, | 5472 | lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON, |
@@ -7047,7 +7042,7 @@ lpfc_sli4_repost_sgl_list(struct lpfc_hba *phba, | |||
7047 | * | 7042 | * |
7048 | * Returns: 0 = success, non-zero failure. | 7043 | * Returns: 0 = success, non-zero failure. |
7049 | **/ | 7044 | **/ |
7050 | int | 7045 | static int |
7051 | lpfc_sli4_repost_io_sgl_list(struct lpfc_hba *phba) | 7046 | lpfc_sli4_repost_io_sgl_list(struct lpfc_hba *phba) |
7052 | { | 7047 | { |
7053 | LIST_HEAD(post_nblist); | 7048 | LIST_HEAD(post_nblist); |
@@ -7067,7 +7062,7 @@ lpfc_sli4_repost_io_sgl_list(struct lpfc_hba *phba) | |||
7067 | return rc; | 7062 | return rc; |
7068 | } | 7063 | } |
7069 | 7064 | ||
7070 | void | 7065 | static void |
7071 | lpfc_set_host_data(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox) | 7066 | lpfc_set_host_data(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox) |
7072 | { | 7067 | { |
7073 | uint32_t len; | 7068 | uint32_t len; |
@@ -7250,6 +7245,12 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
7250 | "3080 Successful retrieving SLI4 device " | 7245 | "3080 Successful retrieving SLI4 device " |
7251 | "physical port name: %s.\n", phba->Port); | 7246 | "physical port name: %s.\n", phba->Port); |
7252 | 7247 | ||
7248 | rc = lpfc_sli4_get_ctl_attr(phba); | ||
7249 | if (!rc) | ||
7250 | lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, | ||
7251 | "8351 Successful retrieving SLI4 device " | ||
7252 | "CTL ATTR\n"); | ||
7253 | |||
7253 | /* | 7254 | /* |
7254 | * Evaluate the read rev and vpd data. Populate the driver | 7255 | * Evaluate the read rev and vpd data. Populate the driver |
7255 | * state with the results. If this routine fails, the failure | 7256 | * state with the results. If this routine fails, the failure |
@@ -7652,12 +7653,6 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
7652 | phba->cfg_xri_rebalancing = 0; | 7653 | phba->cfg_xri_rebalancing = 0; |
7653 | } | 7654 | } |
7654 | 7655 | ||
7655 | /* Arm the CQs and then EQs on device */ | ||
7656 | lpfc_sli4_arm_cqeq_intr(phba); | ||
7657 | |||
7658 | /* Indicate device interrupt mode */ | ||
7659 | phba->sli4_hba.intr_enable = 1; | ||
7660 | |||
7661 | /* Allow asynchronous mailbox command to go through */ | 7656 | /* Allow asynchronous mailbox command to go through */ |
7662 | spin_lock_irq(&phba->hbalock); | 7657 | spin_lock_irq(&phba->hbalock); |
7663 | phba->sli.sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK; | 7658 | phba->sli.sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK; |
@@ -7726,6 +7721,12 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
7726 | phba->trunk_link.link3.state = LPFC_LINK_DOWN; | 7721 | phba->trunk_link.link3.state = LPFC_LINK_DOWN; |
7727 | spin_unlock_irq(&phba->hbalock); | 7722 | spin_unlock_irq(&phba->hbalock); |
7728 | 7723 | ||
7724 | /* Arm the CQs and then EQs on device */ | ||
7725 | lpfc_sli4_arm_cqeq_intr(phba); | ||
7726 | |||
7727 | /* Indicate device interrupt mode */ | ||
7728 | phba->sli4_hba.intr_enable = 1; | ||
7729 | |||
7729 | if (!(phba->hba_flag & HBA_FCOE_MODE) && | 7730 | if (!(phba->hba_flag & HBA_FCOE_MODE) && |
7730 | (phba->hba_flag & LINK_DISABLED)) { | 7731 | (phba->hba_flag & LINK_DISABLED)) { |
7731 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_SLI, | 7732 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_SLI, |
@@ -7820,8 +7821,9 @@ lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba) | |||
7820 | mcq = phba->sli4_hba.mbx_cq; | 7821 | mcq = phba->sli4_hba.mbx_cq; |
7821 | idx = mcq->hba_index; | 7822 | idx = mcq->hba_index; |
7822 | qe_valid = mcq->qe_valid; | 7823 | qe_valid = mcq->qe_valid; |
7823 | while (bf_get_le32(lpfc_cqe_valid, mcq->qe[idx].cqe) == qe_valid) { | 7824 | while (bf_get_le32(lpfc_cqe_valid, |
7824 | mcqe = (struct lpfc_mcqe *)mcq->qe[idx].cqe; | 7825 | (struct lpfc_cqe *)lpfc_sli4_qe(mcq, idx)) == qe_valid) { |
7826 | mcqe = (struct lpfc_mcqe *)(lpfc_sli4_qe(mcq, idx)); | ||
7825 | if (bf_get_le32(lpfc_trailer_completed, mcqe) && | 7827 | if (bf_get_le32(lpfc_trailer_completed, mcqe) && |
7826 | (!bf_get_le32(lpfc_trailer_async, mcqe))) { | 7828 | (!bf_get_le32(lpfc_trailer_async, mcqe))) { |
7827 | pending_completions = true; | 7829 | pending_completions = true; |
@@ -8500,7 +8502,7 @@ lpfc_sli4_wait_bmbx_ready(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
8500 | bmbx_reg.word0 = readl(phba->sli4_hba.BMBXregaddr); | 8502 | bmbx_reg.word0 = readl(phba->sli4_hba.BMBXregaddr); |
8501 | db_ready = bf_get(lpfc_bmbx_rdy, &bmbx_reg); | 8503 | db_ready = bf_get(lpfc_bmbx_rdy, &bmbx_reg); |
8502 | if (!db_ready) | 8504 | if (!db_ready) |
8503 | msleep(2); | 8505 | mdelay(2); |
8504 | 8506 | ||
8505 | if (time_after(jiffies, timeout)) | 8507 | if (time_after(jiffies, timeout)) |
8506 | return MBXERR_ERROR; | 8508 | return MBXERR_ERROR; |
@@ -11264,102 +11266,6 @@ abort_iotag_exit: | |||
11264 | } | 11266 | } |
11265 | 11267 | ||
11266 | /** | 11268 | /** |
11267 | * lpfc_sli4_abort_nvme_io - Issue abort for a command iocb | ||
11268 | * @phba: Pointer to HBA context object. | ||
11269 | * @pring: Pointer to driver SLI ring object. | ||
11270 | * @cmdiocb: Pointer to driver command iocb object. | ||
11271 | * | ||
11272 | * This function issues an abort iocb for the provided command iocb down to | ||
11273 | * the port. Other than the case the outstanding command iocb is an abort | ||
11274 | * request, this function issues abort out unconditionally. This function is | ||
11275 | * called with hbalock held. The function returns 0 when it fails due to | ||
11276 | * memory allocation failure or when the command iocb is an abort request. | ||
11277 | **/ | ||
11278 | static int | ||
11279 | lpfc_sli4_abort_nvme_io(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | ||
11280 | struct lpfc_iocbq *cmdiocb) | ||
11281 | { | ||
11282 | struct lpfc_vport *vport = cmdiocb->vport; | ||
11283 | struct lpfc_iocbq *abtsiocbp; | ||
11284 | union lpfc_wqe128 *abts_wqe; | ||
11285 | int retval; | ||
11286 | int idx = cmdiocb->hba_wqidx; | ||
11287 | |||
11288 | /* | ||
11289 | * There are certain command types we don't want to abort. And we | ||
11290 | * don't want to abort commands that are already in the process of | ||
11291 | * being aborted. | ||
11292 | */ | ||
11293 | if (cmdiocb->iocb.ulpCommand == CMD_ABORT_XRI_CN || | ||
11294 | cmdiocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN || | ||
11295 | (cmdiocb->iocb_flag & LPFC_DRIVER_ABORTED) != 0) | ||
11296 | return 0; | ||
11297 | |||
11298 | /* issue ABTS for this io based on iotag */ | ||
11299 | abtsiocbp = __lpfc_sli_get_iocbq(phba); | ||
11300 | if (abtsiocbp == NULL) | ||
11301 | return 0; | ||
11302 | |||
11303 | /* This signals the response to set the correct status | ||
11304 | * before calling the completion handler | ||
11305 | */ | ||
11306 | cmdiocb->iocb_flag |= LPFC_DRIVER_ABORTED; | ||
11307 | |||
11308 | /* Complete prepping the abort wqe and issue to the FW. */ | ||
11309 | abts_wqe = &abtsiocbp->wqe; | ||
11310 | |||
11311 | /* Clear any stale WQE contents */ | ||
11312 | memset(abts_wqe, 0, sizeof(union lpfc_wqe)); | ||
11313 | bf_set(abort_cmd_criteria, &abts_wqe->abort_cmd, T_XRI_TAG); | ||
11314 | |||
11315 | /* word 7 */ | ||
11316 | bf_set(wqe_cmnd, &abts_wqe->abort_cmd.wqe_com, CMD_ABORT_XRI_CX); | ||
11317 | bf_set(wqe_class, &abts_wqe->abort_cmd.wqe_com, | ||
11318 | cmdiocb->iocb.ulpClass); | ||
11319 | |||
11320 | /* word 8 - tell the FW to abort the IO associated with this | ||
11321 | * outstanding exchange ID. | ||
11322 | */ | ||
11323 | abts_wqe->abort_cmd.wqe_com.abort_tag = cmdiocb->sli4_xritag; | ||
11324 | |||
11325 | /* word 9 - this is the iotag for the abts_wqe completion. */ | ||
11326 | bf_set(wqe_reqtag, &abts_wqe->abort_cmd.wqe_com, | ||
11327 | abtsiocbp->iotag); | ||
11328 | |||
11329 | /* word 10 */ | ||
11330 | bf_set(wqe_qosd, &abts_wqe->abort_cmd.wqe_com, 1); | ||
11331 | bf_set(wqe_lenloc, &abts_wqe->abort_cmd.wqe_com, LPFC_WQE_LENLOC_NONE); | ||
11332 | |||
11333 | /* word 11 */ | ||
11334 | bf_set(wqe_cmd_type, &abts_wqe->abort_cmd.wqe_com, OTHER_COMMAND); | ||
11335 | bf_set(wqe_wqec, &abts_wqe->abort_cmd.wqe_com, 1); | ||
11336 | bf_set(wqe_cqid, &abts_wqe->abort_cmd.wqe_com, LPFC_WQE_CQ_ID_DEFAULT); | ||
11337 | |||
11338 | /* ABTS WQE must go to the same WQ as the WQE to be aborted */ | ||
11339 | abtsiocbp->iocb_flag |= LPFC_IO_NVME; | ||
11340 | abtsiocbp->vport = vport; | ||
11341 | abtsiocbp->wqe_cmpl = lpfc_nvme_abort_fcreq_cmpl; | ||
11342 | retval = lpfc_sli4_issue_wqe(phba, &phba->sli4_hba.hdwq[idx], | ||
11343 | abtsiocbp); | ||
11344 | if (retval) { | ||
11345 | lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME, | ||
11346 | "6147 Failed abts issue_wqe with status x%x " | ||
11347 | "for oxid x%x\n", | ||
11348 | retval, cmdiocb->sli4_xritag); | ||
11349 | lpfc_sli_release_iocbq(phba, abtsiocbp); | ||
11350 | return retval; | ||
11351 | } | ||
11352 | |||
11353 | lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME, | ||
11354 | "6148 Drv Abort NVME Request Issued for " | ||
11355 | "ox_id x%x on reqtag x%x\n", | ||
11356 | cmdiocb->sli4_xritag, | ||
11357 | abtsiocbp->iotag); | ||
11358 | |||
11359 | return retval; | ||
11360 | } | ||
11361 | |||
11362 | /** | ||
11363 | * lpfc_sli_hba_iocb_abort - Abort all iocbs to an hba. | 11269 | * lpfc_sli_hba_iocb_abort - Abort all iocbs to an hba. |
11364 | * @phba: pointer to lpfc HBA data structure. | 11270 | * @phba: pointer to lpfc HBA data structure. |
11365 | * | 11271 | * |
@@ -13636,7 +13542,7 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe, | |||
13636 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 13542 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
13637 | "0390 Cannot schedule soft IRQ " | 13543 | "0390 Cannot schedule soft IRQ " |
13638 | "for CQ eqcqid=%d, cqid=%d on CPU %d\n", | 13544 | "for CQ eqcqid=%d, cqid=%d on CPU %d\n", |
13639 | cqid, cq->queue_id, smp_processor_id()); | 13545 | cqid, cq->queue_id, raw_smp_processor_id()); |
13640 | } | 13546 | } |
13641 | 13547 | ||
13642 | /** | 13548 | /** |
@@ -14019,7 +13925,7 @@ lpfc_sli4_nvmet_handle_rcqe(struct lpfc_hba *phba, struct lpfc_queue *cq, | |||
14019 | return false; | 13925 | return false; |
14020 | } | 13926 | } |
14021 | drop: | 13927 | drop: |
14022 | lpfc_in_buf_free(phba, &dma_buf->dbuf); | 13928 | lpfc_rq_buf_free(phba, &dma_buf->hbuf); |
14023 | break; | 13929 | break; |
14024 | case FC_STATUS_INSUFF_BUF_FRM_DISC: | 13930 | case FC_STATUS_INSUFF_BUF_FRM_DISC: |
14025 | if (phba->nvmet_support) { | 13931 | if (phba->nvmet_support) { |
@@ -14185,7 +14091,7 @@ work_cq: | |||
14185 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 14091 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
14186 | "0363 Cannot schedule soft IRQ " | 14092 | "0363 Cannot schedule soft IRQ " |
14187 | "for CQ eqcqid=%d, cqid=%d on CPU %d\n", | 14093 | "for CQ eqcqid=%d, cqid=%d on CPU %d\n", |
14188 | cqid, cq->queue_id, smp_processor_id()); | 14094 | cqid, cq->queue_id, raw_smp_processor_id()); |
14189 | } | 14095 | } |
14190 | 14096 | ||
14191 | /** | 14097 | /** |
@@ -14324,7 +14230,7 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id) | |||
14324 | 14230 | ||
14325 | eqi = phba->sli4_hba.eq_info; | 14231 | eqi = phba->sli4_hba.eq_info; |
14326 | icnt = this_cpu_inc_return(eqi->icnt); | 14232 | icnt = this_cpu_inc_return(eqi->icnt); |
14327 | fpeq->last_cpu = smp_processor_id(); | 14233 | fpeq->last_cpu = raw_smp_processor_id(); |
14328 | 14234 | ||
14329 | if (icnt > LPFC_EQD_ISR_TRIGGER && | 14235 | if (icnt > LPFC_EQD_ISR_TRIGGER && |
14330 | phba->cfg_irq_chann == 1 && | 14236 | phba->cfg_irq_chann == 1 && |
@@ -14410,6 +14316,9 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue) | |||
14410 | if (!queue) | 14316 | if (!queue) |
14411 | return; | 14317 | return; |
14412 | 14318 | ||
14319 | if (!list_empty(&queue->wq_list)) | ||
14320 | list_del(&queue->wq_list); | ||
14321 | |||
14413 | while (!list_empty(&queue->page_list)) { | 14322 | while (!list_empty(&queue->page_list)) { |
14414 | list_remove_head(&queue->page_list, dmabuf, struct lpfc_dmabuf, | 14323 | list_remove_head(&queue->page_list, dmabuf, struct lpfc_dmabuf, |
14415 | list); | 14324 | list); |
@@ -14425,9 +14334,6 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue) | |||
14425 | if (!list_empty(&queue->cpu_list)) | 14334 | if (!list_empty(&queue->cpu_list)) |
14426 | list_del(&queue->cpu_list); | 14335 | list_del(&queue->cpu_list); |
14427 | 14336 | ||
14428 | if (!list_empty(&queue->wq_list)) | ||
14429 | list_del(&queue->wq_list); | ||
14430 | |||
14431 | kfree(queue); | 14337 | kfree(queue); |
14432 | return; | 14338 | return; |
14433 | } | 14339 | } |
@@ -14438,6 +14344,7 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue) | |||
14438 | * @page_size: The size of a queue page | 14344 | * @page_size: The size of a queue page |
14439 | * @entry_size: The size of each queue entry for this queue. | 14345 | * @entry_size: The size of each queue entry for this queue. |
14440 | * @entry count: The number of entries that this queue will handle. | 14346 | * @entry count: The number of entries that this queue will handle. |
14347 | * @cpu: The cpu that will primarily utilize this queue. | ||
14441 | * | 14348 | * |
14442 | * This function allocates a queue structure and the DMAable memory used for | 14349 | * This function allocates a queue structure and the DMAable memory used for |
14443 | * the host resident queue. This function must be called before creating the | 14350 | * the host resident queue. This function must be called before creating the |
@@ -14445,28 +14352,26 @@ lpfc_sli4_queue_free(struct lpfc_queue *queue) | |||
14445 | **/ | 14352 | **/ |
14446 | struct lpfc_queue * | 14353 | struct lpfc_queue * |
14447 | lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t page_size, | 14354 | lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t page_size, |
14448 | uint32_t entry_size, uint32_t entry_count) | 14355 | uint32_t entry_size, uint32_t entry_count, int cpu) |
14449 | { | 14356 | { |
14450 | struct lpfc_queue *queue; | 14357 | struct lpfc_queue *queue; |
14451 | struct lpfc_dmabuf *dmabuf; | 14358 | struct lpfc_dmabuf *dmabuf; |
14452 | int x, total_qe_count; | ||
14453 | void *dma_pointer; | ||
14454 | uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz; | 14359 | uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz; |
14360 | uint16_t x, pgcnt; | ||
14455 | 14361 | ||
14456 | if (!phba->sli4_hba.pc_sli4_params.supported) | 14362 | if (!phba->sli4_hba.pc_sli4_params.supported) |
14457 | hw_page_size = page_size; | 14363 | hw_page_size = page_size; |
14458 | 14364 | ||
14459 | queue = kzalloc(sizeof(struct lpfc_queue) + | 14365 | pgcnt = ALIGN(entry_size * entry_count, hw_page_size) / hw_page_size; |
14460 | (sizeof(union sli4_qe) * entry_count), GFP_KERNEL); | ||
14461 | if (!queue) | ||
14462 | return NULL; | ||
14463 | queue->page_count = (ALIGN(entry_size * entry_count, | ||
14464 | hw_page_size))/hw_page_size; | ||
14465 | 14366 | ||
14466 | /* If needed, Adjust page count to match the max the adapter supports */ | 14367 | /* If needed, Adjust page count to match the max the adapter supports */ |
14467 | if (phba->sli4_hba.pc_sli4_params.wqpcnt && | 14368 | if (pgcnt > phba->sli4_hba.pc_sli4_params.wqpcnt) |
14468 | (queue->page_count > phba->sli4_hba.pc_sli4_params.wqpcnt)) | 14369 | pgcnt = phba->sli4_hba.pc_sli4_params.wqpcnt; |
14469 | queue->page_count = phba->sli4_hba.pc_sli4_params.wqpcnt; | 14370 | |
14371 | queue = kzalloc_node(sizeof(*queue) + (sizeof(void *) * pgcnt), | ||
14372 | GFP_KERNEL, cpu_to_node(cpu)); | ||
14373 | if (!queue) | ||
14374 | return NULL; | ||
14470 | 14375 | ||
14471 | INIT_LIST_HEAD(&queue->list); | 14376 | INIT_LIST_HEAD(&queue->list); |
14472 | INIT_LIST_HEAD(&queue->wq_list); | 14377 | INIT_LIST_HEAD(&queue->wq_list); |
@@ -14478,13 +14383,17 @@ lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t page_size, | |||
14478 | /* Set queue parameters now. If the system cannot provide memory | 14383 | /* Set queue parameters now. If the system cannot provide memory |
14479 | * resources, the free routine needs to know what was allocated. | 14384 | * resources, the free routine needs to know what was allocated. |
14480 | */ | 14385 | */ |
14386 | queue->page_count = pgcnt; | ||
14387 | queue->q_pgs = (void **)&queue[1]; | ||
14388 | queue->entry_cnt_per_pg = hw_page_size / entry_size; | ||
14481 | queue->entry_size = entry_size; | 14389 | queue->entry_size = entry_size; |
14482 | queue->entry_count = entry_count; | 14390 | queue->entry_count = entry_count; |
14483 | queue->page_size = hw_page_size; | 14391 | queue->page_size = hw_page_size; |
14484 | queue->phba = phba; | 14392 | queue->phba = phba; |
14485 | 14393 | ||
14486 | for (x = 0, total_qe_count = 0; x < queue->page_count; x++) { | 14394 | for (x = 0; x < queue->page_count; x++) { |
14487 | dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | 14395 | dmabuf = kzalloc_node(sizeof(*dmabuf), GFP_KERNEL, |
14396 | dev_to_node(&phba->pcidev->dev)); | ||
14488 | if (!dmabuf) | 14397 | if (!dmabuf) |
14489 | goto out_fail; | 14398 | goto out_fail; |
14490 | dmabuf->virt = dma_alloc_coherent(&phba->pcidev->dev, | 14399 | dmabuf->virt = dma_alloc_coherent(&phba->pcidev->dev, |
@@ -14496,13 +14405,8 @@ lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t page_size, | |||
14496 | } | 14405 | } |
14497 | dmabuf->buffer_tag = x; | 14406 | dmabuf->buffer_tag = x; |
14498 | list_add_tail(&dmabuf->list, &queue->page_list); | 14407 | list_add_tail(&dmabuf->list, &queue->page_list); |
14499 | /* initialize queue's entry array */ | 14408 | /* use lpfc_sli4_qe to index a paritcular entry in this page */ |
14500 | dma_pointer = dmabuf->virt; | 14409 | queue->q_pgs[x] = dmabuf->virt; |
14501 | for (; total_qe_count < entry_count && | ||
14502 | dma_pointer < (hw_page_size + dmabuf->virt); | ||
14503 | total_qe_count++, dma_pointer += entry_size) { | ||
14504 | queue->qe[total_qe_count].address = dma_pointer; | ||
14505 | } | ||
14506 | } | 14410 | } |
14507 | INIT_WORK(&queue->irqwork, lpfc_sli4_hba_process_cq); | 14411 | INIT_WORK(&queue->irqwork, lpfc_sli4_hba_process_cq); |
14508 | INIT_WORK(&queue->spwork, lpfc_sli4_sp_process_cq); | 14412 | INIT_WORK(&queue->spwork, lpfc_sli4_sp_process_cq); |
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index 7a1a761efdd6..467b8270f7fd 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h | |||
@@ -327,6 +327,10 @@ struct lpfc_sli { | |||
327 | #define LPFC_SLI_ASYNC_MBX_BLK 0x2000 /* Async mailbox is blocked */ | 327 | #define LPFC_SLI_ASYNC_MBX_BLK 0x2000 /* Async mailbox is blocked */ |
328 | #define LPFC_SLI_SUPPRESS_RSP 0x4000 /* Suppress RSP feature is supported */ | 328 | #define LPFC_SLI_SUPPRESS_RSP 0x4000 /* Suppress RSP feature is supported */ |
329 | #define LPFC_SLI_USE_EQDR 0x8000 /* EQ Delay Register is supported */ | 329 | #define LPFC_SLI_USE_EQDR 0x8000 /* EQ Delay Register is supported */ |
330 | #define LPFC_QUEUE_FREE_INIT 0x10000 /* Queue freeing is in progress */ | ||
331 | #define LPFC_QUEUE_FREE_WAIT 0x20000 /* Hold Queue free as it is being | ||
332 | * used outside worker thread | ||
333 | */ | ||
330 | 334 | ||
331 | struct lpfc_sli_ring *sli3_ring; | 335 | struct lpfc_sli_ring *sli3_ring; |
332 | 336 | ||
@@ -427,14 +431,13 @@ struct lpfc_io_buf { | |||
427 | struct { | 431 | struct { |
428 | struct nvmefc_fcp_req *nvmeCmd; | 432 | struct nvmefc_fcp_req *nvmeCmd; |
429 | uint16_t qidx; | 433 | uint16_t qidx; |
430 | |||
431 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS | ||
432 | uint64_t ts_cmd_start; | ||
433 | uint64_t ts_last_cmd; | ||
434 | uint64_t ts_cmd_wqput; | ||
435 | uint64_t ts_isr_cmpl; | ||
436 | uint64_t ts_data_nvme; | ||
437 | #endif | ||
438 | }; | 434 | }; |
439 | }; | 435 | }; |
436 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS | ||
437 | uint64_t ts_cmd_start; | ||
438 | uint64_t ts_last_cmd; | ||
439 | uint64_t ts_cmd_wqput; | ||
440 | uint64_t ts_isr_cmpl; | ||
441 | uint64_t ts_data_nvme; | ||
442 | #endif | ||
440 | }; | 443 | }; |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 40c85091c805..8e4fd1a98023 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -117,21 +117,6 @@ enum lpfc_sli4_queue_subtype { | |||
117 | LPFC_USOL | 117 | LPFC_USOL |
118 | }; | 118 | }; |
119 | 119 | ||
120 | union sli4_qe { | ||
121 | void *address; | ||
122 | struct lpfc_eqe *eqe; | ||
123 | struct lpfc_cqe *cqe; | ||
124 | struct lpfc_mcqe *mcqe; | ||
125 | struct lpfc_wcqe_complete *wcqe_complete; | ||
126 | struct lpfc_wcqe_release *wcqe_release; | ||
127 | struct sli4_wcqe_xri_aborted *wcqe_xri_aborted; | ||
128 | struct lpfc_rcqe_complete *rcqe_complete; | ||
129 | struct lpfc_mqe *mqe; | ||
130 | union lpfc_wqe *wqe; | ||
131 | union lpfc_wqe128 *wqe128; | ||
132 | struct lpfc_rqe *rqe; | ||
133 | }; | ||
134 | |||
135 | /* RQ buffer list */ | 120 | /* RQ buffer list */ |
136 | struct lpfc_rqb { | 121 | struct lpfc_rqb { |
137 | uint16_t entry_count; /* Current number of RQ slots */ | 122 | uint16_t entry_count; /* Current number of RQ slots */ |
@@ -157,6 +142,7 @@ struct lpfc_queue { | |||
157 | struct list_head cpu_list; | 142 | struct list_head cpu_list; |
158 | uint32_t entry_count; /* Number of entries to support on the queue */ | 143 | uint32_t entry_count; /* Number of entries to support on the queue */ |
159 | uint32_t entry_size; /* Size of each queue entry. */ | 144 | uint32_t entry_size; /* Size of each queue entry. */ |
145 | uint32_t entry_cnt_per_pg; | ||
160 | uint32_t notify_interval; /* Queue Notification Interval | 146 | uint32_t notify_interval; /* Queue Notification Interval |
161 | * For chip->host queues (EQ, CQ, RQ): | 147 | * For chip->host queues (EQ, CQ, RQ): |
162 | * specifies the interval (number of | 148 | * specifies the interval (number of |
@@ -254,17 +240,17 @@ struct lpfc_queue { | |||
254 | uint16_t last_cpu; /* most recent cpu */ | 240 | uint16_t last_cpu; /* most recent cpu */ |
255 | uint8_t qe_valid; | 241 | uint8_t qe_valid; |
256 | struct lpfc_queue *assoc_qp; | 242 | struct lpfc_queue *assoc_qp; |
257 | union sli4_qe qe[1]; /* array to index entries (must be last) */ | 243 | void **q_pgs; /* array to index entries per page */ |
258 | }; | 244 | }; |
259 | 245 | ||
260 | struct lpfc_sli4_link { | 246 | struct lpfc_sli4_link { |
261 | uint16_t speed; | 247 | uint32_t speed; |
262 | uint8_t duplex; | 248 | uint8_t duplex; |
263 | uint8_t status; | 249 | uint8_t status; |
264 | uint8_t type; | 250 | uint8_t type; |
265 | uint8_t number; | 251 | uint8_t number; |
266 | uint8_t fault; | 252 | uint8_t fault; |
267 | uint16_t logical_speed; | 253 | uint32_t logical_speed; |
268 | uint16_t topology; | 254 | uint16_t topology; |
269 | }; | 255 | }; |
270 | 256 | ||
@@ -543,8 +529,9 @@ struct lpfc_sli4_lnk_info { | |||
543 | #define LPFC_LNK_DAT_INVAL 0 | 529 | #define LPFC_LNK_DAT_INVAL 0 |
544 | #define LPFC_LNK_DAT_VAL 1 | 530 | #define LPFC_LNK_DAT_VAL 1 |
545 | uint8_t lnk_tp; | 531 | uint8_t lnk_tp; |
546 | #define LPFC_LNK_GE 0x0 /* FCoE */ | 532 | #define LPFC_LNK_GE 0x0 /* FCoE */ |
547 | #define LPFC_LNK_FC 0x1 /* FC */ | 533 | #define LPFC_LNK_FC 0x1 /* FC */ |
534 | #define LPFC_LNK_FC_TRUNKED 0x2 /* FC_Trunked */ | ||
548 | uint8_t lnk_no; | 535 | uint8_t lnk_no; |
549 | uint8_t optic_state; | 536 | uint8_t optic_state; |
550 | }; | 537 | }; |
@@ -907,6 +894,18 @@ struct lpfc_sli4_hba { | |||
907 | #define lpfc_conf_trunk_port3_WORD conf_trunk | 894 | #define lpfc_conf_trunk_port3_WORD conf_trunk |
908 | #define lpfc_conf_trunk_port3_SHIFT 3 | 895 | #define lpfc_conf_trunk_port3_SHIFT 3 |
909 | #define lpfc_conf_trunk_port3_MASK 0x1 | 896 | #define lpfc_conf_trunk_port3_MASK 0x1 |
897 | #define lpfc_conf_trunk_port0_nd_WORD conf_trunk | ||
898 | #define lpfc_conf_trunk_port0_nd_SHIFT 4 | ||
899 | #define lpfc_conf_trunk_port0_nd_MASK 0x1 | ||
900 | #define lpfc_conf_trunk_port1_nd_WORD conf_trunk | ||
901 | #define lpfc_conf_trunk_port1_nd_SHIFT 5 | ||
902 | #define lpfc_conf_trunk_port1_nd_MASK 0x1 | ||
903 | #define lpfc_conf_trunk_port2_nd_WORD conf_trunk | ||
904 | #define lpfc_conf_trunk_port2_nd_SHIFT 6 | ||
905 | #define lpfc_conf_trunk_port2_nd_MASK 0x1 | ||
906 | #define lpfc_conf_trunk_port3_nd_WORD conf_trunk | ||
907 | #define lpfc_conf_trunk_port3_nd_SHIFT 7 | ||
908 | #define lpfc_conf_trunk_port3_nd_MASK 0x1 | ||
910 | }; | 909 | }; |
911 | 910 | ||
912 | enum lpfc_sge_type { | 911 | enum lpfc_sge_type { |
@@ -990,8 +989,10 @@ int lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *, struct lpfcMboxq *, | |||
990 | uint16_t); | 989 | uint16_t); |
991 | 990 | ||
992 | void lpfc_sli4_hba_reset(struct lpfc_hba *); | 991 | void lpfc_sli4_hba_reset(struct lpfc_hba *); |
993 | struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t, | 992 | struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *phba, |
994 | uint32_t, uint32_t); | 993 | uint32_t page_size, |
994 | uint32_t entry_size, | ||
995 | uint32_t entry_count, int cpu); | ||
995 | void lpfc_sli4_queue_free(struct lpfc_queue *); | 996 | void lpfc_sli4_queue_free(struct lpfc_queue *); |
996 | int lpfc_eq_create(struct lpfc_hba *, struct lpfc_queue *, uint32_t); | 997 | int lpfc_eq_create(struct lpfc_hba *, struct lpfc_queue *, uint32_t); |
997 | void lpfc_modify_hba_eq_delay(struct lpfc_hba *phba, uint32_t startq, | 998 | void lpfc_modify_hba_eq_delay(struct lpfc_hba *phba, uint32_t startq, |
@@ -1057,12 +1058,12 @@ void lpfc_sli_remove_dflt_fcf(struct lpfc_hba *); | |||
1057 | int lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *); | 1058 | int lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *); |
1058 | int lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba); | 1059 | int lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba); |
1059 | int lpfc_sli4_init_vpi(struct lpfc_vport *); | 1060 | int lpfc_sli4_init_vpi(struct lpfc_vport *); |
1060 | inline void lpfc_sli4_eq_clr_intr(struct lpfc_queue *); | 1061 | void lpfc_sli4_eq_clr_intr(struct lpfc_queue *); |
1061 | void lpfc_sli4_write_cq_db(struct lpfc_hba *phba, struct lpfc_queue *q, | 1062 | void lpfc_sli4_write_cq_db(struct lpfc_hba *phba, struct lpfc_queue *q, |
1062 | uint32_t count, bool arm); | 1063 | uint32_t count, bool arm); |
1063 | void lpfc_sli4_write_eq_db(struct lpfc_hba *phba, struct lpfc_queue *q, | 1064 | void lpfc_sli4_write_eq_db(struct lpfc_hba *phba, struct lpfc_queue *q, |
1064 | uint32_t count, bool arm); | 1065 | uint32_t count, bool arm); |
1065 | inline void lpfc_sli4_if6_eq_clr_intr(struct lpfc_queue *q); | 1066 | void lpfc_sli4_if6_eq_clr_intr(struct lpfc_queue *q); |
1066 | void lpfc_sli4_if6_write_cq_db(struct lpfc_hba *phba, struct lpfc_queue *q, | 1067 | void lpfc_sli4_if6_write_cq_db(struct lpfc_hba *phba, struct lpfc_queue *q, |
1067 | uint32_t count, bool arm); | 1068 | uint32_t count, bool arm); |
1068 | void lpfc_sli4_if6_write_eq_db(struct lpfc_hba *phba, struct lpfc_queue *q, | 1069 | void lpfc_sli4_if6_write_eq_db(struct lpfc_hba *phba, struct lpfc_queue *q, |
@@ -1079,3 +1080,8 @@ int lpfc_sli4_post_status_check(struct lpfc_hba *); | |||
1079 | uint8_t lpfc_sli_config_mbox_subsys_get(struct lpfc_hba *, LPFC_MBOXQ_t *); | 1080 | uint8_t lpfc_sli_config_mbox_subsys_get(struct lpfc_hba *, LPFC_MBOXQ_t *); |
1080 | uint8_t lpfc_sli_config_mbox_opcode_get(struct lpfc_hba *, LPFC_MBOXQ_t *); | 1081 | uint8_t lpfc_sli_config_mbox_opcode_get(struct lpfc_hba *, LPFC_MBOXQ_t *); |
1081 | void lpfc_sli4_ras_dma_free(struct lpfc_hba *phba); | 1082 | void lpfc_sli4_ras_dma_free(struct lpfc_hba *phba); |
1083 | static inline void *lpfc_sli4_qe(struct lpfc_queue *q, uint16_t idx) | ||
1084 | { | ||
1085 | return q->q_pgs[idx / q->entry_cnt_per_pg] + | ||
1086 | (q->entry_size * (idx % q->entry_cnt_per_pg)); | ||
1087 | } | ||
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 43fd693cf042..f7d9ef428417 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h | |||
@@ -20,7 +20,7 @@ | |||
20 | * included with this package. * | 20 | * included with this package. * |
21 | *******************************************************************/ | 21 | *******************************************************************/ |
22 | 22 | ||
23 | #define LPFC_DRIVER_VERSION "12.2.0.0" | 23 | #define LPFC_DRIVER_VERSION "12.2.0.1" |
24 | #define LPFC_DRIVER_NAME "lpfc" | 24 | #define LPFC_DRIVER_NAME "lpfc" |
25 | 25 | ||
26 | /* Used for SLI 2/3 */ | 26 | /* Used for SLI 2/3 */ |
@@ -32,6 +32,6 @@ | |||
32 | 32 | ||
33 | #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \ | 33 | #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \ |
34 | LPFC_DRIVER_VERSION | 34 | LPFC_DRIVER_VERSION |
35 | #define LPFC_COPYRIGHT "Copyright (C) 2017-2018 Broadcom. All Rights " \ | 35 | #define LPFC_COPYRIGHT "Copyright (C) 2017-2019 Broadcom. All Rights " \ |
36 | "Reserved. The term \"Broadcom\" refers to Broadcom Inc. " \ | 36 | "Reserved. The term \"Broadcom\" refers to Broadcom Inc. " \ |
37 | "and/or its subsidiaries." | 37 | "and/or its subsidiaries." |
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 59a6546fd602..473a120eb75d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
@@ -2724,7 +2724,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) | |||
2724 | do { | 2724 | do { |
2725 | if ((fw_state == MFI_STATE_FAULT) || atomic_read(&instance->fw_outstanding)) { | 2725 | if ((fw_state == MFI_STATE_FAULT) || atomic_read(&instance->fw_outstanding)) { |
2726 | dev_info(&instance->pdev->dev, | 2726 | dev_info(&instance->pdev->dev, |
2727 | "%s:%d waiting_for_outstanding: before issue OCR. FW state = 0x%x, oustanding 0x%x\n", | 2727 | "%s:%d waiting_for_outstanding: before issue OCR. FW state = 0x%x, outstanding 0x%x\n", |
2728 | __func__, __LINE__, fw_state, atomic_read(&instance->fw_outstanding)); | 2728 | __func__, __LINE__, fw_state, atomic_read(&instance->fw_outstanding)); |
2729 | if (i == 3) | 2729 | if (i == 3) |
2730 | goto kill_hba_and_failed; | 2730 | goto kill_hba_and_failed; |
@@ -4647,7 +4647,7 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type) | |||
4647 | * Return: 0 if DCMD succeeded | 4647 | * Return: 0 if DCMD succeeded |
4648 | * non-zero if failed | 4648 | * non-zero if failed |
4649 | */ | 4649 | */ |
4650 | int | 4650 | static int |
4651 | megasas_host_device_list_query(struct megasas_instance *instance, | 4651 | megasas_host_device_list_query(struct megasas_instance *instance, |
4652 | bool is_probe) | 4652 | bool is_probe) |
4653 | { | 4653 | { |
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index e35c2b64c145..6129399c1942 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c | |||
@@ -4418,7 +4418,7 @@ int megasas_task_abort_fusion(struct scsi_cmnd *scmd) | |||
4418 | if (!smid) { | 4418 | if (!smid) { |
4419 | ret = SUCCESS; | 4419 | ret = SUCCESS; |
4420 | scmd_printk(KERN_NOTICE, scmd, "Command for which abort is" | 4420 | scmd_printk(KERN_NOTICE, scmd, "Command for which abort is" |
4421 | " issued is not found in oustanding commands\n"); | 4421 | " issued is not found in outstanding commands\n"); |
4422 | mutex_unlock(&instance->reset_mutex); | 4422 | mutex_unlock(&instance->reset_mutex); |
4423 | goto out; | 4423 | goto out; |
4424 | } | 4424 | } |
diff --git a/drivers/scsi/mpt3sas/Kconfig b/drivers/scsi/mpt3sas/Kconfig index b736dbc80485..a072187875df 100644 --- a/drivers/scsi/mpt3sas/Kconfig +++ b/drivers/scsi/mpt3sas/Kconfig | |||
@@ -45,6 +45,7 @@ config SCSI_MPT3SAS | |||
45 | depends on PCI && SCSI | 45 | depends on PCI && SCSI |
46 | select SCSI_SAS_ATTRS | 46 | select SCSI_SAS_ATTRS |
47 | select RAID_ATTRS | 47 | select RAID_ATTRS |
48 | select IRQ_POLL | ||
48 | ---help--- | 49 | ---help--- |
49 | This driver supports PCI-Express SAS 12Gb/s Host Adapters. | 50 | This driver supports PCI-Express SAS 12Gb/s Host Adapters. |
50 | 51 | ||
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index f60b9e0a6ca6..8aacbd1e7db2 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c | |||
@@ -94,6 +94,11 @@ module_param(max_msix_vectors, int, 0); | |||
94 | MODULE_PARM_DESC(max_msix_vectors, | 94 | MODULE_PARM_DESC(max_msix_vectors, |
95 | " max msix vectors"); | 95 | " max msix vectors"); |
96 | 96 | ||
97 | static int irqpoll_weight = -1; | ||
98 | module_param(irqpoll_weight, int, 0); | ||
99 | MODULE_PARM_DESC(irqpoll_weight, | ||
100 | "irq poll weight (default= one fourth of HBA queue depth)"); | ||
101 | |||
97 | static int mpt3sas_fwfault_debug; | 102 | static int mpt3sas_fwfault_debug; |
98 | MODULE_PARM_DESC(mpt3sas_fwfault_debug, | 103 | MODULE_PARM_DESC(mpt3sas_fwfault_debug, |
99 | " enable detection of firmware fault and halt firmware - (default=0)"); | 104 | " enable detection of firmware fault and halt firmware - (default=0)"); |
@@ -1382,20 +1387,30 @@ union reply_descriptor { | |||
1382 | } u; | 1387 | } u; |
1383 | }; | 1388 | }; |
1384 | 1389 | ||
1390 | static u32 base_mod64(u64 dividend, u32 divisor) | ||
1391 | { | ||
1392 | u32 remainder; | ||
1393 | |||
1394 | if (!divisor) | ||
1395 | pr_err("mpt3sas: DIVISOR is zero, in div fn\n"); | ||
1396 | remainder = do_div(dividend, divisor); | ||
1397 | return remainder; | ||
1398 | } | ||
1399 | |||
1385 | /** | 1400 | /** |
1386 | * _base_interrupt - MPT adapter (IOC) specific interrupt handler. | 1401 | * _base_process_reply_queue - Process reply descriptors from reply |
1387 | * @irq: irq number (not used) | 1402 | * descriptor post queue. |
1388 | * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure | 1403 | * @reply_q: per IRQ's reply queue object. |
1389 | * | 1404 | * |
1390 | * Return: IRQ_HANDLED if processed, else IRQ_NONE. | 1405 | * Return: number of reply descriptors processed from reply |
1406 | * descriptor queue. | ||
1391 | */ | 1407 | */ |
1392 | static irqreturn_t | 1408 | static int |
1393 | _base_interrupt(int irq, void *bus_id) | 1409 | _base_process_reply_queue(struct adapter_reply_queue *reply_q) |
1394 | { | 1410 | { |
1395 | struct adapter_reply_queue *reply_q = bus_id; | ||
1396 | union reply_descriptor rd; | 1411 | union reply_descriptor rd; |
1397 | u32 completed_cmds; | 1412 | u64 completed_cmds; |
1398 | u8 request_desript_type; | 1413 | u8 request_descript_type; |
1399 | u16 smid; | 1414 | u16 smid; |
1400 | u8 cb_idx; | 1415 | u8 cb_idx; |
1401 | u32 reply; | 1416 | u32 reply; |
@@ -1404,21 +1419,18 @@ _base_interrupt(int irq, void *bus_id) | |||
1404 | Mpi2ReplyDescriptorsUnion_t *rpf; | 1419 | Mpi2ReplyDescriptorsUnion_t *rpf; |
1405 | u8 rc; | 1420 | u8 rc; |
1406 | 1421 | ||
1407 | if (ioc->mask_interrupts) | 1422 | completed_cmds = 0; |
1408 | return IRQ_NONE; | ||
1409 | |||
1410 | if (!atomic_add_unless(&reply_q->busy, 1, 1)) | 1423 | if (!atomic_add_unless(&reply_q->busy, 1, 1)) |
1411 | return IRQ_NONE; | 1424 | return completed_cmds; |
1412 | 1425 | ||
1413 | rpf = &reply_q->reply_post_free[reply_q->reply_post_host_index]; | 1426 | rpf = &reply_q->reply_post_free[reply_q->reply_post_host_index]; |
1414 | request_desript_type = rpf->Default.ReplyFlags | 1427 | request_descript_type = rpf->Default.ReplyFlags |
1415 | & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; | 1428 | & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; |
1416 | if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) { | 1429 | if (request_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) { |
1417 | atomic_dec(&reply_q->busy); | 1430 | atomic_dec(&reply_q->busy); |
1418 | return IRQ_NONE; | 1431 | return completed_cmds; |
1419 | } | 1432 | } |
1420 | 1433 | ||
1421 | completed_cmds = 0; | ||
1422 | cb_idx = 0xFF; | 1434 | cb_idx = 0xFF; |
1423 | do { | 1435 | do { |
1424 | rd.word = le64_to_cpu(rpf->Words); | 1436 | rd.word = le64_to_cpu(rpf->Words); |
@@ -1426,11 +1438,11 @@ _base_interrupt(int irq, void *bus_id) | |||
1426 | goto out; | 1438 | goto out; |
1427 | reply = 0; | 1439 | reply = 0; |
1428 | smid = le16_to_cpu(rpf->Default.DescriptorTypeDependent1); | 1440 | smid = le16_to_cpu(rpf->Default.DescriptorTypeDependent1); |
1429 | if (request_desript_type == | 1441 | if (request_descript_type == |
1430 | MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS || | 1442 | MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS || |
1431 | request_desript_type == | 1443 | request_descript_type == |
1432 | MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS || | 1444 | MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS || |
1433 | request_desript_type == | 1445 | request_descript_type == |
1434 | MPI26_RPY_DESCRIPT_FLAGS_PCIE_ENCAPSULATED_SUCCESS) { | 1446 | MPI26_RPY_DESCRIPT_FLAGS_PCIE_ENCAPSULATED_SUCCESS) { |
1435 | cb_idx = _base_get_cb_idx(ioc, smid); | 1447 | cb_idx = _base_get_cb_idx(ioc, smid); |
1436 | if ((likely(cb_idx < MPT_MAX_CALLBACKS)) && | 1448 | if ((likely(cb_idx < MPT_MAX_CALLBACKS)) && |
@@ -1440,7 +1452,7 @@ _base_interrupt(int irq, void *bus_id) | |||
1440 | if (rc) | 1452 | if (rc) |
1441 | mpt3sas_base_free_smid(ioc, smid); | 1453 | mpt3sas_base_free_smid(ioc, smid); |
1442 | } | 1454 | } |
1443 | } else if (request_desript_type == | 1455 | } else if (request_descript_type == |
1444 | MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { | 1456 | MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { |
1445 | reply = le32_to_cpu( | 1457 | reply = le32_to_cpu( |
1446 | rpf->AddressReply.ReplyFrameAddress); | 1458 | rpf->AddressReply.ReplyFrameAddress); |
@@ -1486,7 +1498,7 @@ _base_interrupt(int irq, void *bus_id) | |||
1486 | (reply_q->reply_post_host_index == | 1498 | (reply_q->reply_post_host_index == |
1487 | (ioc->reply_post_queue_depth - 1)) ? 0 : | 1499 | (ioc->reply_post_queue_depth - 1)) ? 0 : |
1488 | reply_q->reply_post_host_index + 1; | 1500 | reply_q->reply_post_host_index + 1; |
1489 | request_desript_type = | 1501 | request_descript_type = |
1490 | reply_q->reply_post_free[reply_q->reply_post_host_index]. | 1502 | reply_q->reply_post_free[reply_q->reply_post_host_index]. |
1491 | Default.ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; | 1503 | Default.ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; |
1492 | completed_cmds++; | 1504 | completed_cmds++; |
@@ -1495,7 +1507,7 @@ _base_interrupt(int irq, void *bus_id) | |||
1495 | * So that FW can find enough entries to post the Reply | 1507 | * So that FW can find enough entries to post the Reply |
1496 | * Descriptors in the reply descriptor post queue. | 1508 | * Descriptors in the reply descriptor post queue. |
1497 | */ | 1509 | */ |
1498 | if (completed_cmds > ioc->hba_queue_depth/3) { | 1510 | if (!base_mod64(completed_cmds, ioc->thresh_hold)) { |
1499 | if (ioc->combined_reply_queue) { | 1511 | if (ioc->combined_reply_queue) { |
1500 | writel(reply_q->reply_post_host_index | | 1512 | writel(reply_q->reply_post_host_index | |
1501 | ((msix_index & 7) << | 1513 | ((msix_index & 7) << |
@@ -1507,9 +1519,14 @@ _base_interrupt(int irq, void *bus_id) | |||
1507 | MPI2_RPHI_MSIX_INDEX_SHIFT), | 1519 | MPI2_RPHI_MSIX_INDEX_SHIFT), |
1508 | &ioc->chip->ReplyPostHostIndex); | 1520 | &ioc->chip->ReplyPostHostIndex); |
1509 | } | 1521 | } |
1510 | completed_cmds = 1; | 1522 | if (!reply_q->irq_poll_scheduled) { |
1523 | reply_q->irq_poll_scheduled = true; | ||
1524 | irq_poll_sched(&reply_q->irqpoll); | ||
1525 | } | ||
1526 | atomic_dec(&reply_q->busy); | ||
1527 | return completed_cmds; | ||
1511 | } | 1528 | } |
1512 | if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) | 1529 | if (request_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) |
1513 | goto out; | 1530 | goto out; |
1514 | if (!reply_q->reply_post_host_index) | 1531 | if (!reply_q->reply_post_host_index) |
1515 | rpf = reply_q->reply_post_free; | 1532 | rpf = reply_q->reply_post_free; |
@@ -1521,14 +1538,14 @@ _base_interrupt(int irq, void *bus_id) | |||
1521 | 1538 | ||
1522 | if (!completed_cmds) { | 1539 | if (!completed_cmds) { |
1523 | atomic_dec(&reply_q->busy); | 1540 | atomic_dec(&reply_q->busy); |
1524 | return IRQ_NONE; | 1541 | return completed_cmds; |
1525 | } | 1542 | } |
1526 | 1543 | ||
1527 | if (ioc->is_warpdrive) { | 1544 | if (ioc->is_warpdrive) { |
1528 | writel(reply_q->reply_post_host_index, | 1545 | writel(reply_q->reply_post_host_index, |
1529 | ioc->reply_post_host_index[msix_index]); | 1546 | ioc->reply_post_host_index[msix_index]); |
1530 | atomic_dec(&reply_q->busy); | 1547 | atomic_dec(&reply_q->busy); |
1531 | return IRQ_HANDLED; | 1548 | return completed_cmds; |
1532 | } | 1549 | } |
1533 | 1550 | ||
1534 | /* Update Reply Post Host Index. | 1551 | /* Update Reply Post Host Index. |
@@ -1555,7 +1572,82 @@ _base_interrupt(int irq, void *bus_id) | |||
1555 | MPI2_RPHI_MSIX_INDEX_SHIFT), | 1572 | MPI2_RPHI_MSIX_INDEX_SHIFT), |
1556 | &ioc->chip->ReplyPostHostIndex); | 1573 | &ioc->chip->ReplyPostHostIndex); |
1557 | atomic_dec(&reply_q->busy); | 1574 | atomic_dec(&reply_q->busy); |
1558 | return IRQ_HANDLED; | 1575 | return completed_cmds; |
1576 | } | ||
1577 | |||
1578 | /** | ||
1579 | * _base_interrupt - MPT adapter (IOC) specific interrupt handler. | ||
1580 | * @irq: irq number (not used) | ||
1581 | * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure | ||
1582 | * | ||
1583 | * Return: IRQ_HANDLED if processed, else IRQ_NONE. | ||
1584 | */ | ||
1585 | static irqreturn_t | ||
1586 | _base_interrupt(int irq, void *bus_id) | ||
1587 | { | ||
1588 | struct adapter_reply_queue *reply_q = bus_id; | ||
1589 | struct MPT3SAS_ADAPTER *ioc = reply_q->ioc; | ||
1590 | |||
1591 | if (ioc->mask_interrupts) | ||
1592 | return IRQ_NONE; | ||
1593 | if (reply_q->irq_poll_scheduled) | ||
1594 | return IRQ_HANDLED; | ||
1595 | return ((_base_process_reply_queue(reply_q) > 0) ? | ||
1596 | IRQ_HANDLED : IRQ_NONE); | ||
1597 | } | ||
1598 | |||
1599 | /** | ||
1600 | * _base_irqpoll - IRQ poll callback handler | ||
1601 | * @irqpoll - irq_poll object | ||
1602 | * @budget - irq poll weight | ||
1603 | * | ||
1604 | * returns number of reply descriptors processed | ||
1605 | */ | ||
1606 | static int | ||
1607 | _base_irqpoll(struct irq_poll *irqpoll, int budget) | ||
1608 | { | ||
1609 | struct adapter_reply_queue *reply_q; | ||
1610 | int num_entries = 0; | ||
1611 | |||
1612 | reply_q = container_of(irqpoll, struct adapter_reply_queue, | ||
1613 | irqpoll); | ||
1614 | if (reply_q->irq_line_enable) { | ||
1615 | disable_irq(reply_q->os_irq); | ||
1616 | reply_q->irq_line_enable = false; | ||
1617 | } | ||
1618 | num_entries = _base_process_reply_queue(reply_q); | ||
1619 | if (num_entries < budget) { | ||
1620 | irq_poll_complete(irqpoll); | ||
1621 | reply_q->irq_poll_scheduled = false; | ||
1622 | reply_q->irq_line_enable = true; | ||
1623 | enable_irq(reply_q->os_irq); | ||
1624 | } | ||
1625 | |||
1626 | return num_entries; | ||
1627 | } | ||
1628 | |||
1629 | /** | ||
1630 | * _base_init_irqpolls - initliaze IRQ polls | ||
1631 | * @ioc: per adapter object | ||
1632 | * | ||
1633 | * returns nothing | ||
1634 | */ | ||
1635 | static void | ||
1636 | _base_init_irqpolls(struct MPT3SAS_ADAPTER *ioc) | ||
1637 | { | ||
1638 | struct adapter_reply_queue *reply_q, *next; | ||
1639 | |||
1640 | if (list_empty(&ioc->reply_queue_list)) | ||
1641 | return; | ||
1642 | |||
1643 | list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) { | ||
1644 | irq_poll_init(&reply_q->irqpoll, | ||
1645 | ioc->hba_queue_depth/4, _base_irqpoll); | ||
1646 | reply_q->irq_poll_scheduled = false; | ||
1647 | reply_q->irq_line_enable = true; | ||
1648 | reply_q->os_irq = pci_irq_vector(ioc->pdev, | ||
1649 | reply_q->msix_index); | ||
1650 | } | ||
1559 | } | 1651 | } |
1560 | 1652 | ||
1561 | /** | 1653 | /** |
@@ -1596,6 +1688,17 @@ mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc) | |||
1596 | /* TMs are on msix_index == 0 */ | 1688 | /* TMs are on msix_index == 0 */ |
1597 | if (reply_q->msix_index == 0) | 1689 | if (reply_q->msix_index == 0) |
1598 | continue; | 1690 | continue; |
1691 | if (reply_q->irq_poll_scheduled) { | ||
1692 | /* Calling irq_poll_disable will wait for any pending | ||
1693 | * callbacks to have completed. | ||
1694 | */ | ||
1695 | irq_poll_disable(&reply_q->irqpoll); | ||
1696 | irq_poll_enable(&reply_q->irqpoll); | ||
1697 | reply_q->irq_poll_scheduled = false; | ||
1698 | reply_q->irq_line_enable = true; | ||
1699 | enable_irq(reply_q->os_irq); | ||
1700 | continue; | ||
1701 | } | ||
1599 | synchronize_irq(pci_irq_vector(ioc->pdev, reply_q->msix_index)); | 1702 | synchronize_irq(pci_irq_vector(ioc->pdev, reply_q->msix_index)); |
1600 | } | 1703 | } |
1601 | } | 1704 | } |
@@ -2757,6 +2860,11 @@ _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc) | |||
2757 | 2860 | ||
2758 | if (!_base_is_controller_msix_enabled(ioc)) | 2861 | if (!_base_is_controller_msix_enabled(ioc)) |
2759 | return; | 2862 | return; |
2863 | ioc->msix_load_balance = false; | ||
2864 | if (ioc->reply_queue_count < num_online_cpus()) { | ||
2865 | ioc->msix_load_balance = true; | ||
2866 | return; | ||
2867 | } | ||
2760 | 2868 | ||
2761 | memset(ioc->cpu_msix_table, 0, ioc->cpu_msix_table_sz); | 2869 | memset(ioc->cpu_msix_table, 0, ioc->cpu_msix_table_sz); |
2762 | 2870 | ||
@@ -3015,6 +3123,8 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) | |||
3015 | if (r) | 3123 | if (r) |
3016 | goto out_fail; | 3124 | goto out_fail; |
3017 | 3125 | ||
3126 | if (!ioc->is_driver_loading) | ||
3127 | _base_init_irqpolls(ioc); | ||
3018 | /* Use the Combined reply queue feature only for SAS3 C0 & higher | 3128 | /* Use the Combined reply queue feature only for SAS3 C0 & higher |
3019 | * revision HBAs and also only when reply queue count is greater than 8 | 3129 | * revision HBAs and also only when reply queue count is greater than 8 |
3020 | */ | 3130 | */ |
@@ -3158,6 +3268,12 @@ mpt3sas_base_get_reply_virt_addr(struct MPT3SAS_ADAPTER *ioc, u32 phys_addr) | |||
3158 | static inline u8 | 3268 | static inline u8 |
3159 | _base_get_msix_index(struct MPT3SAS_ADAPTER *ioc) | 3269 | _base_get_msix_index(struct MPT3SAS_ADAPTER *ioc) |
3160 | { | 3270 | { |
3271 | /* Enables reply_queue load balancing */ | ||
3272 | if (ioc->msix_load_balance) | ||
3273 | return ioc->reply_queue_count ? | ||
3274 | base_mod64(atomic64_add_return(1, | ||
3275 | &ioc->total_io_cnt), ioc->reply_queue_count) : 0; | ||
3276 | |||
3161 | return ioc->cpu_msix_table[raw_smp_processor_id()]; | 3277 | return ioc->cpu_msix_table[raw_smp_processor_id()]; |
3162 | } | 3278 | } |
3163 | 3279 | ||
@@ -6506,6 +6622,12 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) | |||
6506 | if (r) | 6622 | if (r) |
6507 | goto out_free_resources; | 6623 | goto out_free_resources; |
6508 | 6624 | ||
6625 | if (irqpoll_weight > 0) | ||
6626 | ioc->thresh_hold = irqpoll_weight; | ||
6627 | else | ||
6628 | ioc->thresh_hold = ioc->hba_queue_depth/4; | ||
6629 | |||
6630 | _base_init_irqpolls(ioc); | ||
6509 | init_waitqueue_head(&ioc->reset_wq); | 6631 | init_waitqueue_head(&ioc->reset_wq); |
6510 | 6632 | ||
6511 | /* allocate memory pd handle bitmask list */ | 6633 | /* allocate memory pd handle bitmask list */ |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index 19158cb59101..480219f0efc5 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h | |||
@@ -67,6 +67,7 @@ | |||
67 | #include <scsi/scsi_eh.h> | 67 | #include <scsi/scsi_eh.h> |
68 | #include <linux/pci.h> | 68 | #include <linux/pci.h> |
69 | #include <linux/poll.h> | 69 | #include <linux/poll.h> |
70 | #include <linux/irq_poll.h> | ||
70 | 71 | ||
71 | #include "mpt3sas_debug.h" | 72 | #include "mpt3sas_debug.h" |
72 | #include "mpt3sas_trigger_diag.h" | 73 | #include "mpt3sas_trigger_diag.h" |
@@ -75,9 +76,9 @@ | |||
75 | #define MPT3SAS_DRIVER_NAME "mpt3sas" | 76 | #define MPT3SAS_DRIVER_NAME "mpt3sas" |
76 | #define MPT3SAS_AUTHOR "Avago Technologies <MPT-FusionLinux.pdl@avagotech.com>" | 77 | #define MPT3SAS_AUTHOR "Avago Technologies <MPT-FusionLinux.pdl@avagotech.com>" |
77 | #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" | 78 | #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" |
78 | #define MPT3SAS_DRIVER_VERSION "27.102.00.00" | 79 | #define MPT3SAS_DRIVER_VERSION "28.100.00.00" |
79 | #define MPT3SAS_MAJOR_VERSION 27 | 80 | #define MPT3SAS_MAJOR_VERSION 28 |
80 | #define MPT3SAS_MINOR_VERSION 102 | 81 | #define MPT3SAS_MINOR_VERSION 100 |
81 | #define MPT3SAS_BUILD_VERSION 0 | 82 | #define MPT3SAS_BUILD_VERSION 0 |
82 | #define MPT3SAS_RELEASE_VERSION 00 | 83 | #define MPT3SAS_RELEASE_VERSION 00 |
83 | 84 | ||
@@ -882,6 +883,9 @@ struct _event_ack_list { | |||
882 | * @reply_post_free: reply post base virt address | 883 | * @reply_post_free: reply post base virt address |
883 | * @name: the name registered to request_irq() | 884 | * @name: the name registered to request_irq() |
884 | * @busy: isr is actively processing replies on another cpu | 885 | * @busy: isr is actively processing replies on another cpu |
886 | * @os_irq: irq number | ||
887 | * @irqpoll: irq_poll object | ||
888 | * @irq_poll_scheduled: Tells whether irq poll is scheduled or not | ||
885 | * @list: this list | 889 | * @list: this list |
886 | */ | 890 | */ |
887 | struct adapter_reply_queue { | 891 | struct adapter_reply_queue { |
@@ -891,6 +895,10 @@ struct adapter_reply_queue { | |||
891 | Mpi2ReplyDescriptorsUnion_t *reply_post_free; | 895 | Mpi2ReplyDescriptorsUnion_t *reply_post_free; |
892 | char name[MPT_NAME_LENGTH]; | 896 | char name[MPT_NAME_LENGTH]; |
893 | atomic_t busy; | 897 | atomic_t busy; |
898 | u32 os_irq; | ||
899 | struct irq_poll irqpoll; | ||
900 | bool irq_poll_scheduled; | ||
901 | bool irq_line_enable; | ||
894 | struct list_head list; | 902 | struct list_head list; |
895 | }; | 903 | }; |
896 | 904 | ||
@@ -1016,7 +1024,12 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); | |||
1016 | * @msix_vector_count: number msix vectors | 1024 | * @msix_vector_count: number msix vectors |
1017 | * @cpu_msix_table: table for mapping cpus to msix index | 1025 | * @cpu_msix_table: table for mapping cpus to msix index |
1018 | * @cpu_msix_table_sz: table size | 1026 | * @cpu_msix_table_sz: table size |
1027 | * @total_io_cnt: Gives total IO count, used to load balance the interrupts | ||
1028 | * @msix_load_balance: Enables load balancing of interrupts across | ||
1029 | * the multiple MSIXs | ||
1019 | * @schedule_dead_ioc_flush_running_cmds: callback to flush pending commands | 1030 | * @schedule_dead_ioc_flush_running_cmds: callback to flush pending commands |
1031 | * @thresh_hold: Max number of reply descriptors processed | ||
1032 | * before updating Host Index | ||
1020 | * @scsi_io_cb_idx: shost generated commands | 1033 | * @scsi_io_cb_idx: shost generated commands |
1021 | * @tm_cb_idx: task management commands | 1034 | * @tm_cb_idx: task management commands |
1022 | * @scsih_cb_idx: scsih internal commands | 1035 | * @scsih_cb_idx: scsih internal commands |
@@ -1192,6 +1205,9 @@ struct MPT3SAS_ADAPTER { | |||
1192 | u32 ioc_reset_count; | 1205 | u32 ioc_reset_count; |
1193 | MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds; | 1206 | MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds; |
1194 | u32 non_operational_loop; | 1207 | u32 non_operational_loop; |
1208 | atomic64_t total_io_cnt; | ||
1209 | bool msix_load_balance; | ||
1210 | u16 thresh_hold; | ||
1195 | 1211 | ||
1196 | /* internal commands, callback index */ | 1212 | /* internal commands, callback index */ |
1197 | u8 scsi_io_cb_idx; | 1213 | u8 scsi_io_cb_idx; |
diff --git a/drivers/scsi/mvsas/mv_64xx.c b/drivers/scsi/mvsas/mv_64xx.c index b757d389e32f..2c699bc785a8 100644 --- a/drivers/scsi/mvsas/mv_64xx.c +++ b/drivers/scsi/mvsas/mv_64xx.c | |||
@@ -678,7 +678,8 @@ static u32 mvs_64xx_spi_read_data(struct mvs_info *mvi) | |||
678 | static void mvs_64xx_spi_write_data(struct mvs_info *mvi, u32 data) | 678 | static void mvs_64xx_spi_write_data(struct mvs_info *mvi, u32 data) |
679 | { | 679 | { |
680 | void __iomem *regs = mvi->regs_ex; | 680 | void __iomem *regs = mvi->regs_ex; |
681 | iow32(SPI_DATA_REG_64XX, data); | 681 | |
682 | iow32(SPI_DATA_REG_64XX, data); | ||
682 | } | 683 | } |
683 | 684 | ||
684 | 685 | ||
diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c index eb5471bc7263..68b5b5f39a03 100644 --- a/drivers/scsi/mvsas/mv_94xx.c +++ b/drivers/scsi/mvsas/mv_94xx.c | |||
@@ -946,7 +946,8 @@ static u32 mvs_94xx_spi_read_data(struct mvs_info *mvi) | |||
946 | static void mvs_94xx_spi_write_data(struct mvs_info *mvi, u32 data) | 946 | static void mvs_94xx_spi_write_data(struct mvs_info *mvi, u32 data) |
947 | { | 947 | { |
948 | void __iomem *regs = mvi->regs_ex - 0x10200; | 948 | void __iomem *regs = mvi->regs_ex - 0x10200; |
949 | mw32(SPI_RD_DATA_REG_94XX, data); | 949 | |
950 | mw32(SPI_RD_DATA_REG_94XX, data); | ||
950 | } | 951 | } |
951 | 952 | ||
952 | 953 | ||
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index 311d23c727ce..e933c65d8e0b 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c | |||
@@ -1422,7 +1422,7 @@ int mvs_I_T_nexus_reset(struct domain_device *dev) | |||
1422 | { | 1422 | { |
1423 | unsigned long flags; | 1423 | unsigned long flags; |
1424 | int rc = TMF_RESP_FUNC_FAILED; | 1424 | int rc = TMF_RESP_FUNC_FAILED; |
1425 | struct mvs_device * mvi_dev = (struct mvs_device *)dev->lldd_dev; | 1425 | struct mvs_device *mvi_dev = (struct mvs_device *)dev->lldd_dev; |
1426 | struct mvs_info *mvi = mvi_dev->mvi_info; | 1426 | struct mvs_info *mvi = mvi_dev->mvi_info; |
1427 | 1427 | ||
1428 | if (mvi_dev->dev_status != MVS_DEV_EH) | 1428 | if (mvi_dev->dev_status != MVS_DEV_EH) |
diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c index 3df02691a092..a5410615edac 100644 --- a/drivers/scsi/mvumi.c +++ b/drivers/scsi/mvumi.c | |||
@@ -752,7 +752,7 @@ static int mvumi_issue_blocked_cmd(struct mvumi_hba *mhba, | |||
752 | spin_lock_irqsave(mhba->shost->host_lock, flags); | 752 | spin_lock_irqsave(mhba->shost->host_lock, flags); |
753 | atomic_dec(&cmd->sync_cmd); | 753 | atomic_dec(&cmd->sync_cmd); |
754 | if (mhba->tag_cmd[cmd->frame->tag]) { | 754 | if (mhba->tag_cmd[cmd->frame->tag]) { |
755 | mhba->tag_cmd[cmd->frame->tag] = 0; | 755 | mhba->tag_cmd[cmd->frame->tag] = NULL; |
756 | dev_warn(&mhba->pdev->dev, "TIMEOUT:release tag [%d]\n", | 756 | dev_warn(&mhba->pdev->dev, "TIMEOUT:release tag [%d]\n", |
757 | cmd->frame->tag); | 757 | cmd->frame->tag); |
758 | tag_release_one(mhba, &mhba->tag_pool, cmd->frame->tag); | 758 | tag_release_one(mhba, &mhba->tag_pool, cmd->frame->tag); |
@@ -1794,7 +1794,7 @@ static void mvumi_handle_clob(struct mvumi_hba *mhba) | |||
1794 | cmd = mhba->tag_cmd[ob_frame->tag]; | 1794 | cmd = mhba->tag_cmd[ob_frame->tag]; |
1795 | 1795 | ||
1796 | atomic_dec(&mhba->fw_outstanding); | 1796 | atomic_dec(&mhba->fw_outstanding); |
1797 | mhba->tag_cmd[ob_frame->tag] = 0; | 1797 | mhba->tag_cmd[ob_frame->tag] = NULL; |
1798 | tag_release_one(mhba, &mhba->tag_pool, ob_frame->tag); | 1798 | tag_release_one(mhba, &mhba->tag_pool, ob_frame->tag); |
1799 | if (cmd->scmd) | 1799 | if (cmd->scmd) |
1800 | mvumi_complete_cmd(mhba, cmd, ob_frame); | 1800 | mvumi_complete_cmd(mhba, cmd, ob_frame); |
@@ -2139,7 +2139,7 @@ static enum blk_eh_timer_return mvumi_timed_out(struct scsi_cmnd *scmd) | |||
2139 | spin_lock_irqsave(mhba->shost->host_lock, flags); | 2139 | spin_lock_irqsave(mhba->shost->host_lock, flags); |
2140 | 2140 | ||
2141 | if (mhba->tag_cmd[cmd->frame->tag]) { | 2141 | if (mhba->tag_cmd[cmd->frame->tag]) { |
2142 | mhba->tag_cmd[cmd->frame->tag] = 0; | 2142 | mhba->tag_cmd[cmd->frame->tag] = NULL; |
2143 | tag_release_one(mhba, &mhba->tag_pool, cmd->frame->tag); | 2143 | tag_release_one(mhba, &mhba->tag_pool, cmd->frame->tag); |
2144 | } | 2144 | } |
2145 | if (!list_empty(&cmd->queue_pointer)) | 2145 | if (!list_empty(&cmd->queue_pointer)) |
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index d0bb357034d8..109effd3557d 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c | |||
@@ -960,9 +960,9 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) | |||
960 | return -1; | 960 | return -1; |
961 | } | 961 | } |
962 | regVal = pm8001_cr32(pm8001_ha, 2, GPIO_GPIO_0_0UTPUT_CTL_OFFSET); | 962 | regVal = pm8001_cr32(pm8001_ha, 2, GPIO_GPIO_0_0UTPUT_CTL_OFFSET); |
963 | PM8001_INIT_DBG(pm8001_ha, | 963 | PM8001_INIT_DBG(pm8001_ha, |
964 | pm8001_printk("GPIO Output Control Register:" | 964 | pm8001_printk("GPIO Output Control Register:" |
965 | " = 0x%x\n", regVal)); | 965 | " = 0x%x\n", regVal)); |
966 | /* set GPIO-0 output control to tri-state */ | 966 | /* set GPIO-0 output control to tri-state */ |
967 | regVal &= 0xFFFFFFFC; | 967 | regVal &= 0xFFFFFFFC; |
968 | pm8001_cw32(pm8001_ha, 2, GPIO_GPIO_0_0UTPUT_CTL_OFFSET, regVal); | 968 | pm8001_cw32(pm8001_ha, 2, GPIO_GPIO_0_0UTPUT_CTL_OFFSET, regVal); |
@@ -1204,6 +1204,7 @@ void pm8001_chip_iounmap(struct pm8001_hba_info *pm8001_ha) | |||
1204 | } | 1204 | } |
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | #ifndef PM8001_USE_MSIX | ||
1207 | /** | 1208 | /** |
1208 | * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt | 1209 | * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt |
1209 | * @pm8001_ha: our hba card information | 1210 | * @pm8001_ha: our hba card information |
@@ -1225,6 +1226,8 @@ pm8001_chip_intx_interrupt_disable(struct pm8001_hba_info *pm8001_ha) | |||
1225 | pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, ODMR_MASK_ALL); | 1226 | pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, ODMR_MASK_ALL); |
1226 | } | 1227 | } |
1227 | 1228 | ||
1229 | #else | ||
1230 | |||
1228 | /** | 1231 | /** |
1229 | * pm8001_chip_msix_interrupt_enable - enable PM8001 chip interrupt | 1232 | * pm8001_chip_msix_interrupt_enable - enable PM8001 chip interrupt |
1230 | * @pm8001_ha: our hba card information | 1233 | * @pm8001_ha: our hba card information |
@@ -1256,6 +1259,7 @@ pm8001_chip_msix_interrupt_disable(struct pm8001_hba_info *pm8001_ha, | |||
1256 | msi_index += MSIX_TABLE_BASE; | 1259 | msi_index += MSIX_TABLE_BASE; |
1257 | pm8001_cw32(pm8001_ha, 0, msi_index, MSIX_INTERRUPT_DISABLE); | 1260 | pm8001_cw32(pm8001_ha, 0, msi_index, MSIX_INTERRUPT_DISABLE); |
1258 | } | 1261 | } |
1262 | #endif | ||
1259 | 1263 | ||
1260 | /** | 1264 | /** |
1261 | * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt | 1265 | * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt |
@@ -1266,10 +1270,9 @@ pm8001_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha, u8 vec) | |||
1266 | { | 1270 | { |
1267 | #ifdef PM8001_USE_MSIX | 1271 | #ifdef PM8001_USE_MSIX |
1268 | pm8001_chip_msix_interrupt_enable(pm8001_ha, 0); | 1272 | pm8001_chip_msix_interrupt_enable(pm8001_ha, 0); |
1269 | return; | 1273 | #else |
1270 | #endif | ||
1271 | pm8001_chip_intx_interrupt_enable(pm8001_ha); | 1274 | pm8001_chip_intx_interrupt_enable(pm8001_ha); |
1272 | 1275 | #endif | |
1273 | } | 1276 | } |
1274 | 1277 | ||
1275 | /** | 1278 | /** |
@@ -1281,10 +1284,9 @@ pm8001_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha, u8 vec) | |||
1281 | { | 1284 | { |
1282 | #ifdef PM8001_USE_MSIX | 1285 | #ifdef PM8001_USE_MSIX |
1283 | pm8001_chip_msix_interrupt_disable(pm8001_ha, 0); | 1286 | pm8001_chip_msix_interrupt_disable(pm8001_ha, 0); |
1284 | return; | 1287 | #else |
1285 | #endif | ||
1286 | pm8001_chip_intx_interrupt_disable(pm8001_ha); | 1288 | pm8001_chip_intx_interrupt_disable(pm8001_ha); |
1287 | 1289 | #endif | |
1288 | } | 1290 | } |
1289 | 1291 | ||
1290 | /** | 1292 | /** |
@@ -2898,7 +2900,6 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) | |||
2898 | static void | 2900 | static void |
2899 | mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | 2901 | mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) |
2900 | { | 2902 | { |
2901 | u32 param; | ||
2902 | struct sas_task *t; | 2903 | struct sas_task *t; |
2903 | struct pm8001_ccb_info *ccb; | 2904 | struct pm8001_ccb_info *ccb; |
2904 | unsigned long flags; | 2905 | unsigned long flags; |
@@ -2913,7 +2914,6 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
2913 | tag = le32_to_cpu(psmpPayload->tag); | 2914 | tag = le32_to_cpu(psmpPayload->tag); |
2914 | 2915 | ||
2915 | ccb = &pm8001_ha->ccb_info[tag]; | 2916 | ccb = &pm8001_ha->ccb_info[tag]; |
2916 | param = le32_to_cpu(psmpPayload->param); | ||
2917 | t = ccb->task; | 2917 | t = ccb->task; |
2918 | ts = &t->task_status; | 2918 | ts = &t->task_status; |
2919 | pm8001_dev = ccb->device; | 2919 | pm8001_dev = ccb->device; |
@@ -2928,7 +2928,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
2928 | PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n")); | 2928 | PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n")); |
2929 | ts->resp = SAS_TASK_COMPLETE; | 2929 | ts->resp = SAS_TASK_COMPLETE; |
2930 | ts->stat = SAM_STAT_GOOD; | 2930 | ts->stat = SAM_STAT_GOOD; |
2931 | if (pm8001_dev) | 2931 | if (pm8001_dev) |
2932 | pm8001_dev->running_req--; | 2932 | pm8001_dev->running_req--; |
2933 | break; | 2933 | break; |
2934 | case IO_ABORTED: | 2934 | case IO_ABORTED: |
@@ -3244,11 +3244,9 @@ void pm8001_bytes_dmaed(struct pm8001_hba_info *pm8001_ha, int i) | |||
3244 | { | 3244 | { |
3245 | struct pm8001_phy *phy = &pm8001_ha->phy[i]; | 3245 | struct pm8001_phy *phy = &pm8001_ha->phy[i]; |
3246 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | 3246 | struct asd_sas_phy *sas_phy = &phy->sas_phy; |
3247 | struct sas_ha_struct *sas_ha; | ||
3248 | if (!phy->phy_attached) | 3247 | if (!phy->phy_attached) |
3249 | return; | 3248 | return; |
3250 | 3249 | ||
3251 | sas_ha = pm8001_ha->sas; | ||
3252 | if (sas_phy->phy) { | 3250 | if (sas_phy->phy) { |
3253 | struct sas_phy *sphy = sas_phy->phy; | 3251 | struct sas_phy *sphy = sas_phy->phy; |
3254 | sphy->negotiated_linkrate = sas_phy->linkrate; | 3252 | sphy->negotiated_linkrate = sas_phy->linkrate; |
@@ -4627,17 +4625,18 @@ static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha, | |||
4627 | return ret; | 4625 | return ret; |
4628 | } | 4626 | } |
4629 | 4627 | ||
4630 | static u32 pm8001_chip_is_our_interupt(struct pm8001_hba_info *pm8001_ha) | 4628 | static u32 pm8001_chip_is_our_interrupt(struct pm8001_hba_info *pm8001_ha) |
4631 | { | 4629 | { |
4632 | u32 value; | ||
4633 | #ifdef PM8001_USE_MSIX | 4630 | #ifdef PM8001_USE_MSIX |
4634 | return 1; | 4631 | return 1; |
4635 | #endif | 4632 | #else |
4633 | u32 value; | ||
4634 | |||
4636 | value = pm8001_cr32(pm8001_ha, 0, MSGU_ODR); | 4635 | value = pm8001_cr32(pm8001_ha, 0, MSGU_ODR); |
4637 | if (value) | 4636 | if (value) |
4638 | return 1; | 4637 | return 1; |
4639 | return 0; | 4638 | return 0; |
4640 | 4639 | #endif | |
4641 | } | 4640 | } |
4642 | 4641 | ||
4643 | /** | 4642 | /** |
@@ -5123,7 +5122,7 @@ const struct pm8001_dispatch pm8001_8001_dispatch = { | |||
5123 | .chip_rst = pm8001_hw_chip_rst, | 5122 | .chip_rst = pm8001_hw_chip_rst, |
5124 | .chip_iounmap = pm8001_chip_iounmap, | 5123 | .chip_iounmap = pm8001_chip_iounmap, |
5125 | .isr = pm8001_chip_isr, | 5124 | .isr = pm8001_chip_isr, |
5126 | .is_our_interupt = pm8001_chip_is_our_interupt, | 5125 | .is_our_interrupt = pm8001_chip_is_our_interrupt, |
5127 | .isr_process_oq = process_oq, | 5126 | .isr_process_oq = process_oq, |
5128 | .interrupt_enable = pm8001_chip_interrupt_enable, | 5127 | .interrupt_enable = pm8001_chip_interrupt_enable, |
5129 | .interrupt_disable = pm8001_chip_interrupt_disable, | 5128 | .interrupt_disable = pm8001_chip_interrupt_disable, |
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index a36060c23b37..3374f553c617 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c | |||
@@ -201,7 +201,7 @@ static irqreturn_t pm8001_interrupt_handler_msix(int irq, void *opaque) | |||
201 | 201 | ||
202 | if (unlikely(!pm8001_ha)) | 202 | if (unlikely(!pm8001_ha)) |
203 | return IRQ_NONE; | 203 | return IRQ_NONE; |
204 | if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha)) | 204 | if (!PM8001_CHIP_DISP->is_our_interrupt(pm8001_ha)) |
205 | return IRQ_NONE; | 205 | return IRQ_NONE; |
206 | #ifdef PM8001_USE_TASKLET | 206 | #ifdef PM8001_USE_TASKLET |
207 | tasklet_schedule(&pm8001_ha->tasklet[irq_vector->irq_id]); | 207 | tasklet_schedule(&pm8001_ha->tasklet[irq_vector->irq_id]); |
@@ -224,7 +224,7 @@ static irqreturn_t pm8001_interrupt_handler_intx(int irq, void *dev_id) | |||
224 | pm8001_ha = sha->lldd_ha; | 224 | pm8001_ha = sha->lldd_ha; |
225 | if (unlikely(!pm8001_ha)) | 225 | if (unlikely(!pm8001_ha)) |
226 | return IRQ_NONE; | 226 | return IRQ_NONE; |
227 | if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha)) | 227 | if (!PM8001_CHIP_DISP->is_our_interrupt(pm8001_ha)) |
228 | return IRQ_NONE; | 228 | return IRQ_NONE; |
229 | 229 | ||
230 | #ifdef PM8001_USE_TASKLET | 230 | #ifdef PM8001_USE_TASKLET |
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 084f2fcced0a..88eef3b18e41 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c | |||
@@ -740,8 +740,8 @@ static int pm8001_exec_internal_tmf_task(struct domain_device *dev, | |||
740 | wait_for_completion(&task->slow_task->completion); | 740 | wait_for_completion(&task->slow_task->completion); |
741 | if (pm8001_ha->chip_id != chip_8001) { | 741 | if (pm8001_ha->chip_id != chip_8001) { |
742 | pm8001_dev->setds_completion = &completion_setstate; | 742 | pm8001_dev->setds_completion = &completion_setstate; |
743 | PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha, | 743 | PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha, |
744 | pm8001_dev, 0x01); | 744 | pm8001_dev, 0x01); |
745 | wait_for_completion(&completion_setstate); | 745 | wait_for_completion(&completion_setstate); |
746 | } | 746 | } |
747 | res = -TMF_RESP_FUNC_FAILED; | 747 | res = -TMF_RESP_FUNC_FAILED; |
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index f88b0d33c385..ac6d8e3f22de 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h | |||
@@ -197,7 +197,7 @@ struct pm8001_dispatch { | |||
197 | int (*chip_ioremap)(struct pm8001_hba_info *pm8001_ha); | 197 | int (*chip_ioremap)(struct pm8001_hba_info *pm8001_ha); |
198 | void (*chip_iounmap)(struct pm8001_hba_info *pm8001_ha); | 198 | void (*chip_iounmap)(struct pm8001_hba_info *pm8001_ha); |
199 | irqreturn_t (*isr)(struct pm8001_hba_info *pm8001_ha, u8 vec); | 199 | irqreturn_t (*isr)(struct pm8001_hba_info *pm8001_ha, u8 vec); |
200 | u32 (*is_our_interupt)(struct pm8001_hba_info *pm8001_ha); | 200 | u32 (*is_our_interrupt)(struct pm8001_hba_info *pm8001_ha); |
201 | int (*isr_process_oq)(struct pm8001_hba_info *pm8001_ha, u8 vec); | 201 | int (*isr_process_oq)(struct pm8001_hba_info *pm8001_ha, u8 vec); |
202 | void (*interrupt_enable)(struct pm8001_hba_info *pm8001_ha, u8 vec); | 202 | void (*interrupt_enable)(struct pm8001_hba_info *pm8001_ha, u8 vec); |
203 | void (*interrupt_disable)(struct pm8001_hba_info *pm8001_ha, u8 vec); | 203 | void (*interrupt_disable)(struct pm8001_hba_info *pm8001_ha, u8 vec); |
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 63e4f7d34d6c..301de40eb708 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c | |||
@@ -1316,7 +1316,7 @@ pm80xx_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) | |||
1316 | 1316 | ||
1317 | static void pm80xx_hw_chip_rst(struct pm8001_hba_info *pm8001_ha) | 1317 | static void pm80xx_hw_chip_rst(struct pm8001_hba_info *pm8001_ha) |
1318 | { | 1318 | { |
1319 | u32 i; | 1319 | u32 i; |
1320 | 1320 | ||
1321 | PM8001_INIT_DBG(pm8001_ha, | 1321 | PM8001_INIT_DBG(pm8001_ha, |
1322 | pm8001_printk("chip reset start\n")); | 1322 | pm8001_printk("chip reset start\n")); |
@@ -4381,27 +4381,27 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, | |||
4381 | sata_cmd.len = cpu_to_le32(task->total_xfer_len); | 4381 | sata_cmd.len = cpu_to_le32(task->total_xfer_len); |
4382 | sata_cmd.esgl = 0; | 4382 | sata_cmd.esgl = 0; |
4383 | } | 4383 | } |
4384 | /* scsi cdb */ | 4384 | /* scsi cdb */ |
4385 | sata_cmd.atapi_scsi_cdb[0] = | 4385 | sata_cmd.atapi_scsi_cdb[0] = |
4386 | cpu_to_le32(((task->ata_task.atapi_packet[0]) | | 4386 | cpu_to_le32(((task->ata_task.atapi_packet[0]) | |
4387 | (task->ata_task.atapi_packet[1] << 8) | | 4387 | (task->ata_task.atapi_packet[1] << 8) | |
4388 | (task->ata_task.atapi_packet[2] << 16) | | 4388 | (task->ata_task.atapi_packet[2] << 16) | |
4389 | (task->ata_task.atapi_packet[3] << 24))); | 4389 | (task->ata_task.atapi_packet[3] << 24))); |
4390 | sata_cmd.atapi_scsi_cdb[1] = | 4390 | sata_cmd.atapi_scsi_cdb[1] = |
4391 | cpu_to_le32(((task->ata_task.atapi_packet[4]) | | 4391 | cpu_to_le32(((task->ata_task.atapi_packet[4]) | |
4392 | (task->ata_task.atapi_packet[5] << 8) | | 4392 | (task->ata_task.atapi_packet[5] << 8) | |
4393 | (task->ata_task.atapi_packet[6] << 16) | | 4393 | (task->ata_task.atapi_packet[6] << 16) | |
4394 | (task->ata_task.atapi_packet[7] << 24))); | 4394 | (task->ata_task.atapi_packet[7] << 24))); |
4395 | sata_cmd.atapi_scsi_cdb[2] = | 4395 | sata_cmd.atapi_scsi_cdb[2] = |
4396 | cpu_to_le32(((task->ata_task.atapi_packet[8]) | | 4396 | cpu_to_le32(((task->ata_task.atapi_packet[8]) | |
4397 | (task->ata_task.atapi_packet[9] << 8) | | 4397 | (task->ata_task.atapi_packet[9] << 8) | |
4398 | (task->ata_task.atapi_packet[10] << 16) | | 4398 | (task->ata_task.atapi_packet[10] << 16) | |
4399 | (task->ata_task.atapi_packet[11] << 24))); | 4399 | (task->ata_task.atapi_packet[11] << 24))); |
4400 | sata_cmd.atapi_scsi_cdb[3] = | 4400 | sata_cmd.atapi_scsi_cdb[3] = |
4401 | cpu_to_le32(((task->ata_task.atapi_packet[12]) | | 4401 | cpu_to_le32(((task->ata_task.atapi_packet[12]) | |
4402 | (task->ata_task.atapi_packet[13] << 8) | | 4402 | (task->ata_task.atapi_packet[13] << 8) | |
4403 | (task->ata_task.atapi_packet[14] << 16) | | 4403 | (task->ata_task.atapi_packet[14] << 16) | |
4404 | (task->ata_task.atapi_packet[15] << 24))); | 4404 | (task->ata_task.atapi_packet[15] << 24))); |
4405 | } | 4405 | } |
4406 | 4406 | ||
4407 | /* Check for read log for failed drive and return */ | 4407 | /* Check for read log for failed drive and return */ |
@@ -4617,17 +4617,18 @@ static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha, | |||
4617 | return pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); | 4617 | return pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); |
4618 | } | 4618 | } |
4619 | 4619 | ||
4620 | static u32 pm80xx_chip_is_our_interupt(struct pm8001_hba_info *pm8001_ha) | 4620 | static u32 pm80xx_chip_is_our_interrupt(struct pm8001_hba_info *pm8001_ha) |
4621 | { | 4621 | { |
4622 | u32 value; | ||
4623 | #ifdef PM8001_USE_MSIX | 4622 | #ifdef PM8001_USE_MSIX |
4624 | return 1; | 4623 | return 1; |
4625 | #endif | 4624 | #else |
4625 | u32 value; | ||
4626 | |||
4626 | value = pm8001_cr32(pm8001_ha, 0, MSGU_ODR); | 4627 | value = pm8001_cr32(pm8001_ha, 0, MSGU_ODR); |
4627 | if (value) | 4628 | if (value) |
4628 | return 1; | 4629 | return 1; |
4629 | return 0; | 4630 | return 0; |
4630 | 4631 | #endif | |
4631 | } | 4632 | } |
4632 | 4633 | ||
4633 | /** | 4634 | /** |
@@ -4724,7 +4725,7 @@ const struct pm8001_dispatch pm8001_80xx_dispatch = { | |||
4724 | .chip_rst = pm80xx_hw_chip_rst, | 4725 | .chip_rst = pm80xx_hw_chip_rst, |
4725 | .chip_iounmap = pm8001_chip_iounmap, | 4726 | .chip_iounmap = pm8001_chip_iounmap, |
4726 | .isr = pm80xx_chip_isr, | 4727 | .isr = pm80xx_chip_isr, |
4727 | .is_our_interupt = pm80xx_chip_is_our_interupt, | 4728 | .is_our_interrupt = pm80xx_chip_is_our_interrupt, |
4728 | .isr_process_oq = process_oq, | 4729 | .isr_process_oq = process_oq, |
4729 | .interrupt_enable = pm80xx_chip_interrupt_enable, | 4730 | .interrupt_enable = pm80xx_chip_interrupt_enable, |
4730 | .interrupt_disable = pm80xx_chip_interrupt_disable, | 4731 | .interrupt_disable = pm80xx_chip_interrupt_disable, |
diff --git a/drivers/scsi/qedf/qedf.h b/drivers/scsi/qedf/qedf.h index 2c78d8fb9122..2c08f6f4db42 100644 --- a/drivers/scsi/qedf/qedf.h +++ b/drivers/scsi/qedf/qedf.h | |||
@@ -35,9 +35,6 @@ | |||
35 | #define QEDF_DESCR "QLogic FCoE Offload Driver" | 35 | #define QEDF_DESCR "QLogic FCoE Offload Driver" |
36 | #define QEDF_MODULE_NAME "qedf" | 36 | #define QEDF_MODULE_NAME "qedf" |
37 | 37 | ||
38 | #define QEDF_MIN_XID 0 | ||
39 | #define QEDF_MAX_SCSI_XID (NUM_TASKS_PER_CONNECTION - 1) | ||
40 | #define QEDF_MAX_ELS_XID 4095 | ||
41 | #define QEDF_FLOGI_RETRY_CNT 3 | 38 | #define QEDF_FLOGI_RETRY_CNT 3 |
42 | #define QEDF_RPORT_RETRY_CNT 255 | 39 | #define QEDF_RPORT_RETRY_CNT 255 |
43 | #define QEDF_MAX_SESSIONS 1024 | 40 | #define QEDF_MAX_SESSIONS 1024 |
@@ -52,8 +49,8 @@ | |||
52 | sizeof(struct fc_frame_header)) | 49 | sizeof(struct fc_frame_header)) |
53 | #define QEDF_MAX_NPIV 64 | 50 | #define QEDF_MAX_NPIV 64 |
54 | #define QEDF_TM_TIMEOUT 10 | 51 | #define QEDF_TM_TIMEOUT 10 |
55 | #define QEDF_ABORT_TIMEOUT 10 | 52 | #define QEDF_ABORT_TIMEOUT (10 * 1000) |
56 | #define QEDF_CLEANUP_TIMEOUT 10 | 53 | #define QEDF_CLEANUP_TIMEOUT 1 |
57 | #define QEDF_MAX_CDB_LEN 16 | 54 | #define QEDF_MAX_CDB_LEN 16 |
58 | 55 | ||
59 | #define UPSTREAM_REMOVE 1 | 56 | #define UPSTREAM_REMOVE 1 |
@@ -85,6 +82,7 @@ struct qedf_els_cb_arg { | |||
85 | }; | 82 | }; |
86 | 83 | ||
87 | enum qedf_ioreq_event { | 84 | enum qedf_ioreq_event { |
85 | QEDF_IOREQ_EV_NONE, | ||
88 | QEDF_IOREQ_EV_ABORT_SUCCESS, | 86 | QEDF_IOREQ_EV_ABORT_SUCCESS, |
89 | QEDF_IOREQ_EV_ABORT_FAILED, | 87 | QEDF_IOREQ_EV_ABORT_FAILED, |
90 | QEDF_IOREQ_EV_SEND_RRQ, | 88 | QEDF_IOREQ_EV_SEND_RRQ, |
@@ -105,7 +103,6 @@ struct qedf_ioreq { | |||
105 | struct list_head link; | 103 | struct list_head link; |
106 | uint16_t xid; | 104 | uint16_t xid; |
107 | struct scsi_cmnd *sc_cmd; | 105 | struct scsi_cmnd *sc_cmd; |
108 | bool use_slowpath; /* Use slow SGL for this I/O */ | ||
109 | #define QEDF_SCSI_CMD 1 | 106 | #define QEDF_SCSI_CMD 1 |
110 | #define QEDF_TASK_MGMT_CMD 2 | 107 | #define QEDF_TASK_MGMT_CMD 2 |
111 | #define QEDF_ABTS 3 | 108 | #define QEDF_ABTS 3 |
@@ -117,22 +114,43 @@ struct qedf_ioreq { | |||
117 | #define QEDF_CMD_IN_ABORT 0x1 | 114 | #define QEDF_CMD_IN_ABORT 0x1 |
118 | #define QEDF_CMD_IN_CLEANUP 0x2 | 115 | #define QEDF_CMD_IN_CLEANUP 0x2 |
119 | #define QEDF_CMD_SRR_SENT 0x3 | 116 | #define QEDF_CMD_SRR_SENT 0x3 |
117 | #define QEDF_CMD_DIRTY 0x4 | ||
118 | #define QEDF_CMD_ERR_SCSI_DONE 0x5 | ||
120 | u8 io_req_flags; | 119 | u8 io_req_flags; |
121 | uint8_t tm_flags; | 120 | uint8_t tm_flags; |
122 | struct qedf_rport *fcport; | 121 | struct qedf_rport *fcport; |
122 | #define QEDF_CMD_ST_INACTIVE 0 | ||
123 | #define QEDFC_CMD_ST_IO_ACTIVE 1 | ||
124 | #define QEDFC_CMD_ST_ABORT_ACTIVE 2 | ||
125 | #define QEDFC_CMD_ST_ABORT_ACTIVE_EH 3 | ||
126 | #define QEDFC_CMD_ST_CLEANUP_ACTIVE 4 | ||
127 | #define QEDFC_CMD_ST_CLEANUP_ACTIVE_EH 5 | ||
128 | #define QEDFC_CMD_ST_RRQ_ACTIVE 6 | ||
129 | #define QEDFC_CMD_ST_RRQ_WAIT 7 | ||
130 | #define QEDFC_CMD_ST_OXID_RETIRE_WAIT 8 | ||
131 | #define QEDFC_CMD_ST_TMF_ACTIVE 9 | ||
132 | #define QEDFC_CMD_ST_DRAIN_ACTIVE 10 | ||
133 | #define QEDFC_CMD_ST_CLEANED 11 | ||
134 | #define QEDFC_CMD_ST_ELS_ACTIVE 12 | ||
135 | atomic_t state; | ||
123 | unsigned long flags; | 136 | unsigned long flags; |
124 | enum qedf_ioreq_event event; | 137 | enum qedf_ioreq_event event; |
125 | size_t data_xfer_len; | 138 | size_t data_xfer_len; |
139 | /* ID: 001: Alloc cmd (qedf_alloc_cmd) */ | ||
140 | /* ID: 002: Initiate ABTS (qedf_initiate_abts) */ | ||
141 | /* ID: 003: For RRQ (qedf_process_abts_compl) */ | ||
126 | struct kref refcount; | 142 | struct kref refcount; |
127 | struct qedf_cmd_mgr *cmd_mgr; | 143 | struct qedf_cmd_mgr *cmd_mgr; |
128 | struct io_bdt *bd_tbl; | 144 | struct io_bdt *bd_tbl; |
129 | struct delayed_work timeout_work; | 145 | struct delayed_work timeout_work; |
130 | struct completion tm_done; | 146 | struct completion tm_done; |
131 | struct completion abts_done; | 147 | struct completion abts_done; |
148 | struct completion cleanup_done; | ||
132 | struct e4_fcoe_task_context *task; | 149 | struct e4_fcoe_task_context *task; |
133 | struct fcoe_task_params *task_params; | 150 | struct fcoe_task_params *task_params; |
134 | struct scsi_sgl_task_params *sgl_task_params; | 151 | struct scsi_sgl_task_params *sgl_task_params; |
135 | int idx; | 152 | int idx; |
153 | int lun; | ||
136 | /* | 154 | /* |
137 | * Need to allocate enough room for both sense data and FCP response data | 155 | * Need to allocate enough room for both sense data and FCP response data |
138 | * which has a max length of 8 bytes according to spec. | 156 | * which has a max length of 8 bytes according to spec. |
@@ -155,9 +173,9 @@ struct qedf_ioreq { | |||
155 | int fp_idx; | 173 | int fp_idx; |
156 | unsigned int cpu; | 174 | unsigned int cpu; |
157 | unsigned int int_cpu; | 175 | unsigned int int_cpu; |
158 | #define QEDF_IOREQ_SLOW_SGE 0 | 176 | #define QEDF_IOREQ_UNKNOWN_SGE 1 |
159 | #define QEDF_IOREQ_SINGLE_SGE 1 | 177 | #define QEDF_IOREQ_SLOW_SGE 2 |
160 | #define QEDF_IOREQ_FAST_SGE 2 | 178 | #define QEDF_IOREQ_FAST_SGE 3 |
161 | u8 sge_type; | 179 | u8 sge_type; |
162 | struct delayed_work rrq_work; | 180 | struct delayed_work rrq_work; |
163 | 181 | ||
@@ -172,6 +190,8 @@ struct qedf_ioreq { | |||
172 | * during some form of error processing. | 190 | * during some form of error processing. |
173 | */ | 191 | */ |
174 | bool return_scsi_cmd_on_abts; | 192 | bool return_scsi_cmd_on_abts; |
193 | |||
194 | unsigned int alloc; | ||
175 | }; | 195 | }; |
176 | 196 | ||
177 | extern struct workqueue_struct *qedf_io_wq; | 197 | extern struct workqueue_struct *qedf_io_wq; |
@@ -181,7 +201,10 @@ struct qedf_rport { | |||
181 | #define QEDF_RPORT_SESSION_READY 1 | 201 | #define QEDF_RPORT_SESSION_READY 1 |
182 | #define QEDF_RPORT_UPLOADING_CONNECTION 2 | 202 | #define QEDF_RPORT_UPLOADING_CONNECTION 2 |
183 | #define QEDF_RPORT_IN_RESET 3 | 203 | #define QEDF_RPORT_IN_RESET 3 |
204 | #define QEDF_RPORT_IN_LUN_RESET 4 | ||
205 | #define QEDF_RPORT_IN_TARGET_RESET 5 | ||
184 | unsigned long flags; | 206 | unsigned long flags; |
207 | int lun_reset_lun; | ||
185 | unsigned long retry_delay_timestamp; | 208 | unsigned long retry_delay_timestamp; |
186 | struct fc_rport *rport; | 209 | struct fc_rport *rport; |
187 | struct fc_rport_priv *rdata; | 210 | struct fc_rport_priv *rdata; |
@@ -191,6 +214,7 @@ struct qedf_rport { | |||
191 | void __iomem *p_doorbell; | 214 | void __iomem *p_doorbell; |
192 | /* Send queue management */ | 215 | /* Send queue management */ |
193 | atomic_t free_sqes; | 216 | atomic_t free_sqes; |
217 | atomic_t ios_to_queue; | ||
194 | atomic_t num_active_ios; | 218 | atomic_t num_active_ios; |
195 | struct fcoe_wqe *sq; | 219 | struct fcoe_wqe *sq; |
196 | dma_addr_t sq_dma; | 220 | dma_addr_t sq_dma; |
@@ -295,8 +319,6 @@ struct qedf_ctx { | |||
295 | #define QEDF_DCBX_PENDING 0 | 319 | #define QEDF_DCBX_PENDING 0 |
296 | #define QEDF_DCBX_DONE 1 | 320 | #define QEDF_DCBX_DONE 1 |
297 | atomic_t dcbx; | 321 | atomic_t dcbx; |
298 | uint16_t max_scsi_xid; | ||
299 | uint16_t max_els_xid; | ||
300 | #define QEDF_NULL_VLAN_ID -1 | 322 | #define QEDF_NULL_VLAN_ID -1 |
301 | #define QEDF_FALLBACK_VLAN 1002 | 323 | #define QEDF_FALLBACK_VLAN 1002 |
302 | #define QEDF_DEFAULT_PRIO 3 | 324 | #define QEDF_DEFAULT_PRIO 3 |
@@ -371,7 +393,6 @@ struct qedf_ctx { | |||
371 | 393 | ||
372 | u32 slow_sge_ios; | 394 | u32 slow_sge_ios; |
373 | u32 fast_sge_ios; | 395 | u32 fast_sge_ios; |
374 | u32 single_sge_ios; | ||
375 | 396 | ||
376 | uint8_t *grcdump; | 397 | uint8_t *grcdump; |
377 | uint32_t grcdump_size; | 398 | uint32_t grcdump_size; |
@@ -396,6 +417,8 @@ struct qedf_ctx { | |||
396 | u8 target_resets; | 417 | u8 target_resets; |
397 | u8 task_set_fulls; | 418 | u8 task_set_fulls; |
398 | u8 busy; | 419 | u8 busy; |
420 | /* Used for flush routine */ | ||
421 | struct mutex flush_mutex; | ||
399 | }; | 422 | }; |
400 | 423 | ||
401 | struct io_bdt { | 424 | struct io_bdt { |
@@ -435,6 +458,12 @@ static inline void qedf_stop_all_io(struct qedf_ctx *qedf) | |||
435 | /* | 458 | /* |
436 | * Externs | 459 | * Externs |
437 | */ | 460 | */ |
461 | |||
462 | /* | ||
463 | * (QEDF_LOG_NPIV | QEDF_LOG_SESS | QEDF_LOG_LPORT | QEDF_LOG_ELS | QEDF_LOG_MQ | ||
464 | * | QEDF_LOG_IO | QEDF_LOG_UNSOL | QEDF_LOG_SCSI_TM | QEDF_LOG_MP_REQ | | ||
465 | * QEDF_LOG_EVT | QEDF_LOG_CONN | QEDF_LOG_DISC | QEDF_LOG_INFO) | ||
466 | */ | ||
438 | #define QEDF_DEFAULT_LOG_MASK 0x3CFB6 | 467 | #define QEDF_DEFAULT_LOG_MASK 0x3CFB6 |
439 | extern const struct qed_fcoe_ops *qed_ops; | 468 | extern const struct qed_fcoe_ops *qed_ops; |
440 | extern uint qedf_dump_frames; | 469 | extern uint qedf_dump_frames; |
@@ -494,7 +523,7 @@ extern void qedf_set_vlan_id(struct qedf_ctx *qedf, int vlan_id); | |||
494 | extern void qedf_create_sysfs_ctx_attr(struct qedf_ctx *qedf); | 523 | extern void qedf_create_sysfs_ctx_attr(struct qedf_ctx *qedf); |
495 | extern void qedf_remove_sysfs_ctx_attr(struct qedf_ctx *qedf); | 524 | extern void qedf_remove_sysfs_ctx_attr(struct qedf_ctx *qedf); |
496 | extern void qedf_capture_grc_dump(struct qedf_ctx *qedf); | 525 | extern void qedf_capture_grc_dump(struct qedf_ctx *qedf); |
497 | extern void qedf_wait_for_upload(struct qedf_ctx *qedf); | 526 | bool qedf_wait_for_upload(struct qedf_ctx *qedf); |
498 | extern void qedf_process_unsol_compl(struct qedf_ctx *qedf, uint16_t que_idx, | 527 | extern void qedf_process_unsol_compl(struct qedf_ctx *qedf, uint16_t que_idx, |
499 | struct fcoe_cqe *cqe); | 528 | struct fcoe_cqe *cqe); |
500 | extern void qedf_restart_rport(struct qedf_rport *fcport); | 529 | extern void qedf_restart_rport(struct qedf_rport *fcport); |
@@ -508,6 +537,8 @@ extern void qedf_get_protocol_tlv_data(void *dev, void *data); | |||
508 | extern void qedf_fp_io_handler(struct work_struct *work); | 537 | extern void qedf_fp_io_handler(struct work_struct *work); |
509 | extern void qedf_get_generic_tlv_data(void *dev, struct qed_generic_tlvs *data); | 538 | extern void qedf_get_generic_tlv_data(void *dev, struct qed_generic_tlvs *data); |
510 | extern void qedf_wq_grcdump(struct work_struct *work); | 539 | extern void qedf_wq_grcdump(struct work_struct *work); |
540 | void qedf_stag_change_work(struct work_struct *work); | ||
541 | void qedf_ctx_soft_reset(struct fc_lport *lport); | ||
511 | 542 | ||
512 | #define FCOE_WORD_TO_BYTE 4 | 543 | #define FCOE_WORD_TO_BYTE 4 |
513 | #define QEDF_MAX_TASK_NUM 0xFFFF | 544 | #define QEDF_MAX_TASK_NUM 0xFFFF |
diff --git a/drivers/scsi/qedf/qedf_dbg.c b/drivers/scsi/qedf/qedf_dbg.c index f2397ee9ba69..f7d170bffc82 100644 --- a/drivers/scsi/qedf/qedf_dbg.c +++ b/drivers/scsi/qedf/qedf_dbg.c | |||
@@ -15,10 +15,6 @@ qedf_dbg_err(struct qedf_dbg_ctx *qedf, const char *func, u32 line, | |||
15 | { | 15 | { |
16 | va_list va; | 16 | va_list va; |
17 | struct va_format vaf; | 17 | struct va_format vaf; |
18 | char nfunc[32]; | ||
19 | |||
20 | memset(nfunc, 0, sizeof(nfunc)); | ||
21 | memcpy(nfunc, func, sizeof(nfunc) - 1); | ||
22 | 18 | ||
23 | va_start(va, fmt); | 19 | va_start(va, fmt); |
24 | 20 | ||
@@ -27,9 +23,9 @@ qedf_dbg_err(struct qedf_dbg_ctx *qedf, const char *func, u32 line, | |||
27 | 23 | ||
28 | if (likely(qedf) && likely(qedf->pdev)) | 24 | if (likely(qedf) && likely(qedf->pdev)) |
29 | pr_err("[%s]:[%s:%d]:%d: %pV", dev_name(&(qedf->pdev->dev)), | 25 | pr_err("[%s]:[%s:%d]:%d: %pV", dev_name(&(qedf->pdev->dev)), |
30 | nfunc, line, qedf->host_no, &vaf); | 26 | func, line, qedf->host_no, &vaf); |
31 | else | 27 | else |
32 | pr_err("[0000:00:00.0]:[%s:%d]: %pV", nfunc, line, &vaf); | 28 | pr_err("[0000:00:00.0]:[%s:%d]: %pV", func, line, &vaf); |
33 | 29 | ||
34 | va_end(va); | 30 | va_end(va); |
35 | } | 31 | } |
@@ -40,10 +36,6 @@ qedf_dbg_warn(struct qedf_dbg_ctx *qedf, const char *func, u32 line, | |||
40 | { | 36 | { |
41 | va_list va; | 37 | va_list va; |
42 | struct va_format vaf; | 38 | struct va_format vaf; |
43 | char nfunc[32]; | ||
44 | |||
45 | memset(nfunc, 0, sizeof(nfunc)); | ||
46 | memcpy(nfunc, func, sizeof(nfunc) - 1); | ||
47 | 39 | ||
48 | va_start(va, fmt); | 40 | va_start(va, fmt); |
49 | 41 | ||
@@ -55,9 +47,9 @@ qedf_dbg_warn(struct qedf_dbg_ctx *qedf, const char *func, u32 line, | |||
55 | 47 | ||
56 | if (likely(qedf) && likely(qedf->pdev)) | 48 | if (likely(qedf) && likely(qedf->pdev)) |
57 | pr_warn("[%s]:[%s:%d]:%d: %pV", dev_name(&(qedf->pdev->dev)), | 49 | pr_warn("[%s]:[%s:%d]:%d: %pV", dev_name(&(qedf->pdev->dev)), |
58 | nfunc, line, qedf->host_no, &vaf); | 50 | func, line, qedf->host_no, &vaf); |
59 | else | 51 | else |
60 | pr_warn("[0000:00:00.0]:[%s:%d]: %pV", nfunc, line, &vaf); | 52 | pr_warn("[0000:00:00.0]:[%s:%d]: %pV", func, line, &vaf); |
61 | 53 | ||
62 | ret: | 54 | ret: |
63 | va_end(va); | 55 | va_end(va); |
@@ -69,10 +61,6 @@ qedf_dbg_notice(struct qedf_dbg_ctx *qedf, const char *func, u32 line, | |||
69 | { | 61 | { |
70 | va_list va; | 62 | va_list va; |
71 | struct va_format vaf; | 63 | struct va_format vaf; |
72 | char nfunc[32]; | ||
73 | |||
74 | memset(nfunc, 0, sizeof(nfunc)); | ||
75 | memcpy(nfunc, func, sizeof(nfunc) - 1); | ||
76 | 64 | ||
77 | va_start(va, fmt); | 65 | va_start(va, fmt); |
78 | 66 | ||
@@ -84,10 +72,10 @@ qedf_dbg_notice(struct qedf_dbg_ctx *qedf, const char *func, u32 line, | |||
84 | 72 | ||
85 | if (likely(qedf) && likely(qedf->pdev)) | 73 | if (likely(qedf) && likely(qedf->pdev)) |
86 | pr_notice("[%s]:[%s:%d]:%d: %pV", | 74 | pr_notice("[%s]:[%s:%d]:%d: %pV", |
87 | dev_name(&(qedf->pdev->dev)), nfunc, line, | 75 | dev_name(&(qedf->pdev->dev)), func, line, |
88 | qedf->host_no, &vaf); | 76 | qedf->host_no, &vaf); |
89 | else | 77 | else |
90 | pr_notice("[0000:00:00.0]:[%s:%d]: %pV", nfunc, line, &vaf); | 78 | pr_notice("[0000:00:00.0]:[%s:%d]: %pV", func, line, &vaf); |
91 | 79 | ||
92 | ret: | 80 | ret: |
93 | va_end(va); | 81 | va_end(va); |
@@ -99,10 +87,6 @@ qedf_dbg_info(struct qedf_dbg_ctx *qedf, const char *func, u32 line, | |||
99 | { | 87 | { |
100 | va_list va; | 88 | va_list va; |
101 | struct va_format vaf; | 89 | struct va_format vaf; |
102 | char nfunc[32]; | ||
103 | |||
104 | memset(nfunc, 0, sizeof(nfunc)); | ||
105 | memcpy(nfunc, func, sizeof(nfunc) - 1); | ||
106 | 90 | ||
107 | va_start(va, fmt); | 91 | va_start(va, fmt); |
108 | 92 | ||
@@ -114,9 +98,9 @@ qedf_dbg_info(struct qedf_dbg_ctx *qedf, const char *func, u32 line, | |||
114 | 98 | ||
115 | if (likely(qedf) && likely(qedf->pdev)) | 99 | if (likely(qedf) && likely(qedf->pdev)) |
116 | pr_info("[%s]:[%s:%d]:%d: %pV", dev_name(&(qedf->pdev->dev)), | 100 | pr_info("[%s]:[%s:%d]:%d: %pV", dev_name(&(qedf->pdev->dev)), |
117 | nfunc, line, qedf->host_no, &vaf); | 101 | func, line, qedf->host_no, &vaf); |
118 | else | 102 | else |
119 | pr_info("[0000:00:00.0]:[%s:%d]: %pV", nfunc, line, &vaf); | 103 | pr_info("[0000:00:00.0]:[%s:%d]: %pV", func, line, &vaf); |
120 | 104 | ||
121 | ret: | 105 | ret: |
122 | va_end(va); | 106 | va_end(va); |
diff --git a/drivers/scsi/qedf/qedf_debugfs.c b/drivers/scsi/qedf/qedf_debugfs.c index a32d8ee4666e..235389209689 100644 --- a/drivers/scsi/qedf/qedf_debugfs.c +++ b/drivers/scsi/qedf/qedf_debugfs.c | |||
@@ -293,6 +293,33 @@ qedf_dbg_io_trace_open(struct inode *inode, struct file *file) | |||
293 | return single_open(file, qedf_io_trace_show, qedf); | 293 | return single_open(file, qedf_io_trace_show, qedf); |
294 | } | 294 | } |
295 | 295 | ||
296 | /* Based on fip_state enum from libfcoe.h */ | ||
297 | static char *fip_state_names[] = { | ||
298 | "FIP_ST_DISABLED", | ||
299 | "FIP_ST_LINK_WAIT", | ||
300 | "FIP_ST_AUTO", | ||
301 | "FIP_ST_NON_FIP", | ||
302 | "FIP_ST_ENABLED", | ||
303 | "FIP_ST_VNMP_START", | ||
304 | "FIP_ST_VNMP_PROBE1", | ||
305 | "FIP_ST_VNMP_PROBE2", | ||
306 | "FIP_ST_VNMP_CLAIM", | ||
307 | "FIP_ST_VNMP_UP", | ||
308 | }; | ||
309 | |||
310 | /* Based on fc_rport_state enum from libfc.h */ | ||
311 | static char *fc_rport_state_names[] = { | ||
312 | "RPORT_ST_INIT", | ||
313 | "RPORT_ST_FLOGI", | ||
314 | "RPORT_ST_PLOGI_WAIT", | ||
315 | "RPORT_ST_PLOGI", | ||
316 | "RPORT_ST_PRLI", | ||
317 | "RPORT_ST_RTV", | ||
318 | "RPORT_ST_READY", | ||
319 | "RPORT_ST_ADISC", | ||
320 | "RPORT_ST_DELETE", | ||
321 | }; | ||
322 | |||
296 | static int | 323 | static int |
297 | qedf_driver_stats_show(struct seq_file *s, void *unused) | 324 | qedf_driver_stats_show(struct seq_file *s, void *unused) |
298 | { | 325 | { |
@@ -300,10 +327,28 @@ qedf_driver_stats_show(struct seq_file *s, void *unused) | |||
300 | struct qedf_rport *fcport; | 327 | struct qedf_rport *fcport; |
301 | struct fc_rport_priv *rdata; | 328 | struct fc_rport_priv *rdata; |
302 | 329 | ||
330 | seq_printf(s, "Host WWNN/WWPN: %016llx/%016llx\n", | ||
331 | qedf->wwnn, qedf->wwpn); | ||
332 | seq_printf(s, "Host NPortID: %06x\n", qedf->lport->port_id); | ||
333 | seq_printf(s, "Link State: %s\n", atomic_read(&qedf->link_state) ? | ||
334 | "Up" : "Down"); | ||
335 | seq_printf(s, "Logical Link State: %s\n", qedf->lport->link_up ? | ||
336 | "Up" : "Down"); | ||
337 | seq_printf(s, "FIP state: %s\n", fip_state_names[qedf->ctlr.state]); | ||
338 | seq_printf(s, "FIP VLAN ID: %d\n", qedf->vlan_id & 0xfff); | ||
339 | seq_printf(s, "FIP 802.1Q Priority: %d\n", qedf->prio); | ||
340 | if (qedf->ctlr.sel_fcf) { | ||
341 | seq_printf(s, "FCF WWPN: %016llx\n", | ||
342 | qedf->ctlr.sel_fcf->switch_name); | ||
343 | seq_printf(s, "FCF MAC: %pM\n", qedf->ctlr.sel_fcf->fcf_mac); | ||
344 | } else { | ||
345 | seq_puts(s, "FCF not selected\n"); | ||
346 | } | ||
347 | |||
348 | seq_puts(s, "\nSGE stats:\n\n"); | ||
303 | seq_printf(s, "cmg_mgr free io_reqs: %d\n", | 349 | seq_printf(s, "cmg_mgr free io_reqs: %d\n", |
304 | atomic_read(&qedf->cmd_mgr->free_list_cnt)); | 350 | atomic_read(&qedf->cmd_mgr->free_list_cnt)); |
305 | seq_printf(s, "slow SGEs: %d\n", qedf->slow_sge_ios); | 351 | seq_printf(s, "slow SGEs: %d\n", qedf->slow_sge_ios); |
306 | seq_printf(s, "single SGEs: %d\n", qedf->single_sge_ios); | ||
307 | seq_printf(s, "fast SGEs: %d\n\n", qedf->fast_sge_ios); | 352 | seq_printf(s, "fast SGEs: %d\n\n", qedf->fast_sge_ios); |
308 | 353 | ||
309 | seq_puts(s, "Offloaded ports:\n\n"); | 354 | seq_puts(s, "Offloaded ports:\n\n"); |
@@ -313,9 +358,12 @@ qedf_driver_stats_show(struct seq_file *s, void *unused) | |||
313 | rdata = fcport->rdata; | 358 | rdata = fcport->rdata; |
314 | if (rdata == NULL) | 359 | if (rdata == NULL) |
315 | continue; | 360 | continue; |
316 | seq_printf(s, "%06x: free_sqes: %d, num_active_ios: %d\n", | 361 | seq_printf(s, "%016llx/%016llx/%06x: state=%s, free_sqes=%d, num_active_ios=%d\n", |
317 | rdata->ids.port_id, atomic_read(&fcport->free_sqes), | 362 | rdata->rport->node_name, rdata->rport->port_name, |
318 | atomic_read(&fcport->num_active_ios)); | 363 | rdata->ids.port_id, |
364 | fc_rport_state_names[rdata->rp_state], | ||
365 | atomic_read(&fcport->free_sqes), | ||
366 | atomic_read(&fcport->num_active_ios)); | ||
319 | } | 367 | } |
320 | rcu_read_unlock(); | 368 | rcu_read_unlock(); |
321 | 369 | ||
@@ -361,7 +409,6 @@ qedf_dbg_clear_stats_cmd_write(struct file *filp, | |||
361 | 409 | ||
362 | /* Clear stat counters exposed by 'stats' node */ | 410 | /* Clear stat counters exposed by 'stats' node */ |
363 | qedf->slow_sge_ios = 0; | 411 | qedf->slow_sge_ios = 0; |
364 | qedf->single_sge_ios = 0; | ||
365 | qedf->fast_sge_ios = 0; | 412 | qedf->fast_sge_ios = 0; |
366 | 413 | ||
367 | return count; | 414 | return count; |
diff --git a/drivers/scsi/qedf/qedf_els.c b/drivers/scsi/qedf/qedf_els.c index 04f0c4d2e256..d900c89e8049 100644 --- a/drivers/scsi/qedf/qedf_els.c +++ b/drivers/scsi/qedf/qedf_els.c | |||
@@ -23,8 +23,6 @@ static int qedf_initiate_els(struct qedf_rport *fcport, unsigned int op, | |||
23 | int rc = 0; | 23 | int rc = 0; |
24 | uint32_t did, sid; | 24 | uint32_t did, sid; |
25 | uint16_t xid; | 25 | uint16_t xid; |
26 | uint32_t start_time = jiffies / HZ; | ||
27 | uint32_t current_time; | ||
28 | struct fcoe_wqe *sqe; | 26 | struct fcoe_wqe *sqe; |
29 | unsigned long flags; | 27 | unsigned long flags; |
30 | u16 sqe_idx; | 28 | u16 sqe_idx; |
@@ -59,18 +57,12 @@ static int qedf_initiate_els(struct qedf_rport *fcport, unsigned int op, | |||
59 | goto els_err; | 57 | goto els_err; |
60 | } | 58 | } |
61 | 59 | ||
62 | retry_els: | ||
63 | els_req = qedf_alloc_cmd(fcport, QEDF_ELS); | 60 | els_req = qedf_alloc_cmd(fcport, QEDF_ELS); |
64 | if (!els_req) { | 61 | if (!els_req) { |
65 | current_time = jiffies / HZ; | 62 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_ELS, |
66 | if ((current_time - start_time) > 10) { | 63 | "Failed to alloc ELS request 0x%x\n", op); |
67 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, | 64 | rc = -ENOMEM; |
68 | "els: Failed els 0x%x\n", op); | 65 | goto els_err; |
69 | rc = -ENOMEM; | ||
70 | goto els_err; | ||
71 | } | ||
72 | mdelay(20 * USEC_PER_MSEC); | ||
73 | goto retry_els; | ||
74 | } | 66 | } |
75 | 67 | ||
76 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "initiate_els els_req = " | 68 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "initiate_els els_req = " |
@@ -143,6 +135,8 @@ retry_els: | |||
143 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Ringing doorbell for ELS " | 135 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Ringing doorbell for ELS " |
144 | "req\n"); | 136 | "req\n"); |
145 | qedf_ring_doorbell(fcport); | 137 | qedf_ring_doorbell(fcport); |
138 | set_bit(QEDF_CMD_OUTSTANDING, &els_req->flags); | ||
139 | |||
146 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 140 | spin_unlock_irqrestore(&fcport->rport_lock, flags); |
147 | els_err: | 141 | els_err: |
148 | return rc; | 142 | return rc; |
@@ -151,21 +145,16 @@ els_err: | |||
151 | void qedf_process_els_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, | 145 | void qedf_process_els_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, |
152 | struct qedf_ioreq *els_req) | 146 | struct qedf_ioreq *els_req) |
153 | { | 147 | { |
154 | struct fcoe_task_context *task_ctx; | ||
155 | struct scsi_cmnd *sc_cmd; | ||
156 | uint16_t xid; | ||
157 | struct fcoe_cqe_midpath_info *mp_info; | 148 | struct fcoe_cqe_midpath_info *mp_info; |
158 | 149 | ||
159 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Entered with xid = 0x%x" | 150 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Entered with xid = 0x%x" |
160 | " cmd_type = %d.\n", els_req->xid, els_req->cmd_type); | 151 | " cmd_type = %d.\n", els_req->xid, els_req->cmd_type); |
161 | 152 | ||
153 | clear_bit(QEDF_CMD_OUTSTANDING, &els_req->flags); | ||
154 | |||
162 | /* Kill the ELS timer */ | 155 | /* Kill the ELS timer */ |
163 | cancel_delayed_work(&els_req->timeout_work); | 156 | cancel_delayed_work(&els_req->timeout_work); |
164 | 157 | ||
165 | xid = els_req->xid; | ||
166 | task_ctx = qedf_get_task_mem(&qedf->tasks, xid); | ||
167 | sc_cmd = els_req->sc_cmd; | ||
168 | |||
169 | /* Get ELS response length from CQE */ | 158 | /* Get ELS response length from CQE */ |
170 | mp_info = &cqe->cqe_info.midpath_info; | 159 | mp_info = &cqe->cqe_info.midpath_info; |
171 | els_req->mp_req.resp_len = mp_info->data_placement_size; | 160 | els_req->mp_req.resp_len = mp_info->data_placement_size; |
@@ -205,8 +194,12 @@ static void qedf_rrq_compl(struct qedf_els_cb_arg *cb_arg) | |||
205 | " orig xid = 0x%x, rrq_xid = 0x%x, refcount=%d\n", | 194 | " orig xid = 0x%x, rrq_xid = 0x%x, refcount=%d\n", |
206 | orig_io_req, orig_io_req->xid, rrq_req->xid, refcount); | 195 | orig_io_req, orig_io_req->xid, rrq_req->xid, refcount); |
207 | 196 | ||
208 | /* This should return the aborted io_req to the command pool */ | 197 | /* |
209 | if (orig_io_req) | 198 | * This should return the aborted io_req to the command pool. Note that |
199 | * we need to check the refcound in case the original request was | ||
200 | * flushed but we get a completion on this xid. | ||
201 | */ | ||
202 | if (orig_io_req && refcount > 0) | ||
210 | kref_put(&orig_io_req->refcount, qedf_release_cmd); | 203 | kref_put(&orig_io_req->refcount, qedf_release_cmd); |
211 | 204 | ||
212 | out_free: | 205 | out_free: |
@@ -233,6 +226,7 @@ int qedf_send_rrq(struct qedf_ioreq *aborted_io_req) | |||
233 | uint32_t sid; | 226 | uint32_t sid; |
234 | uint32_t r_a_tov; | 227 | uint32_t r_a_tov; |
235 | int rc; | 228 | int rc; |
229 | int refcount; | ||
236 | 230 | ||
237 | if (!aborted_io_req) { | 231 | if (!aborted_io_req) { |
238 | QEDF_ERR(NULL, "abort_io_req is NULL.\n"); | 232 | QEDF_ERR(NULL, "abort_io_req is NULL.\n"); |
@@ -241,6 +235,15 @@ int qedf_send_rrq(struct qedf_ioreq *aborted_io_req) | |||
241 | 235 | ||
242 | fcport = aborted_io_req->fcport; | 236 | fcport = aborted_io_req->fcport; |
243 | 237 | ||
238 | if (!fcport) { | ||
239 | refcount = kref_read(&aborted_io_req->refcount); | ||
240 | QEDF_ERR(NULL, | ||
241 | "RRQ work was queued prior to a flush xid=0x%x, refcount=%d.\n", | ||
242 | aborted_io_req->xid, refcount); | ||
243 | kref_put(&aborted_io_req->refcount, qedf_release_cmd); | ||
244 | return -EINVAL; | ||
245 | } | ||
246 | |||
244 | /* Check that fcport is still offloaded */ | 247 | /* Check that fcport is still offloaded */ |
245 | if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) { | 248 | if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) { |
246 | QEDF_ERR(NULL, "fcport is no longer offloaded.\n"); | 249 | QEDF_ERR(NULL, "fcport is no longer offloaded.\n"); |
@@ -253,6 +256,19 @@ int qedf_send_rrq(struct qedf_ioreq *aborted_io_req) | |||
253 | } | 256 | } |
254 | 257 | ||
255 | qedf = fcport->qedf; | 258 | qedf = fcport->qedf; |
259 | |||
260 | /* | ||
261 | * Sanity check that we can send a RRQ to make sure that refcount isn't | ||
262 | * 0 | ||
263 | */ | ||
264 | refcount = kref_read(&aborted_io_req->refcount); | ||
265 | if (refcount != 1) { | ||
266 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_ELS, | ||
267 | "refcount for xid=%x io_req=%p refcount=%d is not 1.\n", | ||
268 | aborted_io_req->xid, aborted_io_req, refcount); | ||
269 | return -EINVAL; | ||
270 | } | ||
271 | |||
256 | lport = qedf->lport; | 272 | lport = qedf->lport; |
257 | sid = fcport->sid; | 273 | sid = fcport->sid; |
258 | r_a_tov = lport->r_a_tov; | 274 | r_a_tov = lport->r_a_tov; |
@@ -335,32 +351,49 @@ void qedf_restart_rport(struct qedf_rport *fcport) | |||
335 | struct fc_lport *lport; | 351 | struct fc_lport *lport; |
336 | struct fc_rport_priv *rdata; | 352 | struct fc_rport_priv *rdata; |
337 | u32 port_id; | 353 | u32 port_id; |
354 | unsigned long flags; | ||
338 | 355 | ||
339 | if (!fcport) | 356 | if (!fcport) |
340 | return; | 357 | return; |
341 | 358 | ||
359 | spin_lock_irqsave(&fcport->rport_lock, flags); | ||
342 | if (test_bit(QEDF_RPORT_IN_RESET, &fcport->flags) || | 360 | if (test_bit(QEDF_RPORT_IN_RESET, &fcport->flags) || |
343 | !test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags) || | 361 | !test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags) || |
344 | test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) { | 362 | test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) { |
345 | QEDF_ERR(&(fcport->qedf->dbg_ctx), "fcport %p already in reset or not offloaded.\n", | 363 | QEDF_ERR(&(fcport->qedf->dbg_ctx), "fcport %p already in reset or not offloaded.\n", |
346 | fcport); | 364 | fcport); |
365 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
347 | return; | 366 | return; |
348 | } | 367 | } |
349 | 368 | ||
350 | /* Set that we are now in reset */ | 369 | /* Set that we are now in reset */ |
351 | set_bit(QEDF_RPORT_IN_RESET, &fcport->flags); | 370 | set_bit(QEDF_RPORT_IN_RESET, &fcport->flags); |
371 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
352 | 372 | ||
353 | rdata = fcport->rdata; | 373 | rdata = fcport->rdata; |
354 | if (rdata) { | 374 | if (rdata && !kref_get_unless_zero(&rdata->kref)) { |
375 | fcport->rdata = NULL; | ||
376 | rdata = NULL; | ||
377 | } | ||
378 | |||
379 | if (rdata && rdata->rp_state == RPORT_ST_READY) { | ||
355 | lport = fcport->qedf->lport; | 380 | lport = fcport->qedf->lport; |
356 | port_id = rdata->ids.port_id; | 381 | port_id = rdata->ids.port_id; |
357 | QEDF_ERR(&(fcport->qedf->dbg_ctx), | 382 | QEDF_ERR(&(fcport->qedf->dbg_ctx), |
358 | "LOGO port_id=%x.\n", port_id); | 383 | "LOGO port_id=%x.\n", port_id); |
359 | fc_rport_logoff(rdata); | 384 | fc_rport_logoff(rdata); |
385 | kref_put(&rdata->kref, fc_rport_destroy); | ||
386 | mutex_lock(&lport->disc.disc_mutex); | ||
360 | /* Recreate the rport and log back in */ | 387 | /* Recreate the rport and log back in */ |
361 | rdata = fc_rport_create(lport, port_id); | 388 | rdata = fc_rport_create(lport, port_id); |
362 | if (rdata) | 389 | if (rdata) { |
390 | mutex_unlock(&lport->disc.disc_mutex); | ||
363 | fc_rport_login(rdata); | 391 | fc_rport_login(rdata); |
392 | fcport->rdata = rdata; | ||
393 | } else { | ||
394 | mutex_unlock(&lport->disc.disc_mutex); | ||
395 | fcport->rdata = NULL; | ||
396 | } | ||
364 | } | 397 | } |
365 | clear_bit(QEDF_RPORT_IN_RESET, &fcport->flags); | 398 | clear_bit(QEDF_RPORT_IN_RESET, &fcport->flags); |
366 | } | 399 | } |
@@ -569,7 +602,7 @@ static int qedf_send_srr(struct qedf_ioreq *orig_io_req, u32 offset, u8 r_ctl) | |||
569 | struct qedf_rport *fcport; | 602 | struct qedf_rport *fcport; |
570 | struct fc_lport *lport; | 603 | struct fc_lport *lport; |
571 | struct qedf_els_cb_arg *cb_arg = NULL; | 604 | struct qedf_els_cb_arg *cb_arg = NULL; |
572 | u32 sid, r_a_tov; | 605 | u32 r_a_tov; |
573 | int rc; | 606 | int rc; |
574 | 607 | ||
575 | if (!orig_io_req) { | 608 | if (!orig_io_req) { |
@@ -595,7 +628,6 @@ static int qedf_send_srr(struct qedf_ioreq *orig_io_req, u32 offset, u8 r_ctl) | |||
595 | 628 | ||
596 | qedf = fcport->qedf; | 629 | qedf = fcport->qedf; |
597 | lport = qedf->lport; | 630 | lport = qedf->lport; |
598 | sid = fcport->sid; | ||
599 | r_a_tov = lport->r_a_tov; | 631 | r_a_tov = lport->r_a_tov; |
600 | 632 | ||
601 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Sending SRR orig_io=%p, " | 633 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Sending SRR orig_io=%p, " |
diff --git a/drivers/scsi/qedf/qedf_fip.c b/drivers/scsi/qedf/qedf_fip.c index 3fd3af799b3d..d4741f8dcb41 100644 --- a/drivers/scsi/qedf/qedf_fip.c +++ b/drivers/scsi/qedf/qedf_fip.c | |||
@@ -19,17 +19,16 @@ void qedf_fcoe_send_vlan_req(struct qedf_ctx *qedf) | |||
19 | { | 19 | { |
20 | struct sk_buff *skb; | 20 | struct sk_buff *skb; |
21 | char *eth_fr; | 21 | char *eth_fr; |
22 | int fr_len; | ||
23 | struct fip_vlan *vlan; | 22 | struct fip_vlan *vlan; |
24 | #define MY_FIP_ALL_FCF_MACS ((__u8[6]) { 1, 0x10, 0x18, 1, 0, 2 }) | 23 | #define MY_FIP_ALL_FCF_MACS ((__u8[6]) { 1, 0x10, 0x18, 1, 0, 2 }) |
25 | static u8 my_fcoe_all_fcfs[ETH_ALEN] = MY_FIP_ALL_FCF_MACS; | 24 | static u8 my_fcoe_all_fcfs[ETH_ALEN] = MY_FIP_ALL_FCF_MACS; |
26 | unsigned long flags = 0; | 25 | unsigned long flags = 0; |
26 | int rc = -1; | ||
27 | 27 | ||
28 | skb = dev_alloc_skb(sizeof(struct fip_vlan)); | 28 | skb = dev_alloc_skb(sizeof(struct fip_vlan)); |
29 | if (!skb) | 29 | if (!skb) |
30 | return; | 30 | return; |
31 | 31 | ||
32 | fr_len = sizeof(*vlan); | ||
33 | eth_fr = (char *)skb->data; | 32 | eth_fr = (char *)skb->data; |
34 | vlan = (struct fip_vlan *)eth_fr; | 33 | vlan = (struct fip_vlan *)eth_fr; |
35 | 34 | ||
@@ -68,7 +67,13 @@ void qedf_fcoe_send_vlan_req(struct qedf_ctx *qedf) | |||
68 | } | 67 | } |
69 | 68 | ||
70 | set_bit(QED_LL2_XMIT_FLAGS_FIP_DISCOVERY, &flags); | 69 | set_bit(QED_LL2_XMIT_FLAGS_FIP_DISCOVERY, &flags); |
71 | qed_ops->ll2->start_xmit(qedf->cdev, skb, flags); | 70 | rc = qed_ops->ll2->start_xmit(qedf->cdev, skb, flags); |
71 | if (rc) { | ||
72 | QEDF_ERR(&qedf->dbg_ctx, "start_xmit failed rc = %d.\n", rc); | ||
73 | kfree_skb(skb); | ||
74 | return; | ||
75 | } | ||
76 | |||
72 | } | 77 | } |
73 | 78 | ||
74 | static void qedf_fcoe_process_vlan_resp(struct qedf_ctx *qedf, | 79 | static void qedf_fcoe_process_vlan_resp(struct qedf_ctx *qedf, |
@@ -95,6 +100,12 @@ static void qedf_fcoe_process_vlan_resp(struct qedf_ctx *qedf, | |||
95 | rlen -= dlen; | 100 | rlen -= dlen; |
96 | } | 101 | } |
97 | 102 | ||
103 | if (atomic_read(&qedf->link_state) == QEDF_LINK_DOWN) { | ||
104 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC, | ||
105 | "Dropping VLAN response as link is down.\n"); | ||
106 | return; | ||
107 | } | ||
108 | |||
98 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "VLAN response, " | 109 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "VLAN response, " |
99 | "vid=0x%x.\n", vid); | 110 | "vid=0x%x.\n", vid); |
100 | 111 | ||
@@ -114,6 +125,7 @@ void qedf_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
114 | struct fip_header *fiph; | 125 | struct fip_header *fiph; |
115 | u16 op, vlan_tci = 0; | 126 | u16 op, vlan_tci = 0; |
116 | u8 sub; | 127 | u8 sub; |
128 | int rc = -1; | ||
117 | 129 | ||
118 | if (!test_bit(QEDF_LL2_STARTED, &qedf->flags)) { | 130 | if (!test_bit(QEDF_LL2_STARTED, &qedf->flags)) { |
119 | QEDF_WARN(&(qedf->dbg_ctx), "LL2 not started\n"); | 131 | QEDF_WARN(&(qedf->dbg_ctx), "LL2 not started\n"); |
@@ -142,9 +154,16 @@ void qedf_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
142 | print_hex_dump(KERN_WARNING, "fip ", DUMP_PREFIX_OFFSET, 16, 1, | 154 | print_hex_dump(KERN_WARNING, "fip ", DUMP_PREFIX_OFFSET, 16, 1, |
143 | skb->data, skb->len, false); | 155 | skb->data, skb->len, false); |
144 | 156 | ||
145 | qed_ops->ll2->start_xmit(qedf->cdev, skb, 0); | 157 | rc = qed_ops->ll2->start_xmit(qedf->cdev, skb, 0); |
158 | if (rc) { | ||
159 | QEDF_ERR(&qedf->dbg_ctx, "start_xmit failed rc = %d.\n", rc); | ||
160 | kfree_skb(skb); | ||
161 | return; | ||
162 | } | ||
146 | } | 163 | } |
147 | 164 | ||
165 | static u8 fcoe_all_enode[ETH_ALEN] = FIP_ALL_ENODE_MACS; | ||
166 | |||
148 | /* Process incoming FIP frames. */ | 167 | /* Process incoming FIP frames. */ |
149 | void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb) | 168 | void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb) |
150 | { | 169 | { |
@@ -157,20 +176,37 @@ void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb) | |||
157 | size_t rlen, dlen; | 176 | size_t rlen, dlen; |
158 | u16 op; | 177 | u16 op; |
159 | u8 sub; | 178 | u8 sub; |
160 | bool do_reset = false; | 179 | bool fcf_valid = false; |
180 | /* Default is to handle CVL regardless of fabric id descriptor */ | ||
181 | bool fabric_id_valid = true; | ||
182 | bool fc_wwpn_valid = false; | ||
183 | u64 switch_name; | ||
184 | u16 vlan = 0; | ||
161 | 185 | ||
162 | eth_hdr = (struct ethhdr *)skb_mac_header(skb); | 186 | eth_hdr = (struct ethhdr *)skb_mac_header(skb); |
163 | fiph = (struct fip_header *) ((void *)skb->data + 2 * ETH_ALEN + 2); | 187 | fiph = (struct fip_header *) ((void *)skb->data + 2 * ETH_ALEN + 2); |
164 | op = ntohs(fiph->fip_op); | 188 | op = ntohs(fiph->fip_op); |
165 | sub = fiph->fip_subcode; | 189 | sub = fiph->fip_subcode; |
166 | 190 | ||
167 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2, "FIP frame received: " | 191 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_LL2, |
168 | "skb=%p fiph=%p source=%pM op=%x sub=%x", skb, fiph, | 192 | "FIP frame received: skb=%p fiph=%p source=%pM destn=%pM op=%x sub=%x vlan=%04x", |
169 | eth_hdr->h_source, op, sub); | 193 | skb, fiph, eth_hdr->h_source, eth_hdr->h_dest, op, |
194 | sub, vlan); | ||
170 | if (qedf_dump_frames) | 195 | if (qedf_dump_frames) |
171 | print_hex_dump(KERN_WARNING, "fip ", DUMP_PREFIX_OFFSET, 16, 1, | 196 | print_hex_dump(KERN_WARNING, "fip ", DUMP_PREFIX_OFFSET, 16, 1, |
172 | skb->data, skb->len, false); | 197 | skb->data, skb->len, false); |
173 | 198 | ||
199 | if (!ether_addr_equal(eth_hdr->h_dest, qedf->mac) && | ||
200 | !ether_addr_equal(eth_hdr->h_dest, fcoe_all_enode) && | ||
201 | !ether_addr_equal(eth_hdr->h_dest, qedf->data_src_addr)) { | ||
202 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_LL2, | ||
203 | "Dropping FIP type 0x%x pkt due to destination MAC mismatch dest_mac=%pM ctlr.dest_addr=%pM data_src_addr=%pM.\n", | ||
204 | op, eth_hdr->h_dest, qedf->mac, | ||
205 | qedf->data_src_addr); | ||
206 | kfree_skb(skb); | ||
207 | return; | ||
208 | } | ||
209 | |||
174 | /* Handle FIP VLAN resp in the driver */ | 210 | /* Handle FIP VLAN resp in the driver */ |
175 | if (op == FIP_OP_VLAN && sub == FIP_SC_VL_NOTE) { | 211 | if (op == FIP_OP_VLAN && sub == FIP_SC_VL_NOTE) { |
176 | qedf_fcoe_process_vlan_resp(qedf, skb); | 212 | qedf_fcoe_process_vlan_resp(qedf, skb); |
@@ -199,25 +235,36 @@ void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb) | |||
199 | switch (desc->fip_dtype) { | 235 | switch (desc->fip_dtype) { |
200 | case FIP_DT_MAC: | 236 | case FIP_DT_MAC: |
201 | mp = (struct fip_mac_desc *)desc; | 237 | mp = (struct fip_mac_desc *)desc; |
202 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2, | 238 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC, |
203 | "fd_mac=%pM\n", mp->fd_mac); | 239 | "Switch fd_mac=%pM.\n", mp->fd_mac); |
204 | if (ether_addr_equal(mp->fd_mac, | 240 | if (ether_addr_equal(mp->fd_mac, |
205 | qedf->ctlr.sel_fcf->fcf_mac)) | 241 | qedf->ctlr.sel_fcf->fcf_mac)) |
206 | do_reset = true; | 242 | fcf_valid = true; |
207 | break; | 243 | break; |
208 | case FIP_DT_NAME: | 244 | case FIP_DT_NAME: |
209 | wp = (struct fip_wwn_desc *)desc; | 245 | wp = (struct fip_wwn_desc *)desc; |
210 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2, | 246 | switch_name = get_unaligned_be64(&wp->fd_wwn); |
211 | "fc_wwpn=%016llx.\n", | 247 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC, |
212 | get_unaligned_be64(&wp->fd_wwn)); | 248 | "Switch fd_wwn=%016llx fcf_switch_name=%016llx.\n", |
249 | switch_name, | ||
250 | qedf->ctlr.sel_fcf->switch_name); | ||
251 | if (switch_name == | ||
252 | qedf->ctlr.sel_fcf->switch_name) | ||
253 | fc_wwpn_valid = true; | ||
213 | break; | 254 | break; |
214 | case FIP_DT_VN_ID: | 255 | case FIP_DT_VN_ID: |
215 | vp = (struct fip_vn_desc *)desc; | 256 | vp = (struct fip_vn_desc *)desc; |
216 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2, | 257 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC, |
217 | "fd_fc_id=%x.\n", ntoh24(vp->fd_fc_id)); | 258 | "vx_port fd_fc_id=%x fd_mac=%pM.\n", |
218 | if (ntoh24(vp->fd_fc_id) == | 259 | ntoh24(vp->fd_fc_id), vp->fd_mac); |
260 | /* Check vx_port fabric ID */ | ||
261 | if (ntoh24(vp->fd_fc_id) != | ||
219 | qedf->lport->port_id) | 262 | qedf->lport->port_id) |
220 | do_reset = true; | 263 | fabric_id_valid = false; |
264 | /* Check vx_port MAC */ | ||
265 | if (!ether_addr_equal(vp->fd_mac, | ||
266 | qedf->data_src_addr)) | ||
267 | fabric_id_valid = false; | ||
221 | break; | 268 | break; |
222 | default: | 269 | default: |
223 | /* Ignore anything else */ | 270 | /* Ignore anything else */ |
@@ -227,13 +274,11 @@ void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb) | |||
227 | rlen -= dlen; | 274 | rlen -= dlen; |
228 | } | 275 | } |
229 | 276 | ||
230 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2, | 277 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC, |
231 | "do_reset=%d.\n", do_reset); | 278 | "fcf_valid=%d fabric_id_valid=%d fc_wwpn_valid=%d.\n", |
232 | if (do_reset) { | 279 | fcf_valid, fabric_id_valid, fc_wwpn_valid); |
233 | fcoe_ctlr_link_down(&qedf->ctlr); | 280 | if (fcf_valid && fabric_id_valid && fc_wwpn_valid) |
234 | qedf_wait_for_upload(qedf); | 281 | qedf_ctx_soft_reset(qedf->lport); |
235 | fcoe_ctlr_link_up(&qedf->ctlr); | ||
236 | } | ||
237 | kfree_skb(skb); | 282 | kfree_skb(skb); |
238 | } else { | 283 | } else { |
239 | /* Everything else is handled by libfcoe */ | 284 | /* Everything else is handled by libfcoe */ |
diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c index 53e8221f6816..42f9f2a9d8ea 100644 --- a/drivers/scsi/qedf/qedf_io.c +++ b/drivers/scsi/qedf/qedf_io.c | |||
@@ -43,8 +43,9 @@ static void qedf_cmd_timeout(struct work_struct *work) | |||
43 | switch (io_req->cmd_type) { | 43 | switch (io_req->cmd_type) { |
44 | case QEDF_ABTS: | 44 | case QEDF_ABTS: |
45 | if (qedf == NULL) { | 45 | if (qedf == NULL) { |
46 | QEDF_INFO(NULL, QEDF_LOG_IO, "qedf is NULL for xid=0x%x.\n", | 46 | QEDF_INFO(NULL, QEDF_LOG_IO, |
47 | io_req->xid); | 47 | "qedf is NULL for ABTS xid=0x%x.\n", |
48 | io_req->xid); | ||
48 | return; | 49 | return; |
49 | } | 50 | } |
50 | 51 | ||
@@ -61,6 +62,9 @@ static void qedf_cmd_timeout(struct work_struct *work) | |||
61 | */ | 62 | */ |
62 | kref_put(&io_req->refcount, qedf_release_cmd); | 63 | kref_put(&io_req->refcount, qedf_release_cmd); |
63 | 64 | ||
65 | /* Clear in abort bit now that we're done with the command */ | ||
66 | clear_bit(QEDF_CMD_IN_ABORT, &io_req->flags); | ||
67 | |||
64 | /* | 68 | /* |
65 | * Now that the original I/O and the ABTS are complete see | 69 | * Now that the original I/O and the ABTS are complete see |
66 | * if we need to reconnect to the target. | 70 | * if we need to reconnect to the target. |
@@ -68,6 +72,15 @@ static void qedf_cmd_timeout(struct work_struct *work) | |||
68 | qedf_restart_rport(fcport); | 72 | qedf_restart_rport(fcport); |
69 | break; | 73 | break; |
70 | case QEDF_ELS: | 74 | case QEDF_ELS: |
75 | if (!qedf) { | ||
76 | QEDF_INFO(NULL, QEDF_LOG_IO, | ||
77 | "qedf is NULL for ELS xid=0x%x.\n", | ||
78 | io_req->xid); | ||
79 | return; | ||
80 | } | ||
81 | /* ELS request no longer outstanding since it timed out */ | ||
82 | clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags); | ||
83 | |||
71 | kref_get(&io_req->refcount); | 84 | kref_get(&io_req->refcount); |
72 | /* | 85 | /* |
73 | * Don't attempt to clean an ELS timeout as any subseqeunt | 86 | * Don't attempt to clean an ELS timeout as any subseqeunt |
@@ -103,7 +116,7 @@ void qedf_cmd_mgr_free(struct qedf_cmd_mgr *cmgr) | |||
103 | struct io_bdt *bdt_info; | 116 | struct io_bdt *bdt_info; |
104 | struct qedf_ctx *qedf = cmgr->qedf; | 117 | struct qedf_ctx *qedf = cmgr->qedf; |
105 | size_t bd_tbl_sz; | 118 | size_t bd_tbl_sz; |
106 | u16 min_xid = QEDF_MIN_XID; | 119 | u16 min_xid = 0; |
107 | u16 max_xid = (FCOE_PARAMS_NUM_TASKS - 1); | 120 | u16 max_xid = (FCOE_PARAMS_NUM_TASKS - 1); |
108 | int num_ios; | 121 | int num_ios; |
109 | int i; | 122 | int i; |
@@ -157,6 +170,7 @@ static void qedf_handle_rrq(struct work_struct *work) | |||
157 | struct qedf_ioreq *io_req = | 170 | struct qedf_ioreq *io_req = |
158 | container_of(work, struct qedf_ioreq, rrq_work.work); | 171 | container_of(work, struct qedf_ioreq, rrq_work.work); |
159 | 172 | ||
173 | atomic_set(&io_req->state, QEDFC_CMD_ST_RRQ_ACTIVE); | ||
160 | qedf_send_rrq(io_req); | 174 | qedf_send_rrq(io_req); |
161 | 175 | ||
162 | } | 176 | } |
@@ -169,7 +183,7 @@ struct qedf_cmd_mgr *qedf_cmd_mgr_alloc(struct qedf_ctx *qedf) | |||
169 | u16 xid; | 183 | u16 xid; |
170 | int i; | 184 | int i; |
171 | int num_ios; | 185 | int num_ios; |
172 | u16 min_xid = QEDF_MIN_XID; | 186 | u16 min_xid = 0; |
173 | u16 max_xid = (FCOE_PARAMS_NUM_TASKS - 1); | 187 | u16 max_xid = (FCOE_PARAMS_NUM_TASKS - 1); |
174 | 188 | ||
175 | /* Make sure num_queues is already set before calling this function */ | 189 | /* Make sure num_queues is already set before calling this function */ |
@@ -201,7 +215,7 @@ struct qedf_cmd_mgr *qedf_cmd_mgr_alloc(struct qedf_ctx *qedf) | |||
201 | /* | 215 | /* |
202 | * Initialize I/O request fields. | 216 | * Initialize I/O request fields. |
203 | */ | 217 | */ |
204 | xid = QEDF_MIN_XID; | 218 | xid = 0; |
205 | 219 | ||
206 | for (i = 0; i < num_ios; i++) { | 220 | for (i = 0; i < num_ios; i++) { |
207 | io_req = &cmgr->cmds[i]; | 221 | io_req = &cmgr->cmds[i]; |
@@ -329,7 +343,7 @@ struct qedf_ioreq *qedf_alloc_cmd(struct qedf_rport *fcport, u8 cmd_type) | |||
329 | cmd_mgr->idx = 0; | 343 | cmd_mgr->idx = 0; |
330 | 344 | ||
331 | /* Check to make sure command was previously freed */ | 345 | /* Check to make sure command was previously freed */ |
332 | if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags)) | 346 | if (!io_req->alloc) |
333 | break; | 347 | break; |
334 | } | 348 | } |
335 | 349 | ||
@@ -338,7 +352,14 @@ struct qedf_ioreq *qedf_alloc_cmd(struct qedf_rport *fcport, u8 cmd_type) | |||
338 | goto out_failed; | 352 | goto out_failed; |
339 | } | 353 | } |
340 | 354 | ||
341 | set_bit(QEDF_CMD_OUTSTANDING, &io_req->flags); | 355 | if (test_bit(QEDF_CMD_DIRTY, &io_req->flags)) |
356 | QEDF_ERR(&qedf->dbg_ctx, | ||
357 | "io_req found to be dirty ox_id = 0x%x.\n", | ||
358 | io_req->xid); | ||
359 | |||
360 | /* Clear any flags now that we've reallocated the xid */ | ||
361 | io_req->flags = 0; | ||
362 | io_req->alloc = 1; | ||
342 | spin_unlock_irqrestore(&cmd_mgr->lock, flags); | 363 | spin_unlock_irqrestore(&cmd_mgr->lock, flags); |
343 | 364 | ||
344 | atomic_inc(&fcport->num_active_ios); | 365 | atomic_inc(&fcport->num_active_ios); |
@@ -349,8 +370,13 @@ struct qedf_ioreq *qedf_alloc_cmd(struct qedf_rport *fcport, u8 cmd_type) | |||
349 | io_req->cmd_mgr = cmd_mgr; | 370 | io_req->cmd_mgr = cmd_mgr; |
350 | io_req->fcport = fcport; | 371 | io_req->fcport = fcport; |
351 | 372 | ||
373 | /* Clear any stale sc_cmd back pointer */ | ||
374 | io_req->sc_cmd = NULL; | ||
375 | io_req->lun = -1; | ||
376 | |||
352 | /* Hold the io_req against deletion */ | 377 | /* Hold the io_req against deletion */ |
353 | kref_init(&io_req->refcount); | 378 | kref_init(&io_req->refcount); /* ID: 001 */ |
379 | atomic_set(&io_req->state, QEDFC_CMD_ST_IO_ACTIVE); | ||
354 | 380 | ||
355 | /* Bind io_bdt for this io_req */ | 381 | /* Bind io_bdt for this io_req */ |
356 | /* Have a static link between io_req and io_bdt_pool */ | 382 | /* Have a static link between io_req and io_bdt_pool */ |
@@ -412,6 +438,10 @@ void qedf_release_cmd(struct kref *ref) | |||
412 | container_of(ref, struct qedf_ioreq, refcount); | 438 | container_of(ref, struct qedf_ioreq, refcount); |
413 | struct qedf_cmd_mgr *cmd_mgr = io_req->cmd_mgr; | 439 | struct qedf_cmd_mgr *cmd_mgr = io_req->cmd_mgr; |
414 | struct qedf_rport *fcport = io_req->fcport; | 440 | struct qedf_rport *fcport = io_req->fcport; |
441 | unsigned long flags; | ||
442 | |||
443 | if (io_req->cmd_type == QEDF_SCSI_CMD) | ||
444 | WARN_ON(io_req->sc_cmd); | ||
415 | 445 | ||
416 | if (io_req->cmd_type == QEDF_ELS || | 446 | if (io_req->cmd_type == QEDF_ELS || |
417 | io_req->cmd_type == QEDF_TASK_MGMT_CMD) | 447 | io_req->cmd_type == QEDF_TASK_MGMT_CMD) |
@@ -419,36 +449,20 @@ void qedf_release_cmd(struct kref *ref) | |||
419 | 449 | ||
420 | atomic_inc(&cmd_mgr->free_list_cnt); | 450 | atomic_inc(&cmd_mgr->free_list_cnt); |
421 | atomic_dec(&fcport->num_active_ios); | 451 | atomic_dec(&fcport->num_active_ios); |
452 | atomic_set(&io_req->state, QEDF_CMD_ST_INACTIVE); | ||
422 | if (atomic_read(&fcport->num_active_ios) < 0) | 453 | if (atomic_read(&fcport->num_active_ios) < 0) |
423 | QEDF_WARN(&(fcport->qedf->dbg_ctx), "active_ios < 0.\n"); | 454 | QEDF_WARN(&(fcport->qedf->dbg_ctx), "active_ios < 0.\n"); |
424 | 455 | ||
425 | /* Increment task retry identifier now that the request is released */ | 456 | /* Increment task retry identifier now that the request is released */ |
426 | io_req->task_retry_identifier++; | 457 | io_req->task_retry_identifier++; |
458 | io_req->fcport = NULL; | ||
427 | 459 | ||
428 | clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags); | 460 | clear_bit(QEDF_CMD_DIRTY, &io_req->flags); |
429 | } | 461 | io_req->cpu = 0; |
430 | 462 | spin_lock_irqsave(&cmd_mgr->lock, flags); | |
431 | static int qedf_split_bd(struct qedf_ioreq *io_req, u64 addr, int sg_len, | 463 | io_req->fcport = NULL; |
432 | int bd_index) | 464 | io_req->alloc = 0; |
433 | { | 465 | spin_unlock_irqrestore(&cmd_mgr->lock, flags); |
434 | struct scsi_sge *bd = io_req->bd_tbl->bd_tbl; | ||
435 | int frag_size, sg_frags; | ||
436 | |||
437 | sg_frags = 0; | ||
438 | while (sg_len) { | ||
439 | if (sg_len > QEDF_BD_SPLIT_SZ) | ||
440 | frag_size = QEDF_BD_SPLIT_SZ; | ||
441 | else | ||
442 | frag_size = sg_len; | ||
443 | bd[bd_index + sg_frags].sge_addr.lo = U64_LO(addr); | ||
444 | bd[bd_index + sg_frags].sge_addr.hi = U64_HI(addr); | ||
445 | bd[bd_index + sg_frags].sge_len = (uint16_t)frag_size; | ||
446 | |||
447 | addr += (u64)frag_size; | ||
448 | sg_frags++; | ||
449 | sg_len -= frag_size; | ||
450 | } | ||
451 | return sg_frags; | ||
452 | } | 466 | } |
453 | 467 | ||
454 | static int qedf_map_sg(struct qedf_ioreq *io_req) | 468 | static int qedf_map_sg(struct qedf_ioreq *io_req) |
@@ -462,75 +476,45 @@ static int qedf_map_sg(struct qedf_ioreq *io_req) | |||
462 | int byte_count = 0; | 476 | int byte_count = 0; |
463 | int sg_count = 0; | 477 | int sg_count = 0; |
464 | int bd_count = 0; | 478 | int bd_count = 0; |
465 | int sg_frags; | 479 | u32 sg_len; |
466 | unsigned int sg_len; | ||
467 | u64 addr, end_addr; | 480 | u64 addr, end_addr; |
468 | int i; | 481 | int i = 0; |
469 | 482 | ||
470 | sg_count = dma_map_sg(&qedf->pdev->dev, scsi_sglist(sc), | 483 | sg_count = dma_map_sg(&qedf->pdev->dev, scsi_sglist(sc), |
471 | scsi_sg_count(sc), sc->sc_data_direction); | 484 | scsi_sg_count(sc), sc->sc_data_direction); |
472 | |||
473 | sg = scsi_sglist(sc); | 485 | sg = scsi_sglist(sc); |
474 | 486 | ||
475 | /* | 487 | io_req->sge_type = QEDF_IOREQ_UNKNOWN_SGE; |
476 | * New condition to send single SGE as cached-SGL with length less | ||
477 | * than 64k. | ||
478 | */ | ||
479 | if ((sg_count == 1) && (sg_dma_len(sg) <= | ||
480 | QEDF_MAX_SGLEN_FOR_CACHESGL)) { | ||
481 | sg_len = sg_dma_len(sg); | ||
482 | addr = (u64)sg_dma_address(sg); | ||
483 | |||
484 | bd[bd_count].sge_addr.lo = (addr & 0xffffffff); | ||
485 | bd[bd_count].sge_addr.hi = (addr >> 32); | ||
486 | bd[bd_count].sge_len = (u16)sg_len; | ||
487 | 488 | ||
488 | return ++bd_count; | 489 | if (sg_count <= 8 || io_req->io_req_flags == QEDF_READ) |
489 | } | 490 | io_req->sge_type = QEDF_IOREQ_FAST_SGE; |
490 | 491 | ||
491 | scsi_for_each_sg(sc, sg, sg_count, i) { | 492 | scsi_for_each_sg(sc, sg, sg_count, i) { |
492 | sg_len = sg_dma_len(sg); | 493 | sg_len = (u32)sg_dma_len(sg); |
493 | addr = (u64)sg_dma_address(sg); | 494 | addr = (u64)sg_dma_address(sg); |
494 | end_addr = (u64)(addr + sg_len); | 495 | end_addr = (u64)(addr + sg_len); |
495 | 496 | ||
496 | /* | 497 | /* |
497 | * First s/g element in the list so check if the end_addr | ||
498 | * is paged aligned. Also check to make sure the length is | ||
499 | * at least page size. | ||
500 | */ | ||
501 | if ((i == 0) && (sg_count > 1) && | ||
502 | ((end_addr % QEDF_PAGE_SIZE) || | ||
503 | sg_len < QEDF_PAGE_SIZE)) | ||
504 | io_req->use_slowpath = true; | ||
505 | /* | ||
506 | * Last s/g element so check if the start address is paged | ||
507 | * aligned. | ||
508 | */ | ||
509 | else if ((i == (sg_count - 1)) && (sg_count > 1) && | ||
510 | (addr % QEDF_PAGE_SIZE)) | ||
511 | io_req->use_slowpath = true; | ||
512 | /* | ||
513 | * Intermediate s/g element so check if start and end address | 498 | * Intermediate s/g element so check if start and end address |
514 | * is page aligned. | 499 | * is page aligned. Only required for writes and only if the |
500 | * number of scatter/gather elements is 8 or more. | ||
515 | */ | 501 | */ |
516 | else if ((i != 0) && (i != (sg_count - 1)) && | 502 | if (io_req->sge_type == QEDF_IOREQ_UNKNOWN_SGE && (i) && |
517 | ((addr % QEDF_PAGE_SIZE) || (end_addr % QEDF_PAGE_SIZE))) | 503 | (i != (sg_count - 1)) && sg_len < QEDF_PAGE_SIZE) |
518 | io_req->use_slowpath = true; | 504 | io_req->sge_type = QEDF_IOREQ_SLOW_SGE; |
519 | 505 | ||
520 | if (sg_len > QEDF_MAX_BD_LEN) { | 506 | bd[bd_count].sge_addr.lo = cpu_to_le32(U64_LO(addr)); |
521 | sg_frags = qedf_split_bd(io_req, addr, sg_len, | 507 | bd[bd_count].sge_addr.hi = cpu_to_le32(U64_HI(addr)); |
522 | bd_count); | 508 | bd[bd_count].sge_len = cpu_to_le32(sg_len); |
523 | } else { | ||
524 | sg_frags = 1; | ||
525 | bd[bd_count].sge_addr.lo = U64_LO(addr); | ||
526 | bd[bd_count].sge_addr.hi = U64_HI(addr); | ||
527 | bd[bd_count].sge_len = (uint16_t)sg_len; | ||
528 | } | ||
529 | 509 | ||
530 | bd_count += sg_frags; | 510 | bd_count++; |
531 | byte_count += sg_len; | 511 | byte_count += sg_len; |
532 | } | 512 | } |
533 | 513 | ||
514 | /* To catch a case where FAST and SLOW nothing is set, set FAST */ | ||
515 | if (io_req->sge_type == QEDF_IOREQ_UNKNOWN_SGE) | ||
516 | io_req->sge_type = QEDF_IOREQ_FAST_SGE; | ||
517 | |||
534 | if (byte_count != scsi_bufflen(sc)) | 518 | if (byte_count != scsi_bufflen(sc)) |
535 | QEDF_ERR(&(qedf->dbg_ctx), "byte_count = %d != " | 519 | QEDF_ERR(&(qedf->dbg_ctx), "byte_count = %d != " |
536 | "scsi_bufflen = %d, task_id = 0x%x.\n", byte_count, | 520 | "scsi_bufflen = %d, task_id = 0x%x.\n", byte_count, |
@@ -655,8 +639,10 @@ static void qedf_init_task(struct qedf_rport *fcport, struct fc_lport *lport, | |||
655 | io_req->sgl_task_params->num_sges = bd_count; | 639 | io_req->sgl_task_params->num_sges = bd_count; |
656 | io_req->sgl_task_params->total_buffer_size = | 640 | io_req->sgl_task_params->total_buffer_size = |
657 | scsi_bufflen(io_req->sc_cmd); | 641 | scsi_bufflen(io_req->sc_cmd); |
658 | io_req->sgl_task_params->small_mid_sge = | 642 | if (io_req->sge_type == QEDF_IOREQ_SLOW_SGE) |
659 | io_req->use_slowpath; | 643 | io_req->sgl_task_params->small_mid_sge = 1; |
644 | else | ||
645 | io_req->sgl_task_params->small_mid_sge = 0; | ||
660 | } | 646 | } |
661 | 647 | ||
662 | /* Fill in physical address of sense buffer */ | 648 | /* Fill in physical address of sense buffer */ |
@@ -679,16 +665,10 @@ static void qedf_init_task(struct qedf_rport *fcport, struct fc_lport *lport, | |||
679 | io_req->task_retry_identifier, fcp_cmnd); | 665 | io_req->task_retry_identifier, fcp_cmnd); |
680 | 666 | ||
681 | /* Increment SGL type counters */ | 667 | /* Increment SGL type counters */ |
682 | if (bd_count == 1) { | 668 | if (io_req->sge_type == QEDF_IOREQ_SLOW_SGE) |
683 | qedf->single_sge_ios++; | ||
684 | io_req->sge_type = QEDF_IOREQ_SINGLE_SGE; | ||
685 | } else if (io_req->use_slowpath) { | ||
686 | qedf->slow_sge_ios++; | 669 | qedf->slow_sge_ios++; |
687 | io_req->sge_type = QEDF_IOREQ_SLOW_SGE; | 670 | else |
688 | } else { | ||
689 | qedf->fast_sge_ios++; | 671 | qedf->fast_sge_ios++; |
690 | io_req->sge_type = QEDF_IOREQ_FAST_SGE; | ||
691 | } | ||
692 | } | 672 | } |
693 | 673 | ||
694 | void qedf_init_mp_task(struct qedf_ioreq *io_req, | 674 | void qedf_init_mp_task(struct qedf_ioreq *io_req, |
@@ -770,9 +750,6 @@ void qedf_init_mp_task(struct qedf_ioreq *io_req, | |||
770 | &task_fc_hdr, | 750 | &task_fc_hdr, |
771 | &tx_sgl_task_params, | 751 | &tx_sgl_task_params, |
772 | &rx_sgl_task_params, 0); | 752 | &rx_sgl_task_params, 0); |
773 | |||
774 | /* Midpath requests always consume 1 SGE */ | ||
775 | qedf->single_sge_ios++; | ||
776 | } | 753 | } |
777 | 754 | ||
778 | /* Presumed that fcport->rport_lock is held */ | 755 | /* Presumed that fcport->rport_lock is held */ |
@@ -804,8 +781,17 @@ void qedf_ring_doorbell(struct qedf_rport *fcport) | |||
804 | FCOE_DB_DATA_AGG_VAL_SEL_SHIFT; | 781 | FCOE_DB_DATA_AGG_VAL_SEL_SHIFT; |
805 | 782 | ||
806 | dbell.sq_prod = fcport->fw_sq_prod_idx; | 783 | dbell.sq_prod = fcport->fw_sq_prod_idx; |
784 | /* wmb makes sure that the BDs data is updated before updating the | ||
785 | * producer, otherwise FW may read old data from the BDs. | ||
786 | */ | ||
787 | wmb(); | ||
788 | barrier(); | ||
807 | writel(*(u32 *)&dbell, fcport->p_doorbell); | 789 | writel(*(u32 *)&dbell, fcport->p_doorbell); |
808 | /* Make sure SQ index is updated so f/w prcesses requests in order */ | 790 | /* |
791 | * Fence required to flush the write combined buffer, since another | ||
792 | * CPU may write to the same doorbell address and data may be lost | ||
793 | * due to relaxed order nature of write combined bar. | ||
794 | */ | ||
809 | wmb(); | 795 | wmb(); |
810 | } | 796 | } |
811 | 797 | ||
@@ -871,7 +857,7 @@ int qedf_post_io_req(struct qedf_rport *fcport, struct qedf_ioreq *io_req) | |||
871 | /* Initialize rest of io_req fileds */ | 857 | /* Initialize rest of io_req fileds */ |
872 | io_req->data_xfer_len = scsi_bufflen(sc_cmd); | 858 | io_req->data_xfer_len = scsi_bufflen(sc_cmd); |
873 | sc_cmd->SCp.ptr = (char *)io_req; | 859 | sc_cmd->SCp.ptr = (char *)io_req; |
874 | io_req->use_slowpath = false; /* Assume fast SGL by default */ | 860 | io_req->sge_type = QEDF_IOREQ_FAST_SGE; /* Assume fast SGL by default */ |
875 | 861 | ||
876 | /* Record which cpu this request is associated with */ | 862 | /* Record which cpu this request is associated with */ |
877 | io_req->cpu = smp_processor_id(); | 863 | io_req->cpu = smp_processor_id(); |
@@ -894,15 +880,24 @@ int qedf_post_io_req(struct qedf_rport *fcport, struct qedf_ioreq *io_req) | |||
894 | /* Build buffer descriptor list for firmware from sg list */ | 880 | /* Build buffer descriptor list for firmware from sg list */ |
895 | if (qedf_build_bd_list_from_sg(io_req)) { | 881 | if (qedf_build_bd_list_from_sg(io_req)) { |
896 | QEDF_ERR(&(qedf->dbg_ctx), "BD list creation failed.\n"); | 882 | QEDF_ERR(&(qedf->dbg_ctx), "BD list creation failed.\n"); |
883 | /* Release cmd will release io_req, but sc_cmd is assigned */ | ||
884 | io_req->sc_cmd = NULL; | ||
897 | kref_put(&io_req->refcount, qedf_release_cmd); | 885 | kref_put(&io_req->refcount, qedf_release_cmd); |
898 | return -EAGAIN; | 886 | return -EAGAIN; |
899 | } | 887 | } |
900 | 888 | ||
901 | if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) { | 889 | if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags) || |
890 | test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) { | ||
902 | QEDF_ERR(&(qedf->dbg_ctx), "Session not offloaded yet.\n"); | 891 | QEDF_ERR(&(qedf->dbg_ctx), "Session not offloaded yet.\n"); |
892 | /* Release cmd will release io_req, but sc_cmd is assigned */ | ||
893 | io_req->sc_cmd = NULL; | ||
903 | kref_put(&io_req->refcount, qedf_release_cmd); | 894 | kref_put(&io_req->refcount, qedf_release_cmd); |
895 | return -EINVAL; | ||
904 | } | 896 | } |
905 | 897 | ||
898 | /* Record LUN number for later use if we neeed them */ | ||
899 | io_req->lun = (int)sc_cmd->device->lun; | ||
900 | |||
906 | /* Obtain free SQE */ | 901 | /* Obtain free SQE */ |
907 | sqe_idx = qedf_get_sqe_idx(fcport); | 902 | sqe_idx = qedf_get_sqe_idx(fcport); |
908 | sqe = &fcport->sq[sqe_idx]; | 903 | sqe = &fcport->sq[sqe_idx]; |
@@ -913,6 +908,8 @@ int qedf_post_io_req(struct qedf_rport *fcport, struct qedf_ioreq *io_req) | |||
913 | if (!task_ctx) { | 908 | if (!task_ctx) { |
914 | QEDF_WARN(&(qedf->dbg_ctx), "task_ctx is NULL, xid=%d.\n", | 909 | QEDF_WARN(&(qedf->dbg_ctx), "task_ctx is NULL, xid=%d.\n", |
915 | xid); | 910 | xid); |
911 | /* Release cmd will release io_req, but sc_cmd is assigned */ | ||
912 | io_req->sc_cmd = NULL; | ||
916 | kref_put(&io_req->refcount, qedf_release_cmd); | 913 | kref_put(&io_req->refcount, qedf_release_cmd); |
917 | return -EINVAL; | 914 | return -EINVAL; |
918 | } | 915 | } |
@@ -922,6 +919,9 @@ int qedf_post_io_req(struct qedf_rport *fcport, struct qedf_ioreq *io_req) | |||
922 | /* Ring doorbell */ | 919 | /* Ring doorbell */ |
923 | qedf_ring_doorbell(fcport); | 920 | qedf_ring_doorbell(fcport); |
924 | 921 | ||
922 | /* Set that command is with the firmware now */ | ||
923 | set_bit(QEDF_CMD_OUTSTANDING, &io_req->flags); | ||
924 | |||
925 | if (qedf_io_tracing && io_req->sc_cmd) | 925 | if (qedf_io_tracing && io_req->sc_cmd) |
926 | qedf_trace_io(fcport, io_req, QEDF_IO_TRACE_REQ); | 926 | qedf_trace_io(fcport, io_req, QEDF_IO_TRACE_REQ); |
927 | 927 | ||
@@ -940,7 +940,17 @@ qedf_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd) | |||
940 | int rc = 0; | 940 | int rc = 0; |
941 | int rval; | 941 | int rval; |
942 | unsigned long flags = 0; | 942 | unsigned long flags = 0; |
943 | 943 | int num_sgs = 0; | |
944 | |||
945 | num_sgs = scsi_sg_count(sc_cmd); | ||
946 | if (scsi_sg_count(sc_cmd) > QEDF_MAX_BDS_PER_CMD) { | ||
947 | QEDF_ERR(&qedf->dbg_ctx, | ||
948 | "Number of SG elements %d exceeds what hardware limitation of %d.\n", | ||
949 | num_sgs, QEDF_MAX_BDS_PER_CMD); | ||
950 | sc_cmd->result = DID_ERROR; | ||
951 | sc_cmd->scsi_done(sc_cmd); | ||
952 | return 0; | ||
953 | } | ||
944 | 954 | ||
945 | if (test_bit(QEDF_UNLOADING, &qedf->flags) || | 955 | if (test_bit(QEDF_UNLOADING, &qedf->flags) || |
946 | test_bit(QEDF_DBG_STOP_IO, &qedf->flags)) { | 956 | test_bit(QEDF_DBG_STOP_IO, &qedf->flags)) { |
@@ -980,7 +990,8 @@ qedf_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd) | |||
980 | /* rport and tgt are allocated together, so tgt should be non-NULL */ | 990 | /* rport and tgt are allocated together, so tgt should be non-NULL */ |
981 | fcport = (struct qedf_rport *)&rp[1]; | 991 | fcport = (struct qedf_rport *)&rp[1]; |
982 | 992 | ||
983 | if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) { | 993 | if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags) || |
994 | test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) { | ||
984 | /* | 995 | /* |
985 | * Session is not offloaded yet. Let SCSI-ml retry | 996 | * Session is not offloaded yet. Let SCSI-ml retry |
986 | * the command. | 997 | * the command. |
@@ -988,12 +999,16 @@ qedf_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd) | |||
988 | rc = SCSI_MLQUEUE_TARGET_BUSY; | 999 | rc = SCSI_MLQUEUE_TARGET_BUSY; |
989 | goto exit_qcmd; | 1000 | goto exit_qcmd; |
990 | } | 1001 | } |
1002 | |||
1003 | atomic_inc(&fcport->ios_to_queue); | ||
1004 | |||
991 | if (fcport->retry_delay_timestamp) { | 1005 | if (fcport->retry_delay_timestamp) { |
992 | if (time_after(jiffies, fcport->retry_delay_timestamp)) { | 1006 | if (time_after(jiffies, fcport->retry_delay_timestamp)) { |
993 | fcport->retry_delay_timestamp = 0; | 1007 | fcport->retry_delay_timestamp = 0; |
994 | } else { | 1008 | } else { |
995 | /* If retry_delay timer is active, flow off the ML */ | 1009 | /* If retry_delay timer is active, flow off the ML */ |
996 | rc = SCSI_MLQUEUE_TARGET_BUSY; | 1010 | rc = SCSI_MLQUEUE_TARGET_BUSY; |
1011 | atomic_dec(&fcport->ios_to_queue); | ||
997 | goto exit_qcmd; | 1012 | goto exit_qcmd; |
998 | } | 1013 | } |
999 | } | 1014 | } |
@@ -1001,6 +1016,7 @@ qedf_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd) | |||
1001 | io_req = qedf_alloc_cmd(fcport, QEDF_SCSI_CMD); | 1016 | io_req = qedf_alloc_cmd(fcport, QEDF_SCSI_CMD); |
1002 | if (!io_req) { | 1017 | if (!io_req) { |
1003 | rc = SCSI_MLQUEUE_HOST_BUSY; | 1018 | rc = SCSI_MLQUEUE_HOST_BUSY; |
1019 | atomic_dec(&fcport->ios_to_queue); | ||
1004 | goto exit_qcmd; | 1020 | goto exit_qcmd; |
1005 | } | 1021 | } |
1006 | 1022 | ||
@@ -1015,6 +1031,7 @@ qedf_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd) | |||
1015 | rc = SCSI_MLQUEUE_HOST_BUSY; | 1031 | rc = SCSI_MLQUEUE_HOST_BUSY; |
1016 | } | 1032 | } |
1017 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 1033 | spin_unlock_irqrestore(&fcport->rport_lock, flags); |
1034 | atomic_dec(&fcport->ios_to_queue); | ||
1018 | 1035 | ||
1019 | exit_qcmd: | 1036 | exit_qcmd: |
1020 | return rc; | 1037 | return rc; |
@@ -1091,7 +1108,7 @@ static void qedf_unmap_sg_list(struct qedf_ctx *qedf, struct qedf_ioreq *io_req) | |||
1091 | void qedf_scsi_completion(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, | 1108 | void qedf_scsi_completion(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, |
1092 | struct qedf_ioreq *io_req) | 1109 | struct qedf_ioreq *io_req) |
1093 | { | 1110 | { |
1094 | u16 xid, rval; | 1111 | u16 xid; |
1095 | struct e4_fcoe_task_context *task_ctx; | 1112 | struct e4_fcoe_task_context *task_ctx; |
1096 | struct scsi_cmnd *sc_cmd; | 1113 | struct scsi_cmnd *sc_cmd; |
1097 | struct fcoe_cqe_rsp_info *fcp_rsp; | 1114 | struct fcoe_cqe_rsp_info *fcp_rsp; |
@@ -1105,6 +1122,15 @@ void qedf_scsi_completion(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, | |||
1105 | if (!cqe) | 1122 | if (!cqe) |
1106 | return; | 1123 | return; |
1107 | 1124 | ||
1125 | if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) || | ||
1126 | test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) || | ||
1127 | test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) { | ||
1128 | QEDF_ERR(&qedf->dbg_ctx, | ||
1129 | "io_req xid=0x%x already in cleanup or abort processing or already completed.\n", | ||
1130 | io_req->xid); | ||
1131 | return; | ||
1132 | } | ||
1133 | |||
1108 | xid = io_req->xid; | 1134 | xid = io_req->xid; |
1109 | task_ctx = qedf_get_task_mem(&qedf->tasks, xid); | 1135 | task_ctx = qedf_get_task_mem(&qedf->tasks, xid); |
1110 | sc_cmd = io_req->sc_cmd; | 1136 | sc_cmd = io_req->sc_cmd; |
@@ -1121,6 +1147,12 @@ void qedf_scsi_completion(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, | |||
1121 | return; | 1147 | return; |
1122 | } | 1148 | } |
1123 | 1149 | ||
1150 | if (!sc_cmd->device) { | ||
1151 | QEDF_ERR(&qedf->dbg_ctx, | ||
1152 | "Device for sc_cmd %p is NULL.\n", sc_cmd); | ||
1153 | return; | ||
1154 | } | ||
1155 | |||
1124 | if (!sc_cmd->request) { | 1156 | if (!sc_cmd->request) { |
1125 | QEDF_WARN(&(qedf->dbg_ctx), "sc_cmd->request is NULL, " | 1157 | QEDF_WARN(&(qedf->dbg_ctx), "sc_cmd->request is NULL, " |
1126 | "sc_cmd=%p.\n", sc_cmd); | 1158 | "sc_cmd=%p.\n", sc_cmd); |
@@ -1135,6 +1167,19 @@ void qedf_scsi_completion(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, | |||
1135 | 1167 | ||
1136 | fcport = io_req->fcport; | 1168 | fcport = io_req->fcport; |
1137 | 1169 | ||
1170 | /* | ||
1171 | * When flush is active, let the cmds be completed from the cleanup | ||
1172 | * context | ||
1173 | */ | ||
1174 | if (test_bit(QEDF_RPORT_IN_TARGET_RESET, &fcport->flags) || | ||
1175 | (test_bit(QEDF_RPORT_IN_LUN_RESET, &fcport->flags) && | ||
1176 | sc_cmd->device->lun == (u64)fcport->lun_reset_lun)) { | ||
1177 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, | ||
1178 | "Dropping good completion xid=0x%x as fcport is flushing", | ||
1179 | io_req->xid); | ||
1180 | return; | ||
1181 | } | ||
1182 | |||
1138 | qedf_parse_fcp_rsp(io_req, fcp_rsp); | 1183 | qedf_parse_fcp_rsp(io_req, fcp_rsp); |
1139 | 1184 | ||
1140 | qedf_unmap_sg_list(qedf, io_req); | 1185 | qedf_unmap_sg_list(qedf, io_req); |
@@ -1152,25 +1197,18 @@ void qedf_scsi_completion(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, | |||
1152 | fw_residual_flag = GET_FIELD(cqe->cqe_info.rsp_info.fw_error_flags, | 1197 | fw_residual_flag = GET_FIELD(cqe->cqe_info.rsp_info.fw_error_flags, |
1153 | FCOE_CQE_RSP_INFO_FW_UNDERRUN); | 1198 | FCOE_CQE_RSP_INFO_FW_UNDERRUN); |
1154 | if (fw_residual_flag) { | 1199 | if (fw_residual_flag) { |
1155 | QEDF_ERR(&(qedf->dbg_ctx), | 1200 | QEDF_ERR(&qedf->dbg_ctx, |
1156 | "Firmware detected underrun: xid=0x%x fcp_rsp.flags=0x%02x " | 1201 | "Firmware detected underrun: xid=0x%x fcp_rsp.flags=0x%02x fcp_resid=%d fw_residual=0x%x lba=%02x%02x%02x%02x.\n", |
1157 | "fcp_resid=%d fw_residual=0x%x.\n", io_req->xid, | 1202 | io_req->xid, fcp_rsp->rsp_flags.flags, |
1158 | fcp_rsp->rsp_flags.flags, io_req->fcp_resid, | 1203 | io_req->fcp_resid, |
1159 | cqe->cqe_info.rsp_info.fw_residual); | 1204 | cqe->cqe_info.rsp_info.fw_residual, sc_cmd->cmnd[2], |
1205 | sc_cmd->cmnd[3], sc_cmd->cmnd[4], sc_cmd->cmnd[5]); | ||
1160 | 1206 | ||
1161 | if (io_req->cdb_status == 0) | 1207 | if (io_req->cdb_status == 0) |
1162 | sc_cmd->result = (DID_ERROR << 16) | io_req->cdb_status; | 1208 | sc_cmd->result = (DID_ERROR << 16) | io_req->cdb_status; |
1163 | else | 1209 | else |
1164 | sc_cmd->result = (DID_OK << 16) | io_req->cdb_status; | 1210 | sc_cmd->result = (DID_OK << 16) | io_req->cdb_status; |
1165 | 1211 | ||
1166 | /* Abort the command since we did not get all the data */ | ||
1167 | init_completion(&io_req->abts_done); | ||
1168 | rval = qedf_initiate_abts(io_req, true); | ||
1169 | if (rval) { | ||
1170 | QEDF_ERR(&(qedf->dbg_ctx), "Failed to queue ABTS.\n"); | ||
1171 | sc_cmd->result = (DID_ERROR << 16) | io_req->cdb_status; | ||
1172 | } | ||
1173 | |||
1174 | /* | 1212 | /* |
1175 | * Set resid to the whole buffer length so we won't try to resue | 1213 | * Set resid to the whole buffer length so we won't try to resue |
1176 | * any previously data. | 1214 | * any previously data. |
@@ -1242,6 +1280,12 @@ out: | |||
1242 | if (qedf_io_tracing) | 1280 | if (qedf_io_tracing) |
1243 | qedf_trace_io(fcport, io_req, QEDF_IO_TRACE_RSP); | 1281 | qedf_trace_io(fcport, io_req, QEDF_IO_TRACE_RSP); |
1244 | 1282 | ||
1283 | /* | ||
1284 | * We wait till the end of the function to clear the | ||
1285 | * outstanding bit in case we need to send an abort | ||
1286 | */ | ||
1287 | clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags); | ||
1288 | |||
1245 | io_req->sc_cmd = NULL; | 1289 | io_req->sc_cmd = NULL; |
1246 | sc_cmd->SCp.ptr = NULL; | 1290 | sc_cmd->SCp.ptr = NULL; |
1247 | sc_cmd->scsi_done(sc_cmd); | 1291 | sc_cmd->scsi_done(sc_cmd); |
@@ -1259,6 +1303,19 @@ void qedf_scsi_done(struct qedf_ctx *qedf, struct qedf_ioreq *io_req, | |||
1259 | if (!io_req) | 1303 | if (!io_req) |
1260 | return; | 1304 | return; |
1261 | 1305 | ||
1306 | if (test_and_set_bit(QEDF_CMD_ERR_SCSI_DONE, &io_req->flags)) { | ||
1307 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, | ||
1308 | "io_req:%p scsi_done handling already done\n", | ||
1309 | io_req); | ||
1310 | return; | ||
1311 | } | ||
1312 | |||
1313 | /* | ||
1314 | * We will be done with this command after this call so clear the | ||
1315 | * outstanding bit. | ||
1316 | */ | ||
1317 | clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags); | ||
1318 | |||
1262 | xid = io_req->xid; | 1319 | xid = io_req->xid; |
1263 | sc_cmd = io_req->sc_cmd; | 1320 | sc_cmd = io_req->sc_cmd; |
1264 | 1321 | ||
@@ -1267,12 +1324,50 @@ void qedf_scsi_done(struct qedf_ctx *qedf, struct qedf_ioreq *io_req, | |||
1267 | return; | 1324 | return; |
1268 | } | 1325 | } |
1269 | 1326 | ||
1327 | if (!virt_addr_valid(sc_cmd)) { | ||
1328 | QEDF_ERR(&qedf->dbg_ctx, "sc_cmd=%p is not valid.", sc_cmd); | ||
1329 | goto bad_scsi_ptr; | ||
1330 | } | ||
1331 | |||
1270 | if (!sc_cmd->SCp.ptr) { | 1332 | if (!sc_cmd->SCp.ptr) { |
1271 | QEDF_WARN(&(qedf->dbg_ctx), "SCp.ptr is NULL, returned in " | 1333 | QEDF_WARN(&(qedf->dbg_ctx), "SCp.ptr is NULL, returned in " |
1272 | "another context.\n"); | 1334 | "another context.\n"); |
1273 | return; | 1335 | return; |
1274 | } | 1336 | } |
1275 | 1337 | ||
1338 | if (!sc_cmd->device) { | ||
1339 | QEDF_ERR(&qedf->dbg_ctx, "Device for sc_cmd %p is NULL.\n", | ||
1340 | sc_cmd); | ||
1341 | goto bad_scsi_ptr; | ||
1342 | } | ||
1343 | |||
1344 | if (!virt_addr_valid(sc_cmd->device)) { | ||
1345 | QEDF_ERR(&qedf->dbg_ctx, | ||
1346 | "Device pointer for sc_cmd %p is bad.\n", sc_cmd); | ||
1347 | goto bad_scsi_ptr; | ||
1348 | } | ||
1349 | |||
1350 | if (!sc_cmd->sense_buffer) { | ||
1351 | QEDF_ERR(&qedf->dbg_ctx, | ||
1352 | "sc_cmd->sense_buffer for sc_cmd %p is NULL.\n", | ||
1353 | sc_cmd); | ||
1354 | goto bad_scsi_ptr; | ||
1355 | } | ||
1356 | |||
1357 | if (!virt_addr_valid(sc_cmd->sense_buffer)) { | ||
1358 | QEDF_ERR(&qedf->dbg_ctx, | ||
1359 | "sc_cmd->sense_buffer for sc_cmd %p is bad.\n", | ||
1360 | sc_cmd); | ||
1361 | goto bad_scsi_ptr; | ||
1362 | } | ||
1363 | |||
1364 | if (!sc_cmd->scsi_done) { | ||
1365 | QEDF_ERR(&qedf->dbg_ctx, | ||
1366 | "sc_cmd->scsi_done for sc_cmd %p is NULL.\n", | ||
1367 | sc_cmd); | ||
1368 | goto bad_scsi_ptr; | ||
1369 | } | ||
1370 | |||
1276 | qedf_unmap_sg_list(qedf, io_req); | 1371 | qedf_unmap_sg_list(qedf, io_req); |
1277 | 1372 | ||
1278 | sc_cmd->result = result << 16; | 1373 | sc_cmd->result = result << 16; |
@@ -1299,6 +1394,15 @@ void qedf_scsi_done(struct qedf_ctx *qedf, struct qedf_ioreq *io_req, | |||
1299 | sc_cmd->SCp.ptr = NULL; | 1394 | sc_cmd->SCp.ptr = NULL; |
1300 | sc_cmd->scsi_done(sc_cmd); | 1395 | sc_cmd->scsi_done(sc_cmd); |
1301 | kref_put(&io_req->refcount, qedf_release_cmd); | 1396 | kref_put(&io_req->refcount, qedf_release_cmd); |
1397 | return; | ||
1398 | |||
1399 | bad_scsi_ptr: | ||
1400 | /* | ||
1401 | * Clear the io_req->sc_cmd backpointer so we don't try to process | ||
1402 | * this again | ||
1403 | */ | ||
1404 | io_req->sc_cmd = NULL; | ||
1405 | kref_put(&io_req->refcount, qedf_release_cmd); /* ID: 001 */ | ||
1302 | } | 1406 | } |
1303 | 1407 | ||
1304 | /* | 1408 | /* |
@@ -1437,6 +1541,10 @@ void qedf_flush_active_ios(struct qedf_rport *fcport, int lun) | |||
1437 | struct qedf_ctx *qedf; | 1541 | struct qedf_ctx *qedf; |
1438 | struct qedf_cmd_mgr *cmd_mgr; | 1542 | struct qedf_cmd_mgr *cmd_mgr; |
1439 | int i, rc; | 1543 | int i, rc; |
1544 | unsigned long flags; | ||
1545 | int flush_cnt = 0; | ||
1546 | int wait_cnt = 100; | ||
1547 | int refcount = 0; | ||
1440 | 1548 | ||
1441 | if (!fcport) | 1549 | if (!fcport) |
1442 | return; | 1550 | return; |
@@ -1448,18 +1556,102 @@ void qedf_flush_active_ios(struct qedf_rport *fcport, int lun) | |||
1448 | } | 1556 | } |
1449 | 1557 | ||
1450 | qedf = fcport->qedf; | 1558 | qedf = fcport->qedf; |
1559 | |||
1560 | if (!qedf) { | ||
1561 | QEDF_ERR(NULL, "qedf is NULL.\n"); | ||
1562 | return; | ||
1563 | } | ||
1564 | |||
1565 | /* Only wait for all commands to be queued in the Upload context */ | ||
1566 | if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags) && | ||
1567 | (lun == -1)) { | ||
1568 | while (atomic_read(&fcport->ios_to_queue)) { | ||
1569 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, | ||
1570 | "Waiting for %d I/Os to be queued\n", | ||
1571 | atomic_read(&fcport->ios_to_queue)); | ||
1572 | if (wait_cnt == 0) { | ||
1573 | QEDF_ERR(NULL, | ||
1574 | "%d IOs request could not be queued\n", | ||
1575 | atomic_read(&fcport->ios_to_queue)); | ||
1576 | } | ||
1577 | msleep(20); | ||
1578 | wait_cnt--; | ||
1579 | } | ||
1580 | } | ||
1581 | |||
1451 | cmd_mgr = qedf->cmd_mgr; | 1582 | cmd_mgr = qedf->cmd_mgr; |
1452 | 1583 | ||
1453 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO, "Flush active i/o's.\n"); | 1584 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, |
1585 | "Flush active i/o's num=0x%x fcport=0x%p port_id=0x%06x scsi_id=%d.\n", | ||
1586 | atomic_read(&fcport->num_active_ios), fcport, | ||
1587 | fcport->rdata->ids.port_id, fcport->rport->scsi_target_id); | ||
1588 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, "Locking flush mutex.\n"); | ||
1589 | |||
1590 | mutex_lock(&qedf->flush_mutex); | ||
1591 | if (lun == -1) { | ||
1592 | set_bit(QEDF_RPORT_IN_TARGET_RESET, &fcport->flags); | ||
1593 | } else { | ||
1594 | set_bit(QEDF_RPORT_IN_LUN_RESET, &fcport->flags); | ||
1595 | fcport->lun_reset_lun = lun; | ||
1596 | } | ||
1454 | 1597 | ||
1455 | for (i = 0; i < FCOE_PARAMS_NUM_TASKS; i++) { | 1598 | for (i = 0; i < FCOE_PARAMS_NUM_TASKS; i++) { |
1456 | io_req = &cmd_mgr->cmds[i]; | 1599 | io_req = &cmd_mgr->cmds[i]; |
1457 | 1600 | ||
1458 | if (!io_req) | 1601 | if (!io_req) |
1459 | continue; | 1602 | continue; |
1603 | if (!io_req->fcport) | ||
1604 | continue; | ||
1605 | |||
1606 | spin_lock_irqsave(&cmd_mgr->lock, flags); | ||
1607 | |||
1608 | if (io_req->alloc) { | ||
1609 | if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags)) { | ||
1610 | if (io_req->cmd_type == QEDF_SCSI_CMD) | ||
1611 | QEDF_ERR(&qedf->dbg_ctx, | ||
1612 | "Allocated but not queued, xid=0x%x\n", | ||
1613 | io_req->xid); | ||
1614 | } | ||
1615 | spin_unlock_irqrestore(&cmd_mgr->lock, flags); | ||
1616 | } else { | ||
1617 | spin_unlock_irqrestore(&cmd_mgr->lock, flags); | ||
1618 | continue; | ||
1619 | } | ||
1620 | |||
1460 | if (io_req->fcport != fcport) | 1621 | if (io_req->fcport != fcport) |
1461 | continue; | 1622 | continue; |
1462 | if (io_req->cmd_type == QEDF_ELS) { | 1623 | |
1624 | /* In case of ABTS, CMD_OUTSTANDING is cleared on ABTS response, | ||
1625 | * but RRQ is still pending. | ||
1626 | * Workaround: Within qedf_send_rrq, we check if the fcport is | ||
1627 | * NULL, and we drop the ref on the io_req to clean it up. | ||
1628 | */ | ||
1629 | if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags)) { | ||
1630 | refcount = kref_read(&io_req->refcount); | ||
1631 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, | ||
1632 | "Not outstanding, xid=0x%x, cmd_type=%d refcount=%d.\n", | ||
1633 | io_req->xid, io_req->cmd_type, refcount); | ||
1634 | /* If RRQ work has been queue, try to cancel it and | ||
1635 | * free the io_req | ||
1636 | */ | ||
1637 | if (atomic_read(&io_req->state) == | ||
1638 | QEDFC_CMD_ST_RRQ_WAIT) { | ||
1639 | if (cancel_delayed_work_sync | ||
1640 | (&io_req->rrq_work)) { | ||
1641 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, | ||
1642 | "Putting reference for pending RRQ work xid=0x%x.\n", | ||
1643 | io_req->xid); | ||
1644 | /* ID: 003 */ | ||
1645 | kref_put(&io_req->refcount, | ||
1646 | qedf_release_cmd); | ||
1647 | } | ||
1648 | } | ||
1649 | continue; | ||
1650 | } | ||
1651 | |||
1652 | /* Only consider flushing ELS during target reset */ | ||
1653 | if (io_req->cmd_type == QEDF_ELS && | ||
1654 | lun == -1) { | ||
1463 | rc = kref_get_unless_zero(&io_req->refcount); | 1655 | rc = kref_get_unless_zero(&io_req->refcount); |
1464 | if (!rc) { | 1656 | if (!rc) { |
1465 | QEDF_ERR(&(qedf->dbg_ctx), | 1657 | QEDF_ERR(&(qedf->dbg_ctx), |
@@ -1467,6 +1659,7 @@ void qedf_flush_active_ios(struct qedf_rport *fcport, int lun) | |||
1467 | io_req, io_req->xid); | 1659 | io_req, io_req->xid); |
1468 | continue; | 1660 | continue; |
1469 | } | 1661 | } |
1662 | flush_cnt++; | ||
1470 | qedf_flush_els_req(qedf, io_req); | 1663 | qedf_flush_els_req(qedf, io_req); |
1471 | /* | 1664 | /* |
1472 | * Release the kref and go back to the top of the | 1665 | * Release the kref and go back to the top of the |
@@ -1476,6 +1669,7 @@ void qedf_flush_active_ios(struct qedf_rport *fcport, int lun) | |||
1476 | } | 1669 | } |
1477 | 1670 | ||
1478 | if (io_req->cmd_type == QEDF_ABTS) { | 1671 | if (io_req->cmd_type == QEDF_ABTS) { |
1672 | /* ID: 004 */ | ||
1479 | rc = kref_get_unless_zero(&io_req->refcount); | 1673 | rc = kref_get_unless_zero(&io_req->refcount); |
1480 | if (!rc) { | 1674 | if (!rc) { |
1481 | QEDF_ERR(&(qedf->dbg_ctx), | 1675 | QEDF_ERR(&(qedf->dbg_ctx), |
@@ -1483,28 +1677,50 @@ void qedf_flush_active_ios(struct qedf_rport *fcport, int lun) | |||
1483 | io_req, io_req->xid); | 1677 | io_req, io_req->xid); |
1484 | continue; | 1678 | continue; |
1485 | } | 1679 | } |
1680 | if (lun != -1 && io_req->lun != lun) | ||
1681 | goto free_cmd; | ||
1682 | |||
1486 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, | 1683 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, |
1487 | "Flushing abort xid=0x%x.\n", io_req->xid); | 1684 | "Flushing abort xid=0x%x.\n", io_req->xid); |
1488 | 1685 | ||
1489 | clear_bit(QEDF_CMD_IN_ABORT, &io_req->flags); | 1686 | if (cancel_delayed_work_sync(&io_req->rrq_work)) { |
1490 | 1687 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, | |
1491 | if (io_req->sc_cmd) { | 1688 | "Putting ref for cancelled RRQ work xid=0x%x.\n", |
1492 | if (io_req->return_scsi_cmd_on_abts) | 1689 | io_req->xid); |
1493 | qedf_scsi_done(qedf, io_req, DID_ERROR); | 1690 | kref_put(&io_req->refcount, qedf_release_cmd); |
1494 | } | 1691 | } |
1495 | 1692 | ||
1496 | /* Notify eh_abort handler that ABTS is complete */ | 1693 | if (cancel_delayed_work_sync(&io_req->timeout_work)) { |
1497 | complete(&io_req->abts_done); | 1694 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, |
1498 | kref_put(&io_req->refcount, qedf_release_cmd); | 1695 | "Putting ref for cancelled tmo work xid=0x%x.\n", |
1499 | 1696 | io_req->xid); | |
1697 | qedf_initiate_cleanup(io_req, true); | ||
1698 | /* Notify eh_abort handler that ABTS is | ||
1699 | * complete | ||
1700 | */ | ||
1701 | complete(&io_req->abts_done); | ||
1702 | clear_bit(QEDF_CMD_IN_ABORT, &io_req->flags); | ||
1703 | /* ID: 002 */ | ||
1704 | kref_put(&io_req->refcount, qedf_release_cmd); | ||
1705 | } | ||
1706 | flush_cnt++; | ||
1500 | goto free_cmd; | 1707 | goto free_cmd; |
1501 | } | 1708 | } |
1502 | 1709 | ||
1503 | if (!io_req->sc_cmd) | 1710 | if (!io_req->sc_cmd) |
1504 | continue; | 1711 | continue; |
1505 | if (lun > 0) { | 1712 | if (!io_req->sc_cmd->device) { |
1506 | if (io_req->sc_cmd->device->lun != | 1713 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, |
1507 | (u64)lun) | 1714 | "Device backpointer NULL for sc_cmd=%p.\n", |
1715 | io_req->sc_cmd); | ||
1716 | /* Put reference for non-existent scsi_cmnd */ | ||
1717 | io_req->sc_cmd = NULL; | ||
1718 | qedf_initiate_cleanup(io_req, false); | ||
1719 | kref_put(&io_req->refcount, qedf_release_cmd); | ||
1720 | continue; | ||
1721 | } | ||
1722 | if (lun > -1) { | ||
1723 | if (io_req->lun != lun) | ||
1508 | continue; | 1724 | continue; |
1509 | } | 1725 | } |
1510 | 1726 | ||
@@ -1518,15 +1734,65 @@ void qedf_flush_active_ios(struct qedf_rport *fcport, int lun) | |||
1518 | "io_req=0x%p xid=0x%x\n", io_req, io_req->xid); | 1734 | "io_req=0x%p xid=0x%x\n", io_req, io_req->xid); |
1519 | continue; | 1735 | continue; |
1520 | } | 1736 | } |
1737 | |||
1521 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO, | 1738 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO, |
1522 | "Cleanup xid=0x%x.\n", io_req->xid); | 1739 | "Cleanup xid=0x%x.\n", io_req->xid); |
1740 | flush_cnt++; | ||
1523 | 1741 | ||
1524 | /* Cleanup task and return I/O mid-layer */ | 1742 | /* Cleanup task and return I/O mid-layer */ |
1525 | qedf_initiate_cleanup(io_req, true); | 1743 | qedf_initiate_cleanup(io_req, true); |
1526 | 1744 | ||
1527 | free_cmd: | 1745 | free_cmd: |
1528 | kref_put(&io_req->refcount, qedf_release_cmd); | 1746 | kref_put(&io_req->refcount, qedf_release_cmd); /* ID: 004 */ |
1747 | } | ||
1748 | |||
1749 | wait_cnt = 60; | ||
1750 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, | ||
1751 | "Flushed 0x%x I/Os, active=0x%x.\n", | ||
1752 | flush_cnt, atomic_read(&fcport->num_active_ios)); | ||
1753 | /* Only wait for all commands to complete in the Upload context */ | ||
1754 | if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags) && | ||
1755 | (lun == -1)) { | ||
1756 | while (atomic_read(&fcport->num_active_ios)) { | ||
1757 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, | ||
1758 | "Flushed 0x%x I/Os, active=0x%x cnt=%d.\n", | ||
1759 | flush_cnt, | ||
1760 | atomic_read(&fcport->num_active_ios), | ||
1761 | wait_cnt); | ||
1762 | if (wait_cnt == 0) { | ||
1763 | QEDF_ERR(&qedf->dbg_ctx, | ||
1764 | "Flushed %d I/Os, active=%d.\n", | ||
1765 | flush_cnt, | ||
1766 | atomic_read(&fcport->num_active_ios)); | ||
1767 | for (i = 0; i < FCOE_PARAMS_NUM_TASKS; i++) { | ||
1768 | io_req = &cmd_mgr->cmds[i]; | ||
1769 | if (io_req->fcport && | ||
1770 | io_req->fcport == fcport) { | ||
1771 | refcount = | ||
1772 | kref_read(&io_req->refcount); | ||
1773 | set_bit(QEDF_CMD_DIRTY, | ||
1774 | &io_req->flags); | ||
1775 | QEDF_ERR(&qedf->dbg_ctx, | ||
1776 | "Outstanding io_req =%p xid=0x%x flags=0x%lx, sc_cmd=%p refcount=%d cmd_type=%d.\n", | ||
1777 | io_req, io_req->xid, | ||
1778 | io_req->flags, | ||
1779 | io_req->sc_cmd, | ||
1780 | refcount, | ||
1781 | io_req->cmd_type); | ||
1782 | } | ||
1783 | } | ||
1784 | WARN_ON(1); | ||
1785 | break; | ||
1786 | } | ||
1787 | msleep(500); | ||
1788 | wait_cnt--; | ||
1789 | } | ||
1529 | } | 1790 | } |
1791 | |||
1792 | clear_bit(QEDF_RPORT_IN_LUN_RESET, &fcport->flags); | ||
1793 | clear_bit(QEDF_RPORT_IN_TARGET_RESET, &fcport->flags); | ||
1794 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, "Unlocking flush mutex.\n"); | ||
1795 | mutex_unlock(&qedf->flush_mutex); | ||
1530 | } | 1796 | } |
1531 | 1797 | ||
1532 | /* | 1798 | /* |
@@ -1545,52 +1811,60 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) | |||
1545 | unsigned long flags; | 1811 | unsigned long flags; |
1546 | struct fcoe_wqe *sqe; | 1812 | struct fcoe_wqe *sqe; |
1547 | u16 sqe_idx; | 1813 | u16 sqe_idx; |
1814 | int refcount = 0; | ||
1548 | 1815 | ||
1549 | /* Sanity check qedf_rport before dereferencing any pointers */ | 1816 | /* Sanity check qedf_rport before dereferencing any pointers */ |
1550 | if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) { | 1817 | if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) { |
1551 | QEDF_ERR(NULL, "tgt not offloaded\n"); | 1818 | QEDF_ERR(NULL, "tgt not offloaded\n"); |
1552 | rc = 1; | 1819 | rc = 1; |
1553 | goto abts_err; | 1820 | goto out; |
1554 | } | 1821 | } |
1555 | 1822 | ||
1823 | qedf = fcport->qedf; | ||
1556 | rdata = fcport->rdata; | 1824 | rdata = fcport->rdata; |
1825 | |||
1826 | if (!rdata || !kref_get_unless_zero(&rdata->kref)) { | ||
1827 | QEDF_ERR(&qedf->dbg_ctx, "stale rport\n"); | ||
1828 | rc = 1; | ||
1829 | goto out; | ||
1830 | } | ||
1831 | |||
1557 | r_a_tov = rdata->r_a_tov; | 1832 | r_a_tov = rdata->r_a_tov; |
1558 | qedf = fcport->qedf; | ||
1559 | lport = qedf->lport; | 1833 | lport = qedf->lport; |
1560 | 1834 | ||
1561 | if (lport->state != LPORT_ST_READY || !(lport->link_up)) { | 1835 | if (lport->state != LPORT_ST_READY || !(lport->link_up)) { |
1562 | QEDF_ERR(&(qedf->dbg_ctx), "link is not ready\n"); | 1836 | QEDF_ERR(&(qedf->dbg_ctx), "link is not ready\n"); |
1563 | rc = 1; | 1837 | rc = 1; |
1564 | goto abts_err; | 1838 | goto drop_rdata_kref; |
1565 | } | 1839 | } |
1566 | 1840 | ||
1567 | if (atomic_read(&qedf->link_down_tmo_valid) > 0) { | 1841 | if (atomic_read(&qedf->link_down_tmo_valid) > 0) { |
1568 | QEDF_ERR(&(qedf->dbg_ctx), "link_down_tmo active.\n"); | 1842 | QEDF_ERR(&(qedf->dbg_ctx), "link_down_tmo active.\n"); |
1569 | rc = 1; | 1843 | rc = 1; |
1570 | goto abts_err; | 1844 | goto drop_rdata_kref; |
1571 | } | 1845 | } |
1572 | 1846 | ||
1573 | /* Ensure room on SQ */ | 1847 | /* Ensure room on SQ */ |
1574 | if (!atomic_read(&fcport->free_sqes)) { | 1848 | if (!atomic_read(&fcport->free_sqes)) { |
1575 | QEDF_ERR(&(qedf->dbg_ctx), "No SQ entries available\n"); | 1849 | QEDF_ERR(&(qedf->dbg_ctx), "No SQ entries available\n"); |
1576 | rc = 1; | 1850 | rc = 1; |
1577 | goto abts_err; | 1851 | goto drop_rdata_kref; |
1578 | } | 1852 | } |
1579 | 1853 | ||
1580 | if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) { | 1854 | if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) { |
1581 | QEDF_ERR(&qedf->dbg_ctx, "fcport is uploading.\n"); | 1855 | QEDF_ERR(&qedf->dbg_ctx, "fcport is uploading.\n"); |
1582 | rc = 1; | 1856 | rc = 1; |
1583 | goto out; | 1857 | goto drop_rdata_kref; |
1584 | } | 1858 | } |
1585 | 1859 | ||
1586 | if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) || | 1860 | if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) || |
1587 | test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) || | 1861 | test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) || |
1588 | test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) { | 1862 | test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) { |
1589 | QEDF_ERR(&(qedf->dbg_ctx), "io_req xid=0x%x already in " | 1863 | QEDF_ERR(&qedf->dbg_ctx, |
1590 | "cleanup or abort processing or already " | 1864 | "io_req xid=0x%x sc_cmd=%p already in cleanup or abort processing or already completed.\n", |
1591 | "completed.\n", io_req->xid); | 1865 | io_req->xid, io_req->sc_cmd); |
1592 | rc = 1; | 1866 | rc = 1; |
1593 | goto out; | 1867 | goto drop_rdata_kref; |
1594 | } | 1868 | } |
1595 | 1869 | ||
1596 | kref_get(&io_req->refcount); | 1870 | kref_get(&io_req->refcount); |
@@ -1599,18 +1873,17 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) | |||
1599 | qedf->control_requests++; | 1873 | qedf->control_requests++; |
1600 | qedf->packet_aborts++; | 1874 | qedf->packet_aborts++; |
1601 | 1875 | ||
1602 | /* Set the return CPU to be the same as the request one */ | ||
1603 | io_req->cpu = smp_processor_id(); | ||
1604 | |||
1605 | /* Set the command type to abort */ | 1876 | /* Set the command type to abort */ |
1606 | io_req->cmd_type = QEDF_ABTS; | 1877 | io_req->cmd_type = QEDF_ABTS; |
1607 | io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; | 1878 | io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; |
1608 | 1879 | ||
1609 | set_bit(QEDF_CMD_IN_ABORT, &io_req->flags); | 1880 | set_bit(QEDF_CMD_IN_ABORT, &io_req->flags); |
1610 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_SCSI_TM, "ABTS io_req xid = " | 1881 | refcount = kref_read(&io_req->refcount); |
1611 | "0x%x\n", xid); | 1882 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_SCSI_TM, |
1883 | "ABTS io_req xid = 0x%x refcount=%d\n", | ||
1884 | xid, refcount); | ||
1612 | 1885 | ||
1613 | qedf_cmd_timer_set(qedf, io_req, QEDF_ABORT_TIMEOUT * HZ); | 1886 | qedf_cmd_timer_set(qedf, io_req, QEDF_ABORT_TIMEOUT); |
1614 | 1887 | ||
1615 | spin_lock_irqsave(&fcport->rport_lock, flags); | 1888 | spin_lock_irqsave(&fcport->rport_lock, flags); |
1616 | 1889 | ||
@@ -1624,13 +1897,8 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) | |||
1624 | 1897 | ||
1625 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 1898 | spin_unlock_irqrestore(&fcport->rport_lock, flags); |
1626 | 1899 | ||
1627 | return rc; | 1900 | drop_rdata_kref: |
1628 | abts_err: | 1901 | kref_put(&rdata->kref, fc_rport_destroy); |
1629 | /* | ||
1630 | * If the ABTS task fails to queue then we need to cleanup the | ||
1631 | * task at the firmware. | ||
1632 | */ | ||
1633 | qedf_initiate_cleanup(io_req, return_scsi_cmd_on_abts); | ||
1634 | out: | 1902 | out: |
1635 | return rc; | 1903 | return rc; |
1636 | } | 1904 | } |
@@ -1640,27 +1908,62 @@ void qedf_process_abts_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, | |||
1640 | { | 1908 | { |
1641 | uint32_t r_ctl; | 1909 | uint32_t r_ctl; |
1642 | uint16_t xid; | 1910 | uint16_t xid; |
1911 | int rc; | ||
1912 | struct qedf_rport *fcport = io_req->fcport; | ||
1643 | 1913 | ||
1644 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_SCSI_TM, "Entered with xid = " | 1914 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_SCSI_TM, "Entered with xid = " |
1645 | "0x%x cmd_type = %d\n", io_req->xid, io_req->cmd_type); | 1915 | "0x%x cmd_type = %d\n", io_req->xid, io_req->cmd_type); |
1646 | 1916 | ||
1647 | cancel_delayed_work(&io_req->timeout_work); | ||
1648 | |||
1649 | xid = io_req->xid; | 1917 | xid = io_req->xid; |
1650 | r_ctl = cqe->cqe_info.abts_info.r_ctl; | 1918 | r_ctl = cqe->cqe_info.abts_info.r_ctl; |
1651 | 1919 | ||
1920 | /* This was added at a point when we were scheduling abts_compl & | ||
1921 | * cleanup_compl on different CPUs and there was a possibility of | ||
1922 | * the io_req to be freed from the other context before we got here. | ||
1923 | */ | ||
1924 | if (!fcport) { | ||
1925 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, | ||
1926 | "Dropping ABTS completion xid=0x%x as fcport is NULL", | ||
1927 | io_req->xid); | ||
1928 | return; | ||
1929 | } | ||
1930 | |||
1931 | /* | ||
1932 | * When flush is active, let the cmds be completed from the cleanup | ||
1933 | * context | ||
1934 | */ | ||
1935 | if (test_bit(QEDF_RPORT_IN_TARGET_RESET, &fcport->flags) || | ||
1936 | test_bit(QEDF_RPORT_IN_LUN_RESET, &fcport->flags)) { | ||
1937 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, | ||
1938 | "Dropping ABTS completion xid=0x%x as fcport is flushing", | ||
1939 | io_req->xid); | ||
1940 | return; | ||
1941 | } | ||
1942 | |||
1943 | if (!cancel_delayed_work(&io_req->timeout_work)) { | ||
1944 | QEDF_ERR(&qedf->dbg_ctx, | ||
1945 | "Wasn't able to cancel abts timeout work.\n"); | ||
1946 | } | ||
1947 | |||
1652 | switch (r_ctl) { | 1948 | switch (r_ctl) { |
1653 | case FC_RCTL_BA_ACC: | 1949 | case FC_RCTL_BA_ACC: |
1654 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_SCSI_TM, | 1950 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_SCSI_TM, |
1655 | "ABTS response - ACC Send RRQ after R_A_TOV\n"); | 1951 | "ABTS response - ACC Send RRQ after R_A_TOV\n"); |
1656 | io_req->event = QEDF_IOREQ_EV_ABORT_SUCCESS; | 1952 | io_req->event = QEDF_IOREQ_EV_ABORT_SUCCESS; |
1953 | rc = kref_get_unless_zero(&io_req->refcount); /* ID: 003 */ | ||
1954 | if (!rc) { | ||
1955 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_SCSI_TM, | ||
1956 | "kref is already zero so ABTS was already completed or flushed xid=0x%x.\n", | ||
1957 | io_req->xid); | ||
1958 | return; | ||
1959 | } | ||
1657 | /* | 1960 | /* |
1658 | * Dont release this cmd yet. It will be relesed | 1961 | * Dont release this cmd yet. It will be relesed |
1659 | * after we get RRQ response | 1962 | * after we get RRQ response |
1660 | */ | 1963 | */ |
1661 | kref_get(&io_req->refcount); | ||
1662 | queue_delayed_work(qedf->dpc_wq, &io_req->rrq_work, | 1964 | queue_delayed_work(qedf->dpc_wq, &io_req->rrq_work, |
1663 | msecs_to_jiffies(qedf->lport->r_a_tov)); | 1965 | msecs_to_jiffies(qedf->lport->r_a_tov)); |
1966 | atomic_set(&io_req->state, QEDFC_CMD_ST_RRQ_WAIT); | ||
1664 | break; | 1967 | break; |
1665 | /* For error cases let the cleanup return the command */ | 1968 | /* For error cases let the cleanup return the command */ |
1666 | case FC_RCTL_BA_RJT: | 1969 | case FC_RCTL_BA_RJT: |
@@ -1802,6 +2105,7 @@ int qedf_initiate_cleanup(struct qedf_ioreq *io_req, | |||
1802 | unsigned long flags; | 2105 | unsigned long flags; |
1803 | struct fcoe_wqe *sqe; | 2106 | struct fcoe_wqe *sqe; |
1804 | u16 sqe_idx; | 2107 | u16 sqe_idx; |
2108 | int refcount = 0; | ||
1805 | 2109 | ||
1806 | fcport = io_req->fcport; | 2110 | fcport = io_req->fcport; |
1807 | if (!fcport) { | 2111 | if (!fcport) { |
@@ -1823,36 +2127,45 @@ int qedf_initiate_cleanup(struct qedf_ioreq *io_req, | |||
1823 | } | 2127 | } |
1824 | 2128 | ||
1825 | if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) || | 2129 | if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) || |
1826 | test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags)) { | 2130 | test_and_set_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags)) { |
1827 | QEDF_ERR(&(qedf->dbg_ctx), "io_req xid=0x%x already in " | 2131 | QEDF_ERR(&(qedf->dbg_ctx), "io_req xid=0x%x already in " |
1828 | "cleanup processing or already completed.\n", | 2132 | "cleanup processing or already completed.\n", |
1829 | io_req->xid); | 2133 | io_req->xid); |
1830 | return SUCCESS; | 2134 | return SUCCESS; |
1831 | } | 2135 | } |
2136 | set_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags); | ||
1832 | 2137 | ||
1833 | /* Ensure room on SQ */ | 2138 | /* Ensure room on SQ */ |
1834 | if (!atomic_read(&fcport->free_sqes)) { | 2139 | if (!atomic_read(&fcport->free_sqes)) { |
1835 | QEDF_ERR(&(qedf->dbg_ctx), "No SQ entries available\n"); | 2140 | QEDF_ERR(&(qedf->dbg_ctx), "No SQ entries available\n"); |
2141 | /* Need to make sure we clear the flag since it was set */ | ||
2142 | clear_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags); | ||
1836 | return FAILED; | 2143 | return FAILED; |
1837 | } | 2144 | } |
1838 | 2145 | ||
2146 | if (io_req->cmd_type == QEDF_CLEANUP) { | ||
2147 | QEDF_ERR(&qedf->dbg_ctx, | ||
2148 | "io_req=0x%x is already a cleanup command cmd_type=%d.\n", | ||
2149 | io_req->xid, io_req->cmd_type); | ||
2150 | clear_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags); | ||
2151 | return SUCCESS; | ||
2152 | } | ||
1839 | 2153 | ||
1840 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO, "Entered xid=0x%x\n", | 2154 | refcount = kref_read(&io_req->refcount); |
1841 | io_req->xid); | 2155 | |
2156 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, | ||
2157 | "Entered xid=0x%x sc_cmd=%p cmd_type=%d flags=0x%lx refcount=%d fcport=%p port_id=0x%06x\n", | ||
2158 | io_req->xid, io_req->sc_cmd, io_req->cmd_type, io_req->flags, | ||
2159 | refcount, fcport, fcport->rdata->ids.port_id); | ||
1842 | 2160 | ||
1843 | /* Cleanup cmds re-use the same TID as the original I/O */ | 2161 | /* Cleanup cmds re-use the same TID as the original I/O */ |
1844 | xid = io_req->xid; | 2162 | xid = io_req->xid; |
1845 | io_req->cmd_type = QEDF_CLEANUP; | 2163 | io_req->cmd_type = QEDF_CLEANUP; |
1846 | io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; | 2164 | io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; |
1847 | 2165 | ||
1848 | /* Set the return CPU to be the same as the request one */ | ||
1849 | io_req->cpu = smp_processor_id(); | ||
1850 | |||
1851 | set_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags); | ||
1852 | |||
1853 | task = qedf_get_task_mem(&qedf->tasks, xid); | 2166 | task = qedf_get_task_mem(&qedf->tasks, xid); |
1854 | 2167 | ||
1855 | init_completion(&io_req->tm_done); | 2168 | init_completion(&io_req->cleanup_done); |
1856 | 2169 | ||
1857 | spin_lock_irqsave(&fcport->rport_lock, flags); | 2170 | spin_lock_irqsave(&fcport->rport_lock, flags); |
1858 | 2171 | ||
@@ -1866,8 +2179,8 @@ int qedf_initiate_cleanup(struct qedf_ioreq *io_req, | |||
1866 | 2179 | ||
1867 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 2180 | spin_unlock_irqrestore(&fcport->rport_lock, flags); |
1868 | 2181 | ||
1869 | tmo = wait_for_completion_timeout(&io_req->tm_done, | 2182 | tmo = wait_for_completion_timeout(&io_req->cleanup_done, |
1870 | QEDF_CLEANUP_TIMEOUT * HZ); | 2183 | QEDF_CLEANUP_TIMEOUT * HZ); |
1871 | 2184 | ||
1872 | if (!tmo) { | 2185 | if (!tmo) { |
1873 | rc = FAILED; | 2186 | rc = FAILED; |
@@ -1880,6 +2193,16 @@ int qedf_initiate_cleanup(struct qedf_ioreq *io_req, | |||
1880 | qedf_drain_request(qedf); | 2193 | qedf_drain_request(qedf); |
1881 | } | 2194 | } |
1882 | 2195 | ||
2196 | /* If it TASK MGMT handle it, reference will be decreased | ||
2197 | * in qedf_execute_tmf | ||
2198 | */ | ||
2199 | if (io_req->tm_flags == FCP_TMF_LUN_RESET || | ||
2200 | io_req->tm_flags == FCP_TMF_TGT_RESET) { | ||
2201 | clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags); | ||
2202 | io_req->sc_cmd = NULL; | ||
2203 | complete(&io_req->tm_done); | ||
2204 | } | ||
2205 | |||
1883 | if (io_req->sc_cmd) { | 2206 | if (io_req->sc_cmd) { |
1884 | if (io_req->return_scsi_cmd_on_abts) | 2207 | if (io_req->return_scsi_cmd_on_abts) |
1885 | qedf_scsi_done(qedf, io_req, DID_ERROR); | 2208 | qedf_scsi_done(qedf, io_req, DID_ERROR); |
@@ -1902,7 +2225,7 @@ void qedf_process_cleanup_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, | |||
1902 | clear_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags); | 2225 | clear_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags); |
1903 | 2226 | ||
1904 | /* Complete so we can finish cleaning up the I/O */ | 2227 | /* Complete so we can finish cleaning up the I/O */ |
1905 | complete(&io_req->tm_done); | 2228 | complete(&io_req->cleanup_done); |
1906 | } | 2229 | } |
1907 | 2230 | ||
1908 | static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, | 2231 | static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, |
@@ -1915,6 +2238,7 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, | |||
1915 | int rc = 0; | 2238 | int rc = 0; |
1916 | uint16_t xid; | 2239 | uint16_t xid; |
1917 | int tmo = 0; | 2240 | int tmo = 0; |
2241 | int lun = 0; | ||
1918 | unsigned long flags; | 2242 | unsigned long flags; |
1919 | struct fcoe_wqe *sqe; | 2243 | struct fcoe_wqe *sqe; |
1920 | u16 sqe_idx; | 2244 | u16 sqe_idx; |
@@ -1924,20 +2248,18 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, | |||
1924 | return FAILED; | 2248 | return FAILED; |
1925 | } | 2249 | } |
1926 | 2250 | ||
2251 | lun = (int)sc_cmd->device->lun; | ||
1927 | if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) { | 2252 | if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) { |
1928 | QEDF_ERR(&(qedf->dbg_ctx), "fcport not offloaded\n"); | 2253 | QEDF_ERR(&(qedf->dbg_ctx), "fcport not offloaded\n"); |
1929 | rc = FAILED; | 2254 | rc = FAILED; |
1930 | return FAILED; | 2255 | goto no_flush; |
1931 | } | 2256 | } |
1932 | 2257 | ||
1933 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_SCSI_TM, "portid = 0x%x " | ||
1934 | "tm_flags = %d\n", fcport->rdata->ids.port_id, tm_flags); | ||
1935 | |||
1936 | io_req = qedf_alloc_cmd(fcport, QEDF_TASK_MGMT_CMD); | 2258 | io_req = qedf_alloc_cmd(fcport, QEDF_TASK_MGMT_CMD); |
1937 | if (!io_req) { | 2259 | if (!io_req) { |
1938 | QEDF_ERR(&(qedf->dbg_ctx), "Failed TMF"); | 2260 | QEDF_ERR(&(qedf->dbg_ctx), "Failed TMF"); |
1939 | rc = -EAGAIN; | 2261 | rc = -EAGAIN; |
1940 | goto reset_tmf_err; | 2262 | goto no_flush; |
1941 | } | 2263 | } |
1942 | 2264 | ||
1943 | if (tm_flags == FCP_TMF_LUN_RESET) | 2265 | if (tm_flags == FCP_TMF_LUN_RESET) |
@@ -1950,7 +2272,7 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, | |||
1950 | io_req->fcport = fcport; | 2272 | io_req->fcport = fcport; |
1951 | io_req->cmd_type = QEDF_TASK_MGMT_CMD; | 2273 | io_req->cmd_type = QEDF_TASK_MGMT_CMD; |
1952 | 2274 | ||
1953 | /* Set the return CPU to be the same as the request one */ | 2275 | /* Record which cpu this request is associated with */ |
1954 | io_req->cpu = smp_processor_id(); | 2276 | io_req->cpu = smp_processor_id(); |
1955 | 2277 | ||
1956 | /* Set TM flags */ | 2278 | /* Set TM flags */ |
@@ -1959,7 +2281,7 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, | |||
1959 | io_req->tm_flags = tm_flags; | 2281 | io_req->tm_flags = tm_flags; |
1960 | 2282 | ||
1961 | /* Default is to return a SCSI command when an error occurs */ | 2283 | /* Default is to return a SCSI command when an error occurs */ |
1962 | io_req->return_scsi_cmd_on_abts = true; | 2284 | io_req->return_scsi_cmd_on_abts = false; |
1963 | 2285 | ||
1964 | /* Obtain exchange id */ | 2286 | /* Obtain exchange id */ |
1965 | xid = io_req->xid; | 2287 | xid = io_req->xid; |
@@ -1983,12 +2305,16 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, | |||
1983 | 2305 | ||
1984 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 2306 | spin_unlock_irqrestore(&fcport->rport_lock, flags); |
1985 | 2307 | ||
2308 | set_bit(QEDF_CMD_OUTSTANDING, &io_req->flags); | ||
1986 | tmo = wait_for_completion_timeout(&io_req->tm_done, | 2309 | tmo = wait_for_completion_timeout(&io_req->tm_done, |
1987 | QEDF_TM_TIMEOUT * HZ); | 2310 | QEDF_TM_TIMEOUT * HZ); |
1988 | 2311 | ||
1989 | if (!tmo) { | 2312 | if (!tmo) { |
1990 | rc = FAILED; | 2313 | rc = FAILED; |
1991 | QEDF_ERR(&(qedf->dbg_ctx), "wait for tm_cmpl timeout!\n"); | 2314 | QEDF_ERR(&(qedf->dbg_ctx), "wait for tm_cmpl timeout!\n"); |
2315 | /* Clear outstanding bit since command timed out */ | ||
2316 | clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags); | ||
2317 | io_req->sc_cmd = NULL; | ||
1992 | } else { | 2318 | } else { |
1993 | /* Check TMF response code */ | 2319 | /* Check TMF response code */ |
1994 | if (io_req->fcp_rsp_code == 0) | 2320 | if (io_req->fcp_rsp_code == 0) |
@@ -1996,14 +2322,25 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, | |||
1996 | else | 2322 | else |
1997 | rc = FAILED; | 2323 | rc = FAILED; |
1998 | } | 2324 | } |
2325 | /* | ||
2326 | * Double check that fcport has not gone into an uploading state before | ||
2327 | * executing the command flush for the LUN/target. | ||
2328 | */ | ||
2329 | if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) { | ||
2330 | QEDF_ERR(&qedf->dbg_ctx, | ||
2331 | "fcport is uploading, not executing flush.\n"); | ||
2332 | goto no_flush; | ||
2333 | } | ||
2334 | /* We do not need this io_req any more */ | ||
2335 | kref_put(&io_req->refcount, qedf_release_cmd); | ||
2336 | |||
1999 | 2337 | ||
2000 | if (tm_flags == FCP_TMF_LUN_RESET) | 2338 | if (tm_flags == FCP_TMF_LUN_RESET) |
2001 | qedf_flush_active_ios(fcport, (int)sc_cmd->device->lun); | 2339 | qedf_flush_active_ios(fcport, lun); |
2002 | else | 2340 | else |
2003 | qedf_flush_active_ios(fcport, -1); | 2341 | qedf_flush_active_ios(fcport, -1); |
2004 | 2342 | ||
2005 | kref_put(&io_req->refcount, qedf_release_cmd); | 2343 | no_flush: |
2006 | |||
2007 | if (rc != SUCCESS) { | 2344 | if (rc != SUCCESS) { |
2008 | QEDF_ERR(&(qedf->dbg_ctx), "task mgmt command failed...\n"); | 2345 | QEDF_ERR(&(qedf->dbg_ctx), "task mgmt command failed...\n"); |
2009 | rc = FAILED; | 2346 | rc = FAILED; |
@@ -2011,7 +2348,6 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, | |||
2011 | QEDF_ERR(&(qedf->dbg_ctx), "task mgmt command success...\n"); | 2348 | QEDF_ERR(&(qedf->dbg_ctx), "task mgmt command success...\n"); |
2012 | rc = SUCCESS; | 2349 | rc = SUCCESS; |
2013 | } | 2350 | } |
2014 | reset_tmf_err: | ||
2015 | return rc; | 2351 | return rc; |
2016 | } | 2352 | } |
2017 | 2353 | ||
@@ -2021,26 +2357,65 @@ int qedf_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) | |||
2021 | struct fc_rport_libfc_priv *rp = rport->dd_data; | 2357 | struct fc_rport_libfc_priv *rp = rport->dd_data; |
2022 | struct qedf_rport *fcport = (struct qedf_rport *)&rp[1]; | 2358 | struct qedf_rport *fcport = (struct qedf_rport *)&rp[1]; |
2023 | struct qedf_ctx *qedf; | 2359 | struct qedf_ctx *qedf; |
2024 | struct fc_lport *lport; | 2360 | struct fc_lport *lport = shost_priv(sc_cmd->device->host); |
2025 | int rc = SUCCESS; | 2361 | int rc = SUCCESS; |
2026 | int rval; | 2362 | int rval; |
2363 | struct qedf_ioreq *io_req = NULL; | ||
2364 | int ref_cnt = 0; | ||
2365 | struct fc_rport_priv *rdata = fcport->rdata; | ||
2027 | 2366 | ||
2028 | rval = fc_remote_port_chkready(rport); | 2367 | QEDF_ERR(NULL, |
2368 | "tm_flags 0x%x sc_cmd %p op = 0x%02x target_id = 0x%x lun=%d\n", | ||
2369 | tm_flags, sc_cmd, sc_cmd->cmnd[0], rport->scsi_target_id, | ||
2370 | (int)sc_cmd->device->lun); | ||
2371 | |||
2372 | if (!rdata || !kref_get_unless_zero(&rdata->kref)) { | ||
2373 | QEDF_ERR(NULL, "stale rport\n"); | ||
2374 | return FAILED; | ||
2375 | } | ||
2376 | |||
2377 | QEDF_ERR(NULL, "portid=%06x tm_flags =%s\n", rdata->ids.port_id, | ||
2378 | (tm_flags == FCP_TMF_TGT_RESET) ? "TARGET RESET" : | ||
2379 | "LUN RESET"); | ||
2380 | |||
2381 | if (sc_cmd->SCp.ptr) { | ||
2382 | io_req = (struct qedf_ioreq *)sc_cmd->SCp.ptr; | ||
2383 | ref_cnt = kref_read(&io_req->refcount); | ||
2384 | QEDF_ERR(NULL, | ||
2385 | "orig io_req = %p xid = 0x%x ref_cnt = %d.\n", | ||
2386 | io_req, io_req->xid, ref_cnt); | ||
2387 | } | ||
2029 | 2388 | ||
2389 | rval = fc_remote_port_chkready(rport); | ||
2030 | if (rval) { | 2390 | if (rval) { |
2031 | QEDF_ERR(NULL, "device_reset rport not ready\n"); | 2391 | QEDF_ERR(NULL, "device_reset rport not ready\n"); |
2032 | rc = FAILED; | 2392 | rc = FAILED; |
2033 | goto tmf_err; | 2393 | goto tmf_err; |
2034 | } | 2394 | } |
2035 | 2395 | ||
2036 | if (fcport == NULL) { | 2396 | rc = fc_block_scsi_eh(sc_cmd); |
2397 | if (rc) | ||
2398 | goto tmf_err; | ||
2399 | |||
2400 | if (!fcport) { | ||
2037 | QEDF_ERR(NULL, "device_reset: rport is NULL\n"); | 2401 | QEDF_ERR(NULL, "device_reset: rport is NULL\n"); |
2038 | rc = FAILED; | 2402 | rc = FAILED; |
2039 | goto tmf_err; | 2403 | goto tmf_err; |
2040 | } | 2404 | } |
2041 | 2405 | ||
2042 | qedf = fcport->qedf; | 2406 | qedf = fcport->qedf; |
2043 | lport = qedf->lport; | 2407 | |
2408 | if (!qedf) { | ||
2409 | QEDF_ERR(NULL, "qedf is NULL.\n"); | ||
2410 | rc = FAILED; | ||
2411 | goto tmf_err; | ||
2412 | } | ||
2413 | |||
2414 | if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) { | ||
2415 | QEDF_ERR(&qedf->dbg_ctx, "Connection is getting uploaded.\n"); | ||
2416 | rc = SUCCESS; | ||
2417 | goto tmf_err; | ||
2418 | } | ||
2044 | 2419 | ||
2045 | if (test_bit(QEDF_UNLOADING, &qedf->flags) || | 2420 | if (test_bit(QEDF_UNLOADING, &qedf->flags) || |
2046 | test_bit(QEDF_DBG_STOP_IO, &qedf->flags)) { | 2421 | test_bit(QEDF_DBG_STOP_IO, &qedf->flags)) { |
@@ -2054,9 +2429,22 @@ int qedf_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) | |||
2054 | goto tmf_err; | 2429 | goto tmf_err; |
2055 | } | 2430 | } |
2056 | 2431 | ||
2432 | if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) { | ||
2433 | if (!fcport->rdata) | ||
2434 | QEDF_ERR(&qedf->dbg_ctx, "fcport %p is uploading.\n", | ||
2435 | fcport); | ||
2436 | else | ||
2437 | QEDF_ERR(&qedf->dbg_ctx, | ||
2438 | "fcport %p port_id=%06x is uploading.\n", | ||
2439 | fcport, fcport->rdata->ids.port_id); | ||
2440 | rc = FAILED; | ||
2441 | goto tmf_err; | ||
2442 | } | ||
2443 | |||
2057 | rc = qedf_execute_tmf(fcport, sc_cmd, tm_flags); | 2444 | rc = qedf_execute_tmf(fcport, sc_cmd, tm_flags); |
2058 | 2445 | ||
2059 | tmf_err: | 2446 | tmf_err: |
2447 | kref_put(&rdata->kref, fc_rport_destroy); | ||
2060 | return rc; | 2448 | return rc; |
2061 | } | 2449 | } |
2062 | 2450 | ||
@@ -2065,6 +2453,8 @@ void qedf_process_tmf_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, | |||
2065 | { | 2453 | { |
2066 | struct fcoe_cqe_rsp_info *fcp_rsp; | 2454 | struct fcoe_cqe_rsp_info *fcp_rsp; |
2067 | 2455 | ||
2456 | clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags); | ||
2457 | |||
2068 | fcp_rsp = &cqe->cqe_info.rsp_info; | 2458 | fcp_rsp = &cqe->cqe_info.rsp_info; |
2069 | qedf_parse_fcp_rsp(io_req, fcp_rsp); | 2459 | qedf_parse_fcp_rsp(io_req, fcp_rsp); |
2070 | 2460 | ||
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index 9f9431a4cc0e..5b07235497c6 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c | |||
@@ -124,21 +124,24 @@ static bool qedf_initiate_fipvlan_req(struct qedf_ctx *qedf) | |||
124 | { | 124 | { |
125 | int rc; | 125 | int rc; |
126 | 126 | ||
127 | if (atomic_read(&qedf->link_state) != QEDF_LINK_UP) { | ||
128 | QEDF_ERR(&(qedf->dbg_ctx), "Link not up.\n"); | ||
129 | return false; | ||
130 | } | ||
131 | |||
132 | while (qedf->fipvlan_retries--) { | 127 | while (qedf->fipvlan_retries--) { |
128 | /* This is to catch if link goes down during fipvlan retries */ | ||
129 | if (atomic_read(&qedf->link_state) == QEDF_LINK_DOWN) { | ||
130 | QEDF_ERR(&qedf->dbg_ctx, "Link not up.\n"); | ||
131 | return false; | ||
132 | } | ||
133 | |||
133 | if (qedf->vlan_id > 0) | 134 | if (qedf->vlan_id > 0) |
134 | return true; | 135 | return true; |
136 | |||
135 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, | 137 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, |
136 | "Retry %d.\n", qedf->fipvlan_retries); | 138 | "Retry %d.\n", qedf->fipvlan_retries); |
137 | init_completion(&qedf->fipvlan_compl); | 139 | init_completion(&qedf->fipvlan_compl); |
138 | qedf_fcoe_send_vlan_req(qedf); | 140 | qedf_fcoe_send_vlan_req(qedf); |
139 | rc = wait_for_completion_timeout(&qedf->fipvlan_compl, | 141 | rc = wait_for_completion_timeout(&qedf->fipvlan_compl, |
140 | 1 * HZ); | 142 | 1 * HZ); |
141 | if (rc > 0) { | 143 | if (rc > 0 && |
144 | (atomic_read(&qedf->link_state) == QEDF_LINK_UP)) { | ||
142 | fcoe_ctlr_link_up(&qedf->ctlr); | 145 | fcoe_ctlr_link_up(&qedf->ctlr); |
143 | return true; | 146 | return true; |
144 | } | 147 | } |
@@ -153,12 +156,19 @@ static void qedf_handle_link_update(struct work_struct *work) | |||
153 | container_of(work, struct qedf_ctx, link_update.work); | 156 | container_of(work, struct qedf_ctx, link_update.work); |
154 | int rc; | 157 | int rc; |
155 | 158 | ||
156 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "Entered.\n"); | 159 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC, "Entered. link_state=%d.\n", |
160 | atomic_read(&qedf->link_state)); | ||
157 | 161 | ||
158 | if (atomic_read(&qedf->link_state) == QEDF_LINK_UP) { | 162 | if (atomic_read(&qedf->link_state) == QEDF_LINK_UP) { |
159 | rc = qedf_initiate_fipvlan_req(qedf); | 163 | rc = qedf_initiate_fipvlan_req(qedf); |
160 | if (rc) | 164 | if (rc) |
161 | return; | 165 | return; |
166 | |||
167 | if (atomic_read(&qedf->link_state) != QEDF_LINK_UP) { | ||
168 | qedf->vlan_id = 0; | ||
169 | return; | ||
170 | } | ||
171 | |||
162 | /* | 172 | /* |
163 | * If we get here then we never received a repsonse to our | 173 | * If we get here then we never received a repsonse to our |
164 | * fip vlan request so set the vlan_id to the default and | 174 | * fip vlan request so set the vlan_id to the default and |
@@ -185,7 +195,9 @@ static void qedf_handle_link_update(struct work_struct *work) | |||
185 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, | 195 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, |
186 | "Calling fcoe_ctlr_link_down().\n"); | 196 | "Calling fcoe_ctlr_link_down().\n"); |
187 | fcoe_ctlr_link_down(&qedf->ctlr); | 197 | fcoe_ctlr_link_down(&qedf->ctlr); |
188 | qedf_wait_for_upload(qedf); | 198 | if (qedf_wait_for_upload(qedf) == false) |
199 | QEDF_ERR(&qedf->dbg_ctx, | ||
200 | "Could not upload all sessions.\n"); | ||
189 | /* Reset the number of FIP VLAN retries */ | 201 | /* Reset the number of FIP VLAN retries */ |
190 | qedf->fipvlan_retries = qedf_fipvlan_retries; | 202 | qedf->fipvlan_retries = qedf_fipvlan_retries; |
191 | } | 203 | } |
@@ -615,50 +627,113 @@ static struct scsi_transport_template *qedf_fc_vport_transport_template; | |||
615 | static int qedf_eh_abort(struct scsi_cmnd *sc_cmd) | 627 | static int qedf_eh_abort(struct scsi_cmnd *sc_cmd) |
616 | { | 628 | { |
617 | struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device)); | 629 | struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device)); |
618 | struct fc_rport_libfc_priv *rp = rport->dd_data; | ||
619 | struct qedf_rport *fcport; | ||
620 | struct fc_lport *lport; | 630 | struct fc_lport *lport; |
621 | struct qedf_ctx *qedf; | 631 | struct qedf_ctx *qedf; |
622 | struct qedf_ioreq *io_req; | 632 | struct qedf_ioreq *io_req; |
633 | struct fc_rport_libfc_priv *rp = rport->dd_data; | ||
634 | struct fc_rport_priv *rdata; | ||
635 | struct qedf_rport *fcport = NULL; | ||
623 | int rc = FAILED; | 636 | int rc = FAILED; |
637 | int wait_count = 100; | ||
638 | int refcount = 0; | ||
624 | int rval; | 639 | int rval; |
625 | 640 | int got_ref = 0; | |
626 | if (fc_remote_port_chkready(rport)) { | ||
627 | QEDF_ERR(NULL, "rport not ready\n"); | ||
628 | goto out; | ||
629 | } | ||
630 | 641 | ||
631 | lport = shost_priv(sc_cmd->device->host); | 642 | lport = shost_priv(sc_cmd->device->host); |
632 | qedf = (struct qedf_ctx *)lport_priv(lport); | 643 | qedf = (struct qedf_ctx *)lport_priv(lport); |
633 | 644 | ||
634 | if ((lport->state != LPORT_ST_READY) || !(lport->link_up)) { | 645 | /* rport and tgt are allocated together, so tgt should be non-NULL */ |
635 | QEDF_ERR(&(qedf->dbg_ctx), "link not ready.\n"); | 646 | fcport = (struct qedf_rport *)&rp[1]; |
647 | rdata = fcport->rdata; | ||
648 | if (!rdata || !kref_get_unless_zero(&rdata->kref)) { | ||
649 | QEDF_ERR(&qedf->dbg_ctx, "stale rport, sc_cmd=%p\n", sc_cmd); | ||
650 | rc = 1; | ||
636 | goto out; | 651 | goto out; |
637 | } | 652 | } |
638 | 653 | ||
639 | fcport = (struct qedf_rport *)&rp[1]; | ||
640 | 654 | ||
641 | io_req = (struct qedf_ioreq *)sc_cmd->SCp.ptr; | 655 | io_req = (struct qedf_ioreq *)sc_cmd->SCp.ptr; |
642 | if (!io_req) { | 656 | if (!io_req) { |
643 | QEDF_ERR(&(qedf->dbg_ctx), "io_req is NULL.\n"); | 657 | QEDF_ERR(&qedf->dbg_ctx, |
658 | "sc_cmd not queued with lld, sc_cmd=%p op=0x%02x, port_id=%06x\n", | ||
659 | sc_cmd, sc_cmd->cmnd[0], | ||
660 | rdata->ids.port_id); | ||
644 | rc = SUCCESS; | 661 | rc = SUCCESS; |
645 | goto out; | 662 | goto drop_rdata_kref; |
663 | } | ||
664 | |||
665 | rval = kref_get_unless_zero(&io_req->refcount); /* ID: 005 */ | ||
666 | if (rval) | ||
667 | got_ref = 1; | ||
668 | |||
669 | /* If we got a valid io_req, confirm it belongs to this sc_cmd. */ | ||
670 | if (!rval || io_req->sc_cmd != sc_cmd) { | ||
671 | QEDF_ERR(&qedf->dbg_ctx, | ||
672 | "Freed/Incorrect io_req, io_req->sc_cmd=%p, sc_cmd=%p, port_id=%06x, bailing out.\n", | ||
673 | io_req->sc_cmd, sc_cmd, rdata->ids.port_id); | ||
674 | |||
675 | goto drop_rdata_kref; | ||
676 | } | ||
677 | |||
678 | if (fc_remote_port_chkready(rport)) { | ||
679 | refcount = kref_read(&io_req->refcount); | ||
680 | QEDF_ERR(&qedf->dbg_ctx, | ||
681 | "rport not ready, io_req=%p, xid=0x%x sc_cmd=%p op=0x%02x, refcount=%d, port_id=%06x\n", | ||
682 | io_req, io_req->xid, sc_cmd, sc_cmd->cmnd[0], | ||
683 | refcount, rdata->ids.port_id); | ||
684 | |||
685 | goto drop_rdata_kref; | ||
686 | } | ||
687 | |||
688 | rc = fc_block_scsi_eh(sc_cmd); | ||
689 | if (rc) | ||
690 | goto drop_rdata_kref; | ||
691 | |||
692 | if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) { | ||
693 | QEDF_ERR(&qedf->dbg_ctx, | ||
694 | "Connection uploading, xid=0x%x., port_id=%06x\n", | ||
695 | io_req->xid, rdata->ids.port_id); | ||
696 | while (io_req->sc_cmd && (wait_count != 0)) { | ||
697 | msleep(100); | ||
698 | wait_count--; | ||
699 | } | ||
700 | if (wait_count) { | ||
701 | QEDF_ERR(&qedf->dbg_ctx, "ABTS succeeded\n"); | ||
702 | rc = SUCCESS; | ||
703 | } else { | ||
704 | QEDF_ERR(&qedf->dbg_ctx, "ABTS failed\n"); | ||
705 | rc = FAILED; | ||
706 | } | ||
707 | goto drop_rdata_kref; | ||
646 | } | 708 | } |
647 | 709 | ||
648 | QEDF_ERR(&(qedf->dbg_ctx), "Aborting io_req sc_cmd=%p xid=0x%x " | 710 | if (lport->state != LPORT_ST_READY || !(lport->link_up)) { |
649 | "fp_idx=%d.\n", sc_cmd, io_req->xid, io_req->fp_idx); | 711 | QEDF_ERR(&qedf->dbg_ctx, "link not ready.\n"); |
712 | goto drop_rdata_kref; | ||
713 | } | ||
714 | |||
715 | QEDF_ERR(&qedf->dbg_ctx, | ||
716 | "Aborting io_req=%p sc_cmd=%p xid=0x%x fp_idx=%d, port_id=%06x.\n", | ||
717 | io_req, sc_cmd, io_req->xid, io_req->fp_idx, | ||
718 | rdata->ids.port_id); | ||
650 | 719 | ||
651 | if (qedf->stop_io_on_error) { | 720 | if (qedf->stop_io_on_error) { |
652 | qedf_stop_all_io(qedf); | 721 | qedf_stop_all_io(qedf); |
653 | rc = SUCCESS; | 722 | rc = SUCCESS; |
654 | goto out; | 723 | goto drop_rdata_kref; |
655 | } | 724 | } |
656 | 725 | ||
657 | init_completion(&io_req->abts_done); | 726 | init_completion(&io_req->abts_done); |
658 | rval = qedf_initiate_abts(io_req, true); | 727 | rval = qedf_initiate_abts(io_req, true); |
659 | if (rval) { | 728 | if (rval) { |
660 | QEDF_ERR(&(qedf->dbg_ctx), "Failed to queue ABTS.\n"); | 729 | QEDF_ERR(&(qedf->dbg_ctx), "Failed to queue ABTS.\n"); |
661 | goto out; | 730 | /* |
731 | * If we fail to queue the ABTS then return this command to | ||
732 | * the SCSI layer as it will own and free the xid | ||
733 | */ | ||
734 | rc = SUCCESS; | ||
735 | qedf_scsi_done(qedf, io_req, DID_ERROR); | ||
736 | goto drop_rdata_kref; | ||
662 | } | 737 | } |
663 | 738 | ||
664 | wait_for_completion(&io_req->abts_done); | 739 | wait_for_completion(&io_req->abts_done); |
@@ -684,38 +759,68 @@ static int qedf_eh_abort(struct scsi_cmnd *sc_cmd) | |||
684 | QEDF_ERR(&(qedf->dbg_ctx), "ABTS failed, xid=0x%x.\n", | 759 | QEDF_ERR(&(qedf->dbg_ctx), "ABTS failed, xid=0x%x.\n", |
685 | io_req->xid); | 760 | io_req->xid); |
686 | 761 | ||
762 | drop_rdata_kref: | ||
763 | kref_put(&rdata->kref, fc_rport_destroy); | ||
687 | out: | 764 | out: |
765 | if (got_ref) | ||
766 | kref_put(&io_req->refcount, qedf_release_cmd); | ||
688 | return rc; | 767 | return rc; |
689 | } | 768 | } |
690 | 769 | ||
691 | static int qedf_eh_target_reset(struct scsi_cmnd *sc_cmd) | 770 | static int qedf_eh_target_reset(struct scsi_cmnd *sc_cmd) |
692 | { | 771 | { |
693 | QEDF_ERR(NULL, "TARGET RESET Issued..."); | 772 | QEDF_ERR(NULL, "%d:0:%d:%lld: TARGET RESET Issued...", |
773 | sc_cmd->device->host->host_no, sc_cmd->device->id, | ||
774 | sc_cmd->device->lun); | ||
694 | return qedf_initiate_tmf(sc_cmd, FCP_TMF_TGT_RESET); | 775 | return qedf_initiate_tmf(sc_cmd, FCP_TMF_TGT_RESET); |
695 | } | 776 | } |
696 | 777 | ||
697 | static int qedf_eh_device_reset(struct scsi_cmnd *sc_cmd) | 778 | static int qedf_eh_device_reset(struct scsi_cmnd *sc_cmd) |
698 | { | 779 | { |
699 | QEDF_ERR(NULL, "LUN RESET Issued...\n"); | 780 | QEDF_ERR(NULL, "%d:0:%d:%lld: LUN RESET Issued... ", |
781 | sc_cmd->device->host->host_no, sc_cmd->device->id, | ||
782 | sc_cmd->device->lun); | ||
700 | return qedf_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET); | 783 | return qedf_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET); |
701 | } | 784 | } |
702 | 785 | ||
703 | void qedf_wait_for_upload(struct qedf_ctx *qedf) | 786 | bool qedf_wait_for_upload(struct qedf_ctx *qedf) |
704 | { | 787 | { |
705 | while (1) { | 788 | struct qedf_rport *fcport = NULL; |
789 | int wait_cnt = 120; | ||
790 | |||
791 | while (wait_cnt--) { | ||
706 | if (atomic_read(&qedf->num_offloads)) | 792 | if (atomic_read(&qedf->num_offloads)) |
707 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, | 793 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC, |
708 | "Waiting for all uploads to complete.\n"); | 794 | "Waiting for all uploads to complete num_offloads = 0x%x.\n", |
795 | atomic_read(&qedf->num_offloads)); | ||
709 | else | 796 | else |
710 | break; | 797 | return true; |
711 | msleep(500); | 798 | msleep(500); |
712 | } | 799 | } |
800 | |||
801 | rcu_read_lock(); | ||
802 | list_for_each_entry_rcu(fcport, &qedf->fcports, peers) { | ||
803 | if (fcport && test_bit(QEDF_RPORT_SESSION_READY, | ||
804 | &fcport->flags)) { | ||
805 | if (fcport->rdata) | ||
806 | QEDF_ERR(&qedf->dbg_ctx, | ||
807 | "Waiting for fcport %p portid=%06x.\n", | ||
808 | fcport, fcport->rdata->ids.port_id); | ||
809 | } else { | ||
810 | QEDF_ERR(&qedf->dbg_ctx, | ||
811 | "Waiting for fcport %p.\n", fcport); | ||
812 | } | ||
813 | } | ||
814 | rcu_read_unlock(); | ||
815 | return false; | ||
816 | |||
713 | } | 817 | } |
714 | 818 | ||
715 | /* Performs soft reset of qedf_ctx by simulating a link down/up */ | 819 | /* Performs soft reset of qedf_ctx by simulating a link down/up */ |
716 | static void qedf_ctx_soft_reset(struct fc_lport *lport) | 820 | void qedf_ctx_soft_reset(struct fc_lport *lport) |
717 | { | 821 | { |
718 | struct qedf_ctx *qedf; | 822 | struct qedf_ctx *qedf; |
823 | struct qed_link_output if_link; | ||
719 | 824 | ||
720 | if (lport->vport) { | 825 | if (lport->vport) { |
721 | QEDF_ERR(NULL, "Cannot issue host reset on NPIV port.\n"); | 826 | QEDF_ERR(NULL, "Cannot issue host reset on NPIV port.\n"); |
@@ -726,11 +831,32 @@ static void qedf_ctx_soft_reset(struct fc_lport *lport) | |||
726 | 831 | ||
727 | /* For host reset, essentially do a soft link up/down */ | 832 | /* For host reset, essentially do a soft link up/down */ |
728 | atomic_set(&qedf->link_state, QEDF_LINK_DOWN); | 833 | atomic_set(&qedf->link_state, QEDF_LINK_DOWN); |
834 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC, | ||
835 | "Queuing link down work.\n"); | ||
729 | queue_delayed_work(qedf->link_update_wq, &qedf->link_update, | 836 | queue_delayed_work(qedf->link_update_wq, &qedf->link_update, |
730 | 0); | 837 | 0); |
731 | qedf_wait_for_upload(qedf); | 838 | |
839 | if (qedf_wait_for_upload(qedf) == false) { | ||
840 | QEDF_ERR(&qedf->dbg_ctx, "Could not upload all sessions.\n"); | ||
841 | WARN_ON(atomic_read(&qedf->num_offloads)); | ||
842 | } | ||
843 | |||
844 | /* Before setting link up query physical link state */ | ||
845 | qed_ops->common->get_link(qedf->cdev, &if_link); | ||
846 | /* Bail if the physical link is not up */ | ||
847 | if (!if_link.link_up) { | ||
848 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC, | ||
849 | "Physical link is not up.\n"); | ||
850 | return; | ||
851 | } | ||
852 | /* Flush and wait to make sure link down is processed */ | ||
853 | flush_delayed_work(&qedf->link_update); | ||
854 | msleep(500); | ||
855 | |||
732 | atomic_set(&qedf->link_state, QEDF_LINK_UP); | 856 | atomic_set(&qedf->link_state, QEDF_LINK_UP); |
733 | qedf->vlan_id = 0; | 857 | qedf->vlan_id = 0; |
858 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC, | ||
859 | "Queue link up work.\n"); | ||
734 | queue_delayed_work(qedf->link_update_wq, &qedf->link_update, | 860 | queue_delayed_work(qedf->link_update_wq, &qedf->link_update, |
735 | 0); | 861 | 0); |
736 | } | 862 | } |
@@ -740,22 +866,6 @@ static int qedf_eh_host_reset(struct scsi_cmnd *sc_cmd) | |||
740 | { | 866 | { |
741 | struct fc_lport *lport; | 867 | struct fc_lport *lport; |
742 | struct qedf_ctx *qedf; | 868 | struct qedf_ctx *qedf; |
743 | struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device)); | ||
744 | struct fc_rport_libfc_priv *rp = rport->dd_data; | ||
745 | struct qedf_rport *fcport = (struct qedf_rport *)&rp[1]; | ||
746 | int rval; | ||
747 | |||
748 | rval = fc_remote_port_chkready(rport); | ||
749 | |||
750 | if (rval) { | ||
751 | QEDF_ERR(NULL, "device_reset rport not ready\n"); | ||
752 | return FAILED; | ||
753 | } | ||
754 | |||
755 | if (fcport == NULL) { | ||
756 | QEDF_ERR(NULL, "device_reset: rport is NULL\n"); | ||
757 | return FAILED; | ||
758 | } | ||
759 | 869 | ||
760 | lport = shost_priv(sc_cmd->device->host); | 870 | lport = shost_priv(sc_cmd->device->host); |
761 | qedf = lport_priv(lport); | 871 | qedf = lport_priv(lport); |
@@ -907,8 +1017,10 @@ static int qedf_xmit(struct fc_lport *lport, struct fc_frame *fp) | |||
907 | "Dropping FCoE frame to %06x.\n", ntoh24(fh->fh_d_id)); | 1017 | "Dropping FCoE frame to %06x.\n", ntoh24(fh->fh_d_id)); |
908 | kfree_skb(skb); | 1018 | kfree_skb(skb); |
909 | rdata = fc_rport_lookup(lport, ntoh24(fh->fh_d_id)); | 1019 | rdata = fc_rport_lookup(lport, ntoh24(fh->fh_d_id)); |
910 | if (rdata) | 1020 | if (rdata) { |
911 | rdata->retries = lport->max_rport_retry_count; | 1021 | rdata->retries = lport->max_rport_retry_count; |
1022 | kref_put(&rdata->kref, fc_rport_destroy); | ||
1023 | } | ||
912 | return -EINVAL; | 1024 | return -EINVAL; |
913 | } | 1025 | } |
914 | /* End NPIV filtering */ | 1026 | /* End NPIV filtering */ |
@@ -1031,7 +1143,12 @@ static int qedf_xmit(struct fc_lport *lport, struct fc_frame *fp) | |||
1031 | if (qedf_dump_frames) | 1143 | if (qedf_dump_frames) |
1032 | print_hex_dump(KERN_WARNING, "fcoe: ", DUMP_PREFIX_OFFSET, 16, | 1144 | print_hex_dump(KERN_WARNING, "fcoe: ", DUMP_PREFIX_OFFSET, 16, |
1033 | 1, skb->data, skb->len, false); | 1145 | 1, skb->data, skb->len, false); |
1034 | qed_ops->ll2->start_xmit(qedf->cdev, skb, 0); | 1146 | rc = qed_ops->ll2->start_xmit(qedf->cdev, skb, 0); |
1147 | if (rc) { | ||
1148 | QEDF_ERR(&qedf->dbg_ctx, "start_xmit failed rc = %d.\n", rc); | ||
1149 | kfree_skb(skb); | ||
1150 | return rc; | ||
1151 | } | ||
1035 | 1152 | ||
1036 | return 0; | 1153 | return 0; |
1037 | } | 1154 | } |
@@ -1224,6 +1341,8 @@ static void qedf_upload_connection(struct qedf_ctx *qedf, | |||
1224 | static void qedf_cleanup_fcport(struct qedf_ctx *qedf, | 1341 | static void qedf_cleanup_fcport(struct qedf_ctx *qedf, |
1225 | struct qedf_rport *fcport) | 1342 | struct qedf_rport *fcport) |
1226 | { | 1343 | { |
1344 | struct fc_rport_priv *rdata = fcport->rdata; | ||
1345 | |||
1227 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_CONN, "Cleaning up portid=%06x.\n", | 1346 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_CONN, "Cleaning up portid=%06x.\n", |
1228 | fcport->rdata->ids.port_id); | 1347 | fcport->rdata->ids.port_id); |
1229 | 1348 | ||
@@ -1235,6 +1354,7 @@ static void qedf_cleanup_fcport(struct qedf_ctx *qedf, | |||
1235 | qedf_free_sq(qedf, fcport); | 1354 | qedf_free_sq(qedf, fcport); |
1236 | fcport->rdata = NULL; | 1355 | fcport->rdata = NULL; |
1237 | fcport->qedf = NULL; | 1356 | fcport->qedf = NULL; |
1357 | kref_put(&rdata->kref, fc_rport_destroy); | ||
1238 | } | 1358 | } |
1239 | 1359 | ||
1240 | /** | 1360 | /** |
@@ -1310,6 +1430,8 @@ static void qedf_rport_event_handler(struct fc_lport *lport, | |||
1310 | break; | 1430 | break; |
1311 | } | 1431 | } |
1312 | 1432 | ||
1433 | /* Initial reference held on entry, so this can't fail */ | ||
1434 | kref_get(&rdata->kref); | ||
1313 | fcport->rdata = rdata; | 1435 | fcport->rdata = rdata; |
1314 | fcport->rport = rport; | 1436 | fcport->rport = rport; |
1315 | 1437 | ||
@@ -1369,11 +1491,15 @@ static void qedf_rport_event_handler(struct fc_lport *lport, | |||
1369 | */ | 1491 | */ |
1370 | fcport = (struct qedf_rport *)&rp[1]; | 1492 | fcport = (struct qedf_rport *)&rp[1]; |
1371 | 1493 | ||
1494 | spin_lock_irqsave(&fcport->rport_lock, flags); | ||
1372 | /* Only free this fcport if it is offloaded already */ | 1495 | /* Only free this fcport if it is offloaded already */ |
1373 | if (test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) { | 1496 | if (test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags) && |
1374 | set_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags); | 1497 | !test_bit(QEDF_RPORT_UPLOADING_CONNECTION, |
1498 | &fcport->flags)) { | ||
1499 | set_bit(QEDF_RPORT_UPLOADING_CONNECTION, | ||
1500 | &fcport->flags); | ||
1501 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
1375 | qedf_cleanup_fcport(qedf, fcport); | 1502 | qedf_cleanup_fcport(qedf, fcport); |
1376 | |||
1377 | /* | 1503 | /* |
1378 | * Remove fcport to list of qedf_ctx list of offloaded | 1504 | * Remove fcport to list of qedf_ctx list of offloaded |
1379 | * ports | 1505 | * ports |
@@ -1385,8 +1511,9 @@ static void qedf_rport_event_handler(struct fc_lport *lport, | |||
1385 | clear_bit(QEDF_RPORT_UPLOADING_CONNECTION, | 1511 | clear_bit(QEDF_RPORT_UPLOADING_CONNECTION, |
1386 | &fcport->flags); | 1512 | &fcport->flags); |
1387 | atomic_dec(&qedf->num_offloads); | 1513 | atomic_dec(&qedf->num_offloads); |
1514 | } else { | ||
1515 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
1388 | } | 1516 | } |
1389 | |||
1390 | break; | 1517 | break; |
1391 | 1518 | ||
1392 | case RPORT_EV_NONE: | 1519 | case RPORT_EV_NONE: |
@@ -1498,11 +1625,15 @@ static int qedf_lport_setup(struct qedf_ctx *qedf) | |||
1498 | fc_set_wwnn(lport, qedf->wwnn); | 1625 | fc_set_wwnn(lport, qedf->wwnn); |
1499 | fc_set_wwpn(lport, qedf->wwpn); | 1626 | fc_set_wwpn(lport, qedf->wwpn); |
1500 | 1627 | ||
1501 | fcoe_libfc_config(lport, &qedf->ctlr, &qedf_lport_template, 0); | 1628 | if (fcoe_libfc_config(lport, &qedf->ctlr, &qedf_lport_template, 0)) { |
1629 | QEDF_ERR(&qedf->dbg_ctx, | ||
1630 | "fcoe_libfc_config failed.\n"); | ||
1631 | return -ENOMEM; | ||
1632 | } | ||
1502 | 1633 | ||
1503 | /* Allocate the exchange manager */ | 1634 | /* Allocate the exchange manager */ |
1504 | fc_exch_mgr_alloc(lport, FC_CLASS_3, qedf->max_scsi_xid + 1, | 1635 | fc_exch_mgr_alloc(lport, FC_CLASS_3, FCOE_PARAMS_NUM_TASKS, |
1505 | qedf->max_els_xid, NULL); | 1636 | 0xfffe, NULL); |
1506 | 1637 | ||
1507 | if (fc_lport_init_stats(lport)) | 1638 | if (fc_lport_init_stats(lport)) |
1508 | return -ENOMEM; | 1639 | return -ENOMEM; |
@@ -1625,14 +1756,15 @@ static int qedf_vport_create(struct fc_vport *vport, bool disabled) | |||
1625 | vport_qedf->wwpn = vn_port->wwpn; | 1756 | vport_qedf->wwpn = vn_port->wwpn; |
1626 | 1757 | ||
1627 | vn_port->host->transportt = qedf_fc_vport_transport_template; | 1758 | vn_port->host->transportt = qedf_fc_vport_transport_template; |
1628 | vn_port->host->can_queue = QEDF_MAX_ELS_XID; | 1759 | vn_port->host->can_queue = FCOE_PARAMS_NUM_TASKS; |
1629 | vn_port->host->max_lun = qedf_max_lun; | 1760 | vn_port->host->max_lun = qedf_max_lun; |
1630 | vn_port->host->sg_tablesize = QEDF_MAX_BDS_PER_CMD; | 1761 | vn_port->host->sg_tablesize = QEDF_MAX_BDS_PER_CMD; |
1631 | vn_port->host->max_cmd_len = QEDF_MAX_CDB_LEN; | 1762 | vn_port->host->max_cmd_len = QEDF_MAX_CDB_LEN; |
1632 | 1763 | ||
1633 | rc = scsi_add_host(vn_port->host, &vport->dev); | 1764 | rc = scsi_add_host(vn_port->host, &vport->dev); |
1634 | if (rc) { | 1765 | if (rc) { |
1635 | QEDF_WARN(&(base_qedf->dbg_ctx), "Error adding Scsi_Host.\n"); | 1766 | QEDF_WARN(&base_qedf->dbg_ctx, |
1767 | "Error adding Scsi_Host rc=0x%x.\n", rc); | ||
1636 | goto err2; | 1768 | goto err2; |
1637 | } | 1769 | } |
1638 | 1770 | ||
@@ -2155,7 +2287,8 @@ static int qedf_setup_int(struct qedf_ctx *qedf) | |||
2155 | QEDF_SIMD_HANDLER_NUM, qedf_simd_int_handler); | 2287 | QEDF_SIMD_HANDLER_NUM, qedf_simd_int_handler); |
2156 | qedf->int_info.used_cnt = 1; | 2288 | qedf->int_info.used_cnt = 1; |
2157 | 2289 | ||
2158 | QEDF_ERR(&qedf->dbg_ctx, "Only MSI-X supported. Failing probe.\n"); | 2290 | QEDF_ERR(&qedf->dbg_ctx, |
2291 | "Cannot load driver due to a lack of MSI-X vectors.\n"); | ||
2159 | return -EINVAL; | 2292 | return -EINVAL; |
2160 | } | 2293 | } |
2161 | 2294 | ||
@@ -2356,6 +2489,13 @@ static int qedf_ll2_rx(void *cookie, struct sk_buff *skb, | |||
2356 | struct qedf_ctx *qedf = (struct qedf_ctx *)cookie; | 2489 | struct qedf_ctx *qedf = (struct qedf_ctx *)cookie; |
2357 | struct qedf_skb_work *skb_work; | 2490 | struct qedf_skb_work *skb_work; |
2358 | 2491 | ||
2492 | if (atomic_read(&qedf->link_state) == QEDF_LINK_DOWN) { | ||
2493 | QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_LL2, | ||
2494 | "Dropping frame as link state is down.\n"); | ||
2495 | kfree_skb(skb); | ||
2496 | return 0; | ||
2497 | } | ||
2498 | |||
2359 | skb_work = kzalloc(sizeof(struct qedf_skb_work), GFP_ATOMIC); | 2499 | skb_work = kzalloc(sizeof(struct qedf_skb_work), GFP_ATOMIC); |
2360 | if (!skb_work) { | 2500 | if (!skb_work) { |
2361 | QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate skb_work so " | 2501 | QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate skb_work so " |
@@ -2990,6 +3130,8 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) | |||
2990 | goto err0; | 3130 | goto err0; |
2991 | } | 3131 | } |
2992 | 3132 | ||
3133 | fc_disc_init(lport); | ||
3134 | |||
2993 | /* Initialize qedf_ctx */ | 3135 | /* Initialize qedf_ctx */ |
2994 | qedf = lport_priv(lport); | 3136 | qedf = lport_priv(lport); |
2995 | qedf->lport = lport; | 3137 | qedf->lport = lport; |
@@ -3005,6 +3147,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) | |||
3005 | pci_set_drvdata(pdev, qedf); | 3147 | pci_set_drvdata(pdev, qedf); |
3006 | init_completion(&qedf->fipvlan_compl); | 3148 | init_completion(&qedf->fipvlan_compl); |
3007 | mutex_init(&qedf->stats_mutex); | 3149 | mutex_init(&qedf->stats_mutex); |
3150 | mutex_init(&qedf->flush_mutex); | ||
3008 | 3151 | ||
3009 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_INFO, | 3152 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_INFO, |
3010 | "QLogic FastLinQ FCoE Module qedf %s, " | 3153 | "QLogic FastLinQ FCoE Module qedf %s, " |
@@ -3181,11 +3324,6 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) | |||
3181 | sprintf(host_buf, "host_%d", host->host_no); | 3324 | sprintf(host_buf, "host_%d", host->host_no); |
3182 | qed_ops->common->set_name(qedf->cdev, host_buf); | 3325 | qed_ops->common->set_name(qedf->cdev, host_buf); |
3183 | 3326 | ||
3184 | |||
3185 | /* Set xid max values */ | ||
3186 | qedf->max_scsi_xid = QEDF_MAX_SCSI_XID; | ||
3187 | qedf->max_els_xid = QEDF_MAX_ELS_XID; | ||
3188 | |||
3189 | /* Allocate cmd mgr */ | 3327 | /* Allocate cmd mgr */ |
3190 | qedf->cmd_mgr = qedf_cmd_mgr_alloc(qedf); | 3328 | qedf->cmd_mgr = qedf_cmd_mgr_alloc(qedf); |
3191 | if (!qedf->cmd_mgr) { | 3329 | if (!qedf->cmd_mgr) { |
@@ -3196,12 +3334,15 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) | |||
3196 | 3334 | ||
3197 | if (mode != QEDF_MODE_RECOVERY) { | 3335 | if (mode != QEDF_MODE_RECOVERY) { |
3198 | host->transportt = qedf_fc_transport_template; | 3336 | host->transportt = qedf_fc_transport_template; |
3199 | host->can_queue = QEDF_MAX_ELS_XID; | ||
3200 | host->max_lun = qedf_max_lun; | 3337 | host->max_lun = qedf_max_lun; |
3201 | host->max_cmd_len = QEDF_MAX_CDB_LEN; | 3338 | host->max_cmd_len = QEDF_MAX_CDB_LEN; |
3339 | host->can_queue = FCOE_PARAMS_NUM_TASKS; | ||
3202 | rc = scsi_add_host(host, &pdev->dev); | 3340 | rc = scsi_add_host(host, &pdev->dev); |
3203 | if (rc) | 3341 | if (rc) { |
3342 | QEDF_WARN(&qedf->dbg_ctx, | ||
3343 | "Error adding Scsi_Host rc=0x%x.\n", rc); | ||
3204 | goto err6; | 3344 | goto err6; |
3345 | } | ||
3205 | } | 3346 | } |
3206 | 3347 | ||
3207 | memset(¶ms, 0, sizeof(params)); | 3348 | memset(¶ms, 0, sizeof(params)); |
@@ -3377,7 +3518,9 @@ static void __qedf_remove(struct pci_dev *pdev, int mode) | |||
3377 | fcoe_ctlr_link_down(&qedf->ctlr); | 3518 | fcoe_ctlr_link_down(&qedf->ctlr); |
3378 | else | 3519 | else |
3379 | fc_fabric_logoff(qedf->lport); | 3520 | fc_fabric_logoff(qedf->lport); |
3380 | qedf_wait_for_upload(qedf); | 3521 | |
3522 | if (qedf_wait_for_upload(qedf) == false) | ||
3523 | QEDF_ERR(&qedf->dbg_ctx, "Could not upload all sessions.\n"); | ||
3381 | 3524 | ||
3382 | #ifdef CONFIG_DEBUG_FS | 3525 | #ifdef CONFIG_DEBUG_FS |
3383 | qedf_dbg_host_exit(&(qedf->dbg_ctx)); | 3526 | qedf_dbg_host_exit(&(qedf->dbg_ctx)); |
diff --git a/drivers/scsi/qedf/qedf_version.h b/drivers/scsi/qedf/qedf_version.h index 9455faacd5de..334a9cdf346a 100644 --- a/drivers/scsi/qedf/qedf_version.h +++ b/drivers/scsi/qedf/qedf_version.h | |||
@@ -7,9 +7,9 @@ | |||
7 | * this source tree. | 7 | * this source tree. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #define QEDF_VERSION "8.33.16.20" | 10 | #define QEDF_VERSION "8.37.25.20" |
11 | #define QEDF_DRIVER_MAJOR_VER 8 | 11 | #define QEDF_DRIVER_MAJOR_VER 8 |
12 | #define QEDF_DRIVER_MINOR_VER 33 | 12 | #define QEDF_DRIVER_MINOR_VER 37 |
13 | #define QEDF_DRIVER_REV_VER 16 | 13 | #define QEDF_DRIVER_REV_VER 25 |
14 | #define QEDF_DRIVER_ENG_VER 20 | 14 | #define QEDF_DRIVER_ENG_VER 20 |
15 | 15 | ||
diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c index f8f86774f77f..bd81bbee61e6 100644 --- a/drivers/scsi/qedi/qedi_fw.c +++ b/drivers/scsi/qedi/qedi_fw.c | |||
@@ -155,12 +155,10 @@ static void qedi_tmf_resp_work(struct work_struct *work) | |||
155 | struct iscsi_conn *conn = qedi_conn->cls_conn->dd_data; | 155 | struct iscsi_conn *conn = qedi_conn->cls_conn->dd_data; |
156 | struct iscsi_session *session = conn->session; | 156 | struct iscsi_session *session = conn->session; |
157 | struct iscsi_tm_rsp *resp_hdr_ptr; | 157 | struct iscsi_tm_rsp *resp_hdr_ptr; |
158 | struct iscsi_cls_session *cls_sess; | ||
159 | int rval = 0; | 158 | int rval = 0; |
160 | 159 | ||
161 | set_bit(QEDI_CONN_FW_CLEANUP, &qedi_conn->flags); | 160 | set_bit(QEDI_CONN_FW_CLEANUP, &qedi_conn->flags); |
162 | resp_hdr_ptr = (struct iscsi_tm_rsp *)qedi_cmd->tmf_resp_buf; | 161 | resp_hdr_ptr = (struct iscsi_tm_rsp *)qedi_cmd->tmf_resp_buf; |
163 | cls_sess = iscsi_conn_to_session(qedi_conn->cls_conn); | ||
164 | 162 | ||
165 | iscsi_block_session(session->cls_session); | 163 | iscsi_block_session(session->cls_session); |
166 | rval = qedi_cleanup_all_io(qedi, qedi_conn, qedi_cmd->task, true); | 164 | rval = qedi_cleanup_all_io(qedi, qedi_conn, qedi_cmd->task, true); |
@@ -1366,7 +1364,6 @@ static void qedi_tmf_work(struct work_struct *work) | |||
1366 | struct qedi_conn *qedi_conn = qedi_cmd->conn; | 1364 | struct qedi_conn *qedi_conn = qedi_cmd->conn; |
1367 | struct qedi_ctx *qedi = qedi_conn->qedi; | 1365 | struct qedi_ctx *qedi = qedi_conn->qedi; |
1368 | struct iscsi_conn *conn = qedi_conn->cls_conn->dd_data; | 1366 | struct iscsi_conn *conn = qedi_conn->cls_conn->dd_data; |
1369 | struct iscsi_cls_session *cls_sess; | ||
1370 | struct qedi_work_map *list_work = NULL; | 1367 | struct qedi_work_map *list_work = NULL; |
1371 | struct iscsi_task *mtask; | 1368 | struct iscsi_task *mtask; |
1372 | struct qedi_cmd *cmd; | 1369 | struct qedi_cmd *cmd; |
@@ -1377,7 +1374,6 @@ static void qedi_tmf_work(struct work_struct *work) | |||
1377 | 1374 | ||
1378 | mtask = qedi_cmd->task; | 1375 | mtask = qedi_cmd->task; |
1379 | tmf_hdr = (struct iscsi_tm *)mtask->hdr; | 1376 | tmf_hdr = (struct iscsi_tm *)mtask->hdr; |
1380 | cls_sess = iscsi_conn_to_session(qedi_conn->cls_conn); | ||
1381 | set_bit(QEDI_CONN_FW_CLEANUP, &qedi_conn->flags); | 1377 | set_bit(QEDI_CONN_FW_CLEANUP, &qedi_conn->flags); |
1382 | 1378 | ||
1383 | ctask = iscsi_itt_to_task(conn, tmf_hdr->rtt); | 1379 | ctask = iscsi_itt_to_task(conn, tmf_hdr->rtt); |
diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c index 6d6d6013e35b..615cea4fad56 100644 --- a/drivers/scsi/qedi/qedi_iscsi.c +++ b/drivers/scsi/qedi/qedi_iscsi.c | |||
@@ -579,7 +579,7 @@ static int qedi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
579 | rval = qedi_iscsi_update_conn(qedi, qedi_conn); | 579 | rval = qedi_iscsi_update_conn(qedi, qedi_conn); |
580 | if (rval) { | 580 | if (rval) { |
581 | iscsi_conn_printk(KERN_ALERT, conn, | 581 | iscsi_conn_printk(KERN_ALERT, conn, |
582 | "conn_start: FW oflload conn failed.\n"); | 582 | "conn_start: FW offload conn failed.\n"); |
583 | rval = -EINVAL; | 583 | rval = -EINVAL; |
584 | goto start_err; | 584 | goto start_err; |
585 | } | 585 | } |
@@ -590,7 +590,7 @@ static int qedi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
590 | rval = iscsi_conn_start(cls_conn); | 590 | rval = iscsi_conn_start(cls_conn); |
591 | if (rval) { | 591 | if (rval) { |
592 | iscsi_conn_printk(KERN_ALERT, conn, | 592 | iscsi_conn_printk(KERN_ALERT, conn, |
593 | "iscsi_conn_start: FW oflload conn failed!!\n"); | 593 | "iscsi_conn_start: FW offload conn failed!!\n"); |
594 | } | 594 | } |
595 | 595 | ||
596 | start_err: | 596 | start_err: |
@@ -993,13 +993,17 @@ static void qedi_ep_disconnect(struct iscsi_endpoint *ep) | |||
993 | struct iscsi_conn *conn = NULL; | 993 | struct iscsi_conn *conn = NULL; |
994 | struct qedi_ctx *qedi; | 994 | struct qedi_ctx *qedi; |
995 | int ret = 0; | 995 | int ret = 0; |
996 | int wait_delay = 20 * HZ; | 996 | int wait_delay; |
997 | int abrt_conn = 0; | 997 | int abrt_conn = 0; |
998 | int count = 10; | 998 | int count = 10; |
999 | 999 | ||
1000 | wait_delay = 60 * HZ + DEF_MAX_RT_TIME; | ||
1000 | qedi_ep = ep->dd_data; | 1001 | qedi_ep = ep->dd_data; |
1001 | qedi = qedi_ep->qedi; | 1002 | qedi = qedi_ep->qedi; |
1002 | 1003 | ||
1004 | if (qedi_ep->state == EP_STATE_OFLDCONN_START) | ||
1005 | goto ep_exit_recover; | ||
1006 | |||
1003 | flush_work(&qedi_ep->offload_work); | 1007 | flush_work(&qedi_ep->offload_work); |
1004 | 1008 | ||
1005 | if (qedi_ep->conn) { | 1009 | if (qedi_ep->conn) { |
@@ -1163,7 +1167,7 @@ static void qedi_offload_work(struct work_struct *work) | |||
1163 | struct qedi_endpoint *qedi_ep = | 1167 | struct qedi_endpoint *qedi_ep = |
1164 | container_of(work, struct qedi_endpoint, offload_work); | 1168 | container_of(work, struct qedi_endpoint, offload_work); |
1165 | struct qedi_ctx *qedi; | 1169 | struct qedi_ctx *qedi; |
1166 | int wait_delay = 20 * HZ; | 1170 | int wait_delay = 5 * HZ; |
1167 | int ret; | 1171 | int ret; |
1168 | 1172 | ||
1169 | qedi = qedi_ep->qedi; | 1173 | qedi = qedi_ep->qedi; |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index f928c4d3a1ef..8d560c562e9c 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -29,24 +29,27 @@ qla2x00_sysfs_read_fw_dump(struct file *filp, struct kobject *kobj, | |||
29 | if (!(ha->fw_dump_reading || ha->mctp_dump_reading)) | 29 | if (!(ha->fw_dump_reading || ha->mctp_dump_reading)) |
30 | return 0; | 30 | return 0; |
31 | 31 | ||
32 | mutex_lock(&ha->optrom_mutex); | ||
32 | if (IS_P3P_TYPE(ha)) { | 33 | if (IS_P3P_TYPE(ha)) { |
33 | if (off < ha->md_template_size) { | 34 | if (off < ha->md_template_size) { |
34 | rval = memory_read_from_buffer(buf, count, | 35 | rval = memory_read_from_buffer(buf, count, |
35 | &off, ha->md_tmplt_hdr, ha->md_template_size); | 36 | &off, ha->md_tmplt_hdr, ha->md_template_size); |
36 | return rval; | 37 | } else { |
38 | off -= ha->md_template_size; | ||
39 | rval = memory_read_from_buffer(buf, count, | ||
40 | &off, ha->md_dump, ha->md_dump_size); | ||
37 | } | 41 | } |
38 | off -= ha->md_template_size; | 42 | } else if (ha->mctp_dumped && ha->mctp_dump_reading) { |
39 | rval = memory_read_from_buffer(buf, count, | 43 | rval = memory_read_from_buffer(buf, count, &off, ha->mctp_dump, |
40 | &off, ha->md_dump, ha->md_dump_size); | ||
41 | return rval; | ||
42 | } else if (ha->mctp_dumped && ha->mctp_dump_reading) | ||
43 | return memory_read_from_buffer(buf, count, &off, ha->mctp_dump, | ||
44 | MCTP_DUMP_SIZE); | 44 | MCTP_DUMP_SIZE); |
45 | else if (ha->fw_dump_reading) | 45 | } else if (ha->fw_dump_reading) { |
46 | return memory_read_from_buffer(buf, count, &off, ha->fw_dump, | 46 | rval = memory_read_from_buffer(buf, count, &off, ha->fw_dump, |
47 | ha->fw_dump_len); | 47 | ha->fw_dump_len); |
48 | else | 48 | } else { |
49 | return 0; | 49 | rval = 0; |
50 | } | ||
51 | mutex_unlock(&ha->optrom_mutex); | ||
52 | return rval; | ||
50 | } | 53 | } |
51 | 54 | ||
52 | static ssize_t | 55 | static ssize_t |
@@ -154,6 +157,8 @@ qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj, | |||
154 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, | 157 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, |
155 | struct device, kobj))); | 158 | struct device, kobj))); |
156 | struct qla_hw_data *ha = vha->hw; | 159 | struct qla_hw_data *ha = vha->hw; |
160 | uint32_t faddr; | ||
161 | struct active_regions active_regions = { }; | ||
157 | 162 | ||
158 | if (!capable(CAP_SYS_ADMIN)) | 163 | if (!capable(CAP_SYS_ADMIN)) |
159 | return 0; | 164 | return 0; |
@@ -164,11 +169,21 @@ qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj, | |||
164 | return -EAGAIN; | 169 | return -EAGAIN; |
165 | } | 170 | } |
166 | 171 | ||
167 | if (IS_NOCACHE_VPD_TYPE(ha)) | 172 | if (!IS_NOCACHE_VPD_TYPE(ha)) { |
168 | ha->isp_ops->read_optrom(vha, ha->nvram, ha->flt_region_nvram << 2, | 173 | mutex_unlock(&ha->optrom_mutex); |
169 | ha->nvram_size); | 174 | goto skip; |
175 | } | ||
176 | |||
177 | faddr = ha->flt_region_nvram; | ||
178 | if (IS_QLA28XX(ha)) { | ||
179 | if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE) | ||
180 | faddr = ha->flt_region_nvram_sec; | ||
181 | } | ||
182 | ha->isp_ops->read_optrom(vha, ha->nvram, faddr << 2, ha->nvram_size); | ||
183 | |||
170 | mutex_unlock(&ha->optrom_mutex); | 184 | mutex_unlock(&ha->optrom_mutex); |
171 | 185 | ||
186 | skip: | ||
172 | return memory_read_from_buffer(buf, count, &off, ha->nvram, | 187 | return memory_read_from_buffer(buf, count, &off, ha->nvram, |
173 | ha->nvram_size); | 188 | ha->nvram_size); |
174 | } | 189 | } |
@@ -223,9 +238,9 @@ qla2x00_sysfs_write_nvram(struct file *filp, struct kobject *kobj, | |||
223 | } | 238 | } |
224 | 239 | ||
225 | /* Write NVRAM. */ | 240 | /* Write NVRAM. */ |
226 | ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count); | 241 | ha->isp_ops->write_nvram(vha, buf, ha->nvram_base, count); |
227 | ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base, | 242 | ha->isp_ops->read_nvram(vha, ha->nvram, ha->nvram_base, |
228 | count); | 243 | count); |
229 | mutex_unlock(&ha->optrom_mutex); | 244 | mutex_unlock(&ha->optrom_mutex); |
230 | 245 | ||
231 | ql_dbg(ql_dbg_user, vha, 0x7060, | 246 | ql_dbg(ql_dbg_user, vha, 0x7060, |
@@ -364,7 +379,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, | |||
364 | } | 379 | } |
365 | 380 | ||
366 | ha->optrom_region_start = start; | 381 | ha->optrom_region_start = start; |
367 | ha->optrom_region_size = start + size; | 382 | ha->optrom_region_size = size; |
368 | 383 | ||
369 | ha->optrom_state = QLA_SREADING; | 384 | ha->optrom_state = QLA_SREADING; |
370 | ha->optrom_buffer = vmalloc(ha->optrom_region_size); | 385 | ha->optrom_buffer = vmalloc(ha->optrom_region_size); |
@@ -418,6 +433,10 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, | |||
418 | * 0x000000 -> 0x07ffff -- Boot code. | 433 | * 0x000000 -> 0x07ffff -- Boot code. |
419 | * 0x080000 -> 0x0fffff -- Firmware. | 434 | * 0x080000 -> 0x0fffff -- Firmware. |
420 | * 0x120000 -> 0x12ffff -- VPD and HBA parameters. | 435 | * 0x120000 -> 0x12ffff -- VPD and HBA parameters. |
436 | * | ||
437 | * > ISP25xx type boards: | ||
438 | * | ||
439 | * None -- should go through BSG. | ||
421 | */ | 440 | */ |
422 | valid = 0; | 441 | valid = 0; |
423 | if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0) | 442 | if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0) |
@@ -425,9 +444,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, | |||
425 | else if (start == (ha->flt_region_boot * 4) || | 444 | else if (start == (ha->flt_region_boot * 4) || |
426 | start == (ha->flt_region_fw * 4)) | 445 | start == (ha->flt_region_fw * 4)) |
427 | valid = 1; | 446 | valid = 1; |
428 | else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) | 447 | else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) |
429 | || IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) | ||
430 | || IS_QLA27XX(ha)) | ||
431 | valid = 1; | 448 | valid = 1; |
432 | if (!valid) { | 449 | if (!valid) { |
433 | ql_log(ql_log_warn, vha, 0x7065, | 450 | ql_log(ql_log_warn, vha, 0x7065, |
@@ -437,7 +454,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, | |||
437 | } | 454 | } |
438 | 455 | ||
439 | ha->optrom_region_start = start; | 456 | ha->optrom_region_start = start; |
440 | ha->optrom_region_size = start + size; | 457 | ha->optrom_region_size = size; |
441 | 458 | ||
442 | ha->optrom_state = QLA_SWRITING; | 459 | ha->optrom_state = QLA_SWRITING; |
443 | ha->optrom_buffer = vmalloc(ha->optrom_region_size); | 460 | ha->optrom_buffer = vmalloc(ha->optrom_region_size); |
@@ -504,6 +521,7 @@ qla2x00_sysfs_read_vpd(struct file *filp, struct kobject *kobj, | |||
504 | struct device, kobj))); | 521 | struct device, kobj))); |
505 | struct qla_hw_data *ha = vha->hw; | 522 | struct qla_hw_data *ha = vha->hw; |
506 | uint32_t faddr; | 523 | uint32_t faddr; |
524 | struct active_regions active_regions = { }; | ||
507 | 525 | ||
508 | if (unlikely(pci_channel_offline(ha->pdev))) | 526 | if (unlikely(pci_channel_offline(ha->pdev))) |
509 | return -EAGAIN; | 527 | return -EAGAIN; |
@@ -511,22 +529,33 @@ qla2x00_sysfs_read_vpd(struct file *filp, struct kobject *kobj, | |||
511 | if (!capable(CAP_SYS_ADMIN)) | 529 | if (!capable(CAP_SYS_ADMIN)) |
512 | return -EINVAL; | 530 | return -EINVAL; |
513 | 531 | ||
514 | if (IS_NOCACHE_VPD_TYPE(ha)) { | 532 | if (IS_NOCACHE_VPD_TYPE(ha)) |
515 | faddr = ha->flt_region_vpd << 2; | 533 | goto skip; |
534 | |||
535 | faddr = ha->flt_region_vpd << 2; | ||
516 | 536 | ||
517 | if (IS_QLA27XX(ha) && | 537 | if (IS_QLA28XX(ha)) { |
518 | qla27xx_find_valid_image(vha) == QLA27XX_SECONDARY_IMAGE) | 538 | qla28xx_get_aux_images(vha, &active_regions); |
539 | if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE) | ||
519 | faddr = ha->flt_region_vpd_sec << 2; | 540 | faddr = ha->flt_region_vpd_sec << 2; |
520 | 541 | ||
521 | mutex_lock(&ha->optrom_mutex); | 542 | ql_dbg(ql_dbg_init, vha, 0x7070, |
522 | if (qla2x00_chip_is_down(vha)) { | 543 | "Loading %s nvram image.\n", |
523 | mutex_unlock(&ha->optrom_mutex); | 544 | active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ? |
524 | return -EAGAIN; | 545 | "primary" : "secondary"); |
525 | } | 546 | } |
526 | ha->isp_ops->read_optrom(vha, ha->vpd, faddr, | 547 | |
527 | ha->vpd_size); | 548 | mutex_lock(&ha->optrom_mutex); |
549 | if (qla2x00_chip_is_down(vha)) { | ||
528 | mutex_unlock(&ha->optrom_mutex); | 550 | mutex_unlock(&ha->optrom_mutex); |
551 | return -EAGAIN; | ||
529 | } | 552 | } |
553 | |||
554 | ha->isp_ops->read_optrom(vha, ha->vpd, faddr, ha->vpd_size); | ||
555 | mutex_unlock(&ha->optrom_mutex); | ||
556 | |||
557 | ha->isp_ops->read_optrom(vha, ha->vpd, faddr, ha->vpd_size); | ||
558 | skip: | ||
530 | return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size); | 559 | return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size); |
531 | } | 560 | } |
532 | 561 | ||
@@ -563,8 +592,8 @@ qla2x00_sysfs_write_vpd(struct file *filp, struct kobject *kobj, | |||
563 | } | 592 | } |
564 | 593 | ||
565 | /* Write NVRAM. */ | 594 | /* Write NVRAM. */ |
566 | ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count); | 595 | ha->isp_ops->write_nvram(vha, buf, ha->vpd_base, count); |
567 | ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count); | 596 | ha->isp_ops->read_nvram(vha, ha->vpd, ha->vpd_base, count); |
568 | 597 | ||
569 | /* Update flash version information for 4Gb & above. */ | 598 | /* Update flash version information for 4Gb & above. */ |
570 | if (!IS_FWI2_CAPABLE(ha)) { | 599 | if (!IS_FWI2_CAPABLE(ha)) { |
@@ -645,6 +674,7 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj, | |||
645 | int type; | 674 | int type; |
646 | uint32_t idc_control; | 675 | uint32_t idc_control; |
647 | uint8_t *tmp_data = NULL; | 676 | uint8_t *tmp_data = NULL; |
677 | |||
648 | if (off != 0) | 678 | if (off != 0) |
649 | return -EINVAL; | 679 | return -EINVAL; |
650 | 680 | ||
@@ -682,7 +712,7 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj, | |||
682 | ql_log(ql_log_info, vha, 0x706f, | 712 | ql_log(ql_log_info, vha, 0x706f, |
683 | "Issuing MPI reset.\n"); | 713 | "Issuing MPI reset.\n"); |
684 | 714 | ||
685 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 715 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
686 | uint32_t idc_control; | 716 | uint32_t idc_control; |
687 | 717 | ||
688 | qla83xx_idc_lock(vha, 0); | 718 | qla83xx_idc_lock(vha, 0); |
@@ -858,7 +888,7 @@ do_read: | |||
858 | count = 0; | 888 | count = 0; |
859 | } | 889 | } |
860 | 890 | ||
861 | count = actual_size > count ? count: actual_size; | 891 | count = actual_size > count ? count : actual_size; |
862 | memcpy(buf, ha->xgmac_data, count); | 892 | memcpy(buf, ha->xgmac_data, count); |
863 | 893 | ||
864 | return count; | 894 | return count; |
@@ -934,7 +964,7 @@ static struct bin_attribute sysfs_dcbx_tlv_attr = { | |||
934 | static struct sysfs_entry { | 964 | static struct sysfs_entry { |
935 | char *name; | 965 | char *name; |
936 | struct bin_attribute *attr; | 966 | struct bin_attribute *attr; |
937 | int is4GBp_only; | 967 | int type; |
938 | } bin_file_entries[] = { | 968 | } bin_file_entries[] = { |
939 | { "fw_dump", &sysfs_fw_dump_attr, }, | 969 | { "fw_dump", &sysfs_fw_dump_attr, }, |
940 | { "nvram", &sysfs_nvram_attr, }, | 970 | { "nvram", &sysfs_nvram_attr, }, |
@@ -957,11 +987,11 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha) | |||
957 | int ret; | 987 | int ret; |
958 | 988 | ||
959 | for (iter = bin_file_entries; iter->name; iter++) { | 989 | for (iter = bin_file_entries; iter->name; iter++) { |
960 | if (iter->is4GBp_only && !IS_FWI2_CAPABLE(vha->hw)) | 990 | if (iter->type && !IS_FWI2_CAPABLE(vha->hw)) |
961 | continue; | 991 | continue; |
962 | if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw)) | 992 | if (iter->type == 2 && !IS_QLA25XX(vha->hw)) |
963 | continue; | 993 | continue; |
964 | if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw))) | 994 | if (iter->type == 3 && !(IS_CNA_CAPABLE(vha->hw))) |
965 | continue; | 995 | continue; |
966 | 996 | ||
967 | ret = sysfs_create_bin_file(&host->shost_gendev.kobj, | 997 | ret = sysfs_create_bin_file(&host->shost_gendev.kobj, |
@@ -985,13 +1015,14 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha, bool stop_beacon) | |||
985 | struct qla_hw_data *ha = vha->hw; | 1015 | struct qla_hw_data *ha = vha->hw; |
986 | 1016 | ||
987 | for (iter = bin_file_entries; iter->name; iter++) { | 1017 | for (iter = bin_file_entries; iter->name; iter++) { |
988 | if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha)) | 1018 | if (iter->type && !IS_FWI2_CAPABLE(ha)) |
989 | continue; | 1019 | continue; |
990 | if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha)) | 1020 | if (iter->type == 2 && !IS_QLA25XX(ha)) |
991 | continue; | 1021 | continue; |
992 | if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw))) | 1022 | if (iter->type == 3 && !(IS_CNA_CAPABLE(ha))) |
993 | continue; | 1023 | continue; |
994 | if (iter->is4GBp_only == 0x27 && !IS_QLA27XX(vha->hw)) | 1024 | if (iter->type == 0x27 && |
1025 | (!IS_QLA27XX(ha) || !IS_QLA28XX(ha))) | ||
995 | continue; | 1026 | continue; |
996 | 1027 | ||
997 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | 1028 | sysfs_remove_bin_file(&host->shost_gendev.kobj, |
@@ -1049,6 +1080,7 @@ qla2x00_isp_name_show(struct device *dev, struct device_attribute *attr, | |||
1049 | char *buf) | 1080 | char *buf) |
1050 | { | 1081 | { |
1051 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1082 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1083 | |||
1052 | return scnprintf(buf, PAGE_SIZE, "ISP%04X\n", vha->hw->pdev->device); | 1084 | return scnprintf(buf, PAGE_SIZE, "ISP%04X\n", vha->hw->pdev->device); |
1053 | } | 1085 | } |
1054 | 1086 | ||
@@ -1082,6 +1114,7 @@ qla2x00_model_desc_show(struct device *dev, struct device_attribute *attr, | |||
1082 | char *buf) | 1114 | char *buf) |
1083 | { | 1115 | { |
1084 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1116 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1117 | |||
1085 | return scnprintf(buf, PAGE_SIZE, "%s\n", vha->hw->model_desc); | 1118 | return scnprintf(buf, PAGE_SIZE, "%s\n", vha->hw->model_desc); |
1086 | } | 1119 | } |
1087 | 1120 | ||
@@ -1294,6 +1327,7 @@ qla2x00_optrom_bios_version_show(struct device *dev, | |||
1294 | { | 1327 | { |
1295 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1328 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1296 | struct qla_hw_data *ha = vha->hw; | 1329 | struct qla_hw_data *ha = vha->hw; |
1330 | |||
1297 | return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1], | 1331 | return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1], |
1298 | ha->bios_revision[0]); | 1332 | ha->bios_revision[0]); |
1299 | } | 1333 | } |
@@ -1304,6 +1338,7 @@ qla2x00_optrom_efi_version_show(struct device *dev, | |||
1304 | { | 1338 | { |
1305 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1339 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1306 | struct qla_hw_data *ha = vha->hw; | 1340 | struct qla_hw_data *ha = vha->hw; |
1341 | |||
1307 | return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1], | 1342 | return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1], |
1308 | ha->efi_revision[0]); | 1343 | ha->efi_revision[0]); |
1309 | } | 1344 | } |
@@ -1314,6 +1349,7 @@ qla2x00_optrom_fcode_version_show(struct device *dev, | |||
1314 | { | 1349 | { |
1315 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1350 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1316 | struct qla_hw_data *ha = vha->hw; | 1351 | struct qla_hw_data *ha = vha->hw; |
1352 | |||
1317 | return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1], | 1353 | return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1], |
1318 | ha->fcode_revision[0]); | 1354 | ha->fcode_revision[0]); |
1319 | } | 1355 | } |
@@ -1324,6 +1360,7 @@ qla2x00_optrom_fw_version_show(struct device *dev, | |||
1324 | { | 1360 | { |
1325 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1361 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1326 | struct qla_hw_data *ha = vha->hw; | 1362 | struct qla_hw_data *ha = vha->hw; |
1363 | |||
1327 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n", | 1364 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n", |
1328 | ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2], | 1365 | ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2], |
1329 | ha->fw_revision[3]); | 1366 | ha->fw_revision[3]); |
@@ -1336,7 +1373,8 @@ qla2x00_optrom_gold_fw_version_show(struct device *dev, | |||
1336 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1373 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1337 | struct qla_hw_data *ha = vha->hw; | 1374 | struct qla_hw_data *ha = vha->hw; |
1338 | 1375 | ||
1339 | if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA27XX(ha)) | 1376 | if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
1377 | !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) | ||
1340 | return scnprintf(buf, PAGE_SIZE, "\n"); | 1378 | return scnprintf(buf, PAGE_SIZE, "\n"); |
1341 | 1379 | ||
1342 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%d)\n", | 1380 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%d)\n", |
@@ -1349,6 +1387,7 @@ qla2x00_total_isp_aborts_show(struct device *dev, | |||
1349 | struct device_attribute *attr, char *buf) | 1387 | struct device_attribute *attr, char *buf) |
1350 | { | 1388 | { |
1351 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1389 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1390 | |||
1352 | return scnprintf(buf, PAGE_SIZE, "%d\n", | 1391 | return scnprintf(buf, PAGE_SIZE, "%d\n", |
1353 | vha->qla_stats.total_isp_aborts); | 1392 | vha->qla_stats.total_isp_aborts); |
1354 | } | 1393 | } |
@@ -1358,24 +1397,40 @@ qla24xx_84xx_fw_version_show(struct device *dev, | |||
1358 | struct device_attribute *attr, char *buf) | 1397 | struct device_attribute *attr, char *buf) |
1359 | { | 1398 | { |
1360 | int rval = QLA_SUCCESS; | 1399 | int rval = QLA_SUCCESS; |
1361 | uint16_t status[2] = {0, 0}; | 1400 | uint16_t status[2] = { 0 }; |
1362 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1401 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1363 | struct qla_hw_data *ha = vha->hw; | 1402 | struct qla_hw_data *ha = vha->hw; |
1364 | 1403 | ||
1365 | if (!IS_QLA84XX(ha)) | 1404 | if (!IS_QLA84XX(ha)) |
1366 | return scnprintf(buf, PAGE_SIZE, "\n"); | 1405 | return scnprintf(buf, PAGE_SIZE, "\n"); |
1367 | 1406 | ||
1368 | if (ha->cs84xx->op_fw_version == 0) | 1407 | if (!ha->cs84xx->op_fw_version) { |
1369 | rval = qla84xx_verify_chip(vha, status); | 1408 | rval = qla84xx_verify_chip(vha, status); |
1370 | 1409 | ||
1371 | if ((rval == QLA_SUCCESS) && (status[0] == 0)) | 1410 | if (!rval && !status[0]) |
1372 | return scnprintf(buf, PAGE_SIZE, "%u\n", | 1411 | return scnprintf(buf, PAGE_SIZE, "%u\n", |
1373 | (uint32_t)ha->cs84xx->op_fw_version); | 1412 | (uint32_t)ha->cs84xx->op_fw_version); |
1413 | } | ||
1374 | 1414 | ||
1375 | return scnprintf(buf, PAGE_SIZE, "\n"); | 1415 | return scnprintf(buf, PAGE_SIZE, "\n"); |
1376 | } | 1416 | } |
1377 | 1417 | ||
1378 | static ssize_t | 1418 | static ssize_t |
1419 | qla2x00_serdes_version_show(struct device *dev, struct device_attribute *attr, | ||
1420 | char *buf) | ||
1421 | { | ||
1422 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | ||
1423 | struct qla_hw_data *ha = vha->hw; | ||
1424 | |||
1425 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) | ||
1426 | return scnprintf(buf, PAGE_SIZE, "\n"); | ||
1427 | |||
1428 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n", | ||
1429 | ha->serdes_version[0], ha->serdes_version[1], | ||
1430 | ha->serdes_version[2]); | ||
1431 | } | ||
1432 | |||
1433 | static ssize_t | ||
1379 | qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr, | 1434 | qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr, |
1380 | char *buf) | 1435 | char *buf) |
1381 | { | 1436 | { |
@@ -1383,7 +1438,7 @@ qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr, | |||
1383 | struct qla_hw_data *ha = vha->hw; | 1438 | struct qla_hw_data *ha = vha->hw; |
1384 | 1439 | ||
1385 | if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha) && | 1440 | if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha) && |
1386 | !IS_QLA27XX(ha)) | 1441 | !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
1387 | return scnprintf(buf, PAGE_SIZE, "\n"); | 1442 | return scnprintf(buf, PAGE_SIZE, "\n"); |
1388 | 1443 | ||
1389 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n", | 1444 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n", |
@@ -1596,7 +1651,7 @@ qla2x00_pep_version_show(struct device *dev, struct device_attribute *attr, | |||
1596 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1651 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1597 | struct qla_hw_data *ha = vha->hw; | 1652 | struct qla_hw_data *ha = vha->hw; |
1598 | 1653 | ||
1599 | if (!IS_QLA27XX(ha)) | 1654 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
1600 | return scnprintf(buf, PAGE_SIZE, "\n"); | 1655 | return scnprintf(buf, PAGE_SIZE, "\n"); |
1601 | 1656 | ||
1602 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n", | 1657 | return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n", |
@@ -1604,35 +1659,38 @@ qla2x00_pep_version_show(struct device *dev, struct device_attribute *attr, | |||
1604 | } | 1659 | } |
1605 | 1660 | ||
1606 | static ssize_t | 1661 | static ssize_t |
1607 | qla2x00_min_link_speed_show(struct device *dev, struct device_attribute *attr, | 1662 | qla2x00_min_supported_speed_show(struct device *dev, |
1608 | char *buf) | 1663 | struct device_attribute *attr, char *buf) |
1609 | { | 1664 | { |
1610 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1665 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1611 | struct qla_hw_data *ha = vha->hw; | 1666 | struct qla_hw_data *ha = vha->hw; |
1612 | 1667 | ||
1613 | if (!IS_QLA27XX(ha)) | 1668 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
1614 | return scnprintf(buf, PAGE_SIZE, "\n"); | 1669 | return scnprintf(buf, PAGE_SIZE, "\n"); |
1615 | 1670 | ||
1616 | return scnprintf(buf, PAGE_SIZE, "%s\n", | 1671 | return scnprintf(buf, PAGE_SIZE, "%s\n", |
1617 | ha->min_link_speed == 5 ? "32Gps" : | 1672 | ha->min_supported_speed == 6 ? "64Gps" : |
1618 | ha->min_link_speed == 4 ? "16Gps" : | 1673 | ha->min_supported_speed == 5 ? "32Gps" : |
1619 | ha->min_link_speed == 3 ? "8Gps" : | 1674 | ha->min_supported_speed == 4 ? "16Gps" : |
1620 | ha->min_link_speed == 2 ? "4Gps" : | 1675 | ha->min_supported_speed == 3 ? "8Gps" : |
1621 | ha->min_link_speed != 0 ? "unknown" : ""); | 1676 | ha->min_supported_speed == 2 ? "4Gps" : |
1677 | ha->min_supported_speed != 0 ? "unknown" : ""); | ||
1622 | } | 1678 | } |
1623 | 1679 | ||
1624 | static ssize_t | 1680 | static ssize_t |
1625 | qla2x00_max_speed_sup_show(struct device *dev, struct device_attribute *attr, | 1681 | qla2x00_max_supported_speed_show(struct device *dev, |
1626 | char *buf) | 1682 | struct device_attribute *attr, char *buf) |
1627 | { | 1683 | { |
1628 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1684 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1629 | struct qla_hw_data *ha = vha->hw; | 1685 | struct qla_hw_data *ha = vha->hw; |
1630 | 1686 | ||
1631 | if (!IS_QLA27XX(ha)) | 1687 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
1632 | return scnprintf(buf, PAGE_SIZE, "\n"); | 1688 | return scnprintf(buf, PAGE_SIZE, "\n"); |
1633 | 1689 | ||
1634 | return scnprintf(buf, PAGE_SIZE, "%s\n", | 1690 | return scnprintf(buf, PAGE_SIZE, "%s\n", |
1635 | ha->max_speed_sup ? "32Gps" : "16Gps"); | 1691 | ha->max_supported_speed == 2 ? "64Gps" : |
1692 | ha->max_supported_speed == 1 ? "32Gps" : | ||
1693 | ha->max_supported_speed == 0 ? "16Gps" : "unknown"); | ||
1636 | } | 1694 | } |
1637 | 1695 | ||
1638 | static ssize_t | 1696 | static ssize_t |
@@ -1645,7 +1703,7 @@ qla2x00_port_speed_store(struct device *dev, struct device_attribute *attr, | |||
1645 | int mode = QLA_SET_DATA_RATE_LR; | 1703 | int mode = QLA_SET_DATA_RATE_LR; |
1646 | struct qla_hw_data *ha = vha->hw; | 1704 | struct qla_hw_data *ha = vha->hw; |
1647 | 1705 | ||
1648 | if (!IS_QLA27XX(vha->hw)) { | 1706 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) { |
1649 | ql_log(ql_log_warn, vha, 0x70d8, | 1707 | ql_log(ql_log_warn, vha, 0x70d8, |
1650 | "Speed setting not supported \n"); | 1708 | "Speed setting not supported \n"); |
1651 | return -EINVAL; | 1709 | return -EINVAL; |
@@ -2164,6 +2222,32 @@ qla2x00_dif_bundle_statistics_show(struct device *dev, | |||
2164 | ha->dif_bundle_dma_allocs, ha->pool.unusable.count); | 2222 | ha->dif_bundle_dma_allocs, ha->pool.unusable.count); |
2165 | } | 2223 | } |
2166 | 2224 | ||
2225 | static ssize_t | ||
2226 | qla2x00_fw_attr_show(struct device *dev, | ||
2227 | struct device_attribute *attr, char *buf) | ||
2228 | { | ||
2229 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | ||
2230 | struct qla_hw_data *ha = vha->hw; | ||
2231 | |||
2232 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) | ||
2233 | return scnprintf(buf, PAGE_SIZE, "\n"); | ||
2234 | |||
2235 | return scnprintf(buf, PAGE_SIZE, "%llx\n", | ||
2236 | (uint64_t)ha->fw_attributes_ext[1] << 48 | | ||
2237 | (uint64_t)ha->fw_attributes_ext[0] << 32 | | ||
2238 | (uint64_t)ha->fw_attributes_h << 16 | | ||
2239 | (uint64_t)ha->fw_attributes); | ||
2240 | } | ||
2241 | |||
2242 | static ssize_t | ||
2243 | qla2x00_port_no_show(struct device *dev, struct device_attribute *attr, | ||
2244 | char *buf) | ||
2245 | { | ||
2246 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | ||
2247 | |||
2248 | return scnprintf(buf, PAGE_SIZE, "%u\n", vha->hw->port_no); | ||
2249 | } | ||
2250 | |||
2167 | static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_driver_version_show, NULL); | 2251 | static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_driver_version_show, NULL); |
2168 | static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); | 2252 | static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); |
2169 | static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); | 2253 | static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); |
@@ -2192,6 +2276,7 @@ static DEVICE_ATTR(84xx_fw_version, S_IRUGO, qla24xx_84xx_fw_version_show, | |||
2192 | NULL); | 2276 | NULL); |
2193 | static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show, | 2277 | static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show, |
2194 | NULL); | 2278 | NULL); |
2279 | static DEVICE_ATTR(serdes_version, 0444, qla2x00_serdes_version_show, NULL); | ||
2195 | static DEVICE_ATTR(mpi_version, S_IRUGO, qla2x00_mpi_version_show, NULL); | 2280 | static DEVICE_ATTR(mpi_version, S_IRUGO, qla2x00_mpi_version_show, NULL); |
2196 | static DEVICE_ATTR(phy_version, S_IRUGO, qla2x00_phy_version_show, NULL); | 2281 | static DEVICE_ATTR(phy_version, S_IRUGO, qla2x00_phy_version_show, NULL); |
2197 | static DEVICE_ATTR(flash_block_size, S_IRUGO, qla2x00_flash_block_size_show, | 2282 | static DEVICE_ATTR(flash_block_size, S_IRUGO, qla2x00_flash_block_size_show, |
@@ -2209,8 +2294,10 @@ static DEVICE_ATTR(allow_cna_fw_dump, S_IRUGO | S_IWUSR, | |||
2209 | qla2x00_allow_cna_fw_dump_show, | 2294 | qla2x00_allow_cna_fw_dump_show, |
2210 | qla2x00_allow_cna_fw_dump_store); | 2295 | qla2x00_allow_cna_fw_dump_store); |
2211 | static DEVICE_ATTR(pep_version, S_IRUGO, qla2x00_pep_version_show, NULL); | 2296 | static DEVICE_ATTR(pep_version, S_IRUGO, qla2x00_pep_version_show, NULL); |
2212 | static DEVICE_ATTR(min_link_speed, S_IRUGO, qla2x00_min_link_speed_show, NULL); | 2297 | static DEVICE_ATTR(min_supported_speed, 0444, |
2213 | static DEVICE_ATTR(max_speed_sup, S_IRUGO, qla2x00_max_speed_sup_show, NULL); | 2298 | qla2x00_min_supported_speed_show, NULL); |
2299 | static DEVICE_ATTR(max_supported_speed, 0444, | ||
2300 | qla2x00_max_supported_speed_show, NULL); | ||
2214 | static DEVICE_ATTR(zio_threshold, 0644, | 2301 | static DEVICE_ATTR(zio_threshold, 0644, |
2215 | qla_zio_threshold_show, | 2302 | qla_zio_threshold_show, |
2216 | qla_zio_threshold_store); | 2303 | qla_zio_threshold_store); |
@@ -2221,6 +2308,8 @@ static DEVICE_ATTR(dif_bundle_statistics, 0444, | |||
2221 | qla2x00_dif_bundle_statistics_show, NULL); | 2308 | qla2x00_dif_bundle_statistics_show, NULL); |
2222 | static DEVICE_ATTR(port_speed, 0644, qla2x00_port_speed_show, | 2309 | static DEVICE_ATTR(port_speed, 0644, qla2x00_port_speed_show, |
2223 | qla2x00_port_speed_store); | 2310 | qla2x00_port_speed_store); |
2311 | static DEVICE_ATTR(port_no, 0444, qla2x00_port_no_show, NULL); | ||
2312 | static DEVICE_ATTR(fw_attr, 0444, qla2x00_fw_attr_show, NULL); | ||
2224 | 2313 | ||
2225 | 2314 | ||
2226 | struct device_attribute *qla2x00_host_attrs[] = { | 2315 | struct device_attribute *qla2x00_host_attrs[] = { |
@@ -2242,6 +2331,7 @@ struct device_attribute *qla2x00_host_attrs[] = { | |||
2242 | &dev_attr_optrom_fw_version, | 2331 | &dev_attr_optrom_fw_version, |
2243 | &dev_attr_84xx_fw_version, | 2332 | &dev_attr_84xx_fw_version, |
2244 | &dev_attr_total_isp_aborts, | 2333 | &dev_attr_total_isp_aborts, |
2334 | &dev_attr_serdes_version, | ||
2245 | &dev_attr_mpi_version, | 2335 | &dev_attr_mpi_version, |
2246 | &dev_attr_phy_version, | 2336 | &dev_attr_phy_version, |
2247 | &dev_attr_flash_block_size, | 2337 | &dev_attr_flash_block_size, |
@@ -2256,11 +2346,13 @@ struct device_attribute *qla2x00_host_attrs[] = { | |||
2256 | &dev_attr_fw_dump_size, | 2346 | &dev_attr_fw_dump_size, |
2257 | &dev_attr_allow_cna_fw_dump, | 2347 | &dev_attr_allow_cna_fw_dump, |
2258 | &dev_attr_pep_version, | 2348 | &dev_attr_pep_version, |
2259 | &dev_attr_min_link_speed, | 2349 | &dev_attr_min_supported_speed, |
2260 | &dev_attr_max_speed_sup, | 2350 | &dev_attr_max_supported_speed, |
2261 | &dev_attr_zio_threshold, | 2351 | &dev_attr_zio_threshold, |
2262 | &dev_attr_dif_bundle_statistics, | 2352 | &dev_attr_dif_bundle_statistics, |
2263 | &dev_attr_port_speed, | 2353 | &dev_attr_port_speed, |
2354 | &dev_attr_port_no, | ||
2355 | &dev_attr_fw_attr, | ||
2264 | NULL, /* reserve for qlini_mode */ | 2356 | NULL, /* reserve for qlini_mode */ |
2265 | NULL, /* reserve for ql2xiniexchg */ | 2357 | NULL, /* reserve for ql2xiniexchg */ |
2266 | NULL, /* reserve for ql2xexchoffld */ | 2358 | NULL, /* reserve for ql2xexchoffld */ |
@@ -2296,16 +2388,15 @@ qla2x00_get_host_port_id(struct Scsi_Host *shost) | |||
2296 | static void | 2388 | static void |
2297 | qla2x00_get_host_speed(struct Scsi_Host *shost) | 2389 | qla2x00_get_host_speed(struct Scsi_Host *shost) |
2298 | { | 2390 | { |
2299 | struct qla_hw_data *ha = ((struct scsi_qla_host *) | 2391 | scsi_qla_host_t *vha = shost_priv(shost); |
2300 | (shost_priv(shost)))->hw; | 2392 | u32 speed; |
2301 | u32 speed = FC_PORTSPEED_UNKNOWN; | ||
2302 | 2393 | ||
2303 | if (IS_QLAFX00(ha)) { | 2394 | if (IS_QLAFX00(vha->hw)) { |
2304 | qlafx00_get_host_speed(shost); | 2395 | qlafx00_get_host_speed(shost); |
2305 | return; | 2396 | return; |
2306 | } | 2397 | } |
2307 | 2398 | ||
2308 | switch (ha->link_data_rate) { | 2399 | switch (vha->hw->link_data_rate) { |
2309 | case PORT_SPEED_1GB: | 2400 | case PORT_SPEED_1GB: |
2310 | speed = FC_PORTSPEED_1GBIT; | 2401 | speed = FC_PORTSPEED_1GBIT; |
2311 | break; | 2402 | break; |
@@ -2327,7 +2418,14 @@ qla2x00_get_host_speed(struct Scsi_Host *shost) | |||
2327 | case PORT_SPEED_32GB: | 2418 | case PORT_SPEED_32GB: |
2328 | speed = FC_PORTSPEED_32GBIT; | 2419 | speed = FC_PORTSPEED_32GBIT; |
2329 | break; | 2420 | break; |
2421 | case PORT_SPEED_64GB: | ||
2422 | speed = FC_PORTSPEED_64GBIT; | ||
2423 | break; | ||
2424 | default: | ||
2425 | speed = FC_PORTSPEED_UNKNOWN; | ||
2426 | break; | ||
2330 | } | 2427 | } |
2428 | |||
2331 | fc_host_speed(shost) = speed; | 2429 | fc_host_speed(shost) = speed; |
2332 | } | 2430 | } |
2333 | 2431 | ||
@@ -2335,7 +2433,7 @@ static void | |||
2335 | qla2x00_get_host_port_type(struct Scsi_Host *shost) | 2433 | qla2x00_get_host_port_type(struct Scsi_Host *shost) |
2336 | { | 2434 | { |
2337 | scsi_qla_host_t *vha = shost_priv(shost); | 2435 | scsi_qla_host_t *vha = shost_priv(shost); |
2338 | uint32_t port_type = FC_PORTTYPE_UNKNOWN; | 2436 | uint32_t port_type; |
2339 | 2437 | ||
2340 | if (vha->vp_idx) { | 2438 | if (vha->vp_idx) { |
2341 | fc_host_port_type(shost) = FC_PORTTYPE_NPIV; | 2439 | fc_host_port_type(shost) = FC_PORTTYPE_NPIV; |
@@ -2354,7 +2452,11 @@ qla2x00_get_host_port_type(struct Scsi_Host *shost) | |||
2354 | case ISP_CFG_F: | 2452 | case ISP_CFG_F: |
2355 | port_type = FC_PORTTYPE_NPORT; | 2453 | port_type = FC_PORTTYPE_NPORT; |
2356 | break; | 2454 | break; |
2455 | default: | ||
2456 | port_type = FC_PORTTYPE_UNKNOWN; | ||
2457 | break; | ||
2357 | } | 2458 | } |
2459 | |||
2358 | fc_host_port_type(shost) = port_type; | 2460 | fc_host_port_type(shost) = port_type; |
2359 | } | 2461 | } |
2360 | 2462 | ||
@@ -2416,13 +2518,10 @@ qla2x00_get_starget_port_id(struct scsi_target *starget) | |||
2416 | fc_starget_port_id(starget) = port_id; | 2518 | fc_starget_port_id(starget) = port_id; |
2417 | } | 2519 | } |
2418 | 2520 | ||
2419 | static void | 2521 | static inline void |
2420 | qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) | 2522 | qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) |
2421 | { | 2523 | { |
2422 | if (timeout) | 2524 | rport->dev_loss_tmo = timeout ? timeout : 1; |
2423 | rport->dev_loss_tmo = timeout; | ||
2424 | else | ||
2425 | rport->dev_loss_tmo = 1; | ||
2426 | } | 2525 | } |
2427 | 2526 | ||
2428 | static void | 2527 | static void |
@@ -2632,8 +2731,9 @@ static void | |||
2632 | qla2x00_get_host_fabric_name(struct Scsi_Host *shost) | 2731 | qla2x00_get_host_fabric_name(struct Scsi_Host *shost) |
2633 | { | 2732 | { |
2634 | scsi_qla_host_t *vha = shost_priv(shost); | 2733 | scsi_qla_host_t *vha = shost_priv(shost); |
2635 | uint8_t node_name[WWN_SIZE] = { 0xFF, 0xFF, 0xFF, 0xFF, \ | 2734 | static const uint8_t node_name[WWN_SIZE] = { |
2636 | 0xFF, 0xFF, 0xFF, 0xFF}; | 2735 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF |
2736 | }; | ||
2637 | u64 fabric_name = wwn_to_u64(node_name); | 2737 | u64 fabric_name = wwn_to_u64(node_name); |
2638 | 2738 | ||
2639 | if (vha->device_flags & SWITCH_FOUND) | 2739 | if (vha->device_flags & SWITCH_FOUND) |
@@ -2711,8 +2811,8 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) | |||
2711 | 2811 | ||
2712 | /* initialized vport states */ | 2812 | /* initialized vport states */ |
2713 | atomic_set(&vha->loop_state, LOOP_DOWN); | 2813 | atomic_set(&vha->loop_state, LOOP_DOWN); |
2714 | vha->vp_err_state= VP_ERR_PORTDWN; | 2814 | vha->vp_err_state = VP_ERR_PORTDWN; |
2715 | vha->vp_prev_err_state= VP_ERR_UNKWN; | 2815 | vha->vp_prev_err_state = VP_ERR_UNKWN; |
2716 | /* Check if physical ha port is Up */ | 2816 | /* Check if physical ha port is Up */ |
2717 | if (atomic_read(&base_vha->loop_state) == LOOP_DOWN || | 2817 | if (atomic_read(&base_vha->loop_state) == LOOP_DOWN || |
2718 | atomic_read(&base_vha->loop_state) == LOOP_DEAD) { | 2818 | atomic_read(&base_vha->loop_state) == LOOP_DEAD) { |
@@ -2727,6 +2827,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) | |||
2727 | if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { | 2827 | if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { |
2728 | if (ha->fw_attributes & BIT_4) { | 2828 | if (ha->fw_attributes & BIT_4) { |
2729 | int prot = 0, guard; | 2829 | int prot = 0, guard; |
2830 | |||
2730 | vha->flags.difdix_supported = 1; | 2831 | vha->flags.difdix_supported = 1; |
2731 | ql_dbg(ql_dbg_user, vha, 0x7082, | 2832 | ql_dbg(ql_dbg_user, vha, 0x7082, |
2732 | "Registered for DIF/DIX type 1 and 3 protection.\n"); | 2833 | "Registered for DIF/DIX type 1 and 3 protection.\n"); |
@@ -2977,7 +3078,7 @@ void | |||
2977 | qla2x00_init_host_attr(scsi_qla_host_t *vha) | 3078 | qla2x00_init_host_attr(scsi_qla_host_t *vha) |
2978 | { | 3079 | { |
2979 | struct qla_hw_data *ha = vha->hw; | 3080 | struct qla_hw_data *ha = vha->hw; |
2980 | u32 speed = FC_PORTSPEED_UNKNOWN; | 3081 | u32 speeds = FC_PORTSPEED_UNKNOWN; |
2981 | 3082 | ||
2982 | fc_host_dev_loss_tmo(vha->host) = ha->port_down_retry_count; | 3083 | fc_host_dev_loss_tmo(vha->host) = ha->port_down_retry_count; |
2983 | fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name); | 3084 | fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name); |
@@ -2988,25 +3089,45 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha) | |||
2988 | fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count; | 3089 | fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count; |
2989 | 3090 | ||
2990 | if (IS_CNA_CAPABLE(ha)) | 3091 | if (IS_CNA_CAPABLE(ha)) |
2991 | speed = FC_PORTSPEED_10GBIT; | 3092 | speeds = FC_PORTSPEED_10GBIT; |
2992 | else if (IS_QLA2031(ha)) | 3093 | else if (IS_QLA28XX(ha) || IS_QLA27XX(ha)) { |
2993 | speed = FC_PORTSPEED_16GBIT | FC_PORTSPEED_8GBIT | | 3094 | if (ha->max_supported_speed == 2) { |
2994 | FC_PORTSPEED_4GBIT; | 3095 | if (ha->min_supported_speed <= 6) |
2995 | else if (IS_QLA25XX(ha)) | 3096 | speeds |= FC_PORTSPEED_64GBIT; |
2996 | speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | | 3097 | } |
2997 | FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; | 3098 | if (ha->max_supported_speed == 2 || |
3099 | ha->max_supported_speed == 1) { | ||
3100 | if (ha->min_supported_speed <= 5) | ||
3101 | speeds |= FC_PORTSPEED_32GBIT; | ||
3102 | } | ||
3103 | if (ha->max_supported_speed == 2 || | ||
3104 | ha->max_supported_speed == 1 || | ||
3105 | ha->max_supported_speed == 0) { | ||
3106 | if (ha->min_supported_speed <= 4) | ||
3107 | speeds |= FC_PORTSPEED_16GBIT; | ||
3108 | } | ||
3109 | if (ha->max_supported_speed == 1 || | ||
3110 | ha->max_supported_speed == 0) { | ||
3111 | if (ha->min_supported_speed <= 3) | ||
3112 | speeds |= FC_PORTSPEED_8GBIT; | ||
3113 | } | ||
3114 | if (ha->max_supported_speed == 0) { | ||
3115 | if (ha->min_supported_speed <= 2) | ||
3116 | speeds |= FC_PORTSPEED_4GBIT; | ||
3117 | } | ||
3118 | } else if (IS_QLA2031(ha)) | ||
3119 | speeds = FC_PORTSPEED_16GBIT|FC_PORTSPEED_8GBIT| | ||
3120 | FC_PORTSPEED_4GBIT; | ||
3121 | else if (IS_QLA25XX(ha) || IS_QLAFX00(ha)) | ||
3122 | speeds = FC_PORTSPEED_8GBIT|FC_PORTSPEED_4GBIT| | ||
3123 | FC_PORTSPEED_2GBIT|FC_PORTSPEED_1GBIT; | ||
2998 | else if (IS_QLA24XX_TYPE(ha)) | 3124 | else if (IS_QLA24XX_TYPE(ha)) |
2999 | speed = FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | | 3125 | speeds = FC_PORTSPEED_4GBIT|FC_PORTSPEED_2GBIT| |
3000 | FC_PORTSPEED_1GBIT; | 3126 | FC_PORTSPEED_1GBIT; |
3001 | else if (IS_QLA23XX(ha)) | 3127 | else if (IS_QLA23XX(ha)) |
3002 | speed = FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; | 3128 | speeds = FC_PORTSPEED_2GBIT|FC_PORTSPEED_1GBIT; |
3003 | else if (IS_QLAFX00(ha)) | ||
3004 | speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | | ||
3005 | FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; | ||
3006 | else if (IS_QLA27XX(ha)) | ||
3007 | speed = FC_PORTSPEED_32GBIT | FC_PORTSPEED_16GBIT | | ||
3008 | FC_PORTSPEED_8GBIT; | ||
3009 | else | 3129 | else |
3010 | speed = FC_PORTSPEED_1GBIT; | 3130 | speeds = FC_PORTSPEED_1GBIT; |
3011 | fc_host_supported_speeds(vha->host) = speed; | 3131 | |
3132 | fc_host_supported_speeds(vha->host) = speeds; | ||
3012 | } | 3133 | } |
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 17d42658ad9a..5441557b424b 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2014 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
@@ -84,8 +84,7 @@ qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *vha, | |||
84 | return 0; | 84 | return 0; |
85 | } | 85 | } |
86 | 86 | ||
87 | if (bcode[0] != 'H' || bcode[1] != 'Q' || bcode[2] != 'O' || | 87 | if (memcmp(bcode, "HQOS", 4)) { |
88 | bcode[3] != 'S') { | ||
89 | /* Invalid FCP priority data header*/ | 88 | /* Invalid FCP priority data header*/ |
90 | ql_dbg(ql_dbg_user, vha, 0x7052, | 89 | ql_dbg(ql_dbg_user, vha, 0x7052, |
91 | "Invalid FCP Priority data header. bcode=0x%x.\n", | 90 | "Invalid FCP Priority data header. bcode=0x%x.\n", |
@@ -1044,7 +1043,7 @@ qla84xx_updatefw(struct bsg_job *bsg_job) | |||
1044 | } | 1043 | } |
1045 | 1044 | ||
1046 | flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1]; | 1045 | flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1]; |
1047 | fw_ver = le32_to_cpu(*((uint32_t *)((uint32_t *)fw_buf + 2))); | 1046 | fw_ver = get_unaligned_le32((uint32_t *)fw_buf + 2); |
1048 | 1047 | ||
1049 | mn->entry_type = VERIFY_CHIP_IOCB_TYPE; | 1048 | mn->entry_type = VERIFY_CHIP_IOCB_TYPE; |
1050 | mn->entry_count = 1; | 1049 | mn->entry_count = 1; |
@@ -1057,9 +1056,8 @@ qla84xx_updatefw(struct bsg_job *bsg_job) | |||
1057 | mn->fw_ver = cpu_to_le32(fw_ver); | 1056 | mn->fw_ver = cpu_to_le32(fw_ver); |
1058 | mn->fw_size = cpu_to_le32(data_len); | 1057 | mn->fw_size = cpu_to_le32(data_len); |
1059 | mn->fw_seq_size = cpu_to_le32(data_len); | 1058 | mn->fw_seq_size = cpu_to_le32(data_len); |
1060 | mn->dseg_address[0] = cpu_to_le32(LSD(fw_dma)); | 1059 | put_unaligned_le64(fw_dma, &mn->dsd.address); |
1061 | mn->dseg_address[1] = cpu_to_le32(MSD(fw_dma)); | 1060 | mn->dsd.length = cpu_to_le32(data_len); |
1062 | mn->dseg_length = cpu_to_le32(data_len); | ||
1063 | mn->data_seg_cnt = cpu_to_le16(1); | 1061 | mn->data_seg_cnt = cpu_to_le16(1); |
1064 | 1062 | ||
1065 | rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120); | 1063 | rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120); |
@@ -1238,9 +1236,8 @@ qla84xx_mgmt_cmd(struct bsg_job *bsg_job) | |||
1238 | if (ql84_mgmt->mgmt.cmd != QLA84_MGMT_CHNG_CONFIG) { | 1236 | if (ql84_mgmt->mgmt.cmd != QLA84_MGMT_CHNG_CONFIG) { |
1239 | mn->total_byte_cnt = cpu_to_le32(ql84_mgmt->mgmt.len); | 1237 | mn->total_byte_cnt = cpu_to_le32(ql84_mgmt->mgmt.len); |
1240 | mn->dseg_count = cpu_to_le16(1); | 1238 | mn->dseg_count = cpu_to_le16(1); |
1241 | mn->dseg_address[0] = cpu_to_le32(LSD(mgmt_dma)); | 1239 | put_unaligned_le64(mgmt_dma, &mn->dsd.address); |
1242 | mn->dseg_address[1] = cpu_to_le32(MSD(mgmt_dma)); | 1240 | mn->dsd.length = cpu_to_le32(ql84_mgmt->mgmt.len); |
1243 | mn->dseg_length = cpu_to_le32(ql84_mgmt->mgmt.len); | ||
1244 | } | 1241 | } |
1245 | 1242 | ||
1246 | rval = qla2x00_issue_iocb(vha, mn, mn_dma, 0); | 1243 | rval = qla2x00_issue_iocb(vha, mn, mn_dma, 0); |
@@ -1354,7 +1351,7 @@ qla24xx_iidma(struct bsg_job *bsg_job) | |||
1354 | 1351 | ||
1355 | if (rval) { | 1352 | if (rval) { |
1356 | ql_log(ql_log_warn, vha, 0x704c, | 1353 | ql_log(ql_log_warn, vha, 0x704c, |
1357 | "iIDMA cmd failed for %8phN -- " | 1354 | "iiDMA cmd failed for %8phN -- " |
1358 | "%04x %x %04x %04x.\n", fcport->port_name, | 1355 | "%04x %x %04x %04x.\n", fcport->port_name, |
1359 | rval, fcport->fp_speed, mb[0], mb[1]); | 1356 | rval, fcport->fp_speed, mb[0], mb[1]); |
1360 | rval = (DID_ERROR << 16); | 1357 | rval = (DID_ERROR << 16); |
@@ -1412,7 +1409,8 @@ qla2x00_optrom_setup(struct bsg_job *bsg_job, scsi_qla_host_t *vha, | |||
1412 | start == (ha->flt_region_fw * 4)) | 1409 | start == (ha->flt_region_fw * 4)) |
1413 | valid = 1; | 1410 | valid = 1; |
1414 | else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || | 1411 | else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || |
1415 | IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) | 1412 | IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || |
1413 | IS_QLA28XX(ha)) | ||
1416 | valid = 1; | 1414 | valid = 1; |
1417 | if (!valid) { | 1415 | if (!valid) { |
1418 | ql_log(ql_log_warn, vha, 0x7058, | 1416 | ql_log(ql_log_warn, vha, 0x7058, |
@@ -1534,6 +1532,7 @@ qla2x00_update_fru_versions(struct bsg_job *bsg_job) | |||
1534 | uint32_t count; | 1532 | uint32_t count; |
1535 | dma_addr_t sfp_dma; | 1533 | dma_addr_t sfp_dma; |
1536 | void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); | 1534 | void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); |
1535 | |||
1537 | if (!sfp) { | 1536 | if (!sfp) { |
1538 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = | 1537 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = |
1539 | EXT_STATUS_NO_MEMORY; | 1538 | EXT_STATUS_NO_MEMORY; |
@@ -1584,6 +1583,7 @@ qla2x00_read_fru_status(struct bsg_job *bsg_job) | |||
1584 | struct qla_status_reg *sr = (void *)bsg; | 1583 | struct qla_status_reg *sr = (void *)bsg; |
1585 | dma_addr_t sfp_dma; | 1584 | dma_addr_t sfp_dma; |
1586 | uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); | 1585 | uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); |
1586 | |||
1587 | if (!sfp) { | 1587 | if (!sfp) { |
1588 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = | 1588 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = |
1589 | EXT_STATUS_NO_MEMORY; | 1589 | EXT_STATUS_NO_MEMORY; |
@@ -1634,6 +1634,7 @@ qla2x00_write_fru_status(struct bsg_job *bsg_job) | |||
1634 | struct qla_status_reg *sr = (void *)bsg; | 1634 | struct qla_status_reg *sr = (void *)bsg; |
1635 | dma_addr_t sfp_dma; | 1635 | dma_addr_t sfp_dma; |
1636 | uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); | 1636 | uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); |
1637 | |||
1637 | if (!sfp) { | 1638 | if (!sfp) { |
1638 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = | 1639 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = |
1639 | EXT_STATUS_NO_MEMORY; | 1640 | EXT_STATUS_NO_MEMORY; |
@@ -1680,6 +1681,7 @@ qla2x00_write_i2c(struct bsg_job *bsg_job) | |||
1680 | struct qla_i2c_access *i2c = (void *)bsg; | 1681 | struct qla_i2c_access *i2c = (void *)bsg; |
1681 | dma_addr_t sfp_dma; | 1682 | dma_addr_t sfp_dma; |
1682 | uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); | 1683 | uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); |
1684 | |||
1683 | if (!sfp) { | 1685 | if (!sfp) { |
1684 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = | 1686 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = |
1685 | EXT_STATUS_NO_MEMORY; | 1687 | EXT_STATUS_NO_MEMORY; |
@@ -1725,6 +1727,7 @@ qla2x00_read_i2c(struct bsg_job *bsg_job) | |||
1725 | struct qla_i2c_access *i2c = (void *)bsg; | 1727 | struct qla_i2c_access *i2c = (void *)bsg; |
1726 | dma_addr_t sfp_dma; | 1728 | dma_addr_t sfp_dma; |
1727 | uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); | 1729 | uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma); |
1730 | |||
1728 | if (!sfp) { | 1731 | if (!sfp) { |
1729 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = | 1732 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = |
1730 | EXT_STATUS_NO_MEMORY; | 1733 | EXT_STATUS_NO_MEMORY; |
@@ -1961,7 +1964,7 @@ qlafx00_mgmt_cmd(struct bsg_job *bsg_job) | |||
1961 | 1964 | ||
1962 | /* Dump the vendor information */ | 1965 | /* Dump the vendor information */ |
1963 | ql_dump_buffer(ql_dbg_user + ql_dbg_verbose , vha, 0x70cf, | 1966 | ql_dump_buffer(ql_dbg_user + ql_dbg_verbose , vha, 0x70cf, |
1964 | (uint8_t *)piocb_rqst, sizeof(struct qla_mt_iocb_rqst_fx00)); | 1967 | piocb_rqst, sizeof(*piocb_rqst)); |
1965 | 1968 | ||
1966 | if (!vha->flags.online) { | 1969 | if (!vha->flags.online) { |
1967 | ql_log(ql_log_warn, vha, 0x70d0, | 1970 | ql_log(ql_log_warn, vha, 0x70d0, |
@@ -2157,7 +2160,7 @@ qla27xx_get_flash_upd_cap(struct bsg_job *bsg_job) | |||
2157 | struct qla_hw_data *ha = vha->hw; | 2160 | struct qla_hw_data *ha = vha->hw; |
2158 | struct qla_flash_update_caps cap; | 2161 | struct qla_flash_update_caps cap; |
2159 | 2162 | ||
2160 | if (!(IS_QLA27XX(ha))) | 2163 | if (!(IS_QLA27XX(ha)) && !IS_QLA28XX(ha)) |
2161 | return -EPERM; | 2164 | return -EPERM; |
2162 | 2165 | ||
2163 | memset(&cap, 0, sizeof(cap)); | 2166 | memset(&cap, 0, sizeof(cap)); |
@@ -2190,7 +2193,7 @@ qla27xx_set_flash_upd_cap(struct bsg_job *bsg_job) | |||
2190 | uint64_t online_fw_attr = 0; | 2193 | uint64_t online_fw_attr = 0; |
2191 | struct qla_flash_update_caps cap; | 2194 | struct qla_flash_update_caps cap; |
2192 | 2195 | ||
2193 | if (!(IS_QLA27XX(ha))) | 2196 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
2194 | return -EPERM; | 2197 | return -EPERM; |
2195 | 2198 | ||
2196 | memset(&cap, 0, sizeof(cap)); | 2199 | memset(&cap, 0, sizeof(cap)); |
@@ -2238,7 +2241,7 @@ qla27xx_get_bbcr_data(struct bsg_job *bsg_job) | |||
2238 | uint8_t domain, area, al_pa, state; | 2241 | uint8_t domain, area, al_pa, state; |
2239 | int rval; | 2242 | int rval; |
2240 | 2243 | ||
2241 | if (!(IS_QLA27XX(ha))) | 2244 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
2242 | return -EPERM; | 2245 | return -EPERM; |
2243 | 2246 | ||
2244 | memset(&bbcr, 0, sizeof(bbcr)); | 2247 | memset(&bbcr, 0, sizeof(bbcr)); |
@@ -2323,8 +2326,8 @@ qla2x00_get_priv_stats(struct bsg_job *bsg_job) | |||
2323 | rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, options); | 2326 | rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, options); |
2324 | 2327 | ||
2325 | if (rval == QLA_SUCCESS) { | 2328 | if (rval == QLA_SUCCESS) { |
2326 | ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, vha, 0x70e3, | 2329 | ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, vha, 0x70e5, |
2327 | (uint8_t *)stats, sizeof(*stats)); | 2330 | stats, sizeof(*stats)); |
2328 | sg_copy_from_buffer(bsg_job->reply_payload.sg_list, | 2331 | sg_copy_from_buffer(bsg_job->reply_payload.sg_list, |
2329 | bsg_job->reply_payload.sg_cnt, stats, sizeof(*stats)); | 2332 | bsg_job->reply_payload.sg_cnt, stats, sizeof(*stats)); |
2330 | } | 2333 | } |
@@ -2353,7 +2356,8 @@ qla2x00_do_dport_diagnostics(struct bsg_job *bsg_job) | |||
2353 | int rval; | 2356 | int rval; |
2354 | struct qla_dport_diag *dd; | 2357 | struct qla_dport_diag *dd; |
2355 | 2358 | ||
2356 | if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw)) | 2359 | if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) && |
2360 | !IS_QLA28XX(vha->hw)) | ||
2357 | return -EPERM; | 2361 | return -EPERM; |
2358 | 2362 | ||
2359 | dd = kmalloc(sizeof(*dd), GFP_KERNEL); | 2363 | dd = kmalloc(sizeof(*dd), GFP_KERNEL); |
@@ -2388,6 +2392,45 @@ qla2x00_do_dport_diagnostics(struct bsg_job *bsg_job) | |||
2388 | } | 2392 | } |
2389 | 2393 | ||
2390 | static int | 2394 | static int |
2395 | qla2x00_get_flash_image_status(struct bsg_job *bsg_job) | ||
2396 | { | ||
2397 | scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job)); | ||
2398 | struct fc_bsg_reply *bsg_reply = bsg_job->reply; | ||
2399 | struct qla_hw_data *ha = vha->hw; | ||
2400 | struct qla_active_regions regions = { }; | ||
2401 | struct active_regions active_regions = { }; | ||
2402 | |||
2403 | qla28xx_get_aux_images(vha, &active_regions); | ||
2404 | regions.global_image = active_regions.global; | ||
2405 | |||
2406 | if (IS_QLA28XX(ha)) { | ||
2407 | qla27xx_get_active_image(vha, &active_regions); | ||
2408 | regions.board_config = active_regions.aux.board_config; | ||
2409 | regions.vpd_nvram = active_regions.aux.vpd_nvram; | ||
2410 | regions.npiv_config_0_1 = active_regions.aux.npiv_config_0_1; | ||
2411 | regions.npiv_config_2_3 = active_regions.aux.npiv_config_2_3; | ||
2412 | } | ||
2413 | |||
2414 | ql_dbg(ql_dbg_user, vha, 0x70e1, | ||
2415 | "%s(%lu): FW=%u BCFG=%u VPDNVR=%u NPIV01=%u NPIV02=%u\n", | ||
2416 | __func__, vha->host_no, regions.global_image, | ||
2417 | regions.board_config, regions.vpd_nvram, | ||
2418 | regions.npiv_config_0_1, regions.npiv_config_2_3); | ||
2419 | |||
2420 | sg_copy_from_buffer(bsg_job->reply_payload.sg_list, | ||
2421 | bsg_job->reply_payload.sg_cnt, ®ions, sizeof(regions)); | ||
2422 | |||
2423 | bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK; | ||
2424 | bsg_reply->reply_payload_rcv_len = sizeof(regions); | ||
2425 | bsg_reply->result = DID_OK << 16; | ||
2426 | bsg_job->reply_len = sizeof(struct fc_bsg_reply); | ||
2427 | bsg_job_done(bsg_job, bsg_reply->result, | ||
2428 | bsg_reply->reply_payload_rcv_len); | ||
2429 | |||
2430 | return 0; | ||
2431 | } | ||
2432 | |||
2433 | static int | ||
2391 | qla2x00_process_vendor_specific(struct bsg_job *bsg_job) | 2434 | qla2x00_process_vendor_specific(struct bsg_job *bsg_job) |
2392 | { | 2435 | { |
2393 | struct fc_bsg_request *bsg_request = bsg_job->request; | 2436 | struct fc_bsg_request *bsg_request = bsg_job->request; |
@@ -2460,6 +2503,9 @@ qla2x00_process_vendor_specific(struct bsg_job *bsg_job) | |||
2460 | case QL_VND_DPORT_DIAGNOSTICS: | 2503 | case QL_VND_DPORT_DIAGNOSTICS: |
2461 | return qla2x00_do_dport_diagnostics(bsg_job); | 2504 | return qla2x00_do_dport_diagnostics(bsg_job); |
2462 | 2505 | ||
2506 | case QL_VND_SS_GET_FLASH_IMAGE_STATUS: | ||
2507 | return qla2x00_get_flash_image_status(bsg_job); | ||
2508 | |||
2463 | default: | 2509 | default: |
2464 | return -ENOSYS; | 2510 | return -ENOSYS; |
2465 | } | 2511 | } |
diff --git a/drivers/scsi/qla2xxx/qla_bsg.h b/drivers/scsi/qla2xxx/qla_bsg.h index d97dfd521356..7594fad7b5b5 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.h +++ b/drivers/scsi/qla2xxx/qla_bsg.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #define QL_VND_GET_PRIV_STATS 0x18 | 31 | #define QL_VND_GET_PRIV_STATS 0x18 |
32 | #define QL_VND_DPORT_DIAGNOSTICS 0x19 | 32 | #define QL_VND_DPORT_DIAGNOSTICS 0x19 |
33 | #define QL_VND_GET_PRIV_STATS_EX 0x1A | 33 | #define QL_VND_GET_PRIV_STATS_EX 0x1A |
34 | #define QL_VND_SS_GET_FLASH_IMAGE_STATUS 0x1E | ||
34 | 35 | ||
35 | /* BSG Vendor specific subcode returns */ | 36 | /* BSG Vendor specific subcode returns */ |
36 | #define EXT_STATUS_OK 0 | 37 | #define EXT_STATUS_OK 0 |
@@ -279,4 +280,14 @@ struct qla_dport_diag { | |||
279 | #define QLA_DPORT_RESULT 0x0 | 280 | #define QLA_DPORT_RESULT 0x0 |
280 | #define QLA_DPORT_START 0x2 | 281 | #define QLA_DPORT_START 0x2 |
281 | 282 | ||
283 | /* active images in flash */ | ||
284 | struct qla_active_regions { | ||
285 | uint8_t global_image; | ||
286 | uint8_t board_config; | ||
287 | uint8_t vpd_nvram; | ||
288 | uint8_t npiv_config_0_1; | ||
289 | uint8_t npiv_config_2_3; | ||
290 | uint8_t reserved[32]; | ||
291 | } __packed; | ||
292 | |||
282 | #endif | 293 | #endif |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index c7533fa7f46e..9e80646722e2 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -111,30 +111,25 @@ int | |||
111 | qla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, | 111 | qla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, |
112 | uint32_t ram_dwords, void **nxt) | 112 | uint32_t ram_dwords, void **nxt) |
113 | { | 113 | { |
114 | int rval; | ||
115 | uint32_t cnt, stat, timer, dwords, idx; | ||
116 | uint16_t mb0; | ||
117 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 114 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
118 | dma_addr_t dump_dma = ha->gid_list_dma; | 115 | dma_addr_t dump_dma = ha->gid_list_dma; |
119 | uint32_t *dump = (uint32_t *)ha->gid_list; | 116 | uint32_t *chunk = (void *)ha->gid_list; |
120 | 117 | uint32_t dwords = qla2x00_gid_list_size(ha) / 4; | |
121 | rval = QLA_SUCCESS; | 118 | uint32_t stat; |
122 | mb0 = 0; | 119 | ulong i, j, timer = 6000000; |
120 | int rval = QLA_FUNCTION_FAILED; | ||
123 | 121 | ||
124 | WRT_REG_WORD(®->mailbox0, MBC_LOAD_DUMP_MPI_RAM); | ||
125 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | 122 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); |
123 | for (i = 0; i < ram_dwords; i += dwords, addr += dwords) { | ||
124 | if (i + dwords > ram_dwords) | ||
125 | dwords = ram_dwords - i; | ||
126 | 126 | ||
127 | dwords = qla2x00_gid_list_size(ha) / 4; | 127 | WRT_REG_WORD(®->mailbox0, MBC_LOAD_DUMP_MPI_RAM); |
128 | for (cnt = 0; cnt < ram_dwords && rval == QLA_SUCCESS; | ||
129 | cnt += dwords, addr += dwords) { | ||
130 | if (cnt + dwords > ram_dwords) | ||
131 | dwords = ram_dwords - cnt; | ||
132 | |||
133 | WRT_REG_WORD(®->mailbox1, LSW(addr)); | 128 | WRT_REG_WORD(®->mailbox1, LSW(addr)); |
134 | WRT_REG_WORD(®->mailbox8, MSW(addr)); | 129 | WRT_REG_WORD(®->mailbox8, MSW(addr)); |
135 | 130 | ||
136 | WRT_REG_WORD(®->mailbox2, MSW(dump_dma)); | 131 | WRT_REG_WORD(®->mailbox2, MSW(LSD(dump_dma))); |
137 | WRT_REG_WORD(®->mailbox3, LSW(dump_dma)); | 132 | WRT_REG_WORD(®->mailbox3, LSW(LSD(dump_dma))); |
138 | WRT_REG_WORD(®->mailbox6, MSW(MSD(dump_dma))); | 133 | WRT_REG_WORD(®->mailbox6, MSW(MSD(dump_dma))); |
139 | WRT_REG_WORD(®->mailbox7, LSW(MSD(dump_dma))); | 134 | WRT_REG_WORD(®->mailbox7, LSW(MSD(dump_dma))); |
140 | 135 | ||
@@ -145,76 +140,76 @@ qla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, | |||
145 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); | 140 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); |
146 | 141 | ||
147 | ha->flags.mbox_int = 0; | 142 | ha->flags.mbox_int = 0; |
148 | for (timer = 6000000; timer; timer--) { | 143 | while (timer--) { |
149 | /* Check for pending interrupts. */ | 144 | udelay(5); |
150 | stat = RD_REG_DWORD(®->host_status); | ||
151 | if (stat & HSRX_RISC_INT) { | ||
152 | stat &= 0xff; | ||
153 | |||
154 | if (stat == 0x1 || stat == 0x2 || | ||
155 | stat == 0x10 || stat == 0x11) { | ||
156 | set_bit(MBX_INTERRUPT, | ||
157 | &ha->mbx_cmd_flags); | ||
158 | 145 | ||
159 | mb0 = RD_REG_WORD(®->mailbox0); | 146 | stat = RD_REG_DWORD(®->host_status); |
160 | RD_REG_WORD(®->mailbox1); | 147 | /* Check for pending interrupts. */ |
148 | if (!(stat & HSRX_RISC_INT)) | ||
149 | continue; | ||
161 | 150 | ||
162 | WRT_REG_DWORD(®->hccr, | 151 | stat &= 0xff; |
163 | HCCRX_CLR_RISC_INT); | 152 | if (stat != 0x1 && stat != 0x2 && |
164 | RD_REG_DWORD(®->hccr); | 153 | stat != 0x10 && stat != 0x11) { |
165 | break; | ||
166 | } | ||
167 | 154 | ||
168 | /* Clear this intr; it wasn't a mailbox intr */ | 155 | /* Clear this intr; it wasn't a mailbox intr */ |
169 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 156 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
170 | RD_REG_DWORD(®->hccr); | 157 | RD_REG_DWORD(®->hccr); |
158 | continue; | ||
171 | } | 159 | } |
172 | udelay(5); | 160 | |
161 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
162 | rval = RD_REG_WORD(®->mailbox0) & MBS_MASK; | ||
163 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | ||
164 | RD_REG_DWORD(®->hccr); | ||
165 | break; | ||
173 | } | 166 | } |
174 | ha->flags.mbox_int = 1; | 167 | ha->flags.mbox_int = 1; |
168 | *nxt = ram + i; | ||
175 | 169 | ||
176 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 170 | if (!test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
177 | rval = mb0 & MBS_MASK; | 171 | /* no interrupt, timed out*/ |
178 | for (idx = 0; idx < dwords; idx++) | 172 | return rval; |
179 | ram[cnt + idx] = IS_QLA27XX(ha) ? | 173 | } |
180 | le32_to_cpu(dump[idx]) : swab32(dump[idx]); | 174 | if (rval) { |
181 | } else { | 175 | /* error completion status */ |
182 | rval = QLA_FUNCTION_FAILED; | 176 | return rval; |
177 | } | ||
178 | for (j = 0; j < dwords; j++) { | ||
179 | ram[i + j] = | ||
180 | (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ? | ||
181 | chunk[j] : swab32(chunk[j]); | ||
183 | } | 182 | } |
184 | } | 183 | } |
185 | 184 | ||
186 | *nxt = rval == QLA_SUCCESS ? &ram[cnt] : NULL; | 185 | *nxt = ram + i; |
187 | return rval; | 186 | return QLA_SUCCESS; |
188 | } | 187 | } |
189 | 188 | ||
190 | int | 189 | int |
191 | qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, | 190 | qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, |
192 | uint32_t ram_dwords, void **nxt) | 191 | uint32_t ram_dwords, void **nxt) |
193 | { | 192 | { |
194 | int rval; | 193 | int rval = QLA_FUNCTION_FAILED; |
195 | uint32_t cnt, stat, timer, dwords, idx; | ||
196 | uint16_t mb0; | ||
197 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 194 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
198 | dma_addr_t dump_dma = ha->gid_list_dma; | 195 | dma_addr_t dump_dma = ha->gid_list_dma; |
199 | uint32_t *dump = (uint32_t *)ha->gid_list; | 196 | uint32_t *chunk = (void *)ha->gid_list; |
197 | uint32_t dwords = qla2x00_gid_list_size(ha) / 4; | ||
198 | uint32_t stat; | ||
199 | ulong i, j, timer = 6000000; | ||
200 | 200 | ||
201 | rval = QLA_SUCCESS; | ||
202 | mb0 = 0; | ||
203 | |||
204 | WRT_REG_WORD(®->mailbox0, MBC_DUMP_RISC_RAM_EXTENDED); | ||
205 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | 201 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); |
206 | 202 | ||
207 | dwords = qla2x00_gid_list_size(ha) / 4; | 203 | for (i = 0; i < ram_dwords; i += dwords, addr += dwords) { |
208 | for (cnt = 0; cnt < ram_dwords && rval == QLA_SUCCESS; | 204 | if (i + dwords > ram_dwords) |
209 | cnt += dwords, addr += dwords) { | 205 | dwords = ram_dwords - i; |
210 | if (cnt + dwords > ram_dwords) | ||
211 | dwords = ram_dwords - cnt; | ||
212 | 206 | ||
207 | WRT_REG_WORD(®->mailbox0, MBC_DUMP_RISC_RAM_EXTENDED); | ||
213 | WRT_REG_WORD(®->mailbox1, LSW(addr)); | 208 | WRT_REG_WORD(®->mailbox1, LSW(addr)); |
214 | WRT_REG_WORD(®->mailbox8, MSW(addr)); | 209 | WRT_REG_WORD(®->mailbox8, MSW(addr)); |
215 | 210 | ||
216 | WRT_REG_WORD(®->mailbox2, MSW(dump_dma)); | 211 | WRT_REG_WORD(®->mailbox2, MSW(LSD(dump_dma))); |
217 | WRT_REG_WORD(®->mailbox3, LSW(dump_dma)); | 212 | WRT_REG_WORD(®->mailbox3, LSW(LSD(dump_dma))); |
218 | WRT_REG_WORD(®->mailbox6, MSW(MSD(dump_dma))); | 213 | WRT_REG_WORD(®->mailbox6, MSW(MSD(dump_dma))); |
219 | WRT_REG_WORD(®->mailbox7, LSW(MSD(dump_dma))); | 214 | WRT_REG_WORD(®->mailbox7, LSW(MSD(dump_dma))); |
220 | 215 | ||
@@ -223,45 +218,48 @@ qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, | |||
223 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); | 218 | WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); |
224 | 219 | ||
225 | ha->flags.mbox_int = 0; | 220 | ha->flags.mbox_int = 0; |
226 | for (timer = 6000000; timer; timer--) { | 221 | while (timer--) { |
227 | /* Check for pending interrupts. */ | 222 | udelay(5); |
228 | stat = RD_REG_DWORD(®->host_status); | 223 | stat = RD_REG_DWORD(®->host_status); |
229 | if (stat & HSRX_RISC_INT) { | ||
230 | stat &= 0xff; | ||
231 | 224 | ||
232 | if (stat == 0x1 || stat == 0x2 || | 225 | /* Check for pending interrupts. */ |
233 | stat == 0x10 || stat == 0x11) { | 226 | if (!(stat & HSRX_RISC_INT)) |
234 | set_bit(MBX_INTERRUPT, | 227 | continue; |
235 | &ha->mbx_cmd_flags); | ||
236 | |||
237 | mb0 = RD_REG_WORD(®->mailbox0); | ||
238 | |||
239 | WRT_REG_DWORD(®->hccr, | ||
240 | HCCRX_CLR_RISC_INT); | ||
241 | RD_REG_DWORD(®->hccr); | ||
242 | break; | ||
243 | } | ||
244 | 228 | ||
245 | /* Clear this intr; it wasn't a mailbox intr */ | 229 | stat &= 0xff; |
230 | if (stat != 0x1 && stat != 0x2 && | ||
231 | stat != 0x10 && stat != 0x11) { | ||
246 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 232 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
247 | RD_REG_DWORD(®->hccr); | 233 | RD_REG_DWORD(®->hccr); |
234 | continue; | ||
248 | } | 235 | } |
249 | udelay(5); | 236 | |
237 | set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | ||
238 | rval = RD_REG_WORD(®->mailbox0) & MBS_MASK; | ||
239 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | ||
240 | RD_REG_DWORD(®->hccr); | ||
241 | break; | ||
250 | } | 242 | } |
251 | ha->flags.mbox_int = 1; | 243 | ha->flags.mbox_int = 1; |
244 | *nxt = ram + i; | ||
252 | 245 | ||
253 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 246 | if (!test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
254 | rval = mb0 & MBS_MASK; | 247 | /* no interrupt, timed out*/ |
255 | for (idx = 0; idx < dwords; idx++) | 248 | return rval; |
256 | ram[cnt + idx] = IS_QLA27XX(ha) ? | 249 | } |
257 | le32_to_cpu(dump[idx]) : swab32(dump[idx]); | 250 | if (rval) { |
258 | } else { | 251 | /* error completion status */ |
259 | rval = QLA_FUNCTION_FAILED; | 252 | return rval; |
253 | } | ||
254 | for (j = 0; j < dwords; j++) { | ||
255 | ram[i + j] = | ||
256 | (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ? | ||
257 | chunk[j] : swab32(chunk[j]); | ||
260 | } | 258 | } |
261 | } | 259 | } |
262 | 260 | ||
263 | *nxt = rval == QLA_SUCCESS ? &ram[cnt]: NULL; | 261 | *nxt = ram + i; |
264 | return rval; | 262 | return QLA_SUCCESS; |
265 | } | 263 | } |
266 | 264 | ||
267 | static int | 265 | static int |
@@ -447,7 +445,7 @@ qla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint16_t *ram, | |||
447 | } | 445 | } |
448 | } | 446 | } |
449 | 447 | ||
450 | *nxt = rval == QLA_SUCCESS ? &ram[cnt]: NULL; | 448 | *nxt = rval == QLA_SUCCESS ? &ram[cnt] : NULL; |
451 | return rval; | 449 | return rval; |
452 | } | 450 | } |
453 | 451 | ||
@@ -669,7 +667,8 @@ qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) | |||
669 | struct qla2xxx_mq_chain *mq = ptr; | 667 | struct qla2xxx_mq_chain *mq = ptr; |
670 | device_reg_t *reg; | 668 | device_reg_t *reg; |
671 | 669 | ||
672 | if (!ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 670 | if (!ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
671 | IS_QLA28XX(ha)) | ||
673 | return ptr; | 672 | return ptr; |
674 | 673 | ||
675 | mq = ptr; | 674 | mq = ptr; |
@@ -2521,7 +2520,7 @@ qla83xx_fw_dump_failed: | |||
2521 | /****************************************************************************/ | 2520 | /****************************************************************************/ |
2522 | 2521 | ||
2523 | static inline int | 2522 | static inline int |
2524 | ql_mask_match(uint32_t level) | 2523 | ql_mask_match(uint level) |
2525 | { | 2524 | { |
2526 | return (level & ql2xextended_error_logging) == level; | 2525 | return (level & ql2xextended_error_logging) == level; |
2527 | } | 2526 | } |
@@ -2540,7 +2539,7 @@ ql_mask_match(uint32_t level) | |||
2540 | * msg: The message to be displayed. | 2539 | * msg: The message to be displayed. |
2541 | */ | 2540 | */ |
2542 | void | 2541 | void |
2543 | ql_dbg(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...) | 2542 | ql_dbg(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...) |
2544 | { | 2543 | { |
2545 | va_list va; | 2544 | va_list va; |
2546 | struct va_format vaf; | 2545 | struct va_format vaf; |
@@ -2583,8 +2582,7 @@ ql_dbg(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...) | |||
2583 | * msg: The message to be displayed. | 2582 | * msg: The message to be displayed. |
2584 | */ | 2583 | */ |
2585 | void | 2584 | void |
2586 | ql_dbg_pci(uint32_t level, struct pci_dev *pdev, int32_t id, | 2585 | ql_dbg_pci(uint level, struct pci_dev *pdev, uint id, const char *fmt, ...) |
2587 | const char *fmt, ...) | ||
2588 | { | 2586 | { |
2589 | va_list va; | 2587 | va_list va; |
2590 | struct va_format vaf; | 2588 | struct va_format vaf; |
@@ -2620,7 +2618,7 @@ ql_dbg_pci(uint32_t level, struct pci_dev *pdev, int32_t id, | |||
2620 | * msg: The message to be displayed. | 2618 | * msg: The message to be displayed. |
2621 | */ | 2619 | */ |
2622 | void | 2620 | void |
2623 | ql_log(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...) | 2621 | ql_log(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...) |
2624 | { | 2622 | { |
2625 | va_list va; | 2623 | va_list va; |
2626 | struct va_format vaf; | 2624 | struct va_format vaf; |
@@ -2678,8 +2676,7 @@ ql_log(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...) | |||
2678 | * msg: The message to be displayed. | 2676 | * msg: The message to be displayed. |
2679 | */ | 2677 | */ |
2680 | void | 2678 | void |
2681 | ql_log_pci(uint32_t level, struct pci_dev *pdev, int32_t id, | 2679 | ql_log_pci(uint level, struct pci_dev *pdev, uint id, const char *fmt, ...) |
2682 | const char *fmt, ...) | ||
2683 | { | 2680 | { |
2684 | va_list va; | 2681 | va_list va; |
2685 | struct va_format vaf; | 2682 | struct va_format vaf; |
@@ -2719,7 +2716,7 @@ ql_log_pci(uint32_t level, struct pci_dev *pdev, int32_t id, | |||
2719 | } | 2716 | } |
2720 | 2717 | ||
2721 | void | 2718 | void |
2722 | ql_dump_regs(uint32_t level, scsi_qla_host_t *vha, int32_t id) | 2719 | ql_dump_regs(uint level, scsi_qla_host_t *vha, uint id) |
2723 | { | 2720 | { |
2724 | int i; | 2721 | int i; |
2725 | struct qla_hw_data *ha = vha->hw; | 2722 | struct qla_hw_data *ha = vha->hw; |
@@ -2741,13 +2738,12 @@ ql_dump_regs(uint32_t level, scsi_qla_host_t *vha, int32_t id) | |||
2741 | ql_dbg(level, vha, id, "Mailbox registers:\n"); | 2738 | ql_dbg(level, vha, id, "Mailbox registers:\n"); |
2742 | for (i = 0; i < 6; i++, mbx_reg++) | 2739 | for (i = 0; i < 6; i++, mbx_reg++) |
2743 | ql_dbg(level, vha, id, | 2740 | ql_dbg(level, vha, id, |
2744 | "mbox[%d] 0x%04x\n", i, RD_REG_WORD(mbx_reg)); | 2741 | "mbox[%d] %#04x\n", i, RD_REG_WORD(mbx_reg)); |
2745 | } | 2742 | } |
2746 | 2743 | ||
2747 | 2744 | ||
2748 | void | 2745 | void |
2749 | ql_dump_buffer(uint32_t level, scsi_qla_host_t *vha, int32_t id, | 2746 | ql_dump_buffer(uint level, scsi_qla_host_t *vha, uint id, void *buf, uint size) |
2750 | uint8_t *buf, uint size) | ||
2751 | { | 2747 | { |
2752 | uint cnt; | 2748 | uint cnt; |
2753 | 2749 | ||
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 8877aa97d829..bb01b680ce9f 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -318,20 +318,20 @@ struct qla2xxx_fw_dump { | |||
318 | * as compared to other log levels. | 318 | * as compared to other log levels. |
319 | */ | 319 | */ |
320 | 320 | ||
321 | extern int ql_errlev; | 321 | extern uint ql_errlev; |
322 | 322 | ||
323 | void __attribute__((format (printf, 4, 5))) | 323 | void __attribute__((format (printf, 4, 5))) |
324 | ql_dbg(uint32_t, scsi_qla_host_t *vha, int32_t, const char *fmt, ...); | 324 | ql_dbg(uint, scsi_qla_host_t *vha, uint, const char *fmt, ...); |
325 | void __attribute__((format (printf, 4, 5))) | 325 | void __attribute__((format (printf, 4, 5))) |
326 | ql_dbg_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...); | 326 | ql_dbg_pci(uint, struct pci_dev *pdev, uint, const char *fmt, ...); |
327 | void __attribute__((format (printf, 4, 5))) | 327 | void __attribute__((format (printf, 4, 5))) |
328 | ql_dbg_qp(uint32_t, struct qla_qpair *, int32_t, const char *fmt, ...); | 328 | ql_dbg_qp(uint32_t, struct qla_qpair *, int32_t, const char *fmt, ...); |
329 | 329 | ||
330 | 330 | ||
331 | void __attribute__((format (printf, 4, 5))) | 331 | void __attribute__((format (printf, 4, 5))) |
332 | ql_log(uint32_t, scsi_qla_host_t *vha, int32_t, const char *fmt, ...); | 332 | ql_log(uint, scsi_qla_host_t *vha, uint, const char *fmt, ...); |
333 | void __attribute__((format (printf, 4, 5))) | 333 | void __attribute__((format (printf, 4, 5))) |
334 | ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...); | 334 | ql_log_pci(uint, struct pci_dev *pdev, uint, const char *fmt, ...); |
335 | 335 | ||
336 | void __attribute__((format (printf, 4, 5))) | 336 | void __attribute__((format (printf, 4, 5))) |
337 | ql_log_qp(uint32_t, struct qla_qpair *, int32_t, const char *fmt, ...); | 337 | ql_log_qp(uint32_t, struct qla_qpair *, int32_t, const char *fmt, ...); |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3d46975a5e5c..1a4095c56eee 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <scsi/scsi_bsg_fc.h> | 35 | #include <scsi/scsi_bsg_fc.h> |
36 | 36 | ||
37 | #include "qla_bsg.h" | 37 | #include "qla_bsg.h" |
38 | #include "qla_dsd.h" | ||
38 | #include "qla_nx.h" | 39 | #include "qla_nx.h" |
39 | #include "qla_nx2.h" | 40 | #include "qla_nx2.h" |
40 | #include "qla_nvme.h" | 41 | #include "qla_nvme.h" |
@@ -545,7 +546,7 @@ typedef struct srb { | |||
545 | u32 gen2; /* scratch */ | 546 | u32 gen2; /* scratch */ |
546 | int rc; | 547 | int rc; |
547 | int retry_count; | 548 | int retry_count; |
548 | struct completion comp; | 549 | struct completion *comp; |
549 | union { | 550 | union { |
550 | struct srb_iocb iocb_cmd; | 551 | struct srb_iocb iocb_cmd; |
551 | struct bsg_job *bsg_job; | 552 | struct bsg_job *bsg_job; |
@@ -1033,6 +1034,7 @@ struct mbx_cmd_32 { | |||
1033 | #define MBC_GET_FIRMWARE_VERSION 8 /* Get firmware revision. */ | 1034 | #define MBC_GET_FIRMWARE_VERSION 8 /* Get firmware revision. */ |
1034 | #define MBC_LOAD_RISC_RAM 9 /* Load RAM command. */ | 1035 | #define MBC_LOAD_RISC_RAM 9 /* Load RAM command. */ |
1035 | #define MBC_DUMP_RISC_RAM 0xa /* Dump RAM command. */ | 1036 | #define MBC_DUMP_RISC_RAM 0xa /* Dump RAM command. */ |
1037 | #define MBC_SECURE_FLASH_UPDATE 0xa /* Secure Flash Update(28xx) */ | ||
1036 | #define MBC_LOAD_RISC_RAM_EXTENDED 0xb /* Load RAM extended. */ | 1038 | #define MBC_LOAD_RISC_RAM_EXTENDED 0xb /* Load RAM extended. */ |
1037 | #define MBC_DUMP_RISC_RAM_EXTENDED 0xc /* Dump RAM extended. */ | 1039 | #define MBC_DUMP_RISC_RAM_EXTENDED 0xc /* Dump RAM extended. */ |
1038 | #define MBC_WRITE_RAM_WORD_EXTENDED 0xd /* Write RAM word extended */ | 1040 | #define MBC_WRITE_RAM_WORD_EXTENDED 0xd /* Write RAM word extended */ |
@@ -1203,6 +1205,10 @@ struct mbx_cmd_32 { | |||
1203 | #define QLA27XX_IMG_STATUS_VER_MAJOR 0x01 | 1205 | #define QLA27XX_IMG_STATUS_VER_MAJOR 0x01 |
1204 | #define QLA27XX_IMG_STATUS_VER_MINOR 0x00 | 1206 | #define QLA27XX_IMG_STATUS_VER_MINOR 0x00 |
1205 | #define QLA27XX_IMG_STATUS_SIGN 0xFACEFADE | 1207 | #define QLA27XX_IMG_STATUS_SIGN 0xFACEFADE |
1208 | #define QLA28XX_IMG_STATUS_SIGN 0xFACEFADF | ||
1209 | #define QLA28XX_IMG_STATUS_SIGN 0xFACEFADF | ||
1210 | #define QLA28XX_AUX_IMG_STATUS_SIGN 0xFACEFAED | ||
1211 | #define QLA27XX_DEFAULT_IMAGE 0 | ||
1206 | #define QLA27XX_PRIMARY_IMAGE 1 | 1212 | #define QLA27XX_PRIMARY_IMAGE 1 |
1207 | #define QLA27XX_SECONDARY_IMAGE 2 | 1213 | #define QLA27XX_SECONDARY_IMAGE 2 |
1208 | 1214 | ||
@@ -1323,8 +1329,8 @@ typedef struct { | |||
1323 | uint16_t response_q_inpointer; | 1329 | uint16_t response_q_inpointer; |
1324 | uint16_t request_q_length; | 1330 | uint16_t request_q_length; |
1325 | uint16_t response_q_length; | 1331 | uint16_t response_q_length; |
1326 | uint32_t request_q_address[2]; | 1332 | __le64 request_q_address __packed; |
1327 | uint32_t response_q_address[2]; | 1333 | __le64 response_q_address __packed; |
1328 | 1334 | ||
1329 | uint16_t lun_enables; | 1335 | uint16_t lun_enables; |
1330 | uint8_t command_resource_count; | 1336 | uint8_t command_resource_count; |
@@ -1749,12 +1755,10 @@ typedef struct { | |||
1749 | uint16_t dseg_count; /* Data segment count. */ | 1755 | uint16_t dseg_count; /* Data segment count. */ |
1750 | uint8_t scsi_cdb[MAX_CMDSZ]; /* SCSI command words. */ | 1756 | uint8_t scsi_cdb[MAX_CMDSZ]; /* SCSI command words. */ |
1751 | uint32_t byte_count; /* Total byte count. */ | 1757 | uint32_t byte_count; /* Total byte count. */ |
1752 | uint32_t dseg_0_address; /* Data segment 0 address. */ | 1758 | union { |
1753 | uint32_t dseg_0_length; /* Data segment 0 length. */ | 1759 | struct dsd32 dsd32[3]; |
1754 | uint32_t dseg_1_address; /* Data segment 1 address. */ | 1760 | struct dsd64 dsd64[2]; |
1755 | uint32_t dseg_1_length; /* Data segment 1 length. */ | 1761 | }; |
1756 | uint32_t dseg_2_address; /* Data segment 2 address. */ | ||
1757 | uint32_t dseg_2_length; /* Data segment 2 length. */ | ||
1758 | } cmd_entry_t; | 1762 | } cmd_entry_t; |
1759 | 1763 | ||
1760 | /* | 1764 | /* |
@@ -1775,10 +1779,7 @@ typedef struct { | |||
1775 | uint16_t dseg_count; /* Data segment count. */ | 1779 | uint16_t dseg_count; /* Data segment count. */ |
1776 | uint8_t scsi_cdb[MAX_CMDSZ]; /* SCSI command words. */ | 1780 | uint8_t scsi_cdb[MAX_CMDSZ]; /* SCSI command words. */ |
1777 | uint32_t byte_count; /* Total byte count. */ | 1781 | uint32_t byte_count; /* Total byte count. */ |
1778 | uint32_t dseg_0_address[2]; /* Data segment 0 address. */ | 1782 | struct dsd64 dsd[2]; |
1779 | uint32_t dseg_0_length; /* Data segment 0 length. */ | ||
1780 | uint32_t dseg_1_address[2]; /* Data segment 1 address. */ | ||
1781 | uint32_t dseg_1_length; /* Data segment 1 length. */ | ||
1782 | } cmd_a64_entry_t, request_t; | 1783 | } cmd_a64_entry_t, request_t; |
1783 | 1784 | ||
1784 | /* | 1785 | /* |
@@ -1791,20 +1792,7 @@ typedef struct { | |||
1791 | uint8_t sys_define; /* System defined. */ | 1792 | uint8_t sys_define; /* System defined. */ |
1792 | uint8_t entry_status; /* Entry Status. */ | 1793 | uint8_t entry_status; /* Entry Status. */ |
1793 | uint32_t reserved; | 1794 | uint32_t reserved; |
1794 | uint32_t dseg_0_address; /* Data segment 0 address. */ | 1795 | struct dsd32 dsd[7]; |
1795 | uint32_t dseg_0_length; /* Data segment 0 length. */ | ||
1796 | uint32_t dseg_1_address; /* Data segment 1 address. */ | ||
1797 | uint32_t dseg_1_length; /* Data segment 1 length. */ | ||
1798 | uint32_t dseg_2_address; /* Data segment 2 address. */ | ||
1799 | uint32_t dseg_2_length; /* Data segment 2 length. */ | ||
1800 | uint32_t dseg_3_address; /* Data segment 3 address. */ | ||
1801 | uint32_t dseg_3_length; /* Data segment 3 length. */ | ||
1802 | uint32_t dseg_4_address; /* Data segment 4 address. */ | ||
1803 | uint32_t dseg_4_length; /* Data segment 4 length. */ | ||
1804 | uint32_t dseg_5_address; /* Data segment 5 address. */ | ||
1805 | uint32_t dseg_5_length; /* Data segment 5 length. */ | ||
1806 | uint32_t dseg_6_address; /* Data segment 6 address. */ | ||
1807 | uint32_t dseg_6_length; /* Data segment 6 length. */ | ||
1808 | } cont_entry_t; | 1796 | } cont_entry_t; |
1809 | 1797 | ||
1810 | /* | 1798 | /* |
@@ -1816,16 +1804,7 @@ typedef struct { | |||
1816 | uint8_t entry_count; /* Entry count. */ | 1804 | uint8_t entry_count; /* Entry count. */ |
1817 | uint8_t sys_define; /* System defined. */ | 1805 | uint8_t sys_define; /* System defined. */ |
1818 | uint8_t entry_status; /* Entry Status. */ | 1806 | uint8_t entry_status; /* Entry Status. */ |
1819 | uint32_t dseg_0_address[2]; /* Data segment 0 address. */ | 1807 | struct dsd64 dsd[5]; |
1820 | uint32_t dseg_0_length; /* Data segment 0 length. */ | ||
1821 | uint32_t dseg_1_address[2]; /* Data segment 1 address. */ | ||
1822 | uint32_t dseg_1_length; /* Data segment 1 length. */ | ||
1823 | uint32_t dseg_2_address [2]; /* Data segment 2 address. */ | ||
1824 | uint32_t dseg_2_length; /* Data segment 2 length. */ | ||
1825 | uint32_t dseg_3_address[2]; /* Data segment 3 address. */ | ||
1826 | uint32_t dseg_3_length; /* Data segment 3 length. */ | ||
1827 | uint32_t dseg_4_address[2]; /* Data segment 4 address. */ | ||
1828 | uint32_t dseg_4_length; /* Data segment 4 length. */ | ||
1829 | } cont_a64_entry_t; | 1808 | } cont_a64_entry_t; |
1830 | 1809 | ||
1831 | #define PO_MODE_DIF_INSERT 0 | 1810 | #define PO_MODE_DIF_INSERT 0 |
@@ -1869,8 +1848,7 @@ struct crc_context { | |||
1869 | uint16_t reserved_2; | 1848 | uint16_t reserved_2; |
1870 | uint16_t reserved_3; | 1849 | uint16_t reserved_3; |
1871 | uint32_t reserved_4; | 1850 | uint32_t reserved_4; |
1872 | uint32_t data_address[2]; | 1851 | struct dsd64 data_dsd; |
1873 | uint32_t data_length; | ||
1874 | uint32_t reserved_5[2]; | 1852 | uint32_t reserved_5[2]; |
1875 | uint32_t reserved_6; | 1853 | uint32_t reserved_6; |
1876 | } nobundling; | 1854 | } nobundling; |
@@ -1880,11 +1858,8 @@ struct crc_context { | |||
1880 | uint16_t reserved_1; | 1858 | uint16_t reserved_1; |
1881 | __le16 dseg_count; /* Data segment count */ | 1859 | __le16 dseg_count; /* Data segment count */ |
1882 | uint32_t reserved_2; | 1860 | uint32_t reserved_2; |
1883 | uint32_t data_address[2]; | 1861 | struct dsd64 data_dsd; |
1884 | uint32_t data_length; | 1862 | struct dsd64 dif_dsd; |
1885 | uint32_t dif_address[2]; | ||
1886 | uint32_t dif_length; /* Data segment 0 | ||
1887 | * length */ | ||
1888 | } bundling; | 1863 | } bundling; |
1889 | } u; | 1864 | } u; |
1890 | 1865 | ||
@@ -2083,10 +2058,8 @@ typedef struct { | |||
2083 | uint32_t handle2; | 2058 | uint32_t handle2; |
2084 | uint32_t rsp_bytecount; | 2059 | uint32_t rsp_bytecount; |
2085 | uint32_t req_bytecount; | 2060 | uint32_t req_bytecount; |
2086 | uint32_t dseg_req_address[2]; /* Data segment 0 address. */ | 2061 | struct dsd64 req_dsd; |
2087 | uint32_t dseg_req_length; /* Data segment 0 length. */ | 2062 | struct dsd64 rsp_dsd; |
2088 | uint32_t dseg_rsp_address[2]; /* Data segment 1 address. */ | ||
2089 | uint32_t dseg_rsp_length; /* Data segment 1 length. */ | ||
2090 | } ms_iocb_entry_t; | 2063 | } ms_iocb_entry_t; |
2091 | 2064 | ||
2092 | 2065 | ||
@@ -2258,7 +2231,10 @@ typedef enum { | |||
2258 | FCT_BROADCAST, | 2231 | FCT_BROADCAST, |
2259 | FCT_INITIATOR, | 2232 | FCT_INITIATOR, |
2260 | FCT_TARGET, | 2233 | FCT_TARGET, |
2261 | FCT_NVME | 2234 | FCT_NVME_INITIATOR = 0x10, |
2235 | FCT_NVME_TARGET = 0x20, | ||
2236 | FCT_NVME_DISCOVERY = 0x40, | ||
2237 | FCT_NVME = 0xf0, | ||
2262 | } fc_port_type_t; | 2238 | } fc_port_type_t; |
2263 | 2239 | ||
2264 | enum qla_sess_deletion { | 2240 | enum qla_sess_deletion { |
@@ -2463,13 +2439,7 @@ struct event_arg { | |||
2463 | #define FCS_DEVICE_LOST 3 | 2439 | #define FCS_DEVICE_LOST 3 |
2464 | #define FCS_ONLINE 4 | 2440 | #define FCS_ONLINE 4 |
2465 | 2441 | ||
2466 | static const char * const port_state_str[] = { | 2442 | extern const char *const port_state_str[5]; |
2467 | "Unknown", | ||
2468 | "UNCONFIGURED", | ||
2469 | "DEAD", | ||
2470 | "LOST", | ||
2471 | "ONLINE" | ||
2472 | }; | ||
2473 | 2443 | ||
2474 | /* | 2444 | /* |
2475 | * FC port flags. | 2445 | * FC port flags. |
@@ -2672,6 +2642,7 @@ struct ct_fdmiv2_hba_attributes { | |||
2672 | #define FDMI_PORT_SPEED_8GB 0x10 | 2642 | #define FDMI_PORT_SPEED_8GB 0x10 |
2673 | #define FDMI_PORT_SPEED_16GB 0x20 | 2643 | #define FDMI_PORT_SPEED_16GB 0x20 |
2674 | #define FDMI_PORT_SPEED_32GB 0x40 | 2644 | #define FDMI_PORT_SPEED_32GB 0x40 |
2645 | #define FDMI_PORT_SPEED_64GB 0x80 | ||
2675 | #define FDMI_PORT_SPEED_UNKNOWN 0x8000 | 2646 | #define FDMI_PORT_SPEED_UNKNOWN 0x8000 |
2676 | 2647 | ||
2677 | #define FC_CLASS_2 0x04 | 2648 | #define FC_CLASS_2 0x04 |
@@ -3060,7 +3031,7 @@ struct sns_cmd_pkt { | |||
3060 | struct { | 3031 | struct { |
3061 | uint16_t buffer_length; | 3032 | uint16_t buffer_length; |
3062 | uint16_t reserved_1; | 3033 | uint16_t reserved_1; |
3063 | uint32_t buffer_address[2]; | 3034 | __le64 buffer_address __packed; |
3064 | uint16_t subcommand_length; | 3035 | uint16_t subcommand_length; |
3065 | uint16_t reserved_2; | 3036 | uint16_t reserved_2; |
3066 | uint16_t subcommand; | 3037 | uint16_t subcommand; |
@@ -3130,10 +3101,10 @@ struct rsp_que; | |||
3130 | struct isp_operations { | 3101 | struct isp_operations { |
3131 | 3102 | ||
3132 | int (*pci_config) (struct scsi_qla_host *); | 3103 | int (*pci_config) (struct scsi_qla_host *); |
3133 | void (*reset_chip) (struct scsi_qla_host *); | 3104 | int (*reset_chip)(struct scsi_qla_host *); |
3134 | int (*chip_diag) (struct scsi_qla_host *); | 3105 | int (*chip_diag) (struct scsi_qla_host *); |
3135 | void (*config_rings) (struct scsi_qla_host *); | 3106 | void (*config_rings) (struct scsi_qla_host *); |
3136 | void (*reset_adapter) (struct scsi_qla_host *); | 3107 | int (*reset_adapter)(struct scsi_qla_host *); |
3137 | int (*nvram_config) (struct scsi_qla_host *); | 3108 | int (*nvram_config) (struct scsi_qla_host *); |
3138 | void (*update_fw_options) (struct scsi_qla_host *); | 3109 | void (*update_fw_options) (struct scsi_qla_host *); |
3139 | int (*load_risc) (struct scsi_qla_host *, uint32_t *); | 3110 | int (*load_risc) (struct scsi_qla_host *, uint32_t *); |
@@ -3159,9 +3130,9 @@ struct isp_operations { | |||
3159 | void *(*prep_ms_fdmi_iocb) (struct scsi_qla_host *, uint32_t, | 3130 | void *(*prep_ms_fdmi_iocb) (struct scsi_qla_host *, uint32_t, |
3160 | uint32_t); | 3131 | uint32_t); |
3161 | 3132 | ||
3162 | uint8_t *(*read_nvram) (struct scsi_qla_host *, uint8_t *, | 3133 | uint8_t *(*read_nvram)(struct scsi_qla_host *, void *, |
3163 | uint32_t, uint32_t); | 3134 | uint32_t, uint32_t); |
3164 | int (*write_nvram) (struct scsi_qla_host *, uint8_t *, uint32_t, | 3135 | int (*write_nvram)(struct scsi_qla_host *, void *, uint32_t, |
3165 | uint32_t); | 3136 | uint32_t); |
3166 | 3137 | ||
3167 | void (*fw_dump) (struct scsi_qla_host *, int); | 3138 | void (*fw_dump) (struct scsi_qla_host *, int); |
@@ -3170,16 +3141,16 @@ struct isp_operations { | |||
3170 | int (*beacon_off) (struct scsi_qla_host *); | 3141 | int (*beacon_off) (struct scsi_qla_host *); |
3171 | void (*beacon_blink) (struct scsi_qla_host *); | 3142 | void (*beacon_blink) (struct scsi_qla_host *); |
3172 | 3143 | ||
3173 | uint8_t * (*read_optrom) (struct scsi_qla_host *, uint8_t *, | 3144 | void *(*read_optrom)(struct scsi_qla_host *, void *, |
3174 | uint32_t, uint32_t); | 3145 | uint32_t, uint32_t); |
3175 | int (*write_optrom) (struct scsi_qla_host *, uint8_t *, uint32_t, | 3146 | int (*write_optrom)(struct scsi_qla_host *, void *, uint32_t, |
3176 | uint32_t); | 3147 | uint32_t); |
3177 | 3148 | ||
3178 | int (*get_flash_version) (struct scsi_qla_host *, void *); | 3149 | int (*get_flash_version) (struct scsi_qla_host *, void *); |
3179 | int (*start_scsi) (srb_t *); | 3150 | int (*start_scsi) (srb_t *); |
3180 | int (*start_scsi_mq) (srb_t *); | 3151 | int (*start_scsi_mq) (srb_t *); |
3181 | int (*abort_isp) (struct scsi_qla_host *); | 3152 | int (*abort_isp) (struct scsi_qla_host *); |
3182 | int (*iospace_config)(struct qla_hw_data*); | 3153 | int (*iospace_config)(struct qla_hw_data *); |
3183 | int (*initialize_adapter)(struct scsi_qla_host *); | 3154 | int (*initialize_adapter)(struct scsi_qla_host *); |
3184 | }; | 3155 | }; |
3185 | 3156 | ||
@@ -3368,7 +3339,8 @@ struct qla_tc_param { | |||
3368 | #define QLA_MQ_SIZE 32 | 3339 | #define QLA_MQ_SIZE 32 |
3369 | #define QLA_MAX_QUEUES 256 | 3340 | #define QLA_MAX_QUEUES 256 |
3370 | #define ISP_QUE_REG(ha, id) \ | 3341 | #define ISP_QUE_REG(ha, id) \ |
3371 | ((ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) ? \ | 3342 | ((ha->mqenable || IS_QLA83XX(ha) || \ |
3343 | IS_QLA27XX(ha) || IS_QLA28XX(ha)) ? \ | ||
3372 | ((void __iomem *)ha->mqiobase + (QLA_QUE_PAGE * id)) :\ | 3344 | ((void __iomem *)ha->mqiobase + (QLA_QUE_PAGE * id)) :\ |
3373 | ((void __iomem *)ha->iobase)) | 3345 | ((void __iomem *)ha->iobase)) |
3374 | #define QLA_REQ_QUE_ID(tag) \ | 3346 | #define QLA_REQ_QUE_ID(tag) \ |
@@ -3621,6 +3593,8 @@ struct qla_hw_data { | |||
3621 | uint32_t rida_fmt2:1; | 3593 | uint32_t rida_fmt2:1; |
3622 | uint32_t purge_mbox:1; | 3594 | uint32_t purge_mbox:1; |
3623 | uint32_t n2n_bigger:1; | 3595 | uint32_t n2n_bigger:1; |
3596 | uint32_t secure_adapter:1; | ||
3597 | uint32_t secure_fw:1; | ||
3624 | } flags; | 3598 | } flags; |
3625 | 3599 | ||
3626 | uint16_t max_exchg; | 3600 | uint16_t max_exchg; |
@@ -3703,6 +3677,7 @@ struct qla_hw_data { | |||
3703 | #define PORT_SPEED_8GB 0x04 | 3677 | #define PORT_SPEED_8GB 0x04 |
3704 | #define PORT_SPEED_16GB 0x05 | 3678 | #define PORT_SPEED_16GB 0x05 |
3705 | #define PORT_SPEED_32GB 0x06 | 3679 | #define PORT_SPEED_32GB 0x06 |
3680 | #define PORT_SPEED_64GB 0x07 | ||
3706 | #define PORT_SPEED_10GB 0x13 | 3681 | #define PORT_SPEED_10GB 0x13 |
3707 | uint16_t link_data_rate; /* F/W operating speed */ | 3682 | uint16_t link_data_rate; /* F/W operating speed */ |
3708 | uint16_t set_data_rate; /* Set by user */ | 3683 | uint16_t set_data_rate; /* Set by user */ |
@@ -3729,6 +3704,11 @@ struct qla_hw_data { | |||
3729 | #define PCI_DEVICE_ID_QLOGIC_ISP2071 0x2071 | 3704 | #define PCI_DEVICE_ID_QLOGIC_ISP2071 0x2071 |
3730 | #define PCI_DEVICE_ID_QLOGIC_ISP2271 0x2271 | 3705 | #define PCI_DEVICE_ID_QLOGIC_ISP2271 0x2271 |
3731 | #define PCI_DEVICE_ID_QLOGIC_ISP2261 0x2261 | 3706 | #define PCI_DEVICE_ID_QLOGIC_ISP2261 0x2261 |
3707 | #define PCI_DEVICE_ID_QLOGIC_ISP2061 0x2061 | ||
3708 | #define PCI_DEVICE_ID_QLOGIC_ISP2081 0x2081 | ||
3709 | #define PCI_DEVICE_ID_QLOGIC_ISP2089 0x2089 | ||
3710 | #define PCI_DEVICE_ID_QLOGIC_ISP2281 0x2281 | ||
3711 | #define PCI_DEVICE_ID_QLOGIC_ISP2289 0x2289 | ||
3732 | 3712 | ||
3733 | uint32_t isp_type; | 3713 | uint32_t isp_type; |
3734 | #define DT_ISP2100 BIT_0 | 3714 | #define DT_ISP2100 BIT_0 |
@@ -3753,7 +3733,12 @@ struct qla_hw_data { | |||
3753 | #define DT_ISP2071 BIT_19 | 3733 | #define DT_ISP2071 BIT_19 |
3754 | #define DT_ISP2271 BIT_20 | 3734 | #define DT_ISP2271 BIT_20 |
3755 | #define DT_ISP2261 BIT_21 | 3735 | #define DT_ISP2261 BIT_21 |
3756 | #define DT_ISP_LAST (DT_ISP2261 << 1) | 3736 | #define DT_ISP2061 BIT_22 |
3737 | #define DT_ISP2081 BIT_23 | ||
3738 | #define DT_ISP2089 BIT_24 | ||
3739 | #define DT_ISP2281 BIT_25 | ||
3740 | #define DT_ISP2289 BIT_26 | ||
3741 | #define DT_ISP_LAST (DT_ISP2289 << 1) | ||
3757 | 3742 | ||
3758 | uint32_t device_type; | 3743 | uint32_t device_type; |
3759 | #define DT_T10_PI BIT_25 | 3744 | #define DT_T10_PI BIT_25 |
@@ -3788,6 +3773,8 @@ struct qla_hw_data { | |||
3788 | #define IS_QLA2071(ha) (DT_MASK(ha) & DT_ISP2071) | 3773 | #define IS_QLA2071(ha) (DT_MASK(ha) & DT_ISP2071) |
3789 | #define IS_QLA2271(ha) (DT_MASK(ha) & DT_ISP2271) | 3774 | #define IS_QLA2271(ha) (DT_MASK(ha) & DT_ISP2271) |
3790 | #define IS_QLA2261(ha) (DT_MASK(ha) & DT_ISP2261) | 3775 | #define IS_QLA2261(ha) (DT_MASK(ha) & DT_ISP2261) |
3776 | #define IS_QLA2081(ha) (DT_MASK(ha) & DT_ISP2081) | ||
3777 | #define IS_QLA2281(ha) (DT_MASK(ha) & DT_ISP2281) | ||
3791 | 3778 | ||
3792 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ | 3779 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ |
3793 | IS_QLA6312(ha) || IS_QLA6322(ha)) | 3780 | IS_QLA6312(ha) || IS_QLA6322(ha)) |
@@ -3797,6 +3784,7 @@ struct qla_hw_data { | |||
3797 | #define IS_QLA83XX(ha) (IS_QLA2031(ha) || IS_QLA8031(ha)) | 3784 | #define IS_QLA83XX(ha) (IS_QLA2031(ha) || IS_QLA8031(ha)) |
3798 | #define IS_QLA84XX(ha) (IS_QLA8432(ha)) | 3785 | #define IS_QLA84XX(ha) (IS_QLA8432(ha)) |
3799 | #define IS_QLA27XX(ha) (IS_QLA2071(ha) || IS_QLA2271(ha) || IS_QLA2261(ha)) | 3786 | #define IS_QLA27XX(ha) (IS_QLA2071(ha) || IS_QLA2271(ha) || IS_QLA2261(ha)) |
3787 | #define IS_QLA28XX(ha) (IS_QLA2081(ha) || IS_QLA2281(ha)) | ||
3800 | #define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \ | 3788 | #define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \ |
3801 | IS_QLA84XX(ha)) | 3789 | IS_QLA84XX(ha)) |
3802 | #define IS_CNA_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA82XX(ha) || \ | 3790 | #define IS_CNA_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA82XX(ha) || \ |
@@ -3805,14 +3793,15 @@ struct qla_hw_data { | |||
3805 | #define IS_QLA2XXX_MIDTYPE(ha) (IS_QLA24XX(ha) || IS_QLA84XX(ha) || \ | 3793 | #define IS_QLA2XXX_MIDTYPE(ha) (IS_QLA24XX(ha) || IS_QLA84XX(ha) || \ |
3806 | IS_QLA25XX(ha) || IS_QLA81XX(ha) || \ | 3794 | IS_QLA25XX(ha) || IS_QLA81XX(ha) || \ |
3807 | IS_QLA82XX(ha) || IS_QLA83XX(ha) || \ | 3795 | IS_QLA82XX(ha) || IS_QLA83XX(ha) || \ |
3808 | IS_QLA8044(ha) || IS_QLA27XX(ha)) | 3796 | IS_QLA8044(ha) || IS_QLA27XX(ha) || \ |
3797 | IS_QLA28XX(ha)) | ||
3809 | #define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha) || \ | 3798 | #define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha) || \ |
3810 | IS_QLA27XX(ha)) | 3799 | IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
3811 | #define IS_NOPOLLING_TYPE(ha) (IS_QLA81XX(ha) && (ha)->flags.msix_enabled) | 3800 | #define IS_NOPOLLING_TYPE(ha) (IS_QLA81XX(ha) && (ha)->flags.msix_enabled) |
3812 | #define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha) || \ | 3801 | #define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha) || \ |
3813 | IS_QLA27XX(ha)) | 3802 | IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
3814 | #define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha) || \ | 3803 | #define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha) || \ |
3815 | IS_QLA27XX(ha)) | 3804 | IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
3816 | #define IS_ALOGIO_CAPABLE(ha) (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha)) | 3805 | #define IS_ALOGIO_CAPABLE(ha) (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha)) |
3817 | 3806 | ||
3818 | #define IS_T10_PI_CAPABLE(ha) ((ha)->device_type & DT_T10_PI) | 3807 | #define IS_T10_PI_CAPABLE(ha) ((ha)->device_type & DT_T10_PI) |
@@ -3823,28 +3812,34 @@ struct qla_hw_data { | |||
3823 | #define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS) | 3812 | #define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS) |
3824 | #define IS_CT6_SUPPORTED(ha) ((ha)->device_type & DT_CT6_SUPPORTED) | 3813 | #define IS_CT6_SUPPORTED(ha) ((ha)->device_type & DT_CT6_SUPPORTED) |
3825 | #define IS_MQUE_CAPABLE(ha) ((ha)->mqenable || IS_QLA83XX(ha) || \ | 3814 | #define IS_MQUE_CAPABLE(ha) ((ha)->mqenable || IS_QLA83XX(ha) || \ |
3826 | IS_QLA27XX(ha)) | 3815 | IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
3827 | #define IS_BIDI_CAPABLE(ha) ((IS_QLA25XX(ha) || IS_QLA2031(ha))) | 3816 | #define IS_BIDI_CAPABLE(ha) \ |
3817 | (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) | ||
3828 | /* Bit 21 of fw_attributes decides the MCTP capabilities */ | 3818 | /* Bit 21 of fw_attributes decides the MCTP capabilities */ |
3829 | #define IS_MCTP_CAPABLE(ha) (IS_QLA2031(ha) && \ | 3819 | #define IS_MCTP_CAPABLE(ha) (IS_QLA2031(ha) && \ |
3830 | ((ha)->fw_attributes_ext[0] & BIT_0)) | 3820 | ((ha)->fw_attributes_ext[0] & BIT_0)) |
3831 | #define IS_PI_UNINIT_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 3821 | #define IS_PI_UNINIT_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha)) |
3832 | #define IS_PI_IPGUARD_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 3822 | #define IS_PI_IPGUARD_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha)) |
3833 | #define IS_PI_DIFB_DIX0_CAPABLE(ha) (0) | 3823 | #define IS_PI_DIFB_DIX0_CAPABLE(ha) (0) |
3834 | #define IS_PI_SPLIT_DET_CAPABLE_HBA(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 3824 | #define IS_PI_SPLIT_DET_CAPABLE_HBA(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha) || \ |
3825 | IS_QLA28XX(ha)) | ||
3835 | #define IS_PI_SPLIT_DET_CAPABLE(ha) (IS_PI_SPLIT_DET_CAPABLE_HBA(ha) && \ | 3826 | #define IS_PI_SPLIT_DET_CAPABLE(ha) (IS_PI_SPLIT_DET_CAPABLE_HBA(ha) && \ |
3836 | (((ha)->fw_attributes_h << 16 | (ha)->fw_attributes) & BIT_22)) | 3827 | (((ha)->fw_attributes_h << 16 | (ha)->fw_attributes) & BIT_22)) |
3837 | #define IS_ATIO_MSIX_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 3828 | #define IS_ATIO_MSIX_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha) || \ |
3829 | IS_QLA28XX(ha)) | ||
3838 | #define IS_TGT_MODE_CAPABLE(ha) (ha->tgt.atio_q_length) | 3830 | #define IS_TGT_MODE_CAPABLE(ha) (ha->tgt.atio_q_length) |
3839 | #define IS_SHADOW_REG_CAPABLE(ha) (IS_QLA27XX(ha)) | 3831 | #define IS_SHADOW_REG_CAPABLE(ha) (IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
3840 | #define IS_DPORT_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 3832 | #define IS_DPORT_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha) || \ |
3841 | #define IS_FAWWN_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 3833 | IS_QLA28XX(ha)) |
3834 | #define IS_FAWWN_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha) || \ | ||
3835 | IS_QLA28XX(ha)) | ||
3842 | #define IS_EXCHG_OFFLD_CAPABLE(ha) \ | 3836 | #define IS_EXCHG_OFFLD_CAPABLE(ha) \ |
3843 | (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 3837 | (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
3844 | #define IS_EXLOGIN_OFFLD_CAPABLE(ha) \ | 3838 | #define IS_EXLOGIN_OFFLD_CAPABLE(ha) \ |
3845 | (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 3839 | (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || \ |
3840 | IS_QLA27XX(ha) || IS_QLA28XX(ha)) | ||
3846 | #define USE_ASYNC_SCAN(ha) (IS_QLA25XX(ha) || IS_QLA81XX(ha) ||\ | 3841 | #define USE_ASYNC_SCAN(ha) (IS_QLA25XX(ha) || IS_QLA81XX(ha) ||\ |
3847 | IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 3842 | IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
3848 | 3843 | ||
3849 | /* HBA serial number */ | 3844 | /* HBA serial number */ |
3850 | uint8_t serial0; | 3845 | uint8_t serial0; |
@@ -3888,6 +3883,9 @@ struct qla_hw_data { | |||
3888 | void *sfp_data; | 3883 | void *sfp_data; |
3889 | dma_addr_t sfp_data_dma; | 3884 | dma_addr_t sfp_data_dma; |
3890 | 3885 | ||
3886 | void *flt; | ||
3887 | dma_addr_t flt_dma; | ||
3888 | |||
3891 | #define XGMAC_DATA_SIZE 4096 | 3889 | #define XGMAC_DATA_SIZE 4096 |
3892 | void *xgmac_data; | 3890 | void *xgmac_data; |
3893 | dma_addr_t xgmac_data_dma; | 3891 | dma_addr_t xgmac_data_dma; |
@@ -3999,18 +3997,23 @@ struct qla_hw_data { | |||
3999 | uint8_t fw_seriallink_options[4]; | 3997 | uint8_t fw_seriallink_options[4]; |
4000 | uint16_t fw_seriallink_options24[4]; | 3998 | uint16_t fw_seriallink_options24[4]; |
4001 | 3999 | ||
4000 | uint8_t serdes_version[3]; | ||
4002 | uint8_t mpi_version[3]; | 4001 | uint8_t mpi_version[3]; |
4003 | uint32_t mpi_capabilities; | 4002 | uint32_t mpi_capabilities; |
4004 | uint8_t phy_version[3]; | 4003 | uint8_t phy_version[3]; |
4005 | uint8_t pep_version[3]; | 4004 | uint8_t pep_version[3]; |
4006 | 4005 | ||
4007 | /* Firmware dump template */ | 4006 | /* Firmware dump template */ |
4008 | void *fw_dump_template; | 4007 | struct fwdt { |
4009 | uint32_t fw_dump_template_len; | 4008 | void *template; |
4010 | /* Firmware dump information. */ | 4009 | ulong length; |
4010 | ulong dump_size; | ||
4011 | } fwdt[2]; | ||
4011 | struct qla2xxx_fw_dump *fw_dump; | 4012 | struct qla2xxx_fw_dump *fw_dump; |
4012 | uint32_t fw_dump_len; | 4013 | uint32_t fw_dump_len; |
4013 | int fw_dumped; | 4014 | u32 fw_dump_alloc_len; |
4015 | bool fw_dumped; | ||
4016 | bool fw_dump_mpi; | ||
4014 | unsigned long fw_dump_cap_flags; | 4017 | unsigned long fw_dump_cap_flags; |
4015 | #define RISC_PAUSE_CMPL 0 | 4018 | #define RISC_PAUSE_CMPL 0 |
4016 | #define DMA_SHUTDOWN_CMPL 1 | 4019 | #define DMA_SHUTDOWN_CMPL 1 |
@@ -4049,7 +4052,6 @@ struct qla_hw_data { | |||
4049 | uint16_t product_id[4]; | 4052 | uint16_t product_id[4]; |
4050 | 4053 | ||
4051 | uint8_t model_number[16+1]; | 4054 | uint8_t model_number[16+1]; |
4052 | #define BINZERO "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | ||
4053 | char model_desc[80]; | 4055 | char model_desc[80]; |
4054 | uint8_t adapter_id[16+1]; | 4056 | uint8_t adapter_id[16+1]; |
4055 | 4057 | ||
@@ -4089,22 +4091,28 @@ struct qla_hw_data { | |||
4089 | uint32_t fdt_protect_sec_cmd; | 4091 | uint32_t fdt_protect_sec_cmd; |
4090 | uint32_t fdt_wrt_sts_reg_cmd; | 4092 | uint32_t fdt_wrt_sts_reg_cmd; |
4091 | 4093 | ||
4092 | uint32_t flt_region_flt; | 4094 | struct { |
4093 | uint32_t flt_region_fdt; | 4095 | uint32_t flt_region_flt; |
4094 | uint32_t flt_region_boot; | 4096 | uint32_t flt_region_fdt; |
4095 | uint32_t flt_region_boot_sec; | 4097 | uint32_t flt_region_boot; |
4096 | uint32_t flt_region_fw; | 4098 | uint32_t flt_region_boot_sec; |
4097 | uint32_t flt_region_fw_sec; | 4099 | uint32_t flt_region_fw; |
4098 | uint32_t flt_region_vpd_nvram; | 4100 | uint32_t flt_region_fw_sec; |
4099 | uint32_t flt_region_vpd; | 4101 | uint32_t flt_region_vpd_nvram; |
4100 | uint32_t flt_region_vpd_sec; | 4102 | uint32_t flt_region_vpd_nvram_sec; |
4101 | uint32_t flt_region_nvram; | 4103 | uint32_t flt_region_vpd; |
4102 | uint32_t flt_region_npiv_conf; | 4104 | uint32_t flt_region_vpd_sec; |
4103 | uint32_t flt_region_gold_fw; | 4105 | uint32_t flt_region_nvram; |
4104 | uint32_t flt_region_fcp_prio; | 4106 | uint32_t flt_region_nvram_sec; |
4105 | uint32_t flt_region_bootload; | 4107 | uint32_t flt_region_npiv_conf; |
4106 | uint32_t flt_region_img_status_pri; | 4108 | uint32_t flt_region_gold_fw; |
4107 | uint32_t flt_region_img_status_sec; | 4109 | uint32_t flt_region_fcp_prio; |
4110 | uint32_t flt_region_bootload; | ||
4111 | uint32_t flt_region_img_status_pri; | ||
4112 | uint32_t flt_region_img_status_sec; | ||
4113 | uint32_t flt_region_aux_img_status_pri; | ||
4114 | uint32_t flt_region_aux_img_status_sec; | ||
4115 | }; | ||
4108 | uint8_t active_image; | 4116 | uint8_t active_image; |
4109 | 4117 | ||
4110 | /* Needed for BEACON */ | 4118 | /* Needed for BEACON */ |
@@ -4197,8 +4205,8 @@ struct qla_hw_data { | |||
4197 | struct qlt_hw_data tgt; | 4205 | struct qlt_hw_data tgt; |
4198 | int allow_cna_fw_dump; | 4206 | int allow_cna_fw_dump; |
4199 | uint32_t fw_ability_mask; | 4207 | uint32_t fw_ability_mask; |
4200 | uint16_t min_link_speed; | 4208 | uint16_t min_supported_speed; |
4201 | uint16_t max_speed_sup; | 4209 | uint16_t max_supported_speed; |
4202 | 4210 | ||
4203 | /* DMA pool for the DIF bundling buffers */ | 4211 | /* DMA pool for the DIF bundling buffers */ |
4204 | struct dma_pool *dif_bundl_pool; | 4212 | struct dma_pool *dif_bundl_pool; |
@@ -4225,9 +4233,20 @@ struct qla_hw_data { | |||
4225 | 4233 | ||
4226 | atomic_t zio_threshold; | 4234 | atomic_t zio_threshold; |
4227 | uint16_t last_zio_threshold; | 4235 | uint16_t last_zio_threshold; |
4236 | |||
4228 | #define DEFAULT_ZIO_THRESHOLD 5 | 4237 | #define DEFAULT_ZIO_THRESHOLD 5 |
4229 | }; | 4238 | }; |
4230 | 4239 | ||
4240 | struct active_regions { | ||
4241 | uint8_t global; | ||
4242 | struct { | ||
4243 | uint8_t board_config; | ||
4244 | uint8_t vpd_nvram; | ||
4245 | uint8_t npiv_config_0_1; | ||
4246 | uint8_t npiv_config_2_3; | ||
4247 | } aux; | ||
4248 | }; | ||
4249 | |||
4231 | #define FW_ABILITY_MAX_SPEED_MASK 0xFUL | 4250 | #define FW_ABILITY_MAX_SPEED_MASK 0xFUL |
4232 | #define FW_ABILITY_MAX_SPEED_16G 0x0 | 4251 | #define FW_ABILITY_MAX_SPEED_16G 0x0 |
4233 | #define FW_ABILITY_MAX_SPEED_32G 0x1 | 4252 | #define FW_ABILITY_MAX_SPEED_32G 0x1 |
@@ -4315,6 +4334,7 @@ typedef struct scsi_qla_host { | |||
4315 | #define N2N_LOGIN_NEEDED 30 | 4334 | #define N2N_LOGIN_NEEDED 30 |
4316 | #define IOCB_WORK_ACTIVE 31 | 4335 | #define IOCB_WORK_ACTIVE 31 |
4317 | #define SET_ZIO_THRESHOLD_NEEDED 32 | 4336 | #define SET_ZIO_THRESHOLD_NEEDED 32 |
4337 | #define ISP_ABORT_TO_ROM 33 | ||
4318 | 4338 | ||
4319 | unsigned long pci_flags; | 4339 | unsigned long pci_flags; |
4320 | #define PFLG_DISCONNECTED 0 /* PCI device removed */ | 4340 | #define PFLG_DISCONNECTED 0 /* PCI device removed */ |
@@ -4429,7 +4449,7 @@ typedef struct scsi_qla_host { | |||
4429 | int fcport_count; | 4449 | int fcport_count; |
4430 | wait_queue_head_t fcport_waitQ; | 4450 | wait_queue_head_t fcport_waitQ; |
4431 | wait_queue_head_t vref_waitq; | 4451 | wait_queue_head_t vref_waitq; |
4432 | uint8_t min_link_speed_feat; | 4452 | uint8_t min_supported_speed; |
4433 | uint8_t n2n_node_name[WWN_SIZE]; | 4453 | uint8_t n2n_node_name[WWN_SIZE]; |
4434 | uint8_t n2n_port_name[WWN_SIZE]; | 4454 | uint8_t n2n_port_name[WWN_SIZE]; |
4435 | uint16_t n2n_id; | 4455 | uint16_t n2n_id; |
@@ -4441,14 +4461,21 @@ typedef struct scsi_qla_host { | |||
4441 | 4461 | ||
4442 | struct qla27xx_image_status { | 4462 | struct qla27xx_image_status { |
4443 | uint8_t image_status_mask; | 4463 | uint8_t image_status_mask; |
4444 | uint16_t generation_number; | 4464 | uint16_t generation; |
4445 | uint8_t reserved[3]; | ||
4446 | uint8_t ver_minor; | ||
4447 | uint8_t ver_major; | 4465 | uint8_t ver_major; |
4466 | uint8_t ver_minor; | ||
4467 | uint8_t bitmap; /* 28xx only */ | ||
4468 | uint8_t reserved[2]; | ||
4448 | uint32_t checksum; | 4469 | uint32_t checksum; |
4449 | uint32_t signature; | 4470 | uint32_t signature; |
4450 | } __packed; | 4471 | } __packed; |
4451 | 4472 | ||
4473 | /* 28xx aux image status bimap values */ | ||
4474 | #define QLA28XX_AUX_IMG_BOARD_CONFIG BIT_0 | ||
4475 | #define QLA28XX_AUX_IMG_VPD_NVRAM BIT_1 | ||
4476 | #define QLA28XX_AUX_IMG_NPIV_CONFIG_0_1 BIT_2 | ||
4477 | #define QLA28XX_AUX_IMG_NPIV_CONFIG_2_3 BIT_3 | ||
4478 | |||
4452 | #define SET_VP_IDX 1 | 4479 | #define SET_VP_IDX 1 |
4453 | #define SET_AL_PA 2 | 4480 | #define SET_AL_PA 2 |
4454 | #define RESET_VP_IDX 3 | 4481 | #define RESET_VP_IDX 3 |
@@ -4495,6 +4522,24 @@ struct qla2_sgx { | |||
4495 | } \ | 4522 | } \ |
4496 | } | 4523 | } |
4497 | 4524 | ||
4525 | |||
4526 | #define SFUB_CHECKSUM_SIZE 4 | ||
4527 | |||
4528 | struct secure_flash_update_block { | ||
4529 | uint32_t block_info; | ||
4530 | uint32_t signature_lo; | ||
4531 | uint32_t signature_hi; | ||
4532 | uint32_t signature_upper[0x3e]; | ||
4533 | }; | ||
4534 | |||
4535 | struct secure_flash_update_block_pk { | ||
4536 | uint32_t block_info; | ||
4537 | uint32_t signature_lo; | ||
4538 | uint32_t signature_hi; | ||
4539 | uint32_t signature_upper[0x3e]; | ||
4540 | uint32_t public_key[0x41]; | ||
4541 | }; | ||
4542 | |||
4498 | /* | 4543 | /* |
4499 | * Macros to help code, maintain, etc. | 4544 | * Macros to help code, maintain, etc. |
4500 | */ | 4545 | */ |
@@ -4595,6 +4640,7 @@ struct qla2_sgx { | |||
4595 | #define OPTROM_SIZE_81XX 0x400000 | 4640 | #define OPTROM_SIZE_81XX 0x400000 |
4596 | #define OPTROM_SIZE_82XX 0x800000 | 4641 | #define OPTROM_SIZE_82XX 0x800000 |
4597 | #define OPTROM_SIZE_83XX 0x1000000 | 4642 | #define OPTROM_SIZE_83XX 0x1000000 |
4643 | #define OPTROM_SIZE_28XX 0x2000000 | ||
4598 | 4644 | ||
4599 | #define OPTROM_BURST_SIZE 0x1000 | 4645 | #define OPTROM_BURST_SIZE 0x1000 |
4600 | #define OPTROM_BURST_DWORDS (OPTROM_BURST_SIZE / 4) | 4646 | #define OPTROM_BURST_DWORDS (OPTROM_BURST_SIZE / 4) |
@@ -4691,10 +4737,13 @@ struct sff_8247_a0 { | |||
4691 | #define AUTO_DETECT_SFP_SUPPORT(_vha)\ | 4737 | #define AUTO_DETECT_SFP_SUPPORT(_vha)\ |
4692 | (ql2xautodetectsfp && !_vha->vp_idx && \ | 4738 | (ql2xautodetectsfp && !_vha->vp_idx && \ |
4693 | (IS_QLA25XX(_vha->hw) || IS_QLA81XX(_vha->hw) ||\ | 4739 | (IS_QLA25XX(_vha->hw) || IS_QLA81XX(_vha->hw) ||\ |
4694 | IS_QLA83XX(_vha->hw) || IS_QLA27XX(_vha->hw))) | 4740 | IS_QLA83XX(_vha->hw) || IS_QLA27XX(_vha->hw) || \ |
4741 | IS_QLA28XX(_vha->hw))) | ||
4742 | |||
4743 | #define FLASH_SEMAPHORE_REGISTER_ADDR 0x00101016 | ||
4695 | 4744 | ||
4696 | #define USER_CTRL_IRQ(_ha) (ql2xuctrlirq && QLA_TGT_MODE_ENABLED() && \ | 4745 | #define USER_CTRL_IRQ(_ha) (ql2xuctrlirq && QLA_TGT_MODE_ENABLED() && \ |
4697 | (IS_QLA27XX(_ha) || IS_QLA83XX(_ha))) | 4746 | (IS_QLA27XX(_ha) || IS_QLA28XX(_ha) || IS_QLA83XX(_ha))) |
4698 | 4747 | ||
4699 | #define SAVE_TOPO(_ha) { \ | 4748 | #define SAVE_TOPO(_ha) { \ |
4700 | if (_ha->current_topology) \ | 4749 | if (_ha->current_topology) \ |
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index 5819a45ac5ef..a432caebefec 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c | |||
@@ -41,6 +41,7 @@ static int | |||
41 | qla2x00_dfs_tgt_sess_open(struct inode *inode, struct file *file) | 41 | qla2x00_dfs_tgt_sess_open(struct inode *inode, struct file *file) |
42 | { | 42 | { |
43 | scsi_qla_host_t *vha = inode->i_private; | 43 | scsi_qla_host_t *vha = inode->i_private; |
44 | |||
44 | return single_open(file, qla2x00_dfs_tgt_sess_show, vha); | 45 | return single_open(file, qla2x00_dfs_tgt_sess_show, vha); |
45 | } | 46 | } |
46 | 47 | ||
@@ -161,6 +162,7 @@ static int | |||
161 | qla_dfs_fw_resource_cnt_open(struct inode *inode, struct file *file) | 162 | qla_dfs_fw_resource_cnt_open(struct inode *inode, struct file *file) |
162 | { | 163 | { |
163 | struct scsi_qla_host *vha = inode->i_private; | 164 | struct scsi_qla_host *vha = inode->i_private; |
165 | |||
164 | return single_open(file, qla_dfs_fw_resource_cnt_show, vha); | 166 | return single_open(file, qla_dfs_fw_resource_cnt_show, vha); |
165 | } | 167 | } |
166 | 168 | ||
@@ -250,6 +252,7 @@ static int | |||
250 | qla_dfs_tgt_counters_open(struct inode *inode, struct file *file) | 252 | qla_dfs_tgt_counters_open(struct inode *inode, struct file *file) |
251 | { | 253 | { |
252 | struct scsi_qla_host *vha = inode->i_private; | 254 | struct scsi_qla_host *vha = inode->i_private; |
255 | |||
253 | return single_open(file, qla_dfs_tgt_counters_show, vha); | 256 | return single_open(file, qla_dfs_tgt_counters_show, vha); |
254 | } | 257 | } |
255 | 258 | ||
@@ -386,7 +389,7 @@ qla_dfs_naqp_write(struct file *file, const char __user *buffer, | |||
386 | int rc = 0; | 389 | int rc = 0; |
387 | unsigned long num_act_qp; | 390 | unsigned long num_act_qp; |
388 | 391 | ||
389 | if (!(IS_QLA27XX(ha) || IS_QLA83XX(ha))) { | 392 | if (!(IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha))) { |
390 | pr_err("host%ld: this adapter does not support Multi Q.", | 393 | pr_err("host%ld: this adapter does not support Multi Q.", |
391 | vha->host_no); | 394 | vha->host_no); |
392 | return -EINVAL; | 395 | return -EINVAL; |
@@ -438,7 +441,7 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha) | |||
438 | struct qla_hw_data *ha = vha->hw; | 441 | struct qla_hw_data *ha = vha->hw; |
439 | 442 | ||
440 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && | 443 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
441 | !IS_QLA27XX(ha)) | 444 | !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
442 | goto out; | 445 | goto out; |
443 | if (!ha->fce) | 446 | if (!ha->fce) |
444 | goto out; | 447 | goto out; |
@@ -474,7 +477,7 @@ create_nodes: | |||
474 | ha->tgt.dfs_tgt_sess = debugfs_create_file("tgt_sess", | 477 | ha->tgt.dfs_tgt_sess = debugfs_create_file("tgt_sess", |
475 | S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_sess_ops); | 478 | S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_sess_ops); |
476 | 479 | ||
477 | if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) | 480 | if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) |
478 | ha->tgt.dfs_naqp = debugfs_create_file("naqp", | 481 | ha->tgt.dfs_naqp = debugfs_create_file("naqp", |
479 | 0400, ha->dfs_dir, vha, &dfs_naqp_ops); | 482 | 0400, ha->dfs_dir, vha, &dfs_naqp_ops); |
480 | out: | 483 | out: |
diff --git a/drivers/scsi/qla2xxx/qla_dsd.h b/drivers/scsi/qla2xxx/qla_dsd.h new file mode 100644 index 000000000000..7479924ba422 --- /dev/null +++ b/drivers/scsi/qla2xxx/qla_dsd.h | |||
@@ -0,0 +1,30 @@ | |||
1 | #ifndef _QLA_DSD_H_ | ||
2 | #define _QLA_DSD_H_ | ||
3 | |||
4 | /* 32-bit data segment descriptor (8 bytes) */ | ||
5 | struct dsd32 { | ||
6 | __le32 address; | ||
7 | __le32 length; | ||
8 | }; | ||
9 | |||
10 | static inline void append_dsd32(struct dsd32 **dsd, struct scatterlist *sg) | ||
11 | { | ||
12 | put_unaligned_le32(sg_dma_address(sg), &(*dsd)->address); | ||
13 | put_unaligned_le32(sg_dma_len(sg), &(*dsd)->length); | ||
14 | (*dsd)++; | ||
15 | } | ||
16 | |||
17 | /* 64-bit data segment descriptor (12 bytes) */ | ||
18 | struct dsd64 { | ||
19 | __le64 address; | ||
20 | __le32 length; | ||
21 | } __packed; | ||
22 | |||
23 | static inline void append_dsd64(struct dsd64 **dsd, struct scatterlist *sg) | ||
24 | { | ||
25 | put_unaligned_le64(sg_dma_address(sg), &(*dsd)->address); | ||
26 | put_unaligned_le32(sg_dma_len(sg), &(*dsd)->length); | ||
27 | (*dsd)++; | ||
28 | } | ||
29 | |||
30 | #endif | ||
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 50c1e6c62e31..df079a8c2b33 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -10,6 +10,8 @@ | |||
10 | #include <linux/nvme.h> | 10 | #include <linux/nvme.h> |
11 | #include <linux/nvme-fc.h> | 11 | #include <linux/nvme-fc.h> |
12 | 12 | ||
13 | #include "qla_dsd.h" | ||
14 | |||
13 | #define MBS_CHECKSUM_ERROR 0x4010 | 15 | #define MBS_CHECKSUM_ERROR 0x4010 |
14 | #define MBS_INVALID_PRODUCT_KEY 0x4020 | 16 | #define MBS_INVALID_PRODUCT_KEY 0x4020 |
15 | 17 | ||
@@ -339,9 +341,9 @@ struct init_cb_24xx { | |||
339 | 341 | ||
340 | uint16_t prio_request_q_length; | 342 | uint16_t prio_request_q_length; |
341 | 343 | ||
342 | uint32_t request_q_address[2]; | 344 | __le64 request_q_address __packed; |
343 | uint32_t response_q_address[2]; | 345 | __le64 response_q_address __packed; |
344 | uint32_t prio_request_q_address[2]; | 346 | __le64 prio_request_q_address __packed; |
345 | 347 | ||
346 | uint16_t msix; | 348 | uint16_t msix; |
347 | uint16_t msix_atio; | 349 | uint16_t msix_atio; |
@@ -349,7 +351,7 @@ struct init_cb_24xx { | |||
349 | 351 | ||
350 | uint16_t atio_q_inpointer; | 352 | uint16_t atio_q_inpointer; |
351 | uint16_t atio_q_length; | 353 | uint16_t atio_q_length; |
352 | uint32_t atio_q_address[2]; | 354 | __le64 atio_q_address __packed; |
353 | 355 | ||
354 | uint16_t interrupt_delay_timer; /* 100us increments. */ | 356 | uint16_t interrupt_delay_timer; /* 100us increments. */ |
355 | uint16_t login_timeout; | 357 | uint16_t login_timeout; |
@@ -453,7 +455,7 @@ struct cmd_bidir { | |||
453 | #define BD_WRITE_DATA BIT_0 | 455 | #define BD_WRITE_DATA BIT_0 |
454 | 456 | ||
455 | uint16_t fcp_cmnd_dseg_len; /* Data segment length. */ | 457 | uint16_t fcp_cmnd_dseg_len; /* Data segment length. */ |
456 | uint32_t fcp_cmnd_dseg_address[2]; /* Data segment address. */ | 458 | __le64 fcp_cmnd_dseg_address __packed;/* Data segment address. */ |
457 | 459 | ||
458 | uint16_t reserved[2]; /* Reserved */ | 460 | uint16_t reserved[2]; /* Reserved */ |
459 | 461 | ||
@@ -463,8 +465,7 @@ struct cmd_bidir { | |||
463 | uint8_t port_id[3]; /* PortID of destination port.*/ | 465 | uint8_t port_id[3]; /* PortID of destination port.*/ |
464 | uint8_t vp_index; | 466 | uint8_t vp_index; |
465 | 467 | ||
466 | uint32_t fcp_data_dseg_address[2]; /* Data segment address. */ | 468 | struct dsd64 fcp_dsd; |
467 | uint16_t fcp_data_dseg_len; /* Data segment length. */ | ||
468 | }; | 469 | }; |
469 | 470 | ||
470 | #define COMMAND_TYPE_6 0x48 /* Command Type 6 entry */ | 471 | #define COMMAND_TYPE_6 0x48 /* Command Type 6 entry */ |
@@ -491,18 +492,18 @@ struct cmd_type_6 { | |||
491 | #define CF_READ_DATA BIT_1 | 492 | #define CF_READ_DATA BIT_1 |
492 | #define CF_WRITE_DATA BIT_0 | 493 | #define CF_WRITE_DATA BIT_0 |
493 | 494 | ||
494 | uint16_t fcp_cmnd_dseg_len; /* Data segment length. */ | 495 | uint16_t fcp_cmnd_dseg_len; /* Data segment length. */ |
495 | uint32_t fcp_cmnd_dseg_address[2]; /* Data segment address. */ | 496 | /* Data segment address. */ |
496 | 497 | __le64 fcp_cmnd_dseg_address __packed; | |
497 | uint32_t fcp_rsp_dseg_address[2]; /* Data segment address. */ | 498 | /* Data segment address. */ |
499 | __le64 fcp_rsp_dseg_address __packed; | ||
498 | 500 | ||
499 | uint32_t byte_count; /* Total byte count. */ | 501 | uint32_t byte_count; /* Total byte count. */ |
500 | 502 | ||
501 | uint8_t port_id[3]; /* PortID of destination port. */ | 503 | uint8_t port_id[3]; /* PortID of destination port. */ |
502 | uint8_t vp_index; | 504 | uint8_t vp_index; |
503 | 505 | ||
504 | uint32_t fcp_data_dseg_address[2]; /* Data segment address. */ | 506 | struct dsd64 fcp_dsd; |
505 | uint32_t fcp_data_dseg_len; /* Data segment length. */ | ||
506 | }; | 507 | }; |
507 | 508 | ||
508 | #define COMMAND_TYPE_7 0x18 /* Command Type 7 entry */ | 509 | #define COMMAND_TYPE_7 0x18 /* Command Type 7 entry */ |
@@ -548,8 +549,7 @@ struct cmd_type_7 { | |||
548 | uint8_t port_id[3]; /* PortID of destination port. */ | 549 | uint8_t port_id[3]; /* PortID of destination port. */ |
549 | uint8_t vp_index; | 550 | uint8_t vp_index; |
550 | 551 | ||
551 | uint32_t dseg_0_address[2]; /* Data segment 0 address. */ | 552 | struct dsd64 dsd; |
552 | uint32_t dseg_0_len; /* Data segment 0 length. */ | ||
553 | }; | 553 | }; |
554 | 554 | ||
555 | #define COMMAND_TYPE_CRC_2 0x6A /* Command Type CRC_2 (Type 6) | 555 | #define COMMAND_TYPE_CRC_2 0x6A /* Command Type CRC_2 (Type 6) |
@@ -573,17 +573,17 @@ struct cmd_type_crc_2 { | |||
573 | 573 | ||
574 | uint16_t control_flags; /* Control flags. */ | 574 | uint16_t control_flags; /* Control flags. */ |
575 | 575 | ||
576 | uint16_t fcp_cmnd_dseg_len; /* Data segment length. */ | 576 | uint16_t fcp_cmnd_dseg_len; /* Data segment length. */ |
577 | uint32_t fcp_cmnd_dseg_address[2]; /* Data segment address. */ | 577 | __le64 fcp_cmnd_dseg_address __packed; |
578 | 578 | /* Data segment address. */ | |
579 | uint32_t fcp_rsp_dseg_address[2]; /* Data segment address. */ | 579 | __le64 fcp_rsp_dseg_address __packed; |
580 | 580 | ||
581 | uint32_t byte_count; /* Total byte count. */ | 581 | uint32_t byte_count; /* Total byte count. */ |
582 | 582 | ||
583 | uint8_t port_id[3]; /* PortID of destination port. */ | 583 | uint8_t port_id[3]; /* PortID of destination port. */ |
584 | uint8_t vp_index; | 584 | uint8_t vp_index; |
585 | 585 | ||
586 | uint32_t crc_context_address[2]; /* Data segment address. */ | 586 | __le64 crc_context_address __packed; /* Data segment address. */ |
587 | uint16_t crc_context_len; /* Data segment length. */ | 587 | uint16_t crc_context_len; /* Data segment length. */ |
588 | uint16_t reserved_1; /* MUST be set to 0. */ | 588 | uint16_t reserved_1; /* MUST be set to 0. */ |
589 | }; | 589 | }; |
@@ -717,10 +717,7 @@ struct ct_entry_24xx { | |||
717 | uint32_t rsp_byte_count; | 717 | uint32_t rsp_byte_count; |
718 | uint32_t cmd_byte_count; | 718 | uint32_t cmd_byte_count; |
719 | 719 | ||
720 | uint32_t dseg_0_address[2]; /* Data segment 0 address. */ | 720 | struct dsd64 dsd[2]; |
721 | uint32_t dseg_0_len; /* Data segment 0 length. */ | ||
722 | uint32_t dseg_1_address[2]; /* Data segment 1 address. */ | ||
723 | uint32_t dseg_1_len; /* Data segment 1 length. */ | ||
724 | }; | 721 | }; |
725 | 722 | ||
726 | /* | 723 | /* |
@@ -767,9 +764,9 @@ struct els_entry_24xx { | |||
767 | uint32_t rx_byte_count; | 764 | uint32_t rx_byte_count; |
768 | uint32_t tx_byte_count; | 765 | uint32_t tx_byte_count; |
769 | 766 | ||
770 | uint32_t tx_address[2]; /* Data segment 0 address. */ | 767 | __le64 tx_address __packed; /* Data segment 0 address. */ |
771 | uint32_t tx_len; /* Data segment 0 length. */ | 768 | uint32_t tx_len; /* Data segment 0 length. */ |
772 | uint32_t rx_address[2]; /* Data segment 1 address. */ | 769 | __le64 rx_address __packed; /* Data segment 1 address. */ |
773 | uint32_t rx_len; /* Data segment 1 length. */ | 770 | uint32_t rx_len; /* Data segment 1 length. */ |
774 | }; | 771 | }; |
775 | 772 | ||
@@ -1422,9 +1419,9 @@ struct vf_evfp_entry_24xx { | |||
1422 | uint16_t control_flags; | 1419 | uint16_t control_flags; |
1423 | uint32_t io_parameter_0; | 1420 | uint32_t io_parameter_0; |
1424 | uint32_t io_parameter_1; | 1421 | uint32_t io_parameter_1; |
1425 | uint32_t tx_address[2]; /* Data segment 0 address. */ | 1422 | __le64 tx_address __packed; /* Data segment 0 address. */ |
1426 | uint32_t tx_len; /* Data segment 0 length. */ | 1423 | uint32_t tx_len; /* Data segment 0 length. */ |
1427 | uint32_t rx_address[2]; /* Data segment 1 address. */ | 1424 | __le64 rx_address __packed; /* Data segment 1 address. */ |
1428 | uint32_t rx_len; /* Data segment 1 length. */ | 1425 | uint32_t rx_len; /* Data segment 1 length. */ |
1429 | }; | 1426 | }; |
1430 | 1427 | ||
@@ -1515,13 +1512,31 @@ struct qla_flt_header { | |||
1515 | #define FLT_REG_VPD_SEC_27XX_2 0xD8 | 1512 | #define FLT_REG_VPD_SEC_27XX_2 0xD8 |
1516 | #define FLT_REG_VPD_SEC_27XX_3 0xDA | 1513 | #define FLT_REG_VPD_SEC_27XX_3 0xDA |
1517 | 1514 | ||
1515 | /* 28xx */ | ||
1516 | #define FLT_REG_AUX_IMG_PRI_28XX 0x125 | ||
1517 | #define FLT_REG_AUX_IMG_SEC_28XX 0x126 | ||
1518 | #define FLT_REG_VPD_SEC_28XX_0 0x10C | ||
1519 | #define FLT_REG_VPD_SEC_28XX_1 0x10E | ||
1520 | #define FLT_REG_VPD_SEC_28XX_2 0x110 | ||
1521 | #define FLT_REG_VPD_SEC_28XX_3 0x112 | ||
1522 | #define FLT_REG_NVRAM_SEC_28XX_0 0x10D | ||
1523 | #define FLT_REG_NVRAM_SEC_28XX_1 0x10F | ||
1524 | #define FLT_REG_NVRAM_SEC_28XX_2 0x111 | ||
1525 | #define FLT_REG_NVRAM_SEC_28XX_3 0x113 | ||
1526 | |||
1518 | struct qla_flt_region { | 1527 | struct qla_flt_region { |
1519 | uint32_t code; | 1528 | uint16_t code; |
1529 | uint8_t attribute; | ||
1530 | uint8_t reserved; | ||
1520 | uint32_t size; | 1531 | uint32_t size; |
1521 | uint32_t start; | 1532 | uint32_t start; |
1522 | uint32_t end; | 1533 | uint32_t end; |
1523 | }; | 1534 | }; |
1524 | 1535 | ||
1536 | #define FLT_REGION_SIZE 16 | ||
1537 | #define FLT_MAX_REGIONS 0xFF | ||
1538 | #define FLT_REGIONS_SIZE (FLT_REGION_SIZE * FLT_MAX_REGIONS) | ||
1539 | |||
1525 | /* Flash NPIV Configuration Table ********************************************/ | 1540 | /* Flash NPIV Configuration Table ********************************************/ |
1526 | 1541 | ||
1527 | struct qla_npiv_header { | 1542 | struct qla_npiv_header { |
@@ -1588,8 +1603,7 @@ struct verify_chip_entry_84xx { | |||
1588 | uint32_t fw_seq_size; | 1603 | uint32_t fw_seq_size; |
1589 | uint32_t relative_offset; | 1604 | uint32_t relative_offset; |
1590 | 1605 | ||
1591 | uint32_t dseg_address[2]; | 1606 | struct dsd64 dsd; |
1592 | uint32_t dseg_length; | ||
1593 | }; | 1607 | }; |
1594 | 1608 | ||
1595 | struct verify_chip_rsp_84xx { | 1609 | struct verify_chip_rsp_84xx { |
@@ -1646,8 +1660,7 @@ struct access_chip_84xx { | |||
1646 | uint32_t total_byte_cnt; | 1660 | uint32_t total_byte_cnt; |
1647 | uint32_t reserved4; | 1661 | uint32_t reserved4; |
1648 | 1662 | ||
1649 | uint32_t dseg_address[2]; | 1663 | struct dsd64 dsd; |
1650 | uint32_t dseg_length; | ||
1651 | }; | 1664 | }; |
1652 | 1665 | ||
1653 | struct access_chip_rsp_84xx { | 1666 | struct access_chip_rsp_84xx { |
@@ -1711,6 +1724,10 @@ struct access_chip_rsp_84xx { | |||
1711 | #define LR_DIST_FW_SHIFT (LR_DIST_FW_POS - LR_DIST_NV_POS) | 1724 | #define LR_DIST_FW_SHIFT (LR_DIST_FW_POS - LR_DIST_NV_POS) |
1712 | #define LR_DIST_FW_FIELD(x) ((x) << LR_DIST_FW_SHIFT & 0xf000) | 1725 | #define LR_DIST_FW_FIELD(x) ((x) << LR_DIST_FW_SHIFT & 0xf000) |
1713 | 1726 | ||
1727 | /* FAC semaphore defines */ | ||
1728 | #define FAC_SEMAPHORE_UNLOCK 0 | ||
1729 | #define FAC_SEMAPHORE_LOCK 1 | ||
1730 | |||
1714 | struct nvram_81xx { | 1731 | struct nvram_81xx { |
1715 | /* NVRAM header. */ | 1732 | /* NVRAM header. */ |
1716 | uint8_t id[4]; | 1733 | uint8_t id[4]; |
@@ -1757,7 +1774,7 @@ struct nvram_81xx { | |||
1757 | uint16_t reserved_6_3[14]; | 1774 | uint16_t reserved_6_3[14]; |
1758 | 1775 | ||
1759 | /* Offset 192. */ | 1776 | /* Offset 192. */ |
1760 | uint8_t min_link_speed; | 1777 | uint8_t min_supported_speed; |
1761 | uint8_t reserved_7_0; | 1778 | uint8_t reserved_7_0; |
1762 | uint16_t reserved_7[31]; | 1779 | uint16_t reserved_7[31]; |
1763 | 1780 | ||
@@ -1911,15 +1928,15 @@ struct init_cb_81xx { | |||
1911 | 1928 | ||
1912 | uint16_t prio_request_q_length; | 1929 | uint16_t prio_request_q_length; |
1913 | 1930 | ||
1914 | uint32_t request_q_address[2]; | 1931 | __le64 request_q_address __packed; |
1915 | uint32_t response_q_address[2]; | 1932 | __le64 response_q_address __packed; |
1916 | uint32_t prio_request_q_address[2]; | 1933 | __le64 prio_request_q_address __packed; |
1917 | 1934 | ||
1918 | uint8_t reserved_4[8]; | 1935 | uint8_t reserved_4[8]; |
1919 | 1936 | ||
1920 | uint16_t atio_q_inpointer; | 1937 | uint16_t atio_q_inpointer; |
1921 | uint16_t atio_q_length; | 1938 | uint16_t atio_q_length; |
1922 | uint32_t atio_q_address[2]; | 1939 | __le64 atio_q_address __packed; |
1923 | 1940 | ||
1924 | uint16_t interrupt_delay_timer; /* 100us increments. */ | 1941 | uint16_t interrupt_delay_timer; /* 100us increments. */ |
1925 | uint16_t login_timeout; | 1942 | uint16_t login_timeout; |
@@ -2005,6 +2022,8 @@ struct ex_init_cb_81xx { | |||
2005 | 2022 | ||
2006 | #define FARX_ACCESS_FLASH_CONF_81XX 0x7FFD0000 | 2023 | #define FARX_ACCESS_FLASH_CONF_81XX 0x7FFD0000 |
2007 | #define FARX_ACCESS_FLASH_DATA_81XX 0x7F800000 | 2024 | #define FARX_ACCESS_FLASH_DATA_81XX 0x7F800000 |
2025 | #define FARX_ACCESS_FLASH_CONF_28XX 0x7FFD0000 | ||
2026 | #define FARX_ACCESS_FLASH_DATA_28XX 0x7F7D0000 | ||
2008 | 2027 | ||
2009 | /* FCP priority config defines *************************************/ | 2028 | /* FCP priority config defines *************************************/ |
2010 | /* operations */ | 2029 | /* operations */ |
@@ -2079,6 +2098,7 @@ struct qla_fcp_prio_cfg { | |||
2079 | #define FA_NPIV_CONF1_ADDR_81 0xD2000 | 2098 | #define FA_NPIV_CONF1_ADDR_81 0xD2000 |
2080 | 2099 | ||
2081 | /* 83XX Flash locations -- occupies second 8MB region. */ | 2100 | /* 83XX Flash locations -- occupies second 8MB region. */ |
2082 | #define FA_FLASH_LAYOUT_ADDR_83 0xFC400 | 2101 | #define FA_FLASH_LAYOUT_ADDR_83 (0x3F1000/4) |
2102 | #define FA_FLASH_LAYOUT_ADDR_28 (0x11000/4) | ||
2083 | 2103 | ||
2084 | #endif | 2104 | #endif |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 4eefe69ca807..bbe69ab5cf3f 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -18,14 +18,14 @@ extern int qla2100_pci_config(struct scsi_qla_host *); | |||
18 | extern int qla2300_pci_config(struct scsi_qla_host *); | 18 | extern int qla2300_pci_config(struct scsi_qla_host *); |
19 | extern int qla24xx_pci_config(scsi_qla_host_t *); | 19 | extern int qla24xx_pci_config(scsi_qla_host_t *); |
20 | extern int qla25xx_pci_config(scsi_qla_host_t *); | 20 | extern int qla25xx_pci_config(scsi_qla_host_t *); |
21 | extern void qla2x00_reset_chip(struct scsi_qla_host *); | 21 | extern int qla2x00_reset_chip(struct scsi_qla_host *); |
22 | extern void qla24xx_reset_chip(struct scsi_qla_host *); | 22 | extern int qla24xx_reset_chip(struct scsi_qla_host *); |
23 | extern int qla2x00_chip_diag(struct scsi_qla_host *); | 23 | extern int qla2x00_chip_diag(struct scsi_qla_host *); |
24 | extern int qla24xx_chip_diag(struct scsi_qla_host *); | 24 | extern int qla24xx_chip_diag(struct scsi_qla_host *); |
25 | extern void qla2x00_config_rings(struct scsi_qla_host *); | 25 | extern void qla2x00_config_rings(struct scsi_qla_host *); |
26 | extern void qla24xx_config_rings(struct scsi_qla_host *); | 26 | extern void qla24xx_config_rings(struct scsi_qla_host *); |
27 | extern void qla2x00_reset_adapter(struct scsi_qla_host *); | 27 | extern int qla2x00_reset_adapter(struct scsi_qla_host *); |
28 | extern void qla24xx_reset_adapter(struct scsi_qla_host *); | 28 | extern int qla24xx_reset_adapter(struct scsi_qla_host *); |
29 | extern int qla2x00_nvram_config(struct scsi_qla_host *); | 29 | extern int qla2x00_nvram_config(struct scsi_qla_host *); |
30 | extern int qla24xx_nvram_config(struct scsi_qla_host *); | 30 | extern int qla24xx_nvram_config(struct scsi_qla_host *); |
31 | extern int qla81xx_nvram_config(struct scsi_qla_host *); | 31 | extern int qla81xx_nvram_config(struct scsi_qla_host *); |
@@ -38,8 +38,7 @@ extern int qla81xx_load_risc(scsi_qla_host_t *, uint32_t *); | |||
38 | 38 | ||
39 | extern int qla2x00_perform_loop_resync(scsi_qla_host_t *); | 39 | extern int qla2x00_perform_loop_resync(scsi_qla_host_t *); |
40 | extern int qla2x00_loop_resync(scsi_qla_host_t *); | 40 | extern int qla2x00_loop_resync(scsi_qla_host_t *); |
41 | 41 | extern void qla2x00_clear_loop_id(fc_port_t *fcport); | |
42 | extern int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *); | ||
43 | 42 | ||
44 | extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); | 43 | extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); |
45 | extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); | 44 | extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); |
@@ -80,6 +79,7 @@ int qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e); | |||
80 | extern void *qla2x00_alloc_iocbs_ready(struct qla_qpair *, srb_t *); | 79 | extern void *qla2x00_alloc_iocbs_ready(struct qla_qpair *, srb_t *); |
81 | extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *); | 80 | extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *); |
82 | 81 | ||
82 | extern void qla2x00_set_fcport_state(fc_port_t *fcport, int state); | ||
83 | extern fc_port_t * | 83 | extern fc_port_t * |
84 | qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t ); | 84 | qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t ); |
85 | 85 | ||
@@ -93,7 +93,6 @@ extern int qla2xxx_mctp_dump(scsi_qla_host_t *); | |||
93 | extern int | 93 | extern int |
94 | qla2x00_alloc_outstanding_cmds(struct qla_hw_data *, struct req_que *); | 94 | qla2x00_alloc_outstanding_cmds(struct qla_hw_data *, struct req_que *); |
95 | extern int qla2x00_init_rings(scsi_qla_host_t *); | 95 | extern int qla2x00_init_rings(scsi_qla_host_t *); |
96 | extern uint8_t qla27xx_find_valid_image(struct scsi_qla_host *); | ||
97 | extern struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *, | 96 | extern struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *, |
98 | int, int, bool); | 97 | int, int, bool); |
99 | extern int qla2xxx_delete_qpair(struct scsi_qla_host *, struct qla_qpair *); | 98 | extern int qla2xxx_delete_qpair(struct scsi_qla_host *, struct qla_qpair *); |
@@ -108,6 +107,11 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *, fc_port_t *); | |||
108 | int qla24xx_detect_sfp(scsi_qla_host_t *vha); | 107 | int qla24xx_detect_sfp(scsi_qla_host_t *vha); |
109 | int qla24xx_post_gpdb_work(struct scsi_qla_host *, fc_port_t *, u8); | 108 | int qla24xx_post_gpdb_work(struct scsi_qla_host *, fc_port_t *, u8); |
110 | 109 | ||
110 | extern void qla28xx_get_aux_images(struct scsi_qla_host *, | ||
111 | struct active_regions *); | ||
112 | extern void qla27xx_get_active_image(struct scsi_qla_host *, | ||
113 | struct active_regions *); | ||
114 | |||
111 | void qla2x00_async_prlo_done(struct scsi_qla_host *, fc_port_t *, | 115 | void qla2x00_async_prlo_done(struct scsi_qla_host *, fc_port_t *, |
112 | uint16_t *); | 116 | uint16_t *); |
113 | extern int qla2x00_post_async_prlo_work(struct scsi_qla_host *, fc_port_t *, | 117 | extern int qla2x00_post_async_prlo_work(struct scsi_qla_host *, fc_port_t *, |
@@ -118,6 +122,7 @@ int qla_post_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport); | |||
118 | void qla_do_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport); | 122 | void qla_do_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport); |
119 | int qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *); | 123 | int qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *); |
120 | void qla_rscn_replay(fc_port_t *fcport); | 124 | void qla_rscn_replay(fc_port_t *fcport); |
125 | extern bool qla24xx_risc_firmware_invalid(uint32_t *); | ||
121 | 126 | ||
122 | /* | 127 | /* |
123 | * Global Data in qla_os.c source file. | 128 | * Global Data in qla_os.c source file. |
@@ -215,7 +220,6 @@ extern void qla24xx_sched_upd_fcport(fc_port_t *); | |||
215 | void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *, | 220 | void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *, |
216 | uint16_t *); | 221 | uint16_t *); |
217 | int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *); | 222 | int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *); |
218 | int qla24xx_async_abort_cmd(srb_t *, bool); | ||
219 | int qla24xx_post_relogin_work(struct scsi_qla_host *vha); | 223 | int qla24xx_post_relogin_work(struct scsi_qla_host *vha); |
220 | void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *); | 224 | void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *); |
221 | 225 | ||
@@ -238,7 +242,7 @@ extern void qla24xx_report_id_acquisition(scsi_qla_host_t *, | |||
238 | struct vp_rpt_id_entry_24xx *); | 242 | struct vp_rpt_id_entry_24xx *); |
239 | extern void qla2x00_do_dpc_all_vps(scsi_qla_host_t *); | 243 | extern void qla2x00_do_dpc_all_vps(scsi_qla_host_t *); |
240 | extern int qla24xx_vport_create_req_sanity_check(struct fc_vport *); | 244 | extern int qla24xx_vport_create_req_sanity_check(struct fc_vport *); |
241 | extern scsi_qla_host_t * qla24xx_create_vhost(struct fc_vport *); | 245 | extern scsi_qla_host_t *qla24xx_create_vhost(struct fc_vport *); |
242 | 246 | ||
243 | extern void qla2x00_sp_free_dma(void *); | 247 | extern void qla2x00_sp_free_dma(void *); |
244 | extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *); | 248 | extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *); |
@@ -276,21 +280,20 @@ extern int qla2x00_start_sp(srb_t *); | |||
276 | extern int qla24xx_dif_start_scsi(srb_t *); | 280 | extern int qla24xx_dif_start_scsi(srb_t *); |
277 | extern int qla2x00_start_bidir(srb_t *, struct scsi_qla_host *, uint32_t); | 281 | extern int qla2x00_start_bidir(srb_t *, struct scsi_qla_host *, uint32_t); |
278 | extern int qla2xxx_dif_start_scsi_mq(srb_t *); | 282 | extern int qla2xxx_dif_start_scsi_mq(srb_t *); |
283 | extern void qla2x00_init_timer(srb_t *sp, unsigned long tmo); | ||
279 | extern unsigned long qla2x00_get_async_timeout(struct scsi_qla_host *); | 284 | extern unsigned long qla2x00_get_async_timeout(struct scsi_qla_host *); |
280 | 285 | ||
281 | extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *); | 286 | extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *); |
282 | extern void *__qla2x00_alloc_iocbs(struct qla_qpair *, srb_t *); | 287 | extern void *__qla2x00_alloc_iocbs(struct qla_qpair *, srb_t *); |
283 | extern int qla2x00_issue_marker(scsi_qla_host_t *, int); | 288 | extern int qla2x00_issue_marker(scsi_qla_host_t *, int); |
284 | extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *, | 289 | extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *, |
285 | uint32_t *, uint16_t, struct qla_tc_param *); | 290 | struct dsd64 *, uint16_t, struct qla_tc_param *); |
286 | extern int qla24xx_walk_and_build_sglist(struct qla_hw_data *, srb_t *, | 291 | extern int qla24xx_walk_and_build_sglist(struct qla_hw_data *, srb_t *, |
287 | uint32_t *, uint16_t, struct qla_tc_param *); | 292 | struct dsd64 *, uint16_t, struct qla_tc_param *); |
288 | extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *, | 293 | extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *, |
289 | uint32_t *, uint16_t, struct qla_tgt_cmd *); | 294 | struct dsd64 *, uint16_t, struct qla_tgt_cmd *); |
290 | extern int qla24xx_get_one_block_sg(uint32_t, struct qla2_sgx *, uint32_t *); | 295 | extern int qla24xx_get_one_block_sg(uint32_t, struct qla2_sgx *, uint32_t *); |
291 | extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *); | 296 | extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *); |
292 | extern int qla24xx_build_scsi_crc_2_iocbs(srb_t *, | ||
293 | struct cmd_type_crc_2 *, uint16_t, uint16_t, uint16_t); | ||
294 | 297 | ||
295 | /* | 298 | /* |
296 | * Global Function Prototypes in qla_mbx.c source file. | 299 | * Global Function Prototypes in qla_mbx.c source file. |
@@ -466,6 +469,8 @@ qla81xx_fac_do_write_enable(scsi_qla_host_t *, int); | |||
466 | extern int | 469 | extern int |
467 | qla81xx_fac_erase_sector(scsi_qla_host_t *, uint32_t, uint32_t); | 470 | qla81xx_fac_erase_sector(scsi_qla_host_t *, uint32_t, uint32_t); |
468 | 471 | ||
472 | extern int qla81xx_fac_semaphore_access(scsi_qla_host_t *, int); | ||
473 | |||
469 | extern int | 474 | extern int |
470 | qla2x00_get_xgmac_stats(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t *); | 475 | qla2x00_get_xgmac_stats(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t *); |
471 | 476 | ||
@@ -511,6 +516,14 @@ extern int qla27xx_get_zio_threshold(scsi_qla_host_t *, uint16_t *); | |||
511 | extern int qla27xx_set_zio_threshold(scsi_qla_host_t *, uint16_t); | 516 | extern int qla27xx_set_zio_threshold(scsi_qla_host_t *, uint16_t); |
512 | int qla24xx_res_count_wait(struct scsi_qla_host *, uint16_t *, int); | 517 | int qla24xx_res_count_wait(struct scsi_qla_host *, uint16_t *, int); |
513 | 518 | ||
519 | extern int qla28xx_secure_flash_update(scsi_qla_host_t *, uint16_t, uint16_t, | ||
520 | uint32_t, dma_addr_t, uint32_t); | ||
521 | |||
522 | extern int qla2xxx_read_remote_register(scsi_qla_host_t *, uint32_t, | ||
523 | uint32_t *); | ||
524 | extern int qla2xxx_write_remote_register(scsi_qla_host_t *, uint32_t, | ||
525 | uint32_t); | ||
526 | |||
514 | /* | 527 | /* |
515 | * Global Function Prototypes in qla_isr.c source file. | 528 | * Global Function Prototypes in qla_isr.c source file. |
516 | */ | 529 | */ |
@@ -542,19 +555,20 @@ fc_port_t *qla2x00_find_fcport_by_nportid(scsi_qla_host_t *, port_id_t *, u8); | |||
542 | */ | 555 | */ |
543 | extern void qla2x00_release_nvram_protection(scsi_qla_host_t *); | 556 | extern void qla2x00_release_nvram_protection(scsi_qla_host_t *); |
544 | extern uint32_t *qla24xx_read_flash_data(scsi_qla_host_t *, uint32_t *, | 557 | extern uint32_t *qla24xx_read_flash_data(scsi_qla_host_t *, uint32_t *, |
545 | uint32_t, uint32_t); | 558 | uint32_t, uint32_t); |
546 | extern uint8_t *qla2x00_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, | 559 | extern uint8_t *qla2x00_read_nvram_data(scsi_qla_host_t *, void *, uint32_t, |
547 | uint32_t); | 560 | uint32_t); |
548 | extern uint8_t *qla24xx_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, | 561 | extern uint8_t *qla24xx_read_nvram_data(scsi_qla_host_t *, void *, uint32_t, |
549 | uint32_t); | 562 | uint32_t); |
550 | extern int qla2x00_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, | 563 | extern int qla2x00_write_nvram_data(scsi_qla_host_t *, void *, uint32_t, |
551 | uint32_t); | 564 | uint32_t); |
552 | extern int qla24xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, | 565 | extern int qla24xx_write_nvram_data(scsi_qla_host_t *, void *, uint32_t, |
553 | uint32_t); | 566 | uint32_t); |
554 | extern uint8_t *qla25xx_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, | 567 | extern uint8_t *qla25xx_read_nvram_data(scsi_qla_host_t *, void *, uint32_t, |
555 | uint32_t); | 568 | uint32_t); |
556 | extern int qla25xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, | 569 | extern int qla25xx_write_nvram_data(scsi_qla_host_t *, void *, uint32_t, |
557 | uint32_t); | 570 | uint32_t); |
571 | |||
558 | extern int qla2x00_is_a_vp_did(scsi_qla_host_t *, uint32_t); | 572 | extern int qla2x00_is_a_vp_did(scsi_qla_host_t *, uint32_t); |
559 | bool qla2x00_check_reg32_for_disconnect(scsi_qla_host_t *, uint32_t); | 573 | bool qla2x00_check_reg32_for_disconnect(scsi_qla_host_t *, uint32_t); |
560 | bool qla2x00_check_reg16_for_disconnect(scsi_qla_host_t *, uint16_t); | 574 | bool qla2x00_check_reg16_for_disconnect(scsi_qla_host_t *, uint16_t); |
@@ -574,18 +588,18 @@ extern int qla83xx_restart_nic_firmware(scsi_qla_host_t *); | |||
574 | extern int qla83xx_access_control(scsi_qla_host_t *, uint16_t, uint32_t, | 588 | extern int qla83xx_access_control(scsi_qla_host_t *, uint16_t, uint32_t, |
575 | uint32_t, uint16_t *); | 589 | uint32_t, uint16_t *); |
576 | 590 | ||
577 | extern uint8_t *qla2x00_read_optrom_data(struct scsi_qla_host *, uint8_t *, | 591 | extern void *qla2x00_read_optrom_data(struct scsi_qla_host *, void *, |
578 | uint32_t, uint32_t); | 592 | uint32_t, uint32_t); |
579 | extern int qla2x00_write_optrom_data(struct scsi_qla_host *, uint8_t *, | 593 | extern int qla2x00_write_optrom_data(struct scsi_qla_host *, void *, |
580 | uint32_t, uint32_t); | 594 | uint32_t, uint32_t); |
581 | extern uint8_t *qla24xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, | 595 | extern void *qla24xx_read_optrom_data(struct scsi_qla_host *, void *, |
582 | uint32_t, uint32_t); | 596 | uint32_t, uint32_t); |
583 | extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, | 597 | extern int qla24xx_write_optrom_data(struct scsi_qla_host *, void *, |
584 | uint32_t, uint32_t); | 598 | uint32_t, uint32_t); |
585 | extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, | 599 | extern void *qla25xx_read_optrom_data(struct scsi_qla_host *, void *, |
586 | uint32_t, uint32_t); | 600 | uint32_t, uint32_t); |
587 | extern uint8_t *qla8044_read_optrom_data(struct scsi_qla_host *, | 601 | extern void *qla8044_read_optrom_data(struct scsi_qla_host *, |
588 | uint8_t *, uint32_t, uint32_t); | 602 | void *, uint32_t, uint32_t); |
589 | extern void qla8044_watchdog(struct scsi_qla_host *vha); | 603 | extern void qla8044_watchdog(struct scsi_qla_host *vha); |
590 | 604 | ||
591 | extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *); | 605 | extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *); |
@@ -610,20 +624,13 @@ extern void qla82xx_fw_dump(scsi_qla_host_t *, int); | |||
610 | extern void qla8044_fw_dump(scsi_qla_host_t *, int); | 624 | extern void qla8044_fw_dump(scsi_qla_host_t *, int); |
611 | 625 | ||
612 | extern void qla27xx_fwdump(scsi_qla_host_t *, int); | 626 | extern void qla27xx_fwdump(scsi_qla_host_t *, int); |
613 | extern ulong qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *); | 627 | extern ulong qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *, void *); |
614 | extern int qla27xx_fwdt_template_valid(void *); | 628 | extern int qla27xx_fwdt_template_valid(void *); |
615 | extern ulong qla27xx_fwdt_template_size(void *); | 629 | extern ulong qla27xx_fwdt_template_size(void *); |
616 | extern const void *qla27xx_fwdt_template_default(void); | ||
617 | extern ulong qla27xx_fwdt_template_default_size(void); | ||
618 | |||
619 | extern void qla2x00_dump_regs(scsi_qla_host_t *); | ||
620 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); | ||
621 | extern void qla2x00_dump_buffer_zipped(uint8_t *, uint32_t); | ||
622 | extern void ql_dump_regs(uint32_t, scsi_qla_host_t *, int32_t); | ||
623 | extern void ql_dump_buffer(uint32_t, scsi_qla_host_t *, int32_t, | ||
624 | uint8_t *, uint32_t); | ||
625 | extern void qla2xxx_dump_post_process(scsi_qla_host_t *, int); | ||
626 | 630 | ||
631 | extern void qla2xxx_dump_post_process(scsi_qla_host_t *, int); | ||
632 | extern void ql_dump_regs(uint, scsi_qla_host_t *, uint); | ||
633 | extern void ql_dump_buffer(uint, scsi_qla_host_t *, uint, void *, uint); | ||
627 | /* | 634 | /* |
628 | * Global Function Prototypes in qla_gs.c source file. | 635 | * Global Function Prototypes in qla_gs.c source file. |
629 | */ | 636 | */ |
@@ -722,7 +729,7 @@ extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); | |||
722 | /* qlafx00 related functions */ | 729 | /* qlafx00 related functions */ |
723 | extern int qlafx00_pci_config(struct scsi_qla_host *); | 730 | extern int qlafx00_pci_config(struct scsi_qla_host *); |
724 | extern int qlafx00_initialize_adapter(struct scsi_qla_host *); | 731 | extern int qlafx00_initialize_adapter(struct scsi_qla_host *); |
725 | extern void qlafx00_soft_reset(scsi_qla_host_t *); | 732 | extern int qlafx00_soft_reset(scsi_qla_host_t *); |
726 | extern int qlafx00_chip_diag(scsi_qla_host_t *); | 733 | extern int qlafx00_chip_diag(scsi_qla_host_t *); |
727 | extern void qlafx00_config_rings(struct scsi_qla_host *); | 734 | extern void qlafx00_config_rings(struct scsi_qla_host *); |
728 | extern char *qlafx00_pci_info_str(struct scsi_qla_host *, char *); | 735 | extern char *qlafx00_pci_info_str(struct scsi_qla_host *, char *); |
@@ -765,16 +772,16 @@ extern int qla82xx_pci_region_offset(struct pci_dev *, int); | |||
765 | extern int qla82xx_iospace_config(struct qla_hw_data *); | 772 | extern int qla82xx_iospace_config(struct qla_hw_data *); |
766 | 773 | ||
767 | /* Initialization related functions */ | 774 | /* Initialization related functions */ |
768 | extern void qla82xx_reset_chip(struct scsi_qla_host *); | 775 | extern int qla82xx_reset_chip(struct scsi_qla_host *); |
769 | extern void qla82xx_config_rings(struct scsi_qla_host *); | 776 | extern void qla82xx_config_rings(struct scsi_qla_host *); |
770 | extern void qla82xx_watchdog(scsi_qla_host_t *); | 777 | extern void qla82xx_watchdog(scsi_qla_host_t *); |
771 | extern int qla82xx_start_firmware(scsi_qla_host_t *); | 778 | extern int qla82xx_start_firmware(scsi_qla_host_t *); |
772 | 779 | ||
773 | /* Firmware and flash related functions */ | 780 | /* Firmware and flash related functions */ |
774 | extern int qla82xx_load_risc(scsi_qla_host_t *, uint32_t *); | 781 | extern int qla82xx_load_risc(scsi_qla_host_t *, uint32_t *); |
775 | extern uint8_t *qla82xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, | 782 | extern void *qla82xx_read_optrom_data(struct scsi_qla_host *, void *, |
776 | uint32_t, uint32_t); | 783 | uint32_t, uint32_t); |
777 | extern int qla82xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, | 784 | extern int qla82xx_write_optrom_data(struct scsi_qla_host *, void *, |
778 | uint32_t, uint32_t); | 785 | uint32_t, uint32_t); |
779 | 786 | ||
780 | /* Mailbox related functions */ | 787 | /* Mailbox related functions */ |
@@ -870,7 +877,7 @@ extern void qla8044_clear_drv_active(struct qla_hw_data *); | |||
870 | void qla8044_get_minidump(struct scsi_qla_host *vha); | 877 | void qla8044_get_minidump(struct scsi_qla_host *vha); |
871 | int qla8044_collect_md_data(struct scsi_qla_host *vha); | 878 | int qla8044_collect_md_data(struct scsi_qla_host *vha); |
872 | extern int qla8044_md_get_template(scsi_qla_host_t *); | 879 | extern int qla8044_md_get_template(scsi_qla_host_t *); |
873 | extern int qla8044_write_optrom_data(struct scsi_qla_host *, uint8_t *, | 880 | extern int qla8044_write_optrom_data(struct scsi_qla_host *, void *, |
874 | uint32_t, uint32_t); | 881 | uint32_t, uint32_t); |
875 | extern irqreturn_t qla8044_intr_handler(int, void *); | 882 | extern irqreturn_t qla8044_intr_handler(int, void *); |
876 | extern void qla82xx_mbx_completion(scsi_qla_host_t *, uint16_t); | 883 | extern void qla82xx_mbx_completion(scsi_qla_host_t *, uint16_t); |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index c6fdad12428e..9f58e591666d 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
@@ -45,13 +45,11 @@ qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg) | |||
45 | ms_pkt->rsp_bytecount = cpu_to_le32(arg->rsp_size); | 45 | ms_pkt->rsp_bytecount = cpu_to_le32(arg->rsp_size); |
46 | ms_pkt->req_bytecount = cpu_to_le32(arg->req_size); | 46 | ms_pkt->req_bytecount = cpu_to_le32(arg->req_size); |
47 | 47 | ||
48 | ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(arg->req_dma)); | 48 | put_unaligned_le64(arg->req_dma, &ms_pkt->req_dsd.address); |
49 | ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(arg->req_dma)); | 49 | ms_pkt->req_dsd.length = ms_pkt->req_bytecount; |
50 | ms_pkt->dseg_req_length = ms_pkt->req_bytecount; | ||
51 | 50 | ||
52 | ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(arg->rsp_dma)); | 51 | put_unaligned_le64(arg->rsp_dma, &ms_pkt->rsp_dsd.address); |
53 | ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(arg->rsp_dma)); | 52 | ms_pkt->rsp_dsd.length = ms_pkt->rsp_bytecount; |
54 | ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount; | ||
55 | 53 | ||
56 | vha->qla_stats.control_requests++; | 54 | vha->qla_stats.control_requests++; |
57 | 55 | ||
@@ -83,13 +81,11 @@ qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg) | |||
83 | ct_pkt->rsp_byte_count = cpu_to_le32(arg->rsp_size); | 81 | ct_pkt->rsp_byte_count = cpu_to_le32(arg->rsp_size); |
84 | ct_pkt->cmd_byte_count = cpu_to_le32(arg->req_size); | 82 | ct_pkt->cmd_byte_count = cpu_to_le32(arg->req_size); |
85 | 83 | ||
86 | ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(arg->req_dma)); | 84 | put_unaligned_le64(arg->req_dma, &ct_pkt->dsd[0].address); |
87 | ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(arg->req_dma)); | 85 | ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count; |
88 | ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; | ||
89 | 86 | ||
90 | ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(arg->rsp_dma)); | 87 | put_unaligned_le64(arg->rsp_dma, &ct_pkt->dsd[1].address); |
91 | ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(arg->rsp_dma)); | 88 | ct_pkt->dsd[1].length = ct_pkt->rsp_byte_count; |
92 | ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; | ||
93 | ct_pkt->vp_index = vha->vp_idx; | 89 | ct_pkt->vp_index = vha->vp_idx; |
94 | 90 | ||
95 | vha->qla_stats.control_requests++; | 91 | vha->qla_stats.control_requests++; |
@@ -152,8 +148,8 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt, | |||
152 | vha->d_id.b.area, vha->d_id.b.al_pa, | 148 | vha->d_id.b.area, vha->d_id.b.al_pa, |
153 | comp_status, ct_rsp->header.response); | 149 | comp_status, ct_rsp->header.response); |
154 | ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, | 150 | ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, |
155 | 0x2078, (uint8_t *)&ct_rsp->header, | 151 | 0x2078, ct_rsp, |
156 | sizeof(struct ct_rsp_hdr)); | 152 | offsetof(typeof(*ct_rsp), rsp)); |
157 | rval = QLA_INVALID_COMMAND; | 153 | rval = QLA_INVALID_COMMAND; |
158 | } else | 154 | } else |
159 | rval = QLA_SUCCESS; | 155 | rval = QLA_SUCCESS; |
@@ -1000,8 +996,7 @@ qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len, | |||
1000 | memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt)); | 996 | memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt)); |
1001 | wc = data_size / 2; /* Size in 16bit words. */ | 997 | wc = data_size / 2; /* Size in 16bit words. */ |
1002 | sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc); | 998 | sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc); |
1003 | sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma)); | 999 | put_unaligned_le64(ha->sns_cmd_dma, &sns_cmd->p.cmd.buffer_address); |
1004 | sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma)); | ||
1005 | sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len); | 1000 | sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len); |
1006 | sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd); | 1001 | sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd); |
1007 | wc = (data_size - 16) / 4; /* Size in 32bit words. */ | 1002 | wc = (data_size - 16) / 4; /* Size in 32bit words. */ |
@@ -1385,6 +1380,7 @@ qla2x00_mgmt_svr_login(scsi_qla_host_t *vha) | |||
1385 | int ret, rval; | 1380 | int ret, rval; |
1386 | uint16_t mb[MAILBOX_REGISTER_COUNT]; | 1381 | uint16_t mb[MAILBOX_REGISTER_COUNT]; |
1387 | struct qla_hw_data *ha = vha->hw; | 1382 | struct qla_hw_data *ha = vha->hw; |
1383 | |||
1388 | ret = QLA_SUCCESS; | 1384 | ret = QLA_SUCCESS; |
1389 | if (vha->flags.management_server_logged_in) | 1385 | if (vha->flags.management_server_logged_in) |
1390 | return ret; | 1386 | return ret; |
@@ -1423,6 +1419,7 @@ qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size, | |||
1423 | { | 1419 | { |
1424 | ms_iocb_entry_t *ms_pkt; | 1420 | ms_iocb_entry_t *ms_pkt; |
1425 | struct qla_hw_data *ha = vha->hw; | 1421 | struct qla_hw_data *ha = vha->hw; |
1422 | |||
1426 | ms_pkt = ha->ms_iocb; | 1423 | ms_pkt = ha->ms_iocb; |
1427 | memset(ms_pkt, 0, sizeof(ms_iocb_entry_t)); | 1424 | memset(ms_pkt, 0, sizeof(ms_iocb_entry_t)); |
1428 | 1425 | ||
@@ -1436,13 +1433,11 @@ qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size, | |||
1436 | ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size); | 1433 | ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size); |
1437 | ms_pkt->req_bytecount = cpu_to_le32(req_size); | 1434 | ms_pkt->req_bytecount = cpu_to_le32(req_size); |
1438 | 1435 | ||
1439 | ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | 1436 | put_unaligned_le64(ha->ct_sns_dma, &ms_pkt->req_dsd.address); |
1440 | ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | 1437 | ms_pkt->req_dsd.length = ms_pkt->req_bytecount; |
1441 | ms_pkt->dseg_req_length = ms_pkt->req_bytecount; | ||
1442 | 1438 | ||
1443 | ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | 1439 | put_unaligned_le64(ha->ct_sns_dma, &ms_pkt->rsp_dsd.address); |
1444 | ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | 1440 | ms_pkt->rsp_dsd.length = ms_pkt->rsp_bytecount; |
1445 | ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount; | ||
1446 | 1441 | ||
1447 | return ms_pkt; | 1442 | return ms_pkt; |
1448 | } | 1443 | } |
@@ -1474,13 +1469,11 @@ qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size, | |||
1474 | ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); | 1469 | ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); |
1475 | ct_pkt->cmd_byte_count = cpu_to_le32(req_size); | 1470 | ct_pkt->cmd_byte_count = cpu_to_le32(req_size); |
1476 | 1471 | ||
1477 | ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | 1472 | put_unaligned_le64(ha->ct_sns_dma, &ct_pkt->dsd[0].address); |
1478 | ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | 1473 | ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count; |
1479 | ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; | ||
1480 | 1474 | ||
1481 | ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); | 1475 | put_unaligned_le64(ha->ct_sns_dma, &ct_pkt->dsd[1].address); |
1482 | ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); | 1476 | ct_pkt->dsd[1].length = ct_pkt->rsp_byte_count; |
1483 | ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; | ||
1484 | ct_pkt->vp_index = vha->vp_idx; | 1477 | ct_pkt->vp_index = vha->vp_idx; |
1485 | 1478 | ||
1486 | return ct_pkt; | 1479 | return ct_pkt; |
@@ -1495,10 +1488,10 @@ qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size) | |||
1495 | 1488 | ||
1496 | if (IS_FWI2_CAPABLE(ha)) { | 1489 | if (IS_FWI2_CAPABLE(ha)) { |
1497 | ct_pkt->cmd_byte_count = cpu_to_le32(req_size); | 1490 | ct_pkt->cmd_byte_count = cpu_to_le32(req_size); |
1498 | ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; | 1491 | ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count; |
1499 | } else { | 1492 | } else { |
1500 | ms_pkt->req_bytecount = cpu_to_le32(req_size); | 1493 | ms_pkt->req_bytecount = cpu_to_le32(req_size); |
1501 | ms_pkt->dseg_req_length = ms_pkt->req_bytecount; | 1494 | ms_pkt->req_dsd.length = ms_pkt->req_bytecount; |
1502 | } | 1495 | } |
1503 | 1496 | ||
1504 | return ms_pkt; | 1497 | return ms_pkt; |
@@ -1794,7 +1787,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *vha) | |||
1794 | if (IS_CNA_CAPABLE(ha)) | 1787 | if (IS_CNA_CAPABLE(ha)) |
1795 | eiter->a.sup_speed = cpu_to_be32( | 1788 | eiter->a.sup_speed = cpu_to_be32( |
1796 | FDMI_PORT_SPEED_10GB); | 1789 | FDMI_PORT_SPEED_10GB); |
1797 | else if (IS_QLA27XX(ha)) | 1790 | else if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
1798 | eiter->a.sup_speed = cpu_to_be32( | 1791 | eiter->a.sup_speed = cpu_to_be32( |
1799 | FDMI_PORT_SPEED_32GB| | 1792 | FDMI_PORT_SPEED_32GB| |
1800 | FDMI_PORT_SPEED_16GB| | 1793 | FDMI_PORT_SPEED_16GB| |
@@ -2373,7 +2366,7 @@ qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha) | |||
2373 | if (IS_CNA_CAPABLE(ha)) | 2366 | if (IS_CNA_CAPABLE(ha)) |
2374 | eiter->a.sup_speed = cpu_to_be32( | 2367 | eiter->a.sup_speed = cpu_to_be32( |
2375 | FDMI_PORT_SPEED_10GB); | 2368 | FDMI_PORT_SPEED_10GB); |
2376 | else if (IS_QLA27XX(ha)) | 2369 | else if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
2377 | eiter->a.sup_speed = cpu_to_be32( | 2370 | eiter->a.sup_speed = cpu_to_be32( |
2378 | FDMI_PORT_SPEED_32GB| | 2371 | FDMI_PORT_SPEED_32GB| |
2379 | FDMI_PORT_SPEED_16GB| | 2372 | FDMI_PORT_SPEED_16GB| |
@@ -2446,7 +2439,7 @@ qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha) | |||
2446 | eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); | 2439 | eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); |
2447 | eiter->len = cpu_to_be16(4 + 4); | 2440 | eiter->len = cpu_to_be16(4 + 4); |
2448 | eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ? | 2441 | eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ? |
2449 | le16_to_cpu(icb24->frame_payload_size): | 2442 | le16_to_cpu(icb24->frame_payload_size) : |
2450 | le16_to_cpu(ha->init_cb->frame_payload_size); | 2443 | le16_to_cpu(ha->init_cb->frame_payload_size); |
2451 | eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size); | 2444 | eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size); |
2452 | size += 4 + 4; | 2445 | size += 4 + 4; |
@@ -2783,6 +2776,31 @@ qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd, | |||
2783 | return &p->p.req; | 2776 | return &p->p.req; |
2784 | } | 2777 | } |
2785 | 2778 | ||
2779 | static uint16_t | ||
2780 | qla2x00_port_speed_capability(uint16_t speed) | ||
2781 | { | ||
2782 | switch (speed) { | ||
2783 | case BIT_15: | ||
2784 | return PORT_SPEED_1GB; | ||
2785 | case BIT_14: | ||
2786 | return PORT_SPEED_2GB; | ||
2787 | case BIT_13: | ||
2788 | return PORT_SPEED_4GB; | ||
2789 | case BIT_12: | ||
2790 | return PORT_SPEED_10GB; | ||
2791 | case BIT_11: | ||
2792 | return PORT_SPEED_8GB; | ||
2793 | case BIT_10: | ||
2794 | return PORT_SPEED_16GB; | ||
2795 | case BIT_8: | ||
2796 | return PORT_SPEED_32GB; | ||
2797 | case BIT_7: | ||
2798 | return PORT_SPEED_64GB; | ||
2799 | default: | ||
2800 | return PORT_SPEED_UNKNOWN; | ||
2801 | } | ||
2802 | } | ||
2803 | |||
2786 | /** | 2804 | /** |
2787 | * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query. | 2805 | * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query. |
2788 | * @vha: HA context | 2806 | * @vha: HA context |
@@ -2855,31 +2873,8 @@ qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list) | |||
2855 | } | 2873 | } |
2856 | rval = QLA_FUNCTION_FAILED; | 2874 | rval = QLA_FUNCTION_FAILED; |
2857 | } else { | 2875 | } else { |
2858 | /* Save port-speed */ | 2876 | list->fp_speed = qla2x00_port_speed_capability( |
2859 | switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) { | 2877 | be16_to_cpu(ct_rsp->rsp.gpsc.speed)); |
2860 | case BIT_15: | ||
2861 | list[i].fp_speed = PORT_SPEED_1GB; | ||
2862 | break; | ||
2863 | case BIT_14: | ||
2864 | list[i].fp_speed = PORT_SPEED_2GB; | ||
2865 | break; | ||
2866 | case BIT_13: | ||
2867 | list[i].fp_speed = PORT_SPEED_4GB; | ||
2868 | break; | ||
2869 | case BIT_12: | ||
2870 | list[i].fp_speed = PORT_SPEED_10GB; | ||
2871 | break; | ||
2872 | case BIT_11: | ||
2873 | list[i].fp_speed = PORT_SPEED_8GB; | ||
2874 | break; | ||
2875 | case BIT_10: | ||
2876 | list[i].fp_speed = PORT_SPEED_16GB; | ||
2877 | break; | ||
2878 | case BIT_8: | ||
2879 | list[i].fp_speed = PORT_SPEED_32GB; | ||
2880 | break; | ||
2881 | } | ||
2882 | |||
2883 | ql_dbg(ql_dbg_disc, vha, 0x205b, | 2878 | ql_dbg(ql_dbg_disc, vha, 0x205b, |
2884 | "GPSC ext entry - fpn " | 2879 | "GPSC ext entry - fpn " |
2885 | "%8phN speeds=%04x speed=%04x.\n", | 2880 | "%8phN speeds=%04x speed=%04x.\n", |
@@ -3031,6 +3026,8 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res) | |||
3031 | "Async done-%s res %x, WWPN %8phC \n", | 3026 | "Async done-%s res %x, WWPN %8phC \n", |
3032 | sp->name, res, fcport->port_name); | 3027 | sp->name, res, fcport->port_name); |
3033 | 3028 | ||
3029 | fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); | ||
3030 | |||
3034 | if (res == QLA_FUNCTION_TIMEOUT) | 3031 | if (res == QLA_FUNCTION_TIMEOUT) |
3035 | return; | 3032 | return; |
3036 | 3033 | ||
@@ -3048,29 +3045,8 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res) | |||
3048 | goto done; | 3045 | goto done; |
3049 | } | 3046 | } |
3050 | } else { | 3047 | } else { |
3051 | switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) { | 3048 | fcport->fp_speed = qla2x00_port_speed_capability( |
3052 | case BIT_15: | 3049 | be16_to_cpu(ct_rsp->rsp.gpsc.speed)); |
3053 | fcport->fp_speed = PORT_SPEED_1GB; | ||
3054 | break; | ||
3055 | case BIT_14: | ||
3056 | fcport->fp_speed = PORT_SPEED_2GB; | ||
3057 | break; | ||
3058 | case BIT_13: | ||
3059 | fcport->fp_speed = PORT_SPEED_4GB; | ||
3060 | break; | ||
3061 | case BIT_12: | ||
3062 | fcport->fp_speed = PORT_SPEED_10GB; | ||
3063 | break; | ||
3064 | case BIT_11: | ||
3065 | fcport->fp_speed = PORT_SPEED_8GB; | ||
3066 | break; | ||
3067 | case BIT_10: | ||
3068 | fcport->fp_speed = PORT_SPEED_16GB; | ||
3069 | break; | ||
3070 | case BIT_8: | ||
3071 | fcport->fp_speed = PORT_SPEED_32GB; | ||
3072 | break; | ||
3073 | } | ||
3074 | 3050 | ||
3075 | ql_dbg(ql_dbg_disc, vha, 0x2054, | 3051 | ql_dbg(ql_dbg_disc, vha, 0x2054, |
3076 | "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n", | 3052 | "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n", |
@@ -4370,6 +4346,7 @@ int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport) | |||
4370 | 4346 | ||
4371 | done_free_sp: | 4347 | done_free_sp: |
4372 | sp->free(sp); | 4348 | sp->free(sp); |
4349 | fcport->flags &= ~FCF_ASYNC_SENT; | ||
4373 | done: | 4350 | done: |
4374 | return rval; | 4351 | return rval; |
4375 | } | 4352 | } |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 0c700b140ce7..54772d4c377f 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -95,6 +95,79 @@ qla2x00_get_async_timeout(struct scsi_qla_host *vha) | |||
95 | return tmo; | 95 | return tmo; |
96 | } | 96 | } |
97 | 97 | ||
98 | static void qla24xx_abort_iocb_timeout(void *data) | ||
99 | { | ||
100 | srb_t *sp = data; | ||
101 | struct srb_iocb *abt = &sp->u.iocb_cmd; | ||
102 | |||
103 | abt->u.abt.comp_status = CS_TIMEOUT; | ||
104 | sp->done(sp, QLA_FUNCTION_TIMEOUT); | ||
105 | } | ||
106 | |||
107 | static void qla24xx_abort_sp_done(void *ptr, int res) | ||
108 | { | ||
109 | srb_t *sp = ptr; | ||
110 | struct srb_iocb *abt = &sp->u.iocb_cmd; | ||
111 | |||
112 | if (del_timer(&sp->u.iocb_cmd.timer)) { | ||
113 | if (sp->flags & SRB_WAKEUP_ON_COMP) | ||
114 | complete(&abt->u.abt.comp); | ||
115 | else | ||
116 | sp->free(sp); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) | ||
121 | { | ||
122 | scsi_qla_host_t *vha = cmd_sp->vha; | ||
123 | struct srb_iocb *abt_iocb; | ||
124 | srb_t *sp; | ||
125 | int rval = QLA_FUNCTION_FAILED; | ||
126 | |||
127 | sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp->fcport, | ||
128 | GFP_ATOMIC); | ||
129 | if (!sp) | ||
130 | goto done; | ||
131 | |||
132 | abt_iocb = &sp->u.iocb_cmd; | ||
133 | sp->type = SRB_ABT_CMD; | ||
134 | sp->name = "abort"; | ||
135 | sp->qpair = cmd_sp->qpair; | ||
136 | if (wait) | ||
137 | sp->flags = SRB_WAKEUP_ON_COMP; | ||
138 | |||
139 | abt_iocb->timeout = qla24xx_abort_iocb_timeout; | ||
140 | init_completion(&abt_iocb->u.abt.comp); | ||
141 | /* FW can send 2 x ABTS's timeout/20s */ | ||
142 | qla2x00_init_timer(sp, 42); | ||
143 | |||
144 | abt_iocb->u.abt.cmd_hndl = cmd_sp->handle; | ||
145 | abt_iocb->u.abt.req_que_no = cpu_to_le16(cmd_sp->qpair->req->id); | ||
146 | |||
147 | sp->done = qla24xx_abort_sp_done; | ||
148 | |||
149 | ql_dbg(ql_dbg_async, vha, 0x507c, | ||
150 | "Abort command issued - hdl=%x, type=%x\n", cmd_sp->handle, | ||
151 | cmd_sp->type); | ||
152 | |||
153 | rval = qla2x00_start_sp(sp); | ||
154 | if (rval != QLA_SUCCESS) | ||
155 | goto done_free_sp; | ||
156 | |||
157 | if (wait) { | ||
158 | wait_for_completion(&abt_iocb->u.abt.comp); | ||
159 | rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ? | ||
160 | QLA_SUCCESS : QLA_FUNCTION_FAILED; | ||
161 | } else { | ||
162 | goto done; | ||
163 | } | ||
164 | |||
165 | done_free_sp: | ||
166 | sp->free(sp); | ||
167 | done: | ||
168 | return rval; | ||
169 | } | ||
170 | |||
98 | void | 171 | void |
99 | qla2x00_async_iocb_timeout(void *data) | 172 | qla2x00_async_iocb_timeout(void *data) |
100 | { | 173 | { |
@@ -514,6 +587,72 @@ done: | |||
514 | return rval; | 587 | return rval; |
515 | } | 588 | } |
516 | 589 | ||
590 | static bool qla2x00_is_reserved_id(scsi_qla_host_t *vha, uint16_t loop_id) | ||
591 | { | ||
592 | struct qla_hw_data *ha = vha->hw; | ||
593 | |||
594 | if (IS_FWI2_CAPABLE(ha)) | ||
595 | return loop_id > NPH_LAST_HANDLE; | ||
596 | |||
597 | return (loop_id > ha->max_loop_id && loop_id < SNS_FIRST_LOOP_ID) || | ||
598 | loop_id == MANAGEMENT_SERVER || loop_id == BROADCAST; | ||
599 | } | ||
600 | |||
601 | /** | ||
602 | * qla2x00_find_new_loop_id - scan through our port list and find a new usable loop ID | ||
603 | * @vha: adapter state pointer. | ||
604 | * @dev: port structure pointer. | ||
605 | * | ||
606 | * Returns: | ||
607 | * qla2x00 local function return status code. | ||
608 | * | ||
609 | * Context: | ||
610 | * Kernel context. | ||
611 | */ | ||
612 | static int qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev) | ||
613 | { | ||
614 | int rval; | ||
615 | struct qla_hw_data *ha = vha->hw; | ||
616 | unsigned long flags = 0; | ||
617 | |||
618 | rval = QLA_SUCCESS; | ||
619 | |||
620 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
621 | |||
622 | dev->loop_id = find_first_zero_bit(ha->loop_id_map, LOOPID_MAP_SIZE); | ||
623 | if (dev->loop_id >= LOOPID_MAP_SIZE || | ||
624 | qla2x00_is_reserved_id(vha, dev->loop_id)) { | ||
625 | dev->loop_id = FC_NO_LOOP_ID; | ||
626 | rval = QLA_FUNCTION_FAILED; | ||
627 | } else { | ||
628 | set_bit(dev->loop_id, ha->loop_id_map); | ||
629 | } | ||
630 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
631 | |||
632 | if (rval == QLA_SUCCESS) | ||
633 | ql_dbg(ql_dbg_disc, dev->vha, 0x2086, | ||
634 | "Assigning new loopid=%x, portid=%x.\n", | ||
635 | dev->loop_id, dev->d_id.b24); | ||
636 | else | ||
637 | ql_log(ql_log_warn, dev->vha, 0x2087, | ||
638 | "No loop_id's available, portid=%x.\n", | ||
639 | dev->d_id.b24); | ||
640 | |||
641 | return rval; | ||
642 | } | ||
643 | |||
644 | void qla2x00_clear_loop_id(fc_port_t *fcport) | ||
645 | { | ||
646 | struct qla_hw_data *ha = fcport->vha->hw; | ||
647 | |||
648 | if (fcport->loop_id == FC_NO_LOOP_ID || | ||
649 | qla2x00_is_reserved_id(fcport->vha, fcport->loop_id)) | ||
650 | return; | ||
651 | |||
652 | clear_bit(fcport->loop_id, ha->loop_id_map); | ||
653 | fcport->loop_id = FC_NO_LOOP_ID; | ||
654 | } | ||
655 | |||
517 | static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, | 656 | static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, |
518 | struct event_arg *ea) | 657 | struct event_arg *ea) |
519 | { | 658 | { |
@@ -1482,6 +1621,7 @@ int qla24xx_post_newsess_work(struct scsi_qla_host *vha, port_id_t *id, | |||
1482 | u8 *port_name, u8 *node_name, void *pla, u8 fc4_type) | 1621 | u8 *port_name, u8 *node_name, void *pla, u8 fc4_type) |
1483 | { | 1622 | { |
1484 | struct qla_work_evt *e; | 1623 | struct qla_work_evt *e; |
1624 | |||
1485 | e = qla2x00_alloc_work(vha, QLA_EVT_NEW_SESS); | 1625 | e = qla2x00_alloc_work(vha, QLA_EVT_NEW_SESS); |
1486 | if (!e) | 1626 | if (!e) |
1487 | return QLA_FUNCTION_FAILED; | 1627 | return QLA_FUNCTION_FAILED; |
@@ -1558,6 +1698,7 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea) | |||
1558 | return; | 1698 | return; |
1559 | { | 1699 | { |
1560 | unsigned long flags; | 1700 | unsigned long flags; |
1701 | |||
1561 | fcport = qla2x00_find_fcport_by_nportid | 1702 | fcport = qla2x00_find_fcport_by_nportid |
1562 | (vha, &ea->id, 1); | 1703 | (vha, &ea->id, 1); |
1563 | if (fcport) { | 1704 | if (fcport) { |
@@ -1620,21 +1761,21 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea) | |||
1620 | */ | 1761 | */ |
1621 | void qla_rscn_replay(fc_port_t *fcport) | 1762 | void qla_rscn_replay(fc_port_t *fcport) |
1622 | { | 1763 | { |
1623 | struct event_arg ea; | 1764 | struct event_arg ea; |
1624 | 1765 | ||
1625 | switch (fcport->disc_state) { | 1766 | switch (fcport->disc_state) { |
1626 | case DSC_DELETE_PEND: | 1767 | case DSC_DELETE_PEND: |
1627 | return; | 1768 | return; |
1628 | default: | 1769 | default: |
1629 | break; | 1770 | break; |
1630 | } | 1771 | } |
1631 | 1772 | ||
1632 | if (fcport->scan_needed) { | 1773 | if (fcport->scan_needed) { |
1633 | memset(&ea, 0, sizeof(ea)); | 1774 | memset(&ea, 0, sizeof(ea)); |
1634 | ea.event = FCME_RSCN; | 1775 | ea.event = FCME_RSCN; |
1635 | ea.id = fcport->d_id; | 1776 | ea.id = fcport->d_id; |
1636 | ea.id.b.rsvd_1 = RSCN_PORT_ADDR; | 1777 | ea.id.b.rsvd_1 = RSCN_PORT_ADDR; |
1637 | qla2x00_fcport_event_handler(fcport->vha, &ea); | 1778 | qla2x00_fcport_event_handler(fcport->vha, &ea); |
1638 | } | 1779 | } |
1639 | } | 1780 | } |
1640 | 1781 | ||
@@ -1717,82 +1858,6 @@ done: | |||
1717 | return rval; | 1858 | return rval; |
1718 | } | 1859 | } |
1719 | 1860 | ||
1720 | static void | ||
1721 | qla24xx_abort_iocb_timeout(void *data) | ||
1722 | { | ||
1723 | srb_t *sp = data; | ||
1724 | struct srb_iocb *abt = &sp->u.iocb_cmd; | ||
1725 | |||
1726 | abt->u.abt.comp_status = CS_TIMEOUT; | ||
1727 | sp->done(sp, QLA_FUNCTION_TIMEOUT); | ||
1728 | } | ||
1729 | |||
1730 | static void | ||
1731 | qla24xx_abort_sp_done(void *ptr, int res) | ||
1732 | { | ||
1733 | srb_t *sp = ptr; | ||
1734 | struct srb_iocb *abt = &sp->u.iocb_cmd; | ||
1735 | |||
1736 | if (del_timer(&sp->u.iocb_cmd.timer)) { | ||
1737 | if (sp->flags & SRB_WAKEUP_ON_COMP) | ||
1738 | complete(&abt->u.abt.comp); | ||
1739 | else | ||
1740 | sp->free(sp); | ||
1741 | } | ||
1742 | } | ||
1743 | |||
1744 | int | ||
1745 | qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) | ||
1746 | { | ||
1747 | scsi_qla_host_t *vha = cmd_sp->vha; | ||
1748 | struct srb_iocb *abt_iocb; | ||
1749 | srb_t *sp; | ||
1750 | int rval = QLA_FUNCTION_FAILED; | ||
1751 | |||
1752 | sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp->fcport, | ||
1753 | GFP_ATOMIC); | ||
1754 | if (!sp) | ||
1755 | goto done; | ||
1756 | |||
1757 | abt_iocb = &sp->u.iocb_cmd; | ||
1758 | sp->type = SRB_ABT_CMD; | ||
1759 | sp->name = "abort"; | ||
1760 | sp->qpair = cmd_sp->qpair; | ||
1761 | if (wait) | ||
1762 | sp->flags = SRB_WAKEUP_ON_COMP; | ||
1763 | |||
1764 | abt_iocb->timeout = qla24xx_abort_iocb_timeout; | ||
1765 | init_completion(&abt_iocb->u.abt.comp); | ||
1766 | /* FW can send 2 x ABTS's timeout/20s */ | ||
1767 | qla2x00_init_timer(sp, 42); | ||
1768 | |||
1769 | abt_iocb->u.abt.cmd_hndl = cmd_sp->handle; | ||
1770 | abt_iocb->u.abt.req_que_no = cpu_to_le16(cmd_sp->qpair->req->id); | ||
1771 | |||
1772 | sp->done = qla24xx_abort_sp_done; | ||
1773 | |||
1774 | ql_dbg(ql_dbg_async, vha, 0x507c, | ||
1775 | "Abort command issued - hdl=%x, type=%x\n", | ||
1776 | cmd_sp->handle, cmd_sp->type); | ||
1777 | |||
1778 | rval = qla2x00_start_sp(sp); | ||
1779 | if (rval != QLA_SUCCESS) | ||
1780 | goto done_free_sp; | ||
1781 | |||
1782 | if (wait) { | ||
1783 | wait_for_completion(&abt_iocb->u.abt.comp); | ||
1784 | rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ? | ||
1785 | QLA_SUCCESS : QLA_FUNCTION_FAILED; | ||
1786 | } else { | ||
1787 | goto done; | ||
1788 | } | ||
1789 | |||
1790 | done_free_sp: | ||
1791 | sp->free(sp); | ||
1792 | done: | ||
1793 | return rval; | ||
1794 | } | ||
1795 | |||
1796 | int | 1861 | int |
1797 | qla24xx_async_abort_command(srb_t *sp) | 1862 | qla24xx_async_abort_command(srb_t *sp) |
1798 | { | 1863 | { |
@@ -2102,6 +2167,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) | |||
2102 | int rval; | 2167 | int rval; |
2103 | struct qla_hw_data *ha = vha->hw; | 2168 | struct qla_hw_data *ha = vha->hw; |
2104 | struct req_que *req = ha->req_q_map[0]; | 2169 | struct req_que *req = ha->req_q_map[0]; |
2170 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
2105 | 2171 | ||
2106 | memset(&vha->qla_stats, 0, sizeof(vha->qla_stats)); | 2172 | memset(&vha->qla_stats, 0, sizeof(vha->qla_stats)); |
2107 | memset(&vha->fc_host_stat, 0, sizeof(vha->fc_host_stat)); | 2173 | memset(&vha->fc_host_stat, 0, sizeof(vha->fc_host_stat)); |
@@ -2136,6 +2202,15 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) | |||
2136 | 2202 | ||
2137 | ha->isp_ops->reset_chip(vha); | 2203 | ha->isp_ops->reset_chip(vha); |
2138 | 2204 | ||
2205 | /* Check for secure flash support */ | ||
2206 | if (IS_QLA28XX(ha)) { | ||
2207 | if (RD_REG_DWORD(®->mailbox12) & BIT_0) { | ||
2208 | ql_log(ql_log_info, vha, 0xffff, "Adapter is Secure\n"); | ||
2209 | ha->flags.secure_adapter = 1; | ||
2210 | } | ||
2211 | } | ||
2212 | |||
2213 | |||
2139 | rval = qla2xxx_get_flash_info(vha); | 2214 | rval = qla2xxx_get_flash_info(vha); |
2140 | if (rval) { | 2215 | if (rval) { |
2141 | ql_log(ql_log_fatal, vha, 0x004f, | 2216 | ql_log(ql_log_fatal, vha, 0x004f, |
@@ -2452,7 +2527,7 @@ qla2x00_isp_firmware(scsi_qla_host_t *vha) | |||
2452 | * | 2527 | * |
2453 | * Returns 0 on success. | 2528 | * Returns 0 on success. |
2454 | */ | 2529 | */ |
2455 | void | 2530 | int |
2456 | qla2x00_reset_chip(scsi_qla_host_t *vha) | 2531 | qla2x00_reset_chip(scsi_qla_host_t *vha) |
2457 | { | 2532 | { |
2458 | unsigned long flags = 0; | 2533 | unsigned long flags = 0; |
@@ -2460,9 +2535,10 @@ qla2x00_reset_chip(scsi_qla_host_t *vha) | |||
2460 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 2535 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
2461 | uint32_t cnt; | 2536 | uint32_t cnt; |
2462 | uint16_t cmd; | 2537 | uint16_t cmd; |
2538 | int rval = QLA_FUNCTION_FAILED; | ||
2463 | 2539 | ||
2464 | if (unlikely(pci_channel_offline(ha->pdev))) | 2540 | if (unlikely(pci_channel_offline(ha->pdev))) |
2465 | return; | 2541 | return rval; |
2466 | 2542 | ||
2467 | ha->isp_ops->disable_intrs(ha); | 2543 | ha->isp_ops->disable_intrs(ha); |
2468 | 2544 | ||
@@ -2588,6 +2664,8 @@ qla2x00_reset_chip(scsi_qla_host_t *vha) | |||
2588 | } | 2664 | } |
2589 | 2665 | ||
2590 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 2666 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
2667 | |||
2668 | return QLA_SUCCESS; | ||
2591 | } | 2669 | } |
2592 | 2670 | ||
2593 | /** | 2671 | /** |
@@ -2828,14 +2906,15 @@ acquired: | |||
2828 | * | 2906 | * |
2829 | * Returns 0 on success. | 2907 | * Returns 0 on success. |
2830 | */ | 2908 | */ |
2831 | void | 2909 | int |
2832 | qla24xx_reset_chip(scsi_qla_host_t *vha) | 2910 | qla24xx_reset_chip(scsi_qla_host_t *vha) |
2833 | { | 2911 | { |
2834 | struct qla_hw_data *ha = vha->hw; | 2912 | struct qla_hw_data *ha = vha->hw; |
2913 | int rval = QLA_FUNCTION_FAILED; | ||
2835 | 2914 | ||
2836 | if (pci_channel_offline(ha->pdev) && | 2915 | if (pci_channel_offline(ha->pdev) && |
2837 | ha->flags.pci_channel_io_perm_failure) { | 2916 | ha->flags.pci_channel_io_perm_failure) { |
2838 | return; | 2917 | return rval; |
2839 | } | 2918 | } |
2840 | 2919 | ||
2841 | ha->isp_ops->disable_intrs(ha); | 2920 | ha->isp_ops->disable_intrs(ha); |
@@ -2843,7 +2922,9 @@ qla24xx_reset_chip(scsi_qla_host_t *vha) | |||
2843 | qla25xx_manipulate_risc_semaphore(vha); | 2922 | qla25xx_manipulate_risc_semaphore(vha); |
2844 | 2923 | ||
2845 | /* Perform RISC reset. */ | 2924 | /* Perform RISC reset. */ |
2846 | qla24xx_reset_risc(vha); | 2925 | rval = qla24xx_reset_risc(vha); |
2926 | |||
2927 | return rval; | ||
2847 | } | 2928 | } |
2848 | 2929 | ||
2849 | /** | 2930 | /** |
@@ -3018,7 +3099,7 @@ qla2x00_alloc_offload_mem(scsi_qla_host_t *vha) | |||
3018 | if (IS_FWI2_CAPABLE(ha)) { | 3099 | if (IS_FWI2_CAPABLE(ha)) { |
3019 | /* Allocate memory for Fibre Channel Event Buffer. */ | 3100 | /* Allocate memory for Fibre Channel Event Buffer. */ |
3020 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && | 3101 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
3021 | !IS_QLA27XX(ha)) | 3102 | !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
3022 | goto try_eft; | 3103 | goto try_eft; |
3023 | 3104 | ||
3024 | if (ha->fce) | 3105 | if (ha->fce) |
@@ -3089,12 +3170,15 @@ eft_err: | |||
3089 | void | 3170 | void |
3090 | qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | 3171 | qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) |
3091 | { | 3172 | { |
3173 | int rval; | ||
3092 | uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size, | 3174 | uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size, |
3093 | eft_size, fce_size, mq_size; | 3175 | eft_size, fce_size, mq_size; |
3094 | struct qla_hw_data *ha = vha->hw; | 3176 | struct qla_hw_data *ha = vha->hw; |
3095 | struct req_que *req = ha->req_q_map[0]; | 3177 | struct req_que *req = ha->req_q_map[0]; |
3096 | struct rsp_que *rsp = ha->rsp_q_map[0]; | 3178 | struct rsp_que *rsp = ha->rsp_q_map[0]; |
3097 | struct qla2xxx_fw_dump *fw_dump; | 3179 | struct qla2xxx_fw_dump *fw_dump; |
3180 | dma_addr_t tc_dma; | ||
3181 | void *tc; | ||
3098 | 3182 | ||
3099 | dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0; | 3183 | dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0; |
3100 | req_q_size = rsp_q_size = 0; | 3184 | req_q_size = rsp_q_size = 0; |
@@ -3106,7 +3190,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
3106 | mem_size = (ha->fw_memory_size - 0x11000 + 1) * | 3190 | mem_size = (ha->fw_memory_size - 0x11000 + 1) * |
3107 | sizeof(uint16_t); | 3191 | sizeof(uint16_t); |
3108 | } else if (IS_FWI2_CAPABLE(ha)) { | 3192 | } else if (IS_FWI2_CAPABLE(ha)) { |
3109 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 3193 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
3110 | fixed_size = offsetof(struct qla83xx_fw_dump, ext_mem); | 3194 | fixed_size = offsetof(struct qla83xx_fw_dump, ext_mem); |
3111 | else if (IS_QLA81XX(ha)) | 3195 | else if (IS_QLA81XX(ha)) |
3112 | fixed_size = offsetof(struct qla81xx_fw_dump, ext_mem); | 3196 | fixed_size = offsetof(struct qla81xx_fw_dump, ext_mem); |
@@ -3118,40 +3202,72 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
3118 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * | 3202 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * |
3119 | sizeof(uint32_t); | 3203 | sizeof(uint32_t); |
3120 | if (ha->mqenable) { | 3204 | if (ha->mqenable) { |
3121 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha)) | 3205 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && |
3206 | !IS_QLA28XX(ha)) | ||
3122 | mq_size = sizeof(struct qla2xxx_mq_chain); | 3207 | mq_size = sizeof(struct qla2xxx_mq_chain); |
3123 | /* | 3208 | /* |
3124 | * Allocate maximum buffer size for all queues. | 3209 | * Allocate maximum buffer size for all queues - Q0. |
3125 | * Resizing must be done at end-of-dump processing. | 3210 | * Resizing must be done at end-of-dump processing. |
3126 | */ | 3211 | */ |
3127 | mq_size += ha->max_req_queues * | 3212 | mq_size += (ha->max_req_queues - 1) * |
3128 | (req->length * sizeof(request_t)); | 3213 | (req->length * sizeof(request_t)); |
3129 | mq_size += ha->max_rsp_queues * | 3214 | mq_size += (ha->max_rsp_queues - 1) * |
3130 | (rsp->length * sizeof(response_t)); | 3215 | (rsp->length * sizeof(response_t)); |
3131 | } | 3216 | } |
3132 | if (ha->tgt.atio_ring) | 3217 | if (ha->tgt.atio_ring) |
3133 | mq_size += ha->tgt.atio_q_length * sizeof(request_t); | 3218 | mq_size += ha->tgt.atio_q_length * sizeof(request_t); |
3134 | /* Allocate memory for Fibre Channel Event Buffer. */ | 3219 | /* Allocate memory for Fibre Channel Event Buffer. */ |
3135 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && | 3220 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
3136 | !IS_QLA27XX(ha)) | 3221 | !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
3137 | goto try_eft; | 3222 | goto try_eft; |
3138 | 3223 | ||
3139 | fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE; | 3224 | fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE; |
3140 | try_eft: | 3225 | try_eft: |
3226 | if (ha->eft) | ||
3227 | dma_free_coherent(&ha->pdev->dev, | ||
3228 | EFT_SIZE, ha->eft, ha->eft_dma); | ||
3229 | |||
3230 | /* Allocate memory for Extended Trace Buffer. */ | ||
3231 | tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, | ||
3232 | GFP_KERNEL); | ||
3233 | if (!tc) { | ||
3234 | ql_log(ql_log_warn, vha, 0x00c1, | ||
3235 | "Unable to allocate (%d KB) for EFT.\n", | ||
3236 | EFT_SIZE / 1024); | ||
3237 | goto allocate; | ||
3238 | } | ||
3239 | |||
3240 | rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS); | ||
3241 | if (rval) { | ||
3242 | ql_log(ql_log_warn, vha, 0x00c2, | ||
3243 | "Unable to initialize EFT (%d).\n", rval); | ||
3244 | dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, | ||
3245 | tc_dma); | ||
3246 | } | ||
3141 | ql_dbg(ql_dbg_init, vha, 0x00c3, | 3247 | ql_dbg(ql_dbg_init, vha, 0x00c3, |
3142 | "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024); | 3248 | "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024); |
3143 | eft_size = EFT_SIZE; | 3249 | eft_size = EFT_SIZE; |
3144 | } | 3250 | } |
3145 | 3251 | ||
3146 | if (IS_QLA27XX(ha)) { | 3252 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
3147 | if (!ha->fw_dump_template) { | 3253 | struct fwdt *fwdt = ha->fwdt; |
3148 | ql_log(ql_log_warn, vha, 0x00ba, | 3254 | uint j; |
3149 | "Failed missing fwdump template\n"); | 3255 | |
3150 | return; | 3256 | for (j = 0; j < 2; j++, fwdt++) { |
3257 | if (!fwdt->template) { | ||
3258 | ql_log(ql_log_warn, vha, 0x00ba, | ||
3259 | "-> fwdt%u no template\n", j); | ||
3260 | continue; | ||
3261 | } | ||
3262 | ql_dbg(ql_dbg_init, vha, 0x00fa, | ||
3263 | "-> fwdt%u calculating fwdump size...\n", j); | ||
3264 | fwdt->dump_size = qla27xx_fwdt_calculate_dump_size( | ||
3265 | vha, fwdt->template); | ||
3266 | ql_dbg(ql_dbg_init, vha, 0x00fa, | ||
3267 | "-> fwdt%u calculated fwdump size = %#lx bytes\n", | ||
3268 | j, fwdt->dump_size); | ||
3269 | dump_size += fwdt->dump_size; | ||
3151 | } | 3270 | } |
3152 | dump_size = qla27xx_fwdt_calculate_dump_size(vha); | ||
3153 | ql_dbg(ql_dbg_init, vha, 0x00fa, | ||
3154 | "-> allocating fwdump (%x bytes)...\n", dump_size); | ||
3155 | goto allocate; | 3271 | goto allocate; |
3156 | } | 3272 | } |
3157 | 3273 | ||
@@ -3170,42 +3286,66 @@ try_eft: | |||
3170 | ha->exlogin_size; | 3286 | ha->exlogin_size; |
3171 | 3287 | ||
3172 | allocate: | 3288 | allocate: |
3173 | if (!ha->fw_dump_len || dump_size != ha->fw_dump_len) { | 3289 | if (!ha->fw_dump_len || dump_size > ha->fw_dump_alloc_len) { |
3290 | |||
3291 | ql_dbg(ql_dbg_init, vha, 0x00c5, | ||
3292 | "%s dump_size %d fw_dump_len %d fw_dump_alloc_len %d\n", | ||
3293 | __func__, dump_size, ha->fw_dump_len, | ||
3294 | ha->fw_dump_alloc_len); | ||
3295 | |||
3174 | fw_dump = vmalloc(dump_size); | 3296 | fw_dump = vmalloc(dump_size); |
3175 | if (!fw_dump) { | 3297 | if (!fw_dump) { |
3176 | ql_log(ql_log_warn, vha, 0x00c4, | 3298 | ql_log(ql_log_warn, vha, 0x00c4, |
3177 | "Unable to allocate (%d KB) for firmware dump.\n", | 3299 | "Unable to allocate (%d KB) for firmware dump.\n", |
3178 | dump_size / 1024); | 3300 | dump_size / 1024); |
3179 | } else { | 3301 | } else { |
3180 | if (ha->fw_dump) | 3302 | mutex_lock(&ha->optrom_mutex); |
3303 | if (ha->fw_dumped) { | ||
3304 | memcpy(fw_dump, ha->fw_dump, ha->fw_dump_len); | ||
3181 | vfree(ha->fw_dump); | 3305 | vfree(ha->fw_dump); |
3182 | ha->fw_dump = fw_dump; | 3306 | ha->fw_dump = fw_dump; |
3183 | 3307 | ha->fw_dump_alloc_len = dump_size; | |
3184 | ha->fw_dump_len = dump_size; | 3308 | ql_dbg(ql_dbg_init, vha, 0x00c5, |
3185 | ql_dbg(ql_dbg_init, vha, 0x00c5, | 3309 | "Re-Allocated (%d KB) and save firmware dump.\n", |
3186 | "Allocated (%d KB) for firmware dump.\n", | 3310 | dump_size / 1024); |
3187 | dump_size / 1024); | 3311 | } else { |
3188 | 3312 | if (ha->fw_dump) | |
3189 | if (IS_QLA27XX(ha)) | 3313 | vfree(ha->fw_dump); |
3190 | return; | 3314 | ha->fw_dump = fw_dump; |
3191 | 3315 | ||
3192 | ha->fw_dump->signature[0] = 'Q'; | 3316 | ha->fw_dump_len = ha->fw_dump_alloc_len = |
3193 | ha->fw_dump->signature[1] = 'L'; | 3317 | dump_size; |
3194 | ha->fw_dump->signature[2] = 'G'; | 3318 | ql_dbg(ql_dbg_init, vha, 0x00c5, |
3195 | ha->fw_dump->signature[3] = 'C'; | 3319 | "Allocated (%d KB) for firmware dump.\n", |
3196 | ha->fw_dump->version = htonl(1); | 3320 | dump_size / 1024); |
3197 | 3321 | ||
3198 | ha->fw_dump->fixed_size = htonl(fixed_size); | 3322 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
3199 | ha->fw_dump->mem_size = htonl(mem_size); | 3323 | mutex_unlock(&ha->optrom_mutex); |
3200 | ha->fw_dump->req_q_size = htonl(req_q_size); | 3324 | return; |
3201 | ha->fw_dump->rsp_q_size = htonl(rsp_q_size); | 3325 | } |
3202 | |||
3203 | ha->fw_dump->eft_size = htonl(eft_size); | ||
3204 | ha->fw_dump->eft_addr_l = htonl(LSD(ha->eft_dma)); | ||
3205 | ha->fw_dump->eft_addr_h = htonl(MSD(ha->eft_dma)); | ||
3206 | 3326 | ||
3207 | ha->fw_dump->header_size = | 3327 | ha->fw_dump->signature[0] = 'Q'; |
3208 | htonl(offsetof(struct qla2xxx_fw_dump, isp)); | 3328 | ha->fw_dump->signature[1] = 'L'; |
3329 | ha->fw_dump->signature[2] = 'G'; | ||
3330 | ha->fw_dump->signature[3] = 'C'; | ||
3331 | ha->fw_dump->version = htonl(1); | ||
3332 | |||
3333 | ha->fw_dump->fixed_size = htonl(fixed_size); | ||
3334 | ha->fw_dump->mem_size = htonl(mem_size); | ||
3335 | ha->fw_dump->req_q_size = htonl(req_q_size); | ||
3336 | ha->fw_dump->rsp_q_size = htonl(rsp_q_size); | ||
3337 | |||
3338 | ha->fw_dump->eft_size = htonl(eft_size); | ||
3339 | ha->fw_dump->eft_addr_l = | ||
3340 | htonl(LSD(ha->eft_dma)); | ||
3341 | ha->fw_dump->eft_addr_h = | ||
3342 | htonl(MSD(ha->eft_dma)); | ||
3343 | |||
3344 | ha->fw_dump->header_size = | ||
3345 | htonl(offsetof | ||
3346 | (struct qla2xxx_fw_dump, isp)); | ||
3347 | } | ||
3348 | mutex_unlock(&ha->optrom_mutex); | ||
3209 | } | 3349 | } |
3210 | } | 3350 | } |
3211 | } | 3351 | } |
@@ -3498,7 +3638,8 @@ qla2x00_setup_chip(scsi_qla_host_t *vha) | |||
3498 | if (rval == QLA_SUCCESS) { | 3638 | if (rval == QLA_SUCCESS) { |
3499 | qla24xx_detect_sfp(vha); | 3639 | qla24xx_detect_sfp(vha); |
3500 | 3640 | ||
3501 | if ((IS_QLA83XX(ha) || IS_QLA27XX(ha)) && | 3641 | if ((IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
3642 | IS_QLA28XX(ha)) && | ||
3502 | (ha->zio_mode == QLA_ZIO_MODE_6)) | 3643 | (ha->zio_mode == QLA_ZIO_MODE_6)) |
3503 | qla27xx_set_zio_threshold(vha, | 3644 | qla27xx_set_zio_threshold(vha, |
3504 | ha->last_zio_threshold); | 3645 | ha->last_zio_threshold); |
@@ -3570,7 +3711,7 @@ enable_82xx_npiv: | |||
3570 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 3711 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
3571 | } | 3712 | } |
3572 | 3713 | ||
3573 | if (IS_QLA27XX(ha)) | 3714 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
3574 | ha->flags.fac_supported = 1; | 3715 | ha->flags.fac_supported = 1; |
3575 | else if (rval == QLA_SUCCESS && IS_FAC_REQUIRED(ha)) { | 3716 | else if (rval == QLA_SUCCESS && IS_FAC_REQUIRED(ha)) { |
3576 | uint32_t size; | 3717 | uint32_t size; |
@@ -3585,7 +3726,8 @@ enable_82xx_npiv: | |||
3585 | ha->fw_major_version, ha->fw_minor_version, | 3726 | ha->fw_major_version, ha->fw_minor_version, |
3586 | ha->fw_subminor_version); | 3727 | ha->fw_subminor_version); |
3587 | 3728 | ||
3588 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 3729 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
3730 | IS_QLA28XX(ha)) { | ||
3589 | ha->flags.fac_supported = 0; | 3731 | ha->flags.fac_supported = 0; |
3590 | rval = QLA_SUCCESS; | 3732 | rval = QLA_SUCCESS; |
3591 | } | 3733 | } |
@@ -3647,8 +3789,7 @@ qla2x00_update_fw_options(scsi_qla_host_t *vha) | |||
3647 | ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x0115, | 3789 | ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x0115, |
3648 | "Serial link options.\n"); | 3790 | "Serial link options.\n"); |
3649 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0109, | 3791 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0109, |
3650 | (uint8_t *)&ha->fw_seriallink_options, | 3792 | ha->fw_seriallink_options, sizeof(ha->fw_seriallink_options)); |
3651 | sizeof(ha->fw_seriallink_options)); | ||
3652 | 3793 | ||
3653 | ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING; | 3794 | ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING; |
3654 | if (ha->fw_seriallink_options[3] & BIT_2) { | 3795 | if (ha->fw_seriallink_options[3] & BIT_2) { |
@@ -3738,7 +3879,7 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha) | |||
3738 | 3879 | ||
3739 | /* Move PUREX, ABTS RX & RIDA to ATIOQ */ | 3880 | /* Move PUREX, ABTS RX & RIDA to ATIOQ */ |
3740 | if (ql2xmvasynctoatio && | 3881 | if (ql2xmvasynctoatio && |
3741 | (IS_QLA83XX(ha) || IS_QLA27XX(ha))) { | 3882 | (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))) { |
3742 | if (qla_tgt_mode_enabled(vha) || | 3883 | if (qla_tgt_mode_enabled(vha) || |
3743 | qla_dual_mode_enabled(vha)) | 3884 | qla_dual_mode_enabled(vha)) |
3744 | ha->fw_options[2] |= BIT_11; | 3885 | ha->fw_options[2] |= BIT_11; |
@@ -3746,7 +3887,8 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha) | |||
3746 | ha->fw_options[2] &= ~BIT_11; | 3887 | ha->fw_options[2] &= ~BIT_11; |
3747 | } | 3888 | } |
3748 | 3889 | ||
3749 | if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 3890 | if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
3891 | IS_QLA28XX(ha)) { | ||
3750 | /* | 3892 | /* |
3751 | * Tell FW to track each exchange to prevent | 3893 | * Tell FW to track each exchange to prevent |
3752 | * driver from using stale exchange. | 3894 | * driver from using stale exchange. |
@@ -3799,10 +3941,8 @@ qla2x00_config_rings(struct scsi_qla_host *vha) | |||
3799 | ha->init_cb->response_q_inpointer = cpu_to_le16(0); | 3941 | ha->init_cb->response_q_inpointer = cpu_to_le16(0); |
3800 | ha->init_cb->request_q_length = cpu_to_le16(req->length); | 3942 | ha->init_cb->request_q_length = cpu_to_le16(req->length); |
3801 | ha->init_cb->response_q_length = cpu_to_le16(rsp->length); | 3943 | ha->init_cb->response_q_length = cpu_to_le16(rsp->length); |
3802 | ha->init_cb->request_q_address[0] = cpu_to_le32(LSD(req->dma)); | 3944 | put_unaligned_le64(req->dma, &ha->init_cb->request_q_address); |
3803 | ha->init_cb->request_q_address[1] = cpu_to_le32(MSD(req->dma)); | 3945 | put_unaligned_le64(rsp->dma, &ha->init_cb->response_q_address); |
3804 | ha->init_cb->response_q_address[0] = cpu_to_le32(LSD(rsp->dma)); | ||
3805 | ha->init_cb->response_q_address[1] = cpu_to_le32(MSD(rsp->dma)); | ||
3806 | 3946 | ||
3807 | WRT_REG_WORD(ISP_REQ_Q_IN(ha, reg), 0); | 3947 | WRT_REG_WORD(ISP_REQ_Q_IN(ha, reg), 0); |
3808 | WRT_REG_WORD(ISP_REQ_Q_OUT(ha, reg), 0); | 3948 | WRT_REG_WORD(ISP_REQ_Q_OUT(ha, reg), 0); |
@@ -3829,21 +3969,19 @@ qla24xx_config_rings(struct scsi_qla_host *vha) | |||
3829 | icb->response_q_inpointer = cpu_to_le16(0); | 3969 | icb->response_q_inpointer = cpu_to_le16(0); |
3830 | icb->request_q_length = cpu_to_le16(req->length); | 3970 | icb->request_q_length = cpu_to_le16(req->length); |
3831 | icb->response_q_length = cpu_to_le16(rsp->length); | 3971 | icb->response_q_length = cpu_to_le16(rsp->length); |
3832 | icb->request_q_address[0] = cpu_to_le32(LSD(req->dma)); | 3972 | put_unaligned_le64(req->dma, &icb->request_q_address); |
3833 | icb->request_q_address[1] = cpu_to_le32(MSD(req->dma)); | 3973 | put_unaligned_le64(rsp->dma, &icb->response_q_address); |
3834 | icb->response_q_address[0] = cpu_to_le32(LSD(rsp->dma)); | ||
3835 | icb->response_q_address[1] = cpu_to_le32(MSD(rsp->dma)); | ||
3836 | 3974 | ||
3837 | /* Setup ATIO queue dma pointers for target mode */ | 3975 | /* Setup ATIO queue dma pointers for target mode */ |
3838 | icb->atio_q_inpointer = cpu_to_le16(0); | 3976 | icb->atio_q_inpointer = cpu_to_le16(0); |
3839 | icb->atio_q_length = cpu_to_le16(ha->tgt.atio_q_length); | 3977 | icb->atio_q_length = cpu_to_le16(ha->tgt.atio_q_length); |
3840 | icb->atio_q_address[0] = cpu_to_le32(LSD(ha->tgt.atio_dma)); | 3978 | put_unaligned_le64(ha->tgt.atio_dma, &icb->atio_q_address); |
3841 | icb->atio_q_address[1] = cpu_to_le32(MSD(ha->tgt.atio_dma)); | ||
3842 | 3979 | ||
3843 | if (IS_SHADOW_REG_CAPABLE(ha)) | 3980 | if (IS_SHADOW_REG_CAPABLE(ha)) |
3844 | icb->firmware_options_2 |= cpu_to_le32(BIT_30|BIT_29); | 3981 | icb->firmware_options_2 |= cpu_to_le32(BIT_30|BIT_29); |
3845 | 3982 | ||
3846 | if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 3983 | if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
3984 | IS_QLA28XX(ha)) { | ||
3847 | icb->qos = cpu_to_le16(QLA_DEFAULT_QUE_QOS); | 3985 | icb->qos = cpu_to_le16(QLA_DEFAULT_QUE_QOS); |
3848 | icb->rid = cpu_to_le16(rid); | 3986 | icb->rid = cpu_to_le16(rid); |
3849 | if (ha->flags.msix_enabled) { | 3987 | if (ha->flags.msix_enabled) { |
@@ -4266,11 +4404,14 @@ qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len, | |||
4266 | { | 4404 | { |
4267 | char *st, *en; | 4405 | char *st, *en; |
4268 | uint16_t index; | 4406 | uint16_t index; |
4407 | uint64_t zero[2] = { 0 }; | ||
4269 | struct qla_hw_data *ha = vha->hw; | 4408 | struct qla_hw_data *ha = vha->hw; |
4270 | int use_tbl = !IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && | 4409 | int use_tbl = !IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && |
4271 | !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha); | 4410 | !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha); |
4272 | 4411 | ||
4273 | if (memcmp(model, BINZERO, len) != 0) { | 4412 | if (len > sizeof(zero)) |
4413 | len = sizeof(zero); | ||
4414 | if (memcmp(model, &zero, len) != 0) { | ||
4274 | strncpy(ha->model_number, model, len); | 4415 | strncpy(ha->model_number, model, len); |
4275 | st = en = ha->model_number; | 4416 | st = en = ha->model_number; |
4276 | en += len - 1; | 4417 | en += len - 1; |
@@ -4357,7 +4498,7 @@ qla2x00_nvram_config(scsi_qla_host_t *vha) | |||
4357 | rval = QLA_SUCCESS; | 4498 | rval = QLA_SUCCESS; |
4358 | 4499 | ||
4359 | /* Determine NVRAM starting address. */ | 4500 | /* Determine NVRAM starting address. */ |
4360 | ha->nvram_size = sizeof(nvram_t); | 4501 | ha->nvram_size = sizeof(*nv); |
4361 | ha->nvram_base = 0; | 4502 | ha->nvram_base = 0; |
4362 | if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha)) | 4503 | if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha)) |
4363 | if ((RD_REG_WORD(®->ctrl_status) >> 14) == 1) | 4504 | if ((RD_REG_WORD(®->ctrl_status) >> 14) == 1) |
@@ -4371,16 +4512,15 @@ qla2x00_nvram_config(scsi_qla_host_t *vha) | |||
4371 | ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x010f, | 4512 | ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x010f, |
4372 | "Contents of NVRAM.\n"); | 4513 | "Contents of NVRAM.\n"); |
4373 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0110, | 4514 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0110, |
4374 | (uint8_t *)nv, ha->nvram_size); | 4515 | nv, ha->nvram_size); |
4375 | 4516 | ||
4376 | /* Bad NVRAM data, set defaults parameters. */ | 4517 | /* Bad NVRAM data, set defaults parameters. */ |
4377 | if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || | 4518 | if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) || |
4378 | nv->id[2] != 'P' || nv->id[3] != ' ' || nv->nvram_version < 1) { | 4519 | nv->nvram_version < 1) { |
4379 | /* Reset NVRAM data. */ | 4520 | /* Reset NVRAM data. */ |
4380 | ql_log(ql_log_warn, vha, 0x0064, | 4521 | ql_log(ql_log_warn, vha, 0x0064, |
4381 | "Inconsistent NVRAM " | 4522 | "Inconsistent NVRAM detected: checksum=%#x id=%.4s version=%#x.\n", |
4382 | "detected: checksum=0x%x id=%c version=0x%x.\n", | 4523 | chksum, nv->id, nv->nvram_version); |
4383 | chksum, nv->id[0], nv->nvram_version); | ||
4384 | ql_log(ql_log_warn, vha, 0x0065, | 4524 | ql_log(ql_log_warn, vha, 0x0065, |
4385 | "Falling back to " | 4525 | "Falling back to " |
4386 | "functioning (yet invalid -- WWPN) defaults.\n"); | 4526 | "functioning (yet invalid -- WWPN) defaults.\n"); |
@@ -4629,7 +4769,7 @@ qla2x00_nvram_config(scsi_qla_host_t *vha) | |||
4629 | ha->zio_mode = icb->add_firmware_options[0] & | 4769 | ha->zio_mode = icb->add_firmware_options[0] & |
4630 | (BIT_3 | BIT_2 | BIT_1 | BIT_0); | 4770 | (BIT_3 | BIT_2 | BIT_1 | BIT_0); |
4631 | ha->zio_timer = icb->interrupt_delay_timer ? | 4771 | ha->zio_timer = icb->interrupt_delay_timer ? |
4632 | icb->interrupt_delay_timer: 2; | 4772 | icb->interrupt_delay_timer : 2; |
4633 | } | 4773 | } |
4634 | icb->add_firmware_options[0] &= | 4774 | icb->add_firmware_options[0] &= |
4635 | ~(BIT_3 | BIT_2 | BIT_1 | BIT_0); | 4775 | ~(BIT_3 | BIT_2 | BIT_1 | BIT_0); |
@@ -4662,7 +4802,7 @@ qla2x00_rport_del(void *data) | |||
4662 | unsigned long flags; | 4802 | unsigned long flags; |
4663 | 4803 | ||
4664 | spin_lock_irqsave(fcport->vha->host->host_lock, flags); | 4804 | spin_lock_irqsave(fcport->vha->host->host_lock, flags); |
4665 | rport = fcport->drport ? fcport->drport: fcport->rport; | 4805 | rport = fcport->drport ? fcport->drport : fcport->rport; |
4666 | fcport->drport = NULL; | 4806 | fcport->drport = NULL; |
4667 | spin_unlock_irqrestore(fcport->vha->host->host_lock, flags); | 4807 | spin_unlock_irqrestore(fcport->vha->host->host_lock, flags); |
4668 | if (rport) { | 4808 | if (rport) { |
@@ -4675,6 +4815,23 @@ qla2x00_rport_del(void *data) | |||
4675 | } | 4815 | } |
4676 | } | 4816 | } |
4677 | 4817 | ||
4818 | void qla2x00_set_fcport_state(fc_port_t *fcport, int state) | ||
4819 | { | ||
4820 | int old_state; | ||
4821 | |||
4822 | old_state = atomic_read(&fcport->state); | ||
4823 | atomic_set(&fcport->state, state); | ||
4824 | |||
4825 | /* Don't print state transitions during initial allocation of fcport */ | ||
4826 | if (old_state && old_state != state) { | ||
4827 | ql_dbg(ql_dbg_disc, fcport->vha, 0x207d, | ||
4828 | "FCPort %8phC state transitioned from %s to %s - portid=%02x%02x%02x.\n", | ||
4829 | fcport->port_name, port_state_str[old_state], | ||
4830 | port_state_str[state], fcport->d_id.b.domain, | ||
4831 | fcport->d_id.b.area, fcport->d_id.b.al_pa); | ||
4832 | } | ||
4833 | } | ||
4834 | |||
4678 | /** | 4835 | /** |
4679 | * qla2x00_alloc_fcport() - Allocate a generic fcport. | 4836 | * qla2x00_alloc_fcport() - Allocate a generic fcport. |
4680 | * @vha: HA context | 4837 | * @vha: HA context |
@@ -4741,6 +4898,8 @@ qla2x00_free_fcport(fc_port_t *fcport) | |||
4741 | 4898 | ||
4742 | fcport->ct_desc.ct_sns = NULL; | 4899 | fcport->ct_desc.ct_sns = NULL; |
4743 | } | 4900 | } |
4901 | list_del(&fcport->list); | ||
4902 | qla2x00_clear_loop_id(fcport); | ||
4744 | kfree(fcport); | 4903 | kfree(fcport); |
4745 | } | 4904 | } |
4746 | 4905 | ||
@@ -4762,6 +4921,7 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) | |||
4762 | int rval; | 4921 | int rval; |
4763 | unsigned long flags, save_flags; | 4922 | unsigned long flags, save_flags; |
4764 | struct qla_hw_data *ha = vha->hw; | 4923 | struct qla_hw_data *ha = vha->hw; |
4924 | |||
4765 | rval = QLA_SUCCESS; | 4925 | rval = QLA_SUCCESS; |
4766 | 4926 | ||
4767 | /* Get Initiator ID */ | 4927 | /* Get Initiator ID */ |
@@ -4943,8 +5103,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) | |||
4943 | ql_dbg(ql_dbg_disc, vha, 0x2011, | 5103 | ql_dbg(ql_dbg_disc, vha, 0x2011, |
4944 | "Entries in ID list (%d).\n", entries); | 5104 | "Entries in ID list (%d).\n", entries); |
4945 | ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2075, | 5105 | ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2075, |
4946 | (uint8_t *)ha->gid_list, | 5106 | ha->gid_list, entries * sizeof(*ha->gid_list)); |
4947 | entries * sizeof(struct gid_list_info)); | ||
4948 | 5107 | ||
4949 | if (entries == 0) { | 5108 | if (entries == 0) { |
4950 | spin_lock_irqsave(&vha->work_lock, flags); | 5109 | spin_lock_irqsave(&vha->work_lock, flags); |
@@ -5194,16 +5353,23 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) | |||
5194 | 5353 | ||
5195 | rport->supported_classes = fcport->supported_classes; | 5354 | rport->supported_classes = fcport->supported_classes; |
5196 | 5355 | ||
5197 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; | 5356 | rport_ids.roles = FC_PORT_ROLE_UNKNOWN; |
5198 | if (fcport->port_type == FCT_INITIATOR) | 5357 | if (fcport->port_type == FCT_INITIATOR) |
5199 | rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR; | 5358 | rport_ids.roles |= FC_PORT_ROLE_FCP_INITIATOR; |
5200 | if (fcport->port_type == FCT_TARGET) | 5359 | if (fcport->port_type == FCT_TARGET) |
5201 | rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; | 5360 | rport_ids.roles |= FC_PORT_ROLE_FCP_TARGET; |
5361 | if (fcport->port_type & FCT_NVME_INITIATOR) | ||
5362 | rport_ids.roles |= FC_PORT_ROLE_NVME_INITIATOR; | ||
5363 | if (fcport->port_type & FCT_NVME_TARGET) | ||
5364 | rport_ids.roles |= FC_PORT_ROLE_NVME_TARGET; | ||
5365 | if (fcport->port_type & FCT_NVME_DISCOVERY) | ||
5366 | rport_ids.roles |= FC_PORT_ROLE_NVME_DISCOVERY; | ||
5202 | 5367 | ||
5203 | ql_dbg(ql_dbg_disc, vha, 0x20ee, | 5368 | ql_dbg(ql_dbg_disc, vha, 0x20ee, |
5204 | "%s %8phN. rport %p is %s mode\n", | 5369 | "%s %8phN. rport %p is %s mode\n", |
5205 | __func__, fcport->port_name, rport, | 5370 | __func__, fcport->port_name, rport, |
5206 | (fcport->port_type == FCT_TARGET) ? "tgt" : "ini"); | 5371 | (fcport->port_type == FCT_TARGET) ? "tgt" : |
5372 | ((fcport->port_type & FCT_NVME) ? "nvme" :"ini")); | ||
5207 | 5373 | ||
5208 | fc_remote_port_rolechg(rport, rport_ids.roles); | 5374 | fc_remote_port_rolechg(rport, rport_ids.roles); |
5209 | } | 5375 | } |
@@ -5778,55 +5944,6 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) | |||
5778 | return (rval); | 5944 | return (rval); |
5779 | } | 5945 | } |
5780 | 5946 | ||
5781 | /* | ||
5782 | * qla2x00_find_new_loop_id | ||
5783 | * Scan through our port list and find a new usable loop ID. | ||
5784 | * | ||
5785 | * Input: | ||
5786 | * ha: adapter state pointer. | ||
5787 | * dev: port structure pointer. | ||
5788 | * | ||
5789 | * Returns: | ||
5790 | * qla2x00 local function return status code. | ||
5791 | * | ||
5792 | * Context: | ||
5793 | * Kernel context. | ||
5794 | */ | ||
5795 | int | ||
5796 | qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev) | ||
5797 | { | ||
5798 | int rval; | ||
5799 | struct qla_hw_data *ha = vha->hw; | ||
5800 | unsigned long flags = 0; | ||
5801 | |||
5802 | rval = QLA_SUCCESS; | ||
5803 | |||
5804 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
5805 | |||
5806 | dev->loop_id = find_first_zero_bit(ha->loop_id_map, | ||
5807 | LOOPID_MAP_SIZE); | ||
5808 | if (dev->loop_id >= LOOPID_MAP_SIZE || | ||
5809 | qla2x00_is_reserved_id(vha, dev->loop_id)) { | ||
5810 | dev->loop_id = FC_NO_LOOP_ID; | ||
5811 | rval = QLA_FUNCTION_FAILED; | ||
5812 | } else | ||
5813 | set_bit(dev->loop_id, ha->loop_id_map); | ||
5814 | |||
5815 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
5816 | |||
5817 | if (rval == QLA_SUCCESS) | ||
5818 | ql_dbg(ql_dbg_disc, dev->vha, 0x2086, | ||
5819 | "Assigning new loopid=%x, portid=%x.\n", | ||
5820 | dev->loop_id, dev->d_id.b24); | ||
5821 | else | ||
5822 | ql_log(ql_log_warn, dev->vha, 0x2087, | ||
5823 | "No loop_id's available, portid=%x.\n", | ||
5824 | dev->d_id.b24); | ||
5825 | |||
5826 | return (rval); | ||
5827 | } | ||
5828 | |||
5829 | |||
5830 | /* FW does not set aside Loop id for MGMT Server/FFFFFAh */ | 5947 | /* FW does not set aside Loop id for MGMT Server/FFFFFAh */ |
5831 | int | 5948 | int |
5832 | qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *vha) | 5949 | qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *vha) |
@@ -6318,6 +6435,7 @@ qla83xx_initiating_reset(scsi_qla_host_t *vha) | |||
6318 | qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP); | 6435 | qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP); |
6319 | } else { | 6436 | } else { |
6320 | const char *state = qla83xx_dev_state_to_string(dev_state); | 6437 | const char *state = qla83xx_dev_state_to_string(dev_state); |
6438 | |||
6321 | ql_log(ql_log_info, vha, 0xb057, "HW State: %s.\n", state); | 6439 | ql_log(ql_log_info, vha, 0xb057, "HW State: %s.\n", state); |
6322 | 6440 | ||
6323 | /* SV: XXX: Is timeout required here? */ | 6441 | /* SV: XXX: Is timeout required here? */ |
@@ -6639,6 +6757,14 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) | |||
6639 | if (vha->flags.online) { | 6757 | if (vha->flags.online) { |
6640 | qla2x00_abort_isp_cleanup(vha); | 6758 | qla2x00_abort_isp_cleanup(vha); |
6641 | 6759 | ||
6760 | if (test_and_clear_bit(ISP_ABORT_TO_ROM, &vha->dpc_flags)) { | ||
6761 | ha->flags.chip_reset_done = 1; | ||
6762 | vha->flags.online = 1; | ||
6763 | status = 0; | ||
6764 | clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); | ||
6765 | return status; | ||
6766 | } | ||
6767 | |||
6642 | if (IS_QLA8031(ha)) { | 6768 | if (IS_QLA8031(ha)) { |
6643 | ql_dbg(ql_dbg_p3p, vha, 0xb05c, | 6769 | ql_dbg(ql_dbg_p3p, vha, 0xb05c, |
6644 | "Clearing fcoe driver presence.\n"); | 6770 | "Clearing fcoe driver presence.\n"); |
@@ -6879,7 +7005,7 @@ qla25xx_init_queues(struct qla_hw_data *ha) | |||
6879 | * Input: | 7005 | * Input: |
6880 | * ha = adapter block pointer. | 7006 | * ha = adapter block pointer. |
6881 | */ | 7007 | */ |
6882 | void | 7008 | int |
6883 | qla2x00_reset_adapter(scsi_qla_host_t *vha) | 7009 | qla2x00_reset_adapter(scsi_qla_host_t *vha) |
6884 | { | 7010 | { |
6885 | unsigned long flags = 0; | 7011 | unsigned long flags = 0; |
@@ -6895,17 +7021,20 @@ qla2x00_reset_adapter(scsi_qla_host_t *vha) | |||
6895 | WRT_REG_WORD(®->hccr, HCCR_RELEASE_RISC); | 7021 | WRT_REG_WORD(®->hccr, HCCR_RELEASE_RISC); |
6896 | RD_REG_WORD(®->hccr); /* PCI Posting. */ | 7022 | RD_REG_WORD(®->hccr); /* PCI Posting. */ |
6897 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 7023 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
7024 | |||
7025 | return QLA_SUCCESS; | ||
6898 | } | 7026 | } |
6899 | 7027 | ||
6900 | void | 7028 | int |
6901 | qla24xx_reset_adapter(scsi_qla_host_t *vha) | 7029 | qla24xx_reset_adapter(scsi_qla_host_t *vha) |
6902 | { | 7030 | { |
6903 | unsigned long flags = 0; | 7031 | unsigned long flags = 0; |
6904 | struct qla_hw_data *ha = vha->hw; | 7032 | struct qla_hw_data *ha = vha->hw; |
6905 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 7033 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
7034 | int rval = QLA_SUCCESS; | ||
6906 | 7035 | ||
6907 | if (IS_P3P_TYPE(ha)) | 7036 | if (IS_P3P_TYPE(ha)) |
6908 | return; | 7037 | return rval; |
6909 | 7038 | ||
6910 | vha->flags.online = 0; | 7039 | vha->flags.online = 0; |
6911 | ha->isp_ops->disable_intrs(ha); | 7040 | ha->isp_ops->disable_intrs(ha); |
@@ -6919,6 +7048,8 @@ qla24xx_reset_adapter(scsi_qla_host_t *vha) | |||
6919 | 7048 | ||
6920 | if (IS_NOPOLLING_TYPE(ha)) | 7049 | if (IS_NOPOLLING_TYPE(ha)) |
6921 | ha->isp_ops->enable_intrs(ha); | 7050 | ha->isp_ops->enable_intrs(ha); |
7051 | |||
7052 | return rval; | ||
6922 | } | 7053 | } |
6923 | 7054 | ||
6924 | /* On sparc systems, obtain port and node WWN from firmware | 7055 | /* On sparc systems, obtain port and node WWN from firmware |
@@ -6969,34 +7100,33 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) | |||
6969 | ha->vpd_base = FA_NVRAM_VPD1_ADDR; | 7100 | ha->vpd_base = FA_NVRAM_VPD1_ADDR; |
6970 | } | 7101 | } |
6971 | 7102 | ||
6972 | ha->nvram_size = sizeof(struct nvram_24xx); | 7103 | ha->nvram_size = sizeof(*nv); |
6973 | ha->vpd_size = FA_NVRAM_VPD_SIZE; | 7104 | ha->vpd_size = FA_NVRAM_VPD_SIZE; |
6974 | 7105 | ||
6975 | /* Get VPD data into cache */ | 7106 | /* Get VPD data into cache */ |
6976 | ha->vpd = ha->nvram + VPD_OFFSET; | 7107 | ha->vpd = ha->nvram + VPD_OFFSET; |
6977 | ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, | 7108 | ha->isp_ops->read_nvram(vha, ha->vpd, |
6978 | ha->nvram_base - FA_NVRAM_FUNC0_ADDR, FA_NVRAM_VPD_SIZE * 4); | 7109 | ha->nvram_base - FA_NVRAM_FUNC0_ADDR, FA_NVRAM_VPD_SIZE * 4); |
6979 | 7110 | ||
6980 | /* Get NVRAM data into cache and calculate checksum. */ | 7111 | /* Get NVRAM data into cache and calculate checksum. */ |
6981 | dptr = (uint32_t *)nv; | 7112 | dptr = (uint32_t *)nv; |
6982 | ha->isp_ops->read_nvram(vha, (uint8_t *)dptr, ha->nvram_base, | 7113 | ha->isp_ops->read_nvram(vha, dptr, ha->nvram_base, ha->nvram_size); |
6983 | ha->nvram_size); | ||
6984 | for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++) | 7114 | for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++) |
6985 | chksum += le32_to_cpu(*dptr); | 7115 | chksum += le32_to_cpu(*dptr); |
6986 | 7116 | ||
6987 | ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x006a, | 7117 | ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x006a, |
6988 | "Contents of NVRAM\n"); | 7118 | "Contents of NVRAM\n"); |
6989 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x010d, | 7119 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x010d, |
6990 | (uint8_t *)nv, ha->nvram_size); | 7120 | nv, ha->nvram_size); |
6991 | 7121 | ||
6992 | /* Bad NVRAM data, set defaults parameters. */ | 7122 | /* Bad NVRAM data, set defaults parameters. */ |
6993 | if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || nv->id[2] != 'P' | 7123 | if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) || |
6994 | || nv->id[3] != ' ' || | 7124 | le16_to_cpu(nv->nvram_version) < ICB_VERSION) { |
6995 | nv->nvram_version < cpu_to_le16(ICB_VERSION)) { | ||
6996 | /* Reset NVRAM data. */ | 7125 | /* Reset NVRAM data. */ |
6997 | ql_log(ql_log_warn, vha, 0x006b, | 7126 | ql_log(ql_log_warn, vha, 0x006b, |
6998 | "Inconsistent NVRAM detected: checksum=0x%x id=%c " | 7127 | "Inconsistent NVRAM checksum=%#x id=%.4s version=%#x.\n", |
6999 | "version=0x%x.\n", chksum, nv->id[0], nv->nvram_version); | 7128 | chksum, nv->id, nv->nvram_version); |
7129 | ql_dump_buffer(ql_dbg_init, vha, 0x006b, nv, sizeof(*nv)); | ||
7000 | ql_log(ql_log_warn, vha, 0x006c, | 7130 | ql_log(ql_log_warn, vha, 0x006c, |
7001 | "Falling back to functioning (yet invalid -- WWPN) " | 7131 | "Falling back to functioning (yet invalid -- WWPN) " |
7002 | "defaults.\n"); | 7132 | "defaults.\n"); |
@@ -7104,11 +7234,11 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) | |||
7104 | ha->flags.disable_risc_code_load = 0; | 7234 | ha->flags.disable_risc_code_load = 0; |
7105 | ha->flags.enable_lip_reset = 0; | 7235 | ha->flags.enable_lip_reset = 0; |
7106 | ha->flags.enable_lip_full_login = | 7236 | ha->flags.enable_lip_full_login = |
7107 | le32_to_cpu(nv->host_p) & BIT_10 ? 1: 0; | 7237 | le32_to_cpu(nv->host_p) & BIT_10 ? 1 : 0; |
7108 | ha->flags.enable_target_reset = | 7238 | ha->flags.enable_target_reset = |
7109 | le32_to_cpu(nv->host_p) & BIT_11 ? 1: 0; | 7239 | le32_to_cpu(nv->host_p) & BIT_11 ? 1 : 0; |
7110 | ha->flags.enable_led_scheme = 0; | 7240 | ha->flags.enable_led_scheme = 0; |
7111 | ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1: 0; | 7241 | ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1 : 0; |
7112 | 7242 | ||
7113 | ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) & | 7243 | ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) & |
7114 | (BIT_6 | BIT_5 | BIT_4)) >> 4; | 7244 | (BIT_6 | BIT_5 | BIT_4)) >> 4; |
@@ -7182,7 +7312,7 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) | |||
7182 | ha->zio_mode = le32_to_cpu(icb->firmware_options_2) & | 7312 | ha->zio_mode = le32_to_cpu(icb->firmware_options_2) & |
7183 | (BIT_3 | BIT_2 | BIT_1 | BIT_0); | 7313 | (BIT_3 | BIT_2 | BIT_1 | BIT_0); |
7184 | ha->zio_timer = le16_to_cpu(icb->interrupt_delay_timer) ? | 7314 | ha->zio_timer = le16_to_cpu(icb->interrupt_delay_timer) ? |
7185 | le16_to_cpu(icb->interrupt_delay_timer): 2; | 7315 | le16_to_cpu(icb->interrupt_delay_timer) : 2; |
7186 | } | 7316 | } |
7187 | icb->firmware_options_2 &= cpu_to_le32( | 7317 | icb->firmware_options_2 &= cpu_to_le32( |
7188 | ~(BIT_3 | BIT_2 | BIT_1 | BIT_0)); | 7318 | ~(BIT_3 | BIT_2 | BIT_1 | BIT_0)); |
@@ -7205,128 +7335,311 @@ qla24xx_nvram_config(scsi_qla_host_t *vha) | |||
7205 | return (rval); | 7335 | return (rval); |
7206 | } | 7336 | } |
7207 | 7337 | ||
7208 | uint8_t qla27xx_find_valid_image(struct scsi_qla_host *vha) | 7338 | static void |
7339 | qla27xx_print_image(struct scsi_qla_host *vha, char *name, | ||
7340 | struct qla27xx_image_status *image_status) | ||
7341 | { | ||
7342 | ql_dbg(ql_dbg_init, vha, 0x018b, | ||
7343 | "%s %s: mask=%#02x gen=%#04x ver=%u.%u map=%#01x sum=%#08x sig=%#08x\n", | ||
7344 | name, "status", | ||
7345 | image_status->image_status_mask, | ||
7346 | le16_to_cpu(image_status->generation), | ||
7347 | image_status->ver_major, | ||
7348 | image_status->ver_minor, | ||
7349 | image_status->bitmap, | ||
7350 | le32_to_cpu(image_status->checksum), | ||
7351 | le32_to_cpu(image_status->signature)); | ||
7352 | } | ||
7353 | |||
7354 | static bool | ||
7355 | qla28xx_check_aux_image_status_signature( | ||
7356 | struct qla27xx_image_status *image_status) | ||
7357 | { | ||
7358 | ulong signature = le32_to_cpu(image_status->signature); | ||
7359 | |||
7360 | return signature != QLA28XX_AUX_IMG_STATUS_SIGN; | ||
7361 | } | ||
7362 | |||
7363 | static bool | ||
7364 | qla27xx_check_image_status_signature(struct qla27xx_image_status *image_status) | ||
7365 | { | ||
7366 | ulong signature = le32_to_cpu(image_status->signature); | ||
7367 | |||
7368 | return | ||
7369 | signature != QLA27XX_IMG_STATUS_SIGN && | ||
7370 | signature != QLA28XX_IMG_STATUS_SIGN; | ||
7371 | } | ||
7372 | |||
7373 | static ulong | ||
7374 | qla27xx_image_status_checksum(struct qla27xx_image_status *image_status) | ||
7375 | { | ||
7376 | uint32_t *p = (void *)image_status; | ||
7377 | uint n = sizeof(*image_status) / sizeof(*p); | ||
7378 | uint32_t sum = 0; | ||
7379 | |||
7380 | for ( ; n--; p++) | ||
7381 | sum += le32_to_cpup(p); | ||
7382 | |||
7383 | return sum; | ||
7384 | } | ||
7385 | |||
7386 | static inline uint | ||
7387 | qla28xx_component_bitmask(struct qla27xx_image_status *aux, uint bitmask) | ||
7388 | { | ||
7389 | return aux->bitmap & bitmask ? | ||
7390 | QLA27XX_SECONDARY_IMAGE : QLA27XX_PRIMARY_IMAGE; | ||
7391 | } | ||
7392 | |||
7393 | static void | ||
7394 | qla28xx_component_status( | ||
7395 | struct active_regions *active_regions, struct qla27xx_image_status *aux) | ||
7396 | { | ||
7397 | active_regions->aux.board_config = | ||
7398 | qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_BOARD_CONFIG); | ||
7399 | |||
7400 | active_regions->aux.vpd_nvram = | ||
7401 | qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_VPD_NVRAM); | ||
7402 | |||
7403 | active_regions->aux.npiv_config_0_1 = | ||
7404 | qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_NPIV_CONFIG_0_1); | ||
7405 | |||
7406 | active_regions->aux.npiv_config_2_3 = | ||
7407 | qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_NPIV_CONFIG_2_3); | ||
7408 | } | ||
7409 | |||
7410 | static int | ||
7411 | qla27xx_compare_image_generation( | ||
7412 | struct qla27xx_image_status *pri_image_status, | ||
7413 | struct qla27xx_image_status *sec_image_status) | ||
7414 | { | ||
7415 | /* calculate generation delta as uint16 (this accounts for wrap) */ | ||
7416 | int16_t delta = | ||
7417 | le16_to_cpu(pri_image_status->generation) - | ||
7418 | le16_to_cpu(sec_image_status->generation); | ||
7419 | |||
7420 | ql_dbg(ql_dbg_init, NULL, 0x0180, "generation delta = %d\n", delta); | ||
7421 | |||
7422 | return delta; | ||
7423 | } | ||
7424 | |||
7425 | void | ||
7426 | qla28xx_get_aux_images( | ||
7427 | struct scsi_qla_host *vha, struct active_regions *active_regions) | ||
7209 | { | 7428 | { |
7210 | struct qla27xx_image_status pri_image_status, sec_image_status; | ||
7211 | uint8_t valid_pri_image, valid_sec_image; | ||
7212 | uint32_t *wptr; | ||
7213 | uint32_t cnt, chksum, size; | ||
7214 | struct qla_hw_data *ha = vha->hw; | 7429 | struct qla_hw_data *ha = vha->hw; |
7430 | struct qla27xx_image_status pri_aux_image_status, sec_aux_image_status; | ||
7431 | bool valid_pri_image = false, valid_sec_image = false; | ||
7432 | bool active_pri_image = false, active_sec_image = false; | ||
7433 | |||
7434 | if (!ha->flt_region_aux_img_status_pri) { | ||
7435 | ql_dbg(ql_dbg_init, vha, 0x018a, "Primary aux image not addressed\n"); | ||
7436 | goto check_sec_image; | ||
7437 | } | ||
7215 | 7438 | ||
7216 | valid_pri_image = valid_sec_image = 1; | 7439 | qla24xx_read_flash_data(vha, (void *)&pri_aux_image_status, |
7217 | ha->active_image = 0; | 7440 | ha->flt_region_aux_img_status_pri, |
7218 | size = sizeof(struct qla27xx_image_status) / sizeof(uint32_t); | 7441 | sizeof(pri_aux_image_status) >> 2); |
7442 | qla27xx_print_image(vha, "Primary aux image", &pri_aux_image_status); | ||
7219 | 7443 | ||
7220 | if (!ha->flt_region_img_status_pri) { | 7444 | if (qla28xx_check_aux_image_status_signature(&pri_aux_image_status)) { |
7221 | valid_pri_image = 0; | 7445 | ql_dbg(ql_dbg_init, vha, 0x018b, |
7446 | "Primary aux image signature (%#x) not valid\n", | ||
7447 | le32_to_cpu(pri_aux_image_status.signature)); | ||
7222 | goto check_sec_image; | 7448 | goto check_sec_image; |
7223 | } | 7449 | } |
7224 | 7450 | ||
7225 | qla24xx_read_flash_data(vha, (uint32_t *)(&pri_image_status), | 7451 | if (qla27xx_image_status_checksum(&pri_aux_image_status)) { |
7226 | ha->flt_region_img_status_pri, size); | 7452 | ql_dbg(ql_dbg_init, vha, 0x018c, |
7453 | "Primary aux image checksum failed\n"); | ||
7454 | goto check_sec_image; | ||
7455 | } | ||
7456 | |||
7457 | valid_pri_image = true; | ||
7458 | |||
7459 | if (pri_aux_image_status.image_status_mask & 1) { | ||
7460 | ql_dbg(ql_dbg_init, vha, 0x018d, | ||
7461 | "Primary aux image is active\n"); | ||
7462 | active_pri_image = true; | ||
7463 | } | ||
7464 | |||
7465 | check_sec_image: | ||
7466 | if (!ha->flt_region_aux_img_status_sec) { | ||
7467 | ql_dbg(ql_dbg_init, vha, 0x018a, | ||
7468 | "Secondary aux image not addressed\n"); | ||
7469 | goto check_valid_image; | ||
7470 | } | ||
7471 | |||
7472 | qla24xx_read_flash_data(vha, (void *)&sec_aux_image_status, | ||
7473 | ha->flt_region_aux_img_status_sec, | ||
7474 | sizeof(sec_aux_image_status) >> 2); | ||
7475 | qla27xx_print_image(vha, "Secondary aux image", &sec_aux_image_status); | ||
7227 | 7476 | ||
7228 | if (pri_image_status.signature != QLA27XX_IMG_STATUS_SIGN) { | 7477 | if (qla28xx_check_aux_image_status_signature(&sec_aux_image_status)) { |
7229 | ql_dbg(ql_dbg_init, vha, 0x018b, | 7478 | ql_dbg(ql_dbg_init, vha, 0x018b, |
7230 | "Primary image signature (0x%x) not valid\n", | 7479 | "Secondary aux image signature (%#x) not valid\n", |
7231 | pri_image_status.signature); | 7480 | le32_to_cpu(sec_aux_image_status.signature)); |
7232 | valid_pri_image = 0; | 7481 | goto check_valid_image; |
7482 | } | ||
7483 | |||
7484 | if (qla27xx_image_status_checksum(&sec_aux_image_status)) { | ||
7485 | ql_dbg(ql_dbg_init, vha, 0x018c, | ||
7486 | "Secondary aux image checksum failed\n"); | ||
7487 | goto check_valid_image; | ||
7488 | } | ||
7489 | |||
7490 | valid_sec_image = true; | ||
7491 | |||
7492 | if (sec_aux_image_status.image_status_mask & 1) { | ||
7493 | ql_dbg(ql_dbg_init, vha, 0x018d, | ||
7494 | "Secondary aux image is active\n"); | ||
7495 | active_sec_image = true; | ||
7496 | } | ||
7497 | |||
7498 | check_valid_image: | ||
7499 | if (valid_pri_image && active_pri_image && | ||
7500 | valid_sec_image && active_sec_image) { | ||
7501 | if (qla27xx_compare_image_generation(&pri_aux_image_status, | ||
7502 | &sec_aux_image_status) >= 0) { | ||
7503 | qla28xx_component_status(active_regions, | ||
7504 | &pri_aux_image_status); | ||
7505 | } else { | ||
7506 | qla28xx_component_status(active_regions, | ||
7507 | &sec_aux_image_status); | ||
7508 | } | ||
7509 | } else if (valid_pri_image && active_pri_image) { | ||
7510 | qla28xx_component_status(active_regions, &pri_aux_image_status); | ||
7511 | } else if (valid_sec_image && active_sec_image) { | ||
7512 | qla28xx_component_status(active_regions, &sec_aux_image_status); | ||
7513 | } | ||
7514 | |||
7515 | ql_dbg(ql_dbg_init, vha, 0x018f, | ||
7516 | "aux images active: BCFG=%u VPD/NVR=%u NPIV0/1=%u NPIV2/3=%u\n", | ||
7517 | active_regions->aux.board_config, | ||
7518 | active_regions->aux.vpd_nvram, | ||
7519 | active_regions->aux.npiv_config_0_1, | ||
7520 | active_regions->aux.npiv_config_2_3); | ||
7521 | } | ||
7522 | |||
7523 | void | ||
7524 | qla27xx_get_active_image(struct scsi_qla_host *vha, | ||
7525 | struct active_regions *active_regions) | ||
7526 | { | ||
7527 | struct qla_hw_data *ha = vha->hw; | ||
7528 | struct qla27xx_image_status pri_image_status, sec_image_status; | ||
7529 | bool valid_pri_image = false, valid_sec_image = false; | ||
7530 | bool active_pri_image = false, active_sec_image = false; | ||
7531 | |||
7532 | if (!ha->flt_region_img_status_pri) { | ||
7533 | ql_dbg(ql_dbg_init, vha, 0x018a, "Primary image not addressed\n"); | ||
7233 | goto check_sec_image; | 7534 | goto check_sec_image; |
7234 | } | 7535 | } |
7235 | 7536 | ||
7236 | wptr = (uint32_t *)(&pri_image_status); | 7537 | qla24xx_read_flash_data(vha, (void *)(&pri_image_status), |
7237 | cnt = size; | 7538 | ha->flt_region_img_status_pri, sizeof(pri_image_status) >> 2); |
7539 | qla27xx_print_image(vha, "Primary image", &pri_image_status); | ||
7238 | 7540 | ||
7239 | for (chksum = 0; cnt--; wptr++) | 7541 | if (qla27xx_check_image_status_signature(&pri_image_status)) { |
7240 | chksum += le32_to_cpu(*wptr); | 7542 | ql_dbg(ql_dbg_init, vha, 0x018b, |
7543 | "Primary image signature (%#x) not valid\n", | ||
7544 | le32_to_cpu(pri_image_status.signature)); | ||
7545 | goto check_sec_image; | ||
7546 | } | ||
7241 | 7547 | ||
7242 | if (chksum) { | 7548 | if (qla27xx_image_status_checksum(&pri_image_status)) { |
7243 | ql_dbg(ql_dbg_init, vha, 0x018c, | 7549 | ql_dbg(ql_dbg_init, vha, 0x018c, |
7244 | "Checksum validation failed for primary image (0x%x)\n", | 7550 | "Primary image checksum failed\n"); |
7245 | chksum); | 7551 | goto check_sec_image; |
7246 | valid_pri_image = 0; | 7552 | } |
7553 | |||
7554 | valid_pri_image = true; | ||
7555 | |||
7556 | if (pri_image_status.image_status_mask & 1) { | ||
7557 | ql_dbg(ql_dbg_init, vha, 0x018d, | ||
7558 | "Primary image is active\n"); | ||
7559 | active_pri_image = true; | ||
7247 | } | 7560 | } |
7248 | 7561 | ||
7249 | check_sec_image: | 7562 | check_sec_image: |
7250 | if (!ha->flt_region_img_status_sec) { | 7563 | if (!ha->flt_region_img_status_sec) { |
7251 | valid_sec_image = 0; | 7564 | ql_dbg(ql_dbg_init, vha, 0x018a, "Secondary image not addressed\n"); |
7252 | goto check_valid_image; | 7565 | goto check_valid_image; |
7253 | } | 7566 | } |
7254 | 7567 | ||
7255 | qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status), | 7568 | qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status), |
7256 | ha->flt_region_img_status_sec, size); | 7569 | ha->flt_region_img_status_sec, sizeof(sec_image_status) >> 2); |
7570 | qla27xx_print_image(vha, "Secondary image", &sec_image_status); | ||
7257 | 7571 | ||
7258 | if (sec_image_status.signature != QLA27XX_IMG_STATUS_SIGN) { | 7572 | if (qla27xx_check_image_status_signature(&sec_image_status)) { |
7259 | ql_dbg(ql_dbg_init, vha, 0x018d, | 7573 | ql_dbg(ql_dbg_init, vha, 0x018b, |
7260 | "Secondary image signature(0x%x) not valid\n", | 7574 | "Secondary image signature (%#x) not valid\n", |
7261 | sec_image_status.signature); | 7575 | le32_to_cpu(sec_image_status.signature)); |
7262 | valid_sec_image = 0; | ||
7263 | goto check_valid_image; | 7576 | goto check_valid_image; |
7264 | } | 7577 | } |
7265 | 7578 | ||
7266 | wptr = (uint32_t *)(&sec_image_status); | 7579 | if (qla27xx_image_status_checksum(&sec_image_status)) { |
7267 | cnt = size; | 7580 | ql_dbg(ql_dbg_init, vha, 0x018c, |
7268 | for (chksum = 0; cnt--; wptr++) | 7581 | "Secondary image checksum failed\n"); |
7269 | chksum += le32_to_cpu(*wptr); | 7582 | goto check_valid_image; |
7270 | if (chksum) { | 7583 | } |
7271 | ql_dbg(ql_dbg_init, vha, 0x018e, | 7584 | |
7272 | "Checksum validation failed for secondary image (0x%x)\n", | 7585 | valid_sec_image = true; |
7273 | chksum); | 7586 | |
7274 | valid_sec_image = 0; | 7587 | if (sec_image_status.image_status_mask & 1) { |
7588 | ql_dbg(ql_dbg_init, vha, 0x018d, | ||
7589 | "Secondary image is active\n"); | ||
7590 | active_sec_image = true; | ||
7275 | } | 7591 | } |
7276 | 7592 | ||
7277 | check_valid_image: | 7593 | check_valid_image: |
7278 | if (valid_pri_image && (pri_image_status.image_status_mask & 0x1)) | 7594 | if (valid_pri_image && active_pri_image) |
7279 | ha->active_image = QLA27XX_PRIMARY_IMAGE; | 7595 | active_regions->global = QLA27XX_PRIMARY_IMAGE; |
7280 | if (valid_sec_image && (sec_image_status.image_status_mask & 0x1)) { | 7596 | |
7281 | if (!ha->active_image || | 7597 | if (valid_sec_image && active_sec_image) { |
7282 | pri_image_status.generation_number < | 7598 | if (!active_regions->global || |
7283 | sec_image_status.generation_number) | 7599 | qla27xx_compare_image_generation( |
7284 | ha->active_image = QLA27XX_SECONDARY_IMAGE; | 7600 | &pri_image_status, &sec_image_status) < 0) { |
7601 | active_regions->global = QLA27XX_SECONDARY_IMAGE; | ||
7602 | } | ||
7285 | } | 7603 | } |
7286 | 7604 | ||
7287 | ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x018f, "%s image\n", | 7605 | ql_dbg(ql_dbg_init, vha, 0x018f, "active image %s (%u)\n", |
7288 | ha->active_image == 0 ? "default bootld and fw" : | 7606 | active_regions->global == QLA27XX_DEFAULT_IMAGE ? |
7289 | ha->active_image == 1 ? "primary" : | 7607 | "default (boot/fw)" : |
7290 | ha->active_image == 2 ? "secondary" : | 7608 | active_regions->global == QLA27XX_PRIMARY_IMAGE ? |
7291 | "Invalid"); | 7609 | "primary" : |
7610 | active_regions->global == QLA27XX_SECONDARY_IMAGE ? | ||
7611 | "secondary" : "invalid", | ||
7612 | active_regions->global); | ||
7613 | } | ||
7292 | 7614 | ||
7293 | return ha->active_image; | 7615 | bool qla24xx_risc_firmware_invalid(uint32_t *dword) |
7616 | { | ||
7617 | return | ||
7618 | !(dword[4] | dword[5] | dword[6] | dword[7]) || | ||
7619 | !(~dword[4] | ~dword[5] | ~dword[6] | ~dword[7]); | ||
7294 | } | 7620 | } |
7295 | 7621 | ||
7296 | static int | 7622 | static int |
7297 | qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, | 7623 | qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, |
7298 | uint32_t faddr) | 7624 | uint32_t faddr) |
7299 | { | 7625 | { |
7300 | int rval = QLA_SUCCESS; | 7626 | int rval; |
7301 | int segments, fragment; | 7627 | uint templates, segments, fragment; |
7302 | uint32_t *dcode, dlen; | 7628 | ulong i; |
7303 | uint32_t risc_addr; | 7629 | uint j; |
7304 | uint32_t risc_size; | 7630 | ulong dlen; |
7305 | uint32_t i; | 7631 | uint32_t *dcode; |
7632 | uint32_t risc_addr, risc_size, risc_attr = 0; | ||
7306 | struct qla_hw_data *ha = vha->hw; | 7633 | struct qla_hw_data *ha = vha->hw; |
7307 | struct req_que *req = ha->req_q_map[0]; | 7634 | struct req_que *req = ha->req_q_map[0]; |
7635 | struct fwdt *fwdt = ha->fwdt; | ||
7308 | 7636 | ||
7309 | ql_dbg(ql_dbg_init, vha, 0x008b, | 7637 | ql_dbg(ql_dbg_init, vha, 0x008b, |
7310 | "FW: Loading firmware from flash (%x).\n", faddr); | 7638 | "FW: Loading firmware from flash (%x).\n", faddr); |
7311 | 7639 | ||
7312 | rval = QLA_SUCCESS; | 7640 | dcode = (void *)req->ring; |
7313 | 7641 | qla24xx_read_flash_data(vha, dcode, faddr, 8); | |
7314 | segments = FA_RISC_CODE_SEGMENTS; | 7642 | if (qla24xx_risc_firmware_invalid(dcode)) { |
7315 | dcode = (uint32_t *)req->ring; | ||
7316 | *srisc_addr = 0; | ||
7317 | |||
7318 | if (IS_QLA27XX(ha) && | ||
7319 | qla27xx_find_valid_image(vha) == QLA27XX_SECONDARY_IMAGE) | ||
7320 | faddr = ha->flt_region_fw_sec; | ||
7321 | |||
7322 | /* Validate firmware image by checking version. */ | ||
7323 | qla24xx_read_flash_data(vha, dcode, faddr + 4, 4); | ||
7324 | for (i = 0; i < 4; i++) | ||
7325 | dcode[i] = be32_to_cpu(dcode[i]); | ||
7326 | if ((dcode[0] == 0xffffffff && dcode[1] == 0xffffffff && | ||
7327 | dcode[2] == 0xffffffff && dcode[3] == 0xffffffff) || | ||
7328 | (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 && | ||
7329 | dcode[3] == 0)) { | ||
7330 | ql_log(ql_log_fatal, vha, 0x008c, | 7643 | ql_log(ql_log_fatal, vha, 0x008c, |
7331 | "Unable to verify the integrity of flash firmware " | 7644 | "Unable to verify the integrity of flash firmware " |
7332 | "image.\n"); | 7645 | "image.\n"); |
@@ -7337,34 +7650,36 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, | |||
7337 | return QLA_FUNCTION_FAILED; | 7650 | return QLA_FUNCTION_FAILED; |
7338 | } | 7651 | } |
7339 | 7652 | ||
7340 | while (segments && rval == QLA_SUCCESS) { | 7653 | dcode = (void *)req->ring; |
7341 | /* Read segment's load information. */ | 7654 | *srisc_addr = 0; |
7342 | qla24xx_read_flash_data(vha, dcode, faddr, 4); | 7655 | segments = FA_RISC_CODE_SEGMENTS; |
7343 | 7656 | for (j = 0; j < segments; j++) { | |
7657 | ql_dbg(ql_dbg_init, vha, 0x008d, | ||
7658 | "-> Loading segment %u...\n", j); | ||
7659 | qla24xx_read_flash_data(vha, dcode, faddr, 10); | ||
7344 | risc_addr = be32_to_cpu(dcode[2]); | 7660 | risc_addr = be32_to_cpu(dcode[2]); |
7345 | *srisc_addr = *srisc_addr == 0 ? risc_addr : *srisc_addr; | ||
7346 | risc_size = be32_to_cpu(dcode[3]); | 7661 | risc_size = be32_to_cpu(dcode[3]); |
7662 | if (!*srisc_addr) { | ||
7663 | *srisc_addr = risc_addr; | ||
7664 | risc_attr = be32_to_cpu(dcode[9]); | ||
7665 | } | ||
7347 | 7666 | ||
7348 | fragment = 0; | 7667 | dlen = ha->fw_transfer_size >> 2; |
7349 | while (risc_size > 0 && rval == QLA_SUCCESS) { | 7668 | for (fragment = 0; risc_size; fragment++) { |
7350 | dlen = (uint32_t)(ha->fw_transfer_size >> 2); | ||
7351 | if (dlen > risc_size) | 7669 | if (dlen > risc_size) |
7352 | dlen = risc_size; | 7670 | dlen = risc_size; |
7353 | 7671 | ||
7354 | ql_dbg(ql_dbg_init, vha, 0x008e, | 7672 | ql_dbg(ql_dbg_init, vha, 0x008e, |
7355 | "Loading risc segment@ risc addr %x " | 7673 | "-> Loading fragment %u: %#x <- %#x (%#lx dwords)...\n", |
7356 | "number of dwords 0x%x offset 0x%x.\n", | 7674 | fragment, risc_addr, faddr, dlen); |
7357 | risc_addr, dlen, faddr); | ||
7358 | |||
7359 | qla24xx_read_flash_data(vha, dcode, faddr, dlen); | 7675 | qla24xx_read_flash_data(vha, dcode, faddr, dlen); |
7360 | for (i = 0; i < dlen; i++) | 7676 | for (i = 0; i < dlen; i++) |
7361 | dcode[i] = swab32(dcode[i]); | 7677 | dcode[i] = swab32(dcode[i]); |
7362 | 7678 | ||
7363 | rval = qla2x00_load_ram(vha, req->dma, risc_addr, | 7679 | rval = qla2x00_load_ram(vha, req->dma, risc_addr, dlen); |
7364 | dlen); | ||
7365 | if (rval) { | 7680 | if (rval) { |
7366 | ql_log(ql_log_fatal, vha, 0x008f, | 7681 | ql_log(ql_log_fatal, vha, 0x008f, |
7367 | "Failed to load segment %d of firmware.\n", | 7682 | "-> Failed load firmware fragment %u.\n", |
7368 | fragment); | 7683 | fragment); |
7369 | return QLA_FUNCTION_FAILED; | 7684 | return QLA_FUNCTION_FAILED; |
7370 | } | 7685 | } |
@@ -7372,107 +7687,82 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, | |||
7372 | faddr += dlen; | 7687 | faddr += dlen; |
7373 | risc_addr += dlen; | 7688 | risc_addr += dlen; |
7374 | risc_size -= dlen; | 7689 | risc_size -= dlen; |
7375 | fragment++; | ||
7376 | } | 7690 | } |
7377 | |||
7378 | /* Next segment. */ | ||
7379 | segments--; | ||
7380 | } | 7691 | } |
7381 | 7692 | ||
7382 | if (!IS_QLA27XX(ha)) | 7693 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
7383 | return rval; | 7694 | return QLA_SUCCESS; |
7384 | 7695 | ||
7385 | if (ha->fw_dump_template) | 7696 | templates = (risc_attr & BIT_9) ? 2 : 1; |
7386 | vfree(ha->fw_dump_template); | 7697 | ql_dbg(ql_dbg_init, vha, 0x0160, "-> templates = %u\n", templates); |
7387 | ha->fw_dump_template = NULL; | 7698 | for (j = 0; j < templates; j++, fwdt++) { |
7388 | ha->fw_dump_template_len = 0; | 7699 | if (fwdt->template) |
7389 | 7700 | vfree(fwdt->template); | |
7390 | ql_dbg(ql_dbg_init, vha, 0x0161, | 7701 | fwdt->template = NULL; |
7391 | "Loading fwdump template from %x\n", faddr); | 7702 | fwdt->length = 0; |
7392 | qla24xx_read_flash_data(vha, dcode, faddr, 7); | 7703 | |
7393 | risc_size = be32_to_cpu(dcode[2]); | 7704 | dcode = (void *)req->ring; |
7394 | ql_dbg(ql_dbg_init, vha, 0x0162, | 7705 | qla24xx_read_flash_data(vha, dcode, faddr, 7); |
7395 | "-> array size %x dwords\n", risc_size); | 7706 | risc_size = be32_to_cpu(dcode[2]); |
7396 | if (risc_size == 0 || risc_size == ~0) | 7707 | ql_dbg(ql_dbg_init, vha, 0x0161, |
7397 | goto default_template; | 7708 | "-> fwdt%u template array at %#x (%#x dwords)\n", |
7398 | 7709 | j, faddr, risc_size); | |
7399 | dlen = (risc_size - 8) * sizeof(*dcode); | 7710 | if (!risc_size || !~risc_size) { |
7400 | ql_dbg(ql_dbg_init, vha, 0x0163, | 7711 | ql_dbg(ql_dbg_init, vha, 0x0162, |
7401 | "-> template allocating %x bytes...\n", dlen); | 7712 | "-> fwdt%u failed to read array\n", j); |
7402 | ha->fw_dump_template = vmalloc(dlen); | 7713 | goto failed; |
7403 | if (!ha->fw_dump_template) { | 7714 | } |
7404 | ql_log(ql_log_warn, vha, 0x0164, | ||
7405 | "Failed fwdump template allocate %x bytes.\n", risc_size); | ||
7406 | goto default_template; | ||
7407 | } | ||
7408 | |||
7409 | faddr += 7; | ||
7410 | risc_size -= 8; | ||
7411 | dcode = ha->fw_dump_template; | ||
7412 | qla24xx_read_flash_data(vha, dcode, faddr, risc_size); | ||
7413 | for (i = 0; i < risc_size; i++) | ||
7414 | dcode[i] = le32_to_cpu(dcode[i]); | ||
7415 | |||
7416 | if (!qla27xx_fwdt_template_valid(dcode)) { | ||
7417 | ql_log(ql_log_warn, vha, 0x0165, | ||
7418 | "Failed fwdump template validate\n"); | ||
7419 | goto default_template; | ||
7420 | } | ||
7421 | |||
7422 | dlen = qla27xx_fwdt_template_size(dcode); | ||
7423 | ql_dbg(ql_dbg_init, vha, 0x0166, | ||
7424 | "-> template size %x bytes\n", dlen); | ||
7425 | if (dlen > risc_size * sizeof(*dcode)) { | ||
7426 | ql_log(ql_log_warn, vha, 0x0167, | ||
7427 | "Failed fwdump template exceeds array by %zx bytes\n", | ||
7428 | (size_t)(dlen - risc_size * sizeof(*dcode))); | ||
7429 | goto default_template; | ||
7430 | } | ||
7431 | ha->fw_dump_template_len = dlen; | ||
7432 | return rval; | ||
7433 | 7715 | ||
7434 | default_template: | 7716 | /* skip header and ignore checksum */ |
7435 | ql_log(ql_log_warn, vha, 0x0168, "Using default fwdump template\n"); | 7717 | faddr += 7; |
7436 | if (ha->fw_dump_template) | 7718 | risc_size -= 8; |
7437 | vfree(ha->fw_dump_template); | 7719 | |
7438 | ha->fw_dump_template = NULL; | 7720 | ql_dbg(ql_dbg_init, vha, 0x0163, |
7439 | ha->fw_dump_template_len = 0; | 7721 | "-> fwdt%u template allocate template %#x words...\n", |
7440 | 7722 | j, risc_size); | |
7441 | dlen = qla27xx_fwdt_template_default_size(); | 7723 | fwdt->template = vmalloc(risc_size * sizeof(*dcode)); |
7442 | ql_dbg(ql_dbg_init, vha, 0x0169, | 7724 | if (!fwdt->template) { |
7443 | "-> template allocating %x bytes...\n", dlen); | 7725 | ql_log(ql_log_warn, vha, 0x0164, |
7444 | ha->fw_dump_template = vmalloc(dlen); | 7726 | "-> fwdt%u failed allocate template.\n", j); |
7445 | if (!ha->fw_dump_template) { | 7727 | goto failed; |
7446 | ql_log(ql_log_warn, vha, 0x016a, | 7728 | } |
7447 | "Failed fwdump template allocate %x bytes.\n", risc_size); | ||
7448 | goto failed_template; | ||
7449 | } | ||
7450 | |||
7451 | dcode = ha->fw_dump_template; | ||
7452 | risc_size = dlen / sizeof(*dcode); | ||
7453 | memcpy(dcode, qla27xx_fwdt_template_default(), dlen); | ||
7454 | for (i = 0; i < risc_size; i++) | ||
7455 | dcode[i] = be32_to_cpu(dcode[i]); | ||
7456 | |||
7457 | if (!qla27xx_fwdt_template_valid(ha->fw_dump_template)) { | ||
7458 | ql_log(ql_log_warn, vha, 0x016b, | ||
7459 | "Failed fwdump template validate\n"); | ||
7460 | goto failed_template; | ||
7461 | } | ||
7462 | |||
7463 | dlen = qla27xx_fwdt_template_size(ha->fw_dump_template); | ||
7464 | ql_dbg(ql_dbg_init, vha, 0x016c, | ||
7465 | "-> template size %x bytes\n", dlen); | ||
7466 | ha->fw_dump_template_len = dlen; | ||
7467 | return rval; | ||
7468 | 7729 | ||
7469 | failed_template: | 7730 | dcode = fwdt->template; |
7470 | ql_log(ql_log_warn, vha, 0x016d, "Failed default fwdump template\n"); | 7731 | qla24xx_read_flash_data(vha, dcode, faddr, risc_size); |
7471 | if (ha->fw_dump_template) | 7732 | |
7472 | vfree(ha->fw_dump_template); | 7733 | if (!qla27xx_fwdt_template_valid(dcode)) { |
7473 | ha->fw_dump_template = NULL; | 7734 | ql_log(ql_log_warn, vha, 0x0165, |
7474 | ha->fw_dump_template_len = 0; | 7735 | "-> fwdt%u failed template validate\n", j); |
7475 | return rval; | 7736 | goto failed; |
7737 | } | ||
7738 | |||
7739 | dlen = qla27xx_fwdt_template_size(dcode); | ||
7740 | ql_dbg(ql_dbg_init, vha, 0x0166, | ||
7741 | "-> fwdt%u template size %#lx bytes (%#lx words)\n", | ||
7742 | j, dlen, dlen / sizeof(*dcode)); | ||
7743 | if (dlen > risc_size * sizeof(*dcode)) { | ||
7744 | ql_log(ql_log_warn, vha, 0x0167, | ||
7745 | "-> fwdt%u template exceeds array (%-lu bytes)\n", | ||
7746 | j, dlen - risc_size * sizeof(*dcode)); | ||
7747 | goto failed; | ||
7748 | } | ||
7749 | |||
7750 | fwdt->length = dlen; | ||
7751 | ql_dbg(ql_dbg_init, vha, 0x0168, | ||
7752 | "-> fwdt%u loaded template ok\n", j); | ||
7753 | |||
7754 | faddr += risc_size + 1; | ||
7755 | } | ||
7756 | |||
7757 | return QLA_SUCCESS; | ||
7758 | |||
7759 | failed: | ||
7760 | if (fwdt->template) | ||
7761 | vfree(fwdt->template); | ||
7762 | fwdt->template = NULL; | ||
7763 | fwdt->length = 0; | ||
7764 | |||
7765 | return QLA_SUCCESS; | ||
7476 | } | 7766 | } |
7477 | 7767 | ||
7478 | #define QLA_FW_URL "http://ldriver.qlogic.com/firmware/" | 7768 | #define QLA_FW_URL "http://ldriver.qlogic.com/firmware/" |
@@ -7580,94 +7870,73 @@ static int | |||
7580 | qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) | 7870 | qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) |
7581 | { | 7871 | { |
7582 | int rval; | 7872 | int rval; |
7583 | int segments, fragment; | 7873 | uint templates, segments, fragment; |
7584 | uint32_t *dcode, dlen; | 7874 | uint32_t *dcode; |
7585 | uint32_t risc_addr; | 7875 | ulong dlen; |
7586 | uint32_t risc_size; | 7876 | uint32_t risc_addr, risc_size, risc_attr = 0; |
7587 | uint32_t i; | 7877 | ulong i; |
7878 | uint j; | ||
7588 | struct fw_blob *blob; | 7879 | struct fw_blob *blob; |
7589 | const uint32_t *fwcode; | 7880 | uint32_t *fwcode; |
7590 | uint32_t fwclen; | ||
7591 | struct qla_hw_data *ha = vha->hw; | 7881 | struct qla_hw_data *ha = vha->hw; |
7592 | struct req_que *req = ha->req_q_map[0]; | 7882 | struct req_que *req = ha->req_q_map[0]; |
7883 | struct fwdt *fwdt = ha->fwdt; | ||
7884 | |||
7885 | ql_dbg(ql_dbg_init, vha, 0x0090, | ||
7886 | "-> FW: Loading via request-firmware.\n"); | ||
7593 | 7887 | ||
7594 | /* Load firmware blob. */ | ||
7595 | blob = qla2x00_request_firmware(vha); | 7888 | blob = qla2x00_request_firmware(vha); |
7596 | if (!blob) { | 7889 | if (!blob) { |
7597 | ql_log(ql_log_warn, vha, 0x0090, | 7890 | ql_log(ql_log_warn, vha, 0x0092, |
7598 | "Firmware image unavailable.\n"); | 7891 | "-> Firmware file not found.\n"); |
7599 | ql_log(ql_log_warn, vha, 0x0091, | ||
7600 | "Firmware images can be retrieved from: " | ||
7601 | QLA_FW_URL ".\n"); | ||
7602 | 7892 | ||
7603 | return QLA_FUNCTION_FAILED; | 7893 | return QLA_FUNCTION_FAILED; |
7604 | } | 7894 | } |
7605 | 7895 | ||
7606 | ql_dbg(ql_dbg_init, vha, 0x0092, | 7896 | fwcode = (void *)blob->fw->data; |
7607 | "FW: Loading via request-firmware.\n"); | 7897 | dcode = fwcode; |
7608 | 7898 | if (qla24xx_risc_firmware_invalid(dcode)) { | |
7609 | rval = QLA_SUCCESS; | ||
7610 | |||
7611 | segments = FA_RISC_CODE_SEGMENTS; | ||
7612 | dcode = (uint32_t *)req->ring; | ||
7613 | *srisc_addr = 0; | ||
7614 | fwcode = (uint32_t *)blob->fw->data; | ||
7615 | fwclen = 0; | ||
7616 | |||
7617 | /* Validate firmware image by checking version. */ | ||
7618 | if (blob->fw->size < 8 * sizeof(uint32_t)) { | ||
7619 | ql_log(ql_log_fatal, vha, 0x0093, | 7899 | ql_log(ql_log_fatal, vha, 0x0093, |
7620 | "Unable to verify integrity of firmware image (%zd).\n", | 7900 | "Unable to verify integrity of firmware image (%zd).\n", |
7621 | blob->fw->size); | 7901 | blob->fw->size); |
7622 | return QLA_FUNCTION_FAILED; | ||
7623 | } | ||
7624 | for (i = 0; i < 4; i++) | ||
7625 | dcode[i] = be32_to_cpu(fwcode[i + 4]); | ||
7626 | if ((dcode[0] == 0xffffffff && dcode[1] == 0xffffffff && | ||
7627 | dcode[2] == 0xffffffff && dcode[3] == 0xffffffff) || | ||
7628 | (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 && | ||
7629 | dcode[3] == 0)) { | ||
7630 | ql_log(ql_log_fatal, vha, 0x0094, | ||
7631 | "Unable to verify integrity of firmware image (%zd).\n", | ||
7632 | blob->fw->size); | ||
7633 | ql_log(ql_log_fatal, vha, 0x0095, | 7902 | ql_log(ql_log_fatal, vha, 0x0095, |
7634 | "Firmware data: %08x %08x %08x %08x.\n", | 7903 | "Firmware data: %08x %08x %08x %08x.\n", |
7635 | dcode[0], dcode[1], dcode[2], dcode[3]); | 7904 | dcode[0], dcode[1], dcode[2], dcode[3]); |
7636 | return QLA_FUNCTION_FAILED; | 7905 | return QLA_FUNCTION_FAILED; |
7637 | } | 7906 | } |
7638 | 7907 | ||
7639 | while (segments && rval == QLA_SUCCESS) { | 7908 | dcode = (void *)req->ring; |
7909 | *srisc_addr = 0; | ||
7910 | segments = FA_RISC_CODE_SEGMENTS; | ||
7911 | for (j = 0; j < segments; j++) { | ||
7912 | ql_dbg(ql_dbg_init, vha, 0x0096, | ||
7913 | "-> Loading segment %u...\n", j); | ||
7640 | risc_addr = be32_to_cpu(fwcode[2]); | 7914 | risc_addr = be32_to_cpu(fwcode[2]); |
7641 | *srisc_addr = *srisc_addr == 0 ? risc_addr : *srisc_addr; | ||
7642 | risc_size = be32_to_cpu(fwcode[3]); | 7915 | risc_size = be32_to_cpu(fwcode[3]); |
7643 | 7916 | ||
7644 | /* Validate firmware image size. */ | 7917 | if (!*srisc_addr) { |
7645 | fwclen += risc_size * sizeof(uint32_t); | 7918 | *srisc_addr = risc_addr; |
7646 | if (blob->fw->size < fwclen) { | 7919 | risc_attr = be32_to_cpu(fwcode[9]); |
7647 | ql_log(ql_log_fatal, vha, 0x0096, | ||
7648 | "Unable to verify integrity of firmware image " | ||
7649 | "(%zd).\n", blob->fw->size); | ||
7650 | return QLA_FUNCTION_FAILED; | ||
7651 | } | 7920 | } |
7652 | 7921 | ||
7653 | fragment = 0; | 7922 | dlen = ha->fw_transfer_size >> 2; |
7654 | while (risc_size > 0 && rval == QLA_SUCCESS) { | 7923 | for (fragment = 0; risc_size; fragment++) { |
7655 | dlen = (uint32_t)(ha->fw_transfer_size >> 2); | ||
7656 | if (dlen > risc_size) | 7924 | if (dlen > risc_size) |
7657 | dlen = risc_size; | 7925 | dlen = risc_size; |
7658 | 7926 | ||
7659 | ql_dbg(ql_dbg_init, vha, 0x0097, | 7927 | ql_dbg(ql_dbg_init, vha, 0x0097, |
7660 | "Loading risc segment@ risc addr %x " | 7928 | "-> Loading fragment %u: %#x <- %#x (%#lx words)...\n", |
7661 | "number of dwords 0x%x.\n", risc_addr, dlen); | 7929 | fragment, risc_addr, |
7930 | (uint32_t)(fwcode - (typeof(fwcode))blob->fw->data), | ||
7931 | dlen); | ||
7662 | 7932 | ||
7663 | for (i = 0; i < dlen; i++) | 7933 | for (i = 0; i < dlen; i++) |
7664 | dcode[i] = swab32(fwcode[i]); | 7934 | dcode[i] = swab32(fwcode[i]); |
7665 | 7935 | ||
7666 | rval = qla2x00_load_ram(vha, req->dma, risc_addr, | 7936 | rval = qla2x00_load_ram(vha, req->dma, risc_addr, dlen); |
7667 | dlen); | ||
7668 | if (rval) { | 7937 | if (rval) { |
7669 | ql_log(ql_log_fatal, vha, 0x0098, | 7938 | ql_log(ql_log_fatal, vha, 0x0098, |
7670 | "Failed to load segment %d of firmware.\n", | 7939 | "-> Failed load firmware fragment %u.\n", |
7671 | fragment); | 7940 | fragment); |
7672 | return QLA_FUNCTION_FAILED; | 7941 | return QLA_FUNCTION_FAILED; |
7673 | } | 7942 | } |
@@ -7675,106 +7944,82 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
7675 | fwcode += dlen; | 7944 | fwcode += dlen; |
7676 | risc_addr += dlen; | 7945 | risc_addr += dlen; |
7677 | risc_size -= dlen; | 7946 | risc_size -= dlen; |
7678 | fragment++; | ||
7679 | } | 7947 | } |
7680 | |||
7681 | /* Next segment. */ | ||
7682 | segments--; | ||
7683 | } | 7948 | } |
7684 | 7949 | ||
7685 | if (!IS_QLA27XX(ha)) | 7950 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
7686 | return rval; | 7951 | return QLA_SUCCESS; |
7687 | 7952 | ||
7688 | if (ha->fw_dump_template) | 7953 | templates = (risc_attr & BIT_9) ? 2 : 1; |
7689 | vfree(ha->fw_dump_template); | 7954 | ql_dbg(ql_dbg_init, vha, 0x0170, "-> templates = %u\n", templates); |
7690 | ha->fw_dump_template = NULL; | 7955 | for (j = 0; j < templates; j++, fwdt++) { |
7691 | ha->fw_dump_template_len = 0; | 7956 | if (fwdt->template) |
7692 | 7957 | vfree(fwdt->template); | |
7693 | ql_dbg(ql_dbg_init, vha, 0x171, | 7958 | fwdt->template = NULL; |
7694 | "Loading fwdump template from %x\n", | 7959 | fwdt->length = 0; |
7695 | (uint32_t)((void *)fwcode - (void *)blob->fw->data)); | 7960 | |
7696 | risc_size = be32_to_cpu(fwcode[2]); | 7961 | risc_size = be32_to_cpu(fwcode[2]); |
7697 | ql_dbg(ql_dbg_init, vha, 0x172, | 7962 | ql_dbg(ql_dbg_init, vha, 0x0171, |
7698 | "-> array size %x dwords\n", risc_size); | 7963 | "-> fwdt%u template array at %#x (%#x dwords)\n", |
7699 | if (risc_size == 0 || risc_size == ~0) | 7964 | j, (uint32_t)((void *)fwcode - (void *)blob->fw->data), |
7700 | goto default_template; | 7965 | risc_size); |
7701 | 7966 | if (!risc_size || !~risc_size) { | |
7702 | dlen = (risc_size - 8) * sizeof(*fwcode); | 7967 | ql_dbg(ql_dbg_init, vha, 0x0172, |
7703 | ql_dbg(ql_dbg_init, vha, 0x0173, | 7968 | "-> fwdt%u failed to read array\n", j); |
7704 | "-> template allocating %x bytes...\n", dlen); | 7969 | goto failed; |
7705 | ha->fw_dump_template = vmalloc(dlen); | 7970 | } |
7706 | if (!ha->fw_dump_template) { | ||
7707 | ql_log(ql_log_warn, vha, 0x0174, | ||
7708 | "Failed fwdump template allocate %x bytes.\n", risc_size); | ||
7709 | goto default_template; | ||
7710 | } | ||
7711 | |||
7712 | fwcode += 7; | ||
7713 | risc_size -= 8; | ||
7714 | dcode = ha->fw_dump_template; | ||
7715 | for (i = 0; i < risc_size; i++) | ||
7716 | dcode[i] = le32_to_cpu(fwcode[i]); | ||
7717 | |||
7718 | if (!qla27xx_fwdt_template_valid(dcode)) { | ||
7719 | ql_log(ql_log_warn, vha, 0x0175, | ||
7720 | "Failed fwdump template validate\n"); | ||
7721 | goto default_template; | ||
7722 | } | ||
7723 | |||
7724 | dlen = qla27xx_fwdt_template_size(dcode); | ||
7725 | ql_dbg(ql_dbg_init, vha, 0x0176, | ||
7726 | "-> template size %x bytes\n", dlen); | ||
7727 | if (dlen > risc_size * sizeof(*fwcode)) { | ||
7728 | ql_log(ql_log_warn, vha, 0x0177, | ||
7729 | "Failed fwdump template exceeds array by %zx bytes\n", | ||
7730 | (size_t)(dlen - risc_size * sizeof(*fwcode))); | ||
7731 | goto default_template; | ||
7732 | } | ||
7733 | ha->fw_dump_template_len = dlen; | ||
7734 | return rval; | ||
7735 | 7971 | ||
7736 | default_template: | 7972 | /* skip header and ignore checksum */ |
7737 | ql_log(ql_log_warn, vha, 0x0178, "Using default fwdump template\n"); | 7973 | fwcode += 7; |
7738 | if (ha->fw_dump_template) | 7974 | risc_size -= 8; |
7739 | vfree(ha->fw_dump_template); | 7975 | |
7740 | ha->fw_dump_template = NULL; | 7976 | ql_dbg(ql_dbg_init, vha, 0x0173, |
7741 | ha->fw_dump_template_len = 0; | 7977 | "-> fwdt%u template allocate template %#x words...\n", |
7742 | 7978 | j, risc_size); | |
7743 | dlen = qla27xx_fwdt_template_default_size(); | 7979 | fwdt->template = vmalloc(risc_size * sizeof(*dcode)); |
7744 | ql_dbg(ql_dbg_init, vha, 0x0179, | 7980 | if (!fwdt->template) { |
7745 | "-> template allocating %x bytes...\n", dlen); | 7981 | ql_log(ql_log_warn, vha, 0x0174, |
7746 | ha->fw_dump_template = vmalloc(dlen); | 7982 | "-> fwdt%u failed allocate template.\n", j); |
7747 | if (!ha->fw_dump_template) { | 7983 | goto failed; |
7748 | ql_log(ql_log_warn, vha, 0x017a, | 7984 | } |
7749 | "Failed fwdump template allocate %x bytes.\n", risc_size); | ||
7750 | goto failed_template; | ||
7751 | } | ||
7752 | |||
7753 | dcode = ha->fw_dump_template; | ||
7754 | risc_size = dlen / sizeof(*fwcode); | ||
7755 | fwcode = qla27xx_fwdt_template_default(); | ||
7756 | for (i = 0; i < risc_size; i++) | ||
7757 | dcode[i] = be32_to_cpu(fwcode[i]); | ||
7758 | |||
7759 | if (!qla27xx_fwdt_template_valid(ha->fw_dump_template)) { | ||
7760 | ql_log(ql_log_warn, vha, 0x017b, | ||
7761 | "Failed fwdump template validate\n"); | ||
7762 | goto failed_template; | ||
7763 | } | ||
7764 | |||
7765 | dlen = qla27xx_fwdt_template_size(ha->fw_dump_template); | ||
7766 | ql_dbg(ql_dbg_init, vha, 0x017c, | ||
7767 | "-> template size %x bytes\n", dlen); | ||
7768 | ha->fw_dump_template_len = dlen; | ||
7769 | return rval; | ||
7770 | 7985 | ||
7771 | failed_template: | 7986 | dcode = fwdt->template; |
7772 | ql_log(ql_log_warn, vha, 0x017d, "Failed default fwdump template\n"); | 7987 | for (i = 0; i < risc_size; i++) |
7773 | if (ha->fw_dump_template) | 7988 | dcode[i] = fwcode[i]; |
7774 | vfree(ha->fw_dump_template); | 7989 | |
7775 | ha->fw_dump_template = NULL; | 7990 | if (!qla27xx_fwdt_template_valid(dcode)) { |
7776 | ha->fw_dump_template_len = 0; | 7991 | ql_log(ql_log_warn, vha, 0x0175, |
7777 | return rval; | 7992 | "-> fwdt%u failed template validate\n", j); |
7993 | goto failed; | ||
7994 | } | ||
7995 | |||
7996 | dlen = qla27xx_fwdt_template_size(dcode); | ||
7997 | ql_dbg(ql_dbg_init, vha, 0x0176, | ||
7998 | "-> fwdt%u template size %#lx bytes (%#lx words)\n", | ||
7999 | j, dlen, dlen / sizeof(*dcode)); | ||
8000 | if (dlen > risc_size * sizeof(*dcode)) { | ||
8001 | ql_log(ql_log_warn, vha, 0x0177, | ||
8002 | "-> fwdt%u template exceeds array (%-lu bytes)\n", | ||
8003 | j, dlen - risc_size * sizeof(*dcode)); | ||
8004 | goto failed; | ||
8005 | } | ||
8006 | |||
8007 | fwdt->length = dlen; | ||
8008 | ql_dbg(ql_dbg_init, vha, 0x0178, | ||
8009 | "-> fwdt%u loaded template ok\n", j); | ||
8010 | |||
8011 | fwcode += risc_size + 1; | ||
8012 | } | ||
8013 | |||
8014 | return QLA_SUCCESS; | ||
8015 | |||
8016 | failed: | ||
8017 | if (fwdt->template) | ||
8018 | vfree(fwdt->template); | ||
8019 | fwdt->template = NULL; | ||
8020 | fwdt->length = 0; | ||
8021 | |||
8022 | return QLA_SUCCESS; | ||
7778 | } | 8023 | } |
7779 | 8024 | ||
7780 | int | 8025 | int |
@@ -7803,32 +8048,50 @@ qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) | |||
7803 | { | 8048 | { |
7804 | int rval; | 8049 | int rval; |
7805 | struct qla_hw_data *ha = vha->hw; | 8050 | struct qla_hw_data *ha = vha->hw; |
8051 | struct active_regions active_regions = { }; | ||
7806 | 8052 | ||
7807 | if (ql2xfwloadbin == 2) | 8053 | if (ql2xfwloadbin == 2) |
7808 | goto try_blob_fw; | 8054 | goto try_blob_fw; |
7809 | 8055 | ||
7810 | /* | 8056 | /* FW Load priority: |
7811 | * FW Load priority: | ||
7812 | * 1) Firmware residing in flash. | 8057 | * 1) Firmware residing in flash. |
7813 | * 2) Firmware via request-firmware interface (.bin file). | 8058 | * 2) Firmware via request-firmware interface (.bin file). |
7814 | * 3) Golden-Firmware residing in flash -- limited operation. | 8059 | * 3) Golden-Firmware residing in flash -- (limited operation). |
7815 | */ | 8060 | */ |
8061 | |||
8062 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) | ||
8063 | goto try_primary_fw; | ||
8064 | |||
8065 | qla27xx_get_active_image(vha, &active_regions); | ||
8066 | |||
8067 | if (active_regions.global != QLA27XX_SECONDARY_IMAGE) | ||
8068 | goto try_primary_fw; | ||
8069 | |||
8070 | ql_dbg(ql_dbg_init, vha, 0x008b, | ||
8071 | "Loading secondary firmware image.\n"); | ||
8072 | rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_fw_sec); | ||
8073 | if (!rval) | ||
8074 | return rval; | ||
8075 | |||
8076 | try_primary_fw: | ||
8077 | ql_dbg(ql_dbg_init, vha, 0x008b, | ||
8078 | "Loading primary firmware image.\n"); | ||
7816 | rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_fw); | 8079 | rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_fw); |
7817 | if (rval == QLA_SUCCESS) | 8080 | if (!rval) |
7818 | return rval; | 8081 | return rval; |
7819 | 8082 | ||
7820 | try_blob_fw: | 8083 | try_blob_fw: |
7821 | rval = qla24xx_load_risc_blob(vha, srisc_addr); | 8084 | rval = qla24xx_load_risc_blob(vha, srisc_addr); |
7822 | if (rval == QLA_SUCCESS || !ha->flt_region_gold_fw) | 8085 | if (!rval || !ha->flt_region_gold_fw) |
7823 | return rval; | 8086 | return rval; |
7824 | 8087 | ||
7825 | ql_log(ql_log_info, vha, 0x0099, | 8088 | ql_log(ql_log_info, vha, 0x0099, |
7826 | "Attempting to fallback to golden firmware.\n"); | 8089 | "Attempting to fallback to golden firmware.\n"); |
7827 | rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_gold_fw); | 8090 | rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_gold_fw); |
7828 | if (rval != QLA_SUCCESS) | 8091 | if (rval) |
7829 | return rval; | 8092 | return rval; |
7830 | 8093 | ||
7831 | ql_log(ql_log_info, vha, 0x009a, "Update operational firmware.\n"); | 8094 | ql_log(ql_log_info, vha, 0x009a, "Need firmware flash update.\n"); |
7832 | ha->flags.running_gold_fw = 1; | 8095 | ha->flags.running_gold_fw = 1; |
7833 | return rval; | 8096 | return rval; |
7834 | } | 8097 | } |
@@ -7963,6 +8226,7 @@ void | |||
7963 | qla84xx_put_chip(struct scsi_qla_host *vha) | 8226 | qla84xx_put_chip(struct scsi_qla_host *vha) |
7964 | { | 8227 | { |
7965 | struct qla_hw_data *ha = vha->hw; | 8228 | struct qla_hw_data *ha = vha->hw; |
8229 | |||
7966 | if (ha->cs84xx) | 8230 | if (ha->cs84xx) |
7967 | kref_put(&ha->cs84xx->kref, __qla84xx_chip_release); | 8231 | kref_put(&ha->cs84xx->kref, __qla84xx_chip_release); |
7968 | } | 8232 | } |
@@ -7980,7 +8244,7 @@ qla84xx_init_chip(scsi_qla_host_t *vha) | |||
7980 | 8244 | ||
7981 | mutex_unlock(&ha->cs84xx->fw_update_mutex); | 8245 | mutex_unlock(&ha->cs84xx->fw_update_mutex); |
7982 | 8246 | ||
7983 | return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED: | 8247 | return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED : |
7984 | QLA_SUCCESS; | 8248 | QLA_SUCCESS; |
7985 | } | 8249 | } |
7986 | 8250 | ||
@@ -7997,25 +8261,48 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) | |||
7997 | uint32_t chksum; | 8261 | uint32_t chksum; |
7998 | uint16_t cnt; | 8262 | uint16_t cnt; |
7999 | struct qla_hw_data *ha = vha->hw; | 8263 | struct qla_hw_data *ha = vha->hw; |
8264 | uint32_t faddr; | ||
8265 | struct active_regions active_regions = { }; | ||
8000 | 8266 | ||
8001 | rval = QLA_SUCCESS; | 8267 | rval = QLA_SUCCESS; |
8002 | icb = (struct init_cb_81xx *)ha->init_cb; | 8268 | icb = (struct init_cb_81xx *)ha->init_cb; |
8003 | nv = ha->nvram; | 8269 | nv = ha->nvram; |
8004 | 8270 | ||
8005 | /* Determine NVRAM starting address. */ | 8271 | /* Determine NVRAM starting address. */ |
8006 | ha->nvram_size = sizeof(struct nvram_81xx); | 8272 | ha->nvram_size = sizeof(*nv); |
8007 | ha->vpd_size = FA_NVRAM_VPD_SIZE; | 8273 | ha->vpd_size = FA_NVRAM_VPD_SIZE; |
8008 | if (IS_P3P_TYPE(ha) || IS_QLA8031(ha)) | 8274 | if (IS_P3P_TYPE(ha) || IS_QLA8031(ha)) |
8009 | ha->vpd_size = FA_VPD_SIZE_82XX; | 8275 | ha->vpd_size = FA_VPD_SIZE_82XX; |
8010 | 8276 | ||
8277 | if (IS_QLA28XX(ha) || IS_QLA27XX(ha)) | ||
8278 | qla28xx_get_aux_images(vha, &active_regions); | ||
8279 | |||
8011 | /* Get VPD data into cache */ | 8280 | /* Get VPD data into cache */ |
8012 | ha->vpd = ha->nvram + VPD_OFFSET; | 8281 | ha->vpd = ha->nvram + VPD_OFFSET; |
8013 | ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_vpd << 2, | 8282 | |
8014 | ha->vpd_size); | 8283 | faddr = ha->flt_region_vpd; |
8284 | if (IS_QLA28XX(ha)) { | ||
8285 | if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE) | ||
8286 | faddr = ha->flt_region_vpd_sec; | ||
8287 | ql_dbg(ql_dbg_init, vha, 0x0110, | ||
8288 | "Loading %s nvram image.\n", | ||
8289 | active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ? | ||
8290 | "primary" : "secondary"); | ||
8291 | } | ||
8292 | qla24xx_read_flash_data(vha, ha->vpd, faddr, ha->vpd_size >> 2); | ||
8015 | 8293 | ||
8016 | /* Get NVRAM data into cache and calculate checksum. */ | 8294 | /* Get NVRAM data into cache and calculate checksum. */ |
8017 | ha->isp_ops->read_optrom(vha, ha->nvram, ha->flt_region_nvram << 2, | 8295 | faddr = ha->flt_region_nvram; |
8018 | ha->nvram_size); | 8296 | if (IS_QLA28XX(ha)) { |
8297 | if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE) | ||
8298 | faddr = ha->flt_region_nvram_sec; | ||
8299 | } | ||
8300 | ql_dbg(ql_dbg_init, vha, 0x0110, | ||
8301 | "Loading %s nvram image.\n", | ||
8302 | active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ? | ||
8303 | "primary" : "secondary"); | ||
8304 | qla24xx_read_flash_data(vha, ha->nvram, faddr, ha->nvram_size >> 2); | ||
8305 | |||
8019 | dptr = (uint32_t *)nv; | 8306 | dptr = (uint32_t *)nv; |
8020 | for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++) | 8307 | for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++) |
8021 | chksum += le32_to_cpu(*dptr); | 8308 | chksum += le32_to_cpu(*dptr); |
@@ -8023,17 +8310,16 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) | |||
8023 | ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x0111, | 8310 | ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x0111, |
8024 | "Contents of NVRAM:\n"); | 8311 | "Contents of NVRAM:\n"); |
8025 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0112, | 8312 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0112, |
8026 | (uint8_t *)nv, ha->nvram_size); | 8313 | nv, ha->nvram_size); |
8027 | 8314 | ||
8028 | /* Bad NVRAM data, set defaults parameters. */ | 8315 | /* Bad NVRAM data, set defaults parameters. */ |
8029 | if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || nv->id[2] != 'P' | 8316 | if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) || |
8030 | || nv->id[3] != ' ' || | 8317 | le16_to_cpu(nv->nvram_version) < ICB_VERSION) { |
8031 | nv->nvram_version < cpu_to_le16(ICB_VERSION)) { | ||
8032 | /* Reset NVRAM data. */ | 8318 | /* Reset NVRAM data. */ |
8033 | ql_log(ql_log_info, vha, 0x0073, | 8319 | ql_log(ql_log_info, vha, 0x0073, |
8034 | "Inconsistent NVRAM detected: checksum=0x%x id=%c " | 8320 | "Inconsistent NVRAM checksum=%#x id=%.4s version=%#x.\n", |
8035 | "version=0x%x.\n", chksum, nv->id[0], | 8321 | chksum, nv->id, le16_to_cpu(nv->nvram_version)); |
8036 | le16_to_cpu(nv->nvram_version)); | 8322 | ql_dump_buffer(ql_dbg_init, vha, 0x0073, nv, sizeof(*nv)); |
8037 | ql_log(ql_log_info, vha, 0x0074, | 8323 | ql_log(ql_log_info, vha, 0x0074, |
8038 | "Falling back to functioning (yet invalid -- WWPN) " | 8324 | "Falling back to functioning (yet invalid -- WWPN) " |
8039 | "defaults.\n"); | 8325 | "defaults.\n"); |
@@ -8154,11 +8440,11 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) | |||
8154 | ha->flags.disable_risc_code_load = 0; | 8440 | ha->flags.disable_risc_code_load = 0; |
8155 | ha->flags.enable_lip_reset = 0; | 8441 | ha->flags.enable_lip_reset = 0; |
8156 | ha->flags.enable_lip_full_login = | 8442 | ha->flags.enable_lip_full_login = |
8157 | le32_to_cpu(nv->host_p) & BIT_10 ? 1: 0; | 8443 | le32_to_cpu(nv->host_p) & BIT_10 ? 1 : 0; |
8158 | ha->flags.enable_target_reset = | 8444 | ha->flags.enable_target_reset = |
8159 | le32_to_cpu(nv->host_p) & BIT_11 ? 1: 0; | 8445 | le32_to_cpu(nv->host_p) & BIT_11 ? 1 : 0; |
8160 | ha->flags.enable_led_scheme = 0; | 8446 | ha->flags.enable_led_scheme = 0; |
8161 | ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1: 0; | 8447 | ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1 : 0; |
8162 | 8448 | ||
8163 | ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) & | 8449 | ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) & |
8164 | (BIT_6 | BIT_5 | BIT_4)) >> 4; | 8450 | (BIT_6 | BIT_5 | BIT_4)) >> 4; |
@@ -8222,7 +8508,8 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) | |||
8222 | ha->login_retry_count = ql2xloginretrycount; | 8508 | ha->login_retry_count = ql2xloginretrycount; |
8223 | 8509 | ||
8224 | /* if not running MSI-X we need handshaking on interrupts */ | 8510 | /* if not running MSI-X we need handshaking on interrupts */ |
8225 | if (!vha->hw->flags.msix_enabled && (IS_QLA83XX(ha) || IS_QLA27XX(ha))) | 8511 | if (!vha->hw->flags.msix_enabled && |
8512 | (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))) | ||
8226 | icb->firmware_options_2 |= cpu_to_le32(BIT_22); | 8513 | icb->firmware_options_2 |= cpu_to_le32(BIT_22); |
8227 | 8514 | ||
8228 | /* Enable ZIO. */ | 8515 | /* Enable ZIO. */ |
@@ -8230,7 +8517,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) | |||
8230 | ha->zio_mode = le32_to_cpu(icb->firmware_options_2) & | 8517 | ha->zio_mode = le32_to_cpu(icb->firmware_options_2) & |
8231 | (BIT_3 | BIT_2 | BIT_1 | BIT_0); | 8518 | (BIT_3 | BIT_2 | BIT_1 | BIT_0); |
8232 | ha->zio_timer = le16_to_cpu(icb->interrupt_delay_timer) ? | 8519 | ha->zio_timer = le16_to_cpu(icb->interrupt_delay_timer) ? |
8233 | le16_to_cpu(icb->interrupt_delay_timer): 2; | 8520 | le16_to_cpu(icb->interrupt_delay_timer) : 2; |
8234 | } | 8521 | } |
8235 | icb->firmware_options_2 &= cpu_to_le32( | 8522 | icb->firmware_options_2 &= cpu_to_le32( |
8236 | ~(BIT_3 | BIT_2 | BIT_1 | BIT_0)); | 8523 | ~(BIT_3 | BIT_2 | BIT_1 | BIT_0)); |
@@ -8255,12 +8542,6 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) | |||
8255 | /* N2N: driver will initiate Login instead of FW */ | 8542 | /* N2N: driver will initiate Login instead of FW */ |
8256 | icb->firmware_options_3 |= BIT_8; | 8543 | icb->firmware_options_3 |= BIT_8; |
8257 | 8544 | ||
8258 | if (IS_QLA27XX(ha)) { | ||
8259 | icb->firmware_options_3 |= BIT_8; | ||
8260 | ql_dbg(ql_log_info, vha, 0x0075, | ||
8261 | "Enabling direct connection.\n"); | ||
8262 | } | ||
8263 | |||
8264 | if (rval) { | 8545 | if (rval) { |
8265 | ql_log(ql_log_warn, vha, 0x0076, | 8546 | ql_log(ql_log_warn, vha, 0x0076, |
8266 | "NVRAM configuration failed.\n"); | 8547 | "NVRAM configuration failed.\n"); |
@@ -8621,7 +8902,6 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, | |||
8621 | "Failed to allocate memory for queue pair.\n"); | 8902 | "Failed to allocate memory for queue pair.\n"); |
8622 | return NULL; | 8903 | return NULL; |
8623 | } | 8904 | } |
8624 | memset(qpair, 0, sizeof(struct qla_qpair)); | ||
8625 | 8905 | ||
8626 | qpair->hw = vha->hw; | 8906 | qpair->hw = vha->hw; |
8627 | qpair->vha = vha; | 8907 | qpair->vha = vha; |
@@ -8668,7 +8948,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, | |||
8668 | qpair->msix->in_use = 1; | 8948 | qpair->msix->in_use = 1; |
8669 | list_add_tail(&qpair->qp_list_elem, &vha->qp_list); | 8949 | list_add_tail(&qpair->qp_list_elem, &vha->qp_list); |
8670 | qpair->pdev = ha->pdev; | 8950 | qpair->pdev = ha->pdev; |
8671 | if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) | 8951 | if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) |
8672 | qpair->reqq_start_iocbs = qla_83xx_start_iocbs; | 8952 | qpair->reqq_start_iocbs = qla_83xx_start_iocbs; |
8673 | 8953 | ||
8674 | mutex_unlock(&ha->mq_lock); | 8954 | mutex_unlock(&ha->mq_lock); |
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index 512c3c37b447..bf063c664352 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h | |||
@@ -91,43 +91,6 @@ host_to_adap(uint8_t *src, uint8_t *dst, uint32_t bsize) | |||
91 | } | 91 | } |
92 | 92 | ||
93 | static inline void | 93 | static inline void |
94 | qla2x00_set_reserved_loop_ids(struct qla_hw_data *ha) | ||
95 | { | ||
96 | int i; | ||
97 | |||
98 | if (IS_FWI2_CAPABLE(ha)) | ||
99 | return; | ||
100 | |||
101 | for (i = 0; i < SNS_FIRST_LOOP_ID; i++) | ||
102 | set_bit(i, ha->loop_id_map); | ||
103 | set_bit(MANAGEMENT_SERVER, ha->loop_id_map); | ||
104 | set_bit(BROADCAST, ha->loop_id_map); | ||
105 | } | ||
106 | |||
107 | static inline int | ||
108 | qla2x00_is_reserved_id(scsi_qla_host_t *vha, uint16_t loop_id) | ||
109 | { | ||
110 | struct qla_hw_data *ha = vha->hw; | ||
111 | if (IS_FWI2_CAPABLE(ha)) | ||
112 | return (loop_id > NPH_LAST_HANDLE); | ||
113 | |||
114 | return ((loop_id > ha->max_loop_id && loop_id < SNS_FIRST_LOOP_ID) || | ||
115 | loop_id == MANAGEMENT_SERVER || loop_id == BROADCAST); | ||
116 | } | ||
117 | |||
118 | static inline void | ||
119 | qla2x00_clear_loop_id(fc_port_t *fcport) { | ||
120 | struct qla_hw_data *ha = fcport->vha->hw; | ||
121 | |||
122 | if (fcport->loop_id == FC_NO_LOOP_ID || | ||
123 | qla2x00_is_reserved_id(fcport->vha, fcport->loop_id)) | ||
124 | return; | ||
125 | |||
126 | clear_bit(fcport->loop_id, ha->loop_id_map); | ||
127 | fcport->loop_id = FC_NO_LOOP_ID; | ||
128 | } | ||
129 | |||
130 | static inline void | ||
131 | qla2x00_clean_dsd_pool(struct qla_hw_data *ha, struct crc_context *ctx) | 94 | qla2x00_clean_dsd_pool(struct qla_hw_data *ha, struct crc_context *ctx) |
132 | { | 95 | { |
133 | struct dsd_dma *dsd, *tdsd; | 96 | struct dsd_dma *dsd, *tdsd; |
@@ -142,25 +105,6 @@ qla2x00_clean_dsd_pool(struct qla_hw_data *ha, struct crc_context *ctx) | |||
142 | INIT_LIST_HEAD(&ctx->dsd_list); | 105 | INIT_LIST_HEAD(&ctx->dsd_list); |
143 | } | 106 | } |
144 | 107 | ||
145 | static inline void | ||
146 | qla2x00_set_fcport_state(fc_port_t *fcport, int state) | ||
147 | { | ||
148 | int old_state; | ||
149 | |||
150 | old_state = atomic_read(&fcport->state); | ||
151 | atomic_set(&fcport->state, state); | ||
152 | |||
153 | /* Don't print state transitions during initial allocation of fcport */ | ||
154 | if (old_state && old_state != state) { | ||
155 | ql_dbg(ql_dbg_disc, fcport->vha, 0x207d, | ||
156 | "FCPort %8phC state transitioned from %s to %s - " | ||
157 | "portid=%02x%02x%02x.\n", fcport->port_name, | ||
158 | port_state_str[old_state], port_state_str[state], | ||
159 | fcport->d_id.b.domain, fcport->d_id.b.area, | ||
160 | fcport->d_id.b.al_pa); | ||
161 | } | ||
162 | } | ||
163 | |||
164 | static inline int | 108 | static inline int |
165 | qla2x00_hba_err_chk_enabled(srb_t *sp) | 109 | qla2x00_hba_err_chk_enabled(srb_t *sp) |
166 | { | 110 | { |
@@ -240,6 +184,7 @@ done: | |||
240 | static inline void | 184 | static inline void |
241 | qla2xxx_rel_qpair_sp(struct qla_qpair *qpair, srb_t *sp) | 185 | qla2xxx_rel_qpair_sp(struct qla_qpair *qpair, srb_t *sp) |
242 | { | 186 | { |
187 | sp->qpair = NULL; | ||
243 | mempool_free(sp, qpair->srb_mempool); | 188 | mempool_free(sp, qpair->srb_mempool); |
244 | QLA_QPAIR_MARK_NOT_BUSY(qpair); | 189 | QLA_QPAIR_MARK_NOT_BUSY(qpair); |
245 | } | 190 | } |
@@ -274,18 +219,6 @@ qla2x00_rel_sp(srb_t *sp) | |||
274 | qla2xxx_rel_qpair_sp(sp->qpair, sp); | 219 | qla2xxx_rel_qpair_sp(sp->qpair, sp); |
275 | } | 220 | } |
276 | 221 | ||
277 | static inline void | ||
278 | qla2x00_init_timer(srb_t *sp, unsigned long tmo) | ||
279 | { | ||
280 | timer_setup(&sp->u.iocb_cmd.timer, qla2x00_sp_timeout, 0); | ||
281 | sp->u.iocb_cmd.timer.expires = jiffies + tmo * HZ; | ||
282 | sp->free = qla2x00_sp_free; | ||
283 | init_completion(&sp->comp); | ||
284 | if (IS_QLAFX00(sp->vha->hw) && (sp->type == SRB_FXIOCB_DCMD)) | ||
285 | init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp); | ||
286 | add_timer(&sp->u.iocb_cmd.timer); | ||
287 | } | ||
288 | |||
289 | static inline int | 222 | static inline int |
290 | qla2x00_gid_list_size(struct qla_hw_data *ha) | 223 | qla2x00_gid_list_size(struct qla_hw_data *ha) |
291 | { | 224 | { |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 456a41d2e2c6..9312b19ed708 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -107,7 +107,7 @@ qla2x00_prep_cont_type0_iocb(struct scsi_qla_host *vha) | |||
107 | cont_pkt = (cont_entry_t *)req->ring_ptr; | 107 | cont_pkt = (cont_entry_t *)req->ring_ptr; |
108 | 108 | ||
109 | /* Load packet defaults. */ | 109 | /* Load packet defaults. */ |
110 | *((uint32_t *)(&cont_pkt->entry_type)) = cpu_to_le32(CONTINUE_TYPE); | 110 | put_unaligned_le32(CONTINUE_TYPE, &cont_pkt->entry_type); |
111 | 111 | ||
112 | return (cont_pkt); | 112 | return (cont_pkt); |
113 | } | 113 | } |
@@ -136,9 +136,8 @@ qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha, struct req_que *req) | |||
136 | cont_pkt = (cont_a64_entry_t *)req->ring_ptr; | 136 | cont_pkt = (cont_a64_entry_t *)req->ring_ptr; |
137 | 137 | ||
138 | /* Load packet defaults. */ | 138 | /* Load packet defaults. */ |
139 | *((uint32_t *)(&cont_pkt->entry_type)) = IS_QLAFX00(vha->hw) ? | 139 | put_unaligned_le32(IS_QLAFX00(vha->hw) ? CONTINUE_A64_TYPE_FX00 : |
140 | cpu_to_le32(CONTINUE_A64_TYPE_FX00) : | 140 | CONTINUE_A64_TYPE, &cont_pkt->entry_type); |
141 | cpu_to_le32(CONTINUE_A64_TYPE); | ||
142 | 141 | ||
143 | return (cont_pkt); | 142 | return (cont_pkt); |
144 | } | 143 | } |
@@ -193,7 +192,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt, | |||
193 | uint16_t tot_dsds) | 192 | uint16_t tot_dsds) |
194 | { | 193 | { |
195 | uint16_t avail_dsds; | 194 | uint16_t avail_dsds; |
196 | uint32_t *cur_dsd; | 195 | struct dsd32 *cur_dsd; |
197 | scsi_qla_host_t *vha; | 196 | scsi_qla_host_t *vha; |
198 | struct scsi_cmnd *cmd; | 197 | struct scsi_cmnd *cmd; |
199 | struct scatterlist *sg; | 198 | struct scatterlist *sg; |
@@ -202,8 +201,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt, | |||
202 | cmd = GET_CMD_SP(sp); | 201 | cmd = GET_CMD_SP(sp); |
203 | 202 | ||
204 | /* Update entry type to indicate Command Type 2 IOCB */ | 203 | /* Update entry type to indicate Command Type 2 IOCB */ |
205 | *((uint32_t *)(&cmd_pkt->entry_type)) = | 204 | put_unaligned_le32(COMMAND_TYPE, &cmd_pkt->entry_type); |
206 | cpu_to_le32(COMMAND_TYPE); | ||
207 | 205 | ||
208 | /* No data transfer */ | 206 | /* No data transfer */ |
209 | if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { | 207 | if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { |
@@ -215,8 +213,8 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt, | |||
215 | cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp)); | 213 | cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp)); |
216 | 214 | ||
217 | /* Three DSDs are available in the Command Type 2 IOCB */ | 215 | /* Three DSDs are available in the Command Type 2 IOCB */ |
218 | avail_dsds = 3; | 216 | avail_dsds = ARRAY_SIZE(cmd_pkt->dsd32); |
219 | cur_dsd = (uint32_t *)&cmd_pkt->dseg_0_address; | 217 | cur_dsd = cmd_pkt->dsd32; |
220 | 218 | ||
221 | /* Load data segments */ | 219 | /* Load data segments */ |
222 | scsi_for_each_sg(cmd, sg, tot_dsds, i) { | 220 | scsi_for_each_sg(cmd, sg, tot_dsds, i) { |
@@ -229,12 +227,11 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt, | |||
229 | * Type 0 IOCB. | 227 | * Type 0 IOCB. |
230 | */ | 228 | */ |
231 | cont_pkt = qla2x00_prep_cont_type0_iocb(vha); | 229 | cont_pkt = qla2x00_prep_cont_type0_iocb(vha); |
232 | cur_dsd = (uint32_t *)&cont_pkt->dseg_0_address; | 230 | cur_dsd = cont_pkt->dsd; |
233 | avail_dsds = 7; | 231 | avail_dsds = ARRAY_SIZE(cont_pkt->dsd); |
234 | } | 232 | } |
235 | 233 | ||
236 | *cur_dsd++ = cpu_to_le32(sg_dma_address(sg)); | 234 | append_dsd32(&cur_dsd, sg); |
237 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
238 | avail_dsds--; | 235 | avail_dsds--; |
239 | } | 236 | } |
240 | } | 237 | } |
@@ -251,7 +248,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt, | |||
251 | uint16_t tot_dsds) | 248 | uint16_t tot_dsds) |
252 | { | 249 | { |
253 | uint16_t avail_dsds; | 250 | uint16_t avail_dsds; |
254 | uint32_t *cur_dsd; | 251 | struct dsd64 *cur_dsd; |
255 | scsi_qla_host_t *vha; | 252 | scsi_qla_host_t *vha; |
256 | struct scsi_cmnd *cmd; | 253 | struct scsi_cmnd *cmd; |
257 | struct scatterlist *sg; | 254 | struct scatterlist *sg; |
@@ -260,7 +257,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt, | |||
260 | cmd = GET_CMD_SP(sp); | 257 | cmd = GET_CMD_SP(sp); |
261 | 258 | ||
262 | /* Update entry type to indicate Command Type 3 IOCB */ | 259 | /* Update entry type to indicate Command Type 3 IOCB */ |
263 | *((uint32_t *)(&cmd_pkt->entry_type)) = cpu_to_le32(COMMAND_A64_TYPE); | 260 | put_unaligned_le32(COMMAND_A64_TYPE, &cmd_pkt->entry_type); |
264 | 261 | ||
265 | /* No data transfer */ | 262 | /* No data transfer */ |
266 | if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { | 263 | if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { |
@@ -272,12 +269,11 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt, | |||
272 | cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp)); | 269 | cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp)); |
273 | 270 | ||
274 | /* Two DSDs are available in the Command Type 3 IOCB */ | 271 | /* Two DSDs are available in the Command Type 3 IOCB */ |
275 | avail_dsds = 2; | 272 | avail_dsds = ARRAY_SIZE(cmd_pkt->dsd64); |
276 | cur_dsd = (uint32_t *)&cmd_pkt->dseg_0_address; | 273 | cur_dsd = cmd_pkt->dsd64; |
277 | 274 | ||
278 | /* Load data segments */ | 275 | /* Load data segments */ |
279 | scsi_for_each_sg(cmd, sg, tot_dsds, i) { | 276 | scsi_for_each_sg(cmd, sg, tot_dsds, i) { |
280 | dma_addr_t sle_dma; | ||
281 | cont_a64_entry_t *cont_pkt; | 277 | cont_a64_entry_t *cont_pkt; |
282 | 278 | ||
283 | /* Allocate additional continuation packets? */ | 279 | /* Allocate additional continuation packets? */ |
@@ -287,14 +283,11 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt, | |||
287 | * Type 1 IOCB. | 283 | * Type 1 IOCB. |
288 | */ | 284 | */ |
289 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req); | 285 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req); |
290 | cur_dsd = (uint32_t *)cont_pkt->dseg_0_address; | 286 | cur_dsd = cont_pkt->dsd; |
291 | avail_dsds = 5; | 287 | avail_dsds = ARRAY_SIZE(cont_pkt->dsd); |
292 | } | 288 | } |
293 | 289 | ||
294 | sle_dma = sg_dma_address(sg); | 290 | append_dsd64(&cur_dsd, sg); |
295 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
296 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
297 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
298 | avail_dsds--; | 291 | avail_dsds--; |
299 | } | 292 | } |
300 | } | 293 | } |
@@ -467,7 +460,7 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req) | |||
467 | req->ring_ptr++; | 460 | req->ring_ptr++; |
468 | 461 | ||
469 | /* Set chip new ring index. */ | 462 | /* Set chip new ring index. */ |
470 | if (ha->mqenable || IS_QLA27XX(ha)) { | 463 | if (ha->mqenable || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
471 | WRT_REG_DWORD(req->req_q_in, req->ring_index); | 464 | WRT_REG_DWORD(req->req_q_in, req->ring_index); |
472 | } else if (IS_QLA83XX(ha)) { | 465 | } else if (IS_QLA83XX(ha)) { |
473 | WRT_REG_DWORD(req->req_q_in, req->ring_index); | 466 | WRT_REG_DWORD(req->req_q_in, req->ring_index); |
@@ -580,13 +573,11 @@ static inline int | |||
580 | qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, | 573 | qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, |
581 | uint16_t tot_dsds) | 574 | uint16_t tot_dsds) |
582 | { | 575 | { |
583 | uint32_t *cur_dsd = NULL; | 576 | struct dsd64 *cur_dsd = NULL, *next_dsd; |
584 | scsi_qla_host_t *vha; | 577 | scsi_qla_host_t *vha; |
585 | struct qla_hw_data *ha; | 578 | struct qla_hw_data *ha; |
586 | struct scsi_cmnd *cmd; | 579 | struct scsi_cmnd *cmd; |
587 | struct scatterlist *cur_seg; | 580 | struct scatterlist *cur_seg; |
588 | uint32_t *dsd_seg; | ||
589 | void *next_dsd; | ||
590 | uint8_t avail_dsds; | 581 | uint8_t avail_dsds; |
591 | uint8_t first_iocb = 1; | 582 | uint8_t first_iocb = 1; |
592 | uint32_t dsd_list_len; | 583 | uint32_t dsd_list_len; |
@@ -596,7 +587,7 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, | |||
596 | cmd = GET_CMD_SP(sp); | 587 | cmd = GET_CMD_SP(sp); |
597 | 588 | ||
598 | /* Update entry type to indicate Command Type 3 IOCB */ | 589 | /* Update entry type to indicate Command Type 3 IOCB */ |
599 | *((uint32_t *)(&cmd_pkt->entry_type)) = cpu_to_le32(COMMAND_TYPE_6); | 590 | put_unaligned_le32(COMMAND_TYPE_6, &cmd_pkt->entry_type); |
600 | 591 | ||
601 | /* No data transfer */ | 592 | /* No data transfer */ |
602 | if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { | 593 | if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { |
@@ -638,32 +629,27 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, | |||
638 | 629 | ||
639 | if (first_iocb) { | 630 | if (first_iocb) { |
640 | first_iocb = 0; | 631 | first_iocb = 0; |
641 | dsd_seg = (uint32_t *)&cmd_pkt->fcp_data_dseg_address; | 632 | put_unaligned_le64(dsd_ptr->dsd_list_dma, |
642 | *dsd_seg++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); | 633 | &cmd_pkt->fcp_dsd.address); |
643 | *dsd_seg++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); | 634 | cmd_pkt->fcp_dsd.length = cpu_to_le32(dsd_list_len); |
644 | cmd_pkt->fcp_data_dseg_len = cpu_to_le32(dsd_list_len); | ||
645 | } else { | 635 | } else { |
646 | *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); | 636 | put_unaligned_le64(dsd_ptr->dsd_list_dma, |
647 | *cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); | 637 | &cur_dsd->address); |
648 | *cur_dsd++ = cpu_to_le32(dsd_list_len); | 638 | cur_dsd->length = cpu_to_le32(dsd_list_len); |
639 | cur_dsd++; | ||
649 | } | 640 | } |
650 | cur_dsd = (uint32_t *)next_dsd; | 641 | cur_dsd = next_dsd; |
651 | while (avail_dsds) { | 642 | while (avail_dsds) { |
652 | dma_addr_t sle_dma; | 643 | append_dsd64(&cur_dsd, cur_seg); |
653 | |||
654 | sle_dma = sg_dma_address(cur_seg); | ||
655 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
656 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
657 | *cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg)); | ||
658 | cur_seg = sg_next(cur_seg); | 644 | cur_seg = sg_next(cur_seg); |
659 | avail_dsds--; | 645 | avail_dsds--; |
660 | } | 646 | } |
661 | } | 647 | } |
662 | 648 | ||
663 | /* Null termination */ | 649 | /* Null termination */ |
664 | *cur_dsd++ = 0; | 650 | cur_dsd->address = 0; |
665 | *cur_dsd++ = 0; | 651 | cur_dsd->length = 0; |
666 | *cur_dsd++ = 0; | 652 | cur_dsd++; |
667 | cmd_pkt->control_flags |= CF_DATA_SEG_DESCR_ENABLE; | 653 | cmd_pkt->control_flags |= CF_DATA_SEG_DESCR_ENABLE; |
668 | return 0; | 654 | return 0; |
669 | } | 655 | } |
@@ -702,7 +688,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt, | |||
702 | uint16_t tot_dsds, struct req_que *req) | 688 | uint16_t tot_dsds, struct req_que *req) |
703 | { | 689 | { |
704 | uint16_t avail_dsds; | 690 | uint16_t avail_dsds; |
705 | uint32_t *cur_dsd; | 691 | struct dsd64 *cur_dsd; |
706 | scsi_qla_host_t *vha; | 692 | scsi_qla_host_t *vha; |
707 | struct scsi_cmnd *cmd; | 693 | struct scsi_cmnd *cmd; |
708 | struct scatterlist *sg; | 694 | struct scatterlist *sg; |
@@ -711,7 +697,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt, | |||
711 | cmd = GET_CMD_SP(sp); | 697 | cmd = GET_CMD_SP(sp); |
712 | 698 | ||
713 | /* Update entry type to indicate Command Type 3 IOCB */ | 699 | /* Update entry type to indicate Command Type 3 IOCB */ |
714 | *((uint32_t *)(&cmd_pkt->entry_type)) = cpu_to_le32(COMMAND_TYPE_7); | 700 | put_unaligned_le32(COMMAND_TYPE_7, &cmd_pkt->entry_type); |
715 | 701 | ||
716 | /* No data transfer */ | 702 | /* No data transfer */ |
717 | if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { | 703 | if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { |
@@ -734,12 +720,11 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt, | |||
734 | 720 | ||
735 | /* One DSD is available in the Command Type 3 IOCB */ | 721 | /* One DSD is available in the Command Type 3 IOCB */ |
736 | avail_dsds = 1; | 722 | avail_dsds = 1; |
737 | cur_dsd = (uint32_t *)&cmd_pkt->dseg_0_address; | 723 | cur_dsd = &cmd_pkt->dsd; |
738 | 724 | ||
739 | /* Load data segments */ | 725 | /* Load data segments */ |
740 | 726 | ||
741 | scsi_for_each_sg(cmd, sg, tot_dsds, i) { | 727 | scsi_for_each_sg(cmd, sg, tot_dsds, i) { |
742 | dma_addr_t sle_dma; | ||
743 | cont_a64_entry_t *cont_pkt; | 728 | cont_a64_entry_t *cont_pkt; |
744 | 729 | ||
745 | /* Allocate additional continuation packets? */ | 730 | /* Allocate additional continuation packets? */ |
@@ -749,14 +734,11 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt, | |||
749 | * Type 1 IOCB. | 734 | * Type 1 IOCB. |
750 | */ | 735 | */ |
751 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, req); | 736 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, req); |
752 | cur_dsd = (uint32_t *)cont_pkt->dseg_0_address; | 737 | cur_dsd = cont_pkt->dsd; |
753 | avail_dsds = 5; | 738 | avail_dsds = ARRAY_SIZE(cont_pkt->dsd); |
754 | } | 739 | } |
755 | 740 | ||
756 | sle_dma = sg_dma_address(sg); | 741 | append_dsd64(&cur_dsd, sg); |
757 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
758 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
759 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
760 | avail_dsds--; | 742 | avail_dsds--; |
761 | } | 743 | } |
762 | } | 744 | } |
@@ -892,14 +874,14 @@ qla24xx_get_one_block_sg(uint32_t blk_sz, struct qla2_sgx *sgx, | |||
892 | 874 | ||
893 | int | 875 | int |
894 | qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, | 876 | qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, |
895 | uint32_t *dsd, uint16_t tot_dsds, struct qla_tc_param *tc) | 877 | struct dsd64 *dsd, uint16_t tot_dsds, struct qla_tc_param *tc) |
896 | { | 878 | { |
897 | void *next_dsd; | 879 | void *next_dsd; |
898 | uint8_t avail_dsds = 0; | 880 | uint8_t avail_dsds = 0; |
899 | uint32_t dsd_list_len; | 881 | uint32_t dsd_list_len; |
900 | struct dsd_dma *dsd_ptr; | 882 | struct dsd_dma *dsd_ptr; |
901 | struct scatterlist *sg_prot; | 883 | struct scatterlist *sg_prot; |
902 | uint32_t *cur_dsd = dsd; | 884 | struct dsd64 *cur_dsd = dsd; |
903 | uint16_t used_dsds = tot_dsds; | 885 | uint16_t used_dsds = tot_dsds; |
904 | uint32_t prot_int; /* protection interval */ | 886 | uint32_t prot_int; /* protection interval */ |
905 | uint32_t partial; | 887 | uint32_t partial; |
@@ -973,14 +955,14 @@ alloc_and_fill: | |||
973 | 955 | ||
974 | 956 | ||
975 | /* add new list to cmd iocb or last list */ | 957 | /* add new list to cmd iocb or last list */ |
976 | *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); | 958 | put_unaligned_le64(dsd_ptr->dsd_list_dma, |
977 | *cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); | 959 | &cur_dsd->address); |
978 | *cur_dsd++ = dsd_list_len; | 960 | cur_dsd->length = cpu_to_le32(dsd_list_len); |
979 | cur_dsd = (uint32_t *)next_dsd; | 961 | cur_dsd = next_dsd; |
980 | } | 962 | } |
981 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | 963 | put_unaligned_le64(sle_dma, &cur_dsd->address); |
982 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | 964 | cur_dsd->length = cpu_to_le32(sle_dma_len); |
983 | *cur_dsd++ = cpu_to_le32(sle_dma_len); | 965 | cur_dsd++; |
984 | avail_dsds--; | 966 | avail_dsds--; |
985 | 967 | ||
986 | if (partial == 0) { | 968 | if (partial == 0) { |
@@ -999,22 +981,22 @@ alloc_and_fill: | |||
999 | } | 981 | } |
1000 | } | 982 | } |
1001 | /* Null termination */ | 983 | /* Null termination */ |
1002 | *cur_dsd++ = 0; | 984 | cur_dsd->address = 0; |
1003 | *cur_dsd++ = 0; | 985 | cur_dsd->length = 0; |
1004 | *cur_dsd++ = 0; | 986 | cur_dsd++; |
1005 | return 0; | 987 | return 0; |
1006 | } | 988 | } |
1007 | 989 | ||
1008 | int | 990 | int |
1009 | qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, | 991 | qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, |
1010 | uint16_t tot_dsds, struct qla_tc_param *tc) | 992 | struct dsd64 *dsd, uint16_t tot_dsds, struct qla_tc_param *tc) |
1011 | { | 993 | { |
1012 | void *next_dsd; | 994 | void *next_dsd; |
1013 | uint8_t avail_dsds = 0; | 995 | uint8_t avail_dsds = 0; |
1014 | uint32_t dsd_list_len; | 996 | uint32_t dsd_list_len; |
1015 | struct dsd_dma *dsd_ptr; | 997 | struct dsd_dma *dsd_ptr; |
1016 | struct scatterlist *sg, *sgl; | 998 | struct scatterlist *sg, *sgl; |
1017 | uint32_t *cur_dsd = dsd; | 999 | struct dsd64 *cur_dsd = dsd; |
1018 | int i; | 1000 | int i; |
1019 | uint16_t used_dsds = tot_dsds; | 1001 | uint16_t used_dsds = tot_dsds; |
1020 | struct scsi_cmnd *cmd; | 1002 | struct scsi_cmnd *cmd; |
@@ -1031,8 +1013,6 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, | |||
1031 | 1013 | ||
1032 | 1014 | ||
1033 | for_each_sg(sgl, sg, tot_dsds, i) { | 1015 | for_each_sg(sgl, sg, tot_dsds, i) { |
1034 | dma_addr_t sle_dma; | ||
1035 | |||
1036 | /* Allocate additional continuation packets? */ | 1016 | /* Allocate additional continuation packets? */ |
1037 | if (avail_dsds == 0) { | 1017 | if (avail_dsds == 0) { |
1038 | avail_dsds = (used_dsds > QLA_DSDS_PER_IOCB) ? | 1018 | avail_dsds = (used_dsds > QLA_DSDS_PER_IOCB) ? |
@@ -1072,29 +1052,25 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, | |||
1072 | } | 1052 | } |
1073 | 1053 | ||
1074 | /* add new list to cmd iocb or last list */ | 1054 | /* add new list to cmd iocb or last list */ |
1075 | *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); | 1055 | put_unaligned_le64(dsd_ptr->dsd_list_dma, |
1076 | *cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); | 1056 | &cur_dsd->address); |
1077 | *cur_dsd++ = dsd_list_len; | 1057 | cur_dsd->length = cpu_to_le32(dsd_list_len); |
1078 | cur_dsd = (uint32_t *)next_dsd; | 1058 | cur_dsd = next_dsd; |
1079 | } | 1059 | } |
1080 | sle_dma = sg_dma_address(sg); | 1060 | append_dsd64(&cur_dsd, sg); |
1081 | |||
1082 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
1083 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
1084 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
1085 | avail_dsds--; | 1061 | avail_dsds--; |
1086 | 1062 | ||
1087 | } | 1063 | } |
1088 | /* Null termination */ | 1064 | /* Null termination */ |
1089 | *cur_dsd++ = 0; | 1065 | cur_dsd->address = 0; |
1090 | *cur_dsd++ = 0; | 1066 | cur_dsd->length = 0; |
1091 | *cur_dsd++ = 0; | 1067 | cur_dsd++; |
1092 | return 0; | 1068 | return 0; |
1093 | } | 1069 | } |
1094 | 1070 | ||
1095 | int | 1071 | int |
1096 | qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, | 1072 | qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, |
1097 | uint32_t *cur_dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc) | 1073 | struct dsd64 *cur_dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc) |
1098 | { | 1074 | { |
1099 | struct dsd_dma *dsd_ptr = NULL, *dif_dsd, *nxt_dsd; | 1075 | struct dsd_dma *dsd_ptr = NULL, *dif_dsd, *nxt_dsd; |
1100 | struct scatterlist *sg, *sgl; | 1076 | struct scatterlist *sg, *sgl; |
@@ -1109,6 +1085,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, | |||
1109 | 1085 | ||
1110 | if (sp) { | 1086 | if (sp) { |
1111 | struct scsi_cmnd *cmd = GET_CMD_SP(sp); | 1087 | struct scsi_cmnd *cmd = GET_CMD_SP(sp); |
1088 | |||
1112 | sgl = scsi_prot_sglist(cmd); | 1089 | sgl = scsi_prot_sglist(cmd); |
1113 | vha = sp->vha; | 1090 | vha = sp->vha; |
1114 | difctx = sp->u.scmd.ctx; | 1091 | difctx = sp->u.scmd.ctx; |
@@ -1314,16 +1291,15 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, | |||
1314 | } | 1291 | } |
1315 | 1292 | ||
1316 | /* add new list to cmd iocb or last list */ | 1293 | /* add new list to cmd iocb or last list */ |
1317 | *cur_dsd++ = | 1294 | put_unaligned_le64(dsd_ptr->dsd_list_dma, |
1318 | cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); | 1295 | &cur_dsd->address); |
1319 | *cur_dsd++ = | 1296 | cur_dsd->length = cpu_to_le32(dsd_list_len); |
1320 | cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); | ||
1321 | *cur_dsd++ = dsd_list_len; | ||
1322 | cur_dsd = dsd_ptr->dsd_addr; | 1297 | cur_dsd = dsd_ptr->dsd_addr; |
1323 | } | 1298 | } |
1324 | *cur_dsd++ = cpu_to_le32(LSD(dif_dsd->dsd_list_dma)); | 1299 | put_unaligned_le64(dif_dsd->dsd_list_dma, |
1325 | *cur_dsd++ = cpu_to_le32(MSD(dif_dsd->dsd_list_dma)); | 1300 | &cur_dsd->address); |
1326 | *cur_dsd++ = cpu_to_le32(sglen); | 1301 | cur_dsd->length = cpu_to_le32(sglen); |
1302 | cur_dsd++; | ||
1327 | avail_dsds--; | 1303 | avail_dsds--; |
1328 | difctx->dif_bundl_len -= sglen; | 1304 | difctx->dif_bundl_len -= sglen; |
1329 | track_difbundl_buf--; | 1305 | track_difbundl_buf--; |
@@ -1334,8 +1310,6 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, | |||
1334 | difctx->no_ldif_dsd, difctx->no_dif_bundl); | 1310 | difctx->no_ldif_dsd, difctx->no_dif_bundl); |
1335 | } else { | 1311 | } else { |
1336 | for_each_sg(sgl, sg, tot_dsds, i) { | 1312 | for_each_sg(sgl, sg, tot_dsds, i) { |
1337 | dma_addr_t sle_dma; | ||
1338 | |||
1339 | /* Allocate additional continuation packets? */ | 1313 | /* Allocate additional continuation packets? */ |
1340 | if (avail_dsds == 0) { | 1314 | if (avail_dsds == 0) { |
1341 | avail_dsds = (used_dsds > QLA_DSDS_PER_IOCB) ? | 1315 | avail_dsds = (used_dsds > QLA_DSDS_PER_IOCB) ? |
@@ -1375,24 +1349,19 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, | |||
1375 | } | 1349 | } |
1376 | 1350 | ||
1377 | /* add new list to cmd iocb or last list */ | 1351 | /* add new list to cmd iocb or last list */ |
1378 | *cur_dsd++ = | 1352 | put_unaligned_le64(dsd_ptr->dsd_list_dma, |
1379 | cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); | 1353 | &cur_dsd->address); |
1380 | *cur_dsd++ = | 1354 | cur_dsd->length = cpu_to_le32(dsd_list_len); |
1381 | cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); | ||
1382 | *cur_dsd++ = dsd_list_len; | ||
1383 | cur_dsd = dsd_ptr->dsd_addr; | 1355 | cur_dsd = dsd_ptr->dsd_addr; |
1384 | } | 1356 | } |
1385 | sle_dma = sg_dma_address(sg); | 1357 | append_dsd64(&cur_dsd, sg); |
1386 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
1387 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
1388 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
1389 | avail_dsds--; | 1358 | avail_dsds--; |
1390 | } | 1359 | } |
1391 | } | 1360 | } |
1392 | /* Null termination */ | 1361 | /* Null termination */ |
1393 | *cur_dsd++ = 0; | 1362 | cur_dsd->address = 0; |
1394 | *cur_dsd++ = 0; | 1363 | cur_dsd->length = 0; |
1395 | *cur_dsd++ = 0; | 1364 | cur_dsd++; |
1396 | return 0; | 1365 | return 0; |
1397 | } | 1366 | } |
1398 | /** | 1367 | /** |
@@ -1405,11 +1374,12 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, | |||
1405 | * @tot_prot_dsds: Total number of segments with protection information | 1374 | * @tot_prot_dsds: Total number of segments with protection information |
1406 | * @fw_prot_opts: Protection options to be passed to firmware | 1375 | * @fw_prot_opts: Protection options to be passed to firmware |
1407 | */ | 1376 | */ |
1408 | inline int | 1377 | static inline int |
1409 | qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | 1378 | qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, |
1410 | uint16_t tot_dsds, uint16_t tot_prot_dsds, uint16_t fw_prot_opts) | 1379 | uint16_t tot_dsds, uint16_t tot_prot_dsds, uint16_t fw_prot_opts) |
1411 | { | 1380 | { |
1412 | uint32_t *cur_dsd, *fcp_dl; | 1381 | struct dsd64 *cur_dsd; |
1382 | uint32_t *fcp_dl; | ||
1413 | scsi_qla_host_t *vha; | 1383 | scsi_qla_host_t *vha; |
1414 | struct scsi_cmnd *cmd; | 1384 | struct scsi_cmnd *cmd; |
1415 | uint32_t total_bytes = 0; | 1385 | uint32_t total_bytes = 0; |
@@ -1427,7 +1397,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1427 | cmd = GET_CMD_SP(sp); | 1397 | cmd = GET_CMD_SP(sp); |
1428 | 1398 | ||
1429 | /* Update entry type to indicate Command Type CRC_2 IOCB */ | 1399 | /* Update entry type to indicate Command Type CRC_2 IOCB */ |
1430 | *((uint32_t *)(&cmd_pkt->entry_type)) = cpu_to_le32(COMMAND_TYPE_CRC_2); | 1400 | put_unaligned_le32(COMMAND_TYPE_CRC_2, &cmd_pkt->entry_type); |
1431 | 1401 | ||
1432 | vha = sp->vha; | 1402 | vha = sp->vha; |
1433 | ha = vha->hw; | 1403 | ha = vha->hw; |
@@ -1475,8 +1445,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1475 | qla24xx_set_t10dif_tags(sp, (struct fw_dif_context *) | 1445 | qla24xx_set_t10dif_tags(sp, (struct fw_dif_context *) |
1476 | &crc_ctx_pkt->ref_tag, tot_prot_dsds); | 1446 | &crc_ctx_pkt->ref_tag, tot_prot_dsds); |
1477 | 1447 | ||
1478 | cmd_pkt->crc_context_address[0] = cpu_to_le32(LSD(crc_ctx_dma)); | 1448 | put_unaligned_le64(crc_ctx_dma, &cmd_pkt->crc_context_address); |
1479 | cmd_pkt->crc_context_address[1] = cpu_to_le32(MSD(crc_ctx_dma)); | ||
1480 | cmd_pkt->crc_context_len = CRC_CONTEXT_LEN_FW; | 1449 | cmd_pkt->crc_context_len = CRC_CONTEXT_LEN_FW; |
1481 | 1450 | ||
1482 | /* Determine SCSI command length -- align to 4 byte boundary */ | 1451 | /* Determine SCSI command length -- align to 4 byte boundary */ |
@@ -1503,10 +1472,8 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1503 | int_to_scsilun(cmd->device->lun, &fcp_cmnd->lun); | 1472 | int_to_scsilun(cmd->device->lun, &fcp_cmnd->lun); |
1504 | memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); | 1473 | memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); |
1505 | cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); | 1474 | cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); |
1506 | cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32( | 1475 | put_unaligned_le64(crc_ctx_dma + CRC_CONTEXT_FCPCMND_OFF, |
1507 | LSD(crc_ctx_dma + CRC_CONTEXT_FCPCMND_OFF)); | 1476 | &cmd_pkt->fcp_cmnd_dseg_address); |
1508 | cmd_pkt->fcp_cmnd_dseg_address[1] = cpu_to_le32( | ||
1509 | MSD(crc_ctx_dma + CRC_CONTEXT_FCPCMND_OFF)); | ||
1510 | fcp_cmnd->task_management = 0; | 1477 | fcp_cmnd->task_management = 0; |
1511 | fcp_cmnd->task_attribute = TSK_SIMPLE; | 1478 | fcp_cmnd->task_attribute = TSK_SIMPLE; |
1512 | 1479 | ||
@@ -1520,18 +1487,18 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1520 | switch (scsi_get_prot_op(GET_CMD_SP(sp))) { | 1487 | switch (scsi_get_prot_op(GET_CMD_SP(sp))) { |
1521 | case SCSI_PROT_READ_INSERT: | 1488 | case SCSI_PROT_READ_INSERT: |
1522 | case SCSI_PROT_WRITE_STRIP: | 1489 | case SCSI_PROT_WRITE_STRIP: |
1523 | total_bytes = data_bytes; | 1490 | total_bytes = data_bytes; |
1524 | data_bytes += dif_bytes; | 1491 | data_bytes += dif_bytes; |
1525 | break; | 1492 | break; |
1526 | 1493 | ||
1527 | case SCSI_PROT_READ_STRIP: | 1494 | case SCSI_PROT_READ_STRIP: |
1528 | case SCSI_PROT_WRITE_INSERT: | 1495 | case SCSI_PROT_WRITE_INSERT: |
1529 | case SCSI_PROT_READ_PASS: | 1496 | case SCSI_PROT_READ_PASS: |
1530 | case SCSI_PROT_WRITE_PASS: | 1497 | case SCSI_PROT_WRITE_PASS: |
1531 | total_bytes = data_bytes + dif_bytes; | 1498 | total_bytes = data_bytes + dif_bytes; |
1532 | break; | 1499 | break; |
1533 | default: | 1500 | default: |
1534 | BUG(); | 1501 | BUG(); |
1535 | } | 1502 | } |
1536 | 1503 | ||
1537 | if (!qla2x00_hba_err_chk_enabled(sp)) | 1504 | if (!qla2x00_hba_err_chk_enabled(sp)) |
@@ -1548,7 +1515,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1548 | } | 1515 | } |
1549 | 1516 | ||
1550 | if (!bundling) { | 1517 | if (!bundling) { |
1551 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.nobundling.data_address; | 1518 | cur_dsd = &crc_ctx_pkt->u.nobundling.data_dsd; |
1552 | } else { | 1519 | } else { |
1553 | /* | 1520 | /* |
1554 | * Configure Bundling if we need to fetch interlaving | 1521 | * Configure Bundling if we need to fetch interlaving |
@@ -1558,7 +1525,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1558 | crc_ctx_pkt->u.bundling.dif_byte_count = cpu_to_le32(dif_bytes); | 1525 | crc_ctx_pkt->u.bundling.dif_byte_count = cpu_to_le32(dif_bytes); |
1559 | crc_ctx_pkt->u.bundling.dseg_count = cpu_to_le16(tot_dsds - | 1526 | crc_ctx_pkt->u.bundling.dseg_count = cpu_to_le16(tot_dsds - |
1560 | tot_prot_dsds); | 1527 | tot_prot_dsds); |
1561 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.data_address; | 1528 | cur_dsd = &crc_ctx_pkt->u.bundling.data_dsd; |
1562 | } | 1529 | } |
1563 | 1530 | ||
1564 | /* Finish the common fields of CRC pkt */ | 1531 | /* Finish the common fields of CRC pkt */ |
@@ -1591,7 +1558,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1591 | if (bundling && tot_prot_dsds) { | 1558 | if (bundling && tot_prot_dsds) { |
1592 | /* Walks dif segments */ | 1559 | /* Walks dif segments */ |
1593 | cmd_pkt->control_flags |= cpu_to_le16(CF_DIF_SEG_DESCR_ENABLE); | 1560 | cmd_pkt->control_flags |= cpu_to_le16(CF_DIF_SEG_DESCR_ENABLE); |
1594 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address; | 1561 | cur_dsd = &crc_ctx_pkt->u.bundling.dif_dsd; |
1595 | if (qla24xx_walk_and_build_prot_sglist(ha, sp, cur_dsd, | 1562 | if (qla24xx_walk_and_build_prot_sglist(ha, sp, cur_dsd, |
1596 | tot_prot_dsds, NULL)) | 1563 | tot_prot_dsds, NULL)) |
1597 | goto crc_queuing_error; | 1564 | goto crc_queuing_error; |
@@ -2325,7 +2292,8 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp) | |||
2325 | if (req->cnt < req_cnt + 2) { | 2292 | if (req->cnt < req_cnt + 2) { |
2326 | if (qpair->use_shadow_reg) | 2293 | if (qpair->use_shadow_reg) |
2327 | cnt = *req->out_ptr; | 2294 | cnt = *req->out_ptr; |
2328 | else if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 2295 | else if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
2296 | IS_QLA28XX(ha)) | ||
2329 | cnt = RD_REG_DWORD(®->isp25mq.req_q_out); | 2297 | cnt = RD_REG_DWORD(®->isp25mq.req_q_out); |
2330 | else if (IS_P3P_TYPE(ha)) | 2298 | else if (IS_P3P_TYPE(ha)) |
2331 | cnt = RD_REG_DWORD(®->isp82.req_q_out); | 2299 | cnt = RD_REG_DWORD(®->isp82.req_q_out); |
@@ -2494,7 +2462,7 @@ qla2x00_logout_iocb(srb_t *sp, struct mbx_entry *mbx) | |||
2494 | SET_TARGET_ID(ha, mbx->loop_id, sp->fcport->loop_id); | 2462 | SET_TARGET_ID(ha, mbx->loop_id, sp->fcport->loop_id); |
2495 | mbx->mb0 = cpu_to_le16(MBC_LOGOUT_FABRIC_PORT); | 2463 | mbx->mb0 = cpu_to_le16(MBC_LOGOUT_FABRIC_PORT); |
2496 | mbx->mb1 = HAS_EXTENDED_IDS(ha) ? | 2464 | mbx->mb1 = HAS_EXTENDED_IDS(ha) ? |
2497 | cpu_to_le16(sp->fcport->loop_id): | 2465 | cpu_to_le16(sp->fcport->loop_id) : |
2498 | cpu_to_le16(sp->fcport->loop_id << 8); | 2466 | cpu_to_le16(sp->fcport->loop_id << 8); |
2499 | mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain); | 2467 | mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain); |
2500 | mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 | | 2468 | mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 | |
@@ -2565,6 +2533,16 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk) | |||
2565 | } | 2533 | } |
2566 | } | 2534 | } |
2567 | 2535 | ||
2536 | void qla2x00_init_timer(srb_t *sp, unsigned long tmo) | ||
2537 | { | ||
2538 | timer_setup(&sp->u.iocb_cmd.timer, qla2x00_sp_timeout, 0); | ||
2539 | sp->u.iocb_cmd.timer.expires = jiffies + tmo * HZ; | ||
2540 | sp->free = qla2x00_sp_free; | ||
2541 | if (IS_QLAFX00(sp->vha->hw) && sp->type == SRB_FXIOCB_DCMD) | ||
2542 | init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp); | ||
2543 | add_timer(&sp->u.iocb_cmd.timer); | ||
2544 | } | ||
2545 | |||
2568 | static void | 2546 | static void |
2569 | qla2x00_els_dcmd_sp_free(void *data) | 2547 | qla2x00_els_dcmd_sp_free(void *data) |
2570 | { | 2548 | { |
@@ -2726,18 +2704,13 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) | |||
2726 | if (elsio->u.els_logo.els_cmd == ELS_DCMD_PLOGI) { | 2704 | if (elsio->u.els_logo.els_cmd == ELS_DCMD_PLOGI) { |
2727 | els_iocb->tx_byte_count = els_iocb->tx_len = | 2705 | els_iocb->tx_byte_count = els_iocb->tx_len = |
2728 | sizeof(struct els_plogi_payload); | 2706 | sizeof(struct els_plogi_payload); |
2729 | els_iocb->tx_address[0] = | 2707 | put_unaligned_le64(elsio->u.els_plogi.els_plogi_pyld_dma, |
2730 | cpu_to_le32(LSD(elsio->u.els_plogi.els_plogi_pyld_dma)); | 2708 | &els_iocb->tx_address); |
2731 | els_iocb->tx_address[1] = | ||
2732 | cpu_to_le32(MSD(elsio->u.els_plogi.els_plogi_pyld_dma)); | ||
2733 | |||
2734 | els_iocb->rx_dsd_count = 1; | 2709 | els_iocb->rx_dsd_count = 1; |
2735 | els_iocb->rx_byte_count = els_iocb->rx_len = | 2710 | els_iocb->rx_byte_count = els_iocb->rx_len = |
2736 | sizeof(struct els_plogi_payload); | 2711 | sizeof(struct els_plogi_payload); |
2737 | els_iocb->rx_address[0] = | 2712 | put_unaligned_le64(elsio->u.els_plogi.els_resp_pyld_dma, |
2738 | cpu_to_le32(LSD(elsio->u.els_plogi.els_resp_pyld_dma)); | 2713 | &els_iocb->rx_address); |
2739 | els_iocb->rx_address[1] = | ||
2740 | cpu_to_le32(MSD(elsio->u.els_plogi.els_resp_pyld_dma)); | ||
2741 | 2714 | ||
2742 | ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073, | 2715 | ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073, |
2743 | "PLOGI ELS IOCB:\n"); | 2716 | "PLOGI ELS IOCB:\n"); |
@@ -2745,15 +2718,12 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) | |||
2745 | (uint8_t *)els_iocb, 0x70); | 2718 | (uint8_t *)els_iocb, 0x70); |
2746 | } else { | 2719 | } else { |
2747 | els_iocb->tx_byte_count = sizeof(struct els_logo_payload); | 2720 | els_iocb->tx_byte_count = sizeof(struct els_logo_payload); |
2748 | els_iocb->tx_address[0] = | 2721 | put_unaligned_le64(elsio->u.els_logo.els_logo_pyld_dma, |
2749 | cpu_to_le32(LSD(elsio->u.els_logo.els_logo_pyld_dma)); | 2722 | &els_iocb->tx_address); |
2750 | els_iocb->tx_address[1] = | ||
2751 | cpu_to_le32(MSD(elsio->u.els_logo.els_logo_pyld_dma)); | ||
2752 | els_iocb->tx_len = cpu_to_le32(sizeof(struct els_logo_payload)); | 2723 | els_iocb->tx_len = cpu_to_le32(sizeof(struct els_logo_payload)); |
2753 | 2724 | ||
2754 | els_iocb->rx_byte_count = 0; | 2725 | els_iocb->rx_byte_count = 0; |
2755 | els_iocb->rx_address[0] = 0; | 2726 | els_iocb->rx_address = 0; |
2756 | els_iocb->rx_address[1] = 0; | ||
2757 | els_iocb->rx_len = 0; | 2727 | els_iocb->rx_len = 0; |
2758 | } | 2728 | } |
2759 | 2729 | ||
@@ -2976,17 +2946,13 @@ qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) | |||
2976 | els_iocb->tx_byte_count = | 2946 | els_iocb->tx_byte_count = |
2977 | cpu_to_le32(bsg_job->request_payload.payload_len); | 2947 | cpu_to_le32(bsg_job->request_payload.payload_len); |
2978 | 2948 | ||
2979 | els_iocb->tx_address[0] = cpu_to_le32(LSD(sg_dma_address | 2949 | put_unaligned_le64(sg_dma_address(bsg_job->request_payload.sg_list), |
2980 | (bsg_job->request_payload.sg_list))); | 2950 | &els_iocb->tx_address); |
2981 | els_iocb->tx_address[1] = cpu_to_le32(MSD(sg_dma_address | ||
2982 | (bsg_job->request_payload.sg_list))); | ||
2983 | els_iocb->tx_len = cpu_to_le32(sg_dma_len | 2951 | els_iocb->tx_len = cpu_to_le32(sg_dma_len |
2984 | (bsg_job->request_payload.sg_list)); | 2952 | (bsg_job->request_payload.sg_list)); |
2985 | 2953 | ||
2986 | els_iocb->rx_address[0] = cpu_to_le32(LSD(sg_dma_address | 2954 | put_unaligned_le64(sg_dma_address(bsg_job->reply_payload.sg_list), |
2987 | (bsg_job->reply_payload.sg_list))); | 2955 | &els_iocb->rx_address); |
2988 | els_iocb->rx_address[1] = cpu_to_le32(MSD(sg_dma_address | ||
2989 | (bsg_job->reply_payload.sg_list))); | ||
2990 | els_iocb->rx_len = cpu_to_le32(sg_dma_len | 2956 | els_iocb->rx_len = cpu_to_le32(sg_dma_len |
2991 | (bsg_job->reply_payload.sg_list)); | 2957 | (bsg_job->reply_payload.sg_list)); |
2992 | 2958 | ||
@@ -2997,14 +2963,13 @@ static void | |||
2997 | qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb) | 2963 | qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb) |
2998 | { | 2964 | { |
2999 | uint16_t avail_dsds; | 2965 | uint16_t avail_dsds; |
3000 | uint32_t *cur_dsd; | 2966 | struct dsd64 *cur_dsd; |
3001 | struct scatterlist *sg; | 2967 | struct scatterlist *sg; |
3002 | int index; | 2968 | int index; |
3003 | uint16_t tot_dsds; | 2969 | uint16_t tot_dsds; |
3004 | scsi_qla_host_t *vha = sp->vha; | 2970 | scsi_qla_host_t *vha = sp->vha; |
3005 | struct qla_hw_data *ha = vha->hw; | 2971 | struct qla_hw_data *ha = vha->hw; |
3006 | struct bsg_job *bsg_job = sp->u.bsg_job; | 2972 | struct bsg_job *bsg_job = sp->u.bsg_job; |
3007 | int loop_iterartion = 0; | ||
3008 | int entry_count = 1; | 2973 | int entry_count = 1; |
3009 | 2974 | ||
3010 | memset(ct_iocb, 0, sizeof(ms_iocb_entry_t)); | 2975 | memset(ct_iocb, 0, sizeof(ms_iocb_entry_t)); |
@@ -3024,25 +2989,20 @@ qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb) | |||
3024 | ct_iocb->rsp_bytecount = | 2989 | ct_iocb->rsp_bytecount = |
3025 | cpu_to_le32(bsg_job->reply_payload.payload_len); | 2990 | cpu_to_le32(bsg_job->reply_payload.payload_len); |
3026 | 2991 | ||
3027 | ct_iocb->dseg_req_address[0] = cpu_to_le32(LSD(sg_dma_address | 2992 | put_unaligned_le64(sg_dma_address(bsg_job->request_payload.sg_list), |
3028 | (bsg_job->request_payload.sg_list))); | 2993 | &ct_iocb->req_dsd.address); |
3029 | ct_iocb->dseg_req_address[1] = cpu_to_le32(MSD(sg_dma_address | 2994 | ct_iocb->req_dsd.length = ct_iocb->req_bytecount; |
3030 | (bsg_job->request_payload.sg_list))); | ||
3031 | ct_iocb->dseg_req_length = ct_iocb->req_bytecount; | ||
3032 | 2995 | ||
3033 | ct_iocb->dseg_rsp_address[0] = cpu_to_le32(LSD(sg_dma_address | 2996 | put_unaligned_le64(sg_dma_address(bsg_job->reply_payload.sg_list), |
3034 | (bsg_job->reply_payload.sg_list))); | 2997 | &ct_iocb->rsp_dsd.address); |
3035 | ct_iocb->dseg_rsp_address[1] = cpu_to_le32(MSD(sg_dma_address | 2998 | ct_iocb->rsp_dsd.length = ct_iocb->rsp_bytecount; |
3036 | (bsg_job->reply_payload.sg_list))); | ||
3037 | ct_iocb->dseg_rsp_length = ct_iocb->rsp_bytecount; | ||
3038 | 2999 | ||
3039 | avail_dsds = 1; | 3000 | avail_dsds = 1; |
3040 | cur_dsd = (uint32_t *)ct_iocb->dseg_rsp_address; | 3001 | cur_dsd = &ct_iocb->rsp_dsd; |
3041 | index = 0; | 3002 | index = 0; |
3042 | tot_dsds = bsg_job->reply_payload.sg_cnt; | 3003 | tot_dsds = bsg_job->reply_payload.sg_cnt; |
3043 | 3004 | ||
3044 | for_each_sg(bsg_job->reply_payload.sg_list, sg, tot_dsds, index) { | 3005 | for_each_sg(bsg_job->reply_payload.sg_list, sg, tot_dsds, index) { |
3045 | dma_addr_t sle_dma; | ||
3046 | cont_a64_entry_t *cont_pkt; | 3006 | cont_a64_entry_t *cont_pkt; |
3047 | 3007 | ||
3048 | /* Allocate additional continuation packets? */ | 3008 | /* Allocate additional continuation packets? */ |
@@ -3053,16 +3013,12 @@ qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb) | |||
3053 | */ | 3013 | */ |
3054 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, | 3014 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, |
3055 | vha->hw->req_q_map[0]); | 3015 | vha->hw->req_q_map[0]); |
3056 | cur_dsd = (uint32_t *) cont_pkt->dseg_0_address; | 3016 | cur_dsd = cont_pkt->dsd; |
3057 | avail_dsds = 5; | 3017 | avail_dsds = 5; |
3058 | entry_count++; | 3018 | entry_count++; |
3059 | } | 3019 | } |
3060 | 3020 | ||
3061 | sle_dma = sg_dma_address(sg); | 3021 | append_dsd64(&cur_dsd, sg); |
3062 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
3063 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
3064 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
3065 | loop_iterartion++; | ||
3066 | avail_dsds--; | 3022 | avail_dsds--; |
3067 | } | 3023 | } |
3068 | ct_iocb->entry_count = entry_count; | 3024 | ct_iocb->entry_count = entry_count; |
@@ -3074,7 +3030,7 @@ static void | |||
3074 | qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb) | 3030 | qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb) |
3075 | { | 3031 | { |
3076 | uint16_t avail_dsds; | 3032 | uint16_t avail_dsds; |
3077 | uint32_t *cur_dsd; | 3033 | struct dsd64 *cur_dsd; |
3078 | struct scatterlist *sg; | 3034 | struct scatterlist *sg; |
3079 | int index; | 3035 | int index; |
3080 | uint16_t cmd_dsds, rsp_dsds; | 3036 | uint16_t cmd_dsds, rsp_dsds; |
@@ -3103,12 +3059,10 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb) | |||
3103 | cpu_to_le32(bsg_job->request_payload.payload_len); | 3059 | cpu_to_le32(bsg_job->request_payload.payload_len); |
3104 | 3060 | ||
3105 | avail_dsds = 2; | 3061 | avail_dsds = 2; |
3106 | cur_dsd = (uint32_t *)ct_iocb->dseg_0_address; | 3062 | cur_dsd = ct_iocb->dsd; |
3107 | index = 0; | 3063 | index = 0; |
3108 | 3064 | ||
3109 | for_each_sg(bsg_job->request_payload.sg_list, sg, cmd_dsds, index) { | 3065 | for_each_sg(bsg_job->request_payload.sg_list, sg, cmd_dsds, index) { |
3110 | dma_addr_t sle_dma; | ||
3111 | |||
3112 | /* Allocate additional continuation packets? */ | 3066 | /* Allocate additional continuation packets? */ |
3113 | if (avail_dsds == 0) { | 3067 | if (avail_dsds == 0) { |
3114 | /* | 3068 | /* |
@@ -3117,23 +3071,18 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb) | |||
3117 | */ | 3071 | */ |
3118 | cont_pkt = qla2x00_prep_cont_type1_iocb( | 3072 | cont_pkt = qla2x00_prep_cont_type1_iocb( |
3119 | vha, ha->req_q_map[0]); | 3073 | vha, ha->req_q_map[0]); |
3120 | cur_dsd = (uint32_t *) cont_pkt->dseg_0_address; | 3074 | cur_dsd = cont_pkt->dsd; |
3121 | avail_dsds = 5; | 3075 | avail_dsds = 5; |
3122 | entry_count++; | 3076 | entry_count++; |
3123 | } | 3077 | } |
3124 | 3078 | ||
3125 | sle_dma = sg_dma_address(sg); | 3079 | append_dsd64(&cur_dsd, sg); |
3126 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
3127 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
3128 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
3129 | avail_dsds--; | 3080 | avail_dsds--; |
3130 | } | 3081 | } |
3131 | 3082 | ||
3132 | index = 0; | 3083 | index = 0; |
3133 | 3084 | ||
3134 | for_each_sg(bsg_job->reply_payload.sg_list, sg, rsp_dsds, index) { | 3085 | for_each_sg(bsg_job->reply_payload.sg_list, sg, rsp_dsds, index) { |
3135 | dma_addr_t sle_dma; | ||
3136 | |||
3137 | /* Allocate additional continuation packets? */ | 3086 | /* Allocate additional continuation packets? */ |
3138 | if (avail_dsds == 0) { | 3087 | if (avail_dsds == 0) { |
3139 | /* | 3088 | /* |
@@ -3142,15 +3091,12 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb) | |||
3142 | */ | 3091 | */ |
3143 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, | 3092 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, |
3144 | ha->req_q_map[0]); | 3093 | ha->req_q_map[0]); |
3145 | cur_dsd = (uint32_t *) cont_pkt->dseg_0_address; | 3094 | cur_dsd = cont_pkt->dsd; |
3146 | avail_dsds = 5; | 3095 | avail_dsds = 5; |
3147 | entry_count++; | 3096 | entry_count++; |
3148 | } | 3097 | } |
3149 | 3098 | ||
3150 | sle_dma = sg_dma_address(sg); | 3099 | append_dsd64(&cur_dsd, sg); |
3151 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
3152 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
3153 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
3154 | avail_dsds--; | 3100 | avail_dsds--; |
3155 | } | 3101 | } |
3156 | ct_iocb->entry_count = entry_count; | 3102 | ct_iocb->entry_count = entry_count; |
@@ -3371,10 +3317,8 @@ sufficient_dsds: | |||
3371 | *fcp_dl = htonl((uint32_t)scsi_bufflen(cmd)); | 3317 | *fcp_dl = htonl((uint32_t)scsi_bufflen(cmd)); |
3372 | 3318 | ||
3373 | cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(ctx->fcp_cmnd_len); | 3319 | cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(ctx->fcp_cmnd_len); |
3374 | cmd_pkt->fcp_cmnd_dseg_address[0] = | 3320 | put_unaligned_le64(ctx->fcp_cmnd_dma, |
3375 | cpu_to_le32(LSD(ctx->fcp_cmnd_dma)); | 3321 | &cmd_pkt->fcp_cmnd_dseg_address); |
3376 | cmd_pkt->fcp_cmnd_dseg_address[1] = | ||
3377 | cpu_to_le32(MSD(ctx->fcp_cmnd_dma)); | ||
3378 | 3322 | ||
3379 | sp->flags |= SRB_FCP_CMND_DMA_VALID; | 3323 | sp->flags |= SRB_FCP_CMND_DMA_VALID; |
3380 | cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd)); | 3324 | cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd)); |
@@ -3386,6 +3330,7 @@ sufficient_dsds: | |||
3386 | cmd_pkt->entry_status = (uint8_t) rsp->id; | 3330 | cmd_pkt->entry_status = (uint8_t) rsp->id; |
3387 | } else { | 3331 | } else { |
3388 | struct cmd_type_7 *cmd_pkt; | 3332 | struct cmd_type_7 *cmd_pkt; |
3333 | |||
3389 | req_cnt = qla24xx_calc_iocbs(vha, tot_dsds); | 3334 | req_cnt = qla24xx_calc_iocbs(vha, tot_dsds); |
3390 | if (req->cnt < (req_cnt + 2)) { | 3335 | if (req->cnt < (req_cnt + 2)) { |
3391 | cnt = (uint16_t)RD_REG_DWORD_RELAXED( | 3336 | cnt = (uint16_t)RD_REG_DWORD_RELAXED( |
@@ -3590,15 +3535,13 @@ qla_nvme_ls(srb_t *sp, struct pt_ls4_request *cmd_pkt) | |||
3590 | 3535 | ||
3591 | cmd_pkt->tx_dseg_count = 1; | 3536 | cmd_pkt->tx_dseg_count = 1; |
3592 | cmd_pkt->tx_byte_count = nvme->u.nvme.cmd_len; | 3537 | cmd_pkt->tx_byte_count = nvme->u.nvme.cmd_len; |
3593 | cmd_pkt->dseg0_len = nvme->u.nvme.cmd_len; | 3538 | cmd_pkt->dsd[0].length = nvme->u.nvme.cmd_len; |
3594 | cmd_pkt->dseg0_address[0] = cpu_to_le32(LSD(nvme->u.nvme.cmd_dma)); | 3539 | put_unaligned_le64(nvme->u.nvme.cmd_dma, &cmd_pkt->dsd[0].address); |
3595 | cmd_pkt->dseg0_address[1] = cpu_to_le32(MSD(nvme->u.nvme.cmd_dma)); | ||
3596 | 3540 | ||
3597 | cmd_pkt->rx_dseg_count = 1; | 3541 | cmd_pkt->rx_dseg_count = 1; |
3598 | cmd_pkt->rx_byte_count = nvme->u.nvme.rsp_len; | 3542 | cmd_pkt->rx_byte_count = nvme->u.nvme.rsp_len; |
3599 | cmd_pkt->dseg1_len = nvme->u.nvme.rsp_len; | 3543 | cmd_pkt->dsd[1].length = nvme->u.nvme.rsp_len; |
3600 | cmd_pkt->dseg1_address[0] = cpu_to_le32(LSD(nvme->u.nvme.rsp_dma)); | 3544 | put_unaligned_le64(nvme->u.nvme.rsp_dma, &cmd_pkt->dsd[1].address); |
3601 | cmd_pkt->dseg1_address[1] = cpu_to_le32(MSD(nvme->u.nvme.rsp_dma)); | ||
3602 | 3545 | ||
3603 | return rval; | 3546 | return rval; |
3604 | } | 3547 | } |
@@ -3737,7 +3680,7 @@ qla25xx_build_bidir_iocb(srb_t *sp, struct scsi_qla_host *vha, | |||
3737 | struct cmd_bidir *cmd_pkt, uint32_t tot_dsds) | 3680 | struct cmd_bidir *cmd_pkt, uint32_t tot_dsds) |
3738 | { | 3681 | { |
3739 | uint16_t avail_dsds; | 3682 | uint16_t avail_dsds; |
3740 | uint32_t *cur_dsd; | 3683 | struct dsd64 *cur_dsd; |
3741 | uint32_t req_data_len = 0; | 3684 | uint32_t req_data_len = 0; |
3742 | uint32_t rsp_data_len = 0; | 3685 | uint32_t rsp_data_len = 0; |
3743 | struct scatterlist *sg; | 3686 | struct scatterlist *sg; |
@@ -3746,8 +3689,7 @@ qla25xx_build_bidir_iocb(srb_t *sp, struct scsi_qla_host *vha, | |||
3746 | struct bsg_job *bsg_job = sp->u.bsg_job; | 3689 | struct bsg_job *bsg_job = sp->u.bsg_job; |
3747 | 3690 | ||
3748 | /*Update entry type to indicate bidir command */ | 3691 | /*Update entry type to indicate bidir command */ |
3749 | *((uint32_t *)(&cmd_pkt->entry_type)) = | 3692 | put_unaligned_le32(COMMAND_BIDIRECTIONAL, &cmd_pkt->entry_type); |
3750 | cpu_to_le32(COMMAND_BIDIRECTIONAL); | ||
3751 | 3693 | ||
3752 | /* Set the transfer direction, in this set both flags | 3694 | /* Set the transfer direction, in this set both flags |
3753 | * Also set the BD_WRAP_BACK flag, firmware will take care | 3695 | * Also set the BD_WRAP_BACK flag, firmware will take care |
@@ -3773,13 +3715,12 @@ qla25xx_build_bidir_iocb(srb_t *sp, struct scsi_qla_host *vha, | |||
3773 | * are bundled in continuation iocb | 3715 | * are bundled in continuation iocb |
3774 | */ | 3716 | */ |
3775 | avail_dsds = 1; | 3717 | avail_dsds = 1; |
3776 | cur_dsd = (uint32_t *)&cmd_pkt->fcp_data_dseg_address; | 3718 | cur_dsd = &cmd_pkt->fcp_dsd; |
3777 | 3719 | ||
3778 | index = 0; | 3720 | index = 0; |
3779 | 3721 | ||
3780 | for_each_sg(bsg_job->request_payload.sg_list, sg, | 3722 | for_each_sg(bsg_job->request_payload.sg_list, sg, |
3781 | bsg_job->request_payload.sg_cnt, index) { | 3723 | bsg_job->request_payload.sg_cnt, index) { |
3782 | dma_addr_t sle_dma; | ||
3783 | cont_a64_entry_t *cont_pkt; | 3724 | cont_a64_entry_t *cont_pkt; |
3784 | 3725 | ||
3785 | /* Allocate additional continuation packets */ | 3726 | /* Allocate additional continuation packets */ |
@@ -3788,14 +3729,11 @@ qla25xx_build_bidir_iocb(srb_t *sp, struct scsi_qla_host *vha, | |||
3788 | * 5 DSDS | 3729 | * 5 DSDS |
3789 | */ | 3730 | */ |
3790 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req); | 3731 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req); |
3791 | cur_dsd = (uint32_t *) cont_pkt->dseg_0_address; | 3732 | cur_dsd = cont_pkt->dsd; |
3792 | avail_dsds = 5; | 3733 | avail_dsds = 5; |
3793 | entry_count++; | 3734 | entry_count++; |
3794 | } | 3735 | } |
3795 | sle_dma = sg_dma_address(sg); | 3736 | append_dsd64(&cur_dsd, sg); |
3796 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
3797 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
3798 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
3799 | avail_dsds--; | 3737 | avail_dsds--; |
3800 | } | 3738 | } |
3801 | /* For read request DSD will always goes to continuation IOCB | 3739 | /* For read request DSD will always goes to continuation IOCB |
@@ -3805,7 +3743,6 @@ qla25xx_build_bidir_iocb(srb_t *sp, struct scsi_qla_host *vha, | |||
3805 | */ | 3743 | */ |
3806 | for_each_sg(bsg_job->reply_payload.sg_list, sg, | 3744 | for_each_sg(bsg_job->reply_payload.sg_list, sg, |
3807 | bsg_job->reply_payload.sg_cnt, index) { | 3745 | bsg_job->reply_payload.sg_cnt, index) { |
3808 | dma_addr_t sle_dma; | ||
3809 | cont_a64_entry_t *cont_pkt; | 3746 | cont_a64_entry_t *cont_pkt; |
3810 | 3747 | ||
3811 | /* Allocate additional continuation packets */ | 3748 | /* Allocate additional continuation packets */ |
@@ -3814,14 +3751,11 @@ qla25xx_build_bidir_iocb(srb_t *sp, struct scsi_qla_host *vha, | |||
3814 | * 5 DSDS | 3751 | * 5 DSDS |
3815 | */ | 3752 | */ |
3816 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req); | 3753 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req); |
3817 | cur_dsd = (uint32_t *) cont_pkt->dseg_0_address; | 3754 | cur_dsd = cont_pkt->dsd; |
3818 | avail_dsds = 5; | 3755 | avail_dsds = 5; |
3819 | entry_count++; | 3756 | entry_count++; |
3820 | } | 3757 | } |
3821 | sle_dma = sg_dma_address(sg); | 3758 | append_dsd64(&cur_dsd, sg); |
3822 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
3823 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
3824 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
3825 | avail_dsds--; | 3759 | avail_dsds--; |
3826 | } | 3760 | } |
3827 | /* This value should be same as number of IOCB required for this cmd */ | 3761 | /* This value should be same as number of IOCB required for this cmd */ |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 69bbea9239cc..78aec50abe0f 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -23,6 +23,14 @@ static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *); | |||
23 | static int qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *, | 23 | static int qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *, |
24 | sts_entry_t *); | 24 | sts_entry_t *); |
25 | 25 | ||
26 | const char *const port_state_str[] = { | ||
27 | "Unknown", | ||
28 | "UNCONFIGURED", | ||
29 | "DEAD", | ||
30 | "LOST", | ||
31 | "ONLINE" | ||
32 | }; | ||
33 | |||
26 | /** | 34 | /** |
27 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. | 35 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. |
28 | * @irq: interrupt number | 36 | * @irq: interrupt number |
@@ -41,7 +49,7 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
41 | int status; | 49 | int status; |
42 | unsigned long iter; | 50 | unsigned long iter; |
43 | uint16_t hccr; | 51 | uint16_t hccr; |
44 | uint16_t mb[4]; | 52 | uint16_t mb[8]; |
45 | struct rsp_que *rsp; | 53 | struct rsp_que *rsp; |
46 | unsigned long flags; | 54 | unsigned long flags; |
47 | 55 | ||
@@ -160,7 +168,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
160 | unsigned long iter; | 168 | unsigned long iter; |
161 | uint32_t stat; | 169 | uint32_t stat; |
162 | uint16_t hccr; | 170 | uint16_t hccr; |
163 | uint16_t mb[4]; | 171 | uint16_t mb[8]; |
164 | struct rsp_que *rsp; | 172 | struct rsp_que *rsp; |
165 | struct qla_hw_data *ha; | 173 | struct qla_hw_data *ha; |
166 | unsigned long flags; | 174 | unsigned long flags; |
@@ -366,7 +374,7 @@ qla2x00_get_link_speed_str(struct qla_hw_data *ha, uint16_t speed) | |||
366 | static const char *const link_speeds[] = { | 374 | static const char *const link_speeds[] = { |
367 | "1", "2", "?", "4", "8", "16", "32", "10" | 375 | "1", "2", "?", "4", "8", "16", "32", "10" |
368 | }; | 376 | }; |
369 | #define QLA_LAST_SPEED 7 | 377 | #define QLA_LAST_SPEED (ARRAY_SIZE(link_speeds) - 1) |
370 | 378 | ||
371 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 379 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) |
372 | return link_speeds[0]; | 380 | return link_speeds[0]; |
@@ -708,12 +716,15 @@ skip_rio: | |||
708 | break; | 716 | break; |
709 | 717 | ||
710 | case MBA_SYSTEM_ERR: /* System Error */ | 718 | case MBA_SYSTEM_ERR: /* System Error */ |
711 | mbx = (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) ? | 719 | mbx = (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
720 | IS_QLA28XX(ha)) ? | ||
712 | RD_REG_WORD(®24->mailbox7) : 0; | 721 | RD_REG_WORD(®24->mailbox7) : 0; |
713 | ql_log(ql_log_warn, vha, 0x5003, | 722 | ql_log(ql_log_warn, vha, 0x5003, |
714 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh " | 723 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh " |
715 | "mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx); | 724 | "mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx); |
716 | 725 | ha->fw_dump_mpi = | |
726 | (IS_QLA27XX(ha) || IS_QLA28XX(ha)) && | ||
727 | RD_REG_WORD(®24->mailbox7) & BIT_8; | ||
717 | ha->isp_ops->fw_dump(vha, 1); | 728 | ha->isp_ops->fw_dump(vha, 1); |
718 | ha->flags.fw_init_done = 0; | 729 | ha->flags.fw_init_done = 0; |
719 | QLA_FW_STOPPED(ha); | 730 | QLA_FW_STOPPED(ha); |
@@ -837,6 +848,7 @@ skip_rio: | |||
837 | if (ha->flags.fawwpn_enabled && | 848 | if (ha->flags.fawwpn_enabled && |
838 | (ha->current_topology == ISP_CFG_F)) { | 849 | (ha->current_topology == ISP_CFG_F)) { |
839 | void *wwpn = ha->init_cb->port_name; | 850 | void *wwpn = ha->init_cb->port_name; |
851 | |||
840 | memcpy(vha->port_name, wwpn, WWN_SIZE); | 852 | memcpy(vha->port_name, wwpn, WWN_SIZE); |
841 | fc_host_port_name(vha->host) = | 853 | fc_host_port_name(vha->host) = |
842 | wwn_to_u64(vha->port_name); | 854 | wwn_to_u64(vha->port_name); |
@@ -1372,7 +1384,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1372 | le16_to_cpu(mbx->status_flags)); | 1384 | le16_to_cpu(mbx->status_flags)); |
1373 | 1385 | ||
1374 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5029, | 1386 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5029, |
1375 | (uint8_t *)mbx, sizeof(*mbx)); | 1387 | mbx, sizeof(*mbx)); |
1376 | 1388 | ||
1377 | goto logio_done; | 1389 | goto logio_done; |
1378 | } | 1390 | } |
@@ -1516,7 +1528,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1516 | bsg_reply->reply_payload_rcv_len = 0; | 1528 | bsg_reply->reply_payload_rcv_len = 0; |
1517 | } | 1529 | } |
1518 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035, | 1530 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035, |
1519 | (uint8_t *)pkt, sizeof(*pkt)); | 1531 | pkt, sizeof(*pkt)); |
1520 | } else { | 1532 | } else { |
1521 | res = DID_OK << 16; | 1533 | res = DID_OK << 16; |
1522 | bsg_reply->reply_payload_rcv_len = | 1534 | bsg_reply->reply_payload_rcv_len = |
@@ -1591,8 +1603,8 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1591 | } | 1603 | } |
1592 | 1604 | ||
1593 | comp_status = fw_status[0] = le16_to_cpu(pkt->comp_status); | 1605 | comp_status = fw_status[0] = le16_to_cpu(pkt->comp_status); |
1594 | fw_status[1] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_1); | 1606 | fw_status[1] = le16_to_cpu(((struct els_sts_entry_24xx *)pkt)->error_subcode_1); |
1595 | fw_status[2] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_2); | 1607 | fw_status[2] = le16_to_cpu(((struct els_sts_entry_24xx *)pkt)->error_subcode_2); |
1596 | 1608 | ||
1597 | if (iocb_type == ELS_IOCB_TYPE) { | 1609 | if (iocb_type == ELS_IOCB_TYPE) { |
1598 | els = &sp->u.iocb_cmd; | 1610 | els = &sp->u.iocb_cmd; |
@@ -1613,7 +1625,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1613 | res = DID_ERROR << 16; | 1625 | res = DID_ERROR << 16; |
1614 | } | 1626 | } |
1615 | } | 1627 | } |
1616 | ql_log(ql_log_info, vha, 0x503f, | 1628 | ql_dbg(ql_dbg_user, vha, 0x503f, |
1617 | "ELS IOCB Done -%s error hdl=%x comp_status=0x%x error subcode 1=0x%x error subcode 2=0x%x total_byte=0x%x\n", | 1629 | "ELS IOCB Done -%s error hdl=%x comp_status=0x%x error subcode 1=0x%x error subcode 2=0x%x total_byte=0x%x\n", |
1618 | type, sp->handle, comp_status, fw_status[1], fw_status[2], | 1630 | type, sp->handle, comp_status, fw_status[1], fw_status[2], |
1619 | le16_to_cpu(((struct els_sts_entry_24xx *) | 1631 | le16_to_cpu(((struct els_sts_entry_24xx *) |
@@ -1656,7 +1668,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1656 | memcpy(bsg_job->reply + sizeof(struct fc_bsg_reply), | 1668 | memcpy(bsg_job->reply + sizeof(struct fc_bsg_reply), |
1657 | fw_status, sizeof(fw_status)); | 1669 | fw_status, sizeof(fw_status)); |
1658 | ql_dump_buffer(ql_dbg_user + ql_dbg_buffer, vha, 0x5056, | 1670 | ql_dump_buffer(ql_dbg_user + ql_dbg_buffer, vha, 0x5056, |
1659 | (uint8_t *)pkt, sizeof(*pkt)); | 1671 | pkt, sizeof(*pkt)); |
1660 | } | 1672 | } |
1661 | else { | 1673 | else { |
1662 | res = DID_OK << 16; | 1674 | res = DID_OK << 16; |
@@ -1700,7 +1712,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1700 | fcport->d_id.b.area, fcport->d_id.b.al_pa, | 1712 | fcport->d_id.b.area, fcport->d_id.b.al_pa, |
1701 | logio->entry_status); | 1713 | logio->entry_status); |
1702 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x504d, | 1714 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x504d, |
1703 | (uint8_t *)logio, sizeof(*logio)); | 1715 | logio, sizeof(*logio)); |
1704 | 1716 | ||
1705 | goto logio_done; | 1717 | goto logio_done; |
1706 | } | 1718 | } |
@@ -1846,8 +1858,8 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk) | |||
1846 | } | 1858 | } |
1847 | 1859 | ||
1848 | if (iocb->u.tmf.data != QLA_SUCCESS) | 1860 | if (iocb->u.tmf.data != QLA_SUCCESS) |
1849 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5055, | 1861 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, sp->vha, 0x5055, |
1850 | (uint8_t *)sts, sizeof(*sts)); | 1862 | sts, sizeof(*sts)); |
1851 | 1863 | ||
1852 | sp->done(sp, 0); | 1864 | sp->done(sp, 0); |
1853 | } | 1865 | } |
@@ -1969,6 +1981,52 @@ static void qla_ctrlvp_completed(scsi_qla_host_t *vha, struct req_que *req, | |||
1969 | sp->done(sp, rval); | 1981 | sp->done(sp, rval); |
1970 | } | 1982 | } |
1971 | 1983 | ||
1984 | /* Process a single response queue entry. */ | ||
1985 | static void qla2x00_process_response_entry(struct scsi_qla_host *vha, | ||
1986 | struct rsp_que *rsp, | ||
1987 | sts_entry_t *pkt) | ||
1988 | { | ||
1989 | sts21_entry_t *sts21_entry; | ||
1990 | sts22_entry_t *sts22_entry; | ||
1991 | uint16_t handle_cnt; | ||
1992 | uint16_t cnt; | ||
1993 | |||
1994 | switch (pkt->entry_type) { | ||
1995 | case STATUS_TYPE: | ||
1996 | qla2x00_status_entry(vha, rsp, pkt); | ||
1997 | break; | ||
1998 | case STATUS_TYPE_21: | ||
1999 | sts21_entry = (sts21_entry_t *)pkt; | ||
2000 | handle_cnt = sts21_entry->handle_count; | ||
2001 | for (cnt = 0; cnt < handle_cnt; cnt++) | ||
2002 | qla2x00_process_completed_request(vha, rsp->req, | ||
2003 | sts21_entry->handle[cnt]); | ||
2004 | break; | ||
2005 | case STATUS_TYPE_22: | ||
2006 | sts22_entry = (sts22_entry_t *)pkt; | ||
2007 | handle_cnt = sts22_entry->handle_count; | ||
2008 | for (cnt = 0; cnt < handle_cnt; cnt++) | ||
2009 | qla2x00_process_completed_request(vha, rsp->req, | ||
2010 | sts22_entry->handle[cnt]); | ||
2011 | break; | ||
2012 | case STATUS_CONT_TYPE: | ||
2013 | qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt); | ||
2014 | break; | ||
2015 | case MBX_IOCB_TYPE: | ||
2016 | qla2x00_mbx_iocb_entry(vha, rsp->req, (struct mbx_entry *)pkt); | ||
2017 | break; | ||
2018 | case CT_IOCB_TYPE: | ||
2019 | qla2x00_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE); | ||
2020 | break; | ||
2021 | default: | ||
2022 | /* Type Not Supported. */ | ||
2023 | ql_log(ql_log_warn, vha, 0x504a, | ||
2024 | "Received unknown response pkt type %x entry status=%x.\n", | ||
2025 | pkt->entry_type, pkt->entry_status); | ||
2026 | break; | ||
2027 | } | ||
2028 | } | ||
2029 | |||
1972 | /** | 2030 | /** |
1973 | * qla2x00_process_response_queue() - Process response queue entries. | 2031 | * qla2x00_process_response_queue() - Process response queue entries. |
1974 | * @rsp: response queue | 2032 | * @rsp: response queue |
@@ -1980,8 +2038,6 @@ qla2x00_process_response_queue(struct rsp_que *rsp) | |||
1980 | struct qla_hw_data *ha = rsp->hw; | 2038 | struct qla_hw_data *ha = rsp->hw; |
1981 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 2039 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
1982 | sts_entry_t *pkt; | 2040 | sts_entry_t *pkt; |
1983 | uint16_t handle_cnt; | ||
1984 | uint16_t cnt; | ||
1985 | 2041 | ||
1986 | vha = pci_get_drvdata(ha->pdev); | 2042 | vha = pci_get_drvdata(ha->pdev); |
1987 | 2043 | ||
@@ -2006,42 +2062,7 @@ qla2x00_process_response_queue(struct rsp_que *rsp) | |||
2006 | continue; | 2062 | continue; |
2007 | } | 2063 | } |
2008 | 2064 | ||
2009 | switch (pkt->entry_type) { | 2065 | qla2x00_process_response_entry(vha, rsp, pkt); |
2010 | case STATUS_TYPE: | ||
2011 | qla2x00_status_entry(vha, rsp, pkt); | ||
2012 | break; | ||
2013 | case STATUS_TYPE_21: | ||
2014 | handle_cnt = ((sts21_entry_t *)pkt)->handle_count; | ||
2015 | for (cnt = 0; cnt < handle_cnt; cnt++) { | ||
2016 | qla2x00_process_completed_request(vha, rsp->req, | ||
2017 | ((sts21_entry_t *)pkt)->handle[cnt]); | ||
2018 | } | ||
2019 | break; | ||
2020 | case STATUS_TYPE_22: | ||
2021 | handle_cnt = ((sts22_entry_t *)pkt)->handle_count; | ||
2022 | for (cnt = 0; cnt < handle_cnt; cnt++) { | ||
2023 | qla2x00_process_completed_request(vha, rsp->req, | ||
2024 | ((sts22_entry_t *)pkt)->handle[cnt]); | ||
2025 | } | ||
2026 | break; | ||
2027 | case STATUS_CONT_TYPE: | ||
2028 | qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt); | ||
2029 | break; | ||
2030 | case MBX_IOCB_TYPE: | ||
2031 | qla2x00_mbx_iocb_entry(vha, rsp->req, | ||
2032 | (struct mbx_entry *)pkt); | ||
2033 | break; | ||
2034 | case CT_IOCB_TYPE: | ||
2035 | qla2x00_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE); | ||
2036 | break; | ||
2037 | default: | ||
2038 | /* Type Not Supported. */ | ||
2039 | ql_log(ql_log_warn, vha, 0x504a, | ||
2040 | "Received unknown response pkt type %x " | ||
2041 | "entry status=%x.\n", | ||
2042 | pkt->entry_type, pkt->entry_status); | ||
2043 | break; | ||
2044 | } | ||
2045 | ((response_t *)pkt)->signature = RESPONSE_PROCESSED; | 2066 | ((response_t *)pkt)->signature = RESPONSE_PROCESSED; |
2046 | wmb(); | 2067 | wmb(); |
2047 | } | 2068 | } |
@@ -2238,6 +2259,7 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt, | |||
2238 | struct fc_bsg_reply *bsg_reply; | 2259 | struct fc_bsg_reply *bsg_reply; |
2239 | sts_entry_t *sts; | 2260 | sts_entry_t *sts; |
2240 | struct sts_entry_24xx *sts24; | 2261 | struct sts_entry_24xx *sts24; |
2262 | |||
2241 | sts = (sts_entry_t *) pkt; | 2263 | sts = (sts_entry_t *) pkt; |
2242 | sts24 = (struct sts_entry_24xx *) pkt; | 2264 | sts24 = (struct sts_entry_24xx *) pkt; |
2243 | 2265 | ||
@@ -3014,7 +3036,8 @@ process_err: | |||
3014 | qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE); | 3036 | qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE); |
3015 | break; | 3037 | break; |
3016 | case ABTS_RECV_24XX: | 3038 | case ABTS_RECV_24XX: |
3017 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 3039 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
3040 | IS_QLA28XX(ha)) { | ||
3018 | /* ensure that the ATIO queue is empty */ | 3041 | /* ensure that the ATIO queue is empty */ |
3019 | qlt_handle_abts_recv(vha, rsp, | 3042 | qlt_handle_abts_recv(vha, rsp, |
3020 | (response_t *)pkt); | 3043 | (response_t *)pkt); |
@@ -3072,6 +3095,7 @@ process_err: | |||
3072 | /* Adjust ring index */ | 3095 | /* Adjust ring index */ |
3073 | if (IS_P3P_TYPE(ha)) { | 3096 | if (IS_P3P_TYPE(ha)) { |
3074 | struct device_reg_82xx __iomem *reg = &ha->iobase->isp82; | 3097 | struct device_reg_82xx __iomem *reg = &ha->iobase->isp82; |
3098 | |||
3075 | WRT_REG_DWORD(®->rsp_q_out[0], rsp->ring_index); | 3099 | WRT_REG_DWORD(®->rsp_q_out[0], rsp->ring_index); |
3076 | } else { | 3100 | } else { |
3077 | WRT_REG_DWORD(rsp->rsp_q_out, rsp->ring_index); | 3101 | WRT_REG_DWORD(rsp->rsp_q_out, rsp->ring_index); |
@@ -3087,7 +3111,7 @@ qla2xxx_check_risc_status(scsi_qla_host_t *vha) | |||
3087 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 3111 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
3088 | 3112 | ||
3089 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && | 3113 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
3090 | !IS_QLA27XX(ha)) | 3114 | !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
3091 | return; | 3115 | return; |
3092 | 3116 | ||
3093 | rval = QLA_SUCCESS; | 3117 | rval = QLA_SUCCESS; |
@@ -3475,7 +3499,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) | |||
3475 | ql_log(ql_log_fatal, vha, 0x00c8, | 3499 | ql_log(ql_log_fatal, vha, 0x00c8, |
3476 | "Failed to allocate memory for ha->msix_entries.\n"); | 3500 | "Failed to allocate memory for ha->msix_entries.\n"); |
3477 | ret = -ENOMEM; | 3501 | ret = -ENOMEM; |
3478 | goto msix_out; | 3502 | goto free_irqs; |
3479 | } | 3503 | } |
3480 | ha->flags.msix_enabled = 1; | 3504 | ha->flags.msix_enabled = 1; |
3481 | 3505 | ||
@@ -3539,7 +3563,7 @@ msix_register_fail: | |||
3539 | } | 3563 | } |
3540 | 3564 | ||
3541 | /* Enable MSI-X vector for response queue update for queue 0 */ | 3565 | /* Enable MSI-X vector for response queue update for queue 0 */ |
3542 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 3566 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
3543 | if (ha->msixbase && ha->mqiobase && | 3567 | if (ha->msixbase && ha->mqiobase && |
3544 | (ha->max_rsp_queues > 1 || ha->max_req_queues > 1 || | 3568 | (ha->max_rsp_queues > 1 || ha->max_req_queues > 1 || |
3545 | ql2xmqsupport)) | 3569 | ql2xmqsupport)) |
@@ -3558,6 +3582,10 @@ msix_register_fail: | |||
3558 | 3582 | ||
3559 | msix_out: | 3583 | msix_out: |
3560 | return ret; | 3584 | return ret; |
3585 | |||
3586 | free_irqs: | ||
3587 | pci_free_irq_vectors(ha->pdev); | ||
3588 | goto msix_out; | ||
3561 | } | 3589 | } |
3562 | 3590 | ||
3563 | int | 3591 | int |
@@ -3570,7 +3598,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) | |||
3570 | /* If possible, enable MSI-X. */ | 3598 | /* If possible, enable MSI-X. */ |
3571 | if (ql2xenablemsix == 0 || (!IS_QLA2432(ha) && !IS_QLA2532(ha) && | 3599 | if (ql2xenablemsix == 0 || (!IS_QLA2432(ha) && !IS_QLA2532(ha) && |
3572 | !IS_QLA8432(ha) && !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha) && | 3600 | !IS_QLA8432(ha) && !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha) && |
3573 | !IS_QLAFX00(ha) && !IS_QLA27XX(ha))) | 3601 | !IS_QLAFX00(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))) |
3574 | goto skip_msi; | 3602 | goto skip_msi; |
3575 | 3603 | ||
3576 | if (ql2xenablemsix == 2) | 3604 | if (ql2xenablemsix == 2) |
@@ -3609,7 +3637,7 @@ skip_msix: | |||
3609 | 3637 | ||
3610 | if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) && | 3638 | if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) && |
3611 | !IS_QLA8001(ha) && !IS_P3P_TYPE(ha) && !IS_QLAFX00(ha) && | 3639 | !IS_QLA8001(ha) && !IS_P3P_TYPE(ha) && !IS_QLAFX00(ha) && |
3612 | !IS_QLA27XX(ha)) | 3640 | !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
3613 | goto skip_msi; | 3641 | goto skip_msi; |
3614 | 3642 | ||
3615 | ret = pci_alloc_irq_vectors(ha->pdev, 1, 1, PCI_IRQ_MSI); | 3643 | ret = pci_alloc_irq_vectors(ha->pdev, 1, 1, PCI_IRQ_MSI); |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 5400696e1f6b..133f5f6270ff 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -567,9 +567,9 @@ mbx_done: | |||
567 | mcp->mb[0]); | 567 | mcp->mb[0]); |
568 | } else if (rval) { | 568 | } else if (rval) { |
569 | if (ql2xextended_error_logging & (ql_dbg_disc|ql_dbg_mbx)) { | 569 | if (ql2xextended_error_logging & (ql_dbg_disc|ql_dbg_mbx)) { |
570 | pr_warn("%s [%s]-%04x:%ld: **** Failed", QL_MSGHDR, | 570 | pr_warn("%s [%s]-%04x:%ld: **** Failed=%x", QL_MSGHDR, |
571 | dev_name(&ha->pdev->dev), 0x1020+0x800, | 571 | dev_name(&ha->pdev->dev), 0x1020+0x800, |
572 | vha->host_no); | 572 | vha->host_no, rval); |
573 | mboxes = mcp->in_mb; | 573 | mboxes = mcp->in_mb; |
574 | cnt = 4; | 574 | cnt = 4; |
575 | for (i = 0; i < ha->mbx_count && cnt; i++, mboxes >>= 1) | 575 | for (i = 0; i < ha->mbx_count && cnt; i++, mboxes >>= 1) |
@@ -634,14 +634,15 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr, | |||
634 | mcp->out_mb |= MBX_4; | 634 | mcp->out_mb |= MBX_4; |
635 | } | 635 | } |
636 | 636 | ||
637 | mcp->in_mb = MBX_0; | 637 | mcp->in_mb = MBX_1|MBX_0; |
638 | mcp->tov = MBX_TOV_SECONDS; | 638 | mcp->tov = MBX_TOV_SECONDS; |
639 | mcp->flags = 0; | 639 | mcp->flags = 0; |
640 | rval = qla2x00_mailbox_command(vha, mcp); | 640 | rval = qla2x00_mailbox_command(vha, mcp); |
641 | 641 | ||
642 | if (rval != QLA_SUCCESS) { | 642 | if (rval != QLA_SUCCESS) { |
643 | ql_dbg(ql_dbg_mbx, vha, 0x1023, | 643 | ql_dbg(ql_dbg_mbx, vha, 0x1023, |
644 | "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); | 644 | "Failed=%x mb[0]=%x mb[1]=%x.\n", |
645 | rval, mcp->mb[0], mcp->mb[1]); | ||
645 | } else { | 646 | } else { |
646 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024, | 647 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024, |
647 | "Done %s.\n", __func__); | 648 | "Done %s.\n", __func__); |
@@ -656,7 +657,7 @@ static inline uint16_t qla25xx_set_sfp_lr_dist(struct qla_hw_data *ha) | |||
656 | { | 657 | { |
657 | uint16_t mb4 = BIT_0; | 658 | uint16_t mb4 = BIT_0; |
658 | 659 | ||
659 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 660 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
660 | mb4 |= ha->long_range_distance << LR_DIST_FW_POS; | 661 | mb4 |= ha->long_range_distance << LR_DIST_FW_POS; |
661 | 662 | ||
662 | return mb4; | 663 | return mb4; |
@@ -666,7 +667,7 @@ static inline uint16_t qla25xx_set_nvr_lr_dist(struct qla_hw_data *ha) | |||
666 | { | 667 | { |
667 | uint16_t mb4 = BIT_0; | 668 | uint16_t mb4 = BIT_0; |
668 | 669 | ||
669 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 670 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
670 | struct nvram_81xx *nv = ha->nvram; | 671 | struct nvram_81xx *nv = ha->nvram; |
671 | 672 | ||
672 | mb4 |= LR_DIST_FW_FIELD(nv->enhanced_features); | 673 | mb4 |= LR_DIST_FW_FIELD(nv->enhanced_features); |
@@ -711,7 +712,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) | |||
711 | mcp->mb[4] = 0; | 712 | mcp->mb[4] = 0; |
712 | ha->flags.using_lr_setting = 0; | 713 | ha->flags.using_lr_setting = 0; |
713 | if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || | 714 | if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || |
714 | IS_QLA27XX(ha)) { | 715 | IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
715 | if (ql2xautodetectsfp) { | 716 | if (ql2xautodetectsfp) { |
716 | if (ha->flags.detected_lr_sfp) { | 717 | if (ha->flags.detected_lr_sfp) { |
717 | mcp->mb[4] |= | 718 | mcp->mb[4] |= |
@@ -730,19 +731,20 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) | |||
730 | } | 731 | } |
731 | } | 732 | } |
732 | 733 | ||
733 | if (ql2xnvmeenable && IS_QLA27XX(ha)) | 734 | if (ql2xnvmeenable && (IS_QLA27XX(ha) || IS_QLA28XX(ha))) |
734 | mcp->mb[4] |= NVME_ENABLE_FLAG; | 735 | mcp->mb[4] |= NVME_ENABLE_FLAG; |
735 | 736 | ||
736 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 737 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
737 | struct nvram_81xx *nv = ha->nvram; | 738 | struct nvram_81xx *nv = ha->nvram; |
738 | /* set minimum speed if specified in nvram */ | 739 | /* set minimum speed if specified in nvram */ |
739 | if (nv->min_link_speed >= 2 && | 740 | if (nv->min_supported_speed >= 2 && |
740 | nv->min_link_speed <= 5) { | 741 | nv->min_supported_speed <= 5) { |
741 | mcp->mb[4] |= BIT_4; | 742 | mcp->mb[4] |= BIT_4; |
742 | mcp->mb[11] = nv->min_link_speed; | 743 | mcp->mb[11] |= nv->min_supported_speed & 0xF; |
743 | mcp->out_mb |= MBX_11; | 744 | mcp->out_mb |= MBX_11; |
744 | mcp->in_mb |= BIT_5; | 745 | mcp->in_mb |= BIT_5; |
745 | vha->min_link_speed_feat = nv->min_link_speed; | 746 | vha->min_supported_speed = |
747 | nv->min_supported_speed; | ||
746 | } | 748 | } |
747 | } | 749 | } |
748 | 750 | ||
@@ -770,34 +772,39 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) | |||
770 | if (rval != QLA_SUCCESS) { | 772 | if (rval != QLA_SUCCESS) { |
771 | ql_dbg(ql_dbg_mbx, vha, 0x1026, | 773 | ql_dbg(ql_dbg_mbx, vha, 0x1026, |
772 | "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); | 774 | "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); |
773 | } else { | 775 | return rval; |
774 | if (IS_FWI2_CAPABLE(ha)) { | 776 | } |
775 | ha->fw_ability_mask = mcp->mb[3] << 16 | mcp->mb[2]; | 777 | |
776 | ql_dbg(ql_dbg_mbx, vha, 0x119a, | 778 | if (!IS_FWI2_CAPABLE(ha)) |
777 | "fw_ability_mask=%x.\n", ha->fw_ability_mask); | 779 | goto done; |
778 | ql_dbg(ql_dbg_mbx, vha, 0x1027, | 780 | |
779 | "exchanges=%x.\n", mcp->mb[1]); | 781 | ha->fw_ability_mask = mcp->mb[3] << 16 | mcp->mb[2]; |
780 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 782 | ql_dbg(ql_dbg_mbx, vha, 0x119a, |
781 | ha->max_speed_sup = mcp->mb[2] & BIT_0; | 783 | "fw_ability_mask=%x.\n", ha->fw_ability_mask); |
782 | ql_dbg(ql_dbg_mbx, vha, 0x119b, | 784 | ql_dbg(ql_dbg_mbx, vha, 0x1027, "exchanges=%x.\n", mcp->mb[1]); |
783 | "Maximum speed supported=%s.\n", | 785 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
784 | ha->max_speed_sup ? "32Gps" : "16Gps"); | 786 | ha->max_supported_speed = mcp->mb[2] & (BIT_0|BIT_1); |
785 | if (vha->min_link_speed_feat) { | 787 | ql_dbg(ql_dbg_mbx, vha, 0x119b, "max_supported_speed=%s.\n", |
786 | ha->min_link_speed = mcp->mb[5]; | 788 | ha->max_supported_speed == 0 ? "16Gps" : |
787 | ql_dbg(ql_dbg_mbx, vha, 0x119c, | 789 | ha->max_supported_speed == 1 ? "32Gps" : |
788 | "Minimum speed set=%s.\n", | 790 | ha->max_supported_speed == 2 ? "64Gps" : "unknown"); |
789 | mcp->mb[5] == 5 ? "32Gps" : | 791 | if (vha->min_supported_speed) { |
790 | mcp->mb[5] == 4 ? "16Gps" : | 792 | ha->min_supported_speed = mcp->mb[5] & |
791 | mcp->mb[5] == 3 ? "8Gps" : | 793 | (BIT_0 | BIT_1 | BIT_2); |
792 | mcp->mb[5] == 2 ? "4Gps" : | 794 | ql_dbg(ql_dbg_mbx, vha, 0x119c, |
793 | "unknown"); | 795 | "min_supported_speed=%s.\n", |
794 | } | 796 | ha->min_supported_speed == 6 ? "64Gps" : |
795 | } | 797 | ha->min_supported_speed == 5 ? "32Gps" : |
798 | ha->min_supported_speed == 4 ? "16Gps" : | ||
799 | ha->min_supported_speed == 3 ? "8Gps" : | ||
800 | ha->min_supported_speed == 2 ? "4Gps" : "unknown"); | ||
796 | } | 801 | } |
797 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028, | ||
798 | "Done.\n"); | ||
799 | } | 802 | } |
800 | 803 | ||
804 | done: | ||
805 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028, | ||
806 | "Done %s.\n", __func__); | ||
807 | |||
801 | return rval; | 808 | return rval; |
802 | } | 809 | } |
803 | 810 | ||
@@ -1053,10 +1060,10 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) | |||
1053 | mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8; | 1060 | mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8; |
1054 | if (IS_FWI2_CAPABLE(ha)) | 1061 | if (IS_FWI2_CAPABLE(ha)) |
1055 | mcp->in_mb |= MBX_17|MBX_16|MBX_15; | 1062 | mcp->in_mb |= MBX_17|MBX_16|MBX_15; |
1056 | if (IS_QLA27XX(ha)) | 1063 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
1057 | mcp->in_mb |= | 1064 | mcp->in_mb |= |
1058 | MBX_25|MBX_24|MBX_23|MBX_22|MBX_21|MBX_20|MBX_19|MBX_18| | 1065 | MBX_25|MBX_24|MBX_23|MBX_22|MBX_21|MBX_20|MBX_19|MBX_18| |
1059 | MBX_14|MBX_13|MBX_11|MBX_10|MBX_9|MBX_8; | 1066 | MBX_14|MBX_13|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7; |
1060 | 1067 | ||
1061 | mcp->flags = 0; | 1068 | mcp->flags = 0; |
1062 | mcp->tov = MBX_TOV_SECONDS; | 1069 | mcp->tov = MBX_TOV_SECONDS; |
@@ -1122,7 +1129,10 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) | |||
1122 | } | 1129 | } |
1123 | } | 1130 | } |
1124 | 1131 | ||
1125 | if (IS_QLA27XX(ha)) { | 1132 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
1133 | ha->serdes_version[0] = mcp->mb[7] & 0xff; | ||
1134 | ha->serdes_version[1] = mcp->mb[8] >> 8; | ||
1135 | ha->serdes_version[2] = mcp->mb[8] & 0xff; | ||
1126 | ha->mpi_version[0] = mcp->mb[10] & 0xff; | 1136 | ha->mpi_version[0] = mcp->mb[10] & 0xff; |
1127 | ha->mpi_version[1] = mcp->mb[11] >> 8; | 1137 | ha->mpi_version[1] = mcp->mb[11] >> 8; |
1128 | ha->mpi_version[2] = mcp->mb[11] & 0xff; | 1138 | ha->mpi_version[2] = mcp->mb[11] & 0xff; |
@@ -1133,6 +1143,13 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) | |||
1133 | ha->fw_shared_ram_end = (mcp->mb[21] << 16) | mcp->mb[20]; | 1143 | ha->fw_shared_ram_end = (mcp->mb[21] << 16) | mcp->mb[20]; |
1134 | ha->fw_ddr_ram_start = (mcp->mb[23] << 16) | mcp->mb[22]; | 1144 | ha->fw_ddr_ram_start = (mcp->mb[23] << 16) | mcp->mb[22]; |
1135 | ha->fw_ddr_ram_end = (mcp->mb[25] << 16) | mcp->mb[24]; | 1145 | ha->fw_ddr_ram_end = (mcp->mb[25] << 16) | mcp->mb[24]; |
1146 | if (IS_QLA28XX(ha)) { | ||
1147 | if (mcp->mb[16] & BIT_10) { | ||
1148 | ql_log(ql_log_info, vha, 0xffff, | ||
1149 | "FW support secure flash updates\n"); | ||
1150 | ha->flags.secure_fw = 1; | ||
1151 | } | ||
1152 | } | ||
1136 | } | 1153 | } |
1137 | 1154 | ||
1138 | failed: | 1155 | failed: |
@@ -1638,7 +1655,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa, | |||
1638 | mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10; | 1655 | mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10; |
1639 | if (IS_FWI2_CAPABLE(vha->hw)) | 1656 | if (IS_FWI2_CAPABLE(vha->hw)) |
1640 | mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16; | 1657 | mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16; |
1641 | if (IS_QLA27XX(vha->hw)) | 1658 | if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) |
1642 | mcp->in_mb |= MBX_15; | 1659 | mcp->in_mb |= MBX_15; |
1643 | mcp->tov = MBX_TOV_SECONDS; | 1660 | mcp->tov = MBX_TOV_SECONDS; |
1644 | mcp->flags = 0; | 1661 | mcp->flags = 0; |
@@ -1692,7 +1709,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa, | |||
1692 | } | 1709 | } |
1693 | } | 1710 | } |
1694 | 1711 | ||
1695 | if (IS_QLA27XX(vha->hw)) | 1712 | if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) |
1696 | vha->bbcr = mcp->mb[15]; | 1713 | vha->bbcr = mcp->mb[15]; |
1697 | } | 1714 | } |
1698 | 1715 | ||
@@ -1808,7 +1825,7 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size) | |||
1808 | } | 1825 | } |
1809 | /* 1 and 2 should normally be captured. */ | 1826 | /* 1 and 2 should normally be captured. */ |
1810 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | 1827 | mcp->in_mb = MBX_2|MBX_1|MBX_0; |
1811 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 1828 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
1812 | /* mb3 is additional info about the installed SFP. */ | 1829 | /* mb3 is additional info about the installed SFP. */ |
1813 | mcp->in_mb |= MBX_3; | 1830 | mcp->in_mb |= MBX_3; |
1814 | mcp->buf_size = size; | 1831 | mcp->buf_size = size; |
@@ -1819,10 +1836,20 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size) | |||
1819 | if (rval != QLA_SUCCESS) { | 1836 | if (rval != QLA_SUCCESS) { |
1820 | /*EMPTY*/ | 1837 | /*EMPTY*/ |
1821 | ql_dbg(ql_dbg_mbx, vha, 0x104d, | 1838 | ql_dbg(ql_dbg_mbx, vha, 0x104d, |
1822 | "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n", | 1839 | "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x.\n", |
1823 | rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]); | 1840 | rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]); |
1841 | if (ha->init_cb) { | ||
1842 | ql_dbg(ql_dbg_mbx, vha, 0x104d, "init_cb:\n"); | ||
1843 | ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, | ||
1844 | 0x0104d, ha->init_cb, sizeof(*ha->init_cb)); | ||
1845 | } | ||
1846 | if (ha->ex_init_cb && ha->ex_init_cb->ex_version) { | ||
1847 | ql_dbg(ql_dbg_mbx, vha, 0x104d, "ex_init_cb:\n"); | ||
1848 | ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, | ||
1849 | 0x0104d, ha->ex_init_cb, sizeof(*ha->ex_init_cb)); | ||
1850 | } | ||
1824 | } else { | 1851 | } else { |
1825 | if (IS_QLA27XX(ha)) { | 1852 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
1826 | if (mcp->mb[2] == 6 || mcp->mb[3] == 2) | 1853 | if (mcp->mb[2] == 6 || mcp->mb[3] == 2) |
1827 | ql_dbg(ql_dbg_mbx, vha, 0x119d, | 1854 | ql_dbg(ql_dbg_mbx, vha, 0x119d, |
1828 | "Invalid SFP/Validation Failed\n"); | 1855 | "Invalid SFP/Validation Failed\n"); |
@@ -2006,7 +2033,7 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt) | |||
2006 | 2033 | ||
2007 | /* Passback COS information. */ | 2034 | /* Passback COS information. */ |
2008 | fcport->supported_classes = (pd->options & BIT_4) ? | 2035 | fcport->supported_classes = (pd->options & BIT_4) ? |
2009 | FC_COS_CLASS2: FC_COS_CLASS3; | 2036 | FC_COS_CLASS2 : FC_COS_CLASS3; |
2010 | } | 2037 | } |
2011 | 2038 | ||
2012 | gpd_error_out: | 2039 | gpd_error_out: |
@@ -2076,7 +2103,7 @@ qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states) | |||
2076 | /*EMPTY*/ | 2103 | /*EMPTY*/ |
2077 | ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval); | 2104 | ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval); |
2078 | } else { | 2105 | } else { |
2079 | if (IS_QLA27XX(ha)) { | 2106 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
2080 | if (mcp->mb[2] == 6 || mcp->mb[3] == 2) | 2107 | if (mcp->mb[2] == 6 || mcp->mb[3] == 2) |
2081 | ql_dbg(ql_dbg_mbx, vha, 0x119e, | 2108 | ql_dbg(ql_dbg_mbx, vha, 0x119e, |
2082 | "Invalid SFP/Validation Failed\n"); | 2109 | "Invalid SFP/Validation Failed\n"); |
@@ -2859,7 +2886,8 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha) | |||
2859 | mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; | 2886 | mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; |
2860 | mcp->out_mb = MBX_0; | 2887 | mcp->out_mb = MBX_0; |
2861 | mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 2888 | mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
2862 | if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw) || IS_QLA27XX(vha->hw)) | 2889 | if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || |
2890 | IS_QLA27XX(ha) || IS_QLA28XX(ha)) | ||
2863 | mcp->in_mb |= MBX_12; | 2891 | mcp->in_mb |= MBX_12; |
2864 | mcp->tov = MBX_TOV_SECONDS; | 2892 | mcp->tov = MBX_TOV_SECONDS; |
2865 | mcp->flags = 0; | 2893 | mcp->flags = 0; |
@@ -2884,7 +2912,8 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha) | |||
2884 | ha->orig_fw_iocb_count = mcp->mb[10]; | 2912 | ha->orig_fw_iocb_count = mcp->mb[10]; |
2885 | if (ha->flags.npiv_supported) | 2913 | if (ha->flags.npiv_supported) |
2886 | ha->max_npiv_vports = mcp->mb[11]; | 2914 | ha->max_npiv_vports = mcp->mb[11]; |
2887 | if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 2915 | if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
2916 | IS_QLA28XX(ha)) | ||
2888 | ha->fw_max_fcf_count = mcp->mb[12]; | 2917 | ha->fw_max_fcf_count = mcp->mb[12]; |
2889 | } | 2918 | } |
2890 | 2919 | ||
@@ -3248,7 +3277,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, | |||
3248 | 3277 | ||
3249 | /* Issue marker IOCB. */ | 3278 | /* Issue marker IOCB. */ |
3250 | rval2 = qla2x00_marker(vha, ha->base_qpair, fcport->loop_id, l, | 3279 | rval2 = qla2x00_marker(vha, ha->base_qpair, fcport->loop_id, l, |
3251 | type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID); | 3280 | type == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID); |
3252 | if (rval2 != QLA_SUCCESS) { | 3281 | if (rval2 != QLA_SUCCESS) { |
3253 | ql_dbg(ql_dbg_mbx, vha, 0x1099, | 3282 | ql_dbg(ql_dbg_mbx, vha, 0x1099, |
3254 | "Failed to issue marker IOCB (%x).\n", rval2); | 3283 | "Failed to issue marker IOCB (%x).\n", rval2); |
@@ -3323,7 +3352,7 @@ qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data) | |||
3323 | mbx_cmd_t *mcp = &mc; | 3352 | mbx_cmd_t *mcp = &mc; |
3324 | 3353 | ||
3325 | if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) && | 3354 | if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) && |
3326 | !IS_QLA27XX(vha->hw)) | 3355 | !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) |
3327 | return QLA_FUNCTION_FAILED; | 3356 | return QLA_FUNCTION_FAILED; |
3328 | 3357 | ||
3329 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182, | 3358 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182, |
@@ -3362,7 +3391,7 @@ qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data) | |||
3362 | mbx_cmd_t *mcp = &mc; | 3391 | mbx_cmd_t *mcp = &mc; |
3363 | 3392 | ||
3364 | if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) && | 3393 | if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) && |
3365 | !IS_QLA27XX(vha->hw)) | 3394 | !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) |
3366 | return QLA_FUNCTION_FAILED; | 3395 | return QLA_FUNCTION_FAILED; |
3367 | 3396 | ||
3368 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185, | 3397 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185, |
@@ -3631,7 +3660,8 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma, | |||
3631 | "Entered %s.\n", __func__); | 3660 | "Entered %s.\n", __func__); |
3632 | 3661 | ||
3633 | if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) && | 3662 | if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) && |
3634 | !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw)) | 3663 | !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) && |
3664 | !IS_QLA28XX(vha->hw)) | ||
3635 | return QLA_FUNCTION_FAILED; | 3665 | return QLA_FUNCTION_FAILED; |
3636 | 3666 | ||
3637 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | 3667 | if (unlikely(pci_channel_offline(vha->hw->pdev))) |
@@ -3744,7 +3774,7 @@ qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, | |||
3744 | rval = qla2x00_mailbox_command(vha, mcp); | 3774 | rval = qla2x00_mailbox_command(vha, mcp); |
3745 | 3775 | ||
3746 | /* Return mailbox statuses. */ | 3776 | /* Return mailbox statuses. */ |
3747 | if (mb != NULL) { | 3777 | if (mb) { |
3748 | mb[0] = mcp->mb[0]; | 3778 | mb[0] = mcp->mb[0]; |
3749 | mb[1] = mcp->mb[1]; | 3779 | mb[1] = mcp->mb[1]; |
3750 | mb[3] = mcp->mb[3]; | 3780 | mb[3] = mcp->mb[3]; |
@@ -3779,7 +3809,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, | |||
3779 | mcp->mb[0] = MBC_PORT_PARAMS; | 3809 | mcp->mb[0] = MBC_PORT_PARAMS; |
3780 | mcp->mb[1] = loop_id; | 3810 | mcp->mb[1] = loop_id; |
3781 | mcp->mb[2] = BIT_0; | 3811 | mcp->mb[2] = BIT_0; |
3782 | mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0); | 3812 | mcp->mb[3] = port_speed & 0x3F; |
3783 | mcp->mb[9] = vha->vp_idx; | 3813 | mcp->mb[9] = vha->vp_idx; |
3784 | mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; | 3814 | mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; |
3785 | mcp->in_mb = MBX_3|MBX_1|MBX_0; | 3815 | mcp->in_mb = MBX_3|MBX_1|MBX_0; |
@@ -3788,7 +3818,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, | |||
3788 | rval = qla2x00_mailbox_command(vha, mcp); | 3818 | rval = qla2x00_mailbox_command(vha, mcp); |
3789 | 3819 | ||
3790 | /* Return mailbox statuses. */ | 3820 | /* Return mailbox statuses. */ |
3791 | if (mb != NULL) { | 3821 | if (mb) { |
3792 | mb[0] = mcp->mb[0]; | 3822 | mb[0] = mcp->mb[0]; |
3793 | mb[1] = mcp->mb[1]; | 3823 | mb[1] = mcp->mb[1]; |
3794 | mb[3] = mcp->mb[3]; | 3824 | mb[3] = mcp->mb[3]; |
@@ -4230,7 +4260,7 @@ qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status) | |||
4230 | ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c, | 4260 | ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c, |
4231 | "Dump of Verify Request.\n"); | 4261 | "Dump of Verify Request.\n"); |
4232 | ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e, | 4262 | ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e, |
4233 | (uint8_t *)mn, sizeof(*mn)); | 4263 | mn, sizeof(*mn)); |
4234 | 4264 | ||
4235 | rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120); | 4265 | rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120); |
4236 | if (rval != QLA_SUCCESS) { | 4266 | if (rval != QLA_SUCCESS) { |
@@ -4242,7 +4272,7 @@ qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status) | |||
4242 | ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110, | 4272 | ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110, |
4243 | "Dump of Verify Response.\n"); | 4273 | "Dump of Verify Response.\n"); |
4244 | ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118, | 4274 | ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118, |
4245 | (uint8_t *)mn, sizeof(*mn)); | 4275 | mn, sizeof(*mn)); |
4246 | 4276 | ||
4247 | status[0] = le16_to_cpu(mn->p.rsp.comp_status); | 4277 | status[0] = le16_to_cpu(mn->p.rsp.comp_status); |
4248 | status[1] = status[0] == CS_VCS_CHIP_FAILURE ? | 4278 | status[1] = status[0] == CS_VCS_CHIP_FAILURE ? |
@@ -4318,7 +4348,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) | |||
4318 | mcp->mb[12] = req->qos; | 4348 | mcp->mb[12] = req->qos; |
4319 | mcp->mb[11] = req->vp_idx; | 4349 | mcp->mb[11] = req->vp_idx; |
4320 | mcp->mb[13] = req->rid; | 4350 | mcp->mb[13] = req->rid; |
4321 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 4351 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
4322 | mcp->mb[15] = 0; | 4352 | mcp->mb[15] = 0; |
4323 | 4353 | ||
4324 | mcp->mb[4] = req->id; | 4354 | mcp->mb[4] = req->id; |
@@ -4332,9 +4362,10 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) | |||
4332 | mcp->flags = MBX_DMA_OUT; | 4362 | mcp->flags = MBX_DMA_OUT; |
4333 | mcp->tov = MBX_TOV_SECONDS * 2; | 4363 | mcp->tov = MBX_TOV_SECONDS * 2; |
4334 | 4364 | ||
4335 | if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 4365 | if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
4366 | IS_QLA28XX(ha)) | ||
4336 | mcp->in_mb |= MBX_1; | 4367 | mcp->in_mb |= MBX_1; |
4337 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 4368 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
4338 | mcp->out_mb |= MBX_15; | 4369 | mcp->out_mb |= MBX_15; |
4339 | /* debug q create issue in SR-IOV */ | 4370 | /* debug q create issue in SR-IOV */ |
4340 | mcp->in_mb |= MBX_9 | MBX_8 | MBX_7; | 4371 | mcp->in_mb |= MBX_9 | MBX_8 | MBX_7; |
@@ -4343,7 +4374,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) | |||
4343 | spin_lock_irqsave(&ha->hardware_lock, flags); | 4374 | spin_lock_irqsave(&ha->hardware_lock, flags); |
4344 | if (!(req->options & BIT_0)) { | 4375 | if (!(req->options & BIT_0)) { |
4345 | WRT_REG_DWORD(req->req_q_in, 0); | 4376 | WRT_REG_DWORD(req->req_q_in, 0); |
4346 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha)) | 4377 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
4347 | WRT_REG_DWORD(req->req_q_out, 0); | 4378 | WRT_REG_DWORD(req->req_q_out, 0); |
4348 | } | 4379 | } |
4349 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4380 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
@@ -4387,7 +4418,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) | |||
4387 | mcp->mb[5] = rsp->length; | 4418 | mcp->mb[5] = rsp->length; |
4388 | mcp->mb[14] = rsp->msix->entry; | 4419 | mcp->mb[14] = rsp->msix->entry; |
4389 | mcp->mb[13] = rsp->rid; | 4420 | mcp->mb[13] = rsp->rid; |
4390 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 4421 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
4391 | mcp->mb[15] = 0; | 4422 | mcp->mb[15] = 0; |
4392 | 4423 | ||
4393 | mcp->mb[4] = rsp->id; | 4424 | mcp->mb[4] = rsp->id; |
@@ -4404,7 +4435,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) | |||
4404 | if (IS_QLA81XX(ha)) { | 4435 | if (IS_QLA81XX(ha)) { |
4405 | mcp->out_mb |= MBX_12|MBX_11|MBX_10; | 4436 | mcp->out_mb |= MBX_12|MBX_11|MBX_10; |
4406 | mcp->in_mb |= MBX_1; | 4437 | mcp->in_mb |= MBX_1; |
4407 | } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 4438 | } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
4408 | mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10; | 4439 | mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10; |
4409 | mcp->in_mb |= MBX_1; | 4440 | mcp->in_mb |= MBX_1; |
4410 | /* debug q create issue in SR-IOV */ | 4441 | /* debug q create issue in SR-IOV */ |
@@ -4414,7 +4445,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) | |||
4414 | spin_lock_irqsave(&ha->hardware_lock, flags); | 4445 | spin_lock_irqsave(&ha->hardware_lock, flags); |
4415 | if (!(rsp->options & BIT_0)) { | 4446 | if (!(rsp->options & BIT_0)) { |
4416 | WRT_REG_DWORD(rsp->rsp_q_out, 0); | 4447 | WRT_REG_DWORD(rsp->rsp_q_out, 0); |
4417 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha)) | 4448 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
4418 | WRT_REG_DWORD(rsp->rsp_q_in, 0); | 4449 | WRT_REG_DWORD(rsp->rsp_q_in, 0); |
4419 | } | 4450 | } |
4420 | 4451 | ||
@@ -4472,7 +4503,7 @@ qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size) | |||
4472 | "Entered %s.\n", __func__); | 4503 | "Entered %s.\n", __func__); |
4473 | 4504 | ||
4474 | if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && | 4505 | if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && |
4475 | !IS_QLA27XX(vha->hw)) | 4506 | !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) |
4476 | return QLA_FUNCTION_FAILED; | 4507 | return QLA_FUNCTION_FAILED; |
4477 | 4508 | ||
4478 | mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; | 4509 | mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; |
@@ -4504,7 +4535,7 @@ qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable) | |||
4504 | mbx_cmd_t *mcp = &mc; | 4535 | mbx_cmd_t *mcp = &mc; |
4505 | 4536 | ||
4506 | if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && | 4537 | if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && |
4507 | !IS_QLA27XX(vha->hw)) | 4538 | !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) |
4508 | return QLA_FUNCTION_FAILED; | 4539 | return QLA_FUNCTION_FAILED; |
4509 | 4540 | ||
4510 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df, | 4541 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df, |
@@ -4539,7 +4570,7 @@ qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish) | |||
4539 | mbx_cmd_t *mcp = &mc; | 4570 | mbx_cmd_t *mcp = &mc; |
4540 | 4571 | ||
4541 | if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && | 4572 | if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) && |
4542 | !IS_QLA27XX(vha->hw)) | 4573 | !IS_QLA27XX(vha->hw) && !IS_QLA28XX(vha->hw)) |
4543 | return QLA_FUNCTION_FAILED; | 4574 | return QLA_FUNCTION_FAILED; |
4544 | 4575 | ||
4545 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2, | 4576 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2, |
@@ -4570,6 +4601,42 @@ qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish) | |||
4570 | } | 4601 | } |
4571 | 4602 | ||
4572 | int | 4603 | int |
4604 | qla81xx_fac_semaphore_access(scsi_qla_host_t *vha, int lock) | ||
4605 | { | ||
4606 | int rval = QLA_SUCCESS; | ||
4607 | mbx_cmd_t mc; | ||
4608 | mbx_cmd_t *mcp = &mc; | ||
4609 | struct qla_hw_data *ha = vha->hw; | ||
4610 | |||
4611 | if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && | ||
4612 | !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) | ||
4613 | return rval; | ||
4614 | |||
4615 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2, | ||
4616 | "Entered %s.\n", __func__); | ||
4617 | |||
4618 | mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; | ||
4619 | mcp->mb[1] = (lock ? FAC_OPT_CMD_LOCK_SEMAPHORE : | ||
4620 | FAC_OPT_CMD_UNLOCK_SEMAPHORE); | ||
4621 | mcp->out_mb = MBX_1|MBX_0; | ||
4622 | mcp->in_mb = MBX_1|MBX_0; | ||
4623 | mcp->tov = MBX_TOV_SECONDS; | ||
4624 | mcp->flags = 0; | ||
4625 | rval = qla2x00_mailbox_command(vha, mcp); | ||
4626 | |||
4627 | if (rval != QLA_SUCCESS) { | ||
4628 | ql_dbg(ql_dbg_mbx, vha, 0x10e3, | ||
4629 | "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", | ||
4630 | rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); | ||
4631 | } else { | ||
4632 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4, | ||
4633 | "Done %s.\n", __func__); | ||
4634 | } | ||
4635 | |||
4636 | return rval; | ||
4637 | } | ||
4638 | |||
4639 | int | ||
4573 | qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha) | 4640 | qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha) |
4574 | { | 4641 | { |
4575 | int rval = 0; | 4642 | int rval = 0; |
@@ -4818,10 +4885,10 @@ qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp, | |||
4818 | if (rval != QLA_SUCCESS) { | 4885 | if (rval != QLA_SUCCESS) { |
4819 | ql_dbg(ql_dbg_mbx, vha, 0x10e9, | 4886 | ql_dbg(ql_dbg_mbx, vha, 0x10e9, |
4820 | "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); | 4887 | "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); |
4821 | if (mcp->mb[0] == MBS_COMMAND_ERROR && | 4888 | if (mcp->mb[0] == MBS_COMMAND_ERROR && mcp->mb[1] == 0x22) { |
4822 | mcp->mb[1] == 0x22) | ||
4823 | /* sfp is not there */ | 4889 | /* sfp is not there */ |
4824 | rval = QLA_INTERFACE_ERROR; | 4890 | rval = QLA_INTERFACE_ERROR; |
4891 | } | ||
4825 | } else { | 4892 | } else { |
4826 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea, | 4893 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea, |
4827 | "Done %s.\n", __func__); | 4894 | "Done %s.\n", __func__); |
@@ -5161,13 +5228,14 @@ qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data) | |||
5161 | mcp->mb[3] = MSW(data); | 5228 | mcp->mb[3] = MSW(data); |
5162 | mcp->mb[8] = MSW(risc_addr); | 5229 | mcp->mb[8] = MSW(risc_addr); |
5163 | mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0; | 5230 | mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0; |
5164 | mcp->in_mb = MBX_0; | 5231 | mcp->in_mb = MBX_1|MBX_0; |
5165 | mcp->tov = 30; | 5232 | mcp->tov = 30; |
5166 | mcp->flags = 0; | 5233 | mcp->flags = 0; |
5167 | rval = qla2x00_mailbox_command(vha, mcp); | 5234 | rval = qla2x00_mailbox_command(vha, mcp); |
5168 | if (rval != QLA_SUCCESS) { | 5235 | if (rval != QLA_SUCCESS) { |
5169 | ql_dbg(ql_dbg_mbx, vha, 0x1101, | 5236 | ql_dbg(ql_dbg_mbx, vha, 0x1101, |
5170 | "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); | 5237 | "Failed=%x mb[0]=%x mb[1]=%x.\n", |
5238 | rval, mcp->mb[0], mcp->mb[1]); | ||
5171 | } else { | 5239 | } else { |
5172 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102, | 5240 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102, |
5173 | "Done %s.\n", __func__); | 5241 | "Done %s.\n", __func__); |
@@ -5278,7 +5346,7 @@ qla2x00_set_data_rate(scsi_qla_host_t *vha, uint16_t mode) | |||
5278 | 5346 | ||
5279 | mcp->out_mb = MBX_2|MBX_1|MBX_0; | 5347 | mcp->out_mb = MBX_2|MBX_1|MBX_0; |
5280 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | 5348 | mcp->in_mb = MBX_2|MBX_1|MBX_0; |
5281 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 5349 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
5282 | mcp->in_mb |= MBX_4|MBX_3; | 5350 | mcp->in_mb |= MBX_4|MBX_3; |
5283 | mcp->tov = MBX_TOV_SECONDS; | 5351 | mcp->tov = MBX_TOV_SECONDS; |
5284 | mcp->flags = 0; | 5352 | mcp->flags = 0; |
@@ -5316,7 +5384,7 @@ qla2x00_get_data_rate(scsi_qla_host_t *vha) | |||
5316 | mcp->mb[1] = QLA_GET_DATA_RATE; | 5384 | mcp->mb[1] = QLA_GET_DATA_RATE; |
5317 | mcp->out_mb = MBX_1|MBX_0; | 5385 | mcp->out_mb = MBX_1|MBX_0; |
5318 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | 5386 | mcp->in_mb = MBX_2|MBX_1|MBX_0; |
5319 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 5387 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
5320 | mcp->in_mb |= MBX_3; | 5388 | mcp->in_mb |= MBX_3; |
5321 | mcp->tov = MBX_TOV_SECONDS; | 5389 | mcp->tov = MBX_TOV_SECONDS; |
5322 | mcp->flags = 0; | 5390 | mcp->flags = 0; |
@@ -5346,7 +5414,7 @@ qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb) | |||
5346 | "Entered %s.\n", __func__); | 5414 | "Entered %s.\n", __func__); |
5347 | 5415 | ||
5348 | if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) && | 5416 | if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) && |
5349 | !IS_QLA27XX(ha)) | 5417 | !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
5350 | return QLA_FUNCTION_FAILED; | 5418 | return QLA_FUNCTION_FAILED; |
5351 | mcp->mb[0] = MBC_GET_PORT_CONFIG; | 5419 | mcp->mb[0] = MBC_GET_PORT_CONFIG; |
5352 | mcp->out_mb = MBX_0; | 5420 | mcp->out_mb = MBX_0; |
@@ -5662,6 +5730,7 @@ qla8044_md_get_template(scsi_qla_host_t *vha) | |||
5662 | mbx_cmd_t *mcp = &mc; | 5730 | mbx_cmd_t *mcp = &mc; |
5663 | int rval = QLA_FUNCTION_FAILED; | 5731 | int rval = QLA_FUNCTION_FAILED; |
5664 | int offset = 0, size = MINIDUMP_SIZE_36K; | 5732 | int offset = 0, size = MINIDUMP_SIZE_36K; |
5733 | |||
5665 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f, | 5734 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f, |
5666 | "Entered %s.\n", __func__); | 5735 | "Entered %s.\n", __func__); |
5667 | 5736 | ||
@@ -5842,7 +5911,7 @@ qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data) | |||
5842 | mbx_cmd_t mc; | 5911 | mbx_cmd_t mc; |
5843 | mbx_cmd_t *mcp = &mc; | 5912 | mbx_cmd_t *mcp = &mc; |
5844 | 5913 | ||
5845 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha)) | 5914 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
5846 | return QLA_FUNCTION_FAILED; | 5915 | return QLA_FUNCTION_FAILED; |
5847 | 5916 | ||
5848 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130, | 5917 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130, |
@@ -5917,7 +5986,7 @@ qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data) | |||
5917 | struct qla_hw_data *ha = vha->hw; | 5986 | struct qla_hw_data *ha = vha->hw; |
5918 | unsigned long retry_max_time = jiffies + (2 * HZ); | 5987 | unsigned long retry_max_time = jiffies + (2 * HZ); |
5919 | 5988 | ||
5920 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha)) | 5989 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
5921 | return QLA_FUNCTION_FAILED; | 5990 | return QLA_FUNCTION_FAILED; |
5922 | 5991 | ||
5923 | ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__); | 5992 | ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__); |
@@ -5967,7 +6036,7 @@ qla83xx_restart_nic_firmware(scsi_qla_host_t *vha) | |||
5967 | mbx_cmd_t *mcp = &mc; | 6036 | mbx_cmd_t *mcp = &mc; |
5968 | struct qla_hw_data *ha = vha->hw; | 6037 | struct qla_hw_data *ha = vha->hw; |
5969 | 6038 | ||
5970 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha)) | 6039 | if (!IS_QLA83XX(ha)) |
5971 | return QLA_FUNCTION_FAILED; | 6040 | return QLA_FUNCTION_FAILED; |
5972 | 6041 | ||
5973 | ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__); | 6042 | ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__); |
@@ -6101,7 +6170,8 @@ qla26xx_dport_diagnostics(scsi_qla_host_t *vha, | |||
6101 | mbx_cmd_t *mcp = &mc; | 6170 | mbx_cmd_t *mcp = &mc; |
6102 | dma_addr_t dd_dma; | 6171 | dma_addr_t dd_dma; |
6103 | 6172 | ||
6104 | if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw)) | 6173 | if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) && |
6174 | !IS_QLA28XX(vha->hw)) | ||
6105 | return QLA_FUNCTION_FAILED; | 6175 | return QLA_FUNCTION_FAILED; |
6106 | 6176 | ||
6107 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f, | 6177 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f, |
@@ -6318,7 +6388,13 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
6318 | fcport->d_id.b.rsvd_1 = 0; | 6388 | fcport->d_id.b.rsvd_1 = 0; |
6319 | 6389 | ||
6320 | if (fcport->fc4f_nvme) { | 6390 | if (fcport->fc4f_nvme) { |
6321 | fcport->port_type = FCT_NVME; | 6391 | fcport->port_type = 0; |
6392 | if ((pd->prli_svc_param_word_3[0] & BIT_5) == 0) | ||
6393 | fcport->port_type |= FCT_NVME_INITIATOR; | ||
6394 | if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) | ||
6395 | fcport->port_type |= FCT_NVME_TARGET; | ||
6396 | if ((pd->prli_svc_param_word_3[0] & BIT_3) == 0) | ||
6397 | fcport->port_type |= FCT_NVME_DISCOVERY; | ||
6322 | } else { | 6398 | } else { |
6323 | /* If not target must be initiator or unknown type. */ | 6399 | /* If not target must be initiator or unknown type. */ |
6324 | if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) | 6400 | if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) |
@@ -6507,3 +6583,101 @@ int qla24xx_res_count_wait(struct scsi_qla_host *vha, | |||
6507 | done: | 6583 | done: |
6508 | return rval; | 6584 | return rval; |
6509 | } | 6585 | } |
6586 | |||
6587 | int qla28xx_secure_flash_update(scsi_qla_host_t *vha, uint16_t opts, | ||
6588 | uint16_t region, uint32_t len, dma_addr_t sfub_dma_addr, | ||
6589 | uint32_t sfub_len) | ||
6590 | { | ||
6591 | int rval; | ||
6592 | mbx_cmd_t mc; | ||
6593 | mbx_cmd_t *mcp = &mc; | ||
6594 | |||
6595 | mcp->mb[0] = MBC_SECURE_FLASH_UPDATE; | ||
6596 | mcp->mb[1] = opts; | ||
6597 | mcp->mb[2] = region; | ||
6598 | mcp->mb[3] = MSW(len); | ||
6599 | mcp->mb[4] = LSW(len); | ||
6600 | mcp->mb[5] = MSW(sfub_dma_addr); | ||
6601 | mcp->mb[6] = LSW(sfub_dma_addr); | ||
6602 | mcp->mb[7] = MSW(MSD(sfub_dma_addr)); | ||
6603 | mcp->mb[8] = LSW(MSD(sfub_dma_addr)); | ||
6604 | mcp->mb[9] = sfub_len; | ||
6605 | mcp->out_mb = | ||
6606 | MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | ||
6607 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | ||
6608 | mcp->tov = MBX_TOV_SECONDS; | ||
6609 | mcp->flags = 0; | ||
6610 | rval = qla2x00_mailbox_command(vha, mcp); | ||
6611 | |||
6612 | if (rval != QLA_SUCCESS) { | ||
6613 | ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s(%ld): failed rval 0x%x, %x %x %x", | ||
6614 | __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1], | ||
6615 | mcp->mb[2]); | ||
6616 | } | ||
6617 | |||
6618 | return rval; | ||
6619 | } | ||
6620 | |||
6621 | int qla2xxx_write_remote_register(scsi_qla_host_t *vha, uint32_t addr, | ||
6622 | uint32_t data) | ||
6623 | { | ||
6624 | int rval; | ||
6625 | mbx_cmd_t mc; | ||
6626 | mbx_cmd_t *mcp = &mc; | ||
6627 | |||
6628 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8, | ||
6629 | "Entered %s.\n", __func__); | ||
6630 | |||
6631 | mcp->mb[0] = MBC_WRITE_REMOTE_REG; | ||
6632 | mcp->mb[1] = LSW(addr); | ||
6633 | mcp->mb[2] = MSW(addr); | ||
6634 | mcp->mb[3] = LSW(data); | ||
6635 | mcp->mb[4] = MSW(data); | ||
6636 | mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | ||
6637 | mcp->in_mb = MBX_1|MBX_0; | ||
6638 | mcp->tov = MBX_TOV_SECONDS; | ||
6639 | mcp->flags = 0; | ||
6640 | rval = qla2x00_mailbox_command(vha, mcp); | ||
6641 | |||
6642 | if (rval != QLA_SUCCESS) { | ||
6643 | ql_dbg(ql_dbg_mbx, vha, 0x10e9, | ||
6644 | "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); | ||
6645 | } else { | ||
6646 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea, | ||
6647 | "Done %s.\n", __func__); | ||
6648 | } | ||
6649 | |||
6650 | return rval; | ||
6651 | } | ||
6652 | |||
6653 | int qla2xxx_read_remote_register(scsi_qla_host_t *vha, uint32_t addr, | ||
6654 | uint32_t *data) | ||
6655 | { | ||
6656 | int rval; | ||
6657 | mbx_cmd_t mc; | ||
6658 | mbx_cmd_t *mcp = &mc; | ||
6659 | |||
6660 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8, | ||
6661 | "Entered %s.\n", __func__); | ||
6662 | |||
6663 | mcp->mb[0] = MBC_READ_REMOTE_REG; | ||
6664 | mcp->mb[1] = LSW(addr); | ||
6665 | mcp->mb[2] = MSW(addr); | ||
6666 | mcp->out_mb = MBX_2|MBX_1|MBX_0; | ||
6667 | mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | ||
6668 | mcp->tov = MBX_TOV_SECONDS; | ||
6669 | mcp->flags = 0; | ||
6670 | rval = qla2x00_mailbox_command(vha, mcp); | ||
6671 | |||
6672 | *data = (uint32_t)((((uint32_t)mcp->mb[4]) << 16) | mcp->mb[3]); | ||
6673 | |||
6674 | if (rval != QLA_SUCCESS) { | ||
6675 | ql_dbg(ql_dbg_mbx, vha, 0x10e9, | ||
6676 | "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); | ||
6677 | } else { | ||
6678 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea, | ||
6679 | "Done %s.\n", __func__); | ||
6680 | } | ||
6681 | |||
6682 | return rval; | ||
6683 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 099d8e9851cb..b2977e49356b 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -905,7 +905,8 @@ static void qla_ctrlvp_sp_done(void *s, int res) | |||
905 | { | 905 | { |
906 | struct srb *sp = s; | 906 | struct srb *sp = s; |
907 | 907 | ||
908 | complete(&sp->comp); | 908 | if (sp->comp) |
909 | complete(sp->comp); | ||
909 | /* don't free sp here. Let the caller do the free */ | 910 | /* don't free sp here. Let the caller do the free */ |
910 | } | 911 | } |
911 | 912 | ||
@@ -922,6 +923,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) | |||
922 | struct qla_hw_data *ha = vha->hw; | 923 | struct qla_hw_data *ha = vha->hw; |
923 | int vp_index = vha->vp_idx; | 924 | int vp_index = vha->vp_idx; |
924 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); | 925 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); |
926 | DECLARE_COMPLETION_ONSTACK(comp); | ||
925 | srb_t *sp; | 927 | srb_t *sp; |
926 | 928 | ||
927 | ql_dbg(ql_dbg_vport, vha, 0x10c1, | 929 | ql_dbg(ql_dbg_vport, vha, 0x10c1, |
@@ -936,6 +938,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) | |||
936 | 938 | ||
937 | sp->type = SRB_CTRL_VP; | 939 | sp->type = SRB_CTRL_VP; |
938 | sp->name = "ctrl_vp"; | 940 | sp->name = "ctrl_vp"; |
941 | sp->comp = ∁ | ||
939 | sp->done = qla_ctrlvp_sp_done; | 942 | sp->done = qla_ctrlvp_sp_done; |
940 | sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; | 943 | sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; |
941 | qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); | 944 | qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); |
@@ -953,7 +956,9 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) | |||
953 | ql_dbg(ql_dbg_vport, vha, 0x113f, "%s hndl %x submitted\n", | 956 | ql_dbg(ql_dbg_vport, vha, 0x113f, "%s hndl %x submitted\n", |
954 | sp->name, sp->handle); | 957 | sp->name, sp->handle); |
955 | 958 | ||
956 | wait_for_completion(&sp->comp); | 959 | wait_for_completion(&comp); |
960 | sp->comp = NULL; | ||
961 | |||
957 | rval = sp->rc; | 962 | rval = sp->rc; |
958 | switch (rval) { | 963 | switch (rval) { |
959 | case QLA_FUNCTION_TIMEOUT: | 964 | case QLA_FUNCTION_TIMEOUT: |
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index 60f964c53c01..942ee13b96a4 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c | |||
@@ -273,9 +273,9 @@ premature_exit: | |||
273 | 273 | ||
274 | if (rval) { | 274 | if (rval) { |
275 | ql_log(ql_log_warn, base_vha, 0x1163, | 275 | ql_log(ql_log_warn, base_vha, 0x1163, |
276 | "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, " | 276 | "**** Failed=%x mbx[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x, cmd=%x ****.\n", |
277 | "mb[3]=%x, cmd=%x ****.\n", | 277 | rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], |
278 | mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], command); | 278 | command); |
279 | } else { | 279 | } else { |
280 | ql_dbg(ql_dbg_mbx, base_vha, 0x1164, "Done %s.\n", __func__); | 280 | ql_dbg(ql_dbg_mbx, base_vha, 0x1164, "Done %s.\n", __func__); |
281 | } | 281 | } |
@@ -629,17 +629,20 @@ qlafx00_soc_cpu_reset(scsi_qla_host_t *vha) | |||
629 | * | 629 | * |
630 | * Returns 0 on success. | 630 | * Returns 0 on success. |
631 | */ | 631 | */ |
632 | void | 632 | int |
633 | qlafx00_soft_reset(scsi_qla_host_t *vha) | 633 | qlafx00_soft_reset(scsi_qla_host_t *vha) |
634 | { | 634 | { |
635 | struct qla_hw_data *ha = vha->hw; | 635 | struct qla_hw_data *ha = vha->hw; |
636 | int rval = QLA_FUNCTION_FAILED; | ||
636 | 637 | ||
637 | if (unlikely(pci_channel_offline(ha->pdev) && | 638 | if (unlikely(pci_channel_offline(ha->pdev) && |
638 | ha->flags.pci_channel_io_perm_failure)) | 639 | ha->flags.pci_channel_io_perm_failure)) |
639 | return; | 640 | return rval; |
640 | 641 | ||
641 | ha->isp_ops->disable_intrs(ha); | 642 | ha->isp_ops->disable_intrs(ha); |
642 | qlafx00_soc_cpu_reset(vha); | 643 | qlafx00_soc_cpu_reset(vha); |
644 | |||
645 | return QLA_SUCCESS; | ||
643 | } | 646 | } |
644 | 647 | ||
645 | /** | 648 | /** |
@@ -1138,8 +1141,8 @@ qlafx00_find_all_targets(scsi_qla_host_t *vha, | |||
1138 | 1141 | ||
1139 | ql_dbg(ql_dbg_disc + ql_dbg_init, vha, 0x2088, | 1142 | ql_dbg(ql_dbg_disc + ql_dbg_init, vha, 0x2088, |
1140 | "Listing Target bit map...\n"); | 1143 | "Listing Target bit map...\n"); |
1141 | ql_dump_buffer(ql_dbg_disc + ql_dbg_init, vha, | 1144 | ql_dump_buffer(ql_dbg_disc + ql_dbg_init, vha, 0x2089, |
1142 | 0x2089, (uint8_t *)ha->gid_list, 32); | 1145 | ha->gid_list, 32); |
1143 | 1146 | ||
1144 | /* Allocate temporary rmtport for any new rmtports discovered. */ | 1147 | /* Allocate temporary rmtport for any new rmtports discovered. */ |
1145 | new_fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL); | 1148 | new_fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL); |
@@ -1320,6 +1323,7 @@ qlafx00_configure_devices(scsi_qla_host_t *vha) | |||
1320 | { | 1323 | { |
1321 | int rval; | 1324 | int rval; |
1322 | unsigned long flags; | 1325 | unsigned long flags; |
1326 | |||
1323 | rval = QLA_SUCCESS; | 1327 | rval = QLA_SUCCESS; |
1324 | 1328 | ||
1325 | flags = vha->dpc_flags; | 1329 | flags = vha->dpc_flags; |
@@ -1913,8 +1917,7 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type) | |||
1913 | phost_info->domainname, | 1917 | phost_info->domainname, |
1914 | phost_info->hostdriver); | 1918 | phost_info->hostdriver); |
1915 | ql_dump_buffer(ql_dbg_init + ql_dbg_disc, vha, 0x014d, | 1919 | ql_dump_buffer(ql_dbg_init + ql_dbg_disc, vha, 0x014d, |
1916 | (uint8_t *)phost_info, | 1920 | phost_info, sizeof(*phost_info)); |
1917 | sizeof(struct host_system_info)); | ||
1918 | } | 1921 | } |
1919 | } | 1922 | } |
1920 | 1923 | ||
@@ -1968,7 +1971,7 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type) | |||
1968 | vha->d_id.b.al_pa = pinfo->port_id[2]; | 1971 | vha->d_id.b.al_pa = pinfo->port_id[2]; |
1969 | qlafx00_update_host_attr(vha, pinfo); | 1972 | qlafx00_update_host_attr(vha, pinfo); |
1970 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0141, | 1973 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0141, |
1971 | (uint8_t *)pinfo, 16); | 1974 | pinfo, 16); |
1972 | } else if (fx_type == FXDISC_GET_TGT_NODE_INFO) { | 1975 | } else if (fx_type == FXDISC_GET_TGT_NODE_INFO) { |
1973 | struct qlafx00_tgt_node_info *pinfo = | 1976 | struct qlafx00_tgt_node_info *pinfo = |
1974 | (struct qlafx00_tgt_node_info *) fdisc->u.fxiocb.rsp_addr; | 1977 | (struct qlafx00_tgt_node_info *) fdisc->u.fxiocb.rsp_addr; |
@@ -1976,12 +1979,12 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type) | |||
1976 | memcpy(fcport->port_name, pinfo->tgt_node_wwpn, WWN_SIZE); | 1979 | memcpy(fcport->port_name, pinfo->tgt_node_wwpn, WWN_SIZE); |
1977 | fcport->port_type = FCT_TARGET; | 1980 | fcport->port_type = FCT_TARGET; |
1978 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0144, | 1981 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0144, |
1979 | (uint8_t *)pinfo, 16); | 1982 | pinfo, 16); |
1980 | } else if (fx_type == FXDISC_GET_TGT_NODE_LIST) { | 1983 | } else if (fx_type == FXDISC_GET_TGT_NODE_LIST) { |
1981 | struct qlafx00_tgt_node_info *pinfo = | 1984 | struct qlafx00_tgt_node_info *pinfo = |
1982 | (struct qlafx00_tgt_node_info *) fdisc->u.fxiocb.rsp_addr; | 1985 | (struct qlafx00_tgt_node_info *) fdisc->u.fxiocb.rsp_addr; |
1983 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0146, | 1986 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0146, |
1984 | (uint8_t *)pinfo, 16); | 1987 | pinfo, 16); |
1985 | memcpy(vha->hw->gid_list, pinfo, QLAFX00_TGT_NODE_LIST_SIZE); | 1988 | memcpy(vha->hw->gid_list, pinfo, QLAFX00_TGT_NODE_LIST_SIZE); |
1986 | } else if (fx_type == FXDISC_ABORT_IOCTL) | 1989 | } else if (fx_type == FXDISC_ABORT_IOCTL) |
1987 | fdisc->u.fxiocb.result = | 1990 | fdisc->u.fxiocb.result = |
@@ -2248,18 +2251,16 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
2248 | 2251 | ||
2249 | fw_sts_ptr = bsg_job->reply + sizeof(struct fc_bsg_reply); | 2252 | fw_sts_ptr = bsg_job->reply + sizeof(struct fc_bsg_reply); |
2250 | 2253 | ||
2251 | memcpy(fw_sts_ptr, (uint8_t *)&fstatus, | 2254 | memcpy(fw_sts_ptr, &fstatus, sizeof(fstatus)); |
2252 | sizeof(struct qla_mt_iocb_rsp_fx00)); | ||
2253 | bsg_job->reply_len = sizeof(struct fc_bsg_reply) + | 2255 | bsg_job->reply_len = sizeof(struct fc_bsg_reply) + |
2254 | sizeof(struct qla_mt_iocb_rsp_fx00) + sizeof(uint8_t); | 2256 | sizeof(struct qla_mt_iocb_rsp_fx00) + sizeof(uint8_t); |
2255 | 2257 | ||
2256 | ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, | 2258 | ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, |
2257 | sp->fcport->vha, 0x5080, | 2259 | sp->vha, 0x5080, pkt, sizeof(*pkt)); |
2258 | (uint8_t *)pkt, sizeof(struct ioctl_iocb_entry_fx00)); | ||
2259 | 2260 | ||
2260 | ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, | 2261 | ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, |
2261 | sp->fcport->vha, 0x5074, | 2262 | sp->vha, 0x5074, |
2262 | (uint8_t *)fw_sts_ptr, sizeof(struct qla_mt_iocb_rsp_fx00)); | 2263 | fw_sts_ptr, sizeof(fstatus)); |
2263 | 2264 | ||
2264 | res = bsg_reply->result = DID_OK << 16; | 2265 | res = bsg_reply->result = DID_OK << 16; |
2265 | bsg_reply->reply_payload_rcv_len = | 2266 | bsg_reply->reply_payload_rcv_len = |
@@ -2597,7 +2598,7 @@ qlafx00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt) | |||
2597 | 2598 | ||
2598 | /* Move sense data. */ | 2599 | /* Move sense data. */ |
2599 | ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x304e, | 2600 | ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x304e, |
2600 | (uint8_t *)pkt, sizeof(sts_cont_entry_t)); | 2601 | pkt, sizeof(*pkt)); |
2601 | memcpy(sense_ptr, pkt->data, sense_sz); | 2602 | memcpy(sense_ptr, pkt->data, sense_sz); |
2602 | ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x304a, | 2603 | ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x304a, |
2603 | sense_ptr, sense_sz); | 2604 | sense_ptr, sense_sz); |
@@ -2992,7 +2993,7 @@ qlafx00_build_scsi_iocbs(srb_t *sp, struct cmd_type_7_fx00 *cmd_pkt, | |||
2992 | uint16_t tot_dsds, struct cmd_type_7_fx00 *lcmd_pkt) | 2993 | uint16_t tot_dsds, struct cmd_type_7_fx00 *lcmd_pkt) |
2993 | { | 2994 | { |
2994 | uint16_t avail_dsds; | 2995 | uint16_t avail_dsds; |
2995 | __le32 *cur_dsd; | 2996 | struct dsd64 *cur_dsd; |
2996 | scsi_qla_host_t *vha; | 2997 | scsi_qla_host_t *vha; |
2997 | struct scsi_cmnd *cmd; | 2998 | struct scsi_cmnd *cmd; |
2998 | struct scatterlist *sg; | 2999 | struct scatterlist *sg; |
@@ -3028,12 +3029,10 @@ qlafx00_build_scsi_iocbs(srb_t *sp, struct cmd_type_7_fx00 *cmd_pkt, | |||
3028 | 3029 | ||
3029 | /* One DSD is available in the Command Type 3 IOCB */ | 3030 | /* One DSD is available in the Command Type 3 IOCB */ |
3030 | avail_dsds = 1; | 3031 | avail_dsds = 1; |
3031 | cur_dsd = (__le32 *)&lcmd_pkt->dseg_0_address; | 3032 | cur_dsd = &lcmd_pkt->dsd; |
3032 | 3033 | ||
3033 | /* Load data segments */ | 3034 | /* Load data segments */ |
3034 | scsi_for_each_sg(cmd, sg, tot_dsds, i) { | 3035 | scsi_for_each_sg(cmd, sg, tot_dsds, i) { |
3035 | dma_addr_t sle_dma; | ||
3036 | |||
3037 | /* Allocate additional continuation packets? */ | 3036 | /* Allocate additional continuation packets? */ |
3038 | if (avail_dsds == 0) { | 3037 | if (avail_dsds == 0) { |
3039 | /* | 3038 | /* |
@@ -3043,26 +3042,23 @@ qlafx00_build_scsi_iocbs(srb_t *sp, struct cmd_type_7_fx00 *cmd_pkt, | |||
3043 | memset(&lcont_pkt, 0, REQUEST_ENTRY_SIZE); | 3042 | memset(&lcont_pkt, 0, REQUEST_ENTRY_SIZE); |
3044 | cont_pkt = | 3043 | cont_pkt = |
3045 | qlafx00_prep_cont_type1_iocb(req, &lcont_pkt); | 3044 | qlafx00_prep_cont_type1_iocb(req, &lcont_pkt); |
3046 | cur_dsd = (__le32 *)lcont_pkt.dseg_0_address; | 3045 | cur_dsd = lcont_pkt.dsd; |
3047 | avail_dsds = 5; | 3046 | avail_dsds = 5; |
3048 | cont = 1; | 3047 | cont = 1; |
3049 | } | 3048 | } |
3050 | 3049 | ||
3051 | sle_dma = sg_dma_address(sg); | 3050 | append_dsd64(&cur_dsd, sg); |
3052 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
3053 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
3054 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
3055 | avail_dsds--; | 3051 | avail_dsds--; |
3056 | if (avail_dsds == 0 && cont == 1) { | 3052 | if (avail_dsds == 0 && cont == 1) { |
3057 | cont = 0; | 3053 | cont = 0; |
3058 | memcpy_toio((void __iomem *)cont_pkt, &lcont_pkt, | 3054 | memcpy_toio((void __iomem *)cont_pkt, &lcont_pkt, |
3059 | REQUEST_ENTRY_SIZE); | 3055 | sizeof(lcont_pkt)); |
3060 | } | 3056 | } |
3061 | 3057 | ||
3062 | } | 3058 | } |
3063 | if (avail_dsds != 0 && cont == 1) { | 3059 | if (avail_dsds != 0 && cont == 1) { |
3064 | memcpy_toio((void __iomem *)cont_pkt, &lcont_pkt, | 3060 | memcpy_toio((void __iomem *)cont_pkt, &lcont_pkt, |
3065 | REQUEST_ENTRY_SIZE); | 3061 | sizeof(lcont_pkt)); |
3066 | } | 3062 | } |
3067 | } | 3063 | } |
3068 | 3064 | ||
@@ -3172,9 +3168,9 @@ qlafx00_start_scsi(srb_t *sp) | |||
3172 | lcmd_pkt.entry_status = (uint8_t) rsp->id; | 3168 | lcmd_pkt.entry_status = (uint8_t) rsp->id; |
3173 | 3169 | ||
3174 | ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302e, | 3170 | ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302e, |
3175 | (uint8_t *)cmd->cmnd, cmd->cmd_len); | 3171 | cmd->cmnd, cmd->cmd_len); |
3176 | ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x3032, | 3172 | ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x3032, |
3177 | (uint8_t *)&lcmd_pkt, REQUEST_ENTRY_SIZE); | 3173 | &lcmd_pkt, sizeof(lcmd_pkt)); |
3178 | 3174 | ||
3179 | memcpy_toio((void __iomem *)cmd_pkt, &lcmd_pkt, REQUEST_ENTRY_SIZE); | 3175 | memcpy_toio((void __iomem *)cmd_pkt, &lcmd_pkt, REQUEST_ENTRY_SIZE); |
3180 | wmb(); | 3176 | wmb(); |
@@ -3282,11 +3278,9 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) | |||
3282 | fx_iocb.req_dsdcnt = cpu_to_le16(1); | 3278 | fx_iocb.req_dsdcnt = cpu_to_le16(1); |
3283 | fx_iocb.req_xfrcnt = | 3279 | fx_iocb.req_xfrcnt = |
3284 | cpu_to_le16(fxio->u.fxiocb.req_len); | 3280 | cpu_to_le16(fxio->u.fxiocb.req_len); |
3285 | fx_iocb.dseg_rq_address[0] = | 3281 | put_unaligned_le64(fxio->u.fxiocb.req_dma_handle, |
3286 | cpu_to_le32(LSD(fxio->u.fxiocb.req_dma_handle)); | 3282 | &fx_iocb.dseg_rq.address); |
3287 | fx_iocb.dseg_rq_address[1] = | 3283 | fx_iocb.dseg_rq.length = |
3288 | cpu_to_le32(MSD(fxio->u.fxiocb.req_dma_handle)); | ||
3289 | fx_iocb.dseg_rq_len = | ||
3290 | cpu_to_le32(fxio->u.fxiocb.req_len); | 3284 | cpu_to_le32(fxio->u.fxiocb.req_len); |
3291 | } | 3285 | } |
3292 | 3286 | ||
@@ -3294,11 +3288,9 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) | |||
3294 | fx_iocb.rsp_dsdcnt = cpu_to_le16(1); | 3288 | fx_iocb.rsp_dsdcnt = cpu_to_le16(1); |
3295 | fx_iocb.rsp_xfrcnt = | 3289 | fx_iocb.rsp_xfrcnt = |
3296 | cpu_to_le16(fxio->u.fxiocb.rsp_len); | 3290 | cpu_to_le16(fxio->u.fxiocb.rsp_len); |
3297 | fx_iocb.dseg_rsp_address[0] = | 3291 | put_unaligned_le64(fxio->u.fxiocb.rsp_dma_handle, |
3298 | cpu_to_le32(LSD(fxio->u.fxiocb.rsp_dma_handle)); | 3292 | &fx_iocb.dseg_rsp.address); |
3299 | fx_iocb.dseg_rsp_address[1] = | 3293 | fx_iocb.dseg_rsp.length = |
3300 | cpu_to_le32(MSD(fxio->u.fxiocb.rsp_dma_handle)); | ||
3301 | fx_iocb.dseg_rsp_len = | ||
3302 | cpu_to_le32(fxio->u.fxiocb.rsp_len); | 3294 | cpu_to_le32(fxio->u.fxiocb.rsp_len); |
3303 | } | 3295 | } |
3304 | 3296 | ||
@@ -3308,6 +3300,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) | |||
3308 | fx_iocb.flags = fxio->u.fxiocb.flags; | 3300 | fx_iocb.flags = fxio->u.fxiocb.flags; |
3309 | } else { | 3301 | } else { |
3310 | struct scatterlist *sg; | 3302 | struct scatterlist *sg; |
3303 | |||
3311 | bsg_job = sp->u.bsg_job; | 3304 | bsg_job = sp->u.bsg_job; |
3312 | bsg_request = bsg_job->request; | 3305 | bsg_request = bsg_job->request; |
3313 | piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *) | 3306 | piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *) |
@@ -3327,19 +3320,17 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) | |||
3327 | int avail_dsds, tot_dsds; | 3320 | int avail_dsds, tot_dsds; |
3328 | cont_a64_entry_t lcont_pkt; | 3321 | cont_a64_entry_t lcont_pkt; |
3329 | cont_a64_entry_t *cont_pkt = NULL; | 3322 | cont_a64_entry_t *cont_pkt = NULL; |
3330 | __le32 *cur_dsd; | 3323 | struct dsd64 *cur_dsd; |
3331 | int index = 0, cont = 0; | 3324 | int index = 0, cont = 0; |
3332 | 3325 | ||
3333 | fx_iocb.req_dsdcnt = | 3326 | fx_iocb.req_dsdcnt = |
3334 | cpu_to_le16(bsg_job->request_payload.sg_cnt); | 3327 | cpu_to_le16(bsg_job->request_payload.sg_cnt); |
3335 | tot_dsds = | 3328 | tot_dsds = |
3336 | bsg_job->request_payload.sg_cnt; | 3329 | bsg_job->request_payload.sg_cnt; |
3337 | cur_dsd = (__le32 *)&fx_iocb.dseg_rq_address[0]; | 3330 | cur_dsd = &fx_iocb.dseg_rq; |
3338 | avail_dsds = 1; | 3331 | avail_dsds = 1; |
3339 | for_each_sg(bsg_job->request_payload.sg_list, sg, | 3332 | for_each_sg(bsg_job->request_payload.sg_list, sg, |
3340 | tot_dsds, index) { | 3333 | tot_dsds, index) { |
3341 | dma_addr_t sle_dma; | ||
3342 | |||
3343 | /* Allocate additional continuation packets? */ | 3334 | /* Allocate additional continuation packets? */ |
3344 | if (avail_dsds == 0) { | 3335 | if (avail_dsds == 0) { |
3345 | /* | 3336 | /* |
@@ -3351,17 +3342,13 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) | |||
3351 | cont_pkt = | 3342 | cont_pkt = |
3352 | qlafx00_prep_cont_type1_iocb( | 3343 | qlafx00_prep_cont_type1_iocb( |
3353 | sp->vha->req, &lcont_pkt); | 3344 | sp->vha->req, &lcont_pkt); |
3354 | cur_dsd = (__le32 *) | 3345 | cur_dsd = lcont_pkt.dsd; |
3355 | lcont_pkt.dseg_0_address; | ||
3356 | avail_dsds = 5; | 3346 | avail_dsds = 5; |
3357 | cont = 1; | 3347 | cont = 1; |
3358 | entry_cnt++; | 3348 | entry_cnt++; |
3359 | } | 3349 | } |
3360 | 3350 | ||
3361 | sle_dma = sg_dma_address(sg); | 3351 | append_dsd64(&cur_dsd, sg); |
3362 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
3363 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
3364 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
3365 | avail_dsds--; | 3352 | avail_dsds--; |
3366 | 3353 | ||
3367 | if (avail_dsds == 0 && cont == 1) { | 3354 | if (avail_dsds == 0 && cont == 1) { |
@@ -3389,19 +3376,17 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) | |||
3389 | int avail_dsds, tot_dsds; | 3376 | int avail_dsds, tot_dsds; |
3390 | cont_a64_entry_t lcont_pkt; | 3377 | cont_a64_entry_t lcont_pkt; |
3391 | cont_a64_entry_t *cont_pkt = NULL; | 3378 | cont_a64_entry_t *cont_pkt = NULL; |
3392 | __le32 *cur_dsd; | 3379 | struct dsd64 *cur_dsd; |
3393 | int index = 0, cont = 0; | 3380 | int index = 0, cont = 0; |
3394 | 3381 | ||
3395 | fx_iocb.rsp_dsdcnt = | 3382 | fx_iocb.rsp_dsdcnt = |
3396 | cpu_to_le16(bsg_job->reply_payload.sg_cnt); | 3383 | cpu_to_le16(bsg_job->reply_payload.sg_cnt); |
3397 | tot_dsds = bsg_job->reply_payload.sg_cnt; | 3384 | tot_dsds = bsg_job->reply_payload.sg_cnt; |
3398 | cur_dsd = (__le32 *)&fx_iocb.dseg_rsp_address[0]; | 3385 | cur_dsd = &fx_iocb.dseg_rsp; |
3399 | avail_dsds = 1; | 3386 | avail_dsds = 1; |
3400 | 3387 | ||
3401 | for_each_sg(bsg_job->reply_payload.sg_list, sg, | 3388 | for_each_sg(bsg_job->reply_payload.sg_list, sg, |
3402 | tot_dsds, index) { | 3389 | tot_dsds, index) { |
3403 | dma_addr_t sle_dma; | ||
3404 | |||
3405 | /* Allocate additional continuation packets? */ | 3390 | /* Allocate additional continuation packets? */ |
3406 | if (avail_dsds == 0) { | 3391 | if (avail_dsds == 0) { |
3407 | /* | 3392 | /* |
@@ -3413,17 +3398,13 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) | |||
3413 | cont_pkt = | 3398 | cont_pkt = |
3414 | qlafx00_prep_cont_type1_iocb( | 3399 | qlafx00_prep_cont_type1_iocb( |
3415 | sp->vha->req, &lcont_pkt); | 3400 | sp->vha->req, &lcont_pkt); |
3416 | cur_dsd = (__le32 *) | 3401 | cur_dsd = lcont_pkt.dsd; |
3417 | lcont_pkt.dseg_0_address; | ||
3418 | avail_dsds = 5; | 3402 | avail_dsds = 5; |
3419 | cont = 1; | 3403 | cont = 1; |
3420 | entry_cnt++; | 3404 | entry_cnt++; |
3421 | } | 3405 | } |
3422 | 3406 | ||
3423 | sle_dma = sg_dma_address(sg); | 3407 | append_dsd64(&cur_dsd, sg); |
3424 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
3425 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
3426 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
3427 | avail_dsds--; | 3408 | avail_dsds--; |
3428 | 3409 | ||
3429 | if (avail_dsds == 0 && cont == 1) { | 3410 | if (avail_dsds == 0 && cont == 1) { |
@@ -3454,10 +3435,8 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) | |||
3454 | } | 3435 | } |
3455 | 3436 | ||
3456 | ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, | 3437 | ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, |
3457 | sp->vha, 0x3047, | 3438 | sp->vha, 0x3047, &fx_iocb, sizeof(fx_iocb)); |
3458 | (uint8_t *)&fx_iocb, sizeof(struct fxdisc_entry_fx00)); | ||
3459 | 3439 | ||
3460 | memcpy_toio((void __iomem *)pfxiocb, &fx_iocb, | 3440 | memcpy_toio((void __iomem *)pfxiocb, &fx_iocb, sizeof(fx_iocb)); |
3461 | sizeof(struct fxdisc_entry_fx00)); | ||
3462 | wmb(); | 3441 | wmb(); |
3463 | } | 3442 | } |
diff --git a/drivers/scsi/qla2xxx/qla_mr.h b/drivers/scsi/qla2xxx/qla_mr.h index aeaa1b40b1fc..4567f0c42486 100644 --- a/drivers/scsi/qla2xxx/qla_mr.h +++ b/drivers/scsi/qla2xxx/qla_mr.h | |||
@@ -7,6 +7,8 @@ | |||
7 | #ifndef __QLA_MR_H | 7 | #ifndef __QLA_MR_H |
8 | #define __QLA_MR_H | 8 | #define __QLA_MR_H |
9 | 9 | ||
10 | #include "qla_dsd.h" | ||
11 | |||
10 | /* | 12 | /* |
11 | * The PCI VendorID and DeviceID for our board. | 13 | * The PCI VendorID and DeviceID for our board. |
12 | */ | 14 | */ |
@@ -46,8 +48,7 @@ struct cmd_type_7_fx00 { | |||
46 | uint8_t fcp_cdb[MAX_CMDSZ]; /* SCSI command words. */ | 48 | uint8_t fcp_cdb[MAX_CMDSZ]; /* SCSI command words. */ |
47 | __le32 byte_count; /* Total byte count. */ | 49 | __le32 byte_count; /* Total byte count. */ |
48 | 50 | ||
49 | uint32_t dseg_0_address[2]; /* Data segment 0 address. */ | 51 | struct dsd64 dsd; |
50 | uint32_t dseg_0_len; /* Data segment 0 length. */ | ||
51 | }; | 52 | }; |
52 | 53 | ||
53 | #define STATUS_TYPE_FX00 0x01 /* Status entry. */ | 54 | #define STATUS_TYPE_FX00 0x01 /* Status entry. */ |
@@ -176,10 +177,8 @@ struct fxdisc_entry_fx00 { | |||
176 | uint8_t flags; | 177 | uint8_t flags; |
177 | uint8_t reserved_1; | 178 | uint8_t reserved_1; |
178 | 179 | ||
179 | __le32 dseg_rq_address[2]; /* Data segment 0 address. */ | 180 | struct dsd64 dseg_rq; |
180 | __le32 dseg_rq_len; /* Data segment 0 length. */ | 181 | struct dsd64 dseg_rsp; |
181 | __le32 dseg_rsp_address[2]; /* Data segment 1 address. */ | ||
182 | __le32 dseg_rsp_len; /* Data segment 1 length. */ | ||
183 | 182 | ||
184 | __le32 dataword; | 183 | __le32 dataword; |
185 | __le32 adapid; | 184 | __le32 adapid; |
diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index 41c85da3ab32..22e3fba28e51 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c | |||
@@ -131,14 +131,10 @@ static void qla_nvme_sp_ls_done(void *ptr, int res) | |||
131 | struct nvmefc_ls_req *fd; | 131 | struct nvmefc_ls_req *fd; |
132 | struct nvme_private *priv; | 132 | struct nvme_private *priv; |
133 | 133 | ||
134 | if (atomic_read(&sp->ref_count) == 0) { | 134 | if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0)) |
135 | ql_log(ql_log_warn, sp->fcport->vha, 0x2123, | ||
136 | "SP reference-count to ZERO on LS_done -- sp=%p.\n", sp); | ||
137 | return; | 135 | return; |
138 | } | ||
139 | 136 | ||
140 | if (!atomic_dec_and_test(&sp->ref_count)) | 137 | atomic_dec(&sp->ref_count); |
141 | return; | ||
142 | 138 | ||
143 | if (res) | 139 | if (res) |
144 | res = -EINVAL; | 140 | res = -EINVAL; |
@@ -161,15 +157,18 @@ static void qla_nvme_sp_done(void *ptr, int res) | |||
161 | nvme = &sp->u.iocb_cmd; | 157 | nvme = &sp->u.iocb_cmd; |
162 | fd = nvme->u.nvme.desc; | 158 | fd = nvme->u.nvme.desc; |
163 | 159 | ||
164 | if (!atomic_dec_and_test(&sp->ref_count)) | 160 | if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0)) |
165 | return; | 161 | return; |
166 | 162 | ||
167 | if (res == QLA_SUCCESS) | 163 | atomic_dec(&sp->ref_count); |
168 | fd->status = 0; | ||
169 | else | ||
170 | fd->status = NVME_SC_INTERNAL; | ||
171 | 164 | ||
172 | fd->rcv_rsplen = nvme->u.nvme.rsp_pyld_len; | 165 | if (res == QLA_SUCCESS) { |
166 | fd->rcv_rsplen = nvme->u.nvme.rsp_pyld_len; | ||
167 | } else { | ||
168 | fd->rcv_rsplen = 0; | ||
169 | fd->transferred_length = 0; | ||
170 | } | ||
171 | fd->status = 0; | ||
173 | fd->done(fd); | 172 | fd->done(fd); |
174 | qla2xxx_rel_qpair_sp(sp->qpair, sp); | 173 | qla2xxx_rel_qpair_sp(sp->qpair, sp); |
175 | 174 | ||
@@ -185,14 +184,24 @@ static void qla_nvme_abort_work(struct work_struct *work) | |||
185 | struct qla_hw_data *ha = fcport->vha->hw; | 184 | struct qla_hw_data *ha = fcport->vha->hw; |
186 | int rval; | 185 | int rval; |
187 | 186 | ||
188 | if (fcport) | 187 | ql_dbg(ql_dbg_io, fcport->vha, 0xffff, |
189 | ql_dbg(ql_dbg_io, fcport->vha, 0xffff, | 188 | "%s called for sp=%p, hndl=%x on fcport=%p deleted=%d\n", |
190 | "%s called for sp=%p, hndl=%x on fcport=%p deleted=%d\n", | 189 | __func__, sp, sp->handle, fcport, fcport->deleted); |
191 | __func__, sp, sp->handle, fcport, fcport->deleted); | ||
192 | 190 | ||
193 | if (!ha->flags.fw_started && (fcport && fcport->deleted)) | 191 | if (!ha->flags.fw_started && (fcport && fcport->deleted)) |
194 | return; | 192 | return; |
195 | 193 | ||
194 | if (ha->flags.host_shutting_down) { | ||
195 | ql_log(ql_log_info, sp->fcport->vha, 0xffff, | ||
196 | "%s Calling done on sp: %p, type: 0x%x, sp->ref_count: 0x%x\n", | ||
197 | __func__, sp, sp->type, atomic_read(&sp->ref_count)); | ||
198 | sp->done(sp, 0); | ||
199 | return; | ||
200 | } | ||
201 | |||
202 | if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0)) | ||
203 | return; | ||
204 | |||
196 | rval = ha->isp_ops->abort_command(sp); | 205 | rval = ha->isp_ops->abort_command(sp); |
197 | 206 | ||
198 | ql_dbg(ql_dbg_io, fcport->vha, 0x212b, | 207 | ql_dbg(ql_dbg_io, fcport->vha, 0x212b, |
@@ -291,7 +300,7 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) | |||
291 | uint16_t req_cnt; | 300 | uint16_t req_cnt; |
292 | uint16_t tot_dsds; | 301 | uint16_t tot_dsds; |
293 | uint16_t avail_dsds; | 302 | uint16_t avail_dsds; |
294 | uint32_t *cur_dsd; | 303 | struct dsd64 *cur_dsd; |
295 | struct req_que *req = NULL; | 304 | struct req_que *req = NULL; |
296 | struct scsi_qla_host *vha = sp->fcport->vha; | 305 | struct scsi_qla_host *vha = sp->fcport->vha; |
297 | struct qla_hw_data *ha = vha->hw; | 306 | struct qla_hw_data *ha = vha->hw; |
@@ -340,6 +349,7 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) | |||
340 | 349 | ||
341 | if (unlikely(!fd->sqid)) { | 350 | if (unlikely(!fd->sqid)) { |
342 | struct nvme_fc_cmd_iu *cmd = fd->cmdaddr; | 351 | struct nvme_fc_cmd_iu *cmd = fd->cmdaddr; |
352 | |||
343 | if (cmd->sqe.common.opcode == nvme_admin_async_event) { | 353 | if (cmd->sqe.common.opcode == nvme_admin_async_event) { |
344 | nvme->u.nvme.aen_op = 1; | 354 | nvme->u.nvme.aen_op = 1; |
345 | atomic_inc(&ha->nvme_active_aen_cnt); | 355 | atomic_inc(&ha->nvme_active_aen_cnt); |
@@ -395,25 +405,22 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) | |||
395 | 405 | ||
396 | /* NVME RSP IU */ | 406 | /* NVME RSP IU */ |
397 | cmd_pkt->nvme_rsp_dsd_len = cpu_to_le16(fd->rsplen); | 407 | cmd_pkt->nvme_rsp_dsd_len = cpu_to_le16(fd->rsplen); |
398 | cmd_pkt->nvme_rsp_dseg_address[0] = cpu_to_le32(LSD(fd->rspdma)); | 408 | put_unaligned_le64(fd->rspdma, &cmd_pkt->nvme_rsp_dseg_address); |
399 | cmd_pkt->nvme_rsp_dseg_address[1] = cpu_to_le32(MSD(fd->rspdma)); | ||
400 | 409 | ||
401 | /* NVME CNMD IU */ | 410 | /* NVME CNMD IU */ |
402 | cmd_pkt->nvme_cmnd_dseg_len = cpu_to_le16(fd->cmdlen); | 411 | cmd_pkt->nvme_cmnd_dseg_len = cpu_to_le16(fd->cmdlen); |
403 | cmd_pkt->nvme_cmnd_dseg_address[0] = cpu_to_le32(LSD(fd->cmddma)); | 412 | cmd_pkt->nvme_cmnd_dseg_address = cpu_to_le64(fd->cmddma); |
404 | cmd_pkt->nvme_cmnd_dseg_address[1] = cpu_to_le32(MSD(fd->cmddma)); | ||
405 | 413 | ||
406 | cmd_pkt->dseg_count = cpu_to_le16(tot_dsds); | 414 | cmd_pkt->dseg_count = cpu_to_le16(tot_dsds); |
407 | cmd_pkt->byte_count = cpu_to_le32(fd->payload_length); | 415 | cmd_pkt->byte_count = cpu_to_le32(fd->payload_length); |
408 | 416 | ||
409 | /* One DSD is available in the Command Type NVME IOCB */ | 417 | /* One DSD is available in the Command Type NVME IOCB */ |
410 | avail_dsds = 1; | 418 | avail_dsds = 1; |
411 | cur_dsd = (uint32_t *)&cmd_pkt->nvme_data_dseg_address[0]; | 419 | cur_dsd = &cmd_pkt->nvme_dsd; |
412 | sgl = fd->first_sgl; | 420 | sgl = fd->first_sgl; |
413 | 421 | ||
414 | /* Load data segments */ | 422 | /* Load data segments */ |
415 | for_each_sg(sgl, sg, tot_dsds, i) { | 423 | for_each_sg(sgl, sg, tot_dsds, i) { |
416 | dma_addr_t sle_dma; | ||
417 | cont_a64_entry_t *cont_pkt; | 424 | cont_a64_entry_t *cont_pkt; |
418 | 425 | ||
419 | /* Allocate additional continuation packets? */ | 426 | /* Allocate additional continuation packets? */ |
@@ -432,17 +439,14 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) | |||
432 | req->ring_ptr++; | 439 | req->ring_ptr++; |
433 | } | 440 | } |
434 | cont_pkt = (cont_a64_entry_t *)req->ring_ptr; | 441 | cont_pkt = (cont_a64_entry_t *)req->ring_ptr; |
435 | *((uint32_t *)(&cont_pkt->entry_type)) = | 442 | put_unaligned_le32(CONTINUE_A64_TYPE, |
436 | cpu_to_le32(CONTINUE_A64_TYPE); | 443 | &cont_pkt->entry_type); |
437 | 444 | ||
438 | cur_dsd = (uint32_t *)cont_pkt->dseg_0_address; | 445 | cur_dsd = cont_pkt->dsd; |
439 | avail_dsds = 5; | 446 | avail_dsds = ARRAY_SIZE(cont_pkt->dsd); |
440 | } | 447 | } |
441 | 448 | ||
442 | sle_dma = sg_dma_address(sg); | 449 | append_dsd64(&cur_dsd, sg); |
443 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
444 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
445 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
446 | avail_dsds--; | 450 | avail_dsds--; |
447 | } | 451 | } |
448 | 452 | ||
@@ -573,7 +577,7 @@ static struct nvme_fc_port_template qla_nvme_fc_transport = { | |||
573 | .fcp_io = qla_nvme_post_cmd, | 577 | .fcp_io = qla_nvme_post_cmd, |
574 | .fcp_abort = qla_nvme_fcp_abort, | 578 | .fcp_abort = qla_nvme_fcp_abort, |
575 | .max_hw_queues = 8, | 579 | .max_hw_queues = 8, |
576 | .max_sgl_segments = 128, | 580 | .max_sgl_segments = 1024, |
577 | .max_dif_sgl_segments = 64, | 581 | .max_dif_sgl_segments = 64, |
578 | .dma_boundary = 0xFFFFFFFF, | 582 | .dma_boundary = 0xFFFFFFFF, |
579 | .local_priv_sz = 8, | 583 | .local_priv_sz = 8, |
@@ -582,40 +586,11 @@ static struct nvme_fc_port_template qla_nvme_fc_transport = { | |||
582 | .fcprqst_priv_sz = sizeof(struct nvme_private), | 586 | .fcprqst_priv_sz = sizeof(struct nvme_private), |
583 | }; | 587 | }; |
584 | 588 | ||
585 | #define NVME_ABORT_POLLING_PERIOD 2 | ||
586 | static int qla_nvme_wait_on_command(srb_t *sp) | ||
587 | { | ||
588 | int ret = QLA_SUCCESS; | ||
589 | |||
590 | wait_event_timeout(sp->nvme_ls_waitq, (atomic_read(&sp->ref_count) > 1), | ||
591 | NVME_ABORT_POLLING_PERIOD*HZ); | ||
592 | |||
593 | if (atomic_read(&sp->ref_count) > 1) | ||
594 | ret = QLA_FUNCTION_FAILED; | ||
595 | |||
596 | return ret; | ||
597 | } | ||
598 | |||
599 | void qla_nvme_abort(struct qla_hw_data *ha, struct srb *sp, int res) | ||
600 | { | ||
601 | int rval; | ||
602 | |||
603 | if (ha->flags.fw_started) { | ||
604 | rval = ha->isp_ops->abort_command(sp); | ||
605 | if (!rval && !qla_nvme_wait_on_command(sp)) | ||
606 | ql_log(ql_log_warn, NULL, 0x2112, | ||
607 | "timed out waiting on sp=%p\n", sp); | ||
608 | } else { | ||
609 | sp->done(sp, res); | ||
610 | } | ||
611 | } | ||
612 | |||
613 | static void qla_nvme_unregister_remote_port(struct work_struct *work) | 589 | static void qla_nvme_unregister_remote_port(struct work_struct *work) |
614 | { | 590 | { |
615 | struct fc_port *fcport = container_of(work, struct fc_port, | 591 | struct fc_port *fcport = container_of(work, struct fc_port, |
616 | nvme_del_work); | 592 | nvme_del_work); |
617 | struct qla_nvme_rport *qla_rport, *trport; | 593 | struct qla_nvme_rport *qla_rport, *trport; |
618 | scsi_qla_host_t *base_vha; | ||
619 | 594 | ||
620 | if (!IS_ENABLED(CONFIG_NVME_FC)) | 595 | if (!IS_ENABLED(CONFIG_NVME_FC)) |
621 | return; | 596 | return; |
@@ -623,23 +598,19 @@ static void qla_nvme_unregister_remote_port(struct work_struct *work) | |||
623 | ql_log(ql_log_warn, NULL, 0x2112, | 598 | ql_log(ql_log_warn, NULL, 0x2112, |
624 | "%s: unregister remoteport on %p\n",__func__, fcport); | 599 | "%s: unregister remoteport on %p\n",__func__, fcport); |
625 | 600 | ||
626 | base_vha = pci_get_drvdata(fcport->vha->hw->pdev); | ||
627 | if (test_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags)) { | ||
628 | ql_dbg(ql_dbg_disc, fcport->vha, 0x2114, | ||
629 | "%s: Notify FC-NVMe transport, set devloss=0\n", | ||
630 | __func__); | ||
631 | |||
632 | nvme_fc_set_remoteport_devloss(fcport->nvme_remote_port, 0); | ||
633 | } | ||
634 | |||
635 | list_for_each_entry_safe(qla_rport, trport, | 601 | list_for_each_entry_safe(qla_rport, trport, |
636 | &fcport->vha->nvme_rport_list, list) { | 602 | &fcport->vha->nvme_rport_list, list) { |
637 | if (qla_rport->fcport == fcport) { | 603 | if (qla_rport->fcport == fcport) { |
638 | ql_log(ql_log_info, fcport->vha, 0x2113, | 604 | ql_log(ql_log_info, fcport->vha, 0x2113, |
639 | "%s: fcport=%p\n", __func__, fcport); | 605 | "%s: fcport=%p\n", __func__, fcport); |
606 | nvme_fc_set_remoteport_devloss | ||
607 | (fcport->nvme_remote_port, 0); | ||
640 | init_completion(&fcport->nvme_del_done); | 608 | init_completion(&fcport->nvme_del_done); |
641 | nvme_fc_unregister_remoteport( | 609 | if (nvme_fc_unregister_remoteport |
642 | fcport->nvme_remote_port); | 610 | (fcport->nvme_remote_port)) |
611 | ql_log(ql_log_info, fcport->vha, 0x2114, | ||
612 | "%s: Failed to unregister nvme_remote_port\n", | ||
613 | __func__); | ||
643 | wait_for_completion(&fcport->nvme_del_done); | 614 | wait_for_completion(&fcport->nvme_del_done); |
644 | break; | 615 | break; |
645 | } | 616 | } |
diff --git a/drivers/scsi/qla2xxx/qla_nvme.h b/drivers/scsi/qla2xxx/qla_nvme.h index da8dad5ad693..d3b8a6440113 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.h +++ b/drivers/scsi/qla2xxx/qla_nvme.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/nvme-fc-driver.h> | 13 | #include <linux/nvme-fc-driver.h> |
14 | 14 | ||
15 | #include "qla_def.h" | 15 | #include "qla_def.h" |
16 | #include "qla_dsd.h" | ||
16 | 17 | ||
17 | /* default dev loss time (seconds) before transport tears down ctrl */ | 18 | /* default dev loss time (seconds) before transport tears down ctrl */ |
18 | #define NVME_FC_DEV_LOSS_TMO 30 | 19 | #define NVME_FC_DEV_LOSS_TMO 30 |
@@ -64,16 +65,15 @@ struct cmd_nvme { | |||
64 | #define CF_WRITE_DATA BIT_0 | 65 | #define CF_WRITE_DATA BIT_0 |
65 | 66 | ||
66 | uint16_t nvme_cmnd_dseg_len; /* Data segment length. */ | 67 | uint16_t nvme_cmnd_dseg_len; /* Data segment length. */ |
67 | uint32_t nvme_cmnd_dseg_address[2]; /* Data segment address. */ | 68 | __le64 nvme_cmnd_dseg_address __packed;/* Data segment address. */ |
68 | uint32_t nvme_rsp_dseg_address[2]; /* Data segment address. */ | 69 | __le64 nvme_rsp_dseg_address __packed; /* Data segment address. */ |
69 | 70 | ||
70 | uint32_t byte_count; /* Total byte count. */ | 71 | uint32_t byte_count; /* Total byte count. */ |
71 | 72 | ||
72 | uint8_t port_id[3]; /* PortID of destination port. */ | 73 | uint8_t port_id[3]; /* PortID of destination port. */ |
73 | uint8_t vp_index; | 74 | uint8_t vp_index; |
74 | 75 | ||
75 | uint32_t nvme_data_dseg_address[2]; /* Data segment address. */ | 76 | struct dsd64 nvme_dsd; |
76 | uint32_t nvme_data_dseg_len; /* Data segment length. */ | ||
77 | }; | 77 | }; |
78 | 78 | ||
79 | #define PT_LS4_REQUEST 0x89 /* Link Service pass-through IOCB (request) */ | 79 | #define PT_LS4_REQUEST 0x89 /* Link Service pass-through IOCB (request) */ |
@@ -101,10 +101,7 @@ struct pt_ls4_request { | |||
101 | uint32_t rsvd3; | 101 | uint32_t rsvd3; |
102 | uint32_t rx_byte_count; | 102 | uint32_t rx_byte_count; |
103 | uint32_t tx_byte_count; | 103 | uint32_t tx_byte_count; |
104 | uint32_t dseg0_address[2]; | 104 | struct dsd64 dsd[2]; |
105 | uint32_t dseg0_len; | ||
106 | uint32_t dseg1_address[2]; | ||
107 | uint32_t dseg1_len; | ||
108 | }; | 105 | }; |
109 | 106 | ||
110 | #define PT_LS4_UNSOL 0x56 /* pass-up unsolicited rec FC-NVMe request */ | 107 | #define PT_LS4_UNSOL 0x56 /* pass-up unsolicited rec FC-NVMe request */ |
@@ -145,7 +142,6 @@ struct pt_ls4_rx_unsol { | |||
145 | int qla_nvme_register_hba(struct scsi_qla_host *); | 142 | int qla_nvme_register_hba(struct scsi_qla_host *); |
146 | int qla_nvme_register_remote(struct scsi_qla_host *, struct fc_port *); | 143 | int qla_nvme_register_remote(struct scsi_qla_host *, struct fc_port *); |
147 | void qla_nvme_delete(struct scsi_qla_host *); | 144 | void qla_nvme_delete(struct scsi_qla_host *); |
148 | void qla_nvme_abort(struct qla_hw_data *, struct srb *sp, int res); | ||
149 | void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *, struct pt_ls4_request *, | 145 | void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *, struct pt_ls4_request *, |
150 | struct req_que *); | 146 | struct req_que *); |
151 | void qla24xx_async_gffid_sp_done(void *, int); | 147 | void qla24xx_async_gffid_sp_done(void *, int); |
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index f2f54806f4da..c760ae354174 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c | |||
@@ -6,6 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
9 | #include <linux/io-64-nonatomic-lo-hi.h> | ||
9 | #include <linux/pci.h> | 10 | #include <linux/pci.h> |
10 | #include <linux/ratelimit.h> | 11 | #include <linux/ratelimit.h> |
11 | #include <linux/vmalloc.h> | 12 | #include <linux/vmalloc.h> |
@@ -608,6 +609,7 @@ qla82xx_pci_set_window(struct qla_hw_data *ha, unsigned long long addr) | |||
608 | } else if (addr_in_range(addr, QLA82XX_ADDR_OCM0, | 609 | } else if (addr_in_range(addr, QLA82XX_ADDR_OCM0, |
609 | QLA82XX_ADDR_OCM0_MAX)) { | 610 | QLA82XX_ADDR_OCM0_MAX)) { |
610 | unsigned int temp1; | 611 | unsigned int temp1; |
612 | |||
611 | if ((addr & 0x00ff800) == 0xff800) { | 613 | if ((addr & 0x00ff800) == 0xff800) { |
612 | ql_log(ql_log_warn, vha, 0xb004, | 614 | ql_log(ql_log_warn, vha, 0xb004, |
613 | "%s: QM access not handled.\n", __func__); | 615 | "%s: QM access not handled.\n", __func__); |
@@ -990,6 +992,7 @@ static int | |||
990 | qla82xx_read_status_reg(struct qla_hw_data *ha, uint32_t *val) | 992 | qla82xx_read_status_reg(struct qla_hw_data *ha, uint32_t *val) |
991 | { | 993 | { |
992 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | 994 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); |
995 | |||
993 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_RDSR); | 996 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_RDSR); |
994 | qla82xx_wait_rom_busy(ha); | 997 | qla82xx_wait_rom_busy(ha); |
995 | if (qla82xx_wait_rom_done(ha)) { | 998 | if (qla82xx_wait_rom_done(ha)) { |
@@ -1030,6 +1033,7 @@ static int | |||
1030 | qla82xx_flash_set_write_enable(struct qla_hw_data *ha) | 1033 | qla82xx_flash_set_write_enable(struct qla_hw_data *ha) |
1031 | { | 1034 | { |
1032 | uint32_t val; | 1035 | uint32_t val; |
1036 | |||
1033 | qla82xx_wait_rom_busy(ha); | 1037 | qla82xx_wait_rom_busy(ha); |
1034 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 0); | 1038 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 0); |
1035 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_WREN); | 1039 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_WREN); |
@@ -1047,6 +1051,7 @@ static int | |||
1047 | qla82xx_write_status_reg(struct qla_hw_data *ha, uint32_t val) | 1051 | qla82xx_write_status_reg(struct qla_hw_data *ha, uint32_t val) |
1048 | { | 1052 | { |
1049 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | 1053 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); |
1054 | |||
1050 | if (qla82xx_flash_set_write_enable(ha)) | 1055 | if (qla82xx_flash_set_write_enable(ha)) |
1051 | return -1; | 1056 | return -1; |
1052 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_WDATA, val); | 1057 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_WDATA, val); |
@@ -1063,6 +1068,7 @@ static int | |||
1063 | qla82xx_write_disable_flash(struct qla_hw_data *ha) | 1068 | qla82xx_write_disable_flash(struct qla_hw_data *ha) |
1064 | { | 1069 | { |
1065 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | 1070 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); |
1071 | |||
1066 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_WRDI); | 1072 | qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_WRDI); |
1067 | if (qla82xx_wait_rom_done(ha)) { | 1073 | if (qla82xx_wait_rom_done(ha)) { |
1068 | ql_log(ql_log_warn, vha, 0xb00f, | 1074 | ql_log(ql_log_warn, vha, 0xb00f, |
@@ -1435,6 +1441,7 @@ qla82xx_fw_load_from_flash(struct qla_hw_data *ha) | |||
1435 | long memaddr = BOOTLD_START; | 1441 | long memaddr = BOOTLD_START; |
1436 | u64 data; | 1442 | u64 data; |
1437 | u32 high, low; | 1443 | u32 high, low; |
1444 | |||
1438 | size = (IMAGE_START - BOOTLD_START) / 8; | 1445 | size = (IMAGE_START - BOOTLD_START) / 8; |
1439 | 1446 | ||
1440 | for (i = 0; i < size; i++) { | 1447 | for (i = 0; i < size; i++) { |
@@ -1757,11 +1764,14 @@ qla82xx_pci_config(scsi_qla_host_t *vha) | |||
1757 | * | 1764 | * |
1758 | * Returns 0 on success. | 1765 | * Returns 0 on success. |
1759 | */ | 1766 | */ |
1760 | void | 1767 | int |
1761 | qla82xx_reset_chip(scsi_qla_host_t *vha) | 1768 | qla82xx_reset_chip(scsi_qla_host_t *vha) |
1762 | { | 1769 | { |
1763 | struct qla_hw_data *ha = vha->hw; | 1770 | struct qla_hw_data *ha = vha->hw; |
1771 | |||
1764 | ha->isp_ops->disable_intrs(ha); | 1772 | ha->isp_ops->disable_intrs(ha); |
1773 | |||
1774 | return QLA_SUCCESS; | ||
1765 | } | 1775 | } |
1766 | 1776 | ||
1767 | void qla82xx_config_rings(struct scsi_qla_host *vha) | 1777 | void qla82xx_config_rings(struct scsi_qla_host *vha) |
@@ -1778,10 +1788,8 @@ void qla82xx_config_rings(struct scsi_qla_host *vha) | |||
1778 | icb->response_q_inpointer = cpu_to_le16(0); | 1788 | icb->response_q_inpointer = cpu_to_le16(0); |
1779 | icb->request_q_length = cpu_to_le16(req->length); | 1789 | icb->request_q_length = cpu_to_le16(req->length); |
1780 | icb->response_q_length = cpu_to_le16(rsp->length); | 1790 | icb->response_q_length = cpu_to_le16(rsp->length); |
1781 | icb->request_q_address[0] = cpu_to_le32(LSD(req->dma)); | 1791 | put_unaligned_le64(req->dma, &icb->request_q_address); |
1782 | icb->request_q_address[1] = cpu_to_le32(MSD(req->dma)); | 1792 | put_unaligned_le64(rsp->dma, &icb->response_q_address); |
1783 | icb->response_q_address[0] = cpu_to_le32(LSD(rsp->dma)); | ||
1784 | icb->response_q_address[1] = cpu_to_le32(MSD(rsp->dma)); | ||
1785 | 1793 | ||
1786 | WRT_REG_DWORD(®->req_q_out[0], 0); | 1794 | WRT_REG_DWORD(®->req_q_out[0], 0); |
1787 | WRT_REG_DWORD(®->rsp_q_in[0], 0); | 1795 | WRT_REG_DWORD(®->rsp_q_in[0], 0); |
@@ -1992,6 +2000,7 @@ qla82xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) | |||
1992 | uint16_t __iomem *wptr; | 2000 | uint16_t __iomem *wptr; |
1993 | struct qla_hw_data *ha = vha->hw; | 2001 | struct qla_hw_data *ha = vha->hw; |
1994 | struct device_reg_82xx __iomem *reg = &ha->iobase->isp82; | 2002 | struct device_reg_82xx __iomem *reg = &ha->iobase->isp82; |
2003 | |||
1995 | wptr = (uint16_t __iomem *)®->mailbox_out[1]; | 2004 | wptr = (uint16_t __iomem *)®->mailbox_out[1]; |
1996 | 2005 | ||
1997 | /* Load return mailbox registers. */ | 2006 | /* Load return mailbox registers. */ |
@@ -2028,7 +2037,7 @@ qla82xx_intr_handler(int irq, void *dev_id) | |||
2028 | unsigned long flags; | 2037 | unsigned long flags; |
2029 | unsigned long iter; | 2038 | unsigned long iter; |
2030 | uint32_t stat = 0; | 2039 | uint32_t stat = 0; |
2031 | uint16_t mb[4]; | 2040 | uint16_t mb[8]; |
2032 | 2041 | ||
2033 | rsp = (struct rsp_que *) dev_id; | 2042 | rsp = (struct rsp_que *) dev_id; |
2034 | if (!rsp) { | 2043 | if (!rsp) { |
@@ -2112,7 +2121,7 @@ qla82xx_msix_default(int irq, void *dev_id) | |||
2112 | unsigned long flags; | 2121 | unsigned long flags; |
2113 | uint32_t stat = 0; | 2122 | uint32_t stat = 0; |
2114 | uint32_t host_int = 0; | 2123 | uint32_t host_int = 0; |
2115 | uint16_t mb[4]; | 2124 | uint16_t mb[8]; |
2116 | 2125 | ||
2117 | rsp = (struct rsp_que *) dev_id; | 2126 | rsp = (struct rsp_que *) dev_id; |
2118 | if (!rsp) { | 2127 | if (!rsp) { |
@@ -2208,7 +2217,7 @@ qla82xx_poll(int irq, void *dev_id) | |||
2208 | int status = 0; | 2217 | int status = 0; |
2209 | uint32_t stat; | 2218 | uint32_t stat; |
2210 | uint32_t host_int = 0; | 2219 | uint32_t host_int = 0; |
2211 | uint16_t mb[4]; | 2220 | uint16_t mb[8]; |
2212 | unsigned long flags; | 2221 | unsigned long flags; |
2213 | 2222 | ||
2214 | rsp = (struct rsp_que *) dev_id; | 2223 | rsp = (struct rsp_que *) dev_id; |
@@ -2262,6 +2271,7 @@ void | |||
2262 | qla82xx_enable_intrs(struct qla_hw_data *ha) | 2271 | qla82xx_enable_intrs(struct qla_hw_data *ha) |
2263 | { | 2272 | { |
2264 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | 2273 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); |
2274 | |||
2265 | qla82xx_mbx_intr_enable(vha); | 2275 | qla82xx_mbx_intr_enable(vha); |
2266 | spin_lock_irq(&ha->hardware_lock); | 2276 | spin_lock_irq(&ha->hardware_lock); |
2267 | if (IS_QLA8044(ha)) | 2277 | if (IS_QLA8044(ha)) |
@@ -2276,6 +2286,7 @@ void | |||
2276 | qla82xx_disable_intrs(struct qla_hw_data *ha) | 2286 | qla82xx_disable_intrs(struct qla_hw_data *ha) |
2277 | { | 2287 | { |
2278 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | 2288 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); |
2289 | |||
2279 | qla82xx_mbx_intr_disable(vha); | 2290 | qla82xx_mbx_intr_disable(vha); |
2280 | spin_lock_irq(&ha->hardware_lock); | 2291 | spin_lock_irq(&ha->hardware_lock); |
2281 | if (IS_QLA8044(ha)) | 2292 | if (IS_QLA8044(ha)) |
@@ -2658,8 +2669,8 @@ done: | |||
2658 | /* | 2669 | /* |
2659 | * Address and length are byte address | 2670 | * Address and length are byte address |
2660 | */ | 2671 | */ |
2661 | uint8_t * | 2672 | void * |
2662 | qla82xx_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | 2673 | qla82xx_read_optrom_data(struct scsi_qla_host *vha, void *buf, |
2663 | uint32_t offset, uint32_t length) | 2674 | uint32_t offset, uint32_t length) |
2664 | { | 2675 | { |
2665 | scsi_block_requests(vha->host); | 2676 | scsi_block_requests(vha->host); |
@@ -2767,15 +2778,14 @@ write_done: | |||
2767 | } | 2778 | } |
2768 | 2779 | ||
2769 | int | 2780 | int |
2770 | qla82xx_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | 2781 | qla82xx_write_optrom_data(struct scsi_qla_host *vha, void *buf, |
2771 | uint32_t offset, uint32_t length) | 2782 | uint32_t offset, uint32_t length) |
2772 | { | 2783 | { |
2773 | int rval; | 2784 | int rval; |
2774 | 2785 | ||
2775 | /* Suspend HBA. */ | 2786 | /* Suspend HBA. */ |
2776 | scsi_block_requests(vha->host); | 2787 | scsi_block_requests(vha->host); |
2777 | rval = qla82xx_write_flash_data(vha, (uint32_t *)buf, offset, | 2788 | rval = qla82xx_write_flash_data(vha, buf, offset, length >> 2); |
2778 | length >> 2); | ||
2779 | scsi_unblock_requests(vha->host); | 2789 | scsi_unblock_requests(vha->host); |
2780 | 2790 | ||
2781 | /* Convert return ISP82xx to generic */ | 2791 | /* Convert return ISP82xx to generic */ |
@@ -4464,6 +4474,7 @@ qla82xx_beacon_on(struct scsi_qla_host *vha) | |||
4464 | 4474 | ||
4465 | int rval; | 4475 | int rval; |
4466 | struct qla_hw_data *ha = vha->hw; | 4476 | struct qla_hw_data *ha = vha->hw; |
4477 | |||
4467 | qla82xx_idc_lock(ha); | 4478 | qla82xx_idc_lock(ha); |
4468 | rval = qla82xx_mbx_beacon_ctl(vha, 1); | 4479 | rval = qla82xx_mbx_beacon_ctl(vha, 1); |
4469 | 4480 | ||
@@ -4484,6 +4495,7 @@ qla82xx_beacon_off(struct scsi_qla_host *vha) | |||
4484 | 4495 | ||
4485 | int rval; | 4496 | int rval; |
4486 | struct qla_hw_data *ha = vha->hw; | 4497 | struct qla_hw_data *ha = vha->hw; |
4498 | |||
4487 | qla82xx_idc_lock(ha); | 4499 | qla82xx_idc_lock(ha); |
4488 | rval = qla82xx_mbx_beacon_ctl(vha, 0); | 4500 | rval = qla82xx_mbx_beacon_ctl(vha, 0); |
4489 | 4501 | ||
diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h index 71a41093530e..3c7beef92c35 100644 --- a/drivers/scsi/qla2xxx/qla_nx.h +++ b/drivers/scsi/qla2xxx/qla_nx.h | |||
@@ -7,7 +7,7 @@ | |||
7 | #ifndef __QLA_NX_H | 7 | #ifndef __QLA_NX_H |
8 | #define __QLA_NX_H | 8 | #define __QLA_NX_H |
9 | 9 | ||
10 | #include <linux/io-64-nonatomic-lo-hi.h> | 10 | #include <scsi/scsi.h> |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * Following are the states of the Phantom. Phantom will set them and | 13 | * Following are the states of the Phantom. Phantom will set them and |
diff --git a/drivers/scsi/qla2xxx/qla_nx2.c b/drivers/scsi/qla2xxx/qla_nx2.c index fe856b602e03..369ac04d0454 100644 --- a/drivers/scsi/qla2xxx/qla_nx2.c +++ b/drivers/scsi/qla2xxx/qla_nx2.c | |||
@@ -559,12 +559,12 @@ exit_lock_error: | |||
559 | /* | 559 | /* |
560 | * Address and length are byte address | 560 | * Address and length are byte address |
561 | */ | 561 | */ |
562 | uint8_t * | 562 | void * |
563 | qla8044_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | 563 | qla8044_read_optrom_data(struct scsi_qla_host *vha, void *buf, |
564 | uint32_t offset, uint32_t length) | 564 | uint32_t offset, uint32_t length) |
565 | { | 565 | { |
566 | scsi_block_requests(vha->host); | 566 | scsi_block_requests(vha->host); |
567 | if (qla8044_read_flash_data(vha, (uint8_t *)buf, offset, length / 4) | 567 | if (qla8044_read_flash_data(vha, buf, offset, length / 4) |
568 | != QLA_SUCCESS) { | 568 | != QLA_SUCCESS) { |
569 | ql_log(ql_log_warn, vha, 0xb08d, | 569 | ql_log(ql_log_warn, vha, 0xb08d, |
570 | "%s: Failed to read from flash\n", | 570 | "%s: Failed to read from flash\n", |
@@ -3007,10 +3007,9 @@ qla8044_minidump_process_rddfe(struct scsi_qla_host *vha, | |||
3007 | uint16_t count; | 3007 | uint16_t count; |
3008 | uint32_t poll, mask, modify_mask; | 3008 | uint32_t poll, mask, modify_mask; |
3009 | uint32_t wait_count = 0; | 3009 | uint32_t wait_count = 0; |
3010 | |||
3011 | uint32_t *data_ptr = *d_ptr; | 3010 | uint32_t *data_ptr = *d_ptr; |
3012 | |||
3013 | struct qla8044_minidump_entry_rddfe *rddfe; | 3011 | struct qla8044_minidump_entry_rddfe *rddfe; |
3012 | |||
3014 | rddfe = (struct qla8044_minidump_entry_rddfe *) entry_hdr; | 3013 | rddfe = (struct qla8044_minidump_entry_rddfe *) entry_hdr; |
3015 | 3014 | ||
3016 | addr1 = rddfe->addr_1; | 3015 | addr1 = rddfe->addr_1; |
@@ -3797,7 +3796,7 @@ qla8044_write_flash_dword_mode(scsi_qla_host_t *vha, uint32_t *dwptr, | |||
3797 | } | 3796 | } |
3798 | 3797 | ||
3799 | int | 3798 | int |
3800 | qla8044_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | 3799 | qla8044_write_optrom_data(struct scsi_qla_host *vha, void *buf, |
3801 | uint32_t offset, uint32_t length) | 3800 | uint32_t offset, uint32_t length) |
3802 | { | 3801 | { |
3803 | int rval = QLA_FUNCTION_FAILED, i, burst_iter_count; | 3802 | int rval = QLA_FUNCTION_FAILED, i, burst_iter_count; |
@@ -3896,7 +3895,7 @@ qla8044_intr_handler(int irq, void *dev_id) | |||
3896 | unsigned long flags; | 3895 | unsigned long flags; |
3897 | unsigned long iter; | 3896 | unsigned long iter; |
3898 | uint32_t stat; | 3897 | uint32_t stat; |
3899 | uint16_t mb[4]; | 3898 | uint16_t mb[8]; |
3900 | uint32_t leg_int_ptr = 0, pf_bit; | 3899 | uint32_t leg_int_ptr = 0, pf_bit; |
3901 | 3900 | ||
3902 | rsp = (struct rsp_que *) dev_id; | 3901 | rsp = (struct rsp_que *) dev_id; |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 91f576d743fe..e1c82a0a9745 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -42,7 +42,7 @@ static struct kmem_cache *ctx_cachep; | |||
42 | /* | 42 | /* |
43 | * error level for logging | 43 | * error level for logging |
44 | */ | 44 | */ |
45 | int ql_errlev = ql_log_all; | 45 | uint ql_errlev = 0x8001; |
46 | 46 | ||
47 | static int ql2xenableclass2; | 47 | static int ql2xenableclass2; |
48 | module_param(ql2xenableclass2, int, S_IRUGO|S_IRUSR); | 48 | module_param(ql2xenableclass2, int, S_IRUGO|S_IRUSR); |
@@ -108,7 +108,7 @@ MODULE_PARM_DESC(ql2xshiftctondsd, | |||
108 | "Set to control shifting of command type processing " | 108 | "Set to control shifting of command type processing " |
109 | "based on total number of SG elements."); | 109 | "based on total number of SG elements."); |
110 | 110 | ||
111 | int ql2xfdmienable=1; | 111 | int ql2xfdmienable = 1; |
112 | module_param(ql2xfdmienable, int, S_IRUGO|S_IWUSR); | 112 | module_param(ql2xfdmienable, int, S_IRUGO|S_IWUSR); |
113 | module_param_named(fdmi, ql2xfdmienable, int, S_IRUGO|S_IWUSR); | 113 | module_param_named(fdmi, ql2xfdmienable, int, S_IRUGO|S_IWUSR); |
114 | MODULE_PARM_DESC(ql2xfdmienable, | 114 | MODULE_PARM_DESC(ql2xfdmienable, |
@@ -154,7 +154,7 @@ MODULE_PARM_DESC(ql2xenablehba_err_chk, | |||
154 | " 1 -- Error isolation enabled only for DIX Type 0\n" | 154 | " 1 -- Error isolation enabled only for DIX Type 0\n" |
155 | " 2 -- Error isolation enabled for all Types\n"); | 155 | " 2 -- Error isolation enabled for all Types\n"); |
156 | 156 | ||
157 | int ql2xiidmaenable=1; | 157 | int ql2xiidmaenable = 1; |
158 | module_param(ql2xiidmaenable, int, S_IRUGO); | 158 | module_param(ql2xiidmaenable, int, S_IRUGO); |
159 | MODULE_PARM_DESC(ql2xiidmaenable, | 159 | MODULE_PARM_DESC(ql2xiidmaenable, |
160 | "Enables iIDMA settings " | 160 | "Enables iIDMA settings " |
@@ -285,14 +285,14 @@ MODULE_PARM_DESC(qla2xuseresexchforels, | |||
285 | "Reserve 1/2 of emergency exchanges for ELS.\n" | 285 | "Reserve 1/2 of emergency exchanges for ELS.\n" |
286 | " 0 (default): disabled"); | 286 | " 0 (default): disabled"); |
287 | 287 | ||
288 | int ql2xprotmask; | 288 | static int ql2xprotmask; |
289 | module_param(ql2xprotmask, int, 0644); | 289 | module_param(ql2xprotmask, int, 0644); |
290 | MODULE_PARM_DESC(ql2xprotmask, | 290 | MODULE_PARM_DESC(ql2xprotmask, |
291 | "Override DIF/DIX protection capabilities mask\n" | 291 | "Override DIF/DIX protection capabilities mask\n" |
292 | "Default is 0 which sets protection mask based on " | 292 | "Default is 0 which sets protection mask based on " |
293 | "capabilities reported by HBA firmware.\n"); | 293 | "capabilities reported by HBA firmware.\n"); |
294 | 294 | ||
295 | int ql2xprotguard; | 295 | static int ql2xprotguard; |
296 | module_param(ql2xprotguard, int, 0644); | 296 | module_param(ql2xprotguard, int, 0644); |
297 | MODULE_PARM_DESC(ql2xprotguard, "Override choice of DIX checksum\n" | 297 | MODULE_PARM_DESC(ql2xprotguard, "Override choice of DIX checksum\n" |
298 | " 0 -- Let HBA firmware decide\n" | 298 | " 0 -- Let HBA firmware decide\n" |
@@ -306,58 +306,12 @@ MODULE_PARM_DESC(ql2xdifbundlinginternalbuffers, | |||
306 | "0 (Default). Based on check.\n" | 306 | "0 (Default). Based on check.\n" |
307 | "1 Force using internal buffers\n"); | 307 | "1 Force using internal buffers\n"); |
308 | 308 | ||
309 | /* | ||
310 | * SCSI host template entry points | ||
311 | */ | ||
312 | static int qla2xxx_slave_configure(struct scsi_device * device); | ||
313 | static int qla2xxx_slave_alloc(struct scsi_device *); | ||
314 | static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time); | ||
315 | static void qla2xxx_scan_start(struct Scsi_Host *); | ||
316 | static void qla2xxx_slave_destroy(struct scsi_device *); | ||
317 | static int qla2xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd); | ||
318 | static int qla2xxx_eh_abort(struct scsi_cmnd *); | ||
319 | static int qla2xxx_eh_device_reset(struct scsi_cmnd *); | ||
320 | static int qla2xxx_eh_target_reset(struct scsi_cmnd *); | ||
321 | static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); | ||
322 | static int qla2xxx_eh_host_reset(struct scsi_cmnd *); | ||
323 | |||
324 | static void qla2x00_clear_drv_active(struct qla_hw_data *); | 309 | static void qla2x00_clear_drv_active(struct qla_hw_data *); |
325 | static void qla2x00_free_device(scsi_qla_host_t *); | 310 | static void qla2x00_free_device(scsi_qla_host_t *); |
326 | static int qla2xxx_map_queues(struct Scsi_Host *shost); | 311 | static int qla2xxx_map_queues(struct Scsi_Host *shost); |
327 | static void qla2x00_destroy_deferred_work(struct qla_hw_data *); | 312 | static void qla2x00_destroy_deferred_work(struct qla_hw_data *); |
328 | 313 | ||
329 | 314 | ||
330 | struct scsi_host_template qla2xxx_driver_template = { | ||
331 | .module = THIS_MODULE, | ||
332 | .name = QLA2XXX_DRIVER_NAME, | ||
333 | .queuecommand = qla2xxx_queuecommand, | ||
334 | |||
335 | .eh_timed_out = fc_eh_timed_out, | ||
336 | .eh_abort_handler = qla2xxx_eh_abort, | ||
337 | .eh_device_reset_handler = qla2xxx_eh_device_reset, | ||
338 | .eh_target_reset_handler = qla2xxx_eh_target_reset, | ||
339 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, | ||
340 | .eh_host_reset_handler = qla2xxx_eh_host_reset, | ||
341 | |||
342 | .slave_configure = qla2xxx_slave_configure, | ||
343 | |||
344 | .slave_alloc = qla2xxx_slave_alloc, | ||
345 | .slave_destroy = qla2xxx_slave_destroy, | ||
346 | .scan_finished = qla2xxx_scan_finished, | ||
347 | .scan_start = qla2xxx_scan_start, | ||
348 | .change_queue_depth = scsi_change_queue_depth, | ||
349 | .map_queues = qla2xxx_map_queues, | ||
350 | .this_id = -1, | ||
351 | .cmd_per_lun = 3, | ||
352 | .sg_tablesize = SG_ALL, | ||
353 | |||
354 | .max_sectors = 0xFFFF, | ||
355 | .shost_attrs = qla2x00_host_attrs, | ||
356 | |||
357 | .supported_mode = MODE_INITIATOR, | ||
358 | .track_queue_depth = 1, | ||
359 | }; | ||
360 | |||
361 | static struct scsi_transport_template *qla2xxx_transport_template = NULL; | 315 | static struct scsi_transport_template *qla2xxx_transport_template = NULL; |
362 | struct scsi_transport_template *qla2xxx_transport_vport_template = NULL; | 316 | struct scsi_transport_template *qla2xxx_transport_vport_template = NULL; |
363 | 317 | ||
@@ -411,6 +365,7 @@ static void qla_init_base_qpair(struct scsi_qla_host *vha, struct req_que *req, | |||
411 | struct rsp_que *rsp) | 365 | struct rsp_que *rsp) |
412 | { | 366 | { |
413 | struct qla_hw_data *ha = vha->hw; | 367 | struct qla_hw_data *ha = vha->hw; |
368 | |||
414 | rsp->qpair = ha->base_qpair; | 369 | rsp->qpair = ha->base_qpair; |
415 | rsp->req = req; | 370 | rsp->req = req; |
416 | ha->base_qpair->hw = ha; | 371 | ha->base_qpair->hw = ha; |
@@ -427,7 +382,7 @@ static void qla_init_base_qpair(struct scsi_qla_host *vha, struct req_que *req, | |||
427 | qla_cpu_update(rsp->qpair, raw_smp_processor_id()); | 382 | qla_cpu_update(rsp->qpair, raw_smp_processor_id()); |
428 | ha->base_qpair->pdev = ha->pdev; | 383 | ha->base_qpair->pdev = ha->pdev; |
429 | 384 | ||
430 | if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) | 385 | if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) |
431 | ha->base_qpair->reqq_start_iocbs = qla_83xx_start_iocbs; | 386 | ha->base_qpair->reqq_start_iocbs = qla_83xx_start_iocbs; |
432 | } | 387 | } |
433 | 388 | ||
@@ -435,6 +390,7 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, | |||
435 | struct rsp_que *rsp) | 390 | struct rsp_que *rsp) |
436 | { | 391 | { |
437 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | 392 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); |
393 | |||
438 | ha->req_q_map = kcalloc(ha->max_req_queues, sizeof(struct req_que *), | 394 | ha->req_q_map = kcalloc(ha->max_req_queues, sizeof(struct req_que *), |
439 | GFP_KERNEL); | 395 | GFP_KERNEL); |
440 | if (!ha->req_q_map) { | 396 | if (!ha->req_q_map) { |
@@ -726,7 +682,7 @@ qla2x00_sp_free_dma(void *ptr) | |||
726 | } | 682 | } |
727 | 683 | ||
728 | if (!ctx) | 684 | if (!ctx) |
729 | goto end; | 685 | return; |
730 | 686 | ||
731 | if (sp->flags & SRB_CRC_CTX_DSD_VALID) { | 687 | if (sp->flags & SRB_CRC_CTX_DSD_VALID) { |
732 | /* List assured to be having elements */ | 688 | /* List assured to be having elements */ |
@@ -751,12 +707,6 @@ qla2x00_sp_free_dma(void *ptr) | |||
751 | ha->gbl_dsd_avail += ctx1->dsd_use_cnt; | 707 | ha->gbl_dsd_avail += ctx1->dsd_use_cnt; |
752 | mempool_free(ctx1, ha->ctx_mempool); | 708 | mempool_free(ctx1, ha->ctx_mempool); |
753 | } | 709 | } |
754 | |||
755 | end: | ||
756 | if (sp->type != SRB_NVME_CMD && sp->type != SRB_NVME_LS) { | ||
757 | CMD_SP(cmd) = NULL; | ||
758 | qla2x00_rel_sp(sp); | ||
759 | } | ||
760 | } | 710 | } |
761 | 711 | ||
762 | void | 712 | void |
@@ -764,22 +714,20 @@ qla2x00_sp_compl(void *ptr, int res) | |||
764 | { | 714 | { |
765 | srb_t *sp = ptr; | 715 | srb_t *sp = ptr; |
766 | struct scsi_cmnd *cmd = GET_CMD_SP(sp); | 716 | struct scsi_cmnd *cmd = GET_CMD_SP(sp); |
717 | struct completion *comp = sp->comp; | ||
767 | 718 | ||
768 | cmd->result = res; | 719 | if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0)) |
769 | |||
770 | if (atomic_read(&sp->ref_count) == 0) { | ||
771 | ql_dbg(ql_dbg_io, sp->vha, 0x3015, | ||
772 | "SP reference-count to ZERO -- sp=%p cmd=%p.\n", | ||
773 | sp, GET_CMD_SP(sp)); | ||
774 | if (ql2xextended_error_logging & ql_dbg_io) | ||
775 | WARN_ON(atomic_read(&sp->ref_count) == 0); | ||
776 | return; | ||
777 | } | ||
778 | if (!atomic_dec_and_test(&sp->ref_count)) | ||
779 | return; | 720 | return; |
780 | 721 | ||
722 | atomic_dec(&sp->ref_count); | ||
723 | |||
781 | sp->free(sp); | 724 | sp->free(sp); |
725 | cmd->result = res; | ||
726 | CMD_SP(cmd) = NULL; | ||
782 | cmd->scsi_done(cmd); | 727 | cmd->scsi_done(cmd); |
728 | if (comp) | ||
729 | complete(comp); | ||
730 | qla2x00_rel_sp(sp); | ||
783 | } | 731 | } |
784 | 732 | ||
785 | void | 733 | void |
@@ -802,7 +750,7 @@ qla2xxx_qpair_sp_free_dma(void *ptr) | |||
802 | } | 750 | } |
803 | 751 | ||
804 | if (!ctx) | 752 | if (!ctx) |
805 | goto end; | 753 | return; |
806 | 754 | ||
807 | if (sp->flags & SRB_CRC_CTX_DSD_VALID) { | 755 | if (sp->flags & SRB_CRC_CTX_DSD_VALID) { |
808 | /* List assured to be having elements */ | 756 | /* List assured to be having elements */ |
@@ -810,25 +758,8 @@ qla2xxx_qpair_sp_free_dma(void *ptr) | |||
810 | sp->flags &= ~SRB_CRC_CTX_DSD_VALID; | 758 | sp->flags &= ~SRB_CRC_CTX_DSD_VALID; |
811 | } | 759 | } |
812 | 760 | ||
813 | if (sp->flags & SRB_CRC_CTX_DMA_VALID) { | ||
814 | struct crc_context *ctx0 = ctx; | ||
815 | |||
816 | dma_pool_free(ha->dl_dma_pool, ctx, ctx0->crc_ctx_dma); | ||
817 | sp->flags &= ~SRB_CRC_CTX_DMA_VALID; | ||
818 | } | ||
819 | |||
820 | if (sp->flags & SRB_FCP_CMND_DMA_VALID) { | ||
821 | struct ct6_dsd *ctx1 = ctx; | ||
822 | dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd, | ||
823 | ctx1->fcp_cmnd_dma); | ||
824 | list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list); | ||
825 | ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt; | ||
826 | ha->gbl_dsd_avail += ctx1->dsd_use_cnt; | ||
827 | mempool_free(ctx1, ha->ctx_mempool); | ||
828 | sp->flags &= ~SRB_FCP_CMND_DMA_VALID; | ||
829 | } | ||
830 | if (sp->flags & SRB_DIF_BUNDL_DMA_VALID) { | 761 | if (sp->flags & SRB_DIF_BUNDL_DMA_VALID) { |
831 | struct crc_context *difctx = sp->u.scmd.ctx; | 762 | struct crc_context *difctx = ctx; |
832 | struct dsd_dma *dif_dsd, *nxt_dsd; | 763 | struct dsd_dma *dif_dsd, *nxt_dsd; |
833 | 764 | ||
834 | list_for_each_entry_safe(dif_dsd, nxt_dsd, | 765 | list_for_each_entry_safe(dif_dsd, nxt_dsd, |
@@ -863,9 +794,24 @@ qla2xxx_qpair_sp_free_dma(void *ptr) | |||
863 | sp->flags &= ~SRB_DIF_BUNDL_DMA_VALID; | 794 | sp->flags &= ~SRB_DIF_BUNDL_DMA_VALID; |
864 | } | 795 | } |
865 | 796 | ||
866 | end: | 797 | if (sp->flags & SRB_FCP_CMND_DMA_VALID) { |
867 | CMD_SP(cmd) = NULL; | 798 | struct ct6_dsd *ctx1 = ctx; |
868 | qla2xxx_rel_qpair_sp(sp->qpair, sp); | 799 | |
800 | dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd, | ||
801 | ctx1->fcp_cmnd_dma); | ||
802 | list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list); | ||
803 | ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt; | ||
804 | ha->gbl_dsd_avail += ctx1->dsd_use_cnt; | ||
805 | mempool_free(ctx1, ha->ctx_mempool); | ||
806 | sp->flags &= ~SRB_FCP_CMND_DMA_VALID; | ||
807 | } | ||
808 | |||
809 | if (sp->flags & SRB_CRC_CTX_DMA_VALID) { | ||
810 | struct crc_context *ctx0 = ctx; | ||
811 | |||
812 | dma_pool_free(ha->dl_dma_pool, ctx, ctx0->crc_ctx_dma); | ||
813 | sp->flags &= ~SRB_CRC_CTX_DMA_VALID; | ||
814 | } | ||
869 | } | 815 | } |
870 | 816 | ||
871 | void | 817 | void |
@@ -873,27 +819,22 @@ qla2xxx_qpair_sp_compl(void *ptr, int res) | |||
873 | { | 819 | { |
874 | srb_t *sp = ptr; | 820 | srb_t *sp = ptr; |
875 | struct scsi_cmnd *cmd = GET_CMD_SP(sp); | 821 | struct scsi_cmnd *cmd = GET_CMD_SP(sp); |
822 | struct completion *comp = sp->comp; | ||
876 | 823 | ||
877 | cmd->result = res; | 824 | if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0)) |
878 | |||
879 | if (atomic_read(&sp->ref_count) == 0) { | ||
880 | ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3079, | ||
881 | "SP reference-count to ZERO -- sp=%p cmd=%p.\n", | ||
882 | sp, GET_CMD_SP(sp)); | ||
883 | if (ql2xextended_error_logging & ql_dbg_io) | ||
884 | WARN_ON(atomic_read(&sp->ref_count) == 0); | ||
885 | return; | ||
886 | } | ||
887 | if (!atomic_dec_and_test(&sp->ref_count)) | ||
888 | return; | 825 | return; |
889 | 826 | ||
827 | atomic_dec(&sp->ref_count); | ||
828 | |||
890 | sp->free(sp); | 829 | sp->free(sp); |
830 | cmd->result = res; | ||
831 | CMD_SP(cmd) = NULL; | ||
891 | cmd->scsi_done(cmd); | 832 | cmd->scsi_done(cmd); |
833 | if (comp) | ||
834 | complete(comp); | ||
835 | qla2xxx_rel_qpair_sp(sp->qpair, sp); | ||
892 | } | 836 | } |
893 | 837 | ||
894 | /* If we are SP1 here, we need to still take and release the host_lock as SP1 | ||
895 | * does not have the changes necessary to avoid taking host->host_lock. | ||
896 | */ | ||
897 | static int | 838 | static int |
898 | qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) | 839 | qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) |
899 | { | 840 | { |
@@ -908,7 +849,8 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) | |||
908 | uint32_t tag; | 849 | uint32_t tag; |
909 | uint16_t hwq; | 850 | uint16_t hwq; |
910 | 851 | ||
911 | if (unlikely(test_bit(UNLOADING, &base_vha->dpc_flags))) { | 852 | if (unlikely(test_bit(UNLOADING, &base_vha->dpc_flags)) || |
853 | WARN_ON_ONCE(!rport)) { | ||
912 | cmd->result = DID_NO_CONNECT << 16; | 854 | cmd->result = DID_NO_CONNECT << 16; |
913 | goto qc24_fail_command; | 855 | goto qc24_fail_command; |
914 | } | 856 | } |
@@ -1031,7 +973,7 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, | |||
1031 | srb_t *sp; | 973 | srb_t *sp; |
1032 | int rval; | 974 | int rval; |
1033 | 975 | ||
1034 | rval = fc_remote_port_chkready(rport); | 976 | rval = rport ? fc_remote_port_chkready(rport) : FC_PORTSTATE_OFFLINE; |
1035 | if (rval) { | 977 | if (rval) { |
1036 | cmd->result = rval; | 978 | cmd->result = rval; |
1037 | ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3076, | 979 | ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3076, |
@@ -1272,7 +1214,7 @@ qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha) | |||
1272 | static int | 1214 | static int |
1273 | sp_get(struct srb *sp) | 1215 | sp_get(struct srb *sp) |
1274 | { | 1216 | { |
1275 | if (!refcount_inc_not_zero((refcount_t*)&sp->ref_count)) | 1217 | if (!refcount_inc_not_zero((refcount_t *)&sp->ref_count)) |
1276 | /* kref get fail */ | 1218 | /* kref get fail */ |
1277 | return ENXIO; | 1219 | return ENXIO; |
1278 | else | 1220 | else |
@@ -1332,7 +1274,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
1332 | unsigned int id; | 1274 | unsigned int id; |
1333 | uint64_t lun; | 1275 | uint64_t lun; |
1334 | unsigned long flags; | 1276 | unsigned long flags; |
1335 | int rval, wait = 0; | 1277 | int rval; |
1336 | struct qla_hw_data *ha = vha->hw; | 1278 | struct qla_hw_data *ha = vha->hw; |
1337 | struct qla_qpair *qpair; | 1279 | struct qla_qpair *qpair; |
1338 | 1280 | ||
@@ -1345,7 +1287,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
1345 | ret = fc_block_scsi_eh(cmd); | 1287 | ret = fc_block_scsi_eh(cmd); |
1346 | if (ret != 0) | 1288 | if (ret != 0) |
1347 | return ret; | 1289 | return ret; |
1348 | ret = SUCCESS; | ||
1349 | 1290 | ||
1350 | sp = (srb_t *) CMD_SP(cmd); | 1291 | sp = (srb_t *) CMD_SP(cmd); |
1351 | if (!sp) | 1292 | if (!sp) |
@@ -1356,7 +1297,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
1356 | return SUCCESS; | 1297 | return SUCCESS; |
1357 | 1298 | ||
1358 | spin_lock_irqsave(qpair->qp_lock_ptr, flags); | 1299 | spin_lock_irqsave(qpair->qp_lock_ptr, flags); |
1359 | if (!CMD_SP(cmd)) { | 1300 | if (sp->type != SRB_SCSI_CMD || GET_CMD_SP(sp) != cmd) { |
1360 | /* there's a chance an interrupt could clear | 1301 | /* there's a chance an interrupt could clear |
1361 | the ptr as part of done & free */ | 1302 | the ptr as part of done & free */ |
1362 | spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); | 1303 | spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); |
@@ -1377,58 +1318,31 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
1377 | "Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p handle=%x\n", | 1318 | "Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p handle=%x\n", |
1378 | vha->host_no, id, lun, sp, cmd, sp->handle); | 1319 | vha->host_no, id, lun, sp, cmd, sp->handle); |
1379 | 1320 | ||
1380 | /* Get a reference to the sp and drop the lock.*/ | ||
1381 | |||
1382 | rval = ha->isp_ops->abort_command(sp); | 1321 | rval = ha->isp_ops->abort_command(sp); |
1383 | if (rval) { | 1322 | ql_dbg(ql_dbg_taskm, vha, 0x8003, |
1384 | if (rval == QLA_FUNCTION_PARAMETER_ERROR) | 1323 | "Abort command mbx cmd=%p, rval=%x.\n", cmd, rval); |
1385 | ret = SUCCESS; | ||
1386 | else | ||
1387 | ret = FAILED; | ||
1388 | |||
1389 | ql_dbg(ql_dbg_taskm, vha, 0x8003, | ||
1390 | "Abort command mbx failed cmd=%p, rval=%x.\n", cmd, rval); | ||
1391 | } else { | ||
1392 | ql_dbg(ql_dbg_taskm, vha, 0x8004, | ||
1393 | "Abort command mbx success cmd=%p.\n", cmd); | ||
1394 | wait = 1; | ||
1395 | } | ||
1396 | |||
1397 | spin_lock_irqsave(qpair->qp_lock_ptr, flags); | ||
1398 | /* | ||
1399 | * Clear the slot in the oustanding_cmds array if we can't find the | ||
1400 | * command to reclaim the resources. | ||
1401 | */ | ||
1402 | if (rval == QLA_FUNCTION_PARAMETER_ERROR) | ||
1403 | vha->req->outstanding_cmds[sp->handle] = NULL; | ||
1404 | 1324 | ||
1405 | /* | 1325 | switch (rval) { |
1406 | * sp->done will do ref_count-- | 1326 | case QLA_SUCCESS: |
1407 | * sp_get() took an extra count above | 1327 | /* |
1408 | */ | 1328 | * The command has been aborted. That means that the firmware |
1409 | sp->done(sp, DID_RESET << 16); | 1329 | * won't report a completion. |
1410 | 1330 | */ | |
1411 | /* Did the command return during mailbox execution? */ | 1331 | sp->done(sp, DID_ABORT << 16); |
1412 | if (ret == FAILED && !CMD_SP(cmd)) | ||
1413 | ret = SUCCESS; | 1332 | ret = SUCCESS; |
1414 | 1333 | break; | |
1415 | if (!CMD_SP(cmd)) | 1334 | default: |
1416 | wait = 0; | 1335 | /* |
1417 | 1336 | * Either abort failed or abort and completion raced. Let | |
1418 | spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); | 1337 | * the SCSI core retry the abort in the former case. |
1419 | 1338 | */ | |
1420 | /* Wait for the command to be returned. */ | 1339 | ret = FAILED; |
1421 | if (wait) { | 1340 | break; |
1422 | if (qla2x00_eh_wait_on_command(cmd) != QLA_SUCCESS) { | ||
1423 | ql_log(ql_log_warn, vha, 0x8006, | ||
1424 | "Abort handler timed out cmd=%p.\n", cmd); | ||
1425 | ret = FAILED; | ||
1426 | } | ||
1427 | } | 1341 | } |
1428 | 1342 | ||
1429 | ql_log(ql_log_info, vha, 0x801c, | 1343 | ql_log(ql_log_info, vha, 0x801c, |
1430 | "Abort command issued nexus=%ld:%d:%llu -- %d %x.\n", | 1344 | "Abort command issued nexus=%ld:%d:%llu -- %x.\n", |
1431 | vha->host_no, id, lun, wait, ret); | 1345 | vha->host_no, id, lun, ret); |
1432 | 1346 | ||
1433 | return ret; | 1347 | return ret; |
1434 | } | 1348 | } |
@@ -1804,42 +1718,34 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res, | |||
1804 | __releases(qp->qp_lock_ptr) | 1718 | __releases(qp->qp_lock_ptr) |
1805 | __acquires(qp->qp_lock_ptr) | 1719 | __acquires(qp->qp_lock_ptr) |
1806 | { | 1720 | { |
1721 | DECLARE_COMPLETION_ONSTACK(comp); | ||
1807 | scsi_qla_host_t *vha = qp->vha; | 1722 | scsi_qla_host_t *vha = qp->vha; |
1808 | struct qla_hw_data *ha = vha->hw; | 1723 | struct qla_hw_data *ha = vha->hw; |
1724 | int rval; | ||
1809 | 1725 | ||
1810 | if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS) { | 1726 | if (sp_get(sp)) |
1811 | if (!sp_get(sp)) { | 1727 | return; |
1812 | /* got sp */ | ||
1813 | spin_unlock_irqrestore(qp->qp_lock_ptr, *flags); | ||
1814 | qla_nvme_abort(ha, sp, res); | ||
1815 | spin_lock_irqsave(qp->qp_lock_ptr, *flags); | ||
1816 | } | ||
1817 | } else if (GET_CMD_SP(sp) && !ha->flags.eeh_busy && | ||
1818 | !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && | ||
1819 | !qla2x00_isp_reg_stat(ha) && sp->type == SRB_SCSI_CMD) { | ||
1820 | /* | ||
1821 | * Don't abort commands in adapter during EEH recovery as it's | ||
1822 | * not accessible/responding. | ||
1823 | * | ||
1824 | * Get a reference to the sp and drop the lock. The reference | ||
1825 | * ensures this sp->done() call and not the call in | ||
1826 | * qla2xxx_eh_abort() ends the SCSI cmd (with result 'res'). | ||
1827 | */ | ||
1828 | if (!sp_get(sp)) { | ||
1829 | int status; | ||
1830 | 1728 | ||
1831 | spin_unlock_irqrestore(qp->qp_lock_ptr, *flags); | 1729 | if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS || |
1832 | status = qla2xxx_eh_abort(GET_CMD_SP(sp)); | 1730 | (sp->type == SRB_SCSI_CMD && !ha->flags.eeh_busy && |
1833 | spin_lock_irqsave(qp->qp_lock_ptr, *flags); | 1731 | !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && |
1834 | /* | 1732 | !qla2x00_isp_reg_stat(ha))) { |
1835 | * Get rid of extra reference caused | 1733 | sp->comp = ∁ |
1836 | * by early exit from qla2xxx_eh_abort | 1734 | rval = ha->isp_ops->abort_command(sp); |
1837 | */ | 1735 | spin_unlock_irqrestore(qp->qp_lock_ptr, *flags); |
1838 | if (status == FAST_IO_FAIL) | 1736 | |
1839 | atomic_dec(&sp->ref_count); | 1737 | switch (rval) { |
1738 | case QLA_SUCCESS: | ||
1739 | sp->done(sp, res); | ||
1740 | break; | ||
1741 | case QLA_FUNCTION_PARAMETER_ERROR: | ||
1742 | wait_for_completion(&comp); | ||
1743 | break; | ||
1840 | } | 1744 | } |
1745 | |||
1746 | spin_lock_irqsave(qp->qp_lock_ptr, *flags); | ||
1747 | sp->comp = NULL; | ||
1841 | } | 1748 | } |
1842 | sp->done(sp, res); | ||
1843 | } | 1749 | } |
1844 | 1750 | ||
1845 | static void | 1751 | static void |
@@ -1875,15 +1781,10 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) | |||
1875 | continue; | 1781 | continue; |
1876 | } | 1782 | } |
1877 | cmd = (struct qla_tgt_cmd *)sp; | 1783 | cmd = (struct qla_tgt_cmd *)sp; |
1878 | qlt_abort_cmd_on_host_reset(cmd->vha, cmd); | 1784 | cmd->aborted = 1; |
1879 | break; | 1785 | break; |
1880 | case TYPE_TGT_TMCMD: | 1786 | case TYPE_TGT_TMCMD: |
1881 | /* | 1787 | /* Skip task management functions. */ |
1882 | * Currently, only ABTS response gets on the | ||
1883 | * outstanding_cmds[] | ||
1884 | */ | ||
1885 | ha->tgt.tgt_ops->free_mcmd( | ||
1886 | (struct qla_tgt_mgmt_cmd *)sp); | ||
1887 | break; | 1788 | break; |
1888 | default: | 1789 | default: |
1889 | break; | 1790 | break; |
@@ -2753,6 +2654,24 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha) | |||
2753 | ha->device_type |= DT_T10_PI; | 2654 | ha->device_type |= DT_T10_PI; |
2754 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | 2655 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
2755 | break; | 2656 | break; |
2657 | case PCI_DEVICE_ID_QLOGIC_ISP2081: | ||
2658 | case PCI_DEVICE_ID_QLOGIC_ISP2089: | ||
2659 | ha->isp_type |= DT_ISP2081; | ||
2660 | ha->device_type |= DT_ZIO_SUPPORTED; | ||
2661 | ha->device_type |= DT_FWI2; | ||
2662 | ha->device_type |= DT_IIDMA; | ||
2663 | ha->device_type |= DT_T10_PI; | ||
2664 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | ||
2665 | break; | ||
2666 | case PCI_DEVICE_ID_QLOGIC_ISP2281: | ||
2667 | case PCI_DEVICE_ID_QLOGIC_ISP2289: | ||
2668 | ha->isp_type |= DT_ISP2281; | ||
2669 | ha->device_type |= DT_ZIO_SUPPORTED; | ||
2670 | ha->device_type |= DT_FWI2; | ||
2671 | ha->device_type |= DT_IIDMA; | ||
2672 | ha->device_type |= DT_T10_PI; | ||
2673 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | ||
2674 | break; | ||
2756 | } | 2675 | } |
2757 | 2676 | ||
2758 | if (IS_QLA82XX(ha)) | 2677 | if (IS_QLA82XX(ha)) |
@@ -2760,7 +2679,8 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha) | |||
2760 | else { | 2679 | else { |
2761 | /* Get adapter physical port no from interrupt pin register. */ | 2680 | /* Get adapter physical port no from interrupt pin register. */ |
2762 | pci_read_config_byte(ha->pdev, PCI_INTERRUPT_PIN, &ha->port_no); | 2681 | pci_read_config_byte(ha->pdev, PCI_INTERRUPT_PIN, &ha->port_no); |
2763 | if (IS_QLA27XX(ha)) | 2682 | if (IS_QLA25XX(ha) || IS_QLA2031(ha) || |
2683 | IS_QLA27XX(ha) || IS_QLA28XX(ha)) | ||
2764 | ha->port_no--; | 2684 | ha->port_no--; |
2765 | else | 2685 | else |
2766 | ha->port_no = !(ha->port_no & 1); | 2686 | ha->port_no = !(ha->port_no & 1); |
@@ -2857,7 +2777,11 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2857 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044 || | 2777 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044 || |
2858 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2071 || | 2778 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2071 || |
2859 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2271 || | 2779 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2271 || |
2860 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2261) { | 2780 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2261 || |
2781 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2081 || | ||
2782 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2281 || | ||
2783 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2089 || | ||
2784 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2289) { | ||
2861 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | 2785 | bars = pci_select_bars(pdev, IORESOURCE_MEM); |
2862 | mem_only = 1; | 2786 | mem_only = 1; |
2863 | ql_dbg_pci(ql_dbg_init, pdev, 0x0007, | 2787 | ql_dbg_pci(ql_dbg_init, pdev, 0x0007, |
@@ -2877,6 +2801,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2877 | /* This may fail but that's ok */ | 2801 | /* This may fail but that's ok */ |
2878 | pci_enable_pcie_error_reporting(pdev); | 2802 | pci_enable_pcie_error_reporting(pdev); |
2879 | 2803 | ||
2804 | /* Turn off T10-DIF when FC-NVMe is enabled */ | ||
2805 | if (ql2xnvmeenable) | ||
2806 | ql2xenabledif = 0; | ||
2807 | |||
2880 | ha = kzalloc(sizeof(struct qla_hw_data), GFP_KERNEL); | 2808 | ha = kzalloc(sizeof(struct qla_hw_data), GFP_KERNEL); |
2881 | if (!ha) { | 2809 | if (!ha) { |
2882 | ql_log_pci(ql_log_fatal, pdev, 0x0009, | 2810 | ql_log_pci(ql_log_fatal, pdev, 0x0009, |
@@ -2906,7 +2834,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2906 | 2834 | ||
2907 | /* Set EEH reset type to fundamental if required by hba */ | 2835 | /* Set EEH reset type to fundamental if required by hba */ |
2908 | if (IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha) || | 2836 | if (IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha) || |
2909 | IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 2837 | IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
2910 | pdev->needs_freset = 1; | 2838 | pdev->needs_freset = 1; |
2911 | 2839 | ||
2912 | ha->prev_topology = 0; | 2840 | ha->prev_topology = 0; |
@@ -3085,6 +3013,23 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
3085 | ha->flash_data_off = FARX_ACCESS_FLASH_DATA_81XX; | 3013 | ha->flash_data_off = FARX_ACCESS_FLASH_DATA_81XX; |
3086 | ha->nvram_conf_off = ~0; | 3014 | ha->nvram_conf_off = ~0; |
3087 | ha->nvram_data_off = ~0; | 3015 | ha->nvram_data_off = ~0; |
3016 | } else if (IS_QLA28XX(ha)) { | ||
3017 | ha->portnum = PCI_FUNC(ha->pdev->devfn); | ||
3018 | ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400; | ||
3019 | ha->mbx_count = MAILBOX_REGISTER_COUNT; | ||
3020 | req_length = REQUEST_ENTRY_CNT_24XX; | ||
3021 | rsp_length = RESPONSE_ENTRY_CNT_2300; | ||
3022 | ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX; | ||
3023 | ha->max_loop_id = SNS_LAST_LOOP_ID_2300; | ||
3024 | ha->init_cb_size = sizeof(struct mid_init_cb_81xx); | ||
3025 | ha->gid_list_info_size = 8; | ||
3026 | ha->optrom_size = OPTROM_SIZE_28XX; | ||
3027 | ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX; | ||
3028 | ha->isp_ops = &qla27xx_isp_ops; | ||
3029 | ha->flash_conf_off = FARX_ACCESS_FLASH_CONF_28XX; | ||
3030 | ha->flash_data_off = FARX_ACCESS_FLASH_DATA_28XX; | ||
3031 | ha->nvram_conf_off = ~0; | ||
3032 | ha->nvram_data_off = ~0; | ||
3088 | } | 3033 | } |
3089 | 3034 | ||
3090 | ql_dbg_pci(ql_dbg_init, pdev, 0x001e, | 3035 | ql_dbg_pci(ql_dbg_init, pdev, 0x001e, |
@@ -3250,7 +3195,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
3250 | req->req_q_out = &ha->iobase->isp24.req_q_out; | 3195 | req->req_q_out = &ha->iobase->isp24.req_q_out; |
3251 | rsp->rsp_q_in = &ha->iobase->isp24.rsp_q_in; | 3196 | rsp->rsp_q_in = &ha->iobase->isp24.rsp_q_in; |
3252 | rsp->rsp_q_out = &ha->iobase->isp24.rsp_q_out; | 3197 | rsp->rsp_q_out = &ha->iobase->isp24.rsp_q_out; |
3253 | if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 3198 | if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
3199 | IS_QLA28XX(ha)) { | ||
3254 | req->req_q_in = &ha->mqiobase->isp25mq.req_q_in; | 3200 | req->req_q_in = &ha->mqiobase->isp25mq.req_q_in; |
3255 | req->req_q_out = &ha->mqiobase->isp25mq.req_q_out; | 3201 | req->req_q_out = &ha->mqiobase->isp25mq.req_q_out; |
3256 | rsp->rsp_q_in = &ha->mqiobase->isp25mq.rsp_q_in; | 3202 | rsp->rsp_q_in = &ha->mqiobase->isp25mq.rsp_q_in; |
@@ -3395,6 +3341,7 @@ skip_dpc: | |||
3395 | if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { | 3341 | if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { |
3396 | if (ha->fw_attributes & BIT_4) { | 3342 | if (ha->fw_attributes & BIT_4) { |
3397 | int prot = 0, guard; | 3343 | int prot = 0, guard; |
3344 | |||
3398 | base_vha->flags.difdix_supported = 1; | 3345 | base_vha->flags.difdix_supported = 1; |
3399 | ql_dbg(ql_dbg_init, base_vha, 0x00f1, | 3346 | ql_dbg(ql_dbg_init, base_vha, 0x00f1, |
3400 | "Registering for DIF/DIX type 1 and 3 protection.\n"); | 3347 | "Registering for DIF/DIX type 1 and 3 protection.\n"); |
@@ -3576,7 +3523,8 @@ qla2x00_shutdown(struct pci_dev *pdev) | |||
3576 | if (ha->eft) | 3523 | if (ha->eft) |
3577 | qla2x00_disable_eft_trace(vha); | 3524 | qla2x00_disable_eft_trace(vha); |
3578 | 3525 | ||
3579 | if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) { | 3526 | if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || |
3527 | IS_QLA28XX(ha)) { | ||
3580 | if (ha->flags.fw_started) | 3528 | if (ha->flags.fw_started) |
3581 | qla2x00_abort_isp_cleanup(vha); | 3529 | qla2x00_abort_isp_cleanup(vha); |
3582 | } else { | 3530 | } else { |
@@ -3681,7 +3629,8 @@ qla2x00_unmap_iobases(struct qla_hw_data *ha) | |||
3681 | if (ha->mqiobase) | 3629 | if (ha->mqiobase) |
3682 | iounmap(ha->mqiobase); | 3630 | iounmap(ha->mqiobase); |
3683 | 3631 | ||
3684 | if ((IS_QLA83XX(ha) || IS_QLA27XX(ha)) && ha->msixbase) | 3632 | if ((IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) && |
3633 | ha->msixbase) | ||
3685 | iounmap(ha->msixbase); | 3634 | iounmap(ha->msixbase); |
3686 | } | 3635 | } |
3687 | } | 3636 | } |
@@ -3732,7 +3681,8 @@ qla2x00_remove_one(struct pci_dev *pdev) | |||
3732 | } | 3681 | } |
3733 | qla2x00_wait_for_hba_ready(base_vha); | 3682 | qla2x00_wait_for_hba_ready(base_vha); |
3734 | 3683 | ||
3735 | if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) { | 3684 | if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || |
3685 | IS_QLA28XX(ha)) { | ||
3736 | if (ha->flags.fw_started) | 3686 | if (ha->flags.fw_started) |
3737 | qla2x00_abort_isp_cleanup(base_vha); | 3687 | qla2x00_abort_isp_cleanup(base_vha); |
3738 | } else if (!IS_QLAFX00(ha)) { | 3688 | } else if (!IS_QLAFX00(ha)) { |
@@ -3770,8 +3720,6 @@ qla2x00_remove_one(struct pci_dev *pdev) | |||
3770 | 3720 | ||
3771 | qla2x00_delete_all_vps(ha, base_vha); | 3721 | qla2x00_delete_all_vps(ha, base_vha); |
3772 | 3722 | ||
3773 | qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16); | ||
3774 | |||
3775 | qla2x00_dfs_remove(base_vha); | 3723 | qla2x00_dfs_remove(base_vha); |
3776 | 3724 | ||
3777 | qla84xx_put_chip(base_vha); | 3725 | qla84xx_put_chip(base_vha); |
@@ -3860,11 +3808,8 @@ void qla2x00_free_fcports(struct scsi_qla_host *vha) | |||
3860 | { | 3808 | { |
3861 | fc_port_t *fcport, *tfcport; | 3809 | fc_port_t *fcport, *tfcport; |
3862 | 3810 | ||
3863 | list_for_each_entry_safe(fcport, tfcport, &vha->vp_fcports, list) { | 3811 | list_for_each_entry_safe(fcport, tfcport, &vha->vp_fcports, list) |
3864 | list_del(&fcport->list); | 3812 | qla2x00_free_fcport(fcport); |
3865 | qla2x00_clear_loop_id(fcport); | ||
3866 | kfree(fcport); | ||
3867 | } | ||
3868 | } | 3813 | } |
3869 | 3814 | ||
3870 | static inline void | 3815 | static inline void |
@@ -3889,6 +3834,7 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
3889 | qla2xxx_wake_dpc(base_vha); | 3834 | qla2xxx_wake_dpc(base_vha); |
3890 | } else { | 3835 | } else { |
3891 | int now; | 3836 | int now; |
3837 | |||
3892 | if (rport) { | 3838 | if (rport) { |
3893 | ql_dbg(ql_dbg_disc, fcport->vha, 0x2109, | 3839 | ql_dbg(ql_dbg_disc, fcport->vha, 0x2109, |
3894 | "%s %8phN. rport %p roles %x\n", | 3840 | "%s %8phN. rport %p roles %x\n", |
@@ -3980,6 +3926,19 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer) | |||
3980 | } | 3926 | } |
3981 | } | 3927 | } |
3982 | 3928 | ||
3929 | static void qla2x00_set_reserved_loop_ids(struct qla_hw_data *ha) | ||
3930 | { | ||
3931 | int i; | ||
3932 | |||
3933 | if (IS_FWI2_CAPABLE(ha)) | ||
3934 | return; | ||
3935 | |||
3936 | for (i = 0; i < SNS_FIRST_LOOP_ID; i++) | ||
3937 | set_bit(i, ha->loop_id_map); | ||
3938 | set_bit(MANAGEMENT_SERVER, ha->loop_id_map); | ||
3939 | set_bit(BROADCAST, ha->loop_id_map); | ||
3940 | } | ||
3941 | |||
3983 | /* | 3942 | /* |
3984 | * qla2x00_mem_alloc | 3943 | * qla2x00_mem_alloc |
3985 | * Allocates adapter memory. | 3944 | * Allocates adapter memory. |
@@ -4222,7 +4181,8 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, | |||
4222 | ha->npiv_info = NULL; | 4181 | ha->npiv_info = NULL; |
4223 | 4182 | ||
4224 | /* Get consistent memory allocated for EX-INIT-CB. */ | 4183 | /* Get consistent memory allocated for EX-INIT-CB. */ |
4225 | if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) { | 4184 | if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || |
4185 | IS_QLA28XX(ha)) { | ||
4226 | ha->ex_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, | 4186 | ha->ex_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, |
4227 | &ha->ex_init_cb_dma); | 4187 | &ha->ex_init_cb_dma); |
4228 | if (!ha->ex_init_cb) | 4188 | if (!ha->ex_init_cb) |
@@ -4265,8 +4225,20 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, | |||
4265 | goto fail_sfp_data; | 4225 | goto fail_sfp_data; |
4266 | } | 4226 | } |
4267 | 4227 | ||
4228 | ha->flt = dma_alloc_coherent(&ha->pdev->dev, | ||
4229 | sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE, &ha->flt_dma, | ||
4230 | GFP_KERNEL); | ||
4231 | if (!ha->flt) { | ||
4232 | ql_dbg_pci(ql_dbg_init, ha->pdev, 0x011b, | ||
4233 | "Unable to allocate memory for FLT.\n"); | ||
4234 | goto fail_flt_buffer; | ||
4235 | } | ||
4236 | |||
4268 | return 0; | 4237 | return 0; |
4269 | 4238 | ||
4239 | fail_flt_buffer: | ||
4240 | dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE, | ||
4241 | ha->sfp_data, ha->sfp_data_dma); | ||
4270 | fail_sfp_data: | 4242 | fail_sfp_data: |
4271 | kfree(ha->loop_id_map); | 4243 | kfree(ha->loop_id_map); |
4272 | fail_loop_id_map: | 4244 | fail_loop_id_map: |
@@ -4602,6 +4574,9 @@ qla2x00_free_exchoffld_buffer(struct qla_hw_data *ha) | |||
4602 | static void | 4574 | static void |
4603 | qla2x00_free_fw_dump(struct qla_hw_data *ha) | 4575 | qla2x00_free_fw_dump(struct qla_hw_data *ha) |
4604 | { | 4576 | { |
4577 | struct fwdt *fwdt = ha->fwdt; | ||
4578 | uint j; | ||
4579 | |||
4605 | if (ha->fce) | 4580 | if (ha->fce) |
4606 | dma_free_coherent(&ha->pdev->dev, | 4581 | dma_free_coherent(&ha->pdev->dev, |
4607 | FCE_SIZE, ha->fce, ha->fce_dma); | 4582 | FCE_SIZE, ha->fce, ha->fce_dma); |
@@ -4612,8 +4587,6 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha) | |||
4612 | 4587 | ||
4613 | if (ha->fw_dump) | 4588 | if (ha->fw_dump) |
4614 | vfree(ha->fw_dump); | 4589 | vfree(ha->fw_dump); |
4615 | if (ha->fw_dump_template) | ||
4616 | vfree(ha->fw_dump_template); | ||
4617 | 4590 | ||
4618 | ha->fce = NULL; | 4591 | ha->fce = NULL; |
4619 | ha->fce_dma = 0; | 4592 | ha->fce_dma = 0; |
@@ -4624,8 +4597,13 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha) | |||
4624 | ha->fw_dump_reading = 0; | 4597 | ha->fw_dump_reading = 0; |
4625 | ha->fw_dump = NULL; | 4598 | ha->fw_dump = NULL; |
4626 | ha->fw_dump_len = 0; | 4599 | ha->fw_dump_len = 0; |
4627 | ha->fw_dump_template = NULL; | 4600 | |
4628 | ha->fw_dump_template_len = 0; | 4601 | for (j = 0; j < 2; j++, fwdt++) { |
4602 | if (fwdt->template) | ||
4603 | vfree(fwdt->template); | ||
4604 | fwdt->template = NULL; | ||
4605 | fwdt->length = 0; | ||
4606 | } | ||
4629 | } | 4607 | } |
4630 | 4608 | ||
4631 | /* | 4609 | /* |
@@ -4643,44 +4621,68 @@ qla2x00_mem_free(struct qla_hw_data *ha) | |||
4643 | if (ha->mctp_dump) | 4621 | if (ha->mctp_dump) |
4644 | dma_free_coherent(&ha->pdev->dev, MCTP_DUMP_SIZE, ha->mctp_dump, | 4622 | dma_free_coherent(&ha->pdev->dev, MCTP_DUMP_SIZE, ha->mctp_dump, |
4645 | ha->mctp_dump_dma); | 4623 | ha->mctp_dump_dma); |
4624 | ha->mctp_dump = NULL; | ||
4646 | 4625 | ||
4647 | mempool_destroy(ha->srb_mempool); | 4626 | mempool_destroy(ha->srb_mempool); |
4627 | ha->srb_mempool = NULL; | ||
4648 | 4628 | ||
4649 | if (ha->dcbx_tlv) | 4629 | if (ha->dcbx_tlv) |
4650 | dma_free_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE, | 4630 | dma_free_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE, |
4651 | ha->dcbx_tlv, ha->dcbx_tlv_dma); | 4631 | ha->dcbx_tlv, ha->dcbx_tlv_dma); |
4632 | ha->dcbx_tlv = NULL; | ||
4652 | 4633 | ||
4653 | if (ha->xgmac_data) | 4634 | if (ha->xgmac_data) |
4654 | dma_free_coherent(&ha->pdev->dev, XGMAC_DATA_SIZE, | 4635 | dma_free_coherent(&ha->pdev->dev, XGMAC_DATA_SIZE, |
4655 | ha->xgmac_data, ha->xgmac_data_dma); | 4636 | ha->xgmac_data, ha->xgmac_data_dma); |
4637 | ha->xgmac_data = NULL; | ||
4656 | 4638 | ||
4657 | if (ha->sns_cmd) | 4639 | if (ha->sns_cmd) |
4658 | dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), | 4640 | dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), |
4659 | ha->sns_cmd, ha->sns_cmd_dma); | 4641 | ha->sns_cmd, ha->sns_cmd_dma); |
4642 | ha->sns_cmd = NULL; | ||
4643 | ha->sns_cmd_dma = 0; | ||
4660 | 4644 | ||
4661 | if (ha->ct_sns) | 4645 | if (ha->ct_sns) |
4662 | dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), | 4646 | dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), |
4663 | ha->ct_sns, ha->ct_sns_dma); | 4647 | ha->ct_sns, ha->ct_sns_dma); |
4648 | ha->ct_sns = NULL; | ||
4649 | ha->ct_sns_dma = 0; | ||
4664 | 4650 | ||
4665 | if (ha->sfp_data) | 4651 | if (ha->sfp_data) |
4666 | dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE, ha->sfp_data, | 4652 | dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE, ha->sfp_data, |
4667 | ha->sfp_data_dma); | 4653 | ha->sfp_data_dma); |
4654 | ha->sfp_data = NULL; | ||
4655 | |||
4656 | if (ha->flt) | ||
4657 | dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE, | ||
4658 | ha->flt, ha->flt_dma); | ||
4659 | ha->flt = NULL; | ||
4660 | ha->flt_dma = 0; | ||
4668 | 4661 | ||
4669 | if (ha->ms_iocb) | 4662 | if (ha->ms_iocb) |
4670 | dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); | 4663 | dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); |
4664 | ha->ms_iocb = NULL; | ||
4665 | ha->ms_iocb_dma = 0; | ||
4671 | 4666 | ||
4672 | if (ha->ex_init_cb) | 4667 | if (ha->ex_init_cb) |
4673 | dma_pool_free(ha->s_dma_pool, | 4668 | dma_pool_free(ha->s_dma_pool, |
4674 | ha->ex_init_cb, ha->ex_init_cb_dma); | 4669 | ha->ex_init_cb, ha->ex_init_cb_dma); |
4670 | ha->ex_init_cb = NULL; | ||
4671 | ha->ex_init_cb_dma = 0; | ||
4675 | 4672 | ||
4676 | if (ha->async_pd) | 4673 | if (ha->async_pd) |
4677 | dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma); | 4674 | dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma); |
4675 | ha->async_pd = NULL; | ||
4676 | ha->async_pd_dma = 0; | ||
4678 | 4677 | ||
4679 | dma_pool_destroy(ha->s_dma_pool); | 4678 | dma_pool_destroy(ha->s_dma_pool); |
4679 | ha->s_dma_pool = NULL; | ||
4680 | 4680 | ||
4681 | if (ha->gid_list) | 4681 | if (ha->gid_list) |
4682 | dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), | 4682 | dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), |
4683 | ha->gid_list, ha->gid_list_dma); | 4683 | ha->gid_list, ha->gid_list_dma); |
4684 | ha->gid_list = NULL; | ||
4685 | ha->gid_list_dma = 0; | ||
4684 | 4686 | ||
4685 | if (IS_QLA82XX(ha)) { | 4687 | if (IS_QLA82XX(ha)) { |
4686 | if (!list_empty(&ha->gbl_dsd_list)) { | 4688 | if (!list_empty(&ha->gbl_dsd_list)) { |
@@ -4698,10 +4700,13 @@ qla2x00_mem_free(struct qla_hw_data *ha) | |||
4698 | } | 4700 | } |
4699 | 4701 | ||
4700 | dma_pool_destroy(ha->dl_dma_pool); | 4702 | dma_pool_destroy(ha->dl_dma_pool); |
4703 | ha->dl_dma_pool = NULL; | ||
4701 | 4704 | ||
4702 | dma_pool_destroy(ha->fcp_cmnd_dma_pool); | 4705 | dma_pool_destroy(ha->fcp_cmnd_dma_pool); |
4706 | ha->fcp_cmnd_dma_pool = NULL; | ||
4703 | 4707 | ||
4704 | mempool_destroy(ha->ctx_mempool); | 4708 | mempool_destroy(ha->ctx_mempool); |
4709 | ha->ctx_mempool = NULL; | ||
4705 | 4710 | ||
4706 | if (ql2xenabledif) { | 4711 | if (ql2xenabledif) { |
4707 | struct dsd_dma *dsd, *nxt; | 4712 | struct dsd_dma *dsd, *nxt; |
@@ -4728,53 +4733,26 @@ qla2x00_mem_free(struct qla_hw_data *ha) | |||
4728 | 4733 | ||
4729 | if (ha->dif_bundl_pool) | 4734 | if (ha->dif_bundl_pool) |
4730 | dma_pool_destroy(ha->dif_bundl_pool); | 4735 | dma_pool_destroy(ha->dif_bundl_pool); |
4736 | ha->dif_bundl_pool = NULL; | ||
4731 | 4737 | ||
4732 | qlt_mem_free(ha); | 4738 | qlt_mem_free(ha); |
4733 | 4739 | ||
4734 | if (ha->init_cb) | 4740 | if (ha->init_cb) |
4735 | dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, | 4741 | dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, |
4736 | ha->init_cb, ha->init_cb_dma); | 4742 | ha->init_cb, ha->init_cb_dma); |
4743 | ha->init_cb = NULL; | ||
4744 | ha->init_cb_dma = 0; | ||
4737 | 4745 | ||
4738 | vfree(ha->optrom_buffer); | 4746 | vfree(ha->optrom_buffer); |
4747 | ha->optrom_buffer = NULL; | ||
4739 | kfree(ha->nvram); | 4748 | kfree(ha->nvram); |
4749 | ha->nvram = NULL; | ||
4740 | kfree(ha->npiv_info); | 4750 | kfree(ha->npiv_info); |
4751 | ha->npiv_info = NULL; | ||
4741 | kfree(ha->swl); | 4752 | kfree(ha->swl); |
4753 | ha->swl = NULL; | ||
4742 | kfree(ha->loop_id_map); | 4754 | kfree(ha->loop_id_map); |
4743 | |||
4744 | ha->srb_mempool = NULL; | ||
4745 | ha->ctx_mempool = NULL; | ||
4746 | ha->sns_cmd = NULL; | ||
4747 | ha->sns_cmd_dma = 0; | ||
4748 | ha->ct_sns = NULL; | ||
4749 | ha->ct_sns_dma = 0; | ||
4750 | ha->ms_iocb = NULL; | ||
4751 | ha->ms_iocb_dma = 0; | ||
4752 | ha->init_cb = NULL; | ||
4753 | ha->init_cb_dma = 0; | ||
4754 | ha->ex_init_cb = NULL; | ||
4755 | ha->ex_init_cb_dma = 0; | ||
4756 | ha->async_pd = NULL; | ||
4757 | ha->async_pd_dma = 0; | ||
4758 | ha->loop_id_map = NULL; | 4755 | ha->loop_id_map = NULL; |
4759 | ha->npiv_info = NULL; | ||
4760 | ha->optrom_buffer = NULL; | ||
4761 | ha->swl = NULL; | ||
4762 | ha->nvram = NULL; | ||
4763 | ha->mctp_dump = NULL; | ||
4764 | ha->dcbx_tlv = NULL; | ||
4765 | ha->xgmac_data = NULL; | ||
4766 | ha->sfp_data = NULL; | ||
4767 | |||
4768 | ha->s_dma_pool = NULL; | ||
4769 | ha->dl_dma_pool = NULL; | ||
4770 | ha->fcp_cmnd_dma_pool = NULL; | ||
4771 | |||
4772 | ha->gid_list = NULL; | ||
4773 | ha->gid_list_dma = 0; | ||
4774 | |||
4775 | ha->tgt.atio_ring = NULL; | ||
4776 | ha->tgt.atio_dma = 0; | ||
4777 | ha->tgt.tgt_vp_map = NULL; | ||
4778 | } | 4756 | } |
4779 | 4757 | ||
4780 | struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, | 4758 | struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, |
@@ -5608,6 +5586,7 @@ qla83xx_force_lock_recovery(scsi_qla_host_t *base_vha) | |||
5608 | uint32_t idc_lck_rcvry_stage_mask = 0x3; | 5586 | uint32_t idc_lck_rcvry_stage_mask = 0x3; |
5609 | uint32_t idc_lck_rcvry_owner_mask = 0x3c; | 5587 | uint32_t idc_lck_rcvry_owner_mask = 0x3c; |
5610 | struct qla_hw_data *ha = base_vha->hw; | 5588 | struct qla_hw_data *ha = base_vha->hw; |
5589 | |||
5611 | ql_dbg(ql_dbg_p3p, base_vha, 0xb086, | 5590 | ql_dbg(ql_dbg_p3p, base_vha, 0xb086, |
5612 | "Trying force recovery of the IDC lock.\n"); | 5591 | "Trying force recovery of the IDC lock.\n"); |
5613 | 5592 | ||
@@ -6677,8 +6656,10 @@ qla2x00_timer(struct timer_list *t) | |||
6677 | * FC-NVME | 6656 | * FC-NVME |
6678 | * see if the active AEN count has changed from what was last reported. | 6657 | * see if the active AEN count has changed from what was last reported. |
6679 | */ | 6658 | */ |
6680 | if (!vha->vp_idx && (atomic_read(&ha->nvme_active_aen_cnt) != | 6659 | if (!vha->vp_idx && |
6681 | ha->nvme_last_rptd_aen) && ha->zio_mode == QLA_ZIO_MODE_6) { | 6660 | (atomic_read(&ha->nvme_active_aen_cnt) != ha->nvme_last_rptd_aen) && |
6661 | ha->zio_mode == QLA_ZIO_MODE_6 && | ||
6662 | !ha->flags.host_shutting_down) { | ||
6682 | ql_log(ql_log_info, vha, 0x3002, | 6663 | ql_log(ql_log_info, vha, 0x3002, |
6683 | "nvme: Sched: Set ZIO exchange threshold to %d.\n", | 6664 | "nvme: Sched: Set ZIO exchange threshold to %d.\n", |
6684 | ha->nvme_last_rptd_aen); | 6665 | ha->nvme_last_rptd_aen); |
@@ -6690,7 +6671,7 @@ qla2x00_timer(struct timer_list *t) | |||
6690 | if (!vha->vp_idx && | 6671 | if (!vha->vp_idx && |
6691 | (atomic_read(&ha->zio_threshold) != ha->last_zio_threshold) && | 6672 | (atomic_read(&ha->zio_threshold) != ha->last_zio_threshold) && |
6692 | (ha->zio_mode == QLA_ZIO_MODE_6) && | 6673 | (ha->zio_mode == QLA_ZIO_MODE_6) && |
6693 | (IS_QLA83XX(ha) || IS_QLA27XX(ha))) { | 6674 | (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))) { |
6694 | ql_log(ql_log_info, vha, 0x3002, | 6675 | ql_log(ql_log_info, vha, 0x3002, |
6695 | "Sched: Set ZIO exchange threshold to %d.\n", | 6676 | "Sched: Set ZIO exchange threshold to %d.\n", |
6696 | ha->last_zio_threshold); | 6677 | ha->last_zio_threshold); |
@@ -6736,7 +6717,6 @@ qla2x00_timer(struct timer_list *t) | |||
6736 | 6717 | ||
6737 | /* Firmware interface routines. */ | 6718 | /* Firmware interface routines. */ |
6738 | 6719 | ||
6739 | #define FW_BLOBS 11 | ||
6740 | #define FW_ISP21XX 0 | 6720 | #define FW_ISP21XX 0 |
6741 | #define FW_ISP22XX 1 | 6721 | #define FW_ISP22XX 1 |
6742 | #define FW_ISP2300 2 | 6722 | #define FW_ISP2300 2 |
@@ -6748,6 +6728,7 @@ qla2x00_timer(struct timer_list *t) | |||
6748 | #define FW_ISP2031 8 | 6728 | #define FW_ISP2031 8 |
6749 | #define FW_ISP8031 9 | 6729 | #define FW_ISP8031 9 |
6750 | #define FW_ISP27XX 10 | 6730 | #define FW_ISP27XX 10 |
6731 | #define FW_ISP28XX 11 | ||
6751 | 6732 | ||
6752 | #define FW_FILE_ISP21XX "ql2100_fw.bin" | 6733 | #define FW_FILE_ISP21XX "ql2100_fw.bin" |
6753 | #define FW_FILE_ISP22XX "ql2200_fw.bin" | 6734 | #define FW_FILE_ISP22XX "ql2200_fw.bin" |
@@ -6760,11 +6741,12 @@ qla2x00_timer(struct timer_list *t) | |||
6760 | #define FW_FILE_ISP2031 "ql2600_fw.bin" | 6741 | #define FW_FILE_ISP2031 "ql2600_fw.bin" |
6761 | #define FW_FILE_ISP8031 "ql8300_fw.bin" | 6742 | #define FW_FILE_ISP8031 "ql8300_fw.bin" |
6762 | #define FW_FILE_ISP27XX "ql2700_fw.bin" | 6743 | #define FW_FILE_ISP27XX "ql2700_fw.bin" |
6744 | #define FW_FILE_ISP28XX "ql2800_fw.bin" | ||
6763 | 6745 | ||
6764 | 6746 | ||
6765 | static DEFINE_MUTEX(qla_fw_lock); | 6747 | static DEFINE_MUTEX(qla_fw_lock); |
6766 | 6748 | ||
6767 | static struct fw_blob qla_fw_blobs[FW_BLOBS] = { | 6749 | static struct fw_blob qla_fw_blobs[] = { |
6768 | { .name = FW_FILE_ISP21XX, .segs = { 0x1000, 0 }, }, | 6750 | { .name = FW_FILE_ISP21XX, .segs = { 0x1000, 0 }, }, |
6769 | { .name = FW_FILE_ISP22XX, .segs = { 0x1000, 0 }, }, | 6751 | { .name = FW_FILE_ISP22XX, .segs = { 0x1000, 0 }, }, |
6770 | { .name = FW_FILE_ISP2300, .segs = { 0x800, 0 }, }, | 6752 | { .name = FW_FILE_ISP2300, .segs = { 0x800, 0 }, }, |
@@ -6776,6 +6758,8 @@ static struct fw_blob qla_fw_blobs[FW_BLOBS] = { | |||
6776 | { .name = FW_FILE_ISP2031, }, | 6758 | { .name = FW_FILE_ISP2031, }, |
6777 | { .name = FW_FILE_ISP8031, }, | 6759 | { .name = FW_FILE_ISP8031, }, |
6778 | { .name = FW_FILE_ISP27XX, }, | 6760 | { .name = FW_FILE_ISP27XX, }, |
6761 | { .name = FW_FILE_ISP28XX, }, | ||
6762 | { .name = NULL, }, | ||
6779 | }; | 6763 | }; |
6780 | 6764 | ||
6781 | struct fw_blob * | 6765 | struct fw_blob * |
@@ -6806,10 +6790,15 @@ qla2x00_request_firmware(scsi_qla_host_t *vha) | |||
6806 | blob = &qla_fw_blobs[FW_ISP8031]; | 6790 | blob = &qla_fw_blobs[FW_ISP8031]; |
6807 | } else if (IS_QLA27XX(ha)) { | 6791 | } else if (IS_QLA27XX(ha)) { |
6808 | blob = &qla_fw_blobs[FW_ISP27XX]; | 6792 | blob = &qla_fw_blobs[FW_ISP27XX]; |
6793 | } else if (IS_QLA28XX(ha)) { | ||
6794 | blob = &qla_fw_blobs[FW_ISP28XX]; | ||
6809 | } else { | 6795 | } else { |
6810 | return NULL; | 6796 | return NULL; |
6811 | } | 6797 | } |
6812 | 6798 | ||
6799 | if (!blob->name) | ||
6800 | return NULL; | ||
6801 | |||
6813 | mutex_lock(&qla_fw_lock); | 6802 | mutex_lock(&qla_fw_lock); |
6814 | if (blob->fw) | 6803 | if (blob->fw) |
6815 | goto out; | 6804 | goto out; |
@@ -6819,7 +6808,6 @@ qla2x00_request_firmware(scsi_qla_host_t *vha) | |||
6819 | "Failed to load firmware image (%s).\n", blob->name); | 6808 | "Failed to load firmware image (%s).\n", blob->name); |
6820 | blob->fw = NULL; | 6809 | blob->fw = NULL; |
6821 | blob = NULL; | 6810 | blob = NULL; |
6822 | goto out; | ||
6823 | } | 6811 | } |
6824 | 6812 | ||
6825 | out: | 6813 | out: |
@@ -6830,11 +6818,11 @@ out: | |||
6830 | static void | 6818 | static void |
6831 | qla2x00_release_firmware(void) | 6819 | qla2x00_release_firmware(void) |
6832 | { | 6820 | { |
6833 | int idx; | 6821 | struct fw_blob *blob; |
6834 | 6822 | ||
6835 | mutex_lock(&qla_fw_lock); | 6823 | mutex_lock(&qla_fw_lock); |
6836 | for (idx = 0; idx < FW_BLOBS; idx++) | 6824 | for (blob = qla_fw_blobs; blob->name; blob++) |
6837 | release_firmware(qla_fw_blobs[idx].fw); | 6825 | release_firmware(blob->fw); |
6838 | mutex_unlock(&qla_fw_lock); | 6826 | mutex_unlock(&qla_fw_lock); |
6839 | } | 6827 | } |
6840 | 6828 | ||
@@ -7179,7 +7167,7 @@ static int qla2xxx_map_queues(struct Scsi_Host *shost) | |||
7179 | { | 7167 | { |
7180 | int rc; | 7168 | int rc; |
7181 | scsi_qla_host_t *vha = (scsi_qla_host_t *)shost->hostdata; | 7169 | scsi_qla_host_t *vha = (scsi_qla_host_t *)shost->hostdata; |
7182 | struct blk_mq_queue_map *qmap = &shost->tag_set.map[0]; | 7170 | struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; |
7183 | 7171 | ||
7184 | if (USER_CTRL_IRQ(vha->hw) || !vha->hw->mqiobase) | 7172 | if (USER_CTRL_IRQ(vha->hw) || !vha->hw->mqiobase) |
7185 | rc = blk_mq_map_queues(qmap); | 7173 | rc = blk_mq_map_queues(qmap); |
@@ -7188,6 +7176,37 @@ static int qla2xxx_map_queues(struct Scsi_Host *shost) | |||
7188 | return rc; | 7176 | return rc; |
7189 | } | 7177 | } |
7190 | 7178 | ||
7179 | struct scsi_host_template qla2xxx_driver_template = { | ||
7180 | .module = THIS_MODULE, | ||
7181 | .name = QLA2XXX_DRIVER_NAME, | ||
7182 | .queuecommand = qla2xxx_queuecommand, | ||
7183 | |||
7184 | .eh_timed_out = fc_eh_timed_out, | ||
7185 | .eh_abort_handler = qla2xxx_eh_abort, | ||
7186 | .eh_device_reset_handler = qla2xxx_eh_device_reset, | ||
7187 | .eh_target_reset_handler = qla2xxx_eh_target_reset, | ||
7188 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, | ||
7189 | .eh_host_reset_handler = qla2xxx_eh_host_reset, | ||
7190 | |||
7191 | .slave_configure = qla2xxx_slave_configure, | ||
7192 | |||
7193 | .slave_alloc = qla2xxx_slave_alloc, | ||
7194 | .slave_destroy = qla2xxx_slave_destroy, | ||
7195 | .scan_finished = qla2xxx_scan_finished, | ||
7196 | .scan_start = qla2xxx_scan_start, | ||
7197 | .change_queue_depth = scsi_change_queue_depth, | ||
7198 | .map_queues = qla2xxx_map_queues, | ||
7199 | .this_id = -1, | ||
7200 | .cmd_per_lun = 3, | ||
7201 | .sg_tablesize = SG_ALL, | ||
7202 | |||
7203 | .max_sectors = 0xFFFF, | ||
7204 | .shost_attrs = qla2x00_host_attrs, | ||
7205 | |||
7206 | .supported_mode = MODE_INITIATOR, | ||
7207 | .track_queue_depth = 1, | ||
7208 | }; | ||
7209 | |||
7191 | static const struct pci_error_handlers qla2xxx_err_handler = { | 7210 | static const struct pci_error_handlers qla2xxx_err_handler = { |
7192 | .error_detected = qla2xxx_pci_error_detected, | 7211 | .error_detected = qla2xxx_pci_error_detected, |
7193 | .mmio_enabled = qla2xxx_pci_mmio_enabled, | 7212 | .mmio_enabled = qla2xxx_pci_mmio_enabled, |
@@ -7220,6 +7239,11 @@ static struct pci_device_id qla2xxx_pci_tbl[] = { | |||
7220 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2071) }, | 7239 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2071) }, |
7221 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2271) }, | 7240 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2271) }, |
7222 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2261) }, | 7241 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2261) }, |
7242 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2061) }, | ||
7243 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2081) }, | ||
7244 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2281) }, | ||
7245 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2089) }, | ||
7246 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2289) }, | ||
7223 | { 0 }, | 7247 | { 0 }, |
7224 | }; | 7248 | }; |
7225 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); | 7249 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); |
@@ -7249,6 +7273,30 @@ qla2x00_module_init(void) | |||
7249 | { | 7273 | { |
7250 | int ret = 0; | 7274 | int ret = 0; |
7251 | 7275 | ||
7276 | BUILD_BUG_ON(sizeof(cmd_entry_t) != 64); | ||
7277 | BUILD_BUG_ON(sizeof(cont_a64_entry_t) != 64); | ||
7278 | BUILD_BUG_ON(sizeof(cont_entry_t) != 64); | ||
7279 | BUILD_BUG_ON(sizeof(init_cb_t) != 96); | ||
7280 | BUILD_BUG_ON(sizeof(ms_iocb_entry_t) != 64); | ||
7281 | BUILD_BUG_ON(sizeof(request_t) != 64); | ||
7282 | BUILD_BUG_ON(sizeof(struct access_chip_84xx) != 64); | ||
7283 | BUILD_BUG_ON(sizeof(struct cmd_bidir) != 64); | ||
7284 | BUILD_BUG_ON(sizeof(struct cmd_nvme) != 64); | ||
7285 | BUILD_BUG_ON(sizeof(struct cmd_type_6) != 64); | ||
7286 | BUILD_BUG_ON(sizeof(struct cmd_type_7) != 64); | ||
7287 | BUILD_BUG_ON(sizeof(struct cmd_type_7_fx00) != 64); | ||
7288 | BUILD_BUG_ON(sizeof(struct cmd_type_crc_2) != 64); | ||
7289 | BUILD_BUG_ON(sizeof(struct ct_entry_24xx) != 64); | ||
7290 | BUILD_BUG_ON(sizeof(struct ctio_crc2_to_fw) != 64); | ||
7291 | BUILD_BUG_ON(sizeof(struct els_entry_24xx) != 64); | ||
7292 | BUILD_BUG_ON(sizeof(struct fxdisc_entry_fx00) != 64); | ||
7293 | BUILD_BUG_ON(sizeof(struct init_cb_24xx) != 128); | ||
7294 | BUILD_BUG_ON(sizeof(struct init_cb_81xx) != 128); | ||
7295 | BUILD_BUG_ON(sizeof(struct pt_ls4_request) != 64); | ||
7296 | BUILD_BUG_ON(sizeof(struct sns_cmd_pkt) != 2064); | ||
7297 | BUILD_BUG_ON(sizeof(struct verify_chip_entry_84xx) != 64); | ||
7298 | BUILD_BUG_ON(sizeof(struct vf_evfp_entry_24xx) != 56); | ||
7299 | |||
7252 | /* Allocate cache for SRBs. */ | 7300 | /* Allocate cache for SRBs. */ |
7253 | srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0, | 7301 | srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0, |
7254 | SLAB_HWCACHE_ALIGN, NULL); | 7302 | SLAB_HWCACHE_ALIGN, NULL); |
@@ -7261,8 +7309,7 @@ qla2x00_module_init(void) | |||
7261 | /* Initialize target kmem_cache and mem_pools */ | 7309 | /* Initialize target kmem_cache and mem_pools */ |
7262 | ret = qlt_init(); | 7310 | ret = qlt_init(); |
7263 | if (ret < 0) { | 7311 | if (ret < 0) { |
7264 | kmem_cache_destroy(srb_cachep); | 7312 | goto destroy_cache; |
7265 | return ret; | ||
7266 | } else if (ret > 0) { | 7313 | } else if (ret > 0) { |
7267 | /* | 7314 | /* |
7268 | * If initiator mode is explictly disabled by qlt_init(), | 7315 | * If initiator mode is explictly disabled by qlt_init(), |
@@ -7286,11 +7333,10 @@ qla2x00_module_init(void) | |||
7286 | qla2xxx_transport_template = | 7333 | qla2xxx_transport_template = |
7287 | fc_attach_transport(&qla2xxx_transport_functions); | 7334 | fc_attach_transport(&qla2xxx_transport_functions); |
7288 | if (!qla2xxx_transport_template) { | 7335 | if (!qla2xxx_transport_template) { |
7289 | kmem_cache_destroy(srb_cachep); | ||
7290 | ql_log(ql_log_fatal, NULL, 0x0002, | 7336 | ql_log(ql_log_fatal, NULL, 0x0002, |
7291 | "fc_attach_transport failed...Failing load!.\n"); | 7337 | "fc_attach_transport failed...Failing load!.\n"); |
7292 | qlt_exit(); | 7338 | ret = -ENODEV; |
7293 | return -ENODEV; | 7339 | goto qlt_exit; |
7294 | } | 7340 | } |
7295 | 7341 | ||
7296 | apidev_major = register_chrdev(0, QLA2XXX_APIDEV, &apidev_fops); | 7342 | apidev_major = register_chrdev(0, QLA2XXX_APIDEV, &apidev_fops); |
@@ -7302,27 +7348,37 @@ qla2x00_module_init(void) | |||
7302 | qla2xxx_transport_vport_template = | 7348 | qla2xxx_transport_vport_template = |
7303 | fc_attach_transport(&qla2xxx_transport_vport_functions); | 7349 | fc_attach_transport(&qla2xxx_transport_vport_functions); |
7304 | if (!qla2xxx_transport_vport_template) { | 7350 | if (!qla2xxx_transport_vport_template) { |
7305 | kmem_cache_destroy(srb_cachep); | ||
7306 | qlt_exit(); | ||
7307 | fc_release_transport(qla2xxx_transport_template); | ||
7308 | ql_log(ql_log_fatal, NULL, 0x0004, | 7351 | ql_log(ql_log_fatal, NULL, 0x0004, |
7309 | "fc_attach_transport vport failed...Failing load!.\n"); | 7352 | "fc_attach_transport vport failed...Failing load!.\n"); |
7310 | return -ENODEV; | 7353 | ret = -ENODEV; |
7354 | goto unreg_chrdev; | ||
7311 | } | 7355 | } |
7312 | ql_log(ql_log_info, NULL, 0x0005, | 7356 | ql_log(ql_log_info, NULL, 0x0005, |
7313 | "QLogic Fibre Channel HBA Driver: %s.\n", | 7357 | "QLogic Fibre Channel HBA Driver: %s.\n", |
7314 | qla2x00_version_str); | 7358 | qla2x00_version_str); |
7315 | ret = pci_register_driver(&qla2xxx_pci_driver); | 7359 | ret = pci_register_driver(&qla2xxx_pci_driver); |
7316 | if (ret) { | 7360 | if (ret) { |
7317 | kmem_cache_destroy(srb_cachep); | ||
7318 | qlt_exit(); | ||
7319 | fc_release_transport(qla2xxx_transport_template); | ||
7320 | fc_release_transport(qla2xxx_transport_vport_template); | ||
7321 | ql_log(ql_log_fatal, NULL, 0x0006, | 7361 | ql_log(ql_log_fatal, NULL, 0x0006, |
7322 | "pci_register_driver failed...ret=%d Failing load!.\n", | 7362 | "pci_register_driver failed...ret=%d Failing load!.\n", |
7323 | ret); | 7363 | ret); |
7364 | goto release_vport_transport; | ||
7324 | } | 7365 | } |
7325 | return ret; | 7366 | return ret; |
7367 | |||
7368 | release_vport_transport: | ||
7369 | fc_release_transport(qla2xxx_transport_vport_template); | ||
7370 | |||
7371 | unreg_chrdev: | ||
7372 | if (apidev_major >= 0) | ||
7373 | unregister_chrdev(apidev_major, QLA2XXX_APIDEV); | ||
7374 | fc_release_transport(qla2xxx_transport_template); | ||
7375 | |||
7376 | qlt_exit: | ||
7377 | qlt_exit(); | ||
7378 | |||
7379 | destroy_cache: | ||
7380 | kmem_cache_destroy(srb_cachep); | ||
7381 | return ret; | ||
7326 | } | 7382 | } |
7327 | 7383 | ||
7328 | /** | 7384 | /** |
@@ -7331,14 +7387,15 @@ qla2x00_module_init(void) | |||
7331 | static void __exit | 7387 | static void __exit |
7332 | qla2x00_module_exit(void) | 7388 | qla2x00_module_exit(void) |
7333 | { | 7389 | { |
7334 | unregister_chrdev(apidev_major, QLA2XXX_APIDEV); | ||
7335 | pci_unregister_driver(&qla2xxx_pci_driver); | 7390 | pci_unregister_driver(&qla2xxx_pci_driver); |
7336 | qla2x00_release_firmware(); | 7391 | qla2x00_release_firmware(); |
7337 | kmem_cache_destroy(srb_cachep); | ||
7338 | qlt_exit(); | ||
7339 | kmem_cache_destroy(ctx_cachep); | 7392 | kmem_cache_destroy(ctx_cachep); |
7340 | fc_release_transport(qla2xxx_transport_template); | ||
7341 | fc_release_transport(qla2xxx_transport_vport_template); | 7393 | fc_release_transport(qla2xxx_transport_vport_template); |
7394 | if (apidev_major >= 0) | ||
7395 | unregister_chrdev(apidev_major, QLA2XXX_APIDEV); | ||
7396 | fc_release_transport(qla2xxx_transport_template); | ||
7397 | qlt_exit(); | ||
7398 | kmem_cache_destroy(srb_cachep); | ||
7342 | } | 7399 | } |
7343 | 7400 | ||
7344 | module_init(qla2x00_module_init); | 7401 | module_init(qla2x00_module_init); |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 2a3055c799fb..1eb82384d933 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -429,66 +429,64 @@ qla2x00_set_nvram_protection(struct qla_hw_data *ha, int stat) | |||
429 | static inline uint32_t | 429 | static inline uint32_t |
430 | flash_conf_addr(struct qla_hw_data *ha, uint32_t faddr) | 430 | flash_conf_addr(struct qla_hw_data *ha, uint32_t faddr) |
431 | { | 431 | { |
432 | return ha->flash_conf_off | faddr; | 432 | return ha->flash_conf_off + faddr; |
433 | } | 433 | } |
434 | 434 | ||
435 | static inline uint32_t | 435 | static inline uint32_t |
436 | flash_data_addr(struct qla_hw_data *ha, uint32_t faddr) | 436 | flash_data_addr(struct qla_hw_data *ha, uint32_t faddr) |
437 | { | 437 | { |
438 | return ha->flash_data_off | faddr; | 438 | return ha->flash_data_off + faddr; |
439 | } | 439 | } |
440 | 440 | ||
441 | static inline uint32_t | 441 | static inline uint32_t |
442 | nvram_conf_addr(struct qla_hw_data *ha, uint32_t naddr) | 442 | nvram_conf_addr(struct qla_hw_data *ha, uint32_t naddr) |
443 | { | 443 | { |
444 | return ha->nvram_conf_off | naddr; | 444 | return ha->nvram_conf_off + naddr; |
445 | } | 445 | } |
446 | 446 | ||
447 | static inline uint32_t | 447 | static inline uint32_t |
448 | nvram_data_addr(struct qla_hw_data *ha, uint32_t naddr) | 448 | nvram_data_addr(struct qla_hw_data *ha, uint32_t naddr) |
449 | { | 449 | { |
450 | return ha->nvram_data_off | naddr; | 450 | return ha->nvram_data_off + naddr; |
451 | } | 451 | } |
452 | 452 | ||
453 | static uint32_t | 453 | static int |
454 | qla24xx_read_flash_dword(struct qla_hw_data *ha, uint32_t addr) | 454 | qla24xx_read_flash_dword(struct qla_hw_data *ha, uint32_t addr, uint32_t *data) |
455 | { | 455 | { |
456 | int rval; | ||
457 | uint32_t cnt, data; | ||
458 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 456 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
457 | ulong cnt = 30000; | ||
459 | 458 | ||
460 | WRT_REG_DWORD(®->flash_addr, addr & ~FARX_DATA_FLAG); | 459 | WRT_REG_DWORD(®->flash_addr, addr & ~FARX_DATA_FLAG); |
461 | /* Wait for READ cycle to complete. */ | 460 | |
462 | rval = QLA_SUCCESS; | 461 | while (cnt--) { |
463 | for (cnt = 3000; | 462 | if (RD_REG_DWORD(®->flash_addr) & FARX_DATA_FLAG) { |
464 | (RD_REG_DWORD(®->flash_addr) & FARX_DATA_FLAG) == 0 && | 463 | *data = RD_REG_DWORD(®->flash_data); |
465 | rval == QLA_SUCCESS; cnt--) { | 464 | return QLA_SUCCESS; |
466 | if (cnt) | 465 | } |
467 | udelay(10); | 466 | udelay(10); |
468 | else | ||
469 | rval = QLA_FUNCTION_TIMEOUT; | ||
470 | cond_resched(); | 467 | cond_resched(); |
471 | } | 468 | } |
472 | 469 | ||
473 | /* TODO: What happens if we time out? */ | 470 | ql_log(ql_log_warn, pci_get_drvdata(ha->pdev), 0x7090, |
474 | data = 0xDEADDEAD; | 471 | "Flash read dword at %x timeout.\n", addr); |
475 | if (rval == QLA_SUCCESS) | 472 | *data = 0xDEADDEAD; |
476 | data = RD_REG_DWORD(®->flash_data); | 473 | return QLA_FUNCTION_TIMEOUT; |
477 | |||
478 | return data; | ||
479 | } | 474 | } |
480 | 475 | ||
481 | uint32_t * | 476 | uint32_t * |
482 | qla24xx_read_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, | 477 | qla24xx_read_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, |
483 | uint32_t dwords) | 478 | uint32_t dwords) |
484 | { | 479 | { |
485 | uint32_t i; | 480 | ulong i; |
486 | struct qla_hw_data *ha = vha->hw; | 481 | struct qla_hw_data *ha = vha->hw; |
487 | 482 | ||
488 | /* Dword reads to flash. */ | 483 | /* Dword reads to flash. */ |
489 | for (i = 0; i < dwords; i++, faddr++) | 484 | faddr = flash_data_addr(ha, faddr); |
490 | dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha, | 485 | for (i = 0; i < dwords; i++, faddr++, dwptr++) { |
491 | flash_data_addr(ha, faddr))); | 486 | if (qla24xx_read_flash_dword(ha, faddr, dwptr)) |
487 | break; | ||
488 | cpu_to_le32s(dwptr); | ||
489 | } | ||
492 | 490 | ||
493 | return dwptr; | 491 | return dwptr; |
494 | } | 492 | } |
@@ -496,35 +494,37 @@ qla24xx_read_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, | |||
496 | static int | 494 | static int |
497 | qla24xx_write_flash_dword(struct qla_hw_data *ha, uint32_t addr, uint32_t data) | 495 | qla24xx_write_flash_dword(struct qla_hw_data *ha, uint32_t addr, uint32_t data) |
498 | { | 496 | { |
499 | int rval; | ||
500 | uint32_t cnt; | ||
501 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 497 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
498 | ulong cnt = 500000; | ||
502 | 499 | ||
503 | WRT_REG_DWORD(®->flash_data, data); | 500 | WRT_REG_DWORD(®->flash_data, data); |
504 | RD_REG_DWORD(®->flash_data); /* PCI Posting. */ | ||
505 | WRT_REG_DWORD(®->flash_addr, addr | FARX_DATA_FLAG); | 501 | WRT_REG_DWORD(®->flash_addr, addr | FARX_DATA_FLAG); |
506 | /* Wait for Write cycle to complete. */ | 502 | |
507 | rval = QLA_SUCCESS; | 503 | while (cnt--) { |
508 | for (cnt = 500000; (RD_REG_DWORD(®->flash_addr) & FARX_DATA_FLAG) && | 504 | if (!(RD_REG_DWORD(®->flash_addr) & FARX_DATA_FLAG)) |
509 | rval == QLA_SUCCESS; cnt--) { | 505 | return QLA_SUCCESS; |
510 | if (cnt) | 506 | udelay(10); |
511 | udelay(10); | ||
512 | else | ||
513 | rval = QLA_FUNCTION_TIMEOUT; | ||
514 | cond_resched(); | 507 | cond_resched(); |
515 | } | 508 | } |
516 | return rval; | 509 | |
510 | ql_log(ql_log_warn, pci_get_drvdata(ha->pdev), 0x7090, | ||
511 | "Flash write dword at %x timeout.\n", addr); | ||
512 | return QLA_FUNCTION_TIMEOUT; | ||
517 | } | 513 | } |
518 | 514 | ||
519 | static void | 515 | static void |
520 | qla24xx_get_flash_manufacturer(struct qla_hw_data *ha, uint8_t *man_id, | 516 | qla24xx_get_flash_manufacturer(struct qla_hw_data *ha, uint8_t *man_id, |
521 | uint8_t *flash_id) | 517 | uint8_t *flash_id) |
522 | { | 518 | { |
523 | uint32_t ids; | 519 | uint32_t faddr, ids = 0; |
524 | 520 | ||
525 | ids = qla24xx_read_flash_dword(ha, flash_conf_addr(ha, 0x03ab)); | 521 | *man_id = *flash_id = 0; |
526 | *man_id = LSB(ids); | 522 | |
527 | *flash_id = MSB(ids); | 523 | faddr = flash_conf_addr(ha, 0x03ab); |
524 | if (!qla24xx_read_flash_dword(ha, faddr, &ids)) { | ||
525 | *man_id = LSB(ids); | ||
526 | *flash_id = MSB(ids); | ||
527 | } | ||
528 | 528 | ||
529 | /* Check if man_id and flash_id are valid. */ | 529 | /* Check if man_id and flash_id are valid. */ |
530 | if (ids != 0xDEADDEAD && (*man_id == 0 || *flash_id == 0)) { | 530 | if (ids != 0xDEADDEAD && (*man_id == 0 || *flash_id == 0)) { |
@@ -534,9 +534,11 @@ qla24xx_get_flash_manufacturer(struct qla_hw_data *ha, uint8_t *man_id, | |||
534 | * Example: ATMEL 0x00 01 45 1F | 534 | * Example: ATMEL 0x00 01 45 1F |
535 | * Extract MFG and Dev ID from last two bytes. | 535 | * Extract MFG and Dev ID from last two bytes. |
536 | */ | 536 | */ |
537 | ids = qla24xx_read_flash_dword(ha, flash_conf_addr(ha, 0x009f)); | 537 | faddr = flash_conf_addr(ha, 0x009f); |
538 | *man_id = LSB(ids); | 538 | if (!qla24xx_read_flash_dword(ha, faddr, &ids)) { |
539 | *flash_id = MSB(ids); | 539 | *man_id = LSB(ids); |
540 | *flash_id = MSB(ids); | ||
541 | } | ||
540 | } | 542 | } |
541 | } | 543 | } |
542 | 544 | ||
@@ -545,12 +547,12 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start) | |||
545 | { | 547 | { |
546 | const char *loc, *locations[] = { "DEF", "PCI" }; | 548 | const char *loc, *locations[] = { "DEF", "PCI" }; |
547 | uint32_t pcihdr, pcids; | 549 | uint32_t pcihdr, pcids; |
548 | uint32_t *dcode; | ||
549 | uint8_t *buf, *bcode, last_image; | ||
550 | uint16_t cnt, chksum, *wptr; | 550 | uint16_t cnt, chksum, *wptr; |
551 | struct qla_flt_location *fltl; | ||
552 | struct qla_hw_data *ha = vha->hw; | 551 | struct qla_hw_data *ha = vha->hw; |
553 | struct req_que *req = ha->req_q_map[0]; | 552 | struct req_que *req = ha->req_q_map[0]; |
553 | struct qla_flt_location *fltl = (void *)req->ring; | ||
554 | uint32_t *dcode = (void *)req->ring; | ||
555 | uint8_t *buf = (void *)req->ring, *bcode, last_image; | ||
554 | 556 | ||
555 | /* | 557 | /* |
556 | * FLT-location structure resides after the last PCI region. | 558 | * FLT-location structure resides after the last PCI region. |
@@ -571,12 +573,13 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start) | |||
571 | } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 573 | } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
572 | *start = FA_FLASH_LAYOUT_ADDR_83; | 574 | *start = FA_FLASH_LAYOUT_ADDR_83; |
573 | goto end; | 575 | goto end; |
576 | } else if (IS_QLA28XX(ha)) { | ||
577 | *start = FA_FLASH_LAYOUT_ADDR_28; | ||
578 | goto end; | ||
574 | } | 579 | } |
580 | |||
575 | /* Begin with first PCI expansion ROM header. */ | 581 | /* Begin with first PCI expansion ROM header. */ |
576 | buf = (uint8_t *)req->ring; | ||
577 | dcode = (uint32_t *)req->ring; | ||
578 | pcihdr = 0; | 582 | pcihdr = 0; |
579 | last_image = 1; | ||
580 | do { | 583 | do { |
581 | /* Verify PCI expansion ROM header. */ | 584 | /* Verify PCI expansion ROM header. */ |
582 | qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20); | 585 | qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20); |
@@ -601,22 +604,19 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start) | |||
601 | } while (!last_image); | 604 | } while (!last_image); |
602 | 605 | ||
603 | /* Now verify FLT-location structure. */ | 606 | /* Now verify FLT-location structure. */ |
604 | fltl = (struct qla_flt_location *)req->ring; | 607 | qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, sizeof(*fltl) >> 2); |
605 | qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, | 608 | if (memcmp(fltl->sig, "QFLT", 4)) |
606 | sizeof(struct qla_flt_location) >> 2); | ||
607 | if (fltl->sig[0] != 'Q' || fltl->sig[1] != 'F' || | ||
608 | fltl->sig[2] != 'L' || fltl->sig[3] != 'T') | ||
609 | goto end; | 609 | goto end; |
610 | 610 | ||
611 | wptr = (uint16_t *)req->ring; | 611 | wptr = (void *)req->ring; |
612 | cnt = sizeof(struct qla_flt_location) >> 1; | 612 | cnt = sizeof(*fltl) / sizeof(*wptr); |
613 | for (chksum = 0; cnt--; wptr++) | 613 | for (chksum = 0; cnt--; wptr++) |
614 | chksum += le16_to_cpu(*wptr); | 614 | chksum += le16_to_cpu(*wptr); |
615 | if (chksum) { | 615 | if (chksum) { |
616 | ql_log(ql_log_fatal, vha, 0x0045, | 616 | ql_log(ql_log_fatal, vha, 0x0045, |
617 | "Inconsistent FLTL detected: checksum=0x%x.\n", chksum); | 617 | "Inconsistent FLTL detected: checksum=0x%x.\n", chksum); |
618 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x010e, | 618 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x010e, |
619 | buf, sizeof(struct qla_flt_location)); | 619 | fltl, sizeof(*fltl)); |
620 | return QLA_FUNCTION_FAILED; | 620 | return QLA_FUNCTION_FAILED; |
621 | } | 621 | } |
622 | 622 | ||
@@ -634,7 +634,7 @@ end: | |||
634 | static void | 634 | static void |
635 | qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | 635 | qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) |
636 | { | 636 | { |
637 | const char *loc, *locations[] = { "DEF", "FLT" }; | 637 | const char *locations[] = { "DEF", "FLT" }, *loc = locations[1]; |
638 | const uint32_t def_fw[] = | 638 | const uint32_t def_fw[] = |
639 | { FA_RISC_CODE_ADDR, FA_RISC_CODE_ADDR, FA_RISC_CODE_ADDR_81 }; | 639 | { FA_RISC_CODE_ADDR, FA_RISC_CODE_ADDR, FA_RISC_CODE_ADDR_81 }; |
640 | const uint32_t def_boot[] = | 640 | const uint32_t def_boot[] = |
@@ -664,20 +664,13 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
664 | const uint32_t fcp_prio_cfg1[] = | 664 | const uint32_t fcp_prio_cfg1[] = |
665 | { FA_FCP_PRIO1_ADDR, FA_FCP_PRIO1_ADDR_25, | 665 | { FA_FCP_PRIO1_ADDR, FA_FCP_PRIO1_ADDR_25, |
666 | 0 }; | 666 | 0 }; |
667 | uint32_t def; | ||
668 | uint16_t *wptr; | ||
669 | uint16_t cnt, chksum; | ||
670 | uint32_t start; | ||
671 | struct qla_flt_header *flt; | ||
672 | struct qla_flt_region *region; | ||
673 | struct qla_hw_data *ha = vha->hw; | ||
674 | struct req_que *req = ha->req_q_map[0]; | ||
675 | 667 | ||
676 | def = 0; | 668 | struct qla_hw_data *ha = vha->hw; |
677 | if (IS_QLA25XX(ha)) | 669 | uint32_t def = IS_QLA81XX(ha) ? 2 : IS_QLA25XX(ha) ? 1 : 0; |
678 | def = 1; | 670 | struct qla_flt_header *flt = (void *)ha->flt; |
679 | else if (IS_QLA81XX(ha)) | 671 | struct qla_flt_region *region = (void *)&flt[1]; |
680 | def = 2; | 672 | uint16_t *wptr, cnt, chksum; |
673 | uint32_t start; | ||
681 | 674 | ||
682 | /* Assign FCP prio region since older adapters may not have FLT, or | 675 | /* Assign FCP prio region since older adapters may not have FLT, or |
683 | FCP prio region in it's FLT. | 676 | FCP prio region in it's FLT. |
@@ -686,12 +679,11 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
686 | fcp_prio_cfg0[def] : fcp_prio_cfg1[def]; | 679 | fcp_prio_cfg0[def] : fcp_prio_cfg1[def]; |
687 | 680 | ||
688 | ha->flt_region_flt = flt_addr; | 681 | ha->flt_region_flt = flt_addr; |
689 | wptr = (uint16_t *)req->ring; | 682 | wptr = (uint16_t *)ha->flt; |
690 | flt = (struct qla_flt_header *)req->ring; | 683 | qla24xx_read_flash_data(vha, (void *)flt, flt_addr, |
691 | region = (struct qla_flt_region *)&flt[1]; | 684 | (sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE) >> 2); |
692 | ha->isp_ops->read_optrom(vha, (uint8_t *)req->ring, | 685 | |
693 | flt_addr << 2, OPTROM_BURST_SIZE); | 686 | if (le16_to_cpu(*wptr) == 0xffff) |
694 | if (*wptr == cpu_to_le16(0xffff)) | ||
695 | goto no_flash_data; | 687 | goto no_flash_data; |
696 | if (flt->version != cpu_to_le16(1)) { | 688 | if (flt->version != cpu_to_le16(1)) { |
697 | ql_log(ql_log_warn, vha, 0x0047, | 689 | ql_log(ql_log_warn, vha, 0x0047, |
@@ -701,7 +693,7 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
701 | goto no_flash_data; | 693 | goto no_flash_data; |
702 | } | 694 | } |
703 | 695 | ||
704 | cnt = (sizeof(struct qla_flt_header) + le16_to_cpu(flt->length)) >> 1; | 696 | cnt = (sizeof(*flt) + le16_to_cpu(flt->length)) / sizeof(*wptr); |
705 | for (chksum = 0; cnt--; wptr++) | 697 | for (chksum = 0; cnt--; wptr++) |
706 | chksum += le16_to_cpu(*wptr); | 698 | chksum += le16_to_cpu(*wptr); |
707 | if (chksum) { | 699 | if (chksum) { |
@@ -712,18 +704,20 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
712 | goto no_flash_data; | 704 | goto no_flash_data; |
713 | } | 705 | } |
714 | 706 | ||
715 | loc = locations[1]; | 707 | cnt = le16_to_cpu(flt->length) / sizeof(*region); |
716 | cnt = le16_to_cpu(flt->length) / sizeof(struct qla_flt_region); | ||
717 | for ( ; cnt; cnt--, region++) { | 708 | for ( ; cnt; cnt--, region++) { |
718 | /* Store addresses as DWORD offsets. */ | 709 | /* Store addresses as DWORD offsets. */ |
719 | start = le32_to_cpu(region->start) >> 2; | 710 | start = le32_to_cpu(region->start) >> 2; |
720 | ql_dbg(ql_dbg_init, vha, 0x0049, | 711 | ql_dbg(ql_dbg_init, vha, 0x0049, |
721 | "FLT[%02x]: start=0x%x " | 712 | "FLT[%#x]: start=%#x end=%#x size=%#x.\n", |
722 | "end=0x%x size=0x%x.\n", le32_to_cpu(region->code) & 0xff, | 713 | le16_to_cpu(region->code), start, |
723 | start, le32_to_cpu(region->end) >> 2, | 714 | le32_to_cpu(region->end) >> 2, |
724 | le32_to_cpu(region->size)); | 715 | le32_to_cpu(region->size) >> 2); |
725 | 716 | if (region->attribute) | |
726 | switch (le32_to_cpu(region->code) & 0xff) { | 717 | ql_log(ql_dbg_init, vha, 0xffff, |
718 | "Region %x is secure\n", region->code); | ||
719 | |||
720 | switch (le16_to_cpu(region->code)) { | ||
727 | case FLT_REG_FCOE_FW: | 721 | case FLT_REG_FCOE_FW: |
728 | if (!IS_QLA8031(ha)) | 722 | if (!IS_QLA8031(ha)) |
729 | break; | 723 | break; |
@@ -753,13 +747,13 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
753 | ha->flt_region_vpd = start; | 747 | ha->flt_region_vpd = start; |
754 | break; | 748 | break; |
755 | case FLT_REG_VPD_2: | 749 | case FLT_REG_VPD_2: |
756 | if (!IS_QLA27XX(ha)) | 750 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
757 | break; | 751 | break; |
758 | if (ha->port_no == 2) | 752 | if (ha->port_no == 2) |
759 | ha->flt_region_vpd = start; | 753 | ha->flt_region_vpd = start; |
760 | break; | 754 | break; |
761 | case FLT_REG_VPD_3: | 755 | case FLT_REG_VPD_3: |
762 | if (!IS_QLA27XX(ha)) | 756 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
763 | break; | 757 | break; |
764 | if (ha->port_no == 3) | 758 | if (ha->port_no == 3) |
765 | ha->flt_region_vpd = start; | 759 | ha->flt_region_vpd = start; |
@@ -777,13 +771,13 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
777 | ha->flt_region_nvram = start; | 771 | ha->flt_region_nvram = start; |
778 | break; | 772 | break; |
779 | case FLT_REG_NVRAM_2: | 773 | case FLT_REG_NVRAM_2: |
780 | if (!IS_QLA27XX(ha)) | 774 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
781 | break; | 775 | break; |
782 | if (ha->port_no == 2) | 776 | if (ha->port_no == 2) |
783 | ha->flt_region_nvram = start; | 777 | ha->flt_region_nvram = start; |
784 | break; | 778 | break; |
785 | case FLT_REG_NVRAM_3: | 779 | case FLT_REG_NVRAM_3: |
786 | if (!IS_QLA27XX(ha)) | 780 | if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
787 | break; | 781 | break; |
788 | if (ha->port_no == 3) | 782 | if (ha->port_no == 3) |
789 | ha->flt_region_nvram = start; | 783 | ha->flt_region_nvram = start; |
@@ -847,36 +841,74 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) | |||
847 | ha->flt_region_nvram = start; | 841 | ha->flt_region_nvram = start; |
848 | break; | 842 | break; |
849 | case FLT_REG_IMG_PRI_27XX: | 843 | case FLT_REG_IMG_PRI_27XX: |
850 | if (IS_QLA27XX(ha)) | 844 | if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
851 | ha->flt_region_img_status_pri = start; | 845 | ha->flt_region_img_status_pri = start; |
852 | break; | 846 | break; |
853 | case FLT_REG_IMG_SEC_27XX: | 847 | case FLT_REG_IMG_SEC_27XX: |
854 | if (IS_QLA27XX(ha)) | 848 | if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
855 | ha->flt_region_img_status_sec = start; | 849 | ha->flt_region_img_status_sec = start; |
856 | break; | 850 | break; |
857 | case FLT_REG_FW_SEC_27XX: | 851 | case FLT_REG_FW_SEC_27XX: |
858 | if (IS_QLA27XX(ha)) | 852 | if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
859 | ha->flt_region_fw_sec = start; | 853 | ha->flt_region_fw_sec = start; |
860 | break; | 854 | break; |
861 | case FLT_REG_BOOTLOAD_SEC_27XX: | 855 | case FLT_REG_BOOTLOAD_SEC_27XX: |
862 | if (IS_QLA27XX(ha)) | 856 | if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
863 | ha->flt_region_boot_sec = start; | 857 | ha->flt_region_boot_sec = start; |
864 | break; | 858 | break; |
859 | case FLT_REG_AUX_IMG_PRI_28XX: | ||
860 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) | ||
861 | ha->flt_region_aux_img_status_pri = start; | ||
862 | break; | ||
863 | case FLT_REG_AUX_IMG_SEC_28XX: | ||
864 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) | ||
865 | ha->flt_region_aux_img_status_sec = start; | ||
866 | break; | ||
867 | case FLT_REG_NVRAM_SEC_28XX_0: | ||
868 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) | ||
869 | if (ha->port_no == 0) | ||
870 | ha->flt_region_nvram_sec = start; | ||
871 | break; | ||
872 | case FLT_REG_NVRAM_SEC_28XX_1: | ||
873 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) | ||
874 | if (ha->port_no == 1) | ||
875 | ha->flt_region_nvram_sec = start; | ||
876 | break; | ||
877 | case FLT_REG_NVRAM_SEC_28XX_2: | ||
878 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) | ||
879 | if (ha->port_no == 2) | ||
880 | ha->flt_region_nvram_sec = start; | ||
881 | break; | ||
882 | case FLT_REG_NVRAM_SEC_28XX_3: | ||
883 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) | ||
884 | if (ha->port_no == 3) | ||
885 | ha->flt_region_nvram_sec = start; | ||
886 | break; | ||
865 | case FLT_REG_VPD_SEC_27XX_0: | 887 | case FLT_REG_VPD_SEC_27XX_0: |
866 | if (IS_QLA27XX(ha)) | 888 | case FLT_REG_VPD_SEC_28XX_0: |
867 | ha->flt_region_vpd_sec = start; | 889 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
890 | ha->flt_region_vpd_nvram_sec = start; | ||
891 | if (ha->port_no == 0) | ||
892 | ha->flt_region_vpd_sec = start; | ||
893 | } | ||
868 | break; | 894 | break; |
869 | case FLT_REG_VPD_SEC_27XX_1: | 895 | case FLT_REG_VPD_SEC_27XX_1: |
870 | if (IS_QLA27XX(ha)) | 896 | case FLT_REG_VPD_SEC_28XX_1: |
871 | ha->flt_region_vpd_sec = start; | 897 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
898 | if (ha->port_no == 1) | ||
899 | ha->flt_region_vpd_sec = start; | ||
872 | break; | 900 | break; |
873 | case FLT_REG_VPD_SEC_27XX_2: | 901 | case FLT_REG_VPD_SEC_27XX_2: |
874 | if (IS_QLA27XX(ha)) | 902 | case FLT_REG_VPD_SEC_28XX_2: |
875 | ha->flt_region_vpd_sec = start; | 903 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
904 | if (ha->port_no == 2) | ||
905 | ha->flt_region_vpd_sec = start; | ||
876 | break; | 906 | break; |
877 | case FLT_REG_VPD_SEC_27XX_3: | 907 | case FLT_REG_VPD_SEC_27XX_3: |
878 | if (IS_QLA27XX(ha)) | 908 | case FLT_REG_VPD_SEC_28XX_3: |
879 | ha->flt_region_vpd_sec = start; | 909 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
910 | if (ha->port_no == 3) | ||
911 | ha->flt_region_vpd_sec = start; | ||
880 | break; | 912 | break; |
881 | } | 913 | } |
882 | } | 914 | } |
@@ -912,22 +944,19 @@ qla2xxx_get_fdt_info(scsi_qla_host_t *vha) | |||
912 | #define FLASH_BLK_SIZE_32K 0x8000 | 944 | #define FLASH_BLK_SIZE_32K 0x8000 |
913 | #define FLASH_BLK_SIZE_64K 0x10000 | 945 | #define FLASH_BLK_SIZE_64K 0x10000 |
914 | const char *loc, *locations[] = { "MID", "FDT" }; | 946 | const char *loc, *locations[] = { "MID", "FDT" }; |
947 | struct qla_hw_data *ha = vha->hw; | ||
948 | struct req_que *req = ha->req_q_map[0]; | ||
915 | uint16_t cnt, chksum; | 949 | uint16_t cnt, chksum; |
916 | uint16_t *wptr; | 950 | uint16_t *wptr = (void *)req->ring; |
917 | struct qla_fdt_layout *fdt; | 951 | struct qla_fdt_layout *fdt = (void *)req->ring; |
918 | uint8_t man_id, flash_id; | 952 | uint8_t man_id, flash_id; |
919 | uint16_t mid = 0, fid = 0; | 953 | uint16_t mid = 0, fid = 0; |
920 | struct qla_hw_data *ha = vha->hw; | ||
921 | struct req_que *req = ha->req_q_map[0]; | ||
922 | 954 | ||
923 | wptr = (uint16_t *)req->ring; | 955 | qla24xx_read_flash_data(vha, (void *)fdt, ha->flt_region_fdt, |
924 | fdt = (struct qla_fdt_layout *)req->ring; | 956 | OPTROM_BURST_DWORDS); |
925 | ha->isp_ops->read_optrom(vha, (uint8_t *)req->ring, | 957 | if (le16_to_cpu(*wptr) == 0xffff) |
926 | ha->flt_region_fdt << 2, OPTROM_BURST_SIZE); | ||
927 | if (*wptr == cpu_to_le16(0xffff)) | ||
928 | goto no_flash_data; | 958 | goto no_flash_data; |
929 | if (fdt->sig[0] != 'Q' || fdt->sig[1] != 'L' || fdt->sig[2] != 'I' || | 959 | if (memcmp(fdt->sig, "QLID", 4)) |
930 | fdt->sig[3] != 'D') | ||
931 | goto no_flash_data; | 960 | goto no_flash_data; |
932 | 961 | ||
933 | for (cnt = 0, chksum = 0; cnt < sizeof(*fdt) >> 1; cnt++, wptr++) | 962 | for (cnt = 0, chksum = 0; cnt < sizeof(*fdt) >> 1; cnt++, wptr++) |
@@ -938,7 +967,7 @@ qla2xxx_get_fdt_info(scsi_qla_host_t *vha) | |||
938 | " checksum=0x%x id=%c version0x%x.\n", chksum, | 967 | " checksum=0x%x id=%c version0x%x.\n", chksum, |
939 | fdt->sig[0], le16_to_cpu(fdt->version)); | 968 | fdt->sig[0], le16_to_cpu(fdt->version)); |
940 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0113, | 969 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0113, |
941 | (uint8_t *)fdt, sizeof(*fdt)); | 970 | fdt, sizeof(*fdt)); |
942 | goto no_flash_data; | 971 | goto no_flash_data; |
943 | } | 972 | } |
944 | 973 | ||
@@ -958,7 +987,7 @@ qla2xxx_get_fdt_info(scsi_qla_host_t *vha) | |||
958 | ha->fdt_unprotect_sec_cmd = flash_conf_addr(ha, 0x0300 | | 987 | ha->fdt_unprotect_sec_cmd = flash_conf_addr(ha, 0x0300 | |
959 | fdt->unprotect_sec_cmd); | 988 | fdt->unprotect_sec_cmd); |
960 | ha->fdt_protect_sec_cmd = fdt->protect_sec_cmd ? | 989 | ha->fdt_protect_sec_cmd = fdt->protect_sec_cmd ? |
961 | flash_conf_addr(ha, 0x0300 | fdt->protect_sec_cmd): | 990 | flash_conf_addr(ha, 0x0300 | fdt->protect_sec_cmd) : |
962 | flash_conf_addr(ha, 0x0336); | 991 | flash_conf_addr(ha, 0x0336); |
963 | } | 992 | } |
964 | goto done; | 993 | goto done; |
@@ -1019,8 +1048,7 @@ qla2xxx_get_idc_param(scsi_qla_host_t *vha) | |||
1019 | return; | 1048 | return; |
1020 | 1049 | ||
1021 | wptr = (uint32_t *)req->ring; | 1050 | wptr = (uint32_t *)req->ring; |
1022 | ha->isp_ops->read_optrom(vha, (uint8_t *)req->ring, | 1051 | ha->isp_ops->read_optrom(vha, req->ring, QLA82XX_IDC_PARAM_ADDR, 8); |
1023 | QLA82XX_IDC_PARAM_ADDR , 8); | ||
1024 | 1052 | ||
1025 | if (*wptr == cpu_to_le32(0xffffffff)) { | 1053 | if (*wptr == cpu_to_le32(0xffffffff)) { |
1026 | ha->fcoe_dev_init_timeout = QLA82XX_ROM_DEV_INIT_TIMEOUT; | 1054 | ha->fcoe_dev_init_timeout = QLA82XX_ROM_DEV_INIT_TIMEOUT; |
@@ -1045,7 +1073,8 @@ qla2xxx_get_flash_info(scsi_qla_host_t *vha) | |||
1045 | struct qla_hw_data *ha = vha->hw; | 1073 | struct qla_hw_data *ha = vha->hw; |
1046 | 1074 | ||
1047 | if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && | 1075 | if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && |
1048 | !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha) && !IS_QLA27XX(ha)) | 1076 | !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha) && |
1077 | !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) | ||
1049 | return QLA_SUCCESS; | 1078 | return QLA_SUCCESS; |
1050 | 1079 | ||
1051 | ret = qla2xxx_find_flt_start(vha, &flt_addr); | 1080 | ret = qla2xxx_find_flt_start(vha, &flt_addr); |
@@ -1081,8 +1110,8 @@ qla2xxx_flash_npiv_conf(scsi_qla_host_t *vha) | |||
1081 | if (IS_QLA8044(ha)) | 1110 | if (IS_QLA8044(ha)) |
1082 | return; | 1111 | return; |
1083 | 1112 | ||
1084 | ha->isp_ops->read_optrom(vha, (uint8_t *)&hdr, | 1113 | ha->isp_ops->read_optrom(vha, &hdr, ha->flt_region_npiv_conf << 2, |
1085 | ha->flt_region_npiv_conf << 2, sizeof(struct qla_npiv_header)); | 1114 | sizeof(struct qla_npiv_header)); |
1086 | if (hdr.version == cpu_to_le16(0xffff)) | 1115 | if (hdr.version == cpu_to_le16(0xffff)) |
1087 | return; | 1116 | return; |
1088 | if (hdr.version != cpu_to_le16(1)) { | 1117 | if (hdr.version != cpu_to_le16(1)) { |
@@ -1101,8 +1130,8 @@ qla2xxx_flash_npiv_conf(scsi_qla_host_t *vha) | |||
1101 | return; | 1130 | return; |
1102 | } | 1131 | } |
1103 | 1132 | ||
1104 | ha->isp_ops->read_optrom(vha, (uint8_t *)data, | 1133 | ha->isp_ops->read_optrom(vha, data, ha->flt_region_npiv_conf << 2, |
1105 | ha->flt_region_npiv_conf << 2, NPIV_CONFIG_SIZE); | 1134 | NPIV_CONFIG_SIZE); |
1106 | 1135 | ||
1107 | cnt = (sizeof(hdr) + le16_to_cpu(hdr.entries) * sizeof(*entry)) >> 1; | 1136 | cnt = (sizeof(hdr) + le16_to_cpu(hdr.entries) * sizeof(*entry)) >> 1; |
1108 | for (wptr = data, chksum = 0; cnt--; wptr++) | 1137 | for (wptr = data, chksum = 0; cnt--; wptr++) |
@@ -1139,10 +1168,8 @@ qla2xxx_flash_npiv_conf(scsi_qla_host_t *vha) | |||
1139 | vid.node_name = wwn_to_u64(entry->node_name); | 1168 | vid.node_name = wwn_to_u64(entry->node_name); |
1140 | 1169 | ||
1141 | ql_dbg(ql_dbg_user, vha, 0x7093, | 1170 | ql_dbg(ql_dbg_user, vha, 0x7093, |
1142 | "NPIV[%02x]: wwpn=%llx " | 1171 | "NPIV[%02x]: wwpn=%llx wwnn=%llx vf_id=%#x Q_qos=%#x F_qos=%#x.\n", |
1143 | "wwnn=%llx vf_id=0x%x Q_qos=0x%x F_qos=0x%x.\n", cnt, | 1172 | cnt, vid.port_name, vid.node_name, |
1144 | (unsigned long long)vid.port_name, | ||
1145 | (unsigned long long)vid.node_name, | ||
1146 | le16_to_cpu(entry->vf_id), | 1173 | le16_to_cpu(entry->vf_id), |
1147 | entry->q_qos, entry->f_qos); | 1174 | entry->q_qos, entry->f_qos); |
1148 | 1175 | ||
@@ -1150,10 +1177,8 @@ qla2xxx_flash_npiv_conf(scsi_qla_host_t *vha) | |||
1150 | vport = fc_vport_create(vha->host, 0, &vid); | 1177 | vport = fc_vport_create(vha->host, 0, &vid); |
1151 | if (!vport) | 1178 | if (!vport) |
1152 | ql_log(ql_log_warn, vha, 0x7094, | 1179 | ql_log(ql_log_warn, vha, 0x7094, |
1153 | "NPIV-Config Failed to create vport [%02x]: " | 1180 | "NPIV-Config Failed to create vport [%02x]: wwpn=%llx wwnn=%llx.\n", |
1154 | "wwpn=%llx wwnn=%llx.\n", cnt, | 1181 | cnt, vid.port_name, vid.node_name); |
1155 | (unsigned long long)vid.port_name, | ||
1156 | (unsigned long long)vid.node_name); | ||
1157 | } | 1182 | } |
1158 | } | 1183 | } |
1159 | done: | 1184 | done: |
@@ -1188,9 +1213,10 @@ done: | |||
1188 | static int | 1213 | static int |
1189 | qla24xx_protect_flash(scsi_qla_host_t *vha) | 1214 | qla24xx_protect_flash(scsi_qla_host_t *vha) |
1190 | { | 1215 | { |
1191 | uint32_t cnt; | ||
1192 | struct qla_hw_data *ha = vha->hw; | 1216 | struct qla_hw_data *ha = vha->hw; |
1193 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 1217 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
1218 | ulong cnt = 300; | ||
1219 | uint32_t faddr, dword; | ||
1194 | 1220 | ||
1195 | if (ha->flags.fac_supported) | 1221 | if (ha->flags.fac_supported) |
1196 | return qla81xx_fac_do_write_enable(vha, 0); | 1222 | return qla81xx_fac_do_write_enable(vha, 0); |
@@ -1199,11 +1225,14 @@ qla24xx_protect_flash(scsi_qla_host_t *vha) | |||
1199 | goto skip_wrt_protect; | 1225 | goto skip_wrt_protect; |
1200 | 1226 | ||
1201 | /* Enable flash write-protection and wait for completion. */ | 1227 | /* Enable flash write-protection and wait for completion. */ |
1202 | qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), | 1228 | faddr = flash_conf_addr(ha, 0x101); |
1203 | ha->fdt_wrt_disable); | 1229 | qla24xx_write_flash_dword(ha, faddr, ha->fdt_wrt_disable); |
1204 | for (cnt = 300; cnt && | 1230 | faddr = flash_conf_addr(ha, 0x5); |
1205 | qla24xx_read_flash_dword(ha, flash_conf_addr(ha, 0x005)) & BIT_0; | 1231 | while (cnt--) { |
1206 | cnt--) { | 1232 | if (!qla24xx_read_flash_dword(ha, faddr, &dword)) { |
1233 | if (!(dword & BIT_0)) | ||
1234 | break; | ||
1235 | } | ||
1207 | udelay(10); | 1236 | udelay(10); |
1208 | } | 1237 | } |
1209 | 1238 | ||
@@ -1211,7 +1240,6 @@ skip_wrt_protect: | |||
1211 | /* Disable flash write. */ | 1240 | /* Disable flash write. */ |
1212 | WRT_REG_DWORD(®->ctrl_status, | 1241 | WRT_REG_DWORD(®->ctrl_status, |
1213 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); | 1242 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); |
1214 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | ||
1215 | 1243 | ||
1216 | return QLA_SUCCESS; | 1244 | return QLA_SUCCESS; |
1217 | } | 1245 | } |
@@ -1239,107 +1267,103 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, | |||
1239 | uint32_t dwords) | 1267 | uint32_t dwords) |
1240 | { | 1268 | { |
1241 | int ret; | 1269 | int ret; |
1242 | uint32_t liter; | 1270 | ulong liter; |
1243 | uint32_t sec_mask, rest_addr; | 1271 | ulong dburst = OPTROM_BURST_DWORDS; /* burst size in dwords */ |
1244 | uint32_t fdata; | 1272 | uint32_t sec_mask, rest_addr, fdata; |
1245 | dma_addr_t optrom_dma; | 1273 | dma_addr_t optrom_dma; |
1246 | void *optrom = NULL; | 1274 | void *optrom = NULL; |
1247 | struct qla_hw_data *ha = vha->hw; | 1275 | struct qla_hw_data *ha = vha->hw; |
1248 | 1276 | ||
1249 | /* Prepare burst-capable write on supported ISPs. */ | 1277 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) && |
1250 | if ((IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || | 1278 | !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
1251 | IS_QLA27XX(ha)) && | 1279 | goto next; |
1252 | !(faddr & 0xfff) && dwords > OPTROM_BURST_DWORDS) { | ||
1253 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | ||
1254 | &optrom_dma, GFP_KERNEL); | ||
1255 | if (!optrom) { | ||
1256 | ql_log(ql_log_warn, vha, 0x7095, | ||
1257 | "Unable to allocate " | ||
1258 | "memory for optrom burst write (%x KB).\n", | ||
1259 | OPTROM_BURST_SIZE / 1024); | ||
1260 | } | ||
1261 | } | ||
1262 | 1280 | ||
1263 | rest_addr = (ha->fdt_block_size >> 2) - 1; | 1281 | /* Allocate dma buffer for burst write */ |
1264 | sec_mask = ~rest_addr; | 1282 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, |
1283 | &optrom_dma, GFP_KERNEL); | ||
1284 | if (!optrom) { | ||
1285 | ql_log(ql_log_warn, vha, 0x7095, | ||
1286 | "Failed allocate burst (%x bytes)\n", OPTROM_BURST_SIZE); | ||
1287 | } | ||
1265 | 1288 | ||
1289 | next: | ||
1290 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0x7095, | ||
1291 | "Unprotect flash...\n"); | ||
1266 | ret = qla24xx_unprotect_flash(vha); | 1292 | ret = qla24xx_unprotect_flash(vha); |
1267 | if (ret != QLA_SUCCESS) { | 1293 | if (ret) { |
1268 | ql_log(ql_log_warn, vha, 0x7096, | 1294 | ql_log(ql_log_warn, vha, 0x7096, |
1269 | "Unable to unprotect flash for update.\n"); | 1295 | "Failed to unprotect flash.\n"); |
1270 | goto done; | 1296 | goto done; |
1271 | } | 1297 | } |
1272 | 1298 | ||
1299 | rest_addr = (ha->fdt_block_size >> 2) - 1; | ||
1300 | sec_mask = ~rest_addr; | ||
1273 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { | 1301 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { |
1274 | fdata = (faddr & sec_mask) << 2; | 1302 | fdata = (faddr & sec_mask) << 2; |
1275 | 1303 | ||
1276 | /* Are we at the beginning of a sector? */ | 1304 | /* Are we at the beginning of a sector? */ |
1277 | if ((faddr & rest_addr) == 0) { | 1305 | if (!(faddr & rest_addr)) { |
1278 | /* Do sector unprotect. */ | 1306 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0x7095, |
1279 | if (ha->fdt_unprotect_sec_cmd) | 1307 | "Erase sector %#x...\n", faddr); |
1280 | qla24xx_write_flash_dword(ha, | 1308 | |
1281 | ha->fdt_unprotect_sec_cmd, | ||
1282 | (fdata & 0xff00) | ((fdata << 16) & | ||
1283 | 0xff0000) | ((fdata >> 16) & 0xff)); | ||
1284 | ret = qla24xx_erase_sector(vha, fdata); | 1309 | ret = qla24xx_erase_sector(vha, fdata); |
1285 | if (ret != QLA_SUCCESS) { | 1310 | if (ret) { |
1286 | ql_dbg(ql_dbg_user, vha, 0x7007, | 1311 | ql_dbg(ql_dbg_user, vha, 0x7007, |
1287 | "Unable to erase erase sector: address=%x.\n", | 1312 | "Failed to erase sector %x.\n", faddr); |
1288 | faddr); | ||
1289 | break; | 1313 | break; |
1290 | } | 1314 | } |
1291 | } | 1315 | } |
1292 | 1316 | ||
1293 | /* Go with burst-write. */ | 1317 | if (optrom) { |
1294 | if (optrom && (liter + OPTROM_BURST_DWORDS) <= dwords) { | 1318 | /* If smaller than a burst remaining */ |
1295 | /* Copy data to DMA'ble buffer. */ | 1319 | if (dwords - liter < dburst) |
1296 | memcpy(optrom, dwptr, OPTROM_BURST_SIZE); | 1320 | dburst = dwords - liter; |
1297 | 1321 | ||
1322 | /* Copy to dma buffer */ | ||
1323 | memcpy(optrom, dwptr, dburst << 2); | ||
1324 | |||
1325 | /* Burst write */ | ||
1326 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0x7095, | ||
1327 | "Write burst (%#lx dwords)...\n", dburst); | ||
1298 | ret = qla2x00_load_ram(vha, optrom_dma, | 1328 | ret = qla2x00_load_ram(vha, optrom_dma, |
1299 | flash_data_addr(ha, faddr), | 1329 | flash_data_addr(ha, faddr), dburst); |
1300 | OPTROM_BURST_DWORDS); | 1330 | if (!ret) { |
1301 | if (ret != QLA_SUCCESS) { | 1331 | liter += dburst - 1; |
1302 | ql_log(ql_log_warn, vha, 0x7097, | 1332 | faddr += dburst - 1; |
1303 | "Unable to burst-write optrom segment " | 1333 | dwptr += dburst - 1; |
1304 | "(%x/%x/%llx).\n", ret, | ||
1305 | flash_data_addr(ha, faddr), | ||
1306 | (unsigned long long)optrom_dma); | ||
1307 | ql_log(ql_log_warn, vha, 0x7098, | ||
1308 | "Reverting to slow-write.\n"); | ||
1309 | |||
1310 | dma_free_coherent(&ha->pdev->dev, | ||
1311 | OPTROM_BURST_SIZE, optrom, optrom_dma); | ||
1312 | optrom = NULL; | ||
1313 | } else { | ||
1314 | liter += OPTROM_BURST_DWORDS - 1; | ||
1315 | faddr += OPTROM_BURST_DWORDS - 1; | ||
1316 | dwptr += OPTROM_BURST_DWORDS - 1; | ||
1317 | continue; | 1334 | continue; |
1318 | } | 1335 | } |
1336 | |||
1337 | ql_log(ql_log_warn, vha, 0x7097, | ||
1338 | "Failed burst-write at %x (%p/%#llx)....\n", | ||
1339 | flash_data_addr(ha, faddr), optrom, | ||
1340 | (u64)optrom_dma); | ||
1341 | |||
1342 | dma_free_coherent(&ha->pdev->dev, | ||
1343 | OPTROM_BURST_SIZE, optrom, optrom_dma); | ||
1344 | optrom = NULL; | ||
1345 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) | ||
1346 | break; | ||
1347 | ql_log(ql_log_warn, vha, 0x7098, | ||
1348 | "Reverting to slow write...\n"); | ||
1319 | } | 1349 | } |
1320 | 1350 | ||
1351 | /* Slow write */ | ||
1321 | ret = qla24xx_write_flash_dword(ha, | 1352 | ret = qla24xx_write_flash_dword(ha, |
1322 | flash_data_addr(ha, faddr), cpu_to_le32(*dwptr)); | 1353 | flash_data_addr(ha, faddr), cpu_to_le32(*dwptr)); |
1323 | if (ret != QLA_SUCCESS) { | 1354 | if (ret) { |
1324 | ql_dbg(ql_dbg_user, vha, 0x7006, | 1355 | ql_dbg(ql_dbg_user, vha, 0x7006, |
1325 | "Unable to program flash address=%x data=%x.\n", | 1356 | "Failed slopw write %x (%x)\n", faddr, *dwptr); |
1326 | faddr, *dwptr); | ||
1327 | break; | 1357 | break; |
1328 | } | 1358 | } |
1329 | |||
1330 | /* Do sector protect. */ | ||
1331 | if (ha->fdt_unprotect_sec_cmd && | ||
1332 | ((faddr & rest_addr) == rest_addr)) | ||
1333 | qla24xx_write_flash_dword(ha, | ||
1334 | ha->fdt_protect_sec_cmd, | ||
1335 | (fdata & 0xff00) | ((fdata << 16) & | ||
1336 | 0xff0000) | ((fdata >> 16) & 0xff)); | ||
1337 | } | 1359 | } |
1338 | 1360 | ||
1361 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0x7095, | ||
1362 | "Protect flash...\n"); | ||
1339 | ret = qla24xx_protect_flash(vha); | 1363 | ret = qla24xx_protect_flash(vha); |
1340 | if (ret != QLA_SUCCESS) | 1364 | if (ret) |
1341 | ql_log(ql_log_warn, vha, 0x7099, | 1365 | ql_log(ql_log_warn, vha, 0x7099, |
1342 | "Unable to protect flash after update.\n"); | 1366 | "Failed to protect flash\n"); |
1343 | done: | 1367 | done: |
1344 | if (optrom) | 1368 | if (optrom) |
1345 | dma_free_coherent(&ha->pdev->dev, | 1369 | dma_free_coherent(&ha->pdev->dev, |
@@ -1349,7 +1373,7 @@ done: | |||
1349 | } | 1373 | } |
1350 | 1374 | ||
1351 | uint8_t * | 1375 | uint8_t * |
1352 | qla2x00_read_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr, | 1376 | qla2x00_read_nvram_data(scsi_qla_host_t *vha, void *buf, uint32_t naddr, |
1353 | uint32_t bytes) | 1377 | uint32_t bytes) |
1354 | { | 1378 | { |
1355 | uint32_t i; | 1379 | uint32_t i; |
@@ -1368,27 +1392,30 @@ qla2x00_read_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr, | |||
1368 | } | 1392 | } |
1369 | 1393 | ||
1370 | uint8_t * | 1394 | uint8_t * |
1371 | qla24xx_read_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr, | 1395 | qla24xx_read_nvram_data(scsi_qla_host_t *vha, void *buf, uint32_t naddr, |
1372 | uint32_t bytes) | 1396 | uint32_t bytes) |
1373 | { | 1397 | { |
1374 | uint32_t i; | ||
1375 | uint32_t *dwptr; | ||
1376 | struct qla_hw_data *ha = vha->hw; | 1398 | struct qla_hw_data *ha = vha->hw; |
1399 | uint32_t *dwptr = buf; | ||
1400 | uint32_t i; | ||
1377 | 1401 | ||
1378 | if (IS_P3P_TYPE(ha)) | 1402 | if (IS_P3P_TYPE(ha)) |
1379 | return buf; | 1403 | return buf; |
1380 | 1404 | ||
1381 | /* Dword reads to flash. */ | 1405 | /* Dword reads to flash. */ |
1382 | dwptr = (uint32_t *)buf; | 1406 | naddr = nvram_data_addr(ha, naddr); |
1383 | for (i = 0; i < bytes >> 2; i++, naddr++) | 1407 | bytes >>= 2; |
1384 | dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha, | 1408 | for (i = 0; i < bytes; i++, naddr++, dwptr++) { |
1385 | nvram_data_addr(ha, naddr))); | 1409 | if (qla24xx_read_flash_dword(ha, naddr, dwptr)) |
1410 | break; | ||
1411 | cpu_to_le32s(dwptr); | ||
1412 | } | ||
1386 | 1413 | ||
1387 | return buf; | 1414 | return buf; |
1388 | } | 1415 | } |
1389 | 1416 | ||
1390 | int | 1417 | int |
1391 | qla2x00_write_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr, | 1418 | qla2x00_write_nvram_data(scsi_qla_host_t *vha, void *buf, uint32_t naddr, |
1392 | uint32_t bytes) | 1419 | uint32_t bytes) |
1393 | { | 1420 | { |
1394 | int ret, stat; | 1421 | int ret, stat; |
@@ -1422,14 +1449,14 @@ qla2x00_write_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr, | |||
1422 | } | 1449 | } |
1423 | 1450 | ||
1424 | int | 1451 | int |
1425 | qla24xx_write_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr, | 1452 | qla24xx_write_nvram_data(scsi_qla_host_t *vha, void *buf, uint32_t naddr, |
1426 | uint32_t bytes) | 1453 | uint32_t bytes) |
1427 | { | 1454 | { |
1428 | int ret; | ||
1429 | uint32_t i; | ||
1430 | uint32_t *dwptr; | ||
1431 | struct qla_hw_data *ha = vha->hw; | 1455 | struct qla_hw_data *ha = vha->hw; |
1432 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 1456 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
1457 | uint32_t *dwptr = buf; | ||
1458 | uint32_t i; | ||
1459 | int ret; | ||
1433 | 1460 | ||
1434 | ret = QLA_SUCCESS; | 1461 | ret = QLA_SUCCESS; |
1435 | 1462 | ||
@@ -1446,11 +1473,10 @@ qla24xx_write_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr, | |||
1446 | qla24xx_write_flash_dword(ha, nvram_conf_addr(ha, 0x101), 0); | 1473 | qla24xx_write_flash_dword(ha, nvram_conf_addr(ha, 0x101), 0); |
1447 | 1474 | ||
1448 | /* Dword writes to flash. */ | 1475 | /* Dword writes to flash. */ |
1449 | dwptr = (uint32_t *)buf; | 1476 | naddr = nvram_data_addr(ha, naddr); |
1450 | for (i = 0; i < bytes >> 2; i++, naddr++, dwptr++) { | 1477 | bytes >>= 2; |
1451 | ret = qla24xx_write_flash_dword(ha, | 1478 | for (i = 0; i < bytes; i++, naddr++, dwptr++) { |
1452 | nvram_data_addr(ha, naddr), cpu_to_le32(*dwptr)); | 1479 | if (qla24xx_write_flash_dword(ha, naddr, cpu_to_le32(*dwptr))) { |
1453 | if (ret != QLA_SUCCESS) { | ||
1454 | ql_dbg(ql_dbg_user, vha, 0x709a, | 1480 | ql_dbg(ql_dbg_user, vha, 0x709a, |
1455 | "Unable to program nvram address=%x data=%x.\n", | 1481 | "Unable to program nvram address=%x data=%x.\n", |
1456 | naddr, *dwptr); | 1482 | naddr, *dwptr); |
@@ -1470,31 +1496,34 @@ qla24xx_write_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr, | |||
1470 | } | 1496 | } |
1471 | 1497 | ||
1472 | uint8_t * | 1498 | uint8_t * |
1473 | qla25xx_read_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr, | 1499 | qla25xx_read_nvram_data(scsi_qla_host_t *vha, void *buf, uint32_t naddr, |
1474 | uint32_t bytes) | 1500 | uint32_t bytes) |
1475 | { | 1501 | { |
1476 | uint32_t i; | ||
1477 | uint32_t *dwptr; | ||
1478 | struct qla_hw_data *ha = vha->hw; | 1502 | struct qla_hw_data *ha = vha->hw; |
1503 | uint32_t *dwptr = buf; | ||
1504 | uint32_t i; | ||
1479 | 1505 | ||
1480 | /* Dword reads to flash. */ | 1506 | /* Dword reads to flash. */ |
1481 | dwptr = (uint32_t *)buf; | 1507 | naddr = flash_data_addr(ha, ha->flt_region_vpd_nvram | naddr); |
1482 | for (i = 0; i < bytes >> 2; i++, naddr++) | 1508 | bytes >>= 2; |
1483 | dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha, | 1509 | for (i = 0; i < bytes; i++, naddr++, dwptr++) { |
1484 | flash_data_addr(ha, ha->flt_region_vpd_nvram | naddr))); | 1510 | if (qla24xx_read_flash_dword(ha, naddr, dwptr)) |
1511 | break; | ||
1512 | |||
1513 | cpu_to_le32s(dwptr); | ||
1514 | } | ||
1485 | 1515 | ||
1486 | return buf; | 1516 | return buf; |
1487 | } | 1517 | } |
1488 | 1518 | ||
1519 | #define RMW_BUFFER_SIZE (64 * 1024) | ||
1489 | int | 1520 | int |
1490 | qla25xx_write_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr, | 1521 | qla25xx_write_nvram_data(scsi_qla_host_t *vha, void *buf, uint32_t naddr, |
1491 | uint32_t bytes) | 1522 | uint32_t bytes) |
1492 | { | 1523 | { |
1493 | struct qla_hw_data *ha = vha->hw; | 1524 | struct qla_hw_data *ha = vha->hw; |
1494 | #define RMW_BUFFER_SIZE (64 * 1024) | 1525 | uint8_t *dbuf = vmalloc(RMW_BUFFER_SIZE); |
1495 | uint8_t *dbuf; | ||
1496 | 1526 | ||
1497 | dbuf = vmalloc(RMW_BUFFER_SIZE); | ||
1498 | if (!dbuf) | 1527 | if (!dbuf) |
1499 | return QLA_MEMORY_ALLOC_FAILED; | 1528 | return QLA_MEMORY_ALLOC_FAILED; |
1500 | ha->isp_ops->read_optrom(vha, dbuf, ha->flt_region_vpd_nvram << 2, | 1529 | ha->isp_ops->read_optrom(vha, dbuf, ha->flt_region_vpd_nvram << 2, |
@@ -1728,7 +1757,7 @@ qla83xx_select_led_port(struct qla_hw_data *ha) | |||
1728 | { | 1757 | { |
1729 | uint32_t led_select_value = 0; | 1758 | uint32_t led_select_value = 0; |
1730 | 1759 | ||
1731 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha)) | 1760 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha)) |
1732 | goto out; | 1761 | goto out; |
1733 | 1762 | ||
1734 | if (ha->port_no == 0) | 1763 | if (ha->port_no == 0) |
@@ -1749,13 +1778,14 @@ qla83xx_beacon_blink(struct scsi_qla_host *vha) | |||
1749 | uint16_t orig_led_cfg[6]; | 1778 | uint16_t orig_led_cfg[6]; |
1750 | uint32_t led_10_value, led_43_value; | 1779 | uint32_t led_10_value, led_43_value; |
1751 | 1780 | ||
1752 | if (!IS_QLA83XX(ha) && !IS_QLA81XX(ha) && !IS_QLA27XX(ha)) | 1781 | if (!IS_QLA83XX(ha) && !IS_QLA81XX(ha) && !IS_QLA27XX(ha) && |
1782 | !IS_QLA28XX(ha)) | ||
1753 | return; | 1783 | return; |
1754 | 1784 | ||
1755 | if (!ha->beacon_blink_led) | 1785 | if (!ha->beacon_blink_led) |
1756 | return; | 1786 | return; |
1757 | 1787 | ||
1758 | if (IS_QLA27XX(ha)) { | 1788 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
1759 | qla2x00_write_ram_word(vha, 0x1003, 0x40000230); | 1789 | qla2x00_write_ram_word(vha, 0x1003, 0x40000230); |
1760 | qla2x00_write_ram_word(vha, 0x1004, 0x40000230); | 1790 | qla2x00_write_ram_word(vha, 0x1004, 0x40000230); |
1761 | } else if (IS_QLA2031(ha)) { | 1791 | } else if (IS_QLA2031(ha)) { |
@@ -1845,7 +1875,7 @@ qla24xx_beacon_on(struct scsi_qla_host *vha) | |||
1845 | return QLA_FUNCTION_FAILED; | 1875 | return QLA_FUNCTION_FAILED; |
1846 | } | 1876 | } |
1847 | 1877 | ||
1848 | if (IS_QLA2031(ha) || IS_QLA27XX(ha)) | 1878 | if (IS_QLA2031(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
1849 | goto skip_gpio; | 1879 | goto skip_gpio; |
1850 | 1880 | ||
1851 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1881 | spin_lock_irqsave(&ha->hardware_lock, flags); |
@@ -1885,7 +1915,7 @@ qla24xx_beacon_off(struct scsi_qla_host *vha) | |||
1885 | 1915 | ||
1886 | ha->beacon_blink_led = 0; | 1916 | ha->beacon_blink_led = 0; |
1887 | 1917 | ||
1888 | if (IS_QLA2031(ha) || IS_QLA27XX(ha)) | 1918 | if (IS_QLA2031(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
1889 | goto set_fw_options; | 1919 | goto set_fw_options; |
1890 | 1920 | ||
1891 | if (IS_QLA8031(ha) || IS_QLA81XX(ha)) | 1921 | if (IS_QLA8031(ha) || IS_QLA81XX(ha)) |
@@ -2314,8 +2344,8 @@ qla2x00_resume_hba(struct scsi_qla_host *vha) | |||
2314 | scsi_unblock_requests(vha->host); | 2344 | scsi_unblock_requests(vha->host); |
2315 | } | 2345 | } |
2316 | 2346 | ||
2317 | uint8_t * | 2347 | void * |
2318 | qla2x00_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | 2348 | qla2x00_read_optrom_data(struct scsi_qla_host *vha, void *buf, |
2319 | uint32_t offset, uint32_t length) | 2349 | uint32_t offset, uint32_t length) |
2320 | { | 2350 | { |
2321 | uint32_t addr, midpoint; | 2351 | uint32_t addr, midpoint; |
@@ -2349,12 +2379,12 @@ qla2x00_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | |||
2349 | } | 2379 | } |
2350 | 2380 | ||
2351 | int | 2381 | int |
2352 | qla2x00_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | 2382 | qla2x00_write_optrom_data(struct scsi_qla_host *vha, void *buf, |
2353 | uint32_t offset, uint32_t length) | 2383 | uint32_t offset, uint32_t length) |
2354 | { | 2384 | { |
2355 | 2385 | ||
2356 | int rval; | 2386 | int rval; |
2357 | uint8_t man_id, flash_id, sec_number, data; | 2387 | uint8_t man_id, flash_id, sec_number, *data; |
2358 | uint16_t wd; | 2388 | uint16_t wd; |
2359 | uint32_t addr, liter, sec_mask, rest_addr; | 2389 | uint32_t addr, liter, sec_mask, rest_addr; |
2360 | struct qla_hw_data *ha = vha->hw; | 2390 | struct qla_hw_data *ha = vha->hw; |
@@ -2483,7 +2513,7 @@ update_flash: | |||
2483 | 2513 | ||
2484 | for (addr = offset, liter = 0; liter < length; liter++, | 2514 | for (addr = offset, liter = 0; liter < length; liter++, |
2485 | addr++) { | 2515 | addr++) { |
2486 | data = buf[liter]; | 2516 | data = buf + liter; |
2487 | /* Are we at the beginning of a sector? */ | 2517 | /* Are we at the beginning of a sector? */ |
2488 | if ((addr & rest_addr) == 0) { | 2518 | if ((addr & rest_addr) == 0) { |
2489 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) { | 2519 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) { |
@@ -2551,7 +2581,7 @@ update_flash: | |||
2551 | } | 2581 | } |
2552 | } | 2582 | } |
2553 | 2583 | ||
2554 | if (qla2x00_program_flash_address(ha, addr, data, | 2584 | if (qla2x00_program_flash_address(ha, addr, *data, |
2555 | man_id, flash_id)) { | 2585 | man_id, flash_id)) { |
2556 | rval = QLA_FUNCTION_FAILED; | 2586 | rval = QLA_FUNCTION_FAILED; |
2557 | break; | 2587 | break; |
@@ -2567,8 +2597,8 @@ update_flash: | |||
2567 | return rval; | 2597 | return rval; |
2568 | } | 2598 | } |
2569 | 2599 | ||
2570 | uint8_t * | 2600 | void * |
2571 | qla24xx_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | 2601 | qla24xx_read_optrom_data(struct scsi_qla_host *vha, void *buf, |
2572 | uint32_t offset, uint32_t length) | 2602 | uint32_t offset, uint32_t length) |
2573 | { | 2603 | { |
2574 | struct qla_hw_data *ha = vha->hw; | 2604 | struct qla_hw_data *ha = vha->hw; |
@@ -2578,7 +2608,7 @@ qla24xx_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | |||
2578 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | 2608 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); |
2579 | 2609 | ||
2580 | /* Go with read. */ | 2610 | /* Go with read. */ |
2581 | qla24xx_read_flash_data(vha, (uint32_t *)buf, offset >> 2, length >> 2); | 2611 | qla24xx_read_flash_data(vha, (void *)buf, offset >> 2, length >> 2); |
2582 | 2612 | ||
2583 | /* Resume HBA. */ | 2613 | /* Resume HBA. */ |
2584 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | 2614 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); |
@@ -2587,8 +2617,340 @@ qla24xx_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | |||
2587 | return buf; | 2617 | return buf; |
2588 | } | 2618 | } |
2589 | 2619 | ||
2620 | static int | ||
2621 | qla28xx_extract_sfub_and_verify(struct scsi_qla_host *vha, uint32_t *buf, | ||
2622 | uint32_t len, uint32_t buf_size_without_sfub, uint8_t *sfub_buf) | ||
2623 | { | ||
2624 | uint32_t *p, check_sum = 0; | ||
2625 | int i; | ||
2626 | |||
2627 | p = buf + buf_size_without_sfub; | ||
2628 | |||
2629 | /* Extract SFUB from end of file */ | ||
2630 | memcpy(sfub_buf, (uint8_t *)p, | ||
2631 | sizeof(struct secure_flash_update_block)); | ||
2632 | |||
2633 | for (i = 0; i < (sizeof(struct secure_flash_update_block) >> 2); i++) | ||
2634 | check_sum += p[i]; | ||
2635 | |||
2636 | check_sum = (~check_sum) + 1; | ||
2637 | |||
2638 | if (check_sum != p[i]) { | ||
2639 | ql_log(ql_log_warn, vha, 0x7097, | ||
2640 | "SFUB checksum failed, 0x%x, 0x%x\n", | ||
2641 | check_sum, p[i]); | ||
2642 | return QLA_COMMAND_ERROR; | ||
2643 | } | ||
2644 | |||
2645 | return QLA_SUCCESS; | ||
2646 | } | ||
2647 | |||
2648 | static int | ||
2649 | qla28xx_get_flash_region(struct scsi_qla_host *vha, uint32_t start, | ||
2650 | struct qla_flt_region *region) | ||
2651 | { | ||
2652 | struct qla_hw_data *ha = vha->hw; | ||
2653 | struct qla_flt_header *flt; | ||
2654 | struct qla_flt_region *flt_reg; | ||
2655 | uint16_t cnt; | ||
2656 | int rval = QLA_FUNCTION_FAILED; | ||
2657 | |||
2658 | if (!ha->flt) | ||
2659 | return QLA_FUNCTION_FAILED; | ||
2660 | |||
2661 | flt = (struct qla_flt_header *)ha->flt; | ||
2662 | flt_reg = (struct qla_flt_region *)&flt[1]; | ||
2663 | cnt = le16_to_cpu(flt->length) / sizeof(struct qla_flt_region); | ||
2664 | |||
2665 | for (; cnt; cnt--, flt_reg++) { | ||
2666 | if (flt_reg->start == start) { | ||
2667 | memcpy((uint8_t *)region, flt_reg, | ||
2668 | sizeof(struct qla_flt_region)); | ||
2669 | rval = QLA_SUCCESS; | ||
2670 | break; | ||
2671 | } | ||
2672 | } | ||
2673 | |||
2674 | return rval; | ||
2675 | } | ||
2676 | |||
2677 | static int | ||
2678 | qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, | ||
2679 | uint32_t dwords) | ||
2680 | { | ||
2681 | struct qla_hw_data *ha = vha->hw; | ||
2682 | ulong liter; | ||
2683 | ulong dburst = OPTROM_BURST_DWORDS; /* burst size in dwords */ | ||
2684 | uint32_t sec_mask, rest_addr, fdata; | ||
2685 | void *optrom = NULL; | ||
2686 | dma_addr_t optrom_dma; | ||
2687 | int rval; | ||
2688 | struct secure_flash_update_block *sfub; | ||
2689 | dma_addr_t sfub_dma; | ||
2690 | uint32_t offset = faddr << 2; | ||
2691 | uint32_t buf_size_without_sfub = 0; | ||
2692 | struct qla_flt_region region; | ||
2693 | bool reset_to_rom = false; | ||
2694 | uint32_t risc_size, risc_attr = 0; | ||
2695 | uint32_t *fw_array = NULL; | ||
2696 | |||
2697 | /* Retrieve region info - must be a start address passed in */ | ||
2698 | rval = qla28xx_get_flash_region(vha, offset, ®ion); | ||
2699 | |||
2700 | if (rval != QLA_SUCCESS) { | ||
2701 | ql_log(ql_log_warn, vha, 0xffff, | ||
2702 | "Invalid address %x - not a region start address\n", | ||
2703 | offset); | ||
2704 | goto done; | ||
2705 | } | ||
2706 | |||
2707 | /* Allocate dma buffer for burst write */ | ||
2708 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | ||
2709 | &optrom_dma, GFP_KERNEL); | ||
2710 | if (!optrom) { | ||
2711 | ql_log(ql_log_warn, vha, 0x7095, | ||
2712 | "Failed allocate burst (%x bytes)\n", OPTROM_BURST_SIZE); | ||
2713 | rval = QLA_COMMAND_ERROR; | ||
2714 | goto done; | ||
2715 | } | ||
2716 | |||
2717 | /* | ||
2718 | * If adapter supports secure flash and region is secure | ||
2719 | * extract secure flash update block (SFUB) and verify | ||
2720 | */ | ||
2721 | if (ha->flags.secure_adapter && region.attribute) { | ||
2722 | |||
2723 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, | ||
2724 | "Region %x is secure\n", region.code); | ||
2725 | |||
2726 | if (region.code == FLT_REG_FW || | ||
2727 | region.code == FLT_REG_FW_SEC_27XX) { | ||
2728 | fw_array = dwptr; | ||
2729 | |||
2730 | /* 1st fw array */ | ||
2731 | risc_size = be32_to_cpu(fw_array[3]); | ||
2732 | risc_attr = be32_to_cpu(fw_array[9]); | ||
2733 | |||
2734 | buf_size_without_sfub = risc_size; | ||
2735 | fw_array += risc_size; | ||
2736 | |||
2737 | /* 2nd fw array */ | ||
2738 | risc_size = be32_to_cpu(fw_array[3]); | ||
2739 | |||
2740 | buf_size_without_sfub += risc_size; | ||
2741 | fw_array += risc_size; | ||
2742 | |||
2743 | /* 1st dump template */ | ||
2744 | risc_size = be32_to_cpu(fw_array[2]); | ||
2745 | |||
2746 | /* skip header and ignore checksum */ | ||
2747 | buf_size_without_sfub += risc_size; | ||
2748 | fw_array += risc_size; | ||
2749 | |||
2750 | if (risc_attr & BIT_9) { | ||
2751 | /* 2nd dump template */ | ||
2752 | risc_size = be32_to_cpu(fw_array[2]); | ||
2753 | |||
2754 | /* skip header and ignore checksum */ | ||
2755 | buf_size_without_sfub += risc_size; | ||
2756 | fw_array += risc_size; | ||
2757 | } | ||
2758 | } else { | ||
2759 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, | ||
2760 | "Secure region %x not supported\n", | ||
2761 | region.code); | ||
2762 | rval = QLA_COMMAND_ERROR; | ||
2763 | goto done; | ||
2764 | } | ||
2765 | |||
2766 | sfub = dma_alloc_coherent(&ha->pdev->dev, | ||
2767 | sizeof(struct secure_flash_update_block), &sfub_dma, | ||
2768 | GFP_KERNEL); | ||
2769 | if (!sfub) { | ||
2770 | ql_log(ql_log_warn, vha, 0xffff, | ||
2771 | "Unable to allocate memory for SFUB\n"); | ||
2772 | rval = QLA_COMMAND_ERROR; | ||
2773 | goto done; | ||
2774 | } | ||
2775 | |||
2776 | rval = qla28xx_extract_sfub_and_verify(vha, dwptr, dwords, | ||
2777 | buf_size_without_sfub, (uint8_t *)sfub); | ||
2778 | |||
2779 | if (rval != QLA_SUCCESS) | ||
2780 | goto done; | ||
2781 | |||
2782 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, | ||
2783 | "SFUB extract and verify successful\n"); | ||
2784 | } | ||
2785 | |||
2786 | rest_addr = (ha->fdt_block_size >> 2) - 1; | ||
2787 | sec_mask = ~rest_addr; | ||
2788 | |||
2789 | /* Lock semaphore */ | ||
2790 | rval = qla81xx_fac_semaphore_access(vha, FAC_SEMAPHORE_LOCK); | ||
2791 | if (rval != QLA_SUCCESS) { | ||
2792 | ql_log(ql_log_warn, vha, 0xffff, | ||
2793 | "Unable to lock flash semaphore."); | ||
2794 | goto done; | ||
2795 | } | ||
2796 | |||
2797 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0x7095, | ||
2798 | "Unprotect flash...\n"); | ||
2799 | rval = qla24xx_unprotect_flash(vha); | ||
2800 | if (rval) { | ||
2801 | qla81xx_fac_semaphore_access(vha, FAC_SEMAPHORE_UNLOCK); | ||
2802 | ql_log(ql_log_warn, vha, 0x7096, "Failed unprotect flash\n"); | ||
2803 | goto done; | ||
2804 | } | ||
2805 | |||
2806 | for (liter = 0; liter < dwords; liter++, faddr++) { | ||
2807 | fdata = (faddr & sec_mask) << 2; | ||
2808 | |||
2809 | /* If start of sector */ | ||
2810 | if (!(faddr & rest_addr)) { | ||
2811 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0x7095, | ||
2812 | "Erase sector %#x...\n", faddr); | ||
2813 | rval = qla24xx_erase_sector(vha, fdata); | ||
2814 | if (rval) { | ||
2815 | ql_dbg(ql_dbg_user, vha, 0x7007, | ||
2816 | "Failed erase sector %#x\n", faddr); | ||
2817 | goto write_protect; | ||
2818 | } | ||
2819 | } | ||
2820 | } | ||
2821 | |||
2822 | if (ha->flags.secure_adapter) { | ||
2823 | /* | ||
2824 | * If adapter supports secure flash but FW doesn't, | ||
2825 | * disable write protect, release semaphore and reset | ||
2826 | * chip to execute ROM code in order to update region securely | ||
2827 | */ | ||
2828 | if (!ha->flags.secure_fw) { | ||
2829 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, | ||
2830 | "Disable Write and Release Semaphore."); | ||
2831 | rval = qla24xx_protect_flash(vha); | ||
2832 | if (rval != QLA_SUCCESS) { | ||
2833 | qla81xx_fac_semaphore_access(vha, | ||
2834 | FAC_SEMAPHORE_UNLOCK); | ||
2835 | ql_log(ql_log_warn, vha, 0xffff, | ||
2836 | "Unable to protect flash."); | ||
2837 | goto done; | ||
2838 | } | ||
2839 | |||
2840 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, | ||
2841 | "Reset chip to ROM."); | ||
2842 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | ||
2843 | set_bit(ISP_ABORT_TO_ROM, &vha->dpc_flags); | ||
2844 | qla2xxx_wake_dpc(vha); | ||
2845 | rval = qla2x00_wait_for_chip_reset(vha); | ||
2846 | if (rval != QLA_SUCCESS) { | ||
2847 | ql_log(ql_log_warn, vha, 0xffff, | ||
2848 | "Unable to reset to ROM code."); | ||
2849 | goto done; | ||
2850 | } | ||
2851 | reset_to_rom = true; | ||
2852 | ha->flags.fac_supported = 0; | ||
2853 | |||
2854 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, | ||
2855 | "Lock Semaphore"); | ||
2856 | rval = qla2xxx_write_remote_register(vha, | ||
2857 | FLASH_SEMAPHORE_REGISTER_ADDR, 0x00020002); | ||
2858 | if (rval != QLA_SUCCESS) { | ||
2859 | ql_log(ql_log_warn, vha, 0xffff, | ||
2860 | "Unable to lock flash semaphore."); | ||
2861 | goto done; | ||
2862 | } | ||
2863 | |||
2864 | /* Unprotect flash */ | ||
2865 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, | ||
2866 | "Enable Write."); | ||
2867 | rval = qla2x00_write_ram_word(vha, 0x7ffd0101, 0); | ||
2868 | if (rval) { | ||
2869 | ql_log(ql_log_warn, vha, 0x7096, | ||
2870 | "Failed unprotect flash\n"); | ||
2871 | goto done; | ||
2872 | } | ||
2873 | } | ||
2874 | |||
2875 | /* If region is secure, send Secure Flash MB Cmd */ | ||
2876 | if (region.attribute && buf_size_without_sfub) { | ||
2877 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, | ||
2878 | "Sending Secure Flash MB Cmd\n"); | ||
2879 | rval = qla28xx_secure_flash_update(vha, 0, region.code, | ||
2880 | buf_size_without_sfub, sfub_dma, | ||
2881 | sizeof(struct secure_flash_update_block)); | ||
2882 | if (rval != QLA_SUCCESS) { | ||
2883 | ql_log(ql_log_warn, vha, 0xffff, | ||
2884 | "Secure Flash MB Cmd failed %x.", rval); | ||
2885 | goto write_protect; | ||
2886 | } | ||
2887 | } | ||
2888 | |||
2889 | } | ||
2890 | |||
2891 | /* re-init flash offset */ | ||
2892 | faddr = offset >> 2; | ||
2893 | |||
2894 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { | ||
2895 | fdata = (faddr & sec_mask) << 2; | ||
2896 | |||
2897 | /* If smaller than a burst remaining */ | ||
2898 | if (dwords - liter < dburst) | ||
2899 | dburst = dwords - liter; | ||
2900 | |||
2901 | /* Copy to dma buffer */ | ||
2902 | memcpy(optrom, dwptr, dburst << 2); | ||
2903 | |||
2904 | /* Burst write */ | ||
2905 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0x7095, | ||
2906 | "Write burst (%#lx dwords)...\n", dburst); | ||
2907 | rval = qla2x00_load_ram(vha, optrom_dma, | ||
2908 | flash_data_addr(ha, faddr), dburst); | ||
2909 | if (rval != QLA_SUCCESS) { | ||
2910 | ql_log(ql_log_warn, vha, 0x7097, | ||
2911 | "Failed burst write at %x (%p/%#llx)...\n", | ||
2912 | flash_data_addr(ha, faddr), optrom, | ||
2913 | (u64)optrom_dma); | ||
2914 | break; | ||
2915 | } | ||
2916 | |||
2917 | liter += dburst - 1; | ||
2918 | faddr += dburst - 1; | ||
2919 | dwptr += dburst - 1; | ||
2920 | continue; | ||
2921 | } | ||
2922 | |||
2923 | write_protect: | ||
2924 | ql_log(ql_log_warn + ql_dbg_verbose, vha, 0x7095, | ||
2925 | "Protect flash...\n"); | ||
2926 | rval = qla24xx_protect_flash(vha); | ||
2927 | if (rval) { | ||
2928 | qla81xx_fac_semaphore_access(vha, FAC_SEMAPHORE_UNLOCK); | ||
2929 | ql_log(ql_log_warn, vha, 0x7099, | ||
2930 | "Failed protect flash\n"); | ||
2931 | } | ||
2932 | |||
2933 | if (reset_to_rom == true) { | ||
2934 | /* Schedule DPC to restart the RISC */ | ||
2935 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | ||
2936 | qla2xxx_wake_dpc(vha); | ||
2937 | |||
2938 | rval = qla2x00_wait_for_hba_online(vha); | ||
2939 | if (rval != QLA_SUCCESS) | ||
2940 | ql_log(ql_log_warn, vha, 0xffff, | ||
2941 | "Adapter did not come out of reset\n"); | ||
2942 | } | ||
2943 | |||
2944 | done: | ||
2945 | if (optrom) | ||
2946 | dma_free_coherent(&ha->pdev->dev, | ||
2947 | OPTROM_BURST_SIZE, optrom, optrom_dma); | ||
2948 | |||
2949 | return rval; | ||
2950 | } | ||
2951 | |||
2590 | int | 2952 | int |
2591 | qla24xx_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | 2953 | qla24xx_write_optrom_data(struct scsi_qla_host *vha, void *buf, |
2592 | uint32_t offset, uint32_t length) | 2954 | uint32_t offset, uint32_t length) |
2593 | { | 2955 | { |
2594 | int rval; | 2956 | int rval; |
@@ -2599,8 +2961,12 @@ qla24xx_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | |||
2599 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | 2961 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); |
2600 | 2962 | ||
2601 | /* Go with write. */ | 2963 | /* Go with write. */ |
2602 | rval = qla24xx_write_flash_data(vha, (uint32_t *)buf, offset >> 2, | 2964 | if (IS_QLA28XX(ha)) |
2603 | length >> 2); | 2965 | rval = qla28xx_write_flash_data(vha, (uint32_t *)buf, |
2966 | offset >> 2, length >> 2); | ||
2967 | else | ||
2968 | rval = qla24xx_write_flash_data(vha, (uint32_t *)buf, | ||
2969 | offset >> 2, length >> 2); | ||
2604 | 2970 | ||
2605 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | 2971 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); |
2606 | scsi_unblock_requests(vha->host); | 2972 | scsi_unblock_requests(vha->host); |
@@ -2608,8 +2974,8 @@ qla24xx_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | |||
2608 | return rval; | 2974 | return rval; |
2609 | } | 2975 | } |
2610 | 2976 | ||
2611 | uint8_t * | 2977 | void * |
2612 | qla25xx_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | 2978 | qla25xx_read_optrom_data(struct scsi_qla_host *vha, void *buf, |
2613 | uint32_t offset, uint32_t length) | 2979 | uint32_t offset, uint32_t length) |
2614 | { | 2980 | { |
2615 | int rval; | 2981 | int rval; |
@@ -2620,7 +2986,7 @@ qla25xx_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | |||
2620 | struct qla_hw_data *ha = vha->hw; | 2986 | struct qla_hw_data *ha = vha->hw; |
2621 | 2987 | ||
2622 | if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || | 2988 | if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || |
2623 | IS_QLA27XX(ha)) | 2989 | IS_QLA27XX(ha) || IS_QLA28XX(ha)) |
2624 | goto try_fast; | 2990 | goto try_fast; |
2625 | if (offset & 0xfff) | 2991 | if (offset & 0xfff) |
2626 | goto slow_read; | 2992 | goto slow_read; |
@@ -2628,6 +2994,8 @@ qla25xx_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | |||
2628 | goto slow_read; | 2994 | goto slow_read; |
2629 | 2995 | ||
2630 | try_fast: | 2996 | try_fast: |
2997 | if (offset & 0xff) | ||
2998 | goto slow_read; | ||
2631 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | 2999 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, |
2632 | &optrom_dma, GFP_KERNEL); | 3000 | &optrom_dma, GFP_KERNEL); |
2633 | if (!optrom) { | 3001 | if (!optrom) { |
@@ -2874,7 +3242,7 @@ qla2x00_get_flash_version(scsi_qla_host_t *vha, void *mbuf) | |||
2874 | "Dumping fw " | 3242 | "Dumping fw " |
2875 | "ver from flash:.\n"); | 3243 | "ver from flash:.\n"); |
2876 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x010b, | 3244 | ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x010b, |
2877 | (uint8_t *)dbyte, 8); | 3245 | dbyte, 32); |
2878 | 3246 | ||
2879 | if ((dcode[0] == 0xffff && dcode[1] == 0xffff && | 3247 | if ((dcode[0] == 0xffff && dcode[1] == 0xffff && |
2880 | dcode[2] == 0xffff && dcode[3] == 0xffff) || | 3248 | dcode[2] == 0xffff && dcode[3] == 0xffff) || |
@@ -2905,8 +3273,8 @@ qla82xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) | |||
2905 | { | 3273 | { |
2906 | int ret = QLA_SUCCESS; | 3274 | int ret = QLA_SUCCESS; |
2907 | uint32_t pcihdr, pcids; | 3275 | uint32_t pcihdr, pcids; |
2908 | uint32_t *dcode; | 3276 | uint32_t *dcode = mbuf; |
2909 | uint8_t *bcode; | 3277 | uint8_t *bcode = mbuf; |
2910 | uint8_t code_type, last_image; | 3278 | uint8_t code_type, last_image; |
2911 | struct qla_hw_data *ha = vha->hw; | 3279 | struct qla_hw_data *ha = vha->hw; |
2912 | 3280 | ||
@@ -2918,17 +3286,14 @@ qla82xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) | |||
2918 | memset(ha->fcode_revision, 0, sizeof(ha->fcode_revision)); | 3286 | memset(ha->fcode_revision, 0, sizeof(ha->fcode_revision)); |
2919 | memset(ha->fw_revision, 0, sizeof(ha->fw_revision)); | 3287 | memset(ha->fw_revision, 0, sizeof(ha->fw_revision)); |
2920 | 3288 | ||
2921 | dcode = mbuf; | ||
2922 | |||
2923 | /* Begin with first PCI expansion ROM header. */ | 3289 | /* Begin with first PCI expansion ROM header. */ |
2924 | pcihdr = ha->flt_region_boot << 2; | 3290 | pcihdr = ha->flt_region_boot << 2; |
2925 | last_image = 1; | 3291 | last_image = 1; |
2926 | do { | 3292 | do { |
2927 | /* Verify PCI expansion ROM header. */ | 3293 | /* Verify PCI expansion ROM header. */ |
2928 | ha->isp_ops->read_optrom(vha, (uint8_t *)dcode, pcihdr, | 3294 | ha->isp_ops->read_optrom(vha, dcode, pcihdr, 0x20 * 4); |
2929 | 0x20 * 4); | ||
2930 | bcode = mbuf + (pcihdr % 4); | 3295 | bcode = mbuf + (pcihdr % 4); |
2931 | if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa) { | 3296 | if (memcmp(bcode, "\x55\xaa", 2)) { |
2932 | /* No signature */ | 3297 | /* No signature */ |
2933 | ql_log(ql_log_fatal, vha, 0x0154, | 3298 | ql_log(ql_log_fatal, vha, 0x0154, |
2934 | "No matching ROM signature.\n"); | 3299 | "No matching ROM signature.\n"); |
@@ -2939,13 +3304,11 @@ qla82xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) | |||
2939 | /* Locate PCI data structure. */ | 3304 | /* Locate PCI data structure. */ |
2940 | pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]); | 3305 | pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]); |
2941 | 3306 | ||
2942 | ha->isp_ops->read_optrom(vha, (uint8_t *)dcode, pcids, | 3307 | ha->isp_ops->read_optrom(vha, dcode, pcids, 0x20 * 4); |
2943 | 0x20 * 4); | ||
2944 | bcode = mbuf + (pcihdr % 4); | 3308 | bcode = mbuf + (pcihdr % 4); |
2945 | 3309 | ||
2946 | /* Validate signature of PCI data structure. */ | 3310 | /* Validate signature of PCI data structure. */ |
2947 | if (bcode[0x0] != 'P' || bcode[0x1] != 'C' || | 3311 | if (memcmp(bcode, "PCIR", 4)) { |
2948 | bcode[0x2] != 'I' || bcode[0x3] != 'R') { | ||
2949 | /* Incorrect header. */ | 3312 | /* Incorrect header. */ |
2950 | ql_log(ql_log_fatal, vha, 0x0155, | 3313 | ql_log(ql_log_fatal, vha, 0x0155, |
2951 | "PCI data struct not found pcir_adr=%x.\n", pcids); | 3314 | "PCI data struct not found pcir_adr=%x.\n", pcids); |
@@ -2996,8 +3359,7 @@ qla82xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) | |||
2996 | /* Read firmware image information. */ | 3359 | /* Read firmware image information. */ |
2997 | memset(ha->fw_revision, 0, sizeof(ha->fw_revision)); | 3360 | memset(ha->fw_revision, 0, sizeof(ha->fw_revision)); |
2998 | dcode = mbuf; | 3361 | dcode = mbuf; |
2999 | ha->isp_ops->read_optrom(vha, (uint8_t *)dcode, ha->flt_region_fw << 2, | 3362 | ha->isp_ops->read_optrom(vha, dcode, ha->flt_region_fw << 2, 0x20); |
3000 | 0x20); | ||
3001 | bcode = mbuf + (pcihdr % 4); | 3363 | bcode = mbuf + (pcihdr % 4); |
3002 | 3364 | ||
3003 | /* Validate signature of PCI data structure. */ | 3365 | /* Validate signature of PCI data structure. */ |
@@ -3019,15 +3381,14 @@ int | |||
3019 | qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) | 3381 | qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) |
3020 | { | 3382 | { |
3021 | int ret = QLA_SUCCESS; | 3383 | int ret = QLA_SUCCESS; |
3022 | uint32_t pcihdr, pcids; | 3384 | uint32_t pcihdr = 0, pcids = 0; |
3023 | uint32_t *dcode; | 3385 | uint32_t *dcode = mbuf; |
3024 | uint8_t *bcode; | 3386 | uint8_t *bcode = mbuf; |
3025 | uint8_t code_type, last_image; | 3387 | uint8_t code_type, last_image; |
3026 | int i; | 3388 | int i; |
3027 | struct qla_hw_data *ha = vha->hw; | 3389 | struct qla_hw_data *ha = vha->hw; |
3028 | uint32_t faddr = 0; | 3390 | uint32_t faddr = 0; |
3029 | 3391 | struct active_regions active_regions = { }; | |
3030 | pcihdr = pcids = 0; | ||
3031 | 3392 | ||
3032 | if (IS_P3P_TYPE(ha)) | 3393 | if (IS_P3P_TYPE(ha)) |
3033 | return ret; | 3394 | return ret; |
@@ -3040,18 +3401,19 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) | |||
3040 | memset(ha->fcode_revision, 0, sizeof(ha->fcode_revision)); | 3401 | memset(ha->fcode_revision, 0, sizeof(ha->fcode_revision)); |
3041 | memset(ha->fw_revision, 0, sizeof(ha->fw_revision)); | 3402 | memset(ha->fw_revision, 0, sizeof(ha->fw_revision)); |
3042 | 3403 | ||
3043 | dcode = mbuf; | ||
3044 | pcihdr = ha->flt_region_boot << 2; | 3404 | pcihdr = ha->flt_region_boot << 2; |
3045 | if (IS_QLA27XX(ha) && | 3405 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
3046 | qla27xx_find_valid_image(vha) == QLA27XX_SECONDARY_IMAGE) | 3406 | qla27xx_get_active_image(vha, &active_regions); |
3047 | pcihdr = ha->flt_region_boot_sec << 2; | 3407 | if (active_regions.global == QLA27XX_SECONDARY_IMAGE) { |
3408 | pcihdr = ha->flt_region_boot_sec << 2; | ||
3409 | } | ||
3410 | } | ||
3048 | 3411 | ||
3049 | last_image = 1; | ||
3050 | do { | 3412 | do { |
3051 | /* Verify PCI expansion ROM header. */ | 3413 | /* Verify PCI expansion ROM header. */ |
3052 | qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20); | 3414 | qla24xx_read_flash_data(vha, dcode, pcihdr >> 2, 0x20); |
3053 | bcode = mbuf + (pcihdr % 4); | 3415 | bcode = mbuf + (pcihdr % 4); |
3054 | if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa) { | 3416 | if (memcmp(bcode, "\x55\xaa", 2)) { |
3055 | /* No signature */ | 3417 | /* No signature */ |
3056 | ql_log(ql_log_fatal, vha, 0x0059, | 3418 | ql_log(ql_log_fatal, vha, 0x0059, |
3057 | "No matching ROM signature.\n"); | 3419 | "No matching ROM signature.\n"); |
@@ -3066,11 +3428,11 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) | |||
3066 | bcode = mbuf + (pcihdr % 4); | 3428 | bcode = mbuf + (pcihdr % 4); |
3067 | 3429 | ||
3068 | /* Validate signature of PCI data structure. */ | 3430 | /* Validate signature of PCI data structure. */ |
3069 | if (bcode[0x0] != 'P' || bcode[0x1] != 'C' || | 3431 | if (memcmp(bcode, "PCIR", 4)) { |
3070 | bcode[0x2] != 'I' || bcode[0x3] != 'R') { | ||
3071 | /* Incorrect header. */ | 3432 | /* Incorrect header. */ |
3072 | ql_log(ql_log_fatal, vha, 0x005a, | 3433 | ql_log(ql_log_fatal, vha, 0x005a, |
3073 | "PCI data struct not found pcir_adr=%x.\n", pcids); | 3434 | "PCI data struct not found pcir_adr=%x.\n", pcids); |
3435 | ql_dump_buffer(ql_dbg_init, vha, 0x0059, dcode, 32); | ||
3074 | ret = QLA_FUNCTION_FAILED; | 3436 | ret = QLA_FUNCTION_FAILED; |
3075 | break; | 3437 | break; |
3076 | } | 3438 | } |
@@ -3117,30 +3479,24 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) | |||
3117 | 3479 | ||
3118 | /* Read firmware image information. */ | 3480 | /* Read firmware image information. */ |
3119 | memset(ha->fw_revision, 0, sizeof(ha->fw_revision)); | 3481 | memset(ha->fw_revision, 0, sizeof(ha->fw_revision)); |
3120 | dcode = mbuf; | ||
3121 | faddr = ha->flt_region_fw; | 3482 | faddr = ha->flt_region_fw; |
3122 | if (IS_QLA27XX(ha) && | 3483 | if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
3123 | qla27xx_find_valid_image(vha) == QLA27XX_SECONDARY_IMAGE) | 3484 | qla27xx_get_active_image(vha, &active_regions); |
3124 | faddr = ha->flt_region_fw_sec; | 3485 | if (active_regions.global == QLA27XX_SECONDARY_IMAGE) |
3125 | 3486 | faddr = ha->flt_region_fw_sec; | |
3126 | qla24xx_read_flash_data(vha, dcode, faddr + 4, 4); | 3487 | } |
3127 | for (i = 0; i < 4; i++) | ||
3128 | dcode[i] = be32_to_cpu(dcode[i]); | ||
3129 | 3488 | ||
3130 | if ((dcode[0] == 0xffffffff && dcode[1] == 0xffffffff && | 3489 | qla24xx_read_flash_data(vha, dcode, faddr, 8); |
3131 | dcode[2] == 0xffffffff && dcode[3] == 0xffffffff) || | 3490 | if (qla24xx_risc_firmware_invalid(dcode)) { |
3132 | (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 && | ||
3133 | dcode[3] == 0)) { | ||
3134 | ql_log(ql_log_warn, vha, 0x005f, | 3491 | ql_log(ql_log_warn, vha, 0x005f, |
3135 | "Unrecognized fw revision at %x.\n", | 3492 | "Unrecognized fw revision at %x.\n", |
3136 | ha->flt_region_fw * 4); | 3493 | ha->flt_region_fw * 4); |
3494 | ql_dump_buffer(ql_dbg_init, vha, 0x005f, dcode, 32); | ||
3137 | } else { | 3495 | } else { |
3138 | ha->fw_revision[0] = dcode[0]; | 3496 | for (i = 0; i < 4; i++) |
3139 | ha->fw_revision[1] = dcode[1]; | 3497 | ha->fw_revision[i] = be32_to_cpu(dcode[4+i]); |
3140 | ha->fw_revision[2] = dcode[2]; | ||
3141 | ha->fw_revision[3] = dcode[3]; | ||
3142 | ql_dbg(ql_dbg_init, vha, 0x0060, | 3498 | ql_dbg(ql_dbg_init, vha, 0x0060, |
3143 | "Firmware revision %d.%d.%d (%x).\n", | 3499 | "Firmware revision (flash) %u.%u.%u (%x).\n", |
3144 | ha->fw_revision[0], ha->fw_revision[1], | 3500 | ha->fw_revision[0], ha->fw_revision[1], |
3145 | ha->fw_revision[2], ha->fw_revision[3]); | 3501 | ha->fw_revision[2], ha->fw_revision[3]); |
3146 | } | 3502 | } |
@@ -3152,20 +3508,17 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) | |||
3152 | } | 3508 | } |
3153 | 3509 | ||
3154 | memset(ha->gold_fw_version, 0, sizeof(ha->gold_fw_version)); | 3510 | memset(ha->gold_fw_version, 0, sizeof(ha->gold_fw_version)); |
3155 | dcode = mbuf; | 3511 | faddr = ha->flt_region_gold_fw; |
3156 | ha->isp_ops->read_optrom(vha, (uint8_t *)dcode, | 3512 | qla24xx_read_flash_data(vha, (void *)dcode, ha->flt_region_gold_fw, 8); |
3157 | ha->flt_region_gold_fw << 2, 32); | 3513 | if (qla24xx_risc_firmware_invalid(dcode)) { |
3158 | |||
3159 | if (dcode[4] == 0xFFFFFFFF && dcode[5] == 0xFFFFFFFF && | ||
3160 | dcode[6] == 0xFFFFFFFF && dcode[7] == 0xFFFFFFFF) { | ||
3161 | ql_log(ql_log_warn, vha, 0x0056, | 3514 | ql_log(ql_log_warn, vha, 0x0056, |
3162 | "Unrecognized golden fw at 0x%x.\n", | 3515 | "Unrecognized golden fw at %#x.\n", faddr); |
3163 | ha->flt_region_gold_fw * 4); | 3516 | ql_dump_buffer(ql_dbg_init, vha, 0x0056, dcode, 32); |
3164 | return ret; | 3517 | return ret; |
3165 | } | 3518 | } |
3166 | 3519 | ||
3167 | for (i = 4; i < 8; i++) | 3520 | for (i = 0; i < 4; i++) |
3168 | ha->gold_fw_version[i-4] = be32_to_cpu(dcode[i]); | 3521 | ha->gold_fw_version[i] = be32_to_cpu(dcode[4+i]); |
3169 | 3522 | ||
3170 | return ret; | 3523 | return ret; |
3171 | } | 3524 | } |
@@ -3237,7 +3590,7 @@ qla24xx_read_fcp_prio_cfg(scsi_qla_host_t *vha) | |||
3237 | fcp_prio_addr = ha->flt_region_fcp_prio; | 3590 | fcp_prio_addr = ha->flt_region_fcp_prio; |
3238 | 3591 | ||
3239 | /* first read the fcp priority data header from flash */ | 3592 | /* first read the fcp priority data header from flash */ |
3240 | ha->isp_ops->read_optrom(vha, (uint8_t *)ha->fcp_prio_cfg, | 3593 | ha->isp_ops->read_optrom(vha, ha->fcp_prio_cfg, |
3241 | fcp_prio_addr << 2, FCP_PRIO_CFG_HDR_SIZE); | 3594 | fcp_prio_addr << 2, FCP_PRIO_CFG_HDR_SIZE); |
3242 | 3595 | ||
3243 | if (!qla24xx_fcp_prio_cfg_valid(vha, ha->fcp_prio_cfg, 0)) | 3596 | if (!qla24xx_fcp_prio_cfg_valid(vha, ha->fcp_prio_cfg, 0)) |
@@ -3248,7 +3601,7 @@ qla24xx_read_fcp_prio_cfg(scsi_qla_host_t *vha) | |||
3248 | len = ha->fcp_prio_cfg->num_entries * FCP_PRIO_CFG_ENTRY_SIZE; | 3601 | len = ha->fcp_prio_cfg->num_entries * FCP_PRIO_CFG_ENTRY_SIZE; |
3249 | max_len = FCP_PRIO_CFG_SIZE - FCP_PRIO_CFG_HDR_SIZE; | 3602 | max_len = FCP_PRIO_CFG_SIZE - FCP_PRIO_CFG_HDR_SIZE; |
3250 | 3603 | ||
3251 | ha->isp_ops->read_optrom(vha, (uint8_t *)&ha->fcp_prio_cfg->entry[0], | 3604 | ha->isp_ops->read_optrom(vha, &ha->fcp_prio_cfg->entry[0], |
3252 | fcp_prio_addr << 2, (len < max_len ? len : max_len)); | 3605 | fcp_prio_addr << 2, (len < max_len ? len : max_len)); |
3253 | 3606 | ||
3254 | /* revalidate the entire FCP priority config data, including entries */ | 3607 | /* revalidate the entire FCP priority config data, including entries */ |
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 582d1663f971..3eeae72793bc 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -184,6 +184,7 @@ static inline int qlt_issue_marker(struct scsi_qla_host *vha, int vha_locked) | |||
184 | /* Send marker if required */ | 184 | /* Send marker if required */ |
185 | if (unlikely(vha->marker_needed != 0)) { | 185 | if (unlikely(vha->marker_needed != 0)) { |
186 | int rc = qla2x00_issue_marker(vha, vha_locked); | 186 | int rc = qla2x00_issue_marker(vha, vha_locked); |
187 | |||
187 | if (rc != QLA_SUCCESS) { | 188 | if (rc != QLA_SUCCESS) { |
188 | ql_dbg(ql_dbg_tgt, vha, 0xe03d, | 189 | ql_dbg(ql_dbg_tgt, vha, 0xe03d, |
189 | "qla_target(%d): issue_marker() failed\n", | 190 | "qla_target(%d): issue_marker() failed\n", |
@@ -557,6 +558,7 @@ static int qla24xx_post_nack_work(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
557 | struct imm_ntfy_from_isp *ntfy, int type) | 558 | struct imm_ntfy_from_isp *ntfy, int type) |
558 | { | 559 | { |
559 | struct qla_work_evt *e; | 560 | struct qla_work_evt *e; |
561 | |||
560 | e = qla2x00_alloc_work(vha, QLA_EVT_NACK); | 562 | e = qla2x00_alloc_work(vha, QLA_EVT_NACK); |
561 | if (!e) | 563 | if (!e) |
562 | return QLA_FUNCTION_FAILED; | 564 | return QLA_FUNCTION_FAILED; |
@@ -680,7 +682,6 @@ done: | |||
680 | void qla24xx_do_nack_work(struct scsi_qla_host *vha, struct qla_work_evt *e) | 682 | void qla24xx_do_nack_work(struct scsi_qla_host *vha, struct qla_work_evt *e) |
681 | { | 683 | { |
682 | fc_port_t *t; | 684 | fc_port_t *t; |
683 | unsigned long flags; | ||
684 | 685 | ||
685 | switch (e->u.nack.type) { | 686 | switch (e->u.nack.type) { |
686 | case SRB_NACK_PRLI: | 687 | case SRB_NACK_PRLI: |
@@ -693,24 +694,19 @@ void qla24xx_do_nack_work(struct scsi_qla_host *vha, struct qla_work_evt *e) | |||
693 | if (t) { | 694 | if (t) { |
694 | ql_log(ql_log_info, vha, 0xd034, | 695 | ql_log(ql_log_info, vha, 0xd034, |
695 | "%s create sess success %p", __func__, t); | 696 | "%s create sess success %p", __func__, t); |
696 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | ||
697 | /* create sess has an extra kref */ | 697 | /* create sess has an extra kref */ |
698 | vha->hw->tgt.tgt_ops->put_sess(e->u.nack.fcport); | 698 | vha->hw->tgt.tgt_ops->put_sess(e->u.nack.fcport); |
699 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | ||
700 | } | 699 | } |
701 | break; | 700 | break; |
702 | } | 701 | } |
703 | qla24xx_async_notify_ack(vha, e->u.nack.fcport, | 702 | qla24xx_async_notify_ack(vha, e->u.nack.fcport, |
704 | (struct imm_ntfy_from_isp*)e->u.nack.iocb, e->u.nack.type); | 703 | (struct imm_ntfy_from_isp *)e->u.nack.iocb, e->u.nack.type); |
705 | } | 704 | } |
706 | 705 | ||
707 | void qla24xx_delete_sess_fn(struct work_struct *work) | 706 | void qla24xx_delete_sess_fn(struct work_struct *work) |
708 | { | 707 | { |
709 | fc_port_t *fcport = container_of(work, struct fc_port, del_work); | 708 | fc_port_t *fcport = container_of(work, struct fc_port, del_work); |
710 | struct qla_hw_data *ha = fcport->vha->hw; | 709 | struct qla_hw_data *ha = fcport->vha->hw; |
711 | unsigned long flags; | ||
712 | |||
713 | spin_lock_irqsave(&ha->tgt.sess_lock, flags); | ||
714 | 710 | ||
715 | if (fcport->se_sess) { | 711 | if (fcport->se_sess) { |
716 | ha->tgt.tgt_ops->shutdown_sess(fcport); | 712 | ha->tgt.tgt_ops->shutdown_sess(fcport); |
@@ -718,7 +714,6 @@ void qla24xx_delete_sess_fn(struct work_struct *work) | |||
718 | } else { | 714 | } else { |
719 | qlt_unreg_sess(fcport); | 715 | qlt_unreg_sess(fcport); |
720 | } | 716 | } |
721 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); | ||
722 | } | 717 | } |
723 | 718 | ||
724 | /* | 719 | /* |
@@ -787,8 +782,9 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
787 | fcport->port_name, sess->loop_id); | 782 | fcport->port_name, sess->loop_id); |
788 | sess->local = 0; | 783 | sess->local = 0; |
789 | } | 784 | } |
790 | ha->tgt.tgt_ops->put_sess(sess); | ||
791 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); | 785 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); |
786 | |||
787 | ha->tgt.tgt_ops->put_sess(sess); | ||
792 | } | 788 | } |
793 | 789 | ||
794 | /* | 790 | /* |
@@ -980,6 +976,8 @@ void qlt_free_session_done(struct work_struct *work) | |||
980 | sess->send_els_logo); | 976 | sess->send_els_logo); |
981 | 977 | ||
982 | if (!IS_SW_RESV_ADDR(sess->d_id)) { | 978 | if (!IS_SW_RESV_ADDR(sess->d_id)) { |
979 | qla2x00_mark_device_lost(vha, sess, 0, 0); | ||
980 | |||
983 | if (sess->send_els_logo) { | 981 | if (sess->send_els_logo) { |
984 | qlt_port_logo_t logo; | 982 | qlt_port_logo_t logo; |
985 | 983 | ||
@@ -1076,6 +1074,7 @@ void qlt_free_session_done(struct work_struct *work) | |||
1076 | struct qlt_plogi_ack_t *con = | 1074 | struct qlt_plogi_ack_t *con = |
1077 | sess->plogi_link[QLT_PLOGI_LINK_CONFLICT]; | 1075 | sess->plogi_link[QLT_PLOGI_LINK_CONFLICT]; |
1078 | struct imm_ntfy_from_isp *iocb; | 1076 | struct imm_ntfy_from_isp *iocb; |
1077 | |||
1079 | own = sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN]; | 1078 | own = sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN]; |
1080 | 1079 | ||
1081 | if (con) { | 1080 | if (con) { |
@@ -1160,8 +1159,6 @@ void qlt_unreg_sess(struct fc_port *sess) | |||
1160 | if (sess->se_sess) | 1159 | if (sess->se_sess) |
1161 | vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess); | 1160 | vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess); |
1162 | 1161 | ||
1163 | qla2x00_mark_device_lost(vha, sess, 0, 0); | ||
1164 | |||
1165 | sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; | 1162 | sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; |
1166 | sess->disc_state = DSC_DELETE_PEND; | 1163 | sess->disc_state = DSC_DELETE_PEND; |
1167 | sess->last_rscn_gen = sess->rscn_gen; | 1164 | sess->last_rscn_gen = sess->rscn_gen; |
@@ -1329,6 +1326,7 @@ static int qla24xx_get_loop_id(struct scsi_qla_host *vha, const uint8_t *s_id, | |||
1329 | res = -ENOENT; | 1326 | res = -ENOENT; |
1330 | for (i = 0; i < entries; i++) { | 1327 | for (i = 0; i < entries; i++) { |
1331 | struct gid_list_info *gid = (struct gid_list_info *)id_iter; | 1328 | struct gid_list_info *gid = (struct gid_list_info *)id_iter; |
1329 | |||
1332 | if ((gid->al_pa == s_id[2]) && | 1330 | if ((gid->al_pa == s_id[2]) && |
1333 | (gid->area == s_id[1]) && | 1331 | (gid->area == s_id[1]) && |
1334 | (gid->domain == s_id[0])) { | 1332 | (gid->domain == s_id[0])) { |
@@ -2331,14 +2329,14 @@ void qlt_send_resp_ctio(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd, | |||
2331 | ctio->u.status1.scsi_status |= | 2329 | ctio->u.status1.scsi_status |= |
2332 | cpu_to_le16(SS_RESIDUAL_UNDER); | 2330 | cpu_to_le16(SS_RESIDUAL_UNDER); |
2333 | 2331 | ||
2334 | /* Response code and sense key */ | 2332 | /* Fixed format sense data. */ |
2335 | put_unaligned_le32(((0x70 << 24) | (sense_key << 8)), | 2333 | ctio->u.status1.sense_data[0] = 0x70; |
2336 | (&ctio->u.status1.sense_data)[0]); | 2334 | ctio->u.status1.sense_data[2] = sense_key; |
2337 | /* Additional sense length */ | 2335 | /* Additional sense length */ |
2338 | put_unaligned_le32(0x0a, (&ctio->u.status1.sense_data)[1]); | 2336 | ctio->u.status1.sense_data[7] = 0xa; |
2339 | /* ASC and ASCQ */ | 2337 | /* ASC and ASCQ */ |
2340 | put_unaligned_le32(((asc << 24) | (ascq << 16)), | 2338 | ctio->u.status1.sense_data[12] = asc; |
2341 | (&ctio->u.status1.sense_data)[3]); | 2339 | ctio->u.status1.sense_data[13] = ascq; |
2342 | 2340 | ||
2343 | /* Memory Barrier */ | 2341 | /* Memory Barrier */ |
2344 | wmb(); | 2342 | wmb(); |
@@ -2387,7 +2385,7 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd) | |||
2387 | case ELS_PRLO: | 2385 | case ELS_PRLO: |
2388 | case ELS_TPRLO: | 2386 | case ELS_TPRLO: |
2389 | ql_dbg(ql_dbg_disc, vha, 0x2106, | 2387 | ql_dbg(ql_dbg_disc, vha, 0x2106, |
2390 | "TM response logo %phC status %#x state %#x", | 2388 | "TM response logo %8phC status %#x state %#x", |
2391 | mcmd->sess->port_name, mcmd->fc_tm_rsp, | 2389 | mcmd->sess->port_name, mcmd->fc_tm_rsp, |
2392 | mcmd->flags); | 2390 | mcmd->flags); |
2393 | qlt_schedule_sess_for_deletion(mcmd->sess); | 2391 | qlt_schedule_sess_for_deletion(mcmd->sess); |
@@ -2485,6 +2483,7 @@ static void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd) | |||
2485 | { | 2483 | { |
2486 | struct qla_hw_data *ha; | 2484 | struct qla_hw_data *ha; |
2487 | struct qla_qpair *qpair; | 2485 | struct qla_qpair *qpair; |
2486 | |||
2488 | if (!cmd->sg_mapped) | 2487 | if (!cmd->sg_mapped) |
2489 | return; | 2488 | return; |
2490 | 2489 | ||
@@ -2635,7 +2634,7 @@ static int qlt_24xx_build_ctio_pkt(struct qla_qpair *qpair, | |||
2635 | static void qlt_load_cont_data_segments(struct qla_tgt_prm *prm) | 2634 | static void qlt_load_cont_data_segments(struct qla_tgt_prm *prm) |
2636 | { | 2635 | { |
2637 | int cnt; | 2636 | int cnt; |
2638 | uint32_t *dword_ptr; | 2637 | struct dsd64 *cur_dsd; |
2639 | 2638 | ||
2640 | /* Build continuation packets */ | 2639 | /* Build continuation packets */ |
2641 | while (prm->seg_cnt > 0) { | 2640 | while (prm->seg_cnt > 0) { |
@@ -2656,19 +2655,13 @@ static void qlt_load_cont_data_segments(struct qla_tgt_prm *prm) | |||
2656 | cont_pkt64->sys_define = 0; | 2655 | cont_pkt64->sys_define = 0; |
2657 | 2656 | ||
2658 | cont_pkt64->entry_type = CONTINUE_A64_TYPE; | 2657 | cont_pkt64->entry_type = CONTINUE_A64_TYPE; |
2659 | dword_ptr = (uint32_t *)&cont_pkt64->dseg_0_address; | 2658 | cur_dsd = cont_pkt64->dsd; |
2660 | 2659 | ||
2661 | /* Load continuation entry data segments */ | 2660 | /* Load continuation entry data segments */ |
2662 | for (cnt = 0; | 2661 | for (cnt = 0; |
2663 | cnt < QLA_TGT_DATASEGS_PER_CONT_24XX && prm->seg_cnt; | 2662 | cnt < QLA_TGT_DATASEGS_PER_CONT_24XX && prm->seg_cnt; |
2664 | cnt++, prm->seg_cnt--) { | 2663 | cnt++, prm->seg_cnt--) { |
2665 | *dword_ptr++ = | 2664 | append_dsd64(&cur_dsd, prm->sg); |
2666 | cpu_to_le32(lower_32_bits | ||
2667 | (sg_dma_address(prm->sg))); | ||
2668 | *dword_ptr++ = cpu_to_le32(upper_32_bits | ||
2669 | (sg_dma_address(prm->sg))); | ||
2670 | *dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg)); | ||
2671 | |||
2672 | prm->sg = sg_next(prm->sg); | 2665 | prm->sg = sg_next(prm->sg); |
2673 | } | 2666 | } |
2674 | } | 2667 | } |
@@ -2681,13 +2674,13 @@ static void qlt_load_cont_data_segments(struct qla_tgt_prm *prm) | |||
2681 | static void qlt_load_data_segments(struct qla_tgt_prm *prm) | 2674 | static void qlt_load_data_segments(struct qla_tgt_prm *prm) |
2682 | { | 2675 | { |
2683 | int cnt; | 2676 | int cnt; |
2684 | uint32_t *dword_ptr; | 2677 | struct dsd64 *cur_dsd; |
2685 | struct ctio7_to_24xx *pkt24 = (struct ctio7_to_24xx *)prm->pkt; | 2678 | struct ctio7_to_24xx *pkt24 = (struct ctio7_to_24xx *)prm->pkt; |
2686 | 2679 | ||
2687 | pkt24->u.status0.transfer_length = cpu_to_le32(prm->cmd->bufflen); | 2680 | pkt24->u.status0.transfer_length = cpu_to_le32(prm->cmd->bufflen); |
2688 | 2681 | ||
2689 | /* Setup packet address segment pointer */ | 2682 | /* Setup packet address segment pointer */ |
2690 | dword_ptr = pkt24->u.status0.dseg_0_address; | 2683 | cur_dsd = &pkt24->u.status0.dsd; |
2691 | 2684 | ||
2692 | /* Set total data segment count */ | 2685 | /* Set total data segment count */ |
2693 | if (prm->seg_cnt) | 2686 | if (prm->seg_cnt) |
@@ -2695,8 +2688,8 @@ static void qlt_load_data_segments(struct qla_tgt_prm *prm) | |||
2695 | 2688 | ||
2696 | if (prm->seg_cnt == 0) { | 2689 | if (prm->seg_cnt == 0) { |
2697 | /* No data transfer */ | 2690 | /* No data transfer */ |
2698 | *dword_ptr++ = 0; | 2691 | cur_dsd->address = 0; |
2699 | *dword_ptr = 0; | 2692 | cur_dsd->length = 0; |
2700 | return; | 2693 | return; |
2701 | } | 2694 | } |
2702 | 2695 | ||
@@ -2706,14 +2699,7 @@ static void qlt_load_data_segments(struct qla_tgt_prm *prm) | |||
2706 | for (cnt = 0; | 2699 | for (cnt = 0; |
2707 | (cnt < QLA_TGT_DATASEGS_PER_CMD_24XX) && prm->seg_cnt; | 2700 | (cnt < QLA_TGT_DATASEGS_PER_CMD_24XX) && prm->seg_cnt; |
2708 | cnt++, prm->seg_cnt--) { | 2701 | cnt++, prm->seg_cnt--) { |
2709 | *dword_ptr++ = | 2702 | append_dsd64(&cur_dsd, prm->sg); |
2710 | cpu_to_le32(lower_32_bits(sg_dma_address(prm->sg))); | ||
2711 | |||
2712 | *dword_ptr++ = cpu_to_le32(upper_32_bits( | ||
2713 | sg_dma_address(prm->sg))); | ||
2714 | |||
2715 | *dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg)); | ||
2716 | |||
2717 | prm->sg = sg_next(prm->sg); | 2703 | prm->sg = sg_next(prm->sg); |
2718 | } | 2704 | } |
2719 | 2705 | ||
@@ -3037,7 +3023,7 @@ qla_tgt_set_dif_tags(struct qla_tgt_cmd *cmd, struct crc_context *ctx, | |||
3037 | static inline int | 3023 | static inline int |
3038 | qlt_build_ctio_crc2_pkt(struct qla_qpair *qpair, struct qla_tgt_prm *prm) | 3024 | qlt_build_ctio_crc2_pkt(struct qla_qpair *qpair, struct qla_tgt_prm *prm) |
3039 | { | 3025 | { |
3040 | uint32_t *cur_dsd; | 3026 | struct dsd64 *cur_dsd; |
3041 | uint32_t transfer_length = 0; | 3027 | uint32_t transfer_length = 0; |
3042 | uint32_t data_bytes; | 3028 | uint32_t data_bytes; |
3043 | uint32_t dif_bytes; | 3029 | uint32_t dif_bytes; |
@@ -3183,12 +3169,11 @@ qlt_build_ctio_crc2_pkt(struct qla_qpair *qpair, struct qla_tgt_prm *prm) | |||
3183 | 3169 | ||
3184 | qla_tgt_set_dif_tags(cmd, crc_ctx_pkt, &fw_prot_opts); | 3170 | qla_tgt_set_dif_tags(cmd, crc_ctx_pkt, &fw_prot_opts); |
3185 | 3171 | ||
3186 | pkt->crc_context_address[0] = cpu_to_le32(LSD(crc_ctx_dma)); | 3172 | put_unaligned_le64(crc_ctx_dma, &pkt->crc_context_address); |
3187 | pkt->crc_context_address[1] = cpu_to_le32(MSD(crc_ctx_dma)); | ||
3188 | pkt->crc_context_len = CRC_CONTEXT_LEN_FW; | 3173 | pkt->crc_context_len = CRC_CONTEXT_LEN_FW; |
3189 | 3174 | ||
3190 | if (!bundling) { | 3175 | if (!bundling) { |
3191 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.nobundling.data_address; | 3176 | cur_dsd = &crc_ctx_pkt->u.nobundling.data_dsd; |
3192 | } else { | 3177 | } else { |
3193 | /* | 3178 | /* |
3194 | * Configure Bundling if we need to fetch interlaving | 3179 | * Configure Bundling if we need to fetch interlaving |
@@ -3198,7 +3183,7 @@ qlt_build_ctio_crc2_pkt(struct qla_qpair *qpair, struct qla_tgt_prm *prm) | |||
3198 | crc_ctx_pkt->u.bundling.dif_byte_count = cpu_to_le32(dif_bytes); | 3183 | crc_ctx_pkt->u.bundling.dif_byte_count = cpu_to_le32(dif_bytes); |
3199 | crc_ctx_pkt->u.bundling.dseg_count = | 3184 | crc_ctx_pkt->u.bundling.dseg_count = |
3200 | cpu_to_le16(prm->tot_dsds - prm->prot_seg_cnt); | 3185 | cpu_to_le16(prm->tot_dsds - prm->prot_seg_cnt); |
3201 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.data_address; | 3186 | cur_dsd = &crc_ctx_pkt->u.bundling.data_dsd; |
3202 | } | 3187 | } |
3203 | 3188 | ||
3204 | /* Finish the common fields of CRC pkt */ | 3189 | /* Finish the common fields of CRC pkt */ |
@@ -3231,7 +3216,7 @@ qlt_build_ctio_crc2_pkt(struct qla_qpair *qpair, struct qla_tgt_prm *prm) | |||
3231 | /* Walks dif segments */ | 3216 | /* Walks dif segments */ |
3232 | pkt->add_flags |= CTIO_CRC2_AF_DIF_DSD_ENA; | 3217 | pkt->add_flags |= CTIO_CRC2_AF_DIF_DSD_ENA; |
3233 | 3218 | ||
3234 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address; | 3219 | cur_dsd = &crc_ctx_pkt->u.bundling.dif_dsd; |
3235 | if (qla24xx_walk_and_build_prot_sglist(ha, NULL, cur_dsd, | 3220 | if (qla24xx_walk_and_build_prot_sglist(ha, NULL, cur_dsd, |
3236 | prm->prot_seg_cnt, cmd)) | 3221 | prm->prot_seg_cnt, cmd)) |
3237 | goto crc_queuing_error; | 3222 | goto crc_queuing_error; |
@@ -3263,7 +3248,6 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, | |||
3263 | if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) || | 3248 | if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) || |
3264 | (cmd->sess && cmd->sess->deleted)) { | 3249 | (cmd->sess && cmd->sess->deleted)) { |
3265 | cmd->state = QLA_TGT_STATE_PROCESSED; | 3250 | cmd->state = QLA_TGT_STATE_PROCESSED; |
3266 | qlt_abort_cmd_on_host_reset(cmd->vha, cmd); | ||
3267 | return 0; | 3251 | return 0; |
3268 | } | 3252 | } |
3269 | 3253 | ||
@@ -3292,7 +3276,6 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, | |||
3292 | * previous life, just abort the processing. | 3276 | * previous life, just abort the processing. |
3293 | */ | 3277 | */ |
3294 | cmd->state = QLA_TGT_STATE_PROCESSED; | 3278 | cmd->state = QLA_TGT_STATE_PROCESSED; |
3295 | qlt_abort_cmd_on_host_reset(cmd->vha, cmd); | ||
3296 | ql_dbg_qp(ql_dbg_async, qpair, 0xe101, | 3279 | ql_dbg_qp(ql_dbg_async, qpair, 0xe101, |
3297 | "RESET-RSP online/active/old-count/new-count = %d/%d/%d/%d.\n", | 3280 | "RESET-RSP online/active/old-count/new-count = %d/%d/%d/%d.\n", |
3298 | vha->flags.online, qla2x00_reset_active(vha), | 3281 | vha->flags.online, qla2x00_reset_active(vha), |
@@ -3384,9 +3367,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, | |||
3384 | 3367 | ||
3385 | 3368 | ||
3386 | cmd->state = QLA_TGT_STATE_PROCESSED; /* Mid-level is done processing */ | 3369 | cmd->state = QLA_TGT_STATE_PROCESSED; /* Mid-level is done processing */ |
3387 | spin_lock(&cmd->cmd_lock); | ||
3388 | cmd->cmd_sent_to_fw = 1; | 3370 | cmd->cmd_sent_to_fw = 1; |
3389 | spin_unlock(&cmd->cmd_lock); | ||
3390 | cmd->ctio_flags = le16_to_cpu(pkt->u.status0.flags); | 3371 | cmd->ctio_flags = le16_to_cpu(pkt->u.status0.flags); |
3391 | 3372 | ||
3392 | /* Memory Barrier */ | 3373 | /* Memory Barrier */ |
@@ -3433,8 +3414,10 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd) | |||
3433 | * Either the port is not online or this request was from | 3414 | * Either the port is not online or this request was from |
3434 | * previous life, just abort the processing. | 3415 | * previous life, just abort the processing. |
3435 | */ | 3416 | */ |
3436 | cmd->state = QLA_TGT_STATE_NEED_DATA; | 3417 | cmd->aborted = 1; |
3437 | qlt_abort_cmd_on_host_reset(cmd->vha, cmd); | 3418 | cmd->write_data_transferred = 0; |
3419 | cmd->state = QLA_TGT_STATE_DATA_IN; | ||
3420 | vha->hw->tgt.tgt_ops->handle_data(cmd); | ||
3438 | ql_dbg_qp(ql_dbg_async, qpair, 0xe102, | 3421 | ql_dbg_qp(ql_dbg_async, qpair, 0xe102, |
3439 | "RESET-XFR online/active/old-count/new-count = %d/%d/%d/%d.\n", | 3422 | "RESET-XFR online/active/old-count/new-count = %d/%d/%d/%d.\n", |
3440 | vha->flags.online, qla2x00_reset_active(vha), | 3423 | vha->flags.online, qla2x00_reset_active(vha), |
@@ -3465,9 +3448,7 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd) | |||
3465 | qlt_load_data_segments(&prm); | 3448 | qlt_load_data_segments(&prm); |
3466 | 3449 | ||
3467 | cmd->state = QLA_TGT_STATE_NEED_DATA; | 3450 | cmd->state = QLA_TGT_STATE_NEED_DATA; |
3468 | spin_lock(&cmd->cmd_lock); | ||
3469 | cmd->cmd_sent_to_fw = 1; | 3451 | cmd->cmd_sent_to_fw = 1; |
3470 | spin_unlock(&cmd->cmd_lock); | ||
3471 | cmd->ctio_flags = le16_to_cpu(pkt->u.status0.flags); | 3452 | cmd->ctio_flags = le16_to_cpu(pkt->u.status0.flags); |
3472 | 3453 | ||
3473 | /* Memory Barrier */ | 3454 | /* Memory Barrier */ |
@@ -3646,33 +3627,11 @@ static int __qlt_send_term_imm_notif(struct scsi_qla_host *vha, | |||
3646 | static void qlt_send_term_imm_notif(struct scsi_qla_host *vha, | 3627 | static void qlt_send_term_imm_notif(struct scsi_qla_host *vha, |
3647 | struct imm_ntfy_from_isp *imm, int ha_locked) | 3628 | struct imm_ntfy_from_isp *imm, int ha_locked) |
3648 | { | 3629 | { |
3649 | unsigned long flags = 0; | ||
3650 | int rc; | 3630 | int rc; |
3651 | 3631 | ||
3652 | if (ha_locked) { | 3632 | WARN_ON_ONCE(!ha_locked); |
3653 | rc = __qlt_send_term_imm_notif(vha, imm); | ||
3654 | |||
3655 | #if 0 /* Todo */ | ||
3656 | if (rc == -ENOMEM) | ||
3657 | qlt_alloc_qfull_cmd(vha, imm, 0, 0); | ||
3658 | #else | ||
3659 | if (rc) { | ||
3660 | } | ||
3661 | #endif | ||
3662 | goto done; | ||
3663 | } | ||
3664 | |||
3665 | spin_lock_irqsave(&vha->hw->hardware_lock, flags); | ||
3666 | rc = __qlt_send_term_imm_notif(vha, imm); | 3633 | rc = __qlt_send_term_imm_notif(vha, imm); |
3667 | 3634 | pr_debug("rc = %d\n", rc); | |
3668 | #if 0 /* Todo */ | ||
3669 | if (rc == -ENOMEM) | ||
3670 | qlt_alloc_qfull_cmd(vha, imm, 0, 0); | ||
3671 | #endif | ||
3672 | |||
3673 | done: | ||
3674 | if (!ha_locked) | ||
3675 | spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); | ||
3676 | } | 3635 | } |
3677 | 3636 | ||
3678 | /* | 3637 | /* |
@@ -3913,6 +3872,7 @@ static int qlt_term_ctio_exchange(struct qla_qpair *qpair, void *ctio, | |||
3913 | 3872 | ||
3914 | if (ctio != NULL) { | 3873 | if (ctio != NULL) { |
3915 | struct ctio7_from_24xx *c = (struct ctio7_from_24xx *)ctio; | 3874 | struct ctio7_from_24xx *c = (struct ctio7_from_24xx *)ctio; |
3875 | |||
3916 | term = !(c->flags & | 3876 | term = !(c->flags & |
3917 | cpu_to_le16(OF_TERM_EXCH)); | 3877 | cpu_to_le16(OF_TERM_EXCH)); |
3918 | } else | 3878 | } else |
@@ -3977,39 +3937,6 @@ static void *qlt_ctio_to_cmd(struct scsi_qla_host *vha, | |||
3977 | return cmd; | 3937 | return cmd; |
3978 | } | 3938 | } |
3979 | 3939 | ||
3980 | /* hardware_lock should be held by caller. */ | ||
3981 | void | ||
3982 | qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd) | ||
3983 | { | ||
3984 | struct qla_hw_data *ha = vha->hw; | ||
3985 | |||
3986 | if (cmd->sg_mapped) | ||
3987 | qlt_unmap_sg(vha, cmd); | ||
3988 | |||
3989 | /* TODO: fix debug message type and ids. */ | ||
3990 | if (cmd->state == QLA_TGT_STATE_PROCESSED) { | ||
3991 | ql_dbg(ql_dbg_io, vha, 0xff00, | ||
3992 | "HOST-ABORT: state=PROCESSED.\n"); | ||
3993 | } else if (cmd->state == QLA_TGT_STATE_NEED_DATA) { | ||
3994 | cmd->write_data_transferred = 0; | ||
3995 | cmd->state = QLA_TGT_STATE_DATA_IN; | ||
3996 | |||
3997 | ql_dbg(ql_dbg_io, vha, 0xff01, | ||
3998 | "HOST-ABORT: state=DATA_IN.\n"); | ||
3999 | |||
4000 | ha->tgt.tgt_ops->handle_data(cmd); | ||
4001 | return; | ||
4002 | } else { | ||
4003 | ql_dbg(ql_dbg_io, vha, 0xff03, | ||
4004 | "HOST-ABORT: state=BAD(%d).\n", | ||
4005 | cmd->state); | ||
4006 | dump_stack(); | ||
4007 | } | ||
4008 | |||
4009 | cmd->trc_flags |= TRC_FLUSH; | ||
4010 | ha->tgt.tgt_ops->free_cmd(cmd); | ||
4011 | } | ||
4012 | |||
4013 | /* | 3940 | /* |
4014 | * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire | 3941 | * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire |
4015 | */ | 3942 | */ |
@@ -4031,7 +3958,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, | |||
4031 | return; | 3958 | return; |
4032 | } | 3959 | } |
4033 | 3960 | ||
4034 | cmd = (struct qla_tgt_cmd *)qlt_ctio_to_cmd(vha, rsp, handle, ctio); | 3961 | cmd = qlt_ctio_to_cmd(vha, rsp, handle, ctio); |
4035 | if (cmd == NULL) | 3962 | if (cmd == NULL) |
4036 | return; | 3963 | return; |
4037 | 3964 | ||
@@ -4240,11 +4167,9 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd) | |||
4240 | if (ret != 0) | 4167 | if (ret != 0) |
4241 | goto out_term; | 4168 | goto out_term; |
4242 | /* | 4169 | /* |
4243 | * Drop extra session reference from qla_tgt_handle_cmd_for_atio*( | 4170 | * Drop extra session reference from qlt_handle_cmd_for_atio(). |
4244 | */ | 4171 | */ |
4245 | spin_lock_irqsave(&ha->tgt.sess_lock, flags); | ||
4246 | ha->tgt.tgt_ops->put_sess(sess); | 4172 | ha->tgt.tgt_ops->put_sess(sess); |
4247 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); | ||
4248 | return; | 4173 | return; |
4249 | 4174 | ||
4250 | out_term: | 4175 | out_term: |
@@ -4261,9 +4186,7 @@ out_term: | |||
4261 | target_free_tag(sess->se_sess, &cmd->se_cmd); | 4186 | target_free_tag(sess->se_sess, &cmd->se_cmd); |
4262 | spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); | 4187 | spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); |
4263 | 4188 | ||
4264 | spin_lock_irqsave(&ha->tgt.sess_lock, flags); | ||
4265 | ha->tgt.tgt_ops->put_sess(sess); | 4189 | ha->tgt.tgt_ops->put_sess(sess); |
4266 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); | ||
4267 | } | 4190 | } |
4268 | 4191 | ||
4269 | static void qlt_do_work(struct work_struct *work) | 4192 | static void qlt_do_work(struct work_struct *work) |
@@ -4472,9 +4395,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, | |||
4472 | if (!cmd) { | 4395 | if (!cmd) { |
4473 | ql_dbg(ql_dbg_io, vha, 0x3062, | 4396 | ql_dbg(ql_dbg_io, vha, 0x3062, |
4474 | "qla_target(%d): Allocation of cmd failed\n", vha->vp_idx); | 4397 | "qla_target(%d): Allocation of cmd failed\n", vha->vp_idx); |
4475 | spin_lock_irqsave(&ha->tgt.sess_lock, flags); | ||
4476 | ha->tgt.tgt_ops->put_sess(sess); | 4398 | ha->tgt.tgt_ops->put_sess(sess); |
4477 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); | ||
4478 | return -EBUSY; | 4399 | return -EBUSY; |
4479 | } | 4400 | } |
4480 | 4401 | ||
@@ -4773,6 +4694,7 @@ static int abort_cmds_for_s_id(struct scsi_qla_host *vha, port_id_t *s_id) | |||
4773 | 4694 | ||
4774 | list_for_each_entry(op, &vha->unknown_atio_list, cmd_list) { | 4695 | list_for_each_entry(op, &vha->unknown_atio_list, cmd_list) { |
4775 | uint32_t op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id); | 4696 | uint32_t op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id); |
4697 | |||
4776 | if (op_key == key) { | 4698 | if (op_key == key) { |
4777 | op->aborted = true; | 4699 | op->aborted = true; |
4778 | count++; | 4700 | count++; |
@@ -4781,6 +4703,7 @@ static int abort_cmds_for_s_id(struct scsi_qla_host *vha, port_id_t *s_id) | |||
4781 | 4703 | ||
4782 | list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) { | 4704 | list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) { |
4783 | uint32_t cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id); | 4705 | uint32_t cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id); |
4706 | |||
4784 | if (cmd_key == key) { | 4707 | if (cmd_key == key) { |
4785 | cmd->aborted = 1; | 4708 | cmd->aborted = 1; |
4786 | count++; | 4709 | count++; |
@@ -5051,6 +4974,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, | |||
5051 | if (sess != NULL) { | 4974 | if (sess != NULL) { |
5052 | bool delete = false; | 4975 | bool delete = false; |
5053 | int sec; | 4976 | int sec; |
4977 | |||
5054 | spin_lock_irqsave(&tgt->ha->tgt.sess_lock, flags); | 4978 | spin_lock_irqsave(&tgt->ha->tgt.sess_lock, flags); |
5055 | switch (sess->fw_login_state) { | 4979 | switch (sess->fw_login_state) { |
5056 | case DSC_LS_PLOGI_PEND: | 4980 | case DSC_LS_PLOGI_PEND: |
@@ -5203,6 +5127,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, | |||
5203 | case ELS_ADISC: | 5127 | case ELS_ADISC: |
5204 | { | 5128 | { |
5205 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; | 5129 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
5130 | |||
5206 | if (tgt->link_reinit_iocb_pending) { | 5131 | if (tgt->link_reinit_iocb_pending) { |
5207 | qlt_send_notify_ack(ha->base_qpair, | 5132 | qlt_send_notify_ack(ha->base_qpair, |
5208 | &tgt->link_reinit_iocb, 0, 0, 0, 0, 0, 0); | 5133 | &tgt->link_reinit_iocb, 0, 0, 0, 0, 0, 0); |
@@ -5266,6 +5191,7 @@ static void qlt_handle_imm_notify(struct scsi_qla_host *vha, | |||
5266 | case IMM_NTFY_LIP_LINK_REINIT: | 5191 | case IMM_NTFY_LIP_LINK_REINIT: |
5267 | { | 5192 | { |
5268 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; | 5193 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
5194 | |||
5269 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf033, | 5195 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf033, |
5270 | "qla_target(%d): LINK REINIT (loop %#x, " | 5196 | "qla_target(%d): LINK REINIT (loop %#x, " |
5271 | "subcode %x)\n", vha->vp_idx, | 5197 | "subcode %x)\n", vha->vp_idx, |
@@ -5492,11 +5418,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, | |||
5492 | se_sess = sess->se_sess; | 5418 | se_sess = sess->se_sess; |
5493 | 5419 | ||
5494 | tag = sbitmap_queue_get(&se_sess->sess_tag_pool, &cpu); | 5420 | tag = sbitmap_queue_get(&se_sess->sess_tag_pool, &cpu); |
5495 | if (tag < 0) | 5421 | if (tag < 0) { |
5496 | return; | ||
5497 | |||
5498 | cmd = &((struct qla_tgt_cmd *)se_sess->sess_cmd_map)[tag]; | ||
5499 | if (!cmd) { | ||
5500 | ql_dbg(ql_dbg_io, vha, 0x3009, | 5422 | ql_dbg(ql_dbg_io, vha, 0x3009, |
5501 | "qla_target(%d): %s: Allocation of cmd failed\n", | 5423 | "qla_target(%d): %s: Allocation of cmd failed\n", |
5502 | vha->vp_idx, __func__); | 5424 | vha->vp_idx, __func__); |
@@ -5511,6 +5433,7 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, | |||
5511 | return; | 5433 | return; |
5512 | } | 5434 | } |
5513 | 5435 | ||
5436 | cmd = &((struct qla_tgt_cmd *)se_sess->sess_cmd_map)[tag]; | ||
5514 | memset(cmd, 0, sizeof(struct qla_tgt_cmd)); | 5437 | memset(cmd, 0, sizeof(struct qla_tgt_cmd)); |
5515 | 5438 | ||
5516 | qlt_incr_num_pend_cmds(vha); | 5439 | qlt_incr_num_pend_cmds(vha); |
@@ -5820,8 +5743,7 @@ static void qlt_handle_abts_completion(struct scsi_qla_host *vha, | |||
5820 | struct qla_tgt_mgmt_cmd *mcmd; | 5743 | struct qla_tgt_mgmt_cmd *mcmd; |
5821 | struct qla_hw_data *ha = vha->hw; | 5744 | struct qla_hw_data *ha = vha->hw; |
5822 | 5745 | ||
5823 | mcmd = (struct qla_tgt_mgmt_cmd *)qlt_ctio_to_cmd(vha, rsp, | 5746 | mcmd = qlt_ctio_to_cmd(vha, rsp, pkt->handle, pkt); |
5824 | pkt->handle, pkt); | ||
5825 | if (mcmd == NULL && h != QLA_TGT_SKIP_HANDLE) { | 5747 | if (mcmd == NULL && h != QLA_TGT_SKIP_HANDLE) { |
5826 | ql_dbg(ql_dbg_async, vha, 0xe064, | 5748 | ql_dbg(ql_dbg_async, vha, 0xe064, |
5827 | "qla_target(%d): ABTS Comp without mcmd\n", | 5749 | "qla_target(%d): ABTS Comp without mcmd\n", |
@@ -5883,6 +5805,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, | |||
5883 | case CTIO_TYPE7: | 5805 | case CTIO_TYPE7: |
5884 | { | 5806 | { |
5885 | struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt; | 5807 | struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt; |
5808 | |||
5886 | qlt_do_ctio_completion(vha, rsp, entry->handle, | 5809 | qlt_do_ctio_completion(vha, rsp, entry->handle, |
5887 | le16_to_cpu(entry->status)|(pkt->entry_status << 16), | 5810 | le16_to_cpu(entry->status)|(pkt->entry_status << 16), |
5888 | entry); | 5811 | entry); |
@@ -5893,6 +5816,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, | |||
5893 | { | 5816 | { |
5894 | struct atio_from_isp *atio = (struct atio_from_isp *)pkt; | 5817 | struct atio_from_isp *atio = (struct atio_from_isp *)pkt; |
5895 | int rc; | 5818 | int rc; |
5819 | |||
5896 | if (atio->u.isp2x.status != | 5820 | if (atio->u.isp2x.status != |
5897 | cpu_to_le16(ATIO_CDB_VALID)) { | 5821 | cpu_to_le16(ATIO_CDB_VALID)) { |
5898 | ql_dbg(ql_dbg_tgt, vha, 0xe05e, | 5822 | ql_dbg(ql_dbg_tgt, vha, 0xe05e, |
@@ -5941,6 +5865,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, | |||
5941 | case CONTINUE_TGT_IO_TYPE: | 5865 | case CONTINUE_TGT_IO_TYPE: |
5942 | { | 5866 | { |
5943 | struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt; | 5867 | struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt; |
5868 | |||
5944 | qlt_do_ctio_completion(vha, rsp, entry->handle, | 5869 | qlt_do_ctio_completion(vha, rsp, entry->handle, |
5945 | le16_to_cpu(entry->status)|(pkt->entry_status << 16), | 5870 | le16_to_cpu(entry->status)|(pkt->entry_status << 16), |
5946 | entry); | 5871 | entry); |
@@ -5950,6 +5875,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, | |||
5950 | case CTIO_A64_TYPE: | 5875 | case CTIO_A64_TYPE: |
5951 | { | 5876 | { |
5952 | struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt; | 5877 | struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt; |
5878 | |||
5953 | qlt_do_ctio_completion(vha, rsp, entry->handle, | 5879 | qlt_do_ctio_completion(vha, rsp, entry->handle, |
5954 | le16_to_cpu(entry->status)|(pkt->entry_status << 16), | 5880 | le16_to_cpu(entry->status)|(pkt->entry_status << 16), |
5955 | entry); | 5881 | entry); |
@@ -5964,6 +5890,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, | |||
5964 | case NOTIFY_ACK_TYPE: | 5890 | case NOTIFY_ACK_TYPE: |
5965 | if (tgt->notify_ack_expected > 0) { | 5891 | if (tgt->notify_ack_expected > 0) { |
5966 | struct nack_to_isp *entry = (struct nack_to_isp *)pkt; | 5892 | struct nack_to_isp *entry = (struct nack_to_isp *)pkt; |
5893 | |||
5967 | ql_dbg(ql_dbg_tgt, vha, 0xe036, | 5894 | ql_dbg(ql_dbg_tgt, vha, 0xe036, |
5968 | "NOTIFY_ACK seq %08x status %x\n", | 5895 | "NOTIFY_ACK seq %08x status %x\n", |
5969 | le16_to_cpu(entry->u.isp2x.seq_id), | 5896 | le16_to_cpu(entry->u.isp2x.seq_id), |
@@ -6239,6 +6166,7 @@ retry: | |||
6239 | 6166 | ||
6240 | if (rc == -ENOENT) { | 6167 | if (rc == -ENOENT) { |
6241 | qlt_port_logo_t logo; | 6168 | qlt_port_logo_t logo; |
6169 | |||
6242 | sid_to_portid(s_id, &logo.id); | 6170 | sid_to_portid(s_id, &logo.id); |
6243 | logo.cmd_count = 1; | 6171 | logo.cmd_count = 1; |
6244 | qlt_send_first_logo(vha, &logo); | 6172 | qlt_send_first_logo(vha, &logo); |
@@ -6318,17 +6246,19 @@ static void qlt_abort_work(struct qla_tgt *tgt, | |||
6318 | } | 6246 | } |
6319 | 6247 | ||
6320 | rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess); | 6248 | rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess); |
6321 | ha->tgt.tgt_ops->put_sess(sess); | ||
6322 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2); | 6249 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2); |
6323 | 6250 | ||
6251 | ha->tgt.tgt_ops->put_sess(sess); | ||
6252 | |||
6324 | if (rc != 0) | 6253 | if (rc != 0) |
6325 | goto out_term; | 6254 | goto out_term; |
6326 | return; | 6255 | return; |
6327 | 6256 | ||
6328 | out_term2: | 6257 | out_term2: |
6258 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2); | ||
6259 | |||
6329 | if (sess) | 6260 | if (sess) |
6330 | ha->tgt.tgt_ops->put_sess(sess); | 6261 | ha->tgt.tgt_ops->put_sess(sess); |
6331 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2); | ||
6332 | 6262 | ||
6333 | out_term: | 6263 | out_term: |
6334 | spin_lock_irqsave(&ha->hardware_lock, flags); | 6264 | spin_lock_irqsave(&ha->hardware_lock, flags); |
@@ -6386,9 +6316,10 @@ static void qlt_tmr_work(struct qla_tgt *tgt, | |||
6386 | scsilun_to_int((struct scsi_lun *)&a->u.isp24.fcp_cmnd.lun); | 6316 | scsilun_to_int((struct scsi_lun *)&a->u.isp24.fcp_cmnd.lun); |
6387 | 6317 | ||
6388 | rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); | 6318 | rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); |
6389 | ha->tgt.tgt_ops->put_sess(sess); | ||
6390 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); | 6319 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); |
6391 | 6320 | ||
6321 | ha->tgt.tgt_ops->put_sess(sess); | ||
6322 | |||
6392 | if (rc != 0) | 6323 | if (rc != 0) |
6393 | goto out_term; | 6324 | goto out_term; |
6394 | return; | 6325 | return; |
@@ -6499,6 +6430,7 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha) | |||
6499 | unsigned long flags; | 6430 | unsigned long flags; |
6500 | 6431 | ||
6501 | struct qla_qpair *qpair = ha->queue_pair_map[i]; | 6432 | struct qla_qpair *qpair = ha->queue_pair_map[i]; |
6433 | |||
6502 | h = &tgt->qphints[i + 1]; | 6434 | h = &tgt->qphints[i + 1]; |
6503 | INIT_LIST_HEAD(&h->hint_elem); | 6435 | INIT_LIST_HEAD(&h->hint_elem); |
6504 | if (qpair) { | 6436 | if (qpair) { |
@@ -6937,7 +6869,7 @@ qlt_24xx_config_rings(struct scsi_qla_host *vha) | |||
6937 | RD_REG_DWORD(ISP_ATIO_Q_OUT(vha)); | 6869 | RD_REG_DWORD(ISP_ATIO_Q_OUT(vha)); |
6938 | 6870 | ||
6939 | if (ha->flags.msix_enabled) { | 6871 | if (ha->flags.msix_enabled) { |
6940 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 6872 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
6941 | if (IS_QLA2071(ha)) { | 6873 | if (IS_QLA2071(ha)) { |
6942 | /* 4 ports Baker: Enable Interrupt Handshake */ | 6874 | /* 4 ports Baker: Enable Interrupt Handshake */ |
6943 | icb->msix_atio = 0; | 6875 | icb->msix_atio = 0; |
@@ -6952,7 +6884,7 @@ qlt_24xx_config_rings(struct scsi_qla_host *vha) | |||
6952 | } | 6884 | } |
6953 | } else { | 6885 | } else { |
6954 | /* INTx|MSI */ | 6886 | /* INTx|MSI */ |
6955 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 6887 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { |
6956 | icb->msix_atio = 0; | 6888 | icb->msix_atio = 0; |
6957 | icb->firmware_options_2 |= BIT_26; | 6889 | icb->firmware_options_2 |= BIT_26; |
6958 | ql_dbg(ql_dbg_init, vha, 0xf072, | 6890 | ql_dbg(ql_dbg_init, vha, 0xf072, |
@@ -7201,7 +7133,8 @@ qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha) | |||
7201 | if (!QLA_TGT_MODE_ENABLED()) | 7133 | if (!QLA_TGT_MODE_ENABLED()) |
7202 | return; | 7134 | return; |
7203 | 7135 | ||
7204 | if ((ql2xenablemsix == 0) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 7136 | if ((ql2xenablemsix == 0) || IS_QLA83XX(ha) || IS_QLA27XX(ha) || |
7137 | IS_QLA28XX(ha)) { | ||
7205 | ISP_ATIO_Q_IN(base_vha) = &ha->mqiobase->isp25mq.atio_q_in; | 7138 | ISP_ATIO_Q_IN(base_vha) = &ha->mqiobase->isp25mq.atio_q_in; |
7206 | ISP_ATIO_Q_OUT(base_vha) = &ha->mqiobase->isp25mq.atio_q_out; | 7139 | ISP_ATIO_Q_OUT(base_vha) = &ha->mqiobase->isp25mq.atio_q_out; |
7207 | } else { | 7140 | } else { |
@@ -7329,7 +7262,10 @@ qlt_mem_free(struct qla_hw_data *ha) | |||
7329 | sizeof(struct atio_from_isp), ha->tgt.atio_ring, | 7262 | sizeof(struct atio_from_isp), ha->tgt.atio_ring, |
7330 | ha->tgt.atio_dma); | 7263 | ha->tgt.atio_dma); |
7331 | } | 7264 | } |
7265 | ha->tgt.atio_ring = NULL; | ||
7266 | ha->tgt.atio_dma = 0; | ||
7332 | kfree(ha->tgt.tgt_vp_map); | 7267 | kfree(ha->tgt.tgt_vp_map); |
7268 | ha->tgt.tgt_vp_map = NULL; | ||
7333 | } | 7269 | } |
7334 | 7270 | ||
7335 | /* vport_slock to be held by the caller */ | 7271 | /* vport_slock to be held by the caller */ |
@@ -7413,6 +7349,9 @@ int __init qlt_init(void) | |||
7413 | { | 7349 | { |
7414 | int ret; | 7350 | int ret; |
7415 | 7351 | ||
7352 | BUILD_BUG_ON(sizeof(struct ctio7_to_24xx) != 64); | ||
7353 | BUILD_BUG_ON(sizeof(struct ctio_to_2xxx) != 64); | ||
7354 | |||
7416 | if (!qlt_parse_ini_mode()) { | 7355 | if (!qlt_parse_ini_mode()) { |
7417 | ql_log(ql_log_fatal, NULL, 0xe06b, | 7356 | ql_log(ql_log_fatal, NULL, 0xe06b, |
7418 | "qlt_parse_ini_mode() failed\n"); | 7357 | "qlt_parse_ini_mode() failed\n"); |
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index f3de75000a08..89ceffa7d4fd 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #define __QLA_TARGET_H | 29 | #define __QLA_TARGET_H |
30 | 30 | ||
31 | #include "qla_def.h" | 31 | #include "qla_def.h" |
32 | #include "qla_dsd.h" | ||
32 | 33 | ||
33 | /* | 34 | /* |
34 | * Must be changed on any change in any initiator visible interfaces or | 35 | * Must be changed on any change in any initiator visible interfaces or |
@@ -224,12 +225,7 @@ struct ctio_to_2xxx { | |||
224 | uint16_t reserved_1[3]; | 225 | uint16_t reserved_1[3]; |
225 | uint16_t scsi_status; | 226 | uint16_t scsi_status; |
226 | uint32_t transfer_length; | 227 | uint32_t transfer_length; |
227 | uint32_t dseg_0_address; /* Data segment 0 address. */ | 228 | struct dsd32 dsd[3]; |
228 | uint32_t dseg_0_length; /* Data segment 0 length. */ | ||
229 | uint32_t dseg_1_address; /* Data segment 1 address. */ | ||
230 | uint32_t dseg_1_length; /* Data segment 1 length. */ | ||
231 | uint32_t dseg_2_address; /* Data segment 2 address. */ | ||
232 | uint32_t dseg_2_length; /* Data segment 2 length. */ | ||
233 | } __packed; | 229 | } __packed; |
234 | #define ATIO_PATH_INVALID 0x07 | 230 | #define ATIO_PATH_INVALID 0x07 |
235 | #define ATIO_CANT_PROV_CAP 0x16 | 231 | #define ATIO_CANT_PROV_CAP 0x16 |
@@ -429,10 +425,7 @@ struct ctio7_to_24xx { | |||
429 | uint32_t reserved2; | 425 | uint32_t reserved2; |
430 | uint32_t transfer_length; | 426 | uint32_t transfer_length; |
431 | uint32_t reserved3; | 427 | uint32_t reserved3; |
432 | /* Data segment 0 address. */ | 428 | struct dsd64 dsd; |
433 | uint32_t dseg_0_address[2]; | ||
434 | /* Data segment 0 length. */ | ||
435 | uint32_t dseg_0_length; | ||
436 | } status0; | 429 | } status0; |
437 | struct { | 430 | struct { |
438 | uint16_t sense_length; | 431 | uint16_t sense_length; |
@@ -526,10 +519,10 @@ struct ctio_crc2_to_fw { | |||
526 | uint32_t reserved5; | 519 | uint32_t reserved5; |
527 | __le32 transfer_length; /* total fc transfer length */ | 520 | __le32 transfer_length; /* total fc transfer length */ |
528 | uint32_t reserved6; | 521 | uint32_t reserved6; |
529 | __le32 crc_context_address[2];/* Data segment address. */ | 522 | __le64 crc_context_address __packed; /* Data segment address. */ |
530 | uint16_t crc_context_len; /* Data segment length. */ | 523 | uint16_t crc_context_len; /* Data segment length. */ |
531 | uint16_t reserved_1; /* MUST be set to 0. */ | 524 | uint16_t reserved_1; /* MUST be set to 0. */ |
532 | } __packed; | 525 | }; |
533 | 526 | ||
534 | /* CTIO Type CRC_x Status IOCB */ | 527 | /* CTIO Type CRC_x Status IOCB */ |
535 | struct ctio_crc_from_fw { | 528 | struct ctio_crc_from_fw { |
@@ -855,7 +848,7 @@ enum trace_flags { | |||
855 | TRC_CTIO_ERR = BIT_11, | 848 | TRC_CTIO_ERR = BIT_11, |
856 | TRC_CTIO_DONE = BIT_12, | 849 | TRC_CTIO_DONE = BIT_12, |
857 | TRC_CTIO_ABORTED = BIT_13, | 850 | TRC_CTIO_ABORTED = BIT_13, |
858 | TRC_CTIO_STRANGE= BIT_14, | 851 | TRC_CTIO_STRANGE = BIT_14, |
859 | TRC_CMD_DONE = BIT_15, | 852 | TRC_CMD_DONE = BIT_15, |
860 | TRC_CMD_CHK_STOP = BIT_16, | 853 | TRC_CMD_CHK_STOP = BIT_16, |
861 | TRC_CMD_FREE = BIT_17, | 854 | TRC_CMD_FREE = BIT_17, |
@@ -889,10 +882,14 @@ struct qla_tgt_cmd { | |||
889 | unsigned int term_exchg:1; | 882 | unsigned int term_exchg:1; |
890 | unsigned int cmd_sent_to_fw:1; | 883 | unsigned int cmd_sent_to_fw:1; |
891 | unsigned int cmd_in_wq:1; | 884 | unsigned int cmd_in_wq:1; |
892 | unsigned int aborted:1; | 885 | |
893 | unsigned int data_work:1; | 886 | /* |
894 | unsigned int data_work_free:1; | 887 | * This variable may be set from outside the LIO and I/O completion |
895 | unsigned int released:1; | 888 | * callback functions. Do not declare this member variable as a |
889 | * bitfield to avoid a read-modify-write operation when this variable | ||
890 | * is set. | ||
891 | */ | ||
892 | unsigned int aborted; | ||
896 | 893 | ||
897 | struct scatterlist *sg; /* cmd data buffer SG vector */ | 894 | struct scatterlist *sg; /* cmd data buffer SG vector */ |
898 | int sg_cnt; /* SG segments count */ | 895 | int sg_cnt; /* SG segments count */ |
@@ -1103,7 +1100,5 @@ extern void qlt_do_generation_tick(struct scsi_qla_host *, int *); | |||
1103 | 1100 | ||
1104 | void qlt_send_resp_ctio(struct qla_qpair *, struct qla_tgt_cmd *, uint8_t, | 1101 | void qlt_send_resp_ctio(struct qla_qpair *, struct qla_tgt_cmd *, uint8_t, |
1105 | uint8_t, uint8_t, uint8_t); | 1102 | uint8_t, uint8_t, uint8_t); |
1106 | extern void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *, | ||
1107 | struct qla_tgt_cmd *); | ||
1108 | 1103 | ||
1109 | #endif /* __QLA_TARGET_H */ | 1104 | #endif /* __QLA_TARGET_H */ |
diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c index 9e52500caff0..de696a07532e 100644 --- a/drivers/scsi/qla2xxx/qla_tmpl.c +++ b/drivers/scsi/qla2xxx/qla_tmpl.c | |||
@@ -7,103 +7,9 @@ | |||
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | #include "qla_tmpl.h" | 8 | #include "qla_tmpl.h" |
9 | 9 | ||
10 | /* note default template is in big endian */ | 10 | #define ISPREG(vha) (&(vha)->hw->iobase->isp24) |
11 | static const uint32_t ql27xx_fwdt_default_template[] = { | 11 | #define IOBAR(reg) offsetof(typeof(*(reg)), iobase_addr) |
12 | 0x63000000, 0xa4000000, 0x7c050000, 0x00000000, | 12 | #define IOBASE(vha) IOBAR(ISPREG(vha)) |
13 | 0x30000000, 0x01000000, 0x00000000, 0xc0406eb4, | ||
14 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
15 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
16 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
17 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
18 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
19 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
20 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
21 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
22 | 0x00000000, 0x04010000, 0x14000000, 0x00000000, | ||
23 | 0x02000000, 0x44000000, 0x09010000, 0x10000000, | ||
24 | 0x00000000, 0x02000000, 0x01010000, 0x1c000000, | ||
25 | 0x00000000, 0x02000000, 0x00600000, 0x00000000, | ||
26 | 0xc0000000, 0x01010000, 0x1c000000, 0x00000000, | ||
27 | 0x02000000, 0x00600000, 0x00000000, 0xcc000000, | ||
28 | 0x01010000, 0x1c000000, 0x00000000, 0x02000000, | ||
29 | 0x10600000, 0x00000000, 0xd4000000, 0x01010000, | ||
30 | 0x1c000000, 0x00000000, 0x02000000, 0x700f0000, | ||
31 | 0x00000060, 0xf0000000, 0x00010000, 0x18000000, | ||
32 | 0x00000000, 0x02000000, 0x00700000, 0x041000c0, | ||
33 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
34 | 0x10700000, 0x041000c0, 0x00010000, 0x18000000, | ||
35 | 0x00000000, 0x02000000, 0x40700000, 0x041000c0, | ||
36 | 0x01010000, 0x1c000000, 0x00000000, 0x02000000, | ||
37 | 0x007c0000, 0x01000000, 0xc0000000, 0x00010000, | ||
38 | 0x18000000, 0x00000000, 0x02000000, 0x007c0000, | ||
39 | 0x040300c4, 0x00010000, 0x18000000, 0x00000000, | ||
40 | 0x02000000, 0x007c0000, 0x040100c0, 0x01010000, | ||
41 | 0x1c000000, 0x00000000, 0x02000000, 0x007c0000, | ||
42 | 0x00000000, 0xc0000000, 0x00010000, 0x18000000, | ||
43 | 0x00000000, 0x02000000, 0x007c0000, 0x04200000, | ||
44 | 0x0b010000, 0x18000000, 0x00000000, 0x02000000, | ||
45 | 0x0c000000, 0x00000000, 0x02010000, 0x20000000, | ||
46 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
47 | 0xf0000000, 0x000000b0, 0x02010000, 0x20000000, | ||
48 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
49 | 0xf0000000, 0x000010b0, 0x02010000, 0x20000000, | ||
50 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
51 | 0xf0000000, 0x000020b0, 0x02010000, 0x20000000, | ||
52 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
53 | 0xf0000000, 0x000030b0, 0x02010000, 0x20000000, | ||
54 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
55 | 0xf0000000, 0x000040b0, 0x02010000, 0x20000000, | ||
56 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
57 | 0xf0000000, 0x000050b0, 0x02010000, 0x20000000, | ||
58 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
59 | 0xf0000000, 0x000060b0, 0x02010000, 0x20000000, | ||
60 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
61 | 0xf0000000, 0x000070b0, 0x02010000, 0x20000000, | ||
62 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
63 | 0xf0000000, 0x000080b0, 0x02010000, 0x20000000, | ||
64 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
65 | 0xf0000000, 0x000090b0, 0x02010000, 0x20000000, | ||
66 | 0x00000000, 0x02000000, 0x700f0000, 0x040100fc, | ||
67 | 0xf0000000, 0x0000a0b0, 0x00010000, 0x18000000, | ||
68 | 0x00000000, 0x02000000, 0x0a000000, 0x040100c0, | ||
69 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
70 | 0x0a000000, 0x04200080, 0x00010000, 0x18000000, | ||
71 | 0x00000000, 0x02000000, 0x00be0000, 0x041000c0, | ||
72 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
73 | 0x10be0000, 0x041000c0, 0x00010000, 0x18000000, | ||
74 | 0x00000000, 0x02000000, 0x20be0000, 0x041000c0, | ||
75 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
76 | 0x30be0000, 0x041000c0, 0x00010000, 0x18000000, | ||
77 | 0x00000000, 0x02000000, 0x00b00000, 0x041000c0, | ||
78 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
79 | 0x10b00000, 0x041000c0, 0x00010000, 0x18000000, | ||
80 | 0x00000000, 0x02000000, 0x20b00000, 0x041000c0, | ||
81 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
82 | 0x30b00000, 0x041000c0, 0x00010000, 0x18000000, | ||
83 | 0x00000000, 0x02000000, 0x00300000, 0x041000c0, | ||
84 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
85 | 0x10300000, 0x041000c0, 0x00010000, 0x18000000, | ||
86 | 0x00000000, 0x02000000, 0x20300000, 0x041000c0, | ||
87 | 0x00010000, 0x18000000, 0x00000000, 0x02000000, | ||
88 | 0x30300000, 0x041000c0, 0x0a010000, 0x10000000, | ||
89 | 0x00000000, 0x02000000, 0x06010000, 0x1c000000, | ||
90 | 0x00000000, 0x02000000, 0x01000000, 0x00000200, | ||
91 | 0xff230200, 0x06010000, 0x1c000000, 0x00000000, | ||
92 | 0x02000000, 0x02000000, 0x00001000, 0x00000000, | ||
93 | 0x07010000, 0x18000000, 0x00000000, 0x02000000, | ||
94 | 0x00000000, 0x01000000, 0x07010000, 0x18000000, | ||
95 | 0x00000000, 0x02000000, 0x00000000, 0x02000000, | ||
96 | 0x07010000, 0x18000000, 0x00000000, 0x02000000, | ||
97 | 0x00000000, 0x03000000, 0x0d010000, 0x14000000, | ||
98 | 0x00000000, 0x02000000, 0x00000000, 0xff000000, | ||
99 | 0x10000000, 0x00000000, 0x00000080, | ||
100 | }; | ||
101 | |||
102 | static inline void __iomem * | ||
103 | qla27xx_isp_reg(struct scsi_qla_host *vha) | ||
104 | { | ||
105 | return &vha->hw->iobase->isp24; | ||
106 | } | ||
107 | 13 | ||
108 | static inline void | 14 | static inline void |
109 | qla27xx_insert16(uint16_t value, void *buf, ulong *len) | 15 | qla27xx_insert16(uint16_t value, void *buf, ulong *len) |
@@ -128,7 +34,6 @@ qla27xx_insert32(uint32_t value, void *buf, ulong *len) | |||
128 | static inline void | 34 | static inline void |
129 | qla27xx_insertbuf(void *mem, ulong size, void *buf, ulong *len) | 35 | qla27xx_insertbuf(void *mem, ulong size, void *buf, ulong *len) |
130 | { | 36 | { |
131 | |||
132 | if (buf && mem && size) { | 37 | if (buf && mem && size) { |
133 | buf += *len; | 38 | buf += *len; |
134 | memcpy(buf, mem, size); | 39 | memcpy(buf, mem, size); |
@@ -190,9 +95,9 @@ static inline void | |||
190 | qla27xx_write_reg(__iomem struct device_reg_24xx *reg, | 95 | qla27xx_write_reg(__iomem struct device_reg_24xx *reg, |
191 | uint offset, uint32_t data, void *buf) | 96 | uint offset, uint32_t data, void *buf) |
192 | { | 97 | { |
193 | __iomem void *window = (void __iomem *)reg + offset; | ||
194 | |||
195 | if (buf) { | 98 | if (buf) { |
99 | void __iomem *window = (void __iomem *)reg + offset; | ||
100 | |||
196 | WRT_REG_DWORD(window, data); | 101 | WRT_REG_DWORD(window, data); |
197 | } | 102 | } |
198 | } | 103 | } |
@@ -205,7 +110,7 @@ qla27xx_read_window(__iomem struct device_reg_24xx *reg, | |||
205 | void __iomem *window = (void __iomem *)reg + offset; | 110 | void __iomem *window = (void __iomem *)reg + offset; |
206 | void (*readn)(void __iomem*, void *, ulong *) = qla27xx_read_vector(width); | 111 | void (*readn)(void __iomem*, void *, ulong *) = qla27xx_read_vector(width); |
207 | 112 | ||
208 | qla27xx_write_reg(reg, IOBASE_ADDR, addr, buf); | 113 | qla27xx_write_reg(reg, IOBAR(reg), addr, buf); |
209 | while (count--) { | 114 | while (count--) { |
210 | qla27xx_insert32(addr, buf, len); | 115 | qla27xx_insert32(addr, buf, len); |
211 | readn(window, buf, len); | 116 | readn(window, buf, len); |
@@ -224,7 +129,7 @@ qla27xx_skip_entry(struct qla27xx_fwdt_entry *ent, void *buf) | |||
224 | static inline struct qla27xx_fwdt_entry * | 129 | static inline struct qla27xx_fwdt_entry * |
225 | qla27xx_next_entry(struct qla27xx_fwdt_entry *ent) | 130 | qla27xx_next_entry(struct qla27xx_fwdt_entry *ent) |
226 | { | 131 | { |
227 | return (void *)ent + ent->hdr.size; | 132 | return (void *)ent + le32_to_cpu(ent->hdr.size); |
228 | } | 133 | } |
229 | 134 | ||
230 | static struct qla27xx_fwdt_entry * | 135 | static struct qla27xx_fwdt_entry * |
@@ -254,12 +159,14 @@ static struct qla27xx_fwdt_entry * | |||
254 | qla27xx_fwdt_entry_t256(struct scsi_qla_host *vha, | 159 | qla27xx_fwdt_entry_t256(struct scsi_qla_host *vha, |
255 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 160 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
256 | { | 161 | { |
257 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | 162 | ulong addr = le32_to_cpu(ent->t256.base_addr); |
163 | uint offset = ent->t256.pci_offset; | ||
164 | ulong count = le16_to_cpu(ent->t256.reg_count); | ||
165 | uint width = ent->t256.reg_width; | ||
258 | 166 | ||
259 | ql_dbg(ql_dbg_misc, vha, 0xd200, | 167 | ql_dbg(ql_dbg_misc, vha, 0xd200, |
260 | "%s: rdio t1 [%lx]\n", __func__, *len); | 168 | "%s: rdio t1 [%lx]\n", __func__, *len); |
261 | qla27xx_read_window(reg, ent->t256.base_addr, ent->t256.pci_offset, | 169 | qla27xx_read_window(ISPREG(vha), addr, offset, count, width, buf, len); |
262 | ent->t256.reg_count, ent->t256.reg_width, buf, len); | ||
263 | 170 | ||
264 | return qla27xx_next_entry(ent); | 171 | return qla27xx_next_entry(ent); |
265 | } | 172 | } |
@@ -268,12 +175,14 @@ static struct qla27xx_fwdt_entry * | |||
268 | qla27xx_fwdt_entry_t257(struct scsi_qla_host *vha, | 175 | qla27xx_fwdt_entry_t257(struct scsi_qla_host *vha, |
269 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 176 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
270 | { | 177 | { |
271 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | 178 | ulong addr = le32_to_cpu(ent->t257.base_addr); |
179 | uint offset = ent->t257.pci_offset; | ||
180 | ulong data = le32_to_cpu(ent->t257.write_data); | ||
272 | 181 | ||
273 | ql_dbg(ql_dbg_misc, vha, 0xd201, | 182 | ql_dbg(ql_dbg_misc, vha, 0xd201, |
274 | "%s: wrio t1 [%lx]\n", __func__, *len); | 183 | "%s: wrio t1 [%lx]\n", __func__, *len); |
275 | qla27xx_write_reg(reg, IOBASE_ADDR, ent->t257.base_addr, buf); | 184 | qla27xx_write_reg(ISPREG(vha), IOBASE(vha), addr, buf); |
276 | qla27xx_write_reg(reg, ent->t257.pci_offset, ent->t257.write_data, buf); | 185 | qla27xx_write_reg(ISPREG(vha), offset, data, buf); |
277 | 186 | ||
278 | return qla27xx_next_entry(ent); | 187 | return qla27xx_next_entry(ent); |
279 | } | 188 | } |
@@ -282,13 +191,17 @@ static struct qla27xx_fwdt_entry * | |||
282 | qla27xx_fwdt_entry_t258(struct scsi_qla_host *vha, | 191 | qla27xx_fwdt_entry_t258(struct scsi_qla_host *vha, |
283 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 192 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
284 | { | 193 | { |
285 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | 194 | uint banksel = ent->t258.banksel_offset; |
195 | ulong bank = le32_to_cpu(ent->t258.bank); | ||
196 | ulong addr = le32_to_cpu(ent->t258.base_addr); | ||
197 | uint offset = ent->t258.pci_offset; | ||
198 | uint count = le16_to_cpu(ent->t258.reg_count); | ||
199 | uint width = ent->t258.reg_width; | ||
286 | 200 | ||
287 | ql_dbg(ql_dbg_misc, vha, 0xd202, | 201 | ql_dbg(ql_dbg_misc, vha, 0xd202, |
288 | "%s: rdio t2 [%lx]\n", __func__, *len); | 202 | "%s: rdio t2 [%lx]\n", __func__, *len); |
289 | qla27xx_write_reg(reg, ent->t258.banksel_offset, ent->t258.bank, buf); | 203 | qla27xx_write_reg(ISPREG(vha), banksel, bank, buf); |
290 | qla27xx_read_window(reg, ent->t258.base_addr, ent->t258.pci_offset, | 204 | qla27xx_read_window(ISPREG(vha), addr, offset, count, width, buf, len); |
291 | ent->t258.reg_count, ent->t258.reg_width, buf, len); | ||
292 | 205 | ||
293 | return qla27xx_next_entry(ent); | 206 | return qla27xx_next_entry(ent); |
294 | } | 207 | } |
@@ -297,13 +210,17 @@ static struct qla27xx_fwdt_entry * | |||
297 | qla27xx_fwdt_entry_t259(struct scsi_qla_host *vha, | 210 | qla27xx_fwdt_entry_t259(struct scsi_qla_host *vha, |
298 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 211 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
299 | { | 212 | { |
300 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | 213 | ulong addr = le32_to_cpu(ent->t259.base_addr); |
214 | uint banksel = ent->t259.banksel_offset; | ||
215 | ulong bank = le32_to_cpu(ent->t259.bank); | ||
216 | uint offset = ent->t259.pci_offset; | ||
217 | ulong data = le32_to_cpu(ent->t259.write_data); | ||
301 | 218 | ||
302 | ql_dbg(ql_dbg_misc, vha, 0xd203, | 219 | ql_dbg(ql_dbg_misc, vha, 0xd203, |
303 | "%s: wrio t2 [%lx]\n", __func__, *len); | 220 | "%s: wrio t2 [%lx]\n", __func__, *len); |
304 | qla27xx_write_reg(reg, IOBASE_ADDR, ent->t259.base_addr, buf); | 221 | qla27xx_write_reg(ISPREG(vha), IOBASE(vha), addr, buf); |
305 | qla27xx_write_reg(reg, ent->t259.banksel_offset, ent->t259.bank, buf); | 222 | qla27xx_write_reg(ISPREG(vha), banksel, bank, buf); |
306 | qla27xx_write_reg(reg, ent->t259.pci_offset, ent->t259.write_data, buf); | 223 | qla27xx_write_reg(ISPREG(vha), offset, data, buf); |
307 | 224 | ||
308 | return qla27xx_next_entry(ent); | 225 | return qla27xx_next_entry(ent); |
309 | } | 226 | } |
@@ -312,12 +229,12 @@ static struct qla27xx_fwdt_entry * | |||
312 | qla27xx_fwdt_entry_t260(struct scsi_qla_host *vha, | 229 | qla27xx_fwdt_entry_t260(struct scsi_qla_host *vha, |
313 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 230 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
314 | { | 231 | { |
315 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | 232 | uint offset = ent->t260.pci_offset; |
316 | 233 | ||
317 | ql_dbg(ql_dbg_misc, vha, 0xd204, | 234 | ql_dbg(ql_dbg_misc, vha, 0xd204, |
318 | "%s: rdpci [%lx]\n", __func__, *len); | 235 | "%s: rdpci [%lx]\n", __func__, *len); |
319 | qla27xx_insert32(ent->t260.pci_offset, buf, len); | 236 | qla27xx_insert32(offset, buf, len); |
320 | qla27xx_read_reg(reg, ent->t260.pci_offset, buf, len); | 237 | qla27xx_read_reg(ISPREG(vha), offset, buf, len); |
321 | 238 | ||
322 | return qla27xx_next_entry(ent); | 239 | return qla27xx_next_entry(ent); |
323 | } | 240 | } |
@@ -326,11 +243,12 @@ static struct qla27xx_fwdt_entry * | |||
326 | qla27xx_fwdt_entry_t261(struct scsi_qla_host *vha, | 243 | qla27xx_fwdt_entry_t261(struct scsi_qla_host *vha, |
327 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 244 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
328 | { | 245 | { |
329 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | 246 | uint offset = ent->t261.pci_offset; |
247 | ulong data = le32_to_cpu(ent->t261.write_data); | ||
330 | 248 | ||
331 | ql_dbg(ql_dbg_misc, vha, 0xd205, | 249 | ql_dbg(ql_dbg_misc, vha, 0xd205, |
332 | "%s: wrpci [%lx]\n", __func__, *len); | 250 | "%s: wrpci [%lx]\n", __func__, *len); |
333 | qla27xx_write_reg(reg, ent->t261.pci_offset, ent->t261.write_data, buf); | 251 | qla27xx_write_reg(ISPREG(vha), offset, data, buf); |
334 | 252 | ||
335 | return qla27xx_next_entry(ent); | 253 | return qla27xx_next_entry(ent); |
336 | } | 254 | } |
@@ -339,51 +257,50 @@ static struct qla27xx_fwdt_entry * | |||
339 | qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha, | 257 | qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha, |
340 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 258 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
341 | { | 259 | { |
260 | uint area = ent->t262.ram_area; | ||
261 | ulong start = le32_to_cpu(ent->t262.start_addr); | ||
262 | ulong end = le32_to_cpu(ent->t262.end_addr); | ||
342 | ulong dwords; | 263 | ulong dwords; |
343 | ulong start; | ||
344 | ulong end; | ||
345 | 264 | ||
346 | ql_dbg(ql_dbg_misc, vha, 0xd206, | 265 | ql_dbg(ql_dbg_misc, vha, 0xd206, |
347 | "%s: rdram(%x) [%lx]\n", __func__, ent->t262.ram_area, *len); | 266 | "%s: rdram(%x) [%lx]\n", __func__, ent->t262.ram_area, *len); |
348 | start = ent->t262.start_addr; | ||
349 | end = ent->t262.end_addr; | ||
350 | 267 | ||
351 | if (ent->t262.ram_area == T262_RAM_AREA_CRITICAL_RAM) { | 268 | if (area == T262_RAM_AREA_CRITICAL_RAM) { |
352 | ; | 269 | ; |
353 | } else if (ent->t262.ram_area == T262_RAM_AREA_EXTERNAL_RAM) { | 270 | } else if (area == T262_RAM_AREA_EXTERNAL_RAM) { |
354 | end = vha->hw->fw_memory_size; | 271 | end = vha->hw->fw_memory_size; |
355 | if (buf) | 272 | if (buf) |
356 | ent->t262.end_addr = end; | 273 | ent->t262.end_addr = cpu_to_le32(end); |
357 | } else if (ent->t262.ram_area == T262_RAM_AREA_SHARED_RAM) { | 274 | } else if (area == T262_RAM_AREA_SHARED_RAM) { |
358 | start = vha->hw->fw_shared_ram_start; | 275 | start = vha->hw->fw_shared_ram_start; |
359 | end = vha->hw->fw_shared_ram_end; | 276 | end = vha->hw->fw_shared_ram_end; |
360 | if (buf) { | 277 | if (buf) { |
361 | ent->t262.start_addr = start; | 278 | ent->t262.start_addr = cpu_to_le32(start); |
362 | ent->t262.end_addr = end; | 279 | ent->t262.end_addr = cpu_to_le32(end); |
363 | } | 280 | } |
364 | } else if (ent->t262.ram_area == T262_RAM_AREA_DDR_RAM) { | 281 | } else if (area == T262_RAM_AREA_DDR_RAM) { |
365 | start = vha->hw->fw_ddr_ram_start; | 282 | start = vha->hw->fw_ddr_ram_start; |
366 | end = vha->hw->fw_ddr_ram_end; | 283 | end = vha->hw->fw_ddr_ram_end; |
367 | if (buf) { | 284 | if (buf) { |
368 | ent->t262.start_addr = start; | 285 | ent->t262.start_addr = cpu_to_le32(start); |
369 | ent->t262.end_addr = end; | 286 | ent->t262.end_addr = cpu_to_le32(end); |
370 | } | 287 | } |
371 | } else if (ent->t262.ram_area == T262_RAM_AREA_MISC) { | 288 | } else if (area == T262_RAM_AREA_MISC) { |
372 | if (buf) { | 289 | if (buf) { |
373 | ent->t262.start_addr = start; | 290 | ent->t262.start_addr = cpu_to_le32(start); |
374 | ent->t262.end_addr = end; | 291 | ent->t262.end_addr = cpu_to_le32(end); |
375 | } | 292 | } |
376 | } else { | 293 | } else { |
377 | ql_dbg(ql_dbg_misc, vha, 0xd022, | 294 | ql_dbg(ql_dbg_misc, vha, 0xd022, |
378 | "%s: unknown area %x\n", __func__, ent->t262.ram_area); | 295 | "%s: unknown area %x\n", __func__, area); |
379 | qla27xx_skip_entry(ent, buf); | 296 | qla27xx_skip_entry(ent, buf); |
380 | goto done; | 297 | goto done; |
381 | } | 298 | } |
382 | 299 | ||
383 | if (end < start || start == 0 || end == 0) { | 300 | if (end < start || start == 0 || end == 0) { |
384 | ql_dbg(ql_dbg_misc, vha, 0xd023, | 301 | ql_dbg(ql_dbg_misc, vha, 0xd023, |
385 | "%s: unusable range (start=%x end=%x)\n", __func__, | 302 | "%s: unusable range (start=%lx end=%lx)\n", |
386 | ent->t262.end_addr, ent->t262.start_addr); | 303 | __func__, start, end); |
387 | qla27xx_skip_entry(ent, buf); | 304 | qla27xx_skip_entry(ent, buf); |
388 | goto done; | 305 | goto done; |
389 | } | 306 | } |
@@ -402,13 +319,14 @@ static struct qla27xx_fwdt_entry * | |||
402 | qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha, | 319 | qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha, |
403 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 320 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
404 | { | 321 | { |
322 | uint type = ent->t263.queue_type; | ||
405 | uint count = 0; | 323 | uint count = 0; |
406 | uint i; | 324 | uint i; |
407 | uint length; | 325 | uint length; |
408 | 326 | ||
409 | ql_dbg(ql_dbg_misc, vha, 0xd207, | 327 | ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd207, |
410 | "%s: getq(%x) [%lx]\n", __func__, ent->t263.queue_type, *len); | 328 | "%s: getq(%x) [%lx]\n", __func__, type, *len); |
411 | if (ent->t263.queue_type == T263_QUEUE_TYPE_REQ) { | 329 | if (type == T263_QUEUE_TYPE_REQ) { |
412 | for (i = 0; i < vha->hw->max_req_queues; i++) { | 330 | for (i = 0; i < vha->hw->max_req_queues; i++) { |
413 | struct req_que *req = vha->hw->req_q_map[i]; | 331 | struct req_que *req = vha->hw->req_q_map[i]; |
414 | 332 | ||
@@ -422,7 +340,7 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha, | |||
422 | count++; | 340 | count++; |
423 | } | 341 | } |
424 | } | 342 | } |
425 | } else if (ent->t263.queue_type == T263_QUEUE_TYPE_RSP) { | 343 | } else if (type == T263_QUEUE_TYPE_RSP) { |
426 | for (i = 0; i < vha->hw->max_rsp_queues; i++) { | 344 | for (i = 0; i < vha->hw->max_rsp_queues; i++) { |
427 | struct rsp_que *rsp = vha->hw->rsp_q_map[i]; | 345 | struct rsp_que *rsp = vha->hw->rsp_q_map[i]; |
428 | 346 | ||
@@ -450,7 +368,7 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha, | |||
450 | } | 368 | } |
451 | } else { | 369 | } else { |
452 | ql_dbg(ql_dbg_misc, vha, 0xd026, | 370 | ql_dbg(ql_dbg_misc, vha, 0xd026, |
453 | "%s: unknown queue %x\n", __func__, ent->t263.queue_type); | 371 | "%s: unknown queue %x\n", __func__, type); |
454 | qla27xx_skip_entry(ent, buf); | 372 | qla27xx_skip_entry(ent, buf); |
455 | } | 373 | } |
456 | 374 | ||
@@ -496,12 +414,10 @@ static struct qla27xx_fwdt_entry * | |||
496 | qla27xx_fwdt_entry_t265(struct scsi_qla_host *vha, | 414 | qla27xx_fwdt_entry_t265(struct scsi_qla_host *vha, |
497 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 415 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
498 | { | 416 | { |
499 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | 417 | ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd209, |
500 | |||
501 | ql_dbg(ql_dbg_misc, vha, 0xd209, | ||
502 | "%s: pause risc [%lx]\n", __func__, *len); | 418 | "%s: pause risc [%lx]\n", __func__, *len); |
503 | if (buf) | 419 | if (buf) |
504 | qla24xx_pause_risc(reg, vha->hw); | 420 | qla24xx_pause_risc(ISPREG(vha), vha->hw); |
505 | 421 | ||
506 | return qla27xx_next_entry(ent); | 422 | return qla27xx_next_entry(ent); |
507 | } | 423 | } |
@@ -522,11 +438,12 @@ static struct qla27xx_fwdt_entry * | |||
522 | qla27xx_fwdt_entry_t267(struct scsi_qla_host *vha, | 438 | qla27xx_fwdt_entry_t267(struct scsi_qla_host *vha, |
523 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 439 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
524 | { | 440 | { |
525 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | 441 | uint offset = ent->t267.pci_offset; |
442 | ulong data = le32_to_cpu(ent->t267.data); | ||
526 | 443 | ||
527 | ql_dbg(ql_dbg_misc, vha, 0xd20b, | 444 | ql_dbg(ql_dbg_misc, vha, 0xd20b, |
528 | "%s: dis intr [%lx]\n", __func__, *len); | 445 | "%s: dis intr [%lx]\n", __func__, *len); |
529 | qla27xx_write_reg(reg, ent->t267.pci_offset, ent->t267.data, buf); | 446 | qla27xx_write_reg(ISPREG(vha), offset, data, buf); |
530 | 447 | ||
531 | return qla27xx_next_entry(ent); | 448 | return qla27xx_next_entry(ent); |
532 | } | 449 | } |
@@ -622,17 +539,16 @@ static struct qla27xx_fwdt_entry * | |||
622 | qla27xx_fwdt_entry_t270(struct scsi_qla_host *vha, | 539 | qla27xx_fwdt_entry_t270(struct scsi_qla_host *vha, |
623 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 540 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
624 | { | 541 | { |
625 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | 542 | ulong addr = le32_to_cpu(ent->t270.addr); |
626 | ulong dwords = ent->t270.count; | 543 | ulong dwords = le32_to_cpu(ent->t270.count); |
627 | ulong addr = ent->t270.addr; | ||
628 | 544 | ||
629 | ql_dbg(ql_dbg_misc, vha, 0xd20e, | 545 | ql_dbg(ql_dbg_misc, vha, 0xd20e, |
630 | "%s: rdremreg [%lx]\n", __func__, *len); | 546 | "%s: rdremreg [%lx]\n", __func__, *len); |
631 | qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf); | 547 | qla27xx_write_reg(ISPREG(vha), IOBASE_ADDR, 0x40, buf); |
632 | while (dwords--) { | 548 | while (dwords--) { |
633 | qla27xx_write_reg(reg, 0xc0, addr|0x80000000, buf); | 549 | qla27xx_write_reg(ISPREG(vha), 0xc0, addr|0x80000000, buf); |
634 | qla27xx_insert32(addr, buf, len); | 550 | qla27xx_insert32(addr, buf, len); |
635 | qla27xx_read_reg(reg, 0xc4, buf, len); | 551 | qla27xx_read_reg(ISPREG(vha), 0xc4, buf, len); |
636 | addr += sizeof(uint32_t); | 552 | addr += sizeof(uint32_t); |
637 | } | 553 | } |
638 | 554 | ||
@@ -643,15 +559,14 @@ static struct qla27xx_fwdt_entry * | |||
643 | qla27xx_fwdt_entry_t271(struct scsi_qla_host *vha, | 559 | qla27xx_fwdt_entry_t271(struct scsi_qla_host *vha, |
644 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 560 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
645 | { | 561 | { |
646 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | 562 | ulong addr = le32_to_cpu(ent->t271.addr); |
647 | ulong addr = ent->t271.addr; | 563 | ulong data = le32_to_cpu(ent->t271.data); |
648 | ulong data = ent->t271.data; | ||
649 | 564 | ||
650 | ql_dbg(ql_dbg_misc, vha, 0xd20f, | 565 | ql_dbg(ql_dbg_misc, vha, 0xd20f, |
651 | "%s: wrremreg [%lx]\n", __func__, *len); | 566 | "%s: wrremreg [%lx]\n", __func__, *len); |
652 | qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf); | 567 | qla27xx_write_reg(ISPREG(vha), IOBASE(vha), 0x40, buf); |
653 | qla27xx_write_reg(reg, 0xc4, data, buf); | 568 | qla27xx_write_reg(ISPREG(vha), 0xc4, data, buf); |
654 | qla27xx_write_reg(reg, 0xc0, addr, buf); | 569 | qla27xx_write_reg(ISPREG(vha), 0xc0, addr, buf); |
655 | 570 | ||
656 | return qla27xx_next_entry(ent); | 571 | return qla27xx_next_entry(ent); |
657 | } | 572 | } |
@@ -660,8 +575,8 @@ static struct qla27xx_fwdt_entry * | |||
660 | qla27xx_fwdt_entry_t272(struct scsi_qla_host *vha, | 575 | qla27xx_fwdt_entry_t272(struct scsi_qla_host *vha, |
661 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 576 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
662 | { | 577 | { |
663 | ulong dwords = ent->t272.count; | 578 | ulong dwords = le32_to_cpu(ent->t272.count); |
664 | ulong start = ent->t272.addr; | 579 | ulong start = le32_to_cpu(ent->t272.addr); |
665 | 580 | ||
666 | ql_dbg(ql_dbg_misc, vha, 0xd210, | 581 | ql_dbg(ql_dbg_misc, vha, 0xd210, |
667 | "%s: rdremram [%lx]\n", __func__, *len); | 582 | "%s: rdremram [%lx]\n", __func__, *len); |
@@ -680,8 +595,8 @@ static struct qla27xx_fwdt_entry * | |||
680 | qla27xx_fwdt_entry_t273(struct scsi_qla_host *vha, | 595 | qla27xx_fwdt_entry_t273(struct scsi_qla_host *vha, |
681 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 596 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
682 | { | 597 | { |
683 | ulong dwords = ent->t273.count; | 598 | ulong dwords = le32_to_cpu(ent->t273.count); |
684 | ulong addr = ent->t273.addr; | 599 | ulong addr = le32_to_cpu(ent->t273.addr); |
685 | uint32_t value; | 600 | uint32_t value; |
686 | 601 | ||
687 | ql_dbg(ql_dbg_misc, vha, 0xd211, | 602 | ql_dbg(ql_dbg_misc, vha, 0xd211, |
@@ -703,12 +618,13 @@ static struct qla27xx_fwdt_entry * | |||
703 | qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha, | 618 | qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha, |
704 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 619 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
705 | { | 620 | { |
621 | ulong type = ent->t274.queue_type; | ||
706 | uint count = 0; | 622 | uint count = 0; |
707 | uint i; | 623 | uint i; |
708 | 624 | ||
709 | ql_dbg(ql_dbg_misc, vha, 0xd212, | 625 | ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd212, |
710 | "%s: getqsh(%x) [%lx]\n", __func__, ent->t274.queue_type, *len); | 626 | "%s: getqsh(%lx) [%lx]\n", __func__, type, *len); |
711 | if (ent->t274.queue_type == T274_QUEUE_TYPE_REQ_SHAD) { | 627 | if (type == T274_QUEUE_TYPE_REQ_SHAD) { |
712 | for (i = 0; i < vha->hw->max_req_queues; i++) { | 628 | for (i = 0; i < vha->hw->max_req_queues; i++) { |
713 | struct req_que *req = vha->hw->req_q_map[i]; | 629 | struct req_que *req = vha->hw->req_q_map[i]; |
714 | 630 | ||
@@ -720,7 +636,7 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha, | |||
720 | count++; | 636 | count++; |
721 | } | 637 | } |
722 | } | 638 | } |
723 | } else if (ent->t274.queue_type == T274_QUEUE_TYPE_RSP_SHAD) { | 639 | } else if (type == T274_QUEUE_TYPE_RSP_SHAD) { |
724 | for (i = 0; i < vha->hw->max_rsp_queues; i++) { | 640 | for (i = 0; i < vha->hw->max_rsp_queues; i++) { |
725 | struct rsp_que *rsp = vha->hw->rsp_q_map[i]; | 641 | struct rsp_que *rsp = vha->hw->rsp_q_map[i]; |
726 | 642 | ||
@@ -746,7 +662,7 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha, | |||
746 | } | 662 | } |
747 | } else { | 663 | } else { |
748 | ql_dbg(ql_dbg_misc, vha, 0xd02f, | 664 | ql_dbg(ql_dbg_misc, vha, 0xd02f, |
749 | "%s: unknown queue %x\n", __func__, ent->t274.queue_type); | 665 | "%s: unknown queue %lx\n", __func__, type); |
750 | qla27xx_skip_entry(ent, buf); | 666 | qla27xx_skip_entry(ent, buf); |
751 | } | 667 | } |
752 | 668 | ||
@@ -765,23 +681,26 @@ qla27xx_fwdt_entry_t275(struct scsi_qla_host *vha, | |||
765 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 681 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
766 | { | 682 | { |
767 | ulong offset = offsetof(typeof(*ent), t275.buffer); | 683 | ulong offset = offsetof(typeof(*ent), t275.buffer); |
684 | ulong length = le32_to_cpu(ent->t275.length); | ||
685 | ulong size = le32_to_cpu(ent->hdr.size); | ||
686 | void *buffer = ent->t275.buffer; | ||
768 | 687 | ||
769 | ql_dbg(ql_dbg_misc, vha, 0xd213, | 688 | ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd213, |
770 | "%s: buffer(%x) [%lx]\n", __func__, ent->t275.length, *len); | 689 | "%s: buffer(%lx) [%lx]\n", __func__, length, *len); |
771 | if (!ent->t275.length) { | 690 | if (!length) { |
772 | ql_dbg(ql_dbg_misc, vha, 0xd020, | 691 | ql_dbg(ql_dbg_misc, vha, 0xd020, |
773 | "%s: buffer zero length\n", __func__); | 692 | "%s: buffer zero length\n", __func__); |
774 | qla27xx_skip_entry(ent, buf); | 693 | qla27xx_skip_entry(ent, buf); |
775 | goto done; | 694 | goto done; |
776 | } | 695 | } |
777 | if (offset + ent->t275.length > ent->hdr.size) { | 696 | if (offset + length > size) { |
697 | length = size - offset; | ||
778 | ql_dbg(ql_dbg_misc, vha, 0xd030, | 698 | ql_dbg(ql_dbg_misc, vha, 0xd030, |
779 | "%s: buffer overflow\n", __func__); | 699 | "%s: buffer overflow, truncate [%lx]\n", __func__, length); |
780 | qla27xx_skip_entry(ent, buf); | 700 | ent->t275.length = cpu_to_le32(length); |
781 | goto done; | ||
782 | } | 701 | } |
783 | 702 | ||
784 | qla27xx_insertbuf(ent->t275.buffer, ent->t275.length, buf, len); | 703 | qla27xx_insertbuf(buffer, length, buf, len); |
785 | done: | 704 | done: |
786 | return qla27xx_next_entry(ent); | 705 | return qla27xx_next_entry(ent); |
787 | } | 706 | } |
@@ -790,15 +709,22 @@ static struct qla27xx_fwdt_entry * | |||
790 | qla27xx_fwdt_entry_t276(struct scsi_qla_host *vha, | 709 | qla27xx_fwdt_entry_t276(struct scsi_qla_host *vha, |
791 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 710 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
792 | { | 711 | { |
793 | uint type = vha->hw->pdev->device >> 4 & 0xf; | ||
794 | uint func = vha->hw->port_no & 0x3; | ||
795 | |||
796 | ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd214, | 712 | ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd214, |
797 | "%s: cond [%lx]\n", __func__, *len); | 713 | "%s: cond [%lx]\n", __func__, *len); |
798 | 714 | ||
799 | if (type != ent->t276.cond1 || func != ent->t276.cond2) { | 715 | if (buf) { |
800 | ent = qla27xx_next_entry(ent); | 716 | ulong cond1 = le32_to_cpu(ent->t276.cond1); |
801 | qla27xx_skip_entry(ent, buf); | 717 | ulong cond2 = le32_to_cpu(ent->t276.cond2); |
718 | uint type = vha->hw->pdev->device >> 4 & 0xf; | ||
719 | uint func = vha->hw->port_no & 0x3; | ||
720 | |||
721 | if (type != cond1 || func != cond2) { | ||
722 | struct qla27xx_fwdt_template *tmp = buf; | ||
723 | |||
724 | tmp->count--; | ||
725 | ent = qla27xx_next_entry(ent); | ||
726 | qla27xx_skip_entry(ent, buf); | ||
727 | } | ||
802 | } | 728 | } |
803 | 729 | ||
804 | return qla27xx_next_entry(ent); | 730 | return qla27xx_next_entry(ent); |
@@ -808,13 +734,15 @@ static struct qla27xx_fwdt_entry * | |||
808 | qla27xx_fwdt_entry_t277(struct scsi_qla_host *vha, | 734 | qla27xx_fwdt_entry_t277(struct scsi_qla_host *vha, |
809 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 735 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
810 | { | 736 | { |
811 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | 737 | ulong cmd_addr = le32_to_cpu(ent->t277.cmd_addr); |
738 | ulong wr_cmd_data = le32_to_cpu(ent->t277.wr_cmd_data); | ||
739 | ulong data_addr = le32_to_cpu(ent->t277.data_addr); | ||
812 | 740 | ||
813 | ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd215, | 741 | ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd215, |
814 | "%s: rdpep [%lx]\n", __func__, *len); | 742 | "%s: rdpep [%lx]\n", __func__, *len); |
815 | qla27xx_insert32(ent->t277.wr_cmd_data, buf, len); | 743 | qla27xx_insert32(wr_cmd_data, buf, len); |
816 | qla27xx_write_reg(reg, ent->t277.cmd_addr, ent->t277.wr_cmd_data, buf); | 744 | qla27xx_write_reg(ISPREG(vha), cmd_addr, wr_cmd_data, buf); |
817 | qla27xx_read_reg(reg, ent->t277.data_addr, buf, len); | 745 | qla27xx_read_reg(ISPREG(vha), data_addr, buf, len); |
818 | 746 | ||
819 | return qla27xx_next_entry(ent); | 747 | return qla27xx_next_entry(ent); |
820 | } | 748 | } |
@@ -823,12 +751,15 @@ static struct qla27xx_fwdt_entry * | |||
823 | qla27xx_fwdt_entry_t278(struct scsi_qla_host *vha, | 751 | qla27xx_fwdt_entry_t278(struct scsi_qla_host *vha, |
824 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 752 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
825 | { | 753 | { |
826 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | 754 | ulong cmd_addr = le32_to_cpu(ent->t278.cmd_addr); |
755 | ulong wr_cmd_data = le32_to_cpu(ent->t278.wr_cmd_data); | ||
756 | ulong data_addr = le32_to_cpu(ent->t278.data_addr); | ||
757 | ulong wr_data = le32_to_cpu(ent->t278.wr_data); | ||
827 | 758 | ||
828 | ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd216, | 759 | ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd216, |
829 | "%s: wrpep [%lx]\n", __func__, *len); | 760 | "%s: wrpep [%lx]\n", __func__, *len); |
830 | qla27xx_write_reg(reg, ent->t278.data_addr, ent->t278.wr_data, buf); | 761 | qla27xx_write_reg(ISPREG(vha), data_addr, wr_data, buf); |
831 | qla27xx_write_reg(reg, ent->t278.cmd_addr, ent->t278.wr_cmd_data, buf); | 762 | qla27xx_write_reg(ISPREG(vha), cmd_addr, wr_cmd_data, buf); |
832 | 763 | ||
833 | return qla27xx_next_entry(ent); | 764 | return qla27xx_next_entry(ent); |
834 | } | 765 | } |
@@ -837,8 +768,10 @@ static struct qla27xx_fwdt_entry * | |||
837 | qla27xx_fwdt_entry_other(struct scsi_qla_host *vha, | 768 | qla27xx_fwdt_entry_other(struct scsi_qla_host *vha, |
838 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 769 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
839 | { | 770 | { |
771 | ulong type = le32_to_cpu(ent->hdr.type); | ||
772 | |||
840 | ql_dbg(ql_dbg_misc, vha, 0xd2ff, | 773 | ql_dbg(ql_dbg_misc, vha, 0xd2ff, |
841 | "%s: type %x [%lx]\n", __func__, ent->hdr.type, *len); | 774 | "%s: other %lx [%lx]\n", __func__, type, *len); |
842 | qla27xx_skip_entry(ent, buf); | 775 | qla27xx_skip_entry(ent, buf); |
843 | 776 | ||
844 | return qla27xx_next_entry(ent); | 777 | return qla27xx_next_entry(ent); |
@@ -893,36 +826,27 @@ static void | |||
893 | qla27xx_walk_template(struct scsi_qla_host *vha, | 826 | qla27xx_walk_template(struct scsi_qla_host *vha, |
894 | struct qla27xx_fwdt_template *tmp, void *buf, ulong *len) | 827 | struct qla27xx_fwdt_template *tmp, void *buf, ulong *len) |
895 | { | 828 | { |
896 | struct qla27xx_fwdt_entry *ent = (void *)tmp + tmp->entry_offset; | 829 | struct qla27xx_fwdt_entry *ent = (void *)tmp + |
897 | ulong count = tmp->entry_count; | 830 | le32_to_cpu(tmp->entry_offset); |
831 | ulong type; | ||
898 | 832 | ||
833 | tmp->count = le32_to_cpu(tmp->entry_count); | ||
899 | ql_dbg(ql_dbg_misc, vha, 0xd01a, | 834 | ql_dbg(ql_dbg_misc, vha, 0xd01a, |
900 | "%s: entry count %lx\n", __func__, count); | 835 | "%s: entry count %u\n", __func__, tmp->count); |
901 | while (count--) { | 836 | while (ent && tmp->count--) { |
902 | ent = qla27xx_find_entry(ent->hdr.type)(vha, ent, buf, len); | 837 | type = le32_to_cpu(ent->hdr.type); |
838 | ent = qla27xx_find_entry(type)(vha, ent, buf, len); | ||
903 | if (!ent) | 839 | if (!ent) |
904 | break; | 840 | break; |
905 | } | 841 | } |
906 | 842 | ||
907 | if (count) | 843 | if (tmp->count) |
908 | ql_dbg(ql_dbg_misc, vha, 0xd018, | 844 | ql_dbg(ql_dbg_misc, vha, 0xd018, |
909 | "%s: entry residual count (%lx)\n", __func__, count); | 845 | "%s: entry count residual=+%u\n", __func__, tmp->count); |
910 | 846 | ||
911 | if (ent) | 847 | if (ent) |
912 | ql_dbg(ql_dbg_misc, vha, 0xd019, | 848 | ql_dbg(ql_dbg_misc, vha, 0xd019, |
913 | "%s: missing end entry (%lx)\n", __func__, count); | 849 | "%s: missing end entry\n", __func__); |
914 | |||
915 | if (buf && *len != vha->hw->fw_dump_len) | ||
916 | ql_dbg(ql_dbg_misc, vha, 0xd01b, | ||
917 | "%s: length=%#lx residual=%+ld\n", | ||
918 | __func__, *len, vha->hw->fw_dump_len - *len); | ||
919 | |||
920 | if (buf) { | ||
921 | ql_log(ql_log_warn, vha, 0xd015, | ||
922 | "Firmware dump saved to temp buffer (%lu/%p)\n", | ||
923 | vha->host_no, vha->hw->fw_dump); | ||
924 | qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP); | ||
925 | } | ||
926 | } | 850 | } |
927 | 851 | ||
928 | static void | 852 | static void |
@@ -945,8 +869,8 @@ qla27xx_driver_info(struct qla27xx_fwdt_template *tmp) | |||
945 | } | 869 | } |
946 | 870 | ||
947 | static void | 871 | static void |
948 | qla27xx_firmware_info(struct qla27xx_fwdt_template *tmp, | 872 | qla27xx_firmware_info(struct scsi_qla_host *vha, |
949 | struct scsi_qla_host *vha) | 873 | struct qla27xx_fwdt_template *tmp) |
950 | { | 874 | { |
951 | tmp->firmware_version[0] = vha->hw->fw_major_version; | 875 | tmp->firmware_version[0] = vha->hw->fw_major_version; |
952 | tmp->firmware_version[1] = vha->hw->fw_minor_version; | 876 | tmp->firmware_version[1] = vha->hw->fw_minor_version; |
@@ -963,19 +887,19 @@ ql27xx_edit_template(struct scsi_qla_host *vha, | |||
963 | { | 887 | { |
964 | qla27xx_time_stamp(tmp); | 888 | qla27xx_time_stamp(tmp); |
965 | qla27xx_driver_info(tmp); | 889 | qla27xx_driver_info(tmp); |
966 | qla27xx_firmware_info(tmp, vha); | 890 | qla27xx_firmware_info(vha, tmp); |
967 | } | 891 | } |
968 | 892 | ||
969 | static inline uint32_t | 893 | static inline uint32_t |
970 | qla27xx_template_checksum(void *p, ulong size) | 894 | qla27xx_template_checksum(void *p, ulong size) |
971 | { | 895 | { |
972 | uint32_t *buf = p; | 896 | __le32 *buf = p; |
973 | uint64_t sum = 0; | 897 | uint64_t sum = 0; |
974 | 898 | ||
975 | size /= sizeof(*buf); | 899 | size /= sizeof(*buf); |
976 | 900 | ||
977 | while (size--) | 901 | for ( ; size--; buf++) |
978 | sum += *buf++; | 902 | sum += le32_to_cpu(*buf); |
979 | 903 | ||
980 | sum = (sum & 0xffffffff) + (sum >> 32); | 904 | sum = (sum & 0xffffffff) + (sum >> 32); |
981 | 905 | ||
@@ -991,29 +915,29 @@ qla27xx_verify_template_checksum(struct qla27xx_fwdt_template *tmp) | |||
991 | static inline int | 915 | static inline int |
992 | qla27xx_verify_template_header(struct qla27xx_fwdt_template *tmp) | 916 | qla27xx_verify_template_header(struct qla27xx_fwdt_template *tmp) |
993 | { | 917 | { |
994 | return tmp->template_type == TEMPLATE_TYPE_FWDUMP; | 918 | return le32_to_cpu(tmp->template_type) == TEMPLATE_TYPE_FWDUMP; |
995 | } | 919 | } |
996 | 920 | ||
997 | static void | 921 | static ulong |
998 | qla27xx_execute_fwdt_template(struct scsi_qla_host *vha) | 922 | qla27xx_execute_fwdt_template(struct scsi_qla_host *vha, |
923 | struct qla27xx_fwdt_template *tmp, void *buf) | ||
999 | { | 924 | { |
1000 | struct qla27xx_fwdt_template *tmp = vha->hw->fw_dump_template; | 925 | ulong len = 0; |
1001 | ulong len; | ||
1002 | 926 | ||
1003 | if (qla27xx_fwdt_template_valid(tmp)) { | 927 | if (qla27xx_fwdt_template_valid(tmp)) { |
1004 | len = tmp->template_size; | 928 | len = tmp->template_size; |
1005 | tmp = memcpy(vha->hw->fw_dump, tmp, len); | 929 | tmp = memcpy(buf, tmp, len); |
1006 | ql27xx_edit_template(vha, tmp); | 930 | ql27xx_edit_template(vha, tmp); |
1007 | qla27xx_walk_template(vha, tmp, tmp, &len); | 931 | qla27xx_walk_template(vha, tmp, buf, &len); |
1008 | vha->hw->fw_dump_len = len; | ||
1009 | vha->hw->fw_dumped = 1; | ||
1010 | } | 932 | } |
933 | |||
934 | return len; | ||
1011 | } | 935 | } |
1012 | 936 | ||
1013 | ulong | 937 | ulong |
1014 | qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *vha) | 938 | qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *vha, void *p) |
1015 | { | 939 | { |
1016 | struct qla27xx_fwdt_template *tmp = vha->hw->fw_dump_template; | 940 | struct qla27xx_fwdt_template *tmp = p; |
1017 | ulong len = 0; | 941 | ulong len = 0; |
1018 | 942 | ||
1019 | if (qla27xx_fwdt_template_valid(tmp)) { | 943 | if (qla27xx_fwdt_template_valid(tmp)) { |
@@ -1032,18 +956,6 @@ qla27xx_fwdt_template_size(void *p) | |||
1032 | return tmp->template_size; | 956 | return tmp->template_size; |
1033 | } | 957 | } |
1034 | 958 | ||
1035 | ulong | ||
1036 | qla27xx_fwdt_template_default_size(void) | ||
1037 | { | ||
1038 | return sizeof(ql27xx_fwdt_default_template); | ||
1039 | } | ||
1040 | |||
1041 | const void * | ||
1042 | qla27xx_fwdt_template_default(void) | ||
1043 | { | ||
1044 | return ql27xx_fwdt_default_template; | ||
1045 | } | ||
1046 | |||
1047 | int | 959 | int |
1048 | qla27xx_fwdt_template_valid(void *p) | 960 | qla27xx_fwdt_template_valid(void *p) |
1049 | { | 961 | { |
@@ -1051,7 +963,8 @@ qla27xx_fwdt_template_valid(void *p) | |||
1051 | 963 | ||
1052 | if (!qla27xx_verify_template_header(tmp)) { | 964 | if (!qla27xx_verify_template_header(tmp)) { |
1053 | ql_log(ql_log_warn, NULL, 0xd01c, | 965 | ql_log(ql_log_warn, NULL, 0xd01c, |
1054 | "%s: template type %x\n", __func__, tmp->template_type); | 966 | "%s: template type %x\n", __func__, |
967 | le32_to_cpu(tmp->template_type)); | ||
1055 | return false; | 968 | return false; |
1056 | } | 969 | } |
1057 | 970 | ||
@@ -1074,17 +987,41 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked) | |||
1074 | spin_lock_irqsave(&vha->hw->hardware_lock, flags); | 987 | spin_lock_irqsave(&vha->hw->hardware_lock, flags); |
1075 | #endif | 988 | #endif |
1076 | 989 | ||
1077 | if (!vha->hw->fw_dump) | 990 | if (!vha->hw->fw_dump) { |
1078 | ql_log(ql_log_warn, vha, 0xd01e, "fwdump buffer missing.\n"); | 991 | ql_log(ql_log_warn, vha, 0xd01e, "-> fwdump no buffer\n"); |
1079 | else if (!vha->hw->fw_dump_template) | 992 | } else if (vha->hw->fw_dumped) { |
1080 | ql_log(ql_log_warn, vha, 0xd01f, "fwdump template missing.\n"); | 993 | ql_log(ql_log_warn, vha, 0xd01f, |
1081 | else if (vha->hw->fw_dumped) | 994 | "-> Firmware already dumped (%p) -- ignoring request\n", |
1082 | ql_log(ql_log_warn, vha, 0xd300, | 995 | vha->hw->fw_dump); |
1083 | "Firmware has been previously dumped (%p)," | 996 | } else { |
1084 | " -- ignoring request\n", vha->hw->fw_dump); | 997 | struct fwdt *fwdt = vha->hw->fwdt; |
1085 | else { | 998 | uint j; |
1086 | QLA_FW_STOPPED(vha->hw); | 999 | ulong len; |
1087 | qla27xx_execute_fwdt_template(vha); | 1000 | void *buf = vha->hw->fw_dump; |
1001 | |||
1002 | for (j = 0; j < 2; j++, fwdt++, buf += len) { | ||
1003 | ql_log(ql_log_warn, vha, 0xd011, | ||
1004 | "-> fwdt%u running...\n", j); | ||
1005 | if (!fwdt->template) { | ||
1006 | ql_log(ql_log_warn, vha, 0xd012, | ||
1007 | "-> fwdt%u no template\n", j); | ||
1008 | break; | ||
1009 | } | ||
1010 | len = qla27xx_execute_fwdt_template(vha, | ||
1011 | fwdt->template, buf); | ||
1012 | if (len != fwdt->dump_size) { | ||
1013 | ql_log(ql_log_warn, vha, 0xd013, | ||
1014 | "-> fwdt%u fwdump residual=%+ld\n", | ||
1015 | j, fwdt->dump_size - len); | ||
1016 | } | ||
1017 | } | ||
1018 | vha->hw->fw_dump_len = buf - (void *)vha->hw->fw_dump; | ||
1019 | vha->hw->fw_dumped = 1; | ||
1020 | |||
1021 | ql_log(ql_log_warn, vha, 0xd015, | ||
1022 | "-> Firmware dump saved to buffer (%lu/%p) <%lx>\n", | ||
1023 | vha->host_no, vha->hw->fw_dump, vha->hw->fw_dump_cap_flags); | ||
1024 | qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP); | ||
1088 | } | 1025 | } |
1089 | 1026 | ||
1090 | #ifndef __CHECKER__ | 1027 | #ifndef __CHECKER__ |
diff --git a/drivers/scsi/qla2xxx/qla_tmpl.h b/drivers/scsi/qla2xxx/qla_tmpl.h index 5c2c2a8a19c4..d2a0014e8b21 100644 --- a/drivers/scsi/qla2xxx/qla_tmpl.h +++ b/drivers/scsi/qla2xxx/qla_tmpl.h | |||
@@ -11,12 +11,12 @@ | |||
11 | #define IOBASE_ADDR offsetof(struct device_reg_24xx, iobase_addr) | 11 | #define IOBASE_ADDR offsetof(struct device_reg_24xx, iobase_addr) |
12 | 12 | ||
13 | struct __packed qla27xx_fwdt_template { | 13 | struct __packed qla27xx_fwdt_template { |
14 | uint32_t template_type; | 14 | __le32 template_type; |
15 | uint32_t entry_offset; | 15 | __le32 entry_offset; |
16 | uint32_t template_size; | 16 | uint32_t template_size; |
17 | uint32_t reserved_1; | 17 | uint32_t count; /* borrow field for running/residual count */ |
18 | 18 | ||
19 | uint32_t entry_count; | 19 | __le32 entry_count; |
20 | uint32_t template_version; | 20 | uint32_t template_version; |
21 | uint32_t capture_timestamp; | 21 | uint32_t capture_timestamp; |
22 | uint32_t template_checksum; | 22 | uint32_t template_checksum; |
@@ -65,8 +65,8 @@ struct __packed qla27xx_fwdt_template { | |||
65 | 65 | ||
66 | struct __packed qla27xx_fwdt_entry { | 66 | struct __packed qla27xx_fwdt_entry { |
67 | struct __packed { | 67 | struct __packed { |
68 | uint32_t type; | 68 | __le32 type; |
69 | uint32_t size; | 69 | __le32 size; |
70 | uint32_t reserved_1; | 70 | uint32_t reserved_1; |
71 | 71 | ||
72 | uint8_t capture_flags; | 72 | uint8_t capture_flags; |
@@ -81,36 +81,36 @@ struct __packed qla27xx_fwdt_entry { | |||
81 | } t255; | 81 | } t255; |
82 | 82 | ||
83 | struct __packed { | 83 | struct __packed { |
84 | uint32_t base_addr; | 84 | __le32 base_addr; |
85 | uint8_t reg_width; | 85 | uint8_t reg_width; |
86 | uint16_t reg_count; | 86 | __le16 reg_count; |
87 | uint8_t pci_offset; | 87 | uint8_t pci_offset; |
88 | } t256; | 88 | } t256; |
89 | 89 | ||
90 | struct __packed { | 90 | struct __packed { |
91 | uint32_t base_addr; | 91 | __le32 base_addr; |
92 | uint32_t write_data; | 92 | __le32 write_data; |
93 | uint8_t pci_offset; | 93 | uint8_t pci_offset; |
94 | uint8_t reserved[3]; | 94 | uint8_t reserved[3]; |
95 | } t257; | 95 | } t257; |
96 | 96 | ||
97 | struct __packed { | 97 | struct __packed { |
98 | uint32_t base_addr; | 98 | __le32 base_addr; |
99 | uint8_t reg_width; | 99 | uint8_t reg_width; |
100 | uint16_t reg_count; | 100 | __le16 reg_count; |
101 | uint8_t pci_offset; | 101 | uint8_t pci_offset; |
102 | uint8_t banksel_offset; | 102 | uint8_t banksel_offset; |
103 | uint8_t reserved[3]; | 103 | uint8_t reserved[3]; |
104 | uint32_t bank; | 104 | __le32 bank; |
105 | } t258; | 105 | } t258; |
106 | 106 | ||
107 | struct __packed { | 107 | struct __packed { |
108 | uint32_t base_addr; | 108 | __le32 base_addr; |
109 | uint32_t write_data; | 109 | __le32 write_data; |
110 | uint8_t reserved[2]; | 110 | uint8_t reserved[2]; |
111 | uint8_t pci_offset; | 111 | uint8_t pci_offset; |
112 | uint8_t banksel_offset; | 112 | uint8_t banksel_offset; |
113 | uint32_t bank; | 113 | __le32 bank; |
114 | } t259; | 114 | } t259; |
115 | 115 | ||
116 | struct __packed { | 116 | struct __packed { |
@@ -121,14 +121,14 @@ struct __packed qla27xx_fwdt_entry { | |||
121 | struct __packed { | 121 | struct __packed { |
122 | uint8_t pci_offset; | 122 | uint8_t pci_offset; |
123 | uint8_t reserved[3]; | 123 | uint8_t reserved[3]; |
124 | uint32_t write_data; | 124 | __le32 write_data; |
125 | } t261; | 125 | } t261; |
126 | 126 | ||
127 | struct __packed { | 127 | struct __packed { |
128 | uint8_t ram_area; | 128 | uint8_t ram_area; |
129 | uint8_t reserved[3]; | 129 | uint8_t reserved[3]; |
130 | uint32_t start_addr; | 130 | __le32 start_addr; |
131 | uint32_t end_addr; | 131 | __le32 end_addr; |
132 | } t262; | 132 | } t262; |
133 | 133 | ||
134 | struct __packed { | 134 | struct __packed { |
@@ -158,7 +158,7 @@ struct __packed qla27xx_fwdt_entry { | |||
158 | struct __packed { | 158 | struct __packed { |
159 | uint8_t pci_offset; | 159 | uint8_t pci_offset; |
160 | uint8_t reserved[3]; | 160 | uint8_t reserved[3]; |
161 | uint32_t data; | 161 | __le32 data; |
162 | } t267; | 162 | } t267; |
163 | 163 | ||
164 | struct __packed { | 164 | struct __packed { |
@@ -173,23 +173,23 @@ struct __packed qla27xx_fwdt_entry { | |||
173 | } t269; | 173 | } t269; |
174 | 174 | ||
175 | struct __packed { | 175 | struct __packed { |
176 | uint32_t addr; | 176 | __le32 addr; |
177 | uint32_t count; | 177 | __le32 count; |
178 | } t270; | 178 | } t270; |
179 | 179 | ||
180 | struct __packed { | 180 | struct __packed { |
181 | uint32_t addr; | 181 | __le32 addr; |
182 | uint32_t data; | 182 | __le32 data; |
183 | } t271; | 183 | } t271; |
184 | 184 | ||
185 | struct __packed { | 185 | struct __packed { |
186 | uint32_t addr; | 186 | __le32 addr; |
187 | uint32_t count; | 187 | __le32 count; |
188 | } t272; | 188 | } t272; |
189 | 189 | ||
190 | struct __packed { | 190 | struct __packed { |
191 | uint32_t addr; | 191 | __le32 addr; |
192 | uint32_t count; | 192 | __le32 count; |
193 | } t273; | 193 | } t273; |
194 | 194 | ||
195 | struct __packed { | 195 | struct __packed { |
@@ -199,26 +199,26 @@ struct __packed qla27xx_fwdt_entry { | |||
199 | } t274; | 199 | } t274; |
200 | 200 | ||
201 | struct __packed { | 201 | struct __packed { |
202 | uint32_t length; | 202 | __le32 length; |
203 | uint8_t buffer[]; | 203 | uint8_t buffer[]; |
204 | } t275; | 204 | } t275; |
205 | 205 | ||
206 | struct __packed { | 206 | struct __packed { |
207 | uint32_t cond1; | 207 | __le32 cond1; |
208 | uint32_t cond2; | 208 | __le32 cond2; |
209 | } t276; | 209 | } t276; |
210 | 210 | ||
211 | struct __packed { | 211 | struct __packed { |
212 | uint32_t cmd_addr; | 212 | __le32 cmd_addr; |
213 | uint32_t wr_cmd_data; | 213 | __le32 wr_cmd_data; |
214 | uint32_t data_addr; | 214 | __le32 data_addr; |
215 | } t277; | 215 | } t277; |
216 | 216 | ||
217 | struct __packed { | 217 | struct __packed { |
218 | uint32_t cmd_addr; | 218 | __le32 cmd_addr; |
219 | uint32_t wr_cmd_data; | 219 | __le32 wr_cmd_data; |
220 | uint32_t data_addr; | 220 | __le32 data_addr; |
221 | uint32_t wr_data; | 221 | __le32 wr_data; |
222 | } t278; | 222 | } t278; |
223 | }; | 223 | }; |
224 | }; | 224 | }; |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 0690dac24081..cd6bdf71e533 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,9 +7,9 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "10.00.00.14-k" | 10 | #define QLA2XXX_VERSION "10.01.00.16-k" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 10 | 12 | #define QLA_DRIVER_MAJOR_VER 10 |
13 | #define QLA_DRIVER_MINOR_VER 0 | 13 | #define QLA_DRIVER_MINOR_VER 1 |
14 | #define QLA_DRIVER_PATCH_VER 0 | 14 | #define QLA_DRIVER_PATCH_VER 0 |
15 | #define QLA_DRIVER_BETA_VER 0 | 15 | #define QLA_DRIVER_BETA_VER 0 |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 8a3075d17c63..ec9f1996b417 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -24,22 +24,16 @@ | |||
24 | 24 | ||
25 | 25 | ||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/moduleparam.h> | ||
28 | #include <linux/utsname.h> | 27 | #include <linux/utsname.h> |
29 | #include <linux/vmalloc.h> | 28 | #include <linux/vmalloc.h> |
30 | #include <linux/init.h> | ||
31 | #include <linux/list.h> | 29 | #include <linux/list.h> |
32 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
33 | #include <linux/kthread.h> | ||
34 | #include <linux/types.h> | 31 | #include <linux/types.h> |
35 | #include <linux/string.h> | 32 | #include <linux/string.h> |
36 | #include <linux/configfs.h> | 33 | #include <linux/configfs.h> |
37 | #include <linux/ctype.h> | 34 | #include <linux/ctype.h> |
38 | #include <asm/unaligned.h> | 35 | #include <asm/unaligned.h> |
39 | #include <scsi/scsi.h> | ||
40 | #include <scsi/scsi_host.h> | 36 | #include <scsi/scsi_host.h> |
41 | #include <scsi/scsi_device.h> | ||
42 | #include <scsi/scsi_cmnd.h> | ||
43 | #include <target/target_core_base.h> | 37 | #include <target/target_core_base.h> |
44 | #include <target/target_core_fabric.h> | 38 | #include <target/target_core_fabric.h> |
45 | 39 | ||
@@ -267,25 +261,17 @@ static void tcm_qla2xxx_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd) | |||
267 | static void tcm_qla2xxx_complete_free(struct work_struct *work) | 261 | static void tcm_qla2xxx_complete_free(struct work_struct *work) |
268 | { | 262 | { |
269 | struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); | 263 | struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); |
270 | bool released = false; | ||
271 | unsigned long flags; | ||
272 | 264 | ||
273 | cmd->cmd_in_wq = 0; | 265 | cmd->cmd_in_wq = 0; |
274 | 266 | ||
275 | WARN_ON(cmd->trc_flags & TRC_CMD_FREE); | 267 | WARN_ON(cmd->trc_flags & TRC_CMD_FREE); |
276 | 268 | ||
277 | spin_lock_irqsave(&cmd->cmd_lock, flags); | 269 | /* To do: protect all tgt_counters manipulations with proper locking. */ |
278 | cmd->qpair->tgt_counters.qla_core_ret_sta_ctio++; | 270 | cmd->qpair->tgt_counters.qla_core_ret_sta_ctio++; |
279 | cmd->trc_flags |= TRC_CMD_FREE; | 271 | cmd->trc_flags |= TRC_CMD_FREE; |
280 | cmd->cmd_sent_to_fw = 0; | 272 | cmd->cmd_sent_to_fw = 0; |
281 | if (cmd->released) | ||
282 | released = true; | ||
283 | spin_unlock_irqrestore(&cmd->cmd_lock, flags); | ||
284 | 273 | ||
285 | if (released) | 274 | transport_generic_free_cmd(&cmd->se_cmd, 0); |
286 | qlt_free_cmd(cmd); | ||
287 | else | ||
288 | transport_generic_free_cmd(&cmd->se_cmd, 0); | ||
289 | } | 275 | } |
290 | 276 | ||
291 | /* | 277 | /* |
@@ -326,7 +312,6 @@ static int tcm_qla2xxx_check_stop_free(struct se_cmd *se_cmd) | |||
326 | static void tcm_qla2xxx_release_cmd(struct se_cmd *se_cmd) | 312 | static void tcm_qla2xxx_release_cmd(struct se_cmd *se_cmd) |
327 | { | 313 | { |
328 | struct qla_tgt_cmd *cmd; | 314 | struct qla_tgt_cmd *cmd; |
329 | unsigned long flags; | ||
330 | 315 | ||
331 | if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) { | 316 | if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) { |
332 | struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd, | 317 | struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd, |
@@ -336,14 +321,10 @@ static void tcm_qla2xxx_release_cmd(struct se_cmd *se_cmd) | |||
336 | } | 321 | } |
337 | cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd); | 322 | cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd); |
338 | 323 | ||
339 | spin_lock_irqsave(&cmd->cmd_lock, flags); | 324 | if (WARN_ON(cmd->cmd_sent_to_fw)) |
340 | if (cmd->cmd_sent_to_fw) { | 325 | return; |
341 | cmd->released = 1; | 326 | |
342 | spin_unlock_irqrestore(&cmd->cmd_lock, flags); | 327 | qlt_free_cmd(cmd); |
343 | } else { | ||
344 | spin_unlock_irqrestore(&cmd->cmd_lock, flags); | ||
345 | qlt_free_cmd(cmd); | ||
346 | } | ||
347 | } | 328 | } |
348 | 329 | ||
349 | static void tcm_qla2xxx_release_session(struct kref *kref) | 330 | static void tcm_qla2xxx_release_session(struct kref *kref) |
@@ -359,7 +340,6 @@ static void tcm_qla2xxx_put_sess(struct fc_port *sess) | |||
359 | if (!sess) | 340 | if (!sess) |
360 | return; | 341 | return; |
361 | 342 | ||
362 | assert_spin_locked(&sess->vha->hw->tgt.sess_lock); | ||
363 | kref_put(&sess->sess_kref, tcm_qla2xxx_release_session); | 343 | kref_put(&sess->sess_kref, tcm_qla2xxx_release_session); |
364 | } | 344 | } |
365 | 345 | ||
@@ -374,8 +354,9 @@ static void tcm_qla2xxx_close_session(struct se_session *se_sess) | |||
374 | 354 | ||
375 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | 355 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); |
376 | target_sess_cmd_list_set_waiting(se_sess); | 356 | target_sess_cmd_list_set_waiting(se_sess); |
377 | tcm_qla2xxx_put_sess(sess); | ||
378 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | 357 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); |
358 | |||
359 | tcm_qla2xxx_put_sess(sess); | ||
379 | } | 360 | } |
380 | 361 | ||
381 | static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess) | 362 | static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess) |
@@ -399,6 +380,8 @@ static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd) | |||
399 | cmd->se_cmd.transport_state, | 380 | cmd->se_cmd.transport_state, |
400 | cmd->se_cmd.t_state, | 381 | cmd->se_cmd.t_state, |
401 | cmd->se_cmd.se_cmd_flags); | 382 | cmd->se_cmd.se_cmd_flags); |
383 | transport_generic_request_failure(&cmd->se_cmd, | ||
384 | TCM_CHECK_CONDITION_ABORT_CMD); | ||
402 | return 0; | 385 | return 0; |
403 | } | 386 | } |
404 | cmd->trc_flags |= TRC_XFR_RDY; | 387 | cmd->trc_flags |= TRC_XFR_RDY; |
@@ -488,32 +471,18 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd, | |||
488 | static void tcm_qla2xxx_handle_data_work(struct work_struct *work) | 471 | static void tcm_qla2xxx_handle_data_work(struct work_struct *work) |
489 | { | 472 | { |
490 | struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); | 473 | struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); |
491 | unsigned long flags; | ||
492 | 474 | ||
493 | /* | 475 | /* |
494 | * Ensure that the complete FCP WRITE payload has been received. | 476 | * Ensure that the complete FCP WRITE payload has been received. |
495 | * Otherwise return an exception via CHECK_CONDITION status. | 477 | * Otherwise return an exception via CHECK_CONDITION status. |
496 | */ | 478 | */ |
497 | cmd->cmd_in_wq = 0; | 479 | cmd->cmd_in_wq = 0; |
498 | |||
499 | spin_lock_irqsave(&cmd->cmd_lock, flags); | ||
500 | cmd->cmd_sent_to_fw = 0; | 480 | cmd->cmd_sent_to_fw = 0; |
501 | |||
502 | if (cmd->released) { | ||
503 | spin_unlock_irqrestore(&cmd->cmd_lock, flags); | ||
504 | qlt_free_cmd(cmd); | ||
505 | return; | ||
506 | } | ||
507 | |||
508 | cmd->data_work = 1; | ||
509 | if (cmd->aborted) { | 481 | if (cmd->aborted) { |
510 | cmd->data_work_free = 1; | 482 | transport_generic_request_failure(&cmd->se_cmd, |
511 | spin_unlock_irqrestore(&cmd->cmd_lock, flags); | 483 | TCM_CHECK_CONDITION_ABORT_CMD); |
512 | |||
513 | tcm_qla2xxx_free_cmd(cmd); | ||
514 | return; | 484 | return; |
515 | } | 485 | } |
516 | spin_unlock_irqrestore(&cmd->cmd_lock, flags); | ||
517 | 486 | ||
518 | cmd->qpair->tgt_counters.qla_core_ret_ctio++; | 487 | cmd->qpair->tgt_counters.qla_core_ret_ctio++; |
519 | if (!cmd->write_data_transferred) { | 488 | if (!cmd->write_data_transferred) { |
@@ -829,7 +798,6 @@ static void tcm_qla2xxx_clear_nacl_from_fcport_map(struct fc_port *sess) | |||
829 | 798 | ||
830 | static void tcm_qla2xxx_shutdown_sess(struct fc_port *sess) | 799 | static void tcm_qla2xxx_shutdown_sess(struct fc_port *sess) |
831 | { | 800 | { |
832 | assert_spin_locked(&sess->vha->hw->tgt.sess_lock); | ||
833 | target_sess_cmd_list_set_waiting(sess->se_sess); | 801 | target_sess_cmd_list_set_waiting(sess->se_sess); |
834 | } | 802 | } |
835 | 803 | ||
@@ -1489,7 +1457,7 @@ static int tcm_qla2xxx_check_initiator_node_acl( | |||
1489 | */ | 1457 | */ |
1490 | tpg = lport->tpg_1; | 1458 | tpg = lport->tpg_1; |
1491 | if (!tpg) { | 1459 | if (!tpg) { |
1492 | pr_err("Unable to lcoate struct tcm_qla2xxx_lport->tpg_1\n"); | 1460 | pr_err("Unable to locate struct tcm_qla2xxx_lport->tpg_1\n"); |
1493 | return -EINVAL; | 1461 | return -EINVAL; |
1494 | } | 1462 | } |
1495 | /* | 1463 | /* |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 6e4f4931ae17..8c674eca09f1 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -5930,7 +5930,7 @@ static int get_fw_boot_info(struct scsi_qla_host *ha, uint16_t ddb_index[]) | |||
5930 | val = rd_nvram_byte(ha, sec_addr); | 5930 | val = rd_nvram_byte(ha, sec_addr); |
5931 | if (val & BIT_7) | 5931 | if (val & BIT_7) |
5932 | ddb_index[1] = (val & 0x7f); | 5932 | ddb_index[1] = (val & 0x7f); |
5933 | 5933 | goto exit_boot_info; | |
5934 | } else if (is_qla80XX(ha)) { | 5934 | } else if (is_qla80XX(ha)) { |
5935 | buf = dma_alloc_coherent(&ha->pdev->dev, size, | 5935 | buf = dma_alloc_coherent(&ha->pdev->dev, size, |
5936 | &buf_dma, GFP_KERNEL); | 5936 | &buf_dma, GFP_KERNEL); |
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c index 8b471a925b43..136681ad18a5 100644 --- a/drivers/scsi/qlogicfas408.c +++ b/drivers/scsi/qlogicfas408.c | |||
@@ -139,7 +139,7 @@ static int ql_pdma(struct qlogicfas408_priv *priv, int phase, char *request, int | |||
139 | } else { /* out */ | 139 | } else { /* out */ |
140 | #if QL_TURBO_PDMA | 140 | #if QL_TURBO_PDMA |
141 | rtrc(4) | 141 | rtrc(4) |
142 | if (reqlen >= 128 && inb(qbase + 8) & 0x10) { /* empty */ | 142 | if (reqlen >= 128 && inb(qbase + 8) & 0x10) { /* empty */ |
143 | outsl(qbase + 4, request, 32); | 143 | outsl(qbase + 4, request, 32); |
144 | reqlen -= 128; | 144 | reqlen -= 128; |
145 | request += 128; | 145 | request += 128; |
@@ -240,7 +240,7 @@ static void ql_icmd(struct scsi_cmnd *cmd) | |||
240 | outb(0x40 | qlcfg8 | priv->qinitid, qbase + 8); | 240 | outb(0x40 | qlcfg8 | priv->qinitid, qbase + 8); |
241 | outb(qlcfg7, qbase + 7); | 241 | outb(qlcfg7, qbase + 7); |
242 | outb(qlcfg6, qbase + 6); | 242 | outb(qlcfg6, qbase + 6); |
243 | /**/ outb(qlcfg5, qbase + 5); /* select timer */ | 243 | outb(qlcfg5, qbase + 5); /* select timer */ |
244 | outb(qlcfg9 & 7, qbase + 9); /* prescaler */ | 244 | outb(qlcfg9 & 7, qbase + 9); /* prescaler */ |
245 | /* outb(0x99, qbase + 5); */ | 245 | /* outb(0x99, qbase + 5); */ |
246 | outb(scmd_id(cmd), qbase + 4); | 246 | outb(scmd_id(cmd), qbase + 4); |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 1b8378f36139..8e9680572b9f 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -2393,7 +2393,6 @@ out_put_autopm_host: | |||
2393 | scsi_autopm_put_host(shost); | 2393 | scsi_autopm_put_host(shost); |
2394 | return error; | 2394 | return error; |
2395 | } | 2395 | } |
2396 | EXPORT_SYMBOL(scsi_ioctl_reset); | ||
2397 | 2396 | ||
2398 | bool scsi_command_normalize_sense(const struct scsi_cmnd *cmd, | 2397 | bool scsi_command_normalize_sense(const struct scsi_cmnd *cmd, |
2399 | struct scsi_sense_hdr *sshdr) | 2398 | struct scsi_sense_hdr *sshdr) |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 07dfc17d4824..0916bd6d22b0 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -141,8 +141,6 @@ scsi_set_blocked(struct scsi_cmnd *cmd, int reason) | |||
141 | 141 | ||
142 | static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd) | 142 | static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd) |
143 | { | 143 | { |
144 | struct scsi_device *sdev = cmd->device; | ||
145 | |||
146 | if (cmd->request->rq_flags & RQF_DONTPREP) { | 144 | if (cmd->request->rq_flags & RQF_DONTPREP) { |
147 | cmd->request->rq_flags &= ~RQF_DONTPREP; | 145 | cmd->request->rq_flags &= ~RQF_DONTPREP; |
148 | scsi_mq_uninit_cmd(cmd); | 146 | scsi_mq_uninit_cmd(cmd); |
@@ -150,7 +148,6 @@ static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd) | |||
150 | WARN_ON_ONCE(true); | 148 | WARN_ON_ONCE(true); |
151 | } | 149 | } |
152 | blk_mq_requeue_request(cmd->request, true); | 150 | blk_mq_requeue_request(cmd->request, true); |
153 | put_device(&sdev->sdev_gendev); | ||
154 | } | 151 | } |
155 | 152 | ||
156 | /** | 153 | /** |
@@ -189,19 +186,7 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy) | |||
189 | */ | 186 | */ |
190 | cmd->result = 0; | 187 | cmd->result = 0; |
191 | 188 | ||
192 | /* | ||
193 | * Before a SCSI command is dispatched, | ||
194 | * get_device(&sdev->sdev_gendev) is called and the host, | ||
195 | * target and device busy counters are increased. Since | ||
196 | * requeuing a request causes these actions to be repeated and | ||
197 | * since scsi_device_unbusy() has already been called, | ||
198 | * put_device(&device->sdev_gendev) must still be called. Call | ||
199 | * put_device() after blk_mq_requeue_request() to avoid that | ||
200 | * removal of the SCSI device can start before requeueing has | ||
201 | * happened. | ||
202 | */ | ||
203 | blk_mq_requeue_request(cmd->request, true); | 189 | blk_mq_requeue_request(cmd->request, true); |
204 | put_device(&device->sdev_gendev); | ||
205 | } | 190 | } |
206 | 191 | ||
207 | /* | 192 | /* |
@@ -619,7 +604,6 @@ static bool scsi_end_request(struct request *req, blk_status_t error, | |||
619 | blk_mq_run_hw_queues(q, true); | 604 | blk_mq_run_hw_queues(q, true); |
620 | 605 | ||
621 | percpu_ref_put(&q->q_usage_counter); | 606 | percpu_ref_put(&q->q_usage_counter); |
622 | put_device(&sdev->sdev_gendev); | ||
623 | return false; | 607 | return false; |
624 | } | 608 | } |
625 | 609 | ||
@@ -1613,7 +1597,6 @@ static void scsi_mq_put_budget(struct blk_mq_hw_ctx *hctx) | |||
1613 | struct scsi_device *sdev = q->queuedata; | 1597 | struct scsi_device *sdev = q->queuedata; |
1614 | 1598 | ||
1615 | atomic_dec(&sdev->device_busy); | 1599 | atomic_dec(&sdev->device_busy); |
1616 | put_device(&sdev->sdev_gendev); | ||
1617 | } | 1600 | } |
1618 | 1601 | ||
1619 | static bool scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx) | 1602 | static bool scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx) |
@@ -1621,16 +1604,9 @@ static bool scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx) | |||
1621 | struct request_queue *q = hctx->queue; | 1604 | struct request_queue *q = hctx->queue; |
1622 | struct scsi_device *sdev = q->queuedata; | 1605 | struct scsi_device *sdev = q->queuedata; |
1623 | 1606 | ||
1624 | if (!get_device(&sdev->sdev_gendev)) | 1607 | if (scsi_dev_queue_ready(q, sdev)) |
1625 | goto out; | 1608 | return true; |
1626 | if (!scsi_dev_queue_ready(q, sdev)) | ||
1627 | goto out_put_device; | ||
1628 | |||
1629 | return true; | ||
1630 | 1609 | ||
1631 | out_put_device: | ||
1632 | put_device(&sdev->sdev_gendev); | ||
1633 | out: | ||
1634 | if (atomic_read(&sdev->device_busy) == 0 && !scsi_device_blocked(sdev)) | 1610 | if (atomic_read(&sdev->device_busy) == 0 && !scsi_device_blocked(sdev)) |
1635 | blk_mq_delay_run_hw_queue(hctx, SCSI_QUEUE_DELAY); | 1611 | blk_mq_delay_run_hw_queue(hctx, SCSI_QUEUE_DELAY); |
1636 | return false; | 1612 | return false; |
@@ -1770,7 +1746,7 @@ static int scsi_map_queues(struct blk_mq_tag_set *set) | |||
1770 | 1746 | ||
1771 | if (shost->hostt->map_queues) | 1747 | if (shost->hostt->map_queues) |
1772 | return shost->hostt->map_queues(shost); | 1748 | return shost->hostt->map_queues(shost); |
1773 | return blk_mq_map_queues(&set->map[0]); | 1749 | return blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT]); |
1774 | } | 1750 | } |
1775 | 1751 | ||
1776 | void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q) | 1752 | void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q) |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 53380e07b40e..058079f915f1 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -1129,7 +1129,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, | |||
1129 | * that no LUN is present, so don't add sdev in these cases. | 1129 | * that no LUN is present, so don't add sdev in these cases. |
1130 | * Two specific examples are: | 1130 | * Two specific examples are: |
1131 | * 1) NetApp targets: return PQ=1, PDT=0x1f | 1131 | * 1) NetApp targets: return PQ=1, PDT=0x1f |
1132 | * 2) USB UFI: returns PDT=0x1f, with the PQ bits being "reserved" | 1132 | * 2) IBM/2145 targets: return PQ=1, PDT=0 |
1133 | * 3) USB UFI: returns PDT=0x1f, with the PQ bits being "reserved" | ||
1133 | * in the UFI 1.0 spec (we cannot rely on reserved bits). | 1134 | * in the UFI 1.0 spec (we cannot rely on reserved bits). |
1134 | * | 1135 | * |
1135 | * References: | 1136 | * References: |
@@ -1143,8 +1144,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, | |||
1143 | * PDT=00h Direct-access device (floppy) | 1144 | * PDT=00h Direct-access device (floppy) |
1144 | * PDT=1Fh none (no FDD connected to the requested logical unit) | 1145 | * PDT=1Fh none (no FDD connected to the requested logical unit) |
1145 | */ | 1146 | */ |
1146 | if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) && | 1147 | if (((result[0] >> 5) == 1 || |
1147 | (result[0] & 0x1f) == 0x1f && | 1148 | (starget->pdt_1f_for_no_lun && (result[0] & 0x1f) == 0x1f)) && |
1148 | !scsi_is_wlun(lun)) { | 1149 | !scsi_is_wlun(lun)) { |
1149 | SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev, | 1150 | SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev, |
1150 | "scsi scan: peripheral device type" | 1151 | "scsi scan: peripheral device type" |
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index d7035270d274..d9e3cf3721f6 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -147,6 +147,7 @@ static const struct { | |||
147 | { FCH_EVT_PORT_OFFLINE, "port_offline" }, | 147 | { FCH_EVT_PORT_OFFLINE, "port_offline" }, |
148 | { FCH_EVT_PORT_FABRIC, "port_fabric" }, | 148 | { FCH_EVT_PORT_FABRIC, "port_fabric" }, |
149 | { FCH_EVT_LINK_UNKNOWN, "link_unknown" }, | 149 | { FCH_EVT_LINK_UNKNOWN, "link_unknown" }, |
150 | { FCH_EVT_LINK_FPIN, "link_FPIN" }, | ||
150 | { FCH_EVT_VENDOR_UNIQUE, "vendor_unique" }, | 151 | { FCH_EVT_VENDOR_UNIQUE, "vendor_unique" }, |
151 | }; | 152 | }; |
152 | fc_enum_name_search(host_event_code, fc_host_event_code, | 153 | fc_enum_name_search(host_event_code, fc_host_event_code, |
@@ -295,6 +296,9 @@ static const struct { | |||
295 | { FC_PORT_ROLE_FCP_INITIATOR, "FCP Initiator" }, | 296 | { FC_PORT_ROLE_FCP_INITIATOR, "FCP Initiator" }, |
296 | { FC_PORT_ROLE_IP_PORT, "IP Port" }, | 297 | { FC_PORT_ROLE_IP_PORT, "IP Port" }, |
297 | { FC_PORT_ROLE_FCP_DUMMY_INITIATOR, "FCP Dummy Initiator" }, | 298 | { FC_PORT_ROLE_FCP_DUMMY_INITIATOR, "FCP Dummy Initiator" }, |
299 | { FC_PORT_ROLE_NVME_INITIATOR, "NVMe Initiator" }, | ||
300 | { FC_PORT_ROLE_NVME_TARGET, "NVMe Target" }, | ||
301 | { FC_PORT_ROLE_NVME_DISCOVERY, "NVMe Discovery" }, | ||
298 | }; | 302 | }; |
299 | fc_bitfield_name_search(port_roles, fc_port_role_names) | 303 | fc_bitfield_name_search(port_roles, fc_port_role_names) |
300 | 304 | ||
@@ -523,20 +527,23 @@ fc_get_event_number(void) | |||
523 | } | 527 | } |
524 | EXPORT_SYMBOL(fc_get_event_number); | 528 | EXPORT_SYMBOL(fc_get_event_number); |
525 | 529 | ||
526 | |||
527 | /** | 530 | /** |
528 | * fc_host_post_event - called to post an even on an fc_host. | 531 | * fc_host_post_fc_event - routine to do the work of posting an event |
532 | * on an fc_host. | ||
529 | * @shost: host the event occurred on | 533 | * @shost: host the event occurred on |
530 | * @event_number: fc event number obtained from get_fc_event_number() | 534 | * @event_number: fc event number obtained from get_fc_event_number() |
531 | * @event_code: fc_host event being posted | 535 | * @event_code: fc_host event being posted |
532 | * @event_data: 32bits of data for the event being posted | 536 | * @data_len: amount, in bytes, of event data |
537 | * @data_buf: pointer to event data | ||
538 | * @vendor_id: value for Vendor id | ||
533 | * | 539 | * |
534 | * Notes: | 540 | * Notes: |
535 | * This routine assumes no locks are held on entry. | 541 | * This routine assumes no locks are held on entry. |
536 | */ | 542 | */ |
537 | void | 543 | void |
538 | fc_host_post_event(struct Scsi_Host *shost, u32 event_number, | 544 | fc_host_post_fc_event(struct Scsi_Host *shost, u32 event_number, |
539 | enum fc_host_event_code event_code, u32 event_data) | 545 | enum fc_host_event_code event_code, |
546 | u32 data_len, char *data_buf, u64 vendor_id) | ||
540 | { | 547 | { |
541 | struct sk_buff *skb; | 548 | struct sk_buff *skb; |
542 | struct nlmsghdr *nlh; | 549 | struct nlmsghdr *nlh; |
@@ -545,12 +552,15 @@ fc_host_post_event(struct Scsi_Host *shost, u32 event_number, | |||
545 | u32 len; | 552 | u32 len; |
546 | int err; | 553 | int err; |
547 | 554 | ||
555 | if (!data_buf || data_len < 4) | ||
556 | data_len = 0; | ||
557 | |||
548 | if (!scsi_nl_sock) { | 558 | if (!scsi_nl_sock) { |
549 | err = -ENOENT; | 559 | err = -ENOENT; |
550 | goto send_fail; | 560 | goto send_fail; |
551 | } | 561 | } |
552 | 562 | ||
553 | len = FC_NL_MSGALIGN(sizeof(*event)); | 563 | len = FC_NL_MSGALIGN(sizeof(*event) + data_len); |
554 | 564 | ||
555 | skb = nlmsg_new(len, GFP_KERNEL); | 565 | skb = nlmsg_new(len, GFP_KERNEL); |
556 | if (!skb) { | 566 | if (!skb) { |
@@ -568,12 +578,13 @@ fc_host_post_event(struct Scsi_Host *shost, u32 event_number, | |||
568 | INIT_SCSI_NL_HDR(&event->snlh, SCSI_NL_TRANSPORT_FC, | 578 | INIT_SCSI_NL_HDR(&event->snlh, SCSI_NL_TRANSPORT_FC, |
569 | FC_NL_ASYNC_EVENT, len); | 579 | FC_NL_ASYNC_EVENT, len); |
570 | event->seconds = ktime_get_real_seconds(); | 580 | event->seconds = ktime_get_real_seconds(); |
571 | event->vendor_id = 0; | 581 | event->vendor_id = vendor_id; |
572 | event->host_no = shost->host_no; | 582 | event->host_no = shost->host_no; |
573 | event->event_datalen = sizeof(u32); /* bytes */ | 583 | event->event_datalen = data_len; /* bytes */ |
574 | event->event_num = event_number; | 584 | event->event_num = event_number; |
575 | event->event_code = event_code; | 585 | event->event_code = event_code; |
576 | event->event_data = event_data; | 586 | if (data_len) |
587 | memcpy(&event->event_data, data_buf, data_len); | ||
577 | 588 | ||
578 | nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS, | 589 | nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS, |
579 | GFP_KERNEL); | 590 | GFP_KERNEL); |
@@ -586,14 +597,35 @@ send_fail: | |||
586 | printk(KERN_WARNING | 597 | printk(KERN_WARNING |
587 | "%s: Dropped Event : host %d %s data 0x%08x - err %d\n", | 598 | "%s: Dropped Event : host %d %s data 0x%08x - err %d\n", |
588 | __func__, shost->host_no, | 599 | __func__, shost->host_no, |
589 | (name) ? name : "<unknown>", event_data, err); | 600 | (name) ? name : "<unknown>", |
601 | (data_len) ? *((u32 *)data_buf) : 0xFFFFFFFF, err); | ||
590 | return; | 602 | return; |
591 | } | 603 | } |
604 | EXPORT_SYMBOL(fc_host_post_fc_event); | ||
605 | |||
606 | /** | ||
607 | * fc_host_post_event - called to post an even on an fc_host. | ||
608 | * @shost: host the event occurred on | ||
609 | * @event_number: fc event number obtained from get_fc_event_number() | ||
610 | * @event_code: fc_host event being posted | ||
611 | * @event_data: 32bits of data for the event being posted | ||
612 | * | ||
613 | * Notes: | ||
614 | * This routine assumes no locks are held on entry. | ||
615 | */ | ||
616 | void | ||
617 | fc_host_post_event(struct Scsi_Host *shost, u32 event_number, | ||
618 | enum fc_host_event_code event_code, u32 event_data) | ||
619 | { | ||
620 | fc_host_post_fc_event(shost, event_number, event_code, | ||
621 | (u32)sizeof(u32), (char *)&event_data, 0); | ||
622 | } | ||
592 | EXPORT_SYMBOL(fc_host_post_event); | 623 | EXPORT_SYMBOL(fc_host_post_event); |
593 | 624 | ||
594 | 625 | ||
595 | /** | 626 | /** |
596 | * fc_host_post_vendor_event - called to post a vendor unique event on an fc_host | 627 | * fc_host_post_vendor_event - called to post a vendor unique event |
628 | * on an fc_host | ||
597 | * @shost: host the event occurred on | 629 | * @shost: host the event occurred on |
598 | * @event_number: fc event number obtained from get_fc_event_number() | 630 | * @event_number: fc event number obtained from get_fc_event_number() |
599 | * @data_len: amount, in bytes, of vendor unique data | 631 | * @data_len: amount, in bytes, of vendor unique data |
@@ -607,56 +639,27 @@ void | |||
607 | fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number, | 639 | fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number, |
608 | u32 data_len, char * data_buf, u64 vendor_id) | 640 | u32 data_len, char * data_buf, u64 vendor_id) |
609 | { | 641 | { |
610 | struct sk_buff *skb; | 642 | fc_host_post_fc_event(shost, event_number, FCH_EVT_VENDOR_UNIQUE, |
611 | struct nlmsghdr *nlh; | 643 | data_len, data_buf, vendor_id); |
612 | struct fc_nl_event *event; | ||
613 | u32 len; | ||
614 | int err; | ||
615 | |||
616 | if (!scsi_nl_sock) { | ||
617 | err = -ENOENT; | ||
618 | goto send_vendor_fail; | ||
619 | } | ||
620 | |||
621 | len = FC_NL_MSGALIGN(sizeof(*event) + data_len); | ||
622 | |||
623 | skb = nlmsg_new(len, GFP_KERNEL); | ||
624 | if (!skb) { | ||
625 | err = -ENOBUFS; | ||
626 | goto send_vendor_fail; | ||
627 | } | ||
628 | |||
629 | nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG, len, 0); | ||
630 | if (!nlh) { | ||
631 | err = -ENOBUFS; | ||
632 | goto send_vendor_fail_skb; | ||
633 | } | ||
634 | event = nlmsg_data(nlh); | ||
635 | |||
636 | INIT_SCSI_NL_HDR(&event->snlh, SCSI_NL_TRANSPORT_FC, | ||
637 | FC_NL_ASYNC_EVENT, len); | ||
638 | event->seconds = ktime_get_real_seconds(); | ||
639 | event->vendor_id = vendor_id; | ||
640 | event->host_no = shost->host_no; | ||
641 | event->event_datalen = data_len; /* bytes */ | ||
642 | event->event_num = event_number; | ||
643 | event->event_code = FCH_EVT_VENDOR_UNIQUE; | ||
644 | memcpy(&event->event_data, data_buf, data_len); | ||
645 | |||
646 | nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS, | ||
647 | GFP_KERNEL); | ||
648 | return; | ||
649 | |||
650 | send_vendor_fail_skb: | ||
651 | kfree_skb(skb); | ||
652 | send_vendor_fail: | ||
653 | printk(KERN_WARNING | ||
654 | "%s: Dropped Event : host %d vendor_unique - err %d\n", | ||
655 | __func__, shost->host_no, err); | ||
656 | return; | ||
657 | } | 644 | } |
658 | EXPORT_SYMBOL(fc_host_post_vendor_event); | 645 | EXPORT_SYMBOL(fc_host_post_vendor_event); |
659 | 646 | ||
647 | /** | ||
648 | * fc_host_rcv_fpin - routine to process a received FPIN. | ||
649 | * @shost: host the FPIN was received on | ||
650 | * @fpin_len: length of FPIN payload, in bytes | ||
651 | * @fpin_buf: pointer to FPIN payload | ||
652 | * | ||
653 | * Notes: | ||
654 | * This routine assumes no locks are held on entry. | ||
655 | */ | ||
656 | void | ||
657 | fc_host_fpin_rcv(struct Scsi_Host *shost, u32 fpin_len, char *fpin_buf) | ||
658 | { | ||
659 | fc_host_post_fc_event(shost, fc_get_event_number(), | ||
660 | FCH_EVT_LINK_FPIN, fpin_len, fpin_buf, 0); | ||
661 | } | ||
662 | EXPORT_SYMBOL(fc_host_fpin_rcv); | ||
660 | 663 | ||
661 | 664 | ||
662 | static __init int fc_transport_init(void) | 665 | static __init int fc_transport_init(void) |
diff --git a/drivers/scsi/smartpqi/Makefile b/drivers/scsi/smartpqi/Makefile index a03a6edb0060..28985e508b5c 100644 --- a/drivers/scsi/smartpqi/Makefile +++ b/drivers/scsi/smartpqi/Makefile | |||
@@ -1,2 +1,3 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
1 | obj-$(CONFIG_SCSI_SMARTPQI) += smartpqi.o | 2 | obj-$(CONFIG_SCSI_SMARTPQI) += smartpqi.o |
2 | smartpqi-objs := smartpqi_init.o smartpqi_sis.o smartpqi_sas_transport.o | 3 | smartpqi-objs := smartpqi_init.o smartpqi_sis.o smartpqi_sas_transport.o |
diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index af962368818b..e8e768849c70 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h | |||
@@ -1,18 +1,11 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
1 | /* | 2 | /* |
2 | * driver for Microsemi PQI-based storage controllers | 3 | * driver for Microsemi PQI-based storage controllers |
3 | * Copyright (c) 2016-2017 Microsemi Corporation | 4 | * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries |
5 | * Copyright (c) 2016-2018 Microsemi Corporation | ||
4 | * Copyright (c) 2016 PMC-Sierra, Inc. | 6 | * Copyright (c) 2016 PMC-Sierra, Inc. |
5 | * | 7 | * |
6 | * This program is free software; you can redistribute it and/or modify | 8 | * Questions/Comments/Bugfixes to storagedev@microchip.com |
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
13 | * NON INFRINGEMENT. See the GNU General Public License for more details. | ||
14 | * | ||
15 | * Questions/Comments/Bugfixes to esc.storagedev@microsemi.com | ||
16 | * | 9 | * |
17 | */ | 10 | */ |
18 | 11 | ||
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 75ec43aa8df3..c26cac819f9e 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c | |||
@@ -1,18 +1,11 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * driver for Microsemi PQI-based storage controllers | 3 | * driver for Microsemi PQI-based storage controllers |
3 | * Copyright (c) 2016-2017 Microsemi Corporation | 4 | * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries |
5 | * Copyright (c) 2016-2018 Microsemi Corporation | ||
4 | * Copyright (c) 2016 PMC-Sierra, Inc. | 6 | * Copyright (c) 2016 PMC-Sierra, Inc. |
5 | * | 7 | * |
6 | * This program is free software; you can redistribute it and/or modify | 8 | * Questions/Comments/Bugfixes to storagedev@microchip.com |
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
13 | * NON INFRINGEMENT. See the GNU General Public License for more details. | ||
14 | * | ||
15 | * Questions/Comments/Bugfixes to esc.storagedev@microsemi.com | ||
16 | * | 9 | * |
17 | */ | 10 | */ |
18 | 11 | ||
@@ -40,11 +33,11 @@ | |||
40 | #define BUILD_TIMESTAMP | 33 | #define BUILD_TIMESTAMP |
41 | #endif | 34 | #endif |
42 | 35 | ||
43 | #define DRIVER_VERSION "1.2.4-070" | 36 | #define DRIVER_VERSION "1.2.6-015" |
44 | #define DRIVER_MAJOR 1 | 37 | #define DRIVER_MAJOR 1 |
45 | #define DRIVER_MINOR 2 | 38 | #define DRIVER_MINOR 2 |
46 | #define DRIVER_RELEASE 4 | 39 | #define DRIVER_RELEASE 6 |
47 | #define DRIVER_REVISION 70 | 40 | #define DRIVER_REVISION 15 |
48 | 41 | ||
49 | #define DRIVER_NAME "Microsemi PQI Driver (v" \ | 42 | #define DRIVER_NAME "Microsemi PQI Driver (v" \ |
50 | DRIVER_VERSION BUILD_TIMESTAMP ")" | 43 | DRIVER_VERSION BUILD_TIMESTAMP ")" |
@@ -5660,9 +5653,11 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, | |||
5660 | return rc; | 5653 | return rc; |
5661 | } | 5654 | } |
5662 | 5655 | ||
5656 | /* Performs a reset at the LUN level. */ | ||
5657 | |||
5663 | #define PQI_LUN_RESET_RETRIES 3 | 5658 | #define PQI_LUN_RESET_RETRIES 3 |
5664 | #define PQI_LUN_RESET_RETRY_INTERVAL_MSECS 10000 | 5659 | #define PQI_LUN_RESET_RETRY_INTERVAL_MSECS 10000 |
5665 | /* Performs a reset at the LUN level. */ | 5660 | #define PQI_LUN_RESET_PENDING_IO_TIMEOUT_SECS 120 |
5666 | 5661 | ||
5667 | static int _pqi_device_reset(struct pqi_ctrl_info *ctrl_info, | 5662 | static int _pqi_device_reset(struct pqi_ctrl_info *ctrl_info, |
5668 | struct pqi_scsi_dev *device) | 5663 | struct pqi_scsi_dev *device) |
@@ -5673,12 +5668,12 @@ static int _pqi_device_reset(struct pqi_ctrl_info *ctrl_info, | |||
5673 | 5668 | ||
5674 | for (retries = 0;;) { | 5669 | for (retries = 0;;) { |
5675 | rc = pqi_lun_reset(ctrl_info, device); | 5670 | rc = pqi_lun_reset(ctrl_info, device); |
5676 | if (rc != -EAGAIN || | 5671 | if (rc != -EAGAIN || ++retries > PQI_LUN_RESET_RETRIES) |
5677 | ++retries > PQI_LUN_RESET_RETRIES) | ||
5678 | break; | 5672 | break; |
5679 | msleep(PQI_LUN_RESET_RETRY_INTERVAL_MSECS); | 5673 | msleep(PQI_LUN_RESET_RETRY_INTERVAL_MSECS); |
5680 | } | 5674 | } |
5681 | timeout_secs = rc ? PQI_LUN_RESET_TIMEOUT_SECS : NO_TIMEOUT; | 5675 | |
5676 | timeout_secs = rc ? PQI_LUN_RESET_PENDING_IO_TIMEOUT_SECS : NO_TIMEOUT; | ||
5682 | 5677 | ||
5683 | rc |= pqi_device_wait_for_pending_io(ctrl_info, device, timeout_secs); | 5678 | rc |= pqi_device_wait_for_pending_io(ctrl_info, device, timeout_secs); |
5684 | 5679 | ||
@@ -5707,6 +5702,7 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info, | |||
5707 | pqi_device_reset_done(device); | 5702 | pqi_device_reset_done(device); |
5708 | 5703 | ||
5709 | mutex_unlock(&ctrl_info->lun_reset_mutex); | 5704 | mutex_unlock(&ctrl_info->lun_reset_mutex); |
5705 | |||
5710 | return rc; | 5706 | return rc; |
5711 | } | 5707 | } |
5712 | 5708 | ||
@@ -5737,6 +5733,7 @@ static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd) | |||
5737 | pqi_wait_until_ofa_finished(ctrl_info); | 5733 | pqi_wait_until_ofa_finished(ctrl_info); |
5738 | 5734 | ||
5739 | rc = pqi_device_reset(ctrl_info, device); | 5735 | rc = pqi_device_reset(ctrl_info, device); |
5736 | |||
5740 | out: | 5737 | out: |
5741 | dev_err(&ctrl_info->pci_dev->dev, | 5738 | dev_err(&ctrl_info->pci_dev->dev, |
5742 | "reset of scsi %d:%d:%d:%d: %s\n", | 5739 | "reset of scsi %d:%d:%d:%d: %s\n", |
@@ -5795,7 +5792,7 @@ static int pqi_map_queues(struct Scsi_Host *shost) | |||
5795 | { | 5792 | { |
5796 | struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); | 5793 | struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); |
5797 | 5794 | ||
5798 | return blk_mq_pci_map_queues(&shost->tag_set.map[0], | 5795 | return blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT], |
5799 | ctrl_info->pci_dev, 0); | 5796 | ctrl_info->pci_dev, 0); |
5800 | } | 5797 | } |
5801 | 5798 | ||
@@ -7948,6 +7945,22 @@ static const struct pci_device_id pqi_pci_id_table[] = { | |||
7948 | }, | 7945 | }, |
7949 | { | 7946 | { |
7950 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | 7947 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, |
7948 | 0x193d, 0x1104) | ||
7949 | }, | ||
7950 | { | ||
7951 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
7952 | 0x193d, 0x1105) | ||
7953 | }, | ||
7954 | { | ||
7955 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
7956 | 0x193d, 0x1106) | ||
7957 | }, | ||
7958 | { | ||
7959 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
7960 | 0x193d, 0x1107) | ||
7961 | }, | ||
7962 | { | ||
7963 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
7951 | 0x193d, 0x8460) | 7964 | 0x193d, 0x8460) |
7952 | }, | 7965 | }, |
7953 | { | 7966 | { |
diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c index 0e4ef215115f..5cca1b9ef1f1 100644 --- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c +++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c | |||
@@ -1,18 +1,11 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * driver for Microsemi PQI-based storage controllers | 3 | * driver for Microsemi PQI-based storage controllers |
3 | * Copyright (c) 2016-2017 Microsemi Corporation | 4 | * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries |
5 | * Copyright (c) 2016-2018 Microsemi Corporation | ||
4 | * Copyright (c) 2016 PMC-Sierra, Inc. | 6 | * Copyright (c) 2016 PMC-Sierra, Inc. |
5 | * | 7 | * |
6 | * This program is free software; you can redistribute it and/or modify | 8 | * Questions/Comments/Bugfixes to storagedev@microchip.com |
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
13 | * NON INFRINGEMENT. See the GNU General Public License for more details. | ||
14 | * | ||
15 | * Questions/Comments/Bugfixes to esc.storagedev@microsemi.com | ||
16 | * | 9 | * |
17 | */ | 10 | */ |
18 | 11 | ||
diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c index dcd11c6418cc..f0d6e88ba2c1 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.c +++ b/drivers/scsi/smartpqi/smartpqi_sis.c | |||
@@ -1,18 +1,11 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * driver for Microsemi PQI-based storage controllers | 3 | * driver for Microsemi PQI-based storage controllers |
3 | * Copyright (c) 2016-2017 Microsemi Corporation | 4 | * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries |
5 | * Copyright (c) 2016-2018 Microsemi Corporation | ||
4 | * Copyright (c) 2016 PMC-Sierra, Inc. | 6 | * Copyright (c) 2016 PMC-Sierra, Inc. |
5 | * | 7 | * |
6 | * This program is free software; you can redistribute it and/or modify | 8 | * Questions/Comments/Bugfixes to storagedev@microchip.com |
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
13 | * NON INFRINGEMENT. See the GNU General Public License for more details. | ||
14 | * | ||
15 | * Questions/Comments/Bugfixes to esc.storagedev@microsemi.com | ||
16 | * | 9 | * |
17 | */ | 10 | */ |
18 | 11 | ||
diff --git a/drivers/scsi/smartpqi/smartpqi_sis.h b/drivers/scsi/smartpqi/smartpqi_sis.h index d018cb9c3f82..86b0e484d921 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.h +++ b/drivers/scsi/smartpqi/smartpqi_sis.h | |||
@@ -1,18 +1,11 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
1 | /* | 2 | /* |
2 | * driver for Microsemi PQI-based storage controllers | 3 | * driver for Microsemi PQI-based storage controllers |
3 | * Copyright (c) 2016-2017 Microsemi Corporation | 4 | * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries |
5 | * Copyright (c) 2016-2018 Microsemi Corporation | ||
4 | * Copyright (c) 2016 PMC-Sierra, Inc. | 6 | * Copyright (c) 2016 PMC-Sierra, Inc. |
5 | * | 7 | * |
6 | * This program is free software; you can redistribute it and/or modify | 8 | * Questions/Comments/Bugfixes to storagedev@microchip.com |
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
13 | * NON INFRINGEMENT. See the GNU General Public License for more details. | ||
14 | * | ||
15 | * Questions/Comments/Bugfixes to esc.storagedev@microsemi.com | ||
16 | * | 9 | * |
17 | */ | 10 | */ |
18 | 11 | ||
diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index 179bda374544..0b845ab7c3bf 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig | |||
@@ -109,6 +109,20 @@ config SCSI_UFS_QCOM | |||
109 | Select this if you have UFS controller on QCOM chipset. | 109 | Select this if you have UFS controller on QCOM chipset. |
110 | If unsure, say N. | 110 | If unsure, say N. |
111 | 111 | ||
112 | config SCSI_UFS_MEDIATEK | ||
113 | tristate "Mediatek specific hooks to UFS controller platform driver" | ||
114 | depends on SCSI_UFSHCD_PLATFORM && ARCH_MEDIATEK | ||
115 | select PHY_MTK_UFS | ||
116 | help | ||
117 | This selects the Mediatek specific additions to UFSHCD platform driver. | ||
118 | UFS host on Mediatek needs some vendor specific configuration before | ||
119 | accessing the hardware which includes PHY configuration and vendor | ||
120 | specific registers. | ||
121 | |||
122 | Select this if you have UFS controller on Mediatek chipset. | ||
123 | |||
124 | If unsure, say N. | ||
125 | |||
112 | config SCSI_UFS_HISI | 126 | config SCSI_UFS_HISI |
113 | tristate "Hisilicon specific hooks to UFS controller platform driver" | 127 | tristate "Hisilicon specific hooks to UFS controller platform driver" |
114 | depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM | 128 | depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM |
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index a3bd70c3652c..2a9097939bcb 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile | |||
@@ -10,3 +10,4 @@ ufshcd-core-$(CONFIG_SCSI_UFS_BSG) += ufs_bsg.o | |||
10 | obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o | 10 | obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o |
11 | obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o | 11 | obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o |
12 | obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o | 12 | obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o |
13 | obj-$(CONFIG_SCSI_UFS_MEDIATEK) += ufs-mediatek.o | ||
diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/scsi/ufs/cdns-pltfrm.c index 4a37b4f57164..86dbb723f3ac 100644 --- a/drivers/scsi/ufs/cdns-pltfrm.c +++ b/drivers/scsi/ufs/cdns-pltfrm.c | |||
@@ -17,7 +17,8 @@ | |||
17 | 17 | ||
18 | #include "ufshcd-pltfrm.h" | 18 | #include "ufshcd-pltfrm.h" |
19 | 19 | ||
20 | #define CDNS_UFS_REG_HCLKDIV 0xFC | 20 | #define CDNS_UFS_REG_HCLKDIV 0xFC |
21 | #define CDNS_UFS_REG_PHY_XCFGD1 0x113C | ||
21 | 22 | ||
22 | /** | 23 | /** |
23 | * Sets HCLKDIV register value based on the core_clk | 24 | * Sets HCLKDIV register value based on the core_clk |
@@ -77,11 +78,66 @@ static int cdns_ufs_setup_clocks(struct ufs_hba *hba, bool on, | |||
77 | return cdns_ufs_set_hclkdiv(hba); | 78 | return cdns_ufs_set_hclkdiv(hba); |
78 | } | 79 | } |
79 | 80 | ||
80 | static struct ufs_hba_variant_ops cdns_pltfm_hba_vops = { | 81 | /** |
82 | * cdns_ufs_init - performs additional ufs initialization | ||
83 | * @hba: host controller instance | ||
84 | * | ||
85 | * Returns status of initialization | ||
86 | */ | ||
87 | static int cdns_ufs_init(struct ufs_hba *hba) | ||
88 | { | ||
89 | int status = 0; | ||
90 | |||
91 | if (hba->vops && hba->vops->phy_initialization) | ||
92 | status = hba->vops->phy_initialization(hba); | ||
93 | |||
94 | return status; | ||
95 | } | ||
96 | |||
97 | /** | ||
98 | * cdns_ufs_m31_16nm_phy_initialization - performs m31 phy initialization | ||
99 | * @hba: host controller instance | ||
100 | * | ||
101 | * Always returns 0 | ||
102 | */ | ||
103 | static int cdns_ufs_m31_16nm_phy_initialization(struct ufs_hba *hba) | ||
104 | { | ||
105 | u32 data; | ||
106 | |||
107 | /* Increase RX_Advanced_Min_ActivateTime_Capability */ | ||
108 | data = ufshcd_readl(hba, CDNS_UFS_REG_PHY_XCFGD1); | ||
109 | data |= BIT(24); | ||
110 | ufshcd_writel(hba, data, CDNS_UFS_REG_PHY_XCFGD1); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static const struct ufs_hba_variant_ops cdns_ufs_pltfm_hba_vops = { | ||
116 | .name = "cdns-ufs-pltfm", | ||
117 | .setup_clocks = cdns_ufs_setup_clocks, | ||
118 | }; | ||
119 | |||
120 | static const struct ufs_hba_variant_ops cdns_ufs_m31_16nm_pltfm_hba_vops = { | ||
81 | .name = "cdns-ufs-pltfm", | 121 | .name = "cdns-ufs-pltfm", |
122 | .init = cdns_ufs_init, | ||
82 | .setup_clocks = cdns_ufs_setup_clocks, | 123 | .setup_clocks = cdns_ufs_setup_clocks, |
124 | .phy_initialization = cdns_ufs_m31_16nm_phy_initialization, | ||
125 | }; | ||
126 | |||
127 | static const struct of_device_id cdns_ufs_of_match[] = { | ||
128 | { | ||
129 | .compatible = "cdns,ufshc", | ||
130 | .data = &cdns_ufs_pltfm_hba_vops, | ||
131 | }, | ||
132 | { | ||
133 | .compatible = "cdns,ufshc-m31-16nm", | ||
134 | .data = &cdns_ufs_m31_16nm_pltfm_hba_vops, | ||
135 | }, | ||
136 | { }, | ||
83 | }; | 137 | }; |
84 | 138 | ||
139 | MODULE_DEVICE_TABLE(of, cdns_ufs_of_match); | ||
140 | |||
85 | /** | 141 | /** |
86 | * cdns_ufs_pltfrm_probe - probe routine of the driver | 142 | * cdns_ufs_pltfrm_probe - probe routine of the driver |
87 | * @pdev: pointer to platform device handle | 143 | * @pdev: pointer to platform device handle |
@@ -91,10 +147,15 @@ static struct ufs_hba_variant_ops cdns_pltfm_hba_vops = { | |||
91 | static int cdns_ufs_pltfrm_probe(struct platform_device *pdev) | 147 | static int cdns_ufs_pltfrm_probe(struct platform_device *pdev) |
92 | { | 148 | { |
93 | int err; | 149 | int err; |
150 | const struct of_device_id *of_id; | ||
151 | struct ufs_hba_variant_ops *vops; | ||
94 | struct device *dev = &pdev->dev; | 152 | struct device *dev = &pdev->dev; |
95 | 153 | ||
154 | of_id = of_match_node(cdns_ufs_of_match, dev->of_node); | ||
155 | vops = (struct ufs_hba_variant_ops *)of_id->data; | ||
156 | |||
96 | /* Perform generic probe */ | 157 | /* Perform generic probe */ |
97 | err = ufshcd_pltfrm_init(pdev, &cdns_pltfm_hba_vops); | 158 | err = ufshcd_pltfrm_init(pdev, vops); |
98 | if (err) | 159 | if (err) |
99 | dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err); | 160 | dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err); |
100 | 161 | ||
@@ -115,13 +176,6 @@ static int cdns_ufs_pltfrm_remove(struct platform_device *pdev) | |||
115 | return 0; | 176 | return 0; |
116 | } | 177 | } |
117 | 178 | ||
118 | static const struct of_device_id cdns_ufs_of_match[] = { | ||
119 | { .compatible = "cdns,ufshc" }, | ||
120 | {}, | ||
121 | }; | ||
122 | |||
123 | MODULE_DEVICE_TABLE(of, cdns_ufs_of_match); | ||
124 | |||
125 | static const struct dev_pm_ops cdns_ufs_dev_pm_ops = { | 179 | static const struct dev_pm_ops cdns_ufs_dev_pm_ops = { |
126 | .suspend = ufshcd_pltfrm_suspend, | 180 | .suspend = ufshcd_pltfrm_suspend, |
127 | .resume = ufshcd_pltfrm_resume, | 181 | .resume = ufshcd_pltfrm_resume, |
diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c index 0e855b5afe82..7aed0a1a794e 100644 --- a/drivers/scsi/ufs/ufs-hisi.c +++ b/drivers/scsi/ufs/ufs-hisi.c | |||
@@ -293,108 +293,7 @@ static int ufs_hisi_link_startup_notify(struct ufs_hba *hba, | |||
293 | return err; | 293 | return err; |
294 | } | 294 | } |
295 | 295 | ||
296 | struct ufs_hisi_dev_params { | 296 | static void ufs_hisi_set_dev_cap(struct ufs_dev_params *hisi_param) |
297 | u32 pwm_rx_gear; /* pwm rx gear to work in */ | ||
298 | u32 pwm_tx_gear; /* pwm tx gear to work in */ | ||
299 | u32 hs_rx_gear; /* hs rx gear to work in */ | ||
300 | u32 hs_tx_gear; /* hs tx gear to work in */ | ||
301 | u32 rx_lanes; /* number of rx lanes */ | ||
302 | u32 tx_lanes; /* number of tx lanes */ | ||
303 | u32 rx_pwr_pwm; /* rx pwm working pwr */ | ||
304 | u32 tx_pwr_pwm; /* tx pwm working pwr */ | ||
305 | u32 rx_pwr_hs; /* rx hs working pwr */ | ||
306 | u32 tx_pwr_hs; /* tx hs working pwr */ | ||
307 | u32 hs_rate; /* rate A/B to work in HS */ | ||
308 | u32 desired_working_mode; | ||
309 | }; | ||
310 | |||
311 | static int ufs_hisi_get_pwr_dev_param( | ||
312 | struct ufs_hisi_dev_params *hisi_param, | ||
313 | struct ufs_pa_layer_attr *dev_max, | ||
314 | struct ufs_pa_layer_attr *agreed_pwr) | ||
315 | { | ||
316 | int min_hisi_gear; | ||
317 | int min_dev_gear; | ||
318 | bool is_dev_sup_hs = false; | ||
319 | bool is_hisi_max_hs = false; | ||
320 | |||
321 | if (dev_max->pwr_rx == FASTAUTO_MODE || dev_max->pwr_rx == FAST_MODE) | ||
322 | is_dev_sup_hs = true; | ||
323 | |||
324 | if (hisi_param->desired_working_mode == FAST) { | ||
325 | is_hisi_max_hs = true; | ||
326 | min_hisi_gear = min_t(u32, hisi_param->hs_rx_gear, | ||
327 | hisi_param->hs_tx_gear); | ||
328 | } else { | ||
329 | min_hisi_gear = min_t(u32, hisi_param->pwm_rx_gear, | ||
330 | hisi_param->pwm_tx_gear); | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | * device doesn't support HS but | ||
335 | * hisi_param->desired_working_mode is HS, | ||
336 | * thus device and hisi_param don't agree | ||
337 | */ | ||
338 | if (!is_dev_sup_hs && is_hisi_max_hs) { | ||
339 | pr_err("%s: device not support HS\n", __func__); | ||
340 | return -ENOTSUPP; | ||
341 | } else if (is_dev_sup_hs && is_hisi_max_hs) { | ||
342 | /* | ||
343 | * since device supports HS, it supports FAST_MODE. | ||
344 | * since hisi_param->desired_working_mode is also HS | ||
345 | * then final decision (FAST/FASTAUTO) is done according | ||
346 | * to hisi_params as it is the restricting factor | ||
347 | */ | ||
348 | agreed_pwr->pwr_rx = agreed_pwr->pwr_tx = | ||
349 | hisi_param->rx_pwr_hs; | ||
350 | } else { | ||
351 | /* | ||
352 | * here hisi_param->desired_working_mode is PWM. | ||
353 | * it doesn't matter whether device supports HS or PWM, | ||
354 | * in both cases hisi_param->desired_working_mode will | ||
355 | * determine the mode | ||
356 | */ | ||
357 | agreed_pwr->pwr_rx = agreed_pwr->pwr_tx = | ||
358 | hisi_param->rx_pwr_pwm; | ||
359 | } | ||
360 | |||
361 | /* | ||
362 | * we would like tx to work in the minimum number of lanes | ||
363 | * between device capability and vendor preferences. | ||
364 | * the same decision will be made for rx | ||
365 | */ | ||
366 | agreed_pwr->lane_tx = | ||
367 | min_t(u32, dev_max->lane_tx, hisi_param->tx_lanes); | ||
368 | agreed_pwr->lane_rx = | ||
369 | min_t(u32, dev_max->lane_rx, hisi_param->rx_lanes); | ||
370 | |||
371 | /* device maximum gear is the minimum between device rx and tx gears */ | ||
372 | min_dev_gear = min_t(u32, dev_max->gear_rx, dev_max->gear_tx); | ||
373 | |||
374 | /* | ||
375 | * if both device capabilities and vendor pre-defined preferences are | ||
376 | * both HS or both PWM then set the minimum gear to be the chosen | ||
377 | * working gear. | ||
378 | * if one is PWM and one is HS then the one that is PWM get to decide | ||
379 | * what is the gear, as it is the one that also decided previously what | ||
380 | * pwr the device will be configured to. | ||
381 | */ | ||
382 | if ((is_dev_sup_hs && is_hisi_max_hs) || | ||
383 | (!is_dev_sup_hs && !is_hisi_max_hs)) | ||
384 | agreed_pwr->gear_rx = agreed_pwr->gear_tx = | ||
385 | min_t(u32, min_dev_gear, min_hisi_gear); | ||
386 | else | ||
387 | agreed_pwr->gear_rx = agreed_pwr->gear_tx = min_hisi_gear; | ||
388 | |||
389 | agreed_pwr->hs_rate = hisi_param->hs_rate; | ||
390 | |||
391 | pr_info("ufs final power mode: gear = %d, lane = %d, pwr = %d, rate = %d\n", | ||
392 | agreed_pwr->gear_rx, agreed_pwr->lane_rx, agreed_pwr->pwr_rx, | ||
393 | agreed_pwr->hs_rate); | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | static void ufs_hisi_set_dev_cap(struct ufs_hisi_dev_params *hisi_param) | ||
398 | { | 297 | { |
399 | hisi_param->rx_lanes = UFS_HISI_LIMIT_NUM_LANES_RX; | 298 | hisi_param->rx_lanes = UFS_HISI_LIMIT_NUM_LANES_RX; |
400 | hisi_param->tx_lanes = UFS_HISI_LIMIT_NUM_LANES_TX; | 299 | hisi_param->tx_lanes = UFS_HISI_LIMIT_NUM_LANES_TX; |
@@ -477,7 +376,7 @@ static int ufs_hisi_pwr_change_notify(struct ufs_hba *hba, | |||
477 | struct ufs_pa_layer_attr *dev_max_params, | 376 | struct ufs_pa_layer_attr *dev_max_params, |
478 | struct ufs_pa_layer_attr *dev_req_params) | 377 | struct ufs_pa_layer_attr *dev_req_params) |
479 | { | 378 | { |
480 | struct ufs_hisi_dev_params ufs_hisi_cap; | 379 | struct ufs_dev_params ufs_hisi_cap; |
481 | int ret = 0; | 380 | int ret = 0; |
482 | 381 | ||
483 | if (!dev_req_params) { | 382 | if (!dev_req_params) { |
@@ -490,8 +389,8 @@ static int ufs_hisi_pwr_change_notify(struct ufs_hba *hba, | |||
490 | switch (status) { | 389 | switch (status) { |
491 | case PRE_CHANGE: | 390 | case PRE_CHANGE: |
492 | ufs_hisi_set_dev_cap(&ufs_hisi_cap); | 391 | ufs_hisi_set_dev_cap(&ufs_hisi_cap); |
493 | ret = ufs_hisi_get_pwr_dev_param( | 392 | ret = ufshcd_get_pwr_dev_param(&ufs_hisi_cap, |
494 | &ufs_hisi_cap, dev_max_params, dev_req_params); | 393 | dev_max_params, dev_req_params); |
495 | if (ret) { | 394 | if (ret) { |
496 | dev_err(hba->dev, | 395 | dev_err(hba->dev, |
497 | "%s: failed to determine capabilities\n", __func__); | 396 | "%s: failed to determine capabilities\n", __func__); |
@@ -587,6 +486,10 @@ static int ufs_hisi_init_common(struct ufs_hba *hba) | |||
587 | ufshcd_set_variant(hba, host); | 486 | ufshcd_set_variant(hba, host); |
588 | 487 | ||
589 | host->rst = devm_reset_control_get(dev, "rst"); | 488 | host->rst = devm_reset_control_get(dev, "rst"); |
489 | if (IS_ERR(host->rst)) { | ||
490 | dev_err(dev, "%s: failed to get reset control\n", __func__); | ||
491 | return PTR_ERR(host->rst); | ||
492 | } | ||
590 | 493 | ||
591 | ufs_hisi_set_pm_lvl(hba); | 494 | ufs_hisi_set_pm_lvl(hba); |
592 | 495 | ||
diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c new file mode 100644 index 000000000000..0f6ff33ce52e --- /dev/null +++ b/drivers/scsi/ufs/ufs-mediatek.c | |||
@@ -0,0 +1,368 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright (C) 2019 MediaTek Inc. | ||
4 | * Authors: | ||
5 | * Stanley Chu <stanley.chu@mediatek.com> | ||
6 | * Peter Wang <peter.wang@mediatek.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/of.h> | ||
10 | #include <linux/of_address.h> | ||
11 | #include <linux/phy/phy.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | |||
14 | #include "ufshcd.h" | ||
15 | #include "ufshcd-pltfrm.h" | ||
16 | #include "unipro.h" | ||
17 | #include "ufs-mediatek.h" | ||
18 | |||
19 | static void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable) | ||
20 | { | ||
21 | u32 tmp; | ||
22 | |||
23 | if (enable) { | ||
24 | ufshcd_dme_get(hba, | ||
25 | UIC_ARG_MIB(VS_SAVEPOWERCONTROL), &tmp); | ||
26 | tmp = tmp | | ||
27 | (1 << RX_SYMBOL_CLK_GATE_EN) | | ||
28 | (1 << SYS_CLK_GATE_EN) | | ||
29 | (1 << TX_CLK_GATE_EN); | ||
30 | ufshcd_dme_set(hba, | ||
31 | UIC_ARG_MIB(VS_SAVEPOWERCONTROL), tmp); | ||
32 | |||
33 | ufshcd_dme_get(hba, | ||
34 | UIC_ARG_MIB(VS_DEBUGCLOCKENABLE), &tmp); | ||
35 | tmp = tmp & ~(1 << TX_SYMBOL_CLK_REQ_FORCE); | ||
36 | ufshcd_dme_set(hba, | ||
37 | UIC_ARG_MIB(VS_DEBUGCLOCKENABLE), tmp); | ||
38 | } else { | ||
39 | ufshcd_dme_get(hba, | ||
40 | UIC_ARG_MIB(VS_SAVEPOWERCONTROL), &tmp); | ||
41 | tmp = tmp & ~((1 << RX_SYMBOL_CLK_GATE_EN) | | ||
42 | (1 << SYS_CLK_GATE_EN) | | ||
43 | (1 << TX_CLK_GATE_EN)); | ||
44 | ufshcd_dme_set(hba, | ||
45 | UIC_ARG_MIB(VS_SAVEPOWERCONTROL), tmp); | ||
46 | |||
47 | ufshcd_dme_get(hba, | ||
48 | UIC_ARG_MIB(VS_DEBUGCLOCKENABLE), &tmp); | ||
49 | tmp = tmp | (1 << TX_SYMBOL_CLK_REQ_FORCE); | ||
50 | ufshcd_dme_set(hba, | ||
51 | UIC_ARG_MIB(VS_DEBUGCLOCKENABLE), tmp); | ||
52 | } | ||
53 | } | ||
54 | |||
55 | static int ufs_mtk_bind_mphy(struct ufs_hba *hba) | ||
56 | { | ||
57 | struct ufs_mtk_host *host = ufshcd_get_variant(hba); | ||
58 | struct device *dev = hba->dev; | ||
59 | struct device_node *np = dev->of_node; | ||
60 | int err = 0; | ||
61 | |||
62 | host->mphy = devm_of_phy_get_by_index(dev, np, 0); | ||
63 | |||
64 | if (host->mphy == ERR_PTR(-EPROBE_DEFER)) { | ||
65 | /* | ||
66 | * UFS driver might be probed before the phy driver does. | ||
67 | * In that case we would like to return EPROBE_DEFER code. | ||
68 | */ | ||
69 | err = -EPROBE_DEFER; | ||
70 | dev_info(dev, | ||
71 | "%s: required phy hasn't probed yet. err = %d\n", | ||
72 | __func__, err); | ||
73 | } else if (IS_ERR(host->mphy)) { | ||
74 | err = PTR_ERR(host->mphy); | ||
75 | dev_info(dev, "%s: PHY get failed %d\n", __func__, err); | ||
76 | } | ||
77 | |||
78 | if (err) | ||
79 | host->mphy = NULL; | ||
80 | |||
81 | return err; | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * ufs_mtk_setup_clocks - enables/disable clocks | ||
86 | * @hba: host controller instance | ||
87 | * @on: If true, enable clocks else disable them. | ||
88 | * @status: PRE_CHANGE or POST_CHANGE notify | ||
89 | * | ||
90 | * Returns 0 on success, non-zero on failure. | ||
91 | */ | ||
92 | static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on, | ||
93 | enum ufs_notify_change_status status) | ||
94 | { | ||
95 | struct ufs_mtk_host *host = ufshcd_get_variant(hba); | ||
96 | int ret = -EINVAL; | ||
97 | |||
98 | /* | ||
99 | * In case ufs_mtk_init() is not yet done, simply ignore. | ||
100 | * This ufs_mtk_setup_clocks() shall be called from | ||
101 | * ufs_mtk_init() after init is done. | ||
102 | */ | ||
103 | if (!host) | ||
104 | return 0; | ||
105 | |||
106 | switch (status) { | ||
107 | case PRE_CHANGE: | ||
108 | if (!on) | ||
109 | ret = phy_power_off(host->mphy); | ||
110 | break; | ||
111 | case POST_CHANGE: | ||
112 | if (on) | ||
113 | ret = phy_power_on(host->mphy); | ||
114 | break; | ||
115 | } | ||
116 | |||
117 | return ret; | ||
118 | } | ||
119 | |||
120 | /** | ||
121 | * ufs_mtk_init - find other essential mmio bases | ||
122 | * @hba: host controller instance | ||
123 | * | ||
124 | * Binds PHY with controller and powers up PHY enabling clocks | ||
125 | * and regulators. | ||
126 | * | ||
127 | * Returns -EPROBE_DEFER if binding fails, returns negative error | ||
128 | * on phy power up failure and returns zero on success. | ||
129 | */ | ||
130 | static int ufs_mtk_init(struct ufs_hba *hba) | ||
131 | { | ||
132 | struct ufs_mtk_host *host; | ||
133 | struct device *dev = hba->dev; | ||
134 | int err = 0; | ||
135 | |||
136 | host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); | ||
137 | if (!host) { | ||
138 | err = -ENOMEM; | ||
139 | dev_info(dev, "%s: no memory for mtk ufs host\n", __func__); | ||
140 | goto out; | ||
141 | } | ||
142 | |||
143 | host->hba = hba; | ||
144 | ufshcd_set_variant(hba, host); | ||
145 | |||
146 | err = ufs_mtk_bind_mphy(hba); | ||
147 | if (err) | ||
148 | goto out_variant_clear; | ||
149 | |||
150 | /* | ||
151 | * ufshcd_vops_init() is invoked after | ||
152 | * ufshcd_setup_clock(true) in ufshcd_hba_init() thus | ||
153 | * phy clock setup is skipped. | ||
154 | * | ||
155 | * Enable phy clocks specifically here. | ||
156 | */ | ||
157 | ufs_mtk_setup_clocks(hba, true, POST_CHANGE); | ||
158 | |||
159 | goto out; | ||
160 | |||
161 | out_variant_clear: | ||
162 | ufshcd_set_variant(hba, NULL); | ||
163 | out: | ||
164 | return err; | ||
165 | } | ||
166 | |||
167 | static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba, | ||
168 | struct ufs_pa_layer_attr *dev_max_params, | ||
169 | struct ufs_pa_layer_attr *dev_req_params) | ||
170 | { | ||
171 | struct ufs_dev_params host_cap; | ||
172 | int ret; | ||
173 | |||
174 | host_cap.tx_lanes = UFS_MTK_LIMIT_NUM_LANES_TX; | ||
175 | host_cap.rx_lanes = UFS_MTK_LIMIT_NUM_LANES_RX; | ||
176 | host_cap.hs_rx_gear = UFS_MTK_LIMIT_HSGEAR_RX; | ||
177 | host_cap.hs_tx_gear = UFS_MTK_LIMIT_HSGEAR_TX; | ||
178 | host_cap.pwm_rx_gear = UFS_MTK_LIMIT_PWMGEAR_RX; | ||
179 | host_cap.pwm_tx_gear = UFS_MTK_LIMIT_PWMGEAR_TX; | ||
180 | host_cap.rx_pwr_pwm = UFS_MTK_LIMIT_RX_PWR_PWM; | ||
181 | host_cap.tx_pwr_pwm = UFS_MTK_LIMIT_TX_PWR_PWM; | ||
182 | host_cap.rx_pwr_hs = UFS_MTK_LIMIT_RX_PWR_HS; | ||
183 | host_cap.tx_pwr_hs = UFS_MTK_LIMIT_TX_PWR_HS; | ||
184 | host_cap.hs_rate = UFS_MTK_LIMIT_HS_RATE; | ||
185 | host_cap.desired_working_mode = | ||
186 | UFS_MTK_LIMIT_DESIRED_MODE; | ||
187 | |||
188 | ret = ufshcd_get_pwr_dev_param(&host_cap, | ||
189 | dev_max_params, | ||
190 | dev_req_params); | ||
191 | if (ret) { | ||
192 | pr_info("%s: failed to determine capabilities\n", | ||
193 | __func__); | ||
194 | } | ||
195 | |||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | static int ufs_mtk_pwr_change_notify(struct ufs_hba *hba, | ||
200 | enum ufs_notify_change_status stage, | ||
201 | struct ufs_pa_layer_attr *dev_max_params, | ||
202 | struct ufs_pa_layer_attr *dev_req_params) | ||
203 | { | ||
204 | int ret = 0; | ||
205 | |||
206 | switch (stage) { | ||
207 | case PRE_CHANGE: | ||
208 | ret = ufs_mtk_pre_pwr_change(hba, dev_max_params, | ||
209 | dev_req_params); | ||
210 | break; | ||
211 | case POST_CHANGE: | ||
212 | break; | ||
213 | default: | ||
214 | ret = -EINVAL; | ||
215 | break; | ||
216 | } | ||
217 | |||
218 | return ret; | ||
219 | } | ||
220 | |||
221 | static int ufs_mtk_pre_link(struct ufs_hba *hba) | ||
222 | { | ||
223 | int ret; | ||
224 | u32 tmp; | ||
225 | |||
226 | /* disable deep stall */ | ||
227 | ret = ufshcd_dme_get(hba, UIC_ARG_MIB(VS_SAVEPOWERCONTROL), &tmp); | ||
228 | if (ret) | ||
229 | return ret; | ||
230 | |||
231 | tmp &= ~(1 << 6); | ||
232 | |||
233 | ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_SAVEPOWERCONTROL), tmp); | ||
234 | |||
235 | return ret; | ||
236 | } | ||
237 | |||
238 | static int ufs_mtk_post_link(struct ufs_hba *hba) | ||
239 | { | ||
240 | /* disable device LCC */ | ||
241 | ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0); | ||
242 | |||
243 | /* enable unipro clock gating feature */ | ||
244 | ufs_mtk_cfg_unipro_cg(hba, true); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static int ufs_mtk_link_startup_notify(struct ufs_hba *hba, | ||
250 | enum ufs_notify_change_status stage) | ||
251 | { | ||
252 | int ret = 0; | ||
253 | |||
254 | switch (stage) { | ||
255 | case PRE_CHANGE: | ||
256 | ret = ufs_mtk_pre_link(hba); | ||
257 | break; | ||
258 | case POST_CHANGE: | ||
259 | ret = ufs_mtk_post_link(hba); | ||
260 | break; | ||
261 | default: | ||
262 | ret = -EINVAL; | ||
263 | break; | ||
264 | } | ||
265 | |||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | static int ufs_mtk_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) | ||
270 | { | ||
271 | struct ufs_mtk_host *host = ufshcd_get_variant(hba); | ||
272 | |||
273 | if (ufshcd_is_link_hibern8(hba)) | ||
274 | phy_power_off(host->mphy); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static int ufs_mtk_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) | ||
280 | { | ||
281 | struct ufs_mtk_host *host = ufshcd_get_variant(hba); | ||
282 | |||
283 | if (ufshcd_is_link_hibern8(hba)) | ||
284 | phy_power_on(host->mphy); | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | /** | ||
290 | * struct ufs_hba_mtk_vops - UFS MTK specific variant operations | ||
291 | * | ||
292 | * The variant operations configure the necessary controller and PHY | ||
293 | * handshake during initialization. | ||
294 | */ | ||
295 | static struct ufs_hba_variant_ops ufs_hba_mtk_vops = { | ||
296 | .name = "mediatek.ufshci", | ||
297 | .init = ufs_mtk_init, | ||
298 | .setup_clocks = ufs_mtk_setup_clocks, | ||
299 | .link_startup_notify = ufs_mtk_link_startup_notify, | ||
300 | .pwr_change_notify = ufs_mtk_pwr_change_notify, | ||
301 | .suspend = ufs_mtk_suspend, | ||
302 | .resume = ufs_mtk_resume, | ||
303 | }; | ||
304 | |||
305 | /** | ||
306 | * ufs_mtk_probe - probe routine of the driver | ||
307 | * @pdev: pointer to Platform device handle | ||
308 | * | ||
309 | * Return zero for success and non-zero for failure | ||
310 | */ | ||
311 | static int ufs_mtk_probe(struct platform_device *pdev) | ||
312 | { | ||
313 | int err; | ||
314 | struct device *dev = &pdev->dev; | ||
315 | |||
316 | /* perform generic probe */ | ||
317 | err = ufshcd_pltfrm_init(pdev, &ufs_hba_mtk_vops); | ||
318 | if (err) | ||
319 | dev_info(dev, "probe failed %d\n", err); | ||
320 | |||
321 | return err; | ||
322 | } | ||
323 | |||
324 | /** | ||
325 | * ufs_mtk_remove - set driver_data of the device to NULL | ||
326 | * @pdev: pointer to platform device handle | ||
327 | * | ||
328 | * Always return 0 | ||
329 | */ | ||
330 | static int ufs_mtk_remove(struct platform_device *pdev) | ||
331 | { | ||
332 | struct ufs_hba *hba = platform_get_drvdata(pdev); | ||
333 | |||
334 | pm_runtime_get_sync(&(pdev)->dev); | ||
335 | ufshcd_remove(hba); | ||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static const struct of_device_id ufs_mtk_of_match[] = { | ||
340 | { .compatible = "mediatek,mt8183-ufshci"}, | ||
341 | {}, | ||
342 | }; | ||
343 | |||
344 | static const struct dev_pm_ops ufs_mtk_pm_ops = { | ||
345 | .suspend = ufshcd_pltfrm_suspend, | ||
346 | .resume = ufshcd_pltfrm_resume, | ||
347 | .runtime_suspend = ufshcd_pltfrm_runtime_suspend, | ||
348 | .runtime_resume = ufshcd_pltfrm_runtime_resume, | ||
349 | .runtime_idle = ufshcd_pltfrm_runtime_idle, | ||
350 | }; | ||
351 | |||
352 | static struct platform_driver ufs_mtk_pltform = { | ||
353 | .probe = ufs_mtk_probe, | ||
354 | .remove = ufs_mtk_remove, | ||
355 | .shutdown = ufshcd_pltfrm_shutdown, | ||
356 | .driver = { | ||
357 | .name = "ufshcd-mtk", | ||
358 | .pm = &ufs_mtk_pm_ops, | ||
359 | .of_match_table = ufs_mtk_of_match, | ||
360 | }, | ||
361 | }; | ||
362 | |||
363 | MODULE_AUTHOR("Stanley Chu <stanley.chu@mediatek.com>"); | ||
364 | MODULE_AUTHOR("Peter Wang <peter.wang@mediatek.com>"); | ||
365 | MODULE_DESCRIPTION("MediaTek UFS Host Driver"); | ||
366 | MODULE_LICENSE("GPL v2"); | ||
367 | |||
368 | module_platform_driver(ufs_mtk_pltform); | ||
diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h new file mode 100644 index 000000000000..19f8c42fe06f --- /dev/null +++ b/drivers/scsi/ufs/ufs-mediatek.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Copyright (C) 2019 MediaTek Inc. | ||
4 | */ | ||
5 | |||
6 | #ifndef _UFS_MEDIATEK_H | ||
7 | #define _UFS_MEDIATEK_H | ||
8 | |||
9 | /* | ||
10 | * Vendor specific pre-defined parameters | ||
11 | */ | ||
12 | #define UFS_MTK_LIMIT_NUM_LANES_RX 1 | ||
13 | #define UFS_MTK_LIMIT_NUM_LANES_TX 1 | ||
14 | #define UFS_MTK_LIMIT_HSGEAR_RX UFS_HS_G3 | ||
15 | #define UFS_MTK_LIMIT_HSGEAR_TX UFS_HS_G3 | ||
16 | #define UFS_MTK_LIMIT_PWMGEAR_RX UFS_PWM_G4 | ||
17 | #define UFS_MTK_LIMIT_PWMGEAR_TX UFS_PWM_G4 | ||
18 | #define UFS_MTK_LIMIT_RX_PWR_PWM SLOW_MODE | ||
19 | #define UFS_MTK_LIMIT_TX_PWR_PWM SLOW_MODE | ||
20 | #define UFS_MTK_LIMIT_RX_PWR_HS FAST_MODE | ||
21 | #define UFS_MTK_LIMIT_TX_PWR_HS FAST_MODE | ||
22 | #define UFS_MTK_LIMIT_HS_RATE PA_HS_MODE_B | ||
23 | #define UFS_MTK_LIMIT_DESIRED_MODE UFS_HS_MODE | ||
24 | |||
25 | /* | ||
26 | * Other attributes | ||
27 | */ | ||
28 | #define VS_DEBUGCLOCKENABLE 0xD0A1 | ||
29 | #define VS_SAVEPOWERCONTROL 0xD0A6 | ||
30 | #define VS_UNIPROPOWERDOWNCONTROL 0xD0A8 | ||
31 | |||
32 | /* | ||
33 | * VS_DEBUGCLOCKENABLE | ||
34 | */ | ||
35 | enum { | ||
36 | TX_SYMBOL_CLK_REQ_FORCE = 5, | ||
37 | }; | ||
38 | |||
39 | /* | ||
40 | * VS_SAVEPOWERCONTROL | ||
41 | */ | ||
42 | enum { | ||
43 | RX_SYMBOL_CLK_GATE_EN = 0, | ||
44 | SYS_CLK_GATE_EN = 2, | ||
45 | TX_CLK_GATE_EN = 3, | ||
46 | }; | ||
47 | |||
48 | struct ufs_mtk_host { | ||
49 | struct ufs_hba *hba; | ||
50 | struct phy *mphy; | ||
51 | }; | ||
52 | |||
53 | #endif /* !_UFS_MEDIATEK_H */ | ||
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index de9d3f56b58c..ea7219407309 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c | |||
@@ -580,104 +580,6 @@ static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) | |||
580 | return 0; | 580 | return 0; |
581 | } | 581 | } |
582 | 582 | ||
583 | struct ufs_qcom_dev_params { | ||
584 | u32 pwm_rx_gear; /* pwm rx gear to work in */ | ||
585 | u32 pwm_tx_gear; /* pwm tx gear to work in */ | ||
586 | u32 hs_rx_gear; /* hs rx gear to work in */ | ||
587 | u32 hs_tx_gear; /* hs tx gear to work in */ | ||
588 | u32 rx_lanes; /* number of rx lanes */ | ||
589 | u32 tx_lanes; /* number of tx lanes */ | ||
590 | u32 rx_pwr_pwm; /* rx pwm working pwr */ | ||
591 | u32 tx_pwr_pwm; /* tx pwm working pwr */ | ||
592 | u32 rx_pwr_hs; /* rx hs working pwr */ | ||
593 | u32 tx_pwr_hs; /* tx hs working pwr */ | ||
594 | u32 hs_rate; /* rate A/B to work in HS */ | ||
595 | u32 desired_working_mode; | ||
596 | }; | ||
597 | |||
598 | static int ufs_qcom_get_pwr_dev_param(struct ufs_qcom_dev_params *qcom_param, | ||
599 | struct ufs_pa_layer_attr *dev_max, | ||
600 | struct ufs_pa_layer_attr *agreed_pwr) | ||
601 | { | ||
602 | int min_qcom_gear; | ||
603 | int min_dev_gear; | ||
604 | bool is_dev_sup_hs = false; | ||
605 | bool is_qcom_max_hs = false; | ||
606 | |||
607 | if (dev_max->pwr_rx == FAST_MODE) | ||
608 | is_dev_sup_hs = true; | ||
609 | |||
610 | if (qcom_param->desired_working_mode == FAST) { | ||
611 | is_qcom_max_hs = true; | ||
612 | min_qcom_gear = min_t(u32, qcom_param->hs_rx_gear, | ||
613 | qcom_param->hs_tx_gear); | ||
614 | } else { | ||
615 | min_qcom_gear = min_t(u32, qcom_param->pwm_rx_gear, | ||
616 | qcom_param->pwm_tx_gear); | ||
617 | } | ||
618 | |||
619 | /* | ||
620 | * device doesn't support HS but qcom_param->desired_working_mode is | ||
621 | * HS, thus device and qcom_param don't agree | ||
622 | */ | ||
623 | if (!is_dev_sup_hs && is_qcom_max_hs) { | ||
624 | pr_err("%s: failed to agree on power mode (device doesn't support HS but requested power is HS)\n", | ||
625 | __func__); | ||
626 | return -ENOTSUPP; | ||
627 | } else if (is_dev_sup_hs && is_qcom_max_hs) { | ||
628 | /* | ||
629 | * since device supports HS, it supports FAST_MODE. | ||
630 | * since qcom_param->desired_working_mode is also HS | ||
631 | * then final decision (FAST/FASTAUTO) is done according | ||
632 | * to qcom_params as it is the restricting factor | ||
633 | */ | ||
634 | agreed_pwr->pwr_rx = agreed_pwr->pwr_tx = | ||
635 | qcom_param->rx_pwr_hs; | ||
636 | } else { | ||
637 | /* | ||
638 | * here qcom_param->desired_working_mode is PWM. | ||
639 | * it doesn't matter whether device supports HS or PWM, | ||
640 | * in both cases qcom_param->desired_working_mode will | ||
641 | * determine the mode | ||
642 | */ | ||
643 | agreed_pwr->pwr_rx = agreed_pwr->pwr_tx = | ||
644 | qcom_param->rx_pwr_pwm; | ||
645 | } | ||
646 | |||
647 | /* | ||
648 | * we would like tx to work in the minimum number of lanes | ||
649 | * between device capability and vendor preferences. | ||
650 | * the same decision will be made for rx | ||
651 | */ | ||
652 | agreed_pwr->lane_tx = min_t(u32, dev_max->lane_tx, | ||
653 | qcom_param->tx_lanes); | ||
654 | agreed_pwr->lane_rx = min_t(u32, dev_max->lane_rx, | ||
655 | qcom_param->rx_lanes); | ||
656 | |||
657 | /* device maximum gear is the minimum between device rx and tx gears */ | ||
658 | min_dev_gear = min_t(u32, dev_max->gear_rx, dev_max->gear_tx); | ||
659 | |||
660 | /* | ||
661 | * if both device capabilities and vendor pre-defined preferences are | ||
662 | * both HS or both PWM then set the minimum gear to be the chosen | ||
663 | * working gear. | ||
664 | * if one is PWM and one is HS then the one that is PWM get to decide | ||
665 | * what is the gear, as it is the one that also decided previously what | ||
666 | * pwr the device will be configured to. | ||
667 | */ | ||
668 | if ((is_dev_sup_hs && is_qcom_max_hs) || | ||
669 | (!is_dev_sup_hs && !is_qcom_max_hs)) | ||
670 | agreed_pwr->gear_rx = agreed_pwr->gear_tx = | ||
671 | min_t(u32, min_dev_gear, min_qcom_gear); | ||
672 | else if (!is_dev_sup_hs) | ||
673 | agreed_pwr->gear_rx = agreed_pwr->gear_tx = min_dev_gear; | ||
674 | else | ||
675 | agreed_pwr->gear_rx = agreed_pwr->gear_tx = min_qcom_gear; | ||
676 | |||
677 | agreed_pwr->hs_rate = qcom_param->hs_rate; | ||
678 | return 0; | ||
679 | } | ||
680 | |||
681 | #ifdef CONFIG_MSM_BUS_SCALING | 583 | #ifdef CONFIG_MSM_BUS_SCALING |
682 | static int ufs_qcom_get_bus_vote(struct ufs_qcom_host *host, | 584 | static int ufs_qcom_get_bus_vote(struct ufs_qcom_host *host, |
683 | const char *speed_mode) | 585 | const char *speed_mode) |
@@ -905,7 +807,7 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba, | |||
905 | { | 807 | { |
906 | u32 val; | 808 | u32 val; |
907 | struct ufs_qcom_host *host = ufshcd_get_variant(hba); | 809 | struct ufs_qcom_host *host = ufshcd_get_variant(hba); |
908 | struct ufs_qcom_dev_params ufs_qcom_cap; | 810 | struct ufs_dev_params ufs_qcom_cap; |
909 | int ret = 0; | 811 | int ret = 0; |
910 | 812 | ||
911 | if (!dev_req_params) { | 813 | if (!dev_req_params) { |
@@ -944,9 +846,9 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba, | |||
944 | ufs_qcom_cap.hs_rx_gear = UFS_HS_G2; | 846 | ufs_qcom_cap.hs_rx_gear = UFS_HS_G2; |
945 | } | 847 | } |
946 | 848 | ||
947 | ret = ufs_qcom_get_pwr_dev_param(&ufs_qcom_cap, | 849 | ret = ufshcd_get_pwr_dev_param(&ufs_qcom_cap, |
948 | dev_max_params, | 850 | dev_max_params, |
949 | dev_req_params); | 851 | dev_req_params); |
950 | if (ret) { | 852 | if (ret) { |
951 | pr_err("%s: failed to determine capabilities\n", | 853 | pr_err("%s: failed to determine capabilities\n", |
952 | __func__); | 854 | __func__); |
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 21e4ccb5ba6e..99a9c4d16f6b 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h | |||
@@ -516,7 +516,6 @@ struct ufs_vreg { | |||
516 | bool enabled; | 516 | bool enabled; |
517 | int min_uV; | 517 | int min_uV; |
518 | int max_uV; | 518 | int max_uV; |
519 | int min_uA; | ||
520 | int max_uA; | 519 | int max_uA; |
521 | }; | 520 | }; |
522 | 521 | ||
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 27213676329c..8a74ec30c3d2 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c | |||
@@ -39,6 +39,7 @@ | |||
39 | 39 | ||
40 | #include "ufshcd.h" | 40 | #include "ufshcd.h" |
41 | #include "ufshcd-pltfrm.h" | 41 | #include "ufshcd-pltfrm.h" |
42 | #include "unipro.h" | ||
42 | 43 | ||
43 | #define UFSHCD_DEFAULT_LANES_PER_DIRECTION 2 | 44 | #define UFSHCD_DEFAULT_LANES_PER_DIRECTION 2 |
44 | 45 | ||
@@ -151,20 +152,12 @@ static int ufshcd_populate_vreg(struct device *dev, const char *name, | |||
151 | 152 | ||
152 | vreg->name = kstrdup(name, GFP_KERNEL); | 153 | vreg->name = kstrdup(name, GFP_KERNEL); |
153 | 154 | ||
154 | /* if fixed regulator no need further initialization */ | ||
155 | snprintf(prop_name, MAX_PROP_SIZE, "%s-fixed-regulator", name); | ||
156 | if (of_property_read_bool(np, prop_name)) | ||
157 | goto out; | ||
158 | |||
159 | snprintf(prop_name, MAX_PROP_SIZE, "%s-max-microamp", name); | 155 | snprintf(prop_name, MAX_PROP_SIZE, "%s-max-microamp", name); |
160 | ret = of_property_read_u32(np, prop_name, &vreg->max_uA); | 156 | if (of_property_read_u32(np, prop_name, &vreg->max_uA)) { |
161 | if (ret) { | 157 | dev_info(dev, "%s: unable to find %s\n", __func__, prop_name); |
162 | dev_err(dev, "%s: unable to find %s err %d\n", | 158 | vreg->max_uA = 0; |
163 | __func__, prop_name, ret); | ||
164 | goto out; | ||
165 | } | 159 | } |
166 | 160 | ||
167 | vreg->min_uA = 0; | ||
168 | if (!strcmp(name, "vcc")) { | 161 | if (!strcmp(name, "vcc")) { |
169 | if (of_property_read_bool(np, "vcc-supply-1p8")) { | 162 | if (of_property_read_bool(np, "vcc-supply-1p8")) { |
170 | vreg->min_uV = UFS_VREG_VCC_1P8_MIN_UV; | 163 | vreg->min_uV = UFS_VREG_VCC_1P8_MIN_UV; |
@@ -290,6 +283,103 @@ static void ufshcd_init_lanes_per_dir(struct ufs_hba *hba) | |||
290 | } | 283 | } |
291 | 284 | ||
292 | /** | 285 | /** |
286 | * ufshcd_get_pwr_dev_param - get finally agreed attributes for | ||
287 | * power mode change | ||
288 | * @pltfrm_param: pointer to platform parameters | ||
289 | * @dev_max: pointer to device attributes | ||
290 | * @agreed_pwr: returned agreed attributes | ||
291 | * | ||
292 | * Returns 0 on success, non-zero value on failure | ||
293 | */ | ||
294 | int ufshcd_get_pwr_dev_param(struct ufs_dev_params *pltfrm_param, | ||
295 | struct ufs_pa_layer_attr *dev_max, | ||
296 | struct ufs_pa_layer_attr *agreed_pwr) | ||
297 | { | ||
298 | int min_pltfrm_gear; | ||
299 | int min_dev_gear; | ||
300 | bool is_dev_sup_hs = false; | ||
301 | bool is_pltfrm_max_hs = false; | ||
302 | |||
303 | if (dev_max->pwr_rx == FAST_MODE) | ||
304 | is_dev_sup_hs = true; | ||
305 | |||
306 | if (pltfrm_param->desired_working_mode == UFS_HS_MODE) { | ||
307 | is_pltfrm_max_hs = true; | ||
308 | min_pltfrm_gear = min_t(u32, pltfrm_param->hs_rx_gear, | ||
309 | pltfrm_param->hs_tx_gear); | ||
310 | } else { | ||
311 | min_pltfrm_gear = min_t(u32, pltfrm_param->pwm_rx_gear, | ||
312 | pltfrm_param->pwm_tx_gear); | ||
313 | } | ||
314 | |||
315 | /* | ||
316 | * device doesn't support HS but | ||
317 | * pltfrm_param->desired_working_mode is HS, | ||
318 | * thus device and pltfrm_param don't agree | ||
319 | */ | ||
320 | if (!is_dev_sup_hs && is_pltfrm_max_hs) { | ||
321 | pr_info("%s: device doesn't support HS\n", | ||
322 | __func__); | ||
323 | return -ENOTSUPP; | ||
324 | } else if (is_dev_sup_hs && is_pltfrm_max_hs) { | ||
325 | /* | ||
326 | * since device supports HS, it supports FAST_MODE. | ||
327 | * since pltfrm_param->desired_working_mode is also HS | ||
328 | * then final decision (FAST/FASTAUTO) is done according | ||
329 | * to pltfrm_params as it is the restricting factor | ||
330 | */ | ||
331 | agreed_pwr->pwr_rx = pltfrm_param->rx_pwr_hs; | ||
332 | agreed_pwr->pwr_tx = agreed_pwr->pwr_rx; | ||
333 | } else { | ||
334 | /* | ||
335 | * here pltfrm_param->desired_working_mode is PWM. | ||
336 | * it doesn't matter whether device supports HS or PWM, | ||
337 | * in both cases pltfrm_param->desired_working_mode will | ||
338 | * determine the mode | ||
339 | */ | ||
340 | agreed_pwr->pwr_rx = pltfrm_param->rx_pwr_pwm; | ||
341 | agreed_pwr->pwr_tx = agreed_pwr->pwr_rx; | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * we would like tx to work in the minimum number of lanes | ||
346 | * between device capability and vendor preferences. | ||
347 | * the same decision will be made for rx | ||
348 | */ | ||
349 | agreed_pwr->lane_tx = min_t(u32, dev_max->lane_tx, | ||
350 | pltfrm_param->tx_lanes); | ||
351 | agreed_pwr->lane_rx = min_t(u32, dev_max->lane_rx, | ||
352 | pltfrm_param->rx_lanes); | ||
353 | |||
354 | /* device maximum gear is the minimum between device rx and tx gears */ | ||
355 | min_dev_gear = min_t(u32, dev_max->gear_rx, dev_max->gear_tx); | ||
356 | |||
357 | /* | ||
358 | * if both device capabilities and vendor pre-defined preferences are | ||
359 | * both HS or both PWM then set the minimum gear to be the chosen | ||
360 | * working gear. | ||
361 | * if one is PWM and one is HS then the one that is PWM get to decide | ||
362 | * what is the gear, as it is the one that also decided previously what | ||
363 | * pwr the device will be configured to. | ||
364 | */ | ||
365 | if ((is_dev_sup_hs && is_pltfrm_max_hs) || | ||
366 | (!is_dev_sup_hs && !is_pltfrm_max_hs)) { | ||
367 | agreed_pwr->gear_rx = | ||
368 | min_t(u32, min_dev_gear, min_pltfrm_gear); | ||
369 | } else if (!is_dev_sup_hs) { | ||
370 | agreed_pwr->gear_rx = min_dev_gear; | ||
371 | } else { | ||
372 | agreed_pwr->gear_rx = min_pltfrm_gear; | ||
373 | } | ||
374 | agreed_pwr->gear_tx = agreed_pwr->gear_rx; | ||
375 | |||
376 | agreed_pwr->hs_rate = pltfrm_param->hs_rate; | ||
377 | |||
378 | return 0; | ||
379 | } | ||
380 | EXPORT_SYMBOL_GPL(ufshcd_get_pwr_dev_param); | ||
381 | |||
382 | /** | ||
293 | * ufshcd_pltfrm_init - probe routine of the driver | 383 | * ufshcd_pltfrm_init - probe routine of the driver |
294 | * @pdev: pointer to Platform device handle | 384 | * @pdev: pointer to Platform device handle |
295 | * @vops: pointer to variant ops | 385 | * @vops: pointer to variant ops |
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.h b/drivers/scsi/ufs/ufshcd-pltfrm.h index 1f29e1fd6d52..0919ebba182b 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.h +++ b/drivers/scsi/ufs/ufshcd-pltfrm.h | |||
@@ -16,6 +16,27 @@ | |||
16 | 16 | ||
17 | #include "ufshcd.h" | 17 | #include "ufshcd.h" |
18 | 18 | ||
19 | #define UFS_PWM_MODE 1 | ||
20 | #define UFS_HS_MODE 2 | ||
21 | |||
22 | struct ufs_dev_params { | ||
23 | u32 pwm_rx_gear; /* pwm rx gear to work in */ | ||
24 | u32 pwm_tx_gear; /* pwm tx gear to work in */ | ||
25 | u32 hs_rx_gear; /* hs rx gear to work in */ | ||
26 | u32 hs_tx_gear; /* hs tx gear to work in */ | ||
27 | u32 rx_lanes; /* number of rx lanes */ | ||
28 | u32 tx_lanes; /* number of tx lanes */ | ||
29 | u32 rx_pwr_pwm; /* rx pwm working pwr */ | ||
30 | u32 tx_pwr_pwm; /* tx pwm working pwr */ | ||
31 | u32 rx_pwr_hs; /* rx hs working pwr */ | ||
32 | u32 tx_pwr_hs; /* tx hs working pwr */ | ||
33 | u32 hs_rate; /* rate A/B to work in HS */ | ||
34 | u32 desired_working_mode; | ||
35 | }; | ||
36 | |||
37 | int ufshcd_get_pwr_dev_param(struct ufs_dev_params *dev_param, | ||
38 | struct ufs_pa_layer_attr *dev_max, | ||
39 | struct ufs_pa_layer_attr *agreed_pwr); | ||
19 | int ufshcd_pltfrm_init(struct platform_device *pdev, | 40 | int ufshcd_pltfrm_init(struct platform_device *pdev, |
20 | const struct ufs_hba_variant_ops *vops); | 41 | const struct ufs_hba_variant_ops *vops); |
21 | void ufshcd_pltfrm_shutdown(struct platform_device *pdev); | 42 | void ufshcd_pltfrm_shutdown(struct platform_device *pdev); |
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index e040f9dd9ff3..8c1c551f2b42 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c | |||
@@ -4704,10 +4704,10 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) | |||
4704 | "Reject UPIU not fully implemented\n"); | 4704 | "Reject UPIU not fully implemented\n"); |
4705 | break; | 4705 | break; |
4706 | default: | 4706 | default: |
4707 | result = DID_ERROR << 16; | ||
4708 | dev_err(hba->dev, | 4707 | dev_err(hba->dev, |
4709 | "Unexpected request response code = %x\n", | 4708 | "Unexpected request response code = %x\n", |
4710 | result); | 4709 | result); |
4710 | result = DID_ERROR << 16; | ||
4711 | break; | 4711 | break; |
4712 | } | 4712 | } |
4713 | break; | 4713 | break; |
@@ -6294,19 +6294,19 @@ static u32 ufshcd_find_max_sup_active_icc_level(struct ufs_hba *hba, | |||
6294 | goto out; | 6294 | goto out; |
6295 | } | 6295 | } |
6296 | 6296 | ||
6297 | if (hba->vreg_info.vcc) | 6297 | if (hba->vreg_info.vcc && hba->vreg_info.vcc->max_uA) |
6298 | icc_level = ufshcd_get_max_icc_level( | 6298 | icc_level = ufshcd_get_max_icc_level( |
6299 | hba->vreg_info.vcc->max_uA, | 6299 | hba->vreg_info.vcc->max_uA, |
6300 | POWER_DESC_MAX_ACTV_ICC_LVLS - 1, | 6300 | POWER_DESC_MAX_ACTV_ICC_LVLS - 1, |
6301 | &desc_buf[PWR_DESC_ACTIVE_LVLS_VCC_0]); | 6301 | &desc_buf[PWR_DESC_ACTIVE_LVLS_VCC_0]); |
6302 | 6302 | ||
6303 | if (hba->vreg_info.vccq) | 6303 | if (hba->vreg_info.vccq && hba->vreg_info.vccq->max_uA) |
6304 | icc_level = ufshcd_get_max_icc_level( | 6304 | icc_level = ufshcd_get_max_icc_level( |
6305 | hba->vreg_info.vccq->max_uA, | 6305 | hba->vreg_info.vccq->max_uA, |
6306 | icc_level, | 6306 | icc_level, |
6307 | &desc_buf[PWR_DESC_ACTIVE_LVLS_VCCQ_0]); | 6307 | &desc_buf[PWR_DESC_ACTIVE_LVLS_VCCQ_0]); |
6308 | 6308 | ||
6309 | if (hba->vreg_info.vccq2) | 6309 | if (hba->vreg_info.vccq2 && hba->vreg_info.vccq2->max_uA) |
6310 | icc_level = ufshcd_get_max_icc_level( | 6310 | icc_level = ufshcd_get_max_icc_level( |
6311 | hba->vreg_info.vccq2->max_uA, | 6311 | hba->vreg_info.vccq2->max_uA, |
6312 | icc_level, | 6312 | icc_level, |
@@ -7004,6 +7004,15 @@ static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg, | |||
7004 | if (!vreg) | 7004 | if (!vreg) |
7005 | return 0; | 7005 | return 0; |
7006 | 7006 | ||
7007 | /* | ||
7008 | * "set_load" operation shall be required on those regulators | ||
7009 | * which specifically configured current limitation. Otherwise | ||
7010 | * zero max_uA may cause unexpected behavior when regulator is | ||
7011 | * enabled or set as high power mode. | ||
7012 | */ | ||
7013 | if (!vreg->max_uA) | ||
7014 | return 0; | ||
7015 | |||
7007 | ret = regulator_set_load(vreg->reg, ua); | 7016 | ret = regulator_set_load(vreg->reg, ua); |
7008 | if (ret < 0) { | 7017 | if (ret < 0) { |
7009 | dev_err(dev, "%s: %s set load (ua=%d) failed, err=%d\n", | 7018 | dev_err(dev, "%s: %s set load (ua=%d) failed, err=%d\n", |
@@ -7039,12 +7048,15 @@ static int ufshcd_config_vreg(struct device *dev, | |||
7039 | name = vreg->name; | 7048 | name = vreg->name; |
7040 | 7049 | ||
7041 | if (regulator_count_voltages(reg) > 0) { | 7050 | if (regulator_count_voltages(reg) > 0) { |
7042 | min_uV = on ? vreg->min_uV : 0; | 7051 | if (vreg->min_uV && vreg->max_uV) { |
7043 | ret = regulator_set_voltage(reg, min_uV, vreg->max_uV); | 7052 | min_uV = on ? vreg->min_uV : 0; |
7044 | if (ret) { | 7053 | ret = regulator_set_voltage(reg, min_uV, vreg->max_uV); |
7045 | dev_err(dev, "%s: %s set voltage failed, err=%d\n", | 7054 | if (ret) { |
7055 | dev_err(dev, | ||
7056 | "%s: %s set voltage failed, err=%d\n", | ||
7046 | __func__, name, ret); | 7057 | __func__, name, ret); |
7047 | goto out; | 7058 | goto out; |
7059 | } | ||
7048 | } | 7060 | } |
7049 | 7061 | ||
7050 | uA_load = on ? vreg->max_uA : 0; | 7062 | uA_load = on ? vreg->max_uA : 0; |
@@ -7103,9 +7115,6 @@ static int ufshcd_setup_vreg(struct ufs_hba *hba, bool on) | |||
7103 | struct device *dev = hba->dev; | 7115 | struct device *dev = hba->dev; |
7104 | struct ufs_vreg_info *info = &hba->vreg_info; | 7116 | struct ufs_vreg_info *info = &hba->vreg_info; |
7105 | 7117 | ||
7106 | if (!info) | ||
7107 | goto out; | ||
7108 | |||
7109 | ret = ufshcd_toggle_vreg(dev, info->vcc, on); | 7118 | ret = ufshcd_toggle_vreg(dev, info->vcc, on); |
7110 | if (ret) | 7119 | if (ret) |
7111 | goto out; | 7120 | goto out; |
@@ -7131,10 +7140,7 @@ static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on) | |||
7131 | { | 7140 | { |
7132 | struct ufs_vreg_info *info = &hba->vreg_info; | 7141 | struct ufs_vreg_info *info = &hba->vreg_info; |
7133 | 7142 | ||
7134 | if (info) | 7143 | return ufshcd_toggle_vreg(hba->dev, info->vdd_hba, on); |
7135 | return ufshcd_toggle_vreg(hba->dev, info->vdd_hba, on); | ||
7136 | |||
7137 | return 0; | ||
7138 | } | 7144 | } |
7139 | 7145 | ||
7140 | static int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg) | 7146 | static int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg) |
@@ -7160,9 +7166,6 @@ static int ufshcd_init_vreg(struct ufs_hba *hba) | |||
7160 | struct device *dev = hba->dev; | 7166 | struct device *dev = hba->dev; |
7161 | struct ufs_vreg_info *info = &hba->vreg_info; | 7167 | struct ufs_vreg_info *info = &hba->vreg_info; |
7162 | 7168 | ||
7163 | if (!info) | ||
7164 | goto out; | ||
7165 | |||
7166 | ret = ufshcd_get_vreg(dev, info->vcc); | 7169 | ret = ufshcd_get_vreg(dev, info->vcc); |
7167 | if (ret) | 7170 | if (ret) |
7168 | goto out; | 7171 | goto out; |
diff --git a/drivers/scsi/ufs/unipro.h b/drivers/scsi/ufs/unipro.h index 23129d7b2678..c77e36526447 100644 --- a/drivers/scsi/ufs/unipro.h +++ b/drivers/scsi/ufs/unipro.h | |||
@@ -52,7 +52,7 @@ | |||
52 | #define RX_HS_UNTERMINATED_ENABLE 0x00A6 | 52 | #define RX_HS_UNTERMINATED_ENABLE 0x00A6 |
53 | #define RX_ENTER_HIBERN8 0x00A7 | 53 | #define RX_ENTER_HIBERN8 0x00A7 |
54 | #define RX_BYPASS_8B10B_ENABLE 0x00A8 | 54 | #define RX_BYPASS_8B10B_ENABLE 0x00A8 |
55 | #define RX_TERMINATION_FORCE_ENABLE 0x0089 | 55 | #define RX_TERMINATION_FORCE_ENABLE 0x00A9 |
56 | #define RX_MIN_ACTIVATETIME_CAPABILITY 0x008F | 56 | #define RX_MIN_ACTIVATETIME_CAPABILITY 0x008F |
57 | #define RX_HIBERN8TIME_CAPABILITY 0x0092 | 57 | #define RX_HIBERN8TIME_CAPABILITY 0x0092 |
58 | #define RX_REFCLKFREQ 0x00EB | 58 | #define RX_REFCLKFREQ 0x00EB |
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index f8cb7c23305b..c47d38bca948 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c | |||
@@ -659,7 +659,7 @@ static int virtscsi_abort(struct scsi_cmnd *sc) | |||
659 | static int virtscsi_map_queues(struct Scsi_Host *shost) | 659 | static int virtscsi_map_queues(struct Scsi_Host *shost) |
660 | { | 660 | { |
661 | struct virtio_scsi *vscsi = shost_priv(shost); | 661 | struct virtio_scsi *vscsi = shost_priv(shost); |
662 | struct blk_mq_queue_map *qmap = &shost->tag_set.map[0]; | 662 | struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; |
663 | 663 | ||
664 | return blk_mq_virtio_map_queues(qmap, vscsi->vdev, 2); | 664 | return blk_mq_virtio_map_queues(qmap, vscsi->vdev, 2); |
665 | } | 665 | } |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 5ce6e2a40e00..59d32453b891 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -573,7 +573,8 @@ iscsit_xmit_nondatain_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
573 | return 0; | 573 | return 0; |
574 | } | 574 | } |
575 | 575 | ||
576 | static int iscsit_map_iovec(struct iscsi_cmd *, struct kvec *, u32, u32); | 576 | static int iscsit_map_iovec(struct iscsi_cmd *cmd, struct kvec *iov, int nvec, |
577 | u32 data_offset, u32 data_length); | ||
577 | static void iscsit_unmap_iovec(struct iscsi_cmd *); | 578 | static void iscsit_unmap_iovec(struct iscsi_cmd *); |
578 | static u32 iscsit_do_crypto_hash_sg(struct ahash_request *, struct iscsi_cmd *, | 579 | static u32 iscsit_do_crypto_hash_sg(struct ahash_request *, struct iscsi_cmd *, |
579 | u32, u32, u32, u8 *); | 580 | u32, u32, u32, u8 *); |
@@ -604,7 +605,8 @@ iscsit_xmit_datain_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
604 | *header_digest); | 605 | *header_digest); |
605 | } | 606 | } |
606 | 607 | ||
607 | iov_ret = iscsit_map_iovec(cmd, &cmd->iov_data[1], | 608 | iov_ret = iscsit_map_iovec(cmd, &cmd->iov_data[iov_count], |
609 | cmd->orig_iov_data_count - (iov_count + 2), | ||
608 | datain->offset, datain->length); | 610 | datain->offset, datain->length); |
609 | if (iov_ret < 0) | 611 | if (iov_ret < 0) |
610 | return -1; | 612 | return -1; |
@@ -886,13 +888,10 @@ EXPORT_SYMBOL(iscsit_reject_cmd); | |||
886 | * Map some portion of the allocated scatterlist to an iovec, suitable for | 888 | * Map some portion of the allocated scatterlist to an iovec, suitable for |
887 | * kernel sockets to copy data in/out. | 889 | * kernel sockets to copy data in/out. |
888 | */ | 890 | */ |
889 | static int iscsit_map_iovec( | 891 | static int iscsit_map_iovec(struct iscsi_cmd *cmd, struct kvec *iov, int nvec, |
890 | struct iscsi_cmd *cmd, | 892 | u32 data_offset, u32 data_length) |
891 | struct kvec *iov, | ||
892 | u32 data_offset, | ||
893 | u32 data_length) | ||
894 | { | 893 | { |
895 | u32 i = 0; | 894 | u32 i = 0, orig_data_length = data_length; |
896 | struct scatterlist *sg; | 895 | struct scatterlist *sg; |
897 | unsigned int page_off; | 896 | unsigned int page_off; |
898 | 897 | ||
@@ -901,9 +900,12 @@ static int iscsit_map_iovec( | |||
901 | */ | 900 | */ |
902 | u32 ent = data_offset / PAGE_SIZE; | 901 | u32 ent = data_offset / PAGE_SIZE; |
903 | 902 | ||
903 | if (!data_length) | ||
904 | return 0; | ||
905 | |||
904 | if (ent >= cmd->se_cmd.t_data_nents) { | 906 | if (ent >= cmd->se_cmd.t_data_nents) { |
905 | pr_err("Initial page entry out-of-bounds\n"); | 907 | pr_err("Initial page entry out-of-bounds\n"); |
906 | return -1; | 908 | goto overflow; |
907 | } | 909 | } |
908 | 910 | ||
909 | sg = &cmd->se_cmd.t_data_sg[ent]; | 911 | sg = &cmd->se_cmd.t_data_sg[ent]; |
@@ -913,7 +915,12 @@ static int iscsit_map_iovec( | |||
913 | cmd->first_data_sg_off = page_off; | 915 | cmd->first_data_sg_off = page_off; |
914 | 916 | ||
915 | while (data_length) { | 917 | while (data_length) { |
916 | u32 cur_len = min_t(u32, data_length, sg->length - page_off); | 918 | u32 cur_len; |
919 | |||
920 | if (WARN_ON_ONCE(!sg || i >= nvec)) | ||
921 | goto overflow; | ||
922 | |||
923 | cur_len = min_t(u32, data_length, sg->length - page_off); | ||
917 | 924 | ||
918 | iov[i].iov_base = kmap(sg_page(sg)) + sg->offset + page_off; | 925 | iov[i].iov_base = kmap(sg_page(sg)) + sg->offset + page_off; |
919 | iov[i].iov_len = cur_len; | 926 | iov[i].iov_len = cur_len; |
@@ -927,6 +934,16 @@ static int iscsit_map_iovec( | |||
927 | cmd->kmapped_nents = i; | 934 | cmd->kmapped_nents = i; |
928 | 935 | ||
929 | return i; | 936 | return i; |
937 | |||
938 | overflow: | ||
939 | pr_err("offset %d + length %d overflow; %d/%d; sg-list:\n", | ||
940 | data_offset, orig_data_length, i, nvec); | ||
941 | for_each_sg(cmd->se_cmd.t_data_sg, sg, | ||
942 | cmd->se_cmd.t_data_nents, i) { | ||
943 | pr_err("[%d] off %d len %d\n", | ||
944 | i, sg->offset, sg->length); | ||
945 | } | ||
946 | return -1; | ||
930 | } | 947 | } |
931 | 948 | ||
932 | static void iscsit_unmap_iovec(struct iscsi_cmd *cmd) | 949 | static void iscsit_unmap_iovec(struct iscsi_cmd *cmd) |
@@ -1268,27 +1285,27 @@ iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr, | |||
1268 | bool dump_payload) | 1285 | bool dump_payload) |
1269 | { | 1286 | { |
1270 | int cmdsn_ret = 0, immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; | 1287 | int cmdsn_ret = 0, immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; |
1288 | int rc; | ||
1289 | |||
1271 | /* | 1290 | /* |
1272 | * Special case for Unsupported SAM WRITE Opcodes and ImmediateData=Yes. | 1291 | * Special case for Unsupported SAM WRITE Opcodes and ImmediateData=Yes. |
1273 | */ | 1292 | */ |
1274 | if (dump_payload) | 1293 | if (dump_payload) { |
1275 | goto after_immediate_data; | 1294 | u32 length = min(cmd->se_cmd.data_length - cmd->write_data_done, |
1276 | /* | 1295 | cmd->first_burst_len); |
1277 | * Check for underflow case where both EDTL and immediate data payload | 1296 | |
1278 | * exceeds what is presented by CDB's TRANSFER LENGTH, and what has | 1297 | pr_debug("Dumping min(%d - %d, %d) = %d bytes of immediate data\n", |
1279 | * already been set in target_cmd_size_check() as se_cmd->data_length. | 1298 | cmd->se_cmd.data_length, cmd->write_data_done, |
1280 | * | 1299 | cmd->first_burst_len, length); |
1281 | * For this special case, fail the command and dump the immediate data | 1300 | rc = iscsit_dump_data_payload(cmd->conn, length, 1); |
1282 | * payload. | 1301 | pr_debug("Finished dumping immediate data\n"); |
1283 | */ | 1302 | if (rc < 0) |
1284 | if (cmd->first_burst_len > cmd->se_cmd.data_length) { | 1303 | immed_ret = IMMEDIATE_DATA_CANNOT_RECOVER; |
1285 | cmd->sense_reason = TCM_INVALID_CDB_FIELD; | 1304 | } else { |
1286 | goto after_immediate_data; | 1305 | immed_ret = iscsit_handle_immediate_data(cmd, hdr, |
1306 | cmd->first_burst_len); | ||
1287 | } | 1307 | } |
1288 | 1308 | ||
1289 | immed_ret = iscsit_handle_immediate_data(cmd, hdr, | ||
1290 | cmd->first_burst_len); | ||
1291 | after_immediate_data: | ||
1292 | if (immed_ret == IMMEDIATE_DATA_NORMAL_OPERATION) { | 1309 | if (immed_ret == IMMEDIATE_DATA_NORMAL_OPERATION) { |
1293 | /* | 1310 | /* |
1294 | * A PDU/CmdSN carrying Immediate Data passed | 1311 | * A PDU/CmdSN carrying Immediate Data passed |
@@ -1301,12 +1318,9 @@ after_immediate_data: | |||
1301 | return -1; | 1318 | return -1; |
1302 | 1319 | ||
1303 | if (cmd->sense_reason || cmdsn_ret == CMDSN_LOWER_THAN_EXP) { | 1320 | if (cmd->sense_reason || cmdsn_ret == CMDSN_LOWER_THAN_EXP) { |
1304 | int rc; | ||
1305 | |||
1306 | rc = iscsit_dump_data_payload(cmd->conn, | ||
1307 | cmd->first_burst_len, 1); | ||
1308 | target_put_sess_cmd(&cmd->se_cmd); | 1321 | target_put_sess_cmd(&cmd->se_cmd); |
1309 | return rc; | 1322 | |
1323 | return 0; | ||
1310 | } else if (cmd->unsolicited_data) | 1324 | } else if (cmd->unsolicited_data) |
1311 | iscsit_set_unsolicited_dataout(cmd); | 1325 | iscsit_set_unsolicited_dataout(cmd); |
1312 | 1326 | ||
@@ -1568,14 +1582,16 @@ iscsit_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1568 | { | 1582 | { |
1569 | struct kvec *iov; | 1583 | struct kvec *iov; |
1570 | u32 checksum, iov_count = 0, padding = 0, rx_got = 0, rx_size = 0; | 1584 | u32 checksum, iov_count = 0, padding = 0, rx_got = 0, rx_size = 0; |
1571 | u32 payload_length = ntoh24(hdr->dlength); | 1585 | u32 payload_length; |
1572 | int iov_ret, data_crc_failed = 0; | 1586 | int iov_ret, data_crc_failed = 0; |
1573 | 1587 | ||
1588 | payload_length = min_t(u32, cmd->se_cmd.data_length, | ||
1589 | ntoh24(hdr->dlength)); | ||
1574 | rx_size += payload_length; | 1590 | rx_size += payload_length; |
1575 | iov = &cmd->iov_data[0]; | 1591 | iov = &cmd->iov_data[0]; |
1576 | 1592 | ||
1577 | iov_ret = iscsit_map_iovec(cmd, iov, be32_to_cpu(hdr->offset), | 1593 | iov_ret = iscsit_map_iovec(cmd, iov, cmd->orig_iov_data_count - 2, |
1578 | payload_length); | 1594 | be32_to_cpu(hdr->offset), payload_length); |
1579 | if (iov_ret < 0) | 1595 | if (iov_ret < 0) |
1580 | return -1; | 1596 | return -1; |
1581 | 1597 | ||
@@ -1595,6 +1611,7 @@ iscsit_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1595 | rx_size += ISCSI_CRC_LEN; | 1611 | rx_size += ISCSI_CRC_LEN; |
1596 | } | 1612 | } |
1597 | 1613 | ||
1614 | WARN_ON_ONCE(iov_count > cmd->orig_iov_data_count); | ||
1598 | rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size); | 1615 | rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size); |
1599 | 1616 | ||
1600 | iscsit_unmap_iovec(cmd); | 1617 | iscsit_unmap_iovec(cmd); |
@@ -1860,6 +1877,7 @@ static int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1860 | rx_size += ISCSI_CRC_LEN; | 1877 | rx_size += ISCSI_CRC_LEN; |
1861 | } | 1878 | } |
1862 | 1879 | ||
1880 | WARN_ON_ONCE(niov > ARRAY_SIZE(cmd->iov_misc)); | ||
1863 | rx_got = rx_data(conn, &cmd->iov_misc[0], niov, rx_size); | 1881 | rx_got = rx_data(conn, &cmd->iov_misc[0], niov, rx_size); |
1864 | if (rx_got != rx_size) { | 1882 | if (rx_got != rx_size) { |
1865 | ret = -1; | 1883 | ret = -1; |
@@ -2265,6 +2283,7 @@ iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
2265 | rx_size += ISCSI_CRC_LEN; | 2283 | rx_size += ISCSI_CRC_LEN; |
2266 | } | 2284 | } |
2267 | 2285 | ||
2286 | WARN_ON_ONCE(niov > ARRAY_SIZE(iov)); | ||
2268 | rx_got = rx_data(conn, &iov[0], niov, rx_size); | 2287 | rx_got = rx_data(conn, &iov[0], niov, rx_size); |
2269 | if (rx_got != rx_size) | 2288 | if (rx_got != rx_size) |
2270 | goto reject; | 2289 | goto reject; |
@@ -2575,14 +2594,34 @@ static int iscsit_handle_immediate_data( | |||
2575 | u32 checksum, iov_count = 0, padding = 0; | 2594 | u32 checksum, iov_count = 0, padding = 0; |
2576 | struct iscsi_conn *conn = cmd->conn; | 2595 | struct iscsi_conn *conn = cmd->conn; |
2577 | struct kvec *iov; | 2596 | struct kvec *iov; |
2597 | void *overflow_buf = NULL; | ||
2578 | 2598 | ||
2579 | iov_ret = iscsit_map_iovec(cmd, cmd->iov_data, cmd->write_data_done, length); | 2599 | BUG_ON(cmd->write_data_done > cmd->se_cmd.data_length); |
2600 | rx_size = min(cmd->se_cmd.data_length - cmd->write_data_done, length); | ||
2601 | iov_ret = iscsit_map_iovec(cmd, cmd->iov_data, | ||
2602 | cmd->orig_iov_data_count - 2, | ||
2603 | cmd->write_data_done, rx_size); | ||
2580 | if (iov_ret < 0) | 2604 | if (iov_ret < 0) |
2581 | return IMMEDIATE_DATA_CANNOT_RECOVER; | 2605 | return IMMEDIATE_DATA_CANNOT_RECOVER; |
2582 | 2606 | ||
2583 | rx_size = length; | ||
2584 | iov_count = iov_ret; | 2607 | iov_count = iov_ret; |
2585 | iov = &cmd->iov_data[0]; | 2608 | iov = &cmd->iov_data[0]; |
2609 | if (rx_size < length) { | ||
2610 | /* | ||
2611 | * Special case: length of immediate data exceeds the data | ||
2612 | * buffer size derived from the CDB. | ||
2613 | */ | ||
2614 | overflow_buf = kmalloc(length - rx_size, GFP_KERNEL); | ||
2615 | if (!overflow_buf) { | ||
2616 | iscsit_unmap_iovec(cmd); | ||
2617 | return IMMEDIATE_DATA_CANNOT_RECOVER; | ||
2618 | } | ||
2619 | cmd->overflow_buf = overflow_buf; | ||
2620 | iov[iov_count].iov_base = overflow_buf; | ||
2621 | iov[iov_count].iov_len = length - rx_size; | ||
2622 | iov_count++; | ||
2623 | rx_size = length; | ||
2624 | } | ||
2586 | 2625 | ||
2587 | padding = ((-length) & 3); | 2626 | padding = ((-length) & 3); |
2588 | if (padding != 0) { | 2627 | if (padding != 0) { |
@@ -2597,6 +2636,7 @@ static int iscsit_handle_immediate_data( | |||
2597 | rx_size += ISCSI_CRC_LEN; | 2636 | rx_size += ISCSI_CRC_LEN; |
2598 | } | 2637 | } |
2599 | 2638 | ||
2639 | WARN_ON_ONCE(iov_count > cmd->orig_iov_data_count); | ||
2600 | rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size); | 2640 | rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size); |
2601 | 2641 | ||
2602 | iscsit_unmap_iovec(cmd); | 2642 | iscsit_unmap_iovec(cmd); |
@@ -3121,6 +3161,12 @@ int iscsit_build_r2ts_for_cmd( | |||
3121 | else | 3161 | else |
3122 | xfer_len = conn->sess->sess_ops->MaxBurstLength; | 3162 | xfer_len = conn->sess->sess_ops->MaxBurstLength; |
3123 | } | 3163 | } |
3164 | |||
3165 | if ((s32)xfer_len < 0) { | ||
3166 | cmd->cmd_flags |= ICF_SENT_LAST_R2T; | ||
3167 | break; | ||
3168 | } | ||
3169 | |||
3124 | cmd->r2t_offset += xfer_len; | 3170 | cmd->r2t_offset += xfer_len; |
3125 | 3171 | ||
3126 | if (cmd->r2t_offset == cmd->se_cmd.data_length) | 3172 | if (cmd->r2t_offset == cmd->se_cmd.data_length) |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index ae3209efd0e0..683d04580eb3 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -883,9 +883,6 @@ int iscsit_setup_np( | |||
883 | return -EINVAL; | 883 | return -EINVAL; |
884 | } | 884 | } |
885 | 885 | ||
886 | np->np_ip_proto = IPPROTO_TCP; | ||
887 | np->np_sock_type = SOCK_STREAM; | ||
888 | |||
889 | ret = sock_create(sockaddr->ss_family, np->np_sock_type, | 886 | ret = sock_create(sockaddr->ss_family, np->np_sock_type, |
890 | np->np_ip_proto, &sock); | 887 | np->np_ip_proto, &sock); |
891 | if (ret < 0) { | 888 | if (ret < 0) { |
@@ -1159,13 +1156,13 @@ static struct iscsi_conn *iscsit_alloc_conn(struct iscsi_np *np) | |||
1159 | 1156 | ||
1160 | if (!zalloc_cpumask_var(&conn->conn_cpumask, GFP_KERNEL)) { | 1157 | if (!zalloc_cpumask_var(&conn->conn_cpumask, GFP_KERNEL)) { |
1161 | pr_err("Unable to allocate conn->conn_cpumask\n"); | 1158 | pr_err("Unable to allocate conn->conn_cpumask\n"); |
1162 | goto free_mask; | 1159 | goto free_conn_ops; |
1163 | } | 1160 | } |
1164 | 1161 | ||
1165 | return conn; | 1162 | return conn; |
1166 | 1163 | ||
1167 | free_mask: | 1164 | free_conn_ops: |
1168 | free_cpumask_var(conn->conn_cpumask); | 1165 | kfree(conn->conn_ops); |
1169 | put_transport: | 1166 | put_transport: |
1170 | iscsit_put_transport(conn->conn_transport); | 1167 | iscsit_put_transport(conn->conn_transport); |
1171 | free_conn: | 1168 | free_conn: |
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 3ac494f63a0b..fae85bfd790e 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
@@ -67,6 +67,8 @@ int iscsit_add_r2t_to_list( | |||
67 | 67 | ||
68 | lockdep_assert_held(&cmd->r2t_lock); | 68 | lockdep_assert_held(&cmd->r2t_lock); |
69 | 69 | ||
70 | WARN_ON_ONCE((s32)xfer_len < 0); | ||
71 | |||
70 | r2t = kmem_cache_zalloc(lio_r2t_cache, GFP_ATOMIC); | 72 | r2t = kmem_cache_zalloc(lio_r2t_cache, GFP_ATOMIC); |
71 | if (!r2t) { | 73 | if (!r2t) { |
72 | pr_err("Unable to allocate memory for struct iscsi_r2t.\n"); | 74 | pr_err("Unable to allocate memory for struct iscsi_r2t.\n"); |
@@ -735,6 +737,7 @@ void iscsit_release_cmd(struct iscsi_cmd *cmd) | |||
735 | kfree(cmd->pdu_list); | 737 | kfree(cmd->pdu_list); |
736 | kfree(cmd->seq_list); | 738 | kfree(cmd->seq_list); |
737 | kfree(cmd->tmr_req); | 739 | kfree(cmd->tmr_req); |
740 | kfree(cmd->overflow_buf); | ||
738 | kfree(cmd->iov_data); | 741 | kfree(cmd->iov_data); |
739 | kfree(cmd->text_in_ptr); | 742 | kfree(cmd->text_in_ptr); |
740 | 743 | ||
@@ -769,6 +772,8 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown) | |||
769 | struct se_cmd *se_cmd = cmd->se_cmd.se_tfo ? &cmd->se_cmd : NULL; | 772 | struct se_cmd *se_cmd = cmd->se_cmd.se_tfo ? &cmd->se_cmd : NULL; |
770 | int rc; | 773 | int rc; |
771 | 774 | ||
775 | WARN_ON(!list_empty(&cmd->i_conn_node)); | ||
776 | |||
772 | __iscsit_free_cmd(cmd, shutdown); | 777 | __iscsit_free_cmd(cmd, shutdown); |
773 | if (se_cmd) { | 778 | if (se_cmd) { |
774 | rc = transport_generic_free_cmd(se_cmd, shutdown); | 779 | rc = transport_generic_free_cmd(se_cmd, shutdown); |
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index e09f0cf86bed..893f1fe8e373 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -1760,8 +1760,10 @@ void core_alua_free_tg_pt_gp( | |||
1760 | * can be made while we are releasing struct t10_alua_tg_pt_gp. | 1760 | * can be made while we are releasing struct t10_alua_tg_pt_gp. |
1761 | */ | 1761 | */ |
1762 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); | 1762 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
1763 | list_del(&tg_pt_gp->tg_pt_gp_list); | 1763 | if (tg_pt_gp->tg_pt_gp_valid_id) { |
1764 | dev->t10_alua.alua_tg_pt_gps_counter--; | 1764 | list_del(&tg_pt_gp->tg_pt_gp_list); |
1765 | dev->t10_alua.alua_tg_pt_gps_count--; | ||
1766 | } | ||
1765 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); | 1767 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1766 | 1768 | ||
1767 | /* | 1769 | /* |
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index fc5ef31f5ba8..db2558fe8d46 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
@@ -1227,6 +1227,29 @@ static struct t10_wwn *to_t10_wwn(struct config_item *item) | |||
1227 | return container_of(to_config_group(item), struct t10_wwn, t10_wwn_group); | 1227 | return container_of(to_config_group(item), struct t10_wwn, t10_wwn_group); |
1228 | } | 1228 | } |
1229 | 1229 | ||
1230 | static ssize_t target_check_inquiry_data(char *buf) | ||
1231 | { | ||
1232 | size_t len; | ||
1233 | int i; | ||
1234 | |||
1235 | len = strlen(buf); | ||
1236 | |||
1237 | /* | ||
1238 | * SPC 4.3.1: | ||
1239 | * ASCII data fields shall contain only ASCII printable characters | ||
1240 | * (i.e., code values 20h to 7Eh) and may be terminated with one or | ||
1241 | * more ASCII null (00h) characters. | ||
1242 | */ | ||
1243 | for (i = 0; i < len; i++) { | ||
1244 | if (buf[i] < 0x20 || buf[i] > 0x7E) { | ||
1245 | pr_err("Emulated T10 Inquiry Data contains non-ASCII-printable characters\n"); | ||
1246 | return -EINVAL; | ||
1247 | } | ||
1248 | } | ||
1249 | |||
1250 | return len; | ||
1251 | } | ||
1252 | |||
1230 | /* | 1253 | /* |
1231 | * STANDARD and VPD page 0x83 T10 Vendor Identification | 1254 | * STANDARD and VPD page 0x83 T10 Vendor Identification |
1232 | */ | 1255 | */ |
@@ -1245,7 +1268,7 @@ static ssize_t target_wwn_vendor_id_store(struct config_item *item, | |||
1245 | unsigned char buf[INQUIRY_VENDOR_LEN + 2]; | 1268 | unsigned char buf[INQUIRY_VENDOR_LEN + 2]; |
1246 | char *stripped = NULL; | 1269 | char *stripped = NULL; |
1247 | size_t len; | 1270 | size_t len; |
1248 | int i; | 1271 | ssize_t ret; |
1249 | 1272 | ||
1250 | len = strlcpy(buf, page, sizeof(buf)); | 1273 | len = strlcpy(buf, page, sizeof(buf)); |
1251 | if (len < sizeof(buf)) { | 1274 | if (len < sizeof(buf)) { |
@@ -1260,19 +1283,10 @@ static ssize_t target_wwn_vendor_id_store(struct config_item *item, | |||
1260 | return -EOVERFLOW; | 1283 | return -EOVERFLOW; |
1261 | } | 1284 | } |
1262 | 1285 | ||
1263 | /* | 1286 | ret = target_check_inquiry_data(stripped); |
1264 | * SPC 4.3.1: | 1287 | |
1265 | * ASCII data fields shall contain only ASCII printable characters (i.e., | 1288 | if (ret < 0) |
1266 | * code values 20h to 7Eh) and may be terminated with one or more ASCII | 1289 | return ret; |
1267 | * null (00h) characters. | ||
1268 | */ | ||
1269 | for (i = 0; i < len; i++) { | ||
1270 | if ((stripped[i] < 0x20) || (stripped[i] > 0x7E)) { | ||
1271 | pr_err("Emulated T10 Vendor Identification contains" | ||
1272 | " non-ASCII-printable characters\n"); | ||
1273 | return -EINVAL; | ||
1274 | } | ||
1275 | } | ||
1276 | 1290 | ||
1277 | /* | 1291 | /* |
1278 | * Check to see if any active exports exist. If they do exist, fail | 1292 | * Check to see if any active exports exist. If they do exist, fail |
@@ -1295,6 +1309,118 @@ static ssize_t target_wwn_vendor_id_store(struct config_item *item, | |||
1295 | return count; | 1309 | return count; |
1296 | } | 1310 | } |
1297 | 1311 | ||
1312 | static ssize_t target_wwn_product_id_show(struct config_item *item, | ||
1313 | char *page) | ||
1314 | { | ||
1315 | return sprintf(page, "%s\n", &to_t10_wwn(item)->model[0]); | ||
1316 | } | ||
1317 | |||
1318 | static ssize_t target_wwn_product_id_store(struct config_item *item, | ||
1319 | const char *page, size_t count) | ||
1320 | { | ||
1321 | struct t10_wwn *t10_wwn = to_t10_wwn(item); | ||
1322 | struct se_device *dev = t10_wwn->t10_dev; | ||
1323 | /* +2 to allow for a trailing (stripped) '\n' and null-terminator */ | ||
1324 | unsigned char buf[INQUIRY_MODEL_LEN + 2]; | ||
1325 | char *stripped = NULL; | ||
1326 | size_t len; | ||
1327 | ssize_t ret; | ||
1328 | |||
1329 | len = strlcpy(buf, page, sizeof(buf)); | ||
1330 | if (len < sizeof(buf)) { | ||
1331 | /* Strip any newline added from userspace. */ | ||
1332 | stripped = strstrip(buf); | ||
1333 | len = strlen(stripped); | ||
1334 | } | ||
1335 | if (len > INQUIRY_MODEL_LEN) { | ||
1336 | pr_err("Emulated T10 Vendor exceeds INQUIRY_MODEL_LEN: " | ||
1337 | __stringify(INQUIRY_MODEL_LEN) | ||
1338 | "\n"); | ||
1339 | return -EOVERFLOW; | ||
1340 | } | ||
1341 | |||
1342 | ret = target_check_inquiry_data(stripped); | ||
1343 | |||
1344 | if (ret < 0) | ||
1345 | return ret; | ||
1346 | |||
1347 | /* | ||
1348 | * Check to see if any active exports exist. If they do exist, fail | ||
1349 | * here as changing this information on the fly (underneath the | ||
1350 | * initiator side OS dependent multipath code) could cause negative | ||
1351 | * effects. | ||
1352 | */ | ||
1353 | if (dev->export_count) { | ||
1354 | pr_err("Unable to set T10 Model while active %d exports exist\n", | ||
1355 | dev->export_count); | ||
1356 | return -EINVAL; | ||
1357 | } | ||
1358 | |||
1359 | BUILD_BUG_ON(sizeof(dev->t10_wwn.model) != INQUIRY_MODEL_LEN + 1); | ||
1360 | strlcpy(dev->t10_wwn.model, stripped, sizeof(dev->t10_wwn.model)); | ||
1361 | |||
1362 | pr_debug("Target_Core_ConfigFS: Set emulated T10 Model Identification: %s\n", | ||
1363 | dev->t10_wwn.model); | ||
1364 | |||
1365 | return count; | ||
1366 | } | ||
1367 | |||
1368 | static ssize_t target_wwn_revision_show(struct config_item *item, | ||
1369 | char *page) | ||
1370 | { | ||
1371 | return sprintf(page, "%s\n", &to_t10_wwn(item)->revision[0]); | ||
1372 | } | ||
1373 | |||
1374 | static ssize_t target_wwn_revision_store(struct config_item *item, | ||
1375 | const char *page, size_t count) | ||
1376 | { | ||
1377 | struct t10_wwn *t10_wwn = to_t10_wwn(item); | ||
1378 | struct se_device *dev = t10_wwn->t10_dev; | ||
1379 | /* +2 to allow for a trailing (stripped) '\n' and null-terminator */ | ||
1380 | unsigned char buf[INQUIRY_REVISION_LEN + 2]; | ||
1381 | char *stripped = NULL; | ||
1382 | size_t len; | ||
1383 | ssize_t ret; | ||
1384 | |||
1385 | len = strlcpy(buf, page, sizeof(buf)); | ||
1386 | if (len < sizeof(buf)) { | ||
1387 | /* Strip any newline added from userspace. */ | ||
1388 | stripped = strstrip(buf); | ||
1389 | len = strlen(stripped); | ||
1390 | } | ||
1391 | if (len > INQUIRY_REVISION_LEN) { | ||
1392 | pr_err("Emulated T10 Revision exceeds INQUIRY_REVISION_LEN: " | ||
1393 | __stringify(INQUIRY_REVISION_LEN) | ||
1394 | "\n"); | ||
1395 | return -EOVERFLOW; | ||
1396 | } | ||
1397 | |||
1398 | ret = target_check_inquiry_data(stripped); | ||
1399 | |||
1400 | if (ret < 0) | ||
1401 | return ret; | ||
1402 | |||
1403 | /* | ||
1404 | * Check to see if any active exports exist. If they do exist, fail | ||
1405 | * here as changing this information on the fly (underneath the | ||
1406 | * initiator side OS dependent multipath code) could cause negative | ||
1407 | * effects. | ||
1408 | */ | ||
1409 | if (dev->export_count) { | ||
1410 | pr_err("Unable to set T10 Revision while active %d exports exist\n", | ||
1411 | dev->export_count); | ||
1412 | return -EINVAL; | ||
1413 | } | ||
1414 | |||
1415 | BUILD_BUG_ON(sizeof(dev->t10_wwn.revision) != INQUIRY_REVISION_LEN + 1); | ||
1416 | strlcpy(dev->t10_wwn.revision, stripped, sizeof(dev->t10_wwn.revision)); | ||
1417 | |||
1418 | pr_debug("Target_Core_ConfigFS: Set emulated T10 Revision: %s\n", | ||
1419 | dev->t10_wwn.revision); | ||
1420 | |||
1421 | return count; | ||
1422 | } | ||
1423 | |||
1298 | /* | 1424 | /* |
1299 | * VPD page 0x80 Unit serial | 1425 | * VPD page 0x80 Unit serial |
1300 | */ | 1426 | */ |
@@ -1442,6 +1568,8 @@ DEF_DEV_WWN_ASSOC_SHOW(vpd_assoc_target_port, 0x10); | |||
1442 | DEF_DEV_WWN_ASSOC_SHOW(vpd_assoc_scsi_target_device, 0x20); | 1568 | DEF_DEV_WWN_ASSOC_SHOW(vpd_assoc_scsi_target_device, 0x20); |
1443 | 1569 | ||
1444 | CONFIGFS_ATTR(target_wwn_, vendor_id); | 1570 | CONFIGFS_ATTR(target_wwn_, vendor_id); |
1571 | CONFIGFS_ATTR(target_wwn_, product_id); | ||
1572 | CONFIGFS_ATTR(target_wwn_, revision); | ||
1445 | CONFIGFS_ATTR(target_wwn_, vpd_unit_serial); | 1573 | CONFIGFS_ATTR(target_wwn_, vpd_unit_serial); |
1446 | CONFIGFS_ATTR_RO(target_wwn_, vpd_protocol_identifier); | 1574 | CONFIGFS_ATTR_RO(target_wwn_, vpd_protocol_identifier); |
1447 | CONFIGFS_ATTR_RO(target_wwn_, vpd_assoc_logical_unit); | 1575 | CONFIGFS_ATTR_RO(target_wwn_, vpd_assoc_logical_unit); |
@@ -1450,6 +1578,8 @@ CONFIGFS_ATTR_RO(target_wwn_, vpd_assoc_scsi_target_device); | |||
1450 | 1578 | ||
1451 | static struct configfs_attribute *target_core_dev_wwn_attrs[] = { | 1579 | static struct configfs_attribute *target_core_dev_wwn_attrs[] = { |
1452 | &target_wwn_attr_vendor_id, | 1580 | &target_wwn_attr_vendor_id, |
1581 | &target_wwn_attr_product_id, | ||
1582 | &target_wwn_attr_revision, | ||
1453 | &target_wwn_attr_vpd_unit_serial, | 1583 | &target_wwn_attr_vpd_unit_serial, |
1454 | &target_wwn_attr_vpd_protocol_identifier, | 1584 | &target_wwn_attr_vpd_protocol_identifier, |
1455 | &target_wwn_attr_vpd_assoc_logical_unit, | 1585 | &target_wwn_attr_vpd_assoc_logical_unit, |
@@ -1494,11 +1624,12 @@ static ssize_t target_core_dev_pr_show_spc3_res(struct se_device *dev, | |||
1494 | static ssize_t target_core_dev_pr_show_spc2_res(struct se_device *dev, | 1624 | static ssize_t target_core_dev_pr_show_spc2_res(struct se_device *dev, |
1495 | char *page) | 1625 | char *page) |
1496 | { | 1626 | { |
1627 | struct se_session *sess = dev->reservation_holder; | ||
1497 | struct se_node_acl *se_nacl; | 1628 | struct se_node_acl *se_nacl; |
1498 | ssize_t len; | 1629 | ssize_t len; |
1499 | 1630 | ||
1500 | se_nacl = dev->dev_reserved_node_acl; | 1631 | if (sess) { |
1501 | if (se_nacl) { | 1632 | se_nacl = sess->se_node_acl; |
1502 | len = sprintf(page, | 1633 | len = sprintf(page, |
1503 | "SPC-2 Reservation: %s Initiator: %s\n", | 1634 | "SPC-2 Reservation: %s Initiator: %s\n", |
1504 | se_nacl->se_tpg->se_tpg_tfo->fabric_name, | 1635 | se_nacl->se_tpg->se_tpg_tfo->fabric_name, |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 1f8482b6473b..7eae1c823c4e 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -85,7 +85,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun) | |||
85 | goto out_unlock; | 85 | goto out_unlock; |
86 | } | 86 | } |
87 | 87 | ||
88 | se_cmd->se_lun = rcu_dereference(deve->se_lun); | 88 | se_cmd->se_lun = se_lun; |
89 | se_cmd->pr_res_key = deve->pr_res_key; | 89 | se_cmd->pr_res_key = deve->pr_res_key; |
90 | se_cmd->orig_fe_lun = unpacked_lun; | 90 | se_cmd->orig_fe_lun = unpacked_lun; |
91 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; | 91 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; |
@@ -176,7 +176,7 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u64 unpacked_lun) | |||
176 | goto out_unlock; | 176 | goto out_unlock; |
177 | } | 177 | } |
178 | 178 | ||
179 | se_cmd->se_lun = rcu_dereference(deve->se_lun); | 179 | se_cmd->se_lun = se_lun; |
180 | se_cmd->pr_res_key = deve->pr_res_key; | 180 | se_cmd->pr_res_key = deve->pr_res_key; |
181 | se_cmd->orig_fe_lun = unpacked_lun; | 181 | se_cmd->orig_fe_lun = unpacked_lun; |
182 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; | 182 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 1597a9ebadca..03767693f580 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -111,10 +111,10 @@ target_scsi2_reservation_check(struct se_cmd *cmd) | |||
111 | break; | 111 | break; |
112 | } | 112 | } |
113 | 113 | ||
114 | if (!dev->dev_reserved_node_acl || !sess) | 114 | if (!dev->reservation_holder || !sess) |
115 | return 0; | 115 | return 0; |
116 | 116 | ||
117 | if (dev->dev_reserved_node_acl != sess->se_node_acl) | 117 | if (dev->reservation_holder->se_node_acl != sess->se_node_acl) |
118 | return TCM_RESERVATION_CONFLICT; | 118 | return TCM_RESERVATION_CONFLICT; |
119 | 119 | ||
120 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) { | 120 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) { |
@@ -200,6 +200,16 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd) | |||
200 | return 0; | 200 | return 0; |
201 | } | 201 | } |
202 | 202 | ||
203 | void target_release_reservation(struct se_device *dev) | ||
204 | { | ||
205 | dev->reservation_holder = NULL; | ||
206 | dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS; | ||
207 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) { | ||
208 | dev->dev_res_bin_isid = 0; | ||
209 | dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS_WITH_ISID; | ||
210 | } | ||
211 | } | ||
212 | |||
203 | sense_reason_t | 213 | sense_reason_t |
204 | target_scsi2_reservation_release(struct se_cmd *cmd) | 214 | target_scsi2_reservation_release(struct se_cmd *cmd) |
205 | { | 215 | { |
@@ -217,21 +227,16 @@ target_scsi2_reservation_release(struct se_cmd *cmd) | |||
217 | return TCM_RESERVATION_CONFLICT; | 227 | return TCM_RESERVATION_CONFLICT; |
218 | 228 | ||
219 | spin_lock(&dev->dev_reservation_lock); | 229 | spin_lock(&dev->dev_reservation_lock); |
220 | if (!dev->dev_reserved_node_acl || !sess) | 230 | if (!dev->reservation_holder || !sess) |
221 | goto out_unlock; | 231 | goto out_unlock; |
222 | 232 | ||
223 | if (dev->dev_reserved_node_acl != sess->se_node_acl) | 233 | if (dev->reservation_holder->se_node_acl != sess->se_node_acl) |
224 | goto out_unlock; | 234 | goto out_unlock; |
225 | 235 | ||
226 | if (dev->dev_res_bin_isid != sess->sess_bin_isid) | 236 | if (dev->dev_res_bin_isid != sess->sess_bin_isid) |
227 | goto out_unlock; | 237 | goto out_unlock; |
228 | 238 | ||
229 | dev->dev_reserved_node_acl = NULL; | 239 | target_release_reservation(dev); |
230 | dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS; | ||
231 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) { | ||
232 | dev->dev_res_bin_isid = 0; | ||
233 | dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS_WITH_ISID; | ||
234 | } | ||
235 | tpg = sess->se_tpg; | 240 | tpg = sess->se_tpg; |
236 | pr_debug("SCSI-2 Released reservation for %s LUN: %llu ->" | 241 | pr_debug("SCSI-2 Released reservation for %s LUN: %llu ->" |
237 | " MAPPED LUN: %llu for %s\n", | 242 | " MAPPED LUN: %llu for %s\n", |
@@ -275,13 +280,13 @@ target_scsi2_reservation_reserve(struct se_cmd *cmd) | |||
275 | 280 | ||
276 | tpg = sess->se_tpg; | 281 | tpg = sess->se_tpg; |
277 | spin_lock(&dev->dev_reservation_lock); | 282 | spin_lock(&dev->dev_reservation_lock); |
278 | if (dev->dev_reserved_node_acl && | 283 | if (dev->reservation_holder && |
279 | (dev->dev_reserved_node_acl != sess->se_node_acl)) { | 284 | dev->reservation_holder->se_node_acl != sess->se_node_acl) { |
280 | pr_err("SCSI-2 RESERVATION CONFLIFT for %s fabric\n", | 285 | pr_err("SCSI-2 RESERVATION CONFLIFT for %s fabric\n", |
281 | tpg->se_tpg_tfo->fabric_name); | 286 | tpg->se_tpg_tfo->fabric_name); |
282 | pr_err("Original reserver LUN: %llu %s\n", | 287 | pr_err("Original reserver LUN: %llu %s\n", |
283 | cmd->se_lun->unpacked_lun, | 288 | cmd->se_lun->unpacked_lun, |
284 | dev->dev_reserved_node_acl->initiatorname); | 289 | dev->reservation_holder->se_node_acl->initiatorname); |
285 | pr_err("Current attempt - LUN: %llu -> MAPPED LUN: %llu" | 290 | pr_err("Current attempt - LUN: %llu -> MAPPED LUN: %llu" |
286 | " from %s \n", cmd->se_lun->unpacked_lun, | 291 | " from %s \n", cmd->se_lun->unpacked_lun, |
287 | cmd->orig_fe_lun, | 292 | cmd->orig_fe_lun, |
@@ -290,7 +295,7 @@ target_scsi2_reservation_reserve(struct se_cmd *cmd) | |||
290 | goto out_unlock; | 295 | goto out_unlock; |
291 | } | 296 | } |
292 | 297 | ||
293 | dev->dev_reserved_node_acl = sess->se_node_acl; | 298 | dev->reservation_holder = sess; |
294 | dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS; | 299 | dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS; |
295 | if (sess->sess_bin_isid != 0) { | 300 | if (sess->sess_bin_isid != 0) { |
296 | dev->dev_res_bin_isid = sess->sess_bin_isid; | 301 | dev->dev_res_bin_isid = sess->sess_bin_isid; |
diff --git a/drivers/target/target_core_pr.h b/drivers/target/target_core_pr.h index 198fad5c89dc..a31c93e4e19c 100644 --- a/drivers/target/target_core_pr.h +++ b/drivers/target/target_core_pr.h | |||
@@ -58,6 +58,7 @@ extern struct kmem_cache *t10_pr_reg_cache; | |||
58 | 58 | ||
59 | extern void core_pr_dump_initiator_port(struct t10_pr_registration *, | 59 | extern void core_pr_dump_initiator_port(struct t10_pr_registration *, |
60 | char *, u32); | 60 | char *, u32); |
61 | extern void target_release_reservation(struct se_device *dev); | ||
61 | extern sense_reason_t target_scsi2_reservation_release(struct se_cmd *); | 62 | extern sense_reason_t target_scsi2_reservation_release(struct se_cmd *); |
62 | extern sense_reason_t target_scsi2_reservation_reserve(struct se_cmd *); | 63 | extern sense_reason_t target_scsi2_reservation_reserve(struct se_cmd *); |
63 | extern int core_scsi3_alloc_aptpl_registration( | 64 | extern int core_scsi3_alloc_aptpl_registration( |
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 3a1bb799a9ab..344df737f3a3 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c | |||
@@ -390,7 +390,7 @@ int core_tmr_lun_reset( | |||
390 | if (!preempt_and_abort_list && | 390 | if (!preempt_and_abort_list && |
391 | (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)) { | 391 | (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)) { |
392 | spin_lock(&dev->dev_reservation_lock); | 392 | spin_lock(&dev->dev_reservation_lock); |
393 | dev->dev_reserved_node_acl = NULL; | 393 | dev->reservation_holder = NULL; |
394 | dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS; | 394 | dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS; |
395 | spin_unlock(&dev->dev_reservation_lock); | 395 | spin_unlock(&dev->dev_reservation_lock); |
396 | pr_debug("LUN_RESET: SCSI-2 Released reservation\n"); | 396 | pr_debug("LUN_RESET: SCSI-2 Released reservation\n"); |
diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c index 9be1418e919f..e59a896ac58a 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c | |||
@@ -389,7 +389,6 @@ out: | |||
389 | */ | 389 | */ |
390 | 390 | ||
391 | struct xcopy_pt_cmd { | 391 | struct xcopy_pt_cmd { |
392 | bool remote_port; | ||
393 | struct se_cmd se_cmd; | 392 | struct se_cmd se_cmd; |
394 | struct completion xpt_passthrough_sem; | 393 | struct completion xpt_passthrough_sem; |
395 | unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER]; | 394 | unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER]; |
@@ -506,72 +505,20 @@ void target_xcopy_release_pt(void) | |||
506 | destroy_workqueue(xcopy_wq); | 505 | destroy_workqueue(xcopy_wq); |
507 | } | 506 | } |
508 | 507 | ||
509 | static void target_xcopy_setup_pt_port( | 508 | /* |
510 | struct xcopy_pt_cmd *xpt_cmd, | 509 | * target_xcopy_setup_pt_cmd - set up a pass-through command |
511 | struct xcopy_op *xop, | 510 | * @xpt_cmd: Data structure to initialize. |
512 | bool remote_port) | 511 | * @xop: Describes the XCOPY operation received from an initiator. |
513 | { | 512 | * @se_dev: Backend device to associate with @xpt_cmd if |
514 | struct se_cmd *ec_cmd = xop->xop_se_cmd; | 513 | * @remote_port == true. |
515 | struct se_cmd *pt_cmd = &xpt_cmd->se_cmd; | 514 | * @cdb: SCSI CDB to be copied into @xpt_cmd. |
516 | 515 | * @remote_port: If false, use the LUN through which the XCOPY command has | |
517 | if (xop->op_origin == XCOL_SOURCE_RECV_OP) { | 516 | * been received. If true, use @se_dev->xcopy_lun. |
518 | /* | 517 | * @alloc_mem: Whether or not to allocate an SGL list. |
519 | * Honor destination port reservations for X-COPY PUSH emulation | 518 | * |
520 | * when CDB is received on local source port, and READs blocks to | 519 | * Set up a SCSI command (READ or WRITE) that will be used to execute an |
521 | * WRITE on remote destination port. | 520 | * XCOPY command. |
522 | */ | 521 | */ |
523 | if (remote_port) { | ||
524 | xpt_cmd->remote_port = remote_port; | ||
525 | } else { | ||
526 | pt_cmd->se_lun = ec_cmd->se_lun; | ||
527 | pt_cmd->se_dev = ec_cmd->se_dev; | ||
528 | |||
529 | pr_debug("Honoring local SRC port from ec_cmd->se_dev:" | ||
530 | " %p\n", pt_cmd->se_dev); | ||
531 | pt_cmd->se_lun = ec_cmd->se_lun; | ||
532 | pr_debug("Honoring local SRC port from ec_cmd->se_lun: %p\n", | ||
533 | pt_cmd->se_lun); | ||
534 | } | ||
535 | } else { | ||
536 | /* | ||
537 | * Honor source port reservation for X-COPY PULL emulation | ||
538 | * when CDB is received on local desintation port, and READs | ||
539 | * blocks from the remote source port to WRITE on local | ||
540 | * destination port. | ||
541 | */ | ||
542 | if (remote_port) { | ||
543 | xpt_cmd->remote_port = remote_port; | ||
544 | } else { | ||
545 | pt_cmd->se_lun = ec_cmd->se_lun; | ||
546 | pt_cmd->se_dev = ec_cmd->se_dev; | ||
547 | |||
548 | pr_debug("Honoring local DST port from ec_cmd->se_dev:" | ||
549 | " %p\n", pt_cmd->se_dev); | ||
550 | pt_cmd->se_lun = ec_cmd->se_lun; | ||
551 | pr_debug("Honoring local DST port from ec_cmd->se_lun: %p\n", | ||
552 | pt_cmd->se_lun); | ||
553 | } | ||
554 | } | ||
555 | } | ||
556 | |||
557 | static void target_xcopy_init_pt_lun(struct se_device *se_dev, | ||
558 | struct se_cmd *pt_cmd, bool remote_port) | ||
559 | { | ||
560 | /* | ||
561 | * Don't allocate + init an pt_cmd->se_lun if honoring local port for | ||
562 | * reservations. The pt_cmd->se_lun pointer will be setup from within | ||
563 | * target_xcopy_setup_pt_port() | ||
564 | */ | ||
565 | if (remote_port) { | ||
566 | pr_debug("Setup emulated se_dev: %p from se_dev\n", | ||
567 | pt_cmd->se_dev); | ||
568 | pt_cmd->se_lun = &se_dev->xcopy_lun; | ||
569 | pt_cmd->se_dev = se_dev; | ||
570 | } | ||
571 | |||
572 | pt_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; | ||
573 | } | ||
574 | |||
575 | static int target_xcopy_setup_pt_cmd( | 522 | static int target_xcopy_setup_pt_cmd( |
576 | struct xcopy_pt_cmd *xpt_cmd, | 523 | struct xcopy_pt_cmd *xpt_cmd, |
577 | struct xcopy_op *xop, | 524 | struct xcopy_op *xop, |
@@ -583,12 +530,19 @@ static int target_xcopy_setup_pt_cmd( | |||
583 | struct se_cmd *cmd = &xpt_cmd->se_cmd; | 530 | struct se_cmd *cmd = &xpt_cmd->se_cmd; |
584 | sense_reason_t sense_rc; | 531 | sense_reason_t sense_rc; |
585 | int ret = 0, rc; | 532 | int ret = 0, rc; |
533 | |||
586 | /* | 534 | /* |
587 | * Setup LUN+port to honor reservations based upon xop->op_origin for | 535 | * Setup LUN+port to honor reservations based upon xop->op_origin for |
588 | * X-COPY PUSH or X-COPY PULL based upon where the CDB was received. | 536 | * X-COPY PUSH or X-COPY PULL based upon where the CDB was received. |
589 | */ | 537 | */ |
590 | target_xcopy_init_pt_lun(se_dev, cmd, remote_port); | 538 | if (remote_port) { |
591 | target_xcopy_setup_pt_port(xpt_cmd, xop, remote_port); | 539 | cmd->se_lun = &se_dev->xcopy_lun; |
540 | cmd->se_dev = se_dev; | ||
541 | } else { | ||
542 | cmd->se_lun = xop->xop_se_cmd->se_lun; | ||
543 | cmd->se_dev = xop->xop_se_cmd->se_dev; | ||
544 | } | ||
545 | cmd->se_cmd_flags |= SCF_SE_LUN_CMD; | ||
592 | 546 | ||
593 | cmd->tag = 0; | 547 | cmd->tag = 0; |
594 | sense_rc = target_setup_cmd_from_cdb(cmd, cdb); | 548 | sense_rc = target_setup_cmd_from_cdb(cmd, cdb); |
diff --git a/include/linux/nvme-fc-driver.h b/include/linux/nvme-fc-driver.h index 2bb349035431..c48e96436f56 100644 --- a/include/linux/nvme-fc-driver.h +++ b/include/linux/nvme-fc-driver.h | |||
@@ -17,12 +17,6 @@ | |||
17 | 17 | ||
18 | 18 | ||
19 | 19 | ||
20 | /* FC Port role bitmask - can merge with FC Port Roles in fc transport */ | ||
21 | #define FC_PORT_ROLE_NVME_INITIATOR 0x10 | ||
22 | #define FC_PORT_ROLE_NVME_TARGET 0x20 | ||
23 | #define FC_PORT_ROLE_NVME_DISCOVERY 0x40 | ||
24 | |||
25 | |||
26 | /** | 20 | /** |
27 | * struct nvme_fc_port_info - port-specific ids and FC connection-specific | 21 | * struct nvme_fc_port_info - port-specific ids and FC connection-specific |
28 | * data element used during NVME Host role | 22 | * data element used during NVME Host role |
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 56b2dba7d911..b08febec7895 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h | |||
@@ -224,6 +224,13 @@ struct sas_work { | |||
224 | struct work_struct work; | 224 | struct work_struct work; |
225 | }; | 225 | }; |
226 | 226 | ||
227 | /* Lots of code duplicates this in the SCSI tree, which can be factored out */ | ||
228 | static inline bool sas_dev_type_is_expander(enum sas_device_type type) | ||
229 | { | ||
230 | return type == SAS_EDGE_EXPANDER_DEVICE || | ||
231 | type == SAS_FANOUT_EXPANDER_DEVICE; | ||
232 | } | ||
233 | |||
227 | static inline void INIT_SAS_WORK(struct sas_work *sw, void (*fn)(struct work_struct *)) | 234 | static inline void INIT_SAS_WORK(struct sas_work *sw, void (*fn)(struct work_struct *)) |
228 | { | 235 | { |
229 | INIT_WORK(&sw->work, fn); | 236 | INIT_WORK(&sw->work, fn); |
@@ -245,9 +252,9 @@ static inline struct sas_discovery_event *to_sas_discovery_event(struct work_str | |||
245 | struct sas_discovery { | 252 | struct sas_discovery { |
246 | struct sas_discovery_event disc_work[DISC_NUM_EVENTS]; | 253 | struct sas_discovery_event disc_work[DISC_NUM_EVENTS]; |
247 | unsigned long pending; | 254 | unsigned long pending; |
248 | u8 fanout_sas_addr[8]; | 255 | u8 fanout_sas_addr[SAS_ADDR_SIZE]; |
249 | u8 eeds_a[8]; | 256 | u8 eeds_a[SAS_ADDR_SIZE]; |
250 | u8 eeds_b[8]; | 257 | u8 eeds_b[SAS_ADDR_SIZE]; |
251 | int max_level; | 258 | int max_level; |
252 | }; | 259 | }; |
253 | 260 | ||
diff --git a/include/scsi/osd_attributes.h b/include/scsi/osd_attributes.h deleted file mode 100644 index 8a6acd054e4e..000000000000 --- a/include/scsi/osd_attributes.h +++ /dev/null | |||
@@ -1,398 +0,0 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | #ifndef __OSD_ATTRIBUTES_H__ | ||
3 | #define __OSD_ATTRIBUTES_H__ | ||
4 | |||
5 | #include <scsi/osd_protocol.h> | ||
6 | |||
7 | /* | ||
8 | * Contains types and constants that define attribute pages and attribute | ||
9 | * numbers and their data types. | ||
10 | */ | ||
11 | |||
12 | #define ATTR_SET(pg, id, l, ptr) \ | ||
13 | { .attr_page = pg, .attr_id = id, .len = l, .val_ptr = ptr } | ||
14 | |||
15 | #define ATTR_DEF(pg, id, l) ATTR_SET(pg, id, l, NULL) | ||
16 | |||
17 | /* osd-r10 4.7.3 Attributes pages */ | ||
18 | enum { | ||
19 | OSD_APAGE_OBJECT_FIRST = 0x0, | ||
20 | OSD_APAGE_OBJECT_DIRECTORY = 0, | ||
21 | OSD_APAGE_OBJECT_INFORMATION = 1, | ||
22 | OSD_APAGE_OBJECT_QUOTAS = 2, | ||
23 | OSD_APAGE_OBJECT_TIMESTAMP = 3, | ||
24 | OSD_APAGE_OBJECT_COLLECTIONS = 4, | ||
25 | OSD_APAGE_OBJECT_SECURITY = 5, | ||
26 | OSD_APAGE_OBJECT_LAST = 0x2fffffff, | ||
27 | |||
28 | OSD_APAGE_PARTITION_FIRST = 0x30000000, | ||
29 | OSD_APAGE_PARTITION_DIRECTORY = OSD_APAGE_PARTITION_FIRST + 0, | ||
30 | OSD_APAGE_PARTITION_INFORMATION = OSD_APAGE_PARTITION_FIRST + 1, | ||
31 | OSD_APAGE_PARTITION_QUOTAS = OSD_APAGE_PARTITION_FIRST + 2, | ||
32 | OSD_APAGE_PARTITION_TIMESTAMP = OSD_APAGE_PARTITION_FIRST + 3, | ||
33 | OSD_APAGE_PARTITION_ATTR_ACCESS = OSD_APAGE_PARTITION_FIRST + 4, | ||
34 | OSD_APAGE_PARTITION_SECURITY = OSD_APAGE_PARTITION_FIRST + 5, | ||
35 | OSD_APAGE_PARTITION_LAST = 0x5FFFFFFF, | ||
36 | |||
37 | OSD_APAGE_COLLECTION_FIRST = 0x60000000, | ||
38 | OSD_APAGE_COLLECTION_DIRECTORY = OSD_APAGE_COLLECTION_FIRST + 0, | ||
39 | OSD_APAGE_COLLECTION_INFORMATION = OSD_APAGE_COLLECTION_FIRST + 1, | ||
40 | OSD_APAGE_COLLECTION_TIMESTAMP = OSD_APAGE_COLLECTION_FIRST + 3, | ||
41 | OSD_APAGE_COLLECTION_SECURITY = OSD_APAGE_COLLECTION_FIRST + 5, | ||
42 | OSD_APAGE_COLLECTION_LAST = 0x8FFFFFFF, | ||
43 | |||
44 | OSD_APAGE_ROOT_FIRST = 0x90000000, | ||
45 | OSD_APAGE_ROOT_DIRECTORY = OSD_APAGE_ROOT_FIRST + 0, | ||
46 | OSD_APAGE_ROOT_INFORMATION = OSD_APAGE_ROOT_FIRST + 1, | ||
47 | OSD_APAGE_ROOT_QUOTAS = OSD_APAGE_ROOT_FIRST + 2, | ||
48 | OSD_APAGE_ROOT_TIMESTAMP = OSD_APAGE_ROOT_FIRST + 3, | ||
49 | OSD_APAGE_ROOT_SECURITY = OSD_APAGE_ROOT_FIRST + 5, | ||
50 | OSD_APAGE_ROOT_LAST = 0xBFFFFFFF, | ||
51 | |||
52 | OSD_APAGE_RESERVED_TYPE_FIRST = 0xC0000000, | ||
53 | OSD_APAGE_RESERVED_TYPE_LAST = 0xEFFFFFFF, | ||
54 | |||
55 | OSD_APAGE_COMMON_FIRST = 0xF0000000, | ||
56 | OSD_APAGE_COMMON_LAST = 0xFFFFFFFD, | ||
57 | |||
58 | OSD_APAGE_CURRENT_COMMAND = 0xFFFFFFFE, | ||
59 | |||
60 | OSD_APAGE_REQUEST_ALL = 0xFFFFFFFF, | ||
61 | }; | ||
62 | |||
63 | /* subcategories of attr pages within each range above */ | ||
64 | enum { | ||
65 | OSD_APAGE_STD_FIRST = 0x0, | ||
66 | OSD_APAGE_STD_DIRECTORY = 0, | ||
67 | OSD_APAGE_STD_INFORMATION = 1, | ||
68 | OSD_APAGE_STD_QUOTAS = 2, | ||
69 | OSD_APAGE_STD_TIMESTAMP = 3, | ||
70 | OSD_APAGE_STD_COLLECTIONS = 4, | ||
71 | OSD_APAGE_STD_POLICY_SECURITY = 5, | ||
72 | OSD_APAGE_STD_LAST = 0x0000007F, | ||
73 | |||
74 | OSD_APAGE_RESERVED_FIRST = 0x00000080, | ||
75 | OSD_APAGE_RESERVED_LAST = 0x00007FFF, | ||
76 | |||
77 | OSD_APAGE_OTHER_STD_FIRST = 0x00008000, | ||
78 | OSD_APAGE_OTHER_STD_LAST = 0x0000EFFF, | ||
79 | |||
80 | OSD_APAGE_PUBLIC_FIRST = 0x0000F000, | ||
81 | OSD_APAGE_PUBLIC_LAST = 0x0000FFFF, | ||
82 | |||
83 | OSD_APAGE_APP_DEFINED_FIRST = 0x00010000, | ||
84 | OSD_APAGE_APP_DEFINED_LAST = 0x1FFFFFFF, | ||
85 | |||
86 | OSD_APAGE_VENDOR_SPECIFIC_FIRST = 0x20000000, | ||
87 | OSD_APAGE_VENDOR_SPECIFIC_LAST = 0x2FFFFFFF, | ||
88 | }; | ||
89 | |||
90 | enum { | ||
91 | OSD_ATTR_PAGE_IDENTIFICATION = 0, /* in all pages 40 bytes */ | ||
92 | }; | ||
93 | |||
94 | struct page_identification { | ||
95 | u8 vendor_identification[8]; | ||
96 | u8 page_identification[32]; | ||
97 | } __packed; | ||
98 | |||
99 | struct osd_attr_page_header { | ||
100 | __be32 page_number; | ||
101 | __be32 page_length; | ||
102 | } __packed; | ||
103 | |||
104 | /* 7.1.2.8 Root Information attributes page (OSD_APAGE_ROOT_INFORMATION) */ | ||
105 | enum { | ||
106 | OSD_ATTR_RI_OSD_SYSTEM_ID = 0x3, /* 20 */ | ||
107 | OSD_ATTR_RI_VENDOR_IDENTIFICATION = 0x4, /* 8 */ | ||
108 | OSD_ATTR_RI_PRODUCT_IDENTIFICATION = 0x5, /* 16 */ | ||
109 | OSD_ATTR_RI_PRODUCT_MODEL = 0x6, /* 32 */ | ||
110 | OSD_ATTR_RI_PRODUCT_REVISION_LEVEL = 0x7, /* 4 */ | ||
111 | OSD_ATTR_RI_PRODUCT_SERIAL_NUMBER = 0x8, /* variable */ | ||
112 | OSD_ATTR_RI_OSD_NAME = 0x9, /* variable */ | ||
113 | OSD_ATTR_RI_MAX_CDB_CONTINUATION_LEN = 0xA, /* 4 */ | ||
114 | OSD_ATTR_RI_TOTAL_CAPACITY = 0x80, /* 8 */ | ||
115 | OSD_ATTR_RI_USED_CAPACITY = 0x81, /* 8 */ | ||
116 | OSD_ATTR_RI_NUMBER_OF_PARTITIONS = 0xC0, /* 8 */ | ||
117 | OSD_ATTR_RI_CLOCK = 0x100, /* 6 */ | ||
118 | OARI_DEFAULT_ISOLATION_METHOD = 0X110, /* 1 */ | ||
119 | OARI_SUPPORTED_ISOLATION_METHODS = 0X111, /* 32 */ | ||
120 | |||
121 | OARI_DATA_ATOMICITY_GUARANTEE = 0X120, /* 8 */ | ||
122 | OARI_DATA_ATOMICITY_ALIGNMENT = 0X121, /* 8 */ | ||
123 | OARI_ATTRIBUTES_ATOMICITY_GUARANTEE = 0X122, /* 8 */ | ||
124 | OARI_DATA_ATTRIBUTES_ATOMICITY_MULTIPLIER = 0X123, /* 1 */ | ||
125 | |||
126 | OARI_MAXIMUM_SNAPSHOTS_COUNT = 0X1C1, /* 0 or 4 */ | ||
127 | OARI_MAXIMUM_CLONES_COUNT = 0X1C2, /* 0 or 4 */ | ||
128 | OARI_MAXIMUM_BRANCH_DEPTH = 0X1CC, /* 0 or 4 */ | ||
129 | OARI_SUPPORTED_OBJECT_DUPLICATION_METHOD_FIRST = 0X200, /* 0 or 4 */ | ||
130 | OARI_SUPPORTED_OBJECT_DUPLICATION_METHOD_LAST = 0X2ff, /* 0 or 4 */ | ||
131 | OARI_SUPPORTED_TIME_OF_DUPLICATION_METHOD_FIRST = 0X300, /* 0 or 4 */ | ||
132 | OARI_SUPPORTED_TIME_OF_DUPLICATION_METHOD_LAST = 0X30F, /* 0 or 4 */ | ||
133 | OARI_SUPPORT_FOR_DUPLICATED_OBJECT_FREEZING = 0X310, /* 0 or 4 */ | ||
134 | OARI_SUPPORT_FOR_SNAPSHOT_REFRESHING = 0X311, /* 0 or 1 */ | ||
135 | OARI_SUPPORTED_CDB_CONTINUATION_DESC_TYPE_FIRST = 0X7000001,/* 0 or 4 */ | ||
136 | OARI_SUPPORTED_CDB_CONTINUATION_DESC_TYPE_LAST = 0X700FFFF,/* 0 or 4 */ | ||
137 | }; | ||
138 | /* Root_Information_attributes_page does not have a get_page structure */ | ||
139 | |||
140 | /* 7.1.2.9 Partition Information attributes page | ||
141 | * (OSD_APAGE_PARTITION_INFORMATION) | ||
142 | */ | ||
143 | enum { | ||
144 | OSD_ATTR_PI_PARTITION_ID = 0x1, /* 8 */ | ||
145 | OSD_ATTR_PI_USERNAME = 0x9, /* variable */ | ||
146 | OSD_ATTR_PI_USED_CAPACITY = 0x81, /* 8 */ | ||
147 | OSD_ATTR_PI_USED_CAPACITY_INCREMENT = 0x84, /* 0 or 8 */ | ||
148 | OSD_ATTR_PI_NUMBER_OF_OBJECTS = 0xC1, /* 8 */ | ||
149 | |||
150 | OSD_ATTR_PI_ACTUAL_DATA_SPACE = 0xD1, /* 0 or 8 */ | ||
151 | OSD_ATTR_PI_RESERVED_DATA_SPACE = 0xD2, /* 0 or 8 */ | ||
152 | OSD_ATTR_PI_DEFAULT_SNAPSHOT_DUPLICATION_METHOD = 0x200,/* 0 or 4 */ | ||
153 | OSD_ATTR_PI_DEFAULT_CLONE_DUPLICATION_METHOD = 0x201,/* 0 or 4 */ | ||
154 | OSD_ATTR_PI_DEFAULT_SP_TIME_OF_DUPLICATION = 0x300,/* 0 or 4 */ | ||
155 | OSD_ATTR_PI_DEFAULT_CLONE_TIME_OF_DUPLICATION = 0x301,/* 0 or 4 */ | ||
156 | }; | ||
157 | /* Partition Information attributes page does not have a get_page structure */ | ||
158 | |||
159 | /* 7.1.2.10 Collection Information attributes page | ||
160 | * (OSD_APAGE_COLLECTION_INFORMATION) | ||
161 | */ | ||
162 | enum { | ||
163 | OSD_ATTR_CI_PARTITION_ID = 0x1, /* 8 */ | ||
164 | OSD_ATTR_CI_COLLECTION_OBJECT_ID = 0x2, /* 8 */ | ||
165 | OSD_ATTR_CI_USERNAME = 0x9, /* variable */ | ||
166 | OSD_ATTR_CI_COLLECTION_TYPE = 0xA, /* 1 */ | ||
167 | OSD_ATTR_CI_USED_CAPACITY = 0x81, /* 8 */ | ||
168 | }; | ||
169 | /* Collection Information attributes page does not have a get_page structure */ | ||
170 | |||
171 | /* 7.1.2.11 User Object Information attributes page | ||
172 | * (OSD_APAGE_OBJECT_INFORMATION) | ||
173 | */ | ||
174 | enum { | ||
175 | OSD_ATTR_OI_PARTITION_ID = 0x1, /* 8 */ | ||
176 | OSD_ATTR_OI_OBJECT_ID = 0x2, /* 8 */ | ||
177 | OSD_ATTR_OI_USERNAME = 0x9, /* variable */ | ||
178 | OSD_ATTR_OI_USED_CAPACITY = 0x81, /* 8 */ | ||
179 | OSD_ATTR_OI_LOGICAL_LENGTH = 0x82, /* 8 */ | ||
180 | SD_ATTR_OI_ACTUAL_DATA_SPACE = 0XD1, /* 0 OR 8 */ | ||
181 | SD_ATTR_OI_RESERVED_DATA_SPACE = 0XD2, /* 0 OR 8 */ | ||
182 | }; | ||
183 | /* Object Information attributes page does not have a get_page structure */ | ||
184 | |||
185 | /* 7.1.2.12 Root Quotas attributes page (OSD_APAGE_ROOT_QUOTAS) */ | ||
186 | enum { | ||
187 | OSD_ATTR_RQ_DEFAULT_MAXIMUM_USER_OBJECT_LENGTH = 0x1, /* 8 */ | ||
188 | OSD_ATTR_RQ_PARTITION_CAPACITY_QUOTA = 0x10001, /* 8 */ | ||
189 | OSD_ATTR_RQ_PARTITION_OBJECT_COUNT = 0x10002, /* 8 */ | ||
190 | OSD_ATTR_RQ_PARTITION_COLLECTIONS_PER_USER_OBJECT = 0x10081, /* 4 */ | ||
191 | OSD_ATTR_RQ_PARTITION_COUNT = 0x20002, /* 8 */ | ||
192 | }; | ||
193 | |||
194 | struct Root_Quotas_attributes_page { | ||
195 | struct osd_attr_page_header hdr; /* id=R+2, size=0x24 */ | ||
196 | __be64 default_maximum_user_object_length; | ||
197 | __be64 partition_capacity_quota; | ||
198 | __be64 partition_object_count; | ||
199 | __be64 partition_collections_per_user_object; | ||
200 | __be64 partition_count; | ||
201 | } __packed; | ||
202 | |||
203 | /* 7.1.2.13 Partition Quotas attributes page (OSD_APAGE_PARTITION_QUOTAS)*/ | ||
204 | enum { | ||
205 | OSD_ATTR_PQ_DEFAULT_MAXIMUM_USER_OBJECT_LENGTH = 0x1, /* 8 */ | ||
206 | OSD_ATTR_PQ_CAPACITY_QUOTA = 0x10001, /* 8 */ | ||
207 | OSD_ATTR_PQ_OBJECT_COUNT = 0x10002, /* 8 */ | ||
208 | OSD_ATTR_PQ_COLLECTIONS_PER_USER_OBJECT = 0x10081, /* 4 */ | ||
209 | }; | ||
210 | |||
211 | struct Partition_Quotas_attributes_page { | ||
212 | struct osd_attr_page_header hdr; /* id=P+2, size=0x1C */ | ||
213 | __be64 default_maximum_user_object_length; | ||
214 | __be64 capacity_quota; | ||
215 | __be64 object_count; | ||
216 | __be64 collections_per_user_object; | ||
217 | } __packed; | ||
218 | |||
219 | /* 7.1.2.14 User Object Quotas attributes page (OSD_APAGE_OBJECT_QUOTAS) */ | ||
220 | enum { | ||
221 | OSD_ATTR_OQ_MAXIMUM_LENGTH = 0x1, /* 8 */ | ||
222 | }; | ||
223 | |||
224 | struct Object_Quotas_attributes_page { | ||
225 | struct osd_attr_page_header hdr; /* id=U+2, size=0x8 */ | ||
226 | __be64 maximum_length; | ||
227 | } __packed; | ||
228 | |||
229 | /* 7.1.2.15 Root Timestamps attributes page (OSD_APAGE_ROOT_TIMESTAMP) */ | ||
230 | enum { | ||
231 | OSD_ATTR_RT_ATTRIBUTES_ACCESSED_TIME = 0x2, /* 6 */ | ||
232 | OSD_ATTR_RT_ATTRIBUTES_MODIFIED_TIME = 0x3, /* 6 */ | ||
233 | OSD_ATTR_RT_TIMESTAMP_BYPASS = 0xFFFFFFFE, /* 1 */ | ||
234 | }; | ||
235 | |||
236 | struct root_timestamps_attributes_page { | ||
237 | struct osd_attr_page_header hdr; /* id=R+3, size=0xD */ | ||
238 | struct osd_timestamp attributes_accessed_time; | ||
239 | struct osd_timestamp attributes_modified_time; | ||
240 | u8 timestamp_bypass; | ||
241 | } __packed; | ||
242 | |||
243 | /* 7.1.2.16 Partition Timestamps attributes page | ||
244 | * (OSD_APAGE_PARTITION_TIMESTAMP) | ||
245 | */ | ||
246 | enum { | ||
247 | OSD_ATTR_PT_CREATED_TIME = 0x1, /* 6 */ | ||
248 | OSD_ATTR_PT_ATTRIBUTES_ACCESSED_TIME = 0x2, /* 6 */ | ||
249 | OSD_ATTR_PT_ATTRIBUTES_MODIFIED_TIME = 0x3, /* 6 */ | ||
250 | OSD_ATTR_PT_DATA_ACCESSED_TIME = 0x4, /* 6 */ | ||
251 | OSD_ATTR_PT_DATA_MODIFIED_TIME = 0x5, /* 6 */ | ||
252 | OSD_ATTR_PT_TIMESTAMP_BYPASS = 0xFFFFFFFE, /* 1 */ | ||
253 | }; | ||
254 | |||
255 | struct partition_timestamps_attributes_page { | ||
256 | struct osd_attr_page_header hdr; /* id=P+3, size=0x1F */ | ||
257 | struct osd_timestamp created_time; | ||
258 | struct osd_timestamp attributes_accessed_time; | ||
259 | struct osd_timestamp attributes_modified_time; | ||
260 | struct osd_timestamp data_accessed_time; | ||
261 | struct osd_timestamp data_modified_time; | ||
262 | u8 timestamp_bypass; | ||
263 | } __packed; | ||
264 | |||
265 | /* 7.1.2.17/18 Collection/Object Timestamps attributes page | ||
266 | * (OSD_APAGE_COLLECTION_TIMESTAMP/OSD_APAGE_OBJECT_TIMESTAMP) | ||
267 | */ | ||
268 | enum { | ||
269 | OSD_ATTR_OT_CREATED_TIME = 0x1, /* 6 */ | ||
270 | OSD_ATTR_OT_ATTRIBUTES_ACCESSED_TIME = 0x2, /* 6 */ | ||
271 | OSD_ATTR_OT_ATTRIBUTES_MODIFIED_TIME = 0x3, /* 6 */ | ||
272 | OSD_ATTR_OT_DATA_ACCESSED_TIME = 0x4, /* 6 */ | ||
273 | OSD_ATTR_OT_DATA_MODIFIED_TIME = 0x5, /* 6 */ | ||
274 | }; | ||
275 | |||
276 | /* same for collection */ | ||
277 | struct object_timestamps_attributes_page { | ||
278 | struct osd_attr_page_header hdr; /* id=C+3/3, size=0x1E */ | ||
279 | struct osd_timestamp created_time; | ||
280 | struct osd_timestamp attributes_accessed_time; | ||
281 | struct osd_timestamp attributes_modified_time; | ||
282 | struct osd_timestamp data_accessed_time; | ||
283 | struct osd_timestamp data_modified_time; | ||
284 | } __packed; | ||
285 | |||
286 | /* OSD2r05: 7.1.3.19 Attributes Access attributes page | ||
287 | * (OSD_APAGE_PARTITION_ATTR_ACCESS) | ||
288 | * | ||
289 | * each attribute is of the form below. Total array length is deduced | ||
290 | * from the attribute's length | ||
291 | * (See allowed_attributes_access of the struct osd_cap_object_descriptor) | ||
292 | */ | ||
293 | struct attributes_access_attr { | ||
294 | struct osd_attributes_list_attrid attr_list[0]; | ||
295 | } __packed; | ||
296 | |||
297 | /* OSD2r05: 7.1.2.21 Collections attributes page */ | ||
298 | /* TBD */ | ||
299 | |||
300 | /* 7.1.2.20 Root Policy/Security attributes page (OSD_APAGE_ROOT_SECURITY) */ | ||
301 | enum { | ||
302 | OSD_ATTR_RS_DEFAULT_SECURITY_METHOD = 0x1, /* 1 */ | ||
303 | OSD_ATTR_RS_OLDEST_VALID_NONCE_LIMIT = 0x2, /* 6 */ | ||
304 | OSD_ATTR_RS_NEWEST_VALID_NONCE_LIMIT = 0x3, /* 6 */ | ||
305 | OSD_ATTR_RS_PARTITION_DEFAULT_SECURITY_METHOD = 0x6, /* 1 */ | ||
306 | OSD_ATTR_RS_SUPPORTED_SECURITY_METHODS = 0x7, /* 2 */ | ||
307 | OSD_ATTR_RS_ADJUSTABLE_CLOCK = 0x9, /* 6 */ | ||
308 | OSD_ATTR_RS_MASTER_KEY_IDENTIFIER = 0x7FFD, /* 0 or 7 */ | ||
309 | OSD_ATTR_RS_ROOT_KEY_IDENTIFIER = 0x7FFE, /* 0 or 7 */ | ||
310 | OSD_ATTR_RS_SUPPORTED_INTEGRITY_ALGORITHM_0 = 0x80000000,/* 1,(x16)*/ | ||
311 | OSD_ATTR_RS_SUPPORTED_DH_GROUP_0 = 0x80000010,/* 1,(x16)*/ | ||
312 | }; | ||
313 | |||
314 | struct root_security_attributes_page { | ||
315 | struct osd_attr_page_header hdr; /* id=R+5, size=0x3F */ | ||
316 | u8 default_security_method; | ||
317 | u8 partition_default_security_method; | ||
318 | __be16 supported_security_methods; | ||
319 | u8 mki_valid_rki_valid; | ||
320 | struct osd_timestamp oldest_valid_nonce_limit; | ||
321 | struct osd_timestamp newest_valid_nonce_limit; | ||
322 | struct osd_timestamp adjustable_clock; | ||
323 | u8 master_key_identifier[32-25]; | ||
324 | u8 root_key_identifier[39-32]; | ||
325 | u8 supported_integrity_algorithm[16]; | ||
326 | u8 supported_dh_group[16]; | ||
327 | } __packed; | ||
328 | |||
329 | /* 7.1.2.21 Partition Policy/Security attributes page | ||
330 | * (OSD_APAGE_PARTITION_SECURITY) | ||
331 | */ | ||
332 | enum { | ||
333 | OSD_ATTR_PS_DEFAULT_SECURITY_METHOD = 0x1, /* 1 */ | ||
334 | OSD_ATTR_PS_OLDEST_VALID_NONCE = 0x2, /* 6 */ | ||
335 | OSD_ATTR_PS_NEWEST_VALID_NONCE = 0x3, /* 6 */ | ||
336 | OSD_ATTR_PS_REQUEST_NONCE_LIST_DEPTH = 0x4, /* 2 */ | ||
337 | OSD_ATTR_PS_FROZEN_WORKING_KEY_BIT_MASK = 0x5, /* 2 */ | ||
338 | OSD_ATTR_PS_PARTITION_KEY_IDENTIFIER = 0x7FFF, /* 0 or 7 */ | ||
339 | OSD_ATTR_PS_WORKING_KEY_IDENTIFIER_FIRST = 0x8000, /* 0 or 7 */ | ||
340 | OSD_ATTR_PS_WORKING_KEY_IDENTIFIER_LAST = 0x800F, /* 0 or 7 */ | ||
341 | OSD_ATTR_PS_POLICY_ACCESS_TAG = 0x40000001, /* 4 */ | ||
342 | OSD_ATTR_PS_USER_OBJECT_POLICY_ACCESS_TAG = 0x40000002, /* 4 */ | ||
343 | }; | ||
344 | |||
345 | struct partition_security_attributes_page { | ||
346 | struct osd_attr_page_header hdr; /* id=p+5, size=0x8f */ | ||
347 | u8 reserved[3]; | ||
348 | u8 default_security_method; | ||
349 | struct osd_timestamp oldest_valid_nonce; | ||
350 | struct osd_timestamp newest_valid_nonce; | ||
351 | __be16 request_nonce_list_depth; | ||
352 | __be16 frozen_working_key_bit_mask; | ||
353 | __be32 policy_access_tag; | ||
354 | __be32 user_object_policy_access_tag; | ||
355 | u8 pki_valid; | ||
356 | __be16 wki_00_0f_vld; | ||
357 | struct osd_key_identifier partition_key_identifier; | ||
358 | struct osd_key_identifier working_key_identifiers[16]; | ||
359 | } __packed; | ||
360 | |||
361 | /* 7.1.2.22/23 Collection/Object Policy-Security attributes page | ||
362 | * (OSD_APAGE_COLLECTION_SECURITY/OSD_APAGE_OBJECT_SECURITY) | ||
363 | */ | ||
364 | enum { | ||
365 | OSD_ATTR_OS_POLICY_ACCESS_TAG = 0x40000001, /* 4 */ | ||
366 | }; | ||
367 | |||
368 | struct object_security_attributes_page { | ||
369 | struct osd_attr_page_header hdr; /* id=C+5/5, size=4 */ | ||
370 | __be32 policy_access_tag; | ||
371 | } __packed; | ||
372 | |||
373 | /* OSD2r05: 7.1.3.31 Current Command attributes page | ||
374 | * (OSD_APAGE_CURRENT_COMMAND) | ||
375 | */ | ||
376 | enum { | ||
377 | OSD_ATTR_CC_RESPONSE_INTEGRITY_CHECK_VALUE = 0x1, /* 32 */ | ||
378 | OSD_ATTR_CC_OBJECT_TYPE = 0x2, /* 1 */ | ||
379 | OSD_ATTR_CC_PARTITION_ID = 0x3, /* 8 */ | ||
380 | OSD_ATTR_CC_OBJECT_ID = 0x4, /* 8 */ | ||
381 | OSD_ATTR_CC_STARTING_BYTE_ADDRESS_OF_APPEND = 0x5, /* 8 */ | ||
382 | OSD_ATTR_CC_CHANGE_IN_USED_CAPACITY = 0x6, /* 8 */ | ||
383 | }; | ||
384 | |||
385 | /*TBD: osdv1_current_command_attributes_page */ | ||
386 | |||
387 | struct osdv2_current_command_attributes_page { | ||
388 | struct osd_attr_page_header hdr; /* id=0xFFFFFFFE, size=0x44 */ | ||
389 | u8 response_integrity_check_value[OSD_CRYPTO_KEYID_SIZE]; | ||
390 | u8 object_type; | ||
391 | u8 reserved[3]; | ||
392 | __be64 partition_id; | ||
393 | __be64 object_id; | ||
394 | __be64 starting_byte_address_of_append; | ||
395 | __be64 change_in_used_capacity; | ||
396 | }; | ||
397 | |||
398 | #endif /*ndef __OSD_ATTRIBUTES_H__*/ | ||
diff --git a/include/scsi/osd_protocol.h b/include/scsi/osd_protocol.h deleted file mode 100644 index e0ca835e7bf7..000000000000 --- a/include/scsi/osd_protocol.h +++ /dev/null | |||
@@ -1,676 +0,0 @@ | |||
1 | /* | ||
2 | * osd_protocol.h - OSD T10 standard C definitions. | ||
3 | * | ||
4 | * Copyright (C) 2008 Panasas Inc. All rights reserved. | ||
5 | * | ||
6 | * Authors: | ||
7 | * Boaz Harrosh <ooo@electrozaur.com> | ||
8 | * Benny Halevy <bhalevy@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * | ||
13 | * This file contains types and constants that are defined by the protocol | ||
14 | * Note: All names and symbols are taken from the OSD standard's text. | ||
15 | */ | ||
16 | #ifndef __OSD_PROTOCOL_H__ | ||
17 | #define __OSD_PROTOCOL_H__ | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <asm/unaligned.h> | ||
22 | #include <scsi/scsi.h> | ||
23 | |||
24 | enum { | ||
25 | OSDv1_ADDITIONAL_CDB_LENGTH = 192, | ||
26 | OSDv1_TOTAL_CDB_LEN = OSDv1_ADDITIONAL_CDB_LENGTH + 8, | ||
27 | OSDv1_CAP_LEN = 80, | ||
28 | |||
29 | /* Latest supported version */ | ||
30 | OSDv2_ADDITIONAL_CDB_LENGTH = 228, | ||
31 | OSD_ADDITIONAL_CDB_LENGTH = | ||
32 | OSDv2_ADDITIONAL_CDB_LENGTH, | ||
33 | OSD_TOTAL_CDB_LEN = OSD_ADDITIONAL_CDB_LENGTH + 8, | ||
34 | OSD_CAP_LEN = 104, | ||
35 | |||
36 | OSD_SYSTEMID_LEN = 20, | ||
37 | OSDv1_CRYPTO_KEYID_SIZE = 20, | ||
38 | OSDv2_CRYPTO_KEYID_SIZE = 32, | ||
39 | OSD_CRYPTO_KEYID_SIZE = OSDv2_CRYPTO_KEYID_SIZE, | ||
40 | OSD_CRYPTO_SEED_SIZE = 4, | ||
41 | OSD_CRYPTO_NONCE_SIZE = 12, | ||
42 | OSD_MAX_SENSE_LEN = 252, /* from SPC-3 */ | ||
43 | |||
44 | OSD_PARTITION_FIRST_ID = 0x10000, | ||
45 | OSD_OBJECT_FIRST_ID = 0x10000, | ||
46 | }; | ||
47 | |||
48 | /* (osd-r10 5.2.4) | ||
49 | * osd2r03: 5.2.3 Caching control bits | ||
50 | */ | ||
51 | enum osd_options_byte { | ||
52 | OSD_CDB_FUA = 0x08, /* Force Unit Access */ | ||
53 | OSD_CDB_DPO = 0x10, /* Disable Page Out */ | ||
54 | }; | ||
55 | |||
56 | /* | ||
57 | * osd2r03: 5.2.5 Isolation. | ||
58 | * First 3 bits, V2-only. | ||
59 | * Also for attr 110h "default isolation method" at Root Information page | ||
60 | */ | ||
61 | enum osd_options_byte_isolation { | ||
62 | OSD_ISOLATION_DEFAULT = 0, | ||
63 | OSD_ISOLATION_NONE = 1, | ||
64 | OSD_ISOLATION_STRICT = 2, | ||
65 | OSD_ISOLATION_RANGE = 4, | ||
66 | OSD_ISOLATION_FUNCTIONAL = 5, | ||
67 | OSD_ISOLATION_VENDOR = 7, | ||
68 | }; | ||
69 | |||
70 | /* (osd-r10: 6.7) | ||
71 | * osd2r03: 6.8 FLUSH, FLUSH COLLECTION, FLUSH OSD, FLUSH PARTITION | ||
72 | */ | ||
73 | enum osd_options_flush_scope_values { | ||
74 | OSD_CDB_FLUSH_ALL = 0, | ||
75 | OSD_CDB_FLUSH_ATTR_ONLY = 1, | ||
76 | |||
77 | OSD_CDB_FLUSH_ALL_RECURSIVE = 2, | ||
78 | /* V2-only */ | ||
79 | OSD_CDB_FLUSH_ALL_RANGE = 2, | ||
80 | }; | ||
81 | |||
82 | /* osd2r03: 5.2.10 Timestamps control */ | ||
83 | enum { | ||
84 | OSD_CDB_NORMAL_TIMESTAMPS = 0, | ||
85 | OSD_CDB_BYPASS_TIMESTAMPS = 0x7f, | ||
86 | }; | ||
87 | |||
88 | /* (osd-r10: 5.2.2.1) | ||
89 | * osd2r03: 5.2.4.1 Get and set attributes CDB format selection | ||
90 | * 2 bits at second nibble of command_specific_options byte | ||
91 | */ | ||
92 | enum osd_attributes_mode { | ||
93 | /* V2-only */ | ||
94 | OSD_CDB_SET_ONE_ATTR = 0x10, | ||
95 | |||
96 | OSD_CDB_GET_ATTR_PAGE_SET_ONE = 0x20, | ||
97 | OSD_CDB_GET_SET_ATTR_LISTS = 0x30, | ||
98 | |||
99 | OSD_CDB_GET_SET_ATTR_MASK = 0x30, | ||
100 | }; | ||
101 | |||
102 | /* (osd-r10: 4.12.5) | ||
103 | * osd2r03: 4.14.5 Data-In and Data-Out buffer offsets | ||
104 | * byte offset = mantissa * (2^(exponent+8)) | ||
105 | * struct { | ||
106 | * unsigned mantissa: 28; | ||
107 | * int exponent: 04; | ||
108 | * } | ||
109 | */ | ||
110 | typedef __be32 osd_cdb_offset; | ||
111 | |||
112 | enum { | ||
113 | OSD_OFFSET_UNUSED = 0xFFFFFFFF, | ||
114 | OSD_OFFSET_MAX_BITS = 28, | ||
115 | |||
116 | OSDv1_OFFSET_MIN_SHIFT = 8, | ||
117 | OSD_OFFSET_MIN_SHIFT = 3, | ||
118 | OSD_OFFSET_MAX_SHIFT = 16, | ||
119 | }; | ||
120 | |||
121 | /* Return the smallest allowed encoded offset that contains @offset. | ||
122 | * | ||
123 | * The actual encoded offset returned is @offset + *padding. | ||
124 | * (up to max_shift, non-inclusive) | ||
125 | */ | ||
126 | osd_cdb_offset __osd_encode_offset(u64 offset, unsigned *padding, | ||
127 | int min_shift, int max_shift); | ||
128 | |||
129 | /* Minimum alignment is 256 bytes | ||
130 | * Note: Seems from std v1 that exponent can be from 0+8 to 0xE+8 (inclusive) | ||
131 | * which is 8 to 23 but IBM code restricts it to 16, so be it. | ||
132 | */ | ||
133 | static inline osd_cdb_offset osd_encode_offset_v1(u64 offset, unsigned *padding) | ||
134 | { | ||
135 | return __osd_encode_offset(offset, padding, | ||
136 | OSDv1_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT); | ||
137 | } | ||
138 | |||
139 | /* Minimum 8 bytes alignment | ||
140 | * Same as v1 but since exponent can be signed than a less than | ||
141 | * 256 alignment can be reached with small offsets (<2GB) | ||
142 | */ | ||
143 | static inline osd_cdb_offset osd_encode_offset_v2(u64 offset, unsigned *padding) | ||
144 | { | ||
145 | return __osd_encode_offset(offset, padding, | ||
146 | OSD_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT); | ||
147 | } | ||
148 | |||
149 | /* osd2r03: 5.2.1 Overview */ | ||
150 | struct osd_cdb_head { | ||
151 | struct scsi_varlen_cdb_hdr varlen_cdb; | ||
152 | /*10*/ u8 options; | ||
153 | u8 command_specific_options; | ||
154 | u8 timestamp_control; | ||
155 | /*13*/ u8 reserved1[3]; | ||
156 | /*16*/ __be64 partition; | ||
157 | /*24*/ __be64 object; | ||
158 | /*32*/ union { /* V1 vs V2 alignment differences */ | ||
159 | struct __osdv1_cdb_addr_len { | ||
160 | /*32*/ __be32 list_identifier;/* Rarely used */ | ||
161 | /*36*/ __be64 length; | ||
162 | /*44*/ __be64 start_address; | ||
163 | } __packed v1; | ||
164 | |||
165 | struct __osdv2_cdb_addr_len { | ||
166 | /* called allocation_length in some commands */ | ||
167 | /*32*/ __be64 length; | ||
168 | /*40*/ __be64 start_address; | ||
169 | union { | ||
170 | /*48*/ __be32 list_identifier;/* Rarely used */ | ||
171 | /* OSD2r05 5.2.5 CDB continuation length */ | ||
172 | /*48*/ __be32 cdb_continuation_length; | ||
173 | }; | ||
174 | } __packed v2; | ||
175 | }; | ||
176 | /*52*/ union { /* selected attributes mode Page/List/Single */ | ||
177 | struct osd_attributes_page_mode { | ||
178 | /*52*/ __be32 get_attr_page; | ||
179 | /*56*/ __be32 get_attr_alloc_length; | ||
180 | /*60*/ osd_cdb_offset get_attr_offset; | ||
181 | |||
182 | /*64*/ __be32 set_attr_page; | ||
183 | /*68*/ __be32 set_attr_id; | ||
184 | /*72*/ __be32 set_attr_length; | ||
185 | /*76*/ osd_cdb_offset set_attr_offset; | ||
186 | /*80*/ } __packed attrs_page; | ||
187 | |||
188 | struct osd_attributes_list_mode { | ||
189 | /*52*/ __be32 get_attr_desc_bytes; | ||
190 | /*56*/ osd_cdb_offset get_attr_desc_offset; | ||
191 | |||
192 | /*60*/ __be32 get_attr_alloc_length; | ||
193 | /*64*/ osd_cdb_offset get_attr_offset; | ||
194 | |||
195 | /*68*/ __be32 set_attr_bytes; | ||
196 | /*72*/ osd_cdb_offset set_attr_offset; | ||
197 | __be32 not_used; | ||
198 | /*80*/ } __packed attrs_list; | ||
199 | |||
200 | /* osd2r03:5.2.4.2 Set one attribute value using CDB fields */ | ||
201 | struct osd_attributes_cdb_mode { | ||
202 | /*52*/ __be32 set_attr_page; | ||
203 | /*56*/ __be32 set_attr_id; | ||
204 | /*60*/ __be16 set_attr_len; | ||
205 | /*62*/ u8 set_attr_val[18]; | ||
206 | /*80*/ } __packed attrs_cdb; | ||
207 | /*52*/ u8 get_set_attributes_parameters[28]; | ||
208 | }; | ||
209 | } __packed; | ||
210 | /*80*/ | ||
211 | |||
212 | /*160 v1*/ | ||
213 | struct osdv1_security_parameters { | ||
214 | /*160*/u8 integrity_check_value[OSDv1_CRYPTO_KEYID_SIZE]; | ||
215 | /*180*/u8 request_nonce[OSD_CRYPTO_NONCE_SIZE]; | ||
216 | /*192*/osd_cdb_offset data_in_integrity_check_offset; | ||
217 | /*196*/osd_cdb_offset data_out_integrity_check_offset; | ||
218 | } __packed; | ||
219 | /*200 v1*/ | ||
220 | |||
221 | /*184 v2*/ | ||
222 | struct osdv2_security_parameters { | ||
223 | /*184*/u8 integrity_check_value[OSDv2_CRYPTO_KEYID_SIZE]; | ||
224 | /*216*/u8 request_nonce[OSD_CRYPTO_NONCE_SIZE]; | ||
225 | /*228*/osd_cdb_offset data_in_integrity_check_offset; | ||
226 | /*232*/osd_cdb_offset data_out_integrity_check_offset; | ||
227 | } __packed; | ||
228 | /*236 v2*/ | ||
229 | |||
230 | struct osd_security_parameters { | ||
231 | union { | ||
232 | struct osdv1_security_parameters v1; | ||
233 | struct osdv2_security_parameters v2; | ||
234 | }; | ||
235 | }; | ||
236 | |||
237 | struct osdv1_cdb { | ||
238 | struct osd_cdb_head h; | ||
239 | u8 caps[OSDv1_CAP_LEN]; | ||
240 | struct osdv1_security_parameters sec_params; | ||
241 | } __packed; | ||
242 | |||
243 | struct osdv2_cdb { | ||
244 | struct osd_cdb_head h; | ||
245 | u8 caps[OSD_CAP_LEN]; | ||
246 | struct osdv2_security_parameters sec_params; | ||
247 | } __packed; | ||
248 | |||
249 | struct osd_cdb { | ||
250 | union { | ||
251 | struct osdv1_cdb v1; | ||
252 | struct osdv2_cdb v2; | ||
253 | u8 buff[OSD_TOTAL_CDB_LEN]; | ||
254 | }; | ||
255 | } __packed; | ||
256 | |||
257 | static inline struct osd_cdb_head *osd_cdb_head(struct osd_cdb *ocdb) | ||
258 | { | ||
259 | return (struct osd_cdb_head *)ocdb->buff; | ||
260 | } | ||
261 | |||
262 | /* define both version actions | ||
263 | * Ex name = FORMAT_OSD we have OSD_ACT_FORMAT_OSD && OSDv1_ACT_FORMAT_OSD | ||
264 | */ | ||
265 | #define OSD_ACT___(Name, Num) \ | ||
266 | OSD_ACT_##Name = cpu_to_be16(0x8880 + Num), \ | ||
267 | OSDv1_ACT_##Name = cpu_to_be16(0x8800 + Num), | ||
268 | |||
269 | /* V2 only actions */ | ||
270 | #define OSD_ACT_V2(Name, Num) \ | ||
271 | OSD_ACT_##Name = cpu_to_be16(0x8880 + Num), | ||
272 | |||
273 | #define OSD_ACT_V1_V2(Name, Num1, Num2) \ | ||
274 | OSD_ACT_##Name = cpu_to_be16(Num2), \ | ||
275 | OSDv1_ACT_##Name = cpu_to_be16(Num1), | ||
276 | |||
277 | enum osd_service_actions { | ||
278 | OSD_ACT_V2(OBJECT_STRUCTURE_CHECK, 0x00) | ||
279 | OSD_ACT___(FORMAT_OSD, 0x01) | ||
280 | OSD_ACT___(CREATE, 0x02) | ||
281 | OSD_ACT___(LIST, 0x03) | ||
282 | OSD_ACT_V2(PUNCH, 0x04) | ||
283 | OSD_ACT___(READ, 0x05) | ||
284 | OSD_ACT___(WRITE, 0x06) | ||
285 | OSD_ACT___(APPEND, 0x07) | ||
286 | OSD_ACT___(FLUSH, 0x08) | ||
287 | OSD_ACT_V2(CLEAR, 0x09) | ||
288 | OSD_ACT___(REMOVE, 0x0A) | ||
289 | OSD_ACT___(CREATE_PARTITION, 0x0B) | ||
290 | OSD_ACT___(REMOVE_PARTITION, 0x0C) | ||
291 | OSD_ACT___(GET_ATTRIBUTES, 0x0E) | ||
292 | OSD_ACT___(SET_ATTRIBUTES, 0x0F) | ||
293 | OSD_ACT___(CREATE_AND_WRITE, 0x12) | ||
294 | OSD_ACT___(CREATE_COLLECTION, 0x15) | ||
295 | OSD_ACT___(REMOVE_COLLECTION, 0x16) | ||
296 | OSD_ACT___(LIST_COLLECTION, 0x17) | ||
297 | OSD_ACT___(SET_KEY, 0x18) | ||
298 | OSD_ACT___(SET_MASTER_KEY, 0x19) | ||
299 | OSD_ACT___(FLUSH_COLLECTION, 0x1A) | ||
300 | OSD_ACT___(FLUSH_PARTITION, 0x1B) | ||
301 | OSD_ACT___(FLUSH_OSD, 0x1C) | ||
302 | |||
303 | OSD_ACT_V2(QUERY, 0x20) | ||
304 | OSD_ACT_V2(REMOVE_MEMBER_OBJECTS, 0x21) | ||
305 | OSD_ACT_V2(GET_MEMBER_ATTRIBUTES, 0x22) | ||
306 | OSD_ACT_V2(SET_MEMBER_ATTRIBUTES, 0x23) | ||
307 | |||
308 | OSD_ACT_V2(CREATE_CLONE, 0x28) | ||
309 | OSD_ACT_V2(CREATE_SNAPSHOT, 0x29) | ||
310 | OSD_ACT_V2(DETACH_CLONE, 0x2A) | ||
311 | OSD_ACT_V2(REFRESH_SNAPSHOT_CLONE, 0x2B) | ||
312 | OSD_ACT_V2(RESTORE_PARTITION_FROM_SNAPSHOT, 0x2C) | ||
313 | |||
314 | OSD_ACT_V2(READ_MAP, 0x31) | ||
315 | OSD_ACT_V2(READ_MAPS_COMPARE, 0x32) | ||
316 | |||
317 | OSD_ACT_V1_V2(PERFORM_SCSI_COMMAND, 0x8F7E, 0x8F7C) | ||
318 | OSD_ACT_V1_V2(SCSI_TASK_MANAGEMENT, 0x8F7F, 0x8F7D) | ||
319 | /* 0x8F80 to 0x8FFF are Vendor specific */ | ||
320 | }; | ||
321 | |||
322 | /* osd2r03: 7.1.3.2 List entry format for retrieving attributes */ | ||
323 | struct osd_attributes_list_attrid { | ||
324 | __be32 attr_page; | ||
325 | __be32 attr_id; | ||
326 | } __packed; | ||
327 | |||
328 | /* | ||
329 | * NOTE: v1: is not aligned. | ||
330 | */ | ||
331 | struct osdv1_attributes_list_element { | ||
332 | __be32 attr_page; | ||
333 | __be32 attr_id; | ||
334 | __be16 attr_bytes; /* valid bytes at attr_val without padding */ | ||
335 | u8 attr_val[0]; | ||
336 | } __packed; | ||
337 | |||
338 | /* | ||
339 | * osd2r03: 7.1.3.3 List entry format for retrieved attributes and | ||
340 | * for setting attributes | ||
341 | * NOTE: v2 is 8-bytes aligned | ||
342 | */ | ||
343 | struct osdv2_attributes_list_element { | ||
344 | __be32 attr_page; | ||
345 | __be32 attr_id; | ||
346 | u8 reserved[6]; | ||
347 | __be16 attr_bytes; /* valid bytes at attr_val without padding */ | ||
348 | u8 attr_val[0]; | ||
349 | } __packed; | ||
350 | |||
351 | enum { | ||
352 | OSDv1_ATTRIBUTES_ELEM_ALIGN = 1, | ||
353 | OSD_ATTRIBUTES_ELEM_ALIGN = 8, | ||
354 | }; | ||
355 | |||
356 | enum { | ||
357 | OSD_ATTR_LIST_ALL_PAGES = 0xFFFFFFFF, | ||
358 | OSD_ATTR_LIST_ALL_IN_PAGE = 0xFFFFFFFF, | ||
359 | }; | ||
360 | |||
361 | static inline unsigned osdv1_attr_list_elem_size(unsigned len) | ||
362 | { | ||
363 | return ALIGN(len + sizeof(struct osdv1_attributes_list_element), | ||
364 | OSDv1_ATTRIBUTES_ELEM_ALIGN); | ||
365 | } | ||
366 | |||
367 | static inline unsigned osdv2_attr_list_elem_size(unsigned len) | ||
368 | { | ||
369 | return ALIGN(len + sizeof(struct osdv2_attributes_list_element), | ||
370 | OSD_ATTRIBUTES_ELEM_ALIGN); | ||
371 | } | ||
372 | |||
373 | /* | ||
374 | * osd2r03: 7.1.3 OSD attributes lists (Table 184) — List type values | ||
375 | */ | ||
376 | enum osd_attr_list_types { | ||
377 | OSD_ATTR_LIST_GET = 0x1, /* descriptors only */ | ||
378 | OSD_ATTR_LIST_SET_RETRIEVE = 0x9, /*descriptors/values variable-length*/ | ||
379 | OSD_V2_ATTR_LIST_MULTIPLE = 0xE, /* ver2, Multiple Objects lists*/ | ||
380 | OSD_V1_ATTR_LIST_CREATE_MULTIPLE = 0xF,/*ver1, used by create_multple*/ | ||
381 | }; | ||
382 | |||
383 | /* osd2r03: 7.1.3.4 Multi-object retrieved attributes format */ | ||
384 | struct osd_attributes_list_multi_header { | ||
385 | __be64 object_id; | ||
386 | u8 object_type; /* object_type enum below */ | ||
387 | u8 reserved[5]; | ||
388 | __be16 list_bytes; | ||
389 | /* followed by struct osd_attributes_list_element's */ | ||
390 | }; | ||
391 | |||
392 | struct osdv1_attributes_list_header { | ||
393 | u8 type; /* low 4-bit only */ | ||
394 | u8 pad; | ||
395 | __be16 list_bytes; /* Initiator shall set to Zero. Only set by target */ | ||
396 | /* | ||
397 | * type=9 followed by struct osd_attributes_list_element's | ||
398 | * type=E followed by struct osd_attributes_list_multi_header's | ||
399 | */ | ||
400 | } __packed; | ||
401 | |||
402 | static inline unsigned osdv1_list_size(struct osdv1_attributes_list_header *h) | ||
403 | { | ||
404 | return be16_to_cpu(h->list_bytes); | ||
405 | } | ||
406 | |||
407 | struct osdv2_attributes_list_header { | ||
408 | u8 type; /* lower 4-bits only */ | ||
409 | u8 pad[3]; | ||
410 | /*4*/ __be32 list_bytes; /* Initiator shall set to zero. Only set by target */ | ||
411 | /* | ||
412 | * type=9 followed by struct osd_attributes_list_element's | ||
413 | * type=E followed by struct osd_attributes_list_multi_header's | ||
414 | */ | ||
415 | } __packed; | ||
416 | |||
417 | static inline unsigned osdv2_list_size(struct osdv2_attributes_list_header *h) | ||
418 | { | ||
419 | return be32_to_cpu(h->list_bytes); | ||
420 | } | ||
421 | |||
422 | /* (osd-r10 6.13) | ||
423 | * osd2r03: 6.15 LIST (Table 79) LIST command parameter data. | ||
424 | * for root_lstchg below | ||
425 | */ | ||
426 | enum { | ||
427 | OSD_OBJ_ID_LIST_PAR = 0x1, /* V1-only. Not used in V2 */ | ||
428 | OSD_OBJ_ID_LIST_LSTCHG = 0x2, | ||
429 | }; | ||
430 | |||
431 | /* | ||
432 | * osd2r03: 6.15.2 LIST command parameter data | ||
433 | * (Also for LIST COLLECTION) | ||
434 | */ | ||
435 | struct osd_obj_id_list { | ||
436 | __be64 list_bytes; /* bytes in list excluding list_bytes (-8) */ | ||
437 | __be64 continuation_id; | ||
438 | __be32 list_identifier; | ||
439 | u8 pad[3]; | ||
440 | u8 root_lstchg; | ||
441 | __be64 object_ids[0]; | ||
442 | } __packed; | ||
443 | |||
444 | static inline bool osd_is_obj_list_done(struct osd_obj_id_list *list, | ||
445 | bool *is_changed) | ||
446 | { | ||
447 | *is_changed = (0 != (list->root_lstchg & OSD_OBJ_ID_LIST_LSTCHG)); | ||
448 | return 0 != list->continuation_id; | ||
449 | } | ||
450 | |||
451 | /* | ||
452 | * osd2r03: 4.12.4.5 The ALLDATA security method | ||
453 | */ | ||
454 | struct osd_data_out_integrity_info { | ||
455 | __be64 data_bytes; | ||
456 | __be64 set_attributes_bytes; | ||
457 | __be64 get_attributes_bytes; | ||
458 | __u8 integrity_check_value[OSD_CRYPTO_KEYID_SIZE]; | ||
459 | } __packed; | ||
460 | |||
461 | /* Same osd_data_out_integrity_info is used for OSD2/OSD1. The only difference | ||
462 | * Is the sizeof the structure since in OSD1 the last array is smaller. Use | ||
463 | * below for version independent handling of this structure | ||
464 | */ | ||
465 | static inline int osd_data_out_integrity_info_sizeof(bool is_ver1) | ||
466 | { | ||
467 | return sizeof(struct osd_data_out_integrity_info) - | ||
468 | (is_ver1 * (OSDv2_CRYPTO_KEYID_SIZE - OSDv1_CRYPTO_KEYID_SIZE)); | ||
469 | } | ||
470 | |||
471 | struct osd_data_in_integrity_info { | ||
472 | __be64 data_bytes; | ||
473 | __be64 retrieved_attributes_bytes; | ||
474 | __u8 integrity_check_value[OSD_CRYPTO_KEYID_SIZE]; | ||
475 | } __packed; | ||
476 | |||
477 | /* Same osd_data_in_integrity_info is used for OSD2/OSD1. The only difference | ||
478 | * Is the sizeof the structure since in OSD1 the last array is smaller. Use | ||
479 | * below for version independent handling of this structure | ||
480 | */ | ||
481 | static inline int osd_data_in_integrity_info_sizeof(bool is_ver1) | ||
482 | { | ||
483 | return sizeof(struct osd_data_in_integrity_info) - | ||
484 | (is_ver1 * (OSDv2_CRYPTO_KEYID_SIZE - OSDv1_CRYPTO_KEYID_SIZE)); | ||
485 | } | ||
486 | |||
487 | struct osd_timestamp { | ||
488 | u8 time[6]; /* number of milliseconds since 1/1/1970 UT (big endian) */ | ||
489 | } __packed; | ||
490 | /* FIXME: define helper functions to convert to/from osd time format */ | ||
491 | |||
492 | /* | ||
493 | * Capability & Security definitions | ||
494 | * osd2r03: 4.11.2.2 Capability format | ||
495 | * osd2r03: 5.2.8 Security parameters | ||
496 | */ | ||
497 | |||
498 | struct osd_key_identifier { | ||
499 | u8 id[7]; /* if you know why 7 please email ooo@electrozaur.com */ | ||
500 | } __packed; | ||
501 | |||
502 | /* for osd_capability.format */ | ||
503 | enum { | ||
504 | OSD_SEC_CAP_FORMAT_NO_CAPS = 0, | ||
505 | OSD_SEC_CAP_FORMAT_VER1 = 1, | ||
506 | OSD_SEC_CAP_FORMAT_VER2 = 2, | ||
507 | }; | ||
508 | |||
509 | /* security_method */ | ||
510 | enum { | ||
511 | OSD_SEC_NOSEC = 0, | ||
512 | OSD_SEC_CAPKEY = 1, | ||
513 | OSD_SEC_CMDRSP = 2, | ||
514 | OSD_SEC_ALLDATA = 3, | ||
515 | }; | ||
516 | |||
517 | enum object_type { | ||
518 | OSD_SEC_OBJ_ROOT = 0x1, | ||
519 | OSD_SEC_OBJ_PARTITION = 0x2, | ||
520 | OSD_SEC_OBJ_COLLECTION = 0x40, | ||
521 | OSD_SEC_OBJ_USER = 0x80, | ||
522 | }; | ||
523 | |||
524 | enum osd_capability_bit_masks { | ||
525 | OSD_SEC_CAP_APPEND = BIT(0), | ||
526 | OSD_SEC_CAP_OBJ_MGMT = BIT(1), | ||
527 | OSD_SEC_CAP_REMOVE = BIT(2), | ||
528 | OSD_SEC_CAP_CREATE = BIT(3), | ||
529 | OSD_SEC_CAP_SET_ATTR = BIT(4), | ||
530 | OSD_SEC_CAP_GET_ATTR = BIT(5), | ||
531 | OSD_SEC_CAP_WRITE = BIT(6), | ||
532 | OSD_SEC_CAP_READ = BIT(7), | ||
533 | |||
534 | OSD_SEC_CAP_NONE1 = BIT(8), | ||
535 | OSD_SEC_CAP_NONE2 = BIT(9), | ||
536 | OSD_SEC_GBL_REM = BIT(10), /*v2 only*/ | ||
537 | OSD_SEC_CAP_QUERY = BIT(11), /*v2 only*/ | ||
538 | OSD_SEC_CAP_M_OBJECT = BIT(12), /*v2 only*/ | ||
539 | OSD_SEC_CAP_POL_SEC = BIT(13), | ||
540 | OSD_SEC_CAP_GLOBAL = BIT(14), | ||
541 | OSD_SEC_CAP_DEV_MGMT = BIT(15), | ||
542 | }; | ||
543 | |||
544 | /* for object_descriptor_type (hi nibble used) */ | ||
545 | enum { | ||
546 | OSD_SEC_OBJ_DESC_NONE = 0, /* Not allowed */ | ||
547 | OSD_SEC_OBJ_DESC_OBJ = 1 << 4, /* v1: also collection */ | ||
548 | OSD_SEC_OBJ_DESC_PAR = 2 << 4, /* also root */ | ||
549 | OSD_SEC_OBJ_DESC_COL = 3 << 4, /* v2 only */ | ||
550 | }; | ||
551 | |||
552 | /* (osd-r10:4.9.2.2) | ||
553 | * osd2r03:4.11.2.2 Capability format | ||
554 | */ | ||
555 | struct osd_capability_head { | ||
556 | u8 format; /* low nibble */ | ||
557 | u8 integrity_algorithm__key_version; /* MAKE_BYTE(integ_alg, key_ver) */ | ||
558 | u8 security_method; | ||
559 | u8 reserved1; | ||
560 | /*04*/ struct osd_timestamp expiration_time; | ||
561 | /*10*/ u8 audit[20]; | ||
562 | /*30*/ u8 discriminator[12]; | ||
563 | /*42*/ struct osd_timestamp object_created_time; | ||
564 | /*48*/ u8 object_type; | ||
565 | /*49*/ u8 permissions_bit_mask[5]; | ||
566 | /*54*/ u8 reserved2; | ||
567 | /*55*/ u8 object_descriptor_type; /* high nibble */ | ||
568 | } __packed; | ||
569 | |||
570 | /*56 v1*/ | ||
571 | struct osdv1_cap_object_descriptor { | ||
572 | union { | ||
573 | struct { | ||
574 | /*56*/ __be32 policy_access_tag; | ||
575 | /*60*/ __be64 allowed_partition_id; | ||
576 | /*68*/ __be64 allowed_object_id; | ||
577 | /*76*/ __be32 reserved; | ||
578 | } __packed obj_desc; | ||
579 | |||
580 | /*56*/ u8 object_descriptor[24]; | ||
581 | }; | ||
582 | } __packed; | ||
583 | /*80 v1*/ | ||
584 | |||
585 | /*56 v2*/ | ||
586 | struct osd_cap_object_descriptor { | ||
587 | union { | ||
588 | struct { | ||
589 | /*56*/ __be32 allowed_attributes_access; | ||
590 | /*60*/ __be32 policy_access_tag; | ||
591 | /*64*/ __be16 boot_epoch; | ||
592 | /*66*/ u8 reserved[6]; | ||
593 | /*72*/ __be64 allowed_partition_id; | ||
594 | /*80*/ __be64 allowed_object_id; | ||
595 | /*88*/ __be64 allowed_range_length; | ||
596 | /*96*/ __be64 allowed_range_start; | ||
597 | } __packed obj_desc; | ||
598 | |||
599 | /*56*/ u8 object_descriptor[48]; | ||
600 | }; | ||
601 | } __packed; | ||
602 | /*104 v2*/ | ||
603 | |||
604 | struct osdv1_capability { | ||
605 | struct osd_capability_head h; | ||
606 | struct osdv1_cap_object_descriptor od; | ||
607 | } __packed; | ||
608 | |||
609 | struct osd_capability { | ||
610 | struct osd_capability_head h; | ||
611 | struct osd_cap_object_descriptor od; | ||
612 | } __packed; | ||
613 | |||
614 | /** | ||
615 | * osd_sec_set_caps - set cap-bits into the capabilities header | ||
616 | * | ||
617 | * @cap: The osd_capability_head to set cap bits to. | ||
618 | * @bit_mask: Use an ORed list of enum osd_capability_bit_masks values | ||
619 | * | ||
620 | * permissions_bit_mask is unaligned use below to set into caps | ||
621 | * in a version independent way | ||
622 | */ | ||
623 | static inline void osd_sec_set_caps(struct osd_capability_head *cap, | ||
624 | u16 bit_mask) | ||
625 | { | ||
626 | /* | ||
627 | *Note: The bits above are defined LE order this is because this way | ||
628 | * they can grow in the future to more then 16, and still retain | ||
629 | * there constant values. | ||
630 | */ | ||
631 | put_unaligned_le16(bit_mask, &cap->permissions_bit_mask); | ||
632 | } | ||
633 | |||
634 | /* osd2r05a sec 5.3: CDB continuation segment formats */ | ||
635 | enum osd_continuation_segment_format { | ||
636 | CDB_CONTINUATION_FORMAT_V2 = 0x01, | ||
637 | }; | ||
638 | |||
639 | struct osd_continuation_segment_header { | ||
640 | u8 format; | ||
641 | u8 reserved1; | ||
642 | __be16 service_action; | ||
643 | __be32 reserved2; | ||
644 | u8 integrity_check[OSDv2_CRYPTO_KEYID_SIZE]; | ||
645 | } __packed; | ||
646 | |||
647 | /* osd2r05a sec 5.4.1: CDB continuation descriptors */ | ||
648 | enum osd_continuation_descriptor_type { | ||
649 | NO_MORE_DESCRIPTORS = 0x0000, | ||
650 | SCATTER_GATHER_LIST = 0x0001, | ||
651 | QUERY_LIST = 0x0002, | ||
652 | USER_OBJECT = 0x0003, | ||
653 | COPY_USER_OBJECT_SOURCE = 0x0101, | ||
654 | EXTENSION_CAPABILITIES = 0xFFEE | ||
655 | }; | ||
656 | |||
657 | struct osd_continuation_descriptor_header { | ||
658 | __be16 type; | ||
659 | u8 reserved; | ||
660 | u8 pad_length; | ||
661 | __be32 length; | ||
662 | } __packed; | ||
663 | |||
664 | |||
665 | /* osd2r05a sec 5.4.2: Scatter/gather list */ | ||
666 | struct osd_sg_list_entry { | ||
667 | __be64 offset; | ||
668 | __be64 len; | ||
669 | }; | ||
670 | |||
671 | struct osd_sg_continuation_descriptor { | ||
672 | struct osd_continuation_descriptor_header hdr; | ||
673 | struct osd_sg_list_entry entries[]; | ||
674 | }; | ||
675 | |||
676 | #endif /* ndef __OSD_PROTOCOL_H__ */ | ||
diff --git a/include/scsi/osd_sec.h b/include/scsi/osd_sec.h deleted file mode 100644 index 7abeb0f0db30..000000000000 --- a/include/scsi/osd_sec.h +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /* | ||
2 | * osd_sec.h - OSD security manager API | ||
3 | * | ||
4 | * Copyright (C) 2008 Panasas Inc. All rights reserved. | ||
5 | * | ||
6 | * Authors: | ||
7 | * Boaz Harrosh <ooo@electrozaur.com> | ||
8 | * Benny Halevy <bhalevy@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * | ||
13 | */ | ||
14 | #ifndef __OSD_SEC_H__ | ||
15 | #define __OSD_SEC_H__ | ||
16 | |||
17 | #include <scsi/osd_protocol.h> | ||
18 | #include <scsi/osd_types.h> | ||
19 | |||
20 | /* | ||
21 | * Contains types and constants of osd capabilities and security | ||
22 | * encoding/decoding. | ||
23 | * API is trying to keep security abstract so initiator of an object | ||
24 | * based pNFS client knows as little as possible about security and | ||
25 | * capabilities. It is the Server's osd-initiator place to know more. | ||
26 | * Also can be used by osd-target. | ||
27 | */ | ||
28 | void osd_sec_encode_caps(void *caps, ...);/* NI */ | ||
29 | void osd_sec_init_nosec_doall_caps(void *caps, | ||
30 | const struct osd_obj_id *obj, bool is_collection, const bool is_v1); | ||
31 | |||
32 | bool osd_is_sec_alldata(struct osd_security_parameters *sec_params); | ||
33 | |||
34 | /* Conditionally sign the CDB according to security setting in ocdb | ||
35 | * with cap_key */ | ||
36 | void osd_sec_sign_cdb(struct osd_cdb *ocdb, const u8 *cap_key); | ||
37 | |||
38 | /* Unconditionally sign the BIO data with cap_key. | ||
39 | * Check for osd_is_sec_alldata() was done prior to calling this. */ | ||
40 | void osd_sec_sign_data(void *data_integ, struct bio *bio, const u8 *cap_key); | ||
41 | |||
42 | /* Version independent copy of caps into the cdb */ | ||
43 | void osd_set_caps(struct osd_cdb *cdb, const void *caps); | ||
44 | |||
45 | #endif /* ndef __OSD_SEC_H__ */ | ||
diff --git a/include/scsi/osd_sense.h b/include/scsi/osd_sense.h deleted file mode 100644 index d52aa93a0b2d..000000000000 --- a/include/scsi/osd_sense.h +++ /dev/null | |||
@@ -1,263 +0,0 @@ | |||
1 | /* | ||
2 | * osd_sense.h - OSD Related sense handling definitions. | ||
3 | * | ||
4 | * Copyright (C) 2008 Panasas Inc. All rights reserved. | ||
5 | * | ||
6 | * Authors: | ||
7 | * Boaz Harrosh <ooo@electrozaur.com> | ||
8 | * Benny Halevy <bhalevy@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * | ||
13 | * This file contains types and constants that are defined by the protocol | ||
14 | * Note: All names and symbols are taken from the OSD standard's text. | ||
15 | */ | ||
16 | #ifndef __OSD_SENSE_H__ | ||
17 | #define __OSD_SENSE_H__ | ||
18 | |||
19 | #include <scsi/osd_protocol.h> | ||
20 | |||
21 | /* SPC3r23 4.5.6 Sense key and sense code definitions table 27 */ | ||
22 | enum scsi_sense_keys { | ||
23 | scsi_sk_no_sense = 0x0, | ||
24 | scsi_sk_recovered_error = 0x1, | ||
25 | scsi_sk_not_ready = 0x2, | ||
26 | scsi_sk_medium_error = 0x3, | ||
27 | scsi_sk_hardware_error = 0x4, | ||
28 | scsi_sk_illegal_request = 0x5, | ||
29 | scsi_sk_unit_attention = 0x6, | ||
30 | scsi_sk_data_protect = 0x7, | ||
31 | scsi_sk_blank_check = 0x8, | ||
32 | scsi_sk_vendor_specific = 0x9, | ||
33 | scsi_sk_copy_aborted = 0xa, | ||
34 | scsi_sk_aborted_command = 0xb, | ||
35 | scsi_sk_volume_overflow = 0xd, | ||
36 | scsi_sk_miscompare = 0xe, | ||
37 | scsi_sk_reserved = 0xf, | ||
38 | }; | ||
39 | |||
40 | /* SPC3r23 4.5.6 Sense key and sense code definitions table 28 */ | ||
41 | /* Note: only those which can be returned by an OSD target. Most of | ||
42 | * these errors are taken care of by the generic scsi layer. | ||
43 | */ | ||
44 | enum osd_additional_sense_codes { | ||
45 | scsi_no_additional_sense_information = 0x0000, | ||
46 | scsi_operation_in_progress = 0x0016, | ||
47 | scsi_cleaning_requested = 0x0017, | ||
48 | scsi_lunr_cause_not_reportable = 0x0400, | ||
49 | scsi_logical_unit_is_in_process_of_becoming_ready = 0x0401, | ||
50 | scsi_lunr_initializing_command_required = 0x0402, | ||
51 | scsi_lunr_manual_intervention_required = 0x0403, | ||
52 | scsi_lunr_operation_in_progress = 0x0407, | ||
53 | scsi_lunr_selftest_in_progress = 0x0409, | ||
54 | scsi_luna_asymmetric_access_state_transition = 0x040a, | ||
55 | scsi_luna_target_port_in_standby_state = 0x040b, | ||
56 | scsi_luna_target_port_in_unavailable_state = 0x040c, | ||
57 | scsi_lunr_notify_enable_spinup_required = 0x0411, | ||
58 | scsi_logical_unit_does_not_respond_to_selection = 0x0500, | ||
59 | scsi_logical_unit_communication_failure = 0x0800, | ||
60 | scsi_logical_unit_communication_timeout = 0x0801, | ||
61 | scsi_logical_unit_communication_parity_error = 0x0802, | ||
62 | scsi_error_log_overflow = 0x0a00, | ||
63 | scsi_warning = 0x0b00, | ||
64 | scsi_warning_specified_temperature_exceeded = 0x0b01, | ||
65 | scsi_warning_enclosure_degraded = 0x0b02, | ||
66 | scsi_write_error_unexpected_unsolicited_data = 0x0c0c, | ||
67 | scsi_write_error_not_enough_unsolicited_data = 0x0c0d, | ||
68 | scsi_invalid_information_unit = 0x0e00, | ||
69 | scsi_invalid_field_in_command_information_unit = 0x0e03, | ||
70 | scsi_read_error_failed_retransmission_request = 0x1113, | ||
71 | scsi_parameter_list_length_error = 0x1a00, | ||
72 | scsi_invalid_command_operation_code = 0x2000, | ||
73 | scsi_invalid_field_in_cdb = 0x2400, | ||
74 | osd_security_audit_value_frozen = 0x2404, | ||
75 | osd_security_working_key_frozen = 0x2405, | ||
76 | osd_nonce_not_unique = 0x2406, | ||
77 | osd_nonce_timestamp_out_of_range = 0x2407, | ||
78 | scsi_logical_unit_not_supported = 0x2500, | ||
79 | scsi_invalid_field_in_parameter_list = 0x2600, | ||
80 | scsi_parameter_not_supported = 0x2601, | ||
81 | scsi_parameter_value_invalid = 0x2602, | ||
82 | scsi_invalid_release_of_persistent_reservation = 0x2604, | ||
83 | osd_invalid_dataout_buffer_integrity_check_value = 0x260f, | ||
84 | scsi_not_ready_to_ready_change_medium_may_have_changed = 0x2800, | ||
85 | scsi_power_on_reset_or_bus_device_reset_occurred = 0x2900, | ||
86 | scsi_power_on_occurred = 0x2901, | ||
87 | scsi_scsi_bus_reset_occurred = 0x2902, | ||
88 | scsi_bus_device_reset_function_occurred = 0x2903, | ||
89 | scsi_device_internal_reset = 0x2904, | ||
90 | scsi_transceiver_mode_changed_to_single_ended = 0x2905, | ||
91 | scsi_transceiver_mode_changed_to_lvd = 0x2906, | ||
92 | scsi_i_t_nexus_loss_occurred = 0x2907, | ||
93 | scsi_parameters_changed = 0x2a00, | ||
94 | scsi_mode_parameters_changed = 0x2a01, | ||
95 | scsi_asymmetric_access_state_changed = 0x2a06, | ||
96 | scsi_priority_changed = 0x2a08, | ||
97 | scsi_command_sequence_error = 0x2c00, | ||
98 | scsi_previous_busy_status = 0x2c07, | ||
99 | scsi_previous_task_set_full_status = 0x2c08, | ||
100 | scsi_previous_reservation_conflict_status = 0x2c09, | ||
101 | osd_partition_or_collection_contains_user_objects = 0x2c0a, | ||
102 | scsi_commands_cleared_by_another_initiator = 0x2f00, | ||
103 | scsi_cleaning_failure = 0x3007, | ||
104 | scsi_enclosure_failure = 0x3400, | ||
105 | scsi_enclosure_services_failure = 0x3500, | ||
106 | scsi_unsupported_enclosure_function = 0x3501, | ||
107 | scsi_enclosure_services_unavailable = 0x3502, | ||
108 | scsi_enclosure_services_transfer_failure = 0x3503, | ||
109 | scsi_enclosure_services_transfer_refused = 0x3504, | ||
110 | scsi_enclosure_services_checksum_error = 0x3505, | ||
111 | scsi_rounded_parameter = 0x3700, | ||
112 | osd_read_past_end_of_user_object = 0x3b17, | ||
113 | scsi_logical_unit_has_not_self_configured_yet = 0x3e00, | ||
114 | scsi_logical_unit_failure = 0x3e01, | ||
115 | scsi_timeout_on_logical_unit = 0x3e02, | ||
116 | scsi_logical_unit_failed_selftest = 0x3e03, | ||
117 | scsi_logical_unit_unable_to_update_selftest_log = 0x3e04, | ||
118 | scsi_target_operating_conditions_have_changed = 0x3f00, | ||
119 | scsi_microcode_has_been_changed = 0x3f01, | ||
120 | scsi_inquiry_data_has_changed = 0x3f03, | ||
121 | scsi_echo_buffer_overwritten = 0x3f0f, | ||
122 | scsi_diagnostic_failure_on_component_nn_first = 0x4080, | ||
123 | scsi_diagnostic_failure_on_component_nn_last = 0x40ff, | ||
124 | scsi_message_error = 0x4300, | ||
125 | scsi_internal_target_failure = 0x4400, | ||
126 | scsi_select_or_reselect_failure = 0x4500, | ||
127 | scsi_scsi_parity_error = 0x4700, | ||
128 | scsi_data_phase_crc_error_detected = 0x4701, | ||
129 | scsi_scsi_parity_error_detected_during_st_data_phase = 0x4702, | ||
130 | scsi_asynchronous_information_protection_error_detected = 0x4704, | ||
131 | scsi_protocol_service_crc_error = 0x4705, | ||
132 | scsi_phy_test_function_in_progress = 0x4706, | ||
133 | scsi_invalid_message_error = 0x4900, | ||
134 | scsi_command_phase_error = 0x4a00, | ||
135 | scsi_data_phase_error = 0x4b00, | ||
136 | scsi_logical_unit_failed_self_configuration = 0x4c00, | ||
137 | scsi_overlapped_commands_attempted = 0x4e00, | ||
138 | osd_quota_error = 0x5507, | ||
139 | scsi_failure_prediction_threshold_exceeded = 0x5d00, | ||
140 | scsi_failure_prediction_threshold_exceeded_false = 0x5dff, | ||
141 | scsi_voltage_fault = 0x6500, | ||
142 | }; | ||
143 | |||
144 | enum scsi_descriptor_types { | ||
145 | scsi_sense_information = 0x0, | ||
146 | scsi_sense_command_specific_information = 0x1, | ||
147 | scsi_sense_key_specific = 0x2, | ||
148 | scsi_sense_field_replaceable_unit = 0x3, | ||
149 | scsi_sense_stream_commands = 0x4, | ||
150 | scsi_sense_block_commands = 0x5, | ||
151 | osd_sense_object_identification = 0x6, | ||
152 | osd_sense_response_integrity_check = 0x7, | ||
153 | osd_sense_attribute_identification = 0x8, | ||
154 | scsi_sense_ata_return = 0x9, | ||
155 | |||
156 | scsi_sense_Reserved_first = 0x0A, | ||
157 | scsi_sense_Reserved_last = 0x7F, | ||
158 | scsi_sense_Vendor_specific_first = 0x80, | ||
159 | scsi_sense_Vendor_specific_last = 0xFF, | ||
160 | }; | ||
161 | |||
162 | struct scsi_sense_descriptor { /* for picking into desc type */ | ||
163 | u8 descriptor_type; /* one of enum scsi_descriptor_types */ | ||
164 | u8 additional_length; /* n - 1 */ | ||
165 | u8 data[]; | ||
166 | } __packed; | ||
167 | |||
168 | /* OSD deploys only scsi descriptor_based sense buffers */ | ||
169 | struct scsi_sense_descriptor_based { | ||
170 | /*0*/ u8 response_code; /* 0x72 or 0x73 */ | ||
171 | /*1*/ u8 sense_key; /* one of enum scsi_sense_keys (4 lower bits) */ | ||
172 | /*2*/ __be16 additional_sense_code; /* enum osd_additional_sense_codes */ | ||
173 | /*4*/ u8 Reserved[3]; | ||
174 | /*7*/ u8 additional_sense_length; /* n - 7 */ | ||
175 | /*8*/ struct scsi_sense_descriptor ssd[0]; /* variable length, 1 or more */ | ||
176 | } __packed; | ||
177 | |||
178 | /* some descriptors deployed by OSD */ | ||
179 | |||
180 | /* SPC3r23 4.5.2.3 Command-specific information sense data descriptor */ | ||
181 | /* Note: this is the same for descriptor_type=00 but with type=00 the | ||
182 | * Reserved[0] == 0x80 (ie. bit-7 set) | ||
183 | */ | ||
184 | struct scsi_sense_command_specific_data_descriptor { | ||
185 | /*0*/ u8 descriptor_type; /* (00h/01h) */ | ||
186 | /*1*/ u8 additional_length; /* (0Ah) */ | ||
187 | /*2*/ u8 Reserved[2]; | ||
188 | /*4*/ __be64 information; | ||
189 | } __packed; | ||
190 | /*12*/ | ||
191 | |||
192 | struct scsi_sense_key_specific_data_descriptor { | ||
193 | /*0*/ u8 descriptor_type; /* (02h) */ | ||
194 | /*1*/ u8 additional_length; /* (06h) */ | ||
195 | /*2*/ u8 Reserved[2]; | ||
196 | /* SKSV, C/D, Reserved (2), BPV, BIT POINTER (3) */ | ||
197 | /*4*/ u8 sksv_cd_bpv_bp; | ||
198 | /*5*/ __be16 value; /* field-pointer/progress-value/retry-count/... */ | ||
199 | /*7*/ u8 Reserved2; | ||
200 | } __packed; | ||
201 | /*8*/ | ||
202 | |||
203 | /* 4.16.2.1 OSD error identification sense data descriptor - table 52 */ | ||
204 | /* Note: these bits are defined LE order for easy definition, this way the BIT() | ||
205 | * number is the same as in the documentation. Below members at | ||
206 | * osd_sense_identification_data_descriptor are therefore defined __le32. | ||
207 | */ | ||
208 | enum osd_command_functions_bits { | ||
209 | OSD_CFB_COMMAND = BIT(4), | ||
210 | OSD_CFB_CMD_CAP_VERIFIED = BIT(5), | ||
211 | OSD_CFB_VALIDATION = BIT(7), | ||
212 | OSD_CFB_IMP_ST_ATT = BIT(12), | ||
213 | OSD_CFB_SET_ATT = BIT(20), | ||
214 | OSD_CFB_SA_CAP_VERIFIED = BIT(21), | ||
215 | OSD_CFB_GET_ATT = BIT(28), | ||
216 | OSD_CFB_GA_CAP_VERIFIED = BIT(29), | ||
217 | }; | ||
218 | |||
219 | struct osd_sense_identification_data_descriptor { | ||
220 | /*0*/ u8 descriptor_type; /* (06h) */ | ||
221 | /*1*/ u8 additional_length; /* (1Eh) */ | ||
222 | /*2*/ u8 Reserved[6]; | ||
223 | /*8*/ __le32 not_initiated_functions; /*osd_command_functions_bits*/ | ||
224 | /*12*/ __le32 completed_functions; /*osd_command_functions_bits*/ | ||
225 | /*16*/ __be64 partition_id; | ||
226 | /*24*/ __be64 object_id; | ||
227 | } __packed; | ||
228 | /*32*/ | ||
229 | |||
230 | struct osd_sense_response_integrity_check_descriptor { | ||
231 | /*0*/ u8 descriptor_type; /* (07h) */ | ||
232 | /*1*/ u8 additional_length; /* (20h) */ | ||
233 | /*2*/ u8 integrity_check_value[32]; /*FIXME: OSDv2_CRYPTO_KEYID_SIZE*/ | ||
234 | } __packed; | ||
235 | /*34*/ | ||
236 | |||
237 | struct osd_sense_attributes_data_descriptor { | ||
238 | /*0*/ u8 descriptor_type; /* (08h) */ | ||
239 | /*1*/ u8 additional_length; /* (n-2) */ | ||
240 | /*2*/ u8 Reserved[6]; | ||
241 | struct osd_sense_attr { | ||
242 | /*8*/ __be32 attr_page; | ||
243 | /*12*/ __be32 attr_id; | ||
244 | /*16*/ } sense_attrs[0]; /* 1 or more */ | ||
245 | } __packed; | ||
246 | /*variable*/ | ||
247 | |||
248 | /* Dig into scsi_sk_illegal_request/scsi_invalid_field_in_cdb errors */ | ||
249 | |||
250 | /*FIXME: Support also field in CAPS*/ | ||
251 | #define OSD_CDB_OFFSET(F) offsetof(struct osd_cdb_head, F) | ||
252 | |||
253 | enum osdv2_cdb_field_offset { | ||
254 | OSDv1_CFO_STARTING_BYTE = OSD_CDB_OFFSET(v1.start_address), | ||
255 | OSD_CFO_STARTING_BYTE = OSD_CDB_OFFSET(v2.start_address), | ||
256 | OSD_CFO_PARTITION_ID = OSD_CDB_OFFSET(partition), | ||
257 | OSD_CFO_OBJECT_ID = OSD_CDB_OFFSET(object), | ||
258 | OSD_CFO_PERMISSIONS = sizeof(struct osd_cdb_head) + | ||
259 | offsetof(struct osd_capability_head, | ||
260 | permissions_bit_mask), | ||
261 | }; | ||
262 | |||
263 | #endif /* ndef __OSD_SENSE_H__ */ | ||
diff --git a/include/scsi/osd_types.h b/include/scsi/osd_types.h deleted file mode 100644 index 48e8a165e136..000000000000 --- a/include/scsi/osd_types.h +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /* | ||
2 | * osd_types.h - Types and constants which are not part of the protocol. | ||
3 | * | ||
4 | * Copyright (C) 2008 Panasas Inc. All rights reserved. | ||
5 | * | ||
6 | * Authors: | ||
7 | * Boaz Harrosh <ooo@electrozaur.com> | ||
8 | * Benny Halevy <bhalevy@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * | ||
13 | * Contains types and constants that are implementation specific and are | ||
14 | * used by more than one part of the osd library. | ||
15 | * (Eg initiator/target/security_manager/...) | ||
16 | */ | ||
17 | #ifndef __OSD_TYPES_H__ | ||
18 | #define __OSD_TYPES_H__ | ||
19 | |||
20 | struct osd_systemid { | ||
21 | u8 data[OSD_SYSTEMID_LEN]; | ||
22 | }; | ||
23 | |||
24 | typedef u64 __bitwise osd_id; | ||
25 | |||
26 | struct osd_obj_id { | ||
27 | osd_id partition; | ||
28 | osd_id id; | ||
29 | }; | ||
30 | |||
31 | static const struct __weak osd_obj_id osd_root_object = {0, 0}; | ||
32 | |||
33 | struct osd_attr { | ||
34 | u32 attr_page; | ||
35 | u32 attr_id; | ||
36 | u16 len; /* byte count of operand */ | ||
37 | void *val_ptr; /* in network order */ | ||
38 | }; | ||
39 | |||
40 | struct osd_sg_entry { | ||
41 | u64 offset; | ||
42 | u64 len; | ||
43 | }; | ||
44 | |||
45 | #endif /* ndef __OSD_TYPES_H__ */ | ||
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 2b539a1b3f62..a5fcdad4a03e 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
@@ -628,6 +628,9 @@ struct Scsi_Host { | |||
628 | /* Host responded with short (<36 bytes) INQUIRY result */ | 628 | /* Host responded with short (<36 bytes) INQUIRY result */ |
629 | unsigned short_inquiry:1; | 629 | unsigned short_inquiry:1; |
630 | 630 | ||
631 | /* The transport requires the LUN bits NOT to be stored in CDB[1] */ | ||
632 | unsigned no_scsi2_lun_in_cdb:1; | ||
633 | |||
631 | /* | 634 | /* |
632 | * Optional work queue to be utilized by the transport | 635 | * Optional work queue to be utilized by the transport |
633 | */ | 636 | */ |
@@ -639,9 +642,6 @@ struct Scsi_Host { | |||
639 | */ | 642 | */ |
640 | struct workqueue_struct *tmf_work_q; | 643 | struct workqueue_struct *tmf_work_q; |
641 | 644 | ||
642 | /* The transport requires the LUN bits NOT to be stored in CDB[1] */ | ||
643 | unsigned no_scsi2_lun_in_cdb:1; | ||
644 | |||
645 | /* | 645 | /* |
646 | * Value host_blocked counts down from | 646 | * Value host_blocked counts down from |
647 | */ | 647 | */ |
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index 15da45dc2a5d..b375c3303fe2 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h | |||
@@ -165,6 +165,9 @@ enum fc_tgtid_binding_type { | |||
165 | #define FC_PORT_ROLE_FCP_INITIATOR 0x02 | 165 | #define FC_PORT_ROLE_FCP_INITIATOR 0x02 |
166 | #define FC_PORT_ROLE_IP_PORT 0x04 | 166 | #define FC_PORT_ROLE_IP_PORT 0x04 |
167 | #define FC_PORT_ROLE_FCP_DUMMY_INITIATOR 0x08 | 167 | #define FC_PORT_ROLE_FCP_DUMMY_INITIATOR 0x08 |
168 | #define FC_PORT_ROLE_NVME_INITIATOR 0x10 | ||
169 | #define FC_PORT_ROLE_NVME_TARGET 0x20 | ||
170 | #define FC_PORT_ROLE_NVME_DISCOVERY 0x40 | ||
168 | 171 | ||
169 | /* The following are for compatibility */ | 172 | /* The following are for compatibility */ |
170 | #define FC_RPORT_ROLE_UNKNOWN FC_PORT_ROLE_UNKNOWN | 173 | #define FC_RPORT_ROLE_UNKNOWN FC_PORT_ROLE_UNKNOWN |
@@ -473,6 +476,7 @@ enum fc_host_event_code { | |||
473 | FCH_EVT_PORT_ONLINE = 0x202, | 476 | FCH_EVT_PORT_ONLINE = 0x202, |
474 | FCH_EVT_PORT_FABRIC = 0x204, | 477 | FCH_EVT_PORT_FABRIC = 0x204, |
475 | FCH_EVT_LINK_UNKNOWN = 0x500, | 478 | FCH_EVT_LINK_UNKNOWN = 0x500, |
479 | FCH_EVT_LINK_FPIN = 0x501, | ||
476 | FCH_EVT_VENDOR_UNIQUE = 0xffff, | 480 | FCH_EVT_VENDOR_UNIQUE = 0xffff, |
477 | }; | 481 | }; |
478 | 482 | ||
@@ -755,7 +759,7 @@ fc_remote_port_chkready(struct fc_rport *rport) | |||
755 | return result; | 759 | return result; |
756 | } | 760 | } |
757 | 761 | ||
758 | static inline u64 wwn_to_u64(u8 *wwn) | 762 | static inline u64 wwn_to_u64(const u8 *wwn) |
759 | { | 763 | { |
760 | return get_unaligned_be64(wwn); | 764 | return get_unaligned_be64(wwn); |
761 | } | 765 | } |
@@ -798,11 +802,17 @@ u32 fc_get_event_number(void); | |||
798 | void fc_host_post_event(struct Scsi_Host *shost, u32 event_number, | 802 | void fc_host_post_event(struct Scsi_Host *shost, u32 event_number, |
799 | enum fc_host_event_code event_code, u32 event_data); | 803 | enum fc_host_event_code event_code, u32 event_data); |
800 | void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number, | 804 | void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number, |
801 | u32 data_len, char * data_buf, u64 vendor_id); | 805 | u32 data_len, char *data_buf, u64 vendor_id); |
806 | void fc_host_post_fc_event(struct Scsi_Host *shost, u32 event_number, | ||
807 | enum fc_host_event_code event_code, | ||
808 | u32 data_len, char *data_buf, u64 vendor_id); | ||
802 | /* Note: when specifying vendor_id to fc_host_post_vendor_event() | 809 | /* Note: when specifying vendor_id to fc_host_post_vendor_event() |
803 | * be sure to read the Vendor Type and ID formatting requirements | 810 | * or fc_host_post_fc_event(), be sure to read the Vendor Type |
804 | * specified in scsi_netlink.h | 811 | * and ID formatting requirements specified in scsi_netlink.h |
812 | * Note: when calling fc_host_post_fc_event(), vendor_id may be | ||
813 | * specified as 0. | ||
805 | */ | 814 | */ |
815 | void fc_host_fpin_rcv(struct Scsi_Host *shost, u32 fpin_len, char *fpin_buf); | ||
806 | struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel, | 816 | struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel, |
807 | struct fc_vport_identifiers *); | 817 | struct fc_vport_identifiers *); |
808 | int fc_vport_terminate(struct fc_vport *vport); | 818 | int fc_vport_terminate(struct fc_vport *vport); |
diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h index 24c398f4a68f..a49d37140a64 100644 --- a/include/target/iscsi/iscsi_target_core.h +++ b/include/target/iscsi/iscsi_target_core.h | |||
@@ -473,6 +473,7 @@ struct iscsi_cmd { | |||
473 | struct timer_list dataout_timer; | 473 | struct timer_list dataout_timer; |
474 | /* Iovecs for SCSI data payload RX/TX w/ kernel level sockets */ | 474 | /* Iovecs for SCSI data payload RX/TX w/ kernel level sockets */ |
475 | struct kvec *iov_data; | 475 | struct kvec *iov_data; |
476 | void *overflow_buf; | ||
476 | /* Iovecs for miscellaneous purposes */ | 477 | /* Iovecs for miscellaneous purposes */ |
477 | #define ISCSI_MISC_IOVECS 5 | 478 | #define ISCSI_MISC_IOVECS 5 |
478 | struct kvec iov_misc[ISCSI_MISC_IOVECS]; | 479 | struct kvec iov_misc[ISCSI_MISC_IOVECS]; |
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 19a5bf4214fc..7c9716fe731e 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
@@ -795,8 +795,8 @@ struct se_device { | |||
795 | spinlock_t se_tmr_lock; | 795 | spinlock_t se_tmr_lock; |
796 | spinlock_t qf_cmd_lock; | 796 | spinlock_t qf_cmd_lock; |
797 | struct semaphore caw_sem; | 797 | struct semaphore caw_sem; |
798 | /* Used for legacy SPC-2 reservationsa */ | 798 | /* Used for legacy SPC-2 reservations */ |
799 | struct se_node_acl *dev_reserved_node_acl; | 799 | struct se_session *reservation_holder; |
800 | /* Used for ALUA Logical Unit Group membership */ | 800 | /* Used for ALUA Logical Unit Group membership */ |
801 | struct t10_alua_lu_gp_member *dev_alua_lu_gp_mem; | 801 | struct t10_alua_lu_gp_member *dev_alua_lu_gp_mem; |
802 | /* Used for SPC-3 Persistent Reservations */ | 802 | /* Used for SPC-3 Persistent Reservations */ |
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 8ed90407f062..063f133e47c2 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h | |||
@@ -142,6 +142,7 @@ void transport_register_session(struct se_portal_group *, | |||
142 | struct se_node_acl *, struct se_session *, void *); | 142 | struct se_node_acl *, struct se_session *, void *); |
143 | ssize_t target_show_dynamic_sessions(struct se_portal_group *, char *); | 143 | ssize_t target_show_dynamic_sessions(struct se_portal_group *, char *); |
144 | void transport_free_session(struct se_session *); | 144 | void transport_free_session(struct se_session *); |
145 | void target_spc2_release(struct se_node_acl *nacl); | ||
145 | void target_put_nacl(struct se_node_acl *); | 146 | void target_put_nacl(struct se_node_acl *); |
146 | void transport_deregister_session_configfs(struct se_session *); | 147 | void transport_deregister_session_configfs(struct se_session *); |
147 | void transport_deregister_session(struct se_session *); | 148 | void transport_deregister_session(struct se_session *); |
diff --git a/include/uapi/scsi/fc/fc_els.h b/include/uapi/scsi/fc/fc_els.h index b7e0a5ed40de..a81c53508cc6 100644 --- a/include/uapi/scsi/fc/fc_els.h +++ b/include/uapi/scsi/fc/fc_els.h | |||
@@ -52,6 +52,7 @@ enum fc_els_cmd { | |||
52 | ELS_RRQ = 0x12, /* reinstate recovery qualifier */ | 52 | ELS_RRQ = 0x12, /* reinstate recovery qualifier */ |
53 | ELS_REC = 0x13, /* read exchange concise */ | 53 | ELS_REC = 0x13, /* read exchange concise */ |
54 | ELS_SRR = 0x14, /* sequence retransmission request */ | 54 | ELS_SRR = 0x14, /* sequence retransmission request */ |
55 | ELS_FPIN = 0x16, /* Fabric Performance Impact Notification */ | ||
55 | ELS_PRLI = 0x20, /* process login */ | 56 | ELS_PRLI = 0x20, /* process login */ |
56 | ELS_PRLO = 0x21, /* process logout */ | 57 | ELS_PRLO = 0x21, /* process logout */ |
57 | ELS_SCN = 0x22, /* state change notification */ | 58 | ELS_SCN = 0x22, /* state change notification */ |
@@ -119,6 +120,7 @@ enum fc_els_cmd { | |||
119 | [ELS_RRQ] = "RRQ", \ | 120 | [ELS_RRQ] = "RRQ", \ |
120 | [ELS_REC] = "REC", \ | 121 | [ELS_REC] = "REC", \ |
121 | [ELS_SRR] = "SRR", \ | 122 | [ELS_SRR] = "SRR", \ |
123 | [ELS_FPIN] = "FPIN", \ | ||
122 | [ELS_PRLI] = "PRLI", \ | 124 | [ELS_PRLI] = "PRLI", \ |
123 | [ELS_PRLO] = "PRLO", \ | 125 | [ELS_PRLO] = "PRLO", \ |
124 | [ELS_SCN] = "SCN", \ | 126 | [ELS_SCN] = "SCN", \ |
@@ -829,4 +831,35 @@ enum fc_els_clid_ic { | |||
829 | ELS_CLID_IC_LIP = 8, /* receiving LIP */ | 831 | ELS_CLID_IC_LIP = 8, /* receiving LIP */ |
830 | }; | 832 | }; |
831 | 833 | ||
834 | |||
835 | /* | ||
836 | * Fabric Notification Descriptor Tag values | ||
837 | */ | ||
838 | enum fc_fn_dtag { | ||
839 | ELS_FN_DTAG_LNK_INTEGRITY = 0x00020001, /* Link Integrity */ | ||
840 | ELS_FN_DTAG_PEER_CONGEST = 0x00020003, /* Peer Congestion */ | ||
841 | ELS_FN_DTAG_CONGESTION = 0x00020004, /* Congestion */ | ||
842 | }; | ||
843 | |||
844 | /* | ||
845 | * Fabric Notification Descriptor | ||
846 | */ | ||
847 | struct fc_fn_desc { | ||
848 | __be32 fn_desc_tag; /* Notification Descriptor Tag */ | ||
849 | __be32 fn_desc_value_len; /* Length of Descriptor Value field | ||
850 | * (in bytes) | ||
851 | */ | ||
852 | __u8 fn_desc_value[0]; /* Descriptor Value */ | ||
853 | }; | ||
854 | |||
855 | /* | ||
856 | * ELS_FPIN - Fabric Performance Impact Notification | ||
857 | */ | ||
858 | struct fc_els_fpin { | ||
859 | __u8 fpin_cmd; /* command (0x16) */ | ||
860 | __u8 fpin_zero[3]; /* specified as zero - part of cmd */ | ||
861 | __be32 fpin_desc_cnt; /* count of descriptors */ | ||
862 | struct fc_fn_desc fpin_desc[0]; /* Descriptor list */ | ||
863 | }; | ||
864 | |||
832 | #endif /* _FC_ELS_H_ */ | 865 | #endif /* _FC_ELS_H_ */ |