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