aic7xxx_osm.c revision 150450
1/*-
2 * Bus independent FreeBSD shim for the aic7xxx based Adaptec SCSI controllers
3 *
4 * Copyright (c) 1994-2001 Justin T. Gibbs.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions, and the following disclaimer,
12 *    without modification.
13 * 2. The name of the author may not be used to endorse or promote products
14 *    derived from this software without specific prior written permission.
15 *
16 * Alternatively, this software may be distributed under the terms of the
17 * GNU Public License ("GPL").
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic7xxx_osm.c#20 $
32 */
33
34#include <sys/cdefs.h>
35__FBSDID("$FreeBSD: head/sys/dev/aic7xxx/aic7xxx_osm.c 150450 2005-09-22 05:01:37Z gibbs $");
36
37#include <dev/aic7xxx/aic7xxx_osm.h>
38#include <dev/aic7xxx/aic7xxx_inline.h>
39
40#include <sys/kthread.h>
41
42#ifndef AHC_TMODE_ENABLE
43#define AHC_TMODE_ENABLE 0
44#endif
45
46#include <dev/aic7xxx/aic_osm_lib.c>
47
48#define ccb_scb_ptr spriv_ptr0
49
50devclass_t ahc_devclass;
51
52#if UNUSED
53static void	ahc_dump_targcmd(struct target_cmd *cmd);
54#endif
55static int	ahc_modevent(module_t mod, int type, void *data);
56static void	ahc_action(struct cam_sim *sim, union ccb *ccb);
57static void	ahc_get_tran_settings(struct ahc_softc *ahc,
58				      int our_id, char channel,
59				      struct ccb_trans_settings *cts);
60static void	ahc_async(void *callback_arg, uint32_t code,
61			  struct cam_path *path, void *arg);
62static void	ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs,
63				int nsegments, int error);
64static void	ahc_poll(struct cam_sim *sim);
65static void	ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim,
66			       struct ccb_scsiio *csio, struct scb *scb);
67static void	ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim,
68			      union ccb *ccb);
69static int	ahc_create_path(struct ahc_softc *ahc,
70				char channel, u_int target, u_int lun,
71				struct cam_path **path);
72
73
74static int
75ahc_create_path(struct ahc_softc *ahc, char channel, u_int target,
76	        u_int lun, struct cam_path **path)
77{
78	path_id_t path_id;
79
80	if (channel == 'B')
81		path_id = cam_sim_path(ahc->platform_data->sim_b);
82	else
83		path_id = cam_sim_path(ahc->platform_data->sim);
84
85	return (xpt_create_path(path, /*periph*/NULL,
86				path_id, target, lun));
87}
88
89int
90ahc_map_int(struct ahc_softc *ahc)
91{
92	int error;
93	int zero;
94	int shareable;
95
96	zero = 0;
97	shareable = (ahc->flags & AHC_EDGE_INTERRUPT) ? 0: RF_SHAREABLE;
98	ahc->platform_data->irq =
99	    bus_alloc_resource_any(ahc->dev_softc, SYS_RES_IRQ, &zero,
100				   RF_ACTIVE | shareable);
101	if (ahc->platform_data->irq == NULL) {
102		device_printf(ahc->dev_softc,
103			      "bus_alloc_resource() failed to allocate IRQ\n");
104		return (ENOMEM);
105	}
106	ahc->platform_data->irq_res_type = SYS_RES_IRQ;
107
108	/* Hook up our interrupt handler */
109	error = bus_setup_intr(ahc->dev_softc, ahc->platform_data->irq,
110			       INTR_TYPE_CAM, ahc_platform_intr, ahc,
111			       &ahc->platform_data->ih);
112
113	if (error != 0)
114		device_printf(ahc->dev_softc, "bus_setup_intr() failed: %d\n",
115			      error);
116	return (error);
117}
118
119int
120aic7770_map_registers(struct ahc_softc *ahc, u_int unused_ioport_arg)
121{
122	struct	resource *regs;
123	int	rid;
124
125	rid = 0;
126	regs = bus_alloc_resource_any(ahc->dev_softc, SYS_RES_IOPORT, &rid,
127				      RF_ACTIVE);
128	if (regs == NULL) {
129		device_printf(ahc->dev_softc, "Unable to map I/O space?!\n");
130		return ENOMEM;
131	}
132	ahc->platform_data->regs_res_type = SYS_RES_IOPORT;
133	ahc->platform_data->regs_res_id = rid,
134	ahc->platform_data->regs = regs;
135	ahc->tag = rman_get_bustag(regs);
136	ahc->bsh = rman_get_bushandle(regs);
137	return (0);
138}
139
140/*
141 * Attach all the sub-devices we can find
142 */
143int
144ahc_attach(struct ahc_softc *ahc)
145{
146	char   ahc_info[256];
147	struct ccb_setasync csa;
148	struct cam_devq *devq;
149	int bus_id;
150	int bus_id2;
151	struct cam_sim *sim;
152	struct cam_sim *sim2;
153	struct cam_path *path;
154	struct cam_path *path2;
155	long s;
156	int count;
157
158	count = 0;
159	sim = NULL;
160	sim2 = NULL;
161
162	/*
163	 * Create a thread to perform all recovery.
164	 */
165	if (ahc_spawn_recovery_thread(ahc) != 0)
166		goto fail;
167
168	ahc_controller_info(ahc, ahc_info);
169	printf("%s\n", ahc_info);
170	ahc_lock(ahc, &s);
171
172	/*
173	 * Attach secondary channel first if the user has
174	 * declared it the primary channel.
175	 */
176	if ((ahc->features & AHC_TWIN) != 0
177	 && (ahc->flags & AHC_PRIMARY_CHANNEL) != 0) {
178		bus_id = 1;
179		bus_id2 = 0;
180	} else {
181		bus_id = 0;
182		bus_id2 = 1;
183	}
184
185	/*
186	 * Create the device queue for our SIM(s).
187	 */
188	devq = cam_simq_alloc(AHC_MAX_QUEUE);
189	if (devq == NULL)
190		goto fail;
191
192	/*
193	 * Construct our first channel SIM entry
194	 */
195	sim = cam_sim_alloc(ahc_action, ahc_poll, "ahc", ahc,
196			    device_get_unit(ahc->dev_softc),
197			    1, AHC_MAX_QUEUE, devq);
198	if (sim == NULL) {
199		cam_simq_free(devq);
200		goto fail;
201	}
202
203	if (xpt_bus_register(sim, bus_id) != CAM_SUCCESS) {
204		cam_sim_free(sim, /*free_devq*/TRUE);
205		sim = NULL;
206		goto fail;
207	}
208
209	if (xpt_create_path(&path, /*periph*/NULL,
210			    cam_sim_path(sim), CAM_TARGET_WILDCARD,
211			    CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
212		xpt_bus_deregister(cam_sim_path(sim));
213		cam_sim_free(sim, /*free_devq*/TRUE);
214		sim = NULL;
215		goto fail;
216	}
217
218	xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5);
219	csa.ccb_h.func_code = XPT_SASYNC_CB;
220	csa.event_enable = AC_LOST_DEVICE;
221	csa.callback = ahc_async;
222	csa.callback_arg = sim;
223	xpt_action((union ccb *)&csa);
224	count++;
225
226	if (ahc->features & AHC_TWIN) {
227		sim2 = cam_sim_alloc(ahc_action, ahc_poll, "ahc",
228				    ahc, device_get_unit(ahc->dev_softc), 1,
229				    AHC_MAX_QUEUE, devq);
230
231		if (sim2 == NULL) {
232			printf("ahc_attach: Unable to attach second "
233			       "bus due to resource shortage");
234			goto fail;
235		}
236
237		if (xpt_bus_register(sim2, bus_id2) != CAM_SUCCESS) {
238			printf("ahc_attach: Unable to attach second "
239			       "bus due to resource shortage");
240			/*
241			 * We do not want to destroy the device queue
242			 * because the first bus is using it.
243			 */
244			cam_sim_free(sim2, /*free_devq*/FALSE);
245			goto fail;
246		}
247
248		if (xpt_create_path(&path2, /*periph*/NULL,
249				    cam_sim_path(sim2),
250				    CAM_TARGET_WILDCARD,
251				    CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
252			xpt_bus_deregister(cam_sim_path(sim2));
253			cam_sim_free(sim2, /*free_devq*/FALSE);
254			sim2 = NULL;
255			goto fail;
256		}
257		xpt_setup_ccb(&csa.ccb_h, path2, /*priority*/5);
258		csa.ccb_h.func_code = XPT_SASYNC_CB;
259		csa.event_enable = AC_LOST_DEVICE;
260		csa.callback = ahc_async;
261		csa.callback_arg = sim2;
262		xpt_action((union ccb *)&csa);
263		count++;
264	}
265
266fail:
267	if ((ahc->features & AHC_TWIN) != 0
268	 && (ahc->flags & AHC_PRIMARY_CHANNEL) != 0) {
269		ahc->platform_data->sim_b = sim;
270		ahc->platform_data->path_b = path;
271		ahc->platform_data->sim = sim2;
272		ahc->platform_data->path = path2;
273	} else {
274		ahc->platform_data->sim = sim;
275		ahc->platform_data->path = path;
276		ahc->platform_data->sim_b = sim2;
277		ahc->platform_data->path_b = path2;
278	}
279
280	if (count != 0) {
281		/* We have to wait until after any system dumps... */
282		ahc->platform_data->eh =
283		    EVENTHANDLER_REGISTER(shutdown_final, ahc_shutdown,
284					  ahc, SHUTDOWN_PRI_DEFAULT);
285		ahc_intr_enable(ahc, TRUE);
286	}
287
288	ahc_unlock(ahc, &s);
289	return (count);
290}
291
292/*
293 * Catch an interrupt from the adapter
294 */
295void
296ahc_platform_intr(void *arg)
297{
298	struct	ahc_softc *ahc;
299
300	ahc = (struct ahc_softc *)arg;
301	ahc_intr(ahc);
302}
303
304/*
305 * We have an scb which has been processed by the
306 * adaptor, now we look to see how the operation
307 * went.
308 */
309void
310ahc_done(struct ahc_softc *ahc, struct scb *scb)
311{
312	union ccb *ccb;
313
314	CAM_DEBUG(scb->io_ctx->ccb_h.path, CAM_DEBUG_TRACE,
315		  ("ahc_done - scb %d\n", scb->hscb->tag));
316
317	ccb = scb->io_ctx;
318	LIST_REMOVE(scb, pending_links);
319	if ((scb->flags & SCB_TIMEDOUT) != 0)
320		LIST_REMOVE(scb, timedout_links);
321	if ((scb->flags & SCB_UNTAGGEDQ) != 0) {
322		struct scb_tailq *untagged_q;
323		int target_offset;
324
325		target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
326		untagged_q = &ahc->untagged_queues[target_offset];
327		TAILQ_REMOVE(untagged_q, scb, links.tqe);
328		scb->flags &= ~SCB_UNTAGGEDQ;
329		ahc_run_untagged_queue(ahc, untagged_q);
330	}
331
332	untimeout(ahc_platform_timeout, (caddr_t)scb, ccb->ccb_h.timeout_ch);
333
334	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
335		bus_dmasync_op_t op;
336
337		if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
338			op = BUS_DMASYNC_POSTREAD;
339		else
340			op = BUS_DMASYNC_POSTWRITE;
341		bus_dmamap_sync(ahc->buffer_dmat, scb->dmamap, op);
342		bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap);
343	}
344
345	if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) {
346		struct cam_path *ccb_path;
347
348		/*
349		 * If we have finally disconnected, clean up our
350		 * pending device state.
351		 * XXX - There may be error states that cause where
352		 *       we will remain connected.
353		 */
354		ccb_path = ccb->ccb_h.path;
355		if (ahc->pending_device != NULL
356		 && xpt_path_comp(ahc->pending_device->path, ccb_path) == 0) {
357
358			if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
359				ahc->pending_device = NULL;
360			} else {
361				if (bootverbose) {
362					xpt_print_path(ccb->ccb_h.path);
363					printf("Still connected\n");
364				}
365				aic_freeze_ccb(ccb);
366			}
367		}
368
369		if (aic_get_transaction_status(scb) == CAM_REQ_INPROG)
370			ccb->ccb_h.status |= CAM_REQ_CMP;
371		ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
372		ahc_free_scb(ahc, scb);
373		xpt_done(ccb);
374		return;
375	}
376
377	/*
378	 * If the recovery SCB completes, we have to be
379	 * out of our timeout.
380	 */
381	if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
382		struct	scb *list_scb;
383
384		ahc->scb_data->recovery_scbs--;
385
386		if (aic_get_transaction_status(scb) == CAM_BDR_SENT
387		 || aic_get_transaction_status(scb) == CAM_REQ_ABORTED)
388			aic_set_transaction_status(scb, CAM_CMD_TIMEOUT);
389
390		if (ahc->scb_data->recovery_scbs == 0) {
391			/*
392			 * All recovery actions have completed successfully,
393			 * so reinstate the timeouts for all other pending
394			 * commands.
395			 */
396			LIST_FOREACH(list_scb, &ahc->pending_scbs,
397				     pending_links) {
398
399				aic_scb_timer_reset(list_scb,
400						    aic_get_timeout(scb));
401			}
402
403			ahc_print_path(ahc, scb);
404			printf("no longer in timeout, status = %x\n",
405			       ccb->ccb_h.status);
406		}
407	}
408
409	/* Don't clobber any existing error state */
410	if (aic_get_transaction_status(scb) == CAM_REQ_INPROG) {
411		ccb->ccb_h.status |= CAM_REQ_CMP;
412	} else if ((scb->flags & SCB_SENSE) != 0) {
413		/*
414		 * We performed autosense retrieval.
415		 *
416		 * Zero any sense not transferred by the
417		 * device.  The SCSI spec mandates that any
418		 * untransfered data should be assumed to be
419		 * zero.  Complete the 'bounce' of sense information
420		 * through buffers accessible via bus-space by
421		 * copying it into the clients csio.
422		 */
423		memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
424		memcpy(&ccb->csio.sense_data,
425		       ahc_get_sense_buf(ahc, scb),
426		       (aic_le32toh(scb->sg_list->len) & AHC_SG_LEN_MASK)
427		       - ccb->csio.sense_resid);
428		scb->io_ctx->ccb_h.status |= CAM_AUTOSNS_VALID;
429	}
430	ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
431	ahc_free_scb(ahc, scb);
432	xpt_done(ccb);
433}
434
435static void
436ahc_action(struct cam_sim *sim, union ccb *ccb)
437{
438	struct	ahc_softc *ahc;
439	struct	ahc_tmode_lstate *lstate;
440	u_int	target_id;
441	u_int	our_id;
442	long	s;
443
444	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahc_action\n"));
445
446	ahc = (struct ahc_softc *)cam_sim_softc(sim);
447
448	target_id = ccb->ccb_h.target_id;
449	our_id = SIM_SCSI_ID(ahc, sim);
450
451	switch (ccb->ccb_h.func_code) {
452	/* Common cases first */
453	case XPT_ACCEPT_TARGET_IO:	/* Accept Host Target Mode CDB */
454	case XPT_CONT_TARGET_IO:/* Continue Host Target I/O Connection*/
455	{
456		struct	   ahc_tmode_tstate *tstate;
457		cam_status status;
458
459		status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate,
460					     &lstate, TRUE);
461
462		if (status != CAM_REQ_CMP) {
463			if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) {
464				/* Response from the black hole device */
465				tstate = NULL;
466				lstate = ahc->black_hole;
467			} else {
468				ccb->ccb_h.status = status;
469				xpt_done(ccb);
470				break;
471			}
472		}
473		if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) {
474
475			ahc_lock(ahc, &s);
476			SLIST_INSERT_HEAD(&lstate->accept_tios, &ccb->ccb_h,
477					  sim_links.sle);
478			ccb->ccb_h.status = CAM_REQ_INPROG;
479			if ((ahc->flags & AHC_TQINFIFO_BLOCKED) != 0)
480				ahc_run_tqinfifo(ahc, /*paused*/FALSE);
481			ahc_unlock(ahc, &s);
482			break;
483		}
484
485		/*
486		 * The target_id represents the target we attempt to
487		 * select.  In target mode, this is the initiator of
488		 * the original command.
489		 */
490		our_id = target_id;
491		target_id = ccb->csio.init_id;
492		/* FALLTHROUGH */
493	}
494	case XPT_SCSI_IO:	/* Execute the requested I/O operation */
495	case XPT_RESET_DEV:	/* Bus Device Reset the specified SCSI device */
496	{
497		struct	scb *scb;
498		struct	hardware_scb *hscb;
499
500		if ((ahc->flags & AHC_INITIATORROLE) == 0
501		 && (ccb->ccb_h.func_code == XPT_SCSI_IO
502		  || ccb->ccb_h.func_code == XPT_RESET_DEV)) {
503			ccb->ccb_h.status = CAM_PROVIDE_FAIL;
504			xpt_done(ccb);
505			return;
506		}
507
508		/*
509		 * get an scb to use.
510		 */
511		ahc_lock(ahc, &s);
512		if ((scb = ahc_get_scb(ahc)) == NULL) {
513
514			xpt_freeze_simq(sim, /*count*/1);
515			ahc->flags |= AHC_RESOURCE_SHORTAGE;
516			ahc_unlock(ahc, &s);
517			ccb->ccb_h.status = CAM_REQUEUE_REQ;
518			xpt_done(ccb);
519			return;
520		}
521		ahc_unlock(ahc, &s);
522
523		hscb = scb->hscb;
524
525		CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE,
526			  ("start scb(%p)\n", scb));
527		scb->io_ctx = ccb;
528		/*
529		 * So we can find the SCB when an abort is requested
530		 */
531		ccb->ccb_h.ccb_scb_ptr = scb;
532
533		/*
534		 * Put all the arguments for the xfer in the scb
535		 */
536		hscb->control = 0;
537		hscb->scsiid = BUILD_SCSIID(ahc, sim, target_id, our_id);
538		hscb->lun = ccb->ccb_h.target_lun;
539		if (ccb->ccb_h.func_code == XPT_RESET_DEV) {
540			hscb->cdb_len = 0;
541			scb->flags |= SCB_DEVICE_RESET;
542			hscb->control |= MK_MESSAGE;
543			ahc_execute_scb(scb, NULL, 0, 0);
544		} else {
545			if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) {
546				struct target_data *tdata;
547
548				tdata = &hscb->shared_data.tdata;
549				if (ahc->pending_device == lstate)
550					scb->flags |= SCB_TARGET_IMMEDIATE;
551				hscb->control |= TARGET_SCB;
552				scb->flags |= SCB_TARGET_SCB;
553				tdata->target_phases = 0;
554				if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
555					tdata->target_phases |= SPHASE_PENDING;
556					tdata->scsi_status =
557					    ccb->csio.scsi_status;
558				}
559	 			if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT)
560					tdata->target_phases |= NO_DISCONNECT;
561
562				tdata->initiator_tag = ccb->csio.tag_id;
563			}
564			if (ccb->ccb_h.flags & CAM_TAG_ACTION_VALID)
565				hscb->control |= ccb->csio.tag_action;
566
567			ahc_setup_data(ahc, sim, &ccb->csio, scb);
568		}
569		break;
570	}
571	case XPT_NOTIFY_ACK:
572	case XPT_IMMED_NOTIFY:
573	{
574		struct	   ahc_tmode_tstate *tstate;
575		struct	   ahc_tmode_lstate *lstate;
576		cam_status status;
577
578		status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate,
579					     &lstate, TRUE);
580
581		if (status != CAM_REQ_CMP) {
582			ccb->ccb_h.status = status;
583			xpt_done(ccb);
584			break;
585		}
586		SLIST_INSERT_HEAD(&lstate->immed_notifies, &ccb->ccb_h,
587				  sim_links.sle);
588		ccb->ccb_h.status = CAM_REQ_INPROG;
589		ahc_send_lstate_events(ahc, lstate);
590		break;
591	}
592	case XPT_EN_LUN:		/* Enable LUN as a target */
593		ahc_handle_en_lun(ahc, sim, ccb);
594		xpt_done(ccb);
595		break;
596	case XPT_ABORT:			/* Abort the specified CCB */
597	{
598		ahc_abort_ccb(ahc, sim, ccb);
599		break;
600	}
601	case XPT_SET_TRAN_SETTINGS:
602	{
603#ifdef AHC_NEW_TRAN_SETTINGS
604		struct	ahc_devinfo devinfo;
605		struct	ccb_trans_settings *cts;
606		struct	ccb_trans_settings_scsi *scsi;
607		struct	ccb_trans_settings_spi *spi;
608		struct	ahc_initiator_tinfo *tinfo;
609		struct	ahc_tmode_tstate *tstate;
610		uint16_t *discenable;
611		uint16_t *tagenable;
612		u_int	update_type;
613
614		cts = &ccb->cts;
615		scsi = &cts->proto_specific.scsi;
616		spi = &cts->xport_specific.spi;
617		ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim),
618				    cts->ccb_h.target_id,
619				    cts->ccb_h.target_lun,
620				    SIM_CHANNEL(ahc, sim),
621				    ROLE_UNKNOWN);
622		tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
623					    devinfo.our_scsiid,
624					    devinfo.target, &tstate);
625		update_type = 0;
626		if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
627			update_type |= AHC_TRANS_GOAL;
628			discenable = &tstate->discenable;
629			tagenable = &tstate->tagenable;
630			tinfo->curr.protocol_version =
631			    cts->protocol_version;
632			tinfo->curr.transport_version =
633			    cts->transport_version;
634			tinfo->goal.protocol_version =
635			    cts->protocol_version;
636			tinfo->goal.transport_version =
637			    cts->transport_version;
638		} else if (cts->type == CTS_TYPE_USER_SETTINGS) {
639			update_type |= AHC_TRANS_USER;
640			discenable = &ahc->user_discenable;
641			tagenable = &ahc->user_tagenable;
642			tinfo->user.protocol_version =
643			    cts->protocol_version;
644			tinfo->user.transport_version =
645			    cts->transport_version;
646		} else {
647			ccb->ccb_h.status = CAM_REQ_INVALID;
648			xpt_done(ccb);
649			break;
650		}
651
652		ahc_lock(ahc, &s);
653
654		if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
655			if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
656				*discenable |= devinfo.target_mask;
657			else
658				*discenable &= ~devinfo.target_mask;
659		}
660
661		if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
662			if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0)
663				*tagenable |= devinfo.target_mask;
664			else
665				*tagenable &= ~devinfo.target_mask;
666		}
667
668		if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
669			ahc_validate_width(ahc, /*tinfo limit*/NULL,
670					   &spi->bus_width, ROLE_UNKNOWN);
671			ahc_set_width(ahc, &devinfo, spi->bus_width,
672				      update_type, /*paused*/FALSE);
673		}
674
675		if ((spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0) {
676			if (update_type == AHC_TRANS_USER)
677				spi->ppr_options = tinfo->user.ppr_options;
678			else
679				spi->ppr_options = tinfo->goal.ppr_options;
680		}
681
682		if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0) {
683			if (update_type == AHC_TRANS_USER)
684				spi->sync_offset = tinfo->user.offset;
685			else
686				spi->sync_offset = tinfo->goal.offset;
687		}
688
689		if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) {
690			if (update_type == AHC_TRANS_USER)
691				spi->sync_period = tinfo->user.period;
692			else
693				spi->sync_period = tinfo->goal.period;
694		}
695
696		if (((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0)
697		 || ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)) {
698			struct ahc_syncrate *syncrate;
699			u_int maxsync;
700
701			if ((ahc->features & AHC_ULTRA2) != 0)
702				maxsync = AHC_SYNCRATE_DT;
703			else if ((ahc->features & AHC_ULTRA) != 0)
704				maxsync = AHC_SYNCRATE_ULTRA;
705			else
706				maxsync = AHC_SYNCRATE_FAST;
707
708			if (spi->bus_width != MSG_EXT_WDTR_BUS_16_BIT)
709				spi->ppr_options &= ~MSG_EXT_PPR_DT_REQ;
710
711			syncrate = ahc_find_syncrate(ahc, &spi->sync_period,
712						     &spi->ppr_options,
713						     maxsync);
714			ahc_validate_offset(ahc, /*tinfo limit*/NULL,
715					    syncrate, &spi->sync_offset,
716					    spi->bus_width, ROLE_UNKNOWN);
717
718			/* We use a period of 0 to represent async */
719			if (spi->sync_offset == 0) {
720				spi->sync_period = 0;
721				spi->ppr_options = 0;
722			}
723
724			ahc_set_syncrate(ahc, &devinfo, syncrate,
725					 spi->sync_period, spi->sync_offset,
726					 spi->ppr_options, update_type,
727					 /*paused*/FALSE);
728		}
729		ahc_unlock(ahc, &s);
730		ccb->ccb_h.status = CAM_REQ_CMP;
731		xpt_done(ccb);
732#else
733		struct	  ahc_devinfo devinfo;
734		struct	  ccb_trans_settings *cts;
735		struct	  ahc_initiator_tinfo *tinfo;
736		struct	  ahc_tmode_tstate *tstate;
737		uint16_t *discenable;
738		uint16_t *tagenable;
739		u_int	  update_type;
740		long	  s;
741
742		cts = &ccb->cts;
743		ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim),
744				    cts->ccb_h.target_id,
745				    cts->ccb_h.target_lun,
746				    SIM_CHANNEL(ahc, sim),
747				    ROLE_UNKNOWN);
748		tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
749					    devinfo.our_scsiid,
750					    devinfo.target, &tstate);
751		update_type = 0;
752		if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) {
753			update_type |= AHC_TRANS_GOAL;
754			discenable = &tstate->discenable;
755			tagenable = &tstate->tagenable;
756		} else if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) {
757			update_type |= AHC_TRANS_USER;
758			discenable = &ahc->user_discenable;
759			tagenable = &ahc->user_tagenable;
760		} else {
761			ccb->ccb_h.status = CAM_REQ_INVALID;
762			xpt_done(ccb);
763			break;
764		}
765
766		ahc_lock(ahc, &s);
767
768		if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) {
769			if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
770				*discenable |= devinfo.target_mask;
771			else
772				*discenable &= ~devinfo.target_mask;
773		}
774
775		if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) {
776			if ((cts->flags & CCB_TRANS_TAG_ENB) != 0)
777				*tagenable |= devinfo.target_mask;
778			else
779				*tagenable &= ~devinfo.target_mask;
780		}
781
782		if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) {
783			ahc_validate_width(ahc, /*tinfo limit*/NULL,
784					   &cts->bus_width, ROLE_UNKNOWN);
785			ahc_set_width(ahc, &devinfo, cts->bus_width,
786				      update_type, /*paused*/FALSE);
787		}
788
789		if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) == 0) {
790			if (update_type == AHC_TRANS_USER)
791				cts->sync_offset = tinfo->user.offset;
792			else
793				cts->sync_offset = tinfo->goal.offset;
794		}
795
796		if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) == 0) {
797			if (update_type == AHC_TRANS_USER)
798				cts->sync_period = tinfo->user.period;
799			else
800				cts->sync_period = tinfo->goal.period;
801		}
802
803		if (((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0)
804		 || ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0)) {
805			struct ahc_syncrate *syncrate;
806			u_int ppr_options;
807			u_int maxsync;
808
809			if ((ahc->features & AHC_ULTRA2) != 0)
810				maxsync = AHC_SYNCRATE_DT;
811			else if ((ahc->features & AHC_ULTRA) != 0)
812				maxsync = AHC_SYNCRATE_ULTRA;
813			else
814				maxsync = AHC_SYNCRATE_FAST;
815
816			ppr_options = 0;
817			if (cts->sync_period <= 9
818			 && cts->bus_width == MSG_EXT_WDTR_BUS_16_BIT)
819				ppr_options = MSG_EXT_PPR_DT_REQ;
820
821			syncrate = ahc_find_syncrate(ahc, &cts->sync_period,
822						     &ppr_options,
823						     maxsync);
824			ahc_validate_offset(ahc, /*tinfo limit*/NULL,
825					    syncrate, &cts->sync_offset,
826					    MSG_EXT_WDTR_BUS_8_BIT,
827					    ROLE_UNKNOWN);
828
829			/* We use a period of 0 to represent async */
830			if (cts->sync_offset == 0) {
831				cts->sync_period = 0;
832				ppr_options = 0;
833			}
834
835			if (ppr_options == MSG_EXT_PPR_DT_REQ
836			 && tinfo->user.transport_version >= 3) {
837				tinfo->goal.transport_version =
838				    tinfo->user.transport_version;
839				tinfo->curr.transport_version =
840				    tinfo->user.transport_version;
841			}
842
843			ahc_set_syncrate(ahc, &devinfo, syncrate,
844					 cts->sync_period, cts->sync_offset,
845					 ppr_options, update_type,
846					 /*paused*/FALSE);
847		}
848		ahc_unlock(ahc, &s);
849		ccb->ccb_h.status = CAM_REQ_CMP;
850		xpt_done(ccb);
851#endif
852		break;
853	}
854	case XPT_GET_TRAN_SETTINGS:
855	/* Get default/user set transfer settings for the target */
856	{
857
858		ahc_lock(ahc, &s);
859		ahc_get_tran_settings(ahc, SIM_SCSI_ID(ahc, sim),
860				      SIM_CHANNEL(ahc, sim), &ccb->cts);
861		ahc_unlock(ahc, &s);
862		xpt_done(ccb);
863		break;
864	}
865	case XPT_CALC_GEOMETRY:
866	{
867		int extended;
868
869		extended = SIM_IS_SCSIBUS_B(ahc, sim)
870			 ? ahc->flags & AHC_EXTENDED_TRANS_B
871			 : ahc->flags & AHC_EXTENDED_TRANS_A;
872		aic_calc_geometry(&ccb->ccg, extended);
873		xpt_done(ccb);
874		break;
875	}
876	case XPT_RESET_BUS:		/* Reset the specified SCSI bus */
877	{
878		int  found;
879
880		ahc_lock(ahc, &s);
881		found = ahc_reset_channel(ahc, SIM_CHANNEL(ahc, sim),
882					  /*initiate reset*/TRUE);
883		ahc_unlock(ahc, &s);
884		if (bootverbose) {
885			xpt_print_path(SIM_PATH(ahc, sim));
886			printf("SCSI bus reset delivered. "
887			       "%d SCBs aborted.\n", found);
888		}
889		ccb->ccb_h.status = CAM_REQ_CMP;
890		xpt_done(ccb);
891		break;
892	}
893	case XPT_TERM_IO:		/* Terminate the I/O process */
894		/* XXX Implement */
895		ccb->ccb_h.status = CAM_REQ_INVALID;
896		xpt_done(ccb);
897		break;
898	case XPT_PATH_INQ:		/* Path routing inquiry */
899	{
900		struct ccb_pathinq *cpi = &ccb->cpi;
901
902		cpi->version_num = 1; /* XXX??? */
903		cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE;
904		if ((ahc->features & AHC_WIDE) != 0)
905			cpi->hba_inquiry |= PI_WIDE_16;
906		if ((ahc->features & AHC_TARGETMODE) != 0) {
907			cpi->target_sprt = PIT_PROCESSOR
908					 | PIT_DISCONNECT
909					 | PIT_TERM_IO;
910		} else {
911			cpi->target_sprt = 0;
912		}
913		cpi->hba_misc = 0;
914		cpi->hba_eng_cnt = 0;
915		cpi->max_target = (ahc->features & AHC_WIDE) ? 15 : 7;
916		cpi->max_lun = AHC_NUM_LUNS - 1;
917		if (SIM_IS_SCSIBUS_B(ahc, sim)) {
918			cpi->initiator_id = ahc->our_id_b;
919			if ((ahc->flags & AHC_RESET_BUS_B) == 0)
920				cpi->hba_misc |= PIM_NOBUSRESET;
921		} else {
922			cpi->initiator_id = ahc->our_id;
923			if ((ahc->flags & AHC_RESET_BUS_A) == 0)
924				cpi->hba_misc |= PIM_NOBUSRESET;
925		}
926		cpi->bus_id = cam_sim_bus(sim);
927		cpi->base_transfer_speed = 3300;
928		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
929		strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN);
930		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
931		cpi->unit_number = cam_sim_unit(sim);
932#ifdef AHC_NEW_TRAN_SETTINGS
933		cpi->protocol = PROTO_SCSI;
934		cpi->protocol_version = SCSI_REV_2;
935		cpi->transport = XPORT_SPI;
936		cpi->transport_version = 2;
937		cpi->xport_specific.spi.ppr_options = SID_SPI_CLOCK_ST;
938		if ((ahc->features & AHC_DT) != 0) {
939			cpi->transport_version = 3;
940			cpi->xport_specific.spi.ppr_options =
941			    SID_SPI_CLOCK_DT_ST;
942		}
943#endif
944		cpi->ccb_h.status = CAM_REQ_CMP;
945		xpt_done(ccb);
946		break;
947	}
948	default:
949		ccb->ccb_h.status = CAM_PROVIDE_FAIL;
950		xpt_done(ccb);
951		break;
952	}
953}
954
955static void
956ahc_get_tran_settings(struct ahc_softc *ahc, int our_id, char channel,
957		      struct ccb_trans_settings *cts)
958{
959#ifdef AHC_NEW_TRAN_SETTINGS
960	struct	ahc_devinfo devinfo;
961	struct	ccb_trans_settings_scsi *scsi;
962	struct	ccb_trans_settings_spi *spi;
963	struct	ahc_initiator_tinfo *targ_info;
964	struct	ahc_tmode_tstate *tstate;
965	struct	ahc_transinfo *tinfo;
966
967	scsi = &cts->proto_specific.scsi;
968	spi = &cts->xport_specific.spi;
969	ahc_compile_devinfo(&devinfo, our_id,
970			    cts->ccb_h.target_id,
971			    cts->ccb_h.target_lun,
972			    channel, ROLE_UNKNOWN);
973	targ_info = ahc_fetch_transinfo(ahc, devinfo.channel,
974					devinfo.our_scsiid,
975					devinfo.target, &tstate);
976
977	if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
978		tinfo = &targ_info->curr;
979	else
980		tinfo = &targ_info->user;
981
982	scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
983	spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
984	if (cts->type == CTS_TYPE_USER_SETTINGS) {
985		if ((ahc->user_discenable & devinfo.target_mask) != 0)
986			spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
987
988		if ((ahc->user_tagenable & devinfo.target_mask) != 0)
989			scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
990	} else {
991		if ((tstate->discenable & devinfo.target_mask) != 0)
992			spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
993
994		if ((tstate->tagenable & devinfo.target_mask) != 0)
995			scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
996	}
997	cts->protocol_version = tinfo->protocol_version;
998	cts->transport_version = tinfo->transport_version;
999
1000	spi->sync_period = tinfo->period;
1001	spi->sync_offset = tinfo->offset;
1002	spi->bus_width = tinfo->width;
1003	spi->ppr_options = tinfo->ppr_options;
1004
1005	cts->protocol = PROTO_SCSI;
1006	cts->transport = XPORT_SPI;
1007	spi->valid = CTS_SPI_VALID_SYNC_RATE
1008		   | CTS_SPI_VALID_SYNC_OFFSET
1009		   | CTS_SPI_VALID_BUS_WIDTH
1010		   | CTS_SPI_VALID_PPR_OPTIONS;
1011
1012	if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
1013		scsi->valid = CTS_SCSI_VALID_TQ;
1014		spi->valid |= CTS_SPI_VALID_DISC;
1015	} else {
1016		scsi->valid = 0;
1017	}
1018
1019	cts->ccb_h.status = CAM_REQ_CMP;
1020#else
1021	struct	ahc_devinfo devinfo;
1022	struct	ahc_initiator_tinfo *targ_info;
1023	struct	ahc_tmode_tstate *tstate;
1024	struct	ahc_transinfo *tinfo;
1025
1026	ahc_compile_devinfo(&devinfo, our_id,
1027			    cts->ccb_h.target_id,
1028			    cts->ccb_h.target_lun,
1029			    channel, ROLE_UNKNOWN);
1030	targ_info = ahc_fetch_transinfo(ahc, devinfo.channel,
1031					devinfo.our_scsiid,
1032					devinfo.target, &tstate);
1033
1034	if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
1035		tinfo = &targ_info->curr;
1036	else
1037		tinfo = &targ_info->user;
1038
1039	cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
1040	if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) == 0) {
1041		if ((ahc->user_discenable & devinfo.target_mask) != 0)
1042			cts->flags |= CCB_TRANS_DISC_ENB;
1043
1044		if ((ahc->user_tagenable & devinfo.target_mask) != 0)
1045			cts->flags |= CCB_TRANS_TAG_ENB;
1046	} else {
1047		if ((tstate->discenable & devinfo.target_mask) != 0)
1048			cts->flags |= CCB_TRANS_DISC_ENB;
1049
1050		if ((tstate->tagenable & devinfo.target_mask) != 0)
1051			cts->flags |= CCB_TRANS_TAG_ENB;
1052	}
1053	cts->sync_period = tinfo->period;
1054	cts->sync_offset = tinfo->offset;
1055	cts->bus_width = tinfo->width;
1056
1057	cts->valid = CCB_TRANS_SYNC_RATE_VALID
1058		   | CCB_TRANS_SYNC_OFFSET_VALID
1059		   | CCB_TRANS_BUS_WIDTH_VALID;
1060
1061	if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD)
1062		cts->valid |= CCB_TRANS_DISC_VALID|CCB_TRANS_TQ_VALID;
1063
1064	cts->ccb_h.status = CAM_REQ_CMP;
1065#endif
1066}
1067
1068static void
1069ahc_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
1070{
1071	struct ahc_softc *ahc;
1072	struct cam_sim *sim;
1073
1074	sim = (struct cam_sim *)callback_arg;
1075	ahc = (struct ahc_softc *)cam_sim_softc(sim);
1076	switch (code) {
1077	case AC_LOST_DEVICE:
1078	{
1079		struct	ahc_devinfo devinfo;
1080		long	s;
1081
1082		ahc_compile_devinfo(&devinfo, SIM_SCSI_ID(ahc, sim),
1083				    xpt_path_target_id(path),
1084				    xpt_path_lun_id(path),
1085				    SIM_CHANNEL(ahc, sim),
1086				    ROLE_UNKNOWN);
1087
1088		/*
1089		 * Revert to async/narrow transfers
1090		 * for the next device.
1091		 */
1092		ahc_lock(ahc, &s);
1093		ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
1094			      AHC_TRANS_GOAL|AHC_TRANS_CUR, /*paused*/FALSE);
1095		ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL,
1096				 /*period*/0, /*offset*/0, /*ppr_options*/0,
1097				 AHC_TRANS_GOAL|AHC_TRANS_CUR,
1098				 /*paused*/FALSE);
1099		ahc_unlock(ahc, &s);
1100		break;
1101	}
1102	default:
1103		break;
1104	}
1105}
1106
1107static void
1108ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments,
1109		int error)
1110{
1111	struct	scb *scb;
1112	union	ccb *ccb;
1113	struct	ahc_softc *ahc;
1114	struct	ahc_initiator_tinfo *tinfo;
1115	struct	ahc_tmode_tstate *tstate;
1116	u_int	mask;
1117	long	s;
1118
1119	scb = (struct scb *)arg;
1120	ccb = scb->io_ctx;
1121	ahc = scb->ahc_softc;
1122
1123	if (error != 0) {
1124		if (error == EFBIG)
1125			aic_set_transaction_status(scb, CAM_REQ_TOO_BIG);
1126		else
1127			aic_set_transaction_status(scb, CAM_REQ_CMP_ERR);
1128		if (nsegments != 0)
1129			bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap);
1130		ahc_lock(ahc, &s);
1131		ahc_free_scb(ahc, scb);
1132		ahc_unlock(ahc, &s);
1133		xpt_done(ccb);
1134		return;
1135	}
1136	if (nsegments != 0) {
1137		struct	  ahc_dma_seg *sg;
1138		bus_dma_segment_t *end_seg;
1139		bus_dmasync_op_t op;
1140
1141		end_seg = dm_segs + nsegments;
1142
1143		/* Copy the segments into our SG list */
1144		sg = scb->sg_list;
1145		while (dm_segs < end_seg) {
1146			uint32_t len;
1147
1148			sg->addr = aic_htole32(dm_segs->ds_addr);
1149			len = dm_segs->ds_len
1150			    | ((dm_segs->ds_addr >> 8) & 0x7F000000);
1151			sg->len = aic_htole32(len);
1152			sg++;
1153			dm_segs++;
1154		}
1155
1156		/*
1157		 * Note where to find the SG entries in bus space.
1158		 * We also set the full residual flag which the
1159		 * sequencer will clear as soon as a data transfer
1160		 * occurs.
1161		 */
1162		scb->hscb->sgptr = aic_htole32(scb->sg_list_phys|SG_FULL_RESID);
1163
1164		if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
1165			op = BUS_DMASYNC_PREREAD;
1166		else
1167			op = BUS_DMASYNC_PREWRITE;
1168
1169		bus_dmamap_sync(ahc->buffer_dmat, scb->dmamap, op);
1170
1171		if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) {
1172			struct target_data *tdata;
1173
1174			tdata = &scb->hscb->shared_data.tdata;
1175			tdata->target_phases |= DPHASE_PENDING;
1176			/*
1177			 * CAM data direction is relative to the initiator.
1178			 */
1179			if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
1180				tdata->data_phase = P_DATAOUT;
1181			else
1182				tdata->data_phase = P_DATAIN;
1183
1184			/*
1185			 * If the transfer is of an odd length and in the
1186			 * "in" direction (scsi->HostBus), then it may
1187			 * trigger a bug in the 'WideODD' feature of
1188			 * non-Ultra2 chips.  Force the total data-length
1189			 * to be even by adding an extra, 1 byte, SG,
1190			 * element.  We do this even if we are not currently
1191			 * negotiated wide as negotiation could occur before
1192			 * this command is executed.
1193			 */
1194			if ((ahc->bugs & AHC_TMODE_WIDEODD_BUG) != 0
1195			 && (ccb->csio.dxfer_len & 0x1) != 0
1196			 && (ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
1197
1198				nsegments++;
1199				if (nsegments > AHC_NSEG) {
1200
1201					aic_set_transaction_status(scb,
1202					    CAM_REQ_TOO_BIG);
1203					bus_dmamap_unload(ahc->buffer_dmat,
1204							  scb->dmamap);
1205					ahc_lock(ahc, &s);
1206					ahc_free_scb(ahc, scb);
1207					ahc_unlock(ahc, &s);
1208					xpt_done(ccb);
1209					return;
1210				}
1211				sg->addr = aic_htole32(ahc->dma_bug_buf);
1212				sg->len = aic_htole32(1);
1213				sg++;
1214			}
1215		}
1216		sg--;
1217		sg->len |= aic_htole32(AHC_DMA_LAST_SEG);
1218
1219		/* Copy the first SG into the "current" data pointer area */
1220		scb->hscb->dataptr = scb->sg_list->addr;
1221		scb->hscb->datacnt = scb->sg_list->len;
1222	} else {
1223		scb->hscb->sgptr = aic_htole32(SG_LIST_NULL);
1224		scb->hscb->dataptr = 0;
1225		scb->hscb->datacnt = 0;
1226	}
1227
1228	scb->sg_count = nsegments;
1229
1230	ahc_lock(ahc, &s);
1231
1232	/*
1233	 * Last time we need to check if this SCB needs to
1234	 * be aborted.
1235	 */
1236	if (aic_get_transaction_status(scb) != CAM_REQ_INPROG) {
1237		if (nsegments != 0)
1238			bus_dmamap_unload(ahc->buffer_dmat, scb->dmamap);
1239		ahc_free_scb(ahc, scb);
1240		ahc_unlock(ahc, &s);
1241		xpt_done(ccb);
1242		return;
1243	}
1244
1245	tinfo = ahc_fetch_transinfo(ahc, SCSIID_CHANNEL(ahc, scb->hscb->scsiid),
1246				    SCSIID_OUR_ID(scb->hscb->scsiid),
1247				    SCSIID_TARGET(ahc, scb->hscb->scsiid),
1248				    &tstate);
1249
1250	mask = SCB_GET_TARGET_MASK(ahc, scb);
1251	scb->hscb->scsirate = tinfo->scsirate;
1252	scb->hscb->scsioffset = tinfo->curr.offset;
1253	if ((tstate->ultraenb & mask) != 0)
1254		scb->hscb->control |= ULTRAENB;
1255
1256	if ((tstate->discenable & mask) != 0
1257	 && (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0)
1258		scb->hscb->control |= DISCENB;
1259
1260	if ((ccb->ccb_h.flags & CAM_NEGOTIATE) != 0
1261	 && (tinfo->goal.width != 0
1262	  || tinfo->goal.offset != 0
1263	  || tinfo->goal.ppr_options != 0)) {
1264		scb->flags |= SCB_NEGOTIATE;
1265		scb->hscb->control |= MK_MESSAGE;
1266	} else if ((tstate->auto_negotiate & mask) != 0) {
1267		scb->flags |= SCB_AUTO_NEGOTIATE;
1268		scb->hscb->control |= MK_MESSAGE;
1269	}
1270
1271	LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links);
1272
1273	ccb->ccb_h.status |= CAM_SIM_QUEUED;
1274
1275	/*
1276	 * We only allow one untagged transaction
1277	 * per target in the initiator role unless
1278	 * we are storing a full busy target *lun*
1279	 * table in SCB space.
1280	 */
1281	if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0
1282	 && (ahc->flags & AHC_SCB_BTT) == 0) {
1283		struct scb_tailq *untagged_q;
1284		int target_offset;
1285
1286		target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
1287		untagged_q = &(ahc->untagged_queues[target_offset]);
1288		TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
1289		scb->flags |= SCB_UNTAGGEDQ;
1290		if (TAILQ_FIRST(untagged_q) != scb) {
1291			ahc_unlock(ahc, &s);
1292			return;
1293		}
1294	}
1295	scb->flags |= SCB_ACTIVE;
1296
1297	/*
1298	 * Timers are disabled while recovery is in progress.
1299	 */
1300	aic_scb_timer_start(scb);
1301
1302	if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) {
1303		/* Define a mapping from our tag to the SCB. */
1304		ahc->scb_data->scbindex[scb->hscb->tag] = scb;
1305		ahc_pause(ahc);
1306		if ((ahc->flags & AHC_PAGESCBS) == 0)
1307			ahc_outb(ahc, SCBPTR, scb->hscb->tag);
1308		ahc_outb(ahc, TARG_IMMEDIATE_SCB, scb->hscb->tag);
1309		ahc_unpause(ahc);
1310	} else {
1311		ahc_queue_scb(ahc, scb);
1312	}
1313
1314	ahc_unlock(ahc, &s);
1315}
1316
1317static void
1318ahc_poll(struct cam_sim *sim)
1319{
1320	struct ahc_softc *ahc;
1321
1322	ahc = (struct ahc_softc *)cam_sim_softc(sim);
1323	ahc_intr(ahc);
1324}
1325
1326static void
1327ahc_setup_data(struct ahc_softc *ahc, struct cam_sim *sim,
1328	       struct ccb_scsiio *csio, struct scb *scb)
1329{
1330	struct hardware_scb *hscb;
1331	struct ccb_hdr *ccb_h;
1332
1333	hscb = scb->hscb;
1334	ccb_h = &csio->ccb_h;
1335
1336	csio->resid = 0;
1337	csio->sense_resid = 0;
1338	if (ccb_h->func_code == XPT_SCSI_IO) {
1339		hscb->cdb_len = csio->cdb_len;
1340		if ((ccb_h->flags & CAM_CDB_POINTER) != 0) {
1341
1342			if (hscb->cdb_len > sizeof(hscb->cdb32)
1343			 || (ccb_h->flags & CAM_CDB_PHYS) != 0) {
1344				u_long s;
1345
1346				aic_set_transaction_status(scb,
1347							   CAM_REQ_INVALID);
1348				ahc_lock(ahc, &s);
1349				ahc_free_scb(ahc, scb);
1350				ahc_unlock(ahc, &s);
1351				xpt_done((union ccb *)csio);
1352				return;
1353			}
1354			if (hscb->cdb_len > 12) {
1355				memcpy(hscb->cdb32,
1356				       csio->cdb_io.cdb_ptr,
1357				       hscb->cdb_len);
1358				scb->flags |= SCB_CDB32_PTR;
1359			} else {
1360				memcpy(hscb->shared_data.cdb,
1361				       csio->cdb_io.cdb_ptr,
1362				       hscb->cdb_len);
1363			}
1364		} else {
1365			if (hscb->cdb_len > 12) {
1366				memcpy(hscb->cdb32, csio->cdb_io.cdb_bytes,
1367				       hscb->cdb_len);
1368				scb->flags |= SCB_CDB32_PTR;
1369			} else {
1370				memcpy(hscb->shared_data.cdb,
1371				       csio->cdb_io.cdb_bytes,
1372				       hscb->cdb_len);
1373			}
1374		}
1375	}
1376
1377	/* Only use S/G if there is a transfer */
1378	if ((ccb_h->flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
1379		if ((ccb_h->flags & CAM_SCATTER_VALID) == 0) {
1380			/* We've been given a pointer to a single buffer */
1381			if ((ccb_h->flags & CAM_DATA_PHYS) == 0) {
1382				int s;
1383				int error;
1384
1385				s = splsoftvm();
1386				error = bus_dmamap_load(ahc->buffer_dmat,
1387							scb->dmamap,
1388							csio->data_ptr,
1389							csio->dxfer_len,
1390							ahc_execute_scb,
1391							scb, /*flags*/0);
1392				if (error == EINPROGRESS) {
1393					/*
1394					 * So as to maintain ordering,
1395					 * freeze the controller queue
1396					 * until our mapping is
1397					 * returned.
1398					 */
1399					xpt_freeze_simq(sim,
1400							/*count*/1);
1401					scb->io_ctx->ccb_h.status |=
1402					    CAM_RELEASE_SIMQ;
1403				}
1404				splx(s);
1405			} else {
1406				struct bus_dma_segment seg;
1407
1408				/* Pointer to physical buffer */
1409				if (csio->dxfer_len > AHC_MAXTRANSFER_SIZE)
1410					panic("ahc_setup_data - Transfer size "
1411					      "larger than can device max");
1412
1413				seg.ds_addr =
1414				    (bus_addr_t)(vm_offset_t)csio->data_ptr;
1415				seg.ds_len = csio->dxfer_len;
1416				ahc_execute_scb(scb, &seg, 1, 0);
1417			}
1418		} else {
1419			struct bus_dma_segment *segs;
1420
1421			if ((ccb_h->flags & CAM_DATA_PHYS) != 0)
1422				panic("ahc_setup_data - Physical segment "
1423				      "pointers unsupported");
1424
1425			if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0)
1426				panic("ahc_setup_data - Virtual segment "
1427				      "addresses unsupported");
1428
1429			/* Just use the segments provided */
1430			segs = (struct bus_dma_segment *)csio->data_ptr;
1431			ahc_execute_scb(scb, segs, csio->sglist_cnt, 0);
1432		}
1433	} else {
1434		ahc_execute_scb(scb, NULL, 0, 0);
1435	}
1436}
1437
1438static void
1439ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
1440{
1441	union ccb *abort_ccb;
1442
1443	abort_ccb = ccb->cab.abort_ccb;
1444	switch (abort_ccb->ccb_h.func_code) {
1445	case XPT_ACCEPT_TARGET_IO:
1446	case XPT_IMMED_NOTIFY:
1447	case XPT_CONT_TARGET_IO:
1448	{
1449		struct ahc_tmode_tstate *tstate;
1450		struct ahc_tmode_lstate *lstate;
1451		struct ccb_hdr_slist *list;
1452		cam_status status;
1453
1454		status = ahc_find_tmode_devs(ahc, sim, abort_ccb, &tstate,
1455					     &lstate, TRUE);
1456
1457		if (status != CAM_REQ_CMP) {
1458			ccb->ccb_h.status = status;
1459			break;
1460		}
1461
1462		if (abort_ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO)
1463			list = &lstate->accept_tios;
1464		else if (abort_ccb->ccb_h.func_code == XPT_IMMED_NOTIFY)
1465			list = &lstate->immed_notifies;
1466		else
1467			list = NULL;
1468
1469		if (list != NULL) {
1470			struct ccb_hdr *curelm;
1471			int found;
1472
1473			curelm = SLIST_FIRST(list);
1474			found = 0;
1475			if (curelm == &abort_ccb->ccb_h) {
1476				found = 1;
1477				SLIST_REMOVE_HEAD(list, sim_links.sle);
1478			} else {
1479				while(curelm != NULL) {
1480					struct ccb_hdr *nextelm;
1481
1482					nextelm =
1483					    SLIST_NEXT(curelm, sim_links.sle);
1484
1485					if (nextelm == &abort_ccb->ccb_h) {
1486						found = 1;
1487						SLIST_NEXT(curelm,
1488							   sim_links.sle) =
1489						    SLIST_NEXT(nextelm,
1490							       sim_links.sle);
1491						break;
1492					}
1493					curelm = nextelm;
1494				}
1495			}
1496
1497			if (found) {
1498				abort_ccb->ccb_h.status = CAM_REQ_ABORTED;
1499				xpt_done(abort_ccb);
1500				ccb->ccb_h.status = CAM_REQ_CMP;
1501			} else {
1502				xpt_print_path(abort_ccb->ccb_h.path);
1503				printf("Not found\n");
1504				ccb->ccb_h.status = CAM_PATH_INVALID;
1505			}
1506			break;
1507		}
1508		/* FALLTHROUGH */
1509	}
1510	case XPT_SCSI_IO:
1511		/* XXX Fully implement the hard ones */
1512		ccb->ccb_h.status = CAM_UA_ABORT;
1513		break;
1514	default:
1515		ccb->ccb_h.status = CAM_REQ_INVALID;
1516		break;
1517	}
1518	xpt_done(ccb);
1519}
1520
1521void
1522ahc_send_async(struct ahc_softc *ahc, char channel, u_int target,
1523		u_int lun, ac_code code, void *opt_arg)
1524{
1525	struct	ccb_trans_settings cts;
1526	struct cam_path *path;
1527	void *arg;
1528	int error;
1529
1530	arg = NULL;
1531	error = ahc_create_path(ahc, channel, target, lun, &path);
1532
1533	if (error != CAM_REQ_CMP)
1534		return;
1535
1536	switch (code) {
1537	case AC_TRANSFER_NEG:
1538	{
1539#ifdef AHC_NEW_TRAN_SETTINGS
1540		struct	ccb_trans_settings_scsi *scsi;
1541
1542		cts.type = CTS_TYPE_CURRENT_SETTINGS;
1543		scsi = &cts.proto_specific.scsi;
1544#else
1545		cts.flags = CCB_TRANS_CURRENT_SETTINGS;
1546#endif
1547		cts.ccb_h.path = path;
1548		cts.ccb_h.target_id = target;
1549		cts.ccb_h.target_lun = lun;
1550		ahc_get_tran_settings(ahc, channel == 'A' ? ahc->our_id
1551							  : ahc->our_id_b,
1552				      channel, &cts);
1553		arg = &cts;
1554#ifdef AHC_NEW_TRAN_SETTINGS
1555		scsi->valid &= ~CTS_SCSI_VALID_TQ;
1556		scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1557#else
1558		cts.valid &= ~CCB_TRANS_TQ_VALID;
1559		cts.flags &= ~CCB_TRANS_TAG_ENB;
1560#endif
1561		if (opt_arg == NULL)
1562			break;
1563		if (*((ahc_queue_alg *)opt_arg) == AHC_QUEUE_TAGGED)
1564#ifdef AHC_NEW_TRAN_SETTINGS
1565			scsi->flags |= ~CTS_SCSI_FLAGS_TAG_ENB;
1566		scsi->valid |= CTS_SCSI_VALID_TQ;
1567#else
1568			cts.flags |= CCB_TRANS_TAG_ENB;
1569		cts.valid |= CCB_TRANS_TQ_VALID;
1570#endif
1571		break;
1572	}
1573	case AC_SENT_BDR:
1574	case AC_BUS_RESET:
1575		break;
1576	default:
1577		panic("ahc_send_async: Unexpected async event");
1578	}
1579	xpt_async(code, path, arg);
1580	xpt_free_path(path);
1581}
1582
1583void
1584ahc_platform_set_tags(struct ahc_softc *ahc,
1585		      struct ahc_devinfo *devinfo, int enable)
1586{
1587}
1588
1589int
1590ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
1591{
1592	ahc->platform_data = malloc(sizeof(struct ahc_platform_data), M_DEVBUF,
1593	    M_NOWAIT | M_ZERO);
1594	if (ahc->platform_data == NULL)
1595		return (ENOMEM);
1596	return (0);
1597}
1598
1599void
1600ahc_platform_free(struct ahc_softc *ahc)
1601{
1602	struct ahc_platform_data *pdata;
1603
1604	pdata = ahc->platform_data;
1605	if (pdata != NULL) {
1606		if (pdata->regs != NULL)
1607			bus_release_resource(ahc->dev_softc,
1608					     pdata->regs_res_type,
1609					     pdata->regs_res_id,
1610					     pdata->regs);
1611
1612		if (pdata->irq != NULL)
1613			bus_release_resource(ahc->dev_softc,
1614					     pdata->irq_res_type,
1615					     0, pdata->irq);
1616
1617		if (pdata->sim_b != NULL) {
1618			xpt_async(AC_LOST_DEVICE, pdata->path_b, NULL);
1619			xpt_free_path(pdata->path_b);
1620			xpt_bus_deregister(cam_sim_path(pdata->sim_b));
1621			cam_sim_free(pdata->sim_b, /*free_devq*/TRUE);
1622		}
1623		if (pdata->sim != NULL) {
1624			xpt_async(AC_LOST_DEVICE, pdata->path, NULL);
1625			xpt_free_path(pdata->path);
1626			xpt_bus_deregister(cam_sim_path(pdata->sim));
1627			cam_sim_free(pdata->sim, /*free_devq*/TRUE);
1628		}
1629		if (pdata->eh != NULL)
1630			EVENTHANDLER_DEREGISTER(shutdown_final, pdata->eh);
1631		free(ahc->platform_data, M_DEVBUF);
1632	}
1633}
1634
1635int
1636ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc)
1637{
1638	/* We don't sort softcs under FreeBSD so report equal always */
1639	return (0);
1640}
1641
1642int
1643ahc_detach(device_t dev)
1644{
1645	struct ahc_softc *ahc;
1646	u_long l;
1647	u_long s;
1648
1649	ahc_list_lock(&l);
1650	device_printf(dev, "detaching device\n");
1651	ahc = device_get_softc(dev);
1652	ahc = ahc_find_softc(ahc);
1653	if (ahc == NULL) {
1654		device_printf(dev, "aic7xxx already detached\n");
1655		ahc_list_unlock(&l);
1656		return (ENOENT);
1657	}
1658	TAILQ_REMOVE(&ahc_tailq, ahc, links);
1659	ahc_list_unlock(&l);
1660	ahc_lock(ahc, &s);
1661	ahc_intr_enable(ahc, FALSE);
1662	bus_teardown_intr(dev, ahc->platform_data->irq, ahc->platform_data->ih);
1663	ahc_unlock(ahc, &s);
1664	ahc_free(ahc);
1665	return (0);
1666}
1667
1668#if UNUSED
1669static void
1670ahc_dump_targcmd(struct target_cmd *cmd)
1671{
1672	uint8_t *byte;
1673	uint8_t *last_byte;
1674	int i;
1675
1676	byte = &cmd->initiator_channel;
1677	/* Debugging info for received commands */
1678	last_byte = &cmd[1].initiator_channel;
1679
1680	i = 0;
1681	while (byte < last_byte) {
1682		if (i == 0)
1683			printf("\t");
1684		printf("%#x", *byte++);
1685		i++;
1686		if (i == 8) {
1687			printf("\n");
1688			i = 0;
1689		} else {
1690			printf(", ");
1691		}
1692	}
1693}
1694#endif
1695
1696static int
1697ahc_modevent(module_t mod, int type, void *data)
1698{
1699	/* XXX Deal with busy status on unload. */
1700	/* XXX Deal with unknown events */
1701	return 0;
1702}
1703
1704static moduledata_t ahc_mod = {
1705	"ahc",
1706	ahc_modevent,
1707	NULL
1708};
1709
1710DECLARE_MODULE(ahc, ahc_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
1711MODULE_DEPEND(ahc, cam, 1, 1, 1);
1712MODULE_VERSION(ahc, 1);
1713