arcmsr(4): Sync with FreeBSD.
authorSascha Wildner <saw@online.de>
Sun, 6 May 2012 17:18:28 +0000 (19:18 +0200)
committerSascha Wildner <saw@online.de>
Sun, 6 May 2012 17:19:17 +0000 (19:19 +0200)
Updates to 1.20.00.22

Some bugfixing (mainly, better timeout handling) and cleanups.

share/man/man4/arcmsr.4
sys/dev/raid/arcmsr/arcmsr.c
sys/dev/raid/arcmsr/arcmsr.h

index 3711495..7548f01 100644 (file)
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/share/man/man4/arcmsr.4,v 1.6 2008/03/28 23:25:58 brueffer Exp $
+.\" $FreeBSD: src/share/man/man4/arcmsr.4,v 1.7 2010/11/25 19:33:39 delphij Exp $
 .\"
-.Dd April 7, 2012
+.Dd May 6, 2012
 .Dt ARCMSR 4
 .Os
 .Sh NAME
 .Nm arcmsr
-.Nd Areca SATA II RAID Controller driver
+.Nd Areca RAID Controller driver
 .Sh SYNOPSIS
 To compile this driver into the kernel,
 place the following lines in your
@@ -50,11 +50,11 @@ arcmsr_load="YES"
 .Sh DESCRIPTION
 The
 .Nm
-driver provides support for the Areca ARC-11xx and ARC-12xx series of SATA II
-RAID controllers.
+driver provides support for the Areca ARC-11xx, ARC-12xx, ARC-13xx,
+ARC-16xx and ARC-18xx series of SAS and SATA RAID controllers.
 These controllers feature RAID-0, 1, 3, 5, 6, and 10 and
 JBOD acceleration for up to 16 SATA drives.
-Raid level and stripe level
+RAID level and stripe level
 migration, online capacity expansion, hot insertion/removal, automatic failover
 and rebuild, and SMART are also supported.
 Access to the arrays is provided
@@ -88,8 +88,6 @@ ARC-1160
 .It
 ARC-1170
 .It
-ARC-1180
-.It
 ARC-1110ML
 .It
 ARC-1120ML
@@ -98,14 +96,28 @@ ARC-1130ML
 .It
 ARC-1160ML
 .It
+ARC-1200
+.It
+ARC-1201
+.It
 ARC-1210
 .It
+ARC-1212
+.It
 ARC-1220
 .It
+ARC-1222
+.It
 ARC-1230
 .It
+ARC-1231
+.It
 ARC-1260
 .It
+ARC-1261
+.It
+ARC-1270
+.It
 ARC-1280
 .It
 ARC-1210ML
@@ -118,6 +130,10 @@ ARC-1261ML
 .It
 ARC-1280ML
 .It
+ARC-1380
+.It
+ARC-1381
+.It
 ARC-1680i
 .It
 ARC-1680x
@@ -128,6 +144,8 @@ ARC-1680ixl
 .It
 ARC-1680LP
 .It
+ARC-1681
+.It
 ARC-1880i
 .It
 ARC-1880x
index ea6533b..4b02bba 100644 (file)
 ** History
 **
 **        REV#         DATE                NAME                 DESCRIPTION
-**     1.00.00.00    3/31/2004        Erich Chen        First release
-**     1.20.00.02   11/29/2004         Erich Chen        bug fix with arcmsr_bus_reset when PHY error
-**     1.20.00.03    4/19/2005         Erich Chen        add SATA 24 Ports adapter type support
+**     1.00.00.00      03/31/2004              Erich Chen                       First release
+**     1.20.00.02      11/29/2004              Erich Chen                       bug fix with arcmsr_bus_reset when PHY error
+**     1.20.00.03      04/19/2005              Erich Chen                       add SATA 24 Ports adapter type support
 **                                                       clean unused function
-**     1.20.00.12    9/12/2005         Erich Chen        bug fix with abort command handling,
+**     1.20.00.12      09/12/2005              Erich Chen               bug fix with abort command handling,
 **                                                       firmware version check
 **                                                       and firmware update notify for hardware bug fix
 **                                                       handling if none zero high part physical address
 **                                                       of srb resource
-**     1.20.00.13    8/18/2006         Erich Chen        remove pending srb and report busy
+**     1.20.00.13      08/18/2006              Erich Chen                       remove pending srb and report busy
 **                                                       add iop message xfer
 **                                                       with scsi pass-through command
 **                                                       add new device id of sas raid adapters
 **                                                       code fit for SPARC64 & PPC
