Annotation of sys/arch/hp300/dev/mb89352.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: mb89352.c,v 1.15 2006/11/28 23:59:45 dlg Exp $ */
2: /* $NetBSD: mb89352.c,v 1.5 2000/03/23 07:01:31 thorpej Exp $ */
3: /* NecBSD: mb89352.c,v 1.4 1998/03/14 07:31:20 kmatsuda Exp */
4:
5: /*-
6: * Copyright (c) 1996,97,98,99 The NetBSD Foundation, Inc.
7: * All rights reserved.
8: *
9: * This code is derived from software contributed to The NetBSD Foundation
10: * by Charles M. Hannum, Masaru Oki and Kouichi Matsuda.
11: *
12: * Redistribution and use in source and binary forms, with or without
13: * modification, are permitted provided that the following conditions
14: * are met:
15: * 1. Redistributions of source code must retain the above copyright
16: * notice, this list of conditions and the following disclaimer.
17: * 2. Redistributions in binary form must reproduce the above copyright
18: * notice, this list of conditions and the following disclaimer in the
19: * documentation and/or other materials provided with the distribution.
20: * 3. All advertising materials mentioning features or use of this software
21: * must display the following acknowledgement:
22: * This product includes software developed by Charles M. Hannum.
23: * 4. The name of the author may not be used to endorse or promote products
24: * derived from this software without specific prior written permission.
25: *
26: * Copyright (c) 1994 Jarle Greipsland
27: * All rights reserved.
28: *
29: * Redistribution and use in source and binary forms, with or without
30: * modification, are permitted provided that the following conditions
31: * are met:
32: * 1. Redistributions of source code must retain the above copyright
33: * notice, this list of conditions and the following disclaimer.
34: * 2. Redistributions in binary form must reproduce the above copyright
35: * notice, this list of conditions and the following disclaimer in the
36: * documentation and/or other materials provided with the distribution.
37: * 3. The name of the author may not be used to endorse or promote products
38: * derived from this software without specific prior written permission.
39: *
40: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
41: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
42: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
44: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
45: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
46: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
49: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
50: * POSSIBILITY OF SUCH DAMAGE.
51: */
52: /*
53: * [NetBSD for NEC PC-98 series]
54: * Copyright (c) 1996, 1997, 1998
55: * NetBSD/pc98 porting staff. All rights reserved.
56: * Copyright (c) 1996, 1997, 1998
57: * Kouichi Matsuda. All rights reserved.
58: */
59:
60: /*
61: * Acknowledgements: Many of the algorithms used in this driver are
62: * inspired by the work of Julian Elischer (julian@tfs.com) and
63: * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million!
64: */
65:
66: /*
67: * A few customizable items:
68: */
69:
70: /* Synchronous data transfers? */
71: #define SPC_USE_SYNCHRONOUS 0
72: #define SPC_SYNC_REQ_ACK_OFS 8
73:
74: /* Wide data transfers? */
75: #define SPC_USE_WIDE 0
76: #define SPC_MAX_WIDTH 0
77:
78: /* Max attempts made to transmit a message */
79: #define SPC_MSG_MAX_ATTEMPT 3 /* Not used now XXX */
80:
81: /*
82: * Some spin loop parameters (essentially how long to wait some places)
83: * The problem(?) is that sometimes we expect either to be able to transmit a
84: * byte or to get a new one from the SCSI bus pretty soon. In order to avoid
85: * returning from the interrupt just to get yanked back for the next byte we
86: * may spin in the interrupt routine waiting for this byte to come. How long?
87: * This is really (SCSI) device and processor dependent. Tunable, I guess.
88: */
89: #define SPC_MSGIN_SPIN 1 /* Will spinwait upto ?ms for a new msg byte */
90: #define SPC_MSGOUT_SPIN 1
91:
92: /*
93: * Include debug functions? At the end of this file there are a bunch of
94: * functions that will print out various information regarding queued SCSI
95: * commands, driver state and chip contents. You can call them from the
96: * kernel debugger. If you set SPC_DEBUG to 0 they are not included (the
97: * kernel uses less memory) but you lose the debugging facilities.
98: */
99: #if 0
100: #define SPC_DEBUG
101: #endif
102:
103: #define SPC_ABORT_TIMEOUT 2000 /* time to wait for abort */
104:
105: /* threshold length for DMA transfer */
106: #define SPC_MIN_DMA_LEN 32
107:
108: /* End of customizable parameters */
109:
110: /*
111: * MB89352 SCSI Protocol Controller (SPC) routines.
112: */
113:
114: #include <sys/param.h>
115: #include <sys/systm.h>
116: #include <sys/kernel.h>
117: #include <sys/errno.h>
118: #include <sys/ioctl.h>
119: #include <sys/device.h>
120: #include <sys/buf.h>
121: #include <sys/proc.h>
122: #include <sys/user.h>
123: #include <sys/queue.h>
124:
125: #include <machine/intr.h>
126:
127: #include <scsi/scsi_all.h>
128: #include <scsi/scsi_message.h>
129: #include <scsi/scsiconf.h>
130:
131: #include <hp300/dev/mb89352reg.h>
132: #include <hp300/dev/mb89352var.h>
133:
134: #ifdef SPC_DEBUG
135: int spc_debug = 0x00; /* SPC_SHOWSTART|SPC_SHOWMISC|SPC_SHOWTRACE; */
136: #endif
137:
138: void spc_done (struct spc_softc *, struct spc_acb *);
139: void spc_dequeue (struct spc_softc *, struct spc_acb *);
140: int spc_scsi_cmd (struct scsi_xfer *);
141: int spc_poll (struct spc_softc *, struct scsi_xfer *, int);
142: void spc_sched_msgout(struct spc_softc *, u_char);
143: void spc_setsync(struct spc_softc *, struct spc_tinfo *);
144: void spc_select (struct spc_softc *, struct spc_acb *);
145: void spc_timeout (void *);
146: void spc_scsi_reset (struct spc_softc *);
147: void spc_free_acb (struct spc_softc *, struct spc_acb *, int);
148: struct spc_acb* spc_get_acb(struct spc_softc *, int);
149: int spc_reselect (struct spc_softc *, int);
150: void spc_sense (struct spc_softc *, struct spc_acb *);
151: void spc_msgin (struct spc_softc *);
152: void spc_abort (struct spc_softc *, struct spc_acb *);
153: void spc_msgout (struct spc_softc *);
154: int spc_dataout_pio (struct spc_softc *, u_char *, int);
155: int spc_datain_pio (struct spc_softc *, u_char *, int);
156: void spc_process_intr(void *, u_char);
157: #ifdef SPC_DEBUG
158: void spc_print_acb (struct spc_acb *);
159: void spc_dump_driver (struct spc_softc *);
160: void spc_dump89352 (struct spc_softc *);
161: void spc_show_scsi_cmd(struct spc_acb *);
162: void spc_print_active_acb(void);
163: #endif
164:
165: extern struct cfdriver spc_cd;
166:
167: struct scsi_device spc_dev = {
168: NULL, /* Use default error handler */
169: NULL, /* have a queue, served by this */
170: NULL, /* have no async handler */
171: NULL, /* Use default 'done' routine */
172: };
173:
174: struct scsi_adapter spc_switch = {
175: spc_scsi_cmd,
176: minphys,
177: NULL,
178: NULL
179: };
180:
181: /*
182: * INITIALIZATION ROUTINES (probe, attach ++)
183: */
184:
185: void
186: spc_attach(struct spc_softc *sc)
187: {
188: struct scsibus_attach_args saa;
189:
190: SPC_TRACE(("spc_attach "));
191: sc->sc_state = SPC_INIT;
192:
193: sc->sc_freq = 20; /* XXX Assume 20 MHz. */
194:
195: #if SPC_USE_SYNCHRONOUS
196: /*
197: * These are the bounds of the sync period, based on the frequency of
198: * the chip's clock input and the size and offset of the sync period
199: * register.
200: *
201: * For a 20MHz clock, this gives us 25, or 100nS, or 10MB/s, as a
202: * maximum transfer rate, and 112.5, or 450nS, or 2.22MB/s, as a
203: * minimum transfer rate.
204: */
205: sc->sc_minsync = (2 * 250) / sc->sc_freq;
206: sc->sc_maxsync = (9 * 250) / sc->sc_freq;
207: #endif
208:
209: spc_init(sc); /* Init chip and driver */
210:
211: /*
212: * Fill in the adapter.
213: */
214: sc->sc_link.adapter_softc = sc;
215: sc->sc_link.adapter_target = sc->sc_initiator;
216: sc->sc_link.adapter = &spc_switch;
217: sc->sc_link.device = &spc_dev;
218: sc->sc_link.openings = 2;
219:
220: bzero(&saa, sizeof(saa));
221: saa.saa_sc_link = &sc->sc_link;
222:
223: /*
224: * ask the adapter what subunits are present
225: */
226: config_found(&sc->sc_dev, &saa, scsiprint);
227: }
228:
229: /*
230: * Initialize the MB89352 chip itself.
231: */
232: void
233: spc_reset(struct spc_softc *sc)
234: {
235: SPC_TRACE(("spc_reset "));
236: /*
237: * Disable interrupts then reset the FUJITSU chip.
238: */
239: spc_write(SCTL, SCTL_DISABLE | SCTL_CTRLRST);
240: spc_write(SCMD, 0);
241: spc_write(TMOD, 0);
242: spc_write(PCTL, 0);
243: spc_write(TEMP, 0);
244: spc_write(TCH, 0);
245: spc_write(TCM, 0);
246: spc_write(TCL, 0);
247: spc_write(INTS, 0);
248: spc_write(SCTL, sc->sc_ctlflags |
249: SCTL_DISABLE | SCTL_ABRT_ENAB | SCTL_SEL_ENAB | SCTL_RESEL_ENAB);
250: spc_write(BDID, sc->sc_initiator);
251: delay(400);
252: spc_write(SCTL, spc_read(SCTL) & ~SCTL_DISABLE);
253: }
254:
255:
256: /*
257: * Pull the SCSI RST line for 500us.
258: */
259: void
260: spc_scsi_reset(struct spc_softc *sc)
261: {
262: SPC_TRACE(("spc_scsi_reset "));
263: spc_write(SCMD, spc_read(SCMD) | SCMD_RST);
264: delay(500);
265: spc_write(SCMD, spc_read(SCMD) & ~SCMD_RST);
266: delay(50);
267: }
268:
269: /*
270: * Initialize spc SCSI driver.
271: */
272: void
273: spc_init(struct spc_softc *sc)
274: {
275: struct spc_acb *acb;
276: int r;
277:
278: SPC_TRACE(("spc_init "));
279: (*sc->sc_reset)(sc);
280: spc_scsi_reset(sc);
281: (*sc->sc_reset)(sc);
282:
283: if (sc->sc_state == SPC_INIT) {
284: /* First time through; initialize. */
285: TAILQ_INIT(&sc->ready_list);
286: TAILQ_INIT(&sc->nexus_list);
287: TAILQ_INIT(&sc->free_list);
288: sc->sc_nexus = NULL;
289: acb = sc->sc_acb;
290: bzero(acb, sizeof(sc->sc_acb));
291: for (r = 0; r < sizeof(sc->sc_acb) / sizeof(*acb); r++) {
292: TAILQ_INSERT_TAIL(&sc->free_list, acb, chain);
293: acb++;
294: }
295: bzero(&sc->sc_tinfo, sizeof(sc->sc_tinfo));
296: } else {
297: /* Cancel any active commands. */
298: sc->sc_state = SPC_CLEANING;
299: if ((acb = sc->sc_nexus) != NULL) {
300: acb->xs->error = XS_DRIVER_STUFFUP;
301: spc_done(sc, acb);
302: }
303: while ((acb = TAILQ_FIRST(&sc->nexus_list)) != NULL) {
304: acb->xs->error = XS_DRIVER_STUFFUP;
305: spc_done(sc, acb);
306: }
307: }
308:
309: sc->sc_prevphase = PH_INVALID;
310: for (r = 0; r < 8; r++) {
311: struct spc_tinfo *ti = &sc->sc_tinfo[r];
312:
313: ti->flags = 0;
314: #if SPC_USE_SYNCHRONOUS
315: ti->flags |= DO_SYNC;
316: ti->period = sc->sc_minsync;
317: ti->offset = SPC_SYNC_REQ_ACK_OFS;
318: #else
319: ti->period = ti->offset = 0;
320: #endif
321: #if SPC_USE_WIDE
322: ti->flags |= DO_WIDE;
323: ti->width = SPC_MAX_WIDTH;
324: #else
325: ti->width = 0;
326: #endif
327: }
328:
329: sc->sc_state = SPC_IDLE;
330: spc_write(SCTL, spc_read(SCTL) | SCTL_INTR_ENAB);
331: }
332:
333: void
334: spc_free_acb(struct spc_softc *sc, struct spc_acb *acb, int flags)
335: {
336: int s;
337:
338: SPC_TRACE(("spc_free_acb "));
339: s = splbio();
340:
341: acb->flags = 0;
342: TAILQ_INSERT_HEAD(&sc->free_list, acb, chain);
343:
344: /*
345: * If there were none, wake anybody waiting for one to come free,
346: * starting with queued entries.
347: */
348: if (TAILQ_NEXT(acb, chain) == NULL)
349: wakeup(&sc->free_list);
350:
351: splx(s);
352: }
353:
354: struct spc_acb *
355: spc_get_acb(struct spc_softc *sc, int flags)
356: {
357: struct spc_acb *acb;
358: int s;
359:
360: SPC_TRACE(("spc_get_acb "));
361: s = splbio();
362:
363: while ((acb = TAILQ_FIRST(&sc->free_list)) == NULL &&
364: (flags & SCSI_NOSLEEP) == 0)
365: tsleep(&sc->free_list, PRIBIO, "spcacb", 0);
366: if (acb) {
367: TAILQ_REMOVE(&sc->free_list, acb, chain);
368: acb->flags |= ACB_ALLOC;
369: }
370:
371: splx(s);
372: return acb;
373: }
374:
375: /*
376: * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
377: */
378:
379: /*
380: * Expected sequence:
381: * 1) Command inserted into ready list
382: * 2) Command selected for execution
383: * 3) Command won arbitration and has selected target device
384: * 4) Send message out (identify message, eventually also sync.negotiations)
385: * 5) Send command
386: * 5a) Receive disconnect message, disconnect.
387: * 5b) Reselected by target
388: * 5c) Receive identify message from target.
389: * 6) Send or receive data
390: * 7) Receive status
391: * 8) Receive message (command complete etc.)
392: * 9) If status == SCSI_CHECK construct a synthetic request sense SCSI cmd.
393: * Repeat 2-8 (no disconnects please...)
394: */
395:
396: /*
397: * Start a SCSI-command
398: * This function is called by the higher level SCSI-driver to queue/run
399: * SCSI-commands.
400: */
401: int
402: spc_scsi_cmd(struct scsi_xfer *xs)
403: {
404: struct scsi_link *sc_link = xs->sc_link;
405: struct spc_softc *sc = sc_link->adapter_softc;
406: struct spc_acb *acb;
407: int s, flags;
408:
409: SPC_TRACE(("spc_scsi_cmd "));
410: SPC_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
411: sc_link->target));
412:
413: flags = xs->flags;
414: if ((acb = spc_get_acb(sc, flags)) == NULL) {
415: return TRY_AGAIN_LATER;
416: }
417:
418: /* Initialize acb */
419: acb->xs = xs;
420: acb->timeout = xs->timeout;
421:
422: if (xs->flags & SCSI_RESET) {
423: acb->flags |= ACB_RESET;
424: acb->scsi_cmd_length = 0;
425: acb->data_length = 0;
426: } else {
427: bcopy(xs->cmd, &acb->scsi_cmd, xs->cmdlen);
428: acb->scsi_cmd_length = xs->cmdlen;
429: acb->data_addr = xs->data;
430: acb->data_length = xs->datalen;
431: }
432: acb->target_stat = 0;
433:
434: s = splbio();
435:
436: TAILQ_INSERT_TAIL(&sc->ready_list, acb, chain);
437: /*
438: * Start scheduling unless a queue process is in progress.
439: */
440: if (sc->sc_state == SPC_IDLE)
441: spc_sched(sc);
442: /*
443: * After successful sending, check if we should return just now.
444: * If so, return SUCCESSFULLY_QUEUED.
445: */
446:
447: splx(s);
448:
449: if ((flags & SCSI_POLL) == 0)
450: return SUCCESSFULLY_QUEUED;
451:
452: /* Not allowed to use interrupts, use polling instead */
453: s = splbio();
454: if (spc_poll(sc, xs, acb->timeout)) {
455: spc_timeout(acb);
456: if (spc_poll(sc, xs, acb->timeout))
457: spc_timeout(acb);
458: }
459: splx(s);
460: return COMPLETE;
461: }
462:
463: /*
464: * Used when interrupt driven I/O isn't allowed, e.g. during boot.
465: */
466: int
467: spc_poll(struct spc_softc *sc, struct scsi_xfer *xs, int count)
468: {
469: u_char intr;
470:
471: SPC_TRACE(("spc_poll "));
472: while (count) {
473: /*
474: * If we had interrupts enabled, would we
475: * have got an interrupt?
476: */
477: intr = spc_read(INTS);
478: if (intr != 0)
479: spc_process_intr(sc, intr);
480: if ((xs->flags & ITSDONE) != 0)
481: return 0;
482: delay(1000);
483: count--;
484: }
485: return 1;
486: }
487:
488: /*
489: * LOW LEVEL SCSI UTILITIES
490: */
491:
492: void
493: spc_sched_msgout(struct spc_softc *sc, u_char m)
494: {
495: SPC_TRACE(("spc_sched_msgout "));
496: if (sc->sc_msgpriq == 0)
497: spc_write(SCMD, SCMD_SET_ATN);
498: sc->sc_msgpriq |= m;
499: }
500:
501: /*
502: * Set synchronous transfer offset and period.
503: */
504: void
505: spc_setsync(struct spc_softc *sc, struct spc_tinfo *ti)
506: {
507: #if SPC_USE_SYNCHRONOUS
508: SPC_TRACE(("spc_setsync "));
509: if (ti->offset != 0)
510: spc_write(TMOD,
511: ((ti->period * sc->sc_freq) / 250 - 2) << 4 | ti->offset);
512: else
513: spc_write(TMOD, 0);
514: #endif
515: }
516:
517: /*
518: * Start a selection. This is used by spc_sched() to select an idle target,
519: * and by spc_done() to immediately reselect a target to get sense information.
520: */
521: void
522: spc_select(struct spc_softc *sc, struct spc_acb *acb)
523: {
524: struct scsi_link *sc_link = acb->xs->sc_link;
525: int target = sc_link->target;
526: struct spc_tinfo *ti = &sc->sc_tinfo[target];
527:
528: SPC_TRACE(("spc_select "));
529: spc_setsync(sc, ti);
530:
531: #if 0
532: spc_write(SCMD, SCMD_SET_ATN);
533: #endif
534:
535: spc_write(PCTL, 0);
536: spc_write(TEMP, (1 << sc->sc_initiator) | (1 << target));
537:
538: /*
539: * Setup BSY timeout (selection timeout).
540: * 250ms according to the SCSI specification.
541: * T = (X * 256 + 15) * Tclf * 2 (Tclf = 200ns on x68k)
542: * To setup 256ms timeout,
543: * 128000ns/200ns = X * 256 + 15
544: * 640 - 15 = X * 256
545: * X = 625 / 256
546: * X = 2 + 113 / 256
547: * ==> tch = 2, tcm = 113 (correct?)
548: */
549: /* Time to the information transfer phase start. */
550: /* XXX These values should be calculated from sc_freq */
551: spc_write(TCH, 2);
552: spc_write(TCM, 113);
553: spc_write(TCL, 3);
554: spc_write(SCMD, SCMD_SELECT);
555:
556: sc->sc_state = SPC_SELECTING;
557: }
558:
559: int
560: spc_reselect(struct spc_softc *sc, int message)
561: {
562: u_char selid, target, lun;
563: struct spc_acb *acb;
564: struct scsi_link *sc_link;
565: struct spc_tinfo *ti;
566:
567: SPC_TRACE(("spc_reselect "));
568: /*
569: * The SCSI chip made a snapshot of the data bus while the reselection
570: * was being negotiated. This enables us to determine which target did
571: * the reselect.
572: */
573: selid = sc->sc_selid & ~(1 << sc->sc_initiator);
574: if (selid & (selid - 1)) {
575: printf("%s: reselect with invalid selid %02x; "
576: "sending DEVICE RESET\n", sc->sc_dev.dv_xname, selid);
577: SPC_BREAK();
578: goto reset;
579: }
580:
581: /*
582: * Search wait queue for disconnected cmd
583: * The list should be short, so I haven't bothered with
584: * any more sophisticated structures than a simple
585: * singly linked list.
586: */
587: target = ffs(selid) - 1;
588: lun = message & 0x07;
589: TAILQ_FOREACH(acb, &sc->nexus_list, chain) {
590: sc_link = acb->xs->sc_link;
591: if (sc_link->target == target &&
592: sc_link->lun == lun)
593: break;
594: }
595: if (acb == NULL) {
596: printf("%s: reselect from target %d lun %d with no nexus; "
597: "sending ABORT\n", sc->sc_dev.dv_xname, target, lun);
598: SPC_BREAK();
599: goto abort;
600: }
601:
602: /* Make this nexus active again. */
603: TAILQ_REMOVE(&sc->nexus_list, acb, chain);
604: sc->sc_state = SPC_CONNECTED;
605: sc->sc_nexus = acb;
606: ti = &sc->sc_tinfo[target];
607: ti->lubusy |= (1 << lun);
608: spc_setsync(sc, ti);
609:
610: if (acb->flags & ACB_RESET)
611: spc_sched_msgout(sc, SEND_DEV_RESET);
612: else if (acb->flags & ACB_ABORT)
613: spc_sched_msgout(sc, SEND_ABORT);
614:
615: /* Do an implicit RESTORE POINTERS. */
616: sc->sc_dp = acb->data_addr;
617: sc->sc_dleft = acb->data_length;
618: sc->sc_cp = (u_char *)&acb->scsi_cmd;
619: sc->sc_cleft = acb->scsi_cmd_length;
620:
621: return (0);
622:
623: reset:
624: spc_sched_msgout(sc, SEND_DEV_RESET);
625: return (1);
626:
627: abort:
628: spc_sched_msgout(sc, SEND_ABORT);
629: return (1);
630: }
631:
632: /*
633: * Schedule a SCSI operation. This has now been pulled out of the interrupt
634: * handler so that we may call it from spc_scsi_cmd and spc_done. This may
635: * save us an unnecessary interrupt just to get things going. Should only be
636: * called when state == SPC_IDLE and at bio ipl.
637: */
638: void
639: spc_sched(struct spc_softc *sc)
640: {
641: struct spc_acb *acb;
642: struct scsi_link *sc_link;
643: struct spc_tinfo *ti;
644:
645: splassert(IPL_BIO);
646:
647: /* missing the hw, just return and wait for our hw */
648: if (sc->sc_flags & SPC_INACTIVE)
649: return;
650: SPC_TRACE(("spc_sched "));
651: /*
652: * Find first acb in ready queue that is for a target/lunit pair that
653: * is not busy.
654: */
655: TAILQ_FOREACH(acb, &sc->ready_list, chain) {
656: sc_link = acb->xs->sc_link;
657: ti = &sc->sc_tinfo[sc_link->target];
658: if ((ti->lubusy & (1 << sc_link->lun)) == 0) {
659: SPC_MISC(("selecting %d:%d ",
660: sc_link->target, sc_link->lun));
661: TAILQ_REMOVE(&sc->ready_list, acb, chain);
662: sc->sc_nexus = acb;
663: spc_select(sc, acb);
664: return;
665: } else
666: SPC_MISC(("%d:%d busy\n",
667: sc_link->target, sc_link->lun));
668: }
669: SPC_MISC(("idle "));
670: /* Nothing to start; just enable reselections and wait. */
671: }
672:
673: void
674: spc_sense(struct spc_softc *sc, struct spc_acb *acb)
675: {
676: struct scsi_xfer *xs = acb->xs;
677: struct scsi_link *sc_link = xs->sc_link;
678: struct spc_tinfo *ti = &sc->sc_tinfo[sc_link->target];
679: struct scsi_sense *ss = (void *)&acb->scsi_cmd;
680:
681: SPC_MISC(("requesting sense "));
682: /* Next, setup a request sense command block */
683: bzero(ss, sizeof(*ss));
684: ss->opcode = REQUEST_SENSE;
685: ss->byte2 = sc_link->lun << 5;
686: ss->length = sizeof(struct scsi_sense_data);
687: acb->scsi_cmd_length = sizeof(*ss);
688: acb->data_addr = (char *)&xs->sense;
689: acb->data_length = sizeof(struct scsi_sense_data);
690: acb->flags |= ACB_SENSE;
691: ti->senses++;
692: if (acb->flags & ACB_NEXUS)
693: ti->lubusy &= ~(1 << sc_link->lun);
694: if (acb == sc->sc_nexus) {
695: spc_select(sc, acb);
696: } else {
697: spc_dequeue(sc, acb);
698: TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
699: if (sc->sc_state == SPC_IDLE)
700: spc_sched(sc);
701: }
702: }
703:
704: /*
705: * POST PROCESSING OF SCSI_CMD (usually current)
706: */
707: void
708: spc_done(struct spc_softc *sc, struct spc_acb *acb)
709: {
710: struct scsi_xfer *xs = acb->xs;
711: struct scsi_link *sc_link = xs->sc_link;
712: struct spc_tinfo *ti = &sc->sc_tinfo[sc_link->target];
713:
714: SPC_TRACE(("spc_done "));
715:
716: timeout_del(&acb->xs->stimeout);
717:
718: /*
719: * Now, if we've come here with no error code, i.e. we've kept the
720: * initial XS_NOERROR, and the status code signals that we should
721: * check sense, we'll need to set up a request sense cmd block and
722: * push the command back into the ready queue *before* any other
723: * commands for this target/lunit, else we lose the sense info.
724: * We don't support chk sense conditions for the request sense cmd.
725: */
726: if (xs->error == XS_NOERROR) {
727: if (acb->flags & ACB_ABORT) {
728: xs->error = XS_DRIVER_STUFFUP;
729: } else if (acb->flags & ACB_SENSE) {
730: xs->error = XS_SENSE;
731: } else {
732: switch (acb->target_stat) {
733: case SCSI_CHECK:
734: /* First, save the return values */
735: xs->resid = acb->data_length;
736: xs->status = acb->target_stat;
737: spc_sense(sc, acb);
738: return;
739: case SCSI_BUSY:
740: xs->error = XS_BUSY;
741: break;
742: case SCSI_OK:
743: xs->resid = acb->data_length;
744: break;
745: default:
746: xs->error = XS_DRIVER_STUFFUP;
747: #ifdef SPC_DEBUG
748: printf("%s: spc_done: bad stat 0x%x\n",
749: sc->sc_dev.dv_xname, acb->target_stat);
750: #endif
751: break;
752: }
753: }
754: }
755:
756: xs->flags |= ITSDONE;
757:
758: #ifdef SPC_DEBUG
759: if ((spc_debug & SPC_SHOWMISC) != 0) {
760: if (xs->resid != 0)
761: printf("resid=%d ", xs->resid);
762: if (xs->error == XS_SENSE)
763: printf("sense=0x%02x\n", xs->sense.error_code);
764: else
765: printf("error=%d\n", xs->error);
766: }
767: #endif
768:
769: /*
770: * Remove the ACB from whatever queue it happens to be on.
771: */
772: if (acb->flags & ACB_NEXUS)
773: ti->lubusy &= ~(1 << sc_link->lun);
774: if (acb == sc->sc_nexus) {
775: sc->sc_nexus = NULL;
776: sc->sc_state = SPC_IDLE;
777: spc_sched(sc);
778: } else
779: spc_dequeue(sc, acb);
780:
781: spc_free_acb(sc, acb, xs->flags);
782: ti->cmds++;
783: scsi_done(xs);
784: }
785:
786: void
787: spc_dequeue(struct spc_softc *sc, struct spc_acb *acb)
788: {
789: SPC_TRACE(("spc_dequeue "));
790: if (acb->flags & ACB_NEXUS)
791: TAILQ_REMOVE(&sc->nexus_list, acb, chain);
792: else
793: TAILQ_REMOVE(&sc->ready_list, acb, chain);
794: }
795:
796: /*
797: * INTERRUPT/PROTOCOL ENGINE
798: */
799:
800: #define IS1BYTEMSG(m) (((m) != 0x01 && (m) < 0x20) || (m) >= 0x80)
801: #define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
802: #define ISEXTMSG(m) ((m) == 0x01)
803:
804: /*
805: * Precondition:
806: * The SCSI bus is already in the MSGI phase and there is a message byte
807: * on the bus, along with an asserted REQ signal.
808: */
809: void
810: spc_msgin(struct spc_softc *sc)
811: {
812: int n;
813: u_int8_t msg;
814:
815: SPC_TRACE(("spc_msgin "));
816:
817: if (sc->sc_prevphase == PH_MSGIN) {
818: /* This is a continuation of the previous message. */
819: n = sc->sc_imp - sc->sc_imess;
820: goto nextbyte;
821: }
822:
823: /* This is a new MESSAGE IN phase. Clean up our state. */
824: sc->sc_flags &= ~SPC_DROP_MSGIN;
825:
826: nextmsg:
827: n = 0;
828: sc->sc_imp = &sc->sc_imess[n];
829:
830: nextbyte:
831: /*
832: * Read a whole message, but don't ack the last byte. If we reject the
833: * message, we have to assert ATN during the message transfer phase
834: * itself.
835: */
836: for (;;) {
837: /* If parity error, just dump everything on the floor. */
838: if ((spc_read(SERR) & (SERR_SCSI_PAR|SERR_SPC_PAR)) != 0) {
839: sc->sc_flags |= SPC_DROP_MSGIN;
840: spc_sched_msgout(sc, SEND_PARITY_ERROR);
841: }
842:
843: if ((spc_read(PSNS) & PSNS_ATN) != 0)
844: spc_write(SCMD, SCMD_RST_ATN);
845: spc_write(PCTL, PCTL_BFINT_ENAB | PH_MSGIN);
846:
847: while ((spc_read(PSNS) & PSNS_REQ) == 0) {
848: if (((spc_read(PSNS) & PH_MASK) != PH_MSGIN &&
849: (spc_read(SSTS) & SSTS_INITIATOR) == 0) ||
850: spc_read(INTS) != 0)
851: /*
852: * Target left MESSAGE IN, probably because it
853: * a) noticed our ATN signal, or
854: * b) ran out of messages.
855: */
856: goto out;
857: DELAY(1);
858: }
859:
860: msg = spc_read(TEMP);
861:
862: /* Gather incoming message bytes if needed. */
863: if ((sc->sc_flags & SPC_DROP_MSGIN) == 0) {
864: if (n >= SPC_MAX_MSG_LEN) {
865: sc->sc_flags |= SPC_DROP_MSGIN;
866: spc_sched_msgout(sc, SEND_REJECT);
867: } else {
868: *sc->sc_imp++ = msg;
869: n++;
870: /*
871: * This testing is suboptimal, but most
872: * messages will be of the one byte variety, so
873: * it should not affect performance
874: * significantly.
875: */
876: if (n == 1 && IS1BYTEMSG(sc->sc_imess[0]))
877: break;
878: if (n == 2 && IS2BYTEMSG(sc->sc_imess[0]))
879: break;
880: if (n >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
881: n == sc->sc_imess[1] + 2)
882: break;
883: }
884: }
885:
886: /*
887: * If we reach this spot we're either:
888: * a) in the middle of a multi-byte message, or
889: * b) dropping bytes.
890: */
891:
892: /* Ack the last byte read. */
893: spc_write(SCMD, SCMD_SET_ACK);
894: while ((spc_read(PSNS) & PSNS_REQ) != 0)
895: DELAY(1); /* XXX needs timeout */
896: spc_write(SCMD, SCMD_RST_ACK);
897: }
898:
899: SPC_MISC(("n=%d imess=0x%02x ", n, sc->sc_imess[0]));
900:
901: /* We now have a complete message. Parse it. */
902: switch (sc->sc_state) {
903: struct spc_acb *acb;
904: struct scsi_link *sc_link;
905: struct spc_tinfo *ti;
906:
907: case SPC_CONNECTED:
908: SPC_ASSERT(sc->sc_nexus != NULL);
909: acb = sc->sc_nexus;
910: ti = &sc->sc_tinfo[acb->xs->sc_link->target];
911:
912: switch (sc->sc_imess[0]) {
913: case MSG_CMDCOMPLETE:
914: if (sc->sc_dleft < 0) {
915: sc_link = acb->xs->sc_link;
916: printf("%s: %d extra bytes from %d:%d\n",
917: sc->sc_dev.dv_xname, -sc->sc_dleft,
918: sc_link->target, sc_link->lun);
919: sc->sc_dleft = 0;
920: }
921: acb->xs->resid = acb->data_length = sc->sc_dleft;
922: sc->sc_state = SPC_CMDCOMPLETE;
923: break;
924:
925: case MSG_PARITY_ERROR:
926: /* Resend the last message. */
927: spc_sched_msgout(sc, sc->sc_lastmsg);
928: break;
929:
930: case MSG_MESSAGE_REJECT:
931: SPC_MISC(("message rejected %02x ", sc->sc_lastmsg));
932: switch (sc->sc_lastmsg) {
933: #if SPC_USE_SYNCHRONOUS + SPC_USE_WIDE
934: case SEND_IDENTIFY:
935: ti->flags &= ~(DO_SYNC | DO_WIDE);
936: ti->period = ti->offset = 0;
937: spc_setsync(sc, ti);
938: ti->width = 0;
939: break;
940: #endif
941: #if SPC_USE_SYNCHRONOUS
942: case SEND_SDTR:
943: ti->flags &= ~DO_SYNC;
944: ti->period = ti->offset = 0;
945: spc_setsync(sc, ti);
946: break;
947: #endif
948: #if SPC_USE_WIDE
949: case SEND_WDTR:
950: ti->flags &= ~DO_WIDE;
951: ti->width = 0;
952: break;
953: #endif
954: case SEND_INIT_DET_ERR:
955: spc_sched_msgout(sc, SEND_ABORT);
956: break;
957: }
958: break;
959:
960: case MSG_NOOP:
961: break;
962:
963: case MSG_DISCONNECT:
964: ti->dconns++;
965: sc->sc_state = SPC_DISCONNECT;
966: break;
967:
968: case MSG_SAVEDATAPOINTER:
969: acb->data_addr = sc->sc_dp;
970: acb->data_length = sc->sc_dleft;
971: break;
972:
973: case MSG_RESTOREPOINTERS:
974: sc->sc_dp = acb->data_addr;
975: sc->sc_dleft = acb->data_length;
976: sc->sc_cp = (u_char *)&acb->scsi_cmd;
977: sc->sc_cleft = acb->scsi_cmd_length;
978: break;
979:
980: case MSG_EXTENDED:
981: switch (sc->sc_imess[2]) {
982: #if SPC_USE_SYNCHRONOUS
983: case MSG_EXT_SDTR:
984: if (sc->sc_imess[1] != 3)
985: goto reject;
986: ti->period = sc->sc_imess[3];
987: ti->offset = sc->sc_imess[4];
988: ti->flags &= ~DO_SYNC;
989: if (ti->offset == 0) {
990: } else if (ti->period < sc->sc_minsync ||
991: ti->period > sc->sc_maxsync ||
992: ti->offset > 8) {
993: ti->period = ti->offset = 0;
994: spc_sched_msgout(sc, SEND_SDTR);
995: } else {
996: sc_print_addr(acb->xs->sc_link);
997: printf("sync, offset %d, "
998: "period %dnsec\n",
999: ti->offset, ti->period * 4);
1000: }
1001: spc_setsync(sc, ti);
1002: break;
1003: #endif
1004:
1005: #if SPC_USE_WIDE
1006: case MSG_EXT_WDTR:
1007: if (sc->sc_imess[1] != 2)
1008: goto reject;
1009: ti->width = sc->sc_imess[3];
1010: ti->flags &= ~DO_WIDE;
1011: if (ti->width == 0) {
1012: } else if (ti->width > SPC_MAX_WIDTH) {
1013: ti->width = 0;
1014: spc_sched_msgout(sc, SEND_WDTR);
1015: } else {
1016: sc_print_addr(acb->xs->sc_link);
1017: printf("wide, width %d\n",
1018: 1 << (3 + ti->width));
1019: }
1020: break;
1021: #endif
1022:
1023: default:
1024: printf("%s: unrecognized MESSAGE EXTENDED 0x%x;"
1025: " sending REJECT\n",
1026: sc->sc_imess[2], sc->sc_dev.dv_xname);
1027: SPC_BREAK();
1028: goto reject;
1029: }
1030: break;
1031:
1032: default:
1033: printf("%s: unrecognized MESSAGE; sending REJECT\n",
1034: sc->sc_dev.dv_xname);
1035: SPC_BREAK();
1036: reject:
1037: spc_sched_msgout(sc, SEND_REJECT);
1038: break;
1039: }
1040: break;
1041:
1042: case SPC_RESELECTED:
1043: if (!MSG_ISIDENTIFY(sc->sc_imess[0])) {
1044: printf("%s: reselect without IDENTIFY; "
1045: "sending DEVICE RESET\n", sc->sc_dev.dv_xname);
1046: SPC_BREAK();
1047: goto reset;
1048: }
1049:
1050: (void) spc_reselect(sc, sc->sc_imess[0]);
1051: break;
1052:
1053: default:
1054: printf("%s: unexpected MESSAGE IN; sending DEVICE RESET\n",
1055: sc->sc_dev.dv_xname);
1056: SPC_BREAK();
1057: reset:
1058: spc_sched_msgout(sc, SEND_DEV_RESET);
1059: break;
1060:
1061: #ifdef notdef
1062: abort:
1063: spc_sched_msgout(sc, SEND_ABORT);
1064: break;
1065: #endif
1066: }
1067:
1068: /* Ack the last message byte. */
1069: spc_write(SCMD, SCMD_SET_ACK);
1070: while ((spc_read(PSNS) & PSNS_REQ) != 0)
1071: DELAY(1); /* XXX needs timeout */
1072: spc_write(SCMD, SCMD_RST_ACK);
1073:
1074: /* Go get the next message, if any. */
1075: goto nextmsg;
1076:
1077: out:
1078: SPC_MISC(("n=%d imess=0x%02x ", n, sc->sc_imess[0]));
1079: }
1080:
1081: /*
1082: * Send the highest priority, scheduled message.
1083: */
1084: void
1085: spc_msgout(struct spc_softc *sc)
1086: {
1087: #if SPC_USE_SYNCHRONOUS
1088: struct spc_tinfo *ti;
1089: #endif
1090: int n;
1091:
1092: SPC_TRACE(("spc_msgout "));
1093:
1094: if (sc->sc_prevphase == PH_MSGOUT) {
1095: if (sc->sc_omp == sc->sc_omess) {
1096: /*
1097: * This is a retransmission.
1098: *
1099: * We get here if the target stayed in MESSAGE OUT
1100: * phase. Section 5.1.9.2 of the SCSI 2 spec indicates
1101: * that all of the previously transmitted messages must
1102: * be sent again, in the same order. Therefore, we
1103: * requeue all the previously transmitted messages, and
1104: * start again from the top. Our simple priority
1105: * scheme keeps the messages in the right order.
1106: */
1107: SPC_MISC(("retransmitting "));
1108: sc->sc_msgpriq |= sc->sc_msgoutq;
1109: /*
1110: * Set ATN. If we're just sending a trivial 1-byte
1111: * message, we'll clear ATN later on anyway.
1112: */
1113: spc_write(SCMD, SCMD_SET_ATN); /* XXX? */
1114: } else {
1115: /* This is a continuation of the previous message. */
1116: n = sc->sc_omp - sc->sc_omess;
1117: goto nextbyte;
1118: }
1119: }
1120:
1121: /* No messages transmitted so far. */
1122: sc->sc_msgoutq = 0;
1123: sc->sc_lastmsg = 0;
1124:
1125: nextmsg:
1126: /* Pick up highest priority message. */
1127: sc->sc_currmsg = sc->sc_msgpriq & -sc->sc_msgpriq;
1128: sc->sc_msgpriq &= ~sc->sc_currmsg;
1129: sc->sc_msgoutq |= sc->sc_currmsg;
1130:
1131: /* Build the outgoing message data. */
1132: switch (sc->sc_currmsg) {
1133: case SEND_IDENTIFY:
1134: SPC_ASSERT(sc->sc_nexus != NULL);
1135: sc->sc_omess[0] =
1136: MSG_IDENTIFY(sc->sc_nexus->xs->sc_link->lun, 1);
1137: n = 1;
1138: break;
1139:
1140: #if SPC_USE_SYNCHRONOUS
1141: case SEND_SDTR:
1142: SPC_ASSERT(sc->sc_nexus != NULL);
1143: ti = &sc->sc_tinfo[sc->sc_nexus->xs->sc_link->target];
1144: sc->sc_omess[4] = MSG_EXTENDED;
1145: sc->sc_omess[3] = MSG_EXT_SDTR_LEN;
1146: sc->sc_omess[2] = MSG_EXT_SDTR;
1147: sc->sc_omess[1] = ti->period >> 2;
1148: sc->sc_omess[0] = ti->offset;
1149: n = 5;
1150: break;
1151: #endif
1152:
1153: #if SPC_USE_WIDE
1154: case SEND_WDTR:
1155: SPC_ASSERT(sc->sc_nexus != NULL);
1156: ti = &sc->sc_tinfo[sc->sc_nexus->xs->sc_link->target];
1157: sc->sc_omess[3] = MSG_EXTENDED;
1158: sc->sc_omess[2] = MSG_EXT_WDTR_LEN;
1159: sc->sc_omess[1] = MSG_EXT_WDTR;
1160: sc->sc_omess[0] = ti->width;
1161: n = 4;
1162: break;
1163: #endif
1164:
1165: case SEND_DEV_RESET:
1166: sc->sc_flags |= SPC_ABORTING;
1167: sc->sc_omess[0] = MSG_BUS_DEV_RESET;
1168: n = 1;
1169: break;
1170:
1171: case SEND_REJECT:
1172: sc->sc_omess[0] = MSG_MESSAGE_REJECT;
1173: n = 1;
1174: break;
1175:
1176: case SEND_PARITY_ERROR:
1177: sc->sc_omess[0] = MSG_PARITY_ERROR;
1178: n = 1;
1179: break;
1180:
1181: case SEND_INIT_DET_ERR:
1182: sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
1183: n = 1;
1184: break;
1185:
1186: case SEND_ABORT:
1187: sc->sc_flags |= SPC_ABORTING;
1188: sc->sc_omess[0] = MSG_ABORT;
1189: n = 1;
1190: break;
1191:
1192: default:
1193: printf("%s: unexpected MESSAGE OUT; sending NOOP\n",
1194: sc->sc_dev.dv_xname);
1195: SPC_BREAK();
1196: sc->sc_omess[0] = MSG_NOOP;
1197: n = 1;
1198: break;
1199: }
1200: sc->sc_omp = &sc->sc_omess[n];
1201:
1202: nextbyte:
1203: /* Send message bytes. */
1204: /* send TRANSFER command. */
1205: spc_write(TCH, n >> 16);
1206: spc_write(TCM, n >> 8);
1207: spc_write(TCL, n);
1208: spc_write(PCTL, sc->sc_phase | PCTL_BFINT_ENAB);
1209: spc_write(SCMD, SCMD_XFR | SCMD_PROG_XFR);
1210: for (;;) {
1211: if ((spc_read(SSTS) & SSTS_BUSY) != 0)
1212: break;
1213: if (spc_read(INTS) != 0)
1214: goto out;
1215: }
1216: for (;;) {
1217: #if 0
1218: for (;;) {
1219: if ((spc_read(PSNS) & PSNS_REQ) != 0)
1220: break;
1221: /* Wait for REQINIT. XXX Need timeout. */
1222: }
1223: #endif
1224: if (spc_read(INTS) != 0) {
1225: /*
1226: * Target left MESSAGE OUT, possibly to reject
1227: * our message.
1228: *
1229: * If this is the last message being sent, then we
1230: * deassert ATN, since either the target is going to
1231: * ignore this message, or it's going to ask for a
1232: * retransmission via MESSAGE PARITY ERROR (in which
1233: * case we reassert ATN anyway).
1234: */
1235: #if 0
1236: if (sc->sc_msgpriq == 0)
1237: spc_write(SCMD, SCMD_RST_ATN);
1238: #endif
1239: goto out;
1240: }
1241:
1242: #if 0
1243: /* Clear ATN before last byte if this is the last message. */
1244: if (n == 1 && sc->sc_msgpriq == 0)
1245: spc_write(SCMD, SCMD_RST_ATN);
1246: #endif
1247:
1248: while ((spc_read(SSTS) & SSTS_DREG_FULL) != 0)
1249: DELAY(1);
1250: /* Send message byte. */
1251: spc_write(DREG, *--sc->sc_omp);
1252: --n;
1253: /* Keep track of the last message we've sent any bytes of. */
1254: sc->sc_lastmsg = sc->sc_currmsg;
1255: #if 0
1256: /* Wait for ACK to be negated. XXX Need timeout. */
1257: while ((spc_read(PSNS) & ACKI) != 0)
1258: ;
1259: #endif
1260:
1261: if (n == 0)
1262: break;
1263: }
1264:
1265: /* We get here only if the entire message has been transmitted. */
1266: if (sc->sc_msgpriq != 0) {
1267: /* There are more outgoing messages. */
1268: goto nextmsg;
1269: }
1270:
1271: /*
1272: * The last message has been transmitted. We need to remember the last
1273: * message transmitted (in case the target switches to MESSAGE IN phase
1274: * and sends a MESSAGE REJECT), and the list of messages transmitted
1275: * this time around (in case the target stays in MESSAGE OUT phase to
1276: * request a retransmit).
1277: */
1278:
1279: out:
1280: /* Disable REQ/ACK protocol. */
1281: return;
1282: }
1283:
1284: /*
1285: * spc_dataout_pio: perform a data transfer using the FIFO datapath in the spc
1286: * Precondition: The SCSI bus should be in the DOUT phase, with REQ asserted
1287: * and ACK deasserted (i.e. waiting for a data byte).
1288: *
1289: * This new revision has been optimized (I tried) to make the common case fast,
1290: * and the rarer cases (as a result) somewhat more complex.
1291: */
1292: int
1293: spc_dataout_pio(struct spc_softc *sc, u_char *p, int n)
1294: {
1295: u_char intstat = 0;
1296: int out = 0;
1297: #define DOUTAMOUNT 8 /* Full FIFO */
1298:
1299: SPC_TRACE(("spc_dataout_pio "));
1300: /* send TRANSFER command. */
1301: spc_write(TCH, n >> 16);
1302: spc_write(TCM, n >> 8);
1303: spc_write(TCL, n);
1304: spc_write(PCTL, sc->sc_phase | PCTL_BFINT_ENAB);
1305: spc_write(SCMD, SCMD_XFR | SCMD_PROG_XFR); /* XXX */
1306: for (;;) {
1307: if ((spc_read(SSTS) & SSTS_BUSY) != 0)
1308: break;
1309: if (spc_read(INTS) != 0)
1310: break;
1311: }
1312:
1313: /*
1314: * I have tried to make the main loop as tight as possible. This
1315: * means that some of the code following the loop is a bit more
1316: * complex than otherwise.
1317: */
1318: while (n > 0) {
1319: int xfer;
1320:
1321: for (;;) {
1322: intstat = spc_read(INTS);
1323: /* Wait till buffer is empty. */
1324: if ((spc_read(SSTS) & SSTS_DREG_EMPTY) != 0)
1325: break;
1326: /* Break on interrupt. */
1327: if (intstat != 0)
1328: goto phasechange;
1329: DELAY(1);
1330: }
1331:
1332: xfer = min(DOUTAMOUNT, n);
1333:
1334: SPC_MISC(("%d> ", xfer));
1335:
1336: n -= xfer;
1337: out += xfer;
1338:
1339: while (xfer-- > 0)
1340: spc_write(DREG, *p++);
1341: }
1342:
1343: if (out == 0) {
1344: for (;;) {
1345: if (spc_read(INTS) != 0)
1346: break;
1347: DELAY(1);
1348: }
1349: SPC_MISC(("extra data "));
1350: } else {
1351: /* See the bytes off chip */
1352: for (;;) {
1353: /* Wait till buffer is empty. */
1354: if ((spc_read(SSTS) & SSTS_DREG_EMPTY) != 0)
1355: break;
1356: intstat = spc_read(INTS);
1357: /* Break on interrupt. */
1358: if (intstat != 0)
1359: goto phasechange;
1360: DELAY(1);
1361: }
1362: }
1363:
1364: phasechange:
1365: /* Stop the FIFO data path. */
1366:
1367: if (intstat != 0) {
1368: /* Some sort of phase change. */
1369: int amount;
1370:
1371: amount = ((spc_read(TCH) << 16) |
1372: (spc_read(TCM) << 8) | spc_read(TCL));
1373: if (amount > 0) {
1374: out -= amount;
1375: SPC_MISC(("+%d ", amount));
1376: }
1377: }
1378:
1379: return out;
1380: }
1381:
1382: /*
1383: * spc_datain_pio: perform data transfers using the FIFO datapath in the spc
1384: * Precondition: The SCSI bus should be in the DIN phase, with REQ asserted
1385: * and ACK deasserted (i.e. at least one byte is ready).
1386: *
1387: * For now, uses a pretty dumb algorithm, hangs around until all data has been
1388: * transferred. This, is OK for fast targets, but not so smart for slow
1389: * targets which don't disconnect or for huge transfers.
1390: */
1391: int
1392: spc_datain_pio(struct spc_softc *sc, u_char *p, int n)
1393: {
1394: int in = 0;
1395: u_int8_t intstat, sstat;
1396: #define DINAMOUNT 8 /* Full FIFO */
1397:
1398: SPC_TRACE(("spc_datain_pio "));
1399: /* send TRANSFER command. */
1400: spc_write(TCH, n >> 16);
1401: spc_write(TCM, n >> 8);
1402: spc_write(TCL, n);
1403: spc_write(PCTL, sc->sc_phase | PCTL_BFINT_ENAB);
1404: spc_write(SCMD, SCMD_XFR | SCMD_PROG_XFR); /* XXX */
1405:
1406: /*
1407: * We leave this loop if one or more of the following is true:
1408: * a) phase != PH_DATAIN && FIFOs are empty
1409: * b) reset has occurred or busfree is detected.
1410: */
1411: intstat = 0;
1412: while (n > 0) {
1413: int xfer;
1414:
1415: sstat = spc_read(SSTS);
1416: if ((sstat & SSTS_DREG_FULL) != 0) {
1417: xfer = DINAMOUNT;
1418: n -= xfer;
1419: in += xfer;
1420: while (xfer-- > 0)
1421: *p++ = spc_read(DREG);
1422: } else if ((sstat & SSTS_DREG_EMPTY) == 0) {
1423: n--;
1424: in++;
1425: *p++ = spc_read(DREG);
1426: } else {
1427: if (intstat != 0)
1428: goto phasechange;
1429: intstat = spc_read(INTS);
1430: }
1431: }
1432:
1433: /*
1434: * Some SCSI-devices are rude enough to transfer more data than what
1435: * was requested, e.g. 2048 bytes from a CD-ROM instead of the
1436: * requested 512. Test for progress, i.e. real transfers. If no real
1437: * transfers have been performed (n is probably already zero) and the
1438: * FIFO is not empty, waste some bytes....
1439: */
1440: if (in == 0) {
1441: for (;;) {
1442: sstat = spc_read(SSTS);
1443: if ((sstat & SSTS_DREG_EMPTY) == 0) {
1444: (void) spc_read(DREG);
1445: } else {
1446: if (intstat != 0)
1447: goto phasechange;
1448: intstat = spc_read(INTS);
1449: }
1450: DELAY(1);
1451: }
1452: SPC_MISC(("extra data "));
1453: }
1454:
1455: phasechange:
1456: /* Stop the FIFO data path. */
1457:
1458: return in;
1459: }
1460:
1461: /*
1462: * Catch an interrupt from the adaptor
1463: */
1464: int
1465: spc_intr(void *arg)
1466: {
1467: struct spc_softc *sc = arg;
1468: u_char ints;
1469:
1470: SPC_TRACE(("spc_intr "));
1471:
1472: /*
1473: * Disable interrupt.
1474: */
1475: spc_write(SCTL, spc_read(SCTL) & ~SCTL_INTR_ENAB);
1476:
1477: ints = spc_read(INTS);
1478: if (ints != 0)
1479: spc_process_intr(arg, ints);
1480:
1481: spc_write(SCTL, spc_read(SCTL) | SCTL_INTR_ENAB);
1482: return 1;
1483: }
1484:
1485: void
1486: spc_process_intr(void *arg, u_char ints)
1487: {
1488: struct spc_softc *sc = arg;
1489: struct spc_acb *acb;
1490: struct scsi_link *sc_link;
1491: struct spc_tinfo *ti;
1492: int n;
1493:
1494: SPC_TRACE(("spc_process_intr "));
1495:
1496: goto start;
1497:
1498: loop:
1499: /*
1500: * Loop until transfer completion.
1501: */
1502: ints = spc_read(INTS);
1503: start:
1504: SPC_MISC(("ints = 0x%x ", ints));
1505:
1506: /*
1507: * Check for the end of a DMA operation before doing anything else...
1508: */
1509: if ((sc->sc_flags & SPC_DOINGDMA) != 0) {
1510: (*sc->sc_dma_done)(sc);
1511: }
1512:
1513: /*
1514: * Then check for abnormal conditions, such as reset.
1515: */
1516: if ((ints & INTS_RST) != 0) {
1517: printf("%s: SCSI bus reset\n", sc->sc_dev.dv_xname);
1518: goto reset;
1519: }
1520:
1521: /*
1522: * Check for less serious errors.
1523: */
1524: if ((spc_read(SERR) & (SERR_SCSI_PAR|SERR_SPC_PAR))
1525: != 0) {
1526: printf("%s: SCSI bus parity error\n", sc->sc_dev.dv_xname);
1527: if (sc->sc_prevphase == PH_MSGIN) {
1528: sc->sc_flags |= SPC_DROP_MSGIN;
1529: spc_sched_msgout(sc, SEND_PARITY_ERROR);
1530: } else
1531: spc_sched_msgout(sc, SEND_INIT_DET_ERR);
1532: }
1533:
1534: /*
1535: * If we're not already busy doing something test for the following
1536: * conditions:
1537: * 1) We have been reselected by something
1538: * 2) We have selected something successfully
1539: * 3) Our selection process has timed out
1540: * 4) This is really a bus free interrupt just to get a new command
1541: * going?
1542: * 5) Spurious interrupt?
1543: */
1544: switch (sc->sc_state) {
1545: case SPC_IDLE:
1546: case SPC_SELECTING:
1547: SPC_MISC(("ints:0x%02x ", ints));
1548:
1549: if ((ints & INTS_SEL) != 0) {
1550: /*
1551: * We don't currently support target mode.
1552: */
1553: printf("%s: target mode selected; going to BUS FREE\n",
1554: sc->sc_dev.dv_xname);
1555:
1556: goto sched;
1557: } else if ((ints & INTS_RESEL) != 0) {
1558: SPC_MISC(("reselected "));
1559:
1560: /*
1561: * If we're trying to select a target ourselves,
1562: * push our command back into the ready list.
1563: */
1564: if (sc->sc_state == SPC_SELECTING) {
1565: SPC_MISC(("backoff selector "));
1566: SPC_ASSERT(sc->sc_nexus != NULL);
1567: acb = sc->sc_nexus;
1568: sc->sc_nexus = NULL;
1569: TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
1570: }
1571:
1572: /* Save reselection ID. */
1573: sc->sc_selid = spc_read(TEMP);
1574:
1575: sc->sc_state = SPC_RESELECTED;
1576: } else if ((ints & INTS_CMD_DONE) != 0) {
1577: SPC_MISC(("selected "));
1578:
1579: /*
1580: * We have selected a target. Things to do:
1581: * a) Determine what message(s) to send.
1582: * b) Verify that we're still selecting the target.
1583: * c) Mark device as busy.
1584: */
1585: if (sc->sc_state != SPC_SELECTING) {
1586: printf("%s: selection out while idle; "
1587: "resetting\n", sc->sc_dev.dv_xname);
1588: SPC_BREAK();
1589: goto reset;
1590: }
1591: SPC_ASSERT(sc->sc_nexus != NULL);
1592: acb = sc->sc_nexus;
1593: sc_link = acb->xs->sc_link;
1594: ti = &sc->sc_tinfo[sc_link->target];
1595:
1596: sc->sc_msgpriq = SEND_IDENTIFY;
1597: if (acb->flags & ACB_RESET)
1598: sc->sc_msgpriq |= SEND_DEV_RESET;
1599: else if (acb->flags & ACB_ABORT)
1600: sc->sc_msgpriq |= SEND_ABORT;
1601: else {
1602: #if SPC_USE_SYNCHRONOUS
1603: if ((ti->flags & DO_SYNC) != 0)
1604: sc->sc_msgpriq |= SEND_SDTR;
1605: #endif
1606: #if SPC_USE_WIDE
1607: if ((ti->flags & DO_WIDE) != 0)
1608: sc->sc_msgpriq |= SEND_WDTR;
1609: #endif
1610: }
1611:
1612: acb->flags |= ACB_NEXUS;
1613: ti->lubusy |= (1 << sc_link->lun);
1614:
1615: /* Do an implicit RESTORE POINTERS. */
1616: sc->sc_dp = acb->data_addr;
1617: sc->sc_dleft = acb->data_length;
1618: sc->sc_cp = (u_char *)&acb->scsi_cmd;
1619: sc->sc_cleft = acb->scsi_cmd_length;
1620:
1621: /* On our first connection, schedule a timeout. */
1622: if ((acb->xs->flags & SCSI_POLL) == 0) {
1623: timeout_set(&acb->xs->stimeout, spc_timeout,
1624: acb);
1625: timeout_add(&acb->xs->stimeout,
1626: (acb->timeout * hz) / 1000);
1627: }
1628: sc->sc_state = SPC_CONNECTED;
1629: } else if ((ints & INTS_TIMEOUT) != 0) {
1630: SPC_MISC(("selection timeout "));
1631:
1632: if (sc->sc_state != SPC_SELECTING) {
1633: printf("%s: selection timeout while idle; "
1634: "resetting\n", sc->sc_dev.dv_xname);
1635: SPC_BREAK();
1636: goto reset;
1637: }
1638: SPC_ASSERT(sc->sc_nexus != NULL);
1639: acb = sc->sc_nexus;
1640:
1641: delay(250);
1642:
1643: acb->xs->error = XS_SELTIMEOUT;
1644: goto finish;
1645: } else {
1646: if (sc->sc_state != SPC_IDLE) {
1647: printf("%s: BUS FREE while not idle; "
1648: "state=%d\n",
1649: sc->sc_dev.dv_xname, sc->sc_state);
1650: SPC_BREAK();
1651: goto out;
1652: }
1653:
1654: goto sched;
1655: }
1656:
1657: /*
1658: * Turn off selection stuff, and prepare to catch bus free
1659: * interrupts, parity errors, and phase changes.
1660: */
1661:
1662: sc->sc_flags = 0;
1663: sc->sc_prevphase = PH_INVALID;
1664: goto dophase;
1665: }
1666:
1667: if ((ints & INTS_DISCON) != 0) {
1668: /* disable disconnect interrupt */
1669: spc_write(PCTL, spc_read(PCTL) & ~PCTL_BFINT_ENAB);
1670: /* XXX reset interrput */
1671: spc_write(INTS, ints);
1672:
1673: switch (sc->sc_state) {
1674: case SPC_RESELECTED:
1675: goto sched;
1676:
1677: case SPC_CONNECTED:
1678: SPC_ASSERT(sc->sc_nexus != NULL);
1679: acb = sc->sc_nexus;
1680:
1681: #if SPC_USE_SYNCHRONOUS + SPC_USE_WIDE
1682: if (sc->sc_prevphase == PH_MSGOUT) {
1683: /*
1684: * If the target went to BUS FREE phase during
1685: * or immediately after sending a SDTR or WDTR
1686: * message, disable negotiation.
1687: */
1688: sc_link = acb->xs->sc_link;
1689: ti = &sc->sc_tinfo[sc_link->target];
1690: switch (sc->sc_lastmsg) {
1691: #if SPC_USE_SYNCHRONOUS
1692: case SEND_SDTR:
1693: ti->flags &= ~DO_SYNC;
1694: ti->period = ti->offset = 0;
1695: break;
1696: #endif
1697: #if SPC_USE_WIDE
1698: case SEND_WDTR:
1699: ti->flags &= ~DO_WIDE;
1700: ti->width = 0;
1701: break;
1702: #endif
1703: }
1704: }
1705: #endif
1706:
1707: if ((sc->sc_flags & SPC_ABORTING) == 0) {
1708: /*
1709: * Section 5.1.1 of the SCSI 2 spec suggests
1710: * issuing a REQUEST SENSE following an
1711: * unexpected disconnect. Some devices go into
1712: * a contingent allegiance condition when
1713: * disconnecting, and this is necessary to
1714: * clean up their state.
1715: */
1716: printf("%s: unexpected disconnect; "
1717: "sending REQUEST SENSE\n",
1718: sc->sc_dev.dv_xname);
1719: SPC_BREAK();
1720: spc_sense(sc, acb);
1721: goto out;
1722: }
1723:
1724: acb->xs->error = XS_DRIVER_STUFFUP;
1725: goto finish;
1726:
1727: case SPC_DISCONNECT:
1728: SPC_ASSERT(sc->sc_nexus != NULL);
1729: acb = sc->sc_nexus;
1730: TAILQ_INSERT_HEAD(&sc->nexus_list, acb, chain);
1731: sc->sc_nexus = NULL;
1732: goto sched;
1733:
1734: case SPC_CMDCOMPLETE:
1735: SPC_ASSERT(sc->sc_nexus != NULL);
1736: acb = sc->sc_nexus;
1737: goto finish;
1738: }
1739: }
1740: else if ((ints & INTS_CMD_DONE) != 0 &&
1741: sc->sc_prevphase == PH_MSGIN &&
1742: sc->sc_state != SPC_CONNECTED)
1743: goto out;
1744:
1745: /*
1746: * Do not change phase (yet) if we have a pending DMA operation.
1747: */
1748: if ((sc->sc_flags & SPC_DOINGDMA) != 0) {
1749: goto out;
1750: }
1751:
1752: dophase:
1753: #if 0
1754: if ((spc_read(PSNS) & PSNS_REQ) == 0) {
1755: /* Wait for REQINIT. */
1756: goto out;
1757: }
1758: #else
1759: spc_write(INTS, ints);
1760: while ((spc_read(PSNS) & PSNS_REQ) == 0)
1761: DELAY(1); /* need timeout XXX */
1762: #endif
1763:
1764: /*
1765: * State transition.
1766: */
1767: sc->sc_phase = spc_read(PSNS) & PH_MASK;
1768: #if 0
1769: spc_write(PCTL, sc->sc_phase);
1770: #endif
1771:
1772: SPC_MISC(("phase=%d\n", sc->sc_phase));
1773: switch (sc->sc_phase) {
1774: case PH_MSGOUT:
1775: if (sc->sc_state != SPC_CONNECTED &&
1776: sc->sc_state != SPC_RESELECTED)
1777: break;
1778: spc_msgout(sc);
1779: sc->sc_prevphase = PH_MSGOUT;
1780: goto loop;
1781:
1782: case PH_MSGIN:
1783: if (sc->sc_state != SPC_CONNECTED &&
1784: sc->sc_state != SPC_RESELECTED)
1785: break;
1786: spc_msgin(sc);
1787: sc->sc_prevphase = PH_MSGIN;
1788: goto loop;
1789:
1790: case PH_CMD:
1791: if (sc->sc_state != SPC_CONNECTED)
1792: break;
1793: #ifdef SPC_DEBUG
1794: if ((spc_debug & SPC_SHOWMISC) != 0) {
1795: SPC_ASSERT(sc->sc_nexus != NULL);
1796: acb = sc->sc_nexus;
1797: printf("cmd=0x%02x+%d ",
1798: acb->scsi_cmd.opcode, acb->scsi_cmd_length - 1);
1799: }
1800: #endif
1801: n = spc_dataout_pio(sc, sc->sc_cp, sc->sc_cleft);
1802: sc->sc_cp += n;
1803: sc->sc_cleft -= n;
1804: sc->sc_prevphase = PH_CMD;
1805: goto loop;
1806:
1807: case PH_DATAOUT:
1808: if (sc->sc_state != SPC_CONNECTED)
1809: break;
1810: SPC_MISC(("dataout dleft=%d ", sc->sc_dleft));
1811: if (sc->sc_dma_start != NULL &&
1812: sc->sc_dleft > SPC_MIN_DMA_LEN) {
1813: if ((*sc->sc_dma_start)
1814: (sc, sc->sc_dp, sc->sc_dleft, 0) == 0) {
1815: sc->sc_prevphase = PH_DATAOUT;
1816: goto out;
1817: }
1818: }
1819: n = spc_dataout_pio(sc, sc->sc_dp, sc->sc_dleft);
1820: sc->sc_dp += n;
1821: sc->sc_dleft -= n;
1822: sc->sc_prevphase = PH_DATAOUT;
1823: goto loop;
1824:
1825: case PH_DATAIN:
1826: if (sc->sc_state != SPC_CONNECTED)
1827: break;
1828: SPC_MISC(("datain "));
1829: if (sc->sc_dma_start != NULL &&
1830: sc->sc_dleft > SPC_MIN_DMA_LEN) {
1831: if ((*sc->sc_dma_start)
1832: (sc, sc->sc_dp, sc->sc_dleft, 1) == 0) {
1833: sc->sc_prevphase = PH_DATAIN;
1834: goto out;
1835: }
1836: }
1837: n = spc_datain_pio(sc, sc->sc_dp, sc->sc_dleft);
1838: sc->sc_dp += n;
1839: sc->sc_dleft -= n;
1840: sc->sc_prevphase = PH_DATAIN;
1841: goto loop;
1842:
1843: case PH_STAT:
1844: if (sc->sc_state != SPC_CONNECTED)
1845: break;
1846: SPC_ASSERT(sc->sc_nexus != NULL);
1847: acb = sc->sc_nexus;
1848: if ((spc_read(PSNS) & PSNS_ATN) != 0)
1849: spc_write(SCMD, SCMD_RST_ATN);
1850: spc_write(PCTL, PCTL_BFINT_ENAB | PH_STAT);
1851: while ((spc_read(PSNS) & PSNS_REQ) == 0)
1852: DELAY(1); /* XXX needs timeout */
1853: acb->target_stat = spc_read(TEMP);
1854: spc_write(SCMD, SCMD_SET_ACK);
1855: while ((spc_read(PSNS) & PSNS_REQ) != 0)
1856: DELAY(1); /* XXX needs timeout */
1857: spc_write(SCMD, SCMD_RST_ACK);
1858:
1859: SPC_MISC(("target_stat=0x%02x ", acb->target_stat));
1860: sc->sc_prevphase = PH_STAT;
1861: goto loop;
1862: }
1863:
1864: printf("%s: unexpected bus phase; resetting\n", sc->sc_dev.dv_xname);
1865: SPC_BREAK();
1866: reset:
1867: spc_init(sc);
1868: return;
1869:
1870: finish:
1871: spc_write(INTS, ints);
1872: ints = 0;
1873: spc_done(sc, acb);
1874: return;
1875:
1876: sched:
1877: sc->sc_state = SPC_IDLE;
1878: spc_sched(sc);
1879: goto out;
1880:
1881: out:
1882: if (ints != 0)
1883: spc_write(INTS, ints);
1884: }
1885:
1886: void
1887: spc_abort(struct spc_softc *sc, struct spc_acb *acb)
1888: {
1889: /* 2 secs for the abort */
1890: acb->timeout = SPC_ABORT_TIMEOUT;
1891: acb->flags |= ACB_ABORT;
1892:
1893: if (acb == sc->sc_nexus) {
1894: /*
1895: * If we're still selecting, the message will be scheduled
1896: * after selection is complete.
1897: */
1898: if (sc->sc_state == SPC_CONNECTED)
1899: spc_sched_msgout(sc, SEND_ABORT);
1900: } else {
1901: spc_dequeue(sc, acb);
1902: TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
1903: if (sc->sc_state == SPC_IDLE)
1904: spc_sched(sc);
1905: }
1906: }
1907:
1908: void
1909: spc_timeout(void *arg)
1910: {
1911: struct spc_acb *acb = arg;
1912: struct scsi_xfer *xs = acb->xs;
1913: struct scsi_link *sc_link = xs->sc_link;
1914: struct spc_softc *sc = sc_link->adapter_softc;
1915: int s;
1916:
1917: sc_print_addr(sc_link);
1918:
1919: s = splbio();
1920:
1921: /*
1922: * We might have missed a DMA completion.
1923: * If so, fake an interrupt (even if the INTS register is zero - what
1924: * we want here is to change phase).
1925: */
1926: if ((sc->sc_flags & SPC_DOINGDMA) != 0) {
1927: if ((*sc->sc_dma_done)(sc)) {
1928: printf("missed DMA completion\n");
1929: spc_process_intr(sc, spc_read(INTS));
1930: splx(s);
1931: return;
1932: }
1933: }
1934:
1935: printf("timed out");
1936: if (acb->flags & ACB_ABORT) {
1937: /* abort timed out */
1938: printf(" AGAIN\n");
1939: /* XXX Must reset! */
1940: } else {
1941: /* abort the operation that has timed out */
1942: printf("\n");
1943: acb->xs->error = XS_TIMEOUT;
1944: spc_abort(sc, acb);
1945: }
1946:
1947: splx(s);
1948: }
1949:
1950: #ifdef SPC_DEBUG
1951: /*
1952: * The following functions are mostly used for debugging purposes, either
1953: * directly called from the driver or from the kernel debugger.
1954: */
1955:
1956: void
1957: spc_show_scsi_cmd(struct spc_acb *acb)
1958: {
1959: u_char *b = (u_char *)&acb->scsi_cmd;
1960: struct scsi_link *sc_link = acb->xs->sc_link;
1961: int i;
1962:
1963: sc_print_addr(sc_link);
1964: if ((acb->xs->flags & SCSI_RESET) == 0) {
1965: for (i = 0; i < acb->scsi_cmd_length; i++) {
1966: if (i)
1967: printf(",");
1968: printf("%x", b[i]);
1969: }
1970: printf("\n");
1971: } else
1972: printf("RESET\n");
1973: }
1974:
1975: void
1976: spc_print_acb(struct spc_acb *acb)
1977: {
1978: printf("acb@%p xs=%p flags=%x", acb, acb->xs, acb->flags);
1979: printf(" dp=%p dleft=%d target_stat=%x\n",
1980: acb->data_addr, acb->data_length, acb->target_stat);
1981: spc_show_scsi_cmd(acb);
1982: }
1983:
1984: void
1985: spc_print_active_acb(void)
1986: {
1987: struct spc_acb *acb;
1988: struct spc_softc *sc = spc_cd.cd_devs[0]; /* XXX */
1989:
1990: printf("ready list:\n");
1991: TAILQ_FOREACH(acb, &sc->ready_list, chain)
1992: spc_print_acb(acb);
1993: printf("nexus:\n");
1994: if (sc->sc_nexus != NULL)
1995: spc_print_acb(sc->sc_nexus);
1996: printf("nexus list:\n");
1997: TAILQ_FOREACH(acb, &sc->nexus_list, chain)
1998: spc_print_acb(acb);
1999: }
2000:
2001: void
2002: spc_dump89352(struct spc_softc *sc)
2003: {
2004: printf("mb89352: BDID=%x SCTL=%x SCMD=%x TMOD=%x\n",
2005: spc_read(BDID), spc_read(SCTL), spc_read(SCMD), spc_read(TMOD));
2006: printf(" INTS=%x PSNS=%x SSTS=%x SERR=%x PCTL=%x\n",
2007: spc_read(INTS), spc_read(PSNS), spc_read(SSTS), spc_read(SERR),
2008: spc_read(PCTL));
2009: printf(" MBC=%x DREG=%x TEMP=%x TCH=%x TCM=%x\n",
2010: spc_read(MBC),
2011: #if 0
2012: spc_read(DREG),
2013: #else
2014: 0,
2015: #endif
2016: spc_read(TEMP), spc_read(TCH), spc_read(TCM));
2017: printf(" TCL=%x EXBF=%x\n", spc_read(TCL), spc_read(EXBF));
2018: }
2019:
2020: void
2021: spc_dump_driver(struct spc_softc *sc)
2022: {
2023: struct spc_tinfo *ti;
2024: int i;
2025:
2026: printf("nexus=%p phase=%x prevphase=%x\n",
2027: sc->sc_nexus, sc->sc_phase, sc->sc_prevphase);
2028: printf("state=%x msgin=%x msgpriq=%x msgoutq=%x lastmsg=%x "
2029: "currmsg=%x\n", sc->sc_state, sc->sc_imess[0],
2030: sc->sc_msgpriq, sc->sc_msgoutq, sc->sc_lastmsg, sc->sc_currmsg);
2031: for (i = 0; i < 7; i++) {
2032: ti = &sc->sc_tinfo[i];
2033: printf("tinfo%d: %d cmds %d disconnects %d timeouts",
2034: i, ti->cmds, ti->dconns, ti->touts);
2035: printf(" %d senses flags=%x\n", ti->senses, ti->flags);
2036: }
2037: }
2038: #endif
CVSweb