/* * Typically, the complete queue has very few entries * queued to it before the queue is emptied by * ahd_linux_run_complete_queue, so sorting the entries * by generation number should be inexpensive. * We perform the sort so that commands that complete * with an error are retuned in the order origionally * queued to the controller so that any subsequent retries * are performed in order.  The underlying ahd routines do * not guarantee the order that aborted commands will be * returned to us. */ struct ahd_completeq *completeq; struct ahd_cmd *list_cmd; struct ahd_cmd *acmd;  
ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, Scsi_Cmnd *cmd){	/*	 * Typically, the complete queue has very few entries	 * queued to it before the queue is emptied by	 * ahd_linux_run_complete_queue, so sorting the entries	 * by generation number should be inexpensive.	 * We perform the sort so that commands that complete	 * with an error are retuned in the order origionally	 * queued to the controller so that any subsequent retries	 * are performed in order.  The underlying ahd routines do	 * not guarantee the order that aborted commands will be	 * returned to us.	 */	struct ahd_completeq *completeq;	struct ahd_cmd *list_cmd;	struct ahd_cmd *acmd;	/*	 * Map CAM error codes into Linux Error codes.  We	 * avoid the conversion so that the DV code has the	 * full error information available when making	 * state change decisions.	 */	if (AHD_DV_CMD(cmd) == FALSE) {		uint32_t status;		u_int new_status;		status = ahd_cmd_get_transaction_status(cmd);		if (status != CAM_REQ_CMP) {			struct ahd_linux_device *dev;			struct ahd_devinfo devinfo;			cam_status cam_status;			uint32_t action;			u_int scsi_status;			dev = ahd_linux_get_device(ahd, cmd->device->channel,						   cmd->device->id,						   cmd->device->lun,						   /*alloc*/FALSE);			if (dev == NULL)				goto no_fallback;			ahd_compile_devinfo(&devinfo,					    ahd->our_id,					    dev->target->target, dev->lun,					    dev->target->channel == 0 ? 'A':'B',					    ROLE_INITIATOR);			scsi_status = ahd_cmd_get_scsi_status(cmd);			cam_status = ahd_cmd_get_transaction_status(cmd);			action = aic_error_action(cmd, dev->target->inq_data,						  cam_status, scsi_status);			if ((action & SSQ_FALLBACK) != 0) {				/* Update stats */				dev->target->errors_detected++;				if (dev->target->cmds_since_error == 0)					dev->target->cmds_since_error++;				else {					dev->target->cmds_since_error = 0;					ahd_linux_fallback(ahd, &devinfo);				}			}		}no_fallback:		switch (status) {		case CAM_REQ_INPROG:		case CAM_REQ_CMP:		case CAM_SCSI_STATUS_ERROR:			new_status = DID_OK;			break;		case CAM_REQ_ABORTED:			new_status = DID_ABORT;			break;		case CAM_BUSY:			new_status = DID_BUS_BUSY;			break;		case CAM_REQ_INVALID:		case CAM_PATH_INVALID:			new_status = DID_BAD_TARGET;			break;		case CAM_SEL_TIMEOUT:			new_status = DID_NO_CONNECT;			break;		case CAM_SCSI_BUS_RESET:		case CAM_BDR_SENT:			new_status = DID_RESET;			break;		case CAM_UNCOR_PARITY:			new_status = DID_PARITY;			break;		case CAM_CMD_TIMEOUT:			new_status = DID_TIME_OUT;			break;		case CAM_UA_ABORT:		case CAM_REQ_CMP_ERR:		case CAM_AUTOSENSE_FAIL:		case CAM_NO_HBA:		case CAM_DATA_RUN_ERR:		case CAM_UNEXP_BUSFREE:		case CAM_SEQUENCE_FAIL:		case CAM_CCB_LEN_ERR:		case CAM_PROVIDE_FAIL:		case CAM_REQ_TERMIO:		case CAM_UNREC_HBA_ERROR:		case CAM_REQ_TOO_BIG:			new_status = DID_ERROR;			break;		case CAM_REQUEUE_REQ:			/*			 * If we want the request requeued, make sure there			 * are sufficent retries.  In the old scsi error code,			 * we used to be able to specify a result code that			 * bypassed the retry count.  Now we must use this			 * hack.  We also "fake" a check condition with			 * a sense code of ABORTED COMMAND.  This seems to			 * evoke a retry even if this command is being sent			 * via the eh thread.  Ick!  Ick!  Ick!			 */			if (cmd->retries > 0)				cmd->retries--;			new_status = DID_OK;			ahd_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND);			cmd->result |= (DRIVER_SENSE << 24);			memset(cmd->sense_buffer, 0,			       sizeof(cmd->sense_buffer));			cmd->sense_buffer[0] = SSD_ERRCODE_VALID					     | SSD_CURRENT_ERROR;			cmd->sense_buffer[2] = SSD_KEY_ABORTED_COMMAND;			break;		default:			/* We should never get here */			new_status = DID_ERROR;			break;		}		ahd_cmd_set_transaction_status(cmd, new_status);	}	completeq = &ahd->platform_data->completeq;	list_cmd = TAILQ_FIRST(completeq);	acmd = (struct ahd_cmd *)cmd;	while (list_cmd != NULL	    && acmd_scsi_cmd(list_cmd).serial_number	     < acmd_scsi_cmd(acmd).serial_number)		list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe);	if (list_cmd != NULL)		TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe);	else		TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe);}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/73a25462100772b72a5d62fd66dff01b53018618/aic79xx_osm.c/buggy/drivers/scsi/aic7xxx/aic79xx_osm.c