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