xref: /freebsd/sys/dev/mrsas/mrsas_ioctl.c (revision 9f23cbd6cae82fd77edfad7173432fa8dccd0a95)
1 /*
2  * Copyright (c) 2015, AVAGO Tech. All rights reserved. Author: Marian Choy
3  * Copyright (c) 2014, LSI Corp. All rights reserved. Author: Marian Choy
4  * Support: freebsdraid@avagotech.com
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer. 2. Redistributions
12  * in binary form must reproduce the above copyright notice, this list of
13  * conditions and the following disclaimer in the documentation and/or other
14  * materials provided with the distribution. 3. Neither the name of the
15  * <ORGANIZATION> nor the names of its contributors may be used to endorse or
16  * promote products derived from this software without specific prior written
17  * permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  * The views and conclusions contained in the software and documentation are
32  * those of the authors and should not be interpreted as representing
33  * official policies,either expressed or implied, of the FreeBSD Project.
34  *
35  * Send feedback to: <megaraidfbsd@avagotech.com> Mail to: AVAGO TECHNOLOGIES, 1621
36  * Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD
37  *
38  */
39 
40 #include <sys/cdefs.h>
41 __FBSDID("$FreeBSD$");
42 
43 #include <sys/abi_compat.h>
44 #include <dev/mrsas/mrsas.h>
45 #include <dev/mrsas/mrsas_ioctl.h>
46 
47 struct mrsas_passthru_cmd {
48 	struct mrsas_sge64 *kern_sge;
49 	struct mrsas_softc *sc;
50 	struct mrsas_mfi_cmd *cmd;
51 	bus_dma_tag_t ioctl_data_tag;
52 	bus_dmamap_t ioctl_data_dmamap;
53 
54 	u_int32_t error_code;
55 	u_int32_t sge_count;
56 	int complete;
57 };
58 
59 /*
60  * Function prototypes
61  */
62 int	mrsas_alloc_mfi_cmds(struct mrsas_softc *sc);
63 int	mrsas_passthru(struct mrsas_softc *sc, void *arg, u_long ioctlCmd);
64 void	mrsas_free_ioc_cmd(struct mrsas_softc *sc);
65 void	mrsas_free_frame(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd);
66 void   *mrsas_alloc_frame(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd);
67 static int mrsas_create_frame_pool(struct mrsas_softc *sc);
68 static void
69 mrsas_alloc_cb(void *arg, bus_dma_segment_t *segs,
70     int nsegs, int error);
71 
72 extern struct mrsas_mfi_cmd *mrsas_get_mfi_cmd(struct mrsas_softc *sc);
73 extern void mrsas_release_mfi_cmd(struct mrsas_mfi_cmd *cmd);
74 extern int
75 mrsas_issue_blocked_cmd(struct mrsas_softc *sc,
76     struct mrsas_mfi_cmd *cmd);
77 
78 /*
79  * mrsas_data_load_cb:  Callback entry point
80  * input:                               Pointer to command packet as argument
81  *                                              Pointer to segment
82  *                                              Number of segments Error
83  *
84  * This is the callback function of the bus dma map load.  It builds the SG
85  * list.
86  */
87 static void
88 mrsas_passthru_load_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
89 {
90         struct mrsas_passthru_cmd *cb = (struct mrsas_passthru_cmd *)arg;
91         struct mrsas_softc *sc = cb->sc;
92 	int i = 0;
93 
94 	if (error) {
95 		cb->error_code = error;
96 		if (error == EFBIG) {
97 			device_printf(sc->mrsas_dev, "mrsas_passthru_load_cb: "
98 			    "error=%d EFBIG\n", error);
99 			cb->complete = 1;
100 			return;
101 		} else {
102 			device_printf(sc->mrsas_dev, "mrsas_passthru_load_cb: "
103 			    "error=%d UNKNOWN\n", error);
104 		}
105 	}
106 	if (nseg > MAX_IOCTL_SGE) {
107 		cb->error_code = EFBIG;
108 		device_printf(sc->mrsas_dev, "mrsas_passthru_load_cb: "
109 		    "too many segments: %d\n", nseg);
110 		cb->complete = 1;
111 		return;
112 	}
113 
114 	for (i = 0; i < nseg; i++) {
115 		cb->kern_sge[i].phys_addr = htole64(segs[i].ds_addr);
116 		cb->kern_sge[i].length = htole32(segs[i].ds_len);
117 	}
118 	cb->sge_count = nseg;
119 
120 	bus_dmamap_sync(cb->ioctl_data_tag, cb->ioctl_data_dmamap,
121             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
122 
123 	cb->complete = 1;
124 }
125 
126 /*
127  * mrsas_passthru:	Handle pass-through commands
128  * input:			Adapter instance soft state argument pointer
129  *
130  * This function is called from mrsas_ioctl() to handle pass-through and ioctl
131  * commands to Firmware.
132  */
133 int
134 mrsas_passthru(struct mrsas_softc *sc, void *arg, u_long ioctlCmd)
135 {
136 	struct mrsas_iocpacket *user_ioc = (struct mrsas_iocpacket *)arg;
137 
138 #ifdef COMPAT_FREEBSD32
139 	struct mrsas_iocpacket32 *user_ioc32 = (struct mrsas_iocpacket32 *)arg;
140 
141 #endif
142 	union mrsas_frame *in_cmd = (union mrsas_frame *)&(user_ioc->frame.raw);
143 	struct mrsas_mfi_cmd *cmd = NULL;
144 	bus_dma_tag_t ioctl_data_tag[MAX_IOCTL_SGE];
145 	bus_dmamap_t ioctl_data_dmamap[MAX_IOCTL_SGE];
146 	void *ioctl_data_mem[MAX_IOCTL_SGE];
147 	bus_addr_t ioctl_data_phys_addr[MAX_IOCTL_SGE];
148 	bus_dma_tag_t ioctl_sense_tag = 0;
149 	bus_dmamap_t ioctl_sense_dmamap = 0;
150 	void *ioctl_sense_mem = NULL;
151 	bus_addr_t ioctl_sense_phys_addr = 0;
152 	int i, ioctl_data_size = 0, ioctl_sense_size, ret = 0;
153 	struct mrsas_sge32 *kern_sge32;
154 	unsigned long *sense_ptr;
155 	uint8_t *iov_base_ptrin = NULL;
156 	size_t iov_len = 0;
157 
158 	/*
159 	 * Check for NOP from MegaCli... MegaCli can issue a DCMD of 0.  In
160 	 * this case do nothing and return 0 to it as status.
161 	 */
162 	if (in_cmd->dcmd.opcode == 0) {
163 		device_printf(sc->mrsas_dev, "In %s() Got a NOP\n", __func__);
164 		user_ioc->frame.hdr.cmd_status = MFI_STAT_OK;
165 		return (0);
166 	}
167 	/* Validate SGL length */
168 	if (user_ioc->sge_count > MAX_IOCTL_SGE) {
169 		device_printf(sc->mrsas_dev, "In %s() SGL is too long (%d > 8).\n",
170 		    __func__, user_ioc->sge_count);
171 		return (ENOENT);
172 	}
173 	/* Get a command */
174 	cmd = mrsas_get_mfi_cmd(sc);
175 	if (!cmd) {
176 		device_printf(sc->mrsas_dev, "Failed to get a free cmd for IOCTL\n");
177 		return (ENOMEM);
178 	}
179 	/*
180 	 * User's IOCTL packet has 2 frames (maximum). Copy those two frames
181 	 * into our cmd's frames. cmd->frame's context will get overwritten
182 	 * when we copy from user's frames. So set that value alone
183 	 * separately
184 	 */
185 	memcpy(cmd->frame, user_ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
186 	cmd->frame->hdr.context = cmd->index;
187 	cmd->frame->hdr.pad_0 = 0;
188 	cmd->frame->hdr.flags &= ~(MFI_FRAME_IEEE | MFI_FRAME_SGL64 |
189 	    MFI_FRAME_SENSE64);
190 
191 	/*
192 	 * The management interface between applications and the fw uses MFI
193 	 * frames. E.g, RAID configuration changes, LD property changes etc
194 	 * are accomplishes through different kinds of MFI frames. The driver
195 	 * needs to care only about substituting user buffers with kernel
196 	 * buffers in SGLs. The location of SGL is embedded in the struct
197 	 * iocpacket itself.
198 	 */
199 	kern_sge32 = (struct mrsas_sge32 *)
200 	    ((uintptr_t)cmd->frame + user_ioc->sgl_off);
201 
202 	memset(ioctl_data_tag, 0, (sizeof(bus_dma_tag_t) * MAX_IOCTL_SGE));
203 	memset(ioctl_data_dmamap, 0, (sizeof(bus_dmamap_t) * MAX_IOCTL_SGE));
204 	memset(ioctl_data_mem, 0, (sizeof(void *) * MAX_IOCTL_SGE));
205 	memset(ioctl_data_phys_addr, 0, (sizeof(bus_addr_t) * MAX_IOCTL_SGE));
206 
207 	/*
208 	 * For each user buffer, create a mirror buffer and copy in
209 	 */
210 	for (i = 0; i < user_ioc->sge_count; i++) {
211 		if (ioctlCmd == MRSAS_IOC_FIRMWARE_PASS_THROUGH64) {
212 			if (!user_ioc->sgl[i].iov_len)
213 				continue;
214 			ioctl_data_size = user_ioc->sgl[i].iov_len;
215 #ifdef COMPAT_FREEBSD32
216 		} else {
217 			if (!user_ioc32->sgl[i].iov_len)
218 				continue;
219 			ioctl_data_size = user_ioc32->sgl[i].iov_len;
220 #endif
221 		}
222 		if (bus_dma_tag_create(sc->mrsas_parent_tag,
223 		    1, 0,
224 		    BUS_SPACE_MAXADDR_32BIT,
225 		    BUS_SPACE_MAXADDR,
226 		    NULL, NULL,
227 		    ioctl_data_size,
228 		    1,
229 		    ioctl_data_size,
230 		    BUS_DMA_ALLOCNOW,
231 		    NULL, NULL,
232 		    &ioctl_data_tag[i])) {
233 			device_printf(sc->mrsas_dev, "Cannot allocate ioctl data tag\n");
234 			ret = ENOMEM;
235 			goto out;
236 		}
237 		if (bus_dmamem_alloc(ioctl_data_tag[i], (void **)&ioctl_data_mem[i],
238 		    (BUS_DMA_NOWAIT | BUS_DMA_ZERO), &ioctl_data_dmamap[i])) {
239 			device_printf(sc->mrsas_dev, "Cannot allocate ioctl data mem\n");
240 			ret = ENOMEM;
241 			goto out;
242 		}
243 		if (bus_dmamap_load(ioctl_data_tag[i], ioctl_data_dmamap[i],
244 		    ioctl_data_mem[i], ioctl_data_size, mrsas_alloc_cb,
245 		    &ioctl_data_phys_addr[i], BUS_DMA_NOWAIT)) {
246 			device_printf(sc->mrsas_dev, "Cannot load ioctl data mem\n");
247 			ret = ENOMEM;
248 			goto out;
249 		}
250 		/* Save the physical address and length */
251 		kern_sge32[i].phys_addr = (u_int32_t)ioctl_data_phys_addr[i];
252 
253 		if (ioctlCmd == MRSAS_IOC_FIRMWARE_PASS_THROUGH64) {
254 			kern_sge32[i].length = user_ioc->sgl[i].iov_len;
255 
256 			iov_base_ptrin = user_ioc->sgl[i].iov_base;
257 			iov_len = user_ioc->sgl[i].iov_len;
258 #ifdef COMPAT_FREEBSD32
259 		} else {
260 			kern_sge32[i].length = user_ioc32->sgl[i].iov_len;
261 
262 			iov_base_ptrin = PTRIN(user_ioc32->sgl[i].iov_base);
263 			iov_len = user_ioc32->sgl[i].iov_len;
264 #endif
265 		}
266 
267 		/* Copy in data from user space */
268 		ret = copyin(iov_base_ptrin, ioctl_data_mem[i], iov_len);
269 		if (ret) {
270 			device_printf(sc->mrsas_dev, "IOCTL copyin failed!\n");
271 			goto out;
272 		}
273 	}
274 
275 	ioctl_sense_size = user_ioc->sense_len;
276 
277 	if (user_ioc->sense_len) {
278 		if (bus_dma_tag_create(sc->mrsas_parent_tag,
279 		    1, 0,
280 		    BUS_SPACE_MAXADDR_32BIT,
281 		    BUS_SPACE_MAXADDR,
282 		    NULL, NULL,
283 		    ioctl_sense_size,
284 		    1,
285 		    ioctl_sense_size,
286 		    BUS_DMA_ALLOCNOW,
287 		    NULL, NULL,
288 		    &ioctl_sense_tag)) {
289 			device_printf(sc->mrsas_dev, "Cannot allocate ioctl sense tag\n");
290 			ret = ENOMEM;
291 			goto out;
292 		}
293 		if (bus_dmamem_alloc(ioctl_sense_tag, (void **)&ioctl_sense_mem,
294 		    (BUS_DMA_NOWAIT | BUS_DMA_ZERO), &ioctl_sense_dmamap)) {
295 			device_printf(sc->mrsas_dev, "Cannot allocate ioctl sense mem\n");
296 			ret = ENOMEM;
297 			goto out;
298 		}
299 		if (bus_dmamap_load(ioctl_sense_tag, ioctl_sense_dmamap,
300 		    ioctl_sense_mem, ioctl_sense_size, mrsas_alloc_cb,
301 		    &ioctl_sense_phys_addr, BUS_DMA_NOWAIT)) {
302 			device_printf(sc->mrsas_dev, "Cannot load ioctl sense mem\n");
303 			ret = ENOMEM;
304 			goto out;
305 		}
306 		sense_ptr =
307 		    (unsigned long *)((uintptr_t)cmd->frame + user_ioc->sense_off);
308 		*sense_ptr = ioctl_sense_phys_addr;
309 	}
310 	/*
311 	 * Set the sync_cmd flag so that the ISR knows not to complete this
312 	 * cmd to the SCSI mid-layer
313 	 */
314 	cmd->sync_cmd = 1;
315 	ret = mrsas_issue_blocked_cmd(sc, cmd);
316 	if (ret == ETIMEDOUT) {
317 		mrsas_dprint(sc, MRSAS_OCR,
318 		    "IOCTL command is timed out, initiating OCR\n");
319 		sc->do_timedout_reset = MFI_DCMD_TIMEOUT_OCR;
320 		ret = EAGAIN;
321 		goto out;
322 	}
323 	cmd->sync_cmd = 0;
324 
325 	/*
326 	 * copy out the kernel buffers to user buffers
327 	 */
328 	for (i = 0; i < user_ioc->sge_count; i++) {
329 		if (ioctlCmd == MRSAS_IOC_FIRMWARE_PASS_THROUGH64) {
330 			iov_base_ptrin = user_ioc->sgl[i].iov_base;
331 			iov_len = user_ioc->sgl[i].iov_len;
332 #ifdef COMPAT_FREEBSD32
333 		} else {
334 			iov_base_ptrin = PTRIN(user_ioc32->sgl[i].iov_base);
335 			iov_len = user_ioc32->sgl[i].iov_len;
336 #endif
337 		}
338 
339 		ret = copyout(ioctl_data_mem[i], iov_base_ptrin, iov_len);
340 		if (ret) {
341 			device_printf(sc->mrsas_dev, "IOCTL copyout failed!\n");
342 			goto out;
343 		}
344 	}
345 
346 	/*
347 	 * copy out the sense
348 	 */
349 	if (user_ioc->sense_len) {
350 		/*
351 		 * sense_buff points to the location that has the user sense
352 		 * buffer address
353 		 */
354 		sense_ptr = (unsigned long *)((uintptr_t)user_ioc->frame.raw +
355 		    user_ioc->sense_off);
356 		ret = copyout(ioctl_sense_mem, (unsigned long *)(uintptr_t)*sense_ptr,
357 		    user_ioc->sense_len);
358 		if (ret) {
359 			device_printf(sc->mrsas_dev, "IOCTL sense copyout failed!\n");
360 			goto out;
361 		}
362 	}
363 	/*
364 	 * Return command status to user space
365 	 */
366 	memcpy(&user_ioc->frame.hdr.cmd_status, &cmd->frame->hdr.cmd_status,
367 	    sizeof(u_int8_t));
368 
369 out:
370 	/*
371 	 * Release sense buffer
372 	 */
373 	if (user_ioc->sense_len) {
374 		if (ioctl_sense_phys_addr)
375 			bus_dmamap_unload(ioctl_sense_tag, ioctl_sense_dmamap);
376 		if (ioctl_sense_mem != NULL)
377 			bus_dmamem_free(ioctl_sense_tag, ioctl_sense_mem, ioctl_sense_dmamap);
378 		if (ioctl_sense_tag != NULL)
379 			bus_dma_tag_destroy(ioctl_sense_tag);
380 	}
381 	/*
382 	 * Release data buffers
383 	 */
384 	for (i = 0; i < user_ioc->sge_count; i++) {
385 		if (ioctlCmd == MRSAS_IOC_FIRMWARE_PASS_THROUGH64) {
386 			if (!user_ioc->sgl[i].iov_len)
387 				continue;
388 #ifdef COMPAT_FREEBSD32
389 		} else {
390 			if (!user_ioc32->sgl[i].iov_len)
391 				continue;
392 #endif
393 		}
394 		if (ioctl_data_phys_addr[i])
395 			bus_dmamap_unload(ioctl_data_tag[i], ioctl_data_dmamap[i]);
396 		if (ioctl_data_mem[i] != NULL)
397 			bus_dmamem_free(ioctl_data_tag[i], ioctl_data_mem[i],
398 			    ioctl_data_dmamap[i]);
399 		if (ioctl_data_tag[i] != NULL)
400 			bus_dma_tag_destroy(ioctl_data_tag[i]);
401 	}
402 	/* Free command */
403 	mrsas_release_mfi_cmd(cmd);
404 
405 	return (ret);
406 }
407 
408 /**
409  * mrsas_user_command:    Handle user mode DCMD and buffer
410  * input:                 Adapter instance soft state
411  *                        argument pointer
412  *
413  * This function is called from mrsas_ioctl() DCMDs to firmware for mfiutil
414  */
415 int
416 mrsas_user_command(struct mrsas_softc *sc, struct mfi_ioc_passthru *ioc)
417 {
418 	struct mrsas_mfi_cmd *cmd;
419 	struct mrsas_dcmd_frame *dcmd;
420 	struct mrsas_passthru_cmd *passcmd;
421 	bus_dma_tag_t ioctl_data_tag;
422 	bus_dmamap_t ioctl_data_dmamap;
423 	bus_addr_t ioctl_data_phys_addr;
424 	struct mrsas_sge64 *kern_sge;
425 	int ret, ioctl_data_size;
426 	char *ioctl_temp_data_mem;
427 
428 	ret = 0;
429 	ioctl_temp_data_mem = NULL;
430 	passcmd = NULL;
431 	ioctl_data_phys_addr = 0;
432 	dcmd = NULL;
433 	cmd = NULL;
434 	ioctl_data_tag = NULL;
435 	ioctl_data_dmamap = NULL;
436 	ioctl_data_dmamap = NULL;
437 
438 	/* Get a command */
439 	cmd = mrsas_get_mfi_cmd(sc);
440 	if (!cmd) {
441 		device_printf(sc->mrsas_dev,
442 		    "Failed to get a free cmd for IOCTL\n");
443 		return(ENOMEM);
444 	}
445 
446 	/*
447 	 * Frame is DCMD
448 	 */
449 	dcmd = (struct mrsas_dcmd_frame *)cmd->frame;
450 	memcpy(dcmd, &ioc->ioc_frame, sizeof(struct mrsas_dcmd_frame));
451 
452 	ioctl_data_size = ioc->buf_size;
453 
454 	cmd->frame->hdr.context = cmd->index;
455 	cmd->frame->hdr.pad_0 = 0;
456 	cmd->frame->hdr.flags = MFI_FRAME_DIR_BOTH;
457 	if (sizeof(bus_addr_t) == 8)
458 		cmd->frame->hdr.flags |= MFI_FRAME_SGL64 | MFI_FRAME_SENSE64;
459 
460 	kern_sge = (struct mrsas_sge64 *)(&dcmd->sgl);
461 
462 	if (ioctl_data_size == 0) {
463 		kern_sge[0].phys_addr = 0;
464 		kern_sge[0].length = 0;
465 	} else {
466 		ioctl_temp_data_mem = malloc(ioc->buf_size, M_MRSAS, M_WAITOK);
467 		if (ioctl_temp_data_mem == NULL) {
468 			device_printf(sc->mrsas_dev, "Could not allocate "
469 			    "%d memory for temporary passthrough ioctl\n",
470 			    ioc->buf_size);
471 		ret = ENOMEM;
472 		goto out;
473 		}
474 
475 		/* Copy in data from user space */
476 		ret = copyin(ioc->buf, ioctl_temp_data_mem, ioc->buf_size);
477 		if (ret) {
478 			device_printf(sc->mrsas_dev, "IOCTL copyin failed!\n");
479 			goto out;
480 		}
481 
482 		/*
483 		 * Allocate a temporary struct to hold parameters for the
484 		 * callback
485 		 */
486 		passcmd = malloc(sizeof(struct mrsas_passthru_cmd), M_MRSAS,
487 		    M_WAITOK);
488 		if (passcmd == NULL) {
489 			device_printf(sc->mrsas_dev, "Could not allocate "
490 			    "memory for temporary passthrough cb struct\n");
491 			ret = ENOMEM;
492 			goto out;
493 		}
494 		passcmd->complete = 0;
495 		passcmd->sc = sc;
496 		passcmd->cmd = cmd;
497 		passcmd->kern_sge = kern_sge;
498 
499 		/*
500 		 * Create a dma tag for passthru buffers
501 		 */
502 		if (bus_dma_tag_create(sc->mrsas_parent_tag,   /* parent */
503 		    1, 0,                   /* algnmnt, boundary */
504 		    BUS_SPACE_MAXADDR,      /* lowaddr */
505 		    BUS_SPACE_MAXADDR,      /* highaddr */
506 		    NULL, NULL,             /* filter, filterarg */
507 		    ioctl_data_size,        /* maxsize */
508 		    MAX_IOCTL_SGE,          /* msegments */
509 		    ioctl_data_size,        /* maxsegsize */
510 		    BUS_DMA_ALLOCNOW,       /* flags */
511 		    busdma_lock_mutex,      /* lockfunc */
512 		    &sc->ioctl_lock,        /* lockarg */
513 		    &ioctl_data_tag)) {
514 			device_printf(sc->mrsas_dev,
515 			   "Cannot allocate ioctl data tag %d\n",
516 			    ioc->buf_size);
517 			ret = ENOMEM;
518 			goto out;
519 		}
520 
521 		/* Create memmap */
522 		if (bus_dmamap_create(ioctl_data_tag, 0, &ioctl_data_dmamap)) {
523 			device_printf(sc->mrsas_dev, "Cannot create ioctl "
524 			    "passthru dmamap\n");
525 			ret = ENOMEM;
526 			goto out;
527 		}
528 
529 		passcmd->ioctl_data_tag = ioctl_data_tag;
530 		passcmd->ioctl_data_dmamap = ioctl_data_dmamap;
531 
532 		/* Map data buffer into bus space */
533 		if (bus_dmamap_load(ioctl_data_tag, ioctl_data_dmamap,
534 		    ioctl_temp_data_mem, ioc->buf_size, mrsas_passthru_load_cb,
535 		    passcmd, BUS_DMA_NOWAIT)) {
536 			device_printf(sc->mrsas_dev, "Cannot load ioctl "
537 			    "passthru data mem%s %d\n", curproc->p_comm, ioctl_data_size);
538 			ret = ENOMEM;
539 			goto out;
540 		}
541 
542 		while (passcmd->complete == 0) {
543 			pause("mrsas_passthru", hz);
544 		}
545 
546 		cmd->frame->dcmd.sge_count = passcmd->sge_count;
547 	}
548 
549 	/*
550 	 * Set the sync_cmd flag so that the ISR knows not to complete this
551 	 * cmd to the SCSI mid-layer
552 	 */
553 	cmd->sync_cmd = 1;
554 	mrsas_issue_blocked_cmd(sc, cmd);
555 	cmd->sync_cmd = 0;
556 
557 	if (ioctl_data_size != 0) {
558 		bus_dmamap_sync(ioctl_data_tag, ioctl_data_dmamap,
559 		    BUS_DMASYNC_POSTREAD);
560 		/*
561 		 * copy out the kernel buffers to user buffers
562 		 */
563 		ret = copyout(ioctl_temp_data_mem, ioc->buf, ioc->buf_size);
564 		if (ret) {
565 			device_printf(sc->mrsas_dev,
566 			    "IOCTL copyout failed!\n");
567 			goto out;
568 		}
569 	}
570 
571 	/*
572 	 * Return command status to user space
573 	 */
574 	memcpy(&ioc->ioc_frame.cmd_status, &cmd->frame->hdr.cmd_status,
575 	    sizeof(u_int8_t));
576 
577 out:
578 	/*
579 	 * Release temporary passthrough ioctl
580 	 */
581 	if (ioctl_temp_data_mem)
582 		free(ioctl_temp_data_mem, M_MRSAS);
583 	if (passcmd)
584 		free(passcmd, M_MRSAS);
585 
586 	/*
587 	 * Release data buffers
588 	 */
589 	if (ioctl_data_phys_addr) {
590 		bus_dmamap_unload(ioctl_data_tag, ioctl_data_dmamap);
591 		bus_dmamap_destroy(ioctl_data_tag, ioctl_data_dmamap);
592 	}
593 	if (ioctl_data_tag != NULL)
594 		bus_dma_tag_destroy(ioctl_data_tag);
595 	/* Free command */
596 	mrsas_release_mfi_cmd(cmd);
597 
598 	return(ret);
599 }
600 
601 
602 /*
603  * mrsas_alloc_mfi_cmds:	Allocates the command packets
604  * input:					Adapter instance soft state
605  *
606  * Each IOCTL or passthru command that is issued to the FW are wrapped in a
607  * local data structure called mrsas_mfi_cmd.  The frame embedded in this
608  * mrsas_mfi is issued to FW. The array is used only to look up the
609  * mrsas_mfi_cmd given the context. The free commands are maintained in a
610  * linked list.
611  */
612 int
613 mrsas_alloc_mfi_cmds(struct mrsas_softc *sc)
614 {
615 	int i, j;
616 	u_int32_t max_cmd;
617 	struct mrsas_mfi_cmd *cmd;
618 
619 	max_cmd = MRSAS_MAX_MFI_CMDS;
620 
621 	/*
622 	 * sc->mfi_cmd_list is an array of struct mrsas_mfi_cmd pointers.
623 	 * Allocate the dynamic array first and then allocate individual
624 	 * commands.
625 	 */
626 	sc->mfi_cmd_list = malloc(sizeof(struct mrsas_mfi_cmd *) * max_cmd, M_MRSAS, M_NOWAIT);
627 	if (!sc->mfi_cmd_list) {
628 		device_printf(sc->mrsas_dev, "Cannot alloc memory for mfi_cmd cmd_list.\n");
629 		return (ENOMEM);
630 	}
631 	memset(sc->mfi_cmd_list, 0, sizeof(struct mrsas_mfi_cmd *) * max_cmd);
632 	for (i = 0; i < max_cmd; i++) {
633 		sc->mfi_cmd_list[i] = malloc(sizeof(struct mrsas_mfi_cmd),
634 		    M_MRSAS, M_NOWAIT);
635 		if (!sc->mfi_cmd_list[i]) {
636 			for (j = 0; j < i; j++)
637 				free(sc->mfi_cmd_list[j], M_MRSAS);
638 			free(sc->mfi_cmd_list, M_MRSAS);
639 			sc->mfi_cmd_list = NULL;
640 			return (ENOMEM);
641 		}
642 	}
643 
644 	for (i = 0; i < max_cmd; i++) {
645 		cmd = sc->mfi_cmd_list[i];
646 		memset(cmd, 0, sizeof(struct mrsas_mfi_cmd));
647 		cmd->index = i;
648 		cmd->ccb_ptr = NULL;
649 		cmd->sc = sc;
650 		TAILQ_INSERT_TAIL(&(sc->mrsas_mfi_cmd_list_head), cmd, next);
651 	}
652 
653 	/* create a frame pool and assign one frame to each command */
654 	if (mrsas_create_frame_pool(sc)) {
655 		device_printf(sc->mrsas_dev, "Cannot allocate DMA frame pool.\n");
656 		/* Free the frames */
657 		for (i = 0; i < MRSAS_MAX_MFI_CMDS; i++) {
658 			cmd = sc->mfi_cmd_list[i];
659 			mrsas_free_frame(sc, cmd);
660 		}
661 		if (sc->mficmd_frame_tag != NULL)
662 			bus_dma_tag_destroy(sc->mficmd_frame_tag);
663 		return (ENOMEM);
664 	}
665 	return (0);
666 }
667 
668 /*
669  * mrsas_create_frame_pool:	Creates DMA pool for cmd frames
670  * input:					Adapter soft state
671  *
672  * Each command packet has an embedded DMA memory buffer that is used for
673  * filling MFI frame and the SG list that immediately follows the frame. This
674  * function creates those DMA memory buffers for each command packet by using
675  * PCI pool facility. pad_0 is initialized to 0 to prevent corrupting value
676  * of context and could cause FW crash.
677  */
678 static int
679 mrsas_create_frame_pool(struct mrsas_softc *sc)
680 {
681 	int i;
682 	struct mrsas_mfi_cmd *cmd;
683 
684 	if (bus_dma_tag_create(sc->mrsas_parent_tag,
685 	    1, 0,
686 	    BUS_SPACE_MAXADDR_32BIT,
687 	    BUS_SPACE_MAXADDR,
688 	    NULL, NULL,
689 	    MRSAS_MFI_FRAME_SIZE,
690 	    1,
691 	    MRSAS_MFI_FRAME_SIZE,
692 	    BUS_DMA_ALLOCNOW,
693 	    NULL, NULL,
694 	    &sc->mficmd_frame_tag)) {
695 		device_printf(sc->mrsas_dev, "Cannot create MFI frame tag\n");
696 		return (ENOMEM);
697 	}
698 	for (i = 0; i < MRSAS_MAX_MFI_CMDS; i++) {
699 		cmd = sc->mfi_cmd_list[i];
700 		cmd->frame = mrsas_alloc_frame(sc, cmd);
701 		if (cmd->frame == NULL) {
702 			device_printf(sc->mrsas_dev, "Cannot alloc MFI frame memory\n");
703 			return (ENOMEM);
704 		}
705 		/*
706 		 * For MFI controllers.
707 		 * max_num_sge = 60
708 		 * max_sge_sz  = 16 byte (sizeof megasas_sge_skinny)
709 		 * Totl 960 byte (15 MFI frame of 64 byte)
710 		 *
711 		 * Fusion adapter require only 3 extra frame.
712 		 * max_num_sge = 16 (defined as MAX_IOCTL_SGE)
713 		 * max_sge_sz  = 12 byte (sizeof  megasas_sge64)
714 		 * Total 192 byte (3 MFI frame of 64 byte)
715 		 */
716 		memset(cmd->frame, 0, MRSAS_MFI_FRAME_SIZE);
717 		cmd->frame->io.context = cmd->index;
718 		cmd->frame->io.pad_0 = 0;
719 	}
720 
721 	return (0);
722 }
723 
724 /*
725  * mrsas_alloc_frame:	Allocates MFI Frames
726  * input:				Adapter soft state
727  *
728  * Create bus DMA memory tag and dmamap and load memory for MFI frames. Returns
729  * virtual memory pointer to allocated region.
730  */
731 void   *
732 mrsas_alloc_frame(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd)
733 {
734 	u_int32_t frame_size = MRSAS_MFI_FRAME_SIZE;
735 
736 	if (bus_dmamem_alloc(sc->mficmd_frame_tag, (void **)&cmd->frame_mem,
737 	    BUS_DMA_NOWAIT, &cmd->frame_dmamap)) {
738 		device_printf(sc->mrsas_dev, "Cannot alloc MFI frame memory\n");
739 		return (NULL);
740 	}
741 	if (bus_dmamap_load(sc->mficmd_frame_tag, cmd->frame_dmamap,
742 	    cmd->frame_mem, frame_size, mrsas_alloc_cb,
743 	    &cmd->frame_phys_addr, BUS_DMA_NOWAIT)) {
744 		device_printf(sc->mrsas_dev, "Cannot load IO request memory\n");
745 		return (NULL);
746 	}
747 	return (cmd->frame_mem);
748 }
749 
750 /*
751  * mrsas_alloc_cb:	Callback function of bus_dmamap_load()
752  * input:			callback argument,
753  * 					machine dependent type that describes DMA segments,
754  * 					number of segments,
755  * 					error code.
756  *
757  * This function is for the driver to receive mapping information resultant of
758  * the bus_dmamap_load(). The information is actually not being used, but the
759  * address is saved anyway.
760  */
761 static void
762 mrsas_alloc_cb(void *arg, bus_dma_segment_t *segs,
763     int nsegs, int error)
764 {
765 	bus_addr_t *addr;
766 
767 	addr = arg;
768 	*addr = segs[0].ds_addr;
769 }
770 
771 /*
772  * mrsas_free_frames:	Frees memory for  MFI frames
773  * input:				Adapter soft state
774  *
775  * Deallocates MFI frames memory.  Called from mrsas_free_mem() during detach
776  * and error case during creation of frame pool.
777  */
778 void
779 mrsas_free_frame(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd)
780 {
781 	if (cmd->frame_phys_addr)
782 		bus_dmamap_unload(sc->mficmd_frame_tag, cmd->frame_dmamap);
783 	if (cmd->frame_mem != NULL)
784 		bus_dmamem_free(sc->mficmd_frame_tag, cmd->frame_mem, cmd->frame_dmamap);
785 }
786