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