[PATCH] scsi: mpt3sas: fix a missing-check bug

2018-05-04 Thread Wenwen Wang
In _ctl_ioctl_main(), 'ioctl_header' is first copied from the userspace
pointer 'arg'. 'ioctl_header.ioc_number' is then verified by
_ctl_verify_adapter(). If the verification is failed, an error code -ENODEV
is returned. Otherwise, the verification result, i.e., the MPT3SAS adapter
that matches with the 'ioctl_header.ioc_number', is saved to 'ioc'. Later
on, if the 'cmd' is MPT3COMMAND, the whole ioctl command struct is copied
again from the userspace pointer 'arg' and saved to 'karg'. Then the
function _ctl_do_mpt_command() is invoked to execute the command with the
adapter 'ioc' and 'karg' as inputs.

Given that the pointer 'arg' resides in userspace, a malicious userspace
process can race to change the 'ioc_number' between the two copies, which
will cause inconsistency issues, potentially security issues since an
inconsistent adapter could be used with the command struct 'karg' as inputs
of _ctl_do_mpt_command(). Moreover, the user can potentially provide a
valid 'ioc_number' to pass the verification, and then modify it to an
invalid 'ioc_number'. That means, an invalid 'ioc_number' can potentially
bypass the verification check.

To fix this issue, we need to recheck the 'ioc_number' copied after the
second copy to make sure it is not changed since the first copy.

Signed-off-by: Wenwen Wang 
---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c 
b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index d3cb387..0c140c7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -2388,6 +2388,11 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, 
void __user *arg,
break;
}
 
+   if (karg.hdr.ioc_number != ioctl_header.ioc_number) {
+   ret = -EINVAL;
+   break;
+   }
+
if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_command)) {
uarg = arg;
ret = _ctl_do_mpt_command(ioc, karg, &uarg->mf);
-- 
2.7.4



[PATCH 01/10] lpfc: Change IO submit return to EBUSY if remote port is recovering

2018-05-04 Thread James Smart
I/O submission paths in the lpfc nvme path are rejecting the io with an
error code that reflects back to the callee as a hard io failure. Many
of these conditions are transient and would likely resolve if retried.

Correct by returning -EBUSY, which the FC transport triggers off of to
return busy status codes to the blk-mq layer.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_nvme.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 9e0345697e1b..2d80c7207869 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -1452,8 +1452,8 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port 
*pnvme_lport,
 
if (unlikely(!hw_queue_handle)) {
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_ABTS,
-"6129 Fail Abort, NULL hw_queue_handle\n");
-   ret = -EINVAL;
+"6117 Fail Abort, NULL hw_queue_handle\n");
+   ret = -EBUSY;
goto out_fail;
}
 
@@ -1499,7 +1499,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port 
*pnvme_lport,
 "6066 Missing node for DID %x\n",
 pnvme_rport->port_id);
atomic_inc(&lport->xmt_fcp_bad_ndlp);
-   ret = -ENODEV;
+   ret = -EBUSY;
goto out_fail;
}
}
@@ -1509,11 +1509,12 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port 
*pnvme_lport,
(ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR,
 "6036 rport %p, DID x%06x not ready for "
-"IO. State x%x, Type x%x\n",
+"IO. State x%x, Type x%x Flg x%x\n",
 rport, pnvme_rport->port_id,
-ndlp->nlp_state, ndlp->nlp_type);
+ndlp->nlp_state, ndlp->nlp_type,
+ndlp->upcall_flags);
atomic_inc(&lport->xmt_fcp_bad_ndlp);
-   ret = -ENODEV;
+   ret = -EBUSY;
goto out_fail;
 
}
-- 
2.13.1



[PATCH 04/10] lpfc: Handle new link fault code returned by adapter firmware.

2018-05-04 Thread James Smart
The driver encounters a link event ACQE with a fault code it doesn't
recognize, it logs an "Invalid" fault type and futher treats the
unknown value as a mailbox command failure.  First off, there is
no "invalid" value, only values that are unknown. Secondly, the
fault code doesn't indicate status - the rest of the ACQE contains
that status so there is no reason to "fail the commands".

Change the "Invalid" to "Unknown". There is no "invalid" code value.

Separate fault code parsing and message genaration from any mbx
handling status.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_hw4.h  |  1 +
 drivers/scsi/lpfc/lpfc_init.c | 31 ++-
 2 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 571099fbde28..eed8dea42f74 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -3924,6 +3924,7 @@ struct lpfc_acqe_link {
 #define LPFC_ASYNC_LINK_FAULT_NONE 0x0
 #define LPFC_ASYNC_LINK_FAULT_LOCAL0x1
 #define LPFC_ASYNC_LINK_FAULT_REMOTE   0x2
+#define LPFC_ASYNC_LINK_FAULT_LR_LRR   0x3
 #define lpfc_acqe_logical_link_speed_SHIFT 16
 #define lpfc_acqe_logical_link_speed_MASK  0x
 #define lpfc_acqe_logical_link_speed_WORD  word1
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 70583e1b227d..0ba49e605a61 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -4279,32 +4279,24 @@ lpfc_sli4_fcf_redisc_wait_tmo(struct timer_list *t)
  * @phba: pointer to lpfc hba data structure.
  * @acqe_link: pointer to the async link completion queue entry.
  *
- * This routine is to parse the SLI4 link-attention link fault code and
- * translate it into the base driver's read link attention mailbox command
- * status.
- *
- * Return: Link-attention status in terms of base driver's coding.
+ * This routine is to parse the SLI4 link-attention link fault code.
  **/
-static uint16_t
+static void
 lpfc_sli4_parse_latt_fault(struct lpfc_hba *phba,
   struct lpfc_acqe_link *acqe_link)
 {
-   uint16_t latt_fault;
-
switch (bf_get(lpfc_acqe_link_fault, acqe_link)) {
case LPFC_ASYNC_LINK_FAULT_NONE:
case LPFC_ASYNC_LINK_FAULT_LOCAL:
case LPFC_ASYNC_LINK_FAULT_REMOTE:
-   latt_fault = 0;
+   case LPFC_ASYNC_LINK_FAULT_LR_LRR:
break;
default:
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-   "0398 Invalid link fault code: x%x\n",
+   "0398 Unknown link fault code: x%x\n",
bf_get(lpfc_acqe_link_fault, acqe_link));
-   latt_fault = MBXERR_ERROR;
break;
}
-   return latt_fault;
 }
 
 /**
@@ -4579,9 +4571,12 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
 * the READ_TOPOLOGY completion routine to continue without actually
 * sending the READ_TOPOLOGY mailbox command to the port.
 */
-   /* Parse and translate status field */
+   /* Initialize completion status */
mb = &pmb->u.mb;
-   mb->mbxStatus = lpfc_sli4_parse_latt_fault(phba, acqe_link);
+   mb->mbxStatus = MBX_SUCCESS;
+
+   /* Parse port fault information field */
+   lpfc_sli4_parse_latt_fault(phba, acqe_link);
 
/* Parse and translate link attention fields */
la = (struct lpfc_mbx_read_top *) &pmb->u.mb.un.varReadTop;
@@ -4709,10 +4704,12 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct 
lpfc_acqe_fc_la *acqe_fc)
break;
}
 
-   /* Parse and translate status field */
+   /* Initialize completion status */
mb = &pmb->u.mb;
-   mb->mbxStatus = lpfc_sli4_parse_latt_fault(phba,
-  (void *)acqe_fc);
+   mb->mbxStatus = MBX_SUCCESS;
+
+   /* Parse port fault information field */
+   lpfc_sli4_parse_latt_fault(phba, (void *)acqe_fc);
 
/* Parse and translate link attention fields */
la = (struct lpfc_mbx_read_top *)&pmb->u.mb.un.varReadTop;
-- 
2.13.1



[PATCH 06/10] lpfc: Check if SCSI scanning is complete, before allowing I/O commands

2018-05-04 Thread James Smart
A race condition is being seen. I/O is being issued to scsi targets
simultaneous to a short connectivity loss. The rport block/unblock is
occurring, but the unblock is allowing pending I/O commands to intermix
with the commands being used to scan the scsi bus. Thus the target
device is getting a read or write prior to transitioning to an ready
state, thus the device errors the io. The io error propagatest all the
way back to the application.