-**     1.20.00.14   02/05/2007         Erich Chen        bug fix for incorrect ccb_h.status report
+**     1.20.00.14      02/05/2007              Erich Chen                       bug fix for incorrect ccb_h.status report
 **                                                       and cause g_vfs_done() read write error
-**     1.20.00.15   10/10/2007         Erich Chen        support new RAID adapter type ARC120x
-**     1.20.00.16   10/10/2009         Erich Chen        Bug fix for RAID adapter type ARC120x
+**     1.20.00.15      10/10/2007              Erich Chen                       support new RAID adapter type ARC120x
+**     1.20.00.16      10/10/2009              Erich Chen                       Bug fix for RAID adapter type ARC120x
 **                                                       bus_dmamem_alloc() with BUS_DMA_ZERO
 **     1.20.00.17   07/15/2010         Ching Huang       Added support ARC1880
 **                                                      report CAM_DEV_NOT_THERE instead of CAM_SEL_TIMEOUT when device failed,
 **                                                      prevent cam_periph_error removing all LUN devices of one Target id
 **                                                      for any one LUN device failed
-**     1.20.00.18   10/14/2010         Ching Huang      Fixed "inquiry data fails comparion at DV1 step"
-**                 10/25/2010         Ching Huang       Fixed bad range input in bus_alloc_resource for ADAPTER_TYPE_B
-**     1.20.00.19   11/11/2010         Ching Huang      Fixed arcmsr driver prevent arcsas support for Areca SAS HBA ARC13x0
+**     1.20.00.18      10/14/2010              Ching Huang                      Fixed "inquiry data fails comparion at DV1 step"
+**                     10/25/2010              Ching Huang                      Fixed bad range input in bus_alloc_resource for ADAPTER_TYPE_B
+**     1.20.00.19      11/11/2010              Ching Huang                      Fixed arcmsr driver prevent arcsas support for Areca SAS HBA ARC13x0
+**     1.20.00.20      12/08/2010              Ching Huang                      Avoid calling atomic_set_int function
+**     1.20.00.21      02/08/2011              Ching Huang                      Implement I/O request timeout
+**                     02/14/2011              Ching Huang                      Modified pktRequestCount
+**     1.20.00.21      03/03/2011              Ching Huang                      if a command timeout, then wait its ccb back before free it
+**     1.20.00.22      07/04/2011              Ching Huang                      Fixed multiple MTX panic
 ******************************************************************************************
-* $FreeBSD: src/sys/dev/arcmsr/arcmsr.c,v 1.35 2010/11/13 08:58:36 delphij Exp $
+* $FreeBSD: src/sys/dev/arcmsr/arcmsr.c,v 1.38 2011/08/16 08:41:37 delphij Exp $
 */
+#if 0
+#define ARCMSR_DEBUG1                  1
+#endif
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/malloc.h>
@@ -119,9 +127,12 @@ typedef struct lock                arcmsr_lock_t;
 #define        CAM_NEW_TRAN_CODE       1
 #endif
 
-#define ARCMSR_DRIVER_VERSION                  "Driver Version 1.20.00.19 2010-11-11"
+#define arcmsr_callout_init(a) callout_init_mp(a);
+
+#define ARCMSR_DRIVER_VERSION                  "Driver Version 1.20.00.22 2011-07-04"
 #include <dev/raid/arcmsr/arcmsr.h>
-#define ARCMSR_SRBS_POOL_SIZE           ((sizeof(struct CommandControlBlock) * ARCMSR_MAX_FREESRB_NUM))
+#define        SRB_SIZE                                                ((sizeof(struct CommandControlBlock)+0x1f) & 0xffe0)
+#define ARCMSR_SRBS_POOL_SIZE           (SRB_SIZE * ARCMSR_MAX_FREESRB_NUM)
 /*
 **************************************************************************
 **************************************************************************
@@ -132,6 +143,7 @@ typedef struct lock         arcmsr_lock_t;
 **************************************************************************
 **************************************************************************
 */
+static void arcmsr_free_srb(struct CommandControlBlock *srb);
 static struct CommandControlBlock * arcmsr_get_freesrb(struct AdapterControlBlock *acb);
 static u_int8_t arcmsr_seek_cmd2abort(union ccb * abortccb);
 static int arcmsr_probe(device_t dev);
@@ -159,6 +171,10 @@ static int arcmsr_resume(device_t dev);
 static int arcmsr_suspend(device_t dev);
 static void arcmsr_rescanLun_cb(struct cam_periph *periph, union ccb *ccb);
 static void    arcmsr_polling_devmap(void* arg);
