1 /* $NetBSD: mesh.c,v 1.33 2009/09/26 15:45:28 tsutsui Exp $ */
4 * Copyright (c) 2000 Tsubai Masanari.
5 * Copyright (c) 1999 Internet Research Institute, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by
19 * Internet Research Institute, Inc.
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include <sys/cdefs.h>
36 __KERNEL_RCSID(0, "$NetBSD: mesh.c,v 1.33 2009/09/26 15:45:28 tsutsui Exp $");
38 #include <sys/param.h>
40 #include <sys/device.h>
41 #include <sys/errno.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/queue.h>
45 #include <sys/systm.h>
47 #include <uvm/uvm_extern.h>
49 #include <dev/scsipi/scsi_all.h>
50 #include <dev/scsipi/scsipi_all.h>
51 #include <dev/scsipi/scsiconf.h>
52 #include <dev/scsipi/scsi_message.h>
54 #include <dev/ofw/openfirm.h>
56 #include <machine/autoconf.h>
57 #include <machine/cpu.h>
58 #include <machine/pio.h>
60 #include <macppc/dev/dbdma.h>
61 #include <macppc/dev/meshreg.h>
64 # define DPRINTF printf
66 # define DPRINTF while (0) printf
69 #define T_SYNCMODE 0x01 /* target uses sync mode */
70 #define T_SYNCNEGO 0x02 /* sync negotiation done */
79 #define MESH_POLL 0x01
80 #define MESH_CHECK 0x02
81 #define MESH_READ 0x80
84 TAILQ_ENTRY(mesh_scb
) chain
;
86 struct scsipi_xfer
*xs
;
87 struct scsipi_generic cmd
;
89 int target
; /* target SCSI ID */
97 #define MESH_DMA_ACTIVE 0x01
100 device_t sc_dev
; /* us as a device */
101 struct scsipi_channel sc_channel
;
102 struct scsipi_adapter sc_adapter
;
104 u_char
*sc_reg
; /* MESH base address */
105 dbdma_regmap_t
*sc_dmareg
; /* DMA register address */
106 dbdma_command_t
*sc_dmacmd
; /* DMA command area */
109 int sc_cfflags
; /* copy of config flags */
110 int sc_meshid
; /* MESH version */
111 int sc_minsync
; /* minimum sync period */
113 int sc_freq
; /* SCSI bus frequency in MHz */
114 int sc_id
; /* our SCSI ID */
115 struct mesh_tinfo sc_tinfo
[8]; /* target information */
119 struct mesh_scb
*sc_nexus
; /* current command */
126 TAILQ_HEAD(, mesh_scb
) free_scb
;
127 TAILQ_HEAD(, mesh_scb
) ready_scb
;
128 struct mesh_scb sc_scb
[16];
131 /* mesh_msgout() values */
132 #define SEND_REJECT 1
133 #define SEND_IDENTIFY 2
136 static inline int mesh_read_reg(struct mesh_softc
*, int);
137 static inline void mesh_set_reg(struct mesh_softc
*, int, int);
139 static int mesh_match(device_t
, cfdata_t
, void *);
140 static void mesh_attach(device_t
, device_t
, void *);
141 static bool mesh_shutdown(device_t
, int);
142 static int mesh_intr(void *);
143 static void mesh_error(struct mesh_softc
*, struct mesh_scb
*, int, int);
144 static void mesh_select(struct mesh_softc
*, struct mesh_scb
*);
145 static void mesh_identify(struct mesh_softc
*, struct mesh_scb
*);
146 static void mesh_command(struct mesh_softc
*, struct mesh_scb
*);
147 static void mesh_dma_setup(struct mesh_softc
*, struct mesh_scb
*);
148 static void mesh_dataio(struct mesh_softc
*, struct mesh_scb
*);
149 static void mesh_status(struct mesh_softc
*, struct mesh_scb
*);
150 static void mesh_msgin(struct mesh_softc
*, struct mesh_scb
*);
151 static void mesh_msgout(struct mesh_softc
*, int);
152 static void mesh_bus_reset(struct mesh_softc
*);
153 static void mesh_reset(struct mesh_softc
*);
154 static int mesh_stp(struct mesh_softc
*, int);
155 static void mesh_setsync(struct mesh_softc
*, struct mesh_tinfo
*);
156 static struct mesh_scb
*mesh_get_scb(struct mesh_softc
*);
157 static void mesh_free_scb(struct mesh_softc
*, struct mesh_scb
*);
158 static void mesh_scsi_request(struct scsipi_channel
*,
159 scsipi_adapter_req_t
, void *);
160 static void mesh_sched(struct mesh_softc
*);
161 static int mesh_poll(struct mesh_softc
*, struct scsipi_xfer
*);
162 static void mesh_done(struct mesh_softc
*, struct mesh_scb
*);
163 static void mesh_timeout(void *);
164 static void mesh_minphys(struct buf
*);
167 #define MESH_DATAOUT 0
168 #define MESH_DATAIN MESH_STATUS0_IO
169 #define MESH_COMMAND MESH_STATUS0_CD
170 #define MESH_STATUS (MESH_STATUS0_CD | MESH_STATUS0_IO)
171 #define MESH_MSGOUT (MESH_STATUS0_MSG | MESH_STATUS0_CD)
172 #define MESH_MSGIN (MESH_STATUS0_MSG | MESH_STATUS0_CD | MESH_STATUS0_IO)
174 #define MESH_SELECTING 8
175 #define MESH_IDENTIFY 9
176 #define MESH_COMPLETE 10
177 #define MESH_BUSFREE 11
178 #define MESH_UNKNOWN -1
180 #define MESH_PHASE_MASK (MESH_STATUS0_MSG | MESH_STATUS0_CD | MESH_STATUS0_IO)
182 CFATTACH_DECL_NEW(mesh
, sizeof(struct mesh_softc
),
183 mesh_match
, mesh_attach
, NULL
, NULL
);
186 mesh_match(device_t parent
, cfdata_t cf
, void *aux
)
188 struct confargs
*ca
= aux
;
191 if (strcmp(ca
->ca_name
, "mesh") == 0)
194 memset(compat
, 0, sizeof(compat
));
195 OF_getprop(ca
->ca_node
, "compatible", compat
, sizeof(compat
));
196 if (strcmp(compat
, "chrp,mesh0") == 0)
203 mesh_attach(device_t parent
, device_t self
, void *aux
)
205 struct mesh_softc
*sc
= device_private(self
);
206 struct confargs
*ca
= aux
;
212 reg
[0] += ca
->ca_baseaddr
;
213 reg
[2] += ca
->ca_baseaddr
;
214 sc
->sc_reg
= mapiodev(reg
[0], reg
[1]);
215 sc
->sc_irq
= ca
->ca_intr
[0];
216 sc
->sc_dmareg
= mapiodev(reg
[2], reg
[3]);
218 sc
->sc_cfflags
= device_cfdata(self
)->cf_flags
;
219 sc
->sc_meshid
= mesh_read_reg(sc
, MESH_MESH_ID
) & 0x1f;
221 if (sc
->sc_meshid
!= (MESH_SIGNATURE
& 0x1f) {
222 aprint_error(": unknown MESH ID (0x%x)\n", sc
->sc_meshid
);
226 if (OF_getprop(ca
->ca_node
, "clock-frequency", &sc
->sc_freq
, 4) != 4) {
227 aprint_error(": cannot get clock-frequency\n");
230 sc
->sc_freq
/= 1000000; /* in MHz */
231 sc
->sc_minsync
= 25; /* maximum sync rate = 10MB/sec */
234 TAILQ_INIT(&sc
->free_scb
);
235 TAILQ_INIT(&sc
->ready_scb
);
236 for (i
= 0; i
< sizeof(sc
->sc_scb
)/sizeof(sc
->sc_scb
[0]); i
++)
237 TAILQ_INSERT_TAIL(&sc
->free_scb
, &sc
->sc_scb
[i
], chain
);
239 sc
->sc_dmacmd
= dbdma_alloc(sizeof(dbdma_command_t
) * 20);
244 aprint_normal(" irq %d: %dMHz, SCSI ID %d\n",
245 sc
->sc_irq
, sc
->sc_freq
, sc
->sc_id
);
247 sc
->sc_adapter
.adapt_dev
= self
;
248 sc
->sc_adapter
.adapt_nchannels
= 1;
249 sc
->sc_adapter
.adapt_openings
= 7;
250 sc
->sc_adapter
.adapt_max_periph
= 1;
251 sc
->sc_adapter
.adapt_ioctl
= NULL
;
252 sc
->sc_adapter
.adapt_minphys
= mesh_minphys
;
253 sc
->sc_adapter
.adapt_request
= mesh_scsi_request
;
255 sc
->sc_channel
.chan_adapter
= &sc
->sc_adapter
;
256 sc
->sc_channel
.chan_bustype
= &scsi_bustype
;
257 sc
->sc_channel
.chan_channel
= 0;
258 sc
->sc_channel
.chan_ntargets
= 8;
259 sc
->sc_channel
.chan_nluns
= 8;
260 sc
->sc_channel
.chan_id
= sc
->sc_id
;
262 config_found(self
, &sc
->sc_channel
, scsiprint
);
264 intr_establish(sc
->sc_irq
, IST_EDGE
, IPL_BIO
, mesh_intr
, sc
);
266 /* Reset SCSI bus when halt. */
267 if (pmf_device_register1(self
, NULL
, NULL
, mesh_shutdown
))
268 aprint_error_dev(self
, "couldn't establish power handler\n");
271 #define MESH_SET_XFER(sc, count) do { \
272 mesh_set_reg(sc, MESH_XFER_COUNT0, count); \
273 mesh_set_reg(sc, MESH_XFER_COUNT1, count >> 8); \
276 #define MESH_GET_XFER(sc) ((mesh_read_reg(sc, MESH_XFER_COUNT1) << 8) | \
277 mesh_read_reg(sc, MESH_XFER_COUNT0))
280 mesh_read_reg(struct mesh_softc
*sc
, int reg
)
282 return in8(sc
->sc_reg
+ reg
);
286 mesh_set_reg(struct mesh_softc
*sc
, int reg
, int val
)
288 out8(sc
->sc_reg
+ reg
, val
);
292 mesh_shutdown(device_t self
, int howto
)
294 struct mesh_softc
*sc
;
296 sc
= device_private(self
);
298 /* Set to async mode. */
299 mesh_set_reg(sc
, MESH_SYNC_PARAM
, 2);
306 static char scsi_phase
[][8] = {
321 struct mesh_softc
*sc
= arg
;
322 struct mesh_scb
*scb
;
324 u_char intr
, exception
, error
, status0
, status1
;
326 intr
= mesh_read_reg(sc
, MESH_INTERRUPT
);
328 DPRINTF("%s: stray interrupt\n", device_xname(sc
->sc_dev
));
332 exception
= mesh_read_reg(sc
, MESH_EXCEPTION
);
333 error
= mesh_read_reg(sc
, MESH_ERROR
);
334 status0
= mesh_read_reg(sc
, MESH_BUS_STATUS0
);
335 status1
= mesh_read_reg(sc
, MESH_BUS_STATUS1
);
337 /* clear interrupt */
338 mesh_set_reg(sc
, MESH_INTERRUPT
, intr
);
342 char buf1
[64], buf2
[64];
344 snprintb(buf1
, sizeof buf1
, MESH_STATUS0_BITMASK
, status0
);
345 snprintb(buf2
, sizeof buf2
, MESH_EXC_BITMASK
, exception
);
346 printf("mesh_intr status0 = 0x%s (%s), exc = 0x%s\n",
347 buf1
, scsi_phase
[status0
& 7], buf2
);
353 DPRINTF("%s: NULL nexus\n", device_xname(sc
->sc_dev
));
357 if (intr
& MESH_INTR_CMDDONE
) {
358 if (sc
->sc_flags
& MESH_DMA_ACTIVE
) {
359 dbdma_stop(sc
->sc_dmareg
);
361 sc
->sc_flags
&= ~MESH_DMA_ACTIVE
;
362 scb
->resid
= MESH_GET_XFER(sc
);
364 fifocnt
= mesh_read_reg(sc
, MESH_FIFO_COUNT
);
366 if (scb
->flags
& MESH_READ
) {
369 cp
= (char *)scb
->daddr
+ scb
->dlen
371 DPRINTF("fifocnt = %d, resid = %d\n",
372 fifocnt
, scb
->resid
);
373 while (fifocnt
> 0) {
374 *cp
++ = mesh_read_reg(sc
,
379 mesh_set_reg(sc
, MESH_SEQUENCE
,
380 MESH_CMD_FLUSH_FIFO
);
383 /* Clear all interrupts */
384 mesh_set_reg(sc
, MESH_INTERRUPT
, 7);
389 if (intr
& MESH_INTR_ERROR
) {
390 printf("%s: error %02x %02x\n",
391 device_xname(sc
->sc_dev
), error
, exception
);
392 mesh_error(sc
, scb
, error
, 0);
396 if (intr
& MESH_INTR_EXCEPTION
) {
397 /* selection timeout */
398 if (exception
& MESH_EXC_SELTO
) {
399 mesh_error(sc
, scb
, 0, exception
);
404 if (exception
& MESH_EXC_PHASEMM
) {
405 DPRINTF("%s: PHASE MISMATCH; nextstate = %d -> ",
406 device_xname(sc
->sc_dev
), sc
->sc_nextstate
);
407 sc
->sc_nextstate
= status0
& MESH_PHASE_MASK
;
409 DPRINTF("%d, resid = %d\n",
410 sc
->sc_nextstate
, scb
->resid
);
414 if (sc
->sc_nextstate
== MESH_UNKNOWN
)
415 sc
->sc_nextstate
= status0
& MESH_PHASE_MASK
;
417 switch (sc
->sc_nextstate
) {
420 mesh_identify(sc
, scb
);
423 mesh_command(sc
, scb
);
427 mesh_dataio(sc
, scb
);
430 mesh_status(sc
, scb
);
440 printf("%s: unknown state (%d)\n", device_xname(sc
->sc_dev
),
442 scb
->xs
->error
= XS_DRIVER_STUFFUP
;
450 mesh_error(struct mesh_softc
*sc
, struct mesh_scb
*scb
, int error
, int exception
)
452 if (error
& MESH_ERR_SCSI_RESET
) {
453 printf("%s: SCSI RESET\n", device_xname(sc
->sc_dev
));
455 /* Wait until the RST signal is deasserted. */
456 while (mesh_read_reg(sc
, MESH_BUS_STATUS1
) & MESH_STATUS1_RST
);
461 if (error
& MESH_ERR_PARITY_ERR0
) {
462 printf("%s: parity error\n", device_xname(sc
->sc_dev
));
463 scb
->xs
->error
= XS_DRIVER_STUFFUP
;
466 if (error
& MESH_ERR_DISCONNECT
) {
467 printf("%s: unexpected disconnect\n", device_xname(sc
->sc_dev
));
468 if (sc
->sc_nextstate
!= MESH_COMPLETE
)
469 scb
->xs
->error
= XS_DRIVER_STUFFUP
;
472 if (exception
& MESH_EXC_SELTO
) {
473 /* XXX should reset bus here? */
474 scb
->xs
->error
= XS_SELTIMEOUT
;
481 mesh_select(struct mesh_softc
*sc
, struct mesh_scb
*scb
)
483 struct mesh_tinfo
*ti
= &sc
->sc_tinfo
[scb
->target
];
486 DPRINTF("mesh_select\n");
488 mesh_setsync(sc
, ti
);
489 MESH_SET_XFER(sc
, 0);
494 * MESH mistakenly asserts TARGET ID bit along with its own ID bit
495 * in arbitration phase (like selection). So we should load
496 * initiator ID to DestID register temporarily.
498 mesh_set_reg(sc
, MESH_DEST_ID
, sc
->sc_id
);
499 mesh_set_reg(sc
, MESH_INTR_MASK
, 0); /* disable intr. */
500 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_ARBITRATE
);
502 while (mesh_read_reg(sc
, MESH_INTERRUPT
) == 0);
503 mesh_set_reg(sc
, MESH_INTERRUPT
, 1);
504 mesh_set_reg(sc
, MESH_INTR_MASK
, 7);
507 mesh_set_reg(sc
, MESH_DEST_ID
, scb
->target
);
508 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_SELECT
| MESH_SEQ_ATN
);
510 sc
->sc_prevphase
= MESH_SELECTING
;
511 sc
->sc_nextstate
= MESH_IDENTIFY
;
513 timeout
= mstohz(scb
->xs
->timeout
);
517 callout_reset(&scb
->xs
->xs_callout
, timeout
, mesh_timeout
, scb
);
521 mesh_identify(struct mesh_softc
*sc
, struct mesh_scb
*scb
)
523 struct mesh_tinfo
*ti
= &sc
->sc_tinfo
[scb
->target
];
525 DPRINTF("mesh_identify\n");
526 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_FLUSH_FIFO
);
528 if ((ti
->flags
& T_SYNCNEGO
) == 0) {
529 ti
->period
= sc
->sc_minsync
;
531 mesh_msgout(sc
, SEND_IDENTIFY
| SEND_SDTR
);
532 sc
->sc_nextstate
= MESH_MSGIN
;
534 mesh_msgout(sc
, SEND_IDENTIFY
);
535 sc
->sc_nextstate
= MESH_COMMAND
;
540 mesh_command(struct mesh_softc
*sc
, struct mesh_scb
*scb
)
546 printf("mesh_command cdb = %02x", scb
->cmd
.opcode
);
547 for (i
= 0; i
< 5; i
++)
548 printf(" %02x", scb
->cmd
.bytes
[i
]);
552 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_FLUSH_FIFO
);
554 MESH_SET_XFER(sc
, scb
->cmdlen
);
555 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_COMMAND
);
557 cmdp
= (char *)&scb
->cmd
;
558 for (i
= 0; i
< scb
->cmdlen
; i
++)
559 mesh_set_reg(sc
, MESH_FIFO
, *cmdp
++);
562 sc
->sc_nextstate
= MESH_STATUS
; /* no data xfer */
564 sc
->sc_nextstate
= MESH_DATAIN
;
568 mesh_dma_setup(struct mesh_softc
*sc
, struct mesh_scb
*scb
)
570 int datain
= scb
->flags
& MESH_READ
;
571 dbdma_command_t
*cmdp
;
576 cmdp
= sc
->sc_dmacmd
;
577 cmd
= datain
? DBDMA_CMD_IN_MORE
: DBDMA_CMD_OUT_MORE
;
581 if (count
/ PAGE_SIZE
> 32)
582 panic("mesh: transfer size >= 128k");
585 offset
= va
& PGOFSET
;
587 /* if va is not page-aligned, setup the first page */
589 int rest
= PAGE_SIZE
- offset
; /* the rest in the page */
591 if (count
> rest
) { /* if continues to next page */
592 DBDMA_BUILD(cmdp
, cmd
, 0, rest
, vtophys(va
),
593 DBDMA_INT_NEVER
, DBDMA_WAIT_NEVER
,
601 /* now va is page-aligned */
602 while (count
> PAGE_SIZE
) {
603 DBDMA_BUILD(cmdp
, cmd
, 0, PAGE_SIZE
, vtophys(va
),
604 DBDMA_INT_NEVER
, DBDMA_WAIT_NEVER
, DBDMA_BRANCH_NEVER
);
610 /* the last page (count <= PAGE_SIZE here) */
611 cmd
= datain
? DBDMA_CMD_IN_LAST
: DBDMA_CMD_OUT_LAST
;
612 DBDMA_BUILD(cmdp
, cmd
, 0, count
, vtophys(va
),
613 DBDMA_INT_NEVER
, DBDMA_WAIT_NEVER
, DBDMA_BRANCH_NEVER
);
616 DBDMA_BUILD(cmdp
, DBDMA_CMD_STOP
, 0, 0, 0,
617 DBDMA_INT_NEVER
, DBDMA_WAIT_NEVER
, DBDMA_BRANCH_NEVER
);
621 mesh_dataio(struct mesh_softc
*sc
, struct mesh_scb
*scb
)
623 DPRINTF("mesh_dataio len = %ld (%s)\n", scb
->dlen
,
624 scb
->flags
& MESH_READ
? "read" : "write");
626 mesh_dma_setup(sc
, scb
);
628 if (scb
->dlen
== 65536)
629 MESH_SET_XFER(sc
, 0); /* TC = 0 means 64KB transfer */
631 MESH_SET_XFER(sc
, scb
->dlen
);
633 if (scb
->flags
& MESH_READ
)
634 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_DATAIN
| MESH_SEQ_DMA
);
636 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_DATAOUT
| MESH_SEQ_DMA
);
637 dbdma_start(sc
->sc_dmareg
, sc
->sc_dmacmd
);
638 sc
->sc_flags
|= MESH_DMA_ACTIVE
;
639 sc
->sc_nextstate
= MESH_STATUS
;
643 mesh_status(struct mesh_softc
*sc
, struct mesh_scb
*scb
)
645 if (mesh_read_reg(sc
, MESH_FIFO_COUNT
) == 0) { /* XXX cheat */
646 DPRINTF("mesh_status(0)\n");
647 MESH_SET_XFER(sc
, 1);
648 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_STATUS
);
649 sc
->sc_nextstate
= MESH_STATUS
;
653 scb
->status
= mesh_read_reg(sc
, MESH_FIFO
);
654 DPRINTF("mesh_status(1): status = 0x%x\n", scb
->status
);
655 if (mesh_read_reg(sc
, MESH_FIFO_COUNT
) != 0)
656 DPRINTF("FIFO_COUNT=%d\n", mesh_read_reg(sc
, MESH_FIFO_COUNT
));
658 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_FLUSH_FIFO
);
659 MESH_SET_XFER(sc
, 1);
660 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_MSGIN
);
662 sc
->sc_nextstate
= MESH_MSGIN
;
666 mesh_msgin(struct mesh_softc
*sc
, struct mesh_scb
*scb
)
668 DPRINTF("mesh_msgin\n");
670 if (mesh_read_reg(sc
, MESH_FIFO_COUNT
) == 0) { /* XXX cheat */
671 MESH_SET_XFER(sc
, 1);
672 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_MSGIN
);
674 sc
->sc_nextstate
= MESH_MSGIN
;
678 sc
->sc_imsg
[sc
->sc_imsglen
++] = mesh_read_reg(sc
, MESH_FIFO
);
680 if (sc
->sc_imsglen
== 1 && MSG_IS1BYTE(sc
->sc_imsg
[0]))
682 if (sc
->sc_imsglen
== 2 && MSG_IS2BYTE(sc
->sc_imsg
[0]))
684 if (sc
->sc_imsglen
>= 3 && MSG_ISEXTENDED(sc
->sc_imsg
[0]) &&
685 sc
->sc_imsglen
== sc
->sc_imsg
[1] + 2)
688 sc
->sc_nextstate
= MESH_MSGIN
;
689 MESH_SET_XFER(sc
, 1);
690 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_MSGIN
);
696 for (i
= 0; i
< sc
->sc_imsglen
; i
++)
697 printf(" 0x%02x", sc
->sc_imsg
[i
]);
701 switch (sc
->sc_imsg
[0]) {
702 case MSG_CMDCOMPLETE
:
703 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_BUSFREE
);
704 sc
->sc_nextstate
= MESH_COMPLETE
;
708 case MSG_MESSAGE_REJECT
:
709 if (sc
->sc_msgout
& SEND_SDTR
) {
710 printf("SDTR rejected\n");
711 printf("using async mode\n");
712 sc
->sc_tinfo
[scb
->target
].period
= 0;
713 sc
->sc_tinfo
[scb
->target
].offset
= 0;
714 mesh_setsync(sc
, &sc
->sc_tinfo
[scb
->target
]);
726 scsipi_printaddr(scb
->xs
->xs_periph
);
727 printf("unrecognized MESSAGE(0x%02x); sending REJECT\n",
731 mesh_msgout(sc
, SEND_REJECT
);
737 /* process an extended message */
738 switch (sc
->sc_imsg
[2]) {
741 struct mesh_tinfo
*ti
= &sc
->sc_tinfo
[scb
->target
];
742 int period
= sc
->sc_imsg
[3];
743 int offset
= sc
->sc_imsg
[4];
744 int r
= 250 / period
;
745 int s
= (100*250) / period
- 100 * r
;
747 if (period
< sc
->sc_minsync
) {
748 ti
->period
= sc
->sc_minsync
;
750 mesh_msgout(sc
, SEND_SDTR
);
753 scsipi_printaddr(scb
->xs
->xs_periph
);
754 /* XXX if (offset != 0) ... */
755 printf("max sync rate %d.%02dMb/s\n", r
, s
);
758 ti
->flags
|= T_SYNCNEGO
;
759 ti
->flags
|= T_SYNCMODE
;
760 mesh_setsync(sc
, ti
);
764 printf("%s target %d: rejecting extended message 0x%x\n",
765 device_xname(sc
->sc_dev
), scb
->target
, sc
->sc_imsg
[0]);
771 sc
->sc_nextstate
= MESH_UNKNOWN
;
773 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_BUSFREE
); /* XXX really? */
777 mesh_msgout(struct mesh_softc
*sc
, int msg
)
779 struct mesh_scb
*scb
= sc
->sc_nexus
;
780 struct mesh_tinfo
*ti
;
783 DPRINTF("mesh_msgout: sending");
788 if (msg
& SEND_REJECT
) {
790 sc
->sc_omsg
[len
++] = MSG_MESSAGE_REJECT
;
792 if (msg
& SEND_IDENTIFY
) {
793 DPRINTF(" IDENTIFY");
794 lun
= scb
->xs
->xs_periph
->periph_lun
;
795 sc
->sc_omsg
[len
++] = MSG_IDENTIFY(lun
, 0);
797 if (msg
& SEND_SDTR
) {
799 ti
= &sc
->sc_tinfo
[scb
->target
];
800 sc
->sc_omsg
[len
++] = MSG_EXTENDED
;
801 sc
->sc_omsg
[len
++] = 3;
802 sc
->sc_omsg
[len
++] = MSG_EXT_SDTR
;
803 sc
->sc_omsg
[len
++] = ti
->period
;
804 sc
->sc_omsg
[len
++] = ti
->offset
;
808 MESH_SET_XFER(sc
, len
);
810 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_MSGOUT
);
811 mesh_set_reg(sc
, MESH_FIFO
, sc
->sc_omsg
[0]);
813 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_MSGOUT
| MESH_SEQ_ATN
);
815 for (i
= 0; i
< len
- 1; i
++)
816 mesh_set_reg(sc
, MESH_FIFO
, sc
->sc_omsg
[i
]);
818 /* Wait for the FIFO empty... */
819 while (mesh_read_reg(sc
, MESH_FIFO_COUNT
) > 0);
821 /* ...then write the last byte. */
822 mesh_set_reg(sc
, MESH_FIFO
, sc
->sc_omsg
[i
]);
824 sc
->sc_nextstate
= MESH_UNKNOWN
;
828 mesh_bus_reset(struct mesh_softc
*sc
)
830 DPRINTF("mesh_bus_reset\n");
832 /* Disable interrupts. */
833 mesh_set_reg(sc
, MESH_INTR_MASK
, 0);
835 /* Assert RST line. */
836 mesh_set_reg(sc
, MESH_BUS_STATUS1
, MESH_STATUS1_RST
);
838 mesh_set_reg(sc
, MESH_BUS_STATUS1
, 0);
844 mesh_reset(struct mesh_softc
*sc
)
848 DPRINTF("mesh_reset\n");
850 /* Reset DMA first. */
851 dbdma_reset(sc
->sc_dmareg
);
853 /* Disable interrupts. */
854 mesh_set_reg(sc
, MESH_INTR_MASK
, 0);
856 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_RESET_MESH
);
859 /* Wait for reset done. */
860 while (mesh_read_reg(sc
, MESH_INTERRUPT
) == 0);
862 /* Clear interrupts */
863 mesh_set_reg(sc
, MESH_INTERRUPT
, 0x7);
866 mesh_set_reg(sc
, MESH_SOURCE_ID
, sc
->sc_id
);
868 /* Set to async mode by default. */
869 mesh_set_reg(sc
, MESH_SYNC_PARAM
, 2);
871 /* Set selection timeout to 250ms. */
872 mesh_set_reg(sc
, MESH_SEL_TIMEOUT
, 250 * sc
->sc_freq
/ 500);
874 /* Enable parity check. */
875 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_ENABLE_PARITY
);
877 /* Enable all interrupts. */
878 mesh_set_reg(sc
, MESH_INTR_MASK
, 0x7);
880 for (i
= 0; i
< 7; i
++) {
881 struct mesh_tinfo
*ti
= &sc
->sc_tinfo
[i
];
884 ti
->period
= ti
->offset
= 0;
885 if (sc
->sc_cfflags
& (0x100 << i
))
886 ti
->flags
|= T_SYNCNEGO
;
892 mesh_stp(struct mesh_softc
*sc
, int v
)
895 * stp(v) = 5 * clock_period (v == 0)
896 * = (v + 2) * 2 clock_period (v > 0)
900 return 5 * 250 / sc
->sc_freq
;
902 return (v
+ 2) * 2 * 250 / sc
->sc_freq
;
906 mesh_setsync(struct mesh_softc
*sc
, struct mesh_tinfo
*ti
)
908 int period
= ti
->period
;
909 int offset
= ti
->offset
;
912 if ((ti
->flags
& T_SYNCMODE
) == 0)
915 if (offset
== 0) { /* async mode */
916 mesh_set_reg(sc
, MESH_SYNC_PARAM
, 2);
920 v
= period
* sc
->sc_freq
/ 250 / 2 - 2;
923 if (mesh_stp(sc
, v
) < period
)
927 mesh_set_reg(sc
, MESH_SYNC_PARAM
, (offset
<< 4) | v
);
931 mesh_get_scb(struct mesh_softc
*sc
)
933 struct mesh_scb
*scb
;
937 if ((scb
= sc
->free_scb
.tqh_first
) != NULL
)
938 TAILQ_REMOVE(&sc
->free_scb
, scb
, chain
);
945 mesh_free_scb(struct mesh_softc
*sc
, struct mesh_scb
*scb
)
950 TAILQ_INSERT_HEAD(&sc
->free_scb
, scb
, chain
);
955 mesh_scsi_request(struct scsipi_channel
*chan
, scsipi_adapter_req_t req
, void *arg
)
957 struct scsipi_xfer
*xs
;
958 struct scsipi_periph
*periph
;
959 struct mesh_softc
*sc
= device_private(chan
->chan_adapter
->adapt_dev
);
960 struct mesh_scb
*scb
;
965 case ADAPTER_REQ_RUN_XFER
:
967 periph
= xs
->xs_periph
;
968 flags
= xs
->xs_control
;
971 if ((scb
= mesh_get_scb(sc
)) == NULL
) {
972 xs
->error
= XS_RESOURCE_SHORTAGE
;
979 scb
->daddr
= (vaddr_t
)xs
->data
;
980 scb
->dlen
= xs
->datalen
;
981 scb
->resid
= xs
->datalen
;
982 memcpy(&scb
->cmd
, xs
->cmd
, xs
->cmdlen
);
983 scb
->cmdlen
= xs
->cmdlen
;
984 scb
->target
= periph
->periph_target
;
985 sc
->sc_imsglen
= 0; /* XXX ? */
990 printf("mesh_scsi_cmd: target = %d, cdb = %02x",
991 scb
->target
, scb
->cmd
.opcode
);
992 for (i
= 0; i
< 5; i
++)
993 printf(" %02x", scb
->cmd
.bytes
[i
]);
998 if (flags
& XS_CTL_POLL
)
999 scb
->flags
|= MESH_POLL
;
1001 if (flags
& XS_CTL_DATA_OUT
)
1002 scb
->flags
&= ~MESH_READ
;
1004 if (flags
& XS_CTL_DATA_IN
)
1005 scb
->flags
|= MESH_READ
;
1009 TAILQ_INSERT_TAIL(&sc
->ready_scb
, scb
, chain
);
1011 if (sc
->sc_nexus
== NULL
) /* IDLE */
1016 if ((flags
& XS_CTL_POLL
) == 0)
1019 if (mesh_poll(sc
, xs
)) {
1020 printf("%s: timeout\n", device_xname(sc
->sc_dev
));
1021 if (mesh_poll(sc
, xs
))
1022 printf("%s: timeout again\n",
1023 device_xname(sc
->sc_dev
));
1027 case ADAPTER_REQ_GROW_RESOURCES
:
1028 /* XXX Not supported. */
1031 case ADAPTER_REQ_SET_XFER_MODE
:
1032 /* XXX Not supported. */
1039 mesh_sched(struct mesh_softc
*sc
)
1041 struct scsipi_xfer
*xs
;
1042 struct mesh_scb
*scb
;
1044 scb
= sc
->ready_scb
.tqh_first
;
1051 if (sc
->sc_nexus
== NULL
) {
1052 TAILQ_REMOVE(&sc
->ready_scb
, scb
, chain
);
1054 mesh_select(sc
, scb
);
1058 scb
= scb
->chain
.tqe_next
;
1063 mesh_poll(struct mesh_softc
*sc
, struct scsipi_xfer
*xs
)
1065 int count
= xs
->timeout
;
1068 if (mesh_read_reg(sc
, MESH_INTERRUPT
))
1071 if (xs
->xs_status
& XS_STS_DONE
)
1080 mesh_done(struct mesh_softc
*sc
, struct mesh_scb
*scb
)
1082 struct scsipi_xfer
*xs
= scb
->xs
;
1084 DPRINTF("mesh_done\n");
1086 sc
->sc_nextstate
= MESH_BUSFREE
;
1087 sc
->sc_nexus
= NULL
;
1089 callout_stop(&scb
->xs
->xs_callout
);
1091 if (scb
->status
== SCSI_BUSY
) {
1092 xs
->error
= XS_BUSY
;
1093 printf("Target busy\n");
1096 xs
->status
= scb
->status
;
1097 xs
->resid
= scb
->resid
;
1098 if (scb
->status
== SCSI_CHECK
) {
1099 xs
->error
= XS_BUSY
;
1102 mesh_set_reg(sc
, MESH_SYNC_PARAM
, 2);
1104 if ((xs
->xs_control
& XS_CTL_POLL
) == 0)
1108 mesh_free_scb(sc
, scb
);
1112 mesh_timeout(void *arg
)
1114 struct mesh_scb
*scb
= arg
;
1115 struct mesh_softc
*sc
=
1116 device_private(scb
->xs
->xs_periph
->periph_channel
->chan_adapter
->adapt_dev
);
1118 int status0
, status1
;
1119 int intr
, error
, exception
, imsk
;
1121 printf("%s: timeout state %d\n", device_xname(sc
->sc_dev
),
1124 intr
= mesh_read_reg(sc
, MESH_INTERRUPT
);
1125 imsk
= mesh_read_reg(sc
, MESH_INTR_MASK
);
1126 exception
= mesh_read_reg(sc
, MESH_EXCEPTION
);
1127 error
= mesh_read_reg(sc
, MESH_ERROR
);
1128 status0
= mesh_read_reg(sc
, MESH_BUS_STATUS0
);
1129 status1
= mesh_read_reg(sc
, MESH_BUS_STATUS1
);
1131 printf("%s: intr/msk %02x/%02x, exc %02x, err %02x, st0/1 %02x/%02x\n",
1132 device_xname(sc
->sc_dev
),
1133 intr
, imsk
, exception
, error
, status0
, status1
);
1136 if (sc
->sc_flags
& MESH_DMA_ACTIVE
) {
1137 printf("mesh: resetting DMA\n");
1138 dbdma_reset(sc
->sc_dmareg
);
1140 scb
->xs
->error
= XS_TIMEOUT
;
1142 mesh_set_reg(sc
, MESH_SEQUENCE
, MESH_CMD_BUSFREE
);
1143 sc
->sc_nextstate
= MESH_COMPLETE
;
1149 mesh_minphys(struct buf
*bp
)
1151 if (bp
->b_bcount
> 64*1024)
1152 bp
->b_bcount
= 64*1024;