Resolve by augmenting the io submission with a check to see whether
transport is scanning the remote port or not. If not, then the io is
failed such that it will be retried. If so, then normal processing resumes.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_scsi.c | 48 +++
 drivers/scsi/lpfc/lpfc_scsi.h | 15 ++
 2 files changed, 63 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 7932bf30c8d7..303f1ad0c27f 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -4506,6 +4506,43 @@ void lpfc_poll_timeout(struct timer_list *t)
 }
 
 /**
+ * lpfc_is_scan_cmd - check command code within opcode for scanning related cmd
+ * @opcode: opcode of scsi_cmnd data structure.
+ *
+ * scsi midlayer may submit I/O commands before scanning is complete caused by
+ * lip in transport layer.
+ * This routine checks if the scsi cmd is related to scanning following FCP-4
+ * discovery procedure.
+ *
+ * Return value :
+ *   0 - Not a scanning related command
+ *   1 - Is a scanning related command
+ **/
+static int
+lpfc_is_scan_cmd(uint8_t opcode)
+{
+   switch (opcode & 0x1f) {
+   case LPFC_INQUIRY_CMD_CODE:
+   case LPFC_LOG_SELECT_CMD_CODE:
+   case LPFC_LOG_SENSE_CMD_CODE:
+   case LPFC_MODE_SELECT_CMD_CODE:
+   case LPFC_MODE_SENSE_CMD_CODE:
+   case LPFC_REPORT_LUNS_CMD_CODE:
+   case LPFC_SEND_DIAGNOSTIC_CMD_CODE:
+   case LPFC_MAINTENANCE_IN_CMD_CODE:
+   case LPFC_MAINTENANCE_OUT_CMD_CODE:
+   case LPFC_PERSISTENT_RESERVE_IN_CMD_CODE:
+   case LPFC_PERSISTENT_RESERVE_OUT_CMD_CODE:
+   case LPFC_READ_BUFFER_CMD_CODE:
+   case LPFC_WRITE_BUFFER_CMD_CODE:
+   break;
+   default:
+   return 0;
+   }
+   return 1;
+}
+
+/**
  * lpfc_queuecommand - scsi_host_template queuecommand entry point
  * @cmnd: Pointer to scsi_cmnd data structure.
  * @done: Pointer to done routine.
@@ -4537,6 +4574,17 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct 
scsi_cmnd *cmnd)
}
ndlp = rdata->pnode;
 
+   if ((rport->flags & FC_RPORT_SCAN_PENDING) &&
+   !(lpfc_is_scan_cmd(cmnd->cmnd[0]))) {
+   lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
+"6423 scan still pending, "
+"command = 0x%02x to be "
+"retried\n",
+cmnd->cmnd[0]);
+   cmnd->result = DID_IMM_RETRY << 16;
+   goto out_fail_command;
+   }
+
if ((scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) &&
(!(phba->sli3_options & LPFC_SLI3_BG_ENABLED))) {
 
diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h
index 8e38e0204c47..68c8a24c659c 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.h
+++ b/drivers/scsi/lpfc/lpfc_scsi.h
@@ -194,5 +194,20 @@ struct lpfc_scsi_buf {
 
 #define TXRDY_PAYLOAD_LEN  12
 
+/* Safe command codes for scanning, excluding group code */
+#define LPFC_INQUIRY_CMD_CODE  (INQUIRY & 0x1f)
+#define LPFC_LOG_SELECT_CMD_CODE   (LOG_SELECT & 0x1f)
+#define LPFC_LOG_SENSE_CMD_CODE(LOG_SENSE & 0x1f)
+#define LPFC_MODE_SELECT_CMD_CODE  (MODE_SELECT & 0x1f)
+#define LPFC_MODE_SENSE_CMD_CODE   (MODE_SENSE & 0x1f)
+#define LPFC_REPORT_LUNS_CMD_CODE  (REPORT_LUNS & 0x1f)
+#define LPFC_SEND_DIAGNOSTIC_CMD_CODE  (SEND_DIAGNOSTIC & 0x1f)
+#define LPFC_MAINTENANCE_IN_CMD_CODE   (MAINTENANCE_IN & 0x1f)
+#define LPFC_MAINTENANCE_OUT_CMD_CODE  (MAINTENANCE_OUT & 0x1f)
+#define LPFC_PERSISTENT_RESERVE_IN_CMD_CODE(PERSISTENT_RESERVE_IN & 0x1f)
+#define LPFC_PERSISTENT_RESERVE_OUT_CMD_CODE   (PERSISTENT_RESERVE_OUT & 0x1f)
+#define LPFC_READ_BUFFER_CMD_CODE  (READ_BUFFER & 0x1f)
+#define LPFC_WRITE_BUFFER_CMD_CODE (WRITE_BUFFER & 0x1f)
+
 int lpfc_sli4_scmd_to_wqidx_distr(struct lpfc_hba *phba,
  struct lpfc_scsi_buf *lpfc_cmd);
-- 
2.13.1



[PATCH 08/10] lpfc: Enhance log messages when reporting CQE errors

2018-05-04 Thread James Smart
Enhance log messages for CQEs as they were not reporting certain fields.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_sli.c | 23 ---
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 30480e47913f..48ba9eb8a96b 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -12972,6 +12972,17 @@ lpfc_sli4_sp_handle_els_wcqe(struct lpfc_hba *phba, 
struct lpfc_queue *cq,
int txcmplq_cnt = 0;
int fcp_txcmplq_cnt = 0;
 
+   /* Check for response status */
+   if (unlikely(bf_get(lpfc_wcqe_c_status, wcqe))) {
+   /* Log the error status */
+   lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+   "0357 ELS CQE error: status=x%x: "
+   "CQE: %08x %08x %08x %08x\n",
+   bf_get(lpfc_wcqe_c_status, wcqe),
+   wcqe->word0, wcqe->total_data_placed,
+   wcqe->parameter, wcqe->word3);
+   }
+
/* Get an irspiocbq for later ELS response processing use */
irspiocbq = lpfc_sli_get_iocbq(phba);
if (!irspiocbq) {
@@ -13392,14 +13403,12 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba, 
struct lpfc_queue *cq,
phba->lpfc_rampdown_queue_depth(phba);
 
/* Log the error status */
-   lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
-   "0373 FCP complete error: status=x%x, "
-   "hw_status=x%x, total_data_specified=%d, "
-   "parameter=x%x, word3=x%x\n",
+   lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+   "0373 FCP CQE error: status=x%x: "
+   "CQE: %08x %08x %08x %08x\n",
bf_get(lpfc_wcqe_c_status, wcqe),
-   bf_get(lpfc_wcqe_c_hw_status, wcqe),
-   wcqe->total_data_placed, wcqe->parameter,
-   wcqe->word3);
+   wcqe->word0, wcqe->total_data_placed,
+   wcqe->parameter, wcqe->word3);
}
 
/* Look up the FCP command IOCB and create pseudo response IOCB */
-- 
2.13.1



[PATCH 09/10] lpfc: update driver version to 12.0.0.3

2018-05-04 Thread James Smart
Update the driver version to 12.0.0.3

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_version.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 0cd474bb0bdd..666ffa179653 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -20,7 +20,7 @@
  * included with this package. *
  ***/
 
-#define LPFC_DRIVER_VERSION "12.0.0.2"
+#define LPFC_DRIVER_VERSION "12.0.0.3"
 #define LPFC_DRIVER_NAME   "lpfc"
 
 /* Used for SLI 2/3 */
-- 
2.13.1



[PATCH 05/10] lpfc: Driver NVME load fails when CPU cnt > WQ resource cnt

2018-05-04 Thread James Smart
If the cpu count is larger than the number of WQ resources available,
adapter attachment eventually failes due to a WQ_CREATE failure.

Calculate the number of WQs desired (which initializes to cpu count)
after accounting for the number of queues the adapter supports and
the number allocated to SCSI and the control/ELS path, and scale down
if necessary.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_init.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 0ba49e605a61..119432035e9e 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -7790,6 +7790,40 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
phba->sli4_hba.max_cfg_param.max_wq,
phba->sli4_hba.max_cfg_param.max_rq);
 
+   /*
+* Calculate NVME queue resources based on how
+* many WQ/CQs are available.
+*/
+   if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
+   length = phba->sli4_hba.max_cfg_param.max_wq;
+   if (phba->sli4_hba.max_cfg_param.max_cq <
+   phba->sli4_hba.max_cfg_param.max_wq)
+   length = phba->sli4_hba.max_cfg_param.max_cq;
+
+   /*
+* Whats left after this can go toward NVME.
+* The minus 6 accounts for ELS, NVME LS, MBOX
+* fof plus a couple extra. When configured for
+* NVMET, FCP io channel WQs are not created.
+*/
+   length -= 6;
+   if (!phba->nvmet_support)
+   length -= phba->cfg_fcp_io_channel;
+
+   if (phba->cfg_nvme_io_channel > length) {
+   lpfc_printf_log(
+   phba, KERN_ERR, LOG_SLI,
+   "2005 Reducing NVME IO channel to %d: "
+   "WQ %d CQ %d NVMEIO %d FCPIO %d\n",
+   length,
+   phba->sli4_hba.max_cfg_param.max_wq,
+   phba->sli4_hba.max_cfg_param.max_cq,
+   phba->cfg_nvme_io_channel,
+   phba->cfg_fcp_io_channel);
+
+   phba->cfg_nvme_io_channel = length;
+   }
+   }
}
 
if (rc)
-- 
2.13.1



[PATCH 10/10] lpfc: Comment cleanup regarding Broadcom copyright header

2018-05-04 Thread James Smart
Fix small formatting and wording nits in Broadcom copyright header

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_attr.c| 2 +-
 drivers/scsi/lpfc/lpfc_debugfs.c | 2 +-
 drivers/scsi/lpfc/lpfc_hw4.h | 2 +-
 drivers/scsi/lpfc/lpfc_init.c| 2 +-
 drivers/scsi/lpfc/lpfc_nvme.c| 2 +-
 drivers/scsi/lpfc/lpfc_nvme.h| 2 +-
 drivers/scsi/lpfc/lpfc_scsi.c| 2 +-
 drivers/scsi/lpfc/lpfc_scsi.h| 2 +-
 drivers/scsi/lpfc/lpfc_sli.c | 2 +-
 drivers/scsi/lpfc/lpfc_version.h | 2 +-
 10 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index e79724564b2e..a66c4fbc7690 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -2,7 +2,7 @@
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
  * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
- * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
+ * “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*
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index ccc342247782..9df0c051349f 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -2,7 +2,7 @@
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
  * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
- * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.  *
  * Copyright (C) 2007-2015 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
  * www.broadcom.com*
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index eed8dea42f74..807901af9bbe 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -2,7 +2,7 @@
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
  * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
- * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.  *
  * Copyright (C) 2009-2016 Emulex.  All rights reserved.   *
  * EMULEX and SLI are trademarks of Emulex.*
  * www.broadcom.com*
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 119432035e9e..3d89b08896d1 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2,7 +2,7 @@
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
  * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
- * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
+ * “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*
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 9fba34d5d5e1..f5f90d19b215 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -2,7 +2,7 @@
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
  * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
- * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
+ * “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*
diff --git a/drivers/scsi/lpfc/lpfc_nvme.h b/drivers/scsi/lpfc/lpfc_nvme.h
index 129189324c31..04bd463dd043 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.h
+++ b/drivers/scsi/lpfc/lpfc_nvme.h
@@ -2,7 +2,7 @@
  * This file is part of the Emulex Linux Device Driver for *
  * Fibre Channel Host Bus Adapters.*
  * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
- * “Broadcom” refers to Broadcom Limited and/or its subsidiaries.  *
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.  *
  * Copyright (C) 2004-2016 Emulex.  All rights 

