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:
Linus Torvalds 2022-06-05 09:25:12 -07:00
commit b2c9a83d26
80 changed files with 730 additions and 467 deletions

View File

@ -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>

View File

@ -107,6 +107,8 @@ source "drivers/usb/Kconfig"
source "drivers/mmc/Kconfig"
source "drivers/ufs/Kconfig"
source "drivers/memstick/Kconfig"
source "drivers/leds/Kconfig"

View File

@ -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/

View File

@ -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)
{

View File

@ -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"

View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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 }
};

View File

@ -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)

View File

@ -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

View File

@ -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;
}

View 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;
}

View File

@ -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;

View File

@ -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

View File

@ -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) {

View File

@ -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,

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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)
{

View File

@ -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);

View File

@ -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])
{

View File

@ -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;
}

View File

@ -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 */

View File

@ -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
View 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
View 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
View 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
View 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

View File

@ -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;

View File

@ -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 {

View File

@ -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"

View File

@ -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,

View File

@ -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 */

View File

@ -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

View File

@ -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)
{

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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)
{

View File

@ -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>

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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"

View File

@ -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;

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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"