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 **        OS    : FreeBSD
    4 **   FILE NAME  : arcmsr.c
    5 **        BY    : Erich Chen, Ching Huang
    6 **   Description: SCSI RAID Device Driver for 
    7 **                ARECA (ARC11XX/ARC12XX/ARC13XX/ARC16XX/ARC188x)
    8 **                SATA/SAS RAID HOST Adapter
    9 ********************************************************************************
   10 ********************************************************************************
   11 **
   12 ** Copyright (C) 2002 - 2012, Areca Technology Corporation All rights reserved.
   13 **
   14 ** Redistribution and use in source and binary forms, with or without
   15 ** modification, are permitted provided that the following conditions
   16 ** are met:
   17 ** 1. Redistributions of source code must retain the above copyright
   18 **    notice, this list of conditions and the following disclaimer.
   19 ** 2. Redistributions in binary form must reproduce the above copyright
   20 **    notice, this list of conditions and the following disclaimer in the
   21 **    documentation and/or other materials provided with the distribution.
   22 ** 3. The name of the author may not be used to endorse or promote products
   23 **    derived from this software without specific prior written permission.
   24 **
   25 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   26 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   27 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   28 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 
   29 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT
   30 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
   31 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY
   32 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   33 **(INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF
   34 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   35 ********************************************************************************
   36 ** History
   37 **
   38 **    REV#         DATE         NAME        DESCRIPTION
   39 ** 1.00.00.00   03/31/2004  Erich Chen      First release
   40 ** 1.20.00.02   11/29/2004  Erich Chen      bug fix with arcmsr_bus_reset when PHY error
   41 ** 1.20.00.03   04/19/2005  Erich Chen      add SATA 24 Ports adapter type support
   42 **                                          clean unused function
   43 ** 1.20.00.12   09/12/2005  Erich Chen      bug fix with abort command handling, 
   44 **                                          firmware version check 
   45 **                                          and firmware update notify for hardware bug fix
   46 **                                          handling if none zero high part physical address 
   47 **                                          of srb resource 
   48 ** 1.20.00.13   08/18/2006  Erich Chen      remove pending srb and report busy
   49 **                                          add iop message xfer 
   50 **                                          with scsi pass-through command
   51 **                                          add new device id of sas raid adapters 
   52 **                                          code fit for SPARC64 & PPC 
   53 ** 1.20.00.14   02/05/2007  Erich Chen      bug fix for incorrect ccb_h.status report
   54 **                                          and cause g_vfs_done() read write error
   55 ** 1.20.00.15   10/10/2007  Erich Chen      support new RAID adapter type ARC120x
   56 ** 1.20.00.16   10/10/2009  Erich Chen      Bug fix for RAID adapter type ARC120x
   57 **                                          bus_dmamem_alloc() with BUS_DMA_ZERO
   58 ** 1.20.00.17   07/15/2010  Ching Huang     Added support ARC1880
   59 **                                          report CAM_DEV_NOT_THERE instead of CAM_SEL_TIMEOUT when device failed,
   60 **                                          prevent cam_periph_error removing all LUN devices of one Target id
   61 **                                          for any one LUN device failed
   62 ** 1.20.00.18   10/14/2010  Ching Huang     Fixed "inquiry data fails comparion at DV1 step"
   63 **              10/25/2010  Ching Huang     Fixed bad range input in bus_alloc_resource for ADAPTER_TYPE_B
   64 ** 1.20.00.19   11/11/2010  Ching Huang     Fixed arcmsr driver prevent arcsas support for Areca SAS HBA ARC13x0
   65 ** 1.20.00.20   12/08/2010  Ching Huang     Avoid calling atomic_set_int function
   66 ** 1.20.00.21   02/08/2011  Ching Huang     Implement I/O request timeout
   67 **              02/14/2011  Ching Huang     Modified pktRequestCount
   68 ** 1.20.00.21   03/03/2011  Ching Huang     if a command timeout, then wait its ccb back before free it
   69 ** 1.20.00.22   07/04/2011  Ching Huang     Fixed multiple MTX panic
   70 ** 1.20.00.23   10/28/2011  Ching Huang     Added TIMEOUT_DELAY in case of too many HDDs need to start 
   71 ** 1.20.00.23   11/08/2011  Ching Huang     Added report device transfer speed 
   72 ** 1.20.00.23   01/30/2012  Ching Huang     Fixed Request requeued and Retrying command
   73 ** 1.20.00.24   06/11/2012  Ching Huang     Fixed return sense data condition
   74 ** 1.20.00.25   08/17/2012  Ching Huang     Fixed hotplug device no function on type A adapter
   75 ** 1.20.00.26   12/14/2012  Ching Huang     Added support ARC1214,1224,1264,1284
   76 ** 1.20.00.27   05/06/2013  Ching Huang     Fixed out standing cmd full on ARC-12x4
   77 ** 1.20.00.28   09/13/2013  Ching Huang     Removed recursive mutex in arcmsr_abort_dr_ccbs
   78 ** 1.20.00.29   12/18/2013  Ching Huang     Change simq allocation number, support ARC1883
   79 ** 1.30.00.00   11/30/2015  Ching Huang     Added support ARC1203
   80 ** 1.40.00.00   07/11/2017  Ching Huang     Added support ARC1884
   81 ** 1.40.00.01   10/30/2017  Ching Huang     Fixed release memory resource
   82 ** 1.50.00.00   09/30/2020  Ching Huang     Added support ARC-1886, NVMe/SAS/SATA controller
   83 ** 1.50.00.01   02/26/2021  Ching Huang     Fixed no action of hot plugging device on type_F adapter
   84 ** 1.50.00.02   04/16/2021  Ching Huang     Fixed scsi command timeout on ARC-1886 when
   85 **                                          scatter-gather count large than some number
   86 ******************************************************************************************
   87 */
   88 
   89 #include <sys/cdefs.h>
   90 __FBSDID("$FreeBSD$");
   91 
   92 #if 0
   93 #define ARCMSR_DEBUG1                   1
   94 #endif
   95 #include <sys/param.h>
   96 #include <sys/systm.h>
   97 #include <sys/malloc.h>
   98 #include <sys/kernel.h>
   99 #include <sys/bus.h>
  100 #include <sys/queue.h>
  101 #include <sys/stat.h>
  102 #include <sys/devicestat.h>
  103 #include <sys/kthread.h>
  104 #include <sys/module.h>
  105 #include <sys/proc.h>
  106 #include <sys/lock.h>
  107 #include <sys/sysctl.h>
  108 #include <sys/poll.h>
  109 #include <sys/ioccom.h>
  110 #include <vm/vm.h>
  111 #include <vm/vm_param.h>
  112 #include <vm/pmap.h>
  113 
  114 #include <isa/rtc.h>
  115 
  116 #include <machine/bus.h>
  117 #include <machine/resource.h>
  118 #include <machine/atomic.h>
  119 #include <sys/conf.h>
  120 #include <sys/rman.h>
  121 
  122 #include <cam/cam.h>
  123 #include <cam/cam_ccb.h>
  124 #include <cam/cam_sim.h>
  125 #include <cam/cam_periph.h>
  126 #include <cam/cam_xpt_periph.h>
  127 #include <cam/cam_xpt_sim.h>
  128 #include <cam/cam_debug.h>
  129 #include <cam/scsi/scsi_all.h>
  130 #include <cam/scsi/scsi_message.h>
  131 /*
  132 **************************************************************************
  133 **************************************************************************
  134 */
  135 #include <sys/selinfo.h>
  136 #include <sys/mutex.h>
  137 #include <sys/endian.h>
  138 #include <dev/pci/pcivar.h>
  139 #include <dev/pci/pcireg.h>
  140 
  141 #define arcmsr_callout_init(a)  callout_init(a, /*mpsafe*/1);
  142 
  143 #define ARCMSR_DRIVER_VERSION   "arcmsr version 1.50.00.02 2021-04-16"
  144 #include <dev/arcmsr/arcmsr.h>
  145 /*
  146 **************************************************************************
  147 **************************************************************************
  148 */
  149 static void arcmsr_free_srb(struct CommandControlBlock *srb);
  150 static struct CommandControlBlock *arcmsr_get_freesrb(struct AdapterControlBlock *acb);
  151 static u_int8_t arcmsr_seek_cmd2abort(union ccb *abortccb);
  152 static int arcmsr_probe(device_t dev);
  153 static int arcmsr_attach(device_t dev);
  154 static int arcmsr_detach(device_t dev);
  155 static u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_cmd, caddr_t arg);
  156 static void arcmsr_iop_parking(struct AdapterControlBlock *acb);
  157 static int arcmsr_shutdown(device_t dev);
  158 static void arcmsr_interrupt(struct AdapterControlBlock *acb);
  159 static void arcmsr_polling_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb);
  160 static void arcmsr_free_resource(struct AdapterControlBlock *acb);
  161 static void arcmsr_bus_reset(struct AdapterControlBlock *acb);
  162 static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb);
  163 static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb);
  164 static void arcmsr_iop_init(struct AdapterControlBlock *acb);
  165 static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb);
  166 static u_int32_t arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb, struct QBUFFER *prbuffer);
  167 static void arcmsr_Write_data_2iop_wqbuffer(struct AdapterControlBlock *acb);
  168 static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb);
  169 static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag);
  170 static void arcmsr_iop_reset(struct AdapterControlBlock *acb);
  171 static void arcmsr_report_sense_info(struct CommandControlBlock *srb);
  172 static void arcmsr_build_srb(struct CommandControlBlock *srb, bus_dma_segment_t *dm_segs, u_int32_t nseg);
  173 static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *pccb);
  174 static int arcmsr_resume(device_t dev);
  175 static int arcmsr_suspend(device_t dev);
  176 static void arcmsr_rescanLun_cb(struct cam_periph *periph, union ccb *ccb);
  177 static void arcmsr_polling_devmap(void *arg);
  178 static void arcmsr_srb_timeout(void *arg);
  179 static void arcmsr_hbd_postqueue_isr(struct AdapterControlBlock *acb);
  180 static void arcmsr_hbe_postqueue_isr(struct AdapterControlBlock *acb);
  181 static void arcmsr_hbf_postqueue_isr(struct AdapterControlBlock *acb);
  182 static void arcmsr_teardown_intr(device_t dev, struct AdapterControlBlock *acb);
  183 #ifdef ARCMSR_DEBUG1
  184 static void arcmsr_dump_data(struct AdapterControlBlock *acb);
  185 #endif
  186 /*
  187 **************************************************************************
  188 **************************************************************************
  189 */
  190 static void UDELAY(u_int32_t us) { DELAY(us); }
  191 /*
  192 **************************************************************************
  193 **************************************************************************
  194 */
  195 static bus_dmamap_callback_t arcmsr_map_free_srb;
  196 static bus_dmamap_callback_t arcmsr_execute_srb;
  197 /*
  198 **************************************************************************
  199 **************************************************************************
  200 */
  201 static d_open_t arcmsr_open;
  202 static d_close_t arcmsr_close;
  203 static d_ioctl_t arcmsr_ioctl;
  204 
  205 static device_method_t arcmsr_methods[]={
  206         DEVMETHOD(device_probe,         arcmsr_probe),
  207         DEVMETHOD(device_attach,        arcmsr_attach),
  208         DEVMETHOD(device_detach,        arcmsr_detach),
  209         DEVMETHOD(device_shutdown,      arcmsr_shutdown),
  210         DEVMETHOD(device_suspend,       arcmsr_suspend),
  211         DEVMETHOD(device_resume,        arcmsr_resume),
  212         DEVMETHOD_END
  213 };
  214 
  215 static driver_t arcmsr_driver={
  216         "arcmsr", arcmsr_methods, sizeof(struct AdapterControlBlock)
  217 };
  218 
  219 static devclass_t arcmsr_devclass;
  220 DRIVER_MODULE(arcmsr, pci, arcmsr_driver, arcmsr_devclass, 0, 0);
  221 MODULE_DEPEND(arcmsr, pci, 1, 1, 1);
  222 MODULE_DEPEND(arcmsr, cam, 1, 1, 1);
  223 #ifndef BUS_DMA_COHERENT                
  224         #define BUS_DMA_COHERENT        0x04    /* hint: map memory in a coherent way */
  225 #endif
  226 static struct cdevsw arcmsr_cdevsw={
  227                 .d_version = D_VERSION, 
  228                 .d_open    = arcmsr_open,       /* open     */
  229                 .d_close   = arcmsr_close,      /* close    */
  230                 .d_ioctl   = arcmsr_ioctl,      /* ioctl    */
  231                 .d_name    = "arcmsr",          /* name     */
  232         };
  233 /*
  234 **************************************************************************
  235 **************************************************************************
  236 */
  237 static int arcmsr_open(struct cdev *dev, int flags, int fmt, struct thread *proc)
  238 {
  239         int     unit = dev2unit(dev);
  240         struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit);
  241 
  242         if (acb == NULL) {
  243                 return ENXIO;
  244         }
  245         return (0);
  246 }
  247 /*
  248 **************************************************************************
  249 **************************************************************************
  250 */
  251 static int arcmsr_close(struct cdev *dev, int flags, int fmt, struct thread *proc)
  252 {
  253         int     unit = dev2unit(dev);
  254         struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit);
  255 
  256         if (acb == NULL) {
  257                 return ENXIO;
  258         }
  259         return 0;
  260 }
  261 /*
  262 **************************************************************************
  263 **************************************************************************
  264 */
  265 static int arcmsr_ioctl(struct cdev *dev, u_long ioctl_cmd, caddr_t arg, int flags, struct thread *proc)
  266 {
  267         int     unit = dev2unit(dev);
  268         struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit);
  269 
  270         if (acb == NULL) {
  271                 return ENXIO;
  272         }
  273         return (arcmsr_iop_ioctlcmd(acb, ioctl_cmd, arg));
  274 }
  275 /*
  276 **********************************************************************
  277 **********************************************************************
  278 */
  279 static u_int32_t arcmsr_disable_allintr( struct AdapterControlBlock *acb)
  280 {
  281         u_int32_t intmask_org = 0;
  282 
  283         switch (acb->adapter_type) {
  284         case ACB_ADAPTER_TYPE_A: {
  285                         /* disable all outbound interrupt */
  286                         intmask_org = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intmask); /* disable outbound message0 int */
  287                         CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intmask, intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE);
  288                 }
  289                 break;
  290         case ACB_ADAPTER_TYPE_B: {
  291                         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
  292                         /* disable all outbound interrupt */
  293                         intmask_org = READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell_mask)
  294                                                 & (~ARCMSR_IOP2DRV_MESSAGE_CMD_DONE); /* disable outbound message0 int */
  295                         WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell_mask, 0); /* disable all interrupt */
  296                 }
  297                 break;
  298         case ACB_ADAPTER_TYPE_C: {
  299                         /* disable all outbound interrupt */
  300                         intmask_org = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_mask); /* disable outbound message0 int */
  301                         CHIP_REG_WRITE32(HBC_MessageUnit, 0, host_int_mask, intmask_org|ARCMSR_HBCMU_ALL_INTMASKENABLE);
  302                 }
  303                 break;
  304         case ACB_ADAPTER_TYPE_D: {
  305                         /* disable all outbound interrupt */
  306                         intmask_org = CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable); /* disable outbound message0 int */
  307                         CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, ARCMSR_HBDMU_ALL_INT_DISABLE);
  308                 }
  309                 break;
  310         case ACB_ADAPTER_TYPE_E:
  311         case ACB_ADAPTER_TYPE_F: {
  312                         /* disable all outbound interrupt */
  313                         intmask_org = CHIP_REG_READ32(HBE_MessageUnit, 0, host_int_mask); /* disable outbound message0 int */
  314                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_mask, intmask_org | ARCMSR_HBEMU_ALL_INTMASKENABLE);
  315                 }
  316                 break;
  317         }
  318         return (intmask_org);
  319 }
  320 /*
  321 **********************************************************************
  322 **********************************************************************
  323 */
  324 static void arcmsr_enable_allintr( struct AdapterControlBlock *acb, u_int32_t intmask_org)
  325 {
  326         u_int32_t mask;
  327 
  328         switch (acb->adapter_type) {
  329         case ACB_ADAPTER_TYPE_A: {
  330                         /* enable outbound Post Queue, outbound doorbell Interrupt */
  331                         mask = ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE|ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE|ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE);
  332                         CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intmask, intmask_org & mask);
  333                         acb->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff;
  334                 }
  335                 break;
  336         case ACB_ADAPTER_TYPE_B: {
  337                         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
  338                         /* enable ARCMSR_IOP2DRV_MESSAGE_CMD_DONE */
  339                         mask = (ARCMSR_IOP2DRV_DATA_WRITE_OK|ARCMSR_IOP2DRV_DATA_READ_OK|ARCMSR_IOP2DRV_CDB_DONE|ARCMSR_IOP2DRV_MESSAGE_CMD_DONE);
  340                         WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell_mask, intmask_org | mask); /*1=interrupt enable, 0=interrupt disable*/
  341                         acb->outbound_int_enable = (intmask_org | mask) & 0x0000000f;
  342                 }
  343                 break;
  344         case ACB_ADAPTER_TYPE_C: {
  345                         /* enable outbound Post Queue, outbound doorbell Interrupt */
  346                         mask = ~(ARCMSR_HBCMU_UTILITY_A_ISR_MASK | ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR_MASK | ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK);
  347                         CHIP_REG_WRITE32(HBC_MessageUnit, 0, host_int_mask, intmask_org & mask);
  348                         acb->outbound_int_enable = ~(intmask_org & mask) & 0x0000000f;
  349                 }
  350                 break;
  351         case ACB_ADAPTER_TYPE_D: {
  352                         /* enable outbound Post Queue, outbound doorbell Interrupt */
  353                         mask = ARCMSR_HBDMU_ALL_INT_ENABLE;
  354                         CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, intmask_org | mask);
  355                         CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable);
  356                         acb->outbound_int_enable = mask;
  357                 }
  358                 break;
  359         case ACB_ADAPTER_TYPE_E:
  360         case ACB_ADAPTER_TYPE_F: {
  361                         /* enable outbound Post Queue, outbound doorbell Interrupt */
  362                         mask = ~(ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR | ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR);
  363                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_mask, intmask_org & mask);
  364                         acb->outbound_int_enable = ~(intmask_org & mask) & 0x0000000f;
  365                 }
  366                 break;
  367         }
  368 }
  369 /*
  370 **********************************************************************
  371 **********************************************************************
  372 */
  373 static u_int8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
  374 {
  375         u_int32_t Index;
  376         u_int8_t Retries = 0x00;
  377 
  378         do {
  379                 for(Index=0; Index < 100; Index++) {
  380                         if(CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
  381                                 CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, ARCMSR_MU_OUTBOUND_MESSAGE0_INT);/*clear interrupt*/
  382                                 return TRUE;
  383                         }
  384                         UDELAY(10000);
  385                 }/*max 1 seconds*/
  386         }while(Retries++ < 20);/*max 20 sec*/
  387         return (FALSE);
  388 }
  389 /*
  390 **********************************************************************
  391 **********************************************************************
  392 */
  393 static u_int8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb)
  394 {
  395         u_int32_t Index;
  396         u_int8_t Retries = 0x00;
  397         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
  398 
  399         do {
  400                 for(Index=0; Index < 100; Index++) {
  401                         if(READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell) & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
  402                                 WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);/*clear interrupt*/
  403                                 WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
  404                                 return TRUE;
  405                         }
  406                         UDELAY(10000);
  407                 }/*max 1 seconds*/
  408         }while(Retries++ < 20);/*max 20 sec*/
  409         return (FALSE);
  410 }
  411 /*
  412 **********************************************************************
  413 **********************************************************************
  414 */
  415 static u_int8_t arcmsr_hbc_wait_msgint_ready(struct AdapterControlBlock *acb)
  416 {
  417         u_int32_t Index;
  418         u_int8_t Retries = 0x00;
  419 
  420         do {
  421                 for(Index=0; Index < 100; Index++) {
  422                         if(CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
  423                                 CHIP_REG_WRITE32(HBC_MessageUnit, 0, outbound_doorbell_clear, ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR);/*clear interrupt*/
  424                                 return TRUE;
  425                         }
  426                         UDELAY(10000);
  427                 }/*max 1 seconds*/
  428         }while(Retries++ < 20);/*max 20 sec*/
  429         return (FALSE);
  430 }
  431 /*
  432 **********************************************************************
  433 **********************************************************************
  434 */
  435 static u_int8_t arcmsr_hbd_wait_msgint_ready(struct AdapterControlBlock *acb)
  436 {
  437         u_int32_t Index;
  438         u_int8_t Retries = 0x00;
  439 
  440         do {
  441                 for(Index=0; Index < 100; Index++) {
  442                         if(CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE) {
  443                                 CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR);/*clear interrupt*/
  444                                 return TRUE;
  445                         }
  446                         UDELAY(10000);
  447                 }/*max 1 seconds*/
  448         }while(Retries++ < 20);/*max 20 sec*/
  449         return (FALSE);
  450 }
  451 /*
  452 **********************************************************************
  453 **********************************************************************
  454 */
  455 static u_int8_t arcmsr_hbe_wait_msgint_ready(struct AdapterControlBlock *acb)
  456 {
  457         u_int32_t Index, read_doorbell;
  458         u_int8_t Retries = 0x00;
  459 
  460         do {
  461                 for(Index=0; Index < 100; Index++) {
  462                         read_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell);
  463                         if((read_doorbell ^ acb->in_doorbell) & ARCMSR_HBEMU_IOP2DRV_MESSAGE_CMD_DONE) {
  464                                 CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0);/*clear interrupt*/
  465                                 acb->in_doorbell = read_doorbell;
  466                                 return TRUE;
  467                         }
  468                         UDELAY(10000);
  469                 }/*max 1 seconds*/
  470         }while(Retries++ < 20);/*max 20 sec*/
  471         return (FALSE);
  472 }
  473 /*
  474 ************************************************************************
  475 ************************************************************************
  476 */
  477 static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)
  478 {
  479         int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
  480 
  481         CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
  482         do {
  483                 if(arcmsr_hba_wait_msgint_ready(acb)) {
  484                         break;
  485                 } else {
  486                         retry_count--;
  487                 }
  488         }while(retry_count != 0);
  489 }
  490 /*
  491 ************************************************************************
  492 ************************************************************************
  493 */
  494 static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb)
  495 {
  496         int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
  497         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
  498 
  499         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_FLUSH_CACHE);
  500         do {
  501                 if(arcmsr_hbb_wait_msgint_ready(acb)) {
  502                         break;
  503                 } else {
  504                         retry_count--;
  505                 }
  506         }while(retry_count != 0);
  507 }
  508 /*
  509 ************************************************************************
  510 ************************************************************************
  511 */
  512 static void arcmsr_flush_hbc_cache(struct AdapterControlBlock *acb)
  513 {
  514         int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
  515 
  516         CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
  517         CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
  518         do {
  519                 if(arcmsr_hbc_wait_msgint_ready(acb)) {
  520                         break;
  521                 } else {
  522                         retry_count--;
  523                 }
  524         }while(retry_count != 0);
  525 }
  526 /*
  527 ************************************************************************
  528 ************************************************************************
  529 */
  530 static void arcmsr_flush_hbd_cache(struct AdapterControlBlock *acb)
  531 {
  532         int retry_count = 30; /* enlarge wait flush adapter cache time: 10 minute */
  533 
  534         CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
  535         do {
  536                 if(arcmsr_hbd_wait_msgint_ready(acb)) {
  537                         break;
  538                 } else {
  539                         retry_count--;
  540                 }
  541         }while(retry_count != 0);
  542 }
  543 /*
  544 ************************************************************************
  545 ************************************************************************
  546 */
  547 static void arcmsr_flush_hbe_cache(struct AdapterControlBlock *acb)
  548 {
  549         int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
  550 
  551         CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
  552         acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
  553         CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
  554         do {
  555                 if(arcmsr_hbe_wait_msgint_ready(acb)) {
  556                         break;
  557                 } else {
  558                         retry_count--;
  559                 }
  560         }while(retry_count != 0);
  561 }
  562 /*
  563 ************************************************************************
  564 ************************************************************************
  565 */
  566 static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
  567 {
  568         switch (acb->adapter_type) {
  569         case ACB_ADAPTER_TYPE_A: {
  570                         arcmsr_flush_hba_cache(acb);
  571                 }
  572                 break;
  573         case ACB_ADAPTER_TYPE_B: {
  574                         arcmsr_flush_hbb_cache(acb);
  575                 }
  576                 break;
  577         case ACB_ADAPTER_TYPE_C: {
  578                         arcmsr_flush_hbc_cache(acb);
  579                 }
  580                 break;
  581         case ACB_ADAPTER_TYPE_D: {
  582                         arcmsr_flush_hbd_cache(acb);
  583                 }
  584                 break;
  585         case ACB_ADAPTER_TYPE_E:
  586         case ACB_ADAPTER_TYPE_F: {
  587                         arcmsr_flush_hbe_cache(acb);
  588                 }
  589                 break;
  590         }
  591 }
  592 /*
  593 *******************************************************************************
  594 *******************************************************************************
  595 */
  596 static int arcmsr_suspend(device_t dev)
  597 {
  598         struct AdapterControlBlock      *acb = device_get_softc(dev);
  599 
  600         /* flush controller */
  601         arcmsr_iop_parking(acb);
  602         /* disable all outbound interrupt */
  603         arcmsr_disable_allintr(acb);
  604         return(0);
  605 }
  606 /*
  607 *******************************************************************************
  608 *******************************************************************************
  609 */
  610 static int arcmsr_resume(device_t dev)
  611 {
  612         struct AdapterControlBlock      *acb = device_get_softc(dev);
  613 
  614         arcmsr_iop_init(acb);
  615         return(0);
  616 }
  617 /*
  618 *********************************************************************************
  619 *********************************************************************************
  620 */
  621 static void arcmsr_async(void *cb_arg, u_int32_t code, struct cam_path *path, void *arg)
  622 {
  623         struct AdapterControlBlock *acb;
  624         u_int8_t target_id, target_lun;
  625         struct cam_sim *sim;
  626 
  627         sim = (struct cam_sim *) cb_arg;
  628         acb =(struct AdapterControlBlock *) cam_sim_softc(sim);
  629         switch (code) {
  630         case AC_LOST_DEVICE:
  631                 target_id = xpt_path_target_id(path);
  632                 target_lun = xpt_path_lun_id(path);
  633                 if((target_id > ARCMSR_MAX_TARGETID) || (target_lun > ARCMSR_MAX_TARGETLUN)) {
  634                         break;
  635                 }
  636         //      printf("%s:scsi id=%d lun=%d device lost \n", device_get_name(acb->pci_dev), target_id, target_lun);
  637                 break;
  638         default:
  639                 break;
  640         }
  641 }
  642 /*
  643 **********************************************************************
  644 **********************************************************************
  645 */
  646 static void arcmsr_report_sense_info(struct CommandControlBlock *srb)
  647 {
  648         union ccb *pccb = srb->pccb;
  649 
  650         pccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
  651         pccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
  652         if(pccb->csio.sense_len) {
  653                 memset(&pccb->csio.sense_data, 0, sizeof(pccb->csio.sense_data));
  654                 memcpy(&pccb->csio.sense_data, srb->arcmsr_cdb.SenseData, 
  655                 get_min(sizeof(struct SENSE_DATA), sizeof(pccb->csio.sense_data)));
  656                 ((u_int8_t *)&pccb->csio.sense_data)[0] = (0x1 << 7 | 0x70); /* Valid,ErrorCode */
  657                 pccb->ccb_h.status |= CAM_AUTOSNS_VALID;
  658         }
  659 }
  660 /*
  661 *********************************************************************
  662 *********************************************************************
  663 */
  664 static void arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb)
  665 {
  666         CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_ABORT_CMD);
  667         if(!arcmsr_hba_wait_msgint_ready(acb)) {
  668                 printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit);
  669         }
  670 }
  671 /*
  672 *********************************************************************
  673 *********************************************************************
  674 */
  675 static void arcmsr_abort_hbb_allcmd(struct AdapterControlBlock *acb)
  676 {
  677         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
  678         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_ABORT_CMD);
  679         if(!arcmsr_hbb_wait_msgint_ready(acb)) {
  680                 printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit);
  681         }
  682 }
  683 /*
  684 *********************************************************************
  685 *********************************************************************
  686 */
  687 static void arcmsr_abort_hbc_allcmd(struct AdapterControlBlock *acb)
  688 {
  689         CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_ABORT_CMD);
  690         CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
  691         if(!arcmsr_hbc_wait_msgint_ready(acb)) {
  692                 printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit);
  693         }
  694 }
  695 /*
  696 *********************************************************************
  697 *********************************************************************
  698 */
  699 static void arcmsr_abort_hbd_allcmd(struct AdapterControlBlock *acb)
  700 {
  701         CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_ABORT_CMD);
  702         if(!arcmsr_hbd_wait_msgint_ready(acb)) {
  703                 printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit);
  704         }
  705 }
  706 /*
  707 *********************************************************************
  708 *********************************************************************
  709 */
  710 static void arcmsr_abort_hbe_allcmd(struct AdapterControlBlock *acb)
  711 {
  712         CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_ABORT_CMD);
  713         acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
  714         CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
  715         if(!arcmsr_hbe_wait_msgint_ready(acb)) {
  716                 printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit);
  717         }
  718 }
  719 /*
  720 *********************************************************************
  721 *********************************************************************
  722 */
  723 static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb)
  724 {
  725         switch (acb->adapter_type) {
  726         case ACB_ADAPTER_TYPE_A: {
  727                         arcmsr_abort_hba_allcmd(acb);
  728                 }
  729                 break;
  730         case ACB_ADAPTER_TYPE_B: {
  731                         arcmsr_abort_hbb_allcmd(acb);
  732                 }
  733                 break;
  734         case ACB_ADAPTER_TYPE_C: {
  735                         arcmsr_abort_hbc_allcmd(acb);
  736                 }
  737                 break;
  738         case ACB_ADAPTER_TYPE_D: {
  739                         arcmsr_abort_hbd_allcmd(acb);
  740                 }
  741                 break;
  742         case ACB_ADAPTER_TYPE_E:
  743         case ACB_ADAPTER_TYPE_F: {
  744                         arcmsr_abort_hbe_allcmd(acb);
  745                 }
  746                 break;
  747         }
  748 }
  749 /*
  750 **********************************************************************
  751 **********************************************************************
  752 */
  753 static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag)
  754 {
  755         struct AdapterControlBlock *acb = srb->acb;
  756         union ccb *pccb = srb->pccb;
  757 
  758         if(srb->srb_flags & SRB_FLAG_TIMER_START)
  759                 callout_stop(&srb->ccb_callout);
  760         if((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
  761                 bus_dmasync_op_t op;
  762 
  763                 if((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
  764                         op = BUS_DMASYNC_POSTREAD;
  765                 } else {
  766                         op = BUS_DMASYNC_POSTWRITE;
  767                 }
  768                 bus_dmamap_sync(acb->dm_segs_dmat, srb->dm_segs_dmamap, op);
  769                 bus_dmamap_unload(acb->dm_segs_dmat, srb->dm_segs_dmamap);
  770         }
  771         if(stand_flag == 1) {
  772                 atomic_subtract_int(&acb->srboutstandingcount, 1);
  773                 if((acb->acb_flags & ACB_F_CAM_DEV_QFRZN) && (
  774                 acb->srboutstandingcount < (acb->maxOutstanding -10))) {
  775                         acb->acb_flags &= ~ACB_F_CAM_DEV_QFRZN;
  776                         pccb->ccb_h.status |= CAM_RELEASE_SIMQ;
  777                 }
  778         }
  779         if(srb->srb_state != ARCMSR_SRB_TIMEOUT)
  780                 arcmsr_free_srb(srb);
  781         acb->pktReturnCount++;
  782         xpt_done(pccb);
  783 }
  784 /*
  785 **************************************************************************
  786 **************************************************************************
  787 */
  788 static void arcmsr_report_srb_state(struct AdapterControlBlock *acb, struct CommandControlBlock *srb, u_int16_t error)
  789 {
  790         int target, lun;
  791 
  792         target = srb->pccb->ccb_h.target_id;
  793         lun = srb->pccb->ccb_h.target_lun;
  794         if(error == FALSE) {
  795                 if(acb->devstate[target][lun] == ARECA_RAID_GONE) {
  796                         acb->devstate[target][lun] = ARECA_RAID_GOOD;
  797                 }
  798                 srb->pccb->ccb_h.status |= CAM_REQ_CMP;
  799                 arcmsr_srb_complete(srb, 1);
  800         } else {
  801                 switch(srb->arcmsr_cdb.DeviceStatus) {
  802                 case ARCMSR_DEV_SELECT_TIMEOUT: {
  803                                 if(acb->devstate[target][lun] == ARECA_RAID_GOOD) {
  804                                         printf( "arcmsr%d: Target=%x, Lun=%x, selection timeout, raid volume was lost\n", acb->pci_unit, target, lun);
  805                                 }
  806                                 acb->devstate[target][lun] = ARECA_RAID_GONE;
  807                                 srb->pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
  808                                 arcmsr_srb_complete(srb, 1);
  809                         }
  810                         break;
  811                 case ARCMSR_DEV_ABORTED:
  812                 case ARCMSR_DEV_INIT_FAIL: {
  813                                 acb->devstate[target][lun] = ARECA_RAID_GONE;
  814                                 srb->pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
  815                                 arcmsr_srb_complete(srb, 1);
  816                         }
  817                         break;
  818                 case SCSISTAT_CHECK_CONDITION: {
  819                                 acb->devstate[target][lun] = ARECA_RAID_GOOD;
  820                                 arcmsr_report_sense_info(srb);
  821                                 arcmsr_srb_complete(srb, 1);
  822                         }
  823                         break;
  824                 default:
  825                         printf("arcmsr%d: scsi id=%d lun=%d isr got command error done,but got unknown DeviceStatus=0x%x \n"
  826                                         , acb->pci_unit, target, lun ,srb->arcmsr_cdb.DeviceStatus);
  827                         acb->devstate[target][lun] = ARECA_RAID_GONE;
  828                         srb->pccb->ccb_h.status |= CAM_UNCOR_PARITY;
  829                         /*unknown error or crc error just for retry*/
  830                         arcmsr_srb_complete(srb, 1);
  831                         break;
  832                 }
  833         }
  834 }
  835 /*
  836 **************************************************************************
  837 **************************************************************************
  838 */
  839 static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, u_int32_t flag_srb, u_int16_t error)
  840 {
  841         struct CommandControlBlock *srb;
  842 
  843         /* check if command done with no error*/
  844         switch (acb->adapter_type) {
  845         case ACB_ADAPTER_TYPE_A:
  846         case ACB_ADAPTER_TYPE_B:
  847                 srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
  848                 break;
  849         case ACB_ADAPTER_TYPE_C:
  850         case ACB_ADAPTER_TYPE_D:
  851                 srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0)); /*frame must be 32 bytes aligned*/
  852                 break;
  853         case ACB_ADAPTER_TYPE_E:
  854         case ACB_ADAPTER_TYPE_F:
  855                 srb = acb->psrb_pool[flag_srb];
  856                 break;
  857         default:
  858                 srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
  859                 break;
  860         }
  861         if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
  862                 if(srb->srb_state == ARCMSR_SRB_TIMEOUT) {
  863                         arcmsr_free_srb(srb);
  864                         printf("arcmsr%d: srb='%p' return srb has been timeouted\n", acb->pci_unit, srb);
  865                         return;
  866                 }
  867                 printf("arcmsr%d: return srb has been completed\n"
  868                         "srb='%p' srb_state=0x%x outstanding srb count=%d \n",
  869                         acb->pci_unit, srb, srb->srb_state, acb->srboutstandingcount);
  870                 return;
  871         }
  872         arcmsr_report_srb_state(acb, srb, error);
  873 }
  874 /*
  875 **************************************************************************
  876 **************************************************************************
  877 */
  878 static void     arcmsr_srb_timeout(void *arg)
  879 {
  880         struct CommandControlBlock *srb = (struct CommandControlBlock *)arg;
  881         struct AdapterControlBlock *acb;
  882         int target, lun;
  883         u_int8_t cmd;
  884 
  885         target = srb->pccb->ccb_h.target_id;
  886         lun = srb->pccb->ccb_h.target_lun;
  887         acb = srb->acb;
  888         ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
  889         if(srb->srb_state == ARCMSR_SRB_START)
  890         {
  891                 cmd = scsiio_cdb_ptr(&srb->pccb->csio)[0];
  892                 srb->srb_state = ARCMSR_SRB_TIMEOUT;
  893                 srb->pccb->ccb_h.status |= CAM_CMD_TIMEOUT;
  894                 arcmsr_srb_complete(srb, 1);
  895                 printf("arcmsr%d: scsi id %d lun %d cmd=0x%x srb='%p' ccb command time out!\n",
  896                                  acb->pci_unit, target, lun, cmd, srb);
  897         }
  898         ARCMSR_LOCK_RELEASE(&acb->isr_lock);
  899 #ifdef ARCMSR_DEBUG1
  900         arcmsr_dump_data(acb);
  901 #endif
  902 }
  903 
  904 /*
  905 **********************************************************************
  906 **********************************************************************
  907 */
  908 static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
  909 {
  910         int i=0;
  911         u_int32_t flag_srb;
  912         u_int16_t error;
  913 
  914         switch (acb->adapter_type) {
  915         case ACB_ADAPTER_TYPE_A: {
  916                         u_int32_t outbound_intstatus;
  917 
  918                         /*clear and abort all outbound posted Q*/
  919                         outbound_intstatus = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable;
  920                         CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intstatus);/*clear interrupt*/
  921                         while(((flag_srb=CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_queueport)) != 0xFFFFFFFF) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
  922                                 error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
  923                                 arcmsr_drain_donequeue(acb, flag_srb, error);
  924                         }
  925                 }
  926                 break;
  927         case ACB_ADAPTER_TYPE_B: {
  928                         struct HBB_MessageUnit *phbbmu=(struct HBB_MessageUnit *)acb->pmu;
  929 
  930                         /*clear all outbound posted Q*/
  931                         WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN); /* clear doorbell interrupt */
  932                         for(i=0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) {
  933                                 if((flag_srb = phbbmu->done_qbuffer[i]) != 0) {
  934                                         phbbmu->done_qbuffer[i] = 0;
  935                                         error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
  936                                         arcmsr_drain_donequeue(acb, flag_srb, error);
  937                                 }
  938                                 phbbmu->post_qbuffer[i] = 0;
  939                         }/*drain reply FIFO*/
  940                         phbbmu->doneq_index = 0;
  941                         phbbmu->postq_index = 0;
  942                 }
  943                 break;
  944         case ACB_ADAPTER_TYPE_C: {
  945                         while((CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
  946                                 flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
  947                                 error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
  948                                 arcmsr_drain_donequeue(acb, flag_srb, error);
  949                         }
  950                 }
  951                 break;
  952         case ACB_ADAPTER_TYPE_D:
  953                 arcmsr_hbd_postqueue_isr(acb);
  954                 break;
  955         case ACB_ADAPTER_TYPE_E:
  956                 arcmsr_hbe_postqueue_isr(acb);
  957                 break;
  958         case ACB_ADAPTER_TYPE_F:
  959                 arcmsr_hbf_postqueue_isr(acb);
  960                 break;
  961         }
  962 }
  963 /*
  964 ****************************************************************************
  965 ****************************************************************************
  966 */
  967 static void arcmsr_iop_reset(struct AdapterControlBlock *acb)
  968 {
  969         struct CommandControlBlock *srb;
  970         u_int32_t intmask_org;
  971         u_int32_t i=0;
  972 
  973         if(acb->srboutstandingcount>0) {
  974                 /* disable all outbound interrupt */
  975                 intmask_org = arcmsr_disable_allintr(acb);
  976                 /*clear and abort all outbound posted Q*/
  977                 arcmsr_done4abort_postqueue(acb);
  978                 /* talk to iop 331 outstanding command aborted*/
  979                 arcmsr_abort_allcmd(acb);
  980                 for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) {
  981                         srb = acb->psrb_pool[i];
  982                         if(srb->srb_state == ARCMSR_SRB_START) {
  983                                 srb->srb_state = ARCMSR_SRB_ABORTED;
  984                                 srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
  985                                 arcmsr_srb_complete(srb, 1);
  986                                 printf("arcmsr%d: scsi id=%d lun=%jx srb='%p' aborted\n"
  987                                                 , acb->pci_unit, srb->pccb->ccb_h.target_id
  988                                                 , (uintmax_t)srb->pccb->ccb_h.target_lun, srb);
  989                         }
  990                 }
  991                 /* enable all outbound interrupt */
  992                 arcmsr_enable_allintr(acb, intmask_org);
  993         }
  994         acb->srboutstandingcount = 0;
  995         acb->workingsrb_doneindex = 0;
  996         acb->workingsrb_startindex = 0;
  997         acb->pktRequestCount = 0;
  998         acb->pktReturnCount = 0;
  999 }
 1000 /*
 1001 **********************************************************************
 1002 **********************************************************************
 1003 */
 1004 static void arcmsr_build_srb(struct CommandControlBlock *srb, 
 1005                 bus_dma_segment_t *dm_segs, u_int32_t nseg)
 1006 {
 1007         struct ARCMSR_CDB *arcmsr_cdb = &srb->arcmsr_cdb;
 1008         u_int8_t *psge = (u_int8_t *)&arcmsr_cdb->u;
 1009         u_int32_t address_lo, address_hi;
 1010         union ccb *pccb = srb->pccb;
 1011         struct ccb_scsiio *pcsio = &pccb->csio;
 1012         u_int32_t arccdbsize = 0x30;
 1013 
 1014         memset(arcmsr_cdb, 0, sizeof(struct ARCMSR_CDB));
 1015         arcmsr_cdb->Bus = 0;
 1016         arcmsr_cdb->TargetID = pccb->ccb_h.target_id;
 1017         arcmsr_cdb->LUN = pccb->ccb_h.target_lun;
 1018         arcmsr_cdb->Function = 1;
 1019         arcmsr_cdb->CdbLength = (u_int8_t)pcsio->cdb_len;
 1020         bcopy(scsiio_cdb_ptr(pcsio), arcmsr_cdb->Cdb, pcsio->cdb_len);
 1021         if(nseg != 0) {
 1022                 struct AdapterControlBlock *acb = srb->acb;
 1023                 bus_dmasync_op_t op;    
 1024                 u_int32_t length, i, cdb_sgcount = 0;
 1025 
 1026                 if((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
 1027                         op = BUS_DMASYNC_PREREAD;
 1028                 } else {
 1029                         op = BUS_DMASYNC_PREWRITE;
 1030                         arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE;
 1031                         srb->srb_flags |= SRB_FLAG_WRITE;
 1032                 }
 1033                 bus_dmamap_sync(acb->dm_segs_dmat, srb->dm_segs_dmamap, op);
 1034                 for(i=0; i < nseg; i++) {
 1035                         /* Get the physical address of the current data pointer */
 1036                         length = arcmsr_htole32(dm_segs[i].ds_len);
 1037                         address_lo = arcmsr_htole32(dma_addr_lo32(dm_segs[i].ds_addr));
 1038                         address_hi = arcmsr_htole32(dma_addr_hi32(dm_segs[i].ds_addr));
 1039                         if(address_hi == 0) {
 1040                                 struct SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge;
 1041                                 pdma_sg->address = address_lo;
 1042                                 pdma_sg->length = length;
 1043                                 psge += sizeof(struct SG32ENTRY);
 1044                                 arccdbsize += sizeof(struct SG32ENTRY);
 1045                         } else {
 1046                                 u_int32_t sg64s_size = 0, tmplength = length;
 1047 
 1048                                 while(1) {
 1049                                         u_int64_t span4G, length0;
 1050                                         struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge;
 1051 
 1052                                         span4G = (u_int64_t)address_lo + tmplength;
 1053                                         pdma_sg->addresshigh = address_hi;
 1054                                         pdma_sg->address = address_lo;
 1055                                         if(span4G > 0x100000000) {
 1056                                                 /*see if cross 4G boundary*/
 1057                                                 length0 = 0x100000000-address_lo;
 1058                                                 pdma_sg->length = (u_int32_t)length0 | IS_SG64_ADDR;
 1059                                                 address_hi = address_hi+1;
 1060                                                 address_lo = 0;
 1061                                                 tmplength = tmplength - (u_int32_t)length0;
 1062                                                 sg64s_size += sizeof(struct SG64ENTRY);
 1063                                                 psge += sizeof(struct SG64ENTRY);
 1064                                                 cdb_sgcount++;
 1065                                         } else {
 1066                                                 pdma_sg->length = tmplength | IS_SG64_ADDR;
 1067                                                 sg64s_size += sizeof(struct SG64ENTRY);
 1068                                                 psge += sizeof(struct SG64ENTRY);
 1069                                                 break;
 1070                                         }
 1071                                 }
 1072                                 arccdbsize += sg64s_size;
 1073                         }
 1074                         cdb_sgcount++;
 1075                 }
 1076                 arcmsr_cdb->sgcount = (u_int8_t)cdb_sgcount;
 1077                 arcmsr_cdb->DataLength = pcsio->dxfer_len;
 1078                 if( arccdbsize > 256) {
 1079                         arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE;
 1080                 }
 1081         } else {
 1082                 arcmsr_cdb->DataLength = 0;
 1083         }
 1084         srb->arc_cdb_size = arccdbsize;
 1085         arcmsr_cdb->msgPages = (arccdbsize/256) + ((arccdbsize % 256) ? 1 : 0);
 1086 }
 1087 /*
 1088 **************************************************************************
 1089 **************************************************************************
 1090 */ 
 1091 static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandControlBlock *srb)
 1092 {
 1093         u_int32_t cdb_phyaddr_low = (u_int32_t) srb->cdb_phyaddr_low;
 1094         struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&srb->arcmsr_cdb;
 1095 
 1096         bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, (srb->srb_flags & SRB_FLAG_WRITE) ? BUS_DMASYNC_POSTWRITE:BUS_DMASYNC_POSTREAD);
 1097         atomic_add_int(&acb->srboutstandingcount, 1);
 1098         srb->srb_state = ARCMSR_SRB_START;
 1099 
 1100         switch (acb->adapter_type) {
 1101         case ACB_ADAPTER_TYPE_A: {
 1102                         if(arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) {
 1103                                 CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_queueport, cdb_phyaddr_low|ARCMSR_SRBPOST_FLAG_SGL_BSIZE);
 1104                         } else {
 1105                                 CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_queueport, cdb_phyaddr_low);
 1106                         }
 1107                 }
 1108                 break;
 1109         case ACB_ADAPTER_TYPE_B: {
 1110                         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 1111                         int ending_index, index;
 1112 
 1113                         index = phbbmu->postq_index;
 1114                         ending_index = ((index+1) % ARCMSR_MAX_HBB_POSTQUEUE);
 1115                         phbbmu->post_qbuffer[ending_index] = 0;
 1116                         if(arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) {
 1117                                 phbbmu->post_qbuffer[index] = cdb_phyaddr_low | ARCMSR_SRBPOST_FLAG_SGL_BSIZE;
 1118                         } else {
 1119                                 phbbmu->post_qbuffer[index] = cdb_phyaddr_low;
 1120                         }
 1121                         index++;
 1122                         index %= ARCMSR_MAX_HBB_POSTQUEUE;     /*if last index number set it to 0 */
 1123                         phbbmu->postq_index = index;
 1124                         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_CDB_POSTED);
 1125                 }
 1126                 break;
 1127         case ACB_ADAPTER_TYPE_C: {
 1128                         u_int32_t ccb_post_stamp, arc_cdb_size, cdb_phyaddr_hi32;
 1129 
 1130                         arc_cdb_size = (srb->arc_cdb_size > 0x300) ? 0x300 : srb->arc_cdb_size;
 1131                         ccb_post_stamp = (cdb_phyaddr_low | ((arc_cdb_size-1) >> 6) | 1);
 1132                         cdb_phyaddr_hi32 = acb->srb_phyaddr.B.phyadd_high;
 1133                         if(cdb_phyaddr_hi32)
 1134                         {
 1135                                 CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_high, cdb_phyaddr_hi32);
 1136                                 CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_low, ccb_post_stamp);
 1137                         }
 1138                         else
 1139                         {
 1140                                 CHIP_REG_WRITE32(HBC_MessageUnit,0,inbound_queueport_low, ccb_post_stamp);
 1141                         }
 1142                 }
 1143                 break;
 1144         case ACB_ADAPTER_TYPE_D: {
 1145                         struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
 1146                         u_int16_t index_stripped;
 1147                         u_int16_t postq_index;
 1148                         struct InBound_SRB *pinbound_srb;
 1149 
 1150                         ARCMSR_LOCK_ACQUIRE(&acb->postDone_lock);
 1151                         postq_index = phbdmu->postq_index;
 1152                         pinbound_srb = (struct InBound_SRB *)&phbdmu->post_qbuffer[postq_index & 0xFF];
 1153                         pinbound_srb->addressHigh = srb->cdb_phyaddr_high;
 1154                         pinbound_srb->addressLow = srb->cdb_phyaddr_low;
 1155                         pinbound_srb->length = srb->arc_cdb_size >> 2;
 1156                         arcmsr_cdb->Context = srb->cdb_phyaddr_low;
 1157                         if (postq_index & 0x4000) {
 1158                                 index_stripped = postq_index & 0xFF;
 1159                                 index_stripped += 1;
 1160                                 index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
 1161                                 phbdmu->postq_index = index_stripped ? (index_stripped | 0x4000) : index_stripped;
 1162                         } else {
 1163                                 index_stripped = postq_index;
 1164                                 index_stripped += 1;
 1165                                 index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
 1166                                 phbdmu->postq_index = index_stripped ? index_stripped : (index_stripped | 0x4000);
 1167                         }
 1168                         CHIP_REG_WRITE32(HBD_MessageUnit, 0, inboundlist_write_pointer, postq_index);
 1169                         ARCMSR_LOCK_RELEASE(&acb->postDone_lock);
 1170                 }
 1171                 break;
 1172         case ACB_ADAPTER_TYPE_E: {
 1173                         u_int32_t ccb_post_stamp, arc_cdb_size;
 1174 
 1175                         arc_cdb_size = (srb->arc_cdb_size > 0x300) ? 0x300 : srb->arc_cdb_size;
 1176                         ccb_post_stamp = (srb->smid | ((arc_cdb_size-1) >> 6));
 1177                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_queueport_high, 0);
 1178                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_queueport_low, ccb_post_stamp);
 1179                 }
 1180                 break;
 1181         case ACB_ADAPTER_TYPE_F: {
 1182                         u_int32_t ccb_post_stamp, arc_cdb_size;
 1183 
 1184                         if (srb->arc_cdb_size <= 0x300)
 1185                                 arc_cdb_size = (srb->arc_cdb_size - 1) >> 6 | 1;
 1186                         else {
 1187                                 arc_cdb_size = ((srb->arc_cdb_size + 0xff) >> 8) + 2;
 1188                                 if (arc_cdb_size > 0xF)
 1189                                         arc_cdb_size = 0xF;
 1190                                 arc_cdb_size = (arc_cdb_size << 1) | 1;
 1191                         }
 1192                         ccb_post_stamp = (srb->smid | arc_cdb_size);
 1193                         CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_queueport_high, 0);
 1194                         CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_queueport_low, ccb_post_stamp);
 1195                 }
 1196                 break;
 1197         }
 1198 }
 1199 /*
 1200 ************************************************************************
 1201 ************************************************************************
 1202 */
 1203 static struct QBUFFER *arcmsr_get_iop_rqbuffer( struct AdapterControlBlock *acb)
 1204 {
 1205         struct QBUFFER *qbuffer=NULL;
 1206 
 1207         switch (acb->adapter_type) {
 1208         case ACB_ADAPTER_TYPE_A: {
 1209                         struct HBA_MessageUnit *phbamu = (struct HBA_MessageUnit *)acb->pmu;
 1210 
 1211                         qbuffer = (struct QBUFFER *)&phbamu->message_rbuffer;
 1212                 }
 1213                 break;
 1214         case ACB_ADAPTER_TYPE_B: {
 1215                         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 1216 
 1217                         qbuffer = (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_rbuffer;
 1218                 }
 1219                 break;
 1220         case ACB_ADAPTER_TYPE_C: {
 1221                         struct HBC_MessageUnit *phbcmu = (struct HBC_MessageUnit *)acb->pmu;
 1222 
 1223                         qbuffer = (struct QBUFFER *)&phbcmu->message_rbuffer;
 1224                 }
 1225                 break;
 1226         case ACB_ADAPTER_TYPE_D: {
 1227                         struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
 1228 
 1229                         qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_rbuffer;
 1230                 }
 1231                 break;
 1232         case ACB_ADAPTER_TYPE_E: {
 1233                         struct HBE_MessageUnit *phbcmu = (struct HBE_MessageUnit *)acb->pmu;
 1234 
 1235                         qbuffer = (struct QBUFFER *)&phbcmu->message_rbuffer;
 1236                 }
 1237                 break;
 1238         case ACB_ADAPTER_TYPE_F:
 1239                 qbuffer = (struct QBUFFER *)acb->message_rbuffer;
 1240                 break;
 1241         }
 1242         return(qbuffer);
 1243 }
 1244 /*
 1245 ************************************************************************
 1246 ************************************************************************
 1247 */
 1248 static struct QBUFFER *arcmsr_get_iop_wqbuffer( struct AdapterControlBlock *acb)
 1249 {
 1250         struct QBUFFER *qbuffer = NULL;
 1251 
 1252         switch (acb->adapter_type) {
 1253         case ACB_ADAPTER_TYPE_A: {
 1254                         struct HBA_MessageUnit *phbamu = (struct HBA_MessageUnit *)acb->pmu;
 1255 
 1256                         qbuffer = (struct QBUFFER *)&phbamu->message_wbuffer;
 1257                 }
 1258                 break;
 1259         case ACB_ADAPTER_TYPE_B: {
 1260                         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 1261 
 1262                         qbuffer = (struct QBUFFER *)&phbbmu->hbb_rwbuffer->message_wbuffer;
 1263                 }
 1264                 break;
 1265         case ACB_ADAPTER_TYPE_C: {
 1266                         struct HBC_MessageUnit *phbcmu = (struct HBC_MessageUnit *)acb->pmu;
 1267 
 1268                         qbuffer = (struct QBUFFER *)&phbcmu->message_wbuffer;
 1269                 }
 1270                 break;
 1271         case ACB_ADAPTER_TYPE_D: {
 1272                         struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
 1273 
 1274                         qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_wbuffer;
 1275                 }
 1276                 break;
 1277         case ACB_ADAPTER_TYPE_E: {
 1278                         struct HBE_MessageUnit *phbcmu = (struct HBE_MessageUnit *)acb->pmu;
 1279 
 1280                         qbuffer = (struct QBUFFER *)&phbcmu->message_wbuffer;
 1281                 }
 1282                 break;
 1283         case ACB_ADAPTER_TYPE_F:
 1284                 qbuffer = (struct QBUFFER *)acb->message_wbuffer;
 1285                 break;
 1286         }
 1287         return(qbuffer);
 1288 }
 1289 /*
 1290 **************************************************************************
 1291 **************************************************************************
 1292 */
 1293 static void arcmsr_iop_message_read(struct AdapterControlBlock *acb)
 1294 {
 1295         switch (acb->adapter_type) {
 1296         case ACB_ADAPTER_TYPE_A: {
 1297                         /* let IOP know data has been read */
 1298                         CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
 1299                 }
 1300                 break;
 1301         case ACB_ADAPTER_TYPE_B: {
 1302                         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 1303                         /* let IOP know data has been read */
 1304                         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_READ_OK);
 1305                 }
 1306                 break;
 1307         case ACB_ADAPTER_TYPE_C: {
 1308                         /* let IOP know data has been read */
 1309                         CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK);
 1310                 }
 1311                 break;
 1312         case ACB_ADAPTER_TYPE_D: {
 1313                         /* let IOP know data has been read */
 1314                         CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_OUT_READ);
 1315                 }
 1316                 break;
 1317         case ACB_ADAPTER_TYPE_E:
 1318         case ACB_ADAPTER_TYPE_F: {
 1319                         /* let IOP know data has been read */
 1320                         acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_READ_OK;
 1321                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
 1322                 }
 1323                 break;
 1324         }
 1325 }
 1326 /*
 1327 **************************************************************************
 1328 **************************************************************************
 1329 */
 1330 static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb)
 1331 {
 1332         switch (acb->adapter_type) {
 1333         case ACB_ADAPTER_TYPE_A: {
 1334                         /*
 1335                         ** push inbound doorbell tell iop, driver data write ok 
 1336                         ** and wait reply on next hwinterrupt for next Qbuffer post
 1337                         */
 1338                         CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK);
 1339                 }
 1340                 break;
 1341         case ACB_ADAPTER_TYPE_B: {
 1342                         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 1343                         /*
 1344                         ** push inbound doorbell tell iop, driver data write ok 
 1345                         ** and wait reply on next hwinterrupt for next Qbuffer post
 1346                         */
 1347                         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_WRITE_OK);
 1348                 }
 1349                 break;
 1350         case ACB_ADAPTER_TYPE_C: {
 1351                         /*
 1352                         ** push inbound doorbell tell iop, driver data write ok 
 1353                         ** and wait reply on next hwinterrupt for next Qbuffer post
 1354                         */
 1355                         CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_DATA_WRITE_OK);
 1356                 }
 1357                 break;
 1358         case ACB_ADAPTER_TYPE_D: {
 1359                         /*
 1360                         ** push inbound doorbell tell iop, driver data write ok 
 1361                         ** and wait reply on next hwinterrupt for next Qbuffer post
 1362                         */
 1363                         CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_IN_READY);
 1364                 }
 1365                 break;
 1366         case ACB_ADAPTER_TYPE_E:
 1367         case ACB_ADAPTER_TYPE_F: {
 1368                         /*
 1369                         ** push inbound doorbell tell iop, driver data write ok 
 1370                         ** and wait reply on next hwinterrupt for next Qbuffer post
 1371                         */
 1372                         acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_WRITE_OK;
 1373                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
 1374                 }
 1375                 break;
 1376         }
 1377 }
 1378 /*
 1379 ************************************************************************
 1380 ************************************************************************
 1381 */
 1382 static void arcmsr_stop_hba_bgrb(struct AdapterControlBlock *acb)
 1383 {
 1384         acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
 1385         CHIP_REG_WRITE32(HBA_MessageUnit, 
 1386                 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
 1387         if(!arcmsr_hba_wait_msgint_ready(acb)) {
 1388                 printf("arcmsr%d: wait 'stop adapter background rebulid' timeout \n"
 1389                         , acb->pci_unit);
 1390         }
 1391 }
 1392 /*
 1393 ************************************************************************
 1394 ************************************************************************
 1395 */
 1396 static void arcmsr_stop_hbb_bgrb(struct AdapterControlBlock *acb)
 1397 {
 1398         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 1399         acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
 1400         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_STOP_BGRB);
 1401         if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 1402                 printf( "arcmsr%d: wait 'stop adapter background rebulid' timeout \n"
 1403                         , acb->pci_unit);
 1404         }
 1405 }
 1406 /*
 1407 ************************************************************************
 1408 ************************************************************************
 1409 */
 1410 static void arcmsr_stop_hbc_bgrb(struct AdapterControlBlock *acb)
 1411 {
 1412         acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
 1413         CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
 1414         CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell,ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
 1415         if(!arcmsr_hbc_wait_msgint_ready(acb)) {
 1416                 printf("arcmsr%d: wait 'stop adapter background rebulid' timeout \n", acb->pci_unit);
 1417         }
 1418 }
 1419 /*
 1420 ************************************************************************
 1421 ************************************************************************
 1422 */
 1423 static void arcmsr_stop_hbd_bgrb(struct AdapterControlBlock *acb)
 1424 {
 1425         acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
 1426         CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
 1427         if(!arcmsr_hbd_wait_msgint_ready(acb)) {
 1428                 printf("arcmsr%d: wait 'stop adapter background rebulid' timeout \n", acb->pci_unit);
 1429         }
 1430 }
 1431 /*
 1432 ************************************************************************
 1433 ************************************************************************
 1434 */
 1435 static void arcmsr_stop_hbe_bgrb(struct AdapterControlBlock *acb)
 1436 {
 1437         acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
 1438         CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
 1439         acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
 1440         CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
 1441         if(!arcmsr_hbe_wait_msgint_ready(acb)) {
 1442                 printf("arcmsr%d: wait 'stop adapter background rebulid' timeout \n", acb->pci_unit);
 1443         }
 1444 }
 1445 /*
 1446 ************************************************************************
 1447 ************************************************************************
 1448 */
 1449 static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb)
 1450 {
 1451         switch (acb->adapter_type) {
 1452         case ACB_ADAPTER_TYPE_A: {
 1453                         arcmsr_stop_hba_bgrb(acb);
 1454                 }
 1455                 break;
 1456         case ACB_ADAPTER_TYPE_B: {
 1457                         arcmsr_stop_hbb_bgrb(acb);
 1458                 }
 1459                 break;
 1460         case ACB_ADAPTER_TYPE_C: {
 1461                         arcmsr_stop_hbc_bgrb(acb);
 1462                 }
 1463                 break;
 1464         case ACB_ADAPTER_TYPE_D: {
 1465                         arcmsr_stop_hbd_bgrb(acb);
 1466                 }
 1467                 break;
 1468         case ACB_ADAPTER_TYPE_E:
 1469         case ACB_ADAPTER_TYPE_F: {
 1470                         arcmsr_stop_hbe_bgrb(acb);
 1471                 }
 1472                 break;
 1473         }
 1474 }
 1475 /*
 1476 ************************************************************************
 1477 ************************************************************************
 1478 */
 1479 static void arcmsr_poll(struct cam_sim *psim)
 1480 {
 1481         struct AdapterControlBlock *acb;
 1482         int     mutex;
 1483 
 1484         acb = (struct AdapterControlBlock *)cam_sim_softc(psim);
 1485         mutex = mtx_owned(&acb->isr_lock);
 1486         if( mutex == 0 )
 1487                 ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
 1488         arcmsr_interrupt(acb);
 1489         if( mutex == 0 )
 1490                 ARCMSR_LOCK_RELEASE(&acb->isr_lock);
 1491 }
 1492 /*
 1493 **************************************************************************
 1494 **************************************************************************
 1495 */
 1496 static u_int32_t arcmsr_Read_iop_rqbuffer_data_D(struct AdapterControlBlock *acb,
 1497         struct QBUFFER *prbuffer) {
 1498         u_int8_t *pQbuffer;
 1499         u_int8_t *buf1 = NULL;
 1500         u_int32_t *iop_data, *buf2 = NULL;
 1501         u_int32_t iop_len, data_len;
 1502 
 1503         iop_data = (u_int32_t *)prbuffer->data;
 1504         iop_len = (u_int32_t)prbuffer->data_len;
 1505         if ( iop_len > 0 )
 1506         {
 1507                 buf1 = malloc(128, M_DEVBUF, M_NOWAIT | M_ZERO);
 1508                 buf2 = (u_int32_t *)buf1;
 1509                 if( buf1 == NULL)
 1510                         return (0);
 1511                 data_len = iop_len;
 1512                 while(data_len >= 4)
 1513                 {
 1514                         *buf2++ = *iop_data++;
 1515                         data_len -= 4;
 1516                 }
 1517                 if(data_len)
 1518                         *buf2 = *iop_data;
 1519                 buf2 = (u_int32_t *)buf1;
 1520         }
 1521         while (iop_len > 0) {
 1522                 pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex];
 1523                 *pQbuffer = *buf1;
 1524                 acb->rqbuf_lastindex++;
 1525                 /* if last, index number set it to 0 */
 1526                 acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
 1527                 buf1++;
 1528                 iop_len--;
 1529         }
 1530         if(buf2)
 1531                 free( (u_int8_t *)buf2, M_DEVBUF);
 1532         /* let IOP know data has been read */
 1533         arcmsr_iop_message_read(acb);
 1534         return (1);
 1535 }
 1536 /*
 1537 **************************************************************************
 1538 **************************************************************************
 1539 */
 1540 static u_int32_t arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb,
 1541         struct QBUFFER *prbuffer) {
 1542         u_int8_t *pQbuffer;
 1543         u_int8_t *iop_data;
 1544         u_int32_t iop_len;
 1545 
 1546         if(acb->adapter_type >= ACB_ADAPTER_TYPE_B) {
 1547                 return(arcmsr_Read_iop_rqbuffer_data_D(acb, prbuffer));
 1548         }
 1549         iop_data = (u_int8_t *)prbuffer->data;
 1550         iop_len = (u_int32_t)prbuffer->data_len;
 1551         while (iop_len > 0) {
 1552                 pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex];
 1553                 *pQbuffer = *iop_data;
 1554                 acb->rqbuf_lastindex++;
 1555                 /* if last, index number set it to 0 */
 1556                 acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
 1557                 iop_data++;
 1558                 iop_len--;
 1559         }
 1560         /* let IOP know data has been read */
 1561         arcmsr_iop_message_read(acb);
 1562         return (1);
 1563 }
 1564 /*
 1565 **************************************************************************
 1566 **************************************************************************
 1567 */
 1568 static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb)
 1569 {
 1570         struct QBUFFER *prbuffer;
 1571         int my_empty_len;
 1572 
 1573         /*check this iop data if overflow my rqbuffer*/
 1574         ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 1575         prbuffer = arcmsr_get_iop_rqbuffer(acb);
 1576         my_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) &
 1577                 (ARCMSR_MAX_QBUFFER-1);
 1578         if(my_empty_len >= prbuffer->data_len) {
 1579                 if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
 1580                         acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
 1581         } else {
 1582                 acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
 1583         }
 1584         ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 1585 }
 1586 /*
 1587 **********************************************************************
 1588 **********************************************************************
 1589 */
 1590 static void arcmsr_Write_data_2iop_wqbuffer_D(struct AdapterControlBlock *acb)
 1591 {
 1592         u_int8_t *pQbuffer;
 1593         struct QBUFFER *pwbuffer;
 1594         u_int8_t *buf1 = NULL;
 1595         u_int32_t *iop_data, *buf2 = NULL;
 1596         u_int32_t allxfer_len = 0, data_len;
 1597 
 1598         if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) {
 1599                 buf1 = malloc(128, M_DEVBUF, M_NOWAIT | M_ZERO);
 1600                 buf2 = (u_int32_t *)buf1;
 1601                 if( buf1 == NULL)
 1602                         return;
 1603 
 1604                 acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ);
 1605                 pwbuffer = arcmsr_get_iop_wqbuffer(acb);
 1606                 iop_data = (u_int32_t *)pwbuffer->data;
 1607                 while((acb->wqbuf_firstindex != acb->wqbuf_lastindex) 
 1608                         && (allxfer_len < 124)) {
 1609                         pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex];
 1610                         *buf1 = *pQbuffer;
 1611                         acb->wqbuf_firstindex++;
 1612                         acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
 1613                         buf1++;
 1614                         allxfer_len++;
 1615                 }
 1616                 pwbuffer->data_len = allxfer_len;
 1617                 data_len = allxfer_len;
 1618                 buf1 = (u_int8_t *)buf2;
 1619                 while(data_len >= 4)
 1620                 {
 1621                         *iop_data++ = *buf2++;
 1622                         data_len -= 4;
 1623                 }
 1624                 if(data_len)
 1625                         *iop_data = *buf2;
 1626                 free( buf1, M_DEVBUF);
 1627                 arcmsr_iop_message_wrote(acb);
 1628         }
 1629 }
 1630 /*
 1631 **********************************************************************
 1632 **********************************************************************
 1633 */
 1634 static void arcmsr_Write_data_2iop_wqbuffer(struct AdapterControlBlock *acb)
 1635 {
 1636         u_int8_t *pQbuffer;
 1637         struct QBUFFER *pwbuffer;
 1638         u_int8_t *iop_data;
 1639         int32_t allxfer_len=0;
 1640 
 1641         if(acb->adapter_type >= ACB_ADAPTER_TYPE_B) {
 1642                 arcmsr_Write_data_2iop_wqbuffer_D(acb);
 1643                 return;
 1644         }
 1645         if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) {
 1646                 acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ);
 1647                 pwbuffer = arcmsr_get_iop_wqbuffer(acb);
 1648                 iop_data = (u_int8_t *)pwbuffer->data;
 1649                 while((acb->wqbuf_firstindex != acb->wqbuf_lastindex) 
 1650                         && (allxfer_len < 124)) {
 1651                         pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex];
 1652                         *iop_data = *pQbuffer;
 1653                         acb->wqbuf_firstindex++;
 1654                         acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
 1655                         iop_data++;
 1656                         allxfer_len++;
 1657                 }
 1658                 pwbuffer->data_len = allxfer_len;
 1659                 arcmsr_iop_message_wrote(acb);
 1660         }
 1661 }
 1662 /*
 1663 **************************************************************************
 1664 **************************************************************************
 1665 */
 1666 static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb)
 1667 {
 1668         ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 1669         acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READ;
 1670         /*
 1671         *****************************************************************
 1672         **   check if there are any mail packages from user space program
 1673         **   in my post bag, now is the time to send them into Areca's firmware
 1674         *****************************************************************
 1675         */
 1676         if(acb->wqbuf_firstindex != acb->wqbuf_lastindex) {
 1677                 arcmsr_Write_data_2iop_wqbuffer(acb);
 1678         }
 1679         if(acb->wqbuf_firstindex == acb->wqbuf_lastindex) {
 1680                 acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED;
 1681         }
 1682         ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 1683 }
 1684 /*
 1685 **************************************************************************
 1686 **************************************************************************
 1687 */
 1688 static void arcmsr_rescanLun_cb(struct cam_periph *periph, union ccb *ccb)
 1689 {
 1690 /*
 1691         if (ccb->ccb_h.status != CAM_REQ_CMP)
 1692                 printf("arcmsr_rescanLun_cb: Rescan Target=%x, lun=%x,"
 1693                         "failure status=%x\n", ccb->ccb_h.target_id,
 1694                         ccb->ccb_h.target_lun, ccb->ccb_h.status);
 1695         else
 1696                 printf("arcmsr_rescanLun_cb: Rescan lun successfully!\n");
 1697 */
 1698         xpt_free_path(ccb->ccb_h.path);
 1699         xpt_free_ccb(ccb);
 1700 }
 1701 
 1702 static void     arcmsr_rescan_lun(struct AdapterControlBlock *acb, int target, int lun)
 1703 {
 1704         struct cam_path     *path;
 1705         union ccb           *ccb;
 1706 
 1707         if ((ccb = (union ccb *)xpt_alloc_ccb_nowait()) == NULL)
 1708                 return;
 1709         if (xpt_create_path(&path, NULL, cam_sim_path(acb->psim), target, lun) != CAM_REQ_CMP)
 1710         {
 1711                 xpt_free_ccb(ccb);
 1712                 return;
 1713         }
 1714 /*      printf("arcmsr_rescan_lun: Rescan Target=%x, Lun=%x\n", target, lun); */
 1715         bzero(ccb, sizeof(union ccb));
 1716         xpt_setup_ccb(&ccb->ccb_h, path, 5);
 1717         ccb->ccb_h.func_code = XPT_SCAN_LUN;
 1718         ccb->ccb_h.cbfcnp = arcmsr_rescanLun_cb;
 1719         ccb->crcn.flags = CAM_FLAG_NONE;
 1720         xpt_action(ccb);
 1721 }
 1722 
 1723 static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, int lun)
 1724 {
 1725         struct CommandControlBlock *srb;
 1726         u_int32_t intmask_org;
 1727         int i;
 1728 
 1729         /* disable all outbound interrupts */
 1730         intmask_org = arcmsr_disable_allintr(acb);
 1731         for (i = 0; i < ARCMSR_MAX_FREESRB_NUM; i++)
 1732         {
 1733                 srb = acb->psrb_pool[i];
 1734                 if (srb->srb_state == ARCMSR_SRB_START)
 1735                 {
 1736                         if((target == srb->pccb->ccb_h.target_id) && (lun == srb->pccb->ccb_h.target_lun))
 1737                         {
 1738                                 srb->srb_state = ARCMSR_SRB_ABORTED;
 1739                                 srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
 1740                                 arcmsr_srb_complete(srb, 1);
 1741                                 printf("arcmsr%d: abort scsi id %d lun %d srb=%p \n", acb->pci_unit, target, lun, srb);
 1742                         }
 1743                 }
 1744         }
 1745         /* enable outbound Post Queue, outbound doorbell Interrupt */
 1746         arcmsr_enable_allintr(acb, intmask_org);
 1747 }
 1748 /*
 1749 **************************************************************************
 1750 **************************************************************************
 1751 */
 1752 static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
 1753         u_int32_t       devicemap;
 1754         u_int32_t       target, lun;
 1755         u_int32_t       deviceMapCurrent[4]={0};
 1756         u_int8_t        *pDevMap;
 1757 
 1758         switch (acb->adapter_type) {
 1759         case ACB_ADAPTER_TYPE_A:
 1760                 devicemap = offsetof(struct HBA_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
 1761                 for (target = 0; target < 4; target++) 
 1762                 {
 1763                         deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0],  devicemap);
 1764                         devicemap += 4;
 1765                 }
 1766                 break;
 1767 
 1768         case ACB_ADAPTER_TYPE_B:
 1769                 devicemap = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
 1770                 for (target = 0; target < 4; target++) 
 1771                 {
 1772                         deviceMapCurrent[target]=bus_space_read_4(acb->btag[1], acb->bhandle[1],  devicemap);
 1773                         devicemap += 4;
 1774                 }
 1775                 break;
 1776 
 1777         case ACB_ADAPTER_TYPE_C:
 1778                 devicemap = offsetof(struct HBC_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
 1779                 for (target = 0; target < 4; target++) 
 1780                 {
 1781                         deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0],  devicemap);
 1782                         devicemap += 4;
 1783                 }
 1784                 break;
 1785         case ACB_ADAPTER_TYPE_D:
 1786                 devicemap = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
 1787                 for (target = 0; target < 4; target++) 
 1788                 {
 1789                         deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0],  devicemap);
 1790                         devicemap += 4;
 1791                 }
 1792                 break;
 1793         case ACB_ADAPTER_TYPE_E:
 1794                 devicemap = offsetof(struct HBE_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
 1795                 for (target = 0; target < 4; target++) 
 1796                 {
 1797                         deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0],  devicemap);
 1798                         devicemap += 4;
 1799                 }
 1800                 break;
 1801         case ACB_ADAPTER_TYPE_F:
 1802                 devicemap = ARCMSR_FW_DEVMAP_OFFSET;
 1803                 for (target = 0; target < 4; target++)
 1804                 {
 1805                         deviceMapCurrent[target] = acb->msgcode_rwbuffer[devicemap];
 1806                         devicemap += 1;
 1807                 }
 1808                 break;
 1809         }
 1810 
 1811         if(acb->acb_flags & ACB_F_BUS_HANG_ON)
 1812         {
 1813                 acb->acb_flags &= ~ACB_F_BUS_HANG_ON;
 1814         }
 1815         /* 
 1816         ** adapter posted CONFIG message 
 1817         ** copy the new map, note if there are differences with the current map
 1818         */
 1819         pDevMap = (u_int8_t *)&deviceMapCurrent[0];
 1820         for (target = 0; target < ARCMSR_MAX_TARGETID - 1; target++) 
 1821         {
 1822                 if (*pDevMap != acb->device_map[target])
 1823                 {
 1824                         u_int8_t difference, bit_check;
 1825 
 1826                         difference = *pDevMap ^ acb->device_map[target];
 1827                         for(lun=0; lun < ARCMSR_MAX_TARGETLUN; lun++)
 1828                         {
 1829                                 bit_check = (1 << lun);         /*check bit from 0....31*/
 1830                                 if(difference & bit_check)
 1831                                 {
 1832                                         if(acb->device_map[target] & bit_check)
 1833                                         {/* unit departed */
 1834                                                 printf("arcmsr_dr_handle: Target=%x, lun=%x, GONE!!!\n",target,lun);
 1835                                                 arcmsr_abort_dr_ccbs(acb, target, lun);
 1836                                                 arcmsr_rescan_lun(acb, target, lun);
 1837                                                 acb->devstate[target][lun] = ARECA_RAID_GONE;
 1838                                         }
 1839                                         else
 1840                                         {/* unit arrived */
 1841                                                 printf("arcmsr_dr_handle: Target=%x, lun=%x, Plug-IN!!!\n",target,lun);
 1842                                                 arcmsr_rescan_lun(acb, target, lun);
 1843                                                 acb->devstate[target][lun] = ARECA_RAID_GOOD;
 1844                                         }
 1845                                 }
 1846                         }
 1847 /*                      printf("arcmsr_dr_handle: acb->device_map[%x]=0x%x, deviceMapCurrent[%x]=%x\n",target,acb->device_map[target],target,*pDevMap); */
 1848                         acb->device_map[target] = *pDevMap;
 1849                 }
 1850                 pDevMap++;
 1851         }
 1852 }
 1853 /*
 1854 **************************************************************************
 1855 **************************************************************************
 1856 */
 1857 static void arcmsr_hba_message_isr(struct AdapterControlBlock *acb) {
 1858         u_int32_t outbound_message;
 1859 
 1860         CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, ARCMSR_MU_OUTBOUND_MESSAGE0_INT);
 1861         outbound_message = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[0]);
 1862         if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
 1863                 arcmsr_dr_handle( acb );
 1864 }
 1865 /*
 1866 **************************************************************************
 1867 **************************************************************************
 1868 */
 1869 static void arcmsr_hbb_message_isr(struct AdapterControlBlock *acb) {
 1870         u_int32_t outbound_message;
 1871         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 1872 
 1873         /* clear interrupts */
 1874         WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_MESSAGE_INT_CLEAR_PATTERN);
 1875         outbound_message = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[0]);
 1876         if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
 1877                 arcmsr_dr_handle( acb );
 1878 }
 1879 /*
 1880 **************************************************************************
 1881 **************************************************************************
 1882 */
 1883 static void arcmsr_hbc_message_isr(struct AdapterControlBlock *acb) {
 1884         u_int32_t outbound_message;
 1885 
 1886         CHIP_REG_WRITE32(HBC_MessageUnit, 0, outbound_doorbell_clear, ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR);
 1887         outbound_message = CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[0]);
 1888         if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
 1889                 arcmsr_dr_handle( acb );
 1890 }
 1891 /*
 1892 **************************************************************************
 1893 **************************************************************************
 1894 */
 1895 static void arcmsr_hbd_message_isr(struct AdapterControlBlock *acb) {
 1896         u_int32_t outbound_message;
 1897 
 1898         CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR);
 1899         outbound_message = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[0]);
 1900         if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
 1901                 arcmsr_dr_handle( acb );
 1902 }
 1903 /*
 1904 **************************************************************************
 1905 **************************************************************************
 1906 */
 1907 static void arcmsr_hbe_message_isr(struct AdapterControlBlock *acb) {
 1908         u_int32_t outbound_message;
 1909 
 1910         CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0);
 1911         if (acb->adapter_type == ACB_ADAPTER_TYPE_E)
 1912                 outbound_message = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[0]);
 1913         else
 1914                 outbound_message = acb->msgcode_rwbuffer[0];
 1915         if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
 1916                 arcmsr_dr_handle( acb );
 1917 }
 1918 /*
 1919 **************************************************************************
 1920 **************************************************************************
 1921 */
 1922 static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb)
 1923 {
 1924         u_int32_t doorbell_status;
 1925 
 1926         /*
 1927         *******************************************************************
 1928         **  Maybe here we need to check wrqbuffer_lock is lock or not
 1929         **  DOORBELL: din! don! 
 1930         **  check if there are any mail need to pack from firmware
 1931         *******************************************************************
 1932         */
 1933         doorbell_status = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_doorbell);
 1934         CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_doorbell, doorbell_status); /* clear doorbell interrupt */
 1935         if(doorbell_status & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) {
 1936                 arcmsr_iop2drv_data_wrote_handle(acb);
 1937         }
 1938         if(doorbell_status & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) {
 1939                 arcmsr_iop2drv_data_read_handle(acb);
 1940         }
 1941 }
 1942 /*
 1943 **************************************************************************
 1944 **************************************************************************
 1945 */
 1946 static void arcmsr_hbc_doorbell_isr(struct AdapterControlBlock *acb)
 1947 {
 1948         u_int32_t doorbell_status;
 1949 
 1950         /*
 1951         *******************************************************************
 1952         **  Maybe here we need to check wrqbuffer_lock is lock or not
 1953         **  DOORBELL: din! don! 
 1954         **  check if there are any mail need to pack from firmware
 1955         *******************************************************************
 1956         */
 1957         doorbell_status = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell);
 1958         CHIP_REG_WRITE32(HBC_MessageUnit, 0, outbound_doorbell_clear, doorbell_status); /* clear doorbell interrupt */
 1959         if(doorbell_status & ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK) {
 1960                 arcmsr_iop2drv_data_wrote_handle(acb);
 1961         }
 1962         if(doorbell_status & ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK) {
 1963                 arcmsr_iop2drv_data_read_handle(acb);
 1964         }
 1965         if(doorbell_status & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
 1966                 arcmsr_hbc_message_isr(acb);    /* messenger of "driver to iop commands" */
 1967         }
 1968 }
 1969 /*
 1970 **************************************************************************
 1971 **************************************************************************
 1972 */
 1973 static void arcmsr_hbd_doorbell_isr(struct AdapterControlBlock *acb)
 1974 {
 1975         u_int32_t doorbell_status;
 1976 
 1977         /*
 1978         *******************************************************************
 1979         **  Maybe here we need to check wrqbuffer_lock is lock or not
 1980         **  DOORBELL: din! don! 
 1981         **  check if there are any mail need to pack from firmware
 1982         *******************************************************************
 1983         */
 1984         doorbell_status = CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_F0_DOORBELL_CAUSE;
 1985         if(doorbell_status)
 1986                 CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, doorbell_status); /* clear doorbell interrupt */
 1987         while( doorbell_status & ARCMSR_HBDMU_F0_DOORBELL_CAUSE ) {
 1988                 if(doorbell_status & ARCMSR_HBDMU_IOP2DRV_DATA_WRITE_OK) {
 1989                         arcmsr_iop2drv_data_wrote_handle(acb);
 1990                 }
 1991                 if(doorbell_status & ARCMSR_HBDMU_IOP2DRV_DATA_READ_OK) {
 1992                         arcmsr_iop2drv_data_read_handle(acb);
 1993                 }
 1994                 if(doorbell_status & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE) {
 1995                         arcmsr_hbd_message_isr(acb);    /* messenger of "driver to iop commands" */
 1996                 }
 1997                 doorbell_status = CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_F0_DOORBELL_CAUSE;
 1998                 if(doorbell_status)
 1999                         CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, doorbell_status); /* clear doorbell interrupt */
 2000         }
 2001 }
 2002 /*
 2003 **************************************************************************
 2004 **************************************************************************
 2005 */
 2006 static void arcmsr_hbe_doorbell_isr(struct AdapterControlBlock *acb)
 2007 {
 2008         u_int32_t doorbell_status, in_doorbell;
 2009 
 2010         /*
 2011         *******************************************************************
 2012         **  Maybe here we need to check wrqbuffer_lock is lock or not
 2013         **  DOORBELL: din! don! 
 2014         **  check if there are any mail need to pack from firmware
 2015         *******************************************************************
 2016         */
 2017         in_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell);
 2018         CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0); /* clear doorbell interrupt */
 2019         doorbell_status = in_doorbell ^ acb->in_doorbell;
 2020         if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_DATA_WRITE_OK) {
 2021                 arcmsr_iop2drv_data_wrote_handle(acb);
 2022         }
 2023         if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_DATA_READ_OK) {
 2024                 arcmsr_iop2drv_data_read_handle(acb);
 2025         }
 2026         if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_MESSAGE_CMD_DONE) {
 2027                 arcmsr_hbe_message_isr(acb);    /* messenger of "driver to iop commands" */
 2028         }
 2029         acb->in_doorbell = in_doorbell;
 2030 }
 2031 /*
 2032 **************************************************************************
 2033 **************************************************************************
 2034 */
 2035 static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
 2036 {
 2037         u_int32_t flag_srb;
 2038         u_int16_t error;
 2039 
 2040         /*
 2041         *****************************************************************************
 2042         **               areca cdb command done
 2043         *****************************************************************************
 2044         */
 2045         bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, 
 2046                 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 2047         while((flag_srb = CHIP_REG_READ32(HBA_MessageUnit, 
 2048                 0, outbound_queueport)) != 0xFFFFFFFF) {
 2049                 /* check if command done with no error*/
 2050                 error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0) ? TRUE : FALSE;
 2051                 arcmsr_drain_donequeue(acb, flag_srb, error);
 2052         }       /*drain reply FIFO*/
 2053 }
 2054 /*
 2055 **************************************************************************
 2056 **************************************************************************
 2057 */
 2058 static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb)
 2059 {
 2060         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 2061         u_int32_t flag_srb;
 2062         int index;
 2063         u_int16_t error;
 2064 
 2065         /*
 2066         *****************************************************************************
 2067         **               areca cdb command done
 2068         *****************************************************************************
 2069         */
 2070         bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, 
 2071                 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 2072         index = phbbmu->doneq_index;
 2073         while((flag_srb = phbbmu->done_qbuffer[index]) != 0) {
 2074                 phbbmu->done_qbuffer[index] = 0;
 2075                 index++;
 2076                 index %= ARCMSR_MAX_HBB_POSTQUEUE;     /*if last index number set it to 0 */
 2077                 phbbmu->doneq_index = index;
 2078                 /* check if command done with no error*/
 2079                 error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
 2080                 arcmsr_drain_donequeue(acb, flag_srb, error);
 2081         }       /*drain reply FIFO*/
 2082 }
 2083 /*
 2084 **************************************************************************
 2085 **************************************************************************
 2086 */
 2087 static void arcmsr_hbc_postqueue_isr(struct AdapterControlBlock *acb)
 2088 {
 2089         u_int32_t flag_srb,throttling = 0;
 2090         u_int16_t error;
 2091 
 2092         /*
 2093         *****************************************************************************
 2094         **               areca cdb command done
 2095         *****************************************************************************
 2096         */
 2097         bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 2098         do {
 2099                 flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
 2100                 if (flag_srb == 0xFFFFFFFF)
 2101                         break;
 2102                 /* check if command done with no error*/
 2103                 error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE;
 2104                 arcmsr_drain_donequeue(acb, flag_srb, error);
 2105                 throttling++;
 2106                 if(throttling == ARCMSR_HBC_ISR_THROTTLING_LEVEL) {
 2107                         CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING);
 2108                         throttling = 0;
 2109                 }
 2110         } while(CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR);
 2111 }
 2112 /*
 2113 **********************************************************************
 2114 ** 
 2115 **********************************************************************
 2116 */
 2117 static uint16_t arcmsr_get_doneq_index(struct HBD_MessageUnit0 *phbdmu)
 2118 {
 2119         uint16_t doneq_index, index_stripped;
 2120 
 2121         doneq_index = phbdmu->doneq_index;
 2122         if (doneq_index & 0x4000) {
 2123                 index_stripped = doneq_index & 0xFF;
 2124                 index_stripped += 1;
 2125                 index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
 2126                 phbdmu->doneq_index = index_stripped ?
 2127                     (index_stripped | 0x4000) : index_stripped;
 2128         } else {
 2129                 index_stripped = doneq_index;
 2130                 index_stripped += 1;
 2131                 index_stripped %= ARCMSR_MAX_HBD_POSTQUEUE;
 2132                 phbdmu->doneq_index = index_stripped ?
 2133                     index_stripped : (index_stripped | 0x4000);
 2134         }
 2135         return (phbdmu->doneq_index);
 2136 }
 2137 /*
 2138 **************************************************************************
 2139 **************************************************************************
 2140 */
 2141 static void arcmsr_hbd_postqueue_isr(struct AdapterControlBlock *acb)
 2142 {
 2143         struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
 2144         u_int32_t outbound_write_pointer;
 2145         u_int32_t addressLow;
 2146         uint16_t doneq_index;
 2147         u_int16_t error;
 2148         /*
 2149         *****************************************************************************
 2150         **               areca cdb command done
 2151         *****************************************************************************
 2152         */
 2153         if((CHIP_REG_READ32(HBD_MessageUnit, 0, outboundlist_interrupt_cause) &
 2154                 ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT) == 0)
 2155                 return;
 2156         bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, 
 2157                 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 2158         outbound_write_pointer = phbdmu->done_qbuffer[0].addressLow;
 2159         doneq_index = phbdmu->doneq_index;
 2160         while ((doneq_index & 0xFF) != (outbound_write_pointer & 0xFF)) {
 2161                 doneq_index = arcmsr_get_doneq_index(phbdmu);
 2162                 addressLow = phbdmu->done_qbuffer[(doneq_index & 0xFF)+1].addressLow;
 2163                 error = (addressLow & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
 2164                 arcmsr_drain_donequeue(acb, addressLow, error); /*Check if command done with no error */
 2165                 CHIP_REG_WRITE32(HBD_MessageUnit, 0, outboundlist_read_pointer, doneq_index);
 2166                 outbound_write_pointer = phbdmu->done_qbuffer[0].addressLow;
 2167         }
 2168         CHIP_REG_WRITE32(HBD_MessageUnit, 0, outboundlist_interrupt_cause, ARCMSR_HBDMU_OUTBOUND_LIST_INTERRUPT_CLEAR);
 2169         CHIP_REG_READ32(HBD_MessageUnit, 0, outboundlist_interrupt_cause); /*Dummy ioread32 to force pci flush */
 2170 }
 2171 /*
 2172 **************************************************************************
 2173 **************************************************************************
 2174 */
 2175 static void arcmsr_hbe_postqueue_isr(struct AdapterControlBlock *acb)
 2176 {
 2177         u_int16_t error;
 2178         uint32_t doneq_index;
 2179         uint16_t cmdSMID;
 2180 
 2181         /*
 2182         *****************************************************************************
 2183         **               areca cdb command done
 2184         *****************************************************************************
 2185         */
 2186         bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 2187         doneq_index = acb->doneq_index;
 2188         while ((CHIP_REG_READ32(HBE_MessageUnit, 0, reply_post_producer_index) & 0xFFFF) != doneq_index) {
 2189                 cmdSMID = acb->pCompletionQ[doneq_index].cmdSMID;
 2190                 error = (acb->pCompletionQ[doneq_index].cmdFlag & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
 2191                 arcmsr_drain_donequeue(acb, (u_int32_t)cmdSMID, error);
 2192                 doneq_index++;
 2193                 if (doneq_index >= acb->completionQ_entry)
 2194                         doneq_index = 0;
 2195         }
 2196         acb->doneq_index = doneq_index;
 2197         CHIP_REG_WRITE32(HBE_MessageUnit, 0, reply_post_consumer_index, doneq_index);
 2198 }
 2199 
 2200 static void arcmsr_hbf_postqueue_isr(struct AdapterControlBlock *acb)
 2201 {
 2202         uint16_t error;
 2203         uint32_t doneq_index;
 2204         uint16_t cmdSMID;
 2205 
 2206         /*
 2207         *****************************************************************************
 2208         **               areca cdb command done
 2209         *****************************************************************************
 2210         */
 2211         bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 2212         doneq_index = acb->doneq_index;
 2213         while (1) {
 2214                 cmdSMID = acb->pCompletionQ[doneq_index].cmdSMID;
 2215                 if (cmdSMID == 0xffff)
 2216                         break;
 2217                 error = (acb->pCompletionQ[doneq_index].cmdFlag & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
 2218                 arcmsr_drain_donequeue(acb, (u_int32_t)cmdSMID, error);
 2219                 acb->pCompletionQ[doneq_index].cmdSMID = 0xffff;
 2220                 doneq_index++;
 2221                 if (doneq_index >= acb->completionQ_entry)
 2222                         doneq_index = 0;
 2223         }
 2224         acb->doneq_index = doneq_index;
 2225         CHIP_REG_WRITE32(HBF_MessageUnit, 0, reply_post_consumer_index, doneq_index);
 2226 }
 2227 
 2228 /*
 2229 **********************************************************************
 2230 **********************************************************************
 2231 */
 2232 static void arcmsr_handle_hba_isr( struct AdapterControlBlock *acb)
 2233 {
 2234         u_int32_t outbound_intStatus;
 2235         /*
 2236         *********************************************
 2237         **   check outbound intstatus 
 2238         *********************************************
 2239         */
 2240         outbound_intStatus = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable;
 2241         if(!outbound_intStatus) {
 2242                 /*it must be share irq*/
 2243                 return;
 2244         }
 2245         CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intStatus); /*clear interrupt*/
 2246         /* MU doorbell interrupts*/
 2247         if(outbound_intStatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT) {
 2248                 arcmsr_hba_doorbell_isr(acb);
 2249         }
 2250         /* MU post queue interrupts*/
 2251         if(outbound_intStatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT) {
 2252                 arcmsr_hba_postqueue_isr(acb);
 2253         }
 2254         if(outbound_intStatus & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
 2255                 arcmsr_hba_message_isr(acb);
 2256         }
 2257 }
 2258 /*
 2259 **********************************************************************
 2260 **********************************************************************
 2261 */
 2262 static void arcmsr_handle_hbb_isr( struct AdapterControlBlock *acb)
 2263 {
 2264         u_int32_t outbound_doorbell;
 2265         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 2266         /*
 2267         *********************************************
 2268         **   check outbound intstatus 
 2269         *********************************************
 2270         */
 2271         outbound_doorbell = READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell) & acb->outbound_int_enable;
 2272         if(!outbound_doorbell) {
 2273                 /*it must be share irq*/
 2274                 return;
 2275         }
 2276         WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ~outbound_doorbell); /* clear doorbell interrupt */
 2277         READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell);
 2278         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
 2279         /* MU ioctl transfer doorbell interrupts*/
 2280         if(outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK) {
 2281                 arcmsr_iop2drv_data_wrote_handle(acb);
 2282         }
 2283         if(outbound_doorbell & ARCMSR_IOP2DRV_DATA_READ_OK) {
 2284                 arcmsr_iop2drv_data_read_handle(acb);
 2285         }
 2286         /* MU post queue interrupts*/
 2287         if(outbound_doorbell & ARCMSR_IOP2DRV_CDB_DONE) {
 2288                 arcmsr_hbb_postqueue_isr(acb);
 2289         }
 2290         if(outbound_doorbell & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
 2291                 arcmsr_hbb_message_isr(acb);
 2292         }
 2293 }
 2294 /*
 2295 **********************************************************************
 2296 **********************************************************************
 2297 */
 2298 static void arcmsr_handle_hbc_isr( struct AdapterControlBlock *acb)
 2299 {
 2300         u_int32_t host_interrupt_status;
 2301         /*
 2302         *********************************************
 2303         **   check outbound intstatus 
 2304         *********************************************
 2305         */
 2306         host_interrupt_status = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) &
 2307                 (ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR |
 2308                 ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR);
 2309         if(!host_interrupt_status) {
 2310                 /*it must be share irq*/
 2311                 return;
 2312         }
 2313         do {
 2314                 /* MU doorbell interrupts*/
 2315                 if(host_interrupt_status & ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR) {
 2316                         arcmsr_hbc_doorbell_isr(acb);
 2317                 }
 2318                 /* MU post queue interrupts*/
 2319                 if(host_interrupt_status & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) {
 2320                         arcmsr_hbc_postqueue_isr(acb);
 2321                 }
 2322                 host_interrupt_status = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status);
 2323         } while (host_interrupt_status & (ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR | ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR));
 2324 }
 2325 /*
 2326 **********************************************************************
 2327 **********************************************************************
 2328 */
 2329 static void arcmsr_handle_hbd_isr( struct AdapterControlBlock *acb)
 2330 {
 2331         u_int32_t host_interrupt_status;
 2332         u_int32_t intmask_org;
 2333         /*
 2334         *********************************************
 2335         **   check outbound intstatus 
 2336         *********************************************
 2337         */
 2338         host_interrupt_status = CHIP_REG_READ32(HBD_MessageUnit, 0, host_int_status) & acb->outbound_int_enable;
 2339         if(!(host_interrupt_status & ARCMSR_HBDMU_OUTBOUND_INT)) {
 2340                 /*it must be share irq*/
 2341                 return;
 2342         }
 2343         /* disable outbound interrupt */
 2344         intmask_org = CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable)    ; /* disable outbound message0 int */
 2345         CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, ARCMSR_HBDMU_ALL_INT_DISABLE);
 2346         /* MU doorbell interrupts*/
 2347         if(host_interrupt_status & ARCMSR_HBDMU_OUTBOUND_DOORBELL_INT) {
 2348                 arcmsr_hbd_doorbell_isr(acb);
 2349         }
 2350         /* MU post queue interrupts*/
 2351         if(host_interrupt_status & ARCMSR_HBDMU_OUTBOUND_POSTQUEUE_INT) {
 2352                 arcmsr_hbd_postqueue_isr(acb);
 2353         }
 2354         /* enable all outbound interrupt */
 2355         CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, intmask_org | ARCMSR_HBDMU_ALL_INT_ENABLE);
 2356 //      CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable);
 2357 }
 2358 /*
 2359 **********************************************************************
 2360 **********************************************************************
 2361 */
 2362 static void arcmsr_handle_hbe_isr( struct AdapterControlBlock *acb)
 2363 {
 2364         u_int32_t host_interrupt_status;
 2365         /*
 2366         *********************************************
 2367         **   check outbound intstatus 
 2368         *********************************************
 2369         */
 2370         host_interrupt_status = CHIP_REG_READ32(HBE_MessageUnit, 0, host_int_status) &
 2371                 (ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR |
 2372                 ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR);
 2373         if(!host_interrupt_status) {
 2374                 /*it must be share irq*/
 2375                 return;
 2376         }
 2377         do {
 2378                 /* MU doorbell interrupts*/
 2379                 if(host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR) {
 2380                         arcmsr_hbe_doorbell_isr(acb);
 2381                 }
 2382                 /* MU post queue interrupts*/
 2383                 if(host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR) {
 2384                         arcmsr_hbe_postqueue_isr(acb);
 2385                 }
 2386                 host_interrupt_status = CHIP_REG_READ32(HBE_MessageUnit, 0, host_int_status);
 2387         } while (host_interrupt_status & (ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR | ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR));
 2388 }
 2389 
 2390 static void arcmsr_handle_hbf_isr( struct AdapterControlBlock *acb)
 2391 {
 2392         u_int32_t host_interrupt_status;
 2393         /*
 2394         *********************************************
 2395         **   check outbound intstatus 
 2396         *********************************************
 2397         */
 2398         host_interrupt_status = CHIP_REG_READ32(HBF_MessageUnit, 0, host_int_status) &
 2399                 (ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR |
 2400                 ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR);
 2401         if(!host_interrupt_status) {
 2402                 /*it must be share irq*/
 2403                 return;
 2404         }
 2405         do {
 2406                 /* MU doorbell interrupts*/
 2407                 if(host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR) {
 2408                         arcmsr_hbe_doorbell_isr(acb);
 2409                 }
 2410                 /* MU post queue interrupts*/
 2411                 if(host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR) {
 2412                         arcmsr_hbf_postqueue_isr(acb);
 2413                 }
 2414                 host_interrupt_status = CHIP_REG_READ32(HBF_MessageUnit, 0, host_int_status);
 2415         } while (host_interrupt_status & (ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR | ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR));
 2416 }
 2417 /*
 2418 ******************************************************************************
 2419 ******************************************************************************
 2420 */
 2421 static void arcmsr_interrupt(struct AdapterControlBlock *acb)
 2422 {
 2423         switch (acb->adapter_type) {
 2424         case ACB_ADAPTER_TYPE_A:
 2425                 arcmsr_handle_hba_isr(acb);
 2426                 break;
 2427         case ACB_ADAPTER_TYPE_B:
 2428                 arcmsr_handle_hbb_isr(acb);
 2429                 break;
 2430         case ACB_ADAPTER_TYPE_C:
 2431                 arcmsr_handle_hbc_isr(acb);
 2432                 break;
 2433         case ACB_ADAPTER_TYPE_D:
 2434                 arcmsr_handle_hbd_isr(acb);
 2435                 break;
 2436         case ACB_ADAPTER_TYPE_E:
 2437                 arcmsr_handle_hbe_isr(acb);
 2438                 break;
 2439         case ACB_ADAPTER_TYPE_F:
 2440                 arcmsr_handle_hbf_isr(acb);
 2441                 break;
 2442         default:
 2443                 printf("arcmsr%d: interrupt service,"
 2444                 " unknown adapter type =%d\n", acb->pci_unit, acb->adapter_type);
 2445                 break;
 2446         }
 2447 }
 2448 /*
 2449 **********************************************************************
 2450 **********************************************************************
 2451 */
 2452 static void arcmsr_intr_handler(void *arg)
 2453 {
 2454         struct AdapterControlBlock *acb = (struct AdapterControlBlock *)arg;
 2455 
 2456         ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
 2457         arcmsr_interrupt(acb);
 2458         ARCMSR_LOCK_RELEASE(&acb->isr_lock);
 2459 }
 2460 /*
 2461 ******************************************************************************
 2462 ******************************************************************************
 2463 */
 2464 static void     arcmsr_polling_devmap(void *arg)
 2465 {
 2466         struct AdapterControlBlock *acb = (struct AdapterControlBlock *)arg;
 2467         switch (acb->adapter_type) {
 2468         case ACB_ADAPTER_TYPE_A:
 2469                 CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
 2470                 break;
 2471 
 2472         case ACB_ADAPTER_TYPE_B: {
 2473                         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 2474                         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_GET_CONFIG);
 2475                 }
 2476                 break;
 2477 
 2478         case ACB_ADAPTER_TYPE_C:
 2479                 CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
 2480                 CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
 2481                 break;
 2482 
 2483         case ACB_ADAPTER_TYPE_D:
 2484                 CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
 2485                 break;
 2486 
 2487         case ACB_ADAPTER_TYPE_E:
 2488                 CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
 2489                 acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
 2490                 CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
 2491                 break;
 2492 
 2493         case ACB_ADAPTER_TYPE_F: {
 2494                 u_int32_t outMsg1 = CHIP_REG_READ32(HBF_MessageUnit, 0, outbound_msgaddr1);
 2495                 if (!(outMsg1 & ARCMSR_HBFMU_MESSAGE_FIRMWARE_OK) ||
 2496                         (outMsg1 & ARCMSR_HBFMU_MESSAGE_NO_VOLUME_CHANGE))
 2497                         goto nxt6s;
 2498                 CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
 2499                 acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
 2500                 CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
 2501                 break;
 2502                 }
 2503         }
 2504 nxt6s:
 2505         if((acb->acb_flags & ACB_F_SCSISTOPADAPTER) == 0)
 2506         {
 2507                 callout_reset(&acb->devmap_callout, 5 * hz, arcmsr_polling_devmap, acb);        /* polling per 5 seconds */
 2508         }
 2509 }
 2510 
 2511 /*
 2512 *******************************************************************************
 2513 **
 2514 *******************************************************************************
 2515 */
 2516 static void arcmsr_iop_parking(struct AdapterControlBlock *acb)
 2517 {
 2518         u_int32_t intmask_org;
 2519 
 2520         if(acb != NULL) {
 2521                 /* stop adapter background rebuild */
 2522                 if(acb->acb_flags & ACB_F_MSG_START_BGRB) {
 2523                         intmask_org = arcmsr_disable_allintr(acb);
 2524                         arcmsr_stop_adapter_bgrb(acb);
 2525                         arcmsr_flush_adapter_cache(acb);
 2526                         arcmsr_enable_allintr(acb, intmask_org);
 2527                 }
 2528         }
 2529 }
 2530 /*
 2531 ***********************************************************************
 2532 **
 2533 ************************************************************************
 2534 */
 2535 static u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_cmd, caddr_t arg)
 2536 {
 2537         struct CMD_MESSAGE_FIELD *pcmdmessagefld;
 2538         u_int32_t retvalue = EINVAL;
 2539 
 2540         pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) arg;
 2541         if(memcmp(pcmdmessagefld->cmdmessage.Signature, "ARCMSR", 6)!=0) {
 2542                 return retvalue;
 2543         }
 2544         ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 2545         switch(ioctl_cmd) {
 2546         case ARCMSR_MESSAGE_READ_RQBUFFER: {
 2547                         u_int8_t *pQbuffer;
 2548                         u_int8_t *ptmpQbuffer = pcmdmessagefld->messagedatabuffer;                      
 2549                         u_int32_t allxfer_len=0;
 2550 
 2551                         while((acb->rqbuf_firstindex != acb->rqbuf_lastindex) 
 2552                                 && (allxfer_len < 1031)) {
 2553                                 /*copy READ QBUFFER to srb*/
 2554                                 pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
 2555                                 *ptmpQbuffer = *pQbuffer;
 2556                                 acb->rqbuf_firstindex++;
 2557                                 acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; 
 2558                                 /*if last index number set it to 0 */
 2559                                 ptmpQbuffer++;
 2560                                 allxfer_len++;
 2561                         }
 2562                         if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 2563                                 struct QBUFFER *prbuffer;
 2564 
 2565                                 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
 2566                                 prbuffer = arcmsr_get_iop_rqbuffer(acb);
 2567                                 if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
 2568                                         acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
 2569                         }
 2570                         pcmdmessagefld->cmdmessage.Length = allxfer_len;
 2571                         pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
 2572                         retvalue = ARCMSR_MESSAGE_SUCCESS;
 2573                 }
 2574                 break;
 2575         case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
 2576                         u_int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
 2577                         u_int8_t *pQbuffer;
 2578                         u_int8_t *ptmpuserbuffer = pcmdmessagefld->messagedatabuffer;
 2579 
 2580                         user_len = pcmdmessagefld->cmdmessage.Length;
 2581                         /*check if data xfer length of this request will overflow my array qbuffer */
 2582                         wqbuf_lastindex = acb->wqbuf_lastindex;
 2583                         wqbuf_firstindex = acb->wqbuf_firstindex;
 2584                         if(wqbuf_lastindex != wqbuf_firstindex) {
 2585                                 arcmsr_Write_data_2iop_wqbuffer(acb);
 2586                                 pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR;
 2587                         } else {
 2588                                 my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1) &
 2589                                         (ARCMSR_MAX_QBUFFER - 1);
 2590                                 if(my_empty_len >= user_len) {
 2591                                         while(user_len > 0) {
 2592                                                 /*copy srb data to wqbuffer*/
 2593                                                 pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex];
 2594                                                 *pQbuffer = *ptmpuserbuffer;
 2595                                                 acb->wqbuf_lastindex++;
 2596                                                 acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
 2597                                                 /*if last index number set it to 0 */
 2598                                                 ptmpuserbuffer++;
 2599                                                 user_len--;
 2600                                         }
 2601                                         /*post fist Qbuffer*/
 2602                                         if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) {
 2603                                                 acb->acb_flags &= ~ACB_F_MESSAGE_WQBUFFER_CLEARED;
 2604                                                 arcmsr_Write_data_2iop_wqbuffer(acb);
 2605                                         }
 2606                                         pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
 2607                                 } else {
 2608                                         pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR;
 2609                                 }
 2610                         }
 2611                         retvalue = ARCMSR_MESSAGE_SUCCESS;
 2612                 }
 2613                 break;
 2614         case ARCMSR_MESSAGE_CLEAR_RQBUFFER: {
 2615                         u_int8_t *pQbuffer = acb->rqbuffer;
 2616 
 2617                         if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 2618                                 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
 2619                                 arcmsr_iop_message_read(acb);
 2620                                 /*signature, let IOP know data has been readed */
 2621                         }
 2622                         acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
 2623                         acb->rqbuf_firstindex = 0;
 2624                         acb->rqbuf_lastindex = 0;
 2625                         memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
 2626                         pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
 2627                         retvalue = ARCMSR_MESSAGE_SUCCESS;
 2628                 }
 2629                 break;
 2630         case ARCMSR_MESSAGE_CLEAR_WQBUFFER:
 2631                 {
 2632                         u_int8_t *pQbuffer = acb->wqbuffer;
 2633 
 2634                         if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 2635                                 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
 2636                                 arcmsr_iop_message_read(acb);
 2637                                 /*signature, let IOP know data has been readed */
 2638                         }
 2639                         acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED|ACB_F_MESSAGE_WQBUFFER_READ);
 2640                         acb->wqbuf_firstindex = 0;
 2641                         acb->wqbuf_lastindex = 0;
 2642                         memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
 2643                         pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
 2644                         retvalue = ARCMSR_MESSAGE_SUCCESS;
 2645                 }
 2646                 break;
 2647         case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: {
 2648                         u_int8_t *pQbuffer;
 2649 
 2650                         if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 2651                                 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
 2652                                 arcmsr_iop_message_read(acb);
 2653                                 /*signature, let IOP know data has been readed */
 2654                         }
 2655                         acb->acb_flags  |= (ACB_F_MESSAGE_WQBUFFER_CLEARED
 2656                                         |ACB_F_MESSAGE_RQBUFFER_CLEARED
 2657                                         |ACB_F_MESSAGE_WQBUFFER_READ);
 2658                         acb->rqbuf_firstindex = 0;
 2659                         acb->rqbuf_lastindex = 0;
 2660                         acb->wqbuf_firstindex = 0;
 2661                         acb->wqbuf_lastindex = 0;
 2662                         pQbuffer = acb->rqbuffer;
 2663                         memset(pQbuffer, 0, sizeof(struct QBUFFER));
 2664                         pQbuffer = acb->wqbuffer;
 2665                         memset(pQbuffer, 0, sizeof(struct QBUFFER));
 2666                         pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
 2667                         retvalue = ARCMSR_MESSAGE_SUCCESS;
 2668                 }
 2669                 break;
 2670         case ARCMSR_MESSAGE_REQUEST_RETURNCODE_3F: {
 2671                         pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F;
 2672                         retvalue = ARCMSR_MESSAGE_SUCCESS;
 2673                 }
 2674                 break;
 2675         case ARCMSR_MESSAGE_SAY_HELLO: {
 2676                         u_int8_t *hello_string = "Hello! I am ARCMSR";
 2677                         u_int8_t *puserbuffer = (u_int8_t *)pcmdmessagefld->messagedatabuffer;
 2678 
 2679                         if(memcpy(puserbuffer, hello_string, (int16_t)strlen(hello_string))) {
 2680                                 pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_ERROR;
 2681                                 ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 2682                                 return ENOIOCTL;
 2683                         }
 2684                         pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
 2685                         retvalue = ARCMSR_MESSAGE_SUCCESS;
 2686                 }
 2687                 break;
 2688         case ARCMSR_MESSAGE_SAY_GOODBYE: {
 2689                         arcmsr_iop_parking(acb);
 2690                         retvalue = ARCMSR_MESSAGE_SUCCESS;
 2691                 }
 2692                 break;
 2693         case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: {
 2694                         arcmsr_flush_adapter_cache(acb);
 2695                         retvalue = ARCMSR_MESSAGE_SUCCESS;
 2696                 }
 2697                 break;
 2698         }
 2699         ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 2700         return (retvalue);
 2701 }
 2702 /*
 2703 **************************************************************************
 2704 **************************************************************************
 2705 */
 2706 static void arcmsr_free_srb(struct CommandControlBlock *srb)
 2707 {
 2708         struct AdapterControlBlock      *acb;
 2709 
 2710         acb = srb->acb;
 2711         ARCMSR_LOCK_ACQUIRE(&acb->srb_lock);
 2712         srb->srb_state = ARCMSR_SRB_DONE;
 2713         srb->srb_flags = 0;
 2714         acb->srbworkingQ[acb->workingsrb_doneindex] = srb;
 2715         acb->workingsrb_doneindex++;
 2716         acb->workingsrb_doneindex %= ARCMSR_MAX_FREESRB_NUM;
 2717         ARCMSR_LOCK_RELEASE(&acb->srb_lock);
 2718 }
 2719 /*
 2720 **************************************************************************
 2721 **************************************************************************
 2722 */
 2723 static struct CommandControlBlock *arcmsr_get_freesrb(struct AdapterControlBlock *acb)
 2724 {
 2725         struct CommandControlBlock *srb = NULL;
 2726         u_int32_t workingsrb_startindex, workingsrb_doneindex;
 2727 
 2728         ARCMSR_LOCK_ACQUIRE(&acb->srb_lock);
 2729         workingsrb_doneindex = acb->workingsrb_doneindex;
 2730         workingsrb_startindex = acb->workingsrb_startindex;
 2731         srb = acb->srbworkingQ[workingsrb_startindex];
 2732         workingsrb_startindex++;
 2733         workingsrb_startindex %= ARCMSR_MAX_FREESRB_NUM;
 2734         if(workingsrb_doneindex != workingsrb_startindex) {
 2735                 acb->workingsrb_startindex = workingsrb_startindex;
 2736         } else {
 2737                 srb = NULL;
 2738         }
 2739         ARCMSR_LOCK_RELEASE(&acb->srb_lock);
 2740         return(srb);
 2741 }
 2742 /*
 2743 **************************************************************************
 2744 **************************************************************************
 2745 */
 2746 static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *pccb)
 2747 {
 2748         struct CMD_MESSAGE_FIELD *pcmdmessagefld;
 2749         int retvalue = 0, transfer_len = 0;
 2750         char *buffer;
 2751         uint8_t *ptr = scsiio_cdb_ptr(&pccb->csio);
 2752         u_int32_t controlcode = (u_int32_t ) ptr[5] << 24 |
 2753                                 (u_int32_t ) ptr[6] << 16 |
 2754                                 (u_int32_t ) ptr[7] << 8  |
 2755                                 (u_int32_t ) ptr[8];
 2756                                         /* 4 bytes: Areca io control code */
 2757         if ((pccb->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_VADDR) {
 2758                 buffer = pccb->csio.data_ptr;
 2759                 transfer_len = pccb->csio.dxfer_len;
 2760         } else {
 2761                 retvalue = ARCMSR_MESSAGE_FAIL;
 2762                 goto message_out;
 2763         }
 2764         if (transfer_len > sizeof(struct CMD_MESSAGE_FIELD)) {
 2765                 retvalue = ARCMSR_MESSAGE_FAIL;
 2766                 goto message_out;
 2767         }
 2768         pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) buffer;
 2769         switch(controlcode) {
 2770         case ARCMSR_MESSAGE_READ_RQBUFFER: {
 2771                         u_int8_t *pQbuffer;
 2772                         u_int8_t *ptmpQbuffer = pcmdmessagefld->messagedatabuffer;
 2773                         int32_t allxfer_len = 0;
 2774 
 2775                         ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 2776                         while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
 2777                                 && (allxfer_len < 1031)) {
 2778                                 pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
 2779                                 *ptmpQbuffer = *pQbuffer;
 2780                                 acb->rqbuf_firstindex++;
 2781                                 acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
 2782                                 ptmpQbuffer++;
 2783                                 allxfer_len++;
 2784                         }
 2785                         if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 2786                                 struct QBUFFER  *prbuffer;
 2787 
 2788                                 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
 2789                                 prbuffer = arcmsr_get_iop_rqbuffer(acb);
 2790                                 if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
 2791                                         acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
 2792                         }
 2793                         pcmdmessagefld->cmdmessage.Length = allxfer_len;
 2794                         pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
 2795                         retvalue = ARCMSR_MESSAGE_SUCCESS;
 2796                         ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 2797                 }
 2798                 break;
 2799         case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
 2800                         int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
 2801                         u_int8_t *pQbuffer;
 2802                         u_int8_t *ptmpuserbuffer = pcmdmessagefld->messagedatabuffer;
 2803 
 2804                         user_len = pcmdmessagefld->cmdmessage.Length;
 2805                         ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 2806                         wqbuf_lastindex = acb->wqbuf_lastindex;
 2807                         wqbuf_firstindex = acb->wqbuf_firstindex;
 2808                         if (wqbuf_lastindex != wqbuf_firstindex) {
 2809                                 arcmsr_Write_data_2iop_wqbuffer(acb);
 2810                                 /* has error report sensedata */
 2811                                 if(pccb->csio.sense_len) {
 2812                                 ((u_int8_t *)&pccb->csio.sense_data)[0] = (0x1 << 7 | 0x70); 
 2813                                 /* Valid,ErrorCode */
 2814                                 ((u_int8_t *)&pccb->csio.sense_data)[2] = 0x05; 
 2815                                 /* FileMark,EndOfMedia,IncorrectLength,Reserved,SenseKey */
 2816                                 ((u_int8_t *)&pccb->csio.sense_data)[7] = 0x0A; 
 2817                                 /* AdditionalSenseLength */
 2818                                 ((u_int8_t *)&pccb->csio.sense_data)[12] = 0x20; 
 2819                                 /* AdditionalSenseCode */
 2820                                 }
 2821                                 retvalue = ARCMSR_MESSAGE_FAIL;
 2822                         } else {
 2823                                 my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1)
 2824                                                 &(ARCMSR_MAX_QBUFFER - 1);
 2825                                 if (my_empty_len >= user_len) {
 2826                                         while (user_len > 0) {
 2827                                                 pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex];
 2828                                                 *pQbuffer = *ptmpuserbuffer;
 2829                                                 acb->wqbuf_lastindex++;
 2830                                                 acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
 2831                                                 ptmpuserbuffer++;
 2832                                                 user_len--;
 2833                                         }
 2834                                         if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) {
 2835                                                 acb->acb_flags &=
 2836                                                     ~ACB_F_MESSAGE_WQBUFFER_CLEARED;
 2837                                                 arcmsr_Write_data_2iop_wqbuffer(acb);
 2838                                         }
 2839                                 } else {
 2840                                         /* has error report sensedata */
 2841                                         if(pccb->csio.sense_len) {
 2842                                         ((u_int8_t *)&pccb->csio.sense_data)[0] = (0x1 << 7 | 0x70);
 2843                                         /* Valid,ErrorCode */
 2844                                         ((u_int8_t *)&pccb->csio.sense_data)[2] = 0x05; 
 2845                                         /* FileMark,EndOfMedia,IncorrectLength,Reserved,SenseKey */
 2846                                         ((u_int8_t *)&pccb->csio.sense_data)[7] = 0x0A; 
 2847                                         /* AdditionalSenseLength */
 2848                                         ((u_int8_t *)&pccb->csio.sense_data)[12] = 0x20; 
 2849                                         /* AdditionalSenseCode */
 2850                                         }
 2851                                         retvalue = ARCMSR_MESSAGE_FAIL;
 2852                                 }
 2853                         }
 2854                         ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 2855                 }
 2856                 break;
 2857         case ARCMSR_MESSAGE_CLEAR_RQBUFFER: {
 2858                         u_int8_t *pQbuffer = acb->rqbuffer;
 2859 
 2860                         ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 2861                         if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 2862                                 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
 2863                                 arcmsr_iop_message_read(acb);
 2864                         }
 2865                         acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
 2866                         acb->rqbuf_firstindex = 0;
 2867                         acb->rqbuf_lastindex = 0;
 2868                         memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
 2869                         pcmdmessagefld->cmdmessage.ReturnCode =
 2870                             ARCMSR_MESSAGE_RETURNCODE_OK;
 2871                         ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 2872                 }
 2873                 break;
 2874         case ARCMSR_MESSAGE_CLEAR_WQBUFFER: {
 2875                         u_int8_t *pQbuffer = acb->wqbuffer;
 2876 
 2877                         ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 2878                         if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 2879                                 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
 2880                                 arcmsr_iop_message_read(acb);
 2881                         }
 2882                         acb->acb_flags |=
 2883                                 (ACB_F_MESSAGE_WQBUFFER_CLEARED |
 2884                                         ACB_F_MESSAGE_WQBUFFER_READ);
 2885                         acb->wqbuf_firstindex = 0;
 2886                         acb->wqbuf_lastindex = 0;
 2887                         memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
 2888                         pcmdmessagefld->cmdmessage.ReturnCode =
 2889                                 ARCMSR_MESSAGE_RETURNCODE_OK;
 2890                         ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 2891                 }
 2892                 break;
 2893         case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: {
 2894                         u_int8_t *pQbuffer;
 2895 
 2896                         ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
 2897                         if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 2898                                 acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
 2899                                 arcmsr_iop_message_read(acb);
 2900                         }
 2901                         acb->acb_flags |=
 2902                                 (ACB_F_MESSAGE_WQBUFFER_CLEARED
 2903                                 | ACB_F_MESSAGE_RQBUFFER_CLEARED
 2904                                 | ACB_F_MESSAGE_WQBUFFER_READ);
 2905                         acb->rqbuf_firstindex = 0;
 2906                         acb->rqbuf_lastindex = 0;
 2907                         acb->wqbuf_firstindex = 0;
 2908                         acb->wqbuf_lastindex = 0;
 2909                         pQbuffer = acb->rqbuffer;
 2910                         memset(pQbuffer, 0, sizeof (struct QBUFFER));
 2911                         pQbuffer = acb->wqbuffer;
 2912                         memset(pQbuffer, 0, sizeof (struct QBUFFER));
 2913                         pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
 2914                         ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
 2915                 }
 2916                 break;
 2917         case ARCMSR_MESSAGE_REQUEST_RETURNCODE_3F: {
 2918                         pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F;
 2919                 }
 2920                 break;
 2921         case ARCMSR_MESSAGE_SAY_HELLO: {
 2922                         int8_t *hello_string = "Hello! I am ARCMSR";
 2923 
 2924                         memcpy(pcmdmessagefld->messagedatabuffer, hello_string
 2925                                 , (int16_t)strlen(hello_string));
 2926                         pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
 2927                 }
 2928                 break;
 2929         case ARCMSR_MESSAGE_SAY_GOODBYE:
 2930                 arcmsr_iop_parking(acb);
 2931                 break;
 2932         case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE:
 2933                 arcmsr_flush_adapter_cache(acb);
 2934                 break;
 2935         default:
 2936                 retvalue = ARCMSR_MESSAGE_FAIL;
 2937         }
 2938 message_out:
 2939         return (retvalue);
 2940 }
 2941 /*
 2942 *********************************************************************
 2943 *********************************************************************
 2944 */
 2945 static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
 2946 {
 2947         struct CommandControlBlock *srb = (struct CommandControlBlock *)arg;
 2948         struct AdapterControlBlock *acb = (struct AdapterControlBlock *)srb->acb;
 2949         union ccb *pccb;
 2950         int target, lun; 
 2951 
 2952         pccb = srb->pccb;
 2953         target = pccb->ccb_h.target_id;
 2954         lun = pccb->ccb_h.target_lun;
 2955         acb->pktRequestCount++;
 2956         if(error != 0) {
 2957                 if(error != EFBIG) {
 2958                         printf("arcmsr%d: unexpected error %x"
 2959                                 " returned from 'bus_dmamap_load' \n"
 2960                                 , acb->pci_unit, error);
 2961                 }
 2962                 if((pccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
 2963                         pccb->ccb_h.status |= CAM_REQ_TOO_BIG;
 2964                 }
 2965                 arcmsr_srb_complete(srb, 0);
 2966                 return;
 2967         }
 2968         if(nseg > ARCMSR_MAX_SG_ENTRIES) {
 2969                 pccb->ccb_h.status |= CAM_REQ_TOO_BIG;
 2970                 arcmsr_srb_complete(srb, 0);
 2971                 return;
 2972         }
 2973         if(acb->acb_flags & ACB_F_BUS_RESET) {
 2974                 printf("arcmsr%d: bus reset and return busy \n", acb->pci_unit);
 2975                 pccb->ccb_h.status |= CAM_SCSI_BUS_RESET;
 2976                 arcmsr_srb_complete(srb, 0);
 2977                 return;
 2978         }
 2979         if(acb->devstate[target][lun] == ARECA_RAID_GONE) {
 2980                 u_int8_t block_cmd, cmd;
 2981 
 2982                 cmd = scsiio_cdb_ptr(&pccb->csio)[0];
 2983                 block_cmd = cmd & 0x0f;
 2984                 if(block_cmd == 0x08 || block_cmd == 0x0a) {
 2985                         printf("arcmsr%d:block 'read/write' command "
 2986                                 "with gone raid volume Cmd=0x%2x, TargetId=%d, Lun=%d \n"
 2987                                 , acb->pci_unit, cmd, target, lun);
 2988                         pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
 2989                         arcmsr_srb_complete(srb, 0);
 2990                         return;
 2991                 }
 2992         }
 2993         if((pccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
 2994                 if(nseg != 0) {
 2995                         bus_dmamap_unload(acb->dm_segs_dmat, srb->dm_segs_dmamap);
 2996                 }
 2997                 arcmsr_srb_complete(srb, 0);
 2998                 return;
 2999         }
 3000         if(acb->srboutstandingcount >= acb->maxOutstanding) {
 3001                 if((acb->acb_flags & ACB_F_CAM_DEV_QFRZN) == 0)
 3002                 {
 3003                         xpt_freeze_simq(acb->psim, 1);
 3004                         acb->acb_flags |= ACB_F_CAM_DEV_QFRZN;
 3005                 }
 3006                 pccb->ccb_h.status &= ~CAM_SIM_QUEUED;
 3007                 pccb->ccb_h.status |= CAM_REQUEUE_REQ;
 3008                 arcmsr_srb_complete(srb, 0);
 3009                 return;
 3010         }
 3011         pccb->ccb_h.status |= CAM_SIM_QUEUED;
 3012         arcmsr_build_srb(srb, dm_segs, nseg);
 3013         arcmsr_post_srb(acb, srb);
 3014         if (pccb->ccb_h.timeout != CAM_TIME_INFINITY)
 3015         {
 3016                 arcmsr_callout_init(&srb->ccb_callout);
 3017                 callout_reset_sbt(&srb->ccb_callout, SBT_1MS *
 3018                     (pccb->ccb_h.timeout + (ARCMSR_TIMEOUT_DELAY * 1000)), 0,
 3019                     arcmsr_srb_timeout, srb, 0);
 3020                 srb->srb_flags |= SRB_FLAG_TIMER_START;
 3021         }
 3022 }
 3023 /*
 3024 *****************************************************************************************
 3025 *****************************************************************************************
 3026 */
 3027 static u_int8_t arcmsr_seek_cmd2abort(union ccb *abortccb)
 3028 {
 3029         struct CommandControlBlock *srb;
 3030         struct AdapterControlBlock *acb = (struct AdapterControlBlock *) abortccb->ccb_h.arcmsr_ccbacb_ptr;
 3031         u_int32_t intmask_org;
 3032         int i = 0;
 3033 
 3034         acb->num_aborts++;
 3035         /*
 3036         ***************************************************************************
 3037         ** It is the upper layer do abort command this lock just prior to calling us.
 3038         ** First determine if we currently own this command.
 3039         ** Start by searching the device queue. If not found
 3040         ** at all, and the system wanted us to just abort the
 3041         ** command return success.
 3042         ***************************************************************************
 3043         */
 3044         if(acb->srboutstandingcount != 0) {
 3045                 /* disable all outbound interrupt */
 3046                 intmask_org = arcmsr_disable_allintr(acb);
 3047                 for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) {
 3048                         srb = acb->psrb_pool[i];
 3049                         if(srb->srb_state == ARCMSR_SRB_START) {
 3050                                 if(srb->pccb == abortccb) {
 3051                                         srb->srb_state = ARCMSR_SRB_ABORTED;
 3052                                         printf("arcmsr%d:scsi id=%d lun=%jx abort srb '%p'"
 3053                                                 "outstanding command \n"
 3054                                                 , acb->pci_unit, abortccb->ccb_h.target_id
 3055                                                 , (uintmax_t)abortccb->ccb_h.target_lun, srb);
 3056                                         arcmsr_polling_srbdone(acb, srb);
 3057                                         /* enable outbound Post Queue, outbound doorbell Interrupt */
 3058                                         arcmsr_enable_allintr(acb, intmask_org);
 3059                                         return (TRUE);
 3060                                 }
 3061                         }
 3062                 }
 3063                 /* enable outbound Post Queue, outbound doorbell Interrupt */
 3064                 arcmsr_enable_allintr(acb, intmask_org);
 3065         }
 3066         return(FALSE);
 3067 }
 3068 /*
 3069 ****************************************************************************
 3070 ****************************************************************************
 3071 */
 3072 static void arcmsr_bus_reset(struct AdapterControlBlock *acb)
 3073 {
 3074         int retry = 0;
 3075 
 3076         acb->num_resets++;
 3077         acb->acb_flags |= ACB_F_BUS_RESET;
 3078         while(acb->srboutstandingcount != 0 && retry < 400) {
 3079                 arcmsr_interrupt(acb);
 3080                 UDELAY(25000);
 3081                 retry++;
 3082         }
 3083         arcmsr_iop_reset(acb);
 3084         acb->acb_flags &= ~ACB_F_BUS_RESET;
 3085 } 
 3086 /*
 3087 **************************************************************************
 3088 **************************************************************************
 3089 */
 3090 static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
 3091                 union ccb *pccb)
 3092 {
 3093         if (pccb->ccb_h.target_lun) {
 3094                 pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
 3095                 xpt_done(pccb);
 3096                 return;
 3097         }
 3098         pccb->ccb_h.status |= CAM_REQ_CMP;
 3099         switch (scsiio_cdb_ptr(&pccb->csio)[0]) {
 3100         case INQUIRY: {
 3101                 unsigned char inqdata[36];
 3102                 char *buffer = pccb->csio.data_ptr;
 3103 
 3104                 inqdata[0] = T_PROCESSOR;       /* Periph Qualifier & Periph Dev Type */
 3105                 inqdata[1] = 0;                 /* rem media bit & Dev Type Modifier */
 3106                 inqdata[2] = 0;                 /* ISO, ECMA, & ANSI versions */
 3107                 inqdata[3] = 0;
 3108                 inqdata[4] = 31;                /* length of additional data */
 3109                 inqdata[5] = 0;
 3110                 inqdata[6] = 0;
 3111                 inqdata[7] = 0;
 3112                 strncpy(&inqdata[8], "Areca   ", 8);    /* Vendor Identification */
 3113                 strncpy(&inqdata[16], "RAID controller ", 16);  /* Product Identification */
 3114                 strncpy(&inqdata[32], "R001", 4); /* Product Revision */
 3115                 memcpy(buffer, inqdata, sizeof(inqdata));
 3116                 xpt_done(pccb);
 3117         }
 3118         break;
 3119         case WRITE_BUFFER:
 3120         case READ_BUFFER: {
 3121                 if (arcmsr_iop_message_xfer(acb, pccb)) {
 3122                         pccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
 3123                         pccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
 3124                 }
 3125                 xpt_done(pccb);
 3126         }
 3127         break;
 3128         default:
 3129                 xpt_done(pccb);
 3130         }
 3131 }
 3132 /*
 3133 *********************************************************************
 3134 *********************************************************************
 3135 */
 3136 static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
 3137 {
 3138         struct AdapterControlBlock *acb;
 3139 
 3140         acb = (struct AdapterControlBlock *) cam_sim_softc(psim);
 3141         if(acb == NULL) {
 3142                 pccb->ccb_h.status |= CAM_REQ_INVALID;
 3143                 xpt_done(pccb);
 3144                 return;
 3145         }
 3146         switch (pccb->ccb_h.func_code) {
 3147         case XPT_SCSI_IO: {
 3148                         struct CommandControlBlock *srb;
 3149                         int target = pccb->ccb_h.target_id;
 3150                         int error;
 3151 
 3152                         if (pccb->ccb_h.flags & CAM_CDB_PHYS) {
 3153                                 pccb->ccb_h.status = CAM_REQ_INVALID;
 3154                                 xpt_done(pccb);
 3155                                 return;
 3156                         }
 3157 
 3158                         if(target == 16) {
 3159                                 /* virtual device for iop message transfer */
 3160                                 arcmsr_handle_virtual_command(acb, pccb);
 3161                                 return;
 3162                         }
 3163                         if((srb = arcmsr_get_freesrb(acb)) == NULL) {
 3164                                 pccb->ccb_h.status |= CAM_RESRC_UNAVAIL;
 3165                                 xpt_done(pccb);
 3166                                 return;
 3167                         }
 3168                         pccb->ccb_h.arcmsr_ccbsrb_ptr = srb;
 3169                         pccb->ccb_h.arcmsr_ccbacb_ptr = acb;
 3170                         srb->pccb = pccb;
 3171                         error = bus_dmamap_load_ccb(acb->dm_segs_dmat
 3172                                 , srb->dm_segs_dmamap
 3173                                 , pccb
 3174                                 , arcmsr_execute_srb, srb, /*flags*/0);
 3175                         if(error == EINPROGRESS) {
 3176                                 xpt_freeze_simq(acb->psim, 1);
 3177                                 pccb->ccb_h.status |= CAM_RELEASE_SIMQ;
 3178                         }
 3179                         break;
 3180                 }
 3181         case XPT_PATH_INQ: {
 3182                         struct ccb_pathinq *cpi = &pccb->cpi;
 3183 
 3184                         cpi->version_num = 1;
 3185                         cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE;
 3186                         cpi->target_sprt = 0;
 3187                         cpi->hba_misc = 0;
 3188                         cpi->hba_eng_cnt = 0;
 3189                         cpi->max_target = ARCMSR_MAX_TARGETID;        /* 0-16 */
 3190                         cpi->max_lun = ARCMSR_MAX_TARGETLUN;        /* 0-7 */
 3191                         cpi->initiator_id = ARCMSR_SCSI_INITIATOR_ID; /* 255 */
 3192                         cpi->bus_id = cam_sim_bus(psim);
 3193                         strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
 3194                         strlcpy(cpi->hba_vid, "ARCMSR", HBA_IDLEN);
 3195                         strlcpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN);
 3196                         cpi->unit_number = cam_sim_unit(psim);
 3197                         if(acb->adapter_bus_speed == ACB_BUS_SPEED_12G)
 3198                                 cpi->base_transfer_speed = 1200000;
 3199                         else if(acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
 3200                                 cpi->base_transfer_speed = 600000;
 3201                         else
 3202                                 cpi->base_transfer_speed = 300000;
 3203                         if((acb->vendor_device_id == PCIDevVenIDARC1880) ||
 3204                            (acb->vendor_device_id == PCIDevVenIDARC1884) ||
 3205                            (acb->vendor_device_id == PCIDevVenIDARC1680) ||
 3206                            (acb->vendor_device_id == PCIDevVenIDARC1214))
 3207                         {
 3208                                 cpi->transport = XPORT_SAS;
 3209                                 cpi->transport_version = 0;
 3210                                 cpi->protocol_version = SCSI_REV_SPC2;
 3211                         }
 3212                         else
 3213                         {
 3214                                 cpi->transport = XPORT_SPI;
 3215                                 cpi->transport_version = 2;
 3216                                 cpi->protocol_version = SCSI_REV_2;
 3217                         }
 3218                         cpi->protocol = PROTO_SCSI;
 3219                         cpi->ccb_h.status |= CAM_REQ_CMP;
 3220                         xpt_done(pccb);
 3221                         break;
 3222                 }
 3223         case XPT_ABORT: {
 3224                         union ccb *pabort_ccb;
 3225 
 3226                         pabort_ccb = pccb->cab.abort_ccb;
 3227                         switch (pabort_ccb->ccb_h.func_code) {
 3228                         case XPT_ACCEPT_TARGET_IO:
 3229                         case XPT_CONT_TARGET_IO:
 3230                                 if(arcmsr_seek_cmd2abort(pabort_ccb)==TRUE) {
 3231                                         pabort_ccb->ccb_h.status |= CAM_REQ_ABORTED;
 3232                                         xpt_done(pabort_ccb);
 3233                                         pccb->ccb_h.status |= CAM_REQ_CMP;
 3234                                 } else {
 3235                                         xpt_print_path(pabort_ccb->ccb_h.path);
 3236                                         printf("Not found\n");
 3237                                         pccb->ccb_h.status |= CAM_PATH_INVALID;
 3238                                 }
 3239                                 break;
 3240                         case XPT_SCSI_IO:
 3241                                 pccb->ccb_h.status |= CAM_UA_ABORT;
 3242                                 break;
 3243                         default:
 3244                                 pccb->ccb_h.status |= CAM_REQ_INVALID;
 3245                                 break;
 3246                         }
 3247                         xpt_done(pccb);
 3248                         break;
 3249                 }
 3250         case XPT_RESET_BUS:
 3251         case XPT_RESET_DEV: {
 3252                         u_int32_t       i;
 3253 
 3254                         arcmsr_bus_reset(acb);
 3255                         for (i=0; i < 500; i++) {
 3256                                 DELAY(1000);    
 3257                         }
 3258                         pccb->ccb_h.status |= CAM_REQ_CMP;
 3259                         xpt_done(pccb);
 3260                         break;
 3261                 }
 3262         case XPT_TERM_IO: {
 3263                         pccb->ccb_h.status |= CAM_REQ_INVALID;
 3264                         xpt_done(pccb);
 3265                         break;
 3266                 }
 3267         case XPT_GET_TRAN_SETTINGS: {
 3268                         struct ccb_trans_settings *cts;
 3269 
 3270                         if(pccb->ccb_h.target_id == 16) {
 3271                                 pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL;
 3272                                 xpt_done(pccb);
 3273                                 break;
 3274                         }
 3275                         cts = &pccb->cts;
 3276                         {
 3277                                 struct ccb_trans_settings_scsi *scsi;
 3278                                 struct ccb_trans_settings_spi *spi;
 3279                                 struct ccb_trans_settings_sas *sas;     
 3280 
 3281                                 scsi = &cts->proto_specific.scsi;
 3282                                 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
 3283                                 scsi->valid = CTS_SCSI_VALID_TQ;
 3284                                 cts->protocol = PROTO_SCSI;
 3285 
 3286                                 if((acb->vendor_device_id == PCIDevVenIDARC1880) ||
 3287                                    (acb->vendor_device_id == PCIDevVenIDARC1884) ||
 3288                                    (acb->vendor_device_id == PCIDevVenIDARC1680) ||
 3289                                    (acb->vendor_device_id == PCIDevVenIDARC1214))
 3290                                 {
 3291                                         cts->protocol_version = SCSI_REV_SPC2;
 3292                                         cts->transport_version = 0;
 3293                                         cts->transport = XPORT_SAS;
 3294                                         sas = &cts->xport_specific.sas;
 3295                                         sas->valid = CTS_SAS_VALID_SPEED;
 3296                                         if (acb->adapter_bus_speed == ACB_BUS_SPEED_12G)
 3297                                                 sas->bitrate = 1200000;
 3298                                         else if(acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
 3299                                                 sas->bitrate = 600000;
 3300                                         else if(acb->adapter_bus_speed == ACB_BUS_SPEED_3G)
 3301                                                 sas->bitrate = 300000;
 3302                                 }
 3303                                 else
 3304                                 {
 3305                                         cts->protocol_version = SCSI_REV_2;
 3306                                         cts->transport_version = 2;
 3307                                         cts->transport = XPORT_SPI;
 3308                                         spi = &cts->xport_specific.spi;
 3309                                         spi->flags = CTS_SPI_FLAGS_DISC_ENB;
 3310                                         if (acb->adapter_bus_speed == ACB_BUS_SPEED_6G)
 3311                                                 spi->sync_period = 1;
 3312                                         else
 3313                                                 spi->sync_period = 2;
 3314                                         spi->sync_offset = 32;
 3315                                         spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
 3316                                         spi->valid = CTS_SPI_VALID_DISC
 3317                                                 | CTS_SPI_VALID_SYNC_RATE
 3318                                                 | CTS_SPI_VALID_SYNC_OFFSET
 3319                                                 | CTS_SPI_VALID_BUS_WIDTH;
 3320                                 }
 3321                         }
 3322                         pccb->ccb_h.status |= CAM_REQ_CMP;
 3323                         xpt_done(pccb);
 3324                         break;
 3325                 }
 3326         case XPT_SET_TRAN_SETTINGS: {
 3327                         pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL;
 3328                         xpt_done(pccb);
 3329                         break;
 3330                 }
 3331         case XPT_CALC_GEOMETRY:
 3332                         if(pccb->ccb_h.target_id == 16) {
 3333                                 pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL;
 3334                                 xpt_done(pccb);
 3335                                 break;
 3336                         }
 3337                         cam_calc_geometry(&pccb->ccg, 1);
 3338                         xpt_done(pccb);
 3339                         break;
 3340         default:
 3341                 pccb->ccb_h.status |= CAM_REQ_INVALID;
 3342                 xpt_done(pccb);
 3343                 break;
 3344         }
 3345 }
 3346 /*
 3347 **********************************************************************
 3348 **********************************************************************
 3349 */
 3350 static void arcmsr_start_hba_bgrb(struct AdapterControlBlock *acb)
 3351 {
 3352         acb->acb_flags |= ACB_F_MSG_START_BGRB;
 3353         CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB);
 3354         if(!arcmsr_hba_wait_msgint_ready(acb)) {
 3355                 printf("arcmsr%d: wait 'start adapter background rebulid' timeout \n", acb->pci_unit);
 3356         }
 3357 }
 3358 /*
 3359 **********************************************************************
 3360 **********************************************************************
 3361 */
 3362 static void arcmsr_start_hbb_bgrb(struct AdapterControlBlock *acb)
 3363 {
 3364         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 3365         acb->acb_flags |= ACB_F_MSG_START_BGRB;
 3366         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_START_BGRB);
 3367         if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 3368                 printf( "arcmsr%d: wait 'start adapter background rebulid' timeout \n", acb->pci_unit);
 3369         }
 3370 }
 3371 /*
 3372 **********************************************************************
 3373 **********************************************************************
 3374 */
 3375 static void arcmsr_start_hbc_bgrb(struct AdapterControlBlock *acb)
 3376 {
 3377         acb->acb_flags |= ACB_F_MSG_START_BGRB;
 3378         CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB);
 3379         CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
 3380         if(!arcmsr_hbc_wait_msgint_ready(acb)) {
 3381                 printf("arcmsr%d: wait 'start adapter background rebulid' timeout \n", acb->pci_unit);
 3382         }
 3383 }
 3384 /*
 3385 **********************************************************************
 3386 **********************************************************************
 3387 */
 3388 static void arcmsr_start_hbd_bgrb(struct AdapterControlBlock *acb)
 3389 {
 3390         acb->acb_flags |= ACB_F_MSG_START_BGRB;
 3391         CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB);
 3392         if(!arcmsr_hbd_wait_msgint_ready(acb)) {
 3393                 printf("arcmsr%d: wait 'start adapter background rebulid' timeout \n", acb->pci_unit);
 3394         }
 3395 }
 3396 /*
 3397 **********************************************************************
 3398 **********************************************************************
 3399 */
 3400 static void arcmsr_start_hbe_bgrb(struct AdapterControlBlock *acb)
 3401 {
 3402         acb->acb_flags |= ACB_F_MSG_START_BGRB;
 3403         CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB);
 3404         acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
 3405         CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
 3406         if(!arcmsr_hbe_wait_msgint_ready(acb)) {
 3407                 printf("arcmsr%d: wait 'start adapter background rebulid' timeout \n", acb->pci_unit);
 3408         }
 3409 }
 3410 /*
 3411 **********************************************************************
 3412 **********************************************************************
 3413 */
 3414 static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb)
 3415 {
 3416         switch (acb->adapter_type) {
 3417         case ACB_ADAPTER_TYPE_A:
 3418                 arcmsr_start_hba_bgrb(acb);
 3419                 break;
 3420         case ACB_ADAPTER_TYPE_B:
 3421                 arcmsr_start_hbb_bgrb(acb);
 3422                 break;
 3423         case ACB_ADAPTER_TYPE_C:
 3424                 arcmsr_start_hbc_bgrb(acb);
 3425                 break;
 3426         case ACB_ADAPTER_TYPE_D:
 3427                 arcmsr_start_hbd_bgrb(acb);
 3428                 break;
 3429         case ACB_ADAPTER_TYPE_E:
 3430         case ACB_ADAPTER_TYPE_F:
 3431                 arcmsr_start_hbe_bgrb(acb);
 3432                 break;
 3433         }
 3434 }
 3435 /*
 3436 **********************************************************************
 3437 ** 
 3438 **********************************************************************
 3439 */
 3440 static void arcmsr_polling_hba_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
 3441 {
 3442         struct CommandControlBlock *srb;
 3443         u_int32_t flag_srb, outbound_intstatus, poll_srb_done=0, poll_count=0;
 3444         u_int16_t       error;
 3445 
 3446 polling_ccb_retry:
 3447         poll_count++;
 3448         outbound_intstatus=CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_intstatus) & acb->outbound_int_enable;
 3449         CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_intstatus, outbound_intstatus);   /*clear interrupt*/
 3450         bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 3451         while(1) {
 3452                 if((flag_srb = CHIP_REG_READ32(HBA_MessageUnit, 
 3453                         0, outbound_queueport)) == 0xFFFFFFFF) {
 3454                         if(poll_srb_done) {
 3455                                 break;/*chip FIFO no ccb for completion already*/
 3456                         } else {
 3457                                 UDELAY(25000);
 3458                                 if ((poll_count > 100) && (poll_srb != NULL)) {
 3459                                         break;
 3460                                 }
 3461                                 goto polling_ccb_retry;
 3462                         }
 3463                 }
 3464                 /* check if command done with no error*/
 3465                 srb = (struct CommandControlBlock *)
 3466                         (acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
 3467                 error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
 3468                 poll_srb_done = (srb == poll_srb) ? 1:0;
 3469                 if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
 3470                         if(srb->srb_state == ARCMSR_SRB_ABORTED) {
 3471                                 printf("arcmsr%d: scsi id=%d lun=%jx srb='%p'"
 3472                                         "poll command abort successfully \n"
 3473                                         , acb->pci_unit
 3474                                         , srb->pccb->ccb_h.target_id
 3475                                         , (uintmax_t)srb->pccb->ccb_h.target_lun, srb);
 3476                                 srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
 3477                                 arcmsr_srb_complete(srb, 1);
 3478                                 continue;
 3479                         }
 3480                         printf("arcmsr%d: polling get an illegal srb command done srb='%p'"
 3481                                 "srboutstandingcount=%d \n"
 3482                                 , acb->pci_unit
 3483                                 , srb, acb->srboutstandingcount);
 3484                         continue;
 3485                 }
 3486                 arcmsr_report_srb_state(acb, srb, error);
 3487         }       /*drain reply FIFO*/
 3488 }
 3489 /*
 3490 **********************************************************************
 3491 **
 3492 **********************************************************************
 3493 */
 3494 static void arcmsr_polling_hbb_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
 3495 {
 3496         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 3497         struct CommandControlBlock *srb;
 3498         u_int32_t flag_srb, poll_srb_done=0, poll_count=0;
 3499         int index;
 3500         u_int16_t       error;
 3501 
 3502 polling_ccb_retry:
 3503         poll_count++;
 3504         WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN); /* clear doorbell interrupt */
 3505         bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 3506         while(1) {
 3507                 index = phbbmu->doneq_index;
 3508                 if((flag_srb = phbbmu->done_qbuffer[index]) == 0) {
 3509                         if(poll_srb_done) {
 3510                                 break;/*chip FIFO no ccb for completion already*/
 3511                         } else {
 3512                                 UDELAY(25000);
 3513                                 if ((poll_count > 100) && (poll_srb != NULL)) {
 3514                                         break;
 3515                                 }
 3516                                 goto polling_ccb_retry;
 3517                         }
 3518                 }
 3519                 phbbmu->done_qbuffer[index] = 0;
 3520                 index++;
 3521                 index %= ARCMSR_MAX_HBB_POSTQUEUE;     /*if last index number set it to 0 */
 3522                 phbbmu->doneq_index = index;
 3523                 /* check if command done with no error*/
 3524                 srb = (struct CommandControlBlock *)
 3525                         (acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
 3526                 error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
 3527                 poll_srb_done = (srb == poll_srb) ? 1:0;
 3528                 if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
 3529                         if(srb->srb_state == ARCMSR_SRB_ABORTED) {
 3530                                 printf("arcmsr%d: scsi id=%d lun=%jx srb='%p'"
 3531                                         "poll command abort successfully \n"
 3532                                         , acb->pci_unit
 3533                                         , srb->pccb->ccb_h.target_id
 3534                                         , (uintmax_t)srb->pccb->ccb_h.target_lun, srb);
 3535                                 srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
 3536                                 arcmsr_srb_complete(srb, 1);            
 3537                                 continue;
 3538                         }
 3539                         printf("arcmsr%d: polling get an illegal srb command done srb='%p'"
 3540                                 "srboutstandingcount=%d \n"
 3541                                 , acb->pci_unit
 3542                                 , srb, acb->srboutstandingcount);
 3543                         continue;
 3544                 }
 3545                 arcmsr_report_srb_state(acb, srb, error);
 3546         }       /*drain reply FIFO*/
 3547 }
 3548 /*
 3549 **********************************************************************
 3550 ** 
 3551 **********************************************************************
 3552 */
 3553 static void arcmsr_polling_hbc_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
 3554 {
 3555         struct CommandControlBlock *srb;
 3556         u_int32_t flag_srb, poll_srb_done=0, poll_count=0;
 3557         u_int16_t       error;
 3558 
 3559 polling_ccb_retry:
 3560         poll_count++;
 3561         bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 3562         while(1) {
 3563                 if(!(CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR)) {
 3564                         if(poll_srb_done) {
 3565                                 break;/*chip FIFO no ccb for completion already*/
 3566                         } else {
 3567                                 UDELAY(25000);
 3568                                 if ((poll_count > 100) && (poll_srb != NULL)) {
 3569                                         break;
 3570                                 }
 3571                                 if (acb->srboutstandingcount == 0) {
 3572                                         break;
 3573                                 }
 3574                                 goto polling_ccb_retry;
 3575                         }
 3576                 }
 3577                 flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
 3578                 /* check if command done with no error*/
 3579                 srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/
 3580                 error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE;
 3581                 if (poll_srb != NULL)
 3582                         poll_srb_done = (srb == poll_srb) ? 1:0;
 3583                 if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
 3584                         if(srb->srb_state == ARCMSR_SRB_ABORTED) {
 3585                                 printf("arcmsr%d: scsi id=%d lun=%jx srb='%p'poll command abort successfully \n"
 3586                                                 , acb->pci_unit, srb->pccb->ccb_h.target_id, (uintmax_t)srb->pccb->ccb_h.target_lun, srb);
 3587                                 srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
 3588                                 arcmsr_srb_complete(srb, 1);
 3589                                 continue;
 3590                         }
 3591                         printf("arcmsr%d: polling get an illegal srb command done srb='%p'srboutstandingcount=%d \n"
 3592                                         , acb->pci_unit, srb, acb->srboutstandingcount);
 3593                         continue;
 3594                 }
 3595                 arcmsr_report_srb_state(acb, srb, error);
 3596         }       /*drain reply FIFO*/
 3597 }
 3598 /*
 3599 **********************************************************************
 3600 ** 
 3601 **********************************************************************
 3602 */
 3603 static void arcmsr_polling_hbd_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
 3604 {
 3605         struct HBD_MessageUnit0 *phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
 3606         struct CommandControlBlock *srb;
 3607         u_int32_t flag_srb, poll_srb_done=0, poll_count=0;
 3608         u_int32_t outbound_write_pointer;
 3609         u_int16_t       error, doneq_index;
 3610 
 3611 polling_ccb_retry:
 3612         poll_count++;
 3613         bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 3614         while(1) {
 3615                 outbound_write_pointer = phbdmu->done_qbuffer[0].addressLow;
 3616                 doneq_index = phbdmu->doneq_index;
 3617                 if ((outbound_write_pointer & 0xFF) == (doneq_index & 0xFF)) {
 3618                         if(poll_srb_done) {
 3619                                 break;/*chip FIFO no ccb for completion already*/
 3620                         } else {
 3621                                 UDELAY(25000);
 3622                                 if ((poll_count > 100) && (poll_srb != NULL)) {
 3623                                         break;
 3624                                 }
 3625                                 if (acb->srboutstandingcount == 0) {
 3626                                         break;
 3627                                 }
 3628                                 goto polling_ccb_retry;
 3629                         }
 3630                 }
 3631                 doneq_index = arcmsr_get_doneq_index(phbdmu);
 3632                 flag_srb = phbdmu->done_qbuffer[(doneq_index & 0xFF)+1].addressLow;
 3633                 /* check if command done with no error*/
 3634                 srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/
 3635                 error = (flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
 3636                 CHIP_REG_WRITE32(HBD_MessageUnit, 0, outboundlist_read_pointer, doneq_index);
 3637                 if (poll_srb != NULL)
 3638                         poll_srb_done = (srb == poll_srb) ? 1:0;
 3639                 if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
 3640                         if(srb->srb_state == ARCMSR_SRB_ABORTED) {
 3641                                 printf("arcmsr%d: scsi id=%d lun=%jx srb='%p'poll command abort successfully \n"
 3642                                                 , acb->pci_unit, srb->pccb->ccb_h.target_id, (uintmax_t)srb->pccb->ccb_h.target_lun, srb);
 3643                                 srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
 3644                                 arcmsr_srb_complete(srb, 1);
 3645                                 continue;
 3646                         }
 3647                         printf("arcmsr%d: polling get an illegal srb command done srb='%p'srboutstandingcount=%d \n"
 3648                                         , acb->pci_unit, srb, acb->srboutstandingcount);
 3649                         continue;
 3650                 }
 3651                 arcmsr_report_srb_state(acb, srb, error);
 3652         }       /*drain reply FIFO*/
 3653 }
 3654 /*
 3655 **********************************************************************
 3656 ** 
 3657 **********************************************************************
 3658 */
 3659 static void arcmsr_polling_hbe_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
 3660 {
 3661         struct CommandControlBlock *srb;
 3662         u_int32_t poll_srb_done=0, poll_count=0, doneq_index;
 3663         u_int16_t       error, cmdSMID;
 3664 
 3665 polling_ccb_retry:
 3666         poll_count++;
 3667         bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 3668         while(1) {
 3669                 doneq_index = acb->doneq_index;
 3670                 if((CHIP_REG_READ32(HBE_MessageUnit, 0, reply_post_producer_index) & 0xFFFF) == doneq_index) {
 3671                         if(poll_srb_done) {
 3672                                 break;/*chip FIFO no ccb for completion already*/
 3673                         } else {
 3674                                 UDELAY(25000);
 3675                                 if ((poll_count > 100) && (poll_srb != NULL)) {
 3676                                         break;
 3677                                 }
 3678                                 if (acb->srboutstandingcount == 0) {
 3679                                         break;
 3680                                 }
 3681                                 goto polling_ccb_retry;
 3682                         }
 3683                 }
 3684                 cmdSMID = acb->pCompletionQ[doneq_index].cmdSMID;
 3685                 doneq_index++;
 3686                 if (doneq_index >= acb->completionQ_entry)
 3687                         doneq_index = 0;
 3688                 acb->doneq_index = doneq_index;
 3689                 srb = acb->psrb_pool[cmdSMID];
 3690                 error = (acb->pCompletionQ[doneq_index].cmdFlag & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
 3691                 if (poll_srb != NULL)
 3692                         poll_srb_done = (srb == poll_srb) ? 1:0;
 3693                 if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
 3694                         if(srb->srb_state == ARCMSR_SRB_ABORTED) {
 3695                                 printf("arcmsr%d: scsi id=%d lun=%jx srb='%p'poll command abort successfully \n"
 3696                                                 , acb->pci_unit, srb->pccb->ccb_h.target_id, (uintmax_t)srb->pccb->ccb_h.target_lun, srb);
 3697                                 srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
 3698                                 arcmsr_srb_complete(srb, 1);
 3699                                 continue;
 3700                         }
 3701                         printf("arcmsr%d: polling get an illegal srb command done srb='%p'srboutstandingcount=%d \n"
 3702                                         , acb->pci_unit, srb, acb->srboutstandingcount);
 3703                         continue;
 3704                 }
 3705                 arcmsr_report_srb_state(acb, srb, error);
 3706         }       /*drain reply FIFO*/
 3707         CHIP_REG_WRITE32(HBE_MessageUnit, 0, reply_post_producer_index, doneq_index);
 3708 }
 3709 /*
 3710 **********************************************************************
 3711 **********************************************************************
 3712 */
 3713 static void arcmsr_polling_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
 3714 {
 3715         switch (acb->adapter_type) {
 3716         case ACB_ADAPTER_TYPE_A:
 3717                 arcmsr_polling_hba_srbdone(acb, poll_srb);
 3718                 break;
 3719         case ACB_ADAPTER_TYPE_B:
 3720                 arcmsr_polling_hbb_srbdone(acb, poll_srb);
 3721                 break;
 3722         case ACB_ADAPTER_TYPE_C:
 3723                 arcmsr_polling_hbc_srbdone(acb, poll_srb);
 3724                 break;
 3725         case ACB_ADAPTER_TYPE_D:
 3726                 arcmsr_polling_hbd_srbdone(acb, poll_srb);
 3727                 break;
 3728         case ACB_ADAPTER_TYPE_E:
 3729         case ACB_ADAPTER_TYPE_F:
 3730                 arcmsr_polling_hbe_srbdone(acb, poll_srb);
 3731                 break;
 3732         }
 3733 }
 3734 /*
 3735 **********************************************************************
 3736 **********************************************************************
 3737 */
 3738 static void arcmsr_get_hba_config(struct AdapterControlBlock *acb)
 3739 {
 3740         char *acb_firm_model = acb->firm_model;
 3741         char *acb_firm_version = acb->firm_version;
 3742         char *acb_device_map = acb->device_map;
 3743         size_t iop_firm_model = offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);      /*firm_model,15,60-67*/
 3744         size_t iop_firm_version = offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]);     /*firm_version,17,68-83*/
 3745         size_t iop_device_map = offsetof(struct HBA_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
 3746         int i;
 3747 
 3748         CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
 3749         if(!arcmsr_hba_wait_msgint_ready(acb)) {
 3750                 printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
 3751         }
 3752         i = 0;
 3753         while(i < 8) {
 3754                 *acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); 
 3755                 /* 8 bytes firm_model, 15, 60-67*/
 3756                 acb_firm_model++;
 3757                 i++;
 3758         }
 3759         i=0;
 3760         while(i < 16) {
 3761                 *acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i);  
 3762                 /* 16 bytes firm_version, 17, 68-83*/
 3763                 acb_firm_version++;
 3764                 i++;
 3765         }
 3766         i=0;
 3767         while(i < 16) {
 3768                 *acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i);  
 3769                 acb_device_map++;
 3770                 i++;
 3771         }
 3772         printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
 3773         acb->firm_request_len = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[1]);   /*firm_request_len, 1, 04-07*/
 3774         acb->firm_numbers_queue = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/
 3775         acb->firm_sdram_size = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[3]);    /*firm_sdram_size, 3, 12-15*/
 3776         acb->firm_ide_channels = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[4]);  /*firm_ide_channels, 4, 16-19*/
 3777         acb->firm_cfg_version = CHIP_REG_READ32(HBA_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]); /*firm_cfg_version,  25,          */
 3778         if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
 3779                 acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD - 1;
 3780         else
 3781                 acb->maxOutstanding = acb->firm_numbers_queue - 1;
 3782 }
 3783 /*
 3784 **********************************************************************
 3785 **********************************************************************
 3786 */
 3787 static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb)
 3788 {
 3789         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 3790         char *acb_firm_model = acb->firm_model;
 3791         char *acb_firm_version = acb->firm_version;
 3792         char *acb_device_map = acb->device_map;
 3793         size_t iop_firm_model = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);        /*firm_model,15,60-67*/
 3794         size_t iop_firm_version = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]);       /*firm_version,17,68-83*/
 3795         size_t iop_device_map = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
 3796         int i;
 3797 
 3798         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_GET_CONFIG);
 3799         if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 3800                 printf( "arcmsr%d: wait" "'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
 3801         }
 3802         i = 0;
 3803         while(i < 8) {
 3804                 *acb_firm_model = bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_firm_model+i);
 3805                 /* 8 bytes firm_model, 15, 60-67*/
 3806                 acb_firm_model++;
 3807                 i++;
 3808         }
 3809         i = 0;
 3810         while(i < 16) {
 3811                 *acb_firm_version = bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_firm_version+i);
 3812                 /* 16 bytes firm_version, 17, 68-83*/
 3813                 acb_firm_version++;
 3814                 i++;
 3815         }
 3816         i = 0;
 3817         while(i < 16) {
 3818                 *acb_device_map = bus_space_read_1(acb->btag[1], acb->bhandle[1], iop_device_map+i);  
 3819                 acb_device_map++;
 3820                 i++;
 3821         }
 3822         printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
 3823         acb->firm_request_len = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[1]);   /*firm_request_len, 1, 04-07*/
 3824         acb->firm_numbers_queue = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/
 3825         acb->firm_sdram_size = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[3]);    /*firm_sdram_size, 3, 12-15*/
 3826         acb->firm_ide_channels = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[4]);  /*firm_ide_channels, 4, 16-19*/
 3827         acb->firm_cfg_version = CHIP_REG_READ32(HBB_RWBUFFER, 1, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);    /*firm_cfg_version,  25,          */
 3828         if(acb->firm_numbers_queue > ARCMSR_MAX_HBB_POSTQUEUE)
 3829                 acb->maxOutstanding = ARCMSR_MAX_HBB_POSTQUEUE - 1;
 3830         else
 3831                 acb->maxOutstanding = acb->firm_numbers_queue - 1;
 3832 }
 3833 /*
 3834 **********************************************************************
 3835 **********************************************************************
 3836 */
 3837 static void arcmsr_get_hbc_config(struct AdapterControlBlock *acb)
 3838 {
 3839         char *acb_firm_model = acb->firm_model;
 3840         char *acb_firm_version = acb->firm_version;
 3841         char *acb_device_map = acb->device_map;
 3842         size_t iop_firm_model = offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);   /*firm_model,15,60-67*/
 3843         size_t iop_firm_version = offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/
 3844         size_t iop_device_map = offsetof(struct HBC_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
 3845         int i;
 3846 
 3847         CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
 3848         CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
 3849         if(!arcmsr_hbc_wait_msgint_ready(acb)) {
 3850                 printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
 3851         }
 3852         i = 0;
 3853         while(i < 8) {
 3854                 *acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); 
 3855                 /* 8 bytes firm_model, 15, 60-67*/
 3856                 acb_firm_model++;
 3857                 i++;
 3858         }
 3859         i = 0;
 3860         while(i < 16) {
 3861                 *acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i);  
 3862                 /* 16 bytes firm_version, 17, 68-83*/
 3863                 acb_firm_version++;
 3864                 i++;
 3865         }
 3866         i = 0;
 3867         while(i < 16) {
 3868                 *acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i);  
 3869                 acb_device_map++;
 3870                 i++;
 3871         }
 3872         printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
 3873         acb->firm_request_len   = CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[1]);     /*firm_request_len,   1, 04-07*/
 3874         acb->firm_numbers_queue = CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[2]);     /*firm_numbers_queue, 2, 08-11*/
 3875         acb->firm_sdram_size    = CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[3]);     /*firm_sdram_size,    3, 12-15*/
 3876         acb->firm_ide_channels  = CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[4]);     /*firm_ide_channels,  4, 16-19*/
 3877         acb->firm_cfg_version   = CHIP_REG_READ32(HBC_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);       /*firm_cfg_version,  25,          */
 3878         if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
 3879                 acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD - 1;
 3880         else
 3881                 acb->maxOutstanding = acb->firm_numbers_queue - 1;
 3882 }
 3883 /*
 3884 **********************************************************************
 3885 **********************************************************************
 3886 */
 3887 static void arcmsr_get_hbd_config(struct AdapterControlBlock *acb)
 3888 {
 3889         char *acb_firm_model = acb->firm_model;
 3890         char *acb_firm_version = acb->firm_version;
 3891         char *acb_device_map = acb->device_map;
 3892         size_t iop_firm_model = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);   /*firm_model,15,60-67*/
 3893         size_t iop_firm_version = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/
 3894         size_t iop_device_map = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
 3895         int i;
 3896 
 3897         if(CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell) & ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE)
 3898                 CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, ARCMSR_HBDMU_IOP2DRV_MESSAGE_CMD_DONE_CLEAR);
 3899         CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
 3900         if(!arcmsr_hbd_wait_msgint_ready(acb)) {
 3901                 printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
 3902         }
 3903         i = 0;
 3904         while(i < 8) {
 3905                 *acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); 
 3906                 /* 8 bytes firm_model, 15, 60-67*/
 3907                 acb_firm_model++;
 3908                 i++;
 3909         }
 3910         i = 0;
 3911         while(i < 16) {
 3912                 *acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i);  
 3913                 /* 16 bytes firm_version, 17, 68-83*/
 3914                 acb_firm_version++;
 3915                 i++;
 3916         }
 3917         i = 0;
 3918         while(i < 16) {
 3919                 *acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i);  
 3920                 acb_device_map++;
 3921                 i++;
 3922         }
 3923         printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
 3924         acb->firm_request_len   = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[1]);     /*firm_request_len,   1, 04-07*/
 3925         acb->firm_numbers_queue = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[2]);     /*firm_numbers_queue, 2, 08-11*/
 3926         acb->firm_sdram_size    = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[3]);     /*firm_sdram_size,    3, 12-15*/
 3927         acb->firm_ide_channels  = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[4]);     /*firm_ide_channels,  4, 16-19*/
 3928         acb->firm_cfg_version   = CHIP_REG_READ32(HBD_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);       /*firm_cfg_version,  25,          */
 3929         if(acb->firm_numbers_queue > ARCMSR_MAX_HBD_POSTQUEUE)
 3930                 acb->maxOutstanding = ARCMSR_MAX_HBD_POSTQUEUE - 1;
 3931         else
 3932                 acb->maxOutstanding = acb->firm_numbers_queue - 1;
 3933 }
 3934 /*
 3935 **********************************************************************
 3936 **********************************************************************
 3937 */
 3938 static void arcmsr_get_hbe_config(struct AdapterControlBlock *acb)
 3939 {
 3940         char *acb_firm_model = acb->firm_model;
 3941         char *acb_firm_version = acb->firm_version;
 3942         char *acb_device_map = acb->device_map;
 3943         size_t iop_firm_model = offsetof(struct HBE_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]);   /*firm_model,15,60-67*/
 3944         size_t iop_firm_version = offsetof(struct HBE_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/
 3945         size_t iop_device_map = offsetof(struct HBE_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
 3946         int i;
 3947 
 3948         CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
 3949         acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
 3950         CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
 3951         if(!arcmsr_hbe_wait_msgint_ready(acb)) {
 3952                 printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
 3953         }
 3954 
 3955         i = 0;
 3956         while(i < 8) {
 3957                 *acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i); 
 3958                 /* 8 bytes firm_model, 15, 60-67*/
 3959                 acb_firm_model++;
 3960                 i++;
 3961         }
 3962         i = 0;
 3963         while(i < 16) {
 3964                 *acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i);  
 3965                 /* 16 bytes firm_version, 17, 68-83*/
 3966                 acb_firm_version++;
 3967                 i++;
 3968         }
 3969         i = 0;
 3970         while(i < 16) {
 3971                 *acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i);  
 3972                 acb_device_map++;
 3973                 i++;
 3974         }
 3975         printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
 3976         acb->firm_request_len   = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[1]);     /*firm_request_len,   1, 04-07*/
 3977         acb->firm_numbers_queue = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[2]);     /*firm_numbers_queue, 2, 08-11*/
 3978         acb->firm_sdram_size    = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[3]);     /*firm_sdram_size,    3, 12-15*/
 3979         acb->firm_ide_channels  = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[4]);     /*firm_ide_channels,  4, 16-19*/
 3980         acb->firm_cfg_version   = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]);       /*firm_cfg_version,  25,          */
 3981         if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
 3982                 acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD - 1;
 3983         else
 3984                 acb->maxOutstanding = acb->firm_numbers_queue - 1;
 3985 }
 3986 /*
 3987 **********************************************************************
 3988 **********************************************************************
 3989 */
 3990 static void arcmsr_get_hbf_config(struct AdapterControlBlock *acb)
 3991 {
 3992         u_int32_t *acb_firm_model = (u_int32_t *)acb->firm_model;
 3993         u_int32_t *acb_firm_version = (u_int32_t *)acb->firm_version;
 3994         u_int32_t *acb_device_map = (u_int32_t *)acb->device_map;
 3995         size_t iop_firm_model = ARCMSR_FW_MODEL_OFFSET;   /*firm_model,15,60-67*/
 3996         size_t iop_firm_version = ARCMSR_FW_VERS_OFFSET; /*firm_version,17,68-83*/
 3997         size_t iop_device_map = ARCMSR_FW_DEVMAP_OFFSET;
 3998         int i;
 3999 
 4000         CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
 4001         acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
 4002         CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
 4003         if(!arcmsr_hbe_wait_msgint_ready(acb))
 4004                 printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
 4005 
 4006         i = 0;
 4007         while(i < 2) {
 4008                 *acb_firm_model = acb->msgcode_rwbuffer[iop_firm_model];
 4009                 /* 8 bytes firm_model, 15, 60-67*/
 4010                 acb_firm_model++;
 4011                 iop_firm_model++;
 4012                 i++;
 4013         }
 4014         i = 0;
 4015         while(i < 4) {
 4016                 *acb_firm_version = acb->msgcode_rwbuffer[iop_firm_version];
 4017                 /* 16 bytes firm_version, 17, 68-83*/
 4018                 acb_firm_version++;
 4019                 iop_firm_version++;
 4020                 i++;
 4021         }
 4022         i = 0;
 4023         while(i < 4) {
 4024                 *acb_device_map = acb->msgcode_rwbuffer[iop_device_map];
 4025                 acb_device_map++;
 4026                 iop_device_map++;
 4027                 i++;
 4028         }
 4029         printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
 4030         acb->firm_request_len   = acb->msgcode_rwbuffer[1];     /*firm_request_len,   1, 04-07*/
 4031         acb->firm_numbers_queue = acb->msgcode_rwbuffer[2];     /*firm_numbers_queue, 2, 08-11*/
 4032         acb->firm_sdram_size    = acb->msgcode_rwbuffer[3];     /*firm_sdram_size,    3, 12-15*/
 4033         acb->firm_ide_channels  = acb->msgcode_rwbuffer[4];     /*firm_ide_channels,  4, 16-19*/
 4034         acb->firm_cfg_version   = acb->msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]; /*firm_cfg_version,  25*/
 4035         if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
 4036                 acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD - 1;
 4037         else
 4038                 acb->maxOutstanding = acb->firm_numbers_queue - 1;
 4039 }
 4040 /*
 4041 **********************************************************************
 4042 **********************************************************************
 4043 */
 4044 static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
 4045 {
 4046         switch (acb->adapter_type) {
 4047         case ACB_ADAPTER_TYPE_A:
 4048                 arcmsr_get_hba_config(acb);
 4049                 break;
 4050         case ACB_ADAPTER_TYPE_B:
 4051                 arcmsr_get_hbb_config(acb);
 4052                 break;
 4053         case ACB_ADAPTER_TYPE_C:
 4054                 arcmsr_get_hbc_config(acb);
 4055                 break;
 4056         case ACB_ADAPTER_TYPE_D:
 4057                 arcmsr_get_hbd_config(acb);
 4058                 break;
 4059         case ACB_ADAPTER_TYPE_E:
 4060                 arcmsr_get_hbe_config(acb);
 4061                 break;
 4062         case ACB_ADAPTER_TYPE_F:
 4063                 arcmsr_get_hbf_config(acb);
 4064                 break;
 4065         }
 4066 }
 4067 /*
 4068 **********************************************************************
 4069 **********************************************************************
 4070 */
 4071 static void arcmsr_wait_firmware_ready( struct AdapterControlBlock *acb)
 4072 {
 4073         int     timeout=0;
 4074 
 4075         switch (acb->adapter_type) {
 4076         case ACB_ADAPTER_TYPE_A: {
 4077                         while ((CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0)
 4078                         {
 4079                                 if (timeout++ > 2000) /* (2000*15)/1000 = 30 sec */
 4080                                 {
 4081                                         printf( "arcmsr%d:timed out waiting for firmware \n", acb->pci_unit);
 4082                                         return;
 4083                                 }
 4084                                 UDELAY(15000); /* wait 15 milli-seconds */
 4085                         }
 4086                 }
 4087                 break;
 4088         case ACB_ADAPTER_TYPE_B: {
 4089                         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 4090                         while ((READ_CHIP_REG32(0, phbbmu->iop2drv_doorbell) & ARCMSR_MESSAGE_FIRMWARE_OK) == 0)
 4091                         {
 4092                                 if (timeout++ > 2000) /* (2000*15)/1000 = 30 sec */
 4093                                 {
 4094                                         printf( "arcmsr%d: timed out waiting for firmware \n", acb->pci_unit);
 4095                                         return;
 4096                                 }
 4097                                 UDELAY(15000); /* wait 15 milli-seconds */
 4098                         }
 4099                         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_END_OF_INTERRUPT);
 4100                 }
 4101                 break;
 4102         case ACB_ADAPTER_TYPE_C: {
 4103                         while ((CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK) == 0)
 4104                         {
 4105                                 if (timeout++ > 2000) /* (2000*15)/1000 = 30 sec */
 4106                                 {
 4107                                         printf( "arcmsr%d:timed out waiting for firmware ready\n", acb->pci_unit);
 4108                                         return;
 4109                                 }
 4110                                 UDELAY(15000); /* wait 15 milli-seconds */
 4111                         }
 4112                 }
 4113                 break;
 4114         case ACB_ADAPTER_TYPE_D: {
 4115                         while ((CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_HBDMU_MESSAGE_FIRMWARE_OK) == 0)
 4116                         {
 4117                                 if (timeout++ > 2000) /* (2000*15)/1000 = 30 sec */
 4118                                 {
 4119                                         printf( "arcmsr%d:timed out waiting for firmware ready\n", acb->pci_unit);
 4120                                         return;
 4121                                 }
 4122                                 UDELAY(15000); /* wait 15 milli-seconds */
 4123                         }
 4124                 }
 4125                 break;
 4126         case ACB_ADAPTER_TYPE_E:
 4127         case ACB_ADAPTER_TYPE_F: {
 4128                         while ((CHIP_REG_READ32(HBE_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_HBEMU_MESSAGE_FIRMWARE_OK) == 0)
 4129                         {
 4130                                 if (timeout++ > 4000) /* (4000*15)/1000 = 60 sec */
 4131                                 {
 4132                                         printf( "arcmsr%d:timed out waiting for firmware ready\n", acb->pci_unit);
 4133                                         return;
 4134                                 }
 4135                                 UDELAY(15000); /* wait 15 milli-seconds */
 4136                         }
 4137                 }
 4138                 break;
 4139         }
 4140 }
 4141 /*
 4142 **********************************************************************
 4143 **********************************************************************
 4144 */
 4145 static void arcmsr_clear_doorbell_queue_buffer( struct AdapterControlBlock *acb)
 4146 {
 4147         u_int32_t outbound_doorbell;
 4148 
 4149         switch (acb->adapter_type) {
 4150         case ACB_ADAPTER_TYPE_A: {
 4151                         /* empty doorbell Qbuffer if door bell ringed */
 4152                         outbound_doorbell = CHIP_REG_READ32(HBA_MessageUnit, 0, outbound_doorbell);
 4153                         CHIP_REG_WRITE32(HBA_MessageUnit, 0, outbound_doorbell, outbound_doorbell);     /*clear doorbell interrupt */
 4154                         CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
 4155                 }
 4156                 break;
 4157         case ACB_ADAPTER_TYPE_B: {
 4158                         struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 4159                         WRITE_CHIP_REG32(0, phbbmu->iop2drv_doorbell, ARCMSR_DOORBELL_INT_CLEAR_PATTERN);/*clear interrupt and message state*/
 4160                         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_DRV2IOP_DATA_READ_OK);
 4161                         /* let IOP know data has been read */
 4162                 }
 4163                 break;
 4164         case ACB_ADAPTER_TYPE_C: {
 4165                         /* empty doorbell Qbuffer if door bell ringed */
 4166                         outbound_doorbell = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell);
 4167                         CHIP_REG_WRITE32(HBC_MessageUnit, 0, outbound_doorbell_clear, outbound_doorbell);       /*clear doorbell interrupt */
 4168                         CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell, ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK);
 4169                         CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_doorbell_clear); /* Dummy read to force pci flush */
 4170                         CHIP_REG_READ32(HBC_MessageUnit, 0, inbound_doorbell); /* Dummy read to force pci flush */
 4171                 }
 4172                 break;
 4173         case ACB_ADAPTER_TYPE_D: {
 4174                         /* empty doorbell Qbuffer if door bell ringed */
 4175                         outbound_doorbell = CHIP_REG_READ32(HBD_MessageUnit, 0, outbound_doorbell);
 4176                         CHIP_REG_WRITE32(HBD_MessageUnit, 0, outbound_doorbell, outbound_doorbell);     /*clear doorbell interrupt */
 4177                         CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_OUT_READ);
 4178                 }
 4179                 break;
 4180         case ACB_ADAPTER_TYPE_E:
 4181         case ACB_ADAPTER_TYPE_F: {
 4182                         /* empty doorbell Qbuffer if door bell ringed */
 4183                         acb->in_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell);
 4184                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0);       /*clear doorbell interrupt */
 4185                         acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_READ_OK;
 4186                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
 4187                 }
 4188                 break;
 4189         }
 4190 }
 4191 /*
 4192 ************************************************************************
 4193 ************************************************************************
 4194 */
 4195 static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
 4196 {
 4197         unsigned long srb_phyaddr;
 4198         u_int32_t srb_phyaddr_hi32;
 4199         u_int32_t srb_phyaddr_lo32;
 4200 
 4201         /*
 4202         ********************************************************************
 4203         ** here we need to tell iop 331 our freesrb.HighPart 
 4204         ** if freesrb.HighPart is not zero
 4205         ********************************************************************
 4206         */
 4207         srb_phyaddr = (unsigned long) acb->srb_phyaddr.phyaddr;
 4208         srb_phyaddr_hi32 = acb->srb_phyaddr.B.phyadd_high;
 4209         srb_phyaddr_lo32 = acb->srb_phyaddr.B.phyadd_low;
 4210         switch (acb->adapter_type) {
 4211         case ACB_ADAPTER_TYPE_A: {
 4212                         if(srb_phyaddr_hi32 != 0) {
 4213                                 CHIP_REG_WRITE32(HBA_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG);
 4214                                 CHIP_REG_WRITE32(HBA_MessageUnit, 0, msgcode_rwbuffer[1], srb_phyaddr_hi32);
 4215                                 CHIP_REG_WRITE32(HBA_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
 4216                                 if(!arcmsr_hba_wait_msgint_ready(acb)) {
 4217                                         printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit);
 4218                                         return FALSE;
 4219                                 }
 4220                         }
 4221                 }
 4222                 break;
 4223                 /*
 4224                 ***********************************************************************
 4225                 **    if adapter type B, set window of "post command Q" 
 4226                 ***********************************************************************
 4227                 */
 4228         case ACB_ADAPTER_TYPE_B: {
 4229                         u_int32_t post_queue_phyaddr;
 4230                         struct HBB_MessageUnit *phbbmu;
 4231 
 4232                         phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 4233                         phbbmu->postq_index = 0;
 4234                         phbbmu->doneq_index = 0;
 4235                         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_SET_POST_WINDOW);
 4236                         if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 4237                                 printf( "arcmsr%d: 'set window of post command Q' timeout\n", acb->pci_unit);
 4238                                 return FALSE;
 4239                         }
 4240                         post_queue_phyaddr = srb_phyaddr + ARCMSR_SRBS_POOL_SIZE 
 4241                                                                 + offsetof(struct HBB_MessageUnit, post_qbuffer);
 4242                         CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG); /* driver "set config" signature */
 4243                         CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[1], srb_phyaddr_hi32); /* normal should be zero */
 4244                         CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[2], post_queue_phyaddr); /* postQ size (256+8)*4 */
 4245                         CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[3], post_queue_phyaddr+1056); /* doneQ size (256+8)*4 */
 4246                         CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[4], 1056); /* srb maxQ size must be --> [(256+8)*4] */
 4247                         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_SET_CONFIG);
 4248                         if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 4249                                 printf( "arcmsr%d: 'set command Q window' timeout \n", acb->pci_unit);
 4250                                 return FALSE;
 4251                         }
 4252                         WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_START_DRIVER_MODE);
 4253                         if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 4254                                 printf( "arcmsr%d: 'start diver mode' timeout \n", acb->pci_unit);
 4255                                 return FALSE;
 4256                         }
 4257                 }
 4258                 break;
 4259         case ACB_ADAPTER_TYPE_C: {
 4260                         if(srb_phyaddr_hi32 != 0) {
 4261                                 CHIP_REG_WRITE32(HBC_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG);
 4262                                 CHIP_REG_WRITE32(HBC_MessageUnit, 0, msgcode_rwbuffer[1], srb_phyaddr_hi32);
 4263                                 CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
 4264                                 CHIP_REG_WRITE32(HBC_MessageUnit, 0, inbound_doorbell,ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE);
 4265                                 if(!arcmsr_hbc_wait_msgint_ready(acb)) {
 4266                                         printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit);
 4267                                         return FALSE;
 4268                                 }
 4269                         }
 4270                 }
 4271                 break;
 4272         case ACB_ADAPTER_TYPE_D: {
 4273                         u_int32_t post_queue_phyaddr, done_queue_phyaddr;
 4274                         struct HBD_MessageUnit0 *phbdmu;
 4275 
 4276                         phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
 4277                         phbdmu->postq_index = 0;
 4278                         phbdmu->doneq_index = 0x40FF;
 4279                         post_queue_phyaddr = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE 
 4280                                                                 + offsetof(struct HBD_MessageUnit0, post_qbuffer);
 4281                         done_queue_phyaddr = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE 
 4282                                                                 + offsetof(struct HBD_MessageUnit0, done_qbuffer);
 4283                         CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG); /* driver "set config" signature */
 4284                         CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[1], srb_phyaddr_hi32);
 4285                         CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[2], post_queue_phyaddr); /* postQ base */
 4286                         CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[3], done_queue_phyaddr); /* doneQ base */
 4287                         CHIP_REG_WRITE32(HBD_MessageUnit, 0, msgcode_rwbuffer[4], 0x100);
 4288                         CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
 4289                         if(!arcmsr_hbd_wait_msgint_ready(acb)) {
 4290                                 printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit);
 4291                                 return FALSE;
 4292                         }
 4293                 }
 4294                 break;
 4295         case ACB_ADAPTER_TYPE_E: {
 4296                         u_int32_t cdb_phyaddr_lo32;
 4297                         cdb_phyaddr_lo32 = srb_phyaddr_lo32 + offsetof(struct CommandControlBlock, arcmsr_cdb);
 4298                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG);
 4299                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[1], ARCMSR_SIGNATURE_1884);
 4300                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[2], cdb_phyaddr_lo32);
 4301                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[3], srb_phyaddr_hi32);
 4302                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[4], SRB_SIZE);
 4303                         cdb_phyaddr_lo32 = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE;
 4304                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[5], cdb_phyaddr_lo32);
 4305                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[6], srb_phyaddr_hi32);
 4306                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[7], COMPLETION_Q_POOL_SIZE);
 4307                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
 4308                         acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
 4309                         CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
 4310                         if(!arcmsr_hbe_wait_msgint_ready(acb)) {
 4311                                 printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit);
 4312                                 return FALSE;
 4313                         }
 4314                 }
 4315                 break;
 4316         case ACB_ADAPTER_TYPE_F: {
 4317                         u_int32_t cdb_phyaddr_lo32;
 4318                         cdb_phyaddr_lo32 = srb_phyaddr_lo32 + offsetof(struct CommandControlBlock, arcmsr_cdb);
 4319                         acb->msgcode_rwbuffer[0] = ARCMSR_SIGNATURE_SET_CONFIG;
 4320                         acb->msgcode_rwbuffer[1] = ARCMSR_SIGNATURE_1886;
 4321                         acb->msgcode_rwbuffer[2] = cdb_phyaddr_lo32;
 4322                         acb->msgcode_rwbuffer[3] = srb_phyaddr_hi32;
 4323                         acb->msgcode_rwbuffer[4] = SRB_SIZE;
 4324                         cdb_phyaddr_lo32 = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE;
 4325                         acb->msgcode_rwbuffer[5] = cdb_phyaddr_lo32;
 4326                         acb->msgcode_rwbuffer[6] = srb_phyaddr_hi32;
 4327                         acb->msgcode_rwbuffer[7] = COMPLETION_Q_POOL_SIZE;
 4328                         CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
 4329                         acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
 4330                         CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
 4331                         if(!arcmsr_hbe_wait_msgint_ready(acb)) {
 4332                                 printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit);
 4333                                 return FALSE;
 4334                         }
 4335                 }
 4336                 break;
 4337         }
 4338         return (TRUE);
 4339 }
 4340 /*
 4341 ************************************************************************
 4342 ************************************************************************
 4343 */
 4344 static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb)
 4345 {
 4346         if (acb->adapter_type == ACB_ADAPTER_TYPE_B)
 4347         {
 4348                 struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 4349                 WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_ACTIVE_EOI_MODE);
 4350                 if(!arcmsr_hbb_wait_msgint_ready(acb)) {
 4351                         printf( "arcmsr%d: 'iop enable eoi mode' timeout \n", acb->pci_unit);
 4352                         return;
 4353                 }
 4354         }
 4355 }
 4356 /*
 4357 **********************************************************************
 4358 **********************************************************************
 4359 */
 4360 static void arcmsr_iop_init(struct AdapterControlBlock *acb)
 4361 {
 4362         u_int32_t intmask_org;
 4363 
 4364         /* disable all outbound interrupt */
 4365         intmask_org = arcmsr_disable_allintr(acb);
 4366         arcmsr_wait_firmware_ready(acb);
 4367         arcmsr_iop_confirm(acb);
 4368         arcmsr_get_firmware_spec(acb);
 4369         /*start background rebuild*/
 4370         arcmsr_start_adapter_bgrb(acb);
 4371         /* empty doorbell Qbuffer if door bell ringed */
 4372         arcmsr_clear_doorbell_queue_buffer(acb);
 4373         arcmsr_enable_eoi_mode(acb);
 4374         /* enable outbound Post Queue, outbound doorbell Interrupt */
 4375         arcmsr_enable_allintr(acb, intmask_org);
 4376         acb->acb_flags |= ACB_F_IOP_INITED;
 4377 }
 4378 /*
 4379 **********************************************************************
 4380 **********************************************************************
 4381 */
 4382 static void arcmsr_map_free_srb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 4383 {
 4384         struct AdapterControlBlock *acb = arg;
 4385         struct CommandControlBlock *srb_tmp;
 4386         u_int32_t i;
 4387         unsigned long srb_phyaddr = (unsigned long)segs->ds_addr;
 4388 
 4389         acb->srb_phyaddr.phyaddr = srb_phyaddr; 
 4390         srb_tmp = (struct CommandControlBlock *)acb->uncacheptr;
 4391         for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) {
 4392                 if(bus_dmamap_create(acb->dm_segs_dmat,
 4393                          /*flags*/0, &srb_tmp->dm_segs_dmamap) != 0) {
 4394                         acb->acb_flags |= ACB_F_MAPFREESRB_FAILD;
 4395                         printf("arcmsr%d:"
 4396                         " srb dmamap bus_dmamap_create error\n", acb->pci_unit);
 4397                         return;
 4398                 }
 4399                 if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D)
 4400                          || (acb->adapter_type == ACB_ADAPTER_TYPE_E) || (acb->adapter_type == ACB_ADAPTER_TYPE_F))
 4401                 {
 4402                         srb_tmp->cdb_phyaddr_low = srb_phyaddr;
 4403                         srb_tmp->cdb_phyaddr_high = (u_int32_t)((srb_phyaddr >> 16) >> 16);
 4404                 }
 4405                 else
 4406                         srb_tmp->cdb_phyaddr_low = srb_phyaddr >> 5;
 4407                 srb_tmp->acb = acb;
 4408                 srb_tmp->smid = i << 16;
 4409                 acb->srbworkingQ[i] = acb->psrb_pool[i] = srb_tmp;
 4410                 srb_phyaddr = srb_phyaddr + SRB_SIZE;
 4411                 srb_tmp = (struct CommandControlBlock *)((unsigned long)srb_tmp + SRB_SIZE);
 4412         }
 4413         if (acb->adapter_type == ACB_ADAPTER_TYPE_E)
 4414                 acb->pCompletionQ = (pCompletion_Q)srb_tmp;
 4415         else if (acb->adapter_type == ACB_ADAPTER_TYPE_F) {
 4416                 acb->pCompletionQ = (pCompletion_Q)srb_tmp;
 4417                 acb->completeQ_phys = srb_phyaddr;
 4418                 memset(acb->pCompletionQ, 0xff, COMPLETION_Q_POOL_SIZE);
 4419                 acb->message_wbuffer = (u_int32_t *)((unsigned long)acb->pCompletionQ + COMPLETION_Q_POOL_SIZE);
 4420                 acb->message_rbuffer = (u_int32_t *)((unsigned long)acb->message_wbuffer + 0x100);
 4421                 acb->msgcode_rwbuffer = (u_int32_t *)((unsigned long)acb->message_wbuffer + 0x200);
 4422                 memset((void *)acb->message_wbuffer, 0, MESG_RW_BUFFER_SIZE);
 4423         }
 4424         acb->vir2phy_offset = (unsigned long)srb_tmp - (unsigned long)srb_phyaddr;
 4425 }
 4426 /*
 4427 ************************************************************************
 4428 ************************************************************************
 4429 */
 4430 static void arcmsr_free_resource(struct AdapterControlBlock *acb)
 4431 {
 4432         /* remove the control device */
 4433         if(acb->ioctl_dev != NULL) {
 4434                 destroy_dev(acb->ioctl_dev);
 4435         }
 4436         bus_dmamap_unload(acb->srb_dmat, acb->srb_dmamap);
 4437         bus_dmamap_destroy(acb->srb_dmat, acb->srb_dmamap);
 4438         bus_dma_tag_destroy(acb->srb_dmat);
 4439         bus_dma_tag_destroy(acb->dm_segs_dmat);
 4440         bus_dma_tag_destroy(acb->parent_dmat);
 4441 }
 4442 /*
 4443 ************************************************************************
 4444 ************************************************************************
 4445 */
 4446 static void arcmsr_mutex_init(struct AdapterControlBlock *acb)
 4447 {
 4448         ARCMSR_LOCK_INIT(&acb->isr_lock, "arcmsr isr lock");
 4449         ARCMSR_LOCK_INIT(&acb->srb_lock, "arcmsr srb lock");
 4450         ARCMSR_LOCK_INIT(&acb->postDone_lock, "arcmsr postQ lock");
 4451         ARCMSR_LOCK_INIT(&acb->qbuffer_lock, "arcmsr RW buffer lock");
 4452 }
 4453 /*
 4454 ************************************************************************
 4455 ************************************************************************
 4456 */
 4457 static void arcmsr_mutex_destroy(struct AdapterControlBlock *acb)
 4458 {
 4459         ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock);
 4460         ARCMSR_LOCK_DESTROY(&acb->postDone_lock);
 4461         ARCMSR_LOCK_DESTROY(&acb->srb_lock);
 4462         ARCMSR_LOCK_DESTROY(&acb->isr_lock);
 4463 }
 4464 /*
 4465 ************************************************************************
 4466 ************************************************************************
 4467 */
 4468 static u_int32_t arcmsr_initialize(device_t dev)
 4469 {
 4470         struct AdapterControlBlock *acb = device_get_softc(dev);
 4471         u_int16_t pci_command;
 4472         int i, j,max_coherent_size;
 4473         u_int32_t vendor_dev_id;
 4474 
 4475         vendor_dev_id = pci_get_devid(dev);
 4476         acb->vendor_device_id = vendor_dev_id;
 4477         acb->sub_device_id = pci_read_config(dev, PCIR_SUBDEV_0, 2);
 4478         switch (vendor_dev_id) {
 4479         case PCIDevVenIDARC1880:
 4480         case PCIDevVenIDARC1882:
 4481         case PCIDevVenIDARC1213:
 4482         case PCIDevVenIDARC1223: {
 4483                         acb->adapter_type = ACB_ADAPTER_TYPE_C;
 4484                         if ((acb->sub_device_id == ARECA_SUB_DEV_ID_1883) ||
 4485                             (acb->sub_device_id == ARECA_SUB_DEV_ID_1216) ||
 4486                             (acb->sub_device_id == ARECA_SUB_DEV_ID_1226))
 4487                                 acb->adapter_bus_speed = ACB_BUS_SPEED_12G;
 4488                         else
 4489                                 acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
 4490                         max_coherent_size = ARCMSR_SRBS_POOL_SIZE;
 4491                 }
 4492                 break;
 4493         case PCIDevVenIDARC1884:
 4494                 acb->adapter_type = ACB_ADAPTER_TYPE_E;
 4495                 acb->adapter_bus_speed = ACB_BUS_SPEED_12G;
 4496                 max_coherent_size = ARCMSR_SRBS_POOL_SIZE + COMPLETION_Q_POOL_SIZE;
 4497                 acb->completionQ_entry = COMPLETION_Q_POOL_SIZE / sizeof(struct deliver_completeQ);
 4498                 break;
 4499         case PCIDevVenIDARC1886_:
 4500         case PCIDevVenIDARC1886:
 4501                 acb->adapter_type = ACB_ADAPTER_TYPE_F;
 4502                 acb->adapter_bus_speed = ACB_BUS_SPEED_12G;
 4503                 max_coherent_size = ARCMSR_SRBS_POOL_SIZE + COMPLETION_Q_POOL_SIZE + MESG_RW_BUFFER_SIZE;
 4504                 acb->completionQ_entry = COMPLETION_Q_POOL_SIZE / sizeof(struct deliver_completeQ);
 4505                 break;
 4506         case PCIDevVenIDARC1214: {
 4507                         acb->adapter_type = ACB_ADAPTER_TYPE_D;
 4508                         acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
 4509                         max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBD_MessageUnit0));
 4510                 }
 4511                 break;
 4512         case PCIDevVenIDARC1200:
 4513         case PCIDevVenIDARC1201: {
 4514                         acb->adapter_type = ACB_ADAPTER_TYPE_B;
 4515                         acb->adapter_bus_speed = ACB_BUS_SPEED_3G;
 4516                         max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit));
 4517                 }
 4518                 break;
 4519         case PCIDevVenIDARC1203: {
 4520                         acb->adapter_type = ACB_ADAPTER_TYPE_B;
 4521                         acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
 4522                         max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit));
 4523                 }
 4524                 break;
 4525         case PCIDevVenIDARC1110:
 4526         case PCIDevVenIDARC1120:
 4527         case PCIDevVenIDARC1130:
 4528         case PCIDevVenIDARC1160:
 4529         case PCIDevVenIDARC1170:
 4530         case PCIDevVenIDARC1210:
 4531         case PCIDevVenIDARC1220:
 4532         case PCIDevVenIDARC1230:
 4533         case PCIDevVenIDARC1231:
 4534         case PCIDevVenIDARC1260:
 4535         case PCIDevVenIDARC1261:
 4536         case PCIDevVenIDARC1270:
 4537         case PCIDevVenIDARC1280:
 4538         case PCIDevVenIDARC1212:
 4539         case PCIDevVenIDARC1222:
 4540         case PCIDevVenIDARC1380:
 4541         case PCIDevVenIDARC1381:
 4542         case PCIDevVenIDARC1680:
 4543         case PCIDevVenIDARC1681: {
 4544                         acb->adapter_type = ACB_ADAPTER_TYPE_A;
 4545                         acb->adapter_bus_speed = ACB_BUS_SPEED_3G;
 4546                         max_coherent_size = ARCMSR_SRBS_POOL_SIZE;
 4547                 }
 4548                 break;
 4549         default: {
 4550                         printf("arcmsr%d:"
 4551                         " unknown RAID adapter type \n", device_get_unit(dev));
 4552                         return ENOMEM;
 4553                 }
 4554         }
 4555         if(bus_dma_tag_create(  /*PCI parent*/          bus_get_dma_tag(dev),
 4556                                 /*alignemnt*/           1,
 4557                                 /*boundary*/            0,
 4558                                 /*lowaddr*/             BUS_SPACE_MAXADDR,
 4559                                 /*highaddr*/            BUS_SPACE_MAXADDR,
 4560                                 /*filter*/              NULL,
 4561                                 /*filterarg*/           NULL,
 4562                                 /*maxsize*/             BUS_SPACE_MAXSIZE_32BIT,
 4563                                 /*nsegments*/           BUS_SPACE_UNRESTRICTED,
 4564                                 /*maxsegsz*/            BUS_SPACE_MAXSIZE_32BIT,
 4565                                 /*flags*/               0,
 4566                                 /*lockfunc*/            NULL,
 4567                                 /*lockarg*/             NULL,
 4568                                                         &acb->parent_dmat) != 0)
 4569         {
 4570                 printf("arcmsr%d: parent_dmat bus_dma_tag_create failure!\n", device_get_unit(dev));
 4571                 return ENOMEM;
 4572         }
 4573 
 4574         /* Create a single tag describing a region large enough to hold all of the s/g lists we will need. */
 4575         if(bus_dma_tag_create(  /*parent_dmat*/         acb->parent_dmat,
 4576                                 /*alignment*/           1,
 4577                                 /*boundary*/            0,
 4578 #ifdef PAE
 4579                                 /*lowaddr*/             BUS_SPACE_MAXADDR_32BIT,
 4580 #else
 4581                                 /*lowaddr*/             BUS_SPACE_MAXADDR,
 4582 #endif
 4583                                 /*highaddr*/            BUS_SPACE_MAXADDR,
 4584                                 /*filter*/              NULL,
 4585                                 /*filterarg*/           NULL,
 4586                                 /*maxsize*/             ARCMSR_MAX_SG_ENTRIES * PAGE_SIZE * ARCMSR_MAX_FREESRB_NUM,
 4587                                 /*nsegments*/           ARCMSR_MAX_SG_ENTRIES,
 4588                                 /*maxsegsz*/            BUS_SPACE_MAXSIZE_32BIT,
 4589                                 /*flags*/               0,
 4590                                 /*lockfunc*/            busdma_lock_mutex,
 4591                                 /*lockarg*/             &acb->isr_lock,
 4592                                                         &acb->dm_segs_dmat) != 0)
 4593         {
 4594                 bus_dma_tag_destroy(acb->parent_dmat);
 4595                 printf("arcmsr%d: dm_segs_dmat bus_dma_tag_create failure!\n", device_get_unit(dev));
 4596                 return ENOMEM;
 4597         }
 4598 
 4599         /* DMA tag for our srb structures.... Allocate the freesrb memory */
 4600         if(bus_dma_tag_create(  /*parent_dmat*/         acb->parent_dmat,
 4601                                 /*alignment*/           0x20,
 4602                                 /*boundary*/            0,
 4603                                 /*lowaddr*/             BUS_SPACE_MAXADDR_32BIT,
 4604                                 /*highaddr*/            BUS_SPACE_MAXADDR,
 4605                                 /*filter*/              NULL,
 4606                                 /*filterarg*/           NULL,
 4607                                 /*maxsize*/             max_coherent_size,
 4608                                 /*nsegments*/           1,
 4609                                 /*maxsegsz*/            BUS_SPACE_MAXSIZE_32BIT,
 4610                                 /*flags*/               0,
 4611                                 /*lockfunc*/            NULL,
 4612                                 /*lockarg*/             NULL,
 4613                                                         &acb->srb_dmat) != 0)
 4614         {
 4615                 bus_dma_tag_destroy(acb->dm_segs_dmat);
 4616                 bus_dma_tag_destroy(acb->parent_dmat);
 4617                 printf("arcmsr%d: srb_dmat bus_dma_tag_create failure!\n", device_get_unit(dev));
 4618                 return ENXIO;
 4619         }
 4620         /* Allocation for our srbs */
 4621         if(bus_dmamem_alloc(acb->srb_dmat, (void **)&acb->uncacheptr, BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, &acb->srb_dmamap) != 0) {
 4622                 bus_dma_tag_destroy(acb->srb_dmat);
 4623                 bus_dma_tag_destroy(acb->dm_segs_dmat);
 4624                 bus_dma_tag_destroy(acb->parent_dmat);
 4625                 printf("arcmsr%d: srb_dmat bus_dmamem_alloc failure!\n", device_get_unit(dev));
 4626                 return ENXIO;
 4627         }
 4628         /* And permanently map them */
 4629         if(bus_dmamap_load(acb->srb_dmat, acb->srb_dmamap, acb->uncacheptr, max_coherent_size, arcmsr_map_free_srb, acb, /*flags*/0)) {
 4630                 bus_dma_tag_destroy(acb->srb_dmat);
 4631                 bus_dma_tag_destroy(acb->dm_segs_dmat);
 4632                 bus_dma_tag_destroy(acb->parent_dmat);
 4633                 printf("arcmsr%d: srb_dmat bus_dmamap_load failure!\n", device_get_unit(dev));
 4634                 return ENXIO;
 4635         }
 4636         pci_command = pci_read_config(dev, PCIR_COMMAND, 2);
 4637         pci_command |= PCIM_CMD_BUSMASTEREN;
 4638         pci_command |= PCIM_CMD_PERRESPEN;
 4639         pci_command |= PCIM_CMD_MWRICEN;
 4640         /* Enable Busmaster */
 4641         pci_write_config(dev, PCIR_COMMAND, pci_command, 2);
 4642         switch(acb->adapter_type) {
 4643         case ACB_ADAPTER_TYPE_A: {
 4644                 u_int32_t rid0 = PCIR_BAR(0);
 4645                 vm_offset_t     mem_base0;
 4646 
 4647                 acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid0, RF_ACTIVE);
 4648                 if(acb->sys_res_arcmsr[0] == NULL) {
 4649                         arcmsr_free_resource(acb);
 4650                         printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev));
 4651                         return ENOMEM;
 4652                 }
 4653                 if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
 4654                         arcmsr_free_resource(acb);
 4655                         printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev));
 4656                         return ENXIO;
 4657                 }
 4658                 mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
 4659                 if(mem_base0 == 0) {
 4660                         arcmsr_free_resource(acb);
 4661                         printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev));
 4662                         return ENXIO;
 4663                 }
 4664                 acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
 4665                 acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]);
 4666                 acb->pmu = (struct MessageUnit_UNION *)mem_base0;
 4667                 acb->rid[0] = rid0;
 4668                 }
 4669                 break;
 4670         case ACB_ADAPTER_TYPE_B: {
 4671                 struct HBB_MessageUnit *phbbmu;
 4672                 struct CommandControlBlock *freesrb;
 4673                 u_int32_t rid[]={ PCIR_BAR(0), PCIR_BAR(2) };
 4674                 vm_offset_t     mem_base[]={0,0};
 4675                 for(i=0; i < 2; i++) {
 4676                         acb->sys_res_arcmsr[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid[i], RF_ACTIVE);
 4677                         if(acb->sys_res_arcmsr[i] == NULL) {
 4678                                 arcmsr_free_resource(acb);
 4679                                 printf("arcmsr%d: bus_alloc_resource %d failure!\n", device_get_unit(dev), i);
 4680                                 return ENOMEM;
 4681                         }
 4682                         if(rman_get_start(acb->sys_res_arcmsr[i]) <= 0) {
 4683                                 arcmsr_free_resource(acb);
 4684                                 printf("arcmsr%d: rman_get_start %d failure!\n", device_get_unit(dev), i);
 4685                                 return ENXIO;
 4686                         }
 4687                         mem_base[i] = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[i]);
 4688                         if(mem_base[i] == 0) {
 4689                                 arcmsr_free_resource(acb);
 4690                                 printf("arcmsr%d: rman_get_virtual %d failure!\n", device_get_unit(dev), i);
 4691                                 return ENXIO;
 4692                         }
 4693                         acb->btag[i] = rman_get_bustag(acb->sys_res_arcmsr[i]);
 4694                         acb->bhandle[i] = rman_get_bushandle(acb->sys_res_arcmsr[i]);
 4695                 }
 4696                 freesrb = (struct CommandControlBlock *)acb->uncacheptr;
 4697                 acb->pmu = (struct MessageUnit_UNION *)((unsigned long)freesrb+ARCMSR_SRBS_POOL_SIZE);
 4698                 phbbmu = (struct HBB_MessageUnit *)acb->pmu;
 4699                 phbbmu->hbb_doorbell = (struct HBB_DOORBELL *)mem_base[0];
 4700                 phbbmu->hbb_rwbuffer = (struct HBB_RWBUFFER *)mem_base[1];
 4701                 if (vendor_dev_id == PCIDevVenIDARC1203) {
 4702                         phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell);
 4703                         phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell_mask);
 4704                         phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell);
 4705                         phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell_mask);
 4706                 } else {
 4707                         phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL, drv2iop_doorbell);
 4708                         phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL, drv2iop_doorbell_mask);
 4709                         phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL, iop2drv_doorbell);
 4710                         phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL, iop2drv_doorbell_mask);
 4711                 }
 4712                 acb->rid[0] = rid[0];
 4713                 acb->rid[1] = rid[1];
 4714                 }
 4715                 break;
 4716         case ACB_ADAPTER_TYPE_C: {
 4717                 u_int32_t rid0 = PCIR_BAR(1);
 4718                 vm_offset_t     mem_base0;
 4719 
 4720                 acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE);
 4721                 if(acb->sys_res_arcmsr[0] == NULL) {
 4722                         arcmsr_free_resource(acb);
 4723                         printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev));
 4724                         return ENOMEM;
 4725                 }
 4726                 if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
 4727                         arcmsr_free_resource(acb);
 4728                         printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev));
 4729                         return ENXIO;
 4730                 }
 4731                 mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
 4732                 if(mem_base0 == 0) {
 4733                         arcmsr_free_resource(acb);
 4734                         printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev));
 4735                         return ENXIO;
 4736                 }
 4737                 acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
 4738                 acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]);
 4739                 acb->pmu = (struct MessageUnit_UNION *)mem_base0;
 4740                 acb->rid[0] = rid0;
 4741                 }
 4742                 break;
 4743         case ACB_ADAPTER_TYPE_D: {
 4744                 struct HBD_MessageUnit0 *phbdmu;
 4745                 u_int32_t rid0 = PCIR_BAR(0);
 4746                 vm_offset_t     mem_base0;
 4747 
 4748                 acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE);
 4749                 if(acb->sys_res_arcmsr[0] == NULL) {
 4750                         arcmsr_free_resource(acb);
 4751                         printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev));
 4752                         return ENOMEM;
 4753                 }
 4754                 if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
 4755                         arcmsr_free_resource(acb);
 4756                         printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev));
 4757                         return ENXIO;
 4758                 }
 4759                 mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
 4760                 if(mem_base0 == 0) {
 4761                         arcmsr_free_resource(acb);
 4762                         printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev));
 4763                         return ENXIO;
 4764                 }
 4765                 acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
 4766                 acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]);
 4767                 acb->pmu = (struct MessageUnit_UNION *)((unsigned long)acb->uncacheptr+ARCMSR_SRBS_POOL_SIZE);
 4768                 phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
 4769                 phbdmu->phbdmu = (struct HBD_MessageUnit *)mem_base0;
 4770                 acb->rid[0] = rid0;
 4771                 }
 4772                 break;
 4773         case ACB_ADAPTER_TYPE_E: {
 4774                 u_int32_t rid0 = PCIR_BAR(1);
 4775                 vm_offset_t     mem_base0;
 4776 
 4777                 acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE);
 4778                 if(acb->sys_res_arcmsr[0] == NULL) {
 4779                         arcmsr_free_resource(acb);
 4780                         printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev));
 4781                         return ENOMEM;
 4782                 }
 4783                 if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
 4784                         arcmsr_free_resource(acb);
 4785                         printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev));
 4786                         return ENXIO;
 4787                 }
 4788                 mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
 4789                 if(mem_base0 == 0) {
 4790                         arcmsr_free_resource(acb);
 4791                         printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev));
 4792                         return ENXIO;
 4793                 }
 4794                 acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
 4795                 acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]);
 4796                 acb->pmu = (struct MessageUnit_UNION *)mem_base0;
 4797                 acb->doneq_index = 0;
 4798                 acb->in_doorbell = 0;
 4799                 acb->out_doorbell = 0;
 4800                 acb->rid[0] = rid0;
 4801                 CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0); /*clear interrupt*/
 4802                 CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, ARCMSR_HBEMU_DOORBELL_SYNC); /* synchronize doorbell to 0 */
 4803                 }
 4804                 break;
 4805         case ACB_ADAPTER_TYPE_F: {
 4806                 u_int32_t rid0 = PCIR_BAR(0);
 4807                 vm_offset_t     mem_base0;
 4808                 unsigned long   host_buffer_dma;
 4809 
 4810                 acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE);
 4811                 if(acb->sys_res_arcmsr[0] == NULL) {
 4812                         arcmsr_free_resource(acb);
 4813                         printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev));
 4814                         return ENOMEM;
 4815                 }
 4816                 if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
 4817                         arcmsr_free_resource(acb);
 4818                         printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev));
 4819                         return ENXIO;
 4820                 }
 4821                 mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
 4822                 if(mem_base0 == 0) {
 4823                         arcmsr_free_resource(acb);
 4824                         printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev));
 4825                         return ENXIO;
 4826                 }
 4827                 acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
 4828                 acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]);
 4829                 acb->pmu = (struct MessageUnit_UNION *)mem_base0;
 4830                 acb->doneq_index = 0;
 4831                 acb->in_doorbell = 0;
 4832                 acb->out_doorbell = 0;
 4833                 acb->rid[0] = rid0;
 4834                 arcmsr_wait_firmware_ready(acb);
 4835                 CHIP_REG_WRITE32(HBF_MessageUnit, 0, host_int_status, 0); /*clear interrupt*/
 4836                 CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, ARCMSR_HBEMU_DOORBELL_SYNC); /* synchronize doorbell to 0 */
 4837                 host_buffer_dma = acb->completeQ_phys + COMPLETION_Q_POOL_SIZE;
 4838                 CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, (u_int32_t)(host_buffer_dma | 1));  /* host buffer low addr, bit0:1 all buffer active */
 4839                 CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr1, (u_int32_t)((host_buffer_dma >> 16) >> 16));/* host buffer high addr */
 4840                 CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, ARCMSR_HBFMU_DOORBELL_SYNC1);       /* set host buffer physical address */
 4841                 }
 4842                 break;
 4843         }
 4844         if(acb->acb_flags & ACB_F_MAPFREESRB_FAILD) {
 4845                 arcmsr_free_resource(acb);
 4846                 printf("arcmsr%d: map free srb failure!\n", device_get_unit(dev));
 4847                 return ENXIO;
 4848         }
 4849         acb->acb_flags  |= (ACB_F_MESSAGE_WQBUFFER_CLEARED|ACB_F_MESSAGE_RQBUFFER_CLEARED|ACB_F_MESSAGE_WQBUFFER_READ);
 4850         acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER;
 4851         /*
 4852         ********************************************************************
 4853         ** init raid volume state
 4854         ********************************************************************
 4855         */
 4856         for(i=0; i < ARCMSR_MAX_TARGETID; i++) {
 4857                 for(j=0; j < ARCMSR_MAX_TARGETLUN; j++) {
 4858                         acb->devstate[i][j] = ARECA_RAID_GONE;
 4859                 }
 4860         }
 4861         arcmsr_iop_init(acb);
 4862         return(0);
 4863 }
 4864 
 4865 static int arcmsr_setup_msix(struct AdapterControlBlock *acb)
 4866 {
 4867         int i;
 4868 
 4869         for (i = 0; i < acb->msix_vectors; i++) {
 4870                 acb->irq_id[i] = 1 + i;
 4871                 acb->irqres[i] = bus_alloc_resource_any(acb->pci_dev,
 4872                     SYS_RES_IRQ, &acb->irq_id[i], RF_ACTIVE);
 4873                 if (acb->irqres[i] == NULL) {
 4874                         printf("arcmsr: Can't allocate MSI-X resource\n");
 4875                         goto irq_alloc_failed;
 4876                 }
 4877                 if (bus_setup_intr(acb->pci_dev, acb->irqres[i],
 4878                     INTR_MPSAFE | INTR_TYPE_CAM, NULL, arcmsr_intr_handler,
 4879                     acb, &acb->ih[i])) {
 4880                         printf("arcmsr: Cannot set up MSI-X interrupt handler\n");
 4881                         goto irq_alloc_failed;
 4882                 }
 4883         }
 4884         printf("arcmsr: MSI-X INT enabled\n");
 4885         acb->acb_flags |= ACB_F_MSIX_ENABLED;
 4886         return TRUE;
 4887 
 4888 irq_alloc_failed:
 4889         arcmsr_teardown_intr(acb->pci_dev, acb);
 4890         return FALSE;
 4891 }
 4892 
 4893 /*
 4894 ************************************************************************
 4895 ************************************************************************
 4896 */
 4897 static int arcmsr_attach(device_t dev)
 4898 {
 4899         struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev);
 4900         u_int32_t unit=device_get_unit(dev);
 4901         struct ccb_setasync csa;
 4902         struct cam_devq *devq;  /* Device Queue to use for this SIM */
 4903         struct resource *irqres;
 4904 
 4905         if(acb == NULL) {
 4906                 printf("arcmsr%d: cannot allocate softc\n", unit);
 4907                 return (ENOMEM);
 4908         }
 4909         arcmsr_mutex_init(acb);
 4910         acb->pci_dev = dev;
 4911         acb->pci_unit = unit;
 4912         if(arcmsr_initialize(dev)) {
 4913                 printf("arcmsr%d: initialize failure!\n", unit);
 4914                 goto initialize_failed;
 4915         }
 4916         /* After setting up the adapter, map our interrupt */
 4917         acb->msix_vectors = ARCMSR_NUM_MSIX_VECTORS;
 4918         if (pci_alloc_msix(dev, &acb->msix_vectors) == 0) {
 4919                 if (arcmsr_setup_msix(acb) == TRUE)
 4920                         goto irqx;
 4921         }
 4922         acb->irq_id[0] = 0;
 4923         irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &acb->irq_id[0], RF_SHAREABLE | RF_ACTIVE);
 4924         if(irqres == NULL || 
 4925                 bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE, NULL, arcmsr_intr_handler, acb, &acb->ih[0])) {
 4926                 printf("arcmsr%d: unable to register interrupt handler!\n", unit);
 4927                 goto setup_intr_failed;
 4928         }
 4929         acb->irqres[0] = irqres;
 4930 irqx:
 4931         /*
 4932          * Now let the CAM generic SCSI layer find the SCSI devices on
 4933          * the bus *  start queue to reset to the idle loop. *
 4934          * Create device queue of SIM(s) *  (MAX_START_JOB - 1) :
 4935          * max_sim_transactions
 4936         */
 4937         devq = cam_simq_alloc(acb->maxOutstanding);
 4938         if(devq == NULL) {
 4939                 printf("arcmsr%d: cam_simq_alloc failure!\n", unit);
 4940                 goto simq_alloc_failed;
 4941         }
 4942         acb->psim = cam_sim_alloc(arcmsr_action, arcmsr_poll, "arcmsr", acb, unit, &acb->isr_lock, 1, ARCMSR_MAX_OUTSTANDING_CMD, devq);
 4943         if(acb->psim == NULL) {
 4944                 printf("arcmsr%d: cam_sim_alloc failure!\n", unit);
 4945                 goto sim_alloc_failed;
 4946         }
 4947         ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
 4948         if(xpt_bus_register(acb->psim, dev, 0) != CAM_SUCCESS) {
 4949                 printf("arcmsr%d: xpt_bus_register failure!\n", unit);
 4950                 goto xpt_bus_failed;
 4951         }
 4952         if(xpt_create_path(&acb->ppath, /* periph */ NULL, cam_sim_path(acb->psim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
 4953                 printf("arcmsr%d: xpt_create_path failure!\n", unit);
 4954                 goto xpt_path_failed;
 4955         }
 4956         /*
 4957         ****************************************************
 4958         */
 4959         xpt_setup_ccb(&csa.ccb_h, acb->ppath, /*priority*/5);
 4960         csa.ccb_h.func_code = XPT_SASYNC_CB;
 4961         csa.event_enable = AC_FOUND_DEVICE|AC_LOST_DEVICE;
 4962         csa.callback = arcmsr_async;
 4963         csa.callback_arg = acb->psim;
 4964         xpt_action((union ccb *)&csa);
 4965         ARCMSR_LOCK_RELEASE(&acb->isr_lock);
 4966         /* Create the control device.  */
 4967         acb->ioctl_dev = make_dev(&arcmsr_cdevsw, unit, UID_ROOT, GID_WHEEL /* GID_OPERATOR */, S_IRUSR | S_IWUSR, "arcmsr%d", unit);
 4968                 
 4969         (void)make_dev_alias(acb->ioctl_dev, "arc%d", unit);
 4970         arcmsr_callout_init(&acb->devmap_callout);
 4971         callout_reset(&acb->devmap_callout, 60 * hz, arcmsr_polling_devmap, acb);
 4972         return (0);
 4973 xpt_path_failed:
 4974         xpt_bus_deregister(cam_sim_path(acb->psim));
 4975 xpt_bus_failed:
 4976         cam_sim_free(acb->psim, /* free_simq */ TRUE);
 4977 sim_alloc_failed:
 4978         cam_simq_free(devq);
 4979 simq_alloc_failed:
 4980         arcmsr_teardown_intr(dev, acb);
 4981 setup_intr_failed:
 4982         arcmsr_free_resource(acb);
 4983 initialize_failed:
 4984         arcmsr_mutex_destroy(acb);
 4985         return ENXIO;
 4986 }
 4987 
 4988 /*
 4989 ************************************************************************
 4990 ************************************************************************
 4991 */
 4992 static int arcmsr_probe(device_t dev)
 4993 {
 4994         u_int32_t id;
 4995         u_int16_t sub_device_id;
 4996         static char buf[256];
 4997         char x_type[]={"unknown"};
 4998         char *type;
 4999         int raid6 = 1;
 5000 
 5001         if (pci_get_vendor(dev) != PCI_VENDOR_ID_ARECA) {
 5002                 return (ENXIO);
 5003         }
 5004         sub_device_id = pci_read_config(dev, PCIR_SUBDEV_0, 2);
 5005         switch(id = pci_get_devid(dev)) {
 5006         case PCIDevVenIDARC1110:
 5007         case PCIDevVenIDARC1200:
 5008         case PCIDevVenIDARC1201:
 5009         case PCIDevVenIDARC1210:
 5010                 raid6 = 0;
 5011                 /*FALLTHRU*/
 5012         case PCIDevVenIDARC1120:
 5013         case PCIDevVenIDARC1130:
 5014         case PCIDevVenIDARC1160:
 5015         case PCIDevVenIDARC1170:
 5016         case PCIDevVenIDARC1220:
 5017         case PCIDevVenIDARC1230:
 5018         case PCIDevVenIDARC1231:
 5019         case PCIDevVenIDARC1260:
 5020         case PCIDevVenIDARC1261:
 5021         case PCIDevVenIDARC1270:
 5022         case PCIDevVenIDARC1280:
 5023                 type = "SATA 3G";
 5024                 break;
 5025         case PCIDevVenIDARC1212:
 5026         case PCIDevVenIDARC1222:
 5027         case PCIDevVenIDARC1380:
 5028         case PCIDevVenIDARC1381:
 5029         case PCIDevVenIDARC1680:
 5030         case PCIDevVenIDARC1681:
 5031                 type = "SAS 3G";
 5032                 break;
 5033         case PCIDevVenIDARC1880:
 5034         case PCIDevVenIDARC1882:
 5035         case PCIDevVenIDARC1213:
 5036         case PCIDevVenIDARC1223:
 5037                 if ((sub_device_id == ARECA_SUB_DEV_ID_1883) ||
 5038                     (sub_device_id == ARECA_SUB_DEV_ID_1216) ||
 5039                     (sub_device_id == ARECA_SUB_DEV_ID_1226))
 5040                         type = "SAS 12G";
 5041                 else
 5042                         type = "SAS 6G";
 5043                 break;
 5044         case PCIDevVenIDARC1884:
 5045                 type = "SAS 12G";
 5046                 break;
 5047         case PCIDevVenIDARC1886_:
 5048         case PCIDevVenIDARC1886:
 5049                 type = "NVME,SAS-12G,SATA-6G";
 5050                 break;
 5051         case PCIDevVenIDARC1214:
 5052         case PCIDevVenIDARC1203:
 5053                 type = "SATA 6G";
 5054                 break;
 5055         default:
 5056                 type = x_type;
 5057                 raid6 = 0;
 5058                 break;
 5059         }
 5060         if(type == x_type)
 5061                 return(ENXIO);
 5062         sprintf(buf, "Areca %s Host Adapter RAID Controller %s\n%s\n",
 5063                 type, raid6 ? "(RAID6 capable)" : "", ARCMSR_DRIVER_VERSION);
 5064         device_set_desc_copy(dev, buf);
 5065         return (BUS_PROBE_DEFAULT);
 5066 }
 5067 /*
 5068 ************************************************************************
 5069 ************************************************************************
 5070 */
 5071 static int arcmsr_shutdown(device_t dev)
 5072 {
 5073         u_int32_t  i;
 5074         u_int32_t intmask_org;
 5075         struct CommandControlBlock *srb;
 5076         struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev);
 5077 
 5078         /* stop adapter background rebuild */
 5079         ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
 5080         /* disable all outbound interrupt */
 5081         intmask_org = arcmsr_disable_allintr(acb);
 5082         arcmsr_stop_adapter_bgrb(acb);
 5083         arcmsr_flush_adapter_cache(acb);
 5084         /* abort all outstanding command */
 5085         acb->acb_flags |= ACB_F_SCSISTOPADAPTER;
 5086         acb->acb_flags &= ~ACB_F_IOP_INITED;
 5087         if(acb->srboutstandingcount != 0) {
 5088                 /*clear and abort all outbound posted Q*/
 5089                 arcmsr_done4abort_postqueue(acb);
 5090                 /* talk to iop 331 outstanding command aborted*/
 5091                 arcmsr_abort_allcmd(acb);
 5092                 for(i=0; i < ARCMSR_MAX_FREESRB_NUM; i++) {
 5093                         srb = acb->psrb_pool[i];
 5094                         if(srb->srb_state == ARCMSR_SRB_START) {
 5095                                 srb->srb_state = ARCMSR_SRB_ABORTED;
 5096                                 srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
 5097                                 arcmsr_srb_complete(srb, 1);
 5098                         }
 5099                 }
 5100         }
 5101         acb->srboutstandingcount = 0;
 5102         acb->workingsrb_doneindex = 0;
 5103         acb->workingsrb_startindex = 0;
 5104         acb->pktRequestCount = 0;
 5105         acb->pktReturnCount = 0;
 5106         ARCMSR_LOCK_RELEASE(&acb->isr_lock);
 5107         return (0);
 5108 }
 5109 /*
 5110 ************************************************************************
 5111 ************************************************************************
 5112 */
 5113 static void arcmsr_teardown_intr(device_t dev, struct AdapterControlBlock *acb)
 5114 {
 5115         int i;
 5116 
 5117         if (acb->acb_flags & ACB_F_MSIX_ENABLED) {
 5118                 for (i = 0; i < acb->msix_vectors; i++) {
 5119                         if (acb->ih[i])
 5120                                 bus_teardown_intr(dev, acb->irqres[i], acb->ih[i]);
 5121                         if (acb->irqres[i] != NULL)
 5122                                 bus_release_resource(dev, SYS_RES_IRQ,
 5123                                     acb->irq_id[i], acb->irqres[i]);
 5124 
 5125                         acb->ih[i] = NULL;
 5126                 }
 5127                 pci_release_msi(dev);
 5128         } else {
 5129                 if (acb->ih[0])
 5130                         bus_teardown_intr(dev, acb->irqres[0], acb->ih[0]);
 5131                 if (acb->irqres[0] != NULL)
 5132                         bus_release_resource(dev, SYS_RES_IRQ,
 5133                             acb->irq_id[0], acb->irqres[0]);
 5134                 acb->ih[0] = NULL;
 5135         }
 5136 
 5137 }
 5138 /*
 5139 ************************************************************************
 5140 ************************************************************************
 5141 */
 5142 static int arcmsr_detach(device_t dev)
 5143 {
 5144         struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev);
 5145         int i;
 5146 
 5147         callout_stop(&acb->devmap_callout);
 5148         arcmsr_teardown_intr(dev, acb);
 5149         arcmsr_shutdown(dev);
 5150         arcmsr_free_resource(acb);
 5151         for(i=0; (acb->sys_res_arcmsr[i]!=NULL) && (i<2); i++) {
 5152                 bus_release_resource(dev, SYS_RES_MEMORY, acb->rid[i], acb->sys_res_arcmsr[i]);
 5153         }
 5154         ARCMSR_LOCK_ACQUIRE(&acb->isr_lock);
 5155         xpt_async(AC_LOST_DEVICE, acb->ppath, NULL);
 5156         xpt_free_path(acb->ppath);
 5157         xpt_bus_deregister(cam_sim_path(acb->psim));
 5158         cam_sim_free(acb->psim, TRUE);
 5159         ARCMSR_LOCK_RELEASE(&acb->isr_lock);
 5160         arcmsr_mutex_destroy(acb);
 5161         return (0);
 5162 }
 5163 
 5164 #ifdef ARCMSR_DEBUG1
 5165 static void arcmsr_dump_data(struct AdapterControlBlock *acb)
 5166 {
 5167         if((acb->pktRequestCount - acb->pktReturnCount) == 0)
 5168                 return;
 5169         printf("Command Request Count   =0x%x\n",acb->pktRequestCount);
 5170         printf("Command Return Count    =0x%x\n",acb->pktReturnCount);
 5171         printf("Command (Req-Rtn) Count =0x%x\n",(acb->pktRequestCount - acb->pktReturnCount));
 5172         printf("Queued Command Count    =0x%x\n",acb->srboutstandingcount);
 5173 }
 5174 #endif

Cache object: d5256b8b22662356a2e116e9fda31ab5


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