Home | History | Annotate | Line # | Download | only in ic
aic7xxx_osm.c revision 1.4
      1 /*	$NetBSD: aic7xxx_osm.c,v 1.4 2003/04/20 19:49:45 fvdl Exp $	*/
      2 
      3 /*
      4  * Bus independent FreeBSD shim for the aic7xxx based adaptec SCSI controllers
      5  *
      6  * Copyright (c) 1994-2001 Justin T. Gibbs.
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions, and the following disclaimer,
     14  *    without modification.
     15  * 2. The name of the author may not be used to endorse or promote products
     16  *    derived from this software without specific prior written permission.
     17  *
     18  * Alternatively, this software may be distributed under the terms of the
     19  * GNU Public License ("GPL").
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
     25  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  *
     33  * //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#12 $
     34  *
     35  * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_osm.c,v 1.31 2002/11/30 19:08:58 scottl Exp $
     36  */
     37 /*
     38  * Ported from FreeBSD by Pascal Renauld, Network Storage Solutions, Inc. - April 2003
     39  */
     40 #include <dev/ic/aic7xxx_osm.h>
     41 #include <dev/ic/aic7xxx_inline.h>
     42 
     43 #ifndef AHC_TMODE_ENABLE
     44 #define AHC_TMODE_ENABLE 0
     45 #endif
     46 
     47 
     48 static void	ahc_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg);
     49 static void	ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments);
     50 static int	ahc_poll(struct ahc_softc *ahc, int wait);
     51 static void	ahc_setup_data(struct ahc_softc *ahc,
     52 			       struct scsipi_xfer *xs, struct scb *scb);
     53 static void	ahc_set_recoveryscb(struct ahc_softc *ahc, struct scb *scb);
     54 static int	ahc_ioctl(struct scsipi_channel *channel, u_long cmd, caddr_t addr, int flag,
     55 			  struct proc *p);
     56 
     57 
     58 
     59 /*
     60  * Attach all the sub-devices we can find
     61  */
     62 int
     63 ahc_attach(struct ahc_softc *ahc)
     64 {
     65 	u_long 	s;
     66 	int i;
     67 	char ahc_info[256];
     68 
     69 	LIST_INIT(&ahc->pending_scbs);
     70 	for (i = 0; i < AHC_NUM_TARGETS; i++)
     71 		TAILQ_INIT(&ahc->untagged_queues[i]);
     72 
     73         ahc_lock(ahc, &s);
     74 
     75 	ahc->sc_adapter.adapt_dev = &ahc->sc_dev;
     76 	ahc->sc_adapter.adapt_nchannels = (ahc->features & AHC_TWIN) ? 2 : 1;
     77 
     78 	ahc->sc_adapter.adapt_openings = AHC_MAX_QUEUE;
     79 	ahc->sc_adapter.adapt_max_periph = 16;
     80 
     81 	ahc->sc_adapter.adapt_ioctl = ahc_ioctl;
     82 	ahc->sc_adapter.adapt_minphys = ahc_minphys;
     83 	ahc->sc_adapter.adapt_request = ahc_action;
     84 
     85 	ahc->sc_channel.chan_adapter = &ahc->sc_adapter;
     86         ahc->sc_channel.chan_bustype = &scsi_bustype;
     87         ahc->sc_channel.chan_channel = 0;
     88         ahc->sc_channel.chan_ntargets = (ahc->features & AHC_WIDE) ? 16 : 8;
     89         ahc->sc_channel.chan_nluns = 8 /*AHC_NUM_LUNS*/;
     90         ahc->sc_channel.chan_id = ahc->our_id;
     91 
     92 	if (ahc->features & AHC_TWIN) {
     93 		ahc->sc_channel_b = ahc->sc_channel;
     94 		ahc->sc_channel_b.chan_id = ahc->our_id_b;
     95 		ahc->sc_channel_b.chan_channel = 1;
     96 	}
     97 
     98 	ahc_controller_info(ahc, ahc_info);
     99 	printf("%s: %s\n", ahc->sc_dev.dv_xname, ahc_info);
    100 
    101 	if ((ahc->flags & AHC_PRIMARY_CHANNEL) == 0) {
    102 		ahc->sc_child = config_found((void *)&ahc->sc_dev,
    103 		    &ahc->sc_channel, scsiprint);
    104 		if (ahc->features & AHC_TWIN)
    105 			ahc->sc_child_b = config_found((void *)&ahc->sc_dev,
    106 			    &ahc->sc_channel_b, scsiprint);
    107 	} else {
    108 		ahc->sc_child = config_found((void *)&ahc->sc_dev,
    109 		    &ahc->sc_channel_b, scsiprint);
    110 		ahc->sc_child_b = config_found((void *)&ahc->sc_dev,
    111 		    &ahc->sc_channel, scsiprint);
    112 	}
    113 
    114 	ahc_intr_enable(ahc, TRUE);
    115 
    116 	ahc_unlock(ahc, &s);
    117 	return (1);
    118 }
    119 
    120 /*
    121  * Catch an interrupt from the adapter
    122  */
    123 void
    124 ahc_platform_intr(void *arg)
    125 {
    126 	struct	ahc_softc *ahc;
    127 
    128 	ahc = (struct ahc_softc *)arg;
    129 	ahc_intr(ahc);
    130 }
    131 
    132 /*
    133  * We have an scb which has been processed by the
    134  * adaptor, now we look to see how the operation
    135  * went.
    136  */
    137 void
    138 ahc_done(struct ahc_softc *ahc, struct scb *scb)
    139 {
    140 	struct scsipi_xfer *xs;
    141   	struct scsipi_periph *periph;
    142 	u_long s;
    143 
    144 	xs = scb->xs;
    145 	periph = xs->xs_periph;
    146 	LIST_REMOVE(scb, pending_links);
    147 	if ((scb->flags & SCB_UNTAGGEDQ) != 0) {
    148 		struct scb_tailq *untagged_q;
    149 		int target_offset;
    150 
    151 		target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
    152 		untagged_q = &ahc->untagged_queues[target_offset];
    153 		TAILQ_REMOVE(untagged_q, scb, links.tqe);
    154 		scb->flags &= ~SCB_UNTAGGEDQ;
    155 		ahc_run_untagged_queue(ahc, untagged_q);
    156 	}
    157 
    158 	callout_stop(&scb->xs->xs_callout);
    159 
    160 	if (xs->datalen) {
    161 		int op;
    162 
    163 		if (xs->xs_control & XS_CTL_DATA_IN)
    164 			op = BUS_DMASYNC_POSTREAD;
    165 		else
    166 			op = BUS_DMASYNC_POSTWRITE;
    167 		bus_dmamap_sync(ahc->parent_dmat, scb->dmamap, 0,
    168 				scb->dmamap->dm_mapsize, op);
    169 		bus_dmamap_unload(ahc->parent_dmat, scb->dmamap);
    170 	}
    171 
    172 	/*
    173 	 * If the recovery SCB completes, we have to be
    174 	 * out of our timeout.
    175 	 */
    176 	if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
    177 		struct	scb *list_scb;
    178 
    179 		/*
    180 		 * We were able to complete the command successfully,
    181 		 * so reinstate the timeouts for all other pending
    182 		 * commands.
    183 		 */
    184 		LIST_FOREACH(list_scb, &ahc->pending_scbs, pending_links) {
    185 			struct scsipi_xfer *xs = list_scb->xs;
    186 
    187 			if (!(xs->xs_control & XS_CTL_POLL)) {
    188 				callout_reset(&list_scb->xs->xs_callout,
    189 				    (list_scb->xs->timeout > 1000000) ?
    190 				    (list_scb->xs->timeout / 1000) * hz :
    191 				    (list_scb->xs->timeout * hz) / 1000,
    192 				    ahc_timeout, list_scb);
    193 			}
    194 		}
    195 
    196 		if (ahc_get_transaction_status(scb) == CAM_BDR_SENT
    197 		 || ahc_get_transaction_status(scb) == CAM_REQ_ABORTED)
    198 			ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
    199 		scsipi_printaddr(xs->xs_periph);
    200 		printf("%s: no longer in timeout, status = %x\n",
    201 		       ahc_name(ahc), xs->status);
    202 	}
    203 
    204 	/* Don't clobber any existing error state */
    205 	if (xs->error != XS_NOERROR) {
    206 	  /* Don't clobber any existing error state */
    207 	} else if ((scb->flags & SCB_SENSE) != 0) {
    208 		/*
    209 		 * We performed autosense retrieval.
    210 		 *
    211 		 * Zero any sense not transferred by the
    212 		 * device.  The SCSI spec mandates that any
    213 		 * untransfered data should be assumed to be
    214 		 * zero.  Complete the 'bounce' of sense information
    215 		 * through buffers accessible via bus-space by
    216 		 * copying it into the clients csio.
    217 		 */
    218 		memset(&xs->sense.scsi_sense, 0, sizeof(xs->sense.scsi_sense));
    219 		memcpy(&xs->sense.scsi_sense,
    220 		       ahc_get_sense_buf(ahc, scb),
    221 		       sizeof(xs->sense.scsi_sense));
    222 		xs->error = XS_SENSE;
    223 	}
    224 	if (scb->flags & SCB_FREEZE_QUEUE) {
    225 		scsipi_periph_thaw(periph, 1);
    226 		scb->flags &= ~SCB_FREEZE_QUEUE;
    227 	}
    228 
    229         ahc_lock(ahc, &s);
    230 	ahc_free_scb(ahc, scb);
    231         ahc_unlock(ahc, &s);
    232 
    233 	scsipi_done(xs);
    234 }
    235 
    236 static int
    237 ahc_ioctl(struct scsipi_channel *channel, u_long cmd, caddr_t addr, int flag,
    238 	  struct proc *p)
    239 {
    240 	struct ahc_softc *ahc = (void *)channel->chan_adapter->adapt_dev;
    241 	int s, ret = ENOTTY;
    242 
    243 	switch (cmd) {
    244 	case SCBUSIORESET:
    245 		s = splbio();
    246 		ahc_reset_channel(ahc, ahc->channel, TRUE);
    247 		splx(s);
    248 		ret = 0;
    249 		break;
    250 	default:
    251 		break;
    252 	}
    253 
    254 	return ret;
    255 }
    256 
    257 static void
    258 ahc_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
    259 {
    260 	struct ahc_softc *ahc;
    261 	int s;
    262 	struct ahc_initiator_tinfo *tinfo;
    263 	struct ahc_tmode_tstate *tstate;
    264 	char channel;
    265 
    266 	ahc  = (void *)chan->chan_adapter->adapt_dev;
    267 
    268 	channel = chan->chan_channel == 0 ? 'A' : 'B';
    269 
    270 	if (ahc->inited_channels[channel - 'A'] == 0) {
    271 		if ((channel == 'A' && (ahc->flags & AHC_RESET_BUS_A)) ||
    272 		    (channel == 'B' && (ahc->flags & AHC_RESET_BUS_B))) {
    273 			s = splbio();
    274 			ahc_reset_channel(ahc, channel, TRUE);
    275 			splx(s);
    276 		}
    277 		ahc->inited_channels[channel - 'A'] = 1;
    278 	}
    279 
    280 	switch (req) {
    281 
    282 	case ADAPTER_REQ_RUN_XFER:
    283 	  {
    284 		struct scsipi_xfer *xs;
    285 		struct scsipi_periph *periph;
    286 	        struct scb *scb;
    287         	struct hardware_scb *hscb;
    288 		u_int target_id;
    289 		u_int our_id;
    290 		u_long s;
    291 
    292 		xs = arg;
    293 		periph = xs->xs_periph;
    294 
    295 		target_id = periph->periph_target;
    296                 our_id = ahc->our_id;
    297 
    298 		SC_DEBUG(xs->xs_periph, SCSIPI_DB3, ("ahc_action\n"));
    299 
    300 		/*
    301 		 * get an scb to use.
    302 		 */
    303 		ahc_lock(ahc, &s);
    304 		if ((scb = ahc_get_scb(ahc)) == NULL) {
    305 			xs->error = XS_RESOURCE_SHORTAGE;
    306 			ahc_unlock(ahc, &s);
    307 			scsipi_done(xs);
    308 			return;
    309 		}
    310 		ahc_unlock(ahc, &s);
    311 
    312 		hscb = scb->hscb;
    313 
    314 		SC_DEBUG(periph, SCSIPI_DB3, ("start scb(%p)\n", scb));
    315 		scb->xs = xs;
    316 
    317 		/*
    318 		 * Put all the arguments for the xfer in the scb
    319 		 */
    320 		hscb->control = 0;
    321 		hscb->scsiid = BUILD_SCSIID(ahc, 0, target_id, our_id);
    322 		hscb->lun = periph->periph_lun;
    323 		if (xs->xs_control & XS_CTL_RESET) {
    324 			hscb->cdb_len = 0;
    325 			scb->flags |= SCB_DEVICE_RESET;
    326 			hscb->control |= MK_MESSAGE;
    327 			ahc_execute_scb(scb, NULL, 0);
    328 		}
    329 
    330 		ahc_setup_data(ahc, xs, scb);
    331 
    332 		break;
    333 	  }
    334 	case ADAPTER_REQ_GROW_RESOURCES:
    335   		printf("%s: ADAPTER_REQ_GROW_RESOURCES\n", ahc_name(ahc));
    336 		return;
    337 
    338 	case ADAPTER_REQ_SET_XFER_MODE:
    339 	    {
    340 		struct scsipi_xfer_mode *xm = arg;
    341 		struct ahc_devinfo devinfo;
    342 		int target_id, our_id, first;
    343 		u_int width;
    344 		char channel;
    345 
    346 		target_id = xm->xm_target;
    347 		our_id = chan->chan_id;
    348 		channel = (chan->chan_channel == 1) ? 'B' : 'A';
    349 		s = splbio();
    350 		tinfo = ahc_fetch_transinfo(ahc, channel, our_id, target_id,
    351 		    &tstate);
    352 		ahc_compile_devinfo(&devinfo, our_id, target_id,
    353 		    0, channel, ROLE_INITIATOR);
    354 
    355 		/*
    356 		 * XXX since the period and offset are not provided here,
    357 		 * fake things by forcing a renegotiation using the user
    358 		 * settings if this is called for the first time (i.e.
    359 		 * during probe). Also, cap various values at the user
    360 		 * values, assuming that the user set it up that way.
    361 		 */
    362 		if (ahc->inited_target[target_id] == 0) {
    363 			tinfo->goal = tinfo->user;
    364 			tstate->tagenable |=
    365 			    (ahc->user_tagenable & devinfo.target_mask);
    366 			tstate->discenable |=
    367 			    (ahc->user_discenable & devinfo.target_mask);
    368 			ahc->inited_target[target_id] = 1;
    369 			first = 1;
    370 		} else
    371 			first = 0;
    372 
    373 		if (xm->xm_mode & PERIPH_CAP_WIDE16)
    374 			width = MSG_EXT_WDTR_BUS_16_BIT;
    375 		else
    376 			width = MSG_EXT_WDTR_BUS_8_BIT;
    377 
    378 		ahc_validate_width(ahc, NULL, &width, ROLE_UNKNOWN);
    379 		if (width > tinfo->user.width)
    380 			width = tinfo->user.width;
    381 		tinfo->goal.width = width;
    382 
    383 		if (!(xm->xm_mode & PERIPH_CAP_SYNC)) {
    384 			tinfo->goal.period = 0;
    385 			tinfo->goal.offset = 0;
    386 			tinfo->goal.ppr_options = 0;
    387 		}
    388 
    389 		if ((xm->xm_mode & PERIPH_CAP_DT) &&
    390 		    (tinfo->user.ppr_options & MSG_EXT_PPR_DT_REQ))
    391 			tinfo->goal.ppr_options |= MSG_EXT_PPR_DT_REQ;
    392 		else
    393 			tinfo->goal.ppr_options &= ~MSG_EXT_PPR_DT_REQ;
    394 
    395 		if ((xm->xm_mode & PERIPH_CAP_TQING) &&
    396 		    (ahc->user_tagenable & devinfo.target_mask))
    397 			tstate->tagenable |= devinfo.target_mask;
    398 		else
    399 			tstate->tagenable &= ~devinfo.target_mask;
    400 
    401 		/*
    402 		 * If this is the first request, and no negotiation is
    403 		 * needed, just confirm the state to the scsipi layer,
    404 		 * so that it can print a message.
    405 		 */
    406 		if (!ahc_update_neg_request(ahc, &devinfo, tstate,
    407 		    tinfo, AHC_NEG_IF_NON_ASYNC) && first)
    408 			scsipi_async_event(chan, ASYNC_EVENT_XFER_MODE, xm);
    409 		splx(s);
    410 	    }
    411 	}
    412 
    413 	return;
    414 }
    415 
    416 static void
    417 ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments)
    418 {
    419 	struct	scb *scb;
    420 	struct scsipi_xfer *xs;
    421 	struct	ahc_softc *ahc;
    422 	struct	ahc_initiator_tinfo *tinfo;
    423 	struct	ahc_tmode_tstate *tstate;
    424 
    425 	u_int	mask;
    426 	long	s;
    427 
    428 	scb = (struct scb *)arg;
    429 	xs = scb->xs;
    430 	xs->error = 0;
    431 	xs->status = 0;
    432 	xs->xs_status = 0;
    433 	ahc = (void *)xs->xs_periph->periph_channel->chan_adapter->adapt_dev;
    434 
    435 	if (nsegments != 0) {
    436 		struct	  ahc_dma_seg *sg;
    437 		bus_dma_segment_t *end_seg;
    438 		int op;
    439 
    440 		end_seg = dm_segs + nsegments;
    441 
    442 		/* Copy the segments into our SG list */
    443 		sg = scb->sg_list;
    444 		while (dm_segs < end_seg) {
    445 			uint32_t len;
    446 
    447 			sg->addr = ahc_htole32(dm_segs->ds_addr);
    448 			len = dm_segs->ds_len
    449 			    | ((dm_segs->ds_addr >> 8) & 0x7F000000);
    450 			sg->len = ahc_htole32(len);
    451 			sg++;
    452 			dm_segs++;
    453 		}
    454 
    455 		/*
    456 		 * Note where to find the SG entries in bus space.
    457 		 * We also set the full residual flag which the
    458 		 * sequencer will clear as soon as a data transfer
    459 		 * occurs.
    460 		 */
    461 		scb->hscb->sgptr = ahc_htole32(scb->sg_list_phys|SG_FULL_RESID);
    462 
    463 		if (xs->xs_control & XS_CTL_DATA_IN)
    464 			op = BUS_DMASYNC_PREREAD;
    465 		else
    466 			op = BUS_DMASYNC_PREWRITE;
    467 
    468 		bus_dmamap_sync(ahc->parent_dmat, scb->dmamap, 0,
    469 				scb->dmamap->dm_mapsize, op);
    470 
    471 		sg--;
    472 		sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
    473 
    474 		/* Copy the first SG into the "current" data pointer area */
    475 		scb->hscb->dataptr = scb->sg_list->addr;
    476 		scb->hscb->datacnt = scb->sg_list->len;
    477 	} else {
    478 		scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL);
    479 		scb->hscb->dataptr = 0;
    480 		scb->hscb->datacnt = 0;
    481 	}
    482 
    483 	scb->sg_count = nsegments;
    484 
    485 	ahc_lock(ahc, &s);
    486 
    487 	/*
    488 	 * Last time we need to check if this SCB needs to
    489 	 * be aborted.
    490 	 */
    491 	if (xs->xs_status & XS_STS_DONE) {
    492 		if (nsegments != 0)
    493 			bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap);
    494 		ahc_free_scb(ahc, scb);
    495 		ahc_unlock(ahc, &s);
    496 		scsipi_done(xs);
    497 		return;
    498 	}
    499 
    500 	tinfo = ahc_fetch_transinfo(ahc, ahc->channel,
    501 				    SCSIID_OUR_ID(scb->hscb->scsiid),
    502 				    SCSIID_TARGET(ahc, scb->hscb->scsiid),
    503 				    &tstate);
    504 
    505 	mask = SCB_GET_TARGET_MASK(ahc, scb);
    506 	scb->hscb->scsirate = tinfo->scsirate;
    507 	scb->hscb->scsioffset = tinfo->curr.offset;
    508 
    509 	if ((tstate->ultraenb & mask) != 0)
    510 		scb->hscb->control |= ULTRAENB;
    511 
    512 	if ((tstate->discenable & mask) != 0)
    513 	    	scb->hscb->control |= DISCENB;
    514 
    515 	if (xs->xs_tag_type)
    516 		scb->hscb->control |= xs->xs_tag_type;
    517 
    518 	if ((xs->xs_control & XS_CTL_DISCOVERY) && (tinfo->goal.width == 0
    519 	     && tinfo->goal.offset == 0
    520 	     && tinfo->goal.ppr_options == 0)) {
    521 		scb->flags |= SCB_NEGOTIATE;
    522 		scb->hscb->control |= MK_MESSAGE;
    523 	} else if ((tstate->auto_negotiate & mask) != 0) {
    524 		scb->flags |= SCB_AUTO_NEGOTIATE;
    525 		scb->hscb->control |= MK_MESSAGE;
    526 	}
    527 
    528 	LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links);
    529 
    530 	if (!(xs->xs_control & XS_CTL_POLL)) {
    531 		callout_reset(&scb->xs->xs_callout, xs->timeout > 1000000 ?
    532 			      (xs->timeout / 1000) * hz : (xs->timeout * hz) / 1000,
    533 			      ahc_timeout, scb);
    534 	}
    535 
    536 	/*
    537 	 * We only allow one untagged transaction
    538 	 * per target in the initiator role unless
    539 	 * we are storing a full busy target *lun*
    540 	 * table in SCB space.
    541 	 */
    542 	if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0
    543 	    && (ahc->flags & AHC_SCB_BTT) == 0) {
    544 		struct scb_tailq *untagged_q;
    545 		int target_offset;
    546 
    547 		target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
    548 		untagged_q = &(ahc->untagged_queues[target_offset]);
    549 		TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
    550 		scb->flags |= SCB_UNTAGGEDQ;
    551 		if (TAILQ_FIRST(untagged_q) != scb) {
    552 			ahc_unlock(ahc, &s);
    553 			return;
    554 		}
    555 	}
    556 	scb->flags |= SCB_ACTIVE;
    557 
    558 	if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) {
    559 		/* Define a mapping from our tag to the SCB. */
    560 		ahc->scb_data->scbindex[scb->hscb->tag] = scb;
    561 		ahc_pause(ahc);
    562 		if ((ahc->flags & AHC_PAGESCBS) == 0)
    563 			ahc_outb(ahc, SCBPTR, scb->hscb->tag);
    564 		ahc_outb(ahc, TARG_IMMEDIATE_SCB, scb->hscb->tag);
    565 		ahc_unpause(ahc);
    566 	} else {
    567 		ahc_queue_scb(ahc, scb);
    568 	}
    569 
    570 	if (!(xs->xs_control & XS_CTL_POLL)) {
    571 		ahc_unlock(ahc, &s);
    572 		return;
    573 	}
    574 
    575 	/*
    576 	 * If we can't use interrupts, poll for completion
    577 	 */
    578 	SC_DEBUG(xs->xs_periph, SCSIPI_DB3, ("cmd_poll\n"));
    579 	do {
    580 		if (ahc_poll(ahc, xs->timeout)) {
    581 			if (!(xs->xs_control & XS_CTL_SILENT))
    582 				printf("cmd fail\n");
    583 			ahc_timeout(scb);
    584 			break;
    585 		}
    586 	} while (!(xs->xs_status & XS_STS_DONE));
    587 	ahc_unlock(ahc, &s);
    588 
    589 	return;
    590 }
    591 
    592 static int
    593 ahc_poll(struct ahc_softc *ahc, int wait)
    594 {
    595 	while (--wait) {
    596 		DELAY(1000);
    597 		if (ahc_inb(ahc, INTSTAT) & INT_PEND)
    598 			break;
    599 	}
    600 
    601 	if (wait == 0) {
    602 		printf("%s: board is not responding\n", ahc_name(ahc));
    603 		return (EIO);
    604 	}
    605 
    606 	ahc_intr((void *)ahc);
    607 	return (0);
    608 }
    609 
    610 static void
    611 ahc_setup_data(struct ahc_softc *ahc, struct scsipi_xfer *xs,
    612 	       struct scb *scb)
    613 {
    614 	struct hardware_scb *hscb;
    615 
    616 	hscb = scb->hscb;
    617 	xs->resid = xs->status = 0;
    618 
    619 	hscb->cdb_len = xs->cmdlen;
    620 	if (hscb->cdb_len > sizeof(hscb->cdb32)) {
    621 		u_long s;
    622 
    623 		ahc_set_transaction_status(scb, CAM_REQ_INVALID);
    624 		ahc_lock(ahc, &s);
    625 		ahc_free_scb(ahc, scb);
    626 		ahc_unlock(ahc, &s);
    627 		scsipi_done(xs);
    628 		return;
    629 	}
    630 
    631 	if (hscb->cdb_len > 12) {
    632 		memcpy(hscb->cdb32, xs->cmd, hscb->cdb_len);
    633 		scb->flags |= SCB_CDB32_PTR;
    634 	} else {
    635 		memcpy(hscb->shared_data.cdb, xs->cmd, hscb->cdb_len);
    636 	}
    637 
    638 	/* Only use S/G if there is a transfer */
    639 	if (xs->datalen) {
    640 		int error;
    641 
    642                 error = bus_dmamap_load(ahc->parent_dmat,
    643 					scb->dmamap, xs->data,
    644 					xs->datalen, NULL,
    645 					((xs->xs_control & XS_CTL_NOSLEEP) ?
    646 					 BUS_DMA_NOWAIT : BUS_DMA_WAITOK) |
    647 					BUS_DMA_STREAMING |
    648 					((xs->xs_control & XS_CTL_DATA_IN) ?
    649 					 BUS_DMA_READ : BUS_DMA_WRITE));
    650                 if (error) {
    651 #ifdef AHC_DEBUG
    652                         printf("%s: in ahc_setup_data(): bus_dmamap_load() "
    653 			       "= %d\n",
    654 			       ahc_name(ahc), error);
    655 #endif
    656                         xs->error = XS_RESOURCE_SHORTAGE;
    657                         scsipi_done(xs);
    658                         return;
    659                 }
    660                 ahc_execute_scb(scb,
    661 				scb->dmamap->dm_segs,
    662 				scb->dmamap->dm_nsegs);
    663 	} else {
    664 		ahc_execute_scb(scb, NULL, 0);
    665 	}
    666 }
    667 
    668 static void
    669 ahc_set_recoveryscb(struct ahc_softc *ahc, struct scb *scb) {
    670 
    671 	if ((scb->flags & SCB_RECOVERY_SCB) == 0) {
    672 		struct scb *list_scb;
    673 
    674 		scb->flags |= SCB_RECOVERY_SCB;
    675 
    676 		/*
    677 		 * Take all queued, but not sent SCBs out of the equation.
    678 		 * Also ensure that no new CCBs are queued to us while we
    679 		 * try to fix this problem.
    680 		 */
    681 		scsipi_channel_freeze(&ahc->sc_channel, 1);
    682 		if (ahc->features & AHC_TWIN)
    683 			scsipi_channel_freeze(&ahc->sc_channel_b, 1);
    684 
    685 		/*
    686 		 * Go through all of our pending SCBs and remove
    687 		 * any scheduled timeouts for them.  We will reschedule
    688 		 * them after we've successfully fixed this problem.
    689 		 */
    690 		LIST_FOREACH(list_scb, &ahc->pending_scbs, pending_links) {
    691 			callout_stop(&list_scb->xs->xs_callout);
    692 		}
    693 	}
    694 }
    695 
    696 void
    697 ahc_timeout(void *arg)
    698 {
    699 	struct	scb *scb;
    700 	struct	ahc_softc *ahc;
    701 	long	s;
    702 	int	found;
    703 	u_int	last_phase;
    704 	int	target;
    705 	int	lun;
    706 	int	i;
    707 	char	channel;
    708 
    709 	scb = (struct scb *)arg;
    710 	ahc = (struct ahc_softc *)scb->ahc_softc;
    711 
    712 	ahc_lock(ahc, &s);
    713 
    714 	ahc_pause_and_flushwork(ahc);
    715 
    716 	if ((scb->flags & SCB_ACTIVE) == 0) {
    717 		/* Previous timeout took care of me already */
    718 		printf("%s: Timedout SCB already complete. "
    719 		       "Interrupts may not be functioning.\n", ahc_name(ahc));
    720 		ahc_unpause(ahc);
    721 		ahc_unlock(ahc, &s);
    722 		return;
    723 	}
    724 
    725 	target = SCB_GET_TARGET(ahc, scb);
    726 	channel = SCB_GET_CHANNEL(ahc, scb);
    727 	lun = SCB_GET_LUN(scb);
    728 
    729 	ahc_print_path(ahc, scb);
    730 	printf("SCB 0x%x - timed out\n", scb->hscb->tag);
    731 	ahc_dump_card_state(ahc);
    732 	last_phase = ahc_inb(ahc, LASTPHASE);
    733 	if (scb->sg_count > 0) {
    734 		for (i = 0; i < scb->sg_count; i++) {
    735 			printf("sg[%d] - Addr 0x%x : Length %d\n",
    736 			       i,
    737 			       scb->sg_list[i].addr,
    738 			       scb->sg_list[i].len & AHC_SG_LEN_MASK);
    739 		}
    740 	}
    741 	if (scb->flags & (SCB_DEVICE_RESET|SCB_ABORT)) {
    742 		/*
    743 		 * Been down this road before.
    744 		 * Do a full bus reset.
    745 		 */
    746 bus_reset:
    747 		ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
    748 		found = ahc_reset_channel(ahc, channel, /*Initiate Reset*/TRUE);
    749 		printf("%s: Issued Channel %c Bus Reset. "
    750 		       "%d SCBs aborted\n", ahc_name(ahc), channel, found);
    751 	} else {
    752 		/*
    753 		 * If we are a target, transition to bus free and report
    754 		 * the timeout.
    755 		 *
    756 		 * The target/initiator that is holding up the bus may not
    757 		 * be the same as the one that triggered this timeout
    758 		 * (different commands have different timeout lengths).
    759 		 * If the bus is idle and we are actiing as the initiator
    760 		 * for this request, queue a BDR message to the timed out
    761 		 * target.  Otherwise, if the timed out transaction is
    762 		 * active:
    763 		 *   Initiator transaction:
    764 		 *	Stuff the message buffer with a BDR message and assert
    765 		 *	ATN in the hopes that the target will let go of the bus
    766 		 *	and go to the mesgout phase.  If this fails, we'll
    767 		 *	get another timeout 2 seconds later which will attempt
    768 		 *	a bus reset.
    769 		 *
    770 		 *   Target transaction:
    771 		 *	Transition to BUS FREE and report the error.
    772 		 *	It's good to be the target!
    773 		 */
    774 		u_int active_scb_index;
    775 		u_int saved_scbptr;
    776 
    777 		saved_scbptr = ahc_inb(ahc, SCBPTR);
    778 		active_scb_index = ahc_inb(ahc, SCB_TAG);
    779 
    780 		if ((ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) == 0
    781 		  && (active_scb_index < ahc->scb_data->numscbs)) {
    782 			struct scb *active_scb;
    783 
    784 			/*
    785 			 * If the active SCB is not us, assume that
    786 			 * the active SCB has a longer timeout than
    787 			 * the timedout SCB, and wait for the active
    788 			 * SCB to timeout.
    789 			 */
    790 			active_scb = ahc_lookup_scb(ahc, active_scb_index);
    791 			if (active_scb != scb) {
    792 				uint64_t newtimeout;
    793 
    794 				ahc_print_path(ahc, scb);
    795 				printf("Other SCB Timeout%s",
    796 			 	       (scb->flags & SCB_OTHERTCL_TIMEOUT) != 0
    797 				       ? " again\n" : "\n");
    798 				scb->flags |= SCB_OTHERTCL_TIMEOUT;
    799 				newtimeout = MAX(active_scb->xs->timeout,
    800 						 scb->xs->timeout);
    801 				callout_reset(&scb->xs->xs_callout,
    802 				    newtimeout > 1000000 ?
    803 				    (newtimeout / 1000) * hz :
    804 				    (newtimeout * hz) / 1000,
    805 				    ahc_timeout, scb);
    806 				ahc_unpause(ahc);
    807 				ahc_unlock(ahc, &s);
    808 				return;
    809 			}
    810 
    811 			/* It's us */
    812 			if ((scb->flags & SCB_TARGET_SCB) != 0) {
    813 
    814 				/*
    815 				 * Send back any queued up transactions
    816 				 * and properly record the error condition.
    817 				 */
    818 				ahc_abort_scbs(ahc, SCB_GET_TARGET(ahc, scb),
    819 					       SCB_GET_CHANNEL(ahc, scb),
    820 					       SCB_GET_LUN(scb),
    821 					       scb->hscb->tag,
    822 					       ROLE_TARGET,
    823 					       CAM_CMD_TIMEOUT);
    824 
    825 				/* Will clear us from the bus */
    826 				ahc_restart(ahc);
    827 				ahc_unlock(ahc, &s);
    828 				return;
    829 			}
    830 
    831 			ahc_set_recoveryscb(ahc, active_scb);
    832 			ahc_outb(ahc, MSG_OUT, HOST_MSG);
    833 			ahc_outb(ahc, SCSISIGO, last_phase|ATNO);
    834 			ahc_print_path(ahc, active_scb);
    835 			printf("BDR message in message buffer\n");
    836 			active_scb->flags |= SCB_DEVICE_RESET;
    837 			callout_reset(&active_scb->xs->xs_callout,
    838 				      2 * hz, ahc_timeout, active_scb);
    839 			ahc_unpause(ahc);
    840 		} else {
    841 			int	 disconnected;
    842 
    843 			/* XXX Shouldn't panic.  Just punt instead? */
    844 			if ((scb->flags & SCB_TARGET_SCB) != 0)
    845 				panic("Timed-out target SCB but bus idle");
    846 
    847 			if (last_phase != P_BUSFREE
    848 			 && (ahc_inb(ahc, SSTAT0) & TARGET) != 0) {
    849 				/* XXX What happened to the SCB? */
    850 				/* Hung target selection.  Goto busfree */
    851 				printf("%s: Hung target selection\n",
    852 				       ahc_name(ahc));
    853 				ahc_restart(ahc);
    854 				ahc_unlock(ahc, &s);
    855 				return;
    856 			}
    857 
    858 			if (ahc_search_qinfifo(ahc, target, channel, lun,
    859 					       scb->hscb->tag, ROLE_INITIATOR,
    860 					       /*status*/0, SEARCH_COUNT) > 0) {
    861 				disconnected = FALSE;
    862 			} else {
    863 				disconnected = TRUE;
    864 			}
    865 
    866 			if (disconnected) {
    867 
    868 				ahc_set_recoveryscb(ahc, scb);
    869 				/*
    870 				 * Actually re-queue this SCB in an attempt
    871 				 * to select the device before it reconnects.
    872 				 * In either case (selection or reselection),
    873 				 * we will now issue a target reset to the
    874 				 * timed-out device.
    875 				 *
    876 				 * Set the MK_MESSAGE control bit indicating
    877 				 * that we desire to send a message.  We
    878 				 * also set the disconnected flag since
    879 				 * in the paging case there is no guarantee
    880 				 * that our SCB control byte matches the
    881 				 * version on the card.  We don't want the
    882 				 * sequencer to abort the command thinking
    883 				 * an unsolicited reselection occurred.
    884 				 */
    885 				scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
    886 				scb->flags |= SCB_DEVICE_RESET;
    887 
    888 				/*
    889 				 * Remove any cached copy of this SCB in the
    890 				 * disconnected list in preparation for the
    891 				 * queuing of our abort SCB.  We use the
    892 				 * same element in the SCB, SCB_NEXT, for
    893 				 * both the qinfifo and the disconnected list.
    894 				 */
    895 				ahc_search_disc_list(ahc, target, channel,
    896 						     lun, scb->hscb->tag,
    897 						     /*stop_on_first*/TRUE,
    898 						     /*remove*/TRUE,
    899 						     /*save_state*/FALSE);
    900 
    901 				/*
    902 				 * In the non-paging case, the sequencer will
    903 				 * never re-reference the in-core SCB.
    904 				 * To make sure we are notified during
    905 				 * reslection, set the MK_MESSAGE flag in
    906 				 * the card's copy of the SCB.
    907 				 */
    908 				if ((ahc->flags & AHC_PAGESCBS) == 0) {
    909 					ahc_outb(ahc, SCBPTR, scb->hscb->tag);
    910 					ahc_outb(ahc, SCB_CONTROL,
    911 						 ahc_inb(ahc, SCB_CONTROL)
    912 						| MK_MESSAGE);
    913 				}
    914 
    915 				/*
    916 				 * Clear out any entries in the QINFIFO first
    917 				 * so we are the next SCB for this target
    918 				 * to run.
    919 				 */
    920 				ahc_search_qinfifo(ahc,
    921 						   SCB_GET_TARGET(ahc, scb),
    922 						   channel, SCB_GET_LUN(scb),
    923 						   SCB_LIST_NULL,
    924 						   ROLE_INITIATOR,
    925 						   CAM_REQUEUE_REQ,
    926 						   SEARCH_COMPLETE);
    927 				ahc_print_path(ahc, scb);
    928 				printf("Queuing a BDR SCB\n");
    929 				ahc_qinfifo_requeue_tail(ahc, scb);
    930 				ahc_outb(ahc, SCBPTR, saved_scbptr);
    931 				callout_reset(&scb->xs->xs_callout, 2 * hz,
    932 					      ahc_timeout, scb);
    933 				ahc_unpause(ahc);
    934 			} else {
    935 				/* Go "immediatly" to the bus reset */
    936 				/* This shouldn't happen */
    937 				ahc_set_recoveryscb(ahc, scb);
    938 				ahc_print_path(ahc, scb);
    939 				printf("SCB %d: Immediate reset.  "
    940 					"Flags = 0x%x\n", scb->hscb->tag,
    941 					scb->flags);
    942 				goto bus_reset;
    943 			}
    944 		}
    945 	}
    946 	ahc_unlock(ahc, &s);
    947 }
    948 
    949 void
    950 ahc_platform_set_tags(struct ahc_softc *ahc,
    951 		      struct ahc_devinfo *devinfo, int enable)
    952 {
    953 	struct ahc_initiator_tinfo *tinfo;
    954         struct ahc_tmode_tstate *tstate;
    955 
    956         tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
    957                                     devinfo->target, &tstate);
    958 
    959         if (enable)
    960                 tstate->tagenable |= devinfo->target_mask;
    961 	else
    962 	  	tstate->tagenable &= ~devinfo->target_mask;
    963 }
    964 
    965 int
    966 ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
    967 {
    968 	if (sizeof(struct ahc_platform_data) == 0)
    969 		return 0;
    970 	ahc->platform_data = malloc(sizeof(struct ahc_platform_data), M_DEVBUF,
    971 				    M_NOWAIT);
    972 	if (ahc->platform_data == NULL)
    973 		return (ENOMEM);
    974 	return (0);
    975 }
    976 
    977 void
    978 ahc_platform_free(struct ahc_softc *ahc)
    979 {
    980 	if (sizeof(struct ahc_platform_data) == 0)
    981 		return;
    982 	free(ahc->platform_data, M_DEVBUF);
    983 }
    984 
    985 int
    986 ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc)
    987 {
    988 	return (0);
    989 }
    990 
    991 int
    992 ahc_detach(struct device *self, int flags)
    993 {
    994 	int rv = 0;
    995 
    996 	struct ahc_softc *ahc = (struct ahc_softc*)self;
    997 
    998 	ahc_intr_enable(ahc, FALSE);
    999 	if (ahc->sc_child != NULL)
   1000 		rv = config_detach(ahc->sc_child, flags);
   1001 	if (rv == 0 && ahc->sc_child_b != NULL)
   1002 		rv = config_detach(ahc->sc_child_b, flags);
   1003 
   1004 	shutdownhook_disestablish(ahc->shutdown_hook);
   1005 
   1006 	ahc_free(ahc);
   1007 
   1008 	return (rv);
   1009 }
   1010 
   1011 
   1012 void
   1013 ahc_send_async(struct ahc_softc *ahc, char channel, u_int target, u_int lun,
   1014 	       ac_code code, void *opt_arg)
   1015 {
   1016 	struct ahc_tmode_tstate *tstate;
   1017 	struct ahc_initiator_tinfo *tinfo;
   1018 	struct ahc_devinfo devinfo;
   1019 	struct scsipi_channel *chan;
   1020 	struct scsipi_xfer_mode xm;
   1021 
   1022 	chan = channel == 'B' ? &ahc->sc_channel_b : &ahc->sc_channel;
   1023 	switch (code) {
   1024 	case AC_TRANSFER_NEG:
   1025 		tinfo = ahc_fetch_transinfo(ahc, channel, ahc->our_id, target,
   1026 			    &tstate);
   1027 		ahc_compile_devinfo(&devinfo, ahc->our_id, target, lun,
   1028 		    channel, ROLE_UNKNOWN);
   1029 		/*
   1030 		 * Don't bother if negotiating. XXX?
   1031 		 */
   1032 		if (tinfo->curr.period != tinfo->goal.period
   1033 		    || tinfo->curr.width != tinfo->goal.width
   1034 		    || tinfo->curr.offset != tinfo->goal.offset
   1035 		    || tinfo->curr.ppr_options != tinfo->goal.ppr_options)
   1036 			break;
   1037 		xm.xm_target = target;
   1038 		xm.xm_mode = 0;
   1039 		xm.xm_period = tinfo->curr.period;
   1040 		xm.xm_offset = tinfo->curr.offset;
   1041 		if (tinfo->curr.width == MSG_EXT_WDTR_BUS_16_BIT)
   1042 			xm.xm_mode |= PERIPH_CAP_WIDE16;
   1043 		if (tinfo->curr.period)
   1044 			xm.xm_mode |= PERIPH_CAP_SYNC;
   1045 		if (tstate->tagenable & devinfo.target_mask)
   1046 			xm.xm_mode |= PERIPH_CAP_TQING;
   1047 		scsipi_async_event(chan, ASYNC_EVENT_XFER_MODE, &xm);
   1048 		break;
   1049 	case AC_BUS_RESET:
   1050 		scsipi_async_event(chan, ASYNC_EVENT_RESET, NULL);
   1051 	case AC_SENT_BDR:
   1052 	default:
   1053 		break;
   1054 	}
   1055 }
   1056