FreeBSD/sys/dev/pms/freebsd/driver/ini/src/agtiapi.c
/*****************************************************************************
agtiapi_ResetCard()

Purpose:
  Hard or soft reset on the controller and resend any
  outstanding requests if needed.
Parameters:
  struct agtiapi_softc *pCard (IN)  Pointer to HBA data structure
  unsigned lomg flags (IN/OUT) Flags used in locking done from calling layers
Return:
  AGTIAPI_SUCCESS - reset successful
  AGTIAPI_FAIL    - reset failed
Note:
*****************************************************************************/
agtiapi_ResetCard()
Purpose:
Hard or soft reset on the controller and resend any
outstanding requests if needed.
Parameters:
struct agtiapi_softc *pCard (IN)  Pointer to HBA data structure
unsigned lomg flags (IN/OUT) Flags used in locking done from calling layers
Return:
AGTIAPI_SUCCESS - reset successful
AGTIAPI_FAIL    - reset failed
Note.
agtiapi_ResetCard () Purpose : Hard or soft reset on the controller and resend any outstanding requests if needed . Parameters : struct agtiapi_softc * pCard ( IN ) Pointer to HBA data structure unsigned lomg flags ( IN / OUT ) Flags used in locking done from calling layers Return : AGTIAPI_SUCCESS - reset successful AGTIAPI_FAIL - reset failed Note .
U32 agtiapi_ResetCard( struct agtiapi_softc *pCard, unsigned long *flags )
{
  ag_device_t      *pDevice;
  U32               lIdx = 0;
  U32               lFlagVal;
  agBOOLEAN         ret;
  ag_portal_info_t *pPortalInfo;
  ag_portal_data_t *pPortalData;
  U32               count, loop;
  int               szdv;
  if( pCard->flags & AGTIAPI_RESET ) {
    AGTIAPI_PRINTK( "agtiapi_ResetCard: reset card already in progress!\n" );
    return AGTIAPI_FAIL;
  }
  AGTIAPI_PRINTK( "agtiapi_ResetCard: Enter cnt %d\n",
                  pCard->resetCount );
#ifdef LOGEVENT
  agtiapi_LogEvent( pCard,
                    IOCTL_EVT_SEV_INFORMATIONAL,
                    0,
                    agNULL,
                    0,
                    "Reset initiator time = %d!",
                    pCard->resetCount + 1 );
#endif
  pCard->flags |= AGTIAPI_RESET;
  pCard->flags &= ~(AGTIAPI_CB_DONE | AGTIAPI_RESET_SUCCESS);
  tiCOMSystemInterruptsActive( &pCard->tiRoot, FALSE );
  pCard->flags &= ~AGTIAPI_SYS_INTR_ON;
  agtiapi_FlushCCBs( pCard, AGTIAPI_CALLBACK );
  for ( lIdx = 1; 3 >= lIdx; lIdx++ ) 
  {
    if( pCard->flags & AGTIAPI_SOFT_RESET )
    {
      AGTIAPI_PRINTK( "agtiapi_ResetCard: soft variant\n" );
      tiCOMReset( &pCard->tiRoot, tiSoftReset );
    }
    else
    {
      AGTIAPI_PRINTK( "agtiapi_ResetCard: no flag, no reset!\n" );
    }
    lFlagVal = AGTIAPI_RESET_SUCCESS;
    AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
    ret = agtiapi_CheckCB( pCard, 50000, lFlagVal, &pCard->flags );
    AG_SPIN_LOCK_IRQ( agtiapi_host_lock, *flags );
    if( ret == AGTIAPI_FAIL )
    {
      AGTIAPI_PRINTK( "agtiapi_ResetCard: CheckCB indicates failed reset call, "
              "try again?\n" );
    }
    else
    {
      break;
    }
  }
  if ( 1 < lIdx )
  {
    if ( AGTIAPI_FAIL == ret )
    {
      AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset failed after try %d\n",
                      lIdx );
    }
    else
    {
      AGTIAPI_PRINTK( "agtiapi_ResetCard: soft reset success at try %d\n",
                      lIdx );
    }
  }
  if( AGTIAPI_FAIL == ret )
  {
    printf( "agtiapi_ResetCard: reset ERROR\n" );
    pCard->flags &= ~AGTIAPI_INSTALLED;
    return AGTIAPI_FAIL;
  }
  pCard->flags &= ~AGTIAPI_SOFT_RESET;
  pDevice = pCard->pDevList;
  for( lIdx = 0; lIdx < maxTargets; lIdx++, pDevice++ )
  {
    pDevice->flags &= ~ACTIVE;
  }
  AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, *flags );
  if( tiCOMPortInit( &pCard->tiRoot, agFALSE ) != tiSuccess )
    printf( "agtiapi_ResetCard: tiCOMPortInit FAILED \n" );
  else
    AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortInit success\n" );
  if( !pCard->pDevList ) {  
    AGTIAPI_PRINTK( "agtiapi_ResetCard: no pDevList ERROR %p\n",
                    pCard->pDevList );
    return AGTIAPI_FAIL;
  }
  AGTIAPI_PRINTK( "agtiapi_ResetCard: pre target-count %d port-count %d\n",
                  pCard->tgtCount, pCard->portCount );
  pCard->tgtCount = 0;
  DELAY( 500000 );
  pCard->flags &= ~AGTIAPI_CB_DONE;
  pPortalData = pCard->pPortalData;
  for( count = 0; count < pCard->portCount; count++ ) {
    AG_SPIN_LOCK_IRQ( agtiapi_host_lock, flags );
    pPortalInfo = &pPortalData->portalInfo;
    pPortalInfo->portStatus = 0;
    pPortalInfo->portStatus &= ~( AGTIAPI_PORT_START      |
                                  AGTIAPI_PORT_DISC_READY |
                                  AGTIAPI_DISC_DONE       |
                                  AGTIAPI_DISC_COMPLETE );
    szdv =
      sizeof( pPortalInfo->pDevList ) / sizeof( pPortalInfo->pDevList[0] );
    if (szdv > pCard->devDiscover)
    {
      szdv = pCard->devDiscover;
    }
    for( lIdx = 0, loop = 0;
         lIdx < szdv  &&  loop < pPortalInfo->devTotal;
         lIdx++ )
    {
      pDevice = (ag_device_t*)pPortalInfo->pDevList[lIdx];
      if( pDevice )
      {
        loop++;
        pDevice->pDevHandle = 0; 
      }
      AGTIAPI_PRINTK( "agtiapi_ResetCard: reset pDev %p pDevList %p idx %d\n",
                      pDevice, pPortalInfo->pDevList, lIdx );
      pPortalInfo->devTotal = pPortalInfo->devPrev = 0;
    }
    for( lIdx = 0; lIdx < maxTargets; lIdx++ )
    { 
      pPortalInfo->pDevList[lIdx] = NULL;
    }
    for( loop = 0; loop < AGTIAPI_LOOP_MAX; loop++ )
    {
      AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart entry data "
                      "%p / %d / %p\n",
                      &pCard->tiRoot,
                      pPortalInfo->portID,
                      &pPortalInfo->tiPortalContext );
      if( tiCOMPortStart( &pCard->tiRoot,
                          pPortalInfo->portID,
                          &pPortalInfo->tiPortalContext,
                          0 )
          != tiSuccess )
      {
        printf( "agtiapi_ResetCard: tiCOMPortStart %d FAILED\n",
                pPortalInfo->portID );
      }
      else
      {
        AGTIAPI_PRINTK( "agtiapi_ResetCard: tiCOMPortStart %d success\n",
                        pPortalInfo->portID );
        break;
      }
    }
    AG_SPIN_UNLOCK_IRQ( agtiapi_host_lock, flags );
    tiCOMGetPortInfo( &pCard->tiRoot,
                      &pPortalInfo->tiPortalContext,
                      &pPortalInfo->tiPortInfo );
    pPortalData++;
  }
  AG_SPIN_LOCK_IRQ(agtiapi_host_lock, *flags);
  if( !(pCard->flags & AGTIAPI_INSTALLED) ) 
  {
    printf( "agtiapi_ResetCard: error, driver not intstalled? "
            "!AGTIAPI_INSTALLED \n" );
    return AGTIAPI_FAIL;
  }
  AGTIAPI_PRINTK( "agtiapi_ResetCard: total device %d\n", pCard->tgtCount );
#ifdef LOGEVENT
  agtiapi_LogEvent( pCard,
                    IOCTL_EVT_SEV_INFORMATIONAL,
                    0,
                    agNULL,
                    0,
                    "Reset initiator total device = %d!",
                    pCard->tgtCount );
#endif
  pCard->resetCount++;
  AGTIAPI_PRINTK( "agtiapi_ResetCard: clear send and done queues\n" );
  AG_LOCAL_LOCK( &pCard->sendLock );
  pCard->ccbSendHead = NULL;
  pCard->ccbSendTail = NULL;
  AG_LOCAL_UNLOCK( &pCard->sendLock );
  AG_LOCAL_LOCK( &pCard->doneLock );
  pCard->ccbDoneHead = NULL;
  pCard->ccbDoneTail = NULL;
  AG_LOCAL_UNLOCK( &pCard->doneLock );
  AG_LOCAL_LOCK( &pCard->sendSMPLock );
  pCard->smpSendHead = NULL;
  pCard->smpSendTail = NULL;
  AG_LOCAL_UNLOCK( &pCard->sendSMPLock );
  AG_LOCAL_LOCK( &pCard->doneSMPLock );
  pCard->smpDoneHead = NULL;
  pCard->smpDoneTail = NULL;
  AG_LOCAL_UNLOCK( &pCard->doneSMPLock );
  tiCOMSystemInterruptsActive( &pCard->tiRoot, TRUE );
  pCard->flags |= AGTIAPI_SYS_INTR_ON;
  pCard->flags |= AGTIAPI_HAD_RESET;
  pCard->flags &= ~AGTIAPI_RESET;  
  agtiapi_StartIO( pCard );
  AGTIAPI_PRINTK( "agtiapi_ResetCard: local return success\n" );
  return AGTIAPI_SUCCESS;
}
U32 agtiapi_ResetCard ( struct agtiapi_softc * pCard , unsigned long * flags ) { ag_device_t * pDevice ; U32 lIdx = 0 ; U32 lFlagVal ; agBOOLEAN ret ; ag_portal_info_t * pPortalInfo ; ag_portal_data_t * pPortalData ; U32 count , loop ; int szdv ; if ( pCard -> flags & AGTIAPI_RESET ) { AGTIAPI_PRINTK ( " \n " ) ; return AGTIAPI_FAIL ; } AGTIAPI_PRINTK ( " \n " , pCard -> resetCount ) ; #ifdef LOGEVENT agtiapi_LogEvent ( pCard , IOCTL_EVT_SEV_INFORMATIONAL , 0 , agNULL , 0 , " " , pCard -> resetCount + 1 ) ; #endif pCard -> flags |= AGTIAPI_RESET ; pCard -> flags &= ~ ( AGTIAPI_CB_DONE | AGTIAPI_RESET_SUCCESS ) ; tiCOMSystemInterruptsActive ( & pCard -> tiRoot , FALSE ) ; pCard -> flags &= ~ AGTIAPI_SYS_INTR_ON ; agtiapi_FlushCCBs ( pCard , AGTIAPI_CALLBACK ) ; for ( lIdx = 1 ; 3 >= lIdx ; lIdx ++ ) { if ( pCard -> flags & AGTIAPI_SOFT_RESET ) { AGTIAPI_PRINTK ( " \n " ) ; tiCOMReset ( & pCard -> tiRoot , tiSoftReset ) ; } else { AGTIAPI_PRINTK ( " \n " ) ; } lFlagVal = AGTIAPI_RESET_SUCCESS ; AG_SPIN_UNLOCK_IRQ ( agtiapi_host_lock , * flags ) ; ret = agtiapi_CheckCB ( pCard , 50000 , lFlagVal , & pCard -> flags ) ; AG_SPIN_LOCK_IRQ ( agtiapi_host_lock , * flags ) ; if ( ret == AGTIAPI_FAIL ) { AGTIAPI_PRINTK ( " " " \n " ) ; } else { break ; } } if ( 1 < lIdx ) { if ( AGTIAPI_FAIL == ret ) { AGTIAPI_PRINTK ( " \n " , lIdx ) ; } else { AGTIAPI_PRINTK ( " \n " , lIdx ) ; } } if ( AGTIAPI_FAIL == ret ) { printf ( " \n " ) ; pCard -> flags &= ~ AGTIAPI_INSTALLED ; return AGTIAPI_FAIL ; } pCard -> flags &= ~ AGTIAPI_SOFT_RESET ; pDevice = pCard -> pDevList ; for ( lIdx = 0 ; lIdx < maxTargets ; lIdx ++ , pDevice ++ ) { pDevice -> flags &= ~ ACTIVE ; } AG_SPIN_UNLOCK_IRQ ( agtiapi_host_lock , * flags ) ; if ( tiCOMPortInit ( & pCard -> tiRoot , agFALSE ) != tiSuccess ) printf ( " \n " ) ; else AGTIAPI_PRINTK ( " \n " ) ; if ( ! pCard -> pDevList ) { AGTIAPI_PRINTK ( " \n " , pCard -> pDevList ) ; return AGTIAPI_FAIL ; } AGTIAPI_PRINTK ( " \n " , pCard -> tgtCount , pCard -> portCount ) ; pCard -> tgtCount = 0 ; DELAY ( 500000 ) ; pCard -> flags &= ~ AGTIAPI_CB_DONE ; pPortalData = pCard -> pPortalData ; for ( count = 0 ; count < pCard -> portCount ; count ++ ) { AG_SPIN_LOCK_IRQ ( agtiapi_host_lock , flags ) ; pPortalInfo = & pPortalData -> portalInfo ; pPortalInfo -> portStatus = 0 ; pPortalInfo -> portStatus &= ~ ( AGTIAPI_PORT_START | AGTIAPI_PORT_DISC_READY | AGTIAPI_DISC_DONE | AGTIAPI_DISC_COMPLETE ) ; szdv = sizeof ( pPortalInfo -> pDevList ) / sizeof ( pPortalInfo -> pDevList [ 0 ] ) ; if ( szdv > pCard -> devDiscover ) { szdv = pCard -> devDiscover ; } for ( lIdx = 0 , loop = 0 ; lIdx < szdv && loop < pPortalInfo -> devTotal ; lIdx ++ ) { pDevice = ( ag_device_t * ) pPortalInfo -> pDevList [ lIdx ] ; if ( pDevice ) { loop ++ ; pDevice -> pDevHandle = 0 ; } AGTIAPI_PRINTK ( " \n " , pDevice , pPortalInfo -> pDevList , lIdx ) ; pPortalInfo -> devTotal = pPortalInfo -> devPrev = 0 ; } for ( lIdx = 0 ; lIdx < maxTargets ; lIdx ++ ) { pPortalInfo -> pDevList [ lIdx ] = NULL ; } for ( loop = 0 ; loop < AGTIAPI_LOOP_MAX ; loop ++ ) { AGTIAPI_PRINTK ( " " " \n " , & pCard -> tiRoot , pPortalInfo -> portID , & pPortalInfo -> tiPortalContext ) ; if ( tiCOMPortStart ( & pCard -> tiRoot , pPortalInfo -> portID , & pPortalInfo -> tiPortalContext , 0 ) != tiSuccess ) { printf ( " \n " , pPortalInfo -> portID ) ; } else { AGTIAPI_PRINTK ( " \n " , pPortalInfo -> portID ) ; break ; } } AG_SPIN_UNLOCK_IRQ ( agtiapi_host_lock , flags ) ; tiCOMGetPortInfo ( & pCard -> tiRoot , & pPortalInfo -> tiPortalContext , & pPortalInfo -> tiPortInfo ) ; pPortalData ++ ; } AG_SPIN_LOCK_IRQ ( agtiapi_host_lock , * flags ) ; if ( ! ( pCard -> flags & AGTIAPI_INSTALLED ) ) { printf ( " " " \n " ) ; return AGTIAPI_FAIL ; } AGTIAPI_PRINTK ( " \n " , pCard -> tgtCount ) ; #ifdef LOGEVENT agtiapi_LogEvent ( pCard , IOCTL_EVT_SEV_INFORMATIONAL , 0 , agNULL , 0 , " " , pCard -> tgtCount ) ; #endif pCard -> resetCount ++ ; AGTIAPI_PRINTK ( " \n " ) ; AG_LOCAL_LOCK ( & pCard -> sendLock ) ; pCard -> ccbSendHead = NULL ; pCard -> ccbSendTail = NULL ; AG_LOCAL_UNLOCK ( & pCard -> sendLock ) ; AG_LOCAL_LOCK ( & pCard -> doneLock ) ; pCard -> ccbDoneHead = NULL ; pCard -> ccbDoneTail = NULL ; AG_LOCAL_UNLOCK ( & pCard -> doneLock ) ; AG_LOCAL_LOCK ( & pCard -> sendSMPLock ) ; pCard -> smpSendHead = NULL ; pCard -> smpSendTail = NULL ; AG_LOCAL_UNLOCK ( & pCard -> sendSMPLock ) ; AG_LOCAL_LOCK ( & pCard -> doneSMPLock ) ; pCard -> smpDoneHead = NULL ; pCard -> smpDoneTail = NULL ; AG_LOCAL_UNLOCK ( & pCard -> doneSMPLock ) ; tiCOMSystemInterruptsActive ( & pCard -> tiRoot , TRUE ) ; pCard -> flags |= AGTIAPI_SYS_INTR_ON ; pCard -> flags |= AGTIAPI_HAD_RESET ; pCard -> flags &= ~ AGTIAPI_RESET ; agtiapi_StartIO ( pCard ) ; AGTIAPI_PRINTK ( " \n " ) ; return AGTIAPI_SUCCESS ; }
agtiapi_ResetCard()
Purpose:
Hard or soft reset on the controller and resend any
outstanding requests if needed.
agtiapi_ResetCard () Purpose : Hard or soft reset on the controller and resend any outstanding requests if needed .
// we try reset up to 3 times // disable all devices /* if ( pDevice->flags & ACTIVE )
    {
      printf( "agtiapi_ResetCard: before ... active device %d\n", lIdx );
    } */ // try to get a little sanity here // mark for availability in pCard->pDevList[] // don't erase more as the device is scheduled for removal on DPC // we reconstruct dev list later in get dev handle // ## fail case:  pCard->flags &= ~AGTIAPI_INSTALLED; // driver not installed ! // clear send & done queue // clear smp queues also // finished with all reset stuff, now start things back up // ##