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#ifdef __linux__
44#include "aic79xx_osm.h"
45#include "aic79xx_inline.h"
46#include "aicasm/aicasm_insformat.h"
47#else
48#include <dev/aic7xxx/aic79xx_osm.h>
49#include <dev/aic7xxx/aic79xx_inline.h>
50#include <dev/aic7xxx/aicasm/aicasm_insformat.h>
51#endif
52
53
54
55char *ahd_chip_names[] =
56{
57 "NONE",
58 "aic7901",
59 "aic7902",
60 "aic7901A"
61};
62static const u_int num_chip_names = ARRAY_SIZE(ahd_chip_names);
63
64
65
66
67struct ahd_hard_error_entry {
68 uint8_t errno;
69 char *errmesg;
70};
71
72static struct ahd_hard_error_entry ahd_hard_errors[] = {
73 { DSCTMOUT, "Discard Timer has timed out" },
74 { ILLOPCODE, "Illegal Opcode in sequencer program" },
75 { SQPARERR, "Sequencer Parity Error" },
76 { DPARERR, "Data-path Parity Error" },
77 { MPARERR, "Scratch or SCB Memory Parity Error" },
78 { CIOPARERR, "CIOBUS Parity Error" },
79};
80static const u_int num_errors = ARRAY_SIZE(ahd_hard_errors);
81
82static struct ahd_phase_table_entry ahd_phase_table[] =
83{
84 { P_DATAOUT, MSG_NOOP, "in Data-out phase" },
85 { P_DATAIN, MSG_INITIATOR_DET_ERR, "in Data-in phase" },
86 { P_DATAOUT_DT, MSG_NOOP, "in DT Data-out phase" },
87 { P_DATAIN_DT, MSG_INITIATOR_DET_ERR, "in DT Data-in phase" },
88 { P_COMMAND, MSG_NOOP, "in Command phase" },
89 { P_MESGOUT, MSG_NOOP, "in Message-out phase" },
90 { P_STATUS, MSG_INITIATOR_DET_ERR, "in Status phase" },
91 { P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" },
92 { P_BUSFREE, MSG_NOOP, "while idle" },
93 { 0, MSG_NOOP, "in unknown phase" }
94};
95
96
97
98
99
100static const u_int num_phases = ARRAY_SIZE(ahd_phase_table) - 1;
101
102
103#include "aic79xx_seq.h"
104
105
106static void ahd_handle_transmission_error(struct ahd_softc *ahd);
107static void ahd_handle_lqiphase_error(struct ahd_softc *ahd,
108 u_int lqistat1);
109static int ahd_handle_pkt_busfree(struct ahd_softc *ahd,
110 u_int busfreetime);
111static int ahd_handle_nonpkt_busfree(struct ahd_softc *ahd);
112static void ahd_handle_proto_violation(struct ahd_softc *ahd);
113static void ahd_force_renegotiation(struct ahd_softc *ahd,
114 struct ahd_devinfo *devinfo);
115
116static struct ahd_tmode_tstate*
117 ahd_alloc_tstate(struct ahd_softc *ahd,
118 u_int scsi_id, char channel);
119#ifdef AHD_TARGET_MODE
120static void ahd_free_tstate(struct ahd_softc *ahd,
121 u_int scsi_id, char channel, int force);
122#endif
123static void ahd_devlimited_syncrate(struct ahd_softc *ahd,
124 struct ahd_initiator_tinfo *,
125 u_int *period,
126 u_int *ppr_options,
127 role_t role);
128static void ahd_update_neg_table(struct ahd_softc *ahd,
129 struct ahd_devinfo *devinfo,
130 struct ahd_transinfo *tinfo);
131static void ahd_update_pending_scbs(struct ahd_softc *ahd);
132static void ahd_fetch_devinfo(struct ahd_softc *ahd,
133 struct ahd_devinfo *devinfo);
134static void ahd_scb_devinfo(struct ahd_softc *ahd,
135 struct ahd_devinfo *devinfo,
136 struct scb *scb);
137static void ahd_setup_initiator_msgout(struct ahd_softc *ahd,
138 struct ahd_devinfo *devinfo,
139 struct scb *scb);
140static void ahd_build_transfer_msg(struct ahd_softc *ahd,
141 struct ahd_devinfo *devinfo);
142static void ahd_construct_sdtr(struct ahd_softc *ahd,
143 struct ahd_devinfo *devinfo,
144 u_int period, u_int offset);
145static void ahd_construct_wdtr(struct ahd_softc *ahd,
146 struct ahd_devinfo *devinfo,
147 u_int bus_width);
148static void ahd_construct_ppr(struct ahd_softc *ahd,
149 struct ahd_devinfo *devinfo,
150 u_int period, u_int offset,
151 u_int bus_width, u_int ppr_options);
152static void ahd_clear_msg_state(struct ahd_softc *ahd);
153static void ahd_handle_message_phase(struct ahd_softc *ahd);
154typedef enum {
155 AHDMSG_1B,
156 AHDMSG_2B,
157 AHDMSG_EXT
158} ahd_msgtype;
159static int ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type,
160 u_int msgval, int full);
161static int ahd_parse_msg(struct ahd_softc *ahd,
162 struct ahd_devinfo *devinfo);
163static int ahd_handle_msg_reject(struct ahd_softc *ahd,
164 struct ahd_devinfo *devinfo);
165static void ahd_handle_ign_wide_residue(struct ahd_softc *ahd,
166 struct ahd_devinfo *devinfo);
167static void ahd_reinitialize_dataptrs(struct ahd_softc *ahd);
168static void ahd_handle_devreset(struct ahd_softc *ahd,
169 struct ahd_devinfo *devinfo,
170 u_int lun, cam_status status,
171 char *message, int verbose_level);
172#ifdef AHD_TARGET_MODE
173static void ahd_setup_target_msgin(struct ahd_softc *ahd,
174 struct ahd_devinfo *devinfo,
175 struct scb *scb);
176#endif
177
178static u_int ahd_sglist_size(struct ahd_softc *ahd);
179static u_int ahd_sglist_allocsize(struct ahd_softc *ahd);
180static bus_dmamap_callback_t
181 ahd_dmamap_cb;
182static void ahd_initialize_hscbs(struct ahd_softc *ahd);
183static int ahd_init_scbdata(struct ahd_softc *ahd);
184static void ahd_fini_scbdata(struct ahd_softc *ahd);
185static void ahd_setup_iocell_workaround(struct ahd_softc *ahd);
186static void ahd_iocell_first_selection(struct ahd_softc *ahd);
187static void ahd_add_col_list(struct ahd_softc *ahd,
188 struct scb *scb, u_int col_idx);
189static void ahd_rem_col_list(struct ahd_softc *ahd,
190 struct scb *scb);
191static void ahd_chip_init(struct ahd_softc *ahd);
192static void ahd_qinfifo_requeue(struct ahd_softc *ahd,
193 struct scb *prev_scb,
194 struct scb *scb);
195static int ahd_qinfifo_count(struct ahd_softc *ahd);
196static int ahd_search_scb_list(struct ahd_softc *ahd, int target,
197 char channel, int lun, u_int tag,
198 role_t role, uint32_t status,
199 ahd_search_action action,
200 u_int *list_head, u_int *list_tail,
201 u_int tid);
202static void ahd_stitch_tid_list(struct ahd_softc *ahd,
203 u_int tid_prev, u_int tid_cur,
204 u_int tid_next);
205static void ahd_add_scb_to_free_list(struct ahd_softc *ahd,
206 u_int scbid);
207static u_int ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid,
208 u_int prev, u_int next, u_int tid);
209static void ahd_reset_current_bus(struct ahd_softc *ahd);
210static ahd_callback_t ahd_stat_timer;
211#ifdef AHD_DUMP_SEQ
212static void ahd_dumpseq(struct ahd_softc *ahd);
213#endif
214static void ahd_loadseq(struct ahd_softc *ahd);
215static int ahd_check_patch(struct ahd_softc *ahd,
216 struct patch **start_patch,
217 u_int start_instr, u_int *skip_addr);
218static u_int ahd_resolve_seqaddr(struct ahd_softc *ahd,
219 u_int address);
220static void ahd_download_instr(struct ahd_softc *ahd,
221 u_int instrptr, uint8_t *dconsts);
222static int ahd_probe_stack_size(struct ahd_softc *ahd);
223static int ahd_scb_active_in_fifo(struct ahd_softc *ahd,
224 struct scb *scb);
225static void ahd_run_data_fifo(struct ahd_softc *ahd,
226 struct scb *scb);
227
228#ifdef AHD_TARGET_MODE
229static void ahd_queue_lstate_event(struct ahd_softc *ahd,
230 struct ahd_tmode_lstate *lstate,
231 u_int initiator_id,
232 u_int event_type,
233 u_int event_arg);
234static void ahd_update_scsiid(struct ahd_softc *ahd,
235 u_int targid_mask);
236static int ahd_handle_target_cmd(struct ahd_softc *ahd,
237 struct target_cmd *cmd);
238#endif
239
240
241static __inline void ahd_assert_atn(struct ahd_softc *ahd);
242static __inline int ahd_currently_packetized(struct ahd_softc *ahd);
243static __inline int ahd_set_active_fifo(struct ahd_softc *ahd);
244
245static __inline void
246ahd_assert_atn(struct ahd_softc *ahd)
247{
248 ahd_outb(ahd, SCSISIGO, ATNO);
249}
250
251
252
253
254
255
256
257static __inline int
258ahd_currently_packetized(struct ahd_softc *ahd)
259{
260 ahd_mode_state saved_modes;
261 int packetized;
262
263 saved_modes = ahd_save_modes(ahd);
264 if ((ahd->bugs & AHD_PKTIZED_STATUS_BUG) != 0) {
265
266
267
268
269
270 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
271 packetized = ahd_inb(ahd, LQISTATE) != 0;
272 } else {
273 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
274 packetized = ahd_inb(ahd, LQISTAT2) & PACKETIZED;
275 }
276 ahd_restore_modes(ahd, saved_modes);
277 return (packetized);
278}
279
280static __inline int
281ahd_set_active_fifo(struct ahd_softc *ahd)
282{
283 u_int active_fifo;
284
285 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
286 active_fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO;
287 switch (active_fifo) {
288 case 0:
289 case 1:
290 ahd_set_modes(ahd, active_fifo, active_fifo);
291 return (1);
292 default:
293 return (0);
294 }
295}
296
297
298
299
300
301void
302ahd_restart(struct ahd_softc *ahd)
303{
304
305 ahd_pause(ahd);
306
307 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
308
309
310 ahd_clear_msg_state(ahd);
311 ahd_outb(ahd, SCSISIGO, 0);
312 ahd_outb(ahd, MSG_OUT, MSG_NOOP);
313 ahd_outb(ahd, SXFRCTL1, ahd_inb(ahd, SXFRCTL1) & ~BITBUCKET);
314 ahd_outb(ahd, SEQINTCTL, 0);
315 ahd_outb(ahd, LASTPHASE, P_BUSFREE);
316 ahd_outb(ahd, SEQ_FLAGS, 0);
317 ahd_outb(ahd, SAVED_SCSIID, 0xFF);
318 ahd_outb(ahd, SAVED_LUN, 0xFF);
319
320
321
322
323
324
325
326
327 ahd_outb(ahd, TQINPOS, ahd->tqinfifonext);
328
329
330 ahd_outb(ahd, SCSISEQ1,
331 ahd_inb(ahd, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
332 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
333
334
335
336
337
338
339 ahd_outb(ahd, CLRINT, CLRSEQINT);
340
341 ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);
342 ahd_unpause(ahd);
343}
344
345void
346ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo)
347{
348 ahd_mode_state saved_modes;
349
350#ifdef AHD_DEBUG
351 if ((ahd_debug & AHD_SHOW_FIFOS) != 0)
352 printf("%s: Clearing FIFO %d\n", ahd_name(ahd), fifo);
353#endif
354 saved_modes = ahd_save_modes(ahd);
355 ahd_set_modes(ahd, fifo, fifo);
356 ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT);
357 if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0)
358 ahd_outb(ahd, CCSGCTL, CCSGRESET);
359 ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
360 ahd_outb(ahd, SG_STATE, 0);
361 ahd_restore_modes(ahd, saved_modes);
362}
363
364
365
366
367
368
369void
370ahd_flush_qoutfifo(struct ahd_softc *ahd)
371{
372 struct scb *scb;
373 ahd_mode_state saved_modes;
374 u_int saved_scbptr;
375 u_int ccscbctl;
376 u_int scbid;
377 u_int next_scbid;
378
379 saved_modes = ahd_save_modes(ahd);
380
381
382
383
384 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
385 saved_scbptr = ahd_get_scbptr(ahd);
386 while ((ahd_inb(ahd, LQISTAT2) & LQIGSAVAIL) != 0) {
387 u_int fifo_mode;
388 u_int i;
389
390 scbid = ahd_inw(ahd, GSFIFO);
391 scb = ahd_lookup_scb(ahd, scbid);
392 if (scb == NULL) {
393 printf("%s: Warning - GSFIFO SCB %d invalid\n",
394 ahd_name(ahd), scbid);
395 continue;
396 }
397
398
399
400
401
402 fifo_mode = 0;
403rescan_fifos:
404 for (i = 0; i < 2; i++) {
405
406 fifo_mode ^= 1;
407 ahd_set_modes(ahd, fifo_mode, fifo_mode);
408
409 if (ahd_scb_active_in_fifo(ahd, scb) == 0)
410 continue;
411
412 ahd_run_data_fifo(ahd, scb);
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428 ahd_delay(200);
429 goto rescan_fifos;
430 }
431 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
432 ahd_set_scbptr(ahd, scbid);
433 if ((ahd_inb_scbram(ahd, SCB_SGPTR) & SG_LIST_NULL) == 0
434 && ((ahd_inb_scbram(ahd, SCB_SGPTR) & SG_FULL_RESID) != 0
435 || (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR)
436 & SG_LIST_NULL) != 0)) {
437 u_int comp_head;
438
439
440
441
442
443
444
445 ahd_outb(ahd, SCB_SCSI_STATUS, 0);
446 ahd_outb(ahd, SCB_SGPTR,
447 ahd_inb_scbram(ahd, SCB_SGPTR)
448 | SG_STATUS_VALID);
449 ahd_outw(ahd, SCB_TAG, scbid);
450 ahd_outw(ahd, SCB_NEXT_COMPLETE, SCB_LIST_NULL);
451 comp_head = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
452 if (SCBID_IS_NULL(comp_head)) {
453 ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, scbid);
454 ahd_outw(ahd, COMPLETE_DMA_SCB_TAIL, scbid);
455 } else {
456 u_int tail;
457
458 tail = ahd_inw(ahd, COMPLETE_DMA_SCB_TAIL);
459 ahd_set_scbptr(ahd, tail);
460 ahd_outw(ahd, SCB_NEXT_COMPLETE, scbid);
461 ahd_outw(ahd, COMPLETE_DMA_SCB_TAIL, scbid);
462 ahd_set_scbptr(ahd, scbid);
463 }
464 } else
465 ahd_complete_scb(ahd, scb);
466 }
467 ahd_set_scbptr(ahd, saved_scbptr);
468
469
470
471
472 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
473
474
475
476
477
478 while (((ccscbctl = ahd_inb(ahd, CCSCBCTL)) & (CCARREN|CCSCBEN)) != 0) {
479
480 if ((ccscbctl & (CCSCBDIR|CCARREN)) == (CCSCBDIR|CCARREN)) {
481 if ((ccscbctl & ARRDONE) != 0)
482 break;
483 } else if ((ccscbctl & CCSCBDONE) != 0)
484 break;
485 ahd_delay(200);
486 }
487
488
489
490
491
492
493
494 if ((ccscbctl & CCSCBDIR) != 0 || (ccscbctl & ARRDONE) != 0)
495 ahd_outb(ahd, CCSCBCTL, ccscbctl & ~(CCARREN|CCSCBEN));
496
497
498
499
500
501 ahd_run_qoutfifo(ahd);
502
503 saved_scbptr = ahd_get_scbptr(ahd);
504
505
506
507
508 scbid = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
509 while (!SCBID_IS_NULL(scbid)) {
510 uint8_t *hscb_ptr;
511 u_int i;
512
513 ahd_set_scbptr(ahd, scbid);
514 next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
515 scb = ahd_lookup_scb(ahd, scbid);
516 if (scb == NULL) {
517 printf("%s: Warning - DMA-up and complete "
518 "SCB %d invalid\n", ahd_name(ahd), scbid);
519 continue;
520 }
521 hscb_ptr = (uint8_t *)scb->hscb;
522 for (i = 0; i < sizeof(struct hardware_scb); i++)
523 *hscb_ptr++ = ahd_inb_scbram(ahd, SCB_BASE + i);
524
525 ahd_complete_scb(ahd, scb);
526 scbid = next_scbid;
527 }
528 ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL);
529 ahd_outw(ahd, COMPLETE_DMA_SCB_TAIL, SCB_LIST_NULL);
530
531 scbid = ahd_inw(ahd, COMPLETE_ON_QFREEZE_HEAD);
532 while (!SCBID_IS_NULL(scbid)) {
533
534 ahd_set_scbptr(ahd, scbid);
535 next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
536 scb = ahd_lookup_scb(ahd, scbid);
537 if (scb == NULL) {
538 printf("%s: Warning - Complete Qfrz SCB %d invalid\n",
539 ahd_name(ahd), scbid);
540 continue;
541 }
542
543 ahd_complete_scb(ahd, scb);
544 scbid = next_scbid;
545 }
546 ahd_outw(ahd, COMPLETE_ON_QFREEZE_HEAD, SCB_LIST_NULL);
547
548 scbid = ahd_inw(ahd, COMPLETE_SCB_HEAD);
549 while (!SCBID_IS_NULL(scbid)) {
550
551 ahd_set_scbptr(ahd, scbid);
552 next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
553 scb = ahd_lookup_scb(ahd, scbid);
554 if (scb == NULL) {
555 printf("%s: Warning - Complete SCB %d invalid\n",
556 ahd_name(ahd), scbid);
557 continue;
558 }
559
560 ahd_complete_scb(ahd, scb);
561 scbid = next_scbid;
562 }
563 ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL);
564
565
566
567
568 ahd_set_scbptr(ahd, saved_scbptr);
569 ahd_restore_modes(ahd, saved_modes);
570 ahd->flags |= AHD_UPDATE_PEND_CMDS;
571}
572
573
574
575
576
577static int
578ahd_scb_active_in_fifo(struct ahd_softc *ahd, struct scb *scb)
579{
580
581
582
583
584
585
586
587 if (ahd_get_scbptr(ahd) != SCB_GET_TAG(scb)
588 || ((ahd_inb(ahd, LONGJMP_ADDR+1) & INVALID_ADDR) != 0
589 && (ahd_inb(ahd, SEQINTSRC) & (CFG4DATA|SAVEPTRS)) == 0))
590 return (0);
591
592 return (1);
593}
594
595
596
597
598
599
600
601
602
603
604
605
606static void
607ahd_run_data_fifo(struct ahd_softc *ahd, struct scb *scb)
608{
609 u_int seqintsrc;
610
611 seqintsrc = ahd_inb(ahd, SEQINTSRC);
612 if ((seqintsrc & CFG4DATA) != 0) {
613 uint32_t datacnt;
614 uint32_t sgptr;
615
616
617
618
619 sgptr = ahd_inl_scbram(ahd, SCB_SGPTR) & ~SG_FULL_RESID;
620 ahd_outb(ahd, SCB_SGPTR, sgptr);
621
622
623
624
625 datacnt = ahd_inl_scbram(ahd, SCB_DATACNT);
626 if ((datacnt & AHD_DMA_LAST_SEG) != 0) {
627 sgptr |= LAST_SEG;
628 ahd_outb(ahd, SG_STATE, 0);
629 } else
630 ahd_outb(ahd, SG_STATE, LOADING_NEEDED);
631 ahd_outq(ahd, HADDR, ahd_inq_scbram(ahd, SCB_DATAPTR));
632 ahd_outl(ahd, HCNT, datacnt & AHD_SG_LEN_MASK);
633 ahd_outb(ahd, SG_CACHE_PRE, sgptr);
634 ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN);
635
636
637
638
639 ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, datacnt >> 24);
640 ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr & SG_PTR_MASK);
641
642
643
644
645 ahd_outb(ahd, SCB_FIFO_USE_COUNT,
646 ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) + 1);
647
648
649
650
651 ahd_outw(ahd, LONGJMP_ADDR, 0);
652
653
654
655
656
657 ahd_outb(ahd, CLRSEQINTSRC, CLRCFG4DATA);
658 } else if ((seqintsrc & SAVEPTRS) != 0) {
659 uint32_t sgptr;
660 uint32_t resid;
661
662 if ((ahd_inb(ahd, LONGJMP_ADDR+1)&INVALID_ADDR) != 0) {
663
664
665
666
667
668 goto clrchn;
669 }
670
671
672
673
674
675 if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0)
676 ahd_outb(ahd, CCSGCTL, 0);
677 ahd_outb(ahd, SG_STATE, 0);
678
679
680
681
682
683 ahd_outb(ahd, DFCNTRL, ahd_inb(ahd, DFCNTRL) | FIFOFLUSH);
684
685
686
687
688 sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
689 resid = ahd_inl(ahd, SHCNT);
690 resid |= ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24;
691 ahd_outl(ahd, SCB_RESIDUAL_DATACNT, resid);
692 if ((ahd_inb(ahd, SG_CACHE_SHADOW) & LAST_SEG) == 0) {
693
694
695
696
697
698
699
700 if ((ahd_inb(ahd, SG_CACHE_SHADOW) & 0x80) != 0
701 && (sgptr & 0x80) == 0)
702 sgptr -= 0x100;
703 sgptr &= ~0xFF;
704 sgptr |= ahd_inb(ahd, SG_CACHE_SHADOW)
705 & SG_ADDR_MASK;
706 ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
707 ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, 0);
708 } else if ((resid & AHD_SG_LEN_MASK) == 0) {
709 ahd_outb(ahd, SCB_RESIDUAL_SGPTR,
710 sgptr | SG_LIST_NULL);
711 }
712
713
714
715 ahd_outq(ahd, SCB_DATAPTR, ahd_inq(ahd, SHADDR));
716 ahd_outl(ahd, SCB_DATACNT, resid);
717 ahd_outl(ahd, SCB_SGPTR, sgptr);
718 ahd_outb(ahd, CLRSEQINTSRC, CLRSAVEPTRS);
719 ahd_outb(ahd, SEQIMODE,
720 ahd_inb(ahd, SEQIMODE) | ENSAVEPTRS);
721
722
723
724
725 if ((ahd_inb(ahd, DFCNTRL) & DIRECTION) != 0)
726 goto clrchn;
727 } else if ((ahd_inb(ahd, SG_STATE) & LOADING_NEEDED) != 0) {
728 uint32_t sgptr;
729 uint64_t data_addr;
730 uint32_t data_len;
731 u_int dfcntrl;
732
733
734
735
736
737
738 if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) {
739 ahd_outb(ahd, CCSGCTL, 0);
740 ahd_outb(ahd, SG_STATE, LOADING_NEEDED);
741 }
742
743
744
745
746
747
748
749 if ((ahd_inb(ahd, DFSTATUS) & PRELOAD_AVAIL) != 0
750 && (ahd_inb(ahd, DFCNTRL) & HDMAENACK) != 0) {
751
752
753
754
755
756 sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
757 sgptr &= SG_PTR_MASK;
758 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
759 struct ahd_dma64_seg *sg;
760
761 sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
762 data_addr = sg->addr;
763 data_len = sg->len;
764 sgptr += sizeof(*sg);
765 } else {
766 struct ahd_dma_seg *sg;
767
768 sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
769 data_addr = sg->len & AHD_SG_HIGH_ADDR_MASK;
770 data_addr <<= 8;
771 data_addr |= sg->addr;
772 data_len = sg->len;
773 sgptr += sizeof(*sg);
774 }
775
776
777
778
779 ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, data_len >> 24);
780 ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
781
782
783
784
785 if (data_len & AHD_DMA_LAST_SEG) {
786 sgptr |= LAST_SEG;
787 ahd_outb(ahd, SG_STATE, 0);
788 }
789 ahd_outq(ahd, HADDR, data_addr);
790 ahd_outl(ahd, HCNT, data_len & AHD_SG_LEN_MASK);
791 ahd_outb(ahd, SG_CACHE_PRE, sgptr & 0xFF);
792
793
794
795
796 dfcntrl = ahd_inb(ahd, DFCNTRL)|PRELOADEN|HDMAEN;
797 if ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0) {
798
799
800
801
802
803 dfcntrl |= SCSIENWRDIS;
804 }
805 ahd_outb(ahd, DFCNTRL, dfcntrl);
806 }
807 } else if ((ahd_inb(ahd, SG_CACHE_SHADOW) & LAST_SEG_DONE) != 0) {
808
809
810
811
812
813 ahd_outb(ahd, SCB_SGPTR,
814 ahd_inb_scbram(ahd, SCB_SGPTR) | SG_LIST_NULL);
815 goto clrchn;
816 } else if ((ahd_inb(ahd, DFSTATUS) & FIFOEMP) != 0) {
817clrchn:
818
819
820
821
822
823 ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
824 ahd_outb(ahd, SCB_FIFO_USE_COUNT,
825 ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) - 1);
826 ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
827 }
828}
829
830
831
832
833
834
835
836
837
838
839
840void
841ahd_run_qoutfifo(struct ahd_softc *ahd)
842{
843 struct ahd_completion *completion;
844 struct scb *scb;
845 u_int scb_index;
846
847 if ((ahd->flags & AHD_RUNNING_QOUTFIFO) != 0)
848 panic("ahd_run_qoutfifo recursion");
849 ahd->flags |= AHD_RUNNING_QOUTFIFO;
850 ahd_sync_qoutfifo(ahd, BUS_DMASYNC_POSTREAD);
851 for (;;) {
852 completion = &ahd->qoutfifo[ahd->qoutfifonext];
853
854 if (completion->valid_tag != ahd->qoutfifonext_valid_tag)
855 break;
856
857 scb_index = ahd_le16toh(completion->tag);
858 scb = ahd_lookup_scb(ahd, scb_index);
859 if (scb == NULL) {
860 printf("%s: WARNING no command for scb %d "
861 "(cmdcmplt)\nQOUTPOS = %d\n",
862 ahd_name(ahd), scb_index,
863 ahd->qoutfifonext);
864 ahd_dump_card_state(ahd);
865 } else if ((completion->sg_status & SG_STATUS_VALID) != 0) {
866 ahd_handle_scb_status(ahd, scb);
867 } else {
868 ahd_done(ahd, scb);
869 }
870
871 ahd->qoutfifonext = (ahd->qoutfifonext+1) & (AHD_QOUT_SIZE-1);
872 if (ahd->qoutfifonext == 0)
873 ahd->qoutfifonext_valid_tag ^= QOUTFIFO_ENTRY_VALID;
874 }
875 ahd->flags &= ~AHD_RUNNING_QOUTFIFO;
876}
877
878
879void
880ahd_handle_hwerrint(struct ahd_softc *ahd)
881{
882
883
884
885
886 int i;
887 int error;
888
889 error = ahd_inb(ahd, ERROR);
890 for (i = 0; i < num_errors; i++) {
891 if ((error & ahd_hard_errors[i].errno) != 0)
892 printf("%s: hwerrint, %s\n",
893 ahd_name(ahd), ahd_hard_errors[i].errmesg);
894 }
895
896 ahd_dump_card_state(ahd);
897 panic("BRKADRINT");
898
899
900 ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
901 CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
902 CAM_NO_HBA);
903
904
905 ahd_free(ahd);
906}
907
908void
909ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
910{
911 u_int seqintcode;
912
913
914
915
916
917
918 seqintcode = ahd_inb(ahd, SEQINTCODE);
919 ahd_outb(ahd, CLRINT, CLRSEQINT);
920 if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) {
921
922
923
924
925
926
927 ahd_unpause(ahd);
928 while (!ahd_is_paused(ahd))
929 ;
930 ahd_outb(ahd, CLRINT, CLRSEQINT);
931 }
932 ahd_update_modes(ahd);
933#ifdef AHD_DEBUG
934 if ((ahd_debug & AHD_SHOW_MISC) != 0)
935 printf("%s: Handle Seqint Called for code %d\n",
936 ahd_name(ahd), seqintcode);
937#endif
938 switch (seqintcode) {
939 case ENTERING_NONPACK:
940 {
941 struct scb *scb;
942 u_int scbid;
943
944 AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
945 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
946 scbid = ahd_get_scbptr(ahd);
947 scb = ahd_lookup_scb(ahd, scbid);
948 if (scb == NULL) {
949
950
951
952
953
954
955 } else {
956 ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid);
957 ahd_outb(ahd, SAVED_LUN, scb->hscb->lun);
958 ahd_outb(ahd, SEQ_FLAGS, 0x0);
959 }
960 if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0
961 && (ahd_inb(ahd, SCSISIGO) & ATNO) != 0) {
962
963
964
965
966
967#ifdef AHD_DEBUG
968 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
969 printf("%s: Assuming LQIPHASE_NLQ with "
970 "P0 assertion\n", ahd_name(ahd));
971#endif
972 }
973#ifdef AHD_DEBUG
974 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
975 printf("%s: Entering NONPACK\n", ahd_name(ahd));
976#endif
977 break;
978 }
979 case INVALID_SEQINT:
980 printf("%s: Invalid Sequencer interrupt occurred, "
981 "resetting channel.\n",
982 ahd_name(ahd));
983#ifdef AHD_DEBUG
984 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
985 ahd_dump_card_state(ahd);
986#endif
987 ahd_reset_channel(ahd, 'A', TRUE);
988 break;
989 case STATUS_OVERRUN:
990 {
991 struct scb *scb;
992 u_int scbid;
993
994 scbid = ahd_get_scbptr(ahd);
995 scb = ahd_lookup_scb(ahd, scbid);
996 if (scb != NULL)
997 ahd_print_path(ahd, scb);
998 else
999 printf("%s: ", ahd_name(ahd));
1000 printf("SCB %d Packetized Status Overrun", scbid);
1001 ahd_dump_card_state(ahd);
1002 ahd_reset_channel(ahd, 'A', TRUE);
1003 break;
1004 }
1005 case CFG4ISTAT_INTR:
1006 {
1007 struct scb *scb;
1008 u_int scbid;
1009
1010 scbid = ahd_get_scbptr(ahd);
1011 scb = ahd_lookup_scb(ahd, scbid);
1012 if (scb == NULL) {
1013 ahd_dump_card_state(ahd);
1014 printf("CFG4ISTAT: Free SCB %d referenced", scbid);
1015 panic("For safety");
1016 }
1017 ahd_outq(ahd, HADDR, scb->sense_busaddr);
1018 ahd_outw(ahd, HCNT, AHD_SENSE_BUFSIZE);
1019 ahd_outb(ahd, HCNT + 2, 0);
1020 ahd_outb(ahd, SG_CACHE_PRE, SG_LAST_SEG);
1021 ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN);
1022 break;
1023 }
1024 case ILLEGAL_PHASE:
1025 {
1026 u_int bus_phase;
1027
1028 bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
1029 printf("%s: ILLEGAL_PHASE 0x%x\n",
1030 ahd_name(ahd), bus_phase);
1031
1032 switch (bus_phase) {
1033 case P_DATAOUT:
1034 case P_DATAIN:
1035 case P_DATAOUT_DT:
1036 case P_DATAIN_DT:
1037 case P_MESGOUT:
1038 case P_STATUS:
1039 case P_MESGIN:
1040 ahd_reset_channel(ahd, 'A', TRUE);
1041 printf("%s: Issued Bus Reset.\n", ahd_name(ahd));
1042 break;
1043 case P_COMMAND:
1044 {
1045 struct ahd_devinfo devinfo;
1046 struct scb *scb;
1047 struct ahd_initiator_tinfo *targ_info;
1048 struct ahd_tmode_tstate *tstate;
1049 struct ahd_transinfo *tinfo;
1050 u_int scbid;
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061 scbid = ahd_get_scbptr(ahd);
1062 scb = ahd_lookup_scb(ahd, scbid);
1063 if (scb == NULL) {
1064 printf("Invalid phase with no valid SCB. "
1065 "Resetting bus.\n");
1066 ahd_reset_channel(ahd, 'A',
1067 TRUE);
1068 break;
1069 }
1070 ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb),
1071 SCB_GET_TARGET(ahd, scb),
1072 SCB_GET_LUN(scb),
1073 SCB_GET_CHANNEL(ahd, scb),
1074 ROLE_INITIATOR);
1075 targ_info = ahd_fetch_transinfo(ahd,
1076 devinfo.channel,
1077 devinfo.our_scsiid,
1078 devinfo.target,
1079 &tstate);
1080 tinfo = &targ_info->curr;
1081 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
1082 AHD_TRANS_ACTIVE, TRUE);
1083 ahd_set_syncrate(ahd, &devinfo, 0,
1084 0, 0,
1085 AHD_TRANS_ACTIVE, TRUE);
1086 scb->flags |= SCB_EXTERNAL_RESET;
1087 ahd_freeze_devq(ahd, scb);
1088 ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
1089 ahd_freeze_scb(scb);
1090
1091
1092 ahd_send_async(ahd, devinfo.channel, devinfo.target,
1093 CAM_LUN_WILDCARD, AC_SENT_BDR);
1094
1095
1096
1097
1098
1099 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1100 ahd_outb(ahd, CLRLQOINT1, CLRLQOPHACHGINPKT);
1101 if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {
1102 ahd_outb(ahd, CLRLQOINT1, 0);
1103 }
1104#ifdef AHD_DEBUG
1105 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1106 ahd_print_path(ahd, scb);
1107 printf("Unexpected command phase from "
1108 "packetized target\n");
1109 }
1110#endif
1111 break;
1112 }
1113 }
1114 break;
1115 }
1116 case CFG4OVERRUN:
1117 {
1118 struct scb *scb;
1119 u_int scb_index;
1120
1121#ifdef AHD_DEBUG
1122 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1123 printf("%s: CFG4OVERRUN mode = %x\n", ahd_name(ahd),
1124 ahd_inb(ahd, MODE_PTR));
1125 }
1126#endif
1127 scb_index = ahd_get_scbptr(ahd);
1128 scb = ahd_lookup_scb(ahd, scb_index);
1129 if (scb == NULL) {
1130
1131
1132
1133
1134 ahd_assert_atn(ahd);
1135 ahd_outb(ahd, MSG_OUT, HOST_MSG);
1136 ahd->msgout_buf[0] = MSG_ABORT_TASK;
1137 ahd->msgout_len = 1;
1138 ahd->msgout_index = 0;
1139 ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
1140
1141
1142
1143
1144 ahd_outb(ahd, SCB_CONTROL,
1145 ahd_inb_scbram(ahd, SCB_CONTROL)
1146 & ~STATUS_RCVD);
1147 }
1148 break;
1149 }
1150 case DUMP_CARD_STATE:
1151 {
1152 ahd_dump_card_state(ahd);
1153 break;
1154 }
1155 case PDATA_REINIT:
1156 {
1157#ifdef AHD_DEBUG
1158 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1159 printf("%s: PDATA_REINIT - DFCNTRL = 0x%x "
1160 "SG_CACHE_SHADOW = 0x%x\n",
1161 ahd_name(ahd), ahd_inb(ahd, DFCNTRL),
1162 ahd_inb(ahd, SG_CACHE_SHADOW));
1163 }
1164#endif
1165 ahd_reinitialize_dataptrs(ahd);
1166 break;
1167 }
1168 case HOST_MSG_LOOP:
1169 {
1170 struct ahd_devinfo devinfo;
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183 ahd_fetch_devinfo(ahd, &devinfo);
1184 if (ahd->msg_type == MSG_TYPE_NONE) {
1185 struct scb *scb;
1186 u_int scb_index;
1187 u_int bus_phase;
1188
1189 bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
1190 if (bus_phase != P_MESGIN
1191 && bus_phase != P_MESGOUT) {
1192 printf("ahd_intr: HOST_MSG_LOOP bad "
1193 "phase 0x%x\n", bus_phase);
1194
1195
1196
1197
1198 ahd_dump_card_state(ahd);
1199 ahd_clear_intstat(ahd);
1200 ahd_restart(ahd);
1201 return;
1202 }
1203
1204 scb_index = ahd_get_scbptr(ahd);
1205 scb = ahd_lookup_scb(ahd, scb_index);
1206 if (devinfo.role == ROLE_INITIATOR) {
1207 if (bus_phase == P_MESGOUT)
1208 ahd_setup_initiator_msgout(ahd,
1209 &devinfo,
1210 scb);
1211 else {
1212 ahd->msg_type =
1213 MSG_TYPE_INITIATOR_MSGIN;
1214 ahd->msgin_index = 0;
1215 }
1216 }
1217#ifdef AHD_TARGET_MODE
1218 else {
1219 if (bus_phase == P_MESGOUT) {
1220 ahd->msg_type =
1221 MSG_TYPE_TARGET_MSGOUT;
1222 ahd->msgin_index = 0;
1223 }
1224 else
1225 ahd_setup_target_msgin(ahd,
1226 &devinfo,
1227 scb);
1228 }
1229#endif
1230 }
1231
1232 ahd_handle_message_phase(ahd);
1233 break;
1234 }
1235 case NO_MATCH:
1236 {
1237
1238 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
1239 ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
1240
1241 printf("%s:%c:%d: no active SCB for reconnecting "
1242 "target - issuing BUS DEVICE RESET\n",
1243 ahd_name(ahd), 'A', ahd_inb(ahd, SELID) >> 4);
1244 printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
1245 "REG0 == 0x%x ACCUM = 0x%x\n",
1246 ahd_inb(ahd, SAVED_SCSIID), ahd_inb(ahd, SAVED_LUN),
1247 ahd_inw(ahd, REG0), ahd_inb(ahd, ACCUM));
1248 printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
1249 "SINDEX == 0x%x\n",
1250 ahd_inb(ahd, SEQ_FLAGS), ahd_get_scbptr(ahd),
1251 ahd_find_busy_tcl(ahd,
1252 BUILD_TCL(ahd_inb(ahd, SAVED_SCSIID),
1253 ahd_inb(ahd, SAVED_LUN))),
1254 ahd_inw(ahd, SINDEX));
1255 printf("SELID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
1256 "SCB_CONTROL == 0x%x\n",
1257 ahd_inb(ahd, SELID), ahd_inb_scbram(ahd, SCB_SCSIID),
1258 ahd_inb_scbram(ahd, SCB_LUN),
1259 ahd_inb_scbram(ahd, SCB_CONTROL));
1260 printf("SCSIBUS[0] == 0x%x, SCSISIGI == 0x%x\n",
1261 ahd_inb(ahd, SCSIBUS), ahd_inb(ahd, SCSISIGI));
1262 printf("SXFRCTL0 == 0x%x\n", ahd_inb(ahd, SXFRCTL0));
1263 printf("SEQCTL0 == 0x%x\n", ahd_inb(ahd, SEQCTL0));
1264 ahd_dump_card_state(ahd);
1265 ahd->msgout_buf[0] = MSG_BUS_DEV_RESET;
1266 ahd->msgout_len = 1;
1267 ahd->msgout_index = 0;
1268 ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
1269 ahd_outb(ahd, MSG_OUT, HOST_MSG);
1270 ahd_assert_atn(ahd);
1271 break;
1272 }
1273 case PROTO_VIOLATION:
1274 {
1275 ahd_handle_proto_violation(ahd);
1276 break;
1277 }
1278 case IGN_WIDE_RES:
1279 {
1280 struct ahd_devinfo devinfo;
1281
1282 ahd_fetch_devinfo(ahd, &devinfo);
1283 ahd_handle_ign_wide_residue(ahd, &devinfo);
1284 break;
1285 }
1286 case BAD_PHASE:
1287 {
1288 u_int lastphase;
1289
1290 lastphase = ahd_inb(ahd, LASTPHASE);
1291 printf("%s:%c:%d: unknown scsi bus phase %x, "
1292 "lastphase = 0x%x. Attempting to continue\n",
1293 ahd_name(ahd), 'A',
1294 SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)),
1295 lastphase, ahd_inb(ahd, SCSISIGI));
1296 break;
1297 }
1298 case MISSED_BUSFREE:
1299 {
1300 u_int lastphase;
1301
1302 lastphase = ahd_inb(ahd, LASTPHASE);
1303 printf("%s:%c:%d: Missed busfree. "
1304 "Lastphase = 0x%x, Curphase = 0x%x\n",
1305 ahd_name(ahd), 'A',
1306 SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)),
1307 lastphase, ahd_inb(ahd, SCSISIGI));
1308 ahd_restart(ahd);
1309 return;
1310 }
1311 case DATA_OVERRUN:
1312 {
1313
1314
1315
1316
1317
1318
1319
1320
1321 struct scb *scb;
1322 u_int scbindex;
1323#ifdef AHD_DEBUG
1324 u_int lastphase;
1325#endif
1326
1327 scbindex = ahd_get_scbptr(ahd);
1328 scb = ahd_lookup_scb(ahd, scbindex);
1329#ifdef AHD_DEBUG
1330 lastphase = ahd_inb(ahd, LASTPHASE);
1331 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1332 ahd_print_path(ahd, scb);
1333 printf("data overrun detected %s. Tag == 0x%x.\n",
1334 ahd_lookup_phase_entry(lastphase)->phasemsg,
1335 SCB_GET_TAG(scb));
1336 ahd_print_path(ahd, scb);
1337 printf("%s seen Data Phase. Length = %ld. "
1338 "NumSGs = %d.\n",
1339 ahd_inb(ahd, SEQ_FLAGS) & DPHASE
1340 ? "Have" : "Haven't",
1341 ahd_get_transfer_length(scb), scb->sg_count);
1342 ahd_dump_sglist(scb);
1343 }
1344#endif
1345
1346
1347
1348
1349
1350 ahd_freeze_devq(ahd, scb);
1351 ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
1352 ahd_freeze_scb(scb);
1353 break;
1354 }
1355 case MKMSG_FAILED:
1356 {
1357 struct ahd_devinfo devinfo;
1358 struct scb *scb;
1359 u_int scbid;
1360
1361 ahd_fetch_devinfo(ahd, &devinfo);
1362 printf("%s:%c:%d:%d: Attempt to issue message failed\n",
1363 ahd_name(ahd), devinfo.channel, devinfo.target,
1364 devinfo.lun);
1365 scbid = ahd_get_scbptr(ahd);
1366 scb = ahd_lookup_scb(ahd, scbid);
1367 if (scb != NULL
1368 && (scb->flags & SCB_RECOVERY_SCB) != 0)
1369
1370
1371
1372
1373 ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
1374 SCB_GET_CHANNEL(ahd, scb),
1375 SCB_GET_LUN(scb), SCB_GET_TAG(scb),
1376 ROLE_INITIATOR, 0,
1377 SEARCH_REMOVE);
1378 ahd_outb(ahd, SCB_CONTROL,
1379 ahd_inb_scbram(ahd, SCB_CONTROL) & ~MK_MESSAGE);
1380 break;
1381 }
1382 case TASKMGMT_FUNC_COMPLETE:
1383 {
1384 u_int scbid;
1385 struct scb *scb;
1386
1387 scbid = ahd_get_scbptr(ahd);
1388 scb = ahd_lookup_scb(ahd, scbid);
1389 if (scb != NULL) {
1390 u_int lun;
1391 u_int tag;
1392 cam_status error;
1393
1394 ahd_print_path(ahd, scb);
1395 printf("Task Management Func 0x%x Complete\n",
1396 scb->hscb->task_management);
1397 lun = CAM_LUN_WILDCARD;
1398 tag = SCB_LIST_NULL;
1399
1400 switch (scb->hscb->task_management) {
1401 case SIU_TASKMGMT_ABORT_TASK:
1402 tag = SCB_GET_TAG(scb);
1403 case SIU_TASKMGMT_ABORT_TASK_SET:
1404 case SIU_TASKMGMT_CLEAR_TASK_SET:
1405 lun = scb->hscb->lun;
1406 error = CAM_REQ_ABORTED;
1407 ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
1408 'A', lun, tag, ROLE_INITIATOR,
1409 error);
1410 break;
1411 case SIU_TASKMGMT_LUN_RESET:
1412 lun = scb->hscb->lun;
1413 case SIU_TASKMGMT_TARGET_RESET:
1414 {
1415 struct ahd_devinfo devinfo;
1416
1417 ahd_scb_devinfo(ahd, &devinfo, scb);
1418 error = CAM_BDR_SENT;
1419 ahd_handle_devreset(ahd, &devinfo, lun,
1420 CAM_BDR_SENT,
1421 lun != CAM_LUN_WILDCARD
1422 ? "Lun Reset"
1423 : "Target Reset",
1424 0);
1425 break;
1426 }
1427 default:
1428 panic("Unexpected TaskMgmt Func\n");
1429 break;
1430 }
1431 }
1432 break;
1433 }
1434 case TASKMGMT_CMD_CMPLT_OKAY:
1435 {
1436 u_int scbid;
1437 struct scb *scb;
1438
1439
1440
1441
1442
1443 scbid = ahd_get_scbptr(ahd);
1444 scb = ahd_lookup_scb(ahd, scbid);
1445 if (scb != NULL) {
1446
1447
1448
1449
1450 ahd_print_path(ahd, scb);
1451 printf("SCB completes before TMF\n");
1452
1453
1454
1455
1456
1457
1458
1459 while ((ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0
1460 && (ahd_inb(ahd, SSTAT0) & SELDO) == 0
1461 && (ahd_inb(ahd, SSTAT1) & SELTO) == 0)
1462 ;
1463 ahd_outb(ahd, SCB_TASK_MANAGEMENT, 0);
1464 ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
1465 SCB_GET_CHANNEL(ahd, scb),
1466 SCB_GET_LUN(scb), SCB_GET_TAG(scb),
1467 ROLE_INITIATOR, 0,
1468 SEARCH_REMOVE);
1469 }
1470 break;
1471 }
1472 case TRACEPOINT0:
1473 case TRACEPOINT1:
1474 case TRACEPOINT2:
1475 case TRACEPOINT3:
1476 printf("%s: Tracepoint %d\n", ahd_name(ahd),
1477 seqintcode - TRACEPOINT0);
1478 break;
1479 case NO_SEQINT:
1480 break;
1481 case SAW_HWERR:
1482 ahd_handle_hwerrint(ahd);
1483 break;
1484 default:
1485 printf("%s: Unexpected SEQINTCODE %d\n", ahd_name(ahd),
1486 seqintcode);
1487 break;
1488 }
1489
1490
1491
1492
1493
1494 ahd_unpause(ahd);
1495}
1496
1497void
1498ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
1499{
1500 struct scb *scb;
1501 u_int status0;
1502 u_int status3;
1503 u_int status;
1504 u_int lqistat1;
1505 u_int lqostat0;
1506 u_int scbid;
1507 u_int busfreetime;
1508
1509 ahd_update_modes(ahd);
1510 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1511
1512 status3 = ahd_inb(ahd, SSTAT3) & (NTRAMPERR|OSRAMPERR);
1513 status0 = ahd_inb(ahd, SSTAT0) & (IOERR|OVERRUN|SELDI|SELDO);
1514 status = ahd_inb(ahd, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
1515 lqistat1 = ahd_inb(ahd, LQISTAT1);
1516 lqostat0 = ahd_inb(ahd, LQOSTAT0);
1517 busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME;
1518
1519
1520
1521
1522 if (((status & SCSIRSTI) != 0) && (ahd->flags & AHD_BUS_RESET_ACTIVE))
1523 return;
1524
1525
1526
1527
1528 ahd->flags &= ~AHD_BUS_RESET_ACTIVE;
1529
1530 if ((status0 & (SELDI|SELDO)) != 0) {
1531 u_int simode0;
1532
1533 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
1534 simode0 = ahd_inb(ahd, SIMODE0);
1535 status0 &= simode0 & (IOERR|OVERRUN|SELDI|SELDO);
1536 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1537 }
1538 scbid = ahd_get_scbptr(ahd);
1539 scb = ahd_lookup_scb(ahd, scbid);
1540 if (scb != NULL
1541 && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
1542 scb = NULL;
1543
1544 if ((status0 & IOERR) != 0) {
1545 u_int now_lvd;
1546
1547 now_lvd = ahd_inb(ahd, SBLKCTL) & ENAB40;
1548 printf("%s: Transceiver State Has Changed to %s mode\n",
1549 ahd_name(ahd), now_lvd ? "LVD" : "SE");
1550 ahd_outb(ahd, CLRSINT0, CLRIOERR);
1551
1552
1553
1554 ahd_reset_channel(ahd, 'A', TRUE);
1555 ahd_pause(ahd);
1556 ahd_setup_iocell_workaround(ahd);
1557 ahd_unpause(ahd);
1558 } else if ((status0 & OVERRUN) != 0) {
1559
1560 printf("%s: SCSI offset overrun detected. Resetting bus.\n",
1561 ahd_name(ahd));
1562 ahd_reset_channel(ahd, 'A', TRUE);
1563 } else if ((status & SCSIRSTI) != 0) {
1564
1565 printf("%s: Someone reset channel A\n", ahd_name(ahd));
1566 ahd_reset_channel(ahd, 'A', FALSE);
1567 } else if ((status & SCSIPERR) != 0) {
1568
1569
1570 ahd_clear_critical_section(ahd);
1571
1572 ahd_handle_transmission_error(ahd);
1573 } else if (lqostat0 != 0) {
1574
1575 printf("%s: lqostat0 == 0x%x!\n", ahd_name(ahd), lqostat0);
1576 ahd_outb(ahd, CLRLQOINT0, lqostat0);
1577 if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0)
1578 ahd_outb(ahd, CLRLQOINT1, 0);
1579 } else if ((status & SELTO) != 0) {
1580 u_int scbid;
1581
1582
1583 ahd_outb(ahd, SCSISEQ0, 0);
1584
1585
1586 ahd_clear_critical_section(ahd);
1587
1588
1589 ahd_clear_msg_state(ahd);
1590
1591
1592 ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602 ahd_outb(ahd, CLRSINT0, CLRSELINGO);
1603
1604 scbid = ahd_inw(ahd, WAITING_TID_HEAD);
1605 scb = ahd_lookup_scb(ahd, scbid);
1606 if (scb == NULL) {
1607 printf("%s: ahd_intr - referenced scb not "
1608 "valid during SELTO scb(0x%x)\n",
1609 ahd_name(ahd), scbid);
1610 ahd_dump_card_state(ahd);
1611 } else {
1612 struct ahd_devinfo devinfo;
1613#ifdef AHD_DEBUG
1614 if ((ahd_debug & AHD_SHOW_SELTO) != 0) {
1615 ahd_print_path(ahd, scb);
1616 printf("Saw Selection Timeout for SCB 0x%x\n",
1617 scbid);
1618 }
1619#endif
1620 ahd_scb_devinfo(ahd, &devinfo, scb);
1621 ahd_set_transaction_status(scb, CAM_SEL_TIMEOUT);
1622 ahd_freeze_devq(ahd, scb);
1623
1624
1625
1626
1627
1628
1629
1630 ahd_handle_devreset(ahd, &devinfo,
1631 CAM_LUN_WILDCARD,
1632 CAM_SEL_TIMEOUT,
1633 "Selection Timeout",
1634 1);
1635 }
1636 ahd_outb(ahd, CLRINT, CLRSCSIINT);
1637 ahd_iocell_first_selection(ahd);
1638 ahd_unpause(ahd);
1639 } else if ((status0 & (SELDI|SELDO)) != 0) {
1640
1641 ahd_iocell_first_selection(ahd);
1642 ahd_unpause(ahd);
1643 } else if (status3 != 0) {
1644 printf("%s: SCSI Cell parity error SSTAT3 == 0x%x\n",
1645 ahd_name(ahd), status3);
1646 ahd_outb(ahd, CLRSINT3, status3);
1647 } else if ((lqistat1 & (LQIPHASE_LQ|LQIPHASE_NLQ)) != 0) {
1648
1649
1650 ahd_clear_critical_section(ahd);
1651
1652 ahd_handle_lqiphase_error(ahd, lqistat1);
1653 } else if ((lqistat1 & LQICRCI_NLQ) != 0) {
1654
1655
1656
1657
1658
1659
1660 ahd_outb(ahd, CLRLQIINT1, CLRLQICRCI_NLQ);
1661 } else if ((status & BUSFREE) != 0
1662 || (lqistat1 & LQOBUSFREE) != 0) {
1663 u_int lqostat1;
1664 int restart;
1665 int clear_fifo;
1666 int packetized;
1667 u_int mode;
1668
1669
1670
1671
1672
1673
1674
1675 ahd_outb(ahd, SCSISEQ0, 0);
1676
1677
1678 ahd_clear_critical_section(ahd);
1679
1680
1681
1682
1683
1684 mode = AHD_MODE_SCSI;
1685 busfreetime = ahd_inb(ahd, SSTAT2) & BUSFREETIME;
1686 lqostat1 = ahd_inb(ahd, LQOSTAT1);
1687 switch (busfreetime) {
1688 case BUSFREE_DFF0:
1689 case BUSFREE_DFF1:
1690 {
1691 u_int scbid;
1692 struct scb *scb;
1693
1694 mode = busfreetime == BUSFREE_DFF0
1695 ? AHD_MODE_DFF0 : AHD_MODE_DFF1;
1696 ahd_set_modes(ahd, mode, mode);
1697 scbid = ahd_get_scbptr(ahd);
1698 scb = ahd_lookup_scb(ahd, scbid);
1699 if (scb == NULL) {
1700 printf("%s: Invalid SCB %d in DFF%d "
1701 "during unexpected busfree\n",
1702 ahd_name(ahd), scbid, mode);
1703 packetized = 0;
1704 } else
1705 packetized = (scb->flags & SCB_PACKETIZED) != 0;
1706 clear_fifo = 1;
1707 break;
1708 }
1709 case BUSFREE_LQO:
1710 clear_fifo = 0;
1711 packetized = 1;
1712 break;
1713 default:
1714 clear_fifo = 0;
1715 packetized = (lqostat1 & LQOBUSFREE) != 0;
1716 if (!packetized
1717 && ahd_inb(ahd, LASTPHASE) == P_BUSFREE
1718 && (ahd_inb(ahd, SSTAT0) & SELDI) == 0
1719 && ((ahd_inb(ahd, SSTAT0) & SELDO) == 0
1720 || (ahd_inb(ahd, SCSISEQ0) & ENSELO) == 0))
1721
1722
1723
1724
1725
1726
1727 packetized = 1;
1728 break;
1729 }
1730
1731#ifdef AHD_DEBUG
1732 if ((ahd_debug & AHD_SHOW_MISC) != 0)
1733 printf("Saw Busfree. Busfreetime = 0x%x.\n",
1734 busfreetime);
1735#endif
1736
1737
1738
1739
1740 if (packetized && ahd_inb(ahd, LASTPHASE) == P_BUSFREE) {
1741 restart = ahd_handle_pkt_busfree(ahd, busfreetime);
1742 } else {
1743 packetized = 0;
1744 restart = ahd_handle_nonpkt_busfree(ahd);
1745 }
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757 ahd_outb(ahd, CLRSINT1, CLRBUSFREE);
1758 if (packetized == 0
1759 && (ahd->bugs & AHD_BUSFREEREV_BUG) != 0)
1760 ahd_outb(ahd, SIMODE1,
1761 ahd_inb(ahd, SIMODE1) & ~ENBUSFREE);
1762
1763 if (clear_fifo)
1764 ahd_clear_fifo(ahd, mode);
1765
1766 ahd_clear_msg_state(ahd);
1767 ahd_outb(ahd, CLRINT, CLRSCSIINT);
1768 if (restart) {
1769 ahd_restart(ahd);
1770 } else {
1771 ahd_unpause(ahd);
1772 }
1773 } else {
1774 printf("%s: Missing case in ahd_handle_scsiint. status = %x\n",
1775 ahd_name(ahd), status);
1776 ahd_dump_card_state(ahd);
1777 ahd_clear_intstat(ahd);
1778 ahd_unpause(ahd);
1779 }
1780}
1781
1782static void
1783ahd_handle_transmission_error(struct ahd_softc *ahd)
1784{
1785 struct scb *scb;
1786 u_int scbid;
1787 u_int lqistat1;
1788 u_int lqistat2;
1789 u_int msg_out;
1790 u_int curphase;
1791 u_int lastphase;
1792 u_int perrdiag;
1793 u_int cur_col;
1794 int silent;
1795
1796 scb = NULL;
1797 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1798 lqistat1 = ahd_inb(ahd, LQISTAT1) & ~(LQIPHASE_LQ|LQIPHASE_NLQ);
1799 lqistat2 = ahd_inb(ahd, LQISTAT2);
1800 if ((lqistat1 & (LQICRCI_NLQ|LQICRCI_LQ)) == 0
1801 && (ahd->bugs & AHD_NLQICRC_DELAYED_BUG) != 0) {
1802 u_int lqistate;
1803
1804 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
1805 lqistate = ahd_inb(ahd, LQISTATE);
1806 if ((lqistate >= 0x1E && lqistate <= 0x24)
1807 || (lqistate == 0x29)) {
1808#ifdef AHD_DEBUG
1809 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
1810 printf("%s: NLQCRC found via LQISTATE\n",
1811 ahd_name(ahd));
1812 }
1813#endif
1814 lqistat1 |= LQICRCI_NLQ;
1815 }
1816 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1817 }
1818
1819 ahd_outb(ahd, CLRLQIINT1, lqistat1);
1820 lastphase = ahd_inb(ahd, LASTPHASE);
1821 curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
1822 perrdiag = ahd_inb(ahd, PERRDIAG);
1823 msg_out = MSG_INITIATOR_DET_ERR;
1824 ahd_outb(ahd, CLRSINT1, CLRSCSIPERR);
1825
1826
1827
1828
1829 silent = FALSE;
1830 if (lqistat1 == 0
1831 || (lqistat1 & LQICRCI_NLQ) != 0) {
1832 if ((lqistat1 & (LQICRCI_NLQ|LQIOVERI_NLQ)) != 0)
1833 ahd_set_active_fifo(ahd);
1834 scbid = ahd_get_scbptr(ahd);
1835 scb = ahd_lookup_scb(ahd, scbid);
1836 if (scb != NULL && SCB_IS_SILENT(scb))
1837 silent = TRUE;
1838 }
1839
1840 cur_col = 0;
1841 if (silent == FALSE) {
1842 printf("%s: Transmission error detected\n", ahd_name(ahd));
1843 ahd_lqistat1_print(lqistat1, &cur_col, 50);
1844 ahd_lastphase_print(lastphase, &cur_col, 50);
1845 ahd_scsisigi_print(curphase, &cur_col, 50);
1846 ahd_perrdiag_print(perrdiag, &cur_col, 50);
1847 printf("\n");
1848 ahd_dump_card_state(ahd);
1849 }
1850
1851 if ((lqistat1 & (LQIOVERI_LQ|LQIOVERI_NLQ)) != 0) {
1852 if (silent == FALSE) {
1853 printf("%s: Gross protocol error during incoming "
1854 "packet. lqistat1 == 0x%x. Resetting bus.\n",
1855 ahd_name(ahd), lqistat1);
1856 }
1857 ahd_reset_channel(ahd, 'A', TRUE);
1858 return;
1859 } else if ((lqistat1 & LQICRCI_LQ) != 0) {
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881 ahd_outb(ahd, LQCTL2, LQIRETRY);
1882 printf("LQIRetry for LQICRCI_LQ to release ACK\n");
1883 } else if ((lqistat1 & LQICRCI_NLQ) != 0) {
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929 if (silent == FALSE)
1930 printf("LQICRC_NLQ\n");
1931 if (scb == NULL) {
1932 printf("%s: No SCB valid for LQICRC_NLQ. "
1933 "Resetting bus\n", ahd_name(ahd));
1934 ahd_reset_channel(ahd, 'A', TRUE);
1935 return;
1936 }
1937 } else if ((lqistat1 & LQIBADLQI) != 0) {
1938 printf("Need to handle BADLQI!\n");
1939 ahd_reset_channel(ahd, 'A', TRUE);
1940 return;
1941 } else if ((perrdiag & (PARITYERR|PREVPHASE)) == PARITYERR) {
1942 if ((curphase & ~P_DATAIN_DT) != 0) {
1943
1944 if (silent == FALSE)
1945 printf("Acking %s to clear perror\n",
1946 ahd_lookup_phase_entry(curphase)->phasemsg);
1947 ahd_inb(ahd, SCSIDAT);
1948 }
1949
1950 if (curphase == P_MESGIN)
1951 msg_out = MSG_PARITY_ERROR;
1952 }
1953
1954
1955
1956
1957
1958
1959
1960
1961 ahd->send_msg_perror = msg_out;
1962 if (scb != NULL && msg_out == MSG_INITIATOR_DET_ERR)
1963 scb->flags |= SCB_TRANSMISSION_ERROR;
1964 ahd_outb(ahd, MSG_OUT, HOST_MSG);
1965 ahd_outb(ahd, CLRINT, CLRSCSIINT);
1966 ahd_unpause(ahd);
1967}
1968
1969static void
1970ahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1)
1971{
1972
1973
1974
1975 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
1976 ahd_outb(ahd, CLRLQIINT1, lqistat1);
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986 ahd_set_active_fifo(ahd);
1987 if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0
1988 && (ahd_inb(ahd, MDFFSTAT) & DLZERO) != 0) {
1989 if ((lqistat1 & LQIPHASE_LQ) != 0) {
1990 printf("LQIRETRY for LQIPHASE_LQ\n");
1991 ahd_outb(ahd, LQCTL2, LQIRETRY);
1992 } else if ((lqistat1 & LQIPHASE_NLQ) != 0) {
1993 printf("LQIRETRY for LQIPHASE_NLQ\n");
1994 ahd_outb(ahd, LQCTL2, LQIRETRY);
1995 } else
1996 panic("ahd_handle_lqiphase_error: No phase errors\n");
1997 ahd_dump_card_state(ahd);
1998 ahd_outb(ahd, CLRINT, CLRSCSIINT);
1999 ahd_unpause(ahd);
2000 } else {
2001 printf("Reseting Channel for LQI Phase error\n");
2002 ahd_dump_card_state(ahd);
2003 ahd_reset_channel(ahd, 'A', TRUE);
2004 }
2005}
2006
2007
2008
2009
2010
2011static int
2012ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime)
2013{
2014 u_int lqostat1;
2015
2016 AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
2017 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
2018 lqostat1 = ahd_inb(ahd, LQOSTAT1);
2019 if ((lqostat1 & LQOBUSFREE) != 0) {
2020 struct scb *scb;
2021 u_int scbid;
2022 u_int saved_scbptr;
2023 u_int waiting_h;
2024 u_int waiting_t;
2025 u_int next;
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2043 scbid = ahd_inw(ahd, CURRSCB);
2044 scb = ahd_lookup_scb(ahd, scbid);
2045 if (scb == NULL)
2046 panic("SCB not valid during LQOBUSFREE");
2047
2048
2049
2050 ahd_outb(ahd, CLRLQOINT1, CLRLQOBUSFREE);
2051 if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0)
2052 ahd_outb(ahd, CLRLQOINT1, 0);
2053 ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
2054 ahd_flush_device_writes(ahd);
2055 ahd_outb(ahd, CLRSINT0, CLRSELDO);
2056
2057
2058
2059
2060
2061
2062
2063 ahd_outb(ahd, LQCTL2, ahd_inb(ahd, LQCTL2) | LQOTOIDLE);
2064
2065
2066
2067
2068
2069 waiting_h = ahd_inw(ahd, WAITING_TID_HEAD);
2070 saved_scbptr = ahd_get_scbptr(ahd);
2071 if (waiting_h != scbid) {
2072
2073 ahd_outw(ahd, WAITING_TID_HEAD, scbid);
2074 waiting_t = ahd_inw(ahd, WAITING_TID_TAIL);
2075 if (waiting_t == waiting_h) {
2076 ahd_outw(ahd, WAITING_TID_TAIL, scbid);
2077 next = SCB_LIST_NULL;
2078 } else {
2079 ahd_set_scbptr(ahd, waiting_h);
2080 next = ahd_inw_scbram(ahd, SCB_NEXT2);
2081 }
2082 ahd_set_scbptr(ahd, scbid);
2083 ahd_outw(ahd, SCB_NEXT2, next);
2084 }
2085 ahd_set_scbptr(ahd, saved_scbptr);
2086 if (scb->crc_retry_count < AHD_MAX_LQ_CRC_ERRORS) {
2087 if (SCB_IS_SILENT(scb) == FALSE) {
2088 ahd_print_path(ahd, scb);
2089 printf("Probable outgoing LQ CRC error. "
2090 "Retrying command\n");
2091 }
2092 scb->crc_retry_count++;
2093 } else {
2094 ahd_set_transaction_status(scb, CAM_UNCOR_PARITY);
2095 ahd_freeze_scb(scb);
2096 ahd_freeze_devq(ahd, scb);
2097 }
2098
2099 return (0);
2100 } else if ((ahd_inb(ahd, PERRDIAG) & PARITYERR) != 0) {
2101
2102
2103
2104
2105
2106
2107
2108 ahd_outb(ahd, CLRSINT1, CLRSCSIPERR|CLRBUSFREE);
2109#ifdef AHD_DEBUG
2110 if ((ahd_debug & AHD_SHOW_MASKED_ERRORS) != 0)
2111 printf("%s: Parity on last REQ detected "
2112 "during busfree phase.\n",
2113 ahd_name(ahd));
2114#endif
2115
2116 return (0);
2117 }
2118 if (ahd->src_mode != AHD_MODE_SCSI) {
2119 u_int scbid;
2120 struct scb *scb;
2121
2122 scbid = ahd_get_scbptr(ahd);
2123 scb = ahd_lookup_scb(ahd, scbid);
2124 ahd_print_path(ahd, scb);
2125 printf("Unexpected PKT busfree condition\n");
2126 ahd_dump_card_state(ahd);
2127 ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), 'A',
2128 SCB_GET_LUN(scb), SCB_GET_TAG(scb),
2129 ROLE_INITIATOR, CAM_UNEXP_BUSFREE);
2130
2131
2132 return (1);
2133 }
2134 printf("%s: Unexpected PKT busfree condition\n", ahd_name(ahd));
2135 ahd_dump_card_state(ahd);
2136
2137 return (1);
2138}
2139
2140
2141
2142
2143static int
2144ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
2145{
2146 struct ahd_devinfo devinfo;
2147 struct scb *scb;
2148 u_int lastphase;
2149 u_int saved_scsiid;
2150 u_int saved_lun;
2151 u_int target;
2152 u_int initiator_role_id;
2153 u_int scbid;
2154 u_int ppr_busfree;
2155 int printerror;
2156
2157
2158
2159
2160
2161
2162 lastphase = ahd_inb(ahd, LASTPHASE);
2163 saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
2164 saved_lun = ahd_inb(ahd, SAVED_LUN);
2165 target = SCSIID_TARGET(ahd, saved_scsiid);
2166 initiator_role_id = SCSIID_OUR_ID(saved_scsiid);
2167 ahd_compile_devinfo(&devinfo, initiator_role_id,
2168 target, saved_lun, 'A', ROLE_INITIATOR);
2169 printerror = 1;
2170
2171 scbid = ahd_get_scbptr(ahd);
2172 scb = ahd_lookup_scb(ahd, scbid);
2173 if (scb != NULL
2174 && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
2175 scb = NULL;
2176
2177 ppr_busfree = (ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0;
2178 if (lastphase == P_MESGOUT) {
2179 u_int tag;
2180
2181 tag = SCB_LIST_NULL;
2182 if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT_TAG, TRUE)
2183 || ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT, TRUE)) {
2184 int found;
2185 int sent_msg;
2186
2187 if (scb == NULL) {
2188 ahd_print_devinfo(ahd, &devinfo);
2189 printf("Abort for unidentified "
2190 "connection completed.\n");
2191
2192 return (1);
2193 }
2194 sent_msg = ahd->msgout_buf[ahd->msgout_index - 1];
2195 ahd_print_path(ahd, scb);
2196 printf("SCB %d - Abort%s Completed.\n",
2197 SCB_GET_TAG(scb),
2198 sent_msg == MSG_ABORT_TAG ? "" : " Tag");
2199
2200 if (sent_msg == MSG_ABORT_TAG)
2201 tag = SCB_GET_TAG(scb);
2202
2203 found = ahd_abort_scbs(ahd, target, 'A', saved_lun,
2204 tag, ROLE_INITIATOR,
2205 CAM_REQ_ABORTED);
2206 printf("found == 0x%x\n", found);
2207 printerror = 0;
2208 } else if (ahd_sent_msg(ahd, AHDMSG_1B,
2209 MSG_BUS_DEV_RESET, TRUE)) {
2210#ifdef __FreeBSD__
2211
2212
2213
2214
2215
2216 if (scb != NULL
2217 && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV
2218 && ahd_match_scb(ahd, scb, target, 'A',
2219 CAM_LUN_WILDCARD, SCB_LIST_NULL,
2220 ROLE_INITIATOR))
2221 ahd_set_transaction_status(scb, CAM_REQ_CMP);
2222#endif
2223 ahd_handle_devreset(ahd, &devinfo, CAM_LUN_WILDCARD,
2224 CAM_BDR_SENT, "Bus Device Reset",
2225 0);
2226 printerror = 0;
2227 } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE)
2228 && ppr_busfree == 0) {
2229 struct ahd_initiator_tinfo *tinfo;
2230 struct ahd_tmode_tstate *tstate;
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242#ifdef AHD_DEBUG
2243 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2244 printf("PPR negotiation rejected busfree.\n");
2245#endif
2246 tinfo = ahd_fetch_transinfo(ahd, devinfo.channel,
2247 devinfo.our_scsiid,
2248 devinfo.target, &tstate);
2249 if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ)!=0) {
2250 ahd_set_width(ahd, &devinfo,
2251 MSG_EXT_WDTR_BUS_8_BIT,
2252 AHD_TRANS_CUR,
2253 TRUE);
2254 ahd_set_syncrate(ahd, &devinfo,
2255 0, 0,
2256 0,
2257 AHD_TRANS_CUR,
2258 TRUE);
2259
2260
2261
2262
2263
2264 } else {
2265 tinfo->curr.transport_version = 2;
2266 tinfo->goal.transport_version = 2;
2267 tinfo->goal.ppr_options = 0;
2268
2269
2270
2271
2272
2273 ahd_freeze_devq(ahd, scb);
2274 ahd_qinfifo_requeue_tail(ahd, scb);
2275 printerror = 0;
2276 }
2277 } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)
2278 && ppr_busfree == 0) {
2279
2280
2281
2282
2283#ifdef AHD_DEBUG
2284 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2285 printf("WDTR negotiation rejected busfree.\n");
2286#endif
2287 ahd_set_width(ahd, &devinfo,
2288 MSG_EXT_WDTR_BUS_8_BIT,
2289 AHD_TRANS_CUR|AHD_TRANS_GOAL,
2290 TRUE);
2291
2292
2293
2294
2295
2296 ahd_freeze_devq(ahd, scb);
2297 ahd_qinfifo_requeue_tail(ahd, scb);
2298 printerror = 0;
2299 } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)
2300 && ppr_busfree == 0) {
2301
2302
2303
2304
2305#ifdef AHD_DEBUG
2306 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2307 printf("SDTR negotiation rejected busfree.\n");
2308#endif
2309 ahd_set_syncrate(ahd, &devinfo,
2310 0, 0,
2311 0,
2312 AHD_TRANS_CUR|AHD_TRANS_GOAL,
2313 TRUE);
2314
2315
2316
2317
2318
2319 ahd_freeze_devq(ahd, scb);
2320 ahd_qinfifo_requeue_tail(ahd, scb);
2321 printerror = 0;
2322 } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0
2323 && ahd_sent_msg(ahd, AHDMSG_1B,
2324 MSG_INITIATOR_DET_ERR, TRUE)) {
2325
2326#ifdef AHD_DEBUG
2327 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2328 printf("Expected IDE Busfree\n");
2329#endif
2330 printerror = 0;
2331 } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_QASREJ_BUSFREE)
2332 && ahd_sent_msg(ahd, AHDMSG_1B,
2333 MSG_MESSAGE_REJECT, TRUE)) {
2334
2335#ifdef AHD_DEBUG
2336 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2337 printf("Expected QAS Reject Busfree\n");
2338#endif
2339 printerror = 0;
2340 }
2341 }
2342
2343
2344
2345
2346
2347
2348 if (printerror != 0
2349 && (lastphase == P_MESGIN || lastphase == P_MESGOUT)
2350 && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) {
2351
2352 ahd_freeze_devq(ahd, scb);
2353 ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
2354 ahd_freeze_scb(scb);
2355 if ((ahd->msg_flags & MSG_FLAG_IU_REQ_CHANGED) != 0) {
2356 ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
2357 SCB_GET_CHANNEL(ahd, scb),
2358 SCB_GET_LUN(scb), SCB_LIST_NULL,
2359 ROLE_INITIATOR, CAM_REQ_ABORTED);
2360 } else {
2361#ifdef AHD_DEBUG
2362 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
2363 printf("PPR Negotiation Busfree.\n");
2364#endif
2365 ahd_done(ahd, scb);
2366 }
2367 printerror = 0;
2368 }
2369 if (printerror != 0) {
2370 int aborted;
2371
2372 aborted = 0;
2373 if (scb != NULL) {
2374 u_int tag;
2375
2376 if ((scb->hscb->control & TAG_ENB) != 0)
2377 tag = SCB_GET_TAG(scb);
2378 else
2379 tag = SCB_LIST_NULL;
2380 ahd_print_path(ahd, scb);
2381 aborted = ahd_abort_scbs(ahd, target, 'A',
2382 SCB_GET_LUN(scb), tag,
2383 ROLE_INITIATOR,
2384 CAM_UNEXP_BUSFREE);
2385 } else {
2386
2387
2388
2389
2390 printf("%s: ", ahd_name(ahd));
2391 }
2392 printf("Unexpected busfree %s, %d SCBs aborted, "
2393 "PRGMCNT == 0x%x\n",
2394 ahd_lookup_phase_entry(lastphase)->phasemsg,
2395 aborted,
2396 ahd_inw(ahd, PRGMCNT));
2397 ahd_dump_card_state(ahd);
2398 if (lastphase != P_BUSFREE)
2399 ahd_force_renegotiation(ahd, &devinfo);
2400 }
2401
2402 return (1);
2403}
2404
2405static void
2406ahd_handle_proto_violation(struct ahd_softc *ahd)
2407{
2408 struct ahd_devinfo devinfo;
2409 struct scb *scb;
2410 u_int scbid;
2411 u_int seq_flags;
2412 u_int curphase;
2413 u_int lastphase;
2414 int found;
2415
2416 ahd_fetch_devinfo(ahd, &devinfo);
2417 scbid = ahd_get_scbptr(ahd);
2418 scb = ahd_lookup_scb(ahd, scbid);
2419 seq_flags = ahd_inb(ahd, SEQ_FLAGS);
2420 curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
2421 lastphase = ahd_inb(ahd, LASTPHASE);
2422 if ((seq_flags & NOT_IDENTIFIED) != 0) {
2423
2424
2425
2426
2427
2428
2429 ahd_print_devinfo(ahd, &devinfo);
2430 printf("Target did not send an IDENTIFY message. "
2431 "LASTPHASE = 0x%x.\n", lastphase);
2432 scb = NULL;
2433 } else if (scb == NULL) {
2434
2435
2436
2437
2438 ahd_print_devinfo(ahd, &devinfo);
2439 printf("No SCB found during protocol violation\n");
2440 goto proto_violation_reset;
2441 } else {
2442 ahd_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
2443 if ((seq_flags & NO_CDB_SENT) != 0) {
2444 ahd_print_path(ahd, scb);
2445 printf("No or incomplete CDB sent to device.\n");
2446 } else if ((ahd_inb_scbram(ahd, SCB_CONTROL)
2447 & STATUS_RCVD) == 0) {
2448
2449
2450
2451
2452
2453
2454
2455 ahd_print_path(ahd, scb);
2456 printf("Completed command without status.\n");
2457 } else {
2458 ahd_print_path(ahd, scb);
2459 printf("Unknown protocol violation.\n");
2460 ahd_dump_card_state(ahd);
2461 }
2462 }
2463 if ((lastphase & ~P_DATAIN_DT) == 0
2464 || lastphase == P_COMMAND) {
2465proto_violation_reset:
2466
2467
2468
2469
2470
2471
2472 found = ahd_reset_channel(ahd, 'A', TRUE);
2473 printf("%s: Issued Channel %c Bus Reset. "
2474 "%d SCBs aborted\n", ahd_name(ahd), 'A', found);
2475 } else {
2476
2477
2478
2479
2480
2481 ahd_outb(ahd, SCSISEQ0,
2482 ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
2483 ahd_assert_atn(ahd);
2484 ahd_outb(ahd, MSG_OUT, HOST_MSG);
2485 if (scb == NULL) {
2486 ahd_print_devinfo(ahd, &devinfo);
2487 ahd->msgout_buf[0] = MSG_ABORT_TASK;
2488 ahd->msgout_len = 1;
2489 ahd->msgout_index = 0;
2490 ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
2491 } else {
2492 ahd_print_path(ahd, scb);
2493 scb->flags |= SCB_ABORT;
2494 }
2495 printf("Protocol violation %s. Attempting to abort.\n",
2496 ahd_lookup_phase_entry(curphase)->phasemsg);
2497 }
2498}
2499
2500
2501
2502
2503
2504static void
2505ahd_force_renegotiation(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
2506{
2507 struct ahd_initiator_tinfo *targ_info;
2508 struct ahd_tmode_tstate *tstate;
2509
2510#ifdef AHD_DEBUG
2511 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
2512 ahd_print_devinfo(ahd, devinfo);
2513 printf("Forcing renegotiation\n");
2514 }
2515#endif
2516 targ_info = ahd_fetch_transinfo(ahd,
2517 devinfo->channel,
2518 devinfo->our_scsiid,
2519 devinfo->target,
2520 &tstate);
2521 ahd_update_neg_request(ahd, devinfo, tstate,
2522 targ_info, AHD_NEG_IF_NON_ASYNC);
2523}
2524
2525#define AHD_MAX_STEPS 2000
2526void
2527ahd_clear_critical_section(struct ahd_softc *ahd)
2528{
2529 ahd_mode_state saved_modes;
2530 int stepping;
2531 int steps;
2532 int first_instr;
2533 u_int simode0;
2534 u_int simode1;
2535 u_int simode3;
2536 u_int lqimode0;
2537 u_int lqimode1;
2538 u_int lqomode0;
2539 u_int lqomode1;
2540
2541 if (ahd->num_critical_sections == 0)
2542 return;
2543
2544 stepping = FALSE;
2545 steps = 0;
2546 first_instr = 0;
2547 simode0 = 0;
2548 simode1 = 0;
2549 simode3 = 0;
2550 lqimode0 = 0;
2551 lqimode1 = 0;
2552 lqomode0 = 0;
2553 lqomode1 = 0;
2554 saved_modes = ahd_save_modes(ahd);
2555 for (;;) {
2556 struct cs *cs;
2557 u_int seqaddr;
2558 u_int i;
2559
2560 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2561 seqaddr = ahd_inw(ahd, CURADDR);
2562
2563 cs = ahd->critical_sections;
2564 for (i = 0; i < ahd->num_critical_sections; i++, cs++) {
2565
2566 if (cs->begin < seqaddr && cs->end >= seqaddr)
2567 break;
2568 }
2569
2570 if (i == ahd->num_critical_sections)
2571 break;
2572
2573 if (steps > AHD_MAX_STEPS) {
2574 printf("%s: Infinite loop in critical section\n"
2575 "%s: First Instruction 0x%x now 0x%x\n",
2576 ahd_name(ahd), ahd_name(ahd), first_instr,
2577 seqaddr);
2578 ahd_dump_card_state(ahd);
2579 panic("critical section loop");
2580 }
2581
2582 steps++;
2583#ifdef AHD_DEBUG
2584 if ((ahd_debug & AHD_SHOW_MISC) != 0)
2585 printf("%s: Single stepping at 0x%x\n", ahd_name(ahd),
2586 seqaddr);
2587#endif
2588 if (stepping == FALSE) {
2589
2590 first_instr = seqaddr;
2591 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
2592 simode0 = ahd_inb(ahd, SIMODE0);
2593 simode3 = ahd_inb(ahd, SIMODE3);
2594 lqimode0 = ahd_inb(ahd, LQIMODE0);
2595 lqimode1 = ahd_inb(ahd, LQIMODE1);
2596 lqomode0 = ahd_inb(ahd, LQOMODE0);
2597 lqomode1 = ahd_inb(ahd, LQOMODE1);
2598 ahd_outb(ahd, SIMODE0, 0);
2599 ahd_outb(ahd, SIMODE3, 0);
2600 ahd_outb(ahd, LQIMODE0, 0);
2601 ahd_outb(ahd, LQIMODE1, 0);
2602 ahd_outb(ahd, LQOMODE0, 0);
2603 ahd_outb(ahd, LQOMODE1, 0);
2604 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2605 simode1 = ahd_inb(ahd, SIMODE1);
2606
2607
2608
2609
2610
2611
2612 ahd_outb(ahd, SIMODE1, simode1 & ENBUSFREE);
2613 ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) | STEP);
2614 stepping = TRUE;
2615 }
2616 ahd_outb(ahd, CLRSINT1, CLRBUSFREE);
2617 ahd_outb(ahd, CLRINT, CLRSCSIINT);
2618 ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
2619 ahd_outb(ahd, HCNTRL, ahd->unpause);
2620 while (!ahd_is_paused(ahd))
2621 ahd_delay(200);
2622 ahd_update_modes(ahd);
2623 }
2624 if (stepping) {
2625 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
2626 ahd_outb(ahd, SIMODE0, simode0);
2627 ahd_outb(ahd, SIMODE3, simode3);
2628 ahd_outb(ahd, LQIMODE0, lqimode0);
2629 ahd_outb(ahd, LQIMODE1, lqimode1);
2630 ahd_outb(ahd, LQOMODE0, lqomode0);
2631 ahd_outb(ahd, LQOMODE1, lqomode1);
2632 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2633 ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) & ~STEP);
2634 ahd_outb(ahd, SIMODE1, simode1);
2635
2636
2637
2638
2639
2640
2641 ahd_outb(ahd, CLRINT, CLRSCSIINT);
2642 }
2643 ahd_restore_modes(ahd, saved_modes);
2644}
2645
2646
2647
2648
2649void
2650ahd_clear_intstat(struct ahd_softc *ahd)
2651{
2652 AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
2653 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
2654
2655 ahd_outb(ahd, CLRLQIINT0, CLRLQIATNQAS|CLRLQICRCT1|CLRLQICRCT2
2656 |CLRLQIBADLQT|CLRLQIATNLQ|CLRLQIATNCMD);
2657 ahd_outb(ahd, CLRLQIINT1, CLRLQIPHASE_LQ|CLRLQIPHASE_NLQ|CLRLIQABORT
2658 |CLRLQICRCI_LQ|CLRLQICRCI_NLQ|CLRLQIBADLQI
2659 |CLRLQIOVERI_LQ|CLRLQIOVERI_NLQ|CLRNONPACKREQ);
2660 ahd_outb(ahd, CLRLQOINT0, CLRLQOTARGSCBPERR|CLRLQOSTOPT2|CLRLQOATNLQ
2661 |CLRLQOATNPKT|CLRLQOTCRC);
2662 ahd_outb(ahd, CLRLQOINT1, CLRLQOINITSCBPERR|CLRLQOSTOPI2|CLRLQOBADQAS
2663 |CLRLQOBUSFREE|CLRLQOPHACHGINPKT);
2664 if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {
2665 ahd_outb(ahd, CLRLQOINT0, 0);
2666 ahd_outb(ahd, CLRLQOINT1, 0);
2667 }
2668 ahd_outb(ahd, CLRSINT3, CLRNTRAMPERR|CLROSRAMPERR);
2669 ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
2670 |CLRBUSFREE|CLRSCSIPERR|CLRREQINIT);
2671 ahd_outb(ahd, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO
2672 |CLRIOERR|CLROVERRUN);
2673 ahd_outb(ahd, CLRINT, CLRSCSIINT);
2674}
2675
2676
2677#ifdef AHD_DEBUG
2678uint32_t ahd_debug = AHD_DEBUG_OPTS;
2679#endif
2680void
2681ahd_print_scb(struct scb *scb)
2682{
2683 struct hardware_scb *hscb;
2684 int i;
2685
2686 hscb = scb->hscb;
2687 printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
2688 (void *)scb,
2689 hscb->control,
2690 hscb->scsiid,
2691 hscb->lun,
2692 hscb->cdb_len);
2693 printf("Shared Data: ");
2694 for (i = 0; i < sizeof(hscb->shared_data.idata.cdb); i++)
2695 printf("%#02x", hscb->shared_data.idata.cdb[i]);
2696 printf(" dataptr:%#x%x datacnt:%#x sgptr:%#x tag:%#x\n",
2697 (uint32_t)((ahd_le64toh(hscb->dataptr) >> 32) & 0xFFFFFFFF),
2698 (uint32_t)(ahd_le64toh(hscb->dataptr) & 0xFFFFFFFF),
2699 ahd_le32toh(hscb->datacnt),
2700 ahd_le32toh(hscb->sgptr),
2701 SCB_GET_TAG(scb));
2702 ahd_dump_sglist(scb);
2703}
2704
2705void
2706ahd_dump_sglist(struct scb *scb)
2707{
2708 int i;
2709
2710 if (scb->sg_count > 0) {
2711 if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) {
2712 struct ahd_dma64_seg *sg_list;
2713
2714 sg_list = (struct ahd_dma64_seg*)scb->sg_list;
2715 for (i = 0; i < scb->sg_count; i++) {
2716 uint64_t addr;
2717 uint32_t len;
2718
2719 addr = ahd_le64toh(sg_list[i].addr);
2720 len = ahd_le32toh(sg_list[i].len);
2721 printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
2722 i,
2723 (uint32_t)((addr >> 32) & 0xFFFFFFFF),
2724 (uint32_t)(addr & 0xFFFFFFFF),
2725 sg_list[i].len & AHD_SG_LEN_MASK,
2726 (sg_list[i].len & AHD_DMA_LAST_SEG)
2727 ? " Last" : "");
2728 }
2729 } else {
2730 struct ahd_dma_seg *sg_list;
2731
2732 sg_list = (struct ahd_dma_seg*)scb->sg_list;
2733 for (i = 0; i < scb->sg_count; i++) {
2734 uint32_t len;
2735
2736 len = ahd_le32toh(sg_list[i].len);
2737 printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
2738 i,
2739 (len & AHD_SG_HIGH_ADDR_MASK) >> 24,
2740 ahd_le32toh(sg_list[i].addr),
2741 len & AHD_SG_LEN_MASK,
2742 len & AHD_DMA_LAST_SEG ? " Last" : "");
2743 }
2744 }
2745 }
2746}
2747
2748
2749
2750
2751
2752
2753static struct ahd_tmode_tstate *
2754ahd_alloc_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel)
2755{
2756 struct ahd_tmode_tstate *master_tstate;
2757 struct ahd_tmode_tstate *tstate;
2758 int i;
2759
2760 master_tstate = ahd->enabled_targets[ahd->our_id];
2761 if (ahd->enabled_targets[scsi_id] != NULL
2762 && ahd->enabled_targets[scsi_id] != master_tstate)
2763 panic("%s: ahd_alloc_tstate - Target already allocated",
2764 ahd_name(ahd));
2765 tstate = malloc(sizeof(*tstate), M_DEVBUF, M_NOWAIT);
2766 if (tstate == NULL)
2767 return (NULL);
2768
2769
2770
2771
2772
2773
2774
2775 if (master_tstate != NULL) {
2776 memcpy(tstate, master_tstate, sizeof(*tstate));
2777 memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns));
2778 for (i = 0; i < 16; i++) {
2779 memset(&tstate->transinfo[i].curr, 0,
2780 sizeof(tstate->transinfo[i].curr));
2781 memset(&tstate->transinfo[i].goal, 0,
2782 sizeof(tstate->transinfo[i].goal));
2783 }
2784 } else
2785 memset(tstate, 0, sizeof(*tstate));
2786 ahd->enabled_targets[scsi_id] = tstate;
2787 return (tstate);
2788}
2789
2790#ifdef AHD_TARGET_MODE
2791
2792
2793
2794
2795static void
2796ahd_free_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel, int force)
2797{
2798 struct ahd_tmode_tstate *tstate;
2799
2800
2801
2802
2803
2804 if (scsi_id == ahd->our_id
2805 && force == FALSE)
2806 return;
2807
2808 tstate = ahd->enabled_targets[scsi_id];
2809 if (tstate != NULL)
2810 free(tstate, M_DEVBUF);
2811 ahd->enabled_targets[scsi_id] = NULL;
2812}
2813#endif
2814
2815
2816
2817
2818
2819
2820
2821void
2822ahd_devlimited_syncrate(struct ahd_softc *ahd,
2823 struct ahd_initiator_tinfo *tinfo,
2824 u_int *period, u_int *ppr_options, role_t role)
2825{
2826 struct ahd_transinfo *transinfo;
2827 u_int maxsync;
2828
2829 if ((ahd_inb(ahd, SBLKCTL) & ENAB40) != 0
2830 && (ahd_inb(ahd, SSTAT2) & EXP_ACTIVE) == 0) {
2831 maxsync = AHD_SYNCRATE_PACED;
2832 } else {
2833 maxsync = AHD_SYNCRATE_ULTRA;
2834
2835 *ppr_options &= MSG_EXT_PPR_QAS_REQ;
2836 }
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847 if (role == ROLE_TARGET)
2848 transinfo = &tinfo->user;
2849 else
2850 transinfo = &tinfo->goal;
2851 *ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN);
2852 if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
2853 maxsync = MAX(maxsync, AHD_SYNCRATE_ULTRA2);
2854 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
2855 }
2856 if (transinfo->period == 0) {
2857 *period = 0;
2858 *ppr_options = 0;
2859 } else {
2860 *period = MAX(*period, transinfo->period);
2861 ahd_find_syncrate(ahd, period, ppr_options, maxsync);
2862 }
2863}
2864
2865
2866
2867
2868
2869
2870void
2871ahd_find_syncrate(struct ahd_softc *ahd, u_int *period,
2872 u_int *ppr_options, u_int maxsync)
2873{
2874 if (*period < maxsync)
2875 *period = maxsync;
2876
2877 if ((*ppr_options & MSG_EXT_PPR_DT_REQ) != 0
2878 && *period > AHD_SYNCRATE_MIN_DT)
2879 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
2880
2881 if (*period > AHD_SYNCRATE_MIN)
2882 *period = 0;
2883
2884
2885 if (*period > AHD_SYNCRATE_PACED)
2886 *ppr_options &= ~MSG_EXT_PPR_RTI;
2887
2888 if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0)
2889 *ppr_options &= (MSG_EXT_PPR_DT_REQ|MSG_EXT_PPR_QAS_REQ);
2890
2891 if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0)
2892 *ppr_options &= MSG_EXT_PPR_QAS_REQ;
2893
2894
2895 if ((*ppr_options & MSG_EXT_PPR_IU_REQ) == 0
2896 && *period < AHD_SYNCRATE_DT)
2897 *period = AHD_SYNCRATE_DT;
2898
2899
2900 if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
2901 && *period < AHD_SYNCRATE_ULTRA2)
2902 *period = AHD_SYNCRATE_ULTRA2;
2903}
2904
2905
2906
2907
2908
2909void
2910ahd_validate_offset(struct ahd_softc *ahd,
2911 struct ahd_initiator_tinfo *tinfo,
2912 u_int period, u_int *offset, int wide,
2913 role_t role)
2914{
2915 u_int maxoffset;
2916
2917
2918 if (period == 0)
2919 maxoffset = 0;
2920 else if (period <= AHD_SYNCRATE_PACED) {
2921 if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0)
2922 maxoffset = MAX_OFFSET_PACED_BUG;
2923 else
2924 maxoffset = MAX_OFFSET_PACED;
2925 } else
2926 maxoffset = MAX_OFFSET_NON_PACED;
2927 *offset = MIN(*offset, maxoffset);
2928 if (tinfo != NULL) {
2929 if (role == ROLE_TARGET)
2930 *offset = MIN(*offset, tinfo->user.offset);
2931 else
2932 *offset = MIN(*offset, tinfo->goal.offset);
2933 }
2934}
2935
2936
2937
2938
2939
2940void
2941ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo,
2942 u_int *bus_width, role_t role)
2943{
2944 switch (*bus_width) {
2945 default:
2946 if (ahd->features & AHD_WIDE) {
2947
2948 *bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2949 break;
2950 }
2951
2952 case MSG_EXT_WDTR_BUS_8_BIT:
2953 *bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2954 break;
2955 }
2956 if (tinfo != NULL) {
2957 if (role == ROLE_TARGET)
2958 *bus_width = MIN(tinfo->user.width, *bus_width);
2959 else
2960 *bus_width = MIN(tinfo->goal.width, *bus_width);
2961 }
2962}
2963
2964
2965
2966
2967
2968
2969
2970int
2971ahd_update_neg_request(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
2972 struct ahd_tmode_tstate *tstate,
2973 struct ahd_initiator_tinfo *tinfo, ahd_neg_type neg_type)
2974{
2975 u_int auto_negotiate_orig;
2976
2977 auto_negotiate_orig = tstate->auto_negotiate;
2978 if (neg_type == AHD_NEG_ALWAYS) {
2979
2980
2981
2982
2983
2984
2985 if ((ahd->features & AHD_WIDE) != 0)
2986 tinfo->curr.width = AHD_WIDTH_UNKNOWN;
2987 tinfo->curr.period = AHD_PERIOD_UNKNOWN;
2988 tinfo->curr.offset = AHD_OFFSET_UNKNOWN;
2989 }
2990 if (tinfo->curr.period != tinfo->goal.period
2991 || tinfo->curr.width != tinfo->goal.width
2992 || tinfo->curr.offset != tinfo->goal.offset
2993 || tinfo->curr.ppr_options != tinfo->goal.ppr_options
2994 || (neg_type == AHD_NEG_IF_NON_ASYNC
2995 && (tinfo->goal.offset != 0
2996 || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT
2997 || tinfo->goal.ppr_options != 0)))
2998 tstate->auto_negotiate |= devinfo->target_mask;
2999 else
3000 tstate->auto_negotiate &= ~devinfo->target_mask;
3001
3002 return (auto_negotiate_orig != tstate->auto_negotiate);
3003}
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013void
3014ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3015 u_int period, u_int offset, u_int ppr_options,
3016 u_int type, int paused)
3017{
3018 struct ahd_initiator_tinfo *tinfo;
3019 struct ahd_tmode_tstate *tstate;
3020 u_int old_period;
3021 u_int old_offset;
3022 u_int old_ppr;
3023 int active;
3024 int update_needed;
3025
3026 active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE;
3027 update_needed = 0;
3028
3029 if (period == 0 || offset == 0) {
3030 period = 0;
3031 offset = 0;
3032 }
3033
3034 tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
3035 devinfo->target, &tstate);
3036
3037 if ((type & AHD_TRANS_USER) != 0) {
3038 tinfo->user.period = period;
3039 tinfo->user.offset = offset;
3040 tinfo->user.ppr_options = ppr_options;
3041 }
3042
3043 if ((type & AHD_TRANS_GOAL) != 0) {
3044 tinfo->goal.period = period;
3045 tinfo->goal.offset = offset;
3046 tinfo->goal.ppr_options = ppr_options;
3047 }
3048
3049 old_period = tinfo->curr.period;
3050 old_offset = tinfo->curr.offset;
3051 old_ppr = tinfo->curr.ppr_options;
3052
3053 if ((type & AHD_TRANS_CUR) != 0
3054 && (old_period != period
3055 || old_offset != offset
3056 || old_ppr != ppr_options)) {
3057
3058 update_needed++;
3059
3060 tinfo->curr.period = period;
3061 tinfo->curr.offset = offset;
3062 tinfo->curr.ppr_options = ppr_options;
3063
3064 ahd_send_async(ahd, devinfo->channel, devinfo->target,
3065 CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
3066 if (bootverbose) {
3067 if (offset != 0) {
3068 int options;
3069
3070 printf("%s: target %d synchronous with "
3071 "period = 0x%x, offset = 0x%x",
3072 ahd_name(ahd), devinfo->target,
3073 period, offset);
3074 options = 0;
3075 if ((ppr_options & MSG_EXT_PPR_RD_STRM) != 0) {
3076 printf("(RDSTRM");
3077 options++;
3078 }
3079 if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) {
3080 printf("%s", options ? "|DT" : "(DT");
3081 options++;
3082 }
3083 if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
3084 printf("%s", options ? "|IU" : "(IU");
3085 options++;
3086 }
3087 if ((ppr_options & MSG_EXT_PPR_RTI) != 0) {
3088 printf("%s", options ? "|RTI" : "(RTI");
3089 options++;
3090 }
3091 if ((ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) {
3092 printf("%s", options ? "|QAS" : "(QAS");
3093 options++;
3094 }
3095 if (options != 0)
3096 printf(")\n");
3097 else
3098 printf("\n");
3099 } else {
3100 printf("%s: target %d using "
3101 "asynchronous transfers%s\n",
3102 ahd_name(ahd), devinfo->target,
3103 (ppr_options & MSG_EXT_PPR_QAS_REQ) != 0
3104 ? "(QAS)" : "");
3105 }
3106 }
3107 }
3108
3109
3110
3111
3112
3113
3114
3115
3116 if ((type & AHD_TRANS_CUR) != 0) {
3117 if (!paused)
3118 ahd_pause(ahd);
3119 ahd_update_neg_table(ahd, devinfo, &tinfo->curr);
3120 if (!paused)
3121 ahd_unpause(ahd);
3122 if (ahd->msg_type != MSG_TYPE_NONE) {
3123 if ((old_ppr & MSG_EXT_PPR_IU_REQ)
3124 != (ppr_options & MSG_EXT_PPR_IU_REQ)) {
3125#ifdef AHD_DEBUG
3126 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3127 ahd_print_devinfo(ahd, devinfo);
3128 printf("Expecting IU Change busfree\n");
3129 }
3130#endif
3131 ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE
3132 | MSG_FLAG_IU_REQ_CHANGED;
3133 }
3134 if ((old_ppr & MSG_EXT_PPR_IU_REQ) != 0) {
3135#ifdef AHD_DEBUG
3136 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3137 printf("PPR with IU_REQ outstanding\n");
3138#endif
3139 ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE;
3140 }
3141 }
3142 }
3143
3144 update_needed += ahd_update_neg_request(ahd, devinfo, tstate,
3145 tinfo, AHD_NEG_TO_GOAL);
3146
3147 if (update_needed && active)
3148 ahd_update_pending_scbs(ahd);
3149}
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159void
3160ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3161 u_int width, u_int type, int paused)
3162{
3163 struct ahd_initiator_tinfo *tinfo;
3164 struct ahd_tmode_tstate *tstate;
3165 u_int oldwidth;
3166 int active;
3167 int update_needed;
3168
3169 active = (type & AHD_TRANS_ACTIVE) == AHD_TRANS_ACTIVE;
3170 update_needed = 0;
3171 tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
3172 devinfo->target, &tstate);
3173
3174 if ((type & AHD_TRANS_USER) != 0)
3175 tinfo->user.width = width;
3176
3177 if ((type & AHD_TRANS_GOAL) != 0)
3178 tinfo->goal.width = width;
3179
3180 oldwidth = tinfo->curr.width;
3181 if ((type & AHD_TRANS_CUR) != 0 && oldwidth != width) {
3182
3183 update_needed++;
3184
3185 tinfo->curr.width = width;
3186 ahd_send_async(ahd, devinfo->channel, devinfo->target,
3187 CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
3188 if (bootverbose) {
3189 printf("%s: target %d using %dbit transfers\n",
3190 ahd_name(ahd), devinfo->target,
3191 8 * (0x01 << width));
3192 }
3193 }
3194
3195 if ((type & AHD_TRANS_CUR) != 0) {
3196 if (!paused)
3197 ahd_pause(ahd);
3198 ahd_update_neg_table(ahd, devinfo, &tinfo->curr);
3199 if (!paused)
3200 ahd_unpause(ahd);
3201 }
3202
3203 update_needed += ahd_update_neg_request(ahd, devinfo, tstate,
3204 tinfo, AHD_NEG_TO_GOAL);
3205 if (update_needed && active)
3206 ahd_update_pending_scbs(ahd);
3207
3208}
3209
3210
3211
3212
3213void
3214ahd_set_tags(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
3215 struct ahd_devinfo *devinfo, ahd_queue_alg alg)
3216{
3217 struct scsi_device *sdev = cmd->device;
3218
3219 ahd_platform_set_tags(ahd, sdev, devinfo, alg);
3220 ahd_send_async(ahd, devinfo->channel, devinfo->target,
3221 devinfo->lun, AC_TRANSFER_NEG);
3222}
3223
3224static void
3225ahd_update_neg_table(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3226 struct ahd_transinfo *tinfo)
3227{
3228 ahd_mode_state saved_modes;
3229 u_int period;
3230 u_int ppr_opts;
3231 u_int con_opts;
3232 u_int offset;
3233 u_int saved_negoaddr;
3234 uint8_t iocell_opts[sizeof(ahd->iocell_opts)];
3235
3236 saved_modes = ahd_save_modes(ahd);
3237 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
3238
3239 saved_negoaddr = ahd_inb(ahd, NEGOADDR);
3240 ahd_outb(ahd, NEGOADDR, devinfo->target);
3241 period = tinfo->period;
3242 offset = tinfo->offset;
3243 memcpy(iocell_opts, ahd->iocell_opts, sizeof(ahd->iocell_opts));
3244 ppr_opts = tinfo->ppr_options & (MSG_EXT_PPR_QAS_REQ|MSG_EXT_PPR_DT_REQ
3245 |MSG_EXT_PPR_IU_REQ|MSG_EXT_PPR_RTI);
3246 con_opts = 0;
3247 if (period == 0)
3248 period = AHD_SYNCRATE_ASYNC;
3249 if (period == AHD_SYNCRATE_160) {
3250
3251 if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0) {
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263 ppr_opts |= PPROPT_PACE;
3264 offset *= 2;
3265
3266
3267
3268
3269
3270
3271
3272 period = AHD_SYNCRATE_REVA_160;
3273 }
3274 if ((tinfo->ppr_options & MSG_EXT_PPR_PCOMP_EN) == 0)
3275 iocell_opts[AHD_PRECOMP_SLEW_INDEX] &=
3276 ~AHD_PRECOMP_MASK;
3277 } else {
3278
3279
3280
3281 iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK;
3282
3283 if ((ahd->features & AHD_NEW_IOCELL_OPTS) != 0
3284 && (ppr_opts & MSG_EXT_PPR_DT_REQ) != 0
3285 && (ppr_opts & MSG_EXT_PPR_IU_REQ) == 0) {
3286
3287
3288
3289
3290
3291
3292 con_opts |= ENSLOWCRC;
3293 }
3294
3295 if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0) {
3296
3297
3298
3299
3300 iocell_opts[AHD_PRECOMP_SLEW_INDEX] &=
3301 ~AHD_SLEWRATE_MASK;
3302 }
3303 }
3304
3305 ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PRECOMP_SLEW);
3306 ahd_outb(ahd, ANNEXDAT, iocell_opts[AHD_PRECOMP_SLEW_INDEX]);
3307 ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_AMPLITUDE);
3308 ahd_outb(ahd, ANNEXDAT, iocell_opts[AHD_AMPLITUDE_INDEX]);
3309
3310 ahd_outb(ahd, NEGPERIOD, period);
3311 ahd_outb(ahd, NEGPPROPTS, ppr_opts);
3312 ahd_outb(ahd, NEGOFFSET, offset);
3313
3314 if (tinfo->width == MSG_EXT_WDTR_BUS_16_BIT)
3315 con_opts |= WIDEXFER;
3316
3317
3318
3319
3320
3321
3322 if (ahd->features & AHD_AIC79XXB_SLOWCRC) {
3323 con_opts |= ENSLOWCRC;
3324 }
3325
3326
3327
3328
3329
3330
3331 if ((tinfo->ppr_options & MSG_EXT_PPR_IU_REQ) == 0)
3332 con_opts |= ENAUTOATNO;
3333 ahd_outb(ahd, NEGCONOPTS, con_opts);
3334 ahd_outb(ahd, NEGOADDR, saved_negoaddr);
3335 ahd_restore_modes(ahd, saved_modes);
3336}
3337
3338
3339
3340
3341
3342
3343
3344static void
3345ahd_update_pending_scbs(struct ahd_softc *ahd)
3346{
3347 struct scb *pending_scb;
3348 int pending_scb_count;
3349 int paused;
3350 u_int saved_scbptr;
3351 ahd_mode_state saved_modes;
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363 pending_scb_count = 0;
3364 LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
3365 struct ahd_devinfo devinfo;
3366 struct ahd_initiator_tinfo *tinfo;
3367 struct ahd_tmode_tstate *tstate;
3368
3369 ahd_scb_devinfo(ahd, &devinfo, pending_scb);
3370 tinfo = ahd_fetch_transinfo(ahd, devinfo.channel,
3371 devinfo.our_scsiid,
3372 devinfo.target, &tstate);
3373 if ((tstate->auto_negotiate & devinfo.target_mask) == 0
3374 && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) {
3375 pending_scb->flags &= ~SCB_AUTO_NEGOTIATE;
3376 pending_scb->hscb->control &= ~MK_MESSAGE;
3377 }
3378 ahd_sync_scb(ahd, pending_scb,
3379 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3380 pending_scb_count++;
3381 }
3382
3383 if (pending_scb_count == 0)
3384 return;
3385
3386 if (ahd_is_paused(ahd)) {
3387 paused = 1;
3388 } else {
3389 paused = 0;
3390 ahd_pause(ahd);
3391 }
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401 saved_modes = ahd_save_modes(ahd);
3402 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
3403 if ((ahd_inb(ahd, SCSISIGI) & BSYI) != 0
3404 && (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) == 0)
3405 ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
3406 saved_scbptr = ahd_get_scbptr(ahd);
3407
3408 LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
3409 u_int scb_tag;
3410 u_int control;
3411
3412 scb_tag = SCB_GET_TAG(pending_scb);
3413 ahd_set_scbptr(ahd, scb_tag);
3414 control = ahd_inb_scbram(ahd, SCB_CONTROL);
3415 control &= ~MK_MESSAGE;
3416 control |= pending_scb->hscb->control & MK_MESSAGE;
3417 ahd_outb(ahd, SCB_CONTROL, control);
3418 }
3419 ahd_set_scbptr(ahd, saved_scbptr);
3420 ahd_restore_modes(ahd, saved_modes);
3421
3422 if (paused == 0)
3423 ahd_unpause(ahd);
3424}
3425
3426
3427static void
3428ahd_fetch_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
3429{
3430 ahd_mode_state saved_modes;
3431 u_int saved_scsiid;
3432 role_t role;
3433 int our_id;
3434
3435 saved_modes = ahd_save_modes(ahd);
3436 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
3437
3438 if (ahd_inb(ahd, SSTAT0) & TARGET)
3439 role = ROLE_TARGET;
3440 else
3441 role = ROLE_INITIATOR;
3442
3443 if (role == ROLE_TARGET
3444 && (ahd_inb(ahd, SEQ_FLAGS) & CMDPHASE_PENDING) != 0) {
3445
3446 our_id = ahd_inb(ahd, TARGIDIN) & OID;
3447 } else if (role == ROLE_TARGET)
3448 our_id = ahd_inb(ahd, TOWNID);
3449 else
3450 our_id = ahd_inb(ahd, IOWNID);
3451
3452 saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
3453 ahd_compile_devinfo(devinfo,
3454 our_id,
3455 SCSIID_TARGET(ahd, saved_scsiid),
3456 ahd_inb(ahd, SAVED_LUN),
3457 SCSIID_CHANNEL(ahd, saved_scsiid),
3458 role);
3459 ahd_restore_modes(ahd, saved_modes);
3460}
3461
3462void
3463ahd_print_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
3464{
3465 printf("%s:%c:%d:%d: ", ahd_name(ahd), 'A',
3466 devinfo->target, devinfo->lun);
3467}
3468
3469struct ahd_phase_table_entry*
3470ahd_lookup_phase_entry(int phase)
3471{
3472 struct ahd_phase_table_entry *entry;
3473 struct ahd_phase_table_entry *last_entry;
3474
3475
3476
3477
3478
3479 last_entry = &ahd_phase_table[num_phases];
3480 for (entry = ahd_phase_table; entry < last_entry; entry++) {
3481 if (phase == entry->phase)
3482 break;
3483 }
3484 return (entry);
3485}
3486
3487void
3488ahd_compile_devinfo(struct ahd_devinfo *devinfo, u_int our_id, u_int target,
3489 u_int lun, char channel, role_t role)
3490{
3491 devinfo->our_scsiid = our_id;
3492 devinfo->target = target;
3493 devinfo->lun = lun;
3494 devinfo->target_offset = target;
3495 devinfo->channel = channel;
3496 devinfo->role = role;
3497 if (channel == 'B')
3498 devinfo->target_offset += 8;
3499 devinfo->target_mask = (0x01 << devinfo->target_offset);
3500}
3501
3502static void
3503ahd_scb_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3504 struct scb *scb)
3505{
3506 role_t role;
3507 int our_id;
3508
3509 our_id = SCSIID_OUR_ID(scb->hscb->scsiid);
3510 role = ROLE_INITIATOR;
3511 if ((scb->hscb->control & TARGET_SCB) != 0)
3512 role = ROLE_TARGET;
3513 ahd_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahd, scb),
3514 SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahd, scb), role);
3515}
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525static void
3526ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3527 struct scb *scb)
3528{
3529
3530
3531
3532
3533
3534 ahd->msgout_index = 0;
3535 ahd->msgout_len = 0;
3536
3537 if (ahd_currently_packetized(ahd))
3538 ahd->msg_flags |= MSG_FLAG_PACKETIZED;
3539
3540 if (ahd->send_msg_perror
3541 && ahd_inb(ahd, MSG_OUT) == HOST_MSG) {
3542 ahd->msgout_buf[ahd->msgout_index++] = ahd->send_msg_perror;
3543 ahd->msgout_len++;
3544 ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
3545#ifdef AHD_DEBUG
3546 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3547 printf("Setting up for Parity Error delivery\n");
3548#endif
3549 return;
3550 } else if (scb == NULL) {
3551 printf("%s: WARNING. No pending message for "
3552 "I_T msgin. Issuing NO-OP\n", ahd_name(ahd));
3553 ahd->msgout_buf[ahd->msgout_index++] = MSG_NOOP;
3554 ahd->msgout_len++;
3555 ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
3556 return;
3557 }
3558
3559 if ((scb->flags & SCB_DEVICE_RESET) == 0
3560 && (scb->flags & SCB_PACKETIZED) == 0
3561 && ahd_inb(ahd, MSG_OUT) == MSG_IDENTIFYFLAG) {
3562 u_int identify_msg;
3563
3564 identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb);
3565 if ((scb->hscb->control & DISCENB) != 0)
3566 identify_msg |= MSG_IDENTIFY_DISCFLAG;
3567 ahd->msgout_buf[ahd->msgout_index++] = identify_msg;
3568 ahd->msgout_len++;
3569
3570 if ((scb->hscb->control & TAG_ENB) != 0) {
3571 ahd->msgout_buf[ahd->msgout_index++] =
3572 scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE);
3573 ahd->msgout_buf[ahd->msgout_index++] = SCB_GET_TAG(scb);
3574 ahd->msgout_len += 2;
3575 }
3576 }
3577
3578 if (scb->flags & SCB_DEVICE_RESET) {
3579 ahd->msgout_buf[ahd->msgout_index++] = MSG_BUS_DEV_RESET;
3580 ahd->msgout_len++;
3581 ahd_print_path(ahd, scb);
3582 printf("Bus Device Reset Message Sent\n");
3583
3584
3585
3586
3587
3588
3589
3590 ahd_outb(ahd, SCSISEQ0, 0);
3591 } else if ((scb->flags & SCB_ABORT) != 0) {
3592
3593 if ((scb->hscb->control & TAG_ENB) != 0) {
3594 ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT_TAG;
3595 } else {
3596 ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT;
3597 }
3598 ahd->msgout_len++;
3599 ahd_print_path(ahd, scb);
3600 printf("Abort%s Message Sent\n",
3601 (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");
3602
3603
3604
3605
3606
3607
3608
3609 ahd_outb(ahd, SCSISEQ0, 0);
3610 } else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) {
3611 ahd_build_transfer_msg(ahd, devinfo);
3612
3613
3614
3615
3616
3617
3618
3619 ahd_outb(ahd, SCSISEQ0, 0);
3620 } else {
3621 printf("ahd_intr: AWAITING_MSG for an SCB that "
3622 "does not have a waiting message\n");
3623 printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
3624 devinfo->target_mask);
3625 panic("SCB = %d, SCB Control = %x:%x, MSG_OUT = %x "
3626 "SCB flags = %x", SCB_GET_TAG(scb), scb->hscb->control,
3627 ahd_inb_scbram(ahd, SCB_CONTROL), ahd_inb(ahd, MSG_OUT),
3628 scb->flags);
3629 }
3630
3631
3632
3633
3634
3635 ahd_outb(ahd, SCB_CONTROL,
3636 ahd_inb_scbram(ahd, SCB_CONTROL) & ~MK_MESSAGE);
3637 scb->hscb->control &= ~MK_MESSAGE;
3638 ahd->msgout_index = 0;
3639 ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
3640}
3641
3642
3643
3644
3645
3646static void
3647ahd_build_transfer_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
3648{
3649
3650
3651
3652
3653
3654 struct ahd_initiator_tinfo *tinfo;
3655 struct ahd_tmode_tstate *tstate;
3656 int dowide;
3657 int dosync;
3658 int doppr;
3659 u_int period;
3660 u_int ppr_options;
3661 u_int offset;
3662
3663 tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
3664 devinfo->target, &tstate);
3665
3666
3667
3668
3669
3670
3671 period = tinfo->goal.period;
3672 offset = tinfo->goal.offset;
3673 ppr_options = tinfo->goal.ppr_options;
3674
3675 if (devinfo->role == ROLE_TARGET)
3676 ppr_options = 0;
3677 ahd_devlimited_syncrate(ahd, tinfo, &period,
3678 &ppr_options, devinfo->role);
3679 dowide = tinfo->curr.width != tinfo->goal.width;
3680 dosync = tinfo->curr.offset != offset || tinfo->curr.period != period;
3681
3682
3683
3684
3685
3686 doppr = ppr_options != 0;
3687
3688 if (!dowide && !dosync && !doppr) {
3689 dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;
3690 dosync = tinfo->goal.offset != 0;
3691 }
3692
3693 if (!dowide && !dosync && !doppr) {
3694
3695
3696
3697
3698 if ((ahd->features & AHD_WIDE) != 0)
3699 dowide = 1;
3700 else
3701 dosync = 1;
3702
3703 if (bootverbose) {
3704 ahd_print_devinfo(ahd, devinfo);
3705 printf("Ensuring async\n");
3706 }
3707 }
3708
3709 if (devinfo->role == ROLE_TARGET)
3710 doppr = 0;
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720 if (doppr || (dosync && !dowide)) {
3721
3722 offset = tinfo->goal.offset;
3723 ahd_validate_offset(ahd, tinfo, period, &offset,
3724 doppr ? tinfo->goal.width
3725 : tinfo->curr.width,
3726 devinfo->role);
3727 if (doppr) {
3728 ahd_construct_ppr(ahd, devinfo, period, offset,
3729 tinfo->goal.width, ppr_options);
3730 } else {
3731 ahd_construct_sdtr(ahd, devinfo, period, offset);
3732 }
3733 } else {
3734 ahd_construct_wdtr(ahd, devinfo, tinfo->goal.width);
3735 }
3736}
3737
3738
3739
3740
3741
3742static void
3743ahd_construct_sdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3744 u_int period, u_int offset)
3745{
3746 if (offset == 0)
3747 period = AHD_ASYNC_XFER_PERIOD;
3748 ahd->msgout_index += spi_populate_sync_msg(
3749 ahd->msgout_buf + ahd->msgout_index, period, offset);
3750 ahd->msgout_len += 5;
3751 if (bootverbose) {
3752 printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
3753 ahd_name(ahd), devinfo->channel, devinfo->target,
3754 devinfo->lun, period, offset);
3755 }
3756}
3757
3758
3759
3760
3761
3762static void
3763ahd_construct_wdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3764 u_int bus_width)
3765{
3766 ahd->msgout_index += spi_populate_width_msg(
3767 ahd->msgout_buf + ahd->msgout_index, bus_width);
3768 ahd->msgout_len += 4;
3769 if (bootverbose) {
3770 printf("(%s:%c:%d:%d): Sending WDTR %x\n",
3771 ahd_name(ahd), devinfo->channel, devinfo->target,
3772 devinfo->lun, bus_width);
3773 }
3774}
3775
3776
3777
3778
3779
3780static void
3781ahd_construct_ppr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
3782 u_int period, u_int offset, u_int bus_width,
3783 u_int ppr_options)
3784{
3785
3786
3787
3788
3789
3790 if (period <= AHD_SYNCRATE_PACED)
3791 ppr_options |= MSG_EXT_PPR_PCOMP_EN;
3792 if (offset == 0)
3793 period = AHD_ASYNC_XFER_PERIOD;
3794 ahd->msgout_index += spi_populate_ppr_msg(
3795 ahd->msgout_buf + ahd->msgout_index, period, offset,
3796 bus_width, ppr_options);
3797 ahd->msgout_len += 8;
3798 if (bootverbose) {
3799 printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
3800 "offset %x, ppr_options %x\n", ahd_name(ahd),
3801 devinfo->channel, devinfo->target, devinfo->lun,
3802 bus_width, period, offset, ppr_options);
3803 }
3804}
3805
3806
3807
3808
3809static void
3810ahd_clear_msg_state(struct ahd_softc *ahd)
3811{
3812 ahd_mode_state saved_modes;
3813
3814 saved_modes = ahd_save_modes(ahd);
3815 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
3816 ahd->send_msg_perror = 0;
3817 ahd->msg_flags = MSG_FLAG_NONE;
3818 ahd->msgout_len = 0;
3819 ahd->msgin_index = 0;
3820 ahd->msg_type = MSG_TYPE_NONE;
3821 if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0) {
3822
3823
3824
3825
3826 ahd_outb(ahd, CLRSINT1, CLRATNO);
3827 }
3828 ahd_outb(ahd, MSG_OUT, MSG_NOOP);
3829 ahd_outb(ahd, SEQ_FLAGS2,
3830 ahd_inb(ahd, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
3831 ahd_restore_modes(ahd, saved_modes);
3832}
3833
3834
3835
3836
3837static void
3838ahd_handle_message_phase(struct ahd_softc *ahd)
3839{
3840 struct ahd_devinfo devinfo;
3841 u_int bus_phase;
3842 int end_session;
3843
3844 ahd_fetch_devinfo(ahd, &devinfo);
3845 end_session = FALSE;
3846 bus_phase = ahd_inb(ahd, LASTPHASE);
3847
3848 if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0) {
3849 printf("LQIRETRY for LQIPHASE_OUTPKT\n");
3850 ahd_outb(ahd, LQCTL2, LQIRETRY);
3851 }
3852reswitch:
3853 switch (ahd->msg_type) {
3854 case MSG_TYPE_INITIATOR_MSGOUT:
3855 {
3856 int lastbyte;
3857 int phasemis;
3858 int msgdone;
3859
3860 if (ahd->msgout_len == 0 && ahd->send_msg_perror == 0)
3861 panic("HOST_MSG_LOOP interrupt with no active message");
3862
3863#ifdef AHD_DEBUG
3864 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3865 ahd_print_devinfo(ahd, &devinfo);
3866 printf("INITIATOR_MSG_OUT");
3867 }
3868#endif
3869 phasemis = bus_phase != P_MESGOUT;
3870 if (phasemis) {
3871#ifdef AHD_DEBUG
3872 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3873 printf(" PHASEMIS %s\n",
3874 ahd_lookup_phase_entry(bus_phase)
3875 ->phasemsg);
3876 }
3877#endif
3878 if (bus_phase == P_MESGIN) {
3879
3880
3881
3882
3883
3884
3885 ahd_outb(ahd, CLRSINT1, CLRATNO);
3886 ahd->send_msg_perror = 0;
3887 ahd->msg_type = MSG_TYPE_INITIATOR_MSGIN;
3888 ahd->msgin_index = 0;
3889 goto reswitch;
3890 }
3891 end_session = TRUE;
3892 break;
3893 }
3894
3895 if (ahd->send_msg_perror) {
3896 ahd_outb(ahd, CLRSINT1, CLRATNO);
3897 ahd_outb(ahd, CLRSINT1, CLRREQINIT);
3898#ifdef AHD_DEBUG
3899 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3900 printf(" byte 0x%x\n", ahd->send_msg_perror);
3901#endif
3902
3903
3904
3905
3906
3907
3908 if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0
3909 && ahd->send_msg_perror == MSG_INITIATOR_DET_ERR)
3910 ahd->msg_flags |= MSG_FLAG_EXPECT_IDE_BUSFREE;
3911
3912 ahd_outb(ahd, RETURN_2, ahd->send_msg_perror);
3913 ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_WRITE);
3914 break;
3915 }
3916
3917 msgdone = ahd->msgout_index == ahd->msgout_len;
3918 if (msgdone) {
3919
3920
3921
3922
3923
3924 ahd->msgout_index = 0;
3925 ahd_assert_atn(ahd);
3926 }
3927
3928 lastbyte = ahd->msgout_index == (ahd->msgout_len - 1);
3929 if (lastbyte) {
3930
3931 ahd_outb(ahd, CLRSINT1, CLRATNO);
3932 }
3933
3934
3935
3936
3937
3938 ahd_outb(ahd, CLRSINT1, CLRREQINIT);
3939#ifdef AHD_DEBUG
3940 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3941 printf(" byte 0x%x\n",
3942 ahd->msgout_buf[ahd->msgout_index]);
3943#endif
3944 ahd_outb(ahd, RETURN_2, ahd->msgout_buf[ahd->msgout_index++]);
3945 ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_WRITE);
3946 break;
3947 }
3948 case MSG_TYPE_INITIATOR_MSGIN:
3949 {
3950 int phasemis;
3951 int message_done;
3952
3953#ifdef AHD_DEBUG
3954 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3955 ahd_print_devinfo(ahd, &devinfo);
3956 printf("INITIATOR_MSG_IN");
3957 }
3958#endif
3959 phasemis = bus_phase != P_MESGIN;
3960 if (phasemis) {
3961#ifdef AHD_DEBUG
3962 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
3963 printf(" PHASEMIS %s\n",
3964 ahd_lookup_phase_entry(bus_phase)
3965 ->phasemsg);
3966 }
3967#endif
3968 ahd->msgin_index = 0;
3969 if (bus_phase == P_MESGOUT
3970 && (ahd->send_msg_perror != 0
3971 || (ahd->msgout_len != 0
3972 && ahd->msgout_index == 0))) {
3973 ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
3974 goto reswitch;
3975 }
3976 end_session = TRUE;
3977 break;
3978 }
3979
3980
3981 ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIBUS);
3982#ifdef AHD_DEBUG
3983 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
3984 printf(" byte 0x%x\n",
3985 ahd->msgin_buf[ahd->msgin_index]);
3986#endif
3987
3988 message_done = ahd_parse_msg(ahd, &devinfo);
3989
3990 if (message_done) {
3991
3992
3993
3994
3995 ahd->msgin_index = 0;
3996
3997
3998
3999
4000
4001
4002 if (ahd->msgout_len != 0) {
4003#ifdef AHD_DEBUG
4004 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
4005 ahd_print_devinfo(ahd, &devinfo);
4006 printf("Asserting ATN for response\n");
4007 }
4008#endif
4009 ahd_assert_atn(ahd);
4010 }
4011 } else
4012 ahd->msgin_index++;
4013
4014 if (message_done == MSGLOOP_TERMINATED) {
4015 end_session = TRUE;
4016 } else {
4017
4018 ahd_outb(ahd, CLRSINT1, CLRREQINIT);
4019 ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_READ);
4020 }
4021 break;
4022 }
4023 case MSG_TYPE_TARGET_MSGIN:
4024 {
4025 int msgdone;
4026 int msgout_request;
4027
4028
4029
4030
4031 ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG);
4032
4033 if (ahd->msgout_len == 0)
4034 panic("Target MSGIN with no active message");
4035
4036
4037
4038
4039
4040
4041
4042 if ((ahd_inb(ahd, SCSISIGI) & ATNI) != 0
4043 && ahd->msgout_index > 0)
4044 msgout_request = TRUE;
4045 else
4046 msgout_request = FALSE;
4047
4048 if (msgout_request) {
4049
4050
4051
4052
4053
4054
4055
4056 ahd->msg_type = MSG_TYPE_TARGET_MSGOUT;
4057 ahd_outb(ahd, SCSISIGO, P_MESGOUT | BSYO);
4058 ahd->msgin_index = 0;
4059
4060 ahd_inb(ahd, SCSIDAT);
4061 ahd_outb(ahd, SXFRCTL0,
4062 ahd_inb(ahd, SXFRCTL0) | SPIOEN);
4063 break;
4064 }
4065
4066 msgdone = ahd->msgout_index == ahd->msgout_len;
4067 if (msgdone) {
4068 ahd_outb(ahd, SXFRCTL0,
4069 ahd_inb(ahd, SXFRCTL0) & ~SPIOEN);
4070 end_session = TRUE;
4071 break;
4072 }
4073
4074
4075
4076
4077 ahd_outb(ahd, SXFRCTL0, ahd_inb(ahd, SXFRCTL0) | SPIOEN);
4078 ahd_outb(ahd, SCSIDAT, ahd->msgout_buf[ahd->msgout_index++]);
4079 break;
4080 }
4081 case MSG_TYPE_TARGET_MSGOUT:
4082 {
4083 int lastbyte;
4084 int msgdone;
4085
4086
4087
4088
4089 ahd_outb(ahd, RETURN_1, CONT_MSG_LOOP_TARG);
4090
4091
4092
4093
4094
4095 lastbyte = (ahd_inb(ahd, SCSISIGI) & ATNI) == 0;
4096
4097
4098
4099
4100
4101
4102 ahd_outb(ahd, SXFRCTL0, ahd_inb(ahd, SXFRCTL0) & ~SPIOEN);
4103 ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIDAT);
4104 msgdone = ahd_parse_msg(ahd, &devinfo);
4105 if (msgdone == MSGLOOP_TERMINATED) {
4106
4107
4108
4109
4110
4111
4112 return;
4113 }
4114
4115 ahd->msgin_index++;
4116
4117
4118
4119
4120
4121 if (msgdone == MSGLOOP_MSGCOMPLETE) {
4122 ahd->msgin_index = 0;
4123
4124
4125
4126
4127
4128 if (ahd->msgout_len != 0) {
4129 ahd_outb(ahd, SCSISIGO, P_MESGIN | BSYO);
4130 ahd_outb(ahd, SXFRCTL0,
4131 ahd_inb(ahd, SXFRCTL0) | SPIOEN);
4132 ahd->msg_type = MSG_TYPE_TARGET_MSGIN;
4133 ahd->msgin_index = 0;
4134 break;
4135 }
4136 }
4137
4138 if (lastbyte)
4139 end_session = TRUE;
4140 else {
4141
4142 ahd_outb(ahd, SXFRCTL0,
4143 ahd_inb(ahd, SXFRCTL0) | SPIOEN);
4144 }
4145
4146 break;
4147 }
4148 default:
4149 panic("Unknown REQINIT message type");
4150 }
4151
4152 if (end_session) {
4153 if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0) {
4154 printf("%s: Returning to Idle Loop\n",
4155 ahd_name(ahd));
4156 ahd_clear_msg_state(ahd);
4157
4158
4159
4160
4161 ahd_outb(ahd, LASTPHASE, P_BUSFREE);
4162 ahd_outb(ahd, SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT);
4163 ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);
4164 } else {
4165 ahd_clear_msg_state(ahd);
4166 ahd_outb(ahd, RETURN_1, EXIT_MSG_LOOP);
4167 }
4168 }
4169}
4170
4171
4172
4173
4174
4175
4176
4177static int
4178ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type, u_int msgval, int full)
4179{
4180 int found;
4181 u_int index;
4182
4183 found = FALSE;
4184 index = 0;
4185
4186 while (index < ahd->msgout_len) {
4187 if (ahd->msgout_buf[index] == MSG_EXTENDED) {
4188 u_int end_index;
4189
4190 end_index = index + 1 + ahd->msgout_buf[index + 1];
4191 if (ahd->msgout_buf[index+2] == msgval
4192 && type == AHDMSG_EXT) {
4193
4194 if (full) {
4195 if (ahd->msgout_index > end_index)
4196 found = TRUE;
4197 } else if (ahd->msgout_index > index)
4198 found = TRUE;
4199 }
4200 index = end_index;
4201 } else if (ahd->msgout_buf[index] >= MSG_SIMPLE_TASK
4202 && ahd->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
4203
4204
4205 index += 2;
4206 } else {
4207
4208 if (type == AHDMSG_1B
4209 && ahd->msgout_index > index
4210 && (ahd->msgout_buf[index] == msgval
4211 || ((ahd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0
4212 && msgval == MSG_IDENTIFYFLAG)))
4213 found = TRUE;
4214 index++;
4215 }
4216
4217 if (found)
4218 break;
4219 }
4220 return (found);
4221}
4222
4223
4224
4225
4226static int
4227ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
4228{
4229 struct ahd_initiator_tinfo *tinfo;
4230 struct ahd_tmode_tstate *tstate;
4231 int reject;
4232 int done;
4233 int response;
4234
4235 done = MSGLOOP_IN_PROG;
4236 response = FALSE;
4237 reject = FALSE;
4238 tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
4239 devinfo->target, &tstate);
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252 switch (ahd->msgin_buf[0]) {
4253 case MSG_DISCONNECT:
4254 case MSG_SAVEDATAPOINTER:
4255 case MSG_CMDCOMPLETE:
4256 case MSG_RESTOREPOINTERS:
4257 case MSG_IGN_WIDE_RESIDUE:
4258
4259
4260
4261
4262 done = MSGLOOP_TERMINATED;
4263 break;
4264 case MSG_MESSAGE_REJECT:
4265 response = ahd_handle_msg_reject(ahd, devinfo);
4266
4267 case MSG_NOOP:
4268 done = MSGLOOP_MSGCOMPLETE;
4269 break;
4270 case MSG_EXTENDED:
4271 {
4272
4273 if (ahd->msgin_index < 2)
4274 break;
4275 switch (ahd->msgin_buf[2]) {
4276 case MSG_EXT_SDTR:
4277 {
4278 u_int period;
4279 u_int ppr_options;
4280 u_int offset;
4281 u_int saved_offset;
4282
4283 if (ahd->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
4284 reject = TRUE;
4285 break;
4286 }
4287
4288
4289
4290
4291
4292
4293
4294
4295 if (ahd->msgin_index < (MSG_EXT_SDTR_LEN + 1))
4296 break;
4297
4298 period = ahd->msgin_buf[3];
4299 ppr_options = 0;
4300 saved_offset = offset = ahd->msgin_buf[4];
4301 ahd_devlimited_syncrate(ahd, tinfo, &period,
4302 &ppr_options, devinfo->role);
4303 ahd_validate_offset(ahd, tinfo, period, &offset,
4304 tinfo->curr.width, devinfo->role);
4305 if (bootverbose) {
4306 printf("(%s:%c:%d:%d): Received "
4307 "SDTR period %x, offset %x\n\t"
4308 "Filtered to period %x, offset %x\n",
4309 ahd_name(ahd), devinfo->channel,
4310 devinfo->target, devinfo->lun,
4311 ahd->msgin_buf[3], saved_offset,
4312 period, offset);
4313 }
4314 ahd_set_syncrate(ahd, devinfo, period,
4315 offset, ppr_options,
4316 AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4317 TRUE);
4318
4319
4320
4321
4322
4323
4324 if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, TRUE)) {
4325
4326 if (saved_offset != offset) {
4327
4328 reject = TRUE;
4329 }
4330 } else {
4331
4332
4333
4334 if (bootverbose
4335 && devinfo->role == ROLE_INITIATOR) {
4336 printf("(%s:%c:%d:%d): Target "
4337 "Initiated SDTR\n",
4338 ahd_name(ahd), devinfo->channel,
4339 devinfo->target, devinfo->lun);
4340 }
4341 ahd->msgout_index = 0;
4342 ahd->msgout_len = 0;
4343 ahd_construct_sdtr(ahd, devinfo,
4344 period, offset);
4345 ahd->msgout_index = 0;
4346 response = TRUE;
4347 }
4348 done = MSGLOOP_MSGCOMPLETE;
4349 break;
4350 }
4351 case MSG_EXT_WDTR:
4352 {
4353 u_int bus_width;
4354 u_int saved_width;
4355 u_int sending_reply;
4356
4357 sending_reply = FALSE;
4358 if (ahd->msgin_buf[1] != MSG_EXT_WDTR_LEN) {
4359 reject = TRUE;
4360 break;
4361 }
4362
4363
4364
4365
4366
4367
4368
4369
4370 if (ahd->msgin_index < (MSG_EXT_WDTR_LEN + 1))
4371 break;
4372
4373 bus_width = ahd->msgin_buf[3];
4374 saved_width = bus_width;
4375 ahd_validate_width(ahd, tinfo, &bus_width,
4376 devinfo->role);
4377 if (bootverbose) {
4378 printf("(%s:%c:%d:%d): Received WDTR "
4379 "%x filtered to %x\n",
4380 ahd_name(ahd), devinfo->channel,
4381 devinfo->target, devinfo->lun,
4382 saved_width, bus_width);
4383 }
4384
4385 if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, TRUE)) {
4386
4387
4388
4389
4390
4391
4392 if (saved_width > bus_width) {
4393 reject = TRUE;
4394 printf("(%s:%c:%d:%d): requested %dBit "
4395 "transfers. Rejecting...\n",
4396 ahd_name(ahd), devinfo->channel,
4397 devinfo->target, devinfo->lun,
4398 8 * (0x01 << bus_width));
4399 bus_width = 0;
4400 }
4401 } else {
4402
4403
4404
4405 if (bootverbose
4406 && devinfo->role == ROLE_INITIATOR) {
4407 printf("(%s:%c:%d:%d): Target "
4408 "Initiated WDTR\n",
4409 ahd_name(ahd), devinfo->channel,
4410 devinfo->target, devinfo->lun);
4411 }
4412 ahd->msgout_index = 0;
4413 ahd->msgout_len = 0;
4414 ahd_construct_wdtr(ahd, devinfo, bus_width);
4415 ahd->msgout_index = 0;
4416 response = TRUE;
4417 sending_reply = TRUE;
4418 }
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428 ahd_update_neg_request(ahd, devinfo, tstate,
4429 tinfo, AHD_NEG_ALWAYS);
4430 ahd_set_width(ahd, devinfo, bus_width,
4431 AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4432 TRUE);
4433 if (sending_reply == FALSE && reject == FALSE) {
4434
4435
4436
4437
4438 ahd->msgout_index = 0;
4439 ahd->msgout_len = 0;
4440 ahd_build_transfer_msg(ahd, devinfo);
4441 ahd->msgout_index = 0;
4442 response = TRUE;
4443 }
4444 done = MSGLOOP_MSGCOMPLETE;
4445 break;
4446 }
4447 case MSG_EXT_PPR:
4448 {
4449 u_int period;
4450 u_int offset;
4451 u_int bus_width;
4452 u_int ppr_options;
4453 u_int saved_width;
4454 u_int saved_offset;
4455 u_int saved_ppr_options;
4456
4457 if (ahd->msgin_buf[1] != MSG_EXT_PPR_LEN) {
4458 reject = TRUE;
4459 break;
4460 }
4461
4462
4463
4464
4465
4466
4467
4468
4469 if (ahd->msgin_index < (MSG_EXT_PPR_LEN + 1))
4470 break;
4471
4472 period = ahd->msgin_buf[3];
4473 offset = ahd->msgin_buf[5];
4474 bus_width = ahd->msgin_buf[6];
4475 saved_width = bus_width;
4476 ppr_options = ahd->msgin_buf[7];
4477
4478
4479
4480
4481
4482 if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 0
4483 && period <= 9)
4484 offset = 0;
4485 saved_ppr_options = ppr_options;
4486 saved_offset = offset;
4487
4488
4489
4490
4491
4492 if (bus_width == 0)
4493 ppr_options &= MSG_EXT_PPR_QAS_REQ;
4494
4495 ahd_validate_width(ahd, tinfo, &bus_width,
4496 devinfo->role);
4497 ahd_devlimited_syncrate(ahd, tinfo, &period,
4498 &ppr_options, devinfo->role);
4499 ahd_validate_offset(ahd, tinfo, period, &offset,
4500 bus_width, devinfo->role);
4501
4502 if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, TRUE)) {
4503
4504
4505
4506
4507
4508 if (saved_width > bus_width
4509 || saved_offset != offset
4510 || saved_ppr_options != ppr_options) {
4511 reject = TRUE;
4512 period = 0;
4513 offset = 0;
4514 bus_width = 0;
4515 ppr_options = 0;
4516 }
4517 } else {
4518 if (devinfo->role != ROLE_TARGET)
4519 printf("(%s:%c:%d:%d): Target "
4520 "Initiated PPR\n",
4521 ahd_name(ahd), devinfo->channel,
4522 devinfo->target, devinfo->lun);
4523 else
4524 printf("(%s:%c:%d:%d): Initiator "
4525 "Initiated PPR\n",
4526 ahd_name(ahd), devinfo->channel,
4527 devinfo->target, devinfo->lun);
4528 ahd->msgout_index = 0;
4529 ahd->msgout_len = 0;
4530 ahd_construct_ppr(ahd, devinfo, period, offset,
4531 bus_width, ppr_options);
4532 ahd->msgout_index = 0;
4533 response = TRUE;
4534 }
4535 if (bootverbose) {
4536 printf("(%s:%c:%d:%d): Received PPR width %x, "
4537 "period %x, offset %x,options %x\n"
4538 "\tFiltered to width %x, period %x, "
4539 "offset %x, options %x\n",
4540 ahd_name(ahd), devinfo->channel,
4541 devinfo->target, devinfo->lun,
4542 saved_width, ahd->msgin_buf[3],
4543 saved_offset, saved_ppr_options,
4544 bus_width, period, offset, ppr_options);
4545 }
4546 ahd_set_width(ahd, devinfo, bus_width,
4547 AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4548 TRUE);
4549 ahd_set_syncrate(ahd, devinfo, period,
4550 offset, ppr_options,
4551 AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4552 TRUE);
4553
4554 done = MSGLOOP_MSGCOMPLETE;
4555 break;
4556 }
4557 default:
4558
4559 reject = TRUE;
4560 break;
4561 }
4562 break;
4563 }
4564#ifdef AHD_TARGET_MODE
4565 case MSG_BUS_DEV_RESET:
4566 ahd_handle_devreset(ahd, devinfo, CAM_LUN_WILDCARD,
4567 CAM_BDR_SENT,
4568 "Bus Device Reset Received",
4569 0);
4570 ahd_restart(ahd);
4571 done = MSGLOOP_TERMINATED;
4572 break;
4573 case MSG_ABORT_TAG:
4574 case MSG_ABORT:
4575 case MSG_CLEAR_QUEUE:
4576 {
4577 int tag;
4578
4579
4580 if (devinfo->role != ROLE_TARGET) {
4581 reject = TRUE;
4582 break;
4583 }
4584 tag = SCB_LIST_NULL;
4585 if (ahd->msgin_buf[0] == MSG_ABORT_TAG)
4586 tag = ahd_inb(ahd, INITIATOR_TAG);
4587 ahd_abort_scbs(ahd, devinfo->target, devinfo->channel,
4588 devinfo->lun, tag, ROLE_TARGET,
4589 CAM_REQ_ABORTED);
4590
4591 tstate = ahd->enabled_targets[devinfo->our_scsiid];
4592 if (tstate != NULL) {
4593 struct ahd_tmode_lstate* lstate;
4594
4595 lstate = tstate->enabled_luns[devinfo->lun];
4596 if (lstate != NULL) {
4597 ahd_queue_lstate_event(ahd, lstate,
4598 devinfo->our_scsiid,
4599 ahd->msgin_buf[0],
4600 tag);
4601 ahd_send_lstate_events(ahd, lstate);
4602 }
4603 }
4604 ahd_restart(ahd);
4605 done = MSGLOOP_TERMINATED;
4606 break;
4607 }
4608#endif
4609 case MSG_QAS_REQUEST:
4610#ifdef AHD_DEBUG
4611 if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
4612 printf("%s: QAS request. SCSISIGI == 0x%x\n",
4613 ahd_name(ahd), ahd_inb(ahd, SCSISIGI));
4614#endif
4615 ahd->msg_flags |= MSG_FLAG_EXPECT_QASREJ_BUSFREE;
4616
4617 case MSG_TERM_IO_PROC:
4618 default:
4619 reject = TRUE;
4620 break;
4621 }
4622
4623 if (reject) {
4624
4625
4626
4627 ahd->msgout_index = 0;
4628 ahd->msgout_len = 1;
4629 ahd->msgout_buf[0] = MSG_MESSAGE_REJECT;
4630 done = MSGLOOP_MSGCOMPLETE;
4631 response = TRUE;
4632 }
4633
4634 if (done != MSGLOOP_IN_PROG && !response)
4635
4636 ahd->msgout_len = 0;
4637
4638 return (done);
4639}
4640
4641
4642
4643
4644static int
4645ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
4646{
4647
4648
4649
4650
4651
4652
4653 struct scb *scb;
4654 struct ahd_initiator_tinfo *tinfo;
4655 struct ahd_tmode_tstate *tstate;
4656 u_int scb_index;
4657 u_int last_msg;
4658 int response = 0;
4659
4660 scb_index = ahd_get_scbptr(ahd);
4661 scb = ahd_lookup_scb(ahd, scb_index);
4662 tinfo = ahd_fetch_transinfo(ahd, devinfo->channel,
4663 devinfo->our_scsiid,
4664 devinfo->target, &tstate);
4665
4666 last_msg = ahd_inb(ahd, LAST_MSG);
4667
4668 if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE)) {
4669 if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, TRUE)
4670 && tinfo->goal.period <= AHD_SYNCRATE_PACED) {
4671
4672
4673
4674
4675
4676 if (bootverbose) {
4677 printf("(%s:%c:%d:%d): PPR Rejected. "
4678 "Trying simple U160 PPR\n",
4679 ahd_name(ahd), devinfo->channel,
4680 devinfo->target, devinfo->lun);
4681 }
4682 tinfo->goal.period = AHD_SYNCRATE_DT;
4683 tinfo->goal.ppr_options &= MSG_EXT_PPR_IU_REQ
4684 | MSG_EXT_PPR_QAS_REQ
4685 | MSG_EXT_PPR_DT_REQ;
4686 } else {
4687
4688
4689
4690
4691 if (bootverbose) {
4692 printf("(%s:%c:%d:%d): PPR Rejected. "
4693 "Trying WDTR/SDTR\n",
4694 ahd_name(ahd), devinfo->channel,
4695 devinfo->target, devinfo->lun);
4696 }
4697 tinfo->goal.ppr_options = 0;
4698 tinfo->curr.transport_version = 2;
4699 tinfo->goal.transport_version = 2;
4700 }
4701 ahd->msgout_index = 0;
4702 ahd->msgout_len = 0;
4703 ahd_build_transfer_msg(ahd, devinfo);
4704 ahd->msgout_index = 0;
4705 response = 1;
4706 } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)) {
4707
4708
4709 printf("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
4710 "8bit transfers\n", ahd_name(ahd),
4711 devinfo->channel, devinfo->target, devinfo->lun);
4712 ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
4713 AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4714 TRUE);
4715
4716
4717
4718
4719
4720
4721
4722 if (tinfo->goal.offset != tinfo->curr.offset) {
4723
4724
4725 ahd->msgout_index = 0;
4726 ahd->msgout_len = 0;
4727 ahd_build_transfer_msg(ahd, devinfo);
4728 ahd->msgout_index = 0;
4729 response = 1;
4730 }
4731 } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)) {
4732
4733 ahd_set_syncrate(ahd, devinfo, 0,
4734 0, 0,
4735 AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
4736 TRUE);
4737 printf("(%s:%c:%d:%d): refuses synchronous negotiation. "
4738 "Using asynchronous transfers\n",
4739 ahd_name(ahd), devinfo->channel,
4740 devinfo->target, devinfo->lun);
4741 } else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) {
4742 int tag_type;
4743 int mask;
4744
4745 tag_type = (scb->hscb->control & MSG_SIMPLE_TASK);
4746
4747 if (tag_type == MSG_SIMPLE_TASK) {
4748 printf("(%s:%c:%d:%d): refuses tagged commands. "
4749 "Performing non-tagged I/O\n", ahd_name(ahd),
4750 devinfo->channel, devinfo->target, devinfo->lun);
4751 ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_NONE);
4752 mask = ~0x23;
4753 } else {
4754 printf("(%s:%c:%d:%d): refuses %s tagged commands. "
4755 "Performing simple queue tagged I/O only\n",
4756 ahd_name(ahd), devinfo->channel, devinfo->target,
4757 devinfo->lun, tag_type == MSG_ORDERED_TASK
4758 ? "ordered" : "head of queue");
4759 ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_BASIC);
4760 mask = ~0x03;
4761 }
4762
4763
4764
4765
4766
4767 ahd_outb(ahd, SCB_CONTROL,
4768 ahd_inb_scbram(ahd, SCB_CONTROL) & mask);
4769 scb->hscb->control &= mask;
4770 ahd_set_transaction_tag(scb, FALSE,
4771 MSG_SIMPLE_TASK);
4772 ahd_outb(ahd, MSG_OUT, MSG_IDENTIFYFLAG);
4773 ahd_assert_atn(ahd);
4774 ahd_busy_tcl(ahd, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
4775 SCB_GET_TAG(scb));
4776
4777
4778
4779
4780
4781
4782 ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
4783 SCB_GET_CHANNEL(ahd, scb),
4784 SCB_GET_LUN(scb), SCB_LIST_NULL,
4785 ROLE_INITIATOR, CAM_REQUEUE_REQ,
4786 SEARCH_COMPLETE);
4787 } else if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_IDENTIFYFLAG, TRUE)) {
4788
4789
4790
4791
4792 ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE
4793 | MSG_FLAG_IU_REQ_CHANGED;
4794
4795 ahd_force_renegotiation(ahd, devinfo);
4796 ahd->msgout_index = 0;
4797 ahd->msgout_len = 0;
4798 ahd_build_transfer_msg(ahd, devinfo);
4799 ahd->msgout_index = 0;
4800 response = 1;
4801 } else {
4802
4803
4804
4805 printf("%s:%c:%d: Message reject for %x -- ignored\n",
4806 ahd_name(ahd), devinfo->channel, devinfo->target,
4807 last_msg);
4808 }
4809 return (response);
4810}
4811
4812
4813
4814
4815static void
4816ahd_handle_ign_wide_residue(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
4817{
4818 u_int scb_index;
4819 struct scb *scb;
4820
4821 scb_index = ahd_get_scbptr(ahd);
4822 scb = ahd_lookup_scb(ahd, scb_index);
4823
4824
4825
4826
4827 if ((ahd_inb(ahd, SEQ_FLAGS) & DPHASE) == 0
4828 || ahd_get_transfer_dir(scb) != CAM_DIR_IN) {
4829
4830
4831
4832
4833 } else {
4834
4835
4836
4837
4838
4839
4840
4841 uint32_t sgptr;
4842
4843 sgptr = ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR);
4844 if ((sgptr & SG_LIST_NULL) != 0
4845 && (ahd_inb_scbram(ahd, SCB_TASK_ATTRIBUTE)
4846 & SCB_XFERLEN_ODD) != 0) {
4847
4848
4849
4850
4851
4852
4853 } else {
4854 uint32_t data_cnt;
4855 uint64_t data_addr;
4856 uint32_t sglen;
4857
4858
4859 sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
4860 data_cnt = ahd_inl_scbram(ahd, SCB_RESIDUAL_DATACNT);
4861 if ((sgptr & SG_LIST_NULL) != 0) {
4862
4863
4864
4865
4866
4867 data_cnt &= ~AHD_SG_LEN_MASK;
4868 }
4869 data_addr = ahd_inq(ahd, SHADDR);
4870 data_cnt += 1;
4871 data_addr -= 1;
4872 sgptr &= SG_PTR_MASK;
4873 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
4874 struct ahd_dma64_seg *sg;
4875
4876 sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
4877
4878
4879
4880
4881
4882 sg--;
4883 sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
4884 if (sg != scb->sg_list
4885 && sglen < (data_cnt & AHD_SG_LEN_MASK)) {
4886
4887 sg--;
4888 sglen = ahd_le32toh(sg->len);
4889
4890
4891
4892
4893 data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK));
4894 data_addr = ahd_le64toh(sg->addr)
4895 + (sglen & AHD_SG_LEN_MASK)
4896 - 1;
4897
4898
4899
4900
4901
4902 sg++;
4903 sgptr = ahd_sg_virt_to_bus(ahd, scb,
4904 sg);
4905 }
4906 } else {
4907 struct ahd_dma_seg *sg;
4908
4909 sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
4910
4911
4912
4913
4914
4915 sg--;
4916 sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
4917 if (sg != scb->sg_list
4918 && sglen < (data_cnt & AHD_SG_LEN_MASK)) {
4919
4920 sg--;
4921 sglen = ahd_le32toh(sg->len);
4922
4923
4924
4925
4926 data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK));
4927 data_addr = ahd_le32toh(sg->addr)
4928 + (sglen & AHD_SG_LEN_MASK)
4929 - 1;
4930
4931
4932
4933
4934
4935 sg++;
4936 sgptr = ahd_sg_virt_to_bus(ahd, scb,
4937 sg);
4938 }
4939 }
4940
4941
4942
4943
4944
4945
4946 ahd_outb(ahd, SCB_TASK_ATTRIBUTE,
4947 ahd_inb_scbram(ahd, SCB_TASK_ATTRIBUTE)
4948 ^ SCB_XFERLEN_ODD);
4949
4950 ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
4951 ahd_outl(ahd, SCB_RESIDUAL_DATACNT, data_cnt);
4952
4953
4954
4955
4956 }
4957 }
4958}
4959
4960
4961
4962
4963
4964
4965static void
4966ahd_reinitialize_dataptrs(struct ahd_softc *ahd)
4967{
4968 struct scb *scb;
4969 ahd_mode_state saved_modes;
4970 u_int scb_index;
4971 u_int wait;
4972 uint32_t sgptr;
4973 uint32_t resid;
4974 uint64_t dataptr;
4975
4976 AHD_ASSERT_MODES(ahd, AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK,
4977 AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK);
4978
4979 scb_index = ahd_get_scbptr(ahd);
4980 scb = ahd_lookup_scb(ahd, scb_index);
4981
4982
4983
4984
4985
4986 ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
4987 wait = 1000;
4988 while (--wait && !(ahd_inb(ahd, MDFFSTAT) & FIFOFREE))
4989 ahd_delay(100);
4990 if (wait == 0) {
4991 ahd_print_path(ahd, scb);
4992 printf("ahd_reinitialize_dataptrs: Forcing FIFO free.\n");
4993 ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT);
4994 }
4995 saved_modes = ahd_save_modes(ahd);
4996 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
4997 ahd_outb(ahd, DFFSTAT,
4998 ahd_inb(ahd, DFFSTAT)
4999 | (saved_modes == 0x11 ? CURRFIFO_1 : CURRFIFO_0));
5000
5001
5002
5003
5004
5005 sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
5006 sgptr &= SG_PTR_MASK;
5007
5008 resid = (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 2) << 16)
5009 | (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 1) << 8)
5010 | ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT);
5011
5012 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
5013 struct ahd_dma64_seg *sg;
5014
5015 sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
5016
5017
5018 sg--;
5019
5020 dataptr = ahd_le64toh(sg->addr)
5021 + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK)
5022 - resid;
5023 ahd_outl(ahd, HADDR + 4, dataptr >> 32);
5024 } else {
5025 struct ahd_dma_seg *sg;
5026
5027 sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
5028
5029
5030 sg--;
5031
5032 dataptr = ahd_le32toh(sg->addr)
5033 + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK)
5034 - resid;
5035 ahd_outb(ahd, HADDR + 4,
5036 (ahd_le32toh(sg->len) & ~AHD_SG_LEN_MASK) >> 24);
5037 }
5038 ahd_outl(ahd, HADDR, dataptr);
5039 ahd_outb(ahd, HCNT + 2, resid >> 16);
5040 ahd_outb(ahd, HCNT + 1, resid >> 8);
5041 ahd_outb(ahd, HCNT, resid);
5042}
5043
5044
5045
5046
5047static void
5048ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
5049 u_int lun, cam_status status, char *message,
5050 int verbose_level)
5051{
5052#ifdef AHD_TARGET_MODE
5053 struct ahd_tmode_tstate* tstate;
5054#endif
5055 int found;
5056
5057 found = ahd_abort_scbs(ahd, devinfo->target, devinfo->channel,
5058 lun, SCB_LIST_NULL, devinfo->role,
5059 status);
5060
5061#ifdef AHD_TARGET_MODE
5062
5063
5064
5065
5066 tstate = ahd->enabled_targets[devinfo->our_scsiid];
5067 if (tstate != NULL) {
5068 u_int cur_lun;
5069 u_int max_lun;
5070
5071 if (lun != CAM_LUN_WILDCARD) {
5072 cur_lun = 0;
5073 max_lun = AHD_NUM_LUNS - 1;
5074 } else {
5075 cur_lun = lun;
5076 max_lun = lun;
5077 }
5078 for (cur_lun <= max_lun; cur_lun++) {
5079 struct ahd_tmode_lstate* lstate;
5080
5081 lstate = tstate->enabled_luns[cur_lun];
5082 if (lstate == NULL)
5083 continue;
5084
5085 ahd_queue_lstate_event(ahd, lstate, devinfo->our_scsiid,
5086 MSG_BUS_DEV_RESET, 0);
5087 ahd_send_lstate_events(ahd, lstate);
5088 }
5089 }
5090#endif
5091
5092
5093
5094
5095 ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
5096 AHD_TRANS_CUR, TRUE);
5097 ahd_set_syncrate(ahd, devinfo, 0, 0,
5098 0, AHD_TRANS_CUR,
5099 TRUE);
5100
5101 if (status != CAM_SEL_TIMEOUT)
5102 ahd_send_async(ahd, devinfo->channel, devinfo->target,
5103 CAM_LUN_WILDCARD, AC_SENT_BDR);
5104
5105 if (message != NULL && bootverbose)
5106 printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd),
5107 message, devinfo->channel, devinfo->target, found);
5108}
5109
5110#ifdef AHD_TARGET_MODE
5111static void
5112ahd_setup_target_msgin(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
5113 struct scb *scb)
5114{
5115
5116
5117
5118
5119
5120
5121 ahd->msgout_index = 0;
5122 ahd->msgout_len = 0;
5123
5124 if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0)
5125 ahd_build_transfer_msg(ahd, devinfo);
5126 else
5127 panic("ahd_intr: AWAITING target message with no message");
5128
5129 ahd->msgout_index = 0;
5130 ahd->msg_type = MSG_TYPE_TARGET_MSGIN;
5131}
5132#endif
5133
5134static u_int
5135ahd_sglist_size(struct ahd_softc *ahd)
5136{
5137 bus_size_t list_size;
5138
5139 list_size = sizeof(struct ahd_dma_seg) * AHD_NSEG;
5140 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
5141 list_size = sizeof(struct ahd_dma64_seg) * AHD_NSEG;
5142 return (list_size);
5143}
5144
5145
5146
5147
5148
5149
5150
5151static u_int
5152ahd_sglist_allocsize(struct ahd_softc *ahd)
5153{
5154 bus_size_t sg_list_increment;
5155 bus_size_t sg_list_size;
5156 bus_size_t max_list_size;
5157 bus_size_t best_list_size;
5158
5159
5160 sg_list_increment = ahd_sglist_size(ahd);
5161 sg_list_size = sg_list_increment;
5162
5163
5164 while ((sg_list_size + sg_list_increment) <= PAGE_SIZE)
5165 sg_list_size += sg_list_increment;
5166
5167
5168
5169
5170
5171 best_list_size = sg_list_size;
5172 max_list_size = roundup(sg_list_increment, PAGE_SIZE);
5173 if (max_list_size < 4 * PAGE_SIZE)
5174 max_list_size = 4 * PAGE_SIZE;
5175 if (max_list_size > (AHD_SCB_MAX_ALLOC * sg_list_increment))
5176 max_list_size = (AHD_SCB_MAX_ALLOC * sg_list_increment);
5177 while ((sg_list_size + sg_list_increment) <= max_list_size
5178 && (sg_list_size % PAGE_SIZE) != 0) {
5179 bus_size_t new_mod;
5180 bus_size_t best_mod;
5181
5182 sg_list_size += sg_list_increment;
5183 new_mod = sg_list_size % PAGE_SIZE;
5184 best_mod = best_list_size % PAGE_SIZE;
5185 if (new_mod > best_mod || new_mod == 0) {
5186 best_list_size = sg_list_size;
5187 }
5188 }
5189 return (best_list_size);
5190}
5191
5192
5193
5194
5195
5196struct ahd_softc *
5197ahd_alloc(void *platform_arg, char *name)
5198{
5199 struct ahd_softc *ahd;
5200
5201#ifndef __FreeBSD__
5202 ahd = malloc(sizeof(*ahd), M_DEVBUF, M_NOWAIT);
5203 if (!ahd) {
5204 printf("aic7xxx: cannot malloc softc!\n");
5205 free(name, M_DEVBUF);
5206 return NULL;
5207 }
5208#else
5209 ahd = device_get_softc((device_t)platform_arg);
5210#endif
5211 memset(ahd, 0, sizeof(*ahd));
5212 ahd->seep_config = malloc(sizeof(*ahd->seep_config),
5213 M_DEVBUF, M_NOWAIT);
5214 if (ahd->seep_config == NULL) {
5215#ifndef __FreeBSD__
5216 free(ahd, M_DEVBUF);
5217#endif
5218 free(name, M_DEVBUF);
5219 return (NULL);
5220 }
5221 LIST_INIT(&ahd->pending_scbs);
5222
5223 ahd->name = name;
5224 ahd->unit = -1;
5225 ahd->description = NULL;
5226 ahd->bus_description = NULL;
5227 ahd->channel = 'A';
5228 ahd->chip = AHD_NONE;
5229 ahd->features = AHD_FENONE;
5230 ahd->bugs = AHD_BUGNONE;
5231 ahd->flags = AHD_SPCHK_ENB_A|AHD_RESET_BUS_A|AHD_TERM_ENB_A
5232 | AHD_EXTENDED_TRANS_A|AHD_STPWLEVEL_A;
5233 ahd_timer_init(&ahd->reset_timer);
5234 ahd_timer_init(&ahd->stat_timer);
5235 ahd->int_coalescing_timer = AHD_INT_COALESCING_TIMER_DEFAULT;
5236 ahd->int_coalescing_maxcmds = AHD_INT_COALESCING_MAXCMDS_DEFAULT;
5237 ahd->int_coalescing_mincmds = AHD_INT_COALESCING_MINCMDS_DEFAULT;
5238 ahd->int_coalescing_threshold = AHD_INT_COALESCING_THRESHOLD_DEFAULT;
5239 ahd->int_coalescing_stop_threshold =
5240 AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT;
5241
5242 if (ahd_platform_alloc(ahd, platform_arg) != 0) {
5243 ahd_free(ahd);
5244 ahd = NULL;
5245 }
5246#ifdef AHD_DEBUG
5247 if ((ahd_debug & AHD_SHOW_MEMORY) != 0) {
5248 printf("%s: scb size = 0x%x, hscb size = 0x%x\n",
5249 ahd_name(ahd), (u_int)sizeof(struct scb),
5250 (u_int)sizeof(struct hardware_scb));
5251 }
5252#endif
5253 return (ahd);
5254}
5255
5256int
5257ahd_softc_init(struct ahd_softc *ahd)
5258{
5259
5260 ahd->unpause = 0;
5261 ahd->pause = PAUSE;
5262 return (0);
5263}
5264
5265void
5266ahd_set_unit(struct ahd_softc *ahd, int unit)
5267{
5268 ahd->unit = unit;
5269}
5270
5271void
5272ahd_set_name(struct ahd_softc *ahd, char *name)
5273{
5274 if (ahd->name != NULL)
5275 free(ahd->name, M_DEVBUF);
5276 ahd->name = name;
5277}
5278
5279void
5280ahd_free(struct ahd_softc *ahd)
5281{
5282 int i;
5283
5284 switch (ahd->init_level) {
5285 default:
5286 case 5:
5287 ahd_shutdown(ahd);
5288
5289 case 4:
5290 ahd_dmamap_unload(ahd, ahd->shared_data_dmat,
5291 ahd->shared_data_map.dmamap);
5292
5293 case 3:
5294 ahd_dmamem_free(ahd, ahd->shared_data_dmat, ahd->qoutfifo,
5295 ahd->shared_data_map.dmamap);
5296 ahd_dmamap_destroy(ahd, ahd->shared_data_dmat,
5297 ahd->shared_data_map.dmamap);
5298
5299 case 2:
5300 ahd_dma_tag_destroy(ahd, ahd->shared_data_dmat);
5301 case 1:
5302#ifndef __linux__
5303 ahd_dma_tag_destroy(ahd, ahd->buffer_dmat);
5304#endif
5305 break;
5306 case 0:
5307 break;
5308 }
5309
5310#ifndef __linux__
5311 ahd_dma_tag_destroy(ahd, ahd->parent_dmat);
5312#endif
5313 ahd_platform_free(ahd);
5314 ahd_fini_scbdata(ahd);
5315 for (i = 0; i < AHD_NUM_TARGETS; i++) {
5316 struct ahd_tmode_tstate *tstate;
5317
5318 tstate = ahd->enabled_targets[i];
5319 if (tstate != NULL) {
5320#ifdef AHD_TARGET_MODE
5321 int j;
5322
5323 for (j = 0; j < AHD_NUM_LUNS; j++) {
5324 struct ahd_tmode_lstate *lstate;
5325
5326 lstate = tstate->enabled_luns[j];
5327 if (lstate != NULL) {
5328 xpt_free_path(lstate->path);
5329 free(lstate, M_DEVBUF);
5330 }
5331 }
5332#endif
5333 free(tstate, M_DEVBUF);
5334 }
5335 }
5336#ifdef AHD_TARGET_MODE
5337 if (ahd->black_hole != NULL) {
5338 xpt_free_path(ahd->black_hole->path);
5339 free(ahd->black_hole, M_DEVBUF);
5340 }
5341#endif
5342 if (ahd->name != NULL)
5343 free(ahd->name, M_DEVBUF);
5344 if (ahd->seep_config != NULL)
5345 free(ahd->seep_config, M_DEVBUF);
5346 if (ahd->saved_stack != NULL)
5347 free(ahd->saved_stack, M_DEVBUF);
5348#ifndef __FreeBSD__
5349 free(ahd, M_DEVBUF);
5350#endif
5351 return;
5352}
5353
5354void
5355ahd_shutdown(void *arg)
5356{
5357 struct ahd_softc *ahd;
5358
5359 ahd = (struct ahd_softc *)arg;
5360
5361
5362
5363
5364 ahd_timer_stop(&ahd->reset_timer);
5365 ahd_timer_stop(&ahd->stat_timer);
5366
5367
5368 ahd_reset(ahd, FALSE);
5369}
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380int
5381ahd_reset(struct ahd_softc *ahd, int reinit)
5382{
5383 u_int sxfrctl1;
5384 int wait;
5385 uint32_t cmd;
5386
5387
5388
5389
5390
5391
5392 ahd_pause(ahd);
5393 ahd_update_modes(ahd);
5394 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
5395 sxfrctl1 = ahd_inb(ahd, SXFRCTL1);
5396
5397 cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 2);
5398 if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) {
5399 uint32_t mod_cmd;
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410 mod_cmd = cmd & ~(PCIM_CMD_PERRESPEN|PCIM_CMD_SERRESPEN);
5411 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
5412 mod_cmd, 2);
5413 }
5414 ahd_outb(ahd, HCNTRL, CHIPRST | ahd->pause);
5415
5416
5417
5418
5419
5420
5421
5422 wait = 1000;
5423 do {
5424 ahd_delay(1000);
5425 } while (--wait && !(ahd_inb(ahd, HCNTRL) & CHIPRSTACK));
5426
5427 if (wait == 0) {
5428 printf("%s: WARNING - Failed chip reset! "
5429 "Trying to initialize anyway.\n", ahd_name(ahd));
5430 }
5431 ahd_outb(ahd, HCNTRL, ahd->pause);
5432
5433 if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) {
5434
5435
5436
5437
5438 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
5439 0xFF, 1);
5440 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
5441 cmd, 2);
5442 }
5443
5444
5445
5446
5447
5448
5449
5450 ahd_known_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
5451 ahd_outb(ahd, MODE_PTR,
5452 ahd_build_mode_state(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI));
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462 ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
5463 ahd_outb(ahd, SXFRCTL1, sxfrctl1);
5464
5465
5466 ahd->features &= ~AHD_WIDE;
5467 if ((ahd_inb(ahd, SBLKCTL) & SELWIDE) != 0)
5468 ahd->features |= AHD_WIDE;
5469
5470
5471
5472
5473
5474 if (reinit != 0)
5475 ahd_chip_init(ahd);
5476
5477 return (0);
5478}
5479
5480
5481
5482
5483int
5484ahd_probe_scbs(struct ahd_softc *ahd) {
5485 int i;
5486
5487 AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
5488 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
5489 for (i = 0; i < AHD_SCB_MAX; i++) {
5490 int j;
5491
5492 ahd_set_scbptr(ahd, i);
5493 ahd_outw(ahd, SCB_BASE, i);
5494 for (j = 2; j < 64; j++)
5495 ahd_outb(ahd, SCB_BASE+j, 0);
5496
5497 ahd_outb(ahd, SCB_CONTROL, MK_MESSAGE);
5498 if (ahd_inw_scbram(ahd, SCB_BASE) != i)
5499 break;
5500 ahd_set_scbptr(ahd, 0);
5501 if (ahd_inw_scbram(ahd, SCB_BASE) != 0)
5502 break;
5503 }
5504 return (i);
5505}
5506
5507static void
5508ahd_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
5509{
5510 dma_addr_t *baddr;
5511
5512 baddr = (dma_addr_t *)arg;
5513 *baddr = segs->ds_addr;
5514}
5515
5516static void
5517ahd_initialize_hscbs(struct ahd_softc *ahd)
5518{
5519 int i;
5520
5521 for (i = 0; i < ahd->scb_data.maxhscbs; i++) {
5522 ahd_set_scbptr(ahd, i);
5523
5524
5525 ahd_outb(ahd, SCB_CONTROL, 0);
5526
5527
5528 ahd_outw(ahd, SCB_NEXT, SCB_LIST_NULL);
5529 }
5530}
5531
5532static int
5533ahd_init_scbdata(struct ahd_softc *ahd)
5534{
5535 struct scb_data *scb_data;
5536 int i;
5537
5538 scb_data = &ahd->scb_data;
5539 TAILQ_INIT(&scb_data->free_scbs);
5540 for (i = 0; i < AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT; i++)
5541 LIST_INIT(&scb_data->free_scb_lists[i]);
5542 LIST_INIT(&scb_data->any_dev_free_scb_list);
5543 SLIST_INIT(&scb_data->hscb_maps);
5544 SLIST_INIT(&scb_data->sg_maps);
5545 SLIST_INIT(&scb_data->sense_maps);
5546
5547
5548 scb_data->maxhscbs = ahd_probe_scbs(ahd);
5549 if (scb_data->maxhscbs == 0) {
5550 printf("%s: No SCB space found\n", ahd_name(ahd));
5551 return (ENXIO);
5552 }
5553
5554 ahd_initialize_hscbs(ahd);
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, 1,
5568 BUS_SPACE_MAXADDR_32BIT + 1,
5569 BUS_SPACE_MAXADDR_32BIT,
5570 BUS_SPACE_MAXADDR,
5571 NULL, NULL,
5572 PAGE_SIZE, 1,
5573 BUS_SPACE_MAXSIZE_32BIT,
5574 0, &scb_data->hscb_dmat) != 0) {
5575 goto error_exit;
5576 }
5577
5578 scb_data->init_level++;
5579
5580
5581 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, 8,
5582 BUS_SPACE_MAXADDR_32BIT + 1,
5583 BUS_SPACE_MAXADDR_32BIT,
5584 BUS_SPACE_MAXADDR,
5585 NULL, NULL,
5586 ahd_sglist_allocsize(ahd), 1,
5587 BUS_SPACE_MAXSIZE_32BIT,
5588 0, &scb_data->sg_dmat) != 0) {
5589 goto error_exit;
5590 }
5591#ifdef AHD_DEBUG
5592 if ((ahd_debug & AHD_SHOW_MEMORY) != 0)
5593 printf("%s: ahd_sglist_allocsize = 0x%x\n", ahd_name(ahd),
5594 ahd_sglist_allocsize(ahd));
5595#endif
5596
5597 scb_data->init_level++;
5598
5599
5600 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, 1,
5601 BUS_SPACE_MAXADDR_32BIT + 1,
5602 BUS_SPACE_MAXADDR_32BIT,
5603 BUS_SPACE_MAXADDR,
5604 NULL, NULL,
5605 PAGE_SIZE, 1,
5606 BUS_SPACE_MAXSIZE_32BIT,
5607 0, &scb_data->sense_dmat) != 0) {
5608 goto error_exit;
5609 }
5610
5611 scb_data->init_level++;
5612
5613
5614 ahd_alloc_scbs(ahd);
5615
5616 if (scb_data->numscbs == 0) {
5617 printf("%s: ahd_init_scbdata - "
5618 "Unable to allocate initial scbs\n",
5619 ahd_name(ahd));
5620 goto error_exit;
5621 }
5622
5623
5624
5625
5626 return (0);
5627
5628error_exit:
5629
5630 return (ENOMEM);
5631}
5632
5633static struct scb *
5634ahd_find_scb_by_tag(struct ahd_softc *ahd, u_int tag)
5635{
5636 struct scb *scb;
5637
5638
5639
5640
5641 LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
5642 if (SCB_GET_TAG(scb) == tag)
5643 return (scb);
5644 }
5645
5646
5647
5648
5649 TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
5650 struct scb *list_scb;
5651
5652 list_scb = scb;
5653 do {
5654 if (SCB_GET_TAG(list_scb) == tag)
5655 return (list_scb);
5656 list_scb = LIST_NEXT(list_scb, collision_links);
5657 } while (list_scb);
5658 }
5659
5660
5661
5662
5663 LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) {
5664 if (SCB_GET_TAG(scb) == tag)
5665 return (scb);
5666 }
5667
5668 return (NULL);
5669}
5670
5671static void
5672ahd_fini_scbdata(struct ahd_softc *ahd)
5673{
5674 struct scb_data *scb_data;
5675
5676 scb_data = &ahd->scb_data;
5677 if (scb_data == NULL)
5678 return;
5679
5680 switch (scb_data->init_level) {
5681 default:
5682 case 7:
5683 {
5684 struct map_node *sns_map;
5685
5686 while ((sns_map = SLIST_FIRST(&scb_data->sense_maps)) != NULL) {
5687 SLIST_REMOVE_HEAD(&scb_data->sense_maps, links);
5688 ahd_dmamap_unload(ahd, scb_data->sense_dmat,
5689 sns_map->dmamap);
5690 ahd_dmamem_free(ahd, scb_data->sense_dmat,
5691 sns_map->vaddr, sns_map->dmamap);
5692 free(sns_map, M_DEVBUF);
5693 }
5694 ahd_dma_tag_destroy(ahd, scb_data->sense_dmat);
5695
5696 }
5697 case 6:
5698 {
5699 struct map_node *sg_map;
5700
5701 while ((sg_map = SLIST_FIRST(&scb_data->sg_maps)) != NULL) {
5702 SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
5703 ahd_dmamap_unload(ahd, scb_data->sg_dmat,
5704 sg_map->dmamap);
5705 ahd_dmamem_free(ahd, scb_data->sg_dmat,
5706 sg_map->vaddr, sg_map->dmamap);
5707 free(sg_map, M_DEVBUF);
5708 }
5709 ahd_dma_tag_destroy(ahd, scb_data->sg_dmat);
5710
5711 }
5712 case 5:
5713 {
5714 struct map_node *hscb_map;
5715
5716 while ((hscb_map = SLIST_FIRST(&scb_data->hscb_maps)) != NULL) {
5717 SLIST_REMOVE_HEAD(&scb_data->hscb_maps, links);
5718 ahd_dmamap_unload(ahd, scb_data->hscb_dmat,
5719 hscb_map->dmamap);
5720 ahd_dmamem_free(ahd, scb_data->hscb_dmat,
5721 hscb_map->vaddr, hscb_map->dmamap);
5722 free(hscb_map, M_DEVBUF);
5723 }
5724 ahd_dma_tag_destroy(ahd, scb_data->hscb_dmat);
5725
5726 }
5727 case 4:
5728 case 3:
5729 case 2:
5730 case 1:
5731 case 0:
5732 break;
5733 }
5734}
5735
5736
5737
5738
5739
5740static void
5741ahd_setup_iocell_workaround(struct ahd_softc *ahd)
5742{
5743 ahd_mode_state saved_modes;
5744
5745 saved_modes = ahd_save_modes(ahd);
5746 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
5747 ahd_outb(ahd, DSPDATACTL, ahd_inb(ahd, DSPDATACTL)
5748 | BYPASSENAB | RCVROFFSTDIS | XMITOFFSTDIS);
5749 ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) | (ENSELDO|ENSELDI));
5750#ifdef AHD_DEBUG
5751 if ((ahd_debug & AHD_SHOW_MISC) != 0)
5752 printf("%s: Setting up iocell workaround\n", ahd_name(ahd));
5753#endif
5754 ahd_restore_modes(ahd, saved_modes);
5755 ahd->flags &= ~AHD_HAD_FIRST_SEL;
5756}
5757
5758static void
5759ahd_iocell_first_selection(struct ahd_softc *ahd)
5760{
5761 ahd_mode_state saved_modes;
5762 u_int sblkctl;
5763
5764 if ((ahd->flags & AHD_HAD_FIRST_SEL) != 0)
5765 return;
5766 saved_modes = ahd_save_modes(ahd);
5767 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
5768 sblkctl = ahd_inb(ahd, SBLKCTL);
5769 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
5770#ifdef AHD_DEBUG
5771 if ((ahd_debug & AHD_SHOW_MISC) != 0)
5772 printf("%s: iocell first selection\n", ahd_name(ahd));
5773#endif
5774 if ((sblkctl & ENAB40) != 0) {
5775 ahd_outb(ahd, DSPDATACTL,
5776 ahd_inb(ahd, DSPDATACTL) & ~BYPASSENAB);
5777#ifdef AHD_DEBUG
5778 if ((ahd_debug & AHD_SHOW_MISC) != 0)
5779 printf("%s: BYPASS now disabled\n", ahd_name(ahd));
5780#endif
5781 }
5782 ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) & ~(ENSELDO|ENSELDI));
5783 ahd_outb(ahd, CLRINT, CLRSCSIINT);
5784 ahd_restore_modes(ahd, saved_modes);
5785 ahd->flags |= AHD_HAD_FIRST_SEL;
5786}
5787
5788
5789static void
5790ahd_add_col_list(struct ahd_softc *ahd, struct scb *scb, u_int col_idx)
5791{
5792 struct scb_list *free_list;
5793 struct scb_tailq *free_tailq;
5794 struct scb *first_scb;
5795
5796 scb->flags |= SCB_ON_COL_LIST;
5797 AHD_SET_SCB_COL_IDX(scb, col_idx);
5798 free_list = &ahd->scb_data.free_scb_lists[col_idx];
5799 free_tailq = &ahd->scb_data.free_scbs;
5800 first_scb = LIST_FIRST(free_list);
5801 if (first_scb != NULL) {
5802 LIST_INSERT_AFTER(first_scb, scb, collision_links);
5803 } else {
5804 LIST_INSERT_HEAD(free_list, scb, collision_links);
5805 TAILQ_INSERT_TAIL(free_tailq, scb, links.tqe);
5806 }
5807}
5808
5809static void
5810ahd_rem_col_list(struct ahd_softc *ahd, struct scb *scb)
5811{
5812 struct scb_list *free_list;
5813 struct scb_tailq *free_tailq;
5814 struct scb *first_scb;
5815 u_int col_idx;
5816
5817 scb->flags &= ~SCB_ON_COL_LIST;
5818 col_idx = AHD_GET_SCB_COL_IDX(ahd, scb);
5819 free_list = &ahd->scb_data.free_scb_lists[col_idx];
5820 free_tailq = &ahd->scb_data.free_scbs;
5821 first_scb = LIST_FIRST(free_list);
5822 if (first_scb == scb) {
5823 struct scb *next_scb;
5824
5825
5826
5827
5828
5829
5830 next_scb = LIST_NEXT(scb, collision_links);
5831 if (next_scb != NULL) {
5832 TAILQ_INSERT_AFTER(free_tailq, scb,
5833 next_scb, links.tqe);
5834 }
5835 TAILQ_REMOVE(free_tailq, scb, links.tqe);
5836 }
5837 LIST_REMOVE(scb, collision_links);
5838}
5839
5840
5841
5842
5843struct scb *
5844ahd_get_scb(struct ahd_softc *ahd, u_int col_idx)
5845{
5846 struct scb *scb;
5847 int tries;
5848
5849 tries = 0;
5850look_again:
5851 TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
5852 if (AHD_GET_SCB_COL_IDX(ahd, scb) != col_idx) {
5853 ahd_rem_col_list(ahd, scb);
5854 goto found;
5855 }
5856 }
5857 if ((scb = LIST_FIRST(&ahd->scb_data.any_dev_free_scb_list)) == NULL) {
5858
5859 if (tries++ != 0)
5860 return (NULL);
5861 ahd_alloc_scbs(ahd);
5862 goto look_again;
5863 }
5864 LIST_REMOVE(scb, links.le);
5865 if (col_idx != AHD_NEVER_COL_IDX
5866 && (scb->col_scb != NULL)
5867 && (scb->col_scb->flags & SCB_ACTIVE) == 0) {
5868 LIST_REMOVE(scb->col_scb, links.le);
5869 ahd_add_col_list(ahd, scb->col_scb, col_idx);
5870 }
5871found:
5872 scb->flags |= SCB_ACTIVE;
5873 return (scb);
5874}
5875
5876
5877
5878
5879void
5880ahd_free_scb(struct ahd_softc *ahd, struct scb *scb)
5881{
5882
5883
5884 scb->flags = SCB_FLAG_NONE;
5885 scb->hscb->control = 0;
5886 ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = NULL;
5887
5888 if (scb->col_scb == NULL) {
5889
5890
5891
5892
5893 LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
5894 scb, links.le);
5895 } else if ((scb->col_scb->flags & SCB_ON_COL_LIST) != 0) {
5896
5897
5898
5899
5900
5901
5902 ahd_rem_col_list(ahd, scb->col_scb);
5903 LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
5904 scb, links.le);
5905 LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
5906 scb->col_scb, links.le);
5907 } else if ((scb->col_scb->flags
5908 & (SCB_PACKETIZED|SCB_ACTIVE)) == SCB_ACTIVE
5909 && (scb->col_scb->hscb->control & TAG_ENB) != 0) {
5910
5911
5912
5913
5914
5915
5916 ahd_add_col_list(ahd, scb,
5917 AHD_GET_SCB_COL_IDX(ahd, scb->col_scb));
5918 } else {
5919
5920
5921
5922
5923
5924
5925 LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
5926 scb, links.le);
5927 }
5928
5929 ahd_platform_scb_free(ahd, scb);
5930}
5931
5932void
5933ahd_alloc_scbs(struct ahd_softc *ahd)
5934{
5935 struct scb_data *scb_data;
5936 struct scb *next_scb;
5937 struct hardware_scb *hscb;
5938 struct map_node *hscb_map;
5939 struct map_node *sg_map;
5940 struct map_node *sense_map;
5941 uint8_t *segs;
5942 uint8_t *sense_data;
5943 dma_addr_t hscb_busaddr;
5944 dma_addr_t sg_busaddr;
5945 dma_addr_t sense_busaddr;
5946 int newcount;
5947 int i;
5948
5949 scb_data = &ahd->scb_data;
5950 if (scb_data->numscbs >= AHD_SCB_MAX_ALLOC)
5951
5952 return;
5953
5954 if (scb_data->scbs_left != 0) {
5955 int offset;
5956
5957 offset = (PAGE_SIZE / sizeof(*hscb)) - scb_data->scbs_left;
5958 hscb_map = SLIST_FIRST(&scb_data->hscb_maps);
5959 hscb = &((struct hardware_scb *)hscb_map->vaddr)[offset];
5960 hscb_busaddr = hscb_map->physaddr + (offset * sizeof(*hscb));
5961 } else {
5962 hscb_map = malloc(sizeof(*hscb_map), M_DEVBUF, M_NOWAIT);
5963
5964 if (hscb_map == NULL)
5965 return;
5966
5967
5968 if (ahd_dmamem_alloc(ahd, scb_data->hscb_dmat,
5969 (void **)&hscb_map->vaddr,
5970 BUS_DMA_NOWAIT, &hscb_map->dmamap) != 0) {
5971 free(hscb_map, M_DEVBUF);
5972 return;
5973 }
5974
5975 SLIST_INSERT_HEAD(&scb_data->hscb_maps, hscb_map, links);
5976
5977 ahd_dmamap_load(ahd, scb_data->hscb_dmat, hscb_map->dmamap,
5978 hscb_map->vaddr, PAGE_SIZE, ahd_dmamap_cb,
5979 &hscb_map->physaddr, 0);
5980
5981 hscb = (struct hardware_scb *)hscb_map->vaddr;
5982 hscb_busaddr = hscb_map->physaddr;
5983 scb_data->scbs_left = PAGE_SIZE / sizeof(*hscb);
5984 }
5985
5986 if (scb_data->sgs_left != 0) {
5987 int offset;
5988
5989 offset = ((ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd))
5990 - scb_data->sgs_left) * ahd_sglist_size(ahd);
5991 sg_map = SLIST_FIRST(&scb_data->sg_maps);
5992 segs = sg_map->vaddr + offset;
5993 sg_busaddr = sg_map->physaddr + offset;
5994 } else {
5995 sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT);
5996
5997 if (sg_map == NULL)
5998 return;
5999
6000
6001 if (ahd_dmamem_alloc(ahd, scb_data->sg_dmat,
6002 (void **)&sg_map->vaddr,
6003 BUS_DMA_NOWAIT, &sg_map->dmamap) != 0) {
6004 free(sg_map, M_DEVBUF);
6005 return;
6006 }
6007
6008 SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
6009
6010 ahd_dmamap_load(ahd, scb_data->sg_dmat, sg_map->dmamap,
6011 sg_map->vaddr, ahd_sglist_allocsize(ahd),
6012 ahd_dmamap_cb, &sg_map->physaddr, 0);
6013
6014 segs = sg_map->vaddr;
6015 sg_busaddr = sg_map->physaddr;
6016 scb_data->sgs_left =
6017 ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd);
6018#ifdef AHD_DEBUG
6019 if (ahd_debug & AHD_SHOW_MEMORY)
6020 printf("Mapped SG data\n");
6021#endif
6022 }
6023
6024 if (scb_data->sense_left != 0) {
6025 int offset;
6026
6027 offset = PAGE_SIZE - (AHD_SENSE_BUFSIZE * scb_data->sense_left);
6028 sense_map = SLIST_FIRST(&scb_data->sense_maps);
6029 sense_data = sense_map->vaddr + offset;
6030 sense_busaddr = sense_map->physaddr + offset;
6031 } else {
6032 sense_map = malloc(sizeof(*sense_map), M_DEVBUF, M_NOWAIT);
6033
6034 if (sense_map == NULL)
6035 return;
6036
6037
6038 if (ahd_dmamem_alloc(ahd, scb_data->sense_dmat,
6039 (void **)&sense_map->vaddr,
6040 BUS_DMA_NOWAIT, &sense_map->dmamap) != 0) {
6041 free(sense_map, M_DEVBUF);
6042 return;
6043 }
6044
6045 SLIST_INSERT_HEAD(&scb_data->sense_maps, sense_map, links);
6046
6047 ahd_dmamap_load(ahd, scb_data->sense_dmat, sense_map->dmamap,
6048 sense_map->vaddr, PAGE_SIZE, ahd_dmamap_cb,
6049 &sense_map->physaddr, 0);
6050
6051 sense_data = sense_map->vaddr;
6052 sense_busaddr = sense_map->physaddr;
6053 scb_data->sense_left = PAGE_SIZE / AHD_SENSE_BUFSIZE;
6054#ifdef AHD_DEBUG
6055 if (ahd_debug & AHD_SHOW_MEMORY)
6056 printf("Mapped sense data\n");
6057#endif
6058 }
6059
6060 newcount = MIN(scb_data->sense_left, scb_data->scbs_left);
6061 newcount = MIN(newcount, scb_data->sgs_left);
6062 newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs));
6063 for (i = 0; i < newcount; i++) {
6064 struct scb_platform_data *pdata;
6065 u_int col_tag;
6066#ifndef __linux__
6067 int error;
6068#endif
6069
6070 next_scb = (struct scb *)malloc(sizeof(*next_scb),
6071 M_DEVBUF, M_NOWAIT);
6072 if (next_scb == NULL)
6073 break;
6074
6075 pdata = (struct scb_platform_data *)malloc(sizeof(*pdata),
6076 M_DEVBUF, M_NOWAIT);
6077 if (pdata == NULL) {
6078 free(next_scb, M_DEVBUF);
6079 break;
6080 }
6081 next_scb->platform_data = pdata;
6082 next_scb->hscb_map = hscb_map;
6083 next_scb->sg_map = sg_map;
6084 next_scb->sense_map = sense_map;
6085 next_scb->sg_list = segs;
6086 next_scb->sense_data = sense_data;
6087 next_scb->sense_busaddr = sense_busaddr;
6088 memset(hscb, 0, sizeof(*hscb));
6089 next_scb->hscb = hscb;
6090 hscb->hscb_busaddr = ahd_htole32(hscb_busaddr);
6091
6092
6093
6094
6095
6096 next_scb->sg_list_busaddr = sg_busaddr;
6097 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
6098 next_scb->sg_list_busaddr
6099 += sizeof(struct ahd_dma64_seg);
6100 else
6101 next_scb->sg_list_busaddr += sizeof(struct ahd_dma_seg);
6102 next_scb->ahd_softc = ahd;
6103 next_scb->flags = SCB_FLAG_NONE;
6104#ifndef __linux__
6105 error = ahd_dmamap_create(ahd, ahd->buffer_dmat, 0,
6106 &next_scb->dmamap);
6107 if (error != 0) {
6108 free(next_scb, M_DEVBUF);
6109 free(pdata, M_DEVBUF);
6110 break;
6111 }
6112#endif
6113 next_scb->hscb->tag = ahd_htole16(scb_data->numscbs);
6114 col_tag = scb_data->numscbs ^ 0x100;
6115 next_scb->col_scb = ahd_find_scb_by_tag(ahd, col_tag);
6116 if (next_scb->col_scb != NULL)
6117 next_scb->col_scb->col_scb = next_scb;
6118 ahd_free_scb(ahd, next_scb);
6119 hscb++;
6120 hscb_busaddr += sizeof(*hscb);
6121 segs += ahd_sglist_size(ahd);
6122 sg_busaddr += ahd_sglist_size(ahd);
6123 sense_data += AHD_SENSE_BUFSIZE;
6124 sense_busaddr += AHD_SENSE_BUFSIZE;
6125 scb_data->numscbs++;
6126 scb_data->sense_left--;
6127 scb_data->scbs_left--;
6128 scb_data->sgs_left--;
6129 }
6130}
6131
6132void
6133ahd_controller_info(struct ahd_softc *ahd, char *buf)
6134{
6135 const char *speed;
6136 const char *type;
6137 int len;
6138
6139 len = sprintf(buf, "%s: ", ahd_chip_names[ahd->chip & AHD_CHIPID_MASK]);
6140 buf += len;
6141
6142 speed = "Ultra320 ";
6143 if ((ahd->features & AHD_WIDE) != 0) {
6144 type = "Wide ";
6145 } else {
6146 type = "Single ";
6147 }
6148 len = sprintf(buf, "%s%sChannel %c, SCSI Id=%d, ",
6149 speed, type, ahd->channel, ahd->our_id);
6150 buf += len;
6151
6152 sprintf(buf, "%s, %d SCBs", ahd->bus_description,
6153 ahd->scb_data.maxhscbs);
6154}
6155
6156static const char *channel_strings[] = {
6157 "Primary Low",
6158 "Primary High",
6159 "Secondary Low",
6160 "Secondary High"
6161};
6162
6163static const char *termstat_strings[] = {
6164 "Terminated Correctly",
6165 "Over Terminated",
6166 "Under Terminated",
6167 "Not Configured"
6168};
6169
6170
6171
6172
6173int
6174ahd_init(struct ahd_softc *ahd)
6175{
6176 uint8_t *next_vaddr;
6177 dma_addr_t next_baddr;
6178 size_t driver_data_size;
6179 int i;
6180 int error;
6181 u_int warn_user;
6182 uint8_t current_sensing;
6183 uint8_t fstat;
6184
6185 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
6186
6187 ahd->stack_size = ahd_probe_stack_size(ahd);
6188 ahd->saved_stack = malloc(ahd->stack_size * sizeof(uint16_t),
6189 M_DEVBUF, M_NOWAIT);
6190 if (ahd->saved_stack == NULL)
6191 return (ENOMEM);
6192
6193
6194
6195
6196
6197 if (sizeof(struct hardware_scb) != 64)
6198 panic("Hardware SCB size is incorrect");
6199
6200#ifdef AHD_DEBUG
6201 if ((ahd_debug & AHD_DEBUG_SEQUENCER) != 0)
6202 ahd->flags |= AHD_SEQUENCER_DEBUG;
6203#endif
6204
6205
6206
6207
6208 ahd->flags |= AHD_INITIATORROLE;
6209
6210
6211
6212
6213 if ((AHD_TMODE_ENABLE & (0x1 << ahd->unit)) == 0)
6214 ahd->features &= ~AHD_TARGETMODE;
6215
6216#ifndef __linux__
6217
6218 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, 1,
6219 BUS_SPACE_MAXADDR_32BIT + 1,
6220 ahd->flags & AHD_39BIT_ADDRESSING
6221 ? (dma_addr_t)0x7FFFFFFFFFULL
6222 : BUS_SPACE_MAXADDR_32BIT,
6223 BUS_SPACE_MAXADDR,
6224 NULL, NULL,
6225 (AHD_NSEG - 1) * PAGE_SIZE,
6226 AHD_NSEG,
6227 AHD_MAXTRANSFER_SIZE,
6228 BUS_DMA_ALLOCNOW,
6229 &ahd->buffer_dmat) != 0) {
6230 return (ENOMEM);
6231 }
6232#endif
6233
6234 ahd->init_level++;
6235
6236
6237
6238
6239
6240
6241
6242
6243 driver_data_size = AHD_SCB_MAX * sizeof(*ahd->qoutfifo)
6244 + sizeof(struct hardware_scb);
6245 if ((ahd->features & AHD_TARGETMODE) != 0)
6246 driver_data_size += AHD_TMODE_CMDS * sizeof(struct target_cmd);
6247 if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0)
6248 driver_data_size += PKT_OVERRUN_BUFSIZE;
6249 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, 1,
6250 BUS_SPACE_MAXADDR_32BIT + 1,
6251 BUS_SPACE_MAXADDR_32BIT,
6252 BUS_SPACE_MAXADDR,
6253 NULL, NULL,
6254 driver_data_size,
6255 1,
6256 BUS_SPACE_MAXSIZE_32BIT,
6257 0, &ahd->shared_data_dmat) != 0) {
6258 return (ENOMEM);
6259 }
6260
6261 ahd->init_level++;
6262
6263
6264 if (ahd_dmamem_alloc(ahd, ahd->shared_data_dmat,
6265 (void **)&ahd->shared_data_map.vaddr,
6266 BUS_DMA_NOWAIT,
6267 &ahd->shared_data_map.dmamap) != 0) {
6268 return (ENOMEM);
6269 }
6270
6271 ahd->init_level++;
6272
6273
6274 ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap,
6275 ahd->shared_data_map.vaddr, driver_data_size,
6276 ahd_dmamap_cb, &ahd->shared_data_map.physaddr,
6277 0);
6278 ahd->qoutfifo = (struct ahd_completion *)ahd->shared_data_map.vaddr;
6279 next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE];
6280 next_baddr = ahd->shared_data_map.physaddr
6281 + AHD_QOUT_SIZE*sizeof(struct ahd_completion);
6282 if ((ahd->features & AHD_TARGETMODE) != 0) {
6283 ahd->targetcmds = (struct target_cmd *)next_vaddr;
6284 next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd);
6285 next_baddr += AHD_TMODE_CMDS * sizeof(struct target_cmd);
6286 }
6287
6288 if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) {
6289 ahd->overrun_buf = next_vaddr;
6290 next_vaddr += PKT_OVERRUN_BUFSIZE;
6291 next_baddr += PKT_OVERRUN_BUFSIZE;
6292 }
6293
6294
6295
6296
6297
6298
6299
6300
6301 ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr;
6302 ahd->next_queued_hscb_map = &ahd->shared_data_map;
6303 ahd->next_queued_hscb->hscb_busaddr = ahd_htole32(next_baddr);
6304
6305 ahd->init_level++;
6306
6307
6308 if (ahd_init_scbdata(ahd) != 0)
6309 return (ENOMEM);
6310
6311 if ((ahd->flags & AHD_INITIATORROLE) == 0)
6312 ahd->flags &= ~AHD_RESET_BUS_A;
6313
6314
6315
6316
6317
6318 ahd_platform_init(ahd);
6319
6320
6321 ahd_chip_init(ahd);
6322
6323 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
6324
6325 if ((ahd->flags & AHD_CURRENT_SENSING) == 0)
6326 goto init_done;
6327
6328
6329
6330
6331
6332 error = ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL,
6333 CURSENSE_ENB);
6334 if (error != 0) {
6335 printf("%s: current sensing timeout 1\n", ahd_name(ahd));
6336 goto init_done;
6337 }
6338 for (i = 20, fstat = FLX_FSTAT_BUSY;
6339 (fstat & FLX_FSTAT_BUSY) != 0 && i; i--) {
6340 error = ahd_read_flexport(ahd, FLXADDR_FLEXSTAT, &fstat);
6341 if (error != 0) {
6342 printf("%s: current sensing timeout 2\n",
6343 ahd_name(ahd));
6344 goto init_done;
6345 }
6346 }
6347 if (i == 0) {
6348 printf("%s: Timedout during current-sensing test\n",
6349 ahd_name(ahd));
6350 goto init_done;
6351 }
6352
6353
6354 error = ahd_read_flexport(ahd, FLXADDR_CURRENT_STAT, ¤t_sensing);
6355 if (error != 0) {
6356 printf("%s: current sensing timeout 3\n", ahd_name(ahd));
6357 goto init_done;
6358 }
6359
6360
6361 ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
6362
6363#ifdef AHD_DEBUG
6364 if ((ahd_debug & AHD_SHOW_TERMCTL) != 0) {
6365 printf("%s: current_sensing == 0x%x\n",
6366 ahd_name(ahd), current_sensing);
6367 }
6368#endif
6369 warn_user = 0;
6370 for (i = 0; i < 4; i++, current_sensing >>= FLX_CSTAT_SHIFT) {
6371 u_int term_stat;
6372
6373 term_stat = (current_sensing & FLX_CSTAT_MASK);
6374 switch (term_stat) {
6375 case FLX_CSTAT_OVER:
6376 case FLX_CSTAT_UNDER:
6377 warn_user++;
6378 case FLX_CSTAT_INVALID:
6379 case FLX_CSTAT_OKAY:
6380 if (warn_user == 0 && bootverbose == 0)
6381 break;
6382 printf("%s: %s Channel %s\n", ahd_name(ahd),
6383 channel_strings[i], termstat_strings[term_stat]);
6384 break;
6385 }
6386 }
6387 if (warn_user) {
6388 printf("%s: WARNING. Termination is not configured correctly.\n"
6389 "%s: WARNING. SCSI bus operations may FAIL.\n",
6390 ahd_name(ahd), ahd_name(ahd));
6391 }
6392init_done:
6393 ahd_restart(ahd);
6394 ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
6395 ahd_stat_timer, ahd);
6396 return (0);
6397}
6398
6399
6400
6401
6402static void
6403ahd_chip_init(struct ahd_softc *ahd)
6404{
6405 uint32_t busaddr;
6406 u_int sxfrctl1;
6407 u_int scsiseq_template;
6408 u_int wait;
6409 u_int i;
6410 u_int target;
6411
6412 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
6413
6414
6415
6416 ahd_outb(ahd, SBLKCTL, ahd_inb(ahd, SBLKCTL) & ~(DIAGLEDEN|DIAGLEDON));
6417
6418
6419
6420
6421 ahd->hs_mailbox = 0;
6422 ahd_outb(ahd, HS_MAILBOX, 0);
6423
6424
6425 ahd_outb(ahd, IOWNID, ahd->our_id);
6426 ahd_outb(ahd, TOWNID, ahd->our_id);
6427 sxfrctl1 = (ahd->flags & AHD_TERM_ENB_A) != 0 ? STPWEN : 0;
6428 sxfrctl1 |= (ahd->flags & AHD_SPCHK_ENB_A) != 0 ? ENSPCHK : 0;
6429 if ((ahd->bugs & AHD_LONG_SETIMO_BUG)
6430 && (ahd->seltime != STIMESEL_MIN)) {
6431
6432
6433
6434
6435
6436 sxfrctl1 |= ahd->seltime + STIMESEL_BUG_ADJ;
6437 } else {
6438 sxfrctl1 |= ahd->seltime;
6439 }
6440
6441 ahd_outb(ahd, SXFRCTL0, DFON);
6442 ahd_outb(ahd, SXFRCTL1, sxfrctl1|ahd->seltime|ENSTIMER|ACTNEGEN);
6443 ahd_outb(ahd, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
6444
6445
6446
6447
6448
6449
6450
6451
6452 for (wait = 10000;
6453 (ahd_inb(ahd, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
6454 wait--)
6455 ahd_delay(100);
6456
6457
6458 ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
6459 ahd_outb(ahd, CLRINT, CLRSCSIINT);
6460
6461
6462 for (i = 0; i < 2; i++) {
6463 ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i);
6464 ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
6465 ahd_outb(ahd, SG_STATE, 0);
6466 ahd_outb(ahd, CLRSEQINTSRC, 0xFF);
6467 ahd_outb(ahd, SEQIMODE,
6468 ENSAVEPTRS|ENCFG4DATA|ENCFG4ISTAT
6469 |ENCFG4TSTAT|ENCFG4ICMD|ENCFG4TCMD);
6470 }
6471
6472 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
6473 ahd_outb(ahd, DSCOMMAND0, ahd_inb(ahd, DSCOMMAND0)|MPARCKEN|CACHETHEN);
6474 ahd_outb(ahd, DFF_THRSH, RD_DFTHRSH_75|WR_DFTHRSH_75);
6475 ahd_outb(ahd, SIMODE0, ENIOERR|ENOVERRUN);
6476 ahd_outb(ahd, SIMODE3, ENNTRAMPERR|ENOSRAMPERR);
6477 if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
6478 ahd_outb(ahd, OPTIONMODE, AUTOACKEN|AUTO_MSGOUT_DE);
6479 } else {
6480 ahd_outb(ahd, OPTIONMODE, AUTOACKEN|BUSFREEREV|AUTO_MSGOUT_DE);
6481 }
6482 ahd_outb(ahd, SCSCHKN, CURRFIFODEF|WIDERESEN|SHVALIDSTDIS);
6483 if ((ahd->chip & AHD_BUS_MASK) == AHD_PCIX)
6484
6485
6486
6487
6488
6489 ahd_outb(ahd, PCIXCTL, ahd_inb(ahd, PCIXCTL) | SPLTSTADIS);
6490
6491 if ((ahd->bugs & AHD_LQOOVERRUN_BUG) != 0)
6492 ahd_outb(ahd, LQOSCSCTL, LQONOCHKOVER);
6493
6494
6495
6496
6497 if ((ahd->flags & AHD_HP_BOARD) != 0) {
6498 for (i = 0; i < NUMDSPS; i++) {
6499 ahd_outb(ahd, DSPSELECT, i);
6500 ahd_outb(ahd, WRTBIASCTL, WRTBIASCTL_HP_DEFAULT);
6501 }
6502#ifdef AHD_DEBUG
6503 if ((ahd_debug & AHD_SHOW_MISC) != 0)
6504 printf("%s: WRTBIASCTL now 0x%x\n", ahd_name(ahd),
6505 WRTBIASCTL_HP_DEFAULT);
6506#endif
6507 }
6508 ahd_setup_iocell_workaround(ahd);
6509
6510
6511
6512
6513 ahd_outb(ahd, LQIMODE1, ENLQIPHASE_LQ|ENLQIPHASE_NLQ|ENLIQABORT
6514 | ENLQICRCI_LQ|ENLQICRCI_NLQ|ENLQIBADLQI
6515 | ENLQIOVERI_LQ|ENLQIOVERI_NLQ);
6516 ahd_outb(ahd, LQOMODE0, ENLQOATNLQ|ENLQOATNPKT|ENLQOTCRC);
6517
6518
6519
6520
6521
6522
6523
6524
6525 ahd_outb(ahd, LQOMODE1, ENLQOBUSFREE);
6526
6527
6528
6529
6530 ahd_outw(ahd, INTVEC1_ADDR, ahd_resolve_seqaddr(ahd, LABEL_seq_isr));
6531 ahd_outw(ahd, INTVEC2_ADDR, ahd_resolve_seqaddr(ahd, LABEL_timer_isr));
6532
6533
6534
6535
6536 if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) {
6537 ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb,
6538 pkt_long_lun));
6539 } else {
6540 ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb, lun));
6541 }
6542 ahd_outb(ahd, CMDLENPTR, offsetof(struct hardware_scb, cdb_len));
6543 ahd_outb(ahd, ATTRPTR, offsetof(struct hardware_scb, task_attribute));
6544 ahd_outb(ahd, FLAGPTR, offsetof(struct hardware_scb, task_management));
6545 ahd_outb(ahd, CMDPTR, offsetof(struct hardware_scb,
6546 shared_data.idata.cdb));
6547 ahd_outb(ahd, QNEXTPTR,
6548 offsetof(struct hardware_scb, next_hscb_busaddr));
6549 ahd_outb(ahd, ABRTBITPTR, MK_MESSAGE_BIT_OFFSET);
6550 ahd_outb(ahd, ABRTBYTEPTR, offsetof(struct hardware_scb, control));
6551 if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) {
6552 ahd_outb(ahd, LUNLEN,
6553 sizeof(ahd->next_queued_hscb->pkt_long_lun) - 1);
6554 } else {
6555 ahd_outb(ahd, LUNLEN, LUNLEN_SINGLE_LEVEL_LUN);
6556 }
6557 ahd_outb(ahd, CDBLIMIT, SCB_CDB_LEN_PTR - 1);
6558 ahd_outb(ahd, MAXCMD, 0xFF);
6559 ahd_outb(ahd, SCBAUTOPTR,
6560 AUSCBPTR_EN | offsetof(struct hardware_scb, tag));
6561
6562
6563 ahd_outb(ahd, MULTARGID, 0);
6564 ahd_outb(ahd, MULTARGID + 1, 0);
6565
6566 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
6567
6568 if ((ahd->features & AHD_NEW_IOCELL_OPTS) == 0) {
6569
6570
6571
6572
6573 for (target = 0; target < AHD_NUM_TARGETS; target++) {
6574 ahd_outb(ahd, NEGOADDR, target);
6575 ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PER_DEV0);
6576 for (i = 0; i < AHD_NUM_PER_DEV_ANNEXCOLS; i++)
6577 ahd_outb(ahd, ANNEXDAT, 0);
6578 }
6579 }
6580 for (target = 0; target < AHD_NUM_TARGETS; target++) {
6581 struct ahd_devinfo devinfo;
6582 struct ahd_initiator_tinfo *tinfo;
6583 struct ahd_tmode_tstate *tstate;
6584
6585 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
6586 target, &tstate);
6587 ahd_compile_devinfo(&devinfo, ahd->our_id,
6588 target, CAM_LUN_WILDCARD,
6589 'A', ROLE_INITIATOR);
6590 ahd_update_neg_table(ahd, &devinfo, &tinfo->curr);
6591 }
6592
6593 ahd_outb(ahd, CLRSINT3, NTRAMPERR|OSRAMPERR);
6594 ahd_outb(ahd, CLRINT, CLRSCSIINT);
6595
6596#ifdef NEEDS_MORE_TESTING
6597
6598
6599
6600
6601 if ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0)
6602 ahd_outb(ahd, LQCTL1, ABORTPENDING);
6603 else
6604#endif
6605 ahd_outb(ahd, LQCTL1, 0);
6606
6607
6608 ahd->qoutfifonext = 0;
6609 ahd->qoutfifonext_valid_tag = QOUTFIFO_ENTRY_VALID;
6610 ahd_outb(ahd, QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID);
6611 for (i = 0; i < AHD_QOUT_SIZE; i++)
6612 ahd->qoutfifo[i].valid_tag = 0;
6613 ahd_sync_qoutfifo(ahd, BUS_DMASYNC_PREREAD);
6614
6615 ahd->qinfifonext = 0;
6616 for (i = 0; i < AHD_QIN_SIZE; i++)
6617 ahd->qinfifo[i] = SCB_LIST_NULL;
6618
6619 if ((ahd->features & AHD_TARGETMODE) != 0) {
6620
6621 for (i = 0; i < AHD_TMODE_CMDS; i++)
6622 ahd->targetcmds[i].cmd_valid = 0;
6623 ahd_sync_tqinfifo(ahd, BUS_DMASYNC_PREREAD);
6624 ahd->tqinfifonext = 1;
6625 ahd_outb(ahd, KERNEL_TQINPOS, ahd->tqinfifonext - 1);
6626 ahd_outb(ahd, TQINPOS, ahd->tqinfifonext);
6627 }
6628
6629
6630 ahd_outb(ahd, SEQ_FLAGS, 0);
6631 ahd_outb(ahd, SEQ_FLAGS2, 0);
6632
6633
6634 ahd_outw(ahd, WAITING_TID_HEAD, SCB_LIST_NULL);
6635 ahd_outw(ahd, WAITING_TID_TAIL, SCB_LIST_NULL);
6636 ahd_outw(ahd, MK_MESSAGE_SCB, SCB_LIST_NULL);
6637 ahd_outw(ahd, MK_MESSAGE_SCSIID, 0xFF);
6638 for (i = 0; i < AHD_NUM_TARGETS; i++)
6639 ahd_outw(ahd, WAITING_SCB_TAILS + (2 * i), SCB_LIST_NULL);
6640
6641
6642
6643
6644 ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL);
6645 ahd_outw(ahd, COMPLETE_SCB_DMAINPROG_HEAD, SCB_LIST_NULL);
6646 ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL);
6647 ahd_outw(ahd, COMPLETE_DMA_SCB_TAIL, SCB_LIST_NULL);
6648 ahd_outw(ahd, COMPLETE_ON_QFREEZE_HEAD, SCB_LIST_NULL);
6649
6650
6651
6652
6653 ahd->qfreeze_cnt = 0;
6654 ahd_outw(ahd, QFREEZE_COUNT, 0);
6655 ahd_outw(ahd, KERNEL_QFREEZE_COUNT, 0);
6656
6657
6658
6659
6660 busaddr = ahd->shared_data_map.physaddr;
6661 ahd_outl(ahd, SHARED_DATA_ADDR, busaddr);
6662 ahd_outl(ahd, QOUTFIFO_NEXT_ADDR, busaddr);
6663
6664
6665
6666
6667
6668
6669 scsiseq_template = ENAUTOATNP;
6670 if ((ahd->flags & AHD_INITIATORROLE) != 0)
6671 scsiseq_template |= ENRSELI;
6672 ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq_template);
6673
6674
6675 for (target = 0; target < AHD_NUM_TARGETS; target++) {
6676 int lun;
6677
6678 for (lun = 0; lun < AHD_NUM_LUNS_NONPKT; lun++)
6679 ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(target, 'A', lun));
6680 }
6681
6682
6683
6684
6685
6686
6687
6688 ahd_outb(ahd, CMDSIZE_TABLE, 5);
6689 ahd_outb(ahd, CMDSIZE_TABLE + 1, 9);
6690 ahd_outb(ahd, CMDSIZE_TABLE + 2, 9);
6691 ahd_outb(ahd, CMDSIZE_TABLE + 3, 0);
6692 ahd_outb(ahd, CMDSIZE_TABLE + 4, 15);
6693 ahd_outb(ahd, CMDSIZE_TABLE + 5, 11);
6694 ahd_outb(ahd, CMDSIZE_TABLE + 6, 0);
6695 ahd_outb(ahd, CMDSIZE_TABLE + 7, 0);
6696
6697
6698 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
6699 ahd_outb(ahd, QOFF_CTLSTA, SCB_QSIZE_512);
6700 ahd->qinfifonext = 0;
6701 ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
6702 ahd_set_hescb_qoff(ahd, 0);
6703 ahd_set_snscb_qoff(ahd, 0);
6704 ahd_set_sescb_qoff(ahd, 0);
6705 ahd_set_sdscb_qoff(ahd, 0);
6706
6707
6708
6709
6710 busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr);
6711 ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr);
6712
6713
6714
6715
6716 ahd_outw(ahd, INT_COALESCING_CMDCOUNT, 0);
6717 ahd_outw(ahd, CMDS_PENDING, 0);
6718 ahd_update_coalescing_values(ahd, ahd->int_coalescing_timer,
6719 ahd->int_coalescing_maxcmds,
6720 ahd->int_coalescing_mincmds);
6721 ahd_enable_coalescing(ahd, FALSE);
6722
6723 ahd_loadseq(ahd);
6724 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
6725
6726 if (ahd->features & AHD_AIC79XXB_SLOWCRC) {
6727 u_int negodat3 = ahd_inb(ahd, NEGCONOPTS);
6728
6729 negodat3 |= ENSLOWCRC;
6730 ahd_outb(ahd, NEGCONOPTS, negodat3);
6731 negodat3 = ahd_inb(ahd, NEGCONOPTS);
6732 if (!(negodat3 & ENSLOWCRC))
6733 printf("aic79xx: failed to set the SLOWCRC bit\n");
6734 else
6735 printf("aic79xx: SLOWCRC bit set\n");
6736 }
6737}
6738
6739
6740
6741
6742
6743
6744int
6745ahd_default_config(struct ahd_softc *ahd)
6746{
6747 int targ;
6748
6749 ahd->our_id = 7;
6750
6751
6752
6753
6754
6755
6756 if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) {
6757 printf("%s: unable to allocate ahd_tmode_tstate. "
6758 "Failing attach\n", ahd_name(ahd));
6759 return (ENOMEM);
6760 }
6761
6762 for (targ = 0; targ < AHD_NUM_TARGETS; targ++) {
6763 struct ahd_devinfo devinfo;
6764 struct ahd_initiator_tinfo *tinfo;
6765 struct ahd_tmode_tstate *tstate;
6766 uint16_t target_mask;
6767
6768 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
6769 targ, &tstate);
6770
6771
6772
6773 tinfo->user.protocol_version = 4;
6774 tinfo->user.transport_version = 4;
6775
6776 target_mask = 0x01 << targ;
6777 ahd->user_discenable |= target_mask;
6778 tstate->discenable |= target_mask;
6779 ahd->user_tagenable |= target_mask;
6780#ifdef AHD_FORCE_160
6781 tinfo->user.period = AHD_SYNCRATE_DT;
6782#else
6783 tinfo->user.period = AHD_SYNCRATE_160;
6784#endif
6785 tinfo->user.offset = MAX_OFFSET;
6786 tinfo->user.ppr_options = MSG_EXT_PPR_RD_STRM
6787 | MSG_EXT_PPR_WR_FLOW
6788 | MSG_EXT_PPR_HOLD_MCS
6789 | MSG_EXT_PPR_IU_REQ
6790 | MSG_EXT_PPR_QAS_REQ
6791 | MSG_EXT_PPR_DT_REQ;
6792 if ((ahd->features & AHD_RTI) != 0)
6793 tinfo->user.ppr_options |= MSG_EXT_PPR_RTI;
6794
6795 tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
6796
6797
6798
6799
6800
6801 tinfo->goal.protocol_version = 2;
6802 tinfo->goal.transport_version = 2;
6803 tinfo->curr.protocol_version = 2;
6804 tinfo->curr.transport_version = 2;
6805 ahd_compile_devinfo(&devinfo, ahd->our_id,
6806 targ, CAM_LUN_WILDCARD,
6807 'A', ROLE_INITIATOR);
6808 tstate->tagenable &= ~target_mask;
6809 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
6810 AHD_TRANS_CUR|AHD_TRANS_GOAL, TRUE);
6811 ahd_set_syncrate(ahd, &devinfo, 0, 0,
6812 0, AHD_TRANS_CUR|AHD_TRANS_GOAL,
6813 TRUE);
6814 }
6815 return (0);
6816}
6817
6818
6819
6820
6821int
6822ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc)
6823{
6824 int targ;
6825 int max_targ;
6826
6827 max_targ = sc->max_targets & CFMAXTARG;
6828 ahd->our_id = sc->brtime_id & CFSCSIID;
6829
6830
6831
6832
6833
6834
6835 if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) {
6836 printf("%s: unable to allocate ahd_tmode_tstate. "
6837 "Failing attach\n", ahd_name(ahd));
6838 return (ENOMEM);
6839 }
6840
6841 for (targ = 0; targ < max_targ; targ++) {
6842 struct ahd_devinfo devinfo;
6843 struct ahd_initiator_tinfo *tinfo;
6844 struct ahd_transinfo *user_tinfo;
6845 struct ahd_tmode_tstate *tstate;
6846 uint16_t target_mask;
6847
6848 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
6849 targ, &tstate);
6850 user_tinfo = &tinfo->user;
6851
6852
6853
6854
6855 tinfo->user.protocol_version = 4;
6856 tinfo->user.transport_version = 4;
6857
6858 target_mask = 0x01 << targ;
6859 ahd->user_discenable &= ~target_mask;
6860 tstate->discenable &= ~target_mask;
6861 ahd->user_tagenable &= ~target_mask;
6862 if (sc->device_flags[targ] & CFDISC) {
6863 tstate->discenable |= target_mask;
6864 ahd->user_discenable |= target_mask;
6865 ahd->user_tagenable |= target_mask;
6866 } else {
6867
6868
6869
6870 sc->device_flags[targ] &= ~CFPACKETIZED;
6871 }
6872
6873 user_tinfo->ppr_options = 0;
6874 user_tinfo->period = (sc->device_flags[targ] & CFXFER);
6875 if (user_tinfo->period < CFXFER_ASYNC) {
6876 if (user_tinfo->period <= AHD_PERIOD_10MHz)
6877 user_tinfo->ppr_options |= MSG_EXT_PPR_DT_REQ;
6878 user_tinfo->offset = MAX_OFFSET;
6879 } else {
6880 user_tinfo->offset = 0;
6881 user_tinfo->period = AHD_ASYNC_XFER_PERIOD;
6882 }
6883#ifdef AHD_FORCE_160
6884 if (user_tinfo->period <= AHD_SYNCRATE_160)
6885 user_tinfo->period = AHD_SYNCRATE_DT;
6886#endif
6887
6888 if ((sc->device_flags[targ] & CFPACKETIZED) != 0) {
6889 user_tinfo->ppr_options |= MSG_EXT_PPR_RD_STRM
6890 | MSG_EXT_PPR_WR_FLOW
6891 | MSG_EXT_PPR_HOLD_MCS
6892 | MSG_EXT_PPR_IU_REQ;
6893 if ((ahd->features & AHD_RTI) != 0)
6894 user_tinfo->ppr_options |= MSG_EXT_PPR_RTI;
6895 }
6896
6897 if ((sc->device_flags[targ] & CFQAS) != 0)
6898 user_tinfo->ppr_options |= MSG_EXT_PPR_QAS_REQ;
6899
6900 if ((sc->device_flags[targ] & CFWIDEB) != 0)
6901 user_tinfo->width = MSG_EXT_WDTR_BUS_16_BIT;
6902 else
6903 user_tinfo->width = MSG_EXT_WDTR_BUS_8_BIT;
6904#ifdef AHD_DEBUG
6905 if ((ahd_debug & AHD_SHOW_MISC) != 0)
6906 printf("(%d): %x:%x:%x:%x\n", targ, user_tinfo->width,
6907 user_tinfo->period, user_tinfo->offset,
6908 user_tinfo->ppr_options);
6909#endif
6910
6911
6912
6913
6914 tstate->tagenable &= ~target_mask;
6915 tinfo->goal.protocol_version = 2;
6916 tinfo->goal.transport_version = 2;
6917 tinfo->curr.protocol_version = 2;
6918 tinfo->curr.transport_version = 2;
6919 ahd_compile_devinfo(&devinfo, ahd->our_id,
6920 targ, CAM_LUN_WILDCARD,
6921 'A', ROLE_INITIATOR);
6922 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
6923 AHD_TRANS_CUR|AHD_TRANS_GOAL, TRUE);
6924 ahd_set_syncrate(ahd, &devinfo, 0, 0,
6925 0, AHD_TRANS_CUR|AHD_TRANS_GOAL,
6926 TRUE);
6927 }
6928
6929 ahd->flags &= ~AHD_SPCHK_ENB_A;
6930 if (sc->bios_control & CFSPARITY)
6931 ahd->flags |= AHD_SPCHK_ENB_A;
6932
6933 ahd->flags &= ~AHD_RESET_BUS_A;
6934 if (sc->bios_control & CFRESETB)
6935 ahd->flags |= AHD_RESET_BUS_A;
6936
6937 ahd->flags &= ~AHD_EXTENDED_TRANS_A;
6938 if (sc->bios_control & CFEXTEND)
6939 ahd->flags |= AHD_EXTENDED_TRANS_A;
6940
6941 ahd->flags &= ~AHD_BIOS_ENABLED;
6942 if ((sc->bios_control & CFBIOSSTATE) == CFBS_ENABLED)
6943 ahd->flags |= AHD_BIOS_ENABLED;
6944
6945 ahd->flags &= ~AHD_STPWLEVEL_A;
6946 if ((sc->adapter_control & CFSTPWLEVEL) != 0)
6947 ahd->flags |= AHD_STPWLEVEL_A;
6948
6949 return (0);
6950}
6951
6952
6953
6954
6955int
6956ahd_parse_vpddata(struct ahd_softc *ahd, struct vpd_config *vpd)
6957{
6958 int error;
6959
6960 error = ahd_verify_vpd_cksum(vpd);
6961 if (error == 0)
6962 return (EINVAL);
6963 if ((vpd->bios_flags & VPDBOOTHOST) != 0)
6964 ahd->flags |= AHD_BOOT_CHANNEL;
6965 return (0);
6966}
6967
6968void
6969ahd_intr_enable(struct ahd_softc *ahd, int enable)
6970{
6971 u_int hcntrl;
6972
6973 hcntrl = ahd_inb(ahd, HCNTRL);
6974 hcntrl &= ~INTEN;
6975 ahd->pause &= ~INTEN;
6976 ahd->unpause &= ~INTEN;
6977 if (enable) {
6978 hcntrl |= INTEN;
6979 ahd->pause |= INTEN;
6980 ahd->unpause |= INTEN;
6981 }
6982 ahd_outb(ahd, HCNTRL, hcntrl);
6983}
6984
6985void
6986ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds,
6987 u_int mincmds)
6988{
6989 if (timer > AHD_TIMER_MAX_US)
6990 timer = AHD_TIMER_MAX_US;
6991 ahd->int_coalescing_timer = timer;
6992
6993 if (maxcmds > AHD_INT_COALESCING_MAXCMDS_MAX)
6994 maxcmds = AHD_INT_COALESCING_MAXCMDS_MAX;
6995 if (mincmds > AHD_INT_COALESCING_MINCMDS_MAX)
6996 mincmds = AHD_INT_COALESCING_MINCMDS_MAX;
6997 ahd->int_coalescing_maxcmds = maxcmds;
6998 ahd_outw(ahd, INT_COALESCING_TIMER, timer / AHD_TIMER_US_PER_TICK);
6999 ahd_outb(ahd, INT_COALESCING_MAXCMDS, -maxcmds);
7000 ahd_outb(ahd, INT_COALESCING_MINCMDS, -mincmds);
7001}
7002
7003void
7004ahd_enable_coalescing(struct ahd_softc *ahd, int enable)
7005{
7006
7007 ahd->hs_mailbox &= ~ENINT_COALESCE;
7008 if (enable)
7009 ahd->hs_mailbox |= ENINT_COALESCE;
7010 ahd_outb(ahd, HS_MAILBOX, ahd->hs_mailbox);
7011 ahd_flush_device_writes(ahd);
7012 ahd_run_qoutfifo(ahd);
7013}
7014
7015
7016
7017
7018
7019
7020
7021
7022void
7023ahd_pause_and_flushwork(struct ahd_softc *ahd)
7024{
7025 u_int intstat;
7026 u_int maxloops;
7027
7028 maxloops = 1000;
7029 ahd->flags |= AHD_ALL_INTERRUPTS;
7030 ahd_pause(ahd);
7031
7032
7033
7034
7035
7036 ahd->qfreeze_cnt--;
7037 ahd_outw(ahd, KERNEL_QFREEZE_COUNT, ahd->qfreeze_cnt);
7038 ahd_outb(ahd, SEQ_FLAGS2, ahd_inb(ahd, SEQ_FLAGS2) | SELECTOUT_QFROZEN);
7039 do {
7040
7041 ahd_unpause(ahd);
7042
7043
7044
7045
7046 ahd_delay(500);
7047
7048 ahd_intr(ahd);
7049 ahd_pause(ahd);
7050 intstat = ahd_inb(ahd, INTSTAT);
7051 if ((intstat & INT_PEND) == 0) {
7052 ahd_clear_critical_section(ahd);
7053 intstat = ahd_inb(ahd, INTSTAT);
7054 }
7055 } while (--maxloops
7056 && (intstat != 0xFF || (ahd->features & AHD_REMOVABLE) == 0)
7057 && ((intstat & INT_PEND) != 0
7058 || (ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0
7059 || (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0));
7060
7061 if (maxloops == 0) {
7062 printf("Infinite interrupt loop, INTSTAT = %x",
7063 ahd_inb(ahd, INTSTAT));
7064 }
7065 ahd->qfreeze_cnt++;
7066 ahd_outw(ahd, KERNEL_QFREEZE_COUNT, ahd->qfreeze_cnt);
7067
7068 ahd_flush_qoutfifo(ahd);
7069
7070 ahd->flags &= ~AHD_ALL_INTERRUPTS;
7071}
7072
7073int
7074ahd_suspend(struct ahd_softc *ahd)
7075{
7076
7077 ahd_pause_and_flushwork(ahd);
7078
7079 if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
7080 ahd_unpause(ahd);
7081 return (EBUSY);
7082 }
7083 ahd_shutdown(ahd);
7084 return (0);
7085}
7086
7087int
7088ahd_resume(struct ahd_softc *ahd)
7089{
7090
7091 ahd_reset(ahd, TRUE);
7092 ahd_intr_enable(ahd, TRUE);
7093 ahd_restart(ahd);
7094 return (0);
7095}
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106static __inline u_int
7107ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl)
7108{
7109
7110
7111
7112 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
7113 *saved_scbid = ahd_get_scbptr(ahd);
7114 ahd_set_scbptr(ahd, TCL_LUN(tcl)
7115 | ((TCL_TARGET_OFFSET(tcl) & 0xC) << 4));
7116
7117
7118
7119
7120
7121
7122 return (((TCL_TARGET_OFFSET(tcl) & 0x3) << 1) + SCB_DISCONNECTED_LISTS);
7123}
7124
7125
7126
7127
7128u_int
7129ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl)
7130{
7131 u_int scbid;
7132 u_int scb_offset;
7133 u_int saved_scbptr;
7134
7135 scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl);
7136 scbid = ahd_inw_scbram(ahd, scb_offset);
7137 ahd_set_scbptr(ahd, saved_scbptr);
7138 return (scbid);
7139}
7140
7141void
7142ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid)
7143{
7144 u_int scb_offset;
7145 u_int saved_scbptr;
7146
7147 scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl);
7148 ahd_outw(ahd, scb_offset, scbid);
7149 ahd_set_scbptr(ahd, saved_scbptr);
7150}
7151
7152
7153int
7154ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, int target,
7155 char channel, int lun, u_int tag, role_t role)
7156{
7157 int targ = SCB_GET_TARGET(ahd, scb);
7158 char chan = SCB_GET_CHANNEL(ahd, scb);
7159 int slun = SCB_GET_LUN(scb);
7160 int match;
7161
7162 match = ((chan == channel) || (channel == ALL_CHANNELS));
7163 if (match != 0)
7164 match = ((targ == target) || (target == CAM_TARGET_WILDCARD));
7165 if (match != 0)
7166 match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));
7167 if (match != 0) {
7168#ifdef AHD_TARGET_MODE
7169 int group;
7170
7171 group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);
7172 if (role == ROLE_INITIATOR) {
7173 match = (group != XPT_FC_GROUP_TMODE)
7174 && ((tag == SCB_GET_TAG(scb))
7175 || (tag == SCB_LIST_NULL));
7176 } else if (role == ROLE_TARGET) {
7177 match = (group == XPT_FC_GROUP_TMODE)
7178 && ((tag == scb->io_ctx->csio.tag_id)
7179 || (tag == SCB_LIST_NULL));
7180 }
7181#else
7182 match = ((tag == SCB_GET_TAG(scb)) || (tag == SCB_LIST_NULL));
7183#endif
7184 }
7185
7186 return match;
7187}
7188
7189void
7190ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
7191{
7192 int target;
7193 char channel;
7194 int lun;
7195
7196 target = SCB_GET_TARGET(ahd, scb);
7197 lun = SCB_GET_LUN(scb);
7198 channel = SCB_GET_CHANNEL(ahd, scb);
7199
7200 ahd_search_qinfifo(ahd, target, channel, lun,
7201 SCB_LIST_NULL, ROLE_UNKNOWN,
7202 CAM_REQUEUE_REQ, SEARCH_COMPLETE);
7203
7204 ahd_platform_freeze_devq(ahd, scb);
7205}
7206
7207void
7208ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, struct scb *scb)
7209{
7210 struct scb *prev_scb;
7211 ahd_mode_state saved_modes;
7212
7213 saved_modes = ahd_save_modes(ahd);
7214 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
7215 prev_scb = NULL;
7216 if (ahd_qinfifo_count(ahd) != 0) {
7217 u_int prev_tag;
7218 u_int prev_pos;
7219
7220 prev_pos = AHD_QIN_WRAP(ahd->qinfifonext - 1);
7221 prev_tag = ahd->qinfifo[prev_pos];
7222 prev_scb = ahd_lookup_scb(ahd, prev_tag);
7223 }
7224 ahd_qinfifo_requeue(ahd, prev_scb, scb);
7225 ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
7226 ahd_restore_modes(ahd, saved_modes);
7227}
7228
7229static void
7230ahd_qinfifo_requeue(struct ahd_softc *ahd, struct scb *prev_scb,
7231 struct scb *scb)
7232{
7233 if (prev_scb == NULL) {
7234 uint32_t busaddr;
7235
7236 busaddr = ahd_le32toh(scb->hscb->hscb_busaddr);
7237 ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr);
7238 } else {
7239 prev_scb->hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr;
7240 ahd_sync_scb(ahd, prev_scb,
7241 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
7242 }
7243 ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb);
7244 ahd->qinfifonext++;
7245 scb->hscb->next_hscb_busaddr = ahd->next_queued_hscb->hscb_busaddr;
7246 ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
7247}
7248
7249static int
7250ahd_qinfifo_count(struct ahd_softc *ahd)
7251{
7252 u_int qinpos;
7253 u_int wrap_qinpos;
7254 u_int wrap_qinfifonext;
7255
7256 AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
7257 qinpos = ahd_get_snscb_qoff(ahd);
7258 wrap_qinpos = AHD_QIN_WRAP(qinpos);
7259 wrap_qinfifonext = AHD_QIN_WRAP(ahd->qinfifonext);
7260 if (wrap_qinfifonext >= wrap_qinpos)
7261 return (wrap_qinfifonext - wrap_qinpos);
7262 else
7263 return (wrap_qinfifonext
7264 + ARRAY_SIZE(ahd->qinfifo) - wrap_qinpos);
7265}
7266
7267void
7268ahd_reset_cmds_pending(struct ahd_softc *ahd)
7269{
7270 struct scb *scb;
7271 ahd_mode_state saved_modes;
7272 u_int pending_cmds;
7273
7274 saved_modes = ahd_save_modes(ahd);
7275 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
7276
7277
7278
7279
7280
7281 ahd_flush_qoutfifo(ahd);
7282
7283 pending_cmds = 0;
7284 LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
7285 pending_cmds++;
7286 }
7287 ahd_outw(ahd, CMDS_PENDING, pending_cmds - ahd_qinfifo_count(ahd));
7288 ahd_restore_modes(ahd, saved_modes);
7289 ahd->flags &= ~AHD_UPDATE_PEND_CMDS;
7290}
7291
7292static void
7293ahd_done_with_status(struct ahd_softc *ahd, struct scb *scb, uint32_t status)
7294{
7295 cam_status ostat;
7296 cam_status cstat;
7297
7298 ostat = ahd_get_transaction_status(scb);
7299 if (ostat == CAM_REQ_INPROG)
7300 ahd_set_transaction_status(scb, status);
7301 cstat = ahd_get_transaction_status(scb);
7302 if (cstat != CAM_REQ_CMP)
7303 ahd_freeze_scb(scb);
7304 ahd_done(ahd, scb);
7305}
7306
7307int
7308ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
7309 int lun, u_int tag, role_t role, uint32_t status,
7310 ahd_search_action action)
7311{
7312 struct scb *scb;
7313 struct scb *mk_msg_scb;
7314 struct scb *prev_scb;
7315 ahd_mode_state saved_modes;
7316 u_int qinstart;
7317 u_int qinpos;
7318 u_int qintail;
7319 u_int tid_next;
7320 u_int tid_prev;
7321 u_int scbid;
7322 u_int seq_flags2;
7323 u_int savedscbptr;
7324 uint32_t busaddr;
7325 int found;
7326 int targets;
7327
7328
7329 saved_modes = ahd_save_modes(ahd);
7330 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
7331
7332
7333
7334
7335
7336 if ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN|CCSCBDIR))
7337 == (CCARREN|CCSCBEN|CCSCBDIR)) {
7338 ahd_outb(ahd, CCSCBCTL,
7339 ahd_inb(ahd, CCSCBCTL) & ~(CCARREN|CCSCBEN));
7340 while ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN)) != 0)
7341 ;
7342 }
7343
7344 qintail = AHD_QIN_WRAP(ahd->qinfifonext);
7345 qinstart = ahd_get_snscb_qoff(ahd);
7346 qinpos = AHD_QIN_WRAP(qinstart);
7347 found = 0;
7348 prev_scb = NULL;
7349
7350 if (action == SEARCH_PRINT) {
7351 printf("qinstart = %d qinfifonext = %d\nQINFIFO:",
7352 qinstart, ahd->qinfifonext);
7353 }
7354
7355
7356
7357
7358
7359 ahd->qinfifonext = qinstart;
7360 busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr);
7361 ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr);
7362
7363 while (qinpos != qintail) {
7364 scb = ahd_lookup_scb(ahd, ahd->qinfifo[qinpos]);
7365 if (scb == NULL) {
7366 printf("qinpos = %d, SCB index = %d\n",
7367 qinpos, ahd->qinfifo[qinpos]);
7368 panic("Loop 1\n");
7369 }
7370
7371 if (ahd_match_scb(ahd, scb, target, channel, lun, tag, role)) {
7372
7373
7374
7375 found++;
7376 switch (action) {
7377 case SEARCH_COMPLETE:
7378 if ((scb->flags & SCB_ACTIVE) == 0)
7379 printf("Inactive SCB in qinfifo\n");
7380 ahd_done_with_status(ahd, scb, status);
7381
7382 case SEARCH_REMOVE:
7383 break;
7384 case SEARCH_PRINT:
7385 printf(" 0x%x", ahd->qinfifo[qinpos]);
7386
7387 case SEARCH_COUNT:
7388 ahd_qinfifo_requeue(ahd, prev_scb, scb);
7389 prev_scb = scb;
7390 break;
7391 }
7392 } else {
7393 ahd_qinfifo_requeue(ahd, prev_scb, scb);
7394 prev_scb = scb;
7395 }
7396 qinpos = AHD_QIN_WRAP(qinpos+1);
7397 }
7398
7399 ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
7400
7401 if (action == SEARCH_PRINT)
7402 printf("\nWAITING_TID_QUEUES:\n");
7403
7404
7405
7406
7407
7408
7409
7410 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7411 seq_flags2 = ahd_inb(ahd, SEQ_FLAGS2);
7412 if ((seq_flags2 & PENDING_MK_MESSAGE) != 0) {
7413 scbid = ahd_inw(ahd, MK_MESSAGE_SCB);
7414 mk_msg_scb = ahd_lookup_scb(ahd, scbid);
7415 } else
7416 mk_msg_scb = NULL;
7417 savedscbptr = ahd_get_scbptr(ahd);
7418 tid_next = ahd_inw(ahd, WAITING_TID_HEAD);
7419 tid_prev = SCB_LIST_NULL;
7420 targets = 0;
7421 for (scbid = tid_next; !SCBID_IS_NULL(scbid); scbid = tid_next) {
7422 u_int tid_head;
7423 u_int tid_tail;
7424
7425 targets++;
7426 if (targets > AHD_NUM_TARGETS)
7427 panic("TID LIST LOOP");
7428
7429 if (scbid >= ahd->scb_data.numscbs) {
7430 printf("%s: Waiting TID List inconsistency. "
7431 "SCB index == 0x%x, yet numscbs == 0x%x.",
7432 ahd_name(ahd), scbid, ahd->scb_data.numscbs);
7433 ahd_dump_card_state(ahd);
7434 panic("for safety");
7435 }
7436 scb = ahd_lookup_scb(ahd, scbid);
7437 if (scb == NULL) {
7438 printf("%s: SCB = 0x%x Not Active!\n",
7439 ahd_name(ahd), scbid);
7440 panic("Waiting TID List traversal\n");
7441 }
7442 ahd_set_scbptr(ahd, scbid);
7443 tid_next = ahd_inw_scbram(ahd, SCB_NEXT2);
7444 if (ahd_match_scb(ahd, scb, target, channel, CAM_LUN_WILDCARD,
7445 SCB_LIST_NULL, ROLE_UNKNOWN) == 0) {
7446 tid_prev = scbid;
7447 continue;
7448 }
7449
7450
7451
7452
7453 if (action == SEARCH_PRINT)
7454 printf(" %d ( ", SCB_GET_TARGET(ahd, scb));
7455 tid_head = scbid;
7456 found += ahd_search_scb_list(ahd, target, channel,
7457 lun, tag, role, status,
7458 action, &tid_head, &tid_tail,
7459 SCB_GET_TARGET(ahd, scb));
7460
7461
7462
7463
7464 if (mk_msg_scb != NULL
7465 && ahd_match_scb(ahd, mk_msg_scb, target, channel,
7466 lun, tag, role)) {
7467
7468
7469
7470
7471 found++;
7472 switch (action) {
7473 case SEARCH_COMPLETE:
7474 if ((mk_msg_scb->flags & SCB_ACTIVE) == 0)
7475 printf("Inactive SCB pending MK_MSG\n");
7476 ahd_done_with_status(ahd, mk_msg_scb, status);
7477
7478 case SEARCH_REMOVE:
7479 {
7480 u_int tail_offset;
7481
7482 printf("Removing MK_MSG scb\n");
7483
7484
7485
7486
7487
7488 tail_offset = WAITING_SCB_TAILS
7489 + (2 * SCB_GET_TARGET(ahd, mk_msg_scb));
7490 ahd_outw(ahd, tail_offset, tid_tail);
7491
7492 seq_flags2 &= ~PENDING_MK_MESSAGE;
7493 ahd_outb(ahd, SEQ_FLAGS2, seq_flags2);
7494 ahd_outw(ahd, CMDS_PENDING,
7495 ahd_inw(ahd, CMDS_PENDING)-1);
7496 mk_msg_scb = NULL;
7497 break;
7498 }
7499 case SEARCH_PRINT:
7500 printf(" 0x%x", SCB_GET_TAG(scb));
7501
7502 case SEARCH_COUNT:
7503 break;
7504 }
7505 }
7506
7507 if (mk_msg_scb != NULL
7508 && SCBID_IS_NULL(tid_head)
7509 && ahd_match_scb(ahd, scb, target, channel, CAM_LUN_WILDCARD,
7510 SCB_LIST_NULL, ROLE_UNKNOWN)) {
7511
7512
7513
7514
7515
7516
7517 printf("Queueing mk_msg_scb\n");
7518 tid_head = ahd_inw(ahd, MK_MESSAGE_SCB);
7519 seq_flags2 &= ~PENDING_MK_MESSAGE;
7520 ahd_outb(ahd, SEQ_FLAGS2, seq_flags2);
7521 mk_msg_scb = NULL;
7522 }
7523 if (tid_head != scbid)
7524 ahd_stitch_tid_list(ahd, tid_prev, tid_head, tid_next);
7525 if (!SCBID_IS_NULL(tid_head))
7526 tid_prev = tid_head;
7527 if (action == SEARCH_PRINT)
7528 printf(")\n");
7529 }
7530
7531
7532 ahd_set_scbptr(ahd, savedscbptr);
7533 ahd_restore_modes(ahd, saved_modes);
7534 return (found);
7535}
7536
7537static int
7538ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel,
7539 int lun, u_int tag, role_t role, uint32_t status,
7540 ahd_search_action action, u_int *list_head,
7541 u_int *list_tail, u_int tid)
7542{
7543 struct scb *scb;
7544 u_int scbid;
7545 u_int next;
7546 u_int prev;
7547 int found;
7548
7549 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
7550 found = 0;
7551 prev = SCB_LIST_NULL;
7552 next = *list_head;
7553 *list_tail = SCB_LIST_NULL;
7554 for (scbid = next; !SCBID_IS_NULL(scbid); scbid = next) {
7555 if (scbid >= ahd->scb_data.numscbs) {
7556 printf("%s:SCB List inconsistency. "
7557 "SCB == 0x%x, yet numscbs == 0x%x.",
7558 ahd_name(ahd), scbid, ahd->scb_data.numscbs);
7559 ahd_dump_card_state(ahd);
7560 panic("for safety");
7561 }
7562 scb = ahd_lookup_scb(ahd, scbid);
7563 if (scb == NULL) {
7564 printf("%s: SCB = %d Not Active!\n",
7565 ahd_name(ahd), scbid);
7566 panic("Waiting List traversal\n");
7567 }
7568 ahd_set_scbptr(ahd, scbid);
7569 *list_tail = scbid;
7570 next = ahd_inw_scbram(ahd, SCB_NEXT);
7571 if (ahd_match_scb(ahd, scb, target, channel,
7572 lun, SCB_LIST_NULL, role) == 0) {
7573 prev = scbid;
7574 continue;
7575 }
7576 found++;
7577 switch (action) {
7578 case SEARCH_COMPLETE:
7579 if ((scb->flags & SCB_ACTIVE) == 0)
7580 printf("Inactive SCB in Waiting List\n");
7581 ahd_done_with_status(ahd, scb, status);
7582
7583 case SEARCH_REMOVE:
7584 ahd_rem_wscb(ahd, scbid, prev, next, tid);
7585 *list_tail = prev;
7586 if (SCBID_IS_NULL(prev))
7587 *list_head = next;
7588 break;
7589 case SEARCH_PRINT:
7590 printf("0x%x ", scbid);
7591 case SEARCH_COUNT:
7592 prev = scbid;
7593 break;
7594 }
7595 if (found > AHD_SCB_MAX)
7596 panic("SCB LIST LOOP");
7597 }
7598 if (action == SEARCH_COMPLETE
7599 || action == SEARCH_REMOVE)
7600 ahd_outw(ahd, CMDS_PENDING, ahd_inw(ahd, CMDS_PENDING) - found);
7601 return (found);
7602}
7603
7604static void
7605ahd_stitch_tid_list(struct ahd_softc *ahd, u_int tid_prev,
7606 u_int tid_cur, u_int tid_next)
7607{
7608 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
7609
7610 if (SCBID_IS_NULL(tid_cur)) {
7611
7612
7613 if (SCBID_IS_NULL(tid_prev)) {
7614 ahd_outw(ahd, WAITING_TID_HEAD, tid_next);
7615 } else {
7616 ahd_set_scbptr(ahd, tid_prev);
7617 ahd_outw(ahd, SCB_NEXT2, tid_next);
7618 }
7619 if (SCBID_IS_NULL(tid_next))
7620 ahd_outw(ahd, WAITING_TID_TAIL, tid_prev);
7621 } else {
7622
7623
7624 if (SCBID_IS_NULL(tid_prev)) {
7625 ahd_outw(ahd, WAITING_TID_HEAD, tid_cur);
7626 } else {
7627 ahd_set_scbptr(ahd, tid_prev);
7628 ahd_outw(ahd, SCB_NEXT2, tid_cur);
7629 }
7630 ahd_set_scbptr(ahd, tid_cur);
7631 ahd_outw(ahd, SCB_NEXT2, tid_next);
7632
7633 if (SCBID_IS_NULL(tid_next))
7634 ahd_outw(ahd, WAITING_TID_TAIL, tid_cur);
7635 }
7636}
7637
7638
7639
7640
7641
7642static u_int
7643ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid,
7644 u_int prev, u_int next, u_int tid)
7645{
7646 u_int tail_offset;
7647
7648 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
7649 if (!SCBID_IS_NULL(prev)) {
7650 ahd_set_scbptr(ahd, prev);
7651 ahd_outw(ahd, SCB_NEXT, next);
7652 }
7653
7654
7655
7656
7657
7658
7659
7660
7661 tail_offset = WAITING_SCB_TAILS + (2 * tid);
7662 if (SCBID_IS_NULL(next)
7663 && ahd_inw(ahd, tail_offset) == scbid)
7664 ahd_outw(ahd, tail_offset, prev);
7665
7666 ahd_add_scb_to_free_list(ahd, scbid);
7667 return (next);
7668}
7669
7670
7671
7672
7673
7674
7675static void
7676ahd_add_scb_to_free_list(struct ahd_softc *ahd, u_int scbid)
7677{
7678
7679
7680
7681
7682
7683
7684}
7685
7686
7687
7688
7689
7690
7691
7692
7693int
7694ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel,
7695 int lun, u_int tag, role_t role, uint32_t status)
7696{
7697 struct scb *scbp;
7698 struct scb *scbp_next;
7699 u_int i, j;
7700 u_int maxtarget;
7701 u_int minlun;
7702 u_int maxlun;
7703 int found;
7704 ahd_mode_state saved_modes;
7705
7706
7707 saved_modes = ahd_save_modes(ahd);
7708 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7709
7710 found = ahd_search_qinfifo(ahd, target, channel, lun, SCB_LIST_NULL,
7711 role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);
7712
7713
7714
7715
7716 i = 0;
7717 maxtarget = 16;
7718 if (target != CAM_TARGET_WILDCARD) {
7719 i = target;
7720 if (channel == 'B')
7721 i += 8;
7722 maxtarget = i + 1;
7723 }
7724
7725 if (lun == CAM_LUN_WILDCARD) {
7726 minlun = 0;
7727 maxlun = AHD_NUM_LUNS_NONPKT;
7728 } else if (lun >= AHD_NUM_LUNS_NONPKT) {
7729 minlun = maxlun = 0;
7730 } else {
7731 minlun = lun;
7732 maxlun = lun + 1;
7733 }
7734
7735 if (role != ROLE_TARGET) {
7736 for (;i < maxtarget; i++) {
7737 for (j = minlun;j < maxlun; j++) {
7738 u_int scbid;
7739 u_int tcl;
7740
7741 tcl = BUILD_TCL_RAW(i, 'A', j);
7742 scbid = ahd_find_busy_tcl(ahd, tcl);
7743 scbp = ahd_lookup_scb(ahd, scbid);
7744 if (scbp == NULL
7745 || ahd_match_scb(ahd, scbp, target, channel,
7746 lun, tag, role) == 0)
7747 continue;
7748 ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(i, 'A', j));
7749 }
7750 }
7751 }
7752
7753
7754
7755
7756
7757 ahd_flush_qoutfifo(ahd);
7758
7759
7760
7761
7762
7763
7764
7765 scbp_next = LIST_FIRST(&ahd->pending_scbs);
7766 while (scbp_next != NULL) {
7767 scbp = scbp_next;
7768 scbp_next = LIST_NEXT(scbp, pending_links);
7769 if (ahd_match_scb(ahd, scbp, target, channel, lun, tag, role)) {
7770 cam_status ostat;
7771
7772 ostat = ahd_get_transaction_status(scbp);
7773 if (ostat == CAM_REQ_INPROG)
7774 ahd_set_transaction_status(scbp, status);
7775 if (ahd_get_transaction_status(scbp) != CAM_REQ_CMP)
7776 ahd_freeze_scb(scbp);
7777 if ((scbp->flags & SCB_ACTIVE) == 0)
7778 printf("Inactive SCB on pending list\n");
7779 ahd_done(ahd, scbp);
7780 found++;
7781 }
7782 }
7783 ahd_restore_modes(ahd, saved_modes);
7784 ahd_platform_abort_scbs(ahd, target, channel, lun, tag, role, status);
7785 ahd->flags |= AHD_UPDATE_PEND_CMDS;
7786 return found;
7787}
7788
7789static void
7790ahd_reset_current_bus(struct ahd_softc *ahd)
7791{
7792 uint8_t scsiseq;
7793
7794 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
7795 ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) & ~ENSCSIRST);
7796 scsiseq = ahd_inb(ahd, SCSISEQ0) & ~(ENSELO|ENARBO|SCSIRSTO);
7797 ahd_outb(ahd, SCSISEQ0, scsiseq | SCSIRSTO);
7798 ahd_flush_device_writes(ahd);
7799 ahd_delay(AHD_BUSRESET_DELAY);
7800
7801 ahd_outb(ahd, SCSISEQ0, scsiseq);
7802 ahd_flush_device_writes(ahd);
7803 ahd_delay(AHD_BUSRESET_DELAY);
7804 if ((ahd->bugs & AHD_SCSIRST_BUG) != 0) {
7805
7806
7807
7808
7809
7810
7811 ahd_reset(ahd, TRUE);
7812 ahd_intr_enable(ahd, TRUE);
7813 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
7814 }
7815
7816 ahd_clear_intstat(ahd);
7817}
7818
7819int
7820ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
7821{
7822 struct ahd_devinfo devinfo;
7823 u_int initiator;
7824 u_int target;
7825 u_int max_scsiid;
7826 int found;
7827 u_int fifo;
7828 u_int next_fifo;
7829 uint8_t scsiseq;
7830
7831
7832
7833
7834 if (ahd->flags & AHD_BUS_RESET_ACTIVE) {
7835 printf("%s: bus reset still active\n",
7836 ahd_name(ahd));
7837 return 0;
7838 }
7839 ahd->flags |= AHD_BUS_RESET_ACTIVE;
7840
7841 ahd->pending_device = NULL;
7842
7843 ahd_compile_devinfo(&devinfo,
7844 CAM_TARGET_WILDCARD,
7845 CAM_TARGET_WILDCARD,
7846 CAM_LUN_WILDCARD,
7847 channel, ROLE_UNKNOWN);
7848 ahd_pause(ahd);
7849
7850
7851 ahd_clear_critical_section(ahd);
7852
7853
7854
7855
7856
7857
7858 ahd_run_qoutfifo(ahd);
7859#ifdef AHD_TARGET_MODE
7860 if ((ahd->flags & AHD_TARGETROLE) != 0) {
7861 ahd_run_tqinfifo(ahd, TRUE);
7862 }
7863#endif
7864 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7865
7866
7867
7868
7869
7870 ahd_outb(ahd, SCSISEQ0, 0);
7871 ahd_outb(ahd, SCSISEQ1, 0);
7872
7873
7874
7875
7876
7877
7878 next_fifo = fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO;
7879 if (next_fifo > CURRFIFO_1)
7880
7881 next_fifo = fifo = 0;
7882 do {
7883 next_fifo ^= CURRFIFO_1;
7884 ahd_set_modes(ahd, next_fifo, next_fifo);
7885 ahd_outb(ahd, DFCNTRL,
7886 ahd_inb(ahd, DFCNTRL) & ~(SCSIEN|HDMAEN));
7887 while ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) != 0)
7888 ahd_delay(10);
7889
7890
7891
7892 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7893 ahd_outb(ahd, DFFSTAT, next_fifo);
7894 } while (next_fifo != fifo);
7895
7896
7897
7898
7899 ahd_clear_msg_state(ahd);
7900 ahd_outb(ahd, SIMODE1,
7901 ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST));
7902
7903 if (initiate_reset)
7904 ahd_reset_current_bus(ahd);
7905
7906 ahd_clear_intstat(ahd);
7907
7908
7909
7910
7911
7912 found = ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, channel,
7913 CAM_LUN_WILDCARD, SCB_LIST_NULL,
7914 ROLE_UNKNOWN, CAM_SCSI_BUS_RESET);
7915
7916
7917
7918
7919 ahd_clear_fifo(ahd, 0);
7920 ahd_clear_fifo(ahd, 1);
7921
7922
7923
7924
7925 ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST);
7926 scsiseq = ahd_inb(ahd, SCSISEQ_TEMPLATE);
7927 ahd_outb(ahd, SCSISEQ1, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
7928
7929 max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7;
7930#ifdef AHD_TARGET_MODE
7931
7932
7933
7934
7935 for (target = 0; target <= max_scsiid; target++) {
7936 struct ahd_tmode_tstate* tstate;
7937 u_int lun;
7938
7939 tstate = ahd->enabled_targets[target];
7940 if (tstate == NULL)
7941 continue;
7942 for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
7943 struct ahd_tmode_lstate* lstate;
7944
7945 lstate = tstate->enabled_luns[lun];
7946 if (lstate == NULL)
7947 continue;
7948
7949 ahd_queue_lstate_event(ahd, lstate, CAM_TARGET_WILDCARD,
7950 EVENT_TYPE_BUS_RESET, 0);
7951 ahd_send_lstate_events(ahd, lstate);
7952 }
7953 }
7954#endif
7955
7956 ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD,
7957 CAM_LUN_WILDCARD, AC_BUS_RESET);
7958
7959
7960
7961
7962 for (target = 0; target <= max_scsiid; target++) {
7963
7964 if (ahd->enabled_targets[target] == NULL)
7965 continue;
7966 for (initiator = 0; initiator <= max_scsiid; initiator++) {
7967 struct ahd_devinfo devinfo;
7968
7969 ahd_compile_devinfo(&devinfo, target, initiator,
7970 CAM_LUN_WILDCARD,
7971 'A', ROLE_UNKNOWN);
7972 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
7973 AHD_TRANS_CUR, TRUE);
7974 ahd_set_syncrate(ahd, &devinfo, 0,
7975 0, 0,
7976 AHD_TRANS_CUR, TRUE);
7977 }
7978 }
7979
7980 ahd_restart(ahd);
7981
7982 return (found);
7983}
7984
7985
7986static void
7987ahd_stat_timer(void *arg)
7988{
7989 struct ahd_softc *ahd = arg;
7990 u_long s;
7991 int enint_coal;
7992
7993 ahd_lock(ahd, &s);
7994
7995 enint_coal = ahd->hs_mailbox & ENINT_COALESCE;
7996 if (ahd->cmdcmplt_total > ahd->int_coalescing_threshold)
7997 enint_coal |= ENINT_COALESCE;
7998 else if (ahd->cmdcmplt_total < ahd->int_coalescing_stop_threshold)
7999 enint_coal &= ~ENINT_COALESCE;
8000
8001 if (enint_coal != (ahd->hs_mailbox & ENINT_COALESCE)) {
8002 ahd_enable_coalescing(ahd, enint_coal);
8003#ifdef AHD_DEBUG
8004 if ((ahd_debug & AHD_SHOW_INT_COALESCING) != 0)
8005 printf("%s: Interrupt coalescing "
8006 "now %sabled. Cmds %d\n",
8007 ahd_name(ahd),
8008 (enint_coal & ENINT_COALESCE) ? "en" : "dis",
8009 ahd->cmdcmplt_total);
8010#endif
8011 }
8012
8013 ahd->cmdcmplt_bucket = (ahd->cmdcmplt_bucket+1) & (AHD_STAT_BUCKETS-1);
8014 ahd->cmdcmplt_total -= ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket];
8015 ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket] = 0;
8016 ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
8017 ahd_stat_timer, ahd);
8018 ahd_unlock(ahd, &s);
8019}
8020
8021
8022void
8023ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb)
8024{
8025 if (scb->hscb->shared_data.istatus.scsi_status != 0) {
8026 ahd_handle_scsi_status(ahd, scb);
8027 } else {
8028 ahd_calc_residual(ahd, scb);
8029 ahd_done(ahd, scb);
8030 }
8031}
8032
8033void
8034ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
8035{
8036 struct hardware_scb *hscb;
8037 int paused;
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048 hscb = scb->hscb;
8049
8050 if (ahd_is_paused(ahd)) {
8051 paused = 1;
8052 } else {
8053 paused = 0;
8054 ahd_pause(ahd);
8055 }
8056
8057
8058 ahd_freeze_devq(ahd, scb);
8059 ahd_freeze_scb(scb);
8060 ahd->qfreeze_cnt++;
8061 ahd_outw(ahd, KERNEL_QFREEZE_COUNT, ahd->qfreeze_cnt);
8062
8063 if (paused == 0)
8064 ahd_unpause(ahd);
8065
8066
8067 if ((scb->flags & SCB_SENSE) != 0) {
8068
8069
8070
8071
8072 scb->flags &= ~SCB_SENSE;
8073 ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
8074 ahd_done(ahd, scb);
8075 return;
8076 }
8077 ahd_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR);
8078 ahd_set_scsi_status(scb, hscb->shared_data.istatus.scsi_status);
8079 switch (hscb->shared_data.istatus.scsi_status) {
8080 case STATUS_PKT_SENSE:
8081 {
8082 struct scsi_status_iu_header *siu;
8083
8084 ahd_sync_sense(ahd, scb, BUS_DMASYNC_POSTREAD);
8085 siu = (struct scsi_status_iu_header *)scb->sense_data;
8086 ahd_set_scsi_status(scb, siu->status);
8087#ifdef AHD_DEBUG
8088 if ((ahd_debug & AHD_SHOW_SENSE) != 0) {
8089 ahd_print_path(ahd, scb);
8090 printf("SCB 0x%x Received PKT Status of 0x%x\n",
8091 SCB_GET_TAG(scb), siu->status);
8092 printf("\tflags = 0x%x, sense len = 0x%x, "
8093 "pktfail = 0x%x\n",
8094 siu->flags, scsi_4btoul(siu->sense_length),
8095 scsi_4btoul(siu->pkt_failures_length));
8096 }
8097#endif
8098 if ((siu->flags & SIU_RSPVALID) != 0) {
8099 ahd_print_path(ahd, scb);
8100 if (scsi_4btoul(siu->pkt_failures_length) < 4) {
8101 printf("Unable to parse pkt_failures\n");
8102 } else {
8103
8104 switch (SIU_PKTFAIL_CODE(siu)) {
8105 case SIU_PFC_NONE:
8106 printf("No packet failure found\n");
8107 break;
8108 case SIU_PFC_CIU_FIELDS_INVALID:
8109 printf("Invalid Command IU Field\n");
8110 break;
8111 case SIU_PFC_TMF_NOT_SUPPORTED:
8112 printf("TMF not supportd\n");
8113 break;
8114 case SIU_PFC_TMF_FAILED:
8115 printf("TMF failed\n");
8116 break;
8117 case SIU_PFC_INVALID_TYPE_CODE:
8118 printf("Invalid L_Q Type code\n");
8119 break;
8120 case SIU_PFC_ILLEGAL_REQUEST:
8121 printf("Illegal request\n");
8122 default:
8123 break;
8124 }
8125 }
8126 if (siu->status == SCSI_STATUS_OK)
8127 ahd_set_transaction_status(scb,
8128 CAM_REQ_CMP_ERR);
8129 }
8130 if ((siu->flags & SIU_SNSVALID) != 0) {
8131 scb->flags |= SCB_PKT_SENSE;
8132#ifdef AHD_DEBUG
8133 if ((ahd_debug & AHD_SHOW_SENSE) != 0)
8134 printf("Sense data available\n");
8135#endif
8136 }
8137 ahd_done(ahd, scb);
8138 break;
8139 }
8140 case SCSI_STATUS_CMD_TERMINATED:
8141 case SCSI_STATUS_CHECK_COND:
8142 {
8143 struct ahd_devinfo devinfo;
8144 struct ahd_dma_seg *sg;
8145 struct scsi_sense *sc;
8146 struct ahd_initiator_tinfo *targ_info;
8147 struct ahd_tmode_tstate *tstate;
8148 struct ahd_transinfo *tinfo;
8149#ifdef AHD_DEBUG
8150 if (ahd_debug & AHD_SHOW_SENSE) {
8151 ahd_print_path(ahd, scb);
8152 printf("SCB %d: requests Check Status\n",
8153 SCB_GET_TAG(scb));
8154 }
8155#endif
8156
8157 if (ahd_perform_autosense(scb) == 0)
8158 break;
8159
8160 ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb),
8161 SCB_GET_TARGET(ahd, scb),
8162 SCB_GET_LUN(scb),
8163 SCB_GET_CHANNEL(ahd, scb),
8164 ROLE_INITIATOR);
8165 targ_info = ahd_fetch_transinfo(ahd,
8166 devinfo.channel,
8167 devinfo.our_scsiid,
8168 devinfo.target,
8169 &tstate);
8170 tinfo = &targ_info->curr;
8171 sg = scb->sg_list;
8172 sc = (struct scsi_sense *)hscb->shared_data.idata.cdb;
8173
8174
8175
8176 ahd_update_residual(ahd, scb);
8177#ifdef AHD_DEBUG
8178 if (ahd_debug & AHD_SHOW_SENSE) {
8179 ahd_print_path(ahd, scb);
8180 printf("Sending Sense\n");
8181 }
8182#endif
8183 scb->sg_count = 0;
8184 sg = ahd_sg_setup(ahd, scb, sg, ahd_get_sense_bufaddr(ahd, scb),
8185 ahd_get_sense_bufsize(ahd, scb),
8186 TRUE);
8187 sc->opcode = REQUEST_SENSE;
8188 sc->byte2 = 0;
8189 if (tinfo->protocol_version <= SCSI_REV_2
8190 && SCB_GET_LUN(scb) < 8)
8191 sc->byte2 = SCB_GET_LUN(scb) << 5;
8192 sc->unused[0] = 0;
8193 sc->unused[1] = 0;
8194 sc->length = ahd_get_sense_bufsize(ahd, scb);
8195 sc->control = 0;
8196
8197
8198
8199
8200
8201
8202
8203
8204 hscb->control = 0;
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214 if (ahd_get_residual(scb) == ahd_get_transfer_length(scb)) {
8215 ahd_update_neg_request(ahd, &devinfo,
8216 tstate, targ_info,
8217 AHD_NEG_IF_NON_ASYNC);
8218 }
8219 if (tstate->auto_negotiate & devinfo.target_mask) {
8220 hscb->control |= MK_MESSAGE;
8221 scb->flags &=
8222 ~(SCB_NEGOTIATE|SCB_ABORT|SCB_DEVICE_RESET);
8223 scb->flags |= SCB_AUTO_NEGOTIATE;
8224 }
8225 hscb->cdb_len = sizeof(*sc);
8226 ahd_setup_data_scb(ahd, scb);
8227 scb->flags |= SCB_SENSE;
8228 ahd_queue_scb(ahd, scb);
8229 break;
8230 }
8231 case SCSI_STATUS_OK:
8232 printf("%s: Interrupted for staus of 0???\n",
8233 ahd_name(ahd));
8234
8235 default:
8236 ahd_done(ahd, scb);
8237 break;
8238 }
8239}
8240
8241
8242
8243
8244void
8245ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb)
8246{
8247 struct hardware_scb *hscb;
8248 struct initiator_status *spkt;
8249 uint32_t sgptr;
8250 uint32_t resid_sgptr;
8251 uint32_t resid;
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269 hscb = scb->hscb;
8270 sgptr = ahd_le32toh(hscb->sgptr);
8271 if ((sgptr & SG_STATUS_VALID) == 0)
8272
8273 return;
8274 sgptr &= ~SG_STATUS_VALID;
8275
8276 if ((sgptr & SG_LIST_NULL) != 0)
8277
8278 return;
8279
8280
8281
8282
8283
8284
8285
8286 spkt = &hscb->shared_data.istatus;
8287 resid_sgptr = ahd_le32toh(spkt->residual_sgptr);
8288 if ((sgptr & SG_FULL_RESID) != 0) {
8289
8290 resid = ahd_get_transfer_length(scb);
8291 } else if ((resid_sgptr & SG_LIST_NULL) != 0) {
8292
8293 return;
8294 } else if ((resid_sgptr & SG_OVERRUN_RESID) != 0) {
8295 ahd_print_path(ahd, scb);
8296 printf("data overrun detected Tag == 0x%x.\n",
8297 SCB_GET_TAG(scb));
8298 ahd_freeze_devq(ahd, scb);
8299 ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
8300 ahd_freeze_scb(scb);
8301 return;
8302 } else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {
8303 panic("Bogus resid sgptr value 0x%x\n", resid_sgptr);
8304
8305 } else {
8306 struct ahd_dma_seg *sg;
8307
8308
8309
8310
8311
8312 resid = ahd_le32toh(spkt->residual_datacnt) & AHD_SG_LEN_MASK;
8313 sg = ahd_sg_bus_to_virt(ahd, scb, resid_sgptr & SG_PTR_MASK);
8314
8315
8316 sg--;
8317
8318
8319
8320
8321
8322
8323 while ((ahd_le32toh(sg->len) & AHD_DMA_LAST_SEG) == 0) {
8324 sg++;
8325 resid += ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
8326 }
8327 }
8328 if ((scb->flags & SCB_SENSE) == 0)
8329 ahd_set_residual(scb, resid);
8330 else
8331 ahd_set_sense_residual(scb, resid);
8332
8333#ifdef AHD_DEBUG
8334 if ((ahd_debug & AHD_SHOW_MISC) != 0) {
8335 ahd_print_path(ahd, scb);
8336 printf("Handled %sResidual of %d bytes\n",
8337 (scb->flags & SCB_SENSE) ? "Sense " : "", resid);
8338 }
8339#endif
8340}
8341
8342
8343#ifdef AHD_TARGET_MODE
8344
8345
8346
8347static void
8348ahd_queue_lstate_event(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate,
8349 u_int initiator_id, u_int event_type, u_int event_arg)
8350{
8351 struct ahd_tmode_event *event;
8352 int pending;
8353
8354 xpt_freeze_devq(lstate->path, 1);
8355 if (lstate->event_w_idx >= lstate->event_r_idx)
8356 pending = lstate->event_w_idx - lstate->event_r_idx;
8357 else
8358 pending = AHD_TMODE_EVENT_BUFFER_SIZE + 1
8359 - (lstate->event_r_idx - lstate->event_w_idx);
8360
8361 if (event_type == EVENT_TYPE_BUS_RESET
8362 || event_type == MSG_BUS_DEV_RESET) {
8363
8364
8365
8366
8367
8368
8369 lstate->event_r_idx = 0;
8370 lstate->event_w_idx = 0;
8371 xpt_release_devq(lstate->path, pending, FALSE);
8372 }
8373
8374 if (pending == AHD_TMODE_EVENT_BUFFER_SIZE) {
8375 xpt_print_path(lstate->path);
8376 printf("immediate event %x:%x lost\n",
8377 lstate->event_buffer[lstate->event_r_idx].event_type,
8378 lstate->event_buffer[lstate->event_r_idx].event_arg);
8379 lstate->event_r_idx++;
8380 if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
8381 lstate->event_r_idx = 0;
8382 xpt_release_devq(lstate->path, 1, FALSE);
8383 }
8384
8385 event = &lstate->event_buffer[lstate->event_w_idx];
8386 event->initiator_id = initiator_id;
8387 event->event_type = event_type;
8388 event->event_arg = event_arg;
8389 lstate->event_w_idx++;
8390 if (lstate->event_w_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
8391 lstate->event_w_idx = 0;
8392}
8393
8394
8395
8396
8397
8398void
8399ahd_send_lstate_events(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate)
8400{
8401 struct ccb_hdr *ccbh;
8402 struct ccb_immed_notify *inot;
8403
8404 while (lstate->event_r_idx != lstate->event_w_idx
8405 && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) {
8406 struct ahd_tmode_event *event;
8407
8408 event = &lstate->event_buffer[lstate->event_r_idx];
8409 SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);
8410 inot = (struct ccb_immed_notify *)ccbh;
8411 switch (event->event_type) {
8412 case EVENT_TYPE_BUS_RESET:
8413 ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN;
8414 break;
8415 default:
8416 ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN;
8417 inot->message_args[0] = event->event_type;
8418 inot->message_args[1] = event->event_arg;
8419 break;
8420 }
8421 inot->initiator_id = event->initiator_id;
8422 inot->sense_len = 0;
8423 xpt_done((union ccb *)inot);
8424 lstate->event_r_idx++;
8425 if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
8426 lstate->event_r_idx = 0;
8427 }
8428}
8429#endif
8430
8431
8432
8433#ifdef AHD_DUMP_SEQ
8434void
8435ahd_dumpseq(struct ahd_softc* ahd)
8436{
8437 int i;
8438 int max_prog;
8439
8440 max_prog = 2048;
8441
8442 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
8443 ahd_outw(ahd, PRGMCNT, 0);
8444 for (i = 0; i < max_prog; i++) {
8445 uint8_t ins_bytes[4];
8446
8447 ahd_insb(ahd, SEQRAM, ins_bytes, 4);
8448 printf("0x%08x\n", ins_bytes[0] << 24
8449 | ins_bytes[1] << 16
8450 | ins_bytes[2] << 8
8451 | ins_bytes[3]);
8452 }
8453}
8454#endif
8455
8456static void
8457ahd_loadseq(struct ahd_softc *ahd)
8458{
8459 struct cs cs_table[num_critical_sections];
8460 u_int begin_set[num_critical_sections];
8461 u_int end_set[num_critical_sections];
8462 struct patch *cur_patch;
8463 u_int cs_count;
8464 u_int cur_cs;
8465 u_int i;
8466 int downloaded;
8467 u_int skip_addr;
8468 u_int sg_prefetch_cnt;
8469 u_int sg_prefetch_cnt_limit;
8470 u_int sg_prefetch_align;
8471 u_int sg_size;
8472 u_int cacheline_mask;
8473 uint8_t download_consts[DOWNLOAD_CONST_COUNT];
8474
8475 if (bootverbose)
8476 printf("%s: Downloading Sequencer Program...",
8477 ahd_name(ahd));
8478
8479#if DOWNLOAD_CONST_COUNT != 8
8480#error "Download Const Mismatch"
8481#endif
8482
8483
8484
8485
8486 cs_count = 0;
8487 cur_cs = 0;
8488 memset(begin_set, 0, sizeof(begin_set));
8489 memset(end_set, 0, sizeof(end_set));
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509 sg_prefetch_align = ahd->pci_cachesize;
8510 if (sg_prefetch_align == 0)
8511 sg_prefetch_align = 8;
8512
8513 while (powerof2(sg_prefetch_align) == 0)
8514 sg_prefetch_align--;
8515
8516 cacheline_mask = sg_prefetch_align - 1;
8517
8518
8519
8520
8521
8522
8523 if (sg_prefetch_align > CCSGADDR_MAX/2)
8524 sg_prefetch_align = CCSGADDR_MAX/2;
8525
8526 sg_prefetch_cnt = sg_prefetch_align;
8527
8528
8529
8530
8531 sg_size = sizeof(struct ahd_dma_seg);
8532 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
8533 sg_size = sizeof(struct ahd_dma64_seg);
8534 while (sg_prefetch_cnt < sg_size)
8535 sg_prefetch_cnt += sg_prefetch_align;
8536
8537
8538
8539
8540
8541 if ((sg_prefetch_align % sg_size) != 0
8542 && (sg_prefetch_cnt < CCSGADDR_MAX))
8543 sg_prefetch_cnt += sg_prefetch_align;
8544
8545
8546
8547
8548
8549 sg_prefetch_cnt_limit = -(sg_prefetch_cnt - sg_size + 1);
8550 download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt;
8551 download_consts[SG_PREFETCH_CNT_LIMIT] = sg_prefetch_cnt_limit;
8552 download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_align - 1);
8553 download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_align - 1);
8554 download_consts[SG_SIZEOF] = sg_size;
8555 download_consts[PKT_OVERRUN_BUFOFFSET] =
8556 (ahd->overrun_buf - (uint8_t *)ahd->qoutfifo) / 256;
8557 download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_1BYTE_LUN;
8558 download_consts[CACHELINE_MASK] = cacheline_mask;
8559 cur_patch = patches;
8560 downloaded = 0;
8561 skip_addr = 0;
8562 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
8563 ahd_outw(ahd, PRGMCNT, 0);
8564
8565 for (i = 0; i < sizeof(seqprog)/4; i++) {
8566 if (ahd_check_patch(ahd, &cur_patch, i, &skip_addr) == 0) {
8567
8568
8569
8570
8571 continue;
8572 }
8573
8574
8575
8576
8577 for (; cur_cs < num_critical_sections; cur_cs++) {
8578 if (critical_sections[cur_cs].end <= i) {
8579 if (begin_set[cs_count] == TRUE
8580 && end_set[cs_count] == FALSE) {
8581 cs_table[cs_count].end = downloaded;
8582 end_set[cs_count] = TRUE;
8583 cs_count++;
8584 }
8585 continue;
8586 }
8587 if (critical_sections[cur_cs].begin <= i
8588 && begin_set[cs_count] == FALSE) {
8589 cs_table[cs_count].begin = downloaded;
8590 begin_set[cs_count] = TRUE;
8591 }
8592 break;
8593 }
8594 ahd_download_instr(ahd, i, download_consts);
8595 downloaded++;
8596 }
8597
8598 ahd->num_critical_sections = cs_count;
8599 if (cs_count != 0) {
8600
8601 cs_count *= sizeof(struct cs);
8602 ahd->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT);
8603 if (ahd->critical_sections == NULL)
8604 panic("ahd_loadseq: Could not malloc");
8605 memcpy(ahd->critical_sections, cs_table, cs_count);
8606 }
8607 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE);
8608
8609 if (bootverbose) {
8610 printf(" %d instructions downloaded\n", downloaded);
8611 printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
8612 ahd_name(ahd), ahd->features, ahd->bugs, ahd->flags);
8613 }
8614}
8615
8616static int
8617ahd_check_patch(struct ahd_softc *ahd, struct patch **start_patch,
8618 u_int start_instr, u_int *skip_addr)
8619{
8620 struct patch *cur_patch;
8621 struct patch *last_patch;
8622 u_int num_patches;
8623
8624 num_patches = ARRAY_SIZE(patches);
8625 last_patch = &patches[num_patches];
8626 cur_patch = *start_patch;
8627
8628 while (cur_patch < last_patch && start_instr == cur_patch->begin) {
8629
8630 if (cur_patch->patch_func(ahd) == 0) {
8631
8632
8633 *skip_addr = start_instr + cur_patch->skip_instr;
8634 cur_patch += cur_patch->skip_patch;
8635 } else {
8636
8637
8638
8639
8640 cur_patch++;
8641 }
8642 }
8643
8644 *start_patch = cur_patch;
8645 if (start_instr < *skip_addr)
8646
8647 return (0);
8648
8649 return (1);
8650}
8651
8652static u_int
8653ahd_resolve_seqaddr(struct ahd_softc *ahd, u_int address)
8654{
8655 struct patch *cur_patch;
8656 int address_offset;
8657 u_int skip_addr;
8658 u_int i;
8659
8660 address_offset = 0;
8661 cur_patch = patches;
8662 skip_addr = 0;
8663
8664 for (i = 0; i < address;) {
8665
8666 ahd_check_patch(ahd, &cur_patch, i, &skip_addr);
8667
8668 if (skip_addr > i) {
8669 int end_addr;
8670
8671 end_addr = MIN(address, skip_addr);
8672 address_offset += end_addr - i;
8673 i = skip_addr;
8674 } else {
8675 i++;
8676 }
8677 }
8678 return (address - address_offset);
8679}
8680
8681static void
8682ahd_download_instr(struct ahd_softc *ahd, u_int instrptr, uint8_t *dconsts)
8683{
8684 union ins_formats instr;
8685 struct ins_format1 *fmt1_ins;
8686 struct ins_format3 *fmt3_ins;
8687 u_int opcode;
8688
8689
8690
8691
8692 instr.integer = ahd_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);
8693
8694 fmt1_ins = &instr.format1;
8695 fmt3_ins = NULL;
8696
8697
8698 opcode = instr.format1.opcode;
8699 switch (opcode) {
8700 case AIC_OP_JMP:
8701 case AIC_OP_JC:
8702 case AIC_OP_JNC:
8703 case AIC_OP_CALL:
8704 case AIC_OP_JNE:
8705 case AIC_OP_JNZ:
8706 case AIC_OP_JE:
8707 case AIC_OP_JZ:
8708 {
8709 fmt3_ins = &instr.format3;
8710 fmt3_ins->address = ahd_resolve_seqaddr(ahd, fmt3_ins->address);
8711
8712 }
8713 case AIC_OP_OR:
8714 case AIC_OP_AND:
8715 case AIC_OP_XOR:
8716 case AIC_OP_ADD:
8717 case AIC_OP_ADC:
8718 case AIC_OP_BMOV:
8719 if (fmt1_ins->parity != 0) {
8720 fmt1_ins->immediate = dconsts[fmt1_ins->immediate];
8721 }
8722 fmt1_ins->parity = 0;
8723
8724 case AIC_OP_ROL:
8725 {
8726 int i, count;
8727
8728
8729 for (i = 0, count = 0; i < 31; i++) {
8730 uint32_t mask;
8731
8732 mask = 0x01 << i;
8733 if ((instr.integer & mask) != 0)
8734 count++;
8735 }
8736 if ((count & 0x01) == 0)
8737 instr.format1.parity = 1;
8738
8739
8740 instr.integer = ahd_htole32(instr.integer);
8741 ahd_outsb(ahd, SEQRAM, instr.bytes, 4);
8742 break;
8743 }
8744 default:
8745 panic("Unknown opcode encountered in seq program");
8746 break;
8747 }
8748}
8749
8750static int
8751ahd_probe_stack_size(struct ahd_softc *ahd)
8752{
8753 int last_probe;
8754
8755 last_probe = 0;
8756 while (1) {
8757 int i;
8758
8759
8760
8761
8762
8763
8764
8765 for (i = 1; i <= last_probe+1; i++) {
8766 ahd_outb(ahd, STACK, i & 0xFF);
8767 ahd_outb(ahd, STACK, (i >> 8) & 0xFF);
8768 }
8769
8770
8771 for (i = last_probe+1; i > 0; i--) {
8772 u_int stack_entry;
8773
8774 stack_entry = ahd_inb(ahd, STACK)
8775 |(ahd_inb(ahd, STACK) << 8);
8776 if (stack_entry != i)
8777 goto sized;
8778 }
8779 last_probe++;
8780 }
8781sized:
8782 return (last_probe);
8783}
8784
8785int
8786ahd_print_register(ahd_reg_parse_entry_t *table, u_int num_entries,
8787 const char *name, u_int address, u_int value,
8788 u_int *cur_column, u_int wrap_point)
8789{
8790 int printed;
8791 u_int printed_mask;
8792
8793 if (cur_column != NULL && *cur_column >= wrap_point) {
8794 printf("\n");
8795 *cur_column = 0;
8796 }
8797 printed = printf("%s[0x%x]", name, value);
8798 if (table == NULL) {
8799 printed += printf(" ");
8800 *cur_column += printed;
8801 return (printed);
8802 }
8803 printed_mask = 0;
8804 while (printed_mask != 0xFF) {
8805 int entry;
8806
8807 for (entry = 0; entry < num_entries; entry++) {
8808 if (((value & table[entry].mask)
8809 != table[entry].value)
8810 || ((printed_mask & table[entry].mask)
8811 == table[entry].mask))
8812 continue;
8813
8814 printed += printf("%s%s",
8815 printed_mask == 0 ? ":(" : "|",
8816 table[entry].name);
8817 printed_mask |= table[entry].mask;
8818
8819 break;
8820 }
8821 if (entry >= num_entries)
8822 break;
8823 }
8824 if (printed_mask != 0)
8825 printed += printf(") ");
8826 else
8827 printed += printf(" ");
8828 if (cur_column != NULL)
8829 *cur_column += printed;
8830 return (printed);
8831}
8832
8833void
8834ahd_dump_card_state(struct ahd_softc *ahd)
8835{
8836 struct scb *scb;
8837 ahd_mode_state saved_modes;
8838 u_int dffstat;
8839 int paused;
8840 u_int scb_index;
8841 u_int saved_scb_index;
8842 u_int cur_col;
8843 int i;
8844
8845 if (ahd_is_paused(ahd)) {
8846 paused = 1;
8847 } else {
8848 paused = 0;
8849 ahd_pause(ahd);
8850 }
8851 saved_modes = ahd_save_modes(ahd);
8852 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
8853 printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
8854 "%s: Dumping Card State at program address 0x%x Mode 0x%x\n",
8855 ahd_name(ahd),
8856 ahd_inw(ahd, CURADDR),
8857 ahd_build_mode_state(ahd, ahd->saved_src_mode,
8858 ahd->saved_dst_mode));
8859 if (paused)
8860 printf("Card was paused\n");
8861
8862 if (ahd_check_cmdcmpltqueues(ahd))
8863 printf("Completions are pending\n");
8864
8865
8866
8867
8868 cur_col = 0;
8869 ahd_intstat_print(ahd_inb(ahd, INTSTAT), &cur_col, 50);
8870 ahd_seloid_print(ahd_inb(ahd, SELOID), &cur_col, 50);
8871 ahd_selid_print(ahd_inb(ahd, SELID), &cur_col, 50);
8872 ahd_hs_mailbox_print(ahd_inb(ahd, LOCAL_HS_MAILBOX), &cur_col, 50);
8873 ahd_intctl_print(ahd_inb(ahd, INTCTL), &cur_col, 50);
8874 ahd_seqintstat_print(ahd_inb(ahd, SEQINTSTAT), &cur_col, 50);
8875 ahd_saved_mode_print(ahd_inb(ahd, SAVED_MODE), &cur_col, 50);
8876 ahd_dffstat_print(ahd_inb(ahd, DFFSTAT), &cur_col, 50);
8877 ahd_scsisigi_print(ahd_inb(ahd, SCSISIGI), &cur_col, 50);
8878 ahd_scsiphase_print(ahd_inb(ahd, SCSIPHASE), &cur_col, 50);
8879 ahd_scsibus_print(ahd_inb(ahd, SCSIBUS), &cur_col, 50);
8880 ahd_lastphase_print(ahd_inb(ahd, LASTPHASE), &cur_col, 50);
8881 ahd_scsiseq0_print(ahd_inb(ahd, SCSISEQ0), &cur_col, 50);
8882 ahd_scsiseq1_print(ahd_inb(ahd, SCSISEQ1), &cur_col, 50);
8883 ahd_seqctl0_print(ahd_inb(ahd, SEQCTL0), &cur_col, 50);
8884 ahd_seqintctl_print(ahd_inb(ahd, SEQINTCTL), &cur_col, 50);
8885 ahd_seq_flags_print(ahd_inb(ahd, SEQ_FLAGS), &cur_col, 50);
8886 ahd_seq_flags2_print(ahd_inb(ahd, SEQ_FLAGS2), &cur_col, 50);
8887 ahd_qfreeze_count_print(ahd_inw(ahd, QFREEZE_COUNT), &cur_col, 50);
8888 ahd_kernel_qfreeze_count_print(ahd_inw(ahd, KERNEL_QFREEZE_COUNT),
8889 &cur_col, 50);
8890 ahd_mk_message_scb_print(ahd_inw(ahd, MK_MESSAGE_SCB), &cur_col, 50);
8891 ahd_mk_message_scsiid_print(ahd_inb(ahd, MK_MESSAGE_SCSIID),
8892 &cur_col, 50);
8893 ahd_sstat0_print(ahd_inb(ahd, SSTAT0), &cur_col, 50);
8894 ahd_sstat1_print(ahd_inb(ahd, SSTAT1), &cur_col, 50);
8895 ahd_sstat2_print(ahd_inb(ahd, SSTAT2), &cur_col, 50);
8896 ahd_sstat3_print(ahd_inb(ahd, SSTAT3), &cur_col, 50);
8897 ahd_perrdiag_print(ahd_inb(ahd, PERRDIAG), &cur_col, 50);
8898 ahd_simode1_print(ahd_inb(ahd, SIMODE1), &cur_col, 50);
8899 ahd_lqistat0_print(ahd_inb(ahd, LQISTAT0), &cur_col, 50);
8900 ahd_lqistat1_print(ahd_inb(ahd, LQISTAT1), &cur_col, 50);
8901 ahd_lqistat2_print(ahd_inb(ahd, LQISTAT2), &cur_col, 50);
8902 ahd_lqostat0_print(ahd_inb(ahd, LQOSTAT0), &cur_col, 50);
8903 ahd_lqostat1_print(ahd_inb(ahd, LQOSTAT1), &cur_col, 50);
8904 ahd_lqostat2_print(ahd_inb(ahd, LQOSTAT2), &cur_col, 50);
8905 printf("\n");
8906 printf("\nSCB Count = %d CMDS_PENDING = %d LASTSCB 0x%x "
8907 "CURRSCB 0x%x NEXTSCB 0x%x\n",
8908 ahd->scb_data.numscbs, ahd_inw(ahd, CMDS_PENDING),
8909 ahd_inw(ahd, LASTSCB), ahd_inw(ahd, CURRSCB),
8910 ahd_inw(ahd, NEXTSCB));
8911 cur_col = 0;
8912
8913 ahd_search_qinfifo(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
8914 CAM_LUN_WILDCARD, SCB_LIST_NULL,
8915 ROLE_UNKNOWN, 0, SEARCH_PRINT);
8916 saved_scb_index = ahd_get_scbptr(ahd);
8917 printf("Pending list:");
8918 i = 0;
8919 LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
8920 if (i++ > AHD_SCB_MAX)
8921 break;
8922 cur_col = printf("\n%3d FIFO_USE[0x%x] ", SCB_GET_TAG(scb),
8923 ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT));
8924 ahd_set_scbptr(ahd, SCB_GET_TAG(scb));
8925 ahd_scb_control_print(ahd_inb_scbram(ahd, SCB_CONTROL),
8926 &cur_col, 60);
8927 ahd_scb_scsiid_print(ahd_inb_scbram(ahd, SCB_SCSIID),
8928 &cur_col, 60);
8929 }
8930 printf("\nTotal %d\n", i);
8931
8932 printf("Kernel Free SCB list: ");
8933 i = 0;
8934 TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
8935 struct scb *list_scb;
8936
8937 list_scb = scb;
8938 do {
8939 printf("%d ", SCB_GET_TAG(list_scb));
8940 list_scb = LIST_NEXT(list_scb, collision_links);
8941 } while (list_scb && i++ < AHD_SCB_MAX);
8942 }
8943
8944 LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) {
8945 if (i++ > AHD_SCB_MAX)
8946 break;
8947 printf("%d ", SCB_GET_TAG(scb));
8948 }
8949 printf("\n");
8950
8951 printf("Sequencer Complete DMA-inprog list: ");
8952 scb_index = ahd_inw(ahd, COMPLETE_SCB_DMAINPROG_HEAD);
8953 i = 0;
8954 while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
8955 ahd_set_scbptr(ahd, scb_index);
8956 printf("%d ", scb_index);
8957 scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
8958 }
8959 printf("\n");
8960
8961 printf("Sequencer Complete list: ");
8962 scb_index = ahd_inw(ahd, COMPLETE_SCB_HEAD);
8963 i = 0;
8964 while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
8965 ahd_set_scbptr(ahd, scb_index);
8966 printf("%d ", scb_index);
8967 scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
8968 }
8969 printf("\n");
8970
8971
8972 printf("Sequencer DMA-Up and Complete list: ");
8973 scb_index = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
8974 i = 0;
8975 while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
8976 ahd_set_scbptr(ahd, scb_index);
8977 printf("%d ", scb_index);
8978 scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
8979 }
8980 printf("\n");
8981 printf("Sequencer On QFreeze and Complete list: ");
8982 scb_index = ahd_inw(ahd, COMPLETE_ON_QFREEZE_HEAD);
8983 i = 0;
8984 while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
8985 ahd_set_scbptr(ahd, scb_index);
8986 printf("%d ", scb_index);
8987 scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
8988 }
8989 printf("\n");
8990 ahd_set_scbptr(ahd, saved_scb_index);
8991 dffstat = ahd_inb(ahd, DFFSTAT);
8992 for (i = 0; i < 2; i++) {
8993#ifdef AHD_DEBUG
8994 struct scb *fifo_scb;
8995#endif
8996 u_int fifo_scbptr;
8997
8998 ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i);
8999 fifo_scbptr = ahd_get_scbptr(ahd);
9000 printf("\n\n%s: FIFO%d %s, LONGJMP == 0x%x, SCB 0x%x\n",
9001 ahd_name(ahd), i,
9002 (dffstat & (FIFO0FREE << i)) ? "Free" : "Active",
9003 ahd_inw(ahd, LONGJMP_ADDR), fifo_scbptr);
9004 cur_col = 0;
9005 ahd_seqimode_print(ahd_inb(ahd, SEQIMODE), &cur_col, 50);
9006 ahd_seqintsrc_print(ahd_inb(ahd, SEQINTSRC), &cur_col, 50);
9007 ahd_dfcntrl_print(ahd_inb(ahd, DFCNTRL), &cur_col, 50);
9008 ahd_dfstatus_print(ahd_inb(ahd, DFSTATUS), &cur_col, 50);
9009 ahd_sg_cache_shadow_print(ahd_inb(ahd, SG_CACHE_SHADOW),
9010 &cur_col, 50);
9011 ahd_sg_state_print(ahd_inb(ahd, SG_STATE), &cur_col, 50);
9012 ahd_dffsxfrctl_print(ahd_inb(ahd, DFFSXFRCTL), &cur_col, 50);
9013 ahd_soffcnt_print(ahd_inb(ahd, SOFFCNT), &cur_col, 50);
9014 ahd_mdffstat_print(ahd_inb(ahd, MDFFSTAT), &cur_col, 50);
9015 if (cur_col > 50) {
9016 printf("\n");
9017 cur_col = 0;
9018 }
9019 cur_col += printf("SHADDR = 0x%x%x, SHCNT = 0x%x ",
9020 ahd_inl(ahd, SHADDR+4),
9021 ahd_inl(ahd, SHADDR),
9022 (ahd_inb(ahd, SHCNT)
9023 | (ahd_inb(ahd, SHCNT + 1) << 8)
9024 | (ahd_inb(ahd, SHCNT + 2) << 16)));
9025 if (cur_col > 50) {
9026 printf("\n");
9027 cur_col = 0;
9028 }
9029 cur_col += printf("HADDR = 0x%x%x, HCNT = 0x%x ",
9030 ahd_inl(ahd, HADDR+4),
9031 ahd_inl(ahd, HADDR),
9032 (ahd_inb(ahd, HCNT)
9033 | (ahd_inb(ahd, HCNT + 1) << 8)
9034 | (ahd_inb(ahd, HCNT + 2) << 16)));
9035 ahd_ccsgctl_print(ahd_inb(ahd, CCSGCTL), &cur_col, 50);
9036#ifdef AHD_DEBUG
9037 if ((ahd_debug & AHD_SHOW_SG) != 0) {
9038 fifo_scb = ahd_lookup_scb(ahd, fifo_scbptr);
9039 if (fifo_scb != NULL)
9040 ahd_dump_sglist(fifo_scb);
9041 }
9042#endif
9043 }
9044 printf("\nLQIN: ");
9045 for (i = 0; i < 20; i++)
9046 printf("0x%x ", ahd_inb(ahd, LQIN + i));
9047 printf("\n");
9048 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
9049 printf("%s: LQISTATE = 0x%x, LQOSTATE = 0x%x, OPTIONMODE = 0x%x\n",
9050 ahd_name(ahd), ahd_inb(ahd, LQISTATE), ahd_inb(ahd, LQOSTATE),
9051 ahd_inb(ahd, OPTIONMODE));
9052 printf("%s: OS_SPACE_CNT = 0x%x MAXCMDCNT = 0x%x\n",
9053 ahd_name(ahd), ahd_inb(ahd, OS_SPACE_CNT),
9054 ahd_inb(ahd, MAXCMDCNT));
9055 printf("%s: SAVED_SCSIID = 0x%x SAVED_LUN = 0x%x\n",
9056 ahd_name(ahd), ahd_inb(ahd, SAVED_SCSIID),
9057 ahd_inb(ahd, SAVED_LUN));
9058 ahd_simode0_print(ahd_inb(ahd, SIMODE0), &cur_col, 50);
9059 printf("\n");
9060 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
9061 cur_col = 0;
9062 ahd_ccscbctl_print(ahd_inb(ahd, CCSCBCTL), &cur_col, 50);
9063 printf("\n");
9064 ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
9065 printf("%s: REG0 == 0x%x, SINDEX = 0x%x, DINDEX = 0x%x\n",
9066 ahd_name(ahd), ahd_inw(ahd, REG0), ahd_inw(ahd, SINDEX),
9067 ahd_inw(ahd, DINDEX));
9068 printf("%s: SCBPTR == 0x%x, SCB_NEXT == 0x%x, SCB_NEXT2 == 0x%x\n",
9069 ahd_name(ahd), ahd_get_scbptr(ahd),
9070 ahd_inw_scbram(ahd, SCB_NEXT),
9071 ahd_inw_scbram(ahd, SCB_NEXT2));
9072 printf("CDB %x %x %x %x %x %x\n",
9073 ahd_inb_scbram(ahd, SCB_CDB_STORE),
9074 ahd_inb_scbram(ahd, SCB_CDB_STORE+1),
9075 ahd_inb_scbram(ahd, SCB_CDB_STORE+2),
9076 ahd_inb_scbram(ahd, SCB_CDB_STORE+3),
9077 ahd_inb_scbram(ahd, SCB_CDB_STORE+4),
9078 ahd_inb_scbram(ahd, SCB_CDB_STORE+5));
9079 printf("STACK:");
9080 for (i = 0; i < ahd->stack_size; i++) {
9081 ahd->saved_stack[i] =
9082 ahd_inb(ahd, STACK)|(ahd_inb(ahd, STACK) << 8);
9083 printf(" 0x%x", ahd->saved_stack[i]);
9084 }
9085 for (i = ahd->stack_size-1; i >= 0; i--) {
9086 ahd_outb(ahd, STACK, ahd->saved_stack[i] & 0xFF);
9087 ahd_outb(ahd, STACK, (ahd->saved_stack[i] >> 8) & 0xFF);
9088 }
9089 printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");
9090 ahd_restore_modes(ahd, saved_modes);
9091 if (paused == 0)
9092 ahd_unpause(ahd);
9093}
9094
9095void
9096ahd_dump_scbs(struct ahd_softc *ahd)
9097{
9098 ahd_mode_state saved_modes;
9099 u_int saved_scb_index;
9100 int i;
9101
9102 saved_modes = ahd_save_modes(ahd);
9103 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
9104 saved_scb_index = ahd_get_scbptr(ahd);
9105 for (i = 0; i < AHD_SCB_MAX; i++) {
9106 ahd_set_scbptr(ahd, i);
9107 printf("%3d", i);
9108 printf("(CTRL 0x%x ID 0x%x N 0x%x N2 0x%x SG 0x%x, RSG 0x%x)\n",
9109 ahd_inb_scbram(ahd, SCB_CONTROL),
9110 ahd_inb_scbram(ahd, SCB_SCSIID),
9111 ahd_inw_scbram(ahd, SCB_NEXT),
9112 ahd_inw_scbram(ahd, SCB_NEXT2),
9113 ahd_inl_scbram(ahd, SCB_SGPTR),
9114 ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR));
9115 }
9116 printf("\n");
9117 ahd_set_scbptr(ahd, saved_scb_index);
9118 ahd_restore_modes(ahd, saved_modes);
9119}
9120
9121
9122
9123
9124
9125
9126
9127
9128int
9129ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf,
9130 u_int start_addr, u_int count, int bytestream)
9131{
9132 u_int cur_addr;
9133 u_int end_addr;
9134 int error;
9135
9136
9137
9138
9139
9140 error = EINVAL;
9141 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
9142 end_addr = start_addr + count;
9143 for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) {
9144
9145 ahd_outb(ahd, SEEADR, cur_addr);
9146 ahd_outb(ahd, SEECTL, SEEOP_READ | SEESTART);
9147
9148 error = ahd_wait_seeprom(ahd);
9149 if (error)
9150 break;
9151 if (bytestream != 0) {
9152 uint8_t *bytestream_ptr;
9153
9154 bytestream_ptr = (uint8_t *)buf;
9155 *bytestream_ptr++ = ahd_inb(ahd, SEEDAT);
9156 *bytestream_ptr = ahd_inb(ahd, SEEDAT+1);
9157 } else {
9158
9159
9160
9161 *buf = ahd_inw(ahd, SEEDAT);
9162 }
9163 buf++;
9164 }
9165 return (error);
9166}
9167
9168
9169
9170
9171
9172
9173int
9174ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf,
9175 u_int start_addr, u_int count)
9176{
9177 u_int cur_addr;
9178 u_int end_addr;
9179 int error;
9180 int retval;
9181
9182 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
9183 error = ENOENT;
9184
9185
9186 ahd_outb(ahd, SEEADR, SEEOP_EWEN_ADDR);
9187 ahd_outb(ahd, SEECTL, SEEOP_EWEN | SEESTART);
9188 error = ahd_wait_seeprom(ahd);
9189 if (error)
9190 return (error);
9191
9192
9193
9194
9195
9196 retval = EINVAL;
9197 end_addr = start_addr + count;
9198 for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) {
9199 ahd_outw(ahd, SEEDAT, *buf++);
9200 ahd_outb(ahd, SEEADR, cur_addr);
9201 ahd_outb(ahd, SEECTL, SEEOP_WRITE | SEESTART);
9202
9203 retval = ahd_wait_seeprom(ahd);
9204 if (retval)
9205 break;
9206 }
9207
9208
9209
9210
9211 ahd_outb(ahd, SEEADR, SEEOP_EWDS_ADDR);
9212 ahd_outb(ahd, SEECTL, SEEOP_EWDS | SEESTART);
9213 error = ahd_wait_seeprom(ahd);
9214 if (error)
9215 return (error);
9216 return (retval);
9217}
9218
9219
9220
9221
9222int
9223ahd_wait_seeprom(struct ahd_softc *ahd)
9224{
9225 int cnt;
9226
9227 cnt = 5000;
9228 while ((ahd_inb(ahd, SEESTAT) & (SEEARBACK|SEEBUSY)) != 0 && --cnt)
9229 ahd_delay(5);
9230
9231 if (cnt == 0)
9232 return (ETIMEDOUT);
9233 return (0);
9234}
9235
9236
9237
9238
9239
9240int
9241ahd_verify_vpd_cksum(struct vpd_config *vpd)
9242{
9243 int i;
9244 int maxaddr;
9245 uint32_t checksum;
9246 uint8_t *vpdarray;
9247
9248 vpdarray = (uint8_t *)vpd;
9249 maxaddr = offsetof(struct vpd_config, vpd_checksum);
9250 checksum = 0;
9251 for (i = offsetof(struct vpd_config, resource_type); i < maxaddr; i++)
9252 checksum = checksum + vpdarray[i];
9253 if (checksum == 0
9254 || (-checksum & 0xFF) != vpd->vpd_checksum)
9255 return (0);
9256
9257 checksum = 0;
9258 maxaddr = offsetof(struct vpd_config, checksum);
9259 for (i = offsetof(struct vpd_config, default_target_flags);
9260 i < maxaddr; i++)
9261 checksum = checksum + vpdarray[i];
9262 if (checksum == 0
9263 || (-checksum & 0xFF) != vpd->checksum)
9264 return (0);
9265 return (1);
9266}
9267
9268int
9269ahd_verify_cksum(struct seeprom_config *sc)
9270{
9271 int i;
9272 int maxaddr;
9273 uint32_t checksum;
9274 uint16_t *scarray;
9275
9276 maxaddr = (sizeof(*sc)/2) - 1;
9277 checksum = 0;
9278 scarray = (uint16_t *)sc;
9279
9280 for (i = 0; i < maxaddr; i++)
9281 checksum = checksum + scarray[i];
9282 if (checksum == 0
9283 || (checksum & 0xFFFF) != sc->checksum) {
9284 return (0);
9285 } else {
9286 return (1);
9287 }
9288}
9289
9290int
9291ahd_acquire_seeprom(struct ahd_softc *ahd)
9292{
9293
9294
9295
9296
9297
9298
9299
9300 return (1);
9301#if 0
9302 uint8_t seetype;
9303 int error;
9304
9305 error = ahd_read_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, &seetype);
9306 if (error != 0
9307 || ((seetype & FLX_ROMSTAT_SEECFG) == FLX_ROMSTAT_SEE_NONE))
9308 return (0);
9309 return (1);
9310#endif
9311}
9312
9313void
9314ahd_release_seeprom(struct ahd_softc *ahd)
9315{
9316
9317}
9318
9319int
9320ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value)
9321{
9322 int error;
9323
9324 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
9325 if (addr > 7)
9326 panic("ahd_write_flexport: address out of range");
9327 ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3));
9328 error = ahd_wait_flexport(ahd);
9329 if (error != 0)
9330 return (error);
9331 ahd_outb(ahd, BRDDAT, value);
9332 ahd_flush_device_writes(ahd);
9333 ahd_outb(ahd, BRDCTL, BRDSTB|BRDEN|(addr << 3));
9334 ahd_flush_device_writes(ahd);
9335 ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3));
9336 ahd_flush_device_writes(ahd);
9337 ahd_outb(ahd, BRDCTL, 0);
9338 ahd_flush_device_writes(ahd);
9339 return (0);
9340}
9341
9342int
9343ahd_read_flexport(struct ahd_softc *ahd, u_int addr, uint8_t *value)
9344{
9345 int error;
9346
9347 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
9348 if (addr > 7)
9349 panic("ahd_read_flexport: address out of range");
9350 ahd_outb(ahd, BRDCTL, BRDRW|BRDEN|(addr << 3));
9351 error = ahd_wait_flexport(ahd);
9352 if (error != 0)
9353 return (error);
9354 *value = ahd_inb(ahd, BRDDAT);
9355 ahd_outb(ahd, BRDCTL, 0);
9356 ahd_flush_device_writes(ahd);
9357 return (0);
9358}
9359
9360
9361
9362
9363int
9364ahd_wait_flexport(struct ahd_softc *ahd)
9365{
9366 int cnt;
9367
9368 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
9369 cnt = 1000000 * 2 / 5;
9370 while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt)
9371 ahd_delay(5);
9372
9373 if (cnt == 0)
9374 return (ETIMEDOUT);
9375 return (0);
9376}
9377
9378
9379#ifdef AHD_TARGET_MODE
9380cam_status
9381ahd_find_tmode_devs(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb,
9382 struct ahd_tmode_tstate **tstate,
9383 struct ahd_tmode_lstate **lstate,
9384 int notfound_failure)
9385{
9386
9387 if ((ahd->features & AHD_TARGETMODE) == 0)
9388 return (CAM_REQ_INVALID);
9389
9390
9391
9392
9393
9394 if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD
9395 && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {
9396 *tstate = NULL;
9397 *lstate = ahd->black_hole;
9398 } else {
9399 u_int max_id;
9400
9401 max_id = (ahd->features & AHD_WIDE) ? 16 : 8;
9402 if (ccb->ccb_h.target_id >= max_id)
9403 return (CAM_TID_INVALID);
9404
9405 if (ccb->ccb_h.target_lun >= AHD_NUM_LUNS)
9406 return (CAM_LUN_INVALID);
9407
9408 *tstate = ahd->enabled_targets[ccb->ccb_h.target_id];
9409 *lstate = NULL;
9410 if (*tstate != NULL)
9411 *lstate =
9412 (*tstate)->enabled_luns[ccb->ccb_h.target_lun];
9413 }
9414
9415 if (notfound_failure != 0 && *lstate == NULL)
9416 return (CAM_PATH_INVALID);
9417
9418 return (CAM_REQ_CMP);
9419}
9420
9421void
9422ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
9423{
9424#if NOT_YET
9425 struct ahd_tmode_tstate *tstate;
9426 struct ahd_tmode_lstate *lstate;
9427 struct ccb_en_lun *cel;
9428 cam_status status;
9429 u_int target;
9430 u_int lun;
9431 u_int target_mask;
9432 u_long s;
9433 char channel;
9434
9435 status = ahd_find_tmode_devs(ahd, sim, ccb, &tstate, &lstate,
9436 FALSE);
9437
9438 if (status != CAM_REQ_CMP) {
9439 ccb->ccb_h.status = status;
9440 return;
9441 }
9442
9443 if ((ahd->features & AHD_MULTIROLE) != 0) {
9444 u_int our_id;
9445
9446 our_id = ahd->our_id;
9447 if (ccb->ccb_h.target_id != our_id) {
9448 if ((ahd->features & AHD_MULTI_TID) != 0
9449 && (ahd->flags & AHD_INITIATORROLE) != 0) {
9450
9451
9452
9453
9454
9455
9456
9457 status = CAM_TID_INVALID;
9458 } else if ((ahd->flags & AHD_INITIATORROLE) != 0
9459 || ahd->enabled_luns > 0) {
9460
9461
9462
9463
9464
9465
9466
9467 status = CAM_TID_INVALID;
9468 }
9469 }
9470 }
9471
9472 if (status != CAM_REQ_CMP) {
9473 ccb->ccb_h.status = status;
9474 return;
9475 }
9476
9477
9478
9479
9480
9481 if ((ahd->flags & AHD_TARGETROLE) == 0
9482 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
9483 u_long s;
9484
9485 printf("Configuring Target Mode\n");
9486 ahd_lock(ahd, &s);
9487 if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
9488 ccb->ccb_h.status = CAM_BUSY;
9489 ahd_unlock(ahd, &s);
9490 return;
9491 }
9492 ahd->flags |= AHD_TARGETROLE;
9493 if ((ahd->features & AHD_MULTIROLE) == 0)
9494 ahd->flags &= ~AHD_INITIATORROLE;
9495 ahd_pause(ahd);
9496 ahd_loadseq(ahd);
9497 ahd_restart(ahd);
9498 ahd_unlock(ahd, &s);
9499 }
9500 cel = &ccb->cel;
9501 target = ccb->ccb_h.target_id;
9502 lun = ccb->ccb_h.target_lun;
9503 channel = SIM_CHANNEL(ahd, sim);
9504 target_mask = 0x01 << target;
9505 if (channel == 'B')
9506 target_mask <<= 8;
9507
9508 if (cel->enable != 0) {
9509 u_int scsiseq1;
9510
9511
9512 if (lstate != NULL) {
9513 xpt_print_path(ccb->ccb_h.path);
9514 printf("Lun already enabled\n");
9515 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
9516 return;
9517 }
9518
9519 if (cel->grp6_len != 0
9520 || cel->grp7_len != 0) {
9521
9522
9523
9524
9525 ccb->ccb_h.status = CAM_REQ_INVALID;
9526 printf("Non-zero Group Codes\n");
9527 return;
9528 }
9529
9530
9531
9532
9533
9534 if (target != CAM_TARGET_WILDCARD && tstate == NULL) {
9535 tstate = ahd_alloc_tstate(ahd, target, channel);
9536 if (tstate == NULL) {
9537 xpt_print_path(ccb->ccb_h.path);
9538 printf("Couldn't allocate tstate\n");
9539 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
9540 return;
9541 }
9542 }
9543 lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT);
9544 if (lstate == NULL) {
9545 xpt_print_path(ccb->ccb_h.path);
9546 printf("Couldn't allocate lstate\n");
9547 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
9548 return;
9549 }
9550 memset(lstate, 0, sizeof(*lstate));
9551 status = xpt_create_path(&lstate->path, NULL,
9552 xpt_path_path_id(ccb->ccb_h.path),
9553 xpt_path_target_id(ccb->ccb_h.path),
9554 xpt_path_lun_id(ccb->ccb_h.path));
9555 if (status != CAM_REQ_CMP) {
9556 free(lstate, M_DEVBUF);
9557 xpt_print_path(ccb->ccb_h.path);
9558 printf("Couldn't allocate path\n");
9559 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
9560 return;
9561 }
9562 SLIST_INIT(&lstate->accept_tios);
9563 SLIST_INIT(&lstate->immed_notifies);
9564 ahd_lock(ahd, &s);
9565 ahd_pause(ahd);
9566 if (target != CAM_TARGET_WILDCARD) {
9567 tstate->enabled_luns[lun] = lstate;
9568 ahd->enabled_luns++;
9569
9570 if ((ahd->features & AHD_MULTI_TID) != 0) {
9571 u_int targid_mask;
9572
9573 targid_mask = ahd_inw(ahd, TARGID);
9574 targid_mask |= target_mask;
9575 ahd_outw(ahd, TARGID, targid_mask);
9576 ahd_update_scsiid(ahd, targid_mask);
9577 } else {
9578 u_int our_id;
9579 char channel;
9580
9581 channel = SIM_CHANNEL(ahd, sim);
9582 our_id = SIM_SCSI_ID(ahd, sim);
9583
9584
9585
9586
9587
9588 if (target != our_id) {
9589 u_int sblkctl;
9590 char cur_channel;
9591 int swap;
9592
9593 sblkctl = ahd_inb(ahd, SBLKCTL);
9594 cur_channel = (sblkctl & SELBUSB)
9595 ? 'B' : 'A';
9596 if ((ahd->features & AHD_TWIN) == 0)
9597 cur_channel = 'A';
9598 swap = cur_channel != channel;
9599 ahd->our_id = target;
9600
9601 if (swap)
9602 ahd_outb(ahd, SBLKCTL,
9603 sblkctl ^ SELBUSB);
9604
9605 ahd_outb(ahd, SCSIID, target);
9606
9607 if (swap)
9608 ahd_outb(ahd, SBLKCTL, sblkctl);
9609 }
9610 }
9611 } else
9612 ahd->black_hole = lstate;
9613
9614 if (ahd->black_hole != NULL && ahd->enabled_luns > 0) {
9615 scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE);
9616 scsiseq1 |= ENSELI;
9617 ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1);
9618 scsiseq1 = ahd_inb(ahd, SCSISEQ1);
9619 scsiseq1 |= ENSELI;
9620 ahd_outb(ahd, SCSISEQ1, scsiseq1);
9621 }
9622 ahd_unpause(ahd);
9623 ahd_unlock(ahd, &s);
9624 ccb->ccb_h.status = CAM_REQ_CMP;
9625 xpt_print_path(ccb->ccb_h.path);
9626 printf("Lun now enabled for target mode\n");
9627 } else {
9628 struct scb *scb;
9629 int i, empty;
9630
9631 if (lstate == NULL) {
9632 ccb->ccb_h.status = CAM_LUN_INVALID;
9633 return;
9634 }
9635
9636 ahd_lock(ahd, &s);
9637
9638 ccb->ccb_h.status = CAM_REQ_CMP;
9639 LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
9640 struct ccb_hdr *ccbh;
9641
9642 ccbh = &scb->io_ctx->ccb_h;
9643 if (ccbh->func_code == XPT_CONT_TARGET_IO
9644 && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
9645 printf("CTIO pending\n");
9646 ccb->ccb_h.status = CAM_REQ_INVALID;
9647 ahd_unlock(ahd, &s);
9648 return;
9649 }
9650 }
9651
9652 if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
9653 printf("ATIOs pending\n");
9654 ccb->ccb_h.status = CAM_REQ_INVALID;
9655 }
9656
9657 if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
9658 printf("INOTs pending\n");
9659 ccb->ccb_h.status = CAM_REQ_INVALID;
9660 }
9661
9662 if (ccb->ccb_h.status != CAM_REQ_CMP) {
9663 ahd_unlock(ahd, &s);
9664 return;
9665 }
9666
9667 xpt_print_path(ccb->ccb_h.path);
9668 printf("Target mode disabled\n");
9669 xpt_free_path(lstate->path);
9670 free(lstate, M_DEVBUF);
9671
9672 ahd_pause(ahd);
9673
9674 if (target != CAM_TARGET_WILDCARD) {
9675 tstate->enabled_luns[lun] = NULL;
9676 ahd->enabled_luns--;
9677 for (empty = 1, i = 0; i < 8; i++)
9678 if (tstate->enabled_luns[i] != NULL) {
9679 empty = 0;
9680 break;
9681 }
9682
9683 if (empty) {
9684 ahd_free_tstate(ahd, target, channel,
9685 FALSE);
9686 if (ahd->features & AHD_MULTI_TID) {
9687 u_int targid_mask;
9688
9689 targid_mask = ahd_inw(ahd, TARGID);
9690 targid_mask &= ~target_mask;
9691 ahd_outw(ahd, TARGID, targid_mask);
9692 ahd_update_scsiid(ahd, targid_mask);
9693 }
9694 }
9695 } else {
9696
9697 ahd->black_hole = NULL;
9698
9699
9700
9701
9702
9703 empty = TRUE;
9704 }
9705 if (ahd->enabled_luns == 0) {
9706
9707 u_int scsiseq1;
9708
9709 scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE);
9710 scsiseq1 &= ~ENSELI;
9711 ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1);
9712 scsiseq1 = ahd_inb(ahd, SCSISEQ1);
9713 scsiseq1 &= ~ENSELI;
9714 ahd_outb(ahd, SCSISEQ1, scsiseq1);
9715
9716 if ((ahd->features & AHD_MULTIROLE) == 0) {
9717 printf("Configuring Initiator Mode\n");
9718 ahd->flags &= ~AHD_TARGETROLE;
9719 ahd->flags |= AHD_INITIATORROLE;
9720 ahd_pause(ahd);
9721 ahd_loadseq(ahd);
9722 ahd_restart(ahd);
9723
9724
9725
9726
9727 }
9728 }
9729 ahd_unpause(ahd);
9730 ahd_unlock(ahd, &s);
9731 }
9732#endif
9733}
9734
9735static void
9736ahd_update_scsiid(struct ahd_softc *ahd, u_int targid_mask)
9737{
9738#if NOT_YET
9739 u_int scsiid_mask;
9740 u_int scsiid;
9741
9742 if ((ahd->features & AHD_MULTI_TID) == 0)
9743 panic("ahd_update_scsiid called on non-multitid unit\n");
9744
9745
9746
9747
9748
9749
9750
9751 if ((ahd->features & AHD_ULTRA2) != 0)
9752 scsiid = ahd_inb(ahd, SCSIID_ULTRA2);
9753 else
9754 scsiid = ahd_inb(ahd, SCSIID);
9755 scsiid_mask = 0x1 << (scsiid & OID);
9756 if ((targid_mask & scsiid_mask) == 0) {
9757 u_int our_id;
9758
9759
9760 our_id = ffs(targid_mask);
9761 if (our_id == 0)
9762 our_id = ahd->our_id;
9763 else
9764 our_id--;
9765 scsiid &= TID;
9766 scsiid |= our_id;
9767 }
9768 if ((ahd->features & AHD_ULTRA2) != 0)
9769 ahd_outb(ahd, SCSIID_ULTRA2, scsiid);
9770 else
9771 ahd_outb(ahd, SCSIID, scsiid);
9772#endif
9773}
9774
9775void
9776ahd_run_tqinfifo(struct ahd_softc *ahd, int paused)
9777{
9778 struct target_cmd *cmd;
9779
9780 ahd_sync_tqinfifo(ahd, BUS_DMASYNC_POSTREAD);
9781 while ((cmd = &ahd->targetcmds[ahd->tqinfifonext])->cmd_valid != 0) {
9782
9783
9784
9785
9786
9787 if (ahd_handle_target_cmd(ahd, cmd) != 0)
9788 break;
9789
9790 cmd->cmd_valid = 0;
9791 ahd_dmamap_sync(ahd, ahd->shared_data_dmat,
9792 ahd->shared_data_map.dmamap,
9793 ahd_targetcmd_offset(ahd, ahd->tqinfifonext),
9794 sizeof(struct target_cmd),
9795 BUS_DMASYNC_PREREAD);
9796 ahd->tqinfifonext++;
9797
9798
9799
9800
9801
9802 if ((ahd->tqinfifonext & (HOST_TQINPOS - 1)) == 1) {
9803 u_int hs_mailbox;
9804
9805 hs_mailbox = ahd_inb(ahd, HS_MAILBOX);
9806 hs_mailbox &= ~HOST_TQINPOS;
9807 hs_mailbox |= ahd->tqinfifonext & HOST_TQINPOS;
9808 ahd_outb(ahd, HS_MAILBOX, hs_mailbox);
9809 }
9810 }
9811}
9812
9813static int
9814ahd_handle_target_cmd(struct ahd_softc *ahd, struct target_cmd *cmd)
9815{
9816 struct ahd_tmode_tstate *tstate;
9817 struct ahd_tmode_lstate *lstate;
9818 struct ccb_accept_tio *atio;
9819 uint8_t *byte;
9820 int initiator;
9821 int target;
9822 int lun;
9823
9824 initiator = SCSIID_TARGET(ahd, cmd->scsiid);
9825 target = SCSIID_OUR_ID(cmd->scsiid);
9826 lun = (cmd->identify & MSG_IDENTIFY_LUNMASK);
9827
9828 byte = cmd->bytes;
9829 tstate = ahd->enabled_targets[target];
9830 lstate = NULL;
9831 if (tstate != NULL)
9832 lstate = tstate->enabled_luns[lun];
9833
9834
9835
9836
9837 if (lstate == NULL)
9838 lstate = ahd->black_hole;
9839
9840 atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios);
9841 if (atio == NULL) {
9842 ahd->flags |= AHD_TQINFIFO_BLOCKED;
9843
9844
9845
9846 return (1);
9847 } else
9848 ahd->flags &= ~AHD_TQINFIFO_BLOCKED;
9849#ifdef AHD_DEBUG
9850 if ((ahd_debug & AHD_SHOW_TQIN) != 0)
9851 printf("Incoming command from %d for %d:%d%s\n",
9852 initiator, target, lun,
9853 lstate == ahd->black_hole ? "(Black Holed)" : "");
9854#endif
9855 SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);
9856
9857 if (lstate == ahd->black_hole) {
9858
9859 atio->ccb_h.target_id = target;
9860 atio->ccb_h.target_lun = lun;
9861 }
9862
9863
9864
9865
9866
9867 atio->sense_len = 0;
9868 atio->init_id = initiator;
9869 if (byte[0] != 0xFF) {
9870
9871 atio->tag_action = *byte++;
9872 atio->tag_id = *byte++;
9873 atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
9874 } else {
9875 atio->ccb_h.flags = 0;
9876 }
9877 byte++;
9878
9879
9880 switch (*byte >> CMD_GROUP_CODE_SHIFT) {
9881 case 0:
9882 atio->cdb_len = 6;
9883 break;
9884 case 1:
9885 case 2:
9886 atio->cdb_len = 10;
9887 break;
9888 case 4:
9889 atio->cdb_len = 16;
9890 break;
9891 case 5:
9892 atio->cdb_len = 12;
9893 break;
9894 case 3:
9895 default:
9896
9897 atio->cdb_len = 1;
9898 printf("Reserved or VU command code type encountered\n");
9899 break;
9900 }
9901
9902 memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);
9903
9904 atio->ccb_h.status |= CAM_CDB_RECVD;
9905
9906 if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) {
9907
9908
9909
9910
9911
9912
9913#ifdef AHD_DEBUG
9914 if ((ahd_debug & AHD_SHOW_TQIN) != 0)
9915 printf("Received Immediate Command %d:%d:%d - %p\n",
9916 initiator, target, lun, ahd->pending_device);
9917#endif
9918 ahd->pending_device = lstate;
9919 ahd_freeze_ccb((union ccb *)atio);
9920 atio->ccb_h.flags |= CAM_DIS_DISCONNECT;
9921 }
9922 xpt_done((union ccb*)atio);
9923 return (0);
9924}
9925
9926#endif
9927