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/dev/advansys/advlib.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 /*-
    2  * Low level routines for the Advanced Systems Inc. SCSI controllers chips
    3  *
    4  * SPDX-License-Identifier: BSD-3-Clause
    5  *
    6  * Copyright (c) 1996-1997, 1999-2000 Justin Gibbs.
    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  *    without modification, immediately at the beginning of the file.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   25  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  */
   33 /*-
   34  * Ported from:
   35  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
   36  *     
   37  * Copyright (c) 1995-1996 Advanced System Products, Inc.
   38  * All Rights Reserved.
   39  *   
   40  * Redistribution and use in source and binary forms, with or without
   41  * modification, are permitted provided that redistributions of source
   42  * code retain the above copyright notice and this comment without
   43  * modification.
   44  */
   45 
   46 #include <sys/cdefs.h>
   47 __FBSDID("$FreeBSD: releng/12.0/sys/dev/advansys/advlib.c 326255 2017-11-27 14:52:40Z pfg $");
   48 
   49 #include <sys/param.h>
   50 #include <sys/conf.h>
   51 #include <sys/lock.h>
   52 #include <sys/kernel.h>
   53 #include <sys/mutex.h>
   54 #include <sys/systm.h>
   55 
   56 #include <machine/bus.h>
   57 #include <machine/resource.h>
   58 #include <sys/bus.h> 
   59 #include <sys/rman.h> 
   60 
   61 #include <cam/cam.h>
   62 #include <cam/cam_ccb.h>
   63 #include <cam/cam_sim.h>
   64 #include <cam/cam_xpt_sim.h>
   65 
   66 #include <cam/scsi/scsi_all.h>
   67 #include <cam/scsi/scsi_message.h>
   68 #include <cam/scsi/scsi_da.h>
   69 #include <cam/scsi/scsi_cd.h>
   70 
   71 #include <vm/vm.h>
   72 #include <vm/vm_param.h>
   73 #include <vm/pmap.h>
   74 
   75 #include <dev/advansys/advansys.h>
   76 #include <dev/advansys/advmcode.h>
   77 
   78 struct adv_quirk_entry {
   79         struct scsi_inquiry_pattern inq_pat;
   80         u_int8_t quirks;
   81 #define ADV_QUIRK_FIX_ASYN_XFER_ALWAYS  0x01
   82 #define ADV_QUIRK_FIX_ASYN_XFER         0x02
   83 };
   84 
   85 static struct adv_quirk_entry adv_quirk_table[] =
   86 {
   87         {
   88                 { T_CDROM, SIP_MEDIA_REMOVABLE, "HP", "*", "*" },
   89                 ADV_QUIRK_FIX_ASYN_XFER_ALWAYS|ADV_QUIRK_FIX_ASYN_XFER
   90         },
   91         {
   92                 { T_CDROM, SIP_MEDIA_REMOVABLE, "NEC", "CD-ROM DRIVE", "*" },
   93                 0
   94         },
   95         {
   96                 {
   97                   T_SEQUENTIAL, SIP_MEDIA_REMOVABLE,
   98                   "TANDBERG", " TDC 36", "*"
   99                 },
  100                 0
  101         },
  102         {
  103                 { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "WANGTEK", "*", "*" },
  104                 0
  105         },
  106         {
  107                 {
  108                   T_PROCESSOR, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
  109                   "*", "*", "*"
  110                 },
  111                 0
  112         },
  113         {
  114                 {
  115                   T_SCANNER, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
  116                   "*", "*", "*"
  117                 },
  118                 0
  119         },
  120         {
  121                 /* Default quirk entry */
  122                 {
  123                   T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
  124                   /*vendor*/"*", /*product*/"*", /*revision*/"*"
  125                 }, 
  126                 ADV_QUIRK_FIX_ASYN_XFER,
  127         }
  128 };
  129 
  130 /*
  131  * Allowable periods in ns
  132  */
  133 static u_int8_t adv_sdtr_period_tbl[] =
  134 {
  135         25,
  136         30,
  137         35,
  138         40,
  139         50,
  140         60,
  141         70,
  142         85
  143 };
  144 
  145 static u_int8_t adv_sdtr_period_tbl_ultra[] =
  146 {
  147         12,
  148         19,
  149         25,
  150         32,
  151         38,
  152         44,
  153         50,
  154         57,
  155         63,
  156         69,
  157         75,
  158         82,
  159         88, 
  160         94,
  161         100,
  162         107
  163 };
  164 
  165 struct ext_msg {
  166         u_int8_t msg_type;
  167         u_int8_t msg_len;
  168         u_int8_t msg_req;
  169         union {
  170                 struct {
  171                         u_int8_t sdtr_xfer_period;
  172                         u_int8_t sdtr_req_ack_offset;
  173                 } sdtr;
  174                 struct {
  175                         u_int8_t wdtr_width;
  176                 } wdtr;
  177                 struct {
  178                         u_int8_t mdp[4];
  179                 } mdp;
  180         } u_ext_msg;
  181         u_int8_t res;
  182 };
  183 
  184 #define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period
  185 #define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset
  186 #define wdtr_width      u_ext_msg.wdtr.wdtr_width
  187 #define mdp_b3          u_ext_msg.mdp_b3
  188 #define mdp_b2          u_ext_msg.mdp_b2
  189 #define mdp_b1          u_ext_msg.mdp_b1
  190 #define mdp_b0          u_ext_msg.mdp_b0
  191 
  192 /*
  193  * Some of the early PCI adapters have problems with
  194  * async transfers.  Instead use an offset of 1.
  195  */
  196 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
  197 
  198 /* LRAM routines */
  199 static void      adv_read_lram_16_multi(struct adv_softc *adv, u_int16_t s_addr,
  200                                         u_int16_t *buffer, int count);
  201 static void      adv_write_lram_16_multi(struct adv_softc *adv,
  202                                          u_int16_t s_addr, u_int16_t *buffer,
  203                                          int count);
  204 static void      adv_mset_lram_16(struct adv_softc *adv, u_int16_t s_addr,
  205                                   u_int16_t set_value, int count);
  206 static u_int32_t adv_msum_lram_16(struct adv_softc *adv, u_int16_t s_addr,
  207                                   int count);
  208 
  209 static int       adv_write_and_verify_lram_16(struct adv_softc *adv,
  210                                               u_int16_t addr, u_int16_t value);
  211 static u_int32_t adv_read_lram_32(struct adv_softc *adv, u_int16_t addr);
  212 
  213 
  214 static void      adv_write_lram_32(struct adv_softc *adv, u_int16_t addr,
  215                                    u_int32_t value);
  216 static void      adv_write_lram_32_multi(struct adv_softc *adv,
  217                                          u_int16_t s_addr, u_int32_t *buffer,
  218                                          int count);
  219 
  220 /* EEPROM routines */
  221 static u_int16_t adv_read_eeprom_16(struct adv_softc *adv, u_int8_t addr);
  222 static u_int16_t adv_write_eeprom_16(struct adv_softc *adv, u_int8_t addr,
  223                                      u_int16_t value);
  224 static int       adv_write_eeprom_cmd_reg(struct adv_softc *adv,
  225                                           u_int8_t cmd_reg);
  226 static int       adv_set_eeprom_config_once(struct adv_softc *adv,
  227                                             struct adv_eeprom_config *eeconfig);
  228 
  229 /* Initialization */
  230 static u_int32_t adv_load_microcode(struct adv_softc *adv, u_int16_t s_addr,
  231                                     u_int16_t *mcode_buf, u_int16_t mcode_size);
  232 
  233 static void      adv_reinit_lram(struct adv_softc *adv);
  234 static void      adv_init_lram(struct adv_softc *adv);
  235 static int       adv_init_microcode_var(struct adv_softc *adv);
  236 static void      adv_init_qlink_var(struct adv_softc *adv);
  237 
  238 /* Interrupts */
  239 static void      adv_disable_interrupt(struct adv_softc *adv);
  240 static void      adv_enable_interrupt(struct adv_softc *adv);
  241 static void      adv_toggle_irq_act(struct adv_softc *adv);
  242 
  243 /* Chip Control */
  244 static int       adv_host_req_chip_halt(struct adv_softc *adv);
  245 static void      adv_set_chip_ih(struct adv_softc *adv, u_int16_t ins_code);
  246 #if 0
  247 static u_int8_t  adv_get_chip_scsi_ctrl(struct adv_softc *adv);
  248 #endif
  249 
  250 /* Queue handling and execution */
  251 static __inline int
  252                  adv_sgcount_to_qcount(int sgcount);
  253 
  254 static __inline int
  255 adv_sgcount_to_qcount(int sgcount)
  256 {
  257         int     n_sg_list_qs;
  258 
  259         n_sg_list_qs = ((sgcount - 1) / ADV_SG_LIST_PER_Q);
  260         if (((sgcount - 1) % ADV_SG_LIST_PER_Q) != 0)
  261                 n_sg_list_qs++;
  262         return (n_sg_list_qs + 1);
  263 }
  264 
  265 #if BYTE_ORDER == BIG_ENDIAN
  266 static void      adv_adj_endian_qdone_info(struct adv_q_done_info *);
  267 static void      adv_adj_scsiq_endian(struct adv_scsi_q *);
  268 #endif
  269 static void      adv_get_q_info(struct adv_softc *adv, u_int16_t s_addr,
  270                                 u_int16_t *inbuf, int words);
  271 static u_int     adv_get_num_free_queues(struct adv_softc *adv, u_int8_t n_qs);
  272 static u_int8_t  adv_alloc_free_queues(struct adv_softc *adv,
  273                                        u_int8_t free_q_head, u_int8_t n_free_q);
  274 static u_int8_t  adv_alloc_free_queue(struct adv_softc *adv,
  275                                       u_int8_t free_q_head);
  276 static int       adv_send_scsi_queue(struct adv_softc *adv,
  277                                      struct adv_scsi_q *scsiq,
  278                                      u_int8_t n_q_required);
  279 static void      adv_put_ready_sg_list_queue(struct adv_softc *adv,
  280                                              struct adv_scsi_q *scsiq,
  281                                              u_int q_no);
  282 static void      adv_put_ready_queue(struct adv_softc *adv,
  283                                      struct adv_scsi_q *scsiq, u_int q_no);
  284 static void      adv_put_scsiq(struct adv_softc *adv, u_int16_t s_addr,
  285                                u_int16_t *buffer, int words);
  286 
  287 /* Messages */
  288 static void      adv_handle_extmsg_in(struct adv_softc *adv,
  289                                       u_int16_t halt_q_addr, u_int8_t q_cntl,
  290                                       target_bit_vector target_id,
  291                                       int tid);
  292 static void      adv_msgout_sdtr(struct adv_softc *adv, u_int8_t sdtr_period,
  293                                  u_int8_t sdtr_offset);
  294 static void      adv_set_sdtr_reg_at_id(struct adv_softc *adv, int id,
  295                                         u_int8_t sdtr_data);
  296 
  297 
  298 /* Exported functions first */
  299 
  300 void
  301 advasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg)
  302 {
  303         struct adv_softc *adv;
  304 
  305         adv = (struct adv_softc *)callback_arg;
  306         mtx_assert(&adv->lock, MA_OWNED);
  307         switch (code) {
  308         case AC_FOUND_DEVICE:
  309         {
  310                 struct ccb_getdev *cgd;
  311                 target_bit_vector target_mask;
  312                 int num_entries;
  313                 caddr_t match;
  314                 struct adv_quirk_entry *entry;
  315                 struct adv_target_transinfo* tinfo;
  316  
  317                 cgd = (struct ccb_getdev *)arg;
  318 
  319                 target_mask = ADV_TID_TO_TARGET_MASK(cgd->ccb_h.target_id);
  320 
  321                 num_entries = nitems(adv_quirk_table);
  322                 match = cam_quirkmatch((caddr_t)&cgd->inq_data,
  323                                        (caddr_t)adv_quirk_table,
  324                                        num_entries, sizeof(*adv_quirk_table),
  325                                        scsi_inquiry_match);
  326         
  327                 if (match == NULL)
  328                         panic("advasync: device didn't match wildcard entry!!");
  329 
  330                 entry = (struct adv_quirk_entry *)match;
  331 
  332                 if (adv->bug_fix_control & ADV_BUG_FIX_ASYN_USE_SYN) {
  333                         if ((entry->quirks & ADV_QUIRK_FIX_ASYN_XFER_ALWAYS)!=0)
  334                                 adv->fix_asyn_xfer_always |= target_mask;
  335                         else
  336                                 adv->fix_asyn_xfer_always &= ~target_mask;
  337                         /*
  338                          * We start out life with all bits set and clear them
  339                          * after we've determined that the fix isn't necessary.
  340                          * It may well be that we've already cleared a target
  341                          * before the full inquiry session completes, so don't
  342                          * gratuitously set a target bit even if it has this
  343                          * quirk.  But, if the quirk exonerates a device, clear
  344                          * the bit now.
  345                          */
  346                         if ((entry->quirks & ADV_QUIRK_FIX_ASYN_XFER) == 0)
  347                                 adv->fix_asyn_xfer &= ~target_mask;
  348                 }
  349                 /*
  350                  * Reset our sync settings now that we've determined
  351                  * what quirks are in effect for the device.
  352                  */
  353                 tinfo = &adv->tinfo[cgd->ccb_h.target_id];
  354                 adv_set_syncrate(adv, cgd->ccb_h.path,
  355                                  cgd->ccb_h.target_id,
  356                                  tinfo->current.period,
  357                                  tinfo->current.offset,
  358                                  ADV_TRANS_CUR);
  359                 break;
  360         }
  361         case AC_LOST_DEVICE:
  362         {
  363                 u_int target_mask;
  364 
  365                 if (adv->bug_fix_control & ADV_BUG_FIX_ASYN_USE_SYN) {
  366                         target_mask = 0x01 << xpt_path_target_id(path);
  367                         adv->fix_asyn_xfer |= target_mask;
  368                 }
  369 
  370                 /*
  371                  * Revert to async transfers
  372                  * for the next device.
  373                  */
  374                 adv_set_syncrate(adv, /*path*/NULL,
  375                                  xpt_path_target_id(path),
  376                                  /*period*/0,
  377                                  /*offset*/0,
  378                                  ADV_TRANS_GOAL|ADV_TRANS_CUR);
  379         }
  380         default:
  381                 break;
  382         }
  383 }
  384 
  385 void
  386 adv_set_bank(struct adv_softc *adv, u_int8_t bank)
  387 {
  388         u_int8_t control;
  389 
  390         /*
  391          * Start out with the bank reset to 0
  392          */
  393         control = ADV_INB(adv, ADV_CHIP_CTRL)
  394                   &  (~(ADV_CC_SINGLE_STEP | ADV_CC_TEST
  395                         | ADV_CC_DIAG | ADV_CC_SCSI_RESET
  396                         | ADV_CC_CHIP_RESET | ADV_CC_BANK_ONE));
  397         if (bank == 1) {
  398                 control |= ADV_CC_BANK_ONE;
  399         } else if (bank == 2) {
  400                 control |= ADV_CC_DIAG | ADV_CC_BANK_ONE;
  401         }
  402         ADV_OUTB(adv, ADV_CHIP_CTRL, control);
  403 }
  404 
  405 u_int8_t
  406 adv_read_lram_8(struct adv_softc *adv, u_int16_t addr)
  407 {
  408         u_int8_t   byte_data;
  409         u_int16_t  word_data;
  410 
  411         /*
  412          * LRAM is accessed on 16bit boundaries.
  413          */
  414         ADV_OUTW(adv, ADV_LRAM_ADDR, addr & 0xFFFE);
  415         word_data = ADV_INW(adv, ADV_LRAM_DATA);
  416         if (addr & 1) {
  417 #if BYTE_ORDER == BIG_ENDIAN
  418                 byte_data = (u_int8_t)(word_data & 0xFF);
  419 #else
  420                 byte_data = (u_int8_t)((word_data >> 8) & 0xFF);
  421 #endif
  422         } else {
  423 #if BYTE_ORDER == BIG_ENDIAN
  424                 byte_data = (u_int8_t)((word_data >> 8) & 0xFF);
  425 #else           
  426                 byte_data = (u_int8_t)(word_data & 0xFF);
  427 #endif
  428         }
  429         return (byte_data);
  430 }
  431 
  432 void
  433 adv_write_lram_8(struct adv_softc *adv, u_int16_t addr, u_int8_t value)
  434 {
  435         u_int16_t word_data;
  436 
  437         word_data = adv_read_lram_16(adv, addr & 0xFFFE);
  438         if (addr & 1) {
  439                 word_data &= 0x00FF;
  440                 word_data |= (((u_int8_t)value << 8) & 0xFF00);
  441         } else {
  442                 word_data &= 0xFF00;
  443                 word_data |= ((u_int8_t)value & 0x00FF);
  444         }
  445         adv_write_lram_16(adv, addr & 0xFFFE, word_data);
  446 }
  447 
  448 
  449 u_int16_t
  450 adv_read_lram_16(struct adv_softc *adv, u_int16_t addr)
  451 {
  452         ADV_OUTW(adv, ADV_LRAM_ADDR, addr);
  453         return (ADV_INW(adv, ADV_LRAM_DATA));
  454 }
  455 
  456 void
  457 adv_write_lram_16(struct adv_softc *adv, u_int16_t addr, u_int16_t value)
  458 {
  459         ADV_OUTW(adv, ADV_LRAM_ADDR, addr);
  460         ADV_OUTW(adv, ADV_LRAM_DATA, value);
  461 }
  462 
  463 /*
  464  * Determine if there is a board at "iobase" by looking
  465  * for the AdvanSys signatures.  Return 1 if a board is
  466  * found, 0 otherwise.
  467  */
  468 int                         
  469 adv_find_signature(struct resource *res)
  470 {                            
  471         u_int16_t signature;
  472 
  473         if (bus_read_1(res, ADV_SIGNATURE_BYTE) == ADV_1000_ID1B) {
  474                 signature = bus_read_2(res, ADV_SIGNATURE_WORD);
  475                 if ((signature == ADV_1000_ID0W)
  476                  || (signature == ADV_1000_ID0W_FIX))
  477                         return (1);
  478         }
  479         return (0);
  480 }
  481 
  482 void
  483 adv_lib_init(struct adv_softc *adv)
  484 {
  485         if ((adv->type & ADV_ULTRA) != 0) {
  486                 adv->sdtr_period_tbl = adv_sdtr_period_tbl_ultra;
  487                 adv->sdtr_period_tbl_size = sizeof(adv_sdtr_period_tbl_ultra);
  488         } else {
  489                 adv->sdtr_period_tbl = adv_sdtr_period_tbl;
  490                 adv->sdtr_period_tbl_size = sizeof(adv_sdtr_period_tbl);                
  491         }
  492 }
  493 
  494 u_int16_t
  495 adv_get_eeprom_config(struct adv_softc *adv, struct
  496                       adv_eeprom_config  *eeprom_config)
  497 {
  498         u_int16_t       sum;
  499         u_int16_t       *wbuf;
  500         u_int8_t        cfg_beg;
  501         u_int8_t        cfg_end;
  502         u_int8_t        s_addr;
  503 
  504         wbuf = (u_int16_t *)eeprom_config;
  505         sum = 0;
  506 
  507         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
  508                 *wbuf = adv_read_eeprom_16(adv, s_addr);
  509                 sum += *wbuf;
  510         }
  511 
  512         if (adv->type & ADV_VL) {
  513                 cfg_beg = ADV_EEPROM_CFG_BEG_VL;
  514                 cfg_end = ADV_EEPROM_MAX_ADDR_VL;
  515         } else {
  516                 cfg_beg = ADV_EEPROM_CFG_BEG;
  517                 cfg_end = ADV_EEPROM_MAX_ADDR;
  518         }
  519 
  520         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
  521                 *wbuf = adv_read_eeprom_16(adv, s_addr);
  522                 sum += *wbuf;
  523 #ifdef ADV_DEBUG_EEPROM
  524                 printf("Addr 0x%x: 0x%04x\n", s_addr, *wbuf);
  525 #endif
  526         }
  527         *wbuf = adv_read_eeprom_16(adv, s_addr);
  528         return (sum);
  529 }
  530 
  531 int
  532 adv_set_eeprom_config(struct adv_softc *adv,
  533                       struct adv_eeprom_config *eeprom_config)
  534 {
  535         int     retry;
  536 
  537         retry = 0;
  538         while (1) {
  539                 if (adv_set_eeprom_config_once(adv, eeprom_config) == 0) {
  540                         break;
  541                 }
  542                 if (++retry > ADV_EEPROM_MAX_RETRY) {
  543                         break;
  544                 }
  545         }
  546         return (retry > ADV_EEPROM_MAX_RETRY);
  547 }
  548 
  549 int
  550 adv_reset_chip(struct adv_softc *adv, int reset_bus)
  551 {
  552         adv_stop_chip(adv);
  553         ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_CHIP_RESET | ADV_CC_HALT
  554                                      | (reset_bus ? ADV_CC_SCSI_RESET : 0));
  555         DELAY(60);
  556 
  557         adv_set_chip_ih(adv, ADV_INS_RFLAG_WTM);
  558         adv_set_chip_ih(adv, ADV_INS_HALT);
  559 
  560         if (reset_bus)
  561                 ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_CHIP_RESET | ADV_CC_HALT);
  562 
  563         ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT);
  564         if (reset_bus)
  565                 DELAY(200 * 1000);
  566 
  567         ADV_OUTW(adv, ADV_CHIP_STATUS, ADV_CIW_CLR_SCSI_RESET_INT);
  568         ADV_OUTW(adv, ADV_CHIP_STATUS, 0);
  569         return (adv_is_chip_halted(adv));
  570 }
  571 
  572 int
  573 adv_test_external_lram(struct adv_softc* adv)
  574 {
  575         u_int16_t       q_addr;
  576         u_int16_t       saved_value;
  577         int             success;
  578 
  579         success = 0;
  580 
  581         q_addr = ADV_QNO_TO_QADDR(241);
  582         saved_value = adv_read_lram_16(adv, q_addr);
  583         if (adv_write_and_verify_lram_16(adv, q_addr, 0x55AA) == 0) {
  584                 success = 1;
  585                 adv_write_lram_16(adv, q_addr, saved_value);
  586         }
  587         return (success);
  588 }
  589 
  590 
  591 int
  592 adv_init_lram_and_mcode(struct adv_softc *adv)
  593 {
  594         u_int32_t       retval;
  595 
  596         adv_disable_interrupt(adv);
  597 
  598         adv_init_lram(adv);
  599 
  600         retval = adv_load_microcode(adv, 0, (u_int16_t *)adv_mcode,
  601                                     adv_mcode_size);
  602         if (retval != adv_mcode_chksum) {
  603                 device_printf(adv->dev,
  604                     "Microcode download failed checksum!\n");
  605                 return (1);
  606         }
  607         
  608         if (adv_init_microcode_var(adv) != 0)
  609                 return (1);
  610 
  611         adv_enable_interrupt(adv);
  612         return (0);
  613 }
  614 
  615 u_int8_t
  616 adv_get_chip_irq(struct adv_softc *adv)
  617 {
  618         u_int16_t       cfg_lsw;
  619         u_int8_t        chip_irq;
  620 
  621         cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW);
  622 
  623         if ((adv->type & ADV_VL) != 0) {
  624                 chip_irq = (u_int8_t)(((cfg_lsw >> 2) & 0x07));
  625                 if ((chip_irq == 0) ||
  626                     (chip_irq == 4) ||
  627                     (chip_irq == 7)) {
  628                         return (0);
  629                 }
  630                 return (chip_irq + (ADV_MIN_IRQ_NO - 1));
  631         }
  632         chip_irq = (u_int8_t)(((cfg_lsw >> 2) & 0x03));
  633         if (chip_irq == 3)
  634                 chip_irq += 2;
  635         return (chip_irq + ADV_MIN_IRQ_NO);
  636 }
  637 
  638 u_int8_t
  639 adv_set_chip_irq(struct adv_softc *adv, u_int8_t irq_no)
  640 {
  641         u_int16_t       cfg_lsw;
  642 
  643         if ((adv->type & ADV_VL) != 0) {
  644                 if (irq_no != 0) {
  645                         if ((irq_no < ADV_MIN_IRQ_NO)
  646                          || (irq_no > ADV_MAX_IRQ_NO)) {
  647                                 irq_no = 0;
  648                         } else {
  649                                 irq_no -= ADV_MIN_IRQ_NO - 1;
  650                         }
  651                 }
  652                 cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW) & 0xFFE3;
  653                 cfg_lsw |= 0x0010;
  654                 ADV_OUTW(adv, ADV_CONFIG_LSW, cfg_lsw);
  655                 adv_toggle_irq_act(adv);
  656 
  657                 cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW) & 0xFFE0;
  658                 cfg_lsw |= (irq_no & 0x07) << 2;
  659                 ADV_OUTW(adv, ADV_CONFIG_LSW, cfg_lsw);
  660                 adv_toggle_irq_act(adv);
  661         } else if ((adv->type & ADV_ISA) != 0) {
  662                 if (irq_no == 15)
  663                         irq_no -= 2;
  664                 irq_no -= ADV_MIN_IRQ_NO;
  665                 cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW) & 0xFFF3;
  666                 cfg_lsw |= (irq_no & 0x03) << 2;
  667                 ADV_OUTW(adv, ADV_CONFIG_LSW, cfg_lsw);
  668         }
  669         return (adv_get_chip_irq(adv));
  670 }
  671 
  672 void
  673 adv_set_chip_scsiid(struct adv_softc *adv, int new_id)
  674 {
  675         u_int16_t cfg_lsw;
  676 
  677         cfg_lsw = ADV_INW(adv, ADV_CONFIG_LSW);
  678         if (ADV_CONFIG_SCSIID(cfg_lsw) == new_id)
  679                 return;
  680         cfg_lsw &= ~ADV_CFG_LSW_SCSIID;
  681         cfg_lsw |= (new_id & ADV_MAX_TID) << ADV_CFG_LSW_SCSIID_SHIFT;
  682         ADV_OUTW(adv, ADV_CONFIG_LSW, cfg_lsw);
  683 }
  684 
  685 int
  686 adv_execute_scsi_queue(struct adv_softc *adv, struct adv_scsi_q *scsiq,
  687                        u_int32_t datalen)
  688 {
  689         struct          adv_target_transinfo* tinfo;
  690         u_int32_t       *p_data_addr;
  691         u_int32_t       *p_data_bcount;
  692         int             disable_syn_offset_one_fix;
  693         int             retval;
  694         u_int           n_q_required;
  695         u_int32_t       addr;
  696         u_int8_t        sg_entry_cnt;
  697         u_int8_t        target_ix;
  698         u_int8_t        sg_entry_cnt_minus_one;
  699         u_int8_t        tid_no;
  700 
  701         if (!dumping)
  702                 mtx_assert(&adv->lock, MA_OWNED);
  703         scsiq->q1.q_no = 0;
  704         retval = 1;  /* Default to error case */
  705         target_ix = scsiq->q2.target_ix;
  706         tid_no = ADV_TIX_TO_TID(target_ix);
  707         tinfo = &adv->tinfo[tid_no];
  708 
  709         if (scsiq->cdbptr[0] == REQUEST_SENSE) {
  710                 /* Renegotiate if appropriate. */
  711                 adv_set_syncrate(adv, /*struct cam_path */NULL,
  712                                  tid_no, /*period*/0, /*offset*/0,
  713                                  ADV_TRANS_CUR);
  714                 if (tinfo->current.period != tinfo->goal.period) {
  715                         adv_msgout_sdtr(adv, tinfo->goal.period,
  716                                         tinfo->goal.offset);
  717                         scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
  718                 }
  719         }
  720 
  721         if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
  722                 sg_entry_cnt = scsiq->sg_head->entry_cnt;
  723                 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
  724 
  725 #ifdef DIAGNOSTIC
  726                 if (sg_entry_cnt <= 1) 
  727                         panic("adv_execute_scsi_queue: Queue "
  728                               "with QC_SG_HEAD set but %d segs.", sg_entry_cnt);
  729 
  730                 if (sg_entry_cnt > ADV_MAX_SG_LIST)
  731                         panic("adv_execute_scsi_queue: "
  732                               "Queue with too many segs.");
  733 
  734                 if ((adv->type & (ADV_ISA | ADV_VL)) != 0) {
  735                         int i;
  736 
  737                         for (i = 0; i < sg_entry_cnt_minus_one; i++) {
  738                                 addr = scsiq->sg_head->sg_list[i].addr +
  739                                        scsiq->sg_head->sg_list[i].bytes;
  740 
  741                                 if ((addr & 0x0003) != 0)
  742                                         panic("adv_execute_scsi_queue: SG "
  743                                               "with odd address or byte count");
  744                         }
  745                 }
  746 #endif
  747                 p_data_addr =
  748                     &scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].addr;
  749                 p_data_bcount =
  750                     &scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
  751 
  752                 n_q_required = adv_sgcount_to_qcount(sg_entry_cnt);
  753                 scsiq->sg_head->queue_cnt = n_q_required - 1;
  754         } else {
  755                 p_data_addr = &scsiq->q1.data_addr;
  756                 p_data_bcount = &scsiq->q1.data_cnt;
  757                 n_q_required = 1;
  758         }
  759 
  760         disable_syn_offset_one_fix = FALSE;
  761 
  762         if ((adv->fix_asyn_xfer & scsiq->q1.target_id) != 0
  763          && (adv->fix_asyn_xfer_always & scsiq->q1.target_id) == 0) {
  764 
  765                 if (datalen != 0) {
  766                         if (datalen < 512) {
  767                                 disable_syn_offset_one_fix = TRUE;
  768                         } else {
  769                                 if (scsiq->cdbptr[0] == INQUIRY
  770                                  || scsiq->cdbptr[0] == REQUEST_SENSE
  771                                  || scsiq->cdbptr[0] == READ_CAPACITY
  772                                  || scsiq->cdbptr[0] == MODE_SELECT_6 
  773                                  || scsiq->cdbptr[0] == MODE_SENSE_6
  774                                  || scsiq->cdbptr[0] == MODE_SENSE_10 
  775                                  || scsiq->cdbptr[0] == MODE_SELECT_10 
  776                                  || scsiq->cdbptr[0] == READ_TOC) {
  777                                         disable_syn_offset_one_fix = TRUE;
  778                                 }
  779                         }
  780                 }
  781         }
  782 
  783         if (disable_syn_offset_one_fix) {
  784                 scsiq->q2.tag_code &=
  785                     ~(MSG_SIMPLE_Q_TAG|MSG_HEAD_OF_Q_TAG|MSG_ORDERED_Q_TAG);
  786                 scsiq->q2.tag_code |= (ADV_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX
  787                                      | ADV_TAG_FLAG_DISABLE_DISCONNECT);
  788         }
  789 
  790         if ((adv->bug_fix_control & ADV_BUG_FIX_IF_NOT_DWB) != 0
  791          && (scsiq->cdbptr[0] == READ_10 || scsiq->cdbptr[0] == READ_6)) {
  792                 u_int8_t extra_bytes;
  793 
  794                 addr = *p_data_addr + *p_data_bcount;
  795                 extra_bytes = addr & 0x0003;
  796                 if (extra_bytes != 0
  797                  && ((scsiq->q1.cntl & QC_SG_HEAD) != 0
  798                   || (scsiq->q1.data_cnt & 0x01FF) == 0)) {
  799                         scsiq->q2.tag_code |= ADV_TAG_FLAG_EXTRA_BYTES;
  800                         scsiq->q1.extra_bytes = extra_bytes;
  801                         *p_data_bcount -= extra_bytes;
  802                 }
  803         }
  804 
  805         if ((adv_get_num_free_queues(adv, n_q_required) >= n_q_required)
  806          || ((scsiq->q1.cntl & QC_URGENT) != 0))
  807                 retval = adv_send_scsi_queue(adv, scsiq, n_q_required);
  808         
  809         return (retval);
  810 }
  811 
  812 
  813 u_int8_t
  814 adv_copy_lram_doneq(struct adv_softc *adv, u_int16_t q_addr,
  815                     struct adv_q_done_info *scsiq, u_int32_t max_dma_count)
  816 {
  817         u_int16_t val;
  818         u_int8_t  sg_queue_cnt;
  819 
  820         adv_get_q_info(adv, q_addr + ADV_SCSIQ_DONE_INFO_BEG,
  821                        (u_int16_t *)scsiq,
  822                        (sizeof(scsiq->d2) + sizeof(scsiq->d3)) / 2);
  823 
  824 #if BYTE_ORDER == BIG_ENDIAN
  825         adv_adj_endian_qdone_info(scsiq);
  826 #endif
  827 
  828         val = adv_read_lram_16(adv, q_addr + ADV_SCSIQ_B_STATUS);
  829         scsiq->q_status = val & 0xFF;
  830         scsiq->q_no = (val >> 8) & 0XFF;
  831 
  832         val = adv_read_lram_16(adv, q_addr + ADV_SCSIQ_B_CNTL);
  833         scsiq->cntl = val & 0xFF;
  834         sg_queue_cnt = (val >> 8) & 0xFF;
  835 
  836         val = adv_read_lram_16(adv,q_addr + ADV_SCSIQ_B_SENSE_LEN);
  837         scsiq->sense_len = val & 0xFF;
  838         scsiq->extra_bytes = (val >> 8) & 0xFF;
  839 
  840         /*
  841          * Due to a bug in accessing LRAM on the 940UA, the residual
  842          * is split into separate high and low 16bit quantities.
  843          */
  844         scsiq->remain_bytes =
  845             adv_read_lram_16(adv, q_addr + ADV_SCSIQ_DW_REMAIN_XFER_CNT);
  846         scsiq->remain_bytes |=
  847             adv_read_lram_16(adv, q_addr + ADV_SCSIQ_W_ALT_DC1) << 16;
  848 
  849         /*
  850          * XXX Is this just a safeguard or will the counter really
  851          * have bogus upper bits?
  852          */
  853         scsiq->remain_bytes &= max_dma_count;
  854 
  855         return (sg_queue_cnt);
  856 }
  857 
  858 int
  859 adv_start_chip(struct adv_softc *adv)
  860 {
  861         ADV_OUTB(adv, ADV_CHIP_CTRL, 0);
  862         if ((ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_HALTED) != 0)
  863                 return (0);
  864         return (1);
  865 }
  866 
  867 int
  868 adv_stop_execution(struct adv_softc *adv)
  869 {
  870         int count;
  871 
  872         count = 0;
  873         if (adv_read_lram_8(adv, ADV_STOP_CODE_B) == 0) {
  874                 adv_write_lram_8(adv, ADV_STOP_CODE_B,
  875                                  ADV_STOP_REQ_RISC_STOP);
  876                 do {
  877                         if (adv_read_lram_8(adv, ADV_STOP_CODE_B) &
  878                                 ADV_STOP_ACK_RISC_STOP) {
  879                                 return (1);
  880                         }
  881                         DELAY(1000);
  882                 } while (count++ < 20);
  883         }
  884         return (0);
  885 }
  886 
  887 int
  888 adv_is_chip_halted(struct adv_softc *adv)
  889 {
  890         if ((ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_HALTED) != 0) {
  891                 if ((ADV_INB(adv, ADV_CHIP_CTRL) & ADV_CC_HALT) != 0) {
  892                         return (1);
  893                 }
  894         }
  895         return (0);
  896 }
  897 
  898 /*
  899  * XXX The numeric constants and the loops in this routine
  900  * need to be documented.
  901  */
  902 void
  903 adv_ack_interrupt(struct adv_softc *adv)
  904 {
  905         u_int8_t        host_flag;
  906         u_int8_t        risc_flag;
  907         int             loop;
  908 
  909         loop = 0;
  910         do {
  911                 risc_flag = adv_read_lram_8(adv, ADVV_RISC_FLAG_B);
  912                 if (loop++ > 0x7FFF) {
  913                         break;
  914                 }
  915         } while ((risc_flag & ADV_RISC_FLAG_GEN_INT) != 0);
  916 
  917         host_flag = adv_read_lram_8(adv, ADVV_HOST_FLAG_B);
  918         adv_write_lram_8(adv, ADVV_HOST_FLAG_B,
  919                          host_flag | ADV_HOST_FLAG_ACK_INT);
  920 
  921         ADV_OUTW(adv, ADV_CHIP_STATUS, ADV_CIW_INT_ACK);
  922         loop = 0;
  923         while (ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_INT_PENDING) {
  924                 ADV_OUTW(adv, ADV_CHIP_STATUS, ADV_CIW_INT_ACK);
  925                 if (loop++ > 3) {
  926                         break;
  927                 }
  928         }
  929 
  930         adv_write_lram_8(adv, ADVV_HOST_FLAG_B, host_flag);
  931 }
  932 
  933 /*
  934  * Handle all conditions that may halt the chip waiting
  935  * for us to intervene.
  936  */
  937 void
  938 adv_isr_chip_halted(struct adv_softc *adv)
  939 {
  940         u_int16_t         int_halt_code;
  941         u_int16_t         halt_q_addr;
  942         target_bit_vector target_mask;
  943         target_bit_vector scsi_busy;
  944         u_int8_t          halt_qp;
  945         u_int8_t          target_ix;
  946         u_int8_t          q_cntl;
  947         u_int8_t          tid_no;
  948 
  949         if (!dumping)
  950                 mtx_assert(&adv->lock, MA_OWNED);
  951         int_halt_code = adv_read_lram_16(adv, ADVV_HALTCODE_W);
  952         halt_qp = adv_read_lram_8(adv, ADVV_CURCDB_B);
  953         halt_q_addr = ADV_QNO_TO_QADDR(halt_qp);
  954         target_ix = adv_read_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_TARGET_IX);
  955         q_cntl = adv_read_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_CNTL);
  956         tid_no = ADV_TIX_TO_TID(target_ix);
  957         target_mask = ADV_TID_TO_TARGET_MASK(tid_no);
  958         if (int_halt_code == ADV_HALT_DISABLE_ASYN_USE_SYN_FIX) {
  959                 /*
  960                  * Temporarily disable the async fix by removing
  961                  * this target from the list of affected targets,
  962                  * setting our async rate, and then putting us
  963                  * back into the mask.
  964                  */
  965                 adv->fix_asyn_xfer &= ~target_mask;
  966                 adv_set_syncrate(adv, /*struct cam_path */NULL,
  967                                  tid_no, /*period*/0, /*offset*/0,
  968                                  ADV_TRANS_ACTIVE);
  969                 adv->fix_asyn_xfer |= target_mask;
  970         } else if (int_halt_code == ADV_HALT_ENABLE_ASYN_USE_SYN_FIX) {
  971                 adv_set_syncrate(adv, /*struct cam_path */NULL,
  972                                  tid_no, /*period*/0, /*offset*/0,
  973                                  ADV_TRANS_ACTIVE);
  974         } else if (int_halt_code == ADV_HALT_EXTMSG_IN) {
  975                 adv_handle_extmsg_in(adv, halt_q_addr, q_cntl,
  976                                      target_mask, tid_no);
  977         } else if (int_halt_code == ADV_HALT_CHK_CONDITION) {
  978                 struct    adv_target_transinfo* tinfo;
  979                 struct    adv_ccb_info *cinfo;
  980                 union     ccb *ccb;
  981                 u_int32_t cinfo_index;
  982                 u_int8_t  tag_code;
  983                 u_int8_t  q_status;
  984 
  985                 tinfo = &adv->tinfo[tid_no];
  986                 q_cntl |= QC_REQ_SENSE;
  987 
  988                 /* Renegotiate if appropriate. */
  989                 adv_set_syncrate(adv, /*struct cam_path */NULL,
  990                                  tid_no, /*period*/0, /*offset*/0,
  991                                  ADV_TRANS_CUR);
  992                 if (tinfo->current.period != tinfo->goal.period) {
  993                         adv_msgout_sdtr(adv, tinfo->goal.period,
  994                                         tinfo->goal.offset);
  995                         q_cntl |= QC_MSG_OUT;
  996                 }
  997                 adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_CNTL, q_cntl);
  998 
  999                 /* Don't tag request sense commands */
 1000                 tag_code = adv_read_lram_8(adv,
 1001                                            halt_q_addr + ADV_SCSIQ_B_TAG_CODE);
 1002                 tag_code &=
 1003                     ~(MSG_SIMPLE_Q_TAG|MSG_HEAD_OF_Q_TAG|MSG_ORDERED_Q_TAG);
 1004 
 1005                 if ((adv->fix_asyn_xfer & target_mask) != 0
 1006                  && (adv->fix_asyn_xfer_always & target_mask) == 0) {
 1007                         tag_code |= (ADV_TAG_FLAG_DISABLE_DISCONNECT
 1008                                  | ADV_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
 1009                 }
 1010                 adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_TAG_CODE,
 1011                                  tag_code);
 1012                 q_status = adv_read_lram_8(adv,
 1013                                            halt_q_addr + ADV_SCSIQ_B_STATUS);
 1014                 q_status |= (QS_READY | QS_BUSY);
 1015                 adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_STATUS,
 1016                                  q_status);
 1017                 /*
 1018                  * Freeze the devq until we can handle the sense condition.
 1019                  */
 1020                 cinfo_index =
 1021                     adv_read_lram_32(adv, halt_q_addr + ADV_SCSIQ_D_CINFO_IDX);
 1022                 cinfo = &adv->ccb_infos[cinfo_index];
 1023                 ccb = adv->ccb_infos[cinfo_index].ccb;
 1024                 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
 1025                 ccb->ccb_h.status |= CAM_DEV_QFRZN;
 1026                 adv_abort_ccb(adv, tid_no, ADV_TIX_TO_LUN(target_ix),
 1027                               /*ccb*/NULL, CAM_REQUEUE_REQ,
 1028                               /*queued_only*/TRUE);
 1029                 scsi_busy = adv_read_lram_8(adv, ADVV_SCSIBUSY_B);
 1030                 scsi_busy &= ~target_mask;
 1031                 adv_write_lram_8(adv, ADVV_SCSIBUSY_B, scsi_busy);
 1032                 /*
 1033                  * Ensure we have enough time to actually
 1034                  * retrieve the sense.
 1035                  */
 1036                 callout_reset(&cinfo->timer, 5 * hz, adv_timeout, ccb);
 1037         } else if (int_halt_code == ADV_HALT_SDTR_REJECTED) {
 1038                 struct  ext_msg out_msg;
 1039 
 1040                 adv_read_lram_16_multi(adv, ADVV_MSGOUT_BEG,
 1041                                        (u_int16_t *) &out_msg,
 1042                                        sizeof(out_msg)/2);
 1043 
 1044                 if ((out_msg.msg_type == MSG_EXTENDED)
 1045                  && (out_msg.msg_len == MSG_EXT_SDTR_LEN)
 1046                  && (out_msg.msg_req == MSG_EXT_SDTR)) {
 1047 
 1048                         /* Revert to Async */
 1049                         adv_set_syncrate(adv, /*struct cam_path */NULL,
 1050                                          tid_no, /*period*/0, /*offset*/0,
 1051                                          ADV_TRANS_GOAL|ADV_TRANS_ACTIVE);
 1052                 }
 1053                 q_cntl &= ~QC_MSG_OUT;
 1054                 adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_CNTL, q_cntl);
 1055         } else if (int_halt_code == ADV_HALT_SS_QUEUE_FULL) {
 1056                 union ccb *ccb;
 1057                 u_int32_t cinfo_index;
 1058                 
 1059                 adv_read_lram_8(adv, halt_q_addr + ADV_SCSIQ_SCSI_STATUS);
 1060                 cinfo_index =
 1061                     adv_read_lram_32(adv, halt_q_addr + ADV_SCSIQ_D_CINFO_IDX);
 1062                 ccb = adv->ccb_infos[cinfo_index].ccb;
 1063                 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
 1064                 ccb->ccb_h.status |= CAM_DEV_QFRZN|CAM_SCSI_STATUS_ERROR;
 1065                 ccb->csio.scsi_status = SCSI_STATUS_QUEUE_FULL; 
 1066                 adv_abort_ccb(adv, tid_no, ADV_TIX_TO_LUN(target_ix),
 1067                               /*ccb*/NULL, CAM_REQUEUE_REQ,
 1068                               /*queued_only*/TRUE);
 1069                 scsi_busy = adv_read_lram_8(adv, ADVV_SCSIBUSY_B);
 1070                 scsi_busy &= ~target_mask;
 1071                 adv_write_lram_8(adv, ADVV_SCSIBUSY_B, scsi_busy);              
 1072         } else {
 1073                 printf("Unhandled Halt Code %x\n", int_halt_code);
 1074         }
 1075         adv_write_lram_16(adv, ADVV_HALTCODE_W, 0);
 1076 }
 1077 
 1078 void
 1079 adv_sdtr_to_period_offset(struct adv_softc *adv,
 1080                           u_int8_t sync_data, u_int8_t *period,
 1081                           u_int8_t *offset, int tid)
 1082 {
 1083         if (adv->fix_asyn_xfer & ADV_TID_TO_TARGET_MASK(tid)
 1084          && (sync_data == ASYN_SDTR_DATA_FIX_PCI_REV_AB)) {
 1085                 *period = *offset = 0;
 1086         } else {
 1087                 *period = adv->sdtr_period_tbl[((sync_data >> 4) & 0xF)];
 1088                 *offset = sync_data & 0xF;
 1089         }
 1090 }
 1091 
 1092 void
 1093 adv_set_syncrate(struct adv_softc *adv, struct cam_path *path,
 1094                  u_int tid, u_int period, u_int offset, u_int type)
 1095 {
 1096         struct adv_target_transinfo* tinfo;
 1097         u_int old_period;
 1098         u_int old_offset;
 1099         u_int8_t sdtr_data;
 1100 
 1101         mtx_assert(&adv->lock, MA_OWNED);
 1102         tinfo = &adv->tinfo[tid];
 1103 
 1104         /* Filter our input */
 1105         sdtr_data = adv_period_offset_to_sdtr(adv, &period,
 1106                                               &offset, tid);
 1107 
 1108         old_period = tinfo->current.period;
 1109         old_offset = tinfo->current.offset;
 1110 
 1111         if ((type & ADV_TRANS_CUR) != 0
 1112          && ((old_period != period || old_offset != offset)
 1113           || period == 0 || offset == 0) /*Changes in asyn fix settings*/) {
 1114                 int halted;
 1115 
 1116                 halted = adv_is_chip_halted(adv);
 1117                 if (halted == 0)
 1118                         /* Must halt the chip first */
 1119                         adv_host_req_chip_halt(adv);
 1120 
 1121                 /* Update current hardware settings */
 1122                 adv_set_sdtr_reg_at_id(adv, tid, sdtr_data);
 1123 
 1124                 /*
 1125                  * If a target can run in sync mode, we don't need
 1126                  * to check it for sync problems.
 1127                  */
 1128                 if (offset != 0)
 1129                         adv->fix_asyn_xfer &= ~ADV_TID_TO_TARGET_MASK(tid);
 1130 
 1131                 if (halted == 0)
 1132                         /* Start the chip again */
 1133                         adv_start_chip(adv);
 1134 
 1135                 tinfo->current.period = period;
 1136                 tinfo->current.offset = offset;
 1137 
 1138                 if (path != NULL) {
 1139                         /*
 1140                          * Tell the SCSI layer about the
 1141                          * new transfer parameters.
 1142                          */
 1143                         struct  ccb_trans_settings neg;
 1144                         memset(&neg, 0, sizeof (neg));
 1145                         struct ccb_trans_settings_spi *spi =
 1146                             &neg.xport_specific.spi;
 1147 
 1148                         neg.protocol = PROTO_SCSI;
 1149                         neg.protocol_version = SCSI_REV_2;
 1150                         neg.transport = XPORT_SPI;
 1151                         neg.transport_version = 2;
 1152 
 1153                         spi->sync_offset = offset;
 1154                         spi->sync_period = period;
 1155                         spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
 1156                         spi->valid |= CTS_SPI_VALID_SYNC_RATE;
 1157                         xpt_setup_ccb(&neg.ccb_h, path, /*priority*/1);
 1158                         xpt_async(AC_TRANSFER_NEG, path, &neg);
 1159                 }
 1160         }
 1161 
 1162         if ((type & ADV_TRANS_GOAL) != 0) {
 1163                 tinfo->goal.period = period;
 1164                 tinfo->goal.offset = offset;
 1165         }
 1166 
 1167         if ((type & ADV_TRANS_USER) != 0) {
 1168                 tinfo->user.period = period;
 1169                 tinfo->user.offset = offset;
 1170         }
 1171 }
 1172 
 1173 u_int8_t
 1174 adv_period_offset_to_sdtr(struct adv_softc *adv, u_int *period,
 1175                           u_int *offset, int tid)
 1176 {
 1177         u_int i;
 1178         u_int dummy_offset;
 1179         u_int dummy_period;
 1180 
 1181         if (offset == NULL) {
 1182                 dummy_offset = 0;
 1183                 offset = &dummy_offset;
 1184         }
 1185 
 1186         if (period == NULL) {
 1187                 dummy_period = 0;
 1188                 period = &dummy_period;
 1189         }
 1190 
 1191         *offset = MIN(ADV_SYN_MAX_OFFSET, *offset);
 1192         if (*period != 0 && *offset != 0) {
 1193                 for (i = 0; i < adv->sdtr_period_tbl_size; i++) {
 1194                         if (*period <= adv->sdtr_period_tbl[i]) {
 1195                                 /*       
 1196                                  * When responding to a target that requests
 1197                                  * sync, the requested  rate may fall between
 1198                                  * two rates that we can output, but still be
 1199                                  * a rate that we can receive.  Because of this,
 1200                                  * we want to respond to the target with
 1201                                  * the same rate that it sent to us even
 1202                                  * if the period we use to send data to it
 1203                                  * is lower.  Only lower the response period
 1204                                  * if we must.
 1205                                  */        
 1206                                 if (i == 0 /* Our maximum rate */)
 1207                                         *period = adv->sdtr_period_tbl[0];
 1208                                 return ((i << 4) | *offset);
 1209                         }
 1210                 }
 1211         }
 1212         
 1213         /* Must go async */
 1214         *period = 0;
 1215         *offset = 0;
 1216         if (adv->fix_asyn_xfer & ADV_TID_TO_TARGET_MASK(tid))
 1217                 return (ASYN_SDTR_DATA_FIX_PCI_REV_AB);
 1218         return (0);
 1219 }
 1220 
 1221 /* Internal Routines */
 1222 
 1223 static void
 1224 adv_read_lram_16_multi(struct adv_softc *adv, u_int16_t s_addr,
 1225                        u_int16_t *buffer, int count)
 1226 {
 1227         ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
 1228         ADV_INSW(adv, ADV_LRAM_DATA, buffer, count);
 1229 }
 1230 
 1231 static void
 1232 adv_write_lram_16_multi(struct adv_softc *adv, u_int16_t s_addr,
 1233                         u_int16_t *buffer, int count)
 1234 {
 1235         ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
 1236         ADV_OUTSW(adv, ADV_LRAM_DATA, buffer, count);
 1237 }
 1238 
 1239 static void
 1240 adv_mset_lram_16(struct adv_softc *adv, u_int16_t s_addr,
 1241                  u_int16_t set_value, int count)
 1242 {
 1243         ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
 1244         bus_set_multi_2(adv->res, adv->reg_off + ADV_LRAM_DATA,
 1245             set_value, count);
 1246 }
 1247 
 1248 static u_int32_t
 1249 adv_msum_lram_16(struct adv_softc *adv, u_int16_t s_addr, int count)
 1250 {
 1251         u_int32_t       sum;
 1252         int             i;
 1253 
 1254         sum = 0;
 1255         ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
 1256         for (i = 0; i < count; i++)
 1257                 sum += ADV_INW(adv, ADV_LRAM_DATA);
 1258         return (sum);
 1259 }
 1260 
 1261 static int
 1262 adv_write_and_verify_lram_16(struct adv_softc *adv, u_int16_t addr,
 1263                              u_int16_t value)
 1264 {
 1265         int     retval;
 1266 
 1267         retval = 0;
 1268         ADV_OUTW(adv, ADV_LRAM_ADDR, addr);
 1269         ADV_OUTW(adv, ADV_LRAM_DATA, value);
 1270         DELAY(10000);
 1271         ADV_OUTW(adv, ADV_LRAM_ADDR, addr);
 1272         if (value != ADV_INW(adv, ADV_LRAM_DATA))
 1273                 retval = 1;
 1274         return (retval);
 1275 }
 1276 
 1277 static u_int32_t
 1278 adv_read_lram_32(struct adv_softc *adv, u_int16_t addr)
 1279 {
 1280         u_int16_t           val_low, val_high;
 1281 
 1282         ADV_OUTW(adv, ADV_LRAM_ADDR, addr);
 1283 
 1284 #if BYTE_ORDER == BIG_ENDIAN
 1285         val_high = ADV_INW(adv, ADV_LRAM_DATA);
 1286         val_low = ADV_INW(adv, ADV_LRAM_DATA);
 1287 #else
 1288         val_low = ADV_INW(adv, ADV_LRAM_DATA);
 1289         val_high = ADV_INW(adv, ADV_LRAM_DATA);
 1290 #endif
 1291 
 1292         return (((u_int32_t)val_high << 16) | (u_int32_t)val_low);
 1293 }
 1294 
 1295 static void
 1296 adv_write_lram_32(struct adv_softc *adv, u_int16_t addr, u_int32_t value)
 1297 {
 1298         ADV_OUTW(adv, ADV_LRAM_ADDR, addr);
 1299 
 1300 #if BYTE_ORDER == BIG_ENDIAN
 1301         ADV_OUTW(adv, ADV_LRAM_DATA, (u_int16_t)((value >> 16) & 0xFFFF));
 1302         ADV_OUTW(adv, ADV_LRAM_DATA, (u_int16_t)(value & 0xFFFF));
 1303 #else
 1304         ADV_OUTW(adv, ADV_LRAM_DATA, (u_int16_t)(value & 0xFFFF));
 1305         ADV_OUTW(adv, ADV_LRAM_DATA, (u_int16_t)((value >> 16) & 0xFFFF));
 1306 #endif
 1307 }
 1308 
 1309 static void
 1310 adv_write_lram_32_multi(struct adv_softc *adv, u_int16_t s_addr,
 1311                         u_int32_t *buffer, int count)
 1312 {
 1313         ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
 1314         ADV_OUTSW(adv, ADV_LRAM_DATA, (u_int16_t *)buffer, count * 2);
 1315 }
 1316 
 1317 static u_int16_t
 1318 adv_read_eeprom_16(struct adv_softc *adv, u_int8_t addr)
 1319 {
 1320         u_int16_t read_wval;
 1321         u_int8_t  cmd_reg;
 1322 
 1323         adv_write_eeprom_cmd_reg(adv, ADV_EEPROM_CMD_WRITE_DISABLE);
 1324         DELAY(1000);
 1325         cmd_reg = addr | ADV_EEPROM_CMD_READ;
 1326         adv_write_eeprom_cmd_reg(adv, cmd_reg);
 1327         DELAY(1000);
 1328         read_wval = ADV_INW(adv, ADV_EEPROM_DATA);
 1329         DELAY(1000);
 1330         return (read_wval);
 1331 }
 1332 
 1333 static u_int16_t
 1334 adv_write_eeprom_16(struct adv_softc *adv, u_int8_t addr, u_int16_t value)
 1335 {
 1336         u_int16_t       read_value;
 1337 
 1338         read_value = adv_read_eeprom_16(adv, addr);
 1339         if (read_value != value) {
 1340                 adv_write_eeprom_cmd_reg(adv, ADV_EEPROM_CMD_WRITE_ENABLE);
 1341                 DELAY(1000);
 1342                 
 1343                 ADV_OUTW(adv, ADV_EEPROM_DATA, value);
 1344                 DELAY(1000);
 1345 
 1346                 adv_write_eeprom_cmd_reg(adv, ADV_EEPROM_CMD_WRITE | addr);
 1347                 DELAY(20 * 1000);
 1348 
 1349                 adv_write_eeprom_cmd_reg(adv, ADV_EEPROM_CMD_WRITE_DISABLE);
 1350                 DELAY(1000);
 1351                 read_value = adv_read_eeprom_16(adv, addr);
 1352         }
 1353         return (read_value);
 1354 }
 1355 
 1356 static int
 1357 adv_write_eeprom_cmd_reg(struct adv_softc *adv, u_int8_t cmd_reg)
 1358 {
 1359         u_int8_t read_back;
 1360         int      retry;
 1361 
 1362         retry = 0;
 1363         while (1) {
 1364                 ADV_OUTB(adv, ADV_EEPROM_CMD, cmd_reg);
 1365                 DELAY(1000);
 1366                 read_back = ADV_INB(adv, ADV_EEPROM_CMD);
 1367                 if (read_back == cmd_reg) {
 1368                         return (1);
 1369                 }
 1370                 if (retry++ > ADV_EEPROM_MAX_RETRY) {
 1371                         return (0);
 1372                 }
 1373         }
 1374 }
 1375 
 1376 static int
 1377 adv_set_eeprom_config_once(struct adv_softc *adv,
 1378                            struct adv_eeprom_config *eeprom_config)
 1379 {
 1380         int             n_error;
 1381         u_int16_t       *wbuf;
 1382         u_int16_t       sum;
 1383         u_int8_t        s_addr;
 1384         u_int8_t        cfg_beg;
 1385         u_int8_t        cfg_end;
 1386 
 1387         wbuf = (u_int16_t *)eeprom_config;
 1388         n_error = 0;
 1389         sum = 0;
 1390         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
 1391                 sum += *wbuf;
 1392                 if (*wbuf != adv_write_eeprom_16(adv, s_addr, *wbuf)) {
 1393                         n_error++;
 1394                 }
 1395         }
 1396         if (adv->type & ADV_VL) {
 1397                 cfg_beg = ADV_EEPROM_CFG_BEG_VL;
 1398                 cfg_end = ADV_EEPROM_MAX_ADDR_VL;
 1399         } else {
 1400                 cfg_beg = ADV_EEPROM_CFG_BEG;
 1401                 cfg_end = ADV_EEPROM_MAX_ADDR;
 1402         }
 1403 
 1404         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
 1405                 sum += *wbuf;
 1406                 if (*wbuf != adv_write_eeprom_16(adv, s_addr, *wbuf)) {
 1407                         n_error++;
 1408                 }
 1409         }
 1410         *wbuf = sum;
 1411         if (sum != adv_write_eeprom_16(adv, s_addr, sum)) {
 1412                 n_error++;
 1413         }
 1414         wbuf = (u_int16_t *)eeprom_config;
 1415         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
 1416                 if (*wbuf != adv_read_eeprom_16(adv, s_addr)) {
 1417                         n_error++;
 1418                 }
 1419         }
 1420         for (s_addr = cfg_beg; s_addr <= cfg_end; s_addr++, wbuf++) {
 1421                 if (*wbuf != adv_read_eeprom_16(adv, s_addr)) {
 1422                         n_error++;
 1423                 }
 1424         }
 1425         return (n_error);
 1426 }
 1427 
 1428 static u_int32_t
 1429 adv_load_microcode(struct adv_softc *adv, u_int16_t s_addr,
 1430                    u_int16_t *mcode_buf, u_int16_t mcode_size)
 1431 {
 1432         u_int32_t chksum;
 1433         u_int16_t mcode_lram_size;
 1434         u_int16_t mcode_chksum;
 1435 
 1436         mcode_lram_size = mcode_size >> 1;
 1437         /* XXX Why zero the memory just before you write the whole thing?? */
 1438         adv_mset_lram_16(adv, s_addr, 0, mcode_lram_size);
 1439         adv_write_lram_16_multi(adv, s_addr, mcode_buf, mcode_lram_size);
 1440 
 1441         chksum = adv_msum_lram_16(adv, s_addr, mcode_lram_size);
 1442         mcode_chksum = (u_int16_t)adv_msum_lram_16(adv, ADV_CODE_SEC_BEG,
 1443                                                    ((mcode_size - s_addr
 1444                                                      - ADV_CODE_SEC_BEG) >> 1));
 1445         adv_write_lram_16(adv, ADVV_MCODE_CHKSUM_W, mcode_chksum);
 1446         adv_write_lram_16(adv, ADVV_MCODE_SIZE_W, mcode_size);
 1447         return (chksum);
 1448 }
 1449 
 1450 static void
 1451 adv_reinit_lram(struct adv_softc *adv) {
 1452         adv_init_lram(adv);
 1453         adv_init_qlink_var(adv);
 1454 }
 1455 
 1456 static void
 1457 adv_init_lram(struct adv_softc *adv)
 1458 {
 1459         u_int8_t  i;
 1460         u_int16_t s_addr;
 1461 
 1462         adv_mset_lram_16(adv, ADV_QADR_BEG, 0,
 1463                          (((adv->max_openings + 2 + 1) * 64) >> 1));
 1464         
 1465         i = ADV_MIN_ACTIVE_QNO;
 1466         s_addr = ADV_QADR_BEG + ADV_QBLK_SIZE;
 1467 
 1468         adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_FWD, i + 1);
 1469         adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_BWD, adv->max_openings);
 1470         adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_QNO, i);
 1471         i++;
 1472         s_addr += ADV_QBLK_SIZE;
 1473         for (; i < adv->max_openings; i++, s_addr += ADV_QBLK_SIZE) {
 1474                 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_FWD, i + 1);
 1475                 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_BWD, i - 1);
 1476                 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_QNO, i);
 1477         }
 1478 
 1479         adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_FWD, ADV_QLINK_END);
 1480         adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_BWD, adv->max_openings - 1);
 1481         adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_QNO, adv->max_openings);
 1482         i++;
 1483         s_addr += ADV_QBLK_SIZE;
 1484 
 1485         for (; i <= adv->max_openings + 3; i++, s_addr += ADV_QBLK_SIZE) {
 1486                 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_FWD, i);
 1487                 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_BWD, i);
 1488                 adv_write_lram_8(adv, s_addr + ADV_SCSIQ_B_QNO, i);
 1489         }
 1490 }
 1491 
 1492 static int
 1493 adv_init_microcode_var(struct adv_softc *adv)
 1494 {
 1495         int      i;
 1496 
 1497         for (i = 0; i <= ADV_MAX_TID; i++) {
 1498                 
 1499                 /* Start out async all around */
 1500                 adv_set_syncrate(adv, /*path*/NULL,
 1501                                  i, 0, 0,
 1502                                  ADV_TRANS_GOAL|ADV_TRANS_CUR);
 1503         }
 1504 
 1505         adv_init_qlink_var(adv);
 1506 
 1507         adv_write_lram_8(adv, ADVV_DISC_ENABLE_B, adv->disc_enable);
 1508         adv_write_lram_8(adv, ADVV_HOSTSCSI_ID_B, 0x01 << adv->scsi_id);
 1509 
 1510         adv_write_lram_32(adv, ADVV_OVERRUN_PADDR_D, adv->overrun_physbase);
 1511 
 1512         adv_write_lram_32(adv, ADVV_OVERRUN_BSIZE_D, ADV_OVERRUN_BSIZE);
 1513 
 1514         ADV_OUTW(adv, ADV_REG_PROG_COUNTER, ADV_MCODE_START_ADDR);
 1515         if (ADV_INW(adv, ADV_REG_PROG_COUNTER) != ADV_MCODE_START_ADDR) {
 1516                 device_printf(adv->dev,
 1517                     "Unable to set program counter. Aborting.\n");
 1518                 return (1);
 1519         }
 1520         return (0);
 1521 }
 1522 
 1523 static void
 1524 adv_init_qlink_var(struct adv_softc *adv)
 1525 {
 1526         int       i;
 1527         u_int16_t lram_addr;
 1528 
 1529         adv_write_lram_8(adv, ADVV_NEXTRDY_B, 1);
 1530         adv_write_lram_8(adv, ADVV_DONENEXT_B, adv->max_openings);
 1531 
 1532         adv_write_lram_16(adv, ADVV_FREE_Q_HEAD_W, 1);
 1533         adv_write_lram_16(adv, ADVV_DONE_Q_TAIL_W, adv->max_openings);
 1534 
 1535         adv_write_lram_8(adv, ADVV_BUSY_QHEAD_B,
 1536                          (u_int8_t)((int) adv->max_openings + 1));
 1537         adv_write_lram_8(adv, ADVV_DISC1_QHEAD_B,
 1538                          (u_int8_t)((int) adv->max_openings + 2));
 1539 
 1540         adv_write_lram_8(adv, ADVV_TOTAL_READY_Q_B, adv->max_openings);
 1541 
 1542         adv_write_lram_16(adv, ADVV_ASCDVC_ERR_CODE_W, 0);
 1543         adv_write_lram_16(adv, ADVV_HALTCODE_W, 0);
 1544         adv_write_lram_8(adv, ADVV_STOP_CODE_B, 0);
 1545         adv_write_lram_8(adv, ADVV_SCSIBUSY_B, 0);
 1546         adv_write_lram_8(adv, ADVV_WTM_FLAG_B, 0);
 1547         adv_write_lram_8(adv, ADVV_Q_DONE_IN_PROGRESS_B, 0);
 1548 
 1549         lram_addr = ADV_QADR_BEG;
 1550         for (i = 0; i < 32; i++, lram_addr += 2)
 1551                 adv_write_lram_16(adv, lram_addr, 0);
 1552 }
 1553 
 1554 static void
 1555 adv_disable_interrupt(struct adv_softc *adv)
 1556 {
 1557         u_int16_t cfg;
 1558 
 1559         cfg = ADV_INW(adv, ADV_CONFIG_LSW);
 1560         ADV_OUTW(adv, ADV_CONFIG_LSW, cfg & ~ADV_CFG_LSW_HOST_INT_ON);
 1561 }
 1562 
 1563 static void
 1564 adv_enable_interrupt(struct adv_softc *adv)
 1565 {
 1566         u_int16_t cfg;
 1567 
 1568         cfg = ADV_INW(adv, ADV_CONFIG_LSW);
 1569         ADV_OUTW(adv, ADV_CONFIG_LSW, cfg | ADV_CFG_LSW_HOST_INT_ON);
 1570 }
 1571 
 1572 static void
 1573 adv_toggle_irq_act(struct adv_softc *adv)
 1574 {
 1575         ADV_OUTW(adv, ADV_CHIP_STATUS, ADV_CIW_IRQ_ACT);
 1576         ADV_OUTW(adv, ADV_CHIP_STATUS, 0);
 1577 }
 1578 
 1579 void
 1580 adv_start_execution(struct adv_softc *adv)
 1581 {
 1582         if (adv_read_lram_8(adv, ADV_STOP_CODE_B) != 0) {
 1583                 adv_write_lram_8(adv, ADV_STOP_CODE_B, 0);
 1584         }
 1585 }
 1586 
 1587 int
 1588 adv_stop_chip(struct adv_softc *adv)
 1589 {
 1590         u_int8_t cc_val;
 1591 
 1592         cc_val = ADV_INB(adv, ADV_CHIP_CTRL)
 1593                  & (~(ADV_CC_SINGLE_STEP | ADV_CC_TEST | ADV_CC_DIAG));
 1594         ADV_OUTB(adv, ADV_CHIP_CTRL, cc_val | ADV_CC_HALT);
 1595         adv_set_chip_ih(adv, ADV_INS_HALT);
 1596         adv_set_chip_ih(adv, ADV_INS_RFLAG_WTM);
 1597         if ((ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_HALTED) == 0) {
 1598                 return (0);
 1599         }
 1600         return (1);
 1601 }
 1602 
 1603 static int
 1604 adv_host_req_chip_halt(struct adv_softc *adv)
 1605 {       
 1606         int      count;
 1607         u_int8_t saved_stop_code;
 1608 
 1609         if (adv_is_chip_halted(adv))
 1610                 return (1);
 1611 
 1612         count = 0;
 1613         saved_stop_code = adv_read_lram_8(adv, ADVV_STOP_CODE_B);
 1614         adv_write_lram_8(adv, ADVV_STOP_CODE_B,
 1615                          ADV_STOP_HOST_REQ_RISC_HALT | ADV_STOP_REQ_RISC_STOP);
 1616         while (adv_is_chip_halted(adv) == 0
 1617             && count++ < 2000)
 1618                 ;
 1619 
 1620         adv_write_lram_8(adv, ADVV_STOP_CODE_B, saved_stop_code);
 1621         return (count < 2000); 
 1622 }
 1623 
 1624 static void
 1625 adv_set_chip_ih(struct adv_softc *adv, u_int16_t ins_code)
 1626 {
 1627         adv_set_bank(adv, 1);
 1628         ADV_OUTW(adv, ADV_REG_IH, ins_code);
 1629         adv_set_bank(adv, 0);
 1630 }
 1631 
 1632 #if 0
 1633 static u_int8_t
 1634 adv_get_chip_scsi_ctrl(struct adv_softc *adv)
 1635 {
 1636         u_int8_t scsi_ctrl;
 1637 
 1638         adv_set_bank(adv, 1);
 1639         scsi_ctrl = ADV_INB(adv, ADV_REG_SC);
 1640         adv_set_bank(adv, 0);
 1641         return (scsi_ctrl);
 1642 }
 1643 #endif
 1644 
 1645 /*
 1646  * XXX Looks like more padding issues in this routine as well.
 1647  *     There has to be a way to turn this into an insw.
 1648  */
 1649 static void
 1650 adv_get_q_info(struct adv_softc *adv, u_int16_t s_addr,
 1651                u_int16_t *inbuf, int words)
 1652 {
 1653         int     i;
 1654 
 1655         ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
 1656         for (i = 0; i < words; i++, inbuf++) {
 1657                 if (i == 5) {
 1658                         continue;
 1659                 }
 1660                 *inbuf = ADV_INW(adv, ADV_LRAM_DATA);
 1661         }
 1662 }
 1663 
 1664 static u_int
 1665 adv_get_num_free_queues(struct adv_softc *adv, u_int8_t n_qs)
 1666 {
 1667         u_int     cur_used_qs;
 1668         u_int     cur_free_qs;
 1669 
 1670         cur_used_qs = adv->cur_active + ADV_MIN_FREE_Q;
 1671 
 1672         if ((cur_used_qs + n_qs) <= adv->max_openings) {
 1673                 cur_free_qs = adv->max_openings - cur_used_qs;
 1674                 return (cur_free_qs);
 1675         }
 1676         adv->openings_needed = n_qs;
 1677         return (0);
 1678 }
 1679 
 1680 static u_int8_t
 1681 adv_alloc_free_queues(struct adv_softc *adv, u_int8_t free_q_head,
 1682                       u_int8_t n_free_q)
 1683 {
 1684         int i;
 1685 
 1686         for (i = 0; i < n_free_q; i++) {
 1687                 free_q_head = adv_alloc_free_queue(adv, free_q_head);
 1688                 if (free_q_head == ADV_QLINK_END)
 1689                         break;
 1690         }
 1691         return (free_q_head);
 1692 }
 1693 
 1694 static u_int8_t
 1695 adv_alloc_free_queue(struct adv_softc *adv, u_int8_t free_q_head)
 1696 {
 1697         u_int16_t       q_addr;
 1698         u_int8_t        next_qp;
 1699         u_int8_t        q_status;
 1700 
 1701         next_qp = ADV_QLINK_END;
 1702         q_addr = ADV_QNO_TO_QADDR(free_q_head);
 1703         q_status = adv_read_lram_8(adv, q_addr + ADV_SCSIQ_B_STATUS);
 1704         
 1705         if ((q_status & QS_READY) == 0)
 1706                 next_qp = adv_read_lram_8(adv, q_addr + ADV_SCSIQ_B_FWD);
 1707 
 1708         return (next_qp);
 1709 }
 1710 
 1711 static int
 1712 adv_send_scsi_queue(struct adv_softc *adv, struct adv_scsi_q *scsiq,
 1713                     u_int8_t n_q_required)
 1714 {
 1715         u_int8_t        free_q_head;
 1716         u_int8_t        next_qp;
 1717         int             retval;
 1718 
 1719         retval = 1;
 1720         free_q_head = adv_read_lram_16(adv, ADVV_FREE_Q_HEAD_W) & 0xFF;
 1721         if ((next_qp = adv_alloc_free_queues(adv, free_q_head, n_q_required))
 1722             != ADV_QLINK_END) {
 1723                 scsiq->q1.q_no = free_q_head;
 1724 
 1725                 /*
 1726                  * Now that we know our Q number, point our sense
 1727                  * buffer pointer to a bus dma mapped area where
 1728                  * we can dma the data to.
 1729                  */
 1730                 scsiq->q1.sense_addr = adv->sense_physbase
 1731                     + ((free_q_head - 1) * sizeof(struct scsi_sense_data));
 1732                 adv_put_ready_sg_list_queue(adv, scsiq, free_q_head);
 1733                 adv_write_lram_16(adv, ADVV_FREE_Q_HEAD_W, next_qp);
 1734                 adv->cur_active += n_q_required;
 1735                 retval = 0;
 1736         }
 1737         return (retval);
 1738 }
 1739 
 1740 
 1741 static void
 1742 adv_put_ready_sg_list_queue(struct adv_softc *adv, struct adv_scsi_q *scsiq,
 1743                             u_int q_no)
 1744 {
 1745         u_int8_t        sg_list_dwords;
 1746         u_int8_t        sg_index, i;
 1747         u_int8_t        sg_entry_cnt;
 1748         u_int8_t        next_qp;
 1749         u_int16_t       q_addr;
 1750         struct          adv_sg_head *sg_head;
 1751         struct          adv_sg_list_q scsi_sg_q;
 1752 
 1753         sg_head = scsiq->sg_head;
 1754 
 1755         if (sg_head) {
 1756                 sg_entry_cnt = sg_head->entry_cnt - 1;
 1757 #ifdef DIAGNOSTIC
 1758                 if (sg_entry_cnt == 0)
 1759                         panic("adv_put_ready_sg_list_queue: ScsiQ with "
 1760                               "a SG list but only one element");
 1761                 if ((scsiq->q1.cntl & QC_SG_HEAD) == 0)
 1762                         panic("adv_put_ready_sg_list_queue: ScsiQ with "
 1763                               "a SG list but QC_SG_HEAD not set");
 1764 #endif                  
 1765                 q_addr = ADV_QNO_TO_QADDR(q_no);
 1766                 sg_index = 1;
 1767                 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
 1768                 scsi_sg_q.sg_head_qp = q_no;
 1769                 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
 1770                 for (i = 0; i < sg_head->queue_cnt; i++) {
 1771                         u_int8_t segs_this_q;
 1772 
 1773                         if (sg_entry_cnt > ADV_SG_LIST_PER_Q)
 1774                                 segs_this_q = ADV_SG_LIST_PER_Q;
 1775                         else {
 1776                                 /* This will be the last segment then */
 1777                                 segs_this_q = sg_entry_cnt;
 1778                                 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
 1779                         }
 1780                         scsi_sg_q.seq_no = i + 1;
 1781                         sg_list_dwords = segs_this_q << 1;
 1782                         if (i == 0) {
 1783                                 scsi_sg_q.sg_list_cnt = segs_this_q;
 1784                                 scsi_sg_q.sg_cur_list_cnt = segs_this_q;
 1785                         } else {
 1786                                 scsi_sg_q.sg_list_cnt = segs_this_q - 1;
 1787                                 scsi_sg_q.sg_cur_list_cnt = segs_this_q - 1;
 1788                         }
 1789                         next_qp = adv_read_lram_8(adv, q_addr + ADV_SCSIQ_B_FWD);
 1790                         scsi_sg_q.q_no = next_qp;
 1791                         q_addr = ADV_QNO_TO_QADDR(next_qp);
 1792 
 1793                         adv_write_lram_16_multi(adv,
 1794                                                 q_addr + ADV_SCSIQ_SGHD_CPY_BEG,
 1795                                                 (u_int16_t *)&scsi_sg_q,
 1796                                                 sizeof(scsi_sg_q) >> 1);
 1797                         adv_write_lram_32_multi(adv, q_addr + ADV_SGQ_LIST_BEG,
 1798                                                 (u_int32_t *)&sg_head->sg_list[sg_index],
 1799                                                 sg_list_dwords);
 1800                         sg_entry_cnt -= segs_this_q;
 1801                         sg_index += ADV_SG_LIST_PER_Q;
 1802                 }
 1803         }
 1804         adv_put_ready_queue(adv, scsiq, q_no);
 1805 }
 1806 
 1807 static void
 1808 adv_put_ready_queue(struct adv_softc *adv, struct adv_scsi_q *scsiq,
 1809                     u_int q_no)
 1810 {
 1811         struct          adv_target_transinfo* tinfo;
 1812         u_int           q_addr;
 1813         u_int           tid_no;
 1814 
 1815         tid_no = ADV_TIX_TO_TID(scsiq->q2.target_ix);
 1816         tinfo = &adv->tinfo[tid_no];
 1817         if ((tinfo->current.period != tinfo->goal.period)
 1818          || (tinfo->current.offset != tinfo->goal.offset)) {
 1819 
 1820                 adv_msgout_sdtr(adv, tinfo->goal.period, tinfo->goal.offset);
 1821                 scsiq->q1.cntl |= QC_MSG_OUT;
 1822         }
 1823         q_addr = ADV_QNO_TO_QADDR(q_no);
 1824 
 1825         scsiq->q1.status = QS_FREE;
 1826 
 1827         adv_write_lram_16_multi(adv, q_addr + ADV_SCSIQ_CDB_BEG,
 1828                                 (u_int16_t *)scsiq->cdbptr,
 1829                                 scsiq->q2.cdb_len >> 1);
 1830 
 1831 #if BYTE_ORDER == BIG_ENDIAN
 1832         adv_adj_scsiq_endian(scsiq);
 1833 #endif
 1834 
 1835         adv_put_scsiq(adv, q_addr + ADV_SCSIQ_CPY_BEG,
 1836                       (u_int16_t *) &scsiq->q1.cntl,
 1837                       ((sizeof(scsiq->q1) + sizeof(scsiq->q2)) / 2) - 1);
 1838 
 1839 #ifdef CC_WRITE_IO_COUNT
 1840         adv_write_lram_16(adv, q_addr + ADV_SCSIQ_W_REQ_COUNT,
 1841                           adv->req_count);
 1842 #endif
 1843 
 1844 #ifdef CC_CLEAR_DMA_REMAIN
 1845 
 1846         adv_write_lram_32(adv, q_addr + ADV_SCSIQ_DW_REMAIN_XFER_ADDR, 0);
 1847         adv_write_lram_32(adv, q_addr + ADV_SCSIQ_DW_REMAIN_XFER_CNT, 0);
 1848 #endif
 1849 
 1850         adv_write_lram_16(adv, q_addr + ADV_SCSIQ_B_STATUS,
 1851                           (scsiq->q1.q_no << 8) | QS_READY);
 1852 }
 1853 
 1854 static void
 1855 adv_put_scsiq(struct adv_softc *adv, u_int16_t s_addr,
 1856               u_int16_t *buffer, int words)
 1857 {
 1858         int     i;
 1859 
 1860         /*
 1861          * XXX This routine makes *gross* assumptions
 1862          * about padding in the data structures.
 1863          * Either the data structures should have explicit
 1864          * padding members added, or they should have padding
 1865          * turned off via compiler attributes depending on
 1866          * which yields better overall performance.  My hunch
 1867          * would be that turning off padding would be the
 1868          * faster approach as an outsw is much faster than
 1869          * this crude loop and accessing un-aligned data
 1870          * members isn't *that* expensive.  The other choice
 1871          * would be to modify the ASC script so that the
 1872          * the adv_scsiq_1 structure can be re-arranged so
 1873          * padding isn't required.
 1874          */
 1875         ADV_OUTW(adv, ADV_LRAM_ADDR, s_addr);
 1876         for (i = 0; i < words; i++, buffer++) {
 1877                 if (i == 2 || i == 10) {
 1878                         continue;
 1879                 }
 1880                 ADV_OUTW(adv, ADV_LRAM_DATA, *buffer);
 1881         }
 1882 }
 1883 
 1884 #if BYTE_ORDER == BIG_ENDIAN
 1885 void
 1886 adv_adj_endian_qdone_info(struct adv_q_done_info *scsiq)
 1887 {
 1888 
 1889         panic("adv(4) not supported on big-endian machines.\n");
 1890 }
 1891 
 1892 void
 1893 adv_adj_scsiq_endian(struct adv_scsi_q *scsiq)
 1894 {
 1895 
 1896         panic("adv(4) not supported on big-endian machines.\n");
 1897 }
 1898 #endif
 1899 
 1900 static void
 1901 adv_handle_extmsg_in(struct adv_softc *adv, u_int16_t halt_q_addr,
 1902                      u_int8_t q_cntl, target_bit_vector target_mask,
 1903                      int tid_no)
 1904 {
 1905         struct  ext_msg ext_msg;
 1906 
 1907         adv_read_lram_16_multi(adv, ADVV_MSGIN_BEG, (u_int16_t *) &ext_msg,
 1908                                sizeof(ext_msg) >> 1);
 1909         if ((ext_msg.msg_type == MSG_EXTENDED)
 1910          && (ext_msg.msg_req == MSG_EXT_SDTR)
 1911          && (ext_msg.msg_len == MSG_EXT_SDTR_LEN)) {
 1912                 union     ccb *ccb;
 1913                 struct    adv_target_transinfo* tinfo;
 1914                 u_int32_t cinfo_index;
 1915                 u_int    period;
 1916                 u_int    offset;
 1917                 int      sdtr_accept;
 1918                 u_int8_t orig_offset;
 1919 
 1920                 cinfo_index =
 1921                     adv_read_lram_32(adv, halt_q_addr + ADV_SCSIQ_D_CINFO_IDX);
 1922                 ccb = adv->ccb_infos[cinfo_index].ccb;
 1923                 tinfo = &adv->tinfo[tid_no];
 1924                 sdtr_accept = TRUE;
 1925 
 1926                 orig_offset = ext_msg.req_ack_offset;
 1927                 if (ext_msg.xfer_period < tinfo->goal.period) {
 1928                         sdtr_accept = FALSE;
 1929                         ext_msg.xfer_period = tinfo->goal.period;
 1930                 }
 1931 
 1932                 /* Perform range checking */
 1933                 period = ext_msg.xfer_period;
 1934                 offset = ext_msg.req_ack_offset;
 1935                 adv_period_offset_to_sdtr(adv, &period,  &offset, tid_no);
 1936                 ext_msg.xfer_period = period;
 1937                 ext_msg.req_ack_offset = offset;
 1938                 
 1939                 /* Record our current sync settings */
 1940                 adv_set_syncrate(adv, ccb->ccb_h.path,
 1941                                  tid_no, ext_msg.xfer_period,
 1942                                  ext_msg.req_ack_offset,
 1943                                  ADV_TRANS_GOAL|ADV_TRANS_ACTIVE);
 1944 
 1945                 /* Offset too high or large period forced async */
 1946                 if (orig_offset != ext_msg.req_ack_offset)
 1947                         sdtr_accept = FALSE;
 1948 
 1949                 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
 1950                         /* Valid response to our requested negotiation */
 1951                         q_cntl &= ~QC_MSG_OUT;
 1952                 } else {
 1953                         /* Must Respond */
 1954                         q_cntl |= QC_MSG_OUT;
 1955                         adv_msgout_sdtr(adv, ext_msg.xfer_period,
 1956                                         ext_msg.req_ack_offset);
 1957                 }
 1958 
 1959         } else if (ext_msg.msg_type == MSG_EXTENDED
 1960                 && ext_msg.msg_req == MSG_EXT_WDTR
 1961                 && ext_msg.msg_len == MSG_EXT_WDTR_LEN) {
 1962 
 1963                 ext_msg.wdtr_width = 0;
 1964                 adv_write_lram_16_multi(adv, ADVV_MSGOUT_BEG,
 1965                                         (u_int16_t *)&ext_msg,
 1966                                         sizeof(ext_msg) >> 1);
 1967                 q_cntl |= QC_MSG_OUT;
 1968         } else {
 1969 
 1970                 ext_msg.msg_type = MSG_MESSAGE_REJECT;
 1971                 adv_write_lram_16_multi(adv, ADVV_MSGOUT_BEG,
 1972                                         (u_int16_t *)&ext_msg,
 1973                                         sizeof(ext_msg) >> 1);
 1974                 q_cntl |= QC_MSG_OUT;
 1975         }
 1976         adv_write_lram_8(adv, halt_q_addr + ADV_SCSIQ_B_CNTL, q_cntl);
 1977 }
 1978 
 1979 static void
 1980 adv_msgout_sdtr(struct adv_softc *adv, u_int8_t sdtr_period,
 1981                 u_int8_t sdtr_offset)
 1982 {
 1983         struct   ext_msg sdtr_buf;
 1984 
 1985         sdtr_buf.msg_type = MSG_EXTENDED;
 1986         sdtr_buf.msg_len = MSG_EXT_SDTR_LEN;
 1987         sdtr_buf.msg_req = MSG_EXT_SDTR;
 1988         sdtr_buf.xfer_period = sdtr_period;
 1989         sdtr_offset &= ADV_SYN_MAX_OFFSET;
 1990         sdtr_buf.req_ack_offset = sdtr_offset;
 1991         adv_write_lram_16_multi(adv, ADVV_MSGOUT_BEG,
 1992                                 (u_int16_t *) &sdtr_buf,
 1993                                 sizeof(sdtr_buf) / 2);
 1994 }
 1995 
 1996 int
 1997 adv_abort_ccb(struct adv_softc *adv, int target, int lun, union ccb *ccb,
 1998               u_int32_t status, int queued_only)
 1999 {
 2000         u_int16_t q_addr;
 2001         u_int8_t  q_no;
 2002         struct adv_q_done_info scsiq_buf;
 2003         struct adv_q_done_info *scsiq;
 2004         u_int8_t  target_ix;
 2005         int       count;
 2006 
 2007         if (!dumping)
 2008                 mtx_assert(&adv->lock, MA_OWNED);
 2009         scsiq = &scsiq_buf;
 2010         target_ix = ADV_TIDLUN_TO_IX(target, lun);
 2011         count = 0;
 2012         for (q_no = ADV_MIN_ACTIVE_QNO; q_no <= adv->max_openings; q_no++) {
 2013                 struct adv_ccb_info *ccb_info;
 2014                 q_addr = ADV_QNO_TO_QADDR(q_no);
 2015 
 2016                 adv_copy_lram_doneq(adv, q_addr, scsiq, adv->max_dma_count);
 2017                 ccb_info = &adv->ccb_infos[scsiq->d2.ccb_index];
 2018                 if (((scsiq->q_status & QS_READY) != 0)
 2019                  && ((scsiq->q_status & QS_ABORTED) == 0)
 2020                  && ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)
 2021                  && (scsiq->d2.target_ix == target_ix)
 2022                  && (queued_only == 0
 2023                   || !(scsiq->q_status & (QS_DISC1|QS_DISC2|QS_BUSY|QS_DONE)))
 2024                  && (ccb == NULL || (ccb == ccb_info->ccb))) {
 2025                         union ccb *aborted_ccb;
 2026                         struct adv_ccb_info *cinfo;
 2027 
 2028                         scsiq->q_status |= QS_ABORTED;
 2029                         adv_write_lram_8(adv, q_addr + ADV_SCSIQ_B_STATUS,
 2030                                          scsiq->q_status);
 2031                         aborted_ccb = ccb_info->ccb;
 2032                         /* Don't clobber earlier error codes */
 2033                         if ((aborted_ccb->ccb_h.status & CAM_STATUS_MASK)
 2034                           == CAM_REQ_INPROG)
 2035                                 aborted_ccb->ccb_h.status |= status;
 2036                         cinfo = (struct adv_ccb_info *)
 2037                             aborted_ccb->ccb_h.ccb_cinfo_ptr;
 2038                         cinfo->state |= ACCB_ABORT_QUEUED;
 2039                         count++;
 2040                 }
 2041         }
 2042         return (count);
 2043 }
 2044 
 2045 int
 2046 adv_reset_bus(struct adv_softc *adv, int initiate_bus_reset)
 2047 {
 2048         int count; 
 2049         int i;
 2050         union ccb *ccb;
 2051 
 2052         if (!dumping)
 2053                 mtx_assert(&adv->lock, MA_OWNED);
 2054         i = 200;
 2055         while ((ADV_INW(adv, ADV_CHIP_STATUS) & ADV_CSW_SCSI_RESET_ACTIVE) != 0
 2056             && i--)
 2057                 DELAY(1000);
 2058         adv_reset_chip(adv, initiate_bus_reset);
 2059         adv_reinit_lram(adv);
 2060         for (i = 0; i <= ADV_MAX_TID; i++)
 2061                 adv_set_syncrate(adv, NULL, i, /*period*/0,
 2062                                  /*offset*/0, ADV_TRANS_CUR);
 2063         ADV_OUTW(adv, ADV_REG_PROG_COUNTER, ADV_MCODE_START_ADDR);
 2064 
 2065         /* Tell the XPT layer that a bus reset occurred */
 2066         if (adv->path != NULL)
 2067                 xpt_async(AC_BUS_RESET, adv->path, NULL);
 2068 
 2069         count = 0;
 2070         while ((ccb = (union ccb *)LIST_FIRST(&adv->pending_ccbs)) != NULL) {
 2071                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG)
 2072                         ccb->ccb_h.status |= CAM_SCSI_BUS_RESET;
 2073                 adv_done(adv, ccb, QD_ABORTED_BY_HOST, 0, 0, 0);
 2074                 count++;
 2075         }
 2076 
 2077         adv_start_chip(adv);
 2078         return (count);
 2079 }
 2080 
 2081 static void
 2082 adv_set_sdtr_reg_at_id(struct adv_softc *adv, int tid, u_int8_t sdtr_data)
 2083 {
 2084         int orig_id;
 2085 
 2086         adv_set_bank(adv, 1);
 2087         orig_id = ffs(ADV_INB(adv, ADV_HOST_SCSIID)) - 1;
 2088         ADV_OUTB(adv, ADV_HOST_SCSIID, tid);
 2089         if (ADV_INB(adv, ADV_HOST_SCSIID) == (0x01 << tid)) {
 2090                 adv_set_bank(adv, 0);
 2091                 ADV_OUTB(adv, ADV_SYN_OFFSET, sdtr_data);
 2092         }
 2093         adv_set_bank(adv, 1);
 2094         ADV_OUTB(adv, ADV_HOST_SCSIID, orig_id);
 2095         adv_set_bank(adv, 0);
 2096 }

Cache object: 7442b220afb452f01c8a5bdd3bc32205


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