xref: /dragonfly/sys/dev/raid/twa/tw_osl_freebsd.c (revision 92fc8b5c)
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, 0, 0);
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 	if ((sc->non_dma_mem = kmalloc(non_dma_mem_size, TW_OSLI_MALLOC_CLASS,
558 				M_WAITOK)) == NULL) {
559 		tw_osli_printf(sc, "error = %d",
560 			TW_CL_SEVERITY_ERROR_STRING,
561 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
562 			0x2009,
563 			"Can't allocate non-dma memory",
564 			ENOMEM);
565 		return(ENOMEM);
566 	}
567 
568 	/* Create the parent dma tag. */
569 	if (bus_dma_tag_create(NULL,			/* parent */
570 				sc->alignment,		/* alignment */
571 				TW_OSLI_DMA_BOUNDARY,	/* boundary */
572 				BUS_SPACE_MAXADDR,	/* lowaddr */
573 				BUS_SPACE_MAXADDR, 	/* highaddr */
574 				NULL, NULL, 		/* filter, filterarg */
575 				TW_CL_MAX_IO_SIZE,	/* maxsize */
576 				max_sg_elements,	/* nsegments */
577 				TW_CL_MAX_IO_SIZE,	/* maxsegsize */
578 				0,			/* flags */
579 				&sc->parent_tag		/* tag */)) {
580 		tw_osli_printf(sc, "error = %d",
581 			TW_CL_SEVERITY_ERROR_STRING,
582 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
583 			0x200A,
584 			"Can't allocate parent DMA tag",
585 			ENOMEM);
586 		return(ENOMEM);
587 	}
588 
589 	/* Create a dma tag for Common Layer's DMA'able memory (dma_mem). */
590 	if (bus_dma_tag_create(sc->parent_tag,		/* parent */
591 				sc->alignment,		/* alignment */
592 				0,			/* boundary */
593 				BUS_SPACE_MAXADDR,	/* lowaddr */
594 				BUS_SPACE_MAXADDR, 	/* highaddr */
595 				NULL, NULL, 		/* filter, filterarg */
596 				dma_mem_size,		/* maxsize */
597 				1,			/* nsegments */
598 				BUS_SPACE_MAXSIZE,	/* maxsegsize */
599 				0,			/* flags */
600 				&sc->cmd_tag		/* tag */)) {
601 		tw_osli_printf(sc, "error = %d",
602 			TW_CL_SEVERITY_ERROR_STRING,
603 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
604 			0x200B,
605 			"Can't allocate DMA tag for Common Layer's "
606 			"DMA'able memory",
607 			ENOMEM);
608 		return(ENOMEM);
609 	}
610 
611 	if (bus_dmamem_alloc(sc->cmd_tag, &sc->dma_mem,
612 		BUS_DMA_NOWAIT, &sc->cmd_map)) {
613 		/* Try a second time. */
614 		if (bus_dmamem_alloc(sc->cmd_tag, &sc->dma_mem,
615 			BUS_DMA_NOWAIT, &sc->cmd_map)) {
616 			tw_osli_printf(sc, "error = %d",
617 				TW_CL_SEVERITY_ERROR_STRING,
618 				TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
619 				0x200C,
620 				"Can't allocate DMA'able memory for the"
621 				"Common Layer",
622 				ENOMEM);
623 			return(ENOMEM);
624 		}
625 	}
626 
627 	bus_dmamap_load(sc->cmd_tag, sc->cmd_map, sc->dma_mem,
628 		dma_mem_size, twa_map_load_callback,
629 		&sc->dma_mem_phys, 0);
630 
631 	/*
632 	 * Create a dma tag for data buffers; size will be the maximum
633 	 * possible I/O size (128kB).
634 	 */
635 	if (bus_dma_tag_create(sc->parent_tag,		/* parent */
636 				sc->alignment,		/* alignment */
637 				0,			/* boundary */
638 				BUS_SPACE_MAXADDR,	/* lowaddr */
639 				BUS_SPACE_MAXADDR, 	/* highaddr */
640 				NULL, NULL, 		/* filter, filterarg */
641 				TW_CL_MAX_IO_SIZE,	/* maxsize */
642 				max_sg_elements,	/* nsegments */
643 				TW_CL_MAX_IO_SIZE,	/* maxsegsize */
644 				BUS_DMA_ALLOCNOW,	/* flags */
645 #if 0 /* XXX swildner */
646 				twa_busdma_lock,	/* lockfunc */
647 				sc->io_lock,		/* lockfuncarg */
648 #endif
649 				&sc->dma_tag		/* tag */)) {
650 		tw_osli_printf(sc, "error = %d",
651 			TW_CL_SEVERITY_ERROR_STRING,
652 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
653 			0x200F,
654 			"Can't allocate DMA tag for data buffers",
655 			ENOMEM);
656 		return(ENOMEM);
657 	}
658 
659 	/*
660 	 * Create a dma tag for ioctl data buffers; size will be the maximum
661 	 * possible I/O size (128kB).
662 	 */
663 	if (bus_dma_tag_create(sc->parent_tag,		/* parent */
664 				sc->alignment,		/* alignment */
665 				0,			/* boundary */
666 				BUS_SPACE_MAXADDR,	/* lowaddr */
667 				BUS_SPACE_MAXADDR, 	/* highaddr */
668 				NULL, NULL, 		/* filter, filterarg */
669 				TW_CL_MAX_IO_SIZE,	/* maxsize */
670 				max_sg_elements,	/* nsegments */
671 				TW_CL_MAX_IO_SIZE,	/* maxsegsize */
672 				BUS_DMA_ALLOCNOW,	/* flags */
673 #if 0 /* XXX swildner */
674 				twa_busdma_lock,	/* lockfunc */
675 				sc->io_lock,		/* lockfuncarg */
676 #endif
677 				&sc->ioctl_tag		/* tag */)) {
678 		tw_osli_printf(sc, "error = %d",
679 			TW_CL_SEVERITY_ERROR_STRING,
680 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
681 			0x2010,
682 			"Can't allocate DMA tag for ioctl data buffers",
683 			ENOMEM);
684 		return(ENOMEM);
685 	}
686 
687 	/* Create just one map for all ioctl request data buffers. */
688 	if (bus_dmamap_create(sc->ioctl_tag, 0, &sc->ioctl_map)) {
689 		tw_osli_printf(sc, "error = %d",
690 			TW_CL_SEVERITY_ERROR_STRING,
691 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
692 			0x2011,
693 			"Can't create ioctl map",
694 			ENOMEM);
695 		return(ENOMEM);
696 	}
697 
698 
699 	/* Initialize request queues. */
700 	tw_osli_req_q_init(sc, TW_OSLI_FREE_Q);
701 	tw_osli_req_q_init(sc, TW_OSLI_BUSY_Q);
702 
703 	if ((sc->req_ctx_buf = (struct tw_osli_req_context *)
704 			kmalloc((sizeof(struct tw_osli_req_context) *
705 				TW_OSLI_MAX_NUM_REQUESTS),
706 				TW_OSLI_MALLOC_CLASS, M_WAITOK)) == NULL) {
707 		tw_osli_printf(sc, "error = %d",
708 			TW_CL_SEVERITY_ERROR_STRING,
709 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
710 			0x2012,
711 			"Failed to allocate request packets",
712 			ENOMEM);
713 		return(ENOMEM);
714 	}
715 	bzero(sc->req_ctx_buf,
716 		sizeof(struct tw_osli_req_context) * TW_OSLI_MAX_NUM_REQUESTS);
717 
718 	for (i = 0; i < TW_OSLI_MAX_NUM_REQUESTS; i++) {
719 		req = &(sc->req_ctx_buf[i]);
720 		req->ctlr = sc;
721 		if (bus_dmamap_create(sc->dma_tag, 0, &req->dma_map)) {
722 			tw_osli_printf(sc, "request # = %d, error = %d",
723 				TW_CL_SEVERITY_ERROR_STRING,
724 				TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
725 				0x2013,
726 				"Can't create dma map",
727 				i, ENOMEM);
728 			return(ENOMEM);
729 		}
730 
731 		/* Initialize the ioctl wakeup/ timeout mutex */
732 		req->ioctl_wake_timeout_lock = &(req->ioctl_wake_timeout_lock_handle);
733 		lockinit(req->ioctl_wake_timeout_lock, "tw_ioctl_wake_timeout_lock", 0, 0);
734 
735 		/* Insert request into the free queue. */
736 		tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
737 	}
738 
739 	return(0);
740 }
741 
742 
743 
744 /*
745  * Function name:	tw_osli_free_resources
746  * Description:		Performs clean-up at the time of going down.
747  *
748  * Input:		sc	-- ptr to OSL internal ctlr context
749  * Output:		None
750  * Return value:	None
751  */
752 static TW_VOID
753 tw_osli_free_resources(struct twa_softc *sc)
754 {
755 	struct tw_osli_req_context	*req;
756 	TW_INT32			error = 0;
757 
758 	tw_osli_dbg_dprintf(3, sc, "entered");
759 
760 	/* Detach from CAM */
761 	tw_osli_cam_detach(sc);
762 
763 	if (sc->req_ctx_buf)
764 		while ((req = tw_osli_req_q_remove_head(sc, TW_OSLI_FREE_Q)) !=
765 			NULL) {
766 			lockuninit(req->ioctl_wake_timeout_lock);
767 
768 			if ((error = bus_dmamap_destroy(sc->dma_tag,
769 					req->dma_map)))
770 				tw_osli_dbg_dprintf(1, sc,
771 					"dmamap_destroy(dma) returned %d",
772 					error);
773 		}
774 
775 	if ((sc->ioctl_tag) && (sc->ioctl_map))
776 		if ((error = bus_dmamap_destroy(sc->ioctl_tag, sc->ioctl_map)))
777 			tw_osli_dbg_dprintf(1, sc,
778 				"dmamap_destroy(ioctl) returned %d", error);
779 
780 	/* Free all memory allocated so far. */
781 	if (sc->req_ctx_buf)
782 		kfree(sc->req_ctx_buf, TW_OSLI_MALLOC_CLASS);
783 
784 	if (sc->non_dma_mem)
785 		kfree(sc->non_dma_mem, TW_OSLI_MALLOC_CLASS);
786 
787 	if (sc->dma_mem) {
788 		bus_dmamap_unload(sc->cmd_tag, sc->cmd_map);
789 		bus_dmamem_free(sc->cmd_tag, sc->dma_mem,
790 			sc->cmd_map);
791 	}
792 	if (sc->cmd_tag)
793 		if ((error = bus_dma_tag_destroy(sc->cmd_tag)))
794 			tw_osli_dbg_dprintf(1, sc,
795 				"dma_tag_destroy(cmd) returned %d", error);
796 
797 	if (sc->dma_tag)
798 		if ((error = bus_dma_tag_destroy(sc->dma_tag)))
799 			tw_osli_dbg_dprintf(1, sc,
800 				"dma_tag_destroy(dma) returned %d", error);
801 
802 	if (sc->ioctl_tag)
803 		if ((error = bus_dma_tag_destroy(sc->ioctl_tag)))
804 			tw_osli_dbg_dprintf(1, sc,
805 				"dma_tag_destroy(ioctl) returned %d", error);
806 
807 	if (sc->parent_tag)
808 		if ((error = bus_dma_tag_destroy(sc->parent_tag)))
809 			tw_osli_dbg_dprintf(1, sc,
810 				"dma_tag_destroy(parent) returned %d", error);
811 
812 
813 	/* Disconnect the interrupt handler. */
814 	if ((error = twa_teardown_intr(sc)))
815 			tw_osli_dbg_dprintf(1, sc,
816 				"teardown_intr returned %d", error);
817 
818 	if (sc->irq_res != NULL)
819 		if ((error = bus_release_resource(sc->bus_dev,
820 				SYS_RES_IRQ, sc->irq_res_id, sc->irq_res)))
821 			tw_osli_dbg_dprintf(1, sc,
822 				"release_resource(irq) returned %d", error);
823 
824 
825 	/* Release the register window mapping. */
826 	if (sc->reg_res != NULL)
827 		if ((error = bus_release_resource(sc->bus_dev,
828 				SYS_RES_MEMORY, sc->reg_res_id, sc->reg_res)))
829 			tw_osli_dbg_dprintf(1, sc,
830 				"release_resource(io) returned %d", error);
831 
832 	dev_ops_remove_minor(&twa_ops, device_get_unit(sc->bus_dev));
833 
834 	/* Destroy the control device. */
835 	if (sc->ctrl_dev != (struct cdev *)NULL)
836 		destroy_dev(sc->ctrl_dev);
837 
838 	if ((error = sysctl_ctx_free(&sc->sysctl_ctxt)))
839 		tw_osli_dbg_dprintf(1, sc,
840 			"sysctl_ctx_free returned %d", error);
841 
842 }
843 
844 
845 
846 /*
847  * Function name:	twa_detach
848  * Description:		Called when the controller is being detached from
849  *			the pci bus.
850  *
851  * Input:		dev	-- bus device corresponding to the ctlr
852  * Output:		None
853  * Return value:	0	-- success
854  *			non-zero-- failure
855  */
856 static TW_INT32
857 twa_detach(device_t dev)
858 {
859 	struct twa_softc	*sc = device_get_softc(dev);
860 	TW_INT32		error;
861 
862 	tw_osli_dbg_dprintf(3, sc, "entered");
863 
864 	error = EBUSY;
865 	if (sc->open) {
866 		tw_osli_printf(sc, "error = %d",
867 			TW_CL_SEVERITY_ERROR_STRING,
868 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
869 			0x2014,
870 			"Device open",
871 			error);
872 		goto out;
873 	}
874 
875 	/* Shut the controller down. */
876 	if ((error = twa_shutdown(dev)))
877 		goto out;
878 
879 	/* Free all resources associated with this controller. */
880 	tw_osli_free_resources(sc);
881 	error = 0;
882 
883 out:
884 	return(error);
885 }
886 
887 
888 
889 /*
890  * Function name:	twa_shutdown
891  * Description:		Called at unload/shutdown time.  Lets the controller
892  *			know that we are going down.
893  *
894  * Input:		dev	-- bus device corresponding to the ctlr
895  * Output:		None
896  * Return value:	0	-- success
897  *			non-zero-- failure
898  */
899 static TW_INT32
900 twa_shutdown(device_t dev)
901 {
902 	struct twa_softc	*sc = device_get_softc(dev);
903 	TW_INT32		error = 0;
904 
905 	tw_osli_dbg_dprintf(3, sc, "entered");
906 
907 	/* Disconnect interrupts. */
908 	error = twa_teardown_intr(sc);
909 
910 #if 0 /* XXX swildner */
911 	/* Stop watchdog task. */
912 	callout_drain(&(sc->watchdog_callout[0]));
913 	callout_drain(&(sc->watchdog_callout[1]));
914 #endif
915 
916 	/* Disconnect from the controller. */
917 	if ((error = tw_cl_shutdown_ctlr(&(sc->ctlr_handle), 0))) {
918 		tw_osli_printf(sc, "error = %d",
919 			TW_CL_SEVERITY_ERROR_STRING,
920 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
921 			0x2015,
922 			"Failed to shutdown Common Layer/controller",
923 			error);
924 	}
925 	return(error);
926 }
927 
928 
929 
930 #if 0 /* XXX swildner */
931 /*
932  * Function name:	twa_busdma_lock
933  * Description:		Function to provide synchronization during busdma_swi.
934  *
935  * Input:		lock_arg -- lock mutex sent as argument
936  *			op -- operation (lock/unlock) expected of the function
937  * Output:		None
938  * Return value:	None
939  */
940 TW_VOID
941 twa_busdma_lock(TW_VOID *lock_arg, bus_dma_lock_op_t op)
942 {
943 	struct spinlock	*lock;
944 
945 	lock = (struct spinlock *)lock_arg;
946 	switch (op) {
947 	case BUS_DMA_LOCK:
948 		spin_lock(lock);
949 		break;
950 
951 	case BUS_DMA_UNLOCK:
952 		spin_unlock(lock);
953 		break;
954 
955 	default:
956 		panic("Unknown operation 0x%x for twa_busdma_lock!", op);
957 	}
958 }
959 #endif
960 
961 
962 /*
963  * Function name:	twa_pci_intr
964  * Description:		Interrupt handler.  Wrapper for twa_interrupt.
965  *
966  * Input:		arg	-- ptr to OSL internal ctlr context
967  * Output:		None
968  * Return value:	None
969  */
970 static TW_VOID
971 twa_pci_intr(TW_VOID *arg)
972 {
973 	struct twa_softc	*sc = (struct twa_softc *)arg;
974 
975 	tw_osli_dbg_dprintf(10, sc, "entered");
976 	tw_cl_interrupt(&(sc->ctlr_handle));
977 }
978 
979 
980 /*
981  * Function name:	tw_osli_fw_passthru
982  * Description:		Builds a fw passthru cmd pkt, and submits it to CL.
983  *
984  * Input:		sc	-- ptr to OSL internal ctlr context
985  *			buf	-- ptr to ioctl pkt understood by CL
986  * Output:		None
987  * Return value:	0	-- success
988  *			non-zero-- failure
989  */
990 TW_INT32
991 tw_osli_fw_passthru(struct twa_softc *sc, TW_INT8 *buf)
992 {
993 	struct tw_osli_req_context		*req;
994 	struct tw_osli_ioctl_no_data_buf	*user_buf =
995 		(struct tw_osli_ioctl_no_data_buf *)buf;
996 	TW_TIME					end_time;
997 	TW_UINT32				timeout = 60;
998 	TW_UINT32				data_buf_size_adjusted;
999 	struct tw_cl_req_packet			*req_pkt;
1000 	struct tw_cl_passthru_req_packet	*pt_req;
1001 	TW_INT32				error;
1002 
1003 	tw_osli_dbg_dprintf(5, sc, "ioctl: passthru");
1004 
1005 	if ((req = tw_osli_get_request(sc)) == NULL)
1006 		return(EBUSY);
1007 
1008 	req->req_handle.osl_req_ctxt = req;
1009 	req->orig_req = buf;
1010 	req->flags |= TW_OSLI_REQ_FLAGS_PASSTHRU;
1011 
1012 	req_pkt = &(req->req_pkt);
1013 	req_pkt->status = 0;
1014 	req_pkt->tw_osl_callback = tw_osl_complete_passthru;
1015 	/* Let the Common Layer retry the request on cmd queue full. */
1016 	req_pkt->flags |= TW_CL_REQ_RETRY_ON_BUSY;
1017 
1018 	pt_req = &(req_pkt->gen_req_pkt.pt_req);
1019 	/*
1020 	 * Make sure that the data buffer sent to firmware is a
1021 	 * 512 byte multiple in size.
1022 	 */
1023 	data_buf_size_adjusted =
1024 		(user_buf->driver_pkt.buffer_length +
1025 		(sc->sg_size_factor - 1)) & ~(sc->sg_size_factor - 1);
1026 	if ((req->length = data_buf_size_adjusted)) {
1027 		if ((req->data = kmalloc(data_buf_size_adjusted,
1028 			TW_OSLI_MALLOC_CLASS, M_WAITOK)) == NULL) {
1029 			error = ENOMEM;
1030 			tw_osli_printf(sc, "error = %d",
1031 				TW_CL_SEVERITY_ERROR_STRING,
1032 				TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1033 				0x2016,
1034 				"Could not alloc mem for "
1035 				"fw_passthru data_buf",
1036 				error);
1037 			goto fw_passthru_err;
1038 		}
1039 		/* Copy the payload. */
1040 		if ((error = copyin((TW_VOID *)(user_buf->pdata),
1041 			req->data,
1042 			user_buf->driver_pkt.buffer_length)) != 0) {
1043 			tw_osli_printf(sc, "error = %d",
1044 				TW_CL_SEVERITY_ERROR_STRING,
1045 				TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1046 				0x2017,
1047 				"Could not copyin fw_passthru data_buf",
1048 				error);
1049 			goto fw_passthru_err;
1050 		}
1051 		pt_req->sgl_entries = 1; /* will be updated during mapping */
1052 		req->flags |= (TW_OSLI_REQ_FLAGS_DATA_IN |
1053 			TW_OSLI_REQ_FLAGS_DATA_OUT);
1054 	} else
1055 		pt_req->sgl_entries = 0; /* no payload */
1056 
1057 	pt_req->cmd_pkt = (TW_VOID *)(&(user_buf->cmd_pkt));
1058 	pt_req->cmd_pkt_length = sizeof(struct tw_cl_command_packet);
1059 
1060 	if ((error = tw_osli_map_request(req)))
1061 		goto fw_passthru_err;
1062 
1063 	end_time = tw_osl_get_local_time() + timeout;
1064 	while (req->state != TW_OSLI_REQ_STATE_COMPLETE) {
1065 		lockmgr(req->ioctl_wake_timeout_lock, LK_EXCLUSIVE);
1066 		req->flags |= TW_OSLI_REQ_FLAGS_SLEEPING;
1067 
1068 		error = lksleep(req, req->ioctl_wake_timeout_lock, 0,
1069 			    "twa_passthru", timeout*hz);
1070 		lockmgr(req->ioctl_wake_timeout_lock, LK_RELEASE);
1071 
1072 		if (!(req->flags & TW_OSLI_REQ_FLAGS_SLEEPING))
1073 			error = 0;
1074 		req->flags &= ~TW_OSLI_REQ_FLAGS_SLEEPING;
1075 
1076 		if (! error) {
1077 			if (((error = req->error_code)) ||
1078 				((error = (req->state !=
1079 				TW_OSLI_REQ_STATE_COMPLETE))) ||
1080 				((error = req_pkt->status)))
1081 				goto fw_passthru_err;
1082 			break;
1083 		}
1084 
1085 		if (req_pkt->status) {
1086 			error = req_pkt->status;
1087 			goto fw_passthru_err;
1088 		}
1089 
1090 		if (error == EWOULDBLOCK) {
1091 			/* Time out! */
1092 			if ((!(req->error_code))                       &&
1093 			    (req->state == TW_OSLI_REQ_STATE_COMPLETE) &&
1094 			    (!(req_pkt->status))			  ) {
1095 #ifdef    TW_OSL_DEBUG
1096 				tw_osli_printf(sc, "request = %p",
1097 					TW_CL_SEVERITY_ERROR_STRING,
1098 					TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1099 					0x7777,
1100 					"FALSE Passthru timeout!",
1101 					req);
1102 #endif /* TW_OSL_DEBUG */
1103 				error = 0; /* False error */
1104 				break;
1105 			}
1106 			if (!(tw_cl_is_reset_needed(&(req->ctlr->ctlr_handle)))) {
1107 #ifdef    TW_OSL_DEBUG
1108 				tw_osli_printf(sc, "request = %p",
1109 					TW_CL_SEVERITY_ERROR_STRING,
1110 					TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1111 					0x2018,
1112 					"Passthru request timed out!",
1113 					req);
1114 #else  /* TW_OSL_DEBUG */
1115 			device_printf((sc)->bus_dev, "Passthru request timed out!\n");
1116 #endif /* TW_OSL_DEBUG */
1117 				tw_cl_reset_ctlr(&(req->ctlr->ctlr_handle));
1118 			}
1119 
1120 			error = 0;
1121 			end_time = tw_osl_get_local_time() + timeout;
1122 			continue;
1123 			/*
1124 			 * Don't touch req after a reset.  It (and any
1125 			 * associated data) will be
1126 			 * unmapped by the callback.
1127 			 */
1128 		}
1129 		/*
1130 		 * Either the request got completed, or we were woken up by a
1131 		 * signal.  Calculate the new timeout, in case it was the latter.
1132 		 */
1133 		timeout = (end_time - tw_osl_get_local_time());
1134 	} /* End of while loop */
1135 
1136 	/* If there was a payload, copy it back. */
1137 	if ((!error) && (req->length))
1138 		if ((error = copyout(req->data, user_buf->pdata,
1139 			user_buf->driver_pkt.buffer_length)))
1140 			tw_osli_printf(sc, "error = %d",
1141 				TW_CL_SEVERITY_ERROR_STRING,
1142 				TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1143 				0x2019,
1144 				"Could not copyout fw_passthru data_buf",
1145 				error);
1146 
1147 fw_passthru_err:
1148 
1149 	if (req_pkt->status == TW_CL_ERR_REQ_BUS_RESET)
1150 		error = EBUSY;
1151 
1152 	user_buf->driver_pkt.os_status = error;
1153 	/* Free resources. */
1154 	if (req->data)
1155 		kfree(req->data, TW_OSLI_MALLOC_CLASS);
1156 	tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
1157 	return(error);
1158 }
1159 
1160 
1161 
1162 /*
1163  * Function name:	tw_osl_complete_passthru
1164  * Description:		Called to complete passthru requests.
1165  *
1166  * Input:		req_handle	-- ptr to request handle
1167  * Output:		None
1168  * Return value:	None
1169  */
1170 TW_VOID
1171 tw_osl_complete_passthru(struct tw_cl_req_handle *req_handle)
1172 {
1173 	struct tw_osli_req_context	*req = req_handle->osl_req_ctxt;
1174 	struct tw_cl_req_packet		*req_pkt =
1175 		(struct tw_cl_req_packet *)(&req->req_pkt);
1176 	struct twa_softc		*sc = req->ctlr;
1177 
1178 	tw_osli_dbg_dprintf(5, sc, "entered");
1179 
1180 	if (req->state != TW_OSLI_REQ_STATE_BUSY) {
1181 		tw_osli_printf(sc, "request = %p, status = %d",
1182 			TW_CL_SEVERITY_ERROR_STRING,
1183 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1184 			0x201B,
1185 			"Unposted command completed!!",
1186 			req, req->state);
1187 	}
1188 
1189 	/*
1190 	 * Remove request from the busy queue.  Just mark it complete.
1191 	 * There's no need to move it into the complete queue as we are
1192 	 * going to be done with it right now.
1193 	 */
1194 	req->state = TW_OSLI_REQ_STATE_COMPLETE;
1195 	tw_osli_req_q_remove_item(req, TW_OSLI_BUSY_Q);
1196 
1197 	tw_osli_unmap_request(req);
1198 
1199 	/*
1200 	 * Don't do a wake up if there was an error even before the request
1201 	 * was sent down to the Common Layer, and we hadn't gotten an
1202 	 * EINPROGRESS.  The request originator will then be returned an
1203 	 * error, and he can do the clean-up.
1204 	 */
1205 	if ((req->error_code) && (!(req->flags & TW_OSLI_REQ_FLAGS_IN_PROGRESS)))
1206 		return;
1207 
1208 	if (req->flags & TW_OSLI_REQ_FLAGS_PASSTHRU) {
1209 		if (req->flags & TW_OSLI_REQ_FLAGS_SLEEPING) {
1210 			/* Wake up the sleeping command originator. */
1211 			tw_osli_dbg_dprintf(5, sc,
1212 				"Waking up originator of request %p", req);
1213 			req->flags &= ~TW_OSLI_REQ_FLAGS_SLEEPING;
1214 			wakeup_one(req);
1215 		} else {
1216 			/*
1217 			 * If the request completed even before mtx_sleep
1218 			 * was called, simply return.
1219 			 */
1220 			if (req->flags & TW_OSLI_REQ_FLAGS_MAPPED)
1221 				return;
1222 
1223 			if (req_pkt->status == TW_CL_ERR_REQ_BUS_RESET)
1224 				return;
1225 
1226 			tw_osli_printf(sc, "request = %p",
1227 				TW_CL_SEVERITY_ERROR_STRING,
1228 				TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1229 				0x201C,
1230 				"Passthru callback called, "
1231 				"and caller not sleeping",
1232 				req);
1233 		}
1234 	} else {
1235 		tw_osli_printf(sc, "request = %p",
1236 			TW_CL_SEVERITY_ERROR_STRING,
1237 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1238 			0x201D,
1239 			"Passthru callback called for non-passthru request",
1240 			req);
1241 	}
1242 }
1243 
1244 
1245 
1246 /*
1247  * Function name:	tw_osli_get_request
1248  * Description:		Gets a request pkt from the free queue.
1249  *
1250  * Input:		sc	-- ptr to OSL internal ctlr context
1251  * Output:		None
1252  * Return value:	ptr to request pkt	-- success
1253  *			NULL			-- failure
1254  */
1255 struct tw_osli_req_context *
1256 tw_osli_get_request(struct twa_softc *sc)
1257 {
1258 	struct tw_osli_req_context	*req;
1259 
1260 	tw_osli_dbg_dprintf(4, sc, "entered");
1261 
1262 	/* Get a free request packet. */
1263 	req = tw_osli_req_q_remove_head(sc, TW_OSLI_FREE_Q);
1264 
1265 	/* Initialize some fields to their defaults. */
1266 	if (req) {
1267 		req->req_handle.osl_req_ctxt = NULL;
1268 		req->req_handle.cl_req_ctxt = NULL;
1269 		req->req_handle.is_io = 0;
1270 		req->data = NULL;
1271 		req->length = 0;
1272 		req->deadline = 0;
1273 		req->real_data = NULL;
1274 		req->real_length = 0;
1275 		req->state = TW_OSLI_REQ_STATE_INIT;/* req being initialized */
1276 		req->flags = 0;
1277 		req->error_code = 0;
1278 		req->orig_req = NULL;
1279 
1280 		bzero(&(req->req_pkt), sizeof(struct tw_cl_req_packet));
1281 
1282 	}
1283 	return(req);
1284 }
1285 
1286 
1287 
1288 /*
1289  * Function name:	twa_map_load_data_callback
1290  * Description:		Callback of bus_dmamap_load for the buffer associated
1291  *			with data.  Updates the cmd pkt (size/sgl_entries
1292  *			fields, as applicable) to reflect the number of sg
1293  *			elements.
1294  *
1295  * Input:		arg	-- ptr to OSL internal request context
1296  *			segs	-- ptr to a list of segment descriptors
1297  *			nsegments--# of segments
1298  *			error	-- 0 if no errors encountered before callback,
1299  *				   non-zero if errors were encountered
1300  * Output:		None
1301  * Return value:	None
1302  */
1303 static TW_VOID
1304 twa_map_load_data_callback(TW_VOID *arg, bus_dma_segment_t *segs,
1305 	TW_INT32 nsegments, TW_INT32 error)
1306 {
1307 	struct tw_osli_req_context	*req =
1308 		(struct tw_osli_req_context *)arg;
1309 	struct twa_softc		*sc = req->ctlr;
1310 	struct tw_cl_req_packet		*req_pkt = &(req->req_pkt);
1311 
1312 	tw_osli_dbg_dprintf(10, sc, "entered");
1313 
1314 	if (error == EINVAL) {
1315 		req->error_code = error;
1316 		return;
1317 	}
1318 
1319 	/* Mark the request as currently being processed. */
1320 	req->state = TW_OSLI_REQ_STATE_BUSY;
1321 	/* Move the request into the busy queue. */
1322 	tw_osli_req_q_insert_tail(req, TW_OSLI_BUSY_Q);
1323 
1324 	req->flags |= TW_OSLI_REQ_FLAGS_MAPPED;
1325 
1326 	if (error == EFBIG) {
1327 		req->error_code = error;
1328 		goto out;
1329 	}
1330 
1331 	if (req->flags & TW_OSLI_REQ_FLAGS_PASSTHRU) {
1332 		struct tw_cl_passthru_req_packet	*pt_req;
1333 
1334 		if (req->flags & TW_OSLI_REQ_FLAGS_DATA_IN)
1335 			bus_dmamap_sync(sc->ioctl_tag, sc->ioctl_map,
1336 				BUS_DMASYNC_PREREAD);
1337 
1338 		if (req->flags & TW_OSLI_REQ_FLAGS_DATA_OUT) {
1339 			/*
1340 			 * If we're using an alignment buffer, and we're
1341 			 * writing data, copy the real data out.
1342 			 */
1343 			if (req->flags & TW_OSLI_REQ_FLAGS_DATA_COPY_NEEDED)
1344 				bcopy(req->real_data, req->data, req->real_length);
1345 			bus_dmamap_sync(sc->ioctl_tag, sc->ioctl_map,
1346 				BUS_DMASYNC_PREWRITE);
1347 		}
1348 
1349 		pt_req = &(req_pkt->gen_req_pkt.pt_req);
1350 		pt_req->sg_list = (TW_UINT8 *)segs;
1351 		pt_req->sgl_entries += (nsegments - 1);
1352 		error = tw_cl_fw_passthru(&(sc->ctlr_handle), req_pkt,
1353 			&(req->req_handle));
1354 	} else {
1355 		struct tw_cl_scsi_req_packet	*scsi_req;
1356 
1357 		if (req->flags & TW_OSLI_REQ_FLAGS_DATA_IN)
1358 			bus_dmamap_sync(sc->dma_tag, req->dma_map,
1359 				BUS_DMASYNC_PREREAD);
1360 
1361 		if (req->flags & TW_OSLI_REQ_FLAGS_DATA_OUT) {
1362 			/*
1363 			 * If we're using an alignment buffer, and we're
1364 			 * writing data, copy the real data out.
1365 			 */
1366 			if (req->flags & TW_OSLI_REQ_FLAGS_DATA_COPY_NEEDED)
1367 				bcopy(req->real_data, req->data, req->real_length);
1368 			bus_dmamap_sync(sc->dma_tag, req->dma_map,
1369 				BUS_DMASYNC_PREWRITE);
1370 		}
1371 
1372 		scsi_req = &(req_pkt->gen_req_pkt.scsi_req);
1373 		scsi_req->sg_list = (TW_UINT8 *)segs;
1374 		scsi_req->sgl_entries += (nsegments - 1);
1375 		error = tw_cl_start_io(&(sc->ctlr_handle), req_pkt,
1376 			&(req->req_handle));
1377 	}
1378 
1379 out:
1380 	if (error) {
1381 		req->error_code = error;
1382 		req_pkt->tw_osl_callback(&(req->req_handle));
1383 		/*
1384 		 * If the caller had been returned EINPROGRESS, and he has
1385 		 * registered a callback for handling completion, the callback
1386 		 * will never get called because we were unable to submit the
1387 		 * request.  So, free up the request right here.
1388 		 */
1389 		if (req->flags & TW_OSLI_REQ_FLAGS_IN_PROGRESS)
1390 			tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
1391 	}
1392 }
1393 
1394 
1395 
1396 /*
1397  * Function name:	twa_map_load_callback
1398  * Description:		Callback of bus_dmamap_load for the buffer associated
1399  *			with a cmd pkt.
1400  *
1401  * Input:		arg	-- ptr to variable to hold phys addr
1402  *			segs	-- ptr to a list of segment descriptors
1403  *			nsegments--# of segments
1404  *			error	-- 0 if no errors encountered before callback,
1405  *				   non-zero if errors were encountered
1406  * Output:		None
1407  * Return value:	None
1408  */
1409 static TW_VOID
1410 twa_map_load_callback(TW_VOID *arg, bus_dma_segment_t *segs,
1411 	TW_INT32 nsegments, TW_INT32 error)
1412 {
1413 	*((bus_addr_t *)arg) = segs[0].ds_addr;
1414 }
1415 
1416 
1417 
1418 /*
1419  * Function name:	tw_osli_map_request
1420  * Description:		Maps a cmd pkt and data associated with it, into
1421  *			DMA'able memory.
1422  *
1423  * Input:		req	-- ptr to request pkt
1424  * Output:		None
1425  * Return value:	0	-- success
1426  *			non-zero-- failure
1427  */
1428 TW_INT32
1429 tw_osli_map_request(struct tw_osli_req_context *req)
1430 {
1431 	struct twa_softc	*sc = req->ctlr;
1432 	TW_INT32		error = 0;
1433 
1434 	tw_osli_dbg_dprintf(10, sc, "entered");
1435 
1436 	/* If the command involves data, map that too. */
1437 	if (req->data != NULL) {
1438 		/*
1439 		 * It's sufficient for the data pointer to be 4-byte aligned
1440 		 * to work with 9000.  However, if 4-byte aligned addresses
1441 		 * are passed to bus_dmamap_load, we can get back sg elements
1442 		 * that are not 512-byte multiples in size.  So, we will let
1443 		 * only those buffers that are 512-byte aligned to pass
1444 		 * through, and bounce the rest, so as to make sure that we
1445 		 * always get back sg elements that are 512-byte multiples
1446 		 * in size.
1447 		 */
1448 		if (((vm_offset_t)req->data % sc->sg_size_factor) ||
1449 			(req->length % sc->sg_size_factor)) {
1450 			req->flags |= TW_OSLI_REQ_FLAGS_DATA_COPY_NEEDED;
1451 			/* Save original data pointer and length. */
1452 			req->real_data = req->data;
1453 			req->real_length = req->length;
1454 			req->length = (req->length +
1455 				(sc->sg_size_factor - 1)) &
1456 				~(sc->sg_size_factor - 1);
1457 			req->data = kmalloc(req->length, TW_OSLI_MALLOC_CLASS,
1458 					M_NOWAIT);
1459 			if (req->data == NULL) {
1460 				tw_osli_printf(sc, "error = %d",
1461 					TW_CL_SEVERITY_ERROR_STRING,
1462 					TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1463 					0x201E,
1464 					"Failed to allocate memory "
1465 					"for bounce buffer",
1466 					ENOMEM);
1467 				/* Restore original data pointer and length. */
1468 				req->data = req->real_data;
1469 				req->length = req->real_length;
1470 				return(ENOMEM);
1471 			}
1472 		}
1473 
1474 		/*
1475 		 * Map the data buffer into bus space and build the SG list.
1476 		 */
1477 		if (req->flags & TW_OSLI_REQ_FLAGS_PASSTHRU) {
1478 			/* Lock against multiple simultaneous ioctl calls. */
1479 			spin_lock(sc->io_lock);
1480 			error = bus_dmamap_load(sc->ioctl_tag, sc->ioctl_map,
1481 				req->data, req->length,
1482 				twa_map_load_data_callback, req,
1483 				BUS_DMA_WAITOK);
1484 			spin_unlock(sc->io_lock);
1485 		} else {
1486 			/*
1487 			 * There's only one CAM I/O thread running at a time.
1488 			 * So, there's no need to hold the io_lock.
1489 			 */
1490 			error = bus_dmamap_load(sc->dma_tag, req->dma_map,
1491 				req->data, req->length,
1492 				twa_map_load_data_callback, req,
1493 				BUS_DMA_WAITOK);
1494 		}
1495 
1496 		if (!error)
1497 			error = req->error_code;
1498 		else {
1499 			if (error == EINPROGRESS) {
1500 				/*
1501 				 * Specifying sc->io_lock as the lockfuncarg
1502 				 * in ...tag_create should protect the access
1503 				 * of ...FLAGS_MAPPED from the callback.
1504 				 */
1505 				spin_lock(sc->io_lock);
1506 				if (!(req->flags & TW_OSLI_REQ_FLAGS_MAPPED))
1507 					req->flags |= TW_OSLI_REQ_FLAGS_IN_PROGRESS;
1508 				tw_osli_disallow_new_requests(sc, &(req->req_handle));
1509 				spin_unlock(sc->io_lock);
1510 				error = 0;
1511 			} else {
1512 				tw_osli_printf(sc, "error = %d",
1513 					TW_CL_SEVERITY_ERROR_STRING,
1514 					TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
1515 					0x9999,
1516 					"Failed to map DMA memory "
1517 					"for I/O request",
1518 					error);
1519 				req->flags |= TW_OSLI_REQ_FLAGS_FAILED;
1520 				/* Free alignment buffer if it was used. */
1521 				if (req->flags &
1522 					TW_OSLI_REQ_FLAGS_DATA_COPY_NEEDED) {
1523 					kfree(req->data, TW_OSLI_MALLOC_CLASS);
1524 					/*
1525 					 * Restore original data pointer
1526 					 * and length.
1527 					 */
1528 					req->data = req->real_data;
1529 					req->length = req->real_length;
1530 				}
1531 			}
1532 		}
1533 
1534 	} else {
1535 		/* Mark the request as currently being processed. */
1536 		req->state = TW_OSLI_REQ_STATE_BUSY;
1537 		/* Move the request into the busy queue. */
1538 		tw_osli_req_q_insert_tail(req, TW_OSLI_BUSY_Q);
1539 		if (req->flags & TW_OSLI_REQ_FLAGS_PASSTHRU)
1540 			error = tw_cl_fw_passthru(&sc->ctlr_handle,
1541 					&(req->req_pkt), &(req->req_handle));
1542 		else
1543 			error = tw_cl_start_io(&sc->ctlr_handle,
1544 					&(req->req_pkt), &(req->req_handle));
1545 		if (error) {
1546 			req->error_code = error;
1547 			req->req_pkt.tw_osl_callback(&(req->req_handle));
1548 		}
1549 	}
1550 	return(error);
1551 }
1552 
1553 
1554 
1555 /*
1556  * Function name:	tw_osli_unmap_request
1557  * Description:		Undoes the mapping done by tw_osli_map_request.
1558  *
1559  * Input:		req	-- ptr to request pkt
1560  * Output:		None
1561  * Return value:	None
1562  */
1563 TW_VOID
1564 tw_osli_unmap_request(struct tw_osli_req_context *req)
1565 {
1566 	struct twa_softc	*sc = req->ctlr;
1567 
1568 	tw_osli_dbg_dprintf(10, sc, "entered");
1569 
1570 	/* If the command involved data, unmap that too. */
1571 	if (req->data != NULL) {
1572 		if (req->flags & TW_OSLI_REQ_FLAGS_PASSTHRU) {
1573 			/* Lock against multiple simultaneous ioctl calls. */
1574 			spin_lock(sc->io_lock);
1575 
1576 			if (req->flags & TW_OSLI_REQ_FLAGS_DATA_IN) {
1577 				bus_dmamap_sync(sc->ioctl_tag,
1578 					sc->ioctl_map, BUS_DMASYNC_POSTREAD);
1579 
1580 				/*
1581 				 * If we are using a bounce buffer, and we are
1582 				 * reading data, copy the real data in.
1583 				 */
1584 				if (req->flags & TW_OSLI_REQ_FLAGS_DATA_COPY_NEEDED)
1585 					bcopy(req->data, req->real_data,
1586 						req->real_length);
1587 			}
1588 
1589 			if (req->flags & TW_OSLI_REQ_FLAGS_DATA_OUT)
1590 				bus_dmamap_sync(sc->ioctl_tag, sc->ioctl_map,
1591 					BUS_DMASYNC_POSTWRITE);
1592 
1593 			bus_dmamap_unload(sc->ioctl_tag, sc->ioctl_map);
1594 
1595 			spin_unlock(sc->io_lock);
1596 		} else {
1597 			if (req->flags & TW_OSLI_REQ_FLAGS_DATA_IN) {
1598 				bus_dmamap_sync(sc->dma_tag,
1599 					req->dma_map, BUS_DMASYNC_POSTREAD);
1600 
1601 				/*
1602 				 * If we are using a bounce buffer, and we are
1603 				 * reading data, copy the real data in.
1604 				 */
1605 				if (req->flags & TW_OSLI_REQ_FLAGS_DATA_COPY_NEEDED)
1606 					bcopy(req->data, req->real_data,
1607 						req->real_length);
1608 			}
1609 			if (req->flags & TW_OSLI_REQ_FLAGS_DATA_OUT)
1610 				bus_dmamap_sync(sc->dma_tag, req->dma_map,
1611 					BUS_DMASYNC_POSTWRITE);
1612 
1613 			bus_dmamap_unload(sc->dma_tag, req->dma_map);
1614 		}
1615 	}
1616 
1617 	/* Free alignment buffer if it was used. */
1618 	if (req->flags & TW_OSLI_REQ_FLAGS_DATA_COPY_NEEDED) {
1619 		kfree(req->data, TW_OSLI_MALLOC_CLASS);
1620 		/* Restore original data pointer and length. */
1621 		req->data = req->real_data;
1622 		req->length = req->real_length;
1623 	}
1624 }
1625 
1626 
1627 
1628 #ifdef TW_OSL_DEBUG
1629 
1630 TW_VOID	twa_report_stats(TW_VOID);
1631 TW_VOID	twa_reset_stats(TW_VOID);
1632 TW_VOID	tw_osli_print_ctlr_stats(struct twa_softc *sc);
1633 TW_VOID twa_print_req_info(struct tw_osli_req_context *req);
1634 
1635 
1636 /*
1637  * Function name:	twa_report_stats
1638  * Description:		For being called from ddb.  Calls functions that print
1639  *			OSL and CL internal stats for the controller.
1640  *
1641  * Input:		None
1642  * Output:		None
1643  * Return value:	None
1644  */
1645 TW_VOID
1646 twa_report_stats(TW_VOID)
1647 {
1648 	struct twa_softc	*sc;
1649 	TW_INT32		i;
1650 
1651 	for (i = 0; (sc = devclass_get_softc(twa_devclass, i)) != NULL; i++) {
1652 		tw_osli_print_ctlr_stats(sc);
1653 		tw_cl_print_ctlr_stats(&sc->ctlr_handle);
1654 	}
1655 }
1656 
1657 
1658 
1659 /*
1660  * Function name:	tw_osli_print_ctlr_stats
1661  * Description:		For being called from ddb.  Prints OSL controller stats
1662  *
1663  * Input:		sc	-- ptr to OSL internal controller context
1664  * Output:		None
1665  * Return value:	None
1666  */
1667 TW_VOID
1668 tw_osli_print_ctlr_stats(struct twa_softc *sc)
1669 {
1670 	twa_printf(sc, "osl_ctlr_ctxt = %p\n", sc);
1671 	twa_printf(sc, "OSLq type  current  max\n");
1672 	twa_printf(sc, "free      %04d     %04d\n",
1673 		sc->q_stats[TW_OSLI_FREE_Q].cur_len,
1674 		sc->q_stats[TW_OSLI_FREE_Q].max_len);
1675 	twa_printf(sc, "busy      %04d     %04d\n",
1676 		sc->q_stats[TW_OSLI_BUSY_Q].cur_len,
1677 		sc->q_stats[TW_OSLI_BUSY_Q].max_len);
1678 }
1679 
1680 
1681 
1682 /*
1683  * Function name:	twa_print_req_info
1684  * Description:		For being called from ddb.  Calls functions that print
1685  *			OSL and CL internal details for the request.
1686  *
1687  * Input:		req	-- ptr to OSL internal request context
1688  * Output:		None
1689  * Return value:	None
1690  */
1691 TW_VOID
1692 twa_print_req_info(struct tw_osli_req_context *req)
1693 {
1694 	struct twa_softc	*sc = req->ctlr;
1695 
1696 	twa_printf(sc, "OSL details for request:\n");
1697 	twa_printf(sc, "osl_req_ctxt = %p, cl_req_ctxt = %p\n"
1698 		"data = %p, length = 0x%x, real_data = %p, real_length = 0x%x\n"
1699 		"state = 0x%x, flags = 0x%x, error = 0x%x, orig_req = %p\n"
1700 		"next_req = %p, prev_req = %p, dma_map = %p\n",
1701 		req->req_handle.osl_req_ctxt, req->req_handle.cl_req_ctxt,
1702 		req->data, req->length, req->real_data, req->real_length,
1703 		req->state, req->flags, req->error_code, req->orig_req,
1704 		req->link.next, req->link.prev, req->dma_map);
1705 	tw_cl_print_req_info(&(req->req_handle));
1706 }
1707 
1708 
1709 
1710 /*
1711  * Function name:	twa_reset_stats
1712  * Description:		For being called from ddb.
1713  *			Resets some OSL controller stats.
1714  *
1715  * Input:		None
1716  * Output:		None
1717  * Return value:	None
1718  */
1719 TW_VOID
1720 twa_reset_stats(TW_VOID)
1721 {
1722 	struct twa_softc	*sc;
1723 	TW_INT32		i;
1724 
1725 	for (i = 0; (sc = devclass_get_softc(twa_devclass, i)) != NULL; i++) {
1726 		sc->q_stats[TW_OSLI_FREE_Q].max_len = 0;
1727 		sc->q_stats[TW_OSLI_BUSY_Q].max_len = 0;
1728 		tw_cl_reset_stats(&sc->ctlr_handle);
1729 	}
1730 }
1731 
1732 #endif /* TW_OSL_DEBUG */
1733