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

Cache object: 99da45df2873e866280d46f4091583e2


[ 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.