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