Beispiel #1
0
/*-----------------------------------------------------------------------------*
 * This routine queues an SRB to reset the SCSI Bus
 *
 *-----------------------------------------------------------------------------*/
void Sym8xxSCSIController::resetCommand( IOSCSIParallelCommand *scsiCommand )
{
    SRB			* srb;
    IOMemoryDescriptor	* iomd;

//    printf( "SCSI(Symbios8xx): resetCommand\n\r" ); 

    srb = (SRB *) scsiCommand->getCommandData();
    bzero( srb, sizeof(SRB) );

    iomd          = SCSI_IOMDs[ SCSI_RESET_IOMD ];	// special "target" for reset
    srb->srbIOMD  = iomd;		// save in SRB for later ->complete() call
    // ::initWithAddress() causes any previous contents of IOMD to be ::complete()'d
    if ( iomd->initWithAddress( srb, sizeof( SRB ), kIODirectionOutIn ) )
    {
	iomd->prepare();
	srb->srbPhys = (SRB *) iomd->getPhysicalAddress();
    }
    else
    {
	// this should never happen, as we have allocated enough
	// IOMDs for MAX_SCSI_TARGETS plus 2 extra for reset and
	// a "fudge factor" just in case.
	panic( "Sym8xxSCSIController::resetCommand - IOMemoryDescriptor reinitialization failed" );
    }

    srb->scsiCommand = scsiCommand;

    Sym8xxSCSIBusReset( srb );
}
Beispiel #2
0
/*-----------------------------------------------------------------------------*
 *
 *-----------------------------------------------------------------------------*/
void Sym8xxSCSIController::executeCommand( IOSCSIParallelCommand *scsiCommand )
{
    SRB				*srb = NULL;
    SCSICDBInfo			scsiCDB;
    SCSITargetLun               targetLun;
    Nexus                       *nexus;
    Nexus                       *nexusPhys;  
    UInt32                      len;  
    bool                        isWrite;                
    IOMemoryDescriptor		* iomd;

    srb = (SRB *) scsiCommand->getCommandData();
    bzero( srb, sizeof(SRB) );

    srb->scsiCommand = scsiCommand;

    scsiCommand->getCDB( &scsiCDB );
    scsiCommand->getTargetLun( &targetLun );
    
    srb->target      = targetLun.target;
    srb->lun         = targetLun.lun;
    srb->srbCDBFlags = scsiCDB.cdbFlags;

    // 1 IOMD per target, since only 1 transaction possible with current architecture
    iomd             = SCSI_IOMDs[(int) srb->target ];
    srb->srbIOMD     = iomd;
    // ::initWithAddress() causes any previous IOMDs to be ::complete()'d
    if ( iomd->initWithAddress( srb, sizeof( SRB ), kIODirectionOutIn ) )
    {
	iomd->prepare();
	srb->srbPhys = (SRB *) iomd->getPhysicalAddress();
    }
    else
    {
	// this should never happen, as we have allocated enough
	// IOMDs for MAX_SCSI_TARGETS plus 1 extra for reset
	panic( "Sym8xxSCSIController::executeCommand - IOMemoryDescriptor reinitialization failed" );
    }

    /*
     * Setup the Nexus struct. This part of the SRB is read/written both by the
     * script and the driver.
     */

    nexus                     = &srb->nexus;
    nexusPhys                 = &srb->srbPhys->nexus;
    nexus->targetParms.target = srb->target;

//    printf( "SCSI(Symbios8xx): executeCommand: T/L = %d:%d Cmd = %08x CmdType = %d\n\r", 
//                        targetLun.target, targetLun.lun, (int)scsiCommand, scsiCommand->getCmdType() );
    
    switch ( scsiCommand->getCmdType() )
    {
        case kSCSICommandAbort:
        case kSCSICommandAbortAll:
        case kSCSICommandDeviceReset:
            Sym8xxAbortCommand( scsiCommand );
            return;

        default:
            ;
    }
    
    /*
     * Set client data buffer pointers in the SRB
     */
    scsiCommand->getPointers( &srb->xferDesc, &srb->xferCount, &isWrite );
    
    srb->directionMask = (isWrite) ? 0x00000000 :0x01000000;    
    
    nexus->cdb.ppData = OSSwapHostToLittleInt32((UInt32)&nexusPhys->cdbData);

    len = scsiCDB.cdbLength;

    nexus->cdb.length = OSSwapHostToLittleInt32( len );
    // implicit copying of arrays is not desireable.  explicitly spell out what is being copied
    // [rdar://problem/4092008]
    // nexus->cdbData    = scsiCDB.cdb;
    bcopy( &scsiCDB.cdb, &nexus->cdbData, sizeof( nexus->cdbData ) );

    Sym8xxCalcMsgs( scsiCommand );
    
    /*
     * Setup initial data transfer list (SGList) 
     */
    nexus->ppSGList   = (SGEntry *)OSSwapHostToLittleInt32((UInt32)&nexusPhys->sgListData[2]);
    Sym8xxUpdateSGList( srb );

    Sym8xxStartSRB( srb );
}