This source file includes following definitions.
- AHCMSG_1B
- AHCMSG_2B
- AHCMSG_EXT
- ahc_msgtype
- ahc_restart
- ahc_run_qoutfifo
- ahc_run_untagged_queues
- ahc_run_untagged_queue
- ahc_handle_brkadrint
- ahc_handle_seqint
- ahc_handle_scsiint
- ahc_force_renegotiation
- ahc_clear_critical_section
- ahc_clear_intstat
- ahc_print_scb
- ahc_alloc_tstate
- ahc_free_tstate
- ahc_devlimited_syncrate
- ahc_find_syncrate
- ahc_find_period
- ahc_validate_offset
- ahc_validate_width
- ahc_update_neg_request
- ahc_set_syncrate
- ahc_set_width
- ahc_set_tags
- ahc_update_pending_scbs
- ahc_fetch_devinfo
- ahc_lookup_phase_entry
- ahc_compile_devinfo
- ahc_print_devinfo
- ahc_scb_devinfo
- ahc_assert_atn
- ahc_setup_initiator_msgout
- ahc_build_transfer_msg
- ahc_construct_sdtr
- ahc_construct_wdtr
- ahc_construct_ppr
- ahc_clear_msg_state
- ahc_handle_proto_violation
- ahc_handle_message_phase
- ahc_sent_msg
- ahc_parse_msg
- ahc_handle_msg_reject
- ahc_handle_ign_wide_residue
- ahc_reinitialize_dataptrs
- ahc_handle_devreset
- ahc_setup_target_msgin
- ahc_softc_init
- ahc_softc_insert
- ahc_set_unit
- ahc_set_name
- ahc_free
- ahc_shutdown
- ahc_reset
- ahc_probe_scbs
- ahc_dmamap_cb
- ahc_build_free_scb_list
- ahc_init_scbdata
- ahc_fini_scbdata
- ahc_alloc_scbs
- ahc_controller_info
- ahc_chip_init
- ahc_init
- ahc_intr_enable
- ahc_index_busy_tcl
- ahc_unbusy_tcl
- ahc_busy_tcl
- ahc_match_scb
- ahc_freeze_devq
- ahc_qinfifo_requeue_tail
- ahc_qinfifo_requeue
- ahc_qinfifo_count
- ahc_search_qinfifo
- ahc_search_untagged_queues
- ahc_search_disc_list
- ahc_rem_scb_from_disc_list
- ahc_add_curscb_to_free_list
- ahc_rem_wscb
- ahc_abort_scbs
- ahc_reset_current_bus
- ahc_reset_channel
- ahc_calc_residual
- ahc_queue_lstate_event
- ahc_send_lstate_events
- ahc_dumpseq
- ahc_loadseq
- ahc_check_patch
- ahc_download_instr
- ahc_print_register
- ahc_dump_card_state
- ahc_find_tmode_devs
- ahc_handle_en_lun
- ahc_update_scsiid
- ahc_run_tqinfifo
- ahc_handle_target_cmd
- ahc_createdmamem
- ahc_freedmamem
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
46
47
48
49 #include <sys/cdefs.h>
50
51
52 #include <dev/ic/aic7xxx_openbsd.h>
53 #ifdef SMALL_KERNEL
54 #define IO_EXPAND
55 #endif
56 #include <dev/ic/aic7xxx_inline.h>
57 #include <dev/microcode/aic7xxx/aicasm_insformat.h>
58
59
60 struct ahc_softc_tailq ahc_tailq = TAILQ_HEAD_INITIALIZER(ahc_tailq);
61
62
63 char *ahc_chip_names[] =
64 {
65 "NONE",
66 "aic7770",
67 "aic7850",
68 "aic7855",
69 "aic7859",
70 "aic7860",
71 "aic7870",
72 "aic7880",
73 "aic7895",
74 "aic7895C",
75 "aic7890/91",
76 "aic7896/97",
77 "aic7892",
78 "aic7899"
79 };
80
81
82
83
84 struct ahc_hard_error_entry {
85 uint8_t errno;
86 char *errmesg;
87 };
88
89 #if !defined(SMALL_KERNEL)
90 static struct ahc_hard_error_entry ahc_hard_errors[] = {
91 { ILLHADDR, "Illegal Host Access" },
92 { ILLSADDR, "Illegal Sequencer Address referrenced" },
93 { ILLOPCODE, "Illegal Opcode in sequencer program" },
94 { SQPARERR, "Sequencer Parity Error" },
95 { DPARERR, "Data-path Parity Error" },
96 { MPARERR, "Scratch or SCB Memory Parity Error" },
97 { PCIERRSTAT, "PCI Error detected" },
98 { CIOPARERR, "CIOBUS Parity Error" },
99 };
100 static const u_int num_errors = NUM_ELEMENTS(ahc_hard_errors);
101 #endif
102
103 static struct ahc_phase_table_entry ahc_phase_table[] =
104 {
105 { P_DATAOUT, MSG_NOOP, "in Data-out phase" },
106 { P_DATAIN, MSG_INITIATOR_DET_ERR, "in Data-in phase" },
107 { P_DATAOUT_DT, MSG_NOOP, "in DT Data-out phase" },
108 { P_DATAIN_DT, MSG_INITIATOR_DET_ERR, "in DT Data-in phase" },
109 { P_COMMAND, MSG_NOOP, "in Command phase" },
110 { P_MESGOUT, MSG_NOOP, "in Message-out phase" },
111 { P_STATUS, MSG_INITIATOR_DET_ERR, "in Status phase" },
112 { P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" },
113 { P_BUSFREE, MSG_NOOP, "while idle" },
114 { 0, MSG_NOOP, "in unknown phase" }
115 };
116
117
118
119
120
121 static const u_int num_phases = NUM_ELEMENTS(ahc_phase_table) - 1;
122
123
124
125
126
127
128 static struct ahc_syncrate ahc_syncrates[] =
129 {
130
131 { 0x42, 0x000, 9, "80.0" },
132 { 0x03, 0x000, 10, "40.0" },
133 { 0x04, 0x000, 11, "33.0" },
134 { 0x05, 0x100, 12, "20.0" },
135 { 0x06, 0x110, 15, "16.0" },
136 { 0x07, 0x120, 18, "13.4" },
137 { 0x08, 0x000, 25, "10.0" },
138 { 0x19, 0x010, 31, "8.0" },
139 { 0x1a, 0x020, 37, "6.67" },
140 { 0x1b, 0x030, 43, "5.7" },
141 { 0x1c, 0x040, 50, "5.0" },
142 { 0x00, 0x050, 56, "4.4" },
143 { 0x00, 0x060, 62, "4.0" },
144 { 0x00, 0x070, 68, "3.6" },
145 { 0x00, 0x000, 0, NULL }
146 };
147
148
149 #include <dev/microcode/aic7xxx/aic7xxx_seq.h>
150
151
152 static void ahc_force_renegotiation(struct ahc_softc *ahc,
153 struct ahc_devinfo *devinfo);
154 static struct ahc_tmode_tstate*
155 ahc_alloc_tstate(struct ahc_softc *ahc,
156 u_int scsi_id, char channel);
157 #ifdef AHC_TARGET_MODE
158 static void ahc_free_tstate(struct ahc_softc *ahc,
159 u_int scsi_id, char channel, int force);
160 #endif
161 static struct ahc_syncrate*
162 ahc_devlimited_syncrate(struct ahc_softc *ahc,
163 struct ahc_initiator_tinfo *,
164 u_int *period,
165 u_int *ppr_options,
166 role_t role);
167 static void ahc_update_pending_scbs(struct ahc_softc *ahc);
168 static void ahc_fetch_devinfo(struct ahc_softc *ahc,
169 struct ahc_devinfo *devinfo);
170 static void ahc_assert_atn(struct ahc_softc *ahc);
171 static void ahc_setup_initiator_msgout(struct ahc_softc *ahc,
172 struct ahc_devinfo *devinfo,
173 struct scb *scb);
174 static void ahc_build_transfer_msg(struct ahc_softc *ahc,
175 struct ahc_devinfo *devinfo);
176 static void ahc_construct_sdtr(struct ahc_softc *ahc,
177 struct ahc_devinfo *devinfo,
178 u_int period, u_int offset);
179 static void ahc_construct_wdtr(struct ahc_softc *ahc,
180 struct ahc_devinfo *devinfo,
181 u_int bus_width);
182 static void ahc_construct_ppr(struct ahc_softc *ahc,
183 struct ahc_devinfo *devinfo,
184 u_int period, u_int offset,
185 u_int bus_width, u_int ppr_options);
186 static void ahc_clear_msg_state(struct ahc_softc *ahc);
187 static void ahc_handle_proto_violation(struct ahc_softc *ahc);
188 static void ahc_handle_message_phase(struct ahc_softc *ahc);
189 typedef enum {
190 AHCMSG_1B,
191 AHCMSG_2B,
192 AHCMSG_EXT
193 } ahc_msgtype;
194 static int ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type,
195 u_int msgval, int full);
196 static int ahc_parse_msg(struct ahc_softc *ahc,
197 struct ahc_devinfo *devinfo);
198 static int ahc_handle_msg_reject(struct ahc_softc *ahc,
199 struct ahc_devinfo *devinfo);
200 static void ahc_handle_ign_wide_residue(struct ahc_softc *ahc,
201 struct ahc_devinfo *devinfo);
202 static void ahc_reinitialize_dataptrs(struct ahc_softc *ahc);
203 static void ahc_handle_devreset(struct ahc_softc *ahc,
204 struct ahc_devinfo *devinfo,
205 cam_status status, char *message,
206 int verbose_level);
207 #ifdef AHC_TARGET_MODE
208 static void ahc_setup_target_msgin(struct ahc_softc *ahc,
209 struct ahc_devinfo *devinfo,
210 struct scb *scb);
211 #endif
212
213
214 static void ahc_build_free_scb_list(struct ahc_softc *ahc);
215 static int ahc_init_scbdata(struct ahc_softc *ahc);
216 static void ahc_fini_scbdata(struct ahc_softc *ahc);
217 static void ahc_qinfifo_requeue(struct ahc_softc *ahc,
218 struct scb *prev_scb,
219 struct scb *scb);
220 static int ahc_qinfifo_count(struct ahc_softc *ahc);
221 static u_int ahc_rem_scb_from_disc_list(struct ahc_softc *ahc,
222 u_int prev, u_int scbptr);
223 static void ahc_add_curscb_to_free_list(struct ahc_softc *ahc);
224 static u_int ahc_rem_wscb(struct ahc_softc *ahc,
225 u_int scbpos, u_int prev);
226 static void ahc_reset_current_bus(struct ahc_softc *ahc);
227 #ifdef AHC_DUMP_SEQ
228 static void ahc_dumpseq(struct ahc_softc *ahc);
229 #endif
230 static int ahc_loadseq(struct ahc_softc *ahc);
231 static int ahc_check_patch(struct ahc_softc *ahc,
232 const struct patch **start_patch,
233 u_int start_instr, u_int *skip_addr);
234 static void ahc_download_instr(struct ahc_softc *ahc,
235 u_int instrptr, uint8_t *dconsts);
236 #ifdef AHC_TARGET_MODE
237 static void ahc_queue_lstate_event(struct ahc_softc *ahc,
238 struct ahc_tmode_lstate *lstate,
239 u_int initiator_id,
240 u_int event_type,
241 u_int event_arg);
242 static void ahc_update_scsiid(struct ahc_softc *ahc,
243 u_int targid_mask);
244 static int ahc_handle_target_cmd(struct ahc_softc *ahc,
245 struct target_cmd *cmd);
246 #endif
247
248
249 static int ahc_createdmamem(bus_dma_tag_t tag,
250 int size,
251 int flags,
252 bus_dmamap_t *mapp,
253 caddr_t *vaddr,
254 bus_addr_t *baddr,
255 bus_dma_segment_t *seg,
256 int *nseg,
257 const char *myname, const char *what);
258 static void ahc_freedmamem(bus_dma_tag_t tag,
259 int size,
260 bus_dmamap_t map,
261 caddr_t vaddr,
262 bus_dma_segment_t *seg,
263 int nseg);
264
265
266
267
268
269 void
270 ahc_restart(struct ahc_softc *ahc)
271 {
272
273 ahc_pause(ahc);
274
275
276 ahc_clear_msg_state(ahc);
277
278 ahc_outb(ahc, SCSISIGO, 0);
279 ahc_outb(ahc, MSG_OUT, MSG_NOOP);
280 ahc_outb(ahc, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
281 ahc_outb(ahc, LASTPHASE, P_BUSFREE);
282 ahc_outb(ahc, SAVED_SCSIID, 0xFF);
283 ahc_outb(ahc, SAVED_LUN, 0xFF);
284
285
286
287
288
289
290
291
292 ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
293
294
295 ahc_outb(ahc, SCSISEQ,
296 ahc_inb(ahc, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
297 if ((ahc->features & AHC_CMD_CHAN) != 0) {
298
299 ahc_outb(ahc, CCSCBCNT, 0);
300 ahc_outb(ahc, CCSGCTL, 0);
301 ahc_outb(ahc, CCSCBCTL, 0);
302 }
303
304
305
306
307
308 if ((ahc_inb(ahc, SEQ_FLAGS2) & SCB_DMA) != 0) {
309 ahc_add_curscb_to_free_list(ahc);
310 ahc_outb(ahc, SEQ_FLAGS2,
311 ahc_inb(ahc, SEQ_FLAGS2) & ~SCB_DMA);
312 }
313
314
315
316
317
318
319 ahc_outb(ahc, CLRINT, CLRSEQINT);
320
321 ahc_outb(ahc, MWI_RESIDUAL, 0);
322 ahc_outb(ahc, SEQCTL, ahc->seqctl);
323 ahc_outb(ahc, SEQADDR0, 0);
324 ahc_outb(ahc, SEQADDR1, 0);
325
326 ahc_unpause(ahc);
327 }
328
329
330 void
331 ahc_run_qoutfifo(struct ahc_softc *ahc)
332 {
333 struct scb *scb;
334 u_int scb_index;
335
336 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
337 while (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL) {
338
339 scb_index = ahc->qoutfifo[ahc->qoutfifonext];
340 #ifdef __sgi__
341 if ((ahc->qoutfifonext & 0x1f) == 0x1f) {
342 u_int modnext;
343 u_int32_t *nextp;
344
345
346
347
348
349
350
351 modnext = ahc->qoutfifonext & ~0x1f;
352 nextp = (uint32_t *)(&ahc->qoutfifo[modnext]);
353 *nextp++ = 0xFFFFFFFFUL;
354 *nextp++ = 0xFFFFFFFFUL;
355 *nextp++ = 0xFFFFFFFFUL;
356 *nextp++ = 0xFFFFFFFFUL;
357 *nextp++ = 0xFFFFFFFFUL;
358 *nextp++ = 0xFFFFFFFFUL;
359 *nextp++ = 0xFFFFFFFFUL;
360 *nextp++ = 0xFFFFFFFFUL;
361 ahc_dmamap_sync(ahc, ahc->parent_dmat ,
362 ahc->shared_data_dmamap,
363 modnext, 32,
364 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
365 }
366 #else
367 if ((ahc->qoutfifonext & 0x03) == 0x03) {
368 u_int modnext;
369
370
371
372
373
374
375
376
377 modnext = ahc->qoutfifonext & ~0x3;
378 *((uint32_t *)(&ahc->qoutfifo[modnext])) = 0xFFFFFFFFUL;
379 ahc_dmamap_sync(ahc, ahc->parent_dmat ,
380 ahc->shared_data_dmamap,
381 modnext, 4,
382 BUS_DMASYNC_PREREAD);
383 }
384 #endif
385 ahc->qoutfifonext++;
386
387 scb = ahc_lookup_scb(ahc, scb_index);
388 if (scb == NULL) {
389 printf("%s: WARNING no command for scb %d "
390 "(cmdcmplt)\nQOUTPOS = %d\n",
391 ahc_name(ahc), scb_index,
392 (ahc->qoutfifonext - 1) & 0xFF);
393 continue;
394 }
395
396
397
398
399
400 ahc_update_residual(ahc, scb);
401 ahc_done(ahc, scb);
402 }
403 }
404
405 void
406 ahc_run_untagged_queues(struct ahc_softc *ahc)
407 {
408 int i;
409
410 for (i = 0; i < 16; i++)
411 ahc_run_untagged_queue(ahc, &ahc->untagged_queues[i]);
412 }
413
414 void
415 ahc_run_untagged_queue(struct ahc_softc *ahc, struct scb_tailq *queue)
416 {
417 struct scb *scb;
418
419 if (ahc->untagged_queue_lock != 0)
420 return;
421
422 if ((scb = TAILQ_FIRST(queue)) != NULL
423 && (scb->flags & SCB_ACTIVE) == 0) {
424 scb->flags |= SCB_ACTIVE;
425 ahc_queue_scb(ahc, scb);
426 }
427 }
428
429
430 void
431 ahc_handle_brkadrint(struct ahc_softc *ahc)
432 {
433
434
435
436
437 #ifndef SMALL_KERNEL
438 int i;
439 int error;
440
441 error = ahc_inb(ahc, ERROR);
442 for (i = 0; error != 1 && i < num_errors; i++)
443 error >>= 1;
444 printf("%s: brkadrint, %s at seqaddr = 0x%x\n",
445 ahc_name(ahc), ahc_hard_errors[i].errmesg,
446 ahc_inb(ahc, SEQADDR0) |
447 (ahc_inb(ahc, SEQADDR1) << 8));
448
449 ahc_dump_card_state(ahc);
450 #endif
451
452
453 ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS,
454 CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
455 CAM_NO_HBA);
456
457
458 ahc_shutdown(ahc);
459 }
460
461 void
462 ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
463 {
464 struct scb *scb;
465 struct ahc_devinfo devinfo;
466
467 ahc_fetch_devinfo(ahc, &devinfo);
468
469
470
471
472
473
474
475 ahc_outb(ahc, CLRINT, CLRSEQINT);
476 switch (intstat & SEQINT_MASK) {
477 case BAD_STATUS:
478 {
479 u_int scb_index;
480 struct hardware_scb *hscb;
481
482
483
484
485
486
487 ahc_outb(ahc, RETURN_1, 0);
488
489
490
491
492
493
494
495
496
497
498 scb_index = ahc_inb(ahc, SCB_TAG);
499 scb = ahc_lookup_scb(ahc, scb_index);
500 if (scb == NULL) {
501 ahc_print_devinfo(ahc, &devinfo);
502 printf("ahc_intr - referenced scb "
503 "not valid during seqint 0x%x scb(%d)\n",
504 intstat, scb_index);
505 ahc_dump_card_state(ahc);
506 panic("for safety");
507 goto unpause;
508 }
509
510 hscb = scb->hscb;
511
512
513 if ((scb->flags & SCB_SENSE) != 0) {
514
515
516
517
518
519 scb->flags &= ~SCB_SENSE;
520 ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
521 break;
522 }
523 ahc_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR);
524
525 ahc_freeze_devq(ahc, scb);
526 ahc_freeze_scb(scb);
527 ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status);
528 switch (hscb->shared_data.status.scsi_status) {
529 case SCSI_STATUS_OK:
530 printf("%s: Interrupted for status of 0 (?)\n",
531 ahc_name(ahc));
532 break;
533 case SCSI_STATUS_CMD_TERMINATED:
534 case SCSI_STATUS_CHECK_COND:
535 {
536 struct ahc_dma_seg *sg;
537 struct scsi_sense *sc;
538 struct ahc_initiator_tinfo *targ_info;
539 struct ahc_tmode_tstate *tstate;
540 struct ahc_transinfo *tinfo;
541 #ifdef AHC_DEBUG
542 if (ahc_debug & AHC_SHOW_SENSE) {
543 ahc_print_path(ahc, scb);
544 printf("SCB %d: requests Check Status\n",
545 scb->hscb->tag);
546 }
547 #endif
548
549 if (ahc_perform_autosense(scb) == 0)
550 break;
551
552 targ_info = ahc_fetch_transinfo(ahc,
553 devinfo.channel,
554 devinfo.our_scsiid,
555 devinfo.target,
556 &tstate);
557 tinfo = &targ_info->curr;
558 sg = scb->sg_list;
559 sc = (struct scsi_sense *)(&hscb->shared_data.cdb);
560
561
562
563 ahc_update_residual(ahc, scb);
564 #ifdef AHC_DEBUG
565 if (ahc_debug & AHC_SHOW_SENSE) {
566 ahc_print_path(ahc, scb);
567 printf("Sending Sense\n");
568 }
569 #endif
570 sg->addr = ahc_get_sense_bufaddr(ahc, scb);
571 sg->len = ahc_get_sense_bufsize(ahc, scb);
572 sg->len |= AHC_DMA_LAST_SEG;
573
574
575 sg->addr = aic_htole32(sg->addr);
576 sg->len = aic_htole32(sg->len);
577
578 sc->opcode = REQUEST_SENSE;
579 sc->byte2 = 0;
580 if (tinfo->protocol_version <= SCSI_REV_2
581 && SCB_GET_LUN(scb) < 8)
582 sc->byte2 = SCB_GET_LUN(scb) << 5;
583 sc->unused[0] = 0;
584 sc->unused[1] = 0;
585 sc->length = sg->len;
586 sc->control = 0;
587
588
589
590
591
592
593
594
595 hscb->control = 0;
596
597
598
599
600
601
602
603
604
605 if (ahc_get_residual(scb)
606 == ahc_get_transfer_length(scb)) {
607 ahc_update_neg_request(ahc, &devinfo,
608 tstate, targ_info,
609 AHC_NEG_IF_NON_ASYNC);
610 }
611 if (tstate->auto_negotiate & devinfo.target_mask) {
612 hscb->control |= MK_MESSAGE;
613 scb->flags &= ~SCB_NEGOTIATE;
614 scb->flags |= SCB_AUTO_NEGOTIATE;
615 }
616 hscb->cdb_len = sizeof(*sc);
617 hscb->dataptr = sg->addr;
618 hscb->datacnt = sg->len;
619 hscb->sgptr = scb->sg_list_phys | SG_FULL_RESID;
620 hscb->sgptr = aic_htole32(hscb->sgptr);
621 #ifdef __OpenBSD__
622 bus_dmamap_sync(ahc->parent_dmat,
623 ahc->scb_data->sense_dmamap,
624 (scb - ahc->scb_data->scbarray) *
625 sizeof(struct scsi_sense_data),
626 sizeof(struct scsi_sense_data),
627 BUS_DMASYNC_PREREAD);
628 bus_dmamap_sync(ahc->parent_dmat,
629 scb->sg_map->sg_dmamap,
630 0, scb->sg_map->sg_dmamap->dm_mapsize,
631 BUS_DMASYNC_PREWRITE);
632 bus_dmamap_sync(ahc->parent_dmat,
633 ahc->scb_data->hscb_dmamap,
634 0, ahc->scb_data->hscb_dmamap->dm_mapsize,
635 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
636 #endif
637 scb->sg_count = 1;
638 scb->flags |= SCB_SENSE;
639 ahc_qinfifo_requeue_tail(ahc, scb);
640 ahc_outb(ahc, RETURN_1, SEND_SENSE);
641
642
643
644
645 ahc_scb_timer_reset(scb, 5 * 1000000);
646 break;
647 }
648 default:
649 break;
650 }
651 break;
652 }
653 case NO_MATCH:
654 {
655
656 ahc_outb(ahc, SCSISEQ,
657 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
658
659 printf("%s:%c:%d: no active SCB for reconnecting "
660 "target - issuing BUS DEVICE RESET\n",
661 ahc_name(ahc), devinfo.channel, devinfo.target);
662 printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
663 "ARG_1 == 0x%x ACCUM = 0x%x\n",
664 ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
665 ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
666 printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
667 "SINDEX == 0x%x\n",
668 ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
669 ahc_index_busy_tcl(ahc,
670 BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
671 ahc_inb(ahc, SAVED_LUN))),
672 ahc_inb(ahc, SINDEX));
673 printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
674 "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
675 ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
676 ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
677 ahc_inb(ahc, SCB_CONTROL));
678 printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
679 ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
680 printf("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0));
681 printf("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL));
682 ahc_dump_card_state(ahc);
683 ahc->msgout_buf[0] = MSG_BUS_DEV_RESET;
684 ahc->msgout_len = 1;
685 ahc->msgout_index = 0;
686 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
687 ahc_outb(ahc, MSG_OUT, HOST_MSG);
688 ahc_assert_atn(ahc);
689 break;
690 }
691 case SEND_REJECT:
692 {
693 u_int rejbyte = ahc_inb(ahc, ACCUM);
694 printf("%s:%c:%d: Warning - unknown message received from "
695 "target (0x%x). Rejecting\n",
696 ahc_name(ahc), devinfo.channel, devinfo.target, rejbyte);
697 break;
698 }
699 case PROTO_VIOLATION:
700 {
701 ahc_handle_proto_violation(ahc);
702 break;
703 }
704 case IGN_WIDE_RES:
705 ahc_handle_ign_wide_residue(ahc, &devinfo);
706 break;
707 case PDATA_REINIT:
708 ahc_reinitialize_dataptrs(ahc);
709 break;
710 case BAD_PHASE:
711 {
712 u_int lastphase;
713
714 lastphase = ahc_inb(ahc, LASTPHASE);
715 printf("%s:%c:%d: unknown scsi bus phase %x, "
716 "lastphase = 0x%x. Attempting to continue\n",
717 ahc_name(ahc), devinfo.channel, devinfo.target,
718 lastphase, ahc_inb(ahc, SCSISIGI));
719 break;
720 }
721 case MISSED_BUSFREE:
722 {
723 u_int lastphase;
724
725 lastphase = ahc_inb(ahc, LASTPHASE);
726 printf("%s:%c:%d: Missed busfree. "
727 "Lastphase = 0x%x, Curphase = 0x%x\n",
728 ahc_name(ahc), devinfo.channel, devinfo.target,
729 lastphase, ahc_inb(ahc, SCSISIGI));
730 ahc_restart(ahc);
731 return;
732 }
733 case HOST_MSG_LOOP:
734 {
735
736
737
738
739
740
741
742
743
744
745
746 if (ahc->msg_type == MSG_TYPE_NONE) {
747 struct scb *scb;
748 u_int scb_index;
749 u_int bus_phase;
750
751 bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
752 if (bus_phase != P_MESGIN
753 && bus_phase != P_MESGOUT) {
754 printf("ahc_intr: HOST_MSG_LOOP bad "
755 "phase 0x%x\n",
756 bus_phase);
757
758
759
760
761 ahc_clear_intstat(ahc);
762 ahc_restart(ahc);
763 return;
764 }
765
766 scb_index = ahc_inb(ahc, SCB_TAG);
767 scb = ahc_lookup_scb(ahc, scb_index);
768 if (devinfo.role == ROLE_INITIATOR) {
769 if (scb == NULL)
770 panic("HOST_MSG_LOOP with "
771 "invalid SCB %x\n", scb_index);
772
773 if (bus_phase == P_MESGOUT)
774 ahc_setup_initiator_msgout(ahc,
775 &devinfo,
776 scb);
777 else {
778 ahc->msg_type =
779 MSG_TYPE_INITIATOR_MSGIN;
780 ahc->msgin_index = 0;
781 }
782 }
783 #ifdef AHC_TARGET_MODE
784 else {
785 if (bus_phase == P_MESGOUT) {
786 ahc->msg_type =
787 MSG_TYPE_TARGET_MSGOUT;
788 ahc->msgin_index = 0;
789 }
790 else
791 ahc_setup_target_msgin(ahc,
792 &devinfo,
793 scb);
794 }
795 #endif
796 }
797
798 ahc_handle_message_phase(ahc);
799 break;
800 }
801 case PERR_DETECTED:
802 {
803
804
805
806
807
808
809
810
811
812
813
814 if ((intstat & SCSIINT) == 0
815 && (ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0) {
816
817 if ((ahc->features & AHC_DT) == 0) {
818 u_int curphase;
819
820
821
822
823
824
825
826 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
827 ahc_outb(ahc, LASTPHASE, curphase);
828 ahc_outb(ahc, SCSISIGO, curphase);
829 }
830 if ((ahc_inb(ahc, SCSISIGI) & (CDI|MSGI)) == 0) {
831 int wait;
832
833
834
835
836
837
838
839 ahc_outb(ahc, SXFRCTL1,
840 ahc_inb(ahc, SXFRCTL1) | BITBUCKET);
841 wait = 5000;
842 while (--wait != 0) {
843 if ((ahc_inb(ahc, SCSISIGI)
844 & (CDI|MSGI)) != 0)
845 break;
846 aic_delay(100);
847 }
848 ahc_outb(ahc, SXFRCTL1,
849 ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
850 if (wait == 0) {
851 struct scb *scb;
852 u_int scb_index;
853
854 ahc_print_devinfo(ahc, &devinfo);
855 printf("Unable to clear parity error. "
856 "Resetting bus.\n");
857 scb_index = ahc_inb(ahc, SCB_TAG);
858 scb = ahc_lookup_scb(ahc, scb_index);
859 if (scb != NULL)
860 ahc_set_transaction_status(scb,
861 CAM_UNCOR_PARITY);
862 ahc_reset_channel(ahc, devinfo.channel,
863 TRUE);
864 }
865 } else {
866 ahc_inb(ahc, SCSIDATL);
867 }
868 }
869 break;
870 }
871 case DATA_OVERRUN:
872 {
873
874
875
876
877
878
879
880
881 u_int scbindex = ahc_inb(ahc, SCB_TAG);
882 u_int lastphase = ahc_inb(ahc, LASTPHASE);
883 u_int i;
884
885 scb = ahc_lookup_scb(ahc, scbindex);
886 for (i = 0; i < num_phases; i++) {
887 if (lastphase == ahc_phase_table[i].phase)
888 break;
889 }
890 ahc_print_path(ahc, scb);
891 printf("data overrun detected %s."
892 " Tag == 0x%x.\n",
893 ahc_phase_table[i].phasemsg,
894 scb->hscb->tag);
895 #ifndef SMALL_KERNEL
896 ahc_print_path(ahc, scb);
897 printf("%s seen Data Phase. Length = %ld. NumSGs = %d.\n",
898 ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",
899 ahc_get_transfer_length(scb), scb->sg_count);
900 if (scb->sg_count > 0) {
901 for (i = 0; i < scb->sg_count; i++) {
902
903 printf("sg[%d] - Addr 0x%x%x : Length %d\n",
904 i,
905 (aic_le32toh(scb->sg_list[i].len) >> 24
906 & SG_HIGH_ADDR_BITS),
907 aic_le32toh(scb->sg_list[i].addr),
908 aic_le32toh(scb->sg_list[i].len)
909 & AHC_SG_LEN_MASK);
910 }
911 }
912 #endif
913
914
915
916
917 ahc_freeze_devq(ahc, scb);
918 if ((scb->flags & SCB_SENSE) == 0) {
919 ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
920 } else {
921 scb->flags &= ~SCB_SENSE;
922 ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
923 }
924 ahc_freeze_scb(scb);
925
926 if ((ahc->features & AHC_ULTRA2) != 0) {
927
928
929
930
931 ahc_outb(ahc, SXFRCTL0,
932 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);
933 ahc_outb(ahc, SXFRCTL0,
934 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);
935 }
936 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
937 u_int dscommand1;
938
939
940 dscommand1 = ahc_inb(ahc, DSCOMMAND1);
941 ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
942 ahc_outb(ahc, HADDR, 0);
943 ahc_outb(ahc, DSCOMMAND1, dscommand1);
944 }
945 break;
946 }
947 case MKMSG_FAILED:
948 {
949 u_int scbindex;
950
951 printf("%s:%c:%d:%d: Attempt to issue message failed\n",
952 ahc_name(ahc), devinfo.channel, devinfo.target,
953 devinfo.lun);
954 scbindex = ahc_inb(ahc, SCB_TAG);
955 scb = ahc_lookup_scb(ahc, scbindex);
956 if (scb != NULL)
957
958
959
960
961 ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
962 SCB_GET_CHANNEL(ahc, scb),
963 SCB_GET_LUN(scb), scb->hscb->tag,
964 ROLE_INITIATOR, 0,
965 SEARCH_REMOVE);
966 break;
967 }
968 case NO_FREE_SCB:
969 {
970 printf("%s: No free or disconnected SCBs\n", ahc_name(ahc));
971 ahc_dump_card_state(ahc);
972 panic("for safety");
973 break;
974 }
975 case SCB_MISMATCH:
976 {
977 u_int scbptr;
978
979 scbptr = ahc_inb(ahc, SCBPTR);
980 printf("Bogus TAG after DMA. SCBPTR %d, tag %d, our tag %d\n",
981 scbptr, ahc_inb(ahc, ARG_1),
982 ahc->scb_data->hscbs[scbptr].tag);
983 ahc_dump_card_state(ahc);
984 panic("for safety");
985 break;
986 }
987 case OUT_OF_RANGE:
988 {
989 #ifndef SMALL_KERNEL
990 printf("%s: BTT calculation out of range\n", ahc_name(ahc));
991 printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
992 "ARG_1 == 0x%x ACCUM = 0x%x\n",
993 ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
994 ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
995 printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
996 "SINDEX == 0x%x\n, A == 0x%x\n",
997 ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
998 ahc_index_busy_tcl(ahc,
999 BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
1000 ahc_inb(ahc, SAVED_LUN))),
1001 ahc_inb(ahc, SINDEX),
1002 ahc_inb(ahc, ACCUM));
1003 printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
1004 "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
1005 ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
1006 ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
1007 ahc_inb(ahc, SCB_CONTROL));
1008 printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
1009 ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
1010 #endif
1011 ahc_dump_card_state(ahc);
1012 panic("for safety");
1013 break;
1014 }
1015 default:
1016 printf("ahc_intr: seqint, "
1017 "intstat == 0x%x, scsisigi = 0x%x\n",
1018 intstat, ahc_inb(ahc, SCSISIGI));
1019 break;
1020 }
1021 unpause:
1022
1023
1024
1025
1026
1027 ahc_unpause(ahc);
1028 }
1029
1030 void
1031 ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
1032 {
1033 u_int scb_index;
1034 u_int status0;
1035 u_int status;
1036 struct scb *scb;
1037 char cur_channel;
1038 char intr_channel;
1039
1040 if ((ahc->features & AHC_TWIN) != 0
1041 && ((ahc_inb(ahc, SBLKCTL) & SELBUSB) != 0))
1042 cur_channel = 'B';
1043 else
1044 cur_channel = 'A';
1045 intr_channel = cur_channel;
1046
1047 if ((ahc->features & AHC_ULTRA2) != 0)
1048 status0 = ahc_inb(ahc, SSTAT0) & IOERR;
1049 else
1050 status0 = 0;
1051 status = ahc_inb(ahc, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
1052 if (status == 0 && status0 == 0) {
1053 if ((ahc->features & AHC_TWIN) != 0) {
1054
1055 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
1056 status = ahc_inb(ahc, SSTAT1)
1057 & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
1058 intr_channel = (cur_channel == 'A') ? 'B' : 'A';
1059 }
1060 if (status == 0) {
1061 printf("%s: Spurious SCSI interrupt\n", ahc_name(ahc));
1062 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1063 ahc_unpause(ahc);
1064 return;
1065 }
1066 }
1067
1068
1069 ahc_clear_critical_section(ahc);
1070
1071 scb_index = ahc_inb(ahc, SCB_TAG);
1072 scb = ahc_lookup_scb(ahc, scb_index);
1073 if (scb != NULL
1074 && (ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
1075 scb = NULL;
1076
1077 if ((ahc->features & AHC_ULTRA2) != 0
1078 && (status0 & IOERR) != 0) {
1079 int now_lvd;
1080
1081 now_lvd = ahc_inb(ahc, SBLKCTL) & ENAB40;
1082 printf("%s: Transceiver State Has Changed to %s mode\n",
1083 ahc_name(ahc), now_lvd ? "LVD" : "SE");
1084 ahc_outb(ahc, CLRSINT0, CLRIOERR);
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095 ahc_reset_channel(ahc, intr_channel,
1096 now_lvd == 0);
1097 } else if ((status & SCSIRSTI) != 0) {
1098 printf("%s: Someone reset channel %c\n",
1099 ahc_name(ahc), intr_channel);
1100 if (intr_channel != cur_channel)
1101 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
1102 ahc_reset_channel(ahc, intr_channel, FALSE);
1103 } else if ((status & SCSIPERR) != 0) {
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114 struct ahc_devinfo devinfo;
1115 u_int mesg_out;
1116 u_int curphase;
1117 u_int errorphase;
1118 u_int lastphase;
1119 u_int scsirate;
1120 u_int i;
1121 u_int sstat2;
1122 int silent;
1123
1124 lastphase = ahc_inb(ahc, LASTPHASE);
1125 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
1126 sstat2 = ahc_inb(ahc, SSTAT2);
1127 ahc_outb(ahc, CLRSINT1, CLRSCSIPERR);
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139 if ((ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0
1140 || curphase == P_DATAIN || curphase == P_DATAIN_DT)
1141 errorphase = curphase;
1142 else
1143 errorphase = lastphase;
1144
1145 for (i = 0; i < num_phases; i++) {
1146 if (errorphase == ahc_phase_table[i].phase)
1147 break;
1148 }
1149 mesg_out = ahc_phase_table[i].mesg_out;
1150 silent = FALSE;
1151 if (scb != NULL) {
1152 if (SCB_IS_SILENT(scb))
1153 silent = TRUE;
1154 else
1155 ahc_print_path(ahc, scb);
1156 scb->flags |= SCB_TRANSMISSION_ERROR;
1157 } else
1158 printf("%s:%c:%d: ", ahc_name(ahc), intr_channel,
1159 SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)));
1160 scsirate = ahc_inb(ahc, SCSIRATE);
1161 if (silent == FALSE) {
1162 printf("parity error detected %s. "
1163 "SEQADDR(0x%x) SCSIRATE(0x%x)\n",
1164 ahc_phase_table[i].phasemsg,
1165 ahc_inw(ahc, SEQADDR0),
1166 scsirate);
1167 if ((ahc->features & AHC_DT) != 0) {
1168 if ((sstat2 & CRCVALERR) != 0)
1169 printf("\tCRC Value Mismatch\n");
1170 if ((sstat2 & CRCENDERR) != 0)
1171 printf("\tNo terminal CRC packet "
1172 "received\n");
1173 if ((sstat2 & CRCREQERR) != 0)
1174 printf("\tIllegal CRC packet "
1175 "request\n");
1176 if ((sstat2 & DUAL_EDGE_ERR) != 0)
1177 printf("\tUnexpected %sDT Data Phase\n",
1178 (scsirate & SINGLE_EDGE)
1179 ? "" : "non-");
1180 }
1181 }
1182
1183 if ((ahc->features & AHC_DT) != 0
1184 && (sstat2 & DUAL_EDGE_ERR) != 0) {
1185
1186
1187
1188
1189
1190 mesg_out = MSG_INITIATOR_DET_ERR;
1191 }
1192
1193
1194
1195
1196
1197
1198
1199
1200 if (mesg_out != MSG_NOOP) {
1201 if (ahc->msg_type != MSG_TYPE_NONE)
1202 ahc->send_msg_perror = TRUE;
1203 else
1204 ahc_outb(ahc, MSG_OUT, mesg_out);
1205 }
1206
1207
1208
1209
1210
1211 ahc_fetch_devinfo(ahc, &devinfo);
1212 ahc_force_renegotiation(ahc, &devinfo);
1213
1214 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1215 ahc_unpause(ahc);
1216 } else if ((status & SELTO) != 0) {
1217 u_int scbptr;
1218
1219
1220 ahc_outb(ahc, SCSISEQ, 0);
1221
1222
1223 ahc_clear_msg_state(ahc);
1224
1225
1226 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
1227 ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237 ahc_outb(ahc, CLRSINT0, CLRSELINGO);
1238
1239 scbptr = ahc_inb(ahc, WAITING_SCBH);
1240 ahc_outb(ahc, SCBPTR, scbptr);
1241 scb_index = ahc_inb(ahc, SCB_TAG);
1242
1243 scb = ahc_lookup_scb(ahc, scb_index);
1244 if (scb == NULL) {
1245 printf("%s: ahc_intr - referenced scb not "
1246 "valid during SELTO scb(%d, %d)\n",
1247 ahc_name(ahc), scbptr, scb_index);
1248 ahc_dump_card_state(ahc);
1249 } else {
1250 struct ahc_devinfo devinfo;
1251 #ifdef AHC_DEBUG
1252 if ((ahc_debug & AHC_SHOW_SELTO) != 0) {
1253 ahc_print_path(ahc, scb);
1254 printf("Saw Selection Timeout for SCB 0x%x\n",
1255 scb_index);
1256 }
1257 #endif
1258 ahc_scb_devinfo(ahc, &devinfo, scb);
1259 ahc_set_transaction_status(scb, CAM_SEL_TIMEOUT);
1260 ahc_freeze_devq(ahc, scb);
1261
1262
1263
1264
1265
1266
1267
1268 ahc_handle_devreset(ahc, &devinfo,
1269 CAM_SEL_TIMEOUT,
1270 "Selection Timeout",
1271 1);
1272 }
1273 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1274 ahc_restart(ahc);
1275 } else if ((status & BUSFREE) != 0
1276 && (ahc_inb(ahc, SIMODE1) & ENBUSFREE) != 0) {
1277 struct ahc_devinfo devinfo;
1278 u_int lastphase;
1279 u_int saved_scsiid;
1280 u_int saved_lun;
1281 u_int target;
1282 u_int initiator_role_id;
1283 char channel;
1284 int printerror;
1285
1286
1287
1288
1289
1290
1291
1292 ahc_outb(ahc, SCSISEQ,
1293 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
1294
1295
1296
1297
1298
1299
1300
1301 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
1302 ahc_outb(ahc, CLRSINT1, CLRBUSFREE|CLRSCSIPERR);
1303
1304
1305
1306
1307
1308
1309
1310 lastphase = ahc_inb(ahc, LASTPHASE);
1311 saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
1312 saved_lun = ahc_inb(ahc, SAVED_LUN);
1313 target = SCSIID_TARGET(ahc, saved_scsiid);
1314 initiator_role_id = SCSIID_OUR_ID(saved_scsiid);
1315 channel = SCSIID_CHANNEL(ahc, saved_scsiid);
1316 ahc_compile_devinfo(&devinfo, initiator_role_id,
1317 target, saved_lun, channel, ROLE_INITIATOR);
1318 printerror = 1;
1319
1320 if (lastphase == P_MESGOUT) {
1321 u_int tag;
1322
1323 tag = SCB_LIST_NULL;
1324 if (ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT_TAG, TRUE)
1325 || ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT, TRUE)) {
1326 if (ahc->msgout_buf[ahc->msgout_index - 1]
1327 == MSG_ABORT_TAG)
1328 tag = scb->hscb->tag;
1329 ahc_print_path(ahc, scb);
1330 printf("SCB %d - Abort%s Completed.\n",
1331 scb->hscb->tag, tag == SCB_LIST_NULL ?
1332 "" : " Tag");
1333 ahc_abort_scbs(ahc, target, channel,
1334 saved_lun, tag,
1335 ROLE_INITIATOR,
1336 CAM_REQ_ABORTED);
1337 printerror = 0;
1338 } else if (ahc_sent_msg(ahc, AHCMSG_1B,
1339 MSG_BUS_DEV_RESET, TRUE)) {
1340 #ifdef __FreeBSD__
1341
1342
1343
1344
1345
1346 if (scb != NULL
1347 && scb->io_ctx->ccb_h.func_code== XPT_RESET_DEV
1348 && ahc_match_scb(ahc, scb, target, channel,
1349 CAM_LUN_WILDCARD,
1350 SCB_LIST_NULL,
1351 ROLE_INITIATOR)) {
1352 ahc_set_transaction_status(scb, CAM_REQ_CMP);
1353 }
1354 #endif
1355 ahc_compile_devinfo(&devinfo,
1356 initiator_role_id,
1357 target,
1358 CAM_LUN_WILDCARD,
1359 channel,
1360 ROLE_INITIATOR);
1361 ahc_handle_devreset(ahc, &devinfo,
1362 CAM_BDR_SENT,
1363 "Bus Device Reset",
1364 0);
1365 printerror = 0;
1366 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
1367 MSG_EXT_PPR, FALSE)) {
1368 struct ahc_initiator_tinfo *tinfo;
1369 struct ahc_tmode_tstate *tstate;
1370
1371
1372
1373
1374
1375 tinfo = ahc_fetch_transinfo(ahc,
1376 devinfo.channel,
1377 devinfo.our_scsiid,
1378 devinfo.target,
1379 &tstate);
1380 tinfo->curr.transport_version = 2;
1381 tinfo->goal.transport_version = 2;
1382 tinfo->goal.ppr_options = 0;
1383 ahc_qinfifo_requeue_tail(ahc, scb);
1384 printerror = 0;
1385 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
1386 MSG_EXT_WDTR, FALSE)) {
1387
1388
1389
1390
1391 ahc_set_width(ahc, &devinfo,
1392 MSG_EXT_WDTR_BUS_8_BIT,
1393 AHC_TRANS_CUR|AHC_TRANS_GOAL,
1394 TRUE);
1395 ahc_qinfifo_requeue_tail(ahc, scb);
1396 printerror = 0;
1397 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
1398 MSG_EXT_SDTR, FALSE)) {
1399
1400
1401
1402
1403 ahc_set_syncrate(ahc, &devinfo,
1404 NULL,
1405 0, 0,
1406 0,
1407 AHC_TRANS_CUR|AHC_TRANS_GOAL,
1408 TRUE);
1409 ahc_qinfifo_requeue_tail(ahc, scb);
1410 printerror = 0;
1411 }
1412 }
1413 if (printerror != 0) {
1414 u_int i;
1415
1416 if (scb != NULL) {
1417 u_int tag;
1418
1419 if ((scb->hscb->control & TAG_ENB) != 0)
1420 tag = scb->hscb->tag;
1421 else
1422 tag = SCB_LIST_NULL;
1423 ahc_print_path(ahc, scb);
1424 ahc_abort_scbs(ahc, target, channel,
1425 SCB_GET_LUN(scb), tag,
1426 ROLE_INITIATOR,
1427 CAM_UNEXP_BUSFREE);
1428 } else {
1429
1430
1431
1432
1433 printf("%s: ", ahc_name(ahc));
1434 }
1435 for (i = 0; i < num_phases; i++) {
1436 if (lastphase == ahc_phase_table[i].phase)
1437 break;
1438 }
1439 if (lastphase != P_BUSFREE) {
1440
1441
1442
1443
1444
1445
1446 ahc_force_renegotiation(ahc, &devinfo);
1447 }
1448 printf("Unexpected busfree %s\n"
1449 "SEQADDR == 0x%x\n",
1450 ahc_phase_table[i].phasemsg,
1451 ahc_inb(ahc, SEQADDR0)
1452 | (ahc_inb(ahc, SEQADDR1) << 8));
1453 }
1454 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1455 ahc_restart(ahc);
1456 } else {
1457 printf("%s: Missing case in ahc_handle_scsiint. status = %x\n",
1458 ahc_name(ahc), status);
1459 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1460 }
1461 }
1462
1463
1464
1465
1466
1467 void
1468 ahc_force_renegotiation(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
1469 {
1470 struct ahc_initiator_tinfo *targ_info;
1471 struct ahc_tmode_tstate *tstate;
1472
1473 targ_info = ahc_fetch_transinfo(ahc,
1474 devinfo->channel,
1475 devinfo->our_scsiid,
1476 devinfo->target,
1477 &tstate);
1478 ahc_update_neg_request(ahc, devinfo, tstate,
1479 targ_info, AHC_NEG_IF_NON_ASYNC);
1480 }
1481
1482 #define AHC_MAX_STEPS 2000
1483 void
1484 ahc_clear_critical_section(struct ahc_softc *ahc)
1485 {
1486 int stepping;
1487 int steps;
1488 u_int simode0;
1489 u_int simode1;
1490
1491 if (ahc->num_critical_sections == 0)
1492 return;
1493
1494 stepping = FALSE;
1495 steps = 0;
1496 simode0 = 0;
1497 simode1 = 0;
1498 for (;;) {
1499 struct cs *cs;
1500 u_int seqaddr;
1501 u_int i;
1502
1503 seqaddr = ahc_inb(ahc, SEQADDR0)
1504 | (ahc_inb(ahc, SEQADDR1) << 8);
1505
1506
1507
1508
1509
1510
1511 cs = ahc->critical_sections;
1512 for (i = 0; i < ahc->num_critical_sections; i++, cs++) {
1513
1514 if (cs->begin < seqaddr && cs->end >= seqaddr)
1515 break;
1516 }
1517
1518 if (i == ahc->num_critical_sections)
1519 break;
1520
1521 if (steps > AHC_MAX_STEPS) {
1522 printf("%s: Infinite loop in critical section\n",
1523 ahc_name(ahc));
1524 ahc_dump_card_state(ahc);
1525 panic("critical section loop");
1526 }
1527
1528 steps++;
1529 if (stepping == FALSE) {
1530
1531
1532
1533
1534
1535
1536
1537 simode0 = ahc_inb(ahc, SIMODE0);
1538 ahc_outb(ahc, SIMODE0, 0);
1539 simode1 = ahc_inb(ahc, SIMODE1);
1540 if ((ahc->features & AHC_DT) != 0)
1541
1542
1543
1544
1545
1546
1547
1548
1549 ahc_outb(ahc, SIMODE1, simode1 & ENBUSFREE);
1550 else
1551 ahc_outb(ahc, SIMODE1, 0);
1552 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1553 ahc_outb(ahc, SEQCTL, ahc->seqctl | STEP);
1554 stepping = TRUE;
1555 }
1556 if ((ahc->features & AHC_DT) != 0) {
1557 ahc_outb(ahc, CLRSINT1, CLRBUSFREE);
1558 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1559 }
1560 ahc_outb(ahc, HCNTRL, ahc->unpause);
1561 while (!ahc_is_paused(ahc))
1562 aic_delay(200);
1563 }
1564 if (stepping) {
1565 ahc_outb(ahc, SIMODE0, simode0);
1566 ahc_outb(ahc, SIMODE1, simode1);
1567 ahc_outb(ahc, SEQCTL, ahc->seqctl);
1568 }
1569 }
1570
1571
1572
1573
1574 void
1575 ahc_clear_intstat(struct ahc_softc *ahc)
1576 {
1577
1578 ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
1579 |CLRBUSFREE|CLRSCSIPERR|CLRPHASECHG|
1580 CLRREQINIT);
1581 ahc_flush_device_writes(ahc);
1582 ahc_outb(ahc, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO);
1583 ahc_flush_device_writes(ahc);
1584 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1585 ahc_flush_device_writes(ahc);
1586 }
1587
1588
1589 #ifdef AHC_DEBUG
1590 uint32_t ahc_debug = 0;
1591
1592 void
1593 ahc_print_scb(struct scb *scb)
1594 {
1595 int i;
1596
1597 struct hardware_scb *hscb = scb->hscb;
1598
1599 printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
1600 (void *)scb,
1601 hscb->control,
1602 hscb->scsiid,
1603 hscb->lun,
1604 hscb->cdb_len);
1605 printf("Shared Data: ");
1606 for (i = 0; i < sizeof(hscb->shared_data.cdb); i++)
1607 printf("%#02x", hscb->shared_data.cdb[i]);
1608 printf(" dataptr:%#x datacnt:%#x sgptr:%#x tag:%#x\n",
1609 aic_le32toh(hscb->dataptr),
1610 aic_le32toh(hscb->datacnt),
1611 aic_le32toh(hscb->sgptr),
1612 hscb->tag);
1613 if (scb->sg_count > 0) {
1614 for (i = 0; i < scb->sg_count; i++) {
1615 printf("sg[%d] - Addr 0x%x%x : Length %d\n",
1616 i,
1617 (aic_le32toh(scb->sg_list[i].len) >> 24
1618 & SG_HIGH_ADDR_BITS),
1619 aic_le32toh(scb->sg_list[i].addr),
1620 aic_le32toh(scb->sg_list[i].len));
1621 }
1622 }
1623 }
1624 #endif
1625
1626
1627
1628
1629
1630
1631 static struct ahc_tmode_tstate *
1632 ahc_alloc_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel)
1633 {
1634 struct ahc_tmode_tstate *master_tstate;
1635 struct ahc_tmode_tstate *tstate;
1636 int i;
1637
1638 master_tstate = ahc->enabled_targets[ahc->our_id];
1639 if (channel == 'B') {
1640 scsi_id += 8;
1641 master_tstate = ahc->enabled_targets[ahc->our_id_b + 8];
1642 }
1643 if (ahc->enabled_targets[scsi_id] != NULL
1644 && ahc->enabled_targets[scsi_id] != master_tstate)
1645 panic("%s: ahc_alloc_tstate - Target already allocated",
1646 ahc_name(ahc));
1647 tstate = (struct ahc_tmode_tstate*)malloc(sizeof(*tstate),
1648 M_DEVBUF, M_NOWAIT);
1649 if (tstate == NULL)
1650 return (NULL);
1651
1652
1653
1654
1655
1656
1657
1658 if (master_tstate != NULL) {
1659 memcpy(tstate, master_tstate, sizeof(*tstate));
1660 memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns));
1661 tstate->ultraenb = 0;
1662 for (i = 0; i < AHC_NUM_TARGETS; i++) {
1663 memset(&tstate->transinfo[i].curr, 0,
1664 sizeof(tstate->transinfo[i].curr));
1665 memset(&tstate->transinfo[i].goal, 0,
1666 sizeof(tstate->transinfo[i].goal));
1667 }
1668 } else
1669 memset(tstate, 0, sizeof(*tstate));
1670 ahc->enabled_targets[scsi_id] = tstate;
1671 return (tstate);
1672 }
1673
1674 #ifdef AHC_TARGET_MODE
1675
1676
1677
1678
1679 static void
1680 ahc_free_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel, int force)
1681 {
1682 struct ahc_tmode_tstate *tstate;
1683
1684
1685
1686
1687
1688 if (((channel == 'B' && scsi_id == ahc->our_id_b)
1689 || (channel == 'A' && scsi_id == ahc->our_id))
1690 && force == FALSE)
1691 return;
1692
1693 if (channel == 'B')
1694 scsi_id += 8;
1695 tstate = ahc->enabled_targets[scsi_id];
1696 if (tstate != NULL)
1697 free(tstate, M_DEVBUF);
1698 ahc->enabled_targets[scsi_id] = NULL;
1699 }
1700 #endif
1701
1702
1703
1704
1705
1706
1707
1708 struct ahc_syncrate *
1709 ahc_devlimited_syncrate(struct ahc_softc *ahc,
1710 struct ahc_initiator_tinfo *tinfo,
1711 u_int *period, u_int *ppr_options, role_t role)
1712 {
1713 struct ahc_transinfo *transinfo;
1714 u_int maxsync;
1715
1716 if ((ahc->features & AHC_ULTRA2) != 0) {
1717 if ((ahc_inb(ahc, SBLKCTL) & ENAB40) != 0
1718 && (ahc_inb(ahc, SSTAT2) & EXP_ACTIVE) == 0) {
1719 maxsync = AHC_SYNCRATE_DT;
1720 } else {
1721 maxsync = AHC_SYNCRATE_ULTRA;
1722
1723 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1724 }
1725 } else if ((ahc->features & AHC_ULTRA) != 0) {
1726 maxsync = AHC_SYNCRATE_ULTRA;
1727 } else {
1728 maxsync = AHC_SYNCRATE_FAST;
1729 }
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740 if (role == ROLE_TARGET)
1741 transinfo = &tinfo->user;
1742 else
1743 transinfo = &tinfo->goal;
1744 *ppr_options &= transinfo->ppr_options;
1745 if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
1746 maxsync = MAX(maxsync, AHC_SYNCRATE_ULTRA2);
1747 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1748 }
1749 if (transinfo->period == 0) {
1750 *period = 0;
1751 *ppr_options = 0;
1752 return (NULL);
1753 }
1754 *period = MAX(*period, transinfo->period);
1755 return (ahc_find_syncrate(ahc, period, ppr_options, maxsync));
1756 }
1757
1758
1759
1760
1761
1762
1763 struct ahc_syncrate *
1764 ahc_find_syncrate(struct ahc_softc *ahc, u_int *period,
1765 u_int *ppr_options, u_int maxsync)
1766 {
1767 struct ahc_syncrate *syncrate;
1768
1769 if ((ahc->features & AHC_DT) == 0)
1770 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1771
1772
1773 if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
1774 && maxsync < AHC_SYNCRATE_ULTRA2)
1775 maxsync = AHC_SYNCRATE_ULTRA2;
1776
1777 for (syncrate = &ahc_syncrates[maxsync];
1778 syncrate->rate != NULL;
1779 syncrate++) {
1780
1781
1782
1783
1784
1785 if ((ahc->features & AHC_ULTRA2) != 0
1786 && (syncrate->sxfr_u2 == 0))
1787 break;
1788
1789 if (*period <= syncrate->period) {
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801 if (syncrate == &ahc_syncrates[maxsync])
1802 *period = syncrate->period;
1803
1804
1805
1806
1807
1808 if ((syncrate->sxfr_u2 & ST_SXFR) != 0)
1809 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1810 break;
1811 }
1812 }
1813
1814 if ((*period == 0)
1815 || (syncrate->rate == NULL)
1816 || ((ahc->features & AHC_ULTRA2) != 0
1817 && (syncrate->sxfr_u2 == 0))) {
1818
1819 *period = 0;
1820 syncrate = NULL;
1821 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1822 }
1823 return (syncrate);
1824 }
1825
1826
1827
1828
1829
1830 u_int
1831 ahc_find_period(struct ahc_softc *ahc, u_int scsirate, u_int maxsync)
1832 {
1833 struct ahc_syncrate *syncrate;
1834
1835 if ((ahc->features & AHC_ULTRA2) != 0)
1836 scsirate &= SXFR_ULTRA2;
1837 else
1838 scsirate &= SXFR;
1839
1840 syncrate = &ahc_syncrates[maxsync];
1841 while (syncrate->rate != NULL) {
1842
1843 if ((ahc->features & AHC_ULTRA2) != 0) {
1844 if (syncrate->sxfr_u2 == 0)
1845 break;
1846 else if (scsirate == (syncrate->sxfr_u2 & SXFR_ULTRA2))
1847 return (syncrate->period);
1848 } else if (scsirate == (syncrate->sxfr & SXFR)) {
1849 return (syncrate->period);
1850 }
1851 syncrate++;
1852 }
1853 return (0);
1854 }
1855
1856
1857
1858
1859
1860 void
1861 ahc_validate_offset(struct ahc_softc *ahc,
1862 struct ahc_initiator_tinfo *tinfo,
1863 struct ahc_syncrate *syncrate,
1864 u_int *offset, int wide, role_t role)
1865 {
1866 u_int maxoffset;
1867
1868
1869 if (syncrate == NULL) {
1870 maxoffset = 0;
1871 } else if ((ahc->features & AHC_ULTRA2) != 0) {
1872 maxoffset = MAX_OFFSET_ULTRA2;
1873 } else {
1874 if (wide)
1875 maxoffset = MAX_OFFSET_16BIT;
1876 else
1877 maxoffset = MAX_OFFSET_8BIT;
1878 }
1879 *offset = MIN(*offset, maxoffset);
1880 if (tinfo != NULL) {
1881 if (role == ROLE_TARGET)
1882 *offset = MIN(*offset, tinfo->user.offset);
1883 else
1884 *offset = MIN(*offset, tinfo->goal.offset);
1885 }
1886 }
1887
1888
1889
1890
1891
1892 void
1893 ahc_validate_width(struct ahc_softc *ahc, struct ahc_initiator_tinfo *tinfo,
1894 u_int *bus_width, role_t role)
1895 {
1896 switch (*bus_width) {
1897 default:
1898 if (ahc->features & AHC_WIDE) {
1899
1900 *bus_width = MSG_EXT_WDTR_BUS_16_BIT;
1901 break;
1902 }
1903
1904 case MSG_EXT_WDTR_BUS_8_BIT:
1905 *bus_width = MSG_EXT_WDTR_BUS_8_BIT;
1906 break;
1907 }
1908 if (tinfo != NULL) {
1909 if (role == ROLE_TARGET)
1910 *bus_width = MIN(tinfo->user.width, *bus_width);
1911 else
1912 *bus_width = MIN(tinfo->goal.width, *bus_width);
1913 }
1914 }
1915
1916
1917
1918
1919
1920
1921
1922 int
1923 ahc_update_neg_request(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
1924 struct ahc_tmode_tstate *tstate,
1925 struct ahc_initiator_tinfo *tinfo, ahc_neg_type neg_type)
1926 {
1927 u_int auto_negotiate_orig;
1928
1929 auto_negotiate_orig = tstate->auto_negotiate;
1930 if (neg_type == AHC_NEG_ALWAYS) {
1931
1932
1933
1934
1935
1936
1937 if ((ahc->features & AHC_WIDE) != 0)
1938 tinfo->curr.width = AHC_WIDTH_UNKNOWN;
1939 tinfo->curr.period = AHC_PERIOD_UNKNOWN;
1940 tinfo->curr.offset = AHC_OFFSET_UNKNOWN;
1941 }
1942 if (tinfo->curr.period != tinfo->goal.period
1943 || tinfo->curr.width != tinfo->goal.width
1944 || tinfo->curr.offset != tinfo->goal.offset
1945 || tinfo->curr.ppr_options != tinfo->goal.ppr_options
1946 || (neg_type == AHC_NEG_IF_NON_ASYNC
1947 && (tinfo->goal.offset != 0
1948 || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT
1949 || tinfo->goal.ppr_options != 0)))
1950 tstate->auto_negotiate |= devinfo->target_mask;
1951 else
1952 tstate->auto_negotiate &= ~devinfo->target_mask;
1953
1954 return (auto_negotiate_orig != tstate->auto_negotiate);
1955 }
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965 void
1966 ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
1967 struct ahc_syncrate *syncrate, u_int period,
1968 u_int offset, u_int ppr_options, u_int type, int paused)
1969 {
1970 struct ahc_initiator_tinfo *tinfo;
1971 struct ahc_tmode_tstate *tstate;
1972 u_int old_period;
1973 u_int old_offset;
1974 u_int old_ppr;
1975 int active;
1976 int update_needed;
1977
1978 active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
1979 update_needed = 0;
1980
1981 if (syncrate == NULL) {
1982 period = 0;
1983 offset = 0;
1984 }
1985
1986 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
1987 devinfo->target, &tstate);
1988
1989 if ((type & AHC_TRANS_USER) != 0) {
1990 tinfo->user.period = period;
1991 tinfo->user.offset = offset;
1992 tinfo->user.ppr_options = ppr_options;
1993 }
1994
1995 if ((type & AHC_TRANS_GOAL) != 0) {
1996 tinfo->goal.period = period;
1997 tinfo->goal.offset = offset;
1998 tinfo->goal.ppr_options = ppr_options;
1999 }
2000
2001 old_period = tinfo->curr.period;
2002 old_offset = tinfo->curr.offset;
2003 old_ppr = tinfo->curr.ppr_options;
2004
2005 if ((type & AHC_TRANS_CUR) != 0
2006 && (old_period != period
2007 || old_offset != offset
2008 || old_ppr != ppr_options)) {
2009 u_int scsirate;
2010
2011 update_needed++;
2012 scsirate = tinfo->scsirate;
2013 if ((ahc->features & AHC_ULTRA2) != 0) {
2014
2015 scsirate &= ~(SXFR_ULTRA2|SINGLE_EDGE|ENABLE_CRC);
2016 if (syncrate != NULL) {
2017 scsirate |= syncrate->sxfr_u2;
2018 if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0)
2019 scsirate |= ENABLE_CRC;
2020 else
2021 scsirate |= SINGLE_EDGE;
2022 }
2023 } else {
2024
2025 scsirate &= ~(SXFR|SOFS);
2026
2027
2028
2029
2030 tstate->ultraenb &= ~devinfo->target_mask;
2031 if (syncrate != NULL) {
2032 if (syncrate->sxfr & ULTRA_SXFR) {
2033 tstate->ultraenb |=
2034 devinfo->target_mask;
2035 }
2036 scsirate |= syncrate->sxfr & SXFR;
2037 scsirate |= offset & SOFS;
2038 }
2039 if (active) {
2040 u_int sxfrctl0;
2041
2042 sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
2043 sxfrctl0 &= ~FAST20;
2044 if (tstate->ultraenb & devinfo->target_mask)
2045 sxfrctl0 |= FAST20;
2046 ahc_outb(ahc, SXFRCTL0, sxfrctl0);
2047 }
2048 }
2049 if (active) {
2050 ahc_outb(ahc, SCSIRATE, scsirate);
2051 if ((ahc->features & AHC_ULTRA2) != 0)
2052 ahc_outb(ahc, SCSIOFFSET, offset);
2053 }
2054
2055 tinfo->scsirate = scsirate;
2056 tinfo->curr.period = period;
2057 tinfo->curr.offset = offset;
2058 tinfo->curr.ppr_options = ppr_options;
2059
2060 ahc_send_async(ahc, devinfo->channel, devinfo->target,
2061 CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
2062 if (1 ) {
2063 if (offset != 0) {
2064 printf("%s: target %d synchronous at %sMHz%s, "
2065 "offset = 0x%x\n", ahc_name(ahc),
2066 devinfo->target, syncrate->rate,
2067 (ppr_options & MSG_EXT_PPR_DT_REQ)
2068 ? " DT" : "", offset);
2069 } else {
2070 printf("%s: target %d using "
2071 "asynchronous transfers\n",
2072 ahc_name(ahc), devinfo->target);
2073 }
2074 }
2075 }
2076
2077 update_needed += ahc_update_neg_request(ahc, devinfo, tstate,
2078 tinfo, AHC_NEG_TO_GOAL);
2079
2080 if (update_needed)
2081 ahc_update_pending_scbs(ahc);
2082 }
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092 void
2093 ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2094 u_int width, u_int type, int paused)
2095 {
2096 struct ahc_initiator_tinfo *tinfo;
2097 struct ahc_tmode_tstate *tstate;
2098 u_int oldwidth;
2099 int active;
2100 int update_needed;
2101
2102 active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
2103 update_needed = 0;
2104 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
2105 devinfo->target, &tstate);
2106
2107 if ((type & AHC_TRANS_USER) != 0)
2108 tinfo->user.width = width;
2109
2110 if ((type & AHC_TRANS_GOAL) != 0)
2111 tinfo->goal.width = width;
2112
2113 oldwidth = tinfo->curr.width;
2114 if ((type & AHC_TRANS_CUR) != 0 && oldwidth != width) {
2115 u_int scsirate;
2116
2117 update_needed++;
2118 scsirate = tinfo->scsirate;
2119 scsirate &= ~WIDEXFER;
2120 if (width == MSG_EXT_WDTR_BUS_16_BIT)
2121 scsirate |= WIDEXFER;
2122
2123 tinfo->scsirate = scsirate;
2124
2125 if (active)
2126 ahc_outb(ahc, SCSIRATE, scsirate);
2127
2128 tinfo->curr.width = width;
2129
2130 ahc_send_async(ahc, devinfo->channel, devinfo->target,
2131 CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
2132 if (1 ) {
2133 printf("%s: target %d using %dbit transfers\n",
2134 ahc_name(ahc), devinfo->target,
2135 8 * (0x01 << width));
2136 }
2137 }
2138
2139 update_needed += ahc_update_neg_request(ahc, devinfo, tstate,
2140 tinfo, AHC_NEG_TO_GOAL);
2141 if (update_needed)
2142 ahc_update_pending_scbs(ahc);
2143 }
2144
2145
2146
2147
2148 void
2149 ahc_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2150 ahc_queue_alg alg)
2151 {
2152 ahc_platform_set_tags(ahc, devinfo, alg);
2153 ahc_send_async(ahc, devinfo->channel, devinfo->target,
2154 devinfo->lun, AC_TRANSFER_NEG, &alg);
2155 }
2156
2157
2158
2159
2160
2161
2162 static void
2163 ahc_update_pending_scbs(struct ahc_softc *ahc)
2164 {
2165 struct scb *pending_scb;
2166 int pending_scb_count;
2167 int i;
2168 int paused;
2169 u_int saved_scbptr;
2170
2171
2172
2173
2174
2175 pending_scb_count = 0;
2176 LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
2177 struct ahc_devinfo devinfo;
2178 struct hardware_scb *pending_hscb;
2179 struct ahc_initiator_tinfo *tinfo;
2180 struct ahc_tmode_tstate *tstate;
2181
2182 ahc_scb_devinfo(ahc, &devinfo, pending_scb);
2183 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
2184 devinfo.our_scsiid,
2185 devinfo.target, &tstate);
2186 pending_hscb = pending_scb->hscb;
2187 pending_hscb->control &= ~ULTRAENB;
2188 if ((tstate->ultraenb & devinfo.target_mask) != 0)
2189 pending_hscb->control |= ULTRAENB;
2190 pending_hscb->scsirate = tinfo->scsirate;
2191 pending_hscb->scsioffset = tinfo->curr.offset;
2192 if ((tstate->auto_negotiate & devinfo.target_mask) == 0
2193 && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) {
2194 pending_scb->flags &= ~SCB_AUTO_NEGOTIATE;
2195 pending_hscb->control &= ~MK_MESSAGE;
2196 }
2197 ahc_sync_scb(ahc, pending_scb,
2198 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2199 pending_scb_count++;
2200 }
2201
2202 if (pending_scb_count == 0)
2203 return;
2204
2205 if (ahc_is_paused(ahc)) {
2206 paused = 1;
2207 } else {
2208 paused = 0;
2209 ahc_pause(ahc);
2210 }
2211
2212 saved_scbptr = ahc_inb(ahc, SCBPTR);
2213
2214 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
2215 struct hardware_scb *pending_hscb;
2216 u_int control;
2217 u_int scb_tag;
2218
2219 ahc_outb(ahc, SCBPTR, i);
2220 scb_tag = ahc_inb(ahc, SCB_TAG);
2221 pending_scb = ahc_lookup_scb(ahc, scb_tag);
2222 if (pending_scb == NULL)
2223 continue;
2224
2225 pending_hscb = pending_scb->hscb;
2226 control = ahc_inb(ahc, SCB_CONTROL);
2227 control &= ~(ULTRAENB|MK_MESSAGE);
2228 control |= pending_hscb->control & (ULTRAENB|MK_MESSAGE);
2229 ahc_outb(ahc, SCB_CONTROL, control);
2230 ahc_outb(ahc, SCB_SCSIRATE, pending_hscb->scsirate);
2231 ahc_outb(ahc, SCB_SCSIOFFSET, pending_hscb->scsioffset);
2232 }
2233 ahc_outb(ahc, SCBPTR, saved_scbptr);
2234
2235 if (paused == 0)
2236 ahc_unpause(ahc);
2237 }
2238
2239
2240 static void
2241 ahc_fetch_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
2242 {
2243 u_int saved_scsiid;
2244 role_t role;
2245 int our_id;
2246
2247 if (ahc_inb(ahc, SSTAT0) & TARGET)
2248 role = ROLE_TARGET;
2249 else
2250 role = ROLE_INITIATOR;
2251
2252 if (role == ROLE_TARGET
2253 && (ahc->features & AHC_MULTI_TID) != 0
2254 && (ahc_inb(ahc, SEQ_FLAGS)
2255 & (CMDPHASE_PENDING|TARG_CMD_PENDING|NO_DISCONNECT)) != 0) {
2256
2257 our_id = ahc_inb(ahc, TARGIDIN) & OID;
2258 } else if ((ahc->features & AHC_ULTRA2) != 0)
2259 our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
2260 else
2261 our_id = ahc_inb(ahc, SCSIID) & OID;
2262
2263 saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
2264 ahc_compile_devinfo(devinfo,
2265 our_id,
2266 SCSIID_TARGET(ahc, saved_scsiid),
2267 ahc_inb(ahc, SAVED_LUN),
2268 SCSIID_CHANNEL(ahc, saved_scsiid),
2269 role);
2270 }
2271
2272 struct ahc_phase_table_entry*
2273 ahc_lookup_phase_entry(int phase)
2274 {
2275 struct ahc_phase_table_entry *entry;
2276 struct ahc_phase_table_entry *last_entry;
2277
2278
2279
2280
2281
2282 last_entry = &ahc_phase_table[num_phases];
2283 for (entry = ahc_phase_table; entry < last_entry; entry++) {
2284 if (phase == entry->phase)
2285 break;
2286 }
2287 return (entry);
2288 }
2289
2290 void
2291 ahc_compile_devinfo(struct ahc_devinfo *devinfo, u_int our_id, u_int target,
2292 u_int lun, char channel, role_t role)
2293 {
2294 devinfo->our_scsiid = our_id;
2295 devinfo->target = target;
2296 devinfo->lun = lun;
2297 devinfo->target_offset = target;
2298 devinfo->channel = channel;
2299 devinfo->role = role;
2300 if (channel == 'B')
2301 devinfo->target_offset += 8;
2302 devinfo->target_mask = (0x01 << devinfo->target_offset);
2303 }
2304
2305 void
2306 ahc_print_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
2307 {
2308 printf("%s:%c:%d:%d: ", ahc_name(ahc), devinfo->channel,
2309 devinfo->target, devinfo->lun);
2310 }
2311
2312 void
2313 ahc_scb_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2314 struct scb *scb)
2315 {
2316 role_t role;
2317 int our_id;
2318
2319 our_id = SCSIID_OUR_ID(scb->hscb->scsiid);
2320 role = ROLE_INITIATOR;
2321 if ((scb->flags & SCB_TARGET_SCB) != 0)
2322 role = ROLE_TARGET;
2323 ahc_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahc, scb),
2324 SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahc, scb), role);
2325 }
2326
2327
2328
2329 static void
2330 ahc_assert_atn(struct ahc_softc *ahc)
2331 {
2332 u_int scsisigo;
2333
2334 scsisigo = ATNO;
2335 if ((ahc->features & AHC_DT) == 0)
2336 scsisigo |= ahc_inb(ahc, SCSISIGI);
2337 ahc_outb(ahc, SCSISIGO, scsisigo);
2338 }
2339
2340
2341
2342
2343
2344
2345
2346 static void
2347 ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2348 struct scb *scb)
2349 {
2350
2351
2352
2353
2354
2355 ahc->msgout_index = 0;
2356 ahc->msgout_len = 0;
2357
2358 if ((scb->flags & SCB_DEVICE_RESET) == 0
2359 && ahc_inb(ahc, MSG_OUT) == MSG_IDENTIFYFLAG) {
2360 u_int identify_msg;
2361
2362 identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb);
2363 if ((scb->hscb->control & DISCENB) != 0)
2364 identify_msg |= MSG_IDENTIFY_DISCFLAG;
2365 ahc->msgout_buf[ahc->msgout_index++] = identify_msg;
2366 ahc->msgout_len++;
2367
2368 if ((scb->hscb->control & TAG_ENB) != 0) {
2369 ahc->msgout_buf[ahc->msgout_index++] =
2370 scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE);
2371 ahc->msgout_buf[ahc->msgout_index++] = scb->hscb->tag;
2372 ahc->msgout_len += 2;
2373 }
2374 }
2375
2376 if (scb->flags & SCB_DEVICE_RESET) {
2377 ahc->msgout_buf[ahc->msgout_index++] = MSG_BUS_DEV_RESET;
2378 ahc->msgout_len++;
2379 ahc_print_path(ahc, scb);
2380 printf("Bus Device Reset Message Sent\n");
2381
2382
2383
2384
2385
2386
2387
2388 ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
2389 } else if ((scb->flags & SCB_ABORT) != 0) {
2390 if ((scb->hscb->control & TAG_ENB) != 0)
2391 ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT_TAG;
2392 else
2393 ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT;
2394 ahc->msgout_len++;
2395 ahc_print_path(ahc, scb);
2396 printf("Abort%s Message Sent\n",
2397 (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");
2398
2399
2400
2401
2402
2403
2404
2405 ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
2406 } else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) {
2407 ahc_build_transfer_msg(ahc, devinfo);
2408 } else {
2409 printf("ahc_intr: AWAITING_MSG for an SCB that "
2410 "does not have a waiting message\n");
2411 printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
2412 devinfo->target_mask);
2413 panic("SCB = %d, SCB Control = %x, MSG_OUT = %x "
2414 "SCB flags = %x", scb->hscb->tag, scb->hscb->control,
2415 ahc_inb(ahc, MSG_OUT), scb->flags);
2416 }
2417
2418
2419
2420
2421
2422 ahc_outb(ahc, SCB_CONTROL, ahc_inb(ahc, SCB_CONTROL) & ~MK_MESSAGE);
2423 scb->hscb->control &= ~MK_MESSAGE;
2424 ahc->msgout_index = 0;
2425 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
2426 }
2427
2428
2429
2430
2431
2432 static void
2433 ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
2434 {
2435
2436
2437
2438
2439
2440 struct ahc_initiator_tinfo *tinfo;
2441 struct ahc_tmode_tstate *tstate;
2442 struct ahc_syncrate *rate;
2443 int dowide;
2444 int dosync;
2445 int doppr;
2446 u_int period;
2447 u_int ppr_options;
2448 u_int offset;
2449
2450 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
2451 devinfo->target, &tstate);
2452
2453
2454
2455
2456
2457
2458 period = tinfo->goal.period;
2459 offset = tinfo->goal.offset;
2460 ppr_options = tinfo->goal.ppr_options;
2461
2462 if (devinfo->role == ROLE_TARGET)
2463 ppr_options = 0;
2464 rate = ahc_devlimited_syncrate(ahc, tinfo, &period,
2465 &ppr_options, devinfo->role);
2466 dowide = tinfo->curr.width != tinfo->goal.width;
2467 dosync = tinfo->curr.offset != offset || tinfo->curr.period != period;
2468
2469
2470
2471
2472
2473 doppr = ppr_options != 0;
2474
2475 if (!dowide && !dosync && !doppr) {
2476 dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;
2477 dosync = tinfo->goal.offset != 0;
2478 }
2479
2480 if (!dowide && !dosync && !doppr) {
2481
2482
2483
2484
2485 if ((ahc->features & AHC_WIDE) != 0)
2486 dowide = 1;
2487 else
2488 dosync = 1;
2489
2490 if (bootverbose) {
2491 ahc_print_devinfo(ahc, devinfo);
2492 printf("Ensuring async\n");
2493 }
2494 }
2495
2496
2497 if (devinfo->role == ROLE_TARGET)
2498 doppr = 0;
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508 if (doppr || (dosync && !dowide)) {
2509
2510 offset = tinfo->goal.offset;
2511 ahc_validate_offset(ahc, tinfo, rate, &offset,
2512 doppr ? tinfo->goal.width
2513 : tinfo->curr.width,
2514 devinfo->role);
2515 if (doppr) {
2516 ahc_construct_ppr(ahc, devinfo, period, offset,
2517 tinfo->goal.width, ppr_options);
2518 } else {
2519 ahc_construct_sdtr(ahc, devinfo, period, offset);
2520 }
2521 } else {
2522 ahc_construct_wdtr(ahc, devinfo, tinfo->goal.width);
2523 }
2524 }
2525
2526
2527
2528
2529
2530 static void
2531 ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2532 u_int period, u_int offset)
2533 {
2534 if (offset == 0)
2535 period = AHC_ASYNC_XFER_PERIOD;
2536 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
2537 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR_LEN;
2538 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_SDTR;
2539 ahc->msgout_buf[ahc->msgout_index++] = period;
2540 ahc->msgout_buf[ahc->msgout_index++] = offset;
2541 ahc->msgout_len += 5;
2542 if (bootverbose) {
2543 printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
2544 ahc_name(ahc), devinfo->channel, devinfo->target,
2545 devinfo->lun, period, offset);
2546 }
2547 }
2548
2549
2550
2551
2552
2553 static void
2554 ahc_construct_wdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2555 u_int bus_width)
2556 {
2557 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
2558 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR_LEN;
2559 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_WDTR;
2560 ahc->msgout_buf[ahc->msgout_index++] = bus_width;
2561 ahc->msgout_len += 4;
2562 if (bootverbose) {
2563 printf("(%s:%c:%d:%d): Sending WDTR %x\n",
2564 ahc_name(ahc), devinfo->channel, devinfo->target,
2565 devinfo->lun, bus_width);
2566 }
2567 }
2568
2569
2570
2571
2572
2573 static void
2574 ahc_construct_ppr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2575 u_int period, u_int offset, u_int bus_width,
2576 u_int ppr_options)
2577 {
2578 if (offset == 0)
2579 period = AHC_ASYNC_XFER_PERIOD;
2580 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXTENDED;
2581 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR_LEN;
2582 ahc->msgout_buf[ahc->msgout_index++] = MSG_EXT_PPR;
2583 ahc->msgout_buf[ahc->msgout_index++] = period;
2584 ahc->msgout_buf[ahc->msgout_index++] = 0;
2585 ahc->msgout_buf[ahc->msgout_index++] = offset;
2586 ahc->msgout_buf[ahc->msgout_index++] = bus_width;
2587 ahc->msgout_buf[ahc->msgout_index++] = ppr_options;
2588 ahc->msgout_len += 8;
2589 if (bootverbose) {
2590 printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
2591 "offset %x, ppr_options %x\n", ahc_name(ahc),
2592 devinfo->channel, devinfo->target, devinfo->lun,
2593 bus_width, period, offset, ppr_options);
2594 }
2595 }
2596
2597
2598
2599
2600 static void
2601 ahc_clear_msg_state(struct ahc_softc *ahc)
2602 {
2603 ahc->msgout_len = 0;
2604 ahc->msgin_index = 0;
2605 ahc->msg_type = MSG_TYPE_NONE;
2606 if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0) {
2607
2608
2609
2610
2611 ahc_outb(ahc, CLRSINT1, CLRATNO);
2612 }
2613 ahc_outb(ahc, MSG_OUT, MSG_NOOP);
2614 ahc_outb(ahc, SEQ_FLAGS2,
2615 ahc_inb(ahc, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
2616 }
2617
2618 static void
2619 ahc_handle_proto_violation(struct ahc_softc *ahc)
2620 {
2621 struct ahc_devinfo devinfo;
2622 struct scb *scb;
2623 u_int scbid;
2624 u_int seq_flags;
2625 u_int curphase;
2626 u_int lastphase;
2627 int found;
2628
2629 ahc_fetch_devinfo(ahc, &devinfo);
2630 scbid = ahc_inb(ahc, SCB_TAG);
2631 scb = ahc_lookup_scb(ahc, scbid);
2632 seq_flags = ahc_inb(ahc, SEQ_FLAGS);
2633 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
2634 lastphase = ahc_inb(ahc, LASTPHASE);
2635 if ((seq_flags & NOT_IDENTIFIED) != 0) {
2636
2637
2638
2639
2640
2641
2642 ahc_print_devinfo(ahc, &devinfo);
2643 printf("Target did not send an IDENTIFY message. "
2644 "LASTPHASE = 0x%x.\n", lastphase);
2645 scb = NULL;
2646 } else if (scb == NULL) {
2647
2648
2649
2650
2651 ahc_print_devinfo(ahc, &devinfo);
2652 printf("No SCB found during protocol violation\n");
2653 goto proto_violation_reset;
2654 } else {
2655 ahc_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
2656 if ((seq_flags & NO_CDB_SENT) != 0) {
2657 ahc_print_path(ahc, scb);
2658 printf("No or incomplete CDB sent to device.\n");
2659 } else if ((ahc_inb(ahc, SCB_CONTROL) & STATUS_RCVD) == 0) {
2660
2661
2662
2663
2664
2665
2666
2667 ahc_print_path(ahc, scb);
2668 printf("Completed command without status.\n");
2669 } else {
2670 ahc_print_path(ahc, scb);
2671 printf("Unknown protocol violation.\n");
2672 ahc_dump_card_state(ahc);
2673 }
2674 }
2675 if ((lastphase & ~P_DATAIN_DT) == 0
2676 || lastphase == P_COMMAND) {
2677 proto_violation_reset:
2678
2679
2680
2681
2682
2683
2684 found = ahc_reset_channel(ahc, 'A', TRUE);
2685 printf("%s: Issued Channel %c Bus Reset. "
2686 "%d SCBs aborted\n", ahc_name(ahc), 'A', found);
2687 } else {
2688
2689
2690
2691
2692
2693 ahc_outb(ahc, SCSISEQ,
2694 ahc_inb(ahc, SCSISEQ) & ~ENSELO);
2695 ahc_assert_atn(ahc);
2696 ahc_outb(ahc, MSG_OUT, HOST_MSG);
2697 if (scb == NULL) {
2698 ahc_print_devinfo(ahc, &devinfo);
2699 ahc->msgout_buf[0] = MSG_ABORT_TASK;
2700 ahc->msgout_len = 1;
2701 ahc->msgout_index = 0;
2702 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
2703 } else {
2704 ahc_print_path(ahc, scb);
2705 scb->flags |= SCB_ABORT;
2706 }
2707 printf("Protocol violation %s. Attempting to abort.\n",
2708 ahc_lookup_phase_entry(curphase)->phasemsg);
2709 }
2710 }
2711
2712
2713
2714
2715 static void
2716 ahc_handle_message_phase(struct ahc_softc *ahc)
2717 {
2718 struct ahc_devinfo devinfo;
2719 u_int bus_phase;
2720 int end_session;
2721
2722 ahc_fetch_devinfo(ahc, &devinfo);
2723 end_session = FALSE;
2724 bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
2725
2726 reswitch:
2727 switch (ahc->msg_type) {
2728 case MSG_TYPE_INITIATOR_MSGOUT:
2729 {
2730 int lastbyte;
2731 int phasemis;
2732 int msgdone;
2733
2734 if (ahc->msgout_len == 0)
2735 panic("HOST_MSG_LOOP interrupt with no active message");
2736
2737 #ifdef AHC_DEBUG
2738 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2739 ahc_print_devinfo(ahc, &devinfo);
2740 printf("INITIATOR_MSG_OUT");
2741 }
2742 #endif
2743 phasemis = bus_phase != P_MESGOUT;
2744 if (phasemis) {
2745 #ifdef AHC_DEBUG
2746 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2747 printf(" PHASEMIS %s\n",
2748 ahc_lookup_phase_entry(bus_phase)
2749 ->phasemsg);
2750 }
2751 #endif
2752 if (bus_phase == P_MESGIN) {
2753
2754
2755
2756
2757
2758
2759 ahc_outb(ahc, CLRSINT1, CLRATNO);
2760 ahc->send_msg_perror = FALSE;
2761 ahc->msg_type = MSG_TYPE_INITIATOR_MSGIN;
2762 ahc->msgin_index = 0;
2763 goto reswitch;
2764 }
2765 end_session = TRUE;
2766 break;
2767 }
2768
2769 if (ahc->send_msg_perror) {
2770 ahc_outb(ahc, CLRSINT1, CLRATNO);
2771 ahc_outb(ahc, CLRSINT1, CLRREQINIT);
2772 #ifdef AHC_DEBUG
2773 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
2774 printf(" byte 0x%x\n", ahc->send_msg_perror);
2775 #endif
2776 ahc_outb(ahc, SCSIDATL, MSG_PARITY_ERROR);
2777 break;
2778 }
2779
2780 msgdone = ahc->msgout_index == ahc->msgout_len;
2781 if (msgdone) {
2782
2783
2784
2785
2786
2787 ahc->msgout_index = 0;
2788 ahc_assert_atn(ahc);
2789 }
2790
2791 lastbyte = ahc->msgout_index == (ahc->msgout_len - 1);
2792 if (lastbyte) {
2793
2794 ahc_outb(ahc, CLRSINT1, CLRATNO);
2795 }
2796
2797
2798
2799
2800
2801 ahc_outb(ahc, CLRSINT1, CLRREQINIT);
2802 #ifdef AHC_DEBUG
2803 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
2804 printf(" byte 0x%x\n",
2805 ahc->msgout_buf[ahc->msgout_index]);
2806 #endif
2807 ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
2808 break;
2809 }
2810 case MSG_TYPE_INITIATOR_MSGIN:
2811 {
2812 int phasemis;
2813 int message_done;
2814
2815 #ifdef AHC_DEBUG
2816 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2817 ahc_print_devinfo(ahc, &devinfo);
2818 printf("INITIATOR_MSG_IN");
2819 }
2820 #endif
2821 phasemis = bus_phase != P_MESGIN;
2822 if (phasemis) {
2823 #ifdef AHC_DEBUG
2824 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2825 printf(" PHASEMIS %s\n",
2826 ahc_lookup_phase_entry(bus_phase)
2827 ->phasemsg);
2828 }
2829 #endif
2830 ahc->msgin_index = 0;
2831 if (bus_phase == P_MESGOUT
2832 && (ahc->send_msg_perror == TRUE
2833 || (ahc->msgout_len != 0
2834 && ahc->msgout_index == 0))) {
2835 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
2836 goto reswitch;
2837 }
2838 end_session = TRUE;
2839 break;
2840 }
2841
2842
2843 ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIBUSL);
2844 #ifdef AHC_DEBUG
2845 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
2846 printf(" byte 0x%x\n",
2847 ahc->msgin_buf[ahc->msgin_index]);
2848 #endif
2849
2850 message_done = ahc_parse_msg(ahc, &devinfo);
2851
2852 if (message_done) {
2853
2854
2855
2856
2857 ahc->msgin_index = 0;
2858
2859
2860
2861
2862
2863
2864 if (ahc->msgout_len != 0) {
2865 #ifdef AHC_DEBUG
2866 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
2867 ahc_print_devinfo(ahc, &devinfo);
2868 printf("Asserting ATN for response\n");
2869 }
2870 #endif
2871 ahc_assert_atn(ahc);
2872 }
2873 } else
2874 ahc->msgin_index++;
2875
2876 if (message_done == MSGLOOP_TERMINATED) {
2877 end_session = TRUE;
2878 } else {
2879
2880 ahc_outb(ahc, CLRSINT1, CLRREQINIT);
2881 ahc_inb(ahc, SCSIDATL);
2882 }
2883 break;
2884 }
2885 case MSG_TYPE_TARGET_MSGIN:
2886 {
2887 int msgdone;
2888 int msgout_request;
2889
2890 if (ahc->msgout_len == 0)
2891 panic("Target MSGIN with no active message");
2892
2893
2894
2895
2896
2897
2898
2899 if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0
2900 && ahc->msgout_index > 0)
2901 msgout_request = TRUE;
2902 else
2903 msgout_request = FALSE;
2904
2905 if (msgout_request) {
2906
2907
2908
2909
2910
2911
2912
2913 ahc->msg_type = MSG_TYPE_TARGET_MSGOUT;
2914 ahc_outb(ahc, SCSISIGO, P_MESGOUT | BSYO);
2915 ahc->msgin_index = 0;
2916
2917 ahc_inb(ahc, SCSIDATL);
2918 ahc_outb(ahc, SXFRCTL0,
2919 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
2920 break;
2921 }
2922
2923 msgdone = ahc->msgout_index == ahc->msgout_len;
2924 if (msgdone) {
2925 ahc_outb(ahc, SXFRCTL0,
2926 ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
2927 end_session = TRUE;
2928 break;
2929 }
2930
2931
2932
2933
2934 ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) | SPIOEN);
2935 ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
2936 break;
2937 }
2938 case MSG_TYPE_TARGET_MSGOUT:
2939 {
2940 int lastbyte;
2941 int msgdone;
2942
2943
2944
2945
2946
2947 lastbyte = (ahc_inb(ahc, SCSISIGI) & ATNI) == 0;
2948
2949
2950
2951
2952
2953
2954 ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
2955 ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIDATL);
2956 msgdone = ahc_parse_msg(ahc, &devinfo);
2957 if (msgdone == MSGLOOP_TERMINATED) {
2958
2959
2960
2961
2962
2963
2964 return;
2965 }
2966
2967 ahc->msgin_index++;
2968
2969
2970
2971
2972
2973 if (msgdone == MSGLOOP_MSGCOMPLETE) {
2974 ahc->msgin_index = 0;
2975
2976
2977
2978
2979
2980 if (ahc->msgout_len != 0) {
2981 ahc_outb(ahc, SCSISIGO, P_MESGIN | BSYO);
2982 ahc_outb(ahc, SXFRCTL0,
2983 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
2984 ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
2985 ahc->msgin_index = 0;
2986 break;
2987 }
2988 }
2989
2990 if (lastbyte)
2991 end_session = TRUE;
2992 else {
2993
2994 ahc_outb(ahc, SXFRCTL0,
2995 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
2996 }
2997
2998 break;
2999 }
3000 default:
3001 panic("Unknown REQINIT message type");
3002 }
3003
3004 if (end_session) {
3005 ahc_clear_msg_state(ahc);
3006 ahc_outb(ahc, RETURN_1, EXIT_MSG_LOOP);
3007 } else
3008 ahc_outb(ahc, RETURN_1, CONT_MSG_LOOP);
3009 }
3010
3011
3012
3013
3014
3015
3016
3017 static int
3018 ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type, u_int msgval, int full)
3019 {
3020 int found;
3021 u_int index;
3022
3023 found = FALSE;
3024 index = 0;
3025
3026 while (index < ahc->msgout_len) {
3027 if (ahc->msgout_buf[index] == MSG_EXTENDED) {
3028 u_int end_index;
3029
3030 end_index = index + 1 + ahc->msgout_buf[index + 1];
3031 if (ahc->msgout_buf[index+2] == msgval
3032 && type == AHCMSG_EXT) {
3033
3034 if (full) {
3035 if (ahc->msgout_index > end_index)
3036 found = TRUE;
3037 } else if (ahc->msgout_index > index)
3038 found = TRUE;
3039 }
3040 index = end_index;
3041 } else if (ahc->msgout_buf[index] >= MSG_SIMPLE_TASK
3042 && ahc->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
3043
3044
3045 index += 2;
3046 } else {
3047
3048 if (type == AHCMSG_1B
3049 && ahc->msgout_buf[index] == msgval
3050 && ahc->msgout_index > index)
3051 found = TRUE;
3052 index++;
3053 }
3054
3055 if (found)
3056 break;
3057 }
3058 return (found);
3059 }
3060
3061
3062
3063
3064 static int
3065 ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
3066 {
3067 struct ahc_initiator_tinfo *tinfo;
3068 struct ahc_tmode_tstate *tstate;
3069 int reject;
3070 int done;
3071 int response;
3072 u_int targ_scsirate;
3073
3074 done = MSGLOOP_IN_PROG;
3075 response = FALSE;
3076 reject = FALSE;
3077 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
3078 devinfo->target, &tstate);
3079 targ_scsirate = tinfo->scsirate;
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092 switch (ahc->msgin_buf[0]) {
3093 case MSG_DISCONNECT:
3094 case MSG_SAVEDATAPOINTER:
3095 case MSG_CMDCOMPLETE:
3096 case MSG_RESTOREPOINTERS:
3097 case MSG_IGN_WIDE_RESIDUE:
3098
3099
3100
3101
3102 done = MSGLOOP_TERMINATED;
3103 break;
3104 case MSG_MESSAGE_REJECT:
3105 response = ahc_handle_msg_reject(ahc, devinfo);
3106
3107 case MSG_NOOP:
3108 done = MSGLOOP_MSGCOMPLETE;
3109 break;
3110 case MSG_EXTENDED:
3111 {
3112
3113 if (ahc->msgin_index < 2)
3114 break;
3115 switch (ahc->msgin_buf[2]) {
3116 case MSG_EXT_SDTR:
3117 {
3118 struct ahc_syncrate *syncrate;
3119 u_int period;
3120 u_int ppr_options;
3121 u_int offset;
3122 u_int saved_offset;
3123
3124 if (ahc->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
3125 reject = TRUE;
3126 break;
3127 }
3128
3129
3130
3131
3132
3133
3134
3135
3136 if (ahc->msgin_index < (MSG_EXT_SDTR_LEN + 1))
3137 break;
3138
3139 period = ahc->msgin_buf[3];
3140 ppr_options = 0;
3141 saved_offset = offset = ahc->msgin_buf[4];
3142 syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,
3143 &ppr_options,
3144 devinfo->role);
3145 ahc_validate_offset(ahc, tinfo, syncrate, &offset,
3146 targ_scsirate & WIDEXFER,
3147 devinfo->role);
3148 if (bootverbose) {
3149 printf("(%s:%c:%d:%d): Received "
3150 "SDTR period %x, offset %x\n\t"
3151 "Filtered to period %x, offset %x\n",
3152 ahc_name(ahc), devinfo->channel,
3153 devinfo->target, devinfo->lun,
3154 ahc->msgin_buf[3], saved_offset,
3155 period, offset);
3156 }
3157 ahc_set_syncrate(ahc, devinfo,
3158 syncrate, period,
3159 offset, ppr_options,
3160 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3161 TRUE);
3162
3163
3164
3165
3166
3167
3168 if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_SDTR, TRUE)) {
3169
3170 if (saved_offset != offset) {
3171
3172 reject = TRUE;
3173 }
3174 } else {
3175
3176
3177
3178 if (bootverbose
3179 && devinfo->role == ROLE_INITIATOR) {
3180 printf("(%s:%c:%d:%d): Target "
3181 "Initiated SDTR\n",
3182 ahc_name(ahc), devinfo->channel,
3183 devinfo->target, devinfo->lun);
3184 }
3185 ahc->msgout_index = 0;
3186 ahc->msgout_len = 0;
3187 ahc_construct_sdtr(ahc, devinfo,
3188 period, offset);
3189 ahc->msgout_index = 0;
3190 response = TRUE;
3191 }
3192 done = MSGLOOP_MSGCOMPLETE;
3193 break;
3194 }
3195 case MSG_EXT_WDTR:
3196 {
3197 u_int bus_width;
3198 u_int saved_width;
3199 u_int sending_reply;
3200
3201 sending_reply = FALSE;
3202 if (ahc->msgin_buf[1] != MSG_EXT_WDTR_LEN) {
3203 reject = TRUE;
3204 break;
3205 }
3206
3207
3208
3209
3210
3211
3212
3213
3214 if (ahc->msgin_index < (MSG_EXT_WDTR_LEN + 1))
3215 break;
3216
3217 bus_width = ahc->msgin_buf[3];
3218 saved_width = bus_width;
3219 ahc_validate_width(ahc, tinfo, &bus_width,
3220 devinfo->role);
3221 if (bootverbose) {
3222 printf("(%s:%c:%d:%d): Received WDTR "
3223 "%x filtered to %x\n",
3224 ahc_name(ahc), devinfo->channel,
3225 devinfo->target, devinfo->lun,
3226 saved_width, bus_width);
3227 }
3228
3229 if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, TRUE)) {
3230
3231
3232
3233
3234
3235
3236 if (saved_width > bus_width) {
3237 reject = TRUE;
3238 printf("(%s:%c:%d:%d): requested %dBit "
3239 "transfers. Rejecting...\n",
3240 ahc_name(ahc), devinfo->channel,
3241 devinfo->target, devinfo->lun,
3242 8 * (0x01 << bus_width));
3243 bus_width = 0;
3244 }
3245 } else {
3246
3247
3248
3249 if (bootverbose
3250 && devinfo->role == ROLE_INITIATOR) {
3251 printf("(%s:%c:%d:%d): Target "
3252 "Initiated WDTR\n",
3253 ahc_name(ahc), devinfo->channel,
3254 devinfo->target, devinfo->lun);
3255 }
3256 ahc->msgout_index = 0;
3257 ahc->msgout_len = 0;
3258 ahc_construct_wdtr(ahc, devinfo, bus_width);
3259 ahc->msgout_index = 0;
3260 response = TRUE;
3261 sending_reply = TRUE;
3262 }
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272 ahc_update_neg_request(ahc, devinfo, tstate,
3273 tinfo, AHC_NEG_ALWAYS);
3274 ahc_set_width(ahc, devinfo, bus_width,
3275 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3276 TRUE);
3277 if (sending_reply == FALSE && reject == FALSE) {
3278
3279
3280
3281
3282 ahc->msgout_index = 0;
3283 ahc->msgout_len = 0;
3284 ahc_build_transfer_msg(ahc, devinfo);
3285 ahc->msgout_index = 0;
3286 response = TRUE;
3287 }
3288 done = MSGLOOP_MSGCOMPLETE;
3289 break;
3290 }
3291 case MSG_EXT_PPR:
3292 {
3293 struct ahc_syncrate *syncrate;
3294 u_int period;
3295 u_int offset;
3296 u_int bus_width;
3297 u_int ppr_options;
3298 u_int saved_width;
3299 u_int saved_offset;
3300 u_int saved_ppr_options;
3301
3302 if (ahc->msgin_buf[1] != MSG_EXT_PPR_LEN) {
3303 reject = TRUE;
3304 break;
3305 }
3306
3307
3308
3309
3310
3311
3312
3313
3314 if (ahc->msgin_index < (MSG_EXT_PPR_LEN + 1))
3315 break;
3316
3317 period = ahc->msgin_buf[3];
3318 offset = ahc->msgin_buf[5];
3319 bus_width = ahc->msgin_buf[6];
3320 saved_width = bus_width;
3321 ppr_options = ahc->msgin_buf[7];
3322
3323
3324
3325
3326
3327 if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 0
3328 && period == 9)
3329 offset = 0;
3330 saved_ppr_options = ppr_options;
3331 saved_offset = offset;
3332
3333
3334
3335
3336
3337
3338 ppr_options &= MSG_EXT_PPR_DT_REQ;
3339 if (bus_width == 0)
3340 ppr_options = 0;
3341
3342 ahc_validate_width(ahc, tinfo, &bus_width,
3343 devinfo->role);
3344 syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,
3345 &ppr_options,
3346 devinfo->role);
3347 ahc_validate_offset(ahc, tinfo, syncrate,
3348 &offset, bus_width,
3349 devinfo->role);
3350
3351 if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_PPR, TRUE)) {
3352
3353
3354
3355
3356
3357 if (saved_width > bus_width
3358 || saved_offset != offset
3359 || saved_ppr_options != ppr_options) {
3360 reject = TRUE;
3361 period = 0;
3362 offset = 0;
3363 bus_width = 0;
3364 ppr_options = 0;
3365 syncrate = NULL;
3366 }
3367 } else {
3368 if (devinfo->role != ROLE_TARGET)
3369 printf("(%s:%c:%d:%d): Target "
3370 "Initiated PPR\n",
3371 ahc_name(ahc), devinfo->channel,
3372 devinfo->target, devinfo->lun);
3373 else
3374 printf("(%s:%c:%d:%d): Initiator "
3375 "Initiated PPR\n",
3376 ahc_name(ahc), devinfo->channel,
3377 devinfo->target, devinfo->lun);
3378 ahc->msgout_index = 0;
3379 ahc->msgout_len = 0;
3380 ahc_construct_ppr(ahc, devinfo, period, offset,
3381 bus_width, ppr_options);
3382 ahc->msgout_index = 0;
3383 response = TRUE;
3384 }
3385 if (bootverbose) {
3386 printf("(%s:%c:%d:%d): Received PPR width %x, "
3387 "period %x, offset %x,options %x\n"
3388 "\tFiltered to width %x, period %x, "
3389 "offset %x, options %x\n",
3390 ahc_name(ahc), devinfo->channel,
3391 devinfo->target, devinfo->lun,
3392 saved_width, ahc->msgin_buf[3],
3393 saved_offset, saved_ppr_options,
3394 bus_width, period, offset, ppr_options);
3395 }
3396 ahc_set_width(ahc, devinfo, bus_width,
3397 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3398 TRUE);
3399 ahc_set_syncrate(ahc, devinfo,
3400 syncrate, period,
3401 offset, ppr_options,
3402 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3403 TRUE);
3404 done = MSGLOOP_MSGCOMPLETE;
3405 break;
3406 }
3407 default:
3408
3409 reject = TRUE;
3410 break;
3411 }
3412 break;
3413 }
3414 #ifdef AHC_TARGET_MODE
3415 case MSG_BUS_DEV_RESET:
3416 ahc_handle_devreset(ahc, devinfo,
3417 CAM_BDR_SENT,
3418 "Bus Device Reset Received",
3419 0);
3420 ahc_restart(ahc);
3421 done = MSGLOOP_TERMINATED;
3422 break;
3423 case MSG_ABORT_TAG:
3424 case MSG_ABORT:
3425 case MSG_CLEAR_QUEUE:
3426 {
3427 int tag;
3428
3429
3430 if (devinfo->role != ROLE_TARGET) {
3431 reject = TRUE;
3432 break;
3433 }
3434 tag = SCB_LIST_NULL;
3435 if (ahc->msgin_buf[0] == MSG_ABORT_TAG)
3436 tag = ahc_inb(ahc, INITIATOR_TAG);
3437 ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
3438 devinfo->lun, tag, ROLE_TARGET,
3439 CAM_REQ_ABORTED);
3440
3441 tstate = ahc->enabled_targets[devinfo->our_scsiid];
3442 if (tstate != NULL) {
3443 struct ahc_tmode_lstate* lstate;
3444
3445 lstate = tstate->enabled_luns[devinfo->lun];
3446 if (lstate != NULL) {
3447 ahc_queue_lstate_event(ahc, lstate,
3448 devinfo->our_scsiid,
3449 ahc->msgin_buf[0],
3450 tag);
3451 ahc_send_lstate_events(ahc, lstate);
3452 }
3453 }
3454 ahc_restart(ahc);
3455 done = MSGLOOP_TERMINATED;
3456 break;
3457 }
3458 #endif
3459 case MSG_TERM_IO_PROC:
3460 default:
3461 reject = TRUE;
3462 break;
3463 }
3464
3465 if (reject) {
3466
3467
3468
3469 ahc->msgout_index = 0;
3470 ahc->msgout_len = 1;
3471 ahc->msgout_buf[0] = MSG_MESSAGE_REJECT;
3472 done = MSGLOOP_MSGCOMPLETE;
3473 response = TRUE;
3474 }
3475
3476 if (done != MSGLOOP_IN_PROG && !response)
3477
3478 ahc->msgout_len = 0;
3479
3480 return (done);
3481 }
3482
3483
3484
3485
3486 static int
3487 ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
3488 {
3489
3490
3491
3492
3493
3494
3495 struct scb *scb;
3496 struct ahc_initiator_tinfo *tinfo;
3497 struct ahc_tmode_tstate *tstate;
3498 u_int scb_index;
3499 u_int last_msg;
3500 int response = 0;
3501
3502 scb_index = ahc_inb(ahc, SCB_TAG);
3503 scb = ahc_lookup_scb(ahc, scb_index);
3504 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,
3505 devinfo->our_scsiid,
3506 devinfo->target, &tstate);
3507
3508 last_msg = ahc_inb(ahc, LAST_MSG);
3509
3510 if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_PPR, FALSE)) {
3511
3512
3513
3514
3515 if (bootverbose) {
3516 printf("(%s:%c:%d:%d): PPR Rejected. "
3517 "Trying WDTR/SDTR\n",
3518 ahc_name(ahc), devinfo->channel,
3519 devinfo->target, devinfo->lun);
3520 }
3521 tinfo->goal.ppr_options = 0;
3522 tinfo->curr.transport_version = 2;
3523 tinfo->goal.transport_version = 2;
3524 ahc->msgout_index = 0;
3525 ahc->msgout_len = 0;
3526 ahc_build_transfer_msg(ahc, devinfo);
3527 ahc->msgout_index = 0;
3528 response = 1;
3529 } else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, FALSE)) {
3530
3531
3532 printf("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
3533 "8bit transfers\n", ahc_name(ahc),
3534 devinfo->channel, devinfo->target, devinfo->lun);
3535 ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
3536 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3537 TRUE);
3538
3539
3540
3541
3542
3543
3544
3545 if (tinfo->goal.offset != tinfo->curr.offset) {
3546
3547
3548 ahc->msgout_index = 0;
3549 ahc->msgout_len = 0;
3550 ahc_build_transfer_msg(ahc, devinfo);
3551 ahc->msgout_index = 0;
3552 response = 1;
3553 }
3554 } else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_SDTR, FALSE)) {
3555
3556 ahc_set_syncrate(ahc, devinfo, NULL, 0,
3557 0, 0,
3558 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3559 TRUE);
3560 printf("(%s:%c:%d:%d): refuses synchronous negotiation. "
3561 "Using asynchronous transfers\n",
3562 ahc_name(ahc), devinfo->channel,
3563 devinfo->target, devinfo->lun);
3564 } else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) {
3565 int tag_type;
3566 int mask;
3567
3568 tag_type = (scb->hscb->control & MSG_SIMPLE_TASK);
3569
3570 if (tag_type == MSG_SIMPLE_TASK) {
3571 printf("(%s:%c:%d:%d): refuses tagged commands. "
3572 "Performing non-tagged I/O\n", ahc_name(ahc),
3573 devinfo->channel, devinfo->target, devinfo->lun);
3574 ahc_set_tags(ahc, devinfo, AHC_QUEUE_NONE);
3575 mask = ~0x23;
3576 } else {
3577 printf("(%s:%c:%d:%d): refuses %s tagged commands. "
3578 "Performing simple queue tagged I/O only\n",
3579 ahc_name(ahc), devinfo->channel, devinfo->target,
3580 devinfo->lun, tag_type == MSG_ORDERED_TASK
3581 ? "ordered" : "head of queue");
3582 ahc_set_tags(ahc, devinfo, AHC_QUEUE_BASIC);
3583 mask = ~0x03;
3584 }
3585
3586
3587
3588
3589
3590 ahc_outb(ahc, SCB_CONTROL,
3591 ahc_inb(ahc, SCB_CONTROL) & mask);
3592 scb->hscb->control &= mask;
3593 ahc_set_transaction_tag(scb, FALSE,
3594 MSG_SIMPLE_TASK);
3595 ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);
3596 ahc_assert_atn(ahc);
3597
3598
3599
3600
3601
3602 if ((ahc->flags & AHC_SCB_BTT) == 0) {
3603 struct scb_tailq *untagged_q;
3604
3605 untagged_q =
3606 &(ahc->untagged_queues[devinfo->target_offset]);
3607 TAILQ_INSERT_HEAD(untagged_q, scb, links.tqe);
3608 scb->flags |= SCB_UNTAGGEDQ;
3609 }
3610 ahc_busy_tcl(ahc, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
3611 scb->hscb->tag);
3612
3613
3614
3615
3616
3617
3618 ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
3619 SCB_GET_CHANNEL(ahc, scb),
3620 SCB_GET_LUN(scb), SCB_LIST_NULL,
3621 ROLE_INITIATOR, CAM_REQUEUE_REQ,
3622 SEARCH_COMPLETE);
3623 } else {
3624
3625
3626
3627 printf("%s:%c:%d: Message reject for %x -- ignored\n",
3628 ahc_name(ahc), devinfo->channel, devinfo->target,
3629 last_msg);
3630 }
3631 return (response);
3632 }
3633
3634
3635
3636
3637 static void
3638 ahc_handle_ign_wide_residue(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
3639 {
3640 u_int scb_index;
3641 struct scb *scb;
3642
3643 scb_index = ahc_inb(ahc, SCB_TAG);
3644 scb = ahc_lookup_scb(ahc, scb_index);
3645
3646
3647
3648
3649 if ((ahc_inb(ahc, SEQ_FLAGS) & DPHASE) == 0
3650 || ahc_get_transfer_dir(scb) != CAM_DIR_IN) {
3651
3652
3653
3654
3655 } else {
3656
3657
3658
3659
3660
3661
3662
3663 uint32_t sgptr;
3664
3665 sgptr = ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
3666 if ((sgptr & SG_LIST_NULL) != 0
3667 && (ahc_inb(ahc, SCB_LUN) & SCB_XFERLEN_ODD) != 0) {
3668
3669
3670
3671
3672
3673
3674 } else {
3675 struct ahc_dma_seg *sg;
3676 uint32_t data_cnt;
3677 uint32_t data_addr;
3678 uint32_t sglen;
3679
3680
3681 sgptr = ahc_inl(ahc, SCB_RESIDUAL_SGPTR);
3682 data_cnt = ahc_inl(ahc, SCB_RESIDUAL_DATACNT);
3683
3684 if ((sgptr & SG_LIST_NULL) != 0) {
3685
3686
3687
3688
3689
3690 data_cnt &= ~AHC_SG_LEN_MASK;
3691 }
3692
3693 data_addr = ahc_inl(ahc, SHADDR);
3694
3695 data_cnt += 1;
3696 data_addr -= 1;
3697 sgptr &= SG_PTR_MASK;
3698
3699 sg = ahc_sg_bus_to_virt(scb, sgptr);
3700
3701
3702
3703
3704
3705 sg--;
3706 sglen = aic_le32toh(sg->len) & AHC_SG_LEN_MASK;
3707 if (sg != scb->sg_list
3708 && sglen < (data_cnt & AHC_SG_LEN_MASK)) {
3709
3710 sg--;
3711 sglen = aic_le32toh(sg->len);
3712
3713
3714
3715
3716 data_cnt = 1 | (sglen & (~AHC_SG_LEN_MASK));
3717 data_addr = aic_le32toh(sg->addr)
3718 + (sglen & AHC_SG_LEN_MASK) - 1;
3719
3720
3721
3722
3723
3724 sg++;
3725 sgptr = ahc_sg_virt_to_bus(scb, sg);
3726 }
3727 ahc_outl(ahc, SCB_RESIDUAL_SGPTR, sgptr);
3728 ahc_outl(ahc, SCB_RESIDUAL_DATACNT, data_cnt);
3729
3730
3731
3732
3733
3734
3735 ahc_outb(ahc, SCB_LUN,
3736 ahc_inb(ahc, SCB_LUN) ^ SCB_XFERLEN_ODD);
3737 }
3738 }
3739 }
3740
3741
3742
3743
3744
3745
3746 static void
3747 ahc_reinitialize_dataptrs(struct ahc_softc *ahc)
3748 {
3749 struct scb *scb;
3750 struct ahc_dma_seg *sg;
3751 u_int scb_index;
3752 uint32_t sgptr;
3753 uint32_t resid;
3754 uint32_t dataptr;
3755
3756 scb_index = ahc_inb(ahc, SCB_TAG);
3757 scb = ahc_lookup_scb(ahc, scb_index);
3758 sgptr = (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 3) << 24)
3759 | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 2) << 16)
3760 | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 1) << 8)
3761 | ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
3762
3763 sgptr &= SG_PTR_MASK;
3764 sg = ahc_sg_bus_to_virt(scb, sgptr);
3765
3766
3767 sg--;
3768
3769 resid = (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 2) << 16)
3770 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 1) << 8)
3771 | ahc_inb(ahc, SCB_RESIDUAL_DATACNT);
3772
3773 dataptr = aic_le32toh(sg->addr)
3774 + (aic_le32toh(sg->len) & AHC_SG_LEN_MASK)
3775 - resid;
3776 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
3777 u_int dscommand1;
3778
3779 dscommand1 = ahc_inb(ahc, DSCOMMAND1);
3780 ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
3781 ahc_outb(ahc, HADDR,
3782 (aic_le32toh(sg->len) >> 24) & SG_HIGH_ADDR_BITS);
3783 ahc_outb(ahc, DSCOMMAND1, dscommand1);
3784 }
3785 ahc_outb(ahc, HADDR + 3, dataptr >> 24);
3786 ahc_outb(ahc, HADDR + 2, dataptr >> 16);
3787 ahc_outb(ahc, HADDR + 1, dataptr >> 8);
3788 ahc_outb(ahc, HADDR, dataptr);
3789 ahc_outb(ahc, HCNT + 2, resid >> 16);
3790 ahc_outb(ahc, HCNT + 1, resid >> 8);
3791 ahc_outb(ahc, HCNT, resid);
3792 if ((ahc->features & AHC_ULTRA2) == 0) {
3793 ahc_outb(ahc, STCNT + 2, resid >> 16);
3794 ahc_outb(ahc, STCNT + 1, resid >> 8);
3795 ahc_outb(ahc, STCNT, resid);
3796 }
3797 }
3798
3799
3800
3801
3802 static void
3803 ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
3804 cam_status status, char *message, int verbose_level)
3805 {
3806 #ifdef AHC_TARGET_MODE
3807 struct ahc_tmode_tstate* tstate;
3808 u_int lun;
3809 #endif
3810 int found;
3811
3812 found = ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
3813 CAM_LUN_WILDCARD, SCB_LIST_NULL, devinfo->role,
3814 status);
3815
3816 #ifdef AHC_TARGET_MODE
3817
3818
3819
3820
3821 tstate = ahc->enabled_targets[devinfo->our_scsiid];
3822 if (tstate != NULL) {
3823 for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
3824 struct ahc_tmode_lstate* lstate;
3825
3826 lstate = tstate->enabled_luns[lun];
3827 if (lstate == NULL)
3828 continue;
3829
3830 ahc_queue_lstate_event(ahc, lstate, devinfo->our_scsiid,
3831 MSG_BUS_DEV_RESET, 0);
3832 ahc_send_lstate_events(ahc, lstate);
3833 }
3834 }
3835 #endif
3836
3837
3838
3839
3840 ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
3841 AHC_TRANS_CUR, TRUE);
3842 ahc_set_syncrate(ahc, devinfo, NULL,
3843 0, 0, 0,
3844 AHC_TRANS_CUR, TRUE);
3845
3846 if (status != CAM_SEL_TIMEOUT)
3847 ahc_send_async(ahc, devinfo->channel, devinfo->target,
3848 CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
3849
3850 if (message != NULL
3851 && (verbose_level <= bootverbose))
3852 printf("%s: %s on %c:%d. %d SCBs aborted\n", ahc_name(ahc),
3853 message, devinfo->channel, devinfo->target, found);
3854 }
3855
3856 #ifdef AHC_TARGET_MODE
3857 static void
3858 ahc_setup_target_msgin(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
3859 struct scb *scb)
3860 {
3861
3862
3863
3864
3865
3866
3867 ahc->msgout_index = 0;
3868 ahc->msgout_len = 0;
3869
3870 if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0)
3871 ahc_build_transfer_msg(ahc, devinfo);
3872 else
3873 panic("ahc_intr: AWAITING target message with no message");
3874
3875 ahc->msgout_index = 0;
3876 ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
3877 }
3878 #endif
3879
3880 int
3881 ahc_softc_init(struct ahc_softc *ahc)
3882 {
3883
3884
3885 if ((ahc->chip & AHC_PCI) == 0)
3886 ahc->unpause = ahc_inb(ahc, HCNTRL) & IRQMS;
3887 else
3888 ahc->unpause = 0;
3889 ahc->pause = ahc->unpause | PAUSE;
3890
3891 if (ahc->scb_data == NULL) {
3892 ahc->scb_data = malloc(sizeof(*ahc->scb_data),
3893 M_DEVBUF, M_NOWAIT);
3894 if (ahc->scb_data == NULL)
3895 return (ENOMEM);
3896 memset(ahc->scb_data, 0, sizeof(*ahc->scb_data));
3897 }
3898
3899 return (0);
3900 }
3901
3902 void
3903 ahc_softc_insert(struct ahc_softc *ahc)
3904 {
3905 struct ahc_softc *list_ahc;
3906
3907 #if AHC_PCI_CONFIG > 0
3908
3909
3910
3911
3912 if ((ahc->chip & AHC_BUS_MASK) == AHC_PCI
3913 && (ahc->features & AHC_MULTI_FUNC) != 0) {
3914 TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
3915 ahc_dev_softc_t list_pci;
3916 ahc_dev_softc_t pci;
3917
3918 list_pci = list_ahc->dev_softc;
3919 pci = ahc->dev_softc;
3920 if (ahc_get_pci_slot(list_pci) == ahc_get_pci_slot(pci)
3921 && ahc_get_pci_bus(list_pci) == ahc_get_pci_bus(pci)) {
3922 struct ahc_softc *master;
3923 struct ahc_softc *slave;
3924
3925 if (ahc_get_pci_function(list_pci) == 0) {
3926 master = list_ahc;
3927 slave = ahc;
3928 } else {
3929 master = ahc;
3930 slave = list_ahc;
3931 }
3932 slave->flags &= ~AHC_BIOS_ENABLED;
3933 slave->flags |=
3934 master->flags & AHC_BIOS_ENABLED;
3935 slave->flags &= ~AHC_PRIMARY_CHANNEL;
3936 slave->flags |=
3937 master->flags & AHC_PRIMARY_CHANNEL;
3938 break;
3939 }
3940 }
3941 }
3942 #endif
3943
3944
3945
3946
3947 list_ahc = TAILQ_FIRST(&ahc_tailq);
3948 while (list_ahc != NULL
3949 && ahc_softc_comp(ahc, list_ahc) <= 0)
3950 list_ahc = TAILQ_NEXT(list_ahc, links);
3951 if (list_ahc != NULL)
3952 TAILQ_INSERT_BEFORE(list_ahc, ahc, links);
3953 else
3954 TAILQ_INSERT_TAIL(&ahc_tailq, ahc, links);
3955 ahc->init_level++;
3956 }
3957
3958 void
3959 ahc_set_unit(struct ahc_softc *ahc, int unit)
3960 {
3961 ahc->unit = unit;
3962 }
3963
3964 void
3965 ahc_set_name(struct ahc_softc *ahc, char *name)
3966 {
3967 if (ahc->name != NULL)
3968 free(ahc->name, M_DEVBUF);
3969 ahc->name = name;
3970 }
3971
3972 void
3973 ahc_free(struct ahc_softc *ahc)
3974 {
3975 int i;
3976
3977 switch (ahc->init_level) {
3978 default:
3979 case 2:
3980 ahc_shutdown(ahc);
3981
3982 case 1:
3983 bus_dmamap_unload(ahc->parent_dmat, ahc->shared_data_dmamap);
3984 bus_dmamap_destroy(ahc->parent_dmat, ahc->shared_data_dmamap);
3985 bus_dmamem_unmap(ahc->parent_dmat, (caddr_t)ahc->qoutfifo, ahc->shared_data_size);
3986 bus_dmamem_free(ahc->parent_dmat, &ahc->shared_data_seg, ahc->shared_data_nseg);
3987 break;
3988 case 0:
3989 break;
3990 }
3991
3992 ahc_platform_free(ahc);
3993 ahc_fini_scbdata(ahc);
3994 for (i = 0; i < AHC_NUM_TARGETS; i++) {
3995 struct ahc_tmode_tstate *tstate;
3996
3997 tstate = ahc->enabled_targets[i];
3998 if (tstate != NULL) {
3999 #ifdef AHC_TARGET_MODE
4000 int j;
4001
4002 for (j = 0; j < AHC_NUM_LUNS; j++) {
4003 struct ahc_tmode_lstate *lstate;
4004
4005 lstate = tstate->enabled_luns[j];
4006 if (lstate != NULL) {
4007
4008 free(lstate, M_DEVBUF);
4009 }
4010 }
4011 #endif
4012 free(tstate, M_DEVBUF);
4013 }
4014 }
4015 #ifdef AHC_TARGET_MODE
4016 if (ahc->black_hole != NULL) {
4017
4018 free(ahc->black_hole, M_DEVBUF);
4019 }
4020 #endif
4021 #ifndef __NetBSD__
4022 if (ahc->name != NULL)
4023 free(ahc->name, M_DEVBUF);
4024 #endif
4025 if (ahc->seep_config != NULL)
4026 free(ahc->seep_config, M_DEVBUF);
4027 #ifndef __FreeBSD__
4028 free(ahc, M_DEVBUF);
4029 #endif
4030 return;
4031 }
4032
4033 void
4034 ahc_shutdown(void *arg)
4035 {
4036 struct ahc_softc *ahc;
4037 int i;
4038
4039 ahc = (struct ahc_softc *)arg;
4040
4041
4042 ahc_reset(ahc, FALSE);
4043 ahc_outb(ahc, SCSISEQ, 0);
4044 ahc_outb(ahc, SXFRCTL0, 0);
4045 ahc_outb(ahc, DSPCISTATUS, 0);
4046
4047 for (i = TARG_SCSIRATE; i < SCSICONF; i++)
4048 ahc_outb(ahc, i, 0);
4049 }
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060 int
4061 ahc_reset(struct ahc_softc *ahc, int reinit)
4062 {
4063 u_int sblkctl;
4064 u_int sxfrctl1_a, sxfrctl1_b;
4065 int error;
4066 int wait;
4067
4068
4069
4070
4071
4072
4073 ahc_pause(ahc);
4074 sxfrctl1_b = 0;
4075 if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) {
4076 u_int sblkctl;
4077
4078
4079
4080
4081
4082 sblkctl = ahc_inb(ahc, SBLKCTL);
4083 ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
4084 sxfrctl1_b = ahc_inb(ahc, SXFRCTL1);
4085 ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
4086 }
4087 sxfrctl1_a = ahc_inb(ahc, SXFRCTL1);
4088
4089 ahc_outb(ahc, HCNTRL, CHIPRST | ahc->pause);
4090
4091
4092
4093
4094
4095
4096
4097 wait = 1000;
4098 do {
4099 aic_delay(1000);
4100 } while (--wait && !(ahc_inb(ahc, HCNTRL) & CHIPRSTACK));
4101
4102 if (wait == 0) {
4103 printf("%s: WARNING - Failed chip reset! "
4104 "Trying to initialize anyway.\n", ahc_name(ahc));
4105 }
4106 ahc_outb(ahc, HCNTRL, ahc->pause);
4107
4108
4109 sblkctl = ahc_inb(ahc, SBLKCTL) & (SELBUSB|SELWIDE);
4110
4111 if ((ahc->chip & AHC_PCI) != 0)
4112 sblkctl &= ~SELBUSB;
4113 switch (sblkctl) {
4114 case 0:
4115
4116 break;
4117 case 2:
4118
4119 ahc->features |= AHC_WIDE;
4120 break;
4121 case 8:
4122
4123 ahc->features |= AHC_TWIN;
4124 break;
4125 default:
4126 printf(" Unsupported adapter type (0x%x). Ignoring\n", sblkctl);
4127 return(-1);
4128 }
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138 if ((ahc->features & AHC_TWIN) != 0) {
4139 u_int sblkctl;
4140
4141 sblkctl = ahc_inb(ahc, SBLKCTL);
4142 ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
4143 ahc_outb(ahc, SXFRCTL1, sxfrctl1_b);
4144 ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
4145 }
4146 ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);
4147
4148 error = 0;
4149 if (reinit != 0)
4150
4151
4152
4153
4154 error = ahc->bus_chip_init(ahc);
4155 #ifdef AHC_DUMP_SEQ
4156 else
4157 ahc_dumpseq(ahc);
4158 #endif
4159
4160 return (error);
4161 }
4162
4163
4164
4165
4166 int
4167 ahc_probe_scbs(struct ahc_softc *ahc) {
4168 int i;
4169
4170 for (i = 0; i < AHC_SCB_MAX; i++) {
4171
4172 ahc_outb(ahc, SCBPTR, i);
4173 ahc_outb(ahc, SCB_BASE, i);
4174 if (ahc_inb(ahc, SCB_BASE) != i)
4175 break;
4176 ahc_outb(ahc, SCBPTR, 0);
4177 if (ahc_inb(ahc, SCB_BASE) != 0)
4178 break;
4179 }
4180 return (i);
4181 }
4182
4183 #if 0
4184 static void
4185 ahc_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
4186 {
4187 bus_addr_t *baddr;
4188
4189 baddr = (bus_addr_t *)arg;
4190 *baddr = segs->ds_addr;
4191 }
4192 #endif
4193
4194 static void
4195 ahc_build_free_scb_list(struct ahc_softc *ahc)
4196 {
4197 int scbsize;
4198 int i;
4199
4200 scbsize = 32;
4201 if ((ahc->flags & AHC_LSCBS_ENABLED) != 0)
4202 scbsize = 64;
4203
4204 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
4205 int j;
4206
4207 ahc_outb(ahc, SCBPTR, i);
4208
4209
4210
4211
4212
4213
4214 for (j = 0; j < scbsize; j++)
4215 ahc_outb(ahc, SCB_BASE+j, 0xFF);
4216
4217
4218 ahc_outb(ahc, SCB_CONTROL, 0);
4219
4220
4221 if ((ahc->flags & AHC_PAGESCBS) != 0)
4222 ahc_outb(ahc, SCB_NEXT, i+1);
4223 else
4224 ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
4225
4226
4227 ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
4228 ahc_outb(ahc, SCB_SCSIID, 0xFF);
4229 ahc_outb(ahc, SCB_LUN, 0xFF);
4230 }
4231
4232 if ((ahc->flags & AHC_PAGESCBS) != 0) {
4233
4234 ahc_outb(ahc, FREE_SCBH, 0);
4235 } else {
4236
4237 ahc_outb(ahc, FREE_SCBH, SCB_LIST_NULL);
4238 }
4239
4240
4241 ahc_outb(ahc, SCBPTR, i-1);
4242 ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
4243 }
4244
4245 static int
4246 ahc_init_scbdata(struct ahc_softc *ahc)
4247 {
4248 struct scb_data *scb_data;
4249 int i;
4250
4251 scb_data = ahc->scb_data;
4252 SLIST_INIT(&scb_data->free_scbs);
4253 SLIST_INIT(&scb_data->sg_maps);
4254
4255
4256 scb_data->scbarray =
4257 (struct scb *)malloc(sizeof(struct scb) * AHC_SCB_MAX_ALLOC,
4258 M_DEVBUF, M_NOWAIT);
4259 if (scb_data->scbarray == NULL)
4260 return (ENOMEM);
4261 memset(scb_data->scbarray, 0, sizeof(struct scb) * AHC_SCB_MAX_ALLOC);
4262
4263
4264
4265 scb_data->maxhscbs = ahc_probe_scbs(ahc);
4266 if (ahc->scb_data->maxhscbs == 0) {
4267 printf("%s: No SCB space found\n", ahc_name(ahc));
4268 return (ENXIO);
4269 }
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281 if (ahc_createdmamem(ahc->parent_dmat,
4282 AHC_SCB_MAX * sizeof(struct hardware_scb), ahc->sc_dmaflags,
4283 &scb_data->hscb_dmamap,
4284 (caddr_t *)&scb_data->hscbs, &scb_data->hscb_busaddr,
4285 &scb_data->hscb_seg, &scb_data->hscb_nseg, ahc_name(ahc),
4286 "hardware SCB structures") < 0)
4287 goto error_exit;
4288
4289 scb_data->init_level++;
4290
4291 if (ahc_createdmamem(ahc->parent_dmat,
4292 AHC_SCB_MAX * sizeof(struct scsi_sense_data), ahc->sc_dmaflags,
4293 &scb_data->sense_dmamap, (caddr_t *)&scb_data->sense,
4294 &scb_data->sense_busaddr, &scb_data->sense_seg,
4295 &scb_data->sense_nseg, ahc_name(ahc), "sense buffers") < 0)
4296 goto error_exit;
4297
4298 scb_data->init_level++;
4299
4300
4301 memset(scb_data->hscbs, 0,
4302 AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb));
4303 do {
4304 i = scb_data->numscbs;
4305 ahc_alloc_scbs(ahc);
4306 } while ((i != scb_data->numscbs) &&
4307 (scb_data->numscbs < AHC_SCB_MAX_ALLOC));
4308
4309 if (scb_data->numscbs != AHC_SCB_MAX_ALLOC) {
4310 printf("%s: ahc_init_scbdata - "
4311 "Unable to allocate initial scbs\n",
4312 ahc_name(ahc));
4313 goto error_exit;
4314 }
4315
4316
4317
4318
4319 ahc->next_queued_scb = ahc_get_scb(ahc);
4320
4321
4322
4323
4324 return (0);
4325
4326 error_exit:
4327
4328 return (ENOMEM);
4329 }
4330
4331 static void
4332 ahc_fini_scbdata(struct ahc_softc *ahc)
4333 {
4334 struct scb_data *scb_data;
4335
4336 scb_data = ahc->scb_data;
4337 if (scb_data == NULL)
4338 return;
4339
4340 switch (scb_data->init_level) {
4341 default:
4342 case 5:
4343 {
4344 struct sg_map_node *sg_map;
4345
4346 while ((sg_map = SLIST_FIRST(&scb_data->sg_maps))!= NULL) {
4347 SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
4348 ahc_freedmamem(ahc->parent_dmat, PAGE_SIZE,
4349 sg_map->sg_dmamap, (caddr_t)sg_map->sg_vaddr,
4350 &sg_map->sg_dmasegs, sg_map->sg_nseg);
4351 free(sg_map, M_DEVBUF);
4352 }
4353 }
4354
4355 case 4:
4356 ahc_freedmamem(ahc->parent_dmat,
4357 AHC_SCB_MAX * sizeof(struct scsipi_sense_data),
4358 scb_data->sense_dmamap, (caddr_t)scb_data->sense,
4359 &scb_data->sense_seg, scb_data->sense_nseg);
4360
4361 case 3:
4362 ahc_freedmamem(ahc->parent_dmat,
4363 AHC_SCB_MAX * sizeof(struct hardware_scb),
4364 scb_data->hscb_dmamap, (caddr_t)scb_data->hscbs,
4365 &scb_data->hscb_seg, scb_data->hscb_nseg);
4366
4367 case 2:
4368 case 1:
4369 case 0:
4370 break;
4371 }
4372 if (scb_data->scbarray != NULL)
4373 free(scb_data->scbarray, M_DEVBUF);
4374 }
4375
4376 void
4377 ahc_alloc_scbs(struct ahc_softc *ahc)
4378 {
4379 struct scb_data *scb_data;
4380 struct scb *next_scb;
4381 struct sg_map_node *sg_map;
4382 bus_addr_t physaddr;
4383 struct ahc_dma_seg *segs;
4384 int newcount;
4385 int i;
4386
4387 scb_data = ahc->scb_data;
4388 if (scb_data->numscbs >= AHC_SCB_MAX_ALLOC)
4389
4390 return;
4391
4392 next_scb = &scb_data->scbarray[scb_data->numscbs];
4393
4394 sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT);
4395
4396 if (sg_map == NULL)
4397 return;
4398
4399
4400 if (ahc_createdmamem(ahc->parent_dmat, PAGE_SIZE, ahc->sc_dmaflags,
4401 &sg_map->sg_dmamap,
4402 (caddr_t *)&sg_map->sg_vaddr, &sg_map->sg_physaddr,
4403 &sg_map->sg_dmasegs, &sg_map->sg_nseg, ahc_name(ahc),
4404 "SG space") < 0) {
4405 free(sg_map, M_DEVBUF);
4406 return;
4407 }
4408
4409 SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
4410
4411 segs = sg_map->sg_vaddr;
4412 physaddr = sg_map->sg_physaddr;
4413
4414 newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg)));
4415 newcount = MIN(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs));
4416 for (i = 0; i < newcount; i++) {
4417 struct scb_platform_data *pdata = NULL;
4418 int error;
4419
4420 if (sizeof(*pdata) > 0) {
4421 pdata = (struct scb_platform_data *)
4422 malloc(sizeof(*pdata), M_DEVBUF, M_NOWAIT);
4423 if (pdata == NULL)
4424 break;
4425 bzero(pdata, sizeof(*pdata));
4426 }
4427
4428 next_scb->platform_data = pdata;
4429 next_scb->sg_map = sg_map;
4430 next_scb->sg_list = segs;
4431
4432
4433
4434
4435 next_scb->sg_list_phys = physaddr + sizeof(struct ahc_dma_seg);
4436 next_scb->ahc_softc = ahc;
4437 next_scb->flags = SCB_FLAG_NONE;
4438
4439 error = bus_dmamap_create(ahc->parent_dmat,
4440 AHC_MAXTRANSFER_SIZE, AHC_NSEG, MAXPHYS, 0,
4441 BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW|ahc->sc_dmaflags,
4442 &next_scb->dmamap);
4443 if (error != 0)
4444 break;
4445
4446 next_scb->hscb = &scb_data->hscbs[scb_data->numscbs];
4447 next_scb->hscb->tag = ahc->scb_data->numscbs;
4448 SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs,
4449 next_scb, links.sle);
4450 segs += AHC_NSEG;
4451 physaddr += (AHC_NSEG * sizeof(struct ahc_dma_seg));
4452 next_scb++;
4453 ahc->scb_data->numscbs++;
4454 }
4455 }
4456
4457 #ifndef DEBUG
4458 void
4459 ahc_controller_info(struct ahc_softc *ahc, char *buf, size_t buf_len)
4460 {
4461 int len = 0;
4462
4463 snprintf(buf + len, buf_len - len, "%s: ",
4464 ahc_chip_names[ahc->chip & AHC_CHIPID_MASK]);
4465 len = strlen(buf);
4466 if ((ahc->features & AHC_TWIN) != 0)
4467 snprintf(buf + len, buf_len - len,
4468 "Twin Channel, A SCSI Id=%d, B SCSI Id=%d, "
4469 "primary %c, ", ahc->our_id, ahc->our_id_b,
4470 (ahc->flags & AHC_PRIMARY_CHANNEL) + 'A');
4471 else {
4472 const char *speed;
4473 const char *type;
4474
4475 speed = "";
4476 if ((ahc->features & AHC_ULTRA) != 0) {
4477 speed = "Ultra ";
4478 } else if ((ahc->features & AHC_DT) != 0) {
4479 speed = "Ultra160 ";
4480 } else if ((ahc->features & AHC_ULTRA2) != 0) {
4481 speed = "Ultra2 ";
4482 }
4483 if ((ahc->features & AHC_WIDE) != 0) {
4484 type = "Wide";
4485 } else {
4486 type = "Single";
4487 }
4488 snprintf(buf + len, buf_len - len,
4489 "%s%s Channel %c, SCSI Id=%d, ",
4490 speed, type, ahc->channel, ahc->our_id);
4491 }
4492 len = strlen(buf);
4493
4494 if ((ahc->flags & AHC_PAGESCBS) != 0)
4495 snprintf(buf + len, buf_len - len, "%d/%d SCBs",
4496 ahc->scb_data->maxhscbs, AHC_MAX_QUEUE);
4497 else
4498 snprintf(buf + len, buf_len - len, "%d SCBs",
4499 ahc->scb_data->maxhscbs);
4500 }
4501 #endif
4502
4503 int
4504 ahc_chip_init(struct ahc_softc *ahc)
4505 {
4506 int term;
4507 int error;
4508 u_int i;
4509 u_int scsi_conf;
4510 u_int scsiseq_template;
4511 uint32_t physaddr;
4512
4513 ahc_outb(ahc, SEQ_FLAGS, 0);
4514 ahc_outb(ahc, SEQ_FLAGS2, 0);
4515
4516
4517 if (ahc->features & AHC_TWIN) {
4518
4519
4520
4521
4522 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
4523 term = (ahc->flags & AHC_TERM_ENB_B) != 0 ? STPWEN : 0;
4524 ahc_outb(ahc, SCSIID, ahc->our_id_b);
4525 scsi_conf = ahc_inb(ahc, SCSICONF + 1);
4526 ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
4527 |term|ahc->seltime_b|ENSTIMER|ACTNEGEN);
4528 if ((ahc->features & AHC_ULTRA2) != 0)
4529 ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
4530 ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
4531 ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
4532
4533
4534 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
4535 }
4536 term = (ahc->flags & AHC_TERM_ENB_A) != 0 ? STPWEN : 0;
4537 if ((ahc->features & AHC_ULTRA2) != 0)
4538 ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
4539 else
4540 ahc_outb(ahc, SCSIID, ahc->our_id);
4541 scsi_conf = ahc_inb(ahc, SCSICONF);
4542 ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
4543 |term|ahc->seltime
4544 |ENSTIMER|ACTNEGEN);
4545 if ((ahc->features & AHC_ULTRA2) != 0)
4546 ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
4547 ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
4548 ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
4549
4550
4551 for (i = 0; i < 16; i++) {
4552 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, 0));
4553 if ((ahc->flags & AHC_SCB_BTT) != 0) {
4554 int lun;
4555
4556
4557
4558
4559
4560 for (lun = 1; lun < AHC_NUM_LUNS; lun++)
4561 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, lun));
4562 }
4563 }
4564
4565
4566 for (i = 0; i < 256; i++)
4567 ahc->qoutfifo[i] = SCB_LIST_NULL;
4568 #ifdef __sgi__
4569 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
4570 #else
4571 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_PREREAD);
4572 #endif
4573 for (i = 0; i < 256; i++)
4574 ahc->qinfifo[i] = SCB_LIST_NULL;
4575
4576 if ((ahc->features & AHC_MULTI_TID) != 0) {
4577 ahc_outb(ahc, TARGID, 0);
4578 ahc_outb(ahc, TARGID + 1, 0);
4579 }
4580
4581
4582
4583
4584 physaddr = ahc->scb_data->hscb_busaddr;
4585 ahc_outb(ahc, HSCB_ADDR, physaddr & 0xFF);
4586 ahc_outb(ahc, HSCB_ADDR + 1, (physaddr >> 8) & 0xFF);
4587 ahc_outb(ahc, HSCB_ADDR + 2, (physaddr >> 16) & 0xFF);
4588 ahc_outb(ahc, HSCB_ADDR + 3, (physaddr >> 24) & 0xFF);
4589
4590 physaddr = ahc->shared_data_busaddr;
4591 ahc_outb(ahc, SHARED_DATA_ADDR, physaddr & 0xFF);
4592 ahc_outb(ahc, SHARED_DATA_ADDR + 1, (physaddr >> 8) & 0xFF);
4593 ahc_outb(ahc, SHARED_DATA_ADDR + 2, (physaddr >> 16) & 0xFF);
4594 ahc_outb(ahc, SHARED_DATA_ADDR + 3, (physaddr >> 24) & 0xFF);
4595
4596
4597
4598
4599
4600
4601 ahc_outb(ahc, CMDSIZE_TABLE, 5);
4602 ahc_outb(ahc, CMDSIZE_TABLE + 1, 9);
4603 ahc_outb(ahc, CMDSIZE_TABLE + 2, 9);
4604 ahc_outb(ahc, CMDSIZE_TABLE + 3, 0);
4605 ahc_outb(ahc, CMDSIZE_TABLE + 4, 15);
4606 ahc_outb(ahc, CMDSIZE_TABLE + 5, 11);
4607 ahc_outb(ahc, CMDSIZE_TABLE + 6, 0);
4608 ahc_outb(ahc, CMDSIZE_TABLE + 7, 0);
4609
4610 if ((ahc->features & AHC_HS_MAILBOX) != 0)
4611 ahc_outb(ahc, HS_MAILBOX, 0);
4612
4613
4614 if ((ahc->features & AHC_TARGETMODE) != 0) {
4615 ahc->tqinfifonext = 1;
4616 ahc_outb(ahc, KERNEL_TQINPOS, ahc->tqinfifonext - 1);
4617 ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
4618 }
4619 ahc->qinfifonext = 0;
4620 ahc->qoutfifonext = 0;
4621 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
4622 ahc_outb(ahc, QOFF_CTLSTA, SCB_QSIZE_256);
4623 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
4624 ahc_outb(ahc, SNSCB_QOFF, ahc->qinfifonext);
4625 ahc_outb(ahc, SDSCB_QOFF, 0);
4626 } else {
4627 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
4628 ahc_outb(ahc, QINPOS, ahc->qinfifonext);
4629 ahc_outb(ahc, QOUTPOS, ahc->qoutfifonext);
4630 }
4631
4632
4633 ahc_outb(ahc, WAITING_SCBH, SCB_LIST_NULL);
4634
4635
4636 ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
4637
4638
4639 ahc_outb(ahc, MSG_OUT, MSG_NOOP);
4640
4641
4642
4643
4644
4645
4646 scsiseq_template = ENSELO|ENAUTOATNO|ENAUTOATNP;
4647 if ((ahc->flags & AHC_INITIATORROLE) != 0)
4648 scsiseq_template |= ENRSELI;
4649 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq_template);
4650
4651
4652 ahc_build_free_scb_list(ahc);
4653
4654
4655
4656
4657 ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
4658
4659
4660
4661
4662
4663 if (bootverbose)
4664 printf("%s: Downloading Sequencer Program...",
4665 ahc_name(ahc));
4666
4667 error = ahc_loadseq(ahc);
4668 if (error != 0)
4669 return (error);
4670
4671 if ((ahc->features & AHC_ULTRA2) != 0) {
4672 int wait;
4673
4674
4675
4676
4677
4678
4679
4680
4681 for (wait = 5000;
4682 (ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
4683 wait--)
4684 aic_delay(100);
4685 }
4686 ahc_restart(ahc);
4687 return (0);
4688 }
4689
4690
4691
4692
4693 int
4694 ahc_init(struct ahc_softc *ahc)
4695 {
4696 int max_targ;
4697 u_int i;
4698 u_int scsi_conf;
4699 u_int ultraenb;
4700 u_int discenable;
4701 u_int tagenable;
4702 size_t driver_data_size;
4703
4704 #ifdef AHC_DEBUG
4705 if ((ahc_debug & AHC_DEBUG_SEQUENCER) != 0)
4706 ahc->flags |= AHC_SEQUENCER_DEBUG;
4707 #endif
4708
4709 #ifdef AHC_PRINT_SRAM
4710 printf("Scratch Ram:");
4711 for (i = 0x20; i < 0x5f; i++) {
4712 if (((i % 8) == 0) && (i != 0)) {
4713 printf ("\n ");
4714 }
4715 printf (" 0x%x", ahc_inb(ahc, i));
4716 }
4717 if ((ahc->features & AHC_MORE_SRAM) != 0) {
4718 for (i = 0x70; i < 0x7f; i++) {
4719 if (((i % 8) == 0) && (i != 0)) {
4720 printf ("\n ");
4721 }
4722 printf (" 0x%x", ahc_inb(ahc, i));
4723 }
4724 }
4725 printf ("\n");
4726
4727
4728
4729
4730 ahc_outb(ahc, CLRINT, CLRPARERR);
4731 ahc_outb(ahc, CLRINT, CLRBRKADRINT);
4732 #endif
4733 max_targ = 15;
4734
4735
4736
4737
4738 if ((ahc->flags & AHC_USEDEFAULTS) != 0)
4739 ahc->our_id = ahc->our_id_b = 7;
4740
4741
4742
4743
4744 ahc->flags |= AHC_INITIATORROLE;
4745
4746
4747
4748
4749
4750 ahc->features &= ~AHC_TARGETMODE;
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761 driver_data_size = 2 * 256 * sizeof(uint8_t);
4762 if ((ahc->features & AHC_TARGETMODE) != 0)
4763 driver_data_size += AHC_TMODE_CMDS * sizeof(struct target_cmd)
4764 + 1;
4765
4766 ahc->init_level++;
4767
4768 if (ahc_createdmamem(ahc->parent_dmat, driver_data_size,
4769 ahc->sc_dmaflags,
4770 &ahc->shared_data_dmamap, (caddr_t *)&ahc->qoutfifo,
4771 &ahc->shared_data_busaddr, &ahc->shared_data_seg,
4772 &ahc->shared_data_nseg, ahc_name(ahc), "shared data") < 0)
4773 return (ENOMEM);
4774
4775 ahc->init_level++;
4776
4777 if ((ahc->features & AHC_TARGETMODE) != 0) {
4778 ahc->targetcmds = (struct target_cmd *)ahc->qoutfifo;
4779 ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[AHC_TMODE_CMDS];
4780 ahc->dma_bug_buf = ahc->shared_data_busaddr
4781 + driver_data_size - 1;
4782
4783 for (i = 0; i < AHC_TMODE_CMDS; i++)
4784 ahc->targetcmds[i].cmd_valid = 0;
4785 #ifdef __sgi__
4786 ahc_sync_tqinfifo(ahc, BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
4787 #else
4788 ahc_sync_tqinfifo(ahc, BUS_DMASYNC_PREREAD);
4789 #endif
4790 ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[256];
4791 }
4792 ahc->qinfifo = &ahc->qoutfifo[256];
4793
4794 ahc->init_level++;
4795
4796
4797 if (ahc->scb_data->maxhscbs == 0)
4798 if (ahc_init_scbdata(ahc) != 0)
4799 return (ENOMEM);
4800
4801
4802
4803
4804
4805
4806 if (ahc_alloc_tstate(ahc, ahc->our_id, 'A') == NULL) {
4807 printf("%s: unable to allocate ahc_tmode_tstate. "
4808 "Failing attach\n", ahc_name(ahc));
4809 return (ENOMEM);
4810 }
4811
4812 if ((ahc->features & AHC_TWIN) != 0) {
4813 if (ahc_alloc_tstate(ahc, ahc->our_id_b, 'B') == NULL) {
4814 printf("%s: unable to allocate ahc_tmode_tstate. "
4815 "Failing attach\n", ahc_name(ahc));
4816 return (ENOMEM);
4817 }
4818 }
4819
4820 ahc_outb(ahc, SEQ_FLAGS, 0);
4821 ahc_outb(ahc, SEQ_FLAGS2, 0);
4822
4823 if (ahc->scb_data->maxhscbs < AHC_SCB_MAX_ALLOC) {
4824 ahc->flags |= AHC_PAGESCBS;
4825 } else {
4826 ahc->flags &= ~AHC_PAGESCBS;
4827 }
4828
4829 #ifdef AHC_DEBUG
4830 if (ahc_debug & AHC_SHOW_MISC) {
4831 printf("%s: hardware scb %u bytes; kernel scb %u bytes; "
4832 "ahc_dma %u bytes\n",
4833 ahc_name(ahc),
4834 (u_int)sizeof(struct hardware_scb),
4835 (u_int)sizeof(struct scb),
4836 (u_int)sizeof(struct ahc_dma_seg));
4837 }
4838 #endif
4839
4840
4841
4842
4843
4844 if (ahc->features & AHC_TWIN) {
4845 scsi_conf = ahc_inb(ahc, SCSICONF + 1);
4846 if ((scsi_conf & RESET_SCSI) != 0
4847 && (ahc->flags & AHC_INITIATORROLE) != 0)
4848 ahc->flags |= AHC_RESET_BUS_B;
4849 }
4850
4851 scsi_conf = ahc_inb(ahc, SCSICONF);
4852 if ((scsi_conf & RESET_SCSI) != 0
4853 && (ahc->flags & AHC_INITIATORROLE) != 0)
4854 ahc->flags |= AHC_RESET_BUS_A;
4855
4856 ultraenb = 0;
4857 tagenable = ALL_TARGETS_MASK;
4858
4859
4860 if ((ahc->flags & AHC_USEDEFAULTS) != 0) {
4861 printf("%s: Host Adapter Bios disabled. Using default SCSI "
4862 "device parameters\n", ahc_name(ahc));
4863 ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B|
4864 AHC_TERM_ENB_A|AHC_TERM_ENB_B;
4865 discenable = ALL_TARGETS_MASK;
4866 if ((ahc->features & AHC_ULTRA) != 0)
4867 ultraenb = ALL_TARGETS_MASK;
4868 } else {
4869 discenable = ~((ahc_inb(ahc, DISC_DSB + 1) << 8)
4870 | ahc_inb(ahc, DISC_DSB));
4871 if ((ahc->features & (AHC_ULTRA|AHC_ULTRA2)) != 0)
4872 ultraenb = (ahc_inb(ahc, ULTRA_ENB + 1) << 8)
4873 | ahc_inb(ahc, ULTRA_ENB);
4874 }
4875
4876 if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)
4877 max_targ = 7;
4878
4879 for (i = 0; i <= max_targ; i++) {
4880 struct ahc_initiator_tinfo *tinfo;
4881 struct ahc_tmode_tstate *tstate;
4882 u_int our_id;
4883 u_int target_id;
4884 char channel;
4885
4886 channel = 'A';
4887 our_id = ahc->our_id;
4888 target_id = i;
4889 if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
4890 channel = 'B';
4891 our_id = ahc->our_id_b;
4892 target_id = i % 8;
4893 }
4894 tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
4895 target_id, &tstate);
4896
4897 memset(tinfo, 0, sizeof(*tinfo));
4898 if (ahc->flags & AHC_USEDEFAULTS) {
4899 if ((ahc->features & AHC_WIDE) != 0)
4900 tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
4901
4902
4903
4904
4905
4906 tinfo->user.period = ahc_syncrates->period;
4907 tinfo->user.offset = MAX_OFFSET;
4908 } else {
4909 u_int scsirate;
4910 uint16_t mask;
4911
4912
4913 scsirate = ahc_inb(ahc, TARG_SCSIRATE + i);
4914 mask = (0x01 << i);
4915 if ((ahc->features & AHC_ULTRA2) != 0) {
4916 u_int offset;
4917 u_int maxsync;
4918
4919 if ((scsirate & SOFS) == 0x0F) {
4920
4921
4922
4923
4924 scsirate = (scsirate & SXFR) >> 4
4925 | (ultraenb & mask)
4926 ? 0x08 : 0x0
4927 | (scsirate & WIDEXFER);
4928 offset = MAX_OFFSET_ULTRA2;
4929 } else
4930 offset = ahc_inb(ahc, TARG_OFFSET + i);
4931 if ((scsirate & ~WIDEXFER) == 0 && offset != 0)
4932
4933 scsirate |= 0x1c;
4934 maxsync = AHC_SYNCRATE_ULTRA2;
4935 if ((ahc->features & AHC_DT) != 0)
4936 maxsync = AHC_SYNCRATE_DT;
4937 tinfo->user.period =
4938 ahc_find_period(ahc, scsirate, maxsync);
4939 if (offset == 0)
4940 tinfo->user.period = 0;
4941 else
4942 tinfo->user.offset = MAX_OFFSET;
4943 if ((scsirate & SXFR_ULTRA2) <= 8
4944 && (ahc->features & AHC_DT) != 0)
4945 tinfo->user.ppr_options =
4946 MSG_EXT_PPR_DT_REQ;
4947 } else if ((scsirate & SOFS) != 0) {
4948 if ((scsirate & SXFR) == 0x40
4949 && (ultraenb & mask) != 0) {
4950
4951 scsirate &= ~SXFR;
4952 ultraenb &= ~mask;
4953 }
4954 tinfo->user.period =
4955 ahc_find_period(ahc, scsirate,
4956 (ultraenb & mask)
4957 ? AHC_SYNCRATE_ULTRA
4958 : AHC_SYNCRATE_FAST);
4959 if (tinfo->user.period != 0)
4960 tinfo->user.offset = MAX_OFFSET;
4961 }
4962 if (tinfo->user.period == 0)
4963 tinfo->user.offset = 0;
4964 if ((scsirate & WIDEXFER) != 0
4965 && (ahc->features & AHC_WIDE) != 0)
4966 tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
4967 tinfo->user.protocol_version = 4;
4968 if ((ahc->features & AHC_DT) != 0)
4969 tinfo->user.transport_version = 3;
4970 else
4971 tinfo->user.transport_version = 2;
4972 tinfo->goal.protocol_version = 2;
4973 tinfo->goal.transport_version = 2;
4974 tinfo->curr.protocol_version = 2;
4975 tinfo->curr.transport_version = 2;
4976 }
4977 tstate->ultraenb = 0;
4978 tstate->discenable = discenable;
4979 }
4980 ahc->user_discenable = discenable;
4981 ahc->user_tagenable = tagenable;
4982
4983 return (ahc->bus_chip_init(ahc));
4984 }
4985
4986 void
4987 ahc_intr_enable(struct ahc_softc *ahc, int enable)
4988 {
4989 u_int hcntrl;
4990
4991 hcntrl = ahc_inb(ahc, HCNTRL);
4992 hcntrl &= ~INTEN;
4993 ahc->pause &= ~INTEN;
4994 ahc->unpause &= ~INTEN;
4995 if (enable) {
4996 hcntrl |= INTEN;
4997 ahc->pause |= INTEN;
4998 ahc->unpause |= INTEN;
4999 }
5000 ahc_outb(ahc, HCNTRL, hcntrl);
5001 }
5002
5003
5004
5005
5006
5007
5008 u_int
5009 ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl)
5010 {
5011 u_int scbid;
5012 u_int target_offset;
5013
5014 if ((ahc->flags & AHC_SCB_BTT) != 0) {
5015 u_int saved_scbptr;
5016
5017 saved_scbptr = ahc_inb(ahc, SCBPTR);
5018 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
5019 scbid = ahc_inb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl));
5020 ahc_outb(ahc, SCBPTR, saved_scbptr);
5021 } else {
5022 target_offset = TCL_TARGET_OFFSET(tcl);
5023 scbid = ahc_inb(ahc, BUSY_TARGETS + target_offset);
5024 }
5025
5026 return (scbid);
5027 }
5028
5029 void
5030 ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl)
5031 {
5032 u_int target_offset;
5033
5034 if ((ahc->flags & AHC_SCB_BTT) != 0) {
5035 u_int saved_scbptr;
5036
5037 saved_scbptr = ahc_inb(ahc, SCBPTR);
5038 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
5039 ahc_outb(ahc, SCB_64_BTT+TCL_TARGET_OFFSET(tcl), SCB_LIST_NULL);
5040 ahc_outb(ahc, SCBPTR, saved_scbptr);
5041 } else {
5042 target_offset = TCL_TARGET_OFFSET(tcl);
5043 ahc_outb(ahc, BUSY_TARGETS + target_offset, SCB_LIST_NULL);
5044 }
5045 }
5046
5047 void
5048 ahc_busy_tcl(struct ahc_softc *ahc, u_int tcl, u_int scbid)
5049 {
5050 u_int target_offset;
5051
5052 if ((ahc->flags & AHC_SCB_BTT) != 0) {
5053 u_int saved_scbptr;
5054
5055 saved_scbptr = ahc_inb(ahc, SCBPTR);
5056 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
5057 ahc_outb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl), scbid);
5058 ahc_outb(ahc, SCBPTR, saved_scbptr);
5059 } else {
5060 target_offset = TCL_TARGET_OFFSET(tcl);
5061 ahc_outb(ahc, BUSY_TARGETS + target_offset, scbid);
5062 }
5063 }
5064
5065
5066 int
5067 ahc_match_scb(struct ahc_softc *ahc, struct scb *scb, int target,
5068 char channel, int lun, u_int tag, role_t role)
5069 {
5070 char chan;
5071 int targ, slun, match;
5072
5073 if (scb == NULL)
5074 return 0;
5075
5076 targ = SCB_GET_TARGET(ahc, scb);
5077 chan = SCB_GET_CHANNEL(ahc, scb);
5078 slun = SCB_GET_LUN(scb);
5079
5080 match = ((chan == channel) || (channel == ALL_CHANNELS));
5081 if (match != 0)
5082 match = ((targ == target) || (target == CAM_TARGET_WILDCARD));
5083 if (match != 0)
5084 match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));
5085 if (match != 0) {
5086 #ifdef AHC_TARGET_MODE
5087 int group;
5088
5089 group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);
5090 if (role == ROLE_INITIATOR) {
5091 match = (group != XPT_FC_GROUP_TMODE)
5092 && ((tag == scb->hscb->tag)
5093 || (tag == SCB_LIST_NULL));
5094 } else if (role == ROLE_TARGET) {
5095 match = (group == XPT_FC_GROUP_TMODE)
5096 && ((tag == scb->io_ctx->csio.tag_id)
5097 || (tag == SCB_LIST_NULL));
5098 }
5099 #else
5100 match = ((tag == scb->hscb->tag) || (tag == SCB_LIST_NULL));
5101 #endif
5102 }
5103
5104 return match;
5105 }
5106
5107 void
5108 ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb)
5109 {
5110 int target;
5111 char channel;
5112 int lun;
5113
5114 target = SCB_GET_TARGET(ahc, scb);
5115 lun = SCB_GET_LUN(scb);
5116 channel = SCB_GET_CHANNEL(ahc, scb);
5117
5118 ahc_search_qinfifo(ahc, target, channel, lun,
5119 SCB_LIST_NULL, ROLE_UNKNOWN,
5120 CAM_REQUEUE_REQ, SEARCH_COMPLETE);
5121
5122 ahc_platform_freeze_devq(ahc, scb);
5123 }
5124
5125 void
5126 ahc_qinfifo_requeue_tail(struct ahc_softc *ahc, struct scb *scb)
5127 {
5128 struct scb *prev_scb;
5129
5130 prev_scb = NULL;
5131 if (ahc_qinfifo_count(ahc) != 0) {
5132 u_int prev_tag;
5133 uint8_t prev_pos;
5134
5135 prev_pos = ahc->qinfifonext - 1;
5136 prev_tag = ahc->qinfifo[prev_pos];
5137 prev_scb = ahc_lookup_scb(ahc, prev_tag);
5138 }
5139 ahc_qinfifo_requeue(ahc, prev_scb, scb);
5140 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
5141 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
5142 } else {
5143 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
5144 }
5145 }
5146
5147 static void
5148 ahc_qinfifo_requeue(struct ahc_softc *ahc, struct scb *prev_scb,
5149 struct scb *scb)
5150 {
5151 if (prev_scb == NULL) {
5152 ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
5153 } else {
5154 prev_scb->hscb->next = scb->hscb->tag;
5155 ahc_sync_scb(ahc, prev_scb,
5156 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
5157 }
5158 ahc->qinfifo[ahc->qinfifonext] = scb->hscb->tag;
5159 ahc_dmamap_sync(ahc, ahc->parent_dmat, ahc->shared_data_dmamap,
5160 ahc->qinfifonext+256, 1,
5161 BUS_DMASYNC_PREWRITE);
5162 ahc->qinfifonext++;
5163 scb->hscb->next = ahc->next_queued_scb->hscb->tag;
5164 ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
5165 }
5166
5167 static int
5168 ahc_qinfifo_count(struct ahc_softc *ahc)
5169 {
5170 uint8_t qinpos;
5171 uint8_t diff;
5172
5173 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
5174 qinpos = ahc_inb(ahc, SNSCB_QOFF);
5175 ahc_outb(ahc, SNSCB_QOFF, qinpos);
5176 } else
5177 qinpos = ahc_inb(ahc, QINPOS);
5178 diff = ahc->qinfifonext - qinpos;
5179 return (diff);
5180 }
5181
5182 int
5183 ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
5184 int lun, u_int tag, role_t role, uint32_t status,
5185 ahc_search_action action)
5186 {
5187 struct scb *scb;
5188 struct scb *prev_scb;
5189 uint8_t qinstart;
5190 uint8_t qinpos;
5191 uint8_t qintail;
5192 uint8_t next;
5193 uint8_t prev;
5194 uint8_t curscbptr;
5195 int found;
5196 int have_qregs;
5197
5198 qintail = ahc->qinfifonext;
5199 have_qregs = (ahc->features & AHC_QUEUE_REGS) != 0;
5200 if (have_qregs) {
5201 qinstart = ahc_inb(ahc, SNSCB_QOFF);
5202 ahc_outb(ahc, SNSCB_QOFF, qinstart);
5203 } else
5204 qinstart = ahc_inb(ahc, QINPOS);
5205 qinpos = qinstart;
5206 found = 0;
5207 prev_scb = NULL;
5208
5209 if (action == SEARCH_COMPLETE) {
5210
5211
5212
5213
5214 ahc_freeze_untagged_queues(ahc);
5215 }
5216
5217
5218
5219
5220
5221 ahc->qinfifonext = qinpos;
5222 ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
5223
5224 while (qinpos != qintail) {
5225 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinpos]);
5226 if (scb == NULL) {
5227 printf("qinpos = %d, SCB index = %d\n",
5228 qinpos, ahc->qinfifo[qinpos]);
5229 panic("Loop 1");
5230 }
5231
5232 if (ahc_match_scb(ahc, scb, target, channel, lun, tag, role)) {
5233
5234
5235
5236 found++;
5237 switch (action) {
5238 case SEARCH_COMPLETE:
5239 {
5240 cam_status ostat;
5241 cam_status cstat;
5242
5243 ostat = ahc_get_transaction_status(scb);
5244 if (ostat == CAM_REQ_INPROG)
5245 ahc_set_transaction_status(scb, status);
5246 cstat = ahc_get_transaction_status(scb);
5247 if (cstat != CAM_REQ_CMP)
5248 ahc_freeze_scb(scb);
5249 if ((scb->flags & SCB_ACTIVE) == 0)
5250 printf("Inactive SCB in qinfifo\n");
5251 ahc_done(ahc, scb);
5252
5253
5254 }
5255 case SEARCH_REMOVE:
5256 break;
5257 case SEARCH_COUNT:
5258 ahc_qinfifo_requeue(ahc, prev_scb, scb);
5259 prev_scb = scb;
5260 break;
5261 }
5262 } else {
5263 ahc_qinfifo_requeue(ahc, prev_scb, scb);
5264 prev_scb = scb;
5265 }
5266 qinpos++;
5267 }
5268
5269 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
5270 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
5271 } else {
5272 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
5273 }
5274
5275 if (action != SEARCH_COUNT
5276 && (found != 0)
5277 && (qinstart != ahc->qinfifonext)) {
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinstart]);
5291
5292 if (scb == NULL) {
5293 printf("found = %d, qinstart = %d, qinfifionext = %d\n",
5294 found, qinstart, ahc->qinfifonext);
5295 panic("First/Second Qinfifo fixup");
5296 }
5297
5298
5299
5300
5301
5302
5303 next = scb->hscb->next;
5304 ahc->scb_data->scbindex[scb->hscb->tag] = NULL;
5305 ahc_swap_with_next_hscb(ahc, scb);
5306 scb->hscb->next = next;
5307 ahc->qinfifo[qinstart] = scb->hscb->tag;
5308
5309
5310 ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
5311
5312
5313 qintail = ahc->qinfifonext - 1;
5314 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qintail]);
5315 scb->hscb->next = ahc->next_queued_scb->hscb->tag;
5316 }
5317
5318
5319
5320
5321 curscbptr = ahc_inb(ahc, SCBPTR);
5322 next = ahc_inb(ahc, WAITING_SCBH);
5323 prev = SCB_LIST_NULL;
5324
5325 while (next != SCB_LIST_NULL) {
5326 uint8_t scb_index;
5327
5328 ahc_outb(ahc, SCBPTR, next);
5329 scb_index = ahc_inb(ahc, SCB_TAG);
5330 if (scb_index >= ahc->scb_data->numscbs) {
5331 printf("Waiting List inconsistency. "
5332 "SCB index == %d, yet numscbs == %d.",
5333 scb_index, ahc->scb_data->numscbs);
5334 ahc_dump_card_state(ahc);
5335 panic("for safety");
5336 }
5337 scb = ahc_lookup_scb(ahc, scb_index);
5338 if (scb == NULL) {
5339 printf("scb_index = %d, next = %d\n",
5340 scb_index, next);
5341 panic("Waiting List traversal");
5342 }
5343 if (ahc_match_scb(ahc, scb, target, channel,
5344 lun, SCB_LIST_NULL, role)) {
5345
5346
5347
5348 found++;
5349 switch (action) {
5350 case SEARCH_COMPLETE:
5351 {
5352 cam_status ostat;
5353 cam_status cstat;
5354
5355 ostat = ahc_get_transaction_status(scb);
5356 if (ostat == CAM_REQ_INPROG)
5357 ahc_set_transaction_status(scb, status);
5358 cstat = ahc_get_transaction_status(scb);
5359 if (cstat != CAM_REQ_CMP)
5360 ahc_freeze_scb(scb);
5361 if ((scb->flags & SCB_ACTIVE) == 0)
5362 printf("Inactive SCB in Wait List\n");
5363 ahc_done(ahc, scb);
5364
5365 }
5366 case SEARCH_REMOVE:
5367 next = ahc_rem_wscb(ahc, next, prev);
5368 break;
5369 case SEARCH_COUNT:
5370 prev = next;
5371 next = ahc_inb(ahc, SCB_NEXT);
5372 break;
5373 }
5374 } else {
5375
5376 prev = next;
5377 next = ahc_inb(ahc, SCB_NEXT);
5378 }
5379 }
5380 ahc_outb(ahc, SCBPTR, curscbptr);
5381
5382 found += ahc_search_untagged_queues(ahc, NULL, target,
5383 channel, lun, status, action);
5384
5385 if (action == SEARCH_COMPLETE)
5386 ahc_release_untagged_queues(ahc);
5387 return (found);
5388 }
5389
5390 int
5391 ahc_search_untagged_queues(struct ahc_softc *ahc, struct scsi_xfer *xs,
5392 int target, char channel, int lun, uint32_t status,
5393 ahc_search_action action)
5394 {
5395 struct scb *scb;
5396 int maxtarget;
5397 int found;
5398 int i;
5399
5400 if (action == SEARCH_COMPLETE) {
5401
5402
5403
5404
5405 ahc_freeze_untagged_queues(ahc);
5406 }
5407
5408 found = 0;
5409 i = 0;
5410 if ((ahc->flags & AHC_SCB_BTT) == 0) {
5411
5412 maxtarget = 16;
5413 if (target != CAM_TARGET_WILDCARD) {
5414
5415 i = target;
5416 if (channel == 'B')
5417 i += 8;
5418 maxtarget = i + 1;
5419 }
5420 } else {
5421 maxtarget = 0;
5422 }
5423
5424 for (; i < maxtarget; i++) {
5425 struct scb_tailq *untagged_q;
5426 struct scb *next_scb;
5427
5428 untagged_q = &(ahc->untagged_queues[i]);
5429 next_scb = TAILQ_FIRST(untagged_q);
5430 while (next_scb != NULL) {
5431
5432 scb = next_scb;
5433 next_scb = TAILQ_NEXT(scb, links.tqe);
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444 if ((scb->flags & SCB_ACTIVE) != 0)
5445 continue;
5446
5447 if (ahc_match_scb(ahc, scb, target, channel, lun,
5448 SCB_LIST_NULL, ROLE_INITIATOR) == 0
5449 || (xs != NULL && xs != scb->xs))
5450 continue;
5451
5452
5453
5454
5455 found++;
5456 switch (action) {
5457 case SEARCH_COMPLETE:
5458 {
5459 cam_status ostat;
5460 cam_status cstat;
5461
5462 ostat = ahc_get_transaction_status(scb);
5463 if (ostat == CAM_REQ_INPROG)
5464 ahc_set_transaction_status(scb, status);
5465 cstat = ahc_get_transaction_status(scb);
5466 if (cstat != CAM_REQ_CMP)
5467 ahc_freeze_scb(scb);
5468 ahc_done(ahc, scb);
5469 break;
5470 }
5471 case SEARCH_REMOVE:
5472 scb->flags &= ~SCB_UNTAGGEDQ;
5473 TAILQ_REMOVE(untagged_q, scb, links.tqe);
5474 break;
5475 case SEARCH_COUNT:
5476 break;
5477 }
5478 }
5479 }
5480
5481 if (action == SEARCH_COMPLETE)
5482 ahc_release_untagged_queues(ahc);
5483 return (found);
5484 }
5485
5486 int
5487 ahc_search_disc_list(struct ahc_softc *ahc, int target, char channel,
5488 int lun, u_int tag, int stop_on_first, int remove,
5489 int save_state)
5490 {
5491 struct scb *scbp;
5492 u_int next;
5493 u_int prev;
5494 u_int count;
5495 u_int active_scb;
5496
5497 count = 0;
5498 next = ahc_inb(ahc, DISCONNECTED_SCBH);
5499 prev = SCB_LIST_NULL;
5500
5501 if (save_state) {
5502
5503 active_scb = ahc_inb(ahc, SCBPTR);
5504 } else
5505
5506 active_scb = SCB_LIST_NULL;
5507
5508 while (next != SCB_LIST_NULL) {
5509 u_int scb_index;
5510
5511 ahc_outb(ahc, SCBPTR, next);
5512 scb_index = ahc_inb(ahc, SCB_TAG);
5513 if (scb_index >= ahc->scb_data->numscbs) {
5514 printf("Disconnected List inconsistency. "
5515 "SCB index == %d, yet numscbs == %d.",
5516 scb_index, ahc->scb_data->numscbs);
5517 ahc_dump_card_state(ahc);
5518 panic("for safety");
5519 }
5520
5521 if (next == prev) {
5522 panic("Disconnected List Loop. "
5523 "cur SCBPTR == %x, prev SCBPTR == %x.",
5524 next, prev);
5525 }
5526 scbp = ahc_lookup_scb(ahc, scb_index);
5527 if (ahc_match_scb(ahc, scbp, target, channel, lun,
5528 tag, ROLE_INITIATOR)) {
5529 count++;
5530 if (remove) {
5531 next =
5532 ahc_rem_scb_from_disc_list(ahc, prev, next);
5533 } else {
5534 prev = next;
5535 next = ahc_inb(ahc, SCB_NEXT);
5536 }
5537 if (stop_on_first)
5538 break;
5539 } else {
5540 prev = next;
5541 next = ahc_inb(ahc, SCB_NEXT);
5542 }
5543 }
5544 if (save_state)
5545 ahc_outb(ahc, SCBPTR, active_scb);
5546 return (count);
5547 }
5548
5549
5550
5551
5552
5553 static u_int
5554 ahc_rem_scb_from_disc_list(struct ahc_softc *ahc, u_int prev, u_int scbptr)
5555 {
5556 u_int next;
5557
5558 ahc_outb(ahc, SCBPTR, scbptr);
5559 next = ahc_inb(ahc, SCB_NEXT);
5560
5561 ahc_outb(ahc, SCB_CONTROL, 0);
5562
5563 ahc_add_curscb_to_free_list(ahc);
5564
5565 if (prev != SCB_LIST_NULL) {
5566 ahc_outb(ahc, SCBPTR, prev);
5567 ahc_outb(ahc, SCB_NEXT, next);
5568 } else
5569 ahc_outb(ahc, DISCONNECTED_SCBH, next);
5570
5571 return (next);
5572 }
5573
5574
5575
5576
5577
5578
5579 static void
5580 ahc_add_curscb_to_free_list(struct ahc_softc *ahc)
5581 {
5582
5583
5584
5585
5586 ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
5587
5588 if ((ahc->flags & AHC_PAGESCBS) != 0) {
5589 ahc_outb(ahc, SCB_NEXT, ahc_inb(ahc, FREE_SCBH));
5590 ahc_outb(ahc, FREE_SCBH, ahc_inb(ahc, SCBPTR));
5591 }
5592 }
5593
5594
5595
5596
5597
5598 static u_int
5599 ahc_rem_wscb(struct ahc_softc *ahc, u_int scbpos, u_int prev)
5600 {
5601 u_int curscb, next;
5602
5603
5604
5605
5606
5607 curscb = ahc_inb(ahc, SCBPTR);
5608 ahc_outb(ahc, SCBPTR, scbpos);
5609 next = ahc_inb(ahc, SCB_NEXT);
5610
5611
5612 ahc_outb(ahc, SCB_CONTROL, 0);
5613
5614 ahc_add_curscb_to_free_list(ahc);
5615
5616
5617 if (prev == SCB_LIST_NULL) {
5618
5619 ahc_outb(ahc, WAITING_SCBH, next);
5620
5621
5622
5623
5624
5625 ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
5626 } else {
5627
5628
5629
5630
5631 ahc_outb(ahc, SCBPTR, prev);
5632 ahc_outb(ahc, SCB_NEXT, next);
5633 }
5634
5635
5636
5637
5638 ahc_outb(ahc, SCBPTR, curscb);
5639 return next;
5640 }
5641
5642
5643
5644
5645
5646
5647
5648
5649 int
5650 ahc_abort_scbs(struct ahc_softc *ahc, int target, char channel,
5651 int lun, u_int tag, role_t role, uint32_t status)
5652 {
5653 struct scb *scbp;
5654 struct scb *scbp_next;
5655 u_int active_scb;
5656 int i, j;
5657 int maxtarget;
5658 int minlun;
5659 int maxlun;
5660
5661 int found;
5662
5663
5664
5665
5666
5667 ahc_freeze_untagged_queues(ahc);
5668
5669
5670 active_scb = ahc_inb(ahc, SCBPTR);
5671
5672 found = ahc_search_qinfifo(ahc, target, channel, lun, SCB_LIST_NULL,
5673 role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);
5674
5675
5676
5677
5678 i = 0;
5679 maxtarget = 16;
5680 if (target != CAM_TARGET_WILDCARD) {
5681 i = target;
5682 if (channel == 'B')
5683 i += 8;
5684 maxtarget = i + 1;
5685 }
5686
5687 if (lun == CAM_LUN_WILDCARD) {
5688
5689
5690
5691
5692
5693
5694
5695 minlun = 0;
5696 maxlun = 1;
5697 if ((ahc->flags & AHC_SCB_BTT) != 0)
5698 maxlun = AHC_NUM_LUNS;
5699 } else {
5700 minlun = lun;
5701 maxlun = lun + 1;
5702 }
5703
5704 if (role != ROLE_TARGET) {
5705 for (;i < maxtarget; i++) {
5706 for (j = minlun;j < maxlun; j++) {
5707 u_int scbid;
5708 u_int tcl;
5709
5710 tcl = BUILD_TCL(i << 4, j);
5711 scbid = ahc_index_busy_tcl(ahc, tcl);
5712 scbp = ahc_lookup_scb(ahc, scbid);
5713 if (scbp == NULL
5714 || ahc_match_scb(ahc, scbp, target, channel,
5715 lun, tag, role) == 0)
5716 continue;
5717 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, j));
5718 }
5719 }
5720
5721
5722
5723
5724
5725
5726
5727 ahc_search_disc_list(ahc, target, channel, lun, tag,
5728 FALSE, TRUE,
5729 FALSE);
5730 }
5731
5732
5733
5734
5735
5736
5737
5738
5739 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
5740 u_int scbid;
5741
5742 ahc_outb(ahc, SCBPTR, i);
5743 scbid = ahc_inb(ahc, SCB_TAG);
5744 scbp = ahc_lookup_scb(ahc, scbid);
5745 if ((scbp == NULL && scbid != SCB_LIST_NULL)
5746 || (scbp != NULL
5747 && ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)))
5748 ahc_add_curscb_to_free_list(ahc);
5749 }
5750
5751
5752
5753
5754
5755
5756
5757 scbp_next = LIST_FIRST(&ahc->pending_scbs);
5758 while (scbp_next != NULL) {
5759 scbp = scbp_next;
5760 scbp_next = LIST_NEXT(scbp, pending_links);
5761 if (ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)) {
5762 cam_status ostat;
5763
5764 ostat = ahc_get_transaction_status(scbp);
5765 if (ostat == CAM_REQ_INPROG)
5766 ahc_set_transaction_status(scbp, status);
5767 if (ahc_get_transaction_status(scbp) != CAM_REQ_CMP)
5768 ahc_freeze_scb(scbp);
5769 if ((scbp->flags & SCB_ACTIVE) == 0)
5770 printf("Inactive SCB on pending list\n");
5771 ahc_done(ahc, scbp);
5772 found++;
5773 }
5774 }
5775 ahc_outb(ahc, SCBPTR, active_scb);
5776 ahc_platform_abort_scbs(ahc, target, channel, lun, tag, role, status);
5777 ahc_release_untagged_queues(ahc);
5778 return found;
5779 }
5780
5781 static void
5782 ahc_reset_current_bus(struct ahc_softc *ahc)
5783 {
5784 uint8_t scsiseq;
5785
5786 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENSCSIRST);
5787 scsiseq = ahc_inb(ahc, SCSISEQ);
5788 ahc_outb(ahc, SCSISEQ, scsiseq | SCSIRSTO);
5789 ahc_flush_device_writes(ahc);
5790 aic_delay(AHC_BUSRESET_DELAY);
5791
5792 ahc_outb(ahc, SCSISEQ, scsiseq & ~SCSIRSTO);
5793
5794 ahc_clear_intstat(ahc);
5795
5796
5797 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) | ENSCSIRST);
5798 }
5799
5800 int
5801 ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
5802 {
5803 struct ahc_devinfo devinfo;
5804 u_int initiator, target, max_scsiid;
5805 u_int sblkctl;
5806 u_int scsiseq;
5807 u_int simode1;
5808 int found;
5809 int restart_needed;
5810 char cur_channel;
5811
5812 ahc->pending_device = NULL;
5813
5814 ahc_compile_devinfo(&devinfo,
5815 CAM_TARGET_WILDCARD,
5816 CAM_TARGET_WILDCARD,
5817 CAM_LUN_WILDCARD,
5818 channel, ROLE_UNKNOWN);
5819 ahc_pause(ahc);
5820
5821
5822 ahc_clear_critical_section(ahc);
5823
5824
5825
5826
5827
5828
5829 ahc_run_qoutfifo(ahc);
5830 #ifdef AHC_TARGET_MODE
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841 if ((ahc->flags & AHC_TARGETROLE) != 0) {
5842 ahc_run_tqinfifo(ahc, TRUE);
5843 }
5844 #endif
5845
5846
5847
5848
5849 sblkctl = ahc_inb(ahc, SBLKCTL);
5850 cur_channel = 'A';
5851 if ((ahc->features & AHC_TWIN) != 0
5852 && ((sblkctl & SELBUSB) != 0))
5853 cur_channel = 'B';
5854 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
5855 if (cur_channel != channel) {
5856
5857
5858
5859
5860 ahc_outb(ahc, SBLKCTL, sblkctl ^ SELBUSB);
5861 simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
5862 #ifdef AHC_TARGET_MODE
5863
5864
5865
5866
5867
5868 if ((ahc->flags & AHC_TARGETROLE) != 0)
5869 simode1 |= ENSCSIRST;
5870 #endif
5871 ahc_outb(ahc, SIMODE1, simode1);
5872 if (initiate_reset)
5873 ahc_reset_current_bus(ahc);
5874 ahc_clear_intstat(ahc);
5875 ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
5876 ahc_outb(ahc, SBLKCTL, sblkctl);
5877 restart_needed = FALSE;
5878 } else {
5879
5880 simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
5881 #ifdef AHC_TARGET_MODE
5882
5883
5884
5885
5886
5887 if ((ahc->flags & AHC_TARGETROLE) != 0)
5888 simode1 |= ENSCSIRST;
5889 #endif
5890 ahc_outb(ahc, SIMODE1, simode1);
5891 if (initiate_reset)
5892 ahc_reset_current_bus(ahc);
5893 ahc_clear_intstat(ahc);
5894 ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
5895 restart_needed = TRUE;
5896 }
5897
5898
5899
5900
5901
5902 found = ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, channel,
5903 CAM_LUN_WILDCARD, SCB_LIST_NULL,
5904 ROLE_UNKNOWN, CAM_SCSI_BUS_RESET);
5905
5906 max_scsiid = (ahc->features & AHC_WIDE) ? 15 : 7;
5907
5908 #ifdef AHC_TARGET_MODE
5909
5910
5911
5912
5913 for (target = 0; target <= max_scsiid; target++) {
5914 struct ahc_tmode_tstate* tstate;
5915 u_int lun;
5916
5917 tstate = ahc->enabled_targets[target];
5918 if (tstate == NULL)
5919 continue;
5920 for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
5921 struct ahc_tmode_lstate* lstate;
5922
5923 lstate = tstate->enabled_luns[lun];
5924 if (lstate == NULL)
5925 continue;
5926
5927 ahc_queue_lstate_event(ahc, lstate, CAM_TARGET_WILDCARD,
5928 EVENT_TYPE_BUS_RESET, 0);
5929 ahc_send_lstate_events(ahc, lstate);
5930 }
5931 }
5932 #endif
5933
5934 ahc_send_async(ahc, devinfo.channel, CAM_TARGET_WILDCARD,
5935 CAM_LUN_WILDCARD, AC_BUS_RESET, NULL);
5936
5937
5938
5939
5940 for (target = 0; target <= max_scsiid; target++) {
5941
5942 if (ahc->enabled_targets[target] == NULL)
5943 continue;
5944 for (initiator = 0; initiator <= max_scsiid; initiator++) {
5945 struct ahc_devinfo devinfo;
5946
5947 ahc_compile_devinfo(&devinfo, target, initiator,
5948 CAM_LUN_WILDCARD,
5949 channel, ROLE_UNKNOWN);
5950 ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
5951 AHC_TRANS_CUR, TRUE);
5952 ahc_set_syncrate(ahc, &devinfo, NULL,
5953 0, 0,
5954 0, AHC_TRANS_CUR,
5955 TRUE);
5956 }
5957 }
5958
5959 if (restart_needed)
5960 ahc_restart(ahc);
5961 else
5962 ahc_unpause(ahc);
5963 return found;
5964 }
5965
5966
5967
5968
5969
5970
5971 void
5972 ahc_calc_residual(struct ahc_softc *ahc, struct scb *scb)
5973 {
5974 struct hardware_scb *hscb;
5975 struct status_pkt *spkt;
5976 uint32_t sgptr;
5977 uint32_t resid_sgptr;
5978 uint32_t resid;
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996 hscb = scb->hscb;
5997 sgptr = aic_le32toh(hscb->sgptr);
5998 if ((sgptr & SG_RESID_VALID) == 0)
5999
6000 return;
6001 sgptr &= ~SG_RESID_VALID;
6002
6003 if ((sgptr & SG_LIST_NULL) != 0)
6004
6005 return;
6006
6007 spkt = &hscb->shared_data.status;
6008 resid_sgptr = aic_le32toh(spkt->residual_sg_ptr);
6009 if ((sgptr & SG_FULL_RESID) != 0) {
6010
6011 resid = ahc_get_transfer_length(scb);
6012 } else if ((resid_sgptr & SG_LIST_NULL) != 0) {
6013
6014 return;
6015 } else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {
6016 panic("Bogus resid sgptr value 0x%x", resid_sgptr);
6017 } else {
6018 struct ahc_dma_seg *sg;
6019
6020
6021
6022
6023
6024 resid = aic_le32toh(spkt->residual_datacnt) & AHC_SG_LEN_MASK;
6025 sg = ahc_sg_bus_to_virt(scb, resid_sgptr & SG_PTR_MASK);
6026
6027
6028 sg--;
6029
6030
6031
6032
6033
6034
6035 while ((aic_le32toh(sg->len) & AHC_DMA_LAST_SEG) == 0) {
6036 sg++;
6037 resid += aic_le32toh(sg->len) & AHC_SG_LEN_MASK;
6038 }
6039 }
6040 if ((scb->flags & SCB_SENSE) == 0)
6041 ahc_set_residual(scb, resid);
6042 else
6043 ahc_set_sense_residual(scb, resid);
6044
6045 #ifdef AHC_DEBUG
6046 if ((ahc_debug & AHC_SHOW_MISC) != 0) {
6047 ahc_print_path(ahc, scb);
6048 printf("Handled %sResidual of %d bytes\n",
6049 (scb->flags & SCB_SENSE) ? "Sense " : "", resid);
6050 }
6051 #endif
6052 }
6053
6054
6055 #ifdef AHC_TARGET_MODE
6056
6057
6058
6059 static void
6060 ahc_queue_lstate_event(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate,
6061 u_int initiator_id, u_int event_type, u_int event_arg)
6062 {
6063 struct ahc_tmode_event *event;
6064 int pending;
6065
6066 xpt_freeze_devq(lstate->path, 1);
6067 if (lstate->event_w_idx >= lstate->event_r_idx)
6068 pending = lstate->event_w_idx - lstate->event_r_idx;
6069 else
6070 pending = AHC_TMODE_EVENT_BUFFER_SIZE + 1
6071 - (lstate->event_r_idx - lstate->event_w_idx);
6072
6073 if (event_type == EVENT_TYPE_BUS_RESET
6074 || event_type == MSG_BUS_DEV_RESET) {
6075
6076
6077
6078
6079
6080
6081 lstate->event_r_idx = 0;
6082 lstate->event_w_idx = 0;
6083 xpt_release_devq(lstate->path, pending, FALSE);
6084 }
6085
6086 if (pending == AHC_TMODE_EVENT_BUFFER_SIZE) {
6087 xpt_print_path(lstate->path);
6088 printf("immediate event %x:%x lost\n",
6089 lstate->event_buffer[lstate->event_r_idx].event_type,
6090 lstate->event_buffer[lstate->event_r_idx].event_arg);
6091 lstate->event_r_idx++;
6092 if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
6093 lstate->event_r_idx = 0;
6094 xpt_release_devq(lstate->path, 1, FALSE);
6095 }
6096
6097 event = &lstate->event_buffer[lstate->event_w_idx];
6098 event->initiator_id = initiator_id;
6099 event->event_type = event_type;
6100 event->event_arg = event_arg;
6101 lstate->event_w_idx++;
6102 if (lstate->event_w_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
6103 lstate->event_w_idx = 0;
6104 }
6105
6106
6107
6108
6109
6110 void
6111 ahc_send_lstate_events(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate)
6112 {
6113 struct ccb_hdr *ccbh;
6114 struct ccb_immed_notify *inot;
6115
6116 while (lstate->event_r_idx != lstate->event_w_idx
6117 && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) {
6118 struct ahc_tmode_event *event;
6119
6120 event = &lstate->event_buffer[lstate->event_r_idx];
6121 SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);
6122 inot = (struct ccb_immed_notify *)ccbh;
6123 switch (event->event_type) {
6124 case EVENT_TYPE_BUS_RESET:
6125 ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN;
6126 break;
6127 default:
6128 ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN;
6129 inot->message_args[0] = event->event_type;
6130 inot->message_args[1] = event->event_arg;
6131 break;
6132 }
6133 inot->initiator_id = event->initiator_id;
6134 inot->sense_len = 0;
6135 xpt_done((union ccb *)inot);
6136 lstate->event_r_idx++;
6137 if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
6138 lstate->event_r_idx = 0;
6139 }
6140 }
6141 #endif
6142
6143
6144
6145 #ifdef AHC_DUMP_SEQ
6146 void
6147 ahc_dumpseq(struct ahc_softc* ahc)
6148 {
6149 int i;
6150
6151 ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
6152 ahc_outb(ahc, SEQADDR0, 0);
6153 ahc_outb(ahc, SEQADDR1, 0);
6154 for (i = 0; i < ahc->instruction_ram_size; i++) {
6155 uint8_t ins_bytes[4];
6156
6157 ahc_insb(ahc, SEQRAM, ins_bytes, 4);
6158 printf("0x%08x\n", ins_bytes[0] << 24
6159 | ins_bytes[1] << 16
6160 | ins_bytes[2] << 8
6161 | ins_bytes[3]);
6162 }
6163 }
6164 #endif
6165
6166 static int
6167 ahc_loadseq(struct ahc_softc *ahc)
6168 {
6169 struct cs cs_table[NUM_CRITICAL_SECTIONS];
6170 u_int begin_set[NUM_CRITICAL_SECTIONS];
6171 u_int end_set[NUM_CRITICAL_SECTIONS];
6172 const struct patch *cur_patch;
6173 u_int cs_count;
6174 u_int cur_cs;
6175 u_int i;
6176 u_int skip_addr;
6177 u_int sg_prefetch_cnt;
6178 int downloaded;
6179 uint8_t download_consts[7];
6180
6181
6182
6183
6184
6185 cs_count = 0;
6186 cur_cs = 0;
6187 memset(begin_set, 0, sizeof(begin_set));
6188 memset(end_set, 0, sizeof(end_set));
6189
6190
6191 download_consts[QOUTFIFO_OFFSET] = 0;
6192 if (ahc->targetcmds != NULL)
6193 download_consts[QOUTFIFO_OFFSET] += 32;
6194 download_consts[QINFIFO_OFFSET] = download_consts[QOUTFIFO_OFFSET] + 1;
6195 download_consts[CACHESIZE_MASK] = ahc->pci_cachesize - 1;
6196 download_consts[INVERTED_CACHESIZE_MASK] = ~(ahc->pci_cachesize - 1);
6197 sg_prefetch_cnt = ahc->pci_cachesize;
6198 if (sg_prefetch_cnt < (2 * sizeof(struct ahc_dma_seg)))
6199 sg_prefetch_cnt = 2 * sizeof(struct ahc_dma_seg);
6200 download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt;
6201 download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_cnt - 1);
6202 download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_cnt - 1);
6203
6204 cur_patch = patches;
6205 downloaded = 0;
6206 skip_addr = 0;
6207 ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
6208 ahc_outb(ahc, SEQADDR0, 0);
6209 ahc_outb(ahc, SEQADDR1, 0);
6210
6211 for (i = 0; i < sizeof(seqprog)/4; i++) {
6212 if (ahc_check_patch(ahc, &cur_patch, i, &skip_addr) == 0) {
6213
6214
6215
6216
6217 continue;
6218 }
6219
6220 if (downloaded == ahc->instruction_ram_size) {
6221
6222
6223
6224
6225
6226 printf("\n%s: Program too large for instruction memory "
6227 "size of %d!\n", ahc_name(ahc),
6228 ahc->instruction_ram_size);
6229 return (ENOMEM);
6230 }
6231
6232
6233
6234
6235
6236 for (; cur_cs < NUM_CRITICAL_SECTIONS; cur_cs++) {
6237 if (critical_sections[cur_cs].end <= i) {
6238 if (begin_set[cs_count] == TRUE
6239 && end_set[cs_count] == FALSE) {
6240 cs_table[cs_count].end = downloaded;
6241 end_set[cs_count] = TRUE;
6242 cs_count++;
6243 }
6244 continue;
6245 }
6246 if (critical_sections[cur_cs].begin <= i
6247 && begin_set[cs_count] == FALSE) {
6248 cs_table[cs_count].begin = downloaded;
6249 begin_set[cs_count] = TRUE;
6250 }
6251 break;
6252 }
6253 ahc_download_instr(ahc, i, download_consts);
6254 downloaded++;
6255 }
6256
6257 ahc->num_critical_sections = cs_count;
6258 if (cs_count != 0) {
6259
6260 cs_count *= sizeof(struct cs);
6261 ahc->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT);
6262 if (ahc->critical_sections == NULL)
6263 panic("ahc_loadseq: Could not malloc");
6264 memcpy(ahc->critical_sections, cs_table, cs_count);
6265 }
6266 ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
6267
6268 if (bootverbose) {
6269 printf(" %d instructions downloaded\n", downloaded);
6270 printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
6271 ahc_name(ahc), ahc->features, ahc->bugs, ahc->flags);
6272 }
6273 return (0);
6274 }
6275
6276 static int
6277 ahc_check_patch(struct ahc_softc *ahc, const struct patch **start_patch,
6278 u_int start_instr, u_int *skip_addr)
6279 {
6280 const struct patch *cur_patch;
6281 const struct patch *last_patch;
6282 u_int num_patches;
6283
6284 num_patches = sizeof(patches)/sizeof(struct patch);
6285 last_patch = &patches[num_patches];
6286 cur_patch = *start_patch;
6287
6288 while (cur_patch < last_patch && start_instr == cur_patch->begin) {
6289
6290 if (cur_patch->patch_func(ahc) == 0) {
6291
6292
6293 *skip_addr = start_instr + cur_patch->skip_instr;
6294 cur_patch += cur_patch->skip_patch;
6295 } else {
6296
6297
6298
6299
6300 cur_patch++;
6301 }
6302 }
6303
6304 *start_patch = cur_patch;
6305 if (start_instr < *skip_addr)
6306
6307 return (0);
6308
6309 return (1);
6310 }
6311
6312 static void
6313 ahc_download_instr(struct ahc_softc *ahc, u_int instrptr, uint8_t *dconsts)
6314 {
6315 union ins_formats instr;
6316 struct ins_format1 *fmt1_ins;
6317 struct ins_format3 *fmt3_ins;
6318 u_int opcode;
6319
6320
6321
6322
6323 instr.integer = aic_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);
6324
6325 fmt1_ins = &instr.format1;
6326 fmt3_ins = NULL;
6327
6328
6329 opcode = instr.format1.opcode;
6330 switch (opcode) {
6331 case AIC_OP_JMP:
6332 case AIC_OP_JC:
6333 case AIC_OP_JNC:
6334 case AIC_OP_CALL:
6335 case AIC_OP_JNE:
6336 case AIC_OP_JNZ:
6337 case AIC_OP_JE:
6338 case AIC_OP_JZ:
6339 {
6340 const struct patch *cur_patch;
6341 int address_offset;
6342 u_int address;
6343 u_int skip_addr;
6344 u_int i;
6345
6346 fmt3_ins = &instr.format3;
6347 address_offset = 0;
6348 address = fmt3_ins->address;
6349 cur_patch = patches;
6350 skip_addr = 0;
6351
6352 for (i = 0; i < address;) {
6353
6354 ahc_check_patch(ahc, &cur_patch, i, &skip_addr);
6355
6356 if (skip_addr > i) {
6357 int end_addr;
6358
6359 end_addr = MIN(address, skip_addr);
6360 address_offset += end_addr - i;
6361 i = skip_addr;
6362 } else {
6363 i++;
6364 }
6365 }
6366 address -= address_offset;
6367 fmt3_ins->address = address;
6368
6369 }
6370 case AIC_OP_OR:
6371 case AIC_OP_AND:
6372 case AIC_OP_XOR:
6373 case AIC_OP_ADD:
6374 case AIC_OP_ADC:
6375 case AIC_OP_BMOV:
6376 if (fmt1_ins->parity != 0) {
6377 fmt1_ins->immediate = dconsts[fmt1_ins->immediate];
6378 }
6379 fmt1_ins->parity = 0;
6380 if ((ahc->features & AHC_CMD_CHAN) == 0
6381 && opcode == AIC_OP_BMOV) {
6382
6383
6384
6385
6386
6387
6388
6389 if (fmt1_ins->immediate != 1)
6390 panic("%s: BMOV not supported",
6391 ahc_name(ahc));
6392 fmt1_ins->opcode = AIC_OP_AND;
6393 fmt1_ins->immediate = 0xff;
6394 }
6395
6396 case AIC_OP_ROL:
6397 if ((ahc->features & AHC_ULTRA2) != 0) {
6398 int i, count;
6399
6400
6401 for (i = 0, count = 0; i < 31; i++) {
6402 uint32_t mask;
6403
6404 mask = 0x01 << i;
6405 if ((instr.integer & mask) != 0)
6406 count++;
6407 }
6408 if ((count & 0x01) == 0)
6409 instr.format1.parity = 1;
6410 } else {
6411
6412 if (fmt3_ins != NULL) {
6413 instr.integer =
6414 fmt3_ins->immediate
6415 | (fmt3_ins->source << 8)
6416 | (fmt3_ins->address << 16)
6417 | (fmt3_ins->opcode << 25);
6418 } else {
6419 instr.integer =
6420 fmt1_ins->immediate
6421 | (fmt1_ins->source << 8)
6422 | (fmt1_ins->destination << 16)
6423 | (fmt1_ins->ret << 24)
6424 | (fmt1_ins->opcode << 25);
6425 }
6426 }
6427
6428 instr.integer = aic_htole32(instr.integer);
6429 ahc_outsb(ahc, SEQRAM, instr.bytes, 4);
6430 break;
6431 default:
6432 panic("Unknown opcode encountered in seq program");
6433 break;
6434 }
6435 }
6436
6437 #ifndef SMALL_KERNEL
6438 int
6439 ahc_print_register(ahc_reg_parse_entry_t *table, u_int num_entries,
6440 const char *name, u_int address, u_int value,
6441 u_int *cur_column, u_int wrap_point)
6442 {
6443 u_int printed_mask;
6444 int entry, printed;
6445
6446 if (cur_column != NULL && *cur_column >= wrap_point) {
6447 printf("\n");
6448 *cur_column = 0;
6449 }
6450 printed = printf("%s[0x%x]", name, value);
6451 if (table == NULL) {
6452 printed += printf(" ");
6453 if (cur_column != NULL)
6454 *cur_column += printed;
6455 return (printed);
6456 }
6457
6458 printed_mask = 0;
6459 while (printed_mask != 0xFF) {
6460 for (entry = 0; entry < num_entries; entry++) {
6461 if (((value & table[entry].mask) != table[entry].value)
6462 || ((printed_mask & table[entry].mask) ==
6463 table[entry].mask))
6464 continue;
6465
6466 printed += printf("%s%s",
6467 printed_mask == 0 ? ":(" : "|",
6468 table[entry].name);
6469 printed_mask |= table[entry].mask;
6470
6471 break;
6472 }
6473 if (entry >= num_entries)
6474 break;
6475 }
6476
6477 printed += printf("%s", printed_mask == 0 ? " " : ") ");
6478 if (cur_column != NULL)
6479 *cur_column += printed;
6480
6481 return (printed);
6482 }
6483 #endif
6484
6485 void
6486 ahc_dump_card_state(struct ahc_softc *ahc)
6487 {
6488 #ifndef SMALL_KERNEL
6489 struct scb *scb;
6490 struct scb_tailq *untagged_q;
6491 u_int cur_col;
6492 int paused;
6493 int target;
6494 int maxtarget;
6495 int i;
6496 uint8_t last_phase;
6497 uint8_t qinpos;
6498 uint8_t qintail;
6499 uint8_t qoutpos;
6500 uint8_t scb_index;
6501 uint8_t saved_scbptr;
6502
6503 if (ahc_is_paused(ahc)) {
6504 paused = 1;
6505 } else {
6506 paused = 0;
6507 ahc_pause(ahc);
6508 }
6509
6510 saved_scbptr = ahc_inb(ahc, SCBPTR);
6511 last_phase = ahc_inb(ahc, LASTPHASE);
6512 printf("================== Dump Card State Begins =================\n"
6513 "%s: Dumping Card State %s, at SEQADDR 0x%x\n",
6514 ahc_name(ahc), ahc_lookup_phase_entry(last_phase)->phasemsg,
6515 ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
6516 if (paused)
6517 printf("Card was paused\n");
6518 printf("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n",
6519 ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX),
6520 ahc_inb(ahc, ARG_2));
6521 printf("HCNT = 0x%x SCBPTR = 0x%x\n", ahc_inb(ahc, HCNT),
6522 ahc_inb(ahc, SCBPTR));
6523 cur_col = 0;
6524 if ((ahc->features & AHC_DT) != 0)
6525 ahc_scsiphase_print(ahc_inb(ahc, SCSIPHASE), &cur_col, 50);
6526 ahc_scsisigi_print(ahc_inb(ahc, SCSISIGI), &cur_col, 50);
6527 ahc_error_print(ahc_inb(ahc, ERROR), &cur_col, 50);
6528 ahc_scsibusl_print(ahc_inb(ahc, SCSIBUSL), &cur_col, 50);
6529 ahc_lastphase_print(ahc_inb(ahc, LASTPHASE), &cur_col, 50);
6530 ahc_scsiseq_print(ahc_inb(ahc, SCSISEQ), &cur_col, 50);
6531 ahc_sblkctl_print(ahc_inb(ahc, SBLKCTL), &cur_col, 50);
6532 ahc_scsirate_print(ahc_inb(ahc, SCSIRATE), &cur_col, 50);
6533 ahc_seqctl_print(ahc_inb(ahc, SEQCTL), &cur_col, 50);
6534 ahc_seq_flags_print(ahc_inb(ahc, SEQ_FLAGS), &cur_col, 50);
6535 ahc_sstat0_print(ahc_inb(ahc, SSTAT0), &cur_col, 50);
6536 ahc_sstat1_print(ahc_inb(ahc, SSTAT1), &cur_col, 50);
6537 ahc_sstat2_print(ahc_inb(ahc, SSTAT2), &cur_col, 50);
6538 ahc_sstat3_print(ahc_inb(ahc, SSTAT3), &cur_col, 50);
6539 ahc_simode0_print(ahc_inb(ahc, SIMODE0), &cur_col, 50);
6540 ahc_simode1_print(ahc_inb(ahc, SIMODE1), &cur_col, 50);
6541 ahc_sxfrctl0_print(ahc_inb(ahc, SXFRCTL0), &cur_col, 50);
6542 ahc_dfcntrl_print(ahc_inb(ahc, DFCNTRL), &cur_col, 50);
6543 ahc_dfstatus_print(ahc_inb(ahc, DFSTATUS), &cur_col, 50);
6544 if (cur_col != 0)
6545 printf("\n");
6546 printf("STACK:");
6547 for (i = 0; i < STACK_SIZE; i++)
6548 printf(" 0x%x", ahc_inb(ahc, STACK)|(ahc_inb(ahc, STACK) << 8));
6549 printf("\nSCB count = %d\n", ahc->scb_data->numscbs);
6550 printf("Kernel NEXTQSCB = %d\n", ahc->next_queued_scb->hscb->tag);
6551 printf("Card NEXTQSCB = %d\n", ahc_inb(ahc, NEXT_QUEUED_SCB));
6552
6553 printf("QINFIFO entries: ");
6554 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
6555 qinpos = ahc_inb(ahc, SNSCB_QOFF);
6556 ahc_outb(ahc, SNSCB_QOFF, qinpos);
6557 } else
6558 qinpos = ahc_inb(ahc, QINPOS);
6559 qintail = ahc->qinfifonext;
6560 while (qinpos != qintail) {
6561 printf("%d ", ahc->qinfifo[qinpos]);
6562 qinpos++;
6563 }
6564 printf("\n");
6565
6566 printf("Waiting Queue entries: ");
6567 scb_index = ahc_inb(ahc, WAITING_SCBH);
6568 i = 0;
6569 while (scb_index != SCB_LIST_NULL && i++ < 256) {
6570 ahc_outb(ahc, SCBPTR, scb_index);
6571 printf("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
6572 scb_index = ahc_inb(ahc, SCB_NEXT);
6573 }
6574 printf("\n");
6575
6576 printf("Disconnected Queue entries: ");
6577 scb_index = ahc_inb(ahc, DISCONNECTED_SCBH);
6578 i = 0;
6579 while (scb_index != SCB_LIST_NULL && i++ < 256) {
6580 ahc_outb(ahc, SCBPTR, scb_index);
6581 printf("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
6582 scb_index = ahc_inb(ahc, SCB_NEXT);
6583 }
6584 printf("\n");
6585
6586 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
6587 printf("QOUTFIFO entries: ");
6588 qoutpos = ahc->qoutfifonext;
6589 i = 0;
6590 while (ahc->qoutfifo[qoutpos] != SCB_LIST_NULL && i++ < 256) {
6591 printf("%d ", ahc->qoutfifo[qoutpos]);
6592 qoutpos++;
6593 }
6594 printf("\n");
6595
6596 printf("Sequencer Free SCB List: ");
6597 scb_index = ahc_inb(ahc, FREE_SCBH);
6598 i = 0;
6599 while (scb_index != SCB_LIST_NULL && i++ < 256) {
6600 ahc_outb(ahc, SCBPTR, scb_index);
6601 printf("%d ", scb_index);
6602 scb_index = ahc_inb(ahc, SCB_NEXT);
6603 }
6604 printf("\n");
6605
6606 printf("Sequencer SCB Info: ");
6607 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
6608 ahc_outb(ahc, SCBPTR, i);
6609 printf("\n%3d ", i);
6610
6611 ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL), &cur_col, 60);
6612 ahc_scb_scsiid_print(ahc_inb(ahc, SCB_SCSIID), &cur_col, 60);
6613 ahc_scb_lun_print(ahc_inb(ahc, SCB_LUN), &cur_col, 60);
6614 ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60);
6615 }
6616 printf("\n");
6617
6618 printf("Pending list: ");
6619 i = 0;
6620 LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
6621 if (i++ > 256)
6622 break;
6623 printf("\n%3d ", scb->hscb->tag);
6624 ahc_scb_control_print(scb->hscb->control, &cur_col, 60);
6625 ahc_scb_scsiid_print(scb->hscb->scsiid, &cur_col, 60);
6626 ahc_scb_lun_print(scb->hscb->lun, &cur_col, 60);
6627 if ((ahc->flags & AHC_PAGESCBS) == 0) {
6628 ahc_outb(ahc, SCBPTR, scb->hscb->tag);
6629 printf("(");
6630 ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL),
6631 &cur_col, 60);
6632 ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60);
6633 printf(")");
6634 }
6635 }
6636 printf("\n");
6637
6638 printf("Kernel Free SCB list: ");
6639 i = 0;
6640 SLIST_FOREACH(scb, &ahc->scb_data->free_scbs, links.sle) {
6641 if (i++ > 256)
6642 break;
6643 printf("%d ", scb->hscb->tag);
6644 }
6645 printf("\n");
6646
6647 maxtarget = (ahc->features & (AHC_WIDE|AHC_TWIN)) ? 15 : 7;
6648 for (target = 0; target <= maxtarget; target++) {
6649 untagged_q = &ahc->untagged_queues[target];
6650 if (TAILQ_FIRST(untagged_q) == NULL)
6651 continue;
6652 printf("Untagged Q(%d): ", target);
6653 i = 0;
6654 TAILQ_FOREACH(scb, untagged_q, links.tqe) {
6655 if (i++ > 256)
6656 break;
6657 printf("%d ", scb->hscb->tag);
6658 }
6659 printf("\n");
6660 }
6661
6662 ahc_platform_dump_card_state(ahc);
6663 printf("\n================= Dump Card State Ends ==================\n");
6664 ahc_outb(ahc, SCBPTR, saved_scbptr);
6665 if (paused == 0)
6666 ahc_unpause(ahc);
6667 #endif
6668 }
6669
6670
6671 #ifdef AHC_TARGET_MODE
6672 cam_status
6673 ahc_find_tmode_devs(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb,
6674 struct ahc_tmode_tstate **tstate,
6675 struct ahc_tmode_lstate **lstate,
6676 int notfound_failure)
6677 {
6678
6679 if ((ahc->features & AHC_TARGETMODE) == 0)
6680 return (CAM_REQ_INVALID);
6681
6682
6683
6684
6685
6686 if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD
6687 && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {
6688 *tstate = NULL;
6689 *lstate = ahc->black_hole;
6690 } else {
6691 u_int max_id;
6692
6693 max_id = (ahc->features & AHC_WIDE) ? 15 : 7;
6694 if (ccb->ccb_h.target_id > max_id)
6695 return (CAM_TID_INVALID);
6696
6697 if (ccb->ccb_h.target_lun >= AHC_NUM_LUNS)
6698 return (CAM_LUN_INVALID);
6699
6700 *tstate = ahc->enabled_targets[ccb->ccb_h.target_id];
6701 *lstate = NULL;
6702 if (*tstate != NULL)
6703 *lstate =
6704 (*tstate)->enabled_luns[ccb->ccb_h.target_lun];
6705 }
6706
6707 if (notfound_failure != 0 && *lstate == NULL)
6708 return (CAM_PATH_INVALID);
6709
6710 return (CAM_REQ_CMP);
6711 }
6712
6713 void
6714 ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
6715 {
6716 struct ahc_tmode_tstate *tstate;
6717 struct ahc_tmode_lstate *lstate;
6718 struct ccb_en_lun *cel;
6719 cam_status status;
6720 u_long s;
6721 u_int target;
6722 u_int lun;
6723 u_int target_mask;
6724 u_int our_id;
6725 int error;
6726 char channel;
6727
6728 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, &lstate,
6729 FALSE);
6730
6731 if (status != CAM_REQ_CMP) {
6732 ccb->ccb_h.status = status;
6733 return;
6734 }
6735
6736 if (cam_sim_bus(sim) == 0)
6737 our_id = ahc->our_id;
6738 else
6739 our_id = ahc->our_id_b;
6740
6741 if (ccb->ccb_h.target_id != our_id) {
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761 if ((ahc->features & AHC_MULTIROLE) != 0) {
6762
6763 if ((ahc->features & AHC_MULTI_TID) != 0
6764 && (ahc->flags & AHC_INITIATORROLE) != 0) {
6765
6766
6767
6768
6769
6770
6771
6772 status = CAM_TID_INVALID;
6773 } else if ((ahc->flags & AHC_INITIATORROLE) != 0
6774 || ahc->enabled_luns > 0) {
6775
6776
6777
6778
6779
6780
6781
6782 status = CAM_TID_INVALID;
6783 }
6784 } else if ((ahc->features & AHC_MULTI_TID) == 0
6785 && ahc->enabled_luns > 0) {
6786
6787 status = CAM_TID_INVALID;
6788 }
6789 }
6790
6791 if (status != CAM_REQ_CMP) {
6792 ccb->ccb_h.status = status;
6793 return;
6794 }
6795
6796
6797
6798
6799
6800 if ((ahc->flags & AHC_TARGETROLE) == 0
6801 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
6802 u_long s;
6803 ahc_flag saved_flags;
6804
6805 printf("Configuring Target Mode\n");
6806 s = splbio();
6807 if (LIST_FIRST(&ahc->pending_scbs) != NULL) {
6808 ccb->ccb_h.status = CAM_BUSY;
6809 splx(s);
6810 return;
6811 }
6812 saved_flags = ahc->flags;
6813 ahc->flags |= AHC_TARGETROLE;
6814 if ((ahc->features & AHC_MULTIROLE) == 0)
6815 ahc->flags &= ~AHC_INITIATORROLE;
6816 ahc_pause(ahc);
6817 error = ahc_loadseq(ahc);
6818 if (error != 0) {
6819
6820
6821
6822
6823
6824
6825
6826
6827 ahc->flags = saved_flags;
6828 (void)ahc_loadseq(ahc);
6829 ahc_restart(ahc);
6830 splx(s);
6831 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
6832 return;
6833 }
6834 ahc_restart(ahc);
6835 splx(s);
6836 }
6837 cel = &ccb->cel;
6838 target = ccb->ccb_h.target_id;
6839 lun = ccb->ccb_h.target_lun;
6840 channel = SIM_CHANNEL(ahc, sim);
6841 target_mask = 0x01 << target;
6842 if (channel == 'B')
6843 target_mask <<= 8;
6844
6845 if (cel->enable != 0) {
6846 u_int scsiseq;
6847
6848
6849 if (lstate != NULL) {
6850 xpt_print_path(ccb->ccb_h.path);
6851 printf("Lun already enabled\n");
6852 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
6853 return;
6854 }
6855
6856 if (cel->grp6_len != 0
6857 || cel->grp7_len != 0) {
6858
6859
6860
6861
6862 ccb->ccb_h.status = CAM_REQ_INVALID;
6863 printf("Non-zero Group Codes\n");
6864 return;
6865 }
6866
6867
6868
6869
6870
6871 if (target != CAM_TARGET_WILDCARD && tstate == NULL) {
6872 tstate = ahc_alloc_tstate(ahc, target, channel);
6873 if (tstate == NULL) {
6874 xpt_print_path(ccb->ccb_h.path);
6875 printf("Couldn't allocate tstate\n");
6876 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
6877 return;
6878 }
6879 }
6880 lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT);
6881 if (lstate == NULL) {
6882 xpt_print_path(ccb->ccb_h.path);
6883 printf("Couldn't allocate lstate\n");
6884 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
6885 return;
6886 }
6887 memset(lstate, 0, sizeof(*lstate));
6888 status = xpt_create_path(&lstate->path, NULL,
6889 xpt_path_path_id(ccb->ccb_h.path),
6890 xpt_path_target_id(ccb->ccb_h.path),
6891 xpt_path_lun_id(ccb->ccb_h.path));
6892 if (status != CAM_REQ_CMP) {
6893 free(lstate, M_DEVBUF);
6894 xpt_print_path(ccb->ccb_h.path);
6895 printf("Couldn't allocate path\n");
6896 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
6897 return;
6898 }
6899 SLIST_INIT(&lstate->accept_tios);
6900 SLIST_INIT(&lstate->immed_notifies);
6901 s = splbio();
6902 ahc_pause(ahc);
6903 if (target != CAM_TARGET_WILDCARD) {
6904 tstate->enabled_luns[lun] = lstate;
6905 ahc->enabled_luns++;
6906
6907 if ((ahc->features & AHC_MULTI_TID) != 0) {
6908 u_int targid_mask;
6909
6910 targid_mask = ahc_inb(ahc, TARGID)
6911 | (ahc_inb(ahc, TARGID + 1) << 8);
6912
6913 targid_mask |= target_mask;
6914 ahc_outb(ahc, TARGID, targid_mask);
6915 ahc_outb(ahc, TARGID+1, (targid_mask >> 8));
6916
6917 ahc_update_scsiid(ahc, targid_mask);
6918 } else {
6919 u_int our_id;
6920 char channel;
6921
6922 channel = SIM_CHANNEL(ahc, sim);
6923 our_id = SIM_SCSI_ID(ahc, sim);
6924
6925
6926
6927
6928
6929 if (target != our_id) {
6930 u_int sblkctl;
6931 char cur_channel;
6932 int swap;
6933
6934 sblkctl = ahc_inb(ahc, SBLKCTL);
6935 cur_channel = (sblkctl & SELBUSB)
6936 ? 'B' : 'A';
6937 if ((ahc->features & AHC_TWIN) == 0)
6938 cur_channel = 'A';
6939 swap = cur_channel != channel;
6940 if (channel == 'A')
6941 ahc->our_id = target;
6942 else
6943 ahc->our_id_b = target;
6944
6945 if (swap)
6946 ahc_outb(ahc, SBLKCTL,
6947 sblkctl ^ SELBUSB);
6948
6949 ahc_outb(ahc, SCSIID, target);
6950
6951 if (swap)
6952 ahc_outb(ahc, SBLKCTL, sblkctl);
6953 }
6954 }
6955 } else
6956 ahc->black_hole = lstate;
6957
6958 if (ahc->black_hole != NULL && ahc->enabled_luns > 0) {
6959 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
6960 scsiseq |= ENSELI;
6961 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
6962 scsiseq = ahc_inb(ahc, SCSISEQ);
6963 scsiseq |= ENSELI;
6964 ahc_outb(ahc, SCSISEQ, scsiseq);
6965 }
6966 ahc_unpause(ahc);
6967 splx(s);
6968 ccb->ccb_h.status = CAM_REQ_CMP;
6969 xpt_print_path(ccb->ccb_h.path);
6970 printf("Lun now enabled for target mode\n");
6971 } else {
6972 struct scb *scb;
6973 int i, empty;
6974
6975 if (lstate == NULL) {
6976 ccb->ccb_h.status = CAM_LUN_INVALID;
6977 return;
6978 }
6979
6980 s = splbio();
6981
6982 ccb->ccb_h.status = CAM_REQ_CMP;
6983 LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
6984 struct ccb_hdr *ccbh;
6985
6986 ccbh = &scb->io_ctx->ccb_h;
6987 if (ccbh->func_code == XPT_CONT_TARGET_IO
6988 && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
6989 printf("CTIO pending\n");
6990 ccb->ccb_h.status = CAM_REQ_INVALID;
6991 splx(s);
6992 return;
6993 }
6994 }
6995
6996 if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
6997 printf("ATIOs pending\n");
6998 ccb->ccb_h.status = CAM_REQ_INVALID;
6999 }
7000
7001 if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
7002 printf("INOTs pending\n");
7003 ccb->ccb_h.status = CAM_REQ_INVALID;
7004 }
7005
7006 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7007 splx(s);
7008 return;
7009 }
7010
7011 xpt_print_path(ccb->ccb_h.path);
7012 printf("Target mode disabled\n");
7013 xpt_free_path(lstate->path);
7014 free(lstate, M_DEVBUF);
7015
7016 ahc_pause(ahc);
7017
7018 if (target != CAM_TARGET_WILDCARD) {
7019 tstate->enabled_luns[lun] = NULL;
7020 ahc->enabled_luns--;
7021 for (empty = 1, i = 0; i < 8; i++)
7022 if (tstate->enabled_luns[i] != NULL) {
7023 empty = 0;
7024 break;
7025 }
7026
7027 if (empty) {
7028 ahc_free_tstate(ahc, target, channel,
7029 FALSE);
7030 if (ahc->features & AHC_MULTI_TID) {
7031 u_int targid_mask;
7032
7033 targid_mask = ahc_inb(ahc, TARGID)
7034 | (ahc_inb(ahc, TARGID + 1)
7035 << 8);
7036
7037 targid_mask &= ~target_mask;
7038 ahc_outb(ahc, TARGID, targid_mask);
7039 ahc_outb(ahc, TARGID+1,
7040 (targid_mask >> 8));
7041 ahc_update_scsiid(ahc, targid_mask);
7042 }
7043 }
7044 } else {
7045
7046 ahc->black_hole = NULL;
7047
7048
7049
7050
7051
7052 empty = TRUE;
7053 }
7054 if (ahc->enabled_luns == 0) {
7055
7056 u_int scsiseq;
7057
7058 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
7059 scsiseq &= ~ENSELI;
7060 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
7061 scsiseq = ahc_inb(ahc, SCSISEQ);
7062 scsiseq &= ~ENSELI;
7063 ahc_outb(ahc, SCSISEQ, scsiseq);
7064
7065 if ((ahc->features & AHC_MULTIROLE) == 0) {
7066 printf("Configuring Initiator Mode\n");
7067 ahc->flags &= ~AHC_TARGETROLE;
7068 ahc->flags |= AHC_INITIATORROLE;
7069
7070
7071
7072
7073 (void)ahc_loadseq(ahc);
7074 ahc_restart(ahc);
7075
7076
7077
7078
7079 }
7080 }
7081 ahc_unpause(ahc);
7082 splx(s);
7083 }
7084 }
7085
7086 static void
7087 ahc_update_scsiid(struct ahc_softc *ahc, u_int targid_mask)
7088 {
7089 u_int scsiid_mask;
7090 u_int scsiid;
7091
7092 if ((ahc->features & AHC_MULTI_TID) == 0)
7093 panic("ahc_update_scsiid called on non-multitid unit");
7094
7095
7096
7097
7098
7099
7100
7101 if ((ahc->features & AHC_ULTRA2) != 0)
7102 scsiid = ahc_inb(ahc, SCSIID_ULTRA2);
7103 else
7104 scsiid = ahc_inb(ahc, SCSIID);
7105 scsiid_mask = 0x1 << (scsiid & OID);
7106 if ((targid_mask & scsiid_mask) == 0) {
7107 u_int our_id;
7108
7109
7110 our_id = ffs(targid_mask);
7111 if (our_id == 0)
7112 our_id = ahc->our_id;
7113 else
7114 our_id--;
7115 scsiid &= TID;
7116 scsiid |= our_id;
7117 }
7118 if ((ahc->features & AHC_ULTRA2) != 0)
7119 ahc_outb(ahc, SCSIID_ULTRA2, scsiid);
7120 else
7121 ahc_outb(ahc, SCSIID, scsiid);
7122 }
7123
7124 #ifdef AHC_TARGET_MODE
7125 void
7126 ahc_run_tqinfifo(struct ahc_softc *ahc, int paused)
7127 {
7128 struct target_cmd *cmd;
7129
7130
7131
7132
7133
7134
7135 if ((ahc->features & AHC_AUTOPAUSE) != 0)
7136 paused = TRUE;
7137
7138 ahc_sync_tqinfifo(ahc, BUS_DMASYNC_POSTREAD);
7139 while ((cmd = &ahc->targetcmds[ahc->tqinfifonext])->cmd_valid != 0) {
7140
7141
7142
7143
7144
7145 if (ahc_handle_target_cmd(ahc, cmd) != 0)
7146 break;
7147
7148 cmd->cmd_valid = 0;
7149 ahc_dmamap_sync(ahc, ahc->parent_dmat,
7150 ahc->shared_data_dmamap,
7151 ahc_targetcmd_offset(ahc, ahc->tqinfifonext),
7152 sizeof(struct target_cmd),
7153 #ifdef __sgi__
7154 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
7155 #else
7156 BUS_DMASYNC_PREREAD);
7157 #endif
7158 ahc->tqinfifonext++;
7159
7160
7161
7162
7163
7164 if ((ahc->tqinfifonext & (HOST_TQINPOS - 1)) == 1) {
7165 if ((ahc->features & AHC_HS_MAILBOX) != 0) {
7166 u_int hs_mailbox;
7167
7168 hs_mailbox = ahc_inb(ahc, HS_MAILBOX);
7169 hs_mailbox &= ~HOST_TQINPOS;
7170 hs_mailbox |= ahc->tqinfifonext & HOST_TQINPOS;
7171 ahc_outb(ahc, HS_MAILBOX, hs_mailbox);
7172 } else {
7173 if (!paused)
7174 ahc_pause(ahc);
7175 ahc_outb(ahc, KERNEL_TQINPOS,
7176 ahc->tqinfifonext & HOST_TQINPOS);
7177 if (!paused)
7178 ahc_unpause(ahc);
7179 }
7180 }
7181 }
7182 }
7183 #endif
7184
7185 static int
7186 ahc_handle_target_cmd(struct ahc_softc *ahc, struct target_cmd *cmd)
7187 {
7188 struct ahc_tmode_tstate *tstate;
7189 struct ahc_tmode_lstate *lstate;
7190 struct ccb_accept_tio *atio;
7191 uint8_t *byte;
7192 int initiator;
7193 int target;
7194 int lun;
7195
7196 initiator = SCSIID_TARGET(ahc, cmd->scsiid);
7197 target = SCSIID_OUR_ID(cmd->scsiid);
7198 lun = (cmd->identify & MSG_IDENTIFY_LUNMASK);
7199
7200 byte = cmd->bytes;
7201 tstate = ahc->enabled_targets[target];
7202 lstate = NULL;
7203 if (tstate != NULL)
7204 lstate = tstate->enabled_luns[lun];
7205
7206
7207
7208
7209 if (lstate == NULL)
7210 lstate = ahc->black_hole;
7211
7212 atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios);
7213 if (atio == NULL) {
7214 ahc->flags |= AHC_TQINFIFO_BLOCKED;
7215
7216
7217
7218 if (bootverbose)
7219 printf("%s: ATIOs exhausted\n", ahc_name(ahc));
7220 return (1);
7221 } else
7222 ahc->flags &= ~AHC_TQINFIFO_BLOCKED;
7223 #if 0
7224 printf("Incoming command from %d for %d:%d%s\n",
7225 initiator, target, lun,
7226 lstate == ahc->black_hole ? "(Black Holed)" : "");
7227 #endif
7228 SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);
7229
7230 if (lstate == ahc->black_hole) {
7231
7232 atio->ccb_h.target_id = target;
7233 atio->ccb_h.target_lun = lun;
7234 }
7235
7236
7237
7238
7239
7240 atio->sense_len = 0;
7241 atio->init_id = initiator;
7242 if (byte[0] != 0xFF) {
7243
7244 atio->tag_action = *byte++;
7245 atio->tag_id = *byte++;
7246 atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
7247 } else {
7248 atio->ccb_h.flags = 0;
7249 }
7250 byte++;
7251
7252
7253 switch (*byte >> CMD_GROUP_CODE_SHIFT) {
7254 case 0:
7255 atio->cdb_len = 6;
7256 break;
7257 case 1:
7258 case 2:
7259 atio->cdb_len = 10;
7260 break;
7261 case 4:
7262 atio->cdb_len = 16;
7263 break;
7264 case 5:
7265 atio->cdb_len = 12;
7266 break;
7267 case 3:
7268 default:
7269
7270 atio->cdb_len = 1;
7271 printf("Reserved or VU command code type encountered\n");
7272 break;
7273 }
7274
7275 memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);
7276
7277 atio->ccb_h.status |= CAM_CDB_RECVD;
7278
7279 if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) {
7280
7281
7282
7283
7284
7285
7286 #if 0
7287 printf("Received Immediate Command %d:%d:%d - %p\n",
7288 initiator, target, lun, ahc->pending_device);
7289 #endif
7290 ahc->pending_device = lstate;
7291 ahc_freeze_ccb((union ccb *)atio);
7292 atio->ccb_h.flags |= CAM_DIS_DISCONNECT;
7293 }
7294 xpt_done((union ccb*)atio);
7295 return (0);
7296 }
7297 #endif
7298
7299 static int
7300 ahc_createdmamem(bus_dma_tag_t tag, int size, int flags, bus_dmamap_t *mapp,
7301 caddr_t *vaddr, bus_addr_t *baddr, bus_dma_segment_t *seg, int *nseg,
7302 const char *myname, const char *what)
7303 {
7304 int error;
7305
7306 if ((error = bus_dmamap_create(tag, size, 1, size, 0,
7307 BUS_DMA_NOWAIT | flags, mapp)) != 0) {
7308 printf("%s: failed to create DMA map for %s, error = %d\n",
7309 myname, what, error);
7310 return (error);
7311 }
7312
7313 if ((error = bus_dmamem_alloc(tag, size, PAGE_SIZE, 0,
7314 seg, 1, nseg, BUS_DMA_NOWAIT)) != 0) {
7315 printf("%s: failed to allocate DMA mem for %s, error = %d\n",
7316 myname, what, error);
7317 goto destroy;
7318 }
7319
7320 if ((error = bus_dmamem_map(tag, seg, *nseg, size, vaddr,
7321 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
7322 printf("%s: failed to map DMA mem for %s, error = %d\n",
7323 myname, what, error);
7324 goto free;
7325 }
7326
7327 if ((error = bus_dmamap_load(tag, *mapp, *vaddr, size, NULL,
7328 BUS_DMA_NOWAIT)) != 0) {
7329 printf("%s: failed to load DMA map for %s, error = %d\n",
7330 myname, what, error);
7331 goto unmap;
7332 }
7333
7334 *baddr = (*mapp)->dm_segs[0].ds_addr;
7335 return (0);
7336
7337 unmap:
7338 bus_dmamem_unmap(tag, *vaddr, size);
7339 free:
7340 bus_dmamem_free(tag, seg, *nseg);
7341 destroy:
7342 bus_dmamap_destroy(tag, *mapp);
7343
7344 *vaddr = 0;
7345 bzero(seg, sizeof(*seg));
7346 return (error);
7347 }
7348
7349 static void
7350 ahc_freedmamem(bus_dma_tag_t tag, int size, bus_dmamap_t map, caddr_t vaddr,
7351 bus_dma_segment_t *seg, int nseg)
7352 {
7353
7354 bus_dmamap_unload(tag, map);
7355 bus_dmamem_unmap(tag, vaddr, size);
7356 bus_dmamem_free(tag, seg, nseg);
7357 bus_dmamap_destroy(tag, map);
7358 }