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