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