[PATCH 07/10] lpfc: Fix up log messages and stats counters in IO submit code path

2018-05-04 Thread James Smart
Fix up log messages and add an fcp error stat counter in the IO
submit code path to make diagnosing problems easier

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_attr.c|  3 ++-
 drivers/scsi/lpfc/lpfc_debugfs.c |  3 ++-
 drivers/scsi/lpfc/lpfc_nvme.c| 53 
 drivers/scsi/lpfc/lpfc_nvme.h|  1 +
 4 files changed, 37 insertions(+), 23 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index fd3b25317887..e79724564b2e 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -405,11 +405,12 @@ lpfc_nvme_info_show(struct device *dev, struct 
device_attribute *attr,
 
len += snprintf(buf+len, PAGE_SIZE-len,
"  abort %08x noxri %08x nondlp %08x qdepth %08x "
-   "wqerr %08x\n",
+   "wqerr %08x err %08x\n",
atomic_read(&lport->xmt_fcp_abort),
atomic_read(&lport->xmt_fcp_noxri),
atomic_read(&lport->xmt_fcp_bad_ndlp),
atomic_read(&lport->xmt_fcp_qdepth),
+   atomic_read(&lport->xmt_fcp_err),
atomic_read(&lport->xmt_fcp_wqerr));
 
len += snprintf(buf + len, PAGE_SIZE - len,
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index afe7883c988a..ccc342247782 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -959,11 +959,12 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char 
*buf, int size)
 
len += snprintf(buf + len, size - len,
"FCP Xmt Err: noxri %06x nondlp %06x "
-   "qdepth %06x wqerr %06x Abrt %06x\n",
+   "qdepth %06x wqerr %06x err %06x Abrt %06x\n",
atomic_read(&lport->xmt_fcp_noxri),
atomic_read(&lport->xmt_fcp_bad_ndlp),
atomic_read(&lport->xmt_fcp_qdepth),
atomic_read(&lport->xmt_fcp_wqerr),
+   atomic_read(&lport->xmt_fcp_err),
atomic_read(&lport->xmt_fcp_abort));
 
len += snprintf(buf + len, size - len,
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 2d80c7207869..9fba34d5d5e1 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -1451,8 +1451,9 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port 
*pnvme_lport,
vport = lport->vport;
 
if (unlikely(!hw_queue_handle)) {
-   lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_ABTS,
-"6117 Fail Abort, NULL hw_queue_handle\n");
+   lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR,
+"6117 Fail IO, NULL hw_queue_handle\n");
+   atomic_inc(&lport->xmt_fcp_err);
ret = -EBUSY;
goto out_fail;
}
@@ -1465,12 +1466,18 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port 
*pnvme_lport,
}
 
if (vport->load_flag & FC_UNLOADING) {
+   lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR,
+"6124 Fail IO, Driver unload\n");
+   atomic_inc(&lport->xmt_fcp_err);
ret = -ENODEV;
goto out_fail;
}
 
freqpriv = pnvme_fcreq->private;
if (unlikely(!freqpriv)) {
+   lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_IOERR,
+"6158 Fail IO, NULL request data\n");
+   atomic_inc(&lport->xmt_fcp_err);
ret = -EINVAL;
goto out_fail;
}
@@ -1488,29 +1495,22 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port 
*pnvme_lport,
 */
ndlp = rport->ndlp;
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
-   lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR,
-"6053 rport %p, ndlp %p, DID x%06x "
-"ndlp not ready.\n",
+   lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE | LOG_NVME_IOERR,
+"6053 Fail IO, ndlp not ready: rport %p "
+ "ndlp %p, DID x%06x\n",
 rport, ndlp, pnvme_rport->port_id);
-
-   ndlp = lpfc_findnode_did(vport, pnvme_rport->port_id);
-   if (!ndlp) {
-   lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_IOERR,
-"6066 Missing node for DID %x\n",
-pnvme_rport->port_id);
-   atomic_inc(&lport->xmt_fcp_bad_ndlp);
-   ret = -EBUSY;
-   goto out_fail;

[PATCH 00/10] lpfc updates for 12.0.0.3

2018-05-04 Thread James Smart
This patch contains lpfc bug fixes and a few message updates and
cleanups.

The patches were cut against the Martin's 4.17/scsi-queue tree


James Smart (10):
  lpfc: Change IO submit return to EBUSY if remote port is recovering
  lpfc: enhance LE data structure copies to hardware
  lpfc: Correct fw download error message
  lpfc: Handle new link fault code returned by adapter firmware.
  lpfc: Driver NVME load fails when CPU cnt > WQ resource cnt
  lpfc: Check if SCSI scanning is complete, before allowing I/O commands
  lpfc: Fix up log messages and stats counters in IO submit code path
  lpfc: Enhance log messages when reporting CQE errors
  lpfc: update driver version to 12.0.0.3
  lpfc: Comment cleanup regarding Broadcom copyright header

 drivers/scsi/lpfc/lpfc_attr.c|  5 ++-
 drivers/scsi/lpfc/lpfc_debugfs.c |  5 ++-
 drivers/scsi/lpfc/lpfc_hw4.h |  6 ++-
 drivers/scsi/lpfc/lpfc_init.c| 73 ++--
 drivers/scsi/lpfc/lpfc_nvme.c| 64 ++-
 drivers/scsi/lpfc/lpfc_nvme.h|  3 +-
 drivers/scsi/lpfc/lpfc_scsi.c| 50 -
 drivers/scsi/lpfc/lpfc_scsi.h| 17 -
 drivers/scsi/lpfc/lpfc_sli.c | 81 +---
 drivers/scsi/lpfc/lpfc_version.h |  4 +-
 10 files changed, 231 insertions(+), 77 deletions(-)

-- 
2.13.1



[PATCH 02/10] lpfc: enhance LE data structure copies to hardware

2018-05-04 Thread James Smart
The driver builds the control structures in host memory using
definitions that are based on 32-bit words. After building the
structure it is then written to the adapter.

This patch slightly optimizes LE hosts by copying the structures
via 64-bit copies.  This is doable as the adapter interface is LE
thus there is no byteswapping as the copy is performed.

The same optimization would be nice on BE systems, but when
byteswapping occurs, it swaps 32-bit words as well, thus trashing
the control structure. Given amount of code that is dependent
upon the 32-bit word definition, it was decided to not change
things for the minor optimization. Thus PPC 64-bit systems sticks
with doing 32-bit copies.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_sli.c | 56 +---
 1 file changed, 42 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 38993efbe37e..30480e47913f 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -96,6 +96,34 @@ lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq)
return &iocbq->iocb;
 }
 
+#if defined(CONFIG_64BIT) && defined(__LITTLE_ENDIAN)
+/**
+ * lpfc_sli4_pcimem_bcopy - SLI4 memory copy function
+ * @srcp: Source memory pointer.
+ * @destp: Destination memory pointer.
+ * @cnt: Number of words required to be copied.
+ *   Must be a multiple of sizeof(uint64_t)
+ *
+ * This function is used for copying data between driver memory
+ * and the SLI WQ. This function also changes the endianness
+ * of each word if native endianness is different from SLI
+ * endianness. This function can be called with or without
+ * lock.
+ **/
+void
+lpfc_sli4_pcimem_bcopy(void *srcp, void *destp, uint32_t cnt)
+{
+   uint64_t *src = srcp;
+   uint64_t *dest = destp;
+   int i;
+
+   for (i = 0; i < (int)cnt; i += sizeof(uint64_t))
+   *dest++ = *src++;
+}
+#else
+#define lpfc_sli4_pcimem_bcopy(a, b, c) lpfc_sli_pcimem_bcopy(a, b, c)
+#endif
+
 /**
  * lpfc_sli4_wq_put - Put a Work Queue Entry on an Work Queue
  * @q: The Work Queue to operate on.
@@ -137,7 +165,7 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe128 
*wqe)
bf_set(wqe_wqec, &wqe->generic.wqe_com, 0);
if (q->phba->sli3_options & LPFC_SLI4_PHWQ_ENABLED)
bf_set(wqe_wqid, &wqe->generic.wqe_com, q->queue_id);
-   lpfc_sli_pcimem_bcopy(wqe, temp_wqe, q->entry_size);
+   lpfc_sli4_pcimem_bcopy(wqe, temp_wqe, q->entry_size);
if (q->dpp_enable && q->phba->cfg_enable_dpp) {
/* write to DPP aperture taking advatage of Combined Writes */
tmp = (uint8_t *)temp_wqe;
@@ -240,7 +268,7 @@ lpfc_sli4_mq_put(struct lpfc_queue *q, struct lpfc_mqe *mqe)
/* If the host has not yet processed the next entry then we are done */
if (((q->host_index + 1) % q->entry_count) == q->hba_index)
return -ENOMEM;
-   lpfc_sli_pcimem_bcopy(mqe, temp_mqe, q->entry_size);
+   lpfc_sli4_pcimem_bcopy(mqe, temp_mqe, q->entry_size);
/* Save off the mailbox pointer for completion */
q->phba->mbox = (MAILBOX_t *)temp_mqe;
 
@@ -663,8 +691,8 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue 
*dq,
/* If the host has not yet processed the next entry then we are done */
if (((hq_put_index + 1) % hq->entry_count) == hq->hba_index)
return -EBUSY;
-   lpfc_sli_pcimem_bcopy(hrqe, temp_hrqe, hq->entry_size);
-   lpfc_sli_pcimem_bcopy(drqe, temp_drqe, dq->entry_size);
+   lpfc_sli4_pcimem_bcopy(hrqe, temp_hrqe, hq->entry_size);
+   lpfc_sli4_pcimem_bcopy(drqe, temp_drqe, dq->entry_size);
 
