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