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