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