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 void ahd_stat_timer(struct timer_list *t);
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("Resetting 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 timer_setup(&ahd->stat_timer, ahd_stat_timer, 0);
6108 ahd->int_coalescing_timer = AHD_INT_COALESCING_TIMER_DEFAULT;
6109 ahd->int_coalescing_maxcmds = AHD_INT_COALESCING_MAXCMDS_DEFAULT;
6110 ahd->int_coalescing_mincmds = AHD_INT_COALESCING_MINCMDS_DEFAULT;
6111 ahd->int_coalescing_threshold = AHD_INT_COALESCING_THRESHOLD_DEFAULT;
6112 ahd->int_coalescing_stop_threshold =
6113 AHD_INT_COALESCING_STOP_THRESHOLD_DEFAULT;
6114
6115#ifdef AHD_DEBUG
6116 if ((ahd_debug & AHD_SHOW_MEMORY) != 0) {
6117 printk("%s: scb size = 0x%x, hscb size = 0x%x\n",
6118 ahd_name(ahd), (u_int)sizeof(struct scb),
6119 (u_int)sizeof(struct hardware_scb));
6120 }
6121#endif
6122 if (ahd_platform_alloc(ahd, platform_arg) != 0) {
6123 ahd_free(ahd);
6124 ahd = NULL;
6125 }
6126 return (ahd);
6127}
6128
6129int
6130ahd_softc_init(struct ahd_softc *ahd)
6131{
6132
6133 ahd->unpause = 0;
6134 ahd->pause = PAUSE;
6135 return (0);
6136}
6137
6138void
6139ahd_set_unit(struct ahd_softc *ahd, int unit)
6140{
6141 ahd->unit = unit;
6142}
6143
6144void
6145ahd_set_name(struct ahd_softc *ahd, char *name)
6146{
6147 if (ahd->name != NULL)
6148 kfree(ahd->name);
6149 ahd->name = name;
6150}
6151
6152void
6153ahd_free(struct ahd_softc *ahd)
6154{
6155 int i;
6156
6157 switch (ahd->init_level) {
6158 default:
6159 case 5:
6160 ahd_shutdown(ahd);
6161
6162 case 4:
6163 ahd_dmamap_unload(ahd, ahd->shared_data_dmat,
6164 ahd->shared_data_map.dmamap);
6165
6166 case 3:
6167 ahd_dmamem_free(ahd, ahd->shared_data_dmat, ahd->qoutfifo,
6168 ahd->shared_data_map.dmamap);
6169 ahd_dmamap_destroy(ahd, ahd->shared_data_dmat,
6170 ahd->shared_data_map.dmamap);
6171
6172 case 2:
6173 ahd_dma_tag_destroy(ahd, ahd->shared_data_dmat);
6174 case 1:
6175#ifndef __linux__
6176 ahd_dma_tag_destroy(ahd, ahd->buffer_dmat);
6177#endif
6178 break;
6179 case 0:
6180 break;
6181 }
6182
6183#ifndef __linux__
6184 ahd_dma_tag_destroy(ahd, ahd->parent_dmat);
6185#endif
6186 ahd_platform_free(ahd);
6187 ahd_fini_scbdata(ahd);
6188 for (i = 0; i < AHD_NUM_TARGETS; i++) {
6189 struct ahd_tmode_tstate *tstate;
6190
6191 tstate = ahd->enabled_targets[i];
6192 if (tstate != NULL) {
6193#ifdef AHD_TARGET_MODE
6194 int j;
6195
6196 for (j = 0; j < AHD_NUM_LUNS; j++) {
6197 struct ahd_tmode_lstate *lstate;
6198
6199 lstate = tstate->enabled_luns[j];
6200 if (lstate != NULL) {
6201 xpt_free_path(lstate->path);
6202 kfree(lstate);
6203 }
6204 }
6205#endif
6206 kfree(tstate);
6207 }
6208 }
6209#ifdef AHD_TARGET_MODE
6210 if (ahd->black_hole != NULL) {
6211 xpt_free_path(ahd->black_hole->path);
6212 kfree(ahd->black_hole);
6213 }
6214#endif
6215 if (ahd->name != NULL)
6216 kfree(ahd->name);
6217 if (ahd->seep_config != NULL)
6218 kfree(ahd->seep_config);
6219 if (ahd->saved_stack != NULL)
6220 kfree(ahd->saved_stack);
6221#ifndef __FreeBSD__
6222 kfree(ahd);
6223#endif
6224 return;
6225}
6226
6227static void
6228ahd_shutdown(void *arg)
6229{
6230 struct ahd_softc *ahd;
6231
6232 ahd = (struct ahd_softc *)arg;
6233
6234
6235
6236
6237 del_timer_sync(&ahd->stat_timer);
6238
6239
6240 ahd_reset(ahd, FALSE);
6241}
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252int
6253ahd_reset(struct ahd_softc *ahd, int reinit)
6254{
6255 u_int sxfrctl1;
6256 int wait;
6257 uint32_t cmd;
6258
6259
6260
6261
6262
6263
6264 ahd_pause(ahd);
6265 ahd_update_modes(ahd);
6266 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
6267 sxfrctl1 = ahd_inb(ahd, SXFRCTL1);
6268
6269 cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 2);
6270 if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) {
6271 uint32_t mod_cmd;
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282 mod_cmd = cmd & ~(PCIM_CMD_PERRESPEN|PCIM_CMD_SERRESPEN);
6283 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
6284 mod_cmd, 2);
6285 }
6286 ahd_outb(ahd, HCNTRL, CHIPRST | ahd->pause);
6287
6288
6289
6290
6291
6292
6293
6294 wait = 1000;
6295 do {
6296 ahd_delay(1000);
6297 } while (--wait && !(ahd_inb(ahd, HCNTRL) & CHIPRSTACK));
6298
6299 if (wait == 0) {
6300 printk("%s: WARNING - Failed chip reset! "
6301 "Trying to initialize anyway.\n", ahd_name(ahd));
6302 }
6303 ahd_outb(ahd, HCNTRL, ahd->pause);
6304
6305 if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) {
6306
6307
6308
6309
6310 ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
6311 0xFF, 1);
6312 ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
6313 cmd, 2);
6314 }
6315
6316
6317
6318
6319
6320
6321
6322 ahd_known_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
6323 ahd_outb(ahd, MODE_PTR,
6324 ahd_build_mode_state(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI));
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334 ahd_outb(ahd, SXFRCTL1, sxfrctl1|STPWEN);
6335 ahd_outb(ahd, SXFRCTL1, sxfrctl1);
6336
6337
6338 ahd->features &= ~AHD_WIDE;
6339 if ((ahd_inb(ahd, SBLKCTL) & SELWIDE) != 0)
6340 ahd->features |= AHD_WIDE;
6341
6342
6343
6344
6345
6346 if (reinit != 0)
6347 ahd_chip_init(ahd);
6348
6349 return (0);
6350}
6351
6352
6353
6354
6355static int
6356ahd_probe_scbs(struct ahd_softc *ahd) {
6357 int i;
6358
6359 AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
6360 ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK));
6361 for (i = 0; i < AHD_SCB_MAX; i++) {
6362 int j;
6363
6364 ahd_set_scbptr(ahd, i);
6365 ahd_outw(ahd, SCB_BASE, i);
6366 for (j = 2; j < 64; j++)
6367 ahd_outb(ahd, SCB_BASE+j, 0);
6368
6369 ahd_outb(ahd, SCB_CONTROL, MK_MESSAGE);
6370 if (ahd_inw_scbram(ahd, SCB_BASE) != i)
6371 break;
6372 ahd_set_scbptr(ahd, 0);
6373 if (ahd_inw_scbram(ahd, SCB_BASE) != 0)
6374 break;
6375 }
6376 return (i);
6377}
6378
6379static void
6380ahd_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
6381{
6382 dma_addr_t *baddr;
6383
6384 baddr = (dma_addr_t *)arg;
6385 *baddr = segs->ds_addr;
6386}
6387
6388static void
6389ahd_initialize_hscbs(struct ahd_softc *ahd)
6390{
6391 int i;
6392
6393 for (i = 0; i < ahd->scb_data.maxhscbs; i++) {
6394 ahd_set_scbptr(ahd, i);
6395
6396
6397 ahd_outb(ahd, SCB_CONTROL, 0);
6398
6399
6400 ahd_outw(ahd, SCB_NEXT, SCB_LIST_NULL);
6401 }
6402}
6403
6404static int
6405ahd_init_scbdata(struct ahd_softc *ahd)
6406{
6407 struct scb_data *scb_data;
6408 int i;
6409
6410 scb_data = &ahd->scb_data;
6411 TAILQ_INIT(&scb_data->free_scbs);
6412 for (i = 0; i < AHD_NUM_TARGETS * AHD_NUM_LUNS_NONPKT; i++)
6413 LIST_INIT(&scb_data->free_scb_lists[i]);
6414 LIST_INIT(&scb_data->any_dev_free_scb_list);
6415 SLIST_INIT(&scb_data->hscb_maps);
6416 SLIST_INIT(&scb_data->sg_maps);
6417 SLIST_INIT(&scb_data->sense_maps);
6418
6419
6420 scb_data->maxhscbs = ahd_probe_scbs(ahd);
6421 if (scb_data->maxhscbs == 0) {
6422 printk("%s: No SCB space found\n", ahd_name(ahd));
6423 return (ENXIO);
6424 }
6425
6426 ahd_initialize_hscbs(ahd);
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, 1,
6440 BUS_SPACE_MAXADDR_32BIT + 1,
6441 BUS_SPACE_MAXADDR_32BIT,
6442 BUS_SPACE_MAXADDR,
6443 NULL, NULL,
6444 PAGE_SIZE, 1,
6445 BUS_SPACE_MAXSIZE_32BIT,
6446 0, &scb_data->hscb_dmat) != 0) {
6447 goto error_exit;
6448 }
6449
6450 scb_data->init_level++;
6451
6452
6453 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, 8,
6454 BUS_SPACE_MAXADDR_32BIT + 1,
6455 BUS_SPACE_MAXADDR_32BIT,
6456 BUS_SPACE_MAXADDR,
6457 NULL, NULL,
6458 ahd_sglist_allocsize(ahd), 1,
6459 BUS_SPACE_MAXSIZE_32BIT,
6460 0, &scb_data->sg_dmat) != 0) {
6461 goto error_exit;
6462 }
6463#ifdef AHD_DEBUG
6464 if ((ahd_debug & AHD_SHOW_MEMORY) != 0)
6465 printk("%s: ahd_sglist_allocsize = 0x%x\n", ahd_name(ahd),
6466 ahd_sglist_allocsize(ahd));
6467#endif
6468
6469 scb_data->init_level++;
6470
6471
6472 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, 1,
6473 BUS_SPACE_MAXADDR_32BIT + 1,
6474 BUS_SPACE_MAXADDR_32BIT,
6475 BUS_SPACE_MAXADDR,
6476 NULL, NULL,
6477 PAGE_SIZE, 1,
6478 BUS_SPACE_MAXSIZE_32BIT,
6479 0, &scb_data->sense_dmat) != 0) {
6480 goto error_exit;
6481 }
6482
6483 scb_data->init_level++;
6484
6485
6486 ahd_alloc_scbs(ahd);
6487
6488 if (scb_data->numscbs == 0) {
6489 printk("%s: ahd_init_scbdata - "
6490 "Unable to allocate initial scbs\n",
6491 ahd_name(ahd));
6492 goto error_exit;
6493 }
6494
6495
6496
6497
6498 return (0);
6499
6500error_exit:
6501
6502 return (ENOMEM);
6503}
6504
6505static struct scb *
6506ahd_find_scb_by_tag(struct ahd_softc *ahd, u_int tag)
6507{
6508 struct scb *scb;
6509
6510
6511
6512
6513 LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
6514 if (SCB_GET_TAG(scb) == tag)
6515 return (scb);
6516 }
6517
6518
6519
6520
6521 TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
6522 struct scb *list_scb;
6523
6524 list_scb = scb;
6525 do {
6526 if (SCB_GET_TAG(list_scb) == tag)
6527 return (list_scb);
6528 list_scb = LIST_NEXT(list_scb, collision_links);
6529 } while (list_scb);
6530 }
6531
6532
6533
6534
6535 LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) {
6536 if (SCB_GET_TAG(scb) == tag)
6537 return (scb);
6538 }
6539
6540 return (NULL);
6541}
6542
6543static void
6544ahd_fini_scbdata(struct ahd_softc *ahd)
6545{
6546 struct scb_data *scb_data;
6547
6548 scb_data = &ahd->scb_data;
6549 if (scb_data == NULL)
6550 return;
6551
6552 switch (scb_data->init_level) {
6553 default:
6554 case 7:
6555 {
6556 struct map_node *sns_map;
6557
6558 while ((sns_map = SLIST_FIRST(&scb_data->sense_maps)) != NULL) {
6559 SLIST_REMOVE_HEAD(&scb_data->sense_maps, links);
6560 ahd_dmamap_unload(ahd, scb_data->sense_dmat,
6561 sns_map->dmamap);
6562 ahd_dmamem_free(ahd, scb_data->sense_dmat,
6563 sns_map->vaddr, sns_map->dmamap);
6564 kfree(sns_map);
6565 }
6566 ahd_dma_tag_destroy(ahd, scb_data->sense_dmat);
6567
6568 }
6569 case 6:
6570 {
6571 struct map_node *sg_map;
6572
6573 while ((sg_map = SLIST_FIRST(&scb_data->sg_maps)) != NULL) {
6574 SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
6575 ahd_dmamap_unload(ahd, scb_data->sg_dmat,
6576 sg_map->dmamap);
6577 ahd_dmamem_free(ahd, scb_data->sg_dmat,
6578 sg_map->vaddr, sg_map->dmamap);
6579 kfree(sg_map);
6580 }
6581 ahd_dma_tag_destroy(ahd, scb_data->sg_dmat);
6582
6583 }
6584 case 5:
6585 {
6586 struct map_node *hscb_map;
6587
6588 while ((hscb_map = SLIST_FIRST(&scb_data->hscb_maps)) != NULL) {
6589 SLIST_REMOVE_HEAD(&scb_data->hscb_maps, links);
6590 ahd_dmamap_unload(ahd, scb_data->hscb_dmat,
6591 hscb_map->dmamap);
6592 ahd_dmamem_free(ahd, scb_data->hscb_dmat,
6593 hscb_map->vaddr, hscb_map->dmamap);
6594 kfree(hscb_map);
6595 }
6596 ahd_dma_tag_destroy(ahd, scb_data->hscb_dmat);
6597
6598 }
6599 case 4:
6600 case 3:
6601 case 2:
6602 case 1:
6603 case 0:
6604 break;
6605 }
6606}
6607
6608
6609
6610
6611
6612static void
6613ahd_setup_iocell_workaround(struct ahd_softc *ahd)
6614{
6615 ahd_mode_state saved_modes;
6616
6617 saved_modes = ahd_save_modes(ahd);
6618 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
6619 ahd_outb(ahd, DSPDATACTL, ahd_inb(ahd, DSPDATACTL)
6620 | BYPASSENAB | RCVROFFSTDIS | XMITOFFSTDIS);
6621 ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) | (ENSELDO|ENSELDI));
6622#ifdef AHD_DEBUG
6623 if ((ahd_debug & AHD_SHOW_MISC) != 0)
6624 printk("%s: Setting up iocell workaround\n", ahd_name(ahd));
6625#endif
6626 ahd_restore_modes(ahd, saved_modes);
6627 ahd->flags &= ~AHD_HAD_FIRST_SEL;
6628}
6629
6630static void
6631ahd_iocell_first_selection(struct ahd_softc *ahd)
6632{
6633 ahd_mode_state saved_modes;
6634 u_int sblkctl;
6635
6636 if ((ahd->flags & AHD_HAD_FIRST_SEL) != 0)
6637 return;
6638 saved_modes = ahd_save_modes(ahd);
6639 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
6640 sblkctl = ahd_inb(ahd, SBLKCTL);
6641 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
6642#ifdef AHD_DEBUG
6643 if ((ahd_debug & AHD_SHOW_MISC) != 0)
6644 printk("%s: iocell first selection\n", ahd_name(ahd));
6645#endif
6646 if ((sblkctl & ENAB40) != 0) {
6647 ahd_outb(ahd, DSPDATACTL,
6648 ahd_inb(ahd, DSPDATACTL) & ~BYPASSENAB);
6649#ifdef AHD_DEBUG
6650 if ((ahd_debug & AHD_SHOW_MISC) != 0)
6651 printk("%s: BYPASS now disabled\n", ahd_name(ahd));
6652#endif
6653 }
6654 ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) & ~(ENSELDO|ENSELDI));
6655 ahd_outb(ahd, CLRINT, CLRSCSIINT);
6656 ahd_restore_modes(ahd, saved_modes);
6657 ahd->flags |= AHD_HAD_FIRST_SEL;
6658}
6659
6660
6661static void
6662ahd_add_col_list(struct ahd_softc *ahd, struct scb *scb, u_int col_idx)
6663{
6664 struct scb_list *free_list;
6665 struct scb_tailq *free_tailq;
6666 struct scb *first_scb;
6667
6668 scb->flags |= SCB_ON_COL_LIST;
6669 AHD_SET_SCB_COL_IDX(scb, col_idx);
6670 free_list = &ahd->scb_data.free_scb_lists[col_idx];
6671 free_tailq = &ahd->scb_data.free_scbs;
6672 first_scb = LIST_FIRST(free_list);
6673 if (first_scb != NULL) {
6674 LIST_INSERT_AFTER(first_scb, scb, collision_links);
6675 } else {
6676 LIST_INSERT_HEAD(free_list, scb, collision_links);
6677 TAILQ_INSERT_TAIL(free_tailq, scb, links.tqe);
6678 }
6679}
6680
6681static void
6682ahd_rem_col_list(struct ahd_softc *ahd, struct scb *scb)
6683{
6684 struct scb_list *free_list;
6685 struct scb_tailq *free_tailq;
6686 struct scb *first_scb;
6687 u_int col_idx;
6688
6689 scb->flags &= ~SCB_ON_COL_LIST;
6690 col_idx = AHD_GET_SCB_COL_IDX(ahd, scb);
6691 free_list = &ahd->scb_data.free_scb_lists[col_idx];
6692 free_tailq = &ahd->scb_data.free_scbs;
6693 first_scb = LIST_FIRST(free_list);
6694 if (first_scb == scb) {
6695 struct scb *next_scb;
6696
6697
6698
6699
6700
6701
6702 next_scb = LIST_NEXT(scb, collision_links);
6703 if (next_scb != NULL) {
6704 TAILQ_INSERT_AFTER(free_tailq, scb,
6705 next_scb, links.tqe);
6706 }
6707 TAILQ_REMOVE(free_tailq, scb, links.tqe);
6708 }
6709 LIST_REMOVE(scb, collision_links);
6710}
6711
6712
6713
6714
6715struct scb *
6716ahd_get_scb(struct ahd_softc *ahd, u_int col_idx)
6717{
6718 struct scb *scb;
6719 int tries;
6720
6721 tries = 0;
6722look_again:
6723 TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
6724 if (AHD_GET_SCB_COL_IDX(ahd, scb) != col_idx) {
6725 ahd_rem_col_list(ahd, scb);
6726 goto found;
6727 }
6728 }
6729 if ((scb = LIST_FIRST(&ahd->scb_data.any_dev_free_scb_list)) == NULL) {
6730
6731 if (tries++ != 0)
6732 return (NULL);
6733 ahd_alloc_scbs(ahd);
6734 goto look_again;
6735 }
6736 LIST_REMOVE(scb, links.le);
6737 if (col_idx != AHD_NEVER_COL_IDX
6738 && (scb->col_scb != NULL)
6739 && (scb->col_scb->flags & SCB_ACTIVE) == 0) {
6740 LIST_REMOVE(scb->col_scb, links.le);
6741 ahd_add_col_list(ahd, scb->col_scb, col_idx);
6742 }
6743found:
6744 scb->flags |= SCB_ACTIVE;
6745 return (scb);
6746}
6747
6748
6749
6750
6751void
6752ahd_free_scb(struct ahd_softc *ahd, struct scb *scb)
6753{
6754
6755 scb->flags = SCB_FLAG_NONE;
6756 scb->hscb->control = 0;
6757 ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = NULL;
6758
6759 if (scb->col_scb == NULL) {
6760
6761
6762
6763
6764 LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
6765 scb, links.le);
6766 } else if ((scb->col_scb->flags & SCB_ON_COL_LIST) != 0) {
6767
6768
6769
6770
6771
6772
6773 ahd_rem_col_list(ahd, scb->col_scb);
6774 LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
6775 scb, links.le);
6776 LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
6777 scb->col_scb, links.le);
6778 } else if ((scb->col_scb->flags
6779 & (SCB_PACKETIZED|SCB_ACTIVE)) == SCB_ACTIVE
6780 && (scb->col_scb->hscb->control & TAG_ENB) != 0) {
6781
6782
6783
6784
6785
6786
6787 ahd_add_col_list(ahd, scb,
6788 AHD_GET_SCB_COL_IDX(ahd, scb->col_scb));
6789 } else {
6790
6791
6792
6793
6794
6795
6796 LIST_INSERT_HEAD(&ahd->scb_data.any_dev_free_scb_list,
6797 scb, links.le);
6798 }
6799
6800 ahd_platform_scb_free(ahd, scb);
6801}
6802
6803static void
6804ahd_alloc_scbs(struct ahd_softc *ahd)
6805{
6806 struct scb_data *scb_data;
6807 struct scb *next_scb;
6808 struct hardware_scb *hscb;
6809 struct map_node *hscb_map;
6810 struct map_node *sg_map;
6811 struct map_node *sense_map;
6812 uint8_t *segs;
6813 uint8_t *sense_data;
6814 dma_addr_t hscb_busaddr;
6815 dma_addr_t sg_busaddr;
6816 dma_addr_t sense_busaddr;
6817 int newcount;
6818 int i;
6819
6820 scb_data = &ahd->scb_data;
6821 if (scb_data->numscbs >= AHD_SCB_MAX_ALLOC)
6822
6823 return;
6824
6825 if (scb_data->scbs_left != 0) {
6826 int offset;
6827
6828 offset = (PAGE_SIZE / sizeof(*hscb)) - scb_data->scbs_left;
6829 hscb_map = SLIST_FIRST(&scb_data->hscb_maps);
6830 hscb = &((struct hardware_scb *)hscb_map->vaddr)[offset];
6831 hscb_busaddr = hscb_map->physaddr + (offset * sizeof(*hscb));
6832 } else {
6833 hscb_map = kmalloc(sizeof(*hscb_map), GFP_ATOMIC);
6834
6835 if (hscb_map == NULL)
6836 return;
6837
6838
6839 if (ahd_dmamem_alloc(ahd, scb_data->hscb_dmat,
6840 (void **)&hscb_map->vaddr,
6841 BUS_DMA_NOWAIT, &hscb_map->dmamap) != 0) {
6842 kfree(hscb_map);
6843 return;
6844 }
6845
6846 SLIST_INSERT_HEAD(&scb_data->hscb_maps, hscb_map, links);
6847
6848 ahd_dmamap_load(ahd, scb_data->hscb_dmat, hscb_map->dmamap,
6849 hscb_map->vaddr, PAGE_SIZE, ahd_dmamap_cb,
6850 &hscb_map->physaddr, 0);
6851
6852 hscb = (struct hardware_scb *)hscb_map->vaddr;
6853 hscb_busaddr = hscb_map->physaddr;
6854 scb_data->scbs_left = PAGE_SIZE / sizeof(*hscb);
6855 }
6856
6857 if (scb_data->sgs_left != 0) {
6858 int offset;
6859
6860 offset = ((ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd))
6861 - scb_data->sgs_left) * ahd_sglist_size(ahd);
6862 sg_map = SLIST_FIRST(&scb_data->sg_maps);
6863 segs = sg_map->vaddr + offset;
6864 sg_busaddr = sg_map->physaddr + offset;
6865 } else {
6866 sg_map = kmalloc(sizeof(*sg_map), GFP_ATOMIC);
6867
6868 if (sg_map == NULL)
6869 return;
6870
6871
6872 if (ahd_dmamem_alloc(ahd, scb_data->sg_dmat,
6873 (void **)&sg_map->vaddr,
6874 BUS_DMA_NOWAIT, &sg_map->dmamap) != 0) {
6875 kfree(sg_map);
6876 return;
6877 }
6878
6879 SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
6880
6881 ahd_dmamap_load(ahd, scb_data->sg_dmat, sg_map->dmamap,
6882 sg_map->vaddr, ahd_sglist_allocsize(ahd),
6883 ahd_dmamap_cb, &sg_map->physaddr, 0);
6884
6885 segs = sg_map->vaddr;
6886 sg_busaddr = sg_map->physaddr;
6887 scb_data->sgs_left =
6888 ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd);
6889#ifdef AHD_DEBUG
6890 if (ahd_debug & AHD_SHOW_MEMORY)
6891 printk("Mapped SG data\n");
6892#endif
6893 }
6894
6895 if (scb_data->sense_left != 0) {
6896 int offset;
6897
6898 offset = PAGE_SIZE - (AHD_SENSE_BUFSIZE * scb_data->sense_left);
6899 sense_map = SLIST_FIRST(&scb_data->sense_maps);
6900 sense_data = sense_map->vaddr + offset;
6901 sense_busaddr = sense_map->physaddr + offset;
6902 } else {
6903 sense_map = kmalloc(sizeof(*sense_map), GFP_ATOMIC);
6904
6905 if (sense_map == NULL)
6906 return;
6907
6908
6909 if (ahd_dmamem_alloc(ahd, scb_data->sense_dmat,
6910 (void **)&sense_map->vaddr,
6911 BUS_DMA_NOWAIT, &sense_map->dmamap) != 0) {
6912 kfree(sense_map);
6913 return;
6914 }
6915
6916 SLIST_INSERT_HEAD(&scb_data->sense_maps, sense_map, links);
6917
6918 ahd_dmamap_load(ahd, scb_data->sense_dmat, sense_map->dmamap,
6919 sense_map->vaddr, PAGE_SIZE, ahd_dmamap_cb,
6920 &sense_map->physaddr, 0);
6921
6922 sense_data = sense_map->vaddr;
6923 sense_busaddr = sense_map->physaddr;
6924 scb_data->sense_left = PAGE_SIZE / AHD_SENSE_BUFSIZE;
6925#ifdef AHD_DEBUG
6926 if (ahd_debug & AHD_SHOW_MEMORY)
6927 printk("Mapped sense data\n");
6928#endif
6929 }
6930
6931 newcount = min(scb_data->sense_left, scb_data->scbs_left);
6932 newcount = min(newcount, scb_data->sgs_left);
6933 newcount = min(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs));
6934 for (i = 0; i < newcount; i++) {
6935 struct scb_platform_data *pdata;
6936 u_int col_tag;
6937#ifndef __linux__
6938 int error;
6939#endif
6940
6941 next_scb = kmalloc(sizeof(*next_scb), GFP_ATOMIC);
6942 if (next_scb == NULL)
6943 break;
6944
6945 pdata = kmalloc(sizeof(*pdata), GFP_ATOMIC);
6946 if (pdata == NULL) {
6947 kfree(next_scb);
6948 break;
6949 }
6950 next_scb->platform_data = pdata;
6951 next_scb->hscb_map = hscb_map;
6952 next_scb->sg_map = sg_map;
6953 next_scb->sense_map = sense_map;
6954 next_scb->sg_list = segs;
6955 next_scb->sense_data = sense_data;
6956 next_scb->sense_busaddr = sense_busaddr;
6957 memset(hscb, 0, sizeof(*hscb));
6958 next_scb->hscb = hscb;
6959 hscb->hscb_busaddr = ahd_htole32(hscb_busaddr);
6960
6961
6962
6963
6964
6965 next_scb->sg_list_busaddr = sg_busaddr;
6966 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
6967 next_scb->sg_list_busaddr
6968 += sizeof(struct ahd_dma64_seg);
6969 else
6970 next_scb->sg_list_busaddr += sizeof(struct ahd_dma_seg);
6971 next_scb->ahd_softc = ahd;
6972 next_scb->flags = SCB_FLAG_NONE;
6973#ifndef __linux__
6974 error = ahd_dmamap_create(ahd, ahd->buffer_dmat, 0,
6975 &next_scb->dmamap);
6976 if (error != 0) {
6977 kfree(next_scb);
6978 kfree(pdata);
6979 break;
6980 }
6981#endif
6982 next_scb->hscb->tag = ahd_htole16(scb_data->numscbs);
6983 col_tag = scb_data->numscbs ^ 0x100;
6984 next_scb->col_scb = ahd_find_scb_by_tag(ahd, col_tag);
6985 if (next_scb->col_scb != NULL)
6986 next_scb->col_scb->col_scb = next_scb;
6987 ahd_free_scb(ahd, next_scb);
6988 hscb++;
6989 hscb_busaddr += sizeof(*hscb);
6990 segs += ahd_sglist_size(ahd);
6991 sg_busaddr += ahd_sglist_size(ahd);
6992 sense_data += AHD_SENSE_BUFSIZE;
6993 sense_busaddr += AHD_SENSE_BUFSIZE;
6994 scb_data->numscbs++;
6995 scb_data->sense_left--;
6996 scb_data->scbs_left--;
6997 scb_data->sgs_left--;
6998 }
6999}
7000
7001void
7002ahd_controller_info(struct ahd_softc *ahd, char *buf)
7003{
7004 const char *speed;
7005 const char *type;
7006 int len;
7007
7008 len = sprintf(buf, "%s: ", ahd_chip_names[ahd->chip & AHD_CHIPID_MASK]);
7009 buf += len;
7010
7011 speed = "Ultra320 ";
7012 if ((ahd->features & AHD_WIDE) != 0) {
7013 type = "Wide ";
7014 } else {
7015 type = "Single ";
7016 }
7017 len = sprintf(buf, "%s%sChannel %c, SCSI Id=%d, ",
7018 speed, type, ahd->channel, ahd->our_id);
7019 buf += len;
7020
7021 sprintf(buf, "%s, %d SCBs", ahd->bus_description,
7022 ahd->scb_data.maxhscbs);
7023}
7024
7025static const char *channel_strings[] = {
7026 "Primary Low",
7027 "Primary High",
7028 "Secondary Low",
7029 "Secondary High"
7030};
7031
7032static const char *termstat_strings[] = {
7033 "Terminated Correctly",
7034 "Over Terminated",
7035 "Under Terminated",
7036 "Not Configured"
7037};
7038
7039
7040static void
7041ahd_timer_reset(struct timer_list *timer, int usec)
7042{
7043 del_timer(timer);
7044 timer->expires = jiffies + (usec * HZ)/1000000;
7045 add_timer(timer);
7046}
7047
7048
7049
7050
7051int
7052ahd_init(struct ahd_softc *ahd)
7053{
7054 uint8_t *next_vaddr;
7055 dma_addr_t next_baddr;
7056 size_t driver_data_size;
7057 int i;
7058 int error;
7059 u_int warn_user;
7060 uint8_t current_sensing;
7061 uint8_t fstat;
7062
7063 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
7064
7065 ahd->stack_size = ahd_probe_stack_size(ahd);
7066 ahd->saved_stack = kmalloc_array(ahd->stack_size, sizeof(uint16_t),
7067 GFP_ATOMIC);
7068 if (ahd->saved_stack == NULL)
7069 return (ENOMEM);
7070
7071
7072
7073
7074
7075 if (sizeof(struct hardware_scb) != 64)
7076 panic("Hardware SCB size is incorrect");
7077
7078#ifdef AHD_DEBUG
7079 if ((ahd_debug & AHD_DEBUG_SEQUENCER) != 0)
7080 ahd->flags |= AHD_SEQUENCER_DEBUG;
7081#endif
7082
7083
7084
7085
7086 ahd->flags |= AHD_INITIATORROLE;
7087
7088
7089
7090
7091 if ((AHD_TMODE_ENABLE & (0x1 << ahd->unit)) == 0)
7092 ahd->features &= ~AHD_TARGETMODE;
7093
7094#ifndef __linux__
7095
7096 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, 1,
7097 BUS_SPACE_MAXADDR_32BIT + 1,
7098 ahd->flags & AHD_39BIT_ADDRESSING
7099 ? (dma_addr_t)0x7FFFFFFFFFULL
7100 : BUS_SPACE_MAXADDR_32BIT,
7101 BUS_SPACE_MAXADDR,
7102 NULL, NULL,
7103 (AHD_NSEG - 1) * PAGE_SIZE,
7104 AHD_NSEG,
7105 AHD_MAXTRANSFER_SIZE,
7106 BUS_DMA_ALLOCNOW,
7107 &ahd->buffer_dmat) != 0) {
7108 return (ENOMEM);
7109 }
7110#endif
7111
7112 ahd->init_level++;
7113
7114
7115
7116
7117
7118
7119
7120
7121 driver_data_size = AHD_SCB_MAX * sizeof(*ahd->qoutfifo)
7122 + sizeof(struct hardware_scb);
7123 if ((ahd->features & AHD_TARGETMODE) != 0)
7124 driver_data_size += AHD_TMODE_CMDS * sizeof(struct target_cmd);
7125 if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0)
7126 driver_data_size += PKT_OVERRUN_BUFSIZE;
7127 if (ahd_dma_tag_create(ahd, ahd->parent_dmat, 1,
7128 BUS_SPACE_MAXADDR_32BIT + 1,
7129 BUS_SPACE_MAXADDR_32BIT,
7130 BUS_SPACE_MAXADDR,
7131 NULL, NULL,
7132 driver_data_size,
7133 1,
7134 BUS_SPACE_MAXSIZE_32BIT,
7135 0, &ahd->shared_data_dmat) != 0) {
7136 return (ENOMEM);
7137 }
7138
7139 ahd->init_level++;
7140
7141
7142 if (ahd_dmamem_alloc(ahd, ahd->shared_data_dmat,
7143 (void **)&ahd->shared_data_map.vaddr,
7144 BUS_DMA_NOWAIT,
7145 &ahd->shared_data_map.dmamap) != 0) {
7146 return (ENOMEM);
7147 }
7148
7149 ahd->init_level++;
7150
7151
7152 ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap,
7153 ahd->shared_data_map.vaddr, driver_data_size,
7154 ahd_dmamap_cb, &ahd->shared_data_map.physaddr,
7155 0);
7156 ahd->qoutfifo = (struct ahd_completion *)ahd->shared_data_map.vaddr;
7157 next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE];
7158 next_baddr = ahd->shared_data_map.physaddr
7159 + AHD_QOUT_SIZE*sizeof(struct ahd_completion);
7160 if ((ahd->features & AHD_TARGETMODE) != 0) {
7161 ahd->targetcmds = (struct target_cmd *)next_vaddr;
7162 next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd);
7163 next_baddr += AHD_TMODE_CMDS * sizeof(struct target_cmd);
7164 }
7165
7166 if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) {
7167 ahd->overrun_buf = next_vaddr;
7168 next_vaddr += PKT_OVERRUN_BUFSIZE;
7169 next_baddr += PKT_OVERRUN_BUFSIZE;
7170 }
7171
7172
7173
7174
7175
7176
7177
7178
7179 ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr;
7180 ahd->next_queued_hscb_map = &ahd->shared_data_map;
7181 ahd->next_queued_hscb->hscb_busaddr = ahd_htole32(next_baddr);
7182
7183 ahd->init_level++;
7184
7185
7186 if (ahd_init_scbdata(ahd) != 0)
7187 return (ENOMEM);
7188
7189 if ((ahd->flags & AHD_INITIATORROLE) == 0)
7190 ahd->flags &= ~AHD_RESET_BUS_A;
7191
7192
7193
7194
7195
7196 ahd_platform_init(ahd);
7197
7198
7199 ahd_chip_init(ahd);
7200
7201 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
7202
7203 if ((ahd->flags & AHD_CURRENT_SENSING) == 0)
7204 goto init_done;
7205
7206
7207
7208
7209
7210 error = ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL,
7211 CURSENSE_ENB);
7212 if (error != 0) {
7213 printk("%s: current sensing timeout 1\n", ahd_name(ahd));
7214 goto init_done;
7215 }
7216 for (i = 20, fstat = FLX_FSTAT_BUSY;
7217 (fstat & FLX_FSTAT_BUSY) != 0 && i; i--) {
7218 error = ahd_read_flexport(ahd, FLXADDR_FLEXSTAT, &fstat);
7219 if (error != 0) {
7220 printk("%s: current sensing timeout 2\n",
7221 ahd_name(ahd));
7222 goto init_done;
7223 }
7224 }
7225 if (i == 0) {
7226 printk("%s: Timedout during current-sensing test\n",
7227 ahd_name(ahd));
7228 goto init_done;
7229 }
7230
7231
7232 error = ahd_read_flexport(ahd, FLXADDR_CURRENT_STAT, ¤t_sensing);
7233 if (error != 0) {
7234 printk("%s: current sensing timeout 3\n", ahd_name(ahd));
7235 goto init_done;
7236 }
7237
7238
7239 ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, 0);
7240
7241#ifdef AHD_DEBUG
7242 if ((ahd_debug & AHD_SHOW_TERMCTL) != 0) {
7243 printk("%s: current_sensing == 0x%x\n",
7244 ahd_name(ahd), current_sensing);
7245 }
7246#endif
7247 warn_user = 0;
7248 for (i = 0; i < 4; i++, current_sensing >>= FLX_CSTAT_SHIFT) {
7249 u_int term_stat;
7250
7251 term_stat = (current_sensing & FLX_CSTAT_MASK);
7252 switch (term_stat) {
7253 case FLX_CSTAT_OVER:
7254 case FLX_CSTAT_UNDER:
7255 warn_user++;
7256 case FLX_CSTAT_INVALID:
7257 case FLX_CSTAT_OKAY:
7258 if (warn_user == 0 && bootverbose == 0)
7259 break;
7260 printk("%s: %s Channel %s\n", ahd_name(ahd),
7261 channel_strings[i], termstat_strings[term_stat]);
7262 break;
7263 }
7264 }
7265 if (warn_user) {
7266 printk("%s: WARNING. Termination is not configured correctly.\n"
7267 "%s: WARNING. SCSI bus operations may FAIL.\n",
7268 ahd_name(ahd), ahd_name(ahd));
7269 }
7270init_done:
7271 ahd_restart(ahd);
7272 ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US);
7273 return (0);
7274}
7275
7276
7277
7278
7279static void
7280ahd_chip_init(struct ahd_softc *ahd)
7281{
7282 uint32_t busaddr;
7283 u_int sxfrctl1;
7284 u_int scsiseq_template;
7285 u_int wait;
7286 u_int i;
7287 u_int target;
7288
7289 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7290
7291
7292
7293 ahd_outb(ahd, SBLKCTL, ahd_inb(ahd, SBLKCTL) & ~(DIAGLEDEN|DIAGLEDON));
7294
7295
7296
7297
7298 ahd->hs_mailbox = 0;
7299 ahd_outb(ahd, HS_MAILBOX, 0);
7300
7301
7302 ahd_outb(ahd, IOWNID, ahd->our_id);
7303 ahd_outb(ahd, TOWNID, ahd->our_id);
7304 sxfrctl1 = (ahd->flags & AHD_TERM_ENB_A) != 0 ? STPWEN : 0;
7305 sxfrctl1 |= (ahd->flags & AHD_SPCHK_ENB_A) != 0 ? ENSPCHK : 0;
7306 if ((ahd->bugs & AHD_LONG_SETIMO_BUG)
7307 && (ahd->seltime != STIMESEL_MIN)) {
7308
7309
7310
7311
7312
7313 sxfrctl1 |= ahd->seltime + STIMESEL_BUG_ADJ;
7314 } else {
7315 sxfrctl1 |= ahd->seltime;
7316 }
7317
7318 ahd_outb(ahd, SXFRCTL0, DFON);
7319 ahd_outb(ahd, SXFRCTL1, sxfrctl1|ahd->seltime|ENSTIMER|ACTNEGEN);
7320 ahd_outb(ahd, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
7321
7322
7323
7324
7325
7326
7327
7328
7329 for (wait = 10000;
7330 (ahd_inb(ahd, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
7331 wait--)
7332 ahd_delay(100);
7333
7334
7335 ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
7336 ahd_outb(ahd, CLRINT, CLRSCSIINT);
7337
7338
7339 for (i = 0; i < 2; i++) {
7340 ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i);
7341 ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
7342 ahd_outb(ahd, SG_STATE, 0);
7343 ahd_outb(ahd, CLRSEQINTSRC, 0xFF);
7344 ahd_outb(ahd, SEQIMODE,
7345 ENSAVEPTRS|ENCFG4DATA|ENCFG4ISTAT
7346 |ENCFG4TSTAT|ENCFG4ICMD|ENCFG4TCMD);
7347 }
7348
7349 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
7350 ahd_outb(ahd, DSCOMMAND0, ahd_inb(ahd, DSCOMMAND0)|MPARCKEN|CACHETHEN);
7351 ahd_outb(ahd, DFF_THRSH, RD_DFTHRSH_75|WR_DFTHRSH_75);
7352 ahd_outb(ahd, SIMODE0, ENIOERR|ENOVERRUN);
7353 ahd_outb(ahd, SIMODE3, ENNTRAMPERR|ENOSRAMPERR);
7354 if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
7355 ahd_outb(ahd, OPTIONMODE, AUTOACKEN|AUTO_MSGOUT_DE);
7356 } else {
7357 ahd_outb(ahd, OPTIONMODE, AUTOACKEN|BUSFREEREV|AUTO_MSGOUT_DE);
7358 }
7359 ahd_outb(ahd, SCSCHKN, CURRFIFODEF|WIDERESEN|SHVALIDSTDIS);
7360 if ((ahd->chip & AHD_BUS_MASK) == AHD_PCIX)
7361
7362
7363
7364
7365
7366 ahd_outb(ahd, PCIXCTL, ahd_inb(ahd, PCIXCTL) | SPLTSTADIS);
7367
7368 if ((ahd->bugs & AHD_LQOOVERRUN_BUG) != 0)
7369 ahd_outb(ahd, LQOSCSCTL, LQONOCHKOVER);
7370
7371
7372
7373
7374 if ((ahd->flags & AHD_HP_BOARD) != 0) {
7375 for (i = 0; i < NUMDSPS; i++) {
7376 ahd_outb(ahd, DSPSELECT, i);
7377 ahd_outb(ahd, WRTBIASCTL, WRTBIASCTL_HP_DEFAULT);
7378 }
7379#ifdef AHD_DEBUG
7380 if ((ahd_debug & AHD_SHOW_MISC) != 0)
7381 printk("%s: WRTBIASCTL now 0x%x\n", ahd_name(ahd),
7382 WRTBIASCTL_HP_DEFAULT);
7383#endif
7384 }
7385 ahd_setup_iocell_workaround(ahd);
7386
7387
7388
7389
7390 ahd_outb(ahd, LQIMODE1, ENLQIPHASE_LQ|ENLQIPHASE_NLQ|ENLIQABORT
7391 | ENLQICRCI_LQ|ENLQICRCI_NLQ|ENLQIBADLQI
7392 | ENLQIOVERI_LQ|ENLQIOVERI_NLQ);
7393 ahd_outb(ahd, LQOMODE0, ENLQOATNLQ|ENLQOATNPKT|ENLQOTCRC);
7394
7395
7396
7397
7398
7399
7400
7401
7402 ahd_outb(ahd, LQOMODE1, ENLQOBUSFREE);
7403
7404
7405
7406
7407 ahd_outw(ahd, INTVEC1_ADDR, ahd_resolve_seqaddr(ahd, LABEL_seq_isr));
7408 ahd_outw(ahd, INTVEC2_ADDR, ahd_resolve_seqaddr(ahd, LABEL_timer_isr));
7409
7410
7411
7412
7413 if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) {
7414 ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb,
7415 pkt_long_lun));
7416 } else {
7417 ahd_outb(ahd, LUNPTR, offsetof(struct hardware_scb, lun));
7418 }
7419 ahd_outb(ahd, CMDLENPTR, offsetof(struct hardware_scb, cdb_len));
7420 ahd_outb(ahd, ATTRPTR, offsetof(struct hardware_scb, task_attribute));
7421 ahd_outb(ahd, FLAGPTR, offsetof(struct hardware_scb, task_management));
7422 ahd_outb(ahd, CMDPTR, offsetof(struct hardware_scb,
7423 shared_data.idata.cdb));
7424 ahd_outb(ahd, QNEXTPTR,
7425 offsetof(struct hardware_scb, next_hscb_busaddr));
7426 ahd_outb(ahd, ABRTBITPTR, MK_MESSAGE_BIT_OFFSET);
7427 ahd_outb(ahd, ABRTBYTEPTR, offsetof(struct hardware_scb, control));
7428 if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) {
7429 ahd_outb(ahd, LUNLEN,
7430 sizeof(ahd->next_queued_hscb->pkt_long_lun) - 1);
7431 } else {
7432 ahd_outb(ahd, LUNLEN, LUNLEN_SINGLE_LEVEL_LUN);
7433 }
7434 ahd_outb(ahd, CDBLIMIT, SCB_CDB_LEN_PTR - 1);
7435 ahd_outb(ahd, MAXCMD, 0xFF);
7436 ahd_outb(ahd, SCBAUTOPTR,
7437 AUSCBPTR_EN | offsetof(struct hardware_scb, tag));
7438
7439
7440 ahd_outb(ahd, MULTARGID, 0);
7441 ahd_outb(ahd, MULTARGID + 1, 0);
7442
7443 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7444
7445 if ((ahd->features & AHD_NEW_IOCELL_OPTS) == 0) {
7446
7447
7448
7449
7450 for (target = 0; target < AHD_NUM_TARGETS; target++) {
7451 ahd_outb(ahd, NEGOADDR, target);
7452 ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PER_DEV0);
7453 for (i = 0; i < AHD_NUM_PER_DEV_ANNEXCOLS; i++)
7454 ahd_outb(ahd, ANNEXDAT, 0);
7455 }
7456 }
7457 for (target = 0; target < AHD_NUM_TARGETS; target++) {
7458 struct ahd_devinfo devinfo;
7459 struct ahd_initiator_tinfo *tinfo;
7460 struct ahd_tmode_tstate *tstate;
7461
7462 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
7463 target, &tstate);
7464 ahd_compile_devinfo(&devinfo, ahd->our_id,
7465 target, CAM_LUN_WILDCARD,
7466 'A', ROLE_INITIATOR);
7467 ahd_update_neg_table(ahd, &devinfo, &tinfo->curr);
7468 }
7469
7470 ahd_outb(ahd, CLRSINT3, NTRAMPERR|OSRAMPERR);
7471 ahd_outb(ahd, CLRINT, CLRSCSIINT);
7472
7473#ifdef NEEDS_MORE_TESTING
7474
7475
7476
7477
7478 if ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0)
7479 ahd_outb(ahd, LQCTL1, ABORTPENDING);
7480 else
7481#endif
7482 ahd_outb(ahd, LQCTL1, 0);
7483
7484
7485 ahd->qoutfifonext = 0;
7486 ahd->qoutfifonext_valid_tag = QOUTFIFO_ENTRY_VALID;
7487 ahd_outb(ahd, QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID);
7488 for (i = 0; i < AHD_QOUT_SIZE; i++)
7489 ahd->qoutfifo[i].valid_tag = 0;
7490 ahd_sync_qoutfifo(ahd, BUS_DMASYNC_PREREAD);
7491
7492 ahd->qinfifonext = 0;
7493 for (i = 0; i < AHD_QIN_SIZE; i++)
7494 ahd->qinfifo[i] = SCB_LIST_NULL;
7495
7496 if ((ahd->features & AHD_TARGETMODE) != 0) {
7497
7498 for (i = 0; i < AHD_TMODE_CMDS; i++)
7499 ahd->targetcmds[i].cmd_valid = 0;
7500 ahd_sync_tqinfifo(ahd, BUS_DMASYNC_PREREAD);
7501 ahd->tqinfifonext = 1;
7502 ahd_outb(ahd, KERNEL_TQINPOS, ahd->tqinfifonext - 1);
7503 ahd_outb(ahd, TQINPOS, ahd->tqinfifonext);
7504 }
7505
7506
7507 ahd_outb(ahd, SEQ_FLAGS, 0);
7508 ahd_outb(ahd, SEQ_FLAGS2, 0);
7509
7510
7511 ahd_outw(ahd, WAITING_TID_HEAD, SCB_LIST_NULL);
7512 ahd_outw(ahd, WAITING_TID_TAIL, SCB_LIST_NULL);
7513 ahd_outw(ahd, MK_MESSAGE_SCB, SCB_LIST_NULL);
7514 ahd_outw(ahd, MK_MESSAGE_SCSIID, 0xFF);
7515 for (i = 0; i < AHD_NUM_TARGETS; i++)
7516 ahd_outw(ahd, WAITING_SCB_TAILS + (2 * i), SCB_LIST_NULL);
7517
7518
7519
7520
7521 ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL);
7522 ahd_outw(ahd, COMPLETE_SCB_DMAINPROG_HEAD, SCB_LIST_NULL);
7523 ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL);
7524 ahd_outw(ahd, COMPLETE_DMA_SCB_TAIL, SCB_LIST_NULL);
7525 ahd_outw(ahd, COMPLETE_ON_QFREEZE_HEAD, SCB_LIST_NULL);
7526
7527
7528
7529
7530 ahd->qfreeze_cnt = 0;
7531 ahd_outw(ahd, QFREEZE_COUNT, 0);
7532 ahd_outw(ahd, KERNEL_QFREEZE_COUNT, 0);
7533
7534
7535
7536
7537 busaddr = ahd->shared_data_map.physaddr;
7538 ahd_outl(ahd, SHARED_DATA_ADDR, busaddr);
7539 ahd_outl(ahd, QOUTFIFO_NEXT_ADDR, busaddr);
7540
7541
7542
7543
7544
7545
7546 scsiseq_template = ENAUTOATNP;
7547 if ((ahd->flags & AHD_INITIATORROLE) != 0)
7548 scsiseq_template |= ENRSELI;
7549 ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq_template);
7550
7551
7552 for (target = 0; target < AHD_NUM_TARGETS; target++) {
7553 int lun;
7554
7555 for (lun = 0; lun < AHD_NUM_LUNS_NONPKT; lun++)
7556 ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(target, 'A', lun));
7557 }
7558
7559
7560
7561
7562
7563
7564
7565 ahd_outb(ahd, CMDSIZE_TABLE, 5);
7566 ahd_outb(ahd, CMDSIZE_TABLE + 1, 9);
7567 ahd_outb(ahd, CMDSIZE_TABLE + 2, 9);
7568 ahd_outb(ahd, CMDSIZE_TABLE + 3, 0);
7569 ahd_outb(ahd, CMDSIZE_TABLE + 4, 15);
7570 ahd_outb(ahd, CMDSIZE_TABLE + 5, 11);
7571 ahd_outb(ahd, CMDSIZE_TABLE + 6, 0);
7572 ahd_outb(ahd, CMDSIZE_TABLE + 7, 0);
7573
7574
7575 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
7576 ahd_outb(ahd, QOFF_CTLSTA, SCB_QSIZE_512);
7577 ahd->qinfifonext = 0;
7578 ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
7579 ahd_set_hescb_qoff(ahd, 0);
7580 ahd_set_snscb_qoff(ahd, 0);
7581 ahd_set_sescb_qoff(ahd, 0);
7582 ahd_set_sdscb_qoff(ahd, 0);
7583
7584
7585
7586
7587 busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr);
7588 ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr);
7589
7590
7591
7592
7593 ahd_outw(ahd, INT_COALESCING_CMDCOUNT, 0);
7594 ahd_outw(ahd, CMDS_PENDING, 0);
7595 ahd_update_coalescing_values(ahd, ahd->int_coalescing_timer,
7596 ahd->int_coalescing_maxcmds,
7597 ahd->int_coalescing_mincmds);
7598 ahd_enable_coalescing(ahd, FALSE);
7599
7600 ahd_loadseq(ahd);
7601 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
7602
7603 if (ahd->features & AHD_AIC79XXB_SLOWCRC) {
7604 u_int negodat3 = ahd_inb(ahd, NEGCONOPTS);
7605
7606 negodat3 |= ENSLOWCRC;
7607 ahd_outb(ahd, NEGCONOPTS, negodat3);
7608 negodat3 = ahd_inb(ahd, NEGCONOPTS);
7609 if (!(negodat3 & ENSLOWCRC))
7610 printk("aic79xx: failed to set the SLOWCRC bit\n");
7611 else
7612 printk("aic79xx: SLOWCRC bit set\n");
7613 }
7614}
7615
7616
7617
7618
7619
7620
7621int
7622ahd_default_config(struct ahd_softc *ahd)
7623{
7624 int targ;
7625
7626 ahd->our_id = 7;
7627
7628
7629
7630
7631
7632
7633 if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) {
7634 printk("%s: unable to allocate ahd_tmode_tstate. "
7635 "Failing attach\n", ahd_name(ahd));
7636 return (ENOMEM);
7637 }
7638
7639 for (targ = 0; targ < AHD_NUM_TARGETS; targ++) {
7640 struct ahd_devinfo devinfo;
7641 struct ahd_initiator_tinfo *tinfo;
7642 struct ahd_tmode_tstate *tstate;
7643 uint16_t target_mask;
7644
7645 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
7646 targ, &tstate);
7647
7648
7649
7650 tinfo->user.protocol_version = 4;
7651 tinfo->user.transport_version = 4;
7652
7653 target_mask = 0x01 << targ;
7654 ahd->user_discenable |= target_mask;
7655 tstate->discenable |= target_mask;
7656 ahd->user_tagenable |= target_mask;
7657#ifdef AHD_FORCE_160
7658 tinfo->user.period = AHD_SYNCRATE_DT;
7659#else
7660 tinfo->user.period = AHD_SYNCRATE_160;
7661#endif
7662 tinfo->user.offset = MAX_OFFSET;
7663 tinfo->user.ppr_options = MSG_EXT_PPR_RD_STRM
7664 | MSG_EXT_PPR_WR_FLOW
7665 | MSG_EXT_PPR_HOLD_MCS
7666 | MSG_EXT_PPR_IU_REQ
7667 | MSG_EXT_PPR_QAS_REQ
7668 | MSG_EXT_PPR_DT_REQ;
7669 if ((ahd->features & AHD_RTI) != 0)
7670 tinfo->user.ppr_options |= MSG_EXT_PPR_RTI;
7671
7672 tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
7673
7674
7675
7676
7677
7678 tinfo->goal.protocol_version = 2;
7679 tinfo->goal.transport_version = 2;
7680 tinfo->curr.protocol_version = 2;
7681 tinfo->curr.transport_version = 2;
7682 ahd_compile_devinfo(&devinfo, ahd->our_id,
7683 targ, CAM_LUN_WILDCARD,
7684 'A', ROLE_INITIATOR);
7685 tstate->tagenable &= ~target_mask;
7686 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
7687 AHD_TRANS_CUR|AHD_TRANS_GOAL, TRUE);
7688 ahd_set_syncrate(ahd, &devinfo, 0, 0,
7689 0, AHD_TRANS_CUR|AHD_TRANS_GOAL,
7690 TRUE);
7691 }
7692 return (0);
7693}
7694
7695
7696
7697
7698int
7699ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc)
7700{
7701 int targ;
7702 int max_targ;
7703
7704 max_targ = sc->max_targets & CFMAXTARG;
7705 ahd->our_id = sc->brtime_id & CFSCSIID;
7706
7707
7708
7709
7710
7711
7712 if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) {
7713 printk("%s: unable to allocate ahd_tmode_tstate. "
7714 "Failing attach\n", ahd_name(ahd));
7715 return (ENOMEM);
7716 }
7717
7718 for (targ = 0; targ < max_targ; targ++) {
7719 struct ahd_devinfo devinfo;
7720 struct ahd_initiator_tinfo *tinfo;
7721 struct ahd_transinfo *user_tinfo;
7722 struct ahd_tmode_tstate *tstate;
7723 uint16_t target_mask;
7724
7725 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
7726 targ, &tstate);
7727 user_tinfo = &tinfo->user;
7728
7729
7730
7731
7732 tinfo->user.protocol_version = 4;
7733 tinfo->user.transport_version = 4;
7734
7735 target_mask = 0x01 << targ;
7736 ahd->user_discenable &= ~target_mask;
7737 tstate->discenable &= ~target_mask;
7738 ahd->user_tagenable &= ~target_mask;
7739 if (sc->device_flags[targ] & CFDISC) {
7740 tstate->discenable |= target_mask;
7741 ahd->user_discenable |= target_mask;
7742 ahd->user_tagenable |= target_mask;
7743 } else {
7744
7745
7746
7747 sc->device_flags[targ] &= ~CFPACKETIZED;
7748 }
7749
7750 user_tinfo->ppr_options = 0;
7751 user_tinfo->period = (sc->device_flags[targ] & CFXFER);
7752 if (user_tinfo->period < CFXFER_ASYNC) {
7753 if (user_tinfo->period <= AHD_PERIOD_10MHz)
7754 user_tinfo->ppr_options |= MSG_EXT_PPR_DT_REQ;
7755 user_tinfo->offset = MAX_OFFSET;
7756 } else {
7757 user_tinfo->offset = 0;
7758 user_tinfo->period = AHD_ASYNC_XFER_PERIOD;
7759 }
7760#ifdef AHD_FORCE_160
7761 if (user_tinfo->period <= AHD_SYNCRATE_160)
7762 user_tinfo->period = AHD_SYNCRATE_DT;
7763#endif
7764
7765 if ((sc->device_flags[targ] & CFPACKETIZED) != 0) {
7766 user_tinfo->ppr_options |= MSG_EXT_PPR_RD_STRM
7767 | MSG_EXT_PPR_WR_FLOW
7768 | MSG_EXT_PPR_HOLD_MCS
7769 | MSG_EXT_PPR_IU_REQ;
7770 if ((ahd->features & AHD_RTI) != 0)
7771 user_tinfo->ppr_options |= MSG_EXT_PPR_RTI;
7772 }
7773
7774 if ((sc->device_flags[targ] & CFQAS) != 0)
7775 user_tinfo->ppr_options |= MSG_EXT_PPR_QAS_REQ;
7776
7777 if ((sc->device_flags[targ] & CFWIDEB) != 0)
7778 user_tinfo->width = MSG_EXT_WDTR_BUS_16_BIT;
7779 else
7780 user_tinfo->width = MSG_EXT_WDTR_BUS_8_BIT;
7781#ifdef AHD_DEBUG
7782 if ((ahd_debug & AHD_SHOW_MISC) != 0)
7783 printk("(%d): %x:%x:%x:%x\n", targ, user_tinfo->width,
7784 user_tinfo->period, user_tinfo->offset,
7785 user_tinfo->ppr_options);
7786#endif
7787
7788
7789
7790
7791 tstate->tagenable &= ~target_mask;
7792 tinfo->goal.protocol_version = 2;
7793 tinfo->goal.transport_version = 2;
7794 tinfo->curr.protocol_version = 2;
7795 tinfo->curr.transport_version = 2;
7796 ahd_compile_devinfo(&devinfo, ahd->our_id,
7797 targ, CAM_LUN_WILDCARD,
7798 'A', ROLE_INITIATOR);
7799 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
7800 AHD_TRANS_CUR|AHD_TRANS_GOAL, TRUE);
7801 ahd_set_syncrate(ahd, &devinfo, 0, 0,
7802 0, AHD_TRANS_CUR|AHD_TRANS_GOAL,
7803 TRUE);
7804 }
7805
7806 ahd->flags &= ~AHD_SPCHK_ENB_A;
7807 if (sc->bios_control & CFSPARITY)
7808 ahd->flags |= AHD_SPCHK_ENB_A;
7809
7810 ahd->flags &= ~AHD_RESET_BUS_A;
7811 if (sc->bios_control & CFRESETB)
7812 ahd->flags |= AHD_RESET_BUS_A;
7813
7814 ahd->flags &= ~AHD_EXTENDED_TRANS_A;
7815 if (sc->bios_control & CFEXTEND)
7816 ahd->flags |= AHD_EXTENDED_TRANS_A;
7817
7818 ahd->flags &= ~AHD_BIOS_ENABLED;
7819 if ((sc->bios_control & CFBIOSSTATE) == CFBS_ENABLED)
7820 ahd->flags |= AHD_BIOS_ENABLED;
7821
7822 ahd->flags &= ~AHD_STPWLEVEL_A;
7823 if ((sc->adapter_control & CFSTPWLEVEL) != 0)
7824 ahd->flags |= AHD_STPWLEVEL_A;
7825
7826 return (0);
7827}
7828
7829
7830
7831
7832int
7833ahd_parse_vpddata(struct ahd_softc *ahd, struct vpd_config *vpd)
7834{
7835 int error;
7836
7837 error = ahd_verify_vpd_cksum(vpd);
7838 if (error == 0)
7839 return (EINVAL);
7840 if ((vpd->bios_flags & VPDBOOTHOST) != 0)
7841 ahd->flags |= AHD_BOOT_CHANNEL;
7842 return (0);
7843}
7844
7845void
7846ahd_intr_enable(struct ahd_softc *ahd, int enable)
7847{
7848 u_int hcntrl;
7849
7850 hcntrl = ahd_inb(ahd, HCNTRL);
7851 hcntrl &= ~INTEN;
7852 ahd->pause &= ~INTEN;
7853 ahd->unpause &= ~INTEN;
7854 if (enable) {
7855 hcntrl |= INTEN;
7856 ahd->pause |= INTEN;
7857 ahd->unpause |= INTEN;
7858 }
7859 ahd_outb(ahd, HCNTRL, hcntrl);
7860}
7861
7862static void
7863ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds,
7864 u_int mincmds)
7865{
7866 if (timer > AHD_TIMER_MAX_US)
7867 timer = AHD_TIMER_MAX_US;
7868 ahd->int_coalescing_timer = timer;
7869
7870 if (maxcmds > AHD_INT_COALESCING_MAXCMDS_MAX)
7871 maxcmds = AHD_INT_COALESCING_MAXCMDS_MAX;
7872 if (mincmds > AHD_INT_COALESCING_MINCMDS_MAX)
7873 mincmds = AHD_INT_COALESCING_MINCMDS_MAX;
7874 ahd->int_coalescing_maxcmds = maxcmds;
7875 ahd_outw(ahd, INT_COALESCING_TIMER, timer / AHD_TIMER_US_PER_TICK);
7876 ahd_outb(ahd, INT_COALESCING_MAXCMDS, -maxcmds);
7877 ahd_outb(ahd, INT_COALESCING_MINCMDS, -mincmds);
7878}
7879
7880static void
7881ahd_enable_coalescing(struct ahd_softc *ahd, int enable)
7882{
7883
7884 ahd->hs_mailbox &= ~ENINT_COALESCE;
7885 if (enable)
7886 ahd->hs_mailbox |= ENINT_COALESCE;
7887 ahd_outb(ahd, HS_MAILBOX, ahd->hs_mailbox);
7888 ahd_flush_device_writes(ahd);
7889 ahd_run_qoutfifo(ahd);
7890}
7891
7892
7893
7894
7895
7896
7897
7898
7899void
7900ahd_pause_and_flushwork(struct ahd_softc *ahd)
7901{
7902 u_int intstat;
7903 u_int maxloops;
7904
7905 maxloops = 1000;
7906 ahd->flags |= AHD_ALL_INTERRUPTS;
7907 ahd_pause(ahd);
7908
7909
7910
7911
7912
7913 ahd->qfreeze_cnt--;
7914 ahd_outw(ahd, KERNEL_QFREEZE_COUNT, ahd->qfreeze_cnt);
7915 ahd_outb(ahd, SEQ_FLAGS2, ahd_inb(ahd, SEQ_FLAGS2) | SELECTOUT_QFROZEN);
7916 do {
7917
7918 ahd_unpause(ahd);
7919
7920
7921
7922
7923 ahd_delay(500);
7924
7925 ahd_intr(ahd);
7926 ahd_pause(ahd);
7927 intstat = ahd_inb(ahd, INTSTAT);
7928 if ((intstat & INT_PEND) == 0) {
7929 ahd_clear_critical_section(ahd);
7930 intstat = ahd_inb(ahd, INTSTAT);
7931 }
7932 } while (--maxloops
7933 && (intstat != 0xFF || (ahd->features & AHD_REMOVABLE) == 0)
7934 && ((intstat & INT_PEND) != 0
7935 || (ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0
7936 || (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0));
7937
7938 if (maxloops == 0) {
7939 printk("Infinite interrupt loop, INTSTAT = %x",
7940 ahd_inb(ahd, INTSTAT));
7941 }
7942 ahd->qfreeze_cnt++;
7943 ahd_outw(ahd, KERNEL_QFREEZE_COUNT, ahd->qfreeze_cnt);
7944
7945 ahd_flush_qoutfifo(ahd);
7946
7947 ahd->flags &= ~AHD_ALL_INTERRUPTS;
7948}
7949
7950#ifdef CONFIG_PM
7951int
7952ahd_suspend(struct ahd_softc *ahd)
7953{
7954
7955 ahd_pause_and_flushwork(ahd);
7956
7957 if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
7958 ahd_unpause(ahd);
7959 return (EBUSY);
7960 }
7961 ahd_shutdown(ahd);
7962 return (0);
7963}
7964
7965void
7966ahd_resume(struct ahd_softc *ahd)
7967{
7968
7969 ahd_reset(ahd, TRUE);
7970 ahd_intr_enable(ahd, TRUE);
7971 ahd_restart(ahd);
7972}
7973#endif
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984static inline u_int
7985ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl)
7986{
7987
7988
7989
7990 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
7991 *saved_scbid = ahd_get_scbptr(ahd);
7992 ahd_set_scbptr(ahd, TCL_LUN(tcl)
7993 | ((TCL_TARGET_OFFSET(tcl) & 0xC) << 4));
7994
7995
7996
7997
7998
7999
8000 return (((TCL_TARGET_OFFSET(tcl) & 0x3) << 1) + SCB_DISCONNECTED_LISTS);
8001}
8002
8003
8004
8005
8006static u_int
8007ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl)
8008{
8009 u_int scbid;
8010 u_int scb_offset;
8011 u_int saved_scbptr;
8012
8013 scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl);
8014 scbid = ahd_inw_scbram(ahd, scb_offset);
8015 ahd_set_scbptr(ahd, saved_scbptr);
8016 return (scbid);
8017}
8018
8019static void
8020ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid)
8021{
8022 u_int scb_offset;
8023 u_int saved_scbptr;
8024
8025 scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl);
8026 ahd_outw(ahd, scb_offset, scbid);
8027 ahd_set_scbptr(ahd, saved_scbptr);
8028}
8029
8030
8031static int
8032ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, int target,
8033 char channel, int lun, u_int tag, role_t role)
8034{
8035 int targ = SCB_GET_TARGET(ahd, scb);
8036 char chan = SCB_GET_CHANNEL(ahd, scb);
8037 int slun = SCB_GET_LUN(scb);
8038 int match;
8039
8040 match = ((chan == channel) || (channel == ALL_CHANNELS));
8041 if (match != 0)
8042 match = ((targ == target) || (target == CAM_TARGET_WILDCARD));
8043 if (match != 0)
8044 match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));
8045 if (match != 0) {
8046#ifdef AHD_TARGET_MODE
8047 int group;
8048
8049 group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);
8050 if (role == ROLE_INITIATOR) {
8051 match = (group != XPT_FC_GROUP_TMODE)
8052 && ((tag == SCB_GET_TAG(scb))
8053 || (tag == SCB_LIST_NULL));
8054 } else if (role == ROLE_TARGET) {
8055 match = (group == XPT_FC_GROUP_TMODE)
8056 && ((tag == scb->io_ctx->csio.tag_id)
8057 || (tag == SCB_LIST_NULL));
8058 }
8059#else
8060 match = ((tag == SCB_GET_TAG(scb)) || (tag == SCB_LIST_NULL));
8061#endif
8062 }
8063
8064 return match;
8065}
8066
8067static void
8068ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
8069{
8070 int target;
8071 char channel;
8072 int lun;
8073
8074 target = SCB_GET_TARGET(ahd, scb);
8075 lun = SCB_GET_LUN(scb);
8076 channel = SCB_GET_CHANNEL(ahd, scb);
8077
8078 ahd_search_qinfifo(ahd, target, channel, lun,
8079 SCB_LIST_NULL, ROLE_UNKNOWN,
8080 CAM_REQUEUE_REQ, SEARCH_COMPLETE);
8081
8082 ahd_platform_freeze_devq(ahd, scb);
8083}
8084
8085void
8086ahd_qinfifo_requeue_tail(struct ahd_softc *ahd, struct scb *scb)
8087{
8088 struct scb *prev_scb;
8089 ahd_mode_state saved_modes;
8090
8091 saved_modes = ahd_save_modes(ahd);
8092 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
8093 prev_scb = NULL;
8094 if (ahd_qinfifo_count(ahd) != 0) {
8095 u_int prev_tag;
8096 u_int prev_pos;
8097
8098 prev_pos = AHD_QIN_WRAP(ahd->qinfifonext - 1);
8099 prev_tag = ahd->qinfifo[prev_pos];
8100 prev_scb = ahd_lookup_scb(ahd, prev_tag);
8101 }
8102 ahd_qinfifo_requeue(ahd, prev_scb, scb);
8103 ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
8104 ahd_restore_modes(ahd, saved_modes);
8105}
8106
8107static void
8108ahd_qinfifo_requeue(struct ahd_softc *ahd, struct scb *prev_scb,
8109 struct scb *scb)
8110{
8111 if (prev_scb == NULL) {
8112 uint32_t busaddr;
8113
8114 busaddr = ahd_le32toh(scb->hscb->hscb_busaddr);
8115 ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr);
8116 } else {
8117 prev_scb->hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr;
8118 ahd_sync_scb(ahd, prev_scb,
8119 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
8120 }
8121 ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb);
8122 ahd->qinfifonext++;
8123 scb->hscb->next_hscb_busaddr = ahd->next_queued_hscb->hscb_busaddr;
8124 ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
8125}
8126
8127static int
8128ahd_qinfifo_count(struct ahd_softc *ahd)
8129{
8130 u_int qinpos;
8131 u_int wrap_qinpos;
8132 u_int wrap_qinfifonext;
8133
8134 AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);
8135 qinpos = ahd_get_snscb_qoff(ahd);
8136 wrap_qinpos = AHD_QIN_WRAP(qinpos);
8137 wrap_qinfifonext = AHD_QIN_WRAP(ahd->qinfifonext);
8138 if (wrap_qinfifonext >= wrap_qinpos)
8139 return (wrap_qinfifonext - wrap_qinpos);
8140 else
8141 return (wrap_qinfifonext
8142 + ARRAY_SIZE(ahd->qinfifo) - wrap_qinpos);
8143}
8144
8145static void
8146ahd_reset_cmds_pending(struct ahd_softc *ahd)
8147{
8148 struct scb *scb;
8149 ahd_mode_state saved_modes;
8150 u_int pending_cmds;
8151
8152 saved_modes = ahd_save_modes(ahd);
8153 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
8154
8155
8156
8157
8158
8159 ahd_flush_qoutfifo(ahd);
8160
8161 pending_cmds = 0;
8162 LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
8163 pending_cmds++;
8164 }
8165 ahd_outw(ahd, CMDS_PENDING, pending_cmds - ahd_qinfifo_count(ahd));
8166 ahd_restore_modes(ahd, saved_modes);
8167 ahd->flags &= ~AHD_UPDATE_PEND_CMDS;
8168}
8169
8170static void
8171ahd_done_with_status(struct ahd_softc *ahd, struct scb *scb, uint32_t status)
8172{
8173 cam_status ostat;
8174 cam_status cstat;
8175
8176 ostat = ahd_get_transaction_status(scb);
8177 if (ostat == CAM_REQ_INPROG)
8178 ahd_set_transaction_status(scb, status);
8179 cstat = ahd_get_transaction_status(scb);
8180 if (cstat != CAM_REQ_CMP)
8181 ahd_freeze_scb(scb);
8182 ahd_done(ahd, scb);
8183}
8184
8185int
8186ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
8187 int lun, u_int tag, role_t role, uint32_t status,
8188 ahd_search_action action)
8189{
8190 struct scb *scb;
8191 struct scb *mk_msg_scb;
8192 struct scb *prev_scb;
8193 ahd_mode_state saved_modes;
8194 u_int qinstart;
8195 u_int qinpos;
8196 u_int qintail;
8197 u_int tid_next;
8198 u_int tid_prev;
8199 u_int scbid;
8200 u_int seq_flags2;
8201 u_int savedscbptr;
8202 uint32_t busaddr;
8203 int found;
8204 int targets;
8205
8206
8207 saved_modes = ahd_save_modes(ahd);
8208 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
8209
8210
8211
8212
8213
8214 if ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN|CCSCBDIR))
8215 == (CCARREN|CCSCBEN|CCSCBDIR)) {
8216 ahd_outb(ahd, CCSCBCTL,
8217 ahd_inb(ahd, CCSCBCTL) & ~(CCARREN|CCSCBEN));
8218 while ((ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN)) != 0)
8219 ;
8220 }
8221
8222 qintail = AHD_QIN_WRAP(ahd->qinfifonext);
8223 qinstart = ahd_get_snscb_qoff(ahd);
8224 qinpos = AHD_QIN_WRAP(qinstart);
8225 found = 0;
8226 prev_scb = NULL;
8227
8228 if (action == SEARCH_PRINT) {
8229 printk("qinstart = %d qinfifonext = %d\nQINFIFO:",
8230 qinstart, ahd->qinfifonext);
8231 }
8232
8233
8234
8235
8236
8237 ahd->qinfifonext = qinstart;
8238 busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr);
8239 ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr);
8240
8241 while (qinpos != qintail) {
8242 scb = ahd_lookup_scb(ahd, ahd->qinfifo[qinpos]);
8243 if (scb == NULL) {
8244 printk("qinpos = %d, SCB index = %d\n",
8245 qinpos, ahd->qinfifo[qinpos]);
8246 panic("Loop 1\n");
8247 }
8248
8249 if (ahd_match_scb(ahd, scb, target, channel, lun, tag, role)) {
8250
8251
8252
8253 found++;
8254 switch (action) {
8255 case SEARCH_COMPLETE:
8256 if ((scb->flags & SCB_ACTIVE) == 0)
8257 printk("Inactive SCB in qinfifo\n");
8258 ahd_done_with_status(ahd, scb, status);
8259
8260 case SEARCH_REMOVE:
8261 break;
8262 case SEARCH_PRINT:
8263 printk(" 0x%x", ahd->qinfifo[qinpos]);
8264
8265 case SEARCH_COUNT:
8266 ahd_qinfifo_requeue(ahd, prev_scb, scb);
8267 prev_scb = scb;
8268 break;
8269 }
8270 } else {
8271 ahd_qinfifo_requeue(ahd, prev_scb, scb);
8272 prev_scb = scb;
8273 }
8274 qinpos = AHD_QIN_WRAP(qinpos+1);
8275 }
8276
8277 ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
8278
8279 if (action == SEARCH_PRINT)
8280 printk("\nWAITING_TID_QUEUES:\n");
8281
8282
8283
8284
8285
8286
8287
8288 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
8289 seq_flags2 = ahd_inb(ahd, SEQ_FLAGS2);
8290 if ((seq_flags2 & PENDING_MK_MESSAGE) != 0) {
8291 scbid = ahd_inw(ahd, MK_MESSAGE_SCB);
8292 mk_msg_scb = ahd_lookup_scb(ahd, scbid);
8293 } else
8294 mk_msg_scb = NULL;
8295 savedscbptr = ahd_get_scbptr(ahd);
8296 tid_next = ahd_inw(ahd, WAITING_TID_HEAD);
8297 tid_prev = SCB_LIST_NULL;
8298 targets = 0;
8299 for (scbid = tid_next; !SCBID_IS_NULL(scbid); scbid = tid_next) {
8300 u_int tid_head;
8301 u_int tid_tail;
8302
8303 targets++;
8304 if (targets > AHD_NUM_TARGETS)
8305 panic("TID LIST LOOP");
8306
8307 if (scbid >= ahd->scb_data.numscbs) {
8308 printk("%s: Waiting TID List inconsistency. "
8309 "SCB index == 0x%x, yet numscbs == 0x%x.",
8310 ahd_name(ahd), scbid, ahd->scb_data.numscbs);
8311 ahd_dump_card_state(ahd);
8312 panic("for safety");
8313 }
8314 scb = ahd_lookup_scb(ahd, scbid);
8315 if (scb == NULL) {
8316 printk("%s: SCB = 0x%x Not Active!\n",
8317 ahd_name(ahd), scbid);
8318 panic("Waiting TID List traversal\n");
8319 }
8320 ahd_set_scbptr(ahd, scbid);
8321 tid_next = ahd_inw_scbram(ahd, SCB_NEXT2);
8322 if (ahd_match_scb(ahd, scb, target, channel, CAM_LUN_WILDCARD,
8323 SCB_LIST_NULL, ROLE_UNKNOWN) == 0) {
8324 tid_prev = scbid;
8325 continue;
8326 }
8327
8328
8329
8330
8331 if (action == SEARCH_PRINT)
8332 printk(" %d ( ", SCB_GET_TARGET(ahd, scb));
8333 tid_head = scbid;
8334 found += ahd_search_scb_list(ahd, target, channel,
8335 lun, tag, role, status,
8336 action, &tid_head, &tid_tail,
8337 SCB_GET_TARGET(ahd, scb));
8338
8339
8340
8341
8342 if (mk_msg_scb != NULL
8343 && ahd_match_scb(ahd, mk_msg_scb, target, channel,
8344 lun, tag, role)) {
8345
8346
8347
8348
8349 found++;
8350 switch (action) {
8351 case SEARCH_COMPLETE:
8352 if ((mk_msg_scb->flags & SCB_ACTIVE) == 0)
8353 printk("Inactive SCB pending MK_MSG\n");
8354 ahd_done_with_status(ahd, mk_msg_scb, status);
8355
8356 case SEARCH_REMOVE:
8357 {
8358 u_int tail_offset;
8359
8360 printk("Removing MK_MSG scb\n");
8361
8362
8363
8364
8365
8366 tail_offset = WAITING_SCB_TAILS
8367 + (2 * SCB_GET_TARGET(ahd, mk_msg_scb));
8368 ahd_outw(ahd, tail_offset, tid_tail);
8369
8370 seq_flags2 &= ~PENDING_MK_MESSAGE;
8371 ahd_outb(ahd, SEQ_FLAGS2, seq_flags2);
8372 ahd_outw(ahd, CMDS_PENDING,
8373 ahd_inw(ahd, CMDS_PENDING)-1);
8374 mk_msg_scb = NULL;
8375 break;
8376 }
8377 case SEARCH_PRINT:
8378 printk(" 0x%x", SCB_GET_TAG(scb));
8379
8380 case SEARCH_COUNT:
8381 break;
8382 }
8383 }
8384
8385 if (mk_msg_scb != NULL
8386 && SCBID_IS_NULL(tid_head)
8387 && ahd_match_scb(ahd, scb, target, channel, CAM_LUN_WILDCARD,
8388 SCB_LIST_NULL, ROLE_UNKNOWN)) {
8389
8390
8391
8392
8393
8394
8395 printk("Queueing mk_msg_scb\n");
8396 tid_head = ahd_inw(ahd, MK_MESSAGE_SCB);
8397 seq_flags2 &= ~PENDING_MK_MESSAGE;
8398 ahd_outb(ahd, SEQ_FLAGS2, seq_flags2);
8399 mk_msg_scb = NULL;
8400 }
8401 if (tid_head != scbid)
8402 ahd_stitch_tid_list(ahd, tid_prev, tid_head, tid_next);
8403 if (!SCBID_IS_NULL(tid_head))
8404 tid_prev = tid_head;
8405 if (action == SEARCH_PRINT)
8406 printk(")\n");
8407 }
8408
8409
8410 ahd_set_scbptr(ahd, savedscbptr);
8411 ahd_restore_modes(ahd, saved_modes);
8412 return (found);
8413}
8414
8415static int
8416ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel,
8417 int lun, u_int tag, role_t role, uint32_t status,
8418 ahd_search_action action, u_int *list_head,
8419 u_int *list_tail, u_int tid)
8420{
8421 struct scb *scb;
8422 u_int scbid;
8423 u_int next;
8424 u_int prev;
8425 int found;
8426
8427 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
8428 found = 0;
8429 prev = SCB_LIST_NULL;
8430 next = *list_head;
8431 *list_tail = SCB_LIST_NULL;
8432 for (scbid = next; !SCBID_IS_NULL(scbid); scbid = next) {
8433 if (scbid >= ahd->scb_data.numscbs) {
8434 printk("%s:SCB List inconsistency. "
8435 "SCB == 0x%x, yet numscbs == 0x%x.",
8436 ahd_name(ahd), scbid, ahd->scb_data.numscbs);
8437 ahd_dump_card_state(ahd);
8438 panic("for safety");
8439 }
8440 scb = ahd_lookup_scb(ahd, scbid);
8441 if (scb == NULL) {
8442 printk("%s: SCB = %d Not Active!\n",
8443 ahd_name(ahd), scbid);
8444 panic("Waiting List traversal\n");
8445 }
8446 ahd_set_scbptr(ahd, scbid);
8447 *list_tail = scbid;
8448 next = ahd_inw_scbram(ahd, SCB_NEXT);
8449 if (ahd_match_scb(ahd, scb, target, channel,
8450 lun, SCB_LIST_NULL, role) == 0) {
8451 prev = scbid;
8452 continue;
8453 }
8454 found++;
8455 switch (action) {
8456 case SEARCH_COMPLETE:
8457 if ((scb->flags & SCB_ACTIVE) == 0)
8458 printk("Inactive SCB in Waiting List\n");
8459 ahd_done_with_status(ahd, scb, status);
8460
8461 case SEARCH_REMOVE:
8462 ahd_rem_wscb(ahd, scbid, prev, next, tid);
8463 *list_tail = prev;
8464 if (SCBID_IS_NULL(prev))
8465 *list_head = next;
8466 break;
8467 case SEARCH_PRINT:
8468 printk("0x%x ", scbid);
8469 case SEARCH_COUNT:
8470 prev = scbid;
8471 break;
8472 }
8473 if (found > AHD_SCB_MAX)
8474 panic("SCB LIST LOOP");
8475 }
8476 if (action == SEARCH_COMPLETE
8477 || action == SEARCH_REMOVE)
8478 ahd_outw(ahd, CMDS_PENDING, ahd_inw(ahd, CMDS_PENDING) - found);
8479 return (found);
8480}
8481
8482static void
8483ahd_stitch_tid_list(struct ahd_softc *ahd, u_int tid_prev,
8484 u_int tid_cur, u_int tid_next)
8485{
8486 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
8487
8488 if (SCBID_IS_NULL(tid_cur)) {
8489
8490
8491 if (SCBID_IS_NULL(tid_prev)) {
8492 ahd_outw(ahd, WAITING_TID_HEAD, tid_next);
8493 } else {
8494 ahd_set_scbptr(ahd, tid_prev);
8495 ahd_outw(ahd, SCB_NEXT2, tid_next);
8496 }
8497 if (SCBID_IS_NULL(tid_next))
8498 ahd_outw(ahd, WAITING_TID_TAIL, tid_prev);
8499 } else {
8500
8501
8502 if (SCBID_IS_NULL(tid_prev)) {
8503 ahd_outw(ahd, WAITING_TID_HEAD, tid_cur);
8504 } else {
8505 ahd_set_scbptr(ahd, tid_prev);
8506 ahd_outw(ahd, SCB_NEXT2, tid_cur);
8507 }
8508 ahd_set_scbptr(ahd, tid_cur);
8509 ahd_outw(ahd, SCB_NEXT2, tid_next);
8510
8511 if (SCBID_IS_NULL(tid_next))
8512 ahd_outw(ahd, WAITING_TID_TAIL, tid_cur);
8513 }
8514}
8515
8516
8517
8518
8519
8520static u_int
8521ahd_rem_wscb(struct ahd_softc *ahd, u_int scbid,
8522 u_int prev, u_int next, u_int tid)
8523{
8524 u_int tail_offset;
8525
8526 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
8527 if (!SCBID_IS_NULL(prev)) {
8528 ahd_set_scbptr(ahd, prev);
8529 ahd_outw(ahd, SCB_NEXT, next);
8530 }
8531
8532
8533
8534
8535
8536
8537
8538
8539 tail_offset = WAITING_SCB_TAILS + (2 * tid);
8540 if (SCBID_IS_NULL(next)
8541 && ahd_inw(ahd, tail_offset) == scbid)
8542 ahd_outw(ahd, tail_offset, prev);
8543
8544 ahd_add_scb_to_free_list(ahd, scbid);
8545 return (next);
8546}
8547
8548
8549
8550
8551
8552
8553static void
8554ahd_add_scb_to_free_list(struct ahd_softc *ahd, u_int scbid)
8555{
8556
8557
8558
8559
8560
8561
8562}
8563
8564
8565
8566
8567
8568
8569
8570
8571static int
8572ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel,
8573 int lun, u_int tag, role_t role, uint32_t status)
8574{
8575 struct scb *scbp;
8576 struct scb *scbp_next;
8577 u_int i, j;
8578 u_int maxtarget;
8579 u_int minlun;
8580 u_int maxlun;
8581 int found;
8582 ahd_mode_state saved_modes;
8583
8584
8585 saved_modes = ahd_save_modes(ahd);
8586 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
8587
8588 found = ahd_search_qinfifo(ahd, target, channel, lun, SCB_LIST_NULL,
8589 role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);
8590
8591
8592
8593
8594 i = 0;
8595 maxtarget = 16;
8596 if (target != CAM_TARGET_WILDCARD) {
8597 i = target;
8598 if (channel == 'B')
8599 i += 8;
8600 maxtarget = i + 1;
8601 }
8602
8603 if (lun == CAM_LUN_WILDCARD) {
8604 minlun = 0;
8605 maxlun = AHD_NUM_LUNS_NONPKT;
8606 } else if (lun >= AHD_NUM_LUNS_NONPKT) {
8607 minlun = maxlun = 0;
8608 } else {
8609 minlun = lun;
8610 maxlun = lun + 1;
8611 }
8612
8613 if (role != ROLE_TARGET) {
8614 for (;i < maxtarget; i++) {
8615 for (j = minlun;j < maxlun; j++) {
8616 u_int scbid;
8617 u_int tcl;
8618
8619 tcl = BUILD_TCL_RAW(i, 'A', j);
8620 scbid = ahd_find_busy_tcl(ahd, tcl);
8621 scbp = ahd_lookup_scb(ahd, scbid);
8622 if (scbp == NULL
8623 || ahd_match_scb(ahd, scbp, target, channel,
8624 lun, tag, role) == 0)
8625 continue;
8626 ahd_unbusy_tcl(ahd, BUILD_TCL_RAW(i, 'A', j));
8627 }
8628 }
8629 }
8630
8631
8632
8633
8634
8635 ahd_flush_qoutfifo(ahd);
8636
8637
8638
8639
8640
8641
8642
8643 scbp_next = LIST_FIRST(&ahd->pending_scbs);
8644 while (scbp_next != NULL) {
8645 scbp = scbp_next;
8646 scbp_next = LIST_NEXT(scbp, pending_links);
8647 if (ahd_match_scb(ahd, scbp, target, channel, lun, tag, role)) {
8648 cam_status ostat;
8649
8650 ostat = ahd_get_transaction_status(scbp);
8651 if (ostat == CAM_REQ_INPROG)
8652 ahd_set_transaction_status(scbp, status);
8653 if (ahd_get_transaction_status(scbp) != CAM_REQ_CMP)
8654 ahd_freeze_scb(scbp);
8655 if ((scbp->flags & SCB_ACTIVE) == 0)
8656 printk("Inactive SCB on pending list\n");
8657 ahd_done(ahd, scbp);
8658 found++;
8659 }
8660 }
8661 ahd_restore_modes(ahd, saved_modes);
8662 ahd_platform_abort_scbs(ahd, target, channel, lun, tag, role, status);
8663 ahd->flags |= AHD_UPDATE_PEND_CMDS;
8664 return found;
8665}
8666
8667static void
8668ahd_reset_current_bus(struct ahd_softc *ahd)
8669{
8670 uint8_t scsiseq;
8671
8672 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
8673 ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) & ~ENSCSIRST);
8674 scsiseq = ahd_inb(ahd, SCSISEQ0) & ~(ENSELO|ENARBO|SCSIRSTO);
8675 ahd_outb(ahd, SCSISEQ0, scsiseq | SCSIRSTO);
8676 ahd_flush_device_writes(ahd);
8677 ahd_delay(AHD_BUSRESET_DELAY);
8678
8679 ahd_outb(ahd, SCSISEQ0, scsiseq);
8680 ahd_flush_device_writes(ahd);
8681 ahd_delay(AHD_BUSRESET_DELAY);
8682 if ((ahd->bugs & AHD_SCSIRST_BUG) != 0) {
8683
8684
8685
8686
8687
8688
8689 ahd_reset(ahd, TRUE);
8690 ahd_intr_enable(ahd, TRUE);
8691 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
8692 }
8693
8694 ahd_clear_intstat(ahd);
8695}
8696
8697int
8698ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
8699{
8700 struct ahd_devinfo caminfo;
8701 u_int initiator;
8702 u_int target;
8703 u_int max_scsiid;
8704 int found;
8705 u_int fifo;
8706 u_int next_fifo;
8707 uint8_t scsiseq;
8708
8709
8710
8711
8712 if (ahd->flags & AHD_BUS_RESET_ACTIVE) {
8713 printk("%s: bus reset still active\n",
8714 ahd_name(ahd));
8715 return 0;
8716 }
8717 ahd->flags |= AHD_BUS_RESET_ACTIVE;
8718
8719 ahd->pending_device = NULL;
8720
8721 ahd_compile_devinfo(&caminfo,
8722 CAM_TARGET_WILDCARD,
8723 CAM_TARGET_WILDCARD,
8724 CAM_LUN_WILDCARD,
8725 channel, ROLE_UNKNOWN);
8726 ahd_pause(ahd);
8727
8728
8729 ahd_clear_critical_section(ahd);
8730
8731
8732
8733
8734
8735
8736 ahd_run_qoutfifo(ahd);
8737#ifdef AHD_TARGET_MODE
8738 if ((ahd->flags & AHD_TARGETROLE) != 0) {
8739 ahd_run_tqinfifo(ahd, TRUE);
8740 }
8741#endif
8742 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
8743
8744
8745
8746
8747
8748 ahd_outb(ahd, SCSISEQ0, 0);
8749 ahd_outb(ahd, SCSISEQ1, 0);
8750
8751
8752
8753
8754
8755
8756 next_fifo = fifo = ahd_inb(ahd, DFFSTAT) & CURRFIFO;
8757 if (next_fifo > CURRFIFO_1)
8758
8759 next_fifo = fifo = 0;
8760 do {
8761 next_fifo ^= CURRFIFO_1;
8762 ahd_set_modes(ahd, next_fifo, next_fifo);
8763 ahd_outb(ahd, DFCNTRL,
8764 ahd_inb(ahd, DFCNTRL) & ~(SCSIEN|HDMAEN));
8765 while ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) != 0)
8766 ahd_delay(10);
8767
8768
8769
8770 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
8771 ahd_outb(ahd, DFFSTAT, next_fifo);
8772 } while (next_fifo != fifo);
8773
8774
8775
8776
8777 ahd_clear_msg_state(ahd);
8778 ahd_outb(ahd, SIMODE1,
8779 ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST));
8780
8781 if (initiate_reset)
8782 ahd_reset_current_bus(ahd);
8783
8784 ahd_clear_intstat(ahd);
8785
8786
8787
8788
8789
8790 found = ahd_abort_scbs(ahd, CAM_TARGET_WILDCARD, channel,
8791 CAM_LUN_WILDCARD, SCB_LIST_NULL,
8792 ROLE_UNKNOWN, CAM_SCSI_BUS_RESET);
8793
8794
8795
8796
8797 ahd_clear_fifo(ahd, 0);
8798 ahd_clear_fifo(ahd, 1);
8799
8800
8801
8802
8803 ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
8804
8805
8806
8807
8808 ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) | ENSCSIRST);
8809 scsiseq = ahd_inb(ahd, SCSISEQ_TEMPLATE);
8810 ahd_outb(ahd, SCSISEQ1, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
8811
8812 max_scsiid = (ahd->features & AHD_WIDE) ? 15 : 7;
8813#ifdef AHD_TARGET_MODE
8814
8815
8816
8817
8818 for (target = 0; target <= max_scsiid; target++) {
8819 struct ahd_tmode_tstate* tstate;
8820 u_int lun;
8821
8822 tstate = ahd->enabled_targets[target];
8823 if (tstate == NULL)
8824 continue;
8825 for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
8826 struct ahd_tmode_lstate* lstate;
8827
8828 lstate = tstate->enabled_luns[lun];
8829 if (lstate == NULL)
8830 continue;
8831
8832 ahd_queue_lstate_event(ahd, lstate, CAM_TARGET_WILDCARD,
8833 EVENT_TYPE_BUS_RESET, 0);
8834 ahd_send_lstate_events(ahd, lstate);
8835 }
8836 }
8837#endif
8838
8839
8840
8841 for (target = 0; target <= max_scsiid; target++) {
8842
8843 if (ahd->enabled_targets[target] == NULL)
8844 continue;
8845 for (initiator = 0; initiator <= max_scsiid; initiator++) {
8846 struct ahd_devinfo devinfo;
8847
8848 ahd_compile_devinfo(&devinfo, target, initiator,
8849 CAM_LUN_WILDCARD,
8850 'A', ROLE_UNKNOWN);
8851 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
8852 AHD_TRANS_CUR, TRUE);
8853 ahd_set_syncrate(ahd, &devinfo, 0,
8854 0, 0,
8855 AHD_TRANS_CUR, TRUE);
8856 }
8857 }
8858
8859
8860 ahd_send_async(ahd, caminfo.channel, CAM_TARGET_WILDCARD,
8861 CAM_LUN_WILDCARD, AC_BUS_RESET);
8862
8863 ahd_restart(ahd);
8864
8865 return (found);
8866}
8867
8868
8869static void
8870ahd_stat_timer(struct timer_list *t)
8871{
8872 struct ahd_softc *ahd = from_timer(ahd, t, stat_timer);
8873 u_long s;
8874 int enint_coal;
8875
8876 ahd_lock(ahd, &s);
8877
8878 enint_coal = ahd->hs_mailbox & ENINT_COALESCE;
8879 if (ahd->cmdcmplt_total > ahd->int_coalescing_threshold)
8880 enint_coal |= ENINT_COALESCE;
8881 else if (ahd->cmdcmplt_total < ahd->int_coalescing_stop_threshold)
8882 enint_coal &= ~ENINT_COALESCE;
8883
8884 if (enint_coal != (ahd->hs_mailbox & ENINT_COALESCE)) {
8885 ahd_enable_coalescing(ahd, enint_coal);
8886#ifdef AHD_DEBUG
8887 if ((ahd_debug & AHD_SHOW_INT_COALESCING) != 0)
8888 printk("%s: Interrupt coalescing "
8889 "now %sabled. Cmds %d\n",
8890 ahd_name(ahd),
8891 (enint_coal & ENINT_COALESCE) ? "en" : "dis",
8892 ahd->cmdcmplt_total);
8893#endif
8894 }
8895
8896 ahd->cmdcmplt_bucket = (ahd->cmdcmplt_bucket+1) & (AHD_STAT_BUCKETS-1);
8897 ahd->cmdcmplt_total -= ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket];
8898 ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket] = 0;
8899 ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US);
8900 ahd_unlock(ahd, &s);
8901}
8902
8903
8904
8905static void
8906ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
8907{
8908 struct hardware_scb *hscb;
8909 int paused;
8910
8911
8912
8913
8914
8915
8916
8917
8918
8919
8920 hscb = scb->hscb;
8921
8922 if (ahd_is_paused(ahd)) {
8923 paused = 1;
8924 } else {
8925 paused = 0;
8926 ahd_pause(ahd);
8927 }
8928
8929
8930 ahd_freeze_devq(ahd, scb);
8931 ahd_freeze_scb(scb);
8932 ahd->qfreeze_cnt++;
8933 ahd_outw(ahd, KERNEL_QFREEZE_COUNT, ahd->qfreeze_cnt);
8934
8935 if (paused == 0)
8936 ahd_unpause(ahd);
8937
8938
8939 if ((scb->flags & SCB_SENSE) != 0) {
8940
8941
8942
8943
8944 scb->flags &= ~SCB_SENSE;
8945 ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
8946 ahd_done(ahd, scb);
8947 return;
8948 }
8949 ahd_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR);
8950 ahd_set_scsi_status(scb, hscb->shared_data.istatus.scsi_status);
8951 switch (hscb->shared_data.istatus.scsi_status) {
8952 case STATUS_PKT_SENSE:
8953 {
8954 struct scsi_status_iu_header *siu;
8955
8956 ahd_sync_sense(ahd, scb, BUS_DMASYNC_POSTREAD);
8957 siu = (struct scsi_status_iu_header *)scb->sense_data;
8958 ahd_set_scsi_status(scb, siu->status);
8959#ifdef AHD_DEBUG
8960 if ((ahd_debug & AHD_SHOW_SENSE) != 0) {
8961 ahd_print_path(ahd, scb);
8962 printk("SCB 0x%x Received PKT Status of 0x%x\n",
8963 SCB_GET_TAG(scb), siu->status);
8964 printk("\tflags = 0x%x, sense len = 0x%x, "
8965 "pktfail = 0x%x\n",
8966 siu->flags, scsi_4btoul(siu->sense_length),
8967 scsi_4btoul(siu->pkt_failures_length));
8968 }
8969#endif
8970 if ((siu->flags & SIU_RSPVALID) != 0) {
8971 ahd_print_path(ahd, scb);
8972 if (scsi_4btoul(siu->pkt_failures_length) < 4) {
8973 printk("Unable to parse pkt_failures\n");
8974 } else {
8975
8976 switch (SIU_PKTFAIL_CODE(siu)) {
8977 case SIU_PFC_NONE:
8978 printk("No packet failure found\n");
8979 break;
8980 case SIU_PFC_CIU_FIELDS_INVALID:
8981 printk("Invalid Command IU Field\n");
8982 break;
8983 case SIU_PFC_TMF_NOT_SUPPORTED:
8984 printk("TMF not supported\n");
8985 break;
8986 case SIU_PFC_TMF_FAILED:
8987 printk("TMF failed\n");
8988 break;
8989 case SIU_PFC_INVALID_TYPE_CODE:
8990 printk("Invalid L_Q Type code\n");
8991 break;
8992 case SIU_PFC_ILLEGAL_REQUEST:
8993 printk("Illegal request\n");
8994 default:
8995 break;
8996 }
8997 }
8998 if (siu->status == SCSI_STATUS_OK)
8999 ahd_set_transaction_status(scb,
9000 CAM_REQ_CMP_ERR);
9001 }
9002 if ((siu->flags & SIU_SNSVALID) != 0) {
9003 scb->flags |= SCB_PKT_SENSE;
9004#ifdef AHD_DEBUG
9005 if ((ahd_debug & AHD_SHOW_SENSE) != 0)
9006 printk("Sense data available\n");
9007#endif
9008 }
9009 ahd_done(ahd, scb);
9010 break;
9011 }
9012 case SCSI_STATUS_CMD_TERMINATED:
9013 case SCSI_STATUS_CHECK_COND:
9014 {
9015 struct ahd_devinfo devinfo;
9016 struct ahd_dma_seg *sg;
9017 struct scsi_sense *sc;
9018 struct ahd_initiator_tinfo *targ_info;
9019 struct ahd_tmode_tstate *tstate;
9020 struct ahd_transinfo *tinfo;
9021#ifdef AHD_DEBUG
9022 if (ahd_debug & AHD_SHOW_SENSE) {
9023 ahd_print_path(ahd, scb);
9024 printk("SCB %d: requests Check Status\n",
9025 SCB_GET_TAG(scb));
9026 }
9027#endif
9028
9029 if (ahd_perform_autosense(scb) == 0)
9030 break;
9031
9032 ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb),
9033 SCB_GET_TARGET(ahd, scb),
9034 SCB_GET_LUN(scb),
9035 SCB_GET_CHANNEL(ahd, scb),
9036 ROLE_INITIATOR);
9037 targ_info = ahd_fetch_transinfo(ahd,
9038 devinfo.channel,
9039 devinfo.our_scsiid,
9040 devinfo.target,
9041 &tstate);
9042 tinfo = &targ_info->curr;
9043 sg = scb->sg_list;
9044 sc = (struct scsi_sense *)hscb->shared_data.idata.cdb;
9045
9046
9047
9048 ahd_update_residual(ahd, scb);
9049#ifdef AHD_DEBUG
9050 if (ahd_debug & AHD_SHOW_SENSE) {
9051 ahd_print_path(ahd, scb);
9052 printk("Sending Sense\n");
9053 }
9054#endif
9055 scb->sg_count = 0;
9056 sg = ahd_sg_setup(ahd, scb, sg, ahd_get_sense_bufaddr(ahd, scb),
9057 ahd_get_sense_bufsize(ahd, scb),
9058 TRUE);
9059 sc->opcode = REQUEST_SENSE;
9060 sc->byte2 = 0;
9061 if (tinfo->protocol_version <= SCSI_REV_2
9062 && SCB_GET_LUN(scb) < 8)
9063 sc->byte2 = SCB_GET_LUN(scb) << 5;
9064 sc->unused[0] = 0;
9065 sc->unused[1] = 0;
9066 sc->length = ahd_get_sense_bufsize(ahd, scb);
9067 sc->control = 0;
9068
9069
9070
9071
9072
9073
9074
9075
9076 hscb->control = 0;
9077
9078
9079
9080
9081
9082
9083
9084
9085
9086 if (ahd_get_residual(scb) == ahd_get_transfer_length(scb)) {
9087 ahd_update_neg_request(ahd, &devinfo,
9088 tstate, targ_info,
9089 AHD_NEG_IF_NON_ASYNC);
9090 }
9091 if (tstate->auto_negotiate & devinfo.target_mask) {
9092 hscb->control |= MK_MESSAGE;
9093 scb->flags &=
9094 ~(SCB_NEGOTIATE|SCB_ABORT|SCB_DEVICE_RESET);
9095 scb->flags |= SCB_AUTO_NEGOTIATE;
9096 }
9097 hscb->cdb_len = sizeof(*sc);
9098 ahd_setup_data_scb(ahd, scb);
9099 scb->flags |= SCB_SENSE;
9100 ahd_queue_scb(ahd, scb);
9101 break;
9102 }
9103 case SCSI_STATUS_OK:
9104 printk("%s: Interrupted for status of 0???\n",
9105 ahd_name(ahd));
9106
9107 default:
9108 ahd_done(ahd, scb);
9109 break;
9110 }
9111}
9112
9113static void
9114ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb)
9115{
9116 if (scb->hscb->shared_data.istatus.scsi_status != 0) {
9117 ahd_handle_scsi_status(ahd, scb);
9118 } else {
9119 ahd_calc_residual(ahd, scb);
9120 ahd_done(ahd, scb);
9121 }
9122}
9123
9124
9125
9126
9127static void
9128ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb)
9129{
9130 struct hardware_scb *hscb;
9131 struct initiator_status *spkt;
9132 uint32_t sgptr;
9133 uint32_t resid_sgptr;
9134 uint32_t resid;
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152 hscb = scb->hscb;
9153 sgptr = ahd_le32toh(hscb->sgptr);
9154 if ((sgptr & SG_STATUS_VALID) == 0)
9155
9156 return;
9157 sgptr &= ~SG_STATUS_VALID;
9158
9159 if ((sgptr & SG_LIST_NULL) != 0)
9160
9161 return;
9162
9163
9164
9165
9166
9167
9168
9169 spkt = &hscb->shared_data.istatus;
9170 resid_sgptr = ahd_le32toh(spkt->residual_sgptr);
9171 if ((sgptr & SG_FULL_RESID) != 0) {
9172
9173 resid = ahd_get_transfer_length(scb);
9174 } else if ((resid_sgptr & SG_LIST_NULL) != 0) {
9175
9176 return;
9177 } else if ((resid_sgptr & SG_OVERRUN_RESID) != 0) {
9178 ahd_print_path(ahd, scb);
9179 printk("data overrun detected Tag == 0x%x.\n",
9180 SCB_GET_TAG(scb));
9181 ahd_freeze_devq(ahd, scb);
9182 ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
9183 ahd_freeze_scb(scb);
9184 return;
9185 } else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {
9186 panic("Bogus resid sgptr value 0x%x\n", resid_sgptr);
9187
9188 } else {
9189 struct ahd_dma_seg *sg;
9190
9191
9192
9193
9194
9195 resid = ahd_le32toh(spkt->residual_datacnt) & AHD_SG_LEN_MASK;
9196 sg = ahd_sg_bus_to_virt(ahd, scb, resid_sgptr & SG_PTR_MASK);
9197
9198
9199 sg--;
9200
9201
9202
9203
9204
9205
9206 while ((ahd_le32toh(sg->len) & AHD_DMA_LAST_SEG) == 0) {
9207 sg++;
9208 resid += ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
9209 }
9210 }
9211 if ((scb->flags & SCB_SENSE) == 0)
9212 ahd_set_residual(scb, resid);
9213 else
9214 ahd_set_sense_residual(scb, resid);
9215
9216#ifdef AHD_DEBUG
9217 if ((ahd_debug & AHD_SHOW_MISC) != 0) {
9218 ahd_print_path(ahd, scb);
9219 printk("Handled %sResidual of %d bytes\n",
9220 (scb->flags & SCB_SENSE) ? "Sense " : "", resid);
9221 }
9222#endif
9223}
9224
9225
9226#ifdef AHD_TARGET_MODE
9227
9228
9229
9230static void
9231ahd_queue_lstate_event(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate,
9232 u_int initiator_id, u_int event_type, u_int event_arg)
9233{
9234 struct ahd_tmode_event *event;
9235 int pending;
9236
9237 xpt_freeze_devq(lstate->path, 1);
9238 if (lstate->event_w_idx >= lstate->event_r_idx)
9239 pending = lstate->event_w_idx - lstate->event_r_idx;
9240 else
9241 pending = AHD_TMODE_EVENT_BUFFER_SIZE + 1
9242 - (lstate->event_r_idx - lstate->event_w_idx);
9243
9244 if (event_type == EVENT_TYPE_BUS_RESET
9245 || event_type == MSG_BUS_DEV_RESET) {
9246
9247
9248
9249
9250
9251
9252 lstate->event_r_idx = 0;
9253 lstate->event_w_idx = 0;
9254 xpt_release_devq(lstate->path, pending, FALSE);
9255 }
9256
9257 if (pending == AHD_TMODE_EVENT_BUFFER_SIZE) {
9258 xpt_print_path(lstate->path);
9259 printk("immediate event %x:%x lost\n",
9260 lstate->event_buffer[lstate->event_r_idx].event_type,
9261 lstate->event_buffer[lstate->event_r_idx].event_arg);
9262 lstate->event_r_idx++;
9263 if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
9264 lstate->event_r_idx = 0;
9265 xpt_release_devq(lstate->path, 1, FALSE);
9266 }
9267
9268 event = &lstate->event_buffer[lstate->event_w_idx];
9269 event->initiator_id = initiator_id;
9270 event->event_type = event_type;
9271 event->event_arg = event_arg;
9272 lstate->event_w_idx++;
9273 if (lstate->event_w_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
9274 lstate->event_w_idx = 0;
9275}
9276
9277
9278
9279
9280
9281void
9282ahd_send_lstate_events(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate)
9283{
9284 struct ccb_hdr *ccbh;
9285 struct ccb_immed_notify *inot;
9286
9287 while (lstate->event_r_idx != lstate->event_w_idx
9288 && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) {
9289 struct ahd_tmode_event *event;
9290
9291 event = &lstate->event_buffer[lstate->event_r_idx];
9292 SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);
9293 inot = (struct ccb_immed_notify *)ccbh;
9294 switch (event->event_type) {
9295 case EVENT_TYPE_BUS_RESET:
9296 ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN;
9297 break;
9298 default:
9299 ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN;
9300 inot->message_args[0] = event->event_type;
9301 inot->message_args[1] = event->event_arg;
9302 break;
9303 }
9304 inot->initiator_id = event->initiator_id;
9305 inot->sense_len = 0;
9306 xpt_done((union ccb *)inot);
9307 lstate->event_r_idx++;
9308 if (lstate->event_r_idx == AHD_TMODE_EVENT_BUFFER_SIZE)
9309 lstate->event_r_idx = 0;
9310 }
9311}
9312#endif
9313
9314
9315
9316#ifdef AHD_DUMP_SEQ
9317void
9318ahd_dumpseq(struct ahd_softc* ahd)
9319{
9320 int i;
9321 int max_prog;
9322
9323 max_prog = 2048;
9324
9325 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
9326 ahd_outw(ahd, PRGMCNT, 0);
9327 for (i = 0; i < max_prog; i++) {
9328 uint8_t ins_bytes[4];
9329
9330 ahd_insb(ahd, SEQRAM, ins_bytes, 4);
9331 printk("0x%08x\n", ins_bytes[0] << 24
9332 | ins_bytes[1] << 16
9333 | ins_bytes[2] << 8
9334 | ins_bytes[3]);
9335 }
9336}
9337#endif
9338
9339static void
9340ahd_loadseq(struct ahd_softc *ahd)
9341{
9342 struct cs cs_table[NUM_CRITICAL_SECTIONS];
9343 u_int begin_set[NUM_CRITICAL_SECTIONS];
9344 u_int end_set[NUM_CRITICAL_SECTIONS];
9345 const struct patch *cur_patch;
9346 u_int cs_count;
9347 u_int cur_cs;
9348 u_int i;
9349 int downloaded;
9350 u_int skip_addr;
9351 u_int sg_prefetch_cnt;
9352 u_int sg_prefetch_cnt_limit;
9353 u_int sg_prefetch_align;
9354 u_int sg_size;
9355 u_int cacheline_mask;
9356 uint8_t download_consts[DOWNLOAD_CONST_COUNT];
9357
9358 if (bootverbose)
9359 printk("%s: Downloading Sequencer Program...",
9360 ahd_name(ahd));
9361
9362#if DOWNLOAD_CONST_COUNT != 8
9363#error "Download Const Mismatch"
9364#endif
9365
9366
9367
9368
9369 cs_count = 0;
9370 cur_cs = 0;
9371 memset(begin_set, 0, sizeof(begin_set));
9372 memset(end_set, 0, sizeof(end_set));
9373
9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392 sg_prefetch_align = ahd->pci_cachesize;
9393 if (sg_prefetch_align == 0)
9394 sg_prefetch_align = 8;
9395
9396 while (powerof2(sg_prefetch_align) == 0)
9397 sg_prefetch_align--;
9398
9399 cacheline_mask = sg_prefetch_align - 1;
9400
9401
9402
9403
9404
9405
9406 if (sg_prefetch_align > CCSGADDR_MAX/2)
9407 sg_prefetch_align = CCSGADDR_MAX/2;
9408
9409 sg_prefetch_cnt = sg_prefetch_align;
9410
9411
9412
9413
9414 sg_size = sizeof(struct ahd_dma_seg);
9415 if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
9416 sg_size = sizeof(struct ahd_dma64_seg);
9417 while (sg_prefetch_cnt < sg_size)
9418 sg_prefetch_cnt += sg_prefetch_align;
9419
9420
9421
9422
9423
9424 if ((sg_prefetch_align % sg_size) != 0
9425 && (sg_prefetch_cnt < CCSGADDR_MAX))
9426 sg_prefetch_cnt += sg_prefetch_align;
9427
9428
9429
9430
9431
9432 sg_prefetch_cnt_limit = -(sg_prefetch_cnt - sg_size + 1);
9433 download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt;
9434 download_consts[SG_PREFETCH_CNT_LIMIT] = sg_prefetch_cnt_limit;
9435 download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_align - 1);
9436 download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_align - 1);
9437 download_consts[SG_SIZEOF] = sg_size;
9438 download_consts[PKT_OVERRUN_BUFOFFSET] =
9439 (ahd->overrun_buf - (uint8_t *)ahd->qoutfifo) / 256;
9440 download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_1BYTE_LUN;
9441 download_consts[CACHELINE_MASK] = cacheline_mask;
9442 cur_patch = patches;
9443 downloaded = 0;
9444 skip_addr = 0;
9445 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
9446 ahd_outw(ahd, PRGMCNT, 0);
9447
9448 for (i = 0; i < sizeof(seqprog)/4; i++) {
9449 if (ahd_check_patch(ahd, &cur_patch, i, &skip_addr) == 0) {
9450
9451
9452
9453
9454 continue;
9455 }
9456
9457
9458
9459
9460 for (; cur_cs < NUM_CRITICAL_SECTIONS; cur_cs++) {
9461 if (critical_sections[cur_cs].end <= i) {
9462 if (begin_set[cs_count] == TRUE
9463 && end_set[cs_count] == FALSE) {
9464 cs_table[cs_count].end = downloaded;
9465 end_set[cs_count] = TRUE;
9466 cs_count++;
9467 }
9468 continue;
9469 }
9470 if (critical_sections[cur_cs].begin <= i
9471 && begin_set[cs_count] == FALSE) {
9472 cs_table[cs_count].begin = downloaded;
9473 begin_set[cs_count] = TRUE;
9474 }
9475 break;
9476 }
9477 ahd_download_instr(ahd, i, download_consts);
9478 downloaded++;
9479 }
9480
9481 ahd->num_critical_sections = cs_count;
9482 if (cs_count != 0) {
9483
9484 cs_count *= sizeof(struct cs);
9485 ahd->critical_sections = kmalloc(cs_count, GFP_ATOMIC);
9486 if (ahd->critical_sections == NULL)
9487 panic("ahd_loadseq: Could not malloc");
9488 memcpy(ahd->critical_sections, cs_table, cs_count);
9489 }
9490 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE);
9491
9492 if (bootverbose) {
9493 printk(" %d instructions downloaded\n", downloaded);
9494 printk("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
9495 ahd_name(ahd), ahd->features, ahd->bugs, ahd->flags);
9496 }
9497}
9498
9499static int
9500ahd_check_patch(struct ahd_softc *ahd, const struct patch **start_patch,
9501 u_int start_instr, u_int *skip_addr)
9502{
9503 const struct patch *cur_patch;
9504 const struct patch *last_patch;
9505 u_int num_patches;
9506
9507 num_patches = ARRAY_SIZE(patches);
9508 last_patch = &patches[num_patches];
9509 cur_patch = *start_patch;
9510
9511 while (cur_patch < last_patch && start_instr == cur_patch->begin) {
9512
9513 if (cur_patch->patch_func(ahd) == 0) {
9514
9515
9516 *skip_addr = start_instr + cur_patch->skip_instr;
9517 cur_patch += cur_patch->skip_patch;
9518 } else {
9519
9520
9521
9522
9523 cur_patch++;
9524 }
9525 }
9526
9527 *start_patch = cur_patch;
9528 if (start_instr < *skip_addr)
9529
9530 return (0);
9531
9532 return (1);
9533}
9534
9535static u_int
9536ahd_resolve_seqaddr(struct ahd_softc *ahd, u_int address)
9537{
9538 const struct patch *cur_patch;
9539 int address_offset;
9540 u_int skip_addr;
9541 u_int i;
9542
9543 address_offset = 0;
9544 cur_patch = patches;
9545 skip_addr = 0;
9546
9547 for (i = 0; i < address;) {
9548
9549 ahd_check_patch(ahd, &cur_patch, i, &skip_addr);
9550
9551 if (skip_addr > i) {
9552 int end_addr;
9553
9554 end_addr = min(address, skip_addr);
9555 address_offset += end_addr - i;
9556 i = skip_addr;
9557 } else {
9558 i++;
9559 }
9560 }
9561 return (address - address_offset);
9562}
9563
9564static void
9565ahd_download_instr(struct ahd_softc *ahd, u_int instrptr, uint8_t *dconsts)
9566{
9567 union ins_formats instr;
9568 struct ins_format1 *fmt1_ins;
9569 struct ins_format3 *fmt3_ins;
9570 u_int opcode;
9571
9572
9573
9574
9575 instr.integer = ahd_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);
9576
9577 fmt1_ins = &instr.format1;
9578 fmt3_ins = NULL;
9579
9580
9581 opcode = instr.format1.opcode;
9582 switch (opcode) {
9583 case AIC_OP_JMP:
9584 case AIC_OP_JC:
9585 case AIC_OP_JNC:
9586 case AIC_OP_CALL:
9587 case AIC_OP_JNE:
9588 case AIC_OP_JNZ:
9589 case AIC_OP_JE:
9590 case AIC_OP_JZ:
9591 {
9592 fmt3_ins = &instr.format3;
9593 fmt3_ins->address = ahd_resolve_seqaddr(ahd, fmt3_ins->address);
9594
9595 }
9596 case AIC_OP_OR:
9597 case AIC_OP_AND:
9598 case AIC_OP_XOR:
9599 case AIC_OP_ADD:
9600 case AIC_OP_ADC:
9601 case AIC_OP_BMOV:
9602 if (fmt1_ins->parity != 0) {
9603 fmt1_ins->immediate = dconsts[fmt1_ins->immediate];
9604 }
9605 fmt1_ins->parity = 0;
9606
9607 case AIC_OP_ROL:
9608 {
9609 int i, count;
9610
9611
9612 for (i = 0, count = 0; i < 31; i++) {
9613 uint32_t mask;
9614
9615 mask = 0x01 << i;
9616 if ((instr.integer & mask) != 0)
9617 count++;
9618 }
9619 if ((count & 0x01) == 0)
9620 instr.format1.parity = 1;
9621
9622
9623 instr.integer = ahd_htole32(instr.integer);
9624 ahd_outsb(ahd, SEQRAM, instr.bytes, 4);
9625 break;
9626 }
9627 default:
9628 panic("Unknown opcode encountered in seq program");
9629 break;
9630 }
9631}
9632
9633static int
9634ahd_probe_stack_size(struct ahd_softc *ahd)
9635{
9636 int last_probe;
9637
9638 last_probe = 0;
9639 while (1) {
9640 int i;
9641
9642
9643
9644
9645
9646
9647
9648 for (i = 1; i <= last_probe+1; i++) {
9649 ahd_outb(ahd, STACK, i & 0xFF);
9650 ahd_outb(ahd, STACK, (i >> 8) & 0xFF);
9651 }
9652
9653
9654 for (i = last_probe+1; i > 0; i--) {
9655 u_int stack_entry;
9656
9657 stack_entry = ahd_inb(ahd, STACK)
9658 |(ahd_inb(ahd, STACK) << 8);
9659 if (stack_entry != i)
9660 goto sized;
9661 }
9662 last_probe++;
9663 }
9664sized:
9665 return (last_probe);
9666}
9667
9668int
9669ahd_print_register(const ahd_reg_parse_entry_t *table, u_int num_entries,
9670 const char *name, u_int address, u_int value,
9671 u_int *cur_column, u_int wrap_point)
9672{
9673 int printed;
9674 u_int printed_mask;
9675
9676 if (cur_column != NULL && *cur_column >= wrap_point) {
9677 printk("\n");
9678 *cur_column = 0;
9679 }
9680 printed = printk("%s[0x%x]", name, value);
9681 if (table == NULL) {
9682 printed += printk(" ");
9683 *cur_column += printed;
9684 return (printed);
9685 }
9686 printed_mask = 0;
9687 while (printed_mask != 0xFF) {
9688 int entry;
9689
9690 for (entry = 0; entry < num_entries; entry++) {
9691 if (((value & table[entry].mask)
9692 != table[entry].value)
9693 || ((printed_mask & table[entry].mask)
9694 == table[entry].mask))
9695 continue;
9696
9697 printed += printk("%s%s",
9698 printed_mask == 0 ? ":(" : "|",
9699 table[entry].name);
9700 printed_mask |= table[entry].mask;
9701
9702 break;
9703 }
9704 if (entry >= num_entries)
9705 break;
9706 }
9707 if (printed_mask != 0)
9708 printed += printk(") ");
9709 else
9710 printed += printk(" ");
9711 if (cur_column != NULL)
9712 *cur_column += printed;
9713 return (printed);
9714}
9715
9716void
9717ahd_dump_card_state(struct ahd_softc *ahd)
9718{
9719 struct scb *scb;
9720 ahd_mode_state saved_modes;
9721 u_int dffstat;
9722 int paused;
9723 u_int scb_index;
9724 u_int saved_scb_index;
9725 u_int cur_col;
9726 int i;
9727
9728 if (ahd_is_paused(ahd)) {
9729 paused = 1;
9730 } else {
9731 paused = 0;
9732 ahd_pause(ahd);
9733 }
9734 saved_modes = ahd_save_modes(ahd);
9735 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
9736 printk(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
9737 "%s: Dumping Card State at program address 0x%x Mode 0x%x\n",
9738 ahd_name(ahd),
9739 ahd_inw(ahd, CURADDR),
9740 ahd_build_mode_state(ahd, ahd->saved_src_mode,
9741 ahd->saved_dst_mode));
9742 if (paused)
9743 printk("Card was paused\n");
9744
9745 if (ahd_check_cmdcmpltqueues(ahd))
9746 printk("Completions are pending\n");
9747
9748
9749
9750
9751 cur_col = 0;
9752 ahd_intstat_print(ahd_inb(ahd, INTSTAT), &cur_col, 50);
9753 ahd_seloid_print(ahd_inb(ahd, SELOID), &cur_col, 50);
9754 ahd_selid_print(ahd_inb(ahd, SELID), &cur_col, 50);
9755 ahd_hs_mailbox_print(ahd_inb(ahd, LOCAL_HS_MAILBOX), &cur_col, 50);
9756 ahd_intctl_print(ahd_inb(ahd, INTCTL), &cur_col, 50);
9757 ahd_seqintstat_print(ahd_inb(ahd, SEQINTSTAT), &cur_col, 50);
9758 ahd_saved_mode_print(ahd_inb(ahd, SAVED_MODE), &cur_col, 50);
9759 ahd_dffstat_print(ahd_inb(ahd, DFFSTAT), &cur_col, 50);
9760 ahd_scsisigi_print(ahd_inb(ahd, SCSISIGI), &cur_col, 50);
9761 ahd_scsiphase_print(ahd_inb(ahd, SCSIPHASE), &cur_col, 50);
9762 ahd_scsibus_print(ahd_inb(ahd, SCSIBUS), &cur_col, 50);
9763 ahd_lastphase_print(ahd_inb(ahd, LASTPHASE), &cur_col, 50);
9764 ahd_scsiseq0_print(ahd_inb(ahd, SCSISEQ0), &cur_col, 50);
9765 ahd_scsiseq1_print(ahd_inb(ahd, SCSISEQ1), &cur_col, 50);
9766 ahd_seqctl0_print(ahd_inb(ahd, SEQCTL0), &cur_col, 50);
9767 ahd_seqintctl_print(ahd_inb(ahd, SEQINTCTL), &cur_col, 50);
9768 ahd_seq_flags_print(ahd_inb(ahd, SEQ_FLAGS), &cur_col, 50);
9769 ahd_seq_flags2_print(ahd_inb(ahd, SEQ_FLAGS2), &cur_col, 50);
9770 ahd_qfreeze_count_print(ahd_inw(ahd, QFREEZE_COUNT), &cur_col, 50);
9771 ahd_kernel_qfreeze_count_print(ahd_inw(ahd, KERNEL_QFREEZE_COUNT),
9772 &cur_col, 50);
9773 ahd_mk_message_scb_print(ahd_inw(ahd, MK_MESSAGE_SCB), &cur_col, 50);
9774 ahd_mk_message_scsiid_print(ahd_inb(ahd, MK_MESSAGE_SCSIID),
9775 &cur_col, 50);
9776 ahd_sstat0_print(ahd_inb(ahd, SSTAT0), &cur_col, 50);
9777 ahd_sstat1_print(ahd_inb(ahd, SSTAT1), &cur_col, 50);
9778 ahd_sstat2_print(ahd_inb(ahd, SSTAT2), &cur_col, 50);
9779 ahd_sstat3_print(ahd_inb(ahd, SSTAT3), &cur_col, 50);
9780 ahd_perrdiag_print(ahd_inb(ahd, PERRDIAG), &cur_col, 50);
9781 ahd_simode1_print(ahd_inb(ahd, SIMODE1), &cur_col, 50);
9782 ahd_lqistat0_print(ahd_inb(ahd, LQISTAT0), &cur_col, 50);
9783 ahd_lqistat1_print(ahd_inb(ahd, LQISTAT1), &cur_col, 50);
9784 ahd_lqistat2_print(ahd_inb(ahd, LQISTAT2), &cur_col, 50);
9785 ahd_lqostat0_print(ahd_inb(ahd, LQOSTAT0), &cur_col, 50);
9786 ahd_lqostat1_print(ahd_inb(ahd, LQOSTAT1), &cur_col, 50);
9787 ahd_lqostat2_print(ahd_inb(ahd, LQOSTAT2), &cur_col, 50);
9788 printk("\n");
9789 printk("\nSCB Count = %d CMDS_PENDING = %d LASTSCB 0x%x "
9790 "CURRSCB 0x%x NEXTSCB 0x%x\n",
9791 ahd->scb_data.numscbs, ahd_inw(ahd, CMDS_PENDING),
9792 ahd_inw(ahd, LASTSCB), ahd_inw(ahd, CURRSCB),
9793 ahd_inw(ahd, NEXTSCB));
9794 cur_col = 0;
9795
9796 ahd_search_qinfifo(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
9797 CAM_LUN_WILDCARD, SCB_LIST_NULL,
9798 ROLE_UNKNOWN, 0, SEARCH_PRINT);
9799 saved_scb_index = ahd_get_scbptr(ahd);
9800 printk("Pending list:");
9801 i = 0;
9802 LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
9803 if (i++ > AHD_SCB_MAX)
9804 break;
9805 cur_col = printk("\n%3d FIFO_USE[0x%x] ", SCB_GET_TAG(scb),
9806 ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT));
9807 ahd_set_scbptr(ahd, SCB_GET_TAG(scb));
9808 ahd_scb_control_print(ahd_inb_scbram(ahd, SCB_CONTROL),
9809 &cur_col, 60);
9810 ahd_scb_scsiid_print(ahd_inb_scbram(ahd, SCB_SCSIID),
9811 &cur_col, 60);
9812 }
9813 printk("\nTotal %d\n", i);
9814
9815 printk("Kernel Free SCB list: ");
9816 i = 0;
9817 TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
9818 struct scb *list_scb;
9819
9820 list_scb = scb;
9821 do {
9822 printk("%d ", SCB_GET_TAG(list_scb));
9823 list_scb = LIST_NEXT(list_scb, collision_links);
9824 } while (list_scb && i++ < AHD_SCB_MAX);
9825 }
9826
9827 LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) {
9828 if (i++ > AHD_SCB_MAX)
9829 break;
9830 printk("%d ", SCB_GET_TAG(scb));
9831 }
9832 printk("\n");
9833
9834 printk("Sequencer Complete DMA-inprog list: ");
9835 scb_index = ahd_inw(ahd, COMPLETE_SCB_DMAINPROG_HEAD);
9836 i = 0;
9837 while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
9838 ahd_set_scbptr(ahd, scb_index);
9839 printk("%d ", scb_index);
9840 scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
9841 }
9842 printk("\n");
9843
9844 printk("Sequencer Complete list: ");
9845 scb_index = ahd_inw(ahd, COMPLETE_SCB_HEAD);
9846 i = 0;
9847 while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
9848 ahd_set_scbptr(ahd, scb_index);
9849 printk("%d ", scb_index);
9850 scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
9851 }
9852 printk("\n");
9853
9854
9855 printk("Sequencer DMA-Up and Complete list: ");
9856 scb_index = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
9857 i = 0;
9858 while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
9859 ahd_set_scbptr(ahd, scb_index);
9860 printk("%d ", scb_index);
9861 scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
9862 }
9863 printk("\n");
9864 printk("Sequencer On QFreeze and Complete list: ");
9865 scb_index = ahd_inw(ahd, COMPLETE_ON_QFREEZE_HEAD);
9866 i = 0;
9867 while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
9868 ahd_set_scbptr(ahd, scb_index);
9869 printk("%d ", scb_index);
9870 scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
9871 }
9872 printk("\n");
9873 ahd_set_scbptr(ahd, saved_scb_index);
9874 dffstat = ahd_inb(ahd, DFFSTAT);
9875 for (i = 0; i < 2; i++) {
9876#ifdef AHD_DEBUG
9877 struct scb *fifo_scb;
9878#endif
9879 u_int fifo_scbptr;
9880
9881 ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i);
9882 fifo_scbptr = ahd_get_scbptr(ahd);
9883 printk("\n\n%s: FIFO%d %s, LONGJMP == 0x%x, SCB 0x%x\n",
9884 ahd_name(ahd), i,
9885 (dffstat & (FIFO0FREE << i)) ? "Free" : "Active",
9886 ahd_inw(ahd, LONGJMP_ADDR), fifo_scbptr);
9887 cur_col = 0;
9888 ahd_seqimode_print(ahd_inb(ahd, SEQIMODE), &cur_col, 50);
9889 ahd_seqintsrc_print(ahd_inb(ahd, SEQINTSRC), &cur_col, 50);
9890 ahd_dfcntrl_print(ahd_inb(ahd, DFCNTRL), &cur_col, 50);
9891 ahd_dfstatus_print(ahd_inb(ahd, DFSTATUS), &cur_col, 50);
9892 ahd_sg_cache_shadow_print(ahd_inb(ahd, SG_CACHE_SHADOW),
9893 &cur_col, 50);
9894 ahd_sg_state_print(ahd_inb(ahd, SG_STATE), &cur_col, 50);
9895 ahd_dffsxfrctl_print(ahd_inb(ahd, DFFSXFRCTL), &cur_col, 50);
9896 ahd_soffcnt_print(ahd_inb(ahd, SOFFCNT), &cur_col, 50);
9897 ahd_mdffstat_print(ahd_inb(ahd, MDFFSTAT), &cur_col, 50);
9898 if (cur_col > 50) {
9899 printk("\n");
9900 cur_col = 0;
9901 }
9902 cur_col += printk("SHADDR = 0x%x%x, SHCNT = 0x%x ",
9903 ahd_inl(ahd, SHADDR+4),
9904 ahd_inl(ahd, SHADDR),
9905 (ahd_inb(ahd, SHCNT)
9906 | (ahd_inb(ahd, SHCNT + 1) << 8)
9907 | (ahd_inb(ahd, SHCNT + 2) << 16)));
9908 if (cur_col > 50) {
9909 printk("\n");
9910 cur_col = 0;
9911 }
9912 cur_col += printk("HADDR = 0x%x%x, HCNT = 0x%x ",
9913 ahd_inl(ahd, HADDR+4),
9914 ahd_inl(ahd, HADDR),
9915 (ahd_inb(ahd, HCNT)
9916 | (ahd_inb(ahd, HCNT + 1) << 8)
9917 | (ahd_inb(ahd, HCNT + 2) << 16)));
9918 ahd_ccsgctl_print(ahd_inb(ahd, CCSGCTL), &cur_col, 50);
9919#ifdef AHD_DEBUG
9920 if ((ahd_debug & AHD_SHOW_SG) != 0) {
9921 fifo_scb = ahd_lookup_scb(ahd, fifo_scbptr);
9922 if (fifo_scb != NULL)
9923 ahd_dump_sglist(fifo_scb);
9924 }
9925#endif
9926 }
9927 printk("\nLQIN: ");
9928 for (i = 0; i < 20; i++)
9929 printk("0x%x ", ahd_inb(ahd, LQIN + i));
9930 printk("\n");
9931 ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
9932 printk("%s: LQISTATE = 0x%x, LQOSTATE = 0x%x, OPTIONMODE = 0x%x\n",
9933 ahd_name(ahd), ahd_inb(ahd, LQISTATE), ahd_inb(ahd, LQOSTATE),
9934 ahd_inb(ahd, OPTIONMODE));
9935 printk("%s: OS_SPACE_CNT = 0x%x MAXCMDCNT = 0x%x\n",
9936 ahd_name(ahd), ahd_inb(ahd, OS_SPACE_CNT),
9937 ahd_inb(ahd, MAXCMDCNT));
9938 printk("%s: SAVED_SCSIID = 0x%x SAVED_LUN = 0x%x\n",
9939 ahd_name(ahd), ahd_inb(ahd, SAVED_SCSIID),
9940 ahd_inb(ahd, SAVED_LUN));
9941 ahd_simode0_print(ahd_inb(ahd, SIMODE0), &cur_col, 50);
9942 printk("\n");
9943 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
9944 cur_col = 0;
9945 ahd_ccscbctl_print(ahd_inb(ahd, CCSCBCTL), &cur_col, 50);
9946 printk("\n");
9947 ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
9948 printk("%s: REG0 == 0x%x, SINDEX = 0x%x, DINDEX = 0x%x\n",
9949 ahd_name(ahd), ahd_inw(ahd, REG0), ahd_inw(ahd, SINDEX),
9950 ahd_inw(ahd, DINDEX));
9951 printk("%s: SCBPTR == 0x%x, SCB_NEXT == 0x%x, SCB_NEXT2 == 0x%x\n",
9952 ahd_name(ahd), ahd_get_scbptr(ahd),
9953 ahd_inw_scbram(ahd, SCB_NEXT),
9954 ahd_inw_scbram(ahd, SCB_NEXT2));
9955 printk("CDB %x %x %x %x %x %x\n",
9956 ahd_inb_scbram(ahd, SCB_CDB_STORE),
9957 ahd_inb_scbram(ahd, SCB_CDB_STORE+1),
9958 ahd_inb_scbram(ahd, SCB_CDB_STORE+2),
9959 ahd_inb_scbram(ahd, SCB_CDB_STORE+3),
9960 ahd_inb_scbram(ahd, SCB_CDB_STORE+4),
9961 ahd_inb_scbram(ahd, SCB_CDB_STORE+5));
9962 printk("STACK:");
9963 for (i = 0; i < ahd->stack_size; i++) {
9964 ahd->saved_stack[i] =
9965 ahd_inb(ahd, STACK)|(ahd_inb(ahd, STACK) << 8);
9966 printk(" 0x%x", ahd->saved_stack[i]);
9967 }
9968 for (i = ahd->stack_size-1; i >= 0; i--) {
9969 ahd_outb(ahd, STACK, ahd->saved_stack[i] & 0xFF);
9970 ahd_outb(ahd, STACK, (ahd->saved_stack[i] >> 8) & 0xFF);
9971 }
9972 printk("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");
9973 ahd_restore_modes(ahd, saved_modes);
9974 if (paused == 0)
9975 ahd_unpause(ahd);
9976}
9977
9978#if 0
9979void
9980ahd_dump_scbs(struct ahd_softc *ahd)
9981{
9982 ahd_mode_state saved_modes;
9983 u_int saved_scb_index;
9984 int i;
9985
9986 saved_modes = ahd_save_modes(ahd);
9987 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
9988 saved_scb_index = ahd_get_scbptr(ahd);
9989 for (i = 0; i < AHD_SCB_MAX; i++) {
9990 ahd_set_scbptr(ahd, i);
9991 printk("%3d", i);
9992 printk("(CTRL 0x%x ID 0x%x N 0x%x N2 0x%x SG 0x%x, RSG 0x%x)\n",
9993 ahd_inb_scbram(ahd, SCB_CONTROL),
9994 ahd_inb_scbram(ahd, SCB_SCSIID),
9995 ahd_inw_scbram(ahd, SCB_NEXT),
9996 ahd_inw_scbram(ahd, SCB_NEXT2),
9997 ahd_inl_scbram(ahd, SCB_SGPTR),
9998 ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR));
9999 }
10000 printk("\n");
10001 ahd_set_scbptr(ahd, saved_scb_index);
10002 ahd_restore_modes(ahd, saved_modes);
10003}
10004#endif
10005
10006
10007
10008
10009
10010
10011
10012
10013int
10014ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf,
10015 u_int start_addr, u_int count, int bytestream)
10016{
10017 u_int cur_addr;
10018 u_int end_addr;
10019 int error;
10020
10021
10022
10023
10024
10025 error = EINVAL;
10026 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
10027 end_addr = start_addr + count;
10028 for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) {
10029
10030 ahd_outb(ahd, SEEADR, cur_addr);
10031 ahd_outb(ahd, SEECTL, SEEOP_READ | SEESTART);
10032
10033 error = ahd_wait_seeprom(ahd);
10034 if (error)
10035 break;
10036 if (bytestream != 0) {
10037 uint8_t *bytestream_ptr;
10038
10039 bytestream_ptr = (uint8_t *)buf;
10040 *bytestream_ptr++ = ahd_inb(ahd, SEEDAT);
10041 *bytestream_ptr = ahd_inb(ahd, SEEDAT+1);
10042 } else {
10043
10044
10045
10046 *buf = ahd_inw(ahd, SEEDAT);
10047 }
10048 buf++;
10049 }
10050 return (error);
10051}
10052
10053
10054
10055
10056
10057
10058int
10059ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf,
10060 u_int start_addr, u_int count)
10061{
10062 u_int cur_addr;
10063 u_int end_addr;
10064 int error;
10065 int retval;
10066
10067 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
10068 error = ENOENT;
10069
10070
10071 ahd_outb(ahd, SEEADR, SEEOP_EWEN_ADDR);
10072 ahd_outb(ahd, SEECTL, SEEOP_EWEN | SEESTART);
10073 error = ahd_wait_seeprom(ahd);
10074 if (error)
10075 return (error);
10076
10077
10078
10079
10080
10081 retval = EINVAL;
10082 end_addr = start_addr + count;
10083 for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) {
10084 ahd_outw(ahd, SEEDAT, *buf++);
10085 ahd_outb(ahd, SEEADR, cur_addr);
10086 ahd_outb(ahd, SEECTL, SEEOP_WRITE | SEESTART);
10087
10088 retval = ahd_wait_seeprom(ahd);
10089 if (retval)
10090 break;
10091 }
10092
10093
10094
10095
10096 ahd_outb(ahd, SEEADR, SEEOP_EWDS_ADDR);
10097 ahd_outb(ahd, SEECTL, SEEOP_EWDS | SEESTART);
10098 error = ahd_wait_seeprom(ahd);
10099 if (error)
10100 return (error);
10101 return (retval);
10102}
10103
10104
10105
10106
10107static int
10108ahd_wait_seeprom(struct ahd_softc *ahd)
10109{
10110 int cnt;
10111
10112 cnt = 5000;
10113 while ((ahd_inb(ahd, SEESTAT) & (SEEARBACK|SEEBUSY)) != 0 && --cnt)
10114 ahd_delay(5);
10115
10116 if (cnt == 0)
10117 return (ETIMEDOUT);
10118 return (0);
10119}
10120
10121
10122
10123
10124
10125static int
10126ahd_verify_vpd_cksum(struct vpd_config *vpd)
10127{
10128 int i;
10129 int maxaddr;
10130 uint32_t checksum;
10131 uint8_t *vpdarray;
10132
10133 vpdarray = (uint8_t *)vpd;
10134 maxaddr = offsetof(struct vpd_config, vpd_checksum);
10135 checksum = 0;
10136 for (i = offsetof(struct vpd_config, resource_type); i < maxaddr; i++)
10137 checksum = checksum + vpdarray[i];
10138 if (checksum == 0
10139 || (-checksum & 0xFF) != vpd->vpd_checksum)
10140 return (0);
10141
10142 checksum = 0;
10143 maxaddr = offsetof(struct vpd_config, checksum);
10144 for (i = offsetof(struct vpd_config, default_target_flags);
10145 i < maxaddr; i++)
10146 checksum = checksum + vpdarray[i];
10147 if (checksum == 0
10148 || (-checksum & 0xFF) != vpd->checksum)
10149 return (0);
10150 return (1);
10151}
10152
10153int
10154ahd_verify_cksum(struct seeprom_config *sc)
10155{
10156 int i;
10157 int maxaddr;
10158 uint32_t checksum;
10159 uint16_t *scarray;
10160
10161 maxaddr = (sizeof(*sc)/2) - 1;
10162 checksum = 0;
10163 scarray = (uint16_t *)sc;
10164
10165 for (i = 0; i < maxaddr; i++)
10166 checksum = checksum + scarray[i];
10167 if (checksum == 0
10168 || (checksum & 0xFFFF) != sc->checksum) {
10169 return (0);
10170 } else {
10171 return (1);
10172 }
10173}
10174
10175int
10176ahd_acquire_seeprom(struct ahd_softc *ahd)
10177{
10178
10179
10180
10181
10182
10183
10184
10185 return (1);
10186#if 0
10187 uint8_t seetype;
10188 int error;
10189
10190 error = ahd_read_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, &seetype);
10191 if (error != 0
10192 || ((seetype & FLX_ROMSTAT_SEECFG) == FLX_ROMSTAT_SEE_NONE))
10193 return (0);
10194 return (1);
10195#endif
10196}
10197
10198void
10199ahd_release_seeprom(struct ahd_softc *ahd)
10200{
10201
10202}
10203
10204
10205
10206
10207static int
10208ahd_wait_flexport(struct ahd_softc *ahd)
10209{
10210 int cnt;
10211
10212 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
10213 cnt = 1000000 * 2 / 5;
10214 while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt)
10215 ahd_delay(5);
10216
10217 if (cnt == 0)
10218 return (ETIMEDOUT);
10219 return (0);
10220}
10221
10222int
10223ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value)
10224{
10225 int error;
10226
10227 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
10228 if (addr > 7)
10229 panic("ahd_write_flexport: address out of range");
10230 ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3));
10231 error = ahd_wait_flexport(ahd);
10232 if (error != 0)
10233 return (error);
10234 ahd_outb(ahd, BRDDAT, value);
10235 ahd_flush_device_writes(ahd);
10236 ahd_outb(ahd, BRDCTL, BRDSTB|BRDEN|(addr << 3));
10237 ahd_flush_device_writes(ahd);
10238 ahd_outb(ahd, BRDCTL, BRDEN|(addr << 3));
10239 ahd_flush_device_writes(ahd);
10240 ahd_outb(ahd, BRDCTL, 0);
10241 ahd_flush_device_writes(ahd);
10242 return (0);
10243}
10244
10245int
10246ahd_read_flexport(struct ahd_softc *ahd, u_int addr, uint8_t *value)
10247{
10248 int error;
10249
10250 AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
10251 if (addr > 7)
10252 panic("ahd_read_flexport: address out of range");
10253 ahd_outb(ahd, BRDCTL, BRDRW|BRDEN|(addr << 3));
10254 error = ahd_wait_flexport(ahd);
10255 if (error != 0)
10256 return (error);
10257 *value = ahd_inb(ahd, BRDDAT);
10258 ahd_outb(ahd, BRDCTL, 0);
10259 ahd_flush_device_writes(ahd);
10260 return (0);
10261}
10262
10263
10264#ifdef AHD_TARGET_MODE
10265cam_status
10266ahd_find_tmode_devs(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb,
10267 struct ahd_tmode_tstate **tstate,
10268 struct ahd_tmode_lstate **lstate,
10269 int notfound_failure)
10270{
10271
10272 if ((ahd->features & AHD_TARGETMODE) == 0)
10273 return (CAM_REQ_INVALID);
10274
10275
10276
10277
10278
10279 if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD
10280 && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {
10281 *tstate = NULL;
10282 *lstate = ahd->black_hole;
10283 } else {
10284 u_int max_id;
10285
10286 max_id = (ahd->features & AHD_WIDE) ? 16 : 8;
10287 if (ccb->ccb_h.target_id >= max_id)
10288 return (CAM_TID_INVALID);
10289
10290 if (ccb->ccb_h.target_lun >= AHD_NUM_LUNS)
10291 return (CAM_LUN_INVALID);
10292
10293 *tstate = ahd->enabled_targets[ccb->ccb_h.target_id];
10294 *lstate = NULL;
10295 if (*tstate != NULL)
10296 *lstate =
10297 (*tstate)->enabled_luns[ccb->ccb_h.target_lun];
10298 }
10299
10300 if (notfound_failure != 0 && *lstate == NULL)
10301 return (CAM_PATH_INVALID);
10302
10303 return (CAM_REQ_CMP);
10304}
10305
10306void
10307ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
10308{
10309#if NOT_YET
10310 struct ahd_tmode_tstate *tstate;
10311 struct ahd_tmode_lstate *lstate;
10312 struct ccb_en_lun *cel;
10313 cam_status status;
10314 u_int target;
10315 u_int lun;
10316 u_int target_mask;
10317 u_long s;
10318 char channel;
10319
10320 status = ahd_find_tmode_devs(ahd, sim, ccb, &tstate, &lstate,
10321 FALSE);
10322
10323 if (status != CAM_REQ_CMP) {
10324 ccb->ccb_h.status = status;
10325 return;
10326 }
10327
10328 if ((ahd->features & AHD_MULTIROLE) != 0) {
10329 u_int our_id;
10330
10331 our_id = ahd->our_id;
10332 if (ccb->ccb_h.target_id != our_id) {
10333 if ((ahd->features & AHD_MULTI_TID) != 0
10334 && (ahd->flags & AHD_INITIATORROLE) != 0) {
10335
10336
10337
10338
10339
10340
10341
10342 status = CAM_TID_INVALID;
10343 } else if ((ahd->flags & AHD_INITIATORROLE) != 0
10344 || ahd->enabled_luns > 0) {
10345
10346
10347
10348
10349
10350
10351
10352 status = CAM_TID_INVALID;
10353 }
10354 }
10355 }
10356
10357 if (status != CAM_REQ_CMP) {
10358 ccb->ccb_h.status = status;
10359 return;
10360 }
10361
10362
10363
10364
10365
10366 if ((ahd->flags & AHD_TARGETROLE) == 0
10367 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
10368 u_long s;
10369
10370 printk("Configuring Target Mode\n");
10371 ahd_lock(ahd, &s);
10372 if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
10373 ccb->ccb_h.status = CAM_BUSY;
10374 ahd_unlock(ahd, &s);
10375 return;
10376 }
10377 ahd->flags |= AHD_TARGETROLE;
10378 if ((ahd->features & AHD_MULTIROLE) == 0)
10379 ahd->flags &= ~AHD_INITIATORROLE;
10380 ahd_pause(ahd);
10381 ahd_loadseq(ahd);
10382 ahd_restart(ahd);
10383 ahd_unlock(ahd, &s);
10384 }
10385 cel = &ccb->cel;
10386 target = ccb->ccb_h.target_id;
10387 lun = ccb->ccb_h.target_lun;
10388 channel = SIM_CHANNEL(ahd, sim);
10389 target_mask = 0x01 << target;
10390 if (channel == 'B')
10391 target_mask <<= 8;
10392
10393 if (cel->enable != 0) {
10394 u_int scsiseq1;
10395
10396
10397 if (lstate != NULL) {
10398 xpt_print_path(ccb->ccb_h.path);
10399 printk("Lun already enabled\n");
10400 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
10401 return;
10402 }
10403
10404 if (cel->grp6_len != 0
10405 || cel->grp7_len != 0) {
10406
10407
10408
10409
10410 ccb->ccb_h.status = CAM_REQ_INVALID;
10411 printk("Non-zero Group Codes\n");
10412 return;
10413 }
10414
10415
10416
10417
10418
10419 if (target != CAM_TARGET_WILDCARD && tstate == NULL) {
10420 tstate = ahd_alloc_tstate(ahd, target, channel);
10421 if (tstate == NULL) {
10422 xpt_print_path(ccb->ccb_h.path);
10423 printk("Couldn't allocate tstate\n");
10424 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
10425 return;
10426 }
10427 }
10428 lstate = kzalloc(sizeof(*lstate), GFP_ATOMIC);
10429 if (lstate == NULL) {
10430 xpt_print_path(ccb->ccb_h.path);
10431 printk("Couldn't allocate lstate\n");
10432 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
10433 return;
10434 }
10435 status = xpt_create_path(&lstate->path, NULL,
10436 xpt_path_path_id(ccb->ccb_h.path),
10437 xpt_path_target_id(ccb->ccb_h.path),
10438 xpt_path_lun_id(ccb->ccb_h.path));
10439 if (status != CAM_REQ_CMP) {
10440 kfree(lstate);
10441 xpt_print_path(ccb->ccb_h.path);
10442 printk("Couldn't allocate path\n");
10443 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
10444 return;
10445 }
10446 SLIST_INIT(&lstate->accept_tios);
10447 SLIST_INIT(&lstate->immed_notifies);
10448 ahd_lock(ahd, &s);
10449 ahd_pause(ahd);
10450 if (target != CAM_TARGET_WILDCARD) {
10451 tstate->enabled_luns[lun] = lstate;
10452 ahd->enabled_luns++;
10453
10454 if ((ahd->features & AHD_MULTI_TID) != 0) {
10455 u_int targid_mask;
10456
10457 targid_mask = ahd_inw(ahd, TARGID);
10458 targid_mask |= target_mask;
10459 ahd_outw(ahd, TARGID, targid_mask);
10460 ahd_update_scsiid(ahd, targid_mask);
10461 } else {
10462 u_int our_id;
10463 char channel;
10464
10465 channel = SIM_CHANNEL(ahd, sim);
10466 our_id = SIM_SCSI_ID(ahd, sim);
10467
10468
10469
10470
10471
10472 if (target != our_id) {
10473 u_int sblkctl;
10474 char cur_channel;
10475 int swap;
10476
10477 sblkctl = ahd_inb(ahd, SBLKCTL);
10478 cur_channel = (sblkctl & SELBUSB)
10479 ? 'B' : 'A';
10480 if ((ahd->features & AHD_TWIN) == 0)
10481 cur_channel = 'A';
10482 swap = cur_channel != channel;
10483 ahd->our_id = target;
10484
10485 if (swap)
10486 ahd_outb(ahd, SBLKCTL,
10487 sblkctl ^ SELBUSB);
10488
10489 ahd_outb(ahd, SCSIID, target);
10490
10491 if (swap)
10492 ahd_outb(ahd, SBLKCTL, sblkctl);
10493 }
10494 }
10495 } else
10496 ahd->black_hole = lstate;
10497
10498 if (ahd->black_hole != NULL && ahd->enabled_luns > 0) {
10499 scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE);
10500 scsiseq1 |= ENSELI;
10501 ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1);
10502 scsiseq1 = ahd_inb(ahd, SCSISEQ1);
10503 scsiseq1 |= ENSELI;
10504 ahd_outb(ahd, SCSISEQ1, scsiseq1);
10505 }
10506 ahd_unpause(ahd);
10507 ahd_unlock(ahd, &s);
10508 ccb->ccb_h.status = CAM_REQ_CMP;
10509 xpt_print_path(ccb->ccb_h.path);
10510 printk("Lun now enabled for target mode\n");
10511 } else {
10512 struct scb *scb;
10513 int i, empty;
10514
10515 if (lstate == NULL) {
10516 ccb->ccb_h.status = CAM_LUN_INVALID;
10517 return;
10518 }
10519
10520 ahd_lock(ahd, &s);
10521
10522 ccb->ccb_h.status = CAM_REQ_CMP;
10523 LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
10524 struct ccb_hdr *ccbh;
10525
10526 ccbh = &scb->io_ctx->ccb_h;
10527 if (ccbh->func_code == XPT_CONT_TARGET_IO
10528 && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
10529 printk("CTIO pending\n");
10530 ccb->ccb_h.status = CAM_REQ_INVALID;
10531 ahd_unlock(ahd, &s);
10532 return;
10533 }
10534 }
10535
10536 if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
10537 printk("ATIOs pending\n");
10538 ccb->ccb_h.status = CAM_REQ_INVALID;
10539 }
10540
10541 if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
10542 printk("INOTs pending\n");
10543 ccb->ccb_h.status = CAM_REQ_INVALID;
10544 }
10545
10546 if (ccb->ccb_h.status != CAM_REQ_CMP) {
10547 ahd_unlock(ahd, &s);
10548 return;
10549 }
10550
10551 xpt_print_path(ccb->ccb_h.path);
10552 printk("Target mode disabled\n");
10553 xpt_free_path(lstate->path);
10554 kfree(lstate);
10555
10556 ahd_pause(ahd);
10557
10558 if (target != CAM_TARGET_WILDCARD) {
10559 tstate->enabled_luns[lun] = NULL;
10560 ahd->enabled_luns--;
10561 for (empty = 1, i = 0; i < 8; i++)
10562 if (tstate->enabled_luns[i] != NULL) {
10563 empty = 0;
10564 break;
10565 }
10566
10567 if (empty) {
10568 ahd_free_tstate(ahd, target, channel,
10569 FALSE);
10570 if (ahd->features & AHD_MULTI_TID) {
10571 u_int targid_mask;
10572
10573 targid_mask = ahd_inw(ahd, TARGID);
10574 targid_mask &= ~target_mask;
10575 ahd_outw(ahd, TARGID, targid_mask);
10576 ahd_update_scsiid(ahd, targid_mask);
10577 }
10578 }
10579 } else {
10580
10581 ahd->black_hole = NULL;
10582
10583
10584
10585
10586
10587 empty = TRUE;
10588 }
10589 if (ahd->enabled_luns == 0) {
10590
10591 u_int scsiseq1;
10592
10593 scsiseq1 = ahd_inb(ahd, SCSISEQ_TEMPLATE);
10594 scsiseq1 &= ~ENSELI;
10595 ahd_outb(ahd, SCSISEQ_TEMPLATE, scsiseq1);
10596 scsiseq1 = ahd_inb(ahd, SCSISEQ1);
10597 scsiseq1 &= ~ENSELI;
10598 ahd_outb(ahd, SCSISEQ1, scsiseq1);
10599
10600 if ((ahd->features & AHD_MULTIROLE) == 0) {
10601 printk("Configuring Initiator Mode\n");
10602 ahd->flags &= ~AHD_TARGETROLE;
10603 ahd->flags |= AHD_INITIATORROLE;
10604 ahd_pause(ahd);
10605 ahd_loadseq(ahd);
10606 ahd_restart(ahd);
10607
10608
10609
10610
10611 }
10612 }
10613 ahd_unpause(ahd);
10614 ahd_unlock(ahd, &s);
10615 }
10616#endif
10617}
10618
10619static void
10620ahd_update_scsiid(struct ahd_softc *ahd, u_int targid_mask)
10621{
10622#if NOT_YET
10623 u_int scsiid_mask;
10624 u_int scsiid;
10625
10626 if ((ahd->features & AHD_MULTI_TID) == 0)
10627 panic("ahd_update_scsiid called on non-multitid unit\n");
10628
10629
10630
10631
10632
10633
10634
10635 if ((ahd->features & AHD_ULTRA2) != 0)
10636 scsiid = ahd_inb(ahd, SCSIID_ULTRA2);
10637 else
10638 scsiid = ahd_inb(ahd, SCSIID);
10639 scsiid_mask = 0x1 << (scsiid & OID);
10640 if ((targid_mask & scsiid_mask) == 0) {
10641 u_int our_id;
10642
10643
10644 our_id = ffs(targid_mask);
10645 if (our_id == 0)
10646 our_id = ahd->our_id;
10647 else
10648 our_id--;
10649 scsiid &= TID;
10650 scsiid |= our_id;
10651 }
10652 if ((ahd->features & AHD_ULTRA2) != 0)
10653 ahd_outb(ahd, SCSIID_ULTRA2, scsiid);
10654 else
10655 ahd_outb(ahd, SCSIID, scsiid);
10656#endif
10657}
10658
10659static void
10660ahd_run_tqinfifo(struct ahd_softc *ahd, int paused)
10661{
10662 struct target_cmd *cmd;
10663
10664 ahd_sync_tqinfifo(ahd, BUS_DMASYNC_POSTREAD);
10665 while ((cmd = &ahd->targetcmds[ahd->tqinfifonext])->cmd_valid != 0) {
10666
10667
10668
10669
10670
10671 if (ahd_handle_target_cmd(ahd, cmd) != 0)
10672 break;
10673
10674 cmd->cmd_valid = 0;
10675 ahd_dmamap_sync(ahd, ahd->shared_data_dmat,
10676 ahd->shared_data_map.dmamap,
10677 ahd_targetcmd_offset(ahd, ahd->tqinfifonext),
10678 sizeof(struct target_cmd),
10679 BUS_DMASYNC_PREREAD);
10680 ahd->tqinfifonext++;
10681
10682
10683
10684
10685
10686 if ((ahd->tqinfifonext & (HOST_TQINPOS - 1)) == 1) {
10687 u_int hs_mailbox;
10688
10689 hs_mailbox = ahd_inb(ahd, HS_MAILBOX);
10690 hs_mailbox &= ~HOST_TQINPOS;
10691 hs_mailbox |= ahd->tqinfifonext & HOST_TQINPOS;
10692 ahd_outb(ahd, HS_MAILBOX, hs_mailbox);
10693 }
10694 }
10695}
10696
10697static int
10698ahd_handle_target_cmd(struct ahd_softc *ahd, struct target_cmd *cmd)
10699{
10700 struct ahd_tmode_tstate *tstate;
10701 struct ahd_tmode_lstate *lstate;
10702 struct ccb_accept_tio *atio;
10703 uint8_t *byte;
10704 int initiator;
10705 int target;
10706 int lun;
10707
10708 initiator = SCSIID_TARGET(ahd, cmd->scsiid);
10709 target = SCSIID_OUR_ID(cmd->scsiid);
10710 lun = (cmd->identify & MSG_IDENTIFY_LUNMASK);
10711
10712 byte = cmd->bytes;
10713 tstate = ahd->enabled_targets[target];
10714 lstate = NULL;
10715 if (tstate != NULL)
10716 lstate = tstate->enabled_luns[lun];
10717
10718
10719
10720
10721 if (lstate == NULL)
10722 lstate = ahd->black_hole;
10723
10724 atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios);
10725 if (atio == NULL) {
10726 ahd->flags |= AHD_TQINFIFO_BLOCKED;
10727
10728
10729
10730 return (1);
10731 } else
10732 ahd->flags &= ~AHD_TQINFIFO_BLOCKED;
10733#ifdef AHD_DEBUG
10734 if ((ahd_debug & AHD_SHOW_TQIN) != 0)
10735 printk("Incoming command from %d for %d:%d%s\n",
10736 initiator, target, lun,
10737 lstate == ahd->black_hole ? "(Black Holed)" : "");
10738#endif
10739 SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);
10740
10741 if (lstate == ahd->black_hole) {
10742
10743 atio->ccb_h.target_id = target;
10744 atio->ccb_h.target_lun = lun;
10745 }
10746
10747
10748
10749
10750
10751 atio->sense_len = 0;
10752 atio->init_id = initiator;
10753 if (byte[0] != 0xFF) {
10754
10755 atio->tag_action = *byte++;
10756 atio->tag_id = *byte++;
10757 atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
10758 } else {
10759 atio->ccb_h.flags = 0;
10760 }
10761 byte++;
10762
10763
10764 switch (*byte >> CMD_GROUP_CODE_SHIFT) {
10765 case 0:
10766 atio->cdb_len = 6;
10767 break;
10768 case 1:
10769 case 2:
10770 atio->cdb_len = 10;
10771 break;
10772 case 4:
10773 atio->cdb_len = 16;
10774 break;
10775 case 5:
10776 atio->cdb_len = 12;
10777 break;
10778 case 3:
10779 default:
10780
10781 atio->cdb_len = 1;
10782 printk("Reserved or VU command code type encountered\n");
10783 break;
10784 }
10785
10786 memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);
10787
10788 atio->ccb_h.status |= CAM_CDB_RECVD;
10789
10790 if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) {
10791
10792
10793
10794
10795
10796
10797#ifdef AHD_DEBUG
10798 if ((ahd_debug & AHD_SHOW_TQIN) != 0)
10799 printk("Received Immediate Command %d:%d:%d - %p\n",
10800 initiator, target, lun, ahd->pending_device);
10801#endif
10802 ahd->pending_device = lstate;
10803 ahd_freeze_ccb((union ccb *)atio);
10804 atio->ccb_h.flags |= CAM_DIS_DISCONNECT;
10805 }
10806 xpt_done((union ccb*)atio);
10807 return (0);
10808}
10809
10810#endif
10811