xref: /titanic_44/usr/src/uts/intel/io/amr/amr.c (revision 62a1b812a0c45c0d4c10ef645dda42bf71080108)
1 /*
2  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 /*
6  * Copyright (c) 1999,2000 Michael Smith
7  * Copyright (c) 2000 BSDi
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 /*
32  * Copyright (c) 2002 Eric Moore
33  * Copyright (c) 2002 LSI Logic Corporation
34  * All rights reserved.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  * 2. Redistributions in binary form must reproduce the above copyright
42  *    notice, this list of conditions and the following disclaimer in the
43  *    documentation and/or other materials provided with the distribution.
44  * 3. The party using or redistributing the source code and binary forms
45  *    agrees to the disclaimer below and the terms and conditions set forth
46  *    herein.
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58  * SUCH DAMAGE.
59  */
60 #pragma ident	"%Z%%M%	%I%	%E% SMI"
61 
62 #include <sys/int_types.h>
63 #include <sys/scsi/scsi.h>
64 #include <sys/dkbad.h>
65 #include <sys/dklabel.h>
66 #include <sys/dkio.h>
67 #include <sys/cdio.h>
68 #include <sys/mhd.h>
69 #include <sys/vtoc.h>
70 #include <sys/dktp/fdisk.h>
71 #include <sys/scsi/targets/sddef.h>
72 #include <sys/debug.h>
73 #include <sys/pci.h>
74 #include <sys/ksynch.h>
75 #include <sys/ddi.h>
76 #include <sys/sunddi.h>
77 #include <sys/modctl.h>
78 #include <sys/byteorder.h>
79 
80 #include "amrreg.h"
81 #include "amrvar.h"
82 
83 /* dynamic debug symbol */
84 int	amr_debug_var = 0;
85 
86 #define	AMR_DELAY(cond, count, done_flag) { \
87 		int local_counter = 0; \
88 		done_flag = 1; \
89 		while (!(cond)) { \
90 			delay(drv_usectohz(100)); \
91 			if ((local_counter) > count) { \
92 				done_flag = 0; \
93 				break; \
94 			} \
95 			(local_counter)++; \
96 		} \
97 	}
98 
99 #define	AMR_BUSYWAIT(cond, count, done_flag) { \
100 		int local_counter = 0; \
101 		done_flag = 1; \
102 		while (!(cond)) { \
103 			drv_usecwait(100); \
104 			if ((local_counter) > count) { \
105 				done_flag = 0; \
106 				break; \
107 			} \
108 			(local_counter)++; \
109 		} \
110 	}
111 
112 /*
113  * driver interfaces
114  */
115 char _depends_on[] = "misc/scsi";
116 
117 static uint_t amr_intr(caddr_t arg);
118 static void amr_done(struct amr_softs *softs);
119 
120 static int amr_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
121 			void *arg, void **result);
122 static int amr_attach(dev_info_t *, ddi_attach_cmd_t);
123 static int amr_detach(dev_info_t *, ddi_detach_cmd_t);
124 
125 static int amr_setup_mbox(struct amr_softs *softs);
126 static int amr_setup_sg(struct amr_softs *softs);
127 
128 /*
129  * Command wrappers
130  */
131 static int amr_query_controller(struct amr_softs *softs);
132 static void *amr_enquiry(struct amr_softs *softs, size_t bufsize,
133 			uint8_t cmd, uint8_t cmdsub, uint8_t cmdqual);
134 static int amr_flush(struct amr_softs *softs);
135 
136 /*
137  * Command processing.
138  */
139 static void amr_rw_command(struct amr_softs *softs,
140 			struct scsi_pkt *pkt, int lun);
141 static void amr_mode_sense(union scsi_cdb *cdbp, struct buf *bp,
142 			unsigned int capacity);
143 static void amr_set_arq_data(struct scsi_pkt *pkt, uchar_t key);
144 static int amr_enquiry_mapcmd(struct amr_command *ac, uint32_t data_size);
145 static void amr_enquiry_unmapcmd(struct amr_command *ac);
146 static int amr_mapcmd(struct amr_command *ac, int (*callback)(), caddr_t arg);
147 static void amr_unmapcmd(struct amr_command *ac);
148 
149 /*
150  * Status monitoring
151  */
152 static void amr_periodic(void *data);
153 
154 /*
155  * Interface-specific shims
156  */
157 static int amr_poll_command(struct amr_command *ac);
158 static void amr_start_waiting_queue(void *softp);
159 static void amr_call_pkt_comp(struct amr_command *head);
160 
161 /*
162  * SCSI interface
163  */
164 static int amr_setup_tran(dev_info_t  *dip, struct amr_softs *softp);
165 
166 /*
167  * Function prototypes
168  *
169  * SCSA functions exported by means of the transport table
170  */
171 static int amr_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
172 	scsi_hba_tran_t *tran, struct scsi_device *sd);
173 static int amr_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt);
174 static int amr_tran_reset(struct scsi_address *ap, int level);
175 static int amr_tran_getcap(struct scsi_address *ap, char *cap, int whom);
176 static int amr_tran_setcap(struct scsi_address *ap, char *cap, int value,
177     int whom);
178 static struct scsi_pkt *amr_tran_init_pkt(struct scsi_address *ap,
179     struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
180     int tgtlen, int flags, int (*callback)(), caddr_t arg);
181 static void amr_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt);
182 static void amr_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt);
183 static void amr_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt);
184 
185 static ddi_dma_attr_t buffer_dma_attr = {
186 		DMA_ATTR_V0,	/* version of this structure */
187 		0,		/* lowest usable address */
188 		0xffffffffull,	/* highest usable address */
189 		0x00ffffffull,	/* maximum DMAable byte count */
190 		4,		/* alignment */
191 		1,		/* burst sizes */
192 		1,		/* minimum transfer */
193 		0xffffffffull,	/* maximum transfer */
194 		0xffffffffull,	/* maximum segment length */
195 		AMR_NSEG,	/* maximum number of segments */
196 		AMR_BLKSIZE,	/* granularity */
197 		0,		/* flags (reserved) */
198 };
199 
200 static ddi_dma_attr_t addr_dma_attr = {
201 		DMA_ATTR_V0,	/* version of this structure */
202 		0,		/* lowest usable address */
203 		0xffffffffull,	/* highest usable address */
204 		0x7fffffff,	/* maximum DMAable byte count */
205 		4,		/* alignment */
206 		1,		/* burst sizes */
207 		1,		/* minimum transfer */
208 		0xffffffffull,	/* maximum transfer */
209 		0xffffffffull,	/* maximum segment length */
210 		1,		/* maximum number of segments */
211 		1,		/* granularity */
212 		0,		/* flags (reserved) */
213 };
214 
215 
216 static struct dev_ops   amr_ops = {
217 	DEVO_REV,	/* devo_rev, */
218 	0,		/* refcnt  */
219 	amr_info,	/* info */
220 	nulldev,	/* identify */
221 	nulldev,	/* probe */
222 	amr_attach,	/* attach */
223 	amr_detach,	/* detach */
224 	nodev,		/* reset */
225 	NULL,		/* driver operations */
226 	(struct bus_ops *)0,	/* bus operations */
227 	0		/* power */
228 };
229 
230 
231 extern struct mod_ops mod_driverops;
232 static struct modldrv modldrv = {
233 	&mod_driverops,		/* Type of module. driver here */
234 	"AMR Driver V%I%",	/* Name of the module. */
235 	&amr_ops,		/* Driver ops vector */
236 };
237 
238 static struct modlinkage modlinkage = {
239 	MODREV_1,
240 	&modldrv,
241 	NULL
242 };
243 
244 /* DMA access attributes */
245 static ddi_device_acc_attr_t accattr = {
246 	DDI_DEVICE_ATTR_V0,
247 	DDI_NEVERSWAP_ACC,
248 	DDI_STRICTORDER_ACC
249 };
250 
251 static struct amr_softs  *amr_softstatep;
252 
253 
254 int
255 _init(void)
256 {
257 	int		error;
258 
259 	error = ddi_soft_state_init((void *)&amr_softstatep,
260 			sizeof (struct amr_softs), 0);
261 
262 	if (error != 0)
263 		goto error_out;
264 
265 	if ((error = scsi_hba_init(&modlinkage)) != 0) {
266 		ddi_soft_state_fini((void*)&amr_softstatep);
267 		goto error_out;
268 	}
269 
270 	error = mod_install(&modlinkage);
271 	if (error != 0) {
272 		scsi_hba_fini(&modlinkage);
273 		ddi_soft_state_fini((void*)&amr_softstatep);
274 		goto error_out;
275 	}
276 
277 	return (error);
278 
279 error_out:
280 	cmn_err(CE_NOTE, "_init failed");
281 	return (error);
282 }
283 
284 int
285 _info(struct modinfo *modinfop)
286 {
287 	return (mod_info(&modlinkage, modinfop));
288 }
289 
290 int
291 _fini(void)
292 {
293 	int	error;
294 
295 	if ((error = mod_remove(&modlinkage)) != 0) {
296 		return (error);
297 	}
298 
299 	scsi_hba_fini(&modlinkage);
300 
301 	ddi_soft_state_fini((void*)&amr_softstatep);
302 	return (error);
303 }
304 
305 
306 static int
307 amr_attach(dev_info_t *dev, ddi_attach_cmd_t cmd)
308 {
309 	struct amr_softs	*softs;
310 	int			error;
311 	uint32_t		command, i;
312 	int			instance;
313 	caddr_t			cfgaddr;
314 
315 	instance = ddi_get_instance(dev);
316 
317 	switch (cmd) {
318 		case DDI_ATTACH:
319 			break;
320 
321 		case DDI_RESUME:
322 			return (DDI_FAILURE);
323 
324 		default:
325 			return (DDI_FAILURE);
326 	}
327 
328 	/*
329 	 * Initialize softs.
330 	 */
331 	if (ddi_soft_state_zalloc(amr_softstatep, instance) != DDI_SUCCESS)
332 		return (DDI_FAILURE);
333 	softs = ddi_get_soft_state(amr_softstatep, instance);
334 	softs->state |= AMR_STATE_SOFT_STATE_SETUP;
335 
336 	softs->dev_info_p = dev;
337 
338 	AMRDB_PRINT((CE_NOTE, "softs: %p; busy_slot addr: %p",
339 		(void *)softs, (void *)&(softs->amr_busyslots)));
340 
341 	if (pci_config_setup(dev, &(softs->pciconfig_handle))
342 		!= DDI_SUCCESS) {
343 		goto error_out;
344 	}
345 	softs->state |= AMR_STATE_PCI_CONFIG_SETUP;
346 
347 	error = ddi_regs_map_setup(dev, 1, &cfgaddr, 0, 0,
348 		&accattr, &(softs->regsmap_handle));
349 	if (error != DDI_SUCCESS) {
350 		goto error_out;
351 	}
352 	softs->state |= AMR_STATE_PCI_MEM_MAPPED;
353 
354 	/*
355 	 * Determine board type.
356 	 */
357 	command = pci_config_get16(softs->pciconfig_handle, PCI_CONF_COMM);
358 
359 	/*
360 	 * Make sure we are going to be able to talk to this board.
361 	 */
362 	if ((command & PCI_COMM_MAE) == 0) {
363 		AMRDB_PRINT((CE_NOTE,  "memory window not available"));
364 		goto error_out;
365 	}
366 
367 	/* force the busmaster enable bit on */
368 	if (!(command & PCI_COMM_ME)) {
369 		command |= PCI_COMM_ME;
370 		pci_config_put16(softs->pciconfig_handle,
371 				PCI_CONF_COMM, command);
372 		command = pci_config_get16(softs->pciconfig_handle,
373 				PCI_CONF_COMM);
374 		if (!(command & PCI_COMM_ME))
375 			goto error_out;
376 	}
377 
378 	/*
379 	 * Allocate and connect our interrupt.
380 	 */
381 	if (ddi_intr_hilevel(dev, 0) != 0) {
382 	    AMRDB_PRINT((CE_NOTE,  "High level interrupt is not supported!"));
383 	    goto error_out;
384 	}
385 
386 	if (ddi_get_iblock_cookie(dev, 0,  &softs->iblock_cookiep)
387 		!= DDI_SUCCESS) {
388 		goto error_out;
389 	}
390 
391 	mutex_init(&softs->cmd_mutex, NULL, MUTEX_DRIVER,
392 		softs->iblock_cookiep); /* should be used in interrupt */
393 	mutex_init(&softs->queue_mutex, NULL, MUTEX_DRIVER,
394 	    softs->iblock_cookiep); /* should be used in interrupt */
395 	mutex_init(&softs->periodic_mutex, NULL, MUTEX_DRIVER,
396 	    softs->iblock_cookiep); /* should be used in interrupt */
397 	/* sychronize waits for the busy slots via this cv */
398 	cv_init(&softs->cmd_cv, NULL, CV_DRIVER, NULL);
399 	softs->state |= AMR_STATE_KMUTEX_INITED;
400 
401 	/*
402 	 * Do bus-independent initialisation, bring controller online.
403 	 */
404 	if (amr_setup_mbox(softs) != DDI_SUCCESS)
405 		goto error_out;
406 	softs->state |= AMR_STATE_MAILBOX_SETUP;
407 
408 	if (amr_setup_sg(softs) != DDI_SUCCESS)
409 		goto error_out;
410 
411 	softs->state |= AMR_STATE_SG_TABLES_SETUP;
412 
413 	if (amr_query_controller(softs) != DDI_SUCCESS)
414 		goto error_out;
415 
416 	/*
417 	 * A taskq is created for dispatching the waiting queue processing
418 	 * thread. The threads number equals to the logic drive number and
419 	 * the thread number should be 1 if there is no logic driver is
420 	 * configured for this instance.
421 	 */
422 	if ((softs->amr_taskq = ddi_taskq_create(dev, "amr_taskq",
423 		MAX(softs->amr_nlogdrives, 1), TASKQ_DEFAULTPRI, 0)) == NULL) {
424 		goto error_out;
425 	}
426 	softs->state |= AMR_STATE_TASKQ_SETUP;
427 
428 	if (ddi_add_intr(dev, 0, &softs->iblock_cookiep, NULL,
429 		amr_intr, (caddr_t)softs) != DDI_SUCCESS) {
430 		goto error_out;
431 	}
432 	softs->state |= AMR_STATE_INTR_SETUP;
433 
434 	/* set up the tran interface */
435 	if (amr_setup_tran(softs->dev_info_p, softs) != DDI_SUCCESS) {
436 		AMRDB_PRINT((CE_NOTE, "setup tran failed"));
437 		goto error_out;
438 	}
439 	softs->state |= AMR_STATE_TRAN_SETUP;
440 
441 	/* schedule a thread for periodic check */
442 	mutex_enter(&softs->periodic_mutex);
443 	softs->timeout_t = timeout(amr_periodic, (void *)softs,
444 				drv_usectohz(500000*AMR_PERIODIC_TIMEOUT));
445 	softs->state |= AMR_STATE_TIMEOUT_ENABLED;
446 	mutex_exit(&softs->periodic_mutex);
447 
448 	/* print firmware information in verbose mode */
449 	cmn_err(CE_CONT, "?MegaRaid %s %s attached.",
450 		softs->amr_product_info.pi_product_name,
451 		softs->amr_product_info.pi_firmware_ver);
452 
453 	/* clear any interrupts */
454 	AMR_QCLEAR_INTR(softs);
455 	return (DDI_SUCCESS);
456 
457 error_out:
458 	if (softs->state & AMR_STATE_INTR_SETUP) {
459 		ddi_remove_intr(dev, 0, softs->iblock_cookiep);
460 	}
461 	if (softs->state & AMR_STATE_TASKQ_SETUP) {
462 		ddi_taskq_destroy(softs->amr_taskq);
463 	}
464 	if (softs->state & AMR_STATE_SG_TABLES_SETUP) {
465 		for (i = 0; i < softs->sg_max_count; i++) {
466 			(void) ddi_dma_unbind_handle(
467 				softs->sg_items[i].sg_handle);
468 			(void) ddi_dma_mem_free(
469 				&((softs->sg_items[i]).sg_acc_handle));
470 			(void) ddi_dma_free_handle(
471 				&(softs->sg_items[i].sg_handle));
472 		}
473 	}
474 	if (softs->state & AMR_STATE_MAILBOX_SETUP) {
475 		(void) ddi_dma_unbind_handle(softs->mbox_dma_handle);
476 		(void) ddi_dma_mem_free(&softs->mbox_acc_handle);
477 		(void) ddi_dma_free_handle(&softs->mbox_dma_handle);
478 	}
479 	if (softs->state & AMR_STATE_KMUTEX_INITED) {
480 		mutex_destroy(&softs->queue_mutex);
481 		mutex_destroy(&softs->cmd_mutex);
482 		mutex_destroy(&softs->periodic_mutex);
483 		cv_destroy(&softs->cmd_cv);
484 	}
485 	if (softs->state & AMR_STATE_PCI_MEM_MAPPED)
486 		ddi_regs_map_free(&softs->regsmap_handle);
487 	if (softs->state & AMR_STATE_PCI_CONFIG_SETUP)
488 		pci_config_teardown(&softs->pciconfig_handle);
489 	if (softs->state & AMR_STATE_SOFT_STATE_SETUP)
490 		ddi_soft_state_free(amr_softstatep, instance);
491 	return (DDI_FAILURE);
492 }
493 
494 /*
495  * Bring the controller down to a dormant state and detach all child devices.
496  * This function is called during detach, system shutdown.
497  *
498  * Note that we can assume that the bufq on the controller is empty, as we won't
499  * allow shutdown if any device is open.
500  */
501 /*ARGSUSED*/
502 static int amr_detach(dev_info_t *dev, ddi_detach_cmd_t cmd)
503 {
504 	struct amr_softs	*softs;
505 	int			instance;
506 	uint32_t		i, done_flag;
507 
508 	instance = ddi_get_instance(dev);
509 	softs = ddi_get_soft_state(amr_softstatep, instance);
510 
511 	/* flush the controllor */
512 	if (amr_flush(softs) != 0) {
513 		AMRDB_PRINT((CE_NOTE, "device shutdown failed"));
514 		return (EIO);
515 	}
516 
517 	/* release the amr timer */
518 	mutex_enter(&softs->periodic_mutex);
519 	softs->state &= ~AMR_STATE_TIMEOUT_ENABLED;
520 	if (softs->timeout_t) {
521 		(void) untimeout(softs->timeout_t);
522 		softs->timeout_t = 0;
523 	}
524 	mutex_exit(&softs->periodic_mutex);
525 
526 	for (i = 0; i < softs->sg_max_count; i++) {
527 		(void) ddi_dma_unbind_handle(
528 			softs->sg_items[i].sg_handle);
529 		(void) ddi_dma_mem_free(
530 			&((softs->sg_items[i]).sg_acc_handle));
531 		(void) ddi_dma_free_handle(
532 			&(softs->sg_items[i].sg_handle));
533 	}
534 
535 	(void) ddi_dma_unbind_handle(softs->mbox_dma_handle);
536 	(void) ddi_dma_mem_free(&softs->mbox_acc_handle);
537 	(void) ddi_dma_free_handle(&softs->mbox_dma_handle);
538 
539 	/* disconnect the interrupt handler */
540 	ddi_remove_intr(softs->dev_info_p,  0, softs->iblock_cookiep);
541 
542 	/* wait for the completion of current in-progress interruptes */
543 	AMR_DELAY((softs->amr_interrupts_counter == 0), 1000, done_flag);
544 	if (!done_flag) {
545 		cmn_err(CE_WARN, "Suspicious interrupts in-progress.");
546 	}
547 
548 	ddi_taskq_destroy(softs->amr_taskq);
549 
550 	(void) scsi_hba_detach(dev);
551 	scsi_hba_tran_free(softs->hba_tran);
552 	ddi_regs_map_free(&softs->regsmap_handle);
553 	pci_config_teardown(&softs->pciconfig_handle);
554 
555 	mutex_destroy(&softs->queue_mutex);
556 	mutex_destroy(&softs->cmd_mutex);
557 	mutex_destroy(&softs->periodic_mutex);
558 	cv_destroy(&softs->cmd_cv);
559 
560 	/* print firmware information in verbose mode */
561 	cmn_err(CE_NOTE, "?MegaRaid %s %s detached.",
562 		softs->amr_product_info.pi_product_name,
563 		softs->amr_product_info.pi_firmware_ver);
564 
565 	ddi_soft_state_free(amr_softstatep, instance);
566 
567 	return (DDI_SUCCESS);
568 }
569 
570 
571 /*ARGSUSED*/
572 static int amr_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
573 	void *arg, void **result)
574 {
575 	struct amr_softs	*softs;
576 	int			instance;
577 
578 	instance = ddi_get_instance(dip);
579 
580 	switch (infocmd) {
581 		case DDI_INFO_DEVT2DEVINFO:
582 			softs = ddi_get_soft_state(amr_softstatep, instance);
583 			if (softs != NULL) {
584 				*result = softs->dev_info_p;
585 				return (DDI_SUCCESS);
586 			} else {
587 				*result = NULL;
588 				return (DDI_FAILURE);
589 			}
590 		case DDI_INFO_DEVT2INSTANCE:
591 			*(int *)result = instance;
592 			break;
593 		default:
594 			break;
595 	}
596 	return (DDI_SUCCESS);
597 }
598 
599 /*
600  * Take an interrupt, or be poked by other code to look for interrupt-worthy
601  * status.
602  */
603 static uint_t
604 amr_intr(caddr_t arg)
605 {
606 	struct amr_softs *softs = (struct amr_softs *)arg;
607 
608 	softs->amr_interrupts_counter++;
609 
610 	if (AMR_QGET_ODB(softs) != AMR_QODB_READY) {
611 		softs->amr_interrupts_counter--;
612 		return (DDI_INTR_UNCLAIMED);
613 	}
614 
615 	/* collect finished commands, queue anything waiting */
616 	amr_done(softs);
617 
618 	softs->amr_interrupts_counter--;
619 
620 	return (DDI_INTR_CLAIMED);
621 
622 }
623 
624 /*
625  * Setup the amr mailbox
626  */
627 static int
628 amr_setup_mbox(struct amr_softs *softs)
629 {
630 	uint32_t	move;
631 	size_t		mbox_len;
632 
633 	if (ddi_dma_alloc_handle(
634 		softs->dev_info_p,
635 		&addr_dma_attr,
636 		DDI_DMA_SLEEP,
637 		NULL,
638 		&softs->mbox_dma_handle) != DDI_SUCCESS) {
639 		AMRDB_PRINT((CE_NOTE, "Cannot alloc dma handle for mailbox"));
640 		goto error_out;
641 	}
642 
643 	if (ddi_dma_mem_alloc(
644 		softs->mbox_dma_handle,
645 		sizeof (struct amr_mailbox) + 16,
646 		&accattr,
647 		DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
648 		DDI_DMA_SLEEP,
649 		NULL,
650 		(caddr_t *)(&softs->mbox),
651 		&mbox_len,
652 		&softs->mbox_acc_handle) !=
653 		DDI_SUCCESS) {
654 
655 		AMRDB_PRINT((CE_WARN, "Cannot alloc dma memory for mailbox"));
656 		goto error_out;
657 	}
658 
659 	if (ddi_dma_addr_bind_handle(
660 		softs->mbox_dma_handle,
661 		NULL,
662 		(caddr_t)softs->mbox,
663 		mbox_len,
664 		DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
665 		DDI_DMA_SLEEP,
666 		NULL,
667 		&softs->mbox_dma_cookie,
668 		&softs->mbox_dma_cookien) != DDI_DMA_MAPPED) {
669 
670 		AMRDB_PRINT((CE_NOTE, "Cannot bind dma memory for mailbox"));
671 		goto error_out;
672 	}
673 
674 	if (softs->mbox_dma_cookien != 1)
675 		goto error_out;
676 
677 	/* The phy address of mailbox must be aligned on a 16-byte boundary */
678 	move = 16 - (((uint32_t)softs->mbox_dma_cookie.dmac_address)&0xf);
679 	softs->mbox_phyaddr =
680 		(softs->mbox_dma_cookie.dmac_address + move);
681 
682 	softs->mailbox =
683 		(struct amr_mailbox *)(((uintptr_t)softs->mbox) + move);
684 
685 	AMRDB_PRINT((CE_NOTE, "phraddy=%x, mailbox=%p, softs->mbox=%p, move=%x",
686 		softs->mbox_phyaddr, (void *)softs->mailbox,
687 		softs->mbox, move));
688 
689 	return (DDI_SUCCESS);
690 
691 error_out:
692 	if (softs->mbox_dma_cookien)
693 		(void) ddi_dma_unbind_handle(softs->mbox_dma_handle);
694 	if (softs->mbox_acc_handle) {
695 		(void) ddi_dma_mem_free(&(softs->mbox_acc_handle));
696 		softs->mbox_acc_handle = NULL;
697 	}
698 	if (softs->mbox_dma_handle) {
699 		(void) ddi_dma_free_handle(&softs->mbox_dma_handle);
700 		softs->mbox_dma_handle = NULL;
701 	}
702 
703 	return (DDI_FAILURE);
704 }
705 
706 /*
707  * Perform a periodic check of the controller status
708  */
709 static void
710 amr_periodic(void *data)
711 {
712 	uint32_t		i;
713 	struct amr_softs	*softs = (struct amr_softs *)data;
714 	struct scsi_pkt 	*pkt;
715 	register struct amr_command	*ac;
716 
717 	for (i = 0; i < softs->sg_max_count; i++) {
718 		if (softs->busycmd[i] == NULL)
719 			continue;
720 
721 		mutex_enter(&softs->cmd_mutex);
722 
723 		if (softs->busycmd[i] == NULL) {
724 			mutex_exit(&softs->cmd_mutex);
725 			continue;
726 		}
727 
728 		pkt = softs->busycmd[i]->pkt;
729 
730 		if ((pkt->pkt_time != 0) &&
731 			(ddi_get_time() -
732 			softs->busycmd[i]->ac_timestamp >
733 			pkt->pkt_time)) {
734 
735 			cmn_err(CE_WARN,
736 				"!timed out packet detected,\
737 				sc = %p, pkt = %p, index = %d, ac = %p",
738 				(void *)softs,
739 				(void *)pkt,
740 				i,
741 				(void *)softs->busycmd[i]);
742 
743 			ac = softs->busycmd[i];
744 			ac->ac_next = NULL;
745 
746 			/* pull command from the busy index */
747 			softs->busycmd[i] = NULL;
748 			if (softs->amr_busyslots > 0)
749 				softs->amr_busyslots--;
750 			if (softs->amr_busyslots == 0)
751 				cv_broadcast(&softs->cmd_cv);
752 
753 			mutex_exit(&softs->cmd_mutex);
754 
755 			pkt = ac->pkt;
756 			*pkt->pkt_scbp = 0;
757 			pkt->pkt_statistics |= STAT_TIMEOUT;
758 			pkt->pkt_reason = CMD_TIMEOUT;
759 			if (!(pkt->pkt_flags &
760 			FLAG_NOINTR) && pkt->pkt_comp) {
761 				/* call pkt callback */
762 				(*pkt->pkt_comp)(pkt);
763 			}
764 
765 		} else {
766 			mutex_exit(&softs->cmd_mutex);
767 		}
768 	}
769 
770 	/* restart the amr timer */
771 	mutex_enter(&softs->periodic_mutex);
772 	if (softs->state & AMR_STATE_TIMEOUT_ENABLED)
773 		softs->timeout_t = timeout(amr_periodic, (void *)softs,
774 				drv_usectohz(500000*AMR_PERIODIC_TIMEOUT));
775 	mutex_exit(&softs->periodic_mutex);
776 }
777 
778 /*
779  * Interrogate the controller for the operational parameters we require.
780  */
781 static int
782 amr_query_controller(struct amr_softs *softs)
783 {
784 	struct amr_enquiry3	*aex;
785 	struct amr_prodinfo	*ap;
786 	struct amr_enquiry	*ae;
787 	uint32_t		ldrv;
788 	int			instance;
789 
790 	/*
791 	 * If we haven't found the real limit yet, let us have a couple of
792 	 * commands in order to be able to probe.
793 	 */
794 	if (softs->maxio == 0)
795 		softs->maxio = 2;
796 
797 	instance = ddi_get_instance(softs->dev_info_p);
798 
799 	/*
800 	 * Try to issue an ENQUIRY3 command
801 	 */
802 	if ((aex = amr_enquiry(softs, AMR_ENQ_BUFFER_SIZE, AMR_CMD_CONFIG,
803 		AMR_CONFIG_ENQ3, AMR_CONFIG_ENQ3_SOLICITED_FULL)) != NULL) {
804 
805 		AMRDB_PRINT((CE_NOTE, "First enquiry"));
806 
807 		for (ldrv = 0; ldrv < aex->ae_numldrives; ldrv++) {
808 		    softs->logic_drive[ldrv].al_size =
809 						aex->ae_drivesize[ldrv];
810 		    softs->logic_drive[ldrv].al_state =
811 						aex->ae_drivestate[ldrv];
812 		    softs->logic_drive[ldrv].al_properties =
813 						aex->ae_driveprop[ldrv];
814 		    AMRDB_PRINT((CE_NOTE,
815 			"  drive %d: size: %d state %x properties %x\n",
816 			ldrv,
817 			softs->logic_drive[ldrv].al_size,
818 			softs->logic_drive[ldrv].al_state,
819 			softs->logic_drive[ldrv].al_properties));
820 
821 		    if (softs->logic_drive[ldrv].al_state == AMR_LDRV_OFFLINE)
822 			cmn_err(CE_NOTE, "!instance %d log-drive %d is offline",
823 				instance, ldrv);
824 		    else
825 			softs->amr_nlogdrives++;
826 		}
827 		kmem_free(aex, AMR_ENQ_BUFFER_SIZE);
828 
829 		if ((ap = amr_enquiry(softs, AMR_ENQ_BUFFER_SIZE,
830 			AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) == NULL) {
831 			AMRDB_PRINT((CE_NOTE,
832 				"Cannot obtain product data from controller"));
833 			return (EIO);
834 		}
835 
836 		softs->maxdrives = AMR_40LD_MAXDRIVES;
837 		softs->maxchan = ap->ap_nschan;
838 		softs->maxio = ap->ap_maxio;
839 
840 		bcopy(ap->ap_firmware, softs->amr_product_info.pi_firmware_ver,
841 			AMR_FIRMWARE_VER_SIZE);
842 		softs->amr_product_info.
843 			pi_firmware_ver[AMR_FIRMWARE_VER_SIZE] = 0;
844 
845 		bcopy(ap->ap_product, softs->amr_product_info.pi_product_name,
846 			AMR_PRODUCT_INFO_SIZE);
847 		softs->amr_product_info.
848 			pi_product_name[AMR_PRODUCT_INFO_SIZE] = 0;
849 
850 		kmem_free(ap, AMR_ENQ_BUFFER_SIZE);
851 		AMRDB_PRINT((CE_NOTE, "maxio=%d", softs->maxio));
852 	} else {
853 
854 		AMRDB_PRINT((CE_NOTE, "First enquiry failed, \
855 				so try another way"));
856 
857 		/* failed, try the 8LD ENQUIRY commands */
858 		if ((ae = (struct amr_enquiry *)amr_enquiry(softs,
859 			AMR_ENQ_BUFFER_SIZE, AMR_CMD_EXT_ENQUIRY2, 0, 0))
860 			== NULL) {
861 
862 			if ((ae = (struct amr_enquiry *)amr_enquiry(softs,
863 				AMR_ENQ_BUFFER_SIZE, AMR_CMD_ENQUIRY, 0, 0))
864 				== NULL) {
865 				AMRDB_PRINT((CE_NOTE,
866 					"Cannot obtain configuration data"));
867 				return (EIO);
868 			}
869 			ae->ae_signature = 0;
870 		}
871 
872 		/*
873 		 * Fetch current state of logical drives.
874 		 */
875 		for (ldrv = 0; ldrv < ae->ae_ldrv.al_numdrives; ldrv++) {
876 		    softs->logic_drive[ldrv].al_size =
877 						ae->ae_ldrv.al_size[ldrv];
878 		    softs->logic_drive[ldrv].al_state =
879 						ae->ae_ldrv.al_state[ldrv];
880 		    softs->logic_drive[ldrv].al_properties =
881 						ae->ae_ldrv.al_properties[ldrv];
882 		    AMRDB_PRINT((CE_NOTE,
883 			" ********* drive %d: %d state %x properties %x",
884 			ldrv,
885 			softs->logic_drive[ldrv].al_size,
886 			softs->logic_drive[ldrv].al_state,
887 			softs->logic_drive[ldrv].al_properties));
888 
889 		    if (softs->logic_drive[ldrv].al_state == AMR_LDRV_OFFLINE)
890 			cmn_err(CE_NOTE, "!instance %d log-drive %d is offline",
891 				instance, ldrv);
892 		    else
893 			softs->amr_nlogdrives++;
894 		}
895 
896 		softs->maxdrives = AMR_8LD_MAXDRIVES;
897 		softs->maxchan = ae->ae_adapter.aa_channels;
898 		softs->maxio = ae->ae_adapter.aa_maxio;
899 		kmem_free(ae, AMR_ENQ_BUFFER_SIZE);
900 	}
901 
902 	/*
903 	 * Mark remaining drives as unused.
904 	 */
905 	for (; ldrv < AMR_MAXLD; ldrv++)
906 		softs->logic_drive[ldrv].al_state = AMR_LDRV_OFFLINE;
907 
908 	/*
909 	 * Cap the maximum number of outstanding I/Os.  AMI's driver
910 	 * doesn't trust the controller's reported value, and lockups have
911 	 * been seen when we do.
912 	 */
913 	softs->maxio = MIN(softs->maxio, AMR_LIMITCMD);
914 
915 	return (DDI_SUCCESS);
916 }
917 
918 /*
919  * Run a generic enquiry-style command.
920  */
921 static void *
922 amr_enquiry(struct amr_softs *softs, size_t bufsize, uint8_t cmd,
923 				uint8_t cmdsub, uint8_t cmdqual)
924 {
925 	struct amr_command	ac;
926 	void			*result;
927 
928 	result = NULL;
929 
930 	bzero(&ac, sizeof (struct amr_command));
931 	ac.ac_softs = softs;
932 
933 	/* set command flags */
934 	ac.ac_flags |= AMR_CMD_DATAOUT;
935 
936 	/* build the command proper */
937 	ac.mailbox.mb_command	= cmd;
938 	ac.mailbox.mb_cmdsub	= cmdsub;
939 	ac.mailbox.mb_cmdqual	= cmdqual;
940 
941 	if (amr_enquiry_mapcmd(&ac, bufsize) != DDI_SUCCESS)
942 		return (NULL);
943 
944 	if (amr_poll_command(&ac) || ac.ac_status != 0) {
945 		AMRDB_PRINT((CE_NOTE, "can not poll command, goto out"));
946 		amr_enquiry_unmapcmd(&ac);
947 		return (NULL);
948 	}
949 
950 	/* allocate the response structure */
951 	result = kmem_zalloc(bufsize, KM_SLEEP);
952 
953 	bcopy(ac.ac_data, result, bufsize);
954 
955 	amr_enquiry_unmapcmd(&ac);
956 	return (result);
957 }
958 
959 /*
960  * Flush the controller's internal cache, return status.
961  */
962 static int
963 amr_flush(struct amr_softs *softs)
964 {
965 	struct amr_command	ac;
966 	int			error = 0;
967 
968 	bzero(&ac, sizeof (struct amr_command));
969 	ac.ac_softs = softs;
970 
971 	ac.ac_flags |= AMR_CMD_DATAOUT;
972 
973 	/* build the command proper */
974 	ac.mailbox.mb_command = AMR_CMD_FLUSH;
975 
976 	/* have to poll, as the system may be going down or otherwise damaged */
977 	if (error = amr_poll_command(&ac)) {
978 		AMRDB_PRINT((CE_NOTE, "can not poll this cmd"));
979 		return (error);
980 	}
981 
982 	return (error);
983 }
984 
985 /*
986  * Take a command, submit it to the controller and wait for it to return.
987  * Returns nonzero on error.  Can be safely called with interrupts enabled.
988  */
989 static int
990 amr_poll_command(struct amr_command *ac)
991 {
992 	struct amr_softs	*softs = ac->ac_softs;
993 	volatile uint32_t	done_flag;
994 
995 	AMRDB_PRINT((CE_NOTE, "Amr_Poll bcopy(%p, %p, %d)",
996 			(void *)&ac->mailbox,
997 			(void *)softs->mailbox,
998 			(uint32_t)AMR_MBOX_CMDSIZE));
999 
1000 	mutex_enter(&softs->cmd_mutex);
1001 
1002 	while (softs->amr_busyslots != 0)
1003 		cv_wait(&softs->cmd_cv, &softs->cmd_mutex);
1004 
1005 	/*
1006 	 * For read/write commands, the scatter/gather table should be
1007 	 * filled, and the last entry in scatter/gather table will be used.
1008 	 */
1009 	if ((ac->mailbox.mb_command == AMR_CMD_LREAD) ||
1010 	    (ac->mailbox.mb_command == AMR_CMD_LWRITE)) {
1011 		bcopy(ac->sgtable,
1012 			softs->sg_items[softs->sg_max_count - 1].sg_table,
1013 			sizeof (struct amr_sgentry) * AMR_NSEG);
1014 
1015 		(void) ddi_dma_sync(
1016 			softs->sg_items[softs->sg_max_count - 1].sg_handle,
1017 			0, 0, DDI_DMA_SYNC_FORDEV);
1018 
1019 		ac->mailbox.mb_physaddr =
1020 			softs->sg_items[softs->sg_max_count - 1].sg_phyaddr;
1021 	}
1022 
1023 	bcopy(&ac->mailbox, (void *)softs->mailbox, AMR_MBOX_CMDSIZE);
1024 
1025 	/* sync the dma memory */
1026 	(void) ddi_dma_sync(softs->mbox_dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV);
1027 
1028 	/* clear the poll/ack fields in the mailbox */
1029 	softs->mailbox->mb_ident = AMR_POLL_COMMAND_ID;
1030 	softs->mailbox->mb_nstatus = AMR_POLL_DEFAULT_NSTATUS;
1031 	softs->mailbox->mb_status = AMR_POLL_DEFAULT_STATUS;
1032 	softs->mailbox->mb_poll = 0;
1033 	softs->mailbox->mb_ack = 0;
1034 	softs->mailbox->mb_busy = 1;
1035 
1036 	AMR_QPUT_IDB(softs, softs->mbox_phyaddr | AMR_QIDB_SUBMIT);
1037 
1038 	/* sync the dma memory */
1039 	(void) ddi_dma_sync(softs->mbox_dma_handle, 0, 0, DDI_DMA_SYNC_FORCPU);
1040 
1041 	AMR_DELAY((softs->mailbox->mb_nstatus != AMR_POLL_DEFAULT_NSTATUS),
1042 			1000, done_flag);
1043 	if (!done_flag) {
1044 		mutex_exit(&softs->cmd_mutex);
1045 		return (1);
1046 	}
1047 
1048 	ac->ac_status = softs->mailbox->mb_status;
1049 
1050 	AMR_DELAY((softs->mailbox->mb_poll == AMR_POLL_ACK), 1000, done_flag);
1051 	if (!done_flag) {
1052 		mutex_exit(&softs->cmd_mutex);
1053 		return (1);
1054 	}
1055 
1056 	softs->mailbox->mb_poll = 0;
1057 	softs->mailbox->mb_ack = AMR_POLL_ACK;
1058 
1059 	/* acknowledge that we have the commands */
1060 	AMR_QPUT_IDB(softs, softs->mbox_phyaddr | AMR_QIDB_ACK);
1061 
1062 	AMR_DELAY(!(AMR_QGET_IDB(softs) & AMR_QIDB_ACK), 1000, done_flag);
1063 	if (!done_flag) {
1064 		mutex_exit(&softs->cmd_mutex);
1065 		return (1);
1066 	}
1067 
1068 	mutex_exit(&softs->cmd_mutex);
1069 	return (ac->ac_status != AMR_STATUS_SUCCESS);
1070 }
1071 
1072 /*
1073  * setup the scatter/gather table
1074  */
1075 static int
1076 amr_setup_sg(struct amr_softs *softs)
1077 {
1078 	uint32_t		i;
1079 	size_t			len;
1080 	ddi_dma_cookie_t	cookie;
1081 	uint_t			cookien;
1082 
1083 	softs->sg_max_count = 0;
1084 
1085 	for (i = 0; i < AMR_MAXCMD; i++) {
1086 
1087 		/* reset the cookien */
1088 		cookien = 0;
1089 
1090 		(softs->sg_items[i]).sg_handle = NULL;
1091 		if (ddi_dma_alloc_handle(
1092 			softs->dev_info_p,
1093 			&addr_dma_attr,
1094 			DDI_DMA_SLEEP,
1095 			NULL,
1096 			&((softs->sg_items[i]).sg_handle)) != DDI_SUCCESS) {
1097 
1098 			AMRDB_PRINT((CE_WARN,
1099 			"Cannot alloc dma handle for s/g table"));
1100 			goto error_out;
1101 		}
1102 
1103 		if (ddi_dma_mem_alloc((softs->sg_items[i]).sg_handle,
1104 			sizeof (struct amr_sgentry) * AMR_NSEG,
1105 			&accattr,
1106 			DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1107 			DDI_DMA_SLEEP, NULL,
1108 			(caddr_t *)(&(softs->sg_items[i]).sg_table),
1109 			&len,
1110 			&(softs->sg_items[i]).sg_acc_handle)
1111 			!= DDI_SUCCESS) {
1112 
1113 			AMRDB_PRINT((CE_WARN,
1114 			"Cannot allocate DMA memory"));
1115 			goto error_out;
1116 		}
1117 
1118 		if (ddi_dma_addr_bind_handle(
1119 			(softs->sg_items[i]).sg_handle,
1120 			NULL,
1121 			(caddr_t)((softs->sg_items[i]).sg_table),
1122 			len,
1123 			DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1124 			DDI_DMA_SLEEP,
1125 			NULL,
1126 			&cookie,
1127 			&cookien) != DDI_DMA_MAPPED) {
1128 
1129 			AMRDB_PRINT((CE_WARN,
1130 			"Cannot bind communication area for s/g table"));
1131 			goto error_out;
1132 		}
1133 
1134 		if (cookien != 1)
1135 			goto error_out;
1136 
1137 		softs->sg_items[i].sg_phyaddr = cookie.dmac_address;
1138 		softs->sg_max_count++;
1139 	}
1140 
1141 	return (DDI_SUCCESS);
1142 
1143 error_out:
1144 	/*
1145 	 * Couldn't allocate/initialize all of the sg table entries.
1146 	 * Clean up the partially-initialized entry before returning.
1147 	 */
1148 	if (cookien) {
1149 		(void) ddi_dma_unbind_handle((softs->sg_items[i]).sg_handle);
1150 	}
1151 	if ((softs->sg_items[i]).sg_acc_handle) {
1152 		(void) ddi_dma_mem_free(&((softs->sg_items[i]).sg_acc_handle));
1153 		(softs->sg_items[i]).sg_acc_handle = NULL;
1154 	}
1155 	if ((softs->sg_items[i]).sg_handle) {
1156 		(void) ddi_dma_free_handle(&((softs->sg_items[i]).sg_handle));
1157 		(softs->sg_items[i]).sg_handle = NULL;
1158 	}
1159 
1160 	/*
1161 	 * At least two sg table entries are needed. One is for regular data
1162 	 * I/O commands, the other is for poll I/O commands.
1163 	 */
1164 	return (softs->sg_max_count > 1 ? DDI_SUCCESS : DDI_FAILURE);
1165 }
1166 
1167 /*
1168  * Map/unmap (ac)'s data in the controller's addressable space as required.
1169  *
1170  * These functions may be safely called multiple times on a given command.
1171  */
1172 static void
1173 amr_setup_dmamap(struct amr_command *ac, ddi_dma_cookie_t *buffer_dma_cookiep,
1174 		int nsegments)
1175 {
1176 	struct amr_sgentry	*sg;
1177 	uint32_t		i, size;
1178 
1179 	sg = ac->sgtable;
1180 
1181 	size = 0;
1182 
1183 	ac->mailbox.mb_nsgelem = (uint8_t)nsegments;
1184 	for (i = 0; i < nsegments; i++, sg++) {
1185 		sg->sg_addr = buffer_dma_cookiep->dmac_address;
1186 		sg->sg_count = buffer_dma_cookiep->dmac_size;
1187 		size += sg->sg_count;
1188 
1189 		/*
1190 		 * There is no next cookie if the end of the current
1191 		 * window is reached. Otherwise, the next cookie
1192 		 * would be found.
1193 		 */
1194 		if ((ac->current_cookie + i + 1) != ac->num_of_cookie)
1195 			ddi_dma_nextcookie(ac->buffer_dma_handle,
1196 				buffer_dma_cookiep);
1197 	}
1198 
1199 	ac->transfer_size = size;
1200 	ac->data_transfered += size;
1201 }
1202 
1203 
1204 /*
1205  * map the amr command for enquiry, allocate the DMA resource
1206  */
1207 static int
1208 amr_enquiry_mapcmd(struct amr_command *ac, uint32_t data_size)
1209 {
1210 	struct amr_softs	*softs = ac->ac_softs;
1211 	size_t			len;
1212 	uint_t			dma_flags;
1213 
1214 	AMRDB_PRINT((CE_NOTE, "Amr_enquiry_mapcmd called, ac=%p, flags=%x",
1215 			(void *)ac, ac->ac_flags));
1216 
1217 	if (ac->ac_flags & AMR_CMD_DATAOUT) {
1218 		dma_flags = DDI_DMA_READ;
1219 	} else {
1220 		dma_flags = DDI_DMA_WRITE;
1221 	}
1222 
1223 	dma_flags |= DDI_DMA_CONSISTENT;
1224 
1225 	/* process the DMA by address bind mode */
1226 	if (ddi_dma_alloc_handle(softs->dev_info_p,
1227 		&addr_dma_attr, DDI_DMA_SLEEP, NULL,
1228 		&ac->buffer_dma_handle) !=
1229 		DDI_SUCCESS) {
1230 
1231 		AMRDB_PRINT((CE_WARN,
1232 		"Cannot allocate addr DMA tag"));
1233 		goto error_out;
1234 	}
1235 
1236 	if (ddi_dma_mem_alloc(ac->buffer_dma_handle,
1237 		data_size,
1238 		&accattr,
1239 		dma_flags,
1240 		DDI_DMA_SLEEP,
1241 		NULL,
1242 		(caddr_t *)&ac->ac_data,
1243 		&len,
1244 		&ac->buffer_acc_handle) !=
1245 		DDI_SUCCESS) {
1246 
1247 		AMRDB_PRINT((CE_WARN,
1248 		"Cannot allocate DMA memory"));
1249 		goto error_out;
1250 	}
1251 
1252 	if ((ddi_dma_addr_bind_handle(
1253 		ac->buffer_dma_handle,
1254 		NULL, ac->ac_data, len, dma_flags,
1255 		DDI_DMA_SLEEP, NULL, &ac->buffer_dma_cookie,
1256 		&ac->num_of_cookie)) != DDI_DMA_MAPPED) {
1257 
1258 		AMRDB_PRINT((CE_WARN,
1259 			"Cannot bind addr for dma"));
1260 		goto error_out;
1261 	}
1262 
1263 	ac->ac_dataphys = (&ac->buffer_dma_cookie)->dmac_address;
1264 
1265 	((struct amr_mailbox *)&(ac->mailbox))->mb_param = 0;
1266 	ac->mailbox.mb_nsgelem = 0;
1267 	ac->mailbox.mb_physaddr = ac->ac_dataphys;
1268 
1269 	ac->ac_flags |= AMR_CMD_MAPPED;
1270 
1271 	return (DDI_SUCCESS);
1272 
1273 error_out:
1274 	if (ac->num_of_cookie)
1275 		(void) ddi_dma_unbind_handle(ac->buffer_dma_handle);
1276 	if (ac->buffer_acc_handle) {
1277 		ddi_dma_mem_free(&ac->buffer_acc_handle);
1278 		ac->buffer_acc_handle = NULL;
1279 	}
1280 	if (ac->buffer_dma_handle) {
1281 		(void) ddi_dma_free_handle(&ac->buffer_dma_handle);
1282 		ac->buffer_dma_handle = NULL;
1283 	}
1284 
1285 	return (DDI_FAILURE);
1286 }
1287 
1288 /*
1289  * unmap the amr command for enquiry, free the DMA resource
1290  */
1291 static void
1292 amr_enquiry_unmapcmd(struct amr_command *ac)
1293 {
1294 	AMRDB_PRINT((CE_NOTE, "Amr_enquiry_unmapcmd called, ac=%p",
1295 			(void *)ac));
1296 
1297 	/* if the command involved data at all and was mapped */
1298 	if ((ac->ac_flags & AMR_CMD_MAPPED) && ac->ac_data) {
1299 		if (ac->buffer_dma_handle)
1300 			(void) ddi_dma_unbind_handle(
1301 				ac->buffer_dma_handle);
1302 		if (ac->buffer_acc_handle) {
1303 			ddi_dma_mem_free(&ac->buffer_acc_handle);
1304 			ac->buffer_acc_handle = NULL;
1305 		}
1306 		if (ac->buffer_dma_handle) {
1307 			(void) ddi_dma_free_handle(
1308 				&ac->buffer_dma_handle);
1309 			ac->buffer_dma_handle = NULL;
1310 		}
1311 	}
1312 
1313 	ac->ac_flags &= ~AMR_CMD_MAPPED;
1314 }
1315 
1316 /*
1317  * map the amr command, allocate the DMA resource
1318  */
1319 static int
1320 amr_mapcmd(struct amr_command *ac, int (*callback)(), caddr_t arg)
1321 {
1322 	uint_t	dma_flags;
1323 	off_t	off;
1324 	size_t	len;
1325 	int	error;
1326 	int	(*cb)(caddr_t);
1327 
1328 	AMRDB_PRINT((CE_NOTE, "Amr_mapcmd called, ac=%p, flags=%x",
1329 			(void *)ac, ac->ac_flags));
1330 
1331 	if (ac->ac_flags & AMR_CMD_DATAOUT) {
1332 		dma_flags = DDI_DMA_READ;
1333 	} else {
1334 		dma_flags = DDI_DMA_WRITE;
1335 	}
1336 
1337 	if (ac->ac_flags & AMR_CMD_PKT_CONSISTENT) {
1338 		dma_flags |= DDI_DMA_CONSISTENT;
1339 	}
1340 	if (ac->ac_flags & AMR_CMD_PKT_DMA_PARTIAL) {
1341 		dma_flags |= DDI_DMA_PARTIAL;
1342 	}
1343 
1344 	if ((!(ac->ac_flags & AMR_CMD_MAPPED)) && (ac->ac_buf == NULL)) {
1345 		ac->ac_flags |= AMR_CMD_MAPPED;
1346 		return (DDI_SUCCESS);
1347 	}
1348 
1349 	cb = (callback == NULL_FUNC) ? DDI_DMA_DONTWAIT : DDI_DMA_SLEEP;
1350 
1351 	/* if the command involves data at all, and hasn't been mapped */
1352 	if (!(ac->ac_flags & AMR_CMD_MAPPED)) {
1353 		/* process the DMA by buffer bind mode */
1354 		error = ddi_dma_buf_bind_handle(ac->buffer_dma_handle,
1355 			ac->ac_buf,
1356 			dma_flags,
1357 			cb,
1358 			arg,
1359 			&ac->buffer_dma_cookie,
1360 			&ac->num_of_cookie);
1361 		switch (error) {
1362 		case DDI_DMA_PARTIAL_MAP:
1363 			if (ddi_dma_numwin(ac->buffer_dma_handle,
1364 				&ac->num_of_win) == DDI_FAILURE) {
1365 
1366 				AMRDB_PRINT((CE_WARN,
1367 					"Cannot get dma num win"));
1368 				(void) ddi_dma_unbind_handle(
1369 					ac->buffer_dma_handle);
1370 				(void) ddi_dma_free_handle(
1371 					&ac->buffer_dma_handle);
1372 				ac->buffer_dma_handle = NULL;
1373 				return (DDI_FAILURE);
1374 			}
1375 			ac->current_win = 0;
1376 			break;
1377 
1378 		case DDI_DMA_MAPPED:
1379 			ac->num_of_win = 1;
1380 			ac->current_win = 0;
1381 			break;
1382 
1383 		default:
1384 			AMRDB_PRINT((CE_WARN,
1385 				"Cannot bind buf for dma"));
1386 
1387 			(void) ddi_dma_free_handle(
1388 				&ac->buffer_dma_handle);
1389 			ac->buffer_dma_handle = NULL;
1390 			return (DDI_FAILURE);
1391 		}
1392 
1393 		ac->current_cookie = 0;
1394 
1395 		ac->ac_flags |= AMR_CMD_MAPPED;
1396 	} else if (ac->current_cookie == AMR_LAST_COOKIE_TAG) {
1397 		/* get the next window */
1398 		ac->current_win++;
1399 		(void) ddi_dma_getwin(ac->buffer_dma_handle,
1400 			ac->current_win, &off, &len,
1401 			&ac->buffer_dma_cookie,
1402 			&ac->num_of_cookie);
1403 		ac->current_cookie = 0;
1404 	}
1405 
1406 	if ((ac->num_of_cookie - ac->current_cookie) > AMR_NSEG) {
1407 		amr_setup_dmamap(ac, &ac->buffer_dma_cookie, AMR_NSEG);
1408 		ac->current_cookie += AMR_NSEG;
1409 	} else {
1410 		amr_setup_dmamap(ac, &ac->buffer_dma_cookie,
1411 		ac->num_of_cookie - ac->current_cookie);
1412 		ac->current_cookie = AMR_LAST_COOKIE_TAG;
1413 	}
1414 
1415 	return (DDI_SUCCESS);
1416 }
1417 
1418 /*
1419  * unmap the amr command, free the DMA resource
1420  */
1421 static void
1422 amr_unmapcmd(struct amr_command *ac)
1423 {
1424 	AMRDB_PRINT((CE_NOTE, "Amr_unmapcmd called, ac=%p",
1425 			(void *)ac));
1426 
1427 	/* if the command involved data at all and was mapped */
1428 	if ((ac->ac_flags & AMR_CMD_MAPPED) &&
1429 		ac->ac_buf && ac->buffer_dma_handle)
1430 		(void) ddi_dma_unbind_handle(ac->buffer_dma_handle);
1431 
1432 	ac->ac_flags &= ~AMR_CMD_MAPPED;
1433 }
1434 
1435 static int
1436 amr_setup_tran(dev_info_t  *dip, struct amr_softs *softp)
1437 {
1438 	softp->hba_tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
1439 
1440 	/*
1441 	 * hba_private always points to the amr_softs struct
1442 	 */
1443 	softp->hba_tran->tran_hba_private	= softp;
1444 	softp->hba_tran->tran_tgt_init		= amr_tran_tgt_init;
1445 	softp->hba_tran->tran_tgt_probe		= scsi_hba_probe;
1446 	softp->hba_tran->tran_start		= amr_tran_start;
1447 	softp->hba_tran->tran_reset		= amr_tran_reset;
1448 	softp->hba_tran->tran_getcap		= amr_tran_getcap;
1449 	softp->hba_tran->tran_setcap		= amr_tran_setcap;
1450 	softp->hba_tran->tran_init_pkt		= amr_tran_init_pkt;
1451 	softp->hba_tran->tran_destroy_pkt	= amr_tran_destroy_pkt;
1452 	softp->hba_tran->tran_dmafree		= amr_tran_dmafree;
1453 	softp->hba_tran->tran_sync_pkt		= amr_tran_sync_pkt;
1454 	softp->hba_tran->tran_abort		= NULL;
1455 	softp->hba_tran->tran_tgt_free		= NULL;
1456 	softp->hba_tran->tran_quiesce		= NULL;
1457 	softp->hba_tran->tran_unquiesce		= NULL;
1458 	softp->hba_tran->tran_sd		= NULL;
1459 
1460 	if (scsi_hba_attach_setup(dip, &buffer_dma_attr, softp->hba_tran,
1461 		SCSI_HBA_TRAN_CLONE) != DDI_SUCCESS) {
1462 		scsi_hba_tran_free(softp->hba_tran);
1463 		softp->hba_tran = NULL;
1464 		return (DDI_FAILURE);
1465 	} else {
1466 		return (DDI_SUCCESS);
1467 	}
1468 }
1469 
1470 /*ARGSUSED*/
1471 static int
1472 amr_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
1473 	scsi_hba_tran_t *tran, struct scsi_device *sd)
1474 {
1475 	struct amr_softs	*softs;
1476 	ushort_t		target = sd->sd_address.a_target;
1477 	uchar_t			lun = sd->sd_address.a_lun;
1478 
1479 	softs = (struct amr_softs *)
1480 		(sd->sd_address.a_hba_tran->tran_hba_private);
1481 
1482 	if ((lun == 0) && (target < AMR_MAXLD))
1483 		if (softs->logic_drive[target].al_state != AMR_LDRV_OFFLINE)
1484 			return (DDI_SUCCESS);
1485 
1486 	return (DDI_FAILURE);
1487 }
1488 
1489 static int
1490 amr_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt)
1491 {
1492 	struct amr_softs	*softs;
1493 	struct buf		*bp = NULL;
1494 	union scsi_cdb		*cdbp = (union scsi_cdb *)pkt->pkt_cdbp;
1495 	int			ret;
1496 	uint32_t		capacity;
1497 	struct amr_command	*ac;
1498 
1499 	AMRDB_PRINT((CE_NOTE, "amr_tran_start, cmd=%X,target=%d,lun=%d",
1500 		cdbp->scc_cmd, ap->a_target, ap->a_lun));
1501 
1502 	softs = (struct amr_softs *)(ap->a_hba_tran->tran_hba_private);
1503 	if ((ap->a_lun != 0) || (ap->a_target >= AMR_MAXLD) ||
1504 		(softs->logic_drive[ap->a_target].al_state ==
1505 			AMR_LDRV_OFFLINE)) {
1506 		cmn_err(CE_WARN, "target or lun is not correct!");
1507 		ret = TRAN_BADPKT;
1508 		return (ret);
1509 	}
1510 
1511 	ac = (struct amr_command *)pkt->pkt_ha_private;
1512 	bp = ac->ac_buf;
1513 
1514 	AMRDB_PRINT((CE_NOTE, "scsi cmd accepted, cmd=%X", cdbp->scc_cmd));
1515 
1516 	switch (cdbp->scc_cmd) {
1517 	case SCMD_READ:		/* read		*/
1518 	case SCMD_READ_G1:	/* read	g1	*/
1519 	case SCMD_READ_BUFFER:	/* read buffer	*/
1520 	case SCMD_WRITE:	/* write	*/
1521 	case SCMD_WRITE_G1:	/* write g1	*/
1522 	case SCMD_WRITE_BUFFER:	/* write buffer	*/
1523 		amr_rw_command(softs, pkt, ap->a_target);
1524 
1525 		if (pkt->pkt_flags & FLAG_NOINTR) {
1526 			(void) amr_poll_command(ac);
1527 			pkt->pkt_state |= (STATE_GOT_BUS
1528 					| STATE_GOT_TARGET
1529 					| STATE_SENT_CMD
1530 					| STATE_XFERRED_DATA);
1531 			*pkt->pkt_scbp = 0;
1532 			pkt->pkt_statistics |= STAT_SYNC;
1533 			pkt->pkt_reason = CMD_CMPLT;
1534 		} else {
1535 			mutex_enter(&softs->queue_mutex);
1536 			if (softs->waiting_q_head == NULL) {
1537 				ac->ac_prev = NULL;
1538 				ac->ac_next = NULL;
1539 				softs->waiting_q_head = ac;
1540 				softs->waiting_q_tail = ac;
1541 			} else {
1542 				ac->ac_next = NULL;
1543 				ac->ac_prev = softs->waiting_q_tail;
1544 				softs->waiting_q_tail->ac_next = ac;
1545 				softs->waiting_q_tail = ac;
1546 			}
1547 			mutex_exit(&softs->queue_mutex);
1548 			amr_start_waiting_queue((void *)softs);
1549 		}
1550 		ret = TRAN_ACCEPT;
1551 		break;
1552 
1553 	case SCMD_INQUIRY: /* inquiry */
1554 		if (bp && bp->b_un.b_addr && bp->b_bcount) {
1555 			struct scsi_inquiry inqp;
1556 			uint8_t *sinq_p = (uint8_t *)&inqp;
1557 
1558 			bzero(&inqp, sizeof (struct scsi_inquiry));
1559 
1560 			if (((char *)cdbp)[1] || ((char *)cdbp)[2]) {
1561 				/*
1562 				 * The EVDP and pagecode is
1563 				 * not supported
1564 				 */
1565 				sinq_p[1] = 0xFF;
1566 				sinq_p[2] = 0x0;
1567 			} else {
1568 				inqp.inq_len = AMR_INQ_ADDITIONAL_LEN;
1569 				inqp.inq_ansi = AMR_INQ_ANSI_VER;
1570 				inqp.inq_rdf = AMR_INQ_RESP_DATA_FORMAT;
1571 				/* Enable Tag Queue */
1572 				inqp.inq_cmdque = 1;
1573 				bcopy("MegaRaid", inqp.inq_vid,
1574 					sizeof (inqp.inq_vid));
1575 				bcopy(softs->amr_product_info.pi_product_name,
1576 					inqp.inq_pid,
1577 					AMR_PRODUCT_INFO_SIZE);
1578 				bcopy(softs->amr_product_info.pi_firmware_ver,
1579 					inqp.inq_revision,
1580 					AMR_FIRMWARE_VER_SIZE);
1581 			}
1582 
1583 			amr_unmapcmd(ac);
1584 
1585 			if (bp->b_flags & (B_PHYS | B_PAGEIO))
1586 				bp_mapin(bp);
1587 			bcopy(&inqp, bp->b_un.b_addr,
1588 				sizeof (struct scsi_inquiry));
1589 
1590 			pkt->pkt_state |= STATE_XFERRED_DATA;
1591 		}
1592 		pkt->pkt_reason = CMD_CMPLT;
1593 		pkt->pkt_state |= (STATE_GOT_BUS
1594 				| STATE_GOT_TARGET
1595 				| STATE_SENT_CMD);
1596 		*pkt->pkt_scbp = 0;
1597 		ret = TRAN_ACCEPT;
1598 		if (!(pkt->pkt_flags & FLAG_NOINTR))
1599 			(*pkt->pkt_comp)(pkt);
1600 		break;
1601 
1602 	case SCMD_READ_CAPACITY: /* read capacity */
1603 		if (bp && bp->b_un.b_addr && bp->b_bcount) {
1604 			struct scsi_capacity cp;
1605 
1606 			capacity = softs->logic_drive[ap->a_target].al_size - 1;
1607 			cp.capacity = BE_32(capacity);
1608 			cp.lbasize = BE_32(512);
1609 
1610 			amr_unmapcmd(ac);
1611 
1612 			if (bp->b_flags & (B_PHYS | B_PAGEIO))
1613 				bp_mapin(bp);
1614 			bcopy(&cp, bp->b_un.b_addr, 8);
1615 		}
1616 		pkt->pkt_reason = CMD_CMPLT;
1617 		pkt->pkt_state |= (STATE_GOT_BUS
1618 				| STATE_GOT_TARGET
1619 				| STATE_SENT_CMD
1620 				| STATE_XFERRED_DATA);
1621 		*pkt->pkt_scbp = 0;
1622 		ret = TRAN_ACCEPT;
1623 		if (!(pkt->pkt_flags & FLAG_NOINTR))
1624 			(*pkt->pkt_comp)(pkt);
1625 		break;
1626 
1627 	case SCMD_MODE_SENSE:		/* mode sense */
1628 	case SCMD_MODE_SENSE_G1:	/* mode sense g1 */
1629 		amr_unmapcmd(ac);
1630 
1631 		capacity = softs->logic_drive[ap->a_target].al_size - 1;
1632 		amr_mode_sense(cdbp, bp, capacity);
1633 
1634 		pkt->pkt_reason = CMD_CMPLT;
1635 		pkt->pkt_state |= (STATE_GOT_BUS
1636 				| STATE_GOT_TARGET
1637 				| STATE_SENT_CMD
1638 				| STATE_XFERRED_DATA);
1639 		*pkt->pkt_scbp = 0;
1640 		ret = TRAN_ACCEPT;
1641 		if (!(pkt->pkt_flags & FLAG_NOINTR))
1642 			(*pkt->pkt_comp)(pkt);
1643 		break;
1644 
1645 	case SCMD_TEST_UNIT_READY:	/* test unit ready */
1646 	case SCMD_REQUEST_SENSE:	/* request sense */
1647 	case SCMD_FORMAT:		/* format */
1648 	case SCMD_START_STOP:		/* start stop */
1649 	case SCMD_SYNCHRONIZE_CACHE:	/* synchronize cache */
1650 		if (bp && bp->b_un.b_addr && bp->b_bcount) {
1651 			amr_unmapcmd(ac);
1652 
1653 			if (bp->b_flags & (B_PHYS | B_PAGEIO))
1654 				bp_mapin(bp);
1655 			bzero(bp->b_un.b_addr, bp->b_bcount);
1656 
1657 			pkt->pkt_state |= STATE_XFERRED_DATA;
1658 		}
1659 		pkt->pkt_reason = CMD_CMPLT;
1660 		pkt->pkt_state |= (STATE_GOT_BUS
1661 				| STATE_GOT_TARGET
1662 				| STATE_SENT_CMD);
1663 		ret = TRAN_ACCEPT;
1664 		*pkt->pkt_scbp = 0;
1665 		if (!(pkt->pkt_flags & FLAG_NOINTR))
1666 			(*pkt->pkt_comp)(pkt);
1667 		break;
1668 
1669 	default: /* any other commands */
1670 		amr_unmapcmd(ac);
1671 		pkt->pkt_reason = CMD_INCOMPLETE;
1672 		pkt->pkt_state = (STATE_GOT_BUS
1673 				| STATE_GOT_TARGET
1674 				| STATE_SENT_CMD
1675 				| STATE_GOT_STATUS
1676 				| STATE_ARQ_DONE);
1677 		ret = TRAN_ACCEPT;
1678 		*pkt->pkt_scbp = 0;
1679 		amr_set_arq_data(pkt, KEY_ILLEGAL_REQUEST);
1680 		if (!(pkt->pkt_flags & FLAG_NOINTR))
1681 			(*pkt->pkt_comp)(pkt);
1682 		break;
1683 	}
1684 
1685 	return (ret);
1686 }
1687 
1688 /*
1689  * tran_reset() will reset the bus/target/adapter to support the fault recovery
1690  * functionality according to the "level" in interface. However, we got the
1691  * confirmation from LSI that these HBA cards does not support any commands to
1692  * reset bus/target/adapter/channel.
1693  *
1694  * If the tran_reset() return a FAILURE to the sd, the system will not
1695  * continue to dump the core. But core dump is an crucial method to analyze
1696  * problems in panic. Now we adopt a work around solution, that is to return
1697  * a fake SUCCESS to sd during panic, which will force the system continue
1698  * to dump core though the core may have problems in some situtation because
1699  * some on-the-fly commands will continue DMAing data to the memory.
1700  * In addition, the work around core dump method may not be performed
1701  * successfully if the panic is caused by the HBA itself. So the work around
1702  * solution is not a good example for the implementation of tran_reset(),
1703  * the most reasonable approach should send a reset command to the adapter.
1704  */
1705 /*ARGSUSED*/
1706 static int
1707 amr_tran_reset(struct scsi_address *ap, int level)
1708 {
1709 	struct amr_softs	*softs;
1710 	volatile uint32_t	done_flag;
1711 
1712 	if (ddi_in_panic()) {
1713 		softs = (struct amr_softs *)(ap->a_hba_tran->tran_hba_private);
1714 
1715 		/* Acknowledge the card if there are any significant commands */
1716 		while (softs->amr_busyslots > 0) {
1717 			AMR_DELAY((softs->mailbox->mb_busy == 0),
1718 					AMR_RETRYCOUNT, done_flag);
1719 			if (!done_flag) {
1720 				/*
1721 				 * command not completed, indicate the
1722 				 * problem and continue get ac
1723 				 */
1724 				cmn_err(CE_WARN,
1725 					"AMR command is not completed");
1726 				return (0);
1727 			}
1728 
1729 			AMR_QPUT_IDB(softs, softs->mbox_phyaddr | AMR_QIDB_ACK);
1730 
1731 			/* wait for the acknowledge from hardware */
1732 			AMR_BUSYWAIT(!(AMR_QGET_IDB(softs) & AMR_QIDB_ACK),
1733 					AMR_RETRYCOUNT, done_flag);
1734 			if (!done_flag) {
1735 				/*
1736 				 * command is not completed, return from the
1737 				 * current interrupt and wait for the next one
1738 				 */
1739 				cmn_err(CE_WARN, "No answer from the hardware");
1740 
1741 				mutex_exit(&softs->cmd_mutex);
1742 				return (0);
1743 			}
1744 
1745 			softs->amr_busyslots -= softs->mailbox->mb_nstatus;
1746 		}
1747 
1748 		/* flush the controllor */
1749 		(void) amr_flush(softs);
1750 
1751 		/*
1752 		 * If the system is in panic, the tran_reset() will return a
1753 		 * fake SUCCESS to sd, then the system would continue dump the
1754 		 * core by poll commands. This is a work around for dumping
1755 		 * core in panic.
1756 		 *
1757 		 * Note: Some on-the-fly command will continue DMAing data to
1758 		 *	 the memory when the core is dumping, which may cause
1759 		 *	 some flaws in the dumped core file, so a cmn_err()
1760 		 *	 will be printed out to warn users. However, for most
1761 		 *	 cases, the core file will be fine.
1762 		 */
1763 		cmn_err(CE_WARN, "This system contains a SCSI HBA card/driver "
1764 				"that doesn't support software reset. This "
1765 				"means that memory being used by the HBA for "
1766 				"DMA based reads could have been updated after "
1767 				"we panic'd.");
1768 		return (1);
1769 	} else {
1770 		/* return failure to sd */
1771 		return (0);
1772 	}
1773 }
1774 
1775 /*ARGSUSED*/
1776 static int
1777 amr_tran_getcap(struct scsi_address *ap, char *cap, int whom)
1778 {
1779 	struct amr_softs	*softs;
1780 
1781 	/*
1782 	 * We don't allow inquiring about capabilities for other targets
1783 	 */
1784 	if (cap == NULL || whom == 0)
1785 		return (-1);
1786 
1787 	softs = ((struct amr_softs *)(ap->a_hba_tran)->tran_hba_private);
1788 
1789 	switch (scsi_hba_lookup_capstr(cap)) {
1790 	case SCSI_CAP_ARQ:
1791 		return (1);
1792 	case SCSI_CAP_GEOMETRY:
1793 		return ((AMR_DEFAULT_HEADS << 16) | AMR_DEFAULT_CYLINDERS);
1794 	case SCSI_CAP_SECTOR_SIZE:
1795 		return (AMR_DEFAULT_SECTORS);
1796 	case SCSI_CAP_TOTAL_SECTORS:
1797 		/* number of sectors */
1798 		return (softs->logic_drive[ap->a_target].al_size);
1799 	case SCSI_CAP_UNTAGGED_QING:
1800 	case SCSI_CAP_TAGGED_QING:
1801 		return (1);
1802 	default:
1803 		return (-1);
1804 	}
1805 }
1806 
1807 /*ARGSUSED*/
1808 static int
1809 amr_tran_setcap(struct scsi_address *ap, char *cap, int value,
1810 		int whom)
1811 {
1812 	/*
1813 	 * We don't allow setting capabilities for other targets
1814 	 */
1815 	if (cap == NULL || whom == 0) {
1816 		AMRDB_PRINT((CE_NOTE,
1817 			"Set Cap not supported, string = %s, whom=%d",
1818 			cap, whom));
1819 		return (-1);
1820 	}
1821 
1822 	switch (scsi_hba_lookup_capstr(cap)) {
1823 	case SCSI_CAP_ARQ:
1824 		return (1);
1825 	case SCSI_CAP_TOTAL_SECTORS:
1826 		return (1);
1827 	case SCSI_CAP_SECTOR_SIZE:
1828 		return (1);
1829 	case SCSI_CAP_UNTAGGED_QING:
1830 	case SCSI_CAP_TAGGED_QING:
1831 		return ((value == 1) ? 1 : 0);
1832 	default:
1833 		return (0);
1834 	}
1835 }
1836 
1837 static struct scsi_pkt *
1838 amr_tran_init_pkt(struct scsi_address *ap,
1839     struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
1840     int tgtlen, int flags, int (*callback)(), caddr_t arg)
1841 {
1842 	struct amr_softs	*softs;
1843 	struct amr_command	*ac;
1844 	uint32_t		slen;
1845 
1846 	softs = (struct amr_softs *)(ap->a_hba_tran->tran_hba_private);
1847 
1848 	if ((ap->a_lun != 0)||(ap->a_target >= AMR_MAXLD)||
1849 		(softs->logic_drive[ap->a_target].al_state ==
1850 			AMR_LDRV_OFFLINE)) {
1851 		return (NULL);
1852 	}
1853 
1854 	if (pkt == NULL) {
1855 		/* force auto request sense */
1856 		slen = MAX(statuslen, sizeof (struct scsi_arq_status));
1857 
1858 		pkt = scsi_hba_pkt_alloc(softs->dev_info_p, ap, cmdlen,
1859 			slen, tgtlen, sizeof (struct amr_command),
1860 			callback, arg);
1861 		if (pkt == NULL) {
1862 			AMRDB_PRINT((CE_WARN, "scsi_hba_pkt_alloc failed"));
1863 			return (NULL);
1864 		}
1865 		pkt->pkt_address	= *ap;
1866 		pkt->pkt_comp		= (void (*)())NULL;
1867 		pkt->pkt_time		= 0;
1868 		pkt->pkt_resid		= 0;
1869 		pkt->pkt_statistics	= 0;
1870 		pkt->pkt_reason		= 0;
1871 
1872 		ac = (struct amr_command *)pkt->pkt_ha_private;
1873 		ac->ac_buf = bp;
1874 		ac->cmdlen = cmdlen;
1875 		ac->ac_softs = softs;
1876 		ac->pkt = pkt;
1877 		ac->ac_flags &= ~AMR_CMD_GOT_SLOT;
1878 		ac->ac_flags &= ~AMR_CMD_BUSY;
1879 
1880 		if ((bp == NULL) || (bp->b_bcount == 0)) {
1881 			return (pkt);
1882 		}
1883 
1884 		if (ddi_dma_alloc_handle(softs->dev_info_p, &buffer_dma_attr,
1885 			DDI_DMA_SLEEP, NULL,
1886 			&ac->buffer_dma_handle) != DDI_SUCCESS) {
1887 
1888 			AMRDB_PRINT((CE_WARN,
1889 				"Cannot allocate buffer DMA tag"));
1890 			scsi_hba_pkt_free(ap, pkt);
1891 			return (NULL);
1892 
1893 		}
1894 
1895 	} else {
1896 		if ((bp == NULL) || (bp->b_bcount == 0)) {
1897 			return (pkt);
1898 		}
1899 		ac = (struct amr_command *)pkt->pkt_ha_private;
1900 	}
1901 
1902 	ASSERT(ac != NULL);
1903 
1904 	if (bp->b_flags & B_READ) {
1905 		ac->ac_flags |= AMR_CMD_DATAOUT;
1906 	} else {
1907 		ac->ac_flags |= AMR_CMD_DATAIN;
1908 	}
1909 
1910 	if (flags & PKT_CONSISTENT) {
1911 		ac->ac_flags |= AMR_CMD_PKT_CONSISTENT;
1912 	}
1913 
1914 	if (flags & PKT_DMA_PARTIAL) {
1915 		ac->ac_flags |= AMR_CMD_PKT_DMA_PARTIAL;
1916 	}
1917 
1918 	if (amr_mapcmd(ac, callback, arg) != DDI_SUCCESS) {
1919 		scsi_hba_pkt_free(ap, pkt);
1920 		return (NULL);
1921 	}
1922 
1923 	pkt->pkt_resid = bp->b_bcount - ac->data_transfered;
1924 
1925 	AMRDB_PRINT((CE_NOTE,
1926 		"init pkt, pkt_resid=%d, b_bcount=%d, data_transfered=%d",
1927 		(uint32_t)pkt->pkt_resid, (uint32_t)bp->b_bcount,
1928 		ac->data_transfered));
1929 
1930 	ASSERT(pkt->pkt_resid >= 0);
1931 
1932 	return (pkt);
1933 }
1934 
1935 static void
1936 amr_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
1937 {
1938 	struct amr_command *ac = (struct amr_command *)pkt->pkt_ha_private;
1939 
1940 	amr_unmapcmd(ac);
1941 
1942 	if (ac->buffer_dma_handle) {
1943 		(void) ddi_dma_free_handle(&ac->buffer_dma_handle);
1944 		ac->buffer_dma_handle = NULL;
1945 	}
1946 
1947 	scsi_hba_pkt_free(ap, pkt);
1948 	AMRDB_PRINT((CE_NOTE, "Destroy pkt called"));
1949 }
1950 
1951 /*ARGSUSED*/
1952 static void
1953 amr_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
1954 {
1955 	struct amr_command *ac = (struct amr_command *)pkt->pkt_ha_private;
1956 
1957 	if (ac->buffer_dma_handle) {
1958 		(void) ddi_dma_sync(ac->buffer_dma_handle, 0, 0,
1959 			(ac->ac_flags & AMR_CMD_DATAIN) ?
1960 			DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU);
1961 	}
1962 }
1963 
1964 /*ARGSUSED*/
1965 static void
1966 amr_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
1967 {
1968 	struct amr_command *ac = (struct amr_command *)pkt->pkt_ha_private;
1969 
1970 	if (ac->ac_flags & AMR_CMD_MAPPED) {
1971 		(void) ddi_dma_unbind_handle(ac->buffer_dma_handle);
1972 		(void) ddi_dma_free_handle(&ac->buffer_dma_handle);
1973 		ac->buffer_dma_handle = NULL;
1974 		ac->ac_flags &= ~AMR_CMD_MAPPED;
1975 	}
1976 
1977 }
1978 
1979 /*ARGSUSED*/
1980 static void
1981 amr_rw_command(struct amr_softs *softs, struct scsi_pkt *pkt, int target)
1982 {
1983 	struct amr_command	*ac = (struct amr_command *)pkt->pkt_ha_private;
1984 	union scsi_cdb		*cdbp = (union scsi_cdb *)pkt->pkt_cdbp;
1985 	uint8_t			cmd;
1986 
1987 	if (ac->ac_flags & AMR_CMD_DATAOUT) {
1988 		cmd = AMR_CMD_LREAD;
1989 	} else {
1990 		cmd = AMR_CMD_LWRITE;
1991 	}
1992 
1993 	ac->mailbox.mb_command = cmd;
1994 	ac->mailbox.mb_blkcount =
1995 		(ac->transfer_size + AMR_BLKSIZE - 1)/AMR_BLKSIZE;
1996 	ac->mailbox.mb_lba = (ac->cmdlen == 10) ?
1997 				GETG1ADDR(cdbp) : GETG0ADDR(cdbp);
1998 	ac->mailbox.mb_drive = (uint8_t)target;
1999 }
2000 
2001 static void
2002 amr_mode_sense(union scsi_cdb *cdbp, struct buf *bp, unsigned int capacity)
2003 {
2004 	uchar_t			pagecode;
2005 	struct mode_format	*page3p;
2006 	struct mode_geometry	*page4p;
2007 	struct mode_header	*headerp;
2008 	uint32_t		ncyl;
2009 
2010 	if (!(bp && bp->b_un.b_addr && bp->b_bcount))
2011 		return;
2012 
2013 	if (bp->b_flags & (B_PHYS | B_PAGEIO))
2014 		bp_mapin(bp);
2015 
2016 	pagecode = cdbp->cdb_un.sg.scsi[0];
2017 	switch (pagecode) {
2018 	case SD_MODE_SENSE_PAGE3_CODE:
2019 		headerp = (struct mode_header *)(bp->b_un.b_addr);
2020 		headerp->bdesc_length = MODE_BLK_DESC_LENGTH;
2021 
2022 		page3p = (struct mode_format *)((caddr_t)headerp +
2023 			MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH);
2024 		page3p->mode_page.code = BE_8(SD_MODE_SENSE_PAGE3_CODE);
2025 		page3p->mode_page.length = BE_8(sizeof (struct mode_format));
2026 		page3p->data_bytes_sect = BE_16(AMR_DEFAULT_SECTORS);
2027 		page3p->sect_track = BE_16(AMR_DEFAULT_CYLINDERS);
2028 
2029 		return;
2030 
2031 	case SD_MODE_SENSE_PAGE4_CODE:
2032 		headerp = (struct mode_header *)(bp->b_un.b_addr);
2033 		headerp->bdesc_length = MODE_BLK_DESC_LENGTH;
2034 
2035 		page4p = (struct mode_geometry *)((caddr_t)headerp +
2036 			MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH);
2037 		page4p->mode_page.code = BE_8(SD_MODE_SENSE_PAGE4_CODE);
2038 		page4p->mode_page.length = BE_8(sizeof (struct mode_geometry));
2039 		page4p->heads = BE_8(AMR_DEFAULT_HEADS);
2040 		page4p->rpm = BE_16(AMR_DEFAULT_ROTATIONS);
2041 
2042 		ncyl = capacity / (AMR_DEFAULT_HEADS*AMR_DEFAULT_CYLINDERS);
2043 		page4p->cyl_lb = BE_8(ncyl & 0xff);
2044 		page4p->cyl_mb = BE_8((ncyl >> 8) & 0xff);
2045 		page4p->cyl_ub = BE_8((ncyl >> 16) & 0xff);
2046 
2047 		return;
2048 	default:
2049 		bzero(bp->b_un.b_addr, bp->b_bcount);
2050 		return;
2051 	}
2052 }
2053 
2054 static void
2055 amr_set_arq_data(struct scsi_pkt *pkt, uchar_t key)
2056 {
2057 	struct scsi_arq_status *arqstat;
2058 
2059 	arqstat = (struct scsi_arq_status *)(pkt->pkt_scbp);
2060 	arqstat->sts_status.sts_chk = 1; /* CHECK CONDITION */
2061 	arqstat->sts_rqpkt_reason = CMD_CMPLT;
2062 	arqstat->sts_rqpkt_resid = 0;
2063 	arqstat->sts_rqpkt_state = STATE_GOT_BUS | STATE_GOT_TARGET |
2064 				STATE_SENT_CMD | STATE_XFERRED_DATA;
2065 	arqstat->sts_rqpkt_statistics = 0;
2066 	arqstat->sts_sensedata.es_valid = 1;
2067 	arqstat->sts_sensedata.es_class = CLASS_EXTENDED_SENSE;
2068 	arqstat->sts_sensedata.es_key = key;
2069 }
2070 
2071 static void
2072 amr_start_waiting_queue(void *softp)
2073 {
2074 	uint32_t		slot;
2075 	struct amr_command	*ac;
2076 	volatile uint32_t	done_flag;
2077 	struct amr_softs	*softs = (struct amr_softs *)softp;
2078 
2079 	/* only one command allowed at the same time */
2080 	mutex_enter(&softs->queue_mutex);
2081 	mutex_enter(&softs->cmd_mutex);
2082 
2083 	while ((ac = softs->waiting_q_head) != NULL) {
2084 		/*
2085 		 * Find an available slot, the last slot is
2086 		 * occupied by poll I/O command.
2087 		 */
2088 		for (slot = 0; slot < (softs->sg_max_count - 1); slot++) {
2089 			if (softs->busycmd[slot] == NULL) {
2090 				if (AMR_QGET_IDB(softs) & AMR_QIDB_SUBMIT) {
2091 					/*
2092 					 * only one command allowed at the
2093 					 * same time
2094 					 */
2095 					mutex_exit(&softs->cmd_mutex);
2096 					mutex_exit(&softs->queue_mutex);
2097 					return;
2098 				}
2099 
2100 				ac->ac_timestamp = ddi_get_time();
2101 
2102 				if (!(ac->ac_flags & AMR_CMD_GOT_SLOT)) {
2103 
2104 					softs->busycmd[slot] = ac;
2105 					ac->ac_slot = slot;
2106 					softs->amr_busyslots++;
2107 
2108 					bcopy(ac->sgtable,
2109 					softs->sg_items[slot].sg_table,
2110 					sizeof (struct amr_sgentry) * AMR_NSEG);
2111 
2112 					(void) ddi_dma_sync(
2113 					softs->sg_items[slot].sg_handle,
2114 					0, 0, DDI_DMA_SYNC_FORDEV);
2115 
2116 					ac->mailbox.mb_physaddr =
2117 					softs->sg_items[slot].sg_phyaddr;
2118 				}
2119 
2120 				/* take the cmd from the queue */
2121 				softs->waiting_q_head = ac->ac_next;
2122 
2123 				ac->mailbox.mb_ident = ac->ac_slot + 1;
2124 				ac->mailbox.mb_busy = 1;
2125 				ac->ac_next = NULL;
2126 				ac->ac_prev = NULL;
2127 				ac->ac_flags |= AMR_CMD_GOT_SLOT;
2128 
2129 				/* clear the poll/ack fields in the mailbox */
2130 				softs->mailbox->mb_poll = 0;
2131 				softs->mailbox->mb_ack = 0;
2132 
2133 				AMR_DELAY((softs->mailbox->mb_busy == 0),
2134 					AMR_RETRYCOUNT, done_flag);
2135 				if (!done_flag) {
2136 					/*
2137 					 * command not completed, indicate the
2138 					 * problem and continue get ac
2139 					 */
2140 					cmn_err(CE_WARN,
2141 						"AMR command is not completed");
2142 					break;
2143 				}
2144 
2145 				bcopy(&ac->mailbox, (void *)softs->mailbox,
2146 					AMR_MBOX_CMDSIZE);
2147 				ac->ac_flags |= AMR_CMD_BUSY;
2148 
2149 				(void) ddi_dma_sync(softs->mbox_dma_handle,
2150 					0, 0, DDI_DMA_SYNC_FORDEV);
2151 
2152 				AMR_QPUT_IDB(softs,
2153 					softs->mbox_phyaddr | AMR_QIDB_SUBMIT);
2154 
2155 				/*
2156 				 * current ac is submitted
2157 				 * so quit 'for-loop' to get next ac
2158 				 */
2159 				break;
2160 			}
2161 		}
2162 
2163 		/* no slot, finish our task */
2164 		if (slot == softs->maxio)
2165 			break;
2166 	}
2167 
2168 	/* only one command allowed at the same time */
2169 	mutex_exit(&softs->cmd_mutex);
2170 	mutex_exit(&softs->queue_mutex);
2171 }
2172 
2173 static void
2174 amr_done(struct amr_softs *softs)
2175 {
2176 
2177 	uint32_t		i, idx;
2178 	volatile uint32_t	done_flag;
2179 	struct amr_mailbox	*mbox, mbsave;
2180 	struct amr_command	*ac, *head, *tail;
2181 
2182 	head = tail = NULL;
2183 
2184 	AMR_QPUT_ODB(softs, AMR_QODB_READY);
2185 
2186 	/* acknowledge interrupt */
2187 	(void) AMR_QGET_ODB(softs);
2188 
2189 	mutex_enter(&softs->cmd_mutex);
2190 
2191 	if (softs->mailbox->mb_nstatus != 0) {
2192 		(void) ddi_dma_sync(softs->mbox_dma_handle,
2193 			0, 0, DDI_DMA_SYNC_FORCPU);
2194 
2195 		/* save mailbox, which contains a list of completed commands */
2196 		bcopy((void *)(uintptr_t)(volatile void *)softs->mailbox,
2197 				&mbsave, sizeof (mbsave));
2198 
2199 		mbox = &mbsave;
2200 
2201 		AMR_QPUT_IDB(softs, softs->mbox_phyaddr | AMR_QIDB_ACK);
2202 
2203 		/* wait for the acknowledge from hardware */
2204 		AMR_BUSYWAIT(!(AMR_QGET_IDB(softs) & AMR_QIDB_ACK),
2205 				AMR_RETRYCOUNT, done_flag);
2206 		if (!done_flag) {
2207 			/*
2208 			 * command is not completed, return from the current
2209 			 * interrupt and wait for the next one
2210 			 */
2211 			cmn_err(CE_WARN, "No answer from the hardware");
2212 
2213 			mutex_exit(&softs->cmd_mutex);
2214 			return;
2215 		}
2216 
2217 		for (i = 0; i < mbox->mb_nstatus; i++) {
2218 			idx = mbox->mb_completed[i] - 1;
2219 			ac = softs->busycmd[idx];
2220 
2221 			if (ac != NULL) {
2222 				/* pull the command from the busy index */
2223 				softs->busycmd[idx] = NULL;
2224 				if (softs->amr_busyslots > 0)
2225 					softs->amr_busyslots--;
2226 				if (softs->amr_busyslots == 0)
2227 					cv_broadcast(&softs->cmd_cv);
2228 
2229 				ac->ac_flags &= ~AMR_CMD_BUSY;
2230 				ac->ac_flags &= ~AMR_CMD_GOT_SLOT;
2231 				ac->ac_status = mbox->mb_status;
2232 
2233 				/* enqueue here */
2234 				if (head) {
2235 					tail->ac_next = ac;
2236 					tail = ac;
2237 					tail->ac_next = NULL;
2238 				} else {
2239 					tail = head = ac;
2240 					ac->ac_next = NULL;
2241 				}
2242 			} else {
2243 				AMRDB_PRINT((CE_WARN,
2244 					"ac in mailbox is NULL!"));
2245 			}
2246 		}
2247 	} else {
2248 		AMRDB_PRINT((CE_WARN, "mailbox is not ready for copy out!"));
2249 	}
2250 
2251 	mutex_exit(&softs->cmd_mutex);
2252 
2253 	if (head != NULL) {
2254 		amr_call_pkt_comp(head);
2255 	}
2256 
2257 	/* dispatch a thread to process the pending I/O if there is any */
2258 	if ((ddi_taskq_dispatch(softs->amr_taskq, amr_start_waiting_queue,
2259 		(void *)softs, DDI_NOSLEEP)) != DDI_SUCCESS) {
2260 		cmn_err(CE_WARN, "No memory available to dispatch taskq");
2261 	}
2262 }
2263 
2264 static void
2265 amr_call_pkt_comp(register struct amr_command *head)
2266 {
2267 	register struct scsi_pkt	*pkt;
2268 	register struct amr_command	*ac, *localhead;
2269 
2270 	localhead = head;
2271 
2272 	while (localhead) {
2273 		ac = localhead;
2274 		localhead = ac->ac_next;
2275 		ac->ac_next = NULL;
2276 
2277 		pkt = ac->pkt;
2278 		*pkt->pkt_scbp = 0;
2279 
2280 		if (ac->ac_status == AMR_STATUS_SUCCESS) {
2281 			pkt->pkt_state |= (STATE_GOT_BUS
2282 					| STATE_GOT_TARGET
2283 					| STATE_SENT_CMD
2284 					| STATE_XFERRED_DATA);
2285 			pkt->pkt_reason = CMD_CMPLT;
2286 		} else {
2287 			pkt->pkt_state |= STATE_GOT_BUS
2288 					| STATE_ARQ_DONE;
2289 			pkt->pkt_reason = CMD_INCOMPLETE;
2290 			amr_set_arq_data(pkt, KEY_HARDWARE_ERROR);
2291 		}
2292 
2293 		if (!(pkt->pkt_flags & FLAG_NOINTR) &&
2294 			pkt->pkt_comp) {
2295 			(*pkt->pkt_comp)(pkt);
2296 		}
2297 	}
2298 }
2299