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