if ((tinfo->curr.ppr_options & MSG_EXT_PPR_PROT_IUS) == 0) { scb->hscb->control &= ~TAG_ENB; scb->hscb->control &= ~DISCENB; }
ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments){	struct	scb *scb;	struct	scsi_xfer *xs;	struct	ahd_softc *ahd;	struct	ahd_initiator_tinfo *tinfo;	struct	ahd_tmode_tstate *tstate;	u_int	mask;	int	s;	scb = (struct scb *)arg;	xs = scb->xs;	xs->error = CAM_REQ_INPROG;	xs->status = 0;	ahd = (struct ahd_softc *)xs->sc_link->adapter_softc;	if (nsegments != 0) {		void *sg;		int op;		u_int i;		ahd_setup_data_scb(ahd, scb);		/* Copy the segments into our SG list */		for (i = nsegments, sg = scb->sg_list; i > 0; i--) {			sg = ahd_sg_setup(ahd, scb, sg, dm_segs->ds_addr,					  dm_segs->ds_len,					  /*last*/i == 1);			dm_segs++;		}				if ((xs->flags & SCSI_DATA_IN) != 0)			op = BUS_DMASYNC_PREREAD;		else			op = BUS_DMASYNC_PREWRITE;		bus_dmamap_sync(ahd->parent_dmat, scb->dmamap, 0,				scb->dmamap->dm_mapsize, op);	}	ahd_lock(ahd, &s);	/*	 * Last time we need to check if this SCB needs to	 * be aborted.	 */	if (xs->flags & ITSDONE) {		if (nsegments != 0)			bus_dmamap_unload(ahd->parent_dmat,					  scb->dmamap);		ahd_free_scb(ahd, scb);		ahd_unlock(ahd, &s);		return (COMPLETE);	}	tinfo = ahd_fetch_transinfo(ahd, SCSIID_CHANNEL(ahd, scb->hscb->scsiid),				    SCSIID_OUR_ID(scb->hscb->scsiid),				    SCSIID_TARGET(ahd, scb->hscb->scsiid),				    &tstate);	mask = SCB_GET_TARGET_MASK(ahd, scb);	if ((tstate->discenable & mask) != 0)		scb->hscb->control |= DISCENB;	if ((tstate->tagenable & mask) != 0)		scb->hscb->control |= TAG_ENB;	/* disable tags and disconection to work around overlapped commands 	 * for non U320 devices	 */	if ((tinfo->curr.ppr_options & MSG_EXT_PPR_PROT_IUS) == 0) {		scb->hscb->control &= ~TAG_ENB;		scb->hscb->control &= ~DISCENB;	}	if ((tinfo->curr.ppr_options & MSG_EXT_PPR_PROT_IUS) != 0) {		scb->flags |= SCB_PACKETIZED;		if (scb->hscb->task_management != 0)			scb->hscb->control &= ~MK_MESSAGE;	}	if ((tstate->auto_negotiate & mask) != 0) {		scb->flags |= SCB_AUTO_NEGOTIATE;		scb->hscb->control |= MK_MESSAGE;	}	/* XXX with ahc there was some bus_dmamap_sync(PREREAD|PREWRITE); */	LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);	if (!(xs->flags & SCSI_POLL))		timeout_add(&xs->stimeout, (xs->timeout * hz) / 1000);	scb->flags |= SCB_ACTIVE;	if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) {		/* Define a mapping from our tag to the SCB. */		ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb;		ahd_pause(ahd);		ahd_set_scbptr(ahd, SCB_GET_TAG(scb));		ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG);		ahd_unpause(ahd);	} else {		ahd_queue_scb(ahd, scb);	}	if (!(xs->flags & SCSI_POLL)) {		int target = xs->sc_link->target;		int lun = SCB_GET_LUN(scb);		if (ahd->inited_target[target] == 0) {			struct  ahd_devinfo devinfo;			ahd_adapter_req_set_xfer_mode(ahd, scb);			ahd_compile_devinfo(&devinfo, ahd->our_id, target, lun,			    'A', /*XXX milos*/ROLE_UNKNOWN);			ahd_scb_devinfo(ahd, &devinfo, scb);			ahd_update_neg_request(ahd, &devinfo, tstate, tinfo,				AHD_NEG_IF_NON_ASYNC);			ahd->inited_target[target] = 1;		}		ahd_unlock(ahd, &s);		return (SUCCESSFULLY_QUEUED);	}	/*	 * If we can't use interrupts, poll for completion	 */	SC_DEBUG(xs->sc_link, SDEV_DB3, ("cmd_poll\n"));	do {		if (ahd_poll(ahd, xs->timeout)) {			if (!(xs->flags & SCSI_SILENT))				printf("cmd fail\n");			ahd_timeout(scb);			break;		}	} while (!(xs->flags & ITSDONE));	ahd_unlock(ahd, &s);	return (COMPLETE);}