xs->error = XS_NOERROR;
switch (xs->status) { case SCSI_TASKSET_FULL:  xs->error = XS_TIMEOUT; xs->retries++; break; case SCSI_BUSY: xs->error = XS_BUSY; break; case SCSI_CHECK: case SCSI_TERMINATED: if ((scb->flags & SCB_SENSE) == 0) {  xs->error = XS_DRIVER_STUFFUP; } else xs->error = XS_NOERROR; break; default: xs->error = XS_NOERROR; break; }
ahc_done(struct ahc_softc *ahc, struct scb *scb){	struct scsi_xfer *xs = scb->xs;	int s;	bus_dmamap_sync(ahc->parent_dmat, ahc->scb_data->hscb_dmamap,	    0, ahc->scb_data->hscb_dmamap->dm_mapsize,	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);	LIST_REMOVE(scb, pending_links);	if ((scb->flags & SCB_UNTAGGEDQ) != 0) {		struct scb_tailq *untagged_q;		int target_offset;		target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);		untagged_q = &ahc->untagged_queues[target_offset];		TAILQ_REMOVE(untagged_q, scb, links.tqe);		scb->flags &= ~SCB_UNTAGGEDQ;		ahc_run_untagged_queue(ahc, untagged_q);	}	timeout_del(&xs->stimeout);	if (xs->datalen) {		int op;		if ((xs->flags & SCSI_DATA_IN) != 0)			op = BUS_DMASYNC_POSTREAD;		else			op = BUS_DMASYNC_POSTWRITE;		bus_dmamap_sync(ahc->parent_dmat, scb->dmamap, 0,				scb->dmamap->dm_mapsize, op);		bus_dmamap_unload(ahc->parent_dmat, scb->dmamap);	}	/*	 * If the recovery SCB completes, we have to be	 * out of our timeout.	 */	if ((scb->flags & SCB_RECOVERY_SCB) != 0) {		struct	scb *list_scb;		/*		 * We were able to complete the command successfully,		 * so reinstate the timeouts for all other pending		 * commands.		 */		LIST_FOREACH(list_scb, &ahc->pending_scbs, pending_links) {			struct scsi_xfer *txs = list_scb->xs;			if (!(txs->flags & SCSI_POLL))				timeout_add(&list_scb->xs->stimeout,				    (list_scb->xs->timeout * hz)/1000);		}		if (xs->error != CAM_REQ_INPROG)			ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);		ahc_print_path(ahc, scb);		printf("no longer in timeout, status = %x\n", xs->status);	}	/* Translate the CAM status code to a SCSI error code. */	switch (xs->error) {	case CAM_REQ_INPROG:	case CAM_REQ_CMP:		xs->error = XS_NOERROR;		break;	case CAM_BUSY:		xs->error = XS_BUSY;		break;	case CAM_CMD_TIMEOUT:		xs->error = XS_TIMEOUT;		break;	case CAM_BDR_SENT:	case CAM_SCSI_BUS_RESET:	case CAM_REQUEUE_REQ:		xs->error = XS_RESET;		break;	case CAM_SEL_TIMEOUT:		xs->error = XS_SELTIMEOUT;		break;	default:		xs->error = XS_DRIVER_STUFFUP;		break;	}	/* Don't clobber any existing error state */	if (xs->error != XS_NOERROR) {	  /* Don't clobber any existing error state */	} else if ((scb->flags & SCB_SENSE) != 0) {		/*		 * We performed autosense retrieval.		 *		 * Zero any sense not transferred by the		 * device.  The SCSI spec mandates that any		 * untransferred data should be assumed to be		 * zero.  Complete the 'bounce' of sense information		 * through buffers accessible via bus-space by		 * copying it into the clients csio.		 */		memset(&xs->sense, 0, sizeof(struct scsi_sense_data));		memcpy(&xs->sense, ahc_get_sense_buf(ahc, scb),		    ahc_le32toh(scb->sg_list->len) & AHC_SG_LEN_MASK);		xs->error = XS_SENSE;	}	if (scb->flags & SCB_FREEZE_QUEUE) {		scb->flags &= ~SCB_FREEZE_QUEUE;	}        ahc_lock(ahc, &s);       	ahc_free_scb(ahc, scb);        ahc_unlock(ahc, &s);       	xs->flags |= ITSDONE;	scsi_done(xs);}