xref: /dragonfly/sys/dev/raid/twa/tw_osl_freebsd.c (revision 650094e1)
1 /*
2  * Copyright (c) 2004-07 Applied Micro Circuits Corporation.
3  * Copyright (c) 2004-05 Vinod Kashyap.
4  * Copyright (c) 2000 Michael Smith
5  * Copyright (c) 2000 BSDi
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  *	$FreeBSD: src/sys/dev/twa/tw_osl_freebsd.c,v 1.18 2010/09/04 16:27:14 bz Exp $
30  */
31 
32 /*
33  * AMCC'S 3ware driver for 9000 series storage controllers.
34  *
35  * Author: Vinod Kashyap
36  * Modifications by: Adam Radford
37  * Modifications by: Manjunath Ranganathaiah
38  */
39 
40 
41 /*
42  * FreeBSD specific functions not related to CAM, and other
43  * miscellaneous functions.
44  */
45 
46 
47 #include <dev/raid/twa/tw_osl_includes.h>
48 #include <dev/raid/twa/tw_cl_fwif.h>
49 #include <dev/raid/twa/tw_cl_ioctl.h>
50 #include <dev/raid/twa/tw_osl_ioctl.h>
51 
52 #ifdef TW_OSL_DEBUG
53 TW_INT32	TW_DEBUG_LEVEL_FOR_OSL = TW_OSL_DEBUG;
54 TW_INT32	TW_OSL_DEBUG_LEVEL_FOR_CL = TW_OSL_DEBUG;
55 #endif /* TW_OSL_DEBUG */
56 
57 MALLOC_DEFINE(TW_OSLI_MALLOC_CLASS, "twa_commands", "twa commands");
58 
59 
60 static	d_open_t		twa_open;
61 static	d_close_t		twa_close;
62 static	d_ioctl_t		twa_ioctl;
63 
64 static struct dev_ops twa_ops = {
65 	{ "twa", 0, 0 },
66 	.d_open =	twa_open,
67 	.d_close =	twa_close,
68 	.d_ioctl =	twa_ioctl,
69 };
70 
71 static devclass_t	twa_devclass;
72 
73 
74 /*
75  * Function name:	twa_open
76  * Description:		Called when the controller is opened.
77  *			Simply marks the controller as open.
78  *
79  * Input:		dev	-- control device corresponding to the ctlr
80  *			flags	-- mode of open
81  *			fmt	-- device type (character/block etc.)
82  *			proc	-- current process
83  * Output:		None
84  * Return value:	0	-- success
85  *			non-zero-- failure
86  */
87 static TW_INT32
88 twa_open(struct dev_open_args *ap)
89 {
90 	cdev_t			dev = ap->a_head.a_dev;
91 	struct twa_softc	*sc = (struct twa_softc *)(dev->si_drv1);
92 
93 	tw_osli_dbg_dprintf(5, sc, "entered");
94 	sc->open = TW_CL_TRUE;
95 	return(0);
96 }
97 
98 
99 
100 /*
101  * Function name:	twa_close
102  * Description:		Called when the controller is closed.
103  *			Simply marks the controller as not open.
104  *
105  * Input:		dev	-- control device corresponding to the ctlr
106  *			flags	-- mode of corresponding open
107  *			fmt	-- device type (character/block etc.)
108  *			proc	-- current process
109  * Output:		None
110  * Return value:	0	-- success
111  *			non-zero-- failure
112  */
113 static TW_INT32
114 twa_close(struct dev_close_args *ap)
115 {
116 	cdev_t			dev = ap->a_head.a_dev;
117 	struct twa_softc	*sc = (struct twa_softc *)(dev->si_drv1);
118 
119 	tw_osli_dbg_dprintf(5, sc, "entered");
120 	sc->open = TW_CL_FALSE;
121 	return(0);
122 }
123 
124 
125 
126 /*
127  * Function name:	twa_ioctl
128  * Description:		Called when an ioctl is posted to the controller.
129  *			Handles any OS Layer specific cmds, passes the rest
130  *			on to the Common Layer.
131  *
132  * Input:		dev	-- control device corresponding to the ctlr
133  *			cmd	-- ioctl cmd
134  *			buf	-- ptr to buffer in kernel memory, which is
135  *				   a copy of the input buffer in user-space
136  *			flags	-- mode of corresponding open
137  *			proc	-- current process
138  * Output:		buf	-- ptr to buffer in kernel memory, which will
139  *				   be copied to the output buffer in user-space
140  * Return value:	0	-- success
141  *			non-zero-- failure
142  */
143 static TW_INT32
144 twa_ioctl(struct dev_ioctl_args *ap)
145 {
146 	cdev_t			dev = ap->a_head.a_dev;
147 	u_long			cmd = ap->a_cmd;
148 	caddr_t			buf = ap->a_data;
149 	struct twa_softc	*sc = (struct twa_softc *)(dev->si_drv1);
150 	TW_INT32		error;
151 
152 	tw_osli_dbg_dprintf(5, sc, "entered");
153 
154 	switch (cmd) {
155 	case TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH:
156 		tw_osli_dbg_dprintf(6, sc, "ioctl: fw_passthru");
157 		error = tw_osli_fw_passthru(sc, (TW_INT8 *)buf);
158 		break;
159 
160 	case TW_OSL_IOCTL_SCAN_BUS:
161 		/* Request CAM for a bus scan. */
162 		tw_osli_dbg_dprintf(6, sc, "ioctl: scan bus");
163 		error = tw_osli_request_bus_scan(sc);
164 		break;
165 
166 	default:
167 		tw_osli_dbg_dprintf(6, sc, "ioctl: 0x%lx", cmd);
168 		error = tw_cl_ioctl(&sc->ctlr_handle, cmd, buf);
169 		break;
170 	}
171 	return(error);
172 }
173 
174 
175 
176 static TW_INT32	twa_probe(device_t dev);
177 static TW_INT32	twa_attach(device_t dev);
178 static TW_INT32	twa_detach(device_t dev);
179 static TW_INT32	twa_shutdown(device_t dev);
180 #if 0 /* XXX swildner */
181 static TW_VOID	twa_busdma_lock(TW_VOID *lock_arg, bus_dma_lock_op_t op);
182 #endif
183 static TW_VOID	twa_pci_intr(TW_VOID *arg);
184 static TW_VOID	twa_watchdog(TW_VOID *arg);
185 int twa_setup_intr(struct twa_softc *sc);
186 int twa_teardown_intr(struct twa_softc *sc);
187 
188 static TW_INT32	tw_osli_alloc_mem(struct twa_softc *sc);
189 static TW_VOID	tw_osli_free_resources(struct twa_softc *sc);
190 
191 static TW_VOID	twa_map_load_data_callback(TW_VOID *arg,
192 	bus_dma_segment_t *segs, TW_INT32 nsegments, TW_INT32 error);
193 static TW_VOID	twa_map_load_callback(TW_VOID *arg,
194 	bus_dma_segment_t *segs, TW_INT32 nsegments, TW_INT32 error);
195 
196 
197 static device_method_t	twa_methods[] = {
198 	/* Device interface */
199 	DEVMETHOD(device_probe,		twa_probe),
200 	DEVMETHOD(device_attach,	twa_attach),
201 	DEVMETHOD(device_detach,	twa_detach),
202 	DEVMETHOD(device_shutdown,	twa_shutdown),
203 
204 	DEVMETHOD(bus_print_child,	bus_generic_print_child),
205 	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
206 	{0, 0}
207 };
208 
209 static driver_t	twa_pci_driver = {
210 	"twa",
211 	twa_methods,
212 	sizeof(struct twa_softc)
213 };
214 
215 DRIVER_MODULE(twa, pci, twa_pci_driver, twa_devclass, NULL, NULL);
216 MODULE_DEPEND(twa, cam, 1, 1, 1);
217 MODULE_DEPEND(twa, pci, 1, 1, 1);
218 
219 
220 /*
221  * Function name:	twa_probe
222  * Description:		Called at driver load time.  Claims 9000 ctlrs.
223  *
224  * Input:		dev	-- bus device corresponding to the ctlr
225  * Output:		None
226  * Return value:	<= 0	-- success
227  *			> 0	-- failure
228  */
229 static TW_INT32
230 twa_probe(device_t dev)
231 {
232 	static TW_UINT8	first_ctlr = 1;
233 
234 	tw_osli_dbg_printf(3, "entered");
235 
236 	if (tw_cl_ctlr_supported(pci_get_vendor(dev), pci_get_device(dev))) {
237 		device_set_desc(dev, TW_OSLI_DEVICE_NAME);
238 		/* Print the driver version only once. */
239 		if (first_ctlr) {
240 			kprintf("3ware device driver for 9000 series storage "
241 				"controllers, version: %s\n",
242 				TW_OSL_DRIVER_VERSION_STRING);
243 			first_ctlr = 0;
244 		}
245 		return(0);
246 	}
247 	return(ENXIO);
248 }
249 
250 int twa_setup_intr(struct twa_softc *sc)
251 {
252 	int error = 0;
253 
254 	if (!(sc->intr_handle) && (sc->irq_res)) {
255 		error = bus_setup_intr(sc->bus_dev, sc->irq_res,
256 					0,
257 					twa_pci_intr,
258 					sc, &sc->intr_handle, NULL);
259 	}
260 	return( error );
261 }
262 
263 
264 int twa_teardown_intr(struct twa_softc *sc)
265 {
266 	int error = 0;
267 
268 	if ((sc->intr_handle) && (sc->irq_res)) {
269 		error = bus_teardown_intr(sc->bus_dev,
270 						sc->irq_res, sc->intr_handle);
271 		sc->intr_handle = NULL;
272 	}
273 	return( error );
274 }
275 
276 
277 
278 /*
279  * Function name:	twa_attach
280  * Description:		Allocates pci resources; updates sc; adds a node to the
281  *			sysctl tree to expose the driver version; makes calls
282  *			(to the Common Layer) to initialize ctlr, and to
283  *			attach to CAM.
284  *
285  * Input:		dev	-- bus device corresponding to the ctlr
286  * Output:		None
287  * Return value:	0	-- success
288  *			non-zero-- failure
289  */
290 static TW_INT32
291 twa_attach(device_t dev)
292 {
293 	struct twa_softc	*sc = device_get_softc(dev);
294 	TW_UINT32		command;
295 	TW_INT32		bar_num;
296 	TW_INT32		bar0_offset;
297 	TW_INT32		bar_size;
298 	TW_INT32		error;
299 
300 	tw_osli_dbg_dprintf(3, sc, "entered");
301 
302 	sc->ctlr_handle.osl_ctlr_ctxt = sc;
303 
304 	/* Initialize the softc structure. */
305 	sc->bus_dev = dev;
306 	sc->device_id = pci_get_device(dev);
307 
308 	/* Initialize the mutexes right here. */
309 	sc->io_lock = &(sc->io_lock_handle);
310 	spin_init(sc->io_lock);
311 	sc->q_lock = &(sc->q_lock_handle);
312 	spin_init(sc->q_lock);
313 	sc->sim_lock = &(sc->sim_lock_handle);
314 	lockinit(sc->sim_lock, "tw_osl_sim_lock", 0, LK_CANRECURSE);
315 
316 	sysctl_ctx_init(&sc->sysctl_ctxt);
317 	sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctxt,
318 		SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO,
319 		device_get_nameunit(dev), CTLFLAG_RD, 0, "");
320 	if (sc->sysctl_tree == NULL) {
321 		tw_osli_printf(sc, "error = %d",
322 			TW_CL_SEVERITY_ERROR_STRING,
323 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
324 			0x2000,
325 			"Cannot add sysctl tree node",
326 			ENXIO);
327 		return(ENXIO);
328 	}
329 	SYSCTL_ADD_STRING(&sc->sysctl_ctxt, SYSCTL_CHILDREN(sc->sysctl_tree),
330 		OID_AUTO, "driver_version", CTLFLAG_RD,
331 		TW_OSL_DRIVER_VERSION_STRING, 0, "TWA driver version");
332 
333 	/* Make sure we are going to be able to talk to this board. */
334 	command = pci_read_config(dev, PCIR_COMMAND, 2);
335 	if ((command & PCIM_CMD_PORTEN) == 0) {
336 		tw_osli_printf(sc, "error = %d",
337 			TW_CL_SEVERITY_ERROR_STRING,
338 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
339 			0x2001,
340 			"Register window not available",
341 			ENXIO);
342 		tw_osli_free_resources(sc);
343 		return(ENXIO);
344 	}
345 
346 	/* Force the busmaster enable bit on, in case the BIOS forgot. */
347 	command |= PCIM_CMD_BUSMASTEREN;
348 	pci_write_config(dev, PCIR_COMMAND, command, 2);
349 
350 	/* Allocate the PCI register window. */
351 	if ((error = tw_cl_get_pci_bar_info(sc->device_id, TW_CL_BAR_TYPE_MEM,
352 		&bar_num, &bar0_offset, &bar_size))) {
353 		tw_osli_printf(sc, "error = %d",
354 			TW_CL_SEVERITY_ERROR_STRING,
355 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
356 			0x201F,
357 			"Can't get PCI BAR info",
358 			error);
359 		tw_osli_free_resources(sc);
360 		return(error);
361 	}
362 	sc->reg_res_id = PCIR_BARS + bar0_offset;
363 	if ((sc->reg_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
364 				&(sc->reg_res_id), 0, ~0, 1, RF_ACTIVE))
365 				== NULL) {
366 		tw_osli_printf(sc, "error = %d",
367 			TW_CL_SEVERITY_ERROR_STRING,
368 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
369 			0x2002,
370 			"Can't allocate register window",
371 			ENXIO);
372 		tw_osli_free_resources(sc);
373 		return(ENXIO);
374 	}
375 	sc->bus_tag = rman_get_bustag(sc->reg_res);
376 	sc->bus_handle = rman_get_bushandle(sc->reg_res);
377 
378 	/* Allocate and register our interrupt. */
379 	sc->irq_res_id = 0;
380 	if ((sc->irq_res = bus_alloc_resource(sc->bus_dev, SYS_RES_IRQ,
381 				&(sc->irq_res_id), 0, ~0, 1,
382 				RF_SHAREABLE | RF_ACTIVE)) == NULL) {
383 		tw_osli_printf(sc, "error = %d",
384 			TW_CL_SEVERITY_ERROR_STRING,
385 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
386 			0x2003,
387 			"Can't allocate interrupt",
388 			ENXIO);
389 		tw_osli_free_resources(sc);
390 		return(ENXIO);
391 	}
392 	if ((error = twa_setup_intr(sc))) {
393 		tw_osli_printf(sc, "error = %d",
394 			TW_CL_SEVERITY_ERROR_STRING,
395 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
396 			0x2004,
397 			"Can't set up interrupt",
398 			error);
399 		tw_osli_free_resources(sc);
400 		return(error);
401 	}
402 
403 	if ((error = tw_osli_alloc_mem(sc))) {
404 		tw_osli_printf(sc, "error = %d",
405 			TW_CL_SEVERITY_ERROR_STRING,
406 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
407 			0x2005,
408 			"Memory allocation failure",
409 			error);
410 		tw_osli_free_resources(sc);
411 		return(error);
412 	}
413 
414 	/* Initialize the Common Layer for this controller. */
415 	if ((error = tw_cl_init_ctlr(&sc->ctlr_handle, sc->flags, sc->device_id,
416 			TW_OSLI_MAX_NUM_REQUESTS, TW_OSLI_MAX_NUM_AENS,
417 			sc->non_dma_mem, sc->dma_mem,
418 			sc->dma_mem_phys
419 			))) {
420 		tw_osli_printf(sc, "error = %d",
421 			TW_CL_SEVERITY_ERROR_STRING,
422 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
423 			0x2006,
424 			"Failed to initialize Common Layer/controller",
425 			error);
426 		tw_osli_free_resources(sc);
427 		return(error);
428 	}
429 
430 	/* Create the control device. */
431 	sc->ctrl_dev = make_dev(&twa_ops, device_get_unit(sc->bus_dev),
432 			UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
433 			"twa%d", device_get_unit(sc->bus_dev));
434 	sc->ctrl_dev->si_drv1 = sc;
435 
436 	if ((error = tw_osli_cam_attach(sc))) {
437 		tw_osli_free_resources(sc);
438 		tw_osli_printf(sc, "error = %d",
439 			TW_CL_SEVERITY_ERROR_STRING,
440 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
441 			0x2007,
442 			"Failed to initialize CAM",
443 			error);
444 		return(error);
445 	}
446 
447 	sc->watchdog_index = 0;
448 	callout_init(&(sc->watchdog_callout[0]));
449 	callout_init(&(sc->watchdog_callout[1]));
450 	callout_reset(&(sc->watchdog_callout[0]), 5*hz, twa_watchdog, &sc->ctlr_handle);
451 
452 	return(0);
453 }
454 
455 
456 static TW_VOID
457 twa_watchdog(TW_VOID *arg)
458 {
459 	struct tw_cl_ctlr_handle *ctlr_handle =
460 		(struct tw_cl_ctlr_handle *)arg;
461 	struct twa_softc		*sc = ctlr_handle->osl_ctlr_ctxt;
462 	int				i;
463 	int				i_need_a_reset = 0;
464 	int				driver_is_active = 0;
465 	TW_UINT64			current_time;
466 	struct tw_osli_req_context	*my_req;
467 
468 
469 //==============================================================================
470 	current_time = (TW_UINT64) (tw_osl_get_local_time());
471 
472 	for (i = 0; i < TW_OSLI_MAX_NUM_REQUESTS; i++) {
473 		my_req = &(sc->req_ctx_buf[i]);
474 
475 		if ((my_req->state == TW_OSLI_REQ_STATE_BUSY) &&
476 			(my_req->deadline) &&
477 			(my_req->deadline < current_time)) {
478 			tw_cl_set_reset_needed(ctlr_handle);
479 #ifdef    TW_OSL_DEBUG
480 			device_printf((sc)->bus_dev, "Request %d timed out! d = %llu, c = %llu\n", i, my_req->deadline, current_time);
481 #else  /* TW_OSL_DEBUG */
482 			device_printf((sc)->bus_dev, "Request %d timed out!\n", i);
483 #endif /* TW_OSL_DEBUG */
484 			break;
485 		}
486 	}
487 //==============================================================================
488 
489 	i_need_a_reset = tw_cl_is_reset_needed(ctlr_handle);
490 
491 	i = (int) ((sc->watchdog_index++) & 1);
492 
493 	driver_is_active = tw_cl_is_active(ctlr_handle);
494 
495 	if (i_need_a_reset) {
496 #ifdef    TW_OSL_DEBUG
497 		device_printf((sc)->bus_dev, "Watchdog rescheduled in 70 seconds\n");
498 #endif /* TW_OSL_DEBUG */
499 		callout_reset(&(sc->watchdog_callout[i]), 70*hz, twa_watchdog, &sc->ctlr_handle);
500 		tw_cl_reset_ctlr(ctlr_handle);
501 #ifdef    TW_OSL_DEBUG
502 		device_printf((sc)->bus_dev, "Watchdog reset completed!\n");
503 #endif /* TW_OSL_DEBUG */
504 	} else if (driver_is_active) {
505 		callout_reset(&(sc->watchdog_callout[i]),  5*hz, twa_watchdog, &sc->ctlr_handle);
506 	}
507 #ifdef    TW_OSL_DEBUG
508 	if (i_need_a_reset)
509 		device_printf((sc)->bus_dev, "i_need_a_reset = %d, "
510 		"driver_is_active = %d\n",
511 		i_need_a_reset, driver_is_active);
512 #endif /* TW_OSL_DEBUG */
513 }
514 
515 
516 /*
517  * Function name:	tw_osli_alloc_mem
518  * Description:		Allocates memory needed both by CL and OSL.
519  *
520  * Input:		sc	-- OSL internal controller context
521  * Output:		None
522  * Return value:	0	-- success
523  *			non-zero-- failure
524  */
525 static TW_INT32
526 tw_osli_alloc_mem(struct twa_softc *sc)
527 {
528 	struct tw_osli_req_context	*req;
529 	TW_UINT32			max_sg_elements;
530 	TW_UINT32			non_dma_mem_size;
531 	TW_UINT32			dma_mem_size;
532 	TW_INT32			error;
533 	TW_INT32			i;
534 
535 	tw_osli_dbg_dprintf(3, sc, "entered");
536 
537 	sc->flags |= (sizeof(bus_addr_t) == 8) ? TW_CL_64BIT_ADDRESSES : 0;
538 	sc->flags |= (sizeof(bus_size_t) == 8) ? TW_CL_64BIT_SG_LENGTH : 0;
539 
540 	max_sg_elements = (sizeof(bus_addr_t) == 8) ?
541 		TW_CL_MAX_64BIT_SG_ELEMENTS : TW_CL_MAX_32BIT_SG_ELEMENTS;
542 
543 	if ((error = tw_cl_get_mem_requirements(&sc->ctlr_handle, sc->flags,
544 			sc->device_id, TW_OSLI_MAX_NUM_REQUESTS,  TW_OSLI_MAX_NUM_AENS,
545 			&(sc->alignment), &(sc->sg_size_factor),
546 			&non_dma_mem_size, &dma_mem_size
547 			))) {
548 		tw_osli_printf(sc, "error = %d",
549 			TW_CL_SEVERITY_ERROR_STRING,
550 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
551 			0x2008,
552 			"Can't get Common Layer's memory requirements",
553 			error);
554 		return(error);
555 	}
556 
557 	sc->non_dma_mem = kmalloc(non_dma_mem_size, TW_OSLI_MALLOC_CLASS,
558 	    M_WAITOK);
559 
560 	/* Create the parent dma tag. */
561 	if (bus_dma_tag_create(NULL,			/* parent */
562 				sc->alignment,		/* alignment */
563 				TW_OSLI_DMA_BOUNDARY,	/* boundary */
564 				BUS_SPACE_MAXADDR,	/* lowaddr */
565 				BUS_SPACE_MAXADDR, 	/* highaddr */
566 				NULL, NULL, 		/* filter, filterarg */
567 				TW_CL_MAX_IO_SIZE,	/* maxsize */
568 				max_sg_elements,	/* nsegments */
569 				TW_CL_MAX_IO_SIZE,	/* maxsegsize */
570 				0,			/* flags */
571 				&sc->parent_tag		/* tag */)) {
572 		tw_osli_printf(sc, "error = %d",
573 			TW_CL_SEVERITY_ERROR_STRING,
574 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
575 			0x200A,
576 			"Can't allocate parent DMA tag",
577 			ENOMEM);
578 		return(ENOMEM);
579 	}
580 
581 	/* Create a dma tag for Common Layer's DMA'able memory (dma_mem). */
582 	if (bus_dma_tag_create(sc->parent_tag,		/* parent */
583 				sc->alignment,		/* alignment */
584 				0,			/* boundary */
585 				BUS_SPACE_MAXADDR,	/* lowaddr */
586 				BUS_SPACE_MAXADDR, 	/* highaddr */
587 				NULL, NULL, 		/* filter, filterarg */
588 				dma_mem_size,		/* maxsize */
589 				1,			/* nsegments */
590 				BUS_SPACE_MAXSIZE,	/* maxsegsize */
591 				0,			/* flags */
592 				&sc->cmd_tag		/* tag */)) {
593 		tw_osli_printf(sc, "error = %d",
594 			TW_CL_SEVERITY_ERROR_STRING,
595 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
596 			0x200B,
597 			"Can't allocate DMA tag for Common Layer's "
598 			"DMA'able memory",
599 			ENOMEM);
600 		return(ENOMEM);
601 	}
602 
603 	if (bus_dmamem_alloc(sc->cmd_tag, &sc->dma_mem,
604 		BUS_DMA_NOWAIT, &sc->cmd_map)) {
605 		/* Try a second time. */
606 		if (bus_dmamem_alloc(sc->cmd_tag, &sc->dma_mem,
607 			BUS_DMA_NOWAIT, &sc->cmd_map)) {
608 			tw_osli_printf(sc, "error = %d",
609 				TW_CL_SEVERITY_ERROR_STRING,
610 				TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
611 				0x200C,
612 				"Can't allocate DMA'able memory for the"
613 				"Common Layer",
614 				ENOMEM);
615 			return(ENOMEM);
616 		}
617 	}
618 
619 	bus_dmamap_load(sc->cmd_tag, sc->cmd_map, sc->dma_mem,
620 		dma_mem_size, twa_map_load_callback,
621 		&sc->dma_mem_phys, 0);
622 
623 	/*
624 	 * Create a dma tag for data buffers; size will be the maximum
625 	 * possible I/O size (128kB).
626 	 */
627 	if (bus_dma_tag_create(sc->parent_tag,		/* parent */
628 				sc->alignment,		/* alignment */
629 				0,			/* boundary */
630 				BUS_SPACE_MAXADDR,	/* lowaddr */
631 				BUS_SPACE_MAXADDR, 	/* highaddr */
632 				NULL, NULL, 		/* filter, filterarg */
633 				TW_CL_MAX_IO_SIZE,	/* maxsize */
634 				max_sg_elements,	/* nsegments */
635 				TW_CL_MAX_IO_SIZE,	/* maxsegsize */
636 				BUS_DMA_ALLOCNOW,	/* flags */
637 #if 0 /* XXX swildner */
638 				twa_busdma_lock,	/* lockfunc */
639 				sc->io_lock,		/* lockfuncarg */
640 #endif
641 				&sc->dma_tag		/* tag */)) {
642 		tw_osli_printf(sc, "error = %d",
643 			TW_CL_SEVERITY_ERROR_STRING,
644 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
645 			0x200F,
646 			"Can't allocate DMA tag for data buffers",
647 			ENOMEM);
648 		return(ENOMEM);
649 	}
650 
651 	/*
652 	 * Create a dma tag for ioctl data buffers; size will be the maximum
653 	 * possible I/O size (128kB).
654 	 */
655 	if (bus_dma_tag_create(sc->parent_tag,		/* parent */
656 				sc->alignment,		/* alignment */
657 				0,			/* boundary */
658 				BUS_SPACE_MAXADDR,	/* lowaddr */
659 				BUS_SPACE_MAXADDR, 	/* highaddr */
660 				NULL, NULL, 		/* filter, filterarg */
661 				TW_CL_MAX_IO_SIZE,	/* maxsize */
662 				max_sg_elements,	/* nsegments */
663 				TW_CL_MAX_IO_SIZE,	/* maxsegsize */
664 				BUS_DMA_ALLOCNOW,	/* flags */
665 #if 0 /* XXX swildner */
666 				twa_busdma_lock,	/* lockfunc */
667 				sc->io_lock,		/* lockfuncarg */
668 #endif
669 				&sc->ioctl_tag		/* tag */)) {
670 		tw_osli_printf(sc, "error = %d",
671 			TW_CL_SEVERITY_ERROR_STRING,
672 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
673 			0x2010,
674 			"Can't allocate DMA tag for ioctl data buffers",
675 			ENOMEM);
676 		return(ENOMEM);
677 	}
678 
679 	/* Create just one map for all ioctl request data buffers. */
680 	if (bus_dmamap_create(sc->ioctl_tag, 0, &sc->ioctl_map)) {
681 		tw_osli_printf(sc, "error = %d",
682 			TW_CL_SEVERITY_ERROR_STRING,
683 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
684 			0x2011,
685 			"Can't create ioctl map",
686 			ENOMEM);
687 		return(ENOMEM);
688 	}
689 
690 
691 	/* Initialize request queues. */
692 	tw_osli_req_q_init(sc, TW_OSLI_FREE_Q);
693 	tw_osli_req_q_init(sc, TW_OSLI_BUSY_Q);
694 
695 	sc->req_ctx_buf = kmalloc((sizeof(struct tw_osli_req_context) *
696 	    TW_OSLI_MAX_NUM_REQUESTS), TW_OSLI_MALLOC_CLASS,
697 	    M_WAITOK | M_ZERO);
698 	for (i = 0; i < TW_OSLI_MAX_NUM_REQUESTS; i++) {
699 		req = &(sc->req_ctx_buf[i]);
700 		req->ctlr = sc;
701 		if (bus_dmamap_create(sc->dma_tag, 0, &req->dma_map)) {
702 			tw_osli_printf(sc, "request # = %d, error = %d",
703 				TW_CL_SEVERITY_ERROR_STRING,
704 				TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
705 				0x2013,
706 				"Can't create dma map",
707 				i, ENOMEM);
708 			return(ENOMEM);
709 		}
710 
711 		/* Initialize the ioctl wakeup/ timeout mutex */
712 		req->ioctl_wake_timeout_lock = &(req->ioctl_wake_timeout_lock_handle);
713 		lockinit(req->ioctl_wake_timeout_lock, "tw_ioctl_wake_timeout_lock", 0, 0);
714 
715 		/* Insert request into the free queue. */
716 		tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
717 	}
718 
719 	return(0);
720 }
721 
722 
723 
724 /*
725  * Function name:	tw_osli_free_resources
726  * Description:		Performs clean-up at the time of going down.
727  *
728  * Input:		sc	-- ptr to OSL internal ctlr context
729  * Output:		None
730  * Return value:	None
731  */
732 static TW_VOID
733 tw_osli_free_resources(struct twa_softc *sc)
734 {
735 	struct tw_osli_req_context	*req;
736 	TW_INT32			error = 0;
737 
738 	tw_osli_dbg_dprintf(3, sc, "entered");
739 
740 	/* Detach from CAM */
741 	tw_osli_cam_detach(sc);
742 
743 	if (sc->req_ctx_buf)
744 		while ((req = tw_osli_req_q_remove_head(sc, TW_OSLI_FREE_Q)) !=
745 			NULL) {
746 			lockuninit(req->ioctl_wake_timeout_lock);
747 
748 			if ((error = bus_dmamap_destroy(sc->dma_tag,
749 					req->dma_map)))
750 				tw_osli_dbg_dprintf(1, sc,
751 					"dmamap_destroy(dma) returned %d",
752 					error);
753 		}
754 
755 	if ((sc->ioctl_tag) && (sc->ioctl_map))
756 		if ((error = bus_dmamap_destroy(sc->ioctl_tag, sc->ioctl_map)))
757 			tw_osli_dbg_dprintf(1, sc,
758 				"dmamap_destroy(ioctl) returned %d", error);
759 
760 	/* Free all memory allocated so far. */
761 	if (sc->req_ctx_buf)
762 		kfree(sc->req_ctx_buf, TW_OSLI_MALLOC_CLASS);
763 
764 	if (sc->non_dma_mem)
765 		kfree(sc->non_dma_mem, TW_OSLI_MALLOC_CLASS);
766 
767 	if (sc->dma_mem) {
768 		bus_dmamap_unload(sc->cmd_tag, sc->cmd_map);
769 		bus_dmamem_free(sc->cmd_tag, sc->dma_mem,
770 			sc->cmd_map);
771 	}
772 	if (sc->cmd_tag)
773 		if ((error = bus_dma_tag_destroy(sc->cmd_tag)))
774 			tw_osli_dbg_dprintf(1, sc,
775 				"dma_tag_destroy(cmd) returned %d", error);
776 
777 	if (sc->dma_tag)
778 		if ((error = bus_dma_tag_destroy(sc->dma_tag)))
779 			tw_osli_dbg_dprintf(1, sc,
780 				"dma_tag_destroy(dma) returned %d", error);
781 
782 	if (sc->ioctl_tag)
783 		if ((error = bus_dma_tag_destroy(sc->ioctl_tag)))
784 			tw_osli_dbg_dprintf(1, sc,
785 				"dma_tag_destroy(ioctl) returned %d", error);
786 
787 	if (sc->parent_tag)
788 		if ((error = bus_dma_tag_destroy(sc->parent_tag)))
789 			tw_osli_dbg_dprintf(1, sc,
790 				"dma_tag_destroy(parent) returned %d", error);
791 
792 
793 	/* Disconnect the interrupt handler. */
794 	if ((error = twa_teardown_intr(sc)))
795 			tw_osli_dbg_dprintf(1, sc,
796 				"teardown_intr returned %d", error);
797 
798 	if (sc->irq_res != NULL)
799 		if ((error = bus_release_resource(sc->bus_dev,
800 				SYS_RES_IRQ, sc->irq_res_id, sc->irq_res)))
801 			tw_osli_dbg_dprintf(1, sc,
802 				"release_resource(irq) returned %d", error);
803 
804 
805 	/* Release the register window mapping. */
806 	if (sc->reg_res != NULL)
807 		if ((error = bus_release_resource(sc->bus_dev,
808 				SYS_RES_MEMORY, sc->reg_res_id, sc->reg_res)))
809 			tw_osli_dbg_dprintf(1, sc,
810 				"release_resource(io) returned %d", error);
811 
812 	dev_ops_remove_minor(&twa_ops, device_get_unit(sc->bus_dev));
813 
814 	/* Destroy the control device. */
815 	if (sc->ctrl_dev != (struct cdev *)NULL)
816 		destroy_dev(sc->ctrl_dev);
817 
818 	if ((error = sysctl_ctx_free(&sc->sysctl_ctxt)))
819 		tw_osli_dbg_dprintf(1, sc,
820 			"sysctl_ctx_free returned %d", error);
821 
822 }
823 
824 
825 
826 /*
827  * Function name:	twa_detach
828  * Description:		Called when the controller is being detached from
829  *			the pci bus.
830  *
831  * Input:		dev	-- bus device corresponding to the ctlr
832  * Output:		None
833  * Return value:	0	-- success
834  *			non-zero-- failure
835  */
836 static TW_INT32
837 twa_detach(device_t dev)
838 {
839 	struct twa_softc	*sc = device_get_softc(dev);
840 	TW_INT32		error;
841 
842 	tw_osli_dbg_dprintf(3, sc, "entered");
843 
844 	error = EBUSY;
845 	if (sc->open) {
846 		tw_osli_printf(sc, "error = %d",
847 			TW_CL_SEVERITY_ERROR_STRING,
848 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
849 			0x2014,
850 			"Device open",
851 			error);
852 		goto out;
853 	}
854 
855 	/* Shut the controller down. */
856 	if ((error = twa_shutdown(dev)))
857 		goto out;
858 
859 	/* Free all resources associated with this controller. */
860 	tw_osli_free_resources(sc);
861 	error = 0;
862 
863 out:
864 	return(error);
865 }
866 
867 
868 
869 /*
870  * Function name:	twa_shutdown
871  * Description:		Called at unload/shutdown time.  Lets the controller
872  *			know that we are going down.
873  *
874  * Input:		dev	-- bus device corresponding to the ctlr
875  * Output:		None
876  * Return value:	0	-- success
877  *			non-zero-- failure
878  */
879 static TW_INT32
880 twa_shutdown(device_t dev)
881 {
882 	struct twa_softc	*sc = device_get_softc(dev);
883 	TW_INT32		error = 0;
884 
885 	tw_osli_dbg_dprintf(3, sc, "entered");
886 
887 	/* Disconnect interrupts. */
888 	error = twa_teardown_intr(sc);
889 
890 #if 0 /* XXX swildner */
891 	/* Stop watchdog task. */
892 	callout_drain(&(sc->watchdog_callout[0]));
893 	callout_drain(&(sc->watchdog_callout[1]));
894 #endif
895 
896 	/* Disconnect from the controller. */
897 	if ((error = tw_cl_shutdown_ctlr(&(sc->ctlr_handle), 0))) {
898 		tw_osli_printf(sc, "error = %d",
899 			TW_CL_SEVERITY_ERROR_STRING,
900 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
901 			0x2015,
902 			"Failed to shutdown Common Layer/controller",
903 			error);
904 	}
905 	return(error);
906 }
907 
908 
909 
910 #if 0 /* XXX swildner */
911 /*
912  * Function name:	twa_busdma_lock
913  * Description:		Function to provide synchronization during busdma_swi.
914  *
915  * Input:		lock_arg -- lock mutex sent as argument
916  *			op -- operation (lock/unlock) expected of the function
917  * Output:		None
918  * Return value:	None
919  */
920 TW_VOID
921 twa_busdma_lock(TW_VOID *lock_arg, bus_dma_lock_op_t op)
922 {
923 	struct spinlock	*lock;
924 
925 	lock = (struct spinlock *)lock_arg;
926 	switch (op) {
927 	case BUS_DMA_LOCK:
928 		spin_lock(lock);
929 		break;
930 
931 	case BUS_DMA_UNLOCK:
932 		spin_unlock(lock);
933 		break;
934 
935 	default:
936 		panic("Unknown operation 0x%x for twa_busdma_lock!", op);
937 	}
938 }
939 #endif
940 
941 
942 /*
943  * Function name:	twa_pci_intr
944  * Description:		Interrupt handler.  Wrapper for twa_interrupt.
945  *
946  * Input:		arg	-- ptr to OSL internal ctlr context
947  * Output:		None
948  * Return value:	None
949  */
950 static TW_VOID
951 twa_pci_intr(TW_VOID *arg)
952 {
953 	struct twa_softc	*sc = (struct twa_softc *)arg;
954 
955 	tw_osli_dbg_dprintf(10, sc, "entered");
956 	tw_cl_interrupt(&(sc->ctlr_handle));
957 }
958 
959 
960 /*
961  * Function name:	tw_osli_fw_passthru
962  * Description:		Builds a fw passthru cmd pkt, and submits it to CL.
963  *
964  * Input:		sc	-- ptr to OSL internal ctlr context
965  *			buf	-- ptr to ioctl pkt understood by CL
966  * Output:		None
967  * Return value:	0	-- success
968  *			non-zero-- failure
969  */
970 TW_INT32
971 tw_osli_fw_passthru(struct twa_softc *sc, TW_INT8 *buf)
972 {
973 	struct tw_osli_req_context		*req;
974 	struct tw_osli_ioctl_no_data_buf	*user_buf =
975 		(struct tw_osli_ioctl_no_data_buf *)buf;
976 	TW_TIME					end_time;
977 	TW_UINT32				timeout = 60;
978 	TW_UINT32				data_buf_size_adjusted;
979 	struct tw_cl_req_packet			*req_pkt;
980 	struct tw_cl_passthru_req_packet	*pt_req;
981 	TW_INT32				error;
982 
983 	tw_osli_dbg_dprintf(5, sc, "ioctl: passthru");
984 
985 	if ((req = tw_osli_get_request(sc)) == NULL)
986 		return(EBUSY);
987 
988 	req->req_handle.osl_req_ctxt = req;
989 	req->orig_req = buf;
990 	req->flags |= TW_OSLI_REQ_FLAGS_PASSTHRU;
991 
992 	req_pkt = &(req->req_pkt);
993 	req_pkt->status = 0;
994 	req_pkt->tw_osl_callback = tw_osl_complete_passthru;
995 	/* Let the Common Layer retry the request on cmd queue full. */
996 	req_pkt->flags |= TW_CL_REQ_RETRY_ON_BUSY;
997 
998 	pt_req = &(req_pkt->gen_req_pkt.pt_req);
999 	/*
1000 	 * Make sure that the data buffer sent to firmware is a
1001 	 * 512 byte multiple in size.
1002 	 */
1003 	data_buf_size_adjusted =
1004 		(user_buf->driver_pkt.buffer_length +
1005 		(sc->sg_size_factor - 1)) & ~(sc->sg_size_factor - 1);
1006 	if ((req->length = data_buf_size_adjusted)) {
1007 		req->data = kmalloc(data_buf_size_adjusted,
1008 		    TW_OSLI_MALLOC_CLASS, M_WAITOK);
1009 		/* Copy the payload. */
1010 		if ((error = copyin((TW_VOID *)(user_buf->pdata),
1011 			req->data,
1012 			user_buf->driver_pkt.buffer_length)) != 0) {
1013 			tw_osli_printf(sc, "error = %d",
1014 				TW_CL_SEVERITY_ERROR_STRING,
1015 				TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1016 				0x2017,
1017 				"Could not copyin fw_passthru data_buf",
1018 				error);
1019 			goto fw_passthru_err;
1020 		}
1021 		pt_req->sgl_entries = 1; /* will be updated during mapping */
1022 		req->flags |= (TW_OSLI_REQ_FLAGS_DATA_IN |
1023 			TW_OSLI_REQ_FLAGS_DATA_OUT);
1024 	} else
1025 		pt_req->sgl_entries = 0; /* no payload */
1026 
1027 	pt_req->cmd_pkt = (TW_VOID *)(&(user_buf->cmd_pkt));
1028 	pt_req->cmd_pkt_length = sizeof(struct tw_cl_command_packet);
1029 
1030 	if ((error = tw_osli_map_request(req)))
1031 		goto fw_passthru_err;
1032 
1033 	end_time = tw_osl_get_local_time() + timeout;
1034 	while (req->state != TW_OSLI_REQ_STATE_COMPLETE) {
1035 		lockmgr(req->ioctl_wake_timeout_lock, LK_EXCLUSIVE);
1036 		req->flags |= TW_OSLI_REQ_FLAGS_SLEEPING;
1037 
1038 		error = lksleep(req, req->ioctl_wake_timeout_lock, 0,
1039 			    "twa_passthru", timeout*hz);
1040 		lockmgr(req->ioctl_wake_timeout_lock, LK_RELEASE);
1041 
1042 		if (!(req->flags & TW_OSLI_REQ_FLAGS_SLEEPING))
1043 			error = 0;
1044 		req->flags &= ~TW_OSLI_REQ_FLAGS_SLEEPING;
1045 
1046 		if (! error) {
1047 			if (((error = req->error_code)) ||
1048 				((error = (req->state !=
1049 				TW_OSLI_REQ_STATE_COMPLETE))) ||
1050 				((error = req_pkt->status)))
1051 				goto fw_passthru_err;
1052 			break;
1053 		}
1054 
1055 		if (req_pkt->status) {
1056 			error = req_pkt->status;
1057 			goto fw_passthru_err;
1058 		}
1059 
1060 		if (error == EWOULDBLOCK) {
1061 			/* Time out! */
1062 			if ((!(req->error_code))                       &&
1063 			    (req->state == TW_OSLI_REQ_STATE_COMPLETE) &&
1064 			    (!(req_pkt->status))			  ) {
1065 #ifdef    TW_OSL_DEBUG
1066 				tw_osli_printf(sc, "request = %p",
1067 					TW_CL_SEVERITY_ERROR_STRING,
1068 					TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1069 					0x7777,
1070 					"FALSE Passthru timeout!",
1071 					req);
1072 #endif /* TW_OSL_DEBUG */
1073 				error = 0; /* False error */
1074 				break;
1075 			}
1076 			if (!(tw_cl_is_reset_needed(&(req->ctlr->ctlr_handle)))) {
1077 #ifdef    TW_OSL_DEBUG
1078 				tw_osli_printf(sc, "request = %p",
1079 					TW_CL_SEVERITY_ERROR_STRING,
1080 					TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1081 					0x2018,
1082 					"Passthru request timed out!",
1083 					req);
1084 #else  /* TW_OSL_DEBUG */
1085 			device_printf((sc)->bus_dev, "Passthru request timed out!\n");
1086 #endif /* TW_OSL_DEBUG */
1087 				tw_cl_reset_ctlr(&(req->ctlr->ctlr_handle));
1088 			}
1089 
1090 			error = 0;
1091 			end_time = tw_osl_get_local_time() + timeout;
1092 			continue;
1093 			/*
1094 			 * Don't touch req after a reset.  It (and any
1095 			 * associated data) will be
1096 			 * unmapped by the callback.
1097 			 */
1098 		}
1099 		/*
1100 		 * Either the request got completed, or we were woken up by a
1101 		 * signal.  Calculate the new timeout, in case it was the latter.
1102 		 */
1103 		timeout = (end_time - tw_osl_get_local_time());
1104 	} /* End of while loop */
1105 
1106 	/* If there was a payload, copy it back. */
1107 	if ((!error) && (req->length))
1108 		if ((error = copyout(req->data, user_buf->pdata,
1109 			user_buf->driver_pkt.buffer_length)))
1110 			tw_osli_printf(sc, "error = %d",
1111 				TW_CL_SEVERITY_ERROR_STRING,
1112 				TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1113 				0x2019,
1114 				"Could not copyout fw_passthru data_buf",
1115 				error);
1116 
1117 fw_passthru_err:
1118 
1119 	if (req_pkt->status == TW_CL_ERR_REQ_BUS_RESET)
1120 		error = EBUSY;
1121 
1122 	user_buf->driver_pkt.os_status = error;
1123 	/* Free resources. */
1124 	if (req->data)
1125 		kfree(req->data, TW_OSLI_MALLOC_CLASS);
1126 	tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
1127 	return(error);
1128 }
1129 
1130 
1131 
1132 /*
1133  * Function name:	tw_osl_complete_passthru
1134  * Description:		Called to complete passthru requests.
1135  *
1136  * Input:		req_handle	-- ptr to request handle
1137  * Output:		None
1138  * Return value:	None
1139  */
1140 TW_VOID
1141 tw_osl_complete_passthru(struct tw_cl_req_handle *req_handle)
1142 {
1143 	struct tw_osli_req_context	*req = req_handle->osl_req_ctxt;
1144 	struct tw_cl_req_packet		*req_pkt =
1145 		(struct tw_cl_req_packet *)(&req->req_pkt);
1146 	struct twa_softc		*sc = req->ctlr;
1147 
1148 	tw_osli_dbg_dprintf(5, sc, "entered");
1149 
1150 	if (req->state != TW_OSLI_REQ_STATE_BUSY) {
1151 		tw_osli_printf(sc, "request = %p, status = %d",
1152 			TW_CL_SEVERITY_ERROR_STRING,
1153 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1154 			0x201B,
1155 			"Unposted command completed!!",
1156 			req, req->state);
1157 	}
1158 
1159 	/*
1160 	 * Remove request from the busy queue.  Just mark it complete.
1161 	 * There's no need to move it into the complete queue as we are
1162 	 * going to be done with it right now.
1163 	 */
1164 	req->state = TW_OSLI_REQ_STATE_COMPLETE;
1165 	tw_osli_req_q_remove_item(req, TW_OSLI_BUSY_Q);
1166 
1167 	tw_osli_unmap_request(req);
1168 
1169 	/*
1170 	 * Don't do a wake up if there was an error even before the request
1171 	 * was sent down to the Common Layer, and we hadn't gotten an
1172 	 * EINPROGRESS.  The request originator will then be returned an
1173 	 * error, and he can do the clean-up.
1174 	 */
1175 	if ((req->error_code) && (!(req->flags & TW_OSLI_REQ_FLAGS_IN_PROGRESS)))
1176 		return;
1177 
1178 	if (req->flags & TW_OSLI_REQ_FLAGS_PASSTHRU) {
1179 		if (req->flags & TW_OSLI_REQ_FLAGS_SLEEPING) {
1180 			/* Wake up the sleeping command originator. */
1181 			tw_osli_dbg_dprintf(5, sc,
1182 				"Waking up originator of request %p", req);
1183 			req->flags &= ~TW_OSLI_REQ_FLAGS_SLEEPING;
1184 			wakeup_one(req);
1185 		} else {
1186 			/*
1187 			 * If the request completed even before mtx_sleep
1188 			 * was called, simply return.
1189 			 */
1190 			if (req->flags & TW_OSLI_REQ_FLAGS_MAPPED)
1191 				return;
1192 
1193 			if (req_pkt->status == TW_CL_ERR_REQ_BUS_RESET)
1194 				return;
1195 
1196 			tw_osli_printf(sc, "request = %p",
1197 				TW_CL_SEVERITY_ERROR_STRING,
1198 				TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1199 				0x201C,
1200 				"Passthru callback called, "
1201 				"and caller not sleeping",
1202 				req);
1203 		}
1204 	} else {
1205 		tw_osli_printf(sc, "request = %p",
1206 			TW_CL_SEVERITY_ERROR_STRING,
1207 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1208 			0x201D,
1209 			"Passthru callback called for non-passthru request",
1210 			req);
1211 	}
1212 }
1213 
1214 
1215 
1216 /*
1217  * Function name:	tw_osli_get_request
1218  * Description:		Gets a request pkt from the free queue.
1219  *
1220  * Input:		sc	-- ptr to OSL internal ctlr context
1221  * Output:		None
1222  * Return value:	ptr to request pkt	-- success
1223  *			NULL			-- failure
1224  */
1225 struct tw_osli_req_context *
1226 tw_osli_get_request(struct twa_softc *sc)
1227 {
1228 	struct tw_osli_req_context	*req;
1229 
1230 	tw_osli_dbg_dprintf(4, sc, "entered");
1231 
1232 	/* Get a free request packet. */
1233 	req = tw_osli_req_q_remove_head(sc, TW_OSLI_FREE_Q);
1234 
1235 	/* Initialize some fields to their defaults. */
1236 	if (req) {
1237 		req->req_handle.osl_req_ctxt = NULL;
1238 		req->req_handle.cl_req_ctxt = NULL;
1239 		req->req_handle.is_io = 0;
1240 		req->data = NULL;
1241 		req->length = 0;
1242 		req->deadline = 0;
1243 		req->real_data = NULL;
1244 		req->real_length = 0;
1245 		req->state = TW_OSLI_REQ_STATE_INIT;/* req being initialized */
1246 		req->flags = 0;
1247 		req->error_code = 0;
1248 		req->orig_req = NULL;
1249 
1250 		bzero(&(req->req_pkt), sizeof(struct tw_cl_req_packet));
1251 
1252 	}
1253 	return(req);
1254 }
1255 
1256 
1257 
1258 /*
1259  * Function name:	twa_map_load_data_callback
1260  * Description:		Callback of bus_dmamap_load for the buffer associated
1261  *			with data.  Updates the cmd pkt (size/sgl_entries
1262  *			fields, as applicable) to reflect the number of sg
1263  *			elements.
1264  *
1265  * Input:		arg	-- ptr to OSL internal request context
1266  *			segs	-- ptr to a list of segment descriptors
1267  *			nsegments--# of segments
1268  *			error	-- 0 if no errors encountered before callback,
1269  *				   non-zero if errors were encountered
1270  * Output:		None
1271  * Return value:	None
1272  */
1273 static TW_VOID
1274 twa_map_load_data_callback(TW_VOID *arg, bus_dma_segment_t *segs,
1275 	TW_INT32 nsegments, TW_INT32 error)
1276 {
1277 	struct tw_osli_req_context	*req =
1278 		(struct tw_osli_req_context *)arg;
1279 	struct twa_softc		*sc = req->ctlr;
1280 	struct tw_cl_req_packet		*req_pkt = &(req->req_pkt);
1281 
1282 	tw_osli_dbg_dprintf(10, sc, "entered");
1283 
1284 	if (error == EINVAL) {
1285 		req->error_code = error;
1286 		return;
1287 	}
1288 
1289 	/* Mark the request as currently being processed. */
1290 	req->state = TW_OSLI_REQ_STATE_BUSY;
1291 	/* Move the request into the busy queue. */
1292 	tw_osli_req_q_insert_tail(req, TW_OSLI_BUSY_Q);
1293 
1294 	req->flags |= TW_OSLI_REQ_FLAGS_MAPPED;
1295 
1296 	if (error == EFBIG) {
1297 		req->error_code = error;
1298 		goto out;
1299 	}
1300 
1301 	if (req->flags & TW_OSLI_REQ_FLAGS_PASSTHRU) {
1302 		struct tw_cl_passthru_req_packet	*pt_req;
1303 
1304 		if (req->flags & TW_OSLI_REQ_FLAGS_DATA_IN)
1305 			bus_dmamap_sync(sc->ioctl_tag, sc->ioctl_map,
1306 				BUS_DMASYNC_PREREAD);
1307 
1308 		if (req->flags & TW_OSLI_REQ_FLAGS_DATA_OUT) {
1309 			/*
1310 			 * If we're using an alignment buffer, and we're
1311 			 * writing data, copy the real data out.
1312 			 */
1313 			if (req->flags & TW_OSLI_REQ_FLAGS_DATA_COPY_NEEDED)
1314 				bcopy(req->real_data, req->data, req->real_length);
1315 			bus_dmamap_sync(sc->ioctl_tag, sc->ioctl_map,
1316 				BUS_DMASYNC_PREWRITE);
1317 		}
1318 
1319 		pt_req = &(req_pkt->gen_req_pkt.pt_req);
1320 		pt_req->sg_list = (TW_UINT8 *)segs;
1321 		pt_req->sgl_entries += (nsegments - 1);
1322 		error = tw_cl_fw_passthru(&(sc->ctlr_handle), req_pkt,
1323 			&(req->req_handle));
1324 	} else {
1325 		struct tw_cl_scsi_req_packet	*scsi_req;
1326 
1327 		if (req->flags & TW_OSLI_REQ_FLAGS_DATA_IN)
1328 			bus_dmamap_sync(sc->dma_tag, req->dma_map,
1329 				BUS_DMASYNC_PREREAD);
1330 
1331 		if (req->flags & TW_OSLI_REQ_FLAGS_DATA_OUT) {
1332 			/*
1333 			 * If we're using an alignment buffer, and we're
1334 			 * writing data, copy the real data out.
1335 			 */
1336 			if (req->flags & TW_OSLI_REQ_FLAGS_DATA_COPY_NEEDED)
1337 				bcopy(req->real_data, req->data, req->real_length);
1338 			bus_dmamap_sync(sc->dma_tag, req->dma_map,
1339 				BUS_DMASYNC_PREWRITE);
1340 		}
1341 
1342 		scsi_req = &(req_pkt->gen_req_pkt.scsi_req);
1343 		scsi_req->sg_list = (TW_UINT8 *)segs;
1344 		scsi_req->sgl_entries += (nsegments - 1);
1345 		error = tw_cl_start_io(&(sc->ctlr_handle), req_pkt,
1346 			&(req->req_handle));
1347 	}
1348 
1349 out:
1350 	if (error) {
1351 		req->error_code = error;
1352 		req_pkt->tw_osl_callback(&(req->req_handle));
1353 		/*
1354 		 * If the caller had been returned EINPROGRESS, and he has
1355 		 * registered a callback for handling completion, the callback
1356 		 * will never get called because we were unable to submit the
1357 		 * request.  So, free up the request right here.
1358 		 */
1359 		if (req->flags & TW_OSLI_REQ_FLAGS_IN_PROGRESS)
1360 			tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
1361 	}
1362 }
1363 
1364 
1365 
1366 /*
1367  * Function name:	twa_map_load_callback
1368  * Description:		Callback of bus_dmamap_load for the buffer associated
1369  *			with a cmd pkt.
1370  *
1371  * Input:		arg	-- ptr to variable to hold phys addr
1372  *			segs	-- ptr to a list of segment descriptors
1373  *			nsegments--# of segments
1374  *			error	-- 0 if no errors encountered before callback,
1375  *				   non-zero if errors were encountered
1376  * Output:		None
1377  * Return value:	None
1378  */
1379 static TW_VOID
1380 twa_map_load_callback(TW_VOID *arg, bus_dma_segment_t *segs,
1381 	TW_INT32 nsegments, TW_INT32 error)
1382 {
1383 	*((bus_addr_t *)arg) = segs[0].ds_addr;
1384 }
1385 
1386 
1387 
1388 /*
1389  * Function name:	tw_osli_map_request
1390  * Description:		Maps a cmd pkt and data associated with it, into
1391  *			DMA'able memory.
1392  *
1393  * Input:		req	-- ptr to request pkt
1394  * Output:		None
1395  * Return value:	0	-- success
1396  *			non-zero-- failure
1397  */
1398 TW_INT32
1399 tw_osli_map_request(struct tw_osli_req_context *req)
1400 {
1401 	struct twa_softc	*sc = req->ctlr;
1402 	TW_INT32		error = 0;
1403 
1404 	tw_osli_dbg_dprintf(10, sc, "entered");
1405 
1406 	/* If the command involves data, map that too. */
1407 	if (req->data != NULL) {
1408 		/*
1409 		 * It's sufficient for the data pointer to be 4-byte aligned
1410 		 * to work with 9000.  However, if 4-byte aligned addresses
1411 		 * are passed to bus_dmamap_load, we can get back sg elements
1412 		 * that are not 512-byte multiples in size.  So, we will let
1413 		 * only those buffers that are 512-byte aligned to pass
1414 		 * through, and bounce the rest, so as to make sure that we
1415 		 * always get back sg elements that are 512-byte multiples
1416 		 * in size.
1417 		 */
1418 		if (((vm_offset_t)req->data % sc->sg_size_factor) ||
1419 			(req->length % sc->sg_size_factor)) {
1420 			req->flags |= TW_OSLI_REQ_FLAGS_DATA_COPY_NEEDED;
1421 			/* Save original data pointer and length. */
1422 			req->real_data = req->data;
1423 			req->real_length = req->length;
1424 			req->length = (req->length +
1425 				(sc->sg_size_factor - 1)) &
1426 				~(sc->sg_size_factor - 1);
1427 			req->data = kmalloc(req->length, TW_OSLI_MALLOC_CLASS,
1428 					M_NOWAIT);
1429 			if (req->data == NULL) {
1430 				tw_osli_printf(sc, "error = %d",
1431 					TW_CL_SEVERITY_ERROR_STRING,
1432 					TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1433 					0x201E,
1434 					"Failed to allocate memory "
1435 					"for bounce buffer",
1436 					ENOMEM);
1437 				/* Restore original data pointer and length. */
1438 				req->data = req->real_data;
1439 				req->length = req->real_length;
1440 				return(ENOMEM);
1441 			}
1442 		}
1443 
1444 		/*
1445 		 * Map the data buffer into bus space and build the SG list.
1446 		 */
1447 		if (req->flags & TW_OSLI_REQ_FLAGS_PASSTHRU) {
1448 			/* Lock against multiple simultaneous ioctl calls. */
1449 			spin_lock(sc->io_lock);
1450 			error = bus_dmamap_load(sc->ioctl_tag, sc->ioctl_map,
1451 				req->data, req->length,
1452 				twa_map_load_data_callback, req,
1453 				BUS_DMA_WAITOK);
1454 			spin_unlock(sc->io_lock);
1455 		} else {
1456 			/*
1457 			 * There's only one CAM I/O thread running at a time.
1458 			 * So, there's no need to hold the io_lock.
1459 			 */
1460 			error = bus_dmamap_load(sc->dma_tag, req->dma_map,
1461 				req->data, req->length,
1462 				twa_map_load_data_callback, req,
1463 				BUS_DMA_WAITOK);
1464 		}
1465 
1466 		if (!error)
1467 			error = req->error_code;
1468 		else {
1469 			if (error == EINPROGRESS) {
1470 				/*
1471 				 * Specifying sc->io_lock as the lockfuncarg
1472 				 * in ...tag_create should protect the access
1473 				 * of ...FLAGS_MAPPED from the callback.
1474 				 */
1475 				spin_lock(sc->io_lock);
1476 				if (!(req->flags & TW_OSLI_REQ_FLAGS_MAPPED))
1477 					req->flags |= TW_OSLI_REQ_FLAGS_IN_PROGRESS;
1478 				tw_osli_disallow_new_requests(sc, &(req->req_handle));
1479 				spin_unlock(sc->io_lock);
1480 				error = 0;
1481 			} else {
1482 				tw_osli_printf(sc, "error = %d",
1483 					TW_CL_SEVERITY_ERROR_STRING,
1484 					TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1485 					0x9999,
1486 					"Failed to map DMA memory "
1487 					"for I/O request",
1488 					error);
1489 				req->flags |= TW_OSLI_REQ_FLAGS_FAILED;
1490 				/* Free alignment buffer if it was used. */
1491 				if (req->flags &
1492 					TW_OSLI_REQ_FLAGS_DATA_COPY_NEEDED) {
1493 					kfree(req->data, TW_OSLI_MALLOC_CLASS);
1494 					/*
1495 					 * Restore original data pointer
1496 					 * and length.
1497 					 */
1498 					req->data = req->real_data;
1499 					req->length = req->real_length;
1500 				}
1501 			}
1502 		}
1503 
1504 	} else {
1505 		/* Mark the request as currently being processed. */
1506 		req->state = TW_OSLI_REQ_STATE_BUSY;
1507 		/* Move the request into the busy queue. */
1508 		tw_osli_req_q_insert_tail(req, TW_OSLI_BUSY_Q);
1509 		if (req->flags & TW_OSLI_REQ_FLAGS_PASSTHRU)
1510 			error = tw_cl_fw_passthru(&sc->ctlr_handle,
1511 					&(req->req_pkt), &(req->req_handle));
1512 		else
1513 			error = tw_cl_start_io(&sc->ctlr_handle,
1514 					&(req->req_pkt), &(req->req_handle));
1515 		if (error) {
1516 			req->error_code = error;
1517 			req->req_pkt.tw_osl_callback(&(req->req_handle));
1518 		}
1519 	}
1520 	return(error);
1521 }
1522 
1523 
1524 
1525 /*
1526  * Function name:	tw_osli_unmap_request
1527  * Description:		Undoes the mapping done by tw_osli_map_request.
1528  *
1529  * Input:		req	-- ptr to request pkt
1530  * Output:		None
1531  * Return value:	None
1532  */
1533 TW_VOID
1534 tw_osli_unmap_request(struct tw_osli_req_context *req)
1535 {
1536 	struct twa_softc	*sc = req->ctlr;
1537 
1538 	tw_osli_dbg_dprintf(10, sc, "entered");
1539 
1540 	/* If the command involved data, unmap that too. */
1541 	if (req->data != NULL) {
1542 		if (req->flags & TW_OSLI_REQ_FLAGS_PASSTHRU) {
1543 			/* Lock against multiple simultaneous ioctl calls. */
1544 			spin_lock(sc->io_lock);
1545 
1546 			if (req->flags & TW_OSLI_REQ_FLAGS_DATA_IN) {
1547 				bus_dmamap_sync(sc->ioctl_tag,
1548 					sc->ioctl_map, BUS_DMASYNC_POSTREAD);
1549 
1550 				/*
1551 				 * If we are using a bounce buffer, and we are
1552 				 * reading data, copy the real data in.
1553 				 */
1554 				if (req->flags & TW_OSLI_REQ_FLAGS_DATA_COPY_NEEDED)
1555 					bcopy(req->data, req->real_data,
1556 						req->real_length);
1557 			}
1558 
1559 			if (req->flags & TW_OSLI_REQ_FLAGS_DATA_OUT)
1560 				bus_dmamap_sync(sc->ioctl_tag, sc->ioctl_map,
1561 					BUS_DMASYNC_POSTWRITE);
1562 
1563 			bus_dmamap_unload(sc->ioctl_tag, sc->ioctl_map);
1564 
1565 			spin_unlock(sc->io_lock);
1566 		} else {
1567 			if (req->flags & TW_OSLI_REQ_FLAGS_DATA_IN) {
1568 				bus_dmamap_sync(sc->dma_tag,
1569 					req->dma_map, BUS_DMASYNC_POSTREAD);
1570 
1571 				/*
1572 				 * If we are using a bounce buffer, and we are
1573 				 * reading data, copy the real data in.
1574 				 */
1575 				if (req->flags & TW_OSLI_REQ_FLAGS_DATA_COPY_NEEDED)
1576 					bcopy(req->data, req->real_data,
1577 						req->real_length);
1578 			}
1579 			if (req->flags & TW_OSLI_REQ_FLAGS_DATA_OUT)
1580 				bus_dmamap_sync(sc->dma_tag, req->dma_map,
1581 					BUS_DMASYNC_POSTWRITE);
1582 
1583 			bus_dmamap_unload(sc->dma_tag, req->dma_map);
1584 		}
1585 	}
1586 
1587 	/* Free alignment buffer if it was used. */
1588 	if (req->flags & TW_OSLI_REQ_FLAGS_DATA_COPY_NEEDED) {
1589 		kfree(req->data, TW_OSLI_MALLOC_CLASS);
1590 		/* Restore original data pointer and length. */
1591 		req->data = req->real_data;
1592 		req->length = req->real_length;
1593 	}
1594 }
1595 
1596 
1597 
1598 #ifdef TW_OSL_DEBUG
1599 
1600 TW_VOID	twa_report_stats(TW_VOID);
1601 TW_VOID	twa_reset_stats(TW_VOID);
1602 TW_VOID	tw_osli_print_ctlr_stats(struct twa_softc *sc);
1603 TW_VOID twa_print_req_info(struct tw_osli_req_context *req);
1604 
1605 
1606 /*
1607  * Function name:	twa_report_stats
1608  * Description:		For being called from ddb.  Calls functions that print
1609  *			OSL and CL internal stats for the controller.
1610  *
1611  * Input:		None
1612  * Output:		None
1613  * Return value:	None
1614  */
1615 TW_VOID
1616 twa_report_stats(TW_VOID)
1617 {
1618 	struct twa_softc	*sc;
1619 	TW_INT32		i;
1620 
1621 	for (i = 0; (sc = devclass_get_softc(twa_devclass, i)) != NULL; i++) {
1622 		tw_osli_print_ctlr_stats(sc);
1623 		tw_cl_print_ctlr_stats(&sc->ctlr_handle);
1624 	}
1625 }
1626 
1627 
1628 
1629 /*
1630  * Function name:	tw_osli_print_ctlr_stats
1631  * Description:		For being called from ddb.  Prints OSL controller stats
1632  *
1633  * Input:		sc	-- ptr to OSL internal controller context
1634  * Output:		None
1635  * Return value:	None
1636  */
1637 TW_VOID
1638 tw_osli_print_ctlr_stats(struct twa_softc *sc)
1639 {
1640 	twa_printf(sc, "osl_ctlr_ctxt = %p\n", sc);
1641 	twa_printf(sc, "OSLq type  current  max\n");
1642 	twa_printf(sc, "free      %04d     %04d\n",
1643 		sc->q_stats[TW_OSLI_FREE_Q].cur_len,
1644 		sc->q_stats[TW_OSLI_FREE_Q].max_len);
1645 	twa_printf(sc, "busy      %04d     %04d\n",
1646 		sc->q_stats[TW_OSLI_BUSY_Q].cur_len,
1647 		sc->q_stats[TW_OSLI_BUSY_Q].max_len);
1648 }
1649 
1650 
1651 
1652 /*
1653  * Function name:	twa_print_req_info
1654  * Description:		For being called from ddb.  Calls functions that print
1655  *			OSL and CL internal details for the request.
1656  *
1657  * Input:		req	-- ptr to OSL internal request context
1658  * Output:		None
1659  * Return value:	None
1660  */
1661 TW_VOID
1662 twa_print_req_info(struct tw_osli_req_context *req)
1663 {
1664 	struct twa_softc	*sc = req->ctlr;
1665 
1666 	twa_printf(sc, "OSL details for request:\n");
1667 	twa_printf(sc, "osl_req_ctxt = %p, cl_req_ctxt = %p\n"
1668 		"data = %p, length = 0x%x, real_data = %p, real_length = 0x%x\n"
1669 		"state = 0x%x, flags = 0x%x, error = 0x%x, orig_req = %p\n"
1670 		"next_req = %p, prev_req = %p, dma_map = %p\n",
1671 		req->req_handle.osl_req_ctxt, req->req_handle.cl_req_ctxt,
1672 		req->data, req->length, req->real_data, req->real_length,
1673 		req->state, req->flags, req->error_code, req->orig_req,
1674 		req->link.next, req->link.prev, req->dma_map);
1675 	tw_cl_print_req_info(&(req->req_handle));
1676 }
1677 
1678 
1679 
1680 /*
1681  * Function name:	twa_reset_stats
1682  * Description:		For being called from ddb.
1683  *			Resets some OSL controller stats.
1684  *
1685  * Input:		None
1686  * Output:		None
1687  * Return value:	None
1688  */
1689 TW_VOID
1690 twa_reset_stats(TW_VOID)
1691 {
1692 	struct twa_softc	*sc;
1693 	TW_INT32		i;
1694 
1695 	for (i = 0; (sc = devclass_get_softc(twa_devclass, i)) != NULL; i++) {
1696 		sc->q_stats[TW_OSLI_FREE_Q].max_len = 0;
1697 		sc->q_stats[TW_OSLI_BUSY_Q].max_len = 0;
1698 		tw_cl_reset_stats(&sc->ctlr_handle);
1699 	}
1700 }
1701 
1702 #endif /* TW_OSL_DEBUG */
1703