1
2
3
4
5
6
7
8
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#ifdef __linux__
46#include "aic7xxx_osm.h"
47#include "aic7xxx_inline.h"
48#include "aicasm/aicasm_insformat.h"
49#else
50#include <dev/aic7xxx/aic7xxx_osm.h>
51#include <dev/aic7xxx/aic7xxx_inline.h>
52#include <dev/aic7xxx/aicasm/aicasm_insformat.h>
53#endif
54
55
56struct ahc_softc_tailq ahc_tailq = TAILQ_HEAD_INITIALIZER(ahc_tailq);
57
58
59char *ahc_chip_names[] =
60{
61 "NONE",
62 "aic7770",
63 "aic7850",
64 "aic7855",
65 "aic7859",
66 "aic7860",
67 "aic7870",
68 "aic7880",
69 "aic7895",
70 "aic7895C",
71 "aic7890/91",
72 "aic7896/97",
73 "aic7892",
74 "aic7899"
75};
76static const u_int num_chip_names = NUM_ELEMENTS(ahc_chip_names);
77
78
79
80
81struct ahc_hard_error_entry {
82 uint8_t errno;
83 char *errmesg;
84};
85
86static struct ahc_hard_error_entry ahc_hard_errors[] = {
87 { ILLHADDR, "Illegal Host Access" },
88 { ILLSADDR, "Illegal Sequencer Address referrenced" },
89 { ILLOPCODE, "Illegal Opcode in sequencer program" },
90 { SQPARERR, "Sequencer Parity Error" },
91 { DPARERR, "Data-path Parity Error" },
92 { MPARERR, "Scratch or SCB Memory Parity Error" },
93 { PCIERRSTAT, "PCI Error detected" },
94 { CIOPARERR, "CIOBUS Parity Error" },
95};
96static const u_int num_errors = NUM_ELEMENTS(ahc_hard_errors);
97
98static struct ahc_phase_table_entry ahc_phase_table[] =
99{
100 { P_DATAOUT, MSG_NOOP, "in Data-out phase" },
101 { P_DATAIN, MSG_INITIATOR_DET_ERR, "in Data-in phase" },
102 { P_DATAOUT_DT, MSG_NOOP, "in DT Data-out phase" },
103 { P_DATAIN_DT, MSG_INITIATOR_DET_ERR, "in DT Data-in phase" },
104 { P_COMMAND, MSG_NOOP, "in Command phase" },
105 { P_MESGOUT, MSG_NOOP, "in Message-out phase" },
106 { P_STATUS, MSG_INITIATOR_DET_ERR, "in Status phase" },
107 { P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" },
108 { P_BUSFREE, MSG_NOOP, "while idle" },
109 { 0, MSG_NOOP, "in unknown phase" }
110};
111
112
113
114
115
116static const u_int num_phases = NUM_ELEMENTS(ahc_phase_table) - 1;
117
118
119
120
121
122
123static struct ahc_syncrate ahc_syncrates[] =
124{
125
126 { 0x42, 0x000, 9, "80.0" },
127 { 0x03, 0x000, 10, "40.0" },
128 { 0x04, 0x000, 11, "33.0" },
129 { 0x05, 0x100, 12, "20.0" },
130 { 0x06, 0x110, 15, "16.0" },
131 { 0x07, 0x120, 18, "13.4" },
132 { 0x08, 0x000, 25, "10.0" },
133 { 0x19, 0x010, 31, "8.0" },
134 { 0x1a, 0x020, 37, "6.67" },
135 { 0x1b, 0x030, 43, "5.7" },
136 { 0x1c, 0x040, 50, "5.0" },
137 { 0x00, 0x050, 56, "4.4" },
138 { 0x00, 0x060, 62, "4.0" },
139 { 0x00, 0x070, 68, "3.6" },
140 { 0x00, 0x000, 0, NULL }
141};
142
143
144#include "aic7xxx_seq.h"
145
146
147static void ahc_force_renegotiation(struct ahc_softc *ahc,
148 struct ahc_devinfo *devinfo);
149static struct ahc_tmode_tstate*
150 ahc_alloc_tstate(struct ahc_softc *ahc,
151 u_int scsi_id, char channel);
152#ifdef AHC_TARGET_MODE
153static void ahc_free_tstate(struct ahc_softc *ahc,
154 u_int scsi_id, char channel, int force);
155#endif
156static struct ahc_syncrate*
157 ahc_devlimited_syncrate(struct ahc_softc *ahc,
158 struct ahc_initiator_tinfo *,
159 u_int *period,
160 u_int *ppr_options,
161 role_t role);
162static void ahc_update_pending_scbs(struct ahc_softc *ahc);
163static void ahc_fetch_devinfo(struct ahc_softc *ahc,
164 struct ahc_devinfo *devinfo);
165static void ahc_scb_devinfo(struct ahc_softc *ahc,
166 struct ahc_devinfo *devinfo,
167 struct scb *scb);
168static void ahc_assert_atn(struct ahc_softc *ahc);
169static void ahc_setup_initiator_msgout(struct ahc_softc *ahc,
170 struct ahc_devinfo *devinfo,
171 struct scb *scb);
172static void ahc_build_transfer_msg(struct ahc_softc *ahc,
173 struct ahc_devinfo *devinfo);
174static void ahc_construct_sdtr(struct ahc_softc *ahc,
175 struct ahc_devinfo *devinfo,
176 u_int period, u_int offset);
177static void ahc_construct_wdtr(struct ahc_softc *ahc,
178 struct ahc_devinfo *devinfo,
179 u_int bus_width);
180static void ahc_construct_ppr(struct ahc_softc *ahc,
181 struct ahc_devinfo *devinfo,
182 u_int period, u_int offset,
183 u_int bus_width, u_int ppr_options);
184static void ahc_clear_msg_state(struct ahc_softc *ahc);
185static void ahc_handle_proto_violation(struct ahc_softc *ahc);
186static void ahc_handle_message_phase(struct ahc_softc *ahc);
187typedef enum {
188 AHCMSG_1B,
189 AHCMSG_2B,
190 AHCMSG_EXT
191} ahc_msgtype;
192static int ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type,
193 u_int msgval, int full);
194static int ahc_parse_msg(struct ahc_softc *ahc,
195 struct ahc_devinfo *devinfo);
196static int ahc_handle_msg_reject(struct ahc_softc *ahc,
197 struct ahc_devinfo *devinfo);
198static void ahc_handle_ign_wide_residue(struct ahc_softc *ahc,
199 struct ahc_devinfo *devinfo);
200static void ahc_reinitialize_dataptrs(struct ahc_softc *ahc);
201static void ahc_handle_devreset(struct ahc_softc *ahc,
202 struct ahc_devinfo *devinfo,
203 cam_status status, char *message,
204 int verbose_level);
205#ifdef AHC_TARGET_MODE
206static void ahc_setup_target_msgin(struct ahc_softc *ahc,
207 struct ahc_devinfo *devinfo,
208 struct scb *scb);
209#endif
210
211static bus_dmamap_callback_t ahc_dmamap_cb;
212static void ahc_build_free_scb_list(struct ahc_softc *ahc);
213static int ahc_init_scbdata(struct ahc_softc *ahc);
214static void ahc_fini_scbdata(struct ahc_softc *ahc);
215static void ahc_qinfifo_requeue(struct ahc_softc *ahc,
216 struct scb *prev_scb,
217 struct scb *scb);
218static int ahc_qinfifo_count(struct ahc_softc *ahc);
219static u_int ahc_rem_scb_from_disc_list(struct ahc_softc *ahc,
220 u_int prev, u_int scbptr);
221static void ahc_add_curscb_to_free_list(struct ahc_softc *ahc);
222static u_int ahc_rem_wscb(struct ahc_softc *ahc,
223 u_int scbpos, u_int prev);
224static void ahc_reset_current_bus(struct ahc_softc *ahc);
225#ifdef AHC_DUMP_SEQ
226static void ahc_dumpseq(struct ahc_softc *ahc);
227#endif
228static int ahc_loadseq(struct ahc_softc *ahc);
229static int ahc_check_patch(struct ahc_softc *ahc,
230 struct patch **start_patch,
231 u_int start_instr, u_int *skip_addr);
232static void ahc_download_instr(struct ahc_softc *ahc,
233 u_int instrptr, uint8_t *dconsts);
234#ifdef AHC_TARGET_MODE
235static void ahc_queue_lstate_event(struct ahc_softc *ahc,
236 struct ahc_tmode_lstate *lstate,
237 u_int initiator_id,
238 u_int event_type,
239 u_int event_arg);
240static void ahc_update_scsiid(struct ahc_softc *ahc,
241 u_int targid_mask);
242static int ahc_handle_target_cmd(struct ahc_softc *ahc,
243 struct target_cmd *cmd);
244#endif
245
246
247
248
249void
250ahc_restart(struct ahc_softc *ahc)
251{
252
253 ahc_pause(ahc);
254
255
256 ahc_clear_msg_state(ahc);
257
258 ahc_outb(ahc, SCSISIGO, 0);
259 ahc_outb(ahc, MSG_OUT, MSG_NOOP);
260 ahc_outb(ahc, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
261 ahc_outb(ahc, LASTPHASE, P_BUSFREE);
262 ahc_outb(ahc, SAVED_SCSIID, 0xFF);
263 ahc_outb(ahc, SAVED_LUN, 0xFF);
264
265
266
267
268
269
270
271
272 ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
273
274
275 ahc_outb(ahc, SCSISEQ,
276 ahc_inb(ahc, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
277 if ((ahc->features & AHC_CMD_CHAN) != 0) {
278
279 ahc_outb(ahc, CCSCBCNT, 0);
280 ahc_outb(ahc, CCSGCTL, 0);
281 ahc_outb(ahc, CCSCBCTL, 0);
282 }
283
284
285
286
287
288 if ((ahc_inb(ahc, SEQ_FLAGS2) & SCB_DMA) != 0) {
289 ahc_add_curscb_to_free_list(ahc);
290 ahc_outb(ahc, SEQ_FLAGS2,
291 ahc_inb(ahc, SEQ_FLAGS2) & ~SCB_DMA);
292 }
293 ahc_outb(ahc, MWI_RESIDUAL, 0);
294 ahc_outb(ahc, SEQCTL, ahc->seqctl);
295 ahc_outb(ahc, SEQADDR0, 0);
296 ahc_outb(ahc, SEQADDR1, 0);
297 ahc_unpause(ahc);
298}
299
300
301void
302ahc_run_qoutfifo(struct ahc_softc *ahc)
303{
304 struct scb *scb;
305 u_int scb_index;
306
307 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
308 while (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL) {
309
310 scb_index = ahc->qoutfifo[ahc->qoutfifonext];
311 if ((ahc->qoutfifonext & 0x03) == 0x03) {
312 u_int modnext;
313
314
315
316
317
318
319
320
321 modnext = ahc->qoutfifonext & ~0x3;
322 *((uint32_t *)(&ahc->qoutfifo[modnext])) = 0xFFFFFFFFUL;
323 ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
324 ahc->shared_data_dmamap,
325 modnext, 4,
326 BUS_DMASYNC_PREREAD);
327 }
328 ahc->qoutfifonext++;
329
330 scb = ahc_lookup_scb(ahc, scb_index);
331 if (scb == NULL) {
332 printf("%s: WARNING no command for scb %d "
333 "(cmdcmplt)\nQOUTPOS = %d\n",
334 ahc_name(ahc), scb_index,
335 (ahc->qoutfifonext - 1) & 0xFF);
336 continue;
337 }
338
339
340
341
342
343 ahc_update_residual(ahc, scb);
344 ahc_done(ahc, scb);
345 }
346}
347
348void
349ahc_run_untagged_queues(struct ahc_softc *ahc)
350{
351 int i;
352
353 for (i = 0; i < 16; i++)
354 ahc_run_untagged_queue(ahc, &ahc->untagged_queues[i]);
355}
356
357void
358ahc_run_untagged_queue(struct ahc_softc *ahc, struct scb_tailq *queue)
359{
360 struct scb *scb;
361
362 if (ahc->untagged_queue_lock != 0)
363 return;
364
365 if ((scb = TAILQ_FIRST(queue)) != NULL
366 && (scb->flags & SCB_ACTIVE) == 0) {
367 scb->flags |= SCB_ACTIVE;
368 ahc_queue_scb(ahc, scb);
369 }
370}
371
372
373void
374ahc_handle_brkadrint(struct ahc_softc *ahc)
375{
376
377
378
379
380 int i;
381 int error;
382
383 error = ahc_inb(ahc, ERROR);
384 for (i = 0; error != 1 && i < num_errors; i++)
385 error >>= 1;
386 printf("%s: brkadrint, %s at seqaddr = 0x%x\n",
387 ahc_name(ahc), ahc_hard_errors[i].errmesg,
388 ahc_inb(ahc, SEQADDR0) |
389 (ahc_inb(ahc, SEQADDR1) << 8));
390
391 ahc_dump_card_state(ahc);
392
393
394 ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS,
395 CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
396 CAM_NO_HBA);
397
398
399 ahc_shutdown(ahc);
400}
401
402void
403ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
404{
405 struct scb *scb;
406 struct ahc_devinfo devinfo;
407
408 ahc_fetch_devinfo(ahc, &devinfo);
409
410
411
412
413
414
415
416 ahc_outb(ahc, CLRINT, CLRSEQINT);
417 switch (intstat & SEQINT_MASK) {
418 case BAD_STATUS:
419 {
420 u_int scb_index;
421 struct hardware_scb *hscb;
422
423
424
425
426
427
428 ahc_outb(ahc, RETURN_1, 0);
429
430
431
432
433
434
435
436
437
438
439 scb_index = ahc_inb(ahc, SCB_TAG);
440 scb = ahc_lookup_scb(ahc, scb_index);
441 if (scb == NULL) {
442 ahc_print_devinfo(ahc, &devinfo);
443 printf("ahc_intr - referenced scb "
444 "not valid during seqint 0x%x scb(%d)\n",
445 intstat, scb_index);
446 ahc_dump_card_state(ahc);
447 panic("for safety");
448 goto unpause;
449 }
450
451 hscb = scb->hscb;
452
453
454 if ((scb->flags & SCB_SENSE) != 0) {
455
456
457
458
459
460 scb->flags &= ~SCB_SENSE;
461 ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
462 break;
463 }
464 ahc_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR);
465
466 ahc_freeze_devq(ahc, scb);
467 ahc_freeze_scb(scb);
468 ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status);
469 switch (hscb->shared_data.status.scsi_status) {
470 case SCSI_STATUS_OK:
471 printf("%s: Interrupted for staus of 0???\n",
472 ahc_name(ahc));
473 break;
474 case SCSI_STATUS_CMD_TERMINATED:
475 case SCSI_STATUS_CHECK_COND:
476 {
477 struct ahc_dma_seg *sg;
478 struct scsi_sense *sc;
479 struct ahc_initiator_tinfo *targ_info;
480 struct ahc_tmode_tstate *tstate;
481 struct ahc_transinfo *tinfo;
482#ifdef AHC_DEBUG
483 if (ahc_debug & AHC_SHOW_SENSE) {
484 ahc_print_path(ahc, scb);
485 printf("SCB %d: requests Check Status\n",
486 scb->hscb->tag);
487 }
488#endif
489
490 if (ahc_perform_autosense(scb) == 0)
491 break;
492
493 targ_info = ahc_fetch_transinfo(ahc,
494 devinfo.channel,
495 devinfo.our_scsiid,
496 devinfo.target,
497 &tstate);
498 tinfo = &targ_info->curr;
499 sg = scb->sg_list;
500 sc = (struct scsi_sense *)(&hscb->shared_data.cdb);
501
502
503
504 ahc_update_residual(ahc, scb);
505#ifdef AHC_DEBUG
506 if (ahc_debug & AHC_SHOW_SENSE) {
507 ahc_print_path(ahc, scb);
508 printf("Sending Sense\n");
509 }
510#endif
511 sg->addr = ahc_get_sense_bufaddr(ahc, scb);
512 sg->len = ahc_get_sense_bufsize(ahc, scb);
513 sg->len |= AHC_DMA_LAST_SEG;
514
515
516 sg->addr = ahc_htole32(sg->addr);
517 sg->len = ahc_htole32(sg->len);
518
519 sc->opcode = REQUEST_SENSE;
520 sc->byte2 = 0;
521 if (tinfo->protocol_version <= SCSI_REV_2
522 && SCB_GET_LUN(scb) < 8)
523 sc->byte2 = SCB_GET_LUN(scb) << 5;
524 sc->unused[0] = 0;
525 sc->unused[1] = 0;
526 sc->length = sg->len;
527 sc->control = 0;
528
529
530
531
532
533
534
535
536 hscb->control = 0;
537
538
539
540
541
542
543
544
545
546 if (ahc_get_residual(scb)
547 == ahc_get_transfer_length(scb)) {
548 ahc_update_neg_request(ahc, &devinfo,
549 tstate, targ_info,
550 AHC_NEG_IF_NON_ASYNC);
551 }
552 if (tstate->auto_negotiate & devinfo.target_mask) {
553 hscb->control |= MK_MESSAGE;
554 scb->flags &= ~SCB_NEGOTIATE;
555 scb->flags |= SCB_AUTO_NEGOTIATE;
556 }
557 hscb->cdb_len = sizeof(*sc);
558 hscb->dataptr = sg->addr;
559 hscb->datacnt = sg->len;
560 hscb->sgptr = scb->sg_list_phys | SG_FULL_RESID;
561 hscb->sgptr = ahc_htole32(hscb->sgptr);
562 scb->sg_count = 1;
563 scb->flags |= SCB_SENSE;
564 ahc_qinfifo_requeue_tail(ahc, scb);
565 ahc_outb(ahc, RETURN_1, SEND_SENSE);
566
567
568
569
570 ahc_scb_timer_reset(scb, 5 * 1000000);
571 break;
572 }
573 default:
574 break;
575 }
576 break;
577 }
578 case NO_MATCH:
579 {
580
581 ahc_outb(ahc, SCSISEQ,
582 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
583
584 printf("%s:%c:%d: no active SCB for reconnecting "
585 "target - issuing BUS DEVICE RESET\n",
586 ahc_name(ahc), devinfo.channel, devinfo.target);
587 printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
588 "ARG_1 == 0x%x ACCUM = 0x%x\n",
589 ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
590 ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
591 printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
592 "SINDEX == 0x%x\n",
593 ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
594 ahc_index_busy_tcl(ahc,
595 BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
596 ahc_inb(ahc, SAVED_LUN))),
597 ahc_inb(ahc, SINDEX));
598 printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
599 "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
600 ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
601 ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
602 ahc_inb(ahc, SCB_CONTROL));
603 printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
604 ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
605 printf("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0));
606 printf("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL));
607 ahc_dump_card_state(ahc);
608 ahc->msgout_buf[0] = MSG_BUS_DEV_RESET;
609 ahc->msgout_len = 1;
610 ahc->msgout_index = 0;
611 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
612 ahc_outb(ahc, MSG_OUT, HOST_MSG);
613 ahc_assert_atn(ahc);
614 break;
615 }
616 case SEND_REJECT:
617 {
618 u_int rejbyte = ahc_inb(ahc, ACCUM);
619 printf("%s:%c:%d: Warning - unknown message received from "
620 "target (0x%x). Rejecting\n",
621 ahc_name(ahc), devinfo.channel, devinfo.target, rejbyte);
622 break;
623 }
624 case PROTO_VIOLATION:
625 {
626 ahc_handle_proto_violation(ahc);
627 break;
628 }
629 case IGN_WIDE_RES:
630 ahc_handle_ign_wide_residue(ahc, &devinfo);
631 break;
632 case PDATA_REINIT:
633 ahc_reinitialize_dataptrs(ahc);
634 break;
635 case BAD_PHASE:
636 {
637 u_int lastphase;
638
639 lastphase = ahc_inb(ahc, LASTPHASE);
640 printf("%s:%c:%d: unknown scsi bus phase %x, "
641 "lastphase = 0x%x. Attempting to continue\n",
642 ahc_name(ahc), devinfo.channel, devinfo.target,
643 lastphase, ahc_inb(ahc, SCSISIGI));
644 break;
645 }
646 case MISSED_BUSFREE:
647 {
648 u_int lastphase;
649
650 lastphase = ahc_inb(ahc, LASTPHASE);
651 printf("%s:%c:%d: Missed busfree. "
652 "Lastphase = 0x%x, Curphase = 0x%x\n",
653 ahc_name(ahc), devinfo.channel, devinfo.target,
654 lastphase, ahc_inb(ahc, SCSISIGI));
655 ahc_restart(ahc);
656 return;
657 }
658 case HOST_MSG_LOOP:
659 {
660
661
662
663
664
665
666
667
668
669
670
671 if (ahc->msg_type == MSG_TYPE_NONE) {
672 struct scb *scb;
673 u_int scb_index;
674 u_int bus_phase;
675
676 bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
677 if (bus_phase != P_MESGIN
678 && bus_phase != P_MESGOUT) {
679 printf("ahc_intr: HOST_MSG_LOOP bad "
680 "phase 0x%x\n",
681 bus_phase);
682
683
684
685
686 ahc_clear_intstat(ahc);
687 ahc_restart(ahc);
688 return;
689 }
690
691 scb_index = ahc_inb(ahc, SCB_TAG);
692 scb = ahc_lookup_scb(ahc, scb_index);
693 if (devinfo.role == ROLE_INITIATOR) {
694 if (scb == NULL)
695 panic("HOST_MSG_LOOP with "
696 "invalid SCB %x\n", scb_index);
697
698 if (bus_phase == P_MESGOUT)
699 ahc_setup_initiator_msgout(ahc,
700 &devinfo,
701 scb);
702 else {
703 ahc->msg_type =
704 MSG_TYPE_INITIATOR_MSGIN;
705 ahc->msgin_index = 0;
706 }
707 }
708#ifdef AHC_TARGET_MODE
709 else {
710 if (bus_phase == P_MESGOUT) {
711 ahc->msg_type =
712 MSG_TYPE_TARGET_MSGOUT;
713 ahc->msgin_index = 0;
714 }
715 else
716 ahc_setup_target_msgin(ahc,
717 &devinfo,
718 scb);
719 }
720#endif
721 }
722
723 ahc_handle_message_phase(ahc);
724 break;
725 }
726 case PERR_DETECTED:
727 {
728
729
730
731
732
733
734
735
736
737
738
739 if ((intstat & SCSIINT) == 0
740 && (ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0) {
741
742 if ((ahc->features & AHC_DT) == 0) {
743 u_int curphase;
744
745
746
747
748
749
750
751 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
752 ahc_outb(ahc, LASTPHASE, curphase);
753 ahc_outb(ahc, SCSISIGO, curphase);
754 }
755 if ((ahc_inb(ahc, SCSISIGI) & (CDI|MSGI)) == 0) {
756 int wait;
757
758
759
760
761
762
763
764 ahc_outb(ahc, SXFRCTL1,
765 ahc_inb(ahc, SXFRCTL1) | BITBUCKET);
766 wait = 5000;
767 while (--wait != 0) {
768 if ((ahc_inb(ahc, SCSISIGI)
769 & (CDI|MSGI)) != 0)
770 break;
771 ahc_delay(100);
772 }
773 ahc_outb(ahc, SXFRCTL1,
774 ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
775 if (wait == 0) {
776 struct scb *scb;
777 u_int scb_index;
778
779 ahc_print_devinfo(ahc, &devinfo);
780 printf("Unable to clear parity error. "
781 "Resetting bus.\n");
782 scb_index = ahc_inb(ahc, SCB_TAG);
783 scb = ahc_lookup_scb(ahc, scb_index);
784 if (scb != NULL)
785 ahc_set_transaction_status(scb,
786 CAM_UNCOR_PARITY);
787 ahc_reset_channel(ahc, devinfo.channel,
788 TRUE);
789 }
790 } else {
791 ahc_inb(ahc, SCSIDATL);
792 }
793 }
794 break;
795 }
796 case DATA_OVERRUN:
797 {
798
799
800
801
802
803
804
805
806 u_int scbindex = ahc_inb(ahc, SCB_TAG);
807 u_int lastphase = ahc_inb(ahc, LASTPHASE);
808 u_int i;
809
810 scb = ahc_lookup_scb(ahc, scbindex);
811 for (i = 0; i < num_phases; i++) {
812 if (lastphase == ahc_phase_table[i].phase)
813 break;
814 }
815 ahc_print_path(ahc, scb);
816 printf("data overrun detected %s."
817 " Tag == 0x%x.\n",
818 ahc_phase_table[i].phasemsg,
819 scb->hscb->tag);
820 ahc_print_path(ahc, scb);
821 printf("%s seen Data Phase. Length = %ld. NumSGs = %d.\n",
822 ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",
823 ahc_get_transfer_length(scb), scb->sg_count);
824 if (scb->sg_count > 0) {
825 for (i = 0; i < scb->sg_count; i++) {
826
827 printf("sg[%d] - Addr 0x%x%x : Length %d\n",
828 i,
829 (ahc_le32toh(scb->sg_list[i].len) >> 24
830 & SG_HIGH_ADDR_BITS),
831 ahc_le32toh(scb->sg_list[i].addr),
832 ahc_le32toh(scb->sg_list[i].len)
833 & AHC_SG_LEN_MASK);
834 }
835 }
836
837
838
839
840 ahc_freeze_devq(ahc, scb);
841 if ((scb->flags & SCB_SENSE) == 0) {
842 ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
843 } else {
844 scb->flags &= ~SCB_SENSE;
845 ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
846 }
847 ahc_freeze_scb(scb);
848
849 if ((ahc->features & AHC_ULTRA2) != 0) {
850
851
852
853
854 ahc_outb(ahc, SXFRCTL0,
855 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);
856 ahc_outb(ahc, SXFRCTL0,
857 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);
858 }
859 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
860 u_int dscommand1;
861
862
863 dscommand1 = ahc_inb(ahc, DSCOMMAND1);
864 ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
865 ahc_outb(ahc, HADDR, 0);
866 ahc_outb(ahc, DSCOMMAND1, dscommand1);
867 }
868 break;
869 }
870 case MKMSG_FAILED:
871 {
872 u_int scbindex;
873
874 printf("%s:%c:%d:%d: Attempt to issue message failed\n",
875 ahc_name(ahc), devinfo.channel, devinfo.target,
876 devinfo.lun);
877 scbindex = ahc_inb(ahc, SCB_TAG);
878 scb = ahc_lookup_scb(ahc, scbindex);
879 if (scb != NULL
880 && (scb->flags & SCB_RECOVERY_SCB) != 0)
881
882
883
884
885 ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
886 SCB_GET_CHANNEL(ahc, scb),
887 SCB_GET_LUN(scb), scb->hscb->tag,
888 ROLE_INITIATOR, 0,
889 SEARCH_REMOVE);
890 break;
891 }
892 case NO_FREE_SCB:
893 {
894 printf("%s: No free or disconnected SCBs\n", ahc_name(ahc));
895 ahc_dump_card_state(ahc);
896 panic("for safety");
897 break;
898 }
899 case SCB_MISMATCH:
900 {
901 u_int scbptr;
902
903 scbptr = ahc_inb(ahc, SCBPTR);
904 printf("Bogus TAG after DMA. SCBPTR %d, tag %d, our tag %d\n",
905 scbptr, ahc_inb(ahc, ARG_1),
906 ahc->scb_data->hscbs[scbptr].tag);
907 ahc_dump_card_state(ahc);
908 panic("for saftey");
909 break;
910 }
911 case OUT_OF_RANGE:
912 {
913 printf("%s: BTT calculation out of range\n", ahc_name(ahc));
914 printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
915 "ARG_1 == 0x%x ACCUM = 0x%x\n",
916 ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
917 ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
918 printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
919 "SINDEX == 0x%x\n, A == 0x%x\n",
920 ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
921 ahc_index_busy_tcl(ahc,
922 BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
923 ahc_inb(ahc, SAVED_LUN))),
924 ahc_inb(ahc, SINDEX),
925 ahc_inb(ahc, ACCUM));
926 printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
927 "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
928 ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
929 ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
930 ahc_inb(ahc, SCB_CONTROL));
931 printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
932 ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
933 ahc_dump_card_state(ahc);
934 panic("for safety");
935 break;
936 }
937 default:
938 printf("ahc_intr: seqint, "
939 "intstat == 0x%x, scsisigi = 0x%x\n",
940 intstat, ahc_inb(ahc, SCSISIGI));
941 break;
942 }
943unpause:
944
945
946
947
948
949 ahc_unpause(ahc);
950}
951
952void
953ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
954{
955 u_int scb_index;
956 u_int status0;
957 u_int status;
958 struct scb *scb;
959 char cur_channel;
960 char intr_channel;
961
962 if ((ahc->features & AHC_TWIN) != 0
963 && ((ahc_inb(ahc, SBLKCTL) & SELBUSB) != 0))
964 cur_channel = 'B';
965 else
966 cur_channel = 'A';
967 intr_channel = cur_channel;
968
969 if ((ahc->features & AHC_ULTRA2) != 0)
970 status0 = ahc_inb(ahc, SSTAT0) & IOERR;
971 else
972 status0 = 0;
973 status = ahc_inb(ahc, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
974 if (status == 0 && status0 == 0) {
975 if ((ahc->features & AHC_TWIN) != 0) {
976
977 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
978 status = ahc_inb(ahc, SSTAT1)
979 & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
980 intr_channel = (cur_channel == 'A') ? 'B' : 'A';
981 }
982 if (status == 0) {
983 printf("%s: Spurious SCSI interrupt\n", ahc_name(ahc));
984 ahc_outb(ahc, CLRINT, CLRSCSIINT);
985 ahc_unpause(ahc);
986 return;
987 }
988 }
989
990
991 ahc_clear_critical_section(ahc);
992
993 scb_index = ahc_inb(ahc, SCB_TAG);
994 scb = ahc_lookup_scb(ahc, scb_index);
995 if (scb != NULL
996 && (ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
997 scb = NULL;
998
999 if ((ahc->features & AHC_ULTRA2) != 0
1000 && (status0 & IOERR) != 0) {
1001 int now_lvd;
1002
1003 now_lvd = ahc_inb(ahc, SBLKCTL) & ENAB40;
1004 printf("%s: Transceiver State Has Changed to %s mode\n",
1005 ahc_name(ahc), now_lvd ? "LVD" : "SE");
1006 ahc_outb(ahc, CLRSINT0, CLRIOERR);
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017 ahc_reset_channel(ahc, intr_channel,
1018 now_lvd == 0);
1019 } else if ((status & SCSIRSTI) != 0) {
1020 printf("%s: Someone reset channel %c\n",
1021 ahc_name(ahc), intr_channel);
1022 if (intr_channel != cur_channel)
1023 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
1024 ahc_reset_channel(ahc, intr_channel, FALSE);
1025 } else if ((status & SCSIPERR) != 0) {
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036 struct ahc_devinfo devinfo;
1037 u_int mesg_out;
1038 u_int curphase;
1039 u_int errorphase;
1040 u_int lastphase;
1041 u_int scsirate;
1042 u_int i;
1043 u_int sstat2;
1044 int silent;
1045
1046 lastphase = ahc_inb(ahc, LASTPHASE);
1047 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
1048 sstat2 = ahc_inb(ahc, SSTAT2);
1049 ahc_outb(ahc, CLRSINT1, CLRSCSIPERR);
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061 if ((ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0
1062 || curphase == P_DATAIN || curphase == P_DATAIN_DT)
1063 errorphase = curphase;
1064 else
1065 errorphase = lastphase;
1066
1067 for (i = 0; i < num_phases; i++) {
1068 if (errorphase == ahc_phase_table[i].phase)
1069 break;
1070 }
1071 mesg_out = ahc_phase_table[i].mesg_out;
1072 silent = FALSE;
1073 if (scb != NULL) {
1074 if (SCB_IS_SILENT(scb))
1075 silent = TRUE;
1076 else
1077 ahc_print_path(ahc, scb);
1078 scb->flags |= SCB_TRANSMISSION_ERROR;
1079 } else
1080 printf("%s:%c:%d: ", ahc_name(ahc), intr_channel,
1081 SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)));
1082 scsirate = ahc_inb(ahc, SCSIRATE);
1083 if (silent == FALSE) {
1084 printf("parity error detected %s. "
1085 "SEQADDR(0x%x) SCSIRATE(0x%x)\n",
1086 ahc_phase_table[i].phasemsg,
1087 ahc_inw(ahc, SEQADDR0),
1088 scsirate);
1089 if ((ahc->features & AHC_DT) != 0) {
1090 if ((sstat2 & CRCVALERR) != 0)
1091 printf("\tCRC Value Mismatch\n");
1092 if ((sstat2 & CRCENDERR) != 0)
1093 printf("\tNo terminal CRC packet "
1094 "recevied\n");
1095 if ((sstat2 & CRCREQERR) != 0)
1096 printf("\tIllegal CRC packet "
1097 "request\n");
1098 if ((sstat2 & DUAL_EDGE_ERR) != 0)
1099 printf("\tUnexpected %sDT Data Phase\n",
1100 (scsirate & SINGLE_EDGE)
1101 ? "" : "non-");
1102 }
1103 }
1104
1105 if ((ahc->features & AHC_DT) != 0
1106 && (sstat2 & DUAL_EDGE_ERR) != 0) {
1107
1108
1109
1110
1111
1112 mesg_out = MSG_INITIATOR_DET_ERR;
1113 }
1114
1115
1116
1117
1118
1119
1120
1121
1122 if (mesg_out != MSG_NOOP) {
1123 if (ahc->msg_type != MSG_TYPE_NONE)
1124 ahc->send_msg_perror = TRUE;
1125 else
1126 ahc_outb(ahc, MSG_OUT, mesg_out);
1127 }
1128
1129
1130
1131
1132
1133 ahc_fetch_devinfo(ahc, &devinfo);
1134 ahc_force_renegotiation(ahc, &devinfo);
1135
1136 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1137 ahc_unpause(ahc);
1138 } else if ((status & SELTO) != 0) {
1139 u_int scbptr;
1140
1141
1142 ahc_outb(ahc, SCSISEQ, 0);
1143
1144
1145 ahc_clear_msg_state(ahc);
1146
1147
1148 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
1149 ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159 ahc_outb(ahc, CLRSINT0, CLRSELINGO);
1160
1161 scbptr = ahc_inb(ahc, WAITING_SCBH);
1162 ahc_outb(ahc, SCBPTR, scbptr);
1163 scb_index = ahc_inb(ahc, SCB_TAG);
1164
1165 scb = ahc_lookup_scb(ahc, scb_index);
1166 if (scb == NULL) {
1167 printf("%s: ahc_intr - referenced scb not "
1168 "valid during SELTO scb(%d, %d)\n",
1169 ahc_name(ahc), scbptr, scb_index);
1170 ahc_dump_card_state(ahc);
1171 } else {
1172 struct ahc_devinfo devinfo;
1173#ifdef AHC_DEBUG
1174 if ((ahc_debug & AHC_SHOW_SELTO) != 0) {
1175 ahc_print_path(ahc, scb);
1176 printf("Saw Selection Timeout for SCB 0x%x\n",
1177 scb_index);
1178 }
1179#endif
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189 ahc_scb_devinfo(ahc, &devinfo, scb);
1190 ahc_force_renegotiation(ahc, &devinfo);
1191 ahc_set_transaction_status(scb, CAM_SEL_TIMEOUT);
1192 ahc_freeze_devq(ahc, scb);
1193 }
1194 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1195 ahc_restart(ahc);
1196 } else if ((status & BUSFREE) != 0
1197 && (ahc_inb(ahc, SIMODE1) & ENBUSFREE) != 0) {
1198 struct ahc_devinfo devinfo;
1199 u_int lastphase;
1200 u_int saved_scsiid;
1201 u_int saved_lun;
1202 u_int target;
1203 u_int initiator_role_id;
1204 char channel;
1205 int printerror;
1206
1207
1208
1209
1210
1211
1212
1213 ahc_outb(ahc, SCSISEQ,
1214 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
1215
1216
1217
1218
1219
1220
1221
1222 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
1223 ahc_outb(ahc, CLRSINT1, CLRBUSFREE|CLRSCSIPERR);
1224
1225
1226
1227
1228
1229
1230
1231 lastphase = ahc_inb(ahc, LASTPHASE);
1232 saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
1233 saved_lun = ahc_inb(ahc, SAVED_LUN);
1234 target = SCSIID_TARGET(ahc, saved_scsiid);
1235 initiator_role_id = SCSIID_OUR_ID(saved_scsiid);
1236 channel = SCSIID_CHANNEL(ahc, saved_scsiid);
1237 ahc_compile_devinfo(&devinfo, initiator_role_id,
1238 target, saved_lun, channel, ROLE_INITIATOR);
1239 printerror = 1;
1240
1241 if (lastphase == P_MESGOUT) {
1242 u_int tag;
1243
1244 tag = SCB_LIST_NULL;
1245 if (ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT_TAG, TRUE)
1246 || ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT, TRUE)) {
1247 if (ahc->msgout_buf[ahc->msgout_index - 1]
1248 == MSG_ABORT_TAG)
1249 tag = scb->hscb->tag;
1250 ahc_print_path(ahc, scb);
1251 printf("SCB %d - Abort%s Completed.\n",
1252 scb->hscb->tag, tag == SCB_LIST_NULL ?
1253 "" : " Tag");
1254 ahc_abort_scbs(ahc, target, channel,
1255 saved_lun, tag,
1256 ROLE_INITIATOR,
1257 CAM_REQ_ABORTED);
1258 printerror = 0;
1259 } else if (ahc_sent_msg(ahc, AHCMSG_1B,
1260 MSG_BUS_DEV_RESET, TRUE)) {
1261#ifdef __FreeBSD__
1262
1263
1264
1265
1266
1267 if (scb != NULL
1268 && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV
1269 && ahc_match_scb(ahc, scb, target, channel,
1270 CAM_LUN_WILDCARD,
1271 SCB_LIST_NULL,
1272 ROLE_INITIATOR)) {
1273 ahc_set_transaction_status(scb, CAM_REQ_CMP);
1274 }
1275#endif
1276 ahc_compile_devinfo(&devinfo,
1277 initiator_role_id,
1278 target,
1279 CAM_LUN_WILDCARD,
1280 channel,
1281 ROLE_INITIATOR);
1282 ahc_handle_devreset(ahc, &devinfo,
1283 CAM_BDR_SENT,
1284 "Bus Device Reset",
1285 0);
1286 printerror = 0;
1287 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
1288 MSG_EXT_PPR, FALSE)) {
1289 struct ahc_initiator_tinfo *tinfo;
1290 struct ahc_tmode_tstate *tstate;
1291
1292
1293
1294
1295
1296 tinfo = ahc_fetch_transinfo(ahc,
1297 devinfo.channel,
1298 devinfo.our_scsiid,
1299 devinfo.target,
1300 &tstate);
1301 tinfo->curr.transport_version = 2;
1302 tinfo->goal.transport_version = 2;
1303 tinfo->goal.ppr_options = 0;
1304 ahc_qinfifo_requeue_tail(ahc, scb);
1305 printerror = 0;
1306 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
1307 MSG_EXT_WDTR, FALSE)) {
1308
1309
1310
1311
1312 ahc_set_width(ahc, &devinfo,
1313 MSG_EXT_WDTR_BUS_8_BIT,
1314 AHC_TRANS_CUR|AHC_TRANS_GOAL,
1315 TRUE);
1316 ahc_qinfifo_requeue_tail(ahc, scb);
1317 printerror = 0;
1318 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
1319 MSG_EXT_SDTR, FALSE)) {
1320
1321
1322
1323
1324 ahc_set_syncrate(ahc, &devinfo,
1325 NULL,
1326 0, 0,
1327 0,
1328 AHC_TRANS_CUR|AHC_TRANS_GOAL,
1329 TRUE);
1330 ahc_qinfifo_requeue_tail(ahc, scb);
1331 printerror = 0;
1332 }
1333 }
1334 if (printerror != 0) {
1335 u_int i;
1336
1337 if (scb != NULL) {
1338 u_int tag;
1339
1340 if ((scb->hscb->control & TAG_ENB) != 0)
1341 tag = scb->hscb->tag;
1342 else
1343 tag = SCB_LIST_NULL;
1344 ahc_print_path(ahc, scb);
1345 ahc_abort_scbs(ahc, target, channel,
1346 SCB_GET_LUN(scb), tag,
1347 ROLE_INITIATOR,
1348 CAM_UNEXP_BUSFREE);
1349 } else {
1350
1351
1352
1353
1354 printf("%s: ", ahc_name(ahc));
1355 }
1356 for (i = 0; i < num_phases; i++) {
1357 if (lastphase == ahc_phase_table[i].phase)
1358 break;
1359 }
1360 if (lastphase != P_BUSFREE) {
1361
1362
1363
1364
1365
1366
1367 ahc_force_renegotiation(ahc, &devinfo);
1368 }
1369 printf("Unexpected busfree %s\n"
1370 "SEQADDR == 0x%x\n",
1371 ahc_phase_table[i].phasemsg,
1372 ahc_inb(ahc, SEQADDR0)
1373 | (ahc_inb(ahc, SEQADDR1) << 8));
1374 }
1375 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1376 ahc_restart(ahc);
1377 } else {
1378 printf("%s: Missing case in ahc_handle_scsiint. status = %x\n",
1379 ahc_name(ahc), status);
1380 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1381 }
1382}
1383
1384
1385
1386
1387
1388static void
1389ahc_force_renegotiation(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
1390{
1391 struct ahc_initiator_tinfo *targ_info;
1392 struct ahc_tmode_tstate *tstate;
1393
1394 targ_info = ahc_fetch_transinfo(ahc,
1395 devinfo->channel,
1396 devinfo->our_scsiid,
1397 devinfo->target,
1398 &tstate);
1399 ahc_update_neg_request(ahc, devinfo, tstate,
1400 targ_info, AHC_NEG_IF_NON_ASYNC);
1401}
1402
1403#define AHC_MAX_STEPS 2000
1404void
1405ahc_clear_critical_section(struct ahc_softc *ahc)
1406{
1407 int stepping;
1408 int steps;
1409 u_int simode0;
1410 u_int simode1;
1411
1412 if (ahc->num_critical_sections == 0)
1413 return;
1414
1415 stepping = FALSE;
1416 steps = 0;
1417 simode0 = 0;
1418 simode1 = 0;
1419 for (;;) {
1420 struct cs *cs;
1421 u_int seqaddr;
1422 u_int i;
1423
1424 seqaddr = ahc_inb(ahc, SEQADDR0)
1425 | (ahc_inb(ahc, SEQADDR1) << 8);
1426
1427
1428
1429
1430
1431
1432 if (seqaddr != 0)
1433 seqaddr -= 1;
1434 cs = ahc->critical_sections;
1435 for (i = 0; i < ahc->num_critical_sections; i++, cs++) {
1436
1437 if (cs->begin < seqaddr && cs->end >= seqaddr)
1438 break;
1439 }
1440
1441 if (i == ahc->num_critical_sections)
1442 break;
1443
1444 if (steps > AHC_MAX_STEPS) {
1445 printf("%s: Infinite loop in critical section\n",
1446 ahc_name(ahc));
1447 ahc_dump_card_state(ahc);
1448 panic("critical section loop");
1449 }
1450
1451 steps++;
1452 if (stepping == FALSE) {
1453
1454
1455
1456
1457
1458
1459
1460 simode0 = ahc_inb(ahc, SIMODE0);
1461 ahc_outb(ahc, SIMODE0, 0);
1462 simode1 = ahc_inb(ahc, SIMODE1);
1463 if ((ahc->features & AHC_DT) != 0)
1464
1465
1466
1467
1468
1469
1470
1471
1472 ahc_outb(ahc, SIMODE1, simode1 & ENBUSFREE);
1473 else
1474 ahc_outb(ahc, SIMODE1, 0);
1475 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1476 ahc_outb(ahc, SEQCTL, ahc->seqctl | STEP);
1477 stepping = TRUE;
1478 }
1479 if ((ahc->features & AHC_DT) != 0) {
1480 ahc_outb(ahc, CLRSINT1, CLRBUSFREE);
1481 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1482 }
1483 ahc_outb(ahc, HCNTRL, ahc->unpause);
1484 while (!ahc_is_paused(ahc))
1485 ahc_delay(200);
1486 }
1487 if (stepping) {
1488 ahc_outb(ahc, SIMODE0, simode0);
1489 ahc_outb(ahc, SIMODE1, simode1);
1490 ahc_outb(ahc, SEQCTL, ahc->seqctl);
1491 }
1492}
1493
1494
1495
1496
1497void
1498ahc_clear_intstat(struct ahc_softc *ahc)
1499{
1500
1501 ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
1502 |CLRBUSFREE|CLRSCSIPERR|CLRPHASECHG|
1503 CLRREQINIT);
1504 ahc_flush_device_writes(ahc);
1505 ahc_outb(ahc, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO);
1506 ahc_flush_device_writes(ahc);
1507 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1508 ahc_flush_device_writes(ahc);
1509}
1510
1511
1512#ifdef AHC_DEBUG
1513uint32_t ahc_debug = AHC_DEBUG_OPTS;
1514#endif
1515
1516void
1517ahc_print_scb(struct scb *scb)
1518{
1519 int i;
1520
1521 struct hardware_scb *hscb = scb->hscb;
1522
1523 printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
1524 (void *)scb,
1525 hscb->control,
1526 hscb->scsiid,
1527 hscb->lun,
1528 hscb->cdb_len);
1529 printf("Shared Data: ");
1530 for (i = 0; i < sizeof(hscb->shared_data.cdb); i++)
1531 printf("%#02x", hscb->shared_data.cdb[i]);
1532 printf(" dataptr:%#x datacnt:%#x sgptr:%#x tag:%#x\n",
1533 ahc_le32toh(hscb->dataptr),
1534 ahc_le32toh(hscb->datacnt),
1535 ahc_le32toh(hscb->sgptr),
1536 hscb->tag);
1537 if (scb->sg_count > 0) {
1538 for (i = 0; i < scb->sg_count; i++) {
1539 printf("sg[%d] - Addr 0x%x%x : Length %d\n",
1540 i,
1541 (ahc_le32toh(scb->sg_list[i].len) >> 24
1542 & SG_HIGH_ADDR_BITS),
1543 ahc_le32toh(scb->sg_list[i].addr),
1544 ahc_le32toh(scb->sg_list[i].len));
1545 }
1546 }
1547}
1548
1549
1550
1551
1552
1553
1554static struct ahc_tmode_tstate *
1555ahc_alloc_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel)
1556{
1557 struct ahc_tmode_tstate *master_tstate;
1558 struct ahc_tmode_tstate *tstate;
1559 int i;
1560
1561 master_tstate = ahc->enabled_targets[ahc->our_id];
1562 if (channel == 'B') {
1563 scsi_id += 8;
1564 master_tstate = ahc->enabled_targets[ahc->our_id_b + 8];
1565 }
1566 if (ahc->enabled_targets[scsi_id] != NULL
1567 && ahc->enabled_targets[scsi_id] != master_tstate)
1568 panic("%s: ahc_alloc_tstate - Target already allocated",
1569 ahc_name(ahc));
1570 tstate = (struct ahc_tmode_tstate*)malloc(sizeof(*tstate),
1571 M_DEVBUF, M_NOWAIT);
1572 if (tstate == NULL)
1573 return (NULL);
1574
1575
1576
1577
1578
1579
1580
1581 if (master_tstate != NULL) {
1582 memcpy(tstate, master_tstate, sizeof(*tstate));
1583 memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns));
1584 tstate->ultraenb = 0;
1585 for (i = 0; i < AHC_NUM_TARGETS; i++) {
1586 memset(&tstate->transinfo[i].curr, 0,
1587 sizeof(tstate->transinfo[i].curr));
1588 memset(&tstate->transinfo[i].goal, 0,
1589 sizeof(tstate->transinfo[i].goal));
1590 }
1591 } else
1592 memset(tstate, 0, sizeof(*tstate));
1593 ahc->enabled_targets[scsi_id] = tstate;
1594 return (tstate);
1595}
1596
1597#ifdef AHC_TARGET_MODE
1598
1599
1600
1601
1602static void
1603ahc_free_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel, int force)
1604{
1605 struct ahc_tmode_tstate *tstate;
1606
1607
1608
1609
1610
1611 if (((channel == 'B' && scsi_id == ahc->our_id_b)
1612 || (channel == 'A' && scsi_id == ahc->our_id))
1613 && force == FALSE)
1614 return;
1615
1616 if (channel == 'B')
1617 scsi_id += 8;
1618 tstate = ahc->enabled_targets[scsi_id];
1619 if (tstate != NULL)
1620 free(tstate, M_DEVBUF);
1621 ahc->enabled_targets[scsi_id] = NULL;
1622}
1623#endif
1624
1625
1626
1627
1628
1629
1630
1631struct ahc_syncrate *
1632ahc_devlimited_syncrate(struct ahc_softc *ahc,
1633 struct ahc_initiator_tinfo *tinfo,
1634 u_int *period, u_int *ppr_options, role_t role)
1635{
1636 struct ahc_transinfo *transinfo;
1637 u_int maxsync;
1638
1639 if ((ahc->features & AHC_ULTRA2) != 0) {
1640 if ((ahc_inb(ahc, SBLKCTL) & ENAB40) != 0
1641 && (ahc_inb(ahc, SSTAT2) & EXP_ACTIVE) == 0) {
1642 maxsync = AHC_SYNCRATE_DT;
1643 } else {
1644 maxsync = AHC_SYNCRATE_ULTRA;
1645
1646 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1647 }
1648 } else if ((ahc->features & AHC_ULTRA) != 0) {
1649 maxsync = AHC_SYNCRATE_ULTRA;
1650 } else {
1651 maxsync = AHC_SYNCRATE_FAST;
1652 }
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663 if (role == ROLE_TARGET)
1664 transinfo = &tinfo->user;
1665 else
1666 transinfo = &tinfo->goal;
1667 *ppr_options &= transinfo->ppr_options;
1668 if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
1669 maxsync = MAX(maxsync, AHC_SYNCRATE_ULTRA2);
1670 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1671 }
1672 if (transinfo->period == 0) {
1673 *period = 0;
1674 *ppr_options = 0;
1675 return (NULL);
1676 }
1677 *period = MAX(*period, transinfo->period);
1678 return (ahc_find_syncrate(ahc, period, ppr_options, maxsync));
1679}
1680
1681
1682
1683
1684
1685
1686struct ahc_syncrate *
1687ahc_find_syncrate(struct ahc_softc *ahc, u_int *period,
1688 u_int *ppr_options, u_int maxsync)
1689{
1690 struct ahc_syncrate *syncrate;
1691
1692 if ((ahc->features & AHC_DT) == 0)
1693 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1694
1695
1696 if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
1697 && maxsync < AHC_SYNCRATE_ULTRA2)
1698 maxsync = AHC_SYNCRATE_ULTRA2;
1699
1700 for (syncrate = &ahc_syncrates[maxsync];
1701 syncrate->rate != NULL;
1702 syncrate++) {
1703
1704
1705
1706
1707
1708 if ((ahc->features & AHC_ULTRA2) != 0
1709 && (syncrate->sxfr_u2 == 0))
1710 break;
1711
1712 if (*period <= syncrate->period) {
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724 if (syncrate == &ahc_syncrates[maxsync])
1725 *period = syncrate->period;
1726
1727
1728
1729
1730
1731 if ((syncrate->sxfr_u2 & ST_SXFR) != 0)
1732 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1733 break;
1734 }
1735 }
1736
1737 if ((*period == 0)
1738 || (syncrate->rate == NULL)
1739 || ((ahc->features & AHC_ULTRA2) != 0
1740 && (syncrate->sxfr_u2 == 0))) {
1741
1742 *period = 0;
1743 syncrate = NULL;
1744 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1745 }
1746 return (syncrate);
1747}
1748
1749
1750
1751
1752
1753u_int
1754ahc_find_period(struct ahc_softc *ahc, u_int scsirate, u_int maxsync)
1755{
1756 struct ahc_syncrate *syncrate;
1757
1758 if ((ahc->features & AHC_ULTRA2) != 0)
1759 scsirate &= SXFR_ULTRA2;
1760 else
1761 scsirate &= SXFR;
1762
1763 syncrate = &ahc_syncrates[maxsync];
1764 while (syncrate->rate != NULL) {
1765
1766 if ((ahc->features & AHC_ULTRA2) != 0) {
1767 if (syncrate->sxfr_u2 == 0)
1768 break;
1769 else if (scsirate == (syncrate->sxfr_u2 & SXFR_ULTRA2))
1770 return (syncrate->period);
1771 } else if (scsirate == (syncrate->sxfr & SXFR)) {
1772 return (syncrate->period);
1773 }
1774 syncrate++;
1775 }
1776 return (0);
1777}
1778
1779
1780
1781
1782
1783void
1784ahc_validate_offset(struct ahc_softc *ahc,
1785 struct ahc_initiator_tinfo *tinfo,
1786 struct ahc_syncrate *syncrate,
1787 u_int *offset, int wide, role_t role)
1788{
1789 u_int maxoffset;
1790
1791
1792 if (syncrate == NULL) {
1793 maxoffset = 0;
1794 } else if ((ahc->features & AHC_ULTRA2) != 0) {
1795 maxoffset = MAX_OFFSET_ULTRA2;
1796 } else {
1797 if (wide)
1798 maxoffset = MAX_OFFSET_16BIT;
1799 else
1800 maxoffset = MAX_OFFSET_8BIT;
1801 }
1802 *offset = MIN(*offset, maxoffset);
1803 if (tinfo != NULL) {
1804 if (role == ROLE_TARGET)
1805 *offset = MIN(*offset, tinfo->user.offset);
1806 else
1807 *offset = MIN(*offset, tinfo->goal.offset);
1808 }
1809}
1810
1811
1812
1813
1814
1815void
1816ahc_validate_width(struct ahc_softc *ahc, struct ahc_initiator_tinfo *tinfo,
1817 u_int *bus_width, role_t role)
1818{
1819 switch (*bus_width) {
1820 default:
1821 if (ahc->features & AHC_WIDE) {
1822
1823 *bus_width = MSG_EXT_WDTR_BUS_16_BIT;
1824 break;
1825 }
1826
1827 case MSG_EXT_WDTR_BUS_8_BIT:
1828 *bus_width = MSG_EXT_WDTR_BUS_8_BIT;
1829 break;
1830 }
1831 if (tinfo != NULL) {
1832 if (role == ROLE_TARGET)
1833 *bus_width = MIN(tinfo->user.width, *bus_width);
1834 else
1835 *bus_width = MIN(tinfo->goal.width, *bus_width);
1836 }
1837}
1838
1839
1840
1841
1842
1843
1844
1845int
1846ahc_update_neg_request(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
1847 struct ahc_tmode_tstate *tstate,
1848 struct ahc_initiator_tinfo *tinfo, ahc_neg_type neg_type)
1849{
1850 u_int auto_negotiate_orig;
1851
1852 auto_negotiate_orig = tstate->auto_negotiate;
1853 if (neg_type == AHC_NEG_ALWAYS) {
1854
1855
1856
1857
1858
1859
1860 if ((ahc->features & AHC_WIDE) != 0)
1861 tinfo->curr.width = AHC_WIDTH_UNKNOWN;
1862 tinfo->curr.period = AHC_PERIOD_UNKNOWN;
1863 tinfo->curr.offset = AHC_OFFSET_UNKNOWN;
1864 }
1865 if (tinfo->curr.period != tinfo->goal.period
1866 || tinfo->curr.width != tinfo->goal.width
1867 || tinfo->curr.offset != tinfo->goal.offset
1868 || tinfo->curr.ppr_options != tinfo->goal.ppr_options
1869 || (neg_type == AHC_NEG_IF_NON_ASYNC
1870 && (tinfo->goal.offset != 0
1871 || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT
1872 || tinfo->goal.ppr_options != 0)))
1873 tstate->auto_negotiate |= devinfo->target_mask;
1874 else
1875 tstate->auto_negotiate &= ~devinfo->target_mask;
1876
1877 return (auto_negotiate_orig != tstate->auto_negotiate);
1878}
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888void
1889ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
1890 struct ahc_syncrate *syncrate, u_int period,
1891 u_int offset, u_int ppr_options, u_int type, int paused)
1892{
1893 struct ahc_initiator_tinfo *tinfo;
1894 struct ahc_tmode_tstate *tstate;
1895 u_int old_period;
1896 u_int old_offset;
1897 u_int old_ppr;
1898 int active;
1899 int update_needed;
1900
1901 active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
1902 update_needed = 0;
1903
1904 if (syncrate == NULL) {
1905 period = 0;
1906 offset = 0;
1907 }
1908
1909 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
1910 devinfo->target, &tstate);
1911
1912 if ((type & AHC_TRANS_USER) != 0) {
1913 tinfo->user.period = period;
1914 tinfo->user.offset = offset;
1915 tinfo->user.ppr_options = ppr_options;
1916 }
1917
1918 if ((type & AHC_TRANS_GOAL) != 0) {
1919 tinfo->goal.period = period;
1920 tinfo->goal.offset = offset;
1921 tinfo->goal.ppr_options = ppr_options;
1922 }
1923
1924 old_period = tinfo->curr.period;
1925 old_offset = tinfo->curr.offset;
1926 old_ppr = tinfo->curr.ppr_options;
1927
1928 if ((type & AHC_TRANS_CUR) != 0
1929 && (old_period != period
1930 || old_offset != offset
1931 || old_ppr != ppr_options)) {
1932 u_int scsirate;
1933
1934 update_needed++;
1935 scsirate = tinfo->scsirate;
1936 if ((ahc->features & AHC_ULTRA2) != 0) {
1937
1938 scsirate &= ~(SXFR_ULTRA2|SINGLE_EDGE|ENABLE_CRC);
1939 if (syncrate != NULL) {
1940 scsirate |= syncrate->sxfr_u2;
1941 if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0)
1942 scsirate |= ENABLE_CRC;
1943 else
1944 scsirate |= SINGLE_EDGE;
1945 }
1946 } else {
1947
1948 scsirate &= ~(SXFR|SOFS);
1949
1950
1951
1952
1953 tstate->ultraenb &= ~devinfo->target_mask;
1954 if (syncrate != NULL) {
1955 if (syncrate->sxfr & ULTRA_SXFR) {
1956 tstate->ultraenb |=
1957 devinfo->target_mask;
1958 }
1959 scsirate |= syncrate->sxfr & SXFR;
1960 scsirate |= offset & SOFS;
1961 }
1962 if (active) {
1963 u_int sxfrctl0;
1964
1965 sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
1966 sxfrctl0 &= ~FAST20;
1967 if (tstate->ultraenb & devinfo->target_mask)
1968 sxfrctl0 |= FAST20;
1969 ahc_outb(ahc, SXFRCTL0, sxfrctl0);
1970 }
1971 }
1972 if (active) {
1973 ahc_outb(ahc, SCSIRATE, scsirate);
1974 if ((ahc->features & AHC_ULTRA2) != 0)
1975 ahc_outb(ahc, SCSIOFFSET, offset);
1976 }
1977
1978 tinfo->scsirate = scsirate;
1979 tinfo->curr.period = period;
1980 tinfo->curr.offset = offset;
1981 tinfo->curr.ppr_options = ppr_options;
1982
1983 ahc_send_async(ahc, devinfo->channel, devinfo->target,
1984 CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
1985 if (bootverbose) {
1986 if (offset != 0) {
1987 printf("%s: target %d synchronous at %sMHz%s, "
1988 "offset = 0x%x\n", ahc_name(ahc),
1989 devinfo->target, syncrate->rate,
1990 (ppr_options & MSG_EXT_PPR_DT_REQ)
1991 ? " DT" : "", offset);
1992 } else {
1993 printf("%s: target %d using "
1994 "asynchronous transfers\n",
1995 ahc_name(ahc), devinfo->target);
1996 }
1997 }
1998 }
1999
2000 update_needed += ahc_update_neg_request(ahc, devinfo, tstate,
2001 tinfo, AHC_NEG_TO_GOAL);
2002
2003 if (update_needed)
2004 ahc_update_pending_scbs(ahc);
2005}
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015void
2016ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2017 u_int width, u_int type, int paused)
2018{
2019 struct ahc_initiator_tinfo *tinfo;
2020 struct ahc_tmode_tstate *tstate;
2021 u_int oldwidth;
2022 int active;
2023 int update_needed;
2024
2025 active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
2026 update_needed = 0;
2027 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
2028 devinfo->target, &tstate);
2029
2030 if ((type & AHC_TRANS_USER) != 0)
2031 tinfo->user.width = width;
2032
2033 if ((type & AHC_TRANS_GOAL) != 0)
2034 tinfo->goal.width = width;
2035
2036 oldwidth = tinfo->curr.width;
2037 if ((type & AHC_TRANS_CUR) != 0 && oldwidth != width) {
2038 u_int scsirate;
2039
2040 update_needed++;
2041 scsirate = tinfo->scsirate;
2042 scsirate &= ~WIDEXFER;
2043 if (width == MSG_EXT_WDTR_BUS_16_BIT)
2044 scsirate |= WIDEXFER;
2045
2046 tinfo->scsirate = scsirate;
2047
2048 if (active)
2049 ahc_outb(ahc, SCSIRATE, scsirate);
2050
2051 tinfo->curr.width = width;
2052
2053 ahc_send_async(ahc, devinfo->channel, devinfo->target,
2054 CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
2055 if (bootverbose) {
2056 printf("%s: target %d using %dbit transfers\n",
2057 ahc_name(ahc), devinfo->target,
2058 8 * (0x01 << width));
2059 }
2060 }
2061
2062 update_needed += ahc_update_neg_request(ahc, devinfo, tstate,
2063 tinfo, AHC_NEG_TO_GOAL);
2064 if (update_needed)
2065 ahc_update_pending_scbs(ahc);
2066}
2067
2068
2069
2070
2071void
2072ahc_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2073 ahc_queue_alg alg)
2074{
2075 ahc_platform_set_tags(ahc, devinfo, alg);
2076 ahc_send_async(ahc, devinfo->channel, devinfo->target,
2077 devinfo->lun, AC_TRANSFER_NEG, &alg);
2078}
2079
2080
2081
2082
2083
2084
2085static void
2086ahc_update_pending_scbs(struct ahc_softc *ahc)
2087{
2088 struct scb *pending_scb;
2089 int pending_scb_count;
2090 int i;
2091 int paused;
2092 u_int saved_scbptr;
2093
2094
2095
2096
2097
2098 pending_scb_count = 0;
2099 LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
2100 struct ahc_devinfo devinfo;
2101 struct hardware_scb *pending_hscb;
2102 struct ahc_initiator_tinfo *tinfo;
2103 struct ahc_tmode_tstate *tstate;
2104
2105 ahc_scb_devinfo(ahc, &devinfo, pending_scb);
2106 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
2107 devinfo.our_scsiid,
2108 devinfo.target, &tstate);
2109 pending_hscb = pending_scb->hscb;
2110 pending_hscb->control &= ~ULTRAENB;
2111 if ((tstate->ultraenb & devinfo.target_mask) != 0)
2112 pending_hscb->control |= ULTRAENB;
2113 pending_hscb->scsirate = tinfo->scsirate;
2114 pending_hscb->scsioffset = tinfo->curr.offset;
2115 if ((tstate->auto_negotiate & devinfo.target_mask) == 0
2116 && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) {
2117 pending_scb->flags &= ~SCB_AUTO_NEGOTIATE;
2118 pending_hscb->control &= ~MK_MESSAGE;
2119 }
2120 ahc_sync_scb(ahc, pending_scb,
2121 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2122 pending_scb_count++;
2123 }
2124
2125 if (pending_scb_count == 0)
2126 return;
2127
2128 if (ahc_is_paused(ahc)) {
2129 paused = 1;
2130 } else {
2131 paused = 0;
2132 ahc_pause(ahc);
2133 }
2134
2135 saved_scbptr = ahc_inb(ahc, SCBPTR);
2136
2137 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
2138 struct hardware_scb *pending_hscb;
2139 u_int control;
2140 u_int scb_tag;
2141
2142 ahc_outb(ahc, SCBPTR, i);
2143 scb_tag = ahc_inb(ahc, SCB_TAG);
2144 pending_scb = ahc_lookup_scb(ahc, scb_tag);
2145 if (pending_scb == NULL)
2146 continue;
2147
2148 pending_hscb = pending_scb->hscb;
2149 control = ahc_inb(ahc, SCB_CONTROL);
2150 control &= ~(ULTRAENB|MK_MESSAGE);
2151 control |= pending_hscb->control & (ULTRAENB|MK_MESSAGE);
2152 ahc_outb(ahc, SCB_CONTROL, control);
2153 ahc_outb(ahc, SCB_SCSIRATE, pending_hscb->scsirate);
2154 ahc_outb(ahc, SCB_SCSIOFFSET, pending_hscb->scsioffset);
2155 }
2156 ahc_outb(ahc, SCBPTR, saved_scbptr);
2157
2158 if (paused == 0)
2159 ahc_unpause(ahc);
2160}
2161
2162
2163static void
2164ahc_fetch_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
2165{
2166 u_int saved_scsiid;
2167 role_t role;
2168 int our_id;
2169
2170 if (ahc_inb(ahc, SSTAT0) & TARGET)
2171 role = ROLE_TARGET;
2172 else
2173 role = ROLE_INITIATOR;
2174
2175 if (role == ROLE_TARGET
2176 && (ahc->features & AHC_MULTI_TID) != 0
2177 && (ahc_inb(ahc, SEQ_FLAGS)
2178 & (CMDPHASE_PENDING|TARG_CMD_PENDING|NO_DISCONNECT)) != 0) {
2179
2180 our_id = ahc_inb(ahc, TARGIDIN) & OID;
2181 } else if ((ahc->features & AHC_ULTRA2) != 0)
2182 our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
2183 else
2184 our_id = ahc_inb(ahc, SCSIID) & OID;
2185
2186 saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
2187 ahc_compile_devinfo(devinfo,
2188 our_id,
2189 SCSIID_TARGET(ahc, saved_scsiid),
2190 ahc_inb(ahc, SAVED_LUN),
2191 SCSIID_CHANNEL(ahc, saved_scsiid),
2192 role);
2193}
2194
2195struct ahc_phase_table_entry*
2196ahc_lookup_phase_entry(int phase)
2197{
2198 struct ahc_phase_table_entry *entry;
2199 struct ahc_phase_table_entry *last_entry;
2200
2201
2202
2203
2204
2205 last_entry = &ahc_phase_table[num_phases];
2206 for (entry = ahc_phase_table; entry < last_entry; entry++) {
2207 if (phase == entry->phase)
2208 break;
2209 }
2210 return (entry);
2211}
2212
2213void
2214ahc_compile_devinfo(struct ahc_devinfo *devinfo, u_int our_id, u_int target,
2215 u_int lun, char channel, role_t role)
2216{
2217 devinfo->our_scsiid = our_id;
2218 devinfo->target = target;
2219 devinfo->lun = lun;
2220 devinfo->target_offset = target;
2221 devinfo->channel = channel;
2222 devinfo->role = role;
2223 if (channel == 'B')
2224 devinfo->target_offset += 8;
2225 devinfo->target_mask = (0x01 << devinfo->target_offset);
2226}
2227
2228void
2229ahc_print_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
2230{
2231 printf("%s:%c:%d:%d: ", ahc_name(ahc), devinfo->channel,
2232 devinfo->target, devinfo->lun);
2233}
2234
2235static void
2236ahc_scb_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2237 struct scb *scb)
2238{
2239 role_t role;
2240 int our_id;
2241
2242 our_id = SCSIID_OUR_ID(scb->hscb->scsiid);
2243 role = ROLE_INITIATOR;
2244 if ((scb->flags & SCB_TARGET_SCB) != 0)
2245 role = ROLE_TARGET;
2246 ahc_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahc, scb),
2247 SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahc, scb), role);
2248}
2249
2250
2251
2252static void
2253ahc_assert_atn(struct ahc_softc *ahc)
2254{
2255 u_int scsisigo;
2256
2257 scsisigo = ATNO;
2258 if ((ahc->features & AHC_DT) == 0)
2259 scsisigo |= ahc_inb(ahc, SCSISIGI);
2260 ahc_outb(ahc, SCSISIGO, scsisigo);
2261}
2262
2263
2264
2265
2266
2267
2268
2269static void
2270ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2271 struct scb *scb)
2272{
2273
2274
2275
2276
2277
2278 ahc->msgout_index = 0;
2279 ahc->msgout_len = 0;
2280
2281 if ((scb->flags & SCB_DEVICE_RESET) == 0
2282 && ahc_inb(ahc, MSG_OUT) == MSG_IDENTIFYFLAG) {
2283 u_int identify_msg;
2284
2285 identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb);
2286 if ((scb->hscb->control & DISCENB) != 0)
2287 identify_msg |= MSG_IDENTIFY_DISCFLAG;
2288 ahc->msgout_buf[ahc->msgout_index++] = identify_msg;
2289 ahc->msgout_len++;
2290
2291 if ((scb->hscb->control & TAG_ENB) != 0) {
2292 ahc->msgout_buf[ahc->msgout_index++] =
2293 scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE);
2294 ahc->msgout_buf[ahc->msgout_index++] = scb->hscb->tag;
2295 ahc->msgout_len += 2;
2296 }
2297 }
2298
2299 if (scb->flags & SCB_DEVICE_RESET) {
2300 ahc->msgout_buf[ahc->msgout_index++] = MSG_BUS_DEV_RESET;
2301 ahc->msgout_len++;
2302 ahc_print_path(ahc, scb);
2303 printf("Bus Device Reset Message Sent\n");
2304
2305
2306
2307
2308
2309
2310
2311 ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
2312 } else if ((scb->flags & SCB_ABORT) != 0) {
2313 if ((scb->hscb->control & TAG_ENB) != 0)
2314 ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT_TAG;
2315 else
2316 ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT;
2317 ahc->msgout_len++;
2318 ahc_print_path(ahc, scb);
2319 printf("Abort%s Message Sent\n",
2320 (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");
2321
2322
2323
2324
2325
2326
2327
2328 ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
2329 } else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) {
2330 ahc_build_transfer_msg(ahc, devinfo);
2331 } else {
2332 printf("ahc_intr: AWAITING_MSG for an SCB that "
2333 "does not have a waiting message\n");
2334 printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
2335 devinfo->target_mask);
2336 panic("SCB = %d, SCB Control = %x, MSG_OUT = %x "
2337 "SCB flags = %x", scb->hscb->tag, scb->hscb->control,
2338 ahc_inb(ahc, MSG_OUT), scb->flags);
2339 }
2340
2341
2342
2343
2344
2345 ahc_outb(ahc, SCB_CONTROL, ahc_inb(ahc, SCB_CONTROL) & ~MK_MESSAGE);
2346 scb->hscb->control &= ~MK_MESSAGE;
2347 ahc->msgout_index = 0;
2348 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
2349}
2350
2351
2352
2353
2354
2355static void
2356ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
2357{
2358
2359
2360
2361
2362
2363 struct ahc_initiator_tinfo *tinfo;
2364 struct ahc_tmode_tstate *tstate;
2365 struct ahc_syncrate *rate;
2366 int dowide;
2367 int dosync;
2368 int doppr;
2369 u_int period;
2370 u_int ppr_options;
2371 u_int offset;
2372
2373 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
2374 devinfo->target, &tstate);
2375
2376
2377
2378
2379
2380
2381 period = tinfo->goal.period;
2382 offset = tinfo->goal.offset;
2383 ppr_options = tinfo->goal.ppr_options;
2384
2385 if (devinfo->role == ROLE_TARGET)
2386 ppr_options = 0;
2387 rate = ahc_devlimited_syncrate(ahc, tinfo, &period,
2388 &ppr_options, devinfo->role);
2389 dowide = tinfo->curr.width != tinfo->goal.width;
2390 dosync = tinfo->curr.offset != offset || tinfo->curr.period != period;
2391
2392
2393
2394
2395
2396 doppr = ppr_options != 0;
2397
2398 if (!dowide && !dosync && !doppr) {
2399 dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;
2400 dosync = tinfo->goal.offset != 0;
2401 }
2402
2403 if (!dowide && !dosync && !doppr) {
2404
2405
2406
2407
2408 if ((ahc->features & AHC_WIDE) != 0)
2409 dowide = 1;
2410 else
2411 dosync = 1;
2412
2413 if (bootverbose) {
2414 ahc_print_devinfo(ahc, devinfo);
2415 printf("Ensuring async\n");
2416 }
2417 }
2418
2419
2420 if (devinfo->role == ROLE_TARGET)
2421 doppr = 0;
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431 if (doppr || (dosync && !dowide)) {
2432
2433 offset = tinfo->goal.offset;
2434 ahc_validate_offset(ahc, tinfo, rate, &offset,
2435 doppr ? tinfo->goal.width
2436 : tinfo->curr.width,
2437 devinfo->role);
2438 if (doppr) {
2439 ahc_construct_ppr(ahc, devinfo, period, offset,
2440 tinfo->goal.width, ppr_options);
2441 } else {
2442 ahc_construct_sdtr(ahc, devinfo, period, offset);
2443 }
2444 } else {
2445 ahc_construct_wdtr(ahc, devinfo, tinfo->goal.width);
2446 }
2447}
2448
2449
2450
2451
2452
2453static void
2454ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2455 u_int period, u_int offset)
2456{
2457 if (offset == 0)
2458 period = AHC_ASYNC_XFER_PERIOD;
2459 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
2460 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR_LEN;
2461 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR;
2462 ahc->msgout_buf[ahc->msgout_index++] = period;
2463 ahc->msgout_buf[ahc->msgout_index++] = offset;
2464 ahc->msgout_len += 5;
2465 if (bootverbose) {
2466 printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
2467 ahc_name(ahc), devinfo->channel, devinfo->target,
2468 devinfo->lun, period, offset);
2469 }
2470}
2471
2472
2473
2474
2475
2476static void
2477ahc_construct_wdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2478 u_int bus_width)
2479{
2480 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
2481 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR_LEN;
2482 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR;
2483 ahc->msgout_buf[ahc->msgout_index++] = bus_width;
2484 ahc->msgout_len += 4;
2485 if (bootverbose) {
2486 printf("(%s:%c:%d:%d): Sending WDTR %x\n",
2487 ahc_name(ahc), devinfo->channel, devinfo->target,
2488 devinfo->lun, bus_width);
2489 }
2490}
2491
2492
2493
2494
2495
2496static void
2497ahc_construct_ppr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2498 u_int period, u_int offset, u_int bus_width,
2499 u_int ppr_options)
2500{
2501 if (offset == 0)
2502 period = AHC_ASYNC_XFER_PERIOD;
2503 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
2504 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR_LEN;
2505 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR;
2506 ahc->msgout_buf[ahc->msgout_index++] = period;
2507 ahc->msgout_buf[ahc->msgout_index++] = 0;
2508 ahc->msgout_buf[ahc->msgout_index++] = offset;
2509 ahc->msgout_buf[ahc->msgout_index++] = bus_width;
2510 ahc->msgout_buf[ahc->msgout_index++] = ppr_options;
2511 ahc->msgout_len += 8;
2512 if (bootverbose) {
2513 printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
2514 "offset %x, ppr_options %x\n", ahc_name(ahc),
2515 devinfo->channel, devinfo->target, devinfo->lun,
2516 bus_width, period, offset, ppr_options);
2517 }
2518}
2519
2520
2521
2522
2523static void
2524ahc_clear_msg_state(struct ahc_softc *ahc)
2525{
2526 ahc->msgout_len = 0;
2527 ahc->msgin_index = 0;
2528 ahc->msg_type = MSG_TYPE_NONE;
2529 if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0) {
2530
2531
2532
2533
2534 ahc_outb(ahc, CLRSINT1, CLRATNO);
2535 }
2536 ahc_outb(ahc, MSG_OUT, MSG_NOOP);
2537 ahc_outb(ahc, SEQ_FLAGS2,
2538 ahc_inb(ahc, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
2539}
2540
2541static void
2542ahc_handle_proto_violation(struct ahc_softc *ahc)
2543{
2544 struct ahc_devinfo devinfo;
2545 struct scb *scb;
2546 u_int scbid;
2547 u_int seq_flags;
2548 u_int curphase;
2549 u_int lastphase;
2550 int found;
2551
2552 ahc_fetch_devinfo(ahc, &devinfo);
2553 scbid = ahc_inb(ahc, SCB_TAG);
2554 scb = ahc_lookup_scb(ahc, scbid);
2555 seq_flags = ahc_inb(ahc, SEQ_FLAGS);
2556 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
2557 lastphase = ahc_inb(ahc, LASTPHASE);
2558 if ((seq_flags & NOT_IDENTIFIED) != 0) {
2559
2560
2561
2562
2563
2564
2565 ahc_print_devinfo(ahc, &devinfo);
2566 printf("Target did not send an IDENTIFY message. "
2567 "LASTPHASE = 0x%x.\n", lastphase);
2568 scb = NULL;
2569 } else if (scb == NULL) {
2570
2571
2572
2573
2574 ahc_print_devinfo(ahc, &devinfo);
2575 printf("No SCB found during protocol violation\n");
2576 goto proto_violation_reset;
2577 } else {
2578 ahc_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
2579 if ((seq_flags & NO_CDB_SENT) != 0) {
2580 ahc_print_path(ahc, scb);
2581 printf("No or incomplete CDB sent to device.\n");
2582 } else if ((ahc_inb(ahc, SCB_CONTROL) & STATUS_RCVD) == 0) {
2583
2584
2585
2586
2587
2588
2589
2590 ahc_print_path(ahc, scb);
2591 printf("Completed command without status.\n");
2592 } else {
2593 ahc_print_path(ahc, scb);
2594 printf("Unknown protocol violation.\n");
2595 ahc_dump_card_state(ahc);
2596 }
2597 }
2598 if ((lastphase & ~P_DATAIN_DT) == 0
2599 || lastphase == P_COMMAND) {
2600proto_violation_reset:
2601
2602
2603
2604
2605
2606
2607 found = ahc_reset_channel(ahc, 'A', TRUE);
2608 printf("%s: Issued Channel %c Bus Reset. "
2609 "%d SCBs aborted\n", ahc_name(ahc), 'A', found);
2610 } else {
2611
2612
2613
2614
2615
2616 ahc_outb(ahc, SCSISEQ,
2617 ahc_inb(ahc, SCSISEQ) & ~ENSELO);
2618 ahc_assert_atn(ahc);
2619 ahc_outb(ahc, MSG_OUT, HOST_MSG);
2620 if (scb == NULL) {
2621 ahc_print_devinfo(ahc, &devinfo);
2622 ahc->msgout_buf[0] = MSG_ABORT_TASK;
2623 ahc->msgout_len = 1;
2624 ahc->msgout_index = 0;
2625 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
2626 } else {
2627 ahc_print_path(ahc, scb);
2628 scb->flags |= SCB_ABORT;
2629 }
2630 printf("Protocol violation %s. Attempting to abort.\n",
2631 ahc_lookup_phase_entry(curphase)->phasemsg);
2632 }
2633}
2634
2635
2636
2637
2638static void
2639ahc_handle_message_phase(struct ahc_softc *ahc)
2640{
2641 struct ahc_devinfo devinfo;
2642 u_int bus_phase;
2643 int end_session;
2644
2645 ahc_fetch_devinfo(ahc, &devinfo);
2646 end_session = FALSE;
2647 bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
2648
2649reswitch:
2650 switch (ahc->msg_type) {
2651 case MSG_TYPE_INITIATOR_MSGOUT:
2652 {
2653 int lastbyte;
2654 int phasemis;
2655 int msgdone;
2656
2657 if (ahc->msgout_len == 0)
2658 panic("HOST_MSG_LOOP interrupt with no active message");
2659
2660#ifdef AHC_DEBUG
2661 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2662 ahc_print_devinfo(ahc, &devinfo);
2663 printf("INITIATOR_MSG_OUT");
2664 }
2665#endif
2666 phasemis = bus_phase != P_MESGOUT;
2667 if (phasemis) {
2668#ifdef AHC_DEBUG
2669 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2670 printf(" PHASEMIS %s\n",
2671 ahc_lookup_phase_entry(bus_phase)
2672 ->phasemsg);
2673 }
2674#endif
2675 if (bus_phase == P_MESGIN) {
2676
2677
2678
2679
2680
2681
2682 ahc_outb(ahc, CLRSINT1, CLRATNO);
2683 ahc->send_msg_perror = FALSE;
2684 ahc->msg_type = MSG_TYPE_INITIATOR_MSGIN;
2685 ahc->msgin_index = 0;
2686 goto reswitch;
2687 }
2688 end_session = TRUE;
2689 break;
2690 }
2691
2692 if (ahc->send_msg_perror) {
2693 ahc_outb(ahc, CLRSINT1, CLRATNO);
2694 ahc_outb(ahc, CLRSINT1, CLRREQINIT);
2695#ifdef AHC_DEBUG
2696 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
2697 printf(" byte 0x%x\n", ahc->send_msg_perror);
2698#endif
2699 ahc_outb(ahc, SCSIDATL, MSG_PARITY_ERROR);
2700 break;
2701 }
2702
2703 msgdone = ahc->msgout_index == ahc->msgout_len;
2704 if (msgdone) {
2705
2706
2707
2708
2709
2710 ahc->msgout_index = 0;
2711 ahc_assert_atn(ahc);
2712 }
2713
2714 lastbyte = ahc->msgout_index == (ahc->msgout_len - 1);
2715 if (lastbyte) {
2716
2717 ahc_outb(ahc, CLRSINT1, CLRATNO);
2718 }
2719
2720
2721
2722
2723
2724 ahc_outb(ahc, CLRSINT1, CLRREQINIT);
2725#ifdef AHC_DEBUG
2726 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
2727 printf(" byte 0x%x\n",
2728 ahc->msgout_buf[ahc->msgout_index]);
2729#endif
2730 ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
2731 break;
2732 }
2733 case MSG_TYPE_INITIATOR_MSGIN:
2734 {
2735 int phasemis;
2736 int message_done;
2737
2738#ifdef AHC_DEBUG
2739 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2740 ahc_print_devinfo(ahc, &devinfo);
2741 printf("INITIATOR_MSG_IN");
2742 }
2743#endif
2744 phasemis = bus_phase != P_MESGIN;
2745 if (phasemis) {
2746#ifdef AHC_DEBUG
2747 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2748 printf(" PHASEMIS %s\n",
2749 ahc_lookup_phase_entry(bus_phase)
2750 ->phasemsg);
2751 }
2752#endif
2753 ahc->msgin_index = 0;
2754 if (bus_phase == P_MESGOUT
2755 && (ahc->send_msg_perror == TRUE
2756 || (ahc->msgout_len != 0
2757 && ahc->msgout_index == 0))) {
2758 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
2759 goto reswitch;
2760 }
2761 end_session = TRUE;
2762 break;
2763 }
2764
2765
2766 ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIBUSL);
2767#ifdef AHC_DEBUG
2768 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
2769 printf(" byte 0x%x\n",
2770 ahc->msgin_buf[ahc->msgin_index]);
2771#endif
2772
2773 message_done = ahc_parse_msg(ahc, &devinfo);
2774
2775 if (message_done) {
2776
2777
2778
2779
2780 ahc->msgin_index = 0;
2781
2782
2783
2784
2785
2786
2787 if (ahc->msgout_len != 0) {
2788#ifdef AHC_DEBUG
2789 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2790 ahc_print_devinfo(ahc, &devinfo);
2791 printf("Asserting ATN for response\n");
2792 }
2793#endif
2794 ahc_assert_atn(ahc);
2795 }
2796 } else
2797 ahc->msgin_index++;
2798
2799 if (message_done == MSGLOOP_TERMINATED) {
2800 end_session = TRUE;
2801 } else {
2802
2803 ahc_outb(ahc, CLRSINT1, CLRREQINIT);
2804 ahc_inb(ahc, SCSIDATL);
2805 }
2806 break;
2807 }
2808 case MSG_TYPE_TARGET_MSGIN:
2809 {
2810 int msgdone;
2811 int msgout_request;
2812
2813 if (ahc->msgout_len == 0)
2814 panic("Target MSGIN with no active message");
2815
2816
2817
2818
2819
2820
2821
2822 if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0
2823 && ahc->msgout_index > 0)
2824 msgout_request = TRUE;
2825 else
2826 msgout_request = FALSE;
2827
2828 if (msgout_request) {
2829
2830
2831
2832
2833
2834
2835
2836 ahc->msg_type = MSG_TYPE_TARGET_MSGOUT;
2837 ahc_outb(ahc, SCSISIGO, P_MESGOUT | BSYO);
2838 ahc->msgin_index = 0;
2839
2840 ahc_inb(ahc, SCSIDATL);
2841 ahc_outb(ahc, SXFRCTL0,
2842 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
2843 break;
2844 }
2845
2846 msgdone = ahc->msgout_index == ahc->msgout_len;
2847 if (msgdone) {
2848 ahc_outb(ahc, SXFRCTL0,
2849 ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
2850 end_session = TRUE;
2851 break;
2852 }
2853
2854
2855
2856
2857 ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) | SPIOEN);
2858 ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
2859 break;
2860 }
2861 case MSG_TYPE_TARGET_MSGOUT:
2862 {
2863 int lastbyte;
2864 int msgdone;
2865
2866
2867
2868
2869
2870 lastbyte = (ahc_inb(ahc, SCSISIGI) & ATNI) == 0;
2871
2872
2873
2874
2875
2876
2877 ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
2878 ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIDATL);
2879 msgdone = ahc_parse_msg(ahc, &devinfo);
2880 if (msgdone == MSGLOOP_TERMINATED) {
2881
2882
2883
2884
2885
2886
2887 return;
2888 }
2889
2890 ahc->msgin_index++;
2891
2892
2893
2894
2895
2896 if (msgdone == MSGLOOP_MSGCOMPLETE) {
2897 ahc->msgin_index = 0;
2898
2899
2900
2901
2902
2903 if (ahc->msgout_len != 0) {
2904 ahc_outb(ahc, SCSISIGO, P_MESGIN | BSYO);
2905 ahc_outb(ahc, SXFRCTL0,
2906 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
2907 ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
2908 ahc->msgin_index = 0;
2909 break;
2910 }
2911 }
2912
2913 if (lastbyte)
2914 end_session = TRUE;
2915 else {
2916
2917 ahc_outb(ahc, SXFRCTL0,
2918 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
2919 }
2920
2921 break;
2922 }
2923 default:
2924 panic("Unknown REQINIT message type");
2925 }
2926
2927 if (end_session) {
2928 ahc_clear_msg_state(ahc);
2929 ahc_outb(ahc, RETURN_1, EXIT_MSG_LOOP);
2930 } else
2931 ahc_outb(ahc, RETURN_1, CONT_MSG_LOOP);
2932}
2933
2934
2935
2936
2937
2938
2939
2940static int
2941ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type, u_int msgval, int full)
2942{
2943 int found;
2944 u_int index;
2945
2946 found = FALSE;
2947 index = 0;
2948
2949 while (index < ahc->msgout_len) {
2950 if (ahc->msgout_buf[index] == MSG_EXTENDED) {
2951 u_int end_index;
2952
2953 end_index = index + 1 + ahc->msgout_buf[index + 1];
2954 if (ahc->msgout_buf[index+2] == msgval
2955 && type == AHCMSG_EXT) {
2956
2957 if (full) {
2958 if (ahc->msgout_index > end_index)
2959 found = TRUE;
2960 } else if (ahc->msgout_index > index)
2961 found = TRUE;
2962 }
2963 index = end_index;
2964 } else if (ahc->msgout_buf[index] >= MSG_SIMPLE_TASK
2965 && ahc->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
2966
2967
2968 index += 2;
2969 } else {
2970
2971 if (type == AHCMSG_1B
2972 && ahc->msgout_buf[index] == msgval
2973 && ahc->msgout_index > index)
2974 found = TRUE;
2975 index++;
2976 }
2977
2978 if (found)
2979 break;
2980 }
2981 return (found);
2982}
2983
2984
2985
2986
2987static int
2988ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
2989{
2990 struct ahc_initiator_tinfo *tinfo;
2991 struct ahc_tmode_tstate *tstate;
2992 int reject;
2993 int done;
2994 int response;
2995 u_int targ_scsirate;
2996
2997 done = MSGLOOP_IN_PROG;
2998 response = FALSE;
2999 reject = FALSE;
3000 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
3001 devinfo->target, &tstate);
3002 targ_scsirate = tinfo->scsirate;
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015 switch (ahc->msgin_buf[0]) {
3016 case MSG_DISCONNECT:
3017 case MSG_SAVEDATAPOINTER:
3018 case MSG_CMDCOMPLETE:
3019 case MSG_RESTOREPOINTERS:
3020 case MSG_IGN_WIDE_RESIDUE:
3021
3022
3023
3024
3025 done = MSGLOOP_TERMINATED;
3026 break;
3027 case MSG_MESSAGE_REJECT:
3028 response = ahc_handle_msg_reject(ahc, devinfo);
3029
3030 case MSG_NOOP:
3031 done = MSGLOOP_MSGCOMPLETE;
3032 break;
3033 case MSG_EXTENDED:
3034 {
3035
3036 if (ahc->msgin_index < 2)
3037 break;
3038 switch (ahc->msgin_buf[2]) {
3039 case MSG_EXT_SDTR:
3040 {
3041 struct ahc_syncrate *syncrate;
3042 u_int period;
3043 u_int ppr_options;
3044 u_int offset;
3045 u_int saved_offset;
3046
3047 if (ahc->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
3048 reject = TRUE;
3049 break;
3050 }
3051
3052
3053
3054
3055
3056
3057
3058
3059 if (ahc->msgin_index < (MSG_EXT_SDTR_LEN + 1))
3060 break;
3061
3062 period = ahc->msgin_buf[3];
3063 ppr_options = 0;
3064 saved_offset = offset = ahc->msgin_buf[4];
3065 syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,
3066 &ppr_options,
3067 devinfo->role);
3068 ahc_validate_offset(ahc, tinfo, syncrate, &offset,
3069 targ_scsirate & WIDEXFER,
3070 devinfo->role);
3071 if (bootverbose) {
3072 printf("(%s:%c:%d:%d): Received "
3073 "SDTR period %x, offset %x\n\t"
3074 "Filtered to period %x, offset %x\n",
3075 ahc_name(ahc), devinfo->channel,
3076 devinfo->target, devinfo->lun,
3077 ahc->msgin_buf[3], saved_offset,
3078 period, offset);
3079 }
3080 ahc_set_syncrate(ahc, devinfo,
3081 syncrate, period,
3082 offset, ppr_options,
3083 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3084 TRUE);
3085
3086
3087
3088
3089
3090
3091 if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_SDTR, TRUE)) {
3092
3093 if (saved_offset != offset) {
3094
3095 reject = TRUE;
3096 }
3097 } else {
3098
3099
3100
3101 if (bootverbose
3102 && devinfo->role == ROLE_INITIATOR) {
3103 printf("(%s:%c:%d:%d): Target "
3104 "Initiated SDTR\n",
3105 ahc_name(ahc), devinfo->channel,
3106 devinfo->target, devinfo->lun);
3107 }
3108 ahc->msgout_index = 0;
3109 ahc->msgout_len = 0;
3110 ahc_construct_sdtr(ahc, devinfo,
3111 period, offset);
3112 ahc->msgout_index = 0;
3113 response = TRUE;
3114 }
3115 done = MSGLOOP_MSGCOMPLETE;
3116 break;
3117 }
3118 case MSG_EXT_WDTR:
3119 {
3120 u_int bus_width;
3121 u_int saved_width;
3122 u_int sending_reply;
3123
3124 sending_reply = FALSE;
3125 if (ahc->msgin_buf[1] != MSG_EXT_WDTR_LEN) {
3126 reject = TRUE;
3127 break;
3128 }
3129
3130
3131
3132
3133
3134
3135
3136
3137 if (ahc->msgin_index < (MSG_EXT_WDTR_LEN + 1))
3138 break;
3139
3140 bus_width = ahc->msgin_buf[3];
3141 saved_width = bus_width;
3142 ahc_validate_width(ahc, tinfo, &bus_width,
3143 devinfo->role);
3144 if (bootverbose) {
3145 printf("(%s:%c:%d:%d): Received WDTR "
3146 "%x filtered to %x\n",
3147 ahc_name(ahc), devinfo->channel,
3148 devinfo->target, devinfo->lun,
3149 saved_width, bus_width);
3150 }
3151
3152 if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, TRUE)) {
3153
3154
3155
3156
3157
3158
3159 if (saved_width > bus_width) {
3160 reject = TRUE;
3161 printf("(%s:%c:%d:%d): requested %dBit "
3162 "transfers. Rejecting...\n",
3163 ahc_name(ahc), devinfo->channel,
3164 devinfo->target, devinfo->lun,
3165 8 * (0x01 << bus_width));
3166 bus_width = 0;
3167 }
3168 } else {
3169
3170
3171
3172 if (bootverbose
3173 && devinfo->role == ROLE_INITIATOR) {
3174 printf("(%s:%c:%d:%d): Target "
3175 "Initiated WDTR\n",
3176 ahc_name(ahc), devinfo->channel,
3177 devinfo->target, devinfo->lun);
3178 }
3179 ahc->msgout_index = 0;
3180 ahc->msgout_len = 0;
3181 ahc_construct_wdtr(ahc, devinfo, bus_width);
3182 ahc->msgout_index = 0;
3183 response = TRUE;
3184 sending_reply = TRUE;
3185 }
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195 ahc_update_neg_request(ahc, devinfo, tstate,
3196 tinfo, AHC_NEG_ALWAYS);
3197 ahc_set_width(ahc, devinfo, bus_width,
3198 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3199 TRUE);
3200 if (sending_reply == FALSE && reject == FALSE) {
3201
3202
3203
3204
3205 ahc->msgout_index = 0;
3206 ahc->msgout_len = 0;
3207 ahc_build_transfer_msg(ahc, devinfo);
3208 ahc->msgout_index = 0;
3209 response = TRUE;
3210 }
3211 done = MSGLOOP_MSGCOMPLETE;
3212 break;
3213 }
3214 case MSG_EXT_PPR:
3215 {
3216 struct ahc_syncrate *syncrate;
3217 u_int period;
3218 u_int offset;
3219 u_int bus_width;
3220 u_int ppr_options;
3221 u_int saved_width;
3222 u_int saved_offset;
3223 u_int saved_ppr_options;
3224
3225 if (ahc->msgin_buf[1] != MSG_EXT_PPR_LEN) {
3226 reject = TRUE;
3227 break;
3228 }
3229
3230
3231
3232
3233
3234
3235
3236
3237 if (ahc->msgin_index < (MSG_EXT_PPR_LEN + 1))
3238 break;
3239
3240 period = ahc->msgin_buf[3];
3241 offset = ahc->msgin_buf[5];
3242 bus_width = ahc->msgin_buf[6];
3243 saved_width = bus_width;
3244 ppr_options = ahc->msgin_buf[7];
3245
3246
3247
3248
3249
3250 if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 0
3251 && period == 9)
3252 offset = 0;
3253 saved_ppr_options = ppr_options;
3254 saved_offset = offset;
3255
3256
3257
3258
3259
3260
3261 ppr_options &= MSG_EXT_PPR_DT_REQ;
3262 if (bus_width == 0)
3263 ppr_options = 0;
3264
3265 ahc_validate_width(ahc, tinfo, &bus_width,
3266 devinfo->role);
3267 syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,
3268 &ppr_options,
3269 devinfo->role);
3270 ahc_validate_offset(ahc, tinfo, syncrate,
3271 &offset, bus_width,
3272 devinfo->role);
3273
3274 if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_PPR, TRUE)) {
3275
3276
3277
3278
3279
3280 if (saved_width > bus_width
3281 || saved_offset != offset
3282 || saved_ppr_options != ppr_options) {
3283 reject = TRUE;
3284 period = 0;
3285 offset = 0;
3286 bus_width = 0;
3287 ppr_options = 0;
3288 syncrate = NULL;
3289 }
3290 } else {
3291 if (devinfo->role != ROLE_TARGET)
3292 printf("(%s:%c:%d:%d): Target "
3293 "Initiated PPR\n",
3294 ahc_name(ahc), devinfo->channel,
3295 devinfo->target, devinfo->lun);
3296 else
3297 printf("(%s:%c:%d:%d): Initiator "
3298 "Initiated PPR\n",
3299 ahc_name(ahc), devinfo->channel,
3300 devinfo->target, devinfo->lun);
3301 ahc->msgout_index = 0;
3302 ahc->msgout_len = 0;
3303 ahc_construct_ppr(ahc, devinfo, period, offset,
3304 bus_width, ppr_options);
3305 ahc->msgout_index = 0;
3306 response = TRUE;
3307 }
3308 if (bootverbose) {
3309 printf("(%s:%c:%d:%d): Received PPR width %x, "
3310 "period %x, offset %x,options %x\n"
3311 "\tFiltered to width %x, period %x, "
3312 "offset %x, options %x\n",
3313 ahc_name(ahc), devinfo->channel,
3314 devinfo->target, devinfo->lun,
3315 saved_width, ahc->msgin_buf[3],
3316 saved_offset, saved_ppr_options,
3317 bus_width, period, offset, ppr_options);
3318 }
3319 ahc_set_width(ahc, devinfo, bus_width,
3320 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3321 TRUE);
3322 ahc_set_syncrate(ahc, devinfo,
3323 syncrate, period,
3324 offset, ppr_options,
3325 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3326 TRUE);
3327 done = MSGLOOP_MSGCOMPLETE;
3328 break;
3329 }
3330 default:
3331
3332 reject = TRUE;
3333 break;
3334 }
3335 break;
3336 }
3337#ifdef AHC_TARGET_MODE
3338 case MSG_BUS_DEV_RESET:
3339 ahc_handle_devreset(ahc, devinfo,
3340 CAM_BDR_SENT,
3341 "Bus Device Reset Received",
3342 0);
3343 ahc_restart(ahc);
3344 done = MSGLOOP_TERMINATED;
3345 break;
3346 case MSG_ABORT_TAG:
3347 case MSG_ABORT:
3348 case MSG_CLEAR_QUEUE:
3349 {
3350 int tag;
3351
3352
3353 if (devinfo->role != ROLE_TARGET) {
3354 reject = TRUE;
3355 break;
3356 }
3357 tag = SCB_LIST_NULL;
3358 if (ahc->msgin_buf[0] == MSG_ABORT_TAG)
3359 tag = ahc_inb(ahc, INITIATOR_TAG);
3360 ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
3361 devinfo->lun, tag, ROLE_TARGET,
3362 CAM_REQ_ABORTED);
3363
3364 tstate = ahc->enabled_targets[devinfo->our_scsiid];
3365 if (tstate != NULL) {
3366 struct ahc_tmode_lstate* lstate;
3367
3368 lstate = tstate->enabled_luns[devinfo->lun];
3369 if (lstate != NULL) {
3370 ahc_queue_lstate_event(ahc, lstate,
3371 devinfo->our_scsiid,
3372 ahc->msgin_buf[0],
3373 tag);
3374 ahc_send_lstate_events(ahc, lstate);
3375 }
3376 }
3377 ahc_restart(ahc);
3378 done = MSGLOOP_TERMINATED;
3379 break;
3380 }
3381#endif
3382 case MSG_TERM_IO_PROC:
3383 default:
3384 reject = TRUE;
3385 break;
3386 }
3387
3388 if (reject) {
3389
3390
3391
3392 ahc->msgout_index = 0;
3393 ahc->msgout_len = 1;
3394 ahc->msgout_buf[0] = MSG_MESSAGE_REJECT;
3395 done = MSGLOOP_MSGCOMPLETE;
3396 response = TRUE;
3397 }
3398
3399 if (done != MSGLOOP_IN_PROG && !response)
3400
3401 ahc->msgout_len = 0;
3402
3403 return (done);
3404}
3405
3406
3407
3408
3409static int
3410ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
3411{
3412
3413
3414
3415
3416
3417
3418 struct scb *scb;
3419 struct ahc_initiator_tinfo *tinfo;
3420 struct ahc_tmode_tstate *tstate;
3421 u_int scb_index;
3422 u_int last_msg;
3423 int response = 0;
3424
3425 scb_index = ahc_inb(ahc, SCB_TAG);
3426 scb = ahc_lookup_scb(ahc, scb_index);
3427 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,
3428 devinfo->our_scsiid,
3429 devinfo->target, &tstate);
3430
3431 last_msg = ahc_inb(ahc, LAST_MSG);
3432
3433 if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_PPR, FALSE)) {
3434
3435
3436
3437
3438 if (bootverbose) {
3439 printf("(%s:%c:%d:%d): PPR Rejected. "
3440 "Trying WDTR/SDTR\n",
3441 ahc_name(ahc), devinfo->channel,
3442 devinfo->target, devinfo->lun);
3443 }
3444 tinfo->goal.ppr_options = 0;
3445 tinfo->curr.transport_version = 2;
3446 tinfo->goal.transport_version = 2;
3447 ahc->msgout_index = 0;
3448 ahc->msgout_len = 0;
3449 ahc_build_transfer_msg(ahc, devinfo);
3450 ahc->msgout_index = 0;
3451 response = 1;
3452 } else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, FALSE)) {
3453
3454
3455 printf("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
3456 "8bit transfers\n", ahc_name(ahc),
3457 devinfo->channel, devinfo->target, devinfo->lun);
3458 ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
3459 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3460 TRUE);
3461
3462
3463
3464
3465
3466
3467
3468 if (tinfo->goal.offset != tinfo->curr.offset) {
3469
3470
3471 ahc->msgout_index = 0;
3472 ahc->msgout_len = 0;
3473 ahc_build_transfer_msg(ahc, devinfo);
3474 ahc->msgout_index = 0;
3475 response = 1;
3476 }
3477 } else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_SDTR, FALSE)) {
3478
3479 ahc_set_syncrate(ahc, devinfo, NULL, 0,
3480 0, 0,
3481 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3482 TRUE);
3483 printf("(%s:%c:%d:%d): refuses synchronous negotiation. "
3484 "Using asynchronous transfers\n",
3485 ahc_name(ahc), devinfo->channel,
3486 devinfo->target, devinfo->lun);
3487 } else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) {
3488 int tag_type;
3489 int mask;
3490
3491 tag_type = (scb->hscb->control & MSG_SIMPLE_TASK);
3492
3493 if (tag_type == MSG_SIMPLE_TASK) {
3494 printf("(%s:%c:%d:%d): refuses tagged commands. "
3495 "Performing non-tagged I/O\n", ahc_name(ahc),
3496 devinfo->channel, devinfo->target, devinfo->lun);
3497 ahc_set_tags(ahc, devinfo, AHC_QUEUE_NONE);
3498 mask = ~0x23;
3499 } else {
3500 printf("(%s:%c:%d:%d): refuses %s tagged commands. "
3501 "Performing simple queue tagged I/O only\n",
3502 ahc_name(ahc), devinfo->channel, devinfo->target,
3503 devinfo->lun, tag_type == MSG_ORDERED_TASK
3504 ? "ordered" : "head of queue");
3505 ahc_set_tags(ahc, devinfo, AHC_QUEUE_BASIC);
3506 mask = ~0x03;
3507 }
3508
3509
3510
3511
3512
3513 ahc_outb(ahc, SCB_CONTROL,
3514 ahc_inb(ahc, SCB_CONTROL) & mask);
3515 scb->hscb->control &= mask;
3516 ahc_set_transaction_tag(scb, FALSE,
3517 MSG_SIMPLE_TASK);
3518 ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);
3519 ahc_assert_atn(ahc);
3520
3521
3522
3523
3524
3525 if ((ahc->flags & AHC_SCB_BTT) == 0) {
3526 struct scb_tailq *untagged_q;
3527
3528 untagged_q =
3529 &(ahc->untagged_queues[devinfo->target_offset]);
3530 TAILQ_INSERT_HEAD(untagged_q, scb, links.tqe);
3531 scb->flags |= SCB_UNTAGGEDQ;
3532 }
3533 ahc_busy_tcl(ahc, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
3534 scb->hscb->tag);
3535
3536
3537
3538
3539
3540
3541 ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
3542 SCB_GET_CHANNEL(ahc, scb),
3543 SCB_GET_LUN(scb), SCB_LIST_NULL,
3544 ROLE_INITIATOR, CAM_REQUEUE_REQ,
3545 SEARCH_COMPLETE);
3546 } else {
3547
3548
3549
3550 printf("%s:%c:%d: Message reject for %x -- ignored\n",
3551 ahc_name(ahc), devinfo->channel, devinfo->target,
3552 last_msg);
3553 }
3554 return (response);
3555}
3556
3557
3558
3559
3560static void
3561ahc_handle_ign_wide_residue(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
3562{
3563 u_int scb_index;
3564 struct scb *scb;
3565
3566 scb_index = ahc_inb(ahc, SCB_TAG);
3567 scb = ahc_lookup_scb(ahc, scb_index);
3568
3569
3570
3571
3572 if ((ahc_inb(ahc, SEQ_FLAGS) & DPHASE) == 0
3573 || ahc_get_transfer_dir(scb) != CAM_DIR_IN) {
3574
3575
3576
3577
3578 } else {
3579
3580
3581
3582
3583
3584
3585
3586 uint32_t sgptr;
3587
3588 sgptr = ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
3589 if ((sgptr & SG_LIST_NULL) != 0
3590 && (ahc_inb(ahc, SCB_LUN) & SCB_XFERLEN_ODD) != 0) {
3591
3592
3593
3594
3595
3596
3597 } else {
3598 struct ahc_dma_seg *sg;
3599 uint32_t data_cnt;
3600 uint32_t data_addr;
3601 uint32_t sglen;
3602
3603
3604 sgptr = ahc_inl(ahc, SCB_RESIDUAL_SGPTR);
3605 data_cnt = ahc_inl(ahc, SCB_RESIDUAL_DATACNT);
3606
3607 if ((sgptr & SG_LIST_NULL) != 0) {
3608
3609
3610
3611
3612
3613 data_cnt &= ~AHC_SG_LEN_MASK;
3614 }
3615
3616 data_addr = ahc_inl(ahc, SHADDR);
3617
3618 data_cnt += 1;
3619 data_addr -= 1;
3620 sgptr &= SG_PTR_MASK;
3621
3622 sg = ahc_sg_bus_to_virt(scb, sgptr);
3623
3624
3625
3626
3627
3628 sg--;
3629 sglen = ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;
3630 if (sg != scb->sg_list
3631 && sglen < (data_cnt & AHC_SG_LEN_MASK)) {
3632
3633 sg--;
3634 sglen = ahc_le32toh(sg->len);
3635
3636
3637
3638
3639 data_cnt = 1 | (sglen & (~AHC_SG_LEN_MASK));
3640 data_addr = ahc_le32toh(sg->addr)
3641 + (sglen & AHC_SG_LEN_MASK) - 1;
3642
3643
3644
3645
3646
3647 sg++;
3648 sgptr = ahc_sg_virt_to_bus(scb, sg);
3649 }
3650 ahc_outl(ahc, SCB_RESIDUAL_SGPTR, sgptr);
3651 ahc_outl(ahc, SCB_RESIDUAL_DATACNT, data_cnt);
3652
3653
3654
3655
3656
3657
3658 ahc_outb(ahc, SCB_LUN,
3659 ahc_inb(ahc, SCB_LUN) ^ SCB_XFERLEN_ODD);
3660 }
3661 }
3662}
3663
3664
3665
3666
3667
3668
3669static void
3670ahc_reinitialize_dataptrs(struct ahc_softc *ahc)
3671{
3672 struct scb *scb;
3673 struct ahc_dma_seg *sg;
3674 u_int scb_index;
3675 uint32_t sgptr;
3676 uint32_t resid;
3677 uint32_t dataptr;
3678
3679 scb_index = ahc_inb(ahc, SCB_TAG);
3680 scb = ahc_lookup_scb(ahc, scb_index);
3681 sgptr = (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 3) << 24)
3682 | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 2) << 16)
3683 | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 1) << 8)
3684 | ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
3685
3686 sgptr &= SG_PTR_MASK;
3687 sg = ahc_sg_bus_to_virt(scb, sgptr);
3688
3689
3690 sg--;
3691
3692 resid = (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 2) << 16)
3693 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 1) << 8)
3694 | ahc_inb(ahc, SCB_RESIDUAL_DATACNT);
3695
3696 dataptr = ahc_le32toh(sg->addr)
3697 + (ahc_le32toh(sg->len) & AHC_SG_LEN_MASK)
3698 - resid;
3699 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
3700 u_int dscommand1;
3701
3702 dscommand1 = ahc_inb(ahc, DSCOMMAND1);
3703 ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
3704 ahc_outb(ahc, HADDR,
3705 (ahc_le32toh(sg->len) >> 24) & SG_HIGH_ADDR_BITS);
3706 ahc_outb(ahc, DSCOMMAND1, dscommand1);
3707 }
3708 ahc_outb(ahc, HADDR + 3, dataptr >> 24);
3709 ahc_outb(ahc, HADDR + 2, dataptr >> 16);
3710 ahc_outb(ahc, HADDR + 1, dataptr >> 8);
3711 ahc_outb(ahc, HADDR, dataptr);
3712 ahc_outb(ahc, HCNT + 2, resid >> 16);
3713 ahc_outb(ahc, HCNT + 1, resid >> 8);
3714 ahc_outb(ahc, HCNT, resid);
3715 if ((ahc->features & AHC_ULTRA2) == 0) {
3716 ahc_outb(ahc, STCNT + 2, resid >> 16);
3717 ahc_outb(ahc, STCNT + 1, resid >> 8);
3718 ahc_outb(ahc, STCNT, resid);
3719 }
3720}
3721
3722
3723
3724
3725static void
3726ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
3727 cam_status status, char *message, int verbose_level)
3728{
3729#ifdef AHC_TARGET_MODE
3730 struct ahc_tmode_tstate* tstate;
3731 u_int lun;
3732#endif
3733 int found;
3734
3735 found = ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
3736 CAM_LUN_WILDCARD, SCB_LIST_NULL, devinfo->role,
3737 status);
3738
3739#ifdef AHC_TARGET_MODE
3740
3741
3742
3743
3744 tstate = ahc->enabled_targets[devinfo->our_scsiid];
3745 if (tstate != NULL) {
3746 for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
3747 struct ahc_tmode_lstate* lstate;
3748
3749 lstate = tstate->enabled_luns[lun];
3750 if (lstate == NULL)
3751 continue;
3752
3753 ahc_queue_lstate_event(ahc, lstate, devinfo->our_scsiid,
3754 MSG_BUS_DEV_RESET, 0);
3755 ahc_send_lstate_events(ahc, lstate);
3756 }
3757 }
3758#endif
3759
3760
3761
3762
3763 ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
3764 AHC_TRANS_CUR, TRUE);
3765 ahc_set_syncrate(ahc, devinfo, NULL,
3766 0, 0, 0,
3767 AHC_TRANS_CUR, TRUE);
3768
3769 ahc_send_async(ahc, devinfo->channel, devinfo->target,
3770 CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
3771
3772 if (message != NULL
3773 && (verbose_level <= bootverbose))
3774 printf("%s: %s on %c:%d. %d SCBs aborted\n", ahc_name(ahc),
3775 message, devinfo->channel, devinfo->target, found);
3776}
3777
3778#ifdef AHC_TARGET_MODE
3779static void
3780ahc_setup_target_msgin(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
3781 struct scb *scb)
3782{
3783
3784
3785
3786
3787
3788
3789 ahc->msgout_index = 0;
3790 ahc->msgout_len = 0;
3791
3792 if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0)
3793 ahc_build_transfer_msg(ahc, devinfo);
3794 else
3795 panic("ahc_intr: AWAITING target message with no message");
3796
3797 ahc->msgout_index = 0;
3798 ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
3799}
3800#endif
3801
3802
3803
3804
3805
3806struct ahc_softc *
3807ahc_alloc(void *platform_arg, char *name)
3808{
3809 struct ahc_softc *ahc;
3810 int i;
3811
3812#ifndef __FreeBSD__
3813 ahc = malloc(sizeof(*ahc), M_DEVBUF, M_NOWAIT);
3814 if (!ahc) {
3815 printf("aic7xxx: cannot malloc softc!\n");
3816 free(name, M_DEVBUF);
3817 return NULL;
3818 }
3819#else
3820 ahc = device_get_softc((device_t)platform_arg);
3821#endif
3822 memset(ahc, 0, sizeof(*ahc));
3823 ahc->seep_config = malloc(sizeof(*ahc->seep_config),
3824 M_DEVBUF, M_NOWAIT);
3825 if (ahc->seep_config == NULL) {
3826#ifndef __FreeBSD__
3827 free(ahc, M_DEVBUF);
3828#endif
3829 free(name, M_DEVBUF);
3830 return (NULL);
3831 }
3832 LIST_INIT(&ahc->pending_scbs);
3833
3834 ahc->name = name;
3835 ahc->unit = -1;
3836 ahc->description = NULL;
3837 ahc->channel = 'A';
3838 ahc->channel_b = 'B';
3839 ahc->chip = AHC_NONE;
3840 ahc->features = AHC_FENONE;
3841 ahc->bugs = AHC_BUGNONE;
3842 ahc->flags = AHC_FNONE;
3843
3844
3845
3846
3847
3848 ahc->seqctl = FASTMODE;
3849
3850 for (i = 0; i < AHC_NUM_TARGETS; i++)
3851 TAILQ_INIT(&ahc->untagged_queues[i]);
3852 if (ahc_platform_alloc(ahc, platform_arg) != 0) {
3853 ahc_free(ahc);
3854 ahc = NULL;
3855 }
3856 return (ahc);
3857}
3858
3859int
3860ahc_softc_init(struct ahc_softc *ahc)
3861{
3862
3863
3864 if ((ahc->chip & AHC_PCI) == 0)
3865 ahc->unpause = ahc_inb(ahc, HCNTRL) & IRQMS;
3866 else
3867 ahc->unpause = 0;
3868 ahc->pause = ahc->unpause | PAUSE;
3869
3870 if (ahc->scb_data == NULL) {
3871 ahc->scb_data = malloc(sizeof(*ahc->scb_data),
3872 M_DEVBUF, M_NOWAIT);
3873 if (ahc->scb_data == NULL)
3874 return (ENOMEM);
3875 memset(ahc->scb_data, 0, sizeof(*ahc->scb_data));
3876 }
3877
3878 return (0);
3879}
3880
3881void
3882ahc_softc_insert(struct ahc_softc *ahc)
3883{
3884 struct ahc_softc *list_ahc;
3885
3886#if AHC_PCI_CONFIG > 0
3887
3888
3889
3890
3891 if ((ahc->chip & AHC_BUS_MASK) == AHC_PCI
3892 && (ahc->features & AHC_MULTI_FUNC) != 0) {
3893 TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
3894 ahc_dev_softc_t list_pci;
3895 ahc_dev_softc_t pci;
3896
3897 list_pci = list_ahc->dev_softc;
3898 pci = ahc->dev_softc;
3899 if (ahc_get_pci_slot(list_pci) == ahc_get_pci_slot(pci)
3900 && ahc_get_pci_bus(list_pci) == ahc_get_pci_bus(pci)) {
3901 struct ahc_softc *master;
3902 struct ahc_softc *slave;
3903
3904 if (ahc_get_pci_function(list_pci) == 0) {
3905 master = list_ahc;
3906 slave = ahc;
3907 } else {
3908 master = ahc;
3909 slave = list_ahc;
3910 }
3911 slave->flags &= ~AHC_BIOS_ENABLED;
3912 slave->flags |=
3913 master->flags & AHC_BIOS_ENABLED;
3914 slave->flags &= ~AHC_PRIMARY_CHANNEL;
3915 slave->flags |=
3916 master->flags & AHC_PRIMARY_CHANNEL;
3917 break;
3918 }
3919 }
3920 }
3921#endif
3922
3923
3924
3925
3926 list_ahc = TAILQ_FIRST(&ahc_tailq);
3927 while (list_ahc != NULL
3928 && ahc_softc_comp(ahc, list_ahc) <= 0)
3929 list_ahc = TAILQ_NEXT(list_ahc, links);
3930 if (list_ahc != NULL)
3931 TAILQ_INSERT_BEFORE(list_ahc, ahc, links);
3932 else
3933 TAILQ_INSERT_TAIL(&ahc_tailq, ahc, links);
3934 ahc->init_level++;
3935}
3936
3937
3938
3939
3940
3941struct ahc_softc *
3942ahc_find_softc(struct ahc_softc *ahc)
3943{
3944 struct ahc_softc *list_ahc;
3945
3946 TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
3947 if (list_ahc == ahc)
3948 return (ahc);
3949 }
3950 return (NULL);
3951}
3952
3953void
3954ahc_set_unit(struct ahc_softc *ahc, int unit)
3955{
3956 ahc->unit = unit;
3957}
3958
3959void
3960ahc_set_name(struct ahc_softc *ahc, char *name)
3961{
3962 if (ahc->name != NULL)
3963 free(ahc->name, M_DEVBUF);
3964 ahc->name = name;
3965}
3966
3967void
3968ahc_free(struct ahc_softc *ahc)
3969{
3970 int i;
3971
3972 switch (ahc->init_level) {
3973 default:
3974 case 5:
3975 ahc_shutdown(ahc);
3976
3977 case 4:
3978 ahc_dmamap_unload(ahc, ahc->shared_data_dmat,
3979 ahc->shared_data_dmamap);
3980
3981 case 3:
3982 ahc_dmamem_free(ahc, ahc->shared_data_dmat, ahc->qoutfifo,
3983 ahc->shared_data_dmamap);
3984 ahc_dmamap_destroy(ahc, ahc->shared_data_dmat,
3985 ahc->shared_data_dmamap);
3986
3987 case 2:
3988 ahc_dma_tag_destroy(ahc, ahc->shared_data_dmat);
3989 case 1:
3990#ifndef __linux__
3991 ahc_dma_tag_destroy(ahc, ahc->buffer_dmat);
3992#endif
3993 break;
3994 case 0:
3995 break;
3996 }
3997
3998#ifndef __linux__
3999 ahc_dma_tag_destroy(ahc, ahc->parent_dmat);
4000#endif
4001 ahc_platform_free(ahc);
4002 ahc_fini_scbdata(ahc);
4003 for (i = 0; i < AHC_NUM_TARGETS; i++) {
4004 struct ahc_tmode_tstate *tstate;
4005
4006 tstate = ahc->enabled_targets[i];
4007 if (tstate != NULL) {
4008#ifdef AHC_TARGET_MODE
4009 int j;
4010
4011 for (j = 0; j < AHC_NUM_LUNS; j++) {
4012 struct ahc_tmode_lstate *lstate;
4013
4014 lstate = tstate->enabled_luns[j];
4015 if (lstate != NULL) {
4016 xpt_free_path(lstate->path);
4017 free(lstate, M_DEVBUF);
4018 }
4019 }
4020#endif
4021 free(tstate, M_DEVBUF);
4022 }
4023 }
4024#ifdef AHC_TARGET_MODE
4025 if (ahc->black_hole != NULL) {
4026 xpt_free_path(ahc->black_hole->path);
4027 free(ahc->black_hole, M_DEVBUF);
4028 }
4029#endif
4030 if (ahc->name != NULL)
4031 free(ahc->name, M_DEVBUF);
4032 if (ahc->seep_config != NULL)
4033 free(ahc->seep_config, M_DEVBUF);
4034#ifndef __FreeBSD__
4035 free(ahc, M_DEVBUF);
4036#endif
4037 return;
4038}
4039
4040void
4041ahc_shutdown(void *arg)
4042{
4043 struct ahc_softc *ahc;
4044 int i;
4045
4046 ahc = (struct ahc_softc *)arg;
4047
4048
4049 ahc_reset(ahc, FALSE);
4050 ahc_outb(ahc, SCSISEQ, 0);
4051 ahc_outb(ahc, SXFRCTL0, 0);
4052 ahc_outb(ahc, DSPCISTATUS, 0);
4053
4054 for (i = TARG_SCSIRATE; i < SCSICONF; i++)
4055 ahc_outb(ahc, i, 0);
4056}
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067int
4068ahc_reset(struct ahc_softc *ahc, int reinit)
4069{
4070 u_int sblkctl;
4071 u_int sxfrctl1_a, sxfrctl1_b;
4072 int error;
4073 int wait;
4074
4075
4076
4077
4078
4079
4080 ahc_pause(ahc);
4081 if ((ahc_inb(ahc, HCNTRL) & CHIPRST) != 0) {
4082
4083
4084
4085
4086
4087 ahc->flags |= AHC_NO_BIOS_INIT;
4088 }
4089 sxfrctl1_b = 0;
4090 if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) {
4091 u_int sblkctl;
4092
4093
4094
4095
4096
4097 sblkctl = ahc_inb(ahc, SBLKCTL);
4098 ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
4099 sxfrctl1_b = ahc_inb(ahc, SXFRCTL1);
4100 ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
4101 }
4102 sxfrctl1_a = ahc_inb(ahc, SXFRCTL1);
4103
4104 ahc_outb(ahc, HCNTRL, CHIPRST | ahc->pause);
4105
4106
4107
4108
4109
4110
4111
4112 wait = 1000;
4113 do {
4114 ahc_delay(1000);
4115 } while (--wait && !(ahc_inb(ahc, HCNTRL) & CHIPRSTACK));
4116
4117 if (wait == 0) {
4118 printf("%s: WARNING - Failed chip reset! "
4119 "Trying to initialize anyway.\n", ahc_name(ahc));
4120 }
4121 ahc_outb(ahc, HCNTRL, ahc->pause);
4122
4123
4124 sblkctl = ahc_inb(ahc, SBLKCTL) & (SELBUSB|SELWIDE);
4125
4126 if ((ahc->chip & AHC_PCI) != 0)
4127 sblkctl &= ~SELBUSB;
4128 switch (sblkctl) {
4129 case 0:
4130
4131 break;
4132 case 2:
4133
4134 ahc->features |= AHC_WIDE;
4135 break;
4136 case 8:
4137
4138 ahc->features |= AHC_TWIN;
4139 break;
4140 default:
4141 printf(" Unsupported adapter type. Ignoring\n");
4142 return(-1);
4143 }
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153 if ((ahc->features & AHC_TWIN) != 0) {
4154 u_int sblkctl;
4155
4156 sblkctl = ahc_inb(ahc, SBLKCTL);
4157 ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
4158 ahc_outb(ahc, SXFRCTL1, sxfrctl1_b);
4159 ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
4160 }
4161 ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);
4162
4163 error = 0;
4164 if (reinit != 0)
4165
4166
4167
4168
4169 error = ahc->bus_chip_init(ahc);
4170#ifdef AHC_DUMP_SEQ
4171 else
4172 ahc_dumpseq(ahc);
4173#endif
4174
4175 return (error);
4176}
4177
4178
4179
4180
4181int
4182ahc_probe_scbs(struct ahc_softc *ahc) {
4183 int i;
4184
4185 for (i = 0; i < AHC_SCB_MAX; i++) {
4186
4187 ahc_outb(ahc, SCBPTR, i);
4188 ahc_outb(ahc, SCB_BASE, i);
4189 if (ahc_inb(ahc, SCB_BASE) != i)
4190 break;
4191 ahc_outb(ahc, SCBPTR, 0);
4192 if (ahc_inb(ahc, SCB_BASE) != 0)
4193 break;
4194 }
4195 return (i);
4196}
4197
4198static void
4199ahc_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
4200{
4201 dma_addr_t *baddr;
4202
4203 baddr = (dma_addr_t *)arg;
4204 *baddr = segs->ds_addr;
4205}
4206
4207static void
4208ahc_build_free_scb_list(struct ahc_softc *ahc)
4209{
4210 int scbsize;
4211 int i;
4212
4213 scbsize = 32;
4214 if ((ahc->flags & AHC_LSCBS_ENABLED) != 0)
4215 scbsize = 64;
4216
4217 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
4218 int j;
4219
4220 ahc_outb(ahc, SCBPTR, i);
4221
4222
4223
4224
4225
4226
4227 for (j = 0; j < scbsize; j++)
4228 ahc_outb(ahc, SCB_BASE+j, 0xFF);
4229
4230
4231 ahc_outb(ahc, SCB_CONTROL, 0);
4232
4233
4234 if ((ahc->flags & AHC_PAGESCBS) != 0)
4235 ahc_outb(ahc, SCB_NEXT, i+1);
4236 else
4237 ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
4238
4239
4240 ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
4241 ahc_outb(ahc, SCB_SCSIID, 0xFF);
4242 ahc_outb(ahc, SCB_LUN, 0xFF);
4243 }
4244
4245 if ((ahc->flags & AHC_PAGESCBS) != 0) {
4246
4247 ahc_outb(ahc, FREE_SCBH, 0);
4248 } else {
4249
4250 ahc_outb(ahc, FREE_SCBH, SCB_LIST_NULL);
4251 }
4252
4253
4254 ahc_outb(ahc, SCBPTR, i-1);
4255 ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
4256}
4257
4258static int
4259ahc_init_scbdata(struct ahc_softc *ahc)
4260{
4261 struct scb_data *scb_data;
4262
4263 scb_data = ahc->scb_data;
4264 SLIST_INIT(&scb_data->free_scbs);
4265 SLIST_INIT(&scb_data->sg_maps);
4266
4267
4268 scb_data->scbarray =
4269 (struct scb *)malloc(sizeof(struct scb) * AHC_SCB_MAX_ALLOC,
4270 M_DEVBUF, M_NOWAIT);
4271 if (scb_data->scbarray == NULL)
4272 return (ENOMEM);
4273 memset(scb_data->scbarray, 0, sizeof(struct scb) * AHC_SCB_MAX_ALLOC);
4274
4275
4276
4277 scb_data->maxhscbs = ahc_probe_scbs(ahc);
4278 if (ahc->scb_data->maxhscbs == 0) {
4279 printf("%s: No SCB space found\n", ahc_name(ahc));
4280 return (ENXIO);
4281 }
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, 1,
4295 BUS_SPACE_MAXADDR_32BIT + 1,
4296 BUS_SPACE_MAXADDR_32BIT,
4297 BUS_SPACE_MAXADDR,
4298 NULL, NULL,
4299 AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),
4300 1,
4301 BUS_SPACE_MAXSIZE_32BIT,
4302 0, &scb_data->hscb_dmat) != 0) {
4303 goto error_exit;
4304 }
4305
4306 scb_data->init_level++;
4307
4308
4309 if (ahc_dmamem_alloc(ahc, scb_data->hscb_dmat,
4310 (void **)&scb_data->hscbs,
4311 BUS_DMA_NOWAIT, &scb_data->hscb_dmamap) != 0) {
4312 goto error_exit;
4313 }
4314
4315 scb_data->init_level++;
4316
4317
4318 ahc_dmamap_load(ahc, scb_data->hscb_dmat, scb_data->hscb_dmamap,
4319 scb_data->hscbs,
4320 AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),
4321 ahc_dmamap_cb, &scb_data->hscb_busaddr, 0);
4322
4323 scb_data->init_level++;
4324
4325
4326 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, 1,
4327 BUS_SPACE_MAXADDR_32BIT + 1,
4328 BUS_SPACE_MAXADDR_32BIT,
4329 BUS_SPACE_MAXADDR,
4330 NULL, NULL,
4331 AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),
4332 1,
4333 BUS_SPACE_MAXSIZE_32BIT,
4334 0, &scb_data->sense_dmat) != 0) {
4335 goto error_exit;
4336 }
4337
4338 scb_data->init_level++;
4339
4340
4341 if (ahc_dmamem_alloc(ahc, scb_data->sense_dmat,
4342 (void **)&scb_data->sense,
4343 BUS_DMA_NOWAIT, &scb_data->sense_dmamap) != 0) {
4344 goto error_exit;
4345 }
4346
4347 scb_data->init_level++;
4348
4349
4350 ahc_dmamap_load(ahc, scb_data->sense_dmat, scb_data->sense_dmamap,
4351 scb_data->sense,
4352 AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),
4353 ahc_dmamap_cb, &scb_data->sense_busaddr, 0);
4354
4355 scb_data->init_level++;
4356
4357
4358 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, 8,
4359 BUS_SPACE_MAXADDR_32BIT + 1,
4360 BUS_SPACE_MAXADDR_32BIT,
4361 BUS_SPACE_MAXADDR,
4362 NULL, NULL,
4363 PAGE_SIZE, 1,
4364 BUS_SPACE_MAXSIZE_32BIT,
4365 0, &scb_data->sg_dmat) != 0) {
4366 goto error_exit;
4367 }
4368
4369 scb_data->init_level++;
4370
4371
4372 memset(scb_data->hscbs, 0,
4373 AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb));
4374 ahc_alloc_scbs(ahc);
4375
4376 if (scb_data->numscbs == 0) {
4377 printf("%s: ahc_init_scbdata - "
4378 "Unable to allocate initial scbs\n",
4379 ahc_name(ahc));
4380 goto error_exit;
4381 }
4382
4383
4384
4385
4386 ahc->next_queued_scb = ahc_get_scb(ahc);
4387
4388
4389
4390
4391 return (0);
4392
4393error_exit:
4394
4395 return (ENOMEM);
4396}
4397
4398static void
4399ahc_fini_scbdata(struct ahc_softc *ahc)
4400{
4401 struct scb_data *scb_data;
4402
4403 scb_data = ahc->scb_data;
4404 if (scb_data == NULL)
4405 return;
4406
4407 switch (scb_data->init_level) {
4408 default:
4409 case 7:
4410 {
4411 struct sg_map_node *sg_map;
4412
4413 while ((sg_map = SLIST_FIRST(&scb_data->sg_maps))!= NULL) {
4414 SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
4415 ahc_dmamap_unload(ahc, scb_data->sg_dmat,
4416 sg_map->sg_dmamap);
4417 ahc_dmamem_free(ahc, scb_data->sg_dmat,
4418 sg_map->sg_vaddr,
4419 sg_map->sg_dmamap);
4420 free(sg_map, M_DEVBUF);
4421 }
4422 ahc_dma_tag_destroy(ahc, scb_data->sg_dmat);
4423 }
4424 case 6:
4425 ahc_dmamap_unload(ahc, scb_data->sense_dmat,
4426 scb_data->sense_dmamap);
4427 case 5:
4428 ahc_dmamem_free(ahc, scb_data->sense_dmat, scb_data->sense,
4429 scb_data->sense_dmamap);
4430 ahc_dmamap_destroy(ahc, scb_data->sense_dmat,
4431 scb_data->sense_dmamap);
4432 case 4:
4433 ahc_dma_tag_destroy(ahc, scb_data->sense_dmat);
4434 case 3:
4435 ahc_dmamap_unload(ahc, scb_data->hscb_dmat,
4436 scb_data->hscb_dmamap);
4437 case 2:
4438 ahc_dmamem_free(ahc, scb_data->hscb_dmat, scb_data->hscbs,
4439 scb_data->hscb_dmamap);
4440 ahc_dmamap_destroy(ahc, scb_data->hscb_dmat,
4441 scb_data->hscb_dmamap);
4442 case 1:
4443 ahc_dma_tag_destroy(ahc, scb_data->hscb_dmat);
4444 break;
4445 case 0:
4446 break;
4447 }
4448 if (scb_data->scbarray != NULL)
4449 free(scb_data->scbarray, M_DEVBUF);
4450}
4451
4452void
4453ahc_alloc_scbs(struct ahc_softc *ahc)
4454{
4455 struct scb_data *scb_data;
4456 struct scb *next_scb;
4457 struct sg_map_node *sg_map;
4458 dma_addr_t physaddr;
4459 struct ahc_dma_seg *segs;
4460 int newcount;
4461 int i;
4462
4463 scb_data = ahc->scb_data;
4464 if (scb_data->numscbs >= AHC_SCB_MAX_ALLOC)
4465
4466 return;
4467
4468 next_scb = &scb_data->scbarray[scb_data->numscbs];
4469
4470 sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT);
4471
4472 if (sg_map == NULL)
4473 return;
4474
4475
4476 if (ahc_dmamem_alloc(ahc, scb_data->sg_dmat,
4477 (void **)&sg_map->sg_vaddr,
4478 BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) {
4479 free(sg_map, M_DEVBUF);
4480 return;
4481 }
4482
4483 SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
4484
4485 ahc_dmamap_load(ahc, scb_data->sg_dmat, sg_map->sg_dmamap,
4486 sg_map->sg_vaddr, PAGE_SIZE, ahc_dmamap_cb,
4487 &sg_map->sg_physaddr, 0);
4488
4489 segs = sg_map->sg_vaddr;
4490 physaddr = sg_map->sg_physaddr;
4491
4492 newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg)));
4493 newcount = MIN(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs));
4494 for (i = 0; i < newcount; i++) {
4495 struct scb_platform_data *pdata;
4496#ifndef __linux__
4497 int error;
4498#endif
4499 pdata = (struct scb_platform_data *)malloc(sizeof(*pdata),
4500 M_DEVBUF, M_NOWAIT);
4501 if (pdata == NULL)
4502 break;
4503 next_scb->platform_data = pdata;
4504 next_scb->sg_map = sg_map;
4505 next_scb->sg_list = segs;
4506
4507
4508
4509
4510 next_scb->sg_list_phys = physaddr + sizeof(struct ahc_dma_seg);
4511 next_scb->ahc_softc = ahc;
4512 next_scb->flags = SCB_FREE;
4513#ifndef __linux__
4514 error = ahc_dmamap_create(ahc, ahc->buffer_dmat, 0,
4515 &next_scb->dmamap);
4516 if (error != 0)
4517 break;
4518#endif
4519 next_scb->hscb = &scb_data->hscbs[scb_data->numscbs];
4520 next_scb->hscb->tag = ahc->scb_data->numscbs;
4521 SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs,
4522 next_scb, links.sle);
4523 segs += AHC_NSEG;
4524 physaddr += (AHC_NSEG * sizeof(struct ahc_dma_seg));
4525 next_scb++;
4526 ahc->scb_data->numscbs++;
4527 }
4528}
4529
4530void
4531ahc_controller_info(struct ahc_softc *ahc, char *buf)
4532{
4533 int len;
4534
4535 len = sprintf(buf, "%s: ", ahc_chip_names[ahc->chip & AHC_CHIPID_MASK]);
4536 buf += len;
4537 if ((ahc->features & AHC_TWIN) != 0)
4538 len = sprintf(buf, "Twin Channel, A SCSI Id=%d, "
4539 "B SCSI Id=%d, primary %c, ",
4540 ahc->our_id, ahc->our_id_b,
4541 (ahc->flags & AHC_PRIMARY_CHANNEL) + 'A');
4542 else {
4543 const char *speed;
4544 const char *type;
4545
4546 speed = "";
4547 if ((ahc->features & AHC_ULTRA) != 0) {
4548 speed = "Ultra ";
4549 } else if ((ahc->features & AHC_DT) != 0) {
4550 speed = "Ultra160 ";
4551 } else if ((ahc->features & AHC_ULTRA2) != 0) {
4552 speed = "Ultra2 ";
4553 }
4554 if ((ahc->features & AHC_WIDE) != 0) {
4555 type = "Wide";
4556 } else {
4557 type = "Single";
4558 }
4559 len = sprintf(buf, "%s%s Channel %c, SCSI Id=%d, ",
4560 speed, type, ahc->channel, ahc->our_id);
4561 }
4562 buf += len;
4563
4564 if ((ahc->flags & AHC_PAGESCBS) != 0)
4565 sprintf(buf, "%d/%d SCBs",
4566 ahc->scb_data->maxhscbs, AHC_MAX_QUEUE);
4567 else
4568 sprintf(buf, "%d SCBs", ahc->scb_data->maxhscbs);
4569}
4570
4571int
4572ahc_chip_init(struct ahc_softc *ahc)
4573{
4574 int term;
4575 int error;
4576 u_int i;
4577 u_int scsi_conf;
4578 u_int scsiseq_template;
4579 uint32_t physaddr;
4580
4581 ahc_outb(ahc, SEQ_FLAGS, 0);
4582 ahc_outb(ahc, SEQ_FLAGS2, 0);
4583
4584
4585 if (ahc->features & AHC_TWIN) {
4586
4587
4588
4589
4590 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
4591 term = (ahc->flags & AHC_TERM_ENB_B) != 0 ? STPWEN : 0;
4592 ahc_outb(ahc, SCSIID, ahc->our_id_b);
4593 scsi_conf = ahc_inb(ahc, SCSICONF + 1);
4594 ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
4595 |term|ahc->seltime_b|ENSTIMER|ACTNEGEN);
4596 if ((ahc->features & AHC_ULTRA2) != 0)
4597 ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
4598 ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
4599 ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
4600
4601
4602 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
4603 }
4604 term = (ahc->flags & AHC_TERM_ENB_A) != 0 ? STPWEN : 0;
4605 if ((ahc->features & AHC_ULTRA2) != 0)
4606 ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
4607 else
4608 ahc_outb(ahc, SCSIID, ahc->our_id);
4609 scsi_conf = ahc_inb(ahc, SCSICONF);
4610 ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
4611 |term|ahc->seltime
4612 |ENSTIMER|ACTNEGEN);
4613 if ((ahc->features & AHC_ULTRA2) != 0)
4614 ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
4615 ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
4616 ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
4617
4618
4619 for (i = 0; i < 16; i++) {
4620 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, 0));
4621 if ((ahc->flags & AHC_SCB_BTT) != 0) {
4622 int lun;
4623
4624
4625
4626
4627
4628 for (lun = 1; lun < AHC_NUM_LUNS; lun++)
4629 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, lun));
4630 }
4631 }
4632
4633
4634 for (i = 0; i < 256; i++)
4635 ahc->qoutfifo[i] = SCB_LIST_NULL;
4636 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_PREREAD);
4637
4638 for (i = 0; i < 256; i++)
4639 ahc->qinfifo[i] = SCB_LIST_NULL;
4640
4641 if ((ahc->features & AHC_MULTI_TID) != 0) {
4642 ahc_outb(ahc, TARGID, 0);
4643 ahc_outb(ahc, TARGID + 1, 0);
4644 }
4645
4646
4647
4648
4649 physaddr = ahc->scb_data->hscb_busaddr;
4650 ahc_outb(ahc, HSCB_ADDR, physaddr & 0xFF);
4651 ahc_outb(ahc, HSCB_ADDR + 1, (physaddr >> 8) & 0xFF);
4652 ahc_outb(ahc, HSCB_ADDR + 2, (physaddr >> 16) & 0xFF);
4653 ahc_outb(ahc, HSCB_ADDR + 3, (physaddr >> 24) & 0xFF);
4654
4655 physaddr = ahc->shared_data_busaddr;
4656 ahc_outb(ahc, SHARED_DATA_ADDR, physaddr & 0xFF);
4657 ahc_outb(ahc, SHARED_DATA_ADDR + 1, (physaddr >> 8) & 0xFF);
4658 ahc_outb(ahc, SHARED_DATA_ADDR + 2, (physaddr >> 16) & 0xFF);
4659 ahc_outb(ahc, SHARED_DATA_ADDR + 3, (physaddr >> 24) & 0xFF);
4660
4661
4662
4663
4664
4665
4666 ahc_outb(ahc, CMDSIZE_TABLE, 5);
4667 ahc_outb(ahc, CMDSIZE_TABLE + 1, 9);
4668 ahc_outb(ahc, CMDSIZE_TABLE + 2, 9);
4669 ahc_outb(ahc, CMDSIZE_TABLE + 3, 0);
4670 ahc_outb(ahc, CMDSIZE_TABLE + 4, 15);
4671 ahc_outb(ahc, CMDSIZE_TABLE + 5, 11);
4672 ahc_outb(ahc, CMDSIZE_TABLE + 6, 0);
4673 ahc_outb(ahc, CMDSIZE_TABLE + 7, 0);
4674
4675 if ((ahc->features & AHC_HS_MAILBOX) != 0)
4676 ahc_outb(ahc, HS_MAILBOX, 0);
4677
4678
4679 if ((ahc->features & AHC_TARGETMODE) != 0) {
4680 ahc->tqinfifonext = 1;
4681 ahc_outb(ahc, KERNEL_TQINPOS, ahc->tqinfifonext - 1);
4682 ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
4683 }
4684 ahc->qinfifonext = 0;
4685 ahc->qoutfifonext = 0;
4686 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
4687 ahc_outb(ahc, QOFF_CTLSTA, SCB_QSIZE_256);
4688 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
4689 ahc_outb(ahc, SNSCB_QOFF, ahc->qinfifonext);
4690 ahc_outb(ahc, SDSCB_QOFF, 0);
4691 } else {
4692 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
4693 ahc_outb(ahc, QINPOS, ahc->qinfifonext);
4694 ahc_outb(ahc, QOUTPOS, ahc->qoutfifonext);
4695 }
4696
4697
4698 ahc_outb(ahc, WAITING_SCBH, SCB_LIST_NULL);
4699
4700
4701 ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
4702
4703
4704 ahc_outb(ahc, MSG_OUT, MSG_NOOP);
4705
4706
4707
4708
4709
4710
4711 scsiseq_template = ENSELO|ENAUTOATNO|ENAUTOATNP;
4712 if ((ahc->flags & AHC_INITIATORROLE) != 0)
4713 scsiseq_template |= ENRSELI;
4714 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq_template);
4715
4716
4717 ahc_build_free_scb_list(ahc);
4718
4719
4720
4721
4722 ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
4723
4724
4725
4726
4727
4728 if (bootverbose)
4729 printf("%s: Downloading Sequencer Program...",
4730 ahc_name(ahc));
4731
4732 error = ahc_loadseq(ahc);
4733 if (error != 0)
4734 return (error);
4735
4736 if ((ahc->features & AHC_ULTRA2) != 0) {
4737 int wait;
4738
4739
4740
4741
4742
4743
4744
4745
4746 for (wait = 5000;
4747 (ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
4748 wait--)
4749 ahc_delay(100);
4750 }
4751 ahc_restart(ahc);
4752 return (0);
4753}
4754
4755
4756
4757
4758int
4759ahc_init(struct ahc_softc *ahc)
4760{
4761 int max_targ;
4762 u_int i;
4763 u_int scsi_conf;
4764 u_int ultraenb;
4765 u_int discenable;
4766 u_int tagenable;
4767 size_t driver_data_size;
4768
4769#ifdef AHC_DEBUG
4770 if ((ahc_debug & AHC_DEBUG_SEQUENCER) != 0)
4771 ahc->flags |= AHC_SEQUENCER_DEBUG;
4772#endif
4773
4774#ifdef AHC_PRINT_SRAM
4775 printf("Scratch Ram:");
4776 for (i = 0x20; i < 0x5f; i++) {
4777 if (((i % 8) == 0) && (i != 0)) {
4778 printf ("\n ");
4779 }
4780 printf (" 0x%x", ahc_inb(ahc, i));
4781 }
4782 if ((ahc->features & AHC_MORE_SRAM) != 0) {
4783 for (i = 0x70; i < 0x7f; i++) {
4784 if (((i % 8) == 0) && (i != 0)) {
4785 printf ("\n ");
4786 }
4787 printf (" 0x%x", ahc_inb(ahc, i));
4788 }
4789 }
4790 printf ("\n");
4791
4792
4793
4794
4795 ahc_outb(ahc, CLRINT, CLRPARERR);
4796 ahc_outb(ahc, CLRINT, CLRBRKADRINT);
4797#endif
4798 max_targ = 15;
4799
4800
4801
4802
4803 if ((ahc->flags & AHC_USEDEFAULTS) != 0)
4804 ahc->our_id = ahc->our_id_b = 7;
4805
4806
4807
4808
4809 ahc->flags |= AHC_INITIATORROLE;
4810
4811
4812
4813
4814 if ((AHC_TMODE_ENABLE & (0x1 << ahc->unit)) == 0)
4815 ahc->features &= ~AHC_TARGETMODE;
4816
4817#ifndef __linux__
4818
4819 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, 1,
4820 BUS_SPACE_MAXADDR_32BIT + 1,
4821 ahc->flags & AHC_39BIT_ADDRESSING
4822 ? (dma_addr_t)0x7FFFFFFFFFULL
4823 : BUS_SPACE_MAXADDR_32BIT,
4824 BUS_SPACE_MAXADDR,
4825 NULL, NULL,
4826 (AHC_NSEG - 1) * PAGE_SIZE,
4827 AHC_NSEG,
4828 AHC_MAXTRANSFER_SIZE,
4829 BUS_DMA_ALLOCNOW,
4830 &ahc->buffer_dmat) != 0) {
4831 return (ENOMEM);
4832 }
4833#endif
4834
4835 ahc->init_level++;
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846 driver_data_size = 2 * 256 * sizeof(uint8_t);
4847 if ((ahc->features & AHC_TARGETMODE) != 0)
4848 driver_data_size += AHC_TMODE_CMDS * sizeof(struct target_cmd)
4849 + 1;
4850 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, 1,
4851 BUS_SPACE_MAXADDR_32BIT + 1,
4852 BUS_SPACE_MAXADDR_32BIT,
4853 BUS_SPACE_MAXADDR,
4854 NULL, NULL,
4855 driver_data_size,
4856 1,
4857 BUS_SPACE_MAXSIZE_32BIT,
4858 0, &ahc->shared_data_dmat) != 0) {
4859 return (ENOMEM);
4860 }
4861
4862 ahc->init_level++;
4863
4864
4865 if (ahc_dmamem_alloc(ahc, ahc->shared_data_dmat,
4866 (void **)&ahc->qoutfifo,
4867 BUS_DMA_NOWAIT, &ahc->shared_data_dmamap) != 0) {
4868 return (ENOMEM);
4869 }
4870
4871 ahc->init_level++;
4872
4873
4874 ahc_dmamap_load(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
4875 ahc->qoutfifo, driver_data_size, ahc_dmamap_cb,
4876 &ahc->shared_data_busaddr, 0);
4877
4878 if ((ahc->features & AHC_TARGETMODE) != 0) {
4879 ahc->targetcmds = (struct target_cmd *)ahc->qoutfifo;
4880 ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[AHC_TMODE_CMDS];
4881 ahc->dma_bug_buf = ahc->shared_data_busaddr
4882 + driver_data_size - 1;
4883
4884 for (i = 0; i < AHC_TMODE_CMDS; i++)
4885 ahc->targetcmds[i].cmd_valid = 0;
4886 ahc_sync_tqinfifo(ahc, BUS_DMASYNC_PREREAD);
4887 ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[256];
4888 }
4889 ahc->qinfifo = &ahc->qoutfifo[256];
4890
4891 ahc->init_level++;
4892
4893
4894 if (ahc->scb_data->maxhscbs == 0)
4895 if (ahc_init_scbdata(ahc) != 0)
4896 return (ENOMEM);
4897
4898
4899
4900
4901
4902
4903 if (ahc_alloc_tstate(ahc, ahc->our_id, 'A') == NULL) {
4904 printf("%s: unable to allocate ahc_tmode_tstate. "
4905 "Failing attach\n", ahc_name(ahc));
4906 return (ENOMEM);
4907 }
4908
4909 if ((ahc->features & AHC_TWIN) != 0) {
4910 if (ahc_alloc_tstate(ahc, ahc->our_id_b, 'B') == NULL) {
4911 printf("%s: unable to allocate ahc_tmode_tstate. "
4912 "Failing attach\n", ahc_name(ahc));
4913 return (ENOMEM);
4914 }
4915 }
4916
4917 if (ahc->scb_data->maxhscbs < AHC_SCB_MAX_ALLOC) {
4918 ahc->flags |= AHC_PAGESCBS;
4919 } else {
4920 ahc->flags &= ~AHC_PAGESCBS;
4921 }
4922
4923#ifdef AHC_DEBUG
4924 if (ahc_debug & AHC_SHOW_MISC) {
4925 printf("%s: hardware scb %u bytes; kernel scb %u bytes; "
4926 "ahc_dma %u bytes\n",
4927 ahc_name(ahc),
4928 (u_int)sizeof(struct hardware_scb),
4929 (u_int)sizeof(struct scb),
4930 (u_int)sizeof(struct ahc_dma_seg));
4931 }
4932#endif
4933
4934
4935
4936
4937
4938 if (ahc->features & AHC_TWIN) {
4939 scsi_conf = ahc_inb(ahc, SCSICONF + 1);
4940 if ((scsi_conf & RESET_SCSI) != 0
4941 && (ahc->flags & AHC_INITIATORROLE) != 0)
4942 ahc->flags |= AHC_RESET_BUS_B;
4943 }
4944
4945 scsi_conf = ahc_inb(ahc, SCSICONF);
4946 if ((scsi_conf & RESET_SCSI) != 0
4947 && (ahc->flags & AHC_INITIATORROLE) != 0)
4948 ahc->flags |= AHC_RESET_BUS_A;
4949
4950 ultraenb = 0;
4951 tagenable = ALL_TARGETS_MASK;
4952
4953
4954 if ((ahc->flags & AHC_USEDEFAULTS) != 0) {
4955 printf("%s: Host Adapter Bios disabled. Using default SCSI "
4956 "device parameters\n", ahc_name(ahc));
4957 ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B|
4958 AHC_TERM_ENB_A|AHC_TERM_ENB_B;
4959 discenable =