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