remove __P() from this directory
[dragonfly.git] / sys / dev / disk / i386 / bs / bs.c
CommitLineData
984263bc
MD
1/* $NecBSD: bs.c,v 1.1 1997/07/18 09:18:59 kmatsuda Exp $ */
2/* $NetBSD$ */
3/* $FreeBSD: src/sys/i386/isa/bs/bs.c,v 1.8 1999/12/03 11:58:11 nyan Exp $ */
38e94a25 4/* $DragonFly: src/sys/dev/disk/i386/bs/Attic/bs.c,v 1.5 2003/08/27 10:35:16 rob Exp $ */
984263bc
MD
5/*
6 * [NetBSD for NEC PC98 series]
7 * Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33/*
34 * Copyright (c) 1994, 1995, 1996 Naofumi HONDA. All rights reserved.
35 */
36
37#ifdef __NetBSD__
38#include <i386/Cbus/dev/bs/bsif.h>
39#endif
40#ifdef __FreeBSD__
1f2de5d4 41#include "bsif.h"
984263bc
MD
42#endif
43
1f2de5d4
MD
44#include <bus/cam/cam.h>
45#include <bus/cam/cam_ccb.h>
46#include <bus/cam/cam_sim.h>
47#include <bus/cam/cam_xpt_sim.h>
48#include <bus/cam/cam_debug.h>
984263bc 49
1f2de5d4
MD
50#include <bus/cam/scsi/scsi_all.h>
51#include <bus/cam/scsi/scsi_message.h>
984263bc
MD
52
53/*****************************************************************
54 * Inline phase funcs
55 *****************************************************************/
56/* static inline declare */
38e94a25
RG
57static BS_INLINE struct targ_info *bs_reselect (struct bs_softc *);
58static BS_INLINE void bs_sat_continue (struct bs_softc *, struct targ_info *, struct bsccb *);
59static BS_INLINE struct targ_info *bs_selected (struct bs_softc *, struct targ_info *, struct bsccb *);
60static BS_INLINE u_int8_t bs_read_1byte (struct bs_softc *);
61static BS_INLINE void bs_write_1byte (struct bs_softc *, u_int8_t);
62static BS_INLINE void bs_commandout (struct bs_softc *, struct targ_info *, struct bsccb *);
63static BS_INLINE void bs_status_check (struct bs_softc *, struct targ_info *);
64static BS_INLINE void bs_msgin (struct bs_softc *, struct targ_info *);
65static BS_INLINE void bs_msgout (struct bs_softc *, struct targ_info *, struct bsccb *);
66static BS_INLINE void bs_disconnect_phase (struct bs_softc *, struct targ_info *, struct bsccb *);
67static void bs_phase_error (struct targ_info *, struct bsccb *);
68static int bs_scsi_cmd_poll_internal (struct targ_info *);
69static int bs_xfer (struct bs_softc *, char *, int);
70static void bs_io_xfer (struct targ_info *);
71static void bs_quick_abort (struct targ_info *, u_int);
72static void bs_msgin_error (struct targ_info *, u_int);
73static void bs_msgin_ext (struct targ_info *);
74static void bs_msg_reject (struct targ_info *);
75static void bshoststart (struct bs_softc *, struct targ_info *);
984263bc
MD
76
77/*****************************************************************
78 * SIM interface
79 *****************************************************************/
80void
81bs_scsi_cmd(struct cam_sim *sim, union ccb *ccb)
82{
83 struct bs_softc *bsc = (struct bs_softc *) cam_sim_softc(sim);
84 int s, target = (u_int) (ccb->ccb_h.target_id);
85 struct targ_info *ti;
86 struct bsccb *cb;
87
88 switch (ccb->ccb_h.func_code) {
89 case XPT_SCSI_IO: /* Execute the requested I/O operation */
90 ti = bsc->sc_ti[target];
91 if ((cb = bs_get_ccb()) == NULL) {
92 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
93 xpt_done(ccb);
94 return;
95 }
96
97 /* make up ccb! */
98 cb->ccb = ccb;
99 cb->lun = ccb->ccb_h.target_lun;
100 cb->cmd = ccb->csio.cdb_io.cdb_bytes;
101 cb->cmdlen = (int) ccb->csio.cdb_len;
102 cb->data = ccb->csio.data_ptr;
103 cb->datalen = (int) ccb->csio.dxfer_len;
104 cb->rcnt = 0;
105 cb->msgoutlen = 0;
106 cb->bsccb_flags = 0;
107 bs_targ_flags(ti, cb);
108 cb->tcmax = 0;/*(xs->timeout >> 10); default HN2*/
109 if (cb->tcmax < BS_DEFAULT_TIMEOUT_SECOND)
110 cb->tcmax = BS_DEFAULT_TIMEOUT_SECOND;
111
112 s = splcam();
113
114 TAILQ_INSERT_TAIL(&ti->ti_ctab, cb, ccb_chain);
115
116 if (ti->ti_phase == FREE) {
117 if (ti->ti_state == BS_TARG_START)
118 bs_start_syncmsg(ti, NULL, BS_SYNCMSG_ASSERT);
119 bscmdstart(ti, BSCMDSTART);
120 }
121
122 splx(s);
123 break;
124 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
125 case XPT_EN_LUN: /* Enable LUN as a target */
126 case XPT_TARGET_IO: /* Execute target I/O request */
127 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
128 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
129 case XPT_ABORT: /* Abort the specified CCB */
130 /* XXX Implement */
131 ccb->ccb_h.status = CAM_REQ_INVALID;
132 xpt_done(ccb);
133 break;
134 case XPT_SET_TRAN_SETTINGS:
135 /* XXX Implement */
136 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
137 xpt_done(ccb);
138 break;
139 case XPT_GET_TRAN_SETTINGS: {
140 struct ccb_trans_settings *cts;
141 struct targ_info *ti;
142 /*int s;*/
143
144 cts = &ccb->cts;
145 ti = bsc->sc_ti[ccb->ccb_h.target_id];
146 /*s = splcam();*/
147 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) {
148 if (ti->ti_cfgflags & BS_SCSI_DISC)
149 cts->flags = CCB_TRANS_DISC_ENB;
150 else
151 cts->flags = 0;
152 if (ti->ti_cfgflags & BS_SCSI_QTAG)
153 cts->flags |= CCB_TRANS_TAG_ENB;
154 cts->sync_period = ti->ti_syncnow.period;
155 cts->sync_offset = ti->ti_syncnow.offset;
156 cts->bus_width = 0;/*HN2*/
157
158 cts->valid = CCB_TRANS_SYNC_RATE_VALID
159 | CCB_TRANS_SYNC_OFFSET_VALID
160 | CCB_TRANS_BUS_WIDTH_VALID
161 | CCB_TRANS_DISC_VALID
162 | CCB_TRANS_TQ_VALID;
163 ccb->ccb_h.status = CAM_REQ_CMP;
164 } else
165 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
166
167 /*splx(s);*/
168 xpt_done(ccb);
169 break;
170 }
171 case XPT_CALC_GEOMETRY: { /* not yet HN2 */
172 struct ccb_calc_geometry *ccg;
173 u_int32_t size_mb;
174 u_int32_t secs_per_cylinder;
175
176 ccg = &ccb->ccg;
177 size_mb = ccg->volume_size
178 / ((1024L * 1024L) / ccg->block_size);
179
180 ccg->heads = 8;
181 ccg->secs_per_track = 34;
182
183 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
184 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
185 ccb->ccb_h.status = CAM_REQ_CMP;
186 xpt_done(ccb);
187 break;
188 }
189 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
190 bshw_chip_reset(bsc); /* XXX need perfect RESET? */
191 ccb->ccb_h.status = CAM_REQ_CMP;
192 xpt_done(ccb);
193 break;
194 case XPT_TERM_IO: /* Terminate the I/O process */
195 /* XXX Implement */
196 ccb->ccb_h.status = CAM_REQ_INVALID;
197 xpt_done(ccb);
198 break;
199 case XPT_PATH_INQ: { /* Path routing inquiry */
200 struct ccb_pathinq *cpi = &ccb->cpi;
201
202 cpi->version_num = 1; /* XXX??? */
203 cpi->hba_inquiry = PI_SDTR_ABLE;
204 cpi->target_sprt = 0;
205 cpi->hba_misc = 0;
206 cpi->hba_eng_cnt = 0;
207 cpi->max_target = NTARGETS - 1;
208 cpi->max_lun = 7;
209 cpi->initiator_id = bsc->sc_hostid;
210 cpi->bus_id = cam_sim_bus(sim);
211 cpi->base_transfer_speed = 3300;
212 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
213 strncpy(cpi->hba_vid, "NEC", HBA_IDLEN);
214 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
215 cpi->unit_number = cam_sim_unit(sim);
216 cpi->ccb_h.status = CAM_REQ_CMP;
217 xpt_done(ccb);
218 break;
219 }
220 default:
221/*printf("bs: non support func_code = %d ", ccb->ccb_h.func_code);*/
222 ccb->ccb_h.status = CAM_REQ_INVALID;
223 xpt_done(ccb);
224 break;
225 }
226}
227
228/**************************************************
229 * ### NEXUS START and TERMINATE ###
230 **************************************************/
231/*
232 * FLAGS : BSCMDRESTART restart in case of error.
233 */
234int
235bscmdstart(ti, flags)
236 struct targ_info *ti;
237 int flags;
238{
239 struct bsccb *cb;
240 struct bs_softc *bsc = ti->ti_bsc;
241
242 if ((cb = ti->ti_ctab.tqh_first) == NULL)
243 {
244 if (bsc->sc_nexus == NULL)
245 bshoststart(bsc, NULL);
246 return 0;
247 }
248
249 ti->ti_lun = cb->lun;
250 ti->ti_error = 0;
251 ti->ti_scsp.data = cb->data;
252 ti->ti_scsp.datalen = cb->datalen;
253 ti->ti_scsp.seglen = 0;
254 if (cb->rcnt)
255 cb->bsccb_flags &= ~(BSSAT | BSLINK);
256 ti->ti_flags &= ~BSCFLAGSMASK;
257 ti->ti_flags |= cb->bsccb_flags & BSCFLAGSMASK;
258 cb->tc = cb->tcmax;
259
260 /* GO GO */
261 if (ti->ti_phase == FREE)
262 {
263 if (bsc->sc_nexus == NULL)
264 bshoststart(bsc, ti);
265 else
266 {
267 if (flags & BSCMDRESTART)
268 bs_hostque_head(bsc, ti);
269 else
270 bs_hostque_tail(bsc, ti);
271 BS_SETUP_PHASE(HOSTQUEUE)
272 }
273 }
274 else if (bsc->sc_nexus == NULL)
275 bshoststart(bsc, NULL);
276
277 return 1;
278}
279
280struct bsccb *
281bscmddone(ti)
282 struct targ_info *ti;
283{
284 struct bs_softc *bsc = ti->ti_bsc;
285 struct bsccb *cb = ti->ti_ctab.tqh_first;
286 union ccb *ccb;
287 int error;
288
289 if (ti->ti_state == BS_TARG_SYNCH)
290 {
291 if (bs_analyze_syncmsg(ti, cb))
292 return cb;
293 }
294
295 if (bsc->sc_p.datalen != 0)
296 ti->ti_error |= BSDMAABNORMAL;
297
298 cb->error = ti->ti_error;
299
300 do
301 {
302 ccb = cb->ccb;
303 error = CAM_REQ_CMP;
304
305 if (cb->bsccb_flags & (BSITSDONE | BSSENSECCB | BSCASTAT))
306 {
307 if (cb->bsccb_flags & BSSENSECCB)
308 {
309 cb->error &= ~BSDMAABNORMAL;
310 if (cb->error == 0)
311 ti->ti_flags |= BSCASTAT;
312
313 ti->ti_flags |= BSERROROK;
314 }
315 else if (cb->bsccb_flags & BSCASTAT)
316 {
317 if (ti->ti_flags & BSCASTAT)
318 {
319 ti->ti_flags &= ~BSCASTAT;
320 error = CAM_AUTOSNS_VALID|CAM_SCSI_STATUS_ERROR;
321 if (ccb)
322 ccb->csio.sense_data = ti->sense;/* XXX may not be csio.... */
323 }
324 else
325 error = CAM_AUTOSENSE_FAIL;
326 ti->ti_flags |= BSERROROK;
327 } else
328 bs_panic(bsc, "internal error");
329 }
330
331 while (cb->error)
332 {
333 if (ti->ti_flags & BSERROROK)
334 break;
335
336 if (cb->rcnt >= bsc->sc_retry || (cb->error & BSFATALIO))
337 {
338 if (cb->error & (BSSELTIMEOUT | BSTIMEOUT))
339 error = CAM_CMD_TIMEOUT;
340 else if (cb->error & BSTARGETBUSY)
341 error = CAM_SCSI_STATUS_ERROR;
342 else
343 error = CAM_REQ_CMP_ERR;
344 break;
345 }
346
347 if (cb->error & BSREQSENSE)
348 {
349 /* must clear the target's sense state */
350 cb->rcnt++;
351 cb->bsccb_flags |= (BSITSDONE | BSCASTAT);
352 cb->error &= ~BSREQSENSE;
353 return bs_request_sense(ti);
354 }
355
356 /* XXX: compat with upper driver */
357 if ((cb->error & BSDMAABNORMAL) &&
358 BSHW_CMD_CHECK(cb, BSERROROK))
359 {
360 cb->error &= ~BSDMAABNORMAL;
361 continue;
362 }
363 if (/*(xs && xs->bp) || can't know whether bufferd i/o or not */
364 (cb->error & BSSELTIMEOUT) == 0)
365 bs_debug_print(bsc, ti);
366 cb->rcnt++;
367 return cb;
368 }
369
370#ifdef BS_DIAG
371 cb->bsccb_flags |= BSITSDONE;
372#endif /* BS_DIAG */
373 if (bsc->sc_poll)
374 {
375 bsc->sc_flags |= BSJOBDONE;
376 if (bsc->sc_outccb == cb)
377 bsc->sc_flags |= BSPOLLDONE;
378 }
379
380 TAILQ_REMOVE(&ti->ti_ctab, cb, ccb_chain);
381
382 if (ccb)
383 {
384 ccb->ccb_h.status = error;
385 ccb->csio.scsi_status = ti->ti_status;/*XXX*/
386 xpt_done(ccb);
387 }
388
389 bs_free_ccb(cb);
390 cb = ti->ti_ctab.tqh_first;
391
392 }
393 while (cb != NULL && (cb->bsccb_flags & BSITSDONE) != 0);
394
395 /* complete */
396 return NULL;
397}
398
399/**************************************************
400 * ### PHASE FUNCTIONS ###
401 **************************************************/
402/**************************************************
403 * <SELECTION PHASE>
404 **************************************************/
405static void
406bshoststart(bsc, ti)
407 struct bs_softc *bsc;
408 struct targ_info *ti;
409{
410 struct bsccb *cb;
411 int s;
412
413 if (bsc->sc_flags & BSINACTIVE)
414 return;
415
416again:
417 if (ti == NULL)
418 {
419 if ((ti = bsc->sc_sttab.tqh_first) == NULL)
420 return;
421 bs_hostque_delete(bsc, ti);
422 }
423
424 if ((cb = ti->ti_ctab.tqh_first) == NULL)
425 {
426 bs_printf(ti, "bshoststart", "Warning: No ccb");
427 BS_SETUP_PHASE(FREE);
428 ti = NULL;
429 goto again;
430 }
431
432#ifdef BS_DIAG
433 if (cb->bsccb_flags & BSITSDONE)
434 bs_panic(bsc, "bshoststart: already done");
435
436 if (bsc->sc_nexus || (ti->ti_flags & BSNEXUS))
437 {
438 char *s = ((ti->ti_flags & BSNEXUS) ?
439 "nexus already established" : "scsi board busy");
440
441 bs_debug_print(bsc, ti);
442 bs_printf(ti, "bshoststart", s);
443 }
444#endif /* BS_DIAG */
445
446#ifdef BS_STATICS
447 bs_statics[ti->ti_id].select++;
448#endif /* BS_STATICS */
449
450 if (ti->ti_cfgflags & BS_SCSI_WAIT)
451 {
452 struct targ_info *tmpti;
453
454 for (tmpti = bsc->sc_titab.tqh_first; tmpti;
455 tmpti = tmpti->ti_tchain.tqe_next)
456 if (tmpti->ti_phase >= DISCONNECTED)
457 goto retry;
458 }
459
460 /* start selection */
461 ti->ti_status = ST_UNK;
462 if (bs_check_sat(ti))
463 {
464 if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
465 {
466 BS_LOAD_SDP
467 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
468 bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
469 bshw_cmd_pass(bsc, 0);
470 bshw_set_sync_reg(bsc, ti->ti_sync);
471 bshw_issue_satcmd(bsc, cb, bs_check_link(ti, cb));
472 if (bs_check_smit(ti) || bsc->sc_p.datalen <= 0)
473 bshw_set_count(bsc, 0);
474 else
475 bs_dma_xfer(ti, BSHW_CMD_CHECK(cb, BSREAD));
476
477 s = splhigh();
478 if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
479 {
480 /* XXX:
481 * Reload a lun again here.
482 */
483 bshw_set_lun(bsc, ti->ti_lun);
484 bshw_start_sat(bsc, bs_check_disc(ti));
485 if ((bshw_get_auxstat(bsc) & STR_LCI) == 0)
486 {
487 splx(s);
488 BS_HOST_START
489 BS_SELECTION_START
490 BS_SETUP_PHASE(SATSEL);
491 ti->ti_omsgoutlen = 0;
492 ti->ti_msgout = bs_identify_msg(ti);
493#ifdef BS_DIAG
494 ti->ti_flags |= BSNEXUS;
495#endif /* BS_DIAG */
496#ifdef BS_STATICS
497 bs_statics[ti->ti_id].select_win++;
498#endif /* BS_STATICS */
499 return;
500 }
501 }
502 splx(s);
503
504 if (bs_check_smit(ti) == 0)
505 bshw_dmaabort(bsc, ti);
506#ifdef BS_STATICS
507 bs_statics[ti->ti_id].select_miss_in_assert++;
508#endif /* BS_STATICS */
509 }
510 }
511 else
512 {
513 s = splhigh();
514 if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
515 {
516 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
517 bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
518 bshw_set_sync_reg(bsc, ti->ti_sync);
519 bshw_assert_select(bsc);
520
521 if ((bshw_get_auxstat(bsc) & STR_LCI) == 0)
522 {
523 splx(s);
524 BS_HOST_START
525 BS_SELECTION_START
526 BS_SETUP_PHASE(SELECTASSERT);
527#ifdef BS_STATICS
528 bs_statics[ti->ti_id].select_win++;
529#endif /* BS_STATICS */
530 return;
531 }
532#ifdef BS_STATICS
533 bs_statics[ti->ti_id].select_miss_in_assert++;
534#endif /* BS_STATICS */
535 }
536 splx(s);
537 }
538
539 /* RETRY LATER */
540retry:
541#ifdef BS_STATICS
542 bs_statics[ti->ti_id].select_miss++;
543#endif /* BS_STATICS */
544 bs_hostque_head(bsc, ti);
545 BS_SETUP_PHASE(HOSTQUEUE)
546}
547
548static BS_INLINE struct targ_info *
549bs_selected(bsc, ti, cb)
550 struct bs_softc *bsc;
551 struct targ_info *ti;
552 struct bsccb *cb;
553{
554
555 if (bsc->sc_busstat != BSR_SELECTED)
556 {
557 bs_phase_error(ti, cb);
558 return NULL;
559 }
560
561#ifdef BS_DIAG
562 if (bsc->sc_selwait != ti)
563 panic("%s selection internal error\n", bsc->sc_dvname);
564
565 ti->ti_flags |= BSNEXUS;
566#endif /* BS_DIAG */
567
568 /* clear select wait state */
569 BS_SETUP_PHASE(SELECTED);
570 BS_SELECTION_TERMINATE;
571 BS_LOAD_SDP
572 return ti;
573}
574
575/**************************************************
576 * <RESELECTION>
577 **************************************************/
578static BS_INLINE struct targ_info *
579bs_reselect(bsc)
580 struct bs_softc *bsc;
581{
582 u_int target;
583 struct targ_info *ti;
584
585 /* check collision */
586 if ((ti = bsc->sc_selwait) != NULL)
587 {
588 if (ti->ti_phase == SATSEL)
589 {
590#ifdef BS_DIAG
591 ti->ti_flags &= ~BSNEXUS;
592#endif /* BS_DIAG */
593 ti->ti_msgout = 0;
594 if (bs_check_smit(ti) == 0)
595 bshw_dmaabort(bsc, ti);
596 }
597 bs_hostque_head(bsc, ti);
598 BS_SELECTION_TERMINATE
599 BS_SETUP_PHASE(HOSTQUEUE)
600#ifdef BS_STATICS
601 bs_statics[ti->ti_id].select_miss_by_reselect++;
602 bs_statics[ti->ti_id].select_miss++;
603#endif /* BS_STATICS */
604 }
605
606 /* who are you ? */
607 target = bshw_get_src_id(bsc);
608 if ((ti = bsc->sc_ti[target]) == NULL)
609 {
610 bs_debug_print_all(bsc);
611 printf("reselect: miss reselect. target(%d)\n", target);
612 bs_reset_nexus(bsc);
613 return NULL;
614 }
615
616 /* confirm nexus */
617 BS_HOST_START
618 bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
619 if (ti->ti_ctab.tqh_first == NULL || ti->ti_phase != DISCONNECTED)
620 {
621 bs_printf(ti, "reselect", "phase mismatch");
622 BS_SETUP_PHASE(UNDEF)
623 bs_force_abort(ti);
624 bs_hostque_delete(bsc, ti);
625 }
626 else
627 bsc->sc_dtgnum --;
628
629 /* recover host */
630 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
631 bshw_set_sync_reg(bsc, ti->ti_sync);
632 BS_RESTORE_SDP
633 BS_SETUP_PHASE(RESELECTED)
634#ifdef BS_STATICS
635 bs_statics[ti->ti_id].reselect++;
636#endif /* BS_STATICS */
637 return ti;
638}
639
640static BS_INLINE void
641bs_sat_continue(bsc, ti, cb)
642 struct bs_softc *bsc;
643 struct targ_info *ti;
644 struct bsccb *cb;
645{
646
647 BS_SETUP_PHASE(SATRESEL);
648 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
649 bshw_cmd_pass(bsc, 0x44);
650 bshw_set_sync_reg(bsc, ti->ti_sync);
651 bshw_issue_satcmd(bsc, cb, 0);
652 if (bs_check_smit(ti) || bsc->sc_p.datalen <= 0)
653 bshw_set_count(bsc, 0);
654 else
655 bs_dma_xfer(ti, BSHW_CMD_CHECK(cb, BSREAD));
656 bshw_set_lun(bsc, ti->ti_lun); /* XXX */
657 bshw_start_sat(bsc, 0);
658}
659
660/*************************************************
661 * <DATA PHASE>
662 *************************************************/
663#define DR (STR_BSY | STR_DBR)
664
665void
666bs_poll_timeout(bsc, s)
667 struct bs_softc *bsc;
668 char *s;
669{
670 struct targ_info *ti;
671
672 bs_printf(NULL, s, "timeout");
673 bsc->sc_flags |= BSRESET;
674 if ((ti = bsc->sc_nexus) && ti->ti_ctab.tqh_first)
675 ti->ti_error |= BSTIMEOUT;
676}
677
678static BS_INLINE u_int8_t
679bs_read_1byte(bsc)
680 struct bs_softc *bsc;
681{
c9faf524 682 u_int wc;
984263bc
MD
683
684 bshw_start_sxfer(bsc);
685 for (wc = bsc->sc_wc; (bshw_get_auxstat(bsc) & DR) != DR && --wc; );
686 if (wc)
687 return bshw_read_data(bsc);
688 else
689 bs_poll_timeout(bsc, "read_1byte");
690
691 return 0;
692}
693
694static BS_INLINE void
695bs_write_1byte(bsc, data)
696 struct bs_softc *bsc;
697 u_int8_t data;
698{
c9faf524 699 u_int wc;
984263bc
MD
700
701 bshw_start_sxfer(bsc);
702 for (wc = bsc->sc_wc; (bshw_get_auxstat(bsc) & DR) != DR && --wc; );
703 if (wc)
704 bshw_write_data(bsc, data);
705 else
706 bs_poll_timeout(bsc, "write_1byte");
707}
708
709static int
710bs_xfer(bsc, data, len)
711 struct bs_softc *bsc;
712 char *data;
713 int len;
714{
715 u_int8_t aux;
716 u_int count, wc;
717
718 bshw_set_count(bsc, len);
719 bshw_start_xfer(bsc);
720
721 for (count = 0, wc = bsc->sc_wc; count < len && --wc; )
722 {
723 if (((aux = bshw_get_auxstat(bsc)) & DR) == DR)
724 {
725 if (bsc->sc_busstat & BSHW_READ)
726 *(data++) = bshw_read_data(bsc);
727 else
728 bshw_write_data(bsc, *(data++));
729 count++;
730 wc = bsc->sc_wc;
731 }
732
733 if (aux & STR_INT)
734 break;
735 }
736
737 if (wc == 0)
738 bs_poll_timeout(bsc, "bs_xfer");
739
740 return count;
741}
742#undef DR
743
744static void
745bs_io_xfer(ti)
746 struct targ_info *ti;
747{
748 struct bs_softc *bsc = ti->ti_bsc;
749 struct sc_p *sp = &bsc->sc_p;
750 u_int count, dummy;
751
752 /* switch dma trasnfr mode */
753 bshw_set_poll_trans(bsc, ti->ti_cfgflags);
754 sp->seglen = 0;
755 sp->bufp = NULL;
756
757 if (sp->datalen <= 0)
758 {
759 ti->ti_error |= BSDMAABNORMAL;
760 dummy = 0;
761 count = bs_xfer(bsc, (u_int8_t *) &dummy, 1);
762 }
763 else
764 count = bs_xfer(bsc, sp->data, sp->datalen);
765
766 sp->data += count;
767 sp->datalen -= count;
768}
769
770/************************************************
771 * <COMMAND PHASE>
772 ************************************************/
773static BS_INLINE void
774bs_commandout(bsc, ti, cb)
775 struct bs_softc *bsc;
776 struct targ_info *ti;
777 struct bsccb *cb;
778{
779 u_int8_t scsi_cmd[16];
780 int len;
781
782 BS_SETUP_PHASE(CMDPHASE);
783
784 if (bs_check_link(ti, cb))
785 {
786 bcopy(cb->cmd, scsi_cmd, cb->cmdlen);
787 scsi_cmd[cb->cmdlen - 1] |= 0x01;
788 len = bs_xfer(bsc, scsi_cmd, cb->cmdlen);
789 }
790 else
791 len = bs_xfer(bsc, cb->cmd, cb->cmdlen);
792
793 if (len != cb->cmdlen)
794 ti->ti_error |= BSCMDABNORMAL;
795}
796
797/************************************************
798 * <STATUS IN>
799 ************************************************/
800static BS_INLINE void
801bs_status_check(bsc, ti)
802 struct bs_softc *bsc;
803 struct targ_info *ti;
804{
805
806 if (ti->ti_status == ST_GOOD || ti->ti_status == ST_INTERGOOD)
807 return;
808
809 switch (ti->ti_status)
810 {
811 case ST_MET:
812 case ST_INTERMET:
813 case ST_CHKCOND:
814 ti->ti_error |= BSREQSENSE;
815 break;
816
817 case ST_BUSY:
818 ti->ti_error |= BSTARGETBUSY;
819 break;
820
821 default:
822 ti->ti_error |= BSSTATUSERROR;
823 break;
824 }
825}
826
827/************************************************
828 * <MSG IN>
829 ************************************************/
830#define MSGWAIT(cnt) { if (ti->ti_msginptr < (cnt)) return; }
831
832static void
833bs_quick_abort(ti, msg)
834 struct targ_info *ti;
835 u_int msg;
836{
837 struct bsccb *cb;
838
839 if ((cb = ti->ti_ctab.tqh_first) == NULL)
840 return;
841
842 cb->msgoutlen = 1;
843 cb->msgout[0] = msg;
844 cb->rcnt++;
845
846 ti->ti_error |= BSMSGERROR;
847}
848
849static void
850bs_msgin_error(ti, count)
851 struct targ_info *ti;
852 u_int count;
853{
854 int n;
855
856 MSGWAIT(count);
857
858 bs_printf(ti, "msgin", "illegal msg");
859
860 for (n = 0; n < ti->ti_msginptr; n ++)
861 printf("[0x%x] ", (u_int) ti->ti_msgin[n]);
862 printf("\n");
863
864 bs_quick_abort(ti, MSG_REJECT);
865 ti->ti_msginptr = 0;
866}
867
868static void
869bs_msgin_ext(ti)
870 struct targ_info *ti;
871{
872 struct bs_softc *bsc = ti->ti_bsc;
873 struct bsccb *cb = ti->ti_ctab.tqh_first;
874 int count;
875 u_int reqlen;
876 u_int32_t *ptr;
877 struct msgbase msg;
878
879 MSGWAIT(2);
880
881 reqlen = ti->ti_msgin[1];
882 if (reqlen == 0)
883 reqlen = 256;
884
885 if (ti->ti_msginptr >= MAXMSGLEN)
886 ti->ti_msginptr = 3; /* XXX */
887
888 MSGWAIT(reqlen + 2);
889
890 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
891 {
892 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
893 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
894 count = (int) htonl((long) (*ptr));
895
896 bsc->sc_p.seglen = ti->ti_scsp.seglen = 0;
897 if (bsc->sc_p.datalen - count >= 0 &&
898 bsc->sc_p.datalen - count <= cb->datalen)
899 {
900 bsc->sc_p.datalen -= count;
901 bsc->sc_p.data += count;
902 }
903 else
904 bs_msgin_error(ti, 7);
905 break;
906
907 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
908 ti->ti_syncnow.period = ti->ti_msgin[3];
909 ti->ti_syncnow.offset = ti->ti_msgin[4];
910 if (ti->ti_syncnow.offset == 0)
911 ti->ti_syncnow.period = 0;
912
913 if (ti->ti_syncnow.state != BS_SYNCMSG_ASSERT)
914 {
915 bs_start_syncmsg(ti, NULL, BS_SYNCMSG_REQUESTED);
916 bscmdstart(ti, BSCMDSTART);
917 }
918 else
919 BS_SETUP_SYNCSTATE(BS_SYNCMSG_ACCEPT)
920 break;
921
922 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
923 msg.msglen = MSG_EXTEND_WIDELEN + 2;
924 msg.msg[0] = MSG_EXTEND;
925 msg.msg[1] = MSG_EXTEND_WIDELEN;
926 msg.msg[2] = MSG_EXTEND_WIDECODE;
927 msg.msg[3] = 0;
928 msg.flag = 0;
929 bs_make_msg_ccb(ti, cb->lun, cb, &msg, 0);
930 break;
931
932 default:
933 bs_msgin_error(ti, 0);
934 return;
935 }
936
937 ti->ti_msginptr = 0;
938 return;
939}
940
941static void
942bs_msg_reject(ti)
943 struct targ_info *ti;
944{
945 struct bs_softc *bsc = ti->ti_bsc;
946 struct bsccb *cb = ti->ti_ctab.tqh_first;
947 char *s = "unexpected msg reject";
948
949 switch (ti->ti_ophase)
950 {
951 case CMDPHASE:
952 s = "cmd rejected";
953 cb->bsccb_flags &= ~BSLINK;
954 BS_SETUP_MSGPHASE(IOCOMPLETED);
955 break;
956
957 case MSGOUT:
958 if (ti->ti_msgout & 0x80)
959 {
960 s = "identify msg rejected";
961 cb->bsccb_flags &= ~BSDISC;
962 BS_SETUP_MSGPHASE(IOCOMPLETED);
963 }
964 else if (ti->ti_msgout == MSG_EXTEND)
965 {
966 switch (ti->ti_emsgout)
967 {
968 case MSG_EXTEND_SYNCHCODE:
969 BS_SETUP_SYNCSTATE(BS_SYNCMSG_REJECT);
970 return;
971
972 default:
973 break;
974 }
975 }
976 break;
977
978 default:
979 break;
980 }
981
982 bs_debug_print(bsc, ti);
983 bs_printf(ti, "msgin", s);
984 ti->ti_error |= BSMSGERROR;
985}
986
987static BS_INLINE void
988bs_msgin(bsc, ti)
989 struct bs_softc *bsc;
990 struct targ_info *ti;
991{
992
993 BS_SETUP_PHASE(MSGIN);
994
995 switch (ti->ti_msgin[0])
996 {
997 case MSG_SAVESP:
998 BS_SAVE_SDP
999 break;
1000
1001 case MSG_RESTORESP:
1002 BS_RESTORE_SDP
1003 bs_printf(ti, "msgin", "restore scsi pointer");
1004 break;
1005
1006 case MSG_REJECT:
1007 bs_msg_reject(ti);
1008 break;
1009
1010 case 0xf:
1011 break;
1012
1013 case MSG_I_ERROR:/* all I -> T : nothing to do*/
1014 case MSG_ABORT:
1015 case MSG_PARITY:
1016 case MSG_RESET:
1017 case 0xe:
1018 bs_msgin_error(ti, 1);
1019 goto resume;
1020
1021 case MSG_NOOP:
1022 break;
1023
1024 case MSG_EXTEND:
1025 bs_msgin_ext(ti);
1026 goto resume;
1027
1028 case 0xd:
1029 bs_msgin_error(ti, 2);
1030 goto resume;
1031
1032 case MSG_DISCON:
1033 BS_SETUP_MSGPHASE(DISCONNECTASSERT);
1034 break;
1035
1036 case MSG_COMP:
1037 BS_SETUP_MSGPHASE(IOCOMPLETED);
1038 break;
1039
1040 case MSG_LCOMP:
1041 case MSG_LCOMP_F:
1042 bs_status_check(bsc, ti);
1043 if (bscmddone(ti) == NULL)
1044 {
1045 if (bscmdstart(ti, BSCMDSTART) == 0)
1046 {
1047 bs_printf(ti, "msgin", "cmd line miss");
1048 bs_force_abort(ti);
1049 }
1050 }
1051 else
1052 bscmdstart(ti, BSCMDRESTART);
1053#ifdef BS_STATICS
1054 bs_linkcmd_count[ti->ti_id]++;
1055#endif /* BS_STATICS */
1056 BS_LOAD_SDP
1057 ti->ti_status = ST_UNK;
1058 break;
1059
1060 default:
1061 if (ti->ti_msgin[0] & 0x80)
1062 {
1063 if ((ti->ti_msgin[0] & 0x07) != ti->ti_lun)
1064 {
1065 ti->ti_lun = (ti->ti_msgin[0] & 0x07);
1066 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
1067 bshw_set_sync_reg(bsc, ti->ti_sync);
1068
1069 bs_printf(ti, "msgin", "lun error");
1070 bs_quick_abort(ti, MSG_ABORT);
1071 }
1072 break;
1073 }
1074 else if (ti->ti_msgin[0] < 0x20)
1075 bs_msgin_error(ti, 1);
1076 else if (ti->ti_msgin[0] < 0x30)
1077 bs_msgin_error(ti, 2);
1078 else
1079 bs_msgin_error(ti, 1);
1080 goto resume;
1081 }
1082
1083 ti->ti_msginptr = 0;
1084
1085resume:
1086 return;
1087}
1088
1089/************************************************
1090 * <MSG OUT>
1091 ************************************************/
1092static BS_INLINE void
1093bs_msgout(bsc, ti, cb)
1094 struct bs_softc *bsc;
1095 struct targ_info *ti;
1096 struct bsccb *cb;
1097{
1098 u_int8_t msg[MAXMSGLEN + 1];
1099
1100 if (ti->ti_phase == MSGOUT)
1101 {
1102 if (cb->rcnt ++ < bsc->sc_retry)
1103 cb->msgoutlen = ti->ti_omsgoutlen;
1104 }
1105 else
1106 BS_SETUP_PHASE(MSGOUT);
1107
1108 if (ti->ti_ophase == SELECTED)
1109 {
1110identify:
1111 if (cb->msgoutlen == 0)
1112 {
1113 ti->ti_msgout = bs_identify_msg(ti);
1114 ti->ti_omsgoutlen = 0;
1115 bs_write_1byte(bsc, ti->ti_msgout);
1116 }
1117 else
1118 {
1119 if (cb->msgout[0] != MSG_RESET &&
1120 cb->msgout[0] != MSG_ABORT)
1121 {
1122 msg[0] = bs_identify_msg(ti);
1123 bcopy(cb->msgout, &msg[1], cb->msgoutlen);
1124 bs_xfer(bsc, msg, cb->msgoutlen + 1);
1125 }
1126 else
1127 bs_xfer(bsc, cb->msgout, cb->msgoutlen);
1128
1129 ti->ti_msgout = cb->msgout[0];
1130 ti->ti_emsgout = cb->msgout[2];
1131 ti->ti_omsgoutlen = cb->msgoutlen;
1132 cb->msgoutlen = 0;
1133 }
1134 return;
1135 }
1136
1137 if (ti->ti_ophase == SATSEL)
1138 {
1139 /* XXX:
1140 * Maybe identify msg rejected due to
1141 * a parity error in target side.
1142 */
1143
1144 bs_printf(ti, "msgout", "msg identify retry (SAT)");
1145 goto identify;
1146 }
1147
1148 if (cb->msgoutlen == 0)
1149 {
1150 ti->ti_msgout = MSG_REJECT;
1151 ti->ti_omsgoutlen = 0;
1152 bs_write_1byte(bsc, ti->ti_msgout);
1153 }
1154 else
1155 {
1156 ti->ti_msgout = cb->msgout[0];
1157 ti->ti_emsgout = cb->msgout[2];
1158 ti->ti_omsgoutlen = cb->msgoutlen;
1159 bs_xfer(bsc, cb->msgout, cb->msgoutlen);
1160 cb->msgoutlen = 0;
1161 }
1162}
1163
1164/************************************************
1165 * <DISCONNECT>
1166 ************************************************/
1167static BS_INLINE void
1168bs_disconnect_phase(bsc, ti, cb)
1169 struct bs_softc *bsc;
1170 struct targ_info *ti;
1171 struct bsccb *cb;
1172{
1173
1174 switch (bsc->sc_msgphase)
1175 {
1176 default:
1177 panic("%s unknown msg phase\n", bsc->sc_dvname);
1178 break;
1179
1180 case DISCONNECTASSERT:
1181 case FREE:
1182#ifdef BS_STATICS
1183 bs_statics[ti->ti_id].disconnected++;
1184#endif /* BS_STATICS */
1185 if (ti->ti_cfgflags & BS_SCSI_SAVESP)
1186 BS_SAVE_SDP;
1187 BS_HOST_TERMINATE;
1188 BS_SETUP_PHASE(DISCONNECTED);
1189 bsc->sc_dtgnum ++;
1190 bshoststart(bsc, NULL);
1191 break;
1192
1193 case IOCOMPLETED:
1194 bs_status_check(bsc, ti);
1195 cb = bscmddone(ti);
1196#ifdef BS_DIAG
1197 ti->ti_flags &= ~BSNEXUS;
1198#endif /* BS_DIAG */
1199 BS_SETUP_PHASE(FREE);
1200 if (cb || bsc->sc_sttab.tqh_first == NULL)
1201 {
1202 BS_HOST_TERMINATE;
1203 bscmdstart(ti, BSCMDSTART);
1204 }
1205 else
1206 {
1207 /* give a chance to other target */
1208 bscmdstart(ti, BSCMDSTART);
1209 BS_HOST_TERMINATE;
1210 bshoststart(bsc, NULL);
1211 }
1212 break;
1213 }
1214
1215 BS_SETUP_MSGPHASE(FREE);
1216}
1217
1218/**************************************************
1219 * <PHASE ERROR>
1220 **************************************************/
1221#define scsi_status (bsc->sc_busstat)
1222
1223struct bs_err {
1224 u_char *pe_msg;
1225 u_int pe_err;
1226 u_int pe_ph;
1227};
1228
1229struct bs_err bs_cmderr[] = {
1230/*0*/ { "illegal cmd", BSABNORMAL, UNDEF },
1231/*1*/ { "unexpected bus free", BSABNORMAL, FREE },
1232/*2*/ { NULL, BSSELTIMEOUT, FREE},
1233/*3*/ { "scsi bus parity error", BSPARITY, UNDEF },
1234/*4*/ { "scsi bus parity error", BSPARITY, UNDEF },
1235/*5*/ { "unknown" , BSFATALIO, UNDEF },
1236/*6*/ { "miss reselection (target mode)", BSFATALIO, UNDEF },
1237/*7*/ { "wrong status byte", BSPARITY, STATUSIN },
1238};
1239
1240static void
1241bs_phase_error(ti, cb)
1242 struct targ_info *ti;
1243 struct bsccb *cb;
1244{
1245 struct bs_softc *bsc = ti->ti_bsc;
1246 struct bs_err *pep;
1247
1248 if ((scsi_status & BSR_CM) == BSR_CMDERR &&
1249 (scsi_status & BSR_PHVALID) == 0)
1250 {
1251 pep = &bs_cmderr[scsi_status & BSR_PM];
1252 ti->ti_error |= pep->pe_err;
1253 if (pep->pe_msg)
1254 {
1255 bs_debug_print(bsc, ti);
1256 bs_printf(ti, "bsintr", pep->pe_msg);
1257 }
1258 BS_SETUP_PHASE(pep->pe_ph);
1259 }
1260 else
1261 {
1262 ti->ti_error |= BSABNORMAL;
1263 bs_debug_print(bsc, ti);
1264 bs_printf(ti, "bsintr", "phase error");
1265 BS_SETUP_PHASE(UNDEF);
1266 }
1267
1268 BS_SETUP_MSGPHASE(FREE);
1269 switch (ti->ti_phase)
1270 {
1271 case FREE:
1272 BS_SETUP_PHASE(UNDEF);
1273 cb = bscmddone(ti);
1274#ifdef BS_DIAG
1275 ti->ti_flags &= ~BSNEXUS;
1276#endif /* BS_DIAG */
1277 BS_HOST_TERMINATE;
1278 BS_SETUP_PHASE(FREE);
1279 bscmdstart(ti, ((cb == NULL) ? BSCMDSTART : BSCMDRESTART));
1280 break;
1281
1282 case STATUSIN:
1283 ti->ti_error |= BSSTATUSERROR;
1284 ti->ti_status = bshw_get_status_insat(bsc); /* XXX SAT */
1285 bs_debug_print(bsc, ti);
1286 break;
1287
1288 case UNDEF:
1289 default:
1290 ti->ti_error |= BSABNORMAL;
1291 bs_reset_nexus(bsc);
1292 break;
1293 }
1294}
1295
1296/**************************************************
1297 * ### SCSI PHASE SEQUENCER ###
1298 **************************************************/
38e94a25 1299static BS_INLINE void bs_ack_wait (struct bs_softc *, struct targ_info *, struct bsccb *);
984263bc
MD
1300
1301static BS_INLINE void
1302bs_ack_wait(bsc, ti, cb)
1303 struct bs_softc *bsc;
1304 struct targ_info *ti;
1305 struct bsccb *cb;
1306{
1307 int wc = bsc->sc_wc;
1308
1309 for (wc = bsc->sc_wc; bshw_get_busstat(bsc) != BSR_ACKREQ && wc > 0; )
1310 wc --;
1311
1312 if (wc <= 0)
1313 {
1314 bs_printf(ti, "bs_ack_wait", "timeout I");
1315 return;
1316 }
1317
1318 bshw_get_auxstat(bsc);
1319 scsi_status = bshw_get_busstat(bsc);
1320
1321 if (cb->msgoutlen > 0)
1322 {
1323 bshw_assert_atn(bsc);
1324 delay(800);
1325 BS_SETUP_PHASE(ATTENTIONASSERT);
1326 }
1327
1328 bshw_negate_ack(bsc);
1329
1330#ifdef WAITNEXTP
1331 for (wc = bsc->sc_wc; bshw_get_busstat(bsc) == BSR_ACKREQ && wc > 0; )
1332 wc --;
1333
1334 if (wc <= 0)
1335 bs_printf(ti, "bs_ack_wait", "timeout II");
1336#endif /* WAITNEXTP */
1337}
1338
1339int
1340bs_sequencer(bsc)
1341 struct bs_softc *bsc;
1342{
c9faf524 1343 struct targ_info *ti;
984263bc
MD
1344 struct bsccb *cb;
1345
1346 /**************************************************
1347 * Check reset
1348 **************************************************/
1349 if (bsc->sc_flags & (BSRESET | BSINACTIVE))
1350 {
1351 if (bsc->sc_flags & BSRESET)
1352 bs_reset_nexus(bsc);
1353 return 1;
1354 }
1355
1356 /**************************************************
1357 * Get status & bus phase
1358 **************************************************/
1359 if ((bshw_get_auxstat(bsc) & STR_INT) == 0)
1360 return 0;
1361
1362 scsi_status = bshw_get_busstat(bsc);
1363 if (scsi_status == ((u_int8_t) -1))
1364 {
1365 bs_debug_print_all(bsc);
1366 return 1;
1367 }
1368 /**************************************************
1369 * Check reselection, or nexus
1370 **************************************************/
1371 if (scsi_status == BSR_RESEL)
1372 {
1373 bs_reselect(bsc);
1374 return 1;
1375 }
1376
1377 ti = bsc->sc_nexus;
1378 if (ti == NULL || (cb = ti->ti_ctab.tqh_first) == NULL)
1379 {
1380 bs_debug_print_all(bsc);
1381 bs_printf(ti, "bsintr", "no nexus");
1382 bs_reset_nexus(bsc);
1383 return 1;
1384 }
1385
1386 /**************************************************
1387 * Debug section
1388 **************************************************/
1389#ifdef BS_DEBUG
1390 if (bs_debug_flag)
1391 {
1392 bs_debug_print(bsc, ti);
1393 if (bs_debug_flag > 1)
1394 Debugger();
1395 }
1396#endif /* BS_DEBUG */
1397
1398 /**************************************************
1399 * internal scsi phase
1400 **************************************************/
1401 switch (ti->ti_phase)
1402 {
1403 case SELECTASSERT:
1404 bs_selected(bsc, ti, cb);
1405 return 1;
1406
1407 case SATSEL:
1408 BS_SELECTION_TERMINATE;
1409
1410 case SATRESEL:
1411 if (bsc->sc_flags & (BSDMASTART | BSSMITSTART))
1412 {
1413 if (bsc->sc_flags & BSSMITSTART)
1414 {
1415 bs_debug_print_all(bsc);
1416 bs_reset_nexus(bsc);
1417 bs_printf(ti, "bsintr", "smit transfer");
1418 return 1;
1419 }
1420
1421 BS_SETUP_PHASE(DATAPHASE); /* XXX */
1422 bs_dma_xfer_end(ti);
1423 ti->ti_phase = ti->ti_ophase; /* XXX */
1424 }
1425 break;
1426
1427 default:
1428 /* XXX:
1429 * check check check for safety !!
1430 */
1431 if (bsc->sc_selwait)
1432 {
1433 /* Ghaaa! phase error! retry! */
1434 bs_phase_error(ti, cb);
1435 return 1;
1436 }
1437
1438 if (bsc->sc_flags & (BSDMASTART | BSSMITSTART))
1439 {
1440 if (bsc->sc_flags & BSDMASTART)
1441 bs_dma_xfer_end(ti);
1442 else
1443 bs_smit_xfer_end(ti);
1444 }
1445 break;
1446 }
1447
1448 /**************************************************
1449 * hw scsi phase
1450 **************************************************/
1451 if (scsi_status & BSR_PHVALID)
1452 {
1453 /**************************************************
1454 * Normal SCSI phase.
1455 **************************************************/
1456 if ((scsi_status & BSR_CM) == BSR_CMDABT)
1457 {
1458 bs_phase_error(ti, cb);
1459 return 1;
1460 }
1461
1462 switch (scsi_status & BSR_PM)
1463 {
1464 case BSR_DATAOUT:
1465 case BSR_DATAIN:
1466 BS_SETUP_PHASE(DATAPHASE);
1467
1468 if (bsc->sc_p.datalen <= 0 ||
1469 (ti->ti_flags & BSFORCEIOPOLL))
1470 {
1471 bs_io_xfer(ti);
1472 return 1;
1473 }
1474
1475 if (bs_check_smit(ti) &&
1476 (bsc->sc_p.datalen % sizeof(u_int32_t)) == 0)
1477 {
1478 bs_lc_smit_xfer(ti, scsi_status & BSR_IOR);
1479 return 1;
1480 }
1481
1482 bs_dma_xfer(ti, scsi_status & BSR_IOR);
1483 bshw_start_xfer(bsc);
1484 return 1;
1485
1486 case BSR_CMDOUT:
1487 bs_commandout(bsc, ti, cb);
1488 return 1;
1489
1490 case BSR_STATIN:
1491 if (bs_check_sat(ti))
1492 {
1493 BS_SETUP_PHASE(SATCOMPSEQ);
1494 bshw_set_count(bsc, 0);
1495 bshw_cmd_pass(bsc, 0x41);
1496 bshw_start_sat(bsc, 0);
1497 }
1498 else
1499 {
1500 BS_SETUP_PHASE(STATUSIN);
1501 ti->ti_status = bs_read_1byte(bsc);
1502 }
1503 return 1;
1504
1505 case BSR_UNSPINFO0:
1506 case BSR_UNSPINFO1:
1507 bs_debug_print(bsc, ti);
1508 bs_printf(ti, "bsintr", "illegal bus phase");
1509 return 1;
1510
1511 case BSR_MSGOUT:
1512 bs_msgout(bsc, ti, cb);
1513 return 1;
1514
1515 case BSR_MSGIN:/* msg in */
1516 if (bs_check_sat(ti))
1517 {
1518 if (ti->ti_phase == RESELECTED)
1519 {
1520 bs_sat_continue(bsc, ti, cb);
1521 return 1;
1522 }
1523 /* XXX */
1524 if (ti->ti_status == ST_UNK)
1525 ti->ti_status = bshw_get_status_insat(bsc);
1526 }
1527
1528 ti->ti_msgin[ti->ti_msginptr ++] = bs_read_1byte(bsc);
1529 bs_msgin(bsc, ti);
1530 if (bsc->sc_cfgflags & BSC_FASTACK)
1531 bs_ack_wait(bsc, ti, cb);
1532
1533 return 1;
1534 }
1535 }
1536 else
1537 {
1538 /**************************************************
1539 * Special SCSI phase
1540 **************************************************/
1541 switch (scsi_status)
1542 {
1543 case BSR_SATSDP:/* SAT with save data pointer */
1544 BS_SAVE_SDP
1545 bshw_cmd_pass(bsc, 0x41);
1546 bshw_start_sat(bsc, 0);
1547 BS_SETUP_PHASE(SATSDP)
1548 return 1;
1549
1550 case BSR_SATFIN:/* SAT COMPLETE */
1551 ti->ti_status = bshw_get_status_insat(bsc);
1552 BS_SETUP_MSGPHASE(IOCOMPLETED);
1553 bs_disconnect_phase(bsc, ti, cb);
1554 return 1;
1555
1556 case BSR_ACKREQ:/* negate ACK */
1557 if (cb->msgoutlen > 0)
1558 {
1559 bshw_assert_atn(bsc);
1560 delay(800);
1561 BS_SETUP_PHASE(ATTENTIONASSERT);
1562 }
1563 bshw_negate_ack(bsc);
1564 return 1;
1565
1566 case BSR_DISC:/* disconnect */
1567 bs_disconnect_phase(bsc, ti, cb);
1568 return 1;
1569
1570 default:
1571 break;
1572 }
1573 }
1574
1575 bs_phase_error(ti, cb);
1576 return 1;
1577}
1578
1579/*****************************************************************
1580 * INTERNAL POLLING FUNCTIONS
1581 *****************************************************************/
1582static int
1583bs_scsi_cmd_poll_internal(cti)
1584 struct targ_info *cti;
1585{
1586 struct bs_softc *bsc = cti->ti_bsc;
1587 struct targ_info *ti;
1588 struct bsccb *cb;
1589 int i, waits, delay_count;
1590
1591 bsc->sc_poll++;
1592
1593 /* setup timeout count */
1594 if ((ti = bsc->sc_nexus) == NULL ||
1595 (cb = ti->ti_ctab.tqh_first) == NULL)
1596 waits = BS_DEFAULT_TIMEOUT_SECOND * 1000000;
1597 else
1598 waits = cb->tcmax * 1000000;
1599
1600 /* force all current jobs into the polling state. */
1601 for (i = 0; i < NTARGETS; i++)
1602 {
1603 if ((ti = bsc->sc_ti[i]) != NULL)
1604 {
1605 ti->ti_flags |= BSFORCEIOPOLL;
1606 if ((cb = ti->ti_ctab.tqh_first) != NULL)
1607 cb->bsccb_flags |= BSFORCEIOPOLL;
1608 }
1609 }
1610
1611 /* do io */
1612 bsc->sc_flags &= ~BSJOBDONE;
1613 do
1614 {
1615 delay_count = ((bsc->sc_flags & BSDMASTART) ? 1000000 : 100);
1616 delay(delay_count);
1617 waits -= delay_count;
1618 bs_sequencer(bsc);
1619 }
1620 while (waits >= 0 && (bsc->sc_flags & (BSUNDERRESET | BSJOBDONE)) == 0);
1621
1622 /* done */
1623 bsc->sc_poll--;
1624 if (waits < 0 || (bsc->sc_flags & BSUNDERRESET))
1625 {
1626 bs_printf(NULL, "cmd_poll", "timeout or fatal");
1627 return HASERROR;
1628 }
1629
1630 return COMPLETE;
1631}
1632
1633int
1634bs_scsi_cmd_poll(cti, targetcb)
1635 struct targ_info *cti;
1636 struct bsccb *targetcb;
1637{
1638 struct bs_softc *bsc = cti->ti_bsc;
1639 struct targ_info *ti;
1640 int s, error = COMPLETE;
1641
1642 s = splcam();
1643 bs_terminate_timeout(bsc);
1644
1645 if (bsc->sc_hstate == BSC_TARG_CHECK)
1646 {
1647 if ((error = bs_scsi_cmd_poll_internal(cti)) != COMPLETE)
1648 bs_reset_nexus(bsc);
1649 }
1650 else
1651 {
1652 if (bsc->sc_outccb)
1653 bs_panic(bsc, "bs_cmd_poll: internal error");
1654
1655 bsc->sc_flags &= ~BSPOLLDONE;
1656 bsc->sc_outccb = targetcb;
1657
1658 while ((bsc->sc_flags & BSPOLLDONE) == 0)
1659 {
1660 if (bs_scsi_cmd_poll_internal(cti) != COMPLETE)
1661 {
1662 if ((ti = bsc->sc_nexus) && ti->ti_ctab.tqh_first)
1663 ti->ti_error |= (BSTIMEOUT | BSABNORMAL);
1664 bs_reset_nexus(bsc);
1665 }
1666 }
1667
1668 bsc->sc_outccb = NULL;
1669 }
1670
1671 bs_start_timeout(bsc);
1672 softintr(bsc->sc_irq);
1673 splx(s);
1674 return error;
1675}