root/arch/i386/isa/ahc_isa.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. LIST_HEAD
  2. ahc_isa_idstring
  3. ahc_isa_match
  4. ahc_isa_probe
  5. ahc_isa_attach
  6. aha2840_load_seeprom

    1 /*      $OpenBSD: ahc_isa.c,v 1.16 2007/04/10 17:47:54 miod Exp $       */
    2 /*      $NetBSD: ahc_isa.c,v 1.5 1996/10/21 22:27:39 thorpej Exp $      */
    3 
    4 /*
    5  * Product specific probe and attach routines for:
    6  *      284X VLbus SCSI controllers
    7  *
    8  * Copyright (c) 1996 Jason R. Thorpe.
    9  * All rights reserved.
   10  *
   11  * Copyright (c) 1995, 1996 Christopher G. Demetriou.
   12  * All rights reserved.
   13  *
   14  * Copyright (c) 1994, 1995, 1996 Justin T. Gibbs.
   15  * All rights reserved.
   16  *
   17  * Redistribution and use in source and binary forms, with or without
   18  * modification, are permitted provided that the following conditions
   19  * are met:
   20  * 1. Redistributions of source code must retain the above copyright
   21  *    notice immediately at the beginning of the file, without modification,
   22  *    this list of conditions, and the following disclaimer.
   23  * 2. Redistributions in binary form must reproduce the above copyright
   24  *    notice, this list of conditions and the following disclaimer in the
   25  *    documentation and/or other materials provided with the distribution.
   26  * 3. All advertising materials mentioning features or use of this software
   27  *    must display the following acknowledgement:
   28  *      This product includes software developed by Christopher G. Demetriou
   29  *      for the NetBSD Project.
   30  * 4. The name of the author may not be used to endorse or promote products
   31  *    derived from this software without specific prior written permission.
   32  *
   33  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   34  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   35  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   36  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   37  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   38  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   39  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   40  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   41  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   42  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   43  * SUCH DAMAGE.
   44  */
   45 
   46 /*
   47  * This front-end driver is really sort of a hack.  The AHA-284X likes
   48  * to masquerade as an EISA device.  However, on VLbus machines with
   49  * no EISA signature in the BIOS, the EISA bus will never be scanned.
   50  * This is intended to catch the 284X controllers on those systems
   51  * by looking in "EISA i/o space" for 284X controllers.
   52  *
   53  * This relies heavily on i/o port accounting.  We also just use the
   54  * EISA macros for everything ... it's a real waste to redefine them.
   55  *
   56  * Note: there isn't any #ifdef for FreeBSD in this file, since the
   57  * FreeBSD EISA driver handles all cases of the 284X.
   58  *
   59  *      -- Jason R. Thorpe <thorpej@NetBSD.ORG>
   60  *         July 12, 1996
   61  *
   62  * TODO: some code could be shared with ahc_eisa.c, but it would probably
   63  * be a logistical mightmare to even try.
   64  */
   65 
   66 #include <sys/param.h>
   67 #include <sys/systm.h>
   68 #include <sys/kernel.h>
   69 #include <sys/device.h>
   70 #include <sys/queue.h>
   71 #include <sys/malloc.h>
   72 
   73 #include <machine/bus.h>
   74 #include <machine/intr.h>
   75 
   76 #include <scsi/scsi_all.h>
   77 #include <scsi/scsiconf.h>
   78 
   79 #include <dev/isa/isavar.h>
   80 
   81 #include <dev/eisa/eisareg.h>
   82 #include <dev/eisa/eisavar.h>
   83 #include <dev/eisa/eisadevs.h>
   84 
   85 #include <dev/ic/aic7xxx_openbsd.h>
   86 #include <dev/ic/aic7xxx_inline.h>
   87 #include <dev/ic/smc93cx6var.h>
   88 
   89 #ifdef DEBUG
   90 #define bootverbose     1
   91 #else
   92 #define bootverbose     0
   93 #endif
   94 
   95 /* IO port address setting range as EISA slot number */
   96 #define AHC_ISA_MIN_SLOT        0x1     /* from iobase = 0x1c00 */
   97 #define AHC_ISA_MAX_SLOT        0xe     /* to   iobase = 0xec00 */
   98 
   99 #define AHC_ISA_SLOT_OFFSET     0xc00   /* offset from EISA IO space */
  100 #define AHC_ISA_IOSIZE          0x100
  101 
  102 /*
  103  * I/O port offsets
  104  */
  105 #define AHC_ISA_VID             (EISA_SLOTOFF_VID - AHC_ISA_SLOT_OFFSET)
  106 #define AHC_ISA_PID             (EISA_SLOTOFF_PID - AHC_ISA_SLOT_OFFSET)
  107 #define AHC_ISA_PRIMING         AHC_ISA_VID     /* enable vendor/product ID */
  108 
  109 /*
  110  * AHC_ISA_PRIMING register values (write)
  111  */
  112 #define AHC_ISA_PRIMING_VID(index)      (AHC_ISA_VID + (index))
  113 #define AHC_ISA_PRIMING_PID(index)      (AHC_ISA_PID + (index))
  114 
  115 int     ahc_isa_irq(bus_space_tag_t, bus_space_handle_t);
  116 int     ahc_isa_idstring(bus_space_tag_t, bus_space_handle_t, char *);
  117 int     ahc_isa_match(struct isa_attach_args *, bus_addr_t);
  118 
  119 int     ahc_isa_probe(struct device *, void *, void *);
  120 void    ahc_isa_attach(struct device *, struct device *, void *);
  121 void    aha2840_load_seeprom(struct ahc_softc *ahc);
  122 
  123 struct cfattach ahc_isa_ca = {
  124         sizeof(struct ahc_softc), ahc_isa_probe, ahc_isa_attach
  125 };
  126 
  127 /*
  128  * This keeps track of which slots are to be checked next if the
  129  * iobase locator is a wildcard.  A simple static variable isn't enough,
  130  * since it's conceivable that a system might have more than one ISA
  131  * bus.
  132  *
  133  * The "bus" member is the unit number of the parent ISA bus, e.g. "0"
  134  * for "isa0".
  135  */
  136 struct ahc_isa_slot {
  137         LIST_ENTRY(ahc_isa_slot)        link;
  138         int                             bus;
  139         int                             slot;
  140 };
  141 static LIST_HEAD(, ahc_isa_slot) ahc_isa_all_slots;
  142 static int ahc_isa_slot_initialized;
  143 
  144 /*
  145  * Return irq setting of the board, otherwise -1.
  146  */
  147 int
  148 ahc_isa_irq(bus_space_tag_t iot, bus_space_handle_t ioh)
  149 {
  150         int irq;
  151         u_char intdef;
  152         u_char hcntrl;
  153         
  154         /* Pause the card preseving the IRQ type */
  155         hcntrl = bus_space_read_1(iot, ioh, HCNTRL) & IRQMS;
  156         bus_space_write_1(iot, ioh, HCNTRL, hcntrl | PAUSE);
  157 
  158         intdef = bus_space_read_1(iot, ioh, INTDEF);
  159         switch (irq = (intdef & VECTOR)) {
  160         case 9:
  161         case 10:
  162         case 11:
  163         case 12:
  164         case 14:
  165         case 15:
  166                 break;
  167         default:
  168                 printf("ahc_isa_irq: illegal irq setting %d\n", intdef);
  169                 return -1;
  170         }
  171 
  172         /* Note that we are going and return (to probe) */
  173         return irq;
  174 }
  175 
  176 int
  177 ahc_isa_idstring(bus_space_tag_t iot, bus_space_handle_t ioh, char *idstring)
  178 {
  179         u_int8_t vid[EISA_NVIDREGS], pid[EISA_NPIDREGS];
  180         int i;
  181 
  182         /* Get the vendor ID bytes */
  183         for (i = 0; i < EISA_NVIDREGS; i++) {
  184                 bus_space_write_1(iot, ioh, AHC_ISA_PRIMING,
  185                     AHC_ISA_PRIMING_VID(i));
  186                 vid[i] = bus_space_read_1(iot, ioh, AHC_ISA_VID + i);
  187         }
  188 
  189         /* Check for device existence */
  190         if (EISA_VENDID_NODEV(vid)) {
  191 #if 0
  192                 printf("ahc_isa_idstring: no device at 0x%lx\n",
  193                     ioh); /* XXX knows about ioh guts */
  194                 printf("\t(0x%x, 0x%x)\n", vid[0], vid[1]);
  195 #endif
  196                 return (0);
  197         }
  198 
  199         /* And check that the firmware didn't biff something badly */
  200         if (EISA_VENDID_IDDELAY(vid)) {
  201                 printf("ahc_isa_idstring: BIOS biffed it at 0x%lx\n",
  202                     ioh);       /* XXX knows about ioh guts */
  203                 return (0);
  204         }
  205 
  206         /* Get the product ID bytes */
  207         for (i = 0; i < EISA_NPIDREGS; i++) {
  208                 bus_space_write_1(iot, ioh, AHC_ISA_PRIMING,
  209                     AHC_ISA_PRIMING_PID(i));
  210                 pid[i] = bus_space_read_1(iot, ioh, AHC_ISA_PID + i);
  211         }
  212 
  213         /* Create the ID string from the vendor and product IDs */
  214         idstring[0] = EISA_VENDID_0(vid);
  215         idstring[1] = EISA_VENDID_1(vid);
  216         idstring[2] = EISA_VENDID_2(vid);
  217         idstring[3] = EISA_PRODID_0(pid);
  218         idstring[4] = EISA_PRODID_1(pid);
  219         idstring[5] = EISA_PRODID_2(pid);
  220         idstring[6] = EISA_PRODID_3(pid);
  221         idstring[7] = '\0';             /* sanity */
  222 
  223         return (1);
  224 }
  225 
  226 int
  227 ahc_isa_match(struct isa_attach_args *ia, bus_addr_t iobase)
  228 {
  229         bus_space_tag_t iot = ia->ia_iot;
  230         bus_space_handle_t ioh;
  231         int irq;
  232         char idstring[EISA_IDSTRINGLEN];
  233 
  234         /*
  235          * Get a mapping for the while slot-specific address
  236          * space.  If we can't, assume nothing's there, but
  237          * warn about it.
  238          */
  239         if (bus_space_map(iot, iobase, AHC_ISA_IOSIZE, 0, &ioh)) {
  240 #if 0
  241                 /*
  242                  * Don't print anything out here, since this could
  243                  * be common on machines configured to look for
  244                  * ahc_eisa and ahc_isa.
  245                  */
  246                 printf("ahc_isa_match: can't map I/O space for 0x%x\n",
  247                     iobase);
  248 #endif
  249                 return (0);
  250         }
  251 
  252         if (!ahc_isa_idstring(iot, ioh, idstring))
  253                 irq = -1;       /* cannot get the ID string */
  254         else if (strcmp(idstring, "ADP7756") &&
  255             strcmp(idstring, "ADP7757"))
  256                 irq = -1;       /* unknown ID strings */
  257         else
  258                 irq = ahc_isa_irq(iot, ioh);
  259 
  260         bus_space_unmap(iot, ioh, AHC_ISA_IOSIZE);
  261 
  262         if (irq < 0)
  263                 return (0);
  264 
  265         if (ia->ia_irq != IRQUNK &&
  266             ia->ia_irq != irq) {
  267                 printf("ahc_isa_match: irq mismatch (kernel %d, card %d)\n",
  268                        ia->ia_irq, irq);
  269                 return (0);
  270         }
  271 
  272         /* We have a match */
  273         ia->ia_iobase = iobase;
  274         ia->ia_irq = irq;
  275         ia->ia_iosize = AHC_ISA_IOSIZE;
  276         ia->ia_msize = 0;
  277         return (1);
  278 }
  279 
  280 /*
  281  * Check the slots looking for a board we recognise
  282  * If we find one, note its address (slot) and call
  283  * the actual probe routine to check it out.
  284  */
  285 int
  286 ahc_isa_probe(struct device *parent, void *match, void *aux)
  287 {       
  288         struct isa_attach_args *ia = aux;
  289         struct ahc_isa_slot *as;
  290 
  291         if (ahc_isa_slot_initialized == 0) {
  292                 LIST_INIT(&ahc_isa_all_slots);
  293                 ahc_isa_slot_initialized = 1;
  294         }
  295 
  296         if (ia->ia_iobase != IOBASEUNK)
  297                 return (ahc_isa_match(ia, ia->ia_iobase));
  298 
  299         /*
  300          * Find this bus's state.  If we don't yet have a slot
  301          * marker, allocate and initialize one.
  302          */
  303         LIST_FOREACH(as, &ahc_isa_all_slots, link)
  304                 if (as->bus == parent->dv_unit)
  305                         goto found_slot_marker;
  306 
  307         /*
  308          * Don't have one, so make one.
  309          */
  310         as = (struct ahc_isa_slot *)
  311             malloc(sizeof(struct ahc_isa_slot), M_DEVBUF, M_NOWAIT);
  312         if (as == NULL)
  313                 panic("ahc_isa_probe: can't allocate slot marker");
  314 
  315         as->bus = parent->dv_unit;
  316         as->slot = AHC_ISA_MIN_SLOT;
  317         LIST_INSERT_HEAD(&ahc_isa_all_slots, as, link);
  318 
  319  found_slot_marker:
  320 
  321         for (; as->slot <= AHC_ISA_MAX_SLOT; as->slot++) {
  322                 if (ahc_isa_match(ia, EISA_SLOT_ADDR(as->slot) +
  323                     AHC_ISA_SLOT_OFFSET)) {
  324                         as->slot++; /* next slot to search */
  325                         return (1);
  326                 }
  327         }
  328 
  329         /* No matching cards were found. */
  330         return (0);
  331 }
  332 
  333 void
  334 ahc_isa_attach(struct device *parent, struct device *self, void *aux)
  335 {
  336         struct ahc_softc *ahc = (void *)self;
  337         struct isa_attach_args *ia = aux;
  338         bus_space_tag_t iot = ia->ia_iot;
  339         bus_space_handle_t ioh;
  340         int irq;
  341         char idstring[EISA_IDSTRINGLEN];
  342         const char *model;
  343         u_int intdef;
  344         
  345         ahc_set_name(ahc, ahc->sc_dev.dv_xname);
  346         ahc_set_unit(ahc, ahc->sc_dev.dv_unit);
  347         
  348         /* set dma tags */
  349         ahc->parent_dmat = ia->ia_dmat;
  350         
  351         ahc->chip = AHC_VL; /* We are a VL Bus Controller */  
  352         
  353         if (bus_space_map(iot, ia->ia_iobase, ia->ia_iosize, 0, &ioh))
  354                 panic("ahc_isa_attach: could not map slot I/O addresses");
  355         if (!ahc_isa_idstring(iot, ioh, idstring))
  356                 panic("ahc_isa_attach: could not read ID string");
  357         if ((irq = ahc_isa_irq(iot, ioh)) < 0)
  358                 panic("ahc_isa_attach: ahc_isa_irq failed!");
  359 
  360         if (strcmp(idstring, "ADP7756") == 0) {
  361                 model = EISA_PRODUCT_ADP7756;
  362         } else if (strcmp(idstring, "ADP7757") == 0) {
  363                 model = EISA_PRODUCT_ADP7757;
  364         } else {
  365                 panic("ahc_isa_attach: Unknown device type %s", idstring);
  366         }
  367         printf(": %s\n", model);
  368         
  369         ahc->channel = 'A';
  370         ahc->chip = AHC_AIC7770;
  371         ahc->features = AHC_AIC7770_FE;
  372         ahc->bugs |= AHC_TMODE_WIDEODD_BUG;
  373         ahc->flags |= AHC_PAGESCBS;
  374         
  375         /* set tag and handle */
  376         ahc->tag = iot;
  377         ahc->bsh = ioh;
  378 
  379 #ifdef DEBUG
  380         /*
  381          * Tell the user what type of interrupts we're using.
  382          * usefull for debugging irq problems
  383          */
  384         printf( "%s: Using %s Interrupts\n", ahc_name(ahc),
  385             ahc->pause & IRQMS ?  "Level Sensitive" : "Edge Triggered");
  386 #endif
  387 
  388         if (ahc_reset(ahc, /*reinit*/FALSE) != 0)
  389                 return;
  390         
  391         /* See if we are edge triggered */
  392         intdef = ahc_inb(ahc, INTDEF);
  393         if ((intdef & EDGE_TRIG) != 0)
  394                 ahc->flags |= AHC_EDGE_INTERRUPT;
  395 
  396         /*
  397          * Now that we know we own the resources we need, do the 
  398          * card initialization.
  399          */
  400         aha2840_load_seeprom(ahc);
  401 
  402         /*      
  403          * See if we have a Rev E or higher aic7770. Anything below a
  404          * Rev E will have a R/O autoflush disable configuration bit.
  405          * It's still not clear exactly what is differenent about the Rev E.
  406          * We think it allows 8 bit entries in the QOUTFIFO to support
  407          * "paging" SCBs so you can have more than 4 commands active at
  408          * once.
  409          */     
  410         {
  411                 char *id_string;
  412                 u_char sblkctl;
  413                 u_char sblkctl_orig;
  414 
  415                 sblkctl_orig = ahc_inb(ahc, SBLKCTL);
  416                 sblkctl = sblkctl_orig ^ AUTOFLUSHDIS;
  417                 ahc_outb(ahc, SBLKCTL, sblkctl);
  418                 sblkctl = ahc_inb(ahc, SBLKCTL);
  419                 if(sblkctl != sblkctl_orig)
  420                 {
  421                         id_string = "aic7770 >= Rev E, ";
  422                         /*
  423                          * Ensure autoflush is enabled
  424                          */
  425                         sblkctl &= ~AUTOFLUSHDIS;
  426                         ahc_outb(ahc, SBLKCTL, sblkctl);
  427 
  428                         /* Allow paging on this adapter */
  429                         ahc->flags |= AHC_PAGESCBS;
  430                 }
  431                 else
  432                         id_string = "aic7770 <= Rev C, ";
  433 
  434                 printf("%s: %s", ahc_name(ahc), id_string);
  435         }
  436 
  437         /* Setup the FIFO threshold and the bus off time */
  438         {
  439                 u_char hostconf = ahc_inb(ahc, HOSTCONF);
  440                 ahc_outb(ahc, BUSSPD, hostconf & DFTHRSH);
  441                 ahc_outb(ahc, BUSTIME, (hostconf << 2) & BOFF);
  442         }
  443 
  444         /*
  445          * Generic aic7xxx initialization.
  446          */
  447         if(ahc_init(ahc)){
  448                 ahc_free(ahc);
  449                 return;
  450         }
  451         
  452         /*
  453          * Link this softc in with all other ahc instances.
  454          */
  455         ahc_softc_insert(ahc);
  456 
  457         /*
  458          * Enable the board's BUS drivers
  459          */
  460         ahc_outb(ahc, BCTL, ENABLE);
  461 
  462         /*
  463          * The IRQMS bit enables level sensitive interrupts only allow
  464          * IRQ sharing if its set.
  465          */
  466         ahc->ih = isa_intr_establish(ia->ia_ic, irq,
  467             ahc->pause & IRQMS ? IST_LEVEL : IST_EDGE, IPL_BIO, ahc_platform_intr,
  468             ahc, ahc->sc_dev.dv_xname);
  469         if (ahc->ih == NULL) {
  470                 printf("%s: couldn't establish interrupt\n",
  471                        ahc->sc_dev.dv_xname);
  472                 ahc_free(ahc);
  473                 return;
  474         }
  475 
  476         ahc_intr_enable(ahc, TRUE);
  477         
  478         /* Attach sub-devices - always succeeds */
  479         ahc_attach(ahc);
  480 }
  481 
  482 /*
  483  * Read the 284x SEEPROM.
  484  */
  485 void
  486 aha2840_load_seeprom(struct ahc_softc *ahc)
  487 {
  488         struct    seeprom_descriptor sd;
  489         struct    seeprom_config sc;
  490         u_int16_t checksum = 0;
  491         u_int8_t  scsi_conf;
  492         int       have_seeprom;
  493 
  494         sd.sd_tag = ahc->tag;
  495         sd.sd_bsh = ahc->bsh;
  496         sd.sd_regsize = 1;
  497         sd.sd_control_offset = SEECTL_2840;
  498         sd.sd_status_offset = STATUS_2840;
  499         sd.sd_dataout_offset = STATUS_2840;             
  500         sd.sd_chip = C46;
  501         sd.sd_MS = 0;
  502         sd.sd_RDY = EEPROM_TF;
  503         sd.sd_CS = CS_2840;
  504         sd.sd_CK = CK_2840;
  505         sd.sd_DO = DO_2840;
  506         sd.sd_DI = DI_2840;
  507 
  508         if (bootverbose)
  509                 printf("%s: Reading SEEPROM...", ahc_name(ahc));
  510         have_seeprom = read_seeprom(&sd, 
  511                                     (u_int16_t *)&sc, 
  512                                     /*start_addr*/0,
  513                                     sizeof(sc)/2);
  514 
  515         if (have_seeprom) {
  516                 /* Check checksum */
  517                 int i;
  518                 int maxaddr = (sizeof(sc)/2) - 1;
  519                 u_int16_t *scarray = (u_int16_t *)&sc;
  520 
  521                 for (i = 0; i < maxaddr; i++)
  522                         checksum = checksum + scarray[i];
  523                 if (checksum != sc.checksum) {
  524                         if(bootverbose)
  525                                 printf ("checksum error\n");
  526                         have_seeprom = 0;
  527                 } else if (bootverbose) {
  528                         printf("done.\n");
  529                 }
  530         }
  531 
  532         if (!have_seeprom) {
  533                 if (bootverbose)
  534                         printf("%s: No SEEPROM available\n", ahc_name(ahc));
  535                 ahc->flags |= AHC_USEDEFAULTS;
  536         } else {
  537                 /*
  538                  * Put the data we've collected down into SRAM
  539                  * where ahc_init will find it.
  540                  */
  541                 int i;
  542                 int max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8;
  543                 u_int16_t discenable;
  544 
  545                 discenable = 0;
  546                 for (i = 0; i < max_targ; i++){
  547                         u_int8_t target_settings;
  548                         target_settings = (sc.device_flags[i] & CFXFER) << 4;
  549                         if (sc.device_flags[i] & CFSYNCH)
  550                                 target_settings |= SOFS;
  551                         if (sc.device_flags[i] & CFWIDEB)
  552                                 target_settings |= WIDEXFER;
  553                         if (sc.device_flags[i] & CFDISC)
  554                                 discenable |= (0x01 << i);
  555                         ahc_outb(ahc, TARG_SCSIRATE + i, target_settings);
  556                 }
  557                 ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));
  558                 ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));
  559 
  560                 ahc->our_id = sc.brtime_id & CFSCSIID;
  561 
  562                 scsi_conf = (ahc->our_id & 0x7);
  563                 if (sc.adapter_control & CFSPARITY)
  564                         scsi_conf |= ENSPCHK;
  565                 if (sc.adapter_control & CFRESETB)
  566                         scsi_conf |= RESET_SCSI;
  567 
  568                 if (sc.bios_control & CF284XEXTEND)             
  569                         ahc->flags |= AHC_EXTENDED_TRANS_A;
  570                 /* Set SCSICONF info */
  571                 ahc_outb(ahc, SCSICONF, scsi_conf);
  572 
  573                 if (sc.adapter_control & CF284XSTERM)
  574                         ahc->flags |= AHC_TERM_ENB_A;
  575         }
  576 }

/* [<][>][^][v][top][bottom][index][help] */