The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/bs/bs.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: daa30d6369be69ab91bb4cf5700ab5f5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.