This source file includes following definitions.
- aic_find
- aicattach
- aic_detach
- aic_reset
- aic_scsi_reset
- aic_init
- aic_free_acb
- aic_get_acb
- aic_scsi_cmd
- aic_minphys
- aic_poll
- aic_sched_msgout
- aic_setsync
- aic_select
- aic_reselect
- aic_sched
- aic_sense
- aic_done
- aic_dequeue
- aic_msgin
- aic_msgout
- aic_dataout_pio
- aic_datain_pio
- aicintr
- aic_abort
- aic_timeout
- aic_show_scsi_cmd
- aic_print_acb
- aic_print_active_acb
- aic_dump6360
- aic_dump_driver
1
2
3
4 #ifdef DDB
5 #define integrate
6 #else
7 #define integrate static inline
8 #endif
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 #define AIC_USE_DWORDS 0
78
79
80 #define AIC_USE_SYNCHRONOUS 0
81 #define AIC_SYNC_REQ_ACK_OFS 8
82
83
84 #define AIC_USE_WIDE 0
85 #define AIC_MAX_WIDTH 0
86
87
88 #define AIC_MSG_MAX_ATTEMPT 3
89
90
91 #define AIC_USE_EISA_DMA 0
92 #define AIC_USE_ISA_DMA 0
93
94
95 #define EISA_BRST_TIM ((15<<4) + 1)
96
97
98
99
100
101
102
103
104 #define AIC_MSGIN_SPIN 1
105 #define AIC_MSGOUT_SPIN 1
106
107
108
109
110
111
112
113 #ifndef SMALL_KERNEL
114 #define AIC_DEBUG 1
115 #endif
116
117 #define AIC_ABORT_TIMEOUT 2000
118
119
120
121 #if AIC_USE_EISA_DMA || AIC_USE_ISA_DMA
122 #error "I said not yet! Start paying attention... grumble"
123 #endif
124
125 #include <sys/types.h>
126 #include <sys/param.h>
127 #include <sys/systm.h>
128 #include <sys/kernel.h>
129 #include <sys/errno.h>
130 #include <sys/ioctl.h>
131 #include <sys/device.h>
132 #include <sys/buf.h>
133 #include <sys/proc.h>
134 #include <sys/user.h>
135 #include <sys/queue.h>
136
137 #include <machine/bus.h>
138 #include <machine/intr.h>
139
140 #include <scsi/scsi_all.h>
141 #include <scsi/scsi_message.h>
142 #include <scsi/scsiconf.h>
143
144 #include <dev/isa/isavar.h>
145
146 #include <dev/ic/aic6360reg.h>
147 #include <dev/ic/aic6360var.h>
148
149 #ifndef DDB
150 #define Debugger() panic("should call debugger here (aic6360.c)")
151 #endif
152
153 #ifdef AIC_DEBUG
154 int aic_debug = 0x00;
155 #endif
156
157 void aic_minphys(struct buf *);
158 void aic_init(struct aic_softc *);
159 void aic_done(struct aic_softc *, struct aic_acb *);
160 void aic_dequeue(struct aic_softc *, struct aic_acb *);
161 int aic_scsi_cmd(struct scsi_xfer *);
162 int aic_poll(struct aic_softc *, struct scsi_xfer *, int);
163 integrate void aic_sched_msgout(struct aic_softc *, u_char);
164 integrate void aic_setsync(struct aic_softc *, struct aic_tinfo *);
165 void aic_select(struct aic_softc *, struct aic_acb *);
166 void aic_timeout(void *);
167 void aic_sched(struct aic_softc *);
168 void aic_scsi_reset(struct aic_softc *);
169 void aic_reset(struct aic_softc *);
170 void aic_free_acb(struct aic_softc *, struct aic_acb *, int);
171 struct aic_acb* aic_get_acb(struct aic_softc *, int);
172 int aic_reselect(struct aic_softc *, int);
173 void aic_sense(struct aic_softc *, struct aic_acb *);
174 void aic_msgin(struct aic_softc *);
175 void aic_abort(struct aic_softc *, struct aic_acb *);
176 void aic_msgout(struct aic_softc *);
177 int aic_dataout_pio(struct aic_softc *, u_char *, int);
178 int aic_datain_pio(struct aic_softc *, u_char *, int);
179 #ifdef AIC_DEBUG
180 void aic_print_acb(struct aic_acb *);
181 void aic_dump_driver(struct aic_softc *);
182 void aic_dump6360(struct aic_softc *);
183 void aic_show_scsi_cmd(struct aic_acb *);
184 void aic_print_active_acb(void);
185 #endif
186
187 struct cfdriver aic_cd = {
188 NULL, "aic", DV_DULL
189 };
190
191 struct scsi_adapter aic_switch = {
192 aic_scsi_cmd,
193 #ifdef notyet
194 aic_minphys,
195 #else
196 minphys,
197 #endif
198 0,
199 0,
200 };
201
202 struct scsi_device aic_dev = {
203 NULL,
204 NULL,
205 NULL,
206 NULL,
207 };
208
209
210
211
212
213 int
214 aic_find(bus_space_tag_t iot, bus_space_handle_t ioh)
215 {
216 char chip_id[sizeof(IDSTRING)];
217 int i;
218
219
220 bus_space_write_1(iot, ioh, DMACNTRL0, 0);
221
222
223
224
225
226 AIC_TRACE(("aic: probing for aic-chip\n"));
227
228
229
230
231
232 #define STSIZE 16
233 bus_space_write_1(iot, ioh, DMACNTRL1, 0);
234 for (i = 0; i < STSIZE; i++)
235 bus_space_write_1(iot, ioh, STACK, i);
236
237
238 bus_space_write_1(iot, ioh, DMACNTRL1, 0);
239 for (i = 0; i < STSIZE && bus_space_read_1(iot, ioh, STACK) == i; i++)
240 ;
241 if (i != STSIZE) {
242 AIC_START(("STACK futzed at %d.\n", i));
243 return (0);
244 }
245
246
247
248
249 bzero(chip_id, sizeof(chip_id));
250 bus_space_read_multi_1(iot, ioh, ID, chip_id, sizeof(IDSTRING) - 1);
251 AIC_START(("AIC ID: %s ", chip_id));
252 AIC_START(("chip revision %d\n",
253 (int)bus_space_read_1(iot, ioh, REV)));
254
255 return (1);
256 }
257
258
259
260
261 void
262 aicattach(struct aic_softc *sc)
263 {
264 struct scsibus_attach_args saa;
265 AIC_TRACE(("aicattach "));
266 sc->sc_state = AIC_INIT;
267
268 sc->sc_initiator = 7;
269 sc->sc_freq = 20;
270
271
272
273
274
275
276
277
278
279
280 sc->sc_minsync = (2 * 250) / sc->sc_freq;
281 sc->sc_maxsync = (9 * 250) / sc->sc_freq;
282
283 aic_init(sc);
284
285
286
287
288 sc->sc_link.adapter_softc = sc;
289 sc->sc_link.adapter_target = sc->sc_initiator;
290 sc->sc_link.adapter = &aic_switch;
291 sc->sc_link.device = &aic_dev;
292 sc->sc_link.openings = 2;
293
294 bzero(&saa, sizeof(saa));
295 saa.saa_sc_link = &sc->sc_link;
296
297 config_found(&sc->sc_dev, &saa, scsiprint);
298 }
299
300 int
301 aic_detach(struct device *self, int flags)
302 {
303 struct aic_softc *sc = (struct aic_softc *) self;
304 int rv = 0;
305
306 rv = config_detach_children(&sc->sc_dev, flags);
307
308 return (rv);
309 }
310
311
312
313
314
315
316 void
317 aic_reset(struct aic_softc *sc)
318 {
319 bus_space_tag_t iot = sc->sc_iot;
320 bus_space_handle_t ioh = sc->sc_ioh;
321
322
323
324
325
326 bus_space_write_1(iot, ioh, SCSITEST, 0);
327 bus_space_write_1(iot, ioh, TEST, 0);
328
329
330 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | CLRCH | CLRSTCNT);
331
332
333 bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO);
334 bus_space_write_1(iot, ioh, DMACNTRL1, 0);
335
336
337 bus_space_write_1(iot, ioh, SCSISEQ, 0);
338 bus_space_write_1(iot, ioh, SXFRCTL1, 0);
339
340
341 bus_space_write_1(iot, ioh, SIMODE0, 0x00);
342
343 bus_space_write_1(iot, ioh, CLRSINT0, 0x7f);
344
345
346 bus_space_write_1(iot, ioh, SIMODE1, 0x00);
347
348 bus_space_write_1(iot, ioh, CLRSINT1, 0xef);
349
350
351 bus_space_write_1(iot, ioh, SCSIRATE, 0);
352
353
354 bus_space_write_1(iot, ioh, CLRSERR, 0x07);
355
356
357 bus_space_write_1(iot, ioh, SCSIID, sc->sc_initiator << OID_S);
358 bus_space_write_1(iot, ioh, BRSTCNTRL, EISA_BRST_TIM);
359 }
360
361
362 void
363 aic_scsi_reset(struct aic_softc *sc)
364 {
365 bus_space_tag_t iot = sc->sc_iot;
366 bus_space_handle_t ioh = sc->sc_ioh;
367
368 bus_space_write_1(iot, ioh, SCSISEQ, SCSIRSTO);
369 delay(500);
370 bus_space_write_1(iot, ioh, SCSISEQ, 0);
371 delay(50);
372 }
373
374
375
376
377 void
378 aic_init(struct aic_softc *sc)
379 {
380 bus_space_tag_t iot = sc->sc_iot;
381 bus_space_handle_t ioh = sc->sc_ioh;
382 struct aic_acb *acb;
383 int r;
384
385 aic_reset(sc);
386 aic_scsi_reset(sc);
387 aic_reset(sc);
388
389 if (sc->sc_state == AIC_INIT) {
390
391 TAILQ_INIT(&sc->ready_list);
392 TAILQ_INIT(&sc->nexus_list);
393 TAILQ_INIT(&sc->free_list);
394 sc->sc_nexus = NULL;
395 acb = sc->sc_acb;
396 bzero(acb, sizeof(sc->sc_acb));
397 for (r = 0; r < sizeof(sc->sc_acb) / sizeof(*acb); r++) {
398 TAILQ_INSERT_TAIL(&sc->free_list, acb, chain);
399 acb++;
400 }
401 bzero(&sc->sc_tinfo, sizeof(sc->sc_tinfo));
402 } else {
403
404 sc->sc_state = AIC_CLEANING;
405 if ((acb = sc->sc_nexus) != NULL) {
406 acb->xs->error = XS_DRIVER_STUFFUP;
407 timeout_del(&acb->xs->stimeout);
408 aic_done(sc, acb);
409 }
410 while ((acb = TAILQ_FIRST(&sc->nexus_list)) != NULL) {
411 acb->xs->error = XS_DRIVER_STUFFUP;
412 timeout_del(&acb->xs->stimeout);
413 aic_done(sc, acb);
414 }
415 }
416
417 sc->sc_prevphase = PH_INVALID;
418 for (r = 0; r < 8; r++) {
419 struct aic_tinfo *ti = &sc->sc_tinfo[r];
420
421 ti->flags = 0;
422 #if AIC_USE_SYNCHRONOUS
423 ti->flags |= DO_SYNC;
424 ti->period = sc->sc_minsync;
425 ti->offset = AIC_SYNC_REQ_ACK_OFS;
426 #else
427 ti->period = ti->offset = 0;
428 #endif
429 #if AIC_USE_WIDE
430 ti->flags |= DO_WIDE;
431 ti->width = AIC_MAX_WIDTH;
432 #else
433 ti->width = 0;
434 #endif
435 }
436
437 sc->sc_state = AIC_IDLE;
438 bus_space_write_1(iot, ioh, DMACNTRL0, INTEN);
439 }
440
441 void
442 aic_free_acb(struct aic_softc *sc, struct aic_acb *acb, int flags)
443 {
444 int s;
445
446 s = splbio();
447
448 acb->flags = 0;
449 TAILQ_INSERT_HEAD(&sc->free_list, acb, chain);
450
451
452
453
454
455 if (TAILQ_NEXT(acb, chain) == NULL)
456 wakeup(&sc->free_list);
457
458 splx(s);
459 }
460
461 struct aic_acb *
462 aic_get_acb(struct aic_softc *sc, int flags)
463 {
464 struct aic_acb *acb;
465 int s;
466
467 s = splbio();
468
469 while ((acb = TAILQ_FIRST(&sc->free_list)) == NULL &&
470 (flags & SCSI_NOSLEEP) == 0)
471 tsleep(&sc->free_list, PRIBIO, "aicacb", 0);
472 if (acb) {
473 TAILQ_REMOVE(&sc->free_list, acb, chain);
474 acb->flags |= ACB_ALLOC;
475 }
476
477 splx(s);
478 return acb;
479 }
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507 int
508 aic_scsi_cmd(struct scsi_xfer *xs)
509 {
510 struct scsi_link *sc_link = xs->sc_link;
511 struct aic_softc *sc = sc_link->adapter_softc;
512 struct aic_acb *acb;
513 int s, flags;
514
515 AIC_TRACE(("aic_scsi_cmd "));
516 AIC_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
517 sc_link->target));
518
519 flags = xs->flags;
520 if ((acb = aic_get_acb(sc, flags)) == NULL) {
521 return TRY_AGAIN_LATER;
522 }
523
524
525 acb->xs = xs;
526 acb->timeout = xs->timeout;
527 timeout_set(&xs->stimeout, aic_timeout, acb);
528
529 if (xs->flags & SCSI_RESET) {
530 acb->flags |= ACB_RESET;
531 acb->scsi_cmd_length = 0;
532 acb->data_length = 0;
533 } else {
534 bcopy(xs->cmd, &acb->scsi_cmd, xs->cmdlen);
535 acb->scsi_cmd_length = xs->cmdlen;
536 acb->data_addr = xs->data;
537 acb->data_length = xs->datalen;
538 }
539 acb->target_stat = 0;
540
541 s = splbio();
542
543 TAILQ_INSERT_TAIL(&sc->ready_list, acb, chain);
544 if (sc->sc_state == AIC_IDLE)
545 aic_sched(sc);
546
547 splx(s);
548
549 if ((flags & SCSI_POLL) == 0)
550 return SUCCESSFULLY_QUEUED;
551
552
553 if (aic_poll(sc, xs, acb->timeout)) {
554 aic_timeout(acb);
555 if (aic_poll(sc, xs, acb->timeout))
556 aic_timeout(acb);
557 }
558 return COMPLETE;
559 }
560
561 #ifdef notyet
562
563
564
565 void
566 aic_minphys(struct buf *bp)
567 {
568
569 AIC_TRACE(("aic_minphys "));
570 if (bp->b_bcount > (AIC_NSEG << PGSHIFT))
571 bp->b_bcount = (AIC_NSEG << PGSHIFT);
572 minphys(bp);
573 }
574 #endif
575
576
577
578
579 int
580 aic_poll(struct aic_softc *sc, struct scsi_xfer *xs, int count)
581 {
582 bus_space_tag_t iot = sc->sc_iot;
583 bus_space_handle_t ioh = sc->sc_ioh;
584
585 AIC_TRACE(("aic_poll "));
586 while (count) {
587
588
589
590
591 if ((bus_space_read_1(iot, ioh, DMASTAT) & INTSTAT) != 0)
592 aicintr(sc);
593 if ((xs->flags & ITSDONE) != 0)
594 return 0;
595 delay(1000);
596 count--;
597 }
598 return 1;
599 }
600
601
602
603
604
605 integrate void
606 aic_sched_msgout(struct aic_softc *sc, u_char m)
607 {
608 bus_space_tag_t iot = sc->sc_iot;
609 bus_space_handle_t ioh = sc->sc_ioh;
610
611 if (sc->sc_msgpriq == 0)
612 bus_space_write_1(iot, ioh, SCSISIG, sc->sc_phase | ATNO);
613 sc->sc_msgpriq |= m;
614 }
615
616
617
618
619 integrate void
620 aic_setsync(struct aic_softc *sc, struct aic_tinfo *ti)
621 {
622 #if AIC_USE_SYNCHRONOUS
623 bus_space_tag_t iot = sc->sc_iot;
624 bus_space_handle_t ioh = sc->sc_ioh;
625
626 if (ti->offset != 0)
627 bus_space_write_1(iot, ioh, SCSIRATE,
628 ((ti->period * sc->sc_freq) / 250 - 2) << 4 | ti->offset);
629 else
630 bus_space_write_1(iot, ioh, SCSIRATE, 0);
631 #endif
632 }
633
634
635
636
637
638 void
639 aic_select(struct aic_softc *sc, struct aic_acb *acb)
640 {
641 bus_space_tag_t iot = sc->sc_iot;
642 bus_space_handle_t ioh = sc->sc_ioh;
643 struct scsi_link *sc_link = acb->xs->sc_link;
644 int target = sc_link->target;
645 struct aic_tinfo *ti = &sc->sc_tinfo[target];
646
647 bus_space_write_1(iot, ioh, SCSIID,
648 sc->sc_initiator << OID_S | target);
649 aic_setsync(sc, ti);
650 bus_space_write_1(iot, ioh, SXFRCTL1, STIMO_256ms | ENSTIMER);
651
652
653 bus_space_write_1(iot, ioh, SIMODE0, ENSELDI | ENSELDO);
654 bus_space_write_1(iot, ioh, SIMODE1, ENSCSIRST | ENSELTIMO);
655 bus_space_write_1(iot, ioh, SCSISEQ, ENRESELI | ENSELO | ENAUTOATNO);
656
657 sc->sc_state = AIC_SELECTING;
658 }
659
660 int
661 aic_reselect(struct aic_softc *sc, int message)
662 {
663 u_char selid, target, lun;
664 struct aic_acb *acb;
665 struct scsi_link *sc_link;
666 struct aic_tinfo *ti;
667
668
669
670
671
672
673 selid = sc->sc_selid & ~(1 << sc->sc_initiator);
674 if (selid & (selid - 1)) {
675 printf("%s: reselect with invalid selid %02x; ",
676 sc->sc_dev.dv_xname, selid);
677 printf("sending DEVICE RESET\n");
678 AIC_BREAK();
679 goto reset;
680 }
681
682
683
684
685
686
687 target = ffs(selid) - 1;
688 lun = message & 0x07;
689 TAILQ_FOREACH(acb, &sc->nexus_list, chain) {
690 sc_link = acb->xs->sc_link;
691 if (sc_link->target == target && sc_link->lun == lun)
692 break;
693 }
694 if (acb == NULL) {
695 printf("%s: reselect from target %d lun %d with no nexus; ",
696 sc->sc_dev.dv_xname, target, lun);
697 printf("sending ABORT\n");
698 AIC_BREAK();
699 goto abort;
700 }
701
702
703 TAILQ_REMOVE(&sc->nexus_list, acb, chain);
704 sc->sc_state = AIC_CONNECTED;
705 sc->sc_nexus = acb;
706 ti = &sc->sc_tinfo[target];
707 ti->lubusy |= (1 << lun);
708 aic_setsync(sc, ti);
709
710 if (acb->flags & ACB_RESET)
711 aic_sched_msgout(sc, SEND_DEV_RESET);
712 else if (acb->flags & ACB_ABORT)
713 aic_sched_msgout(sc, SEND_ABORT);
714
715
716 sc->sc_dp = acb->data_addr;
717 sc->sc_dleft = acb->data_length;
718 sc->sc_cp = (u_char *)&acb->scsi_cmd;
719 sc->sc_cleft = acb->scsi_cmd_length;
720
721 return (0);
722
723 reset:
724 aic_sched_msgout(sc, SEND_DEV_RESET);
725 return (1);
726
727 abort:
728 aic_sched_msgout(sc, SEND_ABORT);
729 return (1);
730 }
731
732
733
734
735
736
737
738 void
739 aic_sched(struct aic_softc *sc)
740 {
741 bus_space_tag_t iot = sc->sc_iot;
742 bus_space_handle_t ioh = sc->sc_ioh;
743 struct aic_acb *acb;
744 struct scsi_link *sc_link;
745 struct aic_tinfo *ti;
746
747
748
749
750
751 bus_space_write_1(iot, ioh, CLRSINT1,
752 CLRSELTIMO | CLRBUSFREE | CLRSCSIPERR);
753 TAILQ_FOREACH(acb, &sc->ready_list, chain) {
754 sc_link = acb->xs->sc_link;
755 ti = &sc->sc_tinfo[sc_link->target];
756 if ((ti->lubusy & (1 << sc_link->lun)) == 0) {
757 AIC_MISC(("selecting %d:%d ",
758 sc_link->target, sc_link->lun));
759 TAILQ_REMOVE(&sc->ready_list, acb, chain);
760 sc->sc_nexus = acb;
761 aic_select(sc, acb);
762 return;
763 } else
764 AIC_MISC(("%d:%d busy\n",
765 sc_link->target, sc_link->lun));
766 }
767 AIC_MISC(("idle "));
768
769 bus_space_write_1(iot, ioh, SIMODE0, ENSELDI);
770 bus_space_write_1(iot, ioh, SIMODE1, ENSCSIRST);
771 bus_space_write_1(iot, ioh, SCSISEQ, ENRESELI);
772 }
773
774 void
775 aic_sense(struct aic_softc *sc, struct aic_acb *acb)
776 {
777 struct scsi_xfer *xs = acb->xs;
778 struct scsi_link *sc_link = xs->sc_link;
779 struct aic_tinfo *ti = &sc->sc_tinfo[sc_link->target];
780 struct scsi_sense *ss = (void *)&acb->scsi_cmd;
781
782 AIC_MISC(("requesting sense "));
783
784 bzero(ss, sizeof(*ss));
785 ss->opcode = REQUEST_SENSE;
786 ss->byte2 = sc_link->lun << 5;
787 ss->length = sizeof(struct scsi_sense_data);
788 acb->scsi_cmd_length = sizeof(*ss);
789 acb->data_addr = (char *)&xs->sense;
790 acb->data_length = sizeof(struct scsi_sense_data);
791 acb->flags |= ACB_SENSE;
792 ti->senses++;
793 if (acb->flags & ACB_NEXUS)
794 ti->lubusy &= ~(1 << sc_link->lun);
795 if (acb == sc->sc_nexus) {
796 aic_select(sc, acb);
797 } else {
798 aic_dequeue(sc, acb);
799 TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
800 if (sc->sc_state == AIC_IDLE)
801 aic_sched(sc);
802 }
803 }
804
805
806
807
808 void
809 aic_done(struct aic_softc *sc, struct aic_acb *acb)
810 {
811 struct scsi_xfer *xs = acb->xs;
812 struct scsi_link *sc_link = xs->sc_link;
813 struct aic_tinfo *ti = &sc->sc_tinfo[sc_link->target];
814
815 AIC_TRACE(("aic_done "));
816
817
818
819
820
821
822
823
824
825 if (xs->error == XS_NOERROR) {
826 if (acb->flags & ACB_ABORT) {
827 xs->error = XS_DRIVER_STUFFUP;
828 } else if (acb->flags & ACB_SENSE) {
829 xs->error = XS_SENSE;
830 } else if (acb->target_stat == SCSI_CHECK) {
831
832 xs->resid = acb->data_length;
833 xs->status = acb->target_stat;
834 aic_sense(sc, acb);
835 return;
836 } else {
837 xs->resid = acb->data_length;
838 }
839 }
840
841 xs->flags |= ITSDONE;
842
843 #ifdef AIC_DEBUG
844 if ((aic_debug & AIC_SHOWMISC) != 0) {
845 if (xs->resid != 0)
846 printf("resid=%lu ", (u_long)xs->resid);
847 if (xs->error == XS_SENSE)
848 printf("sense=0x%02x\n", xs->sense.error_code);
849 else
850 printf("error=%d\n", xs->error);
851 }
852 #endif
853
854
855
856
857 if (acb->flags & ACB_NEXUS)
858 ti->lubusy &= ~(1 << sc_link->lun);
859 if (acb == sc->sc_nexus) {
860 sc->sc_nexus = NULL;
861 sc->sc_state = AIC_IDLE;
862 aic_sched(sc);
863 } else
864 aic_dequeue(sc, acb);
865
866 aic_free_acb(sc, acb, xs->flags);
867 ti->cmds++;
868 scsi_done(xs);
869 }
870
871 void
872 aic_dequeue(struct aic_softc *sc, struct aic_acb *acb)
873 {
874
875 if (acb->flags & ACB_NEXUS) {
876 TAILQ_REMOVE(&sc->nexus_list, acb, chain);
877 } else {
878 TAILQ_REMOVE(&sc->ready_list, acb, chain);
879 }
880 }
881
882
883
884
885
886 #define IS1BYTEMSG(m) (((m) != 0x01 && (m) < 0x20) || (m) >= 0x80)
887 #define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
888 #define ISEXTMSG(m) ((m) == 0x01)
889
890
891
892
893
894
895 void
896 aic_msgin(struct aic_softc *sc)
897 {
898 bus_space_tag_t iot = sc->sc_iot;
899 bus_space_handle_t ioh = sc->sc_ioh;
900 u_char sstat1;
901 int n;
902
903 AIC_TRACE(("aic_msgin "));
904
905 if (sc->sc_prevphase == PH_MSGIN) {
906
907 n = sc->sc_imp - sc->sc_imess;
908 goto nextbyte;
909 }
910
911
912 sc->sc_flags &= ~AIC_DROP_MSGIN;
913
914 nextmsg:
915 n = 0;
916 sc->sc_imp = &sc->sc_imess[n];
917
918 nextbyte:
919
920
921
922
923
924 for (;;) {
925 for (;;) {
926 sstat1 = bus_space_read_1(iot, ioh, SSTAT1);
927 if ((sstat1 & (REQINIT | PHASECHG | BUSFREE)) != 0)
928 break;
929
930 }
931 if ((sstat1 & (PHASECHG | BUSFREE)) != 0) {
932
933
934
935
936
937 goto out;
938 }
939
940
941 if ((sstat1 & SCSIPERR) != 0) {
942 sc->sc_flags |= AIC_DROP_MSGIN;
943 aic_sched_msgout(sc, SEND_PARITY_ERROR);
944 }
945
946
947 if ((sc->sc_flags & AIC_DROP_MSGIN) == 0) {
948 if (n >= AIC_MAX_MSG_LEN) {
949 (void) bus_space_read_1(iot, ioh, SCSIDAT);
950 sc->sc_flags |= AIC_DROP_MSGIN;
951 aic_sched_msgout(sc, SEND_REJECT);
952 } else {
953 *sc->sc_imp++ = bus_space_read_1(iot, ioh,
954 SCSIDAT);
955 n++;
956
957
958
959
960
961
962 if (n == 1 && IS1BYTEMSG(sc->sc_imess[0]))
963 break;
964 if (n == 2 && IS2BYTEMSG(sc->sc_imess[0]))
965 break;
966 if (n >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
967 n == sc->sc_imess[1] + 2)
968 break;
969 }
970 } else
971 (void) bus_space_read_1(iot, ioh, SCSIDAT);
972
973
974
975
976
977
978 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
979
980 (void) bus_space_read_1(iot, ioh, SCSIDAT);
981 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
982 while ((bus_space_read_1(iot, ioh, SCSISIG) & ACKI) != 0)
983 ;
984 }
985
986 AIC_MISC(("n=%d imess=0x%02x ", n, sc->sc_imess[0]));
987
988
989 switch (sc->sc_state) {
990 struct aic_acb *acb;
991 struct scsi_link *sc_link;
992 struct aic_tinfo *ti;
993
994 case AIC_CONNECTED:
995 AIC_ASSERT(sc->sc_nexus != NULL);
996 acb = sc->sc_nexus;
997 ti = &sc->sc_tinfo[acb->xs->sc_link->target];
998
999 switch (sc->sc_imess[0]) {
1000 case MSG_CMDCOMPLETE:
1001 if ((long)sc->sc_dleft < 0) {
1002 sc_link = acb->xs->sc_link;
1003 printf("%s: %lu extra bytes from %d:%d\n",
1004 sc->sc_dev.dv_xname, (u_long)-sc->sc_dleft,
1005 sc_link->target, sc_link->lun);
1006 acb->data_length = 0;
1007 }
1008 acb->xs->resid = acb->data_length = sc->sc_dleft;
1009 sc->sc_state = AIC_CMDCOMPLETE;
1010 break;
1011
1012 case MSG_PARITY_ERROR:
1013
1014 aic_sched_msgout(sc, sc->sc_lastmsg);
1015 break;
1016
1017 case MSG_MESSAGE_REJECT:
1018 AIC_MISC(("message rejected %02x ", sc->sc_lastmsg));
1019 switch (sc->sc_lastmsg) {
1020 #if AIC_USE_SYNCHRONOUS + AIC_USE_WIDE
1021 case SEND_IDENTIFY:
1022 ti->flags &= ~(DO_SYNC | DO_WIDE);
1023 ti->period = ti->offset = 0;
1024 aic_setsync(sc, ti);
1025 ti->width = 0;
1026 break;
1027 #endif
1028 #if AIC_USE_SYNCHRONOUS
1029 case SEND_SDTR:
1030 ti->flags &= ~DO_SYNC;
1031 ti->period = ti->offset = 0;
1032 aic_setsync(sc, ti);
1033 break;
1034 #endif
1035 #if AIC_USE_WIDE
1036 case SEND_WDTR:
1037 ti->flags &= ~DO_WIDE;
1038 ti->width = 0;
1039 break;
1040 #endif
1041 case SEND_INIT_DET_ERR:
1042 aic_sched_msgout(sc, SEND_ABORT);
1043 break;
1044 }
1045 break;
1046
1047 case MSG_NOOP:
1048 break;
1049
1050 case MSG_DISCONNECT:
1051 ti->dconns++;
1052 sc->sc_state = AIC_DISCONNECT;
1053 break;
1054
1055 case MSG_SAVEDATAPOINTER:
1056 acb->data_addr = sc->sc_dp;
1057 acb->data_length = sc->sc_dleft;
1058 break;
1059
1060 case MSG_RESTOREPOINTERS:
1061 sc->sc_dp = acb->data_addr;
1062 sc->sc_dleft = acb->data_length;
1063 sc->sc_cp = (u_char *)&acb->scsi_cmd;
1064 sc->sc_cleft = acb->scsi_cmd_length;
1065 break;
1066
1067 case MSG_EXTENDED:
1068 switch (sc->sc_imess[2]) {
1069 #if AIC_USE_SYNCHRONOUS
1070 case MSG_EXT_SDTR:
1071 if (sc->sc_imess[1] != 3)
1072 goto reject;
1073 ti->period = sc->sc_imess[3];
1074 ti->offset = sc->sc_imess[4];
1075 ti->flags &= ~DO_SYNC;
1076 if (ti->offset == 0) {
1077 } else if (ti->period < sc->sc_minsync ||
1078 ti->period > sc->sc_maxsync ||
1079 ti->offset > 8) {
1080 ti->period = ti->offset = 0;
1081 aic_sched_msgout(sc, SEND_SDTR);
1082 } else {
1083 sc_print_addr(acb->xs->sc_link);
1084 printf("sync, offset %d, ",
1085 ti->offset);
1086 printf("period %dnsec\n",
1087 ti->period * 4);
1088 }
1089 aic_setsync(sc, ti);
1090 break;
1091 #endif
1092
1093 #if AIC_USE_WIDE
1094 case MSG_EXT_WDTR:
1095 if (sc->sc_imess[1] != 2)
1096 goto reject;
1097 ti->width = sc->sc_imess[3];
1098 ti->flags &= ~DO_WIDE;
1099 if (ti->width == 0) {
1100 } else if (ti->width > AIC_MAX_WIDTH) {
1101 ti->width = 0;
1102 aic_sched_msgout(sc, SEND_WDTR);
1103 } else {
1104 sc_print_addr(acb->xs->sc_link);
1105 printf("wide, width %d\n",
1106 1 << (3 + ti->width));
1107 }
1108 break;
1109 #endif
1110
1111 default:
1112 printf("%s: unrecognized MESSAGE EXTENDED; ",
1113 sc->sc_dev.dv_xname);
1114 printf("sending REJECT\n");
1115 AIC_BREAK();
1116 goto reject;
1117 }
1118 break;
1119
1120 default:
1121 printf("%s: unrecognized MESSAGE; sending REJECT\n",
1122 sc->sc_dev.dv_xname);
1123 AIC_BREAK();
1124 reject:
1125 aic_sched_msgout(sc, SEND_REJECT);
1126 break;
1127 }
1128 break;
1129
1130 case AIC_RESELECTED:
1131 if (!MSG_ISIDENTIFY(sc->sc_imess[0])) {
1132 printf("%s: reselect without IDENTIFY; ",
1133 sc->sc_dev.dv_xname);
1134 printf("sending DEVICE RESET\n");
1135 AIC_BREAK();
1136 goto reset;
1137 }
1138
1139 (void) aic_reselect(sc, sc->sc_imess[0]);
1140 break;
1141
1142 default:
1143 printf("%s: unexpected MESSAGE IN; sending DEVICE RESET\n",
1144 sc->sc_dev.dv_xname);
1145 AIC_BREAK();
1146 reset:
1147 aic_sched_msgout(sc, SEND_DEV_RESET);
1148 break;
1149
1150 #ifdef notdef
1151 abort:
1152 aic_sched_msgout(sc, SEND_ABORT);
1153 break;
1154 #endif
1155 }
1156
1157 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
1158
1159 (void) bus_space_read_1(iot, ioh, SCSIDAT);
1160 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1161 while ((bus_space_read_1(iot, ioh, SCSISIG) & ACKI) != 0)
1162 ;
1163
1164
1165 goto nextmsg;
1166
1167 out:
1168 AIC_MISC(("n=%d imess=0x%02x ", n, sc->sc_imess[0]));
1169 }
1170
1171
1172
1173
1174 void
1175 aic_msgout(struct aic_softc *sc)
1176 {
1177 bus_space_tag_t iot = sc->sc_iot;
1178 bus_space_handle_t ioh = sc->sc_ioh;
1179 #if AIC_USE_SYNCHRONOUS
1180 struct aic_tinfo *ti;
1181 #endif
1182 u_char sstat1;
1183 int n;
1184
1185 AIC_TRACE(("aic_msgout "));
1186
1187
1188 bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO);
1189
1190 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
1191
1192 if (sc->sc_prevphase == PH_MSGOUT) {
1193 if (sc->sc_omp == sc->sc_omess) {
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205 AIC_MISC(("retransmitting "));
1206 sc->sc_msgpriq |= sc->sc_msgoutq;
1207
1208
1209
1210
1211 bus_space_write_1(iot, ioh, SCSISIG, PH_MSGOUT | ATNO);
1212 } else {
1213
1214 n = sc->sc_omp - sc->sc_omess;
1215 goto nextbyte;
1216 }
1217 }
1218
1219
1220 sc->sc_msgoutq = 0;
1221 sc->sc_lastmsg = 0;
1222
1223 nextmsg:
1224
1225 sc->sc_currmsg = sc->sc_msgpriq & -sc->sc_msgpriq;
1226 sc->sc_msgpriq &= ~sc->sc_currmsg;
1227 sc->sc_msgoutq |= sc->sc_currmsg;
1228
1229
1230 switch (sc->sc_currmsg) {
1231 case SEND_IDENTIFY:
1232 AIC_ASSERT(sc->sc_nexus != NULL);
1233 sc->sc_omess[0] =
1234 MSG_IDENTIFY(sc->sc_nexus->xs->sc_link->lun, 1);
1235 n = 1;
1236 break;
1237
1238 #if AIC_USE_SYNCHRONOUS
1239 case SEND_SDTR:
1240 AIC_ASSERT(sc->sc_nexus != NULL);
1241 ti = &sc->sc_tinfo[sc->sc_nexus->xs->sc_link->target];
1242 sc->sc_omess[4] = MSG_EXTENDED;
1243 sc->sc_omess[3] = 3;
1244 sc->sc_omess[2] = MSG_EXT_SDTR;
1245 sc->sc_omess[1] = ti->period >> 2;
1246 sc->sc_omess[0] = ti->offset;
1247 n = 5;
1248 break;
1249 #endif
1250
1251 #if AIC_USE_WIDE
1252 case SEND_WDTR:
1253 AIC_ASSERT(sc->sc_nexus != NULL);
1254 ti = &sc->sc_tinfo[sc->sc_nexus->xs->sc_link->target];
1255 sc->sc_omess[3] = MSG_EXTENDED;
1256 sc->sc_omess[2] = 2;
1257 sc->sc_omess[1] = MSG_EXT_WDTR;
1258 sc->sc_omess[0] = ti->width;
1259 n = 4;
1260 break;
1261 #endif
1262
1263 case SEND_DEV_RESET:
1264 sc->sc_flags |= AIC_ABORTING;
1265 sc->sc_omess[0] = MSG_BUS_DEV_RESET;
1266 n = 1;
1267 break;
1268
1269 case SEND_REJECT:
1270 sc->sc_omess[0] = MSG_MESSAGE_REJECT;
1271 n = 1;
1272 break;
1273
1274 case SEND_PARITY_ERROR:
1275 sc->sc_omess[0] = MSG_PARITY_ERROR;
1276 n = 1;
1277 break;
1278
1279 case SEND_INIT_DET_ERR:
1280 sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
1281 n = 1;
1282 break;
1283
1284 case SEND_ABORT:
1285 sc->sc_flags |= AIC_ABORTING;
1286 sc->sc_omess[0] = MSG_ABORT;
1287 n = 1;
1288 break;
1289
1290 default:
1291 printf("%s: unexpected MESSAGE OUT; sending NOOP\n",
1292 sc->sc_dev.dv_xname);
1293 AIC_BREAK();
1294 sc->sc_omess[0] = MSG_NOOP;
1295 n = 1;
1296 break;
1297 }
1298 sc->sc_omp = &sc->sc_omess[n];
1299
1300 nextbyte:
1301
1302 for (;;) {
1303 for (;;) {
1304 sstat1 = bus_space_read_1(iot, ioh, SSTAT1);
1305 if ((sstat1 & (REQINIT | PHASECHG | BUSFREE)) != 0)
1306 break;
1307
1308 }
1309 if ((sstat1 & (PHASECHG | BUSFREE)) != 0) {
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320 if (sc->sc_msgpriq == 0)
1321 bus_space_write_1(iot, ioh, CLRSINT1, CLRATNO);
1322 goto out;
1323 }
1324
1325
1326 if (n == 1 && sc->sc_msgpriq == 0)
1327 bus_space_write_1(iot, ioh, CLRSINT1, CLRATNO);
1328
1329 bus_space_write_1(iot, ioh, SCSIDAT, *--sc->sc_omp);
1330 --n;
1331
1332 sc->sc_lastmsg = sc->sc_currmsg;
1333
1334 while ((bus_space_read_1(iot, ioh, SCSISIG) & ACKI) != 0)
1335 ;
1336
1337 if (n == 0)
1338 break;
1339 }
1340
1341
1342 if (sc->sc_msgpriq != 0) {
1343
1344 goto nextmsg;
1345 }
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355 out:
1356
1357 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1358 }
1359
1360
1361
1362
1363
1364
1365
1366 int
1367 aic_dataout_pio(struct aic_softc *sc, u_char *p, int n)
1368 {
1369 bus_space_tag_t iot = sc->sc_iot;
1370 bus_space_handle_t ioh = sc->sc_ioh;
1371 u_char dmastat = 0;
1372 int out = 0;
1373 #define DOUTAMOUNT 128
1374
1375 AIC_MISC(("%02x%02x ", bus_space_read_1(iot, ioh, FIFOSTAT),
1376 bus_space_read_1(iot, ioh, SSTAT2)));
1377
1378
1379 bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO | WRITE);
1380
1381 bus_space_write_1(iot, ioh, DMACNTRL0, ENDMA | DWORDPIO | WRITE);
1382 bus_space_write_1(iot, ioh, SXFRCTL0, SCSIEN | DMAEN | CHEN);
1383
1384
1385 bus_space_write_1(iot, ioh, SIMODE1,
1386 ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENPHASECHG);
1387
1388
1389
1390
1391
1392 while (n > 0) {
1393 for (;;) {
1394 dmastat = bus_space_read_1(iot, ioh, DMASTAT);
1395 if ((dmastat & (DFIFOEMP | INTSTAT)) != 0)
1396 break;
1397 }
1398
1399 if ((dmastat & INTSTAT) != 0)
1400 goto phasechange;
1401
1402 if (n >= DOUTAMOUNT) {
1403 n -= DOUTAMOUNT;
1404 out += DOUTAMOUNT;
1405
1406 #if AIC_USE_DWORDS
1407 bus_space_write_multi_4(iot, ioh, DMADATALONG,
1408 (u_int32_t *)p, DOUTAMOUNT >> 2);
1409 #else
1410 bus_space_write_multi_2(iot, ioh, DMADATA,
1411 (u_int16_t *)p, DOUTAMOUNT >> 1);
1412 #endif
1413
1414 p += DOUTAMOUNT;
1415 } else {
1416 int xfer;
1417
1418 xfer = n;
1419 AIC_MISC(("%d> ", xfer));
1420
1421 n -= xfer;
1422 out += xfer;
1423
1424 #if AIC_USE_DWORDS
1425 if (xfer >= 12) {
1426 bus_space_write_multi_4(iot, ioh, DMADATALONG,
1427 (u_int32_t *)p, xfer >> 2);
1428 p += xfer & ~3;
1429 xfer &= 3;
1430 }
1431 #else
1432 if (xfer >= 8) {
1433 bus_space_write_multi_2(iot, ioh, DMADATA,
1434 (u_int16_t *)p, xfer >> 1);
1435 p += xfer & ~1;
1436 xfer &= 1;
1437 }
1438 #endif
1439
1440 if (xfer > 0) {
1441 bus_space_write_1(iot, ioh, DMACNTRL0,
1442 ENDMA | B8MODE | WRITE);
1443 bus_space_write_multi_1(iot, ioh, DMADATA, p,
1444 xfer);
1445 p += xfer;
1446 bus_space_write_1(iot, ioh, DMACNTRL0,
1447 ENDMA | DWORDPIO | WRITE);
1448 }
1449 }
1450 }
1451
1452 if (out == 0) {
1453 bus_space_write_1(iot, ioh, SXFRCTL1, BITBUCKET);
1454 for (;;) {
1455 if ((bus_space_read_1(iot, ioh, DMASTAT) & INTSTAT) !=
1456 0)
1457 break;
1458 }
1459 bus_space_write_1(iot, ioh, SXFRCTL1, 0);
1460 AIC_MISC(("extra data "));
1461 } else {
1462
1463 for (;;) {
1464 dmastat = bus_space_read_1(iot, ioh, DMASTAT);
1465 if ((dmastat & INTSTAT) != 0)
1466 goto phasechange;
1467 if ((dmastat & DFIFOEMP) != 0 &&
1468 (bus_space_read_1(iot, ioh, SSTAT2) & SEMPTY) != 0)
1469 break;
1470 }
1471 }
1472
1473 phasechange:
1474 if ((dmastat & INTSTAT) != 0) {
1475
1476 int amount;
1477
1478
1479 amount = bus_space_read_1(iot, ioh, FIFOSTAT) +
1480 (bus_space_read_1(iot, ioh, SSTAT2) & 15);
1481 if (amount > 0) {
1482 out -= amount;
1483 bus_space_write_1(iot, ioh, DMACNTRL0,
1484 RSTFIFO | WRITE);
1485 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | CLRCH);
1486 AIC_MISC(("+%d ", amount));
1487 }
1488 }
1489
1490
1491 bus_space_write_1(iot, ioh, SIMODE1,
1492 ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENREQINIT | ENPHASECHG);
1493
1494
1495 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1496 bus_space_write_1(iot, ioh, DMACNTRL0, 0);
1497
1498 return out;
1499 }
1500
1501
1502
1503
1504
1505
1506
1507
1508 int
1509 aic_datain_pio(struct aic_softc *sc, u_char *p, int n)
1510 {
1511 bus_space_tag_t iot = sc->sc_iot;
1512 bus_space_handle_t ioh = sc->sc_ioh;
1513 u_char dmastat;
1514 int in = 0;
1515 #define DINAMOUNT 128
1516
1517 AIC_MISC(("%02x%02x ", bus_space_read_1(iot, ioh, FIFOSTAT),
1518 bus_space_read_1(iot, ioh, SSTAT2)));
1519
1520
1521 bus_space_write_1(iot, ioh, DMACNTRL0, RSTFIFO);
1522
1523 bus_space_write_1(iot, ioh, DMACNTRL0, ENDMA | DWORDPIO);
1524 bus_space_write_1(iot, ioh, SXFRCTL0, SCSIEN | DMAEN | CHEN);
1525
1526
1527 bus_space_write_1(iot, ioh, SIMODE1,
1528 ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENPHASECHG);
1529
1530
1531
1532
1533
1534 while (n > 0) {
1535
1536 for (;;) {
1537 dmastat = bus_space_read_1(iot, ioh, DMASTAT);
1538 if ((dmastat & (DFIFOFULL | INTSTAT)) != 0)
1539 break;
1540 }
1541
1542 if ((dmastat & DFIFOFULL) != 0) {
1543 n -= DINAMOUNT;
1544 in += DINAMOUNT;
1545
1546 #if AIC_USE_DWORDS
1547 bus_space_read_multi_4(iot, ioh, DMADATALONG,
1548 (u_int32_t *)p, DINAMOUNT >> 2);
1549 #else
1550 bus_space_read_multi_2(iot, ioh, DMADATA,
1551 (u_int16_t *)p, DINAMOUNT >> 1);
1552 #endif
1553
1554 p += DINAMOUNT;
1555 } else {
1556 int xfer;
1557
1558 xfer = min(bus_space_read_1(iot, ioh, FIFOSTAT), n);
1559 AIC_MISC((">%d ", xfer));
1560
1561 n -= xfer;
1562 in += xfer;
1563
1564 #if AIC_USE_DWORDS
1565 if (xfer >= 12) {
1566 bus_space_read_multi_4(iot, ioh, DMADATALONG,
1567 (u_int32_t *)p, xfer >> 2);
1568 p += xfer & ~3;
1569 xfer &= 3;
1570 }
1571 #else
1572 if (xfer >= 8) {
1573 bus_space_read_multi_2(iot, ioh, DMADATA,
1574 (u_int16_t *)p, xfer >> 1);
1575 p += xfer & ~1;
1576 xfer &= 1;
1577 }
1578 #endif
1579
1580 if (xfer > 0) {
1581 bus_space_write_1(iot, ioh, DMACNTRL0,
1582 ENDMA | B8MODE);
1583 bus_space_read_multi_1(iot, ioh, DMADATA, p,
1584 xfer);
1585 p += xfer;
1586 bus_space_write_1(iot, ioh, DMACNTRL0,
1587 ENDMA | DWORDPIO);
1588 }
1589 }
1590
1591 if ((dmastat & INTSTAT) != 0)
1592 goto phasechange;
1593 }
1594
1595
1596
1597
1598
1599
1600
1601 if (in == 0) {
1602 bus_space_write_1(iot, ioh, SXFRCTL1, BITBUCKET);
1603 for (;;) {
1604 if ((bus_space_read_1(iot, ioh, DMASTAT) & INTSTAT) !=
1605 0)
1606 break;
1607 }
1608 bus_space_write_1(iot, ioh, SXFRCTL1, 0);
1609 AIC_MISC(("extra data "));
1610 }
1611
1612 phasechange:
1613
1614 bus_space_write_1(iot, ioh, SIMODE1,
1615 ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENREQINIT | ENPHASECHG);
1616
1617
1618 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1619 bus_space_write_1(iot, ioh, DMACNTRL0, 0);
1620
1621 return in;
1622 }
1623
1624
1625
1626
1627
1628
1629 int
1630 aicintr(void *arg)
1631 {
1632 struct aic_softc *sc = arg;
1633 bus_space_tag_t iot = sc->sc_iot;
1634 bus_space_handle_t ioh = sc->sc_ioh;
1635 u_char sstat0, sstat1;
1636 struct aic_acb *acb;
1637 struct scsi_link *sc_link;
1638 struct aic_tinfo *ti;
1639 int n;
1640
1641
1642
1643
1644
1645 bus_space_write_1(iot, ioh, DMACNTRL0, 0);
1646
1647 AIC_TRACE(("aicintr "));
1648
1649 loop:
1650
1651
1652
1653 sstat1 = bus_space_read_1(iot, ioh, SSTAT1);
1654 AIC_MISC(("sstat1:0x%02x ", sstat1));
1655
1656 if ((sstat1 & SCSIRSTI) != 0) {
1657 printf("%s: SCSI bus reset\n", sc->sc_dev.dv_xname);
1658 goto reset;
1659 }
1660
1661
1662
1663
1664 if ((sstat1 & SCSIPERR) != 0) {
1665 printf("%s: SCSI bus parity error\n", sc->sc_dev.dv_xname);
1666 bus_space_write_1(iot, ioh, CLRSINT1, CLRSCSIPERR);
1667 if (sc->sc_prevphase == PH_MSGIN) {
1668 sc->sc_flags |= AIC_DROP_MSGIN;
1669 aic_sched_msgout(sc, SEND_PARITY_ERROR);
1670 } else
1671 aic_sched_msgout(sc, SEND_INIT_DET_ERR);
1672 }
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684 switch (sc->sc_state) {
1685 case AIC_IDLE:
1686 case AIC_SELECTING:
1687 sstat0 = bus_space_read_1(iot, ioh, SSTAT0);
1688 AIC_MISC(("sstat0:0x%02x ", sstat0));
1689
1690 if ((sstat0 & TARGET) != 0) {
1691
1692
1693
1694 printf("%s: target mode selected; going to BUS FREE\n",
1695 sc->sc_dev.dv_xname);
1696 bus_space_write_1(iot, ioh, SCSISIG, 0);
1697
1698 goto sched;
1699 } else if ((sstat0 & SELDI) != 0) {
1700 AIC_MISC(("reselected "));
1701
1702
1703
1704
1705
1706 if (sc->sc_state == AIC_SELECTING) {
1707 AIC_MISC(("backoff selector "));
1708 AIC_ASSERT(sc->sc_nexus != NULL);
1709 acb = sc->sc_nexus;
1710 sc->sc_nexus = NULL;
1711 TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
1712 }
1713
1714
1715 sc->sc_selid = bus_space_read_1(iot, ioh, SELID);
1716
1717 sc->sc_state = AIC_RESELECTED;
1718 } else if ((sstat0 & SELDO) != 0) {
1719 AIC_MISC(("selected "));
1720
1721
1722
1723
1724
1725
1726 if (sc->sc_state != AIC_SELECTING) {
1727 printf("%s: selection out while idle; ",
1728 sc->sc_dev.dv_xname);
1729 printf("resetting\n");
1730 AIC_BREAK();
1731 goto reset;
1732 }
1733 AIC_ASSERT(sc->sc_nexus != NULL);
1734 acb = sc->sc_nexus;
1735 sc_link = acb->xs->sc_link;
1736 ti = &sc->sc_tinfo[sc_link->target];
1737
1738 sc->sc_msgpriq = SEND_IDENTIFY;
1739 if (acb->flags & ACB_RESET)
1740 sc->sc_msgpriq |= SEND_DEV_RESET;
1741 else if (acb->flags & ACB_ABORT)
1742 sc->sc_msgpriq |= SEND_ABORT;
1743 else {
1744 #if AIC_USE_SYNCHRONOUS
1745 if ((ti->flags & DO_SYNC) != 0)
1746 sc->sc_msgpriq |= SEND_SDTR;
1747 #endif
1748 #if AIC_USE_WIDE
1749 if ((ti->flags & DO_WIDE) != 0)
1750 sc->sc_msgpriq |= SEND_WDTR;
1751 #endif
1752 }
1753
1754 acb->flags |= ACB_NEXUS;
1755 ti->lubusy |= (1 << sc_link->lun);
1756
1757
1758 sc->sc_dp = acb->data_addr;
1759 sc->sc_dleft = acb->data_length;
1760 sc->sc_cp = (u_char *)&acb->scsi_cmd;
1761 sc->sc_cleft = acb->scsi_cmd_length;
1762
1763
1764 if ((acb->xs->flags & SCSI_POLL) == 0)
1765 timeout_add(&acb->xs->stimeout,
1766 (acb->timeout * hz) / 1000);
1767
1768 sc->sc_state = AIC_CONNECTED;
1769 } else if ((sstat1 & SELTO) != 0) {
1770 AIC_MISC(("selection timeout "));
1771
1772 if (sc->sc_state != AIC_SELECTING) {
1773 printf("%s: selection timeout while idle; ",
1774 sc->sc_dev.dv_xname);
1775 printf("resetting\n");
1776 AIC_BREAK();
1777 goto reset;
1778 }
1779 AIC_ASSERT(sc->sc_nexus != NULL);
1780 acb = sc->sc_nexus;
1781
1782 bus_space_write_1(iot, ioh, SXFRCTL1, 0);
1783 bus_space_write_1(iot, ioh, SCSISEQ, ENRESELI);
1784 bus_space_write_1(iot, ioh, CLRSINT1, CLRSELTIMO);
1785 delay(250);
1786
1787 acb->xs->error = XS_SELTIMEOUT;
1788 goto finish;
1789 } else {
1790 if (sc->sc_state != AIC_IDLE) {
1791 printf("%s: BUS FREE while not idle; ",
1792 sc->sc_dev.dv_xname);
1793 printf("state=%d\n", sc->sc_state);
1794 AIC_BREAK();
1795 goto out;
1796 }
1797
1798 goto sched;
1799 }
1800
1801
1802
1803
1804
1805 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | CLRSTCNT | CLRCH);
1806 bus_space_write_1(iot, ioh, SXFRCTL1, 0);
1807 bus_space_write_1(iot, ioh, SCSISEQ, ENAUTOATNP);
1808 bus_space_write_1(iot, ioh, CLRSINT0, CLRSELDI | CLRSELDO);
1809 bus_space_write_1(iot, ioh, CLRSINT1,
1810 CLRBUSFREE | CLRPHASECHG);
1811 bus_space_write_1(iot, ioh, SIMODE0, 0);
1812 bus_space_write_1(iot, ioh, SIMODE1,
1813 ENSCSIRST | ENSCSIPERR | ENBUSFREE | ENREQINIT |
1814 ENPHASECHG);
1815
1816 sc->sc_flags = 0;
1817 sc->sc_prevphase = PH_INVALID;
1818 goto dophase;
1819 }
1820
1821 if ((sstat1 & BUSFREE) != 0) {
1822
1823 bus_space_write_1(iot, ioh, CLRSINT1,
1824 CLRBUSFREE | CLRPHASECHG);
1825
1826 switch (sc->sc_state) {
1827 case AIC_RESELECTED:
1828 goto sched;
1829
1830 case AIC_CONNECTED:
1831 AIC_ASSERT(sc->sc_nexus != NULL);
1832 acb = sc->sc_nexus;
1833
1834 #if AIC_USE_SYNCHRONOUS + AIC_USE_WIDE
1835 if (sc->sc_prevphase == PH_MSGOUT) {
1836
1837
1838
1839
1840
1841 sc_link = acb->xs->sc_link;
1842 ti = &sc->sc_tinfo[sc_link->target];
1843 switch (sc->sc_lastmsg) {
1844 #if AIC_USE_SYNCHRONOUS
1845 case SEND_SDTR:
1846 ti->flags &= ~DO_SYNC;
1847 ti->period = ti->offset = 0;
1848 break;
1849 #endif
1850 #if AIC_USE_WIDE
1851 case SEND_WDTR:
1852 ti->flags &= ~DO_WIDE;
1853 ti->width = 0;
1854 break;
1855 #endif
1856 }
1857 }
1858 #endif
1859
1860 if ((sc->sc_flags & AIC_ABORTING) == 0) {
1861
1862
1863
1864
1865
1866
1867
1868
1869 printf("%s: unexpected disconnect; ",
1870 sc->sc_dev.dv_xname);
1871 printf("sending REQUEST SENSE\n");
1872 AIC_BREAK();
1873 aic_sense(sc, acb);
1874 goto out;
1875 }
1876
1877 acb->xs->error = XS_DRIVER_STUFFUP;
1878 goto finish;
1879
1880 case AIC_DISCONNECT:
1881 AIC_ASSERT(sc->sc_nexus != NULL);
1882 acb = sc->sc_nexus;
1883 #if 1
1884 acb->data_addr = sc->sc_dp;
1885 acb->data_length = sc->sc_dleft;
1886 #endif
1887 TAILQ_INSERT_HEAD(&sc->nexus_list, acb, chain);
1888 sc->sc_nexus = NULL;
1889 goto sched;
1890
1891 case AIC_CMDCOMPLETE:
1892 AIC_ASSERT(sc->sc_nexus != NULL);
1893 acb = sc->sc_nexus;
1894 goto finish;
1895 }
1896 }
1897
1898 bus_space_write_1(iot, ioh, CLRSINT1, CLRPHASECHG);
1899
1900 dophase:
1901 if ((sstat1 & REQINIT) == 0) {
1902
1903 goto out;
1904 }
1905
1906 sc->sc_phase = bus_space_read_1(iot, ioh, SCSISIG) & PH_MASK;
1907 bus_space_write_1(iot, ioh, SCSISIG, sc->sc_phase);
1908
1909 switch (sc->sc_phase) {
1910 case PH_MSGOUT:
1911 if (sc->sc_state != AIC_CONNECTED &&
1912 sc->sc_state != AIC_RESELECTED)
1913 break;
1914 aic_msgout(sc);
1915 sc->sc_prevphase = PH_MSGOUT;
1916 goto loop;
1917
1918 case PH_MSGIN:
1919 if (sc->sc_state != AIC_CONNECTED &&
1920 sc->sc_state != AIC_RESELECTED)
1921 break;
1922 aic_msgin(sc);
1923 sc->sc_prevphase = PH_MSGIN;
1924 goto loop;
1925
1926 case PH_CMD:
1927 if (sc->sc_state != AIC_CONNECTED)
1928 break;
1929 #ifdef AIC_DEBUG
1930 if ((aic_debug & AIC_SHOWMISC) != 0) {
1931 AIC_ASSERT(sc->sc_nexus != NULL);
1932 acb = sc->sc_nexus;
1933 printf("cmd=0x%02x+%d ",
1934 acb->scsi_cmd.opcode, acb->scsi_cmd_length-1);
1935 }
1936 #endif
1937 n = aic_dataout_pio(sc, sc->sc_cp, sc->sc_cleft);
1938 sc->sc_cp += n;
1939 sc->sc_cleft -= n;
1940 sc->sc_prevphase = PH_CMD;
1941 goto loop;
1942
1943 case PH_DATAOUT:
1944 if (sc->sc_state != AIC_CONNECTED)
1945 break;
1946 AIC_MISC(("dataout dleft=%lu ", (u_long)sc->sc_dleft));
1947 n = aic_dataout_pio(sc, sc->sc_dp, sc->sc_dleft);
1948 sc->sc_dp += n;
1949 sc->sc_dleft -= n;
1950 sc->sc_prevphase = PH_DATAOUT;
1951 goto loop;
1952
1953 case PH_DATAIN:
1954 if (sc->sc_state != AIC_CONNECTED)
1955 break;
1956 AIC_MISC(("datain %lu ", (u_long)sc->sc_dleft));
1957 n = aic_datain_pio(sc, sc->sc_dp, sc->sc_dleft);
1958 sc->sc_dp += n;
1959 sc->sc_dleft -= n;
1960 sc->sc_prevphase = PH_DATAIN;
1961 goto loop;
1962
1963 case PH_STAT:
1964 if (sc->sc_state != AIC_CONNECTED)
1965 break;
1966 AIC_ASSERT(sc->sc_nexus != NULL);
1967 acb = sc->sc_nexus;
1968 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN | SPIOEN);
1969 acb->target_stat = bus_space_read_1(iot, ioh, SCSIDAT);
1970 bus_space_write_1(iot, ioh, SXFRCTL0, CHEN);
1971 AIC_MISC(("target_stat=0x%02x ", acb->target_stat));
1972 sc->sc_prevphase = PH_STAT;
1973 goto loop;
1974 }
1975
1976 printf("%s: unexpected bus phase; resetting\n", sc->sc_dev.dv_xname);
1977 AIC_BREAK();
1978 reset:
1979 aic_init(sc);
1980 return 1;
1981
1982 finish:
1983 timeout_del(&acb->xs->stimeout);
1984 aic_done(sc, acb);
1985 goto out;
1986
1987 sched:
1988 sc->sc_state = AIC_IDLE;
1989 aic_sched(sc);
1990 goto out;
1991
1992 out:
1993 bus_space_write_1(iot, ioh, DMACNTRL0, INTEN);
1994 return 1;
1995 }
1996
1997 void
1998 aic_abort(struct aic_softc *sc, struct aic_acb *acb)
1999 {
2000
2001
2002 acb->timeout = AIC_ABORT_TIMEOUT;
2003 acb->flags |= ACB_ABORT;
2004
2005 if (acb == sc->sc_nexus) {
2006
2007
2008
2009
2010 if (sc->sc_state == AIC_CONNECTED)
2011 aic_sched_msgout(sc, SEND_ABORT);
2012 } else {
2013 aic_dequeue(sc, acb);
2014 TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
2015 if (sc->sc_state == AIC_IDLE)
2016 aic_sched(sc);
2017 }
2018 }
2019
2020 void
2021 aic_timeout(void *arg)
2022 {
2023 struct aic_acb *acb = arg;
2024 struct scsi_xfer *xs = acb->xs;
2025 struct scsi_link *sc_link = xs->sc_link;
2026 struct aic_softc *sc = sc_link->adapter_softc;
2027 int s;
2028
2029 sc_print_addr(sc_link);
2030 printf("timed out");
2031
2032 s = splbio();
2033
2034 if (acb->flags & ACB_ABORT) {
2035
2036 printf(" AGAIN\n");
2037
2038 } else {
2039
2040 printf("\n");
2041 acb->xs->error = XS_TIMEOUT;
2042 aic_abort(sc, acb);
2043 }
2044
2045 splx(s);
2046 }
2047
2048 #ifdef AIC_DEBUG
2049
2050
2051
2052
2053
2054 void
2055 aic_show_scsi_cmd(struct aic_acb *acb)
2056 {
2057 u_char *b = (u_char *)&acb->scsi_cmd;
2058 struct scsi_link *sc_link = acb->xs->sc_link;
2059 int i;
2060
2061 sc_print_addr(sc_link);
2062 if ((acb->xs->flags & SCSI_RESET) == 0) {
2063 for (i = 0; i < acb->scsi_cmd_length; i++) {
2064 if (i)
2065 printf(",");
2066 printf("%x", b[i]);
2067 }
2068 printf("\n");
2069 } else
2070 printf("RESET\n");
2071 }
2072
2073 void
2074 aic_print_acb(struct aic_acb *acb)
2075 {
2076
2077 printf("acb@%p xs=%p flags=%x", acb, acb->xs, acb->flags);
2078 printf(" dp=%p dleft=%d target_stat=%x\n",
2079 acb->data_addr, acb->data_length, acb->target_stat);
2080 aic_show_scsi_cmd(acb);
2081 }
2082
2083 void
2084 aic_print_active_acb(void)
2085 {
2086 struct aic_acb *acb;
2087 struct aic_softc *sc = aic_cd.cd_devs[0];
2088
2089 printf("ready list:\n");
2090 TAILQ_FOREACH(acb, &sc->ready_list, chain)
2091 aic_print_acb(acb);
2092 printf("nexus:\n");
2093 if (sc->sc_nexus != NULL)
2094 aic_print_acb(sc->sc_nexus);
2095 printf("nexus list:\n");
2096 TAILQ_FOREACH(acb, &sc->nexus_list, chain)
2097 aic_print_acb(acb);
2098 }
2099
2100 void
2101 aic_dump6360(struct aic_softc *sc)
2102 {
2103 bus_space_tag_t iot = sc->sc_iot;
2104 bus_space_handle_t ioh = sc->sc_ioh;
2105
2106 printf("aic6360: SCSISEQ=%x SXFRCTL0=%x SXFRCTL1=%x SCSISIG=%x\n",
2107 bus_space_read_1(iot, ioh, SCSISEQ),
2108 bus_space_read_1(iot, ioh, SXFRCTL0),
2109 bus_space_read_1(iot, ioh, SXFRCTL1),
2110 bus_space_read_1(iot, ioh, SCSISIG));
2111 printf(" SSTAT0=%x SSTAT1=%x SSTAT2=%x SSTAT3=%x SSTAT4=%x\n",
2112 bus_space_read_1(iot, ioh, SSTAT0),
2113 bus_space_read_1(iot, ioh, SSTAT1),
2114 bus_space_read_1(iot, ioh, SSTAT2),
2115 bus_space_read_1(iot, ioh, SSTAT3),
2116 bus_space_read_1(iot, ioh, SSTAT4));
2117 printf(" SIMODE0=%x SIMODE1=%x ",
2118 bus_space_read_1(iot, ioh, SIMODE0),
2119 bus_space_read_1(iot, ioh, SIMODE1));
2120 printf("DMACNTRL0=%x DMACNTRL1=%x DMASTAT=%x\n",
2121 bus_space_read_1(iot, ioh, DMACNTRL0),
2122 bus_space_read_1(iot, ioh, DMACNTRL1),
2123 bus_space_read_1(iot, ioh, DMASTAT));
2124 printf(" FIFOSTAT=%d SCSIBUS=0x%x\n",
2125 bus_space_read_1(iot, ioh, FIFOSTAT),
2126 bus_space_read_1(iot, ioh, SCSIBUS));
2127 }
2128
2129 void
2130 aic_dump_driver(struct aic_softc *sc)
2131 {
2132 struct aic_tinfo *ti;
2133 int i;
2134
2135 printf("nexus=%p prevphase=%x\n", sc->sc_nexus, sc->sc_prevphase);
2136 printf("state=%x msgin=%x ", sc->sc_state, sc->sc_imess[0]);
2137 printf("msgpriq=%x msgoutq=%x lastmsg=%x currmsg=%x\n", sc->sc_msgpriq,
2138 sc->sc_msgoutq, sc->sc_lastmsg, sc->sc_currmsg);
2139 for (i = 0; i < 7; i++) {
2140 ti = &sc->sc_tinfo[i];
2141 printf("tinfo%d: %d cmds %d disconnects %d timeouts",
2142 i, ti->cmds, ti->dconns, ti->touts);
2143 printf(" %d senses flags=%x\n", ti->senses, ti->flags);
2144 }
2145 }
2146 #endif