+static void    arcmsr_srb_timeout(void* arg);
+#ifdef ARCMSR_DEBUG1
+static void arcmsr_dump_data(struct AdapterControlBlock *acb);
+#endif
 /*
 **************************************************************************
 **************************************************************************
@@ -529,6 +545,8 @@ static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag)
        struct AdapterControlBlock *acb=srb->acb;
        union ccb * pccb=srb->pccb;
 
+       if(srb->srb_flags & SRB_FLAG_TIMER_START)
+               callout_stop(&srb->ccb_callout);
        if((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
                bus_dmasync_op_t op;
 
@@ -548,11 +566,11 @@ static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag)
                        pccb->ccb_h.status |= CAM_RELEASE_SIMQ;
                }
        }
-       srb->startdone=ARCMSR_SRB_DONE;
-       srb->srb_flags=0;
-       acb->srbworkingQ[acb->workingsrb_doneindex]=srb;
-       acb->workingsrb_doneindex++;
-       acb->workingsrb_doneindex %= ARCMSR_MAX_FREESRB_NUM;
+       if(srb->srb_state != ARCMSR_SRB_TIMEOUT)
+               arcmsr_free_srb(srb);
+#ifdef ARCMSR_DEBUG1
+       acb->pktReturnCount++;
+#endif
        xpt_done(pccb);
        return;
 }
@@ -697,7 +715,7 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, u_int32_t fl
        /* check if command done with no error*/
        switch (acb->adapter_type) {
        case ACB_ADAPTER_TYPE_C:
-               srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFF0));/*frame must be 32 bytes aligned*/
+               srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/
                break;
        case ACB_ADAPTER_TYPE_A:
        case ACB_ADAPTER_TYPE_B:
@@ -705,21 +723,50 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, u_int32_t fl
                srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
                break;
        }
-       if((srb->acb!=acb) || (srb->startdone!=ARCMSR_SRB_START)) {
-               if(srb->startdone==ARCMSR_SRB_ABORTED) {
-                       kprintf("arcmsr%d: srb='%p' isr got aborted command \n", acb->pci_unit, srb);
-                       srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
-                       arcmsr_srb_complete(srb, 1);
+       if((srb->acb!=acb) || (srb->srb_state!=ARCMSR_SRB_START)) {
+               if(srb->srb_state == ARCMSR_SRB_TIMEOUT) {
+                       arcmsr_free_srb(srb);
+                       kprintf("arcmsr%d: srb='%p' return srb has been timeouted\n", acb->pci_unit, srb);
                        return;
                }
-               kprintf("arcmsr%d: isr get an illegal srb command done"
-                       "acb='%p' srb='%p' srbacb='%p' startdone=0x%xsrboutstandingcount=%d \n",
-                       acb->pci_unit, acb, srb, srb->acb,srb->startdone, acb->srboutstandingcount);
+               kprintf("arcmsr%d: return srb has been completed\n"
+                       "srb='%p' srb_state=0x%x outstanding srb count=%d \n",
+                       acb->pci_unit, srb, srb->srb_state, acb->srboutstandingcount);
                return;
        }
        arcmsr_report_srb_state(acb, srb, error);
        return;
 }
+/*
+**************************************************************************
+**************************************************************************
+*/
+static void    arcmsr_srb_timeout(void* arg)
+{
+       struct CommandControlBlock *srb = (struct CommandControlBlock *)arg;
+       struct AdapterControlBlock *acb;
+       int target, lun;
+       u_int8_t cmd;
+
+       target=srb->pccb->ccb_h.target_id;
+       lun=srb->pccb->ccb_h.target_lun;
+       acb = srb->acb;
+       ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
+       if(srb->srb_state == ARCMSR_SRB_START)
+       {
+               cmd = srb->pccb->csio.cdb_io.cdb_bytes[0];
+               srb->srb_state = ARCMSR_SRB_TIMEOUT;
+               srb->pccb->ccb_h.status |= CAM_CMD_TIMEOUT;
+               arcmsr_srb_complete(srb, 1);
+               kprintf("arcmsr%d: scsi id %d lun %d cmd=0x%x srb='%p' ccb command time out!\n",
+                                acb->pci_unit, target, lun, cmd, srb);
+       }
+       ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+#ifdef ARCMSR_DEBUG1
+       arcmsr_dump_data(acb);
+#endif
+}
+
 /*
 **********************************************************************
 **********************************************************************
@@ -791,18 +838,25 @@ static void arcmsr_iop_reset(struct AdapterControlBlock *acb)
                arcmsr_abort_allcmd(acb);
                for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++) {
                        srb=acb->psrb_pool[i];
-                       if(srb->startdone==ARCMSR_SRB_START) {
-                               srb->startdone=ARCMSR_SRB_ABORTED;
+                       if(srb->srb_state==ARCMSR_SRB_START) {
+                               srb->srb_state=ARCMSR_SRB_ABORTED;
                                srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
                                arcmsr_srb_complete(srb, 1);
+                               kprintf("arcmsr%d: scsi id=%d lun=%d srb='%p' aborted\n"
+                                               , acb->pci_unit, srb->pccb->ccb_h.target_id
+                                               , srb->pccb->ccb_h.target_lun, srb);
                        }
                }
                /* enable all outbound interrupt */
                arcmsr_enable_allintr(acb, intmask_org);
        }
