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