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