Annotation of sys/arch/mvme68k/dev/sbic.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: sbic.c,v 1.19 2007/05/29 13:56:14 pyr Exp $ */
2: /* $NetBSD: sbic.c,v 1.2 1996/04/23 16:32:54 chuck Exp $ */
3:
4: /*
5: * Changes Copyright (c) 1996 Steve Woodford
6: * Original Copyright (c) 1994 Christian E. Hopps
7: * Copyright (c) 1990 The Regents of the University of California.
8: * All rights reserved.
9: *
10: * This code is derived from software contributed to Berkeley by
11: * Van Jacobson of Lawrence Berkeley Laboratory.
12: *
13: * Redistribution and use in source and binary forms, with or without
14: * modification, are permitted provided that the following conditions
15: * are met:
16: * 1. Redistributions of source code must retain the above copyright
17: * notice, this list of conditions and the following disclaimer.
18: * 2. Redistributions in binary form must reproduce the above copyright
19: * notice, this list of conditions and the following disclaimer in the
20: * documentation and/or other materials provided with the distribution.
21: * 3. Neither the name of the University nor the names of its contributors
22: * may be used to endorse or promote products derived from this software
23: * without specific prior written permission.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
36: *
37: * @(#)scsi.c 7.5 (Berkeley) 5/4/91
38: */
39:
40: /*
41: * Steve Woodford (SCW), Apr, 1996
42: * MVME147S WD33C93 Scsi Bus Interface Controller driver,
43: *
44: * Basically a de-loused and tidied up version of the Amiga AMD 33C93 driver.
45: *
46: * The original driver used features which required at least a WD33C93A
47: * chip. The '147 has the original WD33C93 chip (no 'A' suffix).
48: *
49: * This version of the driver is pretty well generic, so should work with
50: * any flavour of WD33C93 chip.
51: */
52:
53: #include <sys/param.h>
54: #include <sys/systm.h>
55: #include <sys/device.h>
56: #include <sys/kernel.h> /* For hz */
57: #include <sys/disklabel.h>
58: #include <sys/dkstat.h>
59: #include <sys/buf.h>
60: #include <sys/queue.h>
61: #include <scsi/scsi_all.h>
62: #include <scsi/scsiconf.h>
63: #include <uvm/uvm_extern.h>
64: #include <mvme68k/dev/dmavar.h>
65: #include <mvme68k/dev/sbicreg.h>
66: #include <mvme68k/dev/sbicvar.h>
67: #include <machine/autoconf.h>
68: #include <mvme68k/dev/pccreg.h>
69:
70:
71: /*
72: * Since I can't find this in any other header files
73: */
74: #define SCSI_PHASE(reg) (reg&0x07)
75:
76: /*
77: * SCSI delays
78: * In u-seconds, primarily for state changes on the SPC.
79: */
80: #define SBIC_CMD_WAIT 50000 /* wait per step of 'immediate' cmds */
81: #define SBIC_DATA_WAIT 50000 /* wait per data in/out step */
82: #define SBIC_INIT_WAIT 50000 /* wait per step (both) during init */
83:
84: /*
85: * Convenience macro for waiting for a particular sbic event
86: */
87: #define SBIC_WAIT(regs, until, timeo) sbicwait(regs, until, timeo, __LINE__)
88:
89: int sbicicmd(struct sbic_softc *, void *, int, void *, int);
90: int sbicgo(struct sbic_softc *, struct scsi_xfer *);
91: int sbicdmaok(struct sbic_softc *, struct scsi_xfer *);
92: int sbicwait(sbic_regmap_p, u_char, int , int);
93: int sbiccheckdmap(void *, u_long, u_long);
94: u_char sbicselectbus(struct sbic_softc *);
95: int sbicxfout(sbic_regmap_p, int, void *);
96: int sbicxfin(sbic_regmap_p, int, void *);
97: int sbicfromscsiperiod(struct sbic_softc *, int);
98: int sbictoscsiperiod(struct sbic_softc *, int);
99: int sbicintr(struct sbic_softc *);
100: int sbicpoll(struct sbic_softc *);
101: int sbicnextstate(struct sbic_softc *, u_char, u_char);
102: int sbicmsgin(struct sbic_softc *);
103: int sbicabort(struct sbic_softc *, char *);
104: void sbicxfdone(struct sbic_softc *);
105: void sbicerror(struct sbic_softc *,u_char);
106: void sbicreset(struct sbic_softc *);
107: void sbic_scsidone(struct sbic_acb *, int);
108: void sbic_sched(struct sbic_softc *);
109: void sbic_save_ptrs(struct sbic_softc *);
110: void sbic_load_ptrs(struct sbic_softc *);
111: void sbicinit(struct sbic_softc *);
112:
113: /*
114: * Synch xfer parameters, and timing conversions
115: */
116: int sbic_min_period = SBIC_SYN_MIN_PERIOD; /* in cycles = f(ICLK,FSn) */
117: int sbic_max_offset = SBIC_SYN_MAX_OFFSET; /* pure number */
118: int sbic_cmd_wait = SBIC_CMD_WAIT;
119: int sbic_data_wait = SBIC_DATA_WAIT;
120: int sbic_init_wait = SBIC_INIT_WAIT;
121:
122: /*
123: * was broken before.. now if you want this you get it for all drives
124: * on sbic controllers.
125: */
126: u_char sbic_inhibit_sync[8];
127: int sbic_enable_reselect = 1; /* Allow Disconnect / Reselect */
128: int sbic_no_dma = 0; /* Use PIO transfers instead of DMA */
129: int sbic_parallel_operations = 1; /* Allow command queues */
130:
131: /*
132: * Some useful stuff for debugging purposes
133: */
134: #ifdef DEBUG
135: int sbicdma_ops = 0; /* total DMA operations */
136: int sbicdma_hits = 0; /* number of DMA chains that were contiguous */
137: int sbicdma_misses = 0; /* number of DMA chains that were not contiguous */
138: int sbicdma_saves = 0;
139:
140: #define QPRINTF(a) if (sbic_debug > 1) printf a
141:
142: int sbic_debug = 0; /* Debug all chip related things */
143: int sync_debug = 0; /* Debug all Synchronous Scsi related things */
144: int reselect_debug = 0; /* Debug all reselection related things */
145: int report_sense = 0; /* Always print Sense information */
146: int data_pointer_debug = 0; /* Debug Data Pointer related things */
147:
148: void sbictimeout(struct sbic_softc *dev);
149:
150: #else
151: #define QPRINTF(a) /* */
152: #endif
153:
154:
155: /*
156: * default minphys routine for sbic based controllers
157: */
158: void
159: sbic_minphys(bp)
160: struct buf *bp;
161: {
162: /*
163: * No max transfer at this level.
164: */
165: minphys(bp);
166: }
167:
168:
169: /*
170: * Save DMA pointers. Take into account partial transfer. Shut down DMA.
171: */
172: void
173: sbic_save_ptrs(dev)
174: struct sbic_softc *dev;
175: {
176: sbic_regmap_p regs;
177: struct sbic_acb* acb;
178: int count,
179: asr,
180: s;
181:
182: /*
183: * Only need to save pointers if DMA was active...
184: */
185: if ( dev->sc_cur == NULL || (dev->sc_flags & SBICF_INDMA) == 0 )
186: return;
187:
188: regs = dev->sc_sbicp;
189:
190: s = splbio();
191:
192: /*
193: * Wait until WD chip is idle
194: */
195: do {
196: GET_SBIC_asr(regs, asr);
197: if( asr & SBIC_ASR_DBR ) {
198: printf("sbic_save_ptrs: asr %02x canceled!\n", asr);
199: splx(s);
200: return;
201: }
202: } while( asr & (SBIC_ASR_BSY|SBIC_ASR_CIP) );
203:
204:
205: /*
206: * Save important state.
207: * must be done before dmastop
208: */
209: acb = dev->sc_nexus;
210: acb->sc_dmacmd = dev->sc_dmacmd;
211:
212: /*
213: * Fetch the residual count
214: */
215: SBIC_TC_GET(regs, count);
216:
217: /*
218: * Shut down DMA
219: */
220: dev->sc_dmastop(dev);
221:
222: /*
223: * No longer in DMA
224: */
225: dev->sc_flags &= ~SBICF_INDMA;
226:
227: /*
228: * Ensure the WD chip is back in polled I/O mode, with nothing to
229: * transfer.
230: */
231: SBIC_TC_PUT(regs, 0);
232: SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
233:
234: /*
235: * Update current count...
236: */
237: acb->sc_tcnt = count;
238:
239: /*
240: * Work out how many bytes were actually transferred
241: */
242: count = dev->sc_tcnt - count;
243: dev->sc_tcnt = acb->sc_tcnt;
244:
245: /*
246: * Fixup partial xfers
247: */
248: acb->sc_kv.dc_addr += count;
249: acb->sc_kv.dc_count -= count;
250: acb->sc_pa.dc_addr += count;
251: acb->sc_pa.dc_count -= count >> 1;
252:
253: #ifdef DEBUG
254: if ( data_pointer_debug )
255: printf("save at (%x,%x):%x\n",
256: dev->sc_cur->dc_addr, dev->sc_cur->dc_count,count);
257: sbicdma_saves++;
258: #endif
259:
260: splx(s);
261: }
262:
263:
264: /*
265: * DOES NOT RESTART DMA!!!
266: */
267: void
268: sbic_load_ptrs(dev)
269: struct sbic_softc *dev;
270: {
271: struct sbic_acb *acb = dev->sc_nexus;
272: int s;
273:
274: if ( acb->sc_kv.dc_count == 0 ) {
275: /*
276: * No data to xfer
277: */
278: return;
279: }
280:
281: s = splbio();
282:
283: /*
284: * Reset the Scatter-Gather chain
285: */
286: dev->sc_last = dev->sc_cur = &acb->sc_pa;
287:
288: /*
289: * Restore the Transfer Count and DMA specific data
290: */
291: dev->sc_tcnt = acb->sc_tcnt;
292: dev->sc_dmacmd = acb->sc_dmacmd;
293:
294: #ifdef DEBUG
295: sbicdma_ops++;
296: #endif
297:
298: /*
299: * Need to fixup new segment?
300: */
301: if ( dev->sc_tcnt == 0 ) {
302: /*
303: * sc_tcnt == 0 implies end of segment
304: */
305: char *vaddr, *paddr;
306: int count;
307:
308: /*
309: * do kvm to pa mappings
310: */
311: vaddr = acb->sc_kv.dc_addr;
312: paddr = acb->sc_pa.dc_addr = (char *)kvtop((vaddr_t)vaddr);
313:
314: for (count = (NBPG - ((int)vaddr & PGOFSET));
315: count < acb->sc_kv.dc_count &&
316: (char *)kvtop((vaddr_t)vaddr + count + 4) == paddr + count + 4;
317: count += NBPG)
318: ; /* Do nothing */
319:
320: /*
321: * If it's all contiguous...
322: */
323: if ( count > acb->sc_kv.dc_count ) {
324: count = acb->sc_kv.dc_count;
325: #ifdef DEBUG
326: sbicdma_hits++;
327: #endif
328: }
329: #ifdef DEBUG
330: else
331: sbicdma_misses++;
332: #endif
333:
334: acb->sc_tcnt = count;
335: acb->sc_pa.dc_count = count >> 1;
336:
337: #ifdef DEBUG
338: if ( data_pointer_debug )
339: printf("DMA recalc:kv(%x,%x)pa(%x,%x)\n", acb->sc_kv.dc_addr,
340: acb->sc_kv.dc_count,
341: acb->sc_pa.dc_addr,
342: acb->sc_tcnt);
343: #endif
344:
345: }
346:
347: splx(s);
348: }
349:
350: /*
351: * used by specific sbic controller
352: *
353: * it appears that the higher level code does nothing with LUN's
354: * so I will too. I could plug it in, however so could they
355: * in scsi_scsi_cmd().
356: */
357: int
358: sbic_scsicmd(xs)
359: struct scsi_xfer *xs;
360: {
361: struct scsi_link *slp = xs->sc_link;
362: struct sbic_softc *dev = slp->adapter_softc;
363: struct sbic_acb *acb;
364: int flags = xs->flags,
365: s;
366:
367: if ( flags & SCSI_DATA_UIO )
368: panic("sbic: scsi data uio requested");
369:
370: if ( dev->sc_nexus && (flags & SCSI_POLL) )
371: panic("sbic_scsicmd: busy");
372:
373: if ( slp->target == slp->adapter_target )
374: return ESCAPE_NOT_SUPPORTED;
375:
376: s = splbio();
377:
378: if ( (acb = TAILQ_FIRST(&dev->free_list)) != NULL )
379: TAILQ_REMOVE(&dev->free_list, acb, chain);
380:
381: splx(s);
382:
383: if ( acb == NULL ) {
384: #ifdef DEBUG
385: printf("sbic_scsicmd: unable to queue request for target %d\n",
386: slp->target);
387: #ifdef DDB
388: Debugger();
389: #endif
390: #endif
391: return(TRY_AGAIN_LATER);
392: }
393:
394: if ( flags & SCSI_DATA_IN )
395: acb->flags = ACB_ACTIVE | ACB_DATAIN;
396: else
397: acb->flags = ACB_ACTIVE;
398:
399: acb->xs = xs;
400: acb->clen = xs->cmdlen;
401: acb->sc_kv.dc_addr = xs->data;
402: acb->sc_kv.dc_count = xs->datalen;
403: acb->pa_addr = xs->data ? (char *)kvtop((vaddr_t)xs->data) : 0;
404: bcopy(xs->cmd, &acb->cmd, xs->cmdlen);
405:
406: if ( flags & SCSI_POLL ) {
407: /*
408: * This has major side effects -- it locks up the machine
409: */
410: int stat;
411:
412: s = splbio();
413:
414: dev->sc_flags |= SBICF_ICMD;
415:
416: do {
417: /*
418: * If we already had a nexus, while away the time until idle...
419: * This is likely only to happen if a reselection occurs between
420: * here and our earlier check for ICMD && sc_nexus (which would
421: * have resulted in a panic() had it been true).
422: */
423: while ( dev->sc_nexus )
424: sbicpoll(dev);
425:
426: /*
427: * Fix up the new nexus
428: */
429: dev->sc_nexus = acb;
430: dev->sc_xs = xs;
431: dev->target = slp->target;
432: dev->lun = slp->lun;
433:
434: stat = sbicicmd(dev, &acb->cmd, acb->clen,
435: acb->sc_kv.dc_addr, acb->sc_kv.dc_count);
436:
437: } while ( dev->sc_nexus != acb );
438:
439: sbic_scsidone(acb, stat);
440:
441: splx(s);
442:
443: return(COMPLETE);
444: }
445:
446: s = splbio();
447: TAILQ_INSERT_TAIL(&dev->ready_list, acb, chain);
448:
449: /*
450: * If nothing is active, try to start it now.
451: */
452: if ( dev->sc_nexus == NULL )
453: sbic_sched(dev);
454:
455: splx(s);
456:
457: return(SUCCESSFULLY_QUEUED);
458: }
459:
460: /*
461: * attempt to start the next available command
462: */
463: void
464: sbic_sched(dev)
465: struct sbic_softc *dev;
466: {
467: struct scsi_xfer *xs;
468: struct scsi_link *slp = NULL; /* Gag the compiler */
469: struct sbic_acb *acb;
470: int flags,
471: stat;
472:
473: /*
474: * XXXSCW
475: * I'll keep this test here, even though I can't see any obvious way
476: * in which sbic_sched() could be called with sc_nexus non NULL
477: */
478: if ( dev->sc_nexus )
479: return; /* a command is current active */
480:
481: /*
482: * Loop through the ready list looking for work to do...
483: */
484: TAILQ_FOREACH(acb, &dev->ready_list, chain) {
485: int i, j;
486:
487: slp = acb->xs->sc_link;
488: i = slp->target;
489: j = 1 << slp->lun;
490:
491: /*
492: * We've found a potential command, but is the target/lun busy?
493: */
494: if ( (dev->sc_tinfo[i].lubusy & j) == 0 ) {
495: /*
496: * Nope, it's not busy, so we can use it.
497: */
498: dev->sc_tinfo[i].lubusy |= j;
499: TAILQ_REMOVE(&dev->ready_list, acb, chain);
500: dev->sc_nexus = acb;
501: acb->sc_pa.dc_addr = acb->pa_addr; /* XXXX check */
502: break;
503: }
504: }
505:
506: if ( acb == NULL ) {
507: QPRINTF(("sbicsched: no work\n"));
508: return; /* did not find an available command */
509: }
510:
511: #ifdef DEBUG
512: if ( data_pointer_debug > 1 )
513: printf("sbic_sched(%d,%d)\n", slp->target, slp->lun);
514: #endif
515:
516: dev->sc_xs = xs = acb->xs;
517: flags = xs->flags;
518:
519: if ( flags & SCSI_RESET )
520: sbicreset(dev);
521:
522: dev->sc_stat[0] = -1;
523: dev->target = slp->target;
524: dev->lun = slp->lun;
525:
526: if ( flags & SCSI_POLL || (!sbic_parallel_operations &&
527: (sbicdmaok(dev, xs) == 0)) )
528: stat = sbicicmd(dev, &acb->cmd, acb->clen,
529: acb->sc_kv.dc_addr, acb->sc_kv.dc_count);
530: else
531: if ( sbicgo(dev, xs) == 0 )
532: return;
533: else
534: stat = dev->sc_stat[0];
535:
536: sbic_scsidone(acb, stat);
537: }
538:
539: void
540: sbic_scsidone(acb, stat)
541: struct sbic_acb *acb;
542: int stat;
543: {
544: struct scsi_xfer *xs = acb->xs;
545: struct scsi_link *slp = xs->sc_link;
546: struct sbic_softc *dev = slp->adapter_softc;
547: int dosched = 0;
548:
549: #ifdef DIAGNOSTIC
550: if ( acb == NULL || xs == NULL ) {
551: printf("sbic_scsidone -- (%d,%d) no scsi_xfer\n", dev->target, dev->lun);
552: #ifdef DDB
553: Debugger();
554: #endif
555: return;
556: }
557: #endif
558:
559: /*
560: * is this right?
561: */
562: xs->status = stat;
563:
564: #ifdef DEBUG
565: if ( data_pointer_debug > 1 )
566: printf("scsidone: (%d,%d)->(%d,%d)%02x\n", slp->target, slp->lun,
567: dev->target, dev->lun, stat);
568:
569: if ( xs->sc_link->target == dev->sc_link.adapter_target )
570: panic("target == hostid");
571: #endif
572:
573: if ( xs->error == XS_NOERROR && (acb->flags & ACB_CHKSENSE) == 0 ) {
574:
575: if ( stat == SCSI_CHECK ) {
576: /*
577: * Schedule a REQUEST SENSE
578: */
579: struct scsi_sense *ss = (void *)&acb->cmd;
580:
581: #ifdef DEBUG
582: if ( report_sense )
583: printf("sbic_scsidone: autosense %02x targ %d lun %d",
584: acb->cmd.opcode, slp->target, slp->lun);
585: #endif
586:
587: bzero(ss, sizeof(*ss));
588:
589: ss->opcode = REQUEST_SENSE;
590: ss->byte2 = slp->lun << 5;
591: ss->length = sizeof(struct scsi_sense_data);
592:
593: acb->clen = sizeof(*ss);
594: acb->sc_kv.dc_addr = (char *)&xs->sense;
595: acb->sc_kv.dc_count = sizeof(struct scsi_sense_data);
596: acb->pa_addr = (char *)kvtop((vaddr_t)&xs->sense); /* XXX check */
597: acb->flags = ACB_ACTIVE | ACB_CHKSENSE | ACB_DATAIN;
598:
599: TAILQ_INSERT_HEAD(&dev->ready_list, acb, chain);
600:
601: dev->sc_tinfo[slp->target].lubusy &= ~(1 << slp->lun);
602: dev->sc_tinfo[slp->target].senses++;
603:
604: if ( dev->sc_nexus == acb ) {
605: dev->sc_nexus = NULL;
606: dev->sc_xs = NULL;
607: sbic_sched(dev);
608: }
609: return;
610: }
611: }
612:
613: if ( xs->error == XS_NOERROR && (acb->flags & ACB_CHKSENSE) != 0 ) {
614:
615: xs->error = XS_SENSE;
616:
617: #ifdef DEBUG
618: if (report_sense)
619: printf(" => %02x %02x\n", xs->sense.flags,
620: xs->sense.extra_bytes[3]);
621: #endif
622:
623: } else {
624: xs->resid = 0; /* XXXX */
625: }
626:
627: xs->flags |= ITSDONE;
628:
629: /*
630: * Remove the ACB from whatever queue it's on. We have to do a bit of
631: * a hack to figure out which queue it's on. Note that it is *not*
632: * necessary to cdr down the ready queue, but we must cdr down the
633: * nexus queue and see if it's there, so we can mark the unit as no
634: * longer busy. This code is sickening, but it works.
635: */
636: if ( acb == dev->sc_nexus ) {
637:
638: dev->sc_nexus = NULL;
639: dev->sc_xs = NULL;
640:
641: dev->sc_tinfo[slp->target].lubusy &= ~(1 << slp->lun);
642:
643: if ( !TAILQ_EMPTY(&dev->ready_list) )
644: dosched = 1; /* start next command */
645:
646: } else
647: if (TAILQ_LAST(&dev->ready_list, acb_list) == TAILQ_NEXT(acb, chain)) {
648:
649: TAILQ_REMOVE(&dev->ready_list, acb, chain);
650:
651: } else {
652:
653: register struct sbic_acb *a;
654:
655: TAILQ_FOREACH(a, &dev->nexus_list, chain) {
656: if ( a == acb ) {
657: TAILQ_REMOVE(&dev->nexus_list, acb, chain);
658: dev->sc_tinfo[slp->target].lubusy &= ~(1 << slp->lun);
659: break;
660: }
661: }
662:
663: if ( a )
664: ;
665: else if ( TAILQ_NEXT(acb, chain) != NULL) {
666: TAILQ_REMOVE(&dev->ready_list, acb, chain);
667: } else {
668: printf("%s: can't find matching acb\n", dev->sc_dev.dv_xname);
669: #ifdef DDB
670: Debugger();
671: #endif
672: }
673: }
674:
675: /*
676: * Put it on the free list.
677: */
678: acb->flags = ACB_FREE;
679: TAILQ_INSERT_HEAD(&dev->free_list, acb, chain);
680:
681: dev->sc_tinfo[slp->target].cmds++;
682:
683: scsi_done(xs);
684:
685: if ( dosched )
686: sbic_sched(dev);
687: }
688:
689: int
690: sbicdmaok(dev, xs)
691: struct sbic_softc *dev;
692: struct scsi_xfer *xs;
693: {
694: if ( sbic_no_dma || xs->datalen & 0x03 || (int)xs->data & 0x03)
695: return(0);
696:
697: /*
698: * controller supports dma to any addresses?
699: */
700: if ( (dev->sc_flags & SBICF_BADDMA) == 0 )
701: return(1);
702:
703: /*
704: * this address is ok for dma?
705: */
706: if ( sbiccheckdmap(xs->data, xs->datalen, dev->sc_dmamask) == 0 )
707: return(1);
708:
709: return(0);
710: }
711:
712: int
713: sbicwait(regs, until, timeo, line)
714: sbic_regmap_p regs;
715: u_char until;
716: int timeo;
717: int line;
718: {
719: u_char val;
720:
721: if ( timeo == 0 )
722: timeo = 1000000; /* some large value.. */
723:
724: GET_SBIC_asr(regs, val);
725:
726: while ( (val & until) == 0 ) {
727:
728: if ( timeo-- == 0 ) {
729: int csr;
730: GET_SBIC_csr(regs, csr);
731: printf("sbicwait TIMEO @%d with asr=x%x csr=x%x\n", line, val, csr);
732: #if defined(DDB) && defined(DEBUG)
733: Debugger();
734: #endif
735: return(val); /* Maybe I should abort */
736: break;
737: }
738:
739: DELAY(1);
740: GET_SBIC_asr(regs, val);
741: }
742:
743: return(val);
744: }
745:
746: int
747: sbicabort(dev, where)
748: struct sbic_softc *dev;
749: char *where;
750: {
751: sbic_regmap_p regs = dev->sc_sbicp;
752: u_char csr,
753: asr;
754:
755: GET_SBIC_asr(regs, asr);
756: GET_SBIC_csr(regs, csr);
757:
758: printf ("%s: abort %s: csr = 0x%02x, asr = 0x%02x\n",
759: dev->sc_dev.dv_xname, where, csr, asr);
760:
761: /*
762: * Clean up chip itself
763: */
764: if ( dev->sc_flags & SBICF_SELECTED ) {
765:
766: while ( asr & SBIC_ASR_DBR ) {
767: /*
768: * sbic is jammed w/data. need to clear it
769: * But we don't know what direction it needs to go
770: */
771: GET_SBIC_data(regs, asr);
772: printf("%s: abort %s: clearing data buffer 0x%02x\n",
773: dev->sc_dev.dv_xname, where, asr);
774: GET_SBIC_asr(regs, asr);
775: if ( asr & SBIC_ASR_DBR ) /* Not the read direction, then */
776: SET_SBIC_data(regs, asr);
777: GET_SBIC_asr(regs, asr);
778: }
779:
780: WAIT_CIP(regs);
781:
782: printf("%s: sbicabort - sending ABORT command\n", dev->sc_dev.dv_xname);
783: SET_SBIC_cmd(regs, SBIC_CMD_ABORT);
784: WAIT_CIP(regs);
785:
786: GET_SBIC_asr(regs, asr);
787:
788: if ( asr & (SBIC_ASR_BSY|SBIC_ASR_LCI) ) {
789: /*
790: * ok, get more drastic..
791: */
792: printf("%s: sbicabort - asr %x, trying to reset\n",
793: dev->sc_dev.dv_xname, asr);
794: sbicreset(dev);
795: dev->sc_flags &= ~SBICF_SELECTED;
796: return SBIC_STATE_ERROR;
797: }
798:
799: printf("%s: sbicabort - sending DISC command\n", dev->sc_dev.dv_xname);
800: SET_SBIC_cmd(regs, SBIC_CMD_DISC);
801:
802: do {
803: SBIC_WAIT (regs, SBIC_ASR_INT, 0);
804: GET_SBIC_asr(regs, asr);
805: GET_SBIC_csr (regs, csr);
806: QPRINTF(("csr: 0x%02x, asr: 0x%02x\n", csr, asr));
807: } while ( (csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1) &&
808: (csr != SBIC_CSR_CMD_INVALID) );
809:
810: /*
811: * lets just hope it worked..
812: */
813: dev->sc_flags &= ~SBICF_SELECTED;
814: }
815:
816: return SBIC_STATE_ERROR;
817: }
818:
819:
820: /*
821: * Initialize driver-private structures
822: */
823: void
824: sbicinit(dev)
825: struct sbic_softc *dev;
826: {
827: u_int i;
828:
829: extern u_long scsi_nosync;
830: extern int shift_nosync;
831:
832: if ( (dev->sc_flags & SBICF_ALIVE) == 0 ) {
833:
834: struct sbic_acb *acb;
835:
836: TAILQ_INIT(&dev->ready_list);
837: TAILQ_INIT(&dev->nexus_list);
838: TAILQ_INIT(&dev->free_list);
839:
840: dev->sc_nexus = NULL;
841: dev->sc_xs = NULL;
842:
843: acb = dev->sc_acb;
844: bzero(acb, sizeof(dev->sc_acb));
845:
846: for (i = 0; i < sizeof(dev->sc_acb) / sizeof(*acb); i++) {
847: TAILQ_INSERT_TAIL(&dev->free_list, acb, chain);
848: acb++;
849: }
850:
851: bzero(dev->sc_tinfo, sizeof(dev->sc_tinfo));
852:
853: #ifdef DEBUG
854: /*
855: * make sure timeout is really not needed
856: */
857: timeout((void *)sbictimeout, dev, 30 * hz);
858: #endif
859:
860: } else
861: panic("sbic: reinitializing driver!");
862:
863: dev->sc_flags |= SBICF_ALIVE;
864: dev->sc_flags &= ~SBICF_SELECTED;
865:
866: /*
867: * initialize inhibit array
868: */
869: if ( scsi_nosync ) {
870:
871: u_int inhibit_sync = (scsi_nosync >> shift_nosync) & 0xff;
872:
873: shift_nosync += 8;
874:
875: #ifdef DEBUG
876: if ( inhibit_sync )
877: printf("%s: Inhibiting synchronous transfer %02x\n",
878: dev->sc_dev.dv_xname, inhibit_sync);
879: #endif
880: for (i = 0; i < 8; ++i) {
881: if ( inhibit_sync & (1 << i) )
882: sbic_inhibit_sync[i] = 1;
883: }
884: }
885:
886: sbicreset(dev);
887: }
888:
889: void
890: sbicreset(dev)
891: struct sbic_softc *dev;
892: {
893: sbic_regmap_p regs = dev->sc_sbicp;
894: u_int my_id,
895: s;
896: u_char csr;
897:
898: s = splbio();
899:
900: my_id = dev->sc_link.adapter_target & SBIC_ID_MASK;
901:
902: if (dev->sc_clkfreq < 110)
903: my_id |= SBIC_ID_FS_8_10;
904: else if (dev->sc_clkfreq < 160)
905: my_id |= SBIC_ID_FS_12_15;
906: else if (dev->sc_clkfreq < 210)
907: my_id |= SBIC_ID_FS_16_20;
908:
909: SET_SBIC_myid(regs, my_id);
910:
911: /*
912: * Reset the chip
913: */
914: SET_SBIC_cmd(regs, SBIC_CMD_RESET);
915: DELAY(25);
916:
917: SBIC_WAIT(regs, SBIC_ASR_INT, 0);
918: GET_SBIC_csr(regs, csr); /* clears interrupt also */
919:
920: /*
921: * Set up various chip parameters
922: */
923: SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
924:
925: /*
926: * don't allow Selection (SBIC_RID_ES)
927: * until we can handle target mode!!
928: */
929: SET_SBIC_rselid(regs, SBIC_RID_ER);
930:
931: /*
932: * Asynchronous for now
933: */
934: SET_SBIC_syn(regs, 0);
935:
936: /*
937: * Anything else was zeroed by reset
938: */
939: splx(s);
940:
941: dev->sc_flags &= ~SBICF_SELECTED;
942: }
943:
944: void
945: sbicerror(dev, csr)
946: struct sbic_softc *dev;
947: u_char csr;
948: {
949: struct scsi_xfer *xs = dev->sc_xs;
950:
951: #ifdef DIAGNOSTIC
952: if ( xs == NULL )
953: panic("sbicerror: dev->sc_xs == NULL");
954: #endif
955:
956: if ( xs->flags & SCSI_SILENT )
957: return;
958:
959: printf("%s: csr == 0x%02x\n", dev->sc_dev.dv_xname, csr);
960: }
961:
962: /*
963: * select the bus, return when selected or error.
964: *
965: * Returns the current CSR following selection and optionally MSG out phase.
966: * i.e. the returned CSR *should* indicate CMD phase...
967: * If the return value is 0, some error happened.
968: */
969: u_char
970: sbicselectbus(dev)
971: struct sbic_softc *dev;
972: {
973: sbic_regmap_p regs = dev->sc_sbicp;
974: u_char target = dev->target,
975: lun = dev->lun,
976: asr,
977: csr,
978: id;
979:
980: /*
981: * if we're already selected, return (XXXX panic maybe?)
982: */
983: if ( dev->sc_flags & SBICF_SELECTED )
984: return(0);
985:
986: QPRINTF(("sbicselectbus %d: ", target));
987:
988: /*
989: * issue select
990: */
991: SET_SBIC_selid(regs, target);
992: SET_SBIC_timeo(regs, SBIC_TIMEOUT(250, dev->sc_clkfreq));
993:
994: GET_SBIC_asr(regs, asr);
995:
996: if ( asr & (SBIC_ASR_INT|SBIC_ASR_BSY) ) {
997: /*
998: * This means we got ourselves reselected upon
999: */
1000: QPRINTF(("WD busy (reselect?)\n"));
1001: return 0;
1002: }
1003:
1004: SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN);
1005:
1006: /*
1007: * wait for select (merged from separate function may need
1008: * cleanup)
1009: */
1010: WAIT_CIP(regs);
1011:
1012: do {
1013:
1014: asr = SBIC_WAIT(regs, SBIC_ASR_INT | SBIC_ASR_LCI, 0);
1015:
1016: if ( asr & SBIC_ASR_LCI ) {
1017: QPRINTF(("late LCI: asr %02x\n", asr));
1018: return 0;
1019: }
1020:
1021: /*
1022: * Clear interrupt
1023: */
1024: GET_SBIC_csr (regs, csr);
1025:
1026: QPRINTF(("%02x ", csr));
1027:
1028: /*
1029: * Reselected from under our feet?
1030: */
1031: if ( csr == SBIC_CSR_RSLT_NI || csr == SBIC_CSR_RSLT_IFY ) {
1032: QPRINTF(("got reselected, asr %02x\n", asr));
1033: /*
1034: * We need to handle this now so we don't lock up later
1035: */
1036: sbicnextstate(dev, csr, asr);
1037:
1038: return 0;
1039: }
1040:
1041: /*
1042: * Whoops!
1043: */
1044: if ( csr == SBIC_CSR_SLT || csr == SBIC_CSR_SLT_ATN ) {
1045: panic("sbicselectbus: target issued select!");
1046: return 0;
1047: }
1048:
1049: } while (csr != (SBIC_CSR_MIS_2 | MESG_OUT_PHASE) &&
1050: csr != (SBIC_CSR_MIS_2 | CMD_PHASE) &&
1051: csr != SBIC_CSR_SEL_TIMEO);
1052:
1053: /*
1054: * Anyone at home?
1055: */
1056: if ( csr == SBIC_CSR_SEL_TIMEO ) {
1057: dev->sc_xs->error = XS_SELTIMEOUT;
1058: QPRINTF(("Selection Timeout\n"));
1059: return 0;
1060: }
1061:
1062: QPRINTF(("Selection Complete\n"));
1063:
1064: /*
1065: * Assume we're now selected
1066: */
1067: GET_SBIC_selid(regs, id);
1068: dev->target = id;
1069: dev->lun = lun;
1070: dev->sc_flags |= SBICF_SELECTED;
1071:
1072: /*
1073: * Enable (or not) reselection
1074: * XXXSCW This is probably not necessary since we don't use use the
1075: * Select-and-Xfer-with-ATN command to initiate a selection...
1076: */
1077: if ( !sbic_enable_reselect && TAILQ_EMPTY(&dev->nexus_list))
1078: SET_SBIC_rselid (regs, 0);
1079: else
1080: SET_SBIC_rselid (regs, SBIC_RID_ER);
1081:
1082: /*
1083: * We only really need to do anything when the target goes to MSG out
1084: * If the device ignored ATN, it's probably old and brain-dead,
1085: * but we'll try to support it anyhow.
1086: * If it doesn't support message out, it definitely doesn't
1087: * support synchronous transfers, so no point in even asking...
1088: */
1089: if ( csr == (SBIC_CSR_MIS_2 | MESG_OUT_PHASE) ) {
1090: /*
1091: * Send identify message (SCSI-2 requires an identify msg)
1092: */
1093: if ( sbic_inhibit_sync[id] && dev->sc_sync[id].state == SYNC_START ) {
1094: /*
1095: * Handle drives that don't want to be asked
1096: * whether to go sync at all.
1097: */
1098: dev->sc_sync[id].offset = 0;
1099: dev->sc_sync[id].period = sbic_min_period;
1100: dev->sc_sync[id].state = SYNC_DONE;
1101: }
1102:
1103: /*
1104: * Do we need to negotiate Synchronous Xfers for this target?
1105: */
1106: if ( dev->sc_sync[id].state != SYNC_START ) {
1107: /*
1108: * Nope, we've already negotiated.
1109: * Now see if we should allow the target to disconnect/reselect...
1110: */
1111: if ( dev->sc_xs->flags & SCSI_POLL || dev->sc_flags & SBICF_ICMD ||
1112: !sbic_enable_reselect )
1113: SEND_BYTE (regs, MSG_IDENTIFY | lun);
1114: else
1115: SEND_BYTE (regs, MSG_IDENTIFY_DR | lun);
1116:
1117: } else {
1118: /*
1119: * try to initiate a sync transfer.
1120: * So compose the sync message we're going
1121: * to send to the target
1122: */
1123: #ifdef DEBUG
1124: if ( sync_debug )
1125: printf("\nSending sync request to target %d ... ", id);
1126: #endif
1127: /*
1128: * setup scsi message sync message request
1129: */
1130: dev->sc_msg[0] = MSG_IDENTIFY | lun;
1131: dev->sc_msg[1] = MSG_EXT_MESSAGE;
1132: dev->sc_msg[2] = 3;
1133: dev->sc_msg[3] = MSG_SYNC_REQ;
1134: dev->sc_msg[4] = sbictoscsiperiod(dev, sbic_min_period);
1135: dev->sc_msg[5] = sbic_max_offset;
1136:
1137: sbicxfout(regs, 6, dev->sc_msg);
1138:
1139: dev->sc_sync[id].state = SYNC_SENT;
1140: #ifdef DEBUG
1141: if ( sync_debug )
1142: printf ("sent\n");
1143: #endif
1144: }
1145:
1146: /*
1147: * There's one interrupt still to come: the change to CMD phase...
1148: */
1149: SBIC_WAIT(regs, SBIC_ASR_INT , 0);
1150: GET_SBIC_csr(regs, csr);
1151: }
1152:
1153: /*
1154: * set sync or async
1155: */
1156: if ( dev->sc_sync[target].state == SYNC_DONE ) {
1157: #ifdef DEBUG
1158: if ( sync_debug )
1159: printf("select(%d): sync reg = 0x%02x\n", target,
1160: SBIC_SYN(dev->sc_sync[target].offset,
1161: dev->sc_sync[target].period));
1162: #endif
1163: SET_SBIC_syn(regs, SBIC_SYN(dev->sc_sync[target].offset,
1164: dev->sc_sync[target].period));
1165: } else {
1166: #ifdef DEBUG
1167: if ( sync_debug )
1168: printf("select(%d): sync reg = 0x%02x\n", target,
1169: SBIC_SYN(0,sbic_min_period));
1170: #endif
1171: SET_SBIC_syn(regs, SBIC_SYN(0, sbic_min_period));
1172: }
1173:
1174: return csr;
1175: }
1176:
1177: /*
1178: * Information Transfer *to* a Scsi Target.
1179: *
1180: * Note: Don't expect there to be an interrupt immediately after all
1181: * the data is transferred out. The WD spec sheet says that the Transfer-
1182: * Info command for non-MSG_IN phases only completes when the target
1183: * next asserts 'REQ'. That is, when the SCSI bus changes to a new state.
1184: *
1185: * This can have a nasty effect on commands which take a relatively long
1186: * time to complete, for example a START/STOP unit command may remain in
1187: * CMD phase until the disk has spun up. Only then will the target change
1188: * to STATUS phase. This is really only a problem for immediate commands
1189: * since we don't allow disconnection for them (yet).
1190: */
1191: int
1192: sbicxfout(regs, len, bp)
1193: sbic_regmap_p regs;
1194: int len;
1195: void *bp;
1196: {
1197: int wait = sbic_data_wait;
1198: u_char asr,
1199: *buf = bp;
1200:
1201: QPRINTF(("sbicxfout {%d} %02x %02x %02x %02x %02x "
1202: "%02x %02x %02x %02x %02x\n", len, buf[0], buf[1], buf[2],
1203: buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9]));
1204:
1205: /*
1206: * sigh.. WD-PROTO strikes again.. sending the command in one go
1207: * causes the chip to lock up if talking to certain (misbehaving?)
1208: * targets. Anyway, this procedure should work for all targets, but
1209: * it's slightly slower due to the overhead
1210: */
1211: WAIT_CIP (regs);
1212:
1213: SBIC_TC_PUT (regs, 0);
1214: SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
1215: SBIC_TC_PUT (regs, (unsigned)len);
1216: SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO);
1217:
1218: /*
1219: * Loop for each byte transferred
1220: */
1221: do {
1222:
1223: GET_SBIC_asr (regs, asr);
1224:
1225: if ( asr & SBIC_ASR_DBR ) {
1226: if ( len ) {
1227: SET_SBIC_data (regs, *buf);
1228: buf++;
1229: len--;
1230: } else {
1231: SET_SBIC_data (regs, 0);
1232: }
1233: wait = sbic_data_wait;
1234: }
1235:
1236: } while ( len && (asr & SBIC_ASR_INT) == 0 && wait-- > 0 );
1237:
1238: #ifdef DEBUG
1239: QPRINTF(("sbicxfout done: %d bytes remaining (wait:%d)\n", len, wait));
1240: #endif
1241:
1242: /*
1243: * Normally, an interrupt will be pending when this routing returns.
1244: */
1245: return(len);
1246: }
1247:
1248: /*
1249: * Information Transfer *from* a Scsi Target
1250: * returns # bytes left to read
1251: */
1252: int
1253: sbicxfin(regs, len, bp)
1254: sbic_regmap_p regs;
1255: int len;
1256: void *bp;
1257: {
1258: int wait = sbic_data_wait;
1259: u_char *buf = bp;
1260: u_char asr;
1261: #ifdef DEBUG
1262: u_char *obp = bp;
1263: #endif
1264:
1265: WAIT_CIP (regs);
1266:
1267: SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
1268: SBIC_TC_PUT (regs, (unsigned)len);
1269: SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO);
1270:
1271: /*
1272: * Loop for each byte transferred
1273: */
1274: do {
1275:
1276: GET_SBIC_asr (regs, asr);
1277:
1278: if ( asr & SBIC_ASR_DBR ) {
1279: if ( len ) {
1280: GET_SBIC_data (regs, *buf);
1281: buf++;
1282: len--;
1283: } else {
1284: u_char foo;
1285: GET_SBIC_data (regs, foo);
1286: }
1287: wait = sbic_data_wait;
1288: }
1289:
1290: } while ( (asr & SBIC_ASR_INT) == 0 && wait-- > 0 );
1291:
1292: QPRINTF(("sbicxfin {%d} %02x %02x %02x %02x %02x %02x "
1293: "%02x %02x %02x %02x\n", len, obp[0], obp[1], obp[2],
1294: obp[3], obp[4], obp[5], obp[6], obp[7], obp[8], obp[9]));
1295:
1296: SBIC_TC_PUT (regs, 0);
1297:
1298: /*
1299: * this leaves with one csr to be read
1300: */
1301: return len;
1302: }
1303:
1304: /*
1305: * SCSI 'immediate' command: issue a command to some SCSI device
1306: * and get back an 'immediate' response (i.e., do programmed xfer
1307: * to get the response data). 'cbuf' is a buffer containing a scsi
1308: * command of length clen bytes. 'buf' is a buffer of length 'len'
1309: * bytes for data. The transfer direction is determined by the device
1310: * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the
1311: * command must supply no data.
1312: *
1313: * Note that although this routine looks like it can handle disconnect/
1314: * reselect, the fact is that it can't. There is still some work to be
1315: * done to clean this lot up.
1316: */
1317: int
1318: sbicicmd(dev, cbuf, clen, buf, len)
1319: struct sbic_softc *dev;
1320: void *cbuf,
1321: *buf;
1322: int clen,
1323: len;
1324: {
1325: sbic_regmap_p regs = dev->sc_sbicp;
1326: struct sbic_acb *acb = dev->sc_nexus;
1327: u_char csr,
1328: asr;
1329: int still_busy = SBIC_STATE_RUNNING;
1330: #ifdef DEBUG
1331: int counter = 0;
1332: #endif
1333:
1334: /*
1335: * Make sure pointers are OK
1336: */
1337: dev->sc_last = dev->sc_cur = &acb->sc_pa;
1338: dev->sc_tcnt = acb->sc_tcnt = 0;
1339:
1340: acb->sc_dmacmd = 0;
1341: acb->sc_pa.dc_count = 0; /* No DMA */
1342: acb->sc_kv.dc_addr = buf;
1343: acb->sc_kv.dc_count = len;
1344:
1345: #ifdef DEBUG
1346: if ( data_pointer_debug > 1 )
1347: printf("sbicicmd(%d,%d):%d\n", dev->target, dev->lun, acb->sc_kv.dc_count);
1348: #endif
1349:
1350: /*
1351: * set the sbic into non-DMA mode
1352: */
1353: SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
1354:
1355: dev->sc_stat[0] = 0xff;
1356: dev->sc_msg[0] = 0xff;
1357:
1358: /*
1359: * We're stealing the SCSI bus
1360: */
1361: dev->sc_flags |= SBICF_ICMD;
1362:
1363: do {
1364: GET_SBIC_asr (regs, asr);
1365:
1366: /*
1367: * select the SCSI bus (it's an error if bus isn't free)
1368: */
1369: if ( (dev->sc_flags & SBICF_SELECTED) == 0 &&
1370: still_busy != SBIC_STATE_DISCONNECT ) {
1371: if ( (csr = sbicselectbus(dev)) == 0 ) {
1372: dev->sc_flags &= ~SBICF_ICMD;
1373: return(-1);
1374: }
1375: } else
1376: if ( (asr & (SBIC_ASR_BSY | SBIC_ASR_INT)) == SBIC_ASR_INT )
1377: GET_SBIC_csr(regs, csr);
1378: else
1379: csr = 0;
1380:
1381: if ( csr ) {
1382:
1383: QPRINTF((">ASR:0x%02x CSR:0x%02x< ", asr, csr));
1384:
1385: switch ( csr ) {
1386:
1387: case SBIC_CSR_S_XFERRED:
1388: case SBIC_CSR_DISC:
1389: case SBIC_CSR_DISC_1:
1390: {
1391: u_char phase;
1392:
1393: dev->sc_flags &= ~SBICF_SELECTED;
1394: GET_SBIC_cmd_phase (regs, phase);
1395:
1396: if ( phase == 0x60 ) {
1397: GET_SBIC_tlun (regs, dev->sc_stat[0]);
1398: still_busy = SBIC_STATE_DONE; /* done */
1399: } else {
1400: #ifdef DEBUG
1401: if ( reselect_debug > 1 )
1402: printf("sbicicmd: handling disconnect\n");
1403: #endif
1404: still_busy = SBIC_STATE_DISCONNECT;
1405: }
1406: }
1407: break;
1408:
1409: case SBIC_CSR_XFERRED | CMD_PHASE:
1410: case SBIC_CSR_MIS | CMD_PHASE:
1411: case SBIC_CSR_MIS_1 | CMD_PHASE:
1412: case SBIC_CSR_MIS_2 | CMD_PHASE:
1413: {
1414: if ( sbicxfout(regs, clen, cbuf) )
1415: still_busy = sbicabort(dev, "icmd sending cmd");
1416: }
1417: break;
1418:
1419: case SBIC_CSR_XFERRED | STATUS_PHASE:
1420: case SBIC_CSR_MIS | STATUS_PHASE:
1421: case SBIC_CSR_MIS_1 | STATUS_PHASE:
1422: case SBIC_CSR_MIS_2 | STATUS_PHASE:
1423: {
1424: /*
1425: * The sbic does the status/cmd-complete reading ok,
1426: * so do this with its hi-level commands.
1427: */
1428: #ifdef DEBUG
1429: if ( sbic_debug )
1430: printf("SBICICMD status phase (bsy=%d)\n", still_busy);
1431: #endif
1432: SET_SBIC_cmd_phase(regs, 0x46);
1433: SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN_XFER);
1434: }
1435: break;
1436:
1437: default:
1438: {
1439: still_busy = sbicnextstate(dev, csr, asr);
1440: }
1441: break;
1442: }
1443:
1444: /*
1445: * make sure the last command was taken,
1446: * ie. we're not hunting after an ignored command..
1447: */
1448: GET_SBIC_asr(regs, asr);
1449:
1450: /*
1451: * tapes may take a loooong time..
1452: */
1453: while (asr & SBIC_ASR_BSY ) {
1454:
1455: if ( asr & SBIC_ASR_DBR ) {
1456: int i;
1457:
1458: printf("sbicicmd: Waiting while sbic is jammed, CSR:%02x,ASR:%02x\n", csr,asr);
1459: #ifdef DDB
1460: Debugger();
1461: #endif
1462: /*
1463: * SBIC is jammed
1464: * DUNNO which direction
1465: * Try old direction
1466: */
1467: GET_SBIC_data(regs, i);
1468: GET_SBIC_asr(regs, asr);
1469:
1470: if ( asr & SBIC_ASR_DBR ) /* Wants us to write */
1471: SET_SBIC_data(regs, i);
1472: }
1473:
1474: GET_SBIC_asr(regs, asr);
1475: }
1476: }
1477:
1478: /*
1479: * wait for last command to complete
1480: */
1481: if ( asr & SBIC_ASR_LCI ) {
1482: printf("sbicicmd: last command ignored\n");
1483: }
1484: else
1485: if ( still_busy >= SBIC_STATE_RUNNING ) /* Bsy */
1486: SBIC_WAIT (regs, SBIC_ASR_INT, sbic_cmd_wait);
1487:
1488: /*
1489: * do it again
1490: */
1491: } while ( still_busy >= SBIC_STATE_RUNNING && dev->sc_stat[0] == 0xff );
1492:
1493: /*
1494: * Sometimes we need to do an extra read of the CSR
1495: */
1496: GET_SBIC_csr(regs, csr);
1497:
1498: #ifdef DEBUG
1499: if ( data_pointer_debug > 1 )
1500: printf("sbicicmd done(%d,%d):%d =%d=\n", dev->target, dev->lun,
1501: acb->sc_kv.dc_count,
1502: dev->sc_stat[0]);
1503: #endif
1504:
1505: dev->sc_flags &= ~SBICF_ICMD;
1506:
1507: return(dev->sc_stat[0]);
1508: }
1509:
1510: /*
1511: * Finish SCSI xfer command: After the completion interrupt from
1512: * a read/write operation, sequence through the final phases in
1513: * programmed i/o. This routine is a lot like sbicicmd except we
1514: * skip (and don't allow) the select, cmd out and data in/out phases.
1515: */
1516: void
1517: sbicxfdone(dev)
1518: struct sbic_softc *dev;
1519: {
1520: sbic_regmap_p regs = dev->sc_sbicp;
1521: u_char phase,
1522: csr;
1523: int s;
1524:
1525: QPRINTF(("{"));
1526: s = splbio();
1527:
1528: /*
1529: * have the sbic complete on its own
1530: */
1531: SBIC_TC_PUT(regs, 0);
1532: SET_SBIC_cmd_phase(regs, 0x46);
1533: SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN_XFER);
1534:
1535: do {
1536:
1537: SBIC_WAIT (regs, SBIC_ASR_INT, 0);
1538: GET_SBIC_csr (regs, csr);
1539: QPRINTF(("%02x:", csr));
1540:
1541: } while ( (csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1) &&
1542: (csr != SBIC_CSR_S_XFERRED));
1543:
1544: dev->sc_flags &= ~SBICF_SELECTED;
1545:
1546: GET_SBIC_cmd_phase (regs, phase);
1547: QPRINTF(("}%02x", phase));
1548:
1549: if ( phase == 0x60 )
1550: GET_SBIC_tlun(regs, dev->sc_stat[0]);
1551: else
1552: sbicerror(dev, csr);
1553:
1554: QPRINTF(("=STS:%02x=\n", dev->sc_stat[0]));
1555:
1556: splx(s);
1557: }
1558:
1559: /*
1560: * No DMA chains
1561: */
1562: int
1563: sbicgo(dev, xs)
1564: struct sbic_softc *dev;
1565: struct scsi_xfer *xs;
1566: {
1567: struct sbic_acb *acb = dev->sc_nexus;
1568: sbic_regmap_p regs = dev->sc_sbicp;
1569: int i,
1570: dmaflags,
1571: count,
1572: usedma;
1573: u_char csr,
1574: asr,
1575: *addr;
1576:
1577: dev->target = xs->sc_link->target;
1578: dev->lun = xs->sc_link->lun;
1579:
1580: usedma = sbicdmaok(dev, xs);
1581:
1582: #ifdef DEBUG
1583: if ( data_pointer_debug > 1 )
1584: printf("sbicgo(%d,%d): usedma=%d\n", dev->target, dev->lun, usedma);
1585: #endif
1586:
1587: /*
1588: * select the SCSI bus (it's an error if bus isn't free)
1589: */
1590: if ( (csr = sbicselectbus(dev)) == 0 )
1591: return(0); /* Not done: needs to be rescheduled */
1592:
1593: dev->sc_stat[0] = 0xff;
1594:
1595: /*
1596: * Calculate DMA chains now
1597: */
1598: if ( acb->flags & ACB_DATAIN )
1599: dmaflags = DMAGO_READ;
1600: else
1601: dmaflags = 0;
1602:
1603: addr = acb->sc_kv.dc_addr;
1604: count = acb->sc_kv.dc_count;
1605:
1606: if ( count && ((char *)kvtop((vaddr_t)addr) != acb->sc_pa.dc_addr) ) {
1607: printf("sbic: DMA buffer mapping changed %p->%lx\n",
1608: acb->sc_pa.dc_addr, kvtop((vaddr_t)addr));
1609: #ifdef DDB
1610: Debugger();
1611: #endif
1612: }
1613:
1614: #ifdef DEBUG
1615: ++sbicdma_ops; /* count total DMA operations */
1616: #endif
1617:
1618: /*
1619: * Allocate the DMA chain
1620: * Mark end of segment...
1621: */
1622: acb->sc_tcnt = dev->sc_tcnt = 0;
1623: acb->sc_pa.dc_count = 0;
1624:
1625: sbic_load_ptrs(dev);
1626:
1627: /*
1628: * Enable interrupts but don't do any DMA
1629: * enintr() also enables interrupts for the sbic
1630: */
1631: dev->sc_enintr(dev);
1632:
1633: if ( usedma ) {
1634: dev->sc_tcnt = dev->sc_dmago(dev, acb->sc_pa.dc_addr,
1635: acb->sc_pa.dc_count, dmaflags);
1636: #ifdef DEBUG
1637: dev->sc_dmatimo = dev->sc_tcnt ? 1 : 0;
1638: #endif
1639: } else
1640: dev->sc_dmacmd = 0; /* Don't use DMA */
1641:
1642: acb->sc_dmacmd = dev->sc_dmacmd;
1643:
1644: #ifdef DEBUG
1645: if ( data_pointer_debug > 1 ) {
1646: printf("sbicgo dmago:%d(%x:%x) dmacmd=0x%02x\n", dev->target,
1647: dev->sc_cur->dc_addr,
1648: dev->sc_tcnt,
1649: dev->sc_dmacmd);
1650: }
1651: #endif
1652:
1653: /*
1654: * Lets cycle a while then let the interrupt handler take over.
1655: */
1656: GET_SBIC_asr(regs, asr);
1657:
1658: do {
1659:
1660: QPRINTF(("go "));
1661:
1662: /*
1663: * Handle the new phase
1664: */
1665: i = sbicnextstate(dev, csr, asr);
1666: #if 0
1667: WAIT_CIP(regs);
1668: #endif
1669: if ( i == SBIC_STATE_RUNNING ) {
1670: GET_SBIC_asr(regs, asr);
1671:
1672: if ( asr & SBIC_ASR_LCI )
1673: printf("sbicgo: LCI asr:%02x csr:%02x\n", asr, csr);
1674:
1675: if ( asr & SBIC_ASR_INT )
1676: GET_SBIC_csr(regs, csr);
1677: }
1678:
1679: } while ( i == SBIC_STATE_RUNNING && asr & (SBIC_ASR_INT|SBIC_ASR_LCI) );
1680:
1681: if ( i == SBIC_STATE_DONE ) {
1682: if ( dev->sc_stat[0] == 0xff )
1683: #if 0
1684: printf("sbicgo: done & stat = 0xff\n");
1685: #else
1686: ;
1687: #endif
1688: else
1689: return 1; /* Did we really finish that fast? */
1690: }
1691:
1692: return 0;
1693: }
1694:
1695:
1696: int
1697: sbicintr(dev)
1698: struct sbic_softc *dev;
1699: {
1700: sbic_regmap_p regs = dev->sc_sbicp;
1701: u_char asr,
1702: csr;
1703: int i;
1704:
1705: /*
1706: * pending interrupt?
1707: */
1708: GET_SBIC_asr (regs, asr);
1709: if ( (asr & SBIC_ASR_INT) == 0 )
1710: return(0);
1711:
1712: GET_SBIC_csr(regs, csr);
1713:
1714: do {
1715:
1716: QPRINTF(("intr[0x%x]", csr));
1717:
1718: i = sbicnextstate(dev, csr, asr);
1719: #if 0
1720: WAIT_CIP(regs);
1721: #endif
1722: if ( i == SBIC_STATE_RUNNING ) {
1723: GET_SBIC_asr(regs, asr);
1724:
1725: if ( asr & SBIC_ASR_LCI )
1726: printf("sbicgo: LCI asr:%02x csr:%02x\n", asr, csr);
1727:
1728: if ( asr & SBIC_ASR_INT )
1729: GET_SBIC_csr(regs, csr);
1730: }
1731:
1732: } while ( i == SBIC_STATE_RUNNING && asr & (SBIC_ASR_INT|SBIC_ASR_LCI) );
1733:
1734: QPRINTF(("intr done. state=%d, asr=0x%02x\n", i, asr));
1735:
1736: return(1);
1737: }
1738:
1739: /*
1740: * Run commands and wait for disconnect.
1741: * This is only ever called when a command is in progress, when we
1742: * want to busy wait for it to finish.
1743: */
1744: int
1745: sbicpoll(dev)
1746: struct sbic_softc *dev;
1747: {
1748: sbic_regmap_p regs = dev->sc_sbicp;
1749: u_char asr,
1750: csr = 0;
1751: int i;
1752:
1753: /*
1754: * Wait for the next interrupt
1755: */
1756: SBIC_WAIT(regs, SBIC_ASR_INT, sbic_cmd_wait);
1757:
1758: do {
1759: GET_SBIC_asr (regs, asr);
1760:
1761: if ( asr & SBIC_ASR_INT )
1762: GET_SBIC_csr(regs, csr);
1763:
1764: QPRINTF(("poll[0x%x]", csr));
1765:
1766: /*
1767: * Handle it
1768: */
1769: i = sbicnextstate(dev, csr, asr);
1770:
1771: WAIT_CIP(regs);
1772: GET_SBIC_asr(regs, asr);
1773:
1774: /*
1775: * tapes may take a loooong time..
1776: */
1777: while ( asr & SBIC_ASR_BSY ) {
1778: u_char z = 0;
1779:
1780: if ( asr & SBIC_ASR_DBR ) {
1781: printf("sbipoll: Waiting while sbic is jammed, CSR:%02x,ASR:%02x\n", csr,asr);
1782: #ifdef DDB
1783: Debugger();
1784: #endif
1785: /*
1786: * SBIC is jammed
1787: * DUNNO which direction
1788: * Try old direction
1789: */
1790: GET_SBIC_data(regs, z);
1791: GET_SBIC_asr(regs, asr);
1792:
1793: if ( asr & SBIC_ASR_DBR ) /* Wants us to write */
1794: SET_SBIC_data(regs, z);
1795: }
1796:
1797: GET_SBIC_asr(regs, asr);
1798: }
1799:
1800: if ( asr & SBIC_ASR_LCI )
1801: printf("sbicpoll: LCI asr:%02x csr:%02x\n", asr,csr);
1802: else
1803: if ( i == SBIC_STATE_RUNNING ) /* BSY */
1804: SBIC_WAIT(regs, SBIC_ASR_INT, sbic_cmd_wait);
1805:
1806: } while ( i == SBIC_STATE_RUNNING );
1807:
1808: return(1);
1809: }
1810:
1811: /*
1812: * Handle a single msgin
1813: */
1814: int
1815: sbicmsgin(dev)
1816: struct sbic_softc *dev;
1817: {
1818: sbic_regmap_p regs = dev->sc_sbicp;
1819: int recvlen = 1;
1820: u_char asr,
1821: csr,
1822: *tmpaddr,
1823: *msgaddr;
1824:
1825: tmpaddr = msgaddr = dev->sc_msg;
1826:
1827: tmpaddr[0] = 0xff;
1828: tmpaddr[1] = 0xff;
1829:
1830: GET_SBIC_asr(regs, asr);
1831:
1832: #ifdef DEBUG
1833: if ( reselect_debug > 1 )
1834: printf("sbicmsgin asr=%02x\n", asr);
1835: #endif
1836:
1837: GET_SBIC_selid (regs, csr);
1838: SET_SBIC_selid (regs, csr | SBIC_SID_FROM_SCSI);
1839:
1840: SBIC_TC_PUT(regs, 0);
1841: SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
1842:
1843: do {
1844: while( recvlen-- ) {
1845:
1846: /*
1847: * Fetch the next byte of the message
1848: */
1849: RECV_BYTE(regs, *tmpaddr);
1850:
1851: /*
1852: * get the command completion interrupt, or we
1853: * can't send a new command (LCI)
1854: */
1855: SBIC_WAIT(regs, SBIC_ASR_INT, 0);
1856: GET_SBIC_csr(regs, csr);
1857:
1858: #ifdef DEBUG
1859: if ( reselect_debug > 1 )
1860: printf("sbicmsgin: got %02x csr %02x\n", *tmpaddr, csr);
1861: #endif
1862:
1863: tmpaddr++;
1864:
1865: if ( recvlen ) {
1866: /*
1867: * Clear ACK, and wait for the interrupt for the next byte
1868: */
1869: SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK);
1870: SBIC_WAIT(regs, SBIC_ASR_INT, 0);
1871: GET_SBIC_csr(regs, csr);
1872: }
1873: }
1874:
1875: if ( msgaddr[0] == 0xff ) {
1876: printf("sbicmsgin: sbic swallowed our message\n");
1877: break;
1878: }
1879:
1880: #ifdef DEBUG
1881: if ( sync_debug ) {
1882: GET_SBIC_asr(regs, asr);
1883: printf("msgin done csr 0x%x asr 0x%x msg 0x%x\n", csr, asr, msgaddr[0]);
1884: }
1885: #endif
1886: /*
1887: * test whether this is a reply to our sync
1888: * request
1889: */
1890: if ( MSG_ISIDENTIFY(msgaddr[0]) ) {
1891:
1892: /*
1893: * Got IFFY msg -- ack it
1894: */
1895: QPRINTF(("IFFY"));
1896:
1897: } else
1898: if ( msgaddr[0] == MSG_REJECT &&
1899: dev->sc_sync[dev->target].state == SYNC_SENT) {
1900:
1901: /*
1902: * Target probably rejected our Sync negotiation.
1903: */
1904: QPRINTF(("REJECT of SYN"));
1905:
1906: #ifdef DEBUG
1907: if ( sync_debug )
1908: printf("target %d rejected sync, going async\n", dev->target);
1909: #endif
1910:
1911: dev->sc_sync[dev->target].period = sbic_min_period;
1912: dev->sc_sync[dev->target].offset = 0;
1913: dev->sc_sync[dev->target].state = SYNC_DONE;
1914: SET_SBIC_syn(regs, SBIC_SYN(dev->sc_sync[dev->target].offset,
1915: dev->sc_sync[dev->target].period));
1916:
1917: } else
1918: if ( msgaddr[0] == MSG_REJECT ) {
1919:
1920: /*
1921: * we'll never REJECt a REJECT message..
1922: */
1923: QPRINTF(("REJECT"));
1924:
1925: } else
1926: if ( msgaddr[0] == MSG_SAVE_DATA_PTR ) {
1927:
1928: /*
1929: * don't reject this either.
1930: */
1931: QPRINTF(("MSG_SAVE_DATA_PTR"));
1932:
1933: } else
1934: if ( msgaddr[0] == MSG_RESTORE_PTR ) {
1935:
1936: /*
1937: * don't reject this either.
1938: */
1939: QPRINTF(("MSG_RESTORE_PTR"));
1940:
1941: } else
1942: if ( msgaddr[0] == MSG_DISCONNECT ) {
1943:
1944: /*
1945: * Target is disconnecting...
1946: */
1947: QPRINTF(("DISCONNECT"));
1948:
1949: #ifdef DEBUG
1950: if ( reselect_debug > 1 && msgaddr[0] == MSG_DISCONNECT )
1951: printf("sbicmsgin: got disconnect msg %s\n",
1952: (dev->sc_flags & SBICF_ICMD) ? "rejecting" : "");
1953: #endif
1954:
1955: if ( dev->sc_flags & SBICF_ICMD ) {
1956: /*
1957: * We're in immediate mode. Prevent disconnects.
1958: * prepare to reject the message, NACK
1959: */
1960: SET_SBIC_cmd(regs, SBIC_CMD_SET_ATN);
1961: WAIT_CIP(regs);
1962: }
1963:
1964: } else
1965: if ( msgaddr[0] == MSG_CMD_COMPLETE ) {
1966:
1967: /*
1968: * !! KLUDGE ALERT !! quite a few drives don't seem to
1969: * really like the current way of sending the
1970: * sync-handshake together with the ident-message, and
1971: * they react by sending command-complete and
1972: * disconnecting right after returning the valid sync
1973: * handshake. So, all I can do is reselect the drive,
1974: * and hope it won't disconnect again. I don't think
1975: * this is valid behavior, but I can't help fixing a
1976: * problem that apparently exists.
1977: *
1978: * Note: we should not get here on `normal' command
1979: * completion, as that condition is handled by the
1980: * high-level sel&xfer resume command used to walk
1981: * thru status/cc-phase.
1982: */
1983: QPRINTF(("CMD_COMPLETE"));
1984:
1985: #ifdef DEBUG
1986: if ( sync_debug )
1987: printf ("GOT MSG %d! target %d acting weird.."
1988: " waiting for disconnect...\n", msgaddr[0], dev->target);
1989: #endif
1990:
1991: /*
1992: * Check to see if sbic is handling this
1993: */
1994: GET_SBIC_asr(regs, asr);
1995:
1996: /*
1997: * XXXSCW: I'm not convinced of this, we haven't negated ACK yet...
1998: */
1999: if ( asr & SBIC_ASR_BSY )
2000: return SBIC_STATE_RUNNING;
2001:
2002: /*
2003: * Let's try this: Assume it works and set status to 00
2004: */
2005: dev->sc_stat[0] = 0;
2006:
2007: } else
2008: if ( msgaddr[0] == MSG_EXT_MESSAGE && tmpaddr == &(msgaddr[1]) ) {
2009:
2010: /*
2011: * Target is sending us an extended message. We'll assume it's
2012: * the response to our Sync. negotiation.
2013: */
2014: QPRINTF(("ExtMSG\n"));
2015:
2016: /*
2017: * Read in whole extended message. First, negate ACK to accept
2018: * the MSG_EXT_MESSAGE byte...
2019: */
2020: SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK);
2021:
2022: /*
2023: * Wait for the interrupt for the next byte (length)
2024: */
2025: SBIC_WAIT(regs, SBIC_ASR_INT, 0);
2026: GET_SBIC_csr(regs, csr);
2027:
2028: #ifdef DEBUG
2029: QPRINTF(("CLR ACK csr %02x\n", csr));
2030: #endif
2031:
2032: /*
2033: * Read the length byte
2034: */
2035: RECV_BYTE(regs, *tmpaddr);
2036:
2037: /*
2038: * Wait for command completion IRQ
2039: */
2040: SBIC_WAIT(regs, SBIC_ASR_INT, 0);
2041: GET_SBIC_csr(regs, csr);
2042:
2043: /*
2044: * Reload the loop counter
2045: */
2046: recvlen = *tmpaddr++;
2047:
2048: QPRINTF(("Recving ext msg, csr %02x len %02x\n", csr, recvlen));
2049:
2050: } else
2051: if ( msgaddr[0] == MSG_EXT_MESSAGE && msgaddr[1] == 3 &&
2052: msgaddr[2] == MSG_SYNC_REQ ) {
2053:
2054: /*
2055: * We've received the complete Extended Message Sync. Request...
2056: */
2057: QPRINTF(("SYN"));
2058:
2059: /*
2060: * Compute the required Transfer Period for the WD chip...
2061: */
2062: dev->sc_sync[dev->target].period = sbicfromscsiperiod(dev, msgaddr[3]);
2063: dev->sc_sync[dev->target].offset = msgaddr[4];
2064: dev->sc_sync[dev->target].state = SYNC_DONE;
2065:
2066: /*
2067: * Put the WD chip in synchronous mode
2068: */
2069: SET_SBIC_syn(regs, SBIC_SYN(dev->sc_sync[dev->target].offset,
2070: dev->sc_sync[dev->target].period));
2071: #ifdef DEBUG
2072: if ( sync_debug )
2073: printf("msgin(%d): sync reg = 0x%02x\n", dev->target,
2074: SBIC_SYN(dev->sc_sync[dev->target].offset,
2075: dev->sc_sync[dev->target].period));
2076: #endif
2077:
2078: printf("%s: target %d now synchronous, period=%dns, offset=%d.\n",
2079: dev->sc_dev.dv_xname, dev->target,
2080: msgaddr[3] * 4, msgaddr[4]);
2081:
2082: } else {
2083:
2084: /*
2085: * We don't support whatever this message is...
2086: */
2087: #ifdef DEBUG
2088: if ( sbic_debug || sync_debug )
2089: printf ("sbicmsgin: Rejecting message 0x%02x\n", msgaddr[0]);
2090: #endif
2091:
2092: /*
2093: * prepare to reject the message, NACK
2094: */
2095: SET_SBIC_cmd(regs, SBIC_CMD_SET_ATN);
2096: WAIT_CIP(regs);
2097: }
2098:
2099: /*
2100: * Negate ACK to complete the transfer
2101: */
2102: SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK);
2103:
2104: /*
2105: * Wait for the interrupt for the next byte, or phase change.
2106: * Only read the CSR if we have more data to transfer.
2107: * XXXSCW: We should really verify that we're still in MSG IN phase
2108: * before blindly going back around this loop, but that would mean
2109: * we read the CSR... <sigh>
2110: */
2111: SBIC_WAIT(regs, SBIC_ASR_INT, 0);
2112: if ( recvlen > 0 )
2113: GET_SBIC_csr(regs, csr);
2114:
2115: } while ( recvlen > 0 );
2116:
2117: /*
2118: * Should still have one CSR to read
2119: */
2120: return SBIC_STATE_RUNNING;
2121: }
2122:
2123:
2124: /*
2125: * sbicnextstate()
2126: * return:
2127: * SBIC_STATE_DONE == done
2128: * SBIC_STATE_RUNNING == working
2129: * SBIC_STATE_DISCONNECT == disconnected
2130: * SBIC_STATE_ERROR == error
2131: */
2132: int
2133: sbicnextstate(dev, csr, asr)
2134: struct sbic_softc *dev;
2135: u_char csr,
2136: asr;
2137: {
2138: sbic_regmap_p regs = dev->sc_sbicp;
2139: struct sbic_acb *acb = dev->sc_nexus;
2140:
2141: QPRINTF(("next[%02x,%02x]: ",asr,csr));
2142:
2143: switch (csr) {
2144:
2145: case SBIC_CSR_XFERRED | CMD_PHASE:
2146: case SBIC_CSR_MIS | CMD_PHASE:
2147: case SBIC_CSR_MIS_1 | CMD_PHASE:
2148: case SBIC_CSR_MIS_2 | CMD_PHASE:
2149: {
2150: if ( sbicxfout(regs, acb->clen, &acb->cmd) )
2151: goto abort;
2152: }
2153: break;
2154:
2155: case SBIC_CSR_XFERRED | STATUS_PHASE:
2156: case SBIC_CSR_MIS | STATUS_PHASE:
2157: case SBIC_CSR_MIS_1 | STATUS_PHASE:
2158: case SBIC_CSR_MIS_2 | STATUS_PHASE:
2159: {
2160: SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
2161:
2162: /*
2163: * this should be the normal i/o completion case.
2164: * get the status & cmd complete msg then let the
2165: * device driver look at what happened.
2166: */
2167: sbicxfdone(dev);
2168:
2169: #ifdef DEBUG
2170: dev->sc_dmatimo = 0;
2171: if ( data_pointer_debug > 1 )
2172: printf("next dmastop: %d(%x:%x)\n", dev->target,
2173: dev->sc_cur->dc_addr,
2174: dev->sc_tcnt);
2175: #endif
2176: /*
2177: * Stop the DMA chip
2178: */
2179: dev->sc_dmastop(dev);
2180:
2181: dev->sc_flags &= ~(SBICF_INDMA | SBICF_DCFLUSH);
2182:
2183: /*
2184: * Indicate to the upper layers that the command is done
2185: */
2186: sbic_scsidone(acb, dev->sc_stat[0]);
2187:
2188: return SBIC_STATE_DONE;
2189: }
2190:
2191: case SBIC_CSR_XFERRED | DATA_OUT_PHASE:
2192: case SBIC_CSR_XFERRED | DATA_IN_PHASE:
2193: case SBIC_CSR_MIS | DATA_OUT_PHASE:
2194: case SBIC_CSR_MIS | DATA_IN_PHASE:
2195: case SBIC_CSR_MIS_1 | DATA_OUT_PHASE:
2196: case SBIC_CSR_MIS_1 | DATA_IN_PHASE:
2197: case SBIC_CSR_MIS_2 | DATA_OUT_PHASE:
2198: case SBIC_CSR_MIS_2 | DATA_IN_PHASE:
2199: {
2200: /*
2201: * Verify that we expected to transfer data...
2202: */
2203: if ( acb->sc_kv.dc_count <= 0 ) {
2204: printf("next: DATA phase with xfer count == %d, asr:0x%02x csr:0x%02x\n",
2205: acb->sc_kv.dc_count, asr, csr);
2206: goto abort;
2207: }
2208:
2209: /*
2210: * Should we transfer using PIO or DMA ?
2211: */
2212: if ( dev->sc_xs->flags & SCSI_POLL || dev->sc_flags & SBICF_ICMD ||
2213: acb->sc_dmacmd == 0 ) {
2214:
2215: /*
2216: * Do PIO transfer
2217: */
2218: int i;
2219:
2220: #ifdef DEBUG
2221: if ( data_pointer_debug > 1 )
2222: printf("next PIO: %d(%x:%x)\n", dev->target,
2223: acb->sc_kv.dc_addr,
2224: acb->sc_kv.dc_count);
2225: #endif
2226:
2227: if ( SBIC_PHASE(csr) == DATA_IN_PHASE )
2228: /*
2229: * data in
2230: */
2231: i = sbicxfin(regs, acb->sc_kv.dc_count,
2232: acb->sc_kv.dc_addr);
2233: else
2234: /*
2235: * data out
2236: */
2237: i = sbicxfout(regs, acb->sc_kv.dc_count,
2238: acb->sc_kv.dc_addr);
2239:
2240: acb->sc_kv.dc_addr += (acb->sc_kv.dc_count - i);
2241: acb->sc_kv.dc_count = i;
2242:
2243: /*
2244: * Update current count...
2245: */
2246: acb->sc_tcnt = dev->sc_tcnt = i;
2247:
2248: dev->sc_flags &= ~SBICF_INDMA;
2249:
2250: } else {
2251:
2252: /*
2253: * Do DMA transfer
2254: * set next dma addr and dec count
2255: */
2256: sbic_save_ptrs(dev);
2257: sbic_load_ptrs(dev);
2258:
2259: SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI |
2260: SBIC_MACHINE_DMA_MODE);
2261:
2262: #ifdef DEBUG
2263: dev->sc_dmatimo = 1;
2264: if ( data_pointer_debug > 1 )
2265: printf("next DMA: %d(%x:%x)\n", dev->target,
2266: dev->sc_cur->dc_addr,
2267: dev->sc_tcnt);
2268: #endif
2269: /*
2270: * Start the DMA chip going
2271: */
2272: dev->sc_tcnt = dev->sc_dmanext(dev);
2273:
2274: /*
2275: * Tell the WD chip how much to transfer this time around
2276: */
2277: SBIC_TC_PUT(regs, (unsigned)dev->sc_tcnt);
2278:
2279: /*
2280: * Start the transfer
2281: */
2282: SET_SBIC_cmd(regs, SBIC_CMD_XFER_INFO);
2283:
2284: /*
2285: * Indicate that we're in DMA mode
2286: */
2287: dev->sc_flags |= SBICF_INDMA;
2288: }
2289: }
2290: break;
2291:
2292: case SBIC_CSR_XFERRED | MESG_IN_PHASE:
2293: case SBIC_CSR_MIS | MESG_IN_PHASE:
2294: case SBIC_CSR_MIS_1 | MESG_IN_PHASE:
2295: case SBIC_CSR_MIS_2 | MESG_IN_PHASE:
2296: {
2297: sbic_save_ptrs(dev);
2298:
2299: /*
2300: * Handle a single message in...
2301: */
2302: return sbicmsgin(dev);
2303: }
2304:
2305: case SBIC_CSR_MSGIN_W_ACK:
2306: {
2307: /*
2308: * We should never see this since it's handled in 'sbicmsgin()'
2309: * but just for the sake of paranoia...
2310: */
2311: SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK); /* Dunno what I'm ACKing */
2312: printf("Acking unknown msgin CSR:%02x",csr);
2313: }
2314: break;
2315:
2316: case SBIC_CSR_XFERRED | MESG_OUT_PHASE:
2317: case SBIC_CSR_MIS | MESG_OUT_PHASE:
2318: case SBIC_CSR_MIS_1 | MESG_OUT_PHASE:
2319: case SBIC_CSR_MIS_2 | MESG_OUT_PHASE:
2320: {
2321: /*
2322: * We only ever handle a message out phase here for sending a
2323: * REJECT message.
2324: */
2325: sbic_save_ptrs(dev);
2326:
2327: #ifdef DEBUG
2328: if (sync_debug)
2329: printf ("sending REJECT msg to last msg.\n");
2330: #endif
2331:
2332: SEND_BYTE(regs, MSG_REJECT);
2333: WAIT_CIP(regs);
2334: }
2335: break;
2336:
2337: case SBIC_CSR_DISC:
2338: case SBIC_CSR_DISC_1:
2339: {
2340: /*
2341: * Try to schedule another target
2342: */
2343: sbic_save_ptrs(dev);
2344:
2345: dev->sc_flags &= ~SBICF_SELECTED;
2346:
2347: #ifdef DEBUG
2348: if ( reselect_debug > 1 )
2349: printf("sbicnext target %d disconnected\n", dev->target);
2350: #endif
2351:
2352: TAILQ_INSERT_HEAD(&dev->nexus_list, acb, chain);
2353:
2354: ++dev->sc_tinfo[dev->target].dconns;
2355:
2356: dev->sc_nexus = NULL;
2357: dev->sc_xs = NULL;
2358:
2359: if ( acb->xs->flags & SCSI_POLL || dev->sc_flags & SBICF_ICMD ||
2360: !sbic_parallel_operations )
2361: return SBIC_STATE_DISCONNECT;
2362:
2363: QPRINTF(("sbicnext: calling sbic_sched\n"));
2364:
2365: sbic_sched(dev);
2366:
2367: QPRINTF(("sbicnext: sbic_sched returned\n"));
2368:
2369: return SBIC_STATE_DISCONNECT;
2370: }
2371:
2372: case SBIC_CSR_RSLT_NI:
2373: case SBIC_CSR_RSLT_IFY:
2374: {
2375: /*
2376: * A reselection.
2377: * Note that since we don't enable Advanced Features (assuming
2378: * the WD chip is at least the 'A' revision), we're only ever
2379: * likely to see the 'SBIC_CSR_RSLT_NI' status. But for the
2380: * hell of it, we'll handle it anyway, for all the extra code
2381: * it needs...
2382: */
2383: u_char newtarget,
2384: newlun;
2385:
2386: GET_SBIC_rselid(regs, newtarget);
2387:
2388: /*
2389: * check SBIC_RID_SIV?
2390: */
2391: newtarget &= SBIC_RID_MASK;
2392:
2393: if ( csr == SBIC_CSR_RSLT_IFY ) {
2394:
2395: /*
2396: * Read Identify msg to avoid lockup
2397: */
2398: GET_SBIC_data(regs, newlun);
2399: WAIT_CIP(regs);
2400: newlun &= SBIC_TLUN_MASK;
2401:
2402: } else {
2403:
2404: /*
2405: * Need to read Identify message the hard way, assuming
2406: * the target even sends us one...
2407: */
2408: for (newlun = 255; newlun; --newlun) {
2409: GET_SBIC_asr(regs, asr);
2410: if (asr & SBIC_ASR_INT)
2411: break;
2412: delay(10);
2413: }
2414:
2415: /*
2416: * If we didn't get an interrupt, somethink's up
2417: */
2418: if ( (asr & SBIC_ASR_INT) == 0 ) {
2419: printf("%s: Reselect without identify? asr %x\n",
2420: dev->sc_dev.dv_xname, asr);
2421: newlun = 0; /* XXXX */
2422: } else {
2423: /*
2424: * We got an interrupt, verify that it's a change to
2425: * message in phase, and if so read the message.
2426: */
2427: GET_SBIC_csr(regs,csr);
2428:
2429: if (csr == (SBIC_CSR_MIS | MESG_IN_PHASE) ||
2430: csr == (SBIC_CSR_MIS_1 | MESG_IN_PHASE) ||
2431: csr == (SBIC_CSR_MIS_2 | MESG_IN_PHASE)) {
2432: /*
2433: * Yup, gone to message in. Fetch the target LUN
2434: */
2435: sbicmsgin(dev);
2436: newlun = dev->sc_msg[0] & 0x07;
2437:
2438: } else {
2439: /*
2440: * Whoops! Target didn't go to message in phase!!
2441: */
2442: printf("RSLT_NI - not MESG_IN_PHASE %x\n", csr);
2443: newlun = 0; /* XXXSCW */
2444: }
2445: }
2446: }
2447:
2448: /*
2449: * Ok, we have the identity of the reselecting target.
2450: */
2451: #ifdef DEBUG
2452: if ( reselect_debug > 1 ||
2453: (reselect_debug && csr == SBIC_CSR_RSLT_NI) ) {
2454: printf("sbicnext: reselect %s from targ %d lun %d\n",
2455: csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY", newtarget, newlun);
2456: }
2457: #endif
2458:
2459: if ( dev->sc_nexus ) {
2460: /*
2461: * Whoops! We've been reselected with an command in progress!
2462: * The best we can do is to put the current command back on the
2463: * ready list and hope for the best.
2464: */
2465: #ifdef DEBUG
2466: if ( reselect_debug > 1 ) {
2467: printf("%s: reselect %s with active command\n",
2468: dev->sc_dev.dv_xname,
2469: csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY");
2470: }
2471: #endif
2472:
2473: TAILQ_INSERT_HEAD(&dev->ready_list, dev->sc_nexus, chain);
2474:
2475: dev->sc_tinfo[dev->target].lubusy &= ~(1 << dev->lun);
2476:
2477: dev->sc_nexus = NULL;
2478: dev->sc_xs = NULL;
2479: }
2480:
2481: /*
2482: * Reload sync values for this target
2483: */
2484: if ( dev->sc_sync[newtarget].state == SYNC_DONE )
2485: SET_SBIC_syn(regs, SBIC_SYN (dev->sc_sync[newtarget].offset,
2486: dev->sc_sync[newtarget].period));
2487: else
2488: SET_SBIC_syn(regs, SBIC_SYN (0, sbic_min_period));
2489:
2490: /*
2491: * Loop through the nexus list until we find the saved entry
2492: * for the reselecting target...
2493: */
2494: TAILQ_FOREACH(acb, &dev->nexus_list, chain) {
2495:
2496: if ( acb->xs->sc_link->target == newtarget &&
2497: acb->xs->sc_link->lun == newlun) {
2498: /*
2499: * We've found the saved entry. Dequeue it, and
2500: * make it current again.
2501: */
2502: TAILQ_REMOVE(&dev->nexus_list, acb, chain);
2503:
2504: dev->sc_nexus = acb;
2505: dev->sc_xs = acb->xs;
2506: dev->sc_flags |= SBICF_SELECTED;
2507: dev->target = newtarget;
2508: dev->lun = newlun;
2509: break;
2510: }
2511: }
2512:
2513: if ( acb == NULL ) {
2514: printf("%s: reselect %s targ %d not in nexus_list %p\n",
2515: dev->sc_dev.dv_xname,
2516: csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY", newtarget,
2517: &TAILQ_FIRST(&dev->nexus_list));
2518: panic("bad reselect in sbic");
2519: }
2520:
2521: if ( csr == SBIC_CSR_RSLT_IFY )
2522: SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK);
2523: }
2524: break;
2525:
2526: default:
2527: abort:
2528: {
2529: /*
2530: * Something unexpected happened -- deal with it.
2531: */
2532: printf("next: aborting asr 0x%02x csr 0x%02x\n", asr, csr);
2533:
2534: #ifdef DDB
2535: Debugger();
2536: #endif
2537:
2538: #ifdef DEBUG
2539: dev->sc_dmatimo = 0;
2540: if ( data_pointer_debug > 1 )
2541: printf("next dmastop: %d(%x:%x)\n", dev->target,
2542: dev->sc_cur->dc_addr,
2543: dev->sc_tcnt);
2544: #endif
2545:
2546: dev->sc_dmastop(dev);
2547: SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
2548: if ( dev->sc_xs ) sbicerror(dev, csr);
2549: sbicabort(dev, "next");
2550:
2551: if ( dev->sc_flags & SBICF_INDMA ) {
2552: dev->sc_flags &= ~(SBICF_INDMA | SBICF_DCFLUSH);
2553:
2554: #ifdef DEBUG
2555: dev->sc_dmatimo = 0;
2556: if ( data_pointer_debug > 1 )
2557: printf("next dmastop: %d(%x:%x)\n", dev->target,
2558: dev->sc_cur->dc_addr,
2559: dev->sc_tcnt);
2560: #endif
2561: sbic_scsidone(acb, -1);
2562: }
2563:
2564: return SBIC_STATE_ERROR;
2565: }
2566: }
2567:
2568: return(SBIC_STATE_RUNNING);
2569: }
2570:
2571:
2572: /*
2573: * Check if DMA can not be used with specified buffer
2574: */
2575: int
2576: sbiccheckdmap(bp, len, mask)
2577: void *bp;
2578: u_long len,
2579: mask;
2580: {
2581: u_char *buffer;
2582: u_long phy_buf;
2583: u_long phy_len;
2584:
2585: buffer = bp;
2586:
2587: if ( len == 0 )
2588: return(1);
2589:
2590: while ( len ) {
2591:
2592: phy_buf = kvtop((vaddr_t)buffer);
2593: phy_len = NBPG - ((int) buffer & PGOFSET);
2594:
2595: if ( len < phy_len )
2596: phy_len = len;
2597:
2598: if ( phy_buf & mask )
2599: return(1);
2600:
2601: buffer += phy_len;
2602: len -= phy_len;
2603: }
2604:
2605: return(0);
2606: }
2607:
2608: int
2609: sbictoscsiperiod(dev, a)
2610: struct sbic_softc *dev;
2611: int a;
2612: {
2613: unsigned int fs;
2614:
2615: /*
2616: * cycle = DIV / (2 * CLK)
2617: * DIV = FS + 2
2618: * best we can do is 200ns at 20MHz, 2 cycles
2619: */
2620:
2621: GET_SBIC_myid(dev->sc_sbicp, fs);
2622:
2623: fs = (fs >> 6) + 2; /* DIV */
2624:
2625: fs = (fs * 10000) / (dev->sc_clkfreq << 1); /* Cycle, in ns */
2626:
2627: if ( a < 2 )
2628: a = 8; /* map to Cycles */
2629:
2630: return ( (fs * a) >> 2 ); /* in 4 ns units */
2631: }
2632:
2633: int
2634: sbicfromscsiperiod(dev, p)
2635: struct sbic_softc *dev;
2636: int p;
2637: {
2638: unsigned fs,
2639: ret;
2640:
2641: /*
2642: * Just the inverse of the above
2643: */
2644: GET_SBIC_myid(dev->sc_sbicp, fs);
2645:
2646: fs = (fs >> 6) + 2; /* DIV */
2647:
2648: fs = (fs * 10000) / (dev->sc_clkfreq << 1); /* Cycle, in ns */
2649:
2650: ret = p << 2; /* in ns units */
2651: ret = ret / fs; /* in Cycles */
2652:
2653: if ( ret < sbic_min_period )
2654: return(sbic_min_period);
2655:
2656: /*
2657: * verify rounding
2658: */
2659: if ( sbictoscsiperiod(dev, ret) < p )
2660: ret++;
2661:
2662: return( (ret >= 8) ? 0 : ret );
2663: }
2664:
2665: #ifdef DEBUG
2666: void
2667: sbictimeout(dev)
2668: struct sbic_softc *dev;
2669: {
2670: int s,
2671: asr;
2672:
2673: s = splbio();
2674:
2675: if ( dev->sc_dmatimo ) {
2676:
2677: if ( dev->sc_dmatimo > 1 ) {
2678:
2679: printf("%s: dma timeout #%d\n", dev->sc_dev.dv_xname,
2680: dev->sc_dmatimo - 1);
2681:
2682: GET_SBIC_asr(dev->sc_sbicp, asr);
2683:
2684: if ( asr & SBIC_ASR_INT ) {
2685: /*
2686: * We need to service a missed IRQ
2687: */
2688: sbicintr(dev);
2689: } else {
2690: (void) sbicabort(dev, "timeout");
2691: splx(s);
2692: return;
2693: }
2694: }
2695:
2696: dev->sc_dmatimo++;
2697: }
2698:
2699: splx(s);
2700:
2701: timeout((void *)sbictimeout, dev, 30 * hz);
2702: }
2703: #endif
CVSweb