arcmsr.c revision 7610:79f2dce17cb6
1/*
2 *       O.S   : Solaris
3 *  FILE NAME  : arcmsr.c
4 *       BY    : Erich Chen
5 *  Description: SCSI RAID Device Driver for
6 *               ARECA RAID Host adapter
7 *
8 *  Copyright (C) 2002,2007 Areca Technology Corporation All rights reserved.
9 *  Copyright (C) 2002,2007 Erich Chen
10 *	    Web site: www.areca.com.tw
11 *	      E-mail: erich@areca.com.tw
12 *
13 *	Redistribution and use in source and binary forms, with or without
14 *	modification, are permitted provided that the following conditions
15 *	are met:
16 *	1. Redistributions of source code must retain the above copyright
17 *	   notice, this list of conditions and the following disclaimer.
18 *	2. Redistributions in binary form must reproduce the above copyright
19 *	   notice, this list of conditions and the following disclaimer in the
20 *	   documentation and/or other materials provided with the distribution.
21 *  3. The party using or redistributing the source code and binary forms
22 *     agrees to the disclaimer below and the terms and conditions set forth
23 *     herein.
24 *
25 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26 *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 *  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 *  SUCH DAMAGE.
36 */
37
38/*
39 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
40 * Use is subject to license terms.
41 */
42
43#include <sys/types.h>
44#include <sys/ddidmareq.h>
45#include <sys/scsi/scsi.h>
46#include <sys/ddi.h>
47#include <sys/sunddi.h>
48#include <sys/file.h>
49#include <sys/disp.h>
50#include <sys/signal.h>
51#include <sys/debug.h>
52#include <sys/pci.h>
53#include <sys/policy.h>
54
55#include "arcmsr.h"
56
57static int arcmsr_attach(dev_info_t *dev_info, ddi_attach_cmd_t cmd);
58static int arcmsr_cb_ioctl(dev_t dev, int ioctl_cmd, intptr_t arg,
59    int mode, cred_t *credp, int *rvalp);
60static int arcmsr_detach(dev_info_t *dev_info, ddi_detach_cmd_t cmd);
61static int arcmsr_reset(dev_info_t *resetdev, ddi_reset_cmd_t cmd);
62static int arcmsr_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt);
63static int arcmsr_tran_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
64static int arcmsr_tran_reset(struct scsi_address *ap, int level);
65static int arcmsr_tran_getcap(struct scsi_address *ap, char *cap, int whom);
66static int arcmsr_tran_setcap(struct scsi_address *ap, char *cap, int value,
67    int whom);
68static int arcmsr_tran_tgt_init(dev_info_t *host_dev_info,
69    dev_info_t *target_dev_info, scsi_hba_tran_t *hosttran,
70    struct scsi_device *sd);
71static void arcmsr_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt);
72static void arcmsr_tran_destroy_pkt(struct scsi_address *ap,
73    struct scsi_pkt *pkt);
74static void arcmsr_tran_sync_pkt(struct scsi_address *ap,
75    struct scsi_pkt *pkt);
76static struct scsi_pkt *arcmsr_tran_init_pkt(struct scsi_address *ap,
77    struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
78    int tgtlen, int flags, int (*callback)(), caddr_t arg);
79
80static uint_t arcmsr_interrupt(caddr_t arg);
81static int arcmsr_initialize(struct ACB *acb);
82static int arcmsr_dma_alloc(struct ACB *acb,
83    struct scsi_pkt *pkt, struct buf *bp, int flags, int (*callback)());
84static int arcmsr_dma_move(struct ACB *acb,
85    struct scsi_pkt *pkt, struct buf *bp);
86static void arcmsr_pcidev_disattach(struct ACB *acb);
87static void arcmsr_ccb_complete(struct CCB *ccb, int flag);
88static void arcmsr_iop_init(struct ACB *acb);
89static void arcmsr_iop_parking(struct ACB *acb);
90static void arcmsr_log(struct ACB *acb, int level, char *fmt, ...);
91static struct CCB *arcmsr_get_freeccb(struct ACB *acb);
92static void arcmsr_flush_hba_cache(struct ACB *acb);
93static void arcmsr_flush_hbb_cache(struct ACB *acb);
94static void arcmsr_stop_hba_bgrb(struct ACB *acb);
95static void arcmsr_stop_hbb_bgrb(struct ACB *acb);
96static void arcmsr_start_hba_bgrb(struct ACB *acb);
97static void arcmsr_start_hba_bgrb(struct ACB *acb);
98static void arcmsr_polling_hba_ccbdone(struct ACB *acb, struct CCB *poll_ccb);
99static void arcmsr_polling_hbb_ccbdone(struct ACB *acb, struct CCB *poll_ccb);
100static void arcmsr_build_ccb(struct CCB *ccb);
101
102
103static struct ACB *ArcMSRHBA[ARCMSR_MAX_ADAPTER];
104static int arcmsr_hba_count;
105static void *arcmsr_soft_state = NULL;
106static kmutex_t arcmsr_global_mutex;
107
108static ddi_dma_attr_t arcmsr_dma_attr = {
109	DMA_ATTR_V0,		/* ddi_dma_attr version */
110	0,			/* low DMA address range */
111	0xffffffff,		/* high DMA address range */
112	0x00ffffff,		/* DMA counter counter upper bound */
113	1,			/* DMA address alignment requirements */
114	DEFAULT_BURSTSIZE | BURST32 | BURST64,	/* burst sizes */
115	1,			/* minimum effective DMA size */
116	ARCMSR_MAX_XFER_LEN,	/* maximum DMA xfer size */
117	/*
118	 * The dma_attr_seg field supplies the limit of each Scatter/Gather
119	 * list element's "address+length". The Intel IOP331 can not use
120	 * segments over the 4G boundary due to segment boundary restrictions
121	 */
122	0x00ffffff,
123	ARCMSR_MAX_SG_ENTRIES,	/* scatter/gather list count */
124	1, 			/* device granularity */
125	DDI_DMA_FORCE_PHYSICAL	/* Bus specific DMA flags */
126};
127
128static ddi_dma_attr_t arcmsr_ccb_attr = {
129	DMA_ATTR_V0,	/* ddi_dma_attr version */
130	0,		/* low DMA address range */
131	0xffffffff,	/* high DMA address range */
132	0x00ffffff,	/* DMA counter counter upper bound */
133	1,		/* default byte alignment */
134	DEFAULT_BURSTSIZE | BURST32 | BURST64,   /* burst sizes */
135	1,		/* minimum effective DMA size */
136	0xffffffff,	/* maximum DMA xfer size */
137	0x00ffffff,	/* max segment size, segment boundary restrictions */
138	1,		/* scatter/gather list count */
139	1,		/* device granularity */
140	DDI_DMA_FORCE_PHYSICAL	/* Bus specific DMA flags */
141};
142
143static struct cb_ops arcmsr_cb_ops = {
144	scsi_hba_open,		/* open(9E) */
145	scsi_hba_close,		/* close(9E) */
146	nodev,			/* strategy(9E), returns ENXIO */
147	nodev,			/* print(9E) */
148	nodev,			/* dump(9E) Cannot be used as a dump device */
149	nodev,			/* read(9E) */
150	nodev,			/* write(9E) */
151	arcmsr_cb_ioctl,	/* ioctl(9E) */
152	nodev,			/* devmap(9E) */
153	nodev,			/* mmap(9E) */
154	nodev,			/* segmap(9E) */
155	NULL,			/* chpoll(9E) returns ENXIO */
156	nodev,			/* prop_op(9E) */
157	NULL,			/* streamtab(9S) */
158#ifdef _LP64
159	/*
160	 * cb_ops cb_flag:
161	 *	D_NEW | D_MP	compatibility flags, see conf.h
162	 *	D_MP 		flag indicates that the driver is safe for
163	 *			multi-threaded operation
164	 *	D_64BIT		flag driver properly handles 64-bit offsets
165	 */
166	D_HOTPLUG | D_MP | D_64BIT,
167#else
168	D_HOTPLUG | D_MP,
169#endif
170	CB_REV,
171	nodev,			/* aread(9E) */
172	nodev			/* awrite(9E) */
173};
174
175static struct dev_ops arcmsr_ops = {
176	DEVO_REV,		/* devo_rev */
177	0,			/* reference count */
178	nodev,			/* getinfo */
179	nulldev,		/* identify */
180	nulldev,		/* probe */
181	arcmsr_attach,		/* attach */
182	arcmsr_detach,		/* detach */
183	arcmsr_reset,		/* reset, shutdown, reboot notify */
184	&arcmsr_cb_ops,		/* driver operations */
185	NULL,			/* bus operations */
186	nulldev			/* power */
187};
188
189char _depends_on[] = "misc/scsi";
190
191static struct modldrv arcmsr_modldrv = {
192	&mod_driverops, 	/* Type of module. This is a driver. */
193	ARCMSR_DRIVER_VERSION,  /* module name, from arcmsr.h */
194	&arcmsr_ops,		/* driver ops */
195};
196
197static struct modlinkage arcmsr_modlinkage = {
198	MODREV_1,
199	&arcmsr_modldrv,
200	NULL
201};
202
203
204int
205_init(void) {
206	int ret;
207
208
209	mutex_init(&arcmsr_global_mutex, "arcmsr global mutex",
210	    MUTEX_DRIVER, NULL);
211	ret = ddi_soft_state_init(&arcmsr_soft_state,
212	    sizeof (struct ACB), ARCMSR_MAX_ADAPTER);
213	if (ret != 0) {
214		return (ret);
215	}
216	if ((ret = scsi_hba_init(&arcmsr_modlinkage)) != 0) {
217		ddi_soft_state_fini(&arcmsr_soft_state);
218		return (ret);
219	}
220
221	if ((ret = mod_install(&arcmsr_modlinkage)) != 0) {
222		mutex_destroy(&arcmsr_global_mutex);
223		scsi_hba_fini(&arcmsr_modlinkage);
224		if (arcmsr_soft_state != NULL) {
225			ddi_soft_state_fini(&arcmsr_soft_state);
226		}
227	}
228	return (ret);
229}
230
231
232int
233_fini(void) {
234	int ret;
235
236	ret = mod_remove(&arcmsr_modlinkage);
237	if (ret == 0) {
238		/* if ret = 0 , said driver can remove */
239		mutex_destroy(&arcmsr_global_mutex);
240		scsi_hba_fini(&arcmsr_modlinkage);
241		if (arcmsr_soft_state != NULL) {
242			ddi_soft_state_fini(&arcmsr_soft_state);
243		}
244	}
245	return (ret);
246}
247
248
249int
250_info(struct modinfo *modinfop) {
251	return (mod_info(&arcmsr_modlinkage, modinfop));
252}
253
254
255
256#if defined(ARCMSR_DEBUG)
257static void
258arcmsr_dump_scsi_cdb(struct scsi_address *ap, struct scsi_pkt *pkt) {
259
260	static char hex[] = "0123456789abcdef";
261	struct ACB *acb =
262	    (struct ACB *)ap->a_hba_tran->tran_hba_private;
263	struct CCB *ccb =
264	    (struct CCB *)pkt->pkt_ha_private;
265	uint8_t	*cdb = pkt->pkt_cdbp;
266	char buf [256];
267	char *p;
268	int i;
269
270
271	(void) sprintf(buf, "arcmsr%d: sgcount=%d <%d, %d> "
272	    "cdb ",
273	    ddi_get_instance(acb->dev_info), ccb->arcmsr_cdb.sgcount,
274	    ap->a_target, ap->a_lun);
275
276	p = buf + strlen(buf);
277	*p++ = '[';
278
279	for (i = 0; i < ccb->arcmsr_cdb.CdbLength; i++, cdb++) {
280		if (i != 0) {
281			*p++ = ' ';
282		}
283		*p++ = hex[(*cdb >> 4) & 0x0f];
284		*p++ = hex[*cdb & 0x0f];
285	}
286	*p++ = ']';
287	*p++ = '.';
288	*p = 0;
289	cmn_err(CE_CONT, buf);
290}
291#endif  /* ARCMSR_DEBUG */
292
293static void
294arcmsr_ccbs_timeout(void* arg) {
295
296	struct ACB *acb = (struct ACB *)arg;
297	struct CCB *ccb;
298	int i;
299	int current_time = ddi_get_time();
300
301
302	if (acb->ccboutstandingcount != 0) {
303		/* check each ccb */
304		i = ddi_dma_sync(acb->ccbs_pool_handle, 0,
305		    acb->dma_sync_size, DDI_DMA_SYNC_FORKERNEL);
306		if (i != DDI_SUCCESS) {
307			if ((acb->timeout_id != 0) &&
308			    ((acb->acb_flags & ACB_F_SCSISTOPADAPTER) == 0)) {
309				/* do pkt timeout check each 60 secs */
310				acb->timeout_id = timeout(arcmsr_ccbs_timeout,
311				    (void*)acb,
312				    (60 * drv_usectohz(1000000)));
313			}
314			return;
315		}
316		for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
317			ccb = acb->pccb_pool[i];
318			if (ccb->acb != acb) {
319				break;
320			}
321			if (ccb->startdone == ARCMSR_CCB_DONE) {
322				continue;
323			}
324			if (ccb->pkt == NULL) {
325				continue;
326			}
327			if (ccb->pkt->pkt_time == 0) {
328				continue;
329			}
330			if ((int)ccb->ccb_time >= current_time) {
331				continue;
332			}
333			if (ccb->startdone == ARCMSR_CCB_START) {
334				int id = ccb->pkt->pkt_address.a_target;
335				int lun = ccb->pkt->pkt_address.a_lun;
336
337				/*
338				 * handle outstanding command of timeout ccb
339				 */
340				ccb->pkt->pkt_reason = CMD_TIMEOUT;
341				ccb->pkt->pkt_statistics = STAT_TIMEOUT;
342
343				cmn_err(CE_CONT,
344				    "arcmsr%d: scsi target %d lun %d "
345				    "outstanding command timeout",
346				    ddi_get_instance(acb->dev_info),
347				    id, lun);
348				cmn_err(CE_CONT,
349				    "arcmsr%d: scsi target %d lun %d "
350				    "fatal error on target, device is gone",
351				    ddi_get_instance(acb->dev_info),
352				    id, lun);
353				acb->devstate[id][lun] = ARECA_RAID_GONE;
354				arcmsr_ccb_complete(ccb, 1);
355				continue;
356			}
357			ccb->ccb_time = (time_t)(ccb->pkt->pkt_time +
358			    current_time); /* adjust ccb_time of pending ccb */
359		}
360	}
361	if ((acb->timeout_id != 0) &&
362	    ((acb->acb_flags & ACB_F_SCSISTOPADAPTER) == 0)) {
363		/* do pkt timeout check each 60 secs */
364		acb->timeout_id = timeout(arcmsr_ccbs_timeout,
365		    (void*)acb, (60 * drv_usectohz(1000000)));
366	}
367}
368
369
370static uint32_t
371arcmsr_disable_allintr(struct ACB *acb) {
372
373	uint32_t intmask_org;
374
375	switch (acb->adapter_type) {
376	case ACB_ADAPTER_TYPE_A: {
377		struct HBA_msgUnit *phbamu =
378		    (struct HBA_msgUnit *)acb->pmu;
379
380		/* disable all outbound interrupt */
381		/* disable outbound message0 int */
382		intmask_org = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
383		    &phbamu->outbound_intmask) |
384		    ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE;
385		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
386		    &phbamu->outbound_intmask,
387		    intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE);
388		}
389		break;
390	case ACB_ADAPTER_TYPE_B: {
391		struct HBB_msgUnit *phbbmu =
392		    (struct HBB_msgUnit *)acb->pmu;
393
394		/* disable all outbound interrupt */
395		/* disable outbound message0 int */
396		intmask_org = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
397		    &phbbmu->hbb_doorbell->iop2drv_doorbell_mask) &
398		    (~ARCMSR_IOP2DRV_MESSAGE_CMD_DONE);
399		/* disable all interrupts */
400		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
401		    &phbbmu->hbb_doorbell->iop2drv_doorbell_mask, 0);
402		}
403		break;
404	}
405	return (intmask_org);
406}
407
408
409static void
410arcmsr_enable_allintr(struct ACB *acb, uint32_t intmask_org) {
411
412	int mask;
413
414	switch (acb->adapter_type) {
415	case ACB_ADAPTER_TYPE_A: {
416		struct HBA_msgUnit *phbamu =
417		    (struct HBA_msgUnit *)acb->pmu;
418
419		/* enable outbound Post Queue, outbound doorbell Interrupt */
420		mask = ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE |
421		    ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE);
422		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
423		    &phbamu->outbound_intmask, intmask_org & mask);
424		acb->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff;
425		}
426		break;
427	case ACB_ADAPTER_TYPE_B: {
428		struct HBB_msgUnit *phbbmu =
429		    (struct HBB_msgUnit *)acb->pmu;
430
431		/* disable ARCMSR_IOP2DRV_MESSAGE_CMD_DONE */
432		mask = (ARCMSR_IOP2DRV_DATA_WRITE_OK |
433		    ARCMSR_IOP2DRV_DATA_READ_OK | ARCMSR_IOP2DRV_CDB_DONE);
434		/* 1=interrupt enable, 0=interrupt disable */
435		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
436		    &phbbmu->hbb_doorbell->iop2drv_doorbell_mask,
437		    intmask_org | mask);
438		acb->outbound_int_enable = (intmask_org | mask) & 0x0000000f;
439		}
440		break;
441	}
442}
443
444
445static void
446arcmsr_iop_parking(struct ACB *acb) {
447
448	if (acb != NULL) {
449		/* stop adapter background rebuild */
450		if (acb->acb_flags & ACB_F_MSG_START_BGRB) {
451			uint32_t intmask_org;
452
453			acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
454			/* disable all outbound interrupt */
455			intmask_org = arcmsr_disable_allintr(acb);
456			if (acb->adapter_type == ACB_ADAPTER_TYPE_A) {
457				arcmsr_stop_hba_bgrb(acb);
458				arcmsr_flush_hba_cache(acb);
459			} else {
460				arcmsr_stop_hbb_bgrb(acb);
461				arcmsr_flush_hbb_cache(acb);
462			}
463			/*
464			 * enable outbound Post Queue
465			 * enable outbound doorbell Interrupt
466			 */
467			arcmsr_enable_allintr(acb, intmask_org);
468		}
469	}
470}
471
472
473
474static int
475arcmsr_reset(dev_info_t *resetdev, ddi_reset_cmd_t cmd) {
476
477	struct ACB *acb;
478	scsi_hba_tran_t *scsi_hba_transport;
479
480	scsi_hba_transport = (scsi_hba_tran_t *)
481	    ddi_get_driver_private(resetdev);
482
483	if (!scsi_hba_transport)
484		return (DDI_FAILURE);
485
486	acb = (struct ACB *)
487	    scsi_hba_transport->tran_hba_private;
488
489	if (!acb)
490		return (DDI_FAILURE);
491
492	if ((cmd == RESET_LUN) ||
493	    (cmd == RESET_BUS) ||
494	    (cmd == RESET_TARGET))
495		arcmsr_log(NULL, CE_WARN,
496		    "arcmsr%d: reset op (%d) not supported",
497		    ddi_get_instance(resetdev), cmd);
498
499	arcmsr_pcidev_disattach(acb);
500
501	return (DDI_SUCCESS);
502}
503
504static int
505arcmsr_do_ddi_attach(dev_info_t *dev_info, int instance) {
506
507	scsi_hba_tran_t *hba_trans;
508	ddi_device_acc_attr_t dev_acc_attr;
509	struct ACB *acb;
510	static char buf[256];
511	uint16_t wval;
512	int raid6 = 1;
513	char *type;
514
515	/*
516	 * Soft State Structure
517	 * The driver should allocate the per-device-instance
518	 * soft state structure, being careful to clean up properly if
519	 * an error occurs. Allocate data structure.
520	 */
521	if (ddi_soft_state_zalloc(arcmsr_soft_state, instance)
522	    != DDI_SUCCESS) {
523		arcmsr_log(NULL, CE_WARN,
524		    "arcmsr%d: ddi_soft_state_zalloc failed",
525		    instance);
526		return (DDI_FAILURE);
527	}
528
529	acb = ddi_get_soft_state(arcmsr_soft_state, instance);
530	if (acb == NULL) {
531		arcmsr_log(NULL, CE_WARN,
532		    "arcmsr%d: ddi_get_soft_state failed",
533		    instance);
534		goto error_level_1;
535	}
536
537	/* acb is already zalloc()d so we don't need to bzero() it */
538	dev_acc_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
539	dev_acc_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
540	dev_acc_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
541
542	acb->dev_info = dev_info;
543	acb->dev_acc_attr = dev_acc_attr;
544
545	/*
546	 * The driver, if providing DMA, should also check that its hardware is
547	 * installed in a DMA-capable slot
548	 */
549	if (ddi_slaveonly(dev_info) == DDI_SUCCESS) {
550		arcmsr_log(NULL, CE_WARN,
551		    "arcmsr%d: hardware is not installed in a "
552		    "DMA-capable slot",
553		    instance);
554		goto error_level_0;
555	}
556	/* We do not support adapter drivers with high-level interrupts */
557	if (ddi_intr_hilevel(dev_info, 0) != 0) {
558		arcmsr_log(NULL, CE_WARN,
559		    "arcmsr%d: high-level interrupt not supported",
560		    instance);
561		goto error_level_0;
562	}
563
564
565
566
567	if (pci_config_setup(dev_info, &acb->pci_acc_handle)
568	    != DDI_SUCCESS) {
569		arcmsr_log(NULL, CE_NOTE,
570		    "arcmsr%d: pci_config_setup() failed, attach failed",
571		    instance);
572		return (DDI_PROBE_FAILURE);
573	}
574
575	wval = pci_config_get16(acb->pci_acc_handle, PCI_CONF_VENID);
576	if (wval != PCI_VENDOR_ID_ARECA) {
577		arcmsr_log(NULL, CE_NOTE,
578		    "arcmsr%d: failing attach: 'vendorid (0x%04x) "
579		    "does not match 0x%04x (PCI_VENDOR_ID_ARECA)\n",
580		    instance, wval, PCI_VENDOR_ID_ARECA);
581		return (DDI_PROBE_FAILURE);
582	}
583
584	wval = pci_config_get16(acb->pci_acc_handle, PCI_CONF_DEVID);
585	switch (wval) {
586	case PCI_DEVICE_ID_ARECA_1110:
587	case PCI_DEVICE_ID_ARECA_1210:
588	case PCI_DEVICE_ID_ARECA_1201:
589		raid6 = 0;
590		/*FALLTHRU*/
591	case PCI_DEVICE_ID_ARECA_1120:
592	case PCI_DEVICE_ID_ARECA_1130:
593	case PCI_DEVICE_ID_ARECA_1160:
594	case PCI_DEVICE_ID_ARECA_1170:
595	case PCI_DEVICE_ID_ARECA_1220:
596	case PCI_DEVICE_ID_ARECA_1230:
597	case PCI_DEVICE_ID_ARECA_1260:
598	case PCI_DEVICE_ID_ARECA_1270:
599	case PCI_DEVICE_ID_ARECA_1280:
600		type = "SATA";
601		break;
602	case PCI_DEVICE_ID_ARECA_1380:
603	case PCI_DEVICE_ID_ARECA_1381:
604	case PCI_DEVICE_ID_ARECA_1680:
605	case PCI_DEVICE_ID_ARECA_1681:
606		type = "SAS";
607		break;
608	default:
609		type = "X-TYPE";
610		break;
611	}
612
613	(void) sprintf(buf, "Areca %s Host Adapter RAID Controller%s",
614	    type, raid6 ? " (RAID6 capable)" : "");
615	cmn_err(CE_CONT, "arcmsr%d:%s ", instance, buf);
616	cmn_err(CE_CONT, "arcmsr%d:%s ", instance, ARCMSR_DRIVER_VERSION);
617
618
619	/* we disable iop interrupt here */
620	if (arcmsr_initialize(acb) == DDI_FAILURE) {
621		arcmsr_log(NULL, CE_WARN, "arcmsr%d: arcmsr_initialize "
622		    "failed", instance);
623		goto error_level_1;
624	}
625
626	/*
627	 * The driver must first obtain the iblock cookie to initialize
628	 * mutexes used in the driver handler. Only after those mutexes
629	 * have been initialized can the interrupt handler be added.
630	 */
631	if (ddi_get_iblock_cookie(dev_info, 0, &acb->iblock_cookie)
632	    != DDI_SUCCESS) {
633		arcmsr_log(NULL, CE_WARN, "arcmsr%d: "
634		    "ddi_get_iblock_cookie failed", instance);
635		goto error_level_2;
636	}
637	mutex_init(&acb->acb_mutex, NULL, MUTEX_DRIVER,
638	    (void *)acb->iblock_cookie);
639	mutex_init(&acb->postq_mutex, NULL, MUTEX_DRIVER,
640	    (void *)acb->iblock_cookie);
641	mutex_init(&acb->workingQ_mutex, NULL, MUTEX_DRIVER,
642	    (void *)acb->iblock_cookie);
643	mutex_init(&acb->ioctl_mutex, NULL, MUTEX_DRIVER,
644	    (void *)acb->iblock_cookie);
645
646	/* Allocate a transport structure */
647	hba_trans = scsi_hba_tran_alloc(dev_info, SCSI_HBA_CANSLEEP);
648	if (hba_trans == NULL) {
649		arcmsr_log(NULL, CE_WARN,
650		    "arcmsr%d: scsi_hba_tran_alloc failed",
651		    instance);
652		goto error_level_3;
653	}
654	acb->scsi_hba_transport = hba_trans;
655	acb->dev_info = dev_info;
656	/* init scsi host adapter transport entry */
657	hba_trans->tran_hba_private  = acb;
658	hba_trans->tran_tgt_private  = NULL;
659	/*
660	 * If no per-target initialization is required, the HBA can leave
661	 * tran_tgt_init set to NULL.
662	 */
663	hba_trans->tran_tgt_init = arcmsr_tran_tgt_init;
664	hba_trans->tran_tgt_probe = scsi_hba_probe;
665	hba_trans->tran_tgt_free = NULL;
666	hba_trans->tran_start = arcmsr_tran_start;
667	hba_trans->tran_abort = arcmsr_tran_abort;
668	hba_trans->tran_reset = arcmsr_tran_reset;
669	hba_trans->tran_getcap = arcmsr_tran_getcap;
670	hba_trans->tran_setcap = arcmsr_tran_setcap;
671	hba_trans->tran_init_pkt = arcmsr_tran_init_pkt;
672	hba_trans->tran_destroy_pkt = arcmsr_tran_destroy_pkt;
673	hba_trans->tran_dmafree = arcmsr_tran_dmafree;
674	hba_trans->tran_sync_pkt = arcmsr_tran_sync_pkt;
675
676	hba_trans->tran_reset_notify = NULL;
677	hba_trans->tran_get_bus_addr = NULL;
678	hba_trans->tran_get_name = NULL;
679	hba_trans->tran_quiesce = NULL;
680	hba_trans->tran_unquiesce = NULL;
681	hba_trans->tran_bus_reset = NULL;
682	hba_trans->tran_add_eventcall = NULL;
683	hba_trans->tran_get_eventcookie = NULL;
684	hba_trans->tran_post_event = NULL;
685	hba_trans->tran_remove_eventcall = NULL;
686
687
688	/* Adding an Interrupt Handler */
689	if (ddi_add_intr(dev_info, 0, &acb->iblock_cookie, 0,
690	    arcmsr_interrupt, (caddr_t)acb) != DDI_SUCCESS) {
691		arcmsr_log(NULL, CE_WARN,
692		    "arcmsr%d: failed to add interrupt handler",
693		    instance);
694		goto error_level_4;
695	}
696	/*
697	 * The driver should attach this instance of the device, and
698	 * perform error cleanup if necessary
699	 */
700	if (scsi_hba_attach_setup(dev_info, &arcmsr_dma_attr,
701	    hba_trans, SCSI_HBA_TRAN_CLONE) != DDI_SUCCESS) {
702		arcmsr_log(NULL, CE_WARN,
703		    "arcmsr%d: scsi_hba_attach_setup failed",
704		    instance);
705		goto error_level_5;
706	}
707
708	/* iop init and enable interrupt here */
709	mutex_enter(&arcmsr_global_mutex);
710	arcmsr_iop_init(acb);
711	mutex_exit(&arcmsr_global_mutex);
712
713	/* Initialize power management bookkeeping. */
714	if (pm_create_components(dev_info, 1) == DDI_SUCCESS) {
715		if (pm_idle_component(dev_info, 0) == DDI_FAILURE) {
716			arcmsr_log(NULL, CE_WARN,
717			    "arcmsr%d: pm_idle_component fail",
718			    instance);
719			goto error_level_8;
720		}
721		pm_set_normal_power(dev_info, 0, 1);
722		/* acb->power_level = 1; */
723	} else {
724		arcmsr_log(NULL, CE_WARN,
725		    "arcmsr%d: pm_create_components fail",
726		    instance);
727		goto error_level_7;
728	}
729
730	/*
731	 * Since this driver manages devices with "remote" hardware, "
732	 * i.e. the devices themselves have no "reg" property, the SUSPEND/
733	 * RESUME commands in detach/attach will not be called by the power
734	 * management framework unless we request it by creating a
735	 * "pm-hardware-state" property and setting it to value
736	 * "needs-suspend-resume".
737	 */
738	if (ddi_prop_update_string(DDI_DEV_T_NONE, dev_info,
739	    "pm-hardware-state", "needs-suspend-resume")
740	    != DDI_PROP_SUCCESS) {
741		arcmsr_log(NULL, CE_WARN,
742		    "arcmsr%d: ddi_prop_update(\"pm-hardware-state\")failed",
743		    instance);
744		goto error_level_8;
745	}
746
747	/* active ccbs "timeout" watchdog */
748	acb->timeout_id = timeout(arcmsr_ccbs_timeout, (caddr_t)acb,
749	    (60 * drv_usectohz(1000000)));
750	/* report device info */
751	ddi_report_dev(dev_info);
752	ArcMSRHBA[arcmsr_hba_count] = acb;
753	arcmsr_hba_count++;
754
755	return (DDI_SUCCESS);
756
757error_level_8:
758	pm_destroy_components(dev_info);
759
760error_level_7:
761	/* Remove any previously allocated minor nodes */
762	ddi_remove_minor_node(dev_info, NULL);
763
764error_level_6:
765	scsi_hba_tran_free(hba_trans);
766
767error_level_5:
768	ddi_remove_intr(dev_info, 0, (void *)acb->iblock_cookie);
769
770error_level_4:
771	scsi_hba_tran_free(hba_trans);
772
773error_level_3:
774	mutex_destroy(&acb->acb_mutex);
775	mutex_destroy(&acb->postq_mutex);
776	mutex_destroy(&acb->workingQ_mutex);
777	mutex_destroy(&acb->ioctl_mutex);
778
779error_level_2:
780	ddi_dma_mem_free(&acb->ccbs_acc_handle);
781	ddi_dma_free_handle(&acb->ccbs_pool_handle);
782
783error_level_1:
784	ddi_soft_state_free(arcmsr_soft_state, instance);
785
786error_level_0:
787	return (DDI_FAILURE);
788}
789
790
791
792/*
793 *      Function: arcmsr_attach(9E)
794 *   Description: Set up all device state and allocate data structures,
795 *		  mutexes, condition variables, etc. for device operation.
796 *		  Set mt_attr property for driver to indicate MT-safety.
797 *		  Add interrupts needed.
798 *         Input: dev_info_t *dev_info, ddi_attach_cmd_t cmd
799 *        Output: Return DDI_SUCCESS if device is ready,
800 *		          else return DDI_FAILURE
801 */
802static int
803arcmsr_attach(dev_info_t *dev_info, ddi_attach_cmd_t cmd) {
804
805	scsi_hba_tran_t *hba_trans;
806	struct ACB *acb;
807
808
809#if defined(ARCMSR_DEBUG)
810	arcmsr_log(NULL, CE_NOTE,
811	    "arcmsr_attach called for device %lx (instance %d)",
812	    &dev_info, ddi_get_instance(dev_info));
813#endif
814	switch (cmd) {
815	case DDI_ATTACH:
816		return (arcmsr_do_ddi_attach(dev_info,
817		    ddi_get_instance(dev_info)));
818	case DDI_RESUME:
819	case DDI_PM_RESUME:
820	/*
821	 * There is no hardware state to restart and no timeouts to
822	 * restart since we didn't PM_SUSPEND with active cmds or
823	 * active timeouts We just need to unblock waiting threads
824	 * and restart I/O the code for DDI_RESUME is almost identical
825	 * except it uses the suspend flag rather than pm_suspend flag
826	 */
827	    hba_trans = (scsi_hba_tran_t *)ddi_get_driver_private(dev_info);
828	    if (!hba_trans) {
829		    return (DDI_FAILURE);
830	    }
831	    acb = (struct ACB *)
832		hba_trans->tran_hba_private;
833	    mutex_enter(&acb->acb_mutex);
834	    arcmsr_iop_init(acb);
835
836	    /* restart ccbs "timeout" watchdog */
837	    acb->timeout_id = timeout(arcmsr_ccbs_timeout,
838		(void*)acb, (60 * drv_usectohz(1000000)));
839	    mutex_exit(&acb->acb_mutex);
840	    return (DDI_SUCCESS);
841
842    default:
843	    arcmsr_log(NULL, CE_WARN,
844		"arcmsr%d: ddi attach cmd (%d) unsupported",
845		cmd, ddi_get_instance(dev_info));
846	    return (DDI_FAILURE);
847	}
848}
849
850/*
851 *    Function:	arcmsr_detach(9E)
852 * Description: Remove all device allocation and system resources, disable
853 *		        device interrupt.
854 *       Input: dev_info_t *dev_info
855 *		        ddi_detach_cmd_t cmd
856 *      Output:	Return DDI_SUCCESS if done,
857 *		        else returnDDI_FAILURE
858 */
859static int
860arcmsr_detach(dev_info_t *dev_info, ddi_detach_cmd_t cmd) {
861
862	int instance;
863	struct ACB *acb;
864
865
866	instance = ddi_get_instance(dev_info);
867	acb = (struct ACB *)ddi_get_soft_state(arcmsr_soft_state,
868	    instance);
869	if (!acb) {
870		return (DDI_FAILURE);
871	}
872
873	switch (cmd) {
874	case DDI_DETACH:
875		mutex_enter(&acb->acb_mutex);
876		if (acb->timeout_id != 0) {
877			mutex_exit(&acb->acb_mutex);
878			(void) untimeout(acb->timeout_id);
879			mutex_enter(&acb->acb_mutex);
880			acb->timeout_id = 0;
881		}
882		arcmsr_pcidev_disattach(acb);
883		/* Remove interrupt set up by ddi_add_intr */
884		ddi_remove_intr(dev_info, 0, acb->iblock_cookie);
885		/* unbind mapping object to handle */
886		(void) ddi_dma_unbind_handle(acb->ccbs_pool_handle);
887		/* Free ccb pool memory */
888		ddi_dma_mem_free(&acb->ccbs_acc_handle);
889		/* Free DMA handle */
890		ddi_dma_free_handle(&acb->ccbs_pool_handle);
891		ddi_regs_map_free(&acb->reg_mu_acc_handle0);
892		if (scsi_hba_detach(dev_info) != DDI_SUCCESS)
893			arcmsr_log(NULL, CE_WARN,
894			    "arcmsr%d: Unable to detach instance cleanly "
895			    "(should not happen)",
896			    ddi_get_instance(dev_info));
897		/* free scsi_hba_transport from scsi_hba_tran_alloc */
898		scsi_hba_tran_free(acb->scsi_hba_transport);
899		ddi_remove_minor_node(dev_info, NULL);
900		ddi_prop_remove_all(dev_info);
901		mutex_exit(&acb->acb_mutex);
902		mutex_destroy(&acb->acb_mutex);
903		mutex_destroy(&acb->postq_mutex);
904		mutex_destroy(&acb->workingQ_mutex);
905		mutex_destroy(&acb->ioctl_mutex);
906		pci_config_teardown(&acb->pci_acc_handle);
907		ddi_set_driver_private(dev_info, NULL);
908		ddi_soft_state_free(arcmsr_soft_state, instance);
909		pm_destroy_components(dev_info);
910		return (DDI_SUCCESS);
911	case DDI_SUSPEND:
912	case DDI_PM_SUSPEND:
913		mutex_enter(&acb->acb_mutex);
914		if (acb->timeout_id != 0) {
915			acb->acb_flags |= ACB_F_SCSISTOPADAPTER;
916			mutex_exit(&acb->acb_mutex);
917			(void) untimeout(acb->timeout_id);
918			mutex_enter(&acb->acb_mutex);
919			acb->timeout_id = 0;
920		}
921		/* disable all outbound interrupt */
922		(void) arcmsr_disable_allintr(acb);
923		/* stop adapter background rebuild */
924		if (acb->adapter_type == ACB_ADAPTER_TYPE_A) {
925			arcmsr_stop_hba_bgrb(acb);
926			arcmsr_flush_hba_cache(acb);
927		} else {
928			arcmsr_stop_hbb_bgrb(acb);
929			arcmsr_flush_hbb_cache(acb);
930		}
931		mutex_exit(&acb->acb_mutex);
932		return (DDI_SUCCESS);
933	default:
934		return (DDI_FAILURE);
935	}
936}
937
938
939
940/*
941 *    Function:	arcmsr_tran_tgt_init
942 * Description: Called when initializing a target device instance. If
943 *		        no per-target initialization is required, the HBA
944 *		        may leave tran_tgt_init to NULL
945 *       Input:
946 *		        dev_info_t *host_dev_info,
947 *		        dev_info_t *target_dev_info,
948 *		        scsi_hba_tran_t *tran,
949 *		        struct scsi_device *sd
950 *
951 *      Return: DDI_SUCCESS if success, else return DDI_FAILURE
952 *
953 *  entry point enables the HBA to allocate and/or initialize any per-
954 *  target resources.
955 *  It also enables the HBA to qualify the device's address as valid and
956 *  supportable for that particular HBA.
957 *  By returning DDI_FAILURE, the instance of the target driver for that
958 *  device will not be probed or attached.
959 * 	This entry point is not required, and if none is supplied,
960 *  the framework will attempt to probe and attach all possible instances
961 *  of the appropriate target drivers.
962 */
963static int
964arcmsr_tran_tgt_init(dev_info_t *host_dev_info, dev_info_t *target_dev_info,
965    scsi_hba_tran_t *hosttran, struct scsi_device *sd) {
966#ifndef __lock_lint
967	_NOTE(ARGUNUSED(hosttran, target_dev_info))
968#endif
969
970
971	uint16_t  target;
972	uint8_t  lun;
973
974	target = sd->sd_address.a_target;
975	lun = sd->sd_address.a_lun;
976	if ((target >= ARCMSR_MAX_TARGETID) || (lun >= ARCMSR_MAX_TARGETLUN)) {
977		cmn_err(CE_WARN,
978		    "arcmsr%d: (target %d, lun %d) exceeds "
979		    "maximum supported values (%d, %d)",
980		    ddi_get_instance(host_dev_info),
981		    target, lun, ARCMSR_MAX_TARGETID, ARCMSR_MAX_TARGETLUN);
982		return (DDI_FAILURE);
983	}
984	return (DDI_SUCCESS);
985}
986
987/*
988 *         Function: arcmsr_tran_getcap(9E)
989 *      Description: Get the capability named, and returnits value.
990 *    Return Values: current value of capability, ifdefined
991 *		             -1 ifcapability is not defined
992 * ------------------------------------------------------
993 *         Common Capability Strings Array
994 * ------------------------------------------------------
995 *	#define	SCSI_CAP_DMA_MAX		0
996 *	#define	SCSI_CAP_MSG_OUT		1
997 *	#define	SCSI_CAP_DISCONNECT		2
998 *	#define	SCSI_CAP_SYNCHRONOUS		3
999 *	#define	SCSI_CAP_WIDE_XFER		4
1000 *	#define	SCSI_CAP_PARITY			5
1001 *	#define	SCSI_CAP_INITIATOR_ID		6
1002 *	#define	SCSI_CAP_UNTAGGED_QING		7
1003 *	#define	SCSI_CAP_TAGGED_QING		8
1004 *	#define	SCSI_CAP_ARQ			9
1005 *	#define	SCSI_CAP_LINKED_CMDS		10 a
1006 *	#define	SCSI_CAP_SECTOR_SIZE		11 b
1007 *	#define	SCSI_CAP_TOTAL_SECTORS		12 c
1008 *	#define	SCSI_CAP_GEOMETRY		13 d
1009 *	#define	SCSI_CAP_RESET_NOTIFICATION	14 e
1010 *	#define	SCSI_CAP_QFULL_RETRIES		15 f
1011 *	#define	SCSI_CAP_QFULL_RETRY_INTERVAL	16 10
1012 *	#define	SCSI_CAP_SCSI_VERSION		17 11
1013 *	#define	SCSI_CAP_INTERCONNECT_TYPE	18 12
1014 *	#define	SCSI_CAP_LUN_RESET		19 13
1015 */
1016static int
1017arcmsr_tran_getcap(struct scsi_address *ap, char *cap, int whom) {
1018
1019	int capability = 0;
1020	struct ACB *acb =
1021	    (struct ACB *)ap->a_hba_tran->tran_hba_private;
1022
1023
1024	if (cap == NULL || whom == 0) {
1025		return (DDI_FAILURE);
1026	}
1027
1028	mutex_enter(&arcmsr_global_mutex);
1029	switch (scsi_hba_lookup_capstr(cap)) {
1030	case SCSI_CAP_MSG_OUT:
1031	case SCSI_CAP_DISCONNECT:
1032	case SCSI_CAP_SYNCHRONOUS:
1033	case SCSI_CAP_WIDE_XFER:
1034	case SCSI_CAP_TAGGED_QING:
1035	case SCSI_CAP_UNTAGGED_QING:
1036	case SCSI_CAP_PARITY:
1037	case SCSI_CAP_ARQ:
1038		capability = acb->tgt_scsi_opts[ap->a_target];
1039		break;
1040	case SCSI_CAP_SECTOR_SIZE:
1041		capability = ARCMSR_DEV_SECTOR_SIZE;
1042		break;
1043	case SCSI_CAP_DMA_MAX:
1044		/* Limit to 16MB max transfer */
1045		capability = ARCMSR_MAX_XFER_LEN;
1046		break;
1047	case SCSI_CAP_INITIATOR_ID:
1048		capability = ARCMSR_SCSI_INITIATOR_ID;
1049		break;
1050	case SCSI_CAP_GEOMETRY:
1051		/* head , track , cylinder */
1052		capability = (255 << 16) | 63;
1053		break;
1054	default:
1055		capability = -1;
1056		break;
1057	}
1058	mutex_exit(&arcmsr_global_mutex);
1059	return (capability);
1060}
1061
1062/*
1063 *      Function: arcmsr_tran_setcap(9E)
1064 *   Description: Set the specific capability.
1065 * Return Values: 1 - capability exists and can be set to new value
1066 *		          0 - capability could not be set to new value
1067 *		         -1 - no such capability
1068 */
1069static int
1070arcmsr_tran_setcap(struct scsi_address *ap, char *cap, int value,
1071    int whom) {
1072#ifndef __lock_lint
1073	_NOTE(ARGUNUSED(value))
1074#endif
1075
1076
1077	int supported = 0;
1078	struct ACB *acb =
1079	    (struct ACB *)ap->a_hba_tran->tran_hba_private;
1080
1081
1082	if (cap == NULL || whom == 0) {
1083		return (-1);
1084	}
1085
1086	mutex_enter(&arcmsr_global_mutex);
1087	switch (supported = scsi_hba_lookup_capstr(cap)) {
1088	case SCSI_CAP_DISCONNECT:		/* 2 */
1089	case SCSI_CAP_SYNCHRONOUS:		/* 3 */
1090	case SCSI_CAP_TAGGED_QING:		/* 8 */
1091	case SCSI_CAP_WIDE_XFER:		/* 4 */
1092	case SCSI_CAP_ARQ:			/* 9 auto request sense */
1093	case SCSI_CAP_TOTAL_SECTORS:		/* c */
1094		acb->tgt_scsi_opts[ap->a_target] |= supported;
1095		supported = 1;
1096		break;
1097	case SCSI_CAP_UNTAGGED_QING:   		/* 7 */
1098	case SCSI_CAP_INITIATOR_ID:		/* 6 */
1099	case SCSI_CAP_DMA_MAX:			/* 0 */
1100	case SCSI_CAP_MSG_OUT:			/* 1 */
1101	case SCSI_CAP_PARITY:			/* 5 */
1102	case SCSI_CAP_LINKED_CMDS:		/* a */
1103	case SCSI_CAP_RESET_NOTIFICATION:	/* e */
1104	case SCSI_CAP_SECTOR_SIZE:		/* b */
1105		supported = 0;
1106		break;
1107	default:
1108		supported = -1;
1109		break;
1110	}
1111	mutex_exit(&arcmsr_global_mutex);
1112	return (supported);
1113}
1114
1115
1116
1117static void
1118arcmsr_free_ccb(struct CCB *ccb) {
1119
1120	struct ACB *acb = ccb->acb;
1121
1122	ccb->startdone = ARCMSR_CCB_DONE;
1123	ccb->pkt = NULL;
1124	ccb->ccb_flags = 0;
1125	mutex_enter(&acb->workingQ_mutex);
1126	acb->ccbworkingQ[acb->workingccb_doneindex] = ccb;
1127	acb->workingccb_doneindex++;
1128	acb->workingccb_doneindex %= ARCMSR_MAX_FREECCB_NUM;
1129	mutex_exit(&acb->workingQ_mutex);
1130}
1131
1132/*
1133 *      Function: arcmsr_tran_init_pkt
1134 * Return Values: pointer to scsi_pkt, or NULL
1135 *   Description: simultaneously allocate both a scsi_pkt(9S) structure and
1136 *                DMA resources for that pkt.
1137 *                Called by kernel on behalf of a target driver
1138 *		          calling scsi_init_pkt(9F).
1139 *		          Refer to tran_init_pkt(9E) man page
1140 *       Context: Can be called from different kernel process threads.
1141 *		          Can be called by interrupt thread.
1142 * Allocates SCSI packet and DMA resources
1143 */
1144static struct
1145scsi_pkt *arcmsr_tran_init_pkt(struct scsi_address *ap,
1146    register struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
1147    int tgtlen, int flags, int (*callback)(), caddr_t arg) {
1148
1149	struct CCB *ccb;
1150	struct ARCMSR_CDB *arcmsr_cdb;
1151	struct ACB *acb;
1152	int old_pkt_flag = 1;
1153
1154
1155	acb = (struct ACB *)ap->a_hba_tran->tran_hba_private;
1156
1157	if (pkt == NULL) {
1158		/* get free CCB */
1159		ccb = arcmsr_get_freeccb(acb);
1160		if (ccb == (struct CCB *)NULL) {
1161			return (NULL);
1162		}
1163
1164		if (ccb->pkt != NULL) {
1165			/*
1166			 * If kmem_flags are turned on, expect to
1167			 * see a message
1168			 */
1169			cmn_err(CE_WARN, "arcmsr%d: invalid pkt",
1170			    ddi_get_instance(acb->dev_info));
1171			return (NULL);
1172		}
1173		pkt = scsi_hba_pkt_alloc(acb->dev_info, ap, cmdlen,
1174		    statuslen, tgtlen, sizeof (struct scsi_pkt),
1175		    callback, arg);
1176		if (pkt == NULL) {
1177			cmn_err(CE_WARN,
1178			    "arcmsr%d: scsi pkt allocation failed",
1179			    ddi_get_instance(acb->dev_info));
1180			arcmsr_free_ccb(ccb);
1181			return (NULL);
1182		}
1183		/* Initialize CCB */
1184		ccb->pkt = pkt;
1185		ccb->pkt_dma_handle = NULL;
1186		/* record how many sg are needed to xfer on this pkt */
1187		ccb->pkt_ncookies = 0;
1188		/* record how many sg we got from this window */
1189		ccb->pkt_cookie = 0;
1190		/* record how many windows have partial dma map set */
1191		ccb->pkt_nwin = 0;
1192		/* record current sg window position */
1193		ccb->pkt_curwin	= 0;
1194		ccb->pkt_dma_len = 0;
1195		ccb->pkt_dma_offset = 0;
1196		ccb->resid_dmacookie.dmac_size = 0;
1197
1198		/*
1199		 * we will still use this point for we want to fake some
1200		 * information in tran_start
1201		 */
1202		ccb->bp = bp;
1203
1204		/* Initialize arcmsr_cdb */
1205		arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb;
1206		bzero(arcmsr_cdb, sizeof (struct ARCMSR_CDB));
1207		arcmsr_cdb->Bus = 0;
1208		arcmsr_cdb->Function = 1;
1209		arcmsr_cdb->LUN = ap->a_lun;
1210		arcmsr_cdb->TargetID = ap->a_target;
1211		arcmsr_cdb->CdbLength = (uint8_t)cmdlen;
1212		arcmsr_cdb->Context = (unsigned long)arcmsr_cdb;
1213
1214		/* Fill in the rest of the structure */
1215		pkt->pkt_ha_private = ccb;
1216		pkt->pkt_address = *ap;
1217		pkt->pkt_comp = (void (*)())NULL;
1218		pkt->pkt_flags = 0;
1219		pkt->pkt_time = 0;
1220		pkt->pkt_resid = 0;
1221		pkt->pkt_statistics = 0;
1222		pkt->pkt_reason = 0;
1223		old_pkt_flag = 0;
1224	} else {
1225		ccb = (struct CCB *)pkt->pkt_ha_private;
1226		/*
1227		 * you cannot update CdbLength with cmdlen here, it would
1228		 * cause a data compare error
1229		 */
1230		ccb->startdone = ARCMSR_CCB_UNBUILD;
1231	}
1232
1233	/* Second step : dma allocation/move */
1234	if (bp && bp->b_bcount != 0) {
1235		/*
1236		 * system had a lot of data trunk need to xfer, from...20 byte
1237		 * to 819200 byte.
1238		 * arcmsr_dma_alloc will get pkt_dma_handle (not null) until
1239		 * this lot of data trunk xfer done this mission will be done
1240		 * by some of continue READ or WRITE scsi command, till this
1241		 * lot of data trunk xfer completed.
1242		 * arcmsr_dma_move do the action repeatedly, and use the same
1243		 * ccb till this lot of data trunk xfer complete notice.
1244		 * when after the arcmsr_tran_init_pkt returns the solaris
1245		 * kernel is by your pkt_resid and its b_bcount to give you
1246		 * which type of scsi command descriptor to implement the
1247		 * length of folowing arcmsr_tran_start scsi cdb (data length)
1248		 *
1249		 * Each transfer should be aligned on a 512 byte boundary
1250		 */
1251		if (ccb->pkt_dma_handle == NULL) {
1252			if (arcmsr_dma_alloc(acb, pkt, bp, flags,
1253			    callback) == DDI_FAILURE) {
1254				/*
1255				 * the HBA driver is unable to allocate DMA
1256				 * resources, it must free the allocated
1257				 * scsi_pkt(9S) before returning
1258				 */
1259				cmn_err(CE_WARN, "arcmsr%d: dma allocation "
1260				    "failure ",
1261				    ddi_get_instance(acb->dev_info));
1262				if (old_pkt_flag == 0) {
1263					cmn_err(CE_WARN, "arcmsr%d: dma "
1264					    "allocation failed to free scsi "
1265					    "hba pkt ",
1266					    ddi_get_instance(acb->dev_info));
1267					arcmsr_free_ccb(ccb);
1268					scsi_hba_pkt_free(ap, pkt);
1269				}
1270				return ((struct scsi_pkt *)NULL);
1271			}
1272		} else {
1273			/* DMA resources to next DMA window, for old pkt */
1274			if (arcmsr_dma_move(acb, pkt, bp) == -1) {
1275				cmn_err(CE_WARN, "arcmsr%d: dma move "
1276				    "failed ",
1277				    ddi_get_instance(acb->dev_info));
1278				return ((struct scsi_pkt *)NULL);
1279			}
1280		}
1281	} else {
1282		pkt->pkt_resid = 0;
1283	}
1284	return (pkt);
1285}
1286
1287/*
1288 * Function name: arcmsr_dma_alloc
1289 * Return Values: 0 if successful, -1 if failure
1290 *   Description: allocate DMA resources
1291 *       Context: Can only be called from arcmsr_tran_init_pkt()
1292 *     register struct scsi_address	*ap = &((pkt)->pkt_address);
1293 */
1294static int
1295arcmsr_dma_alloc(struct ACB *acb, struct scsi_pkt *pkt,
1296    struct buf *bp, int flags, int (*callback)()) {
1297
1298	struct CCB *ccb = pkt->pkt_ha_private;
1299	int alloc_result, map_method, dma_flags;
1300	int resid = 0;
1301	int total_ccb_xferlen = 0;
1302	int (*cb)(caddr_t);
1303	uint8_t i;
1304
1305	/*
1306	 * at this point the PKT SCSI CDB is empty, and dma xfer length
1307	 * is bp->b_bcount
1308	 */
1309
1310	if (bp->b_flags & B_READ) {
1311		ccb->ccb_flags &= ~CCB_FLAG_DMAWRITE;
1312		dma_flags = DDI_DMA_READ;
1313	} else {
1314		ccb->ccb_flags |= CCB_FLAG_DMAWRITE;
1315		dma_flags = DDI_DMA_WRITE;
1316	}
1317
1318	if (flags & PKT_CONSISTENT) {
1319		ccb->ccb_flags |= CCB_FLAG_DMACONSISTENT;
1320		dma_flags |= DDI_DMA_CONSISTENT;
1321	}
1322	if (flags & PKT_DMA_PARTIAL) {
1323		dma_flags |= DDI_DMA_PARTIAL;
1324	}
1325
1326	dma_flags |= DDI_DMA_REDZONE;
1327	cb = (callback == NULL_FUNC) ? DDI_DMA_DONTWAIT : DDI_DMA_SLEEP;
1328
1329	if ((alloc_result = ddi_dma_alloc_handle(acb->dev_info,
1330	    &arcmsr_dma_attr, cb, 0, &ccb->pkt_dma_handle))
1331	    != DDI_SUCCESS) {
1332		switch (alloc_result) {
1333		case DDI_DMA_BADATTR:
1334			/*
1335			 * If the system does not support physical DMA,
1336			 * the return value from ddi_dma_alloc_handle
1337			 * will be DDI_DMA_BADATTR
1338			 */
1339			cmn_err(CE_WARN, "arcmsr%d: dma allocate returned "
1340			    "'bad attribute'",
1341			    ddi_get_instance(acb->dev_info));
1342			bioerror(bp, EFAULT);
1343			return (DDI_FAILURE);
1344		case DDI_DMA_NORESOURCES:
1345			cmn_err(CE_WARN, "arcmsr%d: dma allocate returned "
1346			    "'no resources'",
1347			    ddi_get_instance(acb->dev_info));
1348			bioerror(bp, 0);
1349			return (DDI_FAILURE);
1350		default:
1351			cmn_err(CE_WARN, "arcmsr%d: dma allocate returned "
1352			    "'unknown failure'",
1353			    ddi_get_instance(acb->dev_info));
1354			return (DDI_FAILURE);
1355		}
1356	}
1357
1358	map_method = ddi_dma_buf_bind_handle(ccb->pkt_dma_handle, bp,
1359	    dma_flags, cb, 0,
1360	    &ccb->pkt_dmacookies[0],	/* SG List pointer */
1361	    &ccb->pkt_ncookies);	/* number of sgl cookies */
1362
1363	switch (map_method) {
1364	case DDI_DMA_PARTIAL_MAP:
1365		/*
1366		 * When your main memory size larger then 4G
1367		 * DDI_DMA_PARTIAL_MAP will be touched.
1368		 *
1369		 * We've already set DDI_DMA_PARTIAL in dma_flags,
1370		 * so if it's now missing, there's something screwy
1371		 * happening. We plow on....
1372		 */
1373
1374		if ((dma_flags & DDI_DMA_PARTIAL) == 0) {
1375			cmn_err(CE_WARN, "arcmsr%d: dma partial mapping lost "
1376			    "...impossible case!",
1377			    ddi_get_instance(acb->dev_info));
1378		}
1379		if (ddi_dma_numwin(ccb->pkt_dma_handle, &ccb->pkt_nwin) ==
1380		    DDI_FAILURE) {
1381			cmn_err(CE_WARN, "arcmsr%d: ddi_dma_numwin() failed",
1382			    ddi_get_instance(acb->dev_info));
1383		}
1384
1385		if (ddi_dma_getwin(ccb->pkt_dma_handle, ccb->pkt_curwin,
1386		    &ccb->pkt_dma_offset, &ccb->pkt_dma_len,
1387		    &ccb->pkt_dmacookies[0], &ccb->pkt_ncookies) ==
1388		    DDI_FAILURE) {
1389			cmn_err(CE_WARN, "arcmsr%d: ddi_dma_getwin failed",
1390			    ddi_get_instance(acb->dev_info));
1391		}
1392
1393		i = 0;
1394		/* first cookie is accessed from ccb->pkt_dmacookies[0] */
1395		total_ccb_xferlen = ccb->pkt_dmacookies[0].dmac_size;
1396		for (;;) {
1397			i++;
1398			if (i == ARCMSR_MAX_SG_ENTRIES ||
1399			    i == ccb->pkt_ncookies ||
1400			    total_ccb_xferlen == ARCMSR_MAX_XFER_LEN) {
1401				break;
1402			}
1403			/*
1404			 * next cookie will be retrieved from
1405			 * ccb->pkt_dmacookies[i]
1406			 */
1407			ddi_dma_nextcookie(ccb->pkt_dma_handle,
1408			    &ccb->pkt_dmacookies[i]);
1409			total_ccb_xferlen += ccb->pkt_dmacookies[i].dmac_size;
1410		}
1411		ccb->pkt_cookie = i;
1412		ccb->arcmsr_cdb.sgcount = i;
1413		if (total_ccb_xferlen > 512) {
1414			resid = total_ccb_xferlen % 512;
1415			if (resid != 0) {
1416				i--;
1417				total_ccb_xferlen -= resid;
1418				/* modify last sg length */
1419				ccb->pkt_dmacookies[i].dmac_size =
1420				    ccb->pkt_dmacookies[i].dmac_size - resid;
1421				ccb->resid_dmacookie.dmac_size = resid;
1422				ccb->resid_dmacookie.dmac_laddress =
1423				    ccb->pkt_dmacookies[i].dmac_laddress +
1424				    ccb->pkt_dmacookies[i].dmac_size;
1425			}
1426		}
1427		ccb->total_dmac_size = total_ccb_xferlen;
1428		ccb->ccb_flags |= CCB_FLAG_DMAVALID;
1429		pkt->pkt_resid = bp->b_bcount - ccb->total_dmac_size;
1430
1431		return (DDI_SUCCESS);
1432
1433	case DDI_DMA_MAPPED:
1434		ccb->pkt_nwin = 1; /* all mapped, so only one window */
1435		ccb->pkt_dma_len = 0;
1436		ccb->pkt_dma_offset = 0;
1437		i = 0;
1438		/* first cookie is accessed from ccb->pkt_dmacookies[0] */
1439		total_ccb_xferlen = ccb->pkt_dmacookies[0].dmac_size;
1440		for (;;) {
1441			i++;
1442			if (i == ARCMSR_MAX_SG_ENTRIES ||
1443			    i == ccb->pkt_ncookies ||
1444			    total_ccb_xferlen == ARCMSR_MAX_XFER_LEN) {
1445				break;
1446			}
1447			/*
1448			 * next cookie will be retrieved from
1449			 * ccb->pkt_dmacookies[i]
1450			 */
1451			ddi_dma_nextcookie(ccb->pkt_dma_handle,
1452			    &ccb->pkt_dmacookies[i]);
1453			total_ccb_xferlen += ccb->pkt_dmacookies[i].dmac_size;
1454		}
1455		ccb->pkt_cookie = i;
1456		ccb->arcmsr_cdb.sgcount = i;
1457		if (total_ccb_xferlen > 512) {
1458			resid = total_ccb_xferlen % 512;
1459			    if (resid != 0) {
1460				i--;
1461				total_ccb_xferlen -= resid;
1462				/* modify last sg length */
1463				ccb->pkt_dmacookies[i].dmac_size =
1464				    ccb->pkt_dmacookies[i].dmac_size - resid;
1465				ccb->resid_dmacookie.dmac_size = resid;
1466				ccb->resid_dmacookie.dmac_laddress =
1467				    ccb->pkt_dmacookies[i].dmac_laddress +
1468				    ccb->pkt_dmacookies[i].dmac_size;
1469			}
1470		}
1471		ccb->total_dmac_size = total_ccb_xferlen;
1472		ccb->ccb_flags |= CCB_FLAG_DMAVALID;
1473		pkt->pkt_resid = bp->b_bcount - ccb->total_dmac_size;
1474		return (DDI_SUCCESS);
1475
1476	case DDI_DMA_NORESOURCES:
1477		cmn_err(CE_WARN, "arcmsr%d: dma map got 'no resources'",
1478		    ddi_get_instance(acb->dev_info));
1479		bioerror(bp, ENOMEM);
1480		break;
1481
1482	case DDI_DMA_NOMAPPING:
1483		cmn_err(CE_WARN, "arcmsr%d: dma map got 'no mapping'",
1484		    ddi_get_instance(acb->dev_info));
1485		bioerror(bp, EFAULT);
1486		break;
1487
1488	case DDI_DMA_TOOBIG:
1489		cmn_err(CE_WARN, "arcmsr%d: dma map got 'too big'",
1490		    ddi_get_instance(acb->dev_info));
1491		bioerror(bp, EINVAL);
1492		break;
1493
1494	case DDI_DMA_INUSE:
1495		cmn_err(CE_WARN, "arcmsr%d: dma map got 'in use' "
1496		    "(should not happen)",
1497		    ddi_get_instance(acb->dev_info));
1498		break;
1499	default:
1500		cmn_err(CE_WARN,
1501		    "arcmsr%d: dma map got 'unknown failure 0x%x' "
1502		    "(should not happen)",
1503		    ddi_get_instance(acb->dev_info), i);
1504#ifdef ARCMSR_DEBUG
1505		arcmsr_dump_scsi_cdb(&pkt->pkt_address, pkt);
1506#endif
1507		break;
1508	}
1509
1510	ddi_dma_free_handle(&ccb->pkt_dma_handle);
1511	ccb->pkt_dma_handle = NULL;
1512	ccb->ccb_flags &= ~CCB_FLAG_DMAVALID;
1513	return (DDI_FAILURE);
1514}
1515
1516
1517/*
1518 * Function name: arcmsr_dma_move
1519 * Return Values: 0 if successful, -1 if failure
1520 *   Description: move DMA resources to next DMA window
1521 *       Context: Can only be called from arcmsr_tran_init_pkt()
1522 */
1523static int
1524arcmsr_dma_move(struct ACB *acb, struct scsi_pkt *pkt,
1525    struct buf *bp) {
1526
1527	struct CCB *ccb = pkt->pkt_ha_private;
1528	uint8_t i = 0;
1529	int resid = 0;
1530	int total_ccb_xferlen = 0;
1531
1532	if (ccb->resid_dmacookie.dmac_size != 0) 	{
1533		total_ccb_xferlen += ccb->resid_dmacookie.dmac_size;
1534		ccb->pkt_dmacookies[i].dmac_size =
1535		    ccb->resid_dmacookie.dmac_size;
1536		ccb->pkt_dmacookies[i].dmac_laddress =
1537		    ccb->resid_dmacookie.dmac_laddress;
1538		i++;
1539		ccb->resid_dmacookie.dmac_size = 0;
1540	}
1541	/*
1542	 * If there are no more cookies remaining in this window,
1543	 * move to the next window.
1544	 */
1545	if (ccb->pkt_cookie == ccb->pkt_ncookies) {
1546		/*
1547		 * only dma map "partial" arrive here
1548		 */
1549		if ((ccb->pkt_curwin == ccb->pkt_nwin) &&
1550		    (ccb->pkt_nwin == 1)) {
1551			cmn_err(CE_CONT,
1552			    "arcmsr%d: dma partial set, but only "
1553			    "one window allocated",
1554			    ddi_get_instance(acb->dev_info));
1555			return (DDI_SUCCESS);
1556		}
1557
1558		/* At last window, cannot move */
1559		if (++ccb->pkt_curwin >= ccb->pkt_nwin) {
1560			cmn_err(CE_WARN,
1561			    "arcmsr%d: dma partial set, numwin exceeded",
1562			    ddi_get_instance(acb->dev_info));
1563			return (DDI_FAILURE);
1564		}
1565		if (ddi_dma_getwin(ccb->pkt_dma_handle, ccb->pkt_curwin,
1566		    &ccb->pkt_dma_offset, &ccb->pkt_dma_len,
1567		    &ccb->pkt_dmacookies[i], &ccb->pkt_ncookies) ==
1568		    DDI_FAILURE) {
1569			cmn_err(CE_WARN,
1570			    "arcmsr%d: dma partial set, "
1571			    "ddi_dma_getwin failure",
1572			    ddi_get_instance(acb->dev_info));
1573			return (DDI_FAILURE);
1574		}
1575		/* reset cookie pointer */
1576		ccb->pkt_cookie = 0;
1577	} else {
1578		/*
1579		 * only dma map "all" arrive here
1580		 * We still have more cookies in this window,
1581		 * get the next one
1582		 * access the pkt_dma_handle remain cookie record at
1583		 * ccb->pkt_dmacookies array
1584		 */
1585		ddi_dma_nextcookie(ccb->pkt_dma_handle,
1586		    &ccb->pkt_dmacookies[i]);
1587	}
1588
1589	/* Get remaining cookies in this window, up to our maximum */
1590	total_ccb_xferlen += ccb->pkt_dmacookies[i].dmac_size;
1591
1592	/* retrieve and store cookies, start at ccb->pkt_dmacookies[0] */
1593	for (;;) {
1594		i++;
1595		/* handled cookies count level indicator */
1596		ccb->pkt_cookie++;
1597		if (i == ARCMSR_MAX_SG_ENTRIES ||
1598		    ccb->pkt_cookie == ccb->pkt_ncookies ||
1599		    total_ccb_xferlen == ARCMSR_MAX_XFER_LEN) {
1600			break;
1601		}
1602		ddi_dma_nextcookie(ccb->pkt_dma_handle,
1603		    &ccb->pkt_dmacookies[i]);
1604		total_ccb_xferlen += ccb->pkt_dmacookies[i].dmac_size;
1605	}
1606
1607	ccb->arcmsr_cdb.sgcount = i;
1608	if (total_ccb_xferlen > 512) {
1609		resid = total_ccb_xferlen % 512;
1610		if (resid != 0) {
1611			i--;
1612			total_ccb_xferlen -= resid;
1613			/* modify last sg length */
1614			ccb->pkt_dmacookies[i].dmac_size =
1615			    ccb->pkt_dmacookies[i].dmac_size - resid;
1616			ccb->resid_dmacookie.dmac_size = resid;
1617			ccb->resid_dmacookie.dmac_laddress =
1618			    ccb->pkt_dmacookies[i].dmac_laddress +
1619			    ccb->pkt_dmacookies[i].dmac_size;
1620		}
1621	}
1622	ccb->total_dmac_size += total_ccb_xferlen;
1623	pkt->pkt_resid = bp->b_bcount - ccb->total_dmac_size;
1624
1625	return (DDI_SUCCESS);
1626}
1627
1628/*
1629 * Function name: arcmsr_tran_destroy_pkt
1630 * Return Values: none
1631 *   Description: Called by kernel on behalf of a target driver
1632 *	          calling scsi_destroy_pkt(9F).
1633 *	          Refer to tran_destroy_pkt(9E) man page
1634 *       Context: Can be called from different kernel process threads.
1635 *	          Can be called by interrupt thread.
1636 */
1637static void
1638arcmsr_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) {
1639
1640	struct CCB *ccb = pkt->pkt_ha_private;
1641
1642	if ((ccb != NULL) && (ccb->pkt == pkt)) {
1643		struct ACB *acb = ccb->acb;
1644		if (ccb->ccb_flags & CCB_FLAG_DMAVALID) {
1645			if (ddi_dma_unbind_handle(ccb->pkt_dma_handle)
1646			    != DDI_SUCCESS) {
1647				cmn_err(CE_WARN,
1648				    "arcmsr%d: ddi_dma_unbind_handle() failed",
1649				    ddi_get_instance(acb->dev_info));
1650			}
1651			ddi_dma_free_handle(&ccb->pkt_dma_handle);
1652			ccb->pkt_dma_handle = NULL;
1653		}
1654		arcmsr_free_ccb(ccb);
1655	}
1656
1657	scsi_hba_pkt_free(ap, pkt);
1658}
1659
1660/*
1661 * Function name: arcmsr_tran_dmafree()
1662 * Return Values: none
1663 *   Description: free dvma resources
1664 *       Context: Can be called from different kernel process threads.
1665 *	          Can be called by interrupt thread.
1666 */
1667static void
1668arcmsr_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt) {
1669
1670	struct CCB *ccb = pkt->pkt_ha_private;
1671
1672	if (ccb->ccb_flags & CCB_FLAG_DMAVALID) {
1673		ccb->ccb_flags &= ~CCB_FLAG_DMAVALID;
1674		if (ddi_dma_unbind_handle(ccb->pkt_dma_handle)
1675		    != DDI_SUCCESS) {
1676			cmn_err(CE_WARN,
1677			    "arcmsr%d: ddi_dma_unbind_handle() failed "
1678			    "(target %d lun %d)",
1679			    ddi_get_instance(ccb->acb->dev_info),
1680			    ap->a_target, ap->a_lun);
1681		}
1682		ddi_dma_free_handle(&ccb->pkt_dma_handle);
1683		ccb->pkt_dma_handle = NULL;
1684	}
1685}
1686
1687/*
1688 * Function name: arcmsr_tran_sync_pkt()
1689 * Return Values: none
1690 *   Description: sync dma
1691 *       Context: Can be called from different kernel process threads.
1692 *		  Can be called by interrupt thread.
1693 */
1694static void
1695arcmsr_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) {
1696
1697	struct CCB *ccb;
1698
1699	ccb = pkt->pkt_ha_private;
1700
1701	if (ccb->ccb_flags & CCB_FLAG_DMAVALID) {
1702		if (ddi_dma_sync(ccb->pkt_dma_handle,
1703		    ccb->pkt_dma_offset, ccb->pkt_dma_len,
1704		    (ccb->ccb_flags & CCB_FLAG_DMAWRITE) ?
1705		    DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU)
1706			!= DDI_SUCCESS) {
1707			cmn_err(CE_WARN, "arcmsr%d: sync pkt failed "
1708			    "for target %d lun %d",
1709			    ddi_get_instance(ccb->acb->dev_info),
1710			    ap->a_target, ap->a_lun);
1711		}
1712	}
1713}
1714
1715
1716static uint8_t
1717arcmsr_hba_wait_msgint_ready(struct ACB *acb) {
1718
1719	uint32_t i;
1720	uint8_t retries = 0x00;
1721	struct HBA_msgUnit *phbamu;
1722
1723
1724	phbamu = (struct HBA_msgUnit *)acb->pmu;
1725
1726	do {
1727		for (i = 0; i < 100; i++) {
1728			if (CHIP_REG_READ32(acb->reg_mu_acc_handle0,
1729			    &phbamu->outbound_intstatus) &
1730			    ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
1731				/* clear interrupt */
1732				CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
1733				    &phbamu->outbound_intstatus,
1734				    ARCMSR_MU_OUTBOUND_MESSAGE0_INT);
1735				return (TRUE);
1736			}
1737			drv_usecwait(10000);
1738			if (ddi_in_panic()) {
1739				/* clear interrupts */
1740				CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
1741				    &phbamu->outbound_intstatus,
1742				    ARCMSR_MU_OUTBOUND_MESSAGE0_INT);
1743				return (TRUE);
1744			}
1745		} /* max 1 second */
1746	} while (retries++ < 20); /* max 20 seconds */
1747	return (FALSE);
1748}
1749
1750
1751
1752static uint8_t
1753arcmsr_hbb_wait_msgint_ready(struct ACB *acb) {
1754
1755	struct HBB_msgUnit *phbbmu;
1756	uint32_t i;
1757	uint8_t retries = 0x00;
1758
1759	phbbmu = (struct HBB_msgUnit *)acb->pmu;
1760
1761	do {
1762		for (i = 0; i < 100; i++) {
1763			if (CHIP_REG_READ32(acb->reg_mu_acc_handle0,
1764			    &phbbmu->hbb_doorbell->iop2drv_doorbell) &
1765			    ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
1766				/* clear interrupt */
1767				CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
1768				    &phbbmu->hbb_doorbell->iop2drv_doorbell,
1769				    ARCMSR_MESSAGE_INT_CLEAR_PATTERN);
1770				CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
1771				    &phbbmu->hbb_doorbell->drv2iop_doorbell,
1772				    ARCMSR_DRV2IOP_END_OF_INTERRUPT);
1773				return (TRUE);
1774			}
1775			drv_usecwait(10000);
1776			if (ddi_in_panic()) {
1777				/* clear interrupts */
1778				CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
1779				    &phbbmu->hbb_doorbell->iop2drv_doorbell,
1780				    ARCMSR_MESSAGE_INT_CLEAR_PATTERN);
1781				CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
1782				    &phbbmu->hbb_doorbell->drv2iop_doorbell,
1783				    ARCMSR_DRV2IOP_END_OF_INTERRUPT);
1784				return (TRUE);
1785			}
1786		} /* max 1 second */
1787	} while (retries++ < 20); /* max 20 seconds */
1788
1789	return (FALSE);
1790}
1791
1792
1793static void
1794arcmsr_flush_hba_cache(struct ACB *acb) {
1795
1796	struct HBA_msgUnit *phbamu;
1797	int retry_count = 30;
1798
1799	/* enlarge wait flush adapter cache time: 10 minutes */
1800
1801	phbamu = (struct HBA_msgUnit *)acb->pmu;
1802
1803	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0, &phbamu->inbound_msgaddr0,
1804	    ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
1805
1806	do {
1807		if (arcmsr_hba_wait_msgint_ready(acb)) {
1808			break;
1809		} else {
1810			retry_count--;
1811		}
1812	} while (retry_count != 0);
1813}
1814
1815
1816
1817static void
1818arcmsr_flush_hbb_cache(struct ACB *acb) {
1819
1820	struct HBB_msgUnit *phbbmu;
1821	int retry_count = 30;
1822
1823	/* enlarge wait flush adapter cache time: 10 minutes */
1824
1825	phbbmu = (struct HBB_msgUnit *)acb->pmu;
1826	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
1827	    &phbbmu->hbb_doorbell->drv2iop_doorbell,
1828	    ARCMSR_MESSAGE_FLUSH_CACHE);
1829
1830	do {
1831		if (arcmsr_hbb_wait_msgint_ready(acb)) {
1832			break;
1833		} else {
1834			retry_count--;
1835		}
1836	} while (retry_count != 0);
1837}
1838
1839
1840static void
1841arcmsr_ccb_complete(struct CCB *ccb, int flag) {
1842
1843	struct ACB *acb = ccb->acb;
1844	struct scsi_pkt *pkt = ccb->pkt;
1845
1846	if (flag == 1) {
1847		acb->ccboutstandingcount--;
1848	}
1849	pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
1850	    STATE_SENT_CMD | STATE_GOT_STATUS);
1851
1852	if ((ccb->ccb_flags & CCB_FLAG_DMACONSISTENT) &&
1853	    (pkt->pkt_state & STATE_XFERRED_DATA)) {
1854		(void) ddi_dma_sync(ccb->pkt_dma_handle,
1855		    ccb->pkt_dma_offset, ccb->pkt_dma_len,
1856		    DDI_DMA_SYNC_FORCPU);
1857	}
1858
1859	if (pkt->pkt_comp) {
1860		(*pkt->pkt_comp)(pkt);
1861	}
1862}
1863
1864
1865static void
1866arcmsr_report_sense_info(struct CCB *ccb) {
1867
1868	struct scsi_pkt *pkt = ccb->pkt;
1869	struct scsi_arq_status *arq_status;
1870
1871
1872	arq_status = (struct scsi_arq_status *)(intptr_t)(pkt->pkt_scbp);
1873	bzero((caddr_t)arq_status, sizeof (struct scsi_arq_status));
1874	arq_status->sts_rqpkt_reason = CMD_CMPLT;
1875	arq_status->sts_rqpkt_state = (STATE_GOT_BUS | STATE_GOT_TARGET |
1876	    STATE_SENT_CMD | STATE_XFERRED_DATA | STATE_GOT_STATUS);
1877	arq_status->sts_rqpkt_statistics = pkt->pkt_statistics;
1878	arq_status->sts_rqpkt_resid = 0;
1879
1880	pkt->pkt_reason = CMD_CMPLT;
1881	/* auto rqsense took place */
1882	pkt->pkt_state = (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
1883	    STATE_GOT_STATUS | STATE_ARQ_DONE);
1884
1885	if (&arq_status->sts_sensedata != NULL) {
1886		struct SENSE_DATA *cdb_sensedata;
1887		struct scsi_extended_sense *sts_sensedata;
1888
1889		cdb_sensedata =
1890		    (struct SENSE_DATA *)ccb->arcmsr_cdb.SenseData;
1891		sts_sensedata = &arq_status->sts_sensedata;
1892
1893		sts_sensedata->es_code = cdb_sensedata->ErrorCode;
1894		/* must eq CLASS_EXTENDED_SENSE (0x07) */
1895		sts_sensedata->es_class = cdb_sensedata->ErrorClass;
1896		sts_sensedata->es_valid = cdb_sensedata->Valid;
1897		sts_sensedata->es_segnum = cdb_sensedata->SegmentNumber;
1898		sts_sensedata->es_key = cdb_sensedata->SenseKey;
1899		sts_sensedata->es_ili = cdb_sensedata->IncorrectLength;
1900		sts_sensedata->es_eom = cdb_sensedata->EndOfMedia;
1901		sts_sensedata->es_filmk = cdb_sensedata->FileMark;
1902		sts_sensedata->es_info_1 = cdb_sensedata->Information[0];
1903		sts_sensedata->es_info_2 = cdb_sensedata->Information[1];
1904		sts_sensedata->es_info_3 = cdb_sensedata->Information[2];
1905		sts_sensedata->es_info_4 = cdb_sensedata->Information[3];
1906		sts_sensedata->es_add_len =
1907		    cdb_sensedata->AdditionalSenseLength;
1908		sts_sensedata->es_cmd_info[0] =
1909		    cdb_sensedata->CommandSpecificInformation[0];
1910		sts_sensedata->es_cmd_info[1] =
1911		    cdb_sensedata->CommandSpecificInformation[1];
1912		sts_sensedata->es_cmd_info[2] =
1913		    cdb_sensedata->CommandSpecificInformation[2];
1914		sts_sensedata->es_cmd_info[3] =
1915		    cdb_sensedata->CommandSpecificInformation[3];
1916		sts_sensedata->es_add_code =
1917		    cdb_sensedata->AdditionalSenseCode;
1918		sts_sensedata->es_qual_code =
1919		    cdb_sensedata->AdditionalSenseCodeQualifier;
1920		sts_sensedata->es_fru_code =
1921		    cdb_sensedata->FieldReplaceableUnitCode;
1922	}
1923}
1924
1925
1926
1927static void
1928arcmsr_abort_hba_allcmd(struct ACB *acb) {
1929
1930	struct HBA_msgUnit *phbamu;
1931
1932	phbamu = (struct HBA_msgUnit *)acb->pmu;
1933
1934	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
1935	    &phbamu->inbound_msgaddr0,
1936	    ARCMSR_INBOUND_MESG0_ABORT_CMD);
1937
1938	if (!arcmsr_hba_wait_msgint_ready(acb)) {
1939		cmn_err(CE_WARN,
1940		    "arcmsr%d: timeout while waiting for 'abort all "
1941		    "outstanding commands'",
1942		    ddi_get_instance(acb->dev_info));
1943	}
1944}
1945
1946
1947
1948static void
1949arcmsr_abort_hbb_allcmd(struct ACB *acb) {
1950
1951	struct HBB_msgUnit *phbbmu =
1952	    (struct HBB_msgUnit *)acb->pmu;
1953
1954	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
1955	    &phbbmu->hbb_doorbell->drv2iop_doorbell,
1956	    ARCMSR_MESSAGE_ABORT_CMD);
1957
1958	if (!arcmsr_hbb_wait_msgint_ready(acb)) {
1959		cmn_err(CE_WARN,
1960		    "arcmsr%d: timeout while waiting for 'abort all "
1961		    "outstanding commands'",
1962		    ddi_get_instance(acb->dev_info));
1963	}
1964}
1965
1966static void
1967arcmsr_report_ccb_state(struct ACB *acb,
1968    struct CCB *ccb, uint32_t flag_ccb) {
1969
1970	int id, lun;
1971
1972	id = ccb->pkt->pkt_address.a_target;
1973	lun = ccb->pkt->pkt_address.a_lun;
1974
1975	if ((flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR) == 0) {
1976		if (acb->devstate[id][lun] == ARECA_RAID_GONE) {
1977			acb->devstate[id][lun] = ARECA_RAID_GOOD;
1978		}
1979		ccb->pkt->pkt_reason = CMD_CMPLT;
1980		ccb->pkt->pkt_state |= STATE_XFERRED_DATA;
1981		arcmsr_ccb_complete(ccb, 1);
1982	} else {
1983		switch (ccb->arcmsr_cdb.DeviceStatus) {
1984		case ARCMSR_DEV_SELECT_TIMEOUT:
1985			if (acb->devstate[id][lun] == ARECA_RAID_GOOD) {
1986				cmn_err(CE_CONT,
1987				    "arcmsr%d: raid volume was kicked out ",
1988				    ddi_get_instance(acb->dev_info));
1989			}
1990			acb->devstate[id][lun] = ARECA_RAID_GONE;
1991			ccb->pkt->pkt_reason = CMD_TIMEOUT;
1992			ccb->pkt->pkt_statistics |= STAT_TIMEOUT;
1993			arcmsr_ccb_complete(ccb, 1);
1994			break;
1995		case ARCMSR_DEV_ABORTED:
1996		case ARCMSR_DEV_INIT_FAIL:
1997			cmn_err(CE_CONT,
1998			    "arcmsr%d: isr got "
1999			    "'ARCMSR_DEV_ABORTED' 'ARCMSR_DEV_INIT_FAIL'",
2000			    ddi_get_instance(acb->dev_info));
2001			cmn_err(CE_CONT, "arcmsr%d: raid volume was kicked "
2002			    "out", ddi_get_instance(acb->dev_info));
2003			acb->devstate[id][lun] = ARECA_RAID_GONE;
2004			ccb->pkt->pkt_reason = CMD_DEV_GONE;
2005			ccb->pkt->pkt_statistics |= STAT_TERMINATED;
2006			arcmsr_ccb_complete(ccb, 1);
2007			break;
2008		case SCSISTAT_CHECK_CONDITION:
2009			acb->devstate[id][lun] = ARECA_RAID_GOOD;
2010			arcmsr_report_sense_info(ccb);
2011			arcmsr_ccb_complete(ccb, 1);
2012			break;
2013		default:
2014			cmn_err(CE_WARN, "arcmsr%d: target %d lun %d "
2015			    "isr received CMD_DONE with unknown "
2016			    "DeviceStatus (0x%x)",
2017			    ddi_get_instance(acb->dev_info), id, lun,
2018			    ccb->arcmsr_cdb.DeviceStatus);
2019			cmn_err(CE_CONT, "arcmsr%d: raid volume was kicked "
2020			    "out ", ddi_get_instance(acb->dev_info));
2021			acb->devstate[id][lun] = ARECA_RAID_GONE;
2022			/* unknown error or crc error just for retry */
2023			ccb->pkt->pkt_reason = CMD_TRAN_ERR;
2024			ccb->pkt->pkt_statistics |= STAT_TERMINATED;
2025			arcmsr_ccb_complete(ccb, 1);
2026			break;
2027		}
2028	}
2029}
2030
2031
2032static void
2033arcmsr_drain_donequeue(struct ACB *acb, uint32_t flag_ccb) {
2034
2035	struct CCB *ccb;
2036
2037	/* check if command completed without error */
2038	ccb = (struct CCB *)(acb->vir2phy_offset +
2039	    (flag_ccb << 5)); /* frame must be aligned on 32 byte boundary */
2040
2041	if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) 	{
2042		if (ccb->startdone == ARCMSR_CCB_ABORTED) {
2043			cmn_err(CE_CONT,
2044			    "arcmsr%d: isr got aborted command "
2045			    "while draining doneq",
2046			    ddi_get_instance(acb->dev_info));
2047			ccb->pkt->pkt_reason = CMD_ABORTED;
2048			ccb->pkt->pkt_statistics |= STAT_ABORTED;
2049			arcmsr_ccb_complete(ccb, 1);
2050			return;
2051		}
2052
2053		if (ccb->startdone == ARCMSR_CCB_RESET) {
2054			cmn_err(CE_CONT,
2055			    "arcmsr%d: isr got command reset "
2056			    "while draining doneq",
2057			    ddi_get_instance(acb->dev_info));
2058			ccb->pkt->pkt_reason = CMD_RESET;
2059			ccb->pkt->pkt_statistics |= STAT_BUS_RESET;
2060			arcmsr_ccb_complete(ccb, 1);
2061			return;
2062		}
2063
2064		cmn_err(CE_WARN, "arcmsr%d: isr got an illegal ccb command "
2065		    "done while draining doneq",
2066		    ddi_get_instance(acb->dev_info));
2067		return;
2068	}
2069	arcmsr_report_ccb_state(acb, ccb, flag_ccb);
2070}
2071
2072
2073static void
2074arcmsr_done4abort_postqueue(struct ACB *acb) {
2075
2076	int i = 0;
2077	uint32_t flag_ccb;
2078
2079	switch (acb->adapter_type) {
2080	case ACB_ADAPTER_TYPE_A:
2081	{
2082		struct HBA_msgUnit *phbamu;
2083		uint32_t outbound_intstatus;
2084
2085		phbamu = (struct HBA_msgUnit *)acb->pmu;
2086		/* clear and abort all outbound posted Q */
2087		outbound_intstatus = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
2088		    &phbamu->outbound_intstatus) & acb->outbound_int_enable;
2089		/* clear interrupt */
2090		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
2091		    &phbamu->outbound_intstatus, outbound_intstatus);
2092		while (((flag_ccb = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
2093		    &phbamu->outbound_queueport)) != 0xFFFFFFFF) &&
2094		    (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
2095			arcmsr_drain_donequeue(acb, flag_ccb);
2096		}
2097	}
2098		break;
2099
2100	case ACB_ADAPTER_TYPE_B:
2101	{
2102		struct HBB_msgUnit *phbbmu;
2103
2104		phbbmu = (struct HBB_msgUnit *)acb->pmu;
2105
2106		/* clear all outbound posted Q */
2107		/* clear doorbell interrupt */
2108		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
2109		    &phbbmu->hbb_doorbell->iop2drv_doorbell,
2110		    ARCMSR_DOORBELL_INT_CLEAR_PATTERN);
2111		for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) {
2112			if ((flag_ccb = phbbmu->done_qbuffer[i]) != 0) {
2113				phbbmu->done_qbuffer[i] = 0;
2114				arcmsr_drain_donequeue(acb, flag_ccb);
2115			}
2116			phbbmu->post_qbuffer[i] = 0;
2117		}	/* drain reply FIFO */
2118		phbbmu->doneq_index = 0;
2119		phbbmu->postq_index = 0;
2120		break;
2121	}
2122	}
2123}
2124
2125/*
2126 * Routine Description: Reset 80331 iop.
2127 *           Arguments:
2128 *        Return Value: Nothing.
2129 */
2130static void
2131arcmsr_iop_reset(struct ACB *acb) {
2132
2133	struct CCB *ccb;
2134	uint32_t intmask_org;
2135	int i = 0;
2136
2137	if (acb->ccboutstandingcount > 0) {
2138		/* disable all outbound interrupt */
2139		intmask_org = arcmsr_disable_allintr(acb);
2140		/* talk to iop 331 outstanding command aborted */
2141		if (acb->adapter_type == ACB_ADAPTER_TYPE_A) {
2142			arcmsr_abort_hba_allcmd(acb);
2143		} else {
2144			arcmsr_abort_hbb_allcmd(acb);
2145		}
2146		/* clear and abort all outbound posted Q */
2147		arcmsr_done4abort_postqueue(acb);
2148
2149		for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
2150			ccb = acb->pccb_pool[i];
2151			if (ccb->startdone == ARCMSR_CCB_START) {
2152				ccb->startdone = ARCMSR_CCB_RESET;
2153				ccb->pkt->pkt_reason = CMD_RESET;
2154				ccb->pkt->pkt_statistics |= STAT_BUS_RESET;
2155				arcmsr_ccb_complete(ccb, 1);
2156			}
2157		}
2158		/* enable all outbound interrupt */
2159		arcmsr_enable_allintr(acb, intmask_org);
2160	}
2161}
2162
2163/*
2164 * You can access the DMA address through the #defines:
2165 * dmac_address for 32-bit addresses and dmac_laddress for 64-bit addresses.
2166 *	These macros are defined as follows:
2167 *
2168 *	#define dmac_laddress   _dmu._dmac_ll
2169 *	#ifdef _LONG_LONG_HTOL
2170 *		#define dmac_notused    _dmu._dmac_la[0]
2171 *		#define dmac_address    _dmu._dmac_la[1]
2172 *	#else
2173 *		#define dmac_address    _dmu._dmac_la[0]
2174 *		#define dmac_notused    _dmu._dmac_la[1]
2175 *	#endif
2176 */
2177/*ARGSUSED*/
2178static void
2179arcmsr_build_ccb(struct CCB *ccb) {
2180
2181	struct scsi_pkt *pkt = ccb->pkt;
2182	struct ARCMSR_CDB *arcmsr_cdb;
2183	char *psge;
2184	uint32_t address_lo, address_hi;
2185	int arccdbsize = 0x30;
2186	uint8_t sgcount;
2187
2188	arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb;
2189	psge = (char *)&arcmsr_cdb->sgu;
2190
2191	/* return the current time in seconds */
2192	ccb->ccb_time = (time_t)(pkt->pkt_time + ddi_get_time());
2193	bcopy((caddr_t)pkt->pkt_cdbp, arcmsr_cdb->Cdb,
2194	    arcmsr_cdb->CdbLength);
2195	sgcount = ccb->arcmsr_cdb.sgcount;
2196
2197	if (sgcount) {
2198		int length, i;
2199		int cdb_sgcount = 0;
2200		int total_xfer_length = 0;
2201
2202		/* map stor port SG list to our iop SG List. */
2203		for (i = 0; i < sgcount; i++) {
2204			/* Get physaddr of the current data pointer */
2205			length = ccb->pkt_dmacookies[i].dmac_size;
2206			total_xfer_length += length;
2207			address_lo = dma_addr_lo32(
2208				ccb->pkt_dmacookies[i].dmac_laddress);
2209			address_hi = dma_addr_hi32(
2210				ccb->pkt_dmacookies[i].dmac_laddress);
2211
2212			if (address_hi == 0) {
2213				struct SG32ENTRY *dma_sg;
2214
2215				dma_sg = (struct SG32ENTRY *)(intptr_t)psge;
2216
2217				dma_sg->address = address_lo;
2218				dma_sg->length = length;
2219				psge += sizeof (struct SG32ENTRY);
2220				arccdbsize += sizeof (struct SG32ENTRY);
2221			} else {
2222				int sg64s_size = 0;
2223				int tmplength = length;
2224				int64_t span4G, length0;
2225				struct SG64ENTRY *dma_sg;
2226
2227				/*LINTED*/
2228				while (1) {
2229					dma_sg =
2230					    (struct SG64ENTRY *)(intptr_t)psge;
2231					span4G =
2232					    (int64_t)address_lo + tmplength;
2233
2234					dma_sg->addresshigh = address_hi;
2235					dma_sg->address = address_lo;
2236					if (span4G > 0x100000000ULL) {
2237						/* see if we cross 4G */
2238						length0 = 0x100000000ULL -
2239						    address_lo;
2240						dma_sg->length =
2241						    (uint32_t)length0 |
2242						    IS_SG64_ADDR;
2243						address_hi = address_hi + 1;
2244						address_lo = 0;
2245						tmplength = tmplength-
2246						    (int32_t)length0;
2247						sg64s_size +=
2248						    sizeof (struct SG64ENTRY);
2249						psge +=
2250						    sizeof (struct SG64ENTRY);
2251						cdb_sgcount++;
2252					} else {
2253						dma_sg->length = tmplength |
2254						    IS_SG64_ADDR;
2255						sg64s_size +=
2256						    sizeof (struct SG64ENTRY);
2257						psge +=
2258						    sizeof (struct SG64ENTRY);
2259						break;
2260					}
2261				}
2262				arccdbsize += sg64s_size;
2263			}
2264			cdb_sgcount++;
2265		}
2266		arcmsr_cdb->sgcount = (uint8_t)cdb_sgcount;
2267		arcmsr_cdb->DataLength = total_xfer_length;
2268		if (arccdbsize > 256) {
2269			arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE;
2270		}
2271	} else {
2272		arcmsr_cdb->DataLength = 0;
2273	}
2274
2275	if (ccb->ccb_flags & CCB_FLAG_DMAWRITE)
2276		arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE;
2277}
2278
2279/*
2280 * arcmsr_post_ccb - Send a protocol specific ARC send postcard to a AIOC.
2281 *
2282 * handle:		Handle of registered ARC protocol driver
2283 * adapter_id:		AIOC unique identifier(integer)
2284 * pPOSTCARD_SEND:	Pointer to ARC send postcard
2285 *
2286 * This routine posts a ARC send postcard to the request post FIFO of a
2287 * specific ARC adapter.
2288 */
2289static int
2290arcmsr_post_ccb(struct ACB *acb, struct CCB *ccb) {
2291
2292	uint32_t cdb_shifted_phyaddr = ccb->cdb_shifted_phyaddr;
2293	struct scsi_pkt *pkt = ccb->pkt;
2294	struct ARCMSR_CDB *arcmsr_cdb;
2295
2296	arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb;
2297
2298	/* Use correct offset and size for syncing */
2299	if (ddi_dma_sync(acb->ccbs_pool_handle, 0, acb->dma_sync_size,
2300	    DDI_DMA_SYNC_FORDEV) == DDI_FAILURE)
2301		return (DDI_FAILURE);
2302
2303	acb->ccboutstandingcount++;
2304	ccb->startdone = ARCMSR_CCB_START;
2305
2306	switch (acb->adapter_type) {
2307	case ACB_ADAPTER_TYPE_A:
2308	{
2309		struct HBA_msgUnit *phbamu;
2310
2311		phbamu = (struct HBA_msgUnit *)acb->pmu;
2312
2313		if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) {
2314			CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
2315			    &phbamu->inbound_queueport,
2316			    cdb_shifted_phyaddr |
2317			    ARCMSR_CCBPOST_FLAG_SGL_BSIZE);
2318		} else {
2319			CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
2320			    &phbamu->inbound_queueport, cdb_shifted_phyaddr);
2321		}
2322		if (pkt->pkt_flags & FLAG_NOINTR)
2323			arcmsr_polling_hba_ccbdone(acb, ccb);
2324	}
2325		break;
2326	case ACB_ADAPTER_TYPE_B:
2327	{
2328		struct HBB_msgUnit *phbbmu;
2329		int ending_index, index;
2330
2331		phbbmu = (struct HBB_msgUnit *)acb->pmu;
2332		mutex_enter(&acb->postq_mutex);
2333		index = phbbmu->postq_index;
2334		ending_index = ((index+1)%ARCMSR_MAX_HBB_POSTQUEUE);
2335		phbbmu->post_qbuffer[ending_index] = 0;
2336		if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) {
2337			phbbmu->post_qbuffer[index] =
2338			    (cdb_shifted_phyaddr|ARCMSR_CCBPOST_FLAG_SGL_BSIZE);
2339		} else {
2340			phbbmu->post_qbuffer[index] = cdb_shifted_phyaddr;
2341		}
2342		index++;
2343		/* if last index number set it to 0 */
2344		index %= ARCMSR_MAX_HBB_POSTQUEUE;
2345		phbbmu->postq_index = index;
2346		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
2347		    &phbbmu->hbb_doorbell->drv2iop_doorbell,
2348		    ARCMSR_DRV2IOP_CDB_POSTED);
2349		mutex_exit(&acb->postq_mutex);
2350		if (pkt->pkt_flags & FLAG_NOINTR)
2351			arcmsr_polling_hbb_ccbdone(acb, ccb);
2352	}
2353	break;
2354	}
2355
2356	return (DDI_SUCCESS);
2357}
2358
2359
2360
2361
2362static struct QBUFFER *
2363arcmsr_get_iop_rqbuffer(struct ACB *acb) {
2364
2365	struct QBUFFER *qb;
2366
2367	switch (acb->adapter_type) {
2368	case ACB_ADAPTER_TYPE_A:
2369	{
2370		struct HBA_msgUnit *phbamu;
2371
2372		phbamu = (struct HBA_msgUnit *)acb->pmu;
2373		qb = (struct QBUFFER *)&phbamu->message_rbuffer;
2374	}
2375		break;
2376	case ACB_ADAPTER_TYPE_B:
2377	{
2378		struct HBB_msgUnit *phbbmu;
2379
2380		phbbmu = (struct HBB_msgUnit *)acb->pmu;
2381		qb = (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_rbuffer;
2382	}
2383		break;
2384	}
2385
2386	return (qb);
2387}
2388
2389
2390
2391static struct QBUFFER *
2392arcmsr_get_iop_wqbuffer(struct ACB *acb) {
2393
2394	struct QBUFFER *qbuffer = NULL;
2395
2396	switch (acb->adapter_type) {
2397	case ACB_ADAPTER_TYPE_A:
2398	{
2399		struct HBA_msgUnit *phbamu;
2400
2401		phbamu = (struct HBA_msgUnit *)acb->pmu;
2402		qbuffer = (struct QBUFFER *)&phbamu->message_wbuffer;
2403	}
2404	break;
2405	case ACB_ADAPTER_TYPE_B:
2406	{
2407		struct HBB_msgUnit *phbbmu;
2408
2409		phbbmu = (struct HBB_msgUnit *)acb->pmu;
2410		qbuffer =
2411		    (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_wbuffer;
2412	}
2413	break;
2414	}
2415	return (qbuffer);
2416}
2417
2418
2419
2420static void
2421arcmsr_iop_message_read(struct ACB *acb) {
2422
2423	switch (acb->adapter_type) {
2424	case ACB_ADAPTER_TYPE_A:
2425	{
2426		struct HBA_msgUnit *phbamu;
2427
2428		phbamu = (struct HBA_msgUnit *)acb->pmu;
2429		/* let IOP know the data has been read */
2430		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
2431		    &phbamu->inbound_doorbell,
2432		    ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
2433	}
2434	break;
2435	case ACB_ADAPTER_TYPE_B:
2436	{
2437		struct HBB_msgUnit *phbbmu;
2438
2439		phbbmu = (struct HBB_msgUnit *)acb->pmu;
2440		/* let IOP know the data has been read */
2441		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
2442		    &phbbmu->hbb_doorbell->drv2iop_doorbell,
2443		    ARCMSR_DRV2IOP_DATA_READ_OK);
2444	}
2445	break;
2446	}
2447}
2448
2449
2450
2451static void
2452arcmsr_iop_message_wrote(struct ACB *acb) {
2453
2454	switch (acb->adapter_type) {
2455	case ACB_ADAPTER_TYPE_A:
2456	{
2457		struct HBA_msgUnit *phbamu;
2458
2459		phbamu = (struct HBA_msgUnit *)acb->pmu;
2460		/*
2461		 * push inbound doorbell tell iop, driver data write ok
2462		 * and wait reply on next hwinterrupt for next Qbuffer post
2463		 */
2464		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
2465		    &phbamu->inbound_doorbell,
2466		    ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK);
2467	}
2468	break;
2469	case ACB_ADAPTER_TYPE_B:
2470	{
2471		struct HBB_msgUnit *phbbmu;
2472
2473		phbbmu = (struct HBB_msgUnit *)acb->pmu;
2474		/*
2475		 * push inbound doorbell tell iop, driver data was writen
2476		 * successfully, then await reply on next hwinterrupt for
2477		 * next Qbuffer post
2478		 */
2479		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
2480		    &phbbmu->hbb_doorbell->drv2iop_doorbell,
2481		    ARCMSR_DRV2IOP_DATA_WRITE_OK);
2482	}
2483	break;
2484	}
2485}
2486
2487
2488
2489static void
2490arcmsr_post_ioctldata2iop(struct ACB *acb) {
2491
2492	uint8_t *pQbuffer;
2493	struct QBUFFER *pwbuffer;
2494	uint8_t *iop_data;
2495	int32_t allxfer_len = 0;
2496
2497	pwbuffer = arcmsr_get_iop_wqbuffer(acb);
2498	iop_data = (uint8_t *)pwbuffer->data;
2499	if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) {
2500		acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ);
2501		while ((acb->wqbuf_firstidx != acb->wqbuf_lastidx) &&
2502		    (allxfer_len < 124)) {
2503			pQbuffer = &acb->wqbuffer[acb->wqbuf_firstidx];
2504			(void) memcpy(iop_data, pQbuffer, 1);
2505			acb->wqbuf_firstidx++;
2506			/* if last index number set it to 0 */
2507			acb->wqbuf_firstidx %= ARCMSR_MAX_QBUFFER;
2508			iop_data++;
2509			allxfer_len++;
2510		}
2511		pwbuffer->data_len = allxfer_len;
2512		/*
2513		 * push inbound doorbell and wait reply at hwinterrupt
2514		 * routine for next Qbuffer post
2515		 */
2516		arcmsr_iop_message_wrote(acb);
2517	}
2518}
2519
2520
2521
2522static void
2523arcmsr_stop_hba_bgrb(struct ACB *acb) {
2524
2525	struct HBA_msgUnit *phbamu;
2526
2527	phbamu = (struct HBA_msgUnit *)acb->pmu;
2528
2529	acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
2530	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
2531	    &phbamu->inbound_msgaddr0,
2532	    ARCMSR_INBOUND_MESG0_STOP_BGRB);
2533	if (!arcmsr_hba_wait_msgint_ready(acb))
2534		cmn_err(CE_WARN,
2535		    "arcmsr%d: timeout while waiting for background "
2536		    "rebuild completion",
2537		    ddi_get_instance(acb->dev_info));
2538}
2539
2540
2541static void
2542arcmsr_stop_hbb_bgrb(struct ACB *acb) {
2543
2544	struct HBB_msgUnit *phbbmu;
2545
2546	phbbmu = (struct HBB_msgUnit *)acb->pmu;
2547
2548	acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
2549	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
2550	    &phbbmu->hbb_doorbell->drv2iop_doorbell,
2551	    ARCMSR_MESSAGE_STOP_BGRB);
2552
2553	if (!arcmsr_hbb_wait_msgint_ready(acb))
2554		cmn_err(CE_WARN,
2555		    "arcmsr%d: timeout while waiting for background "
2556		    "rebuild completion",
2557		    ddi_get_instance(acb->dev_info));
2558}
2559
2560static int
2561arcmsr_iop_message_xfer(struct ACB *acb, struct scsi_pkt *pkt) {
2562
2563	struct CMD_MESSAGE_FIELD *pcmdmessagefld;
2564	struct CCB *ccb = pkt->pkt_ha_private;
2565	struct buf *bp = ccb->bp;
2566	uint8_t *pQbuffer;
2567	int retvalue = 0, transfer_len = 0;
2568	char *buffer;
2569	uint32_t controlcode;
2570
2571
2572	/* 4 bytes: Areca io control code */
2573	controlcode = (uint32_t)pkt->pkt_cdbp[5] << 24 |
2574	    (uint32_t)pkt->pkt_cdbp[6] << 16 |
2575	    (uint32_t)pkt->pkt_cdbp[7] << 8 |
2576	    (uint32_t)pkt->pkt_cdbp[8];
2577
2578	if (bp->b_flags & (B_PHYS | B_PAGEIO))
2579		bp_mapin(bp);
2580
2581
2582	buffer = bp->b_un.b_addr;
2583	transfer_len = bp->b_bcount;
2584	if (transfer_len > sizeof (struct CMD_MESSAGE_FIELD)) {
2585		retvalue = ARCMSR_MESSAGE_FAIL;
2586		goto message_out;
2587	}
2588
2589	pcmdmessagefld = (struct CMD_MESSAGE_FIELD *)(intptr_t)buffer;
2590
2591	switch (controlcode) {
2592	case ARCMSR_MESSAGE_READ_RQBUFFER:
2593	{
2594		unsigned long *ver_addr;
2595		uint8_t *ptmpQbuffer;
2596		int32_t allxfer_len = 0;
2597
2598		ver_addr = kmem_zalloc(MSGDATABUFLEN, KM_SLEEP);
2599		if (!ver_addr) {
2600			retvalue = ARCMSR_MESSAGE_FAIL;
2601			goto message_out;
2602		}
2603
2604		ptmpQbuffer = (uint8_t *)ver_addr;
2605		while ((acb->rqbuf_firstidx != acb->rqbuf_lastidx) &&
2606		    (allxfer_len < (MSGDATABUFLEN - 1))) {
2607			pQbuffer = &acb->rqbuffer[acb->rqbuf_firstidx];
2608			(void) memcpy(ptmpQbuffer, pQbuffer, 1);
2609			acb->rqbuf_firstidx++;
2610			acb->rqbuf_firstidx %= ARCMSR_MAX_QBUFFER;
2611			ptmpQbuffer++;
2612			allxfer_len++;
2613		}
2614
2615		if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
2616			struct QBUFFER *prbuffer;
2617			uint8_t  *iop_data;
2618			int32_t iop_len;
2619
2620			acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
2621			prbuffer = arcmsr_get_iop_rqbuffer(acb);
2622			iop_data = (uint8_t *)prbuffer->data;
2623			iop_len = (int32_t)prbuffer->data_len;
2624
2625			while (iop_len > 0) {
2626				pQbuffer = &acb->rqbuffer[acb->rqbuf_lastidx];
2627				(void) memcpy(pQbuffer, iop_data, 1);
2628				acb->rqbuf_lastidx++;
2629				acb->rqbuf_lastidx %= ARCMSR_MAX_QBUFFER;
2630				iop_data++;
2631				iop_len--;
2632			}
2633			arcmsr_iop_message_read(acb);
2634		}
2635
2636		(void) memcpy(pcmdmessagefld->messagedatabuffer,
2637		    (uint8_t *)ver_addr, allxfer_len);
2638		pcmdmessagefld->cmdmessage.Length = allxfer_len;
2639		pcmdmessagefld->cmdmessage.ReturnCode =
2640		    ARCMSR_MESSAGE_RETURNCODE_OK;
2641		kmem_free(ver_addr, MSGDATABUFLEN);
2642	}
2643	break;
2644	case ARCMSR_MESSAGE_WRITE_WQBUFFER:
2645	{
2646		unsigned long *ver_addr;
2647		int32_t my_empty_len, user_len, wqbuf_firstidx, wqbuf_lastidx;
2648		uint8_t *ptmpuserbuffer;
2649
2650		ver_addr = kmem_zalloc(MSGDATABUFLEN, KM_SLEEP);
2651		if (!ver_addr) {
2652			retvalue = ARCMSR_MESSAGE_FAIL;
2653			goto message_out;
2654		}
2655		ptmpuserbuffer = (uint8_t *)ver_addr;
2656		user_len = pcmdmessagefld->cmdmessage.Length;
2657		(void) memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer,
2658		    user_len);
2659		wqbuf_lastidx = acb->wqbuf_lastidx;
2660		wqbuf_firstidx = acb->wqbuf_firstidx;
2661		if (wqbuf_lastidx != wqbuf_firstidx) {
2662			struct scsi_arq_status *arq_status;
2663
2664			arcmsr_post_ioctldata2iop(acb);
2665			arq_status =
2666			    (struct scsi_arq_status *)(intptr_t)
2667			    (pkt->pkt_scbp);
2668			bzero((caddr_t)arq_status,
2669			    sizeof (struct scsi_arq_status));
2670			arq_status->sts_rqpkt_reason = CMD_CMPLT;
2671			arq_status->sts_rqpkt_state = (STATE_GOT_BUS |
2672			    STATE_GOT_TARGET |STATE_SENT_CMD |
2673			    STATE_XFERRED_DATA | STATE_GOT_STATUS);
2674
2675			arq_status->sts_rqpkt_statistics = pkt->pkt_statistics;
2676			arq_status->sts_rqpkt_resid = 0;
2677			if (&arq_status->sts_sensedata != NULL) {
2678				struct scsi_extended_sense *sts_sensedata;
2679
2680				sts_sensedata = &arq_status->sts_sensedata;
2681
2682				/* has error report sensedata */
2683				sts_sensedata->es_code = 0x0;
2684				sts_sensedata->es_valid = 0x01;
2685				sts_sensedata->es_key = KEY_ILLEGAL_REQUEST;
2686				/* AdditionalSenseLength */
2687				sts_sensedata->es_add_len = 0x0A;
2688				/* AdditionalSenseCode */
2689				sts_sensedata->es_add_code = 0x20;
2690			}
2691			retvalue = ARCMSR_MESSAGE_FAIL;
2692		} else {
2693			my_empty_len = (wqbuf_firstidx-wqbuf_lastidx - 1) &
2694			    (ARCMSR_MAX_QBUFFER - 1);
2695			if (my_empty_len >= user_len) {
2696				while (user_len > 0) {
2697					pQbuffer =
2698					    &acb->wqbuffer[acb->wqbuf_lastidx];
2699					(void) memcpy(pQbuffer,
2700					    ptmpuserbuffer, 1);
2701					acb->wqbuf_lastidx++;
2702					acb->wqbuf_lastidx %=
2703					    ARCMSR_MAX_QBUFFER;
2704					ptmpuserbuffer++;
2705					user_len--;
2706				}
2707				if (acb->acb_flags &
2708				    ACB_F_MESSAGE_WQBUFFER_CLEARED) {
2709					acb->acb_flags &=
2710					    ~ACB_F_MESSAGE_WQBUFFER_CLEARED;
2711					arcmsr_post_ioctldata2iop(acb);
2712				}
2713			} else {
2714				struct scsi_arq_status *arq_status;
2715
2716				/* has error report sensedata */
2717				arq_status =
2718				    (struct scsi_arq_status *)
2719				    (intptr_t)(pkt->pkt_scbp);
2720				bzero((caddr_t)arq_status,
2721				    sizeof (struct scsi_arq_status));
2722				arq_status->sts_rqpkt_reason = CMD_CMPLT;
2723				arq_status->sts_rqpkt_state = (STATE_GOT_BUS |
2724				    STATE_GOT_TARGET |STATE_SENT_CMD |
2725				    STATE_XFERRED_DATA | STATE_GOT_STATUS);
2726				arq_status->sts_rqpkt_statistics =
2727				    pkt->pkt_statistics;
2728				arq_status->sts_rqpkt_resid = 0;
2729				if (&arq_status->sts_sensedata != NULL) {
2730					struct scsi_extended_sense
2731					    *sts_sensedata;
2732
2733					sts_sensedata =
2734					    &arq_status->sts_sensedata;
2735
2736					/* has error report sensedata */
2737					sts_sensedata->es_code  = 0x0;
2738					sts_sensedata->es_valid = 0x01;
2739					sts_sensedata->es_key =
2740					    KEY_ILLEGAL_REQUEST;
2741					/* AdditionalSenseLength */
2742					sts_sensedata->es_add_len = 0x0A;
2743					/* AdditionalSenseCode */
2744					sts_sensedata->es_add_code = 0x20;
2745				}
2746				retvalue = ARCMSR_MESSAGE_FAIL;
2747			}
2748		}
2749		kmem_free(ver_addr, MSGDATABUFLEN);
2750	}
2751	break;
2752	case ARCMSR_MESSAGE_CLEAR_RQBUFFER:
2753	{
2754		pQbuffer = acb->rqbuffer;
2755
2756		if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
2757			acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
2758			arcmsr_iop_message_read(acb);
2759		}
2760		acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
2761		acb->rqbuf_firstidx = 0;
2762		acb->rqbuf_lastidx = 0;
2763		(void) memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
2764		pcmdmessagefld->cmdmessage.ReturnCode =
2765		    ARCMSR_MESSAGE_RETURNCODE_OK;
2766	}
2767	break;
2768	case ARCMSR_MESSAGE_CLEAR_WQBUFFER:
2769	{
2770		pQbuffer = acb->wqbuffer;
2771
2772		if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
2773			acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
2774			arcmsr_iop_message_read(acb);
2775		}
2776		acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
2777		    ACB_F_MESSAGE_WQBUFFER_READ);
2778		acb->wqbuf_firstidx = 0;
2779		acb->wqbuf_lastidx = 0;
2780		(void) memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
2781		pcmdmessagefld->cmdmessage.ReturnCode =
2782		    ARCMSR_MESSAGE_RETURNCODE_OK;
2783	}
2784	break;
2785	case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER:
2786	{
2787
2788		if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
2789			acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
2790			arcmsr_iop_message_read(acb);
2791		}
2792		acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
2793		    ACB_F_MESSAGE_RQBUFFER_CLEARED |
2794		    ACB_F_MESSAGE_WQBUFFER_READ);
2795		acb->rqbuf_firstidx = 0;
2796		acb->rqbuf_lastidx = 0;
2797		acb->wqbuf_firstidx = 0;
2798		acb->wqbuf_lastidx = 0;
2799		pQbuffer = acb->rqbuffer;
2800		(void) memset(pQbuffer, 0, sizeof (struct QBUFFER));
2801		pQbuffer = acb->wqbuffer;
2802		(void) memset(pQbuffer, 0, sizeof (struct QBUFFER));
2803		pcmdmessagefld->cmdmessage.ReturnCode =
2804		    ARCMSR_MESSAGE_RETURNCODE_OK;
2805	}
2806	break;
2807	case ARCMSR_MESSAGE_REQUEST_RETURN_CODE_3F:
2808		pcmdmessagefld->cmdmessage.ReturnCode =
2809		    ARCMSR_MESSAGE_RETURNCODE_3F;
2810		break;
2811	/*
2812	 * Not supported - ARCMSR_MESSAGE_SAY_HELLO
2813	 */
2814	case ARCMSR_MESSAGE_SAY_GOODBYE:
2815		arcmsr_iop_parking(acb);
2816		break;
2817	case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE:
2818		if (acb->adapter_type == ACB_ADAPTER_TYPE_A) {
2819			arcmsr_flush_hba_cache(acb);
2820		} else {
2821			arcmsr_flush_hbb_cache(acb);
2822		}
2823		break;
2824	default:
2825		retvalue = ARCMSR_MESSAGE_FAIL;
2826	}
2827
2828message_out:
2829
2830	return (retvalue);
2831}
2832
2833
2834
2835static int
2836arcmsr_cb_ioctl(dev_t dev, int ioctl_cmd, intptr_t arg, int mode,
2837    cred_t *credp, int *rvalp) {
2838#ifndef __lock_lint
2839	_NOTE(ARGUNUSED(rvalp))
2840#endif
2841
2842	struct ACB *acb;
2843	struct CMD_MESSAGE_FIELD *pktioctlfld;
2844	int retvalue = 0;
2845	int instance = getminor(dev);
2846
2847
2848	if (instance < 0)
2849		return (ENXIO);
2850
2851	if (secpolicy_sys_config(credp, B_FALSE) != 0)
2852		return (EPERM);
2853
2854	acb = ddi_get_soft_state(arcmsr_soft_state, instance);
2855	if (acb == NULL)
2856		return (ENXIO);
2857
2858	pktioctlfld = kmem_zalloc(sizeof (struct CMD_MESSAGE_FIELD),
2859	    KM_SLEEP);
2860	if (pktioctlfld == NULL)
2861		return (ENXIO);
2862
2863	/*
2864	 * if we got here, we either are a 64-bit app in a 64-bit kernel
2865	 * or a 32-bit app in a 32-bit kernel. Either way, we can just
2866	 * copy in the args without any special conversions.
2867	 */
2868
2869	mutex_enter(&acb->ioctl_mutex);
2870	if (ddi_copyin((void *)arg, pktioctlfld,
2871	    sizeof (struct CMD_MESSAGE_FIELD), mode) != 0) {
2872		retvalue = ENXIO;
2873		goto ioctl_out;
2874	}
2875
2876	if (memcmp(pktioctlfld->cmdmessage.Signature, "ARCMSR", 6) != 0) {
2877		/* validity check */
2878		retvalue = ENXIO;
2879		goto ioctl_out;
2880	}
2881
2882	switch (ioctl_cmd) {
2883	case ARCMSR_MESSAGE_READ_RQBUFFER:
2884	{
2885		unsigned long *ver_addr;
2886		uint8_t *pQbuffer, *ptmpQbuffer;
2887		int32_t allxfer_len = 0;
2888
2889		ver_addr = kmem_zalloc(MSGDATABUFLEN, KM_SLEEP);
2890		if (ver_addr == NULL) {
2891			retvalue = ENXIO;
2892			goto ioctl_out;
2893		}
2894
2895		ptmpQbuffer = (uint8_t *)ver_addr;
2896		while ((acb->rqbuf_firstidx != acb->rqbuf_lastidx) &&
2897		    (allxfer_len < (MSGDATABUFLEN - 1))) {
2898			/* copy READ QBUFFER to srb */
2899			pQbuffer = &acb->rqbuffer[acb->rqbuf_firstidx];
2900			(void) memcpy(ptmpQbuffer, pQbuffer, 1);
2901			acb->rqbuf_firstidx++;
2902			/* if last index number set it to 0 */
2903			acb->rqbuf_firstidx %= ARCMSR_MAX_QBUFFER;
2904			ptmpQbuffer++;
2905			allxfer_len++;
2906		}
2907
2908		if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
2909			struct QBUFFER *prbuffer;
2910			uint8_t *pQbuffer;
2911			uint8_t *iop_data;
2912			int32_t iop_len;
2913
2914			acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
2915			prbuffer = arcmsr_get_iop_rqbuffer(acb);
2916			iop_data = (uint8_t *)prbuffer->data;
2917			iop_len = (int32_t)prbuffer->data_len;
2918			/*
2919			 * this iop data does no chance to make me overflow
2920			 * again here, so just do it
2921			 */
2922			while (iop_len > 0) {
2923				pQbuffer = &acb->rqbuffer[acb->rqbuf_lastidx];
2924				(void) memcpy(pQbuffer, iop_data, 1);
2925				acb->rqbuf_lastidx++;
2926				/* if last index number set it to 0 */
2927				acb->rqbuf_lastidx %= ARCMSR_MAX_QBUFFER;
2928				iop_data++;
2929				iop_len--;
2930			}
2931			/* let IOP know data has been read */
2932			arcmsr_iop_message_read(acb);
2933		}
2934		(void) memcpy(pktioctlfld->messagedatabuffer,
2935		    (uint8_t *)ver_addr, allxfer_len);
2936		pktioctlfld->cmdmessage.Length = allxfer_len;
2937		pktioctlfld->cmdmessage.ReturnCode =
2938		    ARCMSR_MESSAGE_RETURNCODE_OK;
2939
2940		if (ddi_copyout(pktioctlfld, (void *)arg,
2941		    sizeof (struct CMD_MESSAGE_FIELD), mode) != 0)
2942			retvalue = ENXIO;
2943
2944		kmem_free(ver_addr, MSGDATABUFLEN);
2945	}
2946	break;
2947	case ARCMSR_MESSAGE_WRITE_WQBUFFER:
2948	{
2949		unsigned long *ver_addr;
2950		int32_t my_empty_len, user_len;
2951		int32_t wqbuf_firstidx, wqbuf_lastidx;
2952		uint8_t *pQbuffer, *ptmpuserbuffer;
2953
2954		ver_addr = kmem_zalloc(MSGDATABUFLEN, KM_SLEEP);
2955
2956		if (ver_addr == NULL) {
2957			retvalue = ENXIO;
2958			goto ioctl_out;
2959		}
2960
2961		ptmpuserbuffer = (uint8_t *)ver_addr;
2962		user_len = pktioctlfld->cmdmessage.Length;
2963		(void) memcpy(ptmpuserbuffer,
2964		    pktioctlfld->messagedatabuffer, user_len);
2965		/*
2966		 * check ifdata xfer length of this request will overflow
2967		 * my array qbuffer
2968		 */
2969		wqbuf_lastidx = acb->wqbuf_lastidx;
2970		wqbuf_firstidx = acb->wqbuf_firstidx;
2971		if (wqbuf_lastidx != wqbuf_firstidx) {
2972			arcmsr_post_ioctldata2iop(acb);
2973			pktioctlfld->cmdmessage.ReturnCode =
2974			    ARCMSR_MESSAGE_RETURNCODE_ERROR;
2975		} else {
2976			my_empty_len = (wqbuf_firstidx - wqbuf_lastidx - 1)
2977			    & (ARCMSR_MAX_QBUFFER - 1);
2978			if (my_empty_len >= user_len) {
2979				while (user_len > 0) {
2980					/* copy srb data to wqbuffer */
2981					pQbuffer =
2982					    &acb->wqbuffer[acb->wqbuf_lastidx];
2983					(void) memcpy(pQbuffer,
2984					    ptmpuserbuffer, 1);
2985					acb->wqbuf_lastidx++;
2986					/* iflast index number set it to 0 */
2987					acb->wqbuf_lastidx %=
2988					    ARCMSR_MAX_QBUFFER;
2989					ptmpuserbuffer++;
2990					user_len--;
2991				}
2992				/* post first Qbuffer */
2993				if (acb->acb_flags &
2994				    ACB_F_MESSAGE_WQBUFFER_CLEARED) {
2995					acb->acb_flags &=
2996					    ~ACB_F_MESSAGE_WQBUFFER_CLEARED;
2997					arcmsr_post_ioctldata2iop(acb);
2998				}
2999				pktioctlfld->cmdmessage.ReturnCode =
3000				    ARCMSR_MESSAGE_RETURNCODE_OK;
3001			} else {
3002				pktioctlfld->cmdmessage.ReturnCode =
3003				    ARCMSR_MESSAGE_RETURNCODE_ERROR;
3004			}
3005		}
3006		if (ddi_copyout(pktioctlfld, (void *)arg,
3007		    sizeof (struct CMD_MESSAGE_FIELD), mode) != 0)
3008			retvalue = ENXIO;
3009
3010		kmem_free(ver_addr, MSGDATABUFLEN);
3011	}
3012	break;
3013	case ARCMSR_MESSAGE_CLEAR_RQBUFFER:
3014	{
3015		uint8_t *pQbuffer = acb->rqbuffer;
3016
3017		if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
3018			acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
3019				arcmsr_iop_message_read(acb);
3020		}
3021		acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
3022		acb->rqbuf_firstidx = 0;
3023		acb->rqbuf_lastidx = 0;
3024		bzero(pQbuffer, ARCMSR_MAX_QBUFFER);
3025		/* report success */
3026		pktioctlfld->cmdmessage.ReturnCode =
3027		    ARCMSR_MESSAGE_RETURNCODE_OK;
3028		if (ddi_copyout(pktioctlfld, (void *)arg,
3029		    sizeof (struct CMD_MESSAGE_FIELD), mode) != 0)
3030			retvalue = ENXIO;
3031
3032	}
3033	break;
3034	case ARCMSR_MESSAGE_CLEAR_WQBUFFER:
3035	{
3036		uint8_t *pQbuffer = acb->wqbuffer;
3037
3038		if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
3039			acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
3040			arcmsr_iop_message_read(acb);
3041		}
3042		acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
3043		    ACB_F_MESSAGE_WQBUFFER_READ);
3044		acb->wqbuf_firstidx = 0;
3045		acb->wqbuf_lastidx = 0;
3046		bzero(pQbuffer, ARCMSR_MAX_QBUFFER);
3047		/* report success */
3048		pktioctlfld->cmdmessage.ReturnCode =
3049		    ARCMSR_MESSAGE_RETURNCODE_OK;
3050		if (ddi_copyout(pktioctlfld, (void *)arg,
3051		    sizeof (struct CMD_MESSAGE_FIELD), mode) != 0)
3052			retvalue = ENXIO;
3053
3054	}
3055	break;
3056	case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER:
3057	{
3058		uint8_t *pQbuffer;
3059
3060		if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
3061			acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
3062			arcmsr_iop_message_read(acb);
3063		}
3064		acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
3065		    ACB_F_MESSAGE_RQBUFFER_CLEARED |
3066		    ACB_F_MESSAGE_WQBUFFER_READ);
3067		acb->rqbuf_firstidx = 0;
3068		acb->rqbuf_lastidx = 0;
3069		acb->wqbuf_firstidx = 0;
3070		acb->wqbuf_lastidx = 0;
3071		pQbuffer = acb->rqbuffer;
3072		bzero(pQbuffer, sizeof (struct QBUFFER));
3073		pQbuffer = acb->wqbuffer;
3074		bzero(pQbuffer, sizeof (struct QBUFFER));
3075		/* report success */
3076		pktioctlfld->cmdmessage.ReturnCode =
3077		    ARCMSR_MESSAGE_RETURNCODE_OK;
3078		if (ddi_copyout(pktioctlfld, (void *)arg,
3079		    sizeof (struct CMD_MESSAGE_FIELD), mode) != 0)
3080			retvalue = ENXIO;
3081
3082	}
3083	break;
3084	case ARCMSR_MESSAGE_REQUEST_RETURN_CODE_3F:
3085	{
3086		pktioctlfld->cmdmessage.ReturnCode =
3087		    ARCMSR_MESSAGE_RETURNCODE_3F;
3088		if (ddi_copyout(pktioctlfld, (void *)arg,
3089		    sizeof (struct CMD_MESSAGE_FIELD), mode) != 0)
3090			retvalue = ENXIO;
3091	}
3092	break;
3093	/* Not supported: ARCMSR_MESSAGE_SAY_HELLO */
3094	case ARCMSR_MESSAGE_SAY_GOODBYE:
3095		arcmsr_iop_parking(acb);
3096		break;
3097	case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE:
3098		if (acb->adapter_type == ACB_ADAPTER_TYPE_A) {
3099			arcmsr_flush_hba_cache(acb);
3100		} else {
3101			arcmsr_flush_hbb_cache(acb);
3102		}
3103		break;
3104	default:
3105		retvalue = ENOTTY;
3106	}
3107
3108ioctl_out:
3109	kmem_free(pktioctlfld, sizeof (struct CMD_MESSAGE_FIELD));
3110	mutex_exit(&acb->ioctl_mutex);
3111
3112	return (retvalue);
3113}
3114
3115
3116
3117static struct CCB *
3118arcmsr_get_freeccb(struct ACB *acb) {
3119
3120	struct CCB *ccb;
3121	int workingccb_startindex, workingccb_doneindex;
3122
3123
3124	mutex_enter(&acb->workingQ_mutex);
3125	workingccb_doneindex = acb->workingccb_doneindex;
3126	workingccb_startindex = acb->workingccb_startindex;
3127	ccb = acb->ccbworkingQ[workingccb_startindex];
3128	workingccb_startindex++;
3129	workingccb_startindex %= ARCMSR_MAX_FREECCB_NUM;
3130	if (workingccb_doneindex != workingccb_startindex) {
3131		acb->workingccb_startindex = workingccb_startindex;
3132	} else {
3133		ccb = NULL;
3134	}
3135
3136	mutex_exit(&acb->workingQ_mutex);
3137	return (ccb);
3138}
3139
3140
3141
3142static int
3143arcmsr_seek_cmd2abort(struct ACB *acb,
3144    struct scsi_pkt *abortpkt) {
3145
3146	struct CCB *ccb;
3147	uint32_t intmask_org = 0;
3148	int i = 0;
3149
3150	acb->num_aborts++;
3151
3152	if (abortpkt == NULL) {
3153		/*
3154		 * if abortpkt is NULL, the upper layer needs us
3155		 * to abort all commands
3156		 */
3157		if (acb->ccboutstandingcount != 0) {
3158			/* disable all outbound interrupt */
3159			intmask_org = arcmsr_disable_allintr(acb);
3160			/* clear and abort all outbound posted Q */
3161			arcmsr_done4abort_postqueue(acb);
3162			/* talk to iop 331 outstanding command aborted */
3163			if (acb->adapter_type == ACB_ADAPTER_TYPE_A) {
3164				arcmsr_abort_hba_allcmd(acb);
3165			} else {
3166				arcmsr_abort_hbb_allcmd(acb);
3167			}
3168
3169			for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
3170				ccb = acb->pccb_pool[i];
3171				if (ccb->startdone == ARCMSR_CCB_START) {
3172					/*
3173					 * this ccb will complete at
3174					 * hwinterrupt
3175					 */
3176					ccb->startdone = ARCMSR_CCB_ABORTED;
3177					ccb->pkt->pkt_reason = CMD_ABORTED;
3178					ccb->pkt->pkt_statistics |=
3179					    STAT_ABORTED;
3180					arcmsr_ccb_complete(ccb, 1);
3181				}
3182			}
3183			/*
3184			 * enable outbound Post Queue, outbound
3185			 * doorbell Interrupt
3186			 */
3187			arcmsr_enable_allintr(acb, intmask_org);
3188		}
3189		return (DDI_SUCCESS);
3190	}
3191
3192	/*
3193	 * It is the upper layer do abort command this lock
3194	 * just prior to calling us.
3195	 * First determine if we currently own this command.
3196	 * Start by searching the device queue. If not found
3197	 * at all, and the system wanted us to just abort the
3198	 * command returnsuccess.
3199	 */
3200
3201	if (acb->ccboutstandingcount != 0) {
3202		for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
3203			ccb = acb->pccb_pool[i];
3204			if (ccb->startdone == ARCMSR_CCB_START) {
3205				if (ccb->pkt == abortpkt) {
3206					ccb->startdone =
3207					    ARCMSR_CCB_ABORTED;
3208					goto abort_outstanding_cmd;
3209				}
3210			}
3211		}
3212	}
3213
3214	return (DDI_FAILURE);
3215
3216abort_outstanding_cmd:
3217	/* disable all outbound interrupts */
3218	intmask_org = arcmsr_disable_allintr(acb);
3219	if (acb->adapter_type == ACB_ADAPTER_TYPE_A) {
3220		arcmsr_polling_hba_ccbdone(acb, ccb);
3221	} else {
3222		arcmsr_polling_hbb_ccbdone(acb, ccb);
3223	}
3224
3225	/* enable outbound Post Queue, outbound doorbell Interrupt */
3226	arcmsr_enable_allintr(acb, intmask_org);
3227	return (DDI_SUCCESS);
3228}
3229
3230
3231
3232static void
3233arcmsr_pcidev_disattach(struct ACB *acb) {
3234
3235	struct CCB *ccb;
3236	int i = 0;
3237
3238	/* disable all outbound interrupts */
3239	(void) arcmsr_disable_allintr(acb);
3240	/* stop adapter background rebuild */
3241	if (acb->adapter_type == ACB_ADAPTER_TYPE_A) {
3242		arcmsr_stop_hba_bgrb(acb);
3243		arcmsr_flush_hba_cache(acb);
3244	} else {
3245		arcmsr_stop_hbb_bgrb(acb);
3246		arcmsr_flush_hbb_cache(acb);
3247	}
3248	/* abort all outstanding commands */
3249	acb->acb_flags |= ACB_F_SCSISTOPADAPTER;
3250	acb->acb_flags &= ~ACB_F_IOP_INITED;
3251
3252	if (acb->ccboutstandingcount != 0) {
3253		/* clear and abort all outbound posted Q */
3254		arcmsr_done4abort_postqueue(acb);
3255		/* talk to iop 331 outstanding command aborted */
3256		if (acb->adapter_type == ACB_ADAPTER_TYPE_A) {
3257			arcmsr_abort_hba_allcmd(acb);
3258		} else {
3259			arcmsr_abort_hbb_allcmd(acb);
3260		}
3261
3262		for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
3263			ccb = acb->pccb_pool[i];
3264			if (ccb->startdone == ARCMSR_CCB_START) {
3265				ccb->startdone = ARCMSR_CCB_ABORTED;
3266				ccb->pkt->pkt_reason = CMD_ABORTED;
3267				ccb->pkt->pkt_statistics |= STAT_ABORTED;
3268				arcmsr_ccb_complete(ccb, 1);
3269			}
3270		}
3271	}
3272}
3273
3274/* get firmware miscellaneous data */
3275static void
3276arcmsr_get_hba_config(struct ACB *acb) {
3277
3278	struct HBA_msgUnit *phbamu;
3279
3280	char *acb_firm_model;
3281	char *acb_firm_version;
3282	char *iop_firm_model;
3283	char *iop_firm_version;
3284	int count;
3285
3286	phbamu = (struct HBA_msgUnit *)acb->pmu;
3287	acb_firm_model = acb->firm_model;
3288	acb_firm_version = acb->firm_version;
3289	/* firm_model, 15 */
3290	iop_firm_model = (char *)
3291	    (&phbamu->msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);
3292	/* firm_version, 17 */
3293	iop_firm_version =
3294	    (char *)(&phbamu->msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]);
3295
3296	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0, &phbamu->inbound_msgaddr0,
3297	    ARCMSR_INBOUND_MESG0_GET_CONFIG);
3298
3299	if (!arcmsr_hba_wait_msgint_ready(acb))
3300		cmn_err(CE_CONT,
3301		    "arcmsr%d: timeout while waiting for adapter firmware "
3302		    "miscellaneous data",
3303		    ddi_get_instance(acb->dev_info));
3304
3305	count = 8;
3306	while (count) {
3307		*acb_firm_model =
3308		    CHIP_REG_READ8(acb->reg_mu_acc_handle0, iop_firm_model);
3309		acb_firm_model++;
3310		iop_firm_model++;
3311		count--;
3312	}
3313
3314	count = 16;
3315	while (count) {
3316		*acb_firm_version =
3317		    CHIP_REG_READ8(acb->reg_mu_acc_handle0, iop_firm_version);
3318		acb_firm_version++;
3319		iop_firm_version++;
3320		count--;
3321	}
3322
3323	cmn_err(CE_CONT, "arcmsr%d: ARECA RAID FIRMWARE VERSION %s",
3324	    ddi_get_instance(acb->dev_info), acb->firm_version);
3325
3326	/* firm_request_len, 1 */
3327	acb->firm_request_len = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
3328	    &phbamu->msgcode_rwbuffer[1]);
3329	/* firm_numbers_queue, 2 */
3330	acb->firm_numbers_queue = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
3331	    &phbamu->msgcode_rwbuffer[2]);
3332	/* firm_sdram_size, 3 */
3333	acb->firm_sdram_size = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
3334	    &phbamu->msgcode_rwbuffer[3]);
3335	/* firm_ide_channels, 4 */
3336	acb->firm_ide_channels = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
3337	    &phbamu->msgcode_rwbuffer[4]);
3338}
3339
3340/* get firmware miscellaneous data */
3341static void
3342arcmsr_get_hbb_config(struct ACB *acb) {
3343
3344	struct HBB_msgUnit *phbbmu;
3345	char *acb_firm_model;
3346	char *acb_firm_version;
3347	char *iop_firm_model;
3348	char *iop_firm_version;
3349	int count;
3350
3351
3352	phbbmu = (struct HBB_msgUnit *)acb->pmu;
3353	acb_firm_model = acb->firm_model;
3354	acb_firm_version = acb->firm_version;
3355	/* firm_model, 15 */
3356	iop_firm_model = (char *)
3357	    (&phbbmu->hbb_rwbuffer->msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);
3358	/* firm_version, 17 */
3359	iop_firm_version = (char *)
3360	    (&phbbmu->hbb_rwbuffer->msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]);
3361
3362
3363
3364	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
3365	    &phbbmu->hbb_doorbell->drv2iop_doorbell,
3366	    ARCMSR_MESSAGE_GET_CONFIG);
3367
3368	if (!arcmsr_hbb_wait_msgint_ready(acb))
3369		cmn_err(CE_CONT,
3370		    "arcmsr%d: timeout while waiting for adapter firmware "
3371		    "miscellaneous data",
3372		    ddi_get_instance(acb->dev_info));
3373
3374	count = 8;
3375	while (count) {
3376		*acb_firm_model = CHIP_REG_READ8(acb->reg_mu_acc_handle1,
3377		    iop_firm_model);
3378		acb_firm_model++;
3379		iop_firm_model++;
3380		count--;
3381	}
3382
3383	count = 16;
3384	while (count) {
3385		*acb_firm_version = CHIP_REG_READ8(acb->reg_mu_acc_handle1,
3386		    iop_firm_version);
3387		acb_firm_version++;
3388		iop_firm_version++;
3389		count--;
3390	}
3391
3392	cmn_err(CE_CONT, "arcmsr%d: ARECA RAID FIRMWARE VERSION %s",
3393	    ddi_get_instance(acb->dev_info), acb->firm_version);
3394
3395	/* firm_request_len, 1 */
3396	acb->firm_request_len = CHIP_REG_READ32(acb->reg_mu_acc_handle1,
3397		&phbbmu->hbb_rwbuffer->msgcode_rwbuffer[1]);
3398	/* firm_numbers_queue, 2 */
3399	acb->firm_numbers_queue = CHIP_REG_READ32(acb->reg_mu_acc_handle1,
3400	    &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[2]);
3401	/* firm_sdram_size, 3 */
3402	acb->firm_sdram_size = CHIP_REG_READ32(acb->reg_mu_acc_handle1,
3403	    &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[3]);
3404	/* firm_ide_channels, 4 */
3405	acb->firm_ide_channels = CHIP_REG_READ32(acb->reg_mu_acc_handle1,
3406	    &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[4]);
3407}
3408
3409
3410
3411/* start background rebuild */
3412static void
3413arcmsr_start_hba_bgrb(struct ACB *acb) {
3414
3415	struct HBA_msgUnit *phbamu;
3416
3417	phbamu = (struct HBA_msgUnit *)acb->pmu;
3418
3419	acb->acb_flags |= ACB_F_MSG_START_BGRB;
3420	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
3421	    &phbamu->inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB);
3422
3423	if (!arcmsr_hba_wait_msgint_ready(acb))
3424		cmn_err(CE_WARN,
3425		    "arcmsr%d: timeout while waiting for background "
3426		    "rebuild to start",
3427		    ddi_get_instance(acb->dev_info));
3428}
3429
3430
3431static void
3432arcmsr_start_hbb_bgrb(struct ACB *acb) {
3433
3434	struct HBB_msgUnit *phbbmu;
3435
3436	phbbmu = (struct HBB_msgUnit *)acb->pmu;
3437
3438	acb->acb_flags |= ACB_F_MSG_START_BGRB;
3439	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
3440	    &phbbmu->hbb_doorbell->drv2iop_doorbell,
3441	    ARCMSR_MESSAGE_START_BGRB);
3442
3443	if (!arcmsr_hbb_wait_msgint_ready(acb))
3444		cmn_err(CE_WARN,
3445		    "arcmsr%d: timeout while waiting for background "
3446		    "rebuild to start",
3447		    ddi_get_instance(acb->dev_info));
3448}
3449
3450
3451static void
3452arcmsr_polling_hba_ccbdone(struct ACB *acb, struct CCB *poll_ccb) {
3453
3454	struct HBA_msgUnit *phbamu;
3455	struct CCB *ccb;
3456	uint32_t flag_ccb, outbound_intstatus;
3457	uint32_t poll_ccb_done = 0;
3458	uint32_t poll_count = 0;
3459
3460
3461	phbamu = (struct HBA_msgUnit *)acb->pmu;
3462
3463polling_ccb_retry:
3464	poll_count++;
3465	outbound_intstatus = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
3466	    &phbamu->outbound_intstatus) & acb->outbound_int_enable;
3467
3468	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0, &phbamu->outbound_intstatus,
3469	    outbound_intstatus); /* clear interrupt */
3470
3471	/* Use correct offset and size for syncing */
3472	if (ddi_dma_sync(acb->ccbs_pool_handle, 0, acb->dma_sync_size,
3473	    DDI_DMA_SYNC_FORKERNEL) != DDI_SUCCESS)
3474		return;
3475
3476	/*LINTED*/
3477	while (1) {
3478		if ((flag_ccb = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
3479		    &phbamu->outbound_queueport)) == 0xFFFFFFFF) {
3480			if (poll_ccb_done) {
3481				/* chip FIFO no ccb for completion already */
3482				break;
3483			} else {
3484				drv_usecwait(25000);
3485				if (poll_count > 100) {
3486					break;
3487				}
3488				goto polling_ccb_retry;
3489			}
3490		}
3491
3492		/* check ifcommand done with no error */
3493		ccb = (struct CCB *)(acb->vir2phy_offset  +
3494		    (flag_ccb << 5)); /* frame must be 32 bytes aligned */
3495		poll_ccb_done = (ccb == poll_ccb) ? 1 : 0;
3496
3497		if ((ccb->acb != acb) ||
3498		    (ccb->startdone != ARCMSR_CCB_START)) {
3499			if (ccb->startdone == ARCMSR_CCB_ABORTED) {
3500				ccb->pkt->pkt_reason = CMD_ABORTED;
3501				ccb->pkt->pkt_statistics |= STAT_ABORTED;
3502				arcmsr_ccb_complete(ccb, 1);
3503				continue;
3504			}
3505			cmn_err(CE_WARN, "arcmsr%d: polling op got "
3506			    "unexpected ccb command done",
3507			    ddi_get_instance(acb->dev_info));
3508			continue;
3509		}
3510		arcmsr_report_ccb_state(acb, ccb, flag_ccb);
3511	}	/* drain reply FIFO */
3512}
3513
3514
3515static void
3516arcmsr_polling_hbb_ccbdone(struct ACB *acb,
3517    struct CCB *poll_ccb) {
3518
3519	struct HBB_msgUnit *phbbmu;
3520	struct CCB *ccb;
3521	uint32_t flag_ccb;
3522	uint32_t poll_ccb_done = 0;
3523	uint32_t poll_count = 0;
3524	int index;
3525
3526
3527	phbbmu = (struct HBB_msgUnit *)acb->pmu;
3528
3529
3530polling_ccb_retry:
3531	poll_count++;
3532	/* clear doorbell interrupt */
3533	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
3534	    &phbbmu->hbb_doorbell->iop2drv_doorbell,
3535	    ARCMSR_DOORBELL_INT_CLEAR_PATTERN);
3536
3537	/* Use correct offset and size for syncing */
3538	if (ddi_dma_sync(acb->ccbs_pool_handle, 0, acb->dma_sync_size,
3539	    DDI_DMA_SYNC_FORKERNEL) != DDI_SUCCESS)
3540		return;
3541
3542
3543	/*LINTED*/
3544	while (1) {
3545		index = phbbmu->doneq_index;
3546		if ((flag_ccb = phbbmu->done_qbuffer[index]) == 0) {
3547			if (poll_ccb_done) {
3548				/* chip FIFO no ccb for completion already */
3549				break;
3550			} else {
3551				drv_usecwait(25000);
3552				if (poll_count > 100)
3553					break;
3554
3555				goto polling_ccb_retry;
3556			}
3557		}
3558
3559		phbbmu->done_qbuffer[index] = 0;
3560		index++;
3561		/* if last index number set it to 0 */
3562		index %= ARCMSR_MAX_HBB_POSTQUEUE;
3563		phbbmu->doneq_index = index;
3564		/* check if command done with no error */
3565		/* frame must be 32 bytes aligned */
3566		ccb = (struct CCB *)(acb->vir2phy_offset +
3567		    (flag_ccb << 5));
3568		poll_ccb_done = (ccb == poll_ccb) ? 1 : 0;
3569		if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {
3570			if (ccb->startdone == ARCMSR_CCB_ABORTED) {
3571				ccb->pkt->pkt_reason = CMD_ABORTED;
3572				ccb->pkt->pkt_statistics |= STAT_ABORTED;
3573				arcmsr_ccb_complete(ccb, 1);
3574				continue;
3575			}
3576			cmn_err(CE_WARN, "arcmsr%d: polling op got"
3577			    "unexpect ccb command done",
3578			    ddi_get_instance(acb->dev_info));
3579			continue;
3580		}
3581		arcmsr_report_ccb_state(acb, ccb, flag_ccb);
3582	}	/* drain reply FIFO */
3583}
3584
3585
3586/*
3587 *    Function: arcmsr_tran_start(9E)
3588 * Description: Transport the command in pktp to the target device.
3589 *		The command is not finished when this returns, only
3590 *		sent to the target; arcmsr_interrupt will call
3591 *		(*pktp->pkt_comp)(pktp) when the target device has done.
3592 *
3593 *       Input: struct scsi_address *ap, struct scsi_pkt *pktp
3594 *      Output:	TRAN_ACCEPT if pkt is OK and not driver not busy
3595 *		TRAN_BUSY if driver is
3596 *		TRAN_BADPKT if pkt is invalid
3597 */
3598static int
3599arcmsr_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt) {
3600
3601	struct ACB *acb;
3602	struct CCB *ccb;
3603	int target = ap->a_target;
3604	int lun = ap->a_lun;
3605
3606
3607	acb = (struct ACB *)ap->a_hba_tran->tran_hba_private;
3608	ccb = pkt->pkt_ha_private;
3609
3610	if ((ccb->ccb_flags & CCB_FLAG_DMAVALID) &&
3611	    (ccb->ccb_flags & DDI_DMA_CONSISTENT))
3612		(void) ddi_dma_sync(ccb->pkt_dma_handle, ccb->pkt_dma_offset,
3613		    ccb->pkt_dma_len, DDI_DMA_SYNC_FORDEV);
3614
3615
3616	if (ccb->startdone == ARCMSR_CCB_UNBUILD)
3617		arcmsr_build_ccb(ccb);
3618
3619
3620	if (acb->acb_flags & ACB_F_BUS_RESET) {
3621		cmn_err(CE_CONT,
3622		    "arcmsr%d: bus reset returned busy",
3623		    ddi_get_instance(acb->dev_info));
3624		pkt->pkt_reason = CMD_RESET;
3625		pkt->pkt_statistics |= STAT_BUS_RESET;
3626		pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
3627		    STATE_SENT_CMD | STATE_GOT_STATUS);
3628		if ((ccb->ccb_flags & CCB_FLAG_DMACONSISTENT) &&
3629		    (pkt->pkt_state & STATE_XFERRED_DATA))
3630			(void) ddi_dma_sync(ccb->pkt_dma_handle,
3631			    ccb->pkt_dma_offset, ccb->pkt_dma_len,
3632			    DDI_DMA_SYNC_FORCPU);
3633
3634		if (pkt->pkt_comp)
3635			(*pkt->pkt_comp)(pkt);
3636
3637
3638		return (TRAN_ACCEPT);
3639	}
3640
3641	if (acb->devstate[target][lun] == ARECA_RAID_GONE) {
3642		uint8_t block_cmd;
3643
3644		block_cmd = pkt->pkt_cdbp[0] & 0x0f;
3645
3646		if (block_cmd == 0x08 || block_cmd == 0x0a) {
3647			cmn_err(CE_CONT,
3648			    "arcmsr%d: block read/write command while raid"
3649			    "volume missing (cmd %02x for target %d lun %d)",
3650			    ddi_get_instance(acb->dev_info),
3651			    block_cmd, target, lun);
3652			pkt->pkt_reason = CMD_TIMEOUT;
3653			pkt->pkt_statistics |= CMD_TIMEOUT;
3654			pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
3655			    STATE_SENT_CMD | STATE_GOT_STATUS);
3656
3657			if ((ccb->ccb_flags & CCB_FLAG_DMACONSISTENT) &&
3658			    (pkt->pkt_state & STATE_XFERRED_DATA))
3659				(void) ddi_dma_sync(ccb->pkt_dma_handle,
3660				    ccb->pkt_dma_offset, ccb->pkt_dma_len,
3661				    DDI_DMA_SYNC_FORCPU);
3662
3663
3664			if (pkt->pkt_comp)
3665				(*pkt->pkt_comp)(pkt);
3666
3667
3668			return (TRAN_ACCEPT);
3669		}
3670	}
3671
3672
3673	/* IMPORTANT: Target 16 is a virtual device for iop message transfer */
3674	if (target == 16) {
3675
3676		struct buf *bp = ccb->bp;
3677		uint8_t scsicmd = pkt->pkt_cdbp[0];
3678
3679		switch (scsicmd) {
3680		case SCMD_INQUIRY: {
3681			if (lun != 0) {
3682				ccb->pkt->pkt_reason = CMD_TIMEOUT;
3683				ccb->pkt->pkt_statistics |= STAT_TIMEOUT;
3684				arcmsr_ccb_complete(ccb, 0);
3685				return (TRAN_ACCEPT);
3686			}
3687
3688			if (bp && bp->b_un.b_addr && bp->b_bcount) {
3689				uint8_t inqdata[36];
3690
3691				/* The EVDP and pagecode is not supported */
3692				if (pkt->pkt_cdbp[1] || pkt->pkt_cdbp[2]) {
3693					inqdata[1] = 0xFF;
3694					inqdata[2] = 0x00;
3695				} else {
3696					/* Periph Qualifier & Periph Dev Type */
3697					inqdata[0] = DTYPE_PROCESSOR;
3698					/* rem media bit & Dev Type Modifier */
3699					inqdata[1] = 0;
3700					/* ISO, ECMA, & ANSI versions */
3701					inqdata[2] = 0;
3702					/* length of additional data */
3703					inqdata[4] = 31;
3704					/* Vendor Identification */
3705					bcopy("Areca   ",
3706					    &inqdata[8], VIDLEN);
3707					/* Product Identification */
3708					bcopy("RAID controller ",
3709					    &inqdata[16], PIDLEN);
3710					/* Product Revision */
3711					bcopy(&inqdata[32],
3712					    "R001", REVLEN);
3713					if (bp->b_flags & (B_PHYS | B_PAGEIO))
3714						bp_mapin(bp);
3715
3716					(void) memcpy(bp->b_un.b_addr,
3717					    inqdata, sizeof (inqdata));
3718				}
3719				ccb->pkt->pkt_state |= STATE_XFERRED_DATA;
3720			}
3721			arcmsr_ccb_complete(ccb, 0);
3722			return (TRAN_ACCEPT);
3723		}
3724		case SCMD_WRITE_BUFFER:
3725		case SCMD_READ_BUFFER: {
3726			if (arcmsr_iop_message_xfer(acb, pkt)) {
3727				/* error just for retry */
3728				ccb->pkt->pkt_reason = CMD_TRAN_ERR;
3729				ccb->pkt->pkt_statistics |= STAT_TERMINATED;
3730			}
3731			ccb->pkt->pkt_state |= STATE_XFERRED_DATA;
3732			arcmsr_ccb_complete(ccb, 0);
3733			return (TRAN_ACCEPT);
3734		}
3735		default:
3736			ccb->pkt->pkt_state |= STATE_XFERRED_DATA;
3737			arcmsr_ccb_complete(ccb, 0);
3738			return (TRAN_ACCEPT);
3739		}
3740	}
3741
3742	if (acb->ccboutstandingcount >= ARCMSR_MAX_OUTSTANDING_CMD) {
3743		cmn_err(CE_CONT,
3744		    "arcmsr%d: too many outstanding commands (%d > %d)",
3745		    ddi_get_instance(acb->dev_info),
3746		    acb->ccboutstandingcount,
3747		    ARCMSR_MAX_OUTSTANDING_CMD);
3748		return (TRAN_BUSY);
3749	} else if (arcmsr_post_ccb(acb, ccb) == DDI_FAILURE) {
3750		cmn_err(CE_CONT,
3751		    "arcmsr%d: post failure, ccboutstandingcount = %d",
3752		    ddi_get_instance(acb->dev_info),
3753		    acb->ccboutstandingcount);
3754		return (TRAN_BUSY);
3755	}
3756
3757    return (TRAN_ACCEPT);
3758}
3759
3760/*
3761 * Function: arcmsr_tran_abort(9E)
3762 * 		SCSA interface routine to abort pkt(s) in progress.
3763 * 		Aborts the pkt specified.  If NULL pkt, aborts ALL pkts.
3764 * Output:	Return 1 if success
3765 *		Return 0 if failure
3766 */
3767static int
3768arcmsr_tran_abort(struct scsi_address *ap, struct scsi_pkt *abortpkt) {
3769
3770	struct ACB *acb;
3771	int return_code;
3772
3773	acb = (struct ACB *)ap->a_hba_tran->tran_hba_private;
3774
3775
3776	cmn_err(CE_WARN,
3777	    "arcmsr%d: tran_abort called for target %d lun %d",
3778	    ddi_get_instance(acb->dev_info), ap->a_target, ap->a_lun);
3779
3780	while (acb->ccboutstandingcount != 0) {
3781		drv_usecwait(10000);
3782	}
3783
3784	mutex_enter(&acb->acb_mutex);
3785	return_code = arcmsr_seek_cmd2abort(acb, abortpkt);
3786	mutex_exit(&acb->acb_mutex);
3787
3788	if (return_code != DDI_SUCCESS) {
3789		cmn_err(CE_WARN,
3790		    "arcmsr%d: abort command failed for target %d lun %d",
3791		    ddi_get_instance(acb->dev_info),
3792		    ap->a_target, ap->a_lun);
3793		return (0);
3794	}
3795
3796	return (1);
3797}
3798
3799/*
3800 * Function: arcmsr_tran_reset(9E)
3801 *           SCSA interface routine to perform scsi resets on either
3802 *           a specified target or the bus (default).
3803 *   Output: Return 1 if success
3804 *	     Return 0 if failure
3805 */
3806static int
3807arcmsr_tran_reset(struct scsi_address *ap, int level) {
3808
3809	struct ACB *acb;
3810	int return_code = 1;
3811	int retry = 0;
3812
3813
3814	/* Are we in the middle of dumping core? */
3815	if (ddi_in_panic())
3816		return (return_code);
3817
3818	acb = (struct ACB *)ap->a_hba_tran->tran_hba_private;
3819
3820	cmn_err(CE_WARN, "arcmsr%d: tran reset (level 0x%x) called "
3821	    "for target %d lun %d",
3822	    ddi_get_instance(acb->dev_info), level,
3823	    ap->a_target, ap->a_lun);
3824	mutex_enter(&acb->acb_mutex);
3825
3826	while ((acb->ccboutstandingcount > 0) && (retry < 400)) {
3827		(void) arcmsr_interrupt((caddr_t)acb);
3828		drv_usecwait(25000);
3829		retry++;
3830	}
3831
3832	switch (level) {
3833	case RESET_ALL:		/* level 1 */
3834		acb->num_resets++;
3835		acb->acb_flags |= ACB_F_BUS_RESET;
3836		arcmsr_iop_reset(acb);
3837		acb->acb_flags &= ~ACB_F_BUS_RESET;
3838		return_code = 0;
3839		break;
3840	case RESET_TARGET:	/* level 0 */
3841		cmn_err(CE_WARN, "arcmsr%d: target reset not supported",
3842		    ddi_get_instance(acb->dev_info));
3843		return_code = 0;
3844		break;
3845	default:
3846		return_code = 0;
3847	}
3848
3849	mutex_exit(&acb->acb_mutex);
3850	return (return_code);
3851}
3852
3853
3854static void
3855arcmsr_log(struct ACB *acb, int level, char *fmt, ...) {
3856
3857	char	buf[256];
3858	va_list ap;
3859
3860	va_start(ap, fmt);
3861	(void) vsprintf(buf, fmt, ap);
3862	va_end(ap);
3863	scsi_log(acb ? acb->dev_info : NULL, "arcmsr", level, "%s", buf);
3864}
3865
3866
3867static void
3868arcmsr_iop2drv_data_wrote_handle(struct ACB *acb) {
3869
3870	struct QBUFFER *prbuffer;
3871	uint8_t *pQbuffer;
3872	uint8_t *iop_data;
3873	int my_empty_len, iop_len;
3874	int rqbuf_firstidx, rqbuf_lastidx;
3875
3876	/* check this iop data if overflow my rqbuffer */
3877	rqbuf_lastidx = acb->rqbuf_lastidx;
3878	rqbuf_firstidx = acb->rqbuf_firstidx;
3879	prbuffer = arcmsr_get_iop_rqbuffer(acb);
3880	iop_data = (uint8_t *)prbuffer->data;
3881	iop_len = prbuffer->data_len;
3882	my_empty_len = (rqbuf_firstidx-rqbuf_lastidx - 1) &
3883	    (ARCMSR_MAX_QBUFFER - 1);
3884
3885	if (my_empty_len >= iop_len) {
3886		while (iop_len > 0) {
3887			pQbuffer = &acb->rqbuffer[rqbuf_lastidx];
3888			(void) memcpy(pQbuffer, iop_data, 1);
3889			rqbuf_lastidx++;
3890			/* if last index number set it to 0 */
3891			rqbuf_lastidx %= ARCMSR_MAX_QBUFFER;
3892			iop_data++;
3893			iop_len--;
3894		}
3895		acb->rqbuf_lastidx = rqbuf_lastidx;
3896		arcmsr_iop_message_read(acb);
3897		/* signature, let IOP know data has been read */
3898	} else {
3899		acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
3900	}
3901}
3902
3903
3904
3905static void
3906arcmsr_iop2drv_data_read_handle(struct ACB *acb) {
3907
3908	acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READ;
3909	/*
3910	 * check if there are any mail packages from user space program
3911	 * in my post bag, now is the time to send them into Areca's firmware
3912	 */
3913
3914	if (acb->wqbuf_firstidx != acb->wqbuf_lastidx) {
3915
3916		uint8_t *pQbuffer;
3917		struct QBUFFER *pwbuffer;
3918		uint8_t *iop_data;
3919		int allxfer_len = 0;
3920
3921		acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ);
3922		pwbuffer = arcmsr_get_iop_wqbuffer(acb);
3923		iop_data = (uint8_t *)pwbuffer->data;
3924
3925		while ((acb->wqbuf_firstidx != acb->wqbuf_lastidx) &&
3926		    (allxfer_len < 124)) {
3927			pQbuffer = &acb->wqbuffer[acb->wqbuf_firstidx];
3928			(void) memcpy(iop_data, pQbuffer, 1);
3929			acb->wqbuf_firstidx++;
3930			/* if last index number set it to 0 */
3931			acb->wqbuf_firstidx %= ARCMSR_MAX_QBUFFER;
3932			iop_data++;
3933			allxfer_len++;
3934		}
3935		pwbuffer->data_len = allxfer_len;
3936		/*
3937		 * push inbound doorbell, tell iop driver data write ok
3938		 * await reply on next hwinterrupt for next Qbuffer post
3939		 */
3940		arcmsr_iop_message_wrote(acb);
3941	}
3942
3943	if (acb->wqbuf_firstidx == acb->wqbuf_lastidx)
3944		acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED;
3945}
3946
3947
3948static void
3949arcmsr_hba_doorbell_isr(struct ACB *acb) {
3950
3951	uint32_t outbound_doorbell;
3952	struct HBA_msgUnit *phbamu;
3953
3954	phbamu = (struct HBA_msgUnit *)acb->pmu;
3955
3956	/*
3957	 *  Maybe here we need to check wrqbuffer_lock is locked or not
3958	 *  DOORBELL: ding! dong!
3959	 *  check if there are any mail need to pack from firmware
3960	 */
3961
3962	outbound_doorbell = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
3963	    &phbamu->outbound_doorbell);
3964	/* clear doorbell interrupt */
3965	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
3966	    &phbamu->outbound_doorbell, outbound_doorbell);
3967
3968	if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK)
3969		arcmsr_iop2drv_data_wrote_handle(acb);
3970
3971
3972	if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK)
3973		arcmsr_iop2drv_data_read_handle(acb);
3974}
3975
3976
3977
3978static void
3979arcmsr_hba_postqueue_isr(struct ACB *acb) {
3980
3981	uint32_t flag_ccb;
3982	struct HBA_msgUnit *phbamu;
3983
3984
3985	phbamu = (struct HBA_msgUnit *)acb->pmu;
3986
3987	/* areca cdb command done */
3988	/* Use correct offset and size for syncing */
3989	(void) ddi_dma_sync(acb->ccbs_pool_handle, 0, acb->dma_sync_size,
3990	    DDI_DMA_SYNC_FORKERNEL);
3991
3992	while ((flag_ccb = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
3993	    &phbamu->outbound_queueport)) != 0xFFFFFFFF) {
3994		/* check if command done with no error */
3995		arcmsr_drain_donequeue(acb, flag_ccb);
3996	}	/* drain reply FIFO */
3997}
3998
3999
4000
4001static void
4002arcmsr_hbb_postqueue_isr(struct ACB *acb) {
4003
4004	int index;
4005	uint32_t flag_ccb;
4006	struct HBB_msgUnit *phbbmu;
4007
4008	phbbmu = (struct HBB_msgUnit *)acb->pmu;
4009
4010
4011	/* areca cdb command done */
4012	index = phbbmu->doneq_index;
4013
4014	while ((flag_ccb = phbbmu->done_qbuffer[index]) != 0) {
4015		phbbmu->done_qbuffer[index] = 0;
4016		index++;
4017		/* if last index number set it to 0 */
4018		index %= ARCMSR_MAX_HBB_POSTQUEUE;
4019		phbbmu->doneq_index = index;
4020		/* check if command done with no error */
4021		arcmsr_drain_donequeue(acb, flag_ccb);
4022	}	/* drain reply FIFO */
4023}
4024
4025
4026static uint_t
4027arcmsr_handle_hba_isr(struct ACB *acb) {
4028
4029	uint32_t outbound_intstatus;
4030	struct HBA_msgUnit *phbamu;
4031
4032	phbamu = (struct HBA_msgUnit *)acb->pmu;
4033
4034	outbound_intstatus = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
4035	    &phbamu->outbound_intstatus) & acb->outbound_int_enable;
4036
4037	if (!outbound_intstatus)
4038		/* it must be a shared irq */
4039		return (DDI_INTR_UNCLAIMED);
4040
4041	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0, &phbamu->outbound_intstatus,
4042	    outbound_intstatus); /* clear interrupt */
4043
4044
4045	/* MU doorbell interrupts */
4046
4047	if (outbound_intstatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT)
4048		arcmsr_hba_doorbell_isr(acb);
4049
4050	/* MU post queue interrupts */
4051	if (outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT)
4052		arcmsr_hba_postqueue_isr(acb);
4053
4054	/*
4055	 * The following block is commented out pending confirmation from
4056	 * Areca whether it is or is not truly required
4057	 */
4058	/* MU message interrupt */
4059	/*
4060	 * if (outbound_intstatus & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
4061	 *	arcmsr_hba_message_isr(acb);
4062	 * }
4063	 */
4064	return (DDI_INTR_CLAIMED);
4065}
4066
4067
4068static uint_t
4069arcmsr_handle_hbb_isr(struct ACB *acb) {
4070
4071	uint32_t outbound_doorbell;
4072	struct HBB_msgUnit *phbbmu;
4073
4074
4075	phbbmu = (struct HBB_msgUnit *)acb->pmu;
4076
4077	outbound_doorbell = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
4078	    &phbbmu->hbb_doorbell->iop2drv_doorbell) & acb->outbound_int_enable;
4079
4080	if (!outbound_doorbell)
4081		/* it must be a shared irq */
4082		return (DDI_INTR_UNCLAIMED);
4083
4084	/* clear doorbell interrupt */
4085	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
4086	    &phbbmu->hbb_doorbell->iop2drv_doorbell, ~outbound_doorbell);
4087	/* wait a cycle */
4088	(void) CHIP_REG_READ32(acb->reg_mu_acc_handle0,
4089	    &phbbmu->hbb_doorbell->iop2drv_doorbell);
4090	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
4091	    &phbbmu->hbb_doorbell->drv2iop_doorbell,
4092	    ARCMSR_DRV2IOP_END_OF_INTERRUPT);
4093
4094	/* MU ioctl transfer doorbell interrupts */
4095	if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK)
4096		arcmsr_iop2drv_data_wrote_handle(acb);
4097
4098	if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_READ_OK)
4099		arcmsr_iop2drv_data_read_handle(acb);
4100
4101	/* MU post queue interrupts */
4102	if (outbound_doorbell & ARCMSR_IOP2DRV_CDB_DONE)
4103		arcmsr_hbb_postqueue_isr(acb);
4104
4105	/*
4106	 * The following block is commented out pending confirmation from
4107	 * Areca whether it is or is not truly required
4108	 */
4109	/* MU message interrupt */
4110	/*
4111	 * if (outbound_doorbell & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
4112	 *		arcmsr_hbb_message_isr(acb);
4113	 *	}
4114	 */
4115	return (DDI_INTR_CLAIMED);
4116}
4117
4118
4119static uint_t
4120arcmsr_interrupt(caddr_t arg) {
4121
4122
4123	struct ACB *acb = (struct ACB *)(intptr_t)arg;
4124
4125	switch (acb->adapter_type) {
4126	case ACB_ADAPTER_TYPE_A:
4127		return (arcmsr_handle_hba_isr(acb));
4128	case ACB_ADAPTER_TYPE_B:
4129		return (arcmsr_handle_hbb_isr(acb));
4130	default:
4131		cmn_err(CE_WARN, "arcmsr%d: unknown adapter type (%d)",
4132		    ddi_get_instance(acb->dev_info), acb->adapter_type);
4133		return (DDI_INTR_UNCLAIMED);
4134	}
4135}
4136
4137
4138static void
4139arcmsr_wait_firmware_ready(struct ACB *acb) {
4140
4141	uint32_t firmware_state;
4142
4143	firmware_state = 0;
4144
4145	switch (acb->adapter_type) {
4146	case ACB_ADAPTER_TYPE_A:
4147	{
4148		struct HBA_msgUnit *phbamu;
4149
4150		phbamu = (struct HBA_msgUnit *)acb->pmu;
4151		do {
4152			firmware_state =
4153			    CHIP_REG_READ32(acb->reg_mu_acc_handle0,
4154			    &phbamu->outbound_msgaddr1);
4155		} while ((firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK)
4156		    == 0);
4157	}
4158	break;
4159	case ACB_ADAPTER_TYPE_B:
4160	{
4161		struct HBB_msgUnit *phbbmu;
4162
4163		phbbmu = (struct HBB_msgUnit *)acb->pmu;
4164		do {
4165			firmware_state =
4166			    CHIP_REG_READ32(acb->reg_mu_acc_handle0,
4167				    &phbbmu->hbb_doorbell->iop2drv_doorbell);
4168		} while ((firmware_state & ARCMSR_MESSAGE_FIRMWARE_OK) == 0);
4169		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
4170		    &phbbmu->hbb_doorbell->drv2iop_doorbell,
4171		    ARCMSR_DRV2IOP_END_OF_INTERRUPT);
4172	}
4173	break;
4174	}
4175}
4176
4177static void
4178arcmsr_clear_doorbell_queue_buffer(struct ACB *acb) {
4179
4180	switch (acb->adapter_type) {
4181	case ACB_ADAPTER_TYPE_A:
4182	{
4183		struct HBA_msgUnit *phbamu;
4184		uint32_t outbound_doorbell;
4185
4186		phbamu = (struct HBA_msgUnit *)acb->pmu;
4187		/* empty doorbell Qbuffer if door bell rung */
4188		outbound_doorbell = CHIP_REG_READ32(acb->reg_mu_acc_handle0,
4189		    &phbamu->outbound_doorbell);
4190		/* clear doorbell interrupt */
4191		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
4192		    &phbamu->outbound_doorbell, outbound_doorbell);
4193		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
4194		    &phbamu->inbound_doorbell,
4195		    ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
4196	}
4197	break;
4198	case ACB_ADAPTER_TYPE_B:
4199	{
4200		struct HBB_msgUnit *phbbmu;
4201
4202		phbbmu = (struct HBB_msgUnit *)acb->pmu;
4203
4204		/* clear interrupt and message state */
4205		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
4206		    &phbbmu->hbb_doorbell->iop2drv_doorbell,
4207		    ARCMSR_MESSAGE_INT_CLEAR_PATTERN);
4208		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
4209		    &phbbmu->hbb_doorbell->drv2iop_doorbell,
4210		    ARCMSR_DRV2IOP_DATA_READ_OK);
4211		/* let IOP know data has been read */
4212	}
4213	break;
4214	}
4215}
4216
4217
4218static uint32_t
4219arcmsr_iop_confirm(struct ACB *acb) {
4220
4221	unsigned long ccb_phyaddr;
4222	uint32_t ccb_phyaddr_hi32;
4223
4224	/*
4225	 * here we need to tell iop 331 about our freeccb.HighPart
4226	 * if freeccb.HighPart is non-zero
4227	 */
4228	ccb_phyaddr = (unsigned long)acb->ccb_cookie.dmac_address;
4229	ccb_phyaddr_hi32 = (uint32_t)((ccb_phyaddr >> 16) >> 16);
4230
4231	switch (acb->adapter_type) {
4232	case ACB_ADAPTER_TYPE_A:
4233	{
4234		if (ccb_phyaddr_hi32 != 0) {
4235			struct HBA_msgUnit *phbamu;
4236
4237			phbamu = (struct HBA_msgUnit *)acb->pmu;
4238			CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
4239			    &phbamu->msgcode_rwbuffer[0],
4240			    ARCMSR_SIGNATURE_SET_CONFIG);
4241			CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
4242			    &phbamu->msgcode_rwbuffer[1], ccb_phyaddr_hi32);
4243			CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
4244			    &phbamu->inbound_msgaddr0,
4245			    ARCMSR_INBOUND_MESG0_SET_CONFIG);
4246			if (!arcmsr_hba_wait_msgint_ready(acb)) {
4247				cmn_err(CE_WARN,
4248				    "arcmsr%d: timeout setting ccb high "
4249				    "physical address",
4250				    ddi_get_instance(acb->dev_info));
4251				return (FALSE);
4252			}
4253		}
4254	}
4255	break;
4256
4257	/* if adapter is type B, set window of "post command queue" */
4258
4259	case ACB_ADAPTER_TYPE_B:
4260	{
4261		uint32_t post_queue_phyaddr;
4262		struct HBB_msgUnit *phbbmu;
4263
4264		phbbmu = (struct HBB_msgUnit *)acb->pmu;
4265		phbbmu->postq_index = 0;
4266		phbbmu->doneq_index = 0;
4267		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
4268		    &phbbmu->hbb_doorbell->drv2iop_doorbell,
4269		    ARCMSR_MESSAGE_SET_POST_WINDOW);
4270
4271		if (!arcmsr_hbb_wait_msgint_ready(acb)) {
4272			cmn_err(CE_WARN,
4273			    "arcmsr%d: timeout setting post command "
4274			    "queue window",
4275			    ddi_get_instance(acb->dev_info));
4276			return (FALSE);
4277		}
4278
4279		post_queue_phyaddr = ccb_phyaddr +
4280		    ARCMSR_MAX_FREECCB_NUM *
4281		    sizeof (struct CCB)
4282		    + ARCOFFSET(struct HBB_msgUnit, post_qbuffer);
4283		/* driver "set config" signature */
4284		CHIP_REG_WRITE32(acb->reg_mu_acc_handle1,
4285		    &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[0],
4286		    ARCMSR_SIGNATURE_SET_CONFIG);
4287		/* normal should be zero */
4288		CHIP_REG_WRITE32(acb->reg_mu_acc_handle1,
4289		    &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[1],
4290		    ccb_phyaddr_hi32);
4291		/* postQ size (256+8)*4 */
4292		CHIP_REG_WRITE32(acb->reg_mu_acc_handle1,
4293		    &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[2],
4294		    post_queue_phyaddr);
4295		/* doneQ size (256+8)*4 */
4296		CHIP_REG_WRITE32(acb->reg_mu_acc_handle1,
4297		    &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[3],
4298		    post_queue_phyaddr+1056);
4299		/* ccb maxQ size must be --> [(256+8)*4] */
4300		CHIP_REG_WRITE32(acb->reg_mu_acc_handle1,
4301		    &phbbmu->hbb_rwbuffer->msgcode_rwbuffer[4], 1056);
4302		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
4303		    &phbbmu->hbb_doorbell->drv2iop_doorbell,
4304		    ARCMSR_MESSAGE_SET_CONFIG);
4305
4306		if (!arcmsr_hbb_wait_msgint_ready(acb)) {
4307			cmn_err(CE_WARN,
4308			    "arcmsr%d: timeout setting command queue window",
4309			    ddi_get_instance(acb->dev_info));
4310			return (FALSE);
4311		}
4312		CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
4313		    &phbbmu->hbb_doorbell->drv2iop_doorbell,
4314		    ARCMSR_MESSAGE_START_DRIVER_MODE);
4315
4316		if (!arcmsr_hbb_wait_msgint_ready(acb)) {
4317			cmn_err(CE_WARN,
4318			    "arcmsr%d: timeout in 'start driver mode'",
4319			    ddi_get_instance(acb->dev_info));
4320			return (FALSE);
4321		}
4322	}
4323	break;
4324	}
4325	return (TRUE);
4326}
4327
4328
4329/*
4330 * ONLY used for Adapter type B
4331 */
4332static void
4333arcmsr_enable_eoi_mode(struct ACB *acb) {
4334
4335	struct HBB_msgUnit *phbbmu;
4336
4337	phbbmu = (struct HBB_msgUnit *)acb->pmu;
4338
4339	CHIP_REG_WRITE32(acb->reg_mu_acc_handle0,
4340	    &phbbmu->hbb_doorbell->drv2iop_doorbell,
4341	    ARCMSR_MESSAGE_ACTIVE_EOI_MODE);
4342
4343	if (!arcmsr_hbb_wait_msgint_ready(acb))
4344		cmn_err(CE_WARN,
4345		    "arcmsr%d (Adapter type B): "
4346		    "'iop enable eoi mode' timeout ",
4347		    ddi_get_instance(acb->dev_info));
4348
4349}
4350
4351/* start background rebuild */
4352static void
4353arcmsr_iop_init(struct ACB *acb) {
4354
4355	uint32_t intmask_org;
4356
4357	/* disable all outbound interrupt */
4358	intmask_org = arcmsr_disable_allintr(acb);
4359	arcmsr_wait_firmware_ready(acb);
4360	(void) arcmsr_iop_confirm(acb);
4361
4362	/* start background rebuild */
4363	if (acb->adapter_type == ACB_ADAPTER_TYPE_A) {
4364		arcmsr_get_hba_config(acb);
4365		arcmsr_start_hba_bgrb(acb);
4366	} else {
4367		arcmsr_get_hbb_config(acb);
4368		arcmsr_start_hbb_bgrb(acb);
4369	}
4370
4371	/* empty doorbell Qbuffer if door bell rang */
4372	arcmsr_clear_doorbell_queue_buffer(acb);
4373
4374	if (acb->adapter_type == ACB_ADAPTER_TYPE_B)
4375		arcmsr_enable_eoi_mode(acb);
4376
4377	/* enable outbound Post Queue, outbound doorbell Interrupt */
4378	arcmsr_enable_allintr(acb, intmask_org);
4379	acb->acb_flags |= ACB_F_IOP_INITED;
4380}
4381
4382
4383static int
4384arcmsr_initialize(struct ACB *acb) {
4385
4386	struct CCB *pccb_tmp;
4387	size_t allocated_length;
4388	uint16_t wval;
4389	uint32_t wlval;
4390	uint_t intmask_org, count;
4391	caddr_t	arcmsr_ccbs_area;
4392	unsigned long ccb_phyaddr;
4393	int32_t dma_sync_size;
4394	int i, id, lun;
4395
4396	acb->irq = pci_config_get8(acb->pci_acc_handle,
4397	    ARCMSR_PCI2PCI_PRIMARY_INTERRUPT_LINE_REG);
4398	wlval = pci_config_get32(acb->pci_acc_handle, 0);
4399	wval = (uint16_t)((wlval >> 16) & 0xffff);
4400
4401	if (wval == PCI_DEVICE_ID_ARECA_1201) {
4402		uint32_t *iop_mu_regs_map0;
4403		uint32_t *iop_mu_regs_map1;
4404		struct CCB *freeccb;
4405		struct HBB_msgUnit *phbbmu;
4406
4407		acb->adapter_type = ACB_ADAPTER_TYPE_B; /* marvell */
4408		dma_sync_size = (ARCMSR_MAX_FREECCB_NUM*
4409		    sizeof (struct CCB) + 0x20) +
4410		    sizeof (struct HBB_msgUnit);
4411
4412
4413		/* Allocate memory for the ccb */
4414		if ((i = ddi_dma_alloc_handle(acb->dev_info,
4415		    &arcmsr_ccb_attr, DDI_DMA_SLEEP, NULL,
4416		    &acb->ccbs_pool_handle)) != DDI_SUCCESS) {
4417			switch (i) {
4418			case DDI_DMA_BADATTR:
4419				cmn_err(CE_WARN,
4420				    "arcmsr%d: ddi_dma_alloc_handle got "
4421				    "DDI_DMA_BADATTR",
4422				    ddi_get_instance(acb->dev_info));
4423				return (DDI_FAILURE);
4424
4425			case DDI_DMA_NORESOURCES:
4426				cmn_err(CE_WARN, "arcmsr%d: "
4427				    "ddi_dma_alloc_handle got "
4428				    "DDI_DMA_NORESOURCES ",
4429				    ddi_get_instance(acb->dev_info));
4430				return (DDI_FAILURE);
4431			}
4432			cmn_err(CE_WARN,
4433			    "arcmsr%d: ddi_dma_alloc_handle got DDI_FAILURE",
4434			    ddi_get_instance(acb->dev_info));
4435			return (DDI_FAILURE);
4436		}
4437
4438		if (ddi_dma_mem_alloc(acb->ccbs_pool_handle, dma_sync_size,
4439		    &acb->dev_acc_attr, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
4440		    DDI_DMA_SLEEP, NULL, (caddr_t *)&arcmsr_ccbs_area,
4441		    &allocated_length, &acb->ccbs_acc_handle)
4442		    != DDI_SUCCESS) {
4443			cmn_err(CE_CONT,
4444			    "arcmsr%d: ddi_dma_mem_alloc failed ",
4445			    ddi_get_instance(acb->dev_info));
4446			ddi_dma_free_handle(&acb->ccbs_pool_handle);
4447			return (DDI_FAILURE);
4448		}
4449
4450		if (ddi_dma_addr_bind_handle(acb->ccbs_pool_handle, NULL,
4451		    (caddr_t)arcmsr_ccbs_area, dma_sync_size,
4452		    DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
4453		    NULL, &acb->ccb_cookie, &count) != DDI_DMA_MAPPED) {
4454			cmn_err(CE_WARN,
4455			    "arcmsr%d: ddi_dma_addr_bind_handle failed",
4456			    ddi_get_instance(acb->dev_info));
4457			ddi_dma_mem_free(&acb->ccbs_acc_handle);
4458			ddi_dma_free_handle(&acb->ccbs_pool_handle);
4459			return (DDI_FAILURE);
4460		}
4461		bzero(arcmsr_ccbs_area, dma_sync_size);
4462		freeccb = (struct CCB *)(intptr_t)arcmsr_ccbs_area;
4463		acb->pmu = (struct msgUnit *)
4464		    &freeccb[ARCMSR_MAX_FREECCB_NUM];
4465		phbbmu = (struct HBB_msgUnit *)acb->pmu;
4466
4467		/* setup device register */
4468		if (ddi_regs_map_setup(acb->dev_info, 1,
4469		    (caddr_t *)&iop_mu_regs_map0, 0,
4470		    sizeof (struct HBB_DOORBELL), &acb->dev_acc_attr,
4471		    &acb->reg_mu_acc_handle0) != DDI_SUCCESS) {
4472			arcmsr_log(NULL, CE_WARN,
4473			    "arcmsr%d: unable to map PCI device "
4474			    "base0 address registers",
4475			    ddi_get_instance(acb->dev_info));
4476			return (DDI_FAILURE);
4477		}
4478
4479		/* ARCMSR_DRV2IOP_DOORBELL */
4480		phbbmu->hbb_doorbell =
4481		    (struct HBB_DOORBELL *)iop_mu_regs_map0;
4482		if (ddi_regs_map_setup(acb->dev_info, 2,
4483		    (caddr_t *)&iop_mu_regs_map1, 0,
4484		    sizeof (struct HBB_RWBUFFER), &acb->dev_acc_attr,
4485		    &acb->reg_mu_acc_handle1) != DDI_SUCCESS) {
4486			arcmsr_log(NULL, CE_WARN,
4487			    "arcmsr%d: unable to map PCI device "
4488			    "base1 address registers",
4489			    ddi_get_instance(acb->dev_info));
4490			return (DDI_FAILURE);
4491		}
4492
4493		/* ARCMSR_MSGCODE_RWBUFFER */
4494		phbbmu->hbb_rwbuffer =
4495		    (struct HBB_RWBUFFER *)iop_mu_regs_map1;
4496	} else {
4497		uint32_t *iop_mu_regs_map0;
4498
4499		acb->adapter_type = ACB_ADAPTER_TYPE_A; /* intel */
4500		dma_sync_size = ARCMSR_MAX_FREECCB_NUM*
4501		    sizeof (struct CCB) + 0x20;
4502		if (ddi_regs_map_setup(acb->dev_info, 1,
4503		    (caddr_t *)&iop_mu_regs_map0, 0,
4504		    sizeof (struct HBA_msgUnit), &acb->dev_acc_attr,
4505		    &acb->reg_mu_acc_handle0) != DDI_SUCCESS) {
4506			arcmsr_log(NULL, CE_WARN,
4507			    "arcmsr%d: unable to map registers",
4508			    ddi_get_instance(acb->dev_info));
4509			return (DDI_FAILURE);
4510		}
4511
4512		if ((i = ddi_dma_alloc_handle(acb->dev_info, &arcmsr_ccb_attr,
4513		    DDI_DMA_SLEEP, NULL, &acb->ccbs_pool_handle)) !=
4514		    DDI_SUCCESS) {
4515			switch (i) {
4516			case DDI_DMA_BADATTR:
4517				cmn_err(CE_WARN,
4518				    "arcmsr%d: ddi_dma_alloc_handle "
4519				    "got DDI_DMA_BADATTR",
4520				    ddi_get_instance(acb->dev_info));
4521				return (DDI_FAILURE);
4522			case DDI_DMA_NORESOURCES:
4523				cmn_err(CE_WARN, "arcmsr%d: "
4524				    "ddi_dma_alloc_handle got "
4525				    "DDI_DMA_NORESOURCES",
4526				    ddi_get_instance(acb->dev_info));
4527				return (DDI_FAILURE);
4528			}
4529			cmn_err(CE_WARN,
4530			    "arcmsr%d: ddi_dma_alloc_handle failed",
4531			    ddi_get_instance(acb->dev_info));
4532			return (DDI_FAILURE);
4533		}
4534
4535		if (ddi_dma_mem_alloc(acb->ccbs_pool_handle, dma_sync_size,
4536		    &acb->dev_acc_attr, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
4537		    DDI_DMA_SLEEP, NULL, (caddr_t *)&arcmsr_ccbs_area,
4538		    &allocated_length, &acb->ccbs_acc_handle)
4539		    != DDI_SUCCESS) {
4540			cmn_err(CE_WARN, "arcmsr%d: ddi_dma_mem_alloc failed",
4541			    ddi_get_instance(acb->dev_info));
4542			ddi_dma_free_handle(&acb->ccbs_pool_handle);
4543			return (DDI_FAILURE);
4544		}
4545
4546		if (ddi_dma_addr_bind_handle(acb->ccbs_pool_handle, NULL,
4547		    (caddr_t)arcmsr_ccbs_area, dma_sync_size, DDI_DMA_RDWR |
4548		    DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &acb->ccb_cookie,
4549		    &count) != DDI_DMA_MAPPED) {
4550			cmn_err(CE_WARN, "arcmsr%d: ddi_dma_addr_bind_handle "
4551			    "failed",
4552			    ddi_get_instance(acb->dev_info));
4553			ddi_dma_mem_free(&acb->ccbs_acc_handle);
4554			ddi_dma_free_handle(&acb->ccbs_pool_handle);
4555			return (DDI_FAILURE);
4556		}
4557		bzero(arcmsr_ccbs_area, dma_sync_size);
4558		/* ioport base */
4559		acb->pmu = (struct msgUnit *)(intptr_t)iop_mu_regs_map0;
4560	}
4561
4562	/* here we can not access pci configuration again */
4563	acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
4564	    ACB_F_MESSAGE_RQBUFFER_CLEARED | ACB_F_MESSAGE_WQBUFFER_READ);
4565	acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER;
4566	/* physical address of acb->pccb_pool */
4567	ccb_phyaddr = acb->ccb_cookie.dmac_address;
4568
4569	if (((unsigned long)arcmsr_ccbs_area & 0x1F) != 0) {
4570		/* ccb address must 32 (0x20) boundary */
4571		arcmsr_ccbs_area = (caddr_t)((unsigned long)arcmsr_ccbs_area +
4572		    (0x20 - ((unsigned long)arcmsr_ccbs_area & 0x1F)));
4573		ccb_phyaddr = (unsigned long)ccb_phyaddr +
4574		    (0x20 - ((unsigned long)ccb_phyaddr & 0x1F));
4575	}
4576
4577	pccb_tmp = (struct CCB *)(intptr_t)arcmsr_ccbs_area;
4578
4579	for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
4580		pccb_tmp->cdb_shifted_phyaddr = ccb_phyaddr >> 5;
4581		pccb_tmp->acb = acb;
4582		acb->ccbworkingQ[i] = acb->pccb_pool[i] = pccb_tmp;
4583		ccb_phyaddr = ccb_phyaddr + sizeof (struct CCB);
4584		pccb_tmp++;
4585	}
4586
4587	acb->vir2phy_offset = (unsigned long)pccb_tmp -
4588	    (unsigned long)ccb_phyaddr;
4589
4590	/* disable all outbound interrupt */
4591	intmask_org = arcmsr_disable_allintr(acb);
4592
4593	if (!arcmsr_iop_confirm(acb)) {
4594		cmn_err(CE_WARN, "arcmsr%d: arcmsr_iop_confirm error",
4595		    ddi_get_instance(acb->dev_info));
4596		ddi_dma_mem_free(&acb->ccbs_acc_handle);
4597		ddi_dma_free_handle(&acb->ccbs_pool_handle);
4598		return (DDI_FAILURE);
4599	}
4600
4601	for (id = 0; id < ARCMSR_MAX_TARGETID; id++) {
4602		for (lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++) {
4603			acb->devstate[id][lun] = ARECA_RAID_GONE;
4604		}
4605	}
4606
4607	/* enable outbound Post Queue, outbound doorbell Interrupt */
4608	arcmsr_enable_allintr(acb, intmask_org);
4609
4610	return (0);
4611}
4612