xref: /illumos-gate/usr/src/uts/intel/io/amr/amr.c (revision bfed486ad8de8b8ebc6345a8e10accae08bf2f45)
1 /*
2  * Copyright 2008 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 &
761 			    FLAG_NOINTR) && pkt->pkt_comp) {
762 				/* call pkt callback */
763 				(*pkt->pkt_comp)(pkt);
764 			}
765 
766 		} else {
767 			mutex_exit(&softs->cmd_mutex);
768 		}
769 	}
770 
771 	/* restart the amr timer */
772 	mutex_enter(&softs->periodic_mutex);
773 	if (softs->state & AMR_STATE_TIMEOUT_ENABLED)
774 		softs->timeout_t = timeout(amr_periodic, (void *)softs,
775 		    drv_usectohz(500000*AMR_PERIODIC_TIMEOUT));
776 	mutex_exit(&softs->periodic_mutex);
777 }
778 
779 /*
780  * Interrogate the controller for the operational parameters we require.
781  */
782 static int
783 amr_query_controller(struct amr_softs *softs)
784 {
785 	struct amr_enquiry3	*aex;
786 	struct amr_prodinfo	*ap;
787 	struct amr_enquiry	*ae;
788 	uint32_t		ldrv;
789 	int			instance;
790 
791 	/*
792 	 * If we haven't found the real limit yet, let us have a couple of
793 	 * commands in order to be able to probe.
794 	 */
795 	if (softs->maxio == 0)
796 		softs->maxio = 2;
797 
798 	instance = ddi_get_instance(softs->dev_info_p);
799 
800 	/*
801 	 * Try to issue an ENQUIRY3 command
802 	 */
803 	if ((aex = amr_enquiry(softs, AMR_ENQ_BUFFER_SIZE, AMR_CMD_CONFIG,
804 	    AMR_CONFIG_ENQ3, AMR_CONFIG_ENQ3_SOLICITED_FULL)) != NULL) {
805 
806 		AMRDB_PRINT((CE_NOTE, "First enquiry"));
807 
808 		for (ldrv = 0; ldrv < aex->ae_numldrives; ldrv++) {
809 			softs->logic_drive[ldrv].al_size =
810 			    aex->ae_drivesize[ldrv];
811 			softs->logic_drive[ldrv].al_state =
812 			    aex->ae_drivestate[ldrv];
813 			softs->logic_drive[ldrv].al_properties =
814 			    aex->ae_driveprop[ldrv];
815 			AMRDB_PRINT((CE_NOTE,
816 			    "  drive %d: size: %d state %x properties %x\n",
817 			    ldrv,
818 			    softs->logic_drive[ldrv].al_size,
819 			    softs->logic_drive[ldrv].al_state,
820 			    softs->logic_drive[ldrv].al_properties));
821 
822 			if (softs->logic_drive[ldrv].al_state ==
823 			    AMR_LDRV_OFFLINE)
824 				cmn_err(CE_NOTE,
825 				    "!instance %d log-drive %d is offline",
826 				    instance, ldrv);
827 			else
828 				softs->amr_nlogdrives++;
829 		}
830 		kmem_free(aex, AMR_ENQ_BUFFER_SIZE);
831 
832 		if ((ap = amr_enquiry(softs, AMR_ENQ_BUFFER_SIZE,
833 		    AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) == NULL) {
834 			AMRDB_PRINT((CE_NOTE,
835 			    "Cannot obtain product data from controller"));
836 			return (EIO);
837 		}
838 
839 		softs->maxdrives = AMR_40LD_MAXDRIVES;
840 		softs->maxchan = ap->ap_nschan;
841 		softs->maxio = ap->ap_maxio;
842 
843 		bcopy(ap->ap_firmware, softs->amr_product_info.pi_firmware_ver,
844 		    AMR_FIRMWARE_VER_SIZE);
845 		softs->amr_product_info.
846 		    pi_firmware_ver[AMR_FIRMWARE_VER_SIZE] = 0;
847 
848 		bcopy(ap->ap_product, softs->amr_product_info.pi_product_name,
849 		    AMR_PRODUCT_INFO_SIZE);
850 		softs->amr_product_info.
851 		    pi_product_name[AMR_PRODUCT_INFO_SIZE] = 0;
852 
853 		kmem_free(ap, AMR_ENQ_BUFFER_SIZE);
854 		AMRDB_PRINT((CE_NOTE, "maxio=%d", softs->maxio));
855 	} else {
856 
857 		AMRDB_PRINT((CE_NOTE, "First enquiry failed, \
858 				so try another way"));
859 
860 		/* failed, try the 8LD ENQUIRY commands */
861 		if ((ae = (struct amr_enquiry *)amr_enquiry(softs,
862 		    AMR_ENQ_BUFFER_SIZE, AMR_CMD_EXT_ENQUIRY2, 0, 0))
863 		    == NULL) {
864 
865 			if ((ae = (struct amr_enquiry *)amr_enquiry(softs,
866 			    AMR_ENQ_BUFFER_SIZE, AMR_CMD_ENQUIRY, 0, 0))
867 			    == NULL) {
868 				AMRDB_PRINT((CE_NOTE,
869 				    "Cannot obtain configuration data"));
870 				return (EIO);
871 			}
872 			ae->ae_signature = 0;
873 		}
874 
875 		/*
876 		 * Fetch current state of logical drives.
877 		 */
878 		for (ldrv = 0; ldrv < ae->ae_ldrv.al_numdrives; ldrv++) {
879 			softs->logic_drive[ldrv].al_size =
880 			    ae->ae_ldrv.al_size[ldrv];
881 			softs->logic_drive[ldrv].al_state =
882 			    ae->ae_ldrv.al_state[ldrv];
883 			softs->logic_drive[ldrv].al_properties =
884 			    ae->ae_ldrv.al_properties[ldrv];
885 			AMRDB_PRINT((CE_NOTE,
886 			    " ********* drive %d: %d state %x properties %x",
887 			    ldrv,
888 			    softs->logic_drive[ldrv].al_size,
889 			    softs->logic_drive[ldrv].al_state,
890 			    softs->logic_drive[ldrv].al_properties));
891 
892 			if (softs->logic_drive[ldrv].al_state ==
893 			    AMR_LDRV_OFFLINE)
894 				cmn_err(CE_NOTE,
895 				    "!instance %d log-drive %d is offline",
896 				    instance, ldrv);
897 			else
898 				softs->amr_nlogdrives++;
899 		}
900 
901 		softs->maxdrives = AMR_8LD_MAXDRIVES;
902 		softs->maxchan = ae->ae_adapter.aa_channels;
903 		softs->maxio = ae->ae_adapter.aa_maxio;
904 		kmem_free(ae, AMR_ENQ_BUFFER_SIZE);
905 	}
906 
907 	/*
908 	 * Mark remaining drives as unused.
909 	 */
910 	for (; ldrv < AMR_MAXLD; ldrv++)
911 		softs->logic_drive[ldrv].al_state = AMR_LDRV_OFFLINE;
912 
913 	/*
914 	 * Cap the maximum number of outstanding I/Os.  AMI's driver
915 	 * doesn't trust the controller's reported value, and lockups have
916 	 * been seen when we do.
917 	 */
918 	softs->maxio = MIN(softs->maxio, AMR_LIMITCMD);
919 
920 	return (DDI_SUCCESS);
921 }
922 
923 /*
924  * Run a generic enquiry-style command.
925  */
926 static void *
927 amr_enquiry(struct amr_softs *softs, size_t bufsize, uint8_t cmd,
928 				uint8_t cmdsub, uint8_t cmdqual)
929 {
930 	struct amr_command	ac;
931 	void			*result;
932 
933 	result = NULL;
934 
935 	bzero(&ac, sizeof (struct amr_command));
936 	ac.ac_softs = softs;
937 
938 	/* set command flags */
939 	ac.ac_flags |= AMR_CMD_DATAOUT;
940 
941 	/* build the command proper */
942 	ac.mailbox.mb_command	= cmd;
943 	ac.mailbox.mb_cmdsub	= cmdsub;
944 	ac.mailbox.mb_cmdqual	= cmdqual;
945 
946 	if (amr_enquiry_mapcmd(&ac, bufsize) != DDI_SUCCESS)
947 		return (NULL);
948 
949 	if (amr_poll_command(&ac) || ac.ac_status != 0) {
950 		AMRDB_PRINT((CE_NOTE, "can not poll command, goto out"));
951 		amr_enquiry_unmapcmd(&ac);
952 		return (NULL);
953 	}
954 
955 	/* allocate the response structure */
956 	result = kmem_zalloc(bufsize, KM_SLEEP);
957 
958 	bcopy(ac.ac_data, result, bufsize);
959 
960 	amr_enquiry_unmapcmd(&ac);
961 	return (result);
962 }
963 
964 /*
965  * Flush the controller's internal cache, return status.
966  */
967 static int
968 amr_flush(struct amr_softs *softs)
969 {
970 	struct amr_command	ac;
971 	int			error = 0;
972 
973 	bzero(&ac, sizeof (struct amr_command));
974 	ac.ac_softs = softs;
975 
976 	ac.ac_flags |= AMR_CMD_DATAOUT;
977 
978 	/* build the command proper */
979 	ac.mailbox.mb_command = AMR_CMD_FLUSH;
980 
981 	/* have to poll, as the system may be going down or otherwise damaged */
982 	if (error = amr_poll_command(&ac)) {
983 		AMRDB_PRINT((CE_NOTE, "can not poll this cmd"));
984 		return (error);
985 	}
986 
987 	return (error);
988 }
989 
990 /*
991  * Take a command, submit it to the controller and wait for it to return.
992  * Returns nonzero on error.  Can be safely called with interrupts enabled.
993  */
994 static int
995 amr_poll_command(struct amr_command *ac)
996 {
997 	struct amr_softs	*softs = ac->ac_softs;
998 	volatile uint32_t	done_flag;
999 
1000 	AMRDB_PRINT((CE_NOTE, "Amr_Poll bcopy(%p, %p, %d)",
1001 	    (void *)&ac->mailbox,
1002 	    (void *)softs->mailbox,
1003 	    (uint32_t)AMR_MBOX_CMDSIZE));
1004 
1005 	mutex_enter(&softs->cmd_mutex);
1006 
1007 	while (softs->amr_busyslots != 0)
1008 		cv_wait(&softs->cmd_cv, &softs->cmd_mutex);
1009 
1010 	/*
1011 	 * For read/write commands, the scatter/gather table should be
1012 	 * filled, and the last entry in scatter/gather table will be used.
1013 	 */
1014 	if ((ac->mailbox.mb_command == AMR_CMD_LREAD) ||
1015 	    (ac->mailbox.mb_command == AMR_CMD_LWRITE)) {
1016 		bcopy(ac->sgtable,
1017 		    softs->sg_items[softs->sg_max_count - 1].sg_table,
1018 		    sizeof (struct amr_sgentry) * AMR_NSEG);
1019 
1020 		(void) ddi_dma_sync(
1021 		    softs->sg_items[softs->sg_max_count - 1].sg_handle,
1022 		    0, 0, DDI_DMA_SYNC_FORDEV);
1023 
1024 		ac->mailbox.mb_physaddr =
1025 		    softs->sg_items[softs->sg_max_count - 1].sg_phyaddr;
1026 	}
1027 
1028 	bcopy(&ac->mailbox, (void *)softs->mailbox, AMR_MBOX_CMDSIZE);
1029 
1030 	/* sync the dma memory */
1031 	(void) ddi_dma_sync(softs->mbox_dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV);
1032 
1033 	/* clear the poll/ack fields in the mailbox */
1034 	softs->mailbox->mb_ident = AMR_POLL_COMMAND_ID;
1035 	softs->mailbox->mb_nstatus = AMR_POLL_DEFAULT_NSTATUS;
1036 	softs->mailbox->mb_status = AMR_POLL_DEFAULT_STATUS;
1037 	softs->mailbox->mb_poll = 0;
1038 	softs->mailbox->mb_ack = 0;
1039 	softs->mailbox->mb_busy = 1;
1040 
1041 	AMR_QPUT_IDB(softs, softs->mbox_phyaddr | AMR_QIDB_SUBMIT);
1042 
1043 	/* sync the dma memory */
1044 	(void) ddi_dma_sync(softs->mbox_dma_handle, 0, 0, DDI_DMA_SYNC_FORCPU);
1045 
1046 	AMR_DELAY((softs->mailbox->mb_nstatus != AMR_POLL_DEFAULT_NSTATUS),
1047 	    1000, done_flag);
1048 	if (!done_flag) {
1049 		mutex_exit(&softs->cmd_mutex);
1050 		return (1);
1051 	}
1052 
1053 	ac->ac_status = softs->mailbox->mb_status;
1054 
1055 	AMR_DELAY((softs->mailbox->mb_poll == AMR_POLL_ACK), 1000, done_flag);
1056 	if (!done_flag) {
1057 		mutex_exit(&softs->cmd_mutex);
1058 		return (1);
1059 	}
1060 
1061 	softs->mailbox->mb_poll = 0;
1062 	softs->mailbox->mb_ack = AMR_POLL_ACK;
1063 
1064 	/* acknowledge that we have the commands */
1065 	AMR_QPUT_IDB(softs, softs->mbox_phyaddr | AMR_QIDB_ACK);
1066 
1067 	AMR_DELAY(!(AMR_QGET_IDB(softs) & AMR_QIDB_ACK), 1000, done_flag);
1068 	if (!done_flag) {
1069 		mutex_exit(&softs->cmd_mutex);
1070 		return (1);
1071 	}
1072 
1073 	mutex_exit(&softs->cmd_mutex);
1074 	return (ac->ac_status != AMR_STATUS_SUCCESS);
1075 }
1076 
1077 /*
1078  * setup the scatter/gather table
1079  */
1080 static int
1081 amr_setup_sg(struct amr_softs *softs)
1082 {
1083 	uint32_t		i;
1084 	size_t			len;
1085 	ddi_dma_cookie_t	cookie;
1086 	uint_t			cookien;
1087 
1088 	softs->sg_max_count = 0;
1089 
1090 	for (i = 0; i < AMR_MAXCMD; i++) {
1091 
1092 		/* reset the cookien */
1093 		cookien = 0;
1094 
1095 		(softs->sg_items[i]).sg_handle = NULL;
1096 		if (ddi_dma_alloc_handle(
1097 		    softs->dev_info_p,
1098 		    &addr_dma_attr,
1099 		    DDI_DMA_SLEEP,
1100 		    NULL,
1101 		    &((softs->sg_items[i]).sg_handle)) != DDI_SUCCESS) {
1102 
1103 			AMRDB_PRINT((CE_WARN,
1104 			"Cannot alloc dma handle for s/g table"));
1105 			goto error_out;
1106 		}
1107 
1108 		if (ddi_dma_mem_alloc((softs->sg_items[i]).sg_handle,
1109 		    sizeof (struct amr_sgentry) * AMR_NSEG,
1110 		    &accattr,
1111 		    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1112 		    DDI_DMA_SLEEP, NULL,
1113 		    (caddr_t *)(&(softs->sg_items[i]).sg_table),
1114 		    &len,
1115 		    &(softs->sg_items[i]).sg_acc_handle)
1116 		    != DDI_SUCCESS) {
1117 
1118 			AMRDB_PRINT((CE_WARN,
1119 			"Cannot allocate DMA memory"));
1120 			goto error_out;
1121 		}
1122 
1123 		if (ddi_dma_addr_bind_handle(
1124 		    (softs->sg_items[i]).sg_handle,
1125 		    NULL,
1126 		    (caddr_t)((softs->sg_items[i]).sg_table),
1127 		    len,
1128 		    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1129 		    DDI_DMA_SLEEP,
1130 		    NULL,
1131 		    &cookie,
1132 		    &cookien) != DDI_DMA_MAPPED) {
1133 
1134 			AMRDB_PRINT((CE_WARN,
1135 			"Cannot bind communication area for s/g table"));
1136 			goto error_out;
1137 		}
1138 
1139 		if (cookien != 1)
1140 			goto error_out;
1141 
1142 		softs->sg_items[i].sg_phyaddr = cookie.dmac_address;
1143 		softs->sg_max_count++;
1144 	}
1145 
1146 	return (DDI_SUCCESS);
1147 
1148 error_out:
1149 	/*
1150 	 * Couldn't allocate/initialize all of the sg table entries.
1151 	 * Clean up the partially-initialized entry before returning.
1152 	 */
1153 	if (cookien) {
1154 		(void) ddi_dma_unbind_handle((softs->sg_items[i]).sg_handle);
1155 	}
1156 	if ((softs->sg_items[i]).sg_acc_handle) {
1157 		(void) ddi_dma_mem_free(&((softs->sg_items[i]).sg_acc_handle));
1158 		(softs->sg_items[i]).sg_acc_handle = NULL;
1159 	}
1160 	if ((softs->sg_items[i]).sg_handle) {
1161 		(void) ddi_dma_free_handle(&((softs->sg_items[i]).sg_handle));
1162 		(softs->sg_items[i]).sg_handle = NULL;
1163 	}
1164 
1165 	/*
1166 	 * At least two sg table entries are needed. One is for regular data
1167 	 * I/O commands, the other is for poll I/O commands.
1168 	 */
1169 	return (softs->sg_max_count > 1 ? DDI_SUCCESS : DDI_FAILURE);
1170 }
1171 
1172 /*
1173  * Map/unmap (ac)'s data in the controller's addressable space as required.
1174  *
1175  * These functions may be safely called multiple times on a given command.
1176  */
1177 static void
1178 amr_setup_dmamap(struct amr_command *ac, ddi_dma_cookie_t *buffer_dma_cookiep,
1179 		int nsegments)
1180 {
1181 	struct amr_sgentry	*sg;
1182 	uint32_t		i, size;
1183 
1184 	sg = ac->sgtable;
1185 
1186 	size = 0;
1187 
1188 	ac->mailbox.mb_nsgelem = (uint8_t)nsegments;
1189 	for (i = 0; i < nsegments; i++, sg++) {
1190 		sg->sg_addr = buffer_dma_cookiep->dmac_address;
1191 		sg->sg_count = buffer_dma_cookiep->dmac_size;
1192 		size += sg->sg_count;
1193 
1194 		/*
1195 		 * There is no next cookie if the end of the current
1196 		 * window is reached. Otherwise, the next cookie
1197 		 * would be found.
1198 		 */
1199 		if ((ac->current_cookie + i + 1) != ac->num_of_cookie)
1200 			ddi_dma_nextcookie(ac->buffer_dma_handle,
1201 			    buffer_dma_cookiep);
1202 	}
1203 
1204 	ac->transfer_size = size;
1205 	ac->data_transfered += size;
1206 }
1207 
1208 
1209 /*
1210  * map the amr command for enquiry, allocate the DMA resource
1211  */
1212 static int
1213 amr_enquiry_mapcmd(struct amr_command *ac, uint32_t data_size)
1214 {
1215 	struct amr_softs	*softs = ac->ac_softs;
1216 	size_t			len;
1217 	uint_t			dma_flags;
1218 
1219 	AMRDB_PRINT((CE_NOTE, "Amr_enquiry_mapcmd called, ac=%p, flags=%x",
1220 	    (void *)ac, ac->ac_flags));
1221 
1222 	if (ac->ac_flags & AMR_CMD_DATAOUT) {
1223 		dma_flags = DDI_DMA_READ;
1224 	} else {
1225 		dma_flags = DDI_DMA_WRITE;
1226 	}
1227 
1228 	dma_flags |= DDI_DMA_CONSISTENT;
1229 
1230 	/* process the DMA by address bind mode */
1231 	if (ddi_dma_alloc_handle(softs->dev_info_p,
1232 	    &addr_dma_attr, DDI_DMA_SLEEP, NULL,
1233 	    &ac->buffer_dma_handle) !=
1234 	    DDI_SUCCESS) {
1235 
1236 		AMRDB_PRINT((CE_WARN,
1237 		"Cannot allocate addr DMA tag"));
1238 		goto error_out;
1239 	}
1240 
1241 	if (ddi_dma_mem_alloc(ac->buffer_dma_handle,
1242 	    data_size,
1243 	    &accattr,
1244 	    dma_flags,
1245 	    DDI_DMA_SLEEP,
1246 	    NULL,
1247 	    (caddr_t *)&ac->ac_data,
1248 	    &len,
1249 	    &ac->buffer_acc_handle) !=
1250 	    DDI_SUCCESS) {
1251 
1252 		AMRDB_PRINT((CE_WARN,
1253 		"Cannot allocate DMA memory"));
1254 		goto error_out;
1255 	}
1256 
1257 	if ((ddi_dma_addr_bind_handle(
1258 	    ac->buffer_dma_handle,
1259 	    NULL, ac->ac_data, len, dma_flags,
1260 	    DDI_DMA_SLEEP, NULL, &ac->buffer_dma_cookie,
1261 	    &ac->num_of_cookie)) != DDI_DMA_MAPPED) {
1262 
1263 		AMRDB_PRINT((CE_WARN,
1264 		    "Cannot bind addr for dma"));
1265 		goto error_out;
1266 	}
1267 
1268 	ac->ac_dataphys = (&ac->buffer_dma_cookie)->dmac_address;
1269 
1270 	((struct amr_mailbox *)&(ac->mailbox))->mb_param = 0;
1271 	ac->mailbox.mb_nsgelem = 0;
1272 	ac->mailbox.mb_physaddr = ac->ac_dataphys;
1273 
1274 	ac->ac_flags |= AMR_CMD_MAPPED;
1275 
1276 	return (DDI_SUCCESS);
1277 
1278 error_out:
1279 	if (ac->num_of_cookie)
1280 		(void) ddi_dma_unbind_handle(ac->buffer_dma_handle);
1281 	if (ac->buffer_acc_handle) {
1282 		ddi_dma_mem_free(&ac->buffer_acc_handle);
1283 		ac->buffer_acc_handle = NULL;
1284 	}
1285 	if (ac->buffer_dma_handle) {
1286 		(void) ddi_dma_free_handle(&ac->buffer_dma_handle);
1287 		ac->buffer_dma_handle = NULL;
1288 	}
1289 
1290 	return (DDI_FAILURE);
1291 }
1292 
1293 /*
1294  * unmap the amr command for enquiry, free the DMA resource
1295  */
1296 static void
1297 amr_enquiry_unmapcmd(struct amr_command *ac)
1298 {
1299 	AMRDB_PRINT((CE_NOTE, "Amr_enquiry_unmapcmd called, ac=%p",
1300 	    (void *)ac));
1301 
1302 	/* if the command involved data at all and was mapped */
1303 	if ((ac->ac_flags & AMR_CMD_MAPPED) && ac->ac_data) {
1304 		if (ac->buffer_dma_handle)
1305 			(void) ddi_dma_unbind_handle(
1306 			    ac->buffer_dma_handle);
1307 		if (ac->buffer_acc_handle) {
1308 			ddi_dma_mem_free(&ac->buffer_acc_handle);
1309 			ac->buffer_acc_handle = NULL;
1310 		}
1311 		if (ac->buffer_dma_handle) {
1312 			(void) ddi_dma_free_handle(
1313 			    &ac->buffer_dma_handle);
1314 			ac->buffer_dma_handle = NULL;
1315 		}
1316 	}
1317 
1318 	ac->ac_flags &= ~AMR_CMD_MAPPED;
1319 }
1320 
1321 /*
1322  * map the amr command, allocate the DMA resource
1323  */
1324 static int
1325 amr_mapcmd(struct amr_command *ac, int (*callback)(), caddr_t arg)
1326 {
1327 	uint_t	dma_flags;
1328 	off_t	off;
1329 	size_t	len;
1330 	int	error;
1331 	int	(*cb)(caddr_t);
1332 
1333 	AMRDB_PRINT((CE_NOTE, "Amr_mapcmd called, ac=%p, flags=%x",
1334 	    (void *)ac, ac->ac_flags));
1335 
1336 	if (ac->ac_flags & AMR_CMD_DATAOUT) {
1337 		dma_flags = DDI_DMA_READ;
1338 	} else {
1339 		dma_flags = DDI_DMA_WRITE;
1340 	}
1341 
1342 	if (ac->ac_flags & AMR_CMD_PKT_CONSISTENT) {
1343 		dma_flags |= DDI_DMA_CONSISTENT;
1344 	}
1345 	if (ac->ac_flags & AMR_CMD_PKT_DMA_PARTIAL) {
1346 		dma_flags |= DDI_DMA_PARTIAL;
1347 	}
1348 
1349 	if ((!(ac->ac_flags & AMR_CMD_MAPPED)) && (ac->ac_buf == NULL)) {
1350 		ac->ac_flags |= AMR_CMD_MAPPED;
1351 		return (DDI_SUCCESS);
1352 	}
1353 
1354 	cb = (callback == NULL_FUNC) ? DDI_DMA_DONTWAIT : DDI_DMA_SLEEP;
1355 
1356 	/* if the command involves data at all, and hasn't been mapped */
1357 	if (!(ac->ac_flags & AMR_CMD_MAPPED)) {
1358 		/* process the DMA by buffer bind mode */
1359 		error = ddi_dma_buf_bind_handle(ac->buffer_dma_handle,
1360 		    ac->ac_buf,
1361 		    dma_flags,
1362 		    cb,
1363 		    arg,
1364 		    &ac->buffer_dma_cookie,
1365 		    &ac->num_of_cookie);
1366 		switch (error) {
1367 		case DDI_DMA_PARTIAL_MAP:
1368 			if (ddi_dma_numwin(ac->buffer_dma_handle,
1369 			    &ac->num_of_win) == DDI_FAILURE) {
1370 
1371 				AMRDB_PRINT((CE_WARN,
1372 				    "Cannot get dma num win"));
1373 				(void) ddi_dma_unbind_handle(
1374 				    ac->buffer_dma_handle);
1375 				(void) ddi_dma_free_handle(
1376 				    &ac->buffer_dma_handle);
1377 				ac->buffer_dma_handle = NULL;
1378 				return (DDI_FAILURE);
1379 			}
1380 			ac->current_win = 0;
1381 			break;
1382 
1383 		case DDI_DMA_MAPPED:
1384 			ac->num_of_win = 1;
1385 			ac->current_win = 0;
1386 			break;
1387 
1388 		default:
1389 			AMRDB_PRINT((CE_WARN,
1390 			    "Cannot bind buf for dma"));
1391 
1392 			(void) ddi_dma_free_handle(
1393 			    &ac->buffer_dma_handle);
1394 			ac->buffer_dma_handle = NULL;
1395 			return (DDI_FAILURE);
1396 		}
1397 
1398 		ac->current_cookie = 0;
1399 
1400 		ac->ac_flags |= AMR_CMD_MAPPED;
1401 	} else if (ac->current_cookie == AMR_LAST_COOKIE_TAG) {
1402 		/* get the next window */
1403 		ac->current_win++;
1404 		(void) ddi_dma_getwin(ac->buffer_dma_handle,
1405 		    ac->current_win, &off, &len,
1406 		    &ac->buffer_dma_cookie,
1407 		    &ac->num_of_cookie);
1408 		ac->current_cookie = 0;
1409 	}
1410 
1411 	if ((ac->num_of_cookie - ac->current_cookie) > AMR_NSEG) {
1412 		amr_setup_dmamap(ac, &ac->buffer_dma_cookie, AMR_NSEG);
1413 		ac->current_cookie += AMR_NSEG;
1414 	} else {
1415 		amr_setup_dmamap(ac, &ac->buffer_dma_cookie,
1416 		    ac->num_of_cookie - ac->current_cookie);
1417 		ac->current_cookie = AMR_LAST_COOKIE_TAG;
1418 	}
1419 
1420 	return (DDI_SUCCESS);
1421 }
1422 
1423 /*
1424  * unmap the amr command, free the DMA resource
1425  */
1426 static void
1427 amr_unmapcmd(struct amr_command *ac)
1428 {
1429 	AMRDB_PRINT((CE_NOTE, "Amr_unmapcmd called, ac=%p",
1430 	    (void *)ac));
1431 
1432 	/* if the command involved data at all and was mapped */
1433 	if ((ac->ac_flags & AMR_CMD_MAPPED) &&
1434 	    ac->ac_buf && ac->buffer_dma_handle)
1435 		(void) ddi_dma_unbind_handle(ac->buffer_dma_handle);
1436 
1437 	ac->ac_flags &= ~AMR_CMD_MAPPED;
1438 }
1439 
1440 static int
1441 amr_setup_tran(dev_info_t  *dip, struct amr_softs *softp)
1442 {
1443 	softp->hba_tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
1444 
1445 	/*
1446 	 * hba_private always points to the amr_softs struct
1447 	 */
1448 	softp->hba_tran->tran_hba_private	= softp;
1449 	softp->hba_tran->tran_tgt_init		= amr_tran_tgt_init;
1450 	softp->hba_tran->tran_tgt_probe		= scsi_hba_probe;
1451 	softp->hba_tran->tran_start		= amr_tran_start;
1452 	softp->hba_tran->tran_reset		= amr_tran_reset;
1453 	softp->hba_tran->tran_getcap		= amr_tran_getcap;
1454 	softp->hba_tran->tran_setcap		= amr_tran_setcap;
1455 	softp->hba_tran->tran_init_pkt		= amr_tran_init_pkt;
1456 	softp->hba_tran->tran_destroy_pkt	= amr_tran_destroy_pkt;
1457 	softp->hba_tran->tran_dmafree		= amr_tran_dmafree;
1458 	softp->hba_tran->tran_sync_pkt		= amr_tran_sync_pkt;
1459 	softp->hba_tran->tran_abort		= NULL;
1460 	softp->hba_tran->tran_tgt_free		= NULL;
1461 	softp->hba_tran->tran_quiesce		= NULL;
1462 	softp->hba_tran->tran_unquiesce		= NULL;
1463 	softp->hba_tran->tran_sd		= NULL;
1464 
1465 	if (scsi_hba_attach_setup(dip, &buffer_dma_attr, softp->hba_tran,
1466 	    SCSI_HBA_TRAN_CLONE) != DDI_SUCCESS) {
1467 		scsi_hba_tran_free(softp->hba_tran);
1468 		softp->hba_tran = NULL;
1469 		return (DDI_FAILURE);
1470 	} else {
1471 		return (DDI_SUCCESS);
1472 	}
1473 }
1474 
1475 /*ARGSUSED*/
1476 static int
1477 amr_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
1478 	scsi_hba_tran_t *tran, struct scsi_device *sd)
1479 {
1480 	struct amr_softs	*softs;
1481 	ushort_t		target = sd->sd_address.a_target;
1482 	uchar_t			lun = sd->sd_address.a_lun;
1483 
1484 	softs = (struct amr_softs *)
1485 	    (sd->sd_address.a_hba_tran->tran_hba_private);
1486 
1487 	if ((lun == 0) && (target < AMR_MAXLD))
1488 		if (softs->logic_drive[target].al_state != AMR_LDRV_OFFLINE)
1489 			return (DDI_SUCCESS);
1490 
1491 	return (DDI_FAILURE);
1492 }
1493 
1494 static int
1495 amr_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt)
1496 {
1497 	struct amr_softs	*softs;
1498 	struct buf		*bp = NULL;
1499 	union scsi_cdb		*cdbp = (union scsi_cdb *)pkt->pkt_cdbp;
1500 	int			ret;
1501 	uint32_t		capacity;
1502 	struct amr_command	*ac;
1503 
1504 	AMRDB_PRINT((CE_NOTE, "amr_tran_start, cmd=%X,target=%d,lun=%d",
1505 	    cdbp->scc_cmd, ap->a_target, ap->a_lun));
1506 
1507 	softs = (struct amr_softs *)(ap->a_hba_tran->tran_hba_private);
1508 	if ((ap->a_lun != 0) || (ap->a_target >= AMR_MAXLD) ||
1509 	    (softs->logic_drive[ap->a_target].al_state ==
1510 	    AMR_LDRV_OFFLINE)) {
1511 		cmn_err(CE_WARN, "target or lun is not correct!");
1512 		ret = TRAN_BADPKT;
1513 		return (ret);
1514 	}
1515 
1516 	ac = (struct amr_command *)pkt->pkt_ha_private;
1517 	bp = ac->ac_buf;
1518 
1519 	AMRDB_PRINT((CE_NOTE, "scsi cmd accepted, cmd=%X", cdbp->scc_cmd));
1520 
1521 	switch (cdbp->scc_cmd) {
1522 	case SCMD_READ:		/* read		*/
1523 	case SCMD_READ_G1:	/* read	g1	*/
1524 	case SCMD_READ_BUFFER:	/* read buffer	*/
1525 	case SCMD_WRITE:	/* write	*/
1526 	case SCMD_WRITE_G1:	/* write g1	*/
1527 	case SCMD_WRITE_BUFFER:	/* write buffer	*/
1528 		amr_rw_command(softs, pkt, ap->a_target);
1529 
1530 		if (pkt->pkt_flags & FLAG_NOINTR) {
1531 			(void) amr_poll_command(ac);
1532 			pkt->pkt_state |= (STATE_GOT_BUS
1533 			    | STATE_GOT_TARGET
1534 			    | STATE_SENT_CMD
1535 			    | STATE_XFERRED_DATA);
1536 			*pkt->pkt_scbp = 0;
1537 			pkt->pkt_statistics |= STAT_SYNC;
1538 			pkt->pkt_reason = CMD_CMPLT;
1539 		} else {
1540 			mutex_enter(&softs->queue_mutex);
1541 			if (softs->waiting_q_head == NULL) {
1542 				ac->ac_prev = NULL;
1543 				ac->ac_next = NULL;
1544 				softs->waiting_q_head = ac;
1545 				softs->waiting_q_tail = ac;
1546 			} else {
1547 				ac->ac_next = NULL;
1548 				ac->ac_prev = softs->waiting_q_tail;
1549 				softs->waiting_q_tail->ac_next = ac;
1550 				softs->waiting_q_tail = ac;
1551 			}
1552 			mutex_exit(&softs->queue_mutex);
1553 			amr_start_waiting_queue((void *)softs);
1554 		}
1555 		ret = TRAN_ACCEPT;
1556 		break;
1557 
1558 	case SCMD_INQUIRY: /* inquiry */
1559 		if (bp && bp->b_un.b_addr && bp->b_bcount) {
1560 			struct scsi_inquiry inqp;
1561 			uint8_t *sinq_p = (uint8_t *)&inqp;
1562 
1563 			bzero(&inqp, sizeof (struct scsi_inquiry));
1564 
1565 			if (((char *)cdbp)[1] || ((char *)cdbp)[2]) {
1566 				/*
1567 				 * The EVDP and pagecode is
1568 				 * not supported
1569 				 */
1570 				sinq_p[1] = 0xFF;
1571 				sinq_p[2] = 0x0;
1572 			} else {
1573 				inqp.inq_len = AMR_INQ_ADDITIONAL_LEN;
1574 				inqp.inq_ansi = AMR_INQ_ANSI_VER;
1575 				inqp.inq_rdf = AMR_INQ_RESP_DATA_FORMAT;
1576 				/* Enable Tag Queue */
1577 				inqp.inq_cmdque = 1;
1578 				bcopy("MegaRaid", inqp.inq_vid,
1579 				    sizeof (inqp.inq_vid));
1580 				bcopy(softs->amr_product_info.pi_product_name,
1581 				    inqp.inq_pid,
1582 				    AMR_PRODUCT_INFO_SIZE);
1583 				bcopy(softs->amr_product_info.pi_firmware_ver,
1584 				    inqp.inq_revision,
1585 				    AMR_FIRMWARE_VER_SIZE);
1586 			}
1587 
1588 			amr_unmapcmd(ac);
1589 
1590 			if (bp->b_flags & (B_PHYS | B_PAGEIO))
1591 				bp_mapin(bp);
1592 			bcopy(&inqp, bp->b_un.b_addr,
1593 			    sizeof (struct scsi_inquiry));
1594 
1595 			pkt->pkt_state |= STATE_XFERRED_DATA;
1596 		}
1597 		pkt->pkt_reason = CMD_CMPLT;
1598 		pkt->pkt_state |= (STATE_GOT_BUS
1599 		    | STATE_GOT_TARGET
1600 		    | STATE_SENT_CMD);
1601 		*pkt->pkt_scbp = 0;
1602 		ret = TRAN_ACCEPT;
1603 		if (!(pkt->pkt_flags & FLAG_NOINTR))
1604 			(*pkt->pkt_comp)(pkt);
1605 		break;
1606 
1607 	case SCMD_READ_CAPACITY: /* read capacity */
1608 		if (bp && bp->b_un.b_addr && bp->b_bcount) {
1609 			struct scsi_capacity cp;
1610 
1611 			capacity = softs->logic_drive[ap->a_target].al_size - 1;
1612 			cp.capacity = BE_32(capacity);
1613 			cp.lbasize = BE_32(512);
1614 
1615 			amr_unmapcmd(ac);
1616 
1617 			if (bp->b_flags & (B_PHYS | B_PAGEIO))
1618 				bp_mapin(bp);
1619 			bcopy(&cp, bp->b_un.b_addr, 8);
1620 		}
1621 		pkt->pkt_reason = CMD_CMPLT;
1622 		pkt->pkt_state |= (STATE_GOT_BUS
1623 		    | STATE_GOT_TARGET
1624 		    | STATE_SENT_CMD
1625 		    | STATE_XFERRED_DATA);
1626 		*pkt->pkt_scbp = 0;
1627 		ret = TRAN_ACCEPT;
1628 		if (!(pkt->pkt_flags & FLAG_NOINTR))
1629 			(*pkt->pkt_comp)(pkt);
1630 		break;
1631 
1632 	case SCMD_MODE_SENSE:		/* mode sense */
1633 	case SCMD_MODE_SENSE_G1:	/* mode sense g1 */
1634 		amr_unmapcmd(ac);
1635 
1636 		capacity = softs->logic_drive[ap->a_target].al_size - 1;
1637 		amr_mode_sense(cdbp, bp, capacity);
1638 
1639 		pkt->pkt_reason = CMD_CMPLT;
1640 		pkt->pkt_state |= (STATE_GOT_BUS
1641 		    | STATE_GOT_TARGET
1642 		    | STATE_SENT_CMD
1643 		    | STATE_XFERRED_DATA);
1644 		*pkt->pkt_scbp = 0;
1645 		ret = TRAN_ACCEPT;
1646 		if (!(pkt->pkt_flags & FLAG_NOINTR))
1647 			(*pkt->pkt_comp)(pkt);
1648 		break;
1649 
1650 	case SCMD_TEST_UNIT_READY:	/* test unit ready */
1651 	case SCMD_REQUEST_SENSE:	/* request sense */
1652 	case SCMD_FORMAT:		/* format */
1653 	case SCMD_START_STOP:		/* start stop */
1654 	case SCMD_SYNCHRONIZE_CACHE:	/* synchronize cache */
1655 		if (bp && bp->b_un.b_addr && bp->b_bcount) {
1656 			amr_unmapcmd(ac);
1657 
1658 			if (bp->b_flags & (B_PHYS | B_PAGEIO))
1659 				bp_mapin(bp);
1660 			bzero(bp->b_un.b_addr, bp->b_bcount);
1661 
1662 			pkt->pkt_state |= STATE_XFERRED_DATA;
1663 		}
1664 		pkt->pkt_reason = CMD_CMPLT;
1665 		pkt->pkt_state |= (STATE_GOT_BUS
1666 		    | STATE_GOT_TARGET
1667 		    | STATE_SENT_CMD);
1668 		ret = TRAN_ACCEPT;
1669 		*pkt->pkt_scbp = 0;
1670 		if (!(pkt->pkt_flags & FLAG_NOINTR))
1671 			(*pkt->pkt_comp)(pkt);
1672 		break;
1673 
1674 	default: /* any other commands */
1675 		amr_unmapcmd(ac);
1676 		pkt->pkt_reason = CMD_INCOMPLETE;
1677 		pkt->pkt_state = (STATE_GOT_BUS
1678 		    | STATE_GOT_TARGET
1679 		    | STATE_SENT_CMD
1680 		    | STATE_GOT_STATUS
1681 		    | STATE_ARQ_DONE);
1682 		ret = TRAN_ACCEPT;
1683 		*pkt->pkt_scbp = 0;
1684 		amr_set_arq_data(pkt, KEY_ILLEGAL_REQUEST);
1685 		if (!(pkt->pkt_flags & FLAG_NOINTR))
1686 			(*pkt->pkt_comp)(pkt);
1687 		break;
1688 	}
1689 
1690 	return (ret);
1691 }
1692 
1693 /*
1694  * tran_reset() will reset the bus/target/adapter to support the fault recovery
1695  * functionality according to the "level" in interface. However, we got the
1696  * confirmation from LSI that these HBA cards does not support any commands to
1697  * reset bus/target/adapter/channel.
1698  *
1699  * If the tran_reset() return a FAILURE to the sd, the system will not
1700  * continue to dump the core. But core dump is an crucial method to analyze
1701  * problems in panic. Now we adopt a work around solution, that is to return
1702  * a fake SUCCESS to sd during panic, which will force the system continue
1703  * to dump core though the core may have problems in some situtation because
1704  * some on-the-fly commands will continue DMAing data to the memory.
1705  * In addition, the work around core dump method may not be performed
1706  * successfully if the panic is caused by the HBA itself. So the work around
1707  * solution is not a good example for the implementation of tran_reset(),
1708  * the most reasonable approach should send a reset command to the adapter.
1709  */
1710 /*ARGSUSED*/
1711 static int
1712 amr_tran_reset(struct scsi_address *ap, int level)
1713 {
1714 	struct amr_softs	*softs;
1715 	volatile uint32_t	done_flag;
1716 
1717 	if (ddi_in_panic()) {
1718 		softs = (struct amr_softs *)(ap->a_hba_tran->tran_hba_private);
1719 
1720 		/* Acknowledge the card if there are any significant commands */
1721 		while (softs->amr_busyslots > 0) {
1722 			AMR_DELAY((softs->mailbox->mb_busy == 0),
1723 			    AMR_RETRYCOUNT, done_flag);
1724 			if (!done_flag) {
1725 				/*
1726 				 * command not completed, indicate the
1727 				 * problem and continue get ac
1728 				 */
1729 				cmn_err(CE_WARN,
1730 				    "AMR command is not completed");
1731 				return (0);
1732 			}
1733 
1734 			AMR_QPUT_IDB(softs, softs->mbox_phyaddr | AMR_QIDB_ACK);
1735 
1736 			/* wait for the acknowledge from hardware */
1737 			AMR_BUSYWAIT(!(AMR_QGET_IDB(softs) & AMR_QIDB_ACK),
1738 			    AMR_RETRYCOUNT, done_flag);
1739 			if (!done_flag) {
1740 				/*
1741 				 * command is not completed, return from the
1742 				 * current interrupt and wait for the next one
1743 				 */
1744 				cmn_err(CE_WARN, "No answer from the hardware");
1745 
1746 				mutex_exit(&softs->cmd_mutex);
1747 				return (0);
1748 			}
1749 
1750 			softs->amr_busyslots -= softs->mailbox->mb_nstatus;
1751 		}
1752 
1753 		/* flush the controllor */
1754 		(void) amr_flush(softs);
1755 
1756 		/*
1757 		 * If the system is in panic, the tran_reset() will return a
1758 		 * fake SUCCESS to sd, then the system would continue dump the
1759 		 * core by poll commands. This is a work around for dumping
1760 		 * core in panic.
1761 		 *
1762 		 * Note: Some on-the-fly command will continue DMAing data to
1763 		 *	 the memory when the core is dumping, which may cause
1764 		 *	 some flaws in the dumped core file, so a cmn_err()
1765 		 *	 will be printed out to warn users. However, for most
1766 		 *	 cases, the core file will be fine.
1767 		 */
1768 		cmn_err(CE_WARN, "This system contains a SCSI HBA card/driver "
1769 		    "that doesn't support software reset. This "
1770 		    "means that memory being used by the HBA for "
1771 		    "DMA based reads could have been updated after "
1772 		    "we panic'd.");
1773 		return (1);
1774 	} else {
1775 		/* return failure to sd */
1776 		return (0);
1777 	}
1778 }
1779 
1780 /*ARGSUSED*/
1781 static int
1782 amr_tran_getcap(struct scsi_address *ap, char *cap, int whom)
1783 {
1784 	struct amr_softs	*softs;
1785 
1786 	/*
1787 	 * We don't allow inquiring about capabilities for other targets
1788 	 */
1789 	if (cap == NULL || whom == 0)
1790 		return (-1);
1791 
1792 	softs = ((struct amr_softs *)(ap->a_hba_tran)->tran_hba_private);
1793 
1794 	switch (scsi_hba_lookup_capstr(cap)) {
1795 	case SCSI_CAP_ARQ:
1796 		return (1);
1797 	case SCSI_CAP_GEOMETRY:
1798 		return ((AMR_DEFAULT_HEADS << 16) | AMR_DEFAULT_CYLINDERS);
1799 	case SCSI_CAP_SECTOR_SIZE:
1800 		return (AMR_DEFAULT_SECTORS);
1801 	case SCSI_CAP_TOTAL_SECTORS:
1802 		/* number of sectors */
1803 		return (softs->logic_drive[ap->a_target].al_size);
1804 	case SCSI_CAP_UNTAGGED_QING:
1805 	case SCSI_CAP_TAGGED_QING:
1806 		return (1);
1807 	default:
1808 		return (-1);
1809 	}
1810 }
1811 
1812 /*ARGSUSED*/
1813 static int
1814 amr_tran_setcap(struct scsi_address *ap, char *cap, int value,
1815 		int whom)
1816 {
1817 	/*
1818 	 * We don't allow setting capabilities for other targets
1819 	 */
1820 	if (cap == NULL || whom == 0) {
1821 		AMRDB_PRINT((CE_NOTE,
1822 		    "Set Cap not supported, string = %s, whom=%d",
1823 		    cap, whom));
1824 		return (-1);
1825 	}
1826 
1827 	switch (scsi_hba_lookup_capstr(cap)) {
1828 	case SCSI_CAP_ARQ:
1829 		return (1);
1830 	case SCSI_CAP_TOTAL_SECTORS:
1831 		return (1);
1832 	case SCSI_CAP_SECTOR_SIZE:
1833 		return (1);
1834 	case SCSI_CAP_UNTAGGED_QING:
1835 	case SCSI_CAP_TAGGED_QING:
1836 		return ((value == 1) ? 1 : 0);
1837 	default:
1838 		return (0);
1839 	}
1840 }
1841 
1842 static struct scsi_pkt *
1843 amr_tran_init_pkt(struct scsi_address *ap,
1844     struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
1845     int tgtlen, int flags, int (*callback)(), caddr_t arg)
1846 {
1847 	struct amr_softs	*softs;
1848 	struct amr_command	*ac;
1849 	uint32_t		slen;
1850 
1851 	softs = (struct amr_softs *)(ap->a_hba_tran->tran_hba_private);
1852 
1853 	if ((ap->a_lun != 0)||(ap->a_target >= AMR_MAXLD)||
1854 	    (softs->logic_drive[ap->a_target].al_state ==
1855 	    AMR_LDRV_OFFLINE)) {
1856 		return (NULL);
1857 	}
1858 
1859 	if (pkt == NULL) {
1860 		/* force auto request sense */
1861 		slen = MAX(statuslen, sizeof (struct scsi_arq_status));
1862 
1863 		pkt = scsi_hba_pkt_alloc(softs->dev_info_p, ap, cmdlen,
1864 		    slen, tgtlen, sizeof (struct amr_command),
1865 		    callback, arg);
1866 		if (pkt == NULL) {
1867 			AMRDB_PRINT((CE_WARN, "scsi_hba_pkt_alloc failed"));
1868 			return (NULL);
1869 		}
1870 		pkt->pkt_address	= *ap;
1871 		pkt->pkt_comp		= (void (*)())NULL;
1872 		pkt->pkt_time		= 0;
1873 		pkt->pkt_resid		= 0;
1874 		pkt->pkt_statistics	= 0;
1875 		pkt->pkt_reason		= 0;
1876 
1877 		ac = (struct amr_command *)pkt->pkt_ha_private;
1878 		ac->ac_buf = bp;
1879 		ac->cmdlen = cmdlen;
1880 		ac->ac_softs = softs;
1881 		ac->pkt = pkt;
1882 		ac->ac_flags &= ~AMR_CMD_GOT_SLOT;
1883 		ac->ac_flags &= ~AMR_CMD_BUSY;
1884 
1885 		if ((bp == NULL) || (bp->b_bcount == 0)) {
1886 			return (pkt);
1887 		}
1888 
1889 		if (ddi_dma_alloc_handle(softs->dev_info_p, &buffer_dma_attr,
1890 		    DDI_DMA_SLEEP, NULL,
1891 		    &ac->buffer_dma_handle) != DDI_SUCCESS) {
1892 
1893 			AMRDB_PRINT((CE_WARN,
1894 			    "Cannot allocate buffer DMA tag"));
1895 			scsi_hba_pkt_free(ap, pkt);
1896 			return (NULL);
1897 
1898 		}
1899 
1900 	} else {
1901 		if ((bp == NULL) || (bp->b_bcount == 0)) {
1902 			return (pkt);
1903 		}
1904 		ac = (struct amr_command *)pkt->pkt_ha_private;
1905 	}
1906 
1907 	ASSERT(ac != NULL);
1908 
1909 	if (bp->b_flags & B_READ) {
1910 		ac->ac_flags |= AMR_CMD_DATAOUT;
1911 	} else {
1912 		ac->ac_flags |= AMR_CMD_DATAIN;
1913 	}
1914 
1915 	if (flags & PKT_CONSISTENT) {
1916 		ac->ac_flags |= AMR_CMD_PKT_CONSISTENT;
1917 	}
1918 
1919 	if (flags & PKT_DMA_PARTIAL) {
1920 		ac->ac_flags |= AMR_CMD_PKT_DMA_PARTIAL;
1921 	}
1922 
1923 	if (amr_mapcmd(ac, callback, arg) != DDI_SUCCESS) {
1924 		scsi_hba_pkt_free(ap, pkt);
1925 		return (NULL);
1926 	}
1927 
1928 	pkt->pkt_resid = bp->b_bcount - ac->data_transfered;
1929 
1930 	AMRDB_PRINT((CE_NOTE,
1931 	    "init pkt, pkt_resid=%d, b_bcount=%d, data_transfered=%d",
1932 	    (uint32_t)pkt->pkt_resid, (uint32_t)bp->b_bcount,
1933 	    ac->data_transfered));
1934 
1935 	ASSERT(pkt->pkt_resid >= 0);
1936 
1937 	return (pkt);
1938 }
1939 
1940 static void
1941 amr_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
1942 {
1943 	struct amr_command *ac = (struct amr_command *)pkt->pkt_ha_private;
1944 
1945 	amr_unmapcmd(ac);
1946 
1947 	if (ac->buffer_dma_handle) {
1948 		(void) ddi_dma_free_handle(&ac->buffer_dma_handle);
1949 		ac->buffer_dma_handle = NULL;
1950 	}
1951 
1952 	scsi_hba_pkt_free(ap, pkt);
1953 	AMRDB_PRINT((CE_NOTE, "Destroy pkt called"));
1954 }
1955 
1956 /*ARGSUSED*/
1957 static void
1958 amr_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
1959 {
1960 	struct amr_command *ac = (struct amr_command *)pkt->pkt_ha_private;
1961 
1962 	if (ac->buffer_dma_handle) {
1963 		(void) ddi_dma_sync(ac->buffer_dma_handle, 0, 0,
1964 		    (ac->ac_flags & AMR_CMD_DATAIN) ?
1965 		    DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU);
1966 	}
1967 }
1968 
1969 /*ARGSUSED*/
1970 static void
1971 amr_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
1972 {
1973 	struct amr_command *ac = (struct amr_command *)pkt->pkt_ha_private;
1974 
1975 	if (ac->ac_flags & AMR_CMD_MAPPED) {
1976 		(void) ddi_dma_unbind_handle(ac->buffer_dma_handle);
1977 		(void) ddi_dma_free_handle(&ac->buffer_dma_handle);
1978 		ac->buffer_dma_handle = NULL;
1979 		ac->ac_flags &= ~AMR_CMD_MAPPED;
1980 	}
1981 
1982 }
1983 
1984 /*ARGSUSED*/
1985 static void
1986 amr_rw_command(struct amr_softs *softs, struct scsi_pkt *pkt, int target)
1987 {
1988 	struct amr_command	*ac = (struct amr_command *)pkt->pkt_ha_private;
1989 	union scsi_cdb		*cdbp = (union scsi_cdb *)pkt->pkt_cdbp;
1990 	uint8_t			cmd;
1991 
1992 	if (ac->ac_flags & AMR_CMD_DATAOUT) {
1993 		cmd = AMR_CMD_LREAD;
1994 	} else {
1995 		cmd = AMR_CMD_LWRITE;
1996 	}
1997 
1998 	ac->mailbox.mb_command = cmd;
1999 	ac->mailbox.mb_blkcount =
2000 	    (ac->transfer_size + AMR_BLKSIZE - 1)/AMR_BLKSIZE;
2001 	ac->mailbox.mb_lba = (ac->cmdlen == 10) ?
2002 	    GETG1ADDR(cdbp) : GETG0ADDR(cdbp);
2003 	ac->mailbox.mb_drive = (uint8_t)target;
2004 }
2005 
2006 static void
2007 amr_mode_sense(union scsi_cdb *cdbp, struct buf *bp, unsigned int capacity)
2008 {
2009 	uchar_t			pagecode;
2010 	struct mode_format	*page3p;
2011 	struct mode_geometry	*page4p;
2012 	struct mode_header	*headerp;
2013 	uint32_t		ncyl;
2014 
2015 	if (!(bp && bp->b_un.b_addr && bp->b_bcount))
2016 		return;
2017 
2018 	if (bp->b_flags & (B_PHYS | B_PAGEIO))
2019 		bp_mapin(bp);
2020 
2021 	pagecode = cdbp->cdb_un.sg.scsi[0];
2022 	switch (pagecode) {
2023 	case SD_MODE_SENSE_PAGE3_CODE:
2024 		headerp = (struct mode_header *)(bp->b_un.b_addr);
2025 		headerp->bdesc_length = MODE_BLK_DESC_LENGTH;
2026 
2027 		page3p = (struct mode_format *)((caddr_t)headerp +
2028 		    MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH);
2029 		page3p->mode_page.code = BE_8(SD_MODE_SENSE_PAGE3_CODE);
2030 		page3p->mode_page.length = BE_8(sizeof (struct mode_format));
2031 		page3p->data_bytes_sect = BE_16(AMR_DEFAULT_SECTORS);
2032 		page3p->sect_track = BE_16(AMR_DEFAULT_CYLINDERS);
2033 
2034 		return;
2035 
2036 	case SD_MODE_SENSE_PAGE4_CODE:
2037 		headerp = (struct mode_header *)(bp->b_un.b_addr);
2038 		headerp->bdesc_length = MODE_BLK_DESC_LENGTH;
2039 
2040 		page4p = (struct mode_geometry *)((caddr_t)headerp +
2041 		    MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH);
2042 		page4p->mode_page.code = BE_8(SD_MODE_SENSE_PAGE4_CODE);
2043 		page4p->mode_page.length = BE_8(sizeof (struct mode_geometry));
2044 		page4p->heads = BE_8(AMR_DEFAULT_HEADS);
2045 		page4p->rpm = BE_16(AMR_DEFAULT_ROTATIONS);
2046 
2047 		ncyl = capacity / (AMR_DEFAULT_HEADS*AMR_DEFAULT_CYLINDERS);
2048 		page4p->cyl_lb = BE_8(ncyl & 0xff);
2049 		page4p->cyl_mb = BE_8((ncyl >> 8) & 0xff);
2050 		page4p->cyl_ub = BE_8((ncyl >> 16) & 0xff);
2051 
2052 		return;
2053 	default:
2054 		bzero(bp->b_un.b_addr, bp->b_bcount);
2055 		return;
2056 	}
2057 }
2058 
2059 static void
2060 amr_set_arq_data(struct scsi_pkt *pkt, uchar_t key)
2061 {
2062 	struct scsi_arq_status *arqstat;
2063 
2064 	arqstat = (struct scsi_arq_status *)(pkt->pkt_scbp);
2065 	arqstat->sts_status.sts_chk = 1; /* CHECK CONDITION */
2066 	arqstat->sts_rqpkt_reason = CMD_CMPLT;
2067 	arqstat->sts_rqpkt_resid = 0;
2068 	arqstat->sts_rqpkt_state = STATE_GOT_BUS | STATE_GOT_TARGET |
2069 	    STATE_SENT_CMD | STATE_XFERRED_DATA;
2070 	arqstat->sts_rqpkt_statistics = 0;
2071 	arqstat->sts_sensedata.es_valid = 1;
2072 	arqstat->sts_sensedata.es_class = CLASS_EXTENDED_SENSE;
2073 	arqstat->sts_sensedata.es_key = key;
2074 }
2075 
2076 static void
2077 amr_start_waiting_queue(void *softp)
2078 {
2079 	uint32_t		slot;
2080 	struct amr_command	*ac;
2081 	volatile uint32_t	done_flag;
2082 	struct amr_softs	*softs = (struct amr_softs *)softp;
2083 
2084 	/* only one command allowed at the same time */
2085 	mutex_enter(&softs->queue_mutex);
2086 	mutex_enter(&softs->cmd_mutex);
2087 
2088 	while ((ac = softs->waiting_q_head) != NULL) {
2089 		/*
2090 		 * Find an available slot, the last slot is
2091 		 * occupied by poll I/O command.
2092 		 */
2093 		for (slot = 0; slot < (softs->sg_max_count - 1); slot++) {
2094 			if (softs->busycmd[slot] == NULL) {
2095 				if (AMR_QGET_IDB(softs) & AMR_QIDB_SUBMIT) {
2096 					/*
2097 					 * only one command allowed at the
2098 					 * same time
2099 					 */
2100 					mutex_exit(&softs->cmd_mutex);
2101 					mutex_exit(&softs->queue_mutex);
2102 					return;
2103 				}
2104 
2105 				ac->ac_timestamp = ddi_get_time();
2106 
2107 				if (!(ac->ac_flags & AMR_CMD_GOT_SLOT)) {
2108 
2109 					softs->busycmd[slot] = ac;
2110 					ac->ac_slot = slot;
2111 					softs->amr_busyslots++;
2112 
2113 					bcopy(ac->sgtable,
2114 					    softs->sg_items[slot].sg_table,
2115 					    sizeof (struct amr_sgentry) *
2116 					    AMR_NSEG);
2117 
2118 					(void) ddi_dma_sync(
2119 					    softs->sg_items[slot].sg_handle,
2120 					    0, 0, DDI_DMA_SYNC_FORDEV);
2121 
2122 					ac->mailbox.mb_physaddr =
2123 					    softs->sg_items[slot].sg_phyaddr;
2124 				}
2125 
2126 				/* take the cmd from the queue */
2127 				softs->waiting_q_head = ac->ac_next;
2128 
2129 				ac->mailbox.mb_ident = ac->ac_slot + 1;
2130 				ac->mailbox.mb_busy = 1;
2131 				ac->ac_next = NULL;
2132 				ac->ac_prev = NULL;
2133 				ac->ac_flags |= AMR_CMD_GOT_SLOT;
2134 
2135 				/* clear the poll/ack fields in the mailbox */
2136 				softs->mailbox->mb_poll = 0;
2137 				softs->mailbox->mb_ack = 0;
2138 
2139 				AMR_DELAY((softs->mailbox->mb_busy == 0),
2140 				    AMR_RETRYCOUNT, done_flag);
2141 				if (!done_flag) {
2142 					/*
2143 					 * command not completed, indicate the
2144 					 * problem and continue get ac
2145 					 */
2146 					cmn_err(CE_WARN,
2147 					    "AMR command is not completed");
2148 					break;
2149 				}
2150 
2151 				bcopy(&ac->mailbox, (void *)softs->mailbox,
2152 				    AMR_MBOX_CMDSIZE);
2153 				ac->ac_flags |= AMR_CMD_BUSY;
2154 
2155 				(void) ddi_dma_sync(softs->mbox_dma_handle,
2156 				    0, 0, DDI_DMA_SYNC_FORDEV);
2157 
2158 				AMR_QPUT_IDB(softs,
2159 				    softs->mbox_phyaddr | AMR_QIDB_SUBMIT);
2160 
2161 				/*
2162 				 * current ac is submitted
2163 				 * so quit 'for-loop' to get next ac
2164 				 */
2165 				break;
2166 			}
2167 		}
2168 
2169 		/* no slot, finish our task */
2170 		if (slot == softs->maxio)
2171 			break;
2172 	}
2173 
2174 	/* only one command allowed at the same time */
2175 	mutex_exit(&softs->cmd_mutex);
2176 	mutex_exit(&softs->queue_mutex);
2177 }
2178 
2179 static void
2180 amr_done(struct amr_softs *softs)
2181 {
2182 
2183 	uint32_t		i, idx;
2184 	volatile uint32_t	done_flag;
2185 	struct amr_mailbox	*mbox, mbsave;
2186 	struct amr_command	*ac, *head, *tail;
2187 
2188 	head = tail = NULL;
2189 
2190 	AMR_QPUT_ODB(softs, AMR_QODB_READY);
2191 
2192 	/* acknowledge interrupt */
2193 	(void) AMR_QGET_ODB(softs);
2194 
2195 	mutex_enter(&softs->cmd_mutex);
2196 
2197 	if (softs->mailbox->mb_nstatus != 0) {
2198 		(void) ddi_dma_sync(softs->mbox_dma_handle,
2199 		    0, 0, DDI_DMA_SYNC_FORCPU);
2200 
2201 		/* save mailbox, which contains a list of completed commands */
2202 		bcopy((void *)(uintptr_t)(volatile void *)softs->mailbox,
2203 		    &mbsave, sizeof (mbsave));
2204 
2205 		mbox = &mbsave;
2206 
2207 		AMR_QPUT_IDB(softs, softs->mbox_phyaddr | AMR_QIDB_ACK);
2208 
2209 		/* wait for the acknowledge from hardware */
2210 		AMR_BUSYWAIT(!(AMR_QGET_IDB(softs) & AMR_QIDB_ACK),
2211 		    AMR_RETRYCOUNT, done_flag);
2212 		if (!done_flag) {
2213 			/*
2214 			 * command is not completed, return from the current
2215 			 * interrupt and wait for the next one
2216 			 */
2217 			cmn_err(CE_WARN, "No answer from the hardware");
2218 
2219 			mutex_exit(&softs->cmd_mutex);
2220 			return;
2221 		}
2222 
2223 		for (i = 0; i < mbox->mb_nstatus; i++) {
2224 			idx = mbox->mb_completed[i] - 1;
2225 			ac = softs->busycmd[idx];
2226 
2227 			if (ac != NULL) {
2228 				/* pull the command from the busy index */
2229 				softs->busycmd[idx] = NULL;
2230 				if (softs->amr_busyslots > 0)
2231 					softs->amr_busyslots--;
2232 				if (softs->amr_busyslots == 0)
2233 					cv_broadcast(&softs->cmd_cv);
2234 
2235 				ac->ac_flags &= ~AMR_CMD_BUSY;
2236 				ac->ac_flags &= ~AMR_CMD_GOT_SLOT;
2237 				ac->ac_status = mbox->mb_status;
2238 
2239 				/* enqueue here */
2240 				if (head) {
2241 					tail->ac_next = ac;
2242 					tail = ac;
2243 					tail->ac_next = NULL;
2244 				} else {
2245 					tail = head = ac;
2246 					ac->ac_next = NULL;
2247 				}
2248 			} else {
2249 				AMRDB_PRINT((CE_WARN,
2250 				    "ac in mailbox is NULL!"));
2251 			}
2252 		}
2253 	} else {
2254 		AMRDB_PRINT((CE_WARN, "mailbox is not ready for copy out!"));
2255 	}
2256 
2257 	mutex_exit(&softs->cmd_mutex);
2258 
2259 	if (head != NULL) {
2260 		amr_call_pkt_comp(head);
2261 	}
2262 
2263 	/* dispatch a thread to process the pending I/O if there is any */
2264 	if ((ddi_taskq_dispatch(softs->amr_taskq, amr_start_waiting_queue,
2265 	    (void *)softs, DDI_NOSLEEP)) != DDI_SUCCESS) {
2266 		cmn_err(CE_WARN, "No memory available to dispatch taskq");
2267 	}
2268 }
2269 
2270 static void
2271 amr_call_pkt_comp(register struct amr_command *head)
2272 {
2273 	register struct scsi_pkt	*pkt;
2274 	register struct amr_command	*ac, *localhead;
2275 
2276 	localhead = head;
2277 
2278 	while (localhead) {
2279 		ac = localhead;
2280 		localhead = ac->ac_next;
2281 		ac->ac_next = NULL;
2282 
2283 		pkt = ac->pkt;
2284 		*pkt->pkt_scbp = 0;
2285 
2286 		if (ac->ac_status == AMR_STATUS_SUCCESS) {
2287 			pkt->pkt_state |= (STATE_GOT_BUS
2288 			    | STATE_GOT_TARGET
2289 			    | STATE_SENT_CMD
2290 			    | STATE_XFERRED_DATA);
2291 			pkt->pkt_reason = CMD_CMPLT;
2292 		} else {
2293 			pkt->pkt_state |= STATE_GOT_BUS
2294 			    | STATE_ARQ_DONE;
2295 			pkt->pkt_reason = CMD_INCOMPLETE;
2296 			amr_set_arq_data(pkt, KEY_HARDWARE_ERROR);
2297 		}
2298 
2299 		if (!(pkt->pkt_flags & FLAG_NOINTR) &&
2300 		    pkt->pkt_comp) {
2301 			(*pkt->pkt_comp)(pkt);
2302 		}
2303 	}
2304 }
2305