/* Update the host index to point to the next slot */
hq->host_index = ((hq_put_index + 1) % hq->entry_count);
@@ -8185,8 +8213,8 @@ lpfc_sli4_post_sync_mbox(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
 */
mbx_cmnd = bf_get(lpfc_mqe_command, mb);
memset(phba->sli4_hba.bmbx.avirt, 0, sizeof(struct lpfc_bmbx_create));
-   lpfc_sli_pcimem_bcopy(mb, phba->sli4_hba.bmbx.avirt,
- sizeof(struct lpfc_mqe));
+   lpfc_sli4_pcimem_bcopy(mb, phba->sli4_hba.bmbx.avirt,
+  sizeof(struct lpfc_mqe));
 
/* Post the high mailbox dma address to the port and wait for ready. */
dma_address = &phba->sli4_hba.bmbx.dma_address;
@@ -8210,11 +8238,11 @@ lpfc_sli4_post_sync_mbox(struct lpfc_hba *phba, 
LPFC_MBOXQ_t *mboxq)
 * If so, update the mailbox status so that the upper layers
 * can complete the request normally.
 */
-   lpfc_sli_pcimem_bcopy(phba->sli4_hba.bmbx.avirt, mb,
- sizeof(struct lpfc_mqe));
+   lpfc_sli4_pcimem_bcopy(phba->sli4_hba.bmbx.avirt, mb,
+  sizeof(struct lpfc_mqe));
mbox_rgn = (struct lpfc_bmbx_create

[PATCH 03/10] lpfc: Correct fw download error message

2018-05-04 Thread James Smart
In situations when the firmware image in inappropriate for the
chip type, initial validation checks were light, allowing the
checks to pass, thus allowing the firmware to be downloaded.
Eventually, after the download, the chip rejects the firmware
but it is logged as a generic firmware download error.

Revise the initial checks to validate the image vs asic type so
that the correct message is displayed and the download process
is avoided.

Signed-off-by: Dick Kennedy 
Signed-off-by: James Smart 
---
 drivers/scsi/lpfc/lpfc_hw4.h  | 3 +++
 drivers/scsi/lpfc/lpfc_init.c | 6 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 9df1c8da6f52..571099fbde28 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -4628,6 +4628,9 @@ union lpfc_wqe128 {
struct send_frame_wqe send_frame;
 };
 
+#define MAGIC_NUMER_G6 0xFEAA0003
+#define MAGIC_NUMER_G7 0xFEAA0005
+
 struct lpfc_grp_hdr {
uint32_t size;
uint32_t magic_number;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 060f0e2f6ff5..70583e1b227d 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -11349,7 +11349,11 @@ lpfc_log_write_firmware_error(struct lpfc_hba *phba, 
uint32_t offset,
uint32_t magic_number, uint32_t ftype, uint32_t fid, uint32_t fsize,
const struct firmware *fw)
 {
-   if (offset == ADD_STATUS_FW_NOT_SUPPORTED)
+   if ((offset == ADD_STATUS_FW_NOT_SUPPORTED) ||
+   (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC &&
+magic_number != MAGIC_NUMER_G6) ||
+   (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC &&
+magic_number != MAGIC_NUMER_G7))
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3030 This firmware version is not supported on "
"this HBA model. Device:%x Magic:%x Type:%x "
-- 
2.13.1



[PATCH 1/2] scsi: mpt3sas: remove obsolete path "drivers/scsi/mpt2sas/" from MAINTAINERS

2018-05-04 Thread Tomohiro Kusumi
drivers/scsi/mpt2sas/ no longer exists after
c84b06a48c ("mpt3sas: Single driver module which supports both
SAS 2.0 & SAS 3.0 HBAs") merged/removed it.

Signed-off-by: Tomohiro Kusumi 
---
 MAINTAINERS | 1 -
 1 file changed, 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index dc59769564c6..277df76cfcbc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8344,7 +8344,6 @@ L:linux-scsi@vger.kernel.org
 W: http://www.avagotech.com/support/
 S: Supported
 F: drivers/message/fusion/
-F: drivers/scsi/mpt2sas/
 F: drivers/scsi/mpt3sas/
 
 LSILOGIC/SYMBIOS/NCR 53C8XX and 53C1010 PCI-SCSI drivers
-- 
2.14.3



[PATCH 2/2] scsi: mpt3sas: fix header path in ioctl documentation

2018-05-04 Thread Tomohiro Kusumi
MPT2_MAGIC_NUMBER as well as drivers/scsi/mpt2sas/mpt2sas_ctl.h
were removed to reuse mpt3sas code since
09ec55ed74 ("mpt2sas: Remove .c and .h files from mpt2sas driver").

Signed-off-by: Tomohiro Kusumi 
---
 Documentation/ioctl/ioctl-number.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index 7f7413e597f3..d50ba147400c 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -151,7 +151,7 @@ Code  Seq#(hex) Include FileComments
 'J'00-1F   drivers/scsi/gdth_ioctl.h
 'K'all linux/kd.h
 'L'00-1F   linux/loop.hconflict!
-'L'10-1F   drivers/scsi/mpt2sas/mpt2sas_ctl.h  conflict!
+'L'10-1F   drivers/scsi/mpt3sas/mpt3sas_ctl.h  conflict!
 'L'20-2F   linux/lightnvm.h
 'L'E0-FF   linux/ppdd.hencrypted disk device driver


-- 
2.14.3



[PATCH v2 1/2] scsi: ufs: Extract devfreq registration

2018-05-04 Thread Bjorn Andersson
Failing to register with devfreq leaves hba->devfreq assigned, which
causes the error path to dereference the ERR_PTR(). Rather than bolting
on more conditionals, move the call of devm_devfreq_add_device() into
it's own function and only update hba->devfreq once it's successfully
registered.

The subsequent patch builds upon this to make UFS actually work again,
as it's been broken since f1d981eaecf8 ("PM / devfreq: Use the available
min/max frequency")

Reviewed-by: Subhash Jadavani 
Signed-off-by: Bjorn Andersson 
---

Changes since v1:
- None

 drivers/scsi/ufs/ufshcd.c | 31 ++-
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 8f22a980b1a7..2253f24309ec 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1255,6 +1255,26 @@ static struct devfreq_dev_profile ufs_devfreq_profile = {
.get_dev_status = ufshcd_devfreq_get_dev_status,
 };
 
+static int ufshcd_devfreq_init(struct ufs_hba *hba)
+{
+   struct devfreq *devfreq;
+   int ret;
+
+   devfreq = devm_devfreq_add_device(hba->dev,
+   &ufs_devfreq_profile,
+   "simple_ondemand",
+   NULL);
+   if (IS_ERR(devfreq)) {
+   ret = PTR_ERR(devfreq);
+   dev_err(hba->dev, "Unable to register with devfreq %d\n", ret);
+   return ret;
+   }
+
+   hba->devfreq = devfreq;
+
+   return 0;
+}
+
 static void __ufshcd_suspend_clkscaling(struct ufs_hba *hba)
 {
unsigned long flags;
@@ -6399,16 +6419,9 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
sizeof(struct ufs_pa_layer_attr));
hba->clk_scaling.saved_pwr_info.is_valid = true;
if (!hba->devfreq) {
-   hba->devfreq = devm_devfreq_add_device(hba->dev,
-   &ufs_devfreq_profile,
-   "simple_ondemand",
-   NULL);
-   if (IS_ERR(hba->devfreq)) {
-   ret = PTR_ERR(hba->devfreq);
-   dev_err(hba->dev, "Unable to register 
with devfreq %d\n",
-   ret);
+   ret = ufshcd_devfreq_init(hba);
+   if (ret)
goto out;
-   }
}
hba->clk_scaling.is_allowed = true;
}
-- 
2.17.0



[PATCH v2 0/2] Fix UFS and devfreq interaction

2018-05-04 Thread Bjorn Andersson
With the introduction of f1d981eaecf8 ("PM / devfreq: Use the available min/max
frequency") the UFS host controller driver (UFSHCD) stopped probing for
platforms that supports frequency scaling, e.g. all modern Qualcomm platforms.

The cause of this was UFSHCD's reliance of not registering any frequencies and
then being called by devfreq to switch between the frequencies 0 and UINT_MAX.

The devfreq code implies that the client is able to pass the frequency table,
instead of relying on opp tables, but as concluded after v1 this is not
compliant with devfreq cooling, which will enable and disable opp entries in
order to limit the valid frequencies. So instead the UFSHCD driver is modified
to read the freq-table and register the first clock's two rates as the two
available opp levels.


This follows the first patch which facilitates the implementation of this in a
clean fashion, and removes the kernel panic which previously happened when
devfreq initialization failed.


With this UFS is once again functional on the db820c, and is needed to get UFS
working on SDM845 (both tested).

Bjorn Andersson (2):
  scsi: ufs: Extract devfreq registration
  scsi: ufs: Use freq table with devfreq

 drivers/scsi/ufs/ufshcd.c | 76 +++
 1 file changed, 61 insertions(+), 15 deletions(-)

-- 
2.17.0



[PATCH v2 2/2] scsi: ufs: Use freq table with devfreq

2018-05-04 Thread Bjorn Andersson
devfreq requires that the client operates on actual frequencies, not
only 0 and UMAX_INT and as such UFS brok with the introduction of
f1d981eaecf8 ("PM / devfreq: Use the available min/max frequency").

This patch registers the frequencies of the first clock as opp levels
and use these to determine if we're trying to step up or down.

Signed-off-by: Bjorn Andersson 
---

Chances since v1:
- Register min_freq and max_freq as opp levels.
- Unregister opp levels on removal, to make e.g. probe defer working

 drivers/scsi/ufs/ufshcd.c | 47 +--
 1 file changed, 40 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 2253f24309ec..257614b889bd 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1168,16 +1168,13 @@ static int ufshcd_devfreq_target(struct device *dev,
struct ufs_hba *hba = dev_get_drvdata(dev);
ktime_t start;
bool scale_up, sched_clk_scaling_suspend_work = false;
+   struct list_head *clk_list = &hba->clk_list_head;
+   struct ufs_clk_info *clki;
unsigned long irq_flags;
 
if (!ufshcd_is_clkscaling_supported(hba))
return -EINVAL;
 
-   if ((*freq > 0) && (*freq < UINT_MAX)) {
-   dev_err(hba->dev, "%s: invalid freq = %lu\n", __func__, *freq);
-   return -EINVAL;
-   }
-
spin_lock_irqsave(hba->host->host_lock, irq_flags);
if (ufshcd_eh_in_progress(hba)) {
spin_unlock_irqrestore(hba->host->host_lock, irq_flags);
@@ -1187,7 +1184,13 @@ static int ufshcd_devfreq_target(struct device *dev,
if (!hba->clk_scaling.active_reqs)
sched_clk_scaling_suspend_work = true;
 
-   scale_up = (*freq == UINT_MAX) ? true : false;
+   if (list_empty(clk_list)) {
+   spin_unlock_irqrestore(hba->host->host_lock, irq_flags);
+   goto out;
+   }
+
+   clki = list_first_entry(clk_list, struct ufs_clk_info, list);
+   scale_up = (*freq == clki->max_freq) ? true : false;
if (!ufshcd_is_devfreq_scaling_required(hba, scale_up)) {
spin_unlock_irqrestore(hba->host->host_lock, irq_flags);
ret = 0;
@@ -1257,16 +1260,29 @@ static struct devfreq_dev_profile ufs_devfreq_profile = 
{
 
 static int ufshcd_devfreq_init(struct ufs_hba *hba)
 {
+   struct list_head *clk_list = &hba->clk_list_head;
+   struct ufs_clk_info *clki;
struct devfreq *devfreq;
int ret;
 
-   devfreq = devm_devfreq_add_device(hba->dev,
+   /* Skip devfreq if we don't have any clocks in the list */
+   if (list_empty(clk_list))
+   return 0;
+
+   clki = list_first_entry(clk_list, struct ufs_clk_info, list);
+   dev_pm_opp_add(hba->dev, clki->min_freq, 0);
+   dev_pm_opp_add(hba->dev, clki->max_freq, 0);
+
+   devfreq = devfreq_add_device(hba->dev,
&ufs_devfreq_profile,
"simple_ondemand",
NULL);
if (IS_ERR(devfreq)) {
ret = PTR_ERR(devfreq);
dev_err(hba->dev, "Unable to register with devfreq %d\n", ret);
+
+   dev_pm_opp_remove(hba->dev, clki->min_freq);
+   dev_pm_opp_remove(hba->dev, clki->max_freq);
return ret;
}
 
@@ -1275,6 +1291,22 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba)
return 0;
 }
 
+static void ufshcd_devfreq_remove(struct ufs_hba *hba)
+{
+   struct list_head *clk_list = &hba->clk_list_head;
+   struct ufs_clk_info *clki;
+
+   if (!hba->devfreq)
+   return;
+
+   devfreq_remove_device(hba->devfreq);
+   hba->devfreq = NULL;
+
+   clki = list_first_entry(clk_list, struct ufs_clk_info, list);
+   dev_pm_opp_remove(hba->dev, clki->min_freq);
+   dev_pm_opp_remove(hba->dev, clki->max_freq);
+}
+
 static void __ufshcd_suspend_clkscaling(struct ufs_hba *hba)
 {
unsigned long flags;
@@ -6966,6 +6998,7 @@ static void ufshcd_hba_exit(struct ufs_hba *hba)
if (hba->devfreq)
ufshcd_suspend_clkscaling(hba);
destroy_workqueue(hba->clk_scaling.workq);
+   ufshcd_devfreq_remove(hba);
}
ufshcd_setup_clocks(hba, false);
ufshcd_setup_hba_vreg(hba, false);
-- 
2.17.0



Re: [PATCH v5 0/6] firmware_loader: cleanups for v4.18

2018-05-04 Thread Luis R. Rodriguez
On Fri, May 04, 2018 at 09:17:08PM +0200, Krzysztof Halasa wrote:
> "Luis R. Rodriguez"  writes:
> 
> >   * CONFIG_WANXL --> CONFIG_WANXL_BUILD_FIRMWARE
> >   * CONFIG_SCSI_AIC79XX --> CONFIG_AIC79XX_BUILD_FIRMWARE
> >
> > To this day both of these drivers are building driver *firmwares* when
> > the option CONFIG_PREVENT_FIRMWARE_BUILD is disabled, and they don't
> > even make use of the firmware API at all.
> 
> Don't know for sure about Adaptec, but wanXL firmware fits every
> definition of "stable". BTW it's a 1997 or so early PCI card, built
> around the PLX PCI9060 bus mastering PCI bridge and Motorola 68360
> (the original QUICC) processor. Maximum bit rate of 2 Mb/s on each sync
> serial port.

So we can nuke CONFIG_WANXL_BUILD_FIRMWARE now?

> It's more about delivering the .S source for the firmware, I guess.
> Nobody is expected to build it. The fw is about 2.5 KB and is directly
> linked with the driver.

:P Future work I guess would be to just use the firmware API and stuff
it into linux-firmware?

  Luis


Re: [PATCH v5 0/6] firmware_loader: cleanups for v4.18

2018-05-04 Thread Krzysztof Halasa
"Luis R. Rodriguez"  writes:

>   * CONFIG_WANXL --> CONFIG_WANXL_BUILD_FIRMWARE
>   * CONFIG_SCSI_AIC79XX --> CONFIG_AIC79XX_BUILD_FIRMWARE
>
> To this day both of these drivers are building driver *firmwares* when
> the option CONFIG_PREVENT_FIRMWARE_BUILD is disabled, and they don't
> even make use of the firmware API at all.

Don't know for sure about Adaptec, but wanXL firmware fits every
definition of "stable". BTW it's a 1997 or so early PCI card, built
around the PLX PCI9060 bus mastering PCI bridge and Motorola 68360
(the original QUICC) processor. Maximum bit rate of 2 Mb/s on each sync
serial port.

It's more about delivering the .S source for the firmware, I guess.
Nobody is expected to build it. The fw is about 2.5 KB and is directly
linked with the driver.
-- 
Krzysztof Halasa


[PATCH v5 0/6] firmware_loader: cleanups for v4.18

2018-05-04 Thread Luis R. Rodriguez
Greg,

I've reviewed the pending patches for the firmware_laoder and as for
v4.18, the following 3 patches from Andres have been iterated enough
that they're ready after I made some final minor changes, mostly just
style fixes and re-arrangements in terms of order. The new API he was
suggesting to add requires just a bit more review.

The last 3 patches are my own and are new, so I'd like further review
from others on them, but considering the changes Hans de Goede is having
us consider, I think this will prove useful to his work in terms of
splitting up code and documenting things properly. One thing that was
clear -- is our Kconfig entries for FW_LOADER were *extremely* outdated,
as such I've gone ahead and updated them.

The kconfig wording update for FW_LOADER includes prior conclusions made
to help justify keeping the split of the firmware fallback sysfs
interface in terms of size which was discussed with Josh Triplett a
while ago. It also includes modern recommendations, which would otherwise
get lost, on what to do about corner case firmware situations on
provisioning situations which folks have brought to my attention before
and architectural solutions based on firmwared [0] for a few years now.
Finally this work also reveals that a couple of candidate drivers could
likely move to staging considering their age, *or* we could just remove
the respective firmware build options. SCSI folks? Networking folks? To
my surprise *nothing* has been done about PREVENT_FIRMWARE_BUILD for
them since pre-git days!  These sneaky litte buggers are:

  * CONFIG_WANXL --> CONFIG_WANXL_BUILD_FIRMWARE
  * CONFIG_SCSI_AIC79XX --> CONFIG_AIC79XX_BUILD_FIRMWARE

To this day both of these drivers are building driver *firmwares* when
the option CONFIG_PREVENT_FIRMWARE_BUILD is disabled, and they don't
even make use of the firmware API at all. I find it *highly unlikely*
pre-git day drivers are raging in new radical firmware updates these
days. I'll go put a knife into some of that unless I hear back from
SCSI or networking folks that WANXL_BUILD_FIRMWARE and
AIC79XX_BUILD_FIRMWARE are still hip and very much needed.

On my radar as well are Mimi's latest firmware_loader proposed changes,
but I think those need considerable review and attention from more security
folks, Android folks, and the linux-wireless community, our own
scattered random folks of firmware reviewer folks.

These patches are based on top of linux-next next-20180504, they are
also available in a respective git branch, both for linux-next [1] and
linux [2].

Question, and specially rants are greatly appreciated, and of course...
may the 4th be with you.

[0] https://github.com/teg/firmwared
[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git/log/?h=20180504-firmware_loader
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux.git/log/?h=20180504-firmware_loader

  Luis

Andres Rodriguez (3):
  firmware: wrap FW_OPT_* into an enum
  firmware: use () to terminate kernel-doc function names
  firmware: rename fw_sysfs_fallback to firmware_fallback_sysfs()

Luis R. Rodriguez (3):
  firmware_loader: document firmware_sysfs_fallback()
  firmware_loader: enhance Kconfig documentation over FW_LOADER
  firmware_loader: move kconfig FW_LOADER entries to its own file

 drivers/base/Kconfig|  90 +++---
 drivers/base/firmware_loader/Kconfig| 149 
 drivers/base/firmware_loader/fallback.c |  46 +---
 drivers/base/firmware_loader/fallback.h |  18 +--
 drivers/base/firmware_loader/firmware.h |  37 --
 drivers/base/firmware_loader/main.c |  28 ++---
 6 files changed, 252 insertions(+), 116 deletions(-)
 create mode 100644 drivers/base/firmware_loader/Kconfig

-- 
2.17.0



[PATCH v5 1/6] firmware: wrap FW_OPT_* into an enum

2018-05-04 Thread Luis R. Rodriguez
From: Andres Rodriguez 

This should let us associate enum kdoc to these values.
While at it, kdocify the fw_opt.

Signed-off-by: Andres Rodriguez 
Acked-by: Luis R. Rodriguez 
[mcgrof: coding style fixes, merge kdoc with enum move]
Signed-off-by: Luis R. Rodriguez 
---
 drivers/base/firmware_loader/fallback.c | 12 
 drivers/base/firmware_loader/fallback.h |  6 ++--
 drivers/base/firmware_loader/firmware.h | 37 +++--
 drivers/base/firmware_loader/main.c |  6 ++--
 4 files changed, 42 insertions(+), 19 deletions(-)

diff --git a/drivers/base/firmware_loader/fallback.c 
b/drivers/base/firmware_loader/fallback.c
index 358354148dec..b57a7b3b4122 100644
--- a/drivers/base/firmware_loader/fallback.c
+++ b/drivers/base/firmware_loader/fallback.c
@@ -512,7 +512,7 @@ static const struct attribute_group *fw_dev_attr_groups[] = 
{
 
 static struct fw_sysfs *
 fw_create_instance(struct firmware *firmware, const char *fw_name,
-  struct device *device, unsigned int opt_flags)
+  struct device *device, enum fw_opt opt_flags)
 {
struct fw_sysfs *fw_sysfs;
struct device *f_dev;
@@ -545,7 +545,7 @@ fw_create_instance(struct firmware *firmware, const char 
*fw_name,
  * In charge of constructing a sysfs fallback interface for firmware loading.
  **/
 static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs,
- unsigned int opt_flags, long timeout)
+ enum fw_opt opt_flags, long timeout)
 {
int retval = 0;
struct device *f_dev = &fw_sysfs->dev;
@@ -599,7 +599,7 @@ static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs,
 
 static int fw_load_from_user_helper(struct firmware *firmware,
const char *name, struct device *device,
-   unsigned int opt_flags)
+   enum fw_opt opt_flags)
 {
struct fw_sysfs *fw_sysfs;
long timeout;
@@ -640,7 +640,7 @@ static int fw_load_from_user_helper(struct firmware 
*firmware,
return ret;
 }
 
-static bool fw_force_sysfs_fallback(unsigned int opt_flags)
+static bool fw_force_sysfs_fallback(enum fw_opt opt_flags)
 {
if (fw_fallback_config.force_sysfs_fallback)
return true;
@@ -649,7 +649,7 @@ static bool fw_force_sysfs_fallback(unsigned int opt_flags)
return true;
 }
 
-static bool fw_run_sysfs_fallback(unsigned int opt_flags)
+static bool fw_run_sysfs_fallback(enum fw_opt opt_flags)
 {
if (fw_fallback_config.ignore_sysfs_fallback) {
pr_info_once("Ignoring firmware sysfs fallback due to sysctl 
knob\n");
@@ -664,7 +664,7 @@ static bool fw_run_sysfs_fallback(unsigned int opt_flags)
 
 int fw_sysfs_fallback(struct firmware *fw, const char *name,
  struct device *device,
- unsigned int opt_flags,
+ enum fw_opt opt_flags,
  int ret)
 {
if (!fw_run_sysfs_fallback(opt_flags))
diff --git a/drivers/base/firmware_loader/fallback.h 
b/drivers/base/firmware_loader/fallback.h
index f8255670a663..a3b73a09db6c 100644
--- a/drivers/base/firmware_loader/fallback.h
+++ b/drivers/base/firmware_loader/fallback.h
@@ -5,6 +5,8 @@
 #include 
 #include 
 
+#include "firmware.h"
+
 /**
  * struct firmware_fallback_config - firmware fallback configuration settings
  *
@@ -31,7 +33,7 @@ struct firmware_fallback_config {
 #ifdef CONFIG_FW_LOADER_USER_HELPER
 int fw_sysfs_fallback(struct firmware *fw, const char *name,
  struct device *device,
- unsigned int opt_flags,
+ enum fw_opt opt_flags,
  int ret);
 void kill_pending_fw_fallback_reqs(bool only_kill_custom);
 
@@ -43,7 +45,7 @@ void unregister_sysfs_loader(void);
 #else /* CONFIG_FW_LOADER_USER_HELPER */
 static inline int fw_sysfs_fallback(struct firmware *fw, const char *name,
struct device *device,
-   unsigned int opt_flags,
+   enum fw_opt opt_flags,
int ret)
 {
/* Keep carrying over the same error */
diff --git a/drivers/base/firmware_loader/firmware.h 
b/drivers/base/firmware_loader/firmware.h
index 64acbb1a392c..4f433b447367 100644
--- a/drivers/base/firmware_loader/firmware.h
+++ b/drivers/base/firmware_loader/firmware.h
@@ -2,6 +2,7 @@
 #ifndef __FIRMWARE_LOADER_H
 #define __FIRMWARE_LOADER_H
 
+#include 
 #include 
 #include 
 #include 
@@ -10,13 +11,33 @@
 
 #include 
 
-/* firmware behavior options */
-#define FW_OPT_UEVENT  (1U << 0)
-#define FW_OPT_NOWAIT  (1U << 1)
-#define FW_OPT_USERHELPER  (1U << 2)
-#define FW_OPT_NO_WARN (1U << 3)
-#define FW_OPT_NOCACHE (1U << 4)
-#define FW_OPT_NOFALLBACK  (1U << 5)
+/**
+ * enum fw_

[PATCH v5 2/6] firmware: use () to terminate kernel-doc function names

2018-05-04 Thread Luis R. Rodriguez
From: Andres Rodriguez 

The kernel-doc spec dictates a function name ends in ().

Signed-off-by: Andres Rodriguez 
Acked-by: Randy Dunlap 
Acked-by: Luis R. Rodriguez 
Signed-off-by: Luis R. Rodriguez 
---
 drivers/base/firmware_loader/fallback.c |  8 
 drivers/base/firmware_loader/main.c | 20 ++--
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/base/firmware_loader/fallback.c 
b/drivers/base/firmware_loader/fallback.c
index b57a7b3b4122..529f7013616f 100644
--- a/drivers/base/firmware_loader/fallback.c
+++ b/drivers/base/firmware_loader/fallback.c
@@ -125,7 +125,7 @@ static ssize_t timeout_show(struct class *class, struct 
class_attribute *attr,
 }
 
 /**
- * firmware_timeout_store - set number of seconds to wait for firmware
+ * firmware_timeout_store() - set number of seconds to wait for firmware
  * @class: device class pointer
  * @attr: device attribute pointer
  * @buf: buffer to scan for timeout value
@@ -239,7 +239,7 @@ static int map_fw_priv_pages(struct fw_priv *fw_priv)
 }
 
 /**
- * firmware_loading_store - set value in the 'loading' control file
+ * firmware_loading_store() - set value in the 'loading' control file
  * @dev: device pointer
  * @attr: device attribute pointer
  * @buf: buffer to scan for loading control value
@@ -431,7 +431,7 @@ static int fw_realloc_pages(struct fw_sysfs *fw_sysfs, int 
min_size)
 }
 
 /**
- * firmware_data_write - write method for firmware
+ * firmware_data_write() - write method for firmware
  * @filp: open sysfs file
  * @kobj: kobject for the device
  * @bin_attr: bin_attr structure
@@ -537,7 +537,7 @@ fw_create_instance(struct firmware *firmware, const char 
*fw_name,
 }
 
 /**
- * fw_load_sysfs_fallback - load a firmware via the sysfs fallback mechanism
+ * fw_load_sysfs_fallback() - load a firmware via the sysfs fallback mechanism
  * @fw_sysfs: firmware sysfs information for the firmware to load
  * @opt_flags: flags of options, FW_OPT_*
  * @timeout: timeout to wait for the load
diff --git a/drivers/base/firmware_loader/main.c 
b/drivers/base/firmware_loader/main.c
index 9919f0e6a7cc..7f2bc7e8e3c0 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -597,7 +597,7 @@ _request_firmware(const struct firmware **firmware_p, const 
char *name,
 }
 
 /**
- * request_firmware: - send firmware request and wait for it
+ * request_firmware() - send firmware request and wait for it
  * @firmware_p: pointer to firmware image
  * @name: name of firmware file
  * @device: device for which firmware is being loaded
@@ -657,7 +657,7 @@ int request_firmware_direct(const struct firmware 
**firmware_p,
 EXPORT_SYMBOL_GPL(request_firmware_direct);
 
 /**
- * firmware_request_cache: - cache firmware for suspend so resume can use it
+ * firmware_request_cache() - cache firmware for suspend so resume can use it
  * @name: name of firmware file
  * @device: device for which firmware should be cached for
  *
@@ -681,7 +681,7 @@ int firmware_request_cache(struct device *device, const 
char *name)
 EXPORT_SYMBOL_GPL(firmware_request_cache);
 
 /**
- * request_firmware_into_buf - load firmware into a previously allocated buffer
+ * request_firmware_into_buf() - load firmware into a previously allocated 
buffer
  * @firmware_p: pointer to firmware image
  * @name: name of firmware file
  * @device: device for which firmware is being loaded and DMA region allocated
@@ -713,7 +713,7 @@ request_firmware_into_buf(const struct firmware 
**firmware_p, const char *name,
 EXPORT_SYMBOL(request_firmware_into_buf);
 
 /**
- * release_firmware: - release the resource associated with a firmware image
+ * release_firmware() - release the resource associated with a firmware image
  * @fw: firmware resource to release
  **/
 void release_firmware(const struct firmware *fw)
@@ -755,7 +755,7 @@ static void request_firmware_work_func(struct work_struct 
*work)
 }
 
 /**
- * request_firmware_nowait - asynchronous version of request_firmware
+ * request_firmware_nowait() - asynchronous version of request_firmware
  * @module: module requesting the firmware
  * @uevent: sends uevent to copy the firmware image if this flag
  * is non-zero else the firmware copy must be done manually.
@@ -824,7 +824,7 @@ EXPORT_SYMBOL(request_firmware_nowait);
 static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain);
 
 /**
- * cache_firmware - cache one firmware image in kernel memory space
+ * cache_firmware() - cache one firmware image in kernel memory space
  * @fw_name: the firmware image name
  *
  * Cache firmware in kernel memory so that drivers can use it when
@@ -866,7 +866,7 @@ static struct fw_priv *lookup_fw_priv(const char *fw_name)
 }
 
 /**
- * uncache_firmware - remove one cached firmware image
+ * uncache_firmware() - remove one cached firmware image
  * @fw_name: the firmware image name
  *
  * Uncache one firmware image which has been cached successfully
@@ -1042,7 +1042,7 @@ static void __device_uncache_fw_ima

[PATCH v5 3/6] firmware: rename fw_sysfs_fallback to firmware_fallback_sysfs()

2018-05-04 Thread Luis R. Rodriguez
From: Andres Rodriguez 

This is done since this call is now exposed through kernel-doc,
and since this also paves the way for different future types of
fallback mechanims.

Signed-off-by: Andres Rodriguez 
Acked-by: Luis R. Rodriguez 
[mcgrof: small coding style changes]
Signed-off-by: Luis R. Rodriguez 
---
 drivers/base/firmware_loader/fallback.c |  8 
 drivers/base/firmware_loader/fallback.h | 16 
 drivers/base/firmware_loader/firmware.h |  2 +-
 drivers/base/firmware_loader/main.c |  2 +-
 4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/base/firmware_loader/fallback.c 
b/drivers/base/firmware_loader/fallback.c
index 529f7013616f..3db9e0f225ac 100644
--- a/drivers/base/firmware_loader/fallback.c
+++ b/drivers/base/firmware_loader/fallback.c
@@ -662,10 +662,10 @@ static bool fw_run_sysfs_fallback(enum fw_opt opt_flags)
return fw_force_sysfs_fallback(opt_flags);
 }
 
-int fw_sysfs_fallback(struct firmware *fw, const char *name,
- struct device *device,
- enum fw_opt opt_flags,
- int ret)
+int firmware_fallback_sysfs(struct firmware *fw, const char *name,
+   struct device *device,
+   enum fw_opt opt_flags,
+   int ret)
 {
if (!fw_run_sysfs_fallback(opt_flags))
return ret;
diff --git a/drivers/base/firmware_loader/fallback.h 
b/drivers/base/firmware_loader/fallback.h
index a3b73a09db6c..21063503e4ea 100644
--- a/drivers/base/firmware_loader/fallback.h
+++ b/drivers/base/firmware_loader/fallback.h
@@ -31,10 +31,10 @@ struct firmware_fallback_config {
 };
 
 #ifdef CONFIG_FW_LOADER_USER_HELPER
-int fw_sysfs_fallback(struct firmware *fw, const char *name,
- struct device *device,
- enum fw_opt opt_flags,
- int ret);
+int firmware_fallback_sysfs(struct firmware *fw, const char *name,
+   struct device *device,
+   enum fw_opt opt_flags,
+   int ret);
 void kill_pending_fw_fallback_reqs(bool only_kill_custom);
 
 void fw_fallback_set_cache_timeout(void);
@@ -43,10 +43,10 @@ void fw_fallback_set_default_timeout(void);
 int register_sysfs_loader(void);
 void unregister_sysfs_loader(void);
 #else /* CONFIG_FW_LOADER_USER_HELPER */
-static inline int fw_sysfs_fallback(struct firmware *fw, const char *name,
-   struct device *device,
-   enum fw_opt opt_flags,
-   int ret)
+static inline int firmware_fallback_sysfs(struct firmware *fw, const char 
*name,
+ struct device *device,
+ enum fw_opt opt_flags,
+ int ret)
 {
/* Keep carrying over the same error */
return ret;
diff --git a/drivers/base/firmware_loader/firmware.h 
b/drivers/base/firmware_loader/firmware.h
index 4f433b447367..4c1395f8e7ed 100644
--- a/drivers/base/firmware_loader/firmware.h
+++ b/drivers/base/firmware_loader/firmware.h
@@ -20,7 +20,7 @@
  * @FW_OPT_NOWAIT: Used to describe the firmware request is asynchronous.
  * @FW_OPT_USERHELPER: Enable the fallback mechanism, in case the direct
  * filesystem lookup fails at finding the firmware.  For details refer to
- * fw_sysfs_fallback().
+ * firmware_fallback_sysfs().
  * @FW_OPT_NO_WARN: Quiet, avoid printing warning messages.
  * @FW_OPT_NOCACHE: Disables firmware caching. Firmware caching is used to
  * cache the firmware upon suspend, so that upon resume races against the
diff --git a/drivers/base/firmware_loader/main.c 
b/drivers/base/firmware_loader/main.c
index 7f2bc7e8e3c0..d951af29017a 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -581,7 +581,7 @@ _request_firmware(const struct firmware **firmware_p, const 
char *name,
dev_warn(device,
 "Direct firmware load for %s failed with error 
%d\n",
 name, ret);
-   ret = fw_sysfs_fallback(fw, name, device, opt_flags, ret);
+   ret = firmware_fallback_sysfs(fw, name, device, opt_flags, ret);
} else
ret = assign_fw(fw, device, opt_flags);
 
-- 
2.17.0



[PATCH v5 4/6] firmware_loader: document firmware_sysfs_fallback()

2018-05-04 Thread Luis R. Rodriguez
This also sets the expecations for future fallback interfaces, even
if they are not exported.

Signed-off-by: Luis R. Rodriguez 
---
 drivers/base/firmware_loader/fallback.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/drivers/base/firmware_loader/fallback.c 
b/drivers/base/firmware_loader/fallback.c
index 3db9e0f225ac..9169e7b9800c 100644
--- a/drivers/base/firmware_loader/fallback.c
+++ b/drivers/base/firmware_loader/fallback.c
@@ -662,6 +662,26 @@ static bool fw_run_sysfs_fallback(enum fw_opt opt_flags)
return fw_force_sysfs_fallback(opt_flags);
 }
 
+/**
+ * firmware_fallback_sysfs() - use the fallback mechanism to find firmware
+ * @fw: pointer to firmware image
+ * @name: name of firmware file to look for
+ * @device: device for which firmware is being loaded
+ * @opt_flags: options to control firmware loading behaviour
+ * @ret: return value from direct lookup which triggered the fallback mechanism
+ *
+ * This function is called if direct lookup for the firmware failed, it enables
+ * a fallback mechanism through userspace by exposing a sysfs loading
+ * interface. Userspace is in charge of loading the firmware through the syfs
+ * loading interface. This syfs fallback mechanism may be disabled completely
+ * on a system by setting the proc sysctl value ignore_sysfs_fallback to true.
+ * If this false we check if the internal API caller set the @FW_OPT_NOFALLBACK
+ * flag, if so it would also disable the fallback mechanism. A system may want
+ * to enfoce the sysfs fallback mechanism at all times, it can do this by
+ * setting ignore_sysfs_fallback to false and force_sysfs_fallback to true.
+ * Enabling force_sysfs_fallback is functionally equivalent to build a kernel
+ * with CONFIG_FW_LOADER_USER_HELPER_FALLBACK.
+ **/
 int firmware_fallback_sysfs(struct firmware *fw, const char *name,
struct device *device,
enum fw_opt opt_flags,
-- 
2.17.0



[PATCH v5 5/6] firmware_loader: enhance Kconfig documentation over FW_LOADER

2018-05-04 Thread Luis R. Rodriguez
If you try to read FW_LOADER today it speaks of old riddles and
unless you have been following development closely you will loose
track of what is what. Even the documentation for PREVENT_FIRMWARE_BUILD
is a bit fuzzy and how it fits into this big picture.

Give the FW_LOADER kconfig documentation some love with more up to
date developments and recommendations. While at it, wrap the FW_LOADER
code into its own menu to compartamentalize and make it clearer which
components really are part of the FW_LOADER. This should also make
it easier to later move these kconfig entries into the firmware_loader/
directory later.

Signed-off-by: Luis R. Rodriguez 
---
 drivers/base/Kconfig | 160 ++-
 1 file changed, 126 insertions(+), 34 deletions(-)

diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 29b0eb452b3a..bf2d464b0e2c 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -70,39 +70,64 @@ config STANDALONE
  If unsure, say Y.
 
 config PREVENT_FIRMWARE_BUILD
-   bool "Prevent firmware from being built"
+   bool "Disable drivers features which enable custom firmware building"
default y
help
- Say yes to avoid building firmware. Firmware is usually shipped
- with the driver and only when updating the firmware should a
- rebuild be made.
- If unsure, say Y here.
+ Say yes to disable driver features which enable building a custom
+ driver firmwar at kernel build time. These drivers do not use the
+ kernel firmware API to load firmware (CONFIG_FW_LOADER), instead they
+ use their own custom loading mechanism. The required firmware is
+ usually shipped with the driver, building the driver firmware
+ should only be needed if you have an updated firmware source.
+
+ Firmware should not be being built as part of kernel, these days
+ you should always prevent this and say Y here. There are only two
+ old drivers which enable building of its firmware at kernel build
+ time:
+
+   o CONFIG_WANXL through CONFIG_WANXL_BUILD_FIRMWARE
+   o CONFIG_SCSI_AIC79XX through CONFIG_AIC79XX_BUILD_FIRMWARE
+
+menu "Firmware loader"
 
 config FW_LOADER
-   tristate "Userspace firmware loading support" if EXPERT
+   tristate "Firmware loading facility" if EXPERT
default y
---help---
- This option is provided for the case where none of the in-tree modules
- require userspace firmware loading support, but a module built
- out-of-tree does.
+ This enables the firmware loading facility in the kernel. The kernel
+ will first look for built-in firmware, if it has any. Next, it will
+ look for the requested firmware in a series of filesystem paths:
+
+   o firmware_class path module parameter or kernel boot param
+   o /lib/firmware/updates/UTS_RELEASE
+   o /lib/firmware/updates
+   o /lib/firmware/UTS_RELEASE
+   o /lib/firmware
+
+ Enabling this feature only increases your kernel image by about
+ 828 bytes, enable this option unless you are certain you don't
+ need firmware.
+
+ You typically want this built-in (=y) but you can also enable this
+ as a module, in which case the firmware_class module will be built.
+ You also want to be sure to enable this built-in if you are going to
+ enable built-in firmware (CONFIG_EXTRA_FIRMWARE).
+
+if FW_LOADER
 
 config EXTRA_FIRMWARE
-   string "External firmware blobs to build into the kernel binary"
-   depends on FW_LOADER
+   string "Build these firmware blobs into the kernel binary"
help
- Various drivers in the kernel source tree may require firmware,
- which is generally available in your distribution's linux-firmware
- package.
+ Device drivers which require firmware can typically deal with
+ having the kernel load firmware from the various supported
+ /lib/firmware/ paths. This option enables you to build into the
+ kernel firmware files. Built-in firmware searches are preceeded
+ over firmware lookups using your filesystem over the supported
+ /lib/firmware paths documented on CONFIG_FW_LOADER.
 
- The linux-firmware package should install firmware into
- /lib/firmware/ on your system, so they can be loaded by userspace
- helpers on request.
-
- This option allows firmware to be built into the kernel for the case
- where the user either cannot or doesn't want to provide it from
- userspace at runtime (for example, when the firmware in question is
- required for accessing the boot device, and the user doesn't want to
- use an initrd).
+ This may be useful for testing or if the firmware is required early on
+ in boot and can

[PATCH v5 6/6] firmware_loader: move kconfig FW_LOADER entries to its own file

2018-05-04 Thread Luis R. Rodriguez
This will make it easier to track and easier to understand
what components and features are part of the FW_LOADER. There
are some components related to firmware which have *nothing* to
do with the FW_LOADER, souch as PREVENT_FIRMWARE_BUILD.

Signed-off-by: Luis R. Rodriguez 
---
 drivers/base/Kconfig | 150 +--
 drivers/base/firmware_loader/Kconfig | 149 ++
 2 files changed, 150 insertions(+), 149 deletions(-)
 create mode 100644 drivers/base/firmware_loader/Kconfig

diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index bf2d464b0e2c..06d6e27784fa 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -88,155 +88,7 @@ config PREVENT_FIRMWARE_BUILD
o CONFIG_WANXL through CONFIG_WANXL_BUILD_FIRMWARE
o CONFIG_SCSI_AIC79XX through CONFIG_AIC79XX_BUILD_FIRMWARE
 
-menu "Firmware loader"
-
-config FW_LOADER
-   tristate "Firmware loading facility" if EXPERT
-   default y
-   ---help---
- This enables the firmware loading facility in the kernel. The kernel
- will first look for built-in firmware, if it has any. Next, it will
- look for the requested firmware in a series of filesystem paths:
-
-   o firmware_class path module parameter or kernel boot param
-   o /lib/firmware/updates/UTS_RELEASE
-   o /lib/firmware/updates
-   o /lib/firmware/UTS_RELEASE
-   o /lib/firmware
-
- Enabling this feature only increases your kernel image by about
- 828 bytes, enable this option unless you are certain you don't
- need firmware.
-
- You typically want this built-in (=y) but you can also enable this
- as a module, in which case the firmware_class module will be built.
- You also want to be sure to enable this built-in if you are going to
- enable built-in firmware (CONFIG_EXTRA_FIRMWARE).
-
-if FW_LOADER
-
-config EXTRA_FIRMWARE
-   string "Build these firmware blobs into the kernel binary"
-   help
- Device drivers which require firmware can typically deal with
- having the kernel load firmware from the various supported
- /lib/firmware/ paths. This option enables you to build into the
- kernel firmware files. Built-in firmware searches are preceeded
- over firmware lookups using your filesystem over the supported
- /lib/firmware paths documented on CONFIG_FW_LOADER.
-
- This may be useful for testing or if the firmware is required early on
- in boot and cannot rely on the firmware being placed in an initrd or
- initramfs.
-
- This option is a string and takes the (space-separated) names of the
- firmware files -- the same names that appear in MODULE_FIRMWARE()
- and request_firmware() in the source. These files should exist under
- the directory specified by the EXTRA_FIRMWARE_DIR option, which is
- /lib/firmware by default.
-
- For example, you might set CONFIG_EXTRA_FIRMWARE="usb8388.bin", copy
- the usb8388.bin file into /lib/firmware, and build the kernel. Then
- any request_firmware("usb8388.bin") will be satisfied internally
- inside the kernel without ever looking at your filesystem at runtime.
-
- WARNING: If you include additional firmware files into your binary
- kernel image that are not available under the terms of the GPL,
- then it may be a violation of the GPL to distribute the resulting
- image since it combines both GPL and non-GPL work. You should
- consult a lawyer of your own before distributing such an image.
-
-config EXTRA_FIRMWARE_DIR
-   string "Firmware blobs root directory"
-   depends on EXTRA_FIRMWARE != ""
-   default "/lib/firmware"
-   help
- This option controls the directory in which the kernel build system
- looks for the firmware files listed in the EXTRA_FIRMWARE option.
-
-config FW_LOADER_USER_HELPER
-   bool "Enable the firmware sysfs fallback mechanism"
-   help
- This option enables a sysfs loading facility to enable firmware
- loading to the kernel through userspace as a fallback mechanism
- if and only if the kernel's direct filesystem lookup for the
- firmware failed using the different /lib/firmware/ paths, or the
- path specified in the firmware_class path module parameter, or the
- firmware_class path kernel boot parameter if the firmware_class is
- built-in. For details on how to work with the sysfs fallback mechanism
- refer to Documentation/driver-api/firmware/fallback-mechanisms.rst.
-
- The direct filesystem lookup for firwmare is always used first now.
-
- If the kernel's direct filesystem lookup for firware fails to find
- the requested firmware a sysfs fallback loading facility is made
- avail

[PATCH 2/2] qla2xxx: remove irq save in qla2x00_poll()

2018-05-04 Thread Sebastian Andrzej Siewior
In commit d2ba5675d899 ("[SCSI] qla2xxx: Disable local-interrupts while
polling for RISC status.") added a local_irq_disable() before invoking
the ->intr_handler callback. The function, which was used in this
callback, did not disable interrupts while acquiring the spin_lock so a
deadlock was possible and this change was one possible solution.

The function in question was qla2300_intr_handler() and is using
spin_lock_irqsave() since commit 43fac4d97a1a ("[SCSI] qla2xxx: Resolve
a performance issue in interrupt").
I checked all other ->intr_handler callbacks and all of them use the
irqsave variant so it is safe to remove the local_irq_save() block now.

Signed-off-by: Sebastian Andrzej Siewior 
---
 drivers/scsi/qla2xxx/qla_inline.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
index 37ae0f6d8ae5..bcbdf28bd7b9 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -58,14 +58,12 @@ qla2x00_debounce_register(volatile uint16_t __iomem *addr)
 static inline void
 qla2x00_poll(struct rsp_que *rsp)
 {
-   unsigned long flags;
struct qla_hw_data *ha = rsp->hw;
-   local_irq_save(flags);
+
if (IS_P3P_TYPE(ha))
qla82xx_poll(0, rsp);
else
ha->isp_ops->intr_handler(0, rsp);
-   local_irq_restore(flags);
 }
 
 static inline uint8_t *
-- 
2.17.0



[PATCH 1/2] libsas: remove irq save in sas_ata_qc_issue()

2018-05-04 Thread Sebastian Andrzej Siewior
Since commit 312d3e56119a ("[SCSI] libsas: remove ata_port.lock
management duties from lldds") the sas_ata_qc_issue() function unlocks
the ata_port.lock and disables interrupts before doing so.
That lock is always taken with disabled interrupts so at this point, the
interrupts are already disabled. There is no need to disable the
interrupts before the unlock operation because they are already
disabled.
Restoring the interrupt state later does not change anything because
they were disabled and remain disabled. Therefore remove the operations
which do not change the behaviour.

Signed-off-by: Sebastian Andrzej Siewior 
---
 drivers/scsi/libsas/sas_ata.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index 0cc1567eacc1..bc5d917ff643 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -176,7 +176,6 @@ static void sas_ata_task_done(struct sas_task *task)
 
 static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
 {
-   unsigned long flags;
struct sas_task *task;
struct scatterlist *sg;
int ret = AC_ERR_SYSTEM;
@@ -190,7 +189,6 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd 
*qc)
/* TODO: audit callers to ensure they are ready for qc_issue to
 * unconditionally re-enable interrupts
 */
-   local_irq_save(flags);
spin_unlock(ap->lock);
 
/* If the device fell off, no sense in issuing commands */
@@ -252,7 +250,6 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd 
*qc)
 
  out:
spin_lock(ap->lock);
-   local_irq_restore(flags);
return ret;
 }
 
-- 
2.17.0



[PATCH] qlogic_stub: Fixup NULL argument to host_reset()

2018-05-04 Thread Hannes Reinecke
The PCMCIA stub calls host_reset() with a NULL argument, which
is always wrong. So build a dummy scsi command to restore
functionality.

Fixes: 4a56c1c166b6: "scsi: qlogicfas: move bus_reset to host_reset"
Reported-by: Dan Carpenter 
Signed-off-by: Hannes Reinecke 
---
 drivers/scsi/pcmcia/qlogic_stub.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/pcmcia/qlogic_stub.c 
b/drivers/scsi/pcmcia/qlogic_stub.c
index 0556054764dc..6a3b71e3f351 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -254,6 +254,9 @@ static void qlogic_release(struct pcmcia_device *link)
 static int qlogic_resume(struct pcmcia_device *link)
 {
scsi_info_t *info = link->priv;
+   /* Dummy command for host_reset function */
+   struct scsi_cmnd scmd;
+   struct scsi_device sdev;
 
pcmcia_enable_device(link);
if ((info->manf_id == MANFID_MACNICA) ||
@@ -263,8 +266,10 @@ static int qlogic_resume(struct pcmcia_device *link)
outb(0x24, link->resource[0]->start + 0x9);
outb(0x04, link->resource[0]->start + 0xd);
}
-   /* Ulll!!! */
-   qlogicfas408_host_reset(NULL);
+   sdev.host = info->host;
+   scmd->device = &sdev;
+
+   qlogicfas408_host_reset(scmd);
 
return 0;
 }
-- 
2.12.3