-       atomic_set_int(&acb->srboutstandingcount, 0);
+       acb->srboutstandingcount=0;
        acb->workingsrb_doneindex=0;
        acb->workingsrb_startindex=0;
+#ifdef ARCMSR_DEBUG1
+       acb->pktRequestCount = 0;
+       acb->pktReturnCount = 0;
+#endif
        return;
 }
 /*
@@ -904,7 +958,7 @@ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandContr
 
        bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, (srb->srb_flags & SRB_FLAG_WRITE) ? BUS_DMASYNC_POSTWRITE:BUS_DMASYNC_POSTREAD);
        atomic_add_int(&acb->srboutstandingcount, 1);
-       srb->startdone=ARCMSR_SRB_START;
+       srb->srb_state=ARCMSR_SRB_START;
 
        switch (acb->adapter_type) {
        case ACB_ADAPTER_TYPE_A: {
@@ -1176,11 +1230,15 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb)
 static void arcmsr_poll(struct cam_sim * psim)
 {
        struct AdapterControlBlock *acb;
+       int     mutex;
 
        acb = (struct AdapterControlBlock *)cam_sim_softc(psim);
-       ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
+       mutex = lockstatus(&acb->qbuffer_lock, curthread);
+       if( mutex == 0 )
+               ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
        arcmsr_interrupt(acb);
-       ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+       if( mutex == 0 )
+               ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
        return;
 }
 /*
@@ -1303,13 +1361,14 @@ static void arcmsr_abort_dr_ccbs(struct AdapterControlBlock *acb, int target, in
        for (i = 0; i < ARCMSR_MAX_FREESRB_NUM; i++)
        {
                srb = acb->psrb_pool[i];
-               if (srb->startdone == ARCMSR_SRB_START)
+               if (srb->srb_state == ARCMSR_SRB_START)
                {
                if((target == srb->pccb->ccb_h.target_id) && (lun == srb->pccb->ccb_h.target_lun))
             {
-                       srb->startdone = ARCMSR_SRB_ABORTED;
+                       srb->srb_state = ARCMSR_SRB_ABORTED;
                                srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
                        arcmsr_srb_complete(srb, 1);
+                               kprintf("arcmsr%d: abort scsi id %d lun %d srb=%p \n", acb->pci_unit, target, lun, srb);
                }
                }
        }
@@ -1387,7 +1446,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
                         }
                         else
                         {/* unit arrived */
-                                                       kprintf("arcmsr_dr_handle: Target=%x, lun=%x, ARRIVING!!!\n",target,lun);
+                                                       kprintf("arcmsr_dr_handle: Target=%x, lun=%x, Plug-IN!!!\n",target,lun);
                                arcmsr_rescan_lun(acb, target, lun);
                                                acb->devstate[target][lun] = ARECA_RAID_GOOD;
                         }
@@ -1940,12 +1999,36 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
 **************************************************************************
 **************************************************************************
 */
+static void arcmsr_free_srb(struct CommandControlBlock *srb)
+{
+       struct AdapterControlBlock      *acb;
+       int     mutex;
+
+       acb = srb->acb;
+       mutex = lockstatus(&acb->qbuffer_lock, curthread);
+       if( mutex == 0 )
+               ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
+       srb->srb_state=ARCMSR_SRB_DONE;
+       srb->srb_flags=0;
+       acb->srbworkingQ[acb->workingsrb_doneindex]=srb;
+       acb->workingsrb_doneindex++;
+       acb->workingsrb_doneindex %= ARCMSR_MAX_FREESRB_NUM;
+       if( mutex == 0 )
+               ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+}
+/*
+**************************************************************************
+**************************************************************************
+*/
 struct CommandControlBlock * arcmsr_get_freesrb(struct AdapterControlBlock *acb)
 {
        struct CommandControlBlock *srb=NULL;
        u_int32_t workingsrb_startindex, workingsrb_doneindex;
+       int     mutex;
 
-       ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
+       mutex = lockstatus(&acb->qbuffer_lock, curthread);
+       if( mutex == 0 )
+               ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
        workingsrb_doneindex=acb->workingsrb_doneindex;
        workingsrb_startindex=acb->workingsrb_startindex;
        srb=acb->srbworkingQ[workingsrb_startindex];
@@ -1956,7 +2039,8 @@ struct CommandControlBlock * arcmsr_get_freesrb(struct AdapterControlBlock *acb)
        } else {
                srb=NULL;
        }
-       ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+       if( mutex == 0 )
+               ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
        return(srb);
 }
 /*
@@ -2172,6 +2256,9 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg,
        pccb=srb->pccb;
        target=pccb->ccb_h.target_id;
        lun=pccb->ccb_h.target_lun;
+#ifdef ARCMSR_DEBUG1
+       acb->pktRequestCount++;
+#endif
        if(error != 0) {
                if(error != EFBIG) {
                        kprintf("arcmsr%d: unexpected error %x"
@@ -2196,13 +2283,14 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg,
                return;
        }
        if(acb->devstate[target][lun]==ARECA_RAID_GONE) {
-               u_int8_t block_cmd;
+               u_int8_t block_cmd, cmd;
 
-               block_cmd=pccb->csio.cdb_io.cdb_bytes[0] & 0x0f;
+               cmd = pccb->csio.cdb_io.cdb_bytes[0];
+               block_cmd= cmd & 0x0f;
                if(block_cmd==0x08 || block_cmd==0x0a) {
                        kprintf("arcmsr%d:block 'read/write' command "
-                               "with gone raid volume Cmd=%2x, TargetId=%d, Lun=%d \n"
-                               , acb->pci_unit, block_cmd, target, lun);
+                               "with gone raid volume Cmd=0x%2x, TargetId=%d, Lun=%d \n"
+                               , acb->pci_unit, cmd, target, lun);
                        pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
                        arcmsr_srb_complete(srb, 0);
                        return;
@@ -2224,10 +2312,13 @@ static void arcmsr_execute_srb(void *arg, bus_dma_segment_t *dm_segs, int nseg,
        }
        pccb->ccb_h.status |= CAM_SIM_QUEUED;
        arcmsr_build_srb(srb, dm_segs, nseg);
-/*     if (pccb->ccb_h.timeout != CAM_TIME_INFINITY)
-               callout_reset(&srb->ccb_callout, (pccb->ccb_h.timeout * hz) / 1000, arcmsr_srb_timeout, srb);
-*/
        arcmsr_post_srb(acb, srb);
+       if (pccb->ccb_h.timeout != CAM_TIME_INFINITY)
+       {
+               arcmsr_callout_init(&srb->ccb_callout);
+               callout_reset(&srb->ccb_callout, (pccb->ccb_h.timeout * hz ) / 1000, arcmsr_srb_timeout, srb);
+               srb->srb_flags |= SRB_FLAG_TIMER_START;
+       }
        return;
 }
 /*
@@ -2252,28 +2343,28 @@ static u_int8_t arcmsr_seek_cmd2abort(union ccb * abortccb)
        ***************************************************************************
        */
        if(acb->srboutstandingcount!=0) {
+               /* disable all outbound interrupt */
+               intmask_org=arcmsr_disable_allintr(acb);
                for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++) {
                        srb=acb->psrb_pool[i];
-                       if(srb->startdone==ARCMSR_SRB_START) {
+                       if(srb->srb_state==ARCMSR_SRB_START) {
                                if(srb->pccb==abortccb) {
-                                       srb->startdone=ARCMSR_SRB_ABORTED;
+                                       srb->srb_state=ARCMSR_SRB_ABORTED;
                                        kprintf("arcmsr%d:scsi id=%d lun=%d abort srb '%p'"
                                                "outstanding command \n"
                                                , acb->pci_unit, abortccb->ccb_h.target_id
                                                , abortccb->ccb_h.target_lun, srb);
-                                       goto abort_outstanding_cmd;
+                                       arcmsr_polling_srbdone(acb, srb);
+                                       /* enable outbound Post Queue, outbound doorbell Interrupt */
+                                       arcmsr_enable_allintr(acb, intmask_org);
+                                       return (TRUE);
                                }
                        }
                }
+               /* enable outbound Post Queue, outbound doorbell Interrupt */
+               arcmsr_enable_allintr(acb, intmask_org);
        }
        return(FALSE);
-abort_outstanding_cmd:
-       /* disable all outbound interrupt */
-       intmask_org=arcmsr_disable_allintr(acb);
-       arcmsr_polling_srbdone(acb, srb);
-       /* enable outbound Post Queue, outbound doorbell Interrupt */
-       arcmsr_enable_allintr(acb, intmask_org);
-       return (TRUE);
 }
 /*
 ****************************************************************************
@@ -2682,8 +2773,8 @@ polling_ccb_retry:
                        (acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
         error=(flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
                poll_srb_done = (srb==poll_srb) ? 1:0;
-               if((srb->acb!=acb) || (srb->startdone!=ARCMSR_SRB_START)) {
-                       if(srb->startdone==ARCMSR_SRB_ABORTED) {
+               if((srb->acb!=acb) || (srb->srb_state!=ARCMSR_SRB_START)) {
+                       if(srb->srb_state==ARCMSR_SRB_ABORTED) {
                                kprintf("arcmsr%d: scsi id=%d lun=%d srb='%p'"
                                        "poll command abort successfully \n"
                                        , acb->pci_unit
@@ -2743,8 +2834,8 @@ polling_ccb_retry:
                        (acb->vir2phy_offset+(flag_srb << 5));/*frame must be 32 bytes aligned*/
         error=(flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE0)?TRUE:FALSE;
                poll_srb_done = (srb==poll_srb) ? 1:0;
-               if((srb->acb!=acb) || (srb->startdone!=ARCMSR_SRB_START)) {
-                       if(srb->startdone==ARCMSR_SRB_ABORTED) {
+               if((srb->acb!=acb) || (srb->srb_state!=ARCMSR_SRB_START)) {
+                       if(srb->srb_state==ARCMSR_SRB_ABORTED) {
                                kprintf("arcmsr%d: scsi id=%d lun=%d srb='%p'"
                                        "poll command abort successfully \n"
                                        , acb->pci_unit
@@ -2795,12 +2886,12 @@ polling_ccb_retry:
                }
                flag_srb = CHIP_REG_READ32(HBC_MessageUnit, 0, outbound_queueport_low);
                /* check if command done with no error*/
-               srb=(struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFF0));/*frame must be 32 bytes aligned*/
+               srb=(struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0));/*frame must be 32 bytes aligned*/
         error=(flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1)?TRUE:FALSE;
                if (poll_srb != NULL)
                        poll_srb_done = (srb==poll_srb) ? 1:0;
-               if((srb->acb!=acb) || (srb->startdone!=ARCMSR_SRB_START)) {
-                       if(srb->startdone==ARCMSR_SRB_ABORTED) {
+               if((srb->acb!=acb) || (srb->srb_state!=ARCMSR_SRB_START)) {
+                       if(srb->srb_state==ARCMSR_SRB_ABORTED) {
                                kprintf("arcmsr%d: scsi id=%d lun=%d srb='%p'poll command abort successfully \n"
                                                , acb->pci_unit, srb->pccb->ccb_h.target_id, srb->pccb->ccb_h.target_lun, srb);
                                srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
@@ -3131,7 +3222,7 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
                                kprintf( "arcmsr%d: 'set window of post command Q' timeout\n", acb->pci_unit);
                                return FALSE;
                        }
-                       post_queue_phyaddr = srb_phyaddr + ARCMSR_MAX_FREESRB_NUM*sizeof(struct CommandControlBlock)
+                       post_queue_phyaddr = srb_phyaddr + ARCMSR_SRBS_POOL_SIZE
                        + offsetof(struct HBB_MessageUnit, post_qbuffer);
                        CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG); /* driver "set config" signature */
                        CHIP_REG_WRITE32(HBB_RWBUFFER, 1, msgcode_rwbuffer[1], srb_phyaddr_hi32); /* normal should be zero */
@@ -3238,8 +3329,8 @@ static void arcmsr_map_free_srb(void *arg, bus_dma_segment_t *segs, int nseg, in
                srb_tmp->cdb_shifted_phyaddr=(acb->adapter_type==ACB_ADAPTER_TYPE_C)?srb_phyaddr:(srb_phyaddr >> 5);
                srb_tmp->acb=acb;
                acb->srbworkingQ[i]=acb->psrb_pool[i]=srb_tmp;
-               srb_phyaddr=srb_phyaddr+sizeof(struct CommandControlBlock);
-               srb_tmp++;
+               srb_phyaddr=srb_phyaddr+SRB_SIZE;
+               srb_tmp = (struct CommandControlBlock *)((unsigned long)srb_tmp+SRB_SIZE);
        }
        acb->vir2phy_offset=(unsigned long)srb_tmp-(unsigned long)srb_phyaddr;
        return;
@@ -3450,7 +3541,8 @@ static u_int32_t arcmsr_initialize(device_t dev)
                                acb->bhandle[i]=rman_get_bushandle(acb->sys_res_arcmsr[i]);
                        }
                        freesrb=(struct CommandControlBlock *)acb->uncacheptr;
-                       acb->pmu=(struct MessageUnit_UNION *)&freesrb[ARCMSR_MAX_FREESRB_NUM];
+//                     acb->pmu=(struct MessageUnit_UNION *)&freesrb[ARCMSR_MAX_FREESRB_NUM];
+                       acb->pmu=(struct MessageUnit_UNION *)((unsigned long)freesrb+ARCMSR_SRBS_POOL_SIZE);
                        phbbmu=(struct HBB_MessageUnit *)acb->pmu;
                        phbbmu->hbb_doorbell=(struct HBB_DOORBELL *)mem_base[0];
                        phbbmu->hbb_rwbuffer=(struct HBB_RWBUFFER *)mem_base[1];
@@ -3607,10 +3699,11 @@ static int arcmsr_attach(device_t dev)
 
        acb->ioctl_dev->si_drv1=acb;
        (void)make_dev_alias(acb->ioctl_dev, "arc%d", unit);
-       callout_init(&acb->devmap_callout);
+       arcmsr_callout_init(&acb->devmap_callout);
        callout_reset(&acb->devmap_callout, 60 * hz, arcmsr_polling_devmap, acb);
        return 0;
 }
+
 /*
 ************************************************************************
 ************************************************************************
@@ -3694,16 +3787,20 @@ static int arcmsr_shutdown(device_t dev)
                arcmsr_abort_allcmd(acb);
                for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++) {
                        srb=acb->psrb_pool[i];
-                       if(srb->startdone==ARCMSR_SRB_START) {
-                               srb->startdone=ARCMSR_SRB_ABORTED;
+                       if(srb->srb_state==ARCMSR_SRB_START) {
+                               srb->srb_state=ARCMSR_SRB_ABORTED;
                                srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
                                arcmsr_srb_complete(srb, 1);
                        }
                }
        }
-       atomic_set_int(&acb->srboutstandingcount, 0);
+       acb->srboutstandingcount=0;
        acb->workingsrb_doneindex=0;
        acb->workingsrb_startindex=0;
+#ifdef ARCMSR_DEBUG1
+       acb->pktRequestCount = 0;
+       acb->pktReturnCount = 0;
+#endif
        ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
        return (0);
 }
@@ -3735,3 +3832,15 @@ static int arcmsr_detach(device_t dev)
        ARCMSR_LOCK_DESTROY(&acb->qbuffer_lock);
        return (0);
 }
+
+#ifdef ARCMSR_DEBUG1
+static void arcmsr_dump_data(struct AdapterControlBlock *acb)
+{
+       if((acb->pktRequestCount - acb->pktReturnCount) == 0)
+               return;
+       printf("Command Request Count   =0x%x\n",acb->pktRequestCount);
+       printf("Command Return Count    =0x%x\n",acb->pktReturnCount);
+       printf("Command (Req-Rtn) Count =0x%x\n",(acb->pktRequestCount - acb->pktReturnCount));
+       printf("Queued Command Count    =0x%x\n",acb->srboutstandingcount);
+}
+#endif
index 6b99853..e3612fa 100644 (file)
@@ -35,7 +35,7 @@
 **(INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF
 ** THIS SOFTWARE,EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 **************************************************************************
-* $FreeBSD: src/sys/dev/arcmsr/arcmsr.h,v 1.8 2010/11/13 08:58:36 delphij Exp $
+* $FreeBSD: src/sys/dev/arcmsr/arcmsr.h,v 1.9 2011/04/06 20:54:26 delphij Exp $
 */
 
 #include <sys/ioccom.h>
@@ -49,7 +49,7 @@
 #define ARCMSR_MAX_OUTSTANDING_CMD                                            256
 #define ARCMSR_MAX_START_JOB                                                  257
 #define ARCMSR_MAX_CMD_PERLUN                          ARCMSR_MAX_OUTSTANDING_CMD
-#define ARCMSR_MAX_FREESRB_NUM                                                320
+#define ARCMSR_MAX_FREESRB_NUM                         384
 #define ARCMSR_MAX_QBUFFER                                                   4096 /* ioctl QBUFFER */
 #define ARCMSR_MAX_SG_ENTRIES                                                  38 /* max 38*/
 #define ARCMSR_MAX_ADAPTER                                                      4
@@ -717,23 +717,13 @@ struct CommandControlBlock {
        u_int32_t                                       cdb_shifted_phyaddr;     /* 504-507 */
        u_int32_t                                       arc_cdb_size;                   /* 508-511 */
        /*  ======================512+32 bytes============================  */
-#if defined(__x86_64__) || defined(__amd64__) || defined(__ia64__) || defined(__sparc64__) || defined(__powerpc__)
        union ccb                                       *pccb;                                  /* 512-515 516-519 pointer of freebsd scsi command */
        struct AdapterControlBlock      *acb;                                   /* 520-523 524-527 */
                bus_dmamap_t                            dm_segs_dmamap;          /* 528-531 532-535 */
                u_int16_t                               srb_flags;               /* 536-537 */
-               u_int16_t                               startdone;                /* 538-539 */
-           u_int32_t                                   reserved2;                /* 540-543 */
-#else
-       union ccb                                       *pccb;                    /* 512-515 pointer of freebsd scsi command */
-       struct AdapterControlBlock      *acb;                     /* 516-519 */
-               bus_dmamap_t                            dm_segs_dmamap;           /* 520-523 */
-               u_int16_t                               srb_flags;                /* 524-525 */
-               u_int16_t                               startdone;                /* 526-527 */
-               u_int32_t                               reserved2[4];             /* 528-531 532-535 536-539 540-543 */
-#endif
+       u_int16_t                                       srb_state;                /* 538-539 */
+       struct  callout                         ccb_callout;
     /*  ==========================================================  */
-/*     struct  callout                         ccb_callout; */
 };
 /*     srb_flags */
 #define                SRB_FLAG_READ                           0x0000
@@ -745,7 +735,8 @@ struct CommandControlBlock {
 #define                SRB_FLAG_DMACONSISTENT          0x0020
 #define                SRB_FLAG_DMAWRITE                       0x0040
 #define                SRB_FLAG_PKTBIND                        0x0080
-/*     startdone */
+#define                SRB_FLAG_TIMER_START            0x0080
+/*     srb_state */
 #define                ARCMSR_SRB_DONE                         0x0000
 #define                ARCMSR_SRB_UNBUILD                      0x0000
 #define                ARCMSR_SRB_TIMEOUT                      0x1111
@@ -775,18 +766,18 @@ struct AdapterControlBlock {
        bus_dma_tag_t                                   srb_dmat;                             /* dmat for freesrb */
        bus_dmamap_t                                    srb_dmamap;
        device_t                                        pci_dev;
-       struct cdev *                                   ioctl_dev;
+       struct cdev                                     *ioctl_dev;
        int                                             pci_unit;
 
-       struct resource *                               sys_res_arcmsr[2];
-       struct resource *                               irqres;
-       void *                                          ih;                                    /* interrupt handle */
+       struct resource                         *sys_res_arcmsr[2];
+       struct resource                         *irqres;
+       void                                            *ih;                         /* interrupt handle */
        int                                             irq_type;
 
        /* Hooks into the CAM XPT */
        struct                                          cam_sim *psim;
        struct                                          cam_path *ppath;
-       u_int8_t *                                      uncacheptr;
+       u_int8_t                                        *uncacheptr;
        unsigned long                                   vir2phy_offset;
        union   {
                unsigned long                   phyaddr;
@@ -799,14 +790,14 @@ struct AdapterControlBlock {
        /* Offset is used in making arc cdb physical to virtual calculations */
        u_int32_t                                       outbound_int_enable;
 
-       struct MessageUnit_UNION *                              pmu;                                   /* message unit ATU inbound base address0 */
+       struct MessageUnit_UNION        *pmu;                        /* message unit ATU inbound base address0 */
 
        u_int8_t                                        adapter_index;                         /*  */
        u_int8_t                                        irq;
        u_int16_t                                       acb_flags;                             /*  */
 
-       struct CommandControlBlock *                    psrb_pool[ARCMSR_MAX_FREESRB_NUM];     /* serial srb pointer array */
-       struct CommandControlBlock *                    srbworkingQ[ARCMSR_MAX_FREESRB_NUM];   /* working srb pointer array */
+       struct CommandControlBlock *psrb_pool[ARCMSR_MAX_FREESRB_NUM];     /* serial srb pointer array */
+       struct CommandControlBlock *srbworkingQ[ARCMSR_MAX_FREESRB_NUM];   /* working srb pointer array */
        int32_t                                         workingsrb_doneindex;                  /* done srb array index */
        int32_t                                         workingsrb_startindex;                 /* start srb array index  */
        int32_t                                         srboutstandingcount;
@@ -835,6 +826,10 @@ struct AdapterControlBlock {
        char                                            firm_version[20];                      /*17,68-83*/
        char                                            device_map[20];                         /*21,84-99 */
        struct  callout                         devmap_callout;
+#ifdef ARCMSR_DEBUG1
+       u_int32_t                                       pktRequestCount;
+       u_int32_t                                       pktReturnCount;
+#endif
 };/* HW_DEVICE_EXTENSION */
 /* acb_flags */
 #define ACB_F_SCSISTOPADAPTER           0x0001