if (ahc->inited_target[target] == INITED_TARGET_START) { if ((xs->cmd->opcode == INQUIRY) && (xs->error == XS_NOERROR)) ahc->inited_target[target] = INITED_TARGET_INQUIRYOK; }
ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments){	struct	scb *scb;	struct	scsi_xfer *xs;	struct	ahc_softc *ahc;	struct	ahc_initiator_tinfo *tinfo;	struct	ahc_tmode_tstate *tstate;	u_int	mask;	int	s, target;	scb = (struct scb *)arg;	xs = scb->xs;	xs->error = CAM_REQ_INPROG;	xs->status = 0;	ahc = (struct ahc_softc *)xs->sc_link->adapter_softc;	if (nsegments != 0) {		struct	  ahc_dma_seg *sg;		bus_dma_segment_t *end_seg;		int op;				end_seg = dm_segs + nsegments;		/* Copy the segments into our SG list */		sg = scb->sg_list;		while (dm_segs < end_seg) {			uint32_t len;			sg->addr = ahc_htole32(dm_segs->ds_addr);			len = dm_segs->ds_len			    | ((dm_segs->ds_addr >> 8) & 0x7F000000);			sg->len = ahc_htole32(len);			sg++;			dm_segs++;		}		/*		 * Note where to find the SG entries in bus space.		 * We also set the full residual flag which the 		 * sequencer will clear as soon as a data transfer		 * occurs.		 */		scb->hscb->sgptr = ahc_htole32(scb->sg_list_phys|SG_FULL_RESID);		if ((xs->flags & SCSI_DATA_IN) != 0)			op = BUS_DMASYNC_PREREAD;		else			op = BUS_DMASYNC_PREWRITE;		bus_dmamap_sync(ahc->parent_dmat, scb->dmamap, 0,				scb->dmamap->dm_mapsize, op);		sg--;		sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);		bus_dmamap_sync(ahc->parent_dmat, scb->sg_map->sg_dmamap,		    0, scb->sg_map->sg_dmamap->dm_mapsize,		    BUS_DMASYNC_PREWRITE);		/* Copy the first SG into the "current" data pointer area */		scb->hscb->dataptr = scb->sg_list->addr;		scb->hscb->datacnt = scb->sg_list->len;	} else {		scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL);		scb->hscb->dataptr = 0;		scb->hscb->datacnt = 0;	}	scb->sg_count = nsegments;	ahc_lock(ahc, &s);	/*	 * Last time we need to check if this SCB needs to	 * be aborted.	 */	if (xs->flags & ITSDONE) {		if (nsegments != 0)			bus_dmamap_unload(ahc->parent_dmat, scb->dmamap);		ahc_free_scb(ahc, scb);		ahc_unlock(ahc, &s);		return (COMPLETE);	}	tinfo = ahc_fetch_transinfo(ahc, SCSIID_CHANNEL(ahc, scb->hscb->scsiid),				    SCSIID_OUR_ID(scb->hscb->scsiid),				    SCSIID_TARGET(ahc, scb->hscb->scsiid),				    &tstate);	mask = SCB_GET_TARGET_MASK(ahc, scb);	scb->hscb->scsirate = tinfo->scsirate;	scb->hscb->scsioffset = tinfo->curr.offset;	if ((tstate->ultraenb & mask) != 0)		scb->hscb->control |= ULTRAENB;	if ((tstate->discenable & mask) != 0)	    	scb->hscb->control |= DISCENB;	if ((tstate->auto_negotiate & mask) != 0) {		scb->flags |= SCB_AUTO_NEGOTIATE;		scb->hscb->control |= MK_MESSAGE;	}	if ((tstate->tagenable & mask) != 0)		ahc_set_transaction_tag(scb, TRUE, MSG_SIMPLE_TASK);	bus_dmamap_sync(ahc->parent_dmat, ahc->scb_data->hscb_dmamap,	    0, ahc->scb_data->hscb_dmamap->dm_mapsize,	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);	LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links);	if (!(xs->flags & SCSI_POLL))		timeout_add(&xs->stimeout, (xs->timeout * hz) / 1000);	/*	 * We only allow one untagged transaction	 * per target in the initiator role unless	 * we are storing a full busy target *lun*	 * table in SCB space.	 *	 * This really should not be of any	 * concern, as we take care to avoid this	 * in ahc_done().  XXX smurph	 */	if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0	    && (ahc->flags & AHC_SCB_BTT) == 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_INSERT_TAIL(untagged_q, scb, links.tqe);		scb->flags |= SCB_UNTAGGEDQ;		if (TAILQ_FIRST(untagged_q) != scb) {			if (xs->flags & SCSI_POLL)				goto poll;			else {						ahc_unlock(ahc, &s);				return (SUCCESSFULLY_QUEUED);			}		}	}	scb->flags |= SCB_ACTIVE;	if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) {		/* Define a mapping from our tag to the SCB. */		ahc->scb_data->scbindex[scb->hscb->tag] = scb;		ahc_pause(ahc);		if ((ahc->flags & AHC_PAGESCBS) == 0)			ahc_outb(ahc, SCBPTR, scb->hscb->tag);		ahc_outb(ahc, TARG_IMMEDIATE_SCB, scb->hscb->tag);		ahc_unpause(ahc);	} else {		ahc_queue_scb(ahc, scb);	}	if (!(xs->flags & SCSI_POLL)) {		ahc_unlock(ahc, &s);		return (SUCCESSFULLY_QUEUED);	}	/*	 * If we can't use interrupts, poll for completion	 */poll:	SC_DEBUG(xs->sc_link, SDEV_DB3, ("cmd_poll\n"));	target = xs->sc_link->target;	if (ahc->inited_target[target] == INITED_TARGET_INQUIRYOK) {		struct	ahc_initiator_tinfo *tinfo;		struct	ahc_tmode_tstate *tstate;		struct	ahc_devinfo devinfo;		ahc_adapter_req_set_xfer_mode(ahc, scb);		ahc_scb_devinfo(ahc, &devinfo, scb);		tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,		    devinfo.our_scsiid, devinfo.target, &tstate);		ahc_update_neg_request(ahc, &devinfo, tstate, tinfo,		    AHC_NEG_IF_NON_ASYNC);		ahc->inited_target[target] = INITED_TARGET_MODEOK;	}	do {		if (ahc_poll(ahc, xs->timeout)) {			if (!(xs->flags & SCSI_SILENT))				printf("cmd fail\n");			ahc_timeout(scb);			break;		}	} while (!(xs->flags & ITSDONE));	if (ahc->inited_target[target] == INITED_TARGET_START) {		if ((xs->cmd->opcode == INQUIRY) && (xs->error == XS_NOERROR))			ahc->inited_target[target] = INITED_TARGET_INQUIRYOK;	}	ahc_unlock(ahc, &s);	return (COMPLETE);}