kernels/linux-2.4.0/drivers/scsi/ips.c
/****************************************************************************/
/*                                                                          */
/* Routine Name: ips_chk_status                                             */
/*                                                                          */
/* Routine Description:                                                     */
/*                                                                          */
/*   Check the status of commands to logical drives                         */
/*                                                                          */
/****************************************************************************/


Routine Description.

Check the status of commands to logical drives
Routine Description . Check the status of commands to logical drives
static void
ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) {
   ips_scb_t  *scb;
   ips_stat_t *sp;
   u8          basic_status;
   u8          ext_status;
   int         errcode;
   METHOD_TRACE("ips_chkstatus", 1);
   scb = &ha->scbs[pstatus->fields.command_id];
   scb->basic_status = basic_status = pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK;
   scb->extended_status = ext_status = pstatus->fields.extended_status;
   sp = &ha->sp;
   sp->residue_len = 0;
   sp->scb_addr = (u32) scb;
   ips_removeq_scb(&ha->scb_activelist, scb);
   if (!scb->scsi_cmd)
      return ;
   DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)",
             ips_name,
             ha->host_num,
             scb->cdb[0],
             scb->cmd.basic_io.command_id,
             scb->bus,
             scb->target_id,
             scb->lun);
#ifndef NO_IPS_CMDLINE
   if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd)))
      return ;
