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