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

Cache object: 5ddefd751c56c029a22d98558dffee72


[ 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.