This source file includes following definitions.
- ahc_pause_bug_fix
- ahc_is_paused
- ahc_pause
- ahc_unpause
- ahc_freeze_untagged_queues
- ahc_release_untagged_queues
- ahc_sg_bus_to_virt
- ahc_sg_virt_to_bus
- ahc_hscb_busaddr
- ahc_sync_scb
- ahc_targetcmd_offset
- ahc_name
- ahc_update_residual
- ahc_fetch_transinfo
- ahc_inw
- ahc_outw
- ahc_inl
- ahc_outl
- ahc_get_scb
- ahc_free_scb
- ahc_lookup_scb
- ahc_swap_with_next_hscb
- ahc_queue_scb
- ahc_get_sense_buf
- ahc_get_sense_bufaddr
- ahc_sync_qoutfifo
- ahc_sync_tqinfifo
- ahc_check_cmdcmpltqueues
- ahc_intr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 #ifndef _AIC7XXX_INLINE_H_
52 #define _AIC7XXX_INLINE_H_
53
54 #ifdef SMALL_KERNEL
55 #define IO_INLINE
56 #else
57 #define IO_INLINE static __inline
58 #define IO_EXPAND
59 #endif
60
61
62 IO_INLINE void ahc_pause_bug_fix(struct ahc_softc *ahc);
63 IO_INLINE int ahc_is_paused(struct ahc_softc *ahc);
64 IO_INLINE void ahc_pause(struct ahc_softc *ahc);
65 IO_INLINE void ahc_unpause(struct ahc_softc *ahc);
66
67 #ifdef IO_EXPAND
68
69
70
71
72
73
74
75
76 IO_INLINE void
77 ahc_pause_bug_fix(struct ahc_softc *ahc)
78 {
79 if ((ahc->features & AHC_ULTRA2) != 0)
80 (void)ahc_inb(ahc, CCSCBCTL);
81 }
82
83
84
85
86
87 IO_INLINE int
88 ahc_is_paused(struct ahc_softc *ahc)
89 {
90 return ((ahc_inb(ahc, HCNTRL) & PAUSE) != 0);
91 }
92
93
94
95
96
97
98
99
100 IO_INLINE void
101 ahc_pause(struct ahc_softc *ahc)
102 {
103 ahc_outb(ahc, HCNTRL, ahc->pause);
104
105
106
107
108
109 while (ahc_is_paused(ahc) == 0)
110 ;
111
112 ahc_pause_bug_fix(ahc);
113 }
114
115
116
117
118
119
120
121
122
123
124
125 IO_INLINE void
126 ahc_unpause(struct ahc_softc *ahc)
127 {
128 if ((ahc_inb(ahc, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) == 0)
129 ahc_outb(ahc, HCNTRL, ahc->unpause);
130 }
131 #endif
132
133
134 IO_INLINE void ahc_freeze_untagged_queues(struct ahc_softc *ahc);
135 IO_INLINE void ahc_release_untagged_queues(struct ahc_softc *ahc);
136
137 #ifdef IO_EXPAND
138
139
140
141
142 IO_INLINE void
143 ahc_freeze_untagged_queues(struct ahc_softc *ahc)
144 {
145 if ((ahc->flags & AHC_SCB_BTT) == 0)
146 ahc->untagged_queue_lock++;
147 }
148
149
150
151
152
153
154
155 IO_INLINE void
156 ahc_release_untagged_queues(struct ahc_softc *ahc)
157 {
158 if ((ahc->flags & AHC_SCB_BTT) == 0) {
159 ahc->untagged_queue_lock--;
160 if (ahc->untagged_queue_lock == 0)
161 ahc_run_untagged_queues(ahc);
162 }
163 }
164 #endif
165
166
167
168 IO_INLINE struct ahc_dma_seg *
169 ahc_sg_bus_to_virt(struct scb *scb,
170 uint32_t sg_busaddr);
171 IO_INLINE uint32_t
172 ahc_sg_virt_to_bus(struct scb *scb,
173 struct ahc_dma_seg *sg);
174 IO_INLINE uint32_t
175 ahc_hscb_busaddr(struct ahc_softc *ahc, u_int index);
176 IO_INLINE void ahc_sync_scb(struct ahc_softc *ahc,
177 struct scb *scb, int op);
178 #ifdef AHC_TARGET_MODE
179 IO_INLINE uint32_t
180 ahc_targetcmd_offset(struct ahc_softc *ahc,
181 u_int index);
182 #endif
183
184 #ifdef IO_EXPAND
185
186 IO_INLINE struct ahc_dma_seg *
187 ahc_sg_bus_to_virt(struct scb *scb, uint32_t sg_busaddr)
188 {
189 int sg_index;
190
191 sg_index = (sg_busaddr - scb->sg_list_phys)/sizeof(struct ahc_dma_seg);
192
193 sg_index++;
194
195 return (&scb->sg_list[sg_index]);
196 }
197
198 IO_INLINE uint32_t
199 ahc_sg_virt_to_bus(struct scb *scb, struct ahc_dma_seg *sg)
200 {
201 int sg_index;
202
203
204 sg_index = sg - &scb->sg_list[1];
205
206 return (scb->sg_list_phys + (sg_index * sizeof(*scb->sg_list)));
207 }
208
209 IO_INLINE uint32_t
210 ahc_hscb_busaddr(struct ahc_softc *ahc, u_int index)
211 {
212 return (ahc->scb_data->hscb_busaddr
213 + (sizeof(struct hardware_scb) * index));
214 }
215
216 IO_INLINE void
217 ahc_sync_scb(struct ahc_softc *ahc, struct scb *scb, int op)
218 {
219 ahc_dmamap_sync(ahc, ahc->parent_dmat,
220 ahc->scb_data->hscb_dmamap,
221 (scb->hscb - ahc->scb_data->hscbs) * sizeof(*scb->hscb),
222 sizeof(*scb->hscb), op);
223 }
224
225 #ifdef AHC_TARGET_MODE
226 IO_INLINE uint32_t
227 ahc_targetcmd_offset(struct ahc_softc *ahc, u_int index)
228 {
229 return (((uint8_t *)&ahc->targetcmds[index]) - ahc->qoutfifo);
230 }
231 #endif
232 #endif
233
234
235 static __inline char *ahc_name(struct ahc_softc *ahc);
236
237 static __inline char *
238 ahc_name(struct ahc_softc *ahc)
239 {
240 return (ahc->name);
241 }
242
243
244
245 IO_INLINE void ahc_update_residual(struct ahc_softc *ahc,
246 struct scb *scb);
247 IO_INLINE struct ahc_initiator_tinfo *
248 ahc_fetch_transinfo(struct ahc_softc *ahc,
249 char channel, u_int our_id,
250 u_int remote_id,
251 struct ahc_tmode_tstate **tstate);
252
253 IO_INLINE uint16_t
254 ahc_inw(struct ahc_softc *ahc, u_int port);
255 IO_INLINE void ahc_outw(struct ahc_softc *ahc, u_int port,
256 u_int value);
257 IO_INLINE uint32_t
258 ahc_inl(struct ahc_softc *ahc, u_int port);
259 IO_INLINE void ahc_outl(struct ahc_softc *ahc, u_int port,
260 uint32_t value);
261 IO_INLINE struct scb*
262 ahc_get_scb(struct ahc_softc *ahc);
263 IO_INLINE void ahc_free_scb(struct ahc_softc *ahc, struct scb *scb);
264 IO_INLINE struct scb *ahc_lookup_scb(struct ahc_softc *ahc, u_int tag);
265 IO_INLINE void ahc_swap_with_next_hscb(struct ahc_softc *ahc,
266 struct scb *scb);
267 IO_INLINE void ahc_queue_scb(struct ahc_softc *ahc, struct scb *scb);
268 IO_INLINE struct scsi_sense_data *
269 ahc_get_sense_buf(struct ahc_softc *ahc,
270 struct scb *scb);
271 IO_INLINE uint32_t
272 ahc_get_sense_bufaddr(struct ahc_softc *ahc,
273 struct scb *scb);
274
275 #ifdef IO_EXPAND
276
277
278
279
280
281 IO_INLINE void
282 ahc_update_residual(struct ahc_softc *ahc, struct scb *scb)
283 {
284 uint32_t sgptr;
285
286 sgptr = aic_le32toh(scb->hscb->sgptr);
287 if ((sgptr & SG_RESID_VALID) != 0)
288 ahc_calc_residual(ahc, scb);
289 }
290
291
292
293
294
295 IO_INLINE struct ahc_initiator_tinfo *
296 ahc_fetch_transinfo(struct ahc_softc *ahc, char channel, u_int our_id,
297 u_int remote_id, struct ahc_tmode_tstate **tstate)
298 {
299
300
301
302
303
304
305
306
307 *tstate = ahc->enabled_targets[our_id];
308 return (&(*tstate)->transinfo[remote_id]);
309 }
310
311 IO_INLINE uint16_t
312 ahc_inw(struct ahc_softc *ahc, u_int port)
313 {
314 return ((ahc_inb(ahc, port+1) << 8) | ahc_inb(ahc, port));
315 }
316
317 IO_INLINE void
318 ahc_outw(struct ahc_softc *ahc, u_int port, u_int value)
319 {
320 ahc_outb(ahc, port, value & 0xFF);
321 ahc_outb(ahc, port+1, (value >> 8) & 0xFF);
322 }
323
324 IO_INLINE uint32_t
325 ahc_inl(struct ahc_softc *ahc, u_int port)
326 {
327 return ((ahc_inb(ahc, port))
328 | (ahc_inb(ahc, port+1) << 8)
329 | (ahc_inb(ahc, port+2) << 16)
330 | (ahc_inb(ahc, port+3) << 24));
331 }
332
333 IO_INLINE void
334 ahc_outl(struct ahc_softc *ahc, u_int port, uint32_t value)
335 {
336 ahc_outb(ahc, port, (value) & 0xFF);
337 ahc_outb(ahc, port+1, ((value) >> 8) & 0xFF);
338 ahc_outb(ahc, port+2, ((value) >> 16) & 0xFF);
339 ahc_outb(ahc, port+3, ((value) >> 24) & 0xFF);
340 }
341
342
343
344
345 IO_INLINE struct scb *
346 ahc_get_scb(struct ahc_softc *ahc)
347 {
348 struct scb *scb;
349
350 scb = SLIST_FIRST(&ahc->scb_data->free_scbs);
351
352 if (scb != NULL)
353 SLIST_REMOVE_HEAD(&ahc->scb_data->free_scbs, links.sle);
354
355 return (scb);
356 }
357
358
359
360
361 IO_INLINE void
362 ahc_free_scb(struct ahc_softc *ahc, struct scb *scb)
363 {
364 struct hardware_scb *hscb;
365
366 hscb = scb->hscb;
367
368 ahc->scb_data->scbindex[hscb->tag] = NULL;
369 scb->flags = SCB_FLAG_NONE;
370 hscb->control = 0;
371
372 SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs, scb, links.sle);
373
374
375 ahc_platform_scb_free(ahc, scb);
376 }
377
378
379 IO_INLINE struct scb *
380 ahc_lookup_scb(struct ahc_softc *ahc, u_int tag)
381 {
382 struct scb* scb;
383
384 scb = ahc->scb_data->scbindex[tag];
385 if (scb != NULL)
386 ahc_sync_scb(ahc, scb,
387 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
388 return (scb);
389 }
390
391
392 IO_INLINE void
393 ahc_swap_with_next_hscb(struct ahc_softc *ahc, struct scb *scb)
394 {
395 struct hardware_scb *q_hscb;
396 u_int saved_tag;
397
398
399
400
401
402
403
404
405
406
407
408
409
410 q_hscb = ahc->next_queued_scb->hscb;
411 saved_tag = q_hscb->tag;
412 memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb));
413 if ((scb->flags & SCB_CDB32_PTR) != 0) {
414 q_hscb->shared_data.cdb_ptr =
415 aic_htole32(ahc_hscb_busaddr(ahc, q_hscb->tag)
416 + offsetof(struct hardware_scb, cdb32));
417 }
418 q_hscb->tag = saved_tag;
419 q_hscb->next = scb->hscb->tag;
420
421
422 ahc->next_queued_scb->hscb = scb->hscb;
423 scb->hscb = q_hscb;
424
425
426 ahc->scb_data->scbindex[scb->hscb->tag] = scb;
427 }
428
429
430
431
432 IO_INLINE void
433 ahc_queue_scb(struct ahc_softc *ahc, struct scb *scb)
434 {
435 ahc_swap_with_next_hscb(ahc, scb);
436
437 if (scb->hscb->tag == SCB_LIST_NULL
438 || scb->hscb->next == SCB_LIST_NULL)
439 panic("Attempt to queue invalid SCB tag %x:%x",
440 scb->hscb->tag, scb->hscb->next);
441
442
443
444
445 scb->hscb->lun &= LID;
446 if (ahc_get_transfer_length(scb) & 0x1)
447 scb->hscb->lun |= SCB_XFERLEN_ODD;
448
449
450
451
452 ahc->qinfifo[ahc->qinfifonext] = scb->hscb->tag;
453 ahc_dmamap_sync(ahc, ahc->parent_dmat, ahc->shared_data_dmamap,
454 ahc->qinfifonext+256, 1,
455 BUS_DMASYNC_PREWRITE);
456 ahc->qinfifonext++;
457
458
459
460
461
462 ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
463
464
465 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
466 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
467 } else {
468 if ((ahc->features & AHC_AUTOPAUSE) == 0)
469 ahc_pause(ahc);
470 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
471 if ((ahc->features & AHC_AUTOPAUSE) == 0)
472 ahc_unpause(ahc);
473 }
474 }
475
476
477 IO_INLINE struct scsi_sense_data *
478 ahc_get_sense_buf(struct ahc_softc *ahc, struct scb *scb)
479 {
480 int offset;
481
482 offset = scb - ahc->scb_data->scbarray;
483 return (&ahc->scb_data->sense[offset]);
484 }
485
486 IO_INLINE uint32_t
487 ahc_get_sense_bufaddr(struct ahc_softc *ahc, struct scb *scb)
488 {
489 int offset;
490
491 offset = scb - ahc->scb_data->scbarray;
492 return (ahc->scb_data->sense_busaddr
493 + (offset * sizeof(struct scsi_sense_data)));
494 }
495 #endif
496
497
498 IO_INLINE void ahc_sync_qoutfifo(struct ahc_softc *ahc, int op);
499 IO_INLINE void ahc_sync_tqinfifo(struct ahc_softc *ahc, int op);
500 IO_INLINE u_int ahc_check_cmdcmpltqueues(struct ahc_softc *ahc);
501 IO_INLINE int ahc_intr(struct ahc_softc *ahc);
502
503 #ifdef IO_EXPAND
504 IO_INLINE void
505 ahc_sync_qoutfifo(struct ahc_softc *ahc, int op)
506 {
507 ahc_dmamap_sync(ahc, ahc->parent_dmat, ahc->shared_data_dmamap,
508 0, 256, op);
509 }
510
511 IO_INLINE void
512 ahc_sync_tqinfifo(struct ahc_softc *ahc, int op)
513 {
514 #ifdef AHC_TARGET_MODE
515 if ((ahc->flags & AHC_TARGETROLE) != 0) {
516 ahc_dmamap_sync(ahc, ahc->parent_dmat ,
517 ahc->shared_data_dmamap,
518 ahc_targetcmd_offset(ahc, 0),
519 sizeof(struct target_cmd) * AHC_TMODE_CMDS,
520 op);
521 }
522 #endif
523 }
524
525
526
527
528
529 #define AHC_RUN_QOUTFIFO 0x1
530 #define AHC_RUN_TQINFIFO 0x2
531 IO_INLINE u_int
532 ahc_check_cmdcmpltqueues(struct ahc_softc *ahc)
533 {
534 u_int retval;
535
536 retval = 0;
537 ahc_dmamap_sync(ahc, ahc->parent_dmat , ahc->shared_data_dmamap,
538 ahc->qoutfifonext, 1,
539 BUS_DMASYNC_POSTREAD);
540 if (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL)
541 retval |= AHC_RUN_QOUTFIFO;
542 #ifdef AHC_TARGET_MODE
543 if ((ahc->flags & AHC_TARGETROLE) != 0
544 && (ahc->flags & AHC_TQINFIFO_BLOCKED) == 0) {
545 ahc_dmamap_sync(ahc, ahc->parent_dmat ,
546 ahc->shared_data_dmamap,
547 ahc_targetcmd_offset(ahc, ahc->tqinfifonext),
548 sizeof(struct target_cmd),
549 BUS_DMASYNC_POSTREAD);
550 if (ahc->targetcmds[ahc->tqinfifonext].cmd_valid != 0)
551 retval |= AHC_RUN_TQINFIFO;
552 }
553 #endif
554 return (retval);
555 }
556
557
558
559
560
561 IO_INLINE int
562 ahc_intr(struct ahc_softc *ahc)
563 {
564 u_int intstat;
565
566 if ((ahc->pause & INTEN) == 0) {
567
568
569
570
571
572
573 return (0);
574 }
575
576
577
578
579
580
581 if ((ahc->flags & (AHC_ALL_INTERRUPTS|AHC_EDGE_INTERRUPT)) == 0
582 && (ahc_check_cmdcmpltqueues(ahc) != 0))
583 intstat = CMDCMPLT;
584 else {
585 intstat = ahc_inb(ahc, INTSTAT);
586 }
587
588 if (intstat & CMDCMPLT) {
589 ahc_outb(ahc, CLRINT, CLRCMDINT);
590
591
592
593
594
595
596
597
598
599 ahc_flush_device_writes(ahc);
600 ahc_run_qoutfifo(ahc);
601 #ifdef AHC_TARGET_MODE
602 if ((ahc->flags & AHC_TARGETROLE) != 0)
603 ahc_run_tqinfifo(ahc, FALSE);
604 #endif
605 }
606
607 if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0)
608
609 return 1;
610
611 if ((intstat & INT_PEND) == 0) {
612 #if AHC_PCI_CONFIG > 0
613 if (ahc->unsolicited_ints > 500) {
614 ahc->unsolicited_ints = 0;
615 if ((ahc->chip & AHC_PCI) != 0
616 && (ahc_inb(ahc, ERROR) & PCIERRSTAT) != 0)
617 ahc->bus_intr(ahc);
618 }
619 ahc->unsolicited_ints++;
620 #endif
621 return 0;
622 }
623 ahc->unsolicited_ints = 0;
624
625 if (intstat & BRKADRINT) {
626 ahc_handle_brkadrint(ahc);
627
628 return 1;
629 }
630
631 if ((intstat & (SEQINT|SCSIINT)) != 0)
632 ahc_pause_bug_fix(ahc);
633
634 if ((intstat & SEQINT) != 0)
635 ahc_handle_seqint(ahc, intstat);
636
637 if ((intstat & SCSIINT) != 0)
638 ahc_handle_scsiint(ahc, intstat);
639
640 return (1);
641 }
642
643 #endif
644
645 #endif