kernels/linux-2.4.0/drivers/scsi/ips.c
/****************************************************************************/
/*                                                                          */
/* Routine Name: ips_map_status                                             */
/*                                                                          */
/* Routine Description:                                                     */
/*                                                                          */
/*   Map ServeRAID error codes to Linux Error Codes                         */
/*                                                                          */
/****************************************************************************/


Routine Description.

Map ServeRAID error codes to Linux Error Codes
Routine Description . Map ServeRAID error codes to Linux Error Codes
static int
ips_map_status(ips_ha_t *ha, ips_scb_t *scb, ips_stat_t *sp) {
   int       errcode;
   int       device_error;
   METHOD_TRACE("ips_map_status", 1);
   if (scb->bus) {
      DEBUG_VAR(2, "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
                ips_name,
                ha->host_num,
                scb->scsi_cmd->channel,
                scb->scsi_cmd->target,
                scb->scsi_cmd->lun,
                scb->basic_status,
                scb->extended_status,
                scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
                scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0,
                scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0);
   }
   errcode = DID_ERROR;
   device_error = 0;
   switch (scb->basic_status & IPS_GSC_STATUS_MASK) {
   case IPS_CMD_TIMEOUT:
      errcode = DID_TIME_OUT;
      break;
   case IPS_INVAL_OPCO:
   case IPS_INVAL_CMD_BLK:
   case IPS_INVAL_PARM_BLK:
   case IPS_LD_ERROR:
   case IPS_CMD_CMPLT_WERROR:
      break;
   case IPS_PHYS_DRV_ERROR:
      switch (scb->extended_status) {
      case IPS_ERR_SEL_TO:
         if (scb->bus)
            errcode = DID_NO_CONNECT;
         break;
      case IPS_ERR_OU_RUN:
         if ((scb->bus) && (scb->dcdb.transfer_length < scb->data_len)) {
            errcode = DID_OK;
            if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
                ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == TYPE_DISK)) {
               errcode = DID_TIME_OUT;
               break;
            }
         } else
            errcode = DID_ERROR;
         break;
      case IPS_ERR_RECOVERY:
         if (scb->bus)
            errcode = DID_OK;
         break;
      case IPS_ERR_HOST_RESET:
      case IPS_ERR_DEV_RESET:
         errcode = DID_RESET;
         break;
      case IPS_ERR_CKCOND:
         if (scb->bus) {
            memcpy(scb->scsi_cmd->sense_buffer, scb->dcdb.sense_info,
                   sizeof(scb->scsi_cmd->sense_buffer));
            device_error = 2; 
         }
         errcode = DID_OK;
         break;
      default:
         errcode = DID_ERROR;
         break;
      } 
   } 
   scb->scsi_cmd->result = device_error | (errcode << 16);
   return (1);
}
static int ips_map_status ( ips_ha_t * ha , ips_scb_t * scb , ips_stat_t * sp ) { int errcode ; int device_error ; METHOD_TRACE ( " " , 1 ) ; if ( scb -> bus ) { DEBUG_VAR ( 2 , " " , ips_name , ha -> host_num , scb -> scsi_cmd -> channel , scb -> scsi_cmd -> target , scb -> scsi_cmd -> lun , scb -> basic_status , scb -> extended_status , scb -> extended_status == IPS_ERR_CKCOND ? scb -> dcdb . sense_info [ 2 ] & 0xf : 0 , scb -> extended_status == IPS_ERR_CKCOND ? scb -> dcdb . sense_info [ 12 ] : 0 , scb -> extended_status == IPS_ERR_CKCOND ? scb -> dcdb . sense_info [ 13 ] : 0 ) ; } errcode = DID_ERROR ; device_error = 0 ; switch ( scb -> basic_status & IPS_GSC_STATUS_MASK ) { case IPS_CMD_TIMEOUT : errcode = DID_TIME_OUT ; break ; case IPS_INVAL_OPCO : case IPS_INVAL_CMD_BLK : case IPS_INVAL_PARM_BLK : case IPS_LD_ERROR : case IPS_CMD_CMPLT_WERROR : break ; case IPS_PHYS_DRV_ERROR : switch ( scb -> extended_status ) { case IPS_ERR_SEL_TO : if ( scb -> bus ) errcode = DID_NO_CONNECT ; break ; case IPS_ERR_OU_RUN : if ( ( scb -> bus ) && ( scb -> dcdb . transfer_length < scb -> data_len ) ) { errcode = DID_OK ; if ( ( scb -> scsi_cmd -> cmnd [ 0 ] == INQUIRY ) && ( ( ( ( char * ) scb -> scsi_cmd -> buffer ) [ 0 ] & 0x1f ) == TYPE_DISK ) ) { errcode = DID_TIME_OUT ; break ; } } else errcode = DID_ERROR ; break ; case IPS_ERR_RECOVERY : if ( scb -> bus ) errcode = DID_OK ; break ; case IPS_ERR_HOST_RESET : case IPS_ERR_DEV_RESET : errcode = DID_RESET ; break ; case IPS_ERR_CKCOND : if ( scb -> bus ) { memcpy ( scb -> scsi_cmd -> sense_buffer , scb -> dcdb . sense_info , sizeof ( scb -> scsi_cmd -> sense_buffer ) ) ; device_error = 2 ; } errcode = DID_OK ; break ; default : errcode = DID_ERROR ; break ; } } scb -> scsi_cmd -> result = device_error | ( errcode << 16 ) ; return ( 1 ) ; }
Routine Name: ips_map_status
Routine Name : ips_map_status
/* default driver error */ /* Underrun - set default to no error */ /* Restrict access to physical DASD */ /* underflow -- no error               */ /* restrict access to physical DASD    */ /* don't fail recovered errors */ /* check condition */ /* end switch */ /* end switch */