Do a major clean-up of the BUSDMA architecture. A large number of
[dragonfly.git] / sys / dev / disk / stg / tmc18c30.c
CommitLineData
984263bc 1/* $FreeBSD: src/sys/dev/stg/tmc18c30.c,v 1.1.2.5 2001/12/17 13:30:19 non Exp $ */
1f7ab7c9 2/* $DragonFly: src/sys/dev/disk/stg/tmc18c30.c,v 1.11 2006/10/25 20:55:54 dillon Exp $ */
984263bc
MD
3/* $NecBSD: tmc18c30.c,v 1.28.12.3 2001/06/19 04:35:48 honda Exp $ */
4/* $NetBSD$ */
5
6#define STG_DEBUG
7#define STG_STATICS
8#define STG_IO_CONTROL_FLAGS (STG_FIFO_INTERRUPTS | STG_WAIT_FOR_SELECT)
9
10/*
11 * [NetBSD for NEC PC-98 series]
12 * Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001
13 * NetBSD/pc98 porting staff. All rights reserved.
14 * Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001
15 * Naofumi HONDA. All rights reserved.
16 * Copyright (c) 1996, 1997, 1998, 1999
17 * Kouichi Matsuda. All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
27 * 3. The name of the author may not be used to endorse or promote products
28 * derived from this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
31 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
34 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
36 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
38 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
39 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40 * POSSIBILITY OF SUCH DAMAGE.
41 */
42#include "opt_ddb.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/kernel.h>
984263bc
MD
47#include <sys/buf.h>
48#include <sys/queue.h>
49#include <sys/malloc.h>
50#include <sys/errno.h>
1f7ab7c9 51#include <sys/bus.h>
2c9868e4 52#include <sys/thread2.h>
984263bc 53
984263bc
MD
54#include <machine/clock.h>
55#include <machine/cpu.h>
984263bc
MD
56
57#include <machine/dvcfg.h>
58#include <machine/physio_proc.h>
59
1f2de5d4
MD
60#include <bus/cam/scsi/scsi_low.h>
61#include "tmc18c30reg.h"
62#include "tmc18c30var.h"
984263bc
MD
63
64/***************************************************
65 * USER SETTINGS
66 ***************************************************/
67/* DEVICE CONFIGURATION FLAGS (MINOR)
68 *
69 * 0x01 DISCONECT OFF
70 * 0x02 PARITY LINE OFF
71 * 0x04 IDENTIFY MSG OFF ( = single lun)
72 * 0x08 SYNC TRANSFER OFF
73 */
74/* #define STG_SYNC_SUPPORT */ /* NOT YET but easy */
75
76/* For the 512 fifo type: change below */
77#define TMC18C30_FIFOSZ 0x800
78#define TMC18C30_FCBSZ 0x200
79#define TMC18C50_FIFOSZ 0x2000
80#define TMC18C50_FCBSZ 0x400
81
82#define STG_MAX_DATA_SIZE (64 * 1024)
83#define STG_DELAY_MAX (2 * 1000 * 1000)
84#define STG_DELAY_INTERVAL (1)
85#define STG_DELAY_SELECT_POLLING_MAX (5 * 1000 * 1000)
86
87/***************************************************
88 * PARAMS
89 ***************************************************/
90#define STG_NTARGETS 8
91#define STG_NLUNS 8
92
93/***************************************************
94 * DEBUG
95 ***************************************************/
96#ifdef STG_DEBUG
97int stg_debug;
98#endif /* STG_DEBUG */
99
100#ifdef STG_STATICS
101struct stg_statics {
102 int arbit_fail_0;
103 int arbit_fail_1;
104 int disconnect;
105 int reselect;
106} stg_statics;
107#endif /* STG_STATICS */
108
109/***************************************************
110 * IO control flags
111 ***************************************************/
112#define STG_FIFO_INTERRUPTS 0x0001
113#define STG_WAIT_FOR_SELECT 0x0100
114
115int stg_io_control = STG_IO_CONTROL_FLAGS;
116
117/***************************************************
118 * DEVICE STRUCTURE
119 ***************************************************/
120extern struct cfdriver stg_cd;
121
122/**************************************************************
123 * DECLARE
124 **************************************************************/
125/* static */
38e94a25
RG
126static void stg_pio_read (struct stg_softc *, struct targ_info *, u_int);
127static void stg_pio_write (struct stg_softc *, struct targ_info *, u_int);
128static int stg_xfer (struct stg_softc *, u_int8_t *, int, int, int);
129static int stg_msg (struct stg_softc *, struct targ_info *, u_int);
130static int stg_reselected (struct stg_softc *);
131static int stg_disconnected (struct stg_softc *, struct targ_info *);
132static __inline void stg_pdma_end (struct stg_softc *, struct targ_info *);
133static int stghw_select_targ_wait (struct stg_softc *, int);
134static int stghw_check (struct stg_softc *);
135static void stghw_init (struct stg_softc *);
136static int stg_negate_signal (struct stg_softc *, u_int8_t, u_char *);
137static int stg_expect_signal (struct stg_softc *, u_int8_t, u_int8_t);
138static int stg_world_start (struct stg_softc *, int);
139static int stghw_start_selection (struct stg_softc *sc, struct slccb *);
140static void stghw_bus_reset (struct stg_softc *);
141static void stghw_attention (struct stg_softc *);
142static int stg_target_nexus_establish (struct stg_softc *);
143static int stg_lun_nexus_establish (struct stg_softc *);
144static int stg_ccb_nexus_establish (struct stg_softc *);
145static int stg_targ_init (struct stg_softc *, struct targ_info *, int);
146static __inline void stghw_bcr_write_1 (struct stg_softc *, u_int8_t);
147static int stg_timeout (struct stg_softc *);
148static void stg_selection_done_and_expect_msgout (struct stg_softc *);
984263bc
MD
149
150struct scsi_low_funcs stgfuncs = {
151 SC_LOW_INIT_T stg_world_start,
152 SC_LOW_BUSRST_T stghw_bus_reset,
153 SC_LOW_TARG_INIT_T stg_targ_init,
154 SC_LOW_LUN_INIT_T NULL,
155
156 SC_LOW_SELECT_T stghw_start_selection,
157 SC_LOW_NEXUS_T stg_lun_nexus_establish,
158 SC_LOW_NEXUS_T stg_ccb_nexus_establish,
159
160 SC_LOW_ATTEN_T stghw_attention,
161 SC_LOW_MSG_T stg_msg,
162
163 SC_LOW_TIMEOUT_T stg_timeout,
164 SC_LOW_POLL_T stgintr,
165
166 NULL,
167};
168
169/****************************************************
170 * hwfuncs
171 ****************************************************/
172static __inline void
c436375a 173stghw_bcr_write_1(struct stg_softc *sc, u_int8_t bcv)
984263bc
MD
174{
175
176 bus_space_write_1(sc->sc_iot, sc->sc_ioh, tmc_bctl, bcv);
177 sc->sc_busimg = bcv;
178}
179
180static int
c436375a 181stghw_check(struct stg_softc *sc)
984263bc
MD
182{
183 struct scsi_low_softc *slp = &sc->sc_sclow;
184 bus_space_tag_t iot = sc->sc_iot;
185 bus_space_handle_t ioh = sc->sc_ioh;
186 u_int fcbsize, fcb;
187 u_int16_t lsb, msb;
188
189 lsb = bus_space_read_1(iot, ioh, tmc_idlsb);
190 msb = bus_space_read_1(iot, ioh, tmc_idmsb);
191 switch (msb << 8 | lsb)
192 {
193 case 0x6127:
194 /* TMCCHIP_1800 not supported. (it's my policy) */
195 sc->sc_chip = TMCCHIP_1800;
196 return EINVAL;
197
198 case 0x60e9:
199 if (bus_space_read_1(iot, ioh, tmc_cfg2) & 0x02)
200 {
201 sc->sc_chip = TMCCHIP_18C30;
202 sc->sc_fsz = TMC18C30_FIFOSZ;
203 fcbsize = TMC18C30_FCBSZ;
204 }
205 else
206 {
207 sc->sc_chip = TMCCHIP_18C50;
208 sc->sc_fsz = TMC18C50_FIFOSZ;
209 fcbsize = TMC18C50_FCBSZ;
210 }
211 break;
212
213 default:
214 sc->sc_chip = TMCCHIP_UNK;
215 return ENODEV;
216 }
217
218 sc->sc_fcRinit = FCTL_INTEN;
219 sc->sc_fcWinit = FCTL_PARENB | FCTL_INTEN;
220
221 if (slp->sl_cfgflags & CFG_NOATTEN)
222 sc->sc_imsg = 0;
223 else
224 sc->sc_imsg = BCTL_ATN;
225 sc->sc_busc = BCTL_BUSEN;
226
227 sc->sc_wthold = fcbsize + 256;
228 sc->sc_rthold = fcbsize - 256;
229 sc->sc_maxwsize = sc->sc_fsz;
230
231 fcb = fcbsize / (sc->sc_fsz / 16);
232 sc->sc_icinit = ICTL_CD | ICTL_SEL | ICTL_ARBIT | fcb;
233 return 0;
234}
235
236static void
c436375a 237stghw_init(struct stg_softc *sc)
984263bc
MD
238{
239 bus_space_tag_t iot = sc->sc_iot;
240 bus_space_handle_t ioh = sc->sc_ioh;
241
242 bus_space_write_1(iot, ioh, tmc_ictl, 0);
243 stghw_bcr_write_1(sc, BCTL_BUSFREE);
244 bus_space_write_1(iot, ioh, tmc_fctl,
245 sc->sc_fcRinit | FCTL_CLRFIFO | FCTL_CLRINT);
246 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit);
247 bus_space_write_1(iot, ioh, tmc_ictl, sc->sc_icinit);
248
249 bus_space_write_1(iot, ioh, tmc_ssctl, 0);
250}
251
252static int
c436375a 253stg_targ_init(struct stg_softc *sc, struct targ_info *ti, int action)
984263bc
MD
254{
255 struct stg_targ_info *sti = (void *) ti;
256
257 if (action == SCSI_LOW_INFO_ALLOC || action == SCSI_LOW_INFO_REVOKE)
258 {
259 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
260 ti->ti_maxsynch.period = 0;
261 ti->ti_maxsynch.offset = 0;
262 sti->sti_reg_synch = 0;
263 }
264 return 0;
265}
266
267/****************************************************
268 * scsi low interface
269 ****************************************************/
270static void
c436375a 271stghw_attention(struct stg_softc *sc)
984263bc
MD
272{
273
274 sc->sc_busc |= BCTL_ATN;
275 sc->sc_busimg |= BCTL_ATN;
276 bus_space_write_1(sc->sc_iot, sc->sc_ioh, tmc_bctl, sc->sc_busimg);
277 SCSI_LOW_DELAY(10);
278}
279
280static void
c436375a 281stghw_bus_reset(struct stg_softc *sc)
984263bc
MD
282{
283 bus_space_tag_t iot = sc->sc_iot;
284 bus_space_handle_t ioh = sc->sc_ioh;
285
286 bus_space_write_1(iot, ioh, tmc_ictl, 0);
287 bus_space_write_1(iot, ioh, tmc_fctl, 0);
288 stghw_bcr_write_1(sc, BCTL_RST);
289 SCSI_LOW_DELAY(100000);
290 stghw_bcr_write_1(sc, BCTL_BUSFREE);
291}
292
293static int
c436375a 294stghw_start_selection(struct stg_softc *sc, struct slccb *cb)
984263bc
MD
295{
296 bus_space_tag_t iot = sc->sc_iot;
297 bus_space_handle_t ioh = sc->sc_ioh;
298 struct targ_info *ti = cb->ti;
f96d6c88 299 u_int8_t stat;
984263bc
MD
300
301 sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000;
302 sc->sc_dataout_timeout = 0;
303 sc->sc_ubf_timeout = 0;
304 stghw_bcr_write_1(sc, BCTL_BUSFREE);
305 bus_space_write_1(iot, ioh, tmc_ictl, sc->sc_icinit);
306
2c9868e4 307 crit_enter();
984263bc
MD
308 stat = bus_space_read_1(iot, ioh, tmc_astat);
309 if ((stat & ASTAT_INT) != 0)
310 {
2c9868e4 311 crit_exit();
984263bc
MD
312 return SCSI_LOW_START_FAIL;
313 }
314
315 bus_space_write_1(iot, ioh, tmc_scsiid, sc->sc_idbit);
316 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit | FCTL_ARBIT);
2c9868e4 317 crit_exit();
984263bc
MD
318
319 SCSI_LOW_SETUP_PHASE(ti, PH_ARBSTART);
320 return SCSI_LOW_START_OK;
321}
322
323static int
c436375a 324stg_world_start(struct stg_softc *sc, int fdone)
984263bc
MD
325{
326 struct scsi_low_softc *slp = &sc->sc_sclow;
327 int error;
328
329 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0)
330 sc->sc_fcRinit |= FCTL_PARENB;
331 else
332 sc->sc_fcRinit &= ~FCTL_PARENB;
333
334 if ((error = stghw_check(sc)) != 0)
335 return error;
336
337 stghw_init(sc);
338 scsi_low_bus_reset(slp);
339 stghw_init(sc);
340
341 SOFT_INTR_REQUIRED(slp);
342 return 0;
343}
344
345static int
c436375a 346stg_msg(struct stg_softc *sc, struct targ_info *ti, u_int msg)
984263bc
MD
347{
348 bus_space_tag_t iot = sc->sc_iot;
349 bus_space_handle_t ioh = sc->sc_ioh;
350 struct stg_targ_info *sti = (void *) ti;
351 u_int period, offset;
352
353 if ((msg & SCSI_LOW_MSG_WIDE) != 0)
354 {
355 if (ti->ti_width != SCSI_LOW_BUS_WIDTH_8)
356 {
357 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
358 return EINVAL;
359 }
360 return 0;
361 }
362
363 if ((msg & SCSI_LOW_MSG_SYNCH) == 0)
364 return 0;
365
366 period = ti->ti_maxsynch.period;
367 offset = ti->ti_maxsynch.offset;
368 period = period << 2;
369 if (period >= 200)
370 {
371 sti->sti_reg_synch = (period - 200) / 50;
372 if (period % 50)
373 sti->sti_reg_synch ++;
374 sti->sti_reg_synch |= SSCTL_SYNCHEN;
375 }
376 else if (period >= 100)
377 {
378 sti->sti_reg_synch = (period - 100) / 50;
379 if (period % 50)
380 sti->sti_reg_synch ++;
381 sti->sti_reg_synch |= SSCTL_SYNCHEN | SSCTL_FSYNCHEN;
382 }
383 bus_space_write_1(iot, ioh, tmc_ssctl, sti->sti_reg_synch);
384 return 0;
385}
386
387/**************************************************************
388 * General probe attach
389 **************************************************************/
390int
c436375a 391stgprobesubr(bus_space_tag_t iot, bus_space_handle_t ioh, u_int dvcfg)
984263bc
MD
392{
393 u_int16_t lsb, msb;
394
395 lsb = bus_space_read_1(iot, ioh, tmc_idlsb);
396 msb = bus_space_read_1(iot, ioh, tmc_idmsb);
397 switch (msb << 8 | lsb)
398 {
399 default:
400 return 0;
401 case 0x6127:
402 /* not support! */
403 return 0;
404 case 0x60e9:
405 return 1;
406 }
407 return 0;
408}
409
410int
c436375a 411stgprint(void *aux, const char *name)
984263bc
MD
412{
413
414 if (name != NULL)
415 printf("%s: scsibus ", name);
416 return UNCONF;
417}
418
419void
c436375a 420stgattachsubr(struct stg_softc *sc)
984263bc
MD
421{
422 struct scsi_low_softc *slp = &sc->sc_sclow;
423
424 printf("\n");
425
426 sc->sc_idbit = (1 << slp->sl_hostid);
427 slp->sl_funcs = &stgfuncs;
428 sc->sc_tmaxcnt = SCSI_LOW_MIN_TOUT * 1000 * 1000; /* default */
429
430 slp->sl_flags |= HW_READ_PADDING;
431 slp->sl_cfgflags |= CFG_ASYNC; /* XXX */
432
433 (void) scsi_low_attach(slp, 0, STG_NTARGETS, STG_NLUNS,
434 sizeof(struct stg_targ_info), 0);
435}
436
437/**************************************************************
438 * PDMA functions
439 **************************************************************/
440static __inline void
c436375a 441stg_pdma_end(struct stg_softc *sc, struct targ_info *ti)
984263bc
MD
442{
443 struct scsi_low_softc *slp = &sc->sc_sclow;
444 bus_space_tag_t iot = sc->sc_iot;
445 bus_space_handle_t ioh = sc->sc_ioh;
446 struct slccb *cb = slp->sl_Qnexus;
447 u_int len, tres;
448
449 slp->sl_flags &= ~HW_PDMASTART;
450 sc->sc_icinit &= ~ICTL_FIFO;
451 sc->sc_dataout_timeout = 0;
452
453 if (cb == NULL)
454 {
455 slp->sl_error |= PDMAERR;
456 goto out;
457 }
458
459 if (ti->ti_phase == PH_DATA)
460 {
461 len = bus_space_read_2(iot, ioh, tmc_fdcnt);
462 if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE)
463 {
464 if (len != 0)
465 {
466 tres = len + slp->sl_scp.scp_datalen;
467 if (tres <= (u_int) cb->ccb_scp.scp_datalen)
468 {
469 slp->sl_scp.scp_data -= len;
470 slp->sl_scp.scp_datalen = tres;
471 }
472 else
473 {
474 slp->sl_error |= PDMAERR;
475 printf("%s len %x >= datalen %x\n",
476 slp->sl_xname,
477 len, slp->sl_scp.scp_datalen);
478 }
479 }
480 }
481 else if (slp->sl_scp.scp_direction == SCSI_LOW_READ)
482 {
483 if (len != 0)
484 {
485 slp->sl_error |= PDMAERR;
486 printf("%s: len %x left in fifo\n",
487 slp->sl_xname, len);
488 }
489 }
490 scsi_low_data_finish(slp);
491 }
492 else
493 {
494
495 printf("%s data phase miss\n", slp->sl_xname);
496 slp->sl_error |= PDMAERR;
497 }
498
499out:
500 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit);
501}
502
503static void
c436375a 504stg_pio_read(struct stg_softc *sc, struct targ_info *ti, u_int thold)
984263bc
MD
505{
506 struct scsi_low_softc *slp = &sc->sc_sclow;
507 bus_space_tag_t iot = sc->sc_iot;
508 bus_space_handle_t ioh = sc->sc_ioh;
509 struct sc_p *sp = &slp->sl_scp;
2c9868e4 510 int tout;
984263bc
MD
511 u_int res;
512 u_int8_t stat;
513
514 if ((slp->sl_flags & HW_PDMASTART) == 0)
515 {
516 bus_space_write_1(iot, ioh, tmc_fctl,
517 sc->sc_fcRinit | FCTL_FIFOEN);
518 slp->sl_flags |= HW_PDMASTART;
519 }
520
521 tout = sc->sc_tmaxcnt;
522 while (tout -- > 0)
523 {
524 if (thold > 0)
525 {
2c9868e4 526 crit_enter();
984263bc
MD
527 res = bus_space_read_2(iot, ioh, tmc_fdcnt);
528 if (res < thold)
529 {
530 bus_space_write_1(iot, ioh, tmc_ictl,
531 sc->sc_icinit);
2c9868e4 532 crit_exit();
984263bc
MD
533 break;
534 }
2c9868e4 535 crit_exit();
984263bc
MD
536 }
537 else
538 {
539 stat = bus_space_read_1(iot, ioh, tmc_bstat);
540 res = bus_space_read_2(iot, ioh, tmc_fdcnt);
541 if (res == 0)
542 {
543 if ((stat & PHASE_MASK) != DATA_IN_PHASE)
544 break;
545 if (sp->scp_datalen <= 0)
546 break;
547 SCSI_LOW_DELAY(1);
548 continue;
549 }
550 }
551
552 /* The assumtion res != 0 is valid here */
553 if (res > sp->scp_datalen)
554 {
555 if (res == (u_int) -1)
556 break;
557
558 slp->sl_error |= PDMAERR;
559 if ((slp->sl_flags & HW_READ_PADDING) == 0)
560 {
561 printf("%s: read padding required\n",
562 slp->sl_xname);
563 break;
564 }
565
566 sp->scp_datalen = 0;
567 if (res > STG_MAX_DATA_SIZE)
568 res = STG_MAX_DATA_SIZE;
569 while (res -- > 0)
570 {
571 (void) bus_space_read_1(iot, ioh, tmc_rfifo);
572 }
573 continue;
574 }
575
576 sp->scp_datalen -= res;
577 if (res & 1)
578 {
579 *sp->scp_data = bus_space_read_1(iot, ioh, tmc_rfifo);
580 sp->scp_data ++;
581 res --;
582 }
583
584 bus_space_read_multi_2(iot, ioh, tmc_rfifo,
585 (u_int16_t *) sp->scp_data, res >> 1);
586 sp->scp_data += res;
587 }
588
589 if (tout <= 0)
590 printf("%s: pio read timeout\n", slp->sl_xname);
591}
592
593static void
c436375a 594stg_pio_write(struct stg_softc *sc, struct targ_info *ti, u_int thold)
984263bc
MD
595{
596 struct scsi_low_softc *slp = &sc->sc_sclow;
597 bus_space_tag_t iot = sc->sc_iot;
598 bus_space_handle_t ioh = sc->sc_ioh;
599 struct sc_p *sp = &slp->sl_scp;
600 u_int res;
a6a7d26b 601 int tout;
f96d6c88 602 u_int8_t stat;
984263bc
MD
603
604 if ((slp->sl_flags & HW_PDMASTART) == 0)
605 {
606 stat = sc->sc_fcWinit | FCTL_FIFOEN | FCTL_FIFOW;
607 bus_space_write_1(iot, ioh, tmc_fctl, stat | FCTL_CLRFIFO);
608 bus_space_write_1(iot, ioh, tmc_fctl, stat);
609 slp->sl_flags |= HW_PDMASTART;
610 }
611
612 tout = sc->sc_tmaxcnt;
613 while (tout -- > 0)
614 {
615 stat = bus_space_read_1(iot, ioh, tmc_bstat);
616 if ((stat & PHASE_MASK) != DATA_OUT_PHASE)
617 break;
618
619 if (sp->scp_datalen <= 0)
620 {
621 if (sc->sc_dataout_timeout == 0)
622 sc->sc_dataout_timeout = SCSI_LOW_TIMEOUT_HZ;
623 break;
624 }
625
626 if (thold > 0)
627 {
2c9868e4 628 crit_enter();
984263bc
MD
629 res = bus_space_read_2(iot, ioh, tmc_fdcnt);
630 if (res > thold)
631 {
632 bus_space_write_1(iot, ioh, tmc_ictl,
633 sc->sc_icinit);
2c9868e4 634 crit_exit();
984263bc
MD
635 break;
636 }
2c9868e4 637 crit_exit();
984263bc
MD
638 }
639 else
640 {
641 res = bus_space_read_2(iot, ioh, tmc_fdcnt);
642 if (res > sc->sc_maxwsize / 2)
643 {
644 SCSI_LOW_DELAY(1);
645 continue;
646 }
647 }
648
649 if (res == (u_int) -1)
650 break;
651 res = sc->sc_maxwsize - res;
652 if (res > sp->scp_datalen)
653 res = sp->scp_datalen;
654
655 sp->scp_datalen -= res;
656 if ((res & 0x1) != 0)
657 {
658 bus_space_write_1(iot, ioh, tmc_wfifo, *sp->scp_data);
659 sp->scp_data ++;
660 res --;
661 }
662
663 bus_space_write_multi_2(iot, ioh, tmc_wfifo,
664 (u_int16_t *) sp->scp_data, res >> 1);
665 sp->scp_data += res;
666 }
667
668 if (tout <= 0)
669 printf("%s: pio write timeout\n", slp->sl_xname);
670}
671
672static int
c436375a 673stg_negate_signal(struct stg_softc *sc, u_int8_t mask, u_char *s)
984263bc
MD
674{
675 struct scsi_low_softc *slp = &sc->sc_sclow;
676 bus_space_tag_t bst = sc->sc_iot;
677 bus_space_handle_t bsh = sc->sc_ioh;
678 int wc;
679 u_int8_t regv;
680
681 for (wc = 0; wc < STG_DELAY_MAX / STG_DELAY_INTERVAL; wc ++)
682 {
683 regv = bus_space_read_1(bst, bsh, tmc_bstat);
684 if (regv == (u_int8_t) -1)
685 return -1;
686 if ((regv & mask) == 0)
687 return 1;
688
689 SCSI_LOW_DELAY(STG_DELAY_INTERVAL);
690 }
691
692 printf("%s: %s stg_negate_signal timeout\n", slp->sl_xname, s);
693 return -1;
694}
695
696static int
c436375a 697stg_expect_signal(struct stg_softc *sc, u_int8_t phase, u_int8_t mask)
984263bc
MD
698{
699 struct scsi_low_softc *slp = &sc->sc_sclow;
700 bus_space_tag_t bst = sc->sc_iot;
701 bus_space_handle_t bsh = sc->sc_ioh;
702 int wc;
703 u_int8_t ph;
704
705 phase &= PHASE_MASK;
706 for (wc = 0; wc < STG_DELAY_MAX / STG_DELAY_INTERVAL; wc ++)
707 {
708 ph = bus_space_read_1(bst, bsh, tmc_bstat);
709 if (ph == (u_int8_t) -1)
710 return -1;
711 if ((ph & PHASE_MASK) != phase)
712 return 0;
713 if ((ph & mask) != 0)
714 return 1;
715
716 SCSI_LOW_DELAY(STG_DELAY_INTERVAL);
717 }
718
719 printf("%s: stg_expect_signal timeout\n", slp->sl_xname);
720 return -1;
721}
722
723static int
c436375a
SW
724stg_xfer(struct stg_softc *sc, u_int8_t *buf, int len, int phase,
725 int clear_atn)
984263bc
MD
726{
727 bus_space_tag_t iot = sc->sc_iot;
728 bus_space_handle_t ioh = sc->sc_ioh;
729 int rv, ptr;
730
731 if (phase & BSTAT_IO)
732 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit);
733 else
734 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcWinit);
735
736 for (ptr = 0; len > 0; len --)
737 {
738 rv = stg_expect_signal(sc, phase, BSTAT_REQ);
739 if (rv <= 0)
740 goto bad;
741
742 if (len == 1 && clear_atn != 0)
743 {
744 sc->sc_busc &= ~BCTL_ATN;
745 stghw_bcr_write_1(sc, sc->sc_busc);
746 SCSI_LOW_DEASSERT_ATN(&sc->sc_sclow);
747 }
748
749 if (phase & BSTAT_IO)
750 {
751 buf[ptr ++] = bus_space_read_1(iot, ioh, tmc_rdata);
752 }
753 else
754 {
755 bus_space_write_1(iot, ioh, tmc_wdata, buf[ptr ++]);
756 }
757
758 stg_negate_signal(sc, BSTAT_ACK, "xfer<ACK>");
759 }
760
761bad:
762 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit);
763 return len;
764}
765
766/**************************************************************
767 * disconnect & reselect (HW low)
768 **************************************************************/
769static int
c436375a 770stg_reselected(struct stg_softc *sc)
984263bc
MD
771{
772 struct scsi_low_softc *slp = &sc->sc_sclow;
773 bus_space_tag_t iot = sc->sc_iot;
774 bus_space_handle_t ioh = sc->sc_ioh;
775 int tout;
776 u_int sid;
777 u_int8_t regv;
778
779 if (slp->sl_selid != NULL)
780 {
781 /* XXX:
782 * Selection vs Reselection conflicts.
783 */
784 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit);
785 stghw_bcr_write_1(sc, BCTL_BUSFREE);
786 }
787 else if (slp->sl_Tnexus != NULL)
788 {
789 printf("%s: unexpected termination\n", slp->sl_xname);
790 stg_disconnected(sc, slp->sl_Tnexus);
791 }
792
793 /* XXX:
794 * We should ack the reselection as soon as possible,
053d6fd4 795 * because the target would abort the current reselection seq
984263bc
MD
796 * due to reselection timeout.
797 */
798 tout = STG_DELAY_SELECT_POLLING_MAX;
799 while (tout -- > 0)
800 {
801 regv = bus_space_read_1(iot, ioh, tmc_bstat);
802 if ((regv & (BSTAT_IO | BSTAT_SEL | BSTAT_BSY)) ==
803 (BSTAT_IO | BSTAT_SEL))
804 {
805 SCSI_LOW_DELAY(1);
806 regv = bus_space_read_1(iot, ioh, tmc_bstat);
807 if ((regv & (BSTAT_IO | BSTAT_SEL | BSTAT_BSY)) ==
808 (BSTAT_IO | BSTAT_SEL))
809 goto reselect_start;
810 }
811 SCSI_LOW_DELAY(1);
812 }
813 printf("%s: reselction timeout I\n", slp->sl_xname);
814 return EJUSTRETURN;
815
816reselect_start:
817 sid = (u_int) bus_space_read_1(iot, ioh, tmc_scsiid);
818 if ((sid & sc->sc_idbit) == 0)
819 {
820 /* not us */
821 return EJUSTRETURN;
822 }
823
824 bus_space_write_1(iot, ioh, tmc_fctl,
825 sc->sc_fcRinit | FCTL_CLRFIFO | FCTL_CLRINT);
826 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit);
827 stghw_bcr_write_1(sc, sc->sc_busc | BCTL_BSY);
828
829 while (tout -- > 0)
830 {
831 regv = bus_space_read_1(iot, ioh, tmc_bstat);
832 if ((regv & (BSTAT_SEL | BSTAT_BSY)) == BSTAT_BSY)
833 goto reselected;
834 SCSI_LOW_DELAY(1);
835 }
836 printf("%s: reselction timeout II\n", slp->sl_xname);
837 return EJUSTRETURN;
838
839reselected:
840 sid &= ~sc->sc_idbit;
841 sid = ffs(sid) - 1;
842 if (scsi_low_reselected(slp, sid) == NULL)
843 return EJUSTRETURN;
844
845#ifdef STG_STATICS
846 stg_statics.reselect ++;
847#endif /* STG_STATICS */
848 return EJUSTRETURN;
849}
850
851static int
c436375a 852stg_disconnected(struct stg_softc *sc, struct targ_info *ti)
984263bc
MD
853{
854 struct scsi_low_softc *slp = &sc->sc_sclow;
855 bus_space_tag_t iot = sc->sc_iot;
856 bus_space_handle_t ioh = sc->sc_ioh;
857
858 /* clear bus status & fifo */
859 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit | FCTL_CLRFIFO);
860 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit);
861 stghw_bcr_write_1(sc, BCTL_BUSFREE);
862 sc->sc_icinit &= ~ICTL_FIFO;
863 sc->sc_busc &= ~BCTL_ATN;
864 sc->sc_dataout_timeout = 0;
865 sc->sc_ubf_timeout = 0;
866
867#ifdef STG_STATICS
868 stg_statics.disconnect ++;
869#endif /* STG_STATICS */
870 scsi_low_disconnected(slp, ti);
871 return 1;
872}
873
874/**************************************************************
875 * SEQUENCER
876 **************************************************************/
877static int
c436375a 878stg_target_nexus_establish(struct stg_softc *sc)
984263bc
MD
879{
880 struct scsi_low_softc *slp = &sc->sc_sclow;
881 bus_space_tag_t iot = sc->sc_iot;
882 bus_space_handle_t ioh = sc->sc_ioh;
883 struct targ_info *ti = slp->sl_Tnexus;
884 struct stg_targ_info *sti = (void *) ti;
885
886 bus_space_write_1(iot, ioh, tmc_ssctl, sti->sti_reg_synch);
887 if ((stg_io_control & STG_FIFO_INTERRUPTS) != 0)
888 {
889 sc->sc_icinit |= ICTL_FIFO;
890 }
891 return 0;
892}
893
894static int
c436375a 895stg_lun_nexus_establish(struct stg_softc *sc)
984263bc
MD
896{
897
898 return 0;
899}
900
901static int
c436375a 902stg_ccb_nexus_establish(struct stg_softc *sc)
984263bc
MD
903{
904 struct scsi_low_softc *slp = &sc->sc_sclow;
905 struct slccb *cb = slp->sl_Qnexus;
906
907 sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000;
908 return 0;
909}
910
911#define STGHW_SELECT_INTERVAL 10
912
913static int
c436375a 914stghw_select_targ_wait(struct stg_softc *sc, int mu)
984263bc
MD
915{
916 bus_space_tag_t iot = sc->sc_iot;
917 bus_space_handle_t ioh = sc->sc_ioh;
918
919 mu = mu / STGHW_SELECT_INTERVAL;
920 while (mu -- > 0)
921 {
922 if ((bus_space_read_1(iot, ioh, tmc_bstat) & BSTAT_BSY) == 0)
923 {
924 SCSI_LOW_DELAY(STGHW_SELECT_INTERVAL);
925 continue;
926 }
927 SCSI_LOW_DELAY(1);
928 if ((bus_space_read_1(iot, ioh, tmc_bstat) & BSTAT_BSY) != 0)
929 {
930 return 0;
931 }
932 }
933 return ENXIO;
934}
935
936static void
c436375a 937stg_selection_done_and_expect_msgout(struct stg_softc *sc)
984263bc
MD
938{
939 struct scsi_low_softc *slp = &sc->sc_sclow;
940 bus_space_tag_t iot = sc->sc_iot;
941 bus_space_handle_t ioh = sc->sc_ioh;
942
943 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit | FCTL_CLRFIFO);
944 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit);
945 stghw_bcr_write_1(sc, sc->sc_imsg | sc->sc_busc);
946 SCSI_LOW_ASSERT_ATN(slp);
947}
948
949int
c436375a 950stgintr(void *arg)
984263bc
MD
951{
952 struct stg_softc *sc = arg;
953 struct scsi_low_softc *slp = &sc->sc_sclow;
954 bus_space_tag_t iot = sc->sc_iot;
955 bus_space_handle_t ioh = sc->sc_ioh;
956 struct targ_info *ti;
957 struct physio_proc *pp;
958 struct buf *bp;
959 u_int derror, flags;
2c9868e4 960 int len;
984263bc
MD
961 u_int8_t status, astatus, regv;
962
963 /*******************************************
964 * interrupt check
965 *******************************************/
966 if (slp->sl_flags & HW_INACTIVE)
967 return 0;
968
969 astatus = bus_space_read_1(iot, ioh, tmc_astat);
970 status = bus_space_read_1(iot, ioh, tmc_bstat);
971
972 if ((astatus & ASTAT_STATMASK) == 0 || astatus == (u_int8_t) -1)
973 return 0;
974
975 bus_space_write_1(iot, ioh, tmc_ictl, 0);
976 if (astatus & ASTAT_SCSIRST)
977 {
978 bus_space_write_1(iot, ioh, tmc_fctl,
979 sc->sc_fcRinit | FCTL_CLRFIFO);
980 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit);
981 bus_space_write_1(iot, ioh, tmc_ictl, 0);
982
983 scsi_low_restart(slp, SCSI_LOW_RESTART_SOFT,
984 "bus reset (power off?)");
985 return 1;
986 }
987
988 /*******************************************
989 * debug section
990 *******************************************/
991#ifdef STG_DEBUG
992 if (stg_debug)
993 {
994 scsi_low_print(slp, NULL);
995 printf("%s: st %x ist %x\n\n", slp->sl_xname,
996 status, astatus);
997#ifdef DDB
998 if (stg_debug > 1)
999 SCSI_LOW_DEBUGGER("stg");
1000#endif /* DDB */
1001 }
1002#endif /* STG_DEBUG */
1003
1004 /*******************************************
1005 * reselection & nexus
1006 *******************************************/
1007 if ((status & RESEL_PHASE_MASK)== PHASE_RESELECTED)
1008 {
1009 if (stg_reselected(sc) == EJUSTRETURN)
1010 goto out;
1011 }
1012
1013 if ((ti = slp->sl_Tnexus) == NULL)
1014 return 0;
1015
1016 derror = 0;
1017 if ((astatus & ASTAT_PARERR) != 0 && ti->ti_phase != PH_ARBSTART &&
1018 (sc->sc_fcRinit & FCTL_PARENB) != 0)
1019 {
1020 slp->sl_error |= PARITYERR;
1021 derror = SCSI_LOW_DATA_PE;
1022 if ((status & PHASE_MASK) == MESSAGE_IN_PHASE)
1023 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
1024 else
1025 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ERROR, 1);
1026 }
1027
1028 /*******************************************
1029 * aribitration & selection
1030 *******************************************/
1031 switch (ti->ti_phase)
1032 {
1033 case PH_ARBSTART:
1034 if ((astatus & ASTAT_ARBIT) == 0)
1035 {
1036#ifdef STG_STATICS
1037 stg_statics.arbit_fail_0 ++;
1038#endif /* STG_STATICS */
1039 goto arb_fail;
1040 }
1041
1042 status = bus_space_read_1(iot, ioh, tmc_bstat);
1043 if ((status & BSTAT_IO) != 0)
1044 {
1045 /* XXX:
1046 * Selection vs Reselection conflicts.
1047 */
1048#ifdef STG_STATICS
1049 stg_statics.arbit_fail_1 ++;
1050#endif /* STG_STATICS */
1051arb_fail:
1052 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit);
1053 stghw_bcr_write_1(sc, BCTL_BUSFREE);
1054 scsi_low_arbit_fail(slp, slp->sl_Qnexus);
1055 goto out;
1056 }
1057
1058 /*
1059 * selection assert start.
1060 */
1061 SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART);
1062 scsi_low_arbit_win(slp);
1063
2c9868e4 1064 crit_enter();
984263bc
MD
1065 bus_space_write_1(iot, ioh, tmc_scsiid,
1066 sc->sc_idbit | (1 << ti->ti_id));
1067 stghw_bcr_write_1(sc, sc->sc_imsg | sc->sc_busc | BCTL_SEL);
1068 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcWinit);
1069 if ((stg_io_control & STG_WAIT_FOR_SELECT) != 0)
1070 {
1071 /* selection abort delay 200 + 100 micro sec */
1072 if (stghw_select_targ_wait(sc, 300) == 0)
1073 {
1074 SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED);
1075 stg_selection_done_and_expect_msgout(sc);
1076 }
1077 }
2c9868e4 1078 crit_exit();
984263bc
MD
1079 goto out;
1080
1081 case PH_SELSTART:
1082 if ((status & BSTAT_BSY) == 0)
1083 {
1084 /* selection timeout delay 250 ms */
1085 if (stghw_select_targ_wait(sc, 250 * 1000) != 0)
1086 {
1087 stg_disconnected(sc, ti);
1088 goto out;
1089 }
1090 }
1091
1092 SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED);
1093 stg_selection_done_and_expect_msgout(sc);
1094 goto out;
1095
1096 case PH_SELECTED:
1097 if ((status & BSTAT_REQ) == 0)
1098 goto out;
1099 stg_target_nexus_establish(sc);
1100 break;
1101
1102 case PH_RESEL:
1103 if ((status & BSTAT_REQ) == 0)
1104 goto out;
1105
1106 /* clear a busy line */
1107 bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit);
1108 stghw_bcr_write_1(sc, sc->sc_busc);
1109 stg_target_nexus_establish(sc);
1110 if ((status & PHASE_MASK) != MESSAGE_IN_PHASE)
1111 {
1112 printf("%s: unexpected phase after reselect\n",
1113 slp->sl_xname);
1114 slp->sl_error |= FATALIO;
1115 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1);
1116 goto out;
1117 }
1118 break;
1119 }
1120
1121 /*******************************************
1122 * data phase
1123 *******************************************/
1124 if ((slp->sl_flags & HW_PDMASTART) && STG_IS_PHASE_DATA(status) == 0)
1125 {
1126 if (slp->sl_scp.scp_direction == SCSI_LOW_READ)
1127 stg_pio_read(sc, ti, 0);
1128
1129 stg_pdma_end(sc, ti);
1130 }
1131
1132 /*******************************************
1133 * scsi seq
1134 *******************************************/
1135 switch (status & PHASE_MASK)
1136 {
1137 case COMMAND_PHASE:
1138 if (stg_expect_signal(sc, COMMAND_PHASE, BSTAT_REQ) <= 0)
1139 break;
1140
1141 SCSI_LOW_SETUP_PHASE(ti, PH_CMD);
1142 if (scsi_low_cmd(slp, ti) != 0)
1143 {
1144 scsi_low_attention(slp);
1145 }
1146
1147 if (stg_xfer(sc, slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen,
1148 COMMAND_PHASE, 0) != 0)
1149 {
1150 printf("%s: CMDOUT short\n", slp->sl_xname);
1151 }
1152 break;
1153
1154 case DATA_OUT_PHASE:
1155 SCSI_LOW_SETUP_PHASE(ti, PH_DATA);
1156 if (scsi_low_data(slp, ti, &bp, SCSI_LOW_WRITE) != 0)
1157 {
1158 scsi_low_attention(slp);
1159 }
1160
1161 pp = physio_proc_enter(bp);
1162 if ((sc->sc_icinit & ICTL_FIFO) != 0)
1163 stg_pio_write(sc, ti, sc->sc_wthold);
1164 else
1165 stg_pio_write(sc, ti, 0);
1166 physio_proc_leave(pp);
1167 break;
1168
1169 case DATA_IN_PHASE:
1170 SCSI_LOW_SETUP_PHASE(ti, PH_DATA);
1171 if (scsi_low_data(slp, ti, &bp, SCSI_LOW_READ) != 0)
1172 {
1173 scsi_low_attention(slp);
1174 }
1175
1176 pp = physio_proc_enter(bp);
1177 if ((sc->sc_icinit & ICTL_FIFO) != 0)
1178 stg_pio_read(sc, ti, sc->sc_rthold);
1179 else
1180 stg_pio_read(sc, ti, 0);
1181 physio_proc_leave(pp);
1182 break;
1183
1184 case STATUS_PHASE:
1185 regv = stg_expect_signal(sc, STATUS_PHASE, BSTAT_REQ);
1186 if (regv <= 0)
1187 break;
1188
1189 SCSI_LOW_SETUP_PHASE(ti, PH_STAT);
1190 regv = bus_space_read_1(iot, ioh, tmc_sdna);
1191 if (scsi_low_statusin(slp, ti, regv | derror) != 0)
1192 {
1193 scsi_low_attention(slp);
1194 }
1195 if (regv != bus_space_read_1(iot, ioh, tmc_rdata))
1196 {
1197 printf("%s: STATIN: data mismatch\n", slp->sl_xname);
1198 }
1199 stg_negate_signal(sc, BSTAT_ACK, "statin<ACK>");
1200 break;
1201
1202 case MESSAGE_OUT_PHASE:
1203 if (stg_expect_signal(sc, MESSAGE_OUT_PHASE, BSTAT_REQ) <= 0)
1204 break;
1205
1206 SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT);
1207 flags = (ti->ti_ophase != ti->ti_phase) ?
1208 SCSI_LOW_MSGOUT_INIT : 0;
1209 len = scsi_low_msgout(slp, ti, flags);
1210
1211 if (len > 1 && slp->sl_atten == 0)
1212 {
1213 scsi_low_attention(slp);
1214 }
1215
1216 if (stg_xfer(sc, ti->ti_msgoutstr, len, MESSAGE_OUT_PHASE,
1217 slp->sl_clear_atten) != 0)
1218 {
1219 printf("%s: MSGOUT short\n", slp->sl_xname);
1220 }
1221 else
1222 {
1223 if (slp->sl_msgphase >= MSGPH_ABORT)
1224 {
1225 stg_disconnected(sc, ti);
1226 }
1227 }
1228 break;
1229
1230 case MESSAGE_IN_PHASE:
1231 /* confirm phase and req signal */
1232 if (stg_expect_signal(sc, MESSAGE_IN_PHASE, BSTAT_REQ) <= 0)
1233 break;
1234
1235 SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
1236
1237 /* read data with NOACK */
1238 regv = bus_space_read_1(iot, ioh, tmc_sdna);
1239
1240 if (scsi_low_msgin(slp, ti, derror | regv) == 0)
1241 {
1242 if (scsi_low_is_msgout_continue(ti, 0) != 0)
1243 {
1244 scsi_low_attention(slp);
1245 }
1246 }
1247
1248 /* read data with ACK */
1249 if (regv != bus_space_read_1(iot, ioh, tmc_rdata))
1250 {
1251 printf("%s: MSGIN: data mismatch\n", slp->sl_xname);
1252 }
1253
1254 /* wait for the ack negated */
1255 stg_negate_signal(sc, BSTAT_ACK, "msgin<ACK>");
1256
1257 if (slp->sl_msgphase != 0 && slp->sl_msgphase < MSGPH_ABORT)
1258 {
1259 stg_disconnected(sc, ti);
1260 }
1261 break;
1262
1263 case BUSFREE_PHASE:
1264 printf("%s: unexpected disconnect\n", slp->sl_xname);
1265 stg_disconnected(sc, ti);
1266 break;
1267
1268 default:
1269 slp->sl_error |= FATALIO;
1270 printf("%s: unknown phase bus %x intr %x\n",
1271 slp->sl_xname, status, astatus);
1272 break;
1273 }
1274
1275out:
1276 bus_space_write_1(iot, ioh, tmc_ictl, sc->sc_icinit);
1277 return 1;
1278}
1279
1280static int
c436375a 1281stg_timeout(struct stg_softc *sc)
984263bc
MD
1282{
1283 struct scsi_low_softc *slp = &sc->sc_sclow;
1284 bus_space_tag_t iot = sc->sc_iot;
1285 bus_space_handle_t ioh = sc->sc_ioh;
1286 int tout, count;
1287 u_int8_t status;
1288
1289 if (slp->sl_Tnexus == NULL)
1290 return 0;
1291
1292 status = bus_space_read_1(iot, ioh, tmc_bstat);
1293 if ((status & PHASE_MASK) == 0)
1294 {
1295 if (sc->sc_ubf_timeout ++ == 0)
1296 return 0;
1297
1298 printf("%s: unexpected bus free detected\n", slp->sl_xname);
1299 slp->sl_error |= FATALIO;
1300 scsi_low_print(slp, slp->sl_Tnexus);
1301 stg_disconnected(sc, slp->sl_Tnexus);
1302 return 0;
1303 }
1304
1305 switch (status & PHASE_MASK)
1306 {
1307 case DATA_OUT_PHASE:
1308 if (sc->sc_dataout_timeout == 0)
1309 break;
1310 if ((status & BSTAT_REQ) == 0)
1311 break;
1312 if (bus_space_read_2(iot, ioh, tmc_fdcnt) != 0)
1313 break;
1314 if ((-- sc->sc_dataout_timeout) > 0)
1315 break;
1316
1317 slp->sl_error |= PDMAERR;
1318 if ((slp->sl_flags & HW_WRITE_PADDING) == 0)
1319 {
1320 printf("%s: write padding required\n",
1321 slp->sl_xname);
1322 break;
1323 }
1324
1325 bus_space_write_1(iot, ioh, tmc_ictl, 0);
1326
1327 tout = STG_DELAY_MAX;
1328 while (tout --)
1329 {
1330 status = bus_space_read_1(iot, ioh, tmc_bstat);
1331 if ((status & PHASE_MASK) != DATA_OUT_PHASE)
1332 break;
1333
1334 if (bus_space_read_2(iot, ioh, tmc_fdcnt) != 0)
1335 {
1336 SCSI_LOW_DELAY(1);
1337 continue;
1338 }
1339
1340 for (count = sc->sc_maxwsize; count > 0; count --)
1341 bus_space_write_1(iot, ioh, tmc_wfifo, 0);
1342 }
1343
1344 status = bus_space_read_1(iot, ioh, tmc_bstat);
1345 if ((status & PHASE_MASK) == DATA_OUT_PHASE)
1346 sc->sc_dataout_timeout = SCSI_LOW_TIMEOUT_HZ;
1347
1348 bus_space_write_1(iot, ioh, tmc_ictl, sc->sc_icinit);
1349 break;
1350
1351 default:
1352 break;
1353 }
1354 return 0;
1355}