diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-09-19 11:28:51 +0200 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-09-19 11:28:51 +0200 | 
| commit | a1d1eb2f57501b2e7e2076ce89b3f3a666ddbfdd (patch) | |
| tree | 375d5bd69b2fc2610648b649eff32aa6582af4e2 /drivers/scsi/mpi3mr/mpi3mr_fw.c | |
| parent | 726e2d0cf2bbc14e3bf38491cddda1a56fe18663 (diff) | |
| parent | cff06a799dbe81f3a697ae7c805eaf88d30c2308 (diff) | |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
 "Updates to the usual drivers (ufs, smartpqi, NCR5380, mac_scsi, lpfc,
  mpi3mr).
  There are no user visible core changes and a whole series of minor
  updates and fixes. The largest core change is probably the
  simplification of the workqueue allocation path"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (86 commits)
  scsi: smartpqi: update driver version to 2.1.30-031
  scsi: smartpqi: fix volume size updates
  scsi: smartpqi: fix rare system hang during LUN reset
  scsi: smartpqi: add new controller PCI IDs
  scsi: smartpqi: add counter for parity write stream requests
  scsi: smartpqi: correct stream detection
  scsi: smartpqi: Add fw log to kdump
  scsi: bnx2fc: Remove some unused fields in struct bnx2fc_rport
  scsi: qla2xxx: Remove the unused 'del_list_entry' field in struct fc_port
  scsi: ufs: core: Remove ufshcd_urgent_bkops()
  scsi: core: Remove obsoleted declaration for scsi_driverbyte_string()
  scsi: bnx2i: Remove unused declarations
  scsi: core: Simplify an alloc_workqueue() invocation
  scsi: ufs: Simplify alloc*_workqueue() invocation
  scsi: stex: Simplify an alloc_ordered_workqueue() invocation
  scsi: scsi_transport_fc: Simplify alloc_workqueue() invocations
  scsi: snic: Simplify alloc_workqueue() invocations
  scsi: qedi: Simplify an alloc_workqueue() invocation
  scsi: qedf: Simplify alloc_workqueue() invocations
  scsi: myrs: Simplify an alloc_ordered_workqueue() invocation
  ...
Diffstat (limited to 'drivers/scsi/mpi3mr/mpi3mr_fw.c')
| -rw-r--r-- | drivers/scsi/mpi3mr/mpi3mr_fw.c | 36 | 
1 files changed, 27 insertions, 9 deletions
| diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c index c196dc14ad20..2e1a92d306b2 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c @@ -345,6 +345,7 @@ static void mpi3mr_process_admin_reply_desc(struct mpi3mr_ioc *mrioc,  {  	u16 reply_desc_type, host_tag = 0;  	u16 ioc_status = MPI3_IOCSTATUS_SUCCESS; +	u16 masked_ioc_status = MPI3_IOCSTATUS_SUCCESS;  	u32 ioc_loginfo = 0, sense_count = 0;  	struct mpi3_status_reply_descriptor *status_desc;  	struct mpi3_address_reply_descriptor *addr_desc; @@ -366,8 +367,8 @@ static void mpi3mr_process_admin_reply_desc(struct mpi3mr_ioc *mrioc,  		if (ioc_status &  		    MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_LOGINFOAVAIL)  			ioc_loginfo = le32_to_cpu(status_desc->ioc_log_info); -		ioc_status &= MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_STATUS_MASK; -		mpi3mr_reply_trigger(mrioc, ioc_status, ioc_loginfo); +		masked_ioc_status = ioc_status & MPI3_IOCSTATUS_STATUS_MASK; +		mpi3mr_reply_trigger(mrioc, masked_ioc_status, ioc_loginfo);  		break;  	case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_ADDRESS_REPLY:  		addr_desc = (struct mpi3_address_reply_descriptor *)reply_desc; @@ -380,7 +381,7 @@ static void mpi3mr_process_admin_reply_desc(struct mpi3mr_ioc *mrioc,  		if (ioc_status &  		    MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_LOGINFOAVAIL)  			ioc_loginfo = le32_to_cpu(def_reply->ioc_log_info); -		ioc_status &= MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_STATUS_MASK; +		masked_ioc_status = ioc_status & MPI3_IOCSTATUS_STATUS_MASK;  		if (def_reply->function == MPI3_FUNCTION_SCSI_IO) {  			scsi_reply = (struct mpi3_scsi_io_reply *)def_reply;  			sense_buf = mpi3mr_get_sensebuf_virt_addr(mrioc, @@ -393,7 +394,7 @@ static void mpi3mr_process_admin_reply_desc(struct mpi3mr_ioc *mrioc,  				    sshdr.asc, sshdr.ascq);  			}  		} -		mpi3mr_reply_trigger(mrioc, ioc_status, ioc_loginfo); +		mpi3mr_reply_trigger(mrioc, masked_ioc_status, ioc_loginfo);  		break;  	case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_SUCCESS:  		success_desc = (struct mpi3_success_reply_descriptor *)reply_desc; @@ -408,7 +409,10 @@ static void mpi3mr_process_admin_reply_desc(struct mpi3mr_ioc *mrioc,  		if (cmdptr->state & MPI3MR_CMD_PENDING) {  			cmdptr->state |= MPI3MR_CMD_COMPLETE;  			cmdptr->ioc_loginfo = ioc_loginfo; -			cmdptr->ioc_status = ioc_status; +			if (host_tag == MPI3MR_HOSTTAG_BSG_CMDS) +				cmdptr->ioc_status = ioc_status; +			else +				cmdptr->ioc_status = masked_ioc_status;  			cmdptr->state &= ~MPI3MR_CMD_PENDING;  			if (def_reply) {  				cmdptr->state |= MPI3MR_CMD_REPLY_VALID; @@ -439,6 +443,7 @@ int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc)  	u32 admin_reply_ci = mrioc->admin_reply_ci;  	u32 num_admin_replies = 0;  	u64 reply_dma = 0; +	u16 threshold_comps = 0;  	struct mpi3_default_reply_descriptor *reply_desc;  	if (!atomic_add_unless(&mrioc->admin_reply_q_in_use, 1, 1)) @@ -462,6 +467,7 @@ int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc)  		if (reply_dma)  			mpi3mr_repost_reply_buf(mrioc, reply_dma);  		num_admin_replies++; +		threshold_comps++;  		if (++admin_reply_ci == mrioc->num_admin_replies) {  			admin_reply_ci = 0;  			exp_phase ^= 1; @@ -472,6 +478,11 @@ int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc)  		if ((le16_to_cpu(reply_desc->reply_flags) &  		    MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase)  			break; +		if (threshold_comps == MPI3MR_THRESHOLD_REPLY_COUNT) { +			writel(admin_reply_ci, +			    &mrioc->sysif_regs->admin_reply_queue_ci); +			threshold_comps = 0; +		}  	} while (1);  	writel(admin_reply_ci, &mrioc->sysif_regs->admin_reply_queue_ci); @@ -525,7 +536,7 @@ int mpi3mr_process_op_reply_q(struct mpi3mr_ioc *mrioc,  	u32 num_op_reply = 0;  	u64 reply_dma = 0;  	struct mpi3_default_reply_descriptor *reply_desc; -	u16 req_q_idx = 0, reply_qidx; +	u16 req_q_idx = 0, reply_qidx, threshold_comps = 0;  	reply_qidx = op_reply_q->qid - 1; @@ -556,6 +567,7 @@ int mpi3mr_process_op_reply_q(struct mpi3mr_ioc *mrioc,  		if (reply_dma)  			mpi3mr_repost_reply_buf(mrioc, reply_dma);  		num_op_reply++; +		threshold_comps++;  		if (++reply_ci == op_reply_q->num_replies) {  			reply_ci = 0; @@ -577,13 +589,19 @@ int mpi3mr_process_op_reply_q(struct mpi3mr_ioc *mrioc,  			break;  		}  #endif +		if (threshold_comps == MPI3MR_THRESHOLD_REPLY_COUNT) { +			writel(reply_ci, +			    &mrioc->sysif_regs->oper_queue_indexes[reply_qidx].consumer_index); +			atomic_sub(threshold_comps, &op_reply_q->pend_ios); +			threshold_comps = 0; +		}  	} while (1);  	writel(reply_ci,  	    &mrioc->sysif_regs->oper_queue_indexes[reply_qidx].consumer_index);  	op_reply_q->ci = reply_ci;  	op_reply_q->ephase = exp_phase; - +	atomic_sub(threshold_comps, &op_reply_q->pend_ios);  	atomic_dec(&op_reply_q->in_use);  	return num_op_reply;  } @@ -2742,8 +2760,8 @@ void mpi3mr_start_watchdog(struct mpi3mr_ioc *mrioc)  	snprintf(mrioc->watchdog_work_q_name,  	    sizeof(mrioc->watchdog_work_q_name), "watchdog_%s%d", mrioc->name,  	    mrioc->id); -	mrioc->watchdog_work_q = -	    create_singlethread_workqueue(mrioc->watchdog_work_q_name); +	mrioc->watchdog_work_q = alloc_ordered_workqueue( +		"%s", WQ_MEM_RECLAIM, mrioc->watchdog_work_q_name);  	if (!mrioc->watchdog_work_q) {  		ioc_err(mrioc, "%s: failed (line=%d)\n", __func__, __LINE__);  		return; | 
