remove __P() from this directory
[dragonfly.git] / sys / dev / disk / ct / ct.c
CommitLineData
984263bc 1/* $FreeBSD: src/sys/dev/ct/ct.c,v 1.4.2.1 2001/07/26 02:32:18 nyan Exp $ */
38e94a25 2/* $DragonFly: src/sys/dev/disk/ct/Attic/ct.c,v 1.5 2003/08/27 10:35:16 rob Exp $ */
984263bc
MD
3/* $NecBSD: ct.c,v 1.13.12.5 2001/06/26 07:31:53 honda Exp $ */
4/* $NetBSD$ */
5
6#define CT_DEBUG
7#define CT_IO_CONTROL_FLAGS (CT_USE_CCSEQ | CT_FAST_INTR)
8
9/*
10 * [NetBSD for NEC PC-98 series]
11 * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
12 * NetBSD/pc98 porting staff. All rights reserved.
13 *
14 * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
15 * Naofumi HONDA. All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 * 3. The name of the author may not be used to endorse or promote products
26 * derived from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
29 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
32 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
33 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41#include "opt_ddb.h"
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/kernel.h>
46#if defined(__FreeBSD__) && __FreeBSD_version > 500001
47#include <sys/bio.h>
48#endif /* __ FreeBSD__ */
49#include <sys/buf.h>
50#include <sys/queue.h>
51#include <sys/malloc.h>
52#include <sys/errno.h>
53
54#ifdef __NetBSD__
55#include <sys/device.h>
56
57#include <machine/bus.h>
58#include <machine/intr.h>
59
60#include <dev/scsipi/scsi_all.h>
61#include <dev/scsipi/scsipi_all.h>
62#include <dev/scsipi/scsiconf.h>
63#include <dev/scsipi/scsi_disk.h>
64
65#include <machine/dvcfg.h>
66#include <machine/physio_proc.h>
67
68#include <i386/Cbus/dev/scsi_low.h>
69
70#include <dev/ic/wd33c93reg.h>
71#include <i386/Cbus/dev/ct/ctvar.h>
72#include <i386/Cbus/dev/ct/ct_machdep.h>
73#endif /* __NetBSD__ */
74
75#ifdef __FreeBSD__
76#include <machine/clock.h>
77#include <machine/bus.h>
78#include <machine/dvcfg.h>
79#include <machine/physio_proc.h>
80
1f2de5d4 81#include <bus/cam/scsi/scsi_low.h>
984263bc
MD
82
83#include <dev/ic/wd33c93reg.h>
1f2de5d4
MD
84#include "ctvar.h"
85#include "ct_machdep.h"
984263bc
MD
86#endif /* __FreeBSD__ */
87
88#define CT_NTARGETS 8
89#define CT_NLUNS 8
90#define CT_RESET_DEFAULT 2000
91#define CT_DELAY_MAX (2 * 1000 * 1000)
92#define CT_DELAY_INTERVAL (1)
93
94/***************************************************
95 * DEBUG
96 ***************************************************/
97#ifdef CT_DEBUG
98int ct_debug;
99#endif /* CT_DEBUG */
100
101/***************************************************
102 * IO control
103 ***************************************************/
104#define CT_USE_CCSEQ 0x0100
105#define CT_FAST_INTR 0x0200
106
107u_int ct_io_control = CT_IO_CONTROL_FLAGS;
108
109/***************************************************
110 * default data
111 ***************************************************/
112u_int8_t cthw_cmdlevel[256] = {
113/* 0 1 2 3 4 5 6 7 8 9 A B C E D F */
114/*0*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,
115/*1*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
116/*2*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,
117/*3*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
118/*4*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
119/*5*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
120/*6*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
121/*7*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
122/*8*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
123/*9*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
124/*A*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
125/*B*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
126/*C*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
127/*D*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
128/*E*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
129/*F*/0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
130};
131
132#if 0
133/* default synch data table */
134/* A 10 6.6 5.0 4.0 3.3 2.8 2.5 2.0 M/s */
135/* X 100 150 200 250 300 350 400 500 ns */
136static struct ct_synch_data ct_synch_data_FSCSI[] = {
137 {25, 0xa0}, {37, 0xb0}, {50, 0x20}, {62, 0xd0}, {75, 0x30},
138 {87, 0xf0}, {100, 0x40}, {125, 0x50}, {0, 0}
139};
140
141static struct ct_synch_data ct_synch_data_SCSI[] = {
142 {50, 0x20}, {75, 0x30}, {100, 0x40}, {125, 0x50}, {0, 0}
143};
144#endif
145/***************************************************
146 * DEVICE STRUCTURE
147 ***************************************************/
148extern struct cfdriver ct_cd;
149
150/*****************************************************************
151 * Interface functions
152 *****************************************************************/
38e94a25
RG
153static int ct_xfer (struct ct_softc *, u_int8_t *, int, int, u_int *);
154static void ct_io_xfer (struct ct_softc *);
155static int ct_reselected (struct ct_softc *, u_int8_t);
156static void ct_phase_error (struct ct_softc *, u_int8_t);
157static int ct_start_selection (struct ct_softc *, struct slccb *);
158static int ct_msg (struct ct_softc *, struct targ_info *, u_int);
159static int ct_world_start (struct ct_softc *, int);
160static __inline void cthw_phase_bypass (struct ct_softc *, u_int8_t);
161static int cthw_chip_reset (struct ct_bus_access_handle *, int *, int, int);
162static void cthw_bus_reset (struct ct_softc *);
163static int ct_ccb_nexus_establish (struct ct_softc *);
164static int ct_lun_nexus_establish (struct ct_softc *);
165static int ct_target_nexus_establish (struct ct_softc *, int, int);
166static void cthw_attention (struct ct_softc *);
167static int ct_targ_init (struct ct_softc *, struct targ_info *, int);
168static int ct_unbusy (struct ct_softc *);
169static void ct_attention (struct ct_softc *);
170static struct ct_synch_data *ct_make_synch_table (struct ct_softc *);
171static int ct_catch_intr (struct ct_softc *);
984263bc
MD
172
173struct scsi_low_funcs ct_funcs = {
174 SC_LOW_INIT_T ct_world_start,
175 SC_LOW_BUSRST_T cthw_bus_reset,
176 SC_LOW_TARG_INIT_T ct_targ_init,
177 SC_LOW_LUN_INIT_T NULL,
178
179 SC_LOW_SELECT_T ct_start_selection,
180 SC_LOW_NEXUS_T ct_lun_nexus_establish,
181 SC_LOW_NEXUS_T ct_ccb_nexus_establish,
182
183 SC_LOW_ATTEN_T cthw_attention,
184 SC_LOW_MSG_T ct_msg,
185
186 SC_LOW_TIMEOUT_T NULL,
187 SC_LOW_POLL_T ctintr,
188
189 NULL, /* SC_LOW_POWER_T cthw_power, */
190};
191
192/**************************************************
193 * HW functions
194 **************************************************/
195static __inline void
196cthw_phase_bypass(ct, ph)
197 struct ct_softc *ct;
198 u_int8_t ph;
199{
200 struct ct_bus_access_handle *chp = &ct->sc_ch;
201
202 ct_cr_write_1(chp, wd3s_cph, ph);
203 ct_cr_write_1(chp, wd3s_cmd, WD3S_SELECT_ATN_TFR);
204}
205
206static void
207cthw_bus_reset(ct)
208 struct ct_softc *ct;
209{
210
211 /*
212 * wd33c93 does not have bus reset function.
213 */
214 if (ct->ct_bus_reset != NULL)
215 ((*ct->ct_bus_reset) (ct));
216}
217
218static int
219cthw_chip_reset(chp, chiprevp, chipclk, hostid)
220 struct ct_bus_access_handle *chp;
221 int *chiprevp;
222 int chipclk, hostid;
223{
224#define CT_SELTIMEOUT_20MHz_REGV (0x80)
225 u_int8_t aux, regv;
226 u_int seltout;
227 int wc;
228
229 /* issue abort cmd */
230 ct_cr_write_1(chp, wd3s_cmd, WD3S_ABORT);
231 SCSI_LOW_DELAY(1000); /* 1ms wait */
232 (void) ct_stat_read_1(chp);
233 (void) ct_cr_read_1(chp, wd3s_stat);
234
235 /* setup chip registers */
236 regv = 0;
237 seltout = CT_SELTIMEOUT_20MHz_REGV;
238 switch (chipclk)
239 {
240 case 8:
241 case 10:
242 seltout = (seltout * chipclk) / 20;
243 regv = IDR_FS_8_10;
244 break;
245
246 case 12:
247 case 15:
248 seltout = (seltout * chipclk) / 20;
249 regv = IDR_FS_12_15;
250 break;
251
252 case 16:
253 case 20:
254 seltout = (seltout * chipclk) / 20;
255 regv = IDR_FS_16_20;
256 break;
257
258 default:
259 panic("ct: illegal chip clk rate\n");
260 break;
261 }
262
263 regv |= IDR_EHP | hostid | IDR_RAF | IDR_EAF;
264 ct_cr_write_1(chp, wd3s_oid, regv);
265
266 ct_cr_write_1(chp, wd3s_cmd, WD3S_RESET);
267 for (wc = CT_RESET_DEFAULT; wc > 0; wc --)
268 {
269 aux = ct_stat_read_1(chp);
270 if (aux != 0xff && (aux & STR_INT))
271 {
272 regv = ct_cr_read_1(chp, wd3s_stat);
273 if (regv == BSR_RESET || regv == BSR_AFM_RESET)
274 break;
275
276 ct_cr_write_1(chp, wd3s_cmd, WD3S_RESET);
277 }
278 SCSI_LOW_DELAY(1);
279 }
280 if (wc == 0)
281 return ENXIO;
282
283 ct_cr_write_1(chp, wd3s_tout, seltout);
284 ct_cr_write_1(chp, wd3s_sid, SIDR_RESEL);
285 ct_cr_write_1(chp, wd3s_ctrl, CR_DEFAULT);
286 ct_cr_write_1(chp, wd3s_synch, 0);
287 if (chiprevp != NULL)
288 {
289 *chiprevp = CT_WD33C93;
290 if (regv == BSR_RESET)
291 goto out;
292
293 *chiprevp = CT_WD33C93_A;
294 ct_cr_write_1(chp, wd3s_qtag, 0xaa);
295 if (ct_cr_read_1(chp, wd3s_qtag) != 0xaa)
296 {
297 ct_cr_write_1(chp, wd3s_qtag, 0x0);
298 goto out;
299 }
300 ct_cr_write_1(chp, wd3s_qtag, 0x55);
301 if (ct_cr_read_1(chp, wd3s_qtag) != 0x55)
302 {
303 ct_cr_write_1(chp, wd3s_qtag, 0x0);
304 goto out;
305 }
306 ct_cr_write_1(chp, wd3s_qtag, 0x0);
307 *chiprevp = CT_WD33C93_B;
308 }
309
310out:
311 (void) ct_stat_read_1(chp);
312 (void) ct_cr_read_1(chp, wd3s_stat);
313 return 0;
314}
315
316static struct ct_synch_data *
317ct_make_synch_table(ct)
318 struct ct_softc *ct;
319{
320 struct ct_synch_data *sdtp, *sdp;
321 u_int base, i, period;
322
323 sdtp = sdp = &ct->sc_default_sdt[0];
324
325 if ((ct->sc_chipclk % 5) == 0)
326 base = 1000 / (5 * 2); /* 5 MHz type */
327 else
328 base = 1000 / (4 * 2); /* 4 MHz type */
329
330 if (ct->sc_chiprev >= CT_WD33C93_B)
331 {
332 /* fast scsi */
333 for (i = 2; i < 8; i ++, sdp ++)
334 {
335 period = (base * i) / 2;
336 if (period >= 200) /* 5 MHz */
337 break;
338 sdp->cs_period = period / 4;
339 sdp->cs_syncr = (i * 0x10) | 0x80;
340 }
341 }
342
343 for (i = 2; i < 8; i ++, sdp ++)
344 {
345 period = (base * i);
346 if (period > 500) /* 2 MHz */
347 break;
348 sdp->cs_period = period / 4;
349 sdp->cs_syncr = (i * 0x10);
350 }
351
352 sdp->cs_period = 0;
353 sdp->cs_syncr = 0;
354 return sdtp;
355}
356
357/**************************************************
358 * Attach & Probe
359 **************************************************/
360int
361ctprobesubr(chp, dvcfg, hsid, chipclk, chiprevp)
362 struct ct_bus_access_handle *chp;
363 u_int dvcfg, chipclk;
364 int hsid;
365 int *chiprevp;
366{
367
368#if 0
369 if ((ct_stat_read_1(chp) & STR_BSY) != 0)
370 return 0;
371#endif
372 if (cthw_chip_reset(chp, chiprevp, chipclk, hsid) != 0)
373 return 0;
374 return 1;
375}
376
377int
378ctprint(aux, name)
379 void *aux;
380 const char *name;
381{
382
383 if (name != NULL)
384 printf("%s: scsibus ", name);
385 return UNCONF;
386}
387
388void
389ctattachsubr(ct)
390 struct ct_softc *ct;
391{
392 struct scsi_low_softc *slp = &ct->sc_sclow;
393
394 ct->sc_tmaxcnt = SCSI_LOW_MIN_TOUT * 1000 * 1000; /* default */
395 slp->sl_funcs = &ct_funcs;
396 slp->sl_flags |= HW_READ_PADDING;
397 (void) scsi_low_attach(slp, 0, CT_NTARGETS, CT_NLUNS,
398 sizeof(struct ct_targ_info), 0);
399}
400
401/**************************************************
402 * SCSI LOW interface functions
403 **************************************************/
404static void
405cthw_attention(ct)
406 struct ct_softc *ct;
407{
408 struct ct_bus_access_handle *chp = &ct->sc_ch;
409
410 ct->sc_atten = 1;
411 if ((ct_stat_read_1(chp) & (STR_BSY | STR_CIP)) != 0)
412 return;
413
414 ct_cr_write_1(chp, wd3s_cmd, WD3S_ASSERT_ATN);
415 SCSI_LOW_DELAY(10);
416 if ((ct_stat_read_1(chp) & STR_LCI) == 0)
417 ct->sc_atten = 0;
418 ct_unbusy(ct);
419 return;
420}
421
422static void
423ct_attention(ct)
424 struct ct_softc *ct;
425{
426 struct scsi_low_softc *slp = &ct->sc_sclow;
427
428 if (slp->sl_atten == 0)
429 {
430 ct_unbusy(ct);
431 scsi_low_attention(slp);
432 }
433 else if (ct->sc_atten != 0)
434 {
435 ct_unbusy(ct);
436 cthw_attention(ct);
437 }
438}
439
440static int
441ct_targ_init(ct, ti, action)
442 struct ct_softc *ct;
443 struct targ_info *ti;
444 int action;
445{
446 struct ct_targ_info *cti = (void *) ti;
447
448 if (action == SCSI_LOW_INFO_ALLOC || action == SCSI_LOW_INFO_REVOKE)
449 {
450 if (ct->sc_sdp == NULL)
451 {
452 ct->sc_sdp = ct_make_synch_table(ct);
453 }
454
455 switch (ct->sc_chiprev)
456 {
457 default:
458 ti->ti_maxsynch.offset = 5;
459 break;
460
461 case CT_WD33C93_A:
462 case CT_AM33C93_A:
463 ti->ti_maxsynch.offset = 12;
464 break;
465
466 case CT_WD33C93_B:
467 case CT_WD33C93_C:
468 ti->ti_maxsynch.offset = 12;
469 break;
470 }
471
472 ti->ti_maxsynch.period = ct->sc_sdp[0].cs_period;
473 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
474 cti->cti_syncreg = 0;
475 }
476
477 return 0;
478}
479
480static int
481ct_world_start(ct, fdone)
482 struct ct_softc *ct;
483 int fdone;
484{
485 struct scsi_low_softc *slp = &ct->sc_sclow;
486 struct ct_bus_access_handle *chp = &ct->sc_ch;
487
488 if (ct->sc_sdp == NULL)
489 {
490 ct->sc_sdp = ct_make_synch_table(ct);
491 }
492
493 if (slp->sl_cfgflags & CFG_NOPARITY)
494 ct->sc_creg = CR_DEFAULT;
495 else
496 ct->sc_creg = CR_DEFAULT_HP;
497
498 if (ct->sc_dma & CT_DMA_DMASTART)
499 (*ct->ct_dma_xfer_stop) (ct);
500 if (ct->sc_dma & CT_DMA_PIOSTART)
501 (*ct->ct_pio_xfer_stop) (ct);
502 ct->sc_dma = 0;
503 ct->sc_atten = 0;
504
505 cthw_chip_reset(chp, NULL, ct->sc_chipclk, slp->sl_hostid);
506 scsi_low_bus_reset(slp);
507 cthw_chip_reset(chp, NULL, ct->sc_chipclk, slp->sl_hostid);
508
509 SOFT_INTR_REQUIRED(slp);
510 return 0;
511}
512
513static int
514ct_start_selection(ct, cb)
515 struct ct_softc *ct;
516 struct slccb *cb;
517{
518 struct scsi_low_softc *slp = &ct->sc_sclow;
519 struct ct_bus_access_handle *chp = &ct->sc_ch;
520
521 struct targ_info *ti = slp->sl_Tnexus;
522 struct lun_info *li = slp->sl_Lnexus;
523 int s, satok;
524 u_int8_t cmd;
525
526 ct->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000;
527 ct->sc_atten = 0;
528 satok = 0;
529
530 if (scsi_low_is_disconnect_ok(cb) != 0)
531 {
532 if (ct->sc_chiprev >= CT_WD33C93_A)
533 satok = 1;
534 else if (cthw_cmdlevel[slp->sl_scp.scp_cmd[0]] != 0)
535 satok = 1;
536 }
537
538 if (satok != 0 &&
539 scsi_low_is_msgout_continue(ti, SCSI_LOW_MSG_IDENTIFY) == 0)
540 {
541 cmd = WD3S_SELECT_ATN_TFR;
542 ct->sc_satgo = CT_SAT_GOING;
543 }
544 else
545 {
546 cmd = WD3S_SELECT_ATN;
547 ct->sc_satgo = 0;
548 }
549
550 if ((ct_stat_read_1(chp) & (STR_BSY | STR_INT | STR_CIP)) != 0)
551 return SCSI_LOW_START_FAIL;
552
553 if ((ct->sc_satgo & CT_SAT_GOING) != 0)
554 {
555 (void) scsi_low_msgout(slp, ti, SCSI_LOW_MSGOUT_INIT);
556 scsi_low_cmd(slp, ti);
557 ct_cr_write_1(chp, wd3s_oid, slp->sl_scp.scp_cmdlen);
558 ct_write_cmds(chp, slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen);
559 }
560 else
561 {
562 /* anyway attention assert */
563 SCSI_LOW_ASSERT_ATN(slp);
564 }
565
566 ct_target_nexus_establish(ct, li->li_lun, slp->sl_scp.scp_direction);
567
568 s = splhigh();
569 if ((ct_stat_read_1(chp) & (STR_BSY | STR_INT | STR_CIP)) == 0)
570 {
571 /* XXX:
572 * Reload a lun again here.
573 */
574 ct_cr_write_1(chp, wd3s_lun, li->li_lun);
575 ct_cr_write_1(chp, wd3s_cmd, cmd);
576 if ((ct_stat_read_1(chp) & STR_LCI) == 0)
577 {
578 splx(s);
579 SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART);
580 return SCSI_LOW_START_OK;
581 }
582 }
583 splx(s);
584 return SCSI_LOW_START_FAIL;
585}
586
587static int
588ct_msg(ct, ti, msg)
589 struct ct_softc *ct;
590 struct targ_info *ti;
591 u_int msg;
592{
593 struct ct_bus_access_handle *chp = &ct->sc_ch;
594 struct ct_targ_info *cti = (void *) ti;
595 struct ct_synch_data *csp = ct->sc_sdp;
596 u_int offset, period;
597 int error;
598
599 if ((msg & SCSI_LOW_MSG_WIDE) != 0)
600 {
601 if (ti->ti_width != SCSI_LOW_BUS_WIDTH_8)
602 {
603 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
604 return EINVAL;
605 }
606 return 0;
607 }
608
609 if ((msg & SCSI_LOW_MSG_SYNCH) == 0)
610 return 0;
611
612 offset = ti->ti_maxsynch.offset;
613 period = ti->ti_maxsynch.period;
614 for ( ; csp->cs_period != 0; csp ++)
615 {
616 if (period == csp->cs_period)
617 break;
618 }
619
620 if (ti->ti_maxsynch.period != 0 && csp->cs_period == 0)
621 {
622 ti->ti_maxsynch.period = 0;
623 ti->ti_maxsynch.offset = 0;
624 cti->cti_syncreg = 0;
625 error = EINVAL;
626 }
627 else
628 {
629 cti->cti_syncreg = ((offset & 0x0f) | csp->cs_syncr);
630 error = 0;
631 }
632
633 if (ct->ct_synch_setup != 0)
634 (*ct->ct_synch_setup) (ct, ti);
635 ct_cr_write_1(chp, wd3s_synch, cti->cti_syncreg);
636 return error;
637}
638
639/*************************************************
640 * <DATA PHASE>
641 *************************************************/
642static int
643ct_xfer(ct, data, len, direction, statp)
644 struct ct_softc *ct;
645 u_int8_t *data;
646 int len, direction;
647 u_int *statp;
648{
649 struct ct_bus_access_handle *chp = &ct->sc_ch;
650 int wc;
f96d6c88 651 u_int8_t aux;
984263bc
MD
652
653 *statp = 0;
654 if (len == 1)
655 {
656 ct_cr_write_1(chp, wd3s_cmd, WD3S_SBT | WD3S_TFR_INFO);
657 }
658 else
659 {
660 cthw_set_count(chp, len);
661 ct_cr_write_1(chp, wd3s_cmd, WD3S_TFR_INFO);
662 }
663
664 aux = ct_stat_read_1(chp);
665 if ((aux & STR_LCI) != 0)
666 {
667 cthw_set_count(chp, 0);
668 return len;
669 }
670
671 for (wc = 0; wc < ct->sc_tmaxcnt; wc ++)
672 {
673 /* check data ready */
674 if ((aux & (STR_BSY | STR_DBR)) == (STR_BSY | STR_DBR))
675 {
676 if (direction == SCSI_LOW_READ)
677 {
678 *data = ct_cr_read_1(chp, wd3s_data);
679 if ((aux & STR_PE) != 0)
680 *statp |= SCSI_LOW_DATA_PE;
681 }
682 else
683 {
684 ct_cr_write_1(chp, wd3s_data, *data);
685 }
686 len --;
687 if (len <= 0)
688 break;
689 data ++;
690 }
691 else
692 {
693 SCSI_LOW_DELAY(1);
694 }
695
696 /* check phase miss */
697 aux = ct_stat_read_1(chp);
698 if ((aux & STR_INT) != 0)
699 break;
700 }
701 return len;
702}
703
704#define CT_PADDING_BUF_SIZE 32
705
706static void
707ct_io_xfer(ct)
708 struct ct_softc *ct;
709{
710 struct scsi_low_softc *slp = &ct->sc_sclow;
711 struct ct_bus_access_handle *chp = &ct->sc_ch;
712 struct sc_p *sp = &slp->sl_scp;
713 u_int stat;
714 int len;
715 u_int8_t pbuf[CT_PADDING_BUF_SIZE];
716
717 /* polling mode */
718 ct_cr_write_1(chp, wd3s_ctrl, ct->sc_creg);
719
720 if (sp->scp_datalen <= 0)
721 {
722 slp->sl_error |= PDMAERR;
723
724 if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE)
725 SCSI_LOW_BZERO(pbuf, CT_PADDING_BUF_SIZE);
726 ct_xfer(ct, pbuf, CT_PADDING_BUF_SIZE,
727 sp->scp_direction, &stat);
728 }
729 else
730 {
731 len = ct_xfer(ct, sp->scp_data, sp->scp_datalen,
732 sp->scp_direction, &stat);
733 sp->scp_data += (sp->scp_datalen - len);
734 sp->scp_datalen = len;
735 }
736}
737
738/**************************************************
739 * <PHASE ERROR>
740 **************************************************/
741struct ct_err {
742 u_char *pe_msg;
743 u_int pe_err;
744 u_int pe_errmsg;
745 int pe_done;
746};
747
748struct ct_err ct_cmderr[] = {
749/*0*/ { "illegal cmd", FATALIO, SCSI_LOW_MSG_ABORT, 1},
750/*1*/ { "unexpected bus free", FATALIO, 0, 1},
751/*2*/ { NULL, SELTIMEOUTIO, 0, 1},
752/*3*/ { "scsi bus parity error", PARITYERR, SCSI_LOW_MSG_ERROR, 0},
753/*4*/ { "scsi bus parity error", PARITYERR, SCSI_LOW_MSG_ERROR, 0},
754/*5*/ { "unknown" , FATALIO, SCSI_LOW_MSG_ABORT, 1},
755/*6*/ { "miss reselection (target mode)", FATALIO, SCSI_LOW_MSG_ABORT, 0},
756/*7*/ { "wrong status byte", PARITYERR, SCSI_LOW_MSG_ERROR, 0},
757};
758
759static void
760ct_phase_error(ct, scsi_status)
761 struct ct_softc *ct;
762 u_int8_t scsi_status;
763{
764 struct scsi_low_softc *slp = &ct->sc_sclow;
765 struct targ_info *ti = slp->sl_Tnexus;
766 struct ct_err *pep;
767 u_int msg = 0;
768
769 if ((scsi_status & BSR_CM) == BSR_CMDERR &&
770 (scsi_status & BSR_PHVALID) == 0)
771 {
772 pep = &ct_cmderr[scsi_status & BSR_PM];
773 slp->sl_error |= pep->pe_err;
774 if ((pep->pe_err & PARITYERR) != 0)
775 {
776 if (ti->ti_phase == PH_MSGIN)
777 msg = SCSI_LOW_MSG_PARITY;
778 else
779 msg = SCSI_LOW_MSG_ERROR;
780 }
781 else
782 msg = pep->pe_errmsg;
783
784 if (msg != 0)
785 scsi_low_assert_msg(slp, slp->sl_Tnexus, msg, 1);
786
787 if (pep->pe_msg != NULL)
788 {
789 printf("%s: phase error: %s",
790 slp->sl_xname, pep->pe_msg);
791 scsi_low_print(slp, slp->sl_Tnexus);
792 }
793
794 if (pep->pe_done != 0)
795 scsi_low_disconnected(slp, ti);
796 }
797 else
798 {
799 slp->sl_error |= FATALIO;
800 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, "phase error");
801 }
802}
803
804/**************************************************
805 * ### SCSI PHASE SEQUENCER ###
806 **************************************************/
807static int
808ct_reselected(ct, scsi_status)
809 struct ct_softc *ct;
810 u_int8_t scsi_status;
811{
812 struct scsi_low_softc *slp = &ct->sc_sclow;
813 struct ct_bus_access_handle *chp = &ct->sc_ch;
814 struct targ_info *ti;
815 u_int sid;
816 u_int8_t regv;
817
818 ct->sc_atten = 0;
819 ct->sc_satgo &= ~CT_SAT_GOING;
820 regv = ct_cr_read_1(chp, wd3s_sid);
821 if ((regv & SIDR_VALID) == 0)
822 return EJUSTRETURN;
823
824 sid = regv & SIDR_IDM;
825 if ((ti = scsi_low_reselected(slp, sid)) == NULL)
826 return EJUSTRETURN;
827
828 ct_target_nexus_establish(ct, 0, SCSI_LOW_READ);
829 if (scsi_status != BSR_AFM_RESEL)
830 return EJUSTRETURN;
831
832 SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
833 regv = ct_cr_read_1(chp, wd3s_data);
834 if (scsi_low_msgin(slp, ti, (u_int) regv) == 0)
835 {
836 if (scsi_low_is_msgout_continue(ti, 0) != 0)
837 {
838 /* XXX: scsi_low_attetion */
839 scsi_low_attention(slp);
840 }
841 }
842
843 if (ct->sc_atten != 0)
844 {
845 ct_attention(ct);
846 }
847
848 ct_cr_write_1(chp, wd3s_cmd, WD3S_NEGATE_ACK);
849 return EJUSTRETURN;
850}
851
852static int
853ct_target_nexus_establish(ct, lun, dir)
854 struct ct_softc *ct;
855 int lun, dir;
856{
857 struct scsi_low_softc *slp = &ct->sc_sclow;
858 struct ct_bus_access_handle *chp = &ct->sc_ch;
859 struct targ_info *ti = slp->sl_Tnexus;
860 struct ct_targ_info *cti = (void *) ti;
861
862 if (dir == SCSI_LOW_WRITE)
863 ct_cr_write_1(chp, wd3s_did, ti->ti_id);
864 else
865 ct_cr_write_1(chp, wd3s_did, ti->ti_id | DIDR_DPD);
866 ct_cr_write_1(chp, wd3s_lun, lun);
867 ct_cr_write_1(chp, wd3s_ctrl, ct->sc_creg | CR_DMA);
868 ct_cr_write_1(chp, wd3s_cph, 0);
869 ct_cr_write_1(chp, wd3s_synch, cti->cti_syncreg);
870 cthw_set_count(chp, 0);
871 return 0;
872}
873
874static int
875ct_lun_nexus_establish(ct)
876 struct ct_softc *ct;
877{
878 struct scsi_low_softc *slp = &ct->sc_sclow;
879 struct ct_bus_access_handle *chp = &ct->sc_ch;
880 struct lun_info *li = slp->sl_Lnexus;
881
882 ct_cr_write_1(chp, wd3s_lun, li->li_lun);
883 return 0;
884}
885
886static int
887ct_ccb_nexus_establish(ct)
888 struct ct_softc *ct;
889{
890 struct scsi_low_softc *slp = &ct->sc_sclow;
891 struct ct_bus_access_handle *chp = &ct->sc_ch;
892 struct lun_info *li = slp->sl_Lnexus;
893 struct targ_info *ti = slp->sl_Tnexus;
894 struct ct_targ_info *cti = (void *) ti;
895 struct slccb *cb = slp->sl_Qnexus;
896
897 ct->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000;
898
899 if ((ct->sc_satgo & CT_SAT_GOING) != 0)
900 {
901 ct_cr_write_1(chp, wd3s_oid, slp->sl_scp.scp_cmdlen);
902 ct_write_cmds(chp, slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen);
903 }
904 if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE)
905 ct_cr_write_1(chp, wd3s_did, ti->ti_id);
906 else
907 ct_cr_write_1(chp, wd3s_did, ti->ti_id | DIDR_DPD);
908 ct_cr_write_1(chp, wd3s_lun, li->li_lun);
909 ct_cr_write_1(chp, wd3s_synch, cti->cti_syncreg);
910 return 0;
911}
912
913static int
914ct_unbusy(ct)
915 struct ct_softc *ct;
916{
917 struct scsi_low_softc *slp = &ct->sc_sclow;
918 struct ct_bus_access_handle *chp = &ct->sc_ch;
919 int wc;
f96d6c88 920 u_int8_t regv;
984263bc
MD
921
922 for (wc = 0; wc < CT_DELAY_MAX / CT_DELAY_INTERVAL; wc ++)
923 {
924 regv = ct_stat_read_1(chp);
925 if ((regv & (STR_BSY | STR_CIP)) == 0)
926 return 0;
927 if (regv == (u_int8_t) -1)
928 return EIO;
929
930 SCSI_LOW_DELAY(CT_DELAY_INTERVAL);
931 }
932
933 printf("%s: unbusy timeout\n", slp->sl_xname);
934 return EBUSY;
935}
936
937static int
938ct_catch_intr(ct)
939 struct ct_softc *ct;
940{
941 struct ct_bus_access_handle *chp = &ct->sc_ch;
942 int wc;
f96d6c88 943 u_int8_t regv;
984263bc
MD
944
945 for (wc = 0; wc < CT_DELAY_MAX / CT_DELAY_INTERVAL; wc ++)
946 {
947 regv = ct_stat_read_1(chp);
948 if ((regv & (STR_INT | STR_BSY | STR_CIP)) == STR_INT)
949 return 0;
950
951 SCSI_LOW_DELAY(CT_DELAY_INTERVAL);
952 }
953 return EJUSTRETURN;
954}
955
956int
957ctintr(arg)
958 void *arg;
959{
960 struct ct_softc *ct = arg;
961 struct scsi_low_softc *slp = &ct->sc_sclow;
962 struct ct_bus_access_handle *chp = &ct->sc_ch;
963 struct targ_info *ti;
964 struct physio_proc *pp;
965 struct buf *bp;
966 u_int derror, flags;
967 int len, satgo, error;
968 u_int8_t scsi_status, regv;
969
970again:
971 if (slp->sl_flags & HW_INACTIVE)
972 return 0;
973
974 /**************************************************
975 * Get status & bus phase
976 **************************************************/
977 if ((ct_stat_read_1(chp) & STR_INT) == 0)
978 return 0;
979
980 scsi_status = ct_cr_read_1(chp, wd3s_stat);
981 if (scsi_status == ((u_int8_t) -1))
982 return 1;
983
984 /**************************************************
985 * Check reselection, or nexus
986 **************************************************/
987 if (scsi_status == BSR_RESEL || scsi_status == BSR_AFM_RESEL)
988 {
989 if (ct_reselected(ct, scsi_status) == EJUSTRETURN)
990 return 1;
991 }
992
993 if ((ti = slp->sl_Tnexus) == NULL)
994 return 1;
995
996 /**************************************************
997 * Debug section
998 **************************************************/
999#ifdef CT_DEBUG
1000 if (ct_debug > 0)
1001 {
1002 scsi_low_print(slp, NULL);
1003 printf("%s: scsi_status 0x%x\n\n", slp->sl_xname,
1004 (u_int) scsi_status);
1005#ifdef DDB
1006 if (ct_debug > 1)
1007 SCSI_LOW_DEBUGGER("ct");
1008#endif /* DDB */
1009 }
1010#endif /* CT_DEBUG */
1011
1012 /**************************************************
1013 * Internal scsi phase
1014 **************************************************/
1015 satgo = ct->sc_satgo;
1016 ct->sc_satgo &= ~CT_SAT_GOING;
1017
1018 switch (ti->ti_phase)
1019 {
1020 case PH_SELSTART:
1021 if ((satgo & CT_SAT_GOING) == 0)
1022 {
1023 if (scsi_status != BSR_SELECTED)
1024 {
1025 ct_phase_error(ct, scsi_status);
1026 return 1;
1027 }
1028 scsi_low_arbit_win(slp);
1029 SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED);
1030 return 1;
1031 }
1032 else
1033 {
1034 scsi_low_arbit_win(slp);
1035 SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT); /* XXX */
1036 }
1037 break;
1038
1039 case PH_RESEL:
1040 if ((scsi_status & BSR_PHVALID) == 0 ||
1041 (scsi_status & BSR_PM) != BSR_MSGIN)
1042 {
1043 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
1044 "phase miss after reselect");
1045 return 1;
1046 }
1047 break;
1048
1049 default:
1050 if (slp->sl_flags & HW_PDMASTART)
1051 {
1052 slp->sl_flags &= ~HW_PDMASTART;
1053 if (ct->sc_dma & CT_DMA_DMASTART)
1054 {
1055 (*ct->ct_dma_xfer_stop) (ct);
1056 ct->sc_dma &= ~CT_DMA_DMASTART;
1057 }
1058 else if (ct->sc_dma & CT_DMA_PIOSTART)
1059 {
1060 (*ct->ct_pio_xfer_stop) (ct);
1061 ct->sc_dma &= ~CT_DMA_PIOSTART;
1062 }
1063 else
1064 {
1065 scsi_low_data_finish(slp);
1066 }
1067 }
1068 break;
1069 }
1070
1071 /**************************************************
1072 * parse scsi phase
1073 **************************************************/
1074 if (scsi_status & BSR_PHVALID)
1075 {
1076 /**************************************************
1077 * Normal SCSI phase.
1078 **************************************************/
1079 if ((scsi_status & BSR_CM) == BSR_CMDABT)
1080 {
1081 ct_phase_error(ct, scsi_status);
1082 return 1;
1083 }
1084
1085 switch (scsi_status & BSR_PM)
1086 {
1087 case BSR_DATAOUT:
1088 SCSI_LOW_SETUP_PHASE(ti, PH_DATA);
1089 if (scsi_low_data(slp, ti, &bp, SCSI_LOW_WRITE) != 0)
1090 {
1091 ct_attention(ct);
1092 }
1093 goto common_data_phase;
1094
1095 case BSR_DATAIN:
1096 SCSI_LOW_SETUP_PHASE(ti, PH_DATA);
1097 if (scsi_low_data(slp, ti, &bp, SCSI_LOW_READ) != 0)
1098 {
1099 ct_attention(ct);
1100 }
1101
1102common_data_phase:
1103 if (slp->sl_scp.scp_datalen > 0)
1104 {
1105 slp->sl_flags |= HW_PDMASTART;
1106 if ((ct->sc_xmode & CT_XMODE_PIO) != 0)
1107 {
1108 pp = physio_proc_enter(bp);
1109 error = (*ct->ct_pio_xfer_start) (ct);
1110 physio_proc_leave(pp);
1111 if (error == 0)
1112 {
1113 ct->sc_dma |= CT_DMA_PIOSTART;
1114 return 1;
1115 }
1116 }
1117
1118 if ((ct->sc_xmode & CT_XMODE_DMA) != 0)
1119 {
1120 error = (*ct->ct_dma_xfer_start) (ct);
1121 if (error == 0)
1122 {
1123 ct->sc_dma |= CT_DMA_DMASTART;
1124 return 1;
1125 }
1126 }
1127 }
1128 else
1129 {
1130 if (slp->sl_scp.scp_direction == SCSI_LOW_READ)
1131 {
1132 if (!(slp->sl_flags & HW_READ_PADDING))
1133 {
1134 printf("%s: read padding required\n", slp->sl_xname);
1135 return 1;
1136 }
1137 }
1138 else
1139 {
1140 if (!(slp->sl_flags & HW_WRITE_PADDING))
1141 {
1142 printf("%s: write padding required\n", slp->sl_xname);
1143 return 1;
1144 }
1145 }
1146 slp->sl_flags |= HW_PDMASTART;
1147 }
1148
1149 ct_io_xfer(ct);
1150 return 1;
1151
1152 case BSR_CMDOUT:
1153 SCSI_LOW_SETUP_PHASE(ti, PH_CMD);
1154 if (scsi_low_cmd(slp, ti) != 0)
1155 {
1156 ct_attention(ct);
1157 }
1158
1159 if (ct_xfer(ct, slp->sl_scp.scp_cmd,
1160 slp->sl_scp.scp_cmdlen,
1161 SCSI_LOW_WRITE, &derror) != 0)
1162 {
1163 printf("%s: scsi cmd xfer short\n",
1164 slp->sl_xname);
1165 }
1166 return 1;
1167
1168 case BSR_STATIN:
1169 SCSI_LOW_SETUP_PHASE(ti, PH_STAT);
1170 if ((ct_io_control & CT_USE_CCSEQ) != 0)
1171 {
1172 if (scsi_low_is_msgout_continue(ti, 0) != 0 ||
1173 ct->sc_atten != 0)
1174 {
1175 ct_xfer(ct, &regv, 1, SCSI_LOW_READ,
1176 &derror);
1177 scsi_low_statusin(slp, ti,
1178 regv | derror);
1179 }
1180 else
1181 {
1182 ct->sc_satgo |= CT_SAT_GOING;
1183 cthw_set_count(chp, 0);
1184 cthw_phase_bypass(ct, 0x41);
1185 }
1186 }
1187 else
1188 {
1189 ct_xfer(ct, &regv, 1, SCSI_LOW_READ, &derror);
1190 scsi_low_statusin(slp, ti, regv | derror);
1191 }
1192 return 1;
1193
1194 case BSR_UNSPINFO0:
1195 case BSR_UNSPINFO1:
1196 printf("%s: illegal bus phase (0x%x)\n", slp->sl_xname,
1197 (u_int) scsi_status);
1198 scsi_low_print(slp, ti);
1199 return 1;
1200
1201 case BSR_MSGOUT:
1202 SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT);
1203 flags = SCSI_LOW_MSGOUT_UNIFY;
1204 if (ti->ti_ophase != ti->ti_phase)
1205 flags |= SCSI_LOW_MSGOUT_INIT;
1206 len = scsi_low_msgout(slp, ti, flags);
1207
1208 if (len > 1 && slp->sl_atten == 0)
1209 {
1210 ct_attention(ct);
1211 }
1212
1213 if (ct_xfer(ct, ti->ti_msgoutstr, len,
1214 SCSI_LOW_WRITE, &derror) != 0)
1215 {
1216 printf("%s: scsi msgout xfer short\n",
1217 slp->sl_xname);
1218 }
1219 SCSI_LOW_DEASSERT_ATN(slp);
1220 ct->sc_atten = 0;
1221 return 1;
1222
1223 case BSR_MSGIN:/* msg in */
1224 SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
1225
1226 ct_xfer(ct, &regv, 1, SCSI_LOW_READ, &derror);
1227 if (scsi_low_msgin(slp, ti, regv | derror) == 0)
1228 {
1229 if (scsi_low_is_msgout_continue(ti, 0) != 0)
1230 {
1231 /* XXX: scsi_low_attetion */
1232 scsi_low_attention(slp);
1233 }
1234 }
1235
1236 if ((ct_io_control & CT_FAST_INTR) != 0)
1237 {
1238 if (ct_catch_intr(ct) == 0)
1239 goto again;
1240 }
1241 return 1;
1242 }
1243 }
1244 else
1245 {
1246 /**************************************************
1247 * Special SCSI phase
1248 **************************************************/
1249 switch (scsi_status)
1250 {
1251 case BSR_SATSDP: /* SAT with save data pointer */
1252 SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
1253 ct->sc_satgo |= CT_SAT_GOING;
1254 scsi_low_msgin(slp, ti, MSG_SAVESP);
1255 cthw_phase_bypass(ct, 0x41);
1256 return 1;
1257
1258 case BSR_SATFIN: /* SAT COMPLETE */
1259 /*
1260 * emulate statusin => msgin
1261 */
1262 SCSI_LOW_SETUP_PHASE(ti, PH_STAT);
1263 scsi_low_statusin(slp, ti, ct_cr_read_1(chp, wd3s_lun));
1264
1265 SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
1266 scsi_low_msgin(slp, ti, MSG_COMP);
1267
1268 scsi_low_disconnected(slp, ti);
1269 return 1;
1270
1271 case BSR_ACKREQ: /* negate ACK */
1272 if (ct->sc_atten != 0)
1273 {
1274 ct_attention(ct);
1275 }
1276
1277 ct_cr_write_1(chp, wd3s_cmd, WD3S_NEGATE_ACK);
1278 if ((ct_io_control & CT_FAST_INTR) != 0)
1279 {
1280 /* XXX:
1281 * Should clear a pending interrupt and
1282 * sync with a next interrupt!
1283 */
1284 ct_catch_intr(ct);
1285 }
1286 return 1;
1287
1288 case BSR_DISC: /* disconnect */
1289 if (slp->sl_msgphase == MSGPH_NULL &&
1290 (satgo & CT_SAT_GOING) != 0)
1291 {
1292 /*
1293 * emulate disconnect msg
1294 */
1295 SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
1296 scsi_low_msgin(slp, ti, MSG_DISCON);
1297 }
1298 scsi_low_disconnected(slp, ti);
1299 return 1;
1300
1301 default:
1302 break;
1303 }
1304 }
1305
1306 ct_phase_error(ct, scsi_status);
1307 return 1;
1308}