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