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