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