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