kernels/linux-2.4.0/drivers/scsi/cpqfcTSinit.c
// Entry point for upper Scsi layer intiated abort.  Typically
// this is called if the command (for hard disk) fails to complete
// in 30 seconds.  This driver intends to complete all disk commands
// within Exchange ".timeOut" seconds (now 7) with target status, or
// in case of ".timeOut" expiration, a DID_SOFT_ERROR which causes
// immediate retry.
// If any disk commands get the _abort call, except for the case that
// the physical device was removed or unavailable due to hardware
// errors, it should be considered a driver error and reported to
// the author.
Entry point for upper Scsi layer intiated abort.  Typically
this is called if the command (for hard disk) fails to complete
in 30 seconds.  This driver intends to complete all disk commands
within Exchange ".timeOut" seconds (now 7) with target status, or
in case of ".timeOut" expiration, a DID_SOFT_ERROR which causes
immediate retry.
If any disk commands get the _abort call, except for the case that
the physical device was removed or unavailable due to hardware
errors, it should be considered a driver error and reported to
the author.
Entry point for upper Scsi layer intiated abort . Typically this is called if the command ( for hard disk ) fails to complete in 30 seconds . This driver intends to complete all disk commands within Exchange " . timeOut " seconds ( now 7 ) with target status or in case of " . timeOut " expiration a DID_SOFT_ERROR which causes immediate retry . If any disk commands get the _abort call except for the case that the physical device was removed or unavailable due to hardware errors it should be considered a driver error and reported to the author .
int cpqfcTS_abort(Scsi_Cmnd *Cmnd)
{
  struct Scsi_Host *HostAdapter = Cmnd->host;
  CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
  PTACHYON fcChip = &cpqfcHBAdata->fcChip;
  FC_EXCHANGES *Exchanges = fcChip->Exchanges;
  int i;
  ENTER("cpqfcTS_abort");
  Cmnd->result = DID_ABORT <<16;  
  printk(" @Linux _abort Scsi_Cmnd %p ", Cmnd);
  for( i=0; i< TACH_SEST_LEN; i++)
  {
    if( Exchanges->fcExchange[i].Cmnd == Cmnd )
    {
      printk(" x_ID %Xh, type %Xh\n", i, Exchanges->fcExchange[i].type);
      Exchanges->fcExchange[i].status = INITIATOR_ABORT; 
      Exchanges->fcExchange[i].timeOut = 10;  (changed later)
      cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &i);
      break;
    }
  }
  if( i >= TACH_SEST_LEN ) 
  {
    for( i=0; i< CPQFCTS_MAX_TARGET_ID; i++)
    { 
      if( cpqfcHBAdata->BadTargetCmnd[i] == Cmnd )
      {
        cpqfcHBAdata->BadTargetCmnd[i] = NULL;
	printk("in BadTargetCmnd Q\n");
	goto Done; 
      }
    }
    for( i=0; i < CPQFCTS_REQ_QUEUE_LEN; i++)
    {
      if( cpqfcHBAdata->LinkDnCmnd[i] == Cmnd ) 
      {
	cpqfcHBAdata->LinkDnCmnd[i] = NULL;
	printk("in LinkDnCmnd Q\n");
	goto Done;
      }
    }
    for( i=0; i< CPQFCTS_REQ_QUEUE_LEN; i++)
    {    
      if( cpqfcHBAdata->BoardLockCmnd[i] == Cmnd )
      {
        cpqfcHBAdata->BoardLockCmnd[i] = NULL;
	printk("in BoardLockCmnd Q\n");
	goto Done;
      }
    }
    Cmnd->result = DID_ERROR <<16;  
    printk("Not found! ");
  }
Done:
  LEAVE("cpqfcTS_abort");
  return 0;  
}
int cpqfcTS_abort ( Scsi_Cmnd * Cmnd ) { struct Scsi_Host * HostAdapter = Cmnd -> host ; CPQFCHBA * cpqfcHBAdata = ( CPQFCHBA * ) HostAdapter -> hostdata ; PTACHYON fcChip = & cpqfcHBAdata -> fcChip ; FC_EXCHANGES * Exchanges = fcChip -> Exchanges ; int i ; ENTER ( " " ) ; Cmnd -> result = DID_ABORT << 16 ; printk ( " " , Cmnd ) ; for ( i = 0 ; i < TACH_SEST_LEN ; i ++ ) { if ( Exchanges -> fcExchange [ i ] . Cmnd == Cmnd ) { printk ( " \n " , i , Exchanges -> fcExchange [ i ] . type ) ; Exchanges -> fcExchange [ i ] . status = INITIATOR_ABORT ; Exchanges -> fcExchange [ i ] . timeOut = 10 ; cpqfcTSPutLinkQue ( cpqfcHBAdata , BLS_ABTS , & i ) ; break ; } } if ( i >= TACH_SEST_LEN ) { for ( i = 0 ; i < CPQFCTS_MAX_TARGET_ID ; i ++ ) { if ( cpqfcHBAdata -> BadTargetCmnd [ i ] == Cmnd ) { cpqfcHBAdata -> BadTargetCmnd [ i ] = NULL ; printk ( " \n " ) ; goto Done ; } } for ( i = 0 ; i < CPQFCTS_REQ_QUEUE_LEN ; i ++ ) { if ( cpqfcHBAdata -> LinkDnCmnd [ i ] == Cmnd ) { cpqfcHBAdata -> LinkDnCmnd [ i ] = NULL ; printk ( " \n " ) ; goto Done ; } } for ( i = 0 ; i < CPQFCTS_REQ_QUEUE_LEN ; i ++ ) { if ( cpqfcHBAdata -> BoardLockCmnd [ i ] == Cmnd ) { cpqfcHBAdata -> BoardLockCmnd [ i ] = NULL ; printk ( " \n " ) ; goto Done ; } } Cmnd -> result = DID_ERROR << 16 ; printk ( " " ) ; } Done : LEAVE ( " " ) ; return 0 ; }
Entry point for upper Scsi layer intiated abort.
Entry point for upper Scsi layer intiated abort .
// get the pointer to our Scsi layer HBA buffer   // assume we'll find it // See if we can find a Cmnd pointer that matches... // The most likely case is we accepted the command // from Linux Scsi (e.g. ceated a SEST entry) and it // got lost somehow.  If we can't find any reference // to the passed pointer, we can only presume it // got completed as far as our driver is concerned. // If we found it, we will try to abort it through // common mechanism.  If FC ABTS is successful (ACC) // or is rejected (RJT) by target, we will call // Scsi "done" quickly.  Otherwise, the ABTS will timeout // and we'll call "done" later. // Search the SEST exchanges for a matching Cmnd ptr. // found it! // seconds default // seconds default (changed later) // Since we need to immediately return the aborted Cmnd to Scsi  // upper layers, we can't make future reference to any of it's  // fields (e.g the Nexus). // didn't find Cmnd ptr in chip's SEST? // now search our non-SEST buffers (i.e. Cmnd waiting to // start on the HBA or waiting to complete with error for retry). // first check BadTargetCmnd // exit // if not found above... // find spare slot // Hmmm... //    panic("_abort"); //    panic("_abort"); // (see scsi.h)