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