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