forked from Minki/linux
SCSI misc on 20220604
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. Signed-off-by: James E.J. Bottomley <jejb@linux.ibm.com> -----BEGIN PGP SIGNATURE----- iJwEABMIAEQWIQTnYEDbdso9F2cI+arnQslM7pishQUCYptvayYcamFtZXMuYm90 dG9tbGV5QGhhbnNlbnBhcnRuZXJzaGlwLmNvbQAKCRDnQslM7pishb1rAPwJWSl1 kB9Qt1xPa1JK0Z7To2LRkrQ4uxYbAnpTLEP6UgEA3YuBccXRppcYQe5CXCrcZryz BtTbtI3ApiV40xC/SRk= =Uit3 -----END PGP SIGNATURE----- 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 ...
This commit is contained in:
commit
b2c9a83d26
10
MAINTAINERS
10
MAINTAINERS
@ -2565,7 +2565,7 @@ F: drivers/pci/controller/dwc/pcie-qcom.c
|
||||
F: drivers/phy/qualcomm/
|
||||
F: drivers/power/*/msm*
|
||||
F: drivers/reset/reset-qcom-*
|
||||
F: drivers/scsi/ufs/ufs-qcom*
|
||||
F: drivers/ufs/host/ufs-qcom*
|
||||
F: drivers/spi/spi-geni-qcom.c
|
||||
F: drivers/spi/spi-qcom-qspi.c
|
||||
F: drivers/spi/spi-qup.c
|
||||
@ -17755,6 +17755,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
|
||||
F: Documentation/devicetree/bindings/scsi/
|
||||
F: drivers/scsi/
|
||||
F: drivers/ufs/
|
||||
F: include/scsi/
|
||||
|
||||
SCSI TAPE DRIVER
|
||||
@ -20414,24 +20415,25 @@ F: include/uapi/linux/cdrom.h
|
||||
UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER
|
||||
R: Alim Akhtar <alim.akhtar@samsung.com>
|
||||
R: Avri Altman <avri.altman@wdc.com>
|
||||
R: Bart Van Assche <bvanassche@acm.org>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/ufs/
|
||||
F: Documentation/scsi/ufs.rst
|
||||
F: drivers/scsi/ufs/
|
||||
F: drivers/ufs/core/
|
||||
|
||||
UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER DWC HOOKS
|
||||
M: Pedro Sousa <pedrom.sousa@synopsys.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/scsi/ufs/*dwc*
|
||||
F: drivers/ufs/host/*dwc*
|
||||
|
||||
UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER MEDIATEK HOOKS
|
||||
M: Stanley Chu <stanley.chu@mediatek.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: drivers/scsi/ufs/ufs-mediatek*
|
||||
F: drivers/ufs/host/ufs-mediatek*
|
||||
|
||||
UNSORTED BLOCK IMAGES (UBI)
|
||||
M: Richard Weinberger <richard@nod.at>
|
||||
|
@ -107,6 +107,8 @@ source "drivers/usb/Kconfig"
|
||||
|
||||
source "drivers/mmc/Kconfig"
|
||||
|
||||
source "drivers/ufs/Kconfig"
|
||||
|
||||
source "drivers/memstick/Kconfig"
|
||||
|
||||
source "drivers/leds/Kconfig"
|
||||
|
@ -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/
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -2414,6 +2414,90 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
|
||||
return(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
@ -5270,254 +5262,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
|
||||
@ -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;
|
||||
}
|
||||
|
288
drivers/scsi/lpfc/lpfc_vmid.c
Normal file
288
drivers/scsi/lpfc/lpfc_vmid.c
Normal file
@ -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;
|
||||
}
|
@ -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;
|
||||
|
@ -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");
|
||||
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;
|
||||
|
||||
dev_set_name(bsg_dev, "mpi3mrctl%u", mrioc->id);
|
||||
|
||||
if (device_add(bsg_dev)) {
|
||||
ioc_err(mrioc, "%s: bsg device add failed\n",
|
||||
dev_name(bsg_dev));
|
||||
put_device(bsg_dev);
|
||||
return;
|
||||
}
|
||||
|
||||
device_initialize(mrioc->bsg_dev);
|
||||
dev_set_name(mrioc->bsg_dev, "mpi3mrctl%u", mrioc->id);
|
||||
|
||||
if (device_add(mrioc->bsg_dev)) {
|
||||
ioc_err(mrioc, "%s: bsg device add failed\n",
|
||||
dev_name(mrioc->bsg_dev));
|
||||
goto err_device_add;
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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])
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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.
|
||||
|
30
drivers/ufs/Kconfig
Normal file
30
drivers/ufs/Kconfig
Normal file
@ -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
|
5
drivers/ufs/Makefile
Normal file
5
drivers/ufs/Makefile
Normal file
@ -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/
|
60
drivers/ufs/core/Kconfig
Normal file
60
drivers/ufs/core/Kconfig
Normal file
@ -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.
|
10
drivers/ufs/core/Makefile
Normal file
10
drivers/ufs/core/Makefile
Normal file
@ -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
|
@ -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;
|
@ -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 {
|
@ -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"
|
||||
|
@ -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,
|
@ -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 */
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
@ -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)
|
@ -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
|
@ -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
|
@ -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
|
@ -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"
|
||||
|
@ -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"
|
@ -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"
|
||||
|
@ -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)
|
||||
{
|
@ -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>
|
@ -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
|
@ -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)
|
@ -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)
|
@ -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"
|
@ -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;
|
@ -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>
|
@ -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
|
||||
|
@ -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
|
@ -564,6 +564,15 @@ int nvme_fc_rcv_ls_req(struct nvme_fc_remote_port *remoteport,
|
||||
void *lsreqbuf, u32 lsreqbuf_len);
|
||||
|
||||
|
||||
/*
|
||||
* Routine called to get the appid field associated with request by the lldd
|
||||
*
|
||||
* If the return value is NULL : the user/libvirt has not set the appid to VM
|
||||
* If the return value is non-zero: Returns the appid associated with VM
|
||||
*
|
||||
* @req: IO request from nvme fc to driver
|
||||
*/
|
||||
char *nvme_fc_io_getuuid(struct nvmefc_fcp_req *req);
|
||||
|
||||
/*
|
||||
* *************** LLDD FC-NVME Target/Subsystem API ***************
|
||||
@ -1048,5 +1057,10 @@ int nvmet_fc_rcv_fcp_req(struct nvmet_fc_target_port *tgtport,
|
||||
|
||||
void nvmet_fc_rcv_fcp_abort(struct nvmet_fc_target_port *tgtport,
|
||||
struct nvmefc_tgt_fcp_req *fcpreq);
|
||||
/*
|
||||
* add a define, visible to the compiler, that indicates support
|
||||
* for feature. Allows for conditional compilation in LLDDs.
|
||||
*/
|
||||
#define NVME_FC_FEAT_UUID 0x0001
|
||||
|
||||
#endif /* _NVME_FC_DRIVER_H */
|
||||
|
@ -18,10 +18,10 @@
|
||||
#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"
|
||||
#include <ufs/unipro.h>
|
||||
#include <ufs/ufs.h>
|
||||
#include <ufs/ufs_quirks.h>
|
||||
#include <ufs/ufshci.h>
|
||||
|
||||
#define UFSHCD "ufshcd"
|
||||
|
Loading…
Reference in New Issue
Block a user