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

Cache object: 1b6dfc601739955e1ccb27ca40ed73f5


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