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

Cache object: f88c288fe58693962a3ec7eeb95464c1


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