brintos

brintos / linux-shallow public Read only

0
0
Text · 165.6 KiB · 5f2f67a Raw
5887 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Driver for Broadcom MPI3 Storage Controllers4 *5 * Copyright (C) 2017-2023 Broadcom Inc.6 *  (mailto: mpi3mr-linuxdrv.pdl@broadcom.com)7 *8 */9 10#include "mpi3mr.h"11#include <linux/idr.h>12 13/* global driver scop variables */14LIST_HEAD(mrioc_list);15DEFINE_SPINLOCK(mrioc_list_lock);16static DEFINE_IDA(mrioc_ida);17static int warn_non_secure_ctlr;18atomic64_t event_counter;19 20MODULE_AUTHOR(MPI3MR_DRIVER_AUTHOR);21MODULE_DESCRIPTION(MPI3MR_DRIVER_DESC);22MODULE_LICENSE(MPI3MR_DRIVER_LICENSE);23MODULE_VERSION(MPI3MR_DRIVER_VERSION);24 25/* Module parameters*/26int prot_mask = -1;27module_param(prot_mask, int, 0);28MODULE_PARM_DESC(prot_mask, "Host protection capabilities mask, def=0x07");29 30static int prot_guard_mask = 3;31module_param(prot_guard_mask, int, 0);32MODULE_PARM_DESC(prot_guard_mask, " Host protection guard mask, def=3");33static int logging_level;34module_param(logging_level, int, 0);35MODULE_PARM_DESC(logging_level,36	" bits for enabling additional logging info (default=0)");37static int max_sgl_entries = MPI3MR_DEFAULT_SGL_ENTRIES;38module_param(max_sgl_entries, int, 0444);39MODULE_PARM_DESC(max_sgl_entries,40	"Preferred max number of SG entries to be used for a single I/O\n"41	"The actual value will be determined by the driver\n"42	"(Minimum=256, Maximum=2048, default=256)");43 44/* Forward declarations*/45static void mpi3mr_send_event_ack(struct mpi3mr_ioc *mrioc, u8 event,46	struct mpi3mr_drv_cmd *cmdparam, u32 event_ctx);47 48#define MPI3MR_DRIVER_EVENT_TG_QD_REDUCTION	(0xFFFF)49 50#define MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH	(0xFFFE)51 52/**53 * mpi3mr_host_tag_for_scmd - Get host tag for a scmd54 * @mrioc: Adapter instance reference55 * @scmd: SCSI command reference56 *57 * Calculate the host tag based on block tag for a given scmd.58 *59 * Return: Valid host tag or MPI3MR_HOSTTAG_INVALID.60 */61static u16 mpi3mr_host_tag_for_scmd(struct mpi3mr_ioc *mrioc,62	struct scsi_cmnd *scmd)63{64	struct scmd_priv *priv = NULL;65	u32 unique_tag;66	u16 host_tag, hw_queue;67 68	unique_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd));69 70	hw_queue = blk_mq_unique_tag_to_hwq(unique_tag);71	if (hw_queue >= mrioc->num_op_reply_q)72		return MPI3MR_HOSTTAG_INVALID;73	host_tag = blk_mq_unique_tag_to_tag(unique_tag);74 75	if (WARN_ON(host_tag >= mrioc->max_host_ios))76		return MPI3MR_HOSTTAG_INVALID;77 78	priv = scsi_cmd_priv(scmd);79	/*host_tag 0 is invalid hence incrementing by 1*/80	priv->host_tag = host_tag + 1;81	priv->scmd = scmd;82	priv->in_lld_scope = 1;83	priv->req_q_idx = hw_queue;84	priv->meta_chain_idx = -1;85	priv->chain_idx = -1;86	priv->meta_sg_valid = 0;87	return priv->host_tag;88}89 90/**91 * mpi3mr_scmd_from_host_tag - Get SCSI command from host tag92 * @mrioc: Adapter instance reference93 * @host_tag: Host tag94 * @qidx: Operational queue index95 *96 * Identify the block tag from the host tag and queue index and97 * retrieve associated scsi command using scsi_host_find_tag().98 *99 * Return: SCSI command reference or NULL.100 */101static struct scsi_cmnd *mpi3mr_scmd_from_host_tag(102	struct mpi3mr_ioc *mrioc, u16 host_tag, u16 qidx)103{104	struct scsi_cmnd *scmd = NULL;105	struct scmd_priv *priv = NULL;106	u32 unique_tag = host_tag - 1;107 108	if (WARN_ON(host_tag > mrioc->max_host_ios))109		goto out;110 111	unique_tag |= (qidx << BLK_MQ_UNIQUE_TAG_BITS);112 113	scmd = scsi_host_find_tag(mrioc->shost, unique_tag);114	if (scmd) {115		priv = scsi_cmd_priv(scmd);116		if (!priv->in_lld_scope)117			scmd = NULL;118	}119out:120	return scmd;121}122 123/**124 * mpi3mr_clear_scmd_priv - Cleanup SCSI command private date125 * @mrioc: Adapter instance reference126 * @scmd: SCSI command reference127 *128 * Invalidate the SCSI command private data to mark the command129 * is not in LLD scope anymore.130 *131 * Return: Nothing.132 */133static void mpi3mr_clear_scmd_priv(struct mpi3mr_ioc *mrioc,134	struct scsi_cmnd *scmd)135{136	struct scmd_priv *priv = NULL;137 138	priv = scsi_cmd_priv(scmd);139 140	if (WARN_ON(priv->in_lld_scope == 0))141		return;142	priv->host_tag = MPI3MR_HOSTTAG_INVALID;143	priv->req_q_idx = 0xFFFF;144	priv->scmd = NULL;145	priv->in_lld_scope = 0;146	priv->meta_sg_valid = 0;147	if (priv->chain_idx >= 0) {148		clear_bit(priv->chain_idx, mrioc->chain_bitmap);149		priv->chain_idx = -1;150	}151	if (priv->meta_chain_idx >= 0) {152		clear_bit(priv->meta_chain_idx, mrioc->chain_bitmap);153		priv->meta_chain_idx = -1;154	}155}156 157static void mpi3mr_dev_rmhs_send_tm(struct mpi3mr_ioc *mrioc, u16 handle,158	struct mpi3mr_drv_cmd *cmdparam, u8 iou_rc);159static void mpi3mr_fwevt_worker(struct work_struct *work);160 161/**162 * mpi3mr_fwevt_free - firmware event memory dealloctor163 * @r: k reference pointer of the firmware event164 *165 * Free firmware event memory when no reference.166 */167static void mpi3mr_fwevt_free(struct kref *r)168{169	kfree(container_of(r, struct mpi3mr_fwevt, ref_count));170}171 172/**173 * mpi3mr_fwevt_get - k reference incrementor174 * @fwevt: Firmware event reference175 *176 * Increment firmware event reference count.177 */178static void mpi3mr_fwevt_get(struct mpi3mr_fwevt *fwevt)179{180	kref_get(&fwevt->ref_count);181}182 183/**184 * mpi3mr_fwevt_put - k reference decrementor185 * @fwevt: Firmware event reference186 *187 * decrement firmware event reference count.188 */189static void mpi3mr_fwevt_put(struct mpi3mr_fwevt *fwevt)190{191	kref_put(&fwevt->ref_count, mpi3mr_fwevt_free);192}193 194/**195 * mpi3mr_alloc_fwevt - Allocate firmware event196 * @len: length of firmware event data to allocate197 *198 * Allocate firmware event with required length and initialize199 * the reference counter.200 *201 * Return: firmware event reference.202 */203static struct mpi3mr_fwevt *mpi3mr_alloc_fwevt(int len)204{205	struct mpi3mr_fwevt *fwevt;206 207	fwevt = kzalloc(sizeof(*fwevt) + len, GFP_ATOMIC);208	if (!fwevt)209		return NULL;210 211	kref_init(&fwevt->ref_count);212	return fwevt;213}214 215/**216 * mpi3mr_fwevt_add_to_list - Add firmware event to the list217 * @mrioc: Adapter instance reference218 * @fwevt: Firmware event reference219 *220 * Add the given firmware event to the firmware event list.221 *222 * Return: Nothing.223 */224static void mpi3mr_fwevt_add_to_list(struct mpi3mr_ioc *mrioc,225	struct mpi3mr_fwevt *fwevt)226{227	unsigned long flags;228 229	if (!mrioc->fwevt_worker_thread)230		return;231 232	spin_lock_irqsave(&mrioc->fwevt_lock, flags);233	/* get fwevt reference count while adding it to fwevt_list */234	mpi3mr_fwevt_get(fwevt);235	INIT_LIST_HEAD(&fwevt->list);236	list_add_tail(&fwevt->list, &mrioc->fwevt_list);237	INIT_WORK(&fwevt->work, mpi3mr_fwevt_worker);238	/* get fwevt reference count while enqueueing it to worker queue */239	mpi3mr_fwevt_get(fwevt);240	queue_work(mrioc->fwevt_worker_thread, &fwevt->work);241	spin_unlock_irqrestore(&mrioc->fwevt_lock, flags);242}243 244/**245 * mpi3mr_hdb_trigger_data_event - Add hdb trigger data event to246 * the list247 * @mrioc: Adapter instance reference248 * @event_data: Event data249 *250 * Add the given hdb trigger data event to the firmware event251 * list.252 *253 * Return: Nothing.254 */255void mpi3mr_hdb_trigger_data_event(struct mpi3mr_ioc *mrioc,256	struct trigger_event_data *event_data)257{258	struct mpi3mr_fwevt *fwevt;259	u16 sz = sizeof(*event_data);260 261	fwevt = mpi3mr_alloc_fwevt(sz);262	if (!fwevt) {263		ioc_warn(mrioc, "failed to queue hdb trigger data event\n");264		return;265	}266 267	fwevt->mrioc = mrioc;268	fwevt->event_id = MPI3MR_DRIVER_EVENT_PROCESS_TRIGGER;269	fwevt->send_ack = 0;270	fwevt->process_evt = 1;271	fwevt->evt_ctx = 0;272	fwevt->event_data_size = sz;273	memcpy(fwevt->event_data, event_data, sz);274 275	mpi3mr_fwevt_add_to_list(mrioc, fwevt);276}277 278/**279 * mpi3mr_fwevt_del_from_list - Delete firmware event from list280 * @mrioc: Adapter instance reference281 * @fwevt: Firmware event reference282 *283 * Delete the given firmware event from the firmware event list.284 *285 * Return: Nothing.286 */287static void mpi3mr_fwevt_del_from_list(struct mpi3mr_ioc *mrioc,288	struct mpi3mr_fwevt *fwevt)289{290	unsigned long flags;291 292	spin_lock_irqsave(&mrioc->fwevt_lock, flags);293	if (!list_empty(&fwevt->list)) {294		list_del_init(&fwevt->list);295		/*296		 * Put fwevt reference count after297		 * removing it from fwevt_list298		 */299		mpi3mr_fwevt_put(fwevt);300	}301	spin_unlock_irqrestore(&mrioc->fwevt_lock, flags);302}303 304/**305 * mpi3mr_dequeue_fwevt - Dequeue firmware event from the list306 * @mrioc: Adapter instance reference307 *308 * Dequeue a firmware event from the firmware event list.309 *310 * Return: firmware event.311 */312static struct mpi3mr_fwevt *mpi3mr_dequeue_fwevt(313	struct mpi3mr_ioc *mrioc)314{315	unsigned long flags;316	struct mpi3mr_fwevt *fwevt = NULL;317 318	spin_lock_irqsave(&mrioc->fwevt_lock, flags);319	if (!list_empty(&mrioc->fwevt_list)) {320		fwevt = list_first_entry(&mrioc->fwevt_list,321		    struct mpi3mr_fwevt, list);322		list_del_init(&fwevt->list);323		/*324		 * Put fwevt reference count after325		 * removing it from fwevt_list326		 */327		mpi3mr_fwevt_put(fwevt);328	}329	spin_unlock_irqrestore(&mrioc->fwevt_lock, flags);330 331	return fwevt;332}333 334/**335 * mpi3mr_cancel_work - cancel firmware event336 * @fwevt: fwevt object which needs to be canceled337 *338 * Return: Nothing.339 */340static void mpi3mr_cancel_work(struct mpi3mr_fwevt *fwevt)341{342	/*343	 * Wait on the fwevt to complete. If this returns 1, then344	 * the event was never executed.345	 *346	 * If it did execute, we wait for it to finish, and the put will347	 * happen from mpi3mr_process_fwevt()348	 */349	if (cancel_work_sync(&fwevt->work)) {350		/*351		 * Put fwevt reference count after352		 * dequeuing it from worker queue353		 */354		mpi3mr_fwevt_put(fwevt);355		/*356		 * Put fwevt reference count to neutralize357		 * kref_init increment358		 */359		mpi3mr_fwevt_put(fwevt);360	}361}362 363/**364 * mpi3mr_cleanup_fwevt_list - Cleanup firmware event list365 * @mrioc: Adapter instance reference366 *367 * Flush all pending firmware events from the firmware event368 * list.369 *370 * Return: Nothing.371 */372void mpi3mr_cleanup_fwevt_list(struct mpi3mr_ioc *mrioc)373{374	struct mpi3mr_fwevt *fwevt = NULL;375 376	if ((list_empty(&mrioc->fwevt_list) && !mrioc->current_event) ||377	    !mrioc->fwevt_worker_thread)378		return;379 380	while ((fwevt = mpi3mr_dequeue_fwevt(mrioc)))381		mpi3mr_cancel_work(fwevt);382 383	if (mrioc->current_event) {384		fwevt = mrioc->current_event;385		/*386		 * Don't call cancel_work_sync() API for the387		 * fwevt work if the controller reset is388		 * get called as part of processing the389		 * same fwevt work (or) when worker thread is390		 * waiting for device add/remove APIs to complete.391		 * Otherwise we will see deadlock.392		 */393		if (current_work() == &fwevt->work || fwevt->pending_at_sml) {394			fwevt->discard = 1;395			return;396		}397 398		mpi3mr_cancel_work(fwevt);399	}400}401 402/**403 * mpi3mr_queue_qd_reduction_event - Queue TG QD reduction event404 * @mrioc: Adapter instance reference405 * @tg: Throttle group information pointer406 *407 * Accessor to queue on synthetically generated driver event to408 * the event worker thread, the driver event will be used to409 * reduce the QD of all VDs in the TG from the worker thread.410 *411 * Return: None.412 */413static void mpi3mr_queue_qd_reduction_event(struct mpi3mr_ioc *mrioc,414	struct mpi3mr_throttle_group_info *tg)415{416	struct mpi3mr_fwevt *fwevt;417	u16 sz = sizeof(struct mpi3mr_throttle_group_info *);418 419	/*420	 * If the QD reduction event is already queued due to throttle and if421	 * the QD is not restored through device info change event422	 * then dont queue further reduction events423	 */424	if (tg->fw_qd != tg->modified_qd)425		return;426 427	fwevt = mpi3mr_alloc_fwevt(sz);428	if (!fwevt) {429		ioc_warn(mrioc, "failed to queue TG QD reduction event\n");430		return;431	}432	*(struct mpi3mr_throttle_group_info **)fwevt->event_data = tg;433	fwevt->mrioc = mrioc;434	fwevt->event_id = MPI3MR_DRIVER_EVENT_TG_QD_REDUCTION;435	fwevt->send_ack = 0;436	fwevt->process_evt = 1;437	fwevt->evt_ctx = 0;438	fwevt->event_data_size = sz;439	tg->modified_qd = max_t(u16, (tg->fw_qd * tg->qd_reduction) / 10, 8);440 441	dprint_event_bh(mrioc, "qd reduction event queued for tg_id(%d)\n",442	    tg->id);443	mpi3mr_fwevt_add_to_list(mrioc, fwevt);444}445 446/**447 * mpi3mr_invalidate_devhandles -Invalidate device handles448 * @mrioc: Adapter instance reference449 *450 * Invalidate the device handles in the target device structures451 * . Called post reset prior to reinitializing the controller.452 *453 * Return: Nothing.454 */455void mpi3mr_invalidate_devhandles(struct mpi3mr_ioc *mrioc)456{457	struct mpi3mr_tgt_dev *tgtdev;458	struct mpi3mr_stgt_priv_data *tgt_priv;459 460	list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) {461		tgtdev->dev_handle = MPI3MR_INVALID_DEV_HANDLE;462		if (tgtdev->starget && tgtdev->starget->hostdata) {463			tgt_priv = tgtdev->starget->hostdata;464			tgt_priv->dev_handle = MPI3MR_INVALID_DEV_HANDLE;465			tgt_priv->io_throttle_enabled = 0;466			tgt_priv->io_divert = 0;467			tgt_priv->throttle_group = NULL;468			tgt_priv->wslen = 0;469			if (tgtdev->host_exposed)470				atomic_set(&tgt_priv->block_io, 1);471		}472	}473}474 475/**476 * mpi3mr_print_scmd - print individual SCSI command477 * @rq: Block request478 * @data: Adapter instance reference479 *480 * Print the SCSI command details if it is in LLD scope.481 *482 * Return: true always.483 */484static bool mpi3mr_print_scmd(struct request *rq, void *data)485{486	struct mpi3mr_ioc *mrioc = (struct mpi3mr_ioc *)data;487	struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq);488	struct scmd_priv *priv = NULL;489 490	if (scmd) {491		priv = scsi_cmd_priv(scmd);492		if (!priv->in_lld_scope)493			goto out;494 495		ioc_info(mrioc, "%s :Host Tag = %d, qid = %d\n",496		    __func__, priv->host_tag, priv->req_q_idx + 1);497		scsi_print_command(scmd);498	}499 500out:501	return(true);502}503 504/**505 * mpi3mr_flush_scmd - Flush individual SCSI command506 * @rq: Block request507 * @data: Adapter instance reference508 *509 * Return the SCSI command to the upper layers if it is in LLD510 * scope.511 *512 * Return: true always.513 */514 515static bool mpi3mr_flush_scmd(struct request *rq, void *data)516{517	struct mpi3mr_ioc *mrioc = (struct mpi3mr_ioc *)data;518	struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq);519	struct scmd_priv *priv = NULL;520 521	if (scmd) {522		priv = scsi_cmd_priv(scmd);523		if (!priv->in_lld_scope)524			goto out;525 526		if (priv->meta_sg_valid)527			dma_unmap_sg(&mrioc->pdev->dev, scsi_prot_sglist(scmd),528			    scsi_prot_sg_count(scmd), scmd->sc_data_direction);529		mpi3mr_clear_scmd_priv(mrioc, scmd);530		scsi_dma_unmap(scmd);531		scmd->result = DID_RESET << 16;532		scsi_print_command(scmd);533		scsi_done(scmd);534		mrioc->flush_io_count++;535	}536 537out:538	return(true);539}540 541/**542 * mpi3mr_count_dev_pending - Count commands pending for a lun543 * @rq: Block request544 * @data: SCSI device reference545 *546 * This is an iterator function called for each SCSI command in547 * a host and if the command is pending in the LLD for the548 * specific device(lun) then device specific pending I/O counter549 * is updated in the device structure.550 *551 * Return: true always.552 */553 554static bool mpi3mr_count_dev_pending(struct request *rq, void *data)555{556	struct scsi_device *sdev = (struct scsi_device *)data;557	struct mpi3mr_sdev_priv_data *sdev_priv_data = sdev->hostdata;558	struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq);559	struct scmd_priv *priv;560 561	if (scmd) {562		priv = scsi_cmd_priv(scmd);563		if (!priv->in_lld_scope)564			goto out;565		if (scmd->device == sdev)566			sdev_priv_data->pend_count++;567	}568 569out:570	return true;571}572 573/**574 * mpi3mr_count_tgt_pending - Count commands pending for target575 * @rq: Block request576 * @data: SCSI target reference577 *578 * This is an iterator function called for each SCSI command in579 * a host and if the command is pending in the LLD for the580 * specific target then target specific pending I/O counter is581 * updated in the target structure.582 *583 * Return: true always.584 */585 586static bool mpi3mr_count_tgt_pending(struct request *rq, void *data)587{588	struct scsi_target *starget = (struct scsi_target *)data;589	struct mpi3mr_stgt_priv_data *stgt_priv_data = starget->hostdata;590	struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq);591	struct scmd_priv *priv;592 593	if (scmd) {594		priv = scsi_cmd_priv(scmd);595		if (!priv->in_lld_scope)596			goto out;597		if (scmd->device && (scsi_target(scmd->device) == starget))598			stgt_priv_data->pend_count++;599	}600 601out:602	return true;603}604 605/**606 * mpi3mr_flush_host_io -  Flush host I/Os607 * @mrioc: Adapter instance reference608 *609 * Flush all of the pending I/Os by calling610 * blk_mq_tagset_busy_iter() for each possible tag. This is611 * executed post controller reset612 *613 * Return: Nothing.614 */615void mpi3mr_flush_host_io(struct mpi3mr_ioc *mrioc)616{617	struct Scsi_Host *shost = mrioc->shost;618 619	mrioc->flush_io_count = 0;620	ioc_info(mrioc, "%s :Flushing Host I/O cmds post reset\n", __func__);621	blk_mq_tagset_busy_iter(&shost->tag_set,622	    mpi3mr_flush_scmd, (void *)mrioc);623	ioc_info(mrioc, "%s :Flushed %d Host I/O cmds\n", __func__,624	    mrioc->flush_io_count);625}626 627/**628 * mpi3mr_flush_cmds_for_unrecovered_controller - Flush all pending cmds629 * @mrioc: Adapter instance reference630 *631 * This function waits for currently running IO poll threads to632 * exit and then flushes all host I/Os and any internal pending633 * cmds. This is executed after controller is marked as634 * unrecoverable.635 *636 * Return: Nothing.637 */638void mpi3mr_flush_cmds_for_unrecovered_controller(struct mpi3mr_ioc *mrioc)639{640	struct Scsi_Host *shost = mrioc->shost;641	int i;642 643	if (!mrioc->unrecoverable)644		return;645 646	if (mrioc->op_reply_qinfo) {647		for (i = 0; i < mrioc->num_queues; i++) {648			while (atomic_read(&mrioc->op_reply_qinfo[i].in_use))649				udelay(500);650			atomic_set(&mrioc->op_reply_qinfo[i].pend_ios, 0);651		}652	}653	mrioc->flush_io_count = 0;654	blk_mq_tagset_busy_iter(&shost->tag_set,655	    mpi3mr_flush_scmd, (void *)mrioc);656	mpi3mr_flush_delayed_cmd_lists(mrioc);657	mpi3mr_flush_drv_cmds(mrioc);658}659 660/**661 * mpi3mr_alloc_tgtdev - target device allocator662 *663 * Allocate target device instance and initialize the reference664 * count665 *666 * Return: target device instance.667 */668static struct mpi3mr_tgt_dev *mpi3mr_alloc_tgtdev(void)669{670	struct mpi3mr_tgt_dev *tgtdev;671 672	tgtdev = kzalloc(sizeof(*tgtdev), GFP_ATOMIC);673	if (!tgtdev)674		return NULL;675	kref_init(&tgtdev->ref_count);676	return tgtdev;677}678 679/**680 * mpi3mr_tgtdev_add_to_list -Add tgtdevice to the list681 * @mrioc: Adapter instance reference682 * @tgtdev: Target device683 *684 * Add the target device to the target device list685 *686 * Return: Nothing.687 */688static void mpi3mr_tgtdev_add_to_list(struct mpi3mr_ioc *mrioc,689	struct mpi3mr_tgt_dev *tgtdev)690{691	unsigned long flags;692 693	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);694	mpi3mr_tgtdev_get(tgtdev);695	INIT_LIST_HEAD(&tgtdev->list);696	list_add_tail(&tgtdev->list, &mrioc->tgtdev_list);697	tgtdev->state = MPI3MR_DEV_CREATED;698	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);699}700 701/**702 * mpi3mr_tgtdev_del_from_list -Delete tgtdevice from the list703 * @mrioc: Adapter instance reference704 * @tgtdev: Target device705 * @must_delete: Must delete the target device from the list irrespective706 * of the device state.707 *708 * Remove the target device from the target device list709 *710 * Return: Nothing.711 */712static void mpi3mr_tgtdev_del_from_list(struct mpi3mr_ioc *mrioc,713	struct mpi3mr_tgt_dev *tgtdev, bool must_delete)714{715	unsigned long flags;716 717	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);718	if ((tgtdev->state == MPI3MR_DEV_REMOVE_HS_STARTED) || (must_delete == true)) {719		if (!list_empty(&tgtdev->list)) {720			list_del_init(&tgtdev->list);721			tgtdev->state = MPI3MR_DEV_DELETED;722			mpi3mr_tgtdev_put(tgtdev);723		}724	}725	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);726}727 728/**729 * __mpi3mr_get_tgtdev_by_handle -Get tgtdev from device handle730 * @mrioc: Adapter instance reference731 * @handle: Device handle732 *733 * Accessor to retrieve target device from the device handle.734 * Non Lock version735 *736 * Return: Target device reference.737 */738static struct mpi3mr_tgt_dev  *__mpi3mr_get_tgtdev_by_handle(739	struct mpi3mr_ioc *mrioc, u16 handle)740{741	struct mpi3mr_tgt_dev *tgtdev;742 743	assert_spin_locked(&mrioc->tgtdev_lock);744	list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list)745		if (tgtdev->dev_handle == handle)746			goto found_tgtdev;747	return NULL;748 749found_tgtdev:750	mpi3mr_tgtdev_get(tgtdev);751	return tgtdev;752}753 754/**755 * mpi3mr_get_tgtdev_by_handle -Get tgtdev from device handle756 * @mrioc: Adapter instance reference757 * @handle: Device handle758 *759 * Accessor to retrieve target device from the device handle.760 * Lock version761 *762 * Return: Target device reference.763 */764struct mpi3mr_tgt_dev *mpi3mr_get_tgtdev_by_handle(765	struct mpi3mr_ioc *mrioc, u16 handle)766{767	struct mpi3mr_tgt_dev *tgtdev;768	unsigned long flags;769 770	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);771	tgtdev = __mpi3mr_get_tgtdev_by_handle(mrioc, handle);772	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);773	return tgtdev;774}775 776/**777 * __mpi3mr_get_tgtdev_by_perst_id -Get tgtdev from persist ID778 * @mrioc: Adapter instance reference779 * @persist_id: Persistent ID780 *781 * Accessor to retrieve target device from the Persistent ID.782 * Non Lock version783 *784 * Return: Target device reference.785 */786static struct mpi3mr_tgt_dev  *__mpi3mr_get_tgtdev_by_perst_id(787	struct mpi3mr_ioc *mrioc, u16 persist_id)788{789	struct mpi3mr_tgt_dev *tgtdev;790 791	assert_spin_locked(&mrioc->tgtdev_lock);792	list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list)793		if (tgtdev->perst_id == persist_id)794			goto found_tgtdev;795	return NULL;796 797found_tgtdev:798	mpi3mr_tgtdev_get(tgtdev);799	return tgtdev;800}801 802/**803 * mpi3mr_get_tgtdev_by_perst_id -Get tgtdev from persistent ID804 * @mrioc: Adapter instance reference805 * @persist_id: Persistent ID806 *807 * Accessor to retrieve target device from the Persistent ID.808 * Lock version809 *810 * Return: Target device reference.811 */812static struct mpi3mr_tgt_dev *mpi3mr_get_tgtdev_by_perst_id(813	struct mpi3mr_ioc *mrioc, u16 persist_id)814{815	struct mpi3mr_tgt_dev *tgtdev;816	unsigned long flags;817 818	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);819	tgtdev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, persist_id);820	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);821	return tgtdev;822}823 824/**825 * __mpi3mr_get_tgtdev_from_tgtpriv -Get tgtdev from tgt private826 * @mrioc: Adapter instance reference827 * @tgt_priv: Target private data828 *829 * Accessor to return target device from the target private830 * data. Non Lock version831 *832 * Return: Target device reference.833 */834static struct mpi3mr_tgt_dev  *__mpi3mr_get_tgtdev_from_tgtpriv(835	struct mpi3mr_ioc *mrioc, struct mpi3mr_stgt_priv_data *tgt_priv)836{837	struct mpi3mr_tgt_dev *tgtdev;838 839	assert_spin_locked(&mrioc->tgtdev_lock);840	tgtdev = tgt_priv->tgt_dev;841	if (tgtdev)842		mpi3mr_tgtdev_get(tgtdev);843	return tgtdev;844}845 846/**847 * mpi3mr_set_io_divert_for_all_vd_in_tg -set divert for TG VDs848 * @mrioc: Adapter instance reference849 * @tg: Throttle group information pointer850 * @divert_value: 1 or 0851 *852 * Accessor to set io_divert flag for each device associated853 * with the given throttle group with the given value.854 *855 * Return: None.856 */857static void mpi3mr_set_io_divert_for_all_vd_in_tg(struct mpi3mr_ioc *mrioc,858	struct mpi3mr_throttle_group_info *tg, u8 divert_value)859{860	unsigned long flags;861	struct mpi3mr_tgt_dev *tgtdev;862	struct mpi3mr_stgt_priv_data *tgt_priv;863 864	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);865	list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) {866		if (tgtdev->starget && tgtdev->starget->hostdata) {867			tgt_priv = tgtdev->starget->hostdata;868			if (tgt_priv->throttle_group == tg)869				tgt_priv->io_divert = divert_value;870		}871	}872	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);873}874 875/**876 * mpi3mr_print_device_event_notice - print notice related to post processing of877 *					device event after controller reset.878 *879 * @mrioc: Adapter instance reference880 * @device_add: true for device add event and false for device removal event881 *882 * Return: None.883 */884void mpi3mr_print_device_event_notice(struct mpi3mr_ioc *mrioc,885	bool device_add)886{887	ioc_notice(mrioc, "Device %s was in progress before the reset and\n",888	    (device_add ? "addition" : "removal"));889	ioc_notice(mrioc, "completed after reset, verify whether the exposed devices\n");890	ioc_notice(mrioc, "are matched with attached devices for correctness\n");891}892 893/**894 * mpi3mr_remove_tgtdev_from_host - Remove dev from upper layers895 * @mrioc: Adapter instance reference896 * @tgtdev: Target device structure897 *898 * Checks whether the device is exposed to upper layers and if it899 * is then remove the device from upper layers by calling900 * scsi_remove_target().901 *902 * Return: 0 on success, non zero on failure.903 */904void mpi3mr_remove_tgtdev_from_host(struct mpi3mr_ioc *mrioc,905	struct mpi3mr_tgt_dev *tgtdev)906{907	struct mpi3mr_stgt_priv_data *tgt_priv;908 909	ioc_info(mrioc, "%s :Removing handle(0x%04x), wwid(0x%016llx)\n",910	    __func__, tgtdev->dev_handle, (unsigned long long)tgtdev->wwid);911	if (tgtdev->starget && tgtdev->starget->hostdata) {912		tgt_priv = tgtdev->starget->hostdata;913		atomic_set(&tgt_priv->block_io, 0);914		tgt_priv->dev_handle = MPI3MR_INVALID_DEV_HANDLE;915	}916 917	if (!mrioc->sas_transport_enabled || (tgtdev->dev_type !=918	    MPI3_DEVICE_DEVFORM_SAS_SATA) || tgtdev->non_stl) {919		if (tgtdev->starget) {920			if (mrioc->current_event)921				mrioc->current_event->pending_at_sml = 1;922			scsi_remove_target(&tgtdev->starget->dev);923			tgtdev->host_exposed = 0;924			if (mrioc->current_event) {925				mrioc->current_event->pending_at_sml = 0;926				if (mrioc->current_event->discard) {927					mpi3mr_print_device_event_notice(mrioc,928					    false);929					return;930				}931			}932		}933	} else934		mpi3mr_remove_tgtdev_from_sas_transport(mrioc, tgtdev);935	mpi3mr_global_trigger(mrioc,936	    MPI3_DRIVER2_GLOBALTRIGGER_DEVICE_REMOVAL_ENABLED);937 938	ioc_info(mrioc, "%s :Removed handle(0x%04x), wwid(0x%016llx)\n",939	    __func__, tgtdev->dev_handle, (unsigned long long)tgtdev->wwid);940}941 942/**943 * mpi3mr_report_tgtdev_to_host - Expose device to upper layers944 * @mrioc: Adapter instance reference945 * @perst_id: Persistent ID of the device946 *947 * Checks whether the device can be exposed to upper layers and948 * if it is not then expose the device to upper layers by949 * calling scsi_scan_target().950 *951 * Return: 0 on success, non zero on failure.952 */953static int mpi3mr_report_tgtdev_to_host(struct mpi3mr_ioc *mrioc,954	u16 perst_id)955{956	int retval = 0;957	struct mpi3mr_tgt_dev *tgtdev;958 959	if (mrioc->reset_in_progress || mrioc->pci_err_recovery)960		return -1;961 962	tgtdev = mpi3mr_get_tgtdev_by_perst_id(mrioc, perst_id);963	if (!tgtdev) {964		retval = -1;965		goto out;966	}967	if (tgtdev->is_hidden || tgtdev->host_exposed) {968		retval = -1;969		goto out;970	}971	if (!mrioc->sas_transport_enabled || (tgtdev->dev_type !=972	    MPI3_DEVICE_DEVFORM_SAS_SATA) || tgtdev->non_stl){973		tgtdev->host_exposed = 1;974		if (mrioc->current_event)975			mrioc->current_event->pending_at_sml = 1;976		scsi_scan_target(&mrioc->shost->shost_gendev,977		    mrioc->scsi_device_channel, tgtdev->perst_id,978		    SCAN_WILD_CARD, SCSI_SCAN_INITIAL);979		if (!tgtdev->starget)980			tgtdev->host_exposed = 0;981		if (mrioc->current_event) {982			mrioc->current_event->pending_at_sml = 0;983			if (mrioc->current_event->discard) {984				mpi3mr_print_device_event_notice(mrioc, true);985				goto out;986			}987		}988	} else989		mpi3mr_report_tgtdev_to_sas_transport(mrioc, tgtdev);990out:991	if (tgtdev)992		mpi3mr_tgtdev_put(tgtdev);993 994	return retval;995}996 997/**998 * mpi3mr_change_queue_depth- Change QD callback handler999 * @sdev: SCSI device reference1000 * @q_depth: Queue depth1001 *1002 * Validate and limit QD and call scsi_change_queue_depth.1003 *1004 * Return: return value of scsi_change_queue_depth1005 */1006static int mpi3mr_change_queue_depth(struct scsi_device *sdev,1007	int q_depth)1008{1009	struct scsi_target *starget = scsi_target(sdev);1010	struct Scsi_Host *shost = dev_to_shost(&starget->dev);1011	int retval = 0;1012 1013	if (!sdev->tagged_supported)1014		q_depth = 1;1015	if (q_depth > shost->can_queue)1016		q_depth = shost->can_queue;1017	else if (!q_depth)1018		q_depth = MPI3MR_DEFAULT_SDEV_QD;1019	retval = scsi_change_queue_depth(sdev, q_depth);1020	sdev->max_queue_depth = sdev->queue_depth;1021 1022	return retval;1023}1024 1025static void mpi3mr_configure_nvme_dev(struct mpi3mr_tgt_dev *tgt_dev,1026		struct queue_limits *lim)1027{1028	u8 pgsz = tgt_dev->dev_spec.pcie_inf.pgsz ? : MPI3MR_DEFAULT_PGSZEXP;1029 1030	lim->max_hw_sectors = tgt_dev->dev_spec.pcie_inf.mdts / 512;1031	lim->virt_boundary_mask = (1 << pgsz) - 1;1032}1033 1034static void mpi3mr_configure_tgt_dev(struct mpi3mr_tgt_dev *tgt_dev,1035		struct queue_limits *lim)1036{1037	if (tgt_dev->dev_type == MPI3_DEVICE_DEVFORM_PCIE &&1038	    (tgt_dev->dev_spec.pcie_inf.dev_info &1039	     MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) ==1040			MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_NVME_DEVICE)1041		mpi3mr_configure_nvme_dev(tgt_dev, lim);1042}1043 1044/**1045 * mpi3mr_update_sdev - Update SCSI device information1046 * @sdev: SCSI device reference1047 * @data: target device reference1048 *1049 * This is an iterator function called for each SCSI device in a1050 * target to update the target specific information into each1051 * SCSI device.1052 *1053 * Return: Nothing.1054 */1055static void1056mpi3mr_update_sdev(struct scsi_device *sdev, void *data)1057{1058	struct mpi3mr_tgt_dev *tgtdev;1059	struct queue_limits lim;1060 1061	tgtdev = (struct mpi3mr_tgt_dev *)data;1062	if (!tgtdev)1063		return;1064 1065	mpi3mr_change_queue_depth(sdev, tgtdev->q_depth);1066 1067	lim = queue_limits_start_update(sdev->request_queue);1068	mpi3mr_configure_tgt_dev(tgtdev, &lim);1069	WARN_ON_ONCE(queue_limits_commit_update(sdev->request_queue, &lim));1070}1071 1072/**1073 * mpi3mr_refresh_tgtdevs - Refresh target device exposure1074 * @mrioc: Adapter instance reference1075 *1076 * This is executed post controller reset to identify any1077 * missing devices during reset and remove from the upper layers1078 * or expose any newly detected device to the upper layers.1079 *1080 * Return: Nothing.1081 */1082static void mpi3mr_refresh_tgtdevs(struct mpi3mr_ioc *mrioc)1083{1084	struct mpi3mr_tgt_dev *tgtdev, *tgtdev_next;1085	struct mpi3mr_stgt_priv_data *tgt_priv;1086 1087	dprint_reset(mrioc, "refresh target devices: check for removals\n");1088	list_for_each_entry_safe(tgtdev, tgtdev_next, &mrioc->tgtdev_list,1089	    list) {1090		if (((tgtdev->dev_handle == MPI3MR_INVALID_DEV_HANDLE) ||1091		     tgtdev->is_hidden) &&1092		     tgtdev->host_exposed && tgtdev->starget &&1093		     tgtdev->starget->hostdata) {1094			tgt_priv = tgtdev->starget->hostdata;1095			tgt_priv->dev_removed = 1;1096			atomic_set(&tgt_priv->block_io, 0);1097		}1098	}1099 1100	list_for_each_entry_safe(tgtdev, tgtdev_next, &mrioc->tgtdev_list,1101	    list) {1102		if (tgtdev->dev_handle == MPI3MR_INVALID_DEV_HANDLE) {1103			dprint_reset(mrioc, "removing target device with perst_id(%d)\n",1104			    tgtdev->perst_id);1105			if (tgtdev->host_exposed)1106				mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev);1107			mpi3mr_tgtdev_del_from_list(mrioc, tgtdev, true);1108			mpi3mr_tgtdev_put(tgtdev);1109		} else if (tgtdev->is_hidden & tgtdev->host_exposed) {1110			dprint_reset(mrioc, "hiding target device with perst_id(%d)\n",1111				     tgtdev->perst_id);1112			mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev);1113		}1114	}1115 1116	tgtdev = NULL;1117	list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) {1118		if ((tgtdev->dev_handle != MPI3MR_INVALID_DEV_HANDLE) &&1119		    !tgtdev->is_hidden) {1120			if (!tgtdev->host_exposed)1121				mpi3mr_report_tgtdev_to_host(mrioc,1122							     tgtdev->perst_id);1123			else if (tgtdev->starget)1124				starget_for_each_device(tgtdev->starget,1125							(void *)tgtdev, mpi3mr_update_sdev);1126	}1127	}1128}1129 1130/**1131 * mpi3mr_update_tgtdev - DevStatusChange evt bottomhalf1132 * @mrioc: Adapter instance reference1133 * @tgtdev: Target device internal structure1134 * @dev_pg0: New device page01135 * @is_added: Flag to indicate the device is just added1136 *1137 * Update the information from the device page0 into the driver1138 * cached target device structure.1139 *1140 * Return: Nothing.1141 */1142static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,1143	struct mpi3mr_tgt_dev *tgtdev, struct mpi3_device_page0 *dev_pg0,1144	bool is_added)1145{1146	u16 flags = 0;1147	struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data = NULL;1148	struct mpi3mr_enclosure_node *enclosure_dev = NULL;1149	u8 prot_mask = 0;1150 1151	tgtdev->perst_id = le16_to_cpu(dev_pg0->persistent_id);1152	tgtdev->dev_handle = le16_to_cpu(dev_pg0->dev_handle);1153	tgtdev->dev_type = dev_pg0->device_form;1154	tgtdev->io_unit_port = dev_pg0->io_unit_port;1155	tgtdev->encl_handle = le16_to_cpu(dev_pg0->enclosure_handle);1156	tgtdev->parent_handle = le16_to_cpu(dev_pg0->parent_dev_handle);1157	tgtdev->slot = le16_to_cpu(dev_pg0->slot);1158	tgtdev->q_depth = le16_to_cpu(dev_pg0->queue_depth);1159	tgtdev->wwid = le64_to_cpu(dev_pg0->wwid);1160	tgtdev->devpg0_flag = le16_to_cpu(dev_pg0->flags);1161 1162	if (tgtdev->encl_handle)1163		enclosure_dev = mpi3mr_enclosure_find_by_handle(mrioc,1164		    tgtdev->encl_handle);1165	if (enclosure_dev)1166		tgtdev->enclosure_logical_id = le64_to_cpu(1167		    enclosure_dev->pg0.enclosure_logical_id);1168 1169	flags = tgtdev->devpg0_flag;1170 1171	tgtdev->is_hidden = (flags & MPI3_DEVICE0_FLAGS_HIDDEN);1172 1173	if (is_added == true)1174		tgtdev->io_throttle_enabled =1175		    (flags & MPI3_DEVICE0_FLAGS_IO_THROTTLING_REQUIRED) ? 1 : 0;1176 1177	switch (flags & MPI3_DEVICE0_FLAGS_MAX_WRITE_SAME_MASK) {1178	case MPI3_DEVICE0_FLAGS_MAX_WRITE_SAME_256_LB:1179		tgtdev->wslen = MPI3MR_WRITE_SAME_MAX_LEN_256_BLKS;1180		break;1181	case MPI3_DEVICE0_FLAGS_MAX_WRITE_SAME_2048_LB:1182		tgtdev->wslen = MPI3MR_WRITE_SAME_MAX_LEN_2048_BLKS;1183		break;1184	case MPI3_DEVICE0_FLAGS_MAX_WRITE_SAME_NO_LIMIT:1185	default:1186		tgtdev->wslen = 0;1187		break;1188	}1189 1190	if (tgtdev->starget && tgtdev->starget->hostdata) {1191		scsi_tgt_priv_data = (struct mpi3mr_stgt_priv_data *)1192		    tgtdev->starget->hostdata;1193		scsi_tgt_priv_data->perst_id = tgtdev->perst_id;1194		scsi_tgt_priv_data->dev_handle = tgtdev->dev_handle;1195		scsi_tgt_priv_data->dev_type = tgtdev->dev_type;1196		scsi_tgt_priv_data->io_throttle_enabled =1197		    tgtdev->io_throttle_enabled;1198		if (is_added == true)1199			atomic_set(&scsi_tgt_priv_data->block_io, 0);1200		scsi_tgt_priv_data->wslen = tgtdev->wslen;1201	}1202 1203	switch (dev_pg0->access_status) {1204	case MPI3_DEVICE0_ASTATUS_NO_ERRORS:1205	case MPI3_DEVICE0_ASTATUS_PREPARE:1206	case MPI3_DEVICE0_ASTATUS_NEEDS_INITIALIZATION:1207	case MPI3_DEVICE0_ASTATUS_DEVICE_MISSING_DELAY:1208		break;1209	default:1210		tgtdev->is_hidden = 1;1211		break;1212	}1213 1214	switch (tgtdev->dev_type) {1215	case MPI3_DEVICE_DEVFORM_SAS_SATA:1216	{1217		struct mpi3_device0_sas_sata_format *sasinf =1218		    &dev_pg0->device_specific.sas_sata_format;1219		u16 dev_info = le16_to_cpu(sasinf->device_info);1220 1221		tgtdev->dev_spec.sas_sata_inf.dev_info = dev_info;1222		tgtdev->dev_spec.sas_sata_inf.sas_address =1223		    le64_to_cpu(sasinf->sas_address);1224		tgtdev->dev_spec.sas_sata_inf.phy_id = sasinf->phy_num;1225		tgtdev->dev_spec.sas_sata_inf.attached_phy_id =1226		    sasinf->attached_phy_identifier;1227		if ((dev_info & MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_MASK) !=1228		    MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_END_DEVICE)1229			tgtdev->is_hidden = 1;1230		else if (!(dev_info & (MPI3_SAS_DEVICE_INFO_STP_SATA_TARGET |1231		    MPI3_SAS_DEVICE_INFO_SSP_TARGET)))1232			tgtdev->is_hidden = 1;1233 1234		if (((tgtdev->devpg0_flag &1235		    MPI3_DEVICE0_FLAGS_ATT_METHOD_DIR_ATTACHED)1236		    && (tgtdev->devpg0_flag &1237		    MPI3_DEVICE0_FLAGS_ATT_METHOD_VIRTUAL)) ||1238		    (tgtdev->parent_handle == 0xFFFF))1239			tgtdev->non_stl = 1;1240		if (tgtdev->dev_spec.sas_sata_inf.hba_port)1241			tgtdev->dev_spec.sas_sata_inf.hba_port->port_id =1242			    dev_pg0->io_unit_port;1243		break;1244	}1245	case MPI3_DEVICE_DEVFORM_PCIE:1246	{1247		struct mpi3_device0_pcie_format *pcieinf =1248		    &dev_pg0->device_specific.pcie_format;1249		u16 dev_info = le16_to_cpu(pcieinf->device_info);1250 1251		tgtdev->dev_spec.pcie_inf.dev_info = dev_info;1252		tgtdev->dev_spec.pcie_inf.capb =1253		    le32_to_cpu(pcieinf->capabilities);1254		tgtdev->dev_spec.pcie_inf.mdts = MPI3MR_DEFAULT_MDTS;1255		/* 2^12 = 4096 */1256		tgtdev->dev_spec.pcie_inf.pgsz = 12;1257		if (dev_pg0->access_status == MPI3_DEVICE0_ASTATUS_NO_ERRORS) {1258			tgtdev->dev_spec.pcie_inf.mdts =1259			    le32_to_cpu(pcieinf->maximum_data_transfer_size);1260			tgtdev->dev_spec.pcie_inf.pgsz = pcieinf->page_size;1261			tgtdev->dev_spec.pcie_inf.reset_to =1262			    max_t(u8, pcieinf->controller_reset_to,1263			     MPI3MR_INTADMCMD_TIMEOUT);1264			tgtdev->dev_spec.pcie_inf.abort_to =1265			    max_t(u8, pcieinf->nvme_abort_to,1266			    MPI3MR_INTADMCMD_TIMEOUT);1267		}1268		if (tgtdev->dev_spec.pcie_inf.mdts > (1024 * 1024))1269			tgtdev->dev_spec.pcie_inf.mdts = (1024 * 1024);1270		if (((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) !=1271		    MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_NVME_DEVICE) &&1272		    ((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) !=1273		    MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_SCSI_DEVICE))1274			tgtdev->is_hidden = 1;1275		tgtdev->non_stl = 1;1276		if (!mrioc->shost)1277			break;1278		prot_mask = scsi_host_get_prot(mrioc->shost);1279		if (prot_mask & SHOST_DIX_TYPE0_PROTECTION) {1280			scsi_host_set_prot(mrioc->shost, prot_mask & 0x77);1281			ioc_info(mrioc,1282			    "%s : Disabling DIX0 prot capability\n", __func__);1283			ioc_info(mrioc,1284			    "because HBA does not support DIX0 operation on NVME drives\n");1285		}1286		break;1287	}1288	case MPI3_DEVICE_DEVFORM_VD:1289	{1290		struct mpi3_device0_vd_format *vdinf =1291		    &dev_pg0->device_specific.vd_format;1292		struct mpi3mr_throttle_group_info *tg = NULL;1293		u16 vdinf_io_throttle_group =1294		    le16_to_cpu(vdinf->io_throttle_group);1295 1296		tgtdev->dev_spec.vd_inf.state = vdinf->vd_state;1297		if (vdinf->vd_state == MPI3_DEVICE0_VD_STATE_OFFLINE)1298			tgtdev->is_hidden = 1;1299		tgtdev->non_stl = 1;1300		tgtdev->dev_spec.vd_inf.tg_id = vdinf_io_throttle_group;1301		tgtdev->dev_spec.vd_inf.tg_high =1302		    le16_to_cpu(vdinf->io_throttle_group_high) * 2048;1303		tgtdev->dev_spec.vd_inf.tg_low =1304		    le16_to_cpu(vdinf->io_throttle_group_low) * 2048;1305		if (vdinf_io_throttle_group < mrioc->num_io_throttle_group) {1306			tg = mrioc->throttle_groups + vdinf_io_throttle_group;1307			tg->id = vdinf_io_throttle_group;1308			tg->high = tgtdev->dev_spec.vd_inf.tg_high;1309			tg->low = tgtdev->dev_spec.vd_inf.tg_low;1310			tg->qd_reduction =1311			    tgtdev->dev_spec.vd_inf.tg_qd_reduction;1312			if (is_added == true)1313				tg->fw_qd = tgtdev->q_depth;1314			tg->modified_qd = tgtdev->q_depth;1315		}1316		tgtdev->dev_spec.vd_inf.tg = tg;1317		if (scsi_tgt_priv_data)1318			scsi_tgt_priv_data->throttle_group = tg;1319		break;1320	}1321	default:1322		break;1323	}1324}1325 1326/**1327 * mpi3mr_devstatuschg_evt_bh - DevStatusChange evt bottomhalf1328 * @mrioc: Adapter instance reference1329 * @fwevt: Firmware event information.1330 *1331 * Process Device status Change event and based on device's new1332 * information, either expose the device to the upper layers, or1333 * remove the device from upper layers.1334 *1335 * Return: Nothing.1336 */1337static void mpi3mr_devstatuschg_evt_bh(struct mpi3mr_ioc *mrioc,1338	struct mpi3mr_fwevt *fwevt)1339{1340	u16 dev_handle = 0;1341	u8 uhide = 0, delete = 0, cleanup = 0;1342	struct mpi3mr_tgt_dev *tgtdev = NULL;1343	struct mpi3_event_data_device_status_change *evtdata =1344	    (struct mpi3_event_data_device_status_change *)fwevt->event_data;1345 1346	dev_handle = le16_to_cpu(evtdata->dev_handle);1347	ioc_info(mrioc,1348	    "%s :device status change: handle(0x%04x): reason code(0x%x)\n",1349	    __func__, dev_handle, evtdata->reason_code);1350	switch (evtdata->reason_code) {1351	case MPI3_EVENT_DEV_STAT_RC_HIDDEN:1352		delete = 1;1353		break;1354	case MPI3_EVENT_DEV_STAT_RC_NOT_HIDDEN:1355		uhide = 1;1356		break;1357	case MPI3_EVENT_DEV_STAT_RC_VD_NOT_RESPONDING:1358		delete = 1;1359		cleanup = 1;1360		break;1361	default:1362		ioc_info(mrioc, "%s :Unhandled reason code(0x%x)\n", __func__,1363		    evtdata->reason_code);1364		break;1365	}1366 1367	tgtdev = mpi3mr_get_tgtdev_by_handle(mrioc, dev_handle);1368	if (!tgtdev)1369		goto out;1370	if (uhide) {1371		tgtdev->is_hidden = 0;1372		if (!tgtdev->host_exposed)1373			mpi3mr_report_tgtdev_to_host(mrioc, tgtdev->perst_id);1374	}1375 1376	if (delete)1377		mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev);1378 1379	if (cleanup) {1380		mpi3mr_tgtdev_del_from_list(mrioc, tgtdev, false);1381		mpi3mr_tgtdev_put(tgtdev);1382	}1383 1384out:1385	if (tgtdev)1386		mpi3mr_tgtdev_put(tgtdev);1387}1388 1389/**1390 * mpi3mr_devinfochg_evt_bh - DeviceInfoChange evt bottomhalf1391 * @mrioc: Adapter instance reference1392 * @dev_pg0: New device page01393 *1394 * Process Device Info Change event and based on device's new1395 * information, either expose the device to the upper layers, or1396 * remove the device from upper layers or update the details of1397 * the device.1398 *1399 * Return: Nothing.1400 */1401static void mpi3mr_devinfochg_evt_bh(struct mpi3mr_ioc *mrioc,1402	struct mpi3_device_page0 *dev_pg0)1403{1404	struct mpi3mr_tgt_dev *tgtdev = NULL;1405	u16 dev_handle = 0, perst_id = 0;1406 1407	perst_id = le16_to_cpu(dev_pg0->persistent_id);1408	dev_handle = le16_to_cpu(dev_pg0->dev_handle);1409	ioc_info(mrioc,1410	    "%s :Device info change: handle(0x%04x): persist_id(0x%x)\n",1411	    __func__, dev_handle, perst_id);1412	tgtdev = mpi3mr_get_tgtdev_by_handle(mrioc, dev_handle);1413	if (!tgtdev)1414		goto out;1415	mpi3mr_update_tgtdev(mrioc, tgtdev, dev_pg0, false);1416	if (!tgtdev->is_hidden && !tgtdev->host_exposed)1417		mpi3mr_report_tgtdev_to_host(mrioc, perst_id);1418	if (tgtdev->is_hidden && tgtdev->host_exposed)1419		mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev);1420	if (!tgtdev->is_hidden && tgtdev->host_exposed && tgtdev->starget)1421		starget_for_each_device(tgtdev->starget, (void *)tgtdev,1422		    mpi3mr_update_sdev);1423out:1424	if (tgtdev)1425		mpi3mr_tgtdev_put(tgtdev);1426}1427 1428/**1429 * mpi3mr_free_enclosure_list - release enclosures1430 * @mrioc: Adapter instance reference1431 *1432 * Free memory allocated during encloure add.1433 *1434 * Return nothing.1435 */1436void mpi3mr_free_enclosure_list(struct mpi3mr_ioc *mrioc)1437{1438	struct mpi3mr_enclosure_node *enclosure_dev, *enclosure_dev_next;1439 1440	list_for_each_entry_safe(enclosure_dev,1441	    enclosure_dev_next, &mrioc->enclosure_list, list) {1442		list_del(&enclosure_dev->list);1443		kfree(enclosure_dev);1444	}1445}1446 1447/**1448 * mpi3mr_enclosure_find_by_handle - enclosure search by handle1449 * @mrioc: Adapter instance reference1450 * @handle: Firmware device handle of the enclosure1451 *1452 * This searches for enclosure device based on handle, then returns the1453 * enclosure object.1454 *1455 * Return: Enclosure object reference or NULL1456 */1457struct mpi3mr_enclosure_node *mpi3mr_enclosure_find_by_handle(1458	struct mpi3mr_ioc *mrioc, u16 handle)1459{1460	struct mpi3mr_enclosure_node *enclosure_dev, *r = NULL;1461 1462	list_for_each_entry(enclosure_dev, &mrioc->enclosure_list, list) {1463		if (le16_to_cpu(enclosure_dev->pg0.enclosure_handle) != handle)1464			continue;1465		r = enclosure_dev;1466		goto out;1467	}1468out:1469	return r;1470}1471 1472/**1473 * mpi3mr_process_trigger_data_event_bh - Process trigger event1474 * data1475 * @mrioc: Adapter instance reference1476 * @event_data: Event data1477 *1478 * This function releases diage buffers or issues diag fault1479 * based on trigger conditions1480 *1481 * Return: Nothing1482 */1483static void mpi3mr_process_trigger_data_event_bh(struct mpi3mr_ioc *mrioc,1484	struct trigger_event_data *event_data)1485{1486	struct diag_buffer_desc *trace_hdb = event_data->trace_hdb;1487	struct diag_buffer_desc *fw_hdb = event_data->fw_hdb;1488	unsigned long flags;1489	int retval = 0;1490	u8 trigger_type = event_data->trigger_type;1491	union mpi3mr_trigger_data *trigger_data =1492		&event_data->trigger_specific_data;1493 1494	if (event_data->snapdump)  {1495		if (trace_hdb)1496			mpi3mr_set_trigger_data_in_hdb(trace_hdb, trigger_type,1497			    trigger_data, 1);1498		if (fw_hdb)1499			mpi3mr_set_trigger_data_in_hdb(fw_hdb, trigger_type,1500			    trigger_data, 1);1501		mpi3mr_soft_reset_handler(mrioc,1502			    MPI3MR_RESET_FROM_TRIGGER, 1);1503		return;1504	}1505 1506	if (trace_hdb) {1507		retval = mpi3mr_issue_diag_buf_release(mrioc, trace_hdb);1508		if (!retval) {1509			mpi3mr_set_trigger_data_in_hdb(trace_hdb, trigger_type,1510			    trigger_data, 1);1511		}1512		spin_lock_irqsave(&mrioc->trigger_lock, flags);1513		mrioc->trace_release_trigger_active = false;1514		spin_unlock_irqrestore(&mrioc->trigger_lock, flags);1515	}1516	if (fw_hdb) {1517		retval = mpi3mr_issue_diag_buf_release(mrioc, fw_hdb);1518		if (!retval) {1519			mpi3mr_set_trigger_data_in_hdb(fw_hdb, trigger_type,1520		    trigger_data, 1);1521		}1522		spin_lock_irqsave(&mrioc->trigger_lock, flags);1523		mrioc->fw_release_trigger_active = false;1524		spin_unlock_irqrestore(&mrioc->trigger_lock, flags);1525	}1526}1527 1528/**1529 * mpi3mr_encldev_add_chg_evt_debug - debug for enclosure event1530 * @mrioc: Adapter instance reference1531 * @encl_pg0: Enclosure page 0.1532 * @is_added: Added event or not1533 *1534 * Return nothing.1535 */1536static void mpi3mr_encldev_add_chg_evt_debug(struct mpi3mr_ioc *mrioc,1537	struct mpi3_enclosure_page0 *encl_pg0, u8 is_added)1538{1539	char *reason_str = NULL;1540 1541	if (!(mrioc->logging_level & MPI3_DEBUG_EVENT_WORK_TASK))1542		return;1543 1544	if (is_added)1545		reason_str = "enclosure added";1546	else1547		reason_str = "enclosure dev status changed";1548 1549	ioc_info(mrioc,1550	    "%s: handle(0x%04x), enclosure logical id(0x%016llx)\n",1551	    reason_str, le16_to_cpu(encl_pg0->enclosure_handle),1552	    (unsigned long long)le64_to_cpu(encl_pg0->enclosure_logical_id));1553	ioc_info(mrioc,1554	    "number of slots(%d), port(%d), flags(0x%04x), present(%d)\n",1555	    le16_to_cpu(encl_pg0->num_slots), encl_pg0->io_unit_port,1556	    le16_to_cpu(encl_pg0->flags),1557	    ((le16_to_cpu(encl_pg0->flags) &1558	      MPI3_ENCLS0_FLAGS_ENCL_DEV_PRESENT_MASK) >> 4));1559}1560 1561/**1562 * mpi3mr_encldev_add_chg_evt_bh - Enclosure evt bottomhalf1563 * @mrioc: Adapter instance reference1564 * @fwevt: Firmware event reference1565 *1566 * Prints information about the Enclosure device status or1567 * Enclosure add events if logging is enabled and add or remove1568 * the enclosure from the controller's internal list of1569 * enclosures.1570 *1571 * Return: Nothing.1572 */1573static void mpi3mr_encldev_add_chg_evt_bh(struct mpi3mr_ioc *mrioc,1574	struct mpi3mr_fwevt *fwevt)1575{1576	struct mpi3mr_enclosure_node *enclosure_dev = NULL;1577	struct mpi3_enclosure_page0 *encl_pg0;1578	u16 encl_handle;1579	u8 added, present;1580 1581	encl_pg0 = (struct mpi3_enclosure_page0 *) fwevt->event_data;1582	added = (fwevt->event_id == MPI3_EVENT_ENCL_DEVICE_ADDED) ? 1 : 0;1583	mpi3mr_encldev_add_chg_evt_debug(mrioc, encl_pg0, added);1584 1585 1586	encl_handle = le16_to_cpu(encl_pg0->enclosure_handle);1587	present = ((le16_to_cpu(encl_pg0->flags) &1588	      MPI3_ENCLS0_FLAGS_ENCL_DEV_PRESENT_MASK) >> 4);1589 1590	if (encl_handle)1591		enclosure_dev = mpi3mr_enclosure_find_by_handle(mrioc,1592		    encl_handle);1593	if (!enclosure_dev && present) {1594		enclosure_dev =1595			kzalloc(sizeof(struct mpi3mr_enclosure_node),1596			    GFP_KERNEL);1597		if (!enclosure_dev)1598			return;1599		list_add_tail(&enclosure_dev->list,1600		    &mrioc->enclosure_list);1601	}1602	if (enclosure_dev) {1603		if (!present) {1604			list_del(&enclosure_dev->list);1605			kfree(enclosure_dev);1606		} else1607			memcpy(&enclosure_dev->pg0, encl_pg0,1608			    sizeof(enclosure_dev->pg0));1609 1610	}1611}1612 1613/**1614 * mpi3mr_sastopochg_evt_debug - SASTopoChange details1615 * @mrioc: Adapter instance reference1616 * @event_data: SAS topology change list event data1617 *1618 * Prints information about the SAS topology change event.1619 *1620 * Return: Nothing.1621 */1622static void1623mpi3mr_sastopochg_evt_debug(struct mpi3mr_ioc *mrioc,1624	struct mpi3_event_data_sas_topology_change_list *event_data)1625{1626	int i;1627	u16 handle;1628	u8 reason_code, phy_number;1629	char *status_str = NULL;1630	u8 link_rate, prev_link_rate;1631 1632	switch (event_data->exp_status) {1633	case MPI3_EVENT_SAS_TOPO_ES_NOT_RESPONDING:1634		status_str = "remove";1635		break;1636	case MPI3_EVENT_SAS_TOPO_ES_RESPONDING:1637		status_str =  "responding";1638		break;1639	case MPI3_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:1640		status_str = "remove delay";1641		break;1642	case MPI3_EVENT_SAS_TOPO_ES_NO_EXPANDER:1643		status_str = "direct attached";1644		break;1645	default:1646		status_str = "unknown status";1647		break;1648	}1649	ioc_info(mrioc, "%s :sas topology change: (%s)\n",1650	    __func__, status_str);1651	ioc_info(mrioc,1652	    "%s :\texpander_handle(0x%04x), port(%d), enclosure_handle(0x%04x) start_phy(%02d), num_entries(%d)\n",1653	    __func__, le16_to_cpu(event_data->expander_dev_handle),1654	    event_data->io_unit_port,1655	    le16_to_cpu(event_data->enclosure_handle),1656	    event_data->start_phy_num, event_data->num_entries);1657	for (i = 0; i < event_data->num_entries; i++) {1658		handle = le16_to_cpu(event_data->phy_entry[i].attached_dev_handle);1659		if (!handle)1660			continue;1661		phy_number = event_data->start_phy_num + i;1662		reason_code = event_data->phy_entry[i].status &1663		    MPI3_EVENT_SAS_TOPO_PHY_RC_MASK;1664		switch (reason_code) {1665		case MPI3_EVENT_SAS_TOPO_PHY_RC_TARG_NOT_RESPONDING:1666			status_str = "target remove";1667			break;1668		case MPI3_EVENT_SAS_TOPO_PHY_RC_DELAY_NOT_RESPONDING:1669			status_str = "delay target remove";1670			break;1671		case MPI3_EVENT_SAS_TOPO_PHY_RC_PHY_CHANGED:1672			status_str = "link status change";1673			break;1674		case MPI3_EVENT_SAS_TOPO_PHY_RC_NO_CHANGE:1675			status_str = "link status no change";1676			break;1677		case MPI3_EVENT_SAS_TOPO_PHY_RC_RESPONDING:1678			status_str = "target responding";1679			break;1680		default:1681			status_str = "unknown";1682			break;1683		}1684		link_rate = event_data->phy_entry[i].link_rate >> 4;1685		prev_link_rate = event_data->phy_entry[i].link_rate & 0xF;1686		ioc_info(mrioc,1687		    "%s :\tphy(%02d), attached_handle(0x%04x): %s: link rate: new(0x%02x), old(0x%02x)\n",1688		    __func__, phy_number, handle, status_str, link_rate,1689		    prev_link_rate);1690	}1691}1692 1693/**1694 * mpi3mr_sastopochg_evt_bh - SASTopologyChange evt bottomhalf1695 * @mrioc: Adapter instance reference1696 * @fwevt: Firmware event reference1697 *1698 * Prints information about the SAS topology change event and1699 * for "not responding" event code, removes the device from the1700 * upper layers.1701 *1702 * Return: Nothing.1703 */1704static void mpi3mr_sastopochg_evt_bh(struct mpi3mr_ioc *mrioc,1705	struct mpi3mr_fwevt *fwevt)1706{1707	struct mpi3_event_data_sas_topology_change_list *event_data =1708	    (struct mpi3_event_data_sas_topology_change_list *)fwevt->event_data;1709	int i;1710	u16 handle;1711	u8 reason_code;1712	u64 exp_sas_address = 0, parent_sas_address = 0;1713	struct mpi3mr_hba_port *hba_port = NULL;1714	struct mpi3mr_tgt_dev *tgtdev = NULL;1715	struct mpi3mr_sas_node *sas_expander = NULL;1716	unsigned long flags;1717	u8 link_rate, prev_link_rate, parent_phy_number;1718 1719	mpi3mr_sastopochg_evt_debug(mrioc, event_data);1720	if (mrioc->sas_transport_enabled) {1721		hba_port = mpi3mr_get_hba_port_by_id(mrioc,1722		    event_data->io_unit_port);1723		if (le16_to_cpu(event_data->expander_dev_handle)) {1724			spin_lock_irqsave(&mrioc->sas_node_lock, flags);1725			sas_expander = __mpi3mr_expander_find_by_handle(mrioc,1726			    le16_to_cpu(event_data->expander_dev_handle));1727			if (sas_expander) {1728				exp_sas_address = sas_expander->sas_address;1729				hba_port = sas_expander->hba_port;1730			}1731			spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);1732			parent_sas_address = exp_sas_address;1733		} else1734			parent_sas_address = mrioc->sas_hba.sas_address;1735	}1736 1737	for (i = 0; i < event_data->num_entries; i++) {1738		if (fwevt->discard)1739			return;1740		handle = le16_to_cpu(event_data->phy_entry[i].attached_dev_handle);1741		if (!handle)1742			continue;1743		tgtdev = mpi3mr_get_tgtdev_by_handle(mrioc, handle);1744		if (!tgtdev)1745			continue;1746 1747		reason_code = event_data->phy_entry[i].status &1748		    MPI3_EVENT_SAS_TOPO_PHY_RC_MASK;1749 1750		switch (reason_code) {1751		case MPI3_EVENT_SAS_TOPO_PHY_RC_TARG_NOT_RESPONDING:1752			if (tgtdev->host_exposed)1753				mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev);1754			mpi3mr_tgtdev_del_from_list(mrioc, tgtdev, false);1755			mpi3mr_tgtdev_put(tgtdev);1756			break;1757		case MPI3_EVENT_SAS_TOPO_PHY_RC_RESPONDING:1758		case MPI3_EVENT_SAS_TOPO_PHY_RC_PHY_CHANGED:1759		case MPI3_EVENT_SAS_TOPO_PHY_RC_NO_CHANGE:1760		{1761			if (!mrioc->sas_transport_enabled || tgtdev->non_stl1762			    || tgtdev->is_hidden)1763				break;1764			link_rate = event_data->phy_entry[i].link_rate >> 4;1765			prev_link_rate = event_data->phy_entry[i].link_rate & 0xF;1766			if (link_rate == prev_link_rate)1767				break;1768			if (!parent_sas_address)1769				break;1770			parent_phy_number = event_data->start_phy_num + i;1771			mpi3mr_update_links(mrioc, parent_sas_address, handle,1772			    parent_phy_number, link_rate, hba_port);1773			break;1774		}1775		default:1776			break;1777		}1778		if (tgtdev)1779			mpi3mr_tgtdev_put(tgtdev);1780	}1781 1782	if (mrioc->sas_transport_enabled && (event_data->exp_status ==1783	    MPI3_EVENT_SAS_TOPO_ES_NOT_RESPONDING)) {1784		if (sas_expander)1785			mpi3mr_expander_remove(mrioc, exp_sas_address,1786			    hba_port);1787	}1788}1789 1790/**1791 * mpi3mr_pcietopochg_evt_debug - PCIeTopoChange details1792 * @mrioc: Adapter instance reference1793 * @event_data: PCIe topology change list event data1794 *1795 * Prints information about the PCIe topology change event.1796 *1797 * Return: Nothing.1798 */1799static void1800mpi3mr_pcietopochg_evt_debug(struct mpi3mr_ioc *mrioc,1801	struct mpi3_event_data_pcie_topology_change_list *event_data)1802{1803	int i;1804	u16 handle;1805	u16 reason_code;1806	u8 port_number;1807	char *status_str = NULL;1808	u8 link_rate, prev_link_rate;1809 1810	switch (event_data->switch_status) {1811	case MPI3_EVENT_PCIE_TOPO_SS_NOT_RESPONDING:1812		status_str = "remove";1813		break;1814	case MPI3_EVENT_PCIE_TOPO_SS_RESPONDING:1815		status_str =  "responding";1816		break;1817	case MPI3_EVENT_PCIE_TOPO_SS_DELAY_NOT_RESPONDING:1818		status_str = "remove delay";1819		break;1820	case MPI3_EVENT_PCIE_TOPO_SS_NO_PCIE_SWITCH:1821		status_str = "direct attached";1822		break;1823	default:1824		status_str = "unknown status";1825		break;1826	}1827	ioc_info(mrioc, "%s :pcie topology change: (%s)\n",1828	    __func__, status_str);1829	ioc_info(mrioc,1830	    "%s :\tswitch_handle(0x%04x), enclosure_handle(0x%04x) start_port(%02d), num_entries(%d)\n",1831	    __func__, le16_to_cpu(event_data->switch_dev_handle),1832	    le16_to_cpu(event_data->enclosure_handle),1833	    event_data->start_port_num, event_data->num_entries);1834	for (i = 0; i < event_data->num_entries; i++) {1835		handle =1836		    le16_to_cpu(event_data->port_entry[i].attached_dev_handle);1837		if (!handle)1838			continue;1839		port_number = event_data->start_port_num + i;1840		reason_code = event_data->port_entry[i].port_status;1841		switch (reason_code) {1842		case MPI3_EVENT_PCIE_TOPO_PS_NOT_RESPONDING:1843			status_str = "target remove";1844			break;1845		case MPI3_EVENT_PCIE_TOPO_PS_DELAY_NOT_RESPONDING:1846			status_str = "delay target remove";1847			break;1848		case MPI3_EVENT_PCIE_TOPO_PS_PORT_CHANGED:1849			status_str = "link status change";1850			break;1851		case MPI3_EVENT_PCIE_TOPO_PS_NO_CHANGE:1852			status_str = "link status no change";1853			break;1854		case MPI3_EVENT_PCIE_TOPO_PS_RESPONDING:1855			status_str = "target responding";1856			break;1857		default:1858			status_str = "unknown";1859			break;1860		}1861		link_rate = event_data->port_entry[i].current_port_info &1862		    MPI3_EVENT_PCIE_TOPO_PI_RATE_MASK;1863		prev_link_rate = event_data->port_entry[i].previous_port_info &1864		    MPI3_EVENT_PCIE_TOPO_PI_RATE_MASK;1865		ioc_info(mrioc,1866		    "%s :\tport(%02d), attached_handle(0x%04x): %s: link rate: new(0x%02x), old(0x%02x)\n",1867		    __func__, port_number, handle, status_str, link_rate,1868		    prev_link_rate);1869	}1870}1871 1872/**1873 * mpi3mr_pcietopochg_evt_bh - PCIeTopologyChange evt bottomhalf1874 * @mrioc: Adapter instance reference1875 * @fwevt: Firmware event reference1876 *1877 * Prints information about the PCIe topology change event and1878 * for "not responding" event code, removes the device from the1879 * upper layers.1880 *1881 * Return: Nothing.1882 */1883static void mpi3mr_pcietopochg_evt_bh(struct mpi3mr_ioc *mrioc,1884	struct mpi3mr_fwevt *fwevt)1885{1886	struct mpi3_event_data_pcie_topology_change_list *event_data =1887	    (struct mpi3_event_data_pcie_topology_change_list *)fwevt->event_data;1888	int i;1889	u16 handle;1890	u8 reason_code;1891	struct mpi3mr_tgt_dev *tgtdev = NULL;1892 1893	mpi3mr_pcietopochg_evt_debug(mrioc, event_data);1894 1895	for (i = 0; i < event_data->num_entries; i++) {1896		if (fwevt->discard)1897			return;1898		handle =1899		    le16_to_cpu(event_data->port_entry[i].attached_dev_handle);1900		if (!handle)1901			continue;1902		tgtdev = mpi3mr_get_tgtdev_by_handle(mrioc, handle);1903		if (!tgtdev)1904			continue;1905 1906		reason_code = event_data->port_entry[i].port_status;1907 1908		switch (reason_code) {1909		case MPI3_EVENT_PCIE_TOPO_PS_NOT_RESPONDING:1910			if (tgtdev->host_exposed)1911				mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev);1912			mpi3mr_tgtdev_del_from_list(mrioc, tgtdev, false);1913			mpi3mr_tgtdev_put(tgtdev);1914			break;1915		default:1916			break;1917		}1918		if (tgtdev)1919			mpi3mr_tgtdev_put(tgtdev);1920	}1921}1922 1923/**1924 * mpi3mr_logdata_evt_bh -  Log data event bottomhalf1925 * @mrioc: Adapter instance reference1926 * @fwevt: Firmware event reference1927 *1928 * Extracts the event data and calls application interfacing1929 * function to process the event further.1930 *1931 * Return: Nothing.1932 */1933static void mpi3mr_logdata_evt_bh(struct mpi3mr_ioc *mrioc,1934	struct mpi3mr_fwevt *fwevt)1935{1936	mpi3mr_app_save_logdata(mrioc, fwevt->event_data,1937	    fwevt->event_data_size);1938}1939 1940/**1941 * mpi3mr_update_sdev_qd - Update SCSI device queue depath1942 * @sdev: SCSI device reference1943 * @data: Queue depth reference1944 *1945 * This is an iterator function called for each SCSI device in a1946 * target to update the QD of each SCSI device.1947 *1948 * Return: Nothing.1949 */1950static void mpi3mr_update_sdev_qd(struct scsi_device *sdev, void *data)1951{1952	u16 *q_depth = (u16 *)data;1953 1954	scsi_change_queue_depth(sdev, (int)*q_depth);1955	sdev->max_queue_depth = sdev->queue_depth;1956}1957 1958/**1959 * mpi3mr_set_qd_for_all_vd_in_tg -set QD for TG VDs1960 * @mrioc: Adapter instance reference1961 * @tg: Throttle group information pointer1962 *1963 * Accessor to reduce QD for each device associated with the1964 * given throttle group.1965 *1966 * Return: None.1967 */1968static void mpi3mr_set_qd_for_all_vd_in_tg(struct mpi3mr_ioc *mrioc,1969	struct mpi3mr_throttle_group_info *tg)1970{1971	unsigned long flags;1972	struct mpi3mr_tgt_dev *tgtdev;1973	struct mpi3mr_stgt_priv_data *tgt_priv;1974 1975 1976	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);1977	list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) {1978		if (tgtdev->starget && tgtdev->starget->hostdata) {1979			tgt_priv = tgtdev->starget->hostdata;1980			if (tgt_priv->throttle_group == tg) {1981				dprint_event_bh(mrioc,1982				    "updating qd due to throttling for persist_id(%d) original_qd(%d), reduced_qd (%d)\n",1983				    tgt_priv->perst_id, tgtdev->q_depth,1984				    tg->modified_qd);1985				starget_for_each_device(tgtdev->starget,1986				    (void *)&tg->modified_qd,1987				    mpi3mr_update_sdev_qd);1988			}1989		}1990	}1991	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);1992}1993 1994/**1995 * mpi3mr_fwevt_bh - Firmware event bottomhalf handler1996 * @mrioc: Adapter instance reference1997 * @fwevt: Firmware event reference1998 *1999 * Identifies the firmware event and calls corresponding bottomg2000 * half handler and sends event acknowledgment if required.2001 *2002 * Return: Nothing.2003 */2004static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc,2005	struct mpi3mr_fwevt *fwevt)2006{2007	struct mpi3_device_page0 *dev_pg0 = NULL;2008	u16 perst_id, handle, dev_info;2009	struct mpi3_device0_sas_sata_format *sasinf = NULL;2010	unsigned int timeout;2011 2012	mpi3mr_fwevt_del_from_list(mrioc, fwevt);2013	mrioc->current_event = fwevt;2014 2015	if (mrioc->stop_drv_processing)2016		goto out;2017 2018	if (mrioc->unrecoverable) {2019		dprint_event_bh(mrioc,2020		    "ignoring event(0x%02x) in bottom half handler due to unrecoverable controller\n",2021		    fwevt->event_id);2022		goto out;2023	}2024 2025	if (!fwevt->process_evt)2026		goto evt_ack;2027 2028	switch (fwevt->event_id) {2029	case MPI3_EVENT_DEVICE_ADDED:2030	{2031		dev_pg0 = (struct mpi3_device_page0 *)fwevt->event_data;2032		perst_id = le16_to_cpu(dev_pg0->persistent_id);2033		handle = le16_to_cpu(dev_pg0->dev_handle);2034		if (perst_id != MPI3_DEVICE0_PERSISTENTID_INVALID)2035			mpi3mr_report_tgtdev_to_host(mrioc, perst_id);2036		else if (mrioc->sas_transport_enabled &&2037		    (dev_pg0->device_form == MPI3_DEVICE_DEVFORM_SAS_SATA)) {2038			sasinf = &dev_pg0->device_specific.sas_sata_format;2039			dev_info = le16_to_cpu(sasinf->device_info);2040			if (!mrioc->sas_hba.num_phys)2041				mpi3mr_sas_host_add(mrioc);2042			else2043				mpi3mr_sas_host_refresh(mrioc);2044 2045			if (mpi3mr_is_expander_device(dev_info))2046				mpi3mr_expander_add(mrioc, handle);2047		}2048		break;2049	}2050	case MPI3_EVENT_DEVICE_INFO_CHANGED:2051	{2052		dev_pg0 = (struct mpi3_device_page0 *)fwevt->event_data;2053		perst_id = le16_to_cpu(dev_pg0->persistent_id);2054		if (perst_id != MPI3_DEVICE0_PERSISTENTID_INVALID)2055			mpi3mr_devinfochg_evt_bh(mrioc, dev_pg0);2056		break;2057	}2058	case MPI3_EVENT_DEVICE_STATUS_CHANGE:2059	{2060		mpi3mr_devstatuschg_evt_bh(mrioc, fwevt);2061		break;2062	}2063	case MPI3_EVENT_ENCL_DEVICE_ADDED:2064	case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE:2065	{2066		mpi3mr_encldev_add_chg_evt_bh(mrioc, fwevt);2067		break;2068	}2069 2070	case MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST:2071	{2072		mpi3mr_sastopochg_evt_bh(mrioc, fwevt);2073		break;2074	}2075	case MPI3_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:2076	{2077		mpi3mr_pcietopochg_evt_bh(mrioc, fwevt);2078		break;2079	}2080	case MPI3_EVENT_LOG_DATA:2081	{2082		mpi3mr_logdata_evt_bh(mrioc, fwevt);2083		break;2084	}2085	case MPI3MR_DRIVER_EVENT_TG_QD_REDUCTION:2086	{2087		struct mpi3mr_throttle_group_info *tg;2088 2089		tg = *(struct mpi3mr_throttle_group_info **)fwevt->event_data;2090		dprint_event_bh(mrioc,2091		    "qd reduction event processed for tg_id(%d) reduction_needed(%d)\n",2092		    tg->id, tg->need_qd_reduction);2093		if (tg->need_qd_reduction) {2094			mpi3mr_set_qd_for_all_vd_in_tg(mrioc, tg);2095			tg->need_qd_reduction = 0;2096		}2097		break;2098	}2099	case MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH:2100	{2101		timeout = MPI3MR_RESET_TIMEOUT * 2;2102		while ((mrioc->device_refresh_on || mrioc->block_on_pci_err) &&2103		    !mrioc->unrecoverable && !mrioc->pci_err_recovery) {2104			msleep(500);2105			if (!timeout--) {2106				mrioc->unrecoverable = 1;2107				break;2108			}2109		}2110 2111		if (mrioc->unrecoverable || mrioc->pci_err_recovery)2112			break;2113 2114		dprint_event_bh(mrioc,2115		    "scan for non responding and newly added devices after soft reset started\n");2116		if (mrioc->sas_transport_enabled) {2117			mpi3mr_refresh_sas_ports(mrioc);2118			mpi3mr_refresh_expanders(mrioc);2119		}2120		mpi3mr_refresh_tgtdevs(mrioc);2121		ioc_info(mrioc,2122		    "scan for non responding and newly added devices after soft reset completed\n");2123		break;2124	}2125	case MPI3MR_DRIVER_EVENT_PROCESS_TRIGGER:2126	{2127		mpi3mr_process_trigger_data_event_bh(mrioc,2128		    (struct trigger_event_data *)fwevt->event_data);2129		break;2130	}2131	default:2132		break;2133	}2134 2135evt_ack:2136	if (fwevt->send_ack)2137		mpi3mr_process_event_ack(mrioc, fwevt->event_id,2138		    fwevt->evt_ctx);2139out:2140	/* Put fwevt reference count to neutralize kref_init increment */2141	mpi3mr_fwevt_put(fwevt);2142	mrioc->current_event = NULL;2143}2144 2145/**2146 * mpi3mr_fwevt_worker - Firmware event worker2147 * @work: Work struct containing firmware event2148 *2149 * Extracts the firmware event and calls mpi3mr_fwevt_bh.2150 *2151 * Return: Nothing.2152 */2153static void mpi3mr_fwevt_worker(struct work_struct *work)2154{2155	struct mpi3mr_fwevt *fwevt = container_of(work, struct mpi3mr_fwevt,2156	    work);2157	mpi3mr_fwevt_bh(fwevt->mrioc, fwevt);2158	/*2159	 * Put fwevt reference count after2160	 * dequeuing it from worker queue2161	 */2162	mpi3mr_fwevt_put(fwevt);2163}2164 2165/**2166 * mpi3mr_create_tgtdev - Create and add a target device2167 * @mrioc: Adapter instance reference2168 * @dev_pg0: Device Page 0 data2169 *2170 * If the device specified by the device page 0 data is not2171 * present in the driver's internal list, allocate the memory2172 * for the device, populate the data and add to the list, else2173 * update the device data.  The key is persistent ID.2174 *2175 * Return: 0 on success, -ENOMEM on memory allocation failure2176 */2177static int mpi3mr_create_tgtdev(struct mpi3mr_ioc *mrioc,2178	struct mpi3_device_page0 *dev_pg0)2179{2180	int retval = 0;2181	struct mpi3mr_tgt_dev *tgtdev = NULL;2182	u16 perst_id = 0;2183	unsigned long flags;2184 2185	perst_id = le16_to_cpu(dev_pg0->persistent_id);2186	if (perst_id == MPI3_DEVICE0_PERSISTENTID_INVALID)2187		return retval;2188 2189	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);2190	tgtdev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, perst_id);2191	if (tgtdev)2192		tgtdev->state = MPI3MR_DEV_CREATED;2193	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);2194 2195	if (tgtdev) {2196		mpi3mr_update_tgtdev(mrioc, tgtdev, dev_pg0, true);2197		mpi3mr_tgtdev_put(tgtdev);2198	} else {2199		tgtdev = mpi3mr_alloc_tgtdev();2200		if (!tgtdev)2201			return -ENOMEM;2202		mpi3mr_update_tgtdev(mrioc, tgtdev, dev_pg0, true);2203		mpi3mr_tgtdev_add_to_list(mrioc, tgtdev);2204	}2205 2206	return retval;2207}2208 2209/**2210 * mpi3mr_flush_delayed_cmd_lists - Flush pending commands2211 * @mrioc: Adapter instance reference2212 *2213 * Flush pending commands in the delayed lists due to a2214 * controller reset or driver removal as a cleanup.2215 *2216 * Return: Nothing2217 */2218void mpi3mr_flush_delayed_cmd_lists(struct mpi3mr_ioc *mrioc)2219{2220	struct delayed_dev_rmhs_node *_rmhs_node;2221	struct delayed_evt_ack_node *_evtack_node;2222 2223	dprint_reset(mrioc, "flushing delayed dev_remove_hs commands\n");2224	while (!list_empty(&mrioc->delayed_rmhs_list)) {2225		_rmhs_node = list_entry(mrioc->delayed_rmhs_list.next,2226		    struct delayed_dev_rmhs_node, list);2227		list_del(&_rmhs_node->list);2228		kfree(_rmhs_node);2229	}2230	dprint_reset(mrioc, "flushing delayed event ack commands\n");2231	while (!list_empty(&mrioc->delayed_evtack_cmds_list)) {2232		_evtack_node = list_entry(mrioc->delayed_evtack_cmds_list.next,2233		    struct delayed_evt_ack_node, list);2234		list_del(&_evtack_node->list);2235		kfree(_evtack_node);2236	}2237}2238 2239/**2240 * mpi3mr_dev_rmhs_complete_iou - Device removal IOUC completion2241 * @mrioc: Adapter instance reference2242 * @drv_cmd: Internal command tracker2243 *2244 * Issues a target reset TM to the firmware from the device2245 * removal TM pend list or retry the removal handshake sequence2246 * based on the IOU control request IOC status.2247 *2248 * Return: Nothing2249 */2250static void mpi3mr_dev_rmhs_complete_iou(struct mpi3mr_ioc *mrioc,2251	struct mpi3mr_drv_cmd *drv_cmd)2252{2253	u16 cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_DEVRMCMD_MIN;2254	struct delayed_dev_rmhs_node *delayed_dev_rmhs = NULL;2255 2256	if (drv_cmd->state & MPI3MR_CMD_RESET)2257		goto clear_drv_cmd;2258 2259	ioc_info(mrioc,2260	    "%s :dev_rmhs_iouctrl_complete:handle(0x%04x), ioc_status(0x%04x), loginfo(0x%08x)\n",2261	    __func__, drv_cmd->dev_handle, drv_cmd->ioc_status,2262	    drv_cmd->ioc_loginfo);2263	if (drv_cmd->ioc_status != MPI3_IOCSTATUS_SUCCESS) {2264		if (drv_cmd->retry_count < MPI3MR_DEV_RMHS_RETRY_COUNT) {2265			drv_cmd->retry_count++;2266			ioc_info(mrioc,2267			    "%s :dev_rmhs_iouctrl_complete: handle(0x%04x)retrying handshake retry=%d\n",2268			    __func__, drv_cmd->dev_handle,2269			    drv_cmd->retry_count);2270			mpi3mr_dev_rmhs_send_tm(mrioc, drv_cmd->dev_handle,2271			    drv_cmd, drv_cmd->iou_rc);2272			return;2273		}2274		ioc_err(mrioc,2275		    "%s :dev removal handshake failed after all retries: handle(0x%04x)\n",2276		    __func__, drv_cmd->dev_handle);2277	} else {2278		ioc_info(mrioc,2279		    "%s :dev removal handshake completed successfully: handle(0x%04x)\n",2280		    __func__, drv_cmd->dev_handle);2281		clear_bit(drv_cmd->dev_handle, mrioc->removepend_bitmap);2282	}2283 2284	if (!list_empty(&mrioc->delayed_rmhs_list)) {2285		delayed_dev_rmhs = list_entry(mrioc->delayed_rmhs_list.next,2286		    struct delayed_dev_rmhs_node, list);2287		drv_cmd->dev_handle = delayed_dev_rmhs->handle;2288		drv_cmd->retry_count = 0;2289		drv_cmd->iou_rc = delayed_dev_rmhs->iou_rc;2290		ioc_info(mrioc,2291		    "%s :dev_rmhs_iouctrl_complete: processing delayed TM: handle(0x%04x)\n",2292		    __func__, drv_cmd->dev_handle);2293		mpi3mr_dev_rmhs_send_tm(mrioc, drv_cmd->dev_handle, drv_cmd,2294		    drv_cmd->iou_rc);2295		list_del(&delayed_dev_rmhs->list);2296		kfree(delayed_dev_rmhs);2297		return;2298	}2299 2300clear_drv_cmd:2301	drv_cmd->state = MPI3MR_CMD_NOTUSED;2302	drv_cmd->callback = NULL;2303	drv_cmd->retry_count = 0;2304	drv_cmd->dev_handle = MPI3MR_INVALID_DEV_HANDLE;2305	clear_bit(cmd_idx, mrioc->devrem_bitmap);2306}2307 2308/**2309 * mpi3mr_dev_rmhs_complete_tm - Device removal TM completion2310 * @mrioc: Adapter instance reference2311 * @drv_cmd: Internal command tracker2312 *2313 * Issues a target reset TM to the firmware from the device2314 * removal TM pend list or issue IO unit control request as2315 * part of device removal or hidden acknowledgment handshake.2316 *2317 * Return: Nothing2318 */2319static void mpi3mr_dev_rmhs_complete_tm(struct mpi3mr_ioc *mrioc,2320	struct mpi3mr_drv_cmd *drv_cmd)2321{2322	struct mpi3_iounit_control_request iou_ctrl;2323	u16 cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_DEVRMCMD_MIN;2324	struct mpi3_scsi_task_mgmt_reply *tm_reply = NULL;2325	int retval;2326 2327	if (drv_cmd->state & MPI3MR_CMD_RESET)2328		goto clear_drv_cmd;2329 2330	if (drv_cmd->state & MPI3MR_CMD_REPLY_VALID)2331		tm_reply = (struct mpi3_scsi_task_mgmt_reply *)drv_cmd->reply;2332 2333	if (tm_reply)2334		pr_info(IOCNAME2335		    "dev_rmhs_tr_complete:handle(0x%04x), ioc_status(0x%04x), loginfo(0x%08x), term_count(%d)\n",2336		    mrioc->name, drv_cmd->dev_handle, drv_cmd->ioc_status,2337		    drv_cmd->ioc_loginfo,2338		    le32_to_cpu(tm_reply->termination_count));2339 2340	pr_info(IOCNAME "Issuing IOU CTL: handle(0x%04x) dev_rmhs idx(%d)\n",2341	    mrioc->name, drv_cmd->dev_handle, cmd_idx);2342 2343	memset(&iou_ctrl, 0, sizeof(iou_ctrl));2344 2345	drv_cmd->state = MPI3MR_CMD_PENDING;2346	drv_cmd->is_waiting = 0;2347	drv_cmd->callback = mpi3mr_dev_rmhs_complete_iou;2348	iou_ctrl.operation = drv_cmd->iou_rc;2349	iou_ctrl.param16[0] = cpu_to_le16(drv_cmd->dev_handle);2350	iou_ctrl.host_tag = cpu_to_le16(drv_cmd->host_tag);2351	iou_ctrl.function = MPI3_FUNCTION_IO_UNIT_CONTROL;2352 2353	retval = mpi3mr_admin_request_post(mrioc, &iou_ctrl, sizeof(iou_ctrl),2354	    1);2355	if (retval) {2356		pr_err(IOCNAME "Issue DevRmHsTMIOUCTL: Admin post failed\n",2357		    mrioc->name);2358		goto clear_drv_cmd;2359	}2360 2361	return;2362clear_drv_cmd:2363	drv_cmd->state = MPI3MR_CMD_NOTUSED;2364	drv_cmd->callback = NULL;2365	drv_cmd->dev_handle = MPI3MR_INVALID_DEV_HANDLE;2366	drv_cmd->retry_count = 0;2367	clear_bit(cmd_idx, mrioc->devrem_bitmap);2368}2369 2370/**2371 * mpi3mr_dev_rmhs_send_tm - Issue TM for device removal2372 * @mrioc: Adapter instance reference2373 * @handle: Device handle2374 * @cmdparam: Internal command tracker2375 * @iou_rc: IO unit reason code2376 *2377 * Issues a target reset TM to the firmware or add it to a pend2378 * list as part of device removal or hidden acknowledgment2379 * handshake.2380 *2381 * Return: Nothing2382 */2383static void mpi3mr_dev_rmhs_send_tm(struct mpi3mr_ioc *mrioc, u16 handle,2384	struct mpi3mr_drv_cmd *cmdparam, u8 iou_rc)2385{2386	struct mpi3_scsi_task_mgmt_request tm_req;2387	int retval = 0;2388	u16 cmd_idx = MPI3MR_NUM_DEVRMCMD;2389	u8 retrycount = 5;2390	struct mpi3mr_drv_cmd *drv_cmd = cmdparam;2391	struct delayed_dev_rmhs_node *delayed_dev_rmhs = NULL;2392	struct mpi3mr_tgt_dev *tgtdev = NULL;2393	unsigned long flags;2394 2395	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);2396	tgtdev = __mpi3mr_get_tgtdev_by_handle(mrioc, handle);2397	if (tgtdev && (iou_rc == MPI3_CTRL_OP_REMOVE_DEVICE))2398		tgtdev->state = MPI3MR_DEV_REMOVE_HS_STARTED;2399	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);2400 2401	if (drv_cmd)2402		goto issue_cmd;2403	do {2404		cmd_idx = find_first_zero_bit(mrioc->devrem_bitmap,2405		    MPI3MR_NUM_DEVRMCMD);2406		if (cmd_idx < MPI3MR_NUM_DEVRMCMD) {2407			if (!test_and_set_bit(cmd_idx, mrioc->devrem_bitmap))2408				break;2409			cmd_idx = MPI3MR_NUM_DEVRMCMD;2410		}2411	} while (retrycount--);2412 2413	if (cmd_idx >= MPI3MR_NUM_DEVRMCMD) {2414		delayed_dev_rmhs = kzalloc(sizeof(*delayed_dev_rmhs),2415		    GFP_ATOMIC);2416		if (!delayed_dev_rmhs)2417			return;2418		INIT_LIST_HEAD(&delayed_dev_rmhs->list);2419		delayed_dev_rmhs->handle = handle;2420		delayed_dev_rmhs->iou_rc = iou_rc;2421		list_add_tail(&delayed_dev_rmhs->list,2422		    &mrioc->delayed_rmhs_list);2423		ioc_info(mrioc, "%s :DevRmHs: tr:handle(0x%04x) is postponed\n",2424		    __func__, handle);2425		return;2426	}2427	drv_cmd = &mrioc->dev_rmhs_cmds[cmd_idx];2428 2429issue_cmd:2430	cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_DEVRMCMD_MIN;2431	ioc_info(mrioc,2432	    "%s :Issuing TR TM: for devhandle 0x%04x with dev_rmhs %d\n",2433	    __func__, handle, cmd_idx);2434 2435	memset(&tm_req, 0, sizeof(tm_req));2436	if (drv_cmd->state & MPI3MR_CMD_PENDING) {2437		ioc_err(mrioc, "%s :Issue TM: Command is in use\n", __func__);2438		goto out;2439	}2440	drv_cmd->state = MPI3MR_CMD_PENDING;2441	drv_cmd->is_waiting = 0;2442	drv_cmd->callback = mpi3mr_dev_rmhs_complete_tm;2443	drv_cmd->dev_handle = handle;2444	drv_cmd->iou_rc = iou_rc;2445	tm_req.dev_handle = cpu_to_le16(handle);2446	tm_req.task_type = MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET;2447	tm_req.host_tag = cpu_to_le16(drv_cmd->host_tag);2448	tm_req.task_host_tag = cpu_to_le16(MPI3MR_HOSTTAG_INVALID);2449	tm_req.function = MPI3_FUNCTION_SCSI_TASK_MGMT;2450 2451	set_bit(handle, mrioc->removepend_bitmap);2452	retval = mpi3mr_admin_request_post(mrioc, &tm_req, sizeof(tm_req), 1);2453	if (retval) {2454		ioc_err(mrioc, "%s :Issue DevRmHsTM: Admin Post failed\n",2455		    __func__);2456		goto out_failed;2457	}2458out:2459	return;2460out_failed:2461	drv_cmd->state = MPI3MR_CMD_NOTUSED;2462	drv_cmd->callback = NULL;2463	drv_cmd->dev_handle = MPI3MR_INVALID_DEV_HANDLE;2464	drv_cmd->retry_count = 0;2465	clear_bit(cmd_idx, mrioc->devrem_bitmap);2466}2467 2468/**2469 * mpi3mr_complete_evt_ack - event ack request completion2470 * @mrioc: Adapter instance reference2471 * @drv_cmd: Internal command tracker2472 *2473 * This is the completion handler for non blocking event2474 * acknowledgment sent to the firmware and this will issue any2475 * pending event acknowledgment request.2476 *2477 * Return: Nothing2478 */2479static void mpi3mr_complete_evt_ack(struct mpi3mr_ioc *mrioc,2480	struct mpi3mr_drv_cmd *drv_cmd)2481{2482	u16 cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_EVTACKCMD_MIN;2483	struct delayed_evt_ack_node *delayed_evtack = NULL;2484 2485	if (drv_cmd->state & MPI3MR_CMD_RESET)2486		goto clear_drv_cmd;2487 2488	if (drv_cmd->ioc_status != MPI3_IOCSTATUS_SUCCESS) {2489		dprint_event_th(mrioc,2490		    "immediate event ack failed with ioc_status(0x%04x) log_info(0x%08x)\n",2491		    (drv_cmd->ioc_status & MPI3_IOCSTATUS_STATUS_MASK),2492		    drv_cmd->ioc_loginfo);2493	}2494 2495	if (!list_empty(&mrioc->delayed_evtack_cmds_list)) {2496		delayed_evtack =2497			list_entry(mrioc->delayed_evtack_cmds_list.next,2498			    struct delayed_evt_ack_node, list);2499		mpi3mr_send_event_ack(mrioc, delayed_evtack->event, drv_cmd,2500		    delayed_evtack->event_ctx);2501		list_del(&delayed_evtack->list);2502		kfree(delayed_evtack);2503		return;2504	}2505clear_drv_cmd:2506	drv_cmd->state = MPI3MR_CMD_NOTUSED;2507	drv_cmd->callback = NULL;2508	clear_bit(cmd_idx, mrioc->evtack_cmds_bitmap);2509}2510 2511/**2512 * mpi3mr_send_event_ack - Issue event acknwoledgment request2513 * @mrioc: Adapter instance reference2514 * @event: MPI3 event id2515 * @cmdparam: Internal command tracker2516 * @event_ctx: event context2517 *2518 * Issues event acknowledgment request to the firmware if there2519 * is a free command to send the event ack else it to a pend2520 * list so that it will be processed on a completion of a prior2521 * event acknowledgment .2522 *2523 * Return: Nothing2524 */2525static void mpi3mr_send_event_ack(struct mpi3mr_ioc *mrioc, u8 event,2526	struct mpi3mr_drv_cmd *cmdparam, u32 event_ctx)2527{2528	struct mpi3_event_ack_request evtack_req;2529	int retval = 0;2530	u8 retrycount = 5;2531	u16 cmd_idx = MPI3MR_NUM_EVTACKCMD;2532	struct mpi3mr_drv_cmd *drv_cmd = cmdparam;2533	struct delayed_evt_ack_node *delayed_evtack = NULL;2534 2535	if (drv_cmd) {2536		dprint_event_th(mrioc,2537		    "sending delayed event ack in the top half for event(0x%02x), event_ctx(0x%08x)\n",2538		    event, event_ctx);2539		goto issue_cmd;2540	}2541	dprint_event_th(mrioc,2542	    "sending event ack in the top half for event(0x%02x), event_ctx(0x%08x)\n",2543	    event, event_ctx);2544	do {2545		cmd_idx = find_first_zero_bit(mrioc->evtack_cmds_bitmap,2546		    MPI3MR_NUM_EVTACKCMD);2547		if (cmd_idx < MPI3MR_NUM_EVTACKCMD) {2548			if (!test_and_set_bit(cmd_idx,2549			    mrioc->evtack_cmds_bitmap))2550				break;2551			cmd_idx = MPI3MR_NUM_EVTACKCMD;2552		}2553	} while (retrycount--);2554 2555	if (cmd_idx >= MPI3MR_NUM_EVTACKCMD) {2556		delayed_evtack = kzalloc(sizeof(*delayed_evtack),2557		    GFP_ATOMIC);2558		if (!delayed_evtack)2559			return;2560		INIT_LIST_HEAD(&delayed_evtack->list);2561		delayed_evtack->event = event;2562		delayed_evtack->event_ctx = event_ctx;2563		list_add_tail(&delayed_evtack->list,2564		    &mrioc->delayed_evtack_cmds_list);2565		dprint_event_th(mrioc,2566		    "event ack in the top half for event(0x%02x), event_ctx(0x%08x) is postponed\n",2567		    event, event_ctx);2568		return;2569	}2570	drv_cmd = &mrioc->evtack_cmds[cmd_idx];2571 2572issue_cmd:2573	cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_EVTACKCMD_MIN;2574 2575	memset(&evtack_req, 0, sizeof(evtack_req));2576	if (drv_cmd->state & MPI3MR_CMD_PENDING) {2577		dprint_event_th(mrioc,2578		    "sending event ack failed due to command in use\n");2579		goto out;2580	}2581	drv_cmd->state = MPI3MR_CMD_PENDING;2582	drv_cmd->is_waiting = 0;2583	drv_cmd->callback = mpi3mr_complete_evt_ack;2584	evtack_req.host_tag = cpu_to_le16(drv_cmd->host_tag);2585	evtack_req.function = MPI3_FUNCTION_EVENT_ACK;2586	evtack_req.event = event;2587	evtack_req.event_context = cpu_to_le32(event_ctx);2588	retval = mpi3mr_admin_request_post(mrioc, &evtack_req,2589	    sizeof(evtack_req), 1);2590	if (retval) {2591		dprint_event_th(mrioc,2592		    "posting event ack request is failed\n");2593		goto out_failed;2594	}2595 2596	dprint_event_th(mrioc,2597	    "event ack in the top half for event(0x%02x), event_ctx(0x%08x) is posted\n",2598	    event, event_ctx);2599out:2600	return;2601out_failed:2602	drv_cmd->state = MPI3MR_CMD_NOTUSED;2603	drv_cmd->callback = NULL;2604	clear_bit(cmd_idx, mrioc->evtack_cmds_bitmap);2605}2606 2607/**2608 * mpi3mr_pcietopochg_evt_th - PCIETopologyChange evt tophalf2609 * @mrioc: Adapter instance reference2610 * @event_reply: event data2611 *2612 * Checks for the reason code and based on that either block I/O2613 * to device, or unblock I/O to the device, or start the device2614 * removal handshake with reason as remove with the firmware for2615 * PCIe devices.2616 *2617 * Return: Nothing2618 */2619static void mpi3mr_pcietopochg_evt_th(struct mpi3mr_ioc *mrioc,2620	struct mpi3_event_notification_reply *event_reply)2621{2622	struct mpi3_event_data_pcie_topology_change_list *topo_evt =2623	    (struct mpi3_event_data_pcie_topology_change_list *)event_reply->event_data;2624	int i;2625	u16 handle;2626	u8 reason_code;2627	struct mpi3mr_tgt_dev *tgtdev = NULL;2628	struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data = NULL;2629 2630	for (i = 0; i < topo_evt->num_entries; i++) {2631		handle = le16_to_cpu(topo_evt->port_entry[i].attached_dev_handle);2632		if (!handle)2633			continue;2634		reason_code = topo_evt->port_entry[i].port_status;2635		scsi_tgt_priv_data =  NULL;2636		tgtdev = mpi3mr_get_tgtdev_by_handle(mrioc, handle);2637		if (tgtdev && tgtdev->starget && tgtdev->starget->hostdata)2638			scsi_tgt_priv_data = (struct mpi3mr_stgt_priv_data *)2639			    tgtdev->starget->hostdata;2640		switch (reason_code) {2641		case MPI3_EVENT_PCIE_TOPO_PS_NOT_RESPONDING:2642			if (scsi_tgt_priv_data) {2643				scsi_tgt_priv_data->dev_removed = 1;2644				scsi_tgt_priv_data->dev_removedelay = 0;2645				atomic_set(&scsi_tgt_priv_data->block_io, 0);2646			}2647			mpi3mr_dev_rmhs_send_tm(mrioc, handle, NULL,2648			    MPI3_CTRL_OP_REMOVE_DEVICE);2649			break;2650		case MPI3_EVENT_PCIE_TOPO_PS_DELAY_NOT_RESPONDING:2651			if (scsi_tgt_priv_data) {2652				scsi_tgt_priv_data->dev_removedelay = 1;2653				atomic_inc(&scsi_tgt_priv_data->block_io);2654			}2655			break;2656		case MPI3_EVENT_PCIE_TOPO_PS_RESPONDING:2657			if (scsi_tgt_priv_data &&2658			    scsi_tgt_priv_data->dev_removedelay) {2659				scsi_tgt_priv_data->dev_removedelay = 0;2660				atomic_dec_if_positive2661				    (&scsi_tgt_priv_data->block_io);2662			}2663			break;2664		case MPI3_EVENT_PCIE_TOPO_PS_PORT_CHANGED:2665		default:2666			break;2667		}2668		if (tgtdev)2669			mpi3mr_tgtdev_put(tgtdev);2670	}2671}2672 2673/**2674 * mpi3mr_sastopochg_evt_th - SASTopologyChange evt tophalf2675 * @mrioc: Adapter instance reference2676 * @event_reply: event data2677 *2678 * Checks for the reason code and based on that either block I/O2679 * to device, or unblock I/O to the device, or start the device2680 * removal handshake with reason as remove with the firmware for2681 * SAS/SATA devices.2682 *2683 * Return: Nothing2684 */2685static void mpi3mr_sastopochg_evt_th(struct mpi3mr_ioc *mrioc,2686	struct mpi3_event_notification_reply *event_reply)2687{2688	struct mpi3_event_data_sas_topology_change_list *topo_evt =2689	    (struct mpi3_event_data_sas_topology_change_list *)event_reply->event_data;2690	int i;2691	u16 handle;2692	u8 reason_code;2693	struct mpi3mr_tgt_dev *tgtdev = NULL;2694	struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data = NULL;2695 2696	for (i = 0; i < topo_evt->num_entries; i++) {2697		handle = le16_to_cpu(topo_evt->phy_entry[i].attached_dev_handle);2698		if (!handle)2699			continue;2700		reason_code = topo_evt->phy_entry[i].status &2701		    MPI3_EVENT_SAS_TOPO_PHY_RC_MASK;2702		scsi_tgt_priv_data =  NULL;2703		tgtdev = mpi3mr_get_tgtdev_by_handle(mrioc, handle);2704		if (tgtdev && tgtdev->starget && tgtdev->starget->hostdata)2705			scsi_tgt_priv_data = (struct mpi3mr_stgt_priv_data *)2706			    tgtdev->starget->hostdata;2707		switch (reason_code) {2708		case MPI3_EVENT_SAS_TOPO_PHY_RC_TARG_NOT_RESPONDING:2709			if (scsi_tgt_priv_data) {2710				scsi_tgt_priv_data->dev_removed = 1;2711				scsi_tgt_priv_data->dev_removedelay = 0;2712				atomic_set(&scsi_tgt_priv_data->block_io, 0);2713			}2714			mpi3mr_dev_rmhs_send_tm(mrioc, handle, NULL,2715			    MPI3_CTRL_OP_REMOVE_DEVICE);2716			break;2717		case MPI3_EVENT_SAS_TOPO_PHY_RC_DELAY_NOT_RESPONDING:2718			if (scsi_tgt_priv_data) {2719				scsi_tgt_priv_data->dev_removedelay = 1;2720				atomic_inc(&scsi_tgt_priv_data->block_io);2721			}2722			break;2723		case MPI3_EVENT_SAS_TOPO_PHY_RC_RESPONDING:2724			if (scsi_tgt_priv_data &&2725			    scsi_tgt_priv_data->dev_removedelay) {2726				scsi_tgt_priv_data->dev_removedelay = 0;2727				atomic_dec_if_positive2728				    (&scsi_tgt_priv_data->block_io);2729			}2730			break;2731		case MPI3_EVENT_SAS_TOPO_PHY_RC_PHY_CHANGED:2732		default:2733			break;2734		}2735		if (tgtdev)2736			mpi3mr_tgtdev_put(tgtdev);2737	}2738}2739 2740/**2741 * mpi3mr_devstatuschg_evt_th - DeviceStatusChange evt tophalf2742 * @mrioc: Adapter instance reference2743 * @event_reply: event data2744 *2745 * Checks for the reason code and based on that either block I/O2746 * to device, or unblock I/O to the device, or start the device2747 * removal handshake with reason as remove/hide acknowledgment2748 * with the firmware.2749 *2750 * Return: Nothing2751 */2752static void mpi3mr_devstatuschg_evt_th(struct mpi3mr_ioc *mrioc,2753	struct mpi3_event_notification_reply *event_reply)2754{2755	u16 dev_handle = 0;2756	u8 ublock = 0, block = 0, hide = 0, delete = 0, remove = 0;2757	struct mpi3mr_tgt_dev *tgtdev = NULL;2758	struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data = NULL;2759	struct mpi3_event_data_device_status_change *evtdata =2760	    (struct mpi3_event_data_device_status_change *)event_reply->event_data;2761 2762	if (mrioc->stop_drv_processing)2763		goto out;2764 2765	dev_handle = le16_to_cpu(evtdata->dev_handle);2766 2767	switch (evtdata->reason_code) {2768	case MPI3_EVENT_DEV_STAT_RC_INT_DEVICE_RESET_STRT:2769	case MPI3_EVENT_DEV_STAT_RC_INT_IT_NEXUS_RESET_STRT:2770		block = 1;2771		break;2772	case MPI3_EVENT_DEV_STAT_RC_HIDDEN:2773		delete = 1;2774		hide = 1;2775		break;2776	case MPI3_EVENT_DEV_STAT_RC_VD_NOT_RESPONDING:2777		delete = 1;2778		remove = 1;2779		break;2780	case MPI3_EVENT_DEV_STAT_RC_INT_DEVICE_RESET_CMP:2781	case MPI3_EVENT_DEV_STAT_RC_INT_IT_NEXUS_RESET_CMP:2782		ublock = 1;2783		break;2784	default:2785		break;2786	}2787 2788	tgtdev = mpi3mr_get_tgtdev_by_handle(mrioc, dev_handle);2789	if (!tgtdev)2790		goto out;2791	if (hide)2792		tgtdev->is_hidden = hide;2793	if (tgtdev->starget && tgtdev->starget->hostdata) {2794		scsi_tgt_priv_data = (struct mpi3mr_stgt_priv_data *)2795		    tgtdev->starget->hostdata;2796		if (block)2797			atomic_inc(&scsi_tgt_priv_data->block_io);2798		if (delete)2799			scsi_tgt_priv_data->dev_removed = 1;2800		if (ublock)2801			atomic_dec_if_positive(&scsi_tgt_priv_data->block_io);2802	}2803	if (remove)2804		mpi3mr_dev_rmhs_send_tm(mrioc, dev_handle, NULL,2805		    MPI3_CTRL_OP_REMOVE_DEVICE);2806	if (hide)2807		mpi3mr_dev_rmhs_send_tm(mrioc, dev_handle, NULL,2808		    MPI3_CTRL_OP_HIDDEN_ACK);2809 2810out:2811	if (tgtdev)2812		mpi3mr_tgtdev_put(tgtdev);2813}2814 2815/**2816 * mpi3mr_preparereset_evt_th - Prepare for reset event tophalf2817 * @mrioc: Adapter instance reference2818 * @event_reply: event data2819 *2820 * Blocks and unblocks host level I/O based on the reason code2821 *2822 * Return: Nothing2823 */2824static void mpi3mr_preparereset_evt_th(struct mpi3mr_ioc *mrioc,2825	struct mpi3_event_notification_reply *event_reply)2826{2827	struct mpi3_event_data_prepare_for_reset *evtdata =2828	    (struct mpi3_event_data_prepare_for_reset *)event_reply->event_data;2829 2830	if (evtdata->reason_code == MPI3_EVENT_PREPARE_RESET_RC_START) {2831		dprint_event_th(mrioc,2832		    "prepare for reset event top half with rc=start\n");2833		if (mrioc->prepare_for_reset)2834			return;2835		mrioc->prepare_for_reset = 1;2836		mrioc->prepare_for_reset_timeout_counter = 0;2837	} else if (evtdata->reason_code == MPI3_EVENT_PREPARE_RESET_RC_ABORT) {2838		dprint_event_th(mrioc,2839		    "prepare for reset top half with rc=abort\n");2840		mrioc->prepare_for_reset = 0;2841		mrioc->prepare_for_reset_timeout_counter = 0;2842	}2843	if ((event_reply->msg_flags & MPI3_EVENT_NOTIFY_MSGFLAGS_ACK_MASK)2844	    == MPI3_EVENT_NOTIFY_MSGFLAGS_ACK_REQUIRED)2845		mpi3mr_send_event_ack(mrioc, event_reply->event, NULL,2846		    le32_to_cpu(event_reply->event_context));2847}2848 2849/**2850 * mpi3mr_energypackchg_evt_th - Energy pack change evt tophalf2851 * @mrioc: Adapter instance reference2852 * @event_reply: event data2853 *2854 * Identifies the new shutdown timeout value and update.2855 *2856 * Return: Nothing2857 */2858static void mpi3mr_energypackchg_evt_th(struct mpi3mr_ioc *mrioc,2859	struct mpi3_event_notification_reply *event_reply)2860{2861	struct mpi3_event_data_energy_pack_change *evtdata =2862	    (struct mpi3_event_data_energy_pack_change *)event_reply->event_data;2863	u16 shutdown_timeout = le16_to_cpu(evtdata->shutdown_timeout);2864 2865	if (shutdown_timeout <= 0) {2866		ioc_warn(mrioc,2867		    "%s :Invalid Shutdown Timeout received = %d\n",2868		    __func__, shutdown_timeout);2869		return;2870	}2871 2872	ioc_info(mrioc,2873	    "%s :Previous Shutdown Timeout Value = %d New Shutdown Timeout Value = %d\n",2874	    __func__, mrioc->facts.shutdown_timeout, shutdown_timeout);2875	mrioc->facts.shutdown_timeout = shutdown_timeout;2876}2877 2878/**2879 * mpi3mr_cablemgmt_evt_th - Cable management event tophalf2880 * @mrioc: Adapter instance reference2881 * @event_reply: event data2882 *2883 * Displays Cable manegemt event details.2884 *2885 * Return: Nothing2886 */2887static void mpi3mr_cablemgmt_evt_th(struct mpi3mr_ioc *mrioc,2888	struct mpi3_event_notification_reply *event_reply)2889{2890	struct mpi3_event_data_cable_management *evtdata =2891	    (struct mpi3_event_data_cable_management *)event_reply->event_data;2892 2893	switch (evtdata->status) {2894	case MPI3_EVENT_CABLE_MGMT_STATUS_INSUFFICIENT_POWER:2895	{2896		ioc_info(mrioc, "An active cable with receptacle_id %d cannot be powered.\n"2897		    "Devices connected to this cable are not detected.\n"2898		    "This cable requires %d mW of power.\n",2899		    evtdata->receptacle_id,2900		    le32_to_cpu(evtdata->active_cable_power_requirement));2901		break;2902	}2903	case MPI3_EVENT_CABLE_MGMT_STATUS_DEGRADED:2904	{2905		ioc_info(mrioc, "A cable with receptacle_id %d is not running at optimal speed\n",2906		    evtdata->receptacle_id);2907		break;2908	}2909	default:2910		break;2911	}2912}2913 2914/**2915 * mpi3mr_add_event_wait_for_device_refresh - Add Wait for Device Refresh Event2916 * @mrioc: Adapter instance reference2917 *2918 * Add driver specific event to make sure that the driver won't process the2919 * events until all the devices are refreshed during soft reset.2920 *2921 * Return: Nothing2922 */2923void mpi3mr_add_event_wait_for_device_refresh(struct mpi3mr_ioc *mrioc)2924{2925	struct mpi3mr_fwevt *fwevt = NULL;2926 2927	fwevt = mpi3mr_alloc_fwevt(0);2928	if (!fwevt) {2929		dprint_event_th(mrioc,2930		    "failed to schedule bottom half handler for event(0x%02x)\n",2931		    MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH);2932		return;2933	}2934	fwevt->mrioc = mrioc;2935	fwevt->event_id = MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH;2936	fwevt->send_ack = 0;2937	fwevt->process_evt = 1;2938	fwevt->evt_ctx = 0;2939	fwevt->event_data_size = 0;2940	mpi3mr_fwevt_add_to_list(mrioc, fwevt);2941}2942 2943/**2944 * mpi3mr_os_handle_events - Firmware event handler2945 * @mrioc: Adapter instance reference2946 * @event_reply: event data2947 *2948 * Identify whteher the event has to handled and acknowledged2949 * and either process the event in the tophalf and/or schedule a2950 * bottom half through mpi3mr_fwevt_worker.2951 *2952 * Return: Nothing2953 */2954void mpi3mr_os_handle_events(struct mpi3mr_ioc *mrioc,2955	struct mpi3_event_notification_reply *event_reply)2956{2957	u16 evt_type, sz;2958	struct mpi3mr_fwevt *fwevt = NULL;2959	bool ack_req = 0, process_evt_bh = 0;2960 2961	if (mrioc->stop_drv_processing)2962		return;2963 2964	if ((event_reply->msg_flags & MPI3_EVENT_NOTIFY_MSGFLAGS_ACK_MASK)2965	    == MPI3_EVENT_NOTIFY_MSGFLAGS_ACK_REQUIRED)2966		ack_req = 1;2967 2968	evt_type = event_reply->event;2969	mpi3mr_event_trigger(mrioc, event_reply->event);2970 2971	switch (evt_type) {2972	case MPI3_EVENT_DEVICE_ADDED:2973	{2974		struct mpi3_device_page0 *dev_pg0 =2975		    (struct mpi3_device_page0 *)event_reply->event_data;2976		if (mpi3mr_create_tgtdev(mrioc, dev_pg0))2977			ioc_err(mrioc,2978			    "%s :Failed to add device in the device add event\n",2979			    __func__);2980		else2981			process_evt_bh = 1;2982		break;2983	}2984	case MPI3_EVENT_DEVICE_STATUS_CHANGE:2985	{2986		process_evt_bh = 1;2987		mpi3mr_devstatuschg_evt_th(mrioc, event_reply);2988		break;2989	}2990	case MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST:2991	{2992		process_evt_bh = 1;2993		mpi3mr_sastopochg_evt_th(mrioc, event_reply);2994		break;2995	}2996	case MPI3_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:2997	{2998		process_evt_bh = 1;2999		mpi3mr_pcietopochg_evt_th(mrioc, event_reply);3000		break;3001	}3002	case MPI3_EVENT_PREPARE_FOR_RESET:3003	{3004		mpi3mr_preparereset_evt_th(mrioc, event_reply);3005		ack_req = 0;3006		break;3007	}3008	case MPI3_EVENT_DIAGNOSTIC_BUFFER_STATUS_CHANGE:3009	{3010		mpi3mr_hdbstatuschg_evt_th(mrioc, event_reply);3011		break;3012	}3013	case MPI3_EVENT_DEVICE_INFO_CHANGED:3014	case MPI3_EVENT_LOG_DATA:3015	case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE:3016	case MPI3_EVENT_ENCL_DEVICE_ADDED:3017	{3018		process_evt_bh = 1;3019		break;3020	}3021	case MPI3_EVENT_ENERGY_PACK_CHANGE:3022	{3023		mpi3mr_energypackchg_evt_th(mrioc, event_reply);3024		break;3025	}3026	case MPI3_EVENT_CABLE_MGMT:3027	{3028		mpi3mr_cablemgmt_evt_th(mrioc, event_reply);3029		break;3030	}3031	case MPI3_EVENT_SAS_DISCOVERY:3032	case MPI3_EVENT_SAS_DEVICE_DISCOVERY_ERROR:3033	case MPI3_EVENT_SAS_BROADCAST_PRIMITIVE:3034	case MPI3_EVENT_PCIE_ENUMERATION:3035		break;3036	default:3037		ioc_info(mrioc, "%s :event 0x%02x is not handled\n",3038		    __func__, evt_type);3039		break;3040	}3041	if (process_evt_bh || ack_req) {3042		sz = event_reply->event_data_length * 4;3043		fwevt = mpi3mr_alloc_fwevt(sz);3044		if (!fwevt) {3045			ioc_info(mrioc, "%s :failure at %s:%d/%s()!\n",3046			    __func__, __FILE__, __LINE__, __func__);3047			return;3048		}3049 3050		memcpy(fwevt->event_data, event_reply->event_data, sz);3051		fwevt->mrioc = mrioc;3052		fwevt->event_id = evt_type;3053		fwevt->send_ack = ack_req;3054		fwevt->process_evt = process_evt_bh;3055		fwevt->evt_ctx = le32_to_cpu(event_reply->event_context);3056		mpi3mr_fwevt_add_to_list(mrioc, fwevt);3057	}3058}3059 3060/**3061 * mpi3mr_setup_eedp - Setup EEDP information in MPI3 SCSI IO3062 * @mrioc: Adapter instance reference3063 * @scmd: SCSI command reference3064 * @scsiio_req: MPI3 SCSI IO request3065 *3066 * Identifies the protection information flags from the SCSI3067 * command and set appropriate flags in the MPI3 SCSI IO3068 * request.3069 *3070 * Return: Nothing3071 */3072static void mpi3mr_setup_eedp(struct mpi3mr_ioc *mrioc,3073	struct scsi_cmnd *scmd, struct mpi3_scsi_io_request *scsiio_req)3074{3075	u16 eedp_flags = 0;3076	unsigned char prot_op = scsi_get_prot_op(scmd);3077 3078	switch (prot_op) {3079	case SCSI_PROT_NORMAL:3080		return;3081	case SCSI_PROT_READ_STRIP:3082		eedp_flags = MPI3_EEDPFLAGS_EEDP_OP_CHECK_REMOVE;3083		break;3084	case SCSI_PROT_WRITE_INSERT:3085		eedp_flags = MPI3_EEDPFLAGS_EEDP_OP_INSERT;3086		break;3087	case SCSI_PROT_READ_INSERT:3088		eedp_flags = MPI3_EEDPFLAGS_EEDP_OP_INSERT;3089		scsiio_req->msg_flags |= MPI3_SCSIIO_MSGFLAGS_METASGL_VALID;3090		break;3091	case SCSI_PROT_WRITE_STRIP:3092		eedp_flags = MPI3_EEDPFLAGS_EEDP_OP_CHECK_REMOVE;3093		scsiio_req->msg_flags |= MPI3_SCSIIO_MSGFLAGS_METASGL_VALID;3094		break;3095	case SCSI_PROT_READ_PASS:3096		eedp_flags = MPI3_EEDPFLAGS_EEDP_OP_CHECK;3097		scsiio_req->msg_flags |= MPI3_SCSIIO_MSGFLAGS_METASGL_VALID;3098		break;3099	case SCSI_PROT_WRITE_PASS:3100		if (scmd->prot_flags & SCSI_PROT_IP_CHECKSUM) {3101			eedp_flags = MPI3_EEDPFLAGS_EEDP_OP_CHECK_REGEN;3102			scsiio_req->sgl[0].eedp.application_tag_translation_mask =3103			    0xffff;3104		} else3105			eedp_flags = MPI3_EEDPFLAGS_EEDP_OP_CHECK;3106 3107		scsiio_req->msg_flags |= MPI3_SCSIIO_MSGFLAGS_METASGL_VALID;3108		break;3109	default:3110		return;3111	}3112 3113	if (scmd->prot_flags & SCSI_PROT_GUARD_CHECK)3114		eedp_flags |= MPI3_EEDPFLAGS_CHK_GUARD;3115 3116	if (scmd->prot_flags & SCSI_PROT_IP_CHECKSUM)3117		eedp_flags |= MPI3_EEDPFLAGS_HOST_GUARD_IP_CHKSUM;3118 3119	if (scmd->prot_flags & SCSI_PROT_REF_CHECK) {3120		eedp_flags |= MPI3_EEDPFLAGS_CHK_REF_TAG |3121			MPI3_EEDPFLAGS_INCR_PRI_REF_TAG;3122		scsiio_req->cdb.eedp32.primary_reference_tag =3123			cpu_to_be32(scsi_prot_ref_tag(scmd));3124	}3125 3126	if (scmd->prot_flags & SCSI_PROT_REF_INCREMENT)3127		eedp_flags |= MPI3_EEDPFLAGS_INCR_PRI_REF_TAG;3128 3129	eedp_flags |= MPI3_EEDPFLAGS_ESC_MODE_APPTAG_DISABLE;3130 3131	switch (scsi_prot_interval(scmd)) {3132	case 512:3133		scsiio_req->sgl[0].eedp.user_data_size = MPI3_EEDP_UDS_512;3134		break;3135	case 520:3136		scsiio_req->sgl[0].eedp.user_data_size = MPI3_EEDP_UDS_520;3137		break;3138	case 4080:3139		scsiio_req->sgl[0].eedp.user_data_size = MPI3_EEDP_UDS_4080;3140		break;3141	case 4088:3142		scsiio_req->sgl[0].eedp.user_data_size = MPI3_EEDP_UDS_4088;3143		break;3144	case 4096:3145		scsiio_req->sgl[0].eedp.user_data_size = MPI3_EEDP_UDS_4096;3146		break;3147	case 4104:3148		scsiio_req->sgl[0].eedp.user_data_size = MPI3_EEDP_UDS_4104;3149		break;3150	case 4160:3151		scsiio_req->sgl[0].eedp.user_data_size = MPI3_EEDP_UDS_4160;3152		break;3153	default:3154		break;3155	}3156 3157	scsiio_req->sgl[0].eedp.eedp_flags = cpu_to_le16(eedp_flags);3158	scsiio_req->sgl[0].eedp.flags = MPI3_SGE_FLAGS_ELEMENT_TYPE_EXTENDED;3159}3160 3161/**3162 * mpi3mr_build_sense_buffer - Map sense information3163 * @desc: Sense type3164 * @buf: Sense buffer to populate3165 * @key: Sense key3166 * @asc: Additional sense code3167 * @ascq: Additional sense code qualifier3168 *3169 * Maps the given sense information into either descriptor or3170 * fixed format sense data.3171 *3172 * Return: Nothing3173 */3174static inline void mpi3mr_build_sense_buffer(int desc, u8 *buf, u8 key,3175	u8 asc, u8 ascq)3176{3177	if (desc) {3178		buf[0] = 0x72;	/* descriptor, current */3179		buf[1] = key;3180		buf[2] = asc;3181		buf[3] = ascq;3182		buf[7] = 0;3183	} else {3184		buf[0] = 0x70;	/* fixed, current */3185		buf[2] = key;3186		buf[7] = 0xa;3187		buf[12] = asc;3188		buf[13] = ascq;3189	}3190}3191 3192/**3193 * mpi3mr_map_eedp_error - Map EEDP errors from IOC status3194 * @scmd: SCSI command reference3195 * @ioc_status: status of MPI3 request3196 *3197 * Maps the EEDP error status of the SCSI IO request to sense3198 * data.3199 *3200 * Return: Nothing3201 */3202static void mpi3mr_map_eedp_error(struct scsi_cmnd *scmd,3203	u16 ioc_status)3204{3205	u8 ascq = 0;3206 3207	switch (ioc_status) {3208	case MPI3_IOCSTATUS_EEDP_GUARD_ERROR:3209		ascq = 0x01;3210		break;3211	case MPI3_IOCSTATUS_EEDP_APP_TAG_ERROR:3212		ascq = 0x02;3213		break;3214	case MPI3_IOCSTATUS_EEDP_REF_TAG_ERROR:3215		ascq = 0x03;3216		break;3217	default:3218		ascq = 0x00;3219		break;3220	}3221 3222	mpi3mr_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,3223	    0x10, ascq);3224	scmd->result = (DID_ABORT << 16) | SAM_STAT_CHECK_CONDITION;3225}3226 3227/**3228 * mpi3mr_process_op_reply_desc - reply descriptor handler3229 * @mrioc: Adapter instance reference3230 * @reply_desc: Operational reply descriptor3231 * @reply_dma: place holder for reply DMA address3232 * @qidx: Operational queue index3233 *3234 * Process the operational reply descriptor and identifies the3235 * descriptor type. Based on the descriptor map the MPI3 request3236 * status to a SCSI command status and calls scsi_done call3237 * back.3238 *3239 * Return: Nothing3240 */3241void mpi3mr_process_op_reply_desc(struct mpi3mr_ioc *mrioc,3242	struct mpi3_default_reply_descriptor *reply_desc, u64 *reply_dma, u16 qidx)3243{3244	u16 reply_desc_type, host_tag = 0;3245	u16 ioc_status = MPI3_IOCSTATUS_SUCCESS;3246	u32 ioc_loginfo = 0;3247	struct mpi3_status_reply_descriptor *status_desc = NULL;3248	struct mpi3_address_reply_descriptor *addr_desc = NULL;3249	struct mpi3_success_reply_descriptor *success_desc = NULL;3250	struct mpi3_scsi_io_reply *scsi_reply = NULL;3251	struct scsi_cmnd *scmd = NULL;3252	struct scmd_priv *priv = NULL;3253	u8 *sense_buf = NULL;3254	u8 scsi_state = 0, scsi_status = 0, sense_state = 0;3255	u32 xfer_count = 0, sense_count = 0, resp_data = 0;3256	u16 dev_handle = 0xFFFF;3257	struct scsi_sense_hdr sshdr;3258	struct mpi3mr_stgt_priv_data *stgt_priv_data = NULL;3259	struct mpi3mr_sdev_priv_data *sdev_priv_data = NULL;3260	u32 ioc_pend_data_len = 0, tg_pend_data_len = 0, data_len_blks = 0;3261	struct mpi3mr_throttle_group_info *tg = NULL;3262	u8 throttle_enabled_dev = 0;3263 3264	*reply_dma = 0;3265	reply_desc_type = le16_to_cpu(reply_desc->reply_flags) &3266	    MPI3_REPLY_DESCRIPT_FLAGS_TYPE_MASK;3267	switch (reply_desc_type) {3268	case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_STATUS:3269		status_desc = (struct mpi3_status_reply_descriptor *)reply_desc;3270		host_tag = le16_to_cpu(status_desc->host_tag);3271		ioc_status = le16_to_cpu(status_desc->ioc_status);3272		if (ioc_status &3273		    MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_LOGINFOAVAIL)3274			ioc_loginfo = le32_to_cpu(status_desc->ioc_log_info);3275		ioc_status &= MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_STATUS_MASK;3276		mpi3mr_reply_trigger(mrioc, ioc_status, ioc_loginfo);3277		break;3278	case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_ADDRESS_REPLY:3279		addr_desc = (struct mpi3_address_reply_descriptor *)reply_desc;3280		*reply_dma = le64_to_cpu(addr_desc->reply_frame_address);3281		scsi_reply = mpi3mr_get_reply_virt_addr(mrioc,3282		    *reply_dma);3283		if (!scsi_reply) {3284			panic("%s: scsi_reply is NULL, this shouldn't happen\n",3285			    mrioc->name);3286			goto out;3287		}3288		host_tag = le16_to_cpu(scsi_reply->host_tag);3289		ioc_status = le16_to_cpu(scsi_reply->ioc_status);3290		scsi_status = scsi_reply->scsi_status;3291		scsi_state = scsi_reply->scsi_state;3292		dev_handle = le16_to_cpu(scsi_reply->dev_handle);3293		sense_state = (scsi_state & MPI3_SCSI_STATE_SENSE_MASK);3294		xfer_count = le32_to_cpu(scsi_reply->transfer_count);3295		sense_count = le32_to_cpu(scsi_reply->sense_count);3296		resp_data = le32_to_cpu(scsi_reply->response_data);3297		sense_buf = mpi3mr_get_sensebuf_virt_addr(mrioc,3298		    le64_to_cpu(scsi_reply->sense_data_buffer_address));3299		if (ioc_status &3300		    MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_LOGINFOAVAIL)3301			ioc_loginfo = le32_to_cpu(scsi_reply->ioc_log_info);3302		ioc_status &= MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_STATUS_MASK;3303		if (sense_state == MPI3_SCSI_STATE_SENSE_BUFF_Q_EMPTY)3304			panic("%s: Ran out of sense buffers\n", mrioc->name);3305		if (sense_buf) {3306			scsi_normalize_sense(sense_buf, sense_count, &sshdr);3307			mpi3mr_scsisense_trigger(mrioc, sshdr.sense_key,3308			    sshdr.asc, sshdr.ascq);3309		}3310		mpi3mr_reply_trigger(mrioc, ioc_status, ioc_loginfo);3311		break;3312	case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_SUCCESS:3313		success_desc = (struct mpi3_success_reply_descriptor *)reply_desc;3314		host_tag = le16_to_cpu(success_desc->host_tag);3315		break;3316	default:3317		break;3318	}3319	scmd = mpi3mr_scmd_from_host_tag(mrioc, host_tag, qidx);3320	if (!scmd) {3321		panic("%s: Cannot Identify scmd for host_tag 0x%x\n",3322		    mrioc->name, host_tag);3323		goto out;3324	}3325	priv = scsi_cmd_priv(scmd);3326 3327	data_len_blks = scsi_bufflen(scmd) >> 9;3328	sdev_priv_data = scmd->device->hostdata;3329	if (sdev_priv_data) {3330		stgt_priv_data = sdev_priv_data->tgt_priv_data;3331		if (stgt_priv_data) {3332			tg = stgt_priv_data->throttle_group;3333			throttle_enabled_dev =3334			    stgt_priv_data->io_throttle_enabled;3335			dev_handle = stgt_priv_data->dev_handle;3336		}3337	}3338	if (unlikely((data_len_blks >= mrioc->io_throttle_data_length) &&3339	    throttle_enabled_dev)) {3340		ioc_pend_data_len = atomic_sub_return(data_len_blks,3341		    &mrioc->pend_large_data_sz);3342		if (tg) {3343			tg_pend_data_len = atomic_sub_return(data_len_blks,3344			    &tg->pend_large_data_sz);3345			if (tg->io_divert  && ((ioc_pend_data_len <=3346			    mrioc->io_throttle_low) &&3347			    (tg_pend_data_len <= tg->low))) {3348				tg->io_divert = 0;3349				mpi3mr_set_io_divert_for_all_vd_in_tg(3350				    mrioc, tg, 0);3351			}3352		} else {3353			if (ioc_pend_data_len <= mrioc->io_throttle_low)3354				stgt_priv_data->io_divert = 0;3355		}3356	} else if (unlikely((stgt_priv_data && stgt_priv_data->io_divert))) {3357		ioc_pend_data_len = atomic_read(&mrioc->pend_large_data_sz);3358		if (!tg) {3359			if (ioc_pend_data_len <= mrioc->io_throttle_low)3360				stgt_priv_data->io_divert = 0;3361 3362		} else if (ioc_pend_data_len <= mrioc->io_throttle_low) {3363			tg_pend_data_len = atomic_read(&tg->pend_large_data_sz);3364			if (tg->io_divert  && (tg_pend_data_len <= tg->low)) {3365				tg->io_divert = 0;3366				mpi3mr_set_io_divert_for_all_vd_in_tg(3367				    mrioc, tg, 0);3368			}3369		}3370	}3371 3372	if (success_desc) {3373		scmd->result = DID_OK << 16;3374		goto out_success;3375	}3376 3377	scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_count);3378	if (ioc_status == MPI3_IOCSTATUS_SCSI_DATA_UNDERRUN &&3379	    xfer_count == 0 && (scsi_status == MPI3_SCSI_STATUS_BUSY ||3380	    scsi_status == MPI3_SCSI_STATUS_RESERVATION_CONFLICT ||3381	    scsi_status == MPI3_SCSI_STATUS_TASK_SET_FULL))3382		ioc_status = MPI3_IOCSTATUS_SUCCESS;3383 3384	if ((sense_state == MPI3_SCSI_STATE_SENSE_VALID) && sense_count &&3385	    sense_buf) {3386		u32 sz = min_t(u32, SCSI_SENSE_BUFFERSIZE, sense_count);3387 3388		memcpy(scmd->sense_buffer, sense_buf, sz);3389	}3390 3391	switch (ioc_status) {3392	case MPI3_IOCSTATUS_BUSY:3393	case MPI3_IOCSTATUS_INSUFFICIENT_RESOURCES:3394		scmd->result = SAM_STAT_BUSY;3395		break;3396	case MPI3_IOCSTATUS_SCSI_DEVICE_NOT_THERE:3397		scmd->result = DID_NO_CONNECT << 16;3398		break;3399	case MPI3_IOCSTATUS_SCSI_IOC_TERMINATED:3400		scmd->result = DID_SOFT_ERROR << 16;3401		break;3402	case MPI3_IOCSTATUS_SCSI_TASK_TERMINATED:3403	case MPI3_IOCSTATUS_SCSI_EXT_TERMINATED:3404		scmd->result = DID_RESET << 16;3405		break;3406	case MPI3_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:3407		if ((xfer_count == 0) || (scmd->underflow > xfer_count))3408			scmd->result = DID_SOFT_ERROR << 16;3409		else3410			scmd->result = (DID_OK << 16) | scsi_status;3411		break;3412	case MPI3_IOCSTATUS_SCSI_DATA_UNDERRUN:3413		scmd->result = (DID_OK << 16) | scsi_status;3414		if (sense_state == MPI3_SCSI_STATE_SENSE_VALID)3415			break;3416		if (xfer_count < scmd->underflow) {3417			if (scsi_status == SAM_STAT_BUSY)3418				scmd->result = SAM_STAT_BUSY;3419			else3420				scmd->result = DID_SOFT_ERROR << 16;3421		} else if ((scsi_state & (MPI3_SCSI_STATE_NO_SCSI_STATUS)) ||3422		    (sense_state != MPI3_SCSI_STATE_SENSE_NOT_AVAILABLE))3423			scmd->result = DID_SOFT_ERROR << 16;3424		else if (scsi_state & MPI3_SCSI_STATE_TERMINATED)3425			scmd->result = DID_RESET << 16;3426		break;3427	case MPI3_IOCSTATUS_SCSI_DATA_OVERRUN:3428		scsi_set_resid(scmd, 0);3429		fallthrough;3430	case MPI3_IOCSTATUS_SCSI_RECOVERED_ERROR:3431	case MPI3_IOCSTATUS_SUCCESS:3432		scmd->result = (DID_OK << 16) | scsi_status;3433		if ((scsi_state & (MPI3_SCSI_STATE_NO_SCSI_STATUS)) ||3434		    (sense_state == MPI3_SCSI_STATE_SENSE_FAILED) ||3435			(sense_state == MPI3_SCSI_STATE_SENSE_BUFF_Q_EMPTY))3436			scmd->result = DID_SOFT_ERROR << 16;3437		else if (scsi_state & MPI3_SCSI_STATE_TERMINATED)3438			scmd->result = DID_RESET << 16;3439		break;3440	case MPI3_IOCSTATUS_EEDP_GUARD_ERROR:3441	case MPI3_IOCSTATUS_EEDP_REF_TAG_ERROR:3442	case MPI3_IOCSTATUS_EEDP_APP_TAG_ERROR:3443		mpi3mr_map_eedp_error(scmd, ioc_status);3444		break;3445	case MPI3_IOCSTATUS_SCSI_PROTOCOL_ERROR:3446	case MPI3_IOCSTATUS_INVALID_FUNCTION:3447	case MPI3_IOCSTATUS_INVALID_SGL:3448	case MPI3_IOCSTATUS_INTERNAL_ERROR:3449	case MPI3_IOCSTATUS_INVALID_FIELD:3450	case MPI3_IOCSTATUS_INVALID_STATE:3451	case MPI3_IOCSTATUS_SCSI_IO_DATA_ERROR:3452	case MPI3_IOCSTATUS_SCSI_TASK_MGMT_FAILED:3453	case MPI3_IOCSTATUS_INSUFFICIENT_POWER:3454	default:3455		scmd->result = DID_SOFT_ERROR << 16;3456		break;3457	}3458 3459	if (scmd->result != (DID_OK << 16) && (scmd->cmnd[0] != ATA_12) &&3460	    (scmd->cmnd[0] != ATA_16) &&3461	    mrioc->logging_level & MPI3_DEBUG_SCSI_ERROR) {3462		ioc_info(mrioc, "%s :scmd->result 0x%x\n", __func__,3463		    scmd->result);3464		scsi_print_command(scmd);3465		ioc_info(mrioc,3466		    "%s :Command issued to handle 0x%02x returned with error 0x%04x loginfo 0x%08x, qid %d\n",3467		    __func__, dev_handle, ioc_status, ioc_loginfo,3468		    priv->req_q_idx + 1);3469		ioc_info(mrioc,3470		    " host_tag %d scsi_state 0x%02x scsi_status 0x%02x, xfer_cnt %d resp_data 0x%x\n",3471		    host_tag, scsi_state, scsi_status, xfer_count, resp_data);3472		if (sense_buf) {3473			scsi_normalize_sense(sense_buf, sense_count, &sshdr);3474			ioc_info(mrioc,3475			    "%s :sense_count 0x%x, sense_key 0x%x ASC 0x%x, ASCQ 0x%x\n",3476			    __func__, sense_count, sshdr.sense_key,3477			    sshdr.asc, sshdr.ascq);3478		}3479	}3480out_success:3481	if (priv->meta_sg_valid) {3482		dma_unmap_sg(&mrioc->pdev->dev, scsi_prot_sglist(scmd),3483		    scsi_prot_sg_count(scmd), scmd->sc_data_direction);3484	}3485	mpi3mr_clear_scmd_priv(mrioc, scmd);3486	scsi_dma_unmap(scmd);3487	scsi_done(scmd);3488out:3489	if (sense_buf)3490		mpi3mr_repost_sense_buf(mrioc,3491		    le64_to_cpu(scsi_reply->sense_data_buffer_address));3492}3493 3494/**3495 * mpi3mr_get_chain_idx - get free chain buffer index3496 * @mrioc: Adapter instance reference3497 *3498 * Try to get a free chain buffer index from the free pool.3499 *3500 * Return: -1 on failure or the free chain buffer index3501 */3502static int mpi3mr_get_chain_idx(struct mpi3mr_ioc *mrioc)3503{3504	u8 retry_count = 5;3505	int cmd_idx = -1;3506	unsigned long flags;3507 3508	spin_lock_irqsave(&mrioc->chain_buf_lock, flags);3509	do {3510		cmd_idx = find_first_zero_bit(mrioc->chain_bitmap,3511		    mrioc->chain_buf_count);3512		if (cmd_idx < mrioc->chain_buf_count) {3513			set_bit(cmd_idx, mrioc->chain_bitmap);3514			break;3515		}3516		cmd_idx = -1;3517	} while (retry_count--);3518	spin_unlock_irqrestore(&mrioc->chain_buf_lock, flags);3519	return cmd_idx;3520}3521 3522/**3523 * mpi3mr_prepare_sg_scmd - build scatter gather list3524 * @mrioc: Adapter instance reference3525 * @scmd: SCSI command reference3526 * @scsiio_req: MPI3 SCSI IO request3527 *3528 * This function maps SCSI command's data and protection SGEs to3529 * MPI request SGEs. If required additional 4K chain buffer is3530 * used to send the SGEs.3531 *3532 * Return: 0 on success, -ENOMEM on dma_map_sg failure3533 */3534static int mpi3mr_prepare_sg_scmd(struct mpi3mr_ioc *mrioc,3535	struct scsi_cmnd *scmd, struct mpi3_scsi_io_request *scsiio_req)3536{3537	dma_addr_t chain_dma;3538	struct scatterlist *sg_scmd;3539	void *sg_local, *chain;3540	u32 chain_length;3541	int sges_left, chain_idx;3542	u32 sges_in_segment;3543	u8 simple_sgl_flags;3544	u8 simple_sgl_flags_last;3545	u8 last_chain_sgl_flags;3546	struct chain_element *chain_req;3547	struct scmd_priv *priv = NULL;3548	u32 meta_sg = le32_to_cpu(scsiio_req->flags) &3549	    MPI3_SCSIIO_FLAGS_DMAOPERATION_HOST_PI;3550 3551	priv = scsi_cmd_priv(scmd);3552 3553	simple_sgl_flags = MPI3_SGE_FLAGS_ELEMENT_TYPE_SIMPLE |3554	    MPI3_SGE_FLAGS_DLAS_SYSTEM;3555	simple_sgl_flags_last = simple_sgl_flags |3556	    MPI3_SGE_FLAGS_END_OF_LIST;3557	last_chain_sgl_flags = MPI3_SGE_FLAGS_ELEMENT_TYPE_LAST_CHAIN |3558	    MPI3_SGE_FLAGS_DLAS_SYSTEM;3559 3560	if (meta_sg)3561		sg_local = &scsiio_req->sgl[MPI3_SCSIIO_METASGL_INDEX];3562	else3563		sg_local = &scsiio_req->sgl;3564 3565	if (!scsiio_req->data_length && !meta_sg) {3566		mpi3mr_build_zero_len_sge(sg_local);3567		return 0;3568	}3569 3570	if (meta_sg) {3571		sg_scmd = scsi_prot_sglist(scmd);3572		sges_left = dma_map_sg(&mrioc->pdev->dev,3573		    scsi_prot_sglist(scmd),3574		    scsi_prot_sg_count(scmd),3575		    scmd->sc_data_direction);3576		priv->meta_sg_valid = 1; /* To unmap meta sg DMA */3577	} else {3578		/*3579		 * Some firmware versions byte-swap the REPORT ZONES command3580		 * reply from ATA-ZAC devices by directly accessing in the host3581		 * buffer. This does not respect the default command DMA3582		 * direction and causes IOMMU page faults on some architectures3583		 * with an IOMMU enforcing write mappings (e.g. AMD hosts).3584		 * Avoid such issue by making the REPORT ZONES buffer mapping3585		 * bi-directional.3586		 */3587		if (scmd->cmnd[0] == ZBC_IN && scmd->cmnd[1] == ZI_REPORT_ZONES)3588			scmd->sc_data_direction = DMA_BIDIRECTIONAL;3589		sg_scmd = scsi_sglist(scmd);3590		sges_left = scsi_dma_map(scmd);3591	}3592 3593	if (sges_left < 0) {3594		sdev_printk(KERN_ERR, scmd->device,3595		    "scsi_dma_map failed: request for %d bytes!\n",3596		    scsi_bufflen(scmd));3597		return -ENOMEM;3598	}3599	if (sges_left > mrioc->max_sgl_entries) {3600		sdev_printk(KERN_ERR, scmd->device,3601		    "scsi_dma_map returned unsupported sge count %d!\n",3602		    sges_left);3603		return -ENOMEM;3604	}3605 3606	sges_in_segment = (mrioc->facts.op_req_sz -3607	    offsetof(struct mpi3_scsi_io_request, sgl)) / sizeof(struct mpi3_sge_common);3608 3609	if (scsiio_req->sgl[0].eedp.flags ==3610	    MPI3_SGE_FLAGS_ELEMENT_TYPE_EXTENDED && !meta_sg) {3611		sg_local += sizeof(struct mpi3_sge_common);3612		sges_in_segment--;3613		/* Reserve 1st segment (scsiio_req->sgl[0]) for eedp */3614	}3615 3616	if (scsiio_req->msg_flags ==3617	    MPI3_SCSIIO_MSGFLAGS_METASGL_VALID && !meta_sg) {3618		sges_in_segment--;3619		/* Reserve last segment (scsiio_req->sgl[3]) for meta sg */3620	}3621 3622	if (meta_sg)3623		sges_in_segment = 1;3624 3625	if (sges_left <= sges_in_segment)3626		goto fill_in_last_segment;3627 3628	/* fill in main message segment when there is a chain following */3629	while (sges_in_segment > 1) {3630		mpi3mr_add_sg_single(sg_local, simple_sgl_flags,3631		    sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));3632		sg_scmd = sg_next(sg_scmd);3633		sg_local += sizeof(struct mpi3_sge_common);3634		sges_left--;3635		sges_in_segment--;3636	}3637 3638	chain_idx = mpi3mr_get_chain_idx(mrioc);3639	if (chain_idx < 0)3640		return -1;3641	chain_req = &mrioc->chain_sgl_list[chain_idx];3642	if (meta_sg)3643		priv->meta_chain_idx = chain_idx;3644	else3645		priv->chain_idx = chain_idx;3646 3647	chain = chain_req->addr;3648	chain_dma = chain_req->dma_addr;3649	sges_in_segment = sges_left;3650	chain_length = sges_in_segment * sizeof(struct mpi3_sge_common);3651 3652	mpi3mr_add_sg_single(sg_local, last_chain_sgl_flags,3653	    chain_length, chain_dma);3654 3655	sg_local = chain;3656 3657fill_in_last_segment:3658	while (sges_left > 0) {3659		if (sges_left == 1)3660			mpi3mr_add_sg_single(sg_local,3661			    simple_sgl_flags_last, sg_dma_len(sg_scmd),3662			    sg_dma_address(sg_scmd));3663		else3664			mpi3mr_add_sg_single(sg_local, simple_sgl_flags,3665			    sg_dma_len(sg_scmd), sg_dma_address(sg_scmd));3666		sg_scmd = sg_next(sg_scmd);3667		sg_local += sizeof(struct mpi3_sge_common);3668		sges_left--;3669	}3670 3671	return 0;3672}3673 3674/**3675 * mpi3mr_build_sg_scmd - build scatter gather list for SCSI IO3676 * @mrioc: Adapter instance reference3677 * @scmd: SCSI command reference3678 * @scsiio_req: MPI3 SCSI IO request3679 *3680 * This function calls mpi3mr_prepare_sg_scmd for constructing3681 * both data SGEs and protection information SGEs in the MPI3682 * format from the SCSI Command as appropriate .3683 *3684 * Return: return value of mpi3mr_prepare_sg_scmd.3685 */3686static int mpi3mr_build_sg_scmd(struct mpi3mr_ioc *mrioc,3687	struct scsi_cmnd *scmd, struct mpi3_scsi_io_request *scsiio_req)3688{3689	int ret;3690 3691	ret = mpi3mr_prepare_sg_scmd(mrioc, scmd, scsiio_req);3692	if (ret)3693		return ret;3694 3695	if (scsiio_req->msg_flags == MPI3_SCSIIO_MSGFLAGS_METASGL_VALID) {3696		/* There is a valid meta sg */3697		scsiio_req->flags |=3698		    cpu_to_le32(MPI3_SCSIIO_FLAGS_DMAOPERATION_HOST_PI);3699		ret = mpi3mr_prepare_sg_scmd(mrioc, scmd, scsiio_req);3700	}3701 3702	return ret;3703}3704 3705/**3706 * mpi3mr_tm_response_name -  get TM response as a string3707 * @resp_code: TM response code3708 *3709 * Convert known task management response code as a readable3710 * string.3711 *3712 * Return: response code string.3713 */3714static const char *mpi3mr_tm_response_name(u8 resp_code)3715{3716	char *desc;3717 3718	switch (resp_code) {3719	case MPI3_SCSITASKMGMT_RSPCODE_TM_COMPLETE:3720		desc = "task management request completed";3721		break;3722	case MPI3_SCSITASKMGMT_RSPCODE_INVALID_FRAME:3723		desc = "invalid frame";3724		break;3725	case MPI3_SCSITASKMGMT_RSPCODE_TM_FUNCTION_NOT_SUPPORTED:3726		desc = "task management request not supported";3727		break;3728	case MPI3_SCSITASKMGMT_RSPCODE_TM_FAILED:3729		desc = "task management request failed";3730		break;3731	case MPI3_SCSITASKMGMT_RSPCODE_TM_SUCCEEDED:3732		desc = "task management request succeeded";3733		break;3734	case MPI3_SCSITASKMGMT_RSPCODE_TM_INVALID_LUN:3735		desc = "invalid LUN";3736		break;3737	case MPI3_SCSITASKMGMT_RSPCODE_TM_OVERLAPPED_TAG:3738		desc = "overlapped tag attempted";3739		break;3740	case MPI3_SCSITASKMGMT_RSPCODE_IO_QUEUED_ON_IOC:3741		desc = "task queued, however not sent to target";3742		break;3743	case MPI3_SCSITASKMGMT_RSPCODE_TM_NVME_DENIED:3744		desc = "task management request denied by NVMe device";3745		break;3746	default:3747		desc = "unknown";3748		break;3749	}3750 3751	return desc;3752}3753 3754inline void mpi3mr_poll_pend_io_completions(struct mpi3mr_ioc *mrioc)3755{3756	int i;3757	int num_of_reply_queues =3758	    mrioc->num_op_reply_q + mrioc->op_reply_q_offset;3759 3760	for (i = mrioc->op_reply_q_offset; i < num_of_reply_queues; i++)3761		mpi3mr_process_op_reply_q(mrioc,3762		    mrioc->intr_info[i].op_reply_q);3763}3764 3765/**3766 * mpi3mr_issue_tm - Issue Task Management request3767 * @mrioc: Adapter instance reference3768 * @tm_type: Task Management type3769 * @handle: Device handle3770 * @lun: lun ID3771 * @htag: Host tag of the TM request3772 * @timeout: TM timeout value3773 * @drv_cmd: Internal command tracker3774 * @resp_code: Response code place holder3775 * @scmd: SCSI command3776 *3777 * Issues a Task Management Request to the controller for a3778 * specified target, lun and command and wait for its completion3779 * and check TM response. Recover the TM if it timed out by3780 * issuing controller reset.3781 *3782 * Return: 0 on success, non-zero on errors3783 */3784int mpi3mr_issue_tm(struct mpi3mr_ioc *mrioc, u8 tm_type,3785	u16 handle, uint lun, u16 htag, ulong timeout,3786	struct mpi3mr_drv_cmd *drv_cmd,3787	u8 *resp_code, struct scsi_cmnd *scmd)3788{3789	struct mpi3_scsi_task_mgmt_request tm_req;3790	struct mpi3_scsi_task_mgmt_reply *tm_reply = NULL;3791	int retval = 0;3792	struct mpi3mr_tgt_dev *tgtdev = NULL;3793	struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data = NULL;3794	struct scmd_priv *cmd_priv = NULL;3795	struct scsi_device *sdev = NULL;3796	struct mpi3mr_sdev_priv_data *sdev_priv_data = NULL;3797 3798	ioc_info(mrioc, "%s :Issue TM: TM type (0x%x) for devhandle 0x%04x\n",3799	     __func__, tm_type, handle);3800	if (mrioc->unrecoverable) {3801		retval = -1;3802		ioc_err(mrioc, "%s :Issue TM: Unrecoverable controller\n",3803		    __func__);3804		goto out;3805	}3806 3807	memset(&tm_req, 0, sizeof(tm_req));3808	mutex_lock(&drv_cmd->mutex);3809	if (drv_cmd->state & MPI3MR_CMD_PENDING) {3810		retval = -1;3811		ioc_err(mrioc, "%s :Issue TM: Command is in use\n", __func__);3812		mutex_unlock(&drv_cmd->mutex);3813		goto out;3814	}3815	if (mrioc->reset_in_progress) {3816		retval = -1;3817		ioc_err(mrioc, "%s :Issue TM: Reset in progress\n", __func__);3818		mutex_unlock(&drv_cmd->mutex);3819		goto out;3820	}3821	if (mrioc->block_on_pci_err) {3822		retval = -1;3823		dprint_tm(mrioc, "sending task management failed due to\n"3824				"pci error recovery in progress\n");3825		mutex_unlock(&drv_cmd->mutex);3826		goto out;3827	}3828 3829	drv_cmd->state = MPI3MR_CMD_PENDING;3830	drv_cmd->is_waiting = 1;3831	drv_cmd->callback = NULL;3832	tm_req.dev_handle = cpu_to_le16(handle);3833	tm_req.task_type = tm_type;3834	tm_req.host_tag = cpu_to_le16(htag);3835 3836	int_to_scsilun(lun, (struct scsi_lun *)tm_req.lun);3837	tm_req.function = MPI3_FUNCTION_SCSI_TASK_MGMT;3838 3839	tgtdev = mpi3mr_get_tgtdev_by_handle(mrioc, handle);3840 3841	if (scmd) {3842		sdev = scmd->device;3843		sdev_priv_data = sdev->hostdata;3844		scsi_tgt_priv_data = ((sdev_priv_data) ?3845		    sdev_priv_data->tgt_priv_data : NULL);3846	} else {3847		if (tgtdev && tgtdev->starget && tgtdev->starget->hostdata)3848			scsi_tgt_priv_data = (struct mpi3mr_stgt_priv_data *)3849			    tgtdev->starget->hostdata;3850	}3851 3852	if (scsi_tgt_priv_data)3853		atomic_inc(&scsi_tgt_priv_data->block_io);3854 3855	if (tgtdev && (tgtdev->dev_type == MPI3_DEVICE_DEVFORM_PCIE)) {3856		if (cmd_priv && tgtdev->dev_spec.pcie_inf.abort_to)3857			timeout = tgtdev->dev_spec.pcie_inf.abort_to;3858		else if (!cmd_priv && tgtdev->dev_spec.pcie_inf.reset_to)3859			timeout = tgtdev->dev_spec.pcie_inf.reset_to;3860	}3861 3862	init_completion(&drv_cmd->done);3863	retval = mpi3mr_admin_request_post(mrioc, &tm_req, sizeof(tm_req), 1);3864	if (retval) {3865		ioc_err(mrioc, "%s :Issue TM: Admin Post failed\n", __func__);3866		goto out_unlock;3867	}3868	wait_for_completion_timeout(&drv_cmd->done, (timeout * HZ));3869 3870	if (!(drv_cmd->state & MPI3MR_CMD_COMPLETE)) {3871		drv_cmd->is_waiting = 0;3872		retval = -1;3873		if (!(drv_cmd->state & MPI3MR_CMD_RESET)) {3874			dprint_tm(mrioc,3875			    "task management request timed out after %ld seconds\n",3876			    timeout);3877			if (mrioc->logging_level & MPI3_DEBUG_TM)3878				dprint_dump_req(&tm_req, sizeof(tm_req)/4);3879			mpi3mr_soft_reset_handler(mrioc,3880			    MPI3MR_RESET_FROM_TM_TIMEOUT, 1);3881		}3882		goto out_unlock;3883	}3884 3885	if (!(drv_cmd->state & MPI3MR_CMD_REPLY_VALID)) {3886		dprint_tm(mrioc, "invalid task management reply message\n");3887		retval = -1;3888		goto out_unlock;3889	}3890 3891	tm_reply = (struct mpi3_scsi_task_mgmt_reply *)drv_cmd->reply;3892 3893	switch (drv_cmd->ioc_status) {3894	case MPI3_IOCSTATUS_SUCCESS:3895		*resp_code = le32_to_cpu(tm_reply->response_data) &3896			MPI3MR_RI_MASK_RESPCODE;3897		break;3898	case MPI3_IOCSTATUS_SCSI_IOC_TERMINATED:3899		*resp_code = MPI3_SCSITASKMGMT_RSPCODE_TM_COMPLETE;3900		break;3901	default:3902		dprint_tm(mrioc,3903		    "task management request to handle(0x%04x) is failed with ioc_status(0x%04x) log_info(0x%08x)\n",3904		    handle, drv_cmd->ioc_status, drv_cmd->ioc_loginfo);3905		retval = -1;3906		goto out_unlock;3907	}3908 3909	switch (*resp_code) {3910	case MPI3_SCSITASKMGMT_RSPCODE_TM_SUCCEEDED:3911	case MPI3_SCSITASKMGMT_RSPCODE_TM_COMPLETE:3912		break;3913	case MPI3_SCSITASKMGMT_RSPCODE_IO_QUEUED_ON_IOC:3914		if (tm_type != MPI3_SCSITASKMGMT_TASKTYPE_QUERY_TASK)3915			retval = -1;3916		break;3917	default:3918		retval = -1;3919		break;3920	}3921 3922	dprint_tm(mrioc,3923	    "task management request type(%d) completed for handle(0x%04x) with ioc_status(0x%04x), log_info(0x%08x), termination_count(%d), response:%s(0x%x)\n",3924	    tm_type, handle, drv_cmd->ioc_status, drv_cmd->ioc_loginfo,3925	    le32_to_cpu(tm_reply->termination_count),3926	    mpi3mr_tm_response_name(*resp_code), *resp_code);3927 3928	if (!retval) {3929		mpi3mr_ioc_disable_intr(mrioc);3930		mpi3mr_poll_pend_io_completions(mrioc);3931		mpi3mr_ioc_enable_intr(mrioc);3932		mpi3mr_poll_pend_io_completions(mrioc);3933		mpi3mr_process_admin_reply_q(mrioc);3934	}3935	switch (tm_type) {3936	case MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET:3937		if (!scsi_tgt_priv_data)3938			break;3939		scsi_tgt_priv_data->pend_count = 0;3940		blk_mq_tagset_busy_iter(&mrioc->shost->tag_set,3941		    mpi3mr_count_tgt_pending,3942		    (void *)scsi_tgt_priv_data->starget);3943		break;3944	case MPI3_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:3945		if (!sdev_priv_data)3946			break;3947		sdev_priv_data->pend_count = 0;3948		blk_mq_tagset_busy_iter(&mrioc->shost->tag_set,3949		    mpi3mr_count_dev_pending, (void *)sdev);3950		break;3951	default:3952		break;3953	}3954	mpi3mr_global_trigger(mrioc,3955	    MPI3_DRIVER2_GLOBALTRIGGER_TASK_MANAGEMENT_ENABLED);3956 3957out_unlock:3958	drv_cmd->state = MPI3MR_CMD_NOTUSED;3959	mutex_unlock(&drv_cmd->mutex);3960	if (scsi_tgt_priv_data)3961		atomic_dec_if_positive(&scsi_tgt_priv_data->block_io);3962	if (tgtdev)3963		mpi3mr_tgtdev_put(tgtdev);3964out:3965	return retval;3966}3967 3968/**3969 * mpi3mr_bios_param - BIOS param callback3970 * @sdev: SCSI device reference3971 * @bdev: Block device reference3972 * @capacity: Capacity in logical sectors3973 * @params: Parameter array3974 *3975 * Just the parameters with heads/secots/cylinders.3976 *3977 * Return: 0 always3978 */3979static int mpi3mr_bios_param(struct scsi_device *sdev,3980	struct block_device *bdev, sector_t capacity, int params[])3981{3982	int heads;3983	int sectors;3984	sector_t cylinders;3985	ulong dummy;3986 3987	heads = 64;3988	sectors = 32;3989 3990	dummy = heads * sectors;3991	cylinders = capacity;3992	sector_div(cylinders, dummy);3993 3994	if ((ulong)capacity >= 0x200000) {3995		heads = 255;3996		sectors = 63;3997		dummy = heads * sectors;3998		cylinders = capacity;3999		sector_div(cylinders, dummy);4000	}4001 4002	params[0] = heads;4003	params[1] = sectors;4004	params[2] = cylinders;4005	return 0;4006}4007 4008/**4009 * mpi3mr_map_queues - Map queues callback handler4010 * @shost: SCSI host reference4011 *4012 * Maps default and poll queues.4013 *4014 * Return: return zero.4015 */4016static void mpi3mr_map_queues(struct Scsi_Host *shost)4017{4018	struct mpi3mr_ioc *mrioc = shost_priv(shost);4019	int i, qoff, offset;4020	struct blk_mq_queue_map *map = NULL;4021 4022	offset = mrioc->op_reply_q_offset;4023 4024	for (i = 0, qoff = 0; i < HCTX_MAX_TYPES; i++) {4025		map = &shost->tag_set.map[i];4026 4027		map->nr_queues  = 0;4028 4029		if (i == HCTX_TYPE_DEFAULT)4030			map->nr_queues = mrioc->default_qcount;4031		else if (i == HCTX_TYPE_POLL)4032			map->nr_queues = mrioc->active_poll_qcount;4033 4034		if (!map->nr_queues) {4035			BUG_ON(i == HCTX_TYPE_DEFAULT);4036			continue;4037		}4038 4039		/*4040		 * The poll queue(s) doesn't have an IRQ (and hence IRQ4041		 * affinity), so use the regular blk-mq cpu mapping4042		 */4043		map->queue_offset = qoff;4044		if (i != HCTX_TYPE_POLL)4045			blk_mq_pci_map_queues(map, mrioc->pdev, offset);4046		else4047			blk_mq_map_queues(map);4048 4049		qoff += map->nr_queues;4050		offset += map->nr_queues;4051	}4052}4053 4054/**4055 * mpi3mr_get_fw_pending_ios - Calculate pending I/O count4056 * @mrioc: Adapter instance reference4057 *4058 * Calculate the pending I/Os for the controller and return.4059 *4060 * Return: Number of pending I/Os4061 */4062static inline int mpi3mr_get_fw_pending_ios(struct mpi3mr_ioc *mrioc)4063{4064	u16 i;4065	uint pend_ios = 0;4066 4067	for (i = 0; i < mrioc->num_op_reply_q; i++)4068		pend_ios += atomic_read(&mrioc->op_reply_qinfo[i].pend_ios);4069	return pend_ios;4070}4071 4072/**4073 * mpi3mr_print_pending_host_io - print pending I/Os4074 * @mrioc: Adapter instance reference4075 *4076 * Print number of pending I/Os and each I/O details prior to4077 * reset for debug purpose.4078 *4079 * Return: Nothing4080 */4081static void mpi3mr_print_pending_host_io(struct mpi3mr_ioc *mrioc)4082{4083	struct Scsi_Host *shost = mrioc->shost;4084 4085	ioc_info(mrioc, "%s :Pending commands prior to reset: %d\n",4086	    __func__, mpi3mr_get_fw_pending_ios(mrioc));4087	blk_mq_tagset_busy_iter(&shost->tag_set,4088	    mpi3mr_print_scmd, (void *)mrioc);4089}4090 4091/**4092 * mpi3mr_wait_for_host_io - block for I/Os to complete4093 * @mrioc: Adapter instance reference4094 * @timeout: time out in seconds4095 * Waits for pending I/Os for the given adapter to complete or4096 * to hit the timeout.4097 *4098 * Return: Nothing4099 */4100void mpi3mr_wait_for_host_io(struct mpi3mr_ioc *mrioc, u32 timeout)4101{4102	enum mpi3mr_iocstate iocstate;4103	int i = 0;4104 4105	iocstate = mpi3mr_get_iocstate(mrioc);4106	if (iocstate != MRIOC_STATE_READY)4107		return;4108 4109	if (!mpi3mr_get_fw_pending_ios(mrioc))4110		return;4111	ioc_info(mrioc,4112	    "%s :Waiting for %d seconds prior to reset for %d I/O\n",4113	    __func__, timeout, mpi3mr_get_fw_pending_ios(mrioc));4114 4115	for (i = 0; i < timeout; i++) {4116		if (!mpi3mr_get_fw_pending_ios(mrioc))4117			break;4118		iocstate = mpi3mr_get_iocstate(mrioc);4119		if (iocstate != MRIOC_STATE_READY)4120			break;4121		msleep(1000);4122	}4123 4124	ioc_info(mrioc, "%s :Pending I/Os after wait is: %d\n", __func__,4125	    mpi3mr_get_fw_pending_ios(mrioc));4126}4127 4128/**4129 * mpi3mr_setup_divert_ws - Setup Divert IO flag for write same4130 * @mrioc: Adapter instance reference4131 * @scmd: SCSI command reference4132 * @scsiio_req: MPI3 SCSI IO request4133 * @scsiio_flags: Pointer to MPI3 SCSI IO Flags4134 * @wslen: write same max length4135 *4136 * Gets values of unmap, ndob and number of blocks from write4137 * same scsi io and based on these values it sets divert IO flag4138 * and reason for diverting IO to firmware.4139 *4140 * Return: Nothing4141 */4142static inline void mpi3mr_setup_divert_ws(struct mpi3mr_ioc *mrioc,4143	struct scsi_cmnd *scmd, struct mpi3_scsi_io_request *scsiio_req,4144	u32 *scsiio_flags, u16 wslen)4145{4146	u8 unmap = 0, ndob = 0;4147	u8 opcode = scmd->cmnd[0];4148	u32 num_blocks = 0;4149	u16 sa = (scmd->cmnd[8] << 8) | (scmd->cmnd[9]);4150 4151	if (opcode == WRITE_SAME_16) {4152		unmap = scmd->cmnd[1] & 0x08;4153		ndob = scmd->cmnd[1] & 0x01;4154		num_blocks = get_unaligned_be32(scmd->cmnd + 10);4155	} else if ((opcode == VARIABLE_LENGTH_CMD) && (sa == WRITE_SAME_32)) {4156		unmap = scmd->cmnd[10] & 0x08;4157		ndob = scmd->cmnd[10] & 0x01;4158		num_blocks = get_unaligned_be32(scmd->cmnd + 28);4159	} else4160		return;4161 4162	if ((unmap) && (ndob) && (num_blocks > wslen)) {4163		scsiio_req->msg_flags |=4164		    MPI3_SCSIIO_MSGFLAGS_DIVERT_TO_FIRMWARE;4165		*scsiio_flags |=4166			MPI3_SCSIIO_FLAGS_DIVERT_REASON_WRITE_SAME_TOO_LARGE;4167	}4168}4169 4170/**4171 * mpi3mr_eh_host_reset - Host reset error handling callback4172 * @scmd: SCSI command reference4173 *4174 * Issue controller reset4175 *4176 * Return: SUCCESS of successful reset else FAILED4177 */4178static int mpi3mr_eh_host_reset(struct scsi_cmnd *scmd)4179{4180	struct mpi3mr_ioc *mrioc = shost_priv(scmd->device->host);4181	int retval = FAILED, ret;4182 4183	ret = mpi3mr_soft_reset_handler(mrioc,4184	    MPI3MR_RESET_FROM_EH_HOS, 1);4185	if (ret)4186		goto out;4187 4188	retval = SUCCESS;4189out:4190	sdev_printk(KERN_INFO, scmd->device,4191	    "Host reset is %s for scmd(%p)\n",4192	    ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);4193 4194	return retval;4195}4196 4197/**4198 * mpi3mr_eh_bus_reset - Bus reset error handling callback4199 * @scmd: SCSI command reference4200 *4201 * Checks whether pending I/Os are present for the RAID volume;4202 * if not there's no need to reset the adapter.4203 *4204 * Return: SUCCESS of successful reset else FAILED4205 */4206static int mpi3mr_eh_bus_reset(struct scsi_cmnd *scmd)4207{4208	struct mpi3mr_ioc *mrioc = shost_priv(scmd->device->host);4209	struct mpi3mr_stgt_priv_data *stgt_priv_data;4210	struct mpi3mr_sdev_priv_data *sdev_priv_data;4211	u8 dev_type = MPI3_DEVICE_DEVFORM_VD;4212	int retval = FAILED;4213	unsigned int timeout = MPI3MR_RESET_TIMEOUT;4214 4215	sdev_priv_data = scmd->device->hostdata;4216	if (sdev_priv_data && sdev_priv_data->tgt_priv_data) {4217		stgt_priv_data = sdev_priv_data->tgt_priv_data;4218		dev_type = stgt_priv_data->dev_type;4219	}4220 4221	if (dev_type == MPI3_DEVICE_DEVFORM_VD) {4222		mpi3mr_wait_for_host_io(mrioc,4223			MPI3MR_RAID_ERRREC_RESET_TIMEOUT);4224		if (!mpi3mr_get_fw_pending_ios(mrioc)) {4225			while (mrioc->reset_in_progress ||4226			       mrioc->prepare_for_reset ||4227			       mrioc->block_on_pci_err) {4228				ssleep(1);4229				if (!timeout--) {4230					retval = FAILED;4231					goto out;4232				}4233			}4234			retval = SUCCESS;4235			goto out;4236		}4237	}4238	if (retval == FAILED)4239		mpi3mr_print_pending_host_io(mrioc);4240 4241out:4242	sdev_printk(KERN_INFO, scmd->device,4243		"Bus reset is %s for scmd(%p)\n",4244		((retval == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);4245	return retval;4246}4247 4248/**4249 * mpi3mr_eh_target_reset - Target reset error handling callback4250 * @scmd: SCSI command reference4251 *4252 * Issue Target reset Task Management and verify the scmd is4253 * terminated successfully and return status accordingly.4254 *4255 * Return: SUCCESS of successful termination of the scmd else4256 *         FAILED4257 */4258static int mpi3mr_eh_target_reset(struct scsi_cmnd *scmd)4259{4260	struct mpi3mr_ioc *mrioc = shost_priv(scmd->device->host);4261	struct mpi3mr_stgt_priv_data *stgt_priv_data;4262	struct mpi3mr_sdev_priv_data *sdev_priv_data;4263	u16 dev_handle;4264	u8 resp_code = 0;4265	int retval = FAILED, ret = 0;4266 4267	sdev_printk(KERN_INFO, scmd->device,4268	    "Attempting Target Reset! scmd(%p)\n", scmd);4269	scsi_print_command(scmd);4270 4271	sdev_priv_data = scmd->device->hostdata;4272	if (!sdev_priv_data || !sdev_priv_data->tgt_priv_data) {4273		sdev_printk(KERN_INFO, scmd->device,4274		    "SCSI device is not available\n");4275		retval = SUCCESS;4276		goto out;4277	}4278 4279	stgt_priv_data = sdev_priv_data->tgt_priv_data;4280	dev_handle = stgt_priv_data->dev_handle;4281	if (stgt_priv_data->dev_removed) {4282		struct scmd_priv *cmd_priv = scsi_cmd_priv(scmd);4283		sdev_printk(KERN_INFO, scmd->device,4284		    "%s:target(handle = 0x%04x) is removed, target reset is not issued\n",4285		    mrioc->name, dev_handle);4286		if (!cmd_priv->in_lld_scope || cmd_priv->host_tag == MPI3MR_HOSTTAG_INVALID)4287			retval = SUCCESS;4288		else4289			retval = FAILED;4290		goto out;4291	}4292	sdev_printk(KERN_INFO, scmd->device,4293	    "Target Reset is issued to handle(0x%04x)\n",4294	    dev_handle);4295 4296	ret = mpi3mr_issue_tm(mrioc,4297	    MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET, dev_handle,4298	    sdev_priv_data->lun_id, MPI3MR_HOSTTAG_BLK_TMS,4299	    MPI3MR_RESETTM_TIMEOUT, &mrioc->host_tm_cmds, &resp_code, scmd);4300 4301	if (ret)4302		goto out;4303 4304	if (stgt_priv_data->pend_count) {4305		sdev_printk(KERN_INFO, scmd->device,4306		    "%s: target has %d pending commands, target reset is failed\n",4307		    mrioc->name, stgt_priv_data->pend_count);4308		goto out;4309	}4310 4311	retval = SUCCESS;4312out:4313	sdev_printk(KERN_INFO, scmd->device,4314	    "%s: target reset is %s for scmd(%p)\n", mrioc->name,4315	    ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);4316 4317	return retval;4318}4319 4320/**4321 * mpi3mr_eh_dev_reset- Device reset error handling callback4322 * @scmd: SCSI command reference4323 *4324 * Issue lun reset Task Management and verify the scmd is4325 * terminated successfully and return status accordingly.4326 *4327 * Return: SUCCESS of successful termination of the scmd else4328 *         FAILED4329 */4330static int mpi3mr_eh_dev_reset(struct scsi_cmnd *scmd)4331{4332	struct mpi3mr_ioc *mrioc = shost_priv(scmd->device->host);4333	struct mpi3mr_stgt_priv_data *stgt_priv_data;4334	struct mpi3mr_sdev_priv_data *sdev_priv_data;4335	u16 dev_handle;4336	u8 resp_code = 0;4337	int retval = FAILED, ret = 0;4338 4339	sdev_printk(KERN_INFO, scmd->device,4340	    "Attempting Device(lun) Reset! scmd(%p)\n", scmd);4341	scsi_print_command(scmd);4342 4343	sdev_priv_data = scmd->device->hostdata;4344	if (!sdev_priv_data || !sdev_priv_data->tgt_priv_data) {4345		sdev_printk(KERN_INFO, scmd->device,4346		    "SCSI device is not available\n");4347		retval = SUCCESS;4348		goto out;4349	}4350 4351	stgt_priv_data = sdev_priv_data->tgt_priv_data;4352	dev_handle = stgt_priv_data->dev_handle;4353	if (stgt_priv_data->dev_removed) {4354		struct scmd_priv *cmd_priv = scsi_cmd_priv(scmd);4355		sdev_printk(KERN_INFO, scmd->device,4356		    "%s: device(handle = 0x%04x) is removed, device(LUN) reset is not issued\n",4357		    mrioc->name, dev_handle);4358		if (!cmd_priv->in_lld_scope || cmd_priv->host_tag == MPI3MR_HOSTTAG_INVALID)4359			retval = SUCCESS;4360		else4361			retval = FAILED;4362		goto out;4363	}4364	sdev_printk(KERN_INFO, scmd->device,4365	    "Device(lun) Reset is issued to handle(0x%04x)\n", dev_handle);4366 4367	ret = mpi3mr_issue_tm(mrioc,4368	    MPI3_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, dev_handle,4369	    sdev_priv_data->lun_id, MPI3MR_HOSTTAG_BLK_TMS,4370	    MPI3MR_RESETTM_TIMEOUT, &mrioc->host_tm_cmds, &resp_code, scmd);4371 4372	if (ret)4373		goto out;4374 4375	if (sdev_priv_data->pend_count) {4376		sdev_printk(KERN_INFO, scmd->device,4377		    "%s: device has %d pending commands, device(LUN) reset is failed\n",4378		    mrioc->name, sdev_priv_data->pend_count);4379		goto out;4380	}4381	retval = SUCCESS;4382out:4383	sdev_printk(KERN_INFO, scmd->device,4384	    "%s: device(LUN) reset is %s for scmd(%p)\n", mrioc->name,4385	    ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);4386 4387	return retval;4388}4389 4390/**4391 * mpi3mr_scan_start - Scan start callback handler4392 * @shost: SCSI host reference4393 *4394 * Issue port enable request asynchronously.4395 *4396 * Return: Nothing4397 */4398static void mpi3mr_scan_start(struct Scsi_Host *shost)4399{4400	struct mpi3mr_ioc *mrioc = shost_priv(shost);4401 4402	mrioc->scan_started = 1;4403	ioc_info(mrioc, "%s :Issuing Port Enable\n", __func__);4404	if (mpi3mr_issue_port_enable(mrioc, 1)) {4405		ioc_err(mrioc, "%s :Issuing port enable failed\n", __func__);4406		mrioc->scan_started = 0;4407		mrioc->scan_failed = MPI3_IOCSTATUS_INTERNAL_ERROR;4408	}4409}4410 4411/**4412 * mpi3mr_scan_finished - Scan finished callback handler4413 * @shost: SCSI host reference4414 * @time: Jiffies from the scan start4415 *4416 * Checks whether the port enable is completed or timedout or4417 * failed and set the scan status accordingly after taking any4418 * recovery if required.4419 *4420 * Return: 1 on scan finished or timed out, 0 for in progress4421 */4422static int mpi3mr_scan_finished(struct Scsi_Host *shost,4423	unsigned long time)4424{4425	struct mpi3mr_ioc *mrioc = shost_priv(shost);4426	u32 pe_timeout = MPI3MR_PORTENABLE_TIMEOUT;4427	u32 ioc_status = readl(&mrioc->sysif_regs->ioc_status);4428 4429	if ((ioc_status & MPI3_SYSIF_IOC_STATUS_RESET_HISTORY) ||4430	    (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT)) {4431		ioc_err(mrioc, "port enable failed due to fault or reset\n");4432		mpi3mr_print_fault_info(mrioc);4433		mrioc->scan_failed = MPI3_IOCSTATUS_INTERNAL_ERROR;4434		mrioc->scan_started = 0;4435		mrioc->init_cmds.is_waiting = 0;4436		mrioc->init_cmds.callback = NULL;4437		mrioc->init_cmds.state = MPI3MR_CMD_NOTUSED;4438	}4439 4440	if (time >= (pe_timeout * HZ)) {4441		ioc_err(mrioc, "port enable failed due to time out\n");4442		mpi3mr_check_rh_fault_ioc(mrioc,4443		    MPI3MR_RESET_FROM_PE_TIMEOUT);4444		mrioc->scan_failed = MPI3_IOCSTATUS_INTERNAL_ERROR;4445		mrioc->scan_started = 0;4446		mrioc->init_cmds.is_waiting = 0;4447		mrioc->init_cmds.callback = NULL;4448		mrioc->init_cmds.state = MPI3MR_CMD_NOTUSED;4449	}4450 4451	if (mrioc->scan_started)4452		return 0;4453 4454	if (mrioc->scan_failed) {4455		ioc_err(mrioc,4456		    "port enable failed with status=0x%04x\n",4457		    mrioc->scan_failed);4458	} else4459		ioc_info(mrioc, "port enable is successfully completed\n");4460 4461	mpi3mr_start_watchdog(mrioc);4462	mrioc->is_driver_loading = 0;4463	mrioc->stop_bsgs = 0;4464	return 1;4465}4466 4467/**4468 * mpi3mr_slave_destroy - Slave destroy callback handler4469 * @sdev: SCSI device reference4470 *4471 * Cleanup and free per device(lun) private data.4472 *4473 * Return: Nothing.4474 */4475static void mpi3mr_slave_destroy(struct scsi_device *sdev)4476{4477	struct Scsi_Host *shost;4478	struct mpi3mr_ioc *mrioc;4479	struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data;4480	struct mpi3mr_tgt_dev *tgt_dev = NULL;4481	unsigned long flags;4482	struct scsi_target *starget;4483	struct sas_rphy *rphy = NULL;4484 4485	if (!sdev->hostdata)4486		return;4487 4488	starget = scsi_target(sdev);4489	shost = dev_to_shost(&starget->dev);4490	mrioc = shost_priv(shost);4491	scsi_tgt_priv_data = starget->hostdata;4492 4493	scsi_tgt_priv_data->num_luns--;4494 4495	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);4496	if (starget->channel == mrioc->scsi_device_channel)4497		tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id);4498	else if (mrioc->sas_transport_enabled && !starget->channel) {4499		rphy = dev_to_rphy(starget->dev.parent);4500		tgt_dev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc,4501		    rphy->identify.sas_address, rphy);4502	}4503 4504	if (tgt_dev && (!scsi_tgt_priv_data->num_luns))4505		tgt_dev->starget = NULL;4506	if (tgt_dev)4507		mpi3mr_tgtdev_put(tgt_dev);4508	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);4509 4510	kfree(sdev->hostdata);4511	sdev->hostdata = NULL;4512}4513 4514/**4515 * mpi3mr_target_destroy - Target destroy callback handler4516 * @starget: SCSI target reference4517 *4518 * Cleanup and free per target private data.4519 *4520 * Return: Nothing.4521 */4522static void mpi3mr_target_destroy(struct scsi_target *starget)4523{4524	struct Scsi_Host *shost;4525	struct mpi3mr_ioc *mrioc;4526	struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data;4527	struct mpi3mr_tgt_dev *tgt_dev;4528	unsigned long flags;4529 4530	if (!starget->hostdata)4531		return;4532 4533	shost = dev_to_shost(&starget->dev);4534	mrioc = shost_priv(shost);4535	scsi_tgt_priv_data = starget->hostdata;4536 4537	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);4538	tgt_dev = __mpi3mr_get_tgtdev_from_tgtpriv(mrioc, scsi_tgt_priv_data);4539	if (tgt_dev && (tgt_dev->starget == starget) &&4540	    (tgt_dev->perst_id == starget->id))4541		tgt_dev->starget = NULL;4542	if (tgt_dev) {4543		scsi_tgt_priv_data->tgt_dev = NULL;4544		scsi_tgt_priv_data->perst_id = 0;4545		mpi3mr_tgtdev_put(tgt_dev);4546		mpi3mr_tgtdev_put(tgt_dev);4547	}4548	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);4549 4550	kfree(starget->hostdata);4551	starget->hostdata = NULL;4552}4553 4554/**4555 * mpi3mr_device_configure - Slave configure callback handler4556 * @sdev: SCSI device reference4557 * @lim: queue limits4558 *4559 * Configure queue depth, max hardware sectors and virt boundary4560 * as required4561 *4562 * Return: 0 always.4563 */4564static int mpi3mr_device_configure(struct scsi_device *sdev,4565		struct queue_limits *lim)4566{4567	struct scsi_target *starget;4568	struct Scsi_Host *shost;4569	struct mpi3mr_ioc *mrioc;4570	struct mpi3mr_tgt_dev *tgt_dev = NULL;4571	unsigned long flags;4572	int retval = 0;4573	struct sas_rphy *rphy = NULL;4574 4575	starget = scsi_target(sdev);4576	shost = dev_to_shost(&starget->dev);4577	mrioc = shost_priv(shost);4578 4579	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);4580	if (starget->channel == mrioc->scsi_device_channel)4581		tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id);4582	else if (mrioc->sas_transport_enabled && !starget->channel) {4583		rphy = dev_to_rphy(starget->dev.parent);4584		tgt_dev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc,4585		    rphy->identify.sas_address, rphy);4586	}4587	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);4588	if (!tgt_dev)4589		return -ENXIO;4590 4591	mpi3mr_change_queue_depth(sdev, tgt_dev->q_depth);4592 4593	sdev->eh_timeout = MPI3MR_EH_SCMD_TIMEOUT;4594	blk_queue_rq_timeout(sdev->request_queue, MPI3MR_SCMD_TIMEOUT);4595 4596	mpi3mr_configure_tgt_dev(tgt_dev, lim);4597	mpi3mr_tgtdev_put(tgt_dev);4598	return retval;4599}4600 4601/**4602 * mpi3mr_slave_alloc -Slave alloc callback handler4603 * @sdev: SCSI device reference4604 *4605 * Allocate per device(lun) private data and initialize it.4606 *4607 * Return: 0 on success -ENOMEM on memory allocation failure.4608 */4609static int mpi3mr_slave_alloc(struct scsi_device *sdev)4610{4611	struct Scsi_Host *shost;4612	struct mpi3mr_ioc *mrioc;4613	struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data;4614	struct mpi3mr_tgt_dev *tgt_dev = NULL;4615	struct mpi3mr_sdev_priv_data *scsi_dev_priv_data;4616	unsigned long flags;4617	struct scsi_target *starget;4618	int retval = 0;4619	struct sas_rphy *rphy = NULL;4620 4621	starget = scsi_target(sdev);4622	shost = dev_to_shost(&starget->dev);4623	mrioc = shost_priv(shost);4624	scsi_tgt_priv_data = starget->hostdata;4625 4626	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);4627 4628	if (starget->channel == mrioc->scsi_device_channel)4629		tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id);4630	else if (mrioc->sas_transport_enabled && !starget->channel) {4631		rphy = dev_to_rphy(starget->dev.parent);4632		tgt_dev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc,4633		    rphy->identify.sas_address, rphy);4634	}4635 4636	if (tgt_dev) {4637		if (tgt_dev->starget == NULL)4638			tgt_dev->starget = starget;4639		mpi3mr_tgtdev_put(tgt_dev);4640		retval = 0;4641	} else {4642		spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);4643		return -ENXIO;4644	}4645 4646	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);4647 4648	scsi_dev_priv_data = kzalloc(sizeof(*scsi_dev_priv_data), GFP_KERNEL);4649	if (!scsi_dev_priv_data)4650		return -ENOMEM;4651 4652	scsi_dev_priv_data->lun_id = sdev->lun;4653	scsi_dev_priv_data->tgt_priv_data = scsi_tgt_priv_data;4654	sdev->hostdata = scsi_dev_priv_data;4655 4656	scsi_tgt_priv_data->num_luns++;4657 4658	return retval;4659}4660 4661/**4662 * mpi3mr_target_alloc - Target alloc callback handler4663 * @starget: SCSI target reference4664 *4665 * Allocate per target private data and initialize it.4666 *4667 * Return: 0 on success -ENOMEM on memory allocation failure.4668 */4669static int mpi3mr_target_alloc(struct scsi_target *starget)4670{4671	struct Scsi_Host *shost = dev_to_shost(&starget->dev);4672	struct mpi3mr_ioc *mrioc = shost_priv(shost);4673	struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data;4674	struct mpi3mr_tgt_dev *tgt_dev;4675	unsigned long flags;4676	int retval = 0;4677	struct sas_rphy *rphy = NULL;4678 4679	scsi_tgt_priv_data = kzalloc(sizeof(*scsi_tgt_priv_data), GFP_KERNEL);4680	if (!scsi_tgt_priv_data)4681		return -ENOMEM;4682 4683	starget->hostdata = scsi_tgt_priv_data;4684 4685	spin_lock_irqsave(&mrioc->tgtdev_lock, flags);4686	if (starget->channel == mrioc->scsi_device_channel) {4687		tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id);4688		if (tgt_dev && !tgt_dev->is_hidden) {4689			scsi_tgt_priv_data->starget = starget;4690			scsi_tgt_priv_data->dev_handle = tgt_dev->dev_handle;4691			scsi_tgt_priv_data->perst_id = tgt_dev->perst_id;4692			scsi_tgt_priv_data->dev_type = tgt_dev->dev_type;4693			scsi_tgt_priv_data->tgt_dev = tgt_dev;4694			tgt_dev->starget = starget;4695			atomic_set(&scsi_tgt_priv_data->block_io, 0);4696			retval = 0;4697			if ((tgt_dev->dev_type == MPI3_DEVICE_DEVFORM_PCIE) &&4698			    ((tgt_dev->dev_spec.pcie_inf.dev_info &4699			    MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) ==4700			    MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_NVME_DEVICE) &&4701			    ((tgt_dev->dev_spec.pcie_inf.dev_info &4702			    MPI3_DEVICE0_PCIE_DEVICE_INFO_PITYPE_MASK) !=4703			    MPI3_DEVICE0_PCIE_DEVICE_INFO_PITYPE_0))4704				scsi_tgt_priv_data->dev_nvme_dif = 1;4705			scsi_tgt_priv_data->io_throttle_enabled = tgt_dev->io_throttle_enabled;4706			scsi_tgt_priv_data->wslen = tgt_dev->wslen;4707			if (tgt_dev->dev_type == MPI3_DEVICE_DEVFORM_VD)4708				scsi_tgt_priv_data->throttle_group = tgt_dev->dev_spec.vd_inf.tg;4709		} else4710			retval = -ENXIO;4711	} else if (mrioc->sas_transport_enabled && !starget->channel) {4712		rphy = dev_to_rphy(starget->dev.parent);4713		tgt_dev = __mpi3mr_get_tgtdev_by_addr_and_rphy(mrioc,4714		    rphy->identify.sas_address, rphy);4715		if (tgt_dev && !tgt_dev->is_hidden && !tgt_dev->non_stl &&4716		    (tgt_dev->dev_type == MPI3_DEVICE_DEVFORM_SAS_SATA)) {4717			scsi_tgt_priv_data->starget = starget;4718			scsi_tgt_priv_data->dev_handle = tgt_dev->dev_handle;4719			scsi_tgt_priv_data->perst_id = tgt_dev->perst_id;4720			scsi_tgt_priv_data->dev_type = tgt_dev->dev_type;4721			scsi_tgt_priv_data->tgt_dev = tgt_dev;4722			scsi_tgt_priv_data->io_throttle_enabled = tgt_dev->io_throttle_enabled;4723			scsi_tgt_priv_data->wslen = tgt_dev->wslen;4724			tgt_dev->starget = starget;4725			atomic_set(&scsi_tgt_priv_data->block_io, 0);4726			retval = 0;4727		} else4728			retval = -ENXIO;4729	}4730	spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);4731 4732	return retval;4733}4734 4735/**4736 * mpi3mr_check_return_unmap - Whether an unmap is allowed4737 * @mrioc: Adapter instance reference4738 * @scmd: SCSI Command reference4739 *4740 * The controller hardware cannot handle certain unmap commands4741 * for NVMe drives, this routine checks those and return true4742 * and completes the SCSI command with proper status and sense4743 * data.4744 *4745 * Return: TRUE for not  allowed unmap, FALSE otherwise.4746 */4747static bool mpi3mr_check_return_unmap(struct mpi3mr_ioc *mrioc,4748	struct scsi_cmnd *scmd)4749{4750	unsigned char *buf;4751	u16 param_len, desc_len, trunc_param_len;4752 4753	trunc_param_len = param_len = get_unaligned_be16(scmd->cmnd + 7);4754 4755	if (mrioc->pdev->revision) {4756		if ((param_len > 24) && ((param_len - 8) & 0xF)) {4757			trunc_param_len -= (param_len - 8) & 0xF;4758			dprint_scsi_command(mrioc, scmd, MPI3_DEBUG_SCSI_ERROR);4759			dprint_scsi_err(mrioc,4760			    "truncating param_len from (%d) to (%d)\n",4761			    param_len, trunc_param_len);4762			put_unaligned_be16(trunc_param_len, scmd->cmnd + 7);4763			dprint_scsi_command(mrioc, scmd, MPI3_DEBUG_SCSI_ERROR);4764		}4765		return false;4766	}4767 4768	if (!param_len) {4769		ioc_warn(mrioc,4770		    "%s: cdb received with zero parameter length\n",4771		    __func__);4772		scsi_print_command(scmd);4773		scmd->result = DID_OK << 16;4774		scsi_done(scmd);4775		return true;4776	}4777 4778	if (param_len < 24) {4779		ioc_warn(mrioc,4780		    "%s: cdb received with invalid param_len: %d\n",4781		    __func__, param_len);4782		scsi_print_command(scmd);4783		scmd->result = SAM_STAT_CHECK_CONDITION;4784		scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,4785		    0x1A, 0);4786		scsi_done(scmd);4787		return true;4788	}4789	if (param_len != scsi_bufflen(scmd)) {4790		ioc_warn(mrioc,4791		    "%s: cdb received with param_len: %d bufflen: %d\n",4792		    __func__, param_len, scsi_bufflen(scmd));4793		scsi_print_command(scmd);4794		scmd->result = SAM_STAT_CHECK_CONDITION;4795		scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,4796		    0x1A, 0);4797		scsi_done(scmd);4798		return true;4799	}4800	buf = kzalloc(scsi_bufflen(scmd), GFP_ATOMIC);4801	if (!buf) {4802		scsi_print_command(scmd);4803		scmd->result = SAM_STAT_CHECK_CONDITION;4804		scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,4805		    0x55, 0x03);4806		scsi_done(scmd);4807		return true;4808	}4809	scsi_sg_copy_to_buffer(scmd, buf, scsi_bufflen(scmd));4810	desc_len = get_unaligned_be16(&buf[2]);4811 4812	if (desc_len < 16) {4813		ioc_warn(mrioc,4814		    "%s: Invalid descriptor length in param list: %d\n",4815		    __func__, desc_len);4816		scsi_print_command(scmd);4817		scmd->result = SAM_STAT_CHECK_CONDITION;4818		scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,4819		    0x26, 0);4820		scsi_done(scmd);4821		kfree(buf);4822		return true;4823	}4824 4825	if (param_len > (desc_len + 8)) {4826		trunc_param_len = desc_len + 8;4827		scsi_print_command(scmd);4828		dprint_scsi_err(mrioc,4829		    "truncating param_len(%d) to desc_len+8(%d)\n",4830		    param_len, trunc_param_len);4831		put_unaligned_be16(trunc_param_len, scmd->cmnd + 7);4832		scsi_print_command(scmd);4833	}4834 4835	kfree(buf);4836	return false;4837}4838 4839/**4840 * mpi3mr_allow_scmd_to_fw - Command is allowed during shutdown4841 * @scmd: SCSI Command reference4842 *4843 * Checks whether a cdb is allowed during shutdown or not.4844 *4845 * Return: TRUE for allowed commands, FALSE otherwise.4846 */4847 4848inline bool mpi3mr_allow_scmd_to_fw(struct scsi_cmnd *scmd)4849{4850	switch (scmd->cmnd[0]) {4851	case SYNCHRONIZE_CACHE:4852	case START_STOP:4853		return true;4854	default:4855		return false;4856	}4857}4858 4859/**4860 * mpi3mr_qcmd - I/O request despatcher4861 * @shost: SCSI Host reference4862 * @scmd: SCSI Command reference4863 *4864 * Issues the SCSI Command as an MPI3 request.4865 *4866 * Return: 0 on successful queueing of the request or if the4867 *         request is completed with failure.4868 *         SCSI_MLQUEUE_DEVICE_BUSY when the device is busy.4869 *         SCSI_MLQUEUE_HOST_BUSY when the host queue is full.4870 */4871static int mpi3mr_qcmd(struct Scsi_Host *shost,4872	struct scsi_cmnd *scmd)4873{4874	struct mpi3mr_ioc *mrioc = shost_priv(shost);4875	struct mpi3mr_stgt_priv_data *stgt_priv_data;4876	struct mpi3mr_sdev_priv_data *sdev_priv_data;4877	struct scmd_priv *scmd_priv_data = NULL;4878	struct mpi3_scsi_io_request *scsiio_req = NULL;4879	struct op_req_qinfo *op_req_q = NULL;4880	int retval = 0;4881	u16 dev_handle;4882	u16 host_tag;4883	u32 scsiio_flags = 0, data_len_blks = 0;4884	struct request *rq = scsi_cmd_to_rq(scmd);4885	int iprio_class;4886	u8 is_pcie_dev = 0;4887	u32 tracked_io_sz = 0;4888	u32 ioc_pend_data_len = 0, tg_pend_data_len = 0;4889	struct mpi3mr_throttle_group_info *tg = NULL;4890 4891	if (mrioc->unrecoverable) {4892		scmd->result = DID_ERROR << 16;4893		scsi_done(scmd);4894		goto out;4895	}4896 4897	sdev_priv_data = scmd->device->hostdata;4898	if (!sdev_priv_data || !sdev_priv_data->tgt_priv_data) {4899		scmd->result = DID_NO_CONNECT << 16;4900		scsi_done(scmd);4901		goto out;4902	}4903 4904	if (mrioc->stop_drv_processing &&4905	    !(mpi3mr_allow_scmd_to_fw(scmd))) {4906		scmd->result = DID_NO_CONNECT << 16;4907		scsi_done(scmd);4908		goto out;4909	}4910 4911	stgt_priv_data = sdev_priv_data->tgt_priv_data;4912	dev_handle = stgt_priv_data->dev_handle;4913 4914	/* Avoid error handling escalation when device is removed or blocked */4915 4916	if (scmd->device->host->shost_state == SHOST_RECOVERY &&4917		scmd->cmnd[0] == TEST_UNIT_READY &&4918		(stgt_priv_data->dev_removed || (dev_handle == MPI3MR_INVALID_DEV_HANDLE))) {4919		scsi_build_sense(scmd, 0, UNIT_ATTENTION, 0x29, 0x07);4920		scsi_done(scmd);4921		goto out;4922	}4923 4924	if (mrioc->reset_in_progress || mrioc->prepare_for_reset4925	    || mrioc->block_on_pci_err) {4926		retval = SCSI_MLQUEUE_HOST_BUSY;4927		goto out;4928	}4929 4930	if (atomic_read(&stgt_priv_data->block_io)) {4931		if (mrioc->stop_drv_processing) {4932			scmd->result = DID_NO_CONNECT << 16;4933			scsi_done(scmd);4934			goto out;4935		}4936		retval = SCSI_MLQUEUE_DEVICE_BUSY;4937		goto out;4938	}4939 4940	if (dev_handle == MPI3MR_INVALID_DEV_HANDLE) {4941		scmd->result = DID_NO_CONNECT << 16;4942		scsi_done(scmd);4943		goto out;4944	}4945	if (stgt_priv_data->dev_removed) {4946		scmd->result = DID_NO_CONNECT << 16;4947		scsi_done(scmd);4948		goto out;4949	}4950 4951	if (stgt_priv_data->dev_type == MPI3_DEVICE_DEVFORM_PCIE)4952		is_pcie_dev = 1;4953	if ((scmd->cmnd[0] == UNMAP) && is_pcie_dev &&4954	    (mrioc->pdev->device == MPI3_MFGPAGE_DEVID_SAS4116) &&4955	    mpi3mr_check_return_unmap(mrioc, scmd))4956		goto out;4957 4958	host_tag = mpi3mr_host_tag_for_scmd(mrioc, scmd);4959	if (host_tag == MPI3MR_HOSTTAG_INVALID) {4960		scmd->result = DID_ERROR << 16;4961		scsi_done(scmd);4962		goto out;4963	}4964 4965	if (scmd->sc_data_direction == DMA_FROM_DEVICE)4966		scsiio_flags = MPI3_SCSIIO_FLAGS_DATADIRECTION_READ;4967	else if (scmd->sc_data_direction == DMA_TO_DEVICE)4968		scsiio_flags = MPI3_SCSIIO_FLAGS_DATADIRECTION_WRITE;4969	else4970		scsiio_flags = MPI3_SCSIIO_FLAGS_DATADIRECTION_NO_DATA_TRANSFER;4971 4972	scsiio_flags |= MPI3_SCSIIO_FLAGS_TASKATTRIBUTE_SIMPLEQ;4973 4974	if (sdev_priv_data->ncq_prio_enable) {4975		iprio_class = IOPRIO_PRIO_CLASS(req_get_ioprio(rq));4976		if (iprio_class == IOPRIO_CLASS_RT)4977			scsiio_flags |= 1 << MPI3_SCSIIO_FLAGS_CMDPRI_SHIFT;4978	}4979 4980	if (scmd->cmd_len > 16)4981		scsiio_flags |= MPI3_SCSIIO_FLAGS_CDB_GREATER_THAN_16;4982 4983	scmd_priv_data = scsi_cmd_priv(scmd);4984	memset(scmd_priv_data->mpi3mr_scsiio_req, 0, MPI3MR_ADMIN_REQ_FRAME_SZ);4985	scsiio_req = (struct mpi3_scsi_io_request *)scmd_priv_data->mpi3mr_scsiio_req;4986	scsiio_req->function = MPI3_FUNCTION_SCSI_IO;4987	scsiio_req->host_tag = cpu_to_le16(host_tag);4988 4989	mpi3mr_setup_eedp(mrioc, scmd, scsiio_req);4990 4991	if (stgt_priv_data->wslen)4992		mpi3mr_setup_divert_ws(mrioc, scmd, scsiio_req, &scsiio_flags,4993		    stgt_priv_data->wslen);4994 4995	memcpy(scsiio_req->cdb.cdb32, scmd->cmnd, scmd->cmd_len);4996	scsiio_req->data_length = cpu_to_le32(scsi_bufflen(scmd));4997	scsiio_req->dev_handle = cpu_to_le16(dev_handle);4998	scsiio_req->flags = cpu_to_le32(scsiio_flags);4999	int_to_scsilun(sdev_priv_data->lun_id,5000	    (struct scsi_lun *)scsiio_req->lun);5001 5002	if (mpi3mr_build_sg_scmd(mrioc, scmd, scsiio_req)) {5003		mpi3mr_clear_scmd_priv(mrioc, scmd);5004		retval = SCSI_MLQUEUE_HOST_BUSY;5005		goto out;5006	}5007	op_req_q = &mrioc->req_qinfo[scmd_priv_data->req_q_idx];5008	data_len_blks = scsi_bufflen(scmd) >> 9;5009	if ((data_len_blks >= mrioc->io_throttle_data_length) &&5010	    stgt_priv_data->io_throttle_enabled) {5011		tracked_io_sz = data_len_blks;5012		tg = stgt_priv_data->throttle_group;5013		if (tg) {5014			ioc_pend_data_len = atomic_add_return(data_len_blks,5015			    &mrioc->pend_large_data_sz);5016			tg_pend_data_len = atomic_add_return(data_len_blks,5017			    &tg->pend_large_data_sz);5018			if (!tg->io_divert  && ((ioc_pend_data_len >=5019			    mrioc->io_throttle_high) ||5020			    (tg_pend_data_len >= tg->high))) {5021				tg->io_divert = 1;5022				tg->need_qd_reduction = 1;5023				mpi3mr_set_io_divert_for_all_vd_in_tg(mrioc,5024				    tg, 1);5025				mpi3mr_queue_qd_reduction_event(mrioc, tg);5026			}5027		} else {5028			ioc_pend_data_len = atomic_add_return(data_len_blks,5029			    &mrioc->pend_large_data_sz);5030			if (ioc_pend_data_len >= mrioc->io_throttle_high)5031				stgt_priv_data->io_divert = 1;5032		}5033	}5034 5035	if (stgt_priv_data->io_divert) {5036		scsiio_req->msg_flags |=5037		    MPI3_SCSIIO_MSGFLAGS_DIVERT_TO_FIRMWARE;5038		scsiio_flags |= MPI3_SCSIIO_FLAGS_DIVERT_REASON_IO_THROTTLING;5039	}5040	scsiio_req->flags |= cpu_to_le32(scsiio_flags);5041 5042	if (mpi3mr_op_request_post(mrioc, op_req_q,5043	    scmd_priv_data->mpi3mr_scsiio_req)) {5044		mpi3mr_clear_scmd_priv(mrioc, scmd);5045		retval = SCSI_MLQUEUE_HOST_BUSY;5046		if (tracked_io_sz) {5047			atomic_sub(tracked_io_sz, &mrioc->pend_large_data_sz);5048			if (tg)5049				atomic_sub(tracked_io_sz,5050				    &tg->pend_large_data_sz);5051		}5052		goto out;5053	}5054 5055out:5056	return retval;5057}5058 5059static const struct scsi_host_template mpi3mr_driver_template = {5060	.module				= THIS_MODULE,5061	.name				= "MPI3 Storage Controller",5062	.proc_name			= MPI3MR_DRIVER_NAME,5063	.queuecommand			= mpi3mr_qcmd,5064	.target_alloc			= mpi3mr_target_alloc,5065	.slave_alloc			= mpi3mr_slave_alloc,5066	.device_configure		= mpi3mr_device_configure,5067	.target_destroy			= mpi3mr_target_destroy,5068	.slave_destroy			= mpi3mr_slave_destroy,5069	.scan_finished			= mpi3mr_scan_finished,5070	.scan_start			= mpi3mr_scan_start,5071	.change_queue_depth		= mpi3mr_change_queue_depth,5072	.eh_device_reset_handler	= mpi3mr_eh_dev_reset,5073	.eh_target_reset_handler	= mpi3mr_eh_target_reset,5074	.eh_bus_reset_handler		= mpi3mr_eh_bus_reset,5075	.eh_host_reset_handler		= mpi3mr_eh_host_reset,5076	.bios_param			= mpi3mr_bios_param,5077	.map_queues			= mpi3mr_map_queues,5078	.mq_poll                        = mpi3mr_blk_mq_poll,5079	.no_write_same			= 1,5080	.can_queue			= 1,5081	.this_id			= -1,5082	.sg_tablesize			= MPI3MR_DEFAULT_SGL_ENTRIES,5083	/* max xfer supported is 1M (2K in 512 byte sized sectors)5084	 */5085	.max_sectors			= (MPI3MR_DEFAULT_MAX_IO_SIZE / 512),5086	.cmd_per_lun			= MPI3MR_MAX_CMDS_LUN,5087	.max_segment_size		= 0xffffffff,5088	.track_queue_depth		= 1,5089	.cmd_size			= sizeof(struct scmd_priv),5090	.shost_groups			= mpi3mr_host_groups,5091	.sdev_groups			= mpi3mr_dev_groups,5092};5093 5094/**5095 * mpi3mr_init_drv_cmd - Initialize internal command tracker5096 * @cmdptr: Internal command tracker5097 * @host_tag: Host tag used for the specific command5098 *5099 * Initialize the internal command tracker structure with5100 * specified host tag.5101 *5102 * Return: Nothing.5103 */5104static inline void mpi3mr_init_drv_cmd(struct mpi3mr_drv_cmd *cmdptr,5105	u16 host_tag)5106{5107	mutex_init(&cmdptr->mutex);5108	cmdptr->reply = NULL;5109	cmdptr->state = MPI3MR_CMD_NOTUSED;5110	cmdptr->dev_handle = MPI3MR_INVALID_DEV_HANDLE;5111	cmdptr->host_tag = host_tag;5112}5113 5114/**5115 * osintfc_mrioc_security_status -Check controller secure status5116 * @pdev: PCI device instance5117 *5118 * Read the Device Serial Number capability from PCI config5119 * space and decide whether the controller is secure or not.5120 *5121 * Return: 0 on success, non-zero on failure.5122 */5123static int5124osintfc_mrioc_security_status(struct pci_dev *pdev)5125{5126	u32 cap_data;5127	int base;5128	u32 ctlr_status;5129	u32 debug_status;5130	int retval = 0;5131 5132	base = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_DSN);5133	if (!base) {5134		dev_err(&pdev->dev,5135		    "%s: PCI_EXT_CAP_ID_DSN is not supported\n", __func__);5136		return -1;5137	}5138 5139	pci_read_config_dword(pdev, base + 4, &cap_data);5140 5141	debug_status = cap_data & MPI3MR_CTLR_SECURE_DBG_STATUS_MASK;5142	ctlr_status = cap_data & MPI3MR_CTLR_SECURITY_STATUS_MASK;5143 5144	switch (ctlr_status) {5145	case MPI3MR_INVALID_DEVICE:5146		dev_err(&pdev->dev,5147		    "%s: Non secure ctlr (Invalid) is detected: DID: 0x%x: SVID: 0x%x: SDID: 0x%x\n",5148		    __func__, pdev->device, pdev->subsystem_vendor,5149		    pdev->subsystem_device);5150		retval = -1;5151		break;5152	case MPI3MR_CONFIG_SECURE_DEVICE:5153		if (!debug_status)5154			dev_info(&pdev->dev,5155			    "%s: Config secure ctlr is detected\n",5156			    __func__);5157		break;5158	case MPI3MR_HARD_SECURE_DEVICE:5159		break;5160	case MPI3MR_TAMPERED_DEVICE:5161		dev_err(&pdev->dev,5162		    "%s: Non secure ctlr (Tampered) is detected: DID: 0x%x: SVID: 0x%x: SDID: 0x%x\n",5163		    __func__, pdev->device, pdev->subsystem_vendor,5164		    pdev->subsystem_device);5165		retval = -1;5166		break;5167	default:5168		retval = -1;5169			break;5170	}5171 5172	if (!retval && debug_status) {5173		dev_err(&pdev->dev,5174		    "%s: Non secure ctlr (Secure Dbg) is detected: DID: 0x%x: SVID: 0x%x: SDID: 0x%x\n",5175		    __func__, pdev->device, pdev->subsystem_vendor,5176		    pdev->subsystem_device);5177		retval = -1;5178	}5179 5180	return retval;5181}5182 5183/**5184 * mpi3mr_probe - PCI probe callback5185 * @pdev: PCI device instance5186 * @id: PCI device ID details5187 *5188 * controller initialization routine. Checks the security status5189 * of the controller and if it is invalid or tampered return the5190 * probe without initializing the controller. Otherwise,5191 * allocate per adapter instance through shost_priv and5192 * initialize controller specific data structures, initializae5193 * the controller hardware, add shost to the SCSI subsystem.5194 *5195 * Return: 0 on success, non-zero on failure.5196 */5197 5198static int5199mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)5200{5201	struct mpi3mr_ioc *mrioc = NULL;5202	struct Scsi_Host *shost = NULL;5203	int retval = 0, i;5204 5205	if (osintfc_mrioc_security_status(pdev)) {5206		warn_non_secure_ctlr = 1;5207		return 1; /* For Invalid and Tampered device */5208	}5209 5210	shost = scsi_host_alloc(&mpi3mr_driver_template,5211	    sizeof(struct mpi3mr_ioc));5212	if (!shost) {5213		retval = -ENODEV;5214		goto shost_failed;5215	}5216 5217	mrioc = shost_priv(shost);5218	retval = ida_alloc_range(&mrioc_ida, 1, U8_MAX, GFP_KERNEL);5219	if (retval < 0)5220		goto id_alloc_failed;5221	mrioc->id = (u8)retval;5222	sprintf(mrioc->driver_name, "%s", MPI3MR_DRIVER_NAME);5223	sprintf(mrioc->name, "%s%d", mrioc->driver_name, mrioc->id);5224	INIT_LIST_HEAD(&mrioc->list);5225	spin_lock(&mrioc_list_lock);5226	list_add_tail(&mrioc->list, &mrioc_list);5227	spin_unlock(&mrioc_list_lock);5228 5229	spin_lock_init(&mrioc->admin_req_lock);5230	spin_lock_init(&mrioc->reply_free_queue_lock);5231	spin_lock_init(&mrioc->sbq_lock);5232	spin_lock_init(&mrioc->fwevt_lock);5233	spin_lock_init(&mrioc->tgtdev_lock);5234	spin_lock_init(&mrioc->watchdog_lock);5235	spin_lock_init(&mrioc->chain_buf_lock);5236	spin_lock_init(&mrioc->sas_node_lock);5237	spin_lock_init(&mrioc->trigger_lock);5238 5239	INIT_LIST_HEAD(&mrioc->fwevt_list);5240	INIT_LIST_HEAD(&mrioc->tgtdev_list);5241	INIT_LIST_HEAD(&mrioc->delayed_rmhs_list);5242	INIT_LIST_HEAD(&mrioc->delayed_evtack_cmds_list);5243	INIT_LIST_HEAD(&mrioc->sas_expander_list);5244	INIT_LIST_HEAD(&mrioc->hba_port_table_list);5245	INIT_LIST_HEAD(&mrioc->enclosure_list);5246 5247	mutex_init(&mrioc->reset_mutex);5248	mpi3mr_init_drv_cmd(&mrioc->init_cmds, MPI3MR_HOSTTAG_INITCMDS);5249	mpi3mr_init_drv_cmd(&mrioc->host_tm_cmds, MPI3MR_HOSTTAG_BLK_TMS);5250	mpi3mr_init_drv_cmd(&mrioc->bsg_cmds, MPI3MR_HOSTTAG_BSG_CMDS);5251	mpi3mr_init_drv_cmd(&mrioc->cfg_cmds, MPI3MR_HOSTTAG_CFG_CMDS);5252	mpi3mr_init_drv_cmd(&mrioc->transport_cmds,5253	    MPI3MR_HOSTTAG_TRANSPORT_CMDS);5254 5255	for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++)5256		mpi3mr_init_drv_cmd(&mrioc->dev_rmhs_cmds[i],5257		    MPI3MR_HOSTTAG_DEVRMCMD_MIN + i);5258 5259	for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++)5260		mpi3mr_init_drv_cmd(&mrioc->evtack_cmds[i],5261				    MPI3MR_HOSTTAG_EVTACKCMD_MIN + i);5262 5263	if ((pdev->device == MPI3_MFGPAGE_DEVID_SAS4116) &&5264		!pdev->revision)5265		mrioc->enable_segqueue = false;5266	else5267		mrioc->enable_segqueue = true;5268 5269	init_waitqueue_head(&mrioc->reset_waitq);5270	mrioc->logging_level = logging_level;5271	mrioc->shost = shost;5272	mrioc->pdev = pdev;5273	mrioc->stop_bsgs = 1;5274 5275	mrioc->max_sgl_entries = max_sgl_entries;5276	if (max_sgl_entries > MPI3MR_MAX_SGL_ENTRIES)5277		mrioc->max_sgl_entries = MPI3MR_MAX_SGL_ENTRIES;5278	else if (max_sgl_entries < MPI3MR_DEFAULT_SGL_ENTRIES)5279		mrioc->max_sgl_entries = MPI3MR_DEFAULT_SGL_ENTRIES;5280	else {5281		mrioc->max_sgl_entries /= MPI3MR_DEFAULT_SGL_ENTRIES;5282		mrioc->max_sgl_entries *= MPI3MR_DEFAULT_SGL_ENTRIES;5283	}5284 5285	/* init shost parameters */5286	shost->max_cmd_len = MPI3MR_MAX_CDB_LENGTH;5287	shost->max_lun = -1;5288	shost->unique_id = mrioc->id;5289 5290	shost->max_channel = 0;5291	shost->max_id = 0xFFFFFFFF;5292 5293	shost->host_tagset = 1;5294 5295	if (prot_mask >= 0)5296		scsi_host_set_prot(shost, prot_mask);5297	else {5298		prot_mask = SHOST_DIF_TYPE1_PROTECTION5299		    | SHOST_DIF_TYPE2_PROTECTION5300		    | SHOST_DIF_TYPE3_PROTECTION;5301		scsi_host_set_prot(shost, prot_mask);5302	}5303 5304	ioc_info(mrioc,5305	    "%s :host protection capabilities enabled %s%s%s%s%s%s%s\n",5306	    __func__,5307	    (prot_mask & SHOST_DIF_TYPE1_PROTECTION) ? " DIF1" : "",5308	    (prot_mask & SHOST_DIF_TYPE2_PROTECTION) ? " DIF2" : "",5309	    (prot_mask & SHOST_DIF_TYPE3_PROTECTION) ? " DIF3" : "",5310	    (prot_mask & SHOST_DIX_TYPE0_PROTECTION) ? " DIX0" : "",5311	    (prot_mask & SHOST_DIX_TYPE1_PROTECTION) ? " DIX1" : "",5312	    (prot_mask & SHOST_DIX_TYPE2_PROTECTION) ? " DIX2" : "",5313	    (prot_mask & SHOST_DIX_TYPE3_PROTECTION) ? " DIX3" : "");5314 5315	if (prot_guard_mask)5316		scsi_host_set_guard(shost, (prot_guard_mask & 3));5317	else5318		scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC);5319 5320	mrioc->fwevt_worker_thread = alloc_ordered_workqueue(5321		"%s%d_fwevt_wrkr", 0, mrioc->driver_name, mrioc->id);5322	if (!mrioc->fwevt_worker_thread) {5323		ioc_err(mrioc, "failure at %s:%d/%s()!\n",5324		    __FILE__, __LINE__, __func__);5325		retval = -ENODEV;5326		goto fwevtthread_failed;5327	}5328 5329	mrioc->is_driver_loading = 1;5330	mrioc->cpu_count = num_online_cpus();5331	if (mpi3mr_setup_resources(mrioc)) {5332		ioc_err(mrioc, "setup resources failed\n");5333		retval = -ENODEV;5334		goto resource_alloc_failed;5335	}5336	if (mpi3mr_init_ioc(mrioc)) {5337		ioc_err(mrioc, "initializing IOC failed\n");5338		retval = -ENODEV;5339		goto init_ioc_failed;5340	}5341 5342	shost->nr_hw_queues = mrioc->num_op_reply_q;5343	if (mrioc->active_poll_qcount)5344		shost->nr_maps = 3;5345 5346	shost->can_queue = mrioc->max_host_ios;5347	shost->sg_tablesize = mrioc->max_sgl_entries;5348	shost->max_id = mrioc->facts.max_perids + 1;5349 5350	retval = scsi_add_host(shost, &pdev->dev);5351	if (retval) {5352		ioc_err(mrioc, "failure at %s:%d/%s()!\n",5353		    __FILE__, __LINE__, __func__);5354		goto addhost_failed;5355	}5356 5357	scsi_scan_host(shost);5358	mpi3mr_bsg_init(mrioc);5359	return retval;5360 5361addhost_failed:5362	mpi3mr_stop_watchdog(mrioc);5363	mpi3mr_cleanup_ioc(mrioc);5364init_ioc_failed:5365	mpi3mr_free_mem(mrioc);5366	mpi3mr_cleanup_resources(mrioc);5367resource_alloc_failed:5368	destroy_workqueue(mrioc->fwevt_worker_thread);5369fwevtthread_failed:5370	ida_free(&mrioc_ida, mrioc->id);5371	spin_lock(&mrioc_list_lock);5372	list_del(&mrioc->list);5373	spin_unlock(&mrioc_list_lock);5374id_alloc_failed:5375	scsi_host_put(shost);5376shost_failed:5377	return retval;5378}5379 5380/**5381 * mpi3mr_remove - PCI remove callback5382 * @pdev: PCI device instance5383 *5384 * Cleanup the IOC by issuing MUR and shutdown notification.5385 * Free up all memory and resources associated with the5386 * controllerand target devices, unregister the shost.5387 *5388 * Return: Nothing.5389 */5390static void mpi3mr_remove(struct pci_dev *pdev)5391{5392	struct Scsi_Host *shost = pci_get_drvdata(pdev);5393	struct mpi3mr_ioc *mrioc;5394	struct workqueue_struct	*wq;5395	unsigned long flags;5396	struct mpi3mr_tgt_dev *tgtdev, *tgtdev_next;5397	struct mpi3mr_hba_port *port, *hba_port_next;5398	struct mpi3mr_sas_node *sas_expander, *sas_expander_next;5399 5400	if (!shost)5401		return;5402 5403	mrioc = shost_priv(shost);5404	while (mrioc->reset_in_progress || mrioc->is_driver_loading)5405		ssleep(1);5406 5407	if (mrioc->block_on_pci_err) {5408		mrioc->block_on_pci_err = false;5409		scsi_unblock_requests(shost);5410		mrioc->unrecoverable = 1;5411	}5412 5413	if (!pci_device_is_present(mrioc->pdev) ||5414	    mrioc->pci_err_recovery) {5415		mrioc->unrecoverable = 1;5416		mpi3mr_flush_cmds_for_unrecovered_controller(mrioc);5417	}5418 5419	mpi3mr_bsg_exit(mrioc);5420	mrioc->stop_drv_processing = 1;5421	mpi3mr_cleanup_fwevt_list(mrioc);5422	spin_lock_irqsave(&mrioc->fwevt_lock, flags);5423	wq = mrioc->fwevt_worker_thread;5424	mrioc->fwevt_worker_thread = NULL;5425	spin_unlock_irqrestore(&mrioc->fwevt_lock, flags);5426	if (wq)5427		destroy_workqueue(wq);5428 5429	if (mrioc->sas_transport_enabled)5430		sas_remove_host(shost);5431	else5432		scsi_remove_host(shost);5433 5434	list_for_each_entry_safe(tgtdev, tgtdev_next, &mrioc->tgtdev_list,5435	    list) {5436		mpi3mr_remove_tgtdev_from_host(mrioc, tgtdev);5437		mpi3mr_tgtdev_del_from_list(mrioc, tgtdev, true);5438		mpi3mr_tgtdev_put(tgtdev);5439	}5440	mpi3mr_stop_watchdog(mrioc);5441	mpi3mr_cleanup_ioc(mrioc);5442	mpi3mr_free_mem(mrioc);5443	mpi3mr_cleanup_resources(mrioc);5444 5445	spin_lock_irqsave(&mrioc->sas_node_lock, flags);5446	list_for_each_entry_safe_reverse(sas_expander, sas_expander_next,5447	    &mrioc->sas_expander_list, list) {5448		spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);5449		mpi3mr_expander_node_remove(mrioc, sas_expander);5450		spin_lock_irqsave(&mrioc->sas_node_lock, flags);5451	}5452	list_for_each_entry_safe(port, hba_port_next, &mrioc->hba_port_table_list, list) {5453		ioc_info(mrioc,5454		    "removing hba_port entry: %p port: %d from hba_port list\n",5455		    port, port->port_id);5456		list_del(&port->list);5457		kfree(port);5458	}5459	spin_unlock_irqrestore(&mrioc->sas_node_lock, flags);5460 5461	if (mrioc->sas_hba.num_phys) {5462		kfree(mrioc->sas_hba.phy);5463		mrioc->sas_hba.phy = NULL;5464		mrioc->sas_hba.num_phys = 0;5465	}5466 5467	ida_free(&mrioc_ida, mrioc->id);5468	spin_lock(&mrioc_list_lock);5469	list_del(&mrioc->list);5470	spin_unlock(&mrioc_list_lock);5471 5472	scsi_host_put(shost);5473}5474 5475/**5476 * mpi3mr_shutdown - PCI shutdown callback5477 * @pdev: PCI device instance5478 *5479 * Free up all memory and resources associated with the5480 * controller5481 *5482 * Return: Nothing.5483 */5484static void mpi3mr_shutdown(struct pci_dev *pdev)5485{5486	struct Scsi_Host *shost = pci_get_drvdata(pdev);5487	struct mpi3mr_ioc *mrioc;5488	struct workqueue_struct	*wq;5489	unsigned long flags;5490 5491	if (!shost)5492		return;5493 5494	mrioc = shost_priv(shost);5495	while (mrioc->reset_in_progress || mrioc->is_driver_loading)5496		ssleep(1);5497 5498	mrioc->stop_drv_processing = 1;5499	mpi3mr_cleanup_fwevt_list(mrioc);5500	spin_lock_irqsave(&mrioc->fwevt_lock, flags);5501	wq = mrioc->fwevt_worker_thread;5502	mrioc->fwevt_worker_thread = NULL;5503	spin_unlock_irqrestore(&mrioc->fwevt_lock, flags);5504	if (wq)5505		destroy_workqueue(wq);5506 5507	mpi3mr_stop_watchdog(mrioc);5508	mpi3mr_cleanup_ioc(mrioc);5509	mpi3mr_cleanup_resources(mrioc);5510}5511 5512/**5513 * mpi3mr_suspend - PCI power management suspend callback5514 * @dev: Device struct5515 *5516 * Change the power state to the given value and cleanup the IOC5517 * by issuing MUR and shutdown notification5518 *5519 * Return: 0 always.5520 */5521static int __maybe_unused5522mpi3mr_suspend(struct device *dev)5523{5524	struct pci_dev *pdev = to_pci_dev(dev);5525	struct Scsi_Host *shost = pci_get_drvdata(pdev);5526	struct mpi3mr_ioc *mrioc;5527 5528	if (!shost)5529		return 0;5530 5531	mrioc = shost_priv(shost);5532	while (mrioc->reset_in_progress || mrioc->is_driver_loading)5533		ssleep(1);5534	mrioc->stop_drv_processing = 1;5535	mpi3mr_cleanup_fwevt_list(mrioc);5536	scsi_block_requests(shost);5537	mpi3mr_stop_watchdog(mrioc);5538	mpi3mr_cleanup_ioc(mrioc);5539 5540	ioc_info(mrioc, "pdev=0x%p, slot=%s, entering operating state\n",5541	    pdev, pci_name(pdev));5542	mpi3mr_cleanup_resources(mrioc);5543 5544	return 0;5545}5546 5547/**5548 * mpi3mr_resume - PCI power management resume callback5549 * @dev: Device struct5550 *5551 * Restore the power state to D0 and reinitialize the controller5552 * and resume I/O operations to the target devices5553 *5554 * Return: 0 on success, non-zero on failure5555 */5556static int __maybe_unused5557mpi3mr_resume(struct device *dev)5558{5559	struct pci_dev *pdev = to_pci_dev(dev);5560	struct Scsi_Host *shost = pci_get_drvdata(pdev);5561	struct mpi3mr_ioc *mrioc;5562	pci_power_t device_state = pdev->current_state;5563	int r;5564 5565	if (!shost)5566		return 0;5567 5568	mrioc = shost_priv(shost);5569 5570	ioc_info(mrioc, "pdev=0x%p, slot=%s, previous operating state [D%d]\n",5571	    pdev, pci_name(pdev), device_state);5572	mrioc->pdev = pdev;5573	mrioc->cpu_count = num_online_cpus();5574	r = mpi3mr_setup_resources(mrioc);5575	if (r) {5576		ioc_info(mrioc, "%s: Setup resources failed[%d]\n",5577		    __func__, r);5578		return r;5579	}5580 5581	mrioc->stop_drv_processing = 0;5582	mpi3mr_invalidate_devhandles(mrioc);5583	mpi3mr_free_enclosure_list(mrioc);5584	mpi3mr_memset_buffers(mrioc);5585	r = mpi3mr_reinit_ioc(mrioc, 1);5586	if (r) {5587		ioc_err(mrioc, "resuming controller failed[%d]\n", r);5588		return r;5589	}5590	ssleep(MPI3MR_RESET_TOPOLOGY_SETTLE_TIME);5591	scsi_unblock_requests(shost);5592	mrioc->device_refresh_on = 0;5593	mpi3mr_start_watchdog(mrioc);5594 5595	return 0;5596}5597 5598/**5599 * mpi3mr_pcierr_error_detected - PCI error detected callback5600 * @pdev: PCI device instance5601 * @state: channel state5602 *5603 * This function is called by the PCI error recovery driver and5604 * based on the state passed the driver decides what actions to5605 * be recommended back to PCI driver.5606 *5607 * For all of the states if there is no valid mrioc or scsi host5608 * references in the PCI device then this function will return5609 * the result as disconnect.5610 *5611 * For normal state, this function will return the result as can5612 * recover.5613 *5614 * For frozen state, this function will block for any pending5615 * controller initialization or re-initialization to complete,5616 * stop any new interactions with the controller and return5617 * status as reset required.5618 *5619 * For permanent failure state, this function will mark the5620 * controller as unrecoverable and return status as disconnect.5621 *5622 * Returns: PCI_ERS_RESULT_NEED_RESET or CAN_RECOVER or5623 * DISCONNECT based on the controller state.5624 */5625static pci_ers_result_t5626mpi3mr_pcierr_error_detected(struct pci_dev *pdev, pci_channel_state_t state)5627{5628	struct Scsi_Host *shost;5629	struct mpi3mr_ioc *mrioc;5630	unsigned int timeout = MPI3MR_RESET_TIMEOUT;5631 5632	dev_info(&pdev->dev, "%s: callback invoked state(%d)\n", __func__,5633	    state);5634 5635	shost = pci_get_drvdata(pdev);5636	mrioc = shost_priv(shost);5637 5638	switch (state) {5639	case pci_channel_io_normal:5640		return PCI_ERS_RESULT_CAN_RECOVER;5641	case pci_channel_io_frozen:5642		mrioc->pci_err_recovery = true;5643		mrioc->block_on_pci_err = true;5644		do {5645			if (mrioc->reset_in_progress || mrioc->is_driver_loading)5646				ssleep(1);5647			else5648				break;5649		} while (--timeout);5650 5651		if (!timeout) {5652			mrioc->pci_err_recovery = true;5653			mrioc->block_on_pci_err = true;5654			mrioc->unrecoverable = 1;5655			mpi3mr_stop_watchdog(mrioc);5656			mpi3mr_flush_cmds_for_unrecovered_controller(mrioc);5657			return PCI_ERS_RESULT_DISCONNECT;5658		}5659 5660		scsi_block_requests(mrioc->shost);5661		mpi3mr_stop_watchdog(mrioc);5662		mpi3mr_cleanup_resources(mrioc);5663		return PCI_ERS_RESULT_NEED_RESET;5664	case pci_channel_io_perm_failure:5665		mrioc->pci_err_recovery = true;5666		mrioc->block_on_pci_err = true;5667		mrioc->unrecoverable = 1;5668		mpi3mr_stop_watchdog(mrioc);5669		mpi3mr_flush_cmds_for_unrecovered_controller(mrioc);5670		return PCI_ERS_RESULT_DISCONNECT;5671	default:5672		return PCI_ERS_RESULT_DISCONNECT;5673	}5674}5675 5676/**5677 * mpi3mr_pcierr_slot_reset - Post slot reset callback5678 * @pdev: PCI device instance5679 *5680 * This function is called by the PCI error recovery driver5681 * after a slot or link reset issued by it for the recovery, the5682 * driver is expected to bring back the controller and5683 * initialize it.5684 *5685 * This function restores PCI state and reinitializes controller5686 * resources and the controller, this blocks for any pending5687 * reset to complete.5688 *5689 * Returns: PCI_ERS_RESULT_DISCONNECT on failure or5690 * PCI_ERS_RESULT_RECOVERED5691 */5692static pci_ers_result_t mpi3mr_pcierr_slot_reset(struct pci_dev *pdev)5693{5694	struct Scsi_Host *shost;5695	struct mpi3mr_ioc *mrioc;5696	unsigned int timeout = MPI3MR_RESET_TIMEOUT;5697 5698	dev_info(&pdev->dev, "%s: callback invoked\n", __func__);5699 5700	shost = pci_get_drvdata(pdev);5701	mrioc = shost_priv(shost);5702 5703	do {5704		if (mrioc->reset_in_progress)5705			ssleep(1);5706		else5707			break;5708	} while (--timeout);5709 5710	if (!timeout)5711		goto out_failed;5712 5713	pci_restore_state(pdev);5714 5715	if (mpi3mr_setup_resources(mrioc)) {5716		ioc_err(mrioc, "setup resources failed\n");5717		goto out_failed;5718	}5719	mrioc->unrecoverable = 0;5720	mrioc->pci_err_recovery = false;5721 5722	if (mpi3mr_soft_reset_handler(mrioc, MPI3MR_RESET_FROM_FIRMWARE, 0))5723		goto out_failed;5724 5725	return PCI_ERS_RESULT_RECOVERED;5726 5727out_failed:5728	mrioc->unrecoverable = 1;5729	mrioc->block_on_pci_err = false;5730	scsi_unblock_requests(shost);5731	mpi3mr_start_watchdog(mrioc);5732	return PCI_ERS_RESULT_DISCONNECT;5733}5734 5735/**5736 * mpi3mr_pcierr_resume - PCI error recovery resume5737 * callback5738 * @pdev: PCI device instance5739 *5740 * This function enables all I/O and IOCTLs post reset issued as5741 * part of the PCI error recovery5742 *5743 * Return: Nothing.5744 */5745static void mpi3mr_pcierr_resume(struct pci_dev *pdev)5746{5747	struct Scsi_Host *shost;5748	struct mpi3mr_ioc *mrioc;5749 5750	dev_info(&pdev->dev, "%s: callback invoked\n", __func__);5751 5752	shost = pci_get_drvdata(pdev);5753	mrioc = shost_priv(shost);5754 5755	if (mrioc->block_on_pci_err) {5756		mrioc->block_on_pci_err = false;5757		scsi_unblock_requests(shost);5758		mpi3mr_start_watchdog(mrioc);5759	}5760}5761 5762/**5763 * mpi3mr_pcierr_mmio_enabled - PCI error recovery callback5764 * @pdev: PCI device instance5765 *5766 * This is called only if mpi3mr_pcierr_error_detected returns5767 * PCI_ERS_RESULT_CAN_RECOVER.5768 *5769 * Return: PCI_ERS_RESULT_DISCONNECT when the controller is5770 * unrecoverable or when the shost/mrioc reference cannot be5771 * found, else return PCI_ERS_RESULT_RECOVERED5772 */5773static pci_ers_result_t mpi3mr_pcierr_mmio_enabled(struct pci_dev *pdev)5774{5775	struct Scsi_Host *shost;5776	struct mpi3mr_ioc *mrioc;5777 5778	dev_info(&pdev->dev, "%s: callback invoked\n", __func__);5779 5780	shost = pci_get_drvdata(pdev);5781	mrioc = shost_priv(shost);5782 5783	if (mrioc->unrecoverable)5784		return PCI_ERS_RESULT_DISCONNECT;5785 5786	return PCI_ERS_RESULT_RECOVERED;5787}5788 5789static const struct pci_device_id mpi3mr_pci_id_table[] = {5790	{5791		PCI_DEVICE_SUB(MPI3_MFGPAGE_VENDORID_BROADCOM,5792		    MPI3_MFGPAGE_DEVID_SAS4116, PCI_ANY_ID, PCI_ANY_ID)5793	},5794	{5795		PCI_DEVICE_SUB(MPI3_MFGPAGE_VENDORID_BROADCOM,5796		    MPI3_MFGPAGE_DEVID_SAS5116_MPI, PCI_ANY_ID, PCI_ANY_ID)5797	},5798	{5799		PCI_DEVICE_SUB(MPI3_MFGPAGE_VENDORID_BROADCOM,5800		    MPI3_MFGPAGE_DEVID_SAS5116_MPI_MGMT, PCI_ANY_ID, PCI_ANY_ID)5801	},5802	{ 0 }5803};5804MODULE_DEVICE_TABLE(pci, mpi3mr_pci_id_table);5805 5806static struct pci_error_handlers mpi3mr_err_handler = {5807	.error_detected = mpi3mr_pcierr_error_detected,5808	.mmio_enabled = mpi3mr_pcierr_mmio_enabled,5809	.slot_reset = mpi3mr_pcierr_slot_reset,5810	.resume = mpi3mr_pcierr_resume,5811};5812 5813static SIMPLE_DEV_PM_OPS(mpi3mr_pm_ops, mpi3mr_suspend, mpi3mr_resume);5814 5815static struct pci_driver mpi3mr_pci_driver = {5816	.name = MPI3MR_DRIVER_NAME,5817	.id_table = mpi3mr_pci_id_table,5818	.probe = mpi3mr_probe,5819	.remove = mpi3mr_remove,5820	.shutdown = mpi3mr_shutdown,5821	.err_handler = &mpi3mr_err_handler,5822	.driver.pm = &mpi3mr_pm_ops,5823};5824 5825static ssize_t event_counter_show(struct device_driver *dd, char *buf)5826{5827	return sprintf(buf, "%llu\n", atomic64_read(&event_counter));5828}5829static DRIVER_ATTR_RO(event_counter);5830 5831static int __init mpi3mr_init(void)5832{5833	int ret_val;5834 5835	pr_info("Loading %s version %s\n", MPI3MR_DRIVER_NAME,5836	    MPI3MR_DRIVER_VERSION);5837 5838	mpi3mr_transport_template =5839	    sas_attach_transport(&mpi3mr_transport_functions);5840	if (!mpi3mr_transport_template) {5841		pr_err("%s failed to load due to sas transport attach failure\n",5842		    MPI3MR_DRIVER_NAME);5843		return -ENODEV;5844	}5845 5846	ret_val = pci_register_driver(&mpi3mr_pci_driver);5847	if (ret_val) {5848		pr_err("%s failed to load due to pci register driver failure\n",5849		    MPI3MR_DRIVER_NAME);5850		goto err_pci_reg_fail;5851	}5852 5853	ret_val = driver_create_file(&mpi3mr_pci_driver.driver,5854				     &driver_attr_event_counter);5855	if (ret_val)5856		goto err_event_counter;5857 5858	return ret_val;5859 5860err_event_counter:5861	pci_unregister_driver(&mpi3mr_pci_driver);5862 5863err_pci_reg_fail:5864	sas_release_transport(mpi3mr_transport_template);5865	return ret_val;5866}5867 5868static void __exit mpi3mr_exit(void)5869{5870	if (warn_non_secure_ctlr)5871		pr_warn(5872		    "Unloading %s version %s while managing a non secure controller\n",5873		    MPI3MR_DRIVER_NAME, MPI3MR_DRIVER_VERSION);5874	else5875		pr_info("Unloading %s version %s\n", MPI3MR_DRIVER_NAME,5876		    MPI3MR_DRIVER_VERSION);5877 5878	driver_remove_file(&mpi3mr_pci_driver.driver,5879			   &driver_attr_event_counter);5880	pci_unregister_driver(&mpi3mr_pci_driver);5881	sas_release_transport(mpi3mr_transport_template);5882	ida_destroy(&mrioc_ida);5883}5884 5885module_init(mpi3mr_init);5886module_exit(mpi3mr_exit);5887