FreeBSD/Linux Kernel Cross Reference
sys/dev/aic/aic.c
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
1118 aic_poll(struct cam_sim *sim)
1119 {
1120 aic_intr_locked(cam_sim_softc(sim));
1121 }
1122
1123 static void
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
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
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
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
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
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
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
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
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
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 }
Cache object: c8294ca9b8d49209023d7428215842f1
|