1/*
2********************************************************************************
3**        OS    : FreeBSD
4**   FILE NAME  : arcmsr.c
5**        BY    : Erich Chen, Ching Huang
6**   Description: SCSI RAID Device Driver for
7**                ARECA (ARC11XX/ARC12XX/ARC13XX/ARC16XX/ARC188x)
8**                SATA/SAS RAID HOST Adapter
9********************************************************************************
10********************************************************************************
11**
12** SPDX-License-Identifier: BSD-3-Clause
13**
14** Copyright (C) 2002 - 2012, Areca Technology Corporation All rights reserved.
15**
16** Redistribution and use in source and binary forms, with or without
17** modification, are permitted provided that the following conditions
18** are met:
19** 1. Redistributions of source code must retain the above copyright
20**    notice, this list of conditions and the following disclaimer.
21** 2. Redistributions in binary form must reproduce the above copyright
22**    notice, this list of conditions and the following disclaimer in the
23**    documentation and/or other materials provided with the distribution.
24** 3. The name of the author may not be used to endorse or promote products
25**    derived from this software without specific prior written permission.
26**
27** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
28** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
31** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT
32** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35**(INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF
36** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37********************************************************************************
38** History
39**
40**    REV#         DATE         NAME        DESCRIPTION
41** 1.00.00.00   03/31/2004  Erich Chen      First release
42** 1.20.00.02   11/29/2004  Erich Chen      bug fix with arcmsr_bus_reset when PHY error
43** 1.20.00.03   04/19/2005  Erich Chen      add SATA 24 Ports adapter type support
44**                                          clean unused function
45** 1.20.00.12   09/12/2005  Erich Chen      bug fix with abort command handling,
46**                                          firmware version check
47**                                          and firmware update notify for hardware bug fix
48**                                          handling if none zero high part physical address
49**                                          of srb resource
50** 1.20.00.13   08/18/2006  Erich Chen      remove pending srb and report busy
51**                                          add iop message xfer
52**                                          with scsi pass-through command
53**                                          add new device id of sas raid adapters
54**                                          code fit for SPARC64 & PPC
55** 1.20.00.14   02/05/2007  Erich Chen      bug fix for incorrect ccb_h.status report
56**                                          and cause g_vfs_done() read write error
57** 1.20.00.15   10/10/2007  Erich Chen      support new RAID adapter type ARC120x
58** 1.20.00.16   10/10/2009  Erich Chen      Bug fix for RAID adapter type ARC120x
59**                                          bus_dmamem_alloc() with BUS_DMA_ZERO
60** 1.20.00.17   07/15/2010  Ching Huang     Added support ARC1880
61**                                          report CAM_DEV_NOT_THERE instead of CAM_SEL_TIMEOUT when device failed,
62**                                          prevent cam_periph_error removing all LUN devices of one Target id
63**                                          for any one LUN device failed
64** 1.20.00.18   10/14/2010  Ching Huang     Fixed "inquiry data fails comparion at DV1 step"
65**              10/25/2010  Ching Huang     Fixed bad range input in bus_alloc_resource for ADAPTER_TYPE_B
66** 1.20.00.19   11/11/2010  Ching Huang     Fixed arcmsr driver prevent arcsas support for Areca SAS HBA ARC13x0
67** 1.20.00.20   12/08/2010  Ching Huang     Avoid calling atomic_set_int function
68** 1.20.00.21   02/08/2011  Ching Huang     Implement I/O request timeout
69**              02/14/2011  Ching Huang     Modified pktRequestCount
70** 1.20.00.21   03/03/2011  Ching Huang     if a command timeout, then wait its ccb back before free it
71** 1.20.00.22   07/04/2011  Ching Huang     Fixed multiple MTX panic
72** 1.20.00.23   10/28/2011  Ching Huang     Added TIMEOUT_DELAY in case of too many HDDs need to start
73** 1.20.00.23   11/08/2011  Ching Huang     Added report device transfer speed
74** 1.20.00.23   01/30/2012  Ching Huang     Fixed Request requeued and Retrying command
75** 1.20.00.24   06/11/2012  Ching Huang     Fixed return sense data condition
76** 1.20.00.25   08/17/2012  Ching Huang     Fixed hotplug device no function on type A adapter
77** 1.20.00.26   12/14/2012  Ching Huang     Added support ARC1214,1224,1264,1284
78** 1.20.00.27   05/06/2013  Ching Huang     Fixed out standing cmd full on ARC-12x4
79** 1.20.00.28   09/13/2013  Ching Huang     Removed recursive mutex in arcmsr_abort_dr_ccbs
80** 1.20.00.29   12/18/2013  Ching Huang     Change simq allocation number, support ARC1883
81** 1.30.00.00   11/30/2015  Ching Huang     Added support ARC1203
82** 1.40.00.00   07/11/2017  Ching Huang     Added support ARC1884
83** 1.40.00.01   10/30/2017  Ching Huang     Fixed release memory resource
84** 1.50.00.00   09/30/2020  Ching Huang     Added support ARC-1886, NVMe/SAS/SATA controller
85** 1.50.00.01   02/26/2021  Ching Huang     Fixed no action of hot plugging device on type_F adapter
86** 1.50.00.02   04/16/2021  Ching Huang     Fixed scsi command timeout on ARC-1886 when
87**                                          scatter-gather count large than some number
88** 1.50.00.03   05/04/2021  Ching Huang     Fixed doorbell status arrived late on ARC-1886
89** 1.50.00.04   12/08/2021  Ching Huang     Fixed boot up hung under ARC-1886 with no volume created
90** 1.50.00.05   03/23/2023  Ching Huang     Fixed reading buffer empty length error
91** 1.50.00.06   08/07/2023  Ching Huang     Add support adapter using system memory as XOR buffer,
92**                                          Add support device ID 1883,1886
93******************************************************************************************
94*/
95
96#include <sys/cdefs.h>
97#if 0
98#define ARCMSR_DEBUG1			1
99#endif
100#include <sys/param.h>
101#include <sys/systm.h>
102#include <sys/malloc.h>
103#include <sys/kernel.h>
104#include <sys/bus.h>
105#include <sys/queue.h>
106#include <sys/stat.h>
107#include <sys/devicestat.h>
108#include <sys/kthread.h>
109#include <sys/module.h>
110#include <sys/proc.h>
111#include <sys/lock.h>
112#include <sys/sysctl.h>
113#include <sys/poll.h>
114#include <sys/ioccom.h>
115#include <vm/vm.h>
116#include <vm/vm_param.h>
117#include <vm/pmap.h>
118
119#include <isa/rtc.h>
120
121#include <machine/bus.h>
122#include <machine/resource.h>
123#include <machine/atomic.h>
124#include <sys/conf.h>
125#include <sys/rman.h>
126
127#include <cam/cam.h>
128#include <cam/cam_ccb.h>
129#include <cam/cam_sim.h>
130#include <cam/cam_periph.h>
131#include <cam/cam_xpt_periph.h>
132#include <cam/cam_xpt_sim.h>
133#include <cam/cam_debug.h>
134#include <cam/scsi/scsi_all.h>
135#include <cam/scsi/scsi_message.h>
136/*
137**************************************************************************
138**************************************************************************
139*/
140#include <sys/selinfo.h>
141#include <sys/mutex.h>
142#include <sys/endian.h>
143#include <dev/pci/pcivar.h>
144#include <dev/pci/pcireg.h>
145
146#define arcmsr_callout_init(a)	callout_init(a, /*mpsafe*/1);
147
148#define ARCMSR_DRIVER_VERSION	"arcmsr version 1.50.00.06 2023-08-07"
149#include <dev/arcmsr/arcmsr.h>
150/*
151**************************************************************************
152**************************************************************************
153*/
154static void arcmsr_free_srb(struct CommandControlBlock *srb);
155static struct CommandControlBlock *arcmsr_get_freesrb(struct AdapterControlBlock *acb);
156static u_int8_t arcmsr_seek_cmd2abort(union ccb *abortccb);
157static int arcmsr_probe(device_t dev);
158static int arcmsr_attach(device_t dev);
159static int arcmsr_detach(device_t dev);
160static u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_cmd, caddr_t arg);
161static void arcmsr_iop_parking(struct AdapterControlBlock *acb);
162static int arcmsr_shutdown(device_t dev);
163static void arcmsr_interrupt(struct AdapterControlBlock *acb);
164static void arcmsr_polling_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb);
165static void arcmsr_free_resource(struct AdapterControlBlock *acb);
166static void arcmsr_bus_reset(struct AdapterControlBlock *acb);
167static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb);
168static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb);
169static void arcmsr_iop_init(struct AdapterControlBlock *acb);
170static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb);
171static u_int32_t arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb, struct QBUFFER *prbuffer);
172static void arcmsr_Write_data_2iop_wqbuffer(struct AdapterControlBlock *acb);
173static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb);
174static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag);
175static void arcmsr_iop_reset(struct AdapterControlBlock *acb);
176static void arcmsr_report_sense_info(struct CommandControlBlock *srb);
177static void arcmsr_build_srb(struct CommandControlBlock *srb, bus_dma_segment_t *dm_segs, u_int32_t nseg);
178static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *pccb);
179static int arcmsr_resume(device_t dev);
180static int arcmsr_suspend(device_t dev);
181static void arcmsr_rescanLun_cb(struct cam_periph *periph, union ccb *ccb);
182static void arcmsr_polling_devmap(void *arg);
183static void arcmsr_srb_timeout(void *arg);
184static void arcmsr_hbd_postqueue_isr(struct AdapterControlBlock *acb);
185static void arcmsr_hbe_postqueue_isr(struct AdapterControlBlock *acb);
186static void arcmsr_hbf_postqueue_isr(struct AdapterControlBlock *acb);
187static void arcmsr_teardown_intr(device_t dev, struct AdapterControlBlock *acb);
188#ifdef ARCMSR_DEBUG1
189static void arcmsr_dump_data(struct AdapterControlBlock *acb);
190#endif
191/*
192**************************************************************************
193**************************************************************************
194*/
195static void UDELAY(u_int32_t us) { DELAY(us); }
196/*
197**************************************************************************
198**************************************************************************
199*/
200static bus_dmamap_callback_t arcmsr_map_free_srb;
201static bus_dmamap_callback_t arcmsr_execute_srb;
202/*
203**************************************************************************
204**************************************************************************
205*/
206static d_open_t	arcmsr_open;
207static d_close_t arcmsr_close;
208static d_ioctl_t arcmsr_ioctl;
209
210static device_method_t arcmsr_methods[]={
211	DEVMETHOD(device_probe,		arcmsr_probe),
212	DEVMETHOD(device_attach,	arcmsr_attach),
213	DEVMETHOD(device_detach,	arcmsr_detach),
214	DEVMETHOD(device_shutdown,	arcmsr_shutdown),
215	DEVMETHOD(device_suspend,	arcmsr_suspend),
216	DEVMETHOD(device_resume,	arcmsr_resume),
217	DEVMETHOD_END
218};
219
220static driver_t arcmsr_driver={
221	"arcmsr", arcmsr_methods, sizeof(struct AdapterControlBlock)
222};
223
224DRIVER_MODULE(arcmsr, pci, arcmsr_driver, 0, 0);
225MODULE_DEPEND(arcmsr, pci, 1, 1, 1);
226MODULE_DEPEND(arcmsr, cam, 1, 1, 1);
227#ifndef BUS_DMA_COHERENT
228	#define	BUS_DMA_COHERENT	0x04	/* hint: map memory in a coherent way */
229#endif
230static struct cdevsw arcmsr_cdevsw={
231		.d_version = D_VERSION,
232		.d_open    = arcmsr_open, 	/* open     */
233		.d_close   = arcmsr_close, 	/* close    */
234		.d_ioctl   = arcmsr_ioctl, 	/* ioctl    */
235		.d_name    = "arcmsr", 		/* name     */
236	};
237/*
238**************************************************************************
239**************************************************************************
240*/
241static int arcmsr_open(struct cdev *dev, int flags, int fmt, struct thread *proc)
242{
243	return (0);
244}
245/*
246**************************************************************************
247**************************************************************************
248*/
249static int arcmsr_close(struct cdev *dev, int flags, int fmt, struct thread *proc)
250{
251	return 0;
252}
253/*
254**************************************************************************
255**************************************************************************
256*/
257static int arcmsr_ioctl(struct cdev *dev, u_long ioctl_cmd, caddr_t arg, int flags, struct thread *proc)
258{
259	struct AdapterControlBlock *acb = dev->si_drv1;
260
261	return (arcmsr_iop_ioctlcmd(acb, ioctl_cmd, arg));
262}
263/*
264**********************************************************************
265**********************************************************************
266*/
267static u_int32_t arcmsr_disable_allintr( struct AdapterControlBlock *acb)
268{
269	u_int32_t intmask_org = 0;
270
271	switch (acb->adapter_type) {
272	case ACB_ADAPTER_TYPE_A: {
273			/* disable all outbound interrupt */
274			intmask_org = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intmask); /* disable outbound message0 int */
275			CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intmask, intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE);
276		}
277		break;
278	case ACB_ADAPTER_TYPE_B: {
279			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
280			/* disable all outbound interrupt */
281			intmask_org = READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell_mask)
282						& (~ARCMSR_IOP2DRV_MESSAGE_CMD_DONE); /* disable outbound message0 int */
283			WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell_mask, 0); /* disable all interrupt */
284		}
285		break;
286	case ACB_ADAPTER_TYPE_C: {
287			/* disable all outbound interrupt */
288			intmask_org = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_mask); /* disable outbound message0 int */
289			CHIP_REG_WRITE32(HBC_MessageUnit, 0, host_int_mask, intmask_org|ARCMSR_HBCMU_ALL_INTMASKENABLE);
290		}
291		break;
292	case ACB_ADAPTER_TYPE_D: {
293			/* disable all outbound interrupt */
294			intmask_org = CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable); /* disable outbound message0 int */
295			CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, ARCMSR_HBDMU_ALL_INT_DISABLE);
296		}
297		break;
298	case ACB_ADAPTER_TYPE_E:
299	case ACB_ADAPTER_TYPE_F: {
300			/* disable all outbound interrupt */
301			intmask_org = CHIP_REG_READ32(HBE_MessageUnit, 0, host_int_mask); /* disable outbound message0 int */
302			CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_mask, intmask_org | ARCMSR_HBEMU_ALL_INTMASKENABLE);
303		}
304		break;
305	}
306	return (intmask_org);
307}
308/*
309**********************************************************************
310**********************************************************************
311*/
312static void arcmsr_enable_allintr( struct AdapterControlBlock *acb, u_int32_t intmask_org)
313{
314	u_int32_t mask;
315
316	switch (acb->adapter_type) {
317	case ACB_ADAPTER_TYPE_A: {
318			/* enable outbound Post Queue, outbound doorbell Interrupt */
319			mask = ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE|ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE|ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE);
320			CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intmask, intmask_org & mask);
321			acb->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff;
322		}
323		break;
324	case ACB_ADAPTER_TYPE_B: {
325			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
326			/* enable ARCMSR_IOP2DRV_MESSAGE_CMD_DONE */
327			mask = (ARCMSR_IOP2DRV_DATA_WRITE_OK|ARCMSR_IOP2DRV_DATA_READ_OK|ARCMSR_IOP2DRV_CDB_DONE|ARCMSR_IOP2DRV_MESSAGE_CMD_DONE);
328			WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell_mask, intmask_org | mask); /*1=interrupt enable, 0=interrupt disable*/
329			acb->outbound_int_enable = (intmask_org | mask) & 0x0000000f;
330		}
331		break;
332	case ACB_ADAPTER_TYPE_C: {
333			/* enable outbound Post Queue, outbound doorbell Interrupt */
334			mask = ~(ARCMSR_HBCMU_UTILITY_A_ISR_MASK | ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR_MASK | ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK);
335			CHIP_REG_WRITE32(HBC_MessageUnit, 0, host_int_mask, intmask_org & mask);
336			acb->outbound_int_enable = ~(intmask_org & mask) & 0x0000000f;
337		}
338		break;
339	case ACB_ADAPTER_TYPE_D: {
340			/* enable outbound Post Queue, outbound doorbell Interrupt */
341			mask = ARCMSR_HBDMU_ALL_INT_ENABLE;
342			CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, intmask_org | mask);
343			CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable);
344			acb->outbound_int_enable = mask;
345		}
346		break;
347	case ACB_ADAPTER_TYPE_E:
348	case ACB_ADAPTER_TYPE_F: {
349			/* enable outbound Post Queue, outbound doorbell Interrupt */
350			mask = ~(ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR | ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR);
351			CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_mask, intmask_org & mask);
352			acb->outbound_int_enable = ~(intmask_org & mask) & 0x0000000f;
353		}
354		break;
355	}
356}
357/*
358**********************************************************************
359**********************************************************************
360*/
361static u_int8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
362{
363	u_int32_t Index;
364	u_int8_t Retries = 0x00;
365
366	do {
367		for(Index=0; Index < 100; Index++) {
368			if(CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
369				CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, ARCMSR_MU_OUTBOUND_MESSAGE0_INT);/*clear interrupt*/
370				return TRUE;
371			}
372			UDELAY(10000);
373		}/*max 1 seconds*/
374	}while(Retries++ < 20);/*max 20 sec*/
375	return (FALSE);
376}
377/*
378**********************************************************************
379**********************************************************************
380*/
381static u_int8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb)
382{
383	u_int32_t Index;
384	u_int8_t Retries = 0x00;
385	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
386
387	do {
388		for(Index=0; Index < 100; Index++) {
389			if(READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell) & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
390				WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);/*clear interrupt*/
391				WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
392				return TRUE;
393			}
394			UDELAY(10000);
395		}/*max 1 seconds*/
396	}while(Retries++ < 20);/*max 20 sec*/
397	return (FALSE);
398}
399/*
400**********************************************************************
401**********************************************************************
402*/
403static u_int8_t arcmsr_hbc_wait_msgint_ready(struct AdapterControlBlock *acb)
404{
405	u_int32_t Index;
406	u_int8_t Retries = 0x00;
407
408	do {
409		for(Index=0; Index < 100; Index++) {
410			if(CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
411				CHIP_REG_WRITE32(HBC_MessageUnit, 0, outbound_doorbell_clear, ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR);/*clear interrupt*/
412				return TRUE;
413			}
414			UDELAY(10000);
415		}/*max 1 seconds*/
416	}while(Retries++ < 20);/*max 20 sec*/
417	return (FALSE);
418}
419/*
420**********************************************************************
421**********************************************************************
422*/
423static u_int8_t arcmsr_hbd_wait_msgint_ready(struct AdapterControlBlock *acb)
424{
425	u_int32_t Index;
426	u_int8_t Retries = 0x00;
427
428	do {
429		for(Index=0; Index < 100; Index++) {
430			if(CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE) {
431				CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR);/*clear interrupt*/
432				return TRUE;
433			}
434			UDELAY(10000);
435		}/*max 1 seconds*/
436	}while(Retries++ < 20);/*max 20 sec*/
437	return (FALSE);
438}
439/*
440**********************************************************************
441**********************************************************************
442*/
443static u_int8_t arcmsr_hbe_wait_msgint_ready(struct AdapterControlBlock *acb)
444{
445	u_int32_t Index, read_doorbell;
446	u_int8_t Retries = 0x00;
447
448	do {
449		for(Index=0; Index < 100; Index++) {
450			read_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell);
451			if((read_doorbell ^ acb->in_doorbell) & ARCMSR_HBEMU_IOP2DRV_MESSAGE_CMD_DONE) {
452				CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0);/*clear interrupt*/
453				acb->in_doorbell = read_doorbell;
454				return TRUE;
455			}
456			UDELAY(10000);
457		}/*max 1 seconds*/
458	}while(Retries++ < 20);/*max 20 sec*/
459	return (FALSE);
460}
461/*
462************************************************************************
463************************************************************************
464*/
465static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)
466{
467	int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
468
469	CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
470	do {
471		if(arcmsr_hba_wait_msgint_ready(acb)) {
472			break;
473		} else {
474			retry_count--;
475		}
476	}while(retry_count != 0);
477}
478/*
479************************************************************************
480************************************************************************
481*/
482static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb)
483{
484	int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
485	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
486
487	WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_FLUSH_CACHE);
488	do {
489		if(arcmsr_hbb_wait_msgint_ready(acb)) {
490			break;
491		} else {
492			retry_count--;
493		}
494	}while(retry_count != 0);
495}
496/*
497************************************************************************
498************************************************************************
499*/
500static void arcmsr_flush_hbc_cache(struct AdapterControlBlock *acb)
501{
502	int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
503
504	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
505	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
506	do {
507		if(arcmsr_hbc_wait_msgint_ready(acb)) {
508			break;
509		} else {
510			retry_count--;
511		}
512	}while(retry_count != 0);
513}
514/*
515************************************************************************
516************************************************************************
517*/
518static void arcmsr_flush_hbd_cache(struct AdapterControlBlock *acb)
519{
520	int retry_count = 30; /* enlarge wait flush adapter cache time: 10 minute */
521
522	CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
523	do {
524		if(arcmsr_hbd_wait_msgint_ready(acb)) {
525			break;
526		} else {
527			retry_count--;
528		}
529	}while(retry_count != 0);
530}
531/*
532************************************************************************
533************************************************************************
534*/
535static void arcmsr_flush_hbe_cache(struct AdapterControlBlock *acb)
536{
537	int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
538
539	CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
540	acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
541	CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
542	do {
543		if(arcmsr_hbe_wait_msgint_ready(acb)) {
544			break;
545		} else {
546			retry_count--;
547		}
548	}while(retry_count != 0);
549}
550/*
551************************************************************************
552************************************************************************
553*/
554static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
555{
556	switch (acb->adapter_type) {
557	case ACB_ADAPTER_TYPE_A: {
558			arcmsr_flush_hba_cache(acb);
559		}
560		break;
561	case ACB_ADAPTER_TYPE_B: {
562			arcmsr_flush_hbb_cache(acb);
563		}
564		break;
565	case ACB_ADAPTER_TYPE_C: {
566			arcmsr_flush_hbc_cache(acb);
567		}
568		break;
569	case ACB_ADAPTER_TYPE_D: {
570			arcmsr_flush_hbd_cache(acb);
571		}
572		break;
573	case ACB_ADAPTER_TYPE_E:
574	case ACB_ADAPTER_TYPE_F: {
575			arcmsr_flush_hbe_cache(acb);
576		}
577		break;
578	}
579}
580/*
581*******************************************************************************
582*******************************************************************************
583*/
584static int arcmsr_suspend(device_t dev)
585{
586	struct AdapterControlBlock	*acb = device_get_softc(dev);
587
588	/* flush controller */
589	arcmsr_iop_parking(acb);
590	/* disable all outbound interrupt */
591	arcmsr_disable_allintr(acb);
592	return(0);
593}
594/*
595*******************************************************************************
596*******************************************************************************
597*/
598static int arcmsr_resume(device_t dev)
599{
600	struct AdapterControlBlock	*acb = device_get_softc(dev);
601
602	arcmsr_iop_init(acb);
603	return(0);
604}
605/*
606*********************************************************************************
607*********************************************************************************
608*/
609static void arcmsr_async(void *cb_arg, u_int32_t code, struct cam_path *path, void *arg)
610{
611	u_int8_t target_id, target_lun;
612
613	switch (code) {
614	case AC_LOST_DEVICE:
615		target_id = xpt_path_target_id(path);
616		target_lun = xpt_path_lun_id(path);
617		if((target_id > ARCMSR_MAX_TARGETID) || (target_lun > ARCMSR_MAX_TARGETLUN)) {
618			break;
619		}
620		break;
621	default:
622		break;
623	}
624}
625/*
626**********************************************************************
627**********************************************************************
628*/
629static void arcmsr_report_sense_info(struct CommandControlBlock *srb)
630{
631	union ccb *pccb = srb->pccb;
632
633	pccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
634	pccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
635	if(pccb->csio.sense_len) {
636		memset(&pccb->csio.sense_data, 0, sizeof(pccb->csio.sense_data));
637		memcpy(&pccb->csio.sense_data, srb->arcmsr_cdb.SenseData,
638		get_min(sizeof(struct SENSE_DATA), sizeof(pccb->csio.sense_data)));
639		((u_int8_t *)&pccb->csio.sense_data)[0] = (0x1 << 7 | 0x70); /* Valid,ErrorCode */
640		pccb->ccb_h.status |= CAM_AUTOSNS_VALID;
641	}
642}
643/*
644*********************************************************************
645*********************************************************************
646*/
647static void arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb)
648{
649	CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_ABORT_CMD);
650	if(!arcmsr_hba_wait_msgint_ready(acb)) {
651		printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit);
652	}
653}
654/*
655*********************************************************************
656*********************************************************************
657*/
658static void arcmsr_abort_hbb_allcmd(struct AdapterControlBlock *acb)
659{
660	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
661	WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_ABORT_CMD);
662	if(!arcmsr_hbb_wait_msgint_ready(acb)) {
663		printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit);
664	}
665}
666/*
667*********************************************************************
668*********************************************************************
669*/
670static void arcmsr_abort_hbc_allcmd(struct AdapterControlBlock *acb)
671{
672	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_ABORT_CMD);
673	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
674	if(!arcmsr_hbc_wait_msgint_ready(acb)) {
675		printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit);
676	}
677}
678/*
679*********************************************************************
680*********************************************************************
681*/
682static void arcmsr_abort_hbd_allcmd(struct AdapterControlBlock *acb)
683{
684	CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_ABORT_CMD);
685	if(!arcmsr_hbd_wait_msgint_ready(acb)) {
686		printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit);
687	}
688}
689/*
690*********************************************************************
691*********************************************************************
692*/
693static void arcmsr_abort_hbe_allcmd(struct AdapterControlBlock *acb)
694{
695	CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_ABORT_CMD);
696	acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
697	CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
698	if(!arcmsr_hbe_wait_msgint_ready(acb)) {
699		printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit);
700	}
701}
702/*
703*********************************************************************
704*********************************************************************
705*/
706static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb)
707{
708	switch (acb->adapter_type) {
709	case ACB_ADAPTER_TYPE_A: {
710			arcmsr_abort_hba_allcmd(acb);
711		}
712		break;
713	case ACB_ADAPTER_TYPE_B: {
714			arcmsr_abort_hbb_allcmd(acb);
715		}
716		break;
717	case ACB_ADAPTER_TYPE_C: {
718			arcmsr_abort_hbc_allcmd(acb);
719		}
720		break;
721	case ACB_ADAPTER_TYPE_D: {
722			arcmsr_abort_hbd_allcmd(acb);
723		}
724		break;
725	case ACB_ADAPTER_TYPE_E:
726	case ACB_ADAPTER_TYPE_F: {
727			arcmsr_abort_hbe_allcmd(acb);
728		}
729		break;
730	}
731}
732/*
733**********************************************************************
734**********************************************************************
735*/
736static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag)
737{
738	struct AdapterControlBlock *acb = srb->acb;
739	union ccb *pccb = srb->pccb;
740
741	if(srb->srb_flags & SRB_FLAG_TIMER_START)
742		callout_stop(&srb->ccb_callout);
743	if((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
744		bus_dmasync_op_t op;
745
746		if((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
747			op = BUS_DMASYNC_POSTREAD;
748		} else {
749			op = BUS_DMASYNC_POSTWRITE;
750		}
751		bus_dmamap_sync(acb->dm_segs_dmat, srb->dm_segs_dmamap, op);
752		bus_dmamap_unload(acb->dm_segs_dmat, srb->dm_segs_dmamap);
753	}
754	if(stand_flag == 1) {
755		atomic_subtract_int(&acb->srboutstandingcount, 1);
756		if((acb->acb_flags & ACB_F_CAM_DEV_QFRZN) && (
757		acb->srboutstandingcount < (acb->maxOutstanding -10))) {
758			acb->acb_flags &= ~ACB_F_CAM_DEV_QFRZN;
759			pccb->ccb_h.status |= CAM_RELEASE_SIMQ;
760		}
761	}
762	if(srb->srb_state != ARCMSR_SRB_TIMEOUT)
763		arcmsr_free_srb(srb);
764	acb->pktReturnCount++;
765	xpt_done(pccb);
766}
767/*
768**************************************************************************
769**************************************************************************
770*/
771static void arcmsr_report_srb_state(struct AdapterControlBlock *acb, struct CommandControlBlock *srb, u_int16_t error)
772{
773	int target, lun;
774
775	target = srb->pccb->ccb_h.target_id;
776	lun = srb->pccb->ccb_h.target_lun;
777	if(error == FALSE) {
778		if(acb->devstate[target][lun] == ARECA_RAID_GONE) {
779			acb->devstate[target][lun] = ARECA_RAID_GOOD;
780		}
781		srb->pccb->ccb_h.status |= CAM_REQ_CMP;
782		arcmsr_srb_complete(srb, 1);
783	} else {
784		switch(srb->arcmsr_cdb.DeviceStatus) {
785		case ARCMSR_DEV_SELECT_TIMEOUT: {
786				if(acb->devstate[target][lun] == ARECA_RAID_GOOD) {
787					printf( "arcmsr%d: Target=%x, Lun=%x, selection timeout, raid volume was lost\n", acb->pci_unit, target, lun);
788				}
789				acb->devstate[target][lun] = ARECA_RAID_GONE;
790				srb->pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
791				arcmsr_srb_complete(srb, 1);
792			}
793			break;
794		case ARCMSR_DEV_ABORTED:
795		case ARCMSR_DEV_INIT_FAIL: {
796				acb->devstate[target][lun] = ARECA_RAID_GONE;
797				srb->pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
798				arcmsr_srb_complete(srb, 1);
799			}
800			break;
801		case SCSISTAT_CHECK_CONDITION: {
802				acb->devstate[target][lun] = ARECA_RAID_GOOD;
803				arcmsr_report_sense_info(srb);
804				arcmsr_srb_complete(srb, 1);
805			}
806			break;
807		default:
808			printf("arcmsr%d: scsi id=%d lun=%d isr got command error done,but got unknown DeviceStatus=0x%x \n"
809					, acb->pci_unit, target, lun ,srb->arcmsr_cdb.DeviceStatus);
810			acb->devstate[target][lun] = ARECA_RAID_GONE;
811			srb->pccb->ccb_h.status |= CAM_UNCOR_PARITY;
812			/*unknown error or crc error just for retry*/
813			arcmsr_srb_complete(srb, 1);
814			break;
815		}
816	}
817}
818/*
819**************************************************************************
820**************************************************************************
821*/
822static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, u_int32_t flag_srb, u_int16_t error)
823{
824	struct CommandControlBlock *srb;
825
826	/* check if command done with no error*/
827	switch (acb->adapter_type) {
828	case ACB_ADAPTER_TYPE_A:
829	case ACB_ADAPTER_TYPE_B:
830		srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
831		break;
832	case ACB_ADAPTER_TYPE_C:
833	case ACB_ADAPTER_TYPE_D:
834		srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0)); /*frame must be 32 bytes aligned*/
835		break;
836	case ACB_ADAPTER_TYPE_E:
837	case ACB_ADAPTER_TYPE_F:
838		srb = acb->psrb_pool[flag_srb];
839		break;
840	default:
841		srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
842		break;
843	}
844	if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
845		if(srb->srb_state == ARCMSR_SRB_TIMEOUT) {
846			arcmsr_free_srb(srb);
847			printf("arcmsr%d: srb='%p' return srb has been timeouted\n", acb->pci_unit, srb);
848			return;
849		}
850		printf("arcmsr%d: return srb has been completed\n"
851			"srb='%p' srb_state=0x%x outstanding srb count=%d \n",
852			acb->pci_unit, srb, srb->srb_state, acb->srboutstandingcount);
853		return;
854	}
855	arcmsr_report_srb_state(acb, srb, error);
856}
857/*
858**************************************************************************
859**************************************************************************
860*/
861static void	arcmsr_srb_timeout(void *arg)
862{
863	struct CommandControlBlock *srb = (struct CommandControlBlock *)arg;
864	struct AdapterControlBlock *acb;
865	int target, lun;
866	u_int8_t cmd;
867
868	target = srb->pccb->ccb_h.target_id;
869	lun = srb->pccb->ccb_h.target_lun;
870	acb = srb->acb;
871	ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
872	if(srb->srb_state == ARCMSR_SRB_START)
873	{
874		cmd = scsiio_cdb_ptr(&srb->pccb->csio)[0];
875		srb->srb_state = ARCMSR_SRB_TIMEOUT;
876		srb->pccb->ccb_h.status |= CAM_CMD_TIMEOUT;
877		arcmsr_srb_complete(srb, 1);
878		printf("arcmsr%d: scsi id %d lun %d cmd=0x%x srb='%p' ccb command time out!\n",
879				 acb->pci_unit, target, lun, cmd, srb);
880	}
881	ARCMSR_LOCK_RELEASE(&acb->isr_lock);
882#ifdef ARCMSR_DEBUG1
883	arcmsr_dump_data(acb);
884#endif
885}
886
887/*
888**********************************************************************
889**********************************************************************
890*/
891static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
892{
893	int i=0;
894	u_int32_t flag_srb;
895	u_int16_t error;
896
897	switch (acb->adapter_type) {
898	case ACB_ADAPTER_TYPE_A: {
899			u_int32_t outbound_intstatus;
900
901			/*clear and abort all outbound posted Q*/
902			outbound_intstatus = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable;
903			CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intstatus);/*clear interrupt*/
904			while(((flag_srb=CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_queueport)) != 0xFFFFFFFF) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
905				error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
906				arcmsr_drain_donequeue(acb, flag_srb, error);
907			}
908		}
909		break;
910	case ACB_ADAPTER_TYPE_B: {
911			struct HBB_MessageUnit *phbbmu=(struct HBB_MessageUnit *)acb->pmu;
912
913			/*clear all outbound posted Q*/
914			WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN); /* clear doorbell interrupt */
915			for(i=0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) {
916				if((flag_srb = phbbmu->done_qbuffer[i]) != 0) {
917					phbbmu->done_qbuffer[i] = 0;
918					error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
919					arcmsr_drain_donequeue(acb, flag_srb, error);
920				}
921				phbbmu->post_qbuffer[i] = 0;
922			}/*drain reply FIFO*/
923			phbbmu->doneq_index = 0;
924			phbbmu->postq_index = 0;
925		}
926		break;
927	case ACB_ADAPTER_TYPE_C: {
928			while((CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
929				flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
930				error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
931				arcmsr_drain_donequeue(acb, flag_srb, error);
932			}
933		}
934		break;
935	case ACB_ADAPTER_TYPE_D:
936		arcmsr_hbd_postqueue_isr(acb);
937		break;
938	case ACB_ADAPTER_TYPE_E:
939		arcmsr_hbe_postqueue_isr(acb);
940		break;
941	case ACB_ADAPTER_TYPE_F:
942		arcmsr_hbf_postqueue_isr(acb);
943		break;
944	}
945}
946/*
947****************************************************************************
948****************************************************************************
949*/
950static void arcmsr_iop_reset(struct AdapterControlBlock *acb)
951{
952	struct CommandControlBlock *srb;
953	u_int32_t intmask_org;
954	u_int32_t i=0;
955
956	if(acb->srboutstandingcount>0) {
957		/* disable all outbound interrupt */
958		intmask_org = arcmsr_disable_allintr(acb);
959		/*clear and abort all outbound posted Q*/
960		arcmsr_done4abort_postqueue(acb);
961		/* talk to iop 331 outstanding command aborted*/
962		arcmsr_abort_allcmd(acb);
963		for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) {
964			srb = acb->psrb_pool[i];
965			if(srb->srb_state == ARCMSR_SRB_START) {
966				srb->srb_state = ARCMSR_SRB_ABORTED;
967				srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
968				arcmsr_srb_complete(srb, 1);
969				printf("arcmsr%d: scsi id=%d lun=%jx srb='%p' aborted\n"
970						, acb->pci_unit, srb->pccb->ccb_h.target_id
971						, (uintmax_t)srb->pccb->ccb_h.target_lun, srb);
972			}
973		}
974		/* enable all outbound interrupt */
975		arcmsr_enable_allintr(acb, intmask_org);
976	}
977	acb->srboutstandingcount = 0;
978	acb->workingsrb_doneindex = 0;
979	acb->workingsrb_startindex = 0;
980	acb->pktRequestCount = 0;
981	acb->pktReturnCount = 0;
982}
983/*
984**********************************************************************
985**********************************************************************
986*/
987static void arcmsr_build_srb(struct CommandControlBlock *srb,
988		bus_dma_segment_t *dm_segs, u_int32_t nseg)
989{
990	struct ARCMSR_CDB *arcmsr_cdb = &srb->arcmsr_cdb;
991	u_int8_t *psge = (u_int8_t *)&arcmsr_cdb->u;
992	u_int32_t address_lo, address_hi;
993	union ccb *pccb = srb->pccb;
994	struct ccb_scsiio *pcsio = &pccb->csio;
995	u_int32_t arccdbsize = 0x30;
996
997	memset(arcmsr_cdb, 0, sizeof(struct ARCMSR_CDB));
998	arcmsr_cdb->Bus = 0;
999	arcmsr_cdb->TargetID = pccb->ccb_h.target_id;
1000	arcmsr_cdb->LUN = pccb->ccb_h.target_lun;
1001	arcmsr_cdb->Function = 1;
1002	arcmsr_cdb->CdbLength = (u_int8_t)pcsio->cdb_len;
1003	bcopy(scsiio_cdb_ptr(pcsio), arcmsr_cdb->Cdb, pcsio->cdb_len);
1004	if(nseg != 0) {
1005		struct AdapterControlBlock *acb = srb->acb;
1006		bus_dmasync_op_t op;
1007		u_int32_t length, i, cdb_sgcount = 0;
1008
1009		if((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1010			op = BUS_DMASYNC_PREREAD;
1011		} else {
1012			op = BUS_DMASYNC_PREWRITE;
1013			arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE;
1014			srb->srb_flags |= SRB_FLAG_WRITE;
1015		}
1016		bus_dmamap_sync(acb->dm_segs_dmat, srb->dm_segs_dmamap, op);
1017		for(i=0; i < nseg; i++) {
1018			/* Get the physical address of the current data pointer */
1019			length = arcmsr_htole32(dm_segs[i].ds_len);
1020			address_lo = arcmsr_htole32(dma_addr_lo32(dm_segs[i].ds_addr));
1021			address_hi = arcmsr_htole32(dma_addr_hi32(dm_segs[i].ds_addr));
1022			if(address_hi == 0) {
1023				struct SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge;
1024				pdma_sg->address = address_lo;
1025				pdma_sg->length = length;
1026				psge += sizeof(struct SG32ENTRY);
1027				arccdbsize += sizeof(struct SG32ENTRY);
1028			} else {
1029				u_int32_t sg64s_size = 0, tmplength = length;
1030
1031				while(1) {
1032					u_int64_t span4G, length0;
1033					struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge;
1034
1035					span4G = (u_int64_t)address_lo + tmplength;
1036					pdma_sg->addresshigh = address_hi;
1037					pdma_sg->address = address_lo;
1038					if(span4G > 0x100000000) {
1039						/*see if cross 4G boundary*/
1040						length0 = 0x100000000-address_lo;
1041						pdma_sg->length = (u_int32_t)length0 | IS_SG64_ADDR;
1042						address_hi = address_hi+1;
1043						address_lo = 0;
1044						tmplength = tmplength - (u_int32_t)length0;
1045						sg64s_size += sizeof(struct SG64ENTRY);
1046						psge += sizeof(struct SG64ENTRY);
1047						cdb_sgcount++;
1048					} else {
1049						pdma_sg->length = tmplength | IS_SG64_ADDR;
1050						sg64s_size += sizeof(struct SG64ENTRY);
1051						psge += sizeof(struct SG64ENTRY);
1052						break;
1053					}
1054				}
1055				arccdbsize += sg64s_size;
1056			}
1057			cdb_sgcount++;
1058		}
1059		arcmsr_cdb->sgcount = (u_int8_t)cdb_sgcount;
1060		arcmsr_cdb->DataLength = pcsio->dxfer_len;
1061		if( arccdbsize > 256) {
1062			arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE;
1063		}
1064	} else {
1065		arcmsr_cdb->DataLength = 0;
1066	}
1067	srb->arc_cdb_size = arccdbsize;
1068	arcmsr_cdb->msgPages = (arccdbsize/256) + ((arccdbsize % 256) ? 1 : 0);
1069}
1070/*
1071**************************************************************************
1072**************************************************************************
1073*/
1074static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandControlBlock *srb)
1075{
1076	u_int32_t cdb_phyaddr_low = (u_int32_t) srb->cdb_phyaddr;
1077	struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&srb->arcmsr_cdb;
1078
1079	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, (srb->srb_flags & SRB_FLAG_WRITE) ? BUS_DMASYNC_POSTWRITE:BUS_DMASYNC_POSTREAD);
1080	atomic_add_int(&acb->srboutstandingcount, 1);
1081	srb->srb_state = ARCMSR_SRB_START;
1082
1083	switch (acb->adapter_type) {
1084	case ACB_ADAPTER_TYPE_A: {
1085			if(arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) {
1086				CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_queueport, cdb_phyaddr_low|ARCMSR_SRBPOST_FLAG_SGL_BSIZE);
1087			} else {
1088				CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_queueport, cdb_phyaddr_low);
1089			}
1090		}
1091		break;
1092	case ACB_ADAPTER_TYPE_B: {
1093			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
1094			int ending_index, index;
1095
1096			index = phbbmu->postq_index;
1097			ending_index = ((index+1) % ARCMSR_MAX_HBB_POSTQUEUE);
1098			phbbmu->post_qbuffer[ending_index] = 0;
1099			if(arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) {
1100				phbbmu->post_qbuffer[index] = cdb_phyaddr_low | ARCMSR_SRBPOST_FLAG_SGL_BSIZE;
1101			} else {
1102				phbbmu->post_qbuffer[index] = cdb_phyaddr_low;
1103			}
1104			index++;
1105			index %= ARCMSR_MAX_HBB_POSTQUEUE;     /*if last index number set it to 0 */
1106			phbbmu->postq_index = index;
1107			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_CDB_POSTED);
1108		}
1109		break;
1110	case ACB_ADAPTER_TYPE_C: {
1111			u_int32_t ccb_post_stamp, arc_cdb_size, cdb_phyaddr_hi32;
1112
1113			arc_cdb_size = (srb->arc_cdb_size > 0x300) ? 0x300 : srb->arc_cdb_size;
1114			ccb_post_stamp = (cdb_phyaddr_low | ((arc_cdb_size-1) >> 6) | 1);
1115			cdb_phyaddr_hi32 = acb->srb_phyaddr.B.phyadd_high;
1116			if(cdb_phyaddr_hi32)
1117			{
1118				CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_high, cdb_phyaddr_hi32);
1119				CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_low, ccb_post_stamp);
1120			}
1121			else
1122			{
1123				CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_low, ccb_post_stamp);
1124			}
1125		}
1126		break;
1127	case ACB_ADAPTER_TYPE_D: {
1128			struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
1129			u_int16_t index_stripped;
1130			u_int16_t postq_index;
1131			struct InBound_SRB *pinbound_srb;
1132
1133			ARCMSR_LOCK_ACQUIRE(&acb->postDone_lock);
1134			postq_index = phbdmu->postq_index;
1135			pinbound_srb = (struct InBound_SRB *)&phbdmu->post_qbuffer[postq_index & 0xFF];
1136			pinbound_srb->addressHigh = (u_int32_t)((srb->cdb_phyaddr >> 16) >> 16);
1137			pinbound_srb->addressLow = (u_int32_t)srb->cdb_phyaddr;
1138			pinbound_srb->length = srb->arc_cdb_size >> 2;
1139			arcmsr_cdb->Context = (u_int32_t)srb->cdb_phyaddr;
1140			if (postq_index & 0x4000) {
1141				index_stripped = postq_index & 0xFF;
1142				index_stripped += 1;
1143				index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
1144				phbdmu->postq_index = index_stripped ? (index_stripped | 0x4000) : index_stripped;
1145			} else {
1146				index_stripped = postq_index;
1147				index_stripped += 1;
1148				index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
1149				phbdmu->postq_index = index_stripped ? index_stripped : (index_stripped | 0x4000);
1150			}
1151			CHIP_REG_WRITE32(HBD_MessageUnit, 0, inboundlist_write_pointer, postq_index);
1152			ARCMSR_LOCK_RELEASE(&acb->postDone_lock);
1153		}
1154		break;
1155	case ACB_ADAPTER_TYPE_E: {
1156			u_int32_t ccb_post_stamp, arc_cdb_size;
1157
1158			arc_cdb_size = (srb->arc_cdb_size > 0x300) ? 0x300 : srb->arc_cdb_size;
1159			ccb_post_stamp = (srb->smid | ((arc_cdb_size-1) >> 6));
1160			CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_queueport_high, 0);
1161			CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_queueport_low, ccb_post_stamp);
1162		}
1163		break;
1164	case ACB_ADAPTER_TYPE_F: {
1165			u_int32_t ccb_post_stamp, arc_cdb_size;
1166
1167			if (srb->arc_cdb_size <= 0x300)
1168				arc_cdb_size = (srb->arc_cdb_size - 1) >> 6 | 1;
1169			else {
1170				arc_cdb_size = ((srb->arc_cdb_size + 0xff) >> 8) + 2;
1171				if (arc_cdb_size > 0xF)
1172					arc_cdb_size = 0xF;
1173				arc_cdb_size = (arc_cdb_size << 1) | 1;
1174			}
1175			ccb_post_stamp = (srb->smid | arc_cdb_size);
1176			CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_queueport_high, 0);
1177			CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_queueport_low, ccb_post_stamp);
1178		}
1179		break;
1180	}
1181}
1182/*
1183************************************************************************
1184************************************************************************
1185*/
1186static struct QBUFFER *arcmsr_get_iop_rqbuffer( struct AdapterControlBlock *acb)
1187{
1188	struct QBUFFER *qbuffer=NULL;
1189
1190	switch (acb->adapter_type) {
1191	case ACB_ADAPTER_TYPE_A: {
1192			struct HBA_MessageUnit *phbamu = (struct HBA_MessageUnit *)acb->pmu;
1193
1194			qbuffer = (struct QBUFFER *)&phbamu->message_rbuffer;
1195		}
1196		break;
1197	case ACB_ADAPTER_TYPE_B: {
1198			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
1199
1200			qbuffer = (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_rbuffer;
1201		}
1202		break;
1203	case ACB_ADAPTER_TYPE_C: {
1204			struct HBC_MessageUnit *phbcmu = (struct HBC_MessageUnit *)acb->pmu;
1205
1206			qbuffer = (struct QBUFFER *)&phbcmu->message_rbuffer;
1207		}
1208		break;
1209	case ACB_ADAPTER_TYPE_D: {
1210			struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
1211
1212			qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_rbuffer;
1213		}
1214		break;
1215	case ACB_ADAPTER_TYPE_E: {
1216			struct HBE_MessageUnit *phbcmu = (struct HBE_MessageUnit *)acb->pmu;
1217
1218			qbuffer = (struct QBUFFER *)&phbcmu->message_rbuffer;
1219		}
1220		break;
1221	case ACB_ADAPTER_TYPE_F:
1222		qbuffer = (struct QBUFFER *)acb->message_rbuffer;
1223		break;
1224	}
1225	return(qbuffer);
1226}
1227/*
1228************************************************************************
1229************************************************************************
1230*/
1231static struct QBUFFER *arcmsr_get_iop_wqbuffer( struct AdapterControlBlock *acb)
1232{
1233	struct QBUFFER *qbuffer = NULL;
1234
1235	switch (acb->adapter_type) {
1236	case ACB_ADAPTER_TYPE_A: {
1237			struct HBA_MessageUnit *phbamu = (struct HBA_MessageUnit *)acb->pmu;
1238
1239			qbuffer = (struct QBUFFER *)&phbamu->message_wbuffer;
1240		}
1241		break;
1242	case ACB_ADAPTER_TYPE_B: {
1243			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
1244
1245			qbuffer = (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_wbuffer;
1246		}
1247		break;
1248	case ACB_ADAPTER_TYPE_C: {
1249			struct HBC_MessageUnit *phbcmu = (struct HBC_MessageUnit *)acb->pmu;
1250
1251			qbuffer = (struct QBUFFER *)&phbcmu->message_wbuffer;
1252		}
1253		break;
1254	case ACB_ADAPTER_TYPE_D: {
1255			struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
1256
1257			qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_wbuffer;
1258		}
1259		break;
1260	case ACB_ADAPTER_TYPE_E: {
1261			struct HBE_MessageUnit *phbcmu = (struct HBE_MessageUnit *)acb->pmu;
1262
1263			qbuffer = (struct QBUFFER *)&phbcmu->message_wbuffer;
1264		}
1265		break;
1266	case ACB_ADAPTER_TYPE_F:
1267		qbuffer = (struct QBUFFER *)acb->message_wbuffer;
1268		break;
1269	}
1270	return(qbuffer);
1271}
1272/*
1273**************************************************************************
1274**************************************************************************
1275*/
1276static void arcmsr_iop_message_read(struct AdapterControlBlock *acb)
1277{
1278	switch (acb->adapter_type) {
1279	case ACB_ADAPTER_TYPE_A: {
1280			/* let IOP know data has been read */
1281			CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
1282		}
1283		break;
1284	case ACB_ADAPTER_TYPE_B: {
1285			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
1286			/* let IOP know data has been read */
1287			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_READ_OK);
1288		}
1289		break;
1290	case ACB_ADAPTER_TYPE_C: {
1291			/* let IOP know data has been read */
1292			CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK);
1293		}
1294		break;
1295	case ACB_ADAPTER_TYPE_D: {
1296			/* let IOP know data has been read */
1297			CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_OUT_READ);
1298		}
1299		break;
1300	case ACB_ADAPTER_TYPE_E:
1301	case ACB_ADAPTER_TYPE_F: {
1302			/* let IOP know data has been read */
1303			acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_READ_OK;
1304			CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
1305		}
1306		break;
1307	}
1308}
1309/*
1310**************************************************************************
1311**************************************************************************
1312*/
1313static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb)
1314{
1315	switch (acb->adapter_type) {
1316	case ACB_ADAPTER_TYPE_A: {
1317			/*
1318			** push inbound doorbell tell iop, driver data write ok
1319			** and wait reply on next hwinterrupt for next Qbuffer post
1320			*/
1321			CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK);
1322		}
1323		break;
1324	case ACB_ADAPTER_TYPE_B: {
1325			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
1326			/*
1327			** push inbound doorbell tell iop, driver data write ok
1328			** and wait reply on next hwinterrupt for next Qbuffer post
1329			*/
1330			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_WRITE_OK);
1331		}
1332		break;
1333	case ACB_ADAPTER_TYPE_C: {
1334			/*
1335			** push inbound doorbell tell iop, driver data write ok
1336			** and wait reply on next hwinterrupt for next Qbuffer post
1337			*/
1338			CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_DATA_WRITE_OK);
1339		}
1340		break;
1341	case ACB_ADAPTER_TYPE_D: {
1342			/*
1343			** push inbound doorbell tell iop, driver data write ok
1344			** and wait reply on next hwinterrupt for next Qbuffer post
1345			*/
1346			CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_IN_READY);
1347		}
1348		break;
1349	case ACB_ADAPTER_TYPE_E:
1350	case ACB_ADAPTER_TYPE_F: {
1351			/*
1352			** push inbound doorbell tell iop, driver data write ok
1353			** and wait reply on next hwinterrupt for next Qbuffer post
1354			*/
1355			acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_WRITE_OK;
1356			CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
1357		}
1358		break;
1359	}
1360}
1361/*
1362************************************************************************
1363************************************************************************
1364*/
1365static void arcmsr_stop_hba_bgrb(struct AdapterControlBlock *acb)
1366{
1367	acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
1368	CHIP_REG_WRITE32(HBA_MessageUnit,
1369		0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
1370	if(!arcmsr_hba_wait_msgint_ready(acb)) {
1371		printf("arcmsr%d: wait 'stop adapter background rebuild' timeout \n"
1372			, acb->pci_unit);
1373	}
1374}
1375/*
1376************************************************************************
1377************************************************************************
1378*/
1379static void arcmsr_stop_hbb_bgrb(struct AdapterControlBlock *acb)
1380{
1381	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
1382	acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
1383	WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_STOP_BGRB);
1384	if(!arcmsr_hbb_wait_msgint_ready(acb)) {
1385		printf( "arcmsr%d: wait 'stop adapter background rebuild' timeout \n"
1386			, acb->pci_unit);
1387	}
1388}
1389/*
1390************************************************************************
1391************************************************************************
1392*/
1393static void arcmsr_stop_hbc_bgrb(struct AdapterControlBlock *acb)
1394{
1395	acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
1396	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
1397	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell,ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
1398	if(!arcmsr_hbc_wait_msgint_ready(acb)) {
1399		printf("arcmsr%d: wait 'stop adapter background rebuild' timeout \n", acb->pci_unit);
1400	}
1401}
1402/*
1403************************************************************************
1404************************************************************************
1405*/
1406static void arcmsr_stop_hbd_bgrb(struct AdapterControlBlock *acb)
1407{
1408	acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
1409	CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
1410	if(!arcmsr_hbd_wait_msgint_ready(acb)) {
1411		printf("arcmsr%d: wait 'stop adapter background rebuild' timeout \n", acb->pci_unit);
1412	}
1413}
1414/*
1415************************************************************************
1416************************************************************************
1417*/
1418static void arcmsr_stop_hbe_bgrb(struct AdapterControlBlock *acb)
1419{
1420	acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
1421	CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
1422	acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
1423	CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
1424	if(!arcmsr_hbe_wait_msgint_ready(acb)) {
1425		printf("arcmsr%d: wait 'stop adapter background rebuild' timeout \n", acb->pci_unit);
1426	}
1427}
1428/*
1429************************************************************************
1430************************************************************************
1431*/
1432static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb)
1433{
1434	switch (acb->adapter_type) {
1435	case ACB_ADAPTER_TYPE_A: {
1436			arcmsr_stop_hba_bgrb(acb);
1437		}
1438		break;
1439	case ACB_ADAPTER_TYPE_B: {
1440			arcmsr_stop_hbb_bgrb(acb);
1441		}
1442		break;
1443	case ACB_ADAPTER_TYPE_C: {
1444			arcmsr_stop_hbc_bgrb(acb);
1445		}
1446		break;
1447	case ACB_ADAPTER_TYPE_D: {
1448			arcmsr_stop_hbd_bgrb(acb);
1449		}
1450		break;
1451	case ACB_ADAPTER_TYPE_E:
1452	case ACB_ADAPTER_TYPE_F: {
1453			arcmsr_stop_hbe_bgrb(acb);
1454		}
1455		break;
1456	}
1457}
1458/*
1459************************************************************************
1460************************************************************************
1461*/
1462static void arcmsr_poll(struct cam_sim *psim)
1463{
1464	struct AdapterControlBlock *acb;
1465	int	mutex;
1466
1467	acb = (struct AdapterControlBlock *)cam_sim_softc(psim);
1468	mutex = mtx_owned(&acb->isr_lock);
1469	if( mutex == 0 )
1470		ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
1471	arcmsr_interrupt(acb);
1472	if( mutex == 0 )
1473		ARCMSR_LOCK_RELEASE(&acb->isr_lock);
1474}
1475/*
1476**************************************************************************
1477**************************************************************************
1478*/
1479static u_int32_t arcmsr_Read_iop_rqbuffer_data_D(struct AdapterControlBlock *acb,
1480	struct QBUFFER *prbuffer) {
1481	u_int8_t *pQbuffer;
1482	u_int8_t *buf1 = NULL;
1483	u_int32_t *iop_data, *buf2 = NULL;
1484	u_int32_t iop_len, data_len;
1485
1486	iop_data = (u_int32_t *)prbuffer->data;
1487	iop_len = (u_int32_t)prbuffer->data_len;
1488	if ( iop_len > 0 )
1489	{
1490		buf1 = malloc(128, M_DEVBUF, M_NOWAIT | M_ZERO);
1491		buf2 = (u_int32_t *)buf1;
1492		if( buf1 == NULL)
1493			return (0);
1494		data_len = iop_len;
1495		while(data_len >= 4)
1496		{
1497			*buf2++ = *iop_data++;
1498			data_len -= 4;
1499		}
1500		if(data_len)
1501			*buf2 = *iop_data;
1502		buf2 = (u_int32_t *)buf1;
1503	}
1504	while (iop_len > 0) {
1505		pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex];
1506		*pQbuffer = *buf1;
1507		acb->rqbuf_lastindex++;
1508		/* if last, index number set it to 0 */
1509		acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
1510		buf1++;
1511		iop_len--;
1512	}
1513	if(buf2)
1514		free( (u_int8_t *)buf2, M_DEVBUF);
1515	/* let IOP know data has been read */
1516	arcmsr_iop_message_read(acb);
1517	return (1);
1518}
1519/*
1520**************************************************************************
1521**************************************************************************
1522*/
1523static u_int32_t arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb,
1524	struct QBUFFER *prbuffer) {
1525	u_int8_t *pQbuffer;
1526	u_int8_t *iop_data;
1527	u_int32_t iop_len;
1528
1529	if(acb->adapter_type >= ACB_ADAPTER_TYPE_B) {
1530		return(arcmsr_Read_iop_rqbuffer_data_D(acb, prbuffer));
1531	}
1532	iop_data = (u_int8_t *)prbuffer->data;
1533	iop_len = (u_int32_t)prbuffer->data_len;
1534	while (iop_len > 0) {
1535		pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex];
1536		*pQbuffer = *iop_data;
1537		acb->rqbuf_lastindex++;
1538		/* if last, index number set it to 0 */
1539		acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
1540		iop_data++;
1541		iop_len--;
1542	}
1543	/* let IOP know data has been read */
1544	arcmsr_iop_message_read(acb);
1545	return (1);
1546}
1547/*
1548**************************************************************************
1549**************************************************************************
1550*/
1551static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb)
1552{
1553	struct QBUFFER *prbuffer;
1554	int my_empty_len;
1555
1556	/*check this iop data if overflow my rqbuffer*/
1557	ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
1558	prbuffer = arcmsr_get_iop_rqbuffer(acb);
1559	if (acb->rqbuf_lastindex >= acb->rqbuf_firstindex)
1560		my_empty_len = (ARCMSR_MAX_QBUFFER - 1) - (acb->rqbuf_lastindex - acb->rqbuf_firstindex);
1561	else
1562		my_empty_len = acb->rqbuf_firstindex - acb->rqbuf_lastindex - 1;
1563	if(my_empty_len >= prbuffer->data_len) {
1564		if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
1565			acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
1566	} else {
1567		acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
1568	}
1569	ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
1570}
1571/*
1572**********************************************************************
1573**********************************************************************
1574*/
1575static void arcmsr_Write_data_2iop_wqbuffer_D(struct AdapterControlBlock *acb)
1576{
1577	u_int8_t *pQbuffer;
1578	struct QBUFFER *pwbuffer;
1579	u_int8_t *buf1 = NULL;
1580	u_int32_t *iop_data, *buf2 = NULL;
1581	u_int32_t allxfer_len = 0, data_len;
1582
1583	if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) {
1584		buf1 = malloc(128, M_DEVBUF, M_NOWAIT | M_ZERO);
1585		buf2 = (u_int32_t *)buf1;
1586		if( buf1 == NULL)
1587			return;
1588
1589		acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ);
1590		pwbuffer = arcmsr_get_iop_wqbuffer(acb);
1591		iop_data = (u_int32_t *)pwbuffer->data;
1592		while((acb->wqbuf_firstindex != acb->wqbuf_lastindex)
1593			&& (allxfer_len < 124)) {
1594			pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex];
1595			*buf1 = *pQbuffer;
1596			acb->wqbuf_firstindex++;
1597			acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
1598			buf1++;
1599			allxfer_len++;
1600		}
1601		pwbuffer->data_len = allxfer_len;
1602		data_len = allxfer_len;
1603		buf1 = (u_int8_t *)buf2;
1604		while(data_len >= 4)
1605		{
1606			*iop_data++ = *buf2++;
1607			data_len -= 4;
1608		}
1609		if(data_len)
1610			*iop_data = *buf2;
1611		free( buf1, M_DEVBUF);
1612		arcmsr_iop_message_wrote(acb);
1613	}
1614}
1615/*
1616**********************************************************************
1617**********************************************************************
1618*/
1619static void arcmsr_Write_data_2iop_wqbuffer(struct AdapterControlBlock *acb)
1620{
1621	u_int8_t *pQbuffer;
1622	struct QBUFFER *pwbuffer;
1623	u_int8_t *iop_data;
1624	int32_t allxfer_len=0;
1625
1626	if(acb->adapter_type >= ACB_ADAPTER_TYPE_B) {
1627		arcmsr_Write_data_2iop_wqbuffer_D(acb);
1628		return;
1629	}
1630	if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) {
1631		acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ);
1632		pwbuffer = arcmsr_get_iop_wqbuffer(acb);
1633		iop_data = (u_int8_t *)pwbuffer->data;
1634		while((acb->wqbuf_firstindex != acb->wqbuf_lastindex)
1635			&& (allxfer_len < 124)) {
1636			pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex];
1637			*iop_data = *pQbuffer;
1638			acb->wqbuf_firstindex++;
1639			acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
1640			iop_data++;
1641			allxfer_len++;
1642		}
1643		pwbuffer->data_len = allxfer_len;
1644		arcmsr_iop_message_wrote(acb);
1645	}
1646}
1647/*
1648**************************************************************************
1649**************************************************************************
1650*/
1651static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb)
1652{
1653	ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
1654	acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READ;
1655	/*
1656	*****************************************************************
1657	**   check if there are any mail packages from user space program
1658	**   in my post bag, now is the time to send them into Areca's firmware
1659	*****************************************************************
1660	*/
1661	if(acb->wqbuf_firstindex != acb->wqbuf_lastindex) {
1662		arcmsr_Write_data_2iop_wqbuffer(acb);
1663	}
1664	if(acb->wqbuf_firstindex == acb->wqbuf_lastindex) {
1665		acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED;
1666	}
1667	ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
1668}
1669/*
1670**************************************************************************
1671**************************************************************************
1672*/
1673static void arcmsr_rescanLun_cb(struct cam_periph *periph, union ccb *ccb)
1674{
1675/*
1676	if (ccb->ccb_h.status != CAM_REQ_CMP)
1677		printf("arcmsr_rescanLun_cb: Rescan Target=%x, lun=%x,"
1678			"failure status=%x\n", ccb->ccb_h.target_id,
1679			ccb->ccb_h.target_lun, ccb->ccb_h.status);
1680	else
1681		printf("arcmsr_rescanLun_cb: Rescan lun successfully!\n");
1682*/
1683	xpt_free_path(ccb->ccb_h.path);
1684	xpt_free_ccb(ccb);
1685}
1686
1687static void	arcmsr_rescan_lun(struct AdapterControlBlock *acb, int target, int lun)
1688{
1689	struct cam_path     *path;
1690	union ccb           *ccb;
1691
1692	if ((ccb = (union ccb *)xpt_alloc_ccb_nowait()) == NULL)
1693		return;
1694	if (xpt_create_path(&path, NULL, cam_sim_path(acb->psim), target, lun) != CAM_REQ_CMP)
1695	{
1696		xpt_free_ccb(ccb);
1697		return;
1698	}
1699/*	printf("arcmsr_rescan_lun: Rescan Target=%x, Lun=%x\n", target, lun); */
1700	xpt_setup_ccb(&ccb->ccb_h, path, 5);
1701	ccb->ccb_h.func_code = XPT_SCAN_LUN;
1702	ccb->ccb_h.cbfcnp = arcmsr_rescanLun_cb;
1703	ccb->crcn.flags = CAM_FLAG_NONE;
1704	xpt_action(ccb);
1705}
1706
1707static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, int lun)
1708{
1709	struct CommandControlBlock *srb;
1710	u_int32_t intmask_org;
1711	int i;
1712
1713	/* disable all outbound interrupts */
1714	intmask_org = arcmsr_disable_allintr(acb);
1715	for (i = 0; i < ARCMSR_MAX_FREESRB_NUM; i++)
1716	{
1717		srb = acb->psrb_pool[i];
1718		if (srb->srb_state == ARCMSR_SRB_START)
1719		{
1720			if((target == srb->pccb->ccb_h.target_id) && (lun == srb->pccb->ccb_h.target_lun))
1721			{
1722				srb->srb_state = ARCMSR_SRB_ABORTED;
1723				srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
1724				arcmsr_srb_complete(srb, 1);
1725				printf("arcmsr%d: abort scsi id %d lun %d srb=%p \n", acb->pci_unit, target, lun, srb);
1726			}
1727		}
1728	}
1729	/* enable outbound Post Queue, outbound doorbell Interrupt */
1730	arcmsr_enable_allintr(acb, intmask_org);
1731}
1732/*
1733**************************************************************************
1734**************************************************************************
1735*/
1736static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
1737	u_int32_t	devicemap;
1738	u_int32_t	target, lun;
1739	u_int32_t	deviceMapCurrent[4]={0};
1740	u_int8_t	*pDevMap;
1741
1742	switch (acb->adapter_type) {
1743	case ACB_ADAPTER_TYPE_A:
1744		devicemap = offsetof(struct HBA_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
1745		for (target = 0; target < 4; target++)
1746		{
1747			deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
1748			devicemap += 4;
1749		}
1750		break;
1751
1752	case ACB_ADAPTER_TYPE_B:
1753		devicemap = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
1754		for (target = 0; target < 4; target++)
1755		{
1756			deviceMapCurrent[target]=bus_space_read_4(acb->btag[1], acb->bhandle[1], devicemap);
1757			devicemap += 4;
1758		}
1759		break;
1760
1761	case ACB_ADAPTER_TYPE_C:
1762		devicemap = offsetof(struct HBC_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
1763		for (target = 0; target < 4; target++)
1764		{
1765			deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
1766			devicemap += 4;
1767		}
1768		break;
1769	case ACB_ADAPTER_TYPE_D:
1770		devicemap = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
1771		for (target = 0; target < 4; target++)
1772		{
1773			deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
1774			devicemap += 4;
1775		}
1776		break;
1777	case ACB_ADAPTER_TYPE_E:
1778		devicemap = offsetof(struct HBE_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
1779		for (target = 0; target < 4; target++)
1780		{
1781			deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
1782			devicemap += 4;
1783		}
1784		break;
1785	case ACB_ADAPTER_TYPE_F:
1786		devicemap = ARCMSR_FW_DEVMAP_OFFSET;
1787		for (target = 0; target < 4; target++)
1788		{
1789			deviceMapCurrent[target] = acb->msgcode_rwbuffer[devicemap];
1790			devicemap += 1;
1791		}
1792		break;
1793	}
1794
1795	if(acb->acb_flags & ACB_F_BUS_HANG_ON)
1796	{
1797		acb->acb_flags &= ~ACB_F_BUS_HANG_ON;
1798	}
1799	/*
1800	** adapter posted CONFIG message
1801	** copy the new map, note if there are differences with the current map
1802	*/
1803	pDevMap = (u_int8_t *)&deviceMapCurrent[0];
1804	for (target = 0; target < ARCMSR_MAX_TARGETID - 1; target++)
1805	{
1806		if (*pDevMap != acb->device_map[target])
1807		{
1808			u_int8_t difference, bit_check;
1809
1810			difference = *pDevMap ^ acb->device_map[target];
1811			for(lun=0; lun < ARCMSR_MAX_TARGETLUN; lun++)
1812			{
1813				bit_check = (1 << lun);		/*check bit from 0....31*/
1814				if(difference & bit_check)
1815				{
1816					if(acb->device_map[target] & bit_check)
1817					{/* unit departed */
1818						if (target != 0x0f)
1819							printf("arcmsr_dr_handle: Target=0x%x, lun=%x, GONE!!!\n",target,lun);
1820						arcmsr_abort_dr_ccbs(acb, target, lun);
1821						arcmsr_rescan_lun(acb, target, lun);
1822						acb->devstate[target][lun] = ARECA_RAID_GONE;
1823					}
1824					else
1825					{/* unit arrived */
1826						printf("arcmsr_dr_handle: Target=0x%x, lun=%x, Plug-IN!!!\n",target,lun);
1827						arcmsr_rescan_lun(acb, target, lun);
1828						acb->devstate[target][lun] = ARECA_RAID_GOOD;
1829					}
1830				}
1831			}
1832/*			printf("arcmsr_dr_handle: acb->device_map[%x]=0x%x, deviceMapCurrent[%x]=%x\n",target,acb->device_map[target],target,*pDevMap); */
1833			acb->device_map[target] = *pDevMap;
1834		}
1835		pDevMap++;
1836	}
1837}
1838/*
1839**************************************************************************
1840**************************************************************************
1841*/
1842static void arcmsr_hba_message_isr(struct AdapterControlBlock *acb) {
1843	u_int32_t outbound_message;
1844
1845	CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, ARCMSR_MU_OUTBOUND_MESSAGE0_INT);
1846	outbound_message = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[0]);
1847	if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
1848		arcmsr_dr_handle( acb );
1849}
1850/*
1851**************************************************************************
1852**************************************************************************
1853*/
1854static void arcmsr_hbb_message_isr(struct AdapterControlBlock *acb) {
1855	u_int32_t outbound_message;
1856	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
1857
1858	/* clear interrupts */
1859	WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);
1860	outbound_message = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[0]);
1861	if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
1862		arcmsr_dr_handle( acb );
1863}
1864/*
1865**************************************************************************
1866**************************************************************************
1867*/
1868static void arcmsr_hbc_message_isr(struct AdapterControlBlock *acb) {
1869	u_int32_t outbound_message;
1870
1871	CHIP_REG_WRITE32(HBC_MessageUnit, 0, outbound_doorbell_clear, ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR);
1872	outbound_message = CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[0]);
1873	if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
1874		arcmsr_dr_handle( acb );
1875}
1876/*
1877**************************************************************************
1878**************************************************************************
1879*/
1880static void arcmsr_hbd_message_isr(struct AdapterControlBlock *acb) {
1881	u_int32_t outbound_message;
1882
1883	CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR);
1884	outbound_message = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[0]);
1885	if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
1886		arcmsr_dr_handle( acb );
1887}
1888/*
1889**************************************************************************
1890**************************************************************************
1891*/
1892static void arcmsr_hbe_message_isr(struct AdapterControlBlock *acb) {
1893	u_int32_t outbound_message;
1894
1895	CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0);
1896	if (acb->adapter_type == ACB_ADAPTER_TYPE_E)
1897		outbound_message = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[0]);
1898	else
1899		outbound_message = acb->msgcode_rwbuffer[0];
1900	if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
1901		arcmsr_dr_handle( acb );
1902}
1903/*
1904**************************************************************************
1905**************************************************************************
1906*/
1907static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb)
1908{
1909	u_int32_t doorbell_status;
1910
1911	/*
1912	*******************************************************************
1913	**  Maybe here we need to check wrqbuffer_lock is lock or not
1914	**  DOORBELL: din! don!
1915	**  check if there are any mail need to pack from firmware
1916	*******************************************************************
1917	*/
1918	doorbell_status = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_doorbell);
1919	CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_doorbell, doorbell_status); /* clear doorbell interrupt */
1920	if(doorbell_status & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) {
1921		arcmsr_iop2drv_data_wrote_handle(acb);
1922	}
1923	if(doorbell_status & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) {
1924		arcmsr_iop2drv_data_read_handle(acb);
1925	}
1926}
1927/*
1928**************************************************************************
1929**************************************************************************
1930*/
1931static void arcmsr_hbc_doorbell_isr(struct AdapterControlBlock *acb)
1932{
1933	u_int32_t doorbell_status;
1934
1935	/*
1936	*******************************************************************
1937	**  Maybe here we need to check wrqbuffer_lock is lock or not
1938	**  DOORBELL: din! don!
1939	**  check if there are any mail need to pack from firmware
1940	*******************************************************************
1941	*/
1942	doorbell_status = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell);
1943	CHIP_REG_WRITE32(HBC_MessageUnit, 0, outbound_doorbell_clear, doorbell_status); /* clear doorbell interrupt */
1944	if(doorbell_status & ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK) {
1945		arcmsr_iop2drv_data_wrote_handle(acb);
1946	}
1947	if(doorbell_status & ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK) {
1948		arcmsr_iop2drv_data_read_handle(acb);
1949	}
1950	if(doorbell_status & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
1951		arcmsr_hbc_message_isr(acb);    /* messenger of "driver to iop commands" */
1952	}
1953}
1954/*
1955**************************************************************************
1956**************************************************************************
1957*/
1958static void arcmsr_hbd_doorbell_isr(struct AdapterControlBlock *acb)
1959{
1960	u_int32_t doorbell_status;
1961
1962	/*
1963	*******************************************************************
1964	**  Maybe here we need to check wrqbuffer_lock is lock or not
1965	**  DOORBELL: din! don!
1966	**  check if there are any mail need to pack from firmware
1967	*******************************************************************
1968	*/
1969	doorbell_status = CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_F0_DOORBELL_CAUSE;
1970	if(doorbell_status)
1971		CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, doorbell_status); /* clear doorbell interrupt */
1972	while( doorbell_status & ARCMSR_HBDMU_F0_DOORBELL_CAUSE ) {
1973		if(doorbell_status & ARCMSR_HBDMU_IOP2DRV_DATA_WRITE_OK) {
1974			arcmsr_iop2drv_data_wrote_handle(acb);
1975		}
1976		if(doorbell_status & ARCMSR_HBDMU_IOP2DRV_DATA_READ_OK) {
1977			arcmsr_iop2drv_data_read_handle(acb);
1978		}
1979		if(doorbell_status & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE) {
1980			arcmsr_hbd_message_isr(acb);    /* messenger of "driver to iop commands" */
1981		}
1982		doorbell_status = CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_F0_DOORBELL_CAUSE;
1983		if(doorbell_status)
1984			CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, doorbell_status); /* clear doorbell interrupt */
1985	}
1986}
1987/*
1988**************************************************************************
1989**************************************************************************
1990*/
1991static void arcmsr_hbe_doorbell_isr(struct AdapterControlBlock *acb)
1992{
1993	u_int32_t doorbell_status, in_doorbell;
1994
1995	/*
1996	*******************************************************************
1997	**  Maybe here we need to check wrqbuffer_lock is lock or not
1998	**  DOORBELL: din! don!
1999	**  check if there are any mail need to pack from firmware
2000	*******************************************************************
2001	*/
2002	in_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell);
2003	CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0); /* clear doorbell interrupt */
2004	doorbell_status = in_doorbell ^ acb->in_doorbell;
2005	if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_DATA_WRITE_OK) {
2006		arcmsr_iop2drv_data_wrote_handle(acb);
2007	}
2008	if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_DATA_READ_OK) {
2009		arcmsr_iop2drv_data_read_handle(acb);
2010	}
2011	if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_MESSAGE_CMD_DONE) {
2012		arcmsr_hbe_message_isr(acb);    /* messenger of "driver to iop commands" */
2013	}
2014	acb->in_doorbell = in_doorbell;
2015}
2016/*
2017**************************************************************************
2018**************************************************************************
2019*/
2020static void arcmsr_hbf_doorbell_isr(struct AdapterControlBlock *acb)
2021{
2022	u_int32_t doorbell_status, in_doorbell;
2023
2024	/*
2025	*******************************************************************
2026	**  Maybe here we need to check wrqbuffer_lock is lock or not
2027	**  DOORBELL: din! don!
2028	**  check if there are any mail need to pack from firmware
2029	*******************************************************************
2030	*/
2031	while(1) {
2032		in_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell);
2033		if ((in_doorbell != 0) && (in_doorbell != 0xFFFFFFFF))
2034			break;
2035	}
2036	CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0); /* clear doorbell interrupt */
2037	doorbell_status = in_doorbell ^ acb->in_doorbell;
2038	if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_DATA_WRITE_OK) {
2039		arcmsr_iop2drv_data_wrote_handle(acb);
2040	}
2041	if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_DATA_READ_OK) {
2042		arcmsr_iop2drv_data_read_handle(acb);
2043	}
2044	if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_MESSAGE_CMD_DONE) {
2045		arcmsr_hbe_message_isr(acb);    /* messenger of "driver to iop commands" */
2046	}
2047	acb->in_doorbell = in_doorbell;
2048}
2049/*
2050**************************************************************************
2051**************************************************************************
2052*/
2053static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
2054{
2055	u_int32_t flag_srb;
2056	u_int16_t error;
2057
2058	/*
2059	*****************************************************************************
2060	**               areca cdb command done
2061	*****************************************************************************
2062	*/
2063	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap,
2064		BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
2065	while((flag_srb = CHIP_REG_READ32(HBA_MessageUnit,
2066		0, outbound_queueport)) != 0xFFFFFFFF) {
2067		/* check if command done with no error*/
2068		error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0) ? TRUE : FALSE;
2069		arcmsr_drain_donequeue(acb, flag_srb, error);
2070	}	/*drain reply FIFO*/
2071}
2072/*
2073**************************************************************************
2074**************************************************************************
2075*/
2076static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb)
2077{
2078	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
2079	u_int32_t flag_srb;
2080	int index;
2081	u_int16_t error;
2082
2083	/*
2084	*****************************************************************************
2085	**               areca cdb command done
2086	*****************************************************************************
2087	*/
2088	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap,
2089		BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
2090	index = phbbmu->doneq_index;
2091	while((flag_srb = phbbmu->done_qbuffer[index]) != 0) {
2092		phbbmu->done_qbuffer[index] = 0;
2093		index++;
2094		index %= ARCMSR_MAX_HBB_POSTQUEUE;     /*if last index number set it to 0 */
2095		phbbmu->doneq_index = index;
2096		/* check if command done with no error*/
2097		error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
2098		arcmsr_drain_donequeue(acb, flag_srb, error);
2099	}	/*drain reply FIFO*/
2100}
2101/*
2102**************************************************************************
2103**************************************************************************
2104*/
2105static void arcmsr_hbc_postqueue_isr(struct AdapterControlBlock *acb)
2106{
2107	u_int32_t flag_srb,throttling = 0;
2108	u_int16_t error;
2109
2110	/*
2111	*****************************************************************************
2112	**               areca cdb command done
2113	*****************************************************************************
2114	*/
2115	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2116	do {
2117		flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
2118		if (flag_srb == 0xFFFFFFFF)
2119			break;
2120		/* check if command done with no error*/
2121		error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE;
2122		arcmsr_drain_donequeue(acb, flag_srb, error);
2123		throttling++;
2124		if(throttling == ARCMSR_HBC_ISR_THROTTLING_LEVEL) {
2125			CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING);
2126			throttling = 0;
2127		}
2128	} while(CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR);
2129}
2130/*
2131**********************************************************************
2132**
2133**********************************************************************
2134*/
2135static uint16_t arcmsr_get_doneq_index(struct HBD_MessageUnit0 *phbdmu)
2136{
2137	uint16_t doneq_index, index_stripped;
2138
2139	doneq_index = phbdmu->doneq_index;
2140	if (doneq_index & 0x4000) {
2141		index_stripped = doneq_index & 0xFF;
2142		index_stripped += 1;
2143		index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
2144		phbdmu->doneq_index = index_stripped ?
2145		    (index_stripped | 0x4000) : index_stripped;
2146	} else {
2147		index_stripped = doneq_index;
2148		index_stripped += 1;
2149		index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
2150		phbdmu->doneq_index = index_stripped ?
2151		    index_stripped : (index_stripped | 0x4000);
2152	}
2153	return (phbdmu->doneq_index);
2154}
2155/*
2156**************************************************************************
2157**************************************************************************
2158*/
2159static void arcmsr_hbd_postqueue_isr(struct AdapterControlBlock *acb)
2160{
2161	struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
2162	u_int32_t outbound_write_pointer;
2163	u_int32_t addressLow;
2164	uint16_t doneq_index;
2165	u_int16_t error;
2166	/*
2167	*****************************************************************************
2168	**               areca cdb command done
2169	*****************************************************************************
2170	*/
2171	if((CHIP_REG_READ32(HBD_MessageUnit, 0, outboundlist_interrupt_cause) &
2172		ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT) == 0)
2173		return;
2174	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap,
2175		BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2176	outbound_write_pointer = phbdmu->done_qbuffer[0].addressLow;
2177	doneq_index = phbdmu->doneq_index;
2178	while ((doneq_index & 0xFF) != (outbound_write_pointer & 0xFF)) {
2179		doneq_index = arcmsr_get_doneq_index(phbdmu);
2180		addressLow = phbdmu->done_qbuffer[(doneq_index & 0xFF)+1].addressLow;
2181		error = (addressLow & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
2182		arcmsr_drain_donequeue(acb, addressLow, error); /*Check if command done with no error */
2183		CHIP_REG_WRITE32(HBD_MessageUnit, 0, outboundlist_read_pointer, doneq_index);
2184		outbound_write_pointer = phbdmu->done_qbuffer[0].addressLow;
2185	}
2186	CHIP_REG_WRITE32(HBD_MessageUnit, 0, outboundlist_interrupt_cause, ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT_CLEAR);
2187	CHIP_REG_READ32(HBD_MessageUnit, 0, outboundlist_interrupt_cause); /*Dummy ioread32 to force pci flush */
2188}
2189/*
2190**************************************************************************
2191**************************************************************************
2192*/
2193static void arcmsr_hbe_postqueue_isr(struct AdapterControlBlock *acb)
2194{
2195	u_int16_t error;
2196	uint32_t doneq_index;
2197	uint16_t cmdSMID;
2198
2199	/*
2200	*****************************************************************************
2201	**               areca cdb command done
2202	*****************************************************************************
2203	*/
2204	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2205	doneq_index = acb->doneq_index;
2206	while ((CHIP_REG_READ32(HBE_MessageUnit, 0, reply_post_producer_index) & 0xFFFF) != doneq_index) {
2207		cmdSMID = acb->pCompletionQ[doneq_index].cmdSMID;
2208		error = (acb->pCompletionQ[doneq_index].cmdFlag & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
2209		arcmsr_drain_donequeue(acb, (u_int32_t)cmdSMID, error);
2210		doneq_index++;
2211		if (doneq_index >= acb->completionQ_entry)
2212			doneq_index = 0;
2213	}
2214	acb->doneq_index = doneq_index;
2215	CHIP_REG_WRITE32(HBE_MessageUnit, 0, reply_post_consumer_index, doneq_index);
2216}
2217
2218static void arcmsr_hbf_postqueue_isr(struct AdapterControlBlock *acb)
2219{
2220	uint16_t error;
2221	uint32_t doneq_index;
2222	uint16_t cmdSMID;
2223
2224	/*
2225	*****************************************************************************
2226	**               areca cdb command done
2227	*****************************************************************************
2228	*/
2229	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2230	doneq_index = acb->doneq_index;
2231	while (1) {
2232		cmdSMID = acb->pCompletionQ[doneq_index].cmdSMID;
2233		if (cmdSMID == 0xffff)
2234			break;
2235		error = (acb->pCompletionQ[doneq_index].cmdFlag & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
2236		arcmsr_drain_donequeue(acb, (u_int32_t)cmdSMID, error);
2237		acb->pCompletionQ[doneq_index].cmdSMID = 0xffff;
2238		doneq_index++;
2239		if (doneq_index >= acb->completionQ_entry)
2240			doneq_index = 0;
2241	}
2242	acb->doneq_index = doneq_index;
2243	CHIP_REG_WRITE32(HBF_MessageUnit, 0, reply_post_consumer_index, doneq_index);
2244}
2245
2246/*
2247**********************************************************************
2248**********************************************************************
2249*/
2250static void arcmsr_handle_hba_isr( struct AdapterControlBlock *acb)
2251{
2252	u_int32_t outbound_intStatus;
2253	/*
2254	*********************************************
2255	**   check outbound intstatus
2256	*********************************************
2257	*/
2258	outbound_intStatus = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable;
2259	if(!outbound_intStatus) {
2260		/*it must be share irq*/
2261		return;
2262	}
2263	CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intStatus); /*clear interrupt*/
2264	/* MU doorbell interrupts*/
2265	if(outbound_intStatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT) {
2266		arcmsr_hba_doorbell_isr(acb);
2267	}
2268	/* MU post queue interrupts*/
2269	if(outbound_intStatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT) {
2270		arcmsr_hba_postqueue_isr(acb);
2271	}
2272	if(outbound_intStatus & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
2273		arcmsr_hba_message_isr(acb);
2274	}
2275}
2276/*
2277**********************************************************************
2278**********************************************************************
2279*/
2280static void arcmsr_handle_hbb_isr( struct AdapterControlBlock *acb)
2281{
2282	u_int32_t outbound_doorbell;
2283	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
2284	/*
2285	*********************************************
2286	**   check outbound intstatus
2287	*********************************************
2288	*/
2289	outbound_doorbell = READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell) & acb->outbound_int_enable;
2290	if(!outbound_doorbell) {
2291		/*it must be share irq*/
2292		return;
2293	}
2294	WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ~outbound_doorbell); /* clear doorbell interrupt */
2295	READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell);
2296	WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
2297	/* MU ioctl transfer doorbell interrupts*/
2298	if(outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK) {
2299		arcmsr_iop2drv_data_wrote_handle(acb);
2300	}
2301	if(outbound_doorbell & ARCMSR_IOP2DRV_DATA_READ_OK) {
2302		arcmsr_iop2drv_data_read_handle(acb);
2303	}
2304	/* MU post queue interrupts*/
2305	if(outbound_doorbell & ARCMSR_IOP2DRV_CDB_DONE) {
2306		arcmsr_hbb_postqueue_isr(acb);
2307	}
2308	if(outbound_doorbell & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
2309		arcmsr_hbb_message_isr(acb);
2310	}
2311}
2312/*
2313**********************************************************************
2314**********************************************************************
2315*/
2316static void arcmsr_handle_hbc_isr( struct AdapterControlBlock *acb)
2317{
2318	u_int32_t host_interrupt_status;
2319	/*
2320	*********************************************
2321	**   check outbound intstatus
2322	*********************************************
2323	*/
2324	host_interrupt_status = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) &
2325		(ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR |
2326		ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR);
2327	if(!host_interrupt_status) {
2328		/*it must be share irq*/
2329		return;
2330	}
2331	do {
2332		/* MU doorbell interrupts*/
2333		if(host_interrupt_status & ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR) {
2334			arcmsr_hbc_doorbell_isr(acb);
2335		}
2336		/* MU post queue interrupts*/
2337		if(host_interrupt_status & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) {
2338			arcmsr_hbc_postqueue_isr(acb);
2339		}
2340		host_interrupt_status = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status);
2341	} while (host_interrupt_status & (ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR | ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR));
2342}
2343/*
2344**********************************************************************
2345**********************************************************************
2346*/
2347static void arcmsr_handle_hbd_isr( struct AdapterControlBlock *acb)
2348{
2349	u_int32_t host_interrupt_status;
2350	u_int32_t intmask_org;
2351	/*
2352	*********************************************
2353	**   check outbound intstatus
2354	*********************************************
2355	*/
2356	host_interrupt_status = CHIP_REG_READ32(HBD_MessageUnit, 0, host_int_status) & acb->outbound_int_enable;
2357	if(!(host_interrupt_status & ARCMSR_HBDMU_OUTBOUND_INT)) {
2358		/*it must be share irq*/
2359		return;
2360	}
2361	/* disable outbound interrupt */
2362	intmask_org = CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable)	; /* disable outbound message0 int */
2363	CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, ARCMSR_HBDMU_ALL_INT_DISABLE);
2364	/* MU doorbell interrupts*/
2365	if(host_interrupt_status & ARCMSR_HBDMU_OUTBOUND_DOORBELL_INT) {
2366		arcmsr_hbd_doorbell_isr(acb);
2367	}
2368	/* MU post queue interrupts*/
2369	if(host_interrupt_status & ARCMSR_HBDMU_OUTBOUND_POSTQUEUE_INT) {
2370		arcmsr_hbd_postqueue_isr(acb);
2371	}
2372	/* enable all outbound interrupt */
2373	CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, intmask_org | ARCMSR_HBDMU_ALL_INT_ENABLE);
2374//	CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable);
2375}
2376/*
2377**********************************************************************
2378**********************************************************************
2379*/
2380static void arcmsr_handle_hbe_isr( struct AdapterControlBlock *acb)
2381{
2382	u_int32_t host_interrupt_status;
2383	/*
2384	*********************************************
2385	**   check outbound intstatus
2386	*********************************************
2387	*/
2388	host_interrupt_status = CHIP_REG_READ32(HBE_MessageUnit, 0, host_int_status) &
2389		(ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR |
2390		ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR);
2391	if(!host_interrupt_status) {
2392		/*it must be share irq*/
2393		return;
2394	}
2395	do {
2396		/* MU doorbell interrupts*/
2397		if(host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR) {
2398			arcmsr_hbe_doorbell_isr(acb);
2399		}
2400		/* MU post queue interrupts*/
2401		if(host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR) {
2402			arcmsr_hbe_postqueue_isr(acb);
2403		}
2404		host_interrupt_status = CHIP_REG_READ32(HBE_MessageUnit, 0, host_int_status);
2405	} while (host_interrupt_status & (ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR | ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR));
2406}
2407
2408static void arcmsr_handle_hbf_isr( struct AdapterControlBlock *acb)
2409{
2410	u_int32_t host_interrupt_status;
2411	/*
2412	*********************************************
2413	**   check outbound intstatus
2414	*********************************************
2415	*/
2416	host_interrupt_status = CHIP_REG_READ32(HBF_MessageUnit, 0, host_int_status) &
2417		(ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR |
2418		ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR);
2419	if(!host_interrupt_status) {
2420		/*it must be share irq*/
2421		return;
2422	}
2423	do {
2424		/* MU doorbell interrupts*/
2425		if(host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR) {
2426			arcmsr_hbf_doorbell_isr(acb);
2427		}
2428		/* MU post queue interrupts*/
2429		if(host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR) {
2430			arcmsr_hbf_postqueue_isr(acb);
2431		}
2432		host_interrupt_status = CHIP_REG_READ32(HBF_MessageUnit, 0, host_int_status);
2433	} while (host_interrupt_status & (ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR | ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR));
2434}
2435/*
2436******************************************************************************
2437******************************************************************************
2438*/
2439static void arcmsr_interrupt(struct AdapterControlBlock *acb)
2440{
2441	switch (acb->adapter_type) {
2442	case ACB_ADAPTER_TYPE_A:
2443		arcmsr_handle_hba_isr(acb);
2444		break;
2445	case ACB_ADAPTER_TYPE_B:
2446		arcmsr_handle_hbb_isr(acb);
2447		break;
2448	case ACB_ADAPTER_TYPE_C:
2449		arcmsr_handle_hbc_isr(acb);
2450		break;
2451	case ACB_ADAPTER_TYPE_D:
2452		arcmsr_handle_hbd_isr(acb);
2453		break;
2454	case ACB_ADAPTER_TYPE_E:
2455		arcmsr_handle_hbe_isr(acb);
2456		break;
2457	case ACB_ADAPTER_TYPE_F:
2458		arcmsr_handle_hbf_isr(acb);
2459		break;
2460	default:
2461		printf("arcmsr%d: interrupt service,"
2462		" unknown adapter type =%d\n", acb->pci_unit, acb->adapter_type);
2463		break;
2464	}
2465}
2466/*
2467**********************************************************************
2468**********************************************************************
2469*/
2470static void arcmsr_intr_handler(void *arg)
2471{
2472	struct AdapterControlBlock *acb = (struct AdapterControlBlock *)arg;
2473
2474	ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
2475	arcmsr_interrupt(acb);
2476	ARCMSR_LOCK_RELEASE(&acb->isr_lock);
2477}
2478/*
2479******************************************************************************
2480******************************************************************************
2481*/
2482static void	arcmsr_polling_devmap(void *arg)
2483{
2484	struct AdapterControlBlock *acb = (struct AdapterControlBlock *)arg;
2485	switch (acb->adapter_type) {
2486	case ACB_ADAPTER_TYPE_A:
2487		CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
2488		break;
2489
2490	case ACB_ADAPTER_TYPE_B: {
2491			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
2492			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_GET_CONFIG);
2493		}
2494		break;
2495
2496	case ACB_ADAPTER_TYPE_C:
2497		CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
2498		CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
2499		break;
2500
2501	case ACB_ADAPTER_TYPE_D:
2502		CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
2503		break;
2504
2505	case ACB_ADAPTER_TYPE_E:
2506		CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
2507		acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
2508		CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
2509		break;
2510
2511	case ACB_ADAPTER_TYPE_F: {
2512		u_int32_t outMsg1 = CHIP_REG_READ32(HBF_MessageUnit, 0, outbound_msgaddr1);
2513		if (!(outMsg1 & ARCMSR_HBFMU_MESSAGE_FIRMWARE_OK) ||
2514			(outMsg1 & ARCMSR_HBFMU_MESSAGE_NO_VOLUME_CHANGE))
2515			goto nxt6s;
2516		CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
2517		acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
2518		CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
2519		break;
2520		}
2521	}
2522nxt6s:
2523	if((acb->acb_flags & ACB_F_SCSISTOPADAPTER) == 0)
2524	{
2525		callout_reset(&acb->devmap_callout, 5 * hz, arcmsr_polling_devmap, acb);	/* polling per 5 seconds */
2526	}
2527}
2528
2529/*
2530*******************************************************************************
2531**
2532*******************************************************************************
2533*/
2534static void arcmsr_iop_parking(struct AdapterControlBlock *acb)
2535{
2536	u_int32_t intmask_org;
2537
2538	if(acb != NULL) {
2539		/* stop adapter background rebuild */
2540		if(acb->acb_flags & ACB_F_MSG_START_BGRB) {
2541			intmask_org = arcmsr_disable_allintr(acb);
2542			arcmsr_stop_adapter_bgrb(acb);
2543			arcmsr_flush_adapter_cache(acb);
2544			arcmsr_enable_allintr(acb, intmask_org);
2545		}
2546	}
2547}
2548/*
2549***********************************************************************
2550**
2551************************************************************************
2552*/
2553static u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_cmd, caddr_t arg)
2554{
2555	struct CMD_MESSAGE_FIELD *pcmdmessagefld;
2556	u_int32_t retvalue = EINVAL;
2557
2558	pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) arg;
2559	if(memcmp(pcmdmessagefld->cmdmessage.Signature, "ARCMSR", 6)!=0) {
2560		return retvalue;
2561	}
2562	ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
2563	switch(ioctl_cmd) {
2564	case ARCMSR_MESSAGE_READ_RQBUFFER: {
2565			u_int8_t *pQbuffer;
2566			u_int8_t *ptmpQbuffer = pcmdmessagefld->messagedatabuffer;
2567			u_int32_t allxfer_len=0;
2568
2569			while((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
2570				&& (allxfer_len < 1031)) {
2571				/*copy READ QBUFFER to srb*/
2572				pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
2573				*ptmpQbuffer = *pQbuffer;
2574				acb->rqbuf_firstindex++;
2575				acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
2576				/*if last index number set it to 0 */
2577				ptmpQbuffer++;
2578				allxfer_len++;
2579			}
2580			if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
2581				struct QBUFFER *prbuffer;
2582
2583				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
2584				prbuffer = arcmsr_get_iop_rqbuffer(acb);
2585				if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
2586					acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
2587			}
2588			pcmdmessagefld->cmdmessage.Length = allxfer_len;
2589			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
2590			retvalue = ARCMSR_MESSAGE_SUCCESS;
2591		}
2592		break;
2593	case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
2594			u_int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
2595			u_int8_t *pQbuffer;
2596			u_int8_t *ptmpuserbuffer = pcmdmessagefld->messagedatabuffer;
2597
2598			user_len = pcmdmessagefld->cmdmessage.Length;
2599			/*check if data xfer length of this request will overflow my array qbuffer */
2600			wqbuf_lastindex = acb->wqbuf_lastindex;
2601			wqbuf_firstindex = acb->wqbuf_firstindex;
2602			if(wqbuf_lastindex != wqbuf_firstindex) {
2603				arcmsr_Write_data_2iop_wqbuffer(acb);
2604				pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR;
2605			} else {
2606				my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1) &
2607					(ARCMSR_MAX_QBUFFER - 1);
2608				if(my_empty_len >= user_len) {
2609					while(user_len > 0) {
2610						/*copy srb data to wqbuffer*/
2611						pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex];
2612						*pQbuffer = *ptmpuserbuffer;
2613						acb->wqbuf_lastindex++;
2614						acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
2615						/*if last index number set it to 0 */
2616						ptmpuserbuffer++;
2617						user_len--;
2618					}
2619					/*post fist Qbuffer*/
2620					if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) {
2621						acb->acb_flags &= ~ACB_F_MESSAGE_WQBUFFER_CLEARED;
2622						arcmsr_Write_data_2iop_wqbuffer(acb);
2623					}
2624					pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
2625				} else {
2626					pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR;
2627				}
2628			}
2629			retvalue = ARCMSR_MESSAGE_SUCCESS;
2630		}
2631		break;
2632	case ARCMSR_MESSAGE_CLEAR_RQBUFFER: {
2633			u_int8_t *pQbuffer = acb->rqbuffer;
2634
2635			if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
2636				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
2637				arcmsr_iop_message_read(acb);
2638				/*signature, let IOP know data has been readed */
2639			}
2640			acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
2641			acb->rqbuf_firstindex = 0;
2642			acb->rqbuf_lastindex = 0;
2643			memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
2644			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
2645			retvalue = ARCMSR_MESSAGE_SUCCESS;
2646		}
2647		break;
2648	case ARCMSR_MESSAGE_CLEAR_WQBUFFER:
2649		{
2650			u_int8_t *pQbuffer = acb->wqbuffer;
2651
2652			if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
2653				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
2654				arcmsr_iop_message_read(acb);
2655				/*signature, let IOP know data has been readed */
2656			}
2657			acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED|ACB_F_MESSAGE_WQBUFFER_READ);
2658			acb->wqbuf_firstindex = 0;
2659			acb->wqbuf_lastindex = 0;
2660			memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
2661			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
2662			retvalue = ARCMSR_MESSAGE_SUCCESS;
2663		}
2664		break;
2665	case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: {
2666			u_int8_t *pQbuffer;
2667
2668			if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
2669				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
2670				arcmsr_iop_message_read(acb);
2671				/*signature, let IOP know data has been readed */
2672			}
2673			acb->acb_flags  |= (ACB_F_MESSAGE_WQBUFFER_CLEARED
2674					|ACB_F_MESSAGE_RQBUFFER_CLEARED
2675					|ACB_F_MESSAGE_WQBUFFER_READ);
2676			acb->rqbuf_firstindex = 0;
2677			acb->rqbuf_lastindex = 0;
2678			acb->wqbuf_firstindex = 0;
2679			acb->wqbuf_lastindex = 0;
2680			pQbuffer = acb->rqbuffer;
2681			memset(pQbuffer, 0, sizeof(struct QBUFFER));
2682			pQbuffer = acb->wqbuffer;
2683			memset(pQbuffer, 0, sizeof(struct QBUFFER));
2684			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
2685			retvalue = ARCMSR_MESSAGE_SUCCESS;
2686		}
2687		break;
2688	case ARCMSR_MESSAGE_REQUEST_RETURNCODE_3F: {
2689			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F;
2690			retvalue = ARCMSR_MESSAGE_SUCCESS;
2691		}
2692		break;
2693	case ARCMSR_MESSAGE_SAY_HELLO: {
2694			u_int8_t *hello_string = "Hello! I am ARCMSR";
2695			u_int8_t *puserbuffer = (u_int8_t *)pcmdmessagefld->messagedatabuffer;
2696
2697			if(memcpy(puserbuffer, hello_string, (int16_t)strlen(hello_string))) {
2698				pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR;
2699				ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
2700				return ENOIOCTL;
2701			}
2702			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
2703			retvalue = ARCMSR_MESSAGE_SUCCESS;
2704		}
2705		break;
2706	case ARCMSR_MESSAGE_SAY_GOODBYE: {
2707			arcmsr_iop_parking(acb);
2708			retvalue = ARCMSR_MESSAGE_SUCCESS;
2709		}
2710		break;
2711	case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: {
2712			arcmsr_flush_adapter_cache(acb);
2713			retvalue = ARCMSR_MESSAGE_SUCCESS;
2714		}
2715		break;
2716	}
2717	ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
2718	return (retvalue);
2719}
2720/*
2721**************************************************************************
2722**************************************************************************
2723*/
2724static void arcmsr_free_srb(struct CommandControlBlock *srb)
2725{
2726	struct AdapterControlBlock	*acb;
2727
2728	acb = srb->acb;
2729	ARCMSR_LOCK_ACQUIRE(&acb->srb_lock);
2730	srb->srb_state = ARCMSR_SRB_DONE;
2731	srb->srb_flags = 0;
2732	acb->srbworkingQ[acb->workingsrb_doneindex] = srb;
2733	acb->workingsrb_doneindex++;
2734	acb->workingsrb_doneindex %= ARCMSR_MAX_FREESRB_NUM;
2735	ARCMSR_LOCK_RELEASE(&acb->srb_lock);
2736}
2737/*
2738**************************************************************************
2739**************************************************************************
2740*/
2741static struct CommandControlBlock *arcmsr_get_freesrb(struct AdapterControlBlock *acb)
2742{
2743	struct CommandControlBlock *srb = NULL;
2744	u_int32_t workingsrb_startindex, workingsrb_doneindex;
2745
2746	ARCMSR_LOCK_ACQUIRE(&acb->srb_lock);
2747	workingsrb_doneindex = acb->workingsrb_doneindex;
2748	workingsrb_startindex = acb->workingsrb_startindex;
2749	srb = acb->srbworkingQ[workingsrb_startindex];
2750	workingsrb_startindex++;
2751	workingsrb_startindex %= ARCMSR_MAX_FREESRB_NUM;
2752	if(workingsrb_doneindex != workingsrb_startindex) {
2753		acb->workingsrb_startindex = workingsrb_startindex;
2754	} else {
2755		srb = NULL;
2756	}
2757	ARCMSR_LOCK_RELEASE(&acb->srb_lock);
2758	return(srb);
2759}
2760/*
2761**************************************************************************
2762**************************************************************************
2763*/
2764static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *pccb)
2765{
2766	struct CMD_MESSAGE_FIELD *pcmdmessagefld;
2767	int retvalue = 0, transfer_len = 0;
2768	char *buffer;
2769	uint8_t *ptr = scsiio_cdb_ptr(&pccb->csio);
2770	u_int32_t controlcode = (u_int32_t ) ptr[5] << 24 |
2771				(u_int32_t ) ptr[6] << 16 |
2772				(u_int32_t ) ptr[7] << 8  |
2773				(u_int32_t ) ptr[8];
2774					/* 4 bytes: Areca io control code */
2775	if ((pccb->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_VADDR) {
2776		buffer = pccb->csio.data_ptr;
2777		transfer_len = pccb->csio.dxfer_len;
2778	} else {
2779		retvalue = ARCMSR_MESSAGE_FAIL;
2780		goto message_out;
2781	}
2782	if (transfer_len > sizeof(struct CMD_MESSAGE_FIELD)) {
2783		retvalue = ARCMSR_MESSAGE_FAIL;
2784		goto message_out;
2785	}
2786	pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) buffer;
2787	switch(controlcode) {
2788	case ARCMSR_MESSAGE_READ_RQBUFFER: {
2789			u_int8_t *pQbuffer;
2790			u_int8_t *ptmpQbuffer = pcmdmessagefld->messagedatabuffer;
2791			int32_t allxfer_len = 0;
2792
2793			ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
2794			while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
2795				&& (allxfer_len < 1031)) {
2796				pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
2797				*ptmpQbuffer = *pQbuffer;
2798				acb->rqbuf_firstindex++;
2799				acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
2800				ptmpQbuffer++;
2801				allxfer_len++;
2802			}
2803			if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
2804				struct QBUFFER  *prbuffer;
2805
2806				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
2807				prbuffer = arcmsr_get_iop_rqbuffer(acb);
2808				if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
2809					acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
2810			}
2811			pcmdmessagefld->cmdmessage.Length = allxfer_len;
2812			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
2813			retvalue = ARCMSR_MESSAGE_SUCCESS;
2814			ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
2815		}
2816		break;
2817	case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
2818			int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
2819			u_int8_t *pQbuffer;
2820			u_int8_t *ptmpuserbuffer = pcmdmessagefld->messagedatabuffer;
2821
2822			user_len = pcmdmessagefld->cmdmessage.Length;
2823			ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
2824			wqbuf_lastindex = acb->wqbuf_lastindex;
2825			wqbuf_firstindex = acb->wqbuf_firstindex;
2826			if (wqbuf_lastindex != wqbuf_firstindex) {
2827				arcmsr_Write_data_2iop_wqbuffer(acb);
2828				/* has error report sensedata */
2829				if(pccb->csio.sense_len) {
2830				((u_int8_t *)&pccb->csio.sense_data)[0] = (0x1 << 7 | 0x70);
2831				/* Valid,ErrorCode */
2832				((u_int8_t *)&pccb->csio.sense_data)[2] = 0x05;
2833				/* FileMark,EndOfMedia,IncorrectLength,Reserved,SenseKey */
2834				((u_int8_t *)&pccb->csio.sense_data)[7] = 0x0A;
2835				/* AdditionalSenseLength */
2836				((u_int8_t *)&pccb->csio.sense_data)[12] = 0x20;
2837				/* AdditionalSenseCode */
2838				}
2839				retvalue = ARCMSR_MESSAGE_FAIL;
2840			} else {
2841				my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1)
2842						&(ARCMSR_MAX_QBUFFER - 1);
2843				if (my_empty_len >= user_len) {
2844					while (user_len > 0) {
2845						pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex];
2846						*pQbuffer = *ptmpuserbuffer;
2847						acb->wqbuf_lastindex++;
2848						acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
2849						ptmpuserbuffer++;
2850						user_len--;
2851					}
2852					if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) {
2853						acb->acb_flags &=
2854						    ~ACB_F_MESSAGE_WQBUFFER_CLEARED;
2855						arcmsr_Write_data_2iop_wqbuffer(acb);
2856					}
2857				} else {
2858					/* has error report sensedata */
2859					if(pccb->csio.sense_len) {
2860					((u_int8_t *)&pccb->csio.sense_data)[0] = (0x1 << 7 | 0x70);
2861					/* Valid,ErrorCode */
2862					((u_int8_t *)&pccb->csio.sense_data)[2] = 0x05;
2863					/* FileMark,EndOfMedia,IncorrectLength,Reserved,SenseKey */
2864					((u_int8_t *)&pccb->csio.sense_data)[7] = 0x0A;
2865					/* AdditionalSenseLength */
2866					((u_int8_t *)&pccb->csio.sense_data)[12] = 0x20;
2867					/* AdditionalSenseCode */
2868					}
2869					retvalue = ARCMSR_MESSAGE_FAIL;
2870				}
2871			}
2872			ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
2873		}
2874		break;
2875	case ARCMSR_MESSAGE_CLEAR_RQBUFFER: {
2876			u_int8_t *pQbuffer = acb->rqbuffer;
2877
2878			ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
2879			if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
2880				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
2881				arcmsr_iop_message_read(acb);
2882			}
2883			acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
2884			acb->rqbuf_firstindex = 0;
2885			acb->rqbuf_lastindex = 0;
2886			memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
2887			pcmdmessagefld->cmdmessage.ReturnCode =
2888			    ARCMSR_MESSAGE_RETURNCODE_OK;
2889			ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
2890		}
2891		break;
2892	case ARCMSR_MESSAGE_CLEAR_WQBUFFER: {
2893			u_int8_t *pQbuffer = acb->wqbuffer;
2894
2895			ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
2896			if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
2897				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
2898				arcmsr_iop_message_read(acb);
2899			}
2900			acb->acb_flags |=
2901				(ACB_F_MESSAGE_WQBUFFER_CLEARED |
2902					ACB_F_MESSAGE_WQBUFFER_READ);
2903			acb->wqbuf_firstindex = 0;
2904			acb->wqbuf_lastindex = 0;
2905			memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
2906			pcmdmessagefld->cmdmessage.ReturnCode =
2907				ARCMSR_MESSAGE_RETURNCODE_OK;
2908			ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
2909		}
2910		break;
2911	case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: {
2912			u_int8_t *pQbuffer;
2913
2914			ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
2915			if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
2916				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
2917				arcmsr_iop_message_read(acb);
2918			}
2919			acb->acb_flags |=
2920				(ACB_F_MESSAGE_WQBUFFER_CLEARED
2921				| ACB_F_MESSAGE_RQBUFFER_CLEARED
2922				| ACB_F_MESSAGE_WQBUFFER_READ);
2923			acb->rqbuf_firstindex = 0;
2924			acb->rqbuf_lastindex = 0;
2925			acb->wqbuf_firstindex = 0;
2926			acb->wqbuf_lastindex = 0;
2927			pQbuffer = acb->rqbuffer;
2928			memset(pQbuffer, 0, sizeof (struct QBUFFER));
2929			pQbuffer = acb->wqbuffer;
2930			memset(pQbuffer, 0, sizeof (struct QBUFFER));
2931			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
2932			ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
2933		}
2934		break;
2935	case ARCMSR_MESSAGE_REQUEST_RETURNCODE_3F: {
2936			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F;
2937		}
2938		break;
2939	case ARCMSR_MESSAGE_SAY_HELLO: {
2940			int8_t *hello_string = "Hello! I am ARCMSR";
2941
2942			memcpy(pcmdmessagefld->messagedatabuffer, hello_string
2943				, (int16_t)strlen(hello_string));
2944			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
2945		}
2946		break;
2947	case ARCMSR_MESSAGE_SAY_GOODBYE:
2948		arcmsr_iop_parking(acb);
2949		break;
2950	case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE:
2951		arcmsr_flush_adapter_cache(acb);
2952		break;
2953	default:
2954		retvalue = ARCMSR_MESSAGE_FAIL;
2955	}
2956message_out:
2957	return (retvalue);
2958}
2959/*
2960*********************************************************************
2961*********************************************************************
2962*/
2963static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
2964{
2965	struct CommandControlBlock *srb = (struct CommandControlBlock *)arg;
2966	struct AdapterControlBlock *acb = (struct AdapterControlBlock *)srb->acb;
2967	union ccb *pccb;
2968	int target, lun;
2969
2970	pccb = srb->pccb;
2971	target = pccb->ccb_h.target_id;
2972	lun = pccb->ccb_h.target_lun;
2973	acb->pktRequestCount++;
2974	if(error != 0) {
2975		if(error != EFBIG) {
2976			printf("arcmsr%d: unexpected error %x"
2977				" returned from 'bus_dmamap_load' \n"
2978				, acb->pci_unit, error);
2979		}
2980		if((pccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
2981			pccb->ccb_h.status |= CAM_REQ_TOO_BIG;
2982		}
2983		arcmsr_srb_complete(srb, 0);
2984		return;
2985	}
2986	if(nseg > ARCMSR_MAX_SG_ENTRIES) {
2987		pccb->ccb_h.status |= CAM_REQ_TOO_BIG;
2988		arcmsr_srb_complete(srb, 0);
2989		return;
2990	}
2991	if(acb->acb_flags & ACB_F_BUS_RESET) {
2992		printf("arcmsr%d: bus reset and return busy \n", acb->pci_unit);
2993		pccb->ccb_h.status |= CAM_SCSI_BUS_RESET;
2994		arcmsr_srb_complete(srb, 0);
2995		return;
2996	}
2997	if(acb->devstate[target][lun] == ARECA_RAID_GONE) {
2998		u_int8_t block_cmd, cmd;
2999
3000		cmd = scsiio_cdb_ptr(&pccb->csio)[0];
3001		block_cmd = cmd & 0x0f;
3002		if(block_cmd == 0x08 || block_cmd == 0x0a) {
3003			printf("arcmsr%d:block 'read/write' command "
3004				"with gone raid volume Cmd=0x%2x, TargetId=%d, Lun=%d \n"
3005				, acb->pci_unit, cmd, target, lun);
3006			pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
3007			arcmsr_srb_complete(srb, 0);
3008			return;
3009		}
3010	}
3011	if((pccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
3012		if(nseg != 0) {
3013			bus_dmamap_unload(acb->dm_segs_dmat, srb->dm_segs_dmamap);
3014		}
3015		arcmsr_srb_complete(srb, 0);
3016		return;
3017	}
3018	if(acb->srboutstandingcount >= acb->maxOutstanding) {
3019		if((acb->acb_flags & ACB_F_CAM_DEV_QFRZN) == 0)
3020		{
3021			xpt_freeze_simq(acb->psim, 1);
3022			acb->acb_flags |= ACB_F_CAM_DEV_QFRZN;
3023		}
3024		pccb->ccb_h.status &= ~CAM_SIM_QUEUED;
3025		pccb->ccb_h.status |= CAM_REQUEUE_REQ;
3026		arcmsr_srb_complete(srb, 0);
3027		return;
3028	}
3029	pccb->ccb_h.status |= CAM_SIM_QUEUED;
3030	arcmsr_build_srb(srb, dm_segs, nseg);
3031	arcmsr_post_srb(acb, srb);
3032	if (pccb->ccb_h.timeout != CAM_TIME_INFINITY)
3033	{
3034		arcmsr_callout_init(&srb->ccb_callout);
3035		callout_reset_sbt(&srb->ccb_callout, SBT_1MS *
3036		    (pccb->ccb_h.timeout + (ARCMSR_TIMEOUT_DELAY * 1000)), 0,
3037		    arcmsr_srb_timeout, srb, 0);
3038		srb->srb_flags |= SRB_FLAG_TIMER_START;
3039	}
3040}
3041/*
3042*****************************************************************************************
3043*****************************************************************************************
3044*/
3045static u_int8_t arcmsr_seek_cmd2abort(union ccb *abortccb)
3046{
3047	struct CommandControlBlock *srb;
3048	struct AdapterControlBlock *acb = (struct AdapterControlBlock *) abortccb->ccb_h.arcmsr_ccbacb_ptr;
3049	u_int32_t intmask_org;
3050	int i = 0;
3051
3052	acb->num_aborts++;
3053	/*
3054	***************************************************************************
3055	** It is the upper layer do abort command this lock just prior to calling us.
3056	** First determine if we currently own this command.
3057	** Start by searching the device queue. If not found
3058	** at all, and the system wanted us to just abort the
3059	** command return success.
3060	***************************************************************************
3061	*/
3062	if(acb->srboutstandingcount != 0) {
3063		/* disable all outbound interrupt */
3064		intmask_org = arcmsr_disable_allintr(acb);
3065		for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) {
3066			srb = acb->psrb_pool[i];
3067			if(srb->srb_state == ARCMSR_SRB_START) {
3068				if(srb->pccb == abortccb) {
3069					srb->srb_state = ARCMSR_SRB_ABORTED;
3070					printf("arcmsr%d:scsi id=%d lun=%jx abort srb '%p'"
3071						"outstanding command \n"
3072						, acb->pci_unit, abortccb->ccb_h.target_id
3073						, (uintmax_t)abortccb->ccb_h.target_lun, srb);
3074					arcmsr_polling_srbdone(acb, srb);
3075					/* enable outbound Post Queue, outbound doorbell Interrupt */
3076					arcmsr_enable_allintr(acb, intmask_org);
3077					return (TRUE);
3078				}
3079			}
3080		}
3081		/* enable outbound Post Queue, outbound doorbell Interrupt */
3082		arcmsr_enable_allintr(acb, intmask_org);
3083	}
3084	return(FALSE);
3085}
3086/*
3087****************************************************************************
3088****************************************************************************
3089*/
3090static void arcmsr_bus_reset(struct AdapterControlBlock *acb)
3091{
3092	int retry = 0;
3093
3094	acb->num_resets++;
3095	acb->acb_flags |= ACB_F_BUS_RESET;
3096	while(acb->srboutstandingcount != 0 && retry < 400) {
3097		arcmsr_interrupt(acb);
3098		UDELAY(25000);
3099		retry++;
3100	}
3101	arcmsr_iop_reset(acb);
3102	acb->acb_flags &= ~ACB_F_BUS_RESET;
3103}
3104/*
3105**************************************************************************
3106**************************************************************************
3107*/
3108static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
3109		union ccb *pccb)
3110{
3111	if (pccb->ccb_h.target_lun) {
3112		pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
3113		xpt_done(pccb);
3114		return;
3115	}
3116	pccb->ccb_h.status |= CAM_REQ_CMP;
3117	switch (scsiio_cdb_ptr(&pccb->csio)[0]) {
3118	case INQUIRY: {
3119		unsigned char inqdata[36];
3120		char *buffer = pccb->csio.data_ptr;
3121
3122		inqdata[0] = T_PROCESSOR;	/* Periph Qualifier & Periph Dev Type */
3123		inqdata[1] = 0;			/* rem media bit & Dev Type Modifier */
3124		inqdata[2] = 0;			/* ISO, ECMA, & ANSI versions */
3125		inqdata[3] = 0;
3126		inqdata[4] = 31;		/* length of additional data */
3127		inqdata[5] = 0;
3128		inqdata[6] = 0;
3129		inqdata[7] = 0;
3130		strncpy(&inqdata[8], "Areca   ", 8);	/* Vendor Identification */
3131		strncpy(&inqdata[16], "RAID controller ", 16);	/* Product Identification */
3132		strncpy(&inqdata[32], "R001", 4); /* Product Revision */
3133		memcpy(buffer, inqdata, sizeof(inqdata));
3134		xpt_done(pccb);
3135	}
3136	break;
3137	case WRITE_BUFFER:
3138	case READ_BUFFER: {
3139		if (arcmsr_iop_message_xfer(acb, pccb)) {
3140			pccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
3141			pccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
3142		}
3143		xpt_done(pccb);
3144	}
3145	break;
3146	default:
3147		xpt_done(pccb);
3148	}
3149}
3150/*
3151*********************************************************************
3152*********************************************************************
3153*/
3154static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
3155{
3156	struct AdapterControlBlock *acb;
3157
3158	acb = (struct AdapterControlBlock *) cam_sim_softc(psim);
3159	if(acb == NULL) {
3160		pccb->ccb_h.status |= CAM_REQ_INVALID;
3161		xpt_done(pccb);
3162		return;
3163	}
3164	switch (pccb->ccb_h.func_code) {
3165	case XPT_SCSI_IO: {
3166			struct CommandControlBlock *srb;
3167			int target = pccb->ccb_h.target_id;
3168			int error;
3169
3170			if (pccb->ccb_h.flags & CAM_CDB_PHYS) {
3171				pccb->ccb_h.status = CAM_REQ_INVALID;
3172				xpt_done(pccb);
3173				return;
3174			}
3175
3176			if(target == ARCMSR_VIRTUAL_DEVICE_ID) {
3177				/* virtual device for iop message transfer */
3178				arcmsr_handle_virtual_command(acb, pccb);
3179				return;
3180			}
3181			if((srb = arcmsr_get_freesrb(acb)) == NULL) {
3182				pccb->ccb_h.status |= CAM_RESRC_UNAVAIL;
3183				xpt_done(pccb);
3184				return;
3185			}
3186			pccb->ccb_h.arcmsr_ccbsrb_ptr = srb;
3187			pccb->ccb_h.arcmsr_ccbacb_ptr = acb;
3188			srb->pccb = pccb;
3189			error =	bus_dmamap_load_ccb(acb->dm_segs_dmat
3190				, srb->dm_segs_dmamap
3191				, pccb
3192				, arcmsr_execute_srb, srb, /*flags*/0);
3193			if(error == EINPROGRESS) {
3194				xpt_freeze_simq(acb->psim, 1);
3195				pccb->ccb_h.status |= CAM_RELEASE_SIMQ;
3196			}
3197			break;
3198		}
3199	case XPT_PATH_INQ: {
3200			struct ccb_pathinq *cpi = &pccb->cpi;
3201
3202			cpi->version_num = 1;
3203			cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE;
3204			cpi->target_sprt = 0;
3205			cpi->hba_misc = 0;
3206			cpi->hba_eng_cnt = 0;
3207			cpi->max_target = ARCMSR_MAX_TARGETID;        /* 0-16 */
3208			cpi->max_lun = ARCMSR_MAX_TARGETLUN;	    /* 0-7 */
3209			cpi->initiator_id = ARCMSR_SCSI_INITIATOR_ID; /* 255 */
3210			cpi->bus_id = cam_sim_bus(psim);
3211			strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
3212			strlcpy(cpi->hba_vid, "ARCMSR", HBA_IDLEN);
3213			strlcpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN);
3214			cpi->unit_number = cam_sim_unit(psim);
3215			if(acb->adapter_bus_speed == ACB_BUS_SPEED_12G)
3216				cpi->base_transfer_speed = 1200000;
3217			else if(acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
3218				cpi->base_transfer_speed = 600000;
3219			else
3220				cpi->base_transfer_speed = 300000;
3221			if((acb->vendor_device_id == PCIDevVenIDARC1880) ||
3222			   (acb->vendor_device_id == PCIDevVenIDARC1883) ||
3223			   (acb->vendor_device_id == PCIDevVenIDARC1884) ||
3224			   (acb->vendor_device_id == PCIDevVenIDARC1886) ||
3225			   (acb->vendor_device_id == PCIDevVenIDARC1680) ||
3226			   (acb->vendor_device_id == PCIDevVenIDARC1214))
3227			{
3228				cpi->transport = XPORT_SAS;
3229				cpi->transport_version = 0;
3230				cpi->protocol_version = SCSI_REV_SPC2;
3231			}
3232			else
3233			{
3234				cpi->transport = XPORT_SPI;
3235				cpi->transport_version = 2;
3236				cpi->protocol_version = SCSI_REV_2;
3237			}
3238			cpi->protocol = PROTO_SCSI;
3239			cpi->ccb_h.status |= CAM_REQ_CMP;
3240			xpt_done(pccb);
3241			break;
3242		}
3243	case XPT_ABORT: {
3244			union ccb *pabort_ccb;
3245
3246			pabort_ccb = pccb->cab.abort_ccb;
3247			switch (pabort_ccb->ccb_h.func_code) {
3248			case XPT_ACCEPT_TARGET_IO:
3249			case XPT_CONT_TARGET_IO:
3250				if(arcmsr_seek_cmd2abort(pabort_ccb)==TRUE) {
3251					pabort_ccb->ccb_h.status |= CAM_REQ_ABORTED;
3252					xpt_done(pabort_ccb);
3253					pccb->ccb_h.status |= CAM_REQ_CMP;
3254				} else {
3255					xpt_print_path(pabort_ccb->ccb_h.path);
3256					printf("Not found\n");
3257					pccb->ccb_h.status |= CAM_PATH_INVALID;
3258				}
3259				break;
3260			case XPT_SCSI_IO:
3261				pccb->ccb_h.status |= CAM_UA_ABORT;
3262				break;
3263			default:
3264				pccb->ccb_h.status |= CAM_REQ_INVALID;
3265				break;
3266			}
3267			xpt_done(pccb);
3268			break;
3269		}
3270	case XPT_RESET_BUS:
3271	case XPT_RESET_DEV: {
3272			u_int32_t	i;
3273
3274			arcmsr_bus_reset(acb);
3275			for (i=0; i < 500; i++) {
3276				DELAY(1000);
3277			}
3278			pccb->ccb_h.status |= CAM_REQ_CMP;
3279			xpt_done(pccb);
3280			break;
3281		}
3282	case XPT_TERM_IO: {
3283			pccb->ccb_h.status |= CAM_REQ_INVALID;
3284			xpt_done(pccb);
3285			break;
3286		}
3287	case XPT_GET_TRAN_SETTINGS: {
3288			struct ccb_trans_settings *cts;
3289
3290			if(pccb->ccb_h.target_id == ARCMSR_VIRTUAL_DEVICE_ID) {
3291				pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL;
3292				xpt_done(pccb);
3293				break;
3294			}
3295			cts = &pccb->cts;
3296			{
3297				struct ccb_trans_settings_scsi *scsi;
3298				struct ccb_trans_settings_spi *spi;
3299				struct ccb_trans_settings_sas *sas;
3300
3301				scsi = &cts->proto_specific.scsi;
3302				scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
3303				scsi->valid = CTS_SCSI_VALID_TQ;
3304				cts->protocol = PROTO_SCSI;
3305
3306				if((acb->vendor_device_id == PCIDevVenIDARC1880) ||
3307				   (acb->vendor_device_id == PCIDevVenIDARC1883) ||
3308				   (acb->vendor_device_id == PCIDevVenIDARC1884) ||
3309				   (acb->vendor_device_id == PCIDevVenIDARC1886) ||
3310				   (acb->vendor_device_id == PCIDevVenIDARC1680) ||
3311				   (acb->vendor_device_id == PCIDevVenIDARC1214))
3312				{
3313					cts->protocol_version = SCSI_REV_SPC2;
3314					cts->transport_version = 0;
3315					cts->transport = XPORT_SAS;
3316					sas = &cts->xport_specific.sas;
3317					sas->valid = CTS_SAS_VALID_SPEED;
3318					if (acb->adapter_bus_speed == ACB_BUS_SPEED_12G)
3319						sas->bitrate = 1200000;
3320					else if(acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
3321						sas->bitrate = 600000;
3322					else if(acb->adapter_bus_speed == ACB_BUS_SPEED_3G)
3323						sas->bitrate = 300000;
3324				}
3325				else
3326				{
3327					cts->protocol_version = SCSI_REV_2;
3328					cts->transport_version = 2;
3329					cts->transport = XPORT_SPI;
3330					spi = &cts->xport_specific.spi;
3331					spi->flags = CTS_SPI_FLAGS_DISC_ENB;
3332					if (acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
3333						spi->sync_period = 1;
3334					else
3335						spi->sync_period = 2;
3336					spi->sync_offset = 32;
3337					spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
3338					spi->valid = CTS_SPI_VALID_DISC
3339						| CTS_SPI_VALID_SYNC_RATE
3340						| CTS_SPI_VALID_SYNC_OFFSET
3341						| CTS_SPI_VALID_BUS_WIDTH;
3342				}
3343			}
3344			pccb->ccb_h.status |= CAM_REQ_CMP;
3345			xpt_done(pccb);
3346			break;
3347		}
3348	case XPT_SET_TRAN_SETTINGS: {
3349			pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL;
3350			xpt_done(pccb);
3351			break;
3352		}
3353	case XPT_CALC_GEOMETRY:
3354			if(pccb->ccb_h.target_id == ARCMSR_VIRTUAL_DEVICE_ID) {
3355				pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL;
3356				xpt_done(pccb);
3357				break;
3358			}
3359			cam_calc_geometry(&pccb->ccg, 1);
3360			xpt_done(pccb);
3361			break;
3362	default:
3363		pccb->ccb_h.status |= CAM_REQ_INVALID;
3364		xpt_done(pccb);
3365		break;
3366	}
3367}
3368/*
3369**********************************************************************
3370**********************************************************************
3371*/
3372static void arcmsr_start_hba_bgrb(struct AdapterControlBlock *acb)
3373{
3374	acb->acb_flags |= ACB_F_MSG_START_BGRB;
3375	CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB);
3376	if(!arcmsr_hba_wait_msgint_ready(acb)) {
3377		printf("arcmsr%d: wait 'start adapter background rebuild' timeout \n", acb->pci_unit);
3378	}
3379}
3380/*
3381**********************************************************************
3382**********************************************************************
3383*/
3384static void arcmsr_start_hbb_bgrb(struct AdapterControlBlock *acb)
3385{
3386	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
3387	acb->acb_flags |= ACB_F_MSG_START_BGRB;
3388	WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_START_BGRB);
3389	if(!arcmsr_hbb_wait_msgint_ready(acb)) {
3390		printf( "arcmsr%d: wait 'start adapter background rebuild' timeout \n", acb->pci_unit);
3391	}
3392}
3393/*
3394**********************************************************************
3395**********************************************************************
3396*/
3397static void arcmsr_start_hbc_bgrb(struct AdapterControlBlock *acb)
3398{
3399	acb->acb_flags |= ACB_F_MSG_START_BGRB;
3400	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB);
3401	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
3402	if(!arcmsr_hbc_wait_msgint_ready(acb)) {
3403		printf("arcmsr%d: wait 'start adapter background rebuild' timeout \n", acb->pci_unit);
3404	}
3405}
3406/*
3407**********************************************************************
3408**********************************************************************
3409*/
3410static void arcmsr_start_hbd_bgrb(struct AdapterControlBlock *acb)
3411{
3412	acb->acb_flags |= ACB_F_MSG_START_BGRB;
3413	CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB);
3414	if(!arcmsr_hbd_wait_msgint_ready(acb)) {
3415		printf("arcmsr%d: wait 'start adapter background rebuild' timeout \n", acb->pci_unit);
3416	}
3417}
3418/*
3419**********************************************************************
3420**********************************************************************
3421*/
3422static void arcmsr_start_hbe_bgrb(struct AdapterControlBlock *acb)
3423{
3424	acb->acb_flags |= ACB_F_MSG_START_BGRB;
3425	CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB);
3426	acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
3427	CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
3428	if(!arcmsr_hbe_wait_msgint_ready(acb)) {
3429		printf("arcmsr%d: wait 'start adapter background rebuild' timeout \n", acb->pci_unit);
3430	}
3431}
3432/*
3433**********************************************************************
3434**********************************************************************
3435*/
3436static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb)
3437{
3438	switch (acb->adapter_type) {
3439	case ACB_ADAPTER_TYPE_A:
3440		arcmsr_start_hba_bgrb(acb);
3441		break;
3442	case ACB_ADAPTER_TYPE_B:
3443		arcmsr_start_hbb_bgrb(acb);
3444		break;
3445	case ACB_ADAPTER_TYPE_C:
3446		arcmsr_start_hbc_bgrb(acb);
3447		break;
3448	case ACB_ADAPTER_TYPE_D:
3449		arcmsr_start_hbd_bgrb(acb);
3450		break;
3451	case ACB_ADAPTER_TYPE_E:
3452	case ACB_ADAPTER_TYPE_F:
3453		arcmsr_start_hbe_bgrb(acb);
3454		break;
3455	}
3456}
3457/*
3458**********************************************************************
3459**
3460**********************************************************************
3461*/
3462static void arcmsr_polling_hba_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
3463{
3464	struct CommandControlBlock *srb;
3465	u_int32_t flag_srb, outbound_intstatus, poll_srb_done=0, poll_count=0;
3466	u_int16_t	error;
3467
3468polling_ccb_retry:
3469	poll_count++;
3470	outbound_intstatus=CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable;
3471	CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intstatus);	/*clear interrupt*/
3472	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3473	while(1) {
3474		if((flag_srb = CHIP_REG_READ32(HBA_MessageUnit,
3475			0, outbound_queueport)) == 0xFFFFFFFF) {
3476			if(poll_srb_done) {
3477				break;/*chip FIFO no ccb for completion already*/
3478			} else {
3479				UDELAY(25000);
3480				if ((poll_count > 100) && (poll_srb != NULL)) {
3481					break;
3482				}
3483				goto polling_ccb_retry;
3484			}
3485		}
3486		/* check if command done with no error*/
3487		srb = (struct CommandControlBlock *)
3488			(acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
3489		error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
3490		poll_srb_done = (srb == poll_srb) ? 1:0;
3491		if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
3492			if(srb->srb_state == ARCMSR_SRB_ABORTED) {
3493				printf("arcmsr%d: scsi id=%d lun=%jx srb='%p'"
3494					"poll command abort successfully \n"
3495					, acb->pci_unit
3496					, srb->pccb->ccb_h.target_id
3497					, (uintmax_t)srb->pccb->ccb_h.target_lun, srb);
3498				srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
3499				arcmsr_srb_complete(srb, 1);
3500				continue;
3501			}
3502			printf("arcmsr%d: polling get an illegal srb command done srb='%p'"
3503				"srboutstandingcount=%d \n"
3504				, acb->pci_unit
3505				, srb, acb->srboutstandingcount);
3506			continue;
3507		}
3508		arcmsr_report_srb_state(acb, srb, error);
3509	}	/*drain reply FIFO*/
3510}
3511/*
3512**********************************************************************
3513**
3514**********************************************************************
3515*/
3516static void arcmsr_polling_hbb_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
3517{
3518	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
3519	struct CommandControlBlock *srb;
3520	u_int32_t flag_srb, poll_srb_done=0, poll_count=0;
3521	int index;
3522	u_int16_t	error;
3523
3524polling_ccb_retry:
3525	poll_count++;
3526	WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN); /* clear doorbell interrupt */
3527	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3528	while(1) {
3529		index = phbbmu->doneq_index;
3530		if((flag_srb = phbbmu->done_qbuffer[index]) == 0) {
3531			if(poll_srb_done) {
3532				break;/*chip FIFO no ccb for completion already*/
3533			} else {
3534				UDELAY(25000);
3535				if ((poll_count > 100) && (poll_srb != NULL)) {
3536					break;
3537				}
3538				goto polling_ccb_retry;
3539			}
3540		}
3541		phbbmu->done_qbuffer[index] = 0;
3542		index++;
3543		index %= ARCMSR_MAX_HBB_POSTQUEUE;     /*if last index number set it to 0 */
3544		phbbmu->doneq_index = index;
3545		/* check if command done with no error*/
3546		srb = (struct CommandControlBlock *)
3547			(acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
3548		error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
3549		poll_srb_done = (srb == poll_srb) ? 1:0;
3550		if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
3551			if(srb->srb_state == ARCMSR_SRB_ABORTED) {
3552				printf("arcmsr%d: scsi id=%d lun=%jx srb='%p'"
3553					"poll command abort successfully \n"
3554					, acb->pci_unit
3555					, srb->pccb->ccb_h.target_id
3556					, (uintmax_t)srb->pccb->ccb_h.target_lun, srb);
3557				srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
3558				arcmsr_srb_complete(srb, 1);
3559				continue;
3560			}
3561			printf("arcmsr%d: polling get an illegal srb command done srb='%p'"
3562				"srboutstandingcount=%d \n"
3563				, acb->pci_unit
3564				, srb, acb->srboutstandingcount);
3565			continue;
3566		}
3567		arcmsr_report_srb_state(acb, srb, error);
3568	}	/*drain reply FIFO*/
3569}
3570/*
3571**********************************************************************
3572**
3573**********************************************************************
3574*/
3575static void arcmsr_polling_hbc_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
3576{
3577	struct CommandControlBlock *srb;
3578	u_int32_t flag_srb, poll_srb_done=0, poll_count=0;
3579	u_int16_t	error;
3580
3581polling_ccb_retry:
3582	poll_count++;
3583	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3584	while(1) {
3585		if(!(CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR)) {
3586			if(poll_srb_done) {
3587				break;/*chip FIFO no ccb for completion already*/
3588			} else {
3589				UDELAY(25000);
3590				if ((poll_count > 100) && (poll_srb != NULL)) {
3591					break;
3592				}
3593				if (acb->srboutstandingcount == 0) {
3594					break;
3595				}
3596				goto polling_ccb_retry;
3597			}
3598		}
3599		flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
3600		/* check if command done with no error*/
3601		srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/
3602		error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE;
3603		if (poll_srb != NULL)
3604			poll_srb_done = (srb == poll_srb) ? 1:0;
3605		if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
3606			if(srb->srb_state == ARCMSR_SRB_ABORTED) {
3607				printf("arcmsr%d: scsi id=%d lun=%jx srb='%p'poll command abort successfully \n"
3608						, acb->pci_unit, srb->pccb->ccb_h.target_id, (uintmax_t)srb->pccb->ccb_h.target_lun, srb);
3609				srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
3610				arcmsr_srb_complete(srb, 1);
3611				continue;
3612			}
3613			printf("arcmsr%d: polling get an illegal srb command done srb='%p'srboutstandingcount=%d \n"
3614					, acb->pci_unit, srb, acb->srboutstandingcount);
3615			continue;
3616		}
3617		arcmsr_report_srb_state(acb, srb, error);
3618	}	/*drain reply FIFO*/
3619}
3620/*
3621**********************************************************************
3622**
3623**********************************************************************
3624*/
3625static void arcmsr_polling_hbd_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
3626{
3627	struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
3628	struct CommandControlBlock *srb;
3629	u_int32_t flag_srb, poll_srb_done=0, poll_count=0;
3630	u_int32_t outbound_write_pointer;
3631	u_int16_t	error, doneq_index;
3632
3633polling_ccb_retry:
3634	poll_count++;
3635	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3636	while(1) {
3637		outbound_write_pointer = phbdmu->done_qbuffer[0].addressLow;
3638		doneq_index = phbdmu->doneq_index;
3639		if ((outbound_write_pointer & 0xFF) == (doneq_index & 0xFF)) {
3640			if(poll_srb_done) {
3641				break;/*chip FIFO no ccb for completion already*/
3642			} else {
3643				UDELAY(25000);
3644				if ((poll_count > 100) && (poll_srb != NULL)) {
3645					break;
3646				}
3647				if (acb->srboutstandingcount == 0) {
3648					break;
3649				}
3650				goto polling_ccb_retry;
3651			}
3652		}
3653		doneq_index = arcmsr_get_doneq_index(phbdmu);
3654		flag_srb = phbdmu->done_qbuffer[(doneq_index & 0xFF)+1].addressLow;
3655		/* check if command done with no error*/
3656		srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/
3657		error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
3658		CHIP_REG_WRITE32(HBD_MessageUnit, 0, outboundlist_read_pointer, doneq_index);
3659		if (poll_srb != NULL)
3660			poll_srb_done = (srb == poll_srb) ? 1:0;
3661		if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
3662			if(srb->srb_state == ARCMSR_SRB_ABORTED) {
3663				printf("arcmsr%d: scsi id=%d lun=%jx srb='%p'poll command abort successfully \n"
3664						, acb->pci_unit, srb->pccb->ccb_h.target_id, (uintmax_t)srb->pccb->ccb_h.target_lun, srb);
3665				srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
3666				arcmsr_srb_complete(srb, 1);
3667				continue;
3668			}
3669			printf("arcmsr%d: polling get an illegal srb command done srb='%p'srboutstandingcount=%d \n"
3670					, acb->pci_unit, srb, acb->srboutstandingcount);
3671			continue;
3672		}
3673		arcmsr_report_srb_state(acb, srb, error);
3674	}	/*drain reply FIFO*/
3675}
3676/*
3677**********************************************************************
3678**
3679**********************************************************************
3680*/
3681static void arcmsr_polling_hbe_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
3682{
3683	struct CommandControlBlock *srb;
3684	u_int32_t poll_srb_done=0, poll_count=0, doneq_index;
3685	u_int16_t	error, cmdSMID;
3686
3687polling_ccb_retry:
3688	poll_count++;
3689	bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3690	while(1) {
3691		doneq_index = acb->doneq_index;
3692		if((CHIP_REG_READ32(HBE_MessageUnit, 0, reply_post_producer_index) & 0xFFFF) == doneq_index) {
3693			if(poll_srb_done) {
3694				break;/*chip FIFO no ccb for completion already*/
3695			} else {
3696				UDELAY(25000);
3697				if ((poll_count > 100) && (poll_srb != NULL)) {
3698					break;
3699				}
3700				if (acb->srboutstandingcount == 0) {
3701					break;
3702				}
3703				goto polling_ccb_retry;
3704			}
3705		}
3706		cmdSMID = acb->pCompletionQ[doneq_index].cmdSMID;
3707		doneq_index++;
3708		if (doneq_index >= acb->completionQ_entry)
3709			doneq_index = 0;
3710		acb->doneq_index = doneq_index;
3711		srb = acb->psrb_pool[cmdSMID];
3712		error = (acb->pCompletionQ[doneq_index].cmdFlag & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
3713		if (poll_srb != NULL)
3714			poll_srb_done = (srb == poll_srb) ? 1:0;
3715		if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
3716			if(srb->srb_state == ARCMSR_SRB_ABORTED) {
3717				printf("arcmsr%d: scsi id=%d lun=%jx srb='%p'poll command abort successfully \n"
3718						, acb->pci_unit, srb->pccb->ccb_h.target_id, (uintmax_t)srb->pccb->ccb_h.target_lun, srb);
3719				srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
3720				arcmsr_srb_complete(srb, 1);
3721				continue;
3722			}
3723			printf("arcmsr%d: polling get an illegal srb command done srb='%p'srboutstandingcount=%d \n"
3724					, acb->pci_unit, srb, acb->srboutstandingcount);
3725			continue;
3726		}
3727		arcmsr_report_srb_state(acb, srb, error);
3728	}	/*drain reply FIFO*/
3729	CHIP_REG_WRITE32(HBE_MessageUnit, 0, reply_post_producer_index, doneq_index);
3730}
3731/*
3732**********************************************************************
3733**********************************************************************
3734*/
3735static void arcmsr_polling_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
3736{
3737	switch (acb->adapter_type) {
3738	case ACB_ADAPTER_TYPE_A:
3739		arcmsr_polling_hba_srbdone(acb, poll_srb);
3740		break;
3741	case ACB_ADAPTER_TYPE_B:
3742		arcmsr_polling_hbb_srbdone(acb, poll_srb);
3743		break;
3744	case ACB_ADAPTER_TYPE_C:
3745		arcmsr_polling_hbc_srbdone(acb, poll_srb);
3746		break;
3747	case ACB_ADAPTER_TYPE_D:
3748		arcmsr_polling_hbd_srbdone(acb, poll_srb);
3749		break;
3750	case ACB_ADAPTER_TYPE_E:
3751	case ACB_ADAPTER_TYPE_F:
3752		arcmsr_polling_hbe_srbdone(acb, poll_srb);
3753		break;
3754	}
3755}
3756/*
3757**********************************************************************
3758**********************************************************************
3759*/
3760static void arcmsr_get_hba_config(struct AdapterControlBlock *acb)
3761{
3762	char *acb_firm_model = acb->firm_model;
3763	char *acb_firm_version = acb->firm_version;
3764	char *acb_device_map = acb->device_map;
3765	size_t iop_firm_model = offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);	/*firm_model,15,60-67*/
3766	size_t iop_firm_version = offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]);	/*firm_version,17,68-83*/
3767	size_t iop_device_map = offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
3768	int i;
3769
3770	CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
3771	if(!arcmsr_hba_wait_msgint_ready(acb)) {
3772		printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
3773	}
3774	i = 0;
3775	while(i < 8) {
3776		*acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i);
3777		/* 8 bytes firm_model, 15, 60-67*/
3778		acb_firm_model++;
3779		i++;
3780	}
3781	i=0;
3782	while(i < 16) {
3783		*acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i);
3784		/* 16 bytes firm_version, 17, 68-83*/
3785		acb_firm_version++;
3786		i++;
3787	}
3788	i=0;
3789	while(i < 16) {
3790		*acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i);
3791		acb_device_map++;
3792		i++;
3793	}
3794	printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
3795	acb->firm_request_len = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[1]);   /*firm_request_len, 1, 04-07*/
3796	acb->firm_numbers_queue = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/
3797	acb->firm_sdram_size = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[3]);    /*firm_sdram_size, 3, 12-15*/
3798	acb->firm_ide_channels = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[4]);  /*firm_ide_channels, 4, 16-19*/
3799	acb->firm_cfg_version = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);	/*firm_cfg_version,  25, 	  */
3800	if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
3801		acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD - 1;
3802	else
3803		acb->maxOutstanding = acb->firm_numbers_queue - 1;
3804}
3805/*
3806**********************************************************************
3807**********************************************************************
3808*/
3809static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb)
3810{
3811	struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
3812	char *acb_firm_model = acb->firm_model;
3813	char *acb_firm_version = acb->firm_version;
3814	char *acb_device_map = acb->device_map;
3815	size_t iop_firm_model = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);	/*firm_model,15,60-67*/
3816	size_t iop_firm_version = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]);	/*firm_version,17,68-83*/
3817	size_t iop_device_map = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
3818	int i;
3819
3820	WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_GET_CONFIG);
3821	if(!arcmsr_hbb_wait_msgint_ready(acb)) {
3822		printf( "arcmsr%d: wait" "'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
3823	}
3824	i = 0;
3825	while(i < 8) {
3826		*acb_firm_model = bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_firm_model+i);
3827		/* 8 bytes firm_model, 15, 60-67*/
3828		acb_firm_model++;
3829		i++;
3830	}
3831	i = 0;
3832	while(i < 16) {
3833		*acb_firm_version = bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_firm_version+i);
3834		/* 16 bytes firm_version, 17, 68-83*/
3835		acb_firm_version++;
3836		i++;
3837	}
3838	i = 0;
3839	while(i < 16) {
3840		*acb_device_map = bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_device_map+i);
3841		acb_device_map++;
3842		i++;
3843	}
3844	printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
3845	acb->firm_request_len = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[1]);   /*firm_request_len, 1, 04-07*/
3846	acb->firm_numbers_queue = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/
3847	acb->firm_sdram_size = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[3]);    /*firm_sdram_size, 3, 12-15*/
3848	acb->firm_ide_channels = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[4]);  /*firm_ide_channels, 4, 16-19*/
3849	acb->firm_cfg_version = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);	/*firm_cfg_version,  25, 	  */
3850	if(acb->firm_numbers_queue > ARCMSR_MAX_HBB_POSTQUEUE)
3851		acb->maxOutstanding = ARCMSR_MAX_HBB_POSTQUEUE - 1;
3852	else
3853		acb->maxOutstanding = acb->firm_numbers_queue - 1;
3854}
3855/*
3856**********************************************************************
3857**********************************************************************
3858*/
3859static void arcmsr_get_hbc_config(struct AdapterControlBlock *acb)
3860{
3861	char *acb_firm_model = acb->firm_model;
3862	char *acb_firm_version = acb->firm_version;
3863	char *acb_device_map = acb->device_map;
3864	size_t iop_firm_model = offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);   /*firm_model,15,60-67*/
3865	size_t iop_firm_version = offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/
3866	size_t iop_device_map = offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
3867	int i;
3868
3869	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
3870	CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
3871	if(!arcmsr_hbc_wait_msgint_ready(acb)) {
3872		printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
3873	}
3874	i = 0;
3875	while(i < 8) {
3876		*acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i);
3877		/* 8 bytes firm_model, 15, 60-67*/
3878		acb_firm_model++;
3879		i++;
3880	}
3881	i = 0;
3882	while(i < 16) {
3883		*acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i);
3884		/* 16 bytes firm_version, 17, 68-83*/
3885		acb_firm_version++;
3886		i++;
3887	}
3888	i = 0;
3889	while(i < 16) {
3890		*acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i);
3891		acb_device_map++;
3892		i++;
3893	}
3894	printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
3895	acb->firm_request_len	= CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[1]);	/*firm_request_len,   1, 04-07*/
3896	acb->firm_numbers_queue	= CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[2]);	/*firm_numbers_queue, 2, 08-11*/
3897	acb->firm_sdram_size	= CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[3]);	/*firm_sdram_size,    3, 12-15*/
3898	acb->firm_ide_channels	= CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[4]);	/*firm_ide_channels,  4, 16-19*/
3899	acb->firm_cfg_version	= CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);	/*firm_cfg_version,  25, 	  */
3900	if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
3901		acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD - 1;
3902	else
3903		acb->maxOutstanding = acb->firm_numbers_queue - 1;
3904}
3905/*
3906**********************************************************************
3907**********************************************************************
3908*/
3909static void arcmsr_get_hbd_config(struct AdapterControlBlock *acb)
3910{
3911	char *acb_firm_model = acb->firm_model;
3912	char *acb_firm_version = acb->firm_version;
3913	char *acb_device_map = acb->device_map;
3914	size_t iop_firm_model = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);   /*firm_model,15,60-67*/
3915	size_t iop_firm_version = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/
3916	size_t iop_device_map = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
3917	int i;
3918
3919	if(CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE)
3920		CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR);
3921	CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
3922	if(!arcmsr_hbd_wait_msgint_ready(acb)) {
3923		printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
3924	}
3925	i = 0;
3926	while(i < 8) {
3927		*acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i);
3928		/* 8 bytes firm_model, 15, 60-67*/
3929		acb_firm_model++;
3930		i++;
3931	}
3932	i = 0;
3933	while(i < 16) {
3934		*acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i);
3935		/* 16 bytes firm_version, 17, 68-83*/
3936		acb_firm_version++;
3937		i++;
3938	}
3939	i = 0;
3940	while(i < 16) {
3941		*acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i);
3942		acb_device_map++;
3943		i++;
3944	}
3945	printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
3946	acb->firm_request_len	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[1]);	/*firm_request_len,   1, 04-07*/
3947	acb->firm_numbers_queue	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[2]);	/*firm_numbers_queue, 2, 08-11*/
3948	acb->firm_sdram_size	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[3]);	/*firm_sdram_size,    3, 12-15*/
3949	acb->firm_ide_channels	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[4]);	/*firm_ide_channels,  4, 16-19*/
3950	acb->firm_cfg_version	= CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);	/*firm_cfg_version,  25, 	  */
3951	if(acb->firm_numbers_queue > ARCMSR_MAX_HBD_POSTQUEUE)
3952		acb->maxOutstanding = ARCMSR_MAX_HBD_POSTQUEUE - 1;
3953	else
3954		acb->maxOutstanding = acb->firm_numbers_queue - 1;
3955}
3956/*
3957**********************************************************************
3958**********************************************************************
3959*/
3960static void arcmsr_get_hbe_config(struct AdapterControlBlock *acb)
3961{
3962	char *acb_firm_model = acb->firm_model;
3963	char *acb_firm_version = acb->firm_version;
3964	char *acb_device_map = acb->device_map;
3965	size_t iop_firm_model = offsetof(struct HBE_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);   /*firm_model,15,60-67*/
3966	size_t iop_firm_version = offsetof(struct HBE_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/
3967	size_t iop_device_map = offsetof(struct HBE_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
3968	int i;
3969
3970	CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
3971	acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
3972	CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
3973	if(!arcmsr_hbe_wait_msgint_ready(acb)) {
3974		printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
3975	}
3976
3977	i = 0;
3978	while(i < 8) {
3979		*acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i);
3980		/* 8 bytes firm_model, 15, 60-67*/
3981		acb_firm_model++;
3982		i++;
3983	}
3984	i = 0;
3985	while(i < 16) {
3986		*acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i);
3987		/* 16 bytes firm_version, 17, 68-83*/
3988		acb_firm_version++;
3989		i++;
3990	}
3991	i = 0;
3992	while(i < 16) {
3993		*acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i);
3994		acb_device_map++;
3995		i++;
3996	}
3997	printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
3998	acb->firm_request_len	= CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[1]);	/*firm_request_len,   1, 04-07*/
3999	acb->firm_numbers_queue	= CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[2]);	/*firm_numbers_queue, 2, 08-11*/
4000	acb->firm_sdram_size	= CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[3]);	/*firm_sdram_size,    3, 12-15*/
4001	acb->firm_ide_channels	= CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[4]);	/*firm_ide_channels,  4, 16-19*/
4002	acb->firm_cfg_version	= CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);	/*firm_cfg_version,  25, 	  */
4003	if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
4004		acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD - 1;
4005	else
4006		acb->maxOutstanding = acb->firm_numbers_queue - 1;
4007}
4008/*
4009**********************************************************************
4010**********************************************************************
4011*/
4012static void arcmsr_get_hbf_config(struct AdapterControlBlock *acb)
4013{
4014	u_int32_t *acb_firm_model = (u_int32_t *)acb->firm_model;
4015	u_int32_t *acb_firm_version = (u_int32_t *)acb->firm_version;
4016	u_int32_t *acb_device_map = (u_int32_t *)acb->device_map;
4017	size_t iop_firm_model = ARCMSR_FW_MODEL_OFFSET;   /*firm_model,15,60-67*/
4018	size_t iop_firm_version = ARCMSR_FW_VERS_OFFSET; /*firm_version,17,68-83*/
4019	size_t iop_device_map = ARCMSR_FW_DEVMAP_OFFSET;
4020	int i;
4021
4022	CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
4023	acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
4024	CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
4025	if(!arcmsr_hbe_wait_msgint_ready(acb))
4026		printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
4027
4028	i = 0;
4029	while(i < 2) {
4030		*acb_firm_model = acb->msgcode_rwbuffer[iop_firm_model];
4031		/* 8 bytes firm_model, 15, 60-67*/
4032		acb_firm_model++;
4033		iop_firm_model++;
4034		i++;
4035	}
4036	i = 0;
4037	while(i < 4) {
4038		*acb_firm_version = acb->msgcode_rwbuffer[iop_firm_version];
4039		/* 16 bytes firm_version, 17, 68-83*/
4040		acb_firm_version++;
4041		iop_firm_version++;
4042		i++;
4043	}
4044	i = 0;
4045	while(i < 4) {
4046		*acb_device_map = acb->msgcode_rwbuffer[iop_device_map];
4047		acb_device_map++;
4048		iop_device_map++;
4049		i++;
4050	}
4051	printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
4052	acb->firm_request_len	= acb->msgcode_rwbuffer[1];	/*firm_request_len,   1, 04-07*/
4053	acb->firm_numbers_queue	= acb->msgcode_rwbuffer[2];	/*firm_numbers_queue, 2, 08-11*/
4054	acb->firm_sdram_size	= acb->msgcode_rwbuffer[3];	/*firm_sdram_size,    3, 12-15*/
4055	acb->firm_ide_channels	= acb->msgcode_rwbuffer[4];	/*firm_ide_channels,  4, 16-19*/
4056	acb->firm_cfg_version	= acb->msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]; /*firm_cfg_version,  25*/
4057	acb->firm_PicStatus	= acb->msgcode_rwbuffer[ARCMSR_FW_PICSTATUS]; /* firm_PicStatus, 30 */
4058	if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
4059		acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD - 1;
4060	else
4061		acb->maxOutstanding = acb->firm_numbers_queue - 1;
4062}
4063/*
4064**********************************************************************
4065**********************************************************************
4066*/
4067static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
4068{
4069	switch (acb->adapter_type) {
4070	case ACB_ADAPTER_TYPE_A:
4071		arcmsr_get_hba_config(acb);
4072		break;
4073	case ACB_ADAPTER_TYPE_B:
4074		arcmsr_get_hbb_config(acb);
4075		break;
4076	case ACB_ADAPTER_TYPE_C:
4077		arcmsr_get_hbc_config(acb);
4078		break;
4079	case ACB_ADAPTER_TYPE_D:
4080		arcmsr_get_hbd_config(acb);
4081		break;
4082	case ACB_ADAPTER_TYPE_E:
4083		arcmsr_get_hbe_config(acb);
4084		break;
4085	case ACB_ADAPTER_TYPE_F:
4086		arcmsr_get_hbf_config(acb);
4087		break;
4088	}
4089}
4090/*
4091**********************************************************************
4092**********************************************************************
4093*/
4094static void arcmsr_wait_firmware_ready( struct AdapterControlBlock *acb)
4095{
4096	int	timeout=0;
4097
4098	switch (acb->adapter_type) {
4099	case ACB_ADAPTER_TYPE_A: {
4100			while ((CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0)
4101			{
4102				if (timeout++ > 2000) /* (2000*15)/1000 = 30 sec */
4103				{
4104					printf( "arcmsr%d:timed out waiting for firmware \n", acb->pci_unit);
4105					return;
4106				}
4107				UDELAY(15000); /* wait 15 milli-seconds */
4108			}
4109		}
4110		break;
4111	case ACB_ADAPTER_TYPE_B: {
4112			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
4113			while ((READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell) & ARCMSR_MESSAGE_FIRMWARE_OK) == 0)
4114			{
4115				if (timeout++ > 2000) /* (2000*15)/1000 = 30 sec */
4116				{
4117					printf( "arcmsr%d: timed out waiting for firmware \n", acb->pci_unit);
4118					return;
4119				}
4120				UDELAY(15000); /* wait 15 milli-seconds */
4121			}
4122			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
4123		}
4124		break;
4125	case ACB_ADAPTER_TYPE_C: {
4126			while ((CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK) == 0)
4127			{
4128				if (timeout++ > 2000) /* (2000*15)/1000 = 30 sec */
4129				{
4130					printf( "arcmsr%d:timed out waiting for firmware ready\n", acb->pci_unit);
4131					return;
4132				}
4133				UDELAY(15000); /* wait 15 milli-seconds */
4134			}
4135		}
4136		break;
4137	case ACB_ADAPTER_TYPE_D: {
4138			while ((CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_HBDMU_MESSAGE_FIRMWARE_OK) == 0)
4139			{
4140				if (timeout++ > 2000) /* (2000*15)/1000 = 30 sec */
4141				{
4142					printf( "arcmsr%d:timed out waiting for firmware ready\n", acb->pci_unit);
4143					return;
4144				}
4145				UDELAY(15000); /* wait 15 milli-seconds */
4146			}
4147		}
4148		break;
4149	case ACB_ADAPTER_TYPE_E:
4150	case ACB_ADAPTER_TYPE_F: {
4151			while ((CHIP_REG_READ32(HBE_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_HBEMU_MESSAGE_FIRMWARE_OK) == 0)
4152			{
4153				if (timeout++ > 4000) /* (4000*15)/1000 = 60 sec */
4154				{
4155					printf( "arcmsr%d:timed out waiting for firmware ready\n", acb->pci_unit);
4156					return;
4157				}
4158				UDELAY(15000); /* wait 15 milli-seconds */
4159			}
4160		}
4161		break;
4162	}
4163}
4164/*
4165**********************************************************************
4166**********************************************************************
4167*/
4168static void arcmsr_clear_doorbell_queue_buffer( struct AdapterControlBlock *acb)
4169{
4170	u_int32_t outbound_doorbell;
4171
4172	switch (acb->adapter_type) {
4173	case ACB_ADAPTER_TYPE_A: {
4174			/* empty doorbell Qbuffer if door bell ringed */
4175			outbound_doorbell = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_doorbell);
4176			CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_doorbell, outbound_doorbell);	/*clear doorbell interrupt */
4177			CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
4178		}
4179		break;
4180	case ACB_ADAPTER_TYPE_B: {
4181			struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
4182			WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN);/*clear interrupt and message state*/
4183			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_READ_OK);
4184			/* let IOP know data has been read */
4185		}
4186		break;
4187	case ACB_ADAPTER_TYPE_C: {
4188			/* empty doorbell Qbuffer if door bell ringed */
4189			outbound_doorbell = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell);
4190			CHIP_REG_WRITE32(HBC_MessageUnit, 0, outbound_doorbell_clear, outbound_doorbell);	/*clear doorbell interrupt */
4191			CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK);
4192			CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell_clear); /* Dummy read to force pci flush */
4193			CHIP_REG_READ32(HBC_MessageUnit, 0, inbound_doorbell); /* Dummy read to force pci flush */
4194		}
4195		break;
4196	case ACB_ADAPTER_TYPE_D: {
4197			/* empty doorbell Qbuffer if door bell ringed */
4198			outbound_doorbell = CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell);
4199			CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, outbound_doorbell);	/*clear doorbell interrupt */
4200			CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_OUT_READ);
4201		}
4202		break;
4203	case ACB_ADAPTER_TYPE_E:
4204	case ACB_ADAPTER_TYPE_F: {
4205			/* empty doorbell Qbuffer if door bell ringed */
4206			acb->in_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell);
4207			CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0);	/*clear doorbell interrupt */
4208			acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_READ_OK;
4209			CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
4210		}
4211		break;
4212	}
4213}
4214/*
4215************************************************************************
4216************************************************************************
4217*/
4218static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
4219{
4220	unsigned long srb_phyaddr;
4221	u_int32_t srb_phyaddr_hi32;
4222	u_int32_t srb_phyaddr_lo32;
4223
4224	/*
4225	********************************************************************
4226	** here we need to tell iop 331 our freesrb.HighPart
4227	** if freesrb.HighPart is not zero
4228	********************************************************************
4229	*/
4230	srb_phyaddr = (unsigned long) acb->srb_phyaddr.phyaddr;
4231	srb_phyaddr_hi32 = acb->srb_phyaddr.B.phyadd_high;
4232	srb_phyaddr_lo32 = acb->srb_phyaddr.B.phyadd_low;
4233	switch (acb->adapter_type) {
4234	case ACB_ADAPTER_TYPE_A: {
4235			if(srb_phyaddr_hi32 != 0) {
4236				CHIP_REG_WRITE32(HBA_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG);
4237				CHIP_REG_WRITE32(HBA_MessageUnit, 0, msgcode_rwbuffer[1], srb_phyaddr_hi32);
4238				CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
4239				if(!arcmsr_hba_wait_msgint_ready(acb)) {
4240					printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit);
4241					return FALSE;
4242				}
4243			}
4244		}
4245		break;
4246		/*
4247		***********************************************************************
4248		**    if adapter type B, set window of "post command Q"
4249		***********************************************************************
4250		*/
4251	case ACB_ADAPTER_TYPE_B: {
4252			u_int32_t post_queue_phyaddr;
4253			struct HBB_MessageUnit *phbbmu;
4254
4255			phbbmu = (struct HBB_MessageUnit *)acb->pmu;
4256			phbbmu->postq_index = 0;
4257			phbbmu->doneq_index = 0;
4258			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_SET_POST_WINDOW);
4259			if(!arcmsr_hbb_wait_msgint_ready(acb)) {
4260				printf( "arcmsr%d: 'set window of post command Q' timeout\n", acb->pci_unit);
4261				return FALSE;
4262			}
4263			post_queue_phyaddr = srb_phyaddr + ARCMSR_SRBS_POOL_SIZE
4264								+ offsetof(struct HBB_MessageUnit, post_qbuffer);
4265			CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG); /* driver "set config" signature */
4266			CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[1], srb_phyaddr_hi32); /* normal should be zero */
4267			CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[2], post_queue_phyaddr); /* postQ size (256+8)*4 */
4268			CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[3], post_queue_phyaddr+1056); /* doneQ size (256+8)*4 */
4269			CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[4], 1056); /* srb maxQ size must be --> [(256+8)*4] */
4270			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_SET_CONFIG);
4271			if(!arcmsr_hbb_wait_msgint_ready(acb)) {
4272				printf( "arcmsr%d: 'set command Q window' timeout \n", acb->pci_unit);
4273				return FALSE;
4274			}
4275			WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_START_DRIVER_MODE);
4276			if(!arcmsr_hbb_wait_msgint_ready(acb)) {
4277				printf( "arcmsr%d: 'start diver mode' timeout \n", acb->pci_unit);
4278				return FALSE;
4279			}
4280		}
4281		break;
4282	case ACB_ADAPTER_TYPE_C: {
4283			if(srb_phyaddr_hi32 != 0) {
4284				CHIP_REG_WRITE32(HBC_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG);
4285				CHIP_REG_WRITE32(HBC_MessageUnit, 0, msgcode_rwbuffer[1], srb_phyaddr_hi32);
4286				CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
4287				CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell,ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
4288				if(!arcmsr_hbc_wait_msgint_ready(acb)) {
4289					printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit);
4290					return FALSE;
4291				}
4292			}
4293		}
4294		break;
4295	case ACB_ADAPTER_TYPE_D: {
4296			u_int32_t post_queue_phyaddr, done_queue_phyaddr;
4297			struct HBD_MessageUnit0 *phbdmu;
4298
4299			phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
4300			phbdmu->postq_index = 0;
4301			phbdmu->doneq_index = 0x40FF;
4302			post_queue_phyaddr = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE
4303								+ offsetof(struct HBD_MessageUnit0, post_qbuffer);
4304			done_queue_phyaddr = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE
4305								+ offsetof(struct HBD_MessageUnit0, done_qbuffer);
4306			CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG); /* driver "set config" signature */
4307			CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[1], srb_phyaddr_hi32);
4308			CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[2], post_queue_phyaddr); /* postQ base */
4309			CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[3], done_queue_phyaddr); /* doneQ base */
4310			CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[4], 0x100);
4311			CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
4312			if(!arcmsr_hbd_wait_msgint_ready(acb)) {
4313				printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit);
4314				return FALSE;
4315			}
4316		}
4317		break;
4318	case ACB_ADAPTER_TYPE_E: {
4319			u_int32_t cdb_phyaddr_lo32;
4320			cdb_phyaddr_lo32 = srb_phyaddr_lo32 + offsetof(struct CommandControlBlock, arcmsr_cdb);
4321			CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG);
4322			CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[1], ARCMSR_SIGNATURE_1884);
4323			CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[2], cdb_phyaddr_lo32);
4324			CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[3], srb_phyaddr_hi32);
4325			CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[4], SRB_SIZE);
4326			cdb_phyaddr_lo32 = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE;
4327			CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[5], cdb_phyaddr_lo32);
4328			CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[6], srb_phyaddr_hi32);
4329			CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[7], COMPLETION_Q_POOL_SIZE);
4330			CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
4331			acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
4332			CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
4333			if(!arcmsr_hbe_wait_msgint_ready(acb)) {
4334				printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit);
4335				return FALSE;
4336			}
4337		}
4338		break;
4339	case ACB_ADAPTER_TYPE_F: {
4340			u_int32_t cdb_phyaddr_lo32;
4341			cdb_phyaddr_lo32 = srb_phyaddr_lo32 + offsetof(struct CommandControlBlock, arcmsr_cdb);
4342			acb->msgcode_rwbuffer[0] = ARCMSR_SIGNATURE_SET_CONFIG;
4343			acb->msgcode_rwbuffer[1] = ARCMSR_SIGNATURE_1886;
4344			acb->msgcode_rwbuffer[2] = cdb_phyaddr_lo32;
4345			acb->msgcode_rwbuffer[3] = srb_phyaddr_hi32;
4346			acb->msgcode_rwbuffer[4] = SRB_SIZE;
4347			cdb_phyaddr_lo32 = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE;
4348			acb->msgcode_rwbuffer[5] = cdb_phyaddr_lo32;
4349			acb->msgcode_rwbuffer[6] = srb_phyaddr_hi32;
4350			acb->msgcode_rwbuffer[7] = COMPLETION_Q_POOL_SIZE;
4351			if (acb->xor_mega) {
4352				acb->msgcode_rwbuffer[8] = 0x555AA;	//FreeBSD init 2
4353				acb->msgcode_rwbuffer[9] = 0;
4354				acb->msgcode_rwbuffer[10] = (uint32_t)acb->xor_sgtable_phy;
4355				acb->msgcode_rwbuffer[11] = (uint32_t)((acb->xor_sgtable_phy >> 16) >> 16);
4356			}
4357			CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
4358			acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
4359			CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
4360			if(!arcmsr_hbe_wait_msgint_ready(acb)) {
4361				printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit);
4362				return FALSE;
4363			}
4364		}
4365		break;
4366	}
4367	return (TRUE);
4368}
4369/*
4370************************************************************************
4371************************************************************************
4372*/
4373static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb)
4374{
4375	if (acb->adapter_type == ACB_ADAPTER_TYPE_B)
4376	{
4377		struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
4378		WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_ACTIVE_EOI_MODE);
4379		if(!arcmsr_hbb_wait_msgint_ready(acb)) {
4380			printf( "arcmsr%d: 'iop enable eoi mode' timeout \n", acb->pci_unit);
4381			return;
4382		}
4383	}
4384}
4385/*
4386**********************************************************************
4387**********************************************************************
4388*/
4389static void arcmsr_iop_init(struct AdapterControlBlock *acb)
4390{
4391	u_int32_t intmask_org;
4392
4393	/* disable all outbound interrupt */
4394	intmask_org = arcmsr_disable_allintr(acb);
4395	arcmsr_wait_firmware_ready(acb);
4396	arcmsr_iop_confirm(acb);
4397	arcmsr_get_firmware_spec(acb);
4398	/*start background rebuild*/
4399	arcmsr_start_adapter_bgrb(acb);
4400	/* empty doorbell Qbuffer if door bell ringed */
4401	arcmsr_clear_doorbell_queue_buffer(acb);
4402	arcmsr_enable_eoi_mode(acb);
4403	/* enable outbound Post Queue, outbound doorbell Interrupt */
4404	arcmsr_enable_allintr(acb, intmask_org);
4405	acb->acb_flags |= ACB_F_IOP_INITED;
4406}
4407/*
4408**********************************************************************
4409**********************************************************************
4410*/
4411static void arcmsr_map_free_srb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
4412{
4413	struct AdapterControlBlock *acb = arg;
4414	struct CommandControlBlock *srb_tmp;
4415	u_int32_t i;
4416	unsigned long srb_phyaddr = (unsigned long)segs->ds_addr;
4417
4418	acb->srb_phyaddr.phyaddr = srb_phyaddr;
4419	srb_tmp = (struct CommandControlBlock *)acb->uncacheptr;
4420	for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) {
4421		if(bus_dmamap_create(acb->dm_segs_dmat,
4422			 /*flags*/0, &srb_tmp->dm_segs_dmamap) != 0) {
4423			acb->acb_flags |= ACB_F_MAPFREESRB_FAILD;
4424			printf("arcmsr%d:"
4425			" srb dmamap bus_dmamap_create error\n", acb->pci_unit);
4426			return;
4427		}
4428		if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D)
4429			 || (acb->adapter_type == ACB_ADAPTER_TYPE_E) || (acb->adapter_type == ACB_ADAPTER_TYPE_F))
4430		{
4431			srb_tmp->cdb_phyaddr = srb_phyaddr;
4432		}
4433		else
4434			srb_tmp->cdb_phyaddr = srb_phyaddr >> 5;
4435		srb_tmp->acb = acb;
4436		srb_tmp->smid = i << 16;
4437		acb->srbworkingQ[i] = acb->psrb_pool[i] = srb_tmp;
4438		srb_phyaddr = srb_phyaddr + SRB_SIZE;
4439		srb_tmp = (struct CommandControlBlock *)((unsigned long)srb_tmp + SRB_SIZE);
4440	}
4441	srb_tmp = (struct CommandControlBlock *)(acb->uncacheptr + ARCMSR_SRBS_POOL_SIZE);
4442	srb_phyaddr = (unsigned long)segs->ds_addr + ARCMSR_SRBS_POOL_SIZE;
4443	switch (acb->adapter_type) {
4444	case ACB_ADAPTER_TYPE_B: {
4445		struct HBB_MessageUnit *phbbmu;
4446
4447		acb->pmu = (struct MessageUnit_UNION *)srb_tmp;
4448		phbbmu = (struct HBB_MessageUnit *)acb->pmu;
4449		phbbmu->hbb_doorbell = (struct HBB_DOORBELL *)acb->mem_base0;
4450		phbbmu->hbb_rwbuffer = (struct HBB_RWBUFFER *)acb->mem_base1;
4451		if (acb->vendor_device_id == PCIDevVenIDARC1203) {
4452			phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell);
4453			phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell_mask);
4454			phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell);
4455			phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell_mask);
4456		} else {
4457			phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL, drv2iop_doorbell);
4458			phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL, drv2iop_doorbell_mask);
4459			phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL, iop2drv_doorbell);
4460			phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL, iop2drv_doorbell_mask);
4461		}
4462		}
4463		break;
4464	case ACB_ADAPTER_TYPE_D:
4465		acb->pmu = (struct MessageUnit_UNION *)srb_tmp;
4466		acb->pmu->muu.hbdmu.phbdmu = (struct HBD_MessageUnit *)acb->mem_base0;
4467		break;
4468	case ACB_ADAPTER_TYPE_E:
4469		acb->pCompletionQ = (pCompletion_Q)srb_tmp;
4470		break;
4471	case ACB_ADAPTER_TYPE_F: {
4472		unsigned long	host_buffer_dma;
4473		acb->pCompletionQ = (pCompletion_Q)srb_tmp;
4474		acb->completeQ_phys = srb_phyaddr;
4475		memset(acb->pCompletionQ, 0xff, COMPLETION_Q_POOL_SIZE);
4476		acb->message_wbuffer = (u_int32_t *)((unsigned long)acb->pCompletionQ + COMPLETION_Q_POOL_SIZE);
4477		acb->message_rbuffer = (u_int32_t *)((unsigned long)acb->message_wbuffer + 0x100);
4478		acb->msgcode_rwbuffer = (u_int32_t *)((unsigned long)acb->message_wbuffer + 0x200);
4479		memset((void *)acb->message_wbuffer, 0, MESG_RW_BUFFER_SIZE);
4480		arcmsr_wait_firmware_ready(acb);
4481		host_buffer_dma = acb->completeQ_phys + COMPLETION_Q_POOL_SIZE;
4482		CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, (u_int32_t)(host_buffer_dma | 1));  /* host buffer low addr, bit0:1 all buffer active */
4483		CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr1, (u_int32_t)((host_buffer_dma >> 16) >> 16));/* host buffer high addr */
4484		CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, ARCMSR_HBFMU_DOORBELL_SYNC1);       /* set host buffer physical address */
4485		acb->firm_PicStatus = CHIP_REG_READ32(HBF_MessageUnit, 0, outbound_msgaddr1);	/* get firmware spec info */
4486		break;
4487		}
4488	}
4489	acb->vir2phy_offset = (unsigned long)srb_tmp - (unsigned long)srb_phyaddr;
4490}
4491
4492static void arcmsr_map_xor_sgtable(void *arg, bus_dma_segment_t *segs, int nseg, int error)
4493{
4494	struct AdapterControlBlock *acb = arg;
4495
4496	acb->xor_sgtable_phy = (unsigned long)segs->ds_addr;
4497	if ((nseg != 1) || ((u_int32_t)segs->ds_len != acb->init2cfg_size)) {
4498		acb->acb_flags |= ACB_F_MAPXOR_FAILD;
4499		printf("arcmsr%d: alloc xor table seg num or size not as i wish!\n", acb->pci_unit);
4500		return;
4501	}
4502}
4503
4504static void arcmsr_map_xor_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
4505{
4506	struct AdapterControlBlock *acb = arg;
4507	int	i;
4508	struct HostRamBuf *pRamBuf;
4509	struct XorSg *pxortable = (struct XorSg *)(acb->xortable + sizeof(struct HostRamBuf));
4510
4511	if (nseg != acb->xor_mega) {
4512		acb->acb_flags |= ACB_F_MAPXOR_FAILD;
4513		printf("arcmsr%d: alloc xor seg NUM not as i wish!\n", acb->pci_unit);
4514		return;
4515	}
4516	for (i = 0; i < nseg; i++) {
4517		if ((u_int32_t)segs->ds_len != ARCMSR_XOR_SEG_SIZE) {
4518			acb->acb_flags |= ACB_F_MAPXOR_FAILD;
4519			printf("arcmsr%d: alloc xor seg SIZE not as i wish!\n", acb->pci_unit);
4520			return;
4521		}
4522		pxortable->xorPhys = (u_int64_t)segs->ds_addr;
4523		pxortable->xorBufLen = (u_int64_t)segs->ds_len;
4524		pxortable++;
4525		segs++;
4526	}
4527	pRamBuf = (struct HostRamBuf *)acb->xortable;
4528	pRamBuf->hrbSignature = 0x53425248;	//HRBS
4529	pRamBuf->hrbSize = ARCMSR_XOR_SEG_SIZE * nseg;
4530	pRamBuf->hrbRes[0] = 0;
4531	pRamBuf->hrbRes[1] = 0;
4532	bus_dmamap_sync(acb->xortable_dmat, acb->xortable_dmamap, BUS_DMASYNC_PREREAD);
4533	bus_dmamap_sync(acb->xor_dmat, acb->xor_dmamap, BUS_DMASYNC_PREWRITE);
4534}
4535
4536/*
4537************************************************************************
4538************************************************************************
4539*/
4540static void arcmsr_free_resource(struct AdapterControlBlock *acb)
4541{
4542	/* remove the control device */
4543	if(acb->ioctl_dev != NULL) {
4544		destroy_dev(acb->ioctl_dev);
4545	}
4546	if (acb->acb_flags & ACB_F_DMAMAP_SG)
4547		bus_dmamap_unload(acb->xor_dmat, acb->xor_dmamap);
4548	if (acb->xor_dmamap) {
4549		bus_dmamem_free(acb->xor_dmat, acb->xorptr, acb->xor_dmamap);
4550	}
4551	if (acb->acb_flags & ACB_F_DMAMAP_SGTABLE)
4552		bus_dmamap_unload(acb->xortable_dmat, acb->xortable_dmamap);
4553	if (acb->xortable_dmamap) {
4554		bus_dmamem_free(acb->xortable_dmat, acb->xortable, acb->xortable_dmamap);
4555	}
4556	if (acb->acb_flags & ACB_F_DMAMAP_SRB)
4557		bus_dmamap_unload(acb->srb_dmat, acb->srb_dmamap);
4558	if (acb->srb_dmamap) {
4559		bus_dmamem_free(acb->srb_dmat, acb->uncacheptr, acb->srb_dmamap);
4560	}
4561	if (acb->srb_dmat)
4562		bus_dma_tag_destroy(acb->srb_dmat);
4563	if (acb->dm_segs_dmat)
4564		bus_dma_tag_destroy(acb->dm_segs_dmat);
4565	if (acb->parent_dmat)
4566		bus_dma_tag_destroy(acb->parent_dmat);
4567	switch(acb->adapter_type) {
4568		case ACB_ADAPTER_TYPE_A:
4569			if (acb->sys_res_arcmsr[0])
4570				bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(0), acb->sys_res_arcmsr[0]);
4571			break;
4572		case ACB_ADAPTER_TYPE_B:
4573			if (acb->sys_res_arcmsr[0])
4574				bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(0), acb->sys_res_arcmsr[0]);
4575			if (acb->sys_res_arcmsr[1])
4576				bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(2), acb->sys_res_arcmsr[1]);
4577			break;
4578		case ACB_ADAPTER_TYPE_C:
4579			if (acb->sys_res_arcmsr[0])
4580				bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(1), acb->sys_res_arcmsr[0]);
4581			break;
4582		case ACB_ADAPTER_TYPE_D:
4583			if (acb->sys_res_arcmsr[0])
4584				bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(0), acb->sys_res_arcmsr[0]);
4585			break;
4586		case ACB_ADAPTER_TYPE_E:
4587			if (acb->sys_res_arcmsr[0])
4588				bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(1), acb->sys_res_arcmsr[0]);
4589			break;
4590		case ACB_ADAPTER_TYPE_F:
4591			if (acb->sys_res_arcmsr[0])
4592				bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(0), acb->sys_res_arcmsr[0]);
4593			break;
4594	}
4595}
4596/*
4597************************************************************************
4598************************************************************************
4599*/
4600static void arcmsr_mutex_init(struct AdapterControlBlock *acb)
4601{
4602	ARCMSR_LOCK_INIT(&acb->isr_lock, "arcmsr isr lock");
4603	ARCMSR_LOCK_INIT(&acb->srb_lock, "arcmsr srb lock");
4604	ARCMSR_LOCK_INIT(&acb->postDone_lock, "arcmsr postQ lock");
4605	ARCMSR_LOCK_INIT(&acb->qbuffer_lock, "arcmsr RW buffer lock");
4606}
4607/*
4608************************************************************************
4609************************************************************************
4610*/
4611static void arcmsr_mutex_destroy(struct AdapterControlBlock *acb)
4612{
4613	ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock);
4614	ARCMSR_LOCK_DESTROY(&acb->postDone_lock);
4615	ARCMSR_LOCK_DESTROY(&acb->srb_lock);
4616	ARCMSR_LOCK_DESTROY(&acb->isr_lock);
4617}
4618/*
4619************************************************************************
4620************************************************************************
4621*/
4622static int arcmsr_define_adapter_type(struct AdapterControlBlock *acb)
4623{
4624	int rc = 0;
4625
4626	switch (acb->vendor_device_id) {
4627		case PCIDevVenIDARC1880:
4628		case PCIDevVenIDARC1882:
4629		case PCIDevVenIDARC1883:
4630		case PCIDevVenIDARC1213:
4631		case PCIDevVenIDARC1223: {
4632			acb->adapter_type = ACB_ADAPTER_TYPE_C;
4633			if ((acb->sub_device_id == ARECA_SUB_DEV_ID_1883) ||
4634			    (acb->sub_device_id == ARECA_SUB_DEV_ID_1216) ||
4635			    (acb->sub_device_id == ARECA_SUB_DEV_ID_1226))
4636				acb->adapter_bus_speed = ACB_BUS_SPEED_12G;
4637			else
4638				acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
4639			acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE;
4640			}
4641			break;
4642		case PCIDevVenIDARC1884:
4643			acb->adapter_type = ACB_ADAPTER_TYPE_E;
4644			acb->adapter_bus_speed = ACB_BUS_SPEED_12G;
4645			acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + COMPLETION_Q_POOL_SIZE;
4646			acb->completionQ_entry = COMPLETION_Q_POOL_SIZE / sizeof(struct deliver_completeQ);
4647			break;
4648		case PCIDevVenIDARC1886_0:
4649		case PCIDevVenIDARC1886_:
4650		case PCIDevVenIDARC1886:
4651			acb->adapter_type = ACB_ADAPTER_TYPE_F;
4652			acb->adapter_bus_speed = ACB_BUS_SPEED_12G;
4653			acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + COMPLETION_Q_POOL_SIZE + MESG_RW_BUFFER_SIZE;
4654			acb->completionQ_entry = COMPLETION_Q_POOL_SIZE / sizeof(struct deliver_completeQ);
4655			break;
4656		case PCIDevVenIDARC1214:
4657		case PCIDevVenIDARC1224: {
4658			acb->adapter_type = ACB_ADAPTER_TYPE_D;
4659			acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
4660			acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBD_MessageUnit0));
4661			}
4662			break;
4663		case PCIDevVenIDARC1200:
4664		case PCIDevVenIDARC1201: {
4665			acb->adapter_type = ACB_ADAPTER_TYPE_B;
4666			acb->adapter_bus_speed = ACB_BUS_SPEED_3G;
4667			acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit));
4668			}
4669			break;
4670		case PCIDevVenIDARC1203: {
4671			acb->adapter_type = ACB_ADAPTER_TYPE_B;
4672			acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
4673			acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit));
4674			}
4675			break;
4676		case PCIDevVenIDARC1110:
4677		case PCIDevVenIDARC1120:
4678		case PCIDevVenIDARC1130:
4679		case PCIDevVenIDARC1160:
4680		case PCIDevVenIDARC1170:
4681		case PCIDevVenIDARC1210:
4682		case PCIDevVenIDARC1220:
4683		case PCIDevVenIDARC1230:
4684		case PCIDevVenIDARC1231:
4685		case PCIDevVenIDARC1260:
4686		case PCIDevVenIDARC1261:
4687		case PCIDevVenIDARC1270:
4688		case PCIDevVenIDARC1280:
4689		case PCIDevVenIDARC1212:
4690		case PCIDevVenIDARC1222:
4691		case PCIDevVenIDARC1380:
4692		case PCIDevVenIDARC1381:
4693		case PCIDevVenIDARC1680:
4694		case PCIDevVenIDARC1681: {
4695			acb->adapter_type = ACB_ADAPTER_TYPE_A;
4696			acb->adapter_bus_speed = ACB_BUS_SPEED_3G;
4697			acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE;
4698			}
4699			break;
4700		default: {
4701			printf("arcmsr%d:"
4702			" unknown RAID adapter type \n", acb->pci_unit);
4703			rc = ENOMEM;
4704		}
4705	}
4706	return rc;
4707}
4708
4709static int arcmsr_map_pcireg(device_t dev, struct AdapterControlBlock *acb)
4710{
4711	switch(acb->adapter_type) {
4712	case ACB_ADAPTER_TYPE_A: {
4713		u_int32_t rid0 = PCIR_BAR(0);
4714		vm_offset_t	mem_base0;
4715
4716		acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid0, RF_ACTIVE);
4717		if(acb->sys_res_arcmsr[0] == NULL) {
4718			arcmsr_free_resource(acb);
4719			printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit);
4720			return ENOMEM;
4721		}
4722		if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
4723			arcmsr_free_resource(acb);
4724			printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit);
4725			return ENXIO;
4726		}
4727		mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
4728		if(mem_base0 == 0) {
4729			arcmsr_free_resource(acb);
4730			printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit);
4731			return ENXIO;
4732		}
4733		acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
4734		acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]);
4735		acb->pmu = (struct MessageUnit_UNION *)mem_base0;
4736		acb->rid[0] = rid0;
4737		}
4738		break;
4739	case ACB_ADAPTER_TYPE_B: {
4740		u_int32_t rid[]={ PCIR_BAR(0), PCIR_BAR(2) };
4741		vm_offset_t	mem_base[]={0,0};
4742		u_int16_t i;
4743
4744		for(i=0; i < 2; i++) {
4745			acb->sys_res_arcmsr[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid[i], RF_ACTIVE);
4746			if(acb->sys_res_arcmsr[i] == NULL) {
4747				arcmsr_free_resource(acb);
4748				printf("arcmsr%d: bus_alloc_resource %d failure!\n", acb->pci_unit, i);
4749				return ENOMEM;
4750			}
4751			if(rman_get_start(acb->sys_res_arcmsr[i]) <= 0) {
4752				arcmsr_free_resource(acb);
4753				printf("arcmsr%d: rman_get_start %d failure!\n", acb->pci_unit, i);
4754				return ENXIO;
4755			}
4756			mem_base[i] = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[i]);
4757			if(mem_base[i] == 0) {
4758				arcmsr_free_resource(acb);
4759				printf("arcmsr%d: rman_get_virtual %d failure!\n", acb->pci_unit, i);
4760				return ENXIO;
4761			}
4762			acb->btag[i] = rman_get_bustag(acb->sys_res_arcmsr[i]);
4763			acb->bhandle[i] = rman_get_bushandle(acb->sys_res_arcmsr[i]);
4764		}
4765		acb->mem_base0 = mem_base[0];
4766		acb->mem_base1 = mem_base[1];
4767		acb->rid[0] = rid[0];
4768		acb->rid[1] = rid[1];
4769		}
4770		break;
4771	case ACB_ADAPTER_TYPE_C: {
4772		u_int32_t rid0 = PCIR_BAR(1);
4773		vm_offset_t	mem_base0;
4774
4775		acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE);
4776		if(acb->sys_res_arcmsr[0] == NULL) {
4777			arcmsr_free_resource(acb);
4778			printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit);
4779			return ENOMEM;
4780		}
4781		if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
4782			arcmsr_free_resource(acb);
4783			printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit);
4784			return ENXIO;
4785		}
4786		mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
4787		if(mem_base0 == 0) {
4788			arcmsr_free_resource(acb);
4789			printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit);
4790			return ENXIO;
4791		}
4792		acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
4793		acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]);
4794		acb->pmu = (struct MessageUnit_UNION *)mem_base0;
4795		acb->rid[0] = rid0;
4796		}
4797		break;
4798	case ACB_ADAPTER_TYPE_D: {
4799		u_int32_t rid0 = PCIR_BAR(0);
4800		vm_offset_t	mem_base0;
4801
4802		acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE);
4803		if(acb->sys_res_arcmsr[0] == NULL) {
4804			arcmsr_free_resource(acb);
4805			printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit);
4806			return ENOMEM;
4807		}
4808		if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
4809			arcmsr_free_resource(acb);
4810			printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit);
4811			return ENXIO;
4812		}
4813		mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
4814		if(mem_base0 == 0) {
4815			arcmsr_free_resource(acb);
4816			printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit);
4817			return ENXIO;
4818		}
4819		acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
4820		acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]);
4821		acb->mem_base0 = mem_base0;
4822		acb->rid[0] = rid0;
4823		}
4824		break;
4825	case ACB_ADAPTER_TYPE_E: {
4826		u_int32_t rid0 = PCIR_BAR(1);
4827		vm_offset_t	mem_base0;
4828
4829		acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE);
4830		if(acb->sys_res_arcmsr[0] == NULL) {
4831			arcmsr_free_resource(acb);
4832			printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit);
4833			return ENOMEM;
4834		}
4835		if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
4836			arcmsr_free_resource(acb);
4837			printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit);
4838			return ENXIO;
4839		}
4840		mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
4841		if(mem_base0 == 0) {
4842			arcmsr_free_resource(acb);
4843			printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit);
4844			return ENXIO;
4845		}
4846		acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
4847		acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]);
4848		acb->pmu = (struct MessageUnit_UNION *)mem_base0;
4849		acb->doneq_index = 0;
4850		acb->in_doorbell = 0;
4851		acb->out_doorbell = 0;
4852		acb->rid[0] = rid0;
4853		CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0); /*clear interrupt*/
4854		CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, ARCMSR_HBEMU_DOORBELL_SYNC); /* synchronize doorbell to 0 */
4855		}
4856		break;
4857	case ACB_ADAPTER_TYPE_F: {
4858		u_int32_t rid0 = PCIR_BAR(0);
4859		vm_offset_t	mem_base0;
4860
4861		acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE);
4862		if(acb->sys_res_arcmsr[0] == NULL) {
4863			arcmsr_free_resource(acb);
4864			printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit);
4865			return ENOMEM;
4866		}
4867		if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
4868			arcmsr_free_resource(acb);
4869			printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit);
4870			return ENXIO;
4871		}
4872		mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
4873		if(mem_base0 == 0) {
4874			arcmsr_free_resource(acb);
4875			printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit);
4876			return ENXIO;
4877		}
4878		acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
4879		acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]);
4880		acb->pmu = (struct MessageUnit_UNION *)mem_base0;
4881		acb->doneq_index = 0;
4882		acb->in_doorbell = 0;
4883		acb->out_doorbell = 0;
4884		acb->rid[0] = rid0;
4885		CHIP_REG_WRITE32(HBF_MessageUnit, 0, host_int_status, 0); /*clear interrupt*/
4886		CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, ARCMSR_HBEMU_DOORBELL_SYNC); /* synchronize doorbell to 0 */
4887		}
4888		break;
4889	}
4890	return (0);
4891}
4892
4893static int arcmsr_alloc_srb(device_t dev, struct AdapterControlBlock *acb)
4894{
4895	int rc;
4896
4897	if(bus_dma_tag_create(  /*PCI parent*/		bus_get_dma_tag(dev),
4898				/*alignemnt*/		1,
4899				/*boundary*/		0,
4900				/*lowaddr*/		BUS_SPACE_MAXADDR,
4901				/*highaddr*/		BUS_SPACE_MAXADDR,
4902				/*filter*/		NULL,
4903				/*filterarg*/		NULL,
4904				/*maxsize*/		BUS_SPACE_MAXSIZE_32BIT,
4905				/*nsegments*/		BUS_SPACE_UNRESTRICTED,
4906				/*maxsegsz*/		BUS_SPACE_MAXSIZE_32BIT,
4907				/*flags*/		0,
4908				/*lockfunc*/		NULL,
4909				/*lockarg*/		NULL,
4910							&acb->parent_dmat) != 0)
4911	{
4912		printf("arcmsr%d: parent_dmat bus_dma_tag_create failure!\n", acb->pci_unit);
4913		return ENOMEM;
4914	}
4915
4916	/* Create a single tag describing a region large enough to hold all of the s/g lists we will need. */
4917	if(bus_dma_tag_create(  /*parent_dmat*/		acb->parent_dmat,
4918				/*alignment*/		1,
4919				/*boundary*/		0,
4920#ifdef PAE
4921				/*lowaddr*/		BUS_SPACE_MAXADDR_32BIT,
4922#else
4923				/*lowaddr*/		BUS_SPACE_MAXADDR,
4924#endif
4925				/*highaddr*/		BUS_SPACE_MAXADDR,
4926				/*filter*/		NULL,
4927				/*filterarg*/		NULL,
4928				/*maxsize*/		ARCMSR_MAX_SG_ENTRIES * PAGE_SIZE * ARCMSR_MAX_FREESRB_NUM,
4929				/*nsegments*/		ARCMSR_MAX_SG_ENTRIES,
4930				/*maxsegsz*/		BUS_SPACE_MAXSIZE_32BIT,
4931				/*flags*/		0,
4932				/*lockfunc*/		busdma_lock_mutex,
4933				/*lockarg*/		&acb->isr_lock,
4934							&acb->dm_segs_dmat) != 0)
4935	{
4936		arcmsr_free_resource(acb);
4937		printf("arcmsr%d: dm_segs_dmat bus_dma_tag_create failure!\n", acb->pci_unit);
4938		return ENOMEM;
4939	}
4940
4941	/* DMA tag for our srb structures.... Allocate the freesrb memory */
4942	if(bus_dma_tag_create(  /*parent_dmat*/		acb->parent_dmat,
4943				/*alignment*/		0x20,
4944				/*boundary*/		0,
4945				/*lowaddr*/		BUS_SPACE_MAXADDR_32BIT,
4946				/*highaddr*/		BUS_SPACE_MAXADDR,
4947				/*filter*/		NULL,
4948				/*filterarg*/		NULL,
4949				/*maxsize*/		acb->max_coherent_size,
4950				/*nsegments*/		1,
4951				/*maxsegsz*/		BUS_SPACE_MAXSIZE_32BIT,
4952				/*flags*/		0,
4953				/*lockfunc*/		NULL,
4954				/*lockarg*/		NULL,
4955							&acb->srb_dmat) != 0)
4956	{
4957		arcmsr_free_resource(acb);
4958		printf("arcmsr%d: srb_dmat bus_dma_tag_create failure!\n", acb->pci_unit);
4959		return ENXIO;
4960	}
4961	/* Allocation for our srbs */
4962	if(bus_dmamem_alloc(acb->srb_dmat, (void **)&acb->uncacheptr, ARCMSR_DMA_ALLOC_FLAG, &acb->srb_dmamap) != 0) {
4963		arcmsr_free_resource(acb);
4964		printf("arcmsr%d: srb_dmat bus_dmamem_alloc failure!\n", acb->pci_unit);
4965		return ENXIO;
4966	}
4967	/* And permanently map them */
4968	rc = bus_dmamap_load(acb->srb_dmat, acb->srb_dmamap, acb->uncacheptr, acb->max_coherent_size, arcmsr_map_free_srb, acb, /*flags*/0);
4969	if((rc != 0) && (rc != EINPROGRESS)) {
4970		arcmsr_free_resource(acb);
4971		printf("arcmsr%d: srb_dmat bus_dmamap_load failure!\n", acb->pci_unit);
4972		return ENXIO;
4973	}
4974	acb->acb_flags |= ACB_F_DMAMAP_SRB;
4975	return (0);
4976}
4977
4978static int arcmsr_alloc_xor_mem(device_t dev, struct AdapterControlBlock *acb)
4979{
4980	int rc, xor_ram;
4981
4982	xor_ram = (acb->firm_PicStatus >> 24) & 0x0f;
4983	acb->xor_mega = (xor_ram - 1) * 32 + 128 + 3;
4984	acb->init2cfg_size = sizeof(struct HostRamBuf) + (sizeof(struct XorSg) * acb->xor_mega);
4985	/* DMA tag for XOR engine of Raid 5,6 */
4986	if(bus_dma_tag_create(  /*parent_dmat*/		acb->parent_dmat,
4987				/*alignment*/		0x40,
4988				/*boundary*/		0,
4989				/*lowaddr*/		BUS_SPACE_MAXADDR_32BIT,
4990				/*highaddr*/		BUS_SPACE_MAXADDR,
4991				/*filter*/		NULL,
4992				/*filterarg*/		NULL,
4993				/*maxsize*/		acb->init2cfg_size,
4994				/*nsegments*/		1,
4995				/*maxsegsz*/		acb->init2cfg_size,
4996				/*flags*/		0,
4997				/*lockfunc*/		NULL,
4998				/*lockarg*/		NULL,
4999							&acb->xortable_dmat) != 0)
5000	{
5001		arcmsr_free_resource(acb);
5002		printf("arcmsr%d: xor table bus_dma_tag_create failure!\n", acb->pci_unit);
5003		return ENXIO;
5004	}
5005	/* Allocation for xors */
5006	if(bus_dmamem_alloc(acb->xortable_dmat, (void **)&acb->xortable, ARCMSR_DMA_ALLOC_FLAG, &acb->xortable_dmamap) != 0) {
5007		arcmsr_free_resource(acb);
5008		printf("arcmsr%d: xor table bus_dmamem_alloc failure!\n", acb->pci_unit);
5009		return ENXIO;
5010	}
5011	/* And permanently map xor segs */
5012	rc = bus_dmamap_load(acb->xortable_dmat, acb->xortable_dmamap, acb->xortable, acb->init2cfg_size, arcmsr_map_xor_sgtable, acb, /*flags*/0);
5013	if((rc != 0) && (rc != EINPROGRESS)) {
5014		arcmsr_free_resource(acb);
5015		printf("arcmsr%d: xor table bus_dmamap_load failure!\n", acb->pci_unit);
5016		return ENXIO;
5017	}
5018	acb->acb_flags |= ACB_F_DMAMAP_SGTABLE;
5019
5020	/* DMA tag for XOR engine of Raid 5,6 */
5021	if(bus_dma_tag_create(  /*parent_dmat*/		acb->parent_dmat,
5022				/*alignment*/		0x1000,
5023				/*boundary*/		0,
5024				/*lowaddr*/		BUS_SPACE_MAXADDR_32BIT,
5025				/*highaddr*/		BUS_SPACE_MAXADDR,
5026				/*filter*/		NULL,
5027				/*filterarg*/		NULL,
5028				/*maxsize*/		(ARCMSR_XOR_SEG_SIZE * acb->xor_mega),
5029				/*nsegments*/		acb->xor_mega,
5030				/*maxsegsz*/		ARCMSR_XOR_SEG_SIZE,
5031				/*flags*/		0,
5032				/*lockfunc*/		NULL,
5033				/*lockarg*/		NULL,
5034							&acb->xor_dmat) != 0)
5035	{
5036		arcmsr_free_resource(acb);
5037		printf("arcmsr%d: xor bus_dma_tag_create failure!\n", acb->pci_unit);
5038		return ENXIO;
5039	}
5040	/* Allocation for xors */
5041	if(bus_dmamem_alloc(acb->xor_dmat, (void **)&acb->xorptr, ARCMSR_DMA_ALLOC_FLAG, &acb->xor_dmamap) != 0) {
5042		arcmsr_free_resource(acb);
5043		printf("arcmsr%d: xor bus_dmamem_alloc failure!\n", acb->pci_unit);
5044		return ENXIO;
5045	}
5046	/* And permanently map xor segs */
5047	rc = bus_dmamap_load(acb->xor_dmat, acb->xor_dmamap, acb->xorptr, (ARCMSR_XOR_SEG_SIZE * acb->xor_mega), arcmsr_map_xor_sg, acb, /*flags*/0);
5048	if((rc != 0) && (rc != EINPROGRESS)) {
5049		arcmsr_free_resource(acb);
5050		printf("arcmsr%d: xor bus_dmamap_load failure!\n", acb->pci_unit);
5051		return ENXIO;
5052	}
5053	acb->acb_flags |= ACB_F_DMAMAP_SG;
5054	return (0);
5055}
5056
5057static u_int32_t arcmsr_initialize(device_t dev)
5058{
5059	struct AdapterControlBlock *acb = device_get_softc(dev);
5060	int i, j, rc;
5061	u_int32_t vendor_dev_id;
5062
5063	vendor_dev_id = pci_get_devid(dev);
5064	acb->vendor_device_id = vendor_dev_id;
5065	acb->sub_device_id = pci_read_config(dev, PCIR_SUBDEV_0, 2);
5066	rc = arcmsr_define_adapter_type(acb);
5067	if (rc)
5068		return rc;
5069	rc = arcmsr_map_pcireg(dev, acb);
5070	if (rc)
5071		return rc;
5072	rc = arcmsr_alloc_srb(dev, acb);
5073	if (rc)
5074		return rc;
5075	// allocate N times 1 MB physical continuous memory for XOR engine of Raid 5, 6.
5076	if ((acb->firm_PicStatus >> 24) & 0x0f) {
5077		rc = arcmsr_alloc_xor_mem(dev, acb);
5078		if (rc)
5079			return rc;
5080	}
5081	if(acb->acb_flags & (ACB_F_MAPFREESRB_FAILD | ACB_F_MAPXOR_FAILD)) {
5082		arcmsr_free_resource(acb);
5083		printf("arcmsr%d: map free srb or xor buffer failure!\n", acb->pci_unit);
5084		return ENXIO;
5085	}
5086	acb->acb_flags  |= (ACB_F_MESSAGE_WQBUFFER_CLEARED|ACB_F_MESSAGE_RQBUFFER_CLEARED|ACB_F_MESSAGE_WQBUFFER_READ);
5087	acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER;
5088	/*
5089	********************************************************************
5090	** init raid volume state
5091	********************************************************************
5092	*/
5093	for(i=0; i < ARCMSR_MAX_TARGETID; i++) {
5094		for(j=0; j < ARCMSR_MAX_TARGETLUN; j++) {
5095			acb->devstate[i][j] = ARECA_RAID_GONE;
5096		}
5097	}
5098	arcmsr_iop_init(acb);
5099	return(0);
5100}
5101
5102static int arcmsr_setup_msix(struct AdapterControlBlock *acb)
5103{
5104	int i;
5105
5106	for (i = 0; i < acb->msix_vectors; i++) {
5107		acb->irq_id[i] = 1 + i;
5108		acb->irqres[i] = bus_alloc_resource_any(acb->pci_dev,
5109		    SYS_RES_IRQ, &acb->irq_id[i], RF_ACTIVE);
5110		if (acb->irqres[i] == NULL) {
5111			printf("arcmsr: Can't allocate MSI-X resource\n");
5112			goto irq_alloc_failed;
5113		}
5114		if (bus_setup_intr(acb->pci_dev, acb->irqres[i],
5115		    INTR_MPSAFE | INTR_TYPE_CAM, NULL, arcmsr_intr_handler,
5116		    acb, &acb->ih[i])) {
5117			printf("arcmsr: Cannot set up MSI-X interrupt handler\n");
5118			goto irq_alloc_failed;
5119		}
5120	}
5121	printf("arcmsr: MSI-X INT enabled\n");
5122	acb->acb_flags |= ACB_F_MSIX_ENABLED;
5123	return TRUE;
5124
5125irq_alloc_failed:
5126	arcmsr_teardown_intr(acb->pci_dev, acb);
5127	return FALSE;
5128}
5129
5130/*
5131************************************************************************
5132************************************************************************
5133*/
5134static int arcmsr_attach(device_t dev)
5135{
5136	struct make_dev_args args;
5137	struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev);
5138	u_int32_t unit=device_get_unit(dev);
5139	struct ccb_setasync csa;
5140	struct cam_devq	*devq;	/* Device Queue to use for this SIM */
5141	struct resource	*irqres;
5142
5143	if(acb == NULL) {
5144		printf("arcmsr%d: cannot allocate softc\n", unit);
5145		return (ENOMEM);
5146	}
5147	arcmsr_mutex_init(acb);
5148	acb->pci_dev = dev;
5149	acb->pci_unit = unit;
5150	if(arcmsr_initialize(dev)) {
5151		printf("arcmsr%d: initialize failure!\n", unit);
5152		goto initialize_failed;
5153	}
5154	/* After setting up the adapter, map our interrupt */
5155	acb->msix_vectors = ARCMSR_NUM_MSIX_VECTORS;
5156	if (pci_alloc_msix(dev, &acb->msix_vectors) == 0) {
5157		if (arcmsr_setup_msix(acb) == TRUE)
5158			goto irqx;
5159	}
5160	acb->irq_id[0] = 0;
5161	irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &acb->irq_id[0], RF_SHAREABLE | RF_ACTIVE);
5162	if(irqres == NULL ||
5163		bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE, NULL, arcmsr_intr_handler, acb, &acb->ih[0])) {
5164		printf("arcmsr%d: unable to register interrupt handler!\n", unit);
5165		goto setup_intr_failed;
5166	}
5167	acb->irqres[0] = irqres;
5168irqx:
5169	/*
5170	 * Now let the CAM generic SCSI layer find the SCSI devices on
5171	 * the bus *  start queue to reset to the idle loop. *
5172	 * Create device queue of SIM(s) *  (MAX_START_JOB - 1) :
5173	 * max_sim_transactions
5174	*/
5175	devq = cam_simq_alloc(acb->maxOutstanding);
5176	if(devq == NULL) {
5177		printf("arcmsr%d: cam_simq_alloc failure!\n", unit);
5178		goto simq_alloc_failed;
5179	}
5180	acb->psim = cam_sim_alloc(arcmsr_action, arcmsr_poll, "arcmsr", acb, unit, &acb->isr_lock, 1, ARCMSR_MAX_OUTSTANDING_CMD, devq);
5181	if(acb->psim == NULL) {
5182		printf("arcmsr%d: cam_sim_alloc failure!\n", unit);
5183		goto sim_alloc_failed;
5184	}
5185	ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
5186	if(xpt_bus_register(acb->psim, dev, 0) != CAM_SUCCESS) {
5187		printf("arcmsr%d: xpt_bus_register failure!\n", unit);
5188		goto xpt_bus_failed;
5189	}
5190	if(xpt_create_path(&acb->ppath, /* periph */ NULL, cam_sim_path(acb->psim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
5191		printf("arcmsr%d: xpt_create_path failure!\n", unit);
5192		goto xpt_path_failed;
5193	}
5194	/*
5195	****************************************************
5196	*/
5197	memset(&csa, 0, sizeof(csa));
5198	xpt_setup_ccb(&csa.ccb_h, acb->ppath, /*priority*/5);
5199	csa.ccb_h.func_code = XPT_SASYNC_CB;
5200	csa.event_enable = AC_FOUND_DEVICE|AC_LOST_DEVICE;
5201	csa.callback = arcmsr_async;
5202	csa.callback_arg = acb->psim;
5203	xpt_action((union ccb *)&csa);
5204	ARCMSR_LOCK_RELEASE(&acb->isr_lock);
5205	/* Create the control device.  */
5206	make_dev_args_init(&args);
5207	args.mda_devsw = &arcmsr_cdevsw;
5208	args.mda_uid = UID_ROOT;
5209	args.mda_gid = GID_WHEEL /* GID_OPERATOR */;
5210	args.mda_mode = S_IRUSR | S_IWUSR;
5211	args.mda_si_drv1 = acb;
5212	(void)make_dev_s(&args, &acb->ioctl_dev, "arcmsr%d", unit);
5213
5214	(void)make_dev_alias(acb->ioctl_dev, "arc%d", unit);
5215	arcmsr_callout_init(&acb->devmap_callout);
5216	callout_reset(&acb->devmap_callout, 60 * hz, arcmsr_polling_devmap, acb);
5217	return (0);
5218xpt_path_failed:
5219	xpt_bus_deregister(cam_sim_path(acb->psim));
5220xpt_bus_failed:
5221	cam_sim_free(acb->psim, /* free_simq */ TRUE);
5222sim_alloc_failed:
5223	cam_simq_free(devq);
5224simq_alloc_failed:
5225	arcmsr_teardown_intr(dev, acb);
5226setup_intr_failed:
5227	arcmsr_free_resource(acb);
5228initialize_failed:
5229	arcmsr_mutex_destroy(acb);
5230	return ENXIO;
5231}
5232
5233/*
5234************************************************************************
5235************************************************************************
5236*/
5237static int arcmsr_probe(device_t dev)
5238{
5239	u_int32_t id;
5240	u_int16_t sub_device_id;
5241	char x_type[]={"unknown"};
5242	char *type;
5243	int raid6 = 1;
5244
5245	if (pci_get_vendor(dev) != PCI_VENDOR_ID_ARECA) {
5246		return (ENXIO);
5247	}
5248	sub_device_id = pci_read_config(dev, PCIR_SUBDEV_0, 2);
5249	switch(id = pci_get_devid(dev)) {
5250	case PCIDevVenIDARC1110:
5251	case PCIDevVenIDARC1200:
5252	case PCIDevVenIDARC1201:
5253	case PCIDevVenIDARC1210:
5254		raid6 = 0;
5255		/*FALLTHRU*/
5256	case PCIDevVenIDARC1120:
5257	case PCIDevVenIDARC1130:
5258	case PCIDevVenIDARC1160:
5259	case PCIDevVenIDARC1170:
5260	case PCIDevVenIDARC1220:
5261	case PCIDevVenIDARC1230:
5262	case PCIDevVenIDARC1231:
5263	case PCIDevVenIDARC1260:
5264	case PCIDevVenIDARC1261:
5265	case PCIDevVenIDARC1270:
5266	case PCIDevVenIDARC1280:
5267		type = "SATA 3G";
5268		break;
5269	case PCIDevVenIDARC1212:
5270	case PCIDevVenIDARC1222:
5271	case PCIDevVenIDARC1380:
5272	case PCIDevVenIDARC1381:
5273	case PCIDevVenIDARC1680:
5274	case PCIDevVenIDARC1681:
5275		type = "SAS 3G";
5276		break;
5277	case PCIDevVenIDARC1880:
5278	case PCIDevVenIDARC1882:
5279	case PCIDevVenIDARC1883:
5280	case PCIDevVenIDARC1213:
5281	case PCIDevVenIDARC1223:
5282		if ((sub_device_id == ARECA_SUB_DEV_ID_1883) ||
5283		    (sub_device_id == ARECA_SUB_DEV_ID_1216) ||
5284		    (sub_device_id == ARECA_SUB_DEV_ID_1226))
5285			type = "SAS 12G,SATA 6G";
5286		else
5287			type = "SAS,SATA 6G";
5288		break;
5289	case PCIDevVenIDARC1884:
5290		type = "SAS 12G";
5291		break;
5292	case PCIDevVenIDARC1886_0:
5293	case PCIDevVenIDARC1886_:
5294	case PCIDevVenIDARC1886:
5295		type = "NVME,SAS-12G,SATA-6G";
5296		break;
5297	case PCIDevVenIDARC1214:
5298	case PCIDevVenIDARC1224:
5299		if ((sub_device_id == ARECA_SUB_DEV_ID_1214) ||
5300		    (sub_device_id == ARECA_SUB_DEV_ID_1224))
5301			type = "SAS 6G";
5302		else
5303			type = "SATA 6G";
5304		break;
5305	case PCIDevVenIDARC1203:
5306		type = "SATA 6G";
5307		break;
5308	default:
5309		type = x_type;
5310		raid6 = 0;
5311		break;
5312	}
5313	if(type == x_type)
5314		return(ENXIO);
5315	device_set_descf(dev, "Areca %s Host Adapter RAID Controller %s\n%s\n",
5316	    type, raid6 ? "(RAID6 capable)" : "", ARCMSR_DRIVER_VERSION);
5317	return (BUS_PROBE_DEFAULT);
5318}
5319/*
5320************************************************************************
5321************************************************************************
5322*/
5323static int arcmsr_shutdown(device_t dev)
5324{
5325	u_int32_t  i;
5326	struct CommandControlBlock *srb;
5327	struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev);
5328
5329	/* stop adapter background rebuild */
5330	ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
5331	/* disable all outbound interrupt */
5332	arcmsr_disable_allintr(acb);
5333	arcmsr_stop_adapter_bgrb(acb);
5334	arcmsr_flush_adapter_cache(acb);
5335	/* abort all outstanding command */
5336	acb->acb_flags |= ACB_F_SCSISTOPADAPTER;
5337	acb->acb_flags &= ~ACB_F_IOP_INITED;
5338	if(acb->srboutstandingcount != 0) {
5339		/*clear and abort all outbound posted Q*/
5340		arcmsr_done4abort_postqueue(acb);
5341		/* talk to iop 331 outstanding command aborted*/
5342		arcmsr_abort_allcmd(acb);
5343		for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) {
5344			srb = acb->psrb_pool[i];
5345			if(srb->srb_state == ARCMSR_SRB_START) {
5346				srb->srb_state = ARCMSR_SRB_ABORTED;
5347				srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
5348				arcmsr_srb_complete(srb, 1);
5349			}
5350		}
5351	}
5352	acb->srboutstandingcount = 0;
5353	acb->workingsrb_doneindex = 0;
5354	acb->workingsrb_startindex = 0;
5355	acb->pktRequestCount = 0;
5356	acb->pktReturnCount = 0;
5357	ARCMSR_LOCK_RELEASE(&acb->isr_lock);
5358	return (0);
5359}
5360/*
5361************************************************************************
5362************************************************************************
5363*/
5364static void arcmsr_teardown_intr(device_t dev, struct AdapterControlBlock *acb)
5365{
5366	int i;
5367
5368	if (acb->acb_flags & ACB_F_MSIX_ENABLED) {
5369		for (i = 0; i < acb->msix_vectors; i++) {
5370			if (acb->ih[i])
5371				bus_teardown_intr(dev, acb->irqres[i], acb->ih[i]);
5372			if (acb->irqres[i] != NULL)
5373				bus_release_resource(dev, SYS_RES_IRQ,
5374				    acb->irq_id[i], acb->irqres[i]);
5375
5376			acb->ih[i] = NULL;
5377		}
5378		pci_release_msi(dev);
5379	} else {
5380		if (acb->ih[0])
5381			bus_teardown_intr(dev, acb->irqres[0], acb->ih[0]);
5382		if (acb->irqres[0] != NULL)
5383			bus_release_resource(dev, SYS_RES_IRQ,
5384			    acb->irq_id[0], acb->irqres[0]);
5385		acb->ih[0] = NULL;
5386	}
5387
5388}
5389/*
5390************************************************************************
5391************************************************************************
5392*/
5393static int arcmsr_detach(device_t dev)
5394{
5395	struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev);
5396
5397	callout_stop(&acb->devmap_callout);
5398	arcmsr_teardown_intr(dev, acb);
5399	arcmsr_shutdown(dev);
5400	arcmsr_free_resource(acb);
5401	ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
5402	xpt_async(AC_LOST_DEVICE, acb->ppath, NULL);
5403	xpt_free_path(acb->ppath);
5404	xpt_bus_deregister(cam_sim_path(acb->psim));
5405	cam_sim_free(acb->psim, TRUE);
5406	ARCMSR_LOCK_RELEASE(&acb->isr_lock);
5407	arcmsr_mutex_destroy(acb);
5408	return (0);
5409}
5410
5411#ifdef ARCMSR_DEBUG1
5412static void arcmsr_dump_data(struct AdapterControlBlock *acb)
5413{
5414	if((acb->pktRequestCount - acb->pktReturnCount) == 0)
5415		return;
5416	printf("Command Request Count   =0x%x\n",acb->pktRequestCount);
5417	printf("Command Return Count    =0x%x\n",acb->pktReturnCount);
5418	printf("Command (Req-Rtn) Count =0x%x\n",(acb->pktRequestCount - acb->pktReturnCount));
5419	printf("Queued Command Count    =0x%x\n",acb->srboutstandingcount);
5420}
5421#endif
5422