mha.c revision 1.12 1 /* $NetBSD: mha.c,v 1.12 1999/02/07 15:18:58 minoura Exp $ */
2
3 /*
4 * Copyright (c) 1996 Masaru Oki, Takumi Nakamura and Masanobu Saitoh. All rights reserved.
5 * Copyright (c) 1994, 1995, 1996 Charles M. Hannum. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Charles M. Hannum.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * Copyright (c) 1994 Jarle Greipsland
22 * All rights reserved.
23 *
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions
26 * are met:
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
29 * 2. Redistributions in binary form must reproduce the above copyright
30 * notice, this list of conditions and the following disclaimer in the
31 * documentation and/or other materials provided with the distribution.
32 * 3. The name of the author may not be used to endorse or promote products
33 * derived from this software without specific prior written permission.
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
36 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
39 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
40 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
41 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
43 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
44 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
45 * POSSIBILITY OF SUCH DAMAGE.
46 */
47
48 #include "opt_ddb.h"
49
50 /* Synchronous data transfers? */
51 #define SPC_USE_SYNCHRONOUS 0
52 #define SPC_SYNC_REQ_ACK_OFS 8
53
54 /* Default DMA mode? */
55 #define MHA_DMA_LIMIT_XFER 1
56 #define MHA_DMA_BURST_XFER 1
57 #define MHA_DMA_SHORT_BUS_CYCLE 1
58
59 #define MHA_DMA_DATAIN (0 | (MHA_DMA_LIMIT_XFER << 1) \
60 | (MHA_DMA_BURST_XFER << 2) \
61 | (MHA_DMA_SHORT_BUS_CYCLE << 3))
62 #define MHA_DMA_DATAOUT (1 | (MHA_DMA_LIMIT_XFER << 1) \
63 | (MHA_DMA_BURST_XFER << 2) \
64 | (MHA_DMA_SHORT_BUS_CYCLE << 3))
65
66 /* Include debug functions? At the end of this file there are a bunch of
67 * functions that will print out various information regarding queued SCSI
68 * commands, driver state and chip contents. You can call them from the
69 * kernel debugger. If you set SPC_DEBUG to 0 they are not included (the
70 * kernel uses less memory) but you lose the debugging facilities.
71 */
72 #define SPC_DEBUG 0
73
74 /* End of customizable parameters */
75
76 /*
77 * MB86601A SCSI Protocol Controller (SPC) routines for MANKAI Mach-2
78 */
79
80 #include <sys/types.h>
81 #include <sys/param.h>
82 #include <sys/systm.h>
83 #include <sys/kernel.h>
84 #include <sys/errno.h>
85 #include <sys/ioctl.h>
86 #include <sys/device.h>
87 #include <sys/buf.h>
88 #include <sys/proc.h>
89 #include <sys/user.h>
90 #include <sys/queue.h>
91
92 #include <dev/scsipi/scsi_all.h>
93 #include <dev/scsipi/scsipi_all.h>
94 #include <dev/scsipi/scsi_message.h>
95 #include <dev/scsipi/scsiconf.h>
96
97 #include <x68k/x68k/iodevice.h>
98 #include <x68k/dev/mb86601reg.h>
99 #include <x68k/dev/mhavar.h>
100 #include <x68k/dev/dmavar.h>
101
102 #if 0
103 #define WAIT {if (sc->sc_pc[2]) {printf("[W_%d", __LINE__); while (sc->sc_pc[2] & 0x40);printf("]");}}
104 #else
105 #define WAIT {while (sc->sc_pc[2] & 0x40);}
106 #endif
107
108 #define SSR (sc->sc_pc[2])
109 #define SS_IREQUEST 0x80
110 #define SS_BUSY 0x40
111 #define SS_DREG_FULL 0x02
112
113 #define NSR (sc->sc_pc[3])
114
115 #define SIR (sc->sc_pc[4])
116
117 #define CMR (sc->sc_pc[5])
118 #define CMD_SEL_AND_CMD 0x00
119 #define CMD_SELECT 0x09
120 #define CMD_SET_ATN 0x0a
121 #define CMD_RESET_ATN 0x0b
122 #define CMD_RESET_ACK 0x0d
123 #define CMD_SEND_FROM_MPU 0x10
124 #define CMD_SEND_FROM_DMA 0x11
125 #define CMD_RECEIVE_TO_MPU 0x12
126 #define CMD_RECEIVE_TO_DMA 0x13
127 #define CMD_RECEIVE_MSG 0x1a
128 #define CMD_RECEIVE_STS 0x1c
129 #define CMD_SOFT_RESET 0x40
130 #define CMD_SCSI_RESET 0x42
131 #define CMD_SET_UP_REG 0x43
132
133 #define SCR (sc->sc_pc[11])
134
135 #define TMR (sc->sc_pc[12])
136 #define TM_SYNC 0x80
137 #define TM_ASYNC 0x00
138
139 #define WAR (sc->sc_pc[15])
140 #define WA_MCSBUFWIN 0x00
141 #define WA_UPMWIN 0x80
142 #define WA_INITWIN 0xc0
143
144 #define MBR (sc->sc_pc[15])
145
146 #define ISCSR (sc->sc_ps[2])
147
148 #define CCR (sc->sc_pcx[0])
149 #define OIR (sc->sc_pcx[1])
150 #define AMR (sc->sc_pcx[2])
151 #define SMR (sc->sc_pcx[3])
152 #define SRR (sc->sc_pcx[4])
153 #define STR (sc->sc_pcx[5])
154 #define RTR (sc->sc_pcx[6])
155 #define ATR (sc->sc_pcx[7])
156 #define PER (sc->sc_pcx[8])
157 #define IER (sc->sc_pcx[9])
158 #define IE_ALL 0xBF
159
160 #define GLR (sc->sc_pcx[10])
161 #define DMR (sc->sc_pcx[11])
162 #define IMR (sc->sc_pcx[12])
163
164
165 #ifndef DDB
167 #define Debugger() panic("should call debugger here (mha.c)")
168 #endif /* ! DDB */
169
170
171 #if SPC_DEBUG
172 #define SPC_SHOWACBS 0x01
173 #define SPC_SHOWINTS 0x02
174 #define SPC_SHOWCMDS 0x04
175 #define SPC_SHOWMISC 0x08
176 #define SPC_SHOWTRAC 0x10
177 #define SPC_SHOWSTART 0x20
178 #define SPC_SHOWPHASE 0x40
179 #define SPC_SHOWDMA 0x80
180 #define SPC_SHOWCCMDS 0x100
181 #define SPC_SHOWMSGS 0x200
182 #define SPC_DOBREAK 0x400
183
184 int mha_debug =
185 #if 0
186 0x7FF;
187 #else
188 SPC_SHOWSTART|SPC_SHOWTRAC;
189 #endif
190
191
192 #define SPC_ACBS(str) do {if (mha_debug & SPC_SHOWACBS) printf str;} while (0)
193 #define SPC_MISC(str) do {if (mha_debug & SPC_SHOWMISC) printf str;} while (0)
194 #define SPC_INTS(str) do {if (mha_debug & SPC_SHOWINTS) printf str;} while (0)
195 #define SPC_TRACE(str) do {if (mha_debug & SPC_SHOWTRAC) printf str;} while (0)
196 #define SPC_CMDS(str) do {if (mha_debug & SPC_SHOWCMDS) printf str;} while (0)
197 #define SPC_START(str) do {if (mha_debug & SPC_SHOWSTART) printf str;}while (0)
198 #define SPC_PHASE(str) do {if (mha_debug & SPC_SHOWPHASE) printf str;}while (0)
199 #define SPC_DMA(str) do {if (mha_debug & SPC_SHOWDMA) printf str;}while (0)
200 #define SPC_MSGS(str) do {if (mha_debug & SPC_SHOWMSGS) printf str;}while (0)
201 #define SPC_BREAK() do {if ((mha_debug & SPC_DOBREAK) != 0) Debugger();} while (0)
202 #define SPC_ASSERT(x) do {if (x) {} else {printf("%s at line %d: assertion failed\n", sc->sc_dev.dv_xname, __LINE__); Debugger();}} while (0)
203 #else
204 #define SPC_ACBS(str)
205 #define SPC_MISC(str)
206 #define SPC_INTS(str)
207 #define SPC_TRACE(str)
208 #define SPC_CMDS(str)
209 #define SPC_START(str)
210 #define SPC_PHASE(str)
211 #define SPC_DMA(str)
212 #define SPC_MSGS(str)
213 #define SPC_BREAK()
214 #define SPC_ASSERT(x)
215 #endif
216
217 int mhamatch __P((struct device *, struct cfdata *, void *));
218 void mhaattach __P((struct device *, struct device *, void *));
219 void mhaselect __P((struct mha_softc *,
220 u_char, u_char, u_char *, u_char));
221 void mha_scsi_reset __P((struct mha_softc *));
222 void mha_reset __P((struct mha_softc *));
223 void mha_free_acb __P((struct mha_softc *, struct acb *, int));
224 void mha_sense __P((struct mha_softc *, struct acb *));
225 void mha_msgin __P((struct mha_softc *));
226 void mha_msgout __P((struct mha_softc *));
227 int mha_dataout_pio __P((struct mha_softc *, u_char *, int));
228 int mha_datain_pio __P((struct mha_softc *, u_char *, int));
229 int mha_dataout __P((struct mha_softc *, u_char *, int));
230 int mha_datain __P((struct mha_softc *, u_char *, int));
231 void mha_abort __P((struct mha_softc *, struct acb *));
232 void mha_init __P((struct mha_softc *));
233 int mha_scsi_cmd __P((struct scsipi_xfer *));
234 int mha_poll __P((struct mha_softc *, struct acb *));
235 void mha_sched __P((struct mha_softc *));
236 void mha_done __P((struct mha_softc *, struct acb *));
237 int mhaintr __P((int));
238 void mha_timeout __P((void *));
239 void mha_minphys __P((struct buf *));
240 void mha_dequeue __P((struct mha_softc *, struct acb *));
241 inline void mha_setsync __P((struct mha_softc *, struct spc_tinfo *));
242 #if SPC_DEBUG
243 void mha_print_acb __P((struct acb *));
244 void mha_show_scsi_cmd __P((struct acb *));
245 void mha_print_active_acb __P((void));
246 void mha_dump_driver __P((struct mha_softc *));
247 #endif
248 volatile void * mha_find __P((int));
249
250 static int mha_dataio_dma __P((int, int, struct mha_softc *, u_char *, int));
251
252 struct cfattach mha_ca = {
253 sizeof(struct mha_softc), mhamatch, mhaattach
254 };
255
256 extern struct cfdriver mha_cd;
257
258 struct scsipi_device mha_dev = {
259 NULL, /* Use default error handler */
260 NULL, /* have a queue, served by this */
261 NULL, /* have no async handler */
262 NULL, /* Use default 'done' routine */
263 };
264
265 /*
267 * returns non-zero value if a controller is found.
268 */
269 int
270 mhamatch(parent, cf, aux)
271 struct device *parent;
272 struct cfdata *cf;
273 void *aux;
274 {
275 if (strcmp(aux, "mha") || mha_find(cf->cf_unit) == 0)
276 return 0;
277 return 1;
278 }
279
280 /*
281 * Find the board
282 */
283 volatile void *
284 mha_find(unit)
285 int unit;
286 {
287 volatile void *addr;
288
289 if (unit > 1)
290 return 0;
291 /* Find only on-board ROM */
292 if (badaddr(IODEVbase->exscsirom)
293 || bcmp((void *)&IODEVbase->exscsirom[0x24], "SCSIEX", 6))
294 return 0;
295
296 /* If bdid exists, this board is ``CZ-6BS1'' */
297 if (!badbaddr(&IODEVbase->io_exspc.bdid))
298 return 0;
299
300 return (void *)(&IODEVbase->exscsirom[0x60]);
301 }
302
303 /*
304 */
305
306 struct mha_softc *tmpsc;
307
308 void
309 mhaattach(parent, self, aux)
310 struct device *parent, *self;
311 void *aux;
312 {
313 struct mha_softc *sc = (void *)self;
314
315 tmpsc = sc; /* XXX */
316
317 SPC_TRACE(("mhaattach "));
318 sc->sc_state = SPC_INIT;
319 sc->sc_iobase = mha_find(sc->sc_dev.dv_unit); /* XXX */
320
321 sc->sc_pc = (volatile u_char *)sc->sc_iobase;
322 sc->sc_ps = (volatile u_short *)sc->sc_iobase;
323 sc->sc_pcx = &sc->sc_pc[0x10];
324
325 sc->sc_id = IODEVbase->io_sram[0x70] & 0x7; /* XXX */
326
327 mha_init(sc); /* Init chip and driver */
328
329 printf("\n%s: Resetting SCSI bus... ", self->dv_xname);
330 mha_scsi_reset(sc); /* XXX: some devices need this. */
331 printf("done\n");
332
333 sc->sc_phase = BUSFREE_PHASE;
334
335 /*
336 * Fill in the adapter.
337 */
338 sc->sc_adapter.scsipi_cmd = mha_scsi_cmd;
339 sc->sc_adapter.scsipi_minphys = mha_minphys;
340
341 /*
342 * Fill in the prototype scsi_link
343 */
344 sc->sc_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
345 sc->sc_link.adapter_softc = sc;
346 sc->sc_link.scsipi_scsi.adapter_target = sc->sc_id;
347 sc->sc_link.adapter = &sc->sc_adapter;
348 sc->sc_link.device = &mha_dev;
349 sc->sc_link.openings = 2;
350 sc->sc_link.scsipi_scsi.max_target = 7;
351 sc->sc_link.scsipi_scsi.max_lun = 7;
352 sc->sc_link.type = BUS_SCSI;
353
354 sc->sc_spcinitialized = 0;
355 WAR = WA_INITWIN;
356 #if 1
357 CCR = 0x14;
358 OIR = sc->sc_id;
359 AMR = 0x00;
360 SMR = 0x00;
361 SRR = 0x00;
362 STR = 0x20;
363 RTR = 0x40;
364 ATR = 0x01;
365 PER = 0xc9;
366 #endif
367 IER = IE_ALL; /* $B$9$Y$F$N3d$j9~$_$r5v2D(B */
368 #if 1
369 GLR = 0x00;
370 DMR = 0x30;
371 IMR = 0x00;
372 #endif
373 WAR = WA_MCSBUFWIN;
374
375 /* drop off */
376 while (SSR & SS_IREQUEST)
377 {
378 unsigned a = ISCSR;
379 }
380
381 CMR = CMD_SET_UP_REG; /* setup reg cmd. */
382
383 SPC_TRACE(("waiting for intr..."));
384 while (!(SSR & SS_IREQUEST))
385 delay(10);
386 mhaintr (sc->sc_dev.dv_unit);
387
388 tmpsc = NULL;
389
390 config_found(self, &sc->sc_link, scsiprint);
391 }
392
393 #if 0
394 void
395 mha_reset(sc)
396 struct mha_softc *sc;
397 {
398 u_short dummy;
399 printf("reset...");
400 CMR = CMD_SOFT_RESET;
401 asm volatile ("nop"); /* XXX wait (4clk in 20mhz) ??? */
402 dummy = sc->sc_ps[-1];
403 dummy = sc->sc_ps[-1];
404 dummy = sc->sc_ps[-1];
405 dummy = sc->sc_ps[-1];
406 asm volatile ("nop");
407 CMR = CMD_SOFT_RESET;
408 sc->sc_spcinitialized = 0;
409 CMR = CMD_SET_UP_REG; /* setup reg cmd. */
410 while(!sc->sc_spcinitialized);
411
412 sc->sc_id = IODEVbase->io_sram[0x70] & 0x7; /* XXX */
413 printf("done.\n");
414 }
415 #endif
416
417 /*
418 * Pull the SCSI RST line for 500us.
419 */
420 void
421 mha_scsi_reset(sc) /* FINISH? */
422 struct mha_softc *sc;
423 {
424
425 CMR = CMD_SCSI_RESET; /* SCSI RESET */
426 while (!(SSR&SS_IREQUEST))
427 delay(10);
428 }
429
430 /*
431 * Initialize mha SCSI driver.
432 */
433 void
434 mha_init(sc)
435 struct mha_softc *sc;
436 {
437 struct acb *acb;
438 int r;
439
440 if (sc->sc_state == SPC_INIT) {
441 /* First time through; initialize. */
442 TAILQ_INIT(&sc->ready_list);
443 TAILQ_INIT(&sc->nexus_list);
444 TAILQ_INIT(&sc->free_list);
445 sc->sc_nexus = NULL;
446 acb = sc->sc_acb;
447 bzero(acb, sizeof(sc->sc_acb));
448 for (r = 0; r < sizeof(sc->sc_acb) / sizeof(*acb); r++) {
449 TAILQ_INSERT_TAIL(&sc->free_list, acb, chain);
450 acb++;
451 }
452 bzero(&sc->sc_tinfo, sizeof(sc->sc_tinfo));
453 } else {
454 /* Cancel any active commands. */
455 sc->sc_flags |= SPC_ABORTING;
456 sc->sc_state = SPC_IDLE;
457 if ((acb = sc->sc_nexus) != NULL) {
458 acb->xs->error = XS_DRIVER_STUFFUP;
459 mha_done(sc, acb);
460 }
461 while ((acb = sc->nexus_list.tqh_first) != NULL) {
462 acb->xs->error = XS_DRIVER_STUFFUP;
463 mha_done(sc, acb);
464 }
465 }
466
467 sc->sc_phase = sc->sc_prevphase = INVALID_PHASE;
468 for (r = 0; r < 8; r++) {
469 struct spc_tinfo *ti = &sc->sc_tinfo[r];
470
471 ti->flags = 0;
472 #if SPC_USE_SYNCHRONOUS
473 ti->flags |= T_SYNCMODE;
474 ti->period = sc->sc_minsync;
475 ti->offset = SPC_SYNC_REQ_ACK_OFS;
476 #else
477 ti->period = ti->offset = 0;
478 #endif
479 ti->width = 0;
480 }
481
482 sc->sc_state = SPC_IDLE;
483 }
484
485 void
486 mha_free_acb(sc, acb, flags)
487 struct mha_softc *sc;
488 struct acb *acb;
489 int flags;
490 {
491 int s;
492
493 s = splbio();
494
495 acb->flags = 0;
496 TAILQ_INSERT_HEAD(&sc->free_list, acb, chain);
497
498 /*
499 * If there were none, wake anybody waiting for one to come free,
500 * starting with queued entries.
501 */
502 if (acb->chain.tqe_next == 0)
503 wakeup(&sc->free_list);
504
505 splx(s);
506 }
507
508
509 /*
511 * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
512 */
513
514 /*
515 * Expected sequence:
516 * 1) Command inserted into ready list
517 * 2) Command selected for execution
518 * 3) Command won arbitration and has selected target device
519 * 4) Send message out (identify message, eventually also sync.negotiations)
520 * 5) Send command
521 * 5a) Receive disconnect message, disconnect.
522 * 5b) Reselected by target
523 * 5c) Receive identify message from target.
524 * 6) Send or receive data
525 * 7) Receive status
526 * 8) Receive message (command complete etc.)
527 * 9) If status == SCSI_CHECK construct a synthetic request sense SCSI cmd.
528 * Repeat 2-8 (no disconnects please...)
529 */
530
531 /*
532 * Start a selection. This is used by mha_sched() to select an idle target,
533 * and by mha_done() to immediately reselect a target to get sense information.
534 */
535 void
536 mhaselect(sc, target, lun, cmd, clen)
537 struct mha_softc *sc;
538 u_char target, lun;
539 u_char *cmd;
540 u_char clen;
541 {
542 #if 0
543 struct scsi_link *sc_link = acb->xs->sc_link;
544 #endif
545 struct spc_tinfo *ti = &sc->sc_tinfo[target];
546 int i;
547 int s;
548
549 s = splbio(); /* XXX */
550
551 SPC_TRACE(("[mhaselect(t%d,l%d,cmd:%x)] ", target, lun, *(u_char *)cmd));
552
553 /* CDB $B$r(B SPC $B$N(B MCS REG $B$K%;%C%H$9$k(B */
554 /* Now the command into the FIFO */
555 WAIT;
556 #if 1
557 SPC_MISC(("[cmd:"));
558 for (i = 0; i < clen; i++)
559 {
560 unsigned c = cmd[i];
561 if (i == 1)
562 c |= lun << 5;
563 SPC_MISC((" %02x", c));
564 sc->sc_pcx[i] = c;
565 }
566 SPC_MISC(("], target=%d\n", target));
567 #else
568 bcopy(cmd, sc->sc_pcx, clen);
569 #endif
570 if (NSR & 0x80)
571 panic("scsistart: already selected...");
572 sc->sc_phase = COMMAND_PHASE;
573
574 /* new state ASP_SELECTING */
575 sc->sc_state = SPC_SELECTING;
576
577 SIR = target;
578 #if 0
579 CMR = CMD_SELECT;
580 #else
581 CMR = CMD_SEL_AND_CMD; /* select & cmd */
582 #endif
583 splx(s);
584 }
585
586 #if 0
587 int
588 mha_reselect(sc, message)
589 struct mha_softc *sc;
590 u_char message;
591 {
592 u_char selid, target, lun;
593 struct acb *acb;
594 struct scsipi_link *sc_link;
595 struct spc_tinfo *ti;
596
597 /*
598 * The SCSI chip made a snapshot of the data bus while the reselection
599 * was being negotiated. This enables us to determine which target did
600 * the reselect.
601 */
602 selid = sc->sc_selid & ~(1 << sc->sc_id);
603 if (selid & (selid - 1)) {
604 printf("%s: reselect with invalid selid %02x; sending DEVICE RESET\n",
605 sc->sc_dev.dv_xname, selid);
606 SPC_BREAK();
607 goto reset;
608 }
609
610 /*
611 * Search wait queue for disconnected cmd
612 * The list should be short, so I haven't bothered with
613 * any more sophisticated structures than a simple
614 * singly linked list.
615 */
616 target = ffs(selid) - 1;
617 lun = message & 0x07;
618 for (acb = sc->nexus_list.tqh_first; acb != NULL;
619 acb = acb->chain.tqe_next) {
620 sc_link = acb->xs->sc_link;
621 if (sc_link->scsipi_scsi.target == target &&
622 sc_link->scsipi_scsi.lun == lun)
623 break;
624 }
625 if (acb == NULL) {
626 printf("%s: reselect from target %d lun %d with no nexus; sending ABORT\n",
627 sc->sc_dev.dv_xname, target, lun);
628 SPC_BREAK();
629 goto abort;
630 }
631
632 /* Make this nexus active again. */
633 TAILQ_REMOVE(&sc->nexus_list, acb, chain);
634 sc->sc_state = SPC_HASNEXUS;
635 sc->sc_nexus = acb;
636 ti = &sc->sc_tinfo[target];
637 ti->lubusy |= (1 << lun);
638 mha_setsync(sc, ti);
639
640 if (acb->flags & ACB_RESET)
641 mha_sched_msgout(sc, SEND_DEV_RESET);
642 else if (acb->flags & ACB_ABORTED)
643 mha_sched_msgout(sc, SEND_ABORT);
644
645 /* Do an implicit RESTORE POINTERS. */
646 sc->sc_dp = acb->daddr;
647 sc->sc_dleft = acb->dleft;
648 sc->sc_cp = (u_char *)&acb->cmd;
649 sc->sc_cleft = acb->clen;
650
651 return (0);
652
653 reset:
654 mha_sched_msgout(sc, SEND_DEV_RESET);
655 return (1);
656
657 abort:
658 mha_sched_msgout(sc, SEND_ABORT);
659 return (1);
660 }
661 #endif
662 /*
663 * Start a SCSI-command
664 * This function is called by the higher level SCSI-driver to queue/run
665 * SCSI-commands.
666 */
667 int
668 mha_scsi_cmd(xs)
669 struct scsipi_xfer *xs;
670 {
671 struct scsipi_link *sc_link = xs->sc_link;
672 struct mha_softc *sc = sc_link->adapter_softc;
673 struct acb *acb;
674 int s, flags;
675
676 SPC_TRACE(("[mha_scsi_cmd] "));
677 SPC_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
678 sc_link->scsipi_scsi.target));
679
680 flags = xs->flags;
681
682 /* Get a mha command block */
683 s = splbio();
684 acb = sc->free_list.tqh_first;
685 if (acb) {
686 TAILQ_REMOVE(&sc->free_list, acb, chain);
687 ACB_SETQ(acb, ACB_QNONE);
688 }
689 splx(s);
690
691 if (acb == NULL) {
692 SPC_MISC(("TRY_AGAIN_LATER"));
693 return TRY_AGAIN_LATER;
694 }
695
696 /* Initialize acb */
697 acb->xs = xs;
698 bcopy(xs->cmd, &acb->cmd, xs->cmdlen);
699 acb->clen = xs->cmdlen;
700 acb->daddr = xs->data;
701 acb->dleft = xs->datalen;
702 acb->stat = 0;
703
704 s = splbio();
705 ACB_SETQ(acb, ACB_QREADY);
706 TAILQ_INSERT_TAIL(&sc->ready_list, acb, chain);
707 #if 1
708 timeout(mha_timeout, acb, (xs->timeout*hz)/1000);
709 #endif
710
711 /*
712 * $B%-%e!<$N=hM}Cf$G$J$1$l$P!"%9%1%8%e!<%j%s%03+;O$9$k(B
713 */
714 if (sc->sc_state == SPC_IDLE)
715 mha_sched(sc);
716
717 splx(s);
718
719 if (flags & SCSI_POLL) {
720 /* Not allowed to use interrupts, use polling instead */
721 return mha_poll(sc, acb);
722 }
723
724 SPC_MISC(("SUCCESSFULLY_QUEUED"));
725 return SUCCESSFULLY_QUEUED;
726 }
727
728 /*
729 * Adjust transfer size in buffer structure
730 */
731 void
732 mha_minphys(bp)
733 struct buf *bp;
734 {
735
736 SPC_TRACE(("mha_minphys "));
737 minphys(bp);
738 }
739
740 /*
741 * Used when interrupt driven I/O isn't allowed, e.g. during boot.
742 */
743 int
744 mha_poll(sc, acb)
745 struct mha_softc *sc;
746 struct acb *acb;
747 {
748 struct scsipi_xfer *xs = acb->xs;
749 int count = xs->timeout * 100;
750 int s = splbio();
751
752 SPC_TRACE(("[mha_poll] "));
753
754 while (count) {
755 /*
756 * If we had interrupts enabled, would we
757 * have got an interrupt?
758 */
759 if (SSR & SS_IREQUEST)
760 mhaintr(sc->sc_dev.dv_unit);
761 if ((xs->flags & ITSDONE) != 0)
762 break;
763 DELAY(10);
764 #if 1
765 if (sc->sc_state == SPC_IDLE) {
766 SPC_TRACE(("[mha_poll: rescheduling] "));
767 mha_sched(sc);
768 }
769 #endif
770 count--;
771 }
772
773 if (count == 0) {
774 SPC_MISC(("mha_poll: timeout"));
775 mha_timeout((caddr_t)acb);
776 }
777 splx(s);
778 return COMPLETE;
779 }
780
781 /*
783 * LOW LEVEL SCSI UTILITIES
784 */
785
786 /*
787 * Set synchronous transfer offset and period.
788 */
789 inline void
790 mha_setsync(sc, ti)
791 struct mha_softc *sc;
792 struct spc_tinfo *ti;
793 {
794 }
795
796
797 /*
799 * Schedule a SCSI operation. This has now been pulled out of the interrupt
800 * handler so that we may call it from mha_scsi_cmd and mha_done. This may
801 * save us an unecessary interrupt just to get things going. Should only be
802 * called when state == SPC_IDLE and at bio pl.
803 */
804 void
805 mha_sched(sc)
806 register struct mha_softc *sc;
807 {
808 struct scsipi_link *sc_link;
809 struct acb *acb;
810 int t;
811
812 SPC_TRACE(("[mha_sched] "));
813 if (sc->sc_state != SPC_IDLE)
814 panic("mha_sched: not IDLE (state=%d)", sc->sc_state);
815
816 if (sc->sc_flags & SPC_ABORTING)
817 return;
818
819 /*
820 * Find first acb in ready queue that is for a target/lunit
821 * combinations that is not busy.
822 */
823 for (acb = sc->ready_list.tqh_first; acb ; acb = acb->chain.tqe_next) {
824 struct spc_tinfo *ti;
825 sc_link = acb->xs->sc_link;
826 t = sc_link->scsipi_scsi.target;
827 ti = &sc->sc_tinfo[t];
828 if (!(ti->lubusy & (1 << sc_link->scsipi_scsi.lun))) {
829 if ((acb->flags & ACB_QBITS) != ACB_QREADY)
830 panic("mha: busy entry on ready list");
831 TAILQ_REMOVE(&sc->ready_list, acb, chain);
832 ACB_SETQ(acb, ACB_QNONE);
833 sc->sc_nexus = acb;
834 sc->sc_flags = 0;
835 sc->sc_prevphase = INVALID_PHASE;
836 sc->sc_dp = acb->daddr;
837 sc->sc_dleft = acb->dleft;
838 ti->lubusy |= (1<<sc_link->scsipi_scsi.lun);
839 mhaselect(sc, t, sc_link->scsipi_scsi.lun,
840 (u_char *)&acb->cmd, acb->clen);
841 break;
842 } else {
843 SPC_MISC(("%d:%d busy\n",
844 sc_link->scsipi_scsi.target,
845 sc_link->scsipi_scsi.lun));
846 }
847 }
848 }
849
850 void
852 mha_sense(sc, acb)
853 struct mha_softc *sc;
854 struct acb *acb;
855 {
856 struct scsipi_xfer *xs = acb->xs;
857 struct scsipi_link *sc_link = xs->sc_link;
858 struct spc_tinfo *ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
859 struct scsipi_sense *ss = (void *)&acb->cmd;
860
861 SPC_MISC(("requesting sense "));
862 /* Next, setup a request sense command block */
863 bzero(ss, sizeof(*ss));
864 ss->opcode = REQUEST_SENSE;
865 ss->byte2 = sc_link->scsipi_scsi.lun << 5;
866 ss->length = sizeof(struct scsipi_sense_data);
867 acb->clen = sizeof(*ss);
868 acb->daddr = (char *)&xs->sense;
869 acb->dleft = sizeof(struct scsipi_sense_data);
870 acb->flags |= ACB_CHKSENSE;
871 ti->senses++;
872 if (acb->flags & ACB_QNEXUS)
873 ti->lubusy &= ~(1 << sc_link->scsipi_scsi.lun);
874 if (acb == sc->sc_nexus) {
875 mhaselect(sc, sc_link->scsipi_scsi.target,
876 sc_link->scsipi_scsi.lun,
877 (void *)&acb->cmd, acb->clen);
878 } else {
879 mha_dequeue(sc, acb);
880 TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
881 if (sc->sc_state == SPC_IDLE)
882 mha_sched(sc);
883 }
884 }
885
886 /*
887 * POST PROCESSING OF SCSI_CMD (usually current)
888 */
889 void
890 mha_done(sc, acb)
891 struct mha_softc *sc;
892 struct acb *acb;
893 {
894 struct scsipi_xfer *xs = acb->xs;
895 struct scsipi_link *sc_link = xs->sc_link;
896 struct spc_tinfo *ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
897
898 SPC_TRACE(("[mha_done(error:%x)] ", xs->error));
899
900 #if 1
901 untimeout(mha_timeout, acb);
902 #endif
903
904 /*
905 * Now, if we've come here with no error code, i.e. we've kept the
906 * initial XS_NOERROR, and the status code signals that we should
907 * check sense, we'll need to set up a request sense cmd block and
908 * push the command back into the ready queue *before* any other
909 * commands for this target/lunit, else we lose the sense info.
910 * We don't support chk sense conditions for the request sense cmd.
911 */
912 if (xs->error == XS_NOERROR) {
913 if ((acb->flags & ACB_ABORTED) != 0) {
914 xs->error = XS_TIMEOUT;
915 } else if (acb->flags & ACB_CHKSENSE) {
916 xs->error = XS_SENSE;
917 } else {
918 switch (acb->stat & ST_MASK) {
919 case SCSI_CHECK:
920 {
921 struct scsipi_sense *ss = (void *)&acb->cmd;
922 SPC_MISC(("requesting sense "));
923 /* First, save the return values */
924 xs->resid = acb->dleft;
925 xs->status = acb->stat;
926 /* Next, setup a request sense command block */
927 bzero(ss, sizeof(*ss));
928 ss->opcode = REQUEST_SENSE;
929 /*ss->byte2 = sc_link->lun << 5;*/
930 ss->length = sizeof(struct scsipi_sense_data);
931 acb->clen = sizeof(*ss);
932 acb->daddr = (char *)&xs->sense;
933 acb->dleft = sizeof(struct scsipi_sense_data);
934 acb->flags |= ACB_CHKSENSE;
935 /*XXX - must take off queue here */
936 if (acb != sc->sc_nexus) {
937 panic("%s: mha_sched: floating acb %p",
938 sc->sc_dev.dv_xname, acb);
939 }
940 TAILQ_INSERT_HEAD(&sc->ready_list, acb, chain);
941 ACB_SETQ(acb, ACB_QREADY);
942 ti->lubusy &= ~(1<<sc_link->scsipi_scsi.lun);
943 ti->senses++;
944 timeout(mha_timeout, acb, (xs->timeout*hz)/1000);
945 if (sc->sc_nexus == acb) {
946 sc->sc_nexus = NULL;
947 sc->sc_state = SPC_IDLE;
948 mha_sched(sc);
949 }
950 #if 0
951 mha_sense(sc, acb);
952 #endif
953 return;
954 }
955 case SCSI_BUSY:
956 xs->error = XS_BUSY;
957 break;
958 case SCSI_OK:
959 xs->resid = acb->dleft;
960 break;
961 default:
962 xs->error = XS_DRIVER_STUFFUP;
963 #if SPC_DEBUG
964 printf("%s: mha_done: bad stat 0x%x\n",
965 sc->sc_dev.dv_xname, acb->stat);
966 #endif
967 break;
968 }
969 }
970 }
971
972 xs->flags |= ITSDONE;
973
974 #if SPC_DEBUG
975 if ((mha_debug & SPC_SHOWMISC) != 0) {
976 if (xs->resid != 0)
977 printf("resid=%d ", xs->resid);
978 if (xs->error == XS_SENSE)
979 printf("sense=0x%02x\n", xs->sense.scsi_sense.error_code);
980 else
981 printf("error=%d\n", xs->error);
982 }
983 #endif
984
985 /*
986 * Remove the ACB from whatever queue it's on.
987 */
988 switch (acb->flags & ACB_QBITS) {
989 case ACB_QNONE:
990 if (acb != sc->sc_nexus) {
991 panic("%s: floating acb", sc->sc_dev.dv_xname);
992 }
993 sc->sc_nexus = NULL;
994 sc->sc_state = SPC_IDLE;
995 ti->lubusy &= ~(1<<sc_link->scsipi_scsi.lun);
996 mha_sched(sc);
997 break;
998 case ACB_QREADY:
999 TAILQ_REMOVE(&sc->ready_list, acb, chain);
1000 break;
1001 case ACB_QNEXUS:
1002 TAILQ_REMOVE(&sc->nexus_list, acb, chain);
1003 ti->lubusy &= ~(1<<sc_link->scsipi_scsi.lun);
1004 break;
1005 case ACB_QFREE:
1006 panic("%s: dequeue: busy acb on free list",
1007 sc->sc_dev.dv_xname);
1008 break;
1009 default:
1010 panic("%s: dequeue: unknown queue %d",
1011 sc->sc_dev.dv_xname, acb->flags & ACB_QBITS);
1012 }
1013
1014 /* Put it on the free list, and clear flags. */
1015 #if 0
1016 TAILQ_INSERT_HEAD(&sc->free_list, acb, chain);
1017 acb->flags = ACB_QFREE;
1018 #else
1019 mha_free_acb(sc, acb, xs->flags);
1020 #endif
1021
1022 ti->cmds++;
1023 scsipi_done(xs);
1024 }
1025
1026 void
1027 mha_dequeue(sc, acb)
1028 struct mha_softc *sc;
1029 struct acb *acb;
1030 {
1031
1032 if (acb->flags & ACB_QNEXUS) {
1033 TAILQ_REMOVE(&sc->nexus_list, acb, chain);
1034 } else {
1035 TAILQ_REMOVE(&sc->ready_list, acb, chain);
1036 }
1037 }
1038
1039 /*
1041 * INTERRUPT/PROTOCOL ENGINE
1042 */
1043
1044 /*
1045 * Schedule an outgoing message by prioritizing it, and asserting
1046 * attention on the bus. We can only do this when we are the initiator
1047 * else there will be an illegal command interrupt.
1048 */
1049 #define mha_sched_msgout(m) \
1050 do { \
1051 SPC_MISC(("mha_sched_msgout %d ", m)); \
1052 CMR = CMD_SET_ATN; \
1053 sc->sc_msgpriq |= (m); \
1054 } while (0)
1055
1056 #define IS1BYTEMSG(m) (((m) != 0x01 && (m) < 0x20) || (m) >= 0x80)
1057 #define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
1058 #define ISEXTMSG(m) ((m) == 0x01)
1059
1060 /*
1061 * Precondition:
1062 * The SCSI bus is already in the MSGI phase and there is a message byte
1063 * on the bus, along with an asserted REQ signal.
1064 */
1065 void
1066 mha_msgin(sc)
1067 register struct mha_softc *sc;
1068 {
1069 register int v;
1070 int n;
1071
1072 SPC_TRACE(("[mha_msgin(curmsglen:%d)] ", sc->sc_imlen));
1073
1074 /*
1075 * Prepare for a new message. A message should (according
1076 * to the SCSI standard) be transmitted in one single
1077 * MESSAGE_IN_PHASE. If we have been in some other phase,
1078 * then this is a new message.
1079 */
1080 if (sc->sc_prevphase != MESSAGE_IN_PHASE) {
1081 sc->sc_flags &= ~SPC_DROP_MSGI;
1082 sc->sc_imlen = 0;
1083 }
1084
1085 WAIT;
1086
1087 v = MBR; /* modified byte */
1088 v = sc->sc_pcx[0];
1089
1090 sc->sc_imess[sc->sc_imlen] = v;
1091
1092 /*
1093 * If we're going to reject the message, don't bother storing
1094 * the incoming bytes. But still, we need to ACK them.
1095 */
1096
1097 if ((sc->sc_flags & SPC_DROP_MSGI)) {
1098 CMR = CMD_SET_ATN;
1099 /* ESPCMD(sc, ESPCMD_MSGOK);*/
1100 printf("<dropping msg byte %x>",
1101 sc->sc_imess[sc->sc_imlen]);
1102 return;
1103 }
1104
1105 if (sc->sc_imlen >= SPC_MAX_MSG_LEN) {
1106 mha_sched_msgout(SEND_REJECT);
1107 sc->sc_flags |= SPC_DROP_MSGI;
1108 } else {
1109 sc->sc_imlen++;
1110 /*
1111 * This testing is suboptimal, but most
1112 * messages will be of the one byte variety, so
1113 * it should not effect performance
1114 * significantly.
1115 */
1116 if (sc->sc_imlen == 1 && IS1BYTEMSG(sc->sc_imess[0]))
1117 goto gotit;
1118 if (sc->sc_imlen == 2 && IS2BYTEMSG(sc->sc_imess[0]))
1119 goto gotit;
1120 if (sc->sc_imlen >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
1121 sc->sc_imlen == sc->sc_imess[1] + 2)
1122 goto gotit;
1123 }
1124 #if 0
1125 /* Ack what we have so far */
1126 ESPCMD(sc, ESPCMD_MSGOK);
1127 #endif
1128 return;
1129
1130 gotit:
1131 SPC_MSGS(("gotmsg(%x)", sc->sc_imess[0]));
1132 /*
1133 * Now we should have a complete message (1 byte, 2 byte
1134 * and moderately long extended messages). We only handle
1135 * extended messages which total length is shorter than
1136 * SPC_MAX_MSG_LEN. Longer messages will be amputated.
1137 */
1138 if (sc->sc_state == SPC_HASNEXUS) {
1139 struct acb *acb = sc->sc_nexus;
1140 struct spc_tinfo *ti =
1141 &sc->sc_tinfo[acb->xs->sc_link->scsipi_scsi.target];
1142
1143 switch (sc->sc_imess[0]) {
1144 case MSG_CMDCOMPLETE:
1145 SPC_MSGS(("cmdcomplete "));
1146 if (sc->sc_dleft < 0) {
1147 struct scsipi_link *sc_link = acb->xs->sc_link;
1148 printf("mha: %d extra bytes from %d:%d\n",
1149 -sc->sc_dleft,
1150 sc_link->scsipi_scsi.target,
1151 sc_link->scsipi_scsi.lun);
1152 sc->sc_dleft = 0;
1153 }
1154 acb->xs->resid = acb->dleft = sc->sc_dleft;
1155 sc->sc_flags |= SPC_BUSFREE_OK;
1156 break;
1157
1158 case MSG_MESSAGE_REJECT:
1159 #if SPC_DEBUG
1160 if (mha_debug & SPC_SHOWMSGS)
1161 printf("%s: our msg rejected by target\n",
1162 sc->sc_dev.dv_xname);
1163 #endif
1164 #if 1 /* XXX - must remember last message */
1165 scsi_print_addr(acb->xs->sc_link); printf("MSG_MESSAGE_REJECT>>");
1166 #endif
1167 if (sc->sc_flags & SPC_SYNCHNEGO) {
1168 ti->period = ti->offset = 0;
1169 sc->sc_flags &= ~SPC_SYNCHNEGO;
1170 ti->flags &= ~T_NEGOTIATE;
1171 }
1172 /* Not all targets understand INITIATOR_DETECTED_ERR */
1173 if (sc->sc_msgout == SEND_INIT_DET_ERR)
1174 mha_sched_msgout(SEND_ABORT);
1175 break;
1176 case MSG_NOOP:
1177 SPC_MSGS(("noop "));
1178 break;
1179 case MSG_DISCONNECT:
1180 SPC_MSGS(("disconnect "));
1181 ti->dconns++;
1182 sc->sc_flags |= SPC_DISCON;
1183 sc->sc_flags |= SPC_BUSFREE_OK;
1184 if ((acb->xs->sc_link->quirks & SDEV_AUTOSAVE) == 0)
1185 break;
1186 /*FALLTHROUGH*/
1187 case MSG_SAVEDATAPOINTER:
1188 SPC_MSGS(("save datapointer "));
1189 acb->dleft = sc->sc_dleft;
1190 acb->daddr = sc->sc_dp;
1191 break;
1192 case MSG_RESTOREPOINTERS:
1193 SPC_MSGS(("restore datapointer "));
1194 if (!acb) {
1195 mha_sched_msgout(SEND_ABORT);
1196 printf("%s: no DATAPOINTERs to restore\n",
1197 sc->sc_dev.dv_xname);
1198 break;
1199 }
1200 sc->sc_dp = acb->daddr;
1201 sc->sc_dleft = acb->dleft;
1202 break;
1203 case MSG_PARITY_ERROR:
1204 printf("%s:target%d: MSG_PARITY_ERROR\n",
1205 sc->sc_dev.dv_xname,
1206 acb->xs->sc_link->scsipi_scsi.target);
1207 break;
1208 case MSG_EXTENDED:
1209 SPC_MSGS(("extended(%x) ", sc->sc_imess[2]));
1210 switch (sc->sc_imess[2]) {
1211 case MSG_EXT_SDTR:
1212 SPC_MSGS(("SDTR period %d, offset %d ",
1213 sc->sc_imess[3], sc->sc_imess[4]));
1214 ti->period = sc->sc_imess[3];
1215 ti->offset = sc->sc_imess[4];
1216 if (sc->sc_minsync == 0) {
1217 /* We won't do synch */
1218 ti->offset = 0;
1219 mha_sched_msgout(SEND_SDTR);
1220 } else if (ti->offset == 0) {
1221 printf("%s:%d: async\n", "mha",
1222 acb->xs->sc_link->scsipi_scsi.target);
1223 ti->offset = 0;
1224 sc->sc_flags &= ~SPC_SYNCHNEGO;
1225 } else if (ti->period > 124) {
1226 printf("%s:%d: async\n", "mha",
1227 acb->xs->sc_link->scsipi_scsi.target);
1228 ti->offset = 0;
1229 mha_sched_msgout(SEND_SDTR);
1230 } else {
1231 int r = 250/ti->period;
1232 int s = (100*250)/ti->period - 100*r;
1233 int p;
1234 #if 0
1235 p = mha_stp2cpb(sc, ti->period);
1236 ti->period = mha_cpb2stp(sc, p);
1237 #endif
1238
1239 #if SPC_DEBUG
1240 scsi_print_addr(acb->xs->sc_link);
1241 #endif
1242 if ((sc->sc_flags&SPC_SYNCHNEGO) == 0) {
1243 /* Target initiated negotiation */
1244 if (ti->flags & T_SYNCMODE) {
1245 ti->flags &= ~T_SYNCMODE;
1246 #if SPC_DEBUG
1247 printf("renegotiated ");
1248 #endif
1249 }
1250 TMR=TM_ASYNC;
1251 /* Clamp to our maxima */
1252 if (ti->period < sc->sc_minsync)
1253 ti->period = sc->sc_minsync;
1254 if (ti->offset > 15)
1255 ti->offset = 15;
1256 mha_sched_msgout(SEND_SDTR);
1257 } else {
1258 /* we are sync */
1259 sc->sc_flags &= ~SPC_SYNCHNEGO;
1260 TMR = TM_SYNC;
1261 ti->flags |= T_SYNCMODE;
1262 }
1263 #if SPC_DEBUG
1264 printf("max sync rate %d.%02dMb/s\n",
1265 r, s);
1266 #endif
1267 }
1268 ti->flags &= ~T_NEGOTIATE;
1269 break;
1270 default: /* Extended messages we don't handle */
1271 CMR = CMD_SET_ATN; /* XXX? */
1272 break;
1273 }
1274 break;
1275 default:
1276 SPC_MSGS(("ident "));
1277 /* thanks for that ident... */
1278 if (!MSG_ISIDENTIFY(sc->sc_imess[0])) {
1279 SPC_MISC(("unknown "));
1280 printf("%s: unimplemented message: %d\n", sc->sc_dev.dv_xname, sc->sc_imess[0]);
1281 CMR = CMD_SET_ATN; /* XXX? */
1282 }
1283 break;
1284 }
1285 } else if (sc->sc_state == SPC_RESELECTED) {
1286 struct scsipi_link *sc_link = NULL;
1287 struct acb *acb;
1288 struct spc_tinfo *ti;
1289 u_char lunit;
1290
1291 if (MSG_ISIDENTIFY(sc->sc_imess[0])) { /* Identify? */
1292 SPC_MISC(("searching "));
1293 /*
1294 * Search wait queue for disconnected cmd
1295 * The list should be short, so I haven't bothered with
1296 * any more sophisticated structures than a simple
1297 * singly linked list.
1298 */
1299 lunit = sc->sc_imess[0] & 0x07;
1300 for (acb = sc->nexus_list.tqh_first; acb;
1301 acb = acb->chain.tqe_next) {
1302 sc_link = acb->xs->sc_link;
1303 if (sc_link->scsipi_scsi.lun == lunit &&
1304 sc->sc_selid == (1<<sc_link->scsipi_scsi.target)) {
1305 TAILQ_REMOVE(&sc->nexus_list, acb,
1306 chain);
1307 ACB_SETQ(acb, ACB_QNONE);
1308 break;
1309 }
1310 }
1311
1312 if (!acb) { /* Invalid reselection! */
1313 mha_sched_msgout(SEND_ABORT);
1314 printf("mmespc: invalid reselect (idbit=0x%2x)\n",
1315 sc->sc_selid);
1316 } else { /* Reestablish nexus */
1317 /*
1318 * Setup driver data structures and
1319 * do an implicit RESTORE POINTERS
1320 */
1321 ti = &sc->sc_tinfo[sc_link->scsipi_scsi.target];
1322 sc->sc_nexus = acb;
1323 sc->sc_dp = acb->daddr;
1324 sc->sc_dleft = acb->dleft;
1325 sc->sc_tinfo[sc_link->scsipi_scsi.target].lubusy
1326 |= (1<<sc_link->scsipi_scsi.lun);
1327 if (ti->flags & T_SYNCMODE) {
1328 TMR = TM_SYNC; /* XXX */
1329 } else {
1330 TMR = TM_ASYNC;
1331 }
1332 SPC_MISC(("... found acb"));
1333 sc->sc_state = SPC_HASNEXUS;
1334 }
1335 } else {
1336 printf("%s: bogus reselect (no IDENTIFY) %0x2x\n",
1337 sc->sc_dev.dv_xname, sc->sc_selid);
1338 mha_sched_msgout(SEND_DEV_RESET);
1339 }
1340 } else { /* Neither SPC_HASNEXUS nor SPC_RESELECTED! */
1341 printf("%s: unexpected message in; will send DEV_RESET\n",
1342 sc->sc_dev.dv_xname);
1343 mha_sched_msgout(SEND_DEV_RESET);
1344 }
1345
1346 /* Ack last message byte */
1347 #if 0
1348 ESPCMD(sc, ESPCMD_MSGOK);
1349 #endif
1350
1351 /* Done, reset message pointer. */
1352 sc->sc_flags &= ~SPC_DROP_MSGI;
1353 sc->sc_imlen = 0;
1354 }
1355
1356 /*
1357 * Send the highest priority, scheduled message.
1358 */
1359 void
1360 mha_msgout(sc)
1361 register struct mha_softc *sc;
1362 {
1363 struct spc_tinfo *ti;
1364 int n;
1365
1366 SPC_TRACE(("mha_msgout "));
1367
1368 if (sc->sc_prevphase == MESSAGE_OUT_PHASE) {
1369 if (sc->sc_omp == sc->sc_omess) {
1370 /*
1371 * This is a retransmission.
1372 *
1373 * We get here if the target stayed in MESSAGE OUT
1374 * phase. Section 5.1.9.2 of the SCSI 2 spec indicates
1375 * that all of the previously transmitted messages must
1376 * be sent again, in the same order. Therefore, we
1377 * requeue all the previously transmitted messages, and
1378 * start again from the top. Our simple priority
1379 * scheme keeps the messages in the right order.
1380 */
1381 SPC_MISC(("retransmitting "));
1382 sc->sc_msgpriq |= sc->sc_msgoutq;
1383 /*
1384 * Set ATN. If we're just sending a trivial 1-byte
1385 * message, we'll clear ATN later on anyway.
1386 */
1387 CMR = CMD_SET_ATN; /* XXX? */
1388 } else {
1389 /* This is a continuation of the previous message. */
1390 n = sc->sc_omp - sc->sc_omess;
1391 goto nextbyte;
1392 }
1393 }
1394
1395 /* No messages transmitted so far. */
1396 sc->sc_msgoutq = 0;
1397 sc->sc_lastmsg = 0;
1398
1399 nextmsg:
1400 /* Pick up highest priority message. */
1401 sc->sc_currmsg = sc->sc_msgpriq & -sc->sc_msgpriq;
1402 sc->sc_msgpriq &= ~sc->sc_currmsg;
1403 sc->sc_msgoutq |= sc->sc_currmsg;
1404
1405 /* Build the outgoing message data. */
1406 switch (sc->sc_currmsg) {
1407 case SEND_IDENTIFY:
1408 SPC_ASSERT(sc->sc_nexus != NULL);
1409 sc->sc_omess[0] =
1410 MSG_IDENTIFY(sc->sc_nexus->xs->sc_link->scsipi_scsi.lun, 1);
1411 n = 1;
1412 break;
1413
1414 #if SPC_USE_SYNCHRONOUS
1415 case SEND_SDTR:
1416 SPC_ASSERT(sc->sc_nexus != NULL);
1417 ti = &sc->sc_tinfo[sc->sc_nexus->xs->sc_link->scsipi_scsi.target];
1418 sc->sc_omess[4] = MSG_EXTENDED;
1419 sc->sc_omess[3] = 3;
1420 sc->sc_omess[2] = MSG_EXT_SDTR;
1421 sc->sc_omess[1] = ti->period >> 2;
1422 sc->sc_omess[0] = ti->offset;
1423 n = 5;
1424 break;
1425 #endif
1426
1427 #if SPC_USE_WIDE
1428 case SEND_WDTR:
1429 SPC_ASSERT(sc->sc_nexus != NULL);
1430 ti = &sc->sc_tinfo[sc->sc_nexus->xs->sc_link->scsipi_scsi.target];
1431 sc->sc_omess[3] = MSG_EXTENDED;
1432 sc->sc_omess[2] = 2;
1433 sc->sc_omess[1] = MSG_EXT_WDTR;
1434 sc->sc_omess[0] = ti->width;
1435 n = 4;
1436 break;
1437 #endif
1438
1439 case SEND_DEV_RESET:
1440 sc->sc_flags |= SPC_ABORTING;
1441 sc->sc_omess[0] = MSG_BUS_DEV_RESET;
1442 n = 1;
1443 break;
1444
1445 case SEND_REJECT:
1446 sc->sc_omess[0] = MSG_MESSAGE_REJECT;
1447 n = 1;
1448 break;
1449
1450 case SEND_PARITY_ERROR:
1451 sc->sc_omess[0] = MSG_PARITY_ERROR;
1452 n = 1;
1453 break;
1454
1455 case SEND_INIT_DET_ERR:
1456 sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
1457 n = 1;
1458 break;
1459
1460 case SEND_ABORT:
1461 sc->sc_flags |= SPC_ABORTING;
1462 sc->sc_omess[0] = MSG_ABORT;
1463 n = 1;
1464 break;
1465
1466 default:
1467 printf("%s: unexpected MESSAGE OUT; sending NOOP\n",
1468 sc->sc_dev.dv_xname);
1469 SPC_BREAK();
1470 sc->sc_omess[0] = MSG_NOOP;
1471 n = 1;
1472 break;
1473 }
1474 sc->sc_omp = &sc->sc_omess[n];
1475
1476 nextbyte:
1477 /* Send message bytes. */
1478 /* send TRANSFER command. */
1479 sc->sc_ps[3] = 1;
1480 sc->sc_ps[4] = n >> 8;
1481 sc->sc_pc[10] = n;
1482 sc->sc_ps[-1] = 0x000F; /* burst */
1483 asm volatile ("nop");
1484 CMR = CMD_SEND_FROM_DMA; /* send from DMA */
1485 for (;;) {
1486 if ((SSR & SS_BUSY) != 0)
1487 break;
1488 if (SSR & SS_IREQUEST)
1489 goto out;
1490 }
1491 for (;;) {
1492 #if 0
1493 for (;;) {
1494 if ((PSNS & PSNS_REQ) != 0)
1495 break;
1496 /* Wait for REQINIT. XXX Need timeout. */
1497 }
1498 #endif
1499 if (SSR & SS_IREQUEST) {
1500 /*
1501 * Target left MESSAGE OUT, possibly to reject
1502 * our message.
1503 *
1504 * If this is the last message being sent, then we
1505 * deassert ATN, since either the target is going to
1506 * ignore this message, or it's going to ask for a
1507 * retransmission via MESSAGE PARITY ERROR (in which
1508 * case we reassert ATN anyway).
1509 */
1510 #if 0
1511 if (sc->sc_msgpriq == 0)
1512 CMR = CMD_RESET_ATN;
1513 #endif
1514 goto out;
1515 }
1516
1517 #if 0
1518 /* Clear ATN before last byte if this is the last message. */
1519 if (n == 1 && sc->sc_msgpriq == 0)
1520 CMR = CMD_RESET_ATN;
1521 #endif
1522
1523 while ((SSR & SS_DREG_FULL) != 0)
1524 ;
1525 /* Send message byte. */
1526 sc->sc_pc[0] = *--sc->sc_omp;
1527 --n;
1528 /* Keep track of the last message we've sent any bytes of. */
1529 sc->sc_lastmsg = sc->sc_currmsg;
1530
1531 if (n == 0)
1532 break;
1533 }
1534
1535 /* We get here only if the entire message has been transmitted. */
1536 if (sc->sc_msgpriq != 0) {
1537 /* There are more outgoing messages. */
1538 goto nextmsg;
1539 }
1540
1541 /*
1542 * The last message has been transmitted. We need to remember the last
1543 * message transmitted (in case the target switches to MESSAGE IN phase
1544 * and sends a MESSAGE REJECT), and the list of messages transmitted
1545 * this time around (in case the target stays in MESSAGE OUT phase to
1546 * request a retransmit).
1547 */
1548
1549 out:
1550 /* Disable REQ/ACK protocol. */
1551 }
1552
1553
1554 /***************************************************************
1556 *
1557 * datain/dataout
1558 *
1559 */
1560
1561 int
1562 mha_datain_pio(sc, p, n)
1563 register struct mha_softc *sc;
1564 u_char *p;
1565 int n;
1566 {
1567 u_short d;
1568 int a;
1569 int total_n = n;
1570
1571 SPC_TRACE(("[mha_datain_pio(%x,%d)", p, n));
1572
1573 WAIT;
1574 sc->sc_ps[3] = 1;
1575 sc->sc_ps[4] = n >> 8;
1576 sc->sc_pc[10] = n;
1577 /* $BHa$7$-%=%U%HE>Aw(B */
1578 CMR = CMD_RECEIVE_TO_MPU;
1579 for (;;) {
1580 a = SSR;
1581 if (a & 0x04) {
1582 d = sc->sc_ps[0];
1583 *p++ = d >> 8;
1584 if (--n > 0) {
1585 *p++ = d;
1586 --n;
1587 }
1588 a = SSR;
1589 }
1590 if (a & 0x40)
1591 continue;
1592 if (a & 0x80)
1593 break;
1594 }
1595 SPC_TRACE(("...%d resd]", n));
1596 return total_n - n;
1597 }
1598
1599 int
1600 mha_dataout_pio(sc, p, n)
1601 register struct mha_softc *sc;
1602 u_char *p;
1603 int n;
1604 {
1605 u_short d;
1606 int a;
1607 int total_n = n;
1608
1609 SPC_TRACE(("[mha_dataout_pio(%x,%d)", p, n));
1610
1611 WAIT;
1612 sc->sc_ps[3] = 1;
1613 sc->sc_ps[4] = n >> 8;
1614 sc->sc_pc[10] = n;
1615 /* $BHa$7$-%=%U%HE>Aw(B */
1616 CMR = CMD_SEND_FROM_MPU;
1617 for (;;) {
1618 a = SSR;
1619 if (a & 0x04) {
1620 d = *p++ << 8;
1621 if (--n > 0) {
1622 d |= *p++;
1623 --n;
1624 }
1625 sc->sc_ps[0] = d;
1626 a = SSR;
1627 }
1628 if (a & 0x40)
1629 continue;
1630 if (a & 0x80)
1631 break;
1632 }
1633 SPC_TRACE(("...%d resd]", n));
1634 return total_n - n;
1635 }
1636
1637 static int
1638 mha_dataio_dma(dw, cw, sc, p, n)
1639 int dw; /* DMA word */
1640 int cw; /* CMR word */
1641 register struct mha_softc *sc;
1642 u_char *p;
1643 int n;
1644 {
1645 int ts;
1646 char *paddr, *vaddr;
1647
1648 vaddr = p;
1649 paddr = (char *)kvtop(vaddr);
1650 #if MHA_DMA_SHORT_BUS_CYCLE == 1
1651 if ((*(int *)&IODEVbase->io_sram[0xac]) & (1 << ((paddr_t)paddr >> 19)))
1652 dw &= ~(1 << 3);
1653 #endif
1654 #if defined(M68040) || defined(M68060)
1655 #if defined(M68020) || defined(M68030)
1656 if (mmutype == MMU_68040)
1657 #endif
1658 DCFP((paddr_t)paddr); /* XXX */
1659 #endif
1660 for (ts = (NBPG - ((long)vaddr & PGOFSET));
1661 ts < n && (char *)kvtop(vaddr + ts + 4) == paddr + ts + 4;
1662 ts += NBPG)
1663 #if defined(M68040) || defined(M68060)
1664 #if defined(M68020) || defined(M68030)
1665 if (mmutype == MMU_68040)
1666 #endif
1667 DCFP((paddr_t)paddr + ts);
1668 #else
1669 ;
1670 #endif
1671 if (ts > n)
1672 ts = n;
1673 #if 0
1674 printf("(%x,%x)->(%x,%x)\n", p, n, paddr, ts);
1675 PCIA(); /* XXX */
1676 #endif
1677 sc->sc_pc[0x80 + (((long)paddr >> 16) & 0xFF)] = 0;
1678 sc->sc_pc[0x180 + (((long)paddr >> 8) & 0xFF)] = 0;
1679 sc->sc_pc[0x280 + (((long)paddr >> 0) & 0xFF)] = 0;
1680 WAIT;
1681 sc->sc_ps[3] = 1;
1682 sc->sc_ps[4] = ts >> 8;
1683 sc->sc_pc[10] = ts;
1684 /* DMA $BE>Aw@)8f$O0J2<$NDL$j!#(B
1685 3 ... short bus cycle
1686 2 ... MAXIMUM XFER.
1687 1 ... BURST XFER.
1688 0 ... R/W */
1689 sc->sc_ps[-1] = dw; /* burst */
1690 asm volatile ("nop");
1691 CMR = cw; /* receive to DMA */
1692 return ts;
1693 }
1694 int
1695 mha_dataout(sc, p, n)
1696 register struct mha_softc *sc;
1697 u_char *p;
1698 int n;
1699 {
1700 register struct acb *acb = sc->sc_nexus;
1701
1702 if (n == 0)
1703 return n;
1704
1705 if (((long)p & 1) || (n & 1))
1706 return mha_dataout_pio(sc, p, n);
1707 return mha_dataio_dma(MHA_DMA_DATAOUT, CMD_SEND_FROM_DMA, sc, p, n);
1708 }
1709
1710 int
1712 mha_datain(sc, p, n)
1713 register struct mha_softc *sc;
1714 u_char *p;
1715 int n;
1716 {
1717 int ts;
1718 register struct acb *acb = sc->sc_nexus;
1719 char *paddr, *vaddr;
1720
1721 if (n == 0)
1722 return n;
1723 if (acb->cmd.opcode == 0x03 || ((long)p & 1) || (n & 1))
1724 return mha_datain_pio(sc, p, n);
1725 return mha_dataio_dma(MHA_DMA_DATAIN, CMD_RECEIVE_TO_DMA, sc, p, n);
1726 }
1727
1728
1730 /*
1731 * Catch an interrupt from the adaptor
1732 */
1733 /*
1734 * This is the workhorse routine of the driver.
1735 * Deficiencies (for now):
1736 * 1) always uses programmed I/O
1737 */
1738 int
1739 mhaintr(unit)
1740 int unit;
1741 {
1742 struct mha_softc *sc;
1743 u_char ints;
1744 struct acb *acb;
1745 struct scsipi_link *sc_link;
1746 struct spc_tinfo *ti;
1747 u_char ph;
1748 u_short r;
1749 int n;
1750
1751 #if 1 /* XXX called during attach? */
1752 if (tmpsc != NULL) {
1753 SPC_MISC(("[%x %x]\n", mha_cd.cd_devs, sc));
1754 sc = tmpsc;
1755 } else {
1756 #endif
1757
1758 /* return if not configured */
1759 if (!mha_cd.cd_devs) /* Check if at least one unit is attached. */
1760 return; /* XXX should check if THE unit exists. */
1761
1762 sc = mha_cd.cd_devs[unit];
1763
1764 #if 1 /* XXX */
1765 }
1766 #endif
1767
1768 /*
1769 * $B3d$j9~$_6X;_$K$9$k(B
1770 */
1771 #if 0
1772 SCTL &= ~SCTL_INTR_ENAB;
1773 #endif
1774
1775 SPC_TRACE(("[mhaintr]"));
1776
1777 loop:
1778 /*
1779 * $BA4E>Aw$,40A4$K=*N;$9$k$^$G%k!<%W$9$k(B
1780 */
1781 /*
1782 * First check for abnormal conditions, such as reset.
1783 */
1784 #if 0
1785 #if 1 /* XXX? */
1786 while (((ints = SSR) & SS_IREQUEST) == 0)
1787 delay(1);
1788 SPC_MISC(("ints = 0x%x ", ints));
1789 #else /* usually? */
1790 ints = SSR;
1791 #endif
1792 #endif
1793 while (SSR & SS_IREQUEST)
1794 {
1795 acb = sc->sc_nexus;
1796 r = ISCSR;
1797 SPC_MISC(("[r=0x%x]", r));
1798 switch (r >> 8)
1799 {
1800 default:
1801 printf("[addr=%x\n"
1802 "result=0x%x\n"
1803 "cmd=0x%x\n"
1804 "ph=0x%x(ought to be %d)]\n",
1805 &ISCSR,
1806 r,
1807 acb->xs->cmd->opcode,
1808 SCR, sc->sc_phase);
1809 panic("unexpected result.");
1810 case 0x82: /* selection timeout */
1811 SPC_MISC(("selection timeout "));
1812 sc->sc_phase = BUSFREE_PHASE;
1813 SPC_ASSERT(sc->sc_nexus != NULL);
1814 acb = sc->sc_nexus;
1815 delay(250);
1816 acb->xs->error = XS_SELTIMEOUT;
1817 mha_done(sc, acb);
1818 continue; /* XXX ??? msaitoh */
1819 case 0x60: /* command completed */
1820 sc->sc_spcinitialized++;
1821 if (sc->sc_phase == BUSFREE_PHASE)
1822 continue;
1823 ph = SCR;
1824 if (ph & PSNS_ACK)
1825 {
1826 int s;
1827 /* $B$U$D!<$N%3%^%s%I$,=*N;$7$?$i$7$$(B */
1828 SPC_MISC(("0x60)phase = %x(ought to be %x)\n", ph & PHASE_MASK, sc->sc_phase));
1829 # if 0
1830 switch (sc->sc_phase)
1831 #else
1832 switch (ph & PHASE_MASK)
1833 #endif
1834 {
1835 case STATUS_PHASE:
1836 if (sc->sc_state != SPC_HASNEXUS)
1837 {
1838 printf("stsin: !SPC_HASNEXUS->(%d)\n", sc->sc_state);
1839 }
1840 SPC_ASSERT(sc->sc_nexus != NULL);
1841 acb = sc->sc_nexus;
1842 WAIT;
1843 s = MBR;
1844 SPC_ASSERT(s == 1);
1845 acb->stat = sc->sc_pcx[0]; /* XXX */
1846 SPC_MISC(("stat=0x%02x ", acb->stat));
1847 sc->sc_prevphase = STATUS_PHASE;
1848 break;
1849 case MESSAGE_IN_PHASE:
1850 mha_msgin(sc);
1851 sc->sc_prevphase = MESSAGE_IN_PHASE;
1852 break;
1853 }
1854 WAIT;
1855 CMR = CMD_RESET_ACK; /* reset ack */
1856 /*mha_done(sc, acb); XXX */
1857 continue;
1858 }
1859 else if (NSR & 0x80) /* nexus */
1860 {
1861 #if 1
1862 if (sc->sc_state == SPC_SELECTING) /* XXX msaitoh */
1863 sc->sc_state = SPC_HASNEXUS;
1864 /* $B%U%'!<%:$N7h$aBG$A$r$9$k(B
1865 $B30$l$?$i!"(Binitial-phase error(0x54) $B$,(B
1866 $BJV$C$F$/$k$s$GCm0U$7$?$^$(!#(B
1867 $B$G$b$J$<$+(B 0x65 $B$,JV$C$F$-$?$j$7$F$M!<$+(B? */
1868 WAIT;
1869 if (SSR & SS_IREQUEST)
1870 continue;
1871 switch (sc->sc_phase)
1872 {
1873 default:
1874 panic("$B8+CN$i$L(B phase $B$,Mh$A$^$C$?$@$h(B");
1875 case MESSAGE_IN_PHASE:
1876 /* $B2?$b$7$J$$(B */
1877 continue;
1878 case STATUS_PHASE:
1879 sc->sc_phase = MESSAGE_IN_PHASE;
1880 CMR = CMD_RECEIVE_MSG; /* receive msg */
1881 continue;
1882 case DATA_IN_PHASE:
1883 sc->sc_prevphase = DATA_IN_PHASE;
1884 if (sc->sc_dleft == 0)
1885 {
1886 /* $BE>Aw%G!<%?$O$b$&$J$$$N$G(B
1887 $B%9%F!<%?%9%U%'!<%:$r4|BT$7$h$&(B */
1888 sc->sc_phase = STATUS_PHASE;
1889 CMR = CMD_RECEIVE_STS; /* receive sts */
1890 continue;
1891 }
1892 n = mha_datain(sc, sc->sc_dp, sc->sc_dleft);
1893 sc->sc_dp += n;
1894 sc->sc_dleft -= n;
1895 continue;
1896 case DATA_OUT_PHASE:
1897 sc->sc_prevphase = DATA_OUT_PHASE;
1898 if (sc->sc_dleft == 0)
1899 {
1900 /* $BE>Aw%G!<%?$O$b$&$J$$$N$G(B
1901 $B%9%F!<%?%9%U%'!<%:$r4|BT$7$h$&(B */
1902 sc->sc_phase = STATUS_PHASE;
1903 CMR = CMD_RECEIVE_STS; /* receive sts */
1904 continue;
1905 }
1906 /* data phase $B$NB3$-$r$d$m$&(B */
1907 n = mha_dataout(sc, sc->sc_dp, sc->sc_dleft);
1908 sc->sc_dp += n;
1909 sc->sc_dleft -= n;
1910 continue;
1911 case COMMAND_PHASE:
1912 /* $B:G=i$O(B CMD PHASE $B$H$$$&$3$H$i$7$$(B */
1913 if (acb->dleft)
1914 {
1915 /* $B%G!<%?E>Aw$,$"$j$&$k>l9g(B */
1916 if (acb->xs->flags & SCSI_DATA_IN)
1917 {
1918 sc->sc_phase = DATA_IN_PHASE;
1919 n = mha_datain(sc, sc->sc_dp, sc->sc_dleft);
1920 sc->sc_dp += n;
1921 sc->sc_dleft -= n;
1922 }
1923 else if (acb->xs->flags & SCSI_DATA_OUT)
1924 {
1925 sc->sc_phase = DATA_OUT_PHASE;
1926 n = mha_dataout(sc, sc->sc_dp, sc->sc_dleft);
1927 sc->sc_dp += n;
1928 sc->sc_dleft -= n;
1929 }
1930 continue;
1931 }
1932 else
1933 {
1934 /* $B%G!<%?E>Aw$O$J$$$i$7$$(B?! */
1935 WAIT;
1936 sc->sc_phase = STATUS_PHASE;
1937 CMR = CMD_RECEIVE_STS; /* receive sts */
1938 continue;
1939 }
1940 }
1941 #endif
1942 }
1943 continue;
1944 case 0x31: /* disconnected in xfer progress. */
1945 SPC_MISC(("[0x31]"));
1946 case 0x70: /* disconnected. */
1947 SPC_ASSERT(sc->sc_flags & SPC_BUSFREE_OK);
1948 sc->sc_phase = BUSFREE_PHASE;
1949 sc->sc_state = SPC_IDLE;
1950 #if 1
1951 acb = sc->sc_nexus;
1952 SPC_ASSERT(sc->sc_nexus != NULL);
1953 acb->xs->error = XS_NOERROR;
1954 mha_done(sc, acb);
1955 #else
1956 TAILQ_INSERT_HEAD(&sc->nexus_list, acb, chain);
1957 mha_sched(sc);
1958 #endif
1959 continue;
1960 case 0x32: /* phase error in xfer progress. */
1961 SPC_MISC(("[0x32]"));
1962 case 0x65: /* invalid command.
1963 $B$J$<$3$s$J$b$N$,=P$k$N$+(B
1964 $B26$K$OA4$/M}2r$G$-$J$$(B */
1965 #if 1
1966 SPC_MISC(("[0x%04x]", r));
1967 #endif
1968 case 0x54: /* initial-phase error. */
1969 SPC_MISC(("[0x54, ns=%x, ph=%x(ought to be %x)]",
1970 NSR,
1971 SCR, sc->sc_phase));
1972 /* thru */
1973 case 0x71: /* assert req */
1974 WAIT;
1975 if (SSR & 0x40)
1976 {
1977 printf("SPC sts=%2x, r=%04x, ns=%x, ph=%x\n",
1978 SSR, r, NSR, SCR);
1979 WAIT;
1980 }
1981 ph = SCR;
1982 if (sc->sc_state == SPC_SELECTING) /* XXX msaitoh */
1983 {
1984 sc->sc_state = SPC_HASNEXUS;
1985 }
1986 if (ph & 0x80)
1987 {
1988 switch (ph & PHASE_MASK)
1989 {
1990 default:
1991 printf("phase = %x\n", ph);
1992 panic("assert req: the phase I don't know!");
1993 case DATA_IN_PHASE:
1994 sc->sc_prevphase = DATA_IN_PHASE;
1995 SPC_MISC(("DATAIN(%d)...", sc->sc_dleft));
1996 n = mha_datain(sc, sc->sc_dp, sc->sc_dleft);
1997 sc->sc_dp += n;
1998 sc->sc_dleft -= n;
1999 SPC_MISC(("done\n"));
2000 continue;
2001 case DATA_OUT_PHASE:
2002 sc->sc_prevphase = DATA_OUT_PHASE;
2003 SPC_MISC(("DATAOUT\n"));
2004 n = mha_dataout(sc, sc->sc_dp, sc->sc_dleft);
2005 sc->sc_dp += n;
2006 sc->sc_dleft -= n;
2007 continue;
2008 case STATUS_PHASE:
2009 sc->sc_phase = STATUS_PHASE;
2010 SPC_MISC(("[RECV_STS]"));
2011 WAIT;
2012 CMR = CMD_RECEIVE_STS; /* receive sts */
2013 continue;
2014 case MESSAGE_IN_PHASE:
2015 sc->sc_phase = MESSAGE_IN_PHASE;
2016 WAIT;
2017 CMR = CMD_RECEIVE_MSG;
2018 continue;
2019 }
2020 }
2021 continue;
2022 }
2023 }
2024 }
2025
2026 void
2027 mha_abort(sc, acb)
2028 struct mha_softc *sc;
2029 struct acb *acb;
2030 {
2031 acb->flags |= ACB_ABORTED;
2032
2033 if (acb == sc->sc_nexus) {
2034 /*
2035 * If we're still selecting, the message will be scheduled
2036 * after selection is complete.
2037 */
2038 if (sc->sc_state == SPC_HASNEXUS) {
2039 sc->sc_flags |= SPC_ABORTING;
2040 mha_sched_msgout(SEND_ABORT);
2041 }
2042 } else {
2043 if (sc->sc_state == SPC_IDLE)
2044 mha_sched(sc);
2045 }
2046 }
2047
2048 void
2049 mha_timeout(arg)
2050 void *arg;
2051 {
2052 int s = splbio();
2053 struct acb *acb = (struct acb *)arg;
2054 struct scsipi_xfer *xs = acb->xs;
2055 struct scsipi_link *sc_link = xs->sc_link;
2056 struct mha_softc *sc = sc_link->adapter_softc;
2057
2058 scsi_print_addr(sc_link);
2059 again:
2060 printf("%s: timed out [acb %p (flags 0x%x, dleft %x, stat %x)], "
2061 "<state %d, nexus %p, phase(c %x, p %x), resid %x, msg(q %x,o %x) >",
2062 sc->sc_dev.dv_xname,
2063 acb, acb->flags, acb->dleft, acb->stat,
2064 sc->sc_state, sc->sc_nexus, sc->sc_phase, sc->sc_prevphase,
2065 sc->sc_dleft, sc->sc_msgpriq, sc->sc_msgout
2066 );
2067 printf("[%04x %02x]\n", sc->sc_ps[1], SCR);
2068 panic("timeout, ouch!");
2069
2070 if (acb->flags & ACB_ABORTED) {
2071 /* abort timed out */
2072 printf(" AGAIN\n");
2073 #if 0
2074 mha_init(sc, 1); /* XXX 1?*/
2075 #endif
2076 } else {
2077 /* abort the operation that has timed out */
2078 printf("\n");
2079 xs->error = XS_TIMEOUT;
2080 mha_abort(sc, acb);
2081 }
2082
2083 splx(s);
2084 }
2085
2086 #if SPC_DEBUG
2088 /*
2089 * The following functions are mostly used for debugging purposes, either
2090 * directly called from the driver or from the kernel debugger.
2091 */
2092
2093 void
2094 mha_show_scsi_cmd(acb)
2095 struct acb *acb;
2096 {
2097 u_char *b = (u_char *)&acb->cmd;
2098 struct scsipi_link *sc_link = acb->xs->sc_link;
2099 int i;
2100
2101 scsi_print_addr(sc_link);
2102 if ((acb->xs->flags & SCSI_RESET) == 0) {
2103 for (i = 0; i < acb->clen; i++) {
2104 if (i)
2105 printf(",");
2106 printf("%x", b[i]);
2107 }
2108 printf("\n");
2109 } else
2110 printf("RESET\n");
2111 }
2112
2113 void
2114 mha_print_acb(acb)
2115 struct acb *acb;
2116 {
2117
2118 printf("acb@%x xs=%x flags=%x", acb, acb->xs, acb->flags);
2119 printf(" dp=%x dleft=%d stat=%x\n",
2120 (long)acb->daddr, acb->dleft, acb->stat);
2121 mha_show_scsi_cmd(acb);
2122 }
2123
2124 void
2125 mha_print_active_acb()
2126 {
2127 struct acb *acb;
2128 struct mha_softc *sc = mha_cd.cd_devs[0]; /* XXX */
2129
2130 printf("ready list:\n");
2131 for (acb = sc->ready_list.tqh_first; acb != NULL;
2132 acb = acb->chain.tqe_next)
2133 mha_print_acb(acb);
2134 printf("nexus:\n");
2135 if (sc->sc_nexus != NULL)
2136 mha_print_acb(sc->sc_nexus);
2137 printf("nexus list:\n");
2138 for (acb = sc->nexus_list.tqh_first; acb != NULL;
2139 acb = acb->chain.tqe_next)
2140 mha_print_acb(acb);
2141 }
2142
2143 void
2144 mha_dump_driver(sc)
2145 struct mha_softc *sc;
2146 {
2147 struct spc_tinfo *ti;
2148 int i;
2149
2150 printf("nexus=%x prevphase=%x\n", sc->sc_nexus, sc->sc_prevphase);
2151 printf("state=%x msgin=%x msgpriq=%x msgoutq=%x lastmsg=%x currmsg=%x\n",
2152 sc->sc_state, sc->sc_imess[0],
2153 sc->sc_msgpriq, sc->sc_msgoutq, sc->sc_lastmsg, sc->sc_currmsg);
2154 for (i = 0; i < 7; i++) {
2155 ti = &sc->sc_tinfo[i];
2156 printf("tinfo%d: %d cmds %d disconnects %d timeouts",
2157 i, ti->cmds, ti->dconns, ti->touts);
2158 printf(" %d senses flags=%x\n", ti->senses, ti->flags);
2159 }
2160 }
2161 #endif
2162