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