1 /* $NetBSD: ninjascsi32.c,v 1.19 2009/05/16 05:26:31 tsutsui Exp $ */
4 * Copyright (c) 2004, 2006, 2007 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: ninjascsi32.c,v 1.19 2009/05/16 05:26:31 tsutsui Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/callout.h>
38 #include <sys/device.h>
39 #include <sys/kernel.h>
41 #include <sys/scsiio.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>
55 * DualEdge transfer support
57 /* #define NJSC32_DUALEDGE */ /* XXX untested */
60 * Auto param loading does not work properly (it partially works (works on
61 * start, doesn't on restart) on rev 0x54, it doesn't work at all on rev 0x51),
62 * and it doesn't improve the performance so much,
65 #undef NJSC32_AUTOPARAM
67 #include <dev/ic/ninjascsi32reg.h>
68 #include <dev/ic/ninjascsi32var.h>
70 /* #define NJSC32_DEBUG */
71 /* #define NJSC32_TRACE */
74 #define DPRINTF(x) printf x
75 #define DPRINTC(cmd, x) PRINTC(cmd, x)
78 #define DPRINTC(cmd, x)
81 #define TPRINTF(x) printf x
82 #define TPRINTC(cmd, x) PRINTC(cmd, x)
85 #define TPRINTC(cmd, x)
88 #define PRINTC(cmd, x) do { \
89 scsi_print_addr((cmd)->c_xs->xs_periph); \
91 } while (/* CONSTCOND */ 0)
93 static void njsc32_scsipi_request(struct scsipi_channel
*,
94 scsipi_adapter_req_t
, void *);
95 static void njsc32_scsipi_minphys(struct buf
*);
96 static int njsc32_scsipi_ioctl(struct scsipi_channel
*, u_long
, void *,
99 static void njsc32_init(struct njsc32_softc
*, int nosleep
);
100 static int njsc32_init_cmds(struct njsc32_softc
*);
101 static void njsc32_target_async(struct njsc32_softc
*,
102 struct njsc32_target
*);
103 static void njsc32_init_targets(struct njsc32_softc
*);
104 static void njsc32_add_msgout(struct njsc32_softc
*, int);
105 static u_int32_t
njsc32_get_auto_msgout(struct njsc32_softc
*);
106 #ifdef NJSC32_DUALEDGE
107 static void njsc32_msgout_wdtr(struct njsc32_softc
*, int);
109 static void njsc32_msgout_sdtr(struct njsc32_softc
*, int period
,
111 static void njsc32_negotiate_xfer(struct njsc32_softc
*,
112 struct njsc32_target
*);
113 static void njsc32_arbitration_failed(struct njsc32_softc
*);
114 static void njsc32_start(struct njsc32_softc
*);
115 static void njsc32_run_xfer(struct njsc32_softc
*, struct scsipi_xfer
*);
116 static void njsc32_end_cmd(struct njsc32_softc
*, struct njsc32_cmd
*,
117 scsipi_xfer_result_t
);
118 static void njsc32_wait_reset_release(void *);
119 static void njsc32_reset_bus(struct njsc32_softc
*);
120 static void njsc32_clear_cmds(struct njsc32_softc
*,
121 scsipi_xfer_result_t
);
122 static void njsc32_set_ptr(struct njsc32_softc
*, struct njsc32_cmd
*,
124 static void njsc32_assert_ack(struct njsc32_softc
*);
125 static void njsc32_negate_ack(struct njsc32_softc
*);
126 static void njsc32_wait_req_negate(struct njsc32_softc
*);
127 static void njsc32_reconnect(struct njsc32_softc
*, struct njsc32_cmd
*);
128 enum njsc32_reselstat
{
129 NJSC32_RESEL_ERROR
, /* to be rejected */
130 NJSC32_RESEL_COMPLETE
, /* reselection is just complete */
131 NJSC32_RESEL_THROUGH
/* this message is OK (no reply) */
133 static enum njsc32_reselstat
njsc32_resel_identify(struct njsc32_softc
*,
134 int lun
, struct njsc32_cmd
**);
135 static enum njsc32_reselstat
njsc32_resel_tag(struct njsc32_softc
*,
136 int tag
, struct njsc32_cmd
**);
137 static void njsc32_cmd_reload(struct njsc32_softc
*, struct njsc32_cmd
*,
139 static void njsc32_update_xfer_mode(struct njsc32_softc
*,
140 struct njsc32_target
*);
141 static void njsc32_msgin(struct njsc32_softc
*);
142 static void njsc32_msgout(struct njsc32_softc
*);
143 static void njsc32_cmdtimeout(void *);
144 static void njsc32_reseltimeout(void *);
146 static inline unsigned
147 njsc32_read_1(struct njsc32_softc
*sc
, int no
)
150 return bus_space_read_1(sc
->sc_regt
, sc
->sc_regh
, no
);
153 static inline unsigned
154 njsc32_read_2(struct njsc32_softc
*sc
, int no
)
157 return bus_space_read_2(sc
->sc_regt
, sc
->sc_regh
, no
);
160 static inline u_int32_t
161 njsc32_read_4(struct njsc32_softc
*sc
, int no
)
164 return bus_space_read_4(sc
->sc_regt
, sc
->sc_regh
, no
);
168 njsc32_write_1(struct njsc32_softc
*sc
, int no
, int val
)
171 bus_space_write_1(sc
->sc_regt
, sc
->sc_regh
, no
, val
);
175 njsc32_write_2(struct njsc32_softc
*sc
, int no
, int val
)
178 bus_space_write_2(sc
->sc_regt
, sc
->sc_regh
, no
, val
);
182 njsc32_write_4(struct njsc32_softc
*sc
, int no
, u_int32_t val
)
185 bus_space_write_4(sc
->sc_regt
, sc
->sc_regh
, no
, val
);
188 static inline unsigned
189 njsc32_ireg_read_1(struct njsc32_softc
*sc
, int no
)
192 bus_space_write_1(sc
->sc_regt
, sc
->sc_regh
, NJSC32_REG_INDEX
, no
);
193 return bus_space_read_1(sc
->sc_regt
, sc
->sc_regh
, NJSC32_REG_DATA_LOW
);
196 static inline unsigned
197 njsc32_ireg_read_2(struct njsc32_softc
*sc
, int no
)
200 bus_space_write_1(sc
->sc_regt
, sc
->sc_regh
, NJSC32_REG_INDEX
, no
);
201 return bus_space_read_2(sc
->sc_regt
, sc
->sc_regh
, NJSC32_REG_DATA_LOW
);
204 static inline u_int32_t
205 njsc32_ireg_read_4(struct njsc32_softc
*sc
, int no
)
209 bus_space_write_1(sc
->sc_regt
, sc
->sc_regh
, NJSC32_REG_INDEX
, no
);
210 val
= (u_int16_t
)bus_space_read_2(sc
->sc_regt
, sc
->sc_regh
,
211 NJSC32_REG_DATA_LOW
);
212 return val
| (bus_space_read_2(sc
->sc_regt
, sc
->sc_regh
,
213 NJSC32_REG_DATA_HIGH
) << 16);
217 njsc32_ireg_write_1(struct njsc32_softc
*sc
, int no
, int val
)
220 bus_space_write_1(sc
->sc_regt
, sc
->sc_regh
, NJSC32_REG_INDEX
, no
);
221 bus_space_write_1(sc
->sc_regt
, sc
->sc_regh
, NJSC32_REG_DATA_LOW
, val
);
225 njsc32_ireg_write_2(struct njsc32_softc
*sc
, int no
, int val
)
228 bus_space_write_1(sc
->sc_regt
, sc
->sc_regh
, NJSC32_REG_INDEX
, no
);
229 bus_space_write_2(sc
->sc_regt
, sc
->sc_regh
, NJSC32_REG_DATA_LOW
, val
);
233 njsc32_ireg_write_4(struct njsc32_softc
*sc
, int no
, u_int32_t val
)
236 bus_space_write_1(sc
->sc_regt
, sc
->sc_regh
, NJSC32_REG_INDEX
, no
);
237 bus_space_write_2(sc
->sc_regt
, sc
->sc_regh
, NJSC32_REG_DATA_LOW
, val
);
238 bus_space_write_2(sc
->sc_regt
, sc
->sc_regh
, NJSC32_REG_DATA_HIGH
,
242 #define NS(ns) ((ns) / 4) /* nanosecond (>= 50) -> sync value */
244 # define ACKW(n) NJSC32_ACK_WIDTH_ ## n ## CLK
245 # define SMPL(n) (NJSC32_SREQ_SAMPLING_ ## n ## CLK | \
246 NJSC32_SREQ_SAMPLING_ENABLE)
248 # define ACKW(n) NJSC32_ACK_WIDTH_/**/n/**/CLK
249 # define SMPL(n) (NJSC32_SREQ_SAMPLING_/**/n/**/CLK | \
250 NJSC32_SREQ_SAMPLING_ENABLE)
253 #define NJSC32_NSYNCT_MAXSYNC 1
254 #define NJSC32_NSYNCT 16
257 static const struct njsc32_sync_param njsc32_synct_40M
[NJSC32_NSYNCT
] = {
258 { 0, 0, 0 }, /* dummy for async */
259 { NS( 50), ACKW(1), 0 }, /* 20.0 : 50ns, 25ns */
260 { NS( 75), ACKW(1), SMPL(1) }, /* 13.3 : 75ns, 25ns */
261 { NS(100), ACKW(2), SMPL(1) }, /* 10.0 : 100ns, 50ns */
262 { NS(125), ACKW(2), SMPL(2) }, /* 8.0 : 125ns, 50ns */
263 { NS(150), ACKW(3), SMPL(2) }, /* 6.7 : 150ns, 75ns */
264 { NS(175), ACKW(3), SMPL(2) }, /* 5.7 : 175ns, 75ns */
265 { NS(200), ACKW(4), SMPL(2) }, /* 5.0 : 200ns, 100ns */
266 { NS(225), ACKW(4), SMPL(4) }, /* 4.4 : 225ns, 100ns */
267 { NS(250), ACKW(4), SMPL(4) }, /* 4.0 : 250ns, 100ns */
268 { NS(275), ACKW(4), SMPL(4) }, /* 3.64: 275ns, 100ns */
269 { NS(300), ACKW(4), SMPL(4) }, /* 3.33: 300ns, 100ns */
270 { NS(325), ACKW(4), SMPL(4) }, /* 3.01: 325ns, 100ns */
271 { NS(350), ACKW(4), SMPL(4) }, /* 2.86: 350ns, 100ns */
272 { NS(375), ACKW(4), SMPL(4) }, /* 2.67: 375ns, 100ns */
273 { NS(400), ACKW(4), SMPL(4) } /* 2.50: 400ns, 100ns */
276 #ifdef NJSC32_SUPPORT_OTHER_CLOCKS
278 static const struct njsc32_sync_param njsc32_synct_20M
[NJSC32_NSYNCT
] = {
279 { 0, 0, 0 }, /* dummy for async */
280 { NS(100), ACKW(1), 0 }, /* 10.0 : 100ns, 50ns */
281 { NS(150), ACKW(1), SMPL(2) }, /* 6.7 : 150ns, 50ns */
282 { NS(200), ACKW(2), SMPL(2) }, /* 5.0 : 200ns, 100ns */
283 { NS(250), ACKW(2), SMPL(4) }, /* 4.0 : 250ns, 100ns */
284 { NS(300), ACKW(3), SMPL(4) }, /* 3.3 : 300ns, 150ns */
285 { NS(350), ACKW(3), SMPL(4) }, /* 2.8 : 350ns, 150ns */
286 { NS(400), ACKW(4), SMPL(4) }, /* 2.5 : 400ns, 200ns */
287 { NS(450), ACKW(4), SMPL(4) }, /* 2.2 : 450ns, 200ns */
288 { NS(500), ACKW(4), SMPL(4) }, /* 2.0 : 500ns, 200ns */
289 { NS(550), ACKW(4), SMPL(4) }, /* 1.82: 550ns, 200ns */
290 { NS(600), ACKW(4), SMPL(4) }, /* 1.67: 600ns, 200ns */
291 { NS(650), ACKW(4), SMPL(4) }, /* 1.54: 650ns, 200ns */
292 { NS(700), ACKW(4), SMPL(4) }, /* 1.43: 700ns, 200ns */
293 { NS(750), ACKW(4), SMPL(4) }, /* 1.33: 750ns, 200ns */
294 { NS(800), ACKW(4), SMPL(4) } /* 1.25: 800ns, 200ns */
298 static const struct njsc32_sync_param njsc32_synct_pci
[NJSC32_NSYNCT
] = {
299 { 0, 0, 0 }, /* dummy for async */
300 { NS( 60), ACKW(1), 0 }, /* 16.6 : 60ns, 30ns */
301 { NS( 90), ACKW(1), SMPL(1) }, /* 11.1 : 90ns, 30ns */
302 { NS(120), ACKW(2), SMPL(2) }, /* 8.3 : 120ns, 60ns */
303 { NS(150), ACKW(2), SMPL(2) }, /* 6.7 : 150ns, 60ns */
304 { NS(180), ACKW(3), SMPL(2) }, /* 5.6 : 180ns, 90ns */
305 { NS(210), ACKW(3), SMPL(4) }, /* 4.8 : 210ns, 90ns */
306 { NS(240), ACKW(4), SMPL(4) }, /* 4.2 : 240ns, 120ns */
307 { NS(270), ACKW(4), SMPL(4) }, /* 3.7 : 270ns, 120ns */
308 { NS(300), ACKW(4), SMPL(4) }, /* 3.3 : 300ns, 120ns */
309 { NS(330), ACKW(4), SMPL(4) }, /* 3.0 : 330ns, 120ns */
310 { NS(360), ACKW(4), SMPL(4) }, /* 2.8 : 360ns, 120ns */
311 { NS(390), ACKW(4), SMPL(4) }, /* 2.6 : 390ns, 120ns */
312 { NS(420), ACKW(4), SMPL(4) }, /* 2.4 : 420ns, 120ns */
313 { NS(450), ACKW(4), SMPL(4) }, /* 2.2 : 450ns, 120ns */
314 { NS(480), ACKW(4), SMPL(4) } /* 2.1 : 480ns, 120ns */
316 #endif /* NJSC32_SUPPORT_OTHER_CLOCKS */
322 /* initialize device */
324 njsc32_init(struct njsc32_softc
*sc
, int nosleep
)
329 /* block all interrupts */
330 njsc32_write_2(sc
, NJSC32_REG_IRQ
, NJSC32_IRQ_MASK_ALL
);
333 njsc32_write_2(sc
, NJSC32_REG_TRANSFER
, 0);
334 njsc32_write_4(sc
, NJSC32_REG_BM_CNT
, 0);
336 /* make sure interrupts are cleared */
337 for (i
= 0; ((intstat
= njsc32_read_2(sc
, NJSC32_REG_IRQ
))
338 & NJSC32_IRQ_INTR_PENDING
) && i
< 5 /* just not forever */; i
++) {
339 DPRINTF(("%s: njsc32_init: intr pending: %#x\n",
340 device_xname(sc
->sc_dev
), intstat
));
344 njsc32_ireg_write_1(sc
, NJSC32_IREG_FIFO_THRESHOLD_FULL
,
345 NJSC32_FIFO_FULL_BUSMASTER
);
346 njsc32_ireg_write_1(sc
, NJSC32_IREG_FIFO_THRESHOLD_EMPTY
,
347 NJSC32_FIFO_EMPTY_BUSMASTER
);
350 njsc32_ireg_write_1(sc
, NJSC32_IREG_CLOCK
, sc
->sc_clk
);
352 /* memory read multiple */
353 njsc32_ireg_write_1(sc
, NJSC32_IREG_BM
,
354 NJSC32_BM_MEMRD_CMD1
| NJSC32_BM_SGT_AUTO_PARA_MEMRD_CMD
);
356 /* clear parity error and enable parity detection */
357 njsc32_write_1(sc
, NJSC32_REG_PARITY_CONTROL
,
358 NJSC32_PARITYCTL_CHECK_ENABLE
| NJSC32_PARITYCTL_CLEAR_ERROR
);
360 /* misc configuration */
361 njsc32_ireg_write_2(sc
, NJSC32_IREG_MISC
,
362 NJSC32_MISC_SCSI_DIRECTION_DETECTOR_SELECT
|
363 NJSC32_MISC_DELAYED_BMSTART
|
364 NJSC32_MISC_MASTER_TERMINATION_SELECT
|
365 NJSC32_MISC_BMREQ_NEGATE_TIMING_SEL
|
366 NJSC32_MISC_AUTOSEL_TIMING_SEL
|
367 NJSC32_MISC_BMSTOP_CHANGE2_NONDATA_PHASE
);
370 * Check for termination power (32Bi and some versions of 32UDE).
372 if (!nosleep
|| cold
) {
373 DPRINTF(("%s: njsc32_init: checking TERMPWR\n",
374 device_xname(sc
->sc_dev
)));
376 /* First, turn termination power off */
377 njsc32_ireg_write_1(sc
, NJSC32_IREG_TERM_PWR
, 0);
379 /* give 0.5s to settle */
383 tsleep(sc
, PWAIT
, "njs_t1", hz
/ 2);
386 /* supply termination power if not supplied by other devices */
387 if ((njsc32_ireg_read_1(sc
, NJSC32_IREG_TERM_PWR
) &
388 NJSC32_TERMPWR_SENSE
) == 0) {
389 /* termination power is not present on the bus */
390 if (sc
->sc_flags
& NJSC32_CANNOT_SUPPLY_TERMPWR
) {
392 * CardBus device must not supply termination power
393 * to avoid excessive power consumption.
395 printf("%s: no termination power present\n",
396 device_xname(sc
->sc_dev
));
398 /* supply termination power */
399 njsc32_ireg_write_1(sc
, NJSC32_IREG_TERM_PWR
,
400 NJSC32_TERMPWR_BPWR
);
402 DPRINTF(("%s: supplying termination power\n",
403 device_xname(sc
->sc_dev
)));
405 /* give 0.5s to settle */
407 tsleep(sc
, PWAIT
, "njs_t2", hz
/ 2);
412 njsc32_write_2(sc
, NJSC32_REG_TIMER
, NJSC32_TIMER_STOP
);
413 njsc32_write_2(sc
, NJSC32_REG_TIMER
, NJSC32_TIMER_STOP
);
415 /* default transfer parameter */
416 njsc32_write_1(sc
, NJSC32_REG_SYNC
, 0);
417 njsc32_write_1(sc
, NJSC32_REG_ACK_WIDTH
, NJSC32_ACK_WIDTH_1CLK
);
418 njsc32_write_2(sc
, NJSC32_REG_SEL_TIMEOUT
,
419 NJSC32_SEL_TIMEOUT_TIME
);
421 /* select interrupt source */
422 njsc32_ireg_write_2(sc
, NJSC32_IREG_IRQ_SELECT
,
423 NJSC32_IRQSEL_RESELECT
|
424 NJSC32_IRQSEL_PHASE_CHANGE
|
425 NJSC32_IRQSEL_SCSIRESET
|
426 NJSC32_IRQSEL_TIMER
|
427 NJSC32_IRQSEL_FIFO_THRESHOLD
|
428 NJSC32_IRQSEL_TARGET_ABORT
|
429 NJSC32_IRQSEL_MASTER_ABORT
|
433 NJSC32_IRQSEL_BMCNTERR |
435 NJSC32_IRQSEL_AUTO_SCSI_SEQ
);
437 /* interrupts will be unblocked later after bus reset */
440 njsc32_ireg_write_1(sc
, NJSC32_IREG_EXT_PORT_DDR
,
441 NJSC32_EXTPORT_LED_OFF
);
442 njsc32_ireg_write_1(sc
, NJSC32_IREG_EXT_PORT
,
443 NJSC32_EXTPORT_LED_OFF
);
445 /* reset SCSI bus so the targets become known state */
446 njsc32_reset_bus(sc
);
450 njsc32_init_cmds(struct njsc32_softc
*sc
)
452 struct njsc32_cmd
*cmd
;
457 * allocate DMA area for command
459 if ((error
= bus_dmamem_alloc(sc
->sc_dmat
,
460 sizeof(struct njsc32_dma_page
), PAGE_SIZE
, 0,
461 &sc
->sc_cmdpg_seg
, 1, &sc
->sc_cmdpg_nsegs
, BUS_DMA_NOWAIT
)) != 0) {
462 aprint_error_dev(sc
->sc_dev
,
463 "unable to allocate cmd page, error = %d\n",
467 if ((error
= bus_dmamem_map(sc
->sc_dmat
, &sc
->sc_cmdpg_seg
,
468 sc
->sc_cmdpg_nsegs
, sizeof(struct njsc32_dma_page
),
469 (void **)&sc
->sc_cmdpg
,
470 BUS_DMA_NOWAIT
| BUS_DMA_COHERENT
)) != 0) {
471 aprint_error_dev(sc
->sc_dev
,
472 "unable to map cmd page, error = %d\n",
476 if ((error
= bus_dmamap_create(sc
->sc_dmat
,
477 sizeof(struct njsc32_dma_page
), 1,
478 sizeof(struct njsc32_dma_page
), 0, BUS_DMA_NOWAIT
,
479 &sc
->sc_dmamap_cmdpg
)) != 0) {
480 aprint_error_dev(sc
->sc_dev
,
481 "unable to create cmd DMA map, error = %d\n",
485 if ((error
= bus_dmamap_load(sc
->sc_dmat
, sc
->sc_dmamap_cmdpg
,
486 sc
->sc_cmdpg
, sizeof(struct njsc32_dma_page
),
487 NULL
, BUS_DMA_NOWAIT
)) != 0) {
488 aprint_error_dev(sc
->sc_dev
,
489 "unable to load cmd DMA map, error = %d\n",
494 memset(sc
->sc_cmdpg
, 0, sizeof(struct njsc32_dma_page
));
495 dmaaddr
= sc
->sc_dmamap_cmdpg
->dm_segs
[0].ds_addr
;
497 #ifdef NJSC32_AUTOPARAM
498 sc
->sc_ap_dma
= dmaaddr
+ offsetof(struct njsc32_dma_page
, dp_ap
);
501 for (i
= 0; i
< NJSC32_NUM_CMD
; i
++) {
502 cmd
= &sc
->sc_cmds
[i
];
504 cmd
->c_sgt
= sc
->sc_cmdpg
->dp_sg
[i
];
505 cmd
->c_sgt_dma
= dmaaddr
+
506 offsetof(struct njsc32_dma_page
, dp_sg
[i
]);
509 error
= bus_dmamap_create(sc
->sc_dmat
,
510 NJSC32_MAX_XFER
, /* max total map size */
511 NJSC32_NUM_SG
, /* max number of segments */
512 NJSC32_SGT_MAXSEGLEN
, /* max size of a segment */
514 BUS_DMA_NOWAIT
| BUS_DMA_ALLOCNOW
, &cmd
->c_dmamap_xfer
);
516 aprint_error_dev(sc
->sc_dev
,
517 "only %d cmd descs available (error = %d)\n",
521 TAILQ_INSERT_TAIL(&sc
->sc_freecmd
, cmd
, c_q
);
527 bus_dmamap_unload(sc
->sc_dmat
, sc
->sc_dmamap_cmdpg
);
528 fail3
: bus_dmamap_destroy(sc
->sc_dmat
, sc
->sc_dmamap_cmdpg
);
529 fail2
: bus_dmamem_unmap(sc
->sc_dmat
, (void *)sc
->sc_cmdpg
,
530 sizeof(struct njsc32_dma_page
));
531 fail1
: bus_dmamem_free(sc
->sc_dmat
, &sc
->sc_cmdpg_seg
, sc
->sc_cmdpg_nsegs
);
537 njsc32_target_async(struct njsc32_softc
*sc
, struct njsc32_target
*target
)
541 NJSC32_SYNC_VAL(sc
->sc_sync_max
, NJSC32_SYNCOFFSET_ASYNC
);
542 target
->t_ackwidth
= NJSC32_ACK_WIDTH_1CLK
;
543 target
->t_sample
= 0; /* disable */
544 target
->t_syncoffset
= NJSC32_SYNCOFFSET_ASYNC
;
545 target
->t_syncperiod
= NJSC32_SYNCPERIOD_ASYNC
;
549 njsc32_init_targets(struct njsc32_softc
*sc
)
552 struct njsc32_lu
*lu
;
554 for (id
= 0; id
<= NJSC32_MAX_TARGET_ID
; id
++) {
555 /* cancel negotiation status */
556 sc
->sc_targets
[id
].t_state
= NJSC32_TARST_INIT
;
558 /* default to async mode */
559 njsc32_target_async(sc
, &sc
->sc_targets
[id
]);
561 #ifdef NJSC32_DUALEDGE
562 sc
->sc_targets
[id
].t_xferctl
= 0;
565 sc
->sc_targets
[id
].t_targetid
=
566 (1 << id
) | (1 << NJSC32_INITIATOR_ID
);
568 /* init logical units */
569 for (lun
= 0; lun
< NJSC32_NLU
; lun
++) {
570 lu
= &sc
->sc_targets
[id
].t_lus
[lun
];
572 TAILQ_INIT(&lu
->lu_q
);
578 njsc32_attach(struct njsc32_softc
*sc
)
583 njsc32_model_t detected_model
;
587 TAILQ_INIT(&sc
->sc_freecmd
);
588 TAILQ_INIT(&sc
->sc_reqcmd
);
589 callout_init(&sc
->sc_callout
, 0);
593 * try to distinguish 32Bi and 32UDE
595 /* try to set DualEdge bit (exists on 32UDE only) and read it back */
596 njsc32_write_2(sc
, NJSC32_REG_TRANSFER
, NJSC32_XFR_DUALEDGE_ENABLE
);
597 if ((reg
= njsc32_read_2(sc
, NJSC32_REG_TRANSFER
)) == 0xffff) {
598 /* device was removed? */
599 aprint_error_dev(sc
->sc_dev
, "attach failed\n");
601 } else if (reg
& NJSC32_XFR_DUALEDGE_ENABLE
) {
602 detected_model
= NJSC32_MODEL_32UDE
| NJSC32_FLAG_DUALEDGE
;
604 detected_model
= NJSC32_MODEL_32BI
;
606 njsc32_write_2(sc
, NJSC32_REG_TRANSFER
, 0); /* restore */
608 #if 1/*def DIAGNOSTIC*/
609 /* compare what is configured with what is detected */
610 if ((sc
->sc_model
& NJSC32_MODEL_MASK
) !=
611 (detected_model
& NJSC32_MODEL_MASK
)) {
613 * Please report this error if it happens.
615 aprint_error_dev(sc
->sc_dev
, "model mismatch: %#x vs %#x\n",
616 sc
->sc_model
, detected_model
);
623 switch (sc
->sc_model
& NJSC32_MODEL_MASK
) {
624 case NJSC32_MODEL_32BI
:
626 /* 32Bi doesn't support DualEdge transfer */
627 KASSERT((sc
->sc_model
& NJSC32_FLAG_DUALEDGE
) == 0);
629 case NJSC32_MODEL_32UDE
:
633 aprint_error_dev(sc
->sc_dev
, "unknown model!\n");
636 aprint_normal_dev(sc
->sc_dev
, "NJSC-32%s", str
);
638 switch (sc
->sc_clk
) {
641 panic("njsc32_attach: unknown clk %d", sc
->sc_clk
);
643 case NJSC32_CLOCK_DIV_4
:
644 sc
->sc_synct
= njsc32_synct_40M
;
647 #ifdef NJSC32_SUPPORT_OTHER_CLOCKS
648 case NJSC32_CLOCK_DIV_2
:
649 sc
->sc_synct
= njsc32_synct_20M
;
652 case NJSC32_CLOCK_PCICLK
:
653 sc
->sc_synct
= njsc32_synct_pci
;
658 aprint_normal(", G/A rev %#x, clk %s%s\n",
659 NJSC32_INDEX_GAREV(njsc32_read_2(sc
, NJSC32_REG_INDEX
)), str
,
660 (sc
->sc_model
& NJSC32_FLAG_DUALEDGE
) ?
661 #ifdef NJSC32_DUALEDGE
664 ", DualEdge (no driver support)"
668 /* allocate DMA resource */
669 if ((sc
->sc_ncmd
= njsc32_init_cmds(sc
)) == 0) {
670 aprint_error_dev(sc
->sc_dev
, "no usable DMA map\n");
673 sc
->sc_flags
|= NJSC32_CMDPG_MAPPED
;
675 sc
->sc_curcmd
= NULL
;
676 sc
->sc_nusedcmds
= 0;
678 sc
->sc_sync_max
= 1; /* XXX look up EEPROM configuration? */
680 /* initialize hardware and target structure */
681 njsc32_init(sc
, cold
);
684 sc
->sc_adapter
.adapt_dev
= sc
->sc_dev
;
685 sc
->sc_adapter
.adapt_nchannels
= 1;
686 sc
->sc_adapter
.adapt_request
= njsc32_scsipi_request
;
687 sc
->sc_adapter
.adapt_minphys
= njsc32_scsipi_minphys
;
688 sc
->sc_adapter
.adapt_ioctl
= njsc32_scsipi_ioctl
;
690 sc
->sc_adapter
.adapt_max_periph
= sc
->sc_adapter
.adapt_openings
=
694 sc
->sc_channel
.chan_adapter
= &sc
->sc_adapter
;
695 sc
->sc_channel
.chan_bustype
= &scsi_bustype
;
696 sc
->sc_channel
.chan_channel
= 0;
697 sc
->sc_channel
.chan_ntargets
= NJSC32_NTARGET
;
698 sc
->sc_channel
.chan_nluns
= NJSC32_NLU
;
699 sc
->sc_channel
.chan_id
= NJSC32_INITIATOR_ID
;
701 sc
->sc_scsi
= config_found(sc
->sc_dev
, &sc
->sc_channel
, scsiprint
);
705 njsc32_detach(struct njsc32_softc
*sc
, int flags
)
709 struct njsc32_cmd
*cmd
;
711 callout_stop(&sc
->sc_callout
);
715 /* clear running/disconnected commands */
716 njsc32_clear_cmds(sc
, XS_DRIVER_STUFFUP
);
718 sc
->sc_stat
= NJSC32_STAT_DETACH
;
720 /* clear pending commands */
721 while ((cmd
= TAILQ_FIRST(&sc
->sc_reqcmd
)) != NULL
) {
722 TAILQ_REMOVE(&sc
->sc_reqcmd
, cmd
, c_q
);
723 njsc32_end_cmd(sc
, cmd
, XS_RESET
);
726 if (sc
->sc_scsi
!= NULL
)
727 rv
= config_detach(sc
->sc_scsi
, flags
);
731 /* free DMA resource */
732 if (sc
->sc_flags
& NJSC32_CMDPG_MAPPED
) {
733 for (i
= 0; i
< sc
->sc_ncmd
; i
++) {
734 cmd
= &sc
->sc_cmds
[i
];
735 if (cmd
->c_flags
& NJSC32_CMD_DMA_MAPPED
)
736 bus_dmamap_unload(sc
->sc_dmat
,
738 bus_dmamap_destroy(sc
->sc_dmat
, cmd
->c_dmamap_xfer
);
741 bus_dmamap_unload(sc
->sc_dmat
, sc
->sc_dmamap_cmdpg
);
742 bus_dmamap_destroy(sc
->sc_dmat
, sc
->sc_dmamap_cmdpg
);
743 bus_dmamem_unmap(sc
->sc_dmat
, (void *)sc
->sc_cmdpg
,
744 sizeof(struct njsc32_dma_page
));
745 bus_dmamem_free(sc
->sc_dmat
, &sc
->sc_cmdpg_seg
,
753 njsc32_cmd_init(struct njsc32_cmd
*cmd
)
758 /* scatter/gather table */
759 cmd
->c_sgtdmaaddr
= NJSC32_CMD_DMAADDR_SGT(cmd
, 0);
764 cmd
->c_dp_cur
= cmd
->c_dp_saved
= cmd
->c_dp_max
= 0;
768 njsc32_init_msgout(struct njsc32_softc
*sc
)
771 sc
->sc_msgoutlen
= 0;
772 sc
->sc_msgoutidx
= 0;
776 njsc32_add_msgout(struct njsc32_softc
*sc
, int byte
)
779 if (sc
->sc_msgoutlen
>= NJSC32_MSGOUT_LEN
) {
780 printf("njsc32_add_msgout: too many\n");
783 sc
->sc_msgout
[sc
->sc_msgoutlen
++] = byte
;
787 njsc32_get_auto_msgout(struct njsc32_softc
*sc
)
794 switch (sc
->sc_msgoutlen
) {
795 /* 31-24 23-16 15-8 7 ... 1 0 */
796 case 3: /* MSG3 MSG2 MSG1 V --- cnt */
797 val
|= *p
++ << NJSC32_MSGOUT_MSG1_SHIFT
;
800 case 2: /* MSG2 MSG1 --- V --- cnt */
801 val
|= *p
++ << NJSC32_MSGOUT_MSG2_SHIFT
;
804 case 1: /* MSG1 --- --- V --- cnt */
805 val
|= *p
++ << NJSC32_MSGOUT_MSG3_SHIFT
;
806 val
|= NJSC32_MSGOUT_VALID
| sc
->sc_msgoutlen
;
815 #ifdef NJSC32_DUALEDGE
816 /* add Wide Data Transfer Request to the next Message Out */
818 njsc32_msgout_wdtr(struct njsc32_softc
*sc
, int width
)
821 njsc32_add_msgout(sc
, MSG_EXTENDED
);
822 njsc32_add_msgout(sc
, MSG_EXT_WDTR_LEN
);
823 njsc32_add_msgout(sc
, MSG_EXT_WDTR
);
824 njsc32_add_msgout(sc
, width
);
828 /* add Synchronous Data Transfer Request to the next Message Out */
830 njsc32_msgout_sdtr(struct njsc32_softc
*sc
, int period
, int offset
)
833 njsc32_add_msgout(sc
, MSG_EXTENDED
);
834 njsc32_add_msgout(sc
, MSG_EXT_SDTR_LEN
);
835 njsc32_add_msgout(sc
, MSG_EXT_SDTR
);
836 njsc32_add_msgout(sc
, period
);
837 njsc32_add_msgout(sc
, offset
);
841 njsc32_negotiate_xfer(struct njsc32_softc
*sc
, struct njsc32_target
*target
)
844 /* initial negotiation state */
845 if (target
->t_state
== NJSC32_TARST_INIT
) {
846 #ifdef NJSC32_DUALEDGE
847 if (target
->t_flags
& NJSC32_TARF_DE
)
848 target
->t_state
= NJSC32_TARST_DE
;
851 if (target
->t_flags
& NJSC32_TARF_SYNC
)
852 target
->t_state
= NJSC32_TARST_SDTR
;
854 target
->t_state
= NJSC32_TARST_DONE
;
857 switch (target
->t_state
) {
859 case NJSC32_TARST_INIT
:
861 panic("njsc32_negotiate_xfer");
865 case NJSC32_TARST_DONE
:
869 #ifdef NJSC32_DUALEDGE
870 case NJSC32_TARST_DE
:
871 njsc32_msgout_wdtr(sc
, 0xde /* XXX? */);
874 case NJSC32_TARST_WDTR
:
875 njsc32_msgout_wdtr(sc
, MSG_EXT_WDTR_BUS_8_BIT
);
879 case NJSC32_TARST_SDTR
:
880 njsc32_msgout_sdtr(sc
, sc
->sc_synct
[sc
->sc_sync_max
].sp_period
,
881 NJSC32_SYNCOFFSET_MAX
);
884 case NJSC32_TARST_ASYNC
:
885 njsc32_msgout_sdtr(sc
, NJSC32_SYNCPERIOD_ASYNC
,
886 NJSC32_SYNCOFFSET_ASYNC
);
893 njsc32_led_on(struct njsc32_softc
*sc
)
896 njsc32_ireg_write_1(sc
, NJSC32_IREG_EXT_PORT
, NJSC32_EXTPORT_LED_ON
);
901 njsc32_led_off(struct njsc32_softc
*sc
)
904 njsc32_ireg_write_1(sc
, NJSC32_IREG_EXT_PORT
, NJSC32_EXTPORT_LED_OFF
);
908 njsc32_arbitration_failed(struct njsc32_softc
*sc
)
910 struct njsc32_cmd
*cmd
;
912 if ((cmd
= sc
->sc_curcmd
) == NULL
|| sc
->sc_stat
!= NJSC32_STAT_ARBIT
)
915 if ((cmd
->c_xs
->xs_control
& XS_CTL_POLL
) == 0)
916 callout_stop(&cmd
->c_xs
->xs_callout
);
918 sc
->sc_stat
= NJSC32_STAT_IDLE
;
919 sc
->sc_curcmd
= NULL
;
921 /* the command is no longer active */
922 if (--sc
->sc_nusedcmds
== 0)
927 njsc32_cmd_load(struct njsc32_softc
*sc
, struct njsc32_cmd
*cmd
)
929 struct njsc32_target
*target
;
930 struct scsipi_xfer
*xs
;
933 #ifdef NJSC32_AUTOPARAM
934 struct njsc32_autoparam
*ap
;
938 #ifdef NJSC32_AUTOPARAM
939 ap
= &sc
->sc_cmdpg
->dp_ap
;
941 /* reset CDB pointer */
942 njsc32_write_2(sc
, NJSC32_REG_COMMAND_CONTROL
, NJSC32_CMD_CLEAR_CDB_FIFO_PTR
);
946 TPRINTC(cmd
, ("njsc32_cmd_load: CDB"));
947 for (i
= 0; i
< xs
->cmdlen
; i
++) {
948 #ifdef NJSC32_AUTOPARAM
949 ap
->ap_cdb
[i
].cdb_data
= ((u_int8_t
*)xs
->cmd
)[i
];
951 njsc32_write_1(sc
, NJSC32_REG_COMMAND_DATA
,
952 ((u_int8_t
*)xs
->cmd
)[i
]);
954 TPRINTF((" %02x", ((u_int8_t
*)cmd
->c_xs
->cmd
)[i
]));
956 #ifdef NJSC32_AUTOPARAM /* XXX needed? */
957 for ( ; i
< NJSC32_AUTOPARAM_CDBLEN
; i
++)
958 ap
->ap_cdb
[i
].cdb_data
= 0;
961 control
= xs
->xs_control
;
966 njsc32_init_msgout(sc
);
969 lun
= xs
->xs_periph
->periph_lun
;
970 njsc32_add_msgout(sc
, (control
& XS_CTL_REQSENSE
) ?
971 MSG_IDENTIFY(lun
, 0) : MSG_IDENTIFY(lun
, 1));
973 /* tagged queueing */
974 if (control
& XS_CTL_TAGMASK
) {
975 njsc32_add_msgout(sc
, xs
->xs_tag_type
);
976 njsc32_add_msgout(sc
, xs
->xs_tag_id
);
977 TPRINTF((" (tag %#x %#x)\n", xs
->xs_tag_type
, xs
->xs_tag_id
));
981 target
= cmd
->c_target
;
983 /* transfer negotiation */
984 if (control
& XS_CTL_REQSENSE
)
985 target
->t_state
= NJSC32_TARST_INIT
;
986 njsc32_negotiate_xfer(sc
, target
);
988 msgoutreg
= njsc32_get_auto_msgout(sc
);
990 #ifdef NJSC32_AUTOPARAM
991 ap
->ap_msgout
= htole32(msgoutreg
);
993 ap
->ap_sync
= target
->t_sync
;
994 ap
->ap_ackwidth
= target
->t_ackwidth
;
995 ap
->ap_targetid
= target
->t_targetid
;
996 ap
->ap_sample
= target
->t_sample
;
998 ap
->ap_cmdctl
= htole16(NJSC32_CMD_CLEAR_CDB_FIFO_PTR
|
999 NJSC32_CMD_AUTO_COMMAND_PHASE
|
1000 NJSC32_CMD_AUTO_SCSI_START
| NJSC32_CMD_AUTO_ATN
|
1001 NJSC32_CMD_AUTO_MSGIN_00_04
| NJSC32_CMD_AUTO_MSGIN_02
);
1002 #ifdef NJSC32_DUALEDGE
1003 ap
->ap_xferctl
= htole16(cmd
->c_xferctl
| target
->t_xferctl
);
1005 ap
->ap_xferctl
= htole16(cmd
->c_xferctl
);
1007 ap
->ap_sgtdmaaddr
= htole32(cmd
->c_sgtdmaaddr
);
1009 /* sync njsc32_autoparam */
1010 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap_cmdpg
,
1011 offsetof(struct njsc32_dma_page
, dp_ap
), /* offset */
1012 sizeof(struct njsc32_autoparam
),
1013 BUS_DMASYNC_PREWRITE
);
1015 /* autoparam DMA address */
1016 njsc32_write_4(sc
, NJSC32_REG_SGT_ADR
, sc
->sc_ap_dma
);
1018 /* start command (autoparam) */
1019 njsc32_write_2(sc
, NJSC32_REG_COMMAND_CONTROL
,
1020 NJSC32_CMD_CLEAR_CDB_FIFO_PTR
| NJSC32_CMD_AUTO_PARAMETER
);
1022 #else /* not NJSC32_AUTOPARAM */
1024 njsc32_write_4(sc
, NJSC32_REG_SCSI_MSG_OUT
, msgoutreg
);
1026 /* load parameters */
1027 njsc32_write_1(sc
, NJSC32_REG_TARGET_ID
, target
->t_targetid
);
1028 njsc32_write_1(sc
, NJSC32_REG_SYNC
, target
->t_sync
);
1029 njsc32_write_1(sc
, NJSC32_REG_ACK_WIDTH
, target
->t_ackwidth
);
1030 njsc32_write_1(sc
, NJSC32_REG_SREQ_SAMPLING
, target
->t_sample
);
1031 njsc32_write_4(sc
, NJSC32_REG_SGT_ADR
, cmd
->c_sgtdmaaddr
);
1032 #ifdef NJSC32_DUALEDGE
1033 njsc32_write_2(sc
, NJSC32_REG_TRANSFER
,
1034 cmd
->c_xferctl
| target
->t_xferctl
);
1036 njsc32_write_2(sc
, NJSC32_REG_TRANSFER
, cmd
->c_xferctl
);
1038 /* start AutoSCSI */
1039 njsc32_write_2(sc
, NJSC32_REG_COMMAND_CONTROL
,
1040 NJSC32_CMD_CLEAR_CDB_FIFO_PTR
| NJSC32_CMD_AUTO_COMMAND_PHASE
|
1041 NJSC32_CMD_AUTO_SCSI_START
| NJSC32_CMD_AUTO_ATN
|
1042 NJSC32_CMD_AUTO_MSGIN_00_04
| NJSC32_CMD_AUTO_MSGIN_02
);
1043 #endif /* not NJSC32_AUTOPARAM */
1046 /* Note: must be called at splbio() */
1048 njsc32_start(struct njsc32_softc
*sc
)
1050 struct njsc32_cmd
*cmd
;
1052 /* get a command to issue */
1053 TAILQ_FOREACH(cmd
, &sc
->sc_reqcmd
, c_q
) {
1054 if (cmd
->c_lu
->lu_cmd
== NULL
&&
1055 ((cmd
->c_flags
& NJSC32_CMD_TAGGED
) ||
1056 TAILQ_EMPTY(&cmd
->c_lu
->lu_q
)))
1057 break; /* OK, the logical unit is free */
1060 goto out
; /* no work to do */
1062 /* request will always fail if not in bus free phase */
1063 if (njsc32_read_1(sc
, NJSC32_REG_SCSI_BUS_MONITOR
) !=
1064 NJSC32_BUSMON_BUSFREE
)
1067 /* clear parity error and enable parity detection */
1068 njsc32_write_1(sc
, NJSC32_REG_PARITY_CONTROL
,
1069 NJSC32_PARITYCTL_CHECK_ENABLE
| NJSC32_PARITYCTL_CLEAR_ERROR
);
1071 njsc32_cmd_load(sc
, cmd
);
1073 if (sc
->sc_nusedcmds
++ == 0)
1076 sc
->sc_curcmd
= cmd
;
1077 sc
->sc_stat
= NJSC32_STAT_ARBIT
;
1079 if ((cmd
->c_xs
->xs_control
& XS_CTL_POLL
) == 0) {
1080 callout_reset(&cmd
->c_xs
->xs_callout
,
1081 mstohz(cmd
->c_xs
->timeout
),
1082 njsc32_cmdtimeout
, cmd
);
1087 busy
: /* XXX retry counter */
1088 TPRINTF(("%s: njsc32_start: busy\n", device_xname(sc
->sc_dev
)));
1089 njsc32_write_2(sc
, NJSC32_REG_TIMER
, NJSC32_ARBITRATION_RETRY_TIME
);
1090 out
: njsc32_write_2(sc
, NJSC32_REG_TRANSFER
, 0);
1094 njsc32_run_xfer(struct njsc32_softc
*sc
, struct scsipi_xfer
*xs
)
1096 struct scsipi_periph
*periph
;
1099 struct njsc32_cmd
*cmd
;
1102 periph
= xs
->xs_periph
;
1103 KASSERT((unsigned)periph
->periph_target
<= NJSC32_MAX_TARGET_ID
);
1105 control
= xs
->xs_control
;
1106 lun
= periph
->periph_lun
;
1110 * (scsipi layer knows the number of cmds, so this shall never fail)
1113 cmd
= TAILQ_FIRST(&sc
->sc_freecmd
);
1115 TAILQ_REMOVE(&sc
->sc_freecmd
, cmd
, c_q
);
1121 njsc32_cmd_init(cmd
);
1123 cmd
->c_target
= &sc
->sc_targets
[periph
->periph_target
];
1124 cmd
->c_lu
= &cmd
->c_target
->t_lus
[lun
];
1126 /* tagged queueing */
1127 if (control
& XS_CTL_TAGMASK
) {
1128 cmd
->c_flags
|= NJSC32_CMD_TAGGED
;
1129 if (control
& XS_CTL_HEAD_TAG
)
1130 cmd
->c_flags
|= NJSC32_CMD_TAGGED_HEAD
;
1133 /* map DMA buffer */
1134 cmd
->c_datacnt
= xs
->datalen
;
1136 /* Is XS_CTL_DATA_UIO ever used anywhere? */
1137 KASSERT((control
& XS_CTL_DATA_UIO
) == 0);
1139 error
= bus_dmamap_load(sc
->sc_dmat
, cmd
->c_dmamap_xfer
,
1140 xs
->data
, xs
->datalen
, NULL
,
1141 ((control
& XS_CTL_NOSLEEP
) ?
1142 BUS_DMA_NOWAIT
: BUS_DMA_WAITOK
) |
1144 ((control
& XS_CTL_DATA_IN
) ?
1145 BUS_DMA_READ
: BUS_DMA_WRITE
));
1152 xs
->error
= XS_RESOURCE_SHORTAGE
;
1155 xs
->error
= XS_DRIVER_STUFFUP
;
1157 printf("%s: njsc32_run_xfer: map failed, error %d\n",
1158 device_xname(sc
->sc_dev
), error
);
1159 /* put it back to free command list */
1161 TAILQ_INSERT_HEAD(&sc
->sc_freecmd
, cmd
, c_q
);
1163 /* abort this transfer */
1168 bus_dmamap_sync(sc
->sc_dmat
, cmd
->c_dmamap_xfer
,
1169 0, cmd
->c_dmamap_xfer
->dm_mapsize
,
1170 (control
& XS_CTL_DATA_IN
) ?
1171 BUS_DMASYNC_PREREAD
: BUS_DMASYNC_PREWRITE
);
1173 for (i
= 0; i
< cmd
->c_dmamap_xfer
->dm_nsegs
; i
++) {
1174 cmd
->c_sgt
[i
].sg_addr
=
1175 htole32(cmd
->c_dmamap_xfer
->dm_segs
[i
].ds_addr
);
1176 cmd
->c_sgt
[i
].sg_len
=
1177 htole32(cmd
->c_dmamap_xfer
->dm_segs
[i
].ds_len
);
1180 cmd
->c_sgt
[i
- 1].sg_len
|= htole32(NJSC32_SGT_ENDMARK
);
1182 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap_cmdpg
,
1183 (char *)cmd
->c_sgt
- (char *)sc
->sc_cmdpg
, /* offset */
1185 BUS_DMASYNC_PREWRITE
);
1187 cmd
->c_flags
|= NJSC32_CMD_DMA_MAPPED
;
1189 /* enable transfer */
1191 NJSC32_XFR_TRANSFER_GO
| NJSC32_XFR_BM_START
|
1192 NJSC32_XFR_ALL_COUNT_CLR
;
1194 /* XXX How can we specify the DMA direction? */
1196 #if 0 /* faster write mode? (doesn't work) */
1197 if ((control
& XS_CTL_DATA_IN
) == 0)
1198 cmd
->c_xferctl
|= NJSC32_XFR_ADVANCED_BM_WRITE
;
1201 /* no data transfer */
1207 TAILQ_INSERT_TAIL(&sc
->sc_reqcmd
, cmd
, c_q
);
1209 /* start the controller if idle */
1210 if (sc
->sc_stat
== NJSC32_STAT_IDLE
)
1215 if (control
& XS_CTL_POLL
) {
1216 /* wait for completion */
1217 /* XXX should handle timeout? */
1218 while ((xs
->xs_status
& XS_STS_DONE
) == 0) {
1226 njsc32_end_cmd(struct njsc32_softc
*sc
, struct njsc32_cmd
*cmd
,
1227 scsipi_xfer_result_t result
)
1229 struct scsipi_xfer
*xs
;
1232 struct njsc32_cmd
*c
;
1239 TAILQ_FOREACH(c
, &sc
->sc_freecmd
, c_q
) {
1241 panic("njsc32_end_cmd: already in free list");
1247 if (cmd
->c_flags
& NJSC32_CMD_DMA_MAPPED
) {
1248 if (cmd
->c_datacnt
) {
1249 bus_dmamap_sync(sc
->sc_dmat
, cmd
->c_dmamap_xfer
,
1250 0, cmd
->c_dmamap_xfer
->dm_mapsize
,
1251 (xs
->xs_control
& XS_CTL_DATA_IN
) ?
1252 BUS_DMASYNC_POSTREAD
: BUS_DMASYNC_POSTWRITE
);
1254 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap_cmdpg
,
1255 (char *)cmd
->c_sgt
- (char *)sc
->sc_cmdpg
,
1256 NJSC32_SIZE_SGT
, BUS_DMASYNC_POSTWRITE
);
1259 bus_dmamap_unload(sc
->sc_dmat
, cmd
->c_dmamap_xfer
);
1260 cmd
->c_flags
&= ~NJSC32_CMD_DMA_MAPPED
;
1264 if ((xs
->xs_control
& XS_CTL_POLL
) == 0)
1265 callout_stop(&xs
->xs_callout
);
1267 TAILQ_INSERT_HEAD(&sc
->sc_freecmd
, cmd
, c_q
);
1273 if (--sc
->sc_nusedcmds
== 0)
1278 * request from scsipi layer
1281 njsc32_scsipi_request(struct scsipi_channel
*chan
, scsipi_adapter_req_t req
,
1284 struct njsc32_softc
*sc
;
1285 struct scsipi_xfer_mode
*xm
;
1286 struct njsc32_target
*target
;
1288 sc
= device_private(chan
->chan_adapter
->adapt_dev
);
1291 case ADAPTER_REQ_RUN_XFER
:
1292 njsc32_run_xfer(sc
, arg
);
1295 case ADAPTER_REQ_GROW_RESOURCES
:
1299 case ADAPTER_REQ_SET_XFER_MODE
:
1301 target
= &sc
->sc_targets
[xm
->xm_target
];
1303 target
->t_flags
= 0;
1304 if (xm
->xm_mode
& PERIPH_CAP_TQING
)
1305 target
->t_flags
|= NJSC32_TARF_TAG
;
1306 if (xm
->xm_mode
& PERIPH_CAP_SYNC
) {
1307 target
->t_flags
|= NJSC32_TARF_SYNC
;
1308 #ifdef NJSC32_DUALEDGE
1309 if (sc
->sc_model
& NJSC32_FLAG_DUALEDGE
)
1310 target
->t_flags
|= NJSC32_TARF_DE
;
1313 #ifdef NJSC32_DUALEDGE
1314 target
->t_xferctl
= 0;
1316 target
->t_state
= NJSC32_TARST_INIT
;
1317 njsc32_target_async(sc
, target
);
1326 njsc32_scsipi_minphys(struct buf
*bp
)
1329 if (bp
->b_bcount
> NJSC32_MAX_XFER
)
1330 bp
->b_bcount
= NJSC32_MAX_XFER
;
1335 * On some versions of 32UDE (probably the earlier ones), the controller
1336 * detects continuous bus reset when the termination power is absent.
1337 * Make sure the system won't hang on such situation.
1340 njsc32_wait_reset_release(void *arg
)
1342 struct njsc32_softc
*sc
= arg
;
1343 struct njsc32_cmd
*cmd
;
1345 /* clear pending commands */
1346 while ((cmd
= TAILQ_FIRST(&sc
->sc_reqcmd
)) != NULL
) {
1347 TAILQ_REMOVE(&sc
->sc_reqcmd
, cmd
, c_q
);
1348 njsc32_end_cmd(sc
, cmd
, XS_RESET
);
1351 /* If Bus Reset is not released yet, schedule recheck. */
1352 if (njsc32_read_2(sc
, NJSC32_REG_IRQ
) & NJSC32_IRQ_SCSIRESET
) {
1353 switch (sc
->sc_stat
) {
1354 case NJSC32_STAT_RESET
:
1355 sc
->sc_stat
= NJSC32_STAT_RESET1
;
1357 case NJSC32_STAT_RESET1
:
1358 /* print message if Bus Reset is detected twice */
1359 sc
->sc_stat
= NJSC32_STAT_RESET2
;
1360 printf("%s: detected excessive bus reset "
1361 "--- missing termination power?\n",
1362 device_xname(sc
->sc_dev
));
1367 callout_reset(&sc
->sc_callout
,
1368 hz
* 2 /* poll every 2s */,
1369 njsc32_wait_reset_release
, sc
);
1373 if (sc
->sc_stat
== NJSC32_STAT_RESET2
)
1374 printf("%s: bus reset is released\n", device_xname(sc
->sc_dev
));
1376 /* unblock interrupts */
1377 njsc32_write_2(sc
, NJSC32_REG_IRQ
, 0);
1379 sc
->sc_stat
= NJSC32_STAT_IDLE
;
1383 njsc32_reset_bus(struct njsc32_softc
*sc
)
1387 DPRINTF(("%s: njsc32_reset_bus:\n", device_xname(sc
->sc_dev
)));
1389 /* block interrupts */
1390 njsc32_write_2(sc
, NJSC32_REG_IRQ
, NJSC32_IRQ_MASK_ALL
);
1392 sc
->sc_stat
= NJSC32_STAT_RESET
;
1394 /* hold SCSI bus reset */
1395 njsc32_write_1(sc
, NJSC32_REG_SCSI_BUS_CONTROL
, NJSC32_SBCTL_RST
);
1396 delay(NJSC32_RESET_HOLD_TIME
);
1398 /* clear transfer */
1399 njsc32_clear_cmds(sc
, XS_RESET
);
1401 /* initialize target structure */
1402 njsc32_init_targets(sc
);
1405 scsipi_async_event(&sc
->sc_channel
, ASYNC_EVENT_RESET
, NULL
);
1408 /* release SCSI bus reset */
1409 njsc32_write_1(sc
, NJSC32_REG_SCSI_BUS_CONTROL
, 0);
1411 njsc32_wait_reset_release(sc
);
1415 * clear running/disconnected commands
1418 njsc32_clear_cmds(struct njsc32_softc
*sc
, scsipi_xfer_result_t cmdresult
)
1420 struct njsc32_cmd
*cmd
;
1422 struct njsc32_lu
*lu
;
1424 njsc32_arbitration_failed(sc
);
1426 /* clear current transfer */
1427 if ((cmd
= sc
->sc_curcmd
) != NULL
) {
1428 sc
->sc_curcmd
= NULL
;
1429 njsc32_end_cmd(sc
, cmd
, cmdresult
);
1432 /* clear disconnected transfers */
1433 for (id
= 0; id
<= NJSC32_MAX_TARGET_ID
; id
++) {
1434 for (lun
= 0; lun
< NJSC32_NLU
; lun
++) {
1435 lu
= &sc
->sc_targets
[id
].t_lus
[lun
];
1437 if ((cmd
= lu
->lu_cmd
) != NULL
) {
1439 njsc32_end_cmd(sc
, cmd
, cmdresult
);
1441 while ((cmd
= TAILQ_FIRST(&lu
->lu_q
)) != NULL
) {
1442 TAILQ_REMOVE(&lu
->lu_q
, cmd
, c_q
);
1443 njsc32_end_cmd(sc
, cmd
, cmdresult
);
1450 njsc32_scsipi_ioctl(struct scsipi_channel
*chan
, u_long cmd
,
1451 void *addr
, int flag
, struct proc
*p
)
1453 struct njsc32_softc
*sc
;
1455 sc
= device_private(chan
->chan_adapter
->adapt_dev
);
1469 * set current data pointer
1472 njsc32_set_cur_ptr(struct njsc32_cmd
*cmd
, u_int32_t pos
)
1475 /* new current data pointer */
1476 cmd
->c_dp_cur
= pos
;
1478 /* update number of bytes transferred */
1479 if (pos
> cmd
->c_dp_max
)
1480 cmd
->c_dp_max
= pos
;
1484 * set data pointer for the next transfer
1487 njsc32_set_ptr(struct njsc32_softc
*sc
, struct njsc32_cmd
*cmd
, u_int32_t pos
)
1489 struct njsc32_sgtable
*sg
;
1493 /* set current pointer */
1494 njsc32_set_cur_ptr(cmd
, pos
);
1496 /* undo previous fix if any */
1497 if (cmd
->c_sgfixcnt
!= 0) {
1498 sg
= &cmd
->c_sgt
[cmd
->c_sgoffset
];
1499 sg
->sg_addr
= htole32(le32toh(sg
->sg_addr
) - cmd
->c_sgfixcnt
);
1500 sg
->sg_len
= htole32(le32toh(sg
->sg_len
) + cmd
->c_sgfixcnt
);
1501 cmd
->c_sgfixcnt
= 0;
1504 if (pos
>= cmd
->c_datacnt
) {
1506 #if 1 /*def DIAGNOSTIC*/
1507 if (pos
> cmd
->c_datacnt
)
1508 printf("%s: pos %u too large\n",
1509 device_xname(sc
->sc_dev
), pos
- cmd
->c_datacnt
);
1511 cmd
->c_xferctl
= 0; /* XXX correct? */
1516 for (sgte
= 0, sg
= cmd
->c_sgt
;
1517 sgte
< NJSC32_NUM_SG
&& pos
> 0; sgte
++, sg
++) {
1518 len
= le32toh(sg
->sg_len
) & ~NJSC32_SGT_ENDMARK
;
1520 sg
->sg_addr
= htole32(le32toh(sg
->sg_addr
) + pos
);
1521 sg
->sg_len
= htole32(le32toh(sg
->sg_len
) - pos
);
1522 cmd
->c_sgfixcnt
= pos
;
1527 if (sg
->sg_len
& htole32(NJSC32_SGT_ENDMARK
)) {
1528 panic("njsc32_set_ptr: bad pos");
1533 if (sgte
>= NJSC32_NUM_SG
)
1534 panic("njsc32_set_ptr: bad sg");
1536 if (cmd
->c_sgoffset
!= sgte
) {
1537 cmd
->c_sgoffset
= sgte
;
1538 cmd
->c_sgtdmaaddr
= NJSC32_CMD_DMAADDR_SGT(cmd
, sgte
);
1542 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmamap_cmdpg
,
1543 (char *)cmd
->c_sgt
- (char *)sc
->sc_cmdpg
, /* offset */
1545 BUS_DMASYNC_PREWRITE
);
1552 njsc32_save_ptr(struct njsc32_cmd
*cmd
)
1555 cmd
->c_dp_saved
= cmd
->c_dp_cur
;
1559 njsc32_assert_ack(struct njsc32_softc
*sc
)
1563 reg
= njsc32_read_1(sc
, NJSC32_REG_SCSI_BUS_CONTROL
);
1564 reg
|= NJSC32_SBCTL_ACK
| NJSC32_SBCTL_ACK_ENABLE
;
1566 reg
|= NJSC32_SBCTL_AUTODIRECTION
;
1568 njsc32_write_1(sc
, NJSC32_REG_SCSI_BUS_CONTROL
, reg
);
1572 njsc32_negate_ack(struct njsc32_softc
*sc
)
1576 reg
= njsc32_read_1(sc
, NJSC32_REG_SCSI_BUS_CONTROL
);
1578 reg
|= NJSC32_SBCTL_ACK_ENABLE
;
1579 reg
|= NJSC32_SBCTL_AUTODIRECTION
;
1581 reg
&= ~NJSC32_SBCTL_ACK
;
1582 njsc32_write_1(sc
, NJSC32_REG_SCSI_BUS_CONTROL
, reg
);
1586 njsc32_wait_req_negate(struct njsc32_softc
*sc
)
1590 for (cnt
= 0; cnt
< NJSC32_REQ_TIMEOUT
; cnt
++) {
1591 if ((njsc32_read_1(sc
, NJSC32_REG_SCSI_BUS_MONITOR
) &
1592 NJSC32_BUSMON_REQ
) == 0)
1596 printf("%s: njsc32_wait_req_negate: timed out\n",
1597 device_xname(sc
->sc_dev
));
1601 njsc32_reconnect(struct njsc32_softc
*sc
, struct njsc32_cmd
*cmd
)
1603 struct scsipi_xfer
*xs
;
1606 if ((xs
->xs_control
& XS_CTL_POLL
) == 0) {
1607 callout_stop(&xs
->xs_callout
);
1608 callout_reset(&xs
->xs_callout
,
1609 mstohz(xs
->timeout
),
1610 njsc32_cmdtimeout
, cmd
);
1613 /* Reconnection implies Restore Pointers */
1614 njsc32_set_ptr(sc
, cmd
, cmd
->c_dp_saved
);
1617 static enum njsc32_reselstat
1618 njsc32_resel_identify(struct njsc32_softc
*sc
, int lun
,
1619 struct njsc32_cmd
**pcmd
)
1622 struct njsc32_lu
*plu
;
1623 struct njsc32_cmd
*cmd
;
1625 switch (sc
->sc_stat
) {
1626 case NJSC32_STAT_RESEL
:
1629 case NJSC32_STAT_RESEL_LUN
:
1630 case NJSC32_STAT_RECONNECT
:
1632 * accept and ignore if the LUN is the same as the current one,
1635 return sc
->sc_resellun
== lun
?
1636 NJSC32_RESEL_THROUGH
: NJSC32_RESEL_ERROR
;
1639 printf("%s: njsc32_resel_identify: not in reselection\n",
1640 device_xname(sc
->sc_dev
));
1641 return NJSC32_RESEL_ERROR
;
1644 targetid
= sc
->sc_reselid
;
1645 TPRINTF(("%s: njsc32_resel_identify: reselection lun %d\n",
1646 device_xname(sc
->sc_dev
), lun
));
1648 if (targetid
> NJSC32_MAX_TARGET_ID
|| lun
>= NJSC32_NLU
)
1649 return NJSC32_RESEL_ERROR
;
1651 sc
->sc_resellun
= lun
;
1652 plu
= &sc
->sc_targets
[targetid
].t_lus
[lun
];
1654 if ((cmd
= plu
->lu_cmd
) != NULL
) {
1655 sc
->sc_stat
= NJSC32_STAT_RECONNECT
;
1658 TPRINTC(cmd
, ("njsc32_resel_identify: I_T_L nexus\n"));
1659 njsc32_reconnect(sc
, cmd
);
1660 return NJSC32_RESEL_COMPLETE
;
1661 } else if (!TAILQ_EMPTY(&plu
->lu_q
)) {
1663 sc
->sc_stat
= NJSC32_STAT_RESEL_LUN
;
1664 return NJSC32_RESEL_THROUGH
;
1667 /* no disconnected commands */
1668 return NJSC32_RESEL_ERROR
;
1671 static enum njsc32_reselstat
1672 njsc32_resel_tag(struct njsc32_softc
*sc
, int tag
, struct njsc32_cmd
**pcmd
)
1674 struct njsc32_cmd_head
*head
;
1675 struct njsc32_cmd
*cmd
;
1677 TPRINTF(("%s: njsc32_resel_tag: reselection tag %d\n",
1678 device_xname(sc
->sc_dev
), tag
));
1679 if (sc
->sc_stat
!= NJSC32_STAT_RESEL_LUN
)
1680 return NJSC32_RESEL_ERROR
;
1682 head
= &sc
->sc_targets
[sc
->sc_reselid
].t_lus
[sc
->sc_resellun
].lu_q
;
1685 /* search for the command of the tag */
1686 TAILQ_FOREACH(cmd
, head
, c_q
) {
1687 if (cmd
->c_xs
->xs_tag_id
== tag
) {
1688 sc
->sc_stat
= NJSC32_STAT_RECONNECT
;
1689 TAILQ_REMOVE(head
, cmd
, c_q
);
1691 TPRINTC(cmd
, ("njsc32_resel_tag: I_T_L_Q nexus\n"));
1692 njsc32_reconnect(sc
, cmd
);
1693 return NJSC32_RESEL_COMPLETE
;
1697 /* no disconnected commands */
1698 return NJSC32_RESEL_ERROR
;
1702 * Reload parameters and restart AutoSCSI.
1704 * XXX autoparam doesn't work as expected and we can't use it here.
1707 njsc32_cmd_reload(struct njsc32_softc
*sc
, struct njsc32_cmd
*cmd
, int cctl
)
1709 struct njsc32_target
*target
;
1711 target
= cmd
->c_target
;
1713 /* clear parity error and enable parity detection */
1714 njsc32_write_1(sc
, NJSC32_REG_PARITY_CONTROL
,
1715 NJSC32_PARITYCTL_CHECK_ENABLE
| NJSC32_PARITYCTL_CLEAR_ERROR
);
1717 /* load parameters */
1718 njsc32_write_1(sc
, NJSC32_REG_SYNC
, target
->t_sync
);
1719 njsc32_write_1(sc
, NJSC32_REG_ACK_WIDTH
, target
->t_ackwidth
);
1720 njsc32_write_1(sc
, NJSC32_REG_SREQ_SAMPLING
, target
->t_sample
);
1721 njsc32_write_4(sc
, NJSC32_REG_SGT_ADR
, cmd
->c_sgtdmaaddr
);
1722 #ifdef NJSC32_DUALEDGE
1723 njsc32_write_2(sc
, NJSC32_REG_TRANSFER
,
1724 cmd
->c_xferctl
| target
->t_xferctl
);
1726 njsc32_write_2(sc
, NJSC32_REG_TRANSFER
, cmd
->c_xferctl
);
1728 /* start AutoSCSI */
1729 njsc32_write_2(sc
, NJSC32_REG_COMMAND_CONTROL
, cctl
);
1731 sc
->sc_curcmd
= cmd
;
1735 njsc32_update_xfer_mode(struct njsc32_softc
*sc
, struct njsc32_target
*target
)
1737 struct scsipi_xfer_mode xm
;
1739 xm
.xm_target
= target
- sc
->sc_targets
; /* target ID */
1741 xm
.xm_period
= target
->t_syncperiod
;
1742 xm
.xm_offset
= target
->t_syncoffset
;
1743 if (xm
.xm_offset
!= 0)
1744 xm
.xm_mode
|= PERIPH_CAP_SYNC
;
1745 if (target
->t_flags
& NJSC32_TARF_TAG
)
1746 xm
.xm_mode
|= PERIPH_CAP_TQING
;
1748 scsipi_async_event(&sc
->sc_channel
, ASYNC_EVENT_XFER_MODE
, &xm
);
1752 njsc32_msgin(struct njsc32_softc
*sc
)
1756 struct njsc32_cmd
*cmd
;
1757 enum njsc32_reselstat rstat
;
1759 u_int32_t ptr
; /* unsigned type ensures 2-complement calculation */
1760 u_int32_t msgout
= 0;
1761 bool reload_params
= FALSE
;
1762 struct njsc32_target
*target
;
1763 int idx
, period
, offset
;
1766 * we are in Message In, so the previous Message Out should have
1769 njsc32_init_msgout(sc
);
1771 /* get a byte of Message In */
1772 msg
= njsc32_read_1(sc
, NJSC32_REG_DATA_IN
);
1773 TPRINTF(("%s: njsc32_msgin: got %#x\n", device_xname(sc
->sc_dev
), msg
));
1774 if ((msgcnt
= sc
->sc_msgincnt
) < NJSC32_MSGIN_LEN
)
1775 sc
->sc_msginbuf
[sc
->sc_msgincnt
] = msg
;
1777 njsc32_assert_ack(sc
);
1779 msg0
= sc
->sc_msginbuf
[0];
1780 cmd
= sc
->sc_curcmd
;
1782 /* check for parity error */
1783 if (njsc32_read_1(sc
, NJSC32_REG_PARITY_STATUS
) &
1784 NJSC32_PARITYSTATUS_ERROR_LSB
) {
1786 printf("%s: msgin: parity error\n", device_xname(sc
->sc_dev
));
1788 /* clear parity error */
1789 njsc32_write_1(sc
, NJSC32_REG_PARITY_CONTROL
,
1790 NJSC32_PARITYCTL_CHECK_ENABLE
|
1791 NJSC32_PARITYCTL_CLEAR_ERROR
);
1793 /* respond as Message Parity Error */
1794 njsc32_add_msgout(sc
, MSG_PARITY_ERROR
);
1796 /* clear Message In */
1797 sc
->sc_msgincnt
= 0;
1801 #define WAITNEXTMSG do { sc->sc_msgincnt++; goto restart; } while (0)
1802 #define MSGCOMPLETE do { sc->sc_msgincnt = 0; goto restart; } while (0)
1803 if (MSG_ISIDENTIFY(msg0
)) {
1805 * Got Identify message from target.
1807 if ((msg0
& ~MSG_IDENTIFY_LUNMASK
) != MSG_IDENTIFYFLAG
||
1808 (rstat
= njsc32_resel_identify(sc
, msg0
&
1809 MSG_IDENTIFY_LUNMASK
, &cmd
)) == NJSC32_RESEL_ERROR
) {
1811 * invalid Identify -> Reject
1815 if (rstat
== NJSC32_RESEL_COMPLETE
)
1816 reload_params
= TRUE
;
1820 if (msg0
== MSG_SIMPLE_Q_TAG
) {
1824 /* got whole message */
1825 sc
->sc_msgincnt
= 0;
1827 if ((rstat
= njsc32_resel_tag(sc
, sc
->sc_msginbuf
[1], &cmd
))
1828 == NJSC32_RESEL_ERROR
) {
1830 * invalid Simple Queue Tag -> Abort Tag
1832 printf("%s: msgin: invalid tag\n",
1833 device_xname(sc
->sc_dev
));
1834 njsc32_add_msgout(sc
, MSG_ABORT_TAG
);
1837 if (rstat
== NJSC32_RESEL_COMPLETE
)
1838 reload_params
= TRUE
;
1842 /* I_T_L or I_T_L_Q nexus should be established now */
1844 printf("%s: msgin %#x without nexus -- sending abort\n",
1845 device_xname(sc
->sc_dev
), msg0
);
1846 njsc32_add_msgout(sc
, MSG_ABORT
);
1852 * 0x01 <length (0 stands for 256)> <length bytes>
1853 * (<code> [<parameter> ...])
1856 #define EXTCODEOFF 2
1857 if (msg0
== MSG_EXTENDED
) {
1858 if (msgcnt
< EXTLENOFF
||
1859 msgcnt
< EXTLENOFF
+ 1 +
1860 (u_int8_t
)(sc
->sc_msginbuf
[EXTLENOFF
] - 1))
1863 /* got whole message */
1864 sc
->sc_msgincnt
= 0;
1866 switch (sc
->sc_msginbuf
[EXTCODEOFF
]) {
1867 case 0: /* Modify Data Pointer */
1868 if (msgcnt
!= 5 + EXTCODEOFF
- 1)
1871 * parameter is 32bit big-endian signed (2-complement)
1874 ptr
= (sc
->sc_msginbuf
[EXTCODEOFF
+ 1] << 24) |
1875 (sc
->sc_msginbuf
[EXTCODEOFF
+ 2] << 16) |
1876 (sc
->sc_msginbuf
[EXTCODEOFF
+ 3] << 8) |
1877 sc
->sc_msginbuf
[EXTCODEOFF
+ 4];
1880 ptr
+= cmd
->c_dp_cur
; /* ignore overflow */
1882 /* reject if ptr is not in data buffer */
1883 if (ptr
> cmd
->c_datacnt
)
1886 njsc32_set_ptr(sc
, cmd
, ptr
);
1889 case MSG_EXT_SDTR
: /* Synchronous Data Transfer Request */
1890 DPRINTC(cmd
, ("SDTR %#x %#x\n",
1891 sc
->sc_msginbuf
[EXTCODEOFF
+ 1],
1892 sc
->sc_msginbuf
[EXTCODEOFF
+ 2]));
1893 if (msgcnt
!= MSG_EXT_SDTR_LEN
+ EXTCODEOFF
-1)
1896 target
= cmd
->c_target
;
1898 /* lookup sync period parameters */
1899 period
= sc
->sc_msginbuf
[EXTCODEOFF
+ 1];
1900 for (idx
= sc
->sc_sync_max
; idx
< NJSC32_NSYNCT
; idx
++)
1901 if (sc
->sc_synct
[idx
].sp_period
>= period
) {
1902 period
= sc
->sc_synct
[idx
].sp_period
;
1905 if (idx
>= NJSC32_NSYNCT
) {
1907 * We can't meet the timing condition that
1908 * the target requests -- use async.
1910 njsc32_target_async(sc
, target
);
1911 njsc32_update_xfer_mode(sc
, target
);
1912 if (target
->t_state
== NJSC32_TARST_SDTR
) {
1914 * We started SDTR exchange -- start
1915 * negotiation again and request async.
1917 target
->t_state
= NJSC32_TARST_ASYNC
;
1918 njsc32_negotiate_xfer(sc
, target
);
1922 * The target started SDTR exchange
1923 * -- just reject and fallback
1930 /* check sync offset */
1931 offset
= sc
->sc_msginbuf
[EXTCODEOFF
+ 2];
1932 if (offset
> NJSC32_SYNCOFFSET_MAX
) {
1933 if (target
->t_state
== NJSC32_TARST_SDTR
) {
1934 printf("%s: wrong sync offset: %d\n",
1935 device_xname(sc
->sc_dev
), offset
);
1936 /* XXX what to do? */
1938 offset
= NJSC32_SYNCOFFSET_MAX
;
1941 target
->t_ackwidth
= sc
->sc_synct
[idx
].sp_ackw
;
1942 target
->t_sample
= sc
->sc_synct
[idx
].sp_sample
;
1943 target
->t_syncperiod
= period
;
1944 target
->t_syncoffset
= offset
;
1945 target
->t_sync
= NJSC32_SYNC_VAL(idx
, offset
);
1946 njsc32_update_xfer_mode(sc
, target
);
1948 if (target
->t_state
== NJSC32_TARST_SDTR
) {
1949 target
->t_state
= NJSC32_TARST_DONE
;
1951 njsc32_msgout_sdtr(sc
, period
, offset
);
1956 case MSG_EXT_WDTR
: /* Wide Data Transfer Request */
1958 ("WDTR %#x\n", sc
->sc_msginbuf
[EXTCODEOFF
+ 1]));
1959 #ifdef NJSC32_DUALEDGE
1960 if (msgcnt
!= MSG_EXT_WDTR_LEN
+ EXTCODEOFF
-1)
1964 * T->I of this message is not used for
1965 * DualEdge negotiation, so the device
1966 * must not be a DualEdge device.
1970 target
= cmd
->c_target
;
1971 target
->t_xferctl
= 0;
1973 switch (target
->t_state
) {
1974 case NJSC32_TARST_DE
:
1975 if (sc
->sc_msginbuf
[EXTCODEOFF
+ 1] !=
1976 MSG_EXT_WDTR_BUS_8_BIT
) {
1978 * Oops, we got unexpected WDTR.
1979 * Negotiate for 8bit.
1981 target
->t_state
= NJSC32_TARST_WDTR
;
1983 target
->t_state
= NJSC32_TARST_SDTR
;
1985 njsc32_negotiate_xfer(sc
, target
);
1988 case NJSC32_TARST_WDTR
:
1989 if (sc
->sc_msginbuf
[EXTCODEOFF
+ 1] !=
1990 MSG_EXT_WDTR_BUS_8_BIT
) {
1991 printf("%s: unexpected transfer width:"
1992 " %#x\n", device_xname(sc
->sc_dev
),
1993 sc
->sc_msginbuf
[EXTCODEOFF
+ 1]);
1994 /* XXX what to do? */
1996 target
->t_state
= NJSC32_TARST_SDTR
;
1997 njsc32_negotiate_xfer(sc
, target
);
2001 /* the target started WDTR exchange */
2002 DPRINTC(cmd
, ("WDTR from target\n"));
2004 target
->t_state
= NJSC32_TARST_SDTR
;
2005 njsc32_target_async(sc
, target
);
2007 break; /* reject the WDTR (8bit transfer) */
2009 #endif /* NJSC32_DUALEDGE */
2012 DPRINTC(cmd
, ("njsc32_msgin: reject ext msg %#x msgincnt %d\n",
2013 sc
->sc_msginbuf
[EXTCODEOFF
], msgcnt
));
2017 /* 2byte messages */
2018 if (MSG_IS2BYTE(msg0
)) {
2022 /* got whole message */
2023 sc
->sc_msgincnt
= 0;
2027 case MSG_CMDCOMPLETE
: /* 0x00 */
2028 case MSG_SAVEDATAPOINTER
: /* 0x02 */
2029 case MSG_DISCONNECT
: /* 0x04 */
2030 /* handled by AutoSCSI */
2031 PRINTC(cmd
, ("msgin: unexpected msg: %#x\n", msg0
));
2034 case MSG_RESTOREPOINTERS
: /* 0x03 */
2035 /* restore data pointer to what was saved */
2036 DPRINTC(cmd
, ("njsc32_msgin: Restore Pointers\n"));
2037 njsc32_set_ptr(sc
, cmd
, cmd
->c_dp_saved
);
2038 reload_params
= TRUE
;
2043 #if 0 /* handled above */
2044 case MSG_EXTENDED
: /* 0x01 */
2046 case MSG_MESSAGE_REJECT
: /* 0x07 */
2047 target
= cmd
->c_target
;
2048 DPRINTC(cmd
, ("Reject tarst %d\n", target
->t_state
));
2049 switch (target
->t_state
) {
2050 #ifdef NJSC32_DUALEDGE
2051 case NJSC32_TARST_WDTR
:
2052 case NJSC32_TARST_DE
:
2053 target
->t_xferctl
= 0;
2054 target
->t_state
= NJSC32_TARST_SDTR
;
2055 njsc32_negotiate_xfer(sc
, target
);
2058 case NJSC32_TARST_SDTR
:
2059 case NJSC32_TARST_ASYNC
:
2060 njsc32_target_async(sc
, target
);
2061 target
->t_state
= NJSC32_TARST_DONE
;
2062 njsc32_update_xfer_mode(sc
, target
);
2069 case MSG_NOOP
: /* 0x08 */
2070 #ifdef NJSC32_DUALEDGE
2071 target
= cmd
->c_target
;
2072 if (target
->t_state
== NJSC32_TARST_DE
) {
2073 printf("%s: DualEdge transfer\n",
2074 device_xname(sc
->sc_dev
));
2075 target
->t_xferctl
= NJSC32_XFR_DUALEDGE_ENABLE
;
2076 /* go to next negotiation */
2077 target
->t_state
= NJSC32_TARST_SDTR
;
2078 njsc32_negotiate_xfer(sc
, target
);
2084 case MSG_INITIATOR_DET_ERR
: /* 0x05 I->T only */
2085 case MSG_ABORT
: /* 0x06 I->T only */
2086 case MSG_PARITY_ERROR
: /* 0x09 I->T only */
2087 case MSG_LINK_CMD_COMPLETE
: /* 0x0a */
2088 case MSG_LINK_CMD_COMPLETEF
: /* 0x0b */
2089 case MSG_BUS_DEV_RESET
: /* 0x0c I->T only */
2090 case MSG_ABORT_TAG
: /* 0x0d I->T only */
2091 case MSG_CLEAR_QUEUE
: /* 0x0e I->T only */
2093 #if 0 /* handled above */
2094 case MSG_SIMPLE_Q_TAG
: /* 0x20 */
2096 case MSG_HEAD_OF_Q_TAG
: /* 0x21 I->T only */
2097 case MSG_ORDERED_Q_TAG
: /* 0x22 I->T only */
2098 case MSG_IGN_WIDE_RESIDUE
: /* 0x23 */
2102 PRINTC(cmd
, ("msgin: unsupported msg: %#x", msg0
));
2103 if (MSG_IS2BYTE(msg0
))
2104 printf(" %#x", msg
);
2111 njsc32_add_msgout(sc
, MSG_MESSAGE_REJECT
);
2114 msgout
= njsc32_get_auto_msgout(sc
);
2117 cctl
= NJSC32_CMD_CLEAR_CDB_FIFO_PTR
|
2118 NJSC32_CMD_AUTO_COMMAND_PHASE
|
2119 NJSC32_CMD_AUTO_SCSI_RESTART
;
2122 * Be careful the second and latter bytes of Message In
2123 * shall not be absorbed by AutoSCSI.
2125 if (sc
->sc_msgincnt
== 0)
2126 cctl
|= NJSC32_CMD_AUTO_MSGIN_00_04
| NJSC32_CMD_AUTO_MSGIN_02
;
2128 if (sc
->sc_msgoutlen
!= 0)
2129 cctl
|= NJSC32_CMD_AUTO_ATN
;
2131 njsc32_write_4(sc
, NJSC32_REG_SCSI_MSG_OUT
, msgout
);
2133 /* (re)start AutoSCSI (may assert ATN) */
2134 if (reload_params
) {
2135 njsc32_cmd_reload(sc
, cmd
, cctl
);
2137 njsc32_write_2(sc
, NJSC32_REG_COMMAND_CONTROL
, cctl
);
2140 /* +ATN -> -REQ: need 90ns delay? */
2142 njsc32_wait_req_negate(sc
); /* wait for REQ negation */
2144 njsc32_negate_ack(sc
);
2150 njsc32_msgout(struct njsc32_softc
*sc
)
2156 if (sc
->sc_msgoutlen
== 0) {
2157 /* target entered to Message Out on unexpected timing */
2158 njsc32_add_msgout(sc
, MSG_NOOP
);
2161 cctl
= NJSC32_CMD_CLEAR_CDB_FIFO_PTR
|
2162 NJSC32_CMD_AUTO_COMMAND_PHASE
| NJSC32_CMD_AUTO_SCSI_RESTART
|
2163 NJSC32_CMD_AUTO_MSGIN_00_04
| NJSC32_CMD_AUTO_MSGIN_02
;
2165 /* make sure target is in Message Out phase */
2166 bus
= njsc32_read_1(sc
, NJSC32_REG_SCSI_BUS_MONITOR
);
2167 if ((bus
& NJSC32_BUSMON_PHASE_MASK
) != NJSC32_PHASE_MESSAGE_OUT
) {
2169 * Message Out is aborted by target.
2171 printf("%s: njsc32_msgout: phase change %#x\n",
2172 device_xname(sc
->sc_dev
), bus
);
2174 /* XXX what to do? */
2176 /* restart AutoSCSI (negate ATN) */
2177 njsc32_write_2(sc
, NJSC32_REG_COMMAND_CONTROL
, cctl
);
2179 sc
->sc_msgoutidx
= 0;
2183 n
= sc
->sc_msgoutidx
;
2184 if (n
== sc
->sc_msgoutlen
- 1) {
2186 * negate ATN before sending ACK
2188 njsc32_write_2(sc
, NJSC32_REG_COMMAND_CONTROL
, 0);
2190 sc
->sc_msgoutidx
= 0; /* target may retry Message Out */
2192 cctl
|= NJSC32_CMD_AUTO_ATN
;
2196 /* Send Message Out */
2197 njsc32_write_1(sc
, NJSC32_REG_SCSI_OUT_LATCH
, sc
->sc_msgout
[n
]);
2199 /* DBn -> +ACK: need 55ns delay? */
2201 njsc32_assert_ack(sc
);
2202 njsc32_wait_req_negate(sc
); /* wait for REQ negation */
2204 /* restart AutoSCSI */
2205 njsc32_write_2(sc
, NJSC32_REG_COMMAND_CONTROL
, cctl
);
2207 njsc32_negate_ack(sc
);
2210 * do not reset sc->sc_msgoutlen so the target
2211 * can retry Message Out phase
2216 njsc32_cmdtimeout(void *arg
)
2218 struct njsc32_cmd
*cmd
= arg
;
2219 struct njsc32_softc
*sc
;
2222 PRINTC(cmd
, ("command timeout\n"));
2228 if (sc
->sc_stat
== NJSC32_STAT_ARBIT
)
2229 njsc32_arbitration_failed(sc
);
2231 sc
->sc_curcmd
= NULL
;
2232 sc
->sc_stat
= NJSC32_STAT_IDLE
;
2233 njsc32_end_cmd(sc
, cmd
, XS_TIMEOUT
);
2237 njsc32_init(sc
, 1); /* bus reset */
2243 njsc32_reseltimeout(void *arg
)
2245 struct njsc32_cmd
*cmd
= arg
;
2246 struct njsc32_softc
*sc
;
2249 PRINTC(cmd
, ("reselection timeout\n"));
2255 /* remove from disconnected list */
2256 if (cmd
->c_flags
& NJSC32_CMD_TAGGED
) {
2258 KASSERT(cmd
->c_lu
->lu_cmd
== NULL
);
2259 TAILQ_REMOVE(&cmd
->c_lu
->lu_q
, cmd
, c_q
);
2262 KASSERT(cmd
->c_lu
->lu_cmd
== cmd
);
2263 cmd
->c_lu
->lu_cmd
= NULL
;
2266 njsc32_end_cmd(sc
, cmd
, XS_TIMEOUT
);
2269 njsc32_init(sc
, 1); /* bus reset */
2275 njsc32_end_auto(struct njsc32_softc
*sc
, struct njsc32_cmd
*cmd
, int auto_phase
)
2277 struct scsipi_xfer
*xs
;
2279 if (auto_phase
& NJSC32_XPHASE_MSGIN_02
) {
2280 /* Message In: 0x02 Save Data Pointer */
2283 * Adjust saved data pointer
2284 * if the command is not completed yet.
2286 if ((auto_phase
& NJSC32_XPHASE_MSGIN_00
) == 0 &&
2288 (NJSC32_XPHASE_DATA_IN
| NJSC32_XPHASE_DATA_OUT
)) != 0) {
2289 njsc32_save_ptr(cmd
);
2291 TPRINTF(("BM %u, SGT %u, SACK %u, SAVED_ACK %u\n",
2292 njsc32_read_4(sc
, NJSC32_REG_BM_CNT
),
2293 njsc32_read_4(sc
, NJSC32_REG_SGT_ADR
),
2294 njsc32_read_4(sc
, NJSC32_REG_SACK_CNT
),
2295 njsc32_read_4(sc
, NJSC32_REG_SAVED_ACK_CNT
)));
2300 if (auto_phase
& NJSC32_XPHASE_MSGIN_00
) {
2301 /* Command Complete */
2302 TPRINTC(cmd
, ("njsc32_intr: Command Complete\n"));
2303 switch (xs
->status
) {
2304 case SCSI_CHECK
: case SCSI_QUEUE_FULL
: case SCSI_BUSY
:
2306 * scsipi layer will automatically handle the error
2308 njsc32_end_cmd(sc
, cmd
, XS_BUSY
);
2311 xs
->resid
-= cmd
->c_dp_max
;
2312 njsc32_end_cmd(sc
, cmd
, XS_NOERROR
);
2315 } else if (auto_phase
& NJSC32_XPHASE_MSGIN_04
) {
2317 TPRINTC(cmd
, ("njsc32_intr: Disconnect\n"));
2319 /* for ill-designed devices */
2320 if ((xs
->xs_periph
->periph_quirks
& PQUIRK_AUTOSAVE
) != 0)
2321 njsc32_save_ptr(cmd
);
2324 * move current cmd to disconnected list
2326 if (cmd
->c_flags
& NJSC32_CMD_TAGGED
) {
2328 if (cmd
->c_flags
& NJSC32_CMD_TAGGED_HEAD
)
2329 TAILQ_INSERT_HEAD(&cmd
->c_lu
->lu_q
, cmd
, c_q
);
2331 TAILQ_INSERT_TAIL(&cmd
->c_lu
->lu_q
, cmd
, c_q
);
2334 cmd
->c_lu
->lu_cmd
= cmd
;
2338 * schedule timeout -- avoid being
2339 * disconnected forever
2341 if ((xs
->xs_control
& XS_CTL_POLL
) == 0) {
2342 callout_stop(&xs
->xs_callout
);
2343 callout_reset(&xs
->xs_callout
, mstohz(xs
->timeout
),
2344 njsc32_reseltimeout
, cmd
);
2349 * target has come to Bus Free phase
2350 * probably to notify an error
2352 PRINTC(cmd
, ("njsc32_intr: unexpected bus free\n"));
2353 /* try Request Sense */
2354 xs
->status
= SCSI_CHECK
;
2355 njsc32_end_cmd(sc
, cmd
, XS_BUSY
);
2360 njsc32_intr(void *arg
)
2362 struct njsc32_softc
*sc
= arg
;
2364 u_int8_t arbstat
, bus_phase
;
2367 struct njsc32_cmd
*cmd
;
2369 intr
= njsc32_read_2(sc
, NJSC32_REG_IRQ
);
2370 if ((intr
& NJSC32_IRQ_INTR_PENDING
) == 0)
2371 return 0; /* not mine */
2373 TPRINTF(("%s: njsc32_intr: %#x\n", device_xname(sc
->sc_dev
), intr
));
2375 #if 0 /* I don't think this is required */
2376 /* mask interrupts */
2377 njsc32_write_2(sc
, NJSC32_REG_IRQ
, NJSC32_IRQ_MASK_ALL
);
2380 /* we got an interrupt, so stop the timer */
2381 njsc32_write_2(sc
, NJSC32_REG_TIMER
, NJSC32_TIMER_STOP
);
2383 if (intr
& NJSC32_IRQ_SCSIRESET
) {
2384 printf("%s: detected bus reset\n", device_xname(sc
->sc_dev
));
2385 /* make sure all devices on the bus are certainly reset */
2386 njsc32_reset_bus(sc
);
2390 if (sc
->sc_stat
== NJSC32_STAT_ARBIT
) {
2391 cmd
= sc
->sc_curcmd
;
2393 arbstat
= njsc32_read_1(sc
, NJSC32_REG_ARBITRATION_STAT
);
2394 if (arbstat
& (NJSC32_ARBSTAT_WIN
| NJSC32_ARBSTAT_FAIL
)) {
2398 /* clear arbitration status */
2399 njsc32_write_1(sc
, NJSC32_REG_SET_ARBITRATION
,
2400 NJSC32_SETARB_CLEAR
);
2402 if (arbstat
& NJSC32_ARBSTAT_WIN
) {
2404 ("njsc32_intr: arbitration won\n"));
2406 TAILQ_REMOVE(&sc
->sc_reqcmd
, cmd
, c_q
);
2408 sc
->sc_stat
= NJSC32_STAT_CONNECT
;
2411 ("njsc32_intr: arbitration failed\n"));
2413 njsc32_arbitration_failed(sc
);
2416 /* XXX retry counter */
2421 if (intr
& NJSC32_IRQ_TIMER
) {
2422 TPRINTF(("%s: njsc32_intr: timer interrupt\n",
2423 device_xname(sc
->sc_dev
)));
2426 if (intr
& NJSC32_IRQ_RESELECT
) {
2427 /* Reselection from a target */
2428 njsc32_arbitration_failed(sc
); /* just in case */
2429 if ((cmd
= sc
->sc_curcmd
) != NULL
) {
2431 printf("%s: unexpected reselection\n",
2432 device_xname(sc
->sc_dev
));
2433 sc
->sc_curcmd
= NULL
;
2434 sc
->sc_stat
= NJSC32_STAT_IDLE
;
2435 njsc32_end_cmd(sc
, cmd
, XS_DRIVER_STUFFUP
);
2438 idbit
= njsc32_read_1(sc
, NJSC32_REG_RESELECT_ID
);
2439 if ((idbit
& (1 << NJSC32_INITIATOR_ID
)) == 0 ||
2441 ffs(idbit
& ~(1 << NJSC32_INITIATOR_ID
)) - 1) < 0) {
2442 printf("%s: invalid reselection (id: %#x)\n",
2443 device_xname(sc
->sc_dev
), idbit
);
2444 sc
->sc_stat
= NJSC32_STAT_IDLE
; /* XXX ? */
2446 sc
->sc_stat
= NJSC32_STAT_RESEL
;
2447 TPRINTF(("%s: njsc32_intr: reselection from %d\n",
2448 device_xname(sc
->sc_dev
), sc
->sc_reselid
));
2452 if (intr
& NJSC32_IRQ_PHASE_CHANGE
) {
2453 #if 1 /* XXX probably not needed */
2454 if (sc
->sc_stat
== NJSC32_STAT_ARBIT
)
2455 PRINTC(sc
->sc_curcmd
,
2456 ("njsc32_intr: cancel arbitration phase\n"));
2457 njsc32_arbitration_failed(sc
);
2459 /* current bus phase */
2460 bus_phase
= njsc32_read_1(sc
, NJSC32_REG_SCSI_BUS_MONITOR
) &
2461 NJSC32_BUSMON_PHASE_MASK
;
2463 switch (bus_phase
) {
2464 case NJSC32_PHASE_MESSAGE_IN
:
2469 * target may suddenly become Status / Bus Free phase
2470 * to notify an error condition
2472 case NJSC32_PHASE_STATUS
:
2473 printf("%s: unexpected bus phase: Status\n",
2474 device_xname(sc
->sc_dev
));
2475 if ((cmd
= sc
->sc_curcmd
) != NULL
) {
2477 njsc32_read_1(sc
, NJSC32_REG_SCSI_CSB_IN
);
2478 TPRINTC(cmd
, ("njsc32_intr: Status %d\n",
2479 cmd
->c_xs
->status
));
2482 case NJSC32_PHASE_BUSFREE
:
2483 printf("%s: unexpected bus phase: Bus Free\n",
2484 device_xname(sc
->sc_dev
));
2485 if ((cmd
= sc
->sc_curcmd
) != NULL
) {
2486 sc
->sc_curcmd
= NULL
;
2487 sc
->sc_stat
= NJSC32_STAT_IDLE
;
2488 if (cmd
->c_xs
->status
!= SCSI_QUEUE_FULL
&&
2489 cmd
->c_xs
->status
!= SCSI_BUSY
)
2490 cmd
->c_xs
->status
= SCSI_CHECK
;/* XXX */
2491 njsc32_end_cmd(sc
, cmd
, XS_BUSY
);
2496 printf("%s: unexpected bus phase: ",
2497 device_xname(sc
->sc_dev
));
2498 switch (bus_phase
) {
2499 case NJSC32_PHASE_COMMAND
:
2500 printf("Command\n");
2502 case NJSC32_PHASE_MESSAGE_OUT
:
2503 printf("Message Out\n");
2505 case NJSC32_PHASE_DATA_IN
:
2506 printf("Data In\n");
2508 case NJSC32_PHASE_DATA_OUT
:
2509 printf("Data Out\n");
2511 case NJSC32_PHASE_RESELECT
:
2512 printf("Reselect\n");
2515 printf("%#x\n", bus_phase
);
2519 printf("%s: unexpected bus phase: %#x",
2520 device_xname(sc
->sc_dev
), bus_phase
);
2526 if (intr
& NJSC32_IRQ_AUTOSCSI
) {
2528 * AutoSCSI interrupt
2530 auto_phase
= njsc32_read_2(sc
, NJSC32_REG_EXECUTE_PHASE
);
2531 TPRINTF(("%s: njsc32_intr: AutoSCSI: %#x\n",
2532 device_xname(sc
->sc_dev
), auto_phase
));
2533 njsc32_write_2(sc
, NJSC32_REG_EXECUTE_PHASE
, 0);
2535 if (auto_phase
& NJSC32_XPHASE_SEL_TIMEOUT
) {
2536 cmd
= sc
->sc_curcmd
;
2538 printf("%s: sel no cmd\n",
2539 device_xname(sc
->sc_dev
));
2542 DPRINTC(cmd
, ("njsc32_intr: selection timeout\n"));
2544 sc
->sc_curcmd
= NULL
;
2545 sc
->sc_stat
= NJSC32_STAT_IDLE
;
2546 njsc32_end_cmd(sc
, cmd
, XS_SELTIMEOUT
);
2552 if (auto_phase
& NJSC32_XPHASE_COMMAND
) {
2553 /* Command phase has been automatically processed */
2554 TPRINTF(("%s: njsc32_intr: Command\n",
2555 device_xname(sc
->sc_dev
)));
2559 if (auto_phase
& NJSC32_XPHASE_ILLEGAL
) {
2560 printf("%s: njsc32_intr: Illegal phase\n",
2561 device_xname(sc
->sc_dev
));
2565 if (auto_phase
& NJSC32_XPHASE_PAUSED_MSG_IN
) {
2566 TPRINTF(("%s: njsc32_intr: Process Message In\n",
2567 device_xname(sc
->sc_dev
)));
2571 if (auto_phase
& NJSC32_XPHASE_PAUSED_MSG_OUT
) {
2572 TPRINTF(("%s: njsc32_intr: Process Message Out\n",
2573 device_xname(sc
->sc_dev
)));
2577 cmd
= sc
->sc_curcmd
;
2579 TPRINTF(("%s: njsc32_intr: no cmd\n",
2580 device_xname(sc
->sc_dev
)));
2585 (NJSC32_XPHASE_DATA_IN
| NJSC32_XPHASE_DATA_OUT
)) {
2586 u_int32_t sackcnt
, cntoffset
;
2589 if (auto_phase
& NJSC32_XPHASE_DATA_IN
)
2590 PRINTC(cmd
, ("njsc32_intr: data in done\n"));
2591 if (auto_phase
& NJSC32_XPHASE_DATA_OUT
)
2592 PRINTC(cmd
, ("njsc32_intr: data out done\n"));
2593 printf("BM %u, SGT %u, SACK %u, SAVED_ACK %u\n",
2594 njsc32_read_4(sc
, NJSC32_REG_BM_CNT
),
2595 njsc32_read_4(sc
, NJSC32_REG_SGT_ADR
),
2596 njsc32_read_4(sc
, NJSC32_REG_SACK_CNT
),
2597 njsc32_read_4(sc
, NJSC32_REG_SAVED_ACK_CNT
));
2601 * detected parity error on data transfer?
2603 if (njsc32_read_1(sc
, NJSC32_REG_PARITY_STATUS
) &
2604 (NJSC32_PARITYSTATUS_ERROR_LSB
|
2605 NJSC32_PARITYSTATUS_ERROR_MSB
)) {
2607 PRINTC(cmd
, ("datain: parity error\n"));
2609 /* clear parity error */
2610 njsc32_write_1(sc
, NJSC32_REG_PARITY_CONTROL
,
2611 NJSC32_PARITYCTL_CHECK_ENABLE
|
2612 NJSC32_PARITYCTL_CLEAR_ERROR
);
2614 if (auto_phase
& NJSC32_XPHASE_BUS_FREE
) {
2616 * XXX command has already finished
2617 * -- what can we do?
2619 * It is not clear current command
2620 * caused the error -- reset everything.
2622 njsc32_init(sc
, 1); /* XXX */
2624 /* XXX does this case occur? */
2626 printf("%s: datain: parity error\n",
2627 device_xname(sc
->sc_dev
));
2630 * Make attention condition and try
2631 * to send Initiator Detected Error
2634 njsc32_init_msgout(sc
);
2635 njsc32_add_msgout(sc
,
2636 MSG_INITIATOR_DET_ERR
);
2638 NJSC32_REG_SCSI_MSG_OUT
,
2639 njsc32_get_auto_msgout(sc
));
2640 /* restart autoscsi with ATN */
2642 NJSC32_REG_COMMAND_CONTROL
,
2643 NJSC32_CMD_CLEAR_CDB_FIFO_PTR
|
2644 NJSC32_CMD_AUTO_COMMAND_PHASE
|
2645 NJSC32_CMD_AUTO_SCSI_RESTART
|
2646 NJSC32_CMD_AUTO_MSGIN_00_04
|
2647 NJSC32_CMD_AUTO_MSGIN_02
|
2648 NJSC32_CMD_AUTO_ATN
);
2654 * data has been transferred, and current pointer
2657 sackcnt
= njsc32_read_4(sc
, NJSC32_REG_SACK_CNT
);
2660 * The controller returns extra ACK count
2661 * if the DMA buffer is not 4byte aligned.
2663 cntoffset
= le32toh(cmd
->c_sgt
[0].sg_addr
) & 3;
2665 if (cntoffset
!= 0) {
2666 printf("sackcnt %u, cntoffset %u\n",
2667 sackcnt
, cntoffset
);
2670 /* advance SCSI pointer */
2671 njsc32_set_cur_ptr(cmd
,
2672 cmd
->c_dp_cur
+ sackcnt
- cntoffset
);
2675 if (auto_phase
& NJSC32_XPHASE_MSGOUT
) {
2676 /* Message Out phase has been automatically processed */
2677 TPRINTC(cmd
, ("njsc32_intr: Message Out\n"));
2678 if ((auto_phase
& NJSC32_XPHASE_PAUSED_MSG_IN
) == 0 &&
2679 sc
->sc_msgoutlen
<= NJSC32_MSGOUT_MAX_AUTO
) {
2680 njsc32_init_msgout(sc
);
2684 if (auto_phase
& NJSC32_XPHASE_STATUS
) {
2685 /* Status phase has been automatically processed */
2687 njsc32_read_1(sc
, NJSC32_REG_SCSI_CSB_IN
);
2688 TPRINTC(cmd
, ("njsc32_intr: Status %#x\n",
2689 cmd
->c_xs
->status
));
2692 if (auto_phase
& NJSC32_XPHASE_BUS_FREE
) {
2693 /* AutoSCSI is finished */
2695 TPRINTC(cmd
, ("njsc32_intr: Bus Free\n"));
2697 sc
->sc_stat
= NJSC32_STAT_IDLE
;
2698 sc
->sc_curcmd
= NULL
;
2700 njsc32_end_auto(sc
, cmd
, auto_phase
);
2705 if (intr
& NJSC32_IRQ_FIFO_THRESHOLD
) {
2706 /* XXX We use DMA, and this shouldn't happen */
2707 printf("%s: njsc32_intr: FIFO\n", device_xname(sc
->sc_dev
));
2711 if (intr
& NJSC32_IRQ_PCI
) {
2713 printf("%s: njsc32_intr: PCI\n", device_xname(sc
->sc_dev
));
2715 if (intr
& NJSC32_IRQ_BMCNTERR
) {
2717 printf("%s: njsc32_intr: BM\n", device_xname(sc
->sc_dev
));
2721 /* go next command if controller is idle */
2722 if (sc
->sc_stat
== NJSC32_STAT_IDLE
)
2726 /* enable interrupts */
2727 njsc32_write_2(sc
, NJSC32_REG_IRQ
, 0);
2730 return 1; /* processed */