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


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

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

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

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

Cache object: cb38d46aee862f07ca39b83031d0addc


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