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