#endif
   errcode = DID_OK;
   if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) ||
       ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) {
      if (scb->bus == 0) {
         if ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR) {
            DEBUG_VAR(1, "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
                      ips_name, ha->host_num,
                      scb->cmd.basic_io.op_code, basic_status, ext_status);
         }
         switch (scb->scsi_cmd->cmnd[0]) {
         case ALLOW_MEDIUM_REMOVAL:
         case REZERO_UNIT:
         case ERASE:
         case WRITE_FILEMARKS:
         case SPACE:
            errcode = DID_ERROR;
            break;
         case START_STOP:
            break;
         case TEST_UNIT_READY:
            if (!ips_online(ha, scb)) {
               errcode = DID_TIME_OUT;
            }
            break;
         case INQUIRY:
            if (ips_online(ha, scb)) {
               ips_inquiry(ha, scb);
            } else {
               errcode = DID_TIME_OUT;
            }
            break;
         case REQUEST_SENSE:
            ips_reqsen(ha, scb);
            break;
         case READ_6:
         case WRITE_6:
         case READ_10:
         case WRITE_10:
         case RESERVE:
         case RELEASE:
            break;
         case MODE_SENSE:
            if (!ips_online(ha, scb) || !ips_msense(ha, scb)) {
               errcode = DID_ERROR;
            }
            break;
         case READ_CAPACITY:
            if (ips_online(ha, scb))
               ips_rdcap(ha, scb);
            else {
               errcode = DID_TIME_OUT;
            }
            break;
         case SEND_DIAGNOSTIC:
         case REASSIGN_BLOCKS:
            break;
         case FORMAT_UNIT:
            errcode = DID_ERROR;
            break;
         case SEEK_10:
         case VERIFY:
         case READ_DEFECT_DATA:
         case READ_BUFFER:
         case WRITE_BUFFER:
            break;
         default:
            errcode = DID_ERROR;
         } 
         scb->scsi_cmd->result = errcode << 16;
      } else { 
         if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
             ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == TYPE_DISK)) {
            scb->scsi_cmd->result = DID_TIME_OUT << 16;
         }
      } 
   } else { 
      if (scb->bus == 0) {
         DEBUG_VAR(1, "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
                   ips_name, ha->host_num,
                   scb->cmd.basic_io.op_code, basic_status, ext_status);
      }
      ips_map_status(ha, scb, sp);
   } 
}
static void ips_chkstatus ( ips_ha_t * ha , IPS_STATUS * pstatus ) { ips_scb_t * scb ; ips_stat_t * sp ; u8 basic_status ; u8 ext_status ; int errcode ; METHOD_TRACE ( " " , 1 ) ; scb = & ha -> scbs [ pstatus -> fields . command_id ] ; scb -> basic_status = basic_status = pstatus -> fields . basic_status & IPS_BASIC_STATUS_MASK ; scb -> extended_status = ext_status = pstatus -> fields . extended_status ; sp = & ha -> sp ; sp -> residue_len = 0 ; sp -> scb_addr = ( u32 ) scb ; ips_removeq_scb ( & ha -> scb_activelist , scb ) ; if ( ! scb -> scsi_cmd ) return ; DEBUG_VAR ( 2 , " " , ips_name , ha -> host_num , scb -> cdb [ 0 ] , scb -> cmd . basic_io . command_id , scb -> bus , scb -> target_id , scb -> lun ) ; #ifndef NO_IPS_CMDLINE if ( ( scb -> scsi_cmd ) && ( ips_is_passthru ( scb -> scsi_cmd ) ) ) return ; #endif errcode = DID_OK ; if ( ( ( basic_status & IPS_GSC_STATUS_MASK ) == IPS_CMD_SUCCESS ) || ( ( basic_status & IPS_GSC_STATUS_MASK ) == IPS_CMD_RECOVERED_ERROR ) ) { if ( scb -> bus == 0 ) { if ( ( basic_status & IPS_GSC_STATUS_MASK ) == IPS_CMD_RECOVERED_ERROR ) { DEBUG_VAR ( 1 , " " , ips_name , ha -> host_num , scb -> cmd . basic_io . op_code , basic_status , ext_status ) ; } switch ( scb -> scsi_cmd -> cmnd [ 0 ] ) { case ALLOW_MEDIUM_REMOVAL : case REZERO_UNIT : case ERASE : case WRITE_FILEMARKS : case SPACE : errcode = DID_ERROR ; break ; case START_STOP : break ; case TEST_UNIT_READY : if ( ! ips_online ( ha , scb ) ) { errcode = DID_TIME_OUT ; } break ; case INQUIRY : if ( ips_online ( ha , scb ) ) { ips_inquiry ( ha , scb ) ; } else { errcode = DID_TIME_OUT ; } break ; case REQUEST_SENSE : ips_reqsen ( ha , scb ) ; break ; case READ_6 : case WRITE_6 : case READ_10 : case WRITE_10 : case RESERVE : case RELEASE : break ; case MODE_SENSE : if ( ! ips_online ( ha , scb ) || ! ips_msense ( ha , scb ) ) { errcode = DID_ERROR ; } break ; case READ_CAPACITY : if ( ips_online ( ha , scb ) ) ips_rdcap ( ha , scb ) ; else { errcode = DID_TIME_OUT ; } break ; case SEND_DIAGNOSTIC : case REASSIGN_BLOCKS : break ; case FORMAT_UNIT : errcode = DID_ERROR ; break ; case SEEK_10 : case VERIFY : case READ_DEFECT_DATA : case READ_BUFFER : case WRITE_BUFFER : break ; default : errcode = DID_ERROR ; } scb -> scsi_cmd -> result = errcode << 16 ; } else { if ( ( scb -> scsi_cmd -> cmnd [ 0 ] == INQUIRY ) && ( ( ( ( char * ) scb -> scsi_cmd -> buffer ) [ 0 ] & 0x1f ) == TYPE_DISK ) ) { scb -> scsi_cmd -> result = DID_TIME_OUT << 16 ; } } } else { if ( scb -> bus == 0 ) { DEBUG_VAR ( 1 , " " , ips_name , ha -> host_num , scb -> cmd . basic_io . op_code , basic_status , ext_status ) ; } ips_map_status ( ha , scb , sp ) ; } }
Routine Name: ips_chk_status
Routine Name : ips_chk_status
/* Remove the item from the active queue */ /* internal commands are handled in do_ipsintr */ /* passthru - just returns the raw result */ /* end switch */ /* bus == 0 */ /* restrict access to physical drives */ /* else */ /* recovered error / success */ /* else */