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$ */
    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 __P((struct bs_softc *));
   57 static BS_INLINE void bs_sat_continue __P((struct bs_softc *, struct targ_info *, struct bsccb *));
   58 static BS_INLINE struct targ_info *bs_selected __P((struct bs_softc *, struct targ_info *, struct bsccb *));
   59 static BS_INLINE u_int8_t bs_read_1byte __P((struct bs_softc *));
   60 static BS_INLINE void bs_write_1byte __P((struct bs_softc *, u_int8_t));
   61 static BS_INLINE void bs_commandout __P((struct bs_softc *, struct targ_info *, struct bsccb *));
   62 static BS_INLINE void bs_status_check __P((struct bs_softc *, struct targ_info *));
   63 static BS_INLINE void bs_msgin __P((struct bs_softc *, struct targ_info *));
   64 static BS_INLINE void bs_msgout __P((struct bs_softc *, struct targ_info *, struct bsccb *));
   65 static BS_INLINE void bs_disconnect_phase __P((struct bs_softc *, struct targ_info *, struct bsccb *));
   66 static void bs_phase_error __P((struct targ_info *, struct bsccb *));
   67 static int bs_scsi_cmd_poll_internal __P((struct targ_info *));
   68 static int bs_xfer __P((struct bs_softc *, char *, int));
   69 static void bs_io_xfer __P((struct targ_info *));
   70 static void bs_quick_abort __P((struct targ_info *, u_int));
   71 static void bs_msgin_error __P((struct targ_info *, u_int));
   72 static void bs_msgin_ext __P((struct targ_info *));
   73 static void bs_msg_reject __P((struct targ_info *));
   74 static void bshoststart __P((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 = ti->ti_ctab.tqh_first) == 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 = ti->ti_ctab.tqh_first;
  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 = ti->ti_ctab.tqh_first;
  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 = bsc->sc_sttab.tqh_first) == NULL)
  419                         return;
  420                 bs_hostque_delete(bsc, ti);
  421         }
  422 
  423         if ((cb = ti->ti_ctab.tqh_first) == 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                 for (tmpti = bsc->sc_titab.tqh_first; tmpti;
  454                      tmpti = tmpti->ti_tchain.tqe_next)
  455                         if (tmpti->ti_phase >= DISCONNECTED)
  456                                 goto retry;
  457         }
  458 
  459         /* start selection */
  460         ti->ti_status = ST_UNK;
  461         if (bs_check_sat(ti))
  462         {
  463                 if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
  464                 {
  465                         BS_LOAD_SDP
  466                         bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
  467                         bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
  468                         bshw_cmd_pass(bsc, 0);
  469                         bshw_set_sync_reg(bsc, ti->ti_sync);
  470                         bshw_issue_satcmd(bsc, cb, bs_check_link(ti, cb));
  471                         if (bs_check_smit(ti) || bsc->sc_p.datalen <= 0)
  472                                 bshw_set_count(bsc, 0);
  473                         else
  474                                 bs_dma_xfer(ti, BSHW_CMD_CHECK(cb, BSREAD));
  475 
  476                         s = splhigh();
  477                         if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
  478                         {
  479                                 /* XXX:
  480                                  * Reload a lun again here.
  481                                  */
  482                                 bshw_set_lun(bsc, ti->ti_lun);
  483                                 bshw_start_sat(bsc, bs_check_disc(ti));
  484                                 if ((bshw_get_auxstat(bsc) & STR_LCI) == 0)
  485                                 {
  486                                         splx(s);
  487                                         BS_HOST_START
  488                                         BS_SELECTION_START
  489                                         BS_SETUP_PHASE(SATSEL);
  490                                         ti->ti_omsgoutlen = 0;
  491                                         ti->ti_msgout = bs_identify_msg(ti);
  492 #ifdef  BS_DIAG
  493                                         ti->ti_flags |= BSNEXUS;
  494 #endif  /* BS_DIAG */
  495 #ifdef  BS_STATICS
  496                                         bs_statics[ti->ti_id].select_win++;
  497 #endif  /* BS_STATICS */
  498                                         return;
  499                                 }
  500                         }
  501                         splx(s);
  502 
  503                         if (bs_check_smit(ti) == 0)
  504                                 bshw_dmaabort(bsc, ti);
  505 #ifdef  BS_STATICS
  506                         bs_statics[ti->ti_id].select_miss_in_assert++;
  507 #endif  /* BS_STATICS */
  508                 }
  509         }
  510         else
  511         {
  512                 s = splhigh();
  513                 if ((bshw_get_auxstat(bsc) & STR_BUSY) == 0)
  514                 {
  515                         bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
  516                         bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
  517                         bshw_set_sync_reg(bsc, ti->ti_sync);
  518                         bshw_assert_select(bsc);
  519 
  520                         if ((bshw_get_auxstat(bsc) & STR_LCI) == 0)
  521                         {
  522                                 splx(s);
  523                                 BS_HOST_START
  524                                 BS_SELECTION_START
  525                                 BS_SETUP_PHASE(SELECTASSERT);
  526 #ifdef  BS_STATICS
  527                                 bs_statics[ti->ti_id].select_win++;
  528 #endif  /* BS_STATICS */
  529                                 return;
  530                         }
  531 #ifdef  BS_STATICS
  532                         bs_statics[ti->ti_id].select_miss_in_assert++;
  533 #endif  /* BS_STATICS */
  534                 }
  535                 splx(s);
  536         }
  537 
  538         /* RETRY LATER */
  539 retry:
  540 #ifdef  BS_STATICS
  541         bs_statics[ti->ti_id].select_miss++;
  542 #endif  /* BS_STATICS */
  543         bs_hostque_head(bsc, ti);
  544         BS_SETUP_PHASE(HOSTQUEUE)
  545 }
  546 
  547 static BS_INLINE struct targ_info *
  548 bs_selected(bsc, ti, cb)
  549         struct bs_softc *bsc;
  550         struct targ_info *ti;
  551         struct bsccb *cb;
  552 {
  553 
  554         if (bsc->sc_busstat != BSR_SELECTED)
  555         {
  556                 bs_phase_error(ti, cb);
  557                 return NULL;
  558         }
  559 
  560 #ifdef  BS_DIAG
  561         if (bsc->sc_selwait != ti)
  562                 panic("%s selection internal error\n", bsc->sc_dvname);
  563 
  564         ti->ti_flags |= BSNEXUS;
  565 #endif  /* BS_DIAG */
  566 
  567         /* clear select wait state */
  568         BS_SETUP_PHASE(SELECTED);
  569         BS_SELECTION_TERMINATE;
  570         BS_LOAD_SDP
  571         return ti;
  572 }
  573 
  574 /**************************************************
  575  *  <RESELECTION>
  576  **************************************************/
  577 static BS_INLINE struct targ_info *
  578 bs_reselect(bsc)
  579         struct bs_softc *bsc;
  580 {
  581         u_int target;
  582         struct targ_info *ti;
  583 
  584         /* check collision */
  585         if ((ti = bsc->sc_selwait) != NULL)
  586         {
  587                 if (ti->ti_phase == SATSEL)
  588                 {
  589 #ifdef  BS_DIAG
  590                         ti->ti_flags &= ~BSNEXUS;
  591 #endif  /* BS_DIAG */
  592                         ti->ti_msgout = 0;
  593                         if (bs_check_smit(ti) == 0)
  594                                 bshw_dmaabort(bsc, ti);
  595                 }
  596                 bs_hostque_head(bsc, ti);
  597                 BS_SELECTION_TERMINATE
  598                 BS_SETUP_PHASE(HOSTQUEUE)
  599 #ifdef  BS_STATICS
  600                 bs_statics[ti->ti_id].select_miss_by_reselect++;
  601                 bs_statics[ti->ti_id].select_miss++;
  602 #endif  /* BS_STATICS */
  603         }
  604 
  605         /* who are you ? */
  606         target = bshw_get_src_id(bsc);
  607         if ((ti = bsc->sc_ti[target]) == NULL)
  608         {
  609                 bs_debug_print_all(bsc);
  610                 printf("reselect: miss reselect. target(%d)\n", target);
  611                 bs_reset_nexus(bsc);
  612                 return NULL;
  613         }
  614 
  615         /* confirm nexus */
  616         BS_HOST_START
  617         bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);
  618         if (ti->ti_ctab.tqh_first == NULL || ti->ti_phase != DISCONNECTED)
  619         {
  620                 bs_printf(ti, "reselect", "phase mismatch");
  621                 BS_SETUP_PHASE(UNDEF)
  622                 bs_force_abort(ti);
  623                 bs_hostque_delete(bsc, ti);
  624         }
  625         else
  626                 bsc->sc_dtgnum --;
  627 
  628         /* recover host */
  629         bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
  630         bshw_set_sync_reg(bsc, ti->ti_sync);
  631         BS_RESTORE_SDP
  632         BS_SETUP_PHASE(RESELECTED)
  633 #ifdef  BS_STATICS
  634         bs_statics[ti->ti_id].reselect++;
  635 #endif  /* BS_STATICS */
  636         return ti;
  637 }
  638 
  639 static BS_INLINE void
  640 bs_sat_continue(bsc, ti, cb)
  641         struct bs_softc *bsc;
  642         struct targ_info *ti;
  643         struct bsccb *cb;
  644 {
  645 
  646         BS_SETUP_PHASE(SATRESEL);
  647         bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
  648         bshw_cmd_pass(bsc, 0x44);
  649         bshw_set_sync_reg(bsc, ti->ti_sync);
  650         bshw_issue_satcmd(bsc, cb, 0);
  651         if (bs_check_smit(ti) || bsc->sc_p.datalen <= 0)
  652                 bshw_set_count(bsc, 0);
  653         else
  654                 bs_dma_xfer(ti, BSHW_CMD_CHECK(cb, BSREAD));
  655         bshw_set_lun(bsc, ti->ti_lun);          /* XXX */
  656         bshw_start_sat(bsc, 0);
  657 }
  658 
  659 /*************************************************
  660  * <DATA PHASE>
  661  *************************************************/
  662 #define DR      (STR_BSY | STR_DBR)
  663 
  664 void
  665 bs_poll_timeout(bsc, s)
  666         struct bs_softc *bsc;
  667         char *s;
  668 {
  669         struct targ_info *ti;
  670 
  671         bs_printf(NULL, s, "timeout");
  672         bsc->sc_flags |= BSRESET;
  673         if ((ti = bsc->sc_nexus) && ti->ti_ctab.tqh_first)
  674                 ti->ti_error |= BSTIMEOUT;
  675 }
  676 
  677 static BS_INLINE u_int8_t
  678 bs_read_1byte(bsc)
  679         struct bs_softc *bsc;
  680 {
  681         register u_int wc;
  682 
  683         bshw_start_sxfer(bsc);
  684         for (wc = bsc->sc_wc; (bshw_get_auxstat(bsc) & DR) != DR && --wc; );
  685         if (wc)
  686                 return bshw_read_data(bsc);
  687         else
  688                 bs_poll_timeout(bsc, "read_1byte");
  689 
  690         return 0;
  691 }
  692 
  693 static BS_INLINE void
  694 bs_write_1byte(bsc, data)
  695         struct bs_softc *bsc;
  696         u_int8_t data;
  697 {
  698         register u_int wc;
  699 
  700         bshw_start_sxfer(bsc);
  701         for (wc = bsc->sc_wc; (bshw_get_auxstat(bsc) & DR) != DR && --wc; );
  702         if (wc)
  703                 bshw_write_data(bsc, data);
  704         else
  705                 bs_poll_timeout(bsc, "write_1byte");
  706 }
  707 
  708 static int
  709 bs_xfer(bsc, data, len)
  710         struct bs_softc *bsc;
  711         char *data;
  712         int len;
  713 {
  714         u_int8_t aux;
  715         u_int count, wc;
  716 
  717         bshw_set_count(bsc, len);
  718         bshw_start_xfer(bsc);
  719 
  720         for (count = 0, wc = bsc->sc_wc; count < len && --wc; )
  721         {
  722                 if (((aux = bshw_get_auxstat(bsc)) & DR) == DR)
  723                 {
  724                         if (bsc->sc_busstat & BSHW_READ)
  725                                 *(data++) = bshw_read_data(bsc);
  726                         else
  727                                 bshw_write_data(bsc, *(data++));
  728                         count++;
  729                         wc = bsc->sc_wc;
  730                 }
  731 
  732                 if (aux & STR_INT)
  733                         break;
  734         }
  735 
  736         if (wc == 0)
  737                 bs_poll_timeout(bsc, "bs_xfer");
  738 
  739         return count;
  740 }
  741 #undef  DR
  742 
  743 static void
  744 bs_io_xfer(ti)
  745         struct targ_info *ti;
  746 {
  747         struct bs_softc *bsc = ti->ti_bsc;
  748         struct sc_p *sp = &bsc->sc_p;
  749         u_int count, dummy;
  750 
  751         /* switch dma trasnfr mode */
  752         bshw_set_poll_trans(bsc, ti->ti_cfgflags);
  753         sp->seglen = 0;
  754         sp->bufp = NULL;
  755 
  756         if (sp->datalen <= 0)
  757         {
  758                 ti->ti_error |= BSDMAABNORMAL;
  759                 dummy = 0;
  760                 count = bs_xfer(bsc, (u_int8_t *) &dummy, 1);
  761         }
  762         else
  763                 count = bs_xfer(bsc, sp->data, sp->datalen);
  764 
  765         sp->data += count;
  766         sp->datalen -= count;
  767 }
  768 
  769 /************************************************
  770  * <COMMAND PHASE>
  771  ************************************************/
  772 static BS_INLINE void
  773 bs_commandout(bsc, ti, cb)
  774         struct bs_softc *bsc;
  775         struct targ_info *ti;
  776         struct bsccb *cb;
  777 {
  778         u_int8_t scsi_cmd[16];
  779         int len;
  780 
  781         BS_SETUP_PHASE(CMDPHASE);
  782 
  783         if (bs_check_link(ti, cb))
  784         {
  785                 bcopy(cb->cmd, scsi_cmd, cb->cmdlen);
  786                 scsi_cmd[cb->cmdlen - 1] |= 0x01;
  787                 len = bs_xfer(bsc, scsi_cmd, cb->cmdlen);
  788         }
  789         else
  790                 len = bs_xfer(bsc, cb->cmd, cb->cmdlen);
  791 
  792         if (len != cb->cmdlen)
  793                 ti->ti_error |= BSCMDABNORMAL;
  794 }
  795 
  796 /************************************************
  797  * <STATUS IN>
  798  ************************************************/
  799 static BS_INLINE void
  800 bs_status_check(bsc, ti)
  801         struct bs_softc *bsc;
  802         struct targ_info *ti;
  803 {
  804 
  805         if (ti->ti_status == ST_GOOD || ti->ti_status == ST_INTERGOOD)
  806                 return;
  807 
  808         switch (ti->ti_status)
  809         {
  810         case ST_MET:
  811         case ST_INTERMET:
  812         case ST_CHKCOND:
  813                 ti->ti_error |= BSREQSENSE;
  814                 break;
  815 
  816         case ST_BUSY:
  817                 ti->ti_error |= BSTARGETBUSY;
  818                 break;
  819 
  820         default:
  821                 ti->ti_error |= BSSTATUSERROR;
  822                 break;
  823         }
  824 }
  825 
  826 /************************************************
  827  * <MSG IN>
  828  ************************************************/
  829 #define MSGWAIT(cnt) { if (ti->ti_msginptr < (cnt)) return; }
  830 
  831 static void
  832 bs_quick_abort(ti, msg)
  833         struct targ_info *ti;
  834         u_int msg;
  835 {
  836         struct bsccb *cb;
  837 
  838         if ((cb = ti->ti_ctab.tqh_first) == NULL)
  839                 return;
  840 
  841         cb->msgoutlen = 1;
  842         cb->msgout[0] = msg;
  843         cb->rcnt++;
  844 
  845         ti->ti_error |= BSMSGERROR;
  846 }
  847 
  848 static void
  849 bs_msgin_error(ti, count)
  850         struct targ_info *ti;
  851         u_int count;
  852 {
  853         int n;
  854 
  855         MSGWAIT(count);
  856 
  857         bs_printf(ti, "msgin", "illegal msg");
  858 
  859         for (n = 0; n < ti->ti_msginptr; n ++)
  860                 printf("[0x%x] ", (u_int) ti->ti_msgin[n]);
  861         printf("\n");
  862 
  863         bs_quick_abort(ti, MSG_REJECT);
  864         ti->ti_msginptr = 0;
  865 }
  866 
  867 static void
  868 bs_msgin_ext(ti)
  869         struct targ_info *ti;
  870 {
  871         struct bs_softc *bsc = ti->ti_bsc;
  872         struct bsccb *cb = ti->ti_ctab.tqh_first;
  873         int count;
  874         u_int reqlen;
  875         u_int32_t *ptr;
  876         struct msgbase msg;
  877 
  878         MSGWAIT(2);
  879 
  880         reqlen = ti->ti_msgin[1];
  881         if (reqlen == 0)
  882                 reqlen = 256;
  883 
  884         if (ti->ti_msginptr >= MAXMSGLEN)
  885                 ti->ti_msginptr = 3;    /* XXX */
  886 
  887         MSGWAIT(reqlen + 2);
  888 
  889         switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
  890         {
  891         case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
  892                 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
  893                 count = (int) htonl((long) (*ptr));
  894 
  895                 bsc->sc_p.seglen = ti->ti_scsp.seglen = 0;
  896                 if (bsc->sc_p.datalen - count >= 0 &&
  897                     bsc->sc_p.datalen - count <= cb->datalen)
  898                 {
  899                         bsc->sc_p.datalen -= count;
  900                         bsc->sc_p.data += count;
  901                 }
  902                 else
  903                         bs_msgin_error(ti, 7);
  904                 break;
  905 
  906         case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
  907                 ti->ti_syncnow.period = ti->ti_msgin[3];
  908                 ti->ti_syncnow.offset = ti->ti_msgin[4];
  909                 if (ti->ti_syncnow.offset == 0)
  910                         ti->ti_syncnow.period = 0;
  911 
  912                 if (ti->ti_syncnow.state != BS_SYNCMSG_ASSERT)
  913                 {
  914                         bs_start_syncmsg(ti, NULL, BS_SYNCMSG_REQUESTED);
  915                         bscmdstart(ti, BSCMDSTART);
  916                 }
  917                 else
  918                         BS_SETUP_SYNCSTATE(BS_SYNCMSG_ACCEPT)
  919                 break;
  920 
  921         case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
  922                 msg.msglen = MSG_EXTEND_WIDELEN + 2;
  923                 msg.msg[0] = MSG_EXTEND;
  924                 msg.msg[1] = MSG_EXTEND_WIDELEN;
  925                 msg.msg[2] = MSG_EXTEND_WIDECODE;
  926                 msg.msg[3] = 0;
  927                 msg.flag = 0;
  928                 bs_make_msg_ccb(ti, cb->lun, cb, &msg, 0);
  929                 break;
  930 
  931         default:
  932                 bs_msgin_error(ti, 0);
  933                 return;
  934         }
  935 
  936         ti->ti_msginptr = 0;
  937         return;
  938 }
  939 
  940 static void
  941 bs_msg_reject(ti)
  942         struct targ_info *ti;
  943 {
  944         struct bs_softc *bsc = ti->ti_bsc;
  945         struct bsccb *cb = ti->ti_ctab.tqh_first;
  946         char *s = "unexpected msg reject";
  947 
  948         switch (ti->ti_ophase)
  949         {
  950         case CMDPHASE:
  951                 s = "cmd rejected";
  952                 cb->bsccb_flags &= ~BSLINK;
  953                 BS_SETUP_MSGPHASE(IOCOMPLETED);
  954                 break;
  955 
  956         case MSGOUT:
  957                 if (ti->ti_msgout & 0x80)
  958                 {
  959                         s = "identify msg rejected";
  960                         cb->bsccb_flags &= ~BSDISC;
  961                         BS_SETUP_MSGPHASE(IOCOMPLETED);
  962                 }
  963                 else if (ti->ti_msgout == MSG_EXTEND)
  964                 {
  965                         switch (ti->ti_emsgout)
  966                         {
  967                         case MSG_EXTEND_SYNCHCODE:
  968                                 BS_SETUP_SYNCSTATE(BS_SYNCMSG_REJECT);
  969                                 return;
  970 
  971                         default:
  972                                 break;
  973                         }
  974                 }
  975                 break;
  976 
  977         default:
  978                 break;
  979         }
  980 
  981         bs_debug_print(bsc, ti);
  982         bs_printf(ti, "msgin", s);
  983         ti->ti_error |= BSMSGERROR;
  984 }
  985 
  986 static BS_INLINE void
  987 bs_msgin(bsc, ti)
  988         struct bs_softc *bsc;
  989         struct targ_info *ti;
  990 {
  991 
  992         BS_SETUP_PHASE(MSGIN);
  993 
  994         switch (ti->ti_msgin[0])
  995         {
  996         case MSG_SAVESP:
  997                 BS_SAVE_SDP
  998                 break;
  999 
 1000         case MSG_RESTORESP:
 1001                 BS_RESTORE_SDP
 1002                 bs_printf(ti, "msgin", "restore scsi pointer");
 1003                 break;
 1004 
 1005         case MSG_REJECT:
 1006                 bs_msg_reject(ti);
 1007                 break;
 1008 
 1009         case 0xf:
 1010                 break;
 1011 
 1012         case MSG_I_ERROR:/* all I -> T : nothing to do*/
 1013         case MSG_ABORT:
 1014         case MSG_PARITY:
 1015         case MSG_RESET:
 1016         case 0xe:
 1017                 bs_msgin_error(ti, 1);
 1018                 goto resume;
 1019 
 1020         case MSG_NOOP:
 1021                 break;
 1022 
 1023         case MSG_EXTEND:
 1024                 bs_msgin_ext(ti);
 1025                 goto resume;
 1026 
 1027         case 0xd:
 1028                 bs_msgin_error(ti, 2);
 1029                 goto resume;
 1030 
 1031         case MSG_DISCON:
 1032                 BS_SETUP_MSGPHASE(DISCONNECTASSERT);
 1033                 break;
 1034 
 1035         case MSG_COMP:
 1036                 BS_SETUP_MSGPHASE(IOCOMPLETED);
 1037                 break;
 1038 
 1039         case MSG_LCOMP:
 1040         case MSG_LCOMP_F:
 1041                 bs_status_check(bsc, ti);
 1042                 if (bscmddone(ti) == NULL)
 1043                 {
 1044                         if (bscmdstart(ti, BSCMDSTART) == 0)
 1045                         {
 1046                                 bs_printf(ti, "msgin", "cmd line miss");
 1047                                 bs_force_abort(ti);
 1048                         }
 1049                 }
 1050                 else
 1051                         bscmdstart(ti, BSCMDRESTART);
 1052 #ifdef  BS_STATICS
 1053                 bs_linkcmd_count[ti->ti_id]++;
 1054 #endif  /* BS_STATICS */
 1055                 BS_LOAD_SDP
 1056                 ti->ti_status = ST_UNK;
 1057                 break;
 1058 
 1059         default:
 1060                 if (ti->ti_msgin[0] & 0x80)
 1061                 {
 1062                         if ((ti->ti_msgin[0] & 0x07) != ti->ti_lun)
 1063                         {
 1064                                 ti->ti_lun = (ti->ti_msgin[0] & 0x07);
 1065                                 bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);
 1066                                 bshw_set_sync_reg(bsc, ti->ti_sync);
 1067 
 1068                                 bs_printf(ti, "msgin", "lun error");
 1069                                 bs_quick_abort(ti, MSG_ABORT);
 1070                         }
 1071                         break;
 1072                 }
 1073                 else if (ti->ti_msgin[0] < 0x20)
 1074                         bs_msgin_error(ti, 1);
 1075                 else if (ti->ti_msgin[0] < 0x30)
 1076                         bs_msgin_error(ti, 2);
 1077                 else
 1078                         bs_msgin_error(ti, 1);
 1079                 goto resume;
 1080         }
 1081 
 1082         ti->ti_msginptr = 0;
 1083 
 1084 resume:
 1085         return;
 1086 }
 1087 
 1088 /************************************************
 1089  * <MSG OUT>
 1090  ************************************************/
 1091 static BS_INLINE void
 1092 bs_msgout(bsc, ti, cb)
 1093         struct bs_softc *bsc;
 1094         struct targ_info *ti;
 1095         struct bsccb *cb;
 1096 {
 1097         u_int8_t msg[MAXMSGLEN + 1];
 1098 
 1099         if (ti->ti_phase == MSGOUT)
 1100         {
 1101                 if (cb->rcnt ++ < bsc->sc_retry)
 1102                         cb->msgoutlen = ti->ti_omsgoutlen;
 1103         }
 1104         else
 1105                 BS_SETUP_PHASE(MSGOUT);
 1106 
 1107         if (ti->ti_ophase == SELECTED)
 1108         {
 1109 identify:
 1110                 if (cb->msgoutlen == 0)
 1111                 {
 1112                         ti->ti_msgout = bs_identify_msg(ti);
 1113                         ti->ti_omsgoutlen = 0;
 1114                         bs_write_1byte(bsc, ti->ti_msgout);
 1115                 }
 1116                 else
 1117                 {
 1118                         if (cb->msgout[0] != MSG_RESET &&
 1119                             cb->msgout[0] != MSG_ABORT)
 1120                         {
 1121                                 msg[0] = bs_identify_msg(ti);
 1122                                 bcopy(cb->msgout, &msg[1], cb->msgoutlen);
 1123                                 bs_xfer(bsc, msg, cb->msgoutlen + 1);
 1124                         }
 1125                         else
 1126                                 bs_xfer(bsc, cb->msgout, cb->msgoutlen);
 1127 
 1128                         ti->ti_msgout = cb->msgout[0];
 1129                         ti->ti_emsgout = cb->msgout[2];
 1130                         ti->ti_omsgoutlen = cb->msgoutlen;
 1131                         cb->msgoutlen = 0;
 1132                 }
 1133                 return;
 1134         }
 1135 
 1136         if (ti->ti_ophase == SATSEL)
 1137         {
 1138                 /* XXX:
 1139                  * Maybe identify msg rejected due to
 1140                  * a parity error in target side.
 1141                  */
 1142 
 1143                 bs_printf(ti, "msgout", "msg identify retry (SAT)");
 1144                 goto identify;
 1145         }
 1146 
 1147         if (cb->msgoutlen == 0)
 1148         {
 1149                 ti->ti_msgout = MSG_REJECT;
 1150                 ti->ti_omsgoutlen = 0;
 1151                 bs_write_1byte(bsc, ti->ti_msgout);
 1152         }
 1153         else
 1154         {
 1155                 ti->ti_msgout = cb->msgout[0];
 1156                 ti->ti_emsgout = cb->msgout[2];
 1157                 ti->ti_omsgoutlen = cb->msgoutlen;
 1158                 bs_xfer(bsc, cb->msgout, cb->msgoutlen);
 1159                 cb->msgoutlen = 0;
 1160         }
 1161 }
 1162 
 1163 /************************************************
 1164  * <DISCONNECT>
 1165  ************************************************/
 1166 static BS_INLINE void
 1167 bs_disconnect_phase(bsc, ti, cb)
 1168         struct bs_softc *bsc;
 1169         struct targ_info *ti;
 1170         struct bsccb *cb;
 1171 {
 1172 
 1173         switch (bsc->sc_msgphase)
 1174         {
 1175         default:
 1176                 panic("%s unknown msg phase\n", bsc->sc_dvname);
 1177                 break;
 1178 
 1179         case DISCONNECTASSERT:
 1180         case FREE:
 1181 #ifdef  BS_STATICS
 1182                 bs_statics[ti->ti_id].disconnected++;
 1183 #endif  /* BS_STATICS */
 1184                 if (ti->ti_cfgflags & BS_SCSI_SAVESP)
 1185                         BS_SAVE_SDP;
 1186                 BS_HOST_TERMINATE;
 1187                 BS_SETUP_PHASE(DISCONNECTED);
 1188                 bsc->sc_dtgnum ++;
 1189                 bshoststart(bsc, NULL);
 1190                 break;
 1191 
 1192         case IOCOMPLETED:
 1193                 bs_status_check(bsc, ti);
 1194                 cb = bscmddone(ti);
 1195 #ifdef  BS_DIAG
 1196                 ti->ti_flags &= ~BSNEXUS;
 1197 #endif  /* BS_DIAG */
 1198                 BS_SETUP_PHASE(FREE);
 1199                 if (cb || bsc->sc_sttab.tqh_first == NULL)
 1200                 {
 1201                         BS_HOST_TERMINATE;
 1202                         bscmdstart(ti, BSCMDSTART);
 1203                 }
 1204                 else
 1205                 {
 1206                         /* give a chance to other target */
 1207                         bscmdstart(ti, BSCMDSTART);
 1208                         BS_HOST_TERMINATE;
 1209                         bshoststart(bsc, NULL);
 1210                 }
 1211                 break;
 1212         }
 1213 
 1214         BS_SETUP_MSGPHASE(FREE);
 1215 }
 1216 
 1217 /**************************************************
 1218  * <PHASE ERROR>
 1219  **************************************************/
 1220 #define scsi_status     (bsc->sc_busstat)
 1221 
 1222 struct bs_err {
 1223         u_char  *pe_msg;
 1224         u_int   pe_err;
 1225         u_int   pe_ph;
 1226 };
 1227 
 1228 struct bs_err bs_cmderr[] = {
 1229 /**/   { "illegal cmd", BSABNORMAL, UNDEF },
 1230 /*1*/   { "unexpected bus free", BSABNORMAL, FREE },
 1231 /*2*/   { NULL, BSSELTIMEOUT, FREE},
 1232 /*3*/   { "scsi bus parity error", BSPARITY, UNDEF },
 1233 /*4*/   { "scsi bus parity error", BSPARITY, UNDEF },
 1234 /*5*/   { "unknown" , BSFATALIO, UNDEF },
 1235 /*6*/   { "miss reselection (target mode)", BSFATALIO, UNDEF },
 1236 /*7*/   { "wrong status byte", BSPARITY, STATUSIN },
 1237 };
 1238 
 1239 static void
 1240 bs_phase_error(ti, cb)
 1241         struct targ_info *ti;
 1242         struct bsccb *cb;
 1243 {
 1244         struct bs_softc *bsc = ti->ti_bsc;
 1245         struct bs_err *pep;
 1246 
 1247         if ((scsi_status & BSR_CM) == BSR_CMDERR &&
 1248             (scsi_status & BSR_PHVALID) == 0)
 1249         {
 1250                 pep = &bs_cmderr[scsi_status & BSR_PM];
 1251                 ti->ti_error |= pep->pe_err;
 1252                 if (pep->pe_msg)
 1253                 {
 1254                         bs_debug_print(bsc, ti);
 1255                         bs_printf(ti, "bsintr", pep->pe_msg);
 1256                 }
 1257                 BS_SETUP_PHASE(pep->pe_ph);
 1258         }
 1259         else
 1260         {
 1261                 ti->ti_error |= BSABNORMAL;
 1262                 bs_debug_print(bsc, ti);
 1263                 bs_printf(ti, "bsintr", "phase error");
 1264                 BS_SETUP_PHASE(UNDEF);
 1265         }
 1266 
 1267         BS_SETUP_MSGPHASE(FREE);
 1268         switch (ti->ti_phase)
 1269         {
 1270         case FREE:
 1271                 BS_SETUP_PHASE(UNDEF);
 1272                 cb = bscmddone(ti);
 1273 #ifdef  BS_DIAG
 1274                 ti->ti_flags &= ~BSNEXUS;
 1275 #endif  /* BS_DIAG */
 1276                 BS_HOST_TERMINATE;
 1277                 BS_SETUP_PHASE(FREE);
 1278                 bscmdstart(ti, ((cb == NULL) ? BSCMDSTART : BSCMDRESTART));
 1279                 break;
 1280 
 1281         case STATUSIN:
 1282                 ti->ti_error |= BSSTATUSERROR;
 1283                 ti->ti_status = bshw_get_status_insat(bsc);     /* XXX SAT */
 1284                 bs_debug_print(bsc, ti);
 1285                 break;
 1286 
 1287         case UNDEF:
 1288         default:
 1289                 ti->ti_error |= BSABNORMAL;
 1290                 bs_reset_nexus(bsc);
 1291                 break;
 1292         }
 1293 }
 1294 
 1295 /**************************************************
 1296  * ### SCSI PHASE SEQUENCER ###
 1297  **************************************************/
 1298 static BS_INLINE void bs_ack_wait __P((struct bs_softc *, struct targ_info *, struct bsccb *));
 1299 
 1300 static BS_INLINE void
 1301 bs_ack_wait(bsc, ti, cb)
 1302         struct bs_softc *bsc;
 1303         struct targ_info *ti;
 1304         struct bsccb *cb;
 1305 {
 1306         int wc = bsc->sc_wc;
 1307 
 1308         for (wc = bsc->sc_wc; bshw_get_busstat(bsc) != BSR_ACKREQ && wc > 0; )
 1309                 wc --;
 1310 
 1311         if (wc <= 0)
 1312         {
 1313                 bs_printf(ti, "bs_ack_wait", "timeout I");
 1314                 return;
 1315         }
 1316 
 1317         bshw_get_auxstat(bsc);
 1318         scsi_status = bshw_get_busstat(bsc);
 1319 
 1320         if (cb->msgoutlen > 0)
 1321         {
 1322                 bshw_assert_atn(bsc);
 1323                 delay(800);
 1324                 BS_SETUP_PHASE(ATTENTIONASSERT);
 1325         }
 1326 
 1327         bshw_negate_ack(bsc);
 1328 
 1329 #ifdef  WAITNEXTP
 1330         for (wc = bsc->sc_wc; bshw_get_busstat(bsc) == BSR_ACKREQ && wc > 0; )
 1331                 wc --;
 1332 
 1333         if (wc <= 0)
 1334                 bs_printf(ti, "bs_ack_wait", "timeout II");
 1335 #endif  /* WAITNEXTP */
 1336 }
 1337 
 1338 int
 1339 bs_sequencer(bsc)
 1340         struct bs_softc *bsc;
 1341 {
 1342         register struct targ_info *ti;
 1343         struct bsccb *cb;
 1344 
 1345         /**************************************************
 1346          * Check reset
 1347          **************************************************/
 1348         if (bsc->sc_flags & (BSRESET | BSINACTIVE))
 1349         {
 1350                 if (bsc->sc_flags & BSRESET)
 1351                         bs_reset_nexus(bsc);
 1352                 return 1;
 1353         }
 1354 
 1355         /**************************************************
 1356          * Get status & bus phase
 1357          **************************************************/
 1358         if ((bshw_get_auxstat(bsc) & STR_INT) == 0)
 1359                 return 0;
 1360 
 1361         scsi_status = bshw_get_busstat(bsc);
 1362         if (scsi_status == ((u_int8_t) -1))
 1363         {
 1364                 bs_debug_print_all(bsc);
 1365                 return 1;
 1366         }
 1367         /**************************************************
 1368          * Check reselection, or nexus
 1369          **************************************************/
 1370         if (scsi_status == BSR_RESEL)
 1371         {
 1372                 bs_reselect(bsc);
 1373                 return 1;
 1374         }
 1375 
 1376         ti = bsc->sc_nexus;
 1377         if (ti == NULL || (cb = ti->ti_ctab.tqh_first) == NULL)
 1378         {
 1379                 bs_debug_print_all(bsc);
 1380                 bs_printf(ti, "bsintr", "no nexus");
 1381                 bs_reset_nexus(bsc);
 1382                 return 1;
 1383         }
 1384 
 1385         /**************************************************
 1386          * Debug section
 1387          **************************************************/
 1388 #ifdef  BS_DEBUG
 1389         if (bs_debug_flag)
 1390         {
 1391                 bs_debug_print(bsc, ti);
 1392                 if (bs_debug_flag > 1)
 1393                         Debugger();
 1394         }
 1395 #endif  /* BS_DEBUG */
 1396 
 1397         /**************************************************
 1398          * internal scsi phase
 1399          **************************************************/
 1400         switch (ti->ti_phase)
 1401         {
 1402         case SELECTASSERT:
 1403                 bs_selected(bsc, ti, cb);
 1404                 return 1;
 1405 
 1406         case SATSEL:
 1407                 BS_SELECTION_TERMINATE;
 1408 
 1409         case SATRESEL:
 1410                 if (bsc->sc_flags & (BSDMASTART | BSSMITSTART))
 1411                 {
 1412                         if (bsc->sc_flags & BSSMITSTART)
 1413                         {
 1414                                 bs_debug_print_all(bsc);
 1415                                 bs_reset_nexus(bsc);
 1416                                 bs_printf(ti, "bsintr", "smit transfer");
 1417                                 return 1;
 1418                         }
 1419 
 1420                         BS_SETUP_PHASE(DATAPHASE);      /* XXX */
 1421                         bs_dma_xfer_end(ti);
 1422                         ti->ti_phase = ti->ti_ophase;   /* XXX */
 1423                 }
 1424                 break;
 1425 
 1426         default:
 1427                 /* XXX:
 1428                  * check check check for safety !!
 1429                  */
 1430                 if (bsc->sc_selwait)
 1431                 {
 1432                         /* Ghaaa! phase error! retry! */
 1433                         bs_phase_error(ti, cb);
 1434                         return 1;
 1435                 }
 1436 
 1437                 if (bsc->sc_flags & (BSDMASTART | BSSMITSTART))
 1438                 {
 1439                         if (bsc->sc_flags & BSDMASTART)
 1440                                 bs_dma_xfer_end(ti);
 1441                         else
 1442                                 bs_smit_xfer_end(ti);
 1443                 }
 1444                 break;
 1445         }
 1446 
 1447         /**************************************************
 1448          * hw scsi phase
 1449          **************************************************/
 1450         if (scsi_status & BSR_PHVALID)
 1451         {
 1452                 /**************************************************
 1453                  * Normal SCSI phase.
 1454                  **************************************************/
 1455                 if ((scsi_status & BSR_CM) == BSR_CMDABT)
 1456                 {
 1457                         bs_phase_error(ti, cb);
 1458                         return 1;
 1459                 }
 1460 
 1461                 switch (scsi_status & BSR_PM)
 1462                 {
 1463                 case BSR_DATAOUT:
 1464                 case BSR_DATAIN:
 1465                         BS_SETUP_PHASE(DATAPHASE);
 1466 
 1467                         if (bsc->sc_p.datalen <= 0 ||
 1468                             (ti->ti_flags & BSFORCEIOPOLL))
 1469                         {
 1470                                 bs_io_xfer(ti);
 1471                                 return 1;
 1472                         }
 1473 
 1474                         if (bs_check_smit(ti) &&
 1475                             (bsc->sc_p.datalen % sizeof(u_int32_t)) == 0)
 1476                         {
 1477                                 bs_lc_smit_xfer(ti, scsi_status & BSR_IOR);
 1478                                 return 1;
 1479                         }
 1480 
 1481                         bs_dma_xfer(ti, scsi_status & BSR_IOR);
 1482                         bshw_start_xfer(bsc);
 1483                         return 1;
 1484 
 1485                 case BSR_CMDOUT:
 1486                         bs_commandout(bsc, ti, cb);
 1487                         return 1;
 1488 
 1489                 case BSR_STATIN:
 1490                         if (bs_check_sat(ti))
 1491                         {
 1492                                 BS_SETUP_PHASE(SATCOMPSEQ);
 1493                                 bshw_set_count(bsc, 0);
 1494                                 bshw_cmd_pass(bsc, 0x41);
 1495                                 bshw_start_sat(bsc, 0);
 1496                         }
 1497                         else
 1498                         {
 1499                                 BS_SETUP_PHASE(STATUSIN);
 1500                                 ti->ti_status = bs_read_1byte(bsc);
 1501                         }
 1502                         return 1;
 1503 
 1504                 case BSR_UNSPINFO0:
 1505                 case BSR_UNSPINFO1:
 1506                         bs_debug_print(bsc, ti);
 1507                         bs_printf(ti, "bsintr", "illegal bus phase");
 1508                         return 1;
 1509 
 1510                 case BSR_MSGOUT:
 1511                         bs_msgout(bsc, ti, cb);
 1512                         return 1;
 1513 
 1514                 case BSR_MSGIN:/* msg in */
 1515                         if (bs_check_sat(ti))
 1516                         {
 1517                                 if (ti->ti_phase == RESELECTED)
 1518                                 {
 1519                                         bs_sat_continue(bsc, ti, cb);
 1520                                         return 1;
 1521                                 }
 1522                                         /* XXX */
 1523                                 if (ti->ti_status == ST_UNK)
 1524                                         ti->ti_status = bshw_get_status_insat(bsc);
 1525                         }
 1526 
 1527                         ti->ti_msgin[ti->ti_msginptr ++] = bs_read_1byte(bsc);
 1528                         bs_msgin(bsc, ti);
 1529                         if (bsc->sc_cfgflags & BSC_FASTACK)
 1530                                 bs_ack_wait(bsc, ti, cb);
 1531 
 1532                         return 1;
 1533                 }
 1534         }
 1535         else
 1536         {
 1537                 /**************************************************
 1538                  * Special SCSI phase
 1539                  **************************************************/
 1540                 switch (scsi_status)
 1541                 {
 1542                 case BSR_SATSDP:/* SAT with save data pointer */
 1543                         BS_SAVE_SDP
 1544                         bshw_cmd_pass(bsc, 0x41);
 1545                         bshw_start_sat(bsc, 0);
 1546                         BS_SETUP_PHASE(SATSDP)
 1547                         return 1;
 1548 
 1549                 case BSR_SATFIN:/* SAT COMPLETE */
 1550                         ti->ti_status = bshw_get_status_insat(bsc);
 1551                         BS_SETUP_MSGPHASE(IOCOMPLETED);
 1552                         bs_disconnect_phase(bsc, ti, cb);
 1553                         return 1;
 1554 
 1555                 case BSR_ACKREQ:/* negate ACK */
 1556                         if (cb->msgoutlen > 0)
 1557                         {
 1558                                 bshw_assert_atn(bsc);
 1559                                 delay(800);
 1560                                 BS_SETUP_PHASE(ATTENTIONASSERT);
 1561                         }
 1562                         bshw_negate_ack(bsc);
 1563                         return 1;
 1564 
 1565                 case BSR_DISC:/* disconnect */
 1566                         bs_disconnect_phase(bsc, ti, cb);
 1567                         return 1;
 1568 
 1569                 default:
 1570                         break;
 1571                 }
 1572         }
 1573 
 1574         bs_phase_error(ti, cb);
 1575         return 1;
 1576 }
 1577 
 1578 /*****************************************************************
 1579  * INTERNAL POLLING FUNCTIONS
 1580  *****************************************************************/
 1581 static int
 1582 bs_scsi_cmd_poll_internal(cti)
 1583         struct targ_info *cti;
 1584 {
 1585         struct bs_softc *bsc = cti->ti_bsc;
 1586         struct targ_info *ti;
 1587         struct bsccb *cb;
 1588         int i, waits, delay_count;
 1589 
 1590         bsc->sc_poll++;
 1591 
 1592         /* setup timeout count */
 1593         if ((ti = bsc->sc_nexus) == NULL ||
 1594             (cb = ti->ti_ctab.tqh_first) == NULL)
 1595                 waits = BS_DEFAULT_TIMEOUT_SECOND * 1000000;
 1596         else
 1597                 waits = cb->tcmax * 1000000;
 1598 
 1599         /* force all current jobs into the polling state. */
 1600         for (i = 0; i < NTARGETS; i++)
 1601         {
 1602                 if ((ti = bsc->sc_ti[i]) != NULL)
 1603                 {
 1604                         ti->ti_flags |= BSFORCEIOPOLL;
 1605                         if ((cb = ti->ti_ctab.tqh_first) != NULL)
 1606                                 cb->bsccb_flags |= BSFORCEIOPOLL;
 1607                 }
 1608         }
 1609 
 1610         /* do io */
 1611         bsc->sc_flags &= ~BSJOBDONE;
 1612         do
 1613         {
 1614                 delay_count = ((bsc->sc_flags & BSDMASTART) ? 1000000 : 100);
 1615                 delay(delay_count);
 1616                 waits -= delay_count;
 1617                 bs_sequencer(bsc);
 1618         }
 1619         while (waits >= 0 && (bsc->sc_flags & (BSUNDERRESET | BSJOBDONE)) == 0);
 1620 
 1621         /* done */
 1622         bsc->sc_poll--;
 1623         if (waits < 0 || (bsc->sc_flags & BSUNDERRESET))
 1624         {
 1625                 bs_printf(NULL, "cmd_poll", "timeout or fatal");
 1626                 return HASERROR;
 1627         }
 1628 
 1629         return COMPLETE;
 1630 }
 1631 
 1632 int
 1633 bs_scsi_cmd_poll(cti, targetcb)
 1634         struct targ_info *cti;
 1635         struct bsccb *targetcb;
 1636 {
 1637         struct bs_softc *bsc = cti->ti_bsc;
 1638         struct targ_info *ti;
 1639         int s, error = COMPLETE;
 1640 
 1641         s = splcam();
 1642         bs_terminate_timeout(bsc);
 1643 
 1644         if (bsc->sc_hstate == BSC_TARG_CHECK)
 1645         {
 1646                 if ((error = bs_scsi_cmd_poll_internal(cti)) != COMPLETE)
 1647                         bs_reset_nexus(bsc);
 1648         }
 1649         else
 1650         {
 1651                 if (bsc->sc_outccb)
 1652                         bs_panic(bsc, "bs_cmd_poll: internal error");
 1653 
 1654                 bsc->sc_flags &= ~BSPOLLDONE;
 1655                 bsc->sc_outccb = targetcb;
 1656 
 1657                 while ((bsc->sc_flags & BSPOLLDONE) == 0)
 1658                 {
 1659                         if (bs_scsi_cmd_poll_internal(cti) != COMPLETE)
 1660                         {
 1661                                 if ((ti = bsc->sc_nexus) && ti->ti_ctab.tqh_first)
 1662                                         ti->ti_error |= (BSTIMEOUT | BSABNORMAL);
 1663                                 bs_reset_nexus(bsc);
 1664                         }
 1665                 }
 1666 
 1667                 bsc->sc_outccb = NULL;
 1668         }
 1669 
 1670         bs_start_timeout(bsc);
 1671         softintr(bsc->sc_irq);
 1672         splx(s);
 1673         return error;
 1674 }

Cache object: 5bcaa40455f3e91f6340b78de272df83


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