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-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

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

Cache object: 7d2271ad92bb2cff8f04cf3808aa0435


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