aic.c revision 52536
1/*-
2 * Copyright (c) 1999 Luoqi Chen.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/dev/aic/aic.c 52536 1999-10-26 22:11:45Z luoqi $
27 */
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/malloc.h>
32#include <sys/buf.h>
33#include <sys/kernel.h>
34#include <sys/sysctl.h>
35#include <sys/bus.h>
36
37#include <machine/bus_pio.h>
38#include <machine/bus.h>
39#include <machine/clock.h>
40
41#include <cam/cam.h>
42#include <cam/cam_ccb.h>
43#include <cam/cam_sim.h>
44#include <cam/cam_xpt_sim.h>
45#include <cam/cam_debug.h>
46
47#include <cam/scsi/scsi_message.h>
48
49#include <dev/aic/aic6360reg.h>
50#include <dev/aic/aicvar.h>
51
52static void aic_action __P((struct cam_sim *sim, union ccb *ccb));
53static void aic_execute_scb __P((void *arg, bus_dma_segment_t *dm_segs,
54				int nseg, int error));
55static void aic_start __P((struct aic_softc *aic));
56static void aic_select __P((struct aic_softc *aic));
57static void aic_selected __P((struct aic_softc *aic));
58static void aic_reselected __P((struct aic_softc *aic));
59static void aic_cmd __P((struct aic_softc *aic));
60static void aic_msgin __P((struct aic_softc *aic));
61static void aic_handle_msgin __P((struct aic_softc *aic));
62static void aic_msgout __P((struct aic_softc *aic));
63static void aic_datain __P((struct aic_softc *aic));
64static void aic_dataout __P((struct aic_softc *aic));
65static void aic_done __P((struct aic_softc *aic, struct aic_scb *scb));
66static void aic_poll __P((struct cam_sim *sim));
67static void aic_timeout __P((void *arg));
68static void aic_scsi_reset __P((struct aic_softc *aic));
69static void aic_chip_reset __P((struct aic_softc *aic));
70static void aic_reset __P((struct aic_softc *aic, int initiate_reset));
71
72static struct aic_scb *free_scbs;
73
74static struct aic_scb *
75aic_get_scb(struct aic_softc *aic)
76{
77	struct aic_scb *scb;
78	int s = splcam();
79	if ((scb = free_scbs) != NULL)
80		free_scbs = (struct aic_scb *)free_scbs->ccb;
81	splx(s);
82	return (scb);
83}
84
85static void
86aic_free_scb(struct aic_softc *aic, struct aic_scb *scb)
87{
88	int s = splcam();
89	if ((aic->flags & AIC_RESOURCE_SHORTAGE) != 0 &&
90	    (scb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) {
91		scb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
92		aic->flags &= ~AIC_RESOURCE_SHORTAGE;
93	}
94	scb->flags = 0;
95	scb->ccb = (union ccb *)free_scbs;
96	free_scbs = scb;
97	splx(s);
98}
99
100static void
101aic_action(struct cam_sim *sim, union ccb *ccb)
102{
103	struct aic_softc *aic;
104	int s;
105
106	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("aic_action\n"));
107
108	aic = (struct aic_softc *)cam_sim_softc(sim);
109
110	switch (ccb->ccb_h.func_code) {
111	case XPT_SCSI_IO:	/* Execute the requested I/O operation */
112	case XPT_RESET_DEV:	/* Bus Device Reset the specified SCSI device */
113        {
114		struct aic_scb *scb;
115
116		if ((scb = aic_get_scb(aic)) == NULL) {
117			s = splcam();
118			aic->flags |= AIC_RESOURCE_SHORTAGE;
119			splx(s);
120			xpt_freeze_simq(aic->sim, /*count*/1);
121			ccb->ccb_h.status = CAM_REQUEUE_REQ;
122			xpt_done(ccb);
123			return;
124		}
125
126		scb->ccb = ccb;
127		ccb->ccb_h.ccb_scb_ptr = scb;
128		ccb->ccb_h.ccb_aic_ptr = aic;
129
130		scb->target = ccb->ccb_h.target_id;
131		scb->lun = ccb->ccb_h.target_lun;
132
133		if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
134			scb->cmd_len = ccb->csio.cdb_len;
135			if (ccb->ccb_h.flags & CAM_CDB_POINTER) {
136				if (ccb->ccb_h.flags & CAM_CDB_PHYS) {
137					ccb->ccb_h.status = CAM_REQ_INVALID;
138					aic_free_scb(aic, scb);
139					xpt_done(ccb);
140					return;
141				}
142				scb->cmd_ptr = ccb->csio.cdb_io.cdb_ptr;
143			} else {
144				scb->cmd_ptr = ccb->csio.cdb_io.cdb_bytes;
145			}
146			if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
147				if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) ||
148				    (ccb->ccb_h.flags & CAM_DATA_PHYS)) {
149					ccb->ccb_h.status = CAM_REQ_INVALID;
150					aic_free_scb(aic, scb);
151					xpt_done(ccb);
152					return;
153				}
154				scb->data_ptr = ccb->csio.data_ptr;
155				scb->data_len = ccb->csio.dxfer_len;
156			} else {
157				scb->data_ptr = NULL;
158				scb->data_len = 0;
159			}
160			aic_execute_scb(scb, NULL, 0, 0);
161		} else {
162			scb->flags |= SCB_DEVICE_RESET;
163			aic_execute_scb(scb, NULL, 0, 0);
164		}
165		break;
166	}
167	case XPT_SET_TRAN_SETTINGS:
168	{
169		struct ccb_trans_settings *cts;
170		struct aic_tinfo *ti;
171
172		cts = &ccb->cts;
173		ti = &aic->tinfo[ccb->ccb_h.target_id];
174
175		s = splcam();
176
177		if ((cts->valid & CCB_TRANS_DISC_VALID) != 0 &&
178		    (aic->flags & AIC_DISC_ENABLE) != 0) {
179			if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
180				ti->flags |= TINFO_DISC_ENB;
181			else
182				ti->flags &= ~TINFO_DISC_ENB;
183		}
184
185		if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) {
186			if ((cts->flags & CCB_TRANS_TAG_ENB) != 0)
187				ti->flags |= TINFO_TAG_ENB;
188			else
189				ti->flags &= ~TINFO_TAG_ENB;
190		}
191
192		if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
193			ti->goal.period = cts->sync_period;
194			if (ti->goal.period != ti->current.period)
195				ti->flags |= TINFO_SDTR_NEGO;
196		}
197
198		if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0) {
199			ti->goal.offset = cts->sync_offset;
200			if (ti->goal.offset != ti->current.offset)
201				ti->flags |= TINFO_SDTR_NEGO;
202		}
203
204		splx(s);
205		ccb->ccb_h.status = CAM_REQ_CMP;
206		xpt_done(ccb);
207		break;
208	}
209	case XPT_GET_TRAN_SETTINGS:
210	{
211		struct ccb_trans_settings *cts;
212		struct aic_tinfo *ti;
213
214		cts = &ccb->cts;
215		ti = &aic->tinfo[ccb->ccb_h.target_id];
216
217		s = splcam();
218
219		cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
220		if ((ti->flags & TINFO_DISC_ENB) != 0)
221			cts->flags |= CCB_TRANS_DISC_ENB;
222		if ((ti->flags & TINFO_TAG_ENB) != 0)
223			cts->flags |= CCB_TRANS_TAG_ENB;
224
225		if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) {
226			cts->sync_period = ti->current.period;
227			cts->sync_offset = ti->current.offset;
228		} else {
229			cts->sync_period = ti->user.period;
230			cts->sync_offset = ti->user.offset;
231		}
232		cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
233
234		splx(s);
235
236		cts->valid = CCB_TRANS_SYNC_RATE_VALID
237			   | CCB_TRANS_SYNC_OFFSET_VALID
238			   | CCB_TRANS_BUS_WIDTH_VALID
239			   | CCB_TRANS_DISC_VALID
240			   | CCB_TRANS_TQ_VALID;
241
242		ccb->ccb_h.status = CAM_REQ_CMP;
243		xpt_done(ccb);
244		break;
245	}
246	case XPT_CALC_GEOMETRY:
247	{
248		struct ccb_calc_geometry *ccg;
249		u_int32_t size_mb;
250		u_int32_t secs_per_cylinder;
251		int extended = 0;
252
253		ccg = &ccb->ccg;
254		size_mb = ccg->volume_size
255			/ ((1024L * 1024L) / ccg->block_size);
256
257		if (size_mb >= 1024 && extended) {
258			ccg->heads = 255;
259			ccg->secs_per_track = 63;
260		} else {
261			ccg->heads = 64;
262			ccg->secs_per_track = 32;
263		}
264		secs_per_cylinder = ccg->heads * ccg->secs_per_track;
265		ccg->cylinders = ccg->volume_size / secs_per_cylinder;
266		ccb->ccb_h.status = CAM_REQ_CMP;
267		xpt_done(ccb);
268		break;
269	}
270	case XPT_RESET_BUS:		/* Reset the specified SCSI bus */
271		aic_reset(aic, /*initiate_reset*/TRUE);
272		ccb->ccb_h.status = CAM_REQ_CMP;
273		xpt_done(ccb);
274		break;
275        case XPT_PATH_INQ:              /* Path routing inquiry */
276        {
277                struct ccb_pathinq *cpi = &ccb->cpi;
278
279                cpi->version_num = 1; /* XXX??? */
280                cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE;
281                cpi->target_sprt = 0;
282                cpi->hba_misc = 0;
283                cpi->hba_eng_cnt = 0;
284                cpi->max_target = 7;
285                cpi->max_lun = 7;
286                cpi->initiator_id = aic->initiator;
287                cpi->bus_id = cam_sim_bus(sim);
288		cpi->base_transfer_speed = 3300;
289                strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
290                strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN);
291                strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
292                cpi->unit_number = cam_sim_unit(sim);
293                cpi->ccb_h.status = CAM_REQ_CMP;
294                xpt_done(ccb);
295                break;
296        }
297	default:
298                ccb->ccb_h.status = CAM_REQ_INVALID;
299                xpt_done(ccb);
300                break;
301	}
302}
303
304static void
305aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
306{
307	struct aic_scb *scb = (struct aic_scb *)arg;
308	union ccb *ccb = scb->ccb;
309	struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr;
310	int s;
311
312	s = splcam();
313
314	if (ccb->ccb_h.status != CAM_REQ_INPROG) {
315		splx(s);
316		aic_free_scb(aic, scb);
317		xpt_done(ccb);
318		return;
319	}
320
321	scb->flags |= SCB_ACTIVE;
322	ccb->ccb_h.status |= CAM_SIM_QUEUED;
323	TAILQ_INSERT_TAIL(&aic->pending_ccbs, &ccb->ccb_h, sim_links.tqe);
324
325	ccb->ccb_h.timeout_ch = timeout(aic_timeout, (caddr_t)scb,
326		(ccb->ccb_h.timeout * hz) / 1000);
327
328	aic_start(aic);
329	splx(s);
330}
331
332/*
333 * Start another command if the controller is not busy.
334 */
335static void
336aic_start(struct aic_softc *aic)
337{
338	struct ccb_hdr *ccb_h;
339	struct aic_tinfo *ti;
340
341	if (aic->state != AIC_IDLE)
342		return;
343
344	TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) {
345		ti = &aic->tinfo[ccb_h->target_id];
346		if ((ti->lubusy & (1 << ccb_h->target_lun)) == 0) {
347			TAILQ_REMOVE(&aic->pending_ccbs, ccb_h, sim_links.tqe);
348			aic->nexus = (struct aic_scb *)ccb_h->ccb_scb_ptr;
349			aic_select(aic);
350			return;
351		}
352	}
353
354	aic_outb(aic, SIMODE0, ENSELDI);
355	aic_outb(aic, SIMODE1, ENSCSIRST);
356	aic_outb(aic, SCSISEQ, ENRESELI);
357}
358
359/*
360 * Start a selection.
361 */
362static void
363aic_select(struct aic_softc *aic)
364{
365	struct aic_scb *scb = aic->nexus;
366
367	CAM_DEBUG(scb->ccb->ccb_h.path, CAM_DEBUG_TRACE,
368		  ("aic_select - ccb %p\n", scb->ccb));
369
370	aic->state = AIC_SELECTING;
371
372	aic_outb(aic, DMACNTRL1, 0);
373	aic_outb(aic, SCSIID, aic->initiator << OID_S | scb->target);
374	aic_outb(aic, SXFRCTL1, STIMO_256ms | ENSTIMER |
375	    (aic->flags & AIC_PARITY_ENABLE ? ENSPCHK : 0));
376
377	aic_outb(aic, SIMODE0, ENSELDI|ENSELDO);
378	aic_outb(aic, SIMODE1, ENSCSIRST|ENSELTIMO);
379	aic_outb(aic, SCSISEQ, ENRESELI|ENSELO|ENAUTOATNO);
380}
381
382/*
383 * We have successfully selected a target, prepare for the information
384 * transfer phases.
385 */
386static void
387aic_selected(struct aic_softc *aic)
388{
389	struct aic_scb *scb = aic->nexus;
390	union ccb *ccb = scb->ccb;
391	struct aic_tinfo *ti = &aic->tinfo[scb->target];
392
393	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE,
394		  ("aic_selected - ccb %p\n", ccb));
395
396	aic->state = AIC_HASNEXUS;
397
398	if (scb->flags & SCB_DEVICE_RESET) {
399		aic->msg_buf[0] = MSG_BUS_DEV_RESET;
400		aic->msg_len = 1;
401		aic->msg_outq = AIC_MSG_MSGBUF;
402	} else {
403		aic->msg_outq = AIC_MSG_IDENTIFY;
404		if ((ti->flags & TINFO_TAG_ENB) != 0 &&
405		    (ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0)
406			aic->msg_outq |= AIC_MSG_TAG_Q;
407		if ((ti->flags & TINFO_SDTR_NEGO) != 0)
408			aic->msg_outq |= AIC_MSG_SDTR;
409	}
410
411	/* mark target/lun busy only for untagged operations */
412	if ((aic->msg_outq & AIC_MSG_TAG_Q) == 0)
413		ti->lubusy |= 1 << scb->lun;
414
415	aic_outb(aic, CLRSINT0, CLRSELDO);
416	aic_outb(aic, CLRSINT1, CLRBUSFREE);
417	aic_outb(aic, SCSISEQ, ENAUTOATNP);
418	aic_outb(aic, SIMODE0, 0);
419	aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
420	aic_outb(aic, SCSIRATE, ti->scsirate);
421}
422
423/*
424 * We are re-selected by a target, save the target id and wait for the
425 * target to further identify itself.
426 */
427static void
428aic_reselected(struct aic_softc *aic)
429{
430	u_int8_t selid;
431	struct aic_tinfo *ti;
432
433	CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_reselected\n"));
434
435	/*
436	 * If we have started a selection, it must have lost out in
437	 * the arbitration, put the command back to the pending queue.
438	 */
439	if (aic->nexus) {
440		TAILQ_INSERT_HEAD(&aic->pending_ccbs,
441		    &aic->nexus->ccb->ccb_h, sim_links.tqe);
442		aic->nexus = NULL;
443	}
444
445	selid = aic_inb(aic, SELID) & SCSI_ID_MASK;
446	if (selid & (selid - 1)) {
447		/* this should never have happened */
448		aic_reset(aic, /*initiate_reset*/TRUE);
449		return;
450	}
451
452	aic->state = AIC_RESELECTED;
453	aic->target = ffs(selid) - 1;
454	aic->lun = -1;
455	ti = &aic->tinfo[aic->target];
456
457	aic_outb(aic, CLRSINT0, CLRSELDI);
458	aic_outb(aic, CLRSINT1, CLRBUSFREE);
459	aic_outb(aic, SIMODE0, 0);
460	aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
461	aic_outb(aic, SCSISEQ, ENAUTOATNP);
462	aic_outb(aic, SCSIRATE, ti->scsirate);
463}
464
465/*
466 * Raise ATNO to signal the target that we have a message for it.
467 */
468static __inline void
469aic_sched_msgout(struct aic_softc *aic, u_int8_t msg)
470{
471	if (msg) {
472		aic->msg_buf[0] = msg;
473		aic->msg_len = 1;
474	}
475	aic->msg_outq |= AIC_MSG_MSGBUF;
476	aic_outb(aic, SCSISIGO, aic_inb(aic, SCSISIGI) | ATNO);
477}
478
479/*
480 * Wait for SPIORDY (SCSI PIO ready) flag, or a phase change.
481 */
482static __inline int
483aic_spiordy(struct aic_softc *aic)
484{
485	int spincount = 100;
486	u_int8_t spiordy = 0;
487
488	while (spincount-- && !(aic_inb(aic, DMASTAT) & INTSTAT) &&
489	    !(spiordy = aic_inb(aic, SSTAT0) & SPIORDY))
490		;
491	return (spiordy);
492}
493
494/*
495 * Read messages.
496 */
497static void
498aic_msgin(struct aic_softc *aic)
499{
500	int msglen;
501
502	CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_msgin\n"));
503
504	aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
505	aic_outb(aic, SXFRCTL0, CHEN|SPIOEN);
506
507	aic->flags &= ~AIC_DROP_MSGIN;
508	aic->msg_len = 0;
509	do {
510		/*
511		 * If a parity error is detected, drop the remaining
512		 * bytes and inform the target so it could resend
513		 * the messages.
514		 */
515		if (aic_inb(aic, SSTAT1) & SCSIPERR) {
516			aic_outb(aic, CLRSINT1, CLRSCSIPERR);
517			aic->flags |= AIC_DROP_MSGIN;
518			aic_sched_msgout(aic, MSG_PARITY_ERROR);
519		}
520		if ((aic->flags & AIC_DROP_MSGIN)) {
521			aic_inb(aic, SCSIDAT);
522			continue;
523		}
524		/* read the message byte without ACKing on it */
525		aic->msg_buf[aic->msg_len++] = aic_inb(aic, SCSIBUS);
526		if (aic->msg_buf[0] == MSG_EXTENDED) {
527			if (aic->msg_len < 2) {
528				(void) aic_inb(aic, SCSIDAT);
529				continue;
530			}
531			switch (aic->msg_buf[2]) {
532			case MSG_EXT_SDTR:
533				msglen = MSG_EXT_SDTR_LEN;
534				break;
535			case MSG_EXT_WDTR:
536				msglen = MSG_EXT_WDTR_LEN;
537				break;
538			default:
539				msglen = 0;
540				break;
541			}
542			if (aic->msg_buf[1] != msglen) {
543				aic->flags |= AIC_DROP_MSGIN;
544				aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
545			}
546			msglen += 2;
547		} else if (aic->msg_buf[0] & 0x20)
548			msglen = 2;
549		else
550			msglen = 1;
551		/*
552		 * If we have a complete message, handle it before the final
553		 * ACK (in case we decide to reject the message).
554		 */
555		if (aic->msg_len == msglen) {
556			aic_handle_msgin(aic);
557			aic->msg_len = 0;
558		}
559		/* ACK on the message byte */
560		(void) aic_inb(aic, SCSIDAT);
561	} while (aic_spiordy(aic));
562
563	aic_outb(aic, SXFRCTL0, CHEN);
564	aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
565}
566
567/*
568 * Handle a message.
569 */
570static void
571aic_handle_msgin(struct aic_softc *aic)
572{
573	struct aic_scb *scb;
574	struct ccb_hdr *ccb_h;
575	struct aic_tinfo *ti;
576	struct ccb_trans_settings neg;
577
578	if (aic->state == AIC_RESELECTED) {
579		int tag;
580
581		ti = &aic->tinfo[aic->target];
582		/*
583		 * We expect to see an IDENTIFY message, possibly followed
584		 * by a SIMPLE_Q_TAG message.
585		 */
586		if (MSG_ISIDENTIFY(aic->msg_buf[0])) {
587			aic->lun = aic->msg_buf[0] & MSG_IDENTIFY_LUNMASK;
588			if (ti->flags & TINFO_TAG_ENB)
589				return;
590			else
591				tag = -1;
592		} else if (aic->msg_buf[0] != MSG_SIMPLE_Q_TAG) {
593			tag = aic->msg_buf[1];
594		} else {
595			aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
596			return;
597		}
598
599		/* Find the nexus */
600		TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) {
601			scb = (struct aic_scb *)ccb_h->ccb_scb_ptr;
602			if (ccb_h->target_id == aic->target &&
603			    ccb_h->target_lun == aic->lun &&
604			    (tag == -1 || scb->tag == tag))
605				break;
606		}
607
608		/* ABORT if nothing is found */
609		if (!ccb_h) {
610			if (tag == -1)
611				aic_sched_msgout(aic, MSG_ABORT);
612			else
613				aic_sched_msgout(aic, MSG_ABORT_TAG);
614			xpt_async(AC_UNSOL_RESEL, ccb_h->path, NULL);
615			return;
616		}
617
618		/* Reestablish the nexus */
619		TAILQ_REMOVE(&aic->nexus_ccbs, ccb_h, sim_links.tqe);
620		aic->nexus = scb;
621		scb->flags &= ~SCB_DISCONNECTED;
622		aic->state = AIC_HASNEXUS;
623		CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, ("reconnected\n"));
624		return;
625	}
626
627	switch (aic->msg_buf[0]) {
628	case MSG_CMDCOMPLETE: {
629		struct ccb_scsiio *csio;
630		scb = aic->nexus;
631		ccb_h = &scb->ccb->ccb_h;
632		csio = &scb->ccb->csio;
633		ccb_h->status &= ~CAM_STATUS_MASK;
634		if ((scb->flags & SCB_SENSE) != 0) {
635			/* auto REQUEST SENSE command */
636			scb->flags &= ~SCB_SENSE;
637			csio->sense_resid = scb->data_len;
638			if (scb->status == SCSI_STATUS_OK) {
639				ccb_h->status |=
640				    CAM_SCSI_STATUS_ERROR|CAM_AUTOSNS_VALID;
641				/*scsi_sense_print(csio);*/
642			} else {
643				ccb_h->status |= CAM_AUTOSENSE_FAIL;
644				printf("ccb %p sense failed %x\n",
645				    ccb_h, scb->status);
646			}
647		} else {
648			csio->scsi_status = scb->status;
649			csio->resid = scb->data_len;
650			if (scb->status == SCSI_STATUS_OK) {
651				/* everything goes well */
652				ccb_h->status |= CAM_REQ_CMP;
653			} else if ((ccb_h->flags & CAM_DIS_AUTOSENSE) == 0 &&
654			    (csio->scsi_status == SCSI_STATUS_CHECK_COND ||
655			     csio->scsi_status == SCSI_STATUS_CMD_TERMINATED)) {
656				/* try to retrieve sense information */
657				scb->flags |= SCB_SENSE;
658				aic->flags |= AIC_BUSFREE_OK;
659				return;
660			} else
661				ccb_h->status |= CAM_SCSI_STATUS_ERROR;
662		}
663		aic_done(aic, scb);
664		aic->flags |= AIC_BUSFREE_OK;
665		break;
666	}
667	case MSG_EXTENDED:
668		switch (aic->msg_buf[2]) {
669		case MSG_EXT_SDTR:
670			scb = aic->nexus;
671			ti = &aic->tinfo[scb->target];
672			if (ti->flags & TINFO_SDTR_SENT) {
673				ti->current.period = aic->msg_buf[3];
674				ti->current.offset = aic->msg_buf[4];
675			} else {
676				ti->current.period = aic->msg_buf[3] =
677					max(ti->goal.period, aic->msg_buf[3]);
678				ti->current.offset = aic->msg_buf[4] =
679					min(ti->goal.offset, aic->msg_buf[4]);
680				/*
681				 * The target initiated the negotiation,
682				 * send back a response.
683				 */
684				aic_sched_msgout(aic, 0);
685			}
686			ti->flags &= ~(TINFO_SDTR_SENT|TINFO_SDTR_NEGO);
687			ti->scsirate = ti->current.offset ? ti->current.offset |
688			    ((ti->current.period * 4 + 49) / 50 - 2) << 4 : 0;
689			aic_outb(aic, SCSIRATE, ti->scsirate);
690			neg.sync_period = ti->goal.period = ti->current.period;
691			neg.sync_offset = ti->goal.offset = ti->current.offset;
692			neg.valid = CCB_TRANS_SYNC_RATE_VALID
693				  | CCB_TRANS_SYNC_OFFSET_VALID;
694			ccb_h = &scb->ccb->ccb_h;
695			xpt_setup_ccb(&neg.ccb_h, ccb_h->path, 1);
696			xpt_async(AC_TRANSFER_NEG, ccb_h->path, &neg);
697			break;
698		case MSG_EXT_WDTR:
699		default:
700			aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
701			break;
702		}
703		break;
704	case MSG_DISCONNECT:
705		scb = aic->nexus;
706		ccb_h = &scb->ccb->ccb_h;
707		TAILQ_INSERT_HEAD(&aic->nexus_ccbs, ccb_h, sim_links.tqe);
708		scb->flags |= SCB_DISCONNECTED;
709		ti = &aic->tinfo[scb->target];
710		aic->flags |= AIC_BUSFREE_OK;
711		CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, ("disconnected\n"));
712		break;
713	case MSG_MESSAGE_REJECT:
714		switch (aic->msg_outq & -aic->msg_outq) {
715		case AIC_MSG_TAG_Q:
716			scb = aic->nexus;
717			ti = &aic->tinfo[scb->target];
718			ti->flags &= ~TINFO_TAG_ENB;
719			ti->lubusy |= 1 << scb->lun;
720			break;
721		case AIC_MSG_SDTR:
722			scb = aic->nexus;
723			ti = &aic->tinfo[scb->target];
724			ti->current.period = ti->goal.period = 0;
725			ti->current.offset = ti->goal.offset = 0;
726			ti->flags &= ~(TINFO_SDTR_SENT|TINFO_SDTR_NEGO);
727			ti->scsirate = 0;
728			aic_outb(aic, SCSIRATE, ti->scsirate);
729			neg.sync_period = ti->current.period;
730			neg.sync_offset = ti->current.offset;
731			neg.valid = CCB_TRANS_SYNC_RATE_VALID
732				  | CCB_TRANS_SYNC_OFFSET_VALID;
733			ccb_h = &scb->ccb->ccb_h;
734			xpt_setup_ccb(&neg.ccb_h, ccb_h->path, 1);
735			xpt_async(AC_TRANSFER_NEG, ccb_h->path, &neg);
736			break;
737		default:
738			break;
739		}
740		break;
741	case MSG_SAVEDATAPOINTER:
742		break;
743	case MSG_RESTOREPOINTERS:
744		break;
745	case MSG_NOOP:
746		break;
747	default:
748		aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
749		break;
750	}
751}
752
753/*
754 * Send messages.
755 */
756static void
757aic_msgout(struct aic_softc *aic)
758{
759	struct aic_scb *scb;
760	union ccb *ccb;
761	struct aic_tinfo *ti;
762	int msgidx = 0;
763
764	CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_msgout\n"));
765
766	aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
767	aic_outb(aic, SXFRCTL0, CHEN|SPIOEN);
768
769	/*
770	 * If the previous phase is also the message out phase,
771	 * we need to retransmit all the messages, probably
772	 * because the target has detected a parity error during
773	 * the past transmission.
774	 */
775	if (aic->prev_phase == PH_MSGOUT)
776		aic->msg_outq = aic->msg_sent;
777
778	do {
779		int q = aic->msg_outq;
780		if (msgidx > 0 && msgidx == aic->msg_len) {
781			/* complete message sent, start the next one */
782			q &= -q;
783			aic->msg_sent |= q;
784			aic->msg_outq ^= q;
785			q = aic->msg_outq;
786			msgidx = 0;
787		}
788		if (msgidx == 0) {
789			/* setup the message */
790			switch (q & -q) {
791			case AIC_MSG_IDENTIFY:
792				scb = aic->nexus;
793				ccb = scb->ccb;
794				ti = &aic->tinfo[scb->target];
795				aic->msg_buf[0] = MSG_IDENTIFY(scb->lun,
796				    (ti->flags & TINFO_DISC_ENB) &&
797				    (ccb->ccb_h.flags & CAM_DIS_DISCONNECT));
798				aic->msg_len = 1;
799				break;
800			case AIC_MSG_TAG_Q:
801				scb = aic->nexus;
802				ccb = scb->ccb;
803				aic->msg_buf[0] = ccb->csio.tag_action;
804				aic->msg_buf[1] = scb->tag;
805				aic->msg_len = 2;
806				break;
807			case AIC_MSG_SDTR:
808				scb = aic->nexus;
809				ti = &aic->tinfo[scb->target];
810				aic->msg_buf[0] = MSG_EXTENDED;
811				aic->msg_buf[1] = MSG_EXT_SDTR_LEN;
812				aic->msg_buf[2] = MSG_EXT_SDTR;
813				aic->msg_buf[3] = ti->goal.period;
814				aic->msg_buf[4] = ti->goal.offset;
815				aic->msg_len = MSG_EXT_SDTR_LEN + 2;
816				ti->flags |= TINFO_SDTR_SENT;
817				break;
818			case AIC_MSG_MSGBUF:
819				/* a single message already in the buffer */
820				if (aic->msg_buf[0] == MSG_BUS_DEV_RESET ||
821				    aic->msg_buf[0] == MSG_ABORT ||
822				    aic->msg_buf[0] == MSG_ABORT_TAG)
823					aic->flags |= AIC_BUSFREE_OK;
824				break;
825			}
826		}
827		/*
828		 * If this is the last message byte of all messages,
829		 * clear ATNO to signal transmission complete.
830		 */
831		if ((q & (q - 1)) == 0 && msgidx == aic->msg_len - 1)
832			aic_outb(aic, CLRSINT1, CLRATNO);
833		/* transmit the message byte */
834		aic_outb(aic, SCSIDAT, aic->msg_buf[msgidx++]);
835	} while (aic_spiordy(aic));
836
837	aic_outb(aic, SXFRCTL0, CHEN);
838	aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
839}
840
841/*
842 * Read data bytes.
843 */
844static void
845aic_datain(struct aic_softc *aic)
846{
847	struct aic_scb *scb = aic->nexus;
848	u_int8_t dmastat, dmacntrl0;
849	int n;
850
851	CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_datain\n"));
852
853	aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
854	aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN);
855
856	dmacntrl0 = ENDMA;
857	if (aic->flags & AIC_DWIO_ENABLE)
858		dmacntrl0 |= DWORDPIO;
859	aic_outb(aic, DMACNTRL0, dmacntrl0);
860
861	while (scb->data_len > 0) {
862		for (;;) {
863			/* wait for the fifo to fill up or a phase change */
864			dmastat = aic_inb(aic, DMASTAT);
865			if (dmastat & (INTSTAT|DFIFOFULL))
866				break;
867		}
868		if (dmastat & DFIFOFULL) {
869			n = FIFOSIZE;
870		} else {
871			/*
872			 * No more data, wait for the remaining bytes in
873			 * the scsi fifo to be transfer to the host fifo.
874			 */
875			while (!(aic_inb(aic, SSTAT2) & SEMPTY))
876				;
877			n = aic_inb(aic, FIFOSTAT);
878		}
879		n = imin(scb->data_len, n);
880		if (aic->flags & AIC_DWIO_ENABLE) {
881			if (n >= 12) {
882				aic_insl(aic, DMADATALONG, scb->data_ptr, n>>2);
883				scb->data_ptr += n & ~3;
884				scb->data_len -= n & ~3;
885				n &= 3;
886			}
887		} else {
888			if (n >= 8) {
889				aic_insw(aic, DMADATA, scb->data_ptr, n >> 1);
890				scb->data_ptr += n & ~1;
891				scb->data_len -= n & ~1;
892				n &= 1;
893			}
894		}
895		if (n) {
896			aic_outb(aic, DMACNTRL0, ENDMA|B8MODE);
897			aic_insb(aic, DMADATA, scb->data_ptr, n);
898			scb->data_ptr += n;
899			scb->data_len -= n;
900			aic_outb(aic, DMACNTRL0, dmacntrl0);
901		}
902
903		if (dmastat & INTSTAT)
904			break;
905	}
906
907	aic_outb(aic, SXFRCTL0, CHEN);
908	aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
909}
910
911/*
912 * Send data bytes.
913 */
914static void
915aic_dataout(struct aic_softc *aic)
916{
917	struct aic_scb *scb = aic->nexus;
918	u_int8_t dmastat, dmacntrl0;
919	int n;
920
921	CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_dataout\n"));
922
923	aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
924	aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN);
925
926	dmacntrl0 = ENDMA|WRITE;
927	if (aic->flags & AIC_DWIO_ENABLE)
928		dmacntrl0 |= DWORDPIO;
929	aic_outb(aic, DMACNTRL0, dmacntrl0);
930
931	while (scb->data_len > 0) {
932		for (;;) {
933			/* wait for the fifo to clear up or a phase change */
934			dmastat = aic_inb(aic, DMASTAT);
935			if (dmastat & (INTSTAT|DFIFOEMP))
936				break;
937		}
938		if (dmastat & INTSTAT)
939			break;
940		n = imin(scb->data_len, FIFOSIZE);
941		if (aic->flags & AIC_DWIO_ENABLE) {
942			if (n >= 12) {
943				aic_outsl(aic, DMADATALONG, scb->data_ptr,n>>2);
944				scb->data_ptr += n & ~3;
945				scb->data_len -= n & ~3;
946				n &= 3;
947			}
948		} else {
949			if (n >= 8) {
950				aic_outsw(aic, DMADATA, scb->data_ptr, n >> 1);
951				scb->data_ptr += n & ~1;
952				scb->data_len -= n & ~1;
953				n &= 1;
954			}
955		}
956		if (n) {
957			aic_outb(aic, DMACNTRL0, ENDMA|WRITE|B8MODE);
958			aic_outsb(aic, DMADATA, scb->data_ptr, n);
959			scb->data_ptr += n;
960			scb->data_len -= n;
961			aic_outb(aic, DMACNTRL0, dmacntrl0);
962		}
963	}
964
965	for (;;) {
966		/* wait until all bytes in the fifos are transmitted */
967		dmastat = aic_inb(aic, DMASTAT);
968		if (dmastat & INTSTAT)
969			break;
970		if ((dmastat & DFIFOEMP) && (aic_inb(aic, SSTAT2) & SEMPTY))
971			break;
972	}
973
974	aic_outb(aic, SXFRCTL0, CHEN);
975	aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
976}
977
978/*
979 * Send the scsi command.
980 */
981static void
982aic_cmd(struct aic_softc *aic)
983{
984	struct aic_scb *scb = aic->nexus;
985	struct scsi_request_sense sense_cmd;
986
987	if (scb->flags & SCB_SENSE) {
988		/* autosense request */
989		sense_cmd.opcode = REQUEST_SENSE;
990		sense_cmd.byte2 = scb->lun << 5;
991		sense_cmd.length = scb->ccb->csio.sense_len;
992		sense_cmd.control = 0;
993		sense_cmd.unused[0] = 0;
994		sense_cmd.unused[1] = 0;
995		scb->cmd_ptr = (u_int8_t *)&sense_cmd;
996		scb->cmd_len = sizeof(sense_cmd);
997		scb->data_ptr = (u_int8_t *)&scb->ccb->csio.sense_data;
998		scb->data_len = scb->ccb->csio.sense_len;
999	}
1000
1001	aic_outb(aic, DMACNTRL0, ENDMA|WRITE);
1002	aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN);
1003	aic_outsw(aic, DMADATA, (u_int16_t *)scb->cmd_ptr,
1004		scb->cmd_len >> 1);
1005	while ((aic_inb(aic, SSTAT2) & SEMPTY) == 0 &&
1006	    (aic_inb(aic, DMASTAT) & INTSTAT) == 0)
1007		;
1008	aic_outb(aic, SXFRCTL0, CHEN);
1009}
1010
1011/*
1012 * Finish off a command. The caller is responsible to remove the ccb
1013 * from any queue.
1014 */
1015static void
1016aic_done(struct aic_softc *aic, struct aic_scb *scb)
1017{
1018	union ccb *ccb = scb->ccb;
1019
1020	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE,
1021		  ("aic_done - ccb %p status %x resid %d\n",
1022		   ccb, ccb->ccb_h.status, ccb->csio.resid));
1023
1024	untimeout(aic_timeout, (caddr_t)scb, ccb->ccb_h.timeout_ch);
1025
1026	if ((scb->flags & SCB_DEVICE_RESET) != 0 &&
1027	    ccb->ccb_h.func_code != XPT_RESET_DEV) {
1028		struct cam_path *path;
1029		struct ccb_hdr *ccb_h;
1030		cam_status error;
1031
1032		error = xpt_create_path(&path, /*periph*/NULL,
1033					cam_sim_path(aic->sim),
1034					scb->target,
1035					CAM_LUN_WILDCARD);
1036
1037		if (error == CAM_REQ_CMP)
1038			xpt_async(AC_SENT_BDR, path, NULL);
1039
1040		ccb_h = TAILQ_FIRST(&aic->pending_ccbs);
1041		while (ccb_h != NULL) {
1042			struct aic_scb *pending_scb;
1043
1044			pending_scb = (struct aic_scb *)ccb_h->ccb_scb_ptr;
1045			if (ccb_h->target_id == scb->target) {
1046				ccb_h->status = CAM_BDR_SENT;
1047				ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe);
1048				TAILQ_REMOVE(&aic->pending_ccbs,
1049				    &pending_scb->ccb->ccb_h, sim_links.tqe);
1050				aic_done(aic, pending_scb);
1051			} else {
1052				ccb_h->timeout_ch =
1053				    timeout(aic_timeout, (caddr_t)pending_scb,
1054					(ccb_h->timeout * hz) / 1000);
1055				ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe);
1056			}
1057		}
1058
1059		ccb_h = TAILQ_FIRST(&aic->nexus_ccbs);
1060		while (ccb_h != NULL) {
1061			struct aic_scb *nexus_scb;
1062
1063			nexus_scb = (struct aic_scb *)ccb_h->ccb_scb_ptr;
1064			if (ccb_h->target_id == scb->target) {
1065				ccb_h->status = CAM_BDR_SENT;
1066				ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe);
1067				TAILQ_REMOVE(&aic->nexus_ccbs,
1068				    &nexus_scb->ccb->ccb_h, sim_links.tqe);
1069				aic_done(aic, nexus_scb);
1070			} else {
1071				ccb_h->timeout_ch =
1072				    timeout(aic_timeout, (caddr_t)nexus_scb,
1073					(ccb_h->timeout * hz) / 1000);
1074				ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe);
1075			}
1076		}
1077	}
1078
1079	if (aic->nexus == scb || scb->flags & SCB_DISCONNECTED)
1080		aic->tinfo[scb->target].lubusy &= ~(1 << scb->lun);
1081
1082	if (aic->nexus == scb) {
1083		aic->nexus = NULL;
1084		aic->state = AIC_IDLE;
1085	}
1086	aic_free_scb(aic, scb);
1087	xpt_done(ccb);
1088}
1089
1090static void
1091aic_poll(struct cam_sim *sim)
1092{
1093	aic_intr(cam_sim_softc(sim));
1094}
1095
1096static void
1097aic_timeout(void *arg)
1098{
1099	struct aic_scb *scb = (struct aic_scb *)arg;
1100	union ccb *ccb = scb->ccb;
1101	struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr;
1102	int s;
1103
1104	xpt_print_path(ccb->ccb_h.path);
1105	printf("ccb %p - timed out", ccb);
1106	if (aic->nexus && aic->nexus != scb)
1107		printf(", nexus %p", aic->nexus->ccb);
1108	printf("\n");
1109
1110	s = splcam();
1111
1112	if ((scb->flags & SCB_ACTIVE) == 0) {
1113		splx(s);
1114		xpt_print_path(ccb->ccb_h.path);
1115		printf("ccb %p - timed out already completed\n", ccb);
1116		return;
1117	}
1118
1119	if ((scb->flags & SCB_DEVICE_RESET) == 0 && aic->nexus == scb) {
1120		struct ccb_hdr *ccb_h = &scb->ccb->ccb_h;
1121
1122		if ((ccb_h->status & CAM_RELEASE_SIMQ) == 0) {
1123			xpt_freeze_simq(aic->sim, /*count*/1);
1124			ccb_h->status |= CAM_RELEASE_SIMQ;
1125		}
1126
1127		TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) {
1128			untimeout(aic_timeout, (caddr_t)ccb_h->ccb_scb_ptr,
1129			    ccb_h->timeout_ch);
1130		}
1131
1132		TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) {
1133			untimeout(aic_timeout, (caddr_t)ccb_h->ccb_scb_ptr,
1134			    ccb_h->timeout_ch);
1135		}
1136
1137		scb->flags |= SCB_DEVICE_RESET;
1138		ccb->ccb_h.timeout_ch =
1139		    timeout(aic_timeout, (caddr_t)scb, 5 * hz);
1140		aic_sched_msgout(aic, MSG_BUS_DEV_RESET);
1141	} else {
1142		if (aic->nexus == scb) {
1143			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
1144			ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
1145			aic_done(aic, scb);
1146		}
1147		aic_reset(aic, /*initiate_reset*/TRUE);
1148	}
1149
1150	splx(s);
1151}
1152
1153void
1154aic_intr(void *arg)
1155{
1156	struct aic_softc *aic = (struct aic_softc *)arg;
1157	u_int8_t sstat0, sstat1;
1158	union ccb *ccb;
1159	struct aic_scb *scb;
1160
1161	if (!(aic_inb(aic, DMASTAT) & INTSTAT))
1162		return;
1163
1164	aic_outb(aic, DMACNTRL0, 0);
1165
1166	sstat0 = aic_inb(aic, SSTAT0);
1167	sstat1 = aic_inb(aic, SSTAT1);
1168
1169	if ((sstat1 & SCSIRSTI) != 0) {
1170		/* a device-initiated bus reset */
1171		aic_outb(aic, CLRSINT1, CLRSCSIRSTI);
1172		aic_reset(aic, /*initiate_reset*/FALSE);
1173		return;
1174	}
1175
1176	if ((sstat1 & SCSIPERR) != 0) {
1177		aic_outb(aic, CLRSINT1, CLRSCSIPERR);
1178		aic_sched_msgout(aic, MSG_PARITY_ERROR);
1179		aic_outb(aic, DMACNTRL0, INTEN);
1180		return;
1181	}
1182
1183	if (aic_inb(aic, SSTAT4)) {
1184		aic_outb(aic, CLRSERR, CLRSYNCERR|CLRFWERR|CLRFRERR);
1185		aic_reset(aic, /*initiate_reset*/TRUE);
1186		return;
1187	}
1188
1189	if (aic->state != AIC_HASNEXUS) {
1190		if ((sstat0 & SELDI) != 0) {
1191			aic_reselected(aic);
1192			aic_outb(aic, DMACNTRL0, INTEN);
1193			return;
1194		}
1195
1196		if ((sstat0 & SELDO) != 0) {
1197			aic_selected(aic);
1198			aic_outb(aic, DMACNTRL0, INTEN);
1199			return;
1200		}
1201
1202		if ((sstat1 & SELTO) != 0) {
1203			scb = aic->nexus;
1204			ccb = scb->ccb;
1205			ccb->ccb_h.status = CAM_SEL_TIMEOUT;
1206			aic_done(aic, scb);
1207			while ((sstat1 & BUSFREE) == 0)
1208				sstat1 = aic_inb(aic, SSTAT1);
1209			aic->flags |= AIC_BUSFREE_OK;
1210		}
1211	}
1212
1213	if ((sstat1 & REQINIT) != 0) {
1214		u_int8_t phase = aic_inb(aic, SCSISIGI) & PH_MASK;
1215		aic_outb(aic, SCSISIGO, phase);
1216		aic_outb(aic, CLRSINT1, CLRPHASECHG);
1217
1218		switch (phase) {
1219		case PH_MSGOUT:
1220			aic_msgout(aic);
1221			break;
1222		case PH_MSGIN:
1223			aic_msgin(aic);
1224			break;
1225		case PH_STAT:
1226			scb = aic->nexus;
1227			ccb = scb->ccb;
1228			aic_outb(aic, DMACNTRL0, 0);
1229			aic_outb(aic, SXFRCTL0, CHEN|SPIOEN);
1230			scb->status = aic_inb(aic, SCSIDAT);
1231			aic_outb(aic, SXFRCTL0, CHEN);
1232			break;
1233		case PH_CMD:
1234			aic_cmd(aic);
1235			break;
1236		case PH_DATAIN:
1237			aic_datain(aic);
1238			break;
1239		case PH_DATAOUT:
1240			aic_dataout(aic);
1241			break;
1242		}
1243		aic->prev_phase = phase;
1244		aic_outb(aic, DMACNTRL0, INTEN);
1245		return;
1246	}
1247
1248	if ((sstat1 & BUSFREE) != 0) {
1249		aic_outb(aic, SCSISEQ, 0);
1250		aic_outb(aic, CLRSINT0, sstat0);
1251		aic_outb(aic, CLRSINT1, sstat1);
1252		if ((scb = aic->nexus)) {
1253			if ((aic->flags & AIC_BUSFREE_OK) == 0) {
1254				ccb = scb->ccb;
1255				ccb->ccb_h.status = CAM_UNEXP_BUSFREE;
1256				aic_done(aic, scb);
1257			} else if (scb->flags & SCB_SENSE) {
1258				/* autosense request */
1259				aic->flags &= ~AIC_BUSFREE_OK;
1260				aic_select(aic);
1261				aic_outb(aic, DMACNTRL0, INTEN);
1262				return;
1263			}
1264		}
1265		aic->flags &= ~AIC_BUSFREE_OK;
1266		aic->state = AIC_IDLE;
1267		aic_start(aic);
1268		aic_outb(aic, DMACNTRL0, INTEN);
1269		return;
1270	}
1271
1272	printf("aic_intr: unexpected intr sstat0 %x sstat1 %x\n",
1273		sstat0, sstat1);
1274	aic_outb(aic, DMACNTRL0, INTEN);
1275}
1276
1277/*
1278 * Reset ourselves.
1279 */
1280static void
1281aic_chip_reset(struct aic_softc *aic)
1282{
1283	/*
1284	 * Doc. recommends to clear these two registers before
1285	 * operations commence
1286	 */
1287	aic_outb(aic, SCSITEST, 0);
1288	aic_outb(aic, TEST, 0);
1289
1290	/* Reset SCSI-FIFO and abort any transfers */
1291	aic_outb(aic, SXFRCTL0, CHEN|CLRCH|CLRSTCNT);
1292
1293	/* Reset HOST-FIFO */
1294	aic_outb(aic, DMACNTRL0, RSTFIFO);
1295	aic_outb(aic, DMACNTRL1, 0);
1296
1297	/* Disable all selection features */
1298	aic_outb(aic, SCSISEQ, 0);
1299	aic_outb(aic, SXFRCTL1, 0);
1300
1301	/* Disable interrupts */
1302	aic_outb(aic, SIMODE0, 0);
1303	aic_outb(aic, SIMODE1, 0);
1304
1305	/* Clear interrupts */
1306	aic_outb(aic, CLRSINT0, 0x7f);
1307	aic_outb(aic, CLRSINT1, 0xef);
1308
1309	/* Disable synchronous transfers */
1310	aic_outb(aic, SCSIRATE, 0);
1311
1312	/* Haven't seen ant errors (yet) */
1313	aic_outb(aic, CLRSERR, 0x07);
1314
1315	/* Set our SCSI-ID */
1316	aic_outb(aic, SCSIID, aic->initiator << OID_S);
1317	aic_outb(aic, BRSTCNTRL, EISA_BRST_TIM);
1318}
1319
1320/*
1321 * Reset the SCSI bus
1322 */
1323static void
1324aic_scsi_reset(struct aic_softc *aic)
1325{
1326	aic_outb(aic, SCSISEQ, SCSIRSTO);
1327	DELAY(500);
1328	aic_outb(aic, SCSISEQ, 0);
1329	DELAY(50);
1330}
1331
1332/*
1333 * Reset. Abort all pending commands.
1334 */
1335static void
1336aic_reset(struct aic_softc *aic, int initiate_reset)
1337{
1338	struct ccb_hdr *ccb_h;
1339
1340	CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_reset\n"));
1341
1342	if (initiate_reset)
1343		aic_scsi_reset(aic);
1344	aic_chip_reset(aic);
1345
1346	xpt_async(AC_BUS_RESET, aic->path, NULL);
1347
1348	while ((ccb_h = TAILQ_FIRST(&aic->pending_ccbs)) != NULL) {
1349		TAILQ_REMOVE(&aic->pending_ccbs, ccb_h, sim_links.tqe);
1350		ccb_h->status &= ~CAM_STATUS_MASK;
1351		ccb_h->status |= CAM_SCSI_BUS_RESET;
1352		aic_done(aic, (struct aic_scb *)ccb_h->ccb_scb_ptr);
1353	}
1354
1355	while ((ccb_h = TAILQ_FIRST(&aic->nexus_ccbs)) != NULL) {
1356		TAILQ_REMOVE(&aic->nexus_ccbs, ccb_h, sim_links.tqe);
1357		ccb_h->status &= ~CAM_STATUS_MASK;
1358		ccb_h->status |= CAM_SCSI_BUS_RESET;
1359		aic_done(aic, (struct aic_scb *)ccb_h->ccb_scb_ptr);
1360	}
1361
1362	if (aic->nexus) {
1363		ccb_h = &aic->nexus->ccb->ccb_h;
1364		ccb_h->status &= ~CAM_STATUS_MASK;
1365		ccb_h->status |= CAM_SCSI_BUS_RESET;
1366		aic_done(aic, aic->nexus);
1367	}
1368
1369	aic->state = AIC_IDLE;
1370
1371	aic_outb(aic, DMACNTRL0, INTEN);
1372}
1373
1374static void
1375aic_init(struct aic_softc *aic)
1376{
1377	struct aic_scb *scb;
1378	struct aic_tinfo *ti;
1379	u_int8_t porta, portb;
1380	int i;
1381
1382	TAILQ_INIT(&aic->pending_ccbs);
1383	TAILQ_INIT(&aic->nexus_ccbs);
1384	aic->nexus = NULL;
1385	aic->state = AIC_IDLE;
1386	aic->prev_phase = -1;
1387	aic->flags = 0;
1388
1389	aic_chip_reset(aic);
1390	aic_scsi_reset(aic);
1391
1392	porta = aic_inb(aic, PORTA);
1393	portb = aic_inb(aic, PORTB);
1394
1395	aic->initiator = PORTA_ID(porta);
1396	if (PORTA_PARITY(porta))
1397		aic->flags |= AIC_PARITY_ENABLE;
1398	if (PORTB_DISC(portb))
1399		aic->flags |= AIC_DISC_ENABLE;
1400	if (PORTB_DMA(portb))
1401		aic->flags |= AIC_DMA_ENABLE;
1402	if (aic_inb(aic, REV))
1403		aic->flags |= AIC_DWIO_ENABLE;
1404
1405	free_scbs = NULL;
1406	for (i = 255; i >= 0; i--) {
1407		scb = &aic->scbs[i];
1408		scb->tag = i;
1409		aic_free_scb(aic, scb);
1410	}
1411
1412	for (i = 0; i < 8; i++) {
1413		if (i == aic->initiator)
1414			continue;
1415		ti = &aic->tinfo[i];
1416		bzero(ti, sizeof(*ti));
1417		ti->flags = TINFO_TAG_ENB;
1418		if (aic->flags & AIC_DISC_ENABLE)
1419			ti->flags |= TINFO_DISC_ENB;
1420		ti->user.period = AIC_SYNC_PERIOD;
1421		ti->user.offset = AIC_SYNC_OFFSET;
1422		ti->scsirate = 0;
1423	}
1424
1425	aic_outb(aic, DMACNTRL0, INTEN);
1426}
1427
1428int
1429aic_probe(struct aic_softc *aic)
1430{
1431	int i;
1432
1433	/* Remove aic6360 from possible powerdown mode */
1434	aic_outb(aic, DMACNTRL0, 0);
1435
1436#define	STSIZE	16
1437	aic_outb(aic, DMACNTRL1, 0);	/* Reset stack pointer */
1438	for (i = 0; i < STSIZE; i++)
1439		aic_outb(aic, STACK, i);
1440
1441	/* See if we can pull out the same sequence */
1442	aic_outb(aic, DMACNTRL1, 0);
1443	for (i = 0; i < STSIZE && aic_inb(aic, STACK) == i; i++)
1444		;
1445	if (i != STSIZE)
1446		return (ENXIO);
1447#undef	STSIZE
1448	return (0);
1449}
1450
1451int
1452aic_attach(struct aic_softc *aic)
1453{
1454	struct cam_devq *devq;
1455
1456	/*
1457	 * Create the device queue for our SIM.
1458	 */
1459	devq = cam_simq_alloc(256);
1460	if (devq == NULL)
1461		return (ENOMEM);
1462
1463	/*
1464	 * Construct our SIM entry
1465	 */
1466	aic->sim = cam_sim_alloc(aic_action, aic_poll, "aic", aic,
1467				 aic->unit, 2, 256, devq);
1468	if (aic->sim == NULL) {
1469		cam_simq_free(devq);
1470		return (ENOMEM);
1471	}
1472
1473	if (xpt_bus_register(aic->sim, 0) != CAM_SUCCESS) {
1474		cam_sim_free(aic->sim, /*free_devq*/TRUE);
1475		return (ENXIO);
1476	}
1477
1478	if (xpt_create_path(&aic->path, /*periph*/NULL,
1479			    cam_sim_path(aic->sim), CAM_TARGET_WILDCARD,
1480			    CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1481		xpt_bus_deregister(cam_sim_path(aic->sim));
1482		cam_sim_free(aic->sim, /*free_devq*/TRUE);
1483		return (ENXIO);
1484	}
1485
1486	aic_init(aic);
1487
1488	printf("aic%d: %s", aic->unit,
1489	    aic_inb(aic, REV) > 0 ? "aic6360" : "aic6260");
1490	if (aic->flags & AIC_DMA_ENABLE)
1491		printf(", dma");
1492	if (aic->flags & AIC_DISC_ENABLE)
1493		printf(", disconnection");
1494	if (aic->flags & AIC_PARITY_ENABLE)
1495		printf(", parity check");
1496	printf("\n");
1497	return (0);
1498}
1499
1500int
1501aic_detach(struct aic_softc *aic)
1502{
1503	xpt_async(AC_LOST_DEVICE, aic->path, NULL);
1504	xpt_free_path(aic->path);
1505	xpt_bus_deregister(cam_sim_path(aic->sim));
1506	cam_sim_free(aic->sim, /*free_devq*/TRUE);
1507	return (0);
1508}
1509