The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/arcmsr/arcmsr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 8f951dda9c2f783e5c3966ab2812e6ff


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.