remove __P() from this directory
[dragonfly.git] / sys / dev / disk / i386 / bs / bs.c
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 $ */
4 /* $DragonFly: src/sys/dev/disk/i386/bs/Attic/bs.c,v 1.5 2003/08/27 10:35:16 rob Exp $ */
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__
41 #include "bsif.h"
42 #endif
43
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>
49
50 #include <bus/cam/scsi/scsi_all.h>
51 #include <bus/cam/scsi/scsi_message.h>
52
53 /*****************************************************************
54  * Inline phase funcs
55  *****************************************************************/
56 /* static inline declare */
57 static BS_INLINE struct targ_info *bs_reselect (struct bs_softc *);
58 static BS_INLINE void bs_sat_continue (struct bs_softc *, struct targ_info *, struct bsccb *);
59 static BS_INLINE struct targ_info *bs_selected (struct bs_softc *, struct targ_info *, struct bsccb *);
60 static BS_INLINE u_int8_t bs_read_1byte (struct bs_softc *);
61 static BS_INLINE void bs_write_1byte (struct bs_softc *, u_int8_t);
62 static BS_INLINE void bs_commandout (struct bs_softc *, struct targ_info *, struct bsccb *);
63 static BS_INLINE void bs_status_check (struct bs_softc *, struct targ_info *);
64 static BS_INLINE void bs_msgin (struct bs_softc *, struct targ_info *);
65 static BS_INLINE void bs_msgout (struct bs_softc *, struct targ_info *, struct bsccb *);
66 static BS_INLINE void bs_disconnect_phase (struct bs_softc *, struct targ_info *, struct bsccb *);
67 static void bs_phase_error (struct targ_info *, struct bsccb *);
68 static int bs_scsi_cmd_poll_internal (struct targ_info *);
69 static int bs_xfer (struct bs_softc *, char *, int);
70 static void bs_io_xfer (struct targ_info *);
71 static void bs_quick_abort (struct targ_info *, u_int);
72 static void bs_msgin_error (struct targ_info *, u_int);
73 static void bs_msgin_ext (struct targ_info *);
74 static void bs_msg_reject (struct targ_info *);
75 static void bshoststart (struct bs_softc *, struct targ_info *);
76
77 /*****************************************************************
78  * SIM interface
79  *****************************************************************/
80 void
81 bs_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  */
234 int
235 bscmdstart(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
280 struct bsccb *
281 bscmddone(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  **************************************************/
405 static void
406 bshoststart(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
416 again:
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 */
540 retry:
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
548 static BS_INLINE struct targ_info *
549 bs_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  **************************************************/
578 static BS_INLINE struct targ_info *
579 bs_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
640 static BS_INLINE void
641 bs_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
665 void
666 bs_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
678 static BS_INLINE u_int8_t
679 bs_read_1byte(bsc)
680         struct bs_softc *bsc;
681 {
682         u_int wc;
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
694 static BS_INLINE void
695 bs_write_1byte(bsc, data)
696         struct bs_softc *bsc;
697         u_int8_t data;
698 {
699         u_int wc;
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
709 static int
710 bs_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
744 static void
745 bs_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  ************************************************/
773 static BS_INLINE void
774 bs_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  ************************************************/
800 static BS_INLINE void
801 bs_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
832 static void
833 bs_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
849 static void
850 bs_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
868 static void
869 bs_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
941 static void
942 bs_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
987 static BS_INLINE void
988 bs_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
1085 resume:
1086         return;
1087 }
1088
1089 /************************************************
1090  * <MSG OUT>
1091  ************************************************/
1092 static BS_INLINE void
1093 bs_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         {
1110 identify:
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  ************************************************/
1167 static BS_INLINE void
1168 bs_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
1223 struct bs_err {
1224         u_char  *pe_msg;
1225         u_int   pe_err;
1226         u_int   pe_ph;
1227 };
1228
1229 struct 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
1240 static void
1241 bs_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  **************************************************/
1299 static BS_INLINE void bs_ack_wait (struct bs_softc *, struct targ_info *, struct bsccb *);
1300
1301 static BS_INLINE void
1302 bs_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
1339 int
1340 bs_sequencer(bsc)
1341         struct bs_softc *bsc;
1342 {
1343         struct targ_info *ti;
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  *****************************************************************/
1582 static int
1583 bs_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
1633 int
1634 bs_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 }