Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2409207a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI fixes from James Bottomley:
 "This is the same set of patches sent in the merge window as the final
  pull except that Martin's read only rework is replaced with a simple
  revert of the original change that caused the regression.

  Everything else is an obvious fix or small cleanup"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  Revert "scsi: sd: Keep disk read-only when re-reading partition"
  scsi: bnx2fc: fix incorrect cast to u64 on shift operation
  scsi: smartpqi: Reporting unhandled SCSI errors
  scsi: myrs: Fix uninitialized variable
  scsi: lpfc: Update lpfc version to 12.2.0.2
  scsi: lpfc: add check for loss of ndlp when sending RRQ
  scsi: lpfc: correct rcu unlock issue in lpfc_nvme_info_show
  scsi: lpfc: resolve lockdep warnings
  scsi: qedi: remove set but not used variables 'cdev' and 'udev'
  scsi: qedi: remove memset/memcpy to nfunc and use func instead
  scsi: qla2xxx: Add cleanup for PCI EEH recovery
parents 7fbc78e3 8acf608e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -830,7 +830,7 @@ static void bnx2fc_process_unsol_compl(struct bnx2fc_rport *tgt, u16 wqe)
			((u64)err_entry->data.err_warn_bitmap_hi << 32) |
			(u64)err_entry->data.err_warn_bitmap_lo;
		for (i = 0; i < BNX2FC_NUM_ERR_BITS; i++) {
			if (err_warn_bit_map & (u64) (1 << i)) {
			if (err_warn_bit_map & ((u64)1 << i)) {
				err_warn = i;
				break;
			}
+22 −15
Original line number Diff line number Diff line
@@ -176,6 +176,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
	int i;
	int len = 0;
	char tmp[LPFC_MAX_NVME_INFO_TMP_LEN] = {0};
	unsigned long iflags = 0;

	if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) {
		len = scnprintf(buf, PAGE_SIZE, "NVME Disabled\n");
@@ -354,7 +355,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
		  phba->sli4_hba.io_xri_max,
		  lpfc_sli4_get_els_iocb_cnt(phba));
	if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
		goto buffer_done;
		goto rcu_unlock_buf_done;

	/* Port state is only one of two values for now. */
	if (localport->port_id)
@@ -370,15 +371,15 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
		  wwn_to_u64(vport->fc_nodename.u.wwn),
		  localport->port_id, statep);
	if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
		goto buffer_done;
		goto rcu_unlock_buf_done;

	list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
		nrport = NULL;
		spin_lock(&vport->phba->hbalock);
		spin_lock_irqsave(&vport->phba->hbalock, iflags);
		rport = lpfc_ndlp_get_nrport(ndlp);
		if (rport)
			nrport = rport->remoteport;
		spin_unlock(&vport->phba->hbalock);
		spin_unlock_irqrestore(&vport->phba->hbalock, iflags);
		if (!nrport)
			continue;

@@ -397,39 +398,39 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,

		/* Tab in to show lport ownership. */
		if (strlcat(buf, "NVME RPORT       ", PAGE_SIZE) >= PAGE_SIZE)
			goto buffer_done;
			goto rcu_unlock_buf_done;
		if (phba->brd_no >= 10) {
			if (strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE)
				goto buffer_done;
				goto rcu_unlock_buf_done;
		}

		scnprintf(tmp, sizeof(tmp), "WWPN x%llx ",
			  nrport->port_name);
		if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
			goto buffer_done;
			goto rcu_unlock_buf_done;

		scnprintf(tmp, sizeof(tmp), "WWNN x%llx ",
			  nrport->node_name);
		if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
			goto buffer_done;
			goto rcu_unlock_buf_done;

		scnprintf(tmp, sizeof(tmp), "DID x%06x ",
			  nrport->port_id);
		if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
			goto buffer_done;
			goto rcu_unlock_buf_done;

		/* An NVME rport can have multiple roles. */
		if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) {
			if (strlcat(buf, "INITIATOR ", PAGE_SIZE) >= PAGE_SIZE)
				goto buffer_done;
				goto rcu_unlock_buf_done;
		}
		if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) {
			if (strlcat(buf, "TARGET ", PAGE_SIZE) >= PAGE_SIZE)
				goto buffer_done;
				goto rcu_unlock_buf_done;
		}
		if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY) {
			if (strlcat(buf, "DISCSRVC ", PAGE_SIZE) >= PAGE_SIZE)
				goto buffer_done;
				goto rcu_unlock_buf_done;
		}
		if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR |
					  FC_PORT_ROLE_NVME_TARGET |
@@ -437,12 +438,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
			scnprintf(tmp, sizeof(tmp), "UNKNOWN ROLE x%x",
				  nrport->port_role);
			if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
				goto buffer_done;
				goto rcu_unlock_buf_done;
		}

		scnprintf(tmp, sizeof(tmp), "%s\n", statep);
		if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
			goto buffer_done;
			goto rcu_unlock_buf_done;
	}
	rcu_read_unlock();

@@ -504,6 +505,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
		  atomic_read(&lport->cmpl_fcp_err));
	strlcat(buf, tmp, PAGE_SIZE);

	/* RCU is already unlocked. */
	goto buffer_done;

 rcu_unlock_buf_done:
	rcu_read_unlock();

 buffer_done:
	len = strnlen(buf, PAGE_SIZE);

+4 −1
Original line number Diff line number Diff line
@@ -7335,6 +7335,9 @@ lpfc_send_rrq(struct lpfc_hba *phba, struct lpfc_node_rrq *rrq)
{
	struct lpfc_nodelist *ndlp = lpfc_findnode_did(rrq->vport,
						       rrq->nlp_DID);
	if (!ndlp)
		return 1;

	if (lpfc_test_rrq_active(phba, ndlp, rrq->xritag))
		return lpfc_issue_els_rrq(rrq->vport, ndlp,
					 rrq->nlp_DID, rrq);
+53 −31
Original line number Diff line number Diff line
@@ -991,15 +991,14 @@ lpfc_cleanup_vports_rrqs(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 * @ndlp: Targets nodelist pointer for this exchange.
 * @xritag the xri in the bitmap to test.
 *
 * This function is called with hbalock held. This function
 * returns 0 = rrq not active for this xri
 * This function returns:
 * 0 = rrq not active for this xri
 * 1 = rrq is valid for this xri.
 **/
int
lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
			uint16_t  xritag)
{
	lockdep_assert_held(&phba->hbalock);
	if (!ndlp)
		return 0;
	if (!ndlp->active_rrqs_xri_bitmap)
@@ -1102,10 +1101,11 @@ lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
 * @phba: Pointer to HBA context object.
 * @piocb: Pointer to the iocbq.
 *
 * This function is called with the ring lock held. This function
 * gets a new driver sglq object from the sglq list. If the
 * list is not empty then it is successful, it returns pointer to the newly
 * allocated sglq object else it returns NULL.
 * The driver calls this function with either the nvme ls ring lock
 * or the fc els ring lock held depending on the iocb usage.  This function
 * gets a new driver sglq object from the sglq list. If the list is not empty
 * then it is successful, it returns pointer to the newly allocated sglq
 * object else it returns NULL.
 **/
static struct lpfc_sglq *
__lpfc_sli_get_els_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq)
@@ -1115,9 +1115,15 @@ __lpfc_sli_get_els_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq)
	struct lpfc_sglq *start_sglq = NULL;
	struct lpfc_io_buf *lpfc_cmd;
	struct lpfc_nodelist *ndlp;
	struct lpfc_sli_ring *pring = NULL;
	int found = 0;
	lockdep_assert_held(&phba->hbalock);
	if (piocbq->iocb_flag & LPFC_IO_NVME_LS)
		pring =  phba->sli4_hba.nvmels_wq->pring;
	else
		pring = lpfc_phba_elsring(phba);
	lockdep_assert_held(&pring->ring_lock);
	if (piocbq->iocb_flag &  LPFC_IO_FCP) {
		lpfc_cmd = (struct lpfc_io_buf *) piocbq->context1;
@@ -1560,7 +1566,8 @@ lpfc_sli_ring_map(struct lpfc_hba *phba)
 * @pring: Pointer to driver SLI ring object.
 * @piocb: Pointer to the driver iocb object.
 *
 * This function is called with hbalock held. The function adds the
 * The driver calls this function with the hbalock held for SLI3 ports or
 * the ring lock held for SLI4 ports. The function adds the
 * new iocb to txcmplq of the given ring. This function always returns
 * 0. If this function is called for ELS ring, this function checks if
 * there is a vport associated with the ELS command. This function also
@@ -1570,6 +1577,9 @@ static int
lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
			struct lpfc_iocbq *piocb)
{
	if (phba->sli_rev == LPFC_SLI_REV4)
		lockdep_assert_held(&pring->ring_lock);
	else
		lockdep_assert_held(&phba->hbalock);
	BUG_ON(!piocb);
@@ -2967,8 +2977,8 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 *
 * This function looks up the iocb_lookup table to get the command iocb
 * corresponding to the given response iocb using the iotag of the
 * response iocb. This function is called with the hbalock held
 * for sli3 devices or the ring_lock for sli4 devices.
 * response iocb. The driver calls this function with the hbalock held
 * for SLI3 ports or the ring lock held for SLI4 ports.
 * This function returns the command iocb object if it finds the command
 * iocb else returns NULL.
 **/
@@ -2979,8 +2989,15 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba,
{
	struct lpfc_iocbq *cmd_iocb = NULL;
	uint16_t iotag;
	lockdep_assert_held(&phba->hbalock);
	spinlock_t *temp_lock = NULL;
	unsigned long iflag = 0;
	if (phba->sli_rev == LPFC_SLI_REV4)
		temp_lock = &pring->ring_lock;
	else
		temp_lock = &phba->hbalock;
	spin_lock_irqsave(temp_lock, iflag);
	iotag = prspiocb->iocb.ulpIoTag;
	if (iotag != 0 && iotag <= phba->sli.last_iotag) {
@@ -2990,10 +3007,12 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba,
			list_del_init(&cmd_iocb->list);
			cmd_iocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
			pring->txcmplq_cnt--;
			spin_unlock_irqrestore(temp_lock, iflag);
			return cmd_iocb;
		}
	}
	spin_unlock_irqrestore(temp_lock, iflag);
	lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
			"0317 iotag x%x is out of "
			"range: max iotag x%x wd0 x%x\n",
@@ -3009,8 +3028,8 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba,
 * @iotag: IOCB tag.
 *
 * This function looks up the iocb_lookup table to get the command iocb
 * corresponding to the given iotag. This function is called with the
 * hbalock held.
 * corresponding to the given iotag. The driver calls this function with
 * the ring lock held because this function is an SLI4 port only helper.
 * This function returns the command iocb object if it finds the command
 * iocb else returns NULL.
 **/
@@ -3019,8 +3038,15 @@ lpfc_sli_iocbq_lookup_by_tag(struct lpfc_hba *phba,
			     struct lpfc_sli_ring *pring, uint16_t iotag)
{
	struct lpfc_iocbq *cmd_iocb = NULL;
	spinlock_t *temp_lock = NULL;
	unsigned long iflag = 0;
	lockdep_assert_held(&phba->hbalock);
	if (phba->sli_rev == LPFC_SLI_REV4)
		temp_lock = &pring->ring_lock;
	else
		temp_lock = &phba->hbalock;
	spin_lock_irqsave(temp_lock, iflag);
	if (iotag != 0 && iotag <= phba->sli.last_iotag) {
		cmd_iocb = phba->sli.iocbq_lookup[iotag];
		if (cmd_iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ) {
@@ -3028,10 +3054,12 @@ lpfc_sli_iocbq_lookup_by_tag(struct lpfc_hba *phba,
			list_del_init(&cmd_iocb->list);
			cmd_iocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
			pring->txcmplq_cnt--;
			spin_unlock_irqrestore(temp_lock, iflag);
			return cmd_iocb;
		}
	}
	spin_unlock_irqrestore(temp_lock, iflag);
	lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
			"0372 iotag x%x lookup error: max iotag (x%x) "
			"iocb_flag x%x\n",
@@ -3065,17 +3093,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
	int rc = 1;
	unsigned long iflag;
	/* Based on the iotag field, get the cmd IOCB from the txcmplq */
	if (phba->sli_rev == LPFC_SLI_REV4)
		spin_lock_irqsave(&pring->ring_lock, iflag);
	else
		spin_lock_irqsave(&phba->hbalock, iflag);
	cmdiocbp = lpfc_sli_iocbq_lookup(phba, pring, saveq);
	if (phba->sli_rev == LPFC_SLI_REV4)
		spin_unlock_irqrestore(&pring->ring_lock, iflag);
	else
		spin_unlock_irqrestore(&phba->hbalock, iflag);
	if (cmdiocbp) {
		if (cmdiocbp->iocb_cmpl) {
			/*
@@ -3406,8 +3424,10 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
				break;
			}
			spin_unlock_irqrestore(&phba->hbalock, iflag);
			cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
							 &rspiocbq);
			spin_lock_irqsave(&phba->hbalock, iflag);
			if (unlikely(!cmdiocbq))
				break;
			if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED)
@@ -3601,9 +3621,12 @@ lpfc_sli_sp_handle_rspiocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
		case LPFC_ABORT_IOCB:
			cmdiocbp = NULL;
			if (irsp->ulpCommand != CMD_XRI_ABORTED_CX)
			if (irsp->ulpCommand != CMD_XRI_ABORTED_CX) {
				spin_unlock_irqrestore(&phba->hbalock, iflag);
				cmdiocbp = lpfc_sli_iocbq_lookup(phba, pring,
								 saveq);
				spin_lock_irqsave(&phba->hbalock, iflag);
			}
			if (cmdiocbp) {
				/* Call the specified completion routine */
				if (cmdiocbp->iocb_cmpl) {
@@ -12976,13 +12999,11 @@ lpfc_sli4_els_wcqe_to_rspiocbq(struct lpfc_hba *phba,
		return NULL;
	wcqe = &irspiocbq->cq_event.cqe.wcqe_cmpl;
	spin_lock_irqsave(&pring->ring_lock, iflags);
	pring->stats.iocb_event++;
	/* Look up the ELS command IOCB and create pseudo response IOCB */
	cmdiocbq = lpfc_sli_iocbq_lookup_by_tag(phba, pring,
				bf_get(lpfc_wcqe_c_request_tag, wcqe));
	if (unlikely(!cmdiocbq)) {
		spin_unlock_irqrestore(&pring->ring_lock, iflags);
		lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
				"0386 ELS complete with no corresponding "
				"cmdiocb: 0x%x 0x%x 0x%x 0x%x\n",
@@ -12992,6 +13013,7 @@ lpfc_sli4_els_wcqe_to_rspiocbq(struct lpfc_hba *phba,
		return NULL;
	}
	spin_lock_irqsave(&pring->ring_lock, iflags);
	/* Put the iocb back on the txcmplq */
	lpfc_sli_ringtxcmpl_put(phba, pring, cmdiocbq);
	spin_unlock_irqrestore(&pring->ring_lock, iflags);
@@ -13762,9 +13784,9 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
	/* Look up the FCP command IOCB and create pseudo response IOCB */
	spin_lock_irqsave(&pring->ring_lock, iflags);
	pring->stats.iocb_event++;
	spin_unlock_irqrestore(&pring->ring_lock, iflags);
	cmdiocbq = lpfc_sli_iocbq_lookup_by_tag(phba, pring,
				bf_get(lpfc_wcqe_c_request_tag, wcqe));
	spin_unlock_irqrestore(&pring->ring_lock, iflags);
	if (unlikely(!cmdiocbq)) {
		lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
				"0374 FCP complete with no corresponding "
+1 −1
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@
 * included with this package.                                     *
 *******************************************************************/

#define LPFC_DRIVER_VERSION "12.2.0.1"
#define LPFC_DRIVER_VERSION "12.2.0.2"
#define LPFC_DRIVER_NAME		"lpfc"

/* Used for SLI 2/3 */
Loading