xref: /freebsd/sys/dev/mpi3mr/mpi3mr.c (revision b670c9bafc0e31c7609969bf374b2e80bdc00211)
1 /*
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2016-2025, Broadcom Inc. All rights reserved.
5  * Support: <fbsd-storage-driver.pdl@broadcom.com>
6  *
7  * Authors: Sumit Saxena <sumit.saxena@broadcom.com>
8  *	    Chandrakanth Patil <chandrakanth.patil@broadcom.com>
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are
12  * met:
13  *
14  * 1. Redistributions of source code must retain the above copyright notice,
15  *    this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright notice,
17  *    this list of conditions and the following disclaimer in the documentation and/or other
18  *    materials provided with the distribution.
19  * 3. Neither the name of the Broadcom Inc. nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software without
21  *    specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * The views and conclusions contained in the software and documentation are
36  * those of the authors and should not be interpreted as representing
37  * official policies,either expressed or implied, of the FreeBSD Project.
38  *
39  * Mail to: Broadcom Inc 1320 Ridder Park Dr, San Jose, CA 95131
40  *
41  * Broadcom Inc. (Broadcom) MPI3MR Adapter FreeBSD
42  */
43 
44 #include <sys/types.h>
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/kernel.h>
48 #include <sys/module.h>
49 #include <sys/bus.h>
50 #include <sys/conf.h>
51 #include <sys/malloc.h>
52 #include <sys/sysctl.h>
53 #include <sys/uio.h>
54 
55 #include <machine/bus.h>
56 #include <machine/resource.h>
57 #include <sys/rman.h>
58 
59 #include <dev/pci/pcireg.h>
60 #include <dev/pci/pcivar.h>
61 #include <dev/pci/pci_private.h>
62 
63 #include <cam/cam.h>
64 #include <cam/cam_ccb.h>
65 #include <cam/cam_debug.h>
66 #include <cam/cam_sim.h>
67 #include <cam/cam_xpt_sim.h>
68 #include <cam/cam_xpt_periph.h>
69 #include <cam/cam_periph.h>
70 #include <cam/scsi/scsi_all.h>
71 #include <cam/scsi/scsi_message.h>
72 #include <cam/scsi/smp_all.h>
73 #include <sys/queue.h>
74 #include <sys/kthread.h>
75 #include "mpi3mr.h"
76 #include "mpi3mr_cam.h"
77 #include "mpi3mr_app.h"
78 
79 static void mpi3mr_repost_reply_buf(struct mpi3mr_softc *sc,
80 	U64 reply_dma);
81 static int mpi3mr_complete_admin_cmd(struct mpi3mr_softc *sc);
82 static void mpi3mr_port_enable_complete(struct mpi3mr_softc *sc,
83 	struct mpi3mr_drvr_cmd *drvrcmd);
84 static void mpi3mr_flush_io(struct mpi3mr_softc *sc);
85 static int mpi3mr_issue_reset(struct mpi3mr_softc *sc, U16 reset_type,
86 	U16 reset_reason);
87 static void mpi3mr_dev_rmhs_send_tm(struct mpi3mr_softc *sc, U16 handle,
88 	struct mpi3mr_drvr_cmd *cmdparam, U8 iou_rc);
89 static void mpi3mr_dev_rmhs_complete_iou(struct mpi3mr_softc *sc,
90 	struct mpi3mr_drvr_cmd *drv_cmd);
91 static void mpi3mr_dev_rmhs_complete_tm(struct mpi3mr_softc *sc,
92 	struct mpi3mr_drvr_cmd *drv_cmd);
93 static void mpi3mr_send_evt_ack(struct mpi3mr_softc *sc, U8 event,
94 	struct mpi3mr_drvr_cmd *cmdparam, U32 event_ctx);
95 static void mpi3mr_print_fault_info(struct mpi3mr_softc *sc);
96 static inline void mpi3mr_set_diagsave(struct mpi3mr_softc *sc);
97 static const char *mpi3mr_reset_rc_name(enum mpi3mr_reset_reason reason_code);
98 
99 void
100 mpi3mr_hexdump(void *buf, int sz, int format)
101 {
102         int i;
103         U32 *buf_loc = (U32 *)buf;
104 
105         for (i = 0; i < (sz / sizeof(U32)); i++) {
106                 if ((i % format) == 0) {
107                         if (i != 0)
108                                 printf("\n");
109                         printf("%08x: ", (i * 4));
110                 }
111                 printf("%08x ", buf_loc[i]);
112         }
113         printf("\n");
114 }
115 
116 void
117 init_completion(struct completion *completion)
118 {
119 	completion->done = 0;
120 }
121 
122 void
123 complete(struct completion *completion)
124 {
125 	completion->done = 1;
126 	wakeup(complete);
127 }
128 
129 void wait_for_completion_timeout(struct completion *completion,
130 	    U32 timeout)
131 {
132 	U32 count = timeout * 1000;
133 
134 	while ((completion->done == 0) && count) {
135                 DELAY(1000);
136 		count--;
137 	}
138 
139 	if (completion->done == 0) {
140 		printf("%s: Command is timedout\n", __func__);
141 		completion->done = 1;
142 	}
143 }
144 void wait_for_completion_timeout_tm(struct completion *completion,
145 	    U32 timeout, struct mpi3mr_softc *sc)
146 {
147 	U32 count = timeout * 1000;
148 
149 	while ((completion->done == 0) && count) {
150 		msleep(&sc->tm_chan, &sc->mpi3mr_mtx, PRIBIO,
151 		       "TM command", 1 * hz);
152 		count--;
153 	}
154 
155 	if (completion->done == 0) {
156 		printf("%s: Command is timedout\n", __func__);
157 		completion->done = 1;
158 	}
159 }
160 
161 
162 void
163 poll_for_command_completion(struct mpi3mr_softc *sc,
164        struct mpi3mr_drvr_cmd *cmd, U16 wait)
165 {
166 	int wait_time = wait * 1000;
167        while (wait_time) {
168                mpi3mr_complete_admin_cmd(sc);
169                if (cmd->state & MPI3MR_CMD_COMPLETE)
170                        break;
171 	       DELAY(1000);
172                wait_time--;
173        }
174 }
175 
176 /**
177  * mpi3mr_trigger_snapdump - triggers firmware snapdump
178  * @sc: Adapter instance reference
179  * @reason_code: reason code for the fault.
180  *
181  * This routine will trigger the snapdump and wait for it to
182  * complete or timeout before it returns.
183  * This will be called during initilaization time faults/resets/timeouts
184  * before soft reset invocation.
185  *
186  * Return:  None.
187  */
188 static void
189 mpi3mr_trigger_snapdump(struct mpi3mr_softc *sc, U16 reason_code)
190 {
191 	U32 host_diagnostic, timeout = MPI3_SYSIF_DIAG_SAVE_TIMEOUT * 10;
192 
193 	mpi3mr_dprint(sc, MPI3MR_INFO, "snapdump triggered: reason code: %s\n",
194 	    mpi3mr_reset_rc_name(reason_code));
195 
196 	mpi3mr_set_diagsave(sc);
197 	mpi3mr_issue_reset(sc, MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT,
198 			   reason_code);
199 
200 	do {
201 		host_diagnostic = mpi3mr_regread(sc, MPI3_SYSIF_HOST_DIAG_OFFSET);
202 		if (!(host_diagnostic & MPI3_SYSIF_HOST_DIAG_SAVE_IN_PROGRESS))
203 			break;
204                 DELAY(100 * 1000);
205 	} while (--timeout);
206 
207 	return;
208 }
209 
210 /**
211  * mpi3mr_check_rh_fault_ioc - check reset history and fault
212  * controller
213  * @sc: Adapter instance reference
214  * @reason_code, reason code for the fault.
215  *
216  * This routine will fault the controller with
217  * the given reason code if it is not already in the fault or
218  * not asynchronosuly reset. This will be used to handle
219  * initilaization time faults/resets/timeout as in those cases
220  * immediate soft reset invocation is not required.
221  *
222  * Return:  None.
223  */
224 static void mpi3mr_check_rh_fault_ioc(struct mpi3mr_softc *sc, U16 reason_code)
225 {
226 	U32 ioc_status;
227 
228 	if (sc->unrecoverable) {
229 		mpi3mr_dprint(sc, MPI3MR_ERROR, "controller is unrecoverable\n");
230 		return;
231 	}
232 
233 	ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
234 	if ((ioc_status & MPI3_SYSIF_IOC_STATUS_RESET_HISTORY) ||
235 	    (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT)) {
236 		mpi3mr_print_fault_info(sc);
237 		return;
238 	}
239 
240 	mpi3mr_trigger_snapdump(sc, reason_code);
241 
242 	return;
243 }
244 
245 static void * mpi3mr_get_reply_virt_addr(struct mpi3mr_softc *sc,
246     bus_addr_t phys_addr)
247 {
248 	if (!phys_addr)
249 		return NULL;
250 	if ((phys_addr < sc->reply_buf_dma_min_address) ||
251 	    (phys_addr > sc->reply_buf_dma_max_address))
252 		return NULL;
253 
254 	return sc->reply_buf + (phys_addr - sc->reply_buf_phys);
255 }
256 
257 static void * mpi3mr_get_sensebuf_virt_addr(struct mpi3mr_softc *sc,
258     bus_addr_t phys_addr)
259 {
260 	if (!phys_addr)
261 		return NULL;
262 	return sc->sense_buf + (phys_addr - sc->sense_buf_phys);
263 }
264 
265 static void mpi3mr_repost_reply_buf(struct mpi3mr_softc *sc,
266     U64 reply_dma)
267 {
268 	U32 old_idx = 0;
269 
270 	mtx_lock_spin(&sc->reply_free_q_lock);
271 	old_idx  =  sc->reply_free_q_host_index;
272 	sc->reply_free_q_host_index = ((sc->reply_free_q_host_index ==
273 	    (sc->reply_free_q_sz - 1)) ? 0 :
274 	    (sc->reply_free_q_host_index + 1));
275 	sc->reply_free_q[old_idx] = reply_dma;
276 	mpi3mr_regwrite(sc, MPI3_SYSIF_REPLY_FREE_HOST_INDEX_OFFSET,
277 		sc->reply_free_q_host_index);
278 	mtx_unlock_spin(&sc->reply_free_q_lock);
279 }
280 
281 static void mpi3mr_repost_sense_buf(struct mpi3mr_softc *sc,
282     U64 sense_buf_phys)
283 {
284 	U32 old_idx = 0;
285 
286 	mtx_lock_spin(&sc->sense_buf_q_lock);
287 	old_idx  =  sc->sense_buf_q_host_index;
288 	sc->sense_buf_q_host_index = ((sc->sense_buf_q_host_index ==
289 	    (sc->sense_buf_q_sz - 1)) ? 0 :
290 	    (sc->sense_buf_q_host_index + 1));
291 	sc->sense_buf_q[old_idx] = sense_buf_phys;
292 	mpi3mr_regwrite(sc, MPI3_SYSIF_SENSE_BUF_FREE_HOST_INDEX_OFFSET,
293 		sc->sense_buf_q_host_index);
294 	mtx_unlock_spin(&sc->sense_buf_q_lock);
295 
296 }
297 
298 void mpi3mr_set_io_divert_for_all_vd_in_tg(struct mpi3mr_softc *sc,
299 	struct mpi3mr_throttle_group_info *tg, U8 divert_value)
300 {
301 	struct mpi3mr_target *target;
302 
303 	mtx_lock_spin(&sc->target_lock);
304 	TAILQ_FOREACH(target, &sc->cam_sc->tgt_list, tgt_next) {
305 		if (target->throttle_group == tg)
306 			target->io_divert = divert_value;
307 	}
308 	mtx_unlock_spin(&sc->target_lock);
309 }
310 
311 /**
312  * mpi3mr_submit_admin_cmd - Submit request to admin queue
313  * @mrioc: Adapter reference
314  * @admin_req: MPI3 request
315  * @admin_req_sz: Request size
316  *
317  * Post the MPI3 request into admin request queue and
318  * inform the controller, if the queue is full return
319  * appropriate error.
320  *
321  * Return: 0 on success, non-zero on failure.
322  */
323 int mpi3mr_submit_admin_cmd(struct mpi3mr_softc *sc, void *admin_req,
324     U16 admin_req_sz)
325 {
326 	U16 areq_pi = 0, areq_ci = 0, max_entries = 0;
327 	int retval = 0;
328 	U8 *areq_entry;
329 
330 	mtx_lock_spin(&sc->admin_req_lock);
331 	areq_pi = sc->admin_req_pi;
332 	areq_ci = sc->admin_req_ci;
333 	max_entries = sc->num_admin_reqs;
334 
335 	if (sc->unrecoverable)
336 		return -EFAULT;
337 
338 	if ((areq_ci == (areq_pi + 1)) || ((!areq_ci) &&
339 					   (areq_pi == (max_entries - 1)))) {
340 		printf(IOCNAME "AdminReqQ full condition detected\n",
341 		    sc->name);
342 		retval = -EAGAIN;
343 		goto out;
344 	}
345 	areq_entry = (U8 *)sc->admin_req + (areq_pi *
346 						     MPI3MR_AREQ_FRAME_SZ);
347 	memset(areq_entry, 0, MPI3MR_AREQ_FRAME_SZ);
348 	memcpy(areq_entry, (U8 *)admin_req, admin_req_sz);
349 
350 	if (++areq_pi == max_entries)
351 		areq_pi = 0;
352 	sc->admin_req_pi = areq_pi;
353 
354 	mpi3mr_regwrite(sc, MPI3_SYSIF_ADMIN_REQ_Q_PI_OFFSET, sc->admin_req_pi);
355 
356 out:
357 	mtx_unlock_spin(&sc->admin_req_lock);
358 	return retval;
359 }
360 
361 /**
362  * mpi3mr_check_req_qfull - Check request queue is full or not
363  * @op_req_q: Operational reply queue info
364  *
365  * Return: true when queue full, false otherwise.
366  */
367 static inline bool
368 mpi3mr_check_req_qfull(struct mpi3mr_op_req_queue *op_req_q)
369 {
370 	U16 pi, ci, max_entries;
371 	bool is_qfull = false;
372 
373 	pi = op_req_q->pi;
374 	ci = op_req_q->ci;
375 	max_entries = op_req_q->num_reqs;
376 
377 	if ((ci == (pi + 1)) || ((!ci) && (pi == (max_entries - 1))))
378 		is_qfull = true;
379 
380 	return is_qfull;
381 }
382 
383 /**
384  * mpi3mr_submit_io - Post IO command to firmware
385  * @sc:		      Adapter instance reference
386  * @op_req_q:	      Operational Request queue reference
387  * @req:	      MPT request data
388  *
389  * This function submits IO command to firmware.
390  *
391  * Return: Nothing
392  */
393 int mpi3mr_submit_io(struct mpi3mr_softc *sc,
394     struct mpi3mr_op_req_queue *op_req_q, U8 *req)
395 {
396 	U16 pi, max_entries;
397 	int retval = 0;
398 	U8 *req_entry;
399 	U16 req_sz = sc->facts.op_req_sz;
400 	struct mpi3mr_irq_context *irq_ctx;
401 
402 	mtx_lock_spin(&op_req_q->q_lock);
403 
404 	pi = op_req_q->pi;
405 	max_entries = op_req_q->num_reqs;
406 	if (mpi3mr_check_req_qfull(op_req_q)) {
407 		irq_ctx = &sc->irq_ctx[op_req_q->reply_qid - 1];
408 		mpi3mr_complete_io_cmd(sc, irq_ctx);
409 
410 		if (mpi3mr_check_req_qfull(op_req_q)) {
411 			printf(IOCNAME "OpReqQ full condition detected\n",
412 				sc->name);
413 			retval = -EBUSY;
414 			goto out;
415 		}
416 	}
417 
418 	req_entry = (U8 *)op_req_q->q_base + (pi * req_sz);
419 	memset(req_entry, 0, req_sz);
420 	memcpy(req_entry, req, MPI3MR_AREQ_FRAME_SZ);
421 	if (++pi == max_entries)
422 		pi = 0;
423 	op_req_q->pi = pi;
424 
425 	mpi3mr_atomic_inc(&sc->op_reply_q[op_req_q->reply_qid - 1].pend_ios);
426 
427 	mpi3mr_regwrite(sc, MPI3_SYSIF_OPER_REQ_Q_N_PI_OFFSET(op_req_q->qid), op_req_q->pi);
428 	if (sc->mpi3mr_debug & MPI3MR_TRACE) {
429 		device_printf(sc->mpi3mr_dev, "IO submission: QID:%d PI:0x%x\n", op_req_q->qid, op_req_q->pi);
430 		mpi3mr_hexdump(req_entry, MPI3MR_AREQ_FRAME_SZ, 8);
431 	}
432 
433 out:
434 	mtx_unlock_spin(&op_req_q->q_lock);
435 	return retval;
436 }
437 
438 inline void
439 mpi3mr_add_sg_single(void *paddr, U8 flags, U32 length,
440 		     bus_addr_t dma_addr)
441 {
442 	Mpi3SGESimple_t *sgel = paddr;
443 
444 	sgel->Flags = flags;
445 	sgel->Length = (length);
446 	sgel->Address = (U64)dma_addr;
447 }
448 
449 void mpi3mr_build_zero_len_sge(void *paddr)
450 {
451 	U8 sgl_flags = (MPI3_SGE_FLAGS_ELEMENT_TYPE_SIMPLE |
452 		MPI3_SGE_FLAGS_DLAS_SYSTEM | MPI3_SGE_FLAGS_END_OF_LIST);
453 
454 	mpi3mr_add_sg_single(paddr, sgl_flags, 0, -1);
455 
456 }
457 
458 void mpi3mr_enable_interrupts(struct mpi3mr_softc *sc)
459 {
460 	sc->intr_enabled = 1;
461 }
462 
463 void mpi3mr_disable_interrupts(struct mpi3mr_softc *sc)
464 {
465 	sc->intr_enabled = 0;
466 }
467 
468 void
469 mpi3mr_memaddr_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
470 {
471 	bus_addr_t *addr;
472 
473 	addr = arg;
474 	*addr = segs[0].ds_addr;
475 }
476 
477 static int mpi3mr_delete_op_reply_queue(struct mpi3mr_softc *sc, U16 qid)
478 {
479 	Mpi3DeleteReplyQueueRequest_t delq_req;
480 	struct mpi3mr_op_reply_queue *op_reply_q;
481 	int retval = 0;
482 
483 
484 	op_reply_q = &sc->op_reply_q[qid - 1];
485 
486 	if (!op_reply_q->qid)
487 	{
488 		retval = -1;
489 		printf(IOCNAME "Issue DelRepQ: called with invalid Reply QID\n",
490 		    sc->name);
491 		goto out;
492 	}
493 
494 	memset(&delq_req, 0, sizeof(delq_req));
495 
496 	mtx_lock(&sc->init_cmds.completion.lock);
497 	if (sc->init_cmds.state & MPI3MR_CMD_PENDING) {
498 		retval = -1;
499 		printf(IOCNAME "Issue DelRepQ: Init command is in use\n",
500 		    sc->name);
501 		mtx_unlock(&sc->init_cmds.completion.lock);
502 		goto out;
503 	}
504 
505 	if (sc->init_cmds.state & MPI3MR_CMD_PENDING) {
506 		retval = -1;
507 		printf(IOCNAME "Issue DelRepQ: Init command is in use\n",
508 		    sc->name);
509 		goto out;
510 	}
511 	sc->init_cmds.state = MPI3MR_CMD_PENDING;
512 	sc->init_cmds.is_waiting = 1;
513 	sc->init_cmds.callback = NULL;
514 	delq_req.HostTag = MPI3MR_HOSTTAG_INITCMDS;
515 	delq_req.Function = MPI3_FUNCTION_DELETE_REPLY_QUEUE;
516 	delq_req.QueueID = qid;
517 
518 	init_completion(&sc->init_cmds.completion);
519 	retval = mpi3mr_submit_admin_cmd(sc, &delq_req, sizeof(delq_req));
520 	if (retval) {
521 		printf(IOCNAME "Issue DelRepQ: Admin Post failed\n",
522 		    sc->name);
523 		goto out_unlock;
524 	}
525 	wait_for_completion_timeout(&sc->init_cmds.completion,
526 	    (MPI3MR_INTADMCMD_TIMEOUT));
527 	if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) {
528 		printf(IOCNAME "Issue DelRepQ: command timed out\n",
529 		    sc->name);
530 		mpi3mr_check_rh_fault_ioc(sc,
531 		    MPI3MR_RESET_FROM_DELREPQ_TIMEOUT);
532 		sc->unrecoverable = 1;
533 
534 		retval = -1;
535 		goto out_unlock;
536 	}
537 	if ((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK)
538 	     != MPI3_IOCSTATUS_SUCCESS ) {
539 		printf(IOCNAME "Issue DelRepQ: Failed IOCStatus(0x%04x) "
540 		    " Loginfo(0x%08x) \n" , sc->name,
541 		    (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK),
542 		    sc->init_cmds.ioc_loginfo);
543 		retval = -1;
544 		goto out_unlock;
545 	}
546 	sc->irq_ctx[qid - 1].op_reply_q = NULL;
547 
548 	if (sc->op_reply_q[qid - 1].q_base_phys != 0)
549 		bus_dmamap_unload(sc->op_reply_q[qid - 1].q_base_tag, sc->op_reply_q[qid - 1].q_base_dmamap);
550 	if (sc->op_reply_q[qid - 1].q_base != NULL)
551 		bus_dmamem_free(sc->op_reply_q[qid - 1].q_base_tag, sc->op_reply_q[qid - 1].q_base, sc->op_reply_q[qid - 1].q_base_dmamap);
552 	if (sc->op_reply_q[qid - 1].q_base_tag != NULL)
553 		bus_dma_tag_destroy(sc->op_reply_q[qid - 1].q_base_tag);
554 
555 	sc->op_reply_q[qid - 1].q_base = NULL;
556 	sc->op_reply_q[qid - 1].qid = 0;
557 out_unlock:
558 	sc->init_cmds.state = MPI3MR_CMD_NOTUSED;
559 	mtx_unlock(&sc->init_cmds.completion.lock);
560 out:
561 	return retval;
562 }
563 
564 /**
565  * mpi3mr_create_op_reply_queue - create operational reply queue
566  * @sc: Adapter instance reference
567  * @qid: operational reply queue id
568  *
569  * Create operatinal reply queue by issuing MPI request
570  * through admin queue.
571  *
572  * Return:  0 on success, non-zero on failure.
573  */
574 static int mpi3mr_create_op_reply_queue(struct mpi3mr_softc *sc, U16 qid)
575 {
576 	Mpi3CreateReplyQueueRequest_t create_req;
577 	struct mpi3mr_op_reply_queue *op_reply_q;
578 	int retval = 0;
579 	char q_lock_name[32];
580 
581 	op_reply_q = &sc->op_reply_q[qid - 1];
582 
583 	if (op_reply_q->qid)
584 	{
585 		retval = -1;
586 		printf(IOCNAME "CreateRepQ: called for duplicate qid %d\n",
587 		    sc->name, op_reply_q->qid);
588 		return retval;
589 	}
590 
591 	op_reply_q->ci = 0;
592 	if (pci_get_revid(sc->mpi3mr_dev) == SAS4116_CHIP_REV_A0)
593 		op_reply_q->num_replies = MPI3MR_OP_REP_Q_QD_A0;
594 	else
595 		op_reply_q->num_replies = MPI3MR_OP_REP_Q_QD;
596 
597 	op_reply_q->qsz = op_reply_q->num_replies * sc->op_reply_sz;
598 	op_reply_q->ephase = 1;
599 
600         if (!op_reply_q->q_base) {
601 		snprintf(q_lock_name, 32, "Reply Queue Lock[%d]", qid);
602 		mtx_init(&op_reply_q->q_lock, q_lock_name, NULL, MTX_SPIN);
603 
604 		if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,    /* parent */
605 					4, 0,			/* algnmnt, boundary */
606 					sc->dma_loaddr,		/* lowaddr */
607 					BUS_SPACE_MAXADDR,	/* highaddr */
608 					NULL, NULL,		/* filter, filterarg */
609 					op_reply_q->qsz,		/* maxsize */
610 					1,			/* nsegments */
611 					op_reply_q->qsz,		/* maxsegsize */
612 					0,			/* flags */
613 					NULL, NULL,		/* lockfunc, lockarg */
614 					&op_reply_q->q_base_tag)) {
615 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate Operational reply DMA tag\n");
616 			return (ENOMEM);
617 		}
618 
619 		if (bus_dmamem_alloc(op_reply_q->q_base_tag, (void **)&op_reply_q->q_base,
620 		    BUS_DMA_NOWAIT, &op_reply_q->q_base_dmamap)) {
621 			mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__);
622 			return (ENOMEM);
623 		}
624 		bzero(op_reply_q->q_base, op_reply_q->qsz);
625 		bus_dmamap_load(op_reply_q->q_base_tag, op_reply_q->q_base_dmamap, op_reply_q->q_base, op_reply_q->qsz,
626 		    mpi3mr_memaddr_cb, &op_reply_q->q_base_phys, BUS_DMA_NOWAIT);
627 		mpi3mr_dprint(sc, MPI3MR_XINFO, "Operational Reply queue ID: %d phys addr= %#016jx virt_addr: %pa size= %d\n",
628 		    qid, (uintmax_t)op_reply_q->q_base_phys, op_reply_q->q_base, op_reply_q->qsz);
629 
630 		if (!op_reply_q->q_base)
631 		{
632 			retval = -1;
633 			printf(IOCNAME "CreateRepQ: memory alloc failed for qid %d\n",
634 			    sc->name, qid);
635 			goto out;
636 		}
637 	}
638 
639 	memset(&create_req, 0, sizeof(create_req));
640 
641 	mtx_lock(&sc->init_cmds.completion.lock);
642 	if (sc->init_cmds.state & MPI3MR_CMD_PENDING) {
643 		retval = -1;
644 		printf(IOCNAME "CreateRepQ: Init command is in use\n",
645 		    sc->name);
646 		mtx_unlock(&sc->init_cmds.completion.lock);
647 		goto out;
648 	}
649 
650 	sc->init_cmds.state = MPI3MR_CMD_PENDING;
651 	sc->init_cmds.is_waiting = 1;
652 	sc->init_cmds.callback = NULL;
653 	create_req.HostTag = MPI3MR_HOSTTAG_INITCMDS;
654 	create_req.Function = MPI3_FUNCTION_CREATE_REPLY_QUEUE;
655 	create_req.QueueID = qid;
656 	create_req.Flags = MPI3_CREATE_REPLY_QUEUE_FLAGS_INT_ENABLE_ENABLE;
657 	create_req.MSIxIndex = sc->irq_ctx[qid - 1].msix_index;
658 	create_req.BaseAddress = (U64)op_reply_q->q_base_phys;
659 	create_req.Size = op_reply_q->num_replies;
660 
661 	init_completion(&sc->init_cmds.completion);
662 	retval = mpi3mr_submit_admin_cmd(sc, &create_req,
663 	    sizeof(create_req));
664 	if (retval) {
665 		printf(IOCNAME "CreateRepQ: Admin Post failed\n",
666 		    sc->name);
667 		goto out_unlock;
668 	}
669 
670 	wait_for_completion_timeout(&sc->init_cmds.completion,
671 	  	MPI3MR_INTADMCMD_TIMEOUT);
672 	if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) {
673 		printf(IOCNAME "CreateRepQ: command timed out\n",
674 		    sc->name);
675 		mpi3mr_check_rh_fault_ioc(sc,
676 		    MPI3MR_RESET_FROM_CREATEREPQ_TIMEOUT);
677 		sc->unrecoverable = 1;
678 		retval = -1;
679 		goto out_unlock;
680 	}
681 
682 	if ((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK)
683 	     != MPI3_IOCSTATUS_SUCCESS ) {
684 		printf(IOCNAME "CreateRepQ: Failed IOCStatus(0x%04x) "
685 		    " Loginfo(0x%08x) \n" , sc->name,
686 		    (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK),
687 		    sc->init_cmds.ioc_loginfo);
688 		retval = -1;
689 		goto out_unlock;
690 	}
691 	op_reply_q->qid = qid;
692 	sc->irq_ctx[qid - 1].op_reply_q = op_reply_q;
693 
694 out_unlock:
695 	sc->init_cmds.state = MPI3MR_CMD_NOTUSED;
696 	mtx_unlock(&sc->init_cmds.completion.lock);
697 out:
698 	if (retval) {
699 		if (op_reply_q->q_base_phys != 0)
700 			bus_dmamap_unload(op_reply_q->q_base_tag, op_reply_q->q_base_dmamap);
701 		if (op_reply_q->q_base != NULL)
702 			bus_dmamem_free(op_reply_q->q_base_tag, op_reply_q->q_base, op_reply_q->q_base_dmamap);
703 		if (op_reply_q->q_base_tag != NULL)
704 			bus_dma_tag_destroy(op_reply_q->q_base_tag);
705 		op_reply_q->q_base = NULL;
706 		op_reply_q->qid = 0;
707 	}
708 
709 	return retval;
710 }
711 
712 /**
713  * mpi3mr_create_op_req_queue - create operational request queue
714  * @sc: Adapter instance reference
715  * @req_qid: operational request queue id
716  * @reply_qid: Reply queue ID
717  *
718  * Create operatinal request queue by issuing MPI request
719  * through admin queue.
720  *
721  * Return:  0 on success, non-zero on failure.
722  */
723 static int mpi3mr_create_op_req_queue(struct mpi3mr_softc *sc, U16 req_qid, U8 reply_qid)
724 {
725 	Mpi3CreateRequestQueueRequest_t create_req;
726 	struct mpi3mr_op_req_queue *op_req_q;
727 	int retval = 0;
728 	char q_lock_name[32];
729 
730 	op_req_q = &sc->op_req_q[req_qid - 1];
731 
732 	if (op_req_q->qid)
733 	{
734 		retval = -1;
735 		printf(IOCNAME "CreateReqQ: called for duplicate qid %d\n",
736 		    sc->name, op_req_q->qid);
737 		return retval;
738 	}
739 
740 	op_req_q->ci = 0;
741 	op_req_q->pi = 0;
742 	op_req_q->num_reqs = MPI3MR_OP_REQ_Q_QD;
743 	op_req_q->qsz = op_req_q->num_reqs * sc->facts.op_req_sz;
744 	op_req_q->reply_qid = reply_qid;
745 
746 	if (!op_req_q->q_base) {
747 		snprintf(q_lock_name, 32, "Request Queue Lock[%d]", req_qid);
748 		mtx_init(&op_req_q->q_lock, q_lock_name, NULL, MTX_SPIN);
749 
750 		if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,    /* parent */
751 					4, 0,			/* algnmnt, boundary */
752 					sc->dma_loaddr,		/* lowaddr */
753 					BUS_SPACE_MAXADDR,	/* highaddr */
754 					NULL, NULL,		/* filter, filterarg */
755 					op_req_q->qsz,		/* maxsize */
756 					1,			/* nsegments */
757 					op_req_q->qsz,		/* maxsegsize */
758 					0,			/* flags */
759 					NULL, NULL,		/* lockfunc, lockarg */
760 					&op_req_q->q_base_tag)) {
761 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n");
762 			return (ENOMEM);
763 		}
764 
765 		if (bus_dmamem_alloc(op_req_q->q_base_tag, (void **)&op_req_q->q_base,
766 		    BUS_DMA_NOWAIT, &op_req_q->q_base_dmamap)) {
767 			mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__);
768 			return (ENOMEM);
769 		}
770 
771 		bzero(op_req_q->q_base, op_req_q->qsz);
772 
773 		bus_dmamap_load(op_req_q->q_base_tag, op_req_q->q_base_dmamap, op_req_q->q_base, op_req_q->qsz,
774 		    mpi3mr_memaddr_cb, &op_req_q->q_base_phys, BUS_DMA_NOWAIT);
775 
776 		mpi3mr_dprint(sc, MPI3MR_XINFO, "Operational Request QID: %d phys addr= %#016jx virt addr= %pa size= %d associated Reply QID: %d\n",
777 		    req_qid, (uintmax_t)op_req_q->q_base_phys, op_req_q->q_base, op_req_q->qsz, reply_qid);
778 
779 		if (!op_req_q->q_base) {
780 			retval = -1;
781 			printf(IOCNAME "CreateReqQ: memory alloc failed for qid %d\n",
782 			    sc->name, req_qid);
783 			goto out;
784 		}
785 	}
786 
787 	memset(&create_req, 0, sizeof(create_req));
788 
789 	mtx_lock(&sc->init_cmds.completion.lock);
790 	if (sc->init_cmds.state & MPI3MR_CMD_PENDING) {
791 		retval = -1;
792 		printf(IOCNAME "CreateReqQ: Init command is in use\n",
793 		    sc->name);
794 		mtx_unlock(&sc->init_cmds.completion.lock);
795 		goto out;
796 	}
797 
798 	sc->init_cmds.state = MPI3MR_CMD_PENDING;
799 	sc->init_cmds.is_waiting = 1;
800 	sc->init_cmds.callback = NULL;
801 	create_req.HostTag = MPI3MR_HOSTTAG_INITCMDS;
802 	create_req.Function = MPI3_FUNCTION_CREATE_REQUEST_QUEUE;
803 	create_req.QueueID = req_qid;
804 	create_req.Flags = 0;
805 	create_req.ReplyQueueID = reply_qid;
806 	create_req.BaseAddress = (U64)op_req_q->q_base_phys;
807 	create_req.Size = op_req_q->num_reqs;
808 
809 	init_completion(&sc->init_cmds.completion);
810 	retval = mpi3mr_submit_admin_cmd(sc, &create_req,
811 	    sizeof(create_req));
812 	if (retval) {
813 		printf(IOCNAME "CreateReqQ: Admin Post failed\n",
814 		    sc->name);
815 		goto out_unlock;
816 	}
817 
818 	wait_for_completion_timeout(&sc->init_cmds.completion,
819 	    (MPI3MR_INTADMCMD_TIMEOUT));
820 
821 	if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) {
822 		printf(IOCNAME "CreateReqQ: command timed out\n",
823 		    sc->name);
824 		mpi3mr_check_rh_fault_ioc(sc,
825 			MPI3MR_RESET_FROM_CREATEREQQ_TIMEOUT);
826 		sc->unrecoverable = 1;
827 		retval = -1;
828 		goto out_unlock;
829 	}
830 
831 	if ((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK)
832 	     != MPI3_IOCSTATUS_SUCCESS ) {
833 		printf(IOCNAME "CreateReqQ: Failed IOCStatus(0x%04x) "
834 		    " Loginfo(0x%08x) \n" , sc->name,
835 		    (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK),
836 		    sc->init_cmds.ioc_loginfo);
837 		retval = -1;
838 		goto out_unlock;
839 	}
840 	op_req_q->qid = req_qid;
841 
842 out_unlock:
843 	sc->init_cmds.state = MPI3MR_CMD_NOTUSED;
844 	mtx_unlock(&sc->init_cmds.completion.lock);
845 out:
846 	if (retval) {
847 		if (op_req_q->q_base_phys != 0)
848 			bus_dmamap_unload(op_req_q->q_base_tag, op_req_q->q_base_dmamap);
849 		if (op_req_q->q_base != NULL)
850 			bus_dmamem_free(op_req_q->q_base_tag, op_req_q->q_base, op_req_q->q_base_dmamap);
851 		if (op_req_q->q_base_tag != NULL)
852 			bus_dma_tag_destroy(op_req_q->q_base_tag);
853 		op_req_q->q_base = NULL;
854 		op_req_q->qid = 0;
855 	}
856 	return retval;
857 }
858 
859 /**
860  * mpi3mr_create_op_queues - create operational queues
861  * @sc: Adapter instance reference
862  *
863  * Create operatinal queues(request queues and reply queues).
864  * Return:  0 on success, non-zero on failure.
865  */
866 static int mpi3mr_create_op_queues(struct mpi3mr_softc *sc)
867 {
868 	int retval = 0;
869 	U16 num_queues = 0, i = 0, qid;
870 
871 	num_queues = min(sc->facts.max_op_reply_q,
872 	    sc->facts.max_op_req_q);
873 	num_queues = min(num_queues, sc->msix_count);
874 
875 	/*
876 	 * During reset set the num_queues to the number of queues
877 	 * that was set before the reset.
878 	 */
879 	if (sc->num_queues)
880 		num_queues = sc->num_queues;
881 
882 	mpi3mr_dprint(sc, MPI3MR_XINFO, "Trying to create %d Operational Q pairs\n",
883 	    num_queues);
884 
885 	if (!sc->op_req_q) {
886 		sc->op_req_q = malloc(sizeof(struct mpi3mr_op_req_queue) *
887 		    num_queues, M_MPI3MR, M_NOWAIT | M_ZERO);
888 
889 		if (!sc->op_req_q) {
890 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to alloc memory for Request queue info\n");
891 			retval = -1;
892 			goto out_failed;
893 		}
894 	}
895 
896 	if (!sc->op_reply_q) {
897 		sc->op_reply_q = malloc(sizeof(struct mpi3mr_op_reply_queue) * num_queues,
898 			M_MPI3MR, M_NOWAIT | M_ZERO);
899 
900 		if (!sc->op_reply_q) {
901 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to alloc memory for Reply queue info\n");
902 			retval = -1;
903 			goto out_failed;
904 		}
905 	}
906 
907 	sc->num_hosttag_op_req_q = (sc->max_host_ios + 1) / num_queues;
908 
909 	/*Operational Request and reply queue ID starts with 1*/
910 	for (i = 0; i < num_queues; i++) {
911 		qid = i + 1;
912 		if (mpi3mr_create_op_reply_queue(sc, qid)) {
913 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to create Reply queue %d\n",
914 			    qid);
915 			break;
916 		}
917 		if (mpi3mr_create_op_req_queue(sc, qid,
918 		    sc->op_reply_q[qid - 1].qid)) {
919 			mpi3mr_delete_op_reply_queue(sc, qid);
920 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to create Request queue %d\n",
921 			    qid);
922 			break;
923 		}
924 
925 	}
926 
927 	/* Not even one queue is created successfully*/
928         if (i == 0) {
929                 retval = -1;
930                 goto out_failed;
931         }
932 
933 	if (!sc->num_queues) {
934 		sc->num_queues = i;
935 	} else {
936 		if (num_queues != i) {
937 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Number of queues (%d) post reset are not same as"
938 					"queues allocated (%d) during driver init\n", i, num_queues);
939 			goto out_failed;
940 		}
941 	}
942 
943 	mpi3mr_dprint(sc, MPI3MR_INFO, "Successfully created %d Operational Queue pairs\n",
944 	    sc->num_queues);
945 	mpi3mr_dprint(sc, MPI3MR_INFO, "Request Queue QD: %d Reply queue QD: %d\n",
946 	    sc->op_req_q[0].num_reqs, sc->op_reply_q[0].num_replies);
947 
948 	return retval;
949 out_failed:
950 	if (sc->op_req_q) {
951 		free(sc->op_req_q, M_MPI3MR);
952 		sc->op_req_q = NULL;
953 	}
954 	if (sc->op_reply_q) {
955 		free(sc->op_reply_q, M_MPI3MR);
956 		sc->op_reply_q = NULL;
957 	}
958 	return retval;
959 }
960 
961 /**
962  * mpi3mr_setup_admin_qpair - Setup admin queue pairs
963  * @sc: Adapter instance reference
964  *
965  * Allocation and setup admin queues(request queues and reply queues).
966  * Return:  0 on success, non-zero on failure.
967  */
968 static int mpi3mr_setup_admin_qpair(struct mpi3mr_softc *sc)
969 {
970 	int retval = 0;
971 	U32 num_adm_entries = 0;
972 
973 	sc->admin_req_q_sz = MPI3MR_AREQQ_SIZE;
974 	sc->num_admin_reqs = sc->admin_req_q_sz / MPI3MR_AREQ_FRAME_SZ;
975 	sc->admin_req_ci = sc->admin_req_pi = 0;
976 
977 	sc->admin_reply_q_sz = MPI3MR_AREPQ_SIZE;
978 	sc->num_admin_replies = sc->admin_reply_q_sz/ MPI3MR_AREP_FRAME_SZ;
979 	sc->admin_reply_ci = 0;
980 	sc->admin_reply_ephase = 1;
981 
982 	if (!sc->admin_req) {
983 		/*
984 		 * We need to create the tag for the admin queue to get the
985 		 * iofacts to see how many bits the controller decodes.  Solve
986 		 * this chicken and egg problem by only doing lower 4GB DMA.
987 		 */
988 		if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,    /* parent */
989 					4, 0,			/* algnmnt, boundary */
990 					BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
991 					BUS_SPACE_MAXADDR,	/* highaddr */
992 					NULL, NULL,		/* filter, filterarg */
993 					sc->admin_req_q_sz,	/* maxsize */
994 					1,			/* nsegments */
995 					sc->admin_req_q_sz,	/* maxsegsize */
996 					0,			/* flags */
997 					NULL, NULL,		/* lockfunc, lockarg */
998 					&sc->admin_req_tag)) {
999 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n");
1000 			return (ENOMEM);
1001 		}
1002 
1003 		if (bus_dmamem_alloc(sc->admin_req_tag, (void **)&sc->admin_req,
1004 		    BUS_DMA_NOWAIT, &sc->admin_req_dmamap)) {
1005 			mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__);
1006 			return (ENOMEM);
1007 		}
1008 		bzero(sc->admin_req, sc->admin_req_q_sz);
1009 		bus_dmamap_load(sc->admin_req_tag, sc->admin_req_dmamap, sc->admin_req, sc->admin_req_q_sz,
1010 		    mpi3mr_memaddr_cb, &sc->admin_req_phys, BUS_DMA_NOWAIT);
1011 		mpi3mr_dprint(sc, MPI3MR_XINFO, "Admin Req queue phys addr= %#016jx size= %d\n",
1012 		    (uintmax_t)sc->admin_req_phys, sc->admin_req_q_sz);
1013 
1014 		if (!sc->admin_req)
1015 		{
1016 			retval = -1;
1017 			printf(IOCNAME "Memory alloc for AdminReqQ: failed\n",
1018 			    sc->name);
1019 			goto out_failed;
1020 		}
1021 	}
1022 
1023 	if (!sc->admin_reply) {
1024 		mtx_init(&sc->admin_reply_lock, "Admin Reply Queue Lock", NULL, MTX_SPIN);
1025 
1026 		if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,    /* parent */
1027 					4, 0,			/* algnmnt, boundary */
1028 					BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
1029 					BUS_SPACE_MAXADDR,	/* highaddr */
1030 					NULL, NULL,		/* filter, filterarg */
1031 					sc->admin_reply_q_sz,	/* maxsize */
1032 					1,			/* nsegments */
1033 					sc->admin_reply_q_sz,	/* maxsegsize */
1034 					0,			/* flags */
1035 					NULL, NULL,		/* lockfunc, lockarg */
1036 					&sc->admin_reply_tag)) {
1037 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate reply DMA tag\n");
1038 			return (ENOMEM);
1039 		}
1040 
1041 		if (bus_dmamem_alloc(sc->admin_reply_tag, (void **)&sc->admin_reply,
1042 		    BUS_DMA_NOWAIT, &sc->admin_reply_dmamap)) {
1043 			mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__);
1044 			return (ENOMEM);
1045 		}
1046 		bzero(sc->admin_reply, sc->admin_reply_q_sz);
1047 		bus_dmamap_load(sc->admin_reply_tag, sc->admin_reply_dmamap, sc->admin_reply, sc->admin_reply_q_sz,
1048 		    mpi3mr_memaddr_cb, &sc->admin_reply_phys, BUS_DMA_NOWAIT);
1049 		mpi3mr_dprint(sc, MPI3MR_XINFO, "Admin Reply queue phys addr= %#016jx size= %d\n",
1050 		    (uintmax_t)sc->admin_reply_phys, sc->admin_req_q_sz);
1051 
1052 
1053 		if (!sc->admin_reply)
1054 		{
1055 			retval = -1;
1056 			printf(IOCNAME "Memory alloc for AdminRepQ: failed\n",
1057 			    sc->name);
1058 			goto out_failed;
1059 		}
1060 	}
1061 
1062 	num_adm_entries = (sc->num_admin_replies << 16) |
1063 				(sc->num_admin_reqs);
1064 	mpi3mr_regwrite(sc, MPI3_SYSIF_ADMIN_Q_NUM_ENTRIES_OFFSET, num_adm_entries);
1065 	mpi3mr_regwrite64(sc, MPI3_SYSIF_ADMIN_REQ_Q_ADDR_LOW_OFFSET, sc->admin_req_phys);
1066 	mpi3mr_regwrite64(sc, MPI3_SYSIF_ADMIN_REPLY_Q_ADDR_LOW_OFFSET, sc->admin_reply_phys);
1067 	mpi3mr_regwrite(sc, MPI3_SYSIF_ADMIN_REQ_Q_PI_OFFSET, sc->admin_req_pi);
1068 	mpi3mr_regwrite(sc, MPI3_SYSIF_ADMIN_REPLY_Q_CI_OFFSET, sc->admin_reply_ci);
1069 
1070 	return retval;
1071 
1072 out_failed:
1073 	/* Free Admin reply*/
1074 	if (sc->admin_reply_phys)
1075 		bus_dmamap_unload(sc->admin_reply_tag, sc->admin_reply_dmamap);
1076 
1077 	if (sc->admin_reply != NULL)
1078 		bus_dmamem_free(sc->admin_reply_tag, sc->admin_reply,
1079 		    sc->admin_reply_dmamap);
1080 
1081 	if (sc->admin_reply_tag != NULL)
1082 		bus_dma_tag_destroy(sc->admin_reply_tag);
1083 
1084 	/* Free Admin request*/
1085 	if (sc->admin_req_phys)
1086 		bus_dmamap_unload(sc->admin_req_tag, sc->admin_req_dmamap);
1087 
1088 	if (sc->admin_req != NULL)
1089 		bus_dmamem_free(sc->admin_req_tag, sc->admin_req,
1090 		    sc->admin_req_dmamap);
1091 
1092 	if (sc->admin_req_tag != NULL)
1093 		bus_dma_tag_destroy(sc->admin_req_tag);
1094 
1095 	return retval;
1096 }
1097 
1098 /**
1099  * mpi3mr_print_fault_info - Display fault information
1100  * @sc: Adapter instance reference
1101  *
1102  * Display the controller fault information if there is a
1103  * controller fault.
1104  *
1105  * Return: Nothing.
1106  */
1107 static void mpi3mr_print_fault_info(struct mpi3mr_softc *sc)
1108 {
1109 	U32 ioc_status, code, code1, code2, code3;
1110 
1111 	ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
1112 
1113 	if (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT) {
1114 		code = mpi3mr_regread(sc, MPI3_SYSIF_FAULT_OFFSET) &
1115 			MPI3_SYSIF_FAULT_CODE_MASK;
1116 		code1 = mpi3mr_regread(sc, MPI3_SYSIF_FAULT_INFO0_OFFSET);
1117 		code2 = mpi3mr_regread(sc, MPI3_SYSIF_FAULT_INFO1_OFFSET);
1118 		code3 = mpi3mr_regread(sc, MPI3_SYSIF_FAULT_INFO2_OFFSET);
1119 		printf(IOCNAME "fault codes 0x%04x:0x%04x:0x%04x:0x%04x\n",
1120 		    sc->name, code, code1, code2, code3);
1121 	}
1122 }
1123 
1124 enum mpi3mr_iocstate mpi3mr_get_iocstate(struct mpi3mr_softc *sc)
1125 {
1126 	U32 ioc_status, ioc_control;
1127 	U8 ready, enabled;
1128 
1129 	ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
1130 	ioc_control = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET);
1131 
1132 	if(sc->unrecoverable)
1133 		return MRIOC_STATE_UNRECOVERABLE;
1134 	if (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT)
1135 		return MRIOC_STATE_FAULT;
1136 
1137 	ready = (ioc_status & MPI3_SYSIF_IOC_STATUS_READY);
1138 	enabled = (ioc_control & MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC);
1139 
1140 	if (ready && enabled)
1141 		return MRIOC_STATE_READY;
1142 	if ((!ready) && (!enabled))
1143 		return MRIOC_STATE_RESET;
1144 	if ((!ready) && (enabled))
1145 		return MRIOC_STATE_BECOMING_READY;
1146 
1147 	return MRIOC_STATE_RESET_REQUESTED;
1148 }
1149 
1150 static inline void mpi3mr_clear_reset_history(struct mpi3mr_softc *sc)
1151 {
1152         U32 ioc_status;
1153 
1154 	ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
1155         if (ioc_status & MPI3_SYSIF_IOC_STATUS_RESET_HISTORY)
1156 		mpi3mr_regwrite(sc, MPI3_SYSIF_IOC_STATUS_OFFSET, ioc_status);
1157 
1158 }
1159 
1160 /**
1161  * mpi3mr_mur_ioc - Message unit Reset handler
1162  * @sc: Adapter instance reference
1163  * @reset_reason: Reset reason code
1164  *
1165  * Issue Message unit Reset to the controller and wait for it to
1166  * be complete.
1167  *
1168  * Return: 0 on success, -1 on failure.
1169  */
1170 static int mpi3mr_mur_ioc(struct mpi3mr_softc *sc, U16 reset_reason)
1171 {
1172 	U32 ioc_config, timeout, ioc_status, scratch_pad0;
1173         int retval = -1;
1174 
1175         mpi3mr_dprint(sc, MPI3MR_INFO, "Issuing Message Unit Reset(MUR)\n");
1176         if (sc->unrecoverable) {
1177                 mpi3mr_dprint(sc, MPI3MR_ERROR, "IOC is unrecoverable MUR not issued\n");
1178                 return retval;
1179         }
1180 	mpi3mr_clear_reset_history(sc);
1181 
1182 	scratch_pad0 = ((MPI3MR_RESET_REASON_OSTYPE_FREEBSD <<
1183 			MPI3MR_RESET_REASON_OSTYPE_SHIFT) |
1184 			(sc->facts.ioc_num <<
1185 			MPI3MR_RESET_REASON_IOCNUM_SHIFT) | reset_reason);
1186 	mpi3mr_regwrite(sc, MPI3_SYSIF_SCRATCHPAD0_OFFSET, scratch_pad0);
1187 	ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET);
1188         ioc_config &= ~MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC;
1189 	mpi3mr_regwrite(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET, ioc_config);
1190 
1191         timeout = MPI3MR_MUR_TIMEOUT * 10;
1192         do {
1193 		ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
1194                 if ((ioc_status & MPI3_SYSIF_IOC_STATUS_RESET_HISTORY)) {
1195 			mpi3mr_clear_reset_history(sc);
1196 			ioc_config =
1197 				mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET);
1198                         if (!((ioc_status & MPI3_SYSIF_IOC_STATUS_READY) ||
1199                             (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT) ||
1200                             (ioc_config & MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC))) {
1201                                 retval = 0;
1202                                 break;
1203                         }
1204                 }
1205                 DELAY(100 * 1000);
1206         } while (--timeout);
1207 
1208 	ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
1209 	ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET);
1210 
1211         mpi3mr_dprint(sc, MPI3MR_INFO, "IOC Status/Config after %s MUR is (0x%x)/(0x%x)\n",
1212                 !retval ? "successful":"failed", ioc_status, ioc_config);
1213         return retval;
1214 }
1215 
1216 /**
1217  * mpi3mr_bring_ioc_ready - Bring controller to ready state
1218  * @sc: Adapter instance reference
1219  *
1220  * Set Enable IOC bit in IOC configuration register and wait for
1221  * the controller to become ready.
1222  *
1223  * Return: 0 on success, appropriate error on failure.
1224  */
1225 static int mpi3mr_bring_ioc_ready(struct mpi3mr_softc *sc,
1226 				  U64 *start_time)
1227 {
1228 	enum mpi3mr_iocstate current_state;
1229 	U32 ioc_status;
1230 	int retval;
1231 
1232 	U32 ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET);
1233 	ioc_config |= MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC;
1234 	mpi3mr_regwrite(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET, ioc_config);
1235 
1236 	if (*start_time == 0)
1237 		*start_time = ticks;
1238 
1239 	do {
1240 		ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
1241 		if (ioc_status & (MPI3_SYSIF_IOC_STATUS_FAULT | MPI3_SYSIF_IOC_STATUS_RESET_HISTORY)) {
1242 		    if (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT) {
1243 			    mpi3mr_print_fault_info(sc);
1244 			    retval = mpi3mr_issue_reset(sc, MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET, MPI3MR_RESET_FROM_BRINGUP);
1245 			    if (retval) {
1246 				    mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Failed to soft reset the IOC, error 0x%d\n", __func__, retval);
1247 				    return -1;
1248 			    }
1249 		    }
1250 		    mpi3mr_clear_reset_history(sc);
1251 		    return EAGAIN;
1252 		}
1253 
1254 		current_state = mpi3mr_get_iocstate(sc);
1255 		if (current_state == MRIOC_STATE_READY)
1256 			return 0;
1257 
1258 		DELAY(100 * 1000);
1259 
1260 	} while (((ticks - *start_time) / hz) < sc->ready_timeout);
1261 
1262 	return -1;
1263 }
1264 
1265 static const struct {
1266 	enum mpi3mr_iocstate value;
1267 	char *name;
1268 } mrioc_states[] = {
1269 	{ MRIOC_STATE_READY, "ready" },
1270 	{ MRIOC_STATE_FAULT, "fault" },
1271 	{ MRIOC_STATE_RESET, "reset" },
1272 	{ MRIOC_STATE_BECOMING_READY, "becoming ready" },
1273 	{ MRIOC_STATE_RESET_REQUESTED, "reset requested" },
1274 	{ MRIOC_STATE_COUNT, "Count" },
1275 };
1276 
1277 static const char *mpi3mr_iocstate_name(enum mpi3mr_iocstate mrioc_state)
1278 {
1279 	int i;
1280 	char *name = NULL;
1281 
1282 	for (i = 0; i < MRIOC_STATE_COUNT; i++) {
1283 		if (mrioc_states[i].value == mrioc_state){
1284 			name = mrioc_states[i].name;
1285 			break;
1286 		}
1287 	}
1288 	return name;
1289 }
1290 
1291 /* Reset reason to name mapper structure*/
1292 static const struct {
1293 	enum mpi3mr_reset_reason value;
1294 	char *name;
1295 } mpi3mr_reset_reason_codes[] = {
1296 	{ MPI3MR_RESET_FROM_BRINGUP, "timeout in bringup" },
1297 	{ MPI3MR_RESET_FROM_FAULT_WATCH, "fault" },
1298 	{ MPI3MR_RESET_FROM_IOCTL, "application" },
1299 	{ MPI3MR_RESET_FROM_EH_HOS, "error handling" },
1300 	{ MPI3MR_RESET_FROM_TM_TIMEOUT, "TM timeout" },
1301 	{ MPI3MR_RESET_FROM_IOCTL_TIMEOUT, "IOCTL timeout" },
1302 	{ MPI3MR_RESET_FROM_SCSIIO_TIMEOUT, "SCSIIO timeout" },
1303 	{ MPI3MR_RESET_FROM_MUR_FAILURE, "MUR failure" },
1304 	{ MPI3MR_RESET_FROM_CTLR_CLEANUP, "timeout in controller cleanup" },
1305 	{ MPI3MR_RESET_FROM_CIACTIV_FAULT, "component image activation fault" },
1306 	{ MPI3MR_RESET_FROM_PE_TIMEOUT, "port enable timeout" },
1307 	{ MPI3MR_RESET_FROM_TSU_TIMEOUT, "time stamp update timeout" },
1308 	{ MPI3MR_RESET_FROM_DELREQQ_TIMEOUT, "delete request queue timeout" },
1309 	{ MPI3MR_RESET_FROM_DELREPQ_TIMEOUT, "delete reply queue timeout" },
1310 	{
1311 		MPI3MR_RESET_FROM_CREATEREPQ_TIMEOUT,
1312 		"create request queue timeout"
1313 	},
1314 	{
1315 		MPI3MR_RESET_FROM_CREATEREQQ_TIMEOUT,
1316 		"create reply queue timeout"
1317 	},
1318 	{ MPI3MR_RESET_FROM_IOCFACTS_TIMEOUT, "IOC facts timeout" },
1319 	{ MPI3MR_RESET_FROM_IOCINIT_TIMEOUT, "IOC init timeout" },
1320 	{ MPI3MR_RESET_FROM_EVTNOTIFY_TIMEOUT, "event notify timeout" },
1321 	{ MPI3MR_RESET_FROM_EVTACK_TIMEOUT, "event acknowledgment timeout" },
1322 	{
1323 		MPI3MR_RESET_FROM_CIACTVRST_TIMER,
1324 		"component image activation timeout"
1325 	},
1326 	{
1327 		MPI3MR_RESET_FROM_GETPKGVER_TIMEOUT,
1328 		"get package version timeout"
1329 	},
1330 	{
1331 		MPI3MR_RESET_FROM_PELABORT_TIMEOUT,
1332 		"persistent event log abort timeout"
1333 	},
1334 	{ MPI3MR_RESET_FROM_SYSFS, "sysfs invocation" },
1335 	{ MPI3MR_RESET_FROM_SYSFS_TIMEOUT, "sysfs TM timeout" },
1336 	{
1337 		MPI3MR_RESET_FROM_DIAG_BUFFER_POST_TIMEOUT,
1338 		"diagnostic buffer post timeout"
1339 	},
1340 	{ MPI3MR_RESET_FROM_FIRMWARE, "firmware asynchronus reset" },
1341 	{ MPI3MR_RESET_FROM_CFG_REQ_TIMEOUT, "configuration request timeout" },
1342 	{ MPI3MR_RESET_REASON_COUNT, "Reset reason count" },
1343 };
1344 
1345 /**
1346  * mpi3mr_reset_rc_name - get reset reason code name
1347  * @reason_code: reset reason code value
1348  *
1349  * Map reset reason to an NULL terminated ASCII string
1350  *
1351  * Return: Name corresponding to reset reason value or NULL.
1352  */
1353 static const char *mpi3mr_reset_rc_name(enum mpi3mr_reset_reason reason_code)
1354 {
1355 	int i;
1356 	char *name = NULL;
1357 
1358 	for (i = 0; i < MPI3MR_RESET_REASON_COUNT; i++) {
1359 		if (mpi3mr_reset_reason_codes[i].value == reason_code) {
1360 			name = mpi3mr_reset_reason_codes[i].name;
1361 			break;
1362 		}
1363 	}
1364 	return name;
1365 }
1366 
1367 #define MAX_RESET_TYPE 3
1368 /* Reset type to name mapper structure*/
1369 static const struct {
1370 	U16 reset_type;
1371 	char *name;
1372 } mpi3mr_reset_types[] = {
1373 	{ MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET, "soft" },
1374 	{ MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT, "diag fault" },
1375 	{ MAX_RESET_TYPE, "count"}
1376 };
1377 
1378 /**
1379  * mpi3mr_reset_type_name - get reset type name
1380  * @reset_type: reset type value
1381  *
1382  * Map reset type to an NULL terminated ASCII string
1383  *
1384  * Return: Name corresponding to reset type value or NULL.
1385  */
1386 static const char *mpi3mr_reset_type_name(U16 reset_type)
1387 {
1388 	int i;
1389 	char *name = NULL;
1390 
1391 	for (i = 0; i < MAX_RESET_TYPE; i++) {
1392 		if (mpi3mr_reset_types[i].reset_type == reset_type) {
1393 			name = mpi3mr_reset_types[i].name;
1394 			break;
1395 		}
1396 	}
1397 	return name;
1398 }
1399 
1400 /**
1401  * mpi3mr_soft_reset_success - Check softreset is success or not
1402  * @ioc_status: IOC status register value
1403  * @ioc_config: IOC config register value
1404  *
1405  * Check whether the soft reset is successful or not based on
1406  * IOC status and IOC config register values.
1407  *
1408  * Return: True when the soft reset is success, false otherwise.
1409  */
1410 static inline bool
1411 mpi3mr_soft_reset_success(U32 ioc_status, U32 ioc_config)
1412 {
1413 	if (!((ioc_status & MPI3_SYSIF_IOC_STATUS_READY) ||
1414 	    (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT) ||
1415 	    (ioc_config & MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC)))
1416 		return true;
1417 	return false;
1418 }
1419 
1420 /**
1421  * mpi3mr_diagfault_success - Check diag fault is success or not
1422  * @sc: Adapter reference
1423  * @ioc_status: IOC status register value
1424  *
1425  * Check whether the controller hit diag reset fault code.
1426  *
1427  * Return: True when there is diag fault, false otherwise.
1428  */
1429 static inline bool mpi3mr_diagfault_success(struct mpi3mr_softc *sc,
1430 	U32 ioc_status)
1431 {
1432 	if (!(ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT))
1433 		return false;
1434 	mpi3mr_print_fault_info(sc);
1435 	return true;
1436 }
1437 
1438 /**
1439  * mpi3mr_issue_iocfacts - Send IOC Facts
1440  * @sc: Adapter instance reference
1441  * @facts_data: Cached IOC facts data
1442  *
1443  * Issue IOC Facts MPI request through admin queue and wait for
1444  * the completion of it or time out.
1445  *
1446  * Return: 0 on success, non-zero on failures.
1447  */
1448 static int mpi3mr_issue_iocfacts(struct mpi3mr_softc *sc,
1449     Mpi3IOCFactsData_t *facts_data)
1450 {
1451 	Mpi3IOCFactsRequest_t iocfacts_req;
1452 	bus_dma_tag_t data_tag = NULL;
1453 	bus_dmamap_t data_map = NULL;
1454 	bus_addr_t data_phys = 0;
1455 	void *data = NULL;
1456 	U32 data_len = sizeof(*facts_data);
1457 	int retval = 0;
1458 
1459 	U8 sgl_flags = (MPI3_SGE_FLAGS_ELEMENT_TYPE_SIMPLE |
1460                 	MPI3_SGE_FLAGS_DLAS_SYSTEM |
1461 			MPI3_SGE_FLAGS_END_OF_LIST);
1462 
1463 
1464 	/*
1465 	 * We can't use sc->dma_loaddr here.  We set those only after we get the
1466 	 * iocfacts.  So allocate in the lower 4GB.  The amount of data is tiny
1467 	 * and we don't do this that often, so any bouncing we might have to do
1468 	 * isn't a cause for concern.
1469 	 */
1470         if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,    /* parent */
1471 				4, 0,			/* algnmnt, boundary */
1472 				BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
1473 				BUS_SPACE_MAXADDR,	/* highaddr */
1474 				NULL, NULL,		/* filter, filterarg */
1475                                 data_len,		/* maxsize */
1476                                 1,			/* nsegments */
1477                                 data_len,		/* maxsegsize */
1478                                 0,			/* flags */
1479                                 NULL, NULL,		/* lockfunc, lockarg */
1480                                 &data_tag)) {
1481 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n");
1482 		return (ENOMEM);
1483         }
1484 
1485         if (bus_dmamem_alloc(data_tag, (void **)&data,
1486 	    BUS_DMA_NOWAIT, &data_map)) {
1487 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d Data  DMA mem alloc failed\n",
1488 			__func__, __LINE__);
1489 		return (ENOMEM);
1490         }
1491 
1492         bzero(data, data_len);
1493         bus_dmamap_load(data_tag, data_map, data, data_len,
1494 	    mpi3mr_memaddr_cb, &data_phys, BUS_DMA_NOWAIT);
1495 	mpi3mr_dprint(sc, MPI3MR_XINFO, "Func: %s line: %d IOCfacts data phys addr= %#016jx size= %d\n",
1496 	    __func__, __LINE__, (uintmax_t)data_phys, data_len);
1497 
1498 	if (!data)
1499 	{
1500 		retval = -1;
1501 		printf(IOCNAME "Memory alloc for IOCFactsData: failed\n",
1502 		    sc->name);
1503 		goto out;
1504 	}
1505 
1506 	mtx_lock(&sc->init_cmds.completion.lock);
1507 	memset(&iocfacts_req, 0, sizeof(iocfacts_req));
1508 
1509 	if (sc->init_cmds.state & MPI3MR_CMD_PENDING) {
1510 		retval = -1;
1511 		printf(IOCNAME "Issue IOCFacts: Init command is in use\n",
1512 		    sc->name);
1513 		mtx_unlock(&sc->init_cmds.completion.lock);
1514 		goto out;
1515 	}
1516 
1517 	sc->init_cmds.state = MPI3MR_CMD_PENDING;
1518 	sc->init_cmds.is_waiting = 1;
1519 	sc->init_cmds.callback = NULL;
1520 	iocfacts_req.HostTag = (MPI3MR_HOSTTAG_INITCMDS);
1521 	iocfacts_req.Function = MPI3_FUNCTION_IOC_FACTS;
1522 
1523 	mpi3mr_add_sg_single(&iocfacts_req.SGL, sgl_flags, data_len,
1524 	    data_phys);
1525 
1526 	init_completion(&sc->init_cmds.completion);
1527 
1528 	retval = mpi3mr_submit_admin_cmd(sc, &iocfacts_req,
1529 	    sizeof(iocfacts_req));
1530 
1531 	if (retval) {
1532 		printf(IOCNAME "Issue IOCFacts: Admin Post failed\n",
1533 		    sc->name);
1534 		goto out_unlock;
1535 	}
1536 
1537 	wait_for_completion_timeout(&sc->init_cmds.completion,
1538 	    (MPI3MR_INTADMCMD_TIMEOUT));
1539 	if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) {
1540 		printf(IOCNAME "Issue IOCFacts: command timed out\n",
1541 		    sc->name);
1542 		mpi3mr_check_rh_fault_ioc(sc,
1543 		    MPI3MR_RESET_FROM_IOCFACTS_TIMEOUT);
1544 		sc->unrecoverable = 1;
1545 		retval = -1;
1546 		goto out_unlock;
1547 	}
1548 
1549 	if ((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK)
1550 	     != MPI3_IOCSTATUS_SUCCESS ) {
1551 		printf(IOCNAME "Issue IOCFacts: Failed IOCStatus(0x%04x) "
1552 		    " Loginfo(0x%08x) \n" , sc->name,
1553 		    (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK),
1554 		    sc->init_cmds.ioc_loginfo);
1555 		retval = -1;
1556 		goto out_unlock;
1557 	}
1558 
1559 	memcpy(facts_data, (U8 *)data, data_len);
1560 out_unlock:
1561 	sc->init_cmds.state = MPI3MR_CMD_NOTUSED;
1562 	mtx_unlock(&sc->init_cmds.completion.lock);
1563 
1564 out:
1565 	if (data_phys != 0)
1566 		bus_dmamap_unload(data_tag, data_map);
1567 	if (data != NULL)
1568 		bus_dmamem_free(data_tag, data, data_map);
1569 	if (data_tag != NULL)
1570 		bus_dma_tag_destroy(data_tag);
1571 	return retval;
1572 }
1573 
1574 /**
1575  * mpi3mr_process_factsdata - Process IOC facts data
1576  * @sc: Adapter instance reference
1577  * @facts_data: Cached IOC facts data
1578  *
1579  * Convert IOC facts data into cpu endianness and cache it in
1580  * the driver .
1581  *
1582  * Return: Nothing.
1583  */
1584 static int mpi3mr_process_factsdata(struct mpi3mr_softc *sc,
1585     Mpi3IOCFactsData_t *facts_data)
1586 {
1587 	int retval = 0;
1588 	U32 ioc_config, req_sz, facts_flags;
1589         struct mpi3mr_compimg_ver *fwver;
1590 
1591 	if (le16toh(facts_data->IOCFactsDataLength) !=
1592 	    (sizeof(*facts_data) / 4)) {
1593 		mpi3mr_dprint(sc, MPI3MR_INFO, "IOCFacts data length mismatch "
1594 		    " driver_sz(%ld) firmware_sz(%d) \n",
1595 		    sizeof(*facts_data),
1596 		    facts_data->IOCFactsDataLength);
1597 	}
1598 
1599 	ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET);
1600         req_sz = 1 << ((ioc_config & MPI3_SYSIF_IOC_CONFIG_OPER_REQ_ENT_SZ) >>
1601                   MPI3_SYSIF_IOC_CONFIG_OPER_REQ_ENT_SZ_SHIFT);
1602 
1603 	if (facts_data->IOCRequestFrameSize != (req_sz/4)) {
1604 		 mpi3mr_dprint(sc, MPI3MR_INFO, "IOCFacts data reqFrameSize mismatch "
1605 		    " hw_size(%d) firmware_sz(%d) \n" , req_sz/4,
1606 		    facts_data->IOCRequestFrameSize);
1607 	}
1608 
1609 	memset(&sc->facts, 0, sizeof(sc->facts));
1610 
1611 	facts_flags = le32toh(facts_data->Flags);
1612 	sc->facts.op_req_sz = req_sz;
1613 	sc->op_reply_sz = 1 << ((ioc_config &
1614                                   MPI3_SYSIF_IOC_CONFIG_OPER_RPY_ENT_SZ) >>
1615                                   MPI3_SYSIF_IOC_CONFIG_OPER_RPY_ENT_SZ_SHIFT);
1616 
1617 	sc->facts.ioc_num = facts_data->IOCNumber;
1618         sc->facts.who_init = facts_data->WhoInit;
1619         sc->facts.max_msix_vectors = facts_data->MaxMSIxVectors;
1620 	sc->facts.personality = (facts_flags &
1621 	    MPI3_IOCFACTS_FLAGS_PERSONALITY_MASK);
1622 	sc->facts.dma_mask = (facts_flags &
1623 	    MPI3_IOCFACTS_FLAGS_DMA_ADDRESS_WIDTH_MASK) >>
1624 	    MPI3_IOCFACTS_FLAGS_DMA_ADDRESS_WIDTH_SHIFT;
1625         sc->facts.protocol_flags = facts_data->ProtocolFlags;
1626         sc->facts.mpi_version = (facts_data->MPIVersion.Word);
1627         sc->facts.max_reqs = (facts_data->MaxOutstandingRequests);
1628         sc->facts.product_id = (facts_data->ProductID);
1629 	sc->facts.reply_sz = (facts_data->ReplyFrameSize) * 4;
1630         sc->facts.exceptions = (facts_data->IOCExceptions);
1631         sc->facts.max_perids = (facts_data->MaxPersistentID);
1632         sc->facts.max_vds = (facts_data->MaxVDs);
1633         sc->facts.max_hpds = (facts_data->MaxHostPDs);
1634         sc->facts.max_advhpds = (facts_data->MaxAdvHostPDs);
1635         sc->facts.max_raidpds = (facts_data->MaxRAIDPDs);
1636         sc->facts.max_nvme = (facts_data->MaxNVMe);
1637         sc->facts.max_pcieswitches =
1638                 (facts_data->MaxPCIeSwitches);
1639         sc->facts.max_sasexpanders =
1640                 (facts_data->MaxSASExpanders);
1641         sc->facts.max_data_length = facts_data->MaxDataLength;
1642         sc->facts.max_sasinitiators =
1643                 (facts_data->MaxSASInitiators);
1644         sc->facts.max_enclosures = (facts_data->MaxEnclosures);
1645         sc->facts.min_devhandle = (facts_data->MinDevHandle);
1646         sc->facts.max_devhandle = (facts_data->MaxDevHandle);
1647 	sc->facts.max_op_req_q =
1648                 (facts_data->MaxOperationalRequestQueues);
1649 	sc->facts.max_op_reply_q =
1650                 (facts_data->MaxOperationalReplyQueues);
1651         sc->facts.ioc_capabilities =
1652                 (facts_data->IOCCapabilities);
1653         sc->facts.fw_ver.build_num =
1654                 (facts_data->FWVersion.BuildNum);
1655         sc->facts.fw_ver.cust_id =
1656                 (facts_data->FWVersion.CustomerID);
1657         sc->facts.fw_ver.ph_minor = facts_data->FWVersion.PhaseMinor;
1658         sc->facts.fw_ver.ph_major = facts_data->FWVersion.PhaseMajor;
1659         sc->facts.fw_ver.gen_minor = facts_data->FWVersion.GenMinor;
1660         sc->facts.fw_ver.gen_major = facts_data->FWVersion.GenMajor;
1661         sc->max_msix_vectors = min(sc->max_msix_vectors,
1662             sc->facts.max_msix_vectors);
1663         sc->facts.sge_mod_mask = facts_data->SGEModifierMask;
1664         sc->facts.sge_mod_value = facts_data->SGEModifierValue;
1665         sc->facts.sge_mod_shift = facts_data->SGEModifierShift;
1666         sc->facts.shutdown_timeout =
1667                 (facts_data->ShutdownTimeout);
1668 	sc->facts.max_dev_per_tg = facts_data->MaxDevicesPerThrottleGroup;
1669 	sc->facts.io_throttle_data_length =
1670 	    facts_data->IOThrottleDataLength;
1671 	sc->facts.max_io_throttle_group =
1672 	    facts_data->MaxIOThrottleGroup;
1673 	sc->facts.io_throttle_low = facts_data->IOThrottleLow;
1674 	sc->facts.io_throttle_high = facts_data->IOThrottleHigh;
1675 
1676 	if (sc->facts.max_data_length == MPI3_IOCFACTS_MAX_DATA_LENGTH_NOT_REPORTED)
1677 		sc->facts.max_data_length = MPI3MR_DEFAULT_MAX_IO_SIZE;
1678 	else
1679 		sc->facts.max_data_length *= MPI3MR_PAGE_SIZE_4K;
1680 	/*Store in 512b block count*/
1681 	if (sc->facts.io_throttle_data_length)
1682 		sc->io_throttle_data_length =
1683 		    (sc->facts.io_throttle_data_length * 2 * 4);
1684 	else
1685 		/* set the length to 1MB + 1K to disable throttle*/
1686 		sc->io_throttle_data_length = MPI3MR_MAX_SECTORS + 2;
1687 
1688 	sc->io_throttle_high = (sc->facts.io_throttle_high * 2 * 1024);
1689 	sc->io_throttle_low = (sc->facts.io_throttle_low * 2 * 1024);
1690 
1691 	fwver = &sc->facts.fw_ver;
1692 	snprintf(sc->fw_version, sizeof(sc->fw_version),
1693 	    "%d.%d.%d.%d.%05d-%05d",
1694 	    fwver->gen_major, fwver->gen_minor, fwver->ph_major,
1695 	    fwver->ph_minor, fwver->cust_id, fwver->build_num);
1696 
1697 	mpi3mr_dprint(sc, MPI3MR_INFO, "ioc_num(%d), maxopQ(%d), maxopRepQ(%d), maxdh(%d),"
1698             "maxreqs(%d), mindh(%d) maxPDs(%d) maxvectors(%d) maxperids(%d)\n",
1699 	    sc->facts.ioc_num, sc->facts.max_op_req_q,
1700 	    sc->facts.max_op_reply_q, sc->facts.max_devhandle,
1701             sc->facts.max_reqs, sc->facts.min_devhandle,
1702             sc->facts.max_pds, sc->facts.max_msix_vectors,
1703             sc->facts.max_perids);
1704         mpi3mr_dprint(sc, MPI3MR_INFO, "SGEModMask 0x%x SGEModVal 0x%x SGEModShift 0x%x\n",
1705             sc->facts.sge_mod_mask, sc->facts.sge_mod_value,
1706             sc->facts.sge_mod_shift);
1707 	mpi3mr_dprint(sc, MPI3MR_INFO,
1708 	    "max_dev_per_throttle_group(%d), max_throttle_groups(%d), io_throttle_data_len(%dKiB), io_throttle_high(%dMiB), io_throttle_low(%dMiB)\n",
1709 	    sc->facts.max_dev_per_tg, sc->facts.max_io_throttle_group,
1710 	    sc->facts.io_throttle_data_length * 4,
1711 	    sc->facts.io_throttle_high, sc->facts.io_throttle_low);
1712 
1713 	sc->max_host_ios = sc->facts.max_reqs -
1714 	    (MPI3MR_INTERNALCMDS_RESVD + 1);
1715 
1716 	/*
1717 	 * Set the DMA mask for the card.  dma_mask is the number of bits that
1718 	 * can have bits set in them.  Translate this into bus_dma loaddr args.
1719 	 * Add sanity for more bits than address space or other overflow
1720 	 * situations.
1721 	 */
1722 	if (sc->facts.dma_mask == 0 ||
1723 	    (sc->facts.dma_mask >= sizeof(bus_addr_t) * 8))
1724 		sc->dma_loaddr = BUS_SPACE_MAXADDR;
1725 	else
1726 		sc->dma_loaddr = ~((1ull << sc->facts.dma_mask) - 1);
1727 	mpi3mr_dprint(sc, MPI3MR_INFO,
1728 	    "dma_mask bits: %d loaddr 0x%jx\n",
1729 	    sc->facts.dma_mask, sc->dma_loaddr);
1730 
1731 	return retval;
1732 }
1733 
1734 static inline void mpi3mr_setup_reply_free_queues(struct mpi3mr_softc *sc)
1735 {
1736 	int i;
1737 	bus_addr_t phys_addr;
1738 
1739 	/* initialize Reply buffer Queue */
1740 	for (i = 0, phys_addr = sc->reply_buf_phys;
1741 	    i < sc->num_reply_bufs; i++, phys_addr += sc->reply_sz)
1742 		sc->reply_free_q[i] = phys_addr;
1743 	sc->reply_free_q[i] = (0);
1744 
1745 	/* initialize Sense Buffer Queue */
1746 	for (i = 0, phys_addr = sc->sense_buf_phys;
1747 	    i < sc->num_sense_bufs; i++, phys_addr += MPI3MR_SENSEBUF_SZ)
1748 		sc->sense_buf_q[i] = phys_addr;
1749 	sc->sense_buf_q[i] = (0);
1750 
1751 }
1752 
1753 static int mpi3mr_reply_dma_alloc(struct mpi3mr_softc *sc)
1754 {
1755 	U32 sz;
1756 
1757 	sc->num_reply_bufs = sc->facts.max_reqs + MPI3MR_NUM_EVTREPLIES;
1758 	sc->reply_free_q_sz = sc->num_reply_bufs + 1;
1759 	sc->num_sense_bufs = sc->facts.max_reqs / MPI3MR_SENSEBUF_FACTOR;
1760 	sc->sense_buf_q_sz = sc->num_sense_bufs + 1;
1761 
1762 	sz = sc->num_reply_bufs * sc->reply_sz;
1763 
1764 	if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,  /* parent */
1765 				16, 0,			/* algnmnt, boundary */
1766 				sc->dma_loaddr,		/* lowaddr */
1767 				BUS_SPACE_MAXADDR,	/* highaddr */
1768 				NULL, NULL,		/* filter, filterarg */
1769                                 sz,			/* maxsize */
1770                                 1,			/* nsegments */
1771                                 sz,			/* maxsegsize */
1772                                 0,			/* flags */
1773                                 NULL, NULL,		/* lockfunc, lockarg */
1774                                 &sc->reply_buf_tag)) {
1775 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n");
1776 		return (ENOMEM);
1777         }
1778 
1779 	if (bus_dmamem_alloc(sc->reply_buf_tag, (void **)&sc->reply_buf,
1780 	    BUS_DMA_NOWAIT, &sc->reply_buf_dmamap)) {
1781 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d  DMA mem alloc failed\n",
1782 			__func__, __LINE__);
1783 		return (ENOMEM);
1784         }
1785 
1786 	bzero(sc->reply_buf, sz);
1787         bus_dmamap_load(sc->reply_buf_tag, sc->reply_buf_dmamap, sc->reply_buf, sz,
1788 	    mpi3mr_memaddr_cb, &sc->reply_buf_phys, BUS_DMA_NOWAIT);
1789 
1790 	sc->reply_buf_dma_min_address = sc->reply_buf_phys;
1791 	sc->reply_buf_dma_max_address = sc->reply_buf_phys + sz;
1792 	mpi3mr_dprint(sc, MPI3MR_XINFO, "reply buf (0x%p): depth(%d), frame_size(%d), "
1793 	    "pool_size(%d kB), reply_buf_dma(0x%llx)\n",
1794 	    sc->reply_buf, sc->num_reply_bufs, sc->reply_sz,
1795 	    (sz / 1024), (unsigned long long)sc->reply_buf_phys);
1796 
1797 	/* reply free queue, 8 byte align */
1798 	sz = sc->reply_free_q_sz * 8;
1799 
1800         if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,    /* parent */
1801 				8, 0,			/* algnmnt, boundary */
1802 				sc->dma_loaddr,		/* lowaddr */
1803 				BUS_SPACE_MAXADDR,	/* highaddr */
1804 				NULL, NULL,		/* filter, filterarg */
1805                                 sz,			/* maxsize */
1806                                 1,			/* nsegments */
1807                                 sz,			/* maxsegsize */
1808                                 0,			/* flags */
1809                                 NULL, NULL,		/* lockfunc, lockarg */
1810                                 &sc->reply_free_q_tag)) {
1811 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate reply free queue DMA tag\n");
1812 		return (ENOMEM);
1813         }
1814 
1815         if (bus_dmamem_alloc(sc->reply_free_q_tag, (void **)&sc->reply_free_q,
1816 	    BUS_DMA_NOWAIT, &sc->reply_free_q_dmamap)) {
1817 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d  DMA mem alloc failed\n",
1818 			__func__, __LINE__);
1819 		return (ENOMEM);
1820         }
1821 
1822 	bzero(sc->reply_free_q, sz);
1823         bus_dmamap_load(sc->reply_free_q_tag, sc->reply_free_q_dmamap, sc->reply_free_q, sz,
1824 	    mpi3mr_memaddr_cb, &sc->reply_free_q_phys, BUS_DMA_NOWAIT);
1825 
1826 	mpi3mr_dprint(sc, MPI3MR_XINFO, "reply_free_q (0x%p): depth(%d), frame_size(%d), "
1827 	    "pool_size(%d kB), reply_free_q_dma(0x%llx)\n",
1828 	    sc->reply_free_q, sc->reply_free_q_sz, 8, (sz / 1024),
1829 	    (unsigned long long)sc->reply_free_q_phys);
1830 
1831 	/* sense buffer pool,  4 byte align */
1832 	sz = sc->num_sense_bufs * MPI3MR_SENSEBUF_SZ;
1833 
1834         if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,    /* parent */
1835 				4, 0,			/* algnmnt, boundary */
1836 				sc->dma_loaddr,		/* lowaddr */
1837 				BUS_SPACE_MAXADDR,	/* highaddr */
1838 				NULL, NULL,		/* filter, filterarg */
1839                                 sz,			/* maxsize */
1840                                 1,			/* nsegments */
1841                                 sz,			/* maxsegsize */
1842                                 0,			/* flags */
1843                                 NULL, NULL,		/* lockfunc, lockarg */
1844                                 &sc->sense_buf_tag)) {
1845 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate Sense buffer DMA tag\n");
1846 		return (ENOMEM);
1847         }
1848 
1849 	if (bus_dmamem_alloc(sc->sense_buf_tag, (void **)&sc->sense_buf,
1850 	    BUS_DMA_NOWAIT, &sc->sense_buf_dmamap)) {
1851 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d  DMA mem alloc failed\n",
1852 			__func__, __LINE__);
1853 		return (ENOMEM);
1854         }
1855 
1856 	bzero(sc->sense_buf, sz);
1857         bus_dmamap_load(sc->sense_buf_tag, sc->sense_buf_dmamap, sc->sense_buf, sz,
1858 	    mpi3mr_memaddr_cb, &sc->sense_buf_phys, BUS_DMA_NOWAIT);
1859 
1860 	mpi3mr_dprint(sc, MPI3MR_XINFO, "sense_buf (0x%p): depth(%d), frame_size(%d), "
1861 	    "pool_size(%d kB), sense_dma(0x%llx)\n",
1862 	    sc->sense_buf, sc->num_sense_bufs, MPI3MR_SENSEBUF_SZ,
1863 	    (sz / 1024), (unsigned long long)sc->sense_buf_phys);
1864 
1865 	/* sense buffer queue, 8 byte align */
1866 	sz = sc->sense_buf_q_sz * 8;
1867 
1868         if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,    /* parent */
1869 				8, 0,			/* algnmnt, boundary */
1870 				sc->dma_loaddr,		/* lowaddr */
1871 				BUS_SPACE_MAXADDR,	/* highaddr */
1872 				NULL, NULL,		/* filter, filterarg */
1873                                 sz,			/* maxsize */
1874                                 1,			/* nsegments */
1875                                 sz,			/* maxsegsize */
1876                                 0,			/* flags */
1877                                 NULL, NULL,		/* lockfunc, lockarg */
1878                                 &sc->sense_buf_q_tag)) {
1879 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate Sense buffer Queue DMA tag\n");
1880 		return (ENOMEM);
1881         }
1882 
1883 	if (bus_dmamem_alloc(sc->sense_buf_q_tag, (void **)&sc->sense_buf_q,
1884 	    BUS_DMA_NOWAIT, &sc->sense_buf_q_dmamap)) {
1885 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d  DMA mem alloc failed\n",
1886 			__func__, __LINE__);
1887 		return (ENOMEM);
1888         }
1889 
1890 	bzero(sc->sense_buf_q, sz);
1891         bus_dmamap_load(sc->sense_buf_q_tag, sc->sense_buf_q_dmamap, sc->sense_buf_q, sz,
1892 	    mpi3mr_memaddr_cb, &sc->sense_buf_q_phys, BUS_DMA_NOWAIT);
1893 
1894 	mpi3mr_dprint(sc, MPI3MR_XINFO, "sense_buf_q (0x%p): depth(%d), frame_size(%d), "
1895 	    "pool_size(%d kB), sense_dma(0x%llx)\n",
1896 	    sc->sense_buf_q, sc->sense_buf_q_sz, 8, (sz / 1024),
1897 	    (unsigned long long)sc->sense_buf_q_phys);
1898 
1899 	return 0;
1900 }
1901 
1902 static int mpi3mr_reply_alloc(struct mpi3mr_softc *sc)
1903 {
1904 	int retval = 0;
1905 	U32 i;
1906 
1907 	if (sc->init_cmds.reply)
1908 		goto post_reply_sbuf;
1909 
1910 	sc->init_cmds.reply = malloc(sc->reply_sz,
1911 		M_MPI3MR, M_NOWAIT | M_ZERO);
1912 
1913 	if (!sc->init_cmds.reply) {
1914 		printf(IOCNAME "Cannot allocate memory for init_cmds.reply\n",
1915 		    sc->name);
1916 		goto out_failed;
1917 	}
1918 
1919 	sc->cfg_cmds.reply = malloc(sc->reply_sz,
1920 		M_MPI3MR, M_NOWAIT | M_ZERO);
1921 
1922 	if (!sc->cfg_cmds.reply) {
1923 		printf(IOCNAME "Cannot allocate memory for cfg_cmds.reply\n",
1924 		    sc->name);
1925 		goto out_failed;
1926 	}
1927 
1928 	sc->ioctl_cmds.reply = malloc(sc->reply_sz, M_MPI3MR, M_NOWAIT | M_ZERO);
1929 	if (!sc->ioctl_cmds.reply) {
1930 		printf(IOCNAME "Cannot allocate memory for ioctl_cmds.reply\n",
1931 		    sc->name);
1932 		goto out_failed;
1933 	}
1934 
1935 	sc->host_tm_cmds.reply = malloc(sc->reply_sz, M_MPI3MR, M_NOWAIT | M_ZERO);
1936 	if (!sc->host_tm_cmds.reply) {
1937 		printf(IOCNAME "Cannot allocate memory for host_tm.reply\n",
1938 		    sc->name);
1939 		goto out_failed;
1940 	}
1941 	for (i=0; i<MPI3MR_NUM_DEVRMCMD; i++) {
1942 		sc->dev_rmhs_cmds[i].reply = malloc(sc->reply_sz,
1943 		    M_MPI3MR, M_NOWAIT | M_ZERO);
1944 		if (!sc->dev_rmhs_cmds[i].reply) {
1945 			printf(IOCNAME "Cannot allocate memory for"
1946 			    " dev_rmhs_cmd[%d].reply\n",
1947 			    sc->name, i);
1948 			goto out_failed;
1949 		}
1950 	}
1951 
1952 	for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++) {
1953 		sc->evtack_cmds[i].reply = malloc(sc->reply_sz,
1954 			M_MPI3MR, M_NOWAIT | M_ZERO);
1955 		if (!sc->evtack_cmds[i].reply)
1956 			goto out_failed;
1957 	}
1958 
1959 	sc->dev_handle_bitmap_sz = MPI3MR_DIV_ROUND_UP(sc->facts.max_devhandle, 8);
1960 
1961 	sc->removepend_bitmap = malloc(sc->dev_handle_bitmap_sz,
1962 	    M_MPI3MR, M_NOWAIT | M_ZERO);
1963 	if (!sc->removepend_bitmap) {
1964 		printf(IOCNAME "Cannot alloc memory for remove pend bitmap\n",
1965 		    sc->name);
1966 		goto out_failed;
1967 	}
1968 
1969 	sc->devrem_bitmap_sz = MPI3MR_DIV_ROUND_UP(MPI3MR_NUM_DEVRMCMD, 8);
1970 	sc->devrem_bitmap = malloc(sc->devrem_bitmap_sz,
1971 	    M_MPI3MR, M_NOWAIT | M_ZERO);
1972 	if (!sc->devrem_bitmap) {
1973 		printf(IOCNAME "Cannot alloc memory for dev remove bitmap\n",
1974 		    sc->name);
1975 		goto out_failed;
1976 	}
1977 
1978 	sc->evtack_cmds_bitmap_sz = MPI3MR_DIV_ROUND_UP(MPI3MR_NUM_EVTACKCMD, 8);
1979 
1980 	sc->evtack_cmds_bitmap = malloc(sc->evtack_cmds_bitmap_sz,
1981 		M_MPI3MR, M_NOWAIT | M_ZERO);
1982 	if (!sc->evtack_cmds_bitmap)
1983 		goto out_failed;
1984 
1985 	if (mpi3mr_reply_dma_alloc(sc)) {
1986 		printf(IOCNAME "func:%s line:%d DMA memory allocation failed\n",
1987 		    sc->name, __func__, __LINE__);
1988 		goto out_failed;
1989 	}
1990 
1991 post_reply_sbuf:
1992 	mpi3mr_setup_reply_free_queues(sc);
1993 	return retval;
1994 out_failed:
1995 	mpi3mr_cleanup_interrupts(sc);
1996 	mpi3mr_free_mem(sc);
1997 	retval = -1;
1998 	return retval;
1999 }
2000 
2001 static void
2002 mpi3mr_print_fw_pkg_ver(struct mpi3mr_softc *sc)
2003 {
2004 	int retval = 0;
2005 	void *fw_pkg_ver = NULL;
2006 	bus_dma_tag_t fw_pkg_ver_tag;
2007 	bus_dmamap_t fw_pkg_ver_map;
2008 	bus_addr_t fw_pkg_ver_dma;
2009 	Mpi3CIUploadRequest_t ci_upload;
2010 	Mpi3ComponentImageHeader_t *ci_header;
2011 	U32 fw_pkg_ver_len = sizeof(*ci_header);
2012 	U8 sgl_flags = MPI3MR_SGEFLAGS_SYSTEM_SIMPLE_END_OF_LIST;
2013 
2014 	if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,  /* parent */
2015 				4, 0,			/* algnmnt, boundary */
2016 				sc->dma_loaddr,		/* lowaddr */
2017 				BUS_SPACE_MAXADDR,	/* highaddr */
2018 				NULL, NULL,		/* filter, filterarg */
2019 				fw_pkg_ver_len,		/* maxsize */
2020 				1,			/* nsegments */
2021 				fw_pkg_ver_len,		/* maxsegsize */
2022 				0,			/* flags */
2023 				NULL, NULL,		/* lockfunc, lockarg */
2024 				&fw_pkg_ver_tag)) {
2025 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate fw package version request DMA tag\n");
2026 		return;
2027 	}
2028 
2029 	if (bus_dmamem_alloc(fw_pkg_ver_tag, (void **)&fw_pkg_ver, BUS_DMA_NOWAIT, &fw_pkg_ver_map)) {
2030 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d fw package version DMA mem alloc failed\n",
2031 			      __func__, __LINE__);
2032 		return;
2033 	}
2034 
2035 	bzero(fw_pkg_ver, fw_pkg_ver_len);
2036 
2037 	bus_dmamap_load(fw_pkg_ver_tag, fw_pkg_ver_map, fw_pkg_ver, fw_pkg_ver_len,
2038 	    mpi3mr_memaddr_cb, &fw_pkg_ver_dma, BUS_DMA_NOWAIT);
2039 
2040 	mpi3mr_dprint(sc, MPI3MR_XINFO, "Func: %s line: %d fw package version phys addr= %#016jx size= %d\n",
2041 		      __func__, __LINE__, (uintmax_t)fw_pkg_ver_dma, fw_pkg_ver_len);
2042 
2043 	if (!fw_pkg_ver) {
2044 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Memory alloc for fw package version failed\n");
2045 		goto out;
2046 	}
2047 
2048 	memset(&ci_upload, 0, sizeof(ci_upload));
2049 	mtx_lock(&sc->init_cmds.completion.lock);
2050 	if (sc->init_cmds.state & MPI3MR_CMD_PENDING) {
2051 		mpi3mr_dprint(sc, MPI3MR_INFO,"Issue CI Header Upload: command is in use\n");
2052 		mtx_unlock(&sc->init_cmds.completion.lock);
2053 		goto out;
2054 	}
2055 	sc->init_cmds.state = MPI3MR_CMD_PENDING;
2056 	sc->init_cmds.is_waiting = 1;
2057 	sc->init_cmds.callback = NULL;
2058 	ci_upload.HostTag = htole16(MPI3MR_HOSTTAG_INITCMDS);
2059 	ci_upload.Function = MPI3_FUNCTION_CI_UPLOAD;
2060 	ci_upload.MsgFlags = MPI3_CI_UPLOAD_MSGFLAGS_LOCATION_PRIMARY;
2061 	ci_upload.ImageOffset = MPI3_IMAGE_HEADER_SIGNATURE0_OFFSET;
2062 	ci_upload.SegmentSize = MPI3_IMAGE_HEADER_SIZE;
2063 
2064 	mpi3mr_add_sg_single(&ci_upload.SGL, sgl_flags, fw_pkg_ver_len,
2065 	    fw_pkg_ver_dma);
2066 
2067 	init_completion(&sc->init_cmds.completion);
2068 	if ((retval = mpi3mr_submit_admin_cmd(sc, &ci_upload, sizeof(ci_upload)))) {
2069 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Issue CI Header Upload: Admin Post failed\n");
2070 		goto out_unlock;
2071 	}
2072 	wait_for_completion_timeout(&sc->init_cmds.completion,
2073 		(MPI3MR_INTADMCMD_TIMEOUT));
2074 	if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) {
2075 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Issue CI Header Upload: command timed out\n");
2076 		sc->init_cmds.is_waiting = 0;
2077 		if (!(sc->init_cmds.state & MPI3MR_CMD_RESET))
2078 			mpi3mr_check_rh_fault_ioc(sc,
2079 				MPI3MR_RESET_FROM_GETPKGVER_TIMEOUT);
2080 		goto out_unlock;
2081 	}
2082 	if ((GET_IOC_STATUS(sc->init_cmds.ioc_status)) != MPI3_IOCSTATUS_SUCCESS) {
2083 		mpi3mr_dprint(sc, MPI3MR_ERROR,
2084 			      "Issue CI Header Upload: Failed IOCStatus(0x%04x) Loginfo(0x%08x)\n",
2085 			      GET_IOC_STATUS(sc->init_cmds.ioc_status), sc->init_cmds.ioc_loginfo);
2086 		goto out_unlock;
2087 	}
2088 
2089 	ci_header = (Mpi3ComponentImageHeader_t *) fw_pkg_ver;
2090 	mpi3mr_dprint(sc, MPI3MR_XINFO,
2091 		      "Issue CI Header Upload:EnvVariableOffset(0x%x) \
2092 		      HeaderSize(0x%x) Signature1(0x%x)\n",
2093 		      ci_header->EnvironmentVariableOffset,
2094 		      ci_header->HeaderSize,
2095 		      ci_header->Signature1);
2096 	mpi3mr_dprint(sc, MPI3MR_INFO, "FW Package Version: %02d.%02d.%02d.%02d\n",
2097 		      ci_header->ComponentImageVersion.GenMajor,
2098 		      ci_header->ComponentImageVersion.GenMinor,
2099 		      ci_header->ComponentImageVersion.PhaseMajor,
2100 		      ci_header->ComponentImageVersion.PhaseMinor);
2101 out_unlock:
2102 	sc->init_cmds.state = MPI3MR_CMD_NOTUSED;
2103 	mtx_unlock(&sc->init_cmds.completion.lock);
2104 
2105 out:
2106 	if (fw_pkg_ver_dma != 0)
2107 		bus_dmamap_unload(fw_pkg_ver_tag, fw_pkg_ver_map);
2108 	if (fw_pkg_ver)
2109 		bus_dmamem_free(fw_pkg_ver_tag, fw_pkg_ver, fw_pkg_ver_map);
2110 	if (fw_pkg_ver_tag)
2111 		bus_dma_tag_destroy(fw_pkg_ver_tag);
2112 
2113 }
2114 
2115 /**
2116  * mpi3mr_issue_iocinit - Send IOC Init
2117  * @sc: Adapter instance reference
2118  *
2119  * Issue IOC Init MPI request through admin queue and wait for
2120  * the completion of it or time out.
2121  *
2122  * Return: 0 on success, non-zero on failures.
2123  */
2124 static int mpi3mr_issue_iocinit(struct mpi3mr_softc *sc)
2125 {
2126 	Mpi3IOCInitRequest_t iocinit_req;
2127 	Mpi3DriverInfoLayout_t *drvr_info = NULL;
2128 	bus_dma_tag_t drvr_info_tag;
2129 	bus_dmamap_t drvr_info_map;
2130 	bus_addr_t drvr_info_phys;
2131 	U32 drvr_info_len = sizeof(*drvr_info);
2132 	int retval = 0;
2133 	struct timeval now;
2134 	uint64_t time_in_msec;
2135 
2136 	if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,  /* parent */
2137 				4, 0,			/* algnmnt, boundary */
2138 				sc->dma_loaddr,		/* lowaddr */
2139 				BUS_SPACE_MAXADDR,	/* highaddr */
2140 				NULL, NULL,		/* filter, filterarg */
2141                                 drvr_info_len,		/* maxsize */
2142                                 1,			/* nsegments */
2143                                 drvr_info_len,		/* maxsegsize */
2144                                 0,			/* flags */
2145                                 NULL, NULL,		/* lockfunc, lockarg */
2146                                 &drvr_info_tag)) {
2147 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n");
2148 		return (ENOMEM);
2149         }
2150 
2151 	if (bus_dmamem_alloc(drvr_info_tag, (void **)&drvr_info,
2152 	    BUS_DMA_NOWAIT, &drvr_info_map)) {
2153 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d Data  DMA mem alloc failed\n",
2154 			__func__, __LINE__);
2155 		return (ENOMEM);
2156         }
2157 
2158 	bzero(drvr_info, drvr_info_len);
2159         bus_dmamap_load(drvr_info_tag, drvr_info_map, drvr_info, drvr_info_len,
2160 	    mpi3mr_memaddr_cb, &drvr_info_phys, BUS_DMA_NOWAIT);
2161 	mpi3mr_dprint(sc, MPI3MR_XINFO, "Func: %s line: %d IOCfacts drvr_info phys addr= %#016jx size= %d\n",
2162 	    __func__, __LINE__, (uintmax_t)drvr_info_phys, drvr_info_len);
2163 
2164 	if (!drvr_info)
2165 	{
2166 		retval = -1;
2167 		printf(IOCNAME "Memory alloc for Driver Info failed\n",
2168 		    sc->name);
2169 		goto out;
2170 	}
2171 	drvr_info->InformationLength = (drvr_info_len);
2172 	strcpy(drvr_info->DriverSignature, "Broadcom");
2173 	strcpy(drvr_info->OsName, "FreeBSD");
2174 	strcpy(drvr_info->OsVersion, fmt_os_ver);
2175 	strcpy(drvr_info->DriverName, MPI3MR_DRIVER_NAME);
2176 	strcpy(drvr_info->DriverVersion, MPI3MR_DRIVER_VERSION);
2177 	strcpy(drvr_info->DriverReleaseDate, MPI3MR_DRIVER_RELDATE);
2178 	drvr_info->DriverCapabilities = MPI3_IOCINIT_DRIVERCAP_OSEXPOSURE_NO_SPECIAL;
2179 	memcpy((U8 *)&sc->driver_info, (U8 *)drvr_info, sizeof(sc->driver_info));
2180 
2181 	memset(&iocinit_req, 0, sizeof(iocinit_req));
2182 	mtx_lock(&sc->init_cmds.completion.lock);
2183 	if (sc->init_cmds.state & MPI3MR_CMD_PENDING) {
2184 		retval = -1;
2185 		printf(IOCNAME "Issue IOCInit: Init command is in use\n",
2186 		    sc->name);
2187 		mtx_unlock(&sc->init_cmds.completion.lock);
2188 		goto out;
2189 	}
2190 	sc->init_cmds.state = MPI3MR_CMD_PENDING;
2191 	sc->init_cmds.is_waiting = 1;
2192 	sc->init_cmds.callback = NULL;
2193         iocinit_req.HostTag = MPI3MR_HOSTTAG_INITCMDS;
2194         iocinit_req.Function = MPI3_FUNCTION_IOC_INIT;
2195         iocinit_req.MPIVersion.Struct.Dev = MPI3_VERSION_DEV;
2196         iocinit_req.MPIVersion.Struct.Unit = MPI3_VERSION_UNIT;
2197         iocinit_req.MPIVersion.Struct.Major = MPI3_VERSION_MAJOR;
2198         iocinit_req.MPIVersion.Struct.Minor = MPI3_VERSION_MINOR;
2199         iocinit_req.WhoInit = MPI3_WHOINIT_HOST_DRIVER;
2200         iocinit_req.ReplyFreeQueueDepth = sc->reply_free_q_sz;
2201         iocinit_req.ReplyFreeQueueAddress =
2202                 sc->reply_free_q_phys;
2203         iocinit_req.SenseBufferLength = MPI3MR_SENSEBUF_SZ;
2204         iocinit_req.SenseBufferFreeQueueDepth =
2205                 sc->sense_buf_q_sz;
2206         iocinit_req.SenseBufferFreeQueueAddress =
2207                 sc->sense_buf_q_phys;
2208         iocinit_req.DriverInformationAddress = drvr_info_phys;
2209 
2210 	getmicrotime(&now);
2211 	time_in_msec = (now.tv_sec * 1000 + now.tv_usec/1000);
2212 	iocinit_req.TimeStamp = htole64(time_in_msec);
2213 
2214 	iocinit_req.MsgFlags |= MPI3_IOCINIT_MSGFLAGS_WRITESAMEDIVERT_SUPPORTED;
2215 
2216 	init_completion(&sc->init_cmds.completion);
2217 	retval = mpi3mr_submit_admin_cmd(sc, &iocinit_req,
2218 	    sizeof(iocinit_req));
2219 
2220 	if (retval) {
2221 		printf(IOCNAME "Issue IOCInit: Admin Post failed\n",
2222 		    sc->name);
2223 		goto out_unlock;
2224 	}
2225 
2226 	wait_for_completion_timeout(&sc->init_cmds.completion,
2227 	    (MPI3MR_INTADMCMD_TIMEOUT));
2228 	if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) {
2229 		printf(IOCNAME "Issue IOCInit: command timed out\n",
2230 		    sc->name);
2231 		mpi3mr_check_rh_fault_ioc(sc,
2232 		    MPI3MR_RESET_FROM_IOCINIT_TIMEOUT);
2233 		sc->unrecoverable = 1;
2234 		retval = -1;
2235 		goto out_unlock;
2236 	}
2237 
2238 	if ((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK)
2239 	     != MPI3_IOCSTATUS_SUCCESS ) {
2240 		printf(IOCNAME "Issue IOCInit: Failed IOCStatus(0x%04x) "
2241 		    " Loginfo(0x%08x) \n" , sc->name,
2242 		    (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK),
2243 		    sc->init_cmds.ioc_loginfo);
2244 		retval = -1;
2245 		goto out_unlock;
2246 	}
2247 
2248 out_unlock:
2249 	sc->init_cmds.state = MPI3MR_CMD_NOTUSED;
2250 	mtx_unlock(&sc->init_cmds.completion.lock);
2251 
2252 out:
2253 	if (drvr_info_phys != 0)
2254 		bus_dmamap_unload(drvr_info_tag, drvr_info_map);
2255 	if (drvr_info != NULL)
2256 		bus_dmamem_free(drvr_info_tag, drvr_info, drvr_info_map);
2257 	if (drvr_info_tag != NULL)
2258 		bus_dma_tag_destroy(drvr_info_tag);
2259 	return retval;
2260 }
2261 
2262 static void
2263 mpi3mr_display_ioc_info(struct mpi3mr_softc *sc)
2264 {
2265         int i = 0;
2266         char personality[16];
2267 
2268         switch (sc->facts.personality) {
2269         case MPI3_IOCFACTS_FLAGS_PERSONALITY_EHBA:
2270                 strcpy(personality, "Enhanced HBA");
2271                 break;
2272         case MPI3_IOCFACTS_FLAGS_PERSONALITY_RAID_DDR:
2273                 strcpy(personality, "RAID");
2274                 break;
2275         default:
2276                 strcpy(personality, "Unknown");
2277                 break;
2278         }
2279 
2280 	mpi3mr_dprint(sc, MPI3MR_INFO, "Current Personality: %s\n", personality);
2281 
2282 	mpi3mr_dprint(sc, MPI3MR_INFO, "%s\n", sc->fw_version);
2283 
2284         mpi3mr_dprint(sc, MPI3MR_INFO, "Protocol=(");
2285 
2286         if (sc->facts.protocol_flags &
2287             MPI3_IOCFACTS_PROTOCOL_SCSI_INITIATOR) {
2288                 printf("Initiator");
2289                 i++;
2290         }
2291 
2292         if (sc->facts.protocol_flags &
2293             MPI3_IOCFACTS_PROTOCOL_SCSI_TARGET) {
2294                 printf("%sTarget", i ? "," : "");
2295                 i++;
2296         }
2297 
2298         if (sc->facts.protocol_flags &
2299             MPI3_IOCFACTS_PROTOCOL_NVME) {
2300                 printf("%sNVMe attachment", i ? "," : "");
2301                 i++;
2302         }
2303         i = 0;
2304         printf("), ");
2305         printf("Capabilities=(");
2306 
2307         if (sc->facts.ioc_capabilities &
2308 	    MPI3_IOCFACTS_CAPABILITY_RAID_SUPPORTED) {
2309                 printf("RAID");
2310                 i++;
2311         }
2312 
2313         printf(")\n");
2314 }
2315 
2316 /**
2317  * mpi3mr_unmask_events - Unmask events in event mask bitmap
2318  * @sc: Adapter instance reference
2319  * @event: MPI event ID
2320  *
2321  * Un mask the specific event by resetting the event_mask
2322  * bitmap.
2323  *
2324  * Return: None.
2325  */
2326 static void mpi3mr_unmask_events(struct mpi3mr_softc *sc, U16 event)
2327 {
2328 	U32 desired_event;
2329 
2330 	if (event >= 128)
2331 		return;
2332 
2333 	desired_event = (1 << (event % 32));
2334 
2335 	if (event < 32)
2336 		sc->event_masks[0] &= ~desired_event;
2337 	else if (event < 64)
2338 		sc->event_masks[1] &= ~desired_event;
2339 	else if (event < 96)
2340 		sc->event_masks[2] &= ~desired_event;
2341 	else if (event < 128)
2342 		sc->event_masks[3] &= ~desired_event;
2343 }
2344 
2345 static void mpi3mr_set_events_mask(struct mpi3mr_softc *sc)
2346 {
2347 	int i;
2348 	for (i = 0; i < MPI3_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
2349 		sc->event_masks[i] = -1;
2350 
2351         mpi3mr_unmask_events(sc, MPI3_EVENT_DEVICE_ADDED);
2352         mpi3mr_unmask_events(sc, MPI3_EVENT_DEVICE_INFO_CHANGED);
2353         mpi3mr_unmask_events(sc, MPI3_EVENT_DEVICE_STATUS_CHANGE);
2354 
2355         mpi3mr_unmask_events(sc, MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE);
2356 
2357         mpi3mr_unmask_events(sc, MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST);
2358         mpi3mr_unmask_events(sc, MPI3_EVENT_SAS_DISCOVERY);
2359         mpi3mr_unmask_events(sc, MPI3_EVENT_SAS_DEVICE_DISCOVERY_ERROR);
2360         mpi3mr_unmask_events(sc, MPI3_EVENT_SAS_BROADCAST_PRIMITIVE);
2361 
2362         mpi3mr_unmask_events(sc, MPI3_EVENT_PCIE_TOPOLOGY_CHANGE_LIST);
2363         mpi3mr_unmask_events(sc, MPI3_EVENT_PCIE_ENUMERATION);
2364 
2365         mpi3mr_unmask_events(sc, MPI3_EVENT_PREPARE_FOR_RESET);
2366         mpi3mr_unmask_events(sc, MPI3_EVENT_CABLE_MGMT);
2367         mpi3mr_unmask_events(sc, MPI3_EVENT_ENERGY_PACK_CHANGE);
2368 }
2369 
2370 /**
2371  * mpi3mr_issue_event_notification - Send event notification
2372  * @sc: Adapter instance reference
2373  *
2374  * Issue event notification MPI request through admin queue and
2375  * wait for the completion of it or time out.
2376  *
2377  * Return: 0 on success, non-zero on failures.
2378  */
2379 int mpi3mr_issue_event_notification(struct mpi3mr_softc *sc)
2380 {
2381 	Mpi3EventNotificationRequest_t evtnotify_req;
2382 	int retval = 0;
2383 	U8 i;
2384 
2385 	memset(&evtnotify_req, 0, sizeof(evtnotify_req));
2386 	mtx_lock(&sc->init_cmds.completion.lock);
2387 	if (sc->init_cmds.state & MPI3MR_CMD_PENDING) {
2388 		retval = -1;
2389 		printf(IOCNAME "Issue EvtNotify: Init command is in use\n",
2390 		    sc->name);
2391 		mtx_unlock(&sc->init_cmds.completion.lock);
2392 		goto out;
2393 	}
2394 	sc->init_cmds.state = MPI3MR_CMD_PENDING;
2395 	sc->init_cmds.is_waiting = 1;
2396 	sc->init_cmds.callback = NULL;
2397 	evtnotify_req.HostTag = (MPI3MR_HOSTTAG_INITCMDS);
2398 	evtnotify_req.Function = MPI3_FUNCTION_EVENT_NOTIFICATION;
2399 	for (i = 0; i < MPI3_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
2400 		evtnotify_req.EventMasks[i] =
2401 		    (sc->event_masks[i]);
2402 	init_completion(&sc->init_cmds.completion);
2403 	retval = mpi3mr_submit_admin_cmd(sc, &evtnotify_req,
2404 	    sizeof(evtnotify_req));
2405 	if (retval) {
2406 		printf(IOCNAME "Issue EvtNotify: Admin Post failed\n",
2407 		    sc->name);
2408 		goto out_unlock;
2409 	}
2410 
2411 	poll_for_command_completion(sc,
2412 				    &sc->init_cmds,
2413 				    (MPI3MR_INTADMCMD_TIMEOUT));
2414 	if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) {
2415 		printf(IOCNAME "Issue EvtNotify: command timed out\n",
2416 		    sc->name);
2417 		mpi3mr_check_rh_fault_ioc(sc,
2418 		    MPI3MR_RESET_FROM_EVTNOTIFY_TIMEOUT);
2419 		retval = -1;
2420 		goto out_unlock;
2421 	}
2422 
2423 	if ((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK)
2424 	     != MPI3_IOCSTATUS_SUCCESS ) {
2425 		printf(IOCNAME "Issue EvtNotify: Failed IOCStatus(0x%04x) "
2426 		    " Loginfo(0x%08x) \n" , sc->name,
2427 		    (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK),
2428 		    sc->init_cmds.ioc_loginfo);
2429 		retval = -1;
2430 		goto out_unlock;
2431 	}
2432 
2433 out_unlock:
2434 	sc->init_cmds.state = MPI3MR_CMD_NOTUSED;
2435 	mtx_unlock(&sc->init_cmds.completion.lock);
2436 
2437 out:
2438 	return retval;
2439 }
2440 
2441 int
2442 mpi3mr_register_events(struct mpi3mr_softc *sc)
2443 {
2444 	int error;
2445 
2446 	mpi3mr_set_events_mask(sc);
2447 
2448 	error = mpi3mr_issue_event_notification(sc);
2449 
2450 	if (error) {
2451 		printf(IOCNAME "Failed to issue event notification %d\n",
2452 		    sc->name, error);
2453 	}
2454 
2455 	return error;
2456 }
2457 
2458 /**
2459  * mpi3mr_process_event_ack - Process event acknowledgment
2460  * @sc: Adapter instance reference
2461  * @event: MPI3 event ID
2462  * @event_ctx: Event context
2463  *
2464  * Send event acknowledgement through admin queue and wait for
2465  * it to complete.
2466  *
2467  * Return: 0 on success, non-zero on failures.
2468  */
2469 int mpi3mr_process_event_ack(struct mpi3mr_softc *sc, U8 event,
2470 	U32 event_ctx)
2471 {
2472 	Mpi3EventAckRequest_t evtack_req;
2473 	int retval = 0;
2474 
2475 	memset(&evtack_req, 0, sizeof(evtack_req));
2476 	mtx_lock(&sc->init_cmds.completion.lock);
2477 	if (sc->init_cmds.state & MPI3MR_CMD_PENDING) {
2478 		retval = -1;
2479 		printf(IOCNAME "Issue EvtAck: Init command is in use\n",
2480 		    sc->name);
2481 		mtx_unlock(&sc->init_cmds.completion.lock);
2482 		goto out;
2483 	}
2484 	sc->init_cmds.state = MPI3MR_CMD_PENDING;
2485 	sc->init_cmds.is_waiting = 1;
2486 	sc->init_cmds.callback = NULL;
2487 	evtack_req.HostTag = htole16(MPI3MR_HOSTTAG_INITCMDS);
2488 	evtack_req.Function = MPI3_FUNCTION_EVENT_ACK;
2489 	evtack_req.Event = event;
2490 	evtack_req.EventContext = htole32(event_ctx);
2491 
2492 	init_completion(&sc->init_cmds.completion);
2493 	retval = mpi3mr_submit_admin_cmd(sc, &evtack_req,
2494 	    sizeof(evtack_req));
2495 	if (retval) {
2496 		printf(IOCNAME "Issue EvtAck: Admin Post failed\n",
2497 		    sc->name);
2498 		goto out_unlock;
2499 	}
2500 
2501 	wait_for_completion_timeout(&sc->init_cmds.completion,
2502 	    (MPI3MR_INTADMCMD_TIMEOUT));
2503 	if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) {
2504 		printf(IOCNAME "Issue EvtAck: command timed out\n",
2505 		    sc->name);
2506 		retval = -1;
2507 		goto out_unlock;
2508 	}
2509 
2510 	if ((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK)
2511 	     != MPI3_IOCSTATUS_SUCCESS ) {
2512 		printf(IOCNAME "Issue EvtAck: Failed IOCStatus(0x%04x) "
2513 		    " Loginfo(0x%08x) \n" , sc->name,
2514 		    (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK),
2515 		    sc->init_cmds.ioc_loginfo);
2516 		retval = -1;
2517 		goto out_unlock;
2518 	}
2519 
2520 out_unlock:
2521 	sc->init_cmds.state = MPI3MR_CMD_NOTUSED;
2522 	mtx_unlock(&sc->init_cmds.completion.lock);
2523 
2524 out:
2525 	return retval;
2526 }
2527 
2528 
2529 static int mpi3mr_alloc_chain_bufs(struct mpi3mr_softc *sc)
2530 {
2531 	int retval = 0;
2532 	U32 sz, i;
2533 	U16 num_chains;
2534 
2535 	num_chains = sc->max_host_ios;
2536 
2537 	sc->chain_buf_count = num_chains;
2538 	sz = sizeof(struct mpi3mr_chain) * num_chains;
2539 
2540 	sc->chain_sgl_list = malloc(sz, M_MPI3MR, M_NOWAIT | M_ZERO);
2541 
2542 	if (!sc->chain_sgl_list) {
2543 		printf(IOCNAME "Cannot allocate memory for chain SGL list\n",
2544 		    sc->name);
2545 		retval = -1;
2546 		goto out_failed;
2547 	}
2548 
2549 	if (sc->max_sgl_entries > sc->facts.max_data_length / PAGE_SIZE)
2550 		sc->max_sgl_entries = sc->facts.max_data_length / PAGE_SIZE;
2551 	sz = sc->max_sgl_entries * sizeof(Mpi3SGESimple_t);
2552 
2553         if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,  /* parent */
2554 				4096, 0,		/* algnmnt, boundary */
2555 				sc->dma_loaddr,		/* lowaddr */
2556 				BUS_SPACE_MAXADDR,	/* highaddr */
2557 				NULL, NULL,		/* filter, filterarg */
2558                                 sz,			/* maxsize */
2559                                 1,			/* nsegments */
2560                                 sz,			/* maxsegsize */
2561                                 0,			/* flags */
2562                                 NULL, NULL,		/* lockfunc, lockarg */
2563                                 &sc->chain_sgl_list_tag)) {
2564 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate Chain buffer DMA tag\n");
2565 		return (ENOMEM);
2566         }
2567 
2568 	for (i = 0; i < num_chains; i++) {
2569 		if (bus_dmamem_alloc(sc->chain_sgl_list_tag, (void **)&sc->chain_sgl_list[i].buf,
2570 		    BUS_DMA_NOWAIT, &sc->chain_sgl_list[i].buf_dmamap)) {
2571 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d  DMA mem alloc failed\n",
2572 				__func__, __LINE__);
2573 			return (ENOMEM);
2574 		}
2575 
2576 		bzero(sc->chain_sgl_list[i].buf, sz);
2577 		bus_dmamap_load(sc->chain_sgl_list_tag, sc->chain_sgl_list[i].buf_dmamap, sc->chain_sgl_list[i].buf, sz,
2578 		    mpi3mr_memaddr_cb, &sc->chain_sgl_list[i].buf_phys, BUS_DMA_NOWAIT);
2579 		mpi3mr_dprint(sc, MPI3MR_XINFO, "Func: %s line: %d phys addr= %#016jx size= %d\n",
2580 		    __func__, __LINE__, (uintmax_t)sc->chain_sgl_list[i].buf_phys, sz);
2581 	}
2582 
2583 	sc->chain_bitmap_sz = MPI3MR_DIV_ROUND_UP(num_chains, 8);
2584 
2585 	sc->chain_bitmap = malloc(sc->chain_bitmap_sz, M_MPI3MR, M_NOWAIT | M_ZERO);
2586 	if (!sc->chain_bitmap) {
2587 		mpi3mr_dprint(sc, MPI3MR_INFO, "Cannot alloc memory for chain bitmap\n");
2588 		retval = -1;
2589 		goto out_failed;
2590 	}
2591 	return retval;
2592 
2593 out_failed:
2594 	for (i = 0; i < num_chains; i++) {
2595 		if (sc->chain_sgl_list[i].buf_phys != 0)
2596 			bus_dmamap_unload(sc->chain_sgl_list_tag, sc->chain_sgl_list[i].buf_dmamap);
2597 		if (sc->chain_sgl_list[i].buf != NULL)
2598 			bus_dmamem_free(sc->chain_sgl_list_tag, sc->chain_sgl_list[i].buf, sc->chain_sgl_list[i].buf_dmamap);
2599 	}
2600 	if (sc->chain_sgl_list_tag != NULL)
2601 		bus_dma_tag_destroy(sc->chain_sgl_list_tag);
2602 	return retval;
2603 }
2604 
2605 static int mpi3mr_pel_alloc(struct mpi3mr_softc *sc)
2606 {
2607 	int retval = 0;
2608 
2609 	if (!sc->pel_cmds.reply) {
2610 		sc->pel_cmds.reply = malloc(sc->reply_sz, M_MPI3MR, M_NOWAIT | M_ZERO);
2611 		if (!sc->pel_cmds.reply) {
2612 			printf(IOCNAME "Cannot allocate memory for pel_cmds.reply\n",
2613 			    sc->name);
2614 			goto out_failed;
2615 		}
2616 	}
2617 
2618 	if (!sc->pel_abort_cmd.reply) {
2619 		sc->pel_abort_cmd.reply = malloc(sc->reply_sz, M_MPI3MR, M_NOWAIT | M_ZERO);
2620 		if (!sc->pel_abort_cmd.reply) {
2621 			printf(IOCNAME "Cannot allocate memory for pel_abort_cmd.reply\n",
2622 			    sc->name);
2623 			goto out_failed;
2624 		}
2625 	}
2626 
2627 	if (!sc->pel_seq_number) {
2628 		sc->pel_seq_number_sz = sizeof(Mpi3PELSeq_t);
2629 		if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,   /* parent */
2630 				 4, 0,                           /* alignment, boundary */
2631 				 sc->dma_loaddr,	         /* lowaddr */
2632 				 BUS_SPACE_MAXADDR,		 /* highaddr */
2633 				 NULL, NULL,                     /* filter, filterarg */
2634 				 sc->pel_seq_number_sz,		 /* maxsize */
2635 				 1,                              /* nsegments */
2636 				 sc->pel_seq_number_sz,          /* maxsegsize */
2637 				 0,                              /* flags */
2638 				 NULL, NULL,                     /* lockfunc, lockarg */
2639 				 &sc->pel_seq_num_dmatag)) {
2640 			 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot create PEL seq number dma memory tag\n");
2641 			 retval = -ENOMEM;
2642 			 goto out_failed;
2643 		}
2644 
2645 		if (bus_dmamem_alloc(sc->pel_seq_num_dmatag, (void **)&sc->pel_seq_number,
2646 		    BUS_DMA_NOWAIT, &sc->pel_seq_num_dmamap)) {
2647 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate PEL seq number kernel buffer dma memory\n");
2648 			retval = -ENOMEM;
2649 			goto out_failed;
2650 		}
2651 
2652 		bzero(sc->pel_seq_number, sc->pel_seq_number_sz);
2653 
2654 		bus_dmamap_load(sc->pel_seq_num_dmatag, sc->pel_seq_num_dmamap, sc->pel_seq_number,
2655 		    sc->pel_seq_number_sz, mpi3mr_memaddr_cb, &sc->pel_seq_number_dma, BUS_DMA_NOWAIT);
2656 
2657 		if (!sc->pel_seq_number) {
2658 			printf(IOCNAME "%s:%d Cannot load PEL seq number dma memory for size: %d\n", sc->name,
2659 				__func__, __LINE__, sc->pel_seq_number_sz);
2660 			retval = -ENOMEM;
2661 			goto out_failed;
2662 		}
2663 	}
2664 
2665 out_failed:
2666 	return retval;
2667 }
2668 
2669 /**
2670  * mpi3mr_validate_fw_update - validate IOCFacts post adapter reset
2671  * @sc: Adapter instance reference
2672  *
2673  * Return zero if the new IOCFacts is compatible with previous values
2674  * else return appropriate error
2675  */
2676 static int
2677 mpi3mr_validate_fw_update(struct mpi3mr_softc *sc)
2678 {
2679 	U16 dev_handle_bitmap_sz;
2680 	U8 *removepend_bitmap;
2681 
2682 	if (sc->facts.reply_sz > sc->reply_sz) {
2683 		mpi3mr_dprint(sc, MPI3MR_ERROR,
2684 		    "Cannot increase reply size from %d to %d\n",
2685 		    sc->reply_sz, sc->reply_sz);
2686 		return -EPERM;
2687 	}
2688 
2689 	if (sc->num_io_throttle_group != sc->facts.max_io_throttle_group) {
2690 		mpi3mr_dprint(sc, MPI3MR_ERROR,
2691 		    "max io throttle group doesn't match old(%d), new(%d)\n",
2692 		    sc->num_io_throttle_group,
2693 		    sc->facts.max_io_throttle_group);
2694 		return -EPERM;
2695 	}
2696 
2697 	if (sc->facts.max_op_reply_q < sc->num_queues) {
2698 		mpi3mr_dprint(sc, MPI3MR_ERROR,
2699 		    "Cannot reduce number of operational reply queues from %d to %d\n",
2700 		    sc->num_queues,
2701 		    sc->facts.max_op_reply_q);
2702 		return -EPERM;
2703 	}
2704 
2705 	if (sc->facts.max_op_req_q < sc->num_queues) {
2706 		mpi3mr_dprint(sc, MPI3MR_ERROR,
2707 		    "Cannot reduce number of operational request queues from %d to %d\n",
2708 		    sc->num_queues, sc->facts.max_op_req_q);
2709 		return -EPERM;
2710 	}
2711 
2712 	dev_handle_bitmap_sz = MPI3MR_DIV_ROUND_UP(sc->facts.max_devhandle, 8);
2713 
2714 	if (dev_handle_bitmap_sz > sc->dev_handle_bitmap_sz) {
2715 		removepend_bitmap = realloc(sc->removepend_bitmap,
2716 		    dev_handle_bitmap_sz, M_MPI3MR, M_NOWAIT);
2717 
2718 		if (!removepend_bitmap) {
2719 			mpi3mr_dprint(sc, MPI3MR_ERROR,
2720 			    "failed to increase removepend_bitmap sz from: %d to %d\n",
2721 			    sc->dev_handle_bitmap_sz, dev_handle_bitmap_sz);
2722 			return -ENOMEM;
2723 		}
2724 
2725 		memset(removepend_bitmap + sc->dev_handle_bitmap_sz, 0,
2726 		    dev_handle_bitmap_sz - sc->dev_handle_bitmap_sz);
2727 		sc->removepend_bitmap = removepend_bitmap;
2728 		mpi3mr_dprint(sc, MPI3MR_INFO,
2729 		    "increased dev_handle_bitmap_sz from %d to %d\n",
2730 		    sc->dev_handle_bitmap_sz, dev_handle_bitmap_sz);
2731 		sc->dev_handle_bitmap_sz = dev_handle_bitmap_sz;
2732 	}
2733 
2734 	return 0;
2735 }
2736 
2737 /*
2738  * mpi3mr_initialize_ioc - Controller initialization
2739  * @dev: pointer to device struct
2740  *
2741  * This function allocates the controller wide resources and brings
2742  * the controller to operational state
2743  *
2744  * Return: 0 on success and proper error codes on failure
2745  */
2746 int mpi3mr_initialize_ioc(struct mpi3mr_softc *sc, U8 init_type)
2747 {
2748 	int retval = 0;
2749 	enum mpi3mr_iocstate ioc_state;
2750 	U64 ioc_info, start_ticks = 0;
2751 	U32 ioc_status, ioc_control, i, timeout;
2752 	Mpi3IOCFactsData_t facts_data;
2753 	char str[32];
2754 	U32 size;
2755 	U8 retry = 0;
2756 
2757 	sc->cpu_count = mp_ncpus;
2758 
2759 retry_init:
2760 	ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
2761 	ioc_control = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET);
2762 	ioc_info = mpi3mr_regread64(sc, MPI3_SYSIF_IOC_INFO_LOW_OFFSET);
2763 
2764 	mpi3mr_dprint(sc, MPI3MR_INFO, "SOD ioc_status: 0x%x ioc_control: 0x%x "
2765 	    "ioc_info: 0x%lx\n", ioc_status, ioc_control, ioc_info);
2766 
2767 	/*The timeout value is in 2sec unit, changing it to seconds*/
2768 	sc->ready_timeout =
2769                 ((ioc_info & MPI3_SYSIF_IOC_INFO_LOW_TIMEOUT_MASK) >>
2770                     MPI3_SYSIF_IOC_INFO_LOW_TIMEOUT_SHIFT) * 2;
2771 
2772 	ioc_state = mpi3mr_get_iocstate(sc);
2773 	mpi3mr_dprint(sc, MPI3MR_INFO, "IOC state: %s   IOC ready timeout: %d\n",
2774 	    mpi3mr_iocstate_name(ioc_state), sc->ready_timeout);
2775 
2776 	timeout = sc->ready_timeout * 10;
2777 	do {
2778 		ioc_state = mpi3mr_get_iocstate(sc);
2779 
2780 		if (ioc_state != MRIOC_STATE_BECOMING_READY &&
2781 		    ioc_state != MRIOC_STATE_RESET_REQUESTED)
2782 			break;
2783 
2784 		DELAY(1000 * 100);
2785 	} while (--timeout);
2786 
2787 	if (ioc_state == MRIOC_STATE_READY) {
2788                 retval = mpi3mr_mur_ioc(sc, MPI3MR_RESET_FROM_BRINGUP);
2789                 if (retval) {
2790                         mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to MU reset IOC, error 0x%x\n",
2791                                 retval);
2792                 }
2793                 ioc_state = mpi3mr_get_iocstate(sc);
2794         }
2795 
2796         if (ioc_state != MRIOC_STATE_RESET) {
2797 		if (ioc_state == MRIOC_STATE_FAULT) {
2798 			mpi3mr_print_fault_info(sc);
2799 
2800 			U32 fault = mpi3mr_regread(sc, MPI3_SYSIF_FAULT_OFFSET) &
2801 						   MPI3_SYSIF_FAULT_CODE_MASK;
2802 			if (fault == MPI3_SYSIF_FAULT_CODE_INSUFFICIENT_PCI_SLOT_POWER)
2803 				mpi3mr_dprint(sc, MPI3MR_INFO,
2804 					      "controller faulted due to insufficient power, try by connecting it in a different slot\n");
2805 				goto err;
2806 
2807 			U32 host_diagnostic;
2808 			timeout = MPI3_SYSIF_DIAG_SAVE_TIMEOUT * 10;
2809 			do {
2810 				host_diagnostic = mpi3mr_regread(sc, MPI3_SYSIF_HOST_DIAG_OFFSET);
2811 				if (!(host_diagnostic & MPI3_SYSIF_HOST_DIAG_SAVE_IN_PROGRESS))
2812 					break;
2813 				DELAY(100 * 1000);
2814 			} while (--timeout);
2815 		}
2816 		mpi3mr_dprint(sc, MPI3MR_ERROR, "issuing soft reset to bring to reset state\n");
2817 		retval = mpi3mr_issue_reset(sc,
2818 		     MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET,
2819 		     MPI3MR_RESET_FROM_BRINGUP);
2820 		if (retval) {
2821 			mpi3mr_dprint(sc, MPI3MR_ERROR,
2822 			    "%s :Failed to soft reset IOC, error 0x%d\n",
2823 			    __func__, retval);
2824 			goto err_retry;
2825 		}
2826 	}
2827 
2828 	ioc_state = mpi3mr_get_iocstate(sc);
2829 
2830         if (ioc_state != MRIOC_STATE_RESET) {
2831 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot bring IOC to reset state\n");
2832 		goto err_retry;
2833         }
2834 
2835 	retval = mpi3mr_setup_admin_qpair(sc);
2836 	if (retval) {
2837 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to setup Admin queues, error 0x%x\n",
2838 		    retval);
2839 		if (retval == ENOMEM)
2840 			goto err;
2841 		goto err_retry;
2842 	}
2843 
2844 	retval = mpi3mr_bring_ioc_ready(sc, &start_ticks);
2845 	if (retval) {
2846 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to bring IOC ready, error 0x%x\n", retval);
2847 		if (retval == EAGAIN)
2848 			goto err_retry;
2849 		goto err;
2850 	}
2851 
2852 
2853 	if (init_type == MPI3MR_INIT_TYPE_INIT) {
2854 		retval = mpi3mr_alloc_interrupts(sc, 1);
2855 		if (retval) {
2856 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to allocate interrupts, error 0x%x\n",
2857 			    retval);
2858 			goto err;
2859 		}
2860 
2861 		retval = mpi3mr_setup_irqs(sc);
2862 		if (retval) {
2863 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to setup ISR, error 0x%x\n",
2864 			    retval);
2865 			goto err;
2866 		}
2867 	}
2868 
2869 	mpi3mr_enable_interrupts(sc);
2870 
2871 	if (init_type == MPI3MR_INIT_TYPE_INIT) {
2872 		mtx_init(&sc->mpi3mr_mtx, "SIM lock", NULL, MTX_DEF);
2873 		mtx_init(&sc->io_lock, "IO lock", NULL, MTX_DEF);
2874 		mtx_init(&sc->admin_req_lock, "Admin Request Queue lock", NULL, MTX_SPIN);
2875 		mtx_init(&sc->reply_free_q_lock, "Reply free Queue lock", NULL, MTX_SPIN);
2876 		mtx_init(&sc->sense_buf_q_lock, "Sense buffer Queue lock", NULL, MTX_SPIN);
2877 		mtx_init(&sc->chain_buf_lock, "Chain buffer lock", NULL, MTX_SPIN);
2878 		mtx_init(&sc->cmd_pool_lock, "Command pool lock", NULL, MTX_DEF);
2879 		mtx_init(&sc->fwevt_lock, "Firmware Event lock", NULL, MTX_DEF);
2880 		mtx_init(&sc->target_lock, "Target lock", NULL, MTX_SPIN);
2881 		mtx_init(&sc->reset_mutex, "Reset lock", NULL, MTX_DEF);
2882 
2883 		mtx_init(&sc->init_cmds.completion.lock, "Init commands lock", NULL, MTX_DEF);
2884 		sc->init_cmds.reply = NULL;
2885 		sc->init_cmds.state = MPI3MR_CMD_NOTUSED;
2886 		sc->init_cmds.dev_handle = MPI3MR_INVALID_DEV_HANDLE;
2887 		sc->init_cmds.host_tag = MPI3MR_HOSTTAG_INITCMDS;
2888 
2889 		mtx_init(&sc->cfg_cmds.completion.lock, "CFG commands lock", NULL, MTX_DEF);
2890 		sc->cfg_cmds.reply = NULL;
2891 		sc->cfg_cmds.state = MPI3MR_CMD_NOTUSED;
2892 		sc->cfg_cmds.dev_handle = MPI3MR_INVALID_DEV_HANDLE;
2893 		sc->cfg_cmds.host_tag = MPI3MR_HOSTTAG_CFGCMDS;
2894 
2895 		mtx_init(&sc->ioctl_cmds.completion.lock, "IOCTL commands lock", NULL, MTX_DEF);
2896 		sc->ioctl_cmds.reply = NULL;
2897 		sc->ioctl_cmds.state = MPI3MR_CMD_NOTUSED;
2898 		sc->ioctl_cmds.dev_handle = MPI3MR_INVALID_DEV_HANDLE;
2899 		sc->ioctl_cmds.host_tag = MPI3MR_HOSTTAG_IOCTLCMDS;
2900 
2901 		mtx_init(&sc->pel_abort_cmd.completion.lock, "PEL Abort command lock", NULL, MTX_DEF);
2902 		sc->pel_abort_cmd.reply = NULL;
2903 		sc->pel_abort_cmd.state = MPI3MR_CMD_NOTUSED;
2904 		sc->pel_abort_cmd.dev_handle = MPI3MR_INVALID_DEV_HANDLE;
2905 		sc->pel_abort_cmd.host_tag = MPI3MR_HOSTTAG_PELABORT;
2906 
2907 		mtx_init(&sc->host_tm_cmds.completion.lock, "TM commands lock", NULL, MTX_DEF);
2908 		sc->host_tm_cmds.reply = NULL;
2909 		sc->host_tm_cmds.state = MPI3MR_CMD_NOTUSED;
2910 		sc->host_tm_cmds.dev_handle = MPI3MR_INVALID_DEV_HANDLE;
2911 		sc->host_tm_cmds.host_tag = MPI3MR_HOSTTAG_TMS;
2912 
2913 		TAILQ_INIT(&sc->cmd_list_head);
2914 		TAILQ_INIT(&sc->event_list);
2915 		TAILQ_INIT(&sc->delayed_rmhs_list);
2916 		TAILQ_INIT(&sc->delayed_evtack_cmds_list);
2917 
2918 		for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) {
2919 			snprintf(str, 32, "Dev REMHS commands lock[%d]", i);
2920 			mtx_init(&sc->dev_rmhs_cmds[i].completion.lock, str, NULL, MTX_DEF);
2921 			sc->dev_rmhs_cmds[i].reply = NULL;
2922 			sc->dev_rmhs_cmds[i].state = MPI3MR_CMD_NOTUSED;
2923 			sc->dev_rmhs_cmds[i].dev_handle = MPI3MR_INVALID_DEV_HANDLE;
2924 			sc->dev_rmhs_cmds[i].host_tag = MPI3MR_HOSTTAG_DEVRMCMD_MIN
2925 							    + i;
2926 		}
2927 	}
2928 
2929 	retval = mpi3mr_issue_iocfacts(sc, &facts_data);
2930 	if (retval) {
2931 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to Issue IOC Facts, error: 0x%x\n",
2932 		    retval);
2933 		if (retval == ENOMEM)
2934 			goto err;
2935 		goto err_retry;
2936 	}
2937 
2938 	retval = mpi3mr_process_factsdata(sc, &facts_data);
2939 	if (retval) {
2940 		mpi3mr_dprint(sc, MPI3MR_ERROR, "IOC Facts data processing failed, error: 0x%x\n",
2941 		    retval);
2942 		goto err_retry;
2943 	}
2944 
2945 	sc->num_io_throttle_group = sc->facts.max_io_throttle_group;
2946 	mpi3mr_atomic_set(&sc->pend_large_data_sz, 0);
2947 
2948 	if (init_type == MPI3MR_INIT_TYPE_RESET) {
2949 		retval = mpi3mr_validate_fw_update(sc);
2950 		if (retval) {
2951 			if (retval == ENOMEM)
2952 				goto err;
2953 			goto err_retry;
2954 		}
2955 	} else {
2956 		sc->reply_sz = sc->facts.reply_sz;
2957 	}
2958 
2959 	mpi3mr_display_ioc_info(sc);
2960 
2961 	retval = mpi3mr_reply_alloc(sc);
2962 	if (retval) {
2963 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to allocated reply and sense buffers, error: 0x%x\n",
2964 		    retval);
2965 		goto err;
2966 	}
2967 
2968 	if (init_type == MPI3MR_INIT_TYPE_INIT) {
2969 		retval = mpi3mr_alloc_chain_bufs(sc);
2970 		if (retval) {
2971 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to allocated chain buffers, error: 0x%x\n",
2972 				      retval);
2973 			goto err;
2974 		}
2975 	}
2976 
2977 	retval = mpi3mr_issue_iocinit(sc);
2978 	if (retval) {
2979 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to Issue IOC Init, error: 0x%x\n",
2980 			      retval);
2981 		if (retval == ENOMEM)
2982 			goto err;
2983 		goto err_retry;
2984 	}
2985 
2986 	mpi3mr_print_fw_pkg_ver(sc);
2987 
2988 	sc->reply_free_q_host_index = sc->num_reply_bufs;
2989 	mpi3mr_regwrite(sc, MPI3_SYSIF_REPLY_FREE_HOST_INDEX_OFFSET,
2990 		sc->reply_free_q_host_index);
2991 
2992 	sc->sense_buf_q_host_index = sc->num_sense_bufs;
2993 
2994 	mpi3mr_regwrite(sc, MPI3_SYSIF_SENSE_BUF_FREE_HOST_INDEX_OFFSET,
2995 		sc->sense_buf_q_host_index);
2996 
2997 	if (init_type == MPI3MR_INIT_TYPE_INIT) {
2998 		retval = mpi3mr_alloc_interrupts(sc, 0);
2999 		if (retval) {
3000 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to allocate interrupts, error: 0x%x\n",
3001 			    retval);
3002 			goto err;
3003 		}
3004 
3005 		retval = mpi3mr_setup_irqs(sc);
3006 		if (retval) {
3007 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to setup ISR, error: 0x%x\n", retval);
3008 			goto err;
3009 		}
3010 
3011 		mpi3mr_enable_interrupts(sc);
3012 
3013 	} else
3014 		mpi3mr_enable_interrupts(sc);
3015 
3016 	retval = mpi3mr_create_op_queues(sc);
3017 	if (retval) {
3018 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to create operational queues, error: %d\n",
3019 		    retval);
3020 		if (retval == ENOMEM)
3021 			goto err;
3022 		goto err_retry;
3023 	}
3024 
3025 	if (!sc->throttle_groups && sc->num_io_throttle_group) {
3026 		size = sizeof(struct mpi3mr_throttle_group_info);
3027 		sc->throttle_groups = (struct mpi3mr_throttle_group_info *)
3028 					  malloc(sc->num_io_throttle_group *
3029 					      size, M_MPI3MR, M_NOWAIT | M_ZERO);
3030 		if (!sc->throttle_groups) {
3031 			mpi3mr_dprint(sc, MPI3MR_ERROR, "throttle groups memory allocation failed\n");
3032 			goto err;
3033 		}
3034 	}
3035 
3036 	if (init_type == MPI3MR_INIT_TYPE_RESET) {
3037 		mpi3mr_dprint(sc, MPI3MR_XINFO, "Re-register events\n");
3038 		retval = mpi3mr_register_events(sc);
3039 		if (retval) {
3040 			mpi3mr_dprint(sc, MPI3MR_INFO, "Failed to re-register events, error: 0x%x\n",
3041 			    retval);
3042 			goto err_retry;
3043 		}
3044 
3045 		mpi3mr_dprint(sc, MPI3MR_INFO, "Issuing Port Enable\n");
3046 		retval = mpi3mr_issue_port_enable(sc, 0);
3047 		if (retval) {
3048 			mpi3mr_dprint(sc, MPI3MR_INFO, "Failed to issue port enable, error: 0x%x\n",
3049 			    retval);
3050 			goto err_retry;
3051 		}
3052 	}
3053 	retval = mpi3mr_pel_alloc(sc);
3054 	if (retval) {
3055 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to allocate memory for PEL, error: 0x%x\n",
3056 		    retval);
3057 		goto err;
3058 	}
3059 
3060 	if (mpi3mr_cfg_get_driver_pg1(sc) != 0)
3061 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to get the cfg driver page1\n");
3062 
3063 	return retval;
3064 
3065 err_retry:
3066 	if ((retry++ < 2) && (((ticks - start_ticks) / hz) < (sc->ready_timeout - 60))) {
3067 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Retrying controller initialization,"
3068 			      "retry_count: %d\n", retry);
3069 		goto retry_init;
3070 	}
3071 err:
3072 	retval = -1;
3073 	return retval;
3074 }
3075 
3076 static void mpi3mr_port_enable_complete(struct mpi3mr_softc *sc,
3077     struct mpi3mr_drvr_cmd *drvrcmd)
3078 {
3079 	drvrcmd->state = MPI3MR_CMD_NOTUSED;
3080 	drvrcmd->callback = NULL;
3081 	printf(IOCNAME "Completing Port Enable Request\n", sc->name);
3082 	sc->mpi3mr_flags |= MPI3MR_FLAGS_PORT_ENABLE_DONE;
3083 	mpi3mr_startup_decrement(sc->cam_sc);
3084 }
3085 
3086 int mpi3mr_issue_port_enable(struct mpi3mr_softc *sc, U8 async)
3087 {
3088 	Mpi3PortEnableRequest_t pe_req;
3089 	int retval = 0;
3090 
3091 	memset(&pe_req, 0, sizeof(pe_req));
3092 	mtx_lock(&sc->init_cmds.completion.lock);
3093 	if (sc->init_cmds.state & MPI3MR_CMD_PENDING) {
3094 		retval = -1;
3095 		printf(IOCNAME "Issue PortEnable: Init command is in use\n", sc->name);
3096 		mtx_unlock(&sc->init_cmds.completion.lock);
3097 		goto out;
3098 	}
3099 
3100 	sc->init_cmds.state = MPI3MR_CMD_PENDING;
3101 
3102 	if (async) {
3103 		sc->init_cmds.is_waiting = 0;
3104 		sc->init_cmds.callback = mpi3mr_port_enable_complete;
3105 	} else {
3106 		sc->init_cmds.is_waiting = 1;
3107 		sc->init_cmds.callback = NULL;
3108 		init_completion(&sc->init_cmds.completion);
3109 	}
3110 	pe_req.HostTag = MPI3MR_HOSTTAG_INITCMDS;
3111 	pe_req.Function = MPI3_FUNCTION_PORT_ENABLE;
3112 
3113 	printf(IOCNAME "Sending Port Enable Request\n", sc->name);
3114 	retval = mpi3mr_submit_admin_cmd(sc, &pe_req, sizeof(pe_req));
3115 	if (retval) {
3116 		printf(IOCNAME "Issue PortEnable: Admin Post failed\n",
3117 		    sc->name);
3118 		goto out_unlock;
3119 	}
3120 
3121 	if (!async) {
3122 		wait_for_completion_timeout(&sc->init_cmds.completion,
3123 		    MPI3MR_PORTENABLE_TIMEOUT);
3124 		if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) {
3125 			printf(IOCNAME "Issue PortEnable: command timed out\n",
3126 			    sc->name);
3127 			retval = -1;
3128 			mpi3mr_check_rh_fault_ioc(sc, MPI3MR_RESET_FROM_PE_TIMEOUT);
3129 			goto out_unlock;
3130 		}
3131 		mpi3mr_port_enable_complete(sc, &sc->init_cmds);
3132 	}
3133 out_unlock:
3134 	mtx_unlock(&sc->init_cmds.completion.lock);
3135 
3136 out:
3137 	return retval;
3138 }
3139 
3140 static int mpi3mr_timestamp_sync(struct mpi3mr_softc *sc)
3141 {
3142 	int retval = 0;
3143 	struct timeval current_time;
3144 	int64_t time_in_msec;
3145 	Mpi3IoUnitControlRequest_t iou_ctrl = {0};
3146 
3147 	mtx_lock(&sc->init_cmds.completion.lock);
3148 	if (sc->init_cmds.state & MPI3MR_CMD_PENDING) {
3149 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Issue timestamp sync: command is in use\n");
3150 		mtx_unlock(&sc->init_cmds.completion.lock);
3151 		return -1;
3152 	}
3153 
3154 	sc->init_cmds.state = MPI3MR_CMD_PENDING;
3155 	sc->init_cmds.is_waiting = 1;
3156 	sc->init_cmds.callback = NULL;
3157 	iou_ctrl.HostTag = htole64(MPI3MR_HOSTTAG_INITCMDS);
3158 	iou_ctrl.Function = MPI3_FUNCTION_IO_UNIT_CONTROL;
3159 	iou_ctrl.Operation = MPI3_CTRL_OP_UPDATE_TIMESTAMP;
3160 	getmicrotime(&current_time);
3161 	time_in_msec = (int64_t)current_time.tv_sec * 1000 + current_time.tv_usec/1000;
3162 	iou_ctrl.Param64[0] = htole64(time_in_msec);
3163 
3164 	init_completion(&sc->init_cmds.completion);
3165 
3166 	retval = mpi3mr_submit_admin_cmd(sc, &iou_ctrl, sizeof(iou_ctrl));
3167 	if (retval) {
3168 		mpi3mr_dprint(sc, MPI3MR_ERROR, "timestamp sync: Admin Post failed\n");
3169 		goto out_unlock;
3170 	}
3171 
3172 	wait_for_completion_timeout(&sc->init_cmds.completion,
3173 				    (MPI3MR_INTADMCMD_TIMEOUT));
3174 
3175 	if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) {
3176 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Issue timestamp sync: command timed out\n");
3177 		sc->init_cmds.is_waiting = 0;
3178 
3179 		if (!(sc->init_cmds.state & MPI3MR_CMD_RESET))
3180 			mpi3mr_check_rh_fault_ioc(sc, MPI3MR_RESET_FROM_TSU_TIMEOUT);
3181 
3182 		retval = -1;
3183 		goto out_unlock;
3184 	}
3185 
3186 	if (((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK) != MPI3_IOCSTATUS_SUCCESS) &&
3187 	     (sc->init_cmds.ioc_status != MPI3_IOCSTATUS_SUPERVISOR_ONLY)) {
3188 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Issue timestamp sync: Failed IOCStatus(0x%04x) Loginfo(0x%08x)\n",
3189 			      (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK), sc->init_cmds.ioc_loginfo);
3190 		retval = -1;
3191 	}
3192 
3193 out_unlock:
3194 	sc->init_cmds.state = MPI3MR_CMD_NOTUSED;
3195 	mtx_unlock(&sc->init_cmds.completion.lock);
3196 
3197 	return retval;
3198 }
3199 
3200 void
3201 mpi3mr_timestamp_thread(void *arg)
3202 {
3203 	struct mpi3mr_softc *sc = (struct mpi3mr_softc *)arg;
3204 	U64 elapsed_time = 0;
3205 
3206 	sc->timestamp_thread_active = 1;
3207 	mtx_lock(&sc->reset_mutex);
3208 	while (1) {
3209 
3210 		if (sc->mpi3mr_flags & MPI3MR_FLAGS_SHUTDOWN ||
3211 		    (sc->unrecoverable == 1)) {
3212 			mpi3mr_dprint(sc, MPI3MR_INFO,
3213 				      "Exit due to %s from %s\n",
3214 				      sc->mpi3mr_flags & MPI3MR_FLAGS_SHUTDOWN ? "Shutdown" :
3215 				      "Hardware critical error", __func__);
3216 			break;
3217 		}
3218 		mtx_unlock(&sc->reset_mutex);
3219 
3220 		while (sc->reset_in_progress) {
3221 			if (elapsed_time)
3222 				elapsed_time = 0;
3223 			if (sc->unrecoverable)
3224 				break;
3225 			pause("mpi3mr_timestamp_thread", hz / 5);
3226 		}
3227 
3228 		if (elapsed_time++ >= sc->ts_update_interval * 60) {
3229 			mpi3mr_timestamp_sync(sc);
3230 			elapsed_time = 0;
3231 		}
3232 
3233 		/*
3234 		 * Sleep for 1 second if we're not exiting, then loop to top
3235 		 * to poll exit status and hardware health.
3236 		 */
3237 		mtx_lock(&sc->reset_mutex);
3238 		if (((sc->mpi3mr_flags & MPI3MR_FLAGS_SHUTDOWN) == 0) &&
3239 		    (!sc->unrecoverable) && (!sc->reset_in_progress)) {
3240 			msleep(&sc->timestamp_chan, &sc->reset_mutex, PRIBIO,
3241 			       "mpi3mr_timestamp", 1 * hz);
3242 		}
3243 	}
3244 	mtx_unlock(&sc->reset_mutex);
3245 	sc->timestamp_thread_active = 0;
3246 	kproc_exit(0);
3247 }
3248 
3249 void
3250 mpi3mr_watchdog_thread(void *arg)
3251 {
3252 	struct mpi3mr_softc *sc;
3253 	enum mpi3mr_iocstate ioc_state;
3254 	U32 fault, host_diagnostic, ioc_status;
3255 
3256 	sc = (struct mpi3mr_softc *)arg;
3257 
3258 	mpi3mr_dprint(sc, MPI3MR_XINFO, "%s\n", __func__);
3259 
3260 	sc->watchdog_thread_active = 1;
3261 	mtx_lock(&sc->reset_mutex);
3262 	for (;;) {
3263 		if (sc->mpi3mr_flags & MPI3MR_FLAGS_SHUTDOWN ||
3264 		    (sc->unrecoverable == 1)) {
3265 			mpi3mr_dprint(sc, MPI3MR_INFO,
3266 			    "Exit due to %s from %s\n",
3267 			   sc->mpi3mr_flags & MPI3MR_FLAGS_SHUTDOWN ? "Shutdown" :
3268 			    "Hardware critical error", __func__);
3269 			break;
3270 		}
3271 		mtx_unlock(&sc->reset_mutex);
3272 
3273 		if ((sc->prepare_for_reset) &&
3274 		    ((sc->prepare_for_reset_timeout_counter++) >=
3275 		     MPI3MR_PREPARE_FOR_RESET_TIMEOUT)) {
3276 			mpi3mr_soft_reset_handler(sc,
3277 			    MPI3MR_RESET_FROM_CIACTVRST_TIMER, 1);
3278 			goto sleep;
3279 		}
3280 
3281 		ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
3282 
3283 		if (ioc_status & MPI3_SYSIF_IOC_STATUS_RESET_HISTORY) {
3284 			mpi3mr_soft_reset_handler(sc, MPI3MR_RESET_FROM_FIRMWARE, 0);
3285 			goto sleep;
3286 		}
3287 
3288 		ioc_state = mpi3mr_get_iocstate(sc);
3289 		if (ioc_state == MRIOC_STATE_FAULT) {
3290 			fault = mpi3mr_regread(sc, MPI3_SYSIF_FAULT_OFFSET) &
3291 			    MPI3_SYSIF_FAULT_CODE_MASK;
3292 
3293 			host_diagnostic = mpi3mr_regread(sc, MPI3_SYSIF_HOST_DIAG_OFFSET);
3294 			if (host_diagnostic & MPI3_SYSIF_HOST_DIAG_SAVE_IN_PROGRESS) {
3295 				if (!sc->diagsave_timeout) {
3296 					mpi3mr_print_fault_info(sc);
3297 					mpi3mr_dprint(sc, MPI3MR_INFO,
3298 						"diag save in progress\n");
3299 				}
3300 				if ((sc->diagsave_timeout++) <= MPI3_SYSIF_DIAG_SAVE_TIMEOUT)
3301 					goto sleep;
3302 			}
3303 			mpi3mr_print_fault_info(sc);
3304 			sc->diagsave_timeout = 0;
3305 
3306 			if ((fault == MPI3_SYSIF_FAULT_CODE_POWER_CYCLE_REQUIRED) ||
3307 			    (fault == MPI3_SYSIF_FAULT_CODE_COMPLETE_RESET_NEEDED)) {
3308 				mpi3mr_dprint(sc, MPI3MR_INFO,
3309 				    "Controller requires system power cycle or complete reset is needed,"
3310 				    "fault code: 0x%x. marking controller as unrecoverable\n", fault);
3311 				sc->unrecoverable = 1;
3312 				break;
3313 			}
3314 
3315 			if (fault == MPI3_SYSIF_FAULT_CODE_INSUFFICIENT_PCI_SLOT_POWER) {
3316 				mpi3mr_dprint(sc, MPI3MR_INFO,
3317 					      "controller faulted due to insufficient power, marking controller as unrecoverable\n");
3318 				sc->unrecoverable = 1;
3319 				break;
3320 			}
3321 
3322 			if ((fault == MPI3_SYSIF_FAULT_CODE_DIAG_FAULT_RESET)
3323 			    || (fault == MPI3_SYSIF_FAULT_CODE_SOFT_RESET_IN_PROGRESS)
3324 			    || (sc->reset_in_progress))
3325 				break;
3326 			if (fault == MPI3_SYSIF_FAULT_CODE_CI_ACTIVATION_RESET)
3327 				mpi3mr_soft_reset_handler(sc,
3328 				    MPI3MR_RESET_FROM_CIACTIV_FAULT, 0);
3329 			else
3330 				mpi3mr_soft_reset_handler(sc,
3331 				    MPI3MR_RESET_FROM_FAULT_WATCH, 0);
3332 
3333 		}
3334 
3335 		if (sc->reset.type == MPI3MR_TRIGGER_SOFT_RESET) {
3336 			mpi3mr_print_fault_info(sc);
3337 			mpi3mr_soft_reset_handler(sc, sc->reset.reason, 1);
3338 		}
3339 sleep:
3340 		mtx_lock(&sc->reset_mutex);
3341 		/*
3342 		 * Sleep for 1 second if we're not exiting, then loop to top
3343 		 * to poll exit status and hardware health.
3344 		 */
3345 		if ((sc->mpi3mr_flags & MPI3MR_FLAGS_SHUTDOWN) == 0 &&
3346 		    !sc->unrecoverable) {
3347 			msleep(&sc->watchdog_chan, &sc->reset_mutex, PRIBIO,
3348 			    "mpi3mr_watchdog", 1 * hz);
3349 		}
3350 	}
3351 	mtx_unlock(&sc->reset_mutex);
3352 	sc->watchdog_thread_active = 0;
3353 	mpi3mr_kproc_exit(0);
3354 }
3355 
3356 static void mpi3mr_display_event_data(struct mpi3mr_softc *sc,
3357 	Mpi3EventNotificationReply_t *event_rep)
3358 {
3359 	char *desc = NULL;
3360 	U16 event;
3361 
3362 	event = event_rep->Event;
3363 
3364 	switch (event) {
3365 	case MPI3_EVENT_LOG_DATA:
3366 		desc = "Log Data";
3367 		break;
3368 	case MPI3_EVENT_CHANGE:
3369 		desc = "Event Change";
3370 		break;
3371 	case MPI3_EVENT_GPIO_INTERRUPT:
3372 		desc = "GPIO Interrupt";
3373 		break;
3374 	case MPI3_EVENT_CABLE_MGMT:
3375 		desc = "Cable Management";
3376 		break;
3377 	case MPI3_EVENT_ENERGY_PACK_CHANGE:
3378 		desc = "Energy Pack Change";
3379 		break;
3380 	case MPI3_EVENT_DEVICE_ADDED:
3381 	{
3382 		Mpi3DevicePage0_t *event_data =
3383 		    (Mpi3DevicePage0_t *)event_rep->EventData;
3384 		mpi3mr_dprint(sc, MPI3MR_EVENT, "Device Added: Dev=0x%04x Form=0x%x Perst id: 0x%x\n",
3385 			event_data->DevHandle, event_data->DeviceForm, event_data->PersistentID);
3386 		return;
3387 	}
3388 	case MPI3_EVENT_DEVICE_INFO_CHANGED:
3389 	{
3390 		Mpi3DevicePage0_t *event_data =
3391 		    (Mpi3DevicePage0_t *)event_rep->EventData;
3392 		mpi3mr_dprint(sc, MPI3MR_EVENT, "Device Info Changed: Dev=0x%04x Form=0x%x\n",
3393 			event_data->DevHandle, event_data->DeviceForm);
3394 		return;
3395 	}
3396 	case MPI3_EVENT_DEVICE_STATUS_CHANGE:
3397 	{
3398 		Mpi3EventDataDeviceStatusChange_t *event_data =
3399 		    (Mpi3EventDataDeviceStatusChange_t *)event_rep->EventData;
3400 		mpi3mr_dprint(sc, MPI3MR_EVENT, "Device Status Change: Dev=0x%04x RC=0x%x\n",
3401 			event_data->DevHandle, event_data->ReasonCode);
3402 		return;
3403 	}
3404 	case MPI3_EVENT_SAS_DISCOVERY:
3405 	{
3406 		Mpi3EventDataSasDiscovery_t *event_data =
3407 		    (Mpi3EventDataSasDiscovery_t *)event_rep->EventData;
3408 		mpi3mr_dprint(sc, MPI3MR_EVENT, "SAS Discovery: (%s)",
3409 			(event_data->ReasonCode == MPI3_EVENT_SAS_DISC_RC_STARTED) ?
3410 		    "start" : "stop");
3411 		if (event_data->DiscoveryStatus &&
3412 		    (sc->mpi3mr_debug & MPI3MR_EVENT)) {
3413 			printf("discovery_status(0x%08x)",
3414 			    event_data->DiscoveryStatus);
3415 
3416 		}
3417 
3418 		if (sc->mpi3mr_debug & MPI3MR_EVENT)
3419 			printf("\n");
3420 		return;
3421 	}
3422 	case MPI3_EVENT_SAS_BROADCAST_PRIMITIVE:
3423 		desc = "SAS Broadcast Primitive";
3424 		break;
3425 	case MPI3_EVENT_SAS_NOTIFY_PRIMITIVE:
3426 		desc = "SAS Notify Primitive";
3427 		break;
3428 	case MPI3_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
3429 		desc = "SAS Init Device Status Change";
3430 		break;
3431 	case MPI3_EVENT_SAS_INIT_TABLE_OVERFLOW:
3432 		desc = "SAS Init Table Overflow";
3433 		break;
3434 	case MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
3435 		desc = "SAS Topology Change List";
3436 		break;
3437 	case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE:
3438 		desc = "Enclosure Device Status Change";
3439 		break;
3440 	case MPI3_EVENT_HARD_RESET_RECEIVED:
3441 		desc = "Hard Reset Received";
3442 		break;
3443 	case MPI3_EVENT_SAS_PHY_COUNTER:
3444 		desc = "SAS PHY Counter";
3445 		break;
3446 	case MPI3_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
3447 		desc = "SAS Device Discovery Error";
3448 		break;
3449 	case MPI3_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:
3450 		desc = "PCIE Topology Change List";
3451 		break;
3452 	case MPI3_EVENT_PCIE_ENUMERATION:
3453 	{
3454 		Mpi3EventDataPcieEnumeration_t *event_data =
3455 			(Mpi3EventDataPcieEnumeration_t *)event_rep->EventData;
3456 		mpi3mr_dprint(sc, MPI3MR_EVENT, "PCIE Enumeration: (%s)",
3457 			(event_data->ReasonCode ==
3458 			    MPI3_EVENT_PCIE_ENUM_RC_STARTED) ? "start" :
3459 			    "stop");
3460 		if (event_data->EnumerationStatus)
3461 			mpi3mr_dprint(sc, MPI3MR_EVENT, "enumeration_status(0x%08x)",
3462 			   event_data->EnumerationStatus);
3463 		if (sc->mpi3mr_debug & MPI3MR_EVENT)
3464 			printf("\n");
3465 		return;
3466 	}
3467 	case MPI3_EVENT_PREPARE_FOR_RESET:
3468 		desc = "Prepare For Reset";
3469 		break;
3470 	}
3471 
3472 	if (!desc)
3473 		return;
3474 
3475 	mpi3mr_dprint(sc, MPI3MR_EVENT, "%s\n", desc);
3476 }
3477 
3478 struct mpi3mr_target *
3479 mpi3mr_find_target_by_per_id(struct mpi3mr_cam_softc *cam_sc,
3480     uint16_t per_id)
3481 {
3482 	struct mpi3mr_target *target = NULL;
3483 
3484 	mtx_lock_spin(&cam_sc->sc->target_lock);
3485 	TAILQ_FOREACH(target, &cam_sc->tgt_list, tgt_next) {
3486 		if (target->per_id == per_id)
3487 			break;
3488 	}
3489 
3490 	mtx_unlock_spin(&cam_sc->sc->target_lock);
3491 	return target;
3492 }
3493 
3494 struct mpi3mr_target *
3495 mpi3mr_find_target_by_dev_handle(struct mpi3mr_cam_softc *cam_sc,
3496     uint16_t handle)
3497 {
3498 	struct mpi3mr_target *target = NULL;
3499 
3500 	mtx_lock_spin(&cam_sc->sc->target_lock);
3501 	TAILQ_FOREACH(target, &cam_sc->tgt_list, tgt_next) {
3502 		if (target->dev_handle == handle)
3503 			break;
3504 
3505 	}
3506 	mtx_unlock_spin(&cam_sc->sc->target_lock);
3507 	return target;
3508 }
3509 
3510 void mpi3mr_update_device(struct mpi3mr_softc *sc,
3511     struct mpi3mr_target *tgtdev, Mpi3DevicePage0_t *dev_pg0,
3512     bool is_added)
3513 {
3514 	U16 flags = 0;
3515 
3516 	tgtdev->per_id = (dev_pg0->PersistentID);
3517 	tgtdev->dev_handle = (dev_pg0->DevHandle);
3518 	tgtdev->dev_type = dev_pg0->DeviceForm;
3519 	tgtdev->encl_handle = (dev_pg0->EnclosureHandle);
3520 	tgtdev->parent_handle = (dev_pg0->ParentDevHandle);
3521 	tgtdev->slot = (dev_pg0->Slot);
3522 	tgtdev->qdepth = (dev_pg0->QueueDepth);
3523 	tgtdev->wwid = (dev_pg0->WWID);
3524 
3525 	flags = (dev_pg0->Flags);
3526 	tgtdev->is_hidden = (flags & MPI3_DEVICE0_FLAGS_HIDDEN);
3527 	if (is_added == true)
3528 		tgtdev->io_throttle_enabled =
3529 		    (flags & MPI3_DEVICE0_FLAGS_IO_THROTTLING_REQUIRED) ? 1 : 0;
3530 
3531 	switch (dev_pg0->AccessStatus) {
3532 	case MPI3_DEVICE0_ASTATUS_NO_ERRORS:
3533 	case MPI3_DEVICE0_ASTATUS_PREPARE:
3534 	case MPI3_DEVICE0_ASTATUS_NEEDS_INITIALIZATION:
3535 	case MPI3_DEVICE0_ASTATUS_DEVICE_MISSING_DELAY:
3536 		break;
3537 	default:
3538 		tgtdev->is_hidden = 1;
3539 		break;
3540 	}
3541 
3542 	switch (flags & MPI3_DEVICE0_FLAGS_MAX_WRITE_SAME_MASK) {
3543 	case MPI3_DEVICE0_FLAGS_MAX_WRITE_SAME_256_LB:
3544 		tgtdev->ws_len = 256;
3545 		break;
3546 	case MPI3_DEVICE0_FLAGS_MAX_WRITE_SAME_2048_LB:
3547 		tgtdev->ws_len = 2048;
3548 		break;
3549 	case MPI3_DEVICE0_FLAGS_MAX_WRITE_SAME_NO_LIMIT:
3550 	default:
3551 		tgtdev->ws_len = 0;
3552 		break;
3553 	}
3554 
3555 	switch (tgtdev->dev_type) {
3556 	case MPI3_DEVICE_DEVFORM_SAS_SATA:
3557 	{
3558 		Mpi3Device0SasSataFormat_t *sasinf =
3559 		    &dev_pg0->DeviceSpecific.SasSataFormat;
3560 		U16 dev_info = (sasinf->DeviceInfo);
3561 		tgtdev->dev_spec.sassata_inf.dev_info = dev_info;
3562 		tgtdev->dev_spec.sassata_inf.sas_address =
3563 		    (sasinf->SASAddress);
3564 		if ((dev_info & MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_MASK) !=
3565 		    MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_END_DEVICE)
3566 			tgtdev->is_hidden = 1;
3567 		else if (!(dev_info & (MPI3_SAS_DEVICE_INFO_STP_SATA_TARGET |
3568 			    MPI3_SAS_DEVICE_INFO_SSP_TARGET)))
3569 			tgtdev->is_hidden = 1;
3570 		break;
3571 	}
3572 	case MPI3_DEVICE_DEVFORM_PCIE:
3573 	{
3574 		Mpi3Device0PcieFormat_t *pcieinf =
3575 		    &dev_pg0->DeviceSpecific.PcieFormat;
3576 		U16 dev_info = (pcieinf->DeviceInfo);
3577 
3578 		tgtdev->q_depth = dev_pg0->QueueDepth;
3579 		tgtdev->dev_spec.pcie_inf.dev_info = dev_info;
3580 		tgtdev->dev_spec.pcie_inf.capb =
3581 		    (pcieinf->Capabilities);
3582 		tgtdev->dev_spec.pcie_inf.mdts = MPI3MR_DEFAULT_MDTS;
3583 		if (dev_pg0->AccessStatus == MPI3_DEVICE0_ASTATUS_NO_ERRORS) {
3584 			tgtdev->dev_spec.pcie_inf.mdts =
3585 			    (pcieinf->MaximumDataTransferSize);
3586 			tgtdev->dev_spec.pcie_inf.pgsz = pcieinf->PageSize;
3587 			tgtdev->dev_spec.pcie_inf.reset_to =
3588 				pcieinf->ControllerResetTO;
3589 			tgtdev->dev_spec.pcie_inf.abort_to =
3590 				pcieinf->NVMeAbortTO;
3591 		}
3592 		if (tgtdev->dev_spec.pcie_inf.mdts > (1024 * 1024))
3593 			tgtdev->dev_spec.pcie_inf.mdts = (1024 * 1024);
3594 
3595 		if (((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) !=
3596 		    MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_NVME_DEVICE) &&
3597 		    ((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) !=
3598 		    MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_SCSI_DEVICE))
3599 			tgtdev->is_hidden = 1;
3600 
3601 		break;
3602 	}
3603 	case MPI3_DEVICE_DEVFORM_VD:
3604 	{
3605 		Mpi3Device0VdFormat_t *vdinf =
3606 		    &dev_pg0->DeviceSpecific.VdFormat;
3607 		struct mpi3mr_throttle_group_info *tg = NULL;
3608 
3609 		tgtdev->dev_spec.vol_inf.state = vdinf->VdState;
3610 		if (vdinf->VdState == MPI3_DEVICE0_VD_STATE_OFFLINE)
3611 			tgtdev->is_hidden = 1;
3612 		tgtdev->dev_spec.vol_inf.tg_id = vdinf->IOThrottleGroup;
3613 		tgtdev->dev_spec.vol_inf.tg_high =
3614 			vdinf->IOThrottleGroupHigh * 2048;
3615 		tgtdev->dev_spec.vol_inf.tg_low =
3616 			vdinf->IOThrottleGroupLow * 2048;
3617 		if (vdinf->IOThrottleGroup < sc->num_io_throttle_group) {
3618 			tg = sc->throttle_groups + vdinf->IOThrottleGroup;
3619 			tg->id = vdinf->IOThrottleGroup;
3620 			tg->high = tgtdev->dev_spec.vol_inf.tg_high;
3621 			tg->low = tgtdev->dev_spec.vol_inf.tg_low;
3622 			if (is_added == true)
3623 				tg->fw_qd = tgtdev->q_depth;
3624 			tg->modified_qd = tgtdev->q_depth;
3625 		}
3626 		tgtdev->dev_spec.vol_inf.tg = tg;
3627 		tgtdev->throttle_group = tg;
3628 		break;
3629 	}
3630 	default:
3631 		goto out;
3632 	}
3633 
3634 out:
3635 	return;
3636 }
3637 
3638 int mpi3mr_create_device(struct mpi3mr_softc *sc,
3639     Mpi3DevicePage0_t *dev_pg0)
3640 {
3641 	int retval = 0;
3642 	struct mpi3mr_target *target = NULL;
3643 	U16 per_id = 0;
3644 
3645 	per_id = dev_pg0->PersistentID;
3646 
3647 	mtx_lock_spin(&sc->target_lock);
3648 	TAILQ_FOREACH(target, &sc->cam_sc->tgt_list, tgt_next) {
3649 		if (target->per_id == per_id) {
3650 			target->state = MPI3MR_DEV_CREATED;
3651 			break;
3652 		}
3653 	}
3654 	mtx_unlock_spin(&sc->target_lock);
3655 
3656 	if (target) {
3657 			mpi3mr_update_device(sc, target, dev_pg0, true);
3658 	} else {
3659 			target = malloc(sizeof(*target), M_MPI3MR,
3660 				 M_NOWAIT | M_ZERO);
3661 
3662 			if (target == NULL) {
3663 				retval = -1;
3664 				goto out;
3665 			}
3666 
3667 			target->exposed_to_os = 0;
3668 			mpi3mr_update_device(sc, target, dev_pg0, true);
3669 			mtx_lock_spin(&sc->target_lock);
3670 			TAILQ_INSERT_TAIL(&sc->cam_sc->tgt_list, target, tgt_next);
3671 			target->state = MPI3MR_DEV_CREATED;
3672 			mtx_unlock_spin(&sc->target_lock);
3673 	}
3674 out:
3675 	return retval;
3676 }
3677 
3678 /**
3679  * mpi3mr_dev_rmhs_complete_iou - Device removal IOUC completion
3680  * @sc: Adapter instance reference
3681  * @drv_cmd: Internal command tracker
3682  *
3683  * Issues a target reset TM to the firmware from the device
3684  * removal TM pend list or retry the removal handshake sequence
3685  * based on the IOU control request IOC status.
3686  *
3687  * Return: Nothing
3688  */
3689 static void mpi3mr_dev_rmhs_complete_iou(struct mpi3mr_softc *sc,
3690 	struct mpi3mr_drvr_cmd *drv_cmd)
3691 {
3692 	U16 cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_DEVRMCMD_MIN;
3693 	struct delayed_dev_rmhs_node *delayed_dev_rmhs = NULL;
3694 	struct mpi3mr_target *tgtdev = NULL;
3695 
3696 	mpi3mr_dprint(sc, MPI3MR_EVENT,
3697 	    "%s :dev_rmhs_iouctrl_complete:handle(0x%04x), ioc_status(0x%04x), loginfo(0x%08x)\n",
3698 	    __func__, drv_cmd->dev_handle, drv_cmd->ioc_status,
3699 	    drv_cmd->ioc_loginfo);
3700 	if (drv_cmd->ioc_status != MPI3_IOCSTATUS_SUCCESS) {
3701 		if (drv_cmd->retry_count < MPI3MR_DEVRMHS_RETRYCOUNT) {
3702 			drv_cmd->retry_count++;
3703 			mpi3mr_dprint(sc, MPI3MR_EVENT,
3704 			    "%s :dev_rmhs_iouctrl_complete: handle(0x%04x)retrying handshake retry=%d\n",
3705 			    __func__, drv_cmd->dev_handle,
3706 			    drv_cmd->retry_count);
3707 			mpi3mr_dev_rmhs_send_tm(sc, drv_cmd->dev_handle,
3708 			    drv_cmd, drv_cmd->iou_rc);
3709 			return;
3710 		}
3711 		mpi3mr_dprint(sc, MPI3MR_ERROR,
3712 		    "%s :dev removal handshake failed after all retries: handle(0x%04x)\n",
3713 		    __func__, drv_cmd->dev_handle);
3714 	} else {
3715 		mtx_lock_spin(&sc->target_lock);
3716 		TAILQ_FOREACH(tgtdev, &sc->cam_sc->tgt_list, tgt_next) {
3717 		       if (tgtdev->dev_handle == drv_cmd->dev_handle)
3718 			       tgtdev->state = MPI3MR_DEV_REMOVE_HS_COMPLETED;
3719 		}
3720 		mtx_unlock_spin(&sc->target_lock);
3721 
3722 		mpi3mr_dprint(sc, MPI3MR_INFO,
3723 		    "%s :dev removal handshake completed successfully: handle(0x%04x)\n",
3724 		    __func__, drv_cmd->dev_handle);
3725 		mpi3mr_clear_bit(drv_cmd->dev_handle, sc->removepend_bitmap);
3726 	}
3727 
3728 	if (!TAILQ_EMPTY(&sc->delayed_rmhs_list)) {
3729 		delayed_dev_rmhs = TAILQ_FIRST(&sc->delayed_rmhs_list);
3730 		drv_cmd->dev_handle = delayed_dev_rmhs->handle;
3731 		drv_cmd->retry_count = 0;
3732 		drv_cmd->iou_rc = delayed_dev_rmhs->iou_rc;
3733 		mpi3mr_dprint(sc, MPI3MR_EVENT,
3734 		    "%s :dev_rmhs_iouctrl_complete: processing delayed TM: handle(0x%04x)\n",
3735 		    __func__, drv_cmd->dev_handle);
3736 		mpi3mr_dev_rmhs_send_tm(sc, drv_cmd->dev_handle, drv_cmd,
3737 		    drv_cmd->iou_rc);
3738 		TAILQ_REMOVE(&sc->delayed_rmhs_list, delayed_dev_rmhs, list);
3739 		free(delayed_dev_rmhs, M_MPI3MR);
3740 		return;
3741 	}
3742 	drv_cmd->state = MPI3MR_CMD_NOTUSED;
3743 	drv_cmd->callback = NULL;
3744 	drv_cmd->retry_count = 0;
3745 	drv_cmd->dev_handle = MPI3MR_INVALID_DEV_HANDLE;
3746 	mpi3mr_clear_bit(cmd_idx, sc->devrem_bitmap);
3747 }
3748 
3749 /**
3750  * mpi3mr_dev_rmhs_complete_tm - Device removal TM completion
3751  * @sc: Adapter instance reference
3752  * @drv_cmd: Internal command tracker
3753  *
3754  * Issues a target reset TM to the firmware from the device
3755  * removal TM pend list or issue IO Unit control request as
3756  * part of device removal or hidden acknowledgment handshake.
3757  *
3758  * Return: Nothing
3759  */
3760 static void mpi3mr_dev_rmhs_complete_tm(struct mpi3mr_softc *sc,
3761 	struct mpi3mr_drvr_cmd *drv_cmd)
3762 {
3763 	Mpi3IoUnitControlRequest_t iou_ctrl;
3764 	U16 cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_DEVRMCMD_MIN;
3765 	Mpi3SCSITaskMgmtReply_t *tm_reply = NULL;
3766 	int retval;
3767 
3768 	if (drv_cmd->state & MPI3MR_CMD_REPLYVALID)
3769 		tm_reply = (Mpi3SCSITaskMgmtReply_t *)drv_cmd->reply;
3770 
3771 	if (tm_reply)
3772 		printf(IOCNAME
3773 		    "dev_rmhs_tr_complete:handle(0x%04x), ioc_status(0x%04x), loginfo(0x%08x), term_count(%d)\n",
3774 		    sc->name, drv_cmd->dev_handle, drv_cmd->ioc_status,
3775 		    drv_cmd->ioc_loginfo,
3776 		    le32toh(tm_reply->TerminationCount));
3777 
3778 	printf(IOCNAME "Issuing IOU CTL: handle(0x%04x) dev_rmhs idx(%d)\n",
3779 	    sc->name, drv_cmd->dev_handle, cmd_idx);
3780 
3781 	memset(&iou_ctrl, 0, sizeof(iou_ctrl));
3782 
3783 	drv_cmd->state = MPI3MR_CMD_PENDING;
3784 	drv_cmd->is_waiting = 0;
3785 	drv_cmd->callback = mpi3mr_dev_rmhs_complete_iou;
3786 	iou_ctrl.Operation = drv_cmd->iou_rc;
3787 	iou_ctrl.Param16[0] = htole16(drv_cmd->dev_handle);
3788 	iou_ctrl.HostTag = htole16(drv_cmd->host_tag);
3789 	iou_ctrl.Function = MPI3_FUNCTION_IO_UNIT_CONTROL;
3790 
3791 	retval = mpi3mr_submit_admin_cmd(sc, &iou_ctrl, sizeof(iou_ctrl));
3792 	if (retval) {
3793 		printf(IOCNAME "Issue DevRmHsTMIOUCTL: Admin post failed\n",
3794 		    sc->name);
3795 		goto out_failed;
3796 	}
3797 
3798 	return;
3799 out_failed:
3800 	drv_cmd->state = MPI3MR_CMD_NOTUSED;
3801 	drv_cmd->callback = NULL;
3802 	drv_cmd->dev_handle = MPI3MR_INVALID_DEV_HANDLE;
3803 	drv_cmd->retry_count = 0;
3804 	mpi3mr_clear_bit(cmd_idx, sc->devrem_bitmap);
3805 }
3806 
3807 /**
3808  * mpi3mr_dev_rmhs_send_tm - Issue TM for device removal
3809  * @sc: Adapter instance reference
3810  * @handle: Device handle
3811  * @cmdparam: Internal command tracker
3812  * @iou_rc: IO Unit reason code
3813  *
3814  * Issues a target reset TM to the firmware or add it to a pend
3815  * list as part of device removal or hidden acknowledgment
3816  * handshake.
3817  *
3818  * Return: Nothing
3819  */
3820 static void mpi3mr_dev_rmhs_send_tm(struct mpi3mr_softc *sc, U16 handle,
3821 	struct mpi3mr_drvr_cmd *cmdparam, U8 iou_rc)
3822 {
3823 	Mpi3SCSITaskMgmtRequest_t tm_req;
3824 	int retval = 0;
3825 	U16 cmd_idx = MPI3MR_NUM_DEVRMCMD;
3826 	U8 retrycount = 5;
3827 	struct mpi3mr_drvr_cmd *drv_cmd = cmdparam;
3828 	struct delayed_dev_rmhs_node *delayed_dev_rmhs = NULL;
3829 
3830 	if (drv_cmd)
3831 		goto issue_cmd;
3832 	do {
3833 		cmd_idx = mpi3mr_find_first_zero_bit(sc->devrem_bitmap,
3834 		    MPI3MR_NUM_DEVRMCMD);
3835 		if (cmd_idx < MPI3MR_NUM_DEVRMCMD) {
3836 			if (!mpi3mr_test_and_set_bit(cmd_idx, sc->devrem_bitmap))
3837 				break;
3838 			cmd_idx = MPI3MR_NUM_DEVRMCMD;
3839 		}
3840 	} while (retrycount--);
3841 
3842 	if (cmd_idx >= MPI3MR_NUM_DEVRMCMD) {
3843 		delayed_dev_rmhs = malloc(sizeof(*delayed_dev_rmhs),M_MPI3MR,
3844 		     M_ZERO|M_NOWAIT);
3845 
3846 		if (!delayed_dev_rmhs)
3847 			return;
3848 		delayed_dev_rmhs->handle = handle;
3849 		delayed_dev_rmhs->iou_rc = iou_rc;
3850 		TAILQ_INSERT_TAIL(&(sc->delayed_rmhs_list), delayed_dev_rmhs, list);
3851 		mpi3mr_dprint(sc, MPI3MR_EVENT, "%s :DevRmHs: tr:handle(0x%04x) is postponed\n",
3852 		    __func__, handle);
3853 
3854 
3855 		return;
3856 	}
3857 	drv_cmd = &sc->dev_rmhs_cmds[cmd_idx];
3858 
3859 issue_cmd:
3860 	cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_DEVRMCMD_MIN;
3861 	mpi3mr_dprint(sc, MPI3MR_EVENT,
3862 	    "%s :Issuing TR TM: for devhandle 0x%04x with dev_rmhs %d\n",
3863 	    __func__, handle, cmd_idx);
3864 
3865 	memset(&tm_req, 0, sizeof(tm_req));
3866 	if (drv_cmd->state & MPI3MR_CMD_PENDING) {
3867 		mpi3mr_dprint(sc, MPI3MR_EVENT, "%s :Issue TM: Command is in use\n", __func__);
3868 		goto out;
3869 	}
3870 	drv_cmd->state = MPI3MR_CMD_PENDING;
3871 	drv_cmd->is_waiting = 0;
3872 	drv_cmd->callback = mpi3mr_dev_rmhs_complete_tm;
3873 	drv_cmd->dev_handle = handle;
3874 	drv_cmd->iou_rc = iou_rc;
3875 	tm_req.DevHandle = htole16(handle);
3876 	tm_req.TaskType = MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
3877 	tm_req.HostTag = htole16(drv_cmd->host_tag);
3878 	tm_req.TaskHostTag = htole16(MPI3MR_HOSTTAG_INVALID);
3879 	tm_req.Function = MPI3_FUNCTION_SCSI_TASK_MGMT;
3880 
3881 	mpi3mr_set_bit(handle, sc->removepend_bitmap);
3882 	retval = mpi3mr_submit_admin_cmd(sc, &tm_req, sizeof(tm_req));
3883 	if (retval) {
3884 		mpi3mr_dprint(sc, MPI3MR_ERROR, "%s :Issue DevRmHsTM: Admin Post failed\n",
3885 		    __func__);
3886 		goto out_failed;
3887 	}
3888 out:
3889 	return;
3890 out_failed:
3891 	drv_cmd->state = MPI3MR_CMD_NOTUSED;
3892 	drv_cmd->callback = NULL;
3893 	drv_cmd->dev_handle = MPI3MR_INVALID_DEV_HANDLE;
3894 	drv_cmd->retry_count = 0;
3895 	mpi3mr_clear_bit(cmd_idx, sc->devrem_bitmap);
3896 }
3897 
3898 /**
3899  * mpi3mr_complete_evt_ack - Event ack request completion
3900  * @sc: Adapter instance reference
3901  * @drv_cmd: Internal command tracker
3902  *
3903  * This is the completion handler for non blocking event
3904  * acknowledgment sent to the firmware and this will issue any
3905  * pending event acknowledgment request.
3906  *
3907  * Return: Nothing
3908  */
3909 static void mpi3mr_complete_evt_ack(struct mpi3mr_softc *sc,
3910 	struct mpi3mr_drvr_cmd *drv_cmd)
3911 {
3912 	U16 cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_EVTACKCMD_MIN;
3913 	struct delayed_evtack_node *delayed_evtack = NULL;
3914 
3915 	if (drv_cmd->ioc_status != MPI3_IOCSTATUS_SUCCESS) {
3916 		mpi3mr_dprint(sc, MPI3MR_EVENT,
3917 		    "%s: Failed IOCStatus(0x%04x) Loginfo(0x%08x)\n", __func__,
3918 		    (drv_cmd->ioc_status & MPI3_IOCSTATUS_STATUS_MASK),
3919 		    drv_cmd->ioc_loginfo);
3920 	}
3921 
3922 	if (!TAILQ_EMPTY(&sc->delayed_evtack_cmds_list)) {
3923 		delayed_evtack = TAILQ_FIRST(&sc->delayed_evtack_cmds_list);
3924 		mpi3mr_dprint(sc, MPI3MR_EVENT,
3925 		    "%s: processing delayed event ack for event %d\n",
3926 		    __func__, delayed_evtack->event);
3927 		mpi3mr_send_evt_ack(sc, delayed_evtack->event, drv_cmd,
3928 		    delayed_evtack->event_ctx);
3929 		TAILQ_REMOVE(&sc->delayed_evtack_cmds_list, delayed_evtack, list);
3930 		free(delayed_evtack, M_MPI3MR);
3931 		return;
3932 	}
3933 	drv_cmd->state = MPI3MR_CMD_NOTUSED;
3934 	drv_cmd->callback = NULL;
3935 	mpi3mr_clear_bit(cmd_idx, sc->evtack_cmds_bitmap);
3936 }
3937 
3938 /**
3939  * mpi3mr_send_evt_ack - Issue event acknwoledgment request
3940  * @sc: Adapter instance reference
3941  * @event: MPI3 event id
3942  * @cmdparam: Internal command tracker
3943  * @event_ctx: Event context
3944  *
3945  * Issues event acknowledgment request to the firmware if there
3946  * is a free command to send the event ack else it to a pend
3947  * list so that it will be processed on a completion of a prior
3948  * event acknowledgment .
3949  *
3950  * Return: Nothing
3951  */
3952 static void mpi3mr_send_evt_ack(struct mpi3mr_softc *sc, U8 event,
3953 	struct mpi3mr_drvr_cmd *cmdparam, U32 event_ctx)
3954 {
3955 	Mpi3EventAckRequest_t evtack_req;
3956 	int retval = 0;
3957 	U8 retrycount = 5;
3958 	U16 cmd_idx = MPI3MR_NUM_EVTACKCMD;
3959 	struct mpi3mr_drvr_cmd *drv_cmd = cmdparam;
3960 	struct delayed_evtack_node *delayed_evtack = NULL;
3961 
3962 	if (drv_cmd)
3963 		goto issue_cmd;
3964 	do {
3965 		cmd_idx = mpi3mr_find_first_zero_bit(sc->evtack_cmds_bitmap,
3966 		    MPI3MR_NUM_EVTACKCMD);
3967 		if (cmd_idx < MPI3MR_NUM_EVTACKCMD) {
3968 			if (!mpi3mr_test_and_set_bit(cmd_idx,
3969 			    sc->evtack_cmds_bitmap))
3970 				break;
3971 			cmd_idx = MPI3MR_NUM_EVTACKCMD;
3972 		}
3973 	} while (retrycount--);
3974 
3975 	if (cmd_idx >= MPI3MR_NUM_EVTACKCMD) {
3976 		delayed_evtack = malloc(sizeof(*delayed_evtack),M_MPI3MR,
3977 		     M_ZERO | M_NOWAIT);
3978 		if (!delayed_evtack)
3979 			return;
3980 		delayed_evtack->event = event;
3981 		delayed_evtack->event_ctx = event_ctx;
3982 		TAILQ_INSERT_TAIL(&(sc->delayed_evtack_cmds_list), delayed_evtack, list);
3983 		mpi3mr_dprint(sc, MPI3MR_EVENT, "%s : Event ack for event:%d is postponed\n",
3984 		    __func__, event);
3985 		return;
3986 	}
3987 	drv_cmd = &sc->evtack_cmds[cmd_idx];
3988 
3989 issue_cmd:
3990 	cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_EVTACKCMD_MIN;
3991 
3992 	memset(&evtack_req, 0, sizeof(evtack_req));
3993 	if (drv_cmd->state & MPI3MR_CMD_PENDING) {
3994 		mpi3mr_dprint(sc, MPI3MR_EVENT, "%s: Command is in use\n", __func__);
3995 		goto out;
3996 	}
3997 	drv_cmd->state = MPI3MR_CMD_PENDING;
3998 	drv_cmd->is_waiting = 0;
3999 	drv_cmd->callback = mpi3mr_complete_evt_ack;
4000 	evtack_req.HostTag = htole16(drv_cmd->host_tag);
4001 	evtack_req.Function = MPI3_FUNCTION_EVENT_ACK;
4002 	evtack_req.Event = event;
4003 	evtack_req.EventContext = htole32(event_ctx);
4004 	retval = mpi3mr_submit_admin_cmd(sc, &evtack_req,
4005 	    sizeof(evtack_req));
4006 
4007 	if (retval) {
4008 		mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Admin Post failed\n", __func__);
4009 		goto out_failed;
4010 	}
4011 out:
4012 	return;
4013 out_failed:
4014 	drv_cmd->state = MPI3MR_CMD_NOTUSED;
4015 	drv_cmd->callback = NULL;
4016 	mpi3mr_clear_bit(cmd_idx, sc->evtack_cmds_bitmap);
4017 }
4018 
4019 /*
4020  * mpi3mr_pcietopochg_evt_th - PCIETopologyChange evt tophalf
4021  * @sc: Adapter instance reference
4022  * @event_reply: Event data
4023  *
4024  * Checks for the reason code and based on that either block I/O
4025  * to device, or unblock I/O to the device, or start the device
4026  * removal handshake with reason as remove with the firmware for
4027  * PCIe devices.
4028  *
4029  * Return: Nothing
4030  */
4031 static void mpi3mr_pcietopochg_evt_th(struct mpi3mr_softc *sc,
4032 	Mpi3EventNotificationReply_t *event_reply)
4033 {
4034 	Mpi3EventDataPcieTopologyChangeList_t *topo_evt =
4035 	    (Mpi3EventDataPcieTopologyChangeList_t *) event_reply->EventData;
4036 	int i;
4037 	U16 handle;
4038 	U8 reason_code;
4039 	struct mpi3mr_target *tgtdev = NULL;
4040 
4041 	for (i = 0; i < topo_evt->NumEntries; i++) {
4042 		handle = le16toh(topo_evt->PortEntry[i].AttachedDevHandle);
4043 		if (!handle)
4044 			continue;
4045 		reason_code = topo_evt->PortEntry[i].PortStatus;
4046 		tgtdev = mpi3mr_find_target_by_dev_handle(sc->cam_sc, handle);
4047 		switch (reason_code) {
4048 		case MPI3_EVENT_PCIE_TOPO_PS_NOT_RESPONDING:
4049 			if (tgtdev) {
4050 				tgtdev->dev_removed = 1;
4051 				tgtdev->dev_removedelay = 0;
4052 				mpi3mr_atomic_set(&tgtdev->block_io, 0);
4053 			}
4054 			mpi3mr_dev_rmhs_send_tm(sc, handle, NULL,
4055 			    MPI3_CTRL_OP_REMOVE_DEVICE);
4056 			break;
4057 		case MPI3_EVENT_PCIE_TOPO_PS_DELAY_NOT_RESPONDING:
4058 			if (tgtdev) {
4059 				tgtdev->dev_removedelay = 1;
4060 				mpi3mr_atomic_inc(&tgtdev->block_io);
4061 			}
4062 			break;
4063 		case MPI3_EVENT_PCIE_TOPO_PS_RESPONDING:
4064 			if (tgtdev &&
4065 			    tgtdev->dev_removedelay) {
4066 				tgtdev->dev_removedelay = 0;
4067 				if (mpi3mr_atomic_read(&tgtdev->block_io) > 0)
4068 					mpi3mr_atomic_dec(&tgtdev->block_io);
4069 			}
4070 			break;
4071 		case MPI3_EVENT_PCIE_TOPO_PS_PORT_CHANGED:
4072 		default:
4073 			break;
4074 		}
4075 	}
4076 }
4077 
4078 /**
4079  * mpi3mr_sastopochg_evt_th - SASTopologyChange evt tophalf
4080  * @sc: Adapter instance reference
4081  * @event_reply: Event data
4082  *
4083  * Checks for the reason code and based on that either block I/O
4084  * to device, or unblock I/O to the device, or start the device
4085  * removal handshake with reason as remove with the firmware for
4086  * SAS/SATA devices.
4087  *
4088  * Return: Nothing
4089  */
4090 static void mpi3mr_sastopochg_evt_th(struct mpi3mr_softc *sc,
4091 	Mpi3EventNotificationReply_t *event_reply)
4092 {
4093 	Mpi3EventDataSasTopologyChangeList_t *topo_evt =
4094 	    (Mpi3EventDataSasTopologyChangeList_t *)event_reply->EventData;
4095 	int i;
4096 	U16 handle;
4097 	U8 reason_code;
4098 	struct mpi3mr_target *tgtdev = NULL;
4099 
4100 	for (i = 0; i < topo_evt->NumEntries; i++) {
4101 		handle = le16toh(topo_evt->PhyEntry[i].AttachedDevHandle);
4102 		if (!handle)
4103 			continue;
4104 		reason_code = topo_evt->PhyEntry[i].PhyStatus &
4105 		    MPI3_EVENT_SAS_TOPO_PHY_RC_MASK;
4106 		tgtdev = mpi3mr_find_target_by_dev_handle(sc->cam_sc, handle);
4107 		switch (reason_code) {
4108 		case MPI3_EVENT_SAS_TOPO_PHY_RC_TARG_NOT_RESPONDING:
4109 			if (tgtdev) {
4110 				tgtdev->dev_removed = 1;
4111 				tgtdev->dev_removedelay = 0;
4112 				mpi3mr_atomic_set(&tgtdev->block_io, 0);
4113 			}
4114 			mpi3mr_dev_rmhs_send_tm(sc, handle, NULL,
4115 			    MPI3_CTRL_OP_REMOVE_DEVICE);
4116 			break;
4117 		case MPI3_EVENT_SAS_TOPO_PHY_RC_DELAY_NOT_RESPONDING:
4118 			if (tgtdev) {
4119 				tgtdev->dev_removedelay = 1;
4120 				mpi3mr_atomic_inc(&tgtdev->block_io);
4121 			}
4122 			break;
4123 		case MPI3_EVENT_SAS_TOPO_PHY_RC_RESPONDING:
4124 			if (tgtdev &&
4125 			    tgtdev->dev_removedelay) {
4126 				tgtdev->dev_removedelay = 0;
4127 				if (mpi3mr_atomic_read(&tgtdev->block_io) > 0)
4128 					mpi3mr_atomic_dec(&tgtdev->block_io);
4129 			}
4130 		case MPI3_EVENT_SAS_TOPO_PHY_RC_PHY_CHANGED:
4131 		default:
4132 			break;
4133 		}
4134 	}
4135 
4136 }
4137 /**
4138  * mpi3mr_devstatuschg_evt_th - DeviceStatusChange evt tophalf
4139  * @sc: Adapter instance reference
4140  * @event_reply: Event data
4141  *
4142  * Checks for the reason code and based on that either block I/O
4143  * to device, or unblock I/O to the device, or start the device
4144  * removal handshake with reason as remove/hide acknowledgment
4145  * with the firmware.
4146  *
4147  * Return: Nothing
4148  */
4149 static void mpi3mr_devstatuschg_evt_th(struct mpi3mr_softc *sc,
4150 	Mpi3EventNotificationReply_t *event_reply)
4151 {
4152 	U16 dev_handle = 0;
4153 	U8 ublock = 0, block = 0, hide = 0, uhide = 0, delete = 0, remove = 0;
4154 	struct mpi3mr_target *tgtdev = NULL;
4155 	Mpi3EventDataDeviceStatusChange_t *evtdata =
4156 	    (Mpi3EventDataDeviceStatusChange_t *) event_reply->EventData;
4157 
4158 	dev_handle = le16toh(evtdata->DevHandle);
4159 
4160 	switch (evtdata->ReasonCode) {
4161 	case MPI3_EVENT_DEV_STAT_RC_INT_DEVICE_RESET_STRT:
4162 	case MPI3_EVENT_DEV_STAT_RC_INT_IT_NEXUS_RESET_STRT:
4163 		block = 1;
4164 		break;
4165 	case MPI3_EVENT_DEV_STAT_RC_HIDDEN:
4166 		delete = 1;
4167 		hide = 1;
4168 		break;
4169 	case MPI3_EVENT_DEV_STAT_RC_NOT_HIDDEN:
4170 		uhide = 1;
4171 		break;
4172 	case MPI3_EVENT_DEV_STAT_RC_VD_NOT_RESPONDING:
4173 		delete = 1;
4174 		remove = 1;
4175 		break;
4176 	case MPI3_EVENT_DEV_STAT_RC_INT_DEVICE_RESET_CMP:
4177 	case MPI3_EVENT_DEV_STAT_RC_INT_IT_NEXUS_RESET_CMP:
4178 		ublock = 1;
4179 		break;
4180 	default:
4181 		break;
4182 	}
4183 
4184 	tgtdev = mpi3mr_find_target_by_dev_handle(sc->cam_sc, dev_handle);
4185 
4186 	if (!tgtdev) {
4187 		mpi3mr_dprint(sc, MPI3MR_ERROR, "%s :target with dev_handle:0x%x not found\n",
4188 		    __func__, dev_handle);
4189 		return;
4190 	}
4191 
4192 	if (block)
4193 		mpi3mr_atomic_inc(&tgtdev->block_io);
4194 
4195 	if (hide)
4196 		tgtdev->is_hidden = hide;
4197 
4198 	if (uhide) {
4199 		tgtdev->is_hidden = 0;
4200 		tgtdev->dev_removed = 0;
4201 	}
4202 
4203 	if (delete)
4204 		tgtdev->dev_removed = 1;
4205 
4206 	if (ublock) {
4207 		if (mpi3mr_atomic_read(&tgtdev->block_io) > 0)
4208 			mpi3mr_atomic_dec(&tgtdev->block_io);
4209 	}
4210 
4211 	if (remove) {
4212 		mpi3mr_dev_rmhs_send_tm(sc, dev_handle, NULL,
4213 					MPI3_CTRL_OP_REMOVE_DEVICE);
4214 	}
4215 	if (hide)
4216 		mpi3mr_dev_rmhs_send_tm(sc, dev_handle, NULL,
4217 					MPI3_CTRL_OP_HIDDEN_ACK);
4218 }
4219 
4220 /**
4221  * mpi3mr_preparereset_evt_th - Prepareforreset evt tophalf
4222  * @sc: Adapter instance reference
4223  * @event_reply: Event data
4224  *
4225  * Blocks and unblocks host level I/O based on the reason code
4226  *
4227  * Return: Nothing
4228  */
4229 static void mpi3mr_preparereset_evt_th(struct mpi3mr_softc *sc,
4230 	Mpi3EventNotificationReply_t *event_reply)
4231 {
4232 	Mpi3EventDataPrepareForReset_t *evtdata =
4233 	    (Mpi3EventDataPrepareForReset_t *)event_reply->EventData;
4234 
4235 	if (evtdata->ReasonCode == MPI3_EVENT_PREPARE_RESET_RC_START) {
4236 		mpi3mr_dprint(sc, MPI3MR_EVENT, "%s :Recieved PrepForReset Event with RC=START\n",
4237 		    __func__);
4238 		if (sc->prepare_for_reset)
4239 			return;
4240 		sc->prepare_for_reset = 1;
4241 		sc->prepare_for_reset_timeout_counter = 0;
4242 	} else if (evtdata->ReasonCode == MPI3_EVENT_PREPARE_RESET_RC_ABORT) {
4243 		mpi3mr_dprint(sc, MPI3MR_EVENT, "%s :Recieved PrepForReset Event with RC=ABORT\n",
4244 		    __func__);
4245 		sc->prepare_for_reset = 0;
4246 		sc->prepare_for_reset_timeout_counter = 0;
4247 	}
4248 	if ((event_reply->MsgFlags & MPI3_EVENT_NOTIFY_MSGFLAGS_ACK_MASK)
4249 	    == MPI3_EVENT_NOTIFY_MSGFLAGS_ACK_REQUIRED)
4250 		mpi3mr_send_evt_ack(sc, event_reply->Event, NULL,
4251 		    le32toh(event_reply->EventContext));
4252 }
4253 
4254 /**
4255  * mpi3mr_energypackchg_evt_th - Energypackchange evt tophalf
4256  * @sc: Adapter instance reference
4257  * @event_reply: Event data
4258  *
4259  * Identifies the new shutdown timeout value and update.
4260  *
4261  * Return: Nothing
4262  */
4263 static void mpi3mr_energypackchg_evt_th(struct mpi3mr_softc *sc,
4264 	Mpi3EventNotificationReply_t *event_reply)
4265 {
4266 	Mpi3EventDataEnergyPackChange_t *evtdata =
4267 	    (Mpi3EventDataEnergyPackChange_t *)event_reply->EventData;
4268 	U16 shutdown_timeout = le16toh(evtdata->ShutdownTimeout);
4269 
4270 	if (shutdown_timeout <= 0) {
4271 		mpi3mr_dprint(sc, MPI3MR_ERROR,
4272 		    "%s :Invalid Shutdown Timeout received = %d\n",
4273 		    __func__, shutdown_timeout);
4274 		return;
4275 	}
4276 
4277 	mpi3mr_dprint(sc, MPI3MR_EVENT,
4278 	    "%s :Previous Shutdown Timeout Value = %d New Shutdown Timeout Value = %d\n",
4279 	    __func__, sc->facts.shutdown_timeout, shutdown_timeout);
4280 	sc->facts.shutdown_timeout = shutdown_timeout;
4281 }
4282 
4283 /**
4284  * mpi3mr_cablemgmt_evt_th - Cable mgmt evt tophalf
4285  * @sc: Adapter instance reference
4286  * @event_reply: Event data
4287  *
4288  * Displays Cable manegemt event details.
4289  *
4290  * Return: Nothing
4291  */
4292 static void mpi3mr_cablemgmt_evt_th(struct mpi3mr_softc *sc,
4293 	Mpi3EventNotificationReply_t *event_reply)
4294 {
4295 	Mpi3EventDataCableManagement_t *evtdata =
4296 	    (Mpi3EventDataCableManagement_t *)event_reply->EventData;
4297 
4298 	switch (evtdata->Status) {
4299 	case MPI3_EVENT_CABLE_MGMT_STATUS_INSUFFICIENT_POWER:
4300 	{
4301 		mpi3mr_dprint(sc, MPI3MR_INFO, "An active cable with ReceptacleID %d cannot be powered.\n"
4302 		    "Devices connected to this cable are not detected.\n"
4303 		    "This cable requires %d mW of power.\n",
4304 		    evtdata->ReceptacleID,
4305 		    le32toh(evtdata->ActiveCablePowerRequirement));
4306 		break;
4307 	}
4308 	case MPI3_EVENT_CABLE_MGMT_STATUS_DEGRADED:
4309 	{
4310 		mpi3mr_dprint(sc, MPI3MR_INFO, "A cable with ReceptacleID %d is not running at optimal speed\n",
4311 		    evtdata->ReceptacleID);
4312 		break;
4313 	}
4314 	default:
4315 		break;
4316 	}
4317 }
4318 
4319 /**
4320  * mpi3mr_process_events - Event's toph-half handler
4321  * @sc: Adapter instance reference
4322  * @event_reply: Event data
4323  *
4324  * Top half of event processing.
4325  *
4326  * Return: Nothing
4327  */
4328 static void mpi3mr_process_events(struct mpi3mr_softc *sc,
4329     uintptr_t data, Mpi3EventNotificationReply_t *event_reply)
4330 {
4331 	U16 evt_type;
4332 	bool ack_req = 0, process_evt_bh = 0;
4333 	struct mpi3mr_fw_event_work *fw_event;
4334 	U16 sz;
4335 
4336 	if (sc->mpi3mr_flags & MPI3MR_FLAGS_SHUTDOWN)
4337 		goto out;
4338 
4339 	if ((event_reply->MsgFlags & MPI3_EVENT_NOTIFY_MSGFLAGS_ACK_MASK)
4340 	    == MPI3_EVENT_NOTIFY_MSGFLAGS_ACK_REQUIRED)
4341 		ack_req = 1;
4342 
4343 	evt_type = event_reply->Event;
4344 
4345 	switch (evt_type) {
4346 	case MPI3_EVENT_DEVICE_ADDED:
4347 	{
4348 		Mpi3DevicePage0_t *dev_pg0 =
4349 			(Mpi3DevicePage0_t *) event_reply->EventData;
4350 		if (mpi3mr_create_device(sc, dev_pg0))
4351 			mpi3mr_dprint(sc, MPI3MR_ERROR,
4352 			"%s :Failed to add device in the device add event\n",
4353 			__func__);
4354 		else
4355 			process_evt_bh = 1;
4356 		break;
4357 	}
4358 
4359 	case MPI3_EVENT_DEVICE_STATUS_CHANGE:
4360 	{
4361 		process_evt_bh = 1;
4362 		mpi3mr_devstatuschg_evt_th(sc, event_reply);
4363 		break;
4364 	}
4365 	case MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
4366 	{
4367 		process_evt_bh = 1;
4368 		mpi3mr_sastopochg_evt_th(sc, event_reply);
4369 		break;
4370 	}
4371 	case MPI3_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:
4372 	{
4373 		process_evt_bh = 1;
4374 		mpi3mr_pcietopochg_evt_th(sc, event_reply);
4375 		break;
4376 	}
4377 	case MPI3_EVENT_PREPARE_FOR_RESET:
4378 	{
4379 		mpi3mr_preparereset_evt_th(sc, event_reply);
4380 		ack_req = 0;
4381 		break;
4382 	}
4383 	case MPI3_EVENT_DEVICE_INFO_CHANGED:
4384 	{
4385 		process_evt_bh = 1;
4386 		break;
4387 	}
4388 	case MPI3_EVENT_LOG_DATA:
4389 	{
4390 		mpi3mr_app_save_logdata(sc, (char*)event_reply->EventData,
4391 					le16toh(event_reply->EventDataLength) * 4);
4392 		break;
4393 	}
4394 	case MPI3_EVENT_ENERGY_PACK_CHANGE:
4395 	{
4396 		mpi3mr_energypackchg_evt_th(sc, event_reply);
4397 		break;
4398 	}
4399 	case MPI3_EVENT_CABLE_MGMT:
4400 	{
4401 		mpi3mr_cablemgmt_evt_th(sc, event_reply);
4402 		break;
4403 	}
4404 
4405 	case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE:
4406 	case MPI3_EVENT_SAS_DISCOVERY:
4407 	case MPI3_EVENT_SAS_DEVICE_DISCOVERY_ERROR:
4408 	case MPI3_EVENT_SAS_BROADCAST_PRIMITIVE:
4409 	case MPI3_EVENT_PCIE_ENUMERATION:
4410 		break;
4411 	default:
4412 		mpi3mr_dprint(sc, MPI3MR_INFO, "%s :Event 0x%02x is not handled by driver\n",
4413 		    __func__, evt_type);
4414 		break;
4415 	}
4416 
4417 	if (process_evt_bh || ack_req) {
4418 		fw_event = malloc(sizeof(struct mpi3mr_fw_event_work), M_MPI3MR,
4419 		     M_ZERO|M_NOWAIT);
4420 
4421 		if (!fw_event) {
4422 			printf("%s: allocate failed for fw_event\n", __func__);
4423 			return;
4424 		}
4425 
4426 		sz = le16toh(event_reply->EventDataLength) * 4;
4427 		fw_event->event_data = malloc(sz, M_MPI3MR, M_ZERO|M_NOWAIT);
4428 
4429 		if (!fw_event->event_data) {
4430 			printf("%s: allocate failed for event_data\n", __func__);
4431 			free(fw_event, M_MPI3MR);
4432 			return;
4433 		}
4434 
4435 		bcopy(event_reply->EventData, fw_event->event_data, sz);
4436 		fw_event->event = event_reply->Event;
4437 		if ((event_reply->Event == MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
4438 		    event_reply->Event == MPI3_EVENT_PCIE_TOPOLOGY_CHANGE_LIST ||
4439 		    event_reply->Event == MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE ) &&
4440 		    sc->track_mapping_events)
4441 			sc->pending_map_events++;
4442 
4443 		/*
4444 		 * Events should be processed after Port enable is completed.
4445 		 */
4446 		if ((event_reply->Event == MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
4447 		    event_reply->Event == MPI3_EVENT_PCIE_TOPOLOGY_CHANGE_LIST ) &&
4448 		    !(sc->mpi3mr_flags & MPI3MR_FLAGS_PORT_ENABLE_DONE))
4449 			mpi3mr_startup_increment(sc->cam_sc);
4450 
4451 		fw_event->send_ack = ack_req;
4452 		fw_event->event_context = le32toh(event_reply->EventContext);
4453 		fw_event->event_data_size = sz;
4454 		fw_event->process_event = process_evt_bh;
4455 
4456 		mtx_lock(&sc->fwevt_lock);
4457 		TAILQ_INSERT_TAIL(&sc->cam_sc->ev_queue, fw_event, ev_link);
4458 		taskqueue_enqueue(sc->cam_sc->ev_tq, &sc->cam_sc->ev_task);
4459 		mtx_unlock(&sc->fwevt_lock);
4460 
4461 	}
4462 out:
4463 	return;
4464 }
4465 
4466 static void mpi3mr_handle_events(struct mpi3mr_softc *sc, uintptr_t data,
4467     Mpi3DefaultReply_t *def_reply)
4468 {
4469 	Mpi3EventNotificationReply_t *event_reply =
4470 		(Mpi3EventNotificationReply_t *)def_reply;
4471 
4472 	sc->change_count = event_reply->IOCChangeCount;
4473 	mpi3mr_display_event_data(sc, event_reply);
4474 
4475 	mpi3mr_process_events(sc, data, event_reply);
4476 }
4477 
4478 static void mpi3mr_process_admin_reply_desc(struct mpi3mr_softc *sc,
4479     Mpi3DefaultReplyDescriptor_t *reply_desc, U64 *reply_dma)
4480 {
4481 	U16 reply_desc_type, host_tag = 0, idx;
4482 	U16 ioc_status = MPI3_IOCSTATUS_SUCCESS;
4483 	U32 ioc_loginfo = 0;
4484 	Mpi3StatusReplyDescriptor_t *status_desc;
4485 	Mpi3AddressReplyDescriptor_t *addr_desc;
4486 	Mpi3SuccessReplyDescriptor_t *success_desc;
4487 	Mpi3DefaultReply_t *def_reply = NULL;
4488 	struct mpi3mr_drvr_cmd *cmdptr = NULL;
4489 	Mpi3SCSIIOReply_t *scsi_reply;
4490 	U8 *sense_buf = NULL;
4491 
4492 	*reply_dma = 0;
4493 	reply_desc_type = reply_desc->ReplyFlags &
4494 			    MPI3_REPLY_DESCRIPT_FLAGS_TYPE_MASK;
4495 	switch (reply_desc_type) {
4496 	case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_STATUS:
4497 		status_desc = (Mpi3StatusReplyDescriptor_t *)reply_desc;
4498 		host_tag = status_desc->HostTag;
4499 		ioc_status = status_desc->IOCStatus;
4500 		if (ioc_status & MPI3_IOCSTATUS_STATUS_MASK)
4501 			ioc_loginfo = status_desc->IOCLogInfo;
4502 		ioc_status &= MPI3_IOCSTATUS_STATUS_MASK;
4503 		break;
4504 	case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_ADDRESS_REPLY:
4505 		addr_desc = (Mpi3AddressReplyDescriptor_t *)reply_desc;
4506 		*reply_dma = addr_desc->ReplyFrameAddress;
4507 		def_reply = mpi3mr_get_reply_virt_addr(sc, *reply_dma);
4508 		if (def_reply == NULL)
4509 			goto out;
4510 		host_tag = def_reply->HostTag;
4511 		ioc_status = def_reply->IOCStatus;
4512 		if (ioc_status & MPI3_IOCSTATUS_STATUS_MASK)
4513 			ioc_loginfo = def_reply->IOCLogInfo;
4514 		ioc_status &= MPI3_IOCSTATUS_STATUS_MASK;
4515 		if (def_reply->Function == MPI3_FUNCTION_SCSI_IO) {
4516 			scsi_reply = (Mpi3SCSIIOReply_t *)def_reply;
4517 			sense_buf = mpi3mr_get_sensebuf_virt_addr(sc,
4518 			    scsi_reply->SenseDataBufferAddress);
4519 		}
4520 		break;
4521 	case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_SUCCESS:
4522 		success_desc = (Mpi3SuccessReplyDescriptor_t *)reply_desc;
4523 		host_tag = success_desc->HostTag;
4524 		break;
4525 	default:
4526 		break;
4527 	}
4528 	switch (host_tag) {
4529 	case MPI3MR_HOSTTAG_INITCMDS:
4530 		cmdptr = &sc->init_cmds;
4531 		break;
4532 	case MPI3MR_HOSTTAG_CFGCMDS:
4533 		cmdptr = &sc->cfg_cmds;
4534 		break;
4535 	case MPI3MR_HOSTTAG_IOCTLCMDS:
4536 		cmdptr = &sc->ioctl_cmds;
4537 		break;
4538 	case MPI3MR_HOSTTAG_TMS:
4539 		cmdptr = &sc->host_tm_cmds;
4540 		wakeup((void *)&sc->tm_chan);
4541 		break;
4542 	case MPI3MR_HOSTTAG_PELABORT:
4543 		cmdptr = &sc->pel_abort_cmd;
4544 		break;
4545 	case MPI3MR_HOSTTAG_PELWAIT:
4546 		cmdptr = &sc->pel_cmds;
4547 		break;
4548 	case MPI3MR_HOSTTAG_INVALID:
4549 		if (def_reply && def_reply->Function ==
4550 		    MPI3_FUNCTION_EVENT_NOTIFICATION)
4551 			mpi3mr_handle_events(sc, *reply_dma ,def_reply);
4552 	default:
4553 		break;
4554 	}
4555 
4556 	if (host_tag >= MPI3MR_HOSTTAG_DEVRMCMD_MIN &&
4557 	    host_tag <= MPI3MR_HOSTTAG_DEVRMCMD_MAX ) {
4558 		idx = host_tag - MPI3MR_HOSTTAG_DEVRMCMD_MIN;
4559 		cmdptr = &sc->dev_rmhs_cmds[idx];
4560 	}
4561 
4562 	if (host_tag >= MPI3MR_HOSTTAG_EVTACKCMD_MIN &&
4563 	    host_tag <= MPI3MR_HOSTTAG_EVTACKCMD_MAX) {
4564 		idx = host_tag - MPI3MR_HOSTTAG_EVTACKCMD_MIN;
4565 		cmdptr = &sc->evtack_cmds[idx];
4566 	}
4567 
4568 	if (cmdptr) {
4569 		if (cmdptr->state & MPI3MR_CMD_PENDING) {
4570 			cmdptr->state |= MPI3MR_CMD_COMPLETE;
4571 			cmdptr->ioc_loginfo = ioc_loginfo;
4572 			cmdptr->ioc_status = ioc_status;
4573 			cmdptr->state &= ~MPI3MR_CMD_PENDING;
4574 			if (def_reply) {
4575 				cmdptr->state |= MPI3MR_CMD_REPLYVALID;
4576 				memcpy((U8 *)cmdptr->reply, (U8 *)def_reply,
4577 				    sc->reply_sz);
4578 			}
4579 			if (sense_buf && cmdptr->sensebuf) {
4580 				cmdptr->is_senseprst = 1;
4581 				memcpy(cmdptr->sensebuf, sense_buf,
4582 				    MPI3MR_SENSEBUF_SZ);
4583 			}
4584 			if (cmdptr->is_waiting) {
4585 				complete(&cmdptr->completion);
4586 				cmdptr->is_waiting = 0;
4587 			} else if (cmdptr->callback)
4588 				cmdptr->callback(sc, cmdptr);
4589 		}
4590 	}
4591 out:
4592 	if (sense_buf != NULL)
4593 		mpi3mr_repost_sense_buf(sc,
4594 		    scsi_reply->SenseDataBufferAddress);
4595 	return;
4596 }
4597 
4598 /*
4599  * mpi3mr_complete_admin_cmd:	ISR routine for admin commands
4600  * @sc:				Adapter's soft instance
4601  *
4602  * This function processes admin command completions.
4603  */
4604 static int mpi3mr_complete_admin_cmd(struct mpi3mr_softc *sc)
4605 {
4606 	U32 exp_phase = sc->admin_reply_ephase;
4607 	U32 adm_reply_ci = sc->admin_reply_ci;
4608 	U32 num_adm_reply = 0;
4609 	U64 reply_dma = 0;
4610 	Mpi3DefaultReplyDescriptor_t *reply_desc;
4611 	U16 threshold_comps = 0;
4612 
4613 	mtx_lock_spin(&sc->admin_reply_lock);
4614 	if (sc->admin_in_use == false) {
4615 		sc->admin_in_use = true;
4616 		mtx_unlock_spin(&sc->admin_reply_lock);
4617 	} else {
4618 		mtx_unlock_spin(&sc->admin_reply_lock);
4619 		return 0;
4620 	}
4621 
4622 	reply_desc = (Mpi3DefaultReplyDescriptor_t *)sc->admin_reply +
4623 		adm_reply_ci;
4624 
4625 	if ((reply_desc->ReplyFlags &
4626 	     MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase) {
4627 		mtx_lock_spin(&sc->admin_reply_lock);
4628 		sc->admin_in_use = false;
4629 		mtx_unlock_spin(&sc->admin_reply_lock);
4630 		return 0;
4631 	}
4632 
4633 	do {
4634 		sc->admin_req_ci = reply_desc->RequestQueueCI;
4635 		mpi3mr_process_admin_reply_desc(sc, reply_desc, &reply_dma);
4636 		if (reply_dma)
4637 			mpi3mr_repost_reply_buf(sc, reply_dma);
4638 		num_adm_reply++;
4639 		if (++adm_reply_ci == sc->num_admin_replies) {
4640 			adm_reply_ci = 0;
4641 			exp_phase ^= 1;
4642 		}
4643 		reply_desc =
4644 			(Mpi3DefaultReplyDescriptor_t *)sc->admin_reply +
4645 			    adm_reply_ci;
4646 		if ((reply_desc->ReplyFlags &
4647 		     MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase)
4648 			break;
4649 
4650 		if (++threshold_comps == MPI3MR_THRESHOLD_REPLY_COUNT) {
4651 			mpi3mr_regwrite(sc, MPI3_SYSIF_ADMIN_REPLY_Q_CI_OFFSET, adm_reply_ci);
4652 			threshold_comps = 0;
4653 		}
4654 	} while (1);
4655 
4656 	mpi3mr_regwrite(sc, MPI3_SYSIF_ADMIN_REPLY_Q_CI_OFFSET, adm_reply_ci);
4657 	sc->admin_reply_ci = adm_reply_ci;
4658 	sc->admin_reply_ephase = exp_phase;
4659 	mtx_lock_spin(&sc->admin_reply_lock);
4660 	sc->admin_in_use = false;
4661 	mtx_unlock_spin(&sc->admin_reply_lock);
4662 	return num_adm_reply;
4663 }
4664 
4665 static void
4666 mpi3mr_cmd_done(struct mpi3mr_softc *sc, struct mpi3mr_cmd *cmd)
4667 {
4668 	mpi3mr_unmap_request(sc, cmd);
4669 
4670 	mtx_lock(&sc->mpi3mr_mtx);
4671 	if (cmd->callout_owner) {
4672 		callout_stop(&cmd->callout);
4673 		cmd->callout_owner = false;
4674 	}
4675 
4676 	if (sc->unrecoverable)
4677 		mpi3mr_set_ccbstatus(cmd->ccb, CAM_DEV_NOT_THERE);
4678 
4679 	xpt_done(cmd->ccb);
4680 	cmd->ccb = NULL;
4681 	mtx_unlock(&sc->mpi3mr_mtx);
4682 	mpi3mr_release_command(cmd);
4683 }
4684 
4685 void mpi3mr_process_op_reply_desc(struct mpi3mr_softc *sc,
4686     Mpi3DefaultReplyDescriptor_t *reply_desc, U64 *reply_dma)
4687 {
4688 	U16 reply_desc_type, host_tag = 0;
4689 	U16 ioc_status = MPI3_IOCSTATUS_SUCCESS;
4690 	U32 ioc_loginfo = 0;
4691 	Mpi3StatusReplyDescriptor_t *status_desc = NULL;
4692 	Mpi3AddressReplyDescriptor_t *addr_desc = NULL;
4693 	Mpi3SuccessReplyDescriptor_t *success_desc = NULL;
4694 	Mpi3SCSIIOReply_t *scsi_reply = NULL;
4695 	U8 *sense_buf = NULL;
4696 	U8 scsi_state = 0, scsi_status = 0, sense_state = 0;
4697 	U32 xfer_count = 0, sense_count =0, resp_data = 0;
4698 	struct mpi3mr_cmd *cm = NULL;
4699 	union ccb *ccb;
4700 	struct ccb_scsiio *csio;
4701 	struct mpi3mr_cam_softc *cam_sc;
4702 	U32 target_id;
4703 	U8 *scsi_cdb;
4704 	struct mpi3mr_target *target = NULL;
4705 	U32 ioc_pend_data_len = 0, tg_pend_data_len = 0, data_len_blks = 0;
4706 	struct mpi3mr_throttle_group_info *tg = NULL;
4707 	U8 throttle_enabled_dev = 0;
4708 	static int ratelimit;
4709 
4710 	*reply_dma = 0;
4711 	reply_desc_type = reply_desc->ReplyFlags &
4712 			    MPI3_REPLY_DESCRIPT_FLAGS_TYPE_MASK;
4713 	switch (reply_desc_type) {
4714 	case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_STATUS:
4715 		status_desc = (Mpi3StatusReplyDescriptor_t *)reply_desc;
4716 		host_tag = status_desc->HostTag;
4717 		ioc_status = status_desc->IOCStatus;
4718 		if (ioc_status & MPI3_IOCSTATUS_STATUS_MASK)
4719 			ioc_loginfo = status_desc->IOCLogInfo;
4720 		ioc_status &= MPI3_IOCSTATUS_STATUS_MASK;
4721 		break;
4722 	case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_ADDRESS_REPLY:
4723 		addr_desc = (Mpi3AddressReplyDescriptor_t *)reply_desc;
4724 		*reply_dma = addr_desc->ReplyFrameAddress;
4725 		scsi_reply = mpi3mr_get_reply_virt_addr(sc,
4726 		    *reply_dma);
4727 		if (scsi_reply == NULL) {
4728 			mpi3mr_dprint(sc, MPI3MR_ERROR, "scsi_reply is NULL, "
4729 			    "this shouldn't happen, reply_desc: %p\n",
4730 			    reply_desc);
4731 			goto out;
4732 		}
4733 
4734 		host_tag = scsi_reply->HostTag;
4735 		ioc_status = scsi_reply->IOCStatus;
4736 		scsi_status = scsi_reply->SCSIStatus;
4737 		scsi_state = scsi_reply->SCSIState;
4738 		sense_state = (scsi_state & MPI3_SCSI_STATE_SENSE_MASK);
4739 		xfer_count = scsi_reply->TransferCount;
4740 		sense_count = scsi_reply->SenseCount;
4741 		resp_data = scsi_reply->ResponseData;
4742 		sense_buf = mpi3mr_get_sensebuf_virt_addr(sc,
4743 		    scsi_reply->SenseDataBufferAddress);
4744 		if (ioc_status & MPI3_IOCSTATUS_STATUS_MASK)
4745 			ioc_loginfo = scsi_reply->IOCLogInfo;
4746 		ioc_status &= MPI3_IOCSTATUS_STATUS_MASK;
4747 		if (sense_state == MPI3_SCSI_STATE_SENSE_BUFF_Q_EMPTY)
4748 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Ran out of sense buffers\n");
4749 
4750 		break;
4751 	case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_SUCCESS:
4752 		success_desc = (Mpi3SuccessReplyDescriptor_t *)reply_desc;
4753 		host_tag = success_desc->HostTag;
4754 
4755 	default:
4756 		break;
4757 	}
4758 
4759 	cm = sc->cmd_list[host_tag];
4760 
4761 	if (cm->state == MPI3MR_CMD_STATE_FREE)
4762 		goto out;
4763 
4764 	cam_sc = sc->cam_sc;
4765 	ccb = cm->ccb;
4766 	csio = &ccb->csio;
4767 	target_id = csio->ccb_h.target_id;
4768 
4769 	scsi_cdb = scsiio_cdb_ptr(csio);
4770 
4771 	target = mpi3mr_find_target_by_per_id(cam_sc, target_id);
4772 	if (sc->iot_enable) {
4773 		data_len_blks = csio->dxfer_len >> 9;
4774 
4775 		if (target) {
4776 			tg = target->throttle_group;
4777 			throttle_enabled_dev =
4778 				target->io_throttle_enabled;
4779 		}
4780 
4781 		if ((data_len_blks >= sc->io_throttle_data_length) &&
4782 		     throttle_enabled_dev) {
4783 			mpi3mr_atomic_sub(&sc->pend_large_data_sz, data_len_blks);
4784 			ioc_pend_data_len = mpi3mr_atomic_read(
4785 			    &sc->pend_large_data_sz);
4786 			if (tg) {
4787 				mpi3mr_atomic_sub(&tg->pend_large_data_sz,
4788 					data_len_blks);
4789 				tg_pend_data_len = mpi3mr_atomic_read(&tg->pend_large_data_sz);
4790 				if (ratelimit % 1000) {
4791 					mpi3mr_dprint(sc, MPI3MR_IOT,
4792 						"large vd_io completion persist_id(%d), handle(0x%04x), data_len(%d),"
4793 						"ioc_pending(%d), tg_pending(%d), ioc_low(%d), tg_low(%d)\n",
4794 						    target->per_id,
4795 						    target->dev_handle,
4796 						    data_len_blks, ioc_pend_data_len,
4797 						    tg_pend_data_len,
4798 						    sc->io_throttle_low,
4799 						    tg->low);
4800 					ratelimit++;
4801 				}
4802 				if (tg->io_divert  && ((ioc_pend_data_len <=
4803 				    sc->io_throttle_low) &&
4804 				    (tg_pend_data_len <= tg->low))) {
4805 					tg->io_divert = 0;
4806 					mpi3mr_dprint(sc, MPI3MR_IOT,
4807 						"VD: Coming out of divert perst_id(%d) tg_id(%d)\n",
4808 						target->per_id, tg->id);
4809 					mpi3mr_set_io_divert_for_all_vd_in_tg(
4810 					    sc, tg, 0);
4811 				}
4812 			} else {
4813 				if (ratelimit % 1000) {
4814 					mpi3mr_dprint(sc, MPI3MR_IOT,
4815 					    "large pd_io completion persist_id(%d), handle(0x%04x), data_len(%d), ioc_pending(%d), ioc_low(%d)\n",
4816 					    target->per_id,
4817 					    target->dev_handle,
4818 					    data_len_blks, ioc_pend_data_len,
4819 					    sc->io_throttle_low);
4820 					ratelimit++;
4821 				}
4822 
4823 				if (ioc_pend_data_len <= sc->io_throttle_low) {
4824 					target->io_divert = 0;
4825 					mpi3mr_dprint(sc, MPI3MR_IOT,
4826 						"PD: Coming out of divert perst_id(%d)\n",
4827 						target->per_id);
4828 				}
4829 			}
4830 
4831 			} else if (target->io_divert) {
4832 			ioc_pend_data_len = mpi3mr_atomic_read(&sc->pend_large_data_sz);
4833 			if (!tg) {
4834 				if (ratelimit % 1000) {
4835 					mpi3mr_dprint(sc, MPI3MR_IOT,
4836 					    "pd_io completion persist_id(%d), handle(0x%04x), data_len(%d), ioc_pending(%d), ioc_low(%d)\n",
4837 					    target->per_id,
4838 					    target->dev_handle,
4839 					    data_len_blks, ioc_pend_data_len,
4840 					    sc->io_throttle_low);
4841 					ratelimit++;
4842 				}
4843 
4844 				if ( ioc_pend_data_len <= sc->io_throttle_low) {
4845 					mpi3mr_dprint(sc, MPI3MR_IOT,
4846 						"PD: Coming out of divert perst_id(%d)\n",
4847 						target->per_id);
4848 					target->io_divert = 0;
4849 				}
4850 
4851 			} else if (ioc_pend_data_len <= sc->io_throttle_low) {
4852 				tg_pend_data_len = mpi3mr_atomic_read(&tg->pend_large_data_sz);
4853 				if (ratelimit % 1000) {
4854 					mpi3mr_dprint(sc, MPI3MR_IOT,
4855 						"vd_io completion persist_id(%d), handle(0x%04x), data_len(%d),"
4856 						"ioc_pending(%d), tg_pending(%d), ioc_low(%d), tg_low(%d)\n",
4857 						    target->per_id,
4858 						    target->dev_handle,
4859 						    data_len_blks, ioc_pend_data_len,
4860 						    tg_pend_data_len,
4861 						    sc->io_throttle_low,
4862 						    tg->low);
4863 					ratelimit++;
4864 				}
4865 				if (tg->io_divert  && (tg_pend_data_len <= tg->low)) {
4866 					tg->io_divert = 0;
4867 					mpi3mr_dprint(sc, MPI3MR_IOT,
4868 						"VD: Coming out of divert perst_id(%d) tg_id(%d)\n",
4869 						target->per_id, tg->id);
4870 					mpi3mr_set_io_divert_for_all_vd_in_tg(
4871 					    sc, tg, 0);
4872 				}
4873 
4874 			}
4875 		}
4876 	}
4877 
4878 	if (success_desc) {
4879 		mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP);
4880 		goto out_success;
4881 	}
4882 
4883 	if (ioc_status == MPI3_IOCSTATUS_SCSI_DATA_UNDERRUN
4884 	    && xfer_count == 0 && (scsi_status == MPI3_SCSI_STATUS_BUSY ||
4885 	    scsi_status == MPI3_SCSI_STATUS_RESERVATION_CONFLICT ||
4886 	    scsi_status == MPI3_SCSI_STATUS_TASK_SET_FULL))
4887 		ioc_status = MPI3_IOCSTATUS_SUCCESS;
4888 
4889 	if ((sense_state == MPI3_SCSI_STATE_SENSE_VALID) && sense_count
4890 	    && sense_buf) {
4891 		int sense_len, returned_sense_len;
4892 
4893 		returned_sense_len = min(le32toh(sense_count),
4894 		    sizeof(struct scsi_sense_data));
4895 		if (returned_sense_len < csio->sense_len)
4896 			csio->sense_resid = csio->sense_len -
4897 			    returned_sense_len;
4898 		else
4899 			csio->sense_resid = 0;
4900 
4901 		sense_len = min(returned_sense_len,
4902 		    csio->sense_len - csio->sense_resid);
4903 		bzero(&csio->sense_data, sizeof(csio->sense_data));
4904 		bcopy(sense_buf, &csio->sense_data, sense_len);
4905 		ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
4906 	}
4907 
4908 	switch (ioc_status) {
4909 	case MPI3_IOCSTATUS_BUSY:
4910 	case MPI3_IOCSTATUS_INSUFFICIENT_RESOURCES:
4911 		mpi3mr_set_ccbstatus(ccb, CAM_REQUEUE_REQ);
4912 		break;
4913 	case MPI3_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
4914 		/*
4915 		 * If devinfo is 0 this will be a volume.  In that case don't
4916 		 * tell CAM that the volume is not there.  We want volumes to
4917 		 * be enumerated until they are deleted/removed, not just
4918 		 * failed.
4919 		 */
4920 		if (cm->targ->devinfo == 0)
4921 			mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP);
4922 		else
4923 			mpi3mr_set_ccbstatus(ccb, CAM_DEV_NOT_THERE);
4924 		break;
4925 	case MPI3_IOCSTATUS_SCSI_TASK_TERMINATED:
4926 	case MPI3_IOCSTATUS_SCSI_IOC_TERMINATED:
4927 	case MPI3_IOCSTATUS_SCSI_EXT_TERMINATED:
4928 		mpi3mr_set_ccbstatus(ccb, CAM_SCSI_BUSY);
4929 		mpi3mr_dprint(sc, MPI3MR_TRACE,
4930 		    "func: %s line:%d tgt %u Hosttag %u loginfo %x\n",
4931 		    __func__, __LINE__,
4932 		    target_id, cm->hosttag,
4933 		    le32toh(scsi_reply->IOCLogInfo));
4934 		mpi3mr_dprint(sc, MPI3MR_TRACE,
4935 		    "SCSIStatus %x SCSIState %x xfercount %u\n",
4936 		    scsi_reply->SCSIStatus, scsi_reply->SCSIState,
4937 		    le32toh(xfer_count));
4938 		break;
4939 	case MPI3_IOCSTATUS_SCSI_DATA_OVERRUN:
4940 		/* resid is ignored for this condition */
4941 		csio->resid = 0;
4942 		mpi3mr_set_ccbstatus(ccb, CAM_DATA_RUN_ERR);
4943 		break;
4944 	case MPI3_IOCSTATUS_SCSI_DATA_UNDERRUN:
4945 		csio->resid = cm->length - le32toh(xfer_count);
4946 	case MPI3_IOCSTATUS_SCSI_RECOVERED_ERROR:
4947 	case MPI3_IOCSTATUS_SUCCESS:
4948 		if ((scsi_reply->IOCStatus & MPI3_IOCSTATUS_STATUS_MASK) ==
4949 		    MPI3_IOCSTATUS_SCSI_RECOVERED_ERROR)
4950 			mpi3mr_dprint(sc, MPI3MR_XINFO, "func: %s line: %d recovered error\n",  __func__, __LINE__);
4951 
4952 		/* Completion failed at the transport level. */
4953 		if (scsi_reply->SCSIState & (MPI3_SCSI_STATE_NO_SCSI_STATUS |
4954 		    MPI3_SCSI_STATE_TERMINATED)) {
4955 			mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP_ERR);
4956 			break;
4957 		}
4958 
4959 		/* In a modern packetized environment, an autosense failure
4960 		 * implies that there's not much else that can be done to
4961 		 * recover the command.
4962 		 */
4963 		if (scsi_reply->SCSIState & MPI3_SCSI_STATE_SENSE_VALID) {
4964 			mpi3mr_set_ccbstatus(ccb, CAM_AUTOSENSE_FAIL);
4965 			break;
4966 		}
4967 
4968 		/*
4969 		 * Intentionally override the normal SCSI status reporting
4970 		 * for these two cases.  These are likely to happen in a
4971 		 * multi-initiator environment, and we want to make sure that
4972 		 * CAM retries these commands rather than fail them.
4973 		 */
4974 		if ((scsi_reply->SCSIStatus == MPI3_SCSI_STATUS_COMMAND_TERMINATED) ||
4975 		    (scsi_reply->SCSIStatus == MPI3_SCSI_STATUS_TASK_ABORTED)) {
4976 			mpi3mr_set_ccbstatus(ccb, CAM_REQ_ABORTED);
4977 			break;
4978 		}
4979 
4980 		/* Handle normal status and sense */
4981 		csio->scsi_status = scsi_reply->SCSIStatus;
4982 		if (scsi_reply->SCSIStatus == MPI3_SCSI_STATUS_GOOD)
4983 			mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP);
4984 		else
4985 			mpi3mr_set_ccbstatus(ccb, CAM_SCSI_STATUS_ERROR);
4986 
4987 		if (scsi_reply->SCSIState & MPI3_SCSI_STATE_SENSE_VALID) {
4988 			int sense_len, returned_sense_len;
4989 
4990 			returned_sense_len = min(le32toh(scsi_reply->SenseCount),
4991 			    sizeof(struct scsi_sense_data));
4992 			if (returned_sense_len < csio->sense_len)
4993 				csio->sense_resid = csio->sense_len -
4994 				    returned_sense_len;
4995 			else
4996 				csio->sense_resid = 0;
4997 
4998 			sense_len = min(returned_sense_len,
4999 			    csio->sense_len - csio->sense_resid);
5000 			bzero(&csio->sense_data, sizeof(csio->sense_data));
5001 			bcopy(cm->sense, &csio->sense_data, sense_len);
5002 			ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
5003 		}
5004 
5005 		break;
5006 	case MPI3_IOCSTATUS_INVALID_SGL:
5007 		mpi3mr_set_ccbstatus(ccb, CAM_UNREC_HBA_ERROR);
5008 		break;
5009 	case MPI3_IOCSTATUS_EEDP_GUARD_ERROR:
5010 	case MPI3_IOCSTATUS_EEDP_REF_TAG_ERROR:
5011 	case MPI3_IOCSTATUS_EEDP_APP_TAG_ERROR:
5012 	case MPI3_IOCSTATUS_SCSI_PROTOCOL_ERROR:
5013 	case MPI3_IOCSTATUS_INVALID_FUNCTION:
5014 	case MPI3_IOCSTATUS_INTERNAL_ERROR:
5015 	case MPI3_IOCSTATUS_INVALID_FIELD:
5016 	case MPI3_IOCSTATUS_INVALID_STATE:
5017 	case MPI3_IOCSTATUS_SCSI_IO_DATA_ERROR:
5018 	case MPI3_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
5019 	case MPI3_IOCSTATUS_INSUFFICIENT_POWER:
5020 	case MPI3_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
5021 	default:
5022 		csio->resid = cm->length;
5023 		mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP_ERR);
5024 		break;
5025 	}
5026 
5027 out_success:
5028 	if (mpi3mr_get_ccbstatus(ccb) != CAM_REQ_CMP) {
5029 		ccb->ccb_h.status |= CAM_DEV_QFRZN;
5030 		xpt_freeze_devq(ccb->ccb_h.path, /*count*/ 1);
5031 	}
5032 
5033 	mpi3mr_atomic_dec(&cm->targ->outstanding);
5034 	mpi3mr_cmd_done(sc, cm);
5035 	mpi3mr_dprint(sc, MPI3MR_TRACE, "Completion IO path :"
5036 		" cdb[0]: %x targetid: 0x%x SMID: %x ioc_status: 0x%x ioc_loginfo: 0x%x scsi_status: 0x%x "
5037 		"scsi_state: 0x%x response_data: 0x%x\n", scsi_cdb[0], target_id, host_tag,
5038 		ioc_status, ioc_loginfo, scsi_status, scsi_state, resp_data);
5039 	mpi3mr_atomic_dec(&sc->fw_outstanding);
5040 out:
5041 
5042 	if (sense_buf)
5043 		mpi3mr_repost_sense_buf(sc,
5044 		    scsi_reply->SenseDataBufferAddress);
5045 	return;
5046 }
5047 
5048 /*
5049  * mpi3mr_complete_io_cmd:	ISR routine for IO commands
5050  * @sc:				Adapter's soft instance
5051  * @irq_ctx:			Driver's internal per IRQ structure
5052  *
5053  * This function processes IO command completions.
5054  */
5055 int mpi3mr_complete_io_cmd(struct mpi3mr_softc *sc,
5056     struct mpi3mr_irq_context *irq_ctx)
5057 {
5058 	struct mpi3mr_op_reply_queue *op_reply_q = irq_ctx->op_reply_q;
5059 	U32 exp_phase = op_reply_q->ephase;
5060 	U32 reply_ci = op_reply_q->ci;
5061 	U32 num_op_replies = 0;
5062 	U64 reply_dma = 0;
5063 	Mpi3DefaultReplyDescriptor_t *reply_desc;
5064 	U16 req_qid = 0, threshold_comps = 0;
5065 
5066 	mtx_lock_spin(&op_reply_q->q_lock);
5067 	if (op_reply_q->in_use == false) {
5068 		op_reply_q->in_use = true;
5069 		mtx_unlock_spin(&op_reply_q->q_lock);
5070 	} else {
5071 		mtx_unlock_spin(&op_reply_q->q_lock);
5072 		return 0;
5073 	}
5074 
5075 	reply_desc = (Mpi3DefaultReplyDescriptor_t *)op_reply_q->q_base + reply_ci;
5076 	mpi3mr_dprint(sc, MPI3MR_TRACE, "[QID:%d]:reply_desc: (%pa) reply_ci: %x"
5077 		" reply_desc->ReplyFlags: 0x%x\n"
5078 		"reply_q_base_phys: %#016jx reply_q_base: (%pa) exp_phase: %x\n",
5079 		op_reply_q->qid, reply_desc, reply_ci, reply_desc->ReplyFlags, op_reply_q->q_base_phys,
5080 		op_reply_q->q_base, exp_phase);
5081 
5082 	if (((reply_desc->ReplyFlags &
5083 	     MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase) || !op_reply_q->qid) {
5084 		mtx_lock_spin(&op_reply_q->q_lock);
5085 		op_reply_q->in_use = false;
5086 		mtx_unlock_spin(&op_reply_q->q_lock);
5087 		return 0;
5088 	}
5089 
5090 	do {
5091 		req_qid = reply_desc->RequestQueueID;
5092 		sc->op_req_q[req_qid - 1].ci =
5093 		    reply_desc->RequestQueueCI;
5094 
5095 		mpi3mr_process_op_reply_desc(sc, reply_desc, &reply_dma);
5096 		mpi3mr_atomic_dec(&op_reply_q->pend_ios);
5097 		if (reply_dma)
5098 			mpi3mr_repost_reply_buf(sc, reply_dma);
5099 		num_op_replies++;
5100 		if (++reply_ci == op_reply_q->num_replies) {
5101 			reply_ci = 0;
5102 			exp_phase ^= 1;
5103 		}
5104 		reply_desc =
5105 		    (Mpi3DefaultReplyDescriptor_t *)op_reply_q->q_base + reply_ci;
5106 		if ((reply_desc->ReplyFlags &
5107 		     MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase)
5108 			break;
5109 
5110 		if (++threshold_comps == MPI3MR_THRESHOLD_REPLY_COUNT) {
5111 			mpi3mr_regwrite(sc, MPI3_SYSIF_OPER_REPLY_Q_N_CI_OFFSET(op_reply_q->qid), reply_ci);
5112 			threshold_comps = 0;
5113 		}
5114 
5115 	} while (1);
5116 
5117 
5118 	mpi3mr_regwrite(sc, MPI3_SYSIF_OPER_REPLY_Q_N_CI_OFFSET(op_reply_q->qid), reply_ci);
5119 	op_reply_q->ci = reply_ci;
5120 	op_reply_q->ephase = exp_phase;
5121 	mtx_lock_spin(&op_reply_q->q_lock);
5122 	op_reply_q->in_use = false;
5123 	mtx_unlock_spin(&op_reply_q->q_lock);
5124 	return num_op_replies;
5125 }
5126 
5127 /*
5128  * mpi3mr_isr:			Primary ISR function
5129  * privdata:			Driver's internal per IRQ structure
5130  *
5131  * This is driver's primary ISR function which is being called whenever any admin/IO
5132  * command completion.
5133  */
5134 void mpi3mr_isr(void *privdata)
5135 {
5136 	struct mpi3mr_irq_context *irq_ctx = (struct mpi3mr_irq_context *)privdata;
5137 	struct mpi3mr_softc *sc = irq_ctx->sc;
5138 	U16 msi_idx;
5139 
5140 	if (!irq_ctx)
5141 		return;
5142 
5143 	msi_idx = irq_ctx->msix_index;
5144 
5145 	if (!sc->intr_enabled)
5146 		return;
5147 
5148 	if (!msi_idx)
5149 		mpi3mr_complete_admin_cmd(sc);
5150 
5151 	if (irq_ctx->op_reply_q && irq_ctx->op_reply_q->qid) {
5152 		mpi3mr_complete_io_cmd(sc, irq_ctx);
5153 	}
5154 }
5155 
5156 /*
5157  * mpi3mr_alloc_requests - Allocates host commands
5158  * @sc: Adapter reference
5159  *
5160  * This function allocates controller supported host commands
5161  *
5162  * Return: 0 on success and proper error codes on failure
5163  */
5164 int
5165 mpi3mr_alloc_requests(struct mpi3mr_softc *sc)
5166 {
5167 	struct mpi3mr_cmd *cmd;
5168 	int i, j, nsegs, ret;
5169 
5170 	nsegs = sc->max_sgl_entries;
5171 	ret = bus_dma_tag_create( sc->mpi3mr_parent_dmat,    /* parent */
5172 				1, 0,			/* algnmnt, boundary */
5173 				sc->dma_loaddr,		/* lowaddr */
5174 				BUS_SPACE_MAXADDR,	/* highaddr */
5175 				NULL, NULL,		/* filter, filterarg */
5176 				BUS_SPACE_MAXSIZE,	/* maxsize */
5177                                 nsegs,			/* nsegments */
5178 				BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
5179                                 BUS_DMA_ALLOCNOW,	/* flags */
5180                                 busdma_lock_mutex,	/* lockfunc */
5181 				&sc->io_lock,	/* lockarg */
5182 				&sc->buffer_dmat);
5183 	if (ret) {
5184 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate buffer DMA tag ret: %d\n", ret);
5185 		return (ENOMEM);
5186         }
5187 
5188 	/*
5189 	 * sc->cmd_list is an array of struct mpi3mr_cmd pointers.
5190 	 * Allocate the dynamic array first and then allocate individual
5191 	 * commands.
5192 	 */
5193 	sc->cmd_list = malloc(sizeof(struct mpi3mr_cmd *) * sc->max_host_ios,
5194 	    M_MPI3MR, M_NOWAIT | M_ZERO);
5195 
5196 	if (!sc->cmd_list) {
5197 		device_printf(sc->mpi3mr_dev, "Cannot alloc memory for mpt_cmd_list.\n");
5198 		return (ENOMEM);
5199 	}
5200 
5201 	for (i = 0; i < sc->max_host_ios; i++) {
5202 		sc->cmd_list[i] = malloc(sizeof(struct mpi3mr_cmd),
5203 		    M_MPI3MR, M_NOWAIT | M_ZERO);
5204 		if (!sc->cmd_list[i]) {
5205 			for (j = 0; j < i; j++)
5206 				free(sc->cmd_list[j], M_MPI3MR);
5207 			free(sc->cmd_list, M_MPI3MR);
5208 			sc->cmd_list = NULL;
5209 			return (ENOMEM);
5210 		}
5211 	}
5212 
5213 	for (i = 1; i < sc->max_host_ios; i++) {
5214 		cmd = sc->cmd_list[i];
5215 		cmd->hosttag = i;
5216 		cmd->sc = sc;
5217 		cmd->state = MPI3MR_CMD_STATE_BUSY;
5218 		callout_init_mtx(&cmd->callout, &sc->mpi3mr_mtx, 0);
5219 		cmd->ccb = NULL;
5220 		TAILQ_INSERT_TAIL(&(sc->cmd_list_head), cmd, next);
5221 		if (bus_dmamap_create(sc->buffer_dmat, 0, &cmd->dmamap))
5222 			return ENOMEM;
5223 	}
5224 	return (0);
5225 }
5226 
5227 /*
5228  * mpi3mr_get_command:		Get a coomand structure from free command pool
5229  * @sc:				Adapter soft instance
5230  * Return:			MPT command reference
5231  *
5232  * This function returns an MPT command to the caller.
5233  */
5234 struct mpi3mr_cmd *
5235 mpi3mr_get_command(struct mpi3mr_softc *sc)
5236 {
5237 	struct mpi3mr_cmd *cmd = NULL;
5238 
5239 	mtx_lock(&sc->cmd_pool_lock);
5240 	if (!TAILQ_EMPTY(&sc->cmd_list_head)) {
5241 		cmd = TAILQ_FIRST(&sc->cmd_list_head);
5242 		TAILQ_REMOVE(&sc->cmd_list_head, cmd, next);
5243 	} else {
5244 		goto out;
5245 	}
5246 
5247 	mpi3mr_dprint(sc, MPI3MR_TRACE, "Get command SMID: 0x%x\n", cmd->hosttag);
5248 
5249 	memset((uint8_t *)&cmd->io_request, 0, MPI3MR_AREQ_FRAME_SZ);
5250 	cmd->data_dir = 0;
5251 	cmd->ccb = NULL;
5252 	cmd->targ = NULL;
5253 	cmd->state = MPI3MR_CMD_STATE_BUSY;
5254 	cmd->data = NULL;
5255 	cmd->length = 0;
5256 out:
5257 	mtx_unlock(&sc->cmd_pool_lock);
5258 	return cmd;
5259 }
5260 
5261 /*
5262  * mpi3mr_release_command:	Return a cmd to free command pool
5263  * input:			Command packet for return to free command pool
5264  *
5265  * This function returns an MPT command to the free command list.
5266  */
5267 void
5268 mpi3mr_release_command(struct mpi3mr_cmd *cmd)
5269 {
5270 	struct mpi3mr_softc *sc = cmd->sc;
5271 
5272 	mtx_lock(&sc->cmd_pool_lock);
5273 	TAILQ_INSERT_HEAD(&(sc->cmd_list_head), cmd, next);
5274 	cmd->state = MPI3MR_CMD_STATE_FREE;
5275 	cmd->req_qidx = 0;
5276 	mpi3mr_dprint(sc, MPI3MR_TRACE, "Release command SMID: 0x%x\n", cmd->hosttag);
5277 	mtx_unlock(&sc->cmd_pool_lock);
5278 
5279 	return;
5280 }
5281 
5282  /**
5283  * mpi3mr_free_ioctl_dma_memory - free memory for ioctl dma
5284  * @sc: Adapter instance reference
5285  *
5286  * Free the DMA memory allocated for IOCTL handling purpose.
5287  *
5288  * Return: None
5289  */
5290 static void mpi3mr_free_ioctl_dma_memory(struct mpi3mr_softc *sc)
5291 {
5292 	U16 i;
5293 	struct dma_memory_desc *mem_desc;
5294 
5295 	for (i=0; i<MPI3MR_NUM_IOCTL_SGE; i++) {
5296 		mem_desc = &sc->ioctl_sge[i];
5297 		if (mem_desc->addr && mem_desc->dma_addr) {
5298 			bus_dmamap_unload(mem_desc->tag, mem_desc->dmamap);
5299 			bus_dmamem_free(mem_desc->tag, mem_desc->addr, mem_desc->dmamap);
5300 			mem_desc->addr = NULL;
5301 			if (mem_desc->tag != NULL)
5302 				bus_dma_tag_destroy(mem_desc->tag);
5303 		}
5304 	}
5305 
5306 	mem_desc = &sc->ioctl_chain_sge;
5307 	if (mem_desc->addr && mem_desc->dma_addr) {
5308 		bus_dmamap_unload(mem_desc->tag, mem_desc->dmamap);
5309 		bus_dmamem_free(mem_desc->tag, mem_desc->addr, mem_desc->dmamap);
5310 		mem_desc->addr = NULL;
5311 		if (mem_desc->tag != NULL)
5312 			bus_dma_tag_destroy(mem_desc->tag);
5313 	}
5314 
5315 	mem_desc = &sc->ioctl_resp_sge;
5316 	if (mem_desc->addr && mem_desc->dma_addr) {
5317 		bus_dmamap_unload(mem_desc->tag, mem_desc->dmamap);
5318 		bus_dmamem_free(mem_desc->tag, mem_desc->addr, mem_desc->dmamap);
5319 		mem_desc->addr = NULL;
5320 		if (mem_desc->tag != NULL)
5321 			bus_dma_tag_destroy(mem_desc->tag);
5322 	}
5323 
5324 	sc->ioctl_sges_allocated = false;
5325 }
5326 
5327 /**
5328  * mpi3mr_alloc_ioctl_dma_memory - Alloc memory for ioctl dma
5329  * @sc: Adapter instance reference
5330  *
5331  * This function allocates dmaable memory required to handle the
5332  * application issued MPI3 IOCTL requests.
5333  *
5334  * Return: None
5335  */
5336 void mpi3mr_alloc_ioctl_dma_memory(struct mpi3mr_softc *sc)
5337 {
5338 	struct dma_memory_desc *mem_desc;
5339 	U16 i;
5340 
5341 	for (i=0; i<MPI3MR_NUM_IOCTL_SGE; i++) {
5342 		mem_desc = &sc->ioctl_sge[i];
5343 		mem_desc->size = MPI3MR_IOCTL_SGE_SIZE;
5344 
5345 		if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,    /* parent */
5346 					4, 0,			/* algnmnt, boundary */
5347 					sc->dma_loaddr,		/* lowaddr */
5348 					BUS_SPACE_MAXADDR,	/* highaddr */
5349 					NULL, NULL,		/* filter, filterarg */
5350 					mem_desc->size,		/* maxsize */
5351 					1,			/* nsegments */
5352 					mem_desc->size,		/* maxsegsize */
5353 					0,			/* flags */
5354 					NULL, NULL,		/* lockfunc, lockarg */
5355 					&mem_desc->tag)) {
5356 			mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n");
5357 			goto out_failed;
5358 		}
5359 
5360 		if (bus_dmamem_alloc(mem_desc->tag, (void **)&mem_desc->addr,
5361 		    BUS_DMA_NOWAIT, &mem_desc->dmamap)) {
5362 			mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__);
5363 			goto out_failed;
5364 		}
5365 		bzero(mem_desc->addr, mem_desc->size);
5366 		bus_dmamap_load(mem_desc->tag, mem_desc->dmamap, mem_desc->addr, mem_desc->size,
5367 		    mpi3mr_memaddr_cb, &mem_desc->dma_addr, BUS_DMA_NOWAIT);
5368 
5369 		if (!mem_desc->addr)
5370 			goto out_failed;
5371 	}
5372 
5373 	mem_desc = &sc->ioctl_chain_sge;
5374 	mem_desc->size = MPI3MR_4K_PGSZ;
5375 	if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,    /* parent */
5376 				4, 0,			/* algnmnt, boundary */
5377 				sc->dma_loaddr,		/* lowaddr */
5378 				BUS_SPACE_MAXADDR,	/* highaddr */
5379 				NULL, NULL,		/* filter, filterarg */
5380 				mem_desc->size,		/* maxsize */
5381 				1,			/* nsegments */
5382 				mem_desc->size,		/* maxsegsize */
5383 				0,			/* flags */
5384 				NULL, NULL,		/* lockfunc, lockarg */
5385 				&mem_desc->tag)) {
5386 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n");
5387 		goto out_failed;
5388 	}
5389 
5390 	if (bus_dmamem_alloc(mem_desc->tag, (void **)&mem_desc->addr,
5391 	    BUS_DMA_NOWAIT, &mem_desc->dmamap)) {
5392 		mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__);
5393 		goto out_failed;
5394 	}
5395 	bzero(mem_desc->addr, mem_desc->size);
5396 	bus_dmamap_load(mem_desc->tag, mem_desc->dmamap, mem_desc->addr, mem_desc->size,
5397 	    mpi3mr_memaddr_cb, &mem_desc->dma_addr, BUS_DMA_NOWAIT);
5398 
5399 	if (!mem_desc->addr)
5400 		goto out_failed;
5401 
5402 	mem_desc = &sc->ioctl_resp_sge;
5403 	mem_desc->size = MPI3MR_4K_PGSZ;
5404 	if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,    /* parent */
5405 				4, 0,			/* algnmnt, boundary */
5406 				sc->dma_loaddr,		/* lowaddr */
5407 				BUS_SPACE_MAXADDR,	/* highaddr */
5408 				NULL, NULL,		/* filter, filterarg */
5409 				mem_desc->size,		/* maxsize */
5410 				1,			/* nsegments */
5411 				mem_desc->size,		/* maxsegsize */
5412 				0,			/* flags */
5413 				NULL, NULL,		/* lockfunc, lockarg */
5414 				&mem_desc->tag)) {
5415 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n");
5416 		goto out_failed;
5417 	}
5418 
5419 	if (bus_dmamem_alloc(mem_desc->tag, (void **)&mem_desc->addr,
5420 	    BUS_DMA_NOWAIT, &mem_desc->dmamap)) {
5421 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate replies memory\n");
5422 		goto out_failed;
5423 	}
5424 	bzero(mem_desc->addr, mem_desc->size);
5425 	bus_dmamap_load(mem_desc->tag, mem_desc->dmamap, mem_desc->addr, mem_desc->size,
5426 	    mpi3mr_memaddr_cb, &mem_desc->dma_addr, BUS_DMA_NOWAIT);
5427 
5428 	if (!mem_desc->addr)
5429 		goto out_failed;
5430 
5431 	sc->ioctl_sges_allocated = true;
5432 
5433 	return;
5434 out_failed:
5435 	printf("cannot allocate DMA memory for the mpt commands"
5436 	    "  from the applications, application interface for MPT command is disabled\n");
5437 	mpi3mr_free_ioctl_dma_memory(sc);
5438 }
5439 
5440 static void inline
5441 mpi3mr_free_dma_mem(struct mpi3mr_softc *sc,
5442 		    struct dma_memory_desc *mem_desc)
5443 {
5444 	if (mem_desc->dma_addr)
5445 		bus_dmamap_unload(mem_desc->tag, mem_desc->dmamap);
5446 
5447 	if (mem_desc->addr != NULL) {
5448 		bus_dmamem_free(mem_desc->tag, mem_desc->addr, mem_desc->dmamap);
5449 		mem_desc->addr = NULL;
5450 	}
5451 
5452 	if (mem_desc->tag != NULL)
5453 		bus_dma_tag_destroy(mem_desc->tag);
5454 }
5455 
5456 static int
5457 mpi3mr_alloc_dma_mem(struct mpi3mr_softc *sc,
5458 		     struct dma_memory_desc *mem_desc)
5459 {
5460 	int retval;
5461 
5462 	if (bus_dma_tag_create(sc->mpi3mr_parent_dmat,  /* parent */
5463 				4, 0,			/* algnmnt, boundary */
5464 				sc->dma_loaddr,		/* lowaddr */
5465 				sc->dma_hiaddr,		/* highaddr */
5466 				NULL, NULL,		/* filter, filterarg */
5467 				mem_desc->size,		/* maxsize */
5468 				1,			/* nsegments */
5469 				mem_desc->size,		/* maxsize */
5470 				0,			/* flags */
5471 				NULL, NULL,		/* lockfunc, lockarg */
5472 				&mem_desc->tag)) {
5473 		mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate DMA tag\n", __func__);
5474 		return ENOMEM;
5475 	}
5476 
5477 	if (bus_dmamem_alloc(mem_desc->tag, (void **)&mem_desc->addr,
5478 			     BUS_DMA_NOWAIT, &mem_desc->dmamap)) {
5479 		mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate DMA memory\n", __func__);
5480 		retval = ENOMEM;
5481 		goto out;
5482 	}
5483 
5484 	bzero(mem_desc->addr, mem_desc->size);
5485 
5486 	bus_dmamap_load(mem_desc->tag, mem_desc->dmamap, mem_desc->addr, mem_desc->size,
5487 			mpi3mr_memaddr_cb, &mem_desc->dma_addr, BUS_DMA_NOWAIT);
5488 
5489 	if (!mem_desc->addr) {
5490 		mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot load DMA map\n", __func__);
5491 		retval = ENOMEM;
5492 		goto out;
5493 	}
5494 	return 0;
5495 out:
5496 	mpi3mr_free_dma_mem(sc, mem_desc);
5497 	return retval;
5498 }
5499 
5500 static int
5501 mpi3mr_post_cfg_req(struct mpi3mr_softc *sc, Mpi3ConfigRequest_t *cfg_req)
5502 {
5503 	int retval;
5504 
5505 	mtx_lock(&sc->cfg_cmds.completion.lock);
5506 	if (sc->cfg_cmds.state & MPI3MR_CMD_PENDING) {
5507 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Issue cfg request: cfg command is in use\n");
5508 		mtx_unlock(&sc->cfg_cmds.completion.lock);
5509 		return -1;
5510 	}
5511 
5512 	sc->cfg_cmds.state = MPI3MR_CMD_PENDING;
5513 	sc->cfg_cmds.is_waiting = 1;
5514 	sc->cfg_cmds.callback = NULL;
5515 	sc->cfg_cmds.ioc_status = 0;
5516 	sc->cfg_cmds.ioc_loginfo = 0;
5517 
5518 	cfg_req->HostTag = htole16(MPI3MR_HOSTTAG_CFGCMDS);
5519 	cfg_req->Function = MPI3_FUNCTION_CONFIG;
5520 	cfg_req->PageType = MPI3_CONFIG_PAGETYPE_DRIVER;
5521 	cfg_req->PageNumber = 1;
5522 	cfg_req->PageAddress = 0;
5523 
5524 	init_completion(&sc->cfg_cmds.completion);
5525 
5526 	retval = mpi3mr_submit_admin_cmd(sc, cfg_req, sizeof(*cfg_req));
5527 	if (retval) {
5528 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Issue cfg request: Admin Post failed\n");
5529 		goto out;
5530 	}
5531 
5532 	wait_for_completion_timeout(&sc->cfg_cmds.completion,
5533 				   (MPI3MR_INTADMCMD_TIMEOUT));
5534 
5535 	if (!(sc->cfg_cmds.state & MPI3MR_CMD_COMPLETE)) {
5536 		if (!(sc->cfg_cmds.state & MPI3MR_CMD_RESET)) {
5537 			mpi3mr_dprint(sc, MPI3MR_ERROR, "config request command timed out\n");
5538 			mpi3mr_check_rh_fault_ioc(sc, MPI3MR_RESET_FROM_CFG_REQ_TIMEOUT);
5539 		}
5540 		retval = -1;
5541 		sc->cfg_cmds.is_waiting = 0;
5542 		goto out;
5543 	}
5544 
5545 	if ((sc->cfg_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK) !=
5546 	     MPI3_IOCSTATUS_SUCCESS ) {
5547 		mpi3mr_dprint(sc, MPI3MR_ERROR, "config request failed, IOCStatus(0x%04x) "
5548 			      " Loginfo(0x%08x) \n",(sc->cfg_cmds.ioc_status &
5549 			      MPI3_IOCSTATUS_STATUS_MASK), sc->cfg_cmds.ioc_loginfo);
5550 		retval = -1;
5551 	}
5552 
5553 out:
5554 	sc->cfg_cmds.state = MPI3MR_CMD_NOTUSED;
5555 	mtx_unlock(&sc->cfg_cmds.completion.lock);
5556 	return retval;
5557 }
5558 
5559 static int mpi3mr_process_cfg_req(struct mpi3mr_softc *sc,
5560 				  Mpi3ConfigRequest_t *cfg_req,
5561 				  Mpi3ConfigPageHeader_t *cfg_hdr,
5562 				  void *cfg_buf, U32 cfg_buf_sz)
5563 {
5564 	int retval;
5565 	struct dma_memory_desc mem_desc = {0};
5566 
5567 	if (cfg_req->Action == MPI3_CONFIG_ACTION_PAGE_HEADER)
5568 		mem_desc.size = sizeof(Mpi3ConfigPageHeader_t);
5569 	else {
5570 		mem_desc.size = le16toh(cfg_hdr->PageLength) * 4;
5571 		cfg_req->PageLength = cfg_hdr->PageLength;
5572 		cfg_req->PageVersion = cfg_hdr->PageVersion;
5573 	}
5574 
5575 	retval = mpi3mr_alloc_dma_mem(sc, &mem_desc);
5576 	if (retval) {
5577 		mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Failed to allocate DMA memory\n", __func__);
5578 		return retval;
5579 	}
5580 
5581 	mpi3mr_add_sg_single(&cfg_req->SGL, MPI3MR_SGEFLAGS_SYSTEM_SIMPLE_END_OF_LIST,
5582 			     mem_desc.size, mem_desc.dma_addr);
5583 
5584 	retval = mpi3mr_post_cfg_req(sc, cfg_req);
5585 	if (retval)
5586 		mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Failed to post config request\n", __func__);
5587 	else
5588 		memcpy(cfg_buf, mem_desc.addr, min(mem_desc.size, cfg_buf_sz));
5589 
5590 	mpi3mr_free_dma_mem(sc, &mem_desc);
5591 	return retval;
5592 }
5593 
5594 int mpi3mr_cfg_get_driver_pg1(struct mpi3mr_softc *sc)
5595 {
5596 	int retval;
5597 	Mpi3DriverPage1_t driver_pg1 = {0};
5598 	Mpi3ConfigPageHeader_t cfg_hdr = {0};
5599 	Mpi3ConfigRequest_t cfg_req = {0};
5600 
5601 	cfg_req.Action = MPI3_CONFIG_ACTION_PAGE_HEADER;
5602 	retval = mpi3mr_process_cfg_req(sc, &cfg_req, NULL, &cfg_hdr, sizeof(cfg_hdr));
5603 	if (retval)
5604 		goto error;
5605 
5606 	cfg_req.Action = MPI3_CONFIG_ACTION_READ_CURRENT;
5607 	retval = mpi3mr_process_cfg_req(sc, &cfg_req, &cfg_hdr, &driver_pg1, sizeof(driver_pg1));
5608 
5609 error:
5610 	if (!retval && driver_pg1.TimeStampUpdate)
5611 		sc->ts_update_interval = driver_pg1.TimeStampUpdate;
5612 	else
5613 		sc->ts_update_interval = MPI3MR_TSUPDATE_INTERVAL;
5614 
5615 	return retval;
5616 }
5617 
5618 void
5619 mpi3mr_destory_mtx(struct mpi3mr_softc *sc)
5620 {
5621 	int i;
5622 	struct mpi3mr_op_req_queue *op_req_q;
5623 	struct mpi3mr_op_reply_queue *op_reply_q;
5624 
5625 	if (sc->admin_reply) {
5626 		if (mtx_initialized(&sc->admin_reply_lock))
5627 			mtx_destroy(&sc->admin_reply_lock);
5628 	}
5629 
5630 	if (sc->op_reply_q) {
5631 		for(i = 0; i < sc->num_queues; i++) {
5632 			op_reply_q = sc->op_reply_q + i;
5633 			if (mtx_initialized(&op_reply_q->q_lock))
5634 				mtx_destroy(&op_reply_q->q_lock);
5635 		}
5636 	}
5637 
5638 	if (sc->op_req_q) {
5639 		for(i = 0; i < sc->num_queues; i++) {
5640 			op_req_q = sc->op_req_q + i;
5641 			if (mtx_initialized(&op_req_q->q_lock))
5642 				mtx_destroy(&op_req_q->q_lock);
5643 		}
5644 	}
5645 
5646 	if (mtx_initialized(&sc->init_cmds.completion.lock))
5647 		mtx_destroy(&sc->init_cmds.completion.lock);
5648 
5649 	if (mtx_initialized(&sc->cfg_cmds.completion.lock))
5650 		mtx_destroy(&sc->cfg_cmds.completion.lock);
5651 
5652 	if (mtx_initialized(&sc->ioctl_cmds.completion.lock))
5653 		mtx_destroy(&sc->ioctl_cmds.completion.lock);
5654 
5655 	if (mtx_initialized(&sc->host_tm_cmds.completion.lock))
5656 		mtx_destroy(&sc->host_tm_cmds.completion.lock);
5657 
5658 	for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) {
5659 		if (mtx_initialized(&sc->dev_rmhs_cmds[i].completion.lock))
5660 			mtx_destroy(&sc->dev_rmhs_cmds[i].completion.lock);
5661 	}
5662 
5663 	if (mtx_initialized(&sc->reset_mutex))
5664 		mtx_destroy(&sc->reset_mutex);
5665 
5666 	if (mtx_initialized(&sc->target_lock))
5667 		mtx_destroy(&sc->target_lock);
5668 
5669 	if (mtx_initialized(&sc->fwevt_lock))
5670 		mtx_destroy(&sc->fwevt_lock);
5671 
5672 	if (mtx_initialized(&sc->cmd_pool_lock))
5673 		mtx_destroy(&sc->cmd_pool_lock);
5674 
5675 	if (mtx_initialized(&sc->reply_free_q_lock))
5676 		mtx_destroy(&sc->reply_free_q_lock);
5677 
5678 	if (mtx_initialized(&sc->sense_buf_q_lock))
5679 		mtx_destroy(&sc->sense_buf_q_lock);
5680 
5681 	if (mtx_initialized(&sc->chain_buf_lock))
5682 		mtx_destroy(&sc->chain_buf_lock);
5683 
5684 	if (mtx_initialized(&sc->admin_req_lock))
5685 		mtx_destroy(&sc->admin_req_lock);
5686 
5687 	if (mtx_initialized(&sc->mpi3mr_mtx))
5688 		mtx_destroy(&sc->mpi3mr_mtx);
5689 }
5690 
5691 /**
5692  * mpi3mr_free_mem - Freeup adapter level data structures
5693  * @sc: Adapter reference
5694  *
5695  * Return: Nothing.
5696  */
5697 void
5698 mpi3mr_free_mem(struct mpi3mr_softc *sc)
5699 {
5700 	int i;
5701 	struct mpi3mr_op_req_queue *op_req_q;
5702 	struct mpi3mr_op_reply_queue *op_reply_q;
5703 	struct mpi3mr_irq_context *irq_ctx;
5704 
5705 	if (sc->cmd_list) {
5706 		for (i = 0; i < sc->max_host_ios; i++) {
5707 			free(sc->cmd_list[i], M_MPI3MR);
5708 		}
5709 		free(sc->cmd_list, M_MPI3MR);
5710 		sc->cmd_list = NULL;
5711 	}
5712 
5713 	if (sc->pel_seq_number && sc->pel_seq_number_dma) {
5714 		bus_dmamap_unload(sc->pel_seq_num_dmatag, sc->pel_seq_num_dmamap);
5715 		bus_dmamem_free(sc->pel_seq_num_dmatag, sc->pel_seq_number, sc->pel_seq_num_dmamap);
5716 		sc->pel_seq_number = NULL;
5717 		if (sc->pel_seq_num_dmatag != NULL)
5718 			bus_dma_tag_destroy(sc->pel_seq_num_dmatag);
5719 	}
5720 
5721 	if (sc->throttle_groups) {
5722 		free(sc->throttle_groups, M_MPI3MR);
5723 		sc->throttle_groups = NULL;
5724 	}
5725 
5726 	/* Free up operational queues*/
5727 	if (sc->op_req_q) {
5728 		for (i = 0; i < sc->num_queues; i++) {
5729 			op_req_q = sc->op_req_q + i;
5730 			if (op_req_q->q_base && op_req_q->q_base_phys) {
5731 				bus_dmamap_unload(op_req_q->q_base_tag, op_req_q->q_base_dmamap);
5732 				bus_dmamem_free(op_req_q->q_base_tag, op_req_q->q_base, op_req_q->q_base_dmamap);
5733 				op_req_q->q_base = NULL;
5734 				if (op_req_q->q_base_tag != NULL)
5735 					bus_dma_tag_destroy(op_req_q->q_base_tag);
5736 			}
5737 		}
5738 		free(sc->op_req_q, M_MPI3MR);
5739 		sc->op_req_q = NULL;
5740 	}
5741 
5742 	if (sc->op_reply_q) {
5743 		for (i = 0; i < sc->num_queues; i++) {
5744 			op_reply_q = sc->op_reply_q + i;
5745 			if (op_reply_q->q_base && op_reply_q->q_base_phys) {
5746 				bus_dmamap_unload(op_reply_q->q_base_tag, op_reply_q->q_base_dmamap);
5747 				bus_dmamem_free(op_reply_q->q_base_tag, op_reply_q->q_base, op_reply_q->q_base_dmamap);
5748 				op_reply_q->q_base = NULL;
5749 				if (op_reply_q->q_base_tag != NULL)
5750 					bus_dma_tag_destroy(op_reply_q->q_base_tag);
5751 			}
5752 		}
5753 		free(sc->op_reply_q, M_MPI3MR);
5754 		sc->op_reply_q = NULL;
5755 	}
5756 
5757 	/* Free up chain buffers*/
5758 	if (sc->chain_sgl_list) {
5759 		for (i = 0; i < sc->chain_buf_count; i++) {
5760 			if (sc->chain_sgl_list[i].buf && sc->chain_sgl_list[i].buf_phys) {
5761 				bus_dmamap_unload(sc->chain_sgl_list_tag, sc->chain_sgl_list[i].buf_dmamap);
5762 				bus_dmamem_free(sc->chain_sgl_list_tag, sc->chain_sgl_list[i].buf,
5763 						sc->chain_sgl_list[i].buf_dmamap);
5764 				sc->chain_sgl_list[i].buf = NULL;
5765 			}
5766 		}
5767 		if (sc->chain_sgl_list_tag != NULL)
5768 			bus_dma_tag_destroy(sc->chain_sgl_list_tag);
5769 		free(sc->chain_sgl_list, M_MPI3MR);
5770 		sc->chain_sgl_list = NULL;
5771 	}
5772 
5773 	if (sc->chain_bitmap) {
5774 		free(sc->chain_bitmap, M_MPI3MR);
5775 		sc->chain_bitmap = NULL;
5776 	}
5777 
5778 	for (i = 0; i < sc->msix_count; i++) {
5779 		irq_ctx = sc->irq_ctx + i;
5780 		if (irq_ctx)
5781 			irq_ctx->op_reply_q = NULL;
5782 	}
5783 
5784 	/* Free reply_buf_tag */
5785 	if (sc->reply_buf && sc->reply_buf_phys) {
5786 		bus_dmamap_unload(sc->reply_buf_tag, sc->reply_buf_dmamap);
5787 		bus_dmamem_free(sc->reply_buf_tag, sc->reply_buf,
5788 				sc->reply_buf_dmamap);
5789 		sc->reply_buf = NULL;
5790 		if (sc->reply_buf_tag != NULL)
5791 			bus_dma_tag_destroy(sc->reply_buf_tag);
5792 	}
5793 
5794 	/* Free reply_free_q_tag */
5795 	if (sc->reply_free_q && sc->reply_free_q_phys) {
5796 		bus_dmamap_unload(sc->reply_free_q_tag, sc->reply_free_q_dmamap);
5797 		bus_dmamem_free(sc->reply_free_q_tag, sc->reply_free_q,
5798 				sc->reply_free_q_dmamap);
5799 		sc->reply_free_q = NULL;
5800 		if (sc->reply_free_q_tag != NULL)
5801 			bus_dma_tag_destroy(sc->reply_free_q_tag);
5802 	}
5803 
5804 	/* Free sense_buf_tag */
5805 	if (sc->sense_buf && sc->sense_buf_phys) {
5806 		bus_dmamap_unload(sc->sense_buf_tag, sc->sense_buf_dmamap);
5807 		bus_dmamem_free(sc->sense_buf_tag, sc->sense_buf,
5808 				sc->sense_buf_dmamap);
5809 		sc->sense_buf = NULL;
5810 		if (sc->sense_buf_tag != NULL)
5811 			bus_dma_tag_destroy(sc->sense_buf_tag);
5812 	}
5813 
5814 	/* Free sense_buf_q_tag */
5815 	if (sc->sense_buf_q && sc->sense_buf_q_phys) {
5816 		bus_dmamap_unload(sc->sense_buf_q_tag, sc->sense_buf_q_dmamap);
5817 		bus_dmamem_free(sc->sense_buf_q_tag, sc->sense_buf_q,
5818 				sc->sense_buf_q_dmamap);
5819 		sc->sense_buf_q = NULL;
5820 		if (sc->sense_buf_q_tag != NULL)
5821 			bus_dma_tag_destroy(sc->sense_buf_q_tag);
5822 	}
5823 
5824 	/* Free up internal(non-IO) commands*/
5825 	if (sc->init_cmds.reply) {
5826 		free(sc->init_cmds.reply, M_MPI3MR);
5827 		sc->init_cmds.reply = NULL;
5828 	}
5829 
5830 	if (sc->cfg_cmds.reply) {
5831 		free(sc->cfg_cmds.reply, M_MPI3MR);
5832 		sc->cfg_cmds.reply = NULL;
5833 	}
5834 
5835 	if (sc->ioctl_cmds.reply) {
5836 		free(sc->ioctl_cmds.reply, M_MPI3MR);
5837 		sc->ioctl_cmds.reply = NULL;
5838 	}
5839 
5840 	if (sc->pel_cmds.reply) {
5841 		free(sc->pel_cmds.reply, M_MPI3MR);
5842 		sc->pel_cmds.reply = NULL;
5843 	}
5844 
5845 	if (sc->pel_abort_cmd.reply) {
5846 		free(sc->pel_abort_cmd.reply, M_MPI3MR);
5847 		sc->pel_abort_cmd.reply = NULL;
5848 	}
5849 
5850 	if (sc->host_tm_cmds.reply) {
5851 		free(sc->host_tm_cmds.reply, M_MPI3MR);
5852 		sc->host_tm_cmds.reply = NULL;
5853 	}
5854 
5855 	if (sc->log_data_buffer) {
5856 		free(sc->log_data_buffer, M_MPI3MR);
5857 		sc->log_data_buffer = NULL;
5858 	}
5859 
5860 	for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) {
5861 		if (sc->dev_rmhs_cmds[i].reply) {
5862 			free(sc->dev_rmhs_cmds[i].reply, M_MPI3MR);
5863 			sc->dev_rmhs_cmds[i].reply = NULL;
5864 		}
5865 	}
5866 
5867 	for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++) {
5868 		if (sc->evtack_cmds[i].reply) {
5869 			free(sc->evtack_cmds[i].reply, M_MPI3MR);
5870 			sc->evtack_cmds[i].reply = NULL;
5871 		}
5872 	}
5873 
5874 	if (sc->removepend_bitmap) {
5875 		free(sc->removepend_bitmap, M_MPI3MR);
5876 		sc->removepend_bitmap = NULL;
5877 	}
5878 
5879 	if (sc->devrem_bitmap) {
5880 		free(sc->devrem_bitmap, M_MPI3MR);
5881 		sc->devrem_bitmap = NULL;
5882 	}
5883 
5884 	if (sc->evtack_cmds_bitmap) {
5885 		free(sc->evtack_cmds_bitmap, M_MPI3MR);
5886 		sc->evtack_cmds_bitmap = NULL;
5887 	}
5888 
5889 	/* Free Admin reply*/
5890 	if (sc->admin_reply && sc->admin_reply_phys) {
5891 		bus_dmamap_unload(sc->admin_reply_tag, sc->admin_reply_dmamap);
5892 		bus_dmamem_free(sc->admin_reply_tag, sc->admin_reply,
5893 				sc->admin_reply_dmamap);
5894 		sc->admin_reply = NULL;
5895 		if (sc->admin_reply_tag != NULL)
5896 			bus_dma_tag_destroy(sc->admin_reply_tag);
5897 	}
5898 
5899 	/* Free Admin request*/
5900 	if (sc->admin_req && sc->admin_req_phys) {
5901 		bus_dmamap_unload(sc->admin_req_tag, sc->admin_req_dmamap);
5902 		bus_dmamem_free(sc->admin_req_tag, sc->admin_req,
5903 				sc->admin_req_dmamap);
5904 		sc->admin_req = NULL;
5905 		if (sc->admin_req_tag != NULL)
5906 			bus_dma_tag_destroy(sc->admin_req_tag);
5907 	}
5908 	mpi3mr_free_ioctl_dma_memory(sc);
5909 
5910 }
5911 
5912 /**
5913  * mpi3mr_drv_cmd_comp_reset - Flush a internal driver command
5914  * @sc: Adapter instance reference
5915  * @cmdptr: Internal command tracker
5916  *
5917  * Complete an internal driver commands with state indicating it
5918  * is completed due to reset.
5919  *
5920  * Return: Nothing.
5921  */
5922 static inline void mpi3mr_drv_cmd_comp_reset(struct mpi3mr_softc *sc,
5923 	struct mpi3mr_drvr_cmd *cmdptr)
5924 {
5925 	if (cmdptr->state & MPI3MR_CMD_PENDING) {
5926 		cmdptr->state |= MPI3MR_CMD_RESET;
5927 		cmdptr->state &= ~MPI3MR_CMD_PENDING;
5928 		if (cmdptr->is_waiting) {
5929 			complete(&cmdptr->completion);
5930 			cmdptr->is_waiting = 0;
5931 		} else if (cmdptr->callback)
5932 			cmdptr->callback(sc, cmdptr);
5933 	}
5934 }
5935 
5936 /**
5937  * mpi3mr_flush_drv_cmds - Flush internal driver commands
5938  * @sc: Adapter instance reference
5939  *
5940  * Flush all internal driver commands post reset
5941  *
5942  * Return: Nothing.
5943  */
5944 static void mpi3mr_flush_drv_cmds(struct mpi3mr_softc *sc)
5945 {
5946 	int i = 0;
5947 	struct mpi3mr_drvr_cmd *cmdptr;
5948 
5949 	cmdptr = &sc->init_cmds;
5950 	mpi3mr_drv_cmd_comp_reset(sc, cmdptr);
5951 
5952 	cmdptr = &sc->cfg_cmds;
5953 	mpi3mr_drv_cmd_comp_reset(sc, cmdptr);
5954 
5955 	cmdptr = &sc->ioctl_cmds;
5956 	mpi3mr_drv_cmd_comp_reset(sc, cmdptr);
5957 
5958 	cmdptr = &sc->host_tm_cmds;
5959 	mpi3mr_drv_cmd_comp_reset(sc, cmdptr);
5960 
5961 	for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) {
5962 		cmdptr = &sc->dev_rmhs_cmds[i];
5963 		mpi3mr_drv_cmd_comp_reset(sc, cmdptr);
5964 	}
5965 
5966 	for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++) {
5967 		cmdptr = &sc->evtack_cmds[i];
5968 		mpi3mr_drv_cmd_comp_reset(sc, cmdptr);
5969 	}
5970 
5971 	cmdptr = &sc->pel_cmds;
5972 	mpi3mr_drv_cmd_comp_reset(sc, cmdptr);
5973 
5974 	cmdptr = &sc->pel_abort_cmd;
5975 	mpi3mr_drv_cmd_comp_reset(sc, cmdptr);
5976 }
5977 
5978 
5979 /**
5980  * mpi3mr_memset_buffers - memset memory for a controller
5981  * @sc: Adapter instance reference
5982  *
5983  * clear all the memory allocated for a controller, typically
5984  * called post reset to reuse the memory allocated during the
5985  * controller init.
5986  *
5987  * Return: Nothing.
5988  */
5989 static void mpi3mr_memset_buffers(struct mpi3mr_softc *sc)
5990 {
5991 	U16 i;
5992 	struct mpi3mr_throttle_group_info *tg;
5993 
5994 	memset(sc->admin_req, 0, sc->admin_req_q_sz);
5995 	memset(sc->admin_reply, 0, sc->admin_reply_q_sz);
5996 
5997 	memset(sc->init_cmds.reply, 0, sc->reply_sz);
5998 	memset(sc->cfg_cmds.reply, 0, sc->reply_sz);
5999 	memset(sc->ioctl_cmds.reply, 0, sc->reply_sz);
6000 	memset(sc->host_tm_cmds.reply, 0, sc->reply_sz);
6001 	memset(sc->pel_cmds.reply, 0, sc->reply_sz);
6002 	memset(sc->pel_abort_cmd.reply, 0, sc->reply_sz);
6003 	for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++)
6004 		memset(sc->dev_rmhs_cmds[i].reply, 0, sc->reply_sz);
6005 	for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++)
6006 		memset(sc->evtack_cmds[i].reply, 0, sc->reply_sz);
6007 	memset(sc->removepend_bitmap, 0, sc->dev_handle_bitmap_sz);
6008 	memset(sc->devrem_bitmap, 0, sc->devrem_bitmap_sz);
6009 	memset(sc->evtack_cmds_bitmap, 0, sc->evtack_cmds_bitmap_sz);
6010 
6011 	for (i = 0; i < sc->num_queues; i++) {
6012 		sc->op_reply_q[i].qid = 0;
6013 		sc->op_reply_q[i].ci = 0;
6014 		sc->op_reply_q[i].num_replies = 0;
6015 		sc->op_reply_q[i].ephase = 0;
6016 		mpi3mr_atomic_set(&sc->op_reply_q[i].pend_ios, 0);
6017 		memset(sc->op_reply_q[i].q_base, 0, sc->op_reply_q[i].qsz);
6018 
6019 		sc->op_req_q[i].ci = 0;
6020 		sc->op_req_q[i].pi = 0;
6021 		sc->op_req_q[i].num_reqs = 0;
6022 		sc->op_req_q[i].qid = 0;
6023 		sc->op_req_q[i].reply_qid = 0;
6024 		memset(sc->op_req_q[i].q_base, 0, sc->op_req_q[i].qsz);
6025 	}
6026 
6027 	mpi3mr_atomic_set(&sc->pend_large_data_sz, 0);
6028 	if (sc->throttle_groups) {
6029 		tg = sc->throttle_groups;
6030 		for (i = 0; i < sc->num_io_throttle_group; i++, tg++) {
6031 			tg->id = 0;
6032 			tg->fw_qd = 0;
6033 			tg->modified_qd = 0;
6034 			tg->io_divert= 0;
6035 			tg->high = 0;
6036 			tg->low = 0;
6037 			mpi3mr_atomic_set(&tg->pend_large_data_sz, 0);
6038 		}
6039  	}
6040 }
6041 
6042 /**
6043  * mpi3mr_invalidate_devhandles -Invalidate device handles
6044  * @sc: Adapter instance reference
6045  *
6046  * Invalidate the device handles in the target device structures
6047  * . Called post reset prior to reinitializing the controller.
6048  *
6049  * Return: Nothing.
6050  */
6051 static void mpi3mr_invalidate_devhandles(struct mpi3mr_softc *sc)
6052 {
6053 	struct mpi3mr_target *target = NULL;
6054 
6055 	mtx_lock_spin(&sc->target_lock);
6056 	TAILQ_FOREACH(target, &sc->cam_sc->tgt_list, tgt_next) {
6057 		if (target) {
6058 			target->dev_handle = MPI3MR_INVALID_DEV_HANDLE;
6059 			target->io_throttle_enabled = 0;
6060 			target->io_divert = 0;
6061 			target->throttle_group = NULL;
6062 			target->ws_len = 0;
6063 		}
6064 	}
6065 	mtx_unlock_spin(&sc->target_lock);
6066 }
6067 
6068 /**
6069  * mpi3mr_rfresh_tgtdevs - Refresh target device exposure
6070  * @sc: Adapter instance reference
6071  *
6072  * This is executed post controller reset to identify any
6073  * missing devices during reset and remove from the upper layers
6074  * or expose any newly detected device to the upper layers.
6075  *
6076  * Return: Nothing.
6077  */
6078 
6079 static void mpi3mr_rfresh_tgtdevs(struct mpi3mr_softc *sc)
6080 {
6081 	struct mpi3mr_target *target = NULL;
6082 	struct mpi3mr_target *target_temp = NULL;
6083 
6084 	TAILQ_FOREACH_SAFE(target, &sc->cam_sc->tgt_list, tgt_next, target_temp) {
6085 		if (target->dev_handle == MPI3MR_INVALID_DEV_HANDLE) {
6086 			if (target->exposed_to_os)
6087 				mpi3mr_remove_device_from_os(sc, target->dev_handle);
6088 			mpi3mr_remove_device_from_list(sc, target, true);
6089 		} else if (target->is_hidden && target->exposed_to_os) {
6090 				mpi3mr_remove_device_from_os(sc, target->dev_handle);
6091 		}
6092 	}
6093 
6094 	TAILQ_FOREACH(target, &sc->cam_sc->tgt_list, tgt_next) {
6095 		if ((target->dev_handle != MPI3MR_INVALID_DEV_HANDLE) &&
6096 		    !target->is_hidden && !target->exposed_to_os) {
6097 			mpi3mr_add_device(sc, target->per_id);
6098 		}
6099 	}
6100 
6101 }
6102 
6103 static void mpi3mr_flush_io(struct mpi3mr_softc *sc)
6104 {
6105 	int i;
6106 	struct mpi3mr_cmd *cmd = NULL;
6107 	union ccb *ccb = NULL;
6108 
6109 	for (i = 0; i < sc->max_host_ios; i++) {
6110 		cmd = sc->cmd_list[i];
6111 
6112 		if (cmd && cmd->ccb) {
6113 			if (cmd->callout_owner) {
6114 				ccb = (union ccb *)(cmd->ccb);
6115 				ccb->ccb_h.status = CAM_SCSI_BUS_RESET;
6116 				mpi3mr_atomic_dec(&sc->fw_outstanding);
6117 				mpi3mr_atomic_dec(&cmd->targ->outstanding);
6118 				mpi3mr_cmd_done(sc, cmd);
6119 			} else {
6120 				cmd->ccb = NULL;
6121 				mpi3mr_release_command(cmd);
6122 			}
6123 		}
6124 	}
6125 }
6126 
6127 /**
6128  * mpi3mr_set_diagsave - Set diag save bit for snapdump
6129  * @sc: Adapter reference
6130  *
6131  * Set diag save bit in IOC configuration register to enable
6132  * snapdump.
6133  *
6134  * Return: Nothing.
6135  */
6136 static inline void mpi3mr_set_diagsave(struct mpi3mr_softc *sc)
6137 {
6138 	U32 ioc_config;
6139 
6140 	ioc_config =
6141 	    mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET);
6142 	ioc_config |= MPI3_SYSIF_IOC_CONFIG_DIAG_SAVE;
6143 	mpi3mr_regwrite(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET, ioc_config);
6144 }
6145 
6146 /**
6147  * mpi3mr_issue_reset - Issue reset to the controller
6148  * @sc: Adapter reference
6149  * @reset_type: Reset type
6150  * @reset_reason: Reset reason code
6151  *
6152  * Unlock the host diagnostic registers and write the specific
6153  * reset type to that, wait for reset acknowledgement from the
6154  * controller, if the reset is not successful retry for the
6155  * predefined number of times.
6156  *
6157  * Return: 0 on success, non-zero on failure.
6158  */
6159 static int mpi3mr_issue_reset(struct mpi3mr_softc *sc, U16 reset_type,
6160 	U16 reset_reason)
6161 {
6162 	int retval = -1;
6163 	U8 unlock_retry_count = 0;
6164 	U32 host_diagnostic, ioc_status, ioc_config, scratch_pad0;
6165 	U32 timeout = MPI3MR_RESET_ACK_TIMEOUT * 10;
6166 
6167 	if ((reset_type != MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET) &&
6168 	    (reset_type != MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT))
6169 		return retval;
6170 	if (sc->unrecoverable)
6171 		return retval;
6172 
6173 	if (reset_reason == MPI3MR_RESET_FROM_FIRMWARE) {
6174 		retval = 0;
6175 		return retval;
6176 	}
6177 
6178 	mpi3mr_dprint(sc, MPI3MR_INFO, "%s reset due to %s(0x%x)\n",
6179 	    mpi3mr_reset_type_name(reset_type),
6180 	    mpi3mr_reset_rc_name(reset_reason), reset_reason);
6181 
6182 	mpi3mr_clear_reset_history(sc);
6183 	do {
6184 		mpi3mr_dprint(sc, MPI3MR_INFO,
6185 		    "Write magic sequence to unlock host diag register (retry=%d)\n",
6186 		    ++unlock_retry_count);
6187 		if (unlock_retry_count >= MPI3MR_HOSTDIAG_UNLOCK_RETRY_COUNT) {
6188 			mpi3mr_dprint(sc, MPI3MR_ERROR,
6189 			    "%s reset failed! due to host diag register unlock failure"
6190 			    "host_diagnostic(0x%08x)\n", mpi3mr_reset_type_name(reset_type),
6191 			    host_diagnostic);
6192 			sc->unrecoverable = 1;
6193 			return retval;
6194 		}
6195 
6196 		mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET,
6197 			MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_FLUSH);
6198 		mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET,
6199 			MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_1ST);
6200 		mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET,
6201 			MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_2ND);
6202 		mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET,
6203 			MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_3RD);
6204 		mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET,
6205 			MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_4TH);
6206 		mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET,
6207 			MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_5TH);
6208 		mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET,
6209 			MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_6TH);
6210 
6211 		DELAY(1000); /* delay in usec */
6212 		host_diagnostic = mpi3mr_regread(sc, MPI3_SYSIF_HOST_DIAG_OFFSET);
6213 		mpi3mr_dprint(sc, MPI3MR_INFO,
6214 		    "wrote magic sequence: retry_count(%d), host_diagnostic(0x%08x)\n",
6215 		    unlock_retry_count, host_diagnostic);
6216 	} while (!(host_diagnostic & MPI3_SYSIF_HOST_DIAG_DIAG_WRITE_ENABLE));
6217 
6218 	if (reset_type == MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT)
6219 		mpi3mr_set_diagsave(sc);
6220 
6221 	scratch_pad0 = ((MPI3MR_RESET_REASON_OSTYPE_FREEBSD <<
6222 			MPI3MR_RESET_REASON_OSTYPE_SHIFT) |
6223 			(sc->facts.ioc_num <<
6224 			MPI3MR_RESET_REASON_IOCNUM_SHIFT) | reset_reason);
6225 	mpi3mr_regwrite(sc, MPI3_SYSIF_SCRATCHPAD0_OFFSET, scratch_pad0);
6226 	mpi3mr_regwrite(sc, MPI3_SYSIF_HOST_DIAG_OFFSET, host_diagnostic | reset_type);
6227 
6228 	if (reset_type == MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET) {
6229 		do {
6230 			ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
6231 			if (ioc_status &
6232 			    MPI3_SYSIF_IOC_STATUS_RESET_HISTORY) {
6233 				ioc_config =
6234 				    mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET);
6235 				if (mpi3mr_soft_reset_success(ioc_status,
6236 				    ioc_config)) {
6237 					mpi3mr_clear_reset_history(sc);
6238 					retval = 0;
6239 					break;
6240 				}
6241 			}
6242 			DELAY(100 * 1000);
6243 		} while (--timeout);
6244 	} else if (reset_type == MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT) {
6245 		do {
6246 			ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
6247 			if (mpi3mr_diagfault_success(sc, ioc_status)) {
6248 				retval = 0;
6249 				break;
6250 			}
6251 			DELAY(100 * 1000);
6252 		} while (--timeout);
6253 	}
6254 
6255 	mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET,
6256 		MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_2ND);
6257 
6258 	ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
6259 	ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET);
6260 
6261 	mpi3mr_dprint(sc, MPI3MR_INFO,
6262 	    "IOC Status/Config after %s reset is (0x%x)/(0x%x)\n",
6263 	    !retval ? "successful":"failed", ioc_status,
6264 	    ioc_config);
6265 
6266 	if (retval)
6267 		sc->unrecoverable = 1;
6268 
6269 	return retval;
6270 }
6271 
6272 inline void mpi3mr_cleanup_event_taskq(struct mpi3mr_softc *sc)
6273 {
6274 	/*
6275 	 * Block the taskqueue before draining.  This means any new tasks won't
6276 	 * be queued to the taskqueue worker thread.  But it doesn't stop the
6277 	 * current workers that are running.  taskqueue_drain waits for those
6278 	 * correctly in the case of thread backed taskqueues.  The while loop
6279 	 * ensures that all taskqueue threads have finished their current tasks.
6280 	 */
6281 	taskqueue_block(sc->cam_sc->ev_tq);
6282 	while (taskqueue_cancel(sc->cam_sc->ev_tq, &sc->cam_sc->ev_task, NULL) != 0) {
6283 		taskqueue_drain(sc->cam_sc->ev_tq, &sc->cam_sc->ev_task);
6284 	}
6285 }
6286 
6287 /**
6288  * mpi3mr_soft_reset_handler - Reset the controller
6289  * @sc: Adapter instance reference
6290  * @reset_reason: Reset reason code
6291  * @snapdump: snapdump enable/disbale bit
6292  *
6293  * This is an handler for recovering controller by issuing soft
6294  * reset or diag fault reset. This is a blocking function and
6295  * when one reset is executed if any other resets they will be
6296  * blocked. All IOCTLs/IO will be blocked during the reset. If
6297  * controller reset is successful then the controller will be
6298  * reinitalized, otherwise the controller will be marked as not
6299  * recoverable
6300  *
6301  * Return: 0 on success, non-zero on failure.
6302  */
6303 int mpi3mr_soft_reset_handler(struct mpi3mr_softc *sc,
6304 	U16 reset_reason, bool snapdump)
6305 {
6306 	int retval = 0, i = 0;
6307 	enum mpi3mr_iocstate ioc_state;
6308 
6309 	mpi3mr_dprint(sc, MPI3MR_INFO, "soft reset invoked: reason code: %s\n",
6310 	    mpi3mr_reset_rc_name(reset_reason));
6311 
6312 	if ((reset_reason == MPI3MR_RESET_FROM_IOCTL) &&
6313 	     (sc->reset.ioctl_reset_snapdump != true))
6314 		snapdump = false;
6315 
6316 	mpi3mr_dprint(sc, MPI3MR_INFO,
6317 	    "soft_reset_handler: wait if diag save is in progress\n");
6318 	while (sc->diagsave_timeout)
6319 		DELAY(1000 * 1000);
6320 
6321 	ioc_state = mpi3mr_get_iocstate(sc);
6322 	if (ioc_state == MRIOC_STATE_UNRECOVERABLE) {
6323 		mpi3mr_dprint(sc, MPI3MR_ERROR, "controller is in unrecoverable state, exit\n");
6324 		sc->reset.type = MPI3MR_NO_RESET;
6325 		sc->reset.reason = MPI3MR_DEFAULT_RESET_REASON;
6326 		sc->reset.status = -1;
6327 		sc->reset.ioctl_reset_snapdump = false;
6328 		return -1;
6329 	}
6330 
6331 	if (sc->reset_in_progress) {
6332 		mpi3mr_dprint(sc, MPI3MR_INFO, "reset is already in progress, exit\n");
6333 		return -1;
6334 	}
6335 
6336 	/* Pause IOs, drain and block the event taskqueue */
6337 	xpt_freeze_simq(sc->cam_sc->sim, 1);
6338 
6339 	mpi3mr_cleanup_event_taskq(sc);
6340 
6341 	sc->reset_in_progress = 1;
6342 	sc->block_ioctls = 1;
6343 
6344 	if (sc->timestamp_thread_active)
6345 		wakeup(&sc->timestamp_chan);
6346 
6347 	while (mpi3mr_atomic_read(&sc->pend_ioctls) && (i < PEND_IOCTLS_COMP_WAIT_TIME)) {
6348 		ioc_state = mpi3mr_get_iocstate(sc);
6349 		if (ioc_state == MRIOC_STATE_FAULT)
6350 			break;
6351 		i++;
6352 		if (!(i % 5)) {
6353 			mpi3mr_dprint(sc, MPI3MR_INFO,
6354 			    "[%2ds]waiting for IOCTL to be finished from %s\n", i, __func__);
6355 		}
6356 		DELAY(1000 * 1000);
6357 	}
6358 
6359 	if ((!snapdump) && (reset_reason != MPI3MR_RESET_FROM_FAULT_WATCH) &&
6360 	    (reset_reason != MPI3MR_RESET_FROM_FIRMWARE) &&
6361 	    (reset_reason != MPI3MR_RESET_FROM_CIACTIV_FAULT)) {
6362 
6363 		mpi3mr_dprint(sc, MPI3MR_INFO, "Turn off events prior to reset\n");
6364 
6365 		for (i = 0; i < MPI3_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
6366 			sc->event_masks[i] = -1;
6367 		mpi3mr_issue_event_notification(sc);
6368 	}
6369 
6370 	mpi3mr_disable_interrupts(sc);
6371 
6372 	if (snapdump)
6373 		mpi3mr_trigger_snapdump(sc, reset_reason);
6374 
6375 	retval = mpi3mr_issue_reset(sc,
6376 	    MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET, reset_reason);
6377 	if (retval) {
6378 		mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to issue soft reset to the ioc\n");
6379 		goto out;
6380 	}
6381 
6382 	mpi3mr_flush_drv_cmds(sc);
6383 	mpi3mr_flush_io(sc);
6384 	mpi3mr_invalidate_devhandles(sc);
6385 	mpi3mr_memset_buffers(sc);
6386 
6387 	if (sc->prepare_for_reset) {
6388 		sc->prepare_for_reset = 0;
6389 		sc->prepare_for_reset_timeout_counter = 0;
6390 	}
6391 
6392 	retval = mpi3mr_initialize_ioc(sc, MPI3MR_INIT_TYPE_RESET);
6393 	if (retval) {
6394 		mpi3mr_dprint(sc, MPI3MR_ERROR, "reinit after soft reset failed: reason %d\n",
6395 		    reset_reason);
6396 		goto out;
6397 	}
6398 
6399 	DELAY((1000 * 1000) * 10);
6400 out:
6401 	if (!retval) {
6402 		sc->diagsave_timeout = 0;
6403 		sc->reset_in_progress = 0;
6404 		mpi3mr_rfresh_tgtdevs(sc);
6405 		sc->ts_update_counter = 0;
6406 		sc->block_ioctls = 0;
6407 		sc->pel_abort_requested = 0;
6408 		if (sc->pel_wait_pend) {
6409 			sc->pel_cmds.retry_count = 0;
6410 			mpi3mr_issue_pel_wait(sc, &sc->pel_cmds);
6411 			mpi3mr_app_send_aen(sc);
6412 		}
6413 	} else {
6414 		ioc_state = mpi3mr_get_iocstate(sc);
6415 		if (ioc_state != MRIOC_STATE_FAULT)
6416 			mpi3mr_issue_reset(sc,
6417 			    MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT, reset_reason);
6418 
6419 		sc->unrecoverable = 1;
6420 		sc->reset_in_progress = 0;
6421 		sc->block_ioctls = 0;
6422 	}
6423 
6424 	mpi3mr_dprint(sc, MPI3MR_INFO, "Soft Reset: %s\n", ((retval == 0) ? "SUCCESS" : "FAILED"));
6425 
6426 	taskqueue_unblock(sc->cam_sc->ev_tq);
6427 	xpt_release_simq(sc->cam_sc->sim, 1);
6428 
6429 	sc->reset.type = MPI3MR_NO_RESET;
6430 	sc->reset.reason = MPI3MR_DEFAULT_RESET_REASON;
6431 	sc->reset.status = retval;
6432 	sc->reset.ioctl_reset_snapdump = false;
6433 
6434 	return retval;
6435 }
6436 
6437 /**
6438  * mpi3mr_issue_ioc_shutdown - shutdown controller
6439  * @sc: Adapter instance reference
6440  *
6441  * Send shutodwn notification to the controller and wait for the
6442  * shutdown_timeout for it to be completed.
6443  *
6444  * Return: Nothing.
6445  */
6446 static void mpi3mr_issue_ioc_shutdown(struct mpi3mr_softc *sc)
6447 {
6448 	U32 ioc_config, ioc_status;
6449 	U8 retval = 1, retry = 0;
6450 	U32 timeout = MPI3MR_DEFAULT_SHUTDOWN_TIME * 10;
6451 
6452 	mpi3mr_dprint(sc, MPI3MR_INFO, "sending shutdown notification\n");
6453 	if (sc->unrecoverable) {
6454 		mpi3mr_dprint(sc, MPI3MR_ERROR,
6455 		    "controller is unrecoverable, shutdown not issued\n");
6456 		return;
6457 	}
6458 	ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
6459 	if ((ioc_status & MPI3_SYSIF_IOC_STATUS_SHUTDOWN_MASK)
6460 	    == MPI3_SYSIF_IOC_STATUS_SHUTDOWN_IN_PROGRESS) {
6461 		mpi3mr_dprint(sc, MPI3MR_ERROR, "shutdown already in progress\n");
6462 		return;
6463 	}
6464 
6465 	ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET);
6466 	ioc_config |= MPI3_SYSIF_IOC_CONFIG_SHUTDOWN_NORMAL;
6467 	ioc_config |= MPI3_SYSIF_IOC_CONFIG_DEVICE_SHUTDOWN_SEND_REQ;
6468 
6469 	mpi3mr_regwrite(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET, ioc_config);
6470 
6471 	if (sc->facts.shutdown_timeout)
6472 		timeout = sc->facts.shutdown_timeout * 10;
6473 
6474 	do {
6475 		ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
6476 		if ((ioc_status & MPI3_SYSIF_IOC_STATUS_SHUTDOWN_MASK)
6477 		    == MPI3_SYSIF_IOC_STATUS_SHUTDOWN_COMPLETE) {
6478 			retval = 0;
6479 			break;
6480 		}
6481 
6482 		if (sc->unrecoverable)
6483 			break;
6484 
6485 		if ((ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT)) {
6486 			mpi3mr_print_fault_info(sc);
6487 
6488 			if (retry >= MPI3MR_MAX_SHUTDOWN_RETRY_COUNT)
6489 				break;
6490 
6491 			if (mpi3mr_issue_reset(sc,
6492 			    MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET,
6493 			    MPI3MR_RESET_FROM_CTLR_CLEANUP))
6494 				break;
6495 
6496 			ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET);
6497 			ioc_config |= MPI3_SYSIF_IOC_CONFIG_SHUTDOWN_NORMAL;
6498 			ioc_config |= MPI3_SYSIF_IOC_CONFIG_DEVICE_SHUTDOWN_SEND_REQ;
6499 
6500 			mpi3mr_regwrite(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET, ioc_config);
6501 
6502 			if (sc->facts.shutdown_timeout)
6503 				timeout = sc->facts.shutdown_timeout * 10;
6504 
6505 			retry++;
6506 		}
6507 
6508                 DELAY(100 * 1000);
6509 
6510 	} while (--timeout);
6511 
6512 	ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET);
6513 	ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET);
6514 
6515 	if (retval) {
6516 		if ((ioc_status & MPI3_SYSIF_IOC_STATUS_SHUTDOWN_MASK)
6517 		    == MPI3_SYSIF_IOC_STATUS_SHUTDOWN_IN_PROGRESS)
6518 			mpi3mr_dprint(sc, MPI3MR_ERROR,
6519 			    "shutdown still in progress after timeout\n");
6520 	}
6521 
6522 	mpi3mr_dprint(sc, MPI3MR_INFO,
6523 	    "ioc_status/ioc_config after %s shutdown is (0x%x)/(0x%x)\n",
6524 	    (!retval)?"successful":"failed", ioc_status,
6525 	    ioc_config);
6526 }
6527 
6528 /**
6529  * mpi3mr_cleanup_ioc - Cleanup controller
6530  * @sc: Adapter instance reference
6531 
6532  * controller cleanup handler, Message unit reset or soft reset
6533  * and shutdown notification is issued to the controller.
6534  *
6535  * Return: Nothing.
6536  */
6537 void mpi3mr_cleanup_ioc(struct mpi3mr_softc *sc)
6538 {
6539 	enum mpi3mr_iocstate ioc_state;
6540 
6541 	mpi3mr_dprint(sc, MPI3MR_INFO, "cleaning up the controller\n");
6542 	mpi3mr_disable_interrupts(sc);
6543 
6544 	ioc_state = mpi3mr_get_iocstate(sc);
6545 
6546 	if ((!sc->unrecoverable) && (!sc->reset_in_progress) &&
6547 	    (ioc_state == MRIOC_STATE_READY)) {
6548 		if (mpi3mr_mur_ioc(sc,
6549 		    MPI3MR_RESET_FROM_CTLR_CLEANUP))
6550 			mpi3mr_issue_reset(sc,
6551 			    MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET,
6552 			    MPI3MR_RESET_FROM_MUR_FAILURE);
6553 		mpi3mr_issue_ioc_shutdown(sc);
6554 	}
6555 
6556 	mpi3mr_dprint(sc, MPI3MR_INFO, "controller cleanup completed\n");
6557 }
6558