diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-06-05 09:25:12 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-06-05 09:25:12 -0700 |
commit | b2c9a83d262a8feb022e24e9f9aadb66cb10a7a8 (patch) | |
tree | 6f3ded2dbdfd308e04bd781bc33bdb8af3a45558 /drivers | |
parent | 2981436374177f78539b026ce5bcbab8c251818e (diff) | |
parent | aa2a4ded05058f134a4dee1424f829d662e00cda (diff) | |
download | linux-stable-b2c9a83d262a8feb022e24e9f9aadb66cb10a7a8.tar.gz linux-stable-b2c9a83d262a8feb022e24e9f9aadb66cb10a7a8.tar.bz2 linux-stable-b2c9a83d262a8feb022e24e9f9aadb66cb10a7a8.zip |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull more SCSI updates from James Bottomley:
"Mostly small bug fixes plus other trivial updates.
The major change of note is moving ufs out of scsi and a minor update
to lpfc vmid handling"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (24 commits)
scsi: qla2xxx: Remove unused 'ql_dm_tgt_ex_pct' parameter
scsi: qla2xxx: Remove setting of 'req' and 'rsp' parameters
scsi: mpi3mr: Fix kernel-doc
scsi: lpfc: Add support for ATTO Fibre Channel devices
scsi: core: Return BLK_STS_TRANSPORT for ALUA transitioning
scsi: sd_zbc: Prevent zone information memory leak
scsi: sd: Fix potential NULL pointer dereference
scsi: mpi3mr: Rework mrioc->bsg_device model to fix warnings
scsi: myrb: Fix up null pointer access on myrb_cleanup()
scsi: core: Unexport scsi_bus_type
scsi: sd: Don't call blk_cleanup_disk() in sd_probe()
scsi: ufs: ufshcd: Delete unnecessary NULL check
scsi: isci: Fix typo in comment
scsi: pmcraid: Fix typo in comment
scsi: smartpqi: Fix typo in comment
scsi: qedf: Fix typo in comment
scsi: esas2r: Fix typo in comment
scsi: storvsc: Fix typo in comment
scsi: ufs: Split the drivers/scsi/ufs directory
scsi: qla1280: Remove redundant variable
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/Kconfig | 2 | ||||
-rw-r--r-- | drivers/Makefile | 1 | ||||
-rw-r--r-- | drivers/nvme/host/fc.c | 18 | ||||
-rw-r--r-- | drivers/scsi/Kconfig | 1 | ||||
-rw-r--r-- | drivers/scsi/Makefile | 1 | ||||
-rw-r--r-- | drivers/scsi/esas2r/esas2r_flash.c | 2 | ||||
-rw-r--r-- | drivers/scsi/isci/request.c | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/Makefile | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 3 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw.h | 22 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ids.h | 30 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 89 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nvme.c | 45 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 263 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_vmid.c | 288 | ||||
-rw-r--r-- | drivers/scsi/mpi3mr/mpi3mr.h | 2 | ||||
-rw-r--r-- | drivers/scsi/mpi3mr/mpi3mr_app.c | 50 | ||||
-rw-r--r-- | drivers/scsi/myrb.c | 11 | ||||
-rw-r--r-- | drivers/scsi/pmcraid.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qedf/qedf_io.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla1280.c | 3 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mid.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 7 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 2 | ||||
-rw-r--r-- | drivers/scsi/scsi_sysfs.c | 1 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 5 | ||||
-rw-r--r-- | drivers/scsi/sd.h | 4 | ||||
-rw-r--r-- | drivers/scsi/sd_zbc.c | 26 | ||||
-rw-r--r-- | drivers/scsi/smartpqi/smartpqi.h | 2 | ||||
-rw-r--r-- | drivers/scsi/storvsc_drv.c | 2 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufs.h | 623 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufs_quirks.h | 116 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshcd.h | 1230 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshci.h | 510 | ||||
-rw-r--r-- | drivers/scsi/ufs/unipro.h | 316 | ||||
-rw-r--r-- | drivers/ufs/Kconfig | 30 | ||||
-rw-r--r-- | drivers/ufs/Makefile | 5 | ||||
-rw-r--r-- | drivers/ufs/core/Kconfig | 60 | ||||
-rw-r--r-- | drivers/ufs/core/Makefile | 10 | ||||
-rw-r--r-- | drivers/ufs/core/ufs-debugfs.c (renamed from drivers/scsi/ufs/ufs-debugfs.c) | 2 | ||||
-rw-r--r-- | drivers/ufs/core/ufs-debugfs.h (renamed from drivers/scsi/ufs/ufs-debugfs.h) | 0 | ||||
-rw-r--r-- | drivers/ufs/core/ufs-fault-injection.c (renamed from drivers/scsi/ufs/ufs-fault-injection.c) | 0 | ||||
-rw-r--r-- | drivers/ufs/core/ufs-fault-injection.h (renamed from drivers/scsi/ufs/ufs-fault-injection.h) | 0 | ||||
-rw-r--r-- | drivers/ufs/core/ufs-hwmon.c (renamed from drivers/scsi/ufs/ufs-hwmon.c) | 2 | ||||
-rw-r--r-- | drivers/ufs/core/ufs-sysfs.c (renamed from drivers/scsi/ufs/ufs-sysfs.c) | 2 | ||||
-rw-r--r-- | drivers/ufs/core/ufs-sysfs.h (renamed from drivers/scsi/ufs/ufs-sysfs.h) | 0 | ||||
-rw-r--r-- | drivers/ufs/core/ufs_bsg.c (renamed from drivers/scsi/ufs/ufs_bsg.c) | 2 | ||||
-rw-r--r-- | drivers/ufs/core/ufs_bsg.h (renamed from drivers/scsi/ufs/ufs_bsg.h) | 0 | ||||
-rw-r--r-- | drivers/ufs/core/ufshcd-crypto.c (renamed from drivers/scsi/ufs/ufshcd-crypto.c) | 2 | ||||
-rw-r--r-- | drivers/ufs/core/ufshcd-crypto.h (renamed from drivers/scsi/ufs/ufshcd-crypto.h) | 4 | ||||
-rw-r--r-- | drivers/ufs/core/ufshcd-priv.h (renamed from drivers/scsi/ufs/ufshcd-priv.h) | 2 | ||||
-rw-r--r-- | drivers/ufs/core/ufshcd.c (renamed from drivers/scsi/ufs/ufshcd.c) | 9 | ||||
-rw-r--r-- | drivers/ufs/core/ufshpb.c (renamed from drivers/scsi/ufs/ufshpb.c) | 2 | ||||
-rw-r--r-- | drivers/ufs/core/ufshpb.h (renamed from drivers/scsi/ufs/ufshpb.h) | 0 | ||||
-rw-r--r-- | drivers/ufs/host/Kconfig (renamed from drivers/scsi/ufs/Kconfig) | 75 | ||||
-rw-r--r-- | drivers/ufs/host/Makefile (renamed from drivers/scsi/ufs/Makefile) | 12 | ||||
-rw-r--r-- | drivers/ufs/host/cdns-pltfrm.c (renamed from drivers/scsi/ufs/cdns-pltfrm.c) | 0 | ||||
-rw-r--r-- | drivers/ufs/host/tc-dwc-g210-pci.c (renamed from drivers/scsi/ufs/tc-dwc-g210-pci.c) | 2 | ||||
-rw-r--r-- | drivers/ufs/host/tc-dwc-g210-pltfrm.c (renamed from drivers/scsi/ufs/tc-dwc-g210-pltfrm.c) | 0 | ||||
-rw-r--r-- | drivers/ufs/host/tc-dwc-g210.c (renamed from drivers/scsi/ufs/tc-dwc-g210.c) | 4 | ||||
-rw-r--r-- | drivers/ufs/host/tc-dwc-g210.h (renamed from drivers/scsi/ufs/tc-dwc-g210.h) | 0 | ||||
-rw-r--r-- | drivers/ufs/host/ti-j721e-ufs.c (renamed from drivers/scsi/ufs/ti-j721e-ufs.c) | 0 | ||||
-rw-r--r-- | drivers/ufs/host/ufs-exynos.c (renamed from drivers/scsi/ufs/ufs-exynos.c) | 6 | ||||
-rw-r--r-- | drivers/ufs/host/ufs-exynos.h (renamed from drivers/scsi/ufs/ufs-exynos.h) | 0 | ||||
-rw-r--r-- | drivers/ufs/host/ufs-hisi.c (renamed from drivers/scsi/ufs/ufs-hisi.c) | 8 | ||||
-rw-r--r-- | drivers/ufs/host/ufs-hisi.h (renamed from drivers/scsi/ufs/ufs-hisi.h) | 0 | ||||
-rw-r--r-- | drivers/ufs/host/ufs-mediatek-trace.h (renamed from drivers/scsi/ufs/ufs-mediatek-trace.h) | 2 | ||||
-rw-r--r-- | drivers/ufs/host/ufs-mediatek.c (renamed from drivers/scsi/ufs/ufs-mediatek.c) | 6 | ||||
-rw-r--r-- | drivers/ufs/host/ufs-mediatek.h (renamed from drivers/scsi/ufs/ufs-mediatek.h) | 0 | ||||
-rw-r--r-- | drivers/ufs/host/ufs-qcom-ice.c (renamed from drivers/scsi/ufs/ufs-qcom-ice.c) | 0 | ||||
-rw-r--r-- | drivers/ufs/host/ufs-qcom.c (renamed from drivers/scsi/ufs/ufs-qcom.c) | 8 | ||||
-rw-r--r-- | drivers/ufs/host/ufs-qcom.h (renamed from drivers/scsi/ufs/ufs-qcom.h) | 2 | ||||
-rw-r--r-- | drivers/ufs/host/ufshcd-dwc.c (renamed from drivers/scsi/ufs/ufshcd-dwc.c) | 4 | ||||
-rw-r--r-- | drivers/ufs/host/ufshcd-dwc.h (renamed from drivers/scsi/ufs/ufshcd-dwc.h) | 2 | ||||
-rw-r--r-- | drivers/ufs/host/ufshcd-pci.c (renamed from drivers/scsi/ufs/ufshcd-pci.c) | 2 | ||||
-rw-r--r-- | drivers/ufs/host/ufshcd-pltfrm.c (renamed from drivers/scsi/ufs/ufshcd-pltfrm.c) | 4 | ||||
-rw-r--r-- | drivers/ufs/host/ufshcd-pltfrm.h (renamed from drivers/scsi/ufs/ufshcd-pltfrm.h) | 2 | ||||
-rw-r--r-- | drivers/ufs/host/ufshci-dwc.h (renamed from drivers/scsi/ufs/ufshci-dwc.h) | 0 |
78 files changed, 704 insertions, 3252 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index 38af943294ca..b6a172d32a7d 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -107,6 +107,8 @@ source "drivers/usb/Kconfig" source "drivers/mmc/Kconfig" +source "drivers/ufs/Kconfig" + source "drivers/memstick/Kconfig" source "drivers/leds/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 091627d60991..9a30842b22c5 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -128,6 +128,7 @@ obj-$(CONFIG_PM_OPP) += opp/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_CPU_IDLE) += cpuidle/ obj-y += mmc/ +obj-y += ufs/ obj-$(CONFIG_MEMSTICK) += memstick/ obj-$(CONFIG_NEW_LEDS) += leds/ obj-$(CONFIG_INFINIBAND) += infiniband/ diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 7ae72c7a211b..3c778bb0c294 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -1899,6 +1899,24 @@ nvme_fc_ctrl_ioerr_work(struct work_struct *work) nvme_fc_error_recovery(ctrl, "transport detected io error"); } +/* + * nvme_fc_io_getuuid - Routine called to get the appid field + * associated with request by the lldd + * @req:IO request from nvme fc to driver + * Returns: UUID if there is an appid associated with VM or + * NULL if the user/libvirt has not set the appid to VM + */ +char *nvme_fc_io_getuuid(struct nvmefc_fcp_req *req) +{ + struct nvme_fc_fcp_op *op = fcp_req_to_fcp_op(req); + struct request *rq = op->rq; + + if (!IS_ENABLED(CONFIG_BLK_CGROUP_FC_APPID) || !rq->bio) + return NULL; + return blkcg_get_fc_appid(rq->bio); +} +EXPORT_SYMBOL_GPL(nvme_fc_io_getuuid); + static void nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) { diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 6e3a04107bb6..a9fe5152addd 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -500,7 +500,6 @@ source "drivers/scsi/megaraid/Kconfig.megaraid" source "drivers/scsi/mpt3sas/Kconfig" source "drivers/scsi/mpi3mr/Kconfig" source "drivers/scsi/smartpqi/Kconfig" -source "drivers/scsi/ufs/Kconfig" config SCSI_HPTIOP tristate "HighPoint RocketRAID 3xxx/4xxx Controller support" diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 19814c26c908..2ad3bc052531 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -101,7 +101,6 @@ obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/ obj-$(CONFIG_MEGARAID_SAS) += megaraid/ obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas/ obj-$(CONFIG_SCSI_MPI3MR) += mpi3mr/ -obj-$(CONFIG_SCSI_UFSHCD) += ufs/ obj-$(CONFIG_SCSI_ACARD) += atp870u.o obj-$(CONFIG_SCSI_SUNESP) += esp_scsi.o sun_esp.o obj-$(CONFIG_SCSI_INITIO) += initio.o diff --git a/drivers/scsi/esas2r/esas2r_flash.c b/drivers/scsi/esas2r/esas2r_flash.c index 429d64299fe9..f910e2553fbb 100644 --- a/drivers/scsi/esas2r/esas2r_flash.c +++ b/drivers/scsi/esas2r/esas2r_flash.c @@ -232,7 +232,7 @@ static bool load_image(struct esas2r_adapter *a, struct esas2r_request *rq) */ rq->req_stat = RS_PENDING; if (test_bit(AF_DEGRADED_MODE, &a->flags)) - /* not suppported for now */; + /* not supported for now */; else build_flash_msg(a, rq); diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index ac17e3a35d2c..6370cdbfba08 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -2182,7 +2182,7 @@ static enum sci_status atapi_data_tc_completion_handler(struct isci_request *ire case (SCU_TASK_DONE_UNEXP_FIS << SCU_COMPLETION_TL_STATUS_SHIFT): { u16 len = sci_req_tx_bytes(ireq); - /* likely non-error data underrrun, workaround missing + /* likely non-error data underrun, workaround missing * d2h frame from the controller */ if (d2h->fis_type != FIS_REGD2H) { diff --git a/drivers/scsi/lpfc/Makefile b/drivers/scsi/lpfc/Makefile index 092a971d066b..bbd1faf41e80 100644 --- a/drivers/scsi/lpfc/Makefile +++ b/drivers/scsi/lpfc/Makefile @@ -33,4 +33,4 @@ obj-$(CONFIG_SCSI_LPFC) := lpfc.o lpfc-objs := lpfc_mem.o lpfc_sli.o lpfc_ct.o lpfc_els.o \ lpfc_hbadisc.o lpfc_init.o lpfc_mbox.o lpfc_nportdisc.o \ lpfc_scsi.o lpfc_attr.o lpfc_vport.o lpfc_debugfs.o lpfc_bsg.o \ - lpfc_nvme.o lpfc_nvmet.o + lpfc_nvme.o lpfc_nvmet.o lpfc_vmid.o diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index b0775be31d5c..b1be0dd0337a 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -671,6 +671,9 @@ int lpfc_vmid_cmd(struct lpfc_vport *vport, int lpfc_vmid_hash_fn(const char *vmid, int len); struct lpfc_vmid *lpfc_get_vmid_from_hashtable(struct lpfc_vport *vport, uint32_t hash, uint8_t *buf); +int lpfc_vmid_get_appid(struct lpfc_vport *vport, char *uuid, + enum dma_data_direction iodir, + union lpfc_vmid_io_tag *tag); void lpfc_vmid_vport_cleanup(struct lpfc_vport *vport); int lpfc_issue_els_qfpa(struct lpfc_vport *vport); diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 748c53219986..7b8cf678abb5 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -1736,6 +1736,28 @@ struct lpfc_fdmi_reg_portattr { #define PCI_DEVICE_ID_TOMCAT 0x0714 #define PCI_DEVICE_ID_SKYHAWK 0x0724 #define PCI_DEVICE_ID_SKYHAWK_VF 0x072c +#define PCI_VENDOR_ID_ATTO 0x117c +#define PCI_DEVICE_ID_CLRY_16XE 0x0064 +#define PCI_DEVICE_ID_CLRY_161E 0x0063 +#define PCI_DEVICE_ID_CLRY_162E 0x0064 +#define PCI_DEVICE_ID_CLRY_164E 0x0065 +#define PCI_DEVICE_ID_CLRY_16XP 0x0094 +#define PCI_DEVICE_ID_CLRY_161P 0x00a0 +#define PCI_DEVICE_ID_CLRY_162P 0x0094 +#define PCI_DEVICE_ID_CLRY_164P 0x00a1 +#define PCI_DEVICE_ID_CLRY_32XE 0x0094 +#define PCI_DEVICE_ID_CLRY_321E 0x00a2 +#define PCI_DEVICE_ID_CLRY_322E 0x00a3 +#define PCI_DEVICE_ID_CLRY_324E 0x00ac +#define PCI_DEVICE_ID_CLRY_32XP 0x00bb +#define PCI_DEVICE_ID_CLRY_321P 0x00bc +#define PCI_DEVICE_ID_CLRY_322P 0x00bd +#define PCI_DEVICE_ID_CLRY_324P 0x00be +#define PCI_DEVICE_ID_TLFC_2 0x0064 +#define PCI_DEVICE_ID_TLFC_2XX2 0x4064 +#define PCI_DEVICE_ID_TLFC_3 0x0094 +#define PCI_DEVICE_ID_TLFC_3162 0x40a6 +#define PCI_DEVICE_ID_TLFC_3322 0x40a7 #define JEDEC_ID_ADDRESS 0x0080001c #define FIREFLY_JEDEC_ID 0x1ACC diff --git a/drivers/scsi/lpfc/lpfc_ids.h b/drivers/scsi/lpfc/lpfc_ids.h index 6a90e6e53d09..a1b9be245560 100644 --- a/drivers/scsi/lpfc/lpfc_ids.h +++ b/drivers/scsi/lpfc/lpfc_ids.h @@ -124,5 +124,35 @@ const struct pci_device_id lpfc_id_table[] = { PCI_ANY_ID, PCI_ANY_ID, }, {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK_VF, PCI_ANY_ID, PCI_ANY_ID, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_16XE, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_161E, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_16XE, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_162E, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_16XE, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_164E, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_16XP, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_161P, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_16XP, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_162P, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_16XP, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_164P, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_32XE, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_321E, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_32XE, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_322E, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_32XE, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_324E, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_32XP, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_321P, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_32XP, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_322P, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_32XP, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_324P, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_TLFC_2, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_TLFC_2XX2, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_TLFC_3, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_TLFC_3162, }, + {PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_TLFC_3, + PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_TLFC_3322, }, { 0 } }; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 2bffaa681fcc..93b94c64518d 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -2415,6 +2415,90 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len) } /** + * lpfc_get_atto_model_desc - Retrieve ATTO HBA device model name and description + * @phba: pointer to lpfc hba data structure. + * @mdp: pointer to the data structure to hold the derived model name. + * @descp: pointer to the data structure to hold the derived description. + * + * This routine retrieves HBA's description based on its registered PCI device + * ID. The @descp passed into this function points to an array of 256 chars. It + * shall be returned with the model name, maximum speed, and the host bus type. + * The @mdp passed into this function points to an array of 80 chars. When the + * function returns, the @mdp will be filled with the model name. + **/ +static void +lpfc_get_atto_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) +{ + uint16_t sub_dev_id = phba->pcidev->subsystem_device; + char *model = "<Unknown>"; + int tbolt = 0; + + switch (sub_dev_id) { + case PCI_DEVICE_ID_CLRY_161E: + model = "161E"; + break; + case PCI_DEVICE_ID_CLRY_162E: + model = "162E"; + break; + case PCI_DEVICE_ID_CLRY_164E: + model = "164E"; + break; + case PCI_DEVICE_ID_CLRY_161P: + model = "161P"; + break; + case PCI_DEVICE_ID_CLRY_162P: + model = "162P"; + break; + case PCI_DEVICE_ID_CLRY_164P: + model = "164P"; + break; + case PCI_DEVICE_ID_CLRY_321E: + model = "321E"; + break; + case PCI_DEVICE_ID_CLRY_322E: + model = "322E"; + break; + case PCI_DEVICE_ID_CLRY_324E: + model = "324E"; + break; + case PCI_DEVICE_ID_CLRY_321P: + model = "321P"; + break; + case PCI_DEVICE_ID_CLRY_322P: + model = "322P"; + break; + case PCI_DEVICE_ID_CLRY_324P: + model = "324P"; + break; + case PCI_DEVICE_ID_TLFC_2XX2: + model = "2XX2"; + tbolt = 1; + break; + case PCI_DEVICE_ID_TLFC_3162: + model = "3162"; + tbolt = 1; + break; + case PCI_DEVICE_ID_TLFC_3322: + model = "3322"; + tbolt = 1; + break; + default: + model = "Unknown"; + break; + } + + if (mdp && mdp[0] == '\0') + snprintf(mdp, 79, "%s", model); + + if (descp && descp[0] == '\0') + snprintf(descp, 255, + "ATTO %s%s, Fibre Channel Adapter Initiator, Port %s", + (tbolt) ? "ThunderLink FC " : "Celerity FC-", + model, + phba->Port); +} + +/** * lpfc_get_hba_model_desc - Retrieve HBA device model name and description * @phba: pointer to lpfc hba data structure. * @mdp: pointer to the data structure to hold the derived model name. @@ -2444,6 +2528,11 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) && descp && descp[0] != '\0') return; + if (phba->pcidev->vendor == PCI_VENDOR_ID_ATTO) { + lpfc_get_atto_model_desc(phba, mdp, descp); + return; + } + if (phba->lmt & LMT_64Gb) max_speed = 64; else if (phba->lmt & LMT_32Gb) diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 5385f4de5523..335e90633933 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1279,6 +1279,19 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport, /* Words 13 14 15 are for PBDE support */ + /* add the VMID tags as per switch response */ + if (unlikely(lpfc_ncmd->cur_iocbq.cmd_flag & LPFC_IO_VMID)) { + if (phba->pport->vmid_priority_tagging) { + bf_set(wqe_ccpe, &wqe->fcp_iwrite.wqe_com, 1); + bf_set(wqe_ccp, &wqe->fcp_iwrite.wqe_com, + lpfc_ncmd->cur_iocbq.vmid_tag.cs_ctl_vmid); + } else { + bf_set(wqe_appid, &wqe->fcp_iwrite.wqe_com, 1); + bf_set(wqe_wqes, &wqe->fcp_iwrite.wqe_com, 1); + wqe->words[31] = lpfc_ncmd->cur_iocbq.vmid_tag.app_id; + } + } + pwqeq->vport = vport; return 0; } @@ -1504,6 +1517,11 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, struct lpfc_nvme_fcpreq_priv *freqpriv; struct nvme_common_command *sqe; uint64_t start = 0; +#if (IS_ENABLED(CONFIG_NVME_FC)) + u8 *uuid = NULL; + int err; + enum dma_data_direction iodir; +#endif /* Validate pointers. LLDD fault handling with transport does * have timing races. @@ -1662,6 +1680,33 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, lpfc_ncmd->ndlp = ndlp; lpfc_ncmd->qidx = lpfc_queue_info->qidx; +#if (IS_ENABLED(CONFIG_NVME_FC)) + /* check the necessary and sufficient condition to support VMID */ + if (lpfc_is_vmid_enabled(phba) && + (ndlp->vmid_support || + phba->pport->vmid_priority_tagging == + LPFC_VMID_PRIO_TAG_ALL_TARGETS)) { + /* is the I/O generated by a VM, get the associated virtual */ + /* entity id */ + uuid = nvme_fc_io_getuuid(pnvme_fcreq); + + if (uuid) { + if (pnvme_fcreq->io_dir == NVMEFC_FCP_WRITE) + iodir = DMA_TO_DEVICE; + else if (pnvme_fcreq->io_dir == NVMEFC_FCP_READ) + iodir = DMA_FROM_DEVICE; + else + iodir = DMA_NONE; + + err = lpfc_vmid_get_appid(vport, uuid, iodir, + (union lpfc_vmid_io_tag *) + &lpfc_ncmd->cur_iocbq.vmid_tag); + if (!err) + lpfc_ncmd->cur_iocbq.cmd_flag |= LPFC_IO_VMID; + } + } +#endif + /* * Issue the IO on the WQ indicated by index in the hw_queue_handle. * This identfier was create in our hardware queue create callback diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 3b8afa9d3056..d43968203248 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -87,14 +87,6 @@ static void lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_io_buf *psb); static int lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc); -static void -lpfc_put_vmid_in_hashtable(struct lpfc_vport *vport, u32 hash, - struct lpfc_vmid *vmp); -static void lpfc_vmid_update_entry(struct lpfc_vport *vport, struct scsi_cmnd - *cmd, struct lpfc_vmid *vmp, - union lpfc_vmid_io_tag *tag); -static void lpfc_vmid_assign_cs_ctl(struct lpfc_vport *vport, - struct lpfc_vmid *vmid); /** * lpfc_sli4_set_rsp_sgl_last - Set the last bit in the response sge. @@ -5271,254 +5263,6 @@ void lpfc_poll_timeout(struct timer_list *t) } /* - * lpfc_get_vmid_from_hashtable - search the UUID in the hash table - * @vport: The virtual port for which this call is being executed. - * @hash: calculated hash value - * @buf: uuid associated with the VE - * Return the VMID entry associated with the UUID - * Make sure to acquire the appropriate lock before invoking this routine. - */ -struct lpfc_vmid *lpfc_get_vmid_from_hashtable(struct lpfc_vport *vport, - u32 hash, u8 *buf) -{ - struct lpfc_vmid *vmp; - - hash_for_each_possible(vport->hash_table, vmp, hnode, hash) { - if (memcmp(&vmp->host_vmid[0], buf, 16) == 0) - return vmp; - } - return NULL; -} - -/* - * lpfc_put_vmid_in_hashtable - put the VMID in the hash table - * @vport: The virtual port for which this call is being executed. - * @hash - calculated hash value - * @vmp: Pointer to a VMID entry representing a VM sending I/O - * - * This routine will insert the newly acquired VMID entity in the hash table. - * Make sure to acquire the appropriate lock before invoking this routine. - */ -static void -lpfc_put_vmid_in_hashtable(struct lpfc_vport *vport, u32 hash, - struct lpfc_vmid *vmp) -{ - hash_add(vport->hash_table, &vmp->hnode, hash); -} - -/* - * lpfc_vmid_hash_fn - create a hash value of the UUID - * @vmid: uuid associated with the VE - * @len: length of the VMID string - * Returns the calculated hash value - */ -int lpfc_vmid_hash_fn(const char *vmid, int len) -{ - int c; - int hash = 0; - - if (len == 0) - return 0; - while (len--) { - c = *vmid++; - if (c >= 'A' && c <= 'Z') - c += 'a' - 'A'; - - hash = (hash + (c << LPFC_VMID_HASH_SHIFT) + - (c >> LPFC_VMID_HASH_SHIFT)) * 19; - } - - return hash & LPFC_VMID_HASH_MASK; -} - -/* - * lpfc_vmid_update_entry - update the vmid entry in the hash table - * @vport: The virtual port for which this call is being executed. - * @cmd: address of scsi cmd descriptor - * @vmp: Pointer to a VMID entry representing a VM sending I/O - * @tag: VMID tag - */ -static void lpfc_vmid_update_entry(struct lpfc_vport *vport, struct scsi_cmnd - *cmd, struct lpfc_vmid *vmp, - union lpfc_vmid_io_tag *tag) -{ - u64 *lta; - - if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO) - tag->cs_ctl_vmid = vmp->un.cs_ctl_vmid; - else if (vport->phba->cfg_vmid_app_header) - tag->app_id = vmp->un.app_id; - - if (cmd->sc_data_direction == DMA_TO_DEVICE) - vmp->io_wr_cnt++; - else - vmp->io_rd_cnt++; - - /* update the last access timestamp in the table */ - lta = per_cpu_ptr(vmp->last_io_time, raw_smp_processor_id()); - *lta = jiffies; -} - -static void lpfc_vmid_assign_cs_ctl(struct lpfc_vport *vport, - struct lpfc_vmid *vmid) -{ - u32 hash; - struct lpfc_vmid *pvmid; - - if (vport->port_type == LPFC_PHYSICAL_PORT) { - vmid->un.cs_ctl_vmid = lpfc_vmid_get_cs_ctl(vport); - } else { - hash = lpfc_vmid_hash_fn(vmid->host_vmid, vmid->vmid_len); - pvmid = - lpfc_get_vmid_from_hashtable(vport->phba->pport, hash, - vmid->host_vmid); - if (pvmid) - vmid->un.cs_ctl_vmid = pvmid->un.cs_ctl_vmid; - else - vmid->un.cs_ctl_vmid = lpfc_vmid_get_cs_ctl(vport); - } -} - -/* - * lpfc_vmid_get_appid - get the VMID associated with the UUID - * @vport: The virtual port for which this call is being executed. - * @uuid: UUID associated with the VE - * @cmd: address of scsi_cmd descriptor - * @tag: VMID tag - * Returns status of the function - */ -static int lpfc_vmid_get_appid(struct lpfc_vport *vport, char *uuid, struct - scsi_cmnd * cmd, union lpfc_vmid_io_tag *tag) -{ - struct lpfc_vmid *vmp = NULL; - int hash, len, rc = -EPERM, i; - - /* check if QFPA is complete */ - if (lpfc_vmid_is_type_priority_tag(vport) && - !(vport->vmid_flag & LPFC_VMID_QFPA_CMPL) && - (vport->vmid_flag & LPFC_VMID_ISSUE_QFPA)) { - vport->work_port_events |= WORKER_CHECK_VMID_ISSUE_QFPA; - return -EAGAIN; - } - - /* search if the UUID has already been mapped to the VMID */ - len = strlen(uuid); - hash = lpfc_vmid_hash_fn(uuid, len); - - /* search for the VMID in the table */ - read_lock(&vport->vmid_lock); - vmp = lpfc_get_vmid_from_hashtable(vport, hash, uuid); - - /* if found, check if its already registered */ - if (vmp && vmp->flag & LPFC_VMID_REGISTERED) { - read_unlock(&vport->vmid_lock); - lpfc_vmid_update_entry(vport, cmd, vmp, tag); - rc = 0; - } else if (vmp && (vmp->flag & LPFC_VMID_REQ_REGISTER || - vmp->flag & LPFC_VMID_DE_REGISTER)) { - /* else if register or dereg request has already been sent */ - /* Hence VMID tag will not be added for this I/O */ - read_unlock(&vport->vmid_lock); - rc = -EBUSY; - } else { - /* The VMID was not found in the hashtable. At this point, */ - /* drop the read lock first before proceeding further */ - read_unlock(&vport->vmid_lock); - /* start the process to obtain one as per the */ - /* type of the VMID indicated */ - write_lock(&vport->vmid_lock); - vmp = lpfc_get_vmid_from_hashtable(vport, hash, uuid); - - /* while the read lock was released, in case the entry was */ - /* added by other context or is in process of being added */ - if (vmp && vmp->flag & LPFC_VMID_REGISTERED) { - lpfc_vmid_update_entry(vport, cmd, vmp, tag); - write_unlock(&vport->vmid_lock); - return 0; - } else if (vmp && vmp->flag & LPFC_VMID_REQ_REGISTER) { - write_unlock(&vport->vmid_lock); - return -EBUSY; - } - - /* else search and allocate a free slot in the hash table */ - if (vport->cur_vmid_cnt < vport->max_vmid) { - for (i = 0; i < vport->max_vmid; i++) { - vmp = vport->vmid + i; - if (vmp->flag == LPFC_VMID_SLOT_FREE) - break; - } - if (i == vport->max_vmid) - vmp = NULL; - } else { - vmp = NULL; - } - - if (!vmp) { - write_unlock(&vport->vmid_lock); - return -ENOMEM; - } - - /* Add the vmid and register */ - lpfc_put_vmid_in_hashtable(vport, hash, vmp); - vmp->vmid_len = len; - memcpy(vmp->host_vmid, uuid, vmp->vmid_len); - vmp->io_rd_cnt = 0; - vmp->io_wr_cnt = 0; - vmp->flag = LPFC_VMID_SLOT_USED; - - vmp->delete_inactive = - vport->vmid_inactivity_timeout ? 1 : 0; - - /* if type priority tag, get next available VMID */ - if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO) - lpfc_vmid_assign_cs_ctl(vport, vmp); - - /* allocate the per cpu variable for holding */ - /* the last access time stamp only if VMID is enabled */ - if (!vmp->last_io_time) - vmp->last_io_time = __alloc_percpu(sizeof(u64), - __alignof__(struct - lpfc_vmid)); - if (!vmp->last_io_time) { - hash_del(&vmp->hnode); - vmp->flag = LPFC_VMID_SLOT_FREE; - write_unlock(&vport->vmid_lock); - return -EIO; - } - - write_unlock(&vport->vmid_lock); - - /* complete transaction with switch */ - if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO) - rc = lpfc_vmid_uvem(vport, vmp, true); - else if (vport->phba->cfg_vmid_app_header) - rc = lpfc_vmid_cmd(vport, SLI_CTAS_RAPP_IDENT, vmp); - if (!rc) { - write_lock(&vport->vmid_lock); - vport->cur_vmid_cnt++; - vmp->flag |= LPFC_VMID_REQ_REGISTER; - write_unlock(&vport->vmid_lock); - } else { - write_lock(&vport->vmid_lock); - hash_del(&vmp->hnode); - vmp->flag = LPFC_VMID_SLOT_FREE; - free_percpu(vmp->last_io_time); - write_unlock(&vport->vmid_lock); - return -EIO; - } - - /* finally, enable the idle timer once */ - if (!(vport->phba->pport->vmid_flag & LPFC_VMID_TIMER_ENBLD)) { - mod_timer(&vport->phba->inactive_vmid_poll, - jiffies + - msecs_to_jiffies(1000 * LPFC_VMID_TIMER)); - vport->phba->pport->vmid_flag |= LPFC_VMID_TIMER_ENBLD; - } - } - return rc; -} - -/* * lpfc_is_command_vm_io - get the UUID from blk cgroup * @cmd: Pointer to scsi_cmnd data structure * Returns UUID if present, otherwise NULL @@ -5704,9 +5448,10 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) uuid = lpfc_is_command_vm_io(cmnd); if (uuid) { - err = lpfc_vmid_get_appid(vport, uuid, cmnd, - (union lpfc_vmid_io_tag *) - &cur_iocbq->vmid_tag); + err = lpfc_vmid_get_appid(vport, uuid, + cmnd->sc_data_direction, + (union lpfc_vmid_io_tag *) + &cur_iocbq->vmid_tag); if (!err) cur_iocbq->cmd_flag |= LPFC_IO_VMID; } diff --git a/drivers/scsi/lpfc/lpfc_vmid.c b/drivers/scsi/lpfc/lpfc_vmid.c new file mode 100644 index 000000000000..f64ced04b912 --- /dev/null +++ b/drivers/scsi/lpfc/lpfc_vmid.c @@ -0,0 +1,288 @@ +/******************************************************************* + * This file is part of the Emulex Linux Device Driver for * + * Fibre Channel Host Bus Adapters. * + * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term * + * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * + * Copyright (C) 2004-2016 Emulex. All rights reserved. * + * EMULEX and SLI are trademarks of Emulex. * + * www.broadcom.com * + * Portions Copyright (C) 2004-2005 Christoph Hellwig * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of version 2 of the GNU General * + * Public License as published by the Free Software Foundation. * + * This program is distributed in the hope that it will be useful. * + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * + * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * + * TO BE LEGALLY INVALID. See the GNU General Public License for * + * more details, a copy of which can be found in the file COPYING * + * included with this package. * + *******************************************************************/ + +#include <linux/interrupt.h> +#include <linux/dma-direction.h> + +#include <scsi/scsi_transport_fc.h> + +#include "lpfc_hw4.h" +#include "lpfc_hw.h" +#include "lpfc_sli.h" +#include "lpfc_sli4.h" +#include "lpfc_nl.h" +#include "lpfc_disc.h" +#include "lpfc.h" +#include "lpfc_crtn.h" + + +/* + * lpfc_get_vmid_from_hashtable - search the UUID in the hash table + * @vport: The virtual port for which this call is being executed. + * @hash: calculated hash value + * @buf: uuid associated with the VE + * Return the VMID entry associated with the UUID + * Make sure to acquire the appropriate lock before invoking this routine. + */ +struct lpfc_vmid *lpfc_get_vmid_from_hashtable(struct lpfc_vport *vport, + u32 hash, u8 *buf) +{ + struct lpfc_vmid *vmp; + + hash_for_each_possible(vport->hash_table, vmp, hnode, hash) { + if (memcmp(&vmp->host_vmid[0], buf, 16) == 0) + return vmp; + } + return NULL; +} + +/* + * lpfc_put_vmid_in_hashtable - put the VMID in the hash table + * @vport: The virtual port for which this call is being executed. + * @hash - calculated hash value + * @vmp: Pointer to a VMID entry representing a VM sending I/O + * + * This routine will insert the newly acquired VMID entity in the hash table. + * Make sure to acquire the appropriate lock before invoking this routine. + */ +static void +lpfc_put_vmid_in_hashtable(struct lpfc_vport *vport, u32 hash, + struct lpfc_vmid *vmp) +{ + hash_add(vport->hash_table, &vmp->hnode, hash); +} + +/* + * lpfc_vmid_hash_fn - create a hash value of the UUID + * @vmid: uuid associated with the VE + * @len: length of the VMID string + * Returns the calculated hash value + */ +int lpfc_vmid_hash_fn(const char *vmid, int len) +{ + int c; + int hash = 0; + + if (len == 0) + return 0; + while (len--) { + c = *vmid++; + if (c >= 'A' && c <= 'Z') + c += 'a' - 'A'; + + hash = (hash + (c << LPFC_VMID_HASH_SHIFT) + + (c >> LPFC_VMID_HASH_SHIFT)) * 19; + } + + return hash & LPFC_VMID_HASH_MASK; +} + +/* + * lpfc_vmid_update_entry - update the vmid entry in the hash table + * @vport: The virtual port for which this call is being executed. + * @iodir: io direction + * @vmp: Pointer to a VMID entry representing a VM sending I/O + * @tag: VMID tag + */ +static void lpfc_vmid_update_entry(struct lpfc_vport *vport, + enum dma_data_direction iodir, + struct lpfc_vmid *vmp, + union lpfc_vmid_io_tag *tag) +{ + u64 *lta; + + if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO) + tag->cs_ctl_vmid = vmp->un.cs_ctl_vmid; + else if (vport->phba->cfg_vmid_app_header) + tag->app_id = vmp->un.app_id; + + if (iodir == DMA_TO_DEVICE) + vmp->io_wr_cnt++; + else if (iodir == DMA_FROM_DEVICE) + vmp->io_rd_cnt++; + + /* update the last access timestamp in the table */ + lta = per_cpu_ptr(vmp->last_io_time, raw_smp_processor_id()); + *lta = jiffies; +} + +static void lpfc_vmid_assign_cs_ctl(struct lpfc_vport *vport, + struct lpfc_vmid *vmid) +{ + u32 hash; + struct lpfc_vmid *pvmid; + + if (vport->port_type == LPFC_PHYSICAL_PORT) { + vmid->un.cs_ctl_vmid = lpfc_vmid_get_cs_ctl(vport); + } else { + hash = lpfc_vmid_hash_fn(vmid->host_vmid, vmid->vmid_len); + pvmid = + lpfc_get_vmid_from_hashtable(vport->phba->pport, hash, + vmid->host_vmid); + if (pvmid) + vmid->un.cs_ctl_vmid = pvmid->un.cs_ctl_vmid; + else + vmid->un.cs_ctl_vmid = lpfc_vmid_get_cs_ctl(vport); + } +} + +/* + * lpfc_vmid_get_appid - get the VMID associated with the UUID + * @vport: The virtual port for which this call is being executed. + * @uuid: UUID associated with the VE + * @cmd: address of scsi_cmd descriptor + * @iodir: io direction + * @tag: VMID tag + * Returns status of the function + */ +int lpfc_vmid_get_appid(struct lpfc_vport *vport, char *uuid, + enum dma_data_direction iodir, + union lpfc_vmid_io_tag *tag) +{ + struct lpfc_vmid *vmp = NULL; + int hash, len, rc = -EPERM, i; + + /* check if QFPA is complete */ + if (lpfc_vmid_is_type_priority_tag(vport) && + !(vport->vmid_flag & LPFC_VMID_QFPA_CMPL) && + (vport->vmid_flag & LPFC_VMID_ISSUE_QFPA)) { + vport->work_port_events |= WORKER_CHECK_VMID_ISSUE_QFPA; + return -EAGAIN; + } + + /* search if the UUID has already been mapped to the VMID */ + len = strlen(uuid); + hash = lpfc_vmid_hash_fn(uuid, len); + + /* search for the VMID in the table */ + read_lock(&vport->vmid_lock); + vmp = lpfc_get_vmid_from_hashtable(vport, hash, uuid); + + /* if found, check if its already registered */ + if (vmp && vmp->flag & LPFC_VMID_REGISTERED) { + read_unlock(&vport->vmid_lock); + lpfc_vmid_update_entry(vport, iodir, vmp, tag); + rc = 0; + } else if (vmp && (vmp->flag & LPFC_VMID_REQ_REGISTER || + vmp->flag & LPFC_VMID_DE_REGISTER)) { + /* else if register or dereg request has already been sent */ + /* Hence VMID tag will not be added for this I/O */ + read_unlock(&vport->vmid_lock); + rc = -EBUSY; + } else { + /* The VMID was not found in the hashtable. At this point, */ + /* drop the read lock first before proceeding further */ + read_unlock(&vport->vmid_lock); + /* start the process to obtain one as per the */ + /* type of the VMID indicated */ + write_lock(&vport->vmid_lock); + vmp = lpfc_get_vmid_from_hashtable(vport, hash, uuid); + + /* while the read lock was released, in case the entry was */ + /* added by other context or is in process of being added */ + if (vmp && vmp->flag & LPFC_VMID_REGISTERED) { + lpfc_vmid_update_entry(vport, iodir, vmp, tag); + write_unlock(&vport->vmid_lock); + return 0; + } else if (vmp && vmp->flag & LPFC_VMID_REQ_REGISTER) { + write_unlock(&vport->vmid_lock); + return -EBUSY; + } + + /* else search and allocate a free slot in the hash table */ + if (vport->cur_vmid_cnt < vport->max_vmid) { + for (i = 0; i < vport->max_vmid; i++) { + vmp = vport->vmid + i; + if (vmp->flag == LPFC_VMID_SLOT_FREE) + break; + } + if (i == vport->max_vmid) + vmp = NULL; + } else { + vmp = NULL; + } + + if (!vmp) { + write_unlock(&vport->vmid_lock); + return -ENOMEM; + } + + /* Add the vmid and register */ + lpfc_put_vmid_in_hashtable(vport, hash, vmp); + vmp->vmid_len = len; + memcpy(vmp->host_vmid, uuid, vmp->vmid_len); + vmp->io_rd_cnt = 0; + vmp->io_wr_cnt = 0; + vmp->flag = LPFC_VMID_SLOT_USED; + + vmp->delete_inactive = + vport->vmid_inactivity_timeout ? 1 : 0; + + /* if type priority tag, get next available VMID */ + if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO) + lpfc_vmid_assign_cs_ctl(vport, vmp); + + /* allocate the per cpu variable for holding */ + /* the last access time stamp only if VMID is enabled */ + if (!vmp->last_io_time) + vmp->last_io_time = __alloc_percpu(sizeof(u64), + __alignof__(struct + lpfc_vmid)); + if (!vmp->last_io_time) { + hash_del(&vmp->hnode); + vmp->flag = LPFC_VMID_SLOT_FREE; + write_unlock(&vport->vmid_lock); + return -EIO; + } + + write_unlock(&vport->vmid_lock); + + /* complete transaction with switch */ + if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO) + rc = lpfc_vmid_uvem(vport, vmp, true); + else if (vport->phba->cfg_vmid_app_header) + rc = lpfc_vmid_cmd(vport, SLI_CTAS_RAPP_IDENT, vmp); + if (!rc) { + write_lock(&vport->vmid_lock); + vport->cur_vmid_cnt++; + vmp->flag |= LPFC_VMID_REQ_REGISTER; + write_unlock(&vport->vmid_lock); + } else { + write_lock(&vport->vmid_lock); + hash_del(&vmp->hnode); + vmp->flag = LPFC_VMID_SLOT_FREE; + free_percpu(vmp->last_io_time); + write_unlock(&vport->vmid_lock); + return -EIO; + } + + /* finally, enable the idle timer once */ + if (!(vport->phba->pport->vmid_flag & LPFC_VMID_TIMER_ENBLD)) { + mod_timer(&vport->phba->inactive_vmid_poll, + jiffies + + msecs_to_jiffies(1000 * LPFC_VMID_TIMER)); + vport->phba->pport->vmid_flag |= LPFC_VMID_TIMER_ENBLD; + } + } + return rc; +} diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h index 01cd01787b0f..0e1cb4aa4ca2 100644 --- a/drivers/scsi/mpi3mr/mpi3mr.h +++ b/drivers/scsi/mpi3mr/mpi3mr.h @@ -954,7 +954,7 @@ struct mpi3mr_ioc { u16 active_poll_qcount; u16 requested_poll_qcount; - struct device *bsg_dev; + struct device bsg_dev; struct request_queue *bsg_queue; u8 stop_bsgs; u8 *logdata_buf; diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c index 9ab1762468ad..9baac224b213 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_app.c +++ b/drivers/scsi/mpi3mr/mpi3mr_app.c @@ -1487,28 +1487,28 @@ static int mpi3mr_bsg_request(struct bsg_job *job) */ void mpi3mr_bsg_exit(struct mpi3mr_ioc *mrioc) { + struct device *bsg_dev = &mrioc->bsg_dev; if (!mrioc->bsg_queue) return; bsg_remove_queue(mrioc->bsg_queue); mrioc->bsg_queue = NULL; - device_del(mrioc->bsg_dev); - put_device(mrioc->bsg_dev); - kfree(mrioc->bsg_dev); + device_del(bsg_dev); + put_device(bsg_dev); } /** * mpi3mr_bsg_node_release -release bsg device node * @dev: bsg device node * - * decrements bsg dev reference count + * decrements bsg dev parent reference count * * Return:Nothing */ static void mpi3mr_bsg_node_release(struct device *dev) { - put_device(dev); + put_device(dev->parent); } /** @@ -1521,41 +1521,37 @@ static void mpi3mr_bsg_node_release(struct device *dev) */ void mpi3mr_bsg_init(struct mpi3mr_ioc *mrioc) { - mrioc->bsg_dev = kzalloc(sizeof(struct device), GFP_KERNEL); - if (!mrioc->bsg_dev) { - ioc_err(mrioc, "bsg device mem allocation failed\n"); - return; - } + struct device *bsg_dev = &mrioc->bsg_dev; + struct device *parent = &mrioc->shost->shost_gendev; + + device_initialize(bsg_dev); + + bsg_dev->parent = get_device(parent); + bsg_dev->release = mpi3mr_bsg_node_release; - device_initialize(mrioc->bsg_dev); - dev_set_name(mrioc->bsg_dev, "mpi3mrctl%u", mrioc->id); + dev_set_name(bsg_dev, "mpi3mrctl%u", mrioc->id); - if (device_add(mrioc->bsg_dev)) { + if (device_add(bsg_dev)) { ioc_err(mrioc, "%s: bsg device add failed\n", - dev_name(mrioc->bsg_dev)); - goto err_device_add; + dev_name(bsg_dev)); + put_device(bsg_dev); + return; } - mrioc->bsg_dev->release = mpi3mr_bsg_node_release; - - mrioc->bsg_queue = bsg_setup_queue(mrioc->bsg_dev, dev_name(mrioc->bsg_dev), + mrioc->bsg_queue = bsg_setup_queue(bsg_dev, dev_name(bsg_dev), mpi3mr_bsg_request, NULL, 0); if (IS_ERR(mrioc->bsg_queue)) { ioc_err(mrioc, "%s: bsg registration failed\n", - dev_name(mrioc->bsg_dev)); - goto err_setup_queue; + dev_name(bsg_dev)); + device_del(bsg_dev); + put_device(bsg_dev); + return; } blk_queue_max_segments(mrioc->bsg_queue, MPI3MR_MAX_APP_XFER_SEGMENTS); blk_queue_max_hw_sectors(mrioc->bsg_queue, MPI3MR_MAX_APP_XFER_SECTORS); return; - -err_setup_queue: - device_del(mrioc->bsg_dev); - put_device(mrioc->bsg_dev); -err_device_add: - kfree(mrioc->bsg_dev); } /** @@ -1693,7 +1689,7 @@ logging_level_store(struct device *dev, static DEVICE_ATTR_RW(logging_level); /** - * adapter_state_show - SysFS callback for adapter state show + * adp_state_show() - SysFS callback for adapter state show * @dev: class device * @attr: Device attributes * @buf: Buffer to copy diff --git a/drivers/scsi/myrb.c b/drivers/scsi/myrb.c index 71585528e8db..e885c1dbf61f 100644 --- a/drivers/scsi/myrb.c +++ b/drivers/scsi/myrb.c @@ -1239,7 +1239,8 @@ static void myrb_cleanup(struct myrb_hba *cb) myrb_unmap(cb); if (cb->mmio_base) { - cb->disable_intr(cb->io_base); + if (cb->disable_intr) + cb->disable_intr(cb->io_base); iounmap(cb->mmio_base); } if (cb->irq) @@ -3413,9 +3414,13 @@ static struct myrb_hba *myrb_detect(struct pci_dev *pdev, mutex_init(&cb->dcmd_mutex); mutex_init(&cb->dma_mutex); cb->pdev = pdev; + cb->host = shost; - if (pci_enable_device(pdev)) - goto failure; + if (pci_enable_device(pdev)) { + dev_err(&pdev->dev, "Failed to enable PCI device\n"); + scsi_host_put(shost); + return NULL; + } if (privdata->hw_init == DAC960_PD_hw_init || privdata->hw_init == DAC960_P_hw_init) { diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 3d5cd337a2a6..bfce60183a6e 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -1434,7 +1434,7 @@ static int pmcraid_notify_aen( return -EINVAL; } - /* send genetlink multicast message to notify appplications */ + /* send genetlink multicast message to notify applications */ genlmsg_end(skb, msg_header); result = genlmsg_multicast(&pmcraid_event_family, skb, diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c index e57cc22453d0..4750ec5789a8 100644 --- a/drivers/scsi/qedf/qedf_io.c +++ b/drivers/scsi/qedf/qedf_io.c @@ -893,7 +893,7 @@ int qedf_post_io_req(struct qedf_rport *fcport, struct qedf_ioreq *io_req) return -EINVAL; } - /* Record LUN number for later use if we neeed them */ + /* Record LUN number for later use if we need them */ io_req->lun = (int)sc_cmd->device->lun; /* Obtain free SQE */ diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 0ab595c0870a..1e7f4d138e06 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -4037,7 +4037,6 @@ qla1280_setup(char *s) { char *cp, *ptr; unsigned long val; - int toke; cp = s; @@ -4052,7 +4051,7 @@ qla1280_setup(char *s) } else val = simple_strtoul(ptr, &ptr, 0); - switch ((toke = qla1280_get_token(cp))) { + switch (qla1280_get_token(cp)) { case TOKEN_NVRAM: if (!val) driver_setup.no_nvram = 1; diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index e6b5c4ccce97..346d47b61c07 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -591,7 +591,6 @@ qla25xx_free_req_que(struct scsi_qla_host *vha, struct req_que *req) } kfree(req->outstanding_cmds); kfree(req); - req = NULL; } static void @@ -617,7 +616,6 @@ qla25xx_free_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) mutex_unlock(&ha->vport_lock); } kfree(rsp); - rsp = NULL; } int diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index a02235a6a8e9..cb97f625970d 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -48,13 +48,6 @@ MODULE_PARM_DESC(qlini_mode, "when ready " "\"enabled\" (default) - initiator mode will always stay enabled."); -static int ql_dm_tgt_ex_pct = 0; -module_param(ql_dm_tgt_ex_pct, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(ql_dm_tgt_ex_pct, - "For Dual Mode (qlini_mode=dual), this parameter determines " - "the percentage of exchanges/cmds FW will allocate resources " - "for Target mode."); - int ql2xuctrlirq = 1; module_param(ql2xuctrlirq, int, 0644); MODULE_PARM_DESC(ql2xuctrlirq, diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index e9db7da0c79c..6ffc9e4258a8 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -779,7 +779,7 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) action = ACTION_DELAYED_RETRY; break; case 0x0a: /* ALUA state transition */ - blk_stat = BLK_STS_AGAIN; + blk_stat = BLK_STS_TRANSPORT; fallthrough; default: action = ACTION_FAIL; diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 546a9e3cfbec..43949798a2e4 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -573,7 +573,6 @@ struct bus_type scsi_bus_type = { .pm = &scsi_bus_pm_ops, #endif }; -EXPORT_SYMBOL_GPL(scsi_bus_type); int scsi_sysfs_register(void) { diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 749316462075..895b56c8f25e 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3521,7 +3521,7 @@ static int sd_probe(struct device *dev) error = device_add_disk(dev, gd, NULL); if (error) { put_device(&sdkp->disk_dev); - blk_cleanup_disk(gd); + put_disk(gd); goto out; } @@ -3542,7 +3542,6 @@ static int sd_probe(struct device *dev) out_put: put_disk(gd); out_free: - sd_zbc_release_disk(sdkp); kfree(sdkp); out: scsi_autopm_put_device(sdp); @@ -3579,7 +3578,7 @@ static void scsi_disk_release(struct device *dev) struct scsi_disk *sdkp = to_scsi_disk(dev); ida_free(&sd_index_ida, sdkp->index); - sd_zbc_release_disk(sdkp); + sd_zbc_free_zone_info(sdkp); put_device(&sdkp->device->sdev_gendev); free_opal_dev(sdkp->opal_dev); diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 2abad54fd23f..5eea762f84d1 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -241,7 +241,7 @@ static inline int sd_is_zoned(struct scsi_disk *sdkp) #ifdef CONFIG_BLK_DEV_ZONED -void sd_zbc_release_disk(struct scsi_disk *sdkp); +void sd_zbc_free_zone_info(struct scsi_disk *sdkp); int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]); int sd_zbc_revalidate_zones(struct scsi_disk *sdkp); blk_status_t sd_zbc_setup_zone_mgmt_cmnd(struct scsi_cmnd *cmd, @@ -256,7 +256,7 @@ blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba, #else /* CONFIG_BLK_DEV_ZONED */ -static inline void sd_zbc_release_disk(struct scsi_disk *sdkp) {} +static inline void sd_zbc_free_zone_info(struct scsi_disk *sdkp) {} static inline int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]) { diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 5b9fad70aa88..6acc4f406eb8 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -786,8 +786,11 @@ static int sd_zbc_init_disk(struct scsi_disk *sdkp) return 0; } -static void sd_zbc_clear_zone_info(struct scsi_disk *sdkp) +void sd_zbc_free_zone_info(struct scsi_disk *sdkp) { + if (!sdkp->zone_wp_update_buf) + return; + /* Serialize against revalidate zones */ mutex_lock(&sdkp->rev_mutex); @@ -802,12 +805,6 @@ static void sd_zbc_clear_zone_info(struct scsi_disk *sdkp) mutex_unlock(&sdkp->rev_mutex); } -void sd_zbc_release_disk(struct scsi_disk *sdkp) -{ - if (sd_is_zoned(sdkp)) - sd_zbc_clear_zone_info(sdkp); -} - static void sd_zbc_revalidate_zones_cb(struct gendisk *disk) { struct scsi_disk *sdkp = scsi_disk(disk); @@ -914,12 +911,15 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]) u32 zone_blocks = 0; int ret; - if (!sd_is_zoned(sdkp)) + if (!sd_is_zoned(sdkp)) { /* - * Device managed or normal SCSI disk, - * no special handling required + * Device managed or normal SCSI disk, no special handling + * required. Nevertheless, free the disk zone information in + * case the device type changed. */ + sd_zbc_free_zone_info(sdkp); return 0; + } /* READ16/WRITE16 is mandatory for ZBC disks */ sdkp->device->use_16_for_rw = 1; @@ -928,11 +928,11 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]) if (!blk_queue_is_zoned(q)) { /* * This can happen for a host aware disk with partitions. - * The block device zone information was already cleared - * by blk_queue_set_zoned(). Only clear the scsi disk zone + * The block device zone model was already cleared by + * blk_queue_set_zoned(). Only free the scsi disk zone * information and exit early. */ - sd_zbc_clear_zone_info(sdkp); + sd_zbc_free_zone_info(sdkp); return 0; } diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index c4c48272d8ad..2e40320129c0 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1082,7 +1082,7 @@ struct pqi_stream_data { }; struct pqi_scsi_dev { - int devtype; /* as reported by INQUIRY commmand */ + int devtype; /* as reported by INQUIRY command */ u8 device_type; /* as reported by */ /* BMIC_IDENTIFY_PHYSICAL_DEVICE */ /* only valid for devtype = TYPE_DISK */ diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 08ed059a738b..ca3530982e52 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -479,7 +479,7 @@ static void storvsc_host_scan(struct work_struct *work) host = host_device->host; /* * Before scanning the host, first check to see if any of the - * currrently known devices have been hot removed. We issue a + * currently known devices have been hot removed. We issue a * "unit ready" command against all currently known devices. * This I/O will result in an error for devices that have been * removed. As part of handling the I/O error, we remove the device. diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h deleted file mode 100644 index 1bba3fead2ce..000000000000 --- a/drivers/scsi/ufs/ufs.h +++ /dev/null @@ -1,623 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Universal Flash Storage Host controller driver - * Copyright (C) 2011-2013 Samsung India Software Operations - * - * Authors: - * Santosh Yaraganavi <santosh.sy@samsung.com> - * Vinayak Holikatti <h.vinayak@samsung.com> - */ - -#ifndef _UFS_H -#define _UFS_H - -#include <linux/mutex.h> -#include <linux/types.h> -#include <uapi/scsi/scsi_bsg_ufs.h> - -#define GENERAL_UPIU_REQUEST_SIZE (sizeof(struct utp_upiu_req)) -#define QUERY_DESC_MAX_SIZE 255 -#define QUERY_DESC_MIN_SIZE 2 -#define QUERY_DESC_HDR_SIZE 2 -#define QUERY_OSF_SIZE (GENERAL_UPIU_REQUEST_SIZE - \ - (sizeof(struct utp_upiu_header))) -#define UFS_SENSE_SIZE 18 - -#define UPIU_HEADER_DWORD(byte3, byte2, byte1, byte0)\ - cpu_to_be32((byte3 << 24) | (byte2 << 16) |\ - (byte1 << 8) | (byte0)) -/* - * UFS device may have standard LUs and LUN id could be from 0x00 to - * 0x7F. Standard LUs use "Peripheral Device Addressing Format". - * UFS device may also have the Well Known LUs (also referred as W-LU) - * which again could be from 0x00 to 0x7F. For W-LUs, device only use - * the "Extended Addressing Format" which means the W-LUNs would be - * from 0xc100 (SCSI_W_LUN_BASE) onwards. - * This means max. LUN number reported from UFS device could be 0xC17F. - */ -#define UFS_UPIU_MAX_UNIT_NUM_ID 0x7F -#define UFS_MAX_LUNS (SCSI_W_LUN_BASE + UFS_UPIU_MAX_UNIT_NUM_ID) -#define UFS_UPIU_WLUN_ID (1 << 7) -#define UFS_RPMB_UNIT 0xC4 - -/* WriteBooster buffer is available only for the logical unit from 0 to 7 */ -#define UFS_UPIU_MAX_WB_LUN_ID 8 - -/* - * WriteBooster buffer lifetime has a limit setted by vendor. - * If it is over the limit, WriteBooster feature will be disabled. - */ -#define UFS_WB_EXCEED_LIFETIME 0x0B - -/* Well known logical unit id in LUN field of UPIU */ -enum { - UFS_UPIU_REPORT_LUNS_WLUN = 0x81, - UFS_UPIU_UFS_DEVICE_WLUN = 0xD0, - UFS_UPIU_BOOT_WLUN = 0xB0, - UFS_UPIU_RPMB_WLUN = 0xC4, -}; - -/* - * UFS Protocol Information Unit related definitions - */ - -/* Task management functions */ -enum { - UFS_ABORT_TASK = 0x01, - UFS_ABORT_TASK_SET = 0x02, - UFS_CLEAR_TASK_SET = 0x04, - UFS_LOGICAL_RESET = 0x08, - UFS_QUERY_TASK = 0x80, - UFS_QUERY_TASK_SET = 0x81, -}; - -/* UTP UPIU Transaction Codes Initiator to Target */ -enum { - UPIU_TRANSACTION_NOP_OUT = 0x00, - UPIU_TRANSACTION_COMMAND = 0x01, - UPIU_TRANSACTION_DATA_OUT = 0x02, - UPIU_TRANSACTION_TASK_REQ = 0x04, - UPIU_TRANSACTION_QUERY_REQ = 0x16, -}; - -/* UTP UPIU Transaction Codes Target to Initiator */ -enum { - UPIU_TRANSACTION_NOP_IN = 0x20, - UPIU_TRANSACTION_RESPONSE = 0x21, - UPIU_TRANSACTION_DATA_IN = 0x22, - UPIU_TRANSACTION_TASK_RSP = 0x24, - UPIU_TRANSACTION_READY_XFER = 0x31, - UPIU_TRANSACTION_QUERY_RSP = 0x36, - UPIU_TRANSACTION_REJECT_UPIU = 0x3F, -}; - -/* UPIU Read/Write flags */ -enum { - UPIU_CMD_FLAGS_NONE = 0x00, - UPIU_CMD_FLAGS_WRITE = 0x20, - UPIU_CMD_FLAGS_READ = 0x40, -}; - -/* UPIU Task Attributes */ -enum { - UPIU_TASK_ATTR_SIMPLE = 0x00, - UPIU_TASK_ATTR_ORDERED = 0x01, - UPIU_TASK_ATTR_HEADQ = 0x02, - UPIU_TASK_ATTR_ACA = 0x03, -}; - -/* UPIU Query request function */ -enum { - UPIU_QUERY_FUNC_STANDARD_READ_REQUEST = 0x01, - UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST = 0x81, -}; - -/* Flag idn for Query Requests*/ -enum flag_idn { - QUERY_FLAG_IDN_FDEVICEINIT = 0x01, - QUERY_FLAG_IDN_PERMANENT_WPE = 0x02, - QUERY_FLAG_IDN_PWR_ON_WPE = 0x03, - QUERY_FLAG_IDN_BKOPS_EN = 0x04, - QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE = 0x05, - QUERY_FLAG_IDN_PURGE_ENABLE = 0x06, - QUERY_FLAG_IDN_RESERVED2 = 0x07, - QUERY_FLAG_IDN_FPHYRESOURCEREMOVAL = 0x08, - QUERY_FLAG_IDN_BUSY_RTC = 0x09, - QUERY_FLAG_IDN_RESERVED3 = 0x0A, - QUERY_FLAG_IDN_PERMANENTLY_DISABLE_FW_UPDATE = 0x0B, - QUERY_FLAG_IDN_WB_EN = 0x0E, - QUERY_FLAG_IDN_WB_BUFF_FLUSH_EN = 0x0F, - QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8 = 0x10, - QUERY_FLAG_IDN_HPB_RESET = 0x11, - QUERY_FLAG_IDN_HPB_EN = 0x12, -}; - -/* Attribute idn for Query requests */ -enum attr_idn { - QUERY_ATTR_IDN_BOOT_LU_EN = 0x00, - QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD = 0x01, - QUERY_ATTR_IDN_POWER_MODE = 0x02, - QUERY_ATTR_IDN_ACTIVE_ICC_LVL = 0x03, - QUERY_ATTR_IDN_OOO_DATA_EN = 0x04, - QUERY_ATTR_IDN_BKOPS_STATUS = 0x05, - QUERY_ATTR_IDN_PURGE_STATUS = 0x06, - QUERY_ATTR_IDN_MAX_DATA_IN = 0x07, - QUERY_ATTR_IDN_MAX_DATA_OUT = 0x08, - QUERY_ATTR_IDN_DYN_CAP_NEEDED = 0x09, - QUERY_ATTR_IDN_REF_CLK_FREQ = 0x0A, - QUERY_ATTR_IDN_CONF_DESC_LOCK = 0x0B, - QUERY_ATTR_IDN_MAX_NUM_OF_RTT = 0x0C, - QUERY_ATTR_IDN_EE_CONTROL = 0x0D, - QUERY_ATTR_IDN_EE_STATUS = 0x0E, - QUERY_ATTR_IDN_SECONDS_PASSED = 0x0F, - QUERY_ATTR_IDN_CNTX_CONF = 0x10, - QUERY_ATTR_IDN_CORR_PRG_BLK_NUM = 0x11, - QUERY_ATTR_IDN_RESERVED2 = 0x12, - QUERY_ATTR_IDN_RESERVED3 = 0x13, - QUERY_ATTR_IDN_FFU_STATUS = 0x14, - QUERY_ATTR_IDN_PSA_STATE = 0x15, - QUERY_ATTR_IDN_PSA_DATA_SIZE = 0x16, - QUERY_ATTR_IDN_REF_CLK_GATING_WAIT_TIME = 0x17, - QUERY_ATTR_IDN_CASE_ROUGH_TEMP = 0x18, - QUERY_ATTR_IDN_HIGH_TEMP_BOUND = 0x19, - QUERY_ATTR_IDN_LOW_TEMP_BOUND = 0x1A, - QUERY_ATTR_IDN_WB_FLUSH_STATUS = 0x1C, - QUERY_ATTR_IDN_AVAIL_WB_BUFF_SIZE = 0x1D, - QUERY_ATTR_IDN_WB_BUFF_LIFE_TIME_EST = 0x1E, - QUERY_ATTR_IDN_CURR_WB_BUFF_SIZE = 0x1F, -}; - -/* Descriptor idn for Query requests */ -enum desc_idn { - QUERY_DESC_IDN_DEVICE = 0x0, - QUERY_DESC_IDN_CONFIGURATION = 0x1, - QUERY_DESC_IDN_UNIT = 0x2, - QUERY_DESC_IDN_RFU_0 = 0x3, - QUERY_DESC_IDN_INTERCONNECT = 0x4, - QUERY_DESC_IDN_STRING = 0x5, - QUERY_DESC_IDN_RFU_1 = 0x6, - QUERY_DESC_IDN_GEOMETRY = 0x7, - QUERY_DESC_IDN_POWER = 0x8, - QUERY_DESC_IDN_HEALTH = 0x9, - QUERY_DESC_IDN_MAX, -}; - -enum desc_header_offset { - QUERY_DESC_LENGTH_OFFSET = 0x00, - QUERY_DESC_DESC_TYPE_OFFSET = 0x01, -}; - -/* Unit descriptor parameters offsets in bytes*/ -enum unit_desc_param { - UNIT_DESC_PARAM_LEN = 0x0, - UNIT_DESC_PARAM_TYPE = 0x1, - UNIT_DESC_PARAM_UNIT_INDEX = 0x2, - UNIT_DESC_PARAM_LU_ENABLE = 0x3, - UNIT_DESC_PARAM_BOOT_LUN_ID = 0x4, - UNIT_DESC_PARAM_LU_WR_PROTECT = 0x5, - UNIT_DESC_PARAM_LU_Q_DEPTH = 0x6, - UNIT_DESC_PARAM_PSA_SENSITIVE = 0x7, - UNIT_DESC_PARAM_MEM_TYPE = 0x8, - UNIT_DESC_PARAM_DATA_RELIABILITY = 0x9, - UNIT_DESC_PARAM_LOGICAL_BLK_SIZE = 0xA, - UNIT_DESC_PARAM_LOGICAL_BLK_COUNT = 0xB, - UNIT_DESC_PARAM_ERASE_BLK_SIZE = 0x13, - UNIT_DESC_PARAM_PROVISIONING_TYPE = 0x17, - UNIT_DESC_PARAM_PHY_MEM_RSRC_CNT = 0x18, - UNIT_DESC_PARAM_CTX_CAPABILITIES = 0x20, - UNIT_DESC_PARAM_LARGE_UNIT_SIZE_M1 = 0x22, - UNIT_DESC_PARAM_HPB_LU_MAX_ACTIVE_RGNS = 0x23, - UNIT_DESC_PARAM_HPB_PIN_RGN_START_OFF = 0x25, - UNIT_DESC_PARAM_HPB_NUM_PIN_RGNS = 0x27, - UNIT_DESC_PARAM_WB_BUF_ALLOC_UNITS = 0x29, -}; - -/* Device descriptor parameters offsets in bytes*/ -enum device_desc_param { - DEVICE_DESC_PARAM_LEN = 0x0, - DEVICE_DESC_PARAM_TYPE = 0x1, - DEVICE_DESC_PARAM_DEVICE_TYPE = 0x2, - DEVICE_DESC_PARAM_DEVICE_CLASS = 0x3, - DEVICE_DESC_PARAM_DEVICE_SUB_CLASS = 0x4, - DEVICE_DESC_PARAM_PRTCL = 0x5, - DEVICE_DESC_PARAM_NUM_LU = 0x6, - DEVICE_DESC_PARAM_NUM_WLU = 0x7, - DEVICE_DESC_PARAM_BOOT_ENBL = 0x8, - DEVICE_DESC_PARAM_DESC_ACCSS_ENBL = 0x9, - DEVICE_DESC_PARAM_INIT_PWR_MODE = 0xA, - DEVICE_DESC_PARAM_HIGH_PR_LUN = 0xB, - DEVICE_DESC_PARAM_SEC_RMV_TYPE = 0xC, - DEVICE_DESC_PARAM_SEC_LU = 0xD, - DEVICE_DESC_PARAM_BKOP_TERM_LT = 0xE, - DEVICE_DESC_PARAM_ACTVE_ICC_LVL = 0xF, - DEVICE_DESC_PARAM_SPEC_VER = 0x10, - DEVICE_DESC_PARAM_MANF_DATE = 0x12, - DEVICE_DESC_PARAM_MANF_NAME = 0x14, - DEVICE_DESC_PARAM_PRDCT_NAME = 0x15, - DEVICE_DESC_PARAM_SN = 0x16, - DEVICE_DESC_PARAM_OEM_ID = 0x17, - DEVICE_DESC_PARAM_MANF_ID = 0x18, - DEVICE_DESC_PARAM_UD_OFFSET = 0x1A, - DEVICE_DESC_PARAM_UD_LEN = 0x1B, - DEVICE_DESC_PARAM_RTT_CAP = 0x1C, - DEVICE_DESC_PARAM_FRQ_RTC = 0x1D, - DEVICE_DESC_PARAM_UFS_FEAT = 0x1F, - DEVICE_DESC_PARAM_FFU_TMT = 0x20, - DEVICE_DESC_PARAM_Q_DPTH = 0x21, - DEVICE_DESC_PARAM_DEV_VER = 0x22, - DEVICE_DESC_PARAM_NUM_SEC_WPA = 0x24, - DEVICE_DESC_PARAM_PSA_MAX_DATA = 0x25, - DEVICE_DESC_PARAM_PSA_TMT = 0x29, - DEVICE_DESC_PARAM_PRDCT_REV = 0x2A, - DEVICE_DESC_PARAM_HPB_VER = 0x40, - DEVICE_DESC_PARAM_HPB_CONTROL = 0x42, - DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP = 0x4F, - DEVICE_DESC_PARAM_WB_PRESRV_USRSPC_EN = 0x53, - DEVICE_DESC_PARAM_WB_TYPE = 0x54, - DEVICE_DESC_PARAM_WB_SHARED_ALLOC_UNITS = 0x55, -}; - -/* Interconnect descriptor parameters offsets in bytes*/ -enum interconnect_desc_param { - INTERCONNECT_DESC_PARAM_LEN = 0x0, - INTERCONNECT_DESC_PARAM_TYPE = 0x1, - INTERCONNECT_DESC_PARAM_UNIPRO_VER = 0x2, - INTERCONNECT_DESC_PARAM_MPHY_VER = 0x4, -}; - -/* Geometry descriptor parameters offsets in bytes*/ -enum geometry_desc_param { - GEOMETRY_DESC_PARAM_LEN = 0x0, - GEOMETRY_DESC_PARAM_TYPE = 0x1, - GEOMETRY_DESC_PARAM_DEV_CAP = 0x4, - GEOMETRY_DESC_PARAM_MAX_NUM_LUN = 0xC, - GEOMETRY_DESC_PARAM_SEG_SIZE = 0xD, - GEOMETRY_DESC_PARAM_ALLOC_UNIT_SIZE = 0x11, - GEOMETRY_DESC_PARAM_MIN_BLK_SIZE = 0x12, - GEOMETRY_DESC_PARAM_OPT_RD_BLK_SIZE = 0x13, - GEOMETRY_DESC_PARAM_OPT_WR_BLK_SIZE = 0x14, - GEOMETRY_DESC_PARAM_MAX_IN_BUF_SIZE = 0x15, - GEOMETRY_DESC_PARAM_MAX_OUT_BUF_SIZE = 0x16, - GEOMETRY_DESC_PARAM_RPMB_RW_SIZE = 0x17, - GEOMETRY_DESC_PARAM_DYN_CAP_RSRC_PLC = 0x18, - GEOMETRY_DESC_PARAM_DATA_ORDER = 0x19, - GEOMETRY_DESC_PARAM_MAX_NUM_CTX = 0x1A, - GEOMETRY_DESC_PARAM_TAG_UNIT_SIZE = 0x1B, - GEOMETRY_DESC_PARAM_TAG_RSRC_SIZE = 0x1C, - GEOMETRY_DESC_PARAM_SEC_RM_TYPES = 0x1D, - GEOMETRY_DESC_PARAM_MEM_TYPES = 0x1E, - GEOMETRY_DESC_PARAM_SCM_MAX_NUM_UNITS = 0x20, - GEOMETRY_DESC_PARAM_SCM_CAP_ADJ_FCTR = 0x24, - GEOMETRY_DESC_PARAM_NPM_MAX_NUM_UNITS = 0x26, - GEOMETRY_DESC_PARAM_NPM_CAP_ADJ_FCTR = 0x2A, - GEOMETRY_DESC_PARAM_ENM1_MAX_NUM_UNITS = 0x2C, - GEOMETRY_DESC_PARAM_ENM1_CAP_ADJ_FCTR = 0x30, - GEOMETRY_DESC_PARAM_ENM2_MAX_NUM_UNITS = 0x32, - GEOMETRY_DESC_PARAM_ENM2_CAP_ADJ_FCTR = 0x36, - GEOMETRY_DESC_PARAM_ENM3_MAX_NUM_UNITS = 0x38, - GEOMETRY_DESC_PARAM_ENM3_CAP_ADJ_FCTR = 0x3C, - GEOMETRY_DESC_PARAM_ENM4_MAX_NUM_UNITS = 0x3E, - GEOMETRY_DESC_PARAM_ENM4_CAP_ADJ_FCTR = 0x42, - GEOMETRY_DESC_PARAM_OPT_LOG_BLK_SIZE = 0x44, - GEOMETRY_DESC_PARAM_HPB_REGION_SIZE = 0x48, - GEOMETRY_DESC_PARAM_HPB_NUMBER_LU = 0x49, - GEOMETRY_DESC_PARAM_HPB_SUBREGION_SIZE = 0x4A, - GEOMETRY_DESC_PARAM_HPB_MAX_ACTIVE_REGS = 0x4B, - GEOMETRY_DESC_PARAM_WB_MAX_ALLOC_UNITS = 0x4F, - GEOMETRY_DESC_PARAM_WB_MAX_WB_LUNS = 0x53, - GEOMETRY_DESC_PARAM_WB_BUFF_CAP_ADJ = 0x54, - GEOMETRY_DESC_PARAM_WB_SUP_RED_TYPE = 0x55, - GEOMETRY_DESC_PARAM_WB_SUP_WB_TYPE = 0x56, -}; - -/* Health descriptor parameters offsets in bytes*/ -enum health_desc_param { - HEALTH_DESC_PARAM_LEN = 0x0, - HEALTH_DESC_PARAM_TYPE = 0x1, - HEALTH_DESC_PARAM_EOL_INFO = 0x2, - HEALTH_DESC_PARAM_LIFE_TIME_EST_A = 0x3, - HEALTH_DESC_PARAM_LIFE_TIME_EST_B = 0x4, -}; - -/* WriteBooster buffer mode */ -enum { - WB_BUF_MODE_LU_DEDICATED = 0x0, - WB_BUF_MODE_SHARED = 0x1, -}; - -/* - * Logical Unit Write Protect - * 00h: LU not write protected - * 01h: LU write protected when fPowerOnWPEn =1 - * 02h: LU permanently write protected when fPermanentWPEn =1 - */ -enum ufs_lu_wp_type { - UFS_LU_NO_WP = 0x00, - UFS_LU_POWER_ON_WP = 0x01, - UFS_LU_PERM_WP = 0x02, -}; - -/* bActiveICCLevel parameter current units */ -enum { - UFSHCD_NANO_AMP = 0, - UFSHCD_MICRO_AMP = 1, - UFSHCD_MILI_AMP = 2, - UFSHCD_AMP = 3, -}; - -/* Possible values for dExtendedUFSFeaturesSupport */ -enum { - UFS_DEV_LOW_TEMP_NOTIF = BIT(4), - UFS_DEV_HIGH_TEMP_NOTIF = BIT(5), - UFS_DEV_EXT_TEMP_NOTIF = BIT(6), - UFS_DEV_HPB_SUPPORT = BIT(7), - UFS_DEV_WRITE_BOOSTER_SUP = BIT(8), -}; -#define UFS_DEV_HPB_SUPPORT_VERSION 0x310 - -#define POWER_DESC_MAX_ACTV_ICC_LVLS 16 - -/* Attribute bActiveICCLevel parameter bit masks definitions */ -#define ATTR_ICC_LVL_UNIT_OFFSET 14 -#define ATTR_ICC_LVL_UNIT_MASK (0x3 << ATTR_ICC_LVL_UNIT_OFFSET) -#define ATTR_ICC_LVL_VALUE_MASK 0x3FF - -/* Power descriptor parameters offsets in bytes */ -enum power_desc_param_offset { - PWR_DESC_LEN = 0x0, - PWR_DESC_TYPE = 0x1, - PWR_DESC_ACTIVE_LVLS_VCC_0 = 0x2, - PWR_DESC_ACTIVE_LVLS_VCCQ_0 = 0x22, - PWR_DESC_ACTIVE_LVLS_VCCQ2_0 = 0x42, -}; - -/* Exception event mask values */ -enum { - MASK_EE_STATUS = 0xFFFF, - MASK_EE_DYNCAP_EVENT = BIT(0), - MASK_EE_SYSPOOL_EVENT = BIT(1), - MASK_EE_URGENT_BKOPS = BIT(2), - MASK_EE_TOO_HIGH_TEMP = BIT(3), - MASK_EE_TOO_LOW_TEMP = BIT(4), - MASK_EE_WRITEBOOSTER_EVENT = BIT(5), - MASK_EE_PERFORMANCE_THROTTLING = BIT(6), -}; -#define MASK_EE_URGENT_TEMP (MASK_EE_TOO_HIGH_TEMP | MASK_EE_TOO_LOW_TEMP) - -/* Background operation status */ -enum bkops_status { - BKOPS_STATUS_NO_OP = 0x0, - BKOPS_STATUS_NON_CRITICAL = 0x1, - BKOPS_STATUS_PERF_IMPACT = 0x2, - BKOPS_STATUS_CRITICAL = 0x3, - BKOPS_STATUS_MAX = BKOPS_STATUS_CRITICAL, -}; - -/* UTP QUERY Transaction Specific Fields OpCode */ -enum query_opcode { - UPIU_QUERY_OPCODE_NOP = 0x0, - UPIU_QUERY_OPCODE_READ_DESC = 0x1, - UPIU_QUERY_OPCODE_WRITE_DESC = 0x2, - UPIU_QUERY_OPCODE_READ_ATTR = 0x3, - UPIU_QUERY_OPCODE_WRITE_ATTR = 0x4, - UPIU_QUERY_OPCODE_READ_FLAG = 0x5, - UPIU_QUERY_OPCODE_SET_FLAG = 0x6, - UPIU_QUERY_OPCODE_CLEAR_FLAG = 0x7, - UPIU_QUERY_OPCODE_TOGGLE_FLAG = 0x8, -}; - -/* bRefClkFreq attribute values */ -enum ufs_ref_clk_freq { - REF_CLK_FREQ_19_2_MHZ = 0, - REF_CLK_FREQ_26_MHZ = 1, - REF_CLK_FREQ_38_4_MHZ = 2, - REF_CLK_FREQ_52_MHZ = 3, - REF_CLK_FREQ_INVAL = -1, -}; - -/* Query response result code */ -enum { - QUERY_RESULT_SUCCESS = 0x00, - QUERY_RESULT_NOT_READABLE = 0xF6, - QUERY_RESULT_NOT_WRITEABLE = 0xF7, - QUERY_RESULT_ALREADY_WRITTEN = 0xF8, - QUERY_RESULT_INVALID_LENGTH = 0xF9, - QUERY_RESULT_INVALID_VALUE = 0xFA, - QUERY_RESULT_INVALID_SELECTOR = 0xFB, - QUERY_RESULT_INVALID_INDEX = 0xFC, - QUERY_RESULT_INVALID_IDN = 0xFD, - QUERY_RESULT_INVALID_OPCODE = 0xFE, - QUERY_RESULT_GENERAL_FAILURE = 0xFF, -}; - -/* UTP Transfer Request Command Type (CT) */ -enum { - UPIU_COMMAND_SET_TYPE_SCSI = 0x0, - UPIU_COMMAND_SET_TYPE_UFS = 0x1, - UPIU_COMMAND_SET_TYPE_QUERY = 0x2, -}; - -/* UTP Transfer Request Command Offset */ -#define UPIU_COMMAND_TYPE_OFFSET 28 - -/* Offset of the response code in the UPIU header */ -#define UPIU_RSP_CODE_OFFSET 8 - -enum { - MASK_SCSI_STATUS = 0xFF, - MASK_TASK_RESPONSE = 0xFF00, - MASK_RSP_UPIU_RESULT = 0xFFFF, - MASK_QUERY_DATA_SEG_LEN = 0xFFFF, - MASK_RSP_UPIU_DATA_SEG_LEN = 0xFFFF, - MASK_RSP_EXCEPTION_EVENT = 0x10000, - MASK_TM_SERVICE_RESP = 0xFF, - MASK_TM_FUNC = 0xFF, -}; - -/* Task management service response */ -enum { - UPIU_TASK_MANAGEMENT_FUNC_COMPL = 0x00, - UPIU_TASK_MANAGEMENT_FUNC_NOT_SUPPORTED = 0x04, - UPIU_TASK_MANAGEMENT_FUNC_SUCCEEDED = 0x08, - UPIU_TASK_MANAGEMENT_FUNC_FAILED = 0x05, - UPIU_INCORRECT_LOGICAL_UNIT_NO = 0x09, -}; - -/* UFS device power modes */ -enum ufs_dev_pwr_mode { - UFS_ACTIVE_PWR_MODE = 1, - UFS_SLEEP_PWR_MODE = 2, - UFS_POWERDOWN_PWR_MODE = 3, - UFS_DEEPSLEEP_PWR_MODE = 4, -}; - -#define UFS_WB_BUF_REMAIN_PERCENT(val) ((val) / 10) - -/** - * struct utp_cmd_rsp - Response UPIU structure - * @residual_transfer_count: Residual transfer count DW-3 - * @reserved: Reserved double words DW-4 to DW-7 - * @sense_data_len: Sense data length DW-8 U16 - * @sense_data: Sense data field DW-8 to DW-12 - */ -struct utp_cmd_rsp { - __be32 residual_transfer_count; - __be32 reserved[4]; - __be16 sense_data_len; - u8 sense_data[UFS_SENSE_SIZE]; -}; - -struct ufshpb_active_field { - __be16 active_rgn; - __be16 active_srgn; -}; -#define HPB_ACT_FIELD_SIZE 4 - -/** - * struct utp_hpb_rsp - Response UPIU structure - * @residual_transfer_count: Residual transfer count DW-3 - * @reserved1: Reserved double words DW-4 to DW-7 - * @sense_data_len: Sense data length DW-8 U16 - * @desc_type: Descriptor type of sense data - * @additional_len: Additional length of sense data - * @hpb_op: HPB operation type - * @lun: LUN of response UPIU - * @active_rgn_cnt: Active region count - * @inactive_rgn_cnt: Inactive region count - * @hpb_active_field: Recommended to read HPB region and subregion - * @hpb_inactive_field: To be inactivated HPB region and subregion - */ -struct utp_hpb_rsp { - __be32 residual_transfer_count; - __be32 reserved1[4]; - __be16 sense_data_len; - u8 desc_type; - u8 additional_len; - u8 hpb_op; - u8 lun; - u8 active_rgn_cnt; - u8 inactive_rgn_cnt; - struct ufshpb_active_field hpb_active_field[2]; - __be16 hpb_inactive_field[2]; -}; -#define UTP_HPB_RSP_SIZE 40 - -/** - * struct utp_upiu_rsp - general upiu response structure - * @header: UPIU header structure DW-0 to DW-2 - * @sr: fields structure for scsi command DW-3 to DW-12 - * @qr: fields structure for query request DW-3 to DW-7 - */ -struct utp_upiu_rsp { - struct utp_upiu_header header; - union { - struct utp_cmd_rsp sr; - struct utp_hpb_rsp hr; - struct utp_upiu_query qr; - }; -}; - -/** - * struct ufs_query_req - parameters for building a query request - * @query_func: UPIU header query function - * @upiu_req: the query request data - */ -struct ufs_query_req { - u8 query_func; - struct utp_upiu_query upiu_req; -}; - -/** - * struct ufs_query_resp - UPIU QUERY - * @response: device response code - * @upiu_res: query response data - */ -struct ufs_query_res { - u8 response; - struct utp_upiu_query upiu_res; -}; - -/* - * VCCQ & VCCQ2 current requirement when UFS device is in sleep state - * and link is in Hibern8 state. - */ -#define UFS_VREG_LPM_LOAD_UA 1000 /* uA */ - -struct ufs_vreg { - struct regulator *reg; - const char *name; - bool always_on; - bool enabled; - int max_uA; -}; - -struct ufs_vreg_info { - struct ufs_vreg *vcc; - struct ufs_vreg *vccq; - struct ufs_vreg *vccq2; - struct ufs_vreg *vdd_hba; -}; - -struct ufs_dev_info { - bool f_power_on_wp_en; - /* Keeps information if any of the LU is power on write protected */ - bool is_lu_power_on_wp; - /* Maximum number of general LU supported by the UFS device */ - u8 max_lu_supported; - u16 wmanufacturerid; - /*UFS device Product Name */ - u8 *model; - u16 wspecversion; - u32 clk_gating_wait_us; - - /* UFS HPB related flag */ - bool hpb_enabled; - - /* UFS WB related flags */ - bool wb_enabled; - bool wb_buf_flush_enabled; - u8 wb_dedicated_lu; - u8 wb_buffer_type; - - bool b_rpm_dev_flush_capable; - u8 b_presrv_uspc_en; -}; - -/* - * This enum is used in string mapping in include/trace/events/ufs.h. - */ -enum ufs_trace_str_t { - UFS_CMD_SEND, UFS_CMD_COMP, UFS_DEV_COMP, - UFS_QUERY_SEND, UFS_QUERY_COMP, UFS_QUERY_ERR, - UFS_TM_SEND, UFS_TM_COMP, UFS_TM_ERR -}; - -/* - * Transaction Specific Fields (TSF) type in the UPIU package, this enum is - * used in include/trace/events/ufs.h for UFS command trace. - */ -enum ufs_trace_tsf_t { - UFS_TSF_CDB, UFS_TSF_OSF, UFS_TSF_TM_INPUT, UFS_TSF_TM_OUTPUT -}; - -#endif /* End of Header */ diff --git a/drivers/scsi/ufs/ufs_quirks.h b/drivers/scsi/ufs/ufs_quirks.h deleted file mode 100644 index bcb4f004bed5..000000000000 --- a/drivers/scsi/ufs/ufs_quirks.h +++ /dev/null @@ -1,116 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. - */ - -#ifndef _UFS_QUIRKS_H_ -#define _UFS_QUIRKS_H_ - -/* return true if s1 is a prefix of s2 */ -#define STR_PRFX_EQUAL(s1, s2) !strncmp(s1, s2, strlen(s1)) - -#define UFS_ANY_VENDOR 0xFFFF -#define UFS_ANY_MODEL "ANY_MODEL" - -#define UFS_VENDOR_MICRON 0x12C -#define UFS_VENDOR_SAMSUNG 0x1CE -#define UFS_VENDOR_SKHYNIX 0x1AD -#define UFS_VENDOR_TOSHIBA 0x198 -#define UFS_VENDOR_WDC 0x145 - -/** - * ufs_dev_quirk - ufs device quirk info - * @card: ufs card details - * @quirk: device quirk - */ -struct ufs_dev_quirk { - u16 wmanufacturerid; - const u8 *model; - unsigned int quirk; -}; - -/* - * Some vendor's UFS device sends back to back NACs for the DL data frames - * causing the host controller to raise the DFES error status. Sometimes - * such UFS devices send back to back NAC without waiting for new - * retransmitted DL frame from the host and in such cases it might be possible - * the Host UniPro goes into bad state without raising the DFES error - * interrupt. If this happens then all the pending commands would timeout - * only after respective SW command (which is generally too large). - * - * We can workaround such device behaviour like this: - * - As soon as SW sees the DL NAC error, it should schedule the error handler - * - Error handler would sleep for 50ms to see if there are any fatal errors - * raised by UFS controller. - * - If there are fatal errors then SW does normal error recovery. - * - If there are no fatal errors then SW sends the NOP command to device - * to check if link is alive. - * - If NOP command times out, SW does normal error recovery - * - If NOP command succeed, skip the error handling. - * - * If DL NAC error is seen multiple times with some vendor's UFS devices then - * enable this quirk to initiate quick error recovery and also silence related - * error logs to reduce spamming of kernel logs. - */ -#define UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS (1 << 2) - -/* - * Few Toshiba UFS device models advertise RX_MIN_ACTIVATETIME_CAPABILITY as - * 600us which may not be enough for reliable hibern8 exit hardware sequence - * from UFS device. - * To workaround this issue, host should set its PA_TACTIVATE time to 1ms even - * if device advertises RX_MIN_ACTIVATETIME_CAPABILITY less than 1ms. - */ -#define UFS_DEVICE_QUIRK_PA_TACTIVATE (1 << 4) - -/* - * It seems some UFS devices may keep drawing more than sleep current - * (atleast for 500us) from UFS rails (especially from VCCQ rail). - * To avoid this situation, add 2ms delay before putting these UFS - * rails in LPM mode. - */ -#define UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM (1 << 6) - -/* - * Some UFS devices require host PA_TACTIVATE to be lower than device - * PA_TACTIVATE, enabling this quirk ensure this. - */ -#define UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE (1 << 7) - -/* - * The max. value PA_SaveConfigTime is 250 (10us) but this is not enough for - * some vendors. - * Gear switch from PWM to HS may fail even with this max. PA_SaveConfigTime. - * Gear switch can be issued by host controller as an error recovery and any - * software delay will not help on this case so we need to increase - * PA_SaveConfigTime to >32us as per vendor recommendation. - */ -#define UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME (1 << 8) - -/* - * Some UFS devices require VS_DebugSaveConfigTime is 0x10, - * enabling this quirk ensure this. - */ -#define UFS_DEVICE_QUIRK_HOST_VS_DEBUGSAVECONFIGTIME (1 << 9) - -/* - * Some pre-3.1 UFS devices can support extended features by upgrading - * the firmware. Enable this quirk to make UFS core driver probe and enable - * supported features on such devices. - */ -#define UFS_DEVICE_QUIRK_SUPPORT_EXTENDED_FEATURES (1 << 10) - -/* - * Some UFS devices require delay after VCC power rail is turned-off. - * Enable this quirk to introduce 5ms delays after VCC power-off during - * suspend flow. - */ -#define UFS_DEVICE_QUIRK_DELAY_AFTER_LPM (1 << 11) - -/* - * Some UFS devices require L2P entry should be swapped before being sent to the - * UFS device for HPB READ command. - */ -#define UFS_DEVICE_QUIRK_SWAP_L2P_ENTRY_FOR_HPB_READ (1 << 12) - -#endif /* UFS_QUIRKS_H_ */ diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h deleted file mode 100644 index 2b0f3441b813..000000000000 --- a/drivers/scsi/ufs/ufshcd.h +++ /dev/null @@ -1,1230 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Universal Flash Storage Host controller driver - * Copyright (C) 2011-2013 Samsung India Software Operations - * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. - * - * Authors: - * Santosh Yaraganavi <santosh.sy@samsung.com> - * Vinayak Holikatti <h.vinayak@samsung.com> - */ - -#ifndef _UFSHCD_H -#define _UFSHCD_H - -#include <linux/bitfield.h> -#include <linux/blk-crypto-profile.h> -#include <linux/blk-mq.h> -#include <linux/devfreq.h> -#include <linux/pm_runtime.h> -#include <scsi/scsi_device.h> -#include "unipro.h" -#include "ufs.h" -#include "ufs_quirks.h" -#include "ufshci.h" - -#define UFSHCD "ufshcd" - -struct ufs_hba; - -enum dev_cmd_type { - DEV_CMD_TYPE_NOP = 0x0, - DEV_CMD_TYPE_QUERY = 0x1, -}; - -enum ufs_event_type { - /* uic specific errors */ - UFS_EVT_PA_ERR = 0, - UFS_EVT_DL_ERR, - UFS_EVT_NL_ERR, - UFS_EVT_TL_ERR, - UFS_EVT_DME_ERR, - - /* fatal errors */ - UFS_EVT_AUTO_HIBERN8_ERR, - UFS_EVT_FATAL_ERR, - UFS_EVT_LINK_STARTUP_FAIL, - UFS_EVT_RESUME_ERR, - UFS_EVT_SUSPEND_ERR, - UFS_EVT_WL_SUSP_ERR, - UFS_EVT_WL_RES_ERR, - - /* abnormal events */ - UFS_EVT_DEV_RESET, - UFS_EVT_HOST_RESET, - UFS_EVT_ABORT, - - UFS_EVT_CNT, -}; - -/** - * struct uic_command - UIC command structure - * @command: UIC command - * @argument1: UIC command argument 1 - * @argument2: UIC command argument 2 - * @argument3: UIC command argument 3 - * @cmd_active: Indicate if UIC command is outstanding - * @done: UIC command completion - */ -struct uic_command { - u32 command; - u32 argument1; - u32 argument2; - u32 argument3; - int cmd_active; - struct completion done; -}; - -/* Used to differentiate the power management options */ -enum ufs_pm_op { - UFS_RUNTIME_PM, - UFS_SYSTEM_PM, - UFS_SHUTDOWN_PM, -}; - -/* Host <-> Device UniPro Link state */ -enum uic_link_state { - UIC_LINK_OFF_STATE = 0, /* Link powered down or disabled */ - UIC_LINK_ACTIVE_STATE = 1, /* Link is in Fast/Slow/Sleep state */ - UIC_LINK_HIBERN8_STATE = 2, /* Link is in Hibernate state */ - UIC_LINK_BROKEN_STATE = 3, /* Link is in broken state */ -}; - -#define ufshcd_is_link_off(hba) ((hba)->uic_link_state == UIC_LINK_OFF_STATE) -#define ufshcd_is_link_active(hba) ((hba)->uic_link_state == \ - UIC_LINK_ACTIVE_STATE) -#define ufshcd_is_link_hibern8(hba) ((hba)->uic_link_state == \ - UIC_LINK_HIBERN8_STATE) -#define ufshcd_is_link_broken(hba) ((hba)->uic_link_state == \ - UIC_LINK_BROKEN_STATE) -#define ufshcd_set_link_off(hba) ((hba)->uic_link_state = UIC_LINK_OFF_STATE) -#define ufshcd_set_link_active(hba) ((hba)->uic_link_state = \ - UIC_LINK_ACTIVE_STATE) -#define ufshcd_set_link_hibern8(hba) ((hba)->uic_link_state = \ - UIC_LINK_HIBERN8_STATE) -#define ufshcd_set_link_broken(hba) ((hba)->uic_link_state = \ - UIC_LINK_BROKEN_STATE) - -#define ufshcd_set_ufs_dev_active(h) \ - ((h)->curr_dev_pwr_mode = UFS_ACTIVE_PWR_MODE) -#define ufshcd_set_ufs_dev_sleep(h) \ - ((h)->curr_dev_pwr_mode = UFS_SLEEP_PWR_MODE) -#define ufshcd_set_ufs_dev_poweroff(h) \ - ((h)->curr_dev_pwr_mode = UFS_POWERDOWN_PWR_MODE) -#define ufshcd_set_ufs_dev_deepsleep(h) \ - ((h)->curr_dev_pwr_mode = UFS_DEEPSLEEP_PWR_MODE) -#define ufshcd_is_ufs_dev_active(h) \ - ((h)->curr_dev_pwr_mode == UFS_ACTIVE_PWR_MODE) -#define ufshcd_is_ufs_dev_sleep(h) \ - ((h)->curr_dev_pwr_mode == UFS_SLEEP_PWR_MODE) -#define ufshcd_is_ufs_dev_poweroff(h) \ - ((h)->curr_dev_pwr_mode == UFS_POWERDOWN_PWR_MODE) -#define ufshcd_is_ufs_dev_deepsleep(h) \ - ((h)->curr_dev_pwr_mode == UFS_DEEPSLEEP_PWR_MODE) - -/* - * UFS Power management levels. - * Each level is in increasing order of power savings, except DeepSleep - * which is lower than PowerDown with power on but not PowerDown with - * power off. - */ -enum ufs_pm_level { - UFS_PM_LVL_0, - UFS_PM_LVL_1, - UFS_PM_LVL_2, - UFS_PM_LVL_3, - UFS_PM_LVL_4, - UFS_PM_LVL_5, - UFS_PM_LVL_6, - UFS_PM_LVL_MAX -}; - -struct ufs_pm_lvl_states { - enum ufs_dev_pwr_mode dev_state; - enum uic_link_state link_state; -}; - -/** - * struct ufshcd_lrb - local reference block - * @utr_descriptor_ptr: UTRD address of the command - * @ucd_req_ptr: UCD address of the command - * @ucd_rsp_ptr: Response UPIU address for this command - * @ucd_prdt_ptr: PRDT address of the command - * @utrd_dma_addr: UTRD dma address for debug - * @ucd_prdt_dma_addr: PRDT dma address for debug - * @ucd_rsp_dma_addr: UPIU response dma address for debug - * @ucd_req_dma_addr: UPIU request dma address for debug - * @cmd: pointer to SCSI command - * @scsi_status: SCSI status of the command - * @command_type: SCSI, UFS, Query. - * @task_tag: Task tag of the command - * @lun: LUN of the command - * @intr_cmd: Interrupt command (doesn't participate in interrupt aggregation) - * @issue_time_stamp: time stamp for debug purposes - * @compl_time_stamp: time stamp for statistics - * @crypto_key_slot: the key slot to use for inline crypto (-1 if none) - * @data_unit_num: the data unit number for the first block for inline crypto - * @req_abort_skip: skip request abort task flag - */ -struct ufshcd_lrb { - struct utp_transfer_req_desc *utr_descriptor_ptr; - struct utp_upiu_req *ucd_req_ptr; - struct utp_upiu_rsp *ucd_rsp_ptr; - struct ufshcd_sg_entry *ucd_prdt_ptr; - - dma_addr_t utrd_dma_addr; - dma_addr_t ucd_req_dma_addr; - dma_addr_t ucd_rsp_dma_addr; - dma_addr_t ucd_prdt_dma_addr; - - struct scsi_cmnd *cmd; - int scsi_status; - - int command_type; - int task_tag; - u8 lun; /* UPIU LUN id field is only 8-bit wide */ - bool intr_cmd; - ktime_t issue_time_stamp; - ktime_t compl_time_stamp; -#ifdef CONFIG_SCSI_UFS_CRYPTO - int crypto_key_slot; - u64 data_unit_num; -#endif - - bool req_abort_skip; -}; - -/** - * struct ufs_query - holds relevant data structures for query request - * @request: request upiu and function - * @descriptor: buffer for sending/receiving descriptor - * @response: response upiu and response - */ -struct ufs_query { - struct ufs_query_req request; - u8 *descriptor; - struct ufs_query_res response; -}; - -/** - * struct ufs_dev_cmd - all assosiated fields with device management commands - * @type: device management command type - Query, NOP OUT - * @lock: lock to allow one command at a time - * @complete: internal commands completion - * @query: Device management query information - */ -struct ufs_dev_cmd { - enum dev_cmd_type type; - struct mutex lock; - struct completion *complete; - struct ufs_query query; -}; - -/** - * struct ufs_clk_info - UFS clock related info - * @list: list headed by hba->clk_list_head - * @clk: clock node - * @name: clock name - * @max_freq: maximum frequency supported by the clock - * @min_freq: min frequency that can be used for clock scaling - * @curr_freq: indicates the current frequency that it is set to - * @keep_link_active: indicates that the clk should not be disabled if - * link is active - * @enabled: variable to check against multiple enable/disable - */ -struct ufs_clk_info { - struct list_head list; - struct clk *clk; - const char *name; - u32 max_freq; - u32 min_freq; - u32 curr_freq; - bool keep_link_active; - bool enabled; -}; - -enum ufs_notify_change_status { - PRE_CHANGE, - POST_CHANGE, -}; - -struct ufs_pa_layer_attr { - u32 gear_rx; - u32 gear_tx; - u32 lane_rx; - u32 lane_tx; - u32 pwr_rx; - u32 pwr_tx; - u32 hs_rate; -}; - -struct ufs_pwr_mode_info { - bool is_valid; - struct ufs_pa_layer_attr info; -}; - -/** - * struct ufs_hba_variant_ops - variant specific callbacks - * @name: variant name - * @init: called when the driver is initialized - * @exit: called to cleanup everything done in init - * @get_ufs_hci_version: called to get UFS HCI version - * @clk_scale_notify: notifies that clks are scaled up/down - * @setup_clocks: called before touching any of the controller registers - * @hce_enable_notify: called before and after HCE enable bit is set to allow - * variant specific Uni-Pro initialization. - * @link_startup_notify: called before and after Link startup is carried out - * to allow variant specific Uni-Pro initialization. - * @pwr_change_notify: called before and after a power mode change - * is carried out to allow vendor spesific capabilities - * to be set. - * @setup_xfer_req: called before any transfer request is issued - * to set some things - * @setup_task_mgmt: called before any task management request is issued - * to set some things - * @hibern8_notify: called around hibern8 enter/exit - * @apply_dev_quirks: called to apply device specific quirks - * @fixup_dev_quirks: called to modify device specific quirks - * @suspend: called during host controller PM callback - * @resume: called during host controller PM callback - * @dbg_register_dump: used to dump controller debug information - * @phy_initialization: used to initialize phys - * @device_reset: called to issue a reset pulse on the UFS device - * @config_scaling_param: called to configure clock scaling parameters - * @program_key: program or evict an inline encryption key - * @event_notify: called to notify important events - */ -struct ufs_hba_variant_ops { - const char *name; - int (*init)(struct ufs_hba *); - void (*exit)(struct ufs_hba *); - u32 (*get_ufs_hci_version)(struct ufs_hba *); - int (*clk_scale_notify)(struct ufs_hba *, bool, - enum ufs_notify_change_status); - int (*setup_clocks)(struct ufs_hba *, bool, - enum ufs_notify_change_status); - int (*hce_enable_notify)(struct ufs_hba *, - enum ufs_notify_change_status); - int (*link_startup_notify)(struct ufs_hba *, - enum ufs_notify_change_status); - int (*pwr_change_notify)(struct ufs_hba *, - enum ufs_notify_change_status status, - struct ufs_pa_layer_attr *, - struct ufs_pa_layer_attr *); - void (*setup_xfer_req)(struct ufs_hba *hba, int tag, - bool is_scsi_cmd); - void (*setup_task_mgmt)(struct ufs_hba *, int, u8); - void (*hibern8_notify)(struct ufs_hba *, enum uic_cmd_dme, - enum ufs_notify_change_status); - int (*apply_dev_quirks)(struct ufs_hba *hba); - void (*fixup_dev_quirks)(struct ufs_hba *hba); - int (*suspend)(struct ufs_hba *, enum ufs_pm_op, - enum ufs_notify_change_status); - int (*resume)(struct ufs_hba *, enum ufs_pm_op); - void (*dbg_register_dump)(struct ufs_hba *hba); - int (*phy_initialization)(struct ufs_hba *); - int (*device_reset)(struct ufs_hba *hba); - void (*config_scaling_param)(struct ufs_hba *hba, - struct devfreq_dev_profile *profile, - struct devfreq_simple_ondemand_data *data); - int (*program_key)(struct ufs_hba *hba, - const union ufs_crypto_cfg_entry *cfg, int slot); - void (*event_notify)(struct ufs_hba *hba, - enum ufs_event_type evt, void *data); -}; - -/* clock gating state */ -enum clk_gating_state { - CLKS_OFF, - CLKS_ON, - REQ_CLKS_OFF, - REQ_CLKS_ON, -}; - -/** - * struct ufs_clk_gating - UFS clock gating related info - * @gate_work: worker to turn off clocks after some delay as specified in - * delay_ms - * @ungate_work: worker to turn on clocks that will be used in case of - * interrupt context - * @state: the current clocks state - * @delay_ms: gating delay in ms - * @is_suspended: clk gating is suspended when set to 1 which can be used - * during suspend/resume - * @delay_attr: sysfs attribute to control delay_attr - * @enable_attr: sysfs attribute to enable/disable clock gating - * @is_enabled: Indicates the current status of clock gating - * @is_initialized: Indicates whether clock gating is initialized or not - * @active_reqs: number of requests that are pending and should be waited for - * completion before gating clocks. - * @clk_gating_workq: workqueue for clock gating work. - */ -struct ufs_clk_gating { - struct delayed_work gate_work; - struct work_struct ungate_work; - enum clk_gating_state state; - unsigned long delay_ms; - bool is_suspended; - struct device_attribute delay_attr; - struct device_attribute enable_attr; - bool is_enabled; - bool is_initialized; - int active_reqs; - struct workqueue_struct *clk_gating_workq; -}; - -struct ufs_saved_pwr_info { - struct ufs_pa_layer_attr info; - bool is_valid; -}; - -/** - * struct ufs_clk_scaling - UFS clock scaling related data - * @active_reqs: number of requests that are pending. If this is zero when - * devfreq ->target() function is called then schedule "suspend_work" to - * suspend devfreq. - * @tot_busy_t: Total busy time in current polling window - * @window_start_t: Start time (in jiffies) of the current polling window - * @busy_start_t: Start time of current busy period - * @enable_attr: sysfs attribute to enable/disable clock scaling - * @saved_pwr_info: UFS power mode may also be changed during scaling and this - * one keeps track of previous power mode. - * @workq: workqueue to schedule devfreq suspend/resume work - * @suspend_work: worker to suspend devfreq - * @resume_work: worker to resume devfreq - * @min_gear: lowest HS gear to scale down to - * @is_enabled: tracks if scaling is currently enabled or not, controlled by - * clkscale_enable sysfs node - * @is_allowed: tracks if scaling is currently allowed or not, used to block - * clock scaling which is not invoked from devfreq governor - * @is_initialized: Indicates whether clock scaling is initialized or not - * @is_busy_started: tracks if busy period has started or not - * @is_suspended: tracks if devfreq is suspended or not - */ -struct ufs_clk_scaling { - int active_reqs; - unsigned long tot_busy_t; - ktime_t window_start_t; - ktime_t busy_start_t; - struct device_attribute enable_attr; - struct ufs_saved_pwr_info saved_pwr_info; - struct workqueue_struct *workq; - struct work_struct suspend_work; - struct work_struct resume_work; - u32 min_gear; - bool is_enabled; - bool is_allowed; - bool is_initialized; - bool is_busy_started; - bool is_suspended; -}; - -#define UFS_EVENT_HIST_LENGTH 8 -/** - * struct ufs_event_hist - keeps history of errors - * @pos: index to indicate cyclic buffer position - * @val: cyclic buffer for registers value - * @tstamp: cyclic buffer for time stamp - * @cnt: error counter - */ -struct ufs_event_hist { - int pos; - u32 val[UFS_EVENT_HIST_LENGTH]; - ktime_t tstamp[UFS_EVENT_HIST_LENGTH]; - unsigned long long cnt; -}; - -/** - * struct ufs_stats - keeps usage/err statistics - * @last_intr_status: record the last interrupt status. - * @last_intr_ts: record the last interrupt timestamp. - * @hibern8_exit_cnt: Counter to keep track of number of exits, - * reset this after link-startup. - * @last_hibern8_exit_tstamp: Set time after the hibern8 exit. - * Clear after the first successful command completion. - * @event: array with event history. - */ -struct ufs_stats { - u32 last_intr_status; - ktime_t last_intr_ts; - - u32 hibern8_exit_cnt; - ktime_t last_hibern8_exit_tstamp; - struct ufs_event_hist event[UFS_EVT_CNT]; -}; - -/** - * enum ufshcd_state - UFS host controller state - * @UFSHCD_STATE_RESET: Link is not operational. Postpone SCSI command - * processing. - * @UFSHCD_STATE_OPERATIONAL: The host controller is operational and can process - * SCSI commands. - * @UFSHCD_STATE_EH_SCHEDULED_NON_FATAL: The error handler has been scheduled. - * SCSI commands may be submitted to the controller. - * @UFSHCD_STATE_EH_SCHEDULED_FATAL: The error handler has been scheduled. Fail - * newly submitted SCSI commands with error code DID_BAD_TARGET. - * @UFSHCD_STATE_ERROR: An unrecoverable error occurred, e.g. link recovery - * failed. Fail all SCSI commands with error code DID_ERROR. - */ -enum ufshcd_state { - UFSHCD_STATE_RESET, - UFSHCD_STATE_OPERATIONAL, - UFSHCD_STATE_EH_SCHEDULED_NON_FATAL, - UFSHCD_STATE_EH_SCHEDULED_FATAL, - UFSHCD_STATE_ERROR, -}; - -enum ufshcd_quirks { - /* Interrupt aggregation support is broken */ - UFSHCD_QUIRK_BROKEN_INTR_AGGR = 1 << 0, - - /* - * delay before each dme command is required as the unipro - * layer has shown instabilities - */ - UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS = 1 << 1, - - /* - * If UFS host controller is having issue in processing LCC (Line - * Control Command) coming from device then enable this quirk. - * When this quirk is enabled, host controller driver should disable - * the LCC transmission on UFS device (by clearing TX_LCC_ENABLE - * attribute of device to 0). - */ - UFSHCD_QUIRK_BROKEN_LCC = 1 << 2, - - /* - * The attribute PA_RXHSUNTERMCAP specifies whether or not the - * inbound Link supports unterminated line in HS mode. Setting this - * attribute to 1 fixes moving to HS gear. - */ - UFSHCD_QUIRK_BROKEN_PA_RXHSUNTERMCAP = 1 << 3, - - /* - * This quirk needs to be enabled if the host controller only allows - * accessing the peer dme attributes in AUTO mode (FAST AUTO or - * SLOW AUTO). - */ - UFSHCD_QUIRK_DME_PEER_ACCESS_AUTO_MODE = 1 << 4, - - /* - * This quirk needs to be enabled if the host controller doesn't - * advertise the correct version in UFS_VER register. If this quirk - * is enabled, standard UFS host driver will call the vendor specific - * ops (get_ufs_hci_version) to get the correct version. - */ - UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION = 1 << 5, - - /* - * Clear handling for transfer/task request list is just opposite. - */ - UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR = 1 << 6, - - /* - * This quirk needs to be enabled if host controller doesn't allow - * that the interrupt aggregation timer and counter are reset by s/w. - */ - UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR = 1 << 7, - - /* - * This quirks needs to be enabled if host controller cannot be - * enabled via HCE register. - */ - UFSHCI_QUIRK_BROKEN_HCE = 1 << 8, - - /* - * This quirk needs to be enabled if the host controller regards - * resolution of the values of PRDTO and PRDTL in UTRD as byte. - */ - UFSHCD_QUIRK_PRDT_BYTE_GRAN = 1 << 9, - - /* - * This quirk needs to be enabled if the host controller reports - * OCS FATAL ERROR with device error through sense data - */ - UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR = 1 << 10, - - /* - * This quirk needs to be enabled if the host controller has - * auto-hibernate capability but it doesn't work. - */ - UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8 = 1 << 11, - - /* - * This quirk needs to disable manual flush for write booster - */ - UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL = 1 << 12, - - /* - * This quirk needs to disable unipro timeout values - * before power mode change - */ - UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING = 1 << 13, - - /* - * This quirk allows only sg entries aligned with page size. - */ - UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE = 1 << 14, - - /* - * This quirk needs to be enabled if the host controller does not - * support UIC command - */ - UFSHCD_QUIRK_BROKEN_UIC_CMD = 1 << 15, - - /* - * This quirk needs to be enabled if the host controller cannot - * support physical host configuration. - */ - UFSHCD_QUIRK_SKIP_PH_CONFIGURATION = 1 << 16, -}; - -enum ufshcd_caps { - /* Allow dynamic clk gating */ - UFSHCD_CAP_CLK_GATING = 1 << 0, - - /* Allow hiberb8 with clk gating */ - UFSHCD_CAP_HIBERN8_WITH_CLK_GATING = 1 << 1, - - /* Allow dynamic clk scaling */ - UFSHCD_CAP_CLK_SCALING = 1 << 2, - - /* Allow auto bkops to enabled during runtime suspend */ - UFSHCD_CAP_AUTO_BKOPS_SUSPEND = 1 << 3, - - /* - * This capability allows host controller driver to use the UFS HCI's - * interrupt aggregation capability. - * CAUTION: Enabling this might reduce overall UFS throughput. - */ - UFSHCD_CAP_INTR_AGGR = 1 << 4, - - /* - * This capability allows the device auto-bkops to be always enabled - * except during suspend (both runtime and suspend). - * Enabling this capability means that device will always be allowed - * to do background operation when it's active but it might degrade - * the performance of ongoing read/write operations. - */ - UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND = 1 << 5, - - /* - * This capability allows host controller driver to automatically - * enable runtime power management by itself instead of waiting - * for userspace to control the power management. - */ - UFSHCD_CAP_RPM_AUTOSUSPEND = 1 << 6, - - /* - * This capability allows the host controller driver to turn-on - * WriteBooster, if the underlying device supports it and is - * provisioned to be used. This would increase the write performance. - */ - UFSHCD_CAP_WB_EN = 1 << 7, - - /* - * This capability allows the host controller driver to use the - * inline crypto engine, if it is present - */ - UFSHCD_CAP_CRYPTO = 1 << 8, - - /* - * This capability allows the controller regulators to be put into - * lpm mode aggressively during clock gating. - * This would increase power savings. - */ - UFSHCD_CAP_AGGR_POWER_COLLAPSE = 1 << 9, - - /* - * This capability allows the host controller driver to use DeepSleep, - * if it is supported by the UFS device. The host controller driver must - * support device hardware reset via the hba->device_reset() callback, - * in order to exit DeepSleep state. - */ - UFSHCD_CAP_DEEPSLEEP = 1 << 10, - - /* - * This capability allows the host controller driver to use temperature - * notification if it is supported by the UFS device. - */ - UFSHCD_CAP_TEMP_NOTIF = 1 << 11, -}; - -struct ufs_hba_variant_params { - struct devfreq_dev_profile devfreq_profile; - struct devfreq_simple_ondemand_data ondemand_data; - u16 hba_enable_delay_us; - u32 wb_flush_threshold; -}; - -#ifdef CONFIG_SCSI_UFS_HPB -/** - * struct ufshpb_dev_info - UFSHPB device related info - * @num_lu: the number of user logical unit to check whether all lu finished - * initialization - * @rgn_size: device reported HPB region size - * @srgn_size: device reported HPB sub-region size - * @slave_conf_cnt: counter to check all lu finished initialization - * @hpb_disabled: flag to check if HPB is disabled - * @max_hpb_single_cmd: device reported bMAX_DATA_SIZE_FOR_SINGLE_CMD value - * @is_legacy: flag to check HPB 1.0 - * @control_mode: either host or device - */ -struct ufshpb_dev_info { - int num_lu; - int rgn_size; - int srgn_size; - atomic_t slave_conf_cnt; - bool hpb_disabled; - u8 max_hpb_single_cmd; - bool is_legacy; - u8 control_mode; -}; -#endif - -struct ufs_hba_monitor { - unsigned long chunk_size; - - unsigned long nr_sec_rw[2]; - ktime_t total_busy[2]; - - unsigned long nr_req[2]; - /* latencies*/ - ktime_t lat_sum[2]; - ktime_t lat_max[2]; - ktime_t lat_min[2]; - - u32 nr_queued[2]; - ktime_t busy_start_ts[2]; - - ktime_t enabled_ts; - bool enabled; -}; - -/** - * struct ufs_hba - per adapter private structure - * @mmio_base: UFSHCI base register address - * @ucdl_base_addr: UFS Command Descriptor base address - * @utrdl_base_addr: UTP Transfer Request Descriptor base address - * @utmrdl_base_addr: UTP Task Management Descriptor base address - * @ucdl_dma_addr: UFS Command Descriptor DMA address - * @utrdl_dma_addr: UTRDL DMA address - * @utmrdl_dma_addr: UTMRDL DMA address - * @host: Scsi_Host instance of the driver - * @dev: device handle - * @ufs_device_wlun: WLUN that controls the entire UFS device. - * @hwmon_device: device instance registered with the hwmon core. - * @curr_dev_pwr_mode: active UFS device power mode. - * @uic_link_state: active state of the link to the UFS device. - * @rpm_lvl: desired UFS power management level during runtime PM. - * @spm_lvl: desired UFS power management level during system PM. - * @pm_op_in_progress: whether or not a PM operation is in progress. - * @ahit: value of Auto-Hibernate Idle Timer register. - * @lrb: local reference block - * @outstanding_tasks: Bits representing outstanding task requests - * @outstanding_lock: Protects @outstanding_reqs. - * @outstanding_reqs: Bits representing outstanding transfer requests - * @capabilities: UFS Controller Capabilities - * @nutrs: Transfer Request Queue depth supported by controller - * @nutmrs: Task Management Queue depth supported by controller - * @reserved_slot: Used to submit device commands. Protected by @dev_cmd.lock. - * @ufs_version: UFS Version to which controller complies - * @vops: pointer to variant specific operations - * @vps: pointer to variant specific parameters - * @priv: pointer to variant specific private data - * @irq: Irq number of the controller - * @is_irq_enabled: whether or not the UFS controller interrupt is enabled. - * @dev_ref_clk_freq: reference clock frequency - * @quirks: bitmask with information about deviations from the UFSHCI standard. - * @dev_quirks: bitmask with information about deviations from the UFS standard. - * @tmf_tag_set: TMF tag set. - * @tmf_queue: Used to allocate TMF tags. - * @tmf_rqs: array with pointers to TMF requests while these are in progress. - * @active_uic_cmd: handle of active UIC command - * @uic_cmd_mutex: mutex for UIC command - * @uic_async_done: completion used during UIC processing - * @ufshcd_state: UFSHCD state - * @eh_flags: Error handling flags - * @intr_mask: Interrupt Mask Bits - * @ee_ctrl_mask: Exception event control mask - * @ee_drv_mask: Exception event mask for driver - * @ee_usr_mask: Exception event mask for user (set via debugfs) - * @ee_ctrl_mutex: Used to serialize exception event information. - * @is_powered: flag to check if HBA is powered - * @shutting_down: flag to check if shutdown has been invoked - * @host_sem: semaphore used to serialize concurrent contexts - * @eh_wq: Workqueue that eh_work works on - * @eh_work: Worker to handle UFS errors that require s/w attention - * @eeh_work: Worker to handle exception events - * @errors: HBA errors - * @uic_error: UFS interconnect layer error status - * @saved_err: sticky error mask - * @saved_uic_err: sticky UIC error mask - * @ufs_stats: various error counters - * @force_reset: flag to force eh_work perform a full reset - * @force_pmc: flag to force a power mode change - * @silence_err_logs: flag to silence error logs - * @dev_cmd: ufs device management command information - * @last_dme_cmd_tstamp: time stamp of the last completed DME command - * @nop_out_timeout: NOP OUT timeout value - * @dev_info: information about the UFS device - * @auto_bkops_enabled: to track whether bkops is enabled in device - * @vreg_info: UFS device voltage regulator information - * @clk_list_head: UFS host controller clocks list node head - * @req_abort_count: number of times ufshcd_abort() has been called - * @lanes_per_direction: number of lanes per data direction between the UFS - * controller and the UFS device. - * @pwr_info: holds current power mode - * @max_pwr_info: keeps the device max valid pwm - * @clk_gating: information related to clock gating - * @caps: bitmask with information about UFS controller capabilities - * @devfreq: frequency scaling information owned by the devfreq core - * @clk_scaling: frequency scaling information owned by the UFS driver - * @is_sys_suspended: whether or not the entire system has been suspended - * @urgent_bkops_lvl: keeps track of urgent bkops level for device - * @is_urgent_bkops_lvl_checked: keeps track if the urgent bkops level for - * device is known or not. - * @clk_scaling_lock: used to serialize device commands and clock scaling - * @desc_size: descriptor sizes reported by device - * @scsi_block_reqs_cnt: reference counting for scsi block requests - * @bsg_dev: struct device associated with the BSG queue - * @bsg_queue: BSG queue associated with the UFS controller - * @rpm_dev_flush_recheck_work: used to suspend from RPM (runtime power - * management) after the UFS device has finished a WriteBooster buffer - * flush or auto BKOP. - * @ufshpb_dev: information related to HPB (Host Performance Booster). - * @monitor: statistics about UFS commands - * @crypto_capabilities: Content of crypto capabilities register (0x100) - * @crypto_cap_array: Array of crypto capabilities - * @crypto_cfg_register: Start of the crypto cfg array - * @crypto_profile: the crypto profile of this hba (if applicable) - * @debugfs_root: UFS controller debugfs root directory - * @debugfs_ee_work: used to restore ee_ctrl_mask after a delay - * @debugfs_ee_rate_limit_ms: user configurable delay after which to restore - * ee_ctrl_mask - * @luns_avail: number of regular and well known LUNs supported by the UFS - * device - * @complete_put: whether or not to call ufshcd_rpm_put() from inside - * ufshcd_resume_complete() - */ -struct ufs_hba { - void __iomem *mmio_base; - - /* Virtual memory reference */ - struct utp_transfer_cmd_desc *ucdl_base_addr; - struct utp_transfer_req_desc *utrdl_base_addr; - struct utp_task_req_desc *utmrdl_base_addr; - - /* DMA memory reference */ - dma_addr_t ucdl_dma_addr; - dma_addr_t utrdl_dma_addr; - dma_addr_t utmrdl_dma_addr; - - struct Scsi_Host *host; - struct device *dev; - struct scsi_device *ufs_device_wlun; - -#ifdef CONFIG_SCSI_UFS_HWMON - struct device *hwmon_device; -#endif - - enum ufs_dev_pwr_mode curr_dev_pwr_mode; - enum uic_link_state uic_link_state; - /* Desired UFS power management level during runtime PM */ - enum ufs_pm_level rpm_lvl; - /* Desired UFS power management level during system PM */ - enum ufs_pm_level spm_lvl; - int pm_op_in_progress; - - /* Auto-Hibernate Idle Timer register value */ - u32 ahit; - - struct ufshcd_lrb *lrb; - - unsigned long outstanding_tasks; - spinlock_t outstanding_lock; - unsigned long outstanding_reqs; - - u32 capabilities; - int nutrs; - int nutmrs; - u32 reserved_slot; - u32 ufs_version; - const struct ufs_hba_variant_ops *vops; - struct ufs_hba_variant_params *vps; - void *priv; - unsigned int irq; - bool is_irq_enabled; - enum ufs_ref_clk_freq dev_ref_clk_freq; - - unsigned int quirks; /* Deviations from standard UFSHCI spec. */ - - /* Device deviations from standard UFS device spec. */ - unsigned int dev_quirks; - - struct blk_mq_tag_set tmf_tag_set; - struct request_queue *tmf_queue; - struct request **tmf_rqs; - - struct uic_command *active_uic_cmd; - struct mutex uic_cmd_mutex; - struct completion *uic_async_done; - - enum ufshcd_state ufshcd_state; - u32 eh_flags; - u32 intr_mask; - u16 ee_ctrl_mask; - u16 ee_drv_mask; - u16 ee_usr_mask; - struct mutex ee_ctrl_mutex; - bool is_powered; - bool shutting_down; - struct semaphore host_sem; - - /* Work Queues */ - struct workqueue_struct *eh_wq; - struct work_struct eh_work; - struct work_struct eeh_work; - - /* HBA Errors */ - u32 errors; - u32 uic_error; - u32 saved_err; - u32 saved_uic_err; - struct ufs_stats ufs_stats; - bool force_reset; - bool force_pmc; - bool silence_err_logs; - - /* Device management request data */ - struct ufs_dev_cmd dev_cmd; - ktime_t last_dme_cmd_tstamp; - int nop_out_timeout; - - /* Keeps information of the UFS device connected to this host */ - struct ufs_dev_info dev_info; - bool auto_bkops_enabled; - struct ufs_vreg_info vreg_info; - struct list_head clk_list_head; - - /* Number of requests aborts */ - int req_abort_count; - - /* Number of lanes available (1 or 2) for Rx/Tx */ - u32 lanes_per_direction; - struct ufs_pa_layer_attr pwr_info; - struct ufs_pwr_mode_info max_pwr_info; - - struct ufs_clk_gating clk_gating; - /* Control to enable/disable host capabilities */ - u32 caps; - - struct devfreq *devfreq; - struct ufs_clk_scaling clk_scaling; - bool is_sys_suspended; - - enum bkops_status urgent_bkops_lvl; - bool is_urgent_bkops_lvl_checked; - - struct rw_semaphore clk_scaling_lock; - unsigned char desc_size[QUERY_DESC_IDN_MAX]; - atomic_t scsi_block_reqs_cnt; - - struct device bsg_dev; - struct request_queue *bsg_queue; - struct delayed_work rpm_dev_flush_recheck_work; - -#ifdef CONFIG_SCSI_UFS_HPB - struct ufshpb_dev_info ufshpb_dev; -#endif - - struct ufs_hba_monitor monitor; - -#ifdef CONFIG_SCSI_UFS_CRYPTO - union ufs_crypto_capabilities crypto_capabilities; - union ufs_crypto_cap_entry *crypto_cap_array; - u32 crypto_cfg_register; - struct blk_crypto_profile crypto_profile; -#endif -#ifdef CONFIG_DEBUG_FS - struct dentry *debugfs_root; - struct delayed_work debugfs_ee_work; - u32 debugfs_ee_rate_limit_ms; -#endif - u32 luns_avail; - bool complete_put; -}; - -/* Returns true if clocks can be gated. Otherwise false */ -static inline bool ufshcd_is_clkgating_allowed(struct ufs_hba *hba) -{ - return hba->caps & UFSHCD_CAP_CLK_GATING; -} -static inline bool ufshcd_can_hibern8_during_gating(struct ufs_hba *hba) -{ - return hba->caps & UFSHCD_CAP_HIBERN8_WITH_CLK_GATING; -} -static inline int ufshcd_is_clkscaling_supported(struct ufs_hba *hba) -{ - return hba->caps & UFSHCD_CAP_CLK_SCALING; -} -static inline bool ufshcd_can_autobkops_during_suspend(struct ufs_hba *hba) -{ - return hba->caps & UFSHCD_CAP_AUTO_BKOPS_SUSPEND; -} -static inline bool ufshcd_is_rpm_autosuspend_allowed(struct ufs_hba *hba) -{ - return hba->caps & UFSHCD_CAP_RPM_AUTOSUSPEND; -} - -static inline bool ufshcd_is_intr_aggr_allowed(struct ufs_hba *hba) -{ - return (hba->caps & UFSHCD_CAP_INTR_AGGR) && - !(hba->quirks & UFSHCD_QUIRK_BROKEN_INTR_AGGR); -} - -static inline bool ufshcd_can_aggressive_pc(struct ufs_hba *hba) -{ - return !!(ufshcd_is_link_hibern8(hba) && - (hba->caps & UFSHCD_CAP_AGGR_POWER_COLLAPSE)); -} - -static inline bool ufshcd_is_auto_hibern8_supported(struct ufs_hba *hba) -{ - return (hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT) && - !(hba->quirks & UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8); -} - -static inline bool ufshcd_is_auto_hibern8_enabled(struct ufs_hba *hba) -{ - return FIELD_GET(UFSHCI_AHIBERN8_TIMER_MASK, hba->ahit); -} - -static inline bool ufshcd_is_wb_allowed(struct ufs_hba *hba) -{ - return hba->caps & UFSHCD_CAP_WB_EN; -} - -#define ufshcd_writel(hba, val, reg) \ - writel((val), (hba)->mmio_base + (reg)) -#define ufshcd_readl(hba, reg) \ - readl((hba)->mmio_base + (reg)) - -/** - * ufshcd_rmwl - perform read/modify/write for a controller register - * @hba: per adapter instance - * @mask: mask to apply on read value - * @val: actual value to write - * @reg: register address - */ -static inline void ufshcd_rmwl(struct ufs_hba *hba, u32 mask, u32 val, u32 reg) -{ - u32 tmp; - - tmp = ufshcd_readl(hba, reg); - tmp &= ~mask; - tmp |= (val & mask); - ufshcd_writel(hba, tmp, reg); -} - -int ufshcd_alloc_host(struct device *, struct ufs_hba **); -void ufshcd_dealloc_host(struct ufs_hba *); -int ufshcd_hba_enable(struct ufs_hba *hba); -int ufshcd_init(struct ufs_hba *, void __iomem *, unsigned int); -int ufshcd_link_recovery(struct ufs_hba *hba); -int ufshcd_make_hba_operational(struct ufs_hba *hba); -void ufshcd_remove(struct ufs_hba *); -int ufshcd_uic_hibern8_enter(struct ufs_hba *hba); -int ufshcd_uic_hibern8_exit(struct ufs_hba *hba); -void ufshcd_delay_us(unsigned long us, unsigned long tolerance); -void ufshcd_parse_dev_ref_clk_freq(struct ufs_hba *hba, struct clk *refclk); -void ufshcd_update_evt_hist(struct ufs_hba *hba, u32 id, u32 val); -void ufshcd_hba_stop(struct ufs_hba *hba); -void ufshcd_schedule_eh_work(struct ufs_hba *hba); - -static inline void check_upiu_size(void) -{ - BUILD_BUG_ON(ALIGNED_UPIU_SIZE < - GENERAL_UPIU_REQUEST_SIZE + QUERY_DESC_MAX_SIZE); -} - -/** - * ufshcd_set_variant - set variant specific data to the hba - * @hba: per adapter instance - * @variant: pointer to variant specific data - */ -static inline void ufshcd_set_variant(struct ufs_hba *hba, void *variant) -{ - BUG_ON(!hba); - hba->priv = variant; -} - -/** - * ufshcd_get_variant - get variant specific data from the hba - * @hba: per adapter instance - */ -static inline void *ufshcd_get_variant(struct ufs_hba *hba) -{ - BUG_ON(!hba); - return hba->priv; -} - -#ifdef CONFIG_PM -extern int ufshcd_runtime_suspend(struct device *dev); -extern int ufshcd_runtime_resume(struct device *dev); -#endif -#ifdef CONFIG_PM_SLEEP -extern int ufshcd_system_suspend(struct device *dev); -extern int ufshcd_system_resume(struct device *dev); -#endif -extern int ufshcd_shutdown(struct ufs_hba *hba); -extern int ufshcd_dme_configure_adapt(struct ufs_hba *hba, - int agreed_gear, - int adapt_val); -extern int ufshcd_dme_set_attr(struct ufs_hba *hba, u32 attr_sel, - u8 attr_set, u32 mib_val, u8 peer); -extern int ufshcd_dme_get_attr(struct ufs_hba *hba, u32 attr_sel, - u32 *mib_val, u8 peer); -extern int ufshcd_config_pwr_mode(struct ufs_hba *hba, - struct ufs_pa_layer_attr *desired_pwr_mode); - -/* UIC command interfaces for DME primitives */ -#define DME_LOCAL 0 -#define DME_PEER 1 -#define ATTR_SET_NOR 0 /* NORMAL */ -#define ATTR_SET_ST 1 /* STATIC */ - -static inline int ufshcd_dme_set(struct ufs_hba *hba, u32 attr_sel, - u32 mib_val) -{ - return ufshcd_dme_set_attr(hba, attr_sel, ATTR_SET_NOR, - mib_val, DME_LOCAL); -} - -static inline int ufshcd_dme_st_set(struct ufs_hba *hba, u32 attr_sel, - u32 mib_val) -{ - return ufshcd_dme_set_attr(hba, attr_sel, ATTR_SET_ST, - mib_val, DME_LOCAL); -} - -static inline int ufshcd_dme_peer_set(struct ufs_hba *hba, u32 attr_sel, - u32 mib_val) -{ - return ufshcd_dme_set_attr(hba, attr_sel, ATTR_SET_NOR, - mib_val, DME_PEER); -} - -static inline int ufshcd_dme_peer_st_set(struct ufs_hba *hba, u32 attr_sel, - u32 mib_val) -{ - return ufshcd_dme_set_attr(hba, attr_sel, ATTR_SET_ST, - mib_val, DME_PEER); -} - -static inline int ufshcd_dme_get(struct ufs_hba *hba, - u32 attr_sel, u32 *mib_val) -{ - return ufshcd_dme_get_attr(hba, attr_sel, mib_val, DME_LOCAL); -} - -static inline int ufshcd_dme_peer_get(struct ufs_hba *hba, - u32 attr_sel, u32 *mib_val) -{ - return ufshcd_dme_get_attr(hba, attr_sel, mib_val, DME_PEER); -} - -static inline bool ufshcd_is_hs_mode(struct ufs_pa_layer_attr *pwr_info) -{ - return (pwr_info->pwr_rx == FAST_MODE || - pwr_info->pwr_rx == FASTAUTO_MODE) && - (pwr_info->pwr_tx == FAST_MODE || - pwr_info->pwr_tx == FASTAUTO_MODE); -} - -static inline int ufshcd_disable_host_tx_lcc(struct ufs_hba *hba) -{ - return ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0); -} - -/* Expose Query-Request API */ -int ufshcd_query_descriptor_retry(struct ufs_hba *hba, - enum query_opcode opcode, - enum desc_idn idn, u8 index, - u8 selector, - u8 *desc_buf, int *buf_len); -int ufshcd_read_desc_param(struct ufs_hba *hba, - enum desc_idn desc_id, - int desc_index, - u8 param_offset, - u8 *param_read_buf, - u8 param_size); -int ufshcd_query_attr_retry(struct ufs_hba *hba, enum query_opcode opcode, - enum attr_idn idn, u8 index, u8 selector, - u32 *attr_val); -int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, - enum attr_idn idn, u8 index, u8 selector, u32 *attr_val); -int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, - enum flag_idn idn, u8 index, bool *flag_res); - -void ufshcd_auto_hibern8_enable(struct ufs_hba *hba); -void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit); -void ufshcd_fixup_dev_quirks(struct ufs_hba *hba, - const struct ufs_dev_quirk *fixups); -#define SD_ASCII_STD true -#define SD_RAW false -int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, - u8 **buf, bool ascii); - -int ufshcd_hold(struct ufs_hba *hba, bool async); -void ufshcd_release(struct ufs_hba *hba); - -void ufshcd_clkgate_delay_set(struct device *dev, unsigned long value); - -void ufshcd_map_desc_id_to_length(struct ufs_hba *hba, enum desc_idn desc_id, - int *desc_length); - -u32 ufshcd_get_local_unipro_ver(struct ufs_hba *hba); - -int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd); - -int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba, - struct utp_upiu_req *req_upiu, - struct utp_upiu_req *rsp_upiu, - int msgcode, - u8 *desc_buff, int *buff_len, - enum query_opcode desc_op); - -int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable); -int ufshcd_suspend_prepare(struct device *dev); -int __ufshcd_suspend_prepare(struct device *dev, bool rpm_ok_for_spm); -void ufshcd_resume_complete(struct device *dev); - -/* Wrapper functions for safely calling variant operations */ -static inline int ufshcd_vops_init(struct ufs_hba *hba) -{ - if (hba->vops && hba->vops->init) - return hba->vops->init(hba); - - return 0; -} - -static inline int ufshcd_vops_phy_initialization(struct ufs_hba *hba) -{ - if (hba->vops && hba->vops->phy_initialization) - return hba->vops->phy_initialization(hba); - - return 0; -} - -extern struct ufs_pm_lvl_states ufs_pm_lvl_states[]; - -int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len, - const char *prefix); - -int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask); -int ufshcd_write_ee_control(struct ufs_hba *hba); -int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, u16 *other_mask, - u16 set, u16 clr); - -#endif /* End of Header */ diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h deleted file mode 100644 index f81aa95ffbc4..000000000000 --- a/drivers/scsi/ufs/ufshci.h +++ /dev/null @@ -1,510 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Universal Flash Storage Host controller driver - * Copyright (C) 2011-2013 Samsung India Software Operations - * - * Authors: - * Santosh Yaraganavi <santosh.sy@samsung.com> - * Vinayak Holikatti <h.vinayak@samsung.com> - */ - -#ifndef _UFSHCI_H -#define _UFSHCI_H - -#include <scsi/scsi_host.h> - -enum { - TASK_REQ_UPIU_SIZE_DWORDS = 8, - TASK_RSP_UPIU_SIZE_DWORDS = 8, - ALIGNED_UPIU_SIZE = 512, -}; - -/* UFSHCI Registers */ -enum { - REG_CONTROLLER_CAPABILITIES = 0x00, - REG_UFS_VERSION = 0x08, - REG_CONTROLLER_DEV_ID = 0x10, - REG_CONTROLLER_PROD_ID = 0x14, - REG_AUTO_HIBERNATE_IDLE_TIMER = 0x18, - REG_INTERRUPT_STATUS = 0x20, - REG_INTERRUPT_ENABLE = 0x24, - REG_CONTROLLER_STATUS = 0x30, - REG_CONTROLLER_ENABLE = 0x34, - REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER = 0x38, - REG_UIC_ERROR_CODE_DATA_LINK_LAYER = 0x3C, - REG_UIC_ERROR_CODE_NETWORK_LAYER = 0x40, - REG_UIC_ERROR_CODE_TRANSPORT_LAYER = 0x44, - REG_UIC_ERROR_CODE_DME = 0x48, - REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL = 0x4C, - REG_UTP_TRANSFER_REQ_LIST_BASE_L = 0x50, - REG_UTP_TRANSFER_REQ_LIST_BASE_H = 0x54, - REG_UTP_TRANSFER_REQ_DOOR_BELL = 0x58, - REG_UTP_TRANSFER_REQ_LIST_CLEAR = 0x5C, - REG_UTP_TRANSFER_REQ_LIST_RUN_STOP = 0x60, - REG_UTP_TASK_REQ_LIST_BASE_L = 0x70, - REG_UTP_TASK_REQ_LIST_BASE_H = 0x74, - REG_UTP_TASK_REQ_DOOR_BELL = 0x78, - REG_UTP_TASK_REQ_LIST_CLEAR = 0x7C, - REG_UTP_TASK_REQ_LIST_RUN_STOP = 0x80, - REG_UIC_COMMAND = 0x90, - REG_UIC_COMMAND_ARG_1 = 0x94, - REG_UIC_COMMAND_ARG_2 = 0x98, - REG_UIC_COMMAND_ARG_3 = 0x9C, - - UFSHCI_REG_SPACE_SIZE = 0xA0, - - REG_UFS_CCAP = 0x100, - REG_UFS_CRYPTOCAP = 0x104, - - UFSHCI_CRYPTO_REG_SPACE_SIZE = 0x400, -}; - -/* Controller capability masks */ -enum { - MASK_TRANSFER_REQUESTS_SLOTS = 0x0000001F, - MASK_TASK_MANAGEMENT_REQUEST_SLOTS = 0x00070000, - MASK_AUTO_HIBERN8_SUPPORT = 0x00800000, - MASK_64_ADDRESSING_SUPPORT = 0x01000000, - MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT = 0x02000000, - MASK_UIC_DME_TEST_MODE_SUPPORT = 0x04000000, - MASK_CRYPTO_SUPPORT = 0x10000000, -}; - -#define UFS_MASK(mask, offset) ((mask) << (offset)) - -/* UFS Version 08h */ -#define MINOR_VERSION_NUM_MASK UFS_MASK(0xFFFF, 0) -#define MAJOR_VERSION_NUM_MASK UFS_MASK(0xFFFF, 16) - -/* - * Controller UFSHCI version - * - 2.x and newer use the following scheme: - * major << 8 + minor << 4 - * - 1.x has been converted to match this in - * ufshcd_get_ufs_version() - */ -static inline u32 ufshci_version(u32 major, u32 minor) -{ - return (major << 8) + (minor << 4); -} - -/* - * HCDDID - Host Controller Identification Descriptor - * - Device ID and Device Class 10h - */ -#define DEVICE_CLASS UFS_MASK(0xFFFF, 0) -#define DEVICE_ID UFS_MASK(0xFF, 24) - -/* - * HCPMID - Host Controller Identification Descriptor - * - Product/Manufacturer ID 14h - */ -#define MANUFACTURE_ID_MASK UFS_MASK(0xFFFF, 0) -#define PRODUCT_ID_MASK UFS_MASK(0xFFFF, 16) - -/* AHIT - Auto-Hibernate Idle Timer */ -#define UFSHCI_AHIBERN8_TIMER_MASK GENMASK(9, 0) -#define UFSHCI_AHIBERN8_SCALE_MASK GENMASK(12, 10) -#define UFSHCI_AHIBERN8_SCALE_FACTOR 10 -#define UFSHCI_AHIBERN8_MAX (1023 * 100000) - -/* - * IS - Interrupt Status - 20h - */ -#define UTP_TRANSFER_REQ_COMPL 0x1 -#define UIC_DME_END_PT_RESET 0x2 -#define UIC_ERROR 0x4 -#define UIC_TEST_MODE 0x8 -#define UIC_POWER_MODE 0x10 -#define UIC_HIBERNATE_EXIT 0x20 -#define UIC_HIBERNATE_ENTER 0x40 -#define UIC_LINK_LOST 0x80 -#define UIC_LINK_STARTUP 0x100 -#define UTP_TASK_REQ_COMPL 0x200 -#define UIC_COMMAND_COMPL 0x400 -#define DEVICE_FATAL_ERROR 0x800 -#define CONTROLLER_FATAL_ERROR 0x10000 -#define SYSTEM_BUS_FATAL_ERROR 0x20000 -#define CRYPTO_ENGINE_FATAL_ERROR 0x40000 - -#define UFSHCD_UIC_HIBERN8_MASK (UIC_HIBERNATE_ENTER |\ - UIC_HIBERNATE_EXIT) - -#define UFSHCD_UIC_PWR_MASK (UFSHCD_UIC_HIBERN8_MASK |\ - UIC_POWER_MODE) - -#define UFSHCD_UIC_MASK (UIC_COMMAND_COMPL | UFSHCD_UIC_PWR_MASK) - -#define UFSHCD_ERROR_MASK (UIC_ERROR |\ - DEVICE_FATAL_ERROR |\ - CONTROLLER_FATAL_ERROR |\ - SYSTEM_BUS_FATAL_ERROR |\ - CRYPTO_ENGINE_FATAL_ERROR) - -#define INT_FATAL_ERRORS (DEVICE_FATAL_ERROR |\ - CONTROLLER_FATAL_ERROR |\ - SYSTEM_BUS_FATAL_ERROR |\ - CRYPTO_ENGINE_FATAL_ERROR |\ - UIC_LINK_LOST) - -/* HCS - Host Controller Status 30h */ -#define DEVICE_PRESENT 0x1 -#define UTP_TRANSFER_REQ_LIST_READY 0x2 -#define UTP_TASK_REQ_LIST_READY 0x4 -#define UIC_COMMAND_READY 0x8 -#define HOST_ERROR_INDICATOR 0x10 -#define DEVICE_ERROR_INDICATOR 0x20 -#define UIC_POWER_MODE_CHANGE_REQ_STATUS_MASK UFS_MASK(0x7, 8) - -#define UFSHCD_STATUS_READY (UTP_TRANSFER_REQ_LIST_READY |\ - UTP_TASK_REQ_LIST_READY |\ - UIC_COMMAND_READY) - -enum { - PWR_OK = 0x0, - PWR_LOCAL = 0x01, - PWR_REMOTE = 0x02, - PWR_BUSY = 0x03, - PWR_ERROR_CAP = 0x04, - PWR_FATAL_ERROR = 0x05, -}; - -/* HCE - Host Controller Enable 34h */ -#define CONTROLLER_ENABLE 0x1 -#define CONTROLLER_DISABLE 0x0 -#define CRYPTO_GENERAL_ENABLE 0x2 - -/* UECPA - Host UIC Error Code PHY Adapter Layer 38h */ -#define UIC_PHY_ADAPTER_LAYER_ERROR 0x80000000 -#define UIC_PHY_ADAPTER_LAYER_ERROR_CODE_MASK 0x1F -#define UIC_PHY_ADAPTER_LAYER_LANE_ERR_MASK 0xF -#define UIC_PHY_ADAPTER_LAYER_GENERIC_ERROR 0x10 - -/* UECDL - Host UIC Error Code Data Link Layer 3Ch */ -#define UIC_DATA_LINK_LAYER_ERROR 0x80000000 -#define UIC_DATA_LINK_LAYER_ERROR_CODE_MASK 0xFFFF -#define UIC_DATA_LINK_LAYER_ERROR_TCX_REP_TIMER_EXP 0x2 -#define UIC_DATA_LINK_LAYER_ERROR_AFCX_REQ_TIMER_EXP 0x4 -#define UIC_DATA_LINK_LAYER_ERROR_FCX_PRO_TIMER_EXP 0x8 -#define UIC_DATA_LINK_LAYER_ERROR_RX_BUF_OF 0x20 -#define UIC_DATA_LINK_LAYER_ERROR_PA_INIT 0x2000 -#define UIC_DATA_LINK_LAYER_ERROR_NAC_RECEIVED 0x0001 -#define UIC_DATA_LINK_LAYER_ERROR_TCx_REPLAY_TIMEOUT 0x0002 - -/* UECN - Host UIC Error Code Network Layer 40h */ -#define UIC_NETWORK_LAYER_ERROR 0x80000000 -#define UIC_NETWORK_LAYER_ERROR_CODE_MASK 0x7 -#define UIC_NETWORK_UNSUPPORTED_HEADER_TYPE 0x1 -#define UIC_NETWORK_BAD_DEVICEID_ENC 0x2 -#define UIC_NETWORK_LHDR_TRAP_PACKET_DROPPING 0x4 - -/* UECT - Host UIC Error Code Transport Layer 44h */ -#define UIC_TRANSPORT_LAYER_ERROR 0x80000000 -#define UIC_TRANSPORT_LAYER_ERROR_CODE_MASK 0x7F -#define UIC_TRANSPORT_UNSUPPORTED_HEADER_TYPE 0x1 -#define UIC_TRANSPORT_UNKNOWN_CPORTID 0x2 -#define UIC_TRANSPORT_NO_CONNECTION_RX 0x4 -#define UIC_TRANSPORT_CONTROLLED_SEGMENT_DROPPING 0x8 -#define UIC_TRANSPORT_BAD_TC 0x10 -#define UIC_TRANSPORT_E2E_CREDIT_OVERFOW 0x20 -#define UIC_TRANSPORT_SAFETY_VALUE_DROPPING 0x40 - -/* UECDME - Host UIC Error Code DME 48h */ -#define UIC_DME_ERROR 0x80000000 -#define UIC_DME_ERROR_CODE_MASK 0x1 - -/* UTRIACR - Interrupt Aggregation control register - 0x4Ch */ -#define INT_AGGR_TIMEOUT_VAL_MASK 0xFF -#define INT_AGGR_COUNTER_THRESHOLD_MASK UFS_MASK(0x1F, 8) -#define INT_AGGR_COUNTER_AND_TIMER_RESET 0x10000 -#define INT_AGGR_STATUS_BIT 0x100000 -#define INT_AGGR_PARAM_WRITE 0x1000000 -#define INT_AGGR_ENABLE 0x80000000 - -/* UTRLRSR - UTP Transfer Request Run-Stop Register 60h */ -#define UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT 0x1 - -/* UTMRLRSR - UTP Task Management Request Run-Stop Register 80h */ -#define UTP_TASK_REQ_LIST_RUN_STOP_BIT 0x1 - -/* UICCMD - UIC Command */ -#define COMMAND_OPCODE_MASK 0xFF -#define GEN_SELECTOR_INDEX_MASK 0xFFFF - -#define MIB_ATTRIBUTE_MASK UFS_MASK(0xFFFF, 16) -#define RESET_LEVEL 0xFF - -#define ATTR_SET_TYPE_MASK UFS_MASK(0xFF, 16) -#define CONFIG_RESULT_CODE_MASK 0xFF -#define GENERIC_ERROR_CODE_MASK 0xFF - -/* GenSelectorIndex calculation macros for M-PHY attributes */ -#define UIC_ARG_MPHY_TX_GEN_SEL_INDEX(lane) (lane) -#define UIC_ARG_MPHY_RX_GEN_SEL_INDEX(lane) (PA_MAXDATALANES + (lane)) - -#define UIC_ARG_MIB_SEL(attr, sel) ((((attr) & 0xFFFF) << 16) |\ - ((sel) & 0xFFFF)) -#define UIC_ARG_MIB(attr) UIC_ARG_MIB_SEL(attr, 0) -#define UIC_ARG_ATTR_TYPE(t) (((t) & 0xFF) << 16) -#define UIC_GET_ATTR_ID(v) (((v) >> 16) & 0xFFFF) - -/* Link Status*/ -enum link_status { - UFSHCD_LINK_IS_DOWN = 1, - UFSHCD_LINK_IS_UP = 2, -}; - -/* UIC Commands */ -enum uic_cmd_dme { - UIC_CMD_DME_GET = 0x01, - UIC_CMD_DME_SET = 0x02, - UIC_CMD_DME_PEER_GET = 0x03, - UIC_CMD_DME_PEER_SET = 0x04, - UIC_CMD_DME_POWERON = 0x10, - UIC_CMD_DME_POWEROFF = 0x11, - UIC_CMD_DME_ENABLE = 0x12, - UIC_CMD_DME_RESET = 0x14, - UIC_CMD_DME_END_PT_RST = 0x15, - UIC_CMD_DME_LINK_STARTUP = 0x16, - UIC_CMD_DME_HIBER_ENTER = 0x17, - UIC_CMD_DME_HIBER_EXIT = 0x18, - UIC_CMD_DME_TEST_MODE = 0x1A, -}; - -/* UIC Config result code / Generic error code */ -enum { - UIC_CMD_RESULT_SUCCESS = 0x00, - UIC_CMD_RESULT_INVALID_ATTR = 0x01, - UIC_CMD_RESULT_FAILURE = 0x01, - UIC_CMD_RESULT_INVALID_ATTR_VALUE = 0x02, - UIC_CMD_RESULT_READ_ONLY_ATTR = 0x03, - UIC_CMD_RESULT_WRITE_ONLY_ATTR = 0x04, - UIC_CMD_RESULT_BAD_INDEX = 0x05, - UIC_CMD_RESULT_LOCKED_ATTR = 0x06, - UIC_CMD_RESULT_BAD_TEST_FEATURE_INDEX = 0x07, - UIC_CMD_RESULT_PEER_COMM_FAILURE = 0x08, - UIC_CMD_RESULT_BUSY = 0x09, - UIC_CMD_RESULT_DME_FAILURE = 0x0A, -}; - -#define MASK_UIC_COMMAND_RESULT 0xFF - -#define INT_AGGR_COUNTER_THLD_VAL(c) (((c) & 0x1F) << 8) -#define INT_AGGR_TIMEOUT_VAL(t) (((t) & 0xFF) << 0) - -/* Interrupt disable masks */ -enum { - /* Interrupt disable mask for UFSHCI v1.0 */ - INTERRUPT_MASK_ALL_VER_10 = 0x30FFF, - INTERRUPT_MASK_RW_VER_10 = 0x30000, - - /* Interrupt disable mask for UFSHCI v1.1 */ - INTERRUPT_MASK_ALL_VER_11 = 0x31FFF, - - /* Interrupt disable mask for UFSHCI v2.1 */ - INTERRUPT_MASK_ALL_VER_21 = 0x71FFF, -}; - -/* CCAP - Crypto Capability 100h */ -union ufs_crypto_capabilities { - __le32 reg_val; - struct { - u8 num_crypto_cap; - u8 config_count; - u8 reserved; - u8 config_array_ptr; - }; -}; - -enum ufs_crypto_key_size { - UFS_CRYPTO_KEY_SIZE_INVALID = 0x0, - UFS_CRYPTO_KEY_SIZE_128 = 0x1, - UFS_CRYPTO_KEY_SIZE_192 = 0x2, - UFS_CRYPTO_KEY_SIZE_256 = 0x3, - UFS_CRYPTO_KEY_SIZE_512 = 0x4, -}; - -enum ufs_crypto_alg { - UFS_CRYPTO_ALG_AES_XTS = 0x0, - UFS_CRYPTO_ALG_BITLOCKER_AES_CBC = 0x1, - UFS_CRYPTO_ALG_AES_ECB = 0x2, - UFS_CRYPTO_ALG_ESSIV_AES_CBC = 0x3, -}; - -/* x-CRYPTOCAP - Crypto Capability X */ -union ufs_crypto_cap_entry { - __le32 reg_val; - struct { - u8 algorithm_id; - u8 sdus_mask; /* Supported data unit size mask */ - u8 key_size; - u8 reserved; - }; -}; - -#define UFS_CRYPTO_CONFIGURATION_ENABLE (1 << 7) -#define UFS_CRYPTO_KEY_MAX_SIZE 64 -/* x-CRYPTOCFG - Crypto Configuration X */ -union ufs_crypto_cfg_entry { - __le32 reg_val[32]; - struct { - u8 crypto_key[UFS_CRYPTO_KEY_MAX_SIZE]; - u8 data_unit_size; - u8 crypto_cap_idx; - u8 reserved_1; - u8 config_enable; - u8 reserved_multi_host; - u8 reserved_2; - u8 vsb[2]; - u8 reserved_3[56]; - }; -}; - -/* - * Request Descriptor Definitions - */ - -/* Transfer request command type */ -enum { - UTP_CMD_TYPE_SCSI = 0x0, - UTP_CMD_TYPE_UFS = 0x1, - UTP_CMD_TYPE_DEV_MANAGE = 0x2, -}; - -/* To accommodate UFS2.0 required Command type */ -enum { - UTP_CMD_TYPE_UFS_STORAGE = 0x1, -}; - -enum { - UTP_SCSI_COMMAND = 0x00000000, - UTP_NATIVE_UFS_COMMAND = 0x10000000, - UTP_DEVICE_MANAGEMENT_FUNCTION = 0x20000000, - UTP_REQ_DESC_INT_CMD = 0x01000000, - UTP_REQ_DESC_CRYPTO_ENABLE_CMD = 0x00800000, -}; - -/* UTP Transfer Request Data Direction (DD) */ -enum { - UTP_NO_DATA_TRANSFER = 0x00000000, - UTP_HOST_TO_DEVICE = 0x02000000, - UTP_DEVICE_TO_HOST = 0x04000000, -}; - -/* Overall command status values */ -enum utp_ocs { - OCS_SUCCESS = 0x0, - OCS_INVALID_CMD_TABLE_ATTR = 0x1, - OCS_INVALID_PRDT_ATTR = 0x2, - OCS_MISMATCH_DATA_BUF_SIZE = 0x3, - OCS_MISMATCH_RESP_UPIU_SIZE = 0x4, - OCS_PEER_COMM_FAILURE = 0x5, - OCS_ABORTED = 0x6, - OCS_FATAL_ERROR = 0x7, - OCS_DEVICE_FATAL_ERROR = 0x8, - OCS_INVALID_CRYPTO_CONFIG = 0x9, - OCS_GENERAL_CRYPTO_ERROR = 0xA, - OCS_INVALID_COMMAND_STATUS = 0x0F, -}; - -enum { - MASK_OCS = 0x0F, -}; - -/* The maximum length of the data byte count field in the PRDT is 256KB */ -#define PRDT_DATA_BYTE_COUNT_MAX (256 * 1024) -/* The granularity of the data byte count field in the PRDT is 32-bit */ -#define PRDT_DATA_BYTE_COUNT_PAD 4 - -/** - * struct ufshcd_sg_entry - UFSHCI PRD Entry - * @addr: Physical address; DW-0 and DW-1. - * @reserved: Reserved for future use DW-2 - * @size: size of physical segment DW-3 - */ -struct ufshcd_sg_entry { - __le64 addr; - __le32 reserved; - __le32 size; -}; - -/** - * struct utp_transfer_cmd_desc - UTP Command Descriptor (UCD) - * @command_upiu: Command UPIU Frame address - * @response_upiu: Response UPIU Frame address - * @prd_table: Physical Region Descriptor - */ -struct utp_transfer_cmd_desc { - u8 command_upiu[ALIGNED_UPIU_SIZE]; - u8 response_upiu[ALIGNED_UPIU_SIZE]; - struct ufshcd_sg_entry prd_table[SG_ALL]; -}; - -/** - * struct request_desc_header - Descriptor Header common to both UTRD and UTMRD - * @dword0: Descriptor Header DW0 - * @dword1: Descriptor Header DW1 - * @dword2: Descriptor Header DW2 - * @dword3: Descriptor Header DW3 - */ -struct request_desc_header { - __le32 dword_0; - __le32 dword_1; - __le32 dword_2; - __le32 dword_3; -}; - -/** - * struct utp_transfer_req_desc - UTP Transfer Request Descriptor (UTRD) - * @header: UTRD header DW-0 to DW-3 - * @command_desc_base_addr_lo: UCD base address low DW-4 - * @command_desc_base_addr_hi: UCD base address high DW-5 - * @response_upiu_length: response UPIU length DW-6 - * @response_upiu_offset: response UPIU offset DW-6 - * @prd_table_length: Physical region descriptor length DW-7 - * @prd_table_offset: Physical region descriptor offset DW-7 - */ -struct utp_transfer_req_desc { - - /* DW 0-3 */ - struct request_desc_header header; - - /* DW 4-5*/ - __le32 command_desc_base_addr_lo; - __le32 command_desc_base_addr_hi; - - /* DW 6 */ - __le16 response_upiu_length; - __le16 response_upiu_offset; - - /* DW 7 */ - __le16 prd_table_length; - __le16 prd_table_offset; -}; - -/* - * UTMRD structure. - */ -struct utp_task_req_desc { - /* DW 0-3 */ - struct request_desc_header header; - - /* DW 4-11 - Task request UPIU structure */ - struct { - struct utp_upiu_header req_header; - __be32 input_param1; - __be32 input_param2; - __be32 input_param3; - __be32 __reserved1[2]; - } upiu_req; - - /* DW 12-19 - Task Management Response UPIU structure */ - struct { - struct utp_upiu_header rsp_header; - __be32 output_param1; - __be32 output_param2; - __be32 __reserved2[3]; - } upiu_rsp; -}; - -#endif /* End of Header */ diff --git a/drivers/scsi/ufs/unipro.h b/drivers/scsi/ufs/unipro.h deleted file mode 100644 index 0521f887e3ac..000000000000 --- a/drivers/scsi/ufs/unipro.h +++ /dev/null @@ -1,316 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2013 Samsung Electronics Co., Ltd. - */ - -#ifndef _UNIPRO_H_ -#define _UNIPRO_H_ - -/* - * M-TX Configuration Attributes - */ -#define TX_HIBERN8TIME_CAPABILITY 0x000F -#define TX_MODE 0x0021 -#define TX_HSRATE_SERIES 0x0022 -#define TX_HSGEAR 0x0023 -#define TX_PWMGEAR 0x0024 -#define TX_AMPLITUDE 0x0025 -#define TX_HS_SLEWRATE 0x0026 -#define TX_SYNC_SOURCE 0x0027 -#define TX_HS_SYNC_LENGTH 0x0028 -#define TX_HS_PREPARE_LENGTH 0x0029 -#define TX_LS_PREPARE_LENGTH 0x002A -#define TX_HIBERN8_CONTROL 0x002B -#define TX_LCC_ENABLE 0x002C -#define TX_PWM_BURST_CLOSURE_EXTENSION 0x002D -#define TX_BYPASS_8B10B_ENABLE 0x002E -#define TX_DRIVER_POLARITY 0x002F -#define TX_HS_UNTERMINATED_LINE_DRIVE_ENABLE 0x0030 -#define TX_LS_TERMINATED_LINE_DRIVE_ENABLE 0x0031 -#define TX_LCC_SEQUENCER 0x0032 -#define TX_MIN_ACTIVATETIME 0x0033 -#define TX_PWM_G6_G7_SYNC_LENGTH 0x0034 -#define TX_REFCLKFREQ 0x00EB -#define TX_CFGCLKFREQVAL 0x00EC -#define CFGEXTRATTR 0x00F0 -#define DITHERCTRL2 0x00F1 - -/* - * M-RX Configuration Attributes - */ -#define RX_MODE 0x00A1 -#define RX_HSRATE_SERIES 0x00A2 -#define RX_HSGEAR 0x00A3 -#define RX_PWMGEAR 0x00A4 -#define RX_LS_TERMINATED_ENABLE 0x00A5 -#define RX_HS_UNTERMINATED_ENABLE 0x00A6 -#define RX_ENTER_HIBERN8 0x00A7 -#define RX_BYPASS_8B10B_ENABLE 0x00A8 -#define RX_TERMINATION_FORCE_ENABLE 0x00A9 -#define RX_MIN_ACTIVATETIME_CAPABILITY 0x008F -#define RX_HIBERN8TIME_CAPABILITY 0x0092 -#define RX_REFCLKFREQ 0x00EB -#define RX_CFGCLKFREQVAL 0x00EC -#define CFGWIDEINLN 0x00F0 -#define CFGRXCDR8 0x00BA -#define ENARXDIRECTCFG4 0x00F2 -#define CFGRXOVR8 0x00BD -#define RXDIRECTCTRL2 0x00C7 -#define ENARXDIRECTCFG3 0x00F3 -#define RXCALCTRL 0x00B4 -#define ENARXDIRECTCFG2 0x00F4 -#define CFGRXOVR4 0x00E9 -#define RXSQCTRL 0x00B5 -#define CFGRXOVR6 0x00BF -#define RX_HS_G1_SYNC_LENGTH_CAP 0x008B -#define RX_HS_G1_PREP_LENGTH_CAP 0x008C -#define RX_HS_G2_SYNC_LENGTH_CAP 0x0094 -#define RX_HS_G3_SYNC_LENGTH_CAP 0x0095 -#define RX_HS_G2_PREP_LENGTH_CAP 0x0096 -#define RX_HS_G3_PREP_LENGTH_CAP 0x0097 -#define RX_ADV_GRANULARITY_CAP 0x0098 -#define RX_MIN_ACTIVATETIME_CAP 0x008F -#define RX_HIBERN8TIME_CAP 0x0092 -#define RX_ADV_HIBERN8TIME_CAP 0x0099 -#define RX_ADV_MIN_ACTIVATETIME_CAP 0x009A - - -#define is_mphy_tx_attr(attr) (attr < RX_MODE) -#define RX_ADV_FINE_GRAN_STEP(x) ((((x) & 0x3) << 1) | 0x1) -#define SYNC_LEN_FINE(x) ((x) & 0x3F) -#define SYNC_LEN_COARSE(x) ((1 << 6) | ((x) & 0x3F)) -#define PREP_LEN(x) ((x) & 0xF) - -#define RX_MIN_ACTIVATETIME_UNIT_US 100 -#define HIBERN8TIME_UNIT_US 100 - -/* - * Common Block Attributes - */ -#define TX_GLOBALHIBERNATE UNIPRO_CB_OFFSET(0x002B) -#define REFCLKMODE UNIPRO_CB_OFFSET(0x00BF) -#define DIRECTCTRL19 UNIPRO_CB_OFFSET(0x00CD) -#define DIRECTCTRL10 UNIPRO_CB_OFFSET(0x00E6) -#define CDIRECTCTRL6 UNIPRO_CB_OFFSET(0x00EA) -#define RTOBSERVESELECT UNIPRO_CB_OFFSET(0x00F0) -#define CBDIVFACTOR UNIPRO_CB_OFFSET(0x00F1) -#define CBDCOCTRL5 UNIPRO_CB_OFFSET(0x00F3) -#define CBPRGPLL2 UNIPRO_CB_OFFSET(0x00F8) -#define CBPRGTUNING UNIPRO_CB_OFFSET(0x00FB) - -#define UNIPRO_CB_OFFSET(x) (0x8000 | x) - -/* - * PHY Adapter attributes - */ -#define PA_ACTIVETXDATALANES 0x1560 -#define PA_ACTIVERXDATALANES 0x1580 -#define PA_TXTRAILINGCLOCKS 0x1564 -#define PA_PHY_TYPE 0x1500 -#define PA_AVAILTXDATALANES 0x1520 -#define PA_AVAILRXDATALANES 0x1540 -#define PA_MINRXTRAILINGCLOCKS 0x1543 -#define PA_TXPWRSTATUS 0x1567 -#define PA_RXPWRSTATUS 0x1582 -#define PA_TXFORCECLOCK 0x1562 -#define PA_TXPWRMODE 0x1563 -#define PA_LEGACYDPHYESCDL 0x1570 -#define PA_MAXTXSPEEDFAST 0x1521 -#define PA_MAXTXSPEEDSLOW 0x1522 -#define PA_MAXRXSPEEDFAST 0x1541 -#define PA_MAXRXSPEEDSLOW 0x1542 -#define PA_TXLINKSTARTUPHS 0x1544 -#define PA_LOCAL_TX_LCC_ENABLE 0x155E -#define PA_TXSPEEDFAST 0x1565 -#define PA_TXSPEEDSLOW 0x1566 -#define PA_REMOTEVERINFO 0x15A0 -#define PA_TXGEAR 0x1568 -#define PA_TXTERMINATION 0x1569 -#define PA_HSSERIES 0x156A -#define PA_PWRMODE 0x1571 -#define PA_RXGEAR 0x1583 -#define PA_RXTERMINATION 0x1584 -#define PA_MAXRXPWMGEAR 0x1586 -#define PA_MAXRXHSGEAR 0x1587 -#define PA_RXHSUNTERMCAP 0x15A5 -#define PA_RXLSTERMCAP 0x15A6 -#define PA_GRANULARITY 0x15AA -#define PA_PACPREQTIMEOUT 0x1590 -#define PA_PACPREQEOBTIMEOUT 0x1591 -#define PA_HIBERN8TIME 0x15A7 -#define PA_LOCALVERINFO 0x15A9 -#define PA_GRANULARITY 0x15AA -#define PA_TACTIVATE 0x15A8 -#define PA_PACPFRAMECOUNT 0x15C0 -#define PA_PACPERRORCOUNT 0x15C1 -#define PA_PHYTESTCONTROL 0x15C2 -#define PA_PWRMODEUSERDATA0 0x15B0 -#define PA_PWRMODEUSERDATA1 0x15B1 -#define PA_PWRMODEUSERDATA2 0x15B2 -#define PA_PWRMODEUSERDATA3 0x15B3 -#define PA_PWRMODEUSERDATA4 0x15B4 -#define PA_PWRMODEUSERDATA5 0x15B5 -#define PA_PWRMODEUSERDATA6 0x15B6 -#define PA_PWRMODEUSERDATA7 0x15B7 -#define PA_PWRMODEUSERDATA8 0x15B8 -#define PA_PWRMODEUSERDATA9 0x15B9 -#define PA_PWRMODEUSERDATA10 0x15BA -#define PA_PWRMODEUSERDATA11 0x15BB -#define PA_CONNECTEDTXDATALANES 0x1561 -#define PA_CONNECTEDRXDATALANES 0x1581 -#define PA_LOGICALLANEMAP 0x15A1 -#define PA_SLEEPNOCONFIGTIME 0x15A2 -#define PA_STALLNOCONFIGTIME 0x15A3 -#define PA_SAVECONFIGTIME 0x15A4 -#define PA_TXHSADAPTTYPE 0x15D4 - -/* Adpat type for PA_TXHSADAPTTYPE attribute */ -#define PA_REFRESH_ADAPT 0x00 -#define PA_INITIAL_ADAPT 0x01 -#define PA_NO_ADAPT 0x03 - -#define PA_TACTIVATE_TIME_UNIT_US 10 -#define PA_HIBERN8_TIME_UNIT_US 100 - -/*Other attributes*/ -#define VS_MPHYCFGUPDT 0xD085 -#define VS_DEBUGOMC 0xD09E -#define VS_POWERSTATE 0xD083 - -#define PA_GRANULARITY_MIN_VAL 1 -#define PA_GRANULARITY_MAX_VAL 6 - -/* PHY Adapter Protocol Constants */ -#define PA_MAXDATALANES 4 - -#define DL_FC0ProtectionTimeOutVal_Default 8191 -#define DL_TC0ReplayTimeOutVal_Default 65535 -#define DL_AFC0ReqTimeOutVal_Default 32767 -#define DL_FC1ProtectionTimeOutVal_Default 8191 -#define DL_TC1ReplayTimeOutVal_Default 65535 -#define DL_AFC1ReqTimeOutVal_Default 32767 - -#define DME_LocalFC0ProtectionTimeOutVal 0xD041 -#define DME_LocalTC0ReplayTimeOutVal 0xD042 -#define DME_LocalAFC0ReqTimeOutVal 0xD043 - -/* PA power modes */ -enum { - FAST_MODE = 1, - SLOW_MODE = 2, - FASTAUTO_MODE = 4, - SLOWAUTO_MODE = 5, - UNCHANGED = 7, -}; - -#define PWRMODE_MASK 0xF -#define PWRMODE_RX_OFFSET 4 - -/* PA TX/RX Frequency Series */ -enum { - PA_HS_MODE_A = 1, - PA_HS_MODE_B = 2, -}; - -enum ufs_pwm_gear_tag { - UFS_PWM_DONT_CHANGE, /* Don't change Gear */ - UFS_PWM_G1, /* PWM Gear 1 (default for reset) */ - UFS_PWM_G2, /* PWM Gear 2 */ - UFS_PWM_G3, /* PWM Gear 3 */ - UFS_PWM_G4, /* PWM Gear 4 */ - UFS_PWM_G5, /* PWM Gear 5 */ - UFS_PWM_G6, /* PWM Gear 6 */ - UFS_PWM_G7, /* PWM Gear 7 */ -}; - -enum ufs_hs_gear_tag { - UFS_HS_DONT_CHANGE, /* Don't change Gear */ - UFS_HS_G1, /* HS Gear 1 (default for reset) */ - UFS_HS_G2, /* HS Gear 2 */ - UFS_HS_G3, /* HS Gear 3 */ - UFS_HS_G4, /* HS Gear 4 */ -}; - -enum ufs_unipro_ver { - UFS_UNIPRO_VER_RESERVED = 0, - UFS_UNIPRO_VER_1_40 = 1, /* UniPro version 1.40 */ - UFS_UNIPRO_VER_1_41 = 2, /* UniPro version 1.41 */ - UFS_UNIPRO_VER_1_6 = 3, /* UniPro version 1.6 */ - UFS_UNIPRO_VER_1_61 = 4, /* UniPro version 1.61 */ - UFS_UNIPRO_VER_1_8 = 5, /* UniPro version 1.8 */ - UFS_UNIPRO_VER_MAX = 6, /* UniPro unsupported version */ - /* UniPro version field mask in PA_LOCALVERINFO */ - UFS_UNIPRO_VER_MASK = 0xF, -}; - -/* - * Data Link Layer Attributes - */ -#define DL_TC0TXFCTHRESHOLD 0x2040 -#define DL_FC0PROTTIMEOUTVAL 0x2041 -#define DL_TC0REPLAYTIMEOUTVAL 0x2042 -#define DL_AFC0REQTIMEOUTVAL 0x2043 -#define DL_AFC0CREDITTHRESHOLD 0x2044 -#define DL_TC0OUTACKTHRESHOLD 0x2045 -#define DL_TC1TXFCTHRESHOLD 0x2060 -#define DL_FC1PROTTIMEOUTVAL 0x2061 -#define DL_TC1REPLAYTIMEOUTVAL 0x2062 -#define DL_AFC1REQTIMEOUTVAL 0x2063 -#define DL_AFC1CREDITTHRESHOLD 0x2064 -#define DL_TC1OUTACKTHRESHOLD 0x2065 -#define DL_TXPREEMPTIONCAP 0x2000 -#define DL_TC0TXMAXSDUSIZE 0x2001 -#define DL_TC0RXINITCREDITVAL 0x2002 -#define DL_TC0TXBUFFERSIZE 0x2005 -#define DL_PEERTC0PRESENT 0x2046 -#define DL_PEERTC0RXINITCREVAL 0x2047 -#define DL_TC1TXMAXSDUSIZE 0x2003 -#define DL_TC1RXINITCREDITVAL 0x2004 -#define DL_TC1TXBUFFERSIZE 0x2006 -#define DL_PEERTC1PRESENT 0x2066 -#define DL_PEERTC1RXINITCREVAL 0x2067 - -/* - * Network Layer Attributes - */ -#define N_DEVICEID 0x3000 -#define N_DEVICEID_VALID 0x3001 -#define N_TC0TXMAXSDUSIZE 0x3020 -#define N_TC1TXMAXSDUSIZE 0x3021 - -/* - * Transport Layer Attributes - */ -#define T_NUMCPORTS 0x4000 -#define T_NUMTESTFEATURES 0x4001 -#define T_CONNECTIONSTATE 0x4020 -#define T_PEERDEVICEID 0x4021 -#define T_PEERCPORTID 0x4022 -#define T_TRAFFICCLASS 0x4023 -#define T_PROTOCOLID 0x4024 -#define T_CPORTFLAGS 0x4025 -#define T_TXTOKENVALUE 0x4026 -#define T_RXTOKENVALUE 0x4027 -#define T_LOCALBUFFERSPACE 0x4028 -#define T_PEERBUFFERSPACE 0x4029 -#define T_CREDITSTOSEND 0x402A -#define T_CPORTMODE 0x402B -#define T_TC0TXMAXSDUSIZE 0x4060 -#define T_TC1TXMAXSDUSIZE 0x4061 - -/* CPort setting */ -#define E2EFC_ON (1 << 0) -#define E2EFC_OFF (0 << 0) -#define CSD_N_ON (0 << 1) -#define CSD_N_OFF (1 << 1) -#define CSV_N_ON (0 << 2) -#define CSV_N_OFF (1 << 2) -#define CPORT_DEF_FLAGS (CSV_N_OFF | CSD_N_OFF | E2EFC_OFF) - -/* CPort connection state */ -enum { - CPORT_IDLE = 0, - CPORT_CONNECTED, -}; - -#endif /* _UNIPRO_H_ */ diff --git a/drivers/ufs/Kconfig b/drivers/ufs/Kconfig new file mode 100644 index 000000000000..90226f72c158 --- /dev/null +++ b/drivers/ufs/Kconfig @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# UFS subsystem configuration +# + +menuconfig SCSI_UFSHCD + tristate "Universal Flash Storage Controller" + depends on SCSI && SCSI_DMA + select PM_DEVFREQ + select DEVFREQ_GOV_SIMPLE_ONDEMAND + select NLS + help + Enables support for UFS (Universal Flash Storage) host controllers. + A UFS host controller is an electronic component that is able to + communicate with a UFS card. UFS host controllers occur in + smartphones, laptops, digital cameras and also in cars. + The kernel module will be called ufshcd. + + To compile this driver as a module, choose M here and read + <file:Documentation/scsi/ufs.rst>. + However, do not compile this as a module if your root file system + (the one containing the directory /) is located on a UFS device. + +if SCSI_UFSHCD + +source "drivers/ufs/core/Kconfig" + +source "drivers/ufs/host/Kconfig" + +endif diff --git a/drivers/ufs/Makefile b/drivers/ufs/Makefile new file mode 100644 index 000000000000..5a199ef18d4c --- /dev/null +++ b/drivers/ufs/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + +# The link order is important here. ufshcd-core must initialize +# before vendor drivers. +obj-$(CONFIG_SCSI_UFSHCD) += core/ host/ diff --git a/drivers/ufs/core/Kconfig b/drivers/ufs/core/Kconfig new file mode 100644 index 000000000000..e11978171403 --- /dev/null +++ b/drivers/ufs/core/Kconfig @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Kernel configuration file for the UFS Host Controller core. +# +# Copyright (C) 2011-2013 Samsung India Software Operations +# +# Authors: +# Santosh Yaraganavi <santosh.sy@samsung.com> +# Vinayak Holikatti <h.vinayak@samsung.com> + +config SCSI_UFS_BSG + bool "Universal Flash Storage BSG device node" + select BLK_DEV_BSGLIB + help + Universal Flash Storage (UFS) is SCSI transport specification for + accessing flash storage on digital cameras, mobile phones and + consumer electronic devices. + A UFS controller communicates with a UFS device by exchanging + UFS Protocol Information Units (UPIUs). + UPIUs can not only be used as a transport layer for the SCSI protocol + but are also used by the UFS native command set. + This transport driver supports exchanging UFS protocol information units + with a UFS device. See also the ufshcd driver, which is a SCSI driver + that supports UFS devices. + + Select this if you need a bsg device node for your UFS controller. + If unsure, say N. + +config SCSI_UFS_CRYPTO + bool "UFS Crypto Engine Support" + depends on BLK_INLINE_ENCRYPTION + help + Enable Crypto Engine Support in UFS. + Enabling this makes it possible for the kernel to use the crypto + capabilities of the UFS device (if present) to perform crypto + operations on data being transferred to/from the device. + +config SCSI_UFS_HPB + bool "Support UFS Host Performance Booster" + help + The UFS HPB feature improves random read performance. It caches + L2P (logical to physical) map of UFS to host DRAM. The driver uses HPB + read command by piggybacking physical page number for bypassing FTL (flash + translation layer)'s L2P address translation. + +config SCSI_UFS_FAULT_INJECTION + bool "UFS Fault Injection Support" + depends on FAULT_INJECTION + help + Enable fault injection support in the UFS driver. This makes it easier + to test the UFS error handler and abort handler. + +config SCSI_UFS_HWMON + bool "UFS Temperature Notification" + depends on SCSI_UFSHCD=HWMON || HWMON=y + help + This provides support for UFS hardware monitoring. If enabled, + a hardware monitoring device will be created for the UFS device. + + If unsure, say N. diff --git a/drivers/ufs/core/Makefile b/drivers/ufs/core/Makefile new file mode 100644 index 000000000000..62f38c5bf857 --- /dev/null +++ b/drivers/ufs/core/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o +ufshcd-core-y += ufshcd.o ufs-sysfs.o +ufshcd-core-$(CONFIG_DEBUG_FS) += ufs-debugfs.o +ufshcd-core-$(CONFIG_SCSI_UFS_BSG) += ufs_bsg.o +ufshcd-core-$(CONFIG_SCSI_UFS_CRYPTO) += ufshcd-crypto.o +ufshcd-core-$(CONFIG_SCSI_UFS_HPB) += ufshpb.o +ufshcd-core-$(CONFIG_SCSI_UFS_FAULT_INJECTION) += ufs-fault-injection.o +ufshcd-core-$(CONFIG_SCSI_UFS_HWMON) += ufs-hwmon.o diff --git a/drivers/scsi/ufs/ufs-debugfs.c b/drivers/ufs/core/ufs-debugfs.c index c10a8f09682b..e3baed6c70bd 100644 --- a/drivers/scsi/ufs/ufs-debugfs.c +++ b/drivers/ufs/core/ufs-debugfs.c @@ -4,7 +4,7 @@ #include <linux/debugfs.h> #include "ufs-debugfs.h" -#include "ufshcd.h" +#include <ufs/ufshcd.h> #include "ufshcd-priv.h" static struct dentry *ufs_debugfs_root; diff --git a/drivers/scsi/ufs/ufs-debugfs.h b/drivers/ufs/core/ufs-debugfs.h index 97548a3f90eb..97548a3f90eb 100644 --- a/drivers/scsi/ufs/ufs-debugfs.h +++ b/drivers/ufs/core/ufs-debugfs.h diff --git a/drivers/scsi/ufs/ufs-fault-injection.c b/drivers/ufs/core/ufs-fault-injection.c index 7ac7c4e7ff83..7ac7c4e7ff83 100644 --- a/drivers/scsi/ufs/ufs-fault-injection.c +++ b/drivers/ufs/core/ufs-fault-injection.c diff --git a/drivers/scsi/ufs/ufs-fault-injection.h b/drivers/ufs/core/ufs-fault-injection.h index 6d0cd8e10c87..6d0cd8e10c87 100644 --- a/drivers/scsi/ufs/ufs-fault-injection.h +++ b/drivers/ufs/core/ufs-fault-injection.h diff --git a/drivers/scsi/ufs/ufs-hwmon.c b/drivers/ufs/core/ufs-hwmon.c index c38d9d98a86d..4c6a872b7a7c 100644 --- a/drivers/scsi/ufs/ufs-hwmon.c +++ b/drivers/ufs/core/ufs-hwmon.c @@ -7,7 +7,7 @@ #include <linux/hwmon.h> #include <linux/units.h> -#include "ufshcd.h" +#include <ufs/ufshcd.h> #include "ufshcd-priv.h" struct ufs_hwmon_data { diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c index 8a3c6442f291..0a088b47d557 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/ufs/core/ufs-sysfs.c @@ -6,7 +6,7 @@ #include <linux/bitfield.h> #include <asm/unaligned.h> -#include "ufs.h" +#include <ufs/ufs.h> #include "ufs-sysfs.h" #include "ufshcd-priv.h" diff --git a/drivers/scsi/ufs/ufs-sysfs.h b/drivers/ufs/core/ufs-sysfs.h index 8d94af3b8077..8d94af3b8077 100644 --- a/drivers/scsi/ufs/ufs-sysfs.h +++ b/drivers/ufs/core/ufs-sysfs.h diff --git a/drivers/scsi/ufs/ufs_bsg.c b/drivers/ufs/core/ufs_bsg.c index 9e9b93867cab..b99e3f3dc4ef 100644 --- a/drivers/scsi/ufs/ufs_bsg.c +++ b/drivers/ufs/core/ufs_bsg.c @@ -9,7 +9,7 @@ #include <scsi/scsi.h> #include <scsi/scsi_host.h> #include "ufs_bsg.h" -#include "ufshcd.h" +#include <ufs/ufshcd.h> #include "ufshcd-priv.h" static int ufs_bsg_get_query_desc_size(struct ufs_hba *hba, int *desc_len, diff --git a/drivers/scsi/ufs/ufs_bsg.h b/drivers/ufs/core/ufs_bsg.h index 57712d2656d2..57712d2656d2 100644 --- a/drivers/scsi/ufs/ufs_bsg.h +++ b/drivers/ufs/core/ufs_bsg.h diff --git a/drivers/scsi/ufs/ufshcd-crypto.c b/drivers/ufs/core/ufshcd-crypto.c index 67402baf6fae..198360fe5e8e 100644 --- a/drivers/scsi/ufs/ufshcd-crypto.c +++ b/drivers/ufs/core/ufshcd-crypto.c @@ -3,7 +3,7 @@ * Copyright 2019 Google LLC */ -#include "ufshcd.h" +#include <ufs/ufshcd.h> #include "ufshcd-crypto.h" /* Blk-crypto modes supported by UFS crypto */ diff --git a/drivers/scsi/ufs/ufshcd-crypto.h b/drivers/ufs/core/ufshcd-crypto.h index 9f98f18f9646..504cc841540b 100644 --- a/drivers/scsi/ufs/ufshcd-crypto.h +++ b/drivers/ufs/core/ufshcd-crypto.h @@ -7,9 +7,9 @@ #define _UFSHCD_CRYPTO_H #include <scsi/scsi_cmnd.h> -#include "ufshcd.h" +#include <ufs/ufshcd.h> #include "ufshcd-priv.h" -#include "ufshci.h" +#include <ufs/ufshci.h> #ifdef CONFIG_SCSI_UFS_CRYPTO diff --git a/drivers/scsi/ufs/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h index 38bc77d3dbbd..ffb01fc6de75 100644 --- a/drivers/scsi/ufs/ufshcd-priv.h +++ b/drivers/ufs/core/ufshcd-priv.h @@ -4,7 +4,7 @@ #define _UFSHCD_PRIV_H_ #include <linux/pm_runtime.h> -#include "ufshcd.h" +#include <ufs/ufshcd.h> static inline bool ufshcd_is_user_access_allowed(struct ufs_hba *hba) { diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/ufs/core/ufshcd.c index 1fb3a8b9b03e..01fb4bad86be 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -26,8 +26,8 @@ #include <scsi/scsi_driver.h> #include <scsi/scsi_eh.h> #include "ufshcd-priv.h" -#include "ufs_quirks.h" -#include "unipro.h" +#include <ufs/ufs_quirks.h> +#include <ufs/unipro.h> #include "ufs-sysfs.h" #include "ufs-debugfs.h" #include "ufs-fault-injection.h" @@ -8445,10 +8445,7 @@ static int ufshcd_init_hba_vreg(struct ufs_hba *hba) { struct ufs_vreg_info *info = &hba->vreg_info; - if (info) - return ufshcd_get_vreg(hba->dev, info->vdd_hba); - - return 0; + return ufshcd_get_vreg(hba->dev, info->vdd_hba); } static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/ufs/core/ufshpb.c index 002c19c2b31f..de2bb8401bc4 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/ufs/core/ufshpb.c @@ -17,7 +17,7 @@ #include "ufshcd-priv.h" #include "ufshpb.h" -#include "../sd.h" +#include "../../scsi/sd.h" #define ACTIVATION_THRESHOLD 8 /* 8 IOs */ #define READ_TO_MS 1000 diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/ufs/core/ufshpb.h index 0d6e6004d783..0d6e6004d783 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/ufs/core/ufshpb.h diff --git a/drivers/scsi/ufs/Kconfig b/drivers/ufs/host/Kconfig index 393b9a01da36..82590224da13 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/ufs/host/Kconfig @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+ # -# Kernel configuration file for the UFS Host Controller +# Kernel configuration file for the UFS host controller drivers. # # Copyright (C) 2011-2013 Samsung India Software Operations # @@ -8,26 +8,6 @@ # Santosh Yaraganavi <santosh.sy@samsung.com> # Vinayak Holikatti <h.vinayak@samsung.com> -config SCSI_UFSHCD - tristate "Universal Flash Storage Controller Driver Core" - depends on SCSI && SCSI_DMA - select PM_DEVFREQ - select DEVFREQ_GOV_SIMPLE_ONDEMAND - select NLS - help - This selects the support for UFS devices in Linux, say Y and make - sure that you know the name of your UFS host adapter (the card - inside your computer that "speaks" the UFS protocol, also - called UFS Host Controller), because you will be asked for it. - The module will be called ufshcd. - - To compile this driver as a module, choose M here and read - <file:Documentation/scsi/ufs.rst>. - However, do not compile this as a module if your root file system - (the one containing the directory /) is located on a UFS device. - -if SCSI_UFSHCD - config SCSI_UFSHCD_PCI tristate "PCI bus based UFS Controller support" depends on PCI @@ -122,24 +102,6 @@ config SCSI_UFS_TI_J721E Selects this if you have TI platform with UFS controller. If unsure, say N. -config SCSI_UFS_BSG - bool "Universal Flash Storage BSG device node" - select BLK_DEV_BSGLIB - help - Universal Flash Storage (UFS) is SCSI transport specification for - accessing flash storage on digital cameras, mobile phones and - consumer electronic devices. - A UFS controller communicates with a UFS device by exchanging - UFS Protocol Information Units (UPIUs). - UPIUs can not only be used as a transport layer for the SCSI protocol - but are also used by the UFS native command set. - This transport driver supports exchanging UFS protocol information units - with a UFS device. See also the ufshcd driver, which is a SCSI driver - that supports UFS devices. - - Select this if you need a bsg device node for your UFS controller. - If unsure, say N. - config SCSI_UFS_EXYNOS tristate "Exynos specific hooks to UFS controller platform driver" depends on SCSI_UFSHCD_PLATFORM && (ARCH_EXYNOS || COMPILE_TEST) @@ -150,38 +112,3 @@ config SCSI_UFS_EXYNOS Select this if you have UFS host controller on Samsung Exynos SoC. If unsure, say N. - -config SCSI_UFS_CRYPTO - bool "UFS Crypto Engine Support" - depends on BLK_INLINE_ENCRYPTION - help - Enable Crypto Engine Support in UFS. - Enabling this makes it possible for the kernel to use the crypto - capabilities of the UFS device (if present) to perform crypto - operations on data being transferred to/from the device. - -config SCSI_UFS_HPB - bool "Support UFS Host Performance Booster" - help - The UFS HPB feature improves random read performance. It caches - L2P (logical to physical) map of UFS to host DRAM. The driver uses HPB - read command by piggybacking physical page number for bypassing FTL (flash - translation layer)'s L2P address translation. - -config SCSI_UFS_FAULT_INJECTION - bool "UFS Fault Injection Support" - depends on FAULT_INJECTION - help - Enable fault injection support in the UFS driver. This makes it easier - to test the UFS error handler and abort handler. - -config SCSI_UFS_HWMON - bool "UFS Temperature Notification" - depends on SCSI_UFSHCD=HWMON || HWMON=y - help - This provides support for UFS hardware monitoring. If enabled, - a hardware monitoring device will be created for the UFS device. - - If unsure, say N. - -endif diff --git a/drivers/scsi/ufs/Makefile b/drivers/ufs/host/Makefile index 966048875b50..e4be54273c98 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/ufs/host/Makefile @@ -1,16 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -# UFSHCD makefile - -# The link order is important here. ufshcd-core must initialize -# before vendor drivers. -obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o -ufshcd-core-y += ufshcd.o ufs-sysfs.o -ufshcd-core-$(CONFIG_DEBUG_FS) += ufs-debugfs.o -ufshcd-core-$(CONFIG_SCSI_UFS_BSG) += ufs_bsg.o -ufshcd-core-$(CONFIG_SCSI_UFS_CRYPTO) += ufshcd-crypto.o -ufshcd-core-$(CONFIG_SCSI_UFS_HPB) += ufshpb.o -ufshcd-core-$(CONFIG_SCSI_UFS_FAULT_INJECTION) += ufs-fault-injection.o -ufshcd-core-$(CONFIG_SCSI_UFS_HWMON) += ufs-hwmon.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/ufs/host/cdns-pltfrm.c index e05c0ae64eea..e05c0ae64eea 100644 --- a/drivers/scsi/ufs/cdns-pltfrm.c +++ b/drivers/ufs/host/cdns-pltfrm.c diff --git a/drivers/scsi/ufs/tc-dwc-g210-pci.c b/drivers/ufs/host/tc-dwc-g210-pci.c index e635c211c783..92b8ad4b58fe 100644 --- a/drivers/scsi/ufs/tc-dwc-g210-pci.c +++ b/drivers/ufs/host/tc-dwc-g210-pci.c @@ -7,7 +7,7 @@ * Authors: Joao Pinto <jpinto@synopsys.com> */ -#include "ufshcd.h" +#include <ufs/ufshcd.h> #include "ufshcd-dwc.h" #include "tc-dwc-g210.h" diff --git a/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c b/drivers/ufs/host/tc-dwc-g210-pltfrm.c index f15a84d0c176..f15a84d0c176 100644 --- a/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c +++ b/drivers/ufs/host/tc-dwc-g210-pltfrm.c diff --git a/drivers/scsi/ufs/tc-dwc-g210.c b/drivers/ufs/host/tc-dwc-g210.c index 7ef67c9fc5b8..deb93dbd83a4 100644 --- a/drivers/scsi/ufs/tc-dwc-g210.c +++ b/drivers/ufs/host/tc-dwc-g210.c @@ -9,8 +9,8 @@ #include <linux/module.h> -#include "ufshcd.h" -#include "unipro.h" +#include <ufs/ufshcd.h> +#include <ufs/unipro.h> #include "ufshcd-dwc.h" #include "ufshci-dwc.h" diff --git a/drivers/scsi/ufs/tc-dwc-g210.h b/drivers/ufs/host/tc-dwc-g210.h index f7154012f5c7..f7154012f5c7 100644 --- a/drivers/scsi/ufs/tc-dwc-g210.h +++ b/drivers/ufs/host/tc-dwc-g210.h diff --git a/drivers/scsi/ufs/ti-j721e-ufs.c b/drivers/ufs/host/ti-j721e-ufs.c index 122d650d0810..122d650d0810 100644 --- a/drivers/scsi/ufs/ti-j721e-ufs.c +++ b/drivers/ufs/host/ti-j721e-ufs.c diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c index ddb2d42605c5..a81d8cbd542f 100644 --- a/drivers/scsi/ufs/ufs-exynos.c +++ b/drivers/ufs/host/ufs-exynos.c @@ -18,10 +18,10 @@ #include <linux/platform_device.h> #include <linux/regmap.h> -#include "ufshcd.h" +#include <ufs/ufshcd.h> #include "ufshcd-pltfrm.h" -#include "ufshci.h" -#include "unipro.h" +#include <ufs/ufshci.h> +#include <ufs/unipro.h> #include "ufs-exynos.h" diff --git a/drivers/scsi/ufs/ufs-exynos.h b/drivers/ufs/host/ufs-exynos.h index 0b0a3d530ca6..0b0a3d530ca6 100644 --- a/drivers/scsi/ufs/ufs-exynos.h +++ b/drivers/ufs/host/ufs-exynos.h diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/ufs/host/ufs-hisi.c index 7046143063ee..2eed13bc82ca 100644 --- a/drivers/scsi/ufs/ufs-hisi.c +++ b/drivers/ufs/host/ufs-hisi.c @@ -15,12 +15,12 @@ #include <linux/platform_device.h> #include <linux/reset.h> -#include "ufshcd.h" +#include <ufs/ufshcd.h> #include "ufshcd-pltfrm.h" -#include "unipro.h" +#include <ufs/unipro.h> #include "ufs-hisi.h" -#include "ufshci.h" -#include "ufs_quirks.h" +#include <ufs/ufshci.h> +#include <ufs/ufs_quirks.h> static int ufs_hisi_check_hibern8(struct ufs_hba *hba) { diff --git a/drivers/scsi/ufs/ufs-hisi.h b/drivers/ufs/host/ufs-hisi.h index 5a90c0f4e90c..5a90c0f4e90c 100644 --- a/drivers/scsi/ufs/ufs-hisi.h +++ b/drivers/ufs/host/ufs-hisi.h diff --git a/drivers/scsi/ufs/ufs-mediatek-trace.h b/drivers/ufs/host/ufs-mediatek-trace.h index 895e82ea6ece..7e010848dc99 100644 --- a/drivers/scsi/ufs/ufs-mediatek-trace.h +++ b/drivers/ufs/host/ufs-mediatek-trace.h @@ -31,6 +31,6 @@ TRACE_EVENT(ufs_mtk_event, #undef TRACE_INCLUDE_PATH #undef TRACE_INCLUDE_FILE -#define TRACE_INCLUDE_PATH ../../drivers/scsi/ufs/ +#define TRACE_INCLUDE_PATH ../../drivers/ufs/host #define TRACE_INCLUDE_FILE ufs-mediatek-trace #include <trace/define_trace.h> diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c index 083d6bd4d561..beabc3ccd30b 100644 --- a/drivers/scsi/ufs/ufs-mediatek.c +++ b/drivers/ufs/host/ufs-mediatek.c @@ -21,10 +21,10 @@ #include <linux/sched/clock.h> #include <linux/soc/mediatek/mtk_sip_svc.h> -#include "ufshcd.h" +#include <ufs/ufshcd.h> #include "ufshcd-pltfrm.h" -#include "ufs_quirks.h" -#include "unipro.h" +#include <ufs/ufs_quirks.h> +#include <ufs/unipro.h> #include "ufs-mediatek.h" #define CREATE_TRACE_POINTS diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/ufs/host/ufs-mediatek.h index 414dca86c09f..414dca86c09f 100644 --- a/drivers/scsi/ufs/ufs-mediatek.h +++ b/drivers/ufs/host/ufs-mediatek.h diff --git a/drivers/scsi/ufs/ufs-qcom-ice.c b/drivers/ufs/host/ufs-qcom-ice.c index 745e48ec598f..745e48ec598f 100644 --- a/drivers/scsi/ufs/ufs-qcom-ice.c +++ b/drivers/ufs/host/ufs-qcom-ice.c diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 4dcb232facaa..f10d4668814c 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -15,12 +15,12 @@ #include <linux/reset-controller.h> #include <linux/devfreq.h> -#include "ufshcd.h" +#include <ufs/ufshcd.h> #include "ufshcd-pltfrm.h" -#include "unipro.h" +#include <ufs/unipro.h> #include "ufs-qcom.h" -#include "ufshci.h" -#include "ufs_quirks.h" +#include <ufs/ufshci.h> +#include <ufs/ufs_quirks.h> #define UFS_QCOM_DEFAULT_DBG_PRINT_EN \ (UFS_QCOM_DBG_PRINT_REGS_EN | UFS_QCOM_DBG_PRINT_TEST_BUS_EN) diff --git a/drivers/scsi/ufs/ufs-qcom.h b/drivers/ufs/host/ufs-qcom.h index 771bc95d02c7..44466a395bb5 100644 --- a/drivers/scsi/ufs/ufs-qcom.h +++ b/drivers/ufs/host/ufs-qcom.h @@ -7,7 +7,7 @@ #include <linux/reset-controller.h> #include <linux/reset.h> -#include "ufshcd.h" +#include <ufs/ufshcd.h> #define MAX_UFS_QCOM_HOSTS 1 #define MAX_U32 (~(u32)0) diff --git a/drivers/scsi/ufs/ufshcd-dwc.c b/drivers/ufs/host/ufshcd-dwc.c index a57973c8d2a1..e28a67e1e314 100644 --- a/drivers/scsi/ufs/ufshcd-dwc.c +++ b/drivers/ufs/host/ufshcd-dwc.c @@ -9,8 +9,8 @@ #include <linux/module.h> -#include "ufshcd.h" -#include "unipro.h" +#include <ufs/ufshcd.h> +#include <ufs/unipro.h> #include "ufshcd-dwc.h" #include "ufshci-dwc.h" diff --git a/drivers/scsi/ufs/ufshcd-dwc.h b/drivers/ufs/host/ufshcd-dwc.h index 43b70794e24f..ad91ea56662c 100644 --- a/drivers/scsi/ufs/ufshcd-dwc.h +++ b/drivers/ufs/host/ufshcd-dwc.h @@ -10,7 +10,7 @@ #ifndef _UFSHCD_DWC_H #define _UFSHCD_DWC_H -#include "ufshcd.h" +#include <ufs/ufshcd.h> struct ufshcd_dme_attr_val { u32 attr_sel; diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/ufs/host/ufshcd-pci.c index 20af2fbc3af1..04166bda41da 100644 --- a/drivers/scsi/ufs/ufshcd-pci.c +++ b/drivers/ufs/host/ufshcd-pci.c @@ -9,7 +9,7 @@ * Vinayak Holikatti <h.vinayak@samsung.com> */ -#include "ufshcd.h" +#include <ufs/ufshcd.h> #include <linux/delay.h> #include <linux/module.h> #include <linux/pci.h> diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/ufs/host/ufshcd-pltfrm.c index f5313f407617..e7332cc65b1f 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/ufs/host/ufshcd-pltfrm.c @@ -13,9 +13,9 @@ #include <linux/pm_runtime.h> #include <linux/of.h> -#include "ufshcd.h" +#include <ufs/ufshcd.h> #include "ufshcd-pltfrm.h" -#include "unipro.h" +#include <ufs/unipro.h> #define UFSHCD_DEFAULT_LANES_PER_DIRECTION 2 diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.h b/drivers/ufs/host/ufshcd-pltfrm.h index c33e28ac6ef6..43c2e412bd99 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.h +++ b/drivers/ufs/host/ufshcd-pltfrm.h @@ -5,7 +5,7 @@ #ifndef UFSHCD_PLTFRM_H_ #define UFSHCD_PLTFRM_H_ -#include "ufshcd.h" +#include <ufs/ufshcd.h> #define UFS_PWM_MODE 1 #define UFS_HS_MODE 2 diff --git a/drivers/scsi/ufs/ufshci-dwc.h b/drivers/ufs/host/ufshci-dwc.h index 6c290e272106..6c290e272106 100644 --- a/drivers/scsi/ufs/ufshci-dwc.h +++ b/drivers/ufs/host/ufshci-dwc.h |