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/isa/isic_isa_avm_a1.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  *   Copyright (c) 1996 Andrew Gordon. All rights reserved.
    3  *
    4  *   Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
    5  *
    6  *   Redistribution and use in source and binary forms, with or without
    7  *   modification, are permitted provided that the following conditions
    8  *   are met:
    9  *
   10  *   1. Redistributions of source code must retain the above copyright
   11  *      notice, this list of conditions and the following disclaimer.
   12  *   2. Redistributions in binary form must reproduce the above copyright
   13  *      notice, this list of conditions and the following disclaimer in the
   14  *      documentation and/or other materials provided with the distribution.
   15  *   3. Neither the name of the author nor the names of any co-contributors
   16  *      may be used to endorse or promote products derived from this software
   17  *      without specific prior written permission.
   18  *   4. Altered versions must be plainly marked as such, and must not be
   19  *      misrepresented as being the original software and/or documentation.
   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
   25  *   FOR 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  *
   35  *      i4b_avm_a1.c - AVM A1/Fritz passive card driver for isdn4bsd
   36  *      ------------------------------------------------------------
   37  *
   38  *      $Id: isic_isa_avm_a1.c,v 1.4 2002/03/24 20:35:48 martin Exp $ 
   39  *
   40  *      last edit-date: [Fri Jan  5 11:37:22 2001]
   41  *
   42  *---------------------------------------------------------------------------*/
   43 
   44 #include <sys/cdefs.h>
   45 __KERNEL_RCSID(0, "$NetBSD: isic_isa_avm_a1.c,v 1.4 2002/03/24 20:35:48 martin Exp $");
   46 
   47 #include "opt_isicisa.h"
   48 #ifdef ISICISA_AVM_A1
   49 
   50 #include <sys/param.h>
   51 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
   52 #include <sys/ioccom.h>
   53 #else
   54 #include <sys/ioctl.h>
   55 #endif
   56 #include <sys/kernel.h>
   57 #include <sys/systm.h>
   58 #include <sys/mbuf.h>
   59 
   60 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
   61 #include <sys/callout.h>
   62 #endif
   63 
   64 #ifdef __FreeBSD__
   65 #include <machine/clock.h>
   66 #include <i386/isa/isa_device.h>
   67 #else
   68 #include <machine/bus.h>
   69 #include <sys/device.h>
   70 #endif
   71 
   72 #include <sys/socket.h>
   73 #include <net/if.h>
   74 
   75 #ifdef __FreeBSD__
   76 #include <machine/i4b_debug.h>
   77 #include <machine/i4b_ioctl.h>
   78 #else
   79 #include <netisdn/i4b_debug.h>
   80 #include <netisdn/i4b_ioctl.h>
   81 #endif
   82 
   83 #include <netisdn/i4b_global.h>
   84 #include <netisdn/i4b_l2.h>
   85 #include <netisdn/i4b_l1l2.h>
   86 
   87 #include <dev/ic/isic_l1.h>
   88 #include <dev/ic/isac.h>
   89 #include <dev/ic/hscx.h>
   90 
   91 #ifndef __FreeBSD__
   92 static u_int8_t avma1_read_reg __P((struct isic_softc *sc, int what, bus_size_t offs));
   93 static void avma1_write_reg __P((struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data));
   94 static void avma1_read_fifo __P((struct isic_softc *sc, int what, void *buf, size_t size));
   95 static void avma1_write_fifo __P((struct isic_softc *sc, int what, const void *data, size_t size));
   96 #endif
   97 
   98 /*---------------------------------------------------------------------------*
   99  *      AVM A1 and AVM Fritz! Card special registers
  100  *---------------------------------------------------------------------------*/
  101 
  102 #define AVM_CONF_REG    0x1800          /* base offset for config register */
  103 #define AVM_CONF_IRQ    0x1801          /* base offset for IRQ register    */
  104                                         /* config register write           */
  105 #define  AVM_CONF_WR_RESET      0x01    /* 1 = RESET ISAC and HSCX         */
  106 #define  AVM_CONF_WR_CCL        0x02    /* 1 = clear counter low nibble    */
  107 #define  AVM_CONF_WR_CCH        0x04    /* 1 = clear counter high nibble   */
  108 #define  AVM_CONF_WR_IRQEN      0x08    /* 1 = enable IRQ                  */
  109 #define  AVM_CONF_WR_TEST       0x10    /* test bit                        */
  110                                         /* config register read            */
  111 #define  AVM_CONF_RD_IIRQ       0x01    /* 0 = ISAC IRQ active             */
  112 #define  AVM_CONF_RD_HIRQ       0x02    /* 0 = HSCX IRQ active             */
  113 #define  AVM_CONF_RD_CIRQ       0x04    /* 0 = counter IRQ active          */
  114 #define  AVM_CONF_RD_ZER1       0x08    /* unused, always read 0           */
  115 #define  AVM_CONF_RD_TEST       0x10    /* test bit read back              */
  116 #define  AVM_CONF_RD_ZER2       0x20    /* unused, always read 0           */
  117 
  118 /*---------------------------------------------------------------------------*
  119  *      AVM read fifo routines
  120  *---------------------------------------------------------------------------*/
  121 #ifdef __FreeBSD__
  122 static void             
  123 avma1_read_fifo(void *buf, const void *base, size_t len)
  124 {
  125         insb((int)base - 0x3e0, (u_char *)buf, (u_int)len);
  126 }
  127 #else
  128 static void
  129 avma1_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
  130 {
  131         bus_space_tag_t t = sc->sc_maps[what+4].t;
  132         bus_space_handle_t h = sc->sc_maps[what+4].h;
  133         bus_space_read_multi_1(t, h, 0, buf, size);
  134 }
  135 #endif
  136 
  137 /*---------------------------------------------------------------------------*
  138  *      AVM write fifo routines
  139  *---------------------------------------------------------------------------*/
  140 #ifdef __FreeBSD__
  141 static void
  142 avma1_write_fifo(void *base, const void *buf, size_t len)
  143 {
  144         outsb((int)base - 0x3e0, (u_char *)buf, (u_int)len);
  145 }
  146 #else
  147 static void
  148 avma1_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
  149 {
  150         bus_space_tag_t t = sc->sc_maps[what+4].t;
  151         bus_space_handle_t h = sc->sc_maps[what+4].h;
  152         bus_space_write_multi_1(t, h, 0, (u_int8_t*)buf, size);
  153 }
  154 #endif
  155 
  156 /*---------------------------------------------------------------------------*
  157  *      AVM write register routines
  158  *---------------------------------------------------------------------------*/
  159 #ifdef __FreeBSD__
  160 static void
  161 avma1_write_reg(u_char *base, u_int offset, u_int v)
  162 {
  163         outb((int)base + offset, (u_char)v);
  164 }
  165 #else
  166 static void
  167 avma1_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
  168 {
  169         bus_space_tag_t t = sc->sc_maps[what+1].t;
  170         bus_space_handle_t h = sc->sc_maps[what+1].h;
  171         bus_space_write_1(t, h, offs, data);
  172 }
  173 #endif
  174 
  175 /*---------------------------------------------------------------------------*
  176  *      AVM read register routines
  177  *---------------------------------------------------------------------------*/
  178 #ifdef __FreeBSD__
  179 static u_char
  180 avma1_read_reg(u_char *base, u_int offset)
  181 {
  182         return (inb((int)base + offset));
  183 }
  184 #else
  185 static u_int8_t
  186 avma1_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
  187 {
  188         bus_space_tag_t t = sc->sc_maps[what+1].t;
  189         bus_space_handle_t h = sc->sc_maps[what+1].h;
  190         return bus_space_read_1(t, h, offs);
  191 }
  192 #endif
  193 
  194 /*---------------------------------------------------------------------------*
  195  *      isic_probe_avma1 - probe for AVM A1 and compatibles
  196  *---------------------------------------------------------------------------*/
  197 #ifdef __FreeBSD__
  198 int
  199 isic_probe_avma1(struct isa_device *dev)
  200 {
  201         struct isic_softc *sc = &l1_sc[dev->id_unit];
  202         u_char savebyte;
  203         u_char byte;
  204         
  205         /* check max unit range */
  206         
  207         if(dev->id_unit >= ISIC_MAXUNIT)
  208         {
  209                 printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for AVM A1/Fritz!\n",
  210                                 dev->id_unit, dev->id_unit);
  211                 return(0);      
  212         }       
  213         sc->sc_unit = dev->id_unit;
  214 
  215         /* check IRQ validity */
  216         
  217         switch(ffs(dev->id_irq)-1)
  218         {
  219                 case 3:
  220                 case 4:
  221                 case 5:
  222                 case 6:
  223                 case 7:
  224                 case 8:
  225                 case 10:
  226                 case 11:
  227                 case 12:
  228                 case 13:
  229                 case 14:
  230                 case 15:
  231                         break;
  232                         
  233                 default:
  234                         printf("isic%d: Error, invalid IRQ [%d] specified for AVM A1/Fritz!\n",
  235                                 dev->id_unit, ffs(dev->id_irq)-1);
  236                         return(0);
  237                         break;
  238         }               
  239         sc->sc_irq = dev->id_irq;
  240 
  241         /* check if memory addr specified */
  242 
  243         if(dev->id_maddr)
  244         {
  245                 printf("isic%d: Error, mem addr 0x%lx specified for AVM A1/Fritz!\n",
  246                         dev->id_unit, (u_long)dev->id_maddr);
  247                 return(0);
  248         }
  249                 
  250         dev->id_msize = 0;
  251         
  252         /* check if we got an iobase */
  253 
  254         switch(dev->id_iobase)
  255         {
  256                 case 0x200:
  257                 case 0x240:
  258                 case 0x300:
  259                 case 0x340:             
  260                         break;
  261                         
  262                 default:
  263                         printf("isic%d: Error, invalid iobase 0x%x specified for AVM A1/Fritz!\n",
  264                                 dev->id_unit, dev->id_iobase);
  265                         return(0);
  266                         break;
  267         }
  268         sc->sc_port = dev->id_iobase;
  269 
  270         sc->clearirq = NULL;
  271         sc->readreg = avma1_read_reg;
  272         sc->writereg = avma1_write_reg;
  273 
  274         sc->readfifo = avma1_read_fifo;
  275         sc->writefifo = avma1_write_fifo;
  276 
  277         /* setup card type */
  278 
  279         sc->sc_cardtyp = CARD_TYPEP_AVMA1;
  280 
  281         /* setup IOM bus type */
  282         
  283         sc->sc_bustyp = BUS_TYPE_IOM2;
  284 
  285         sc->sc_ipac = 0;
  286         sc->sc_bfifolen = HSCX_FIFO_LEN;
  287 
  288         /* setup ISAC and HSCX base addr */
  289         
  290         ISAC_BASE = (caddr_t)dev->id_iobase + 0x1400 - 0x20;
  291 
  292         HSCX_A_BASE = (caddr_t)dev->id_iobase + 0x400 - 0x20;
  293         HSCX_B_BASE = (caddr_t)dev->id_iobase + 0xc00 - 0x20;
  294 
  295         /* 
  296          * Read HSCX A/B VSTR.
  297          * Expected value for AVM A1 is 0x04 or 0x05 and for the
  298          * AVM Fritz!Card is 0x05 in the least significant bits.
  299          */
  300 
  301         if( (((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) &&
  302              ((HSCX_READ(0, H_VSTR) & 0xf) != 0x4))     ||
  303             (((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) &&
  304              ((HSCX_READ(1, H_VSTR) & 0xf) != 0x4)) )  
  305         {
  306                 printf("isic%d: HSCX VSTR test failed for AVM A1/Fritz\n",
  307                         dev->id_unit);
  308                 printf("isic%d: HSC0: VSTR: %#x\n",
  309                         dev->id_unit, HSCX_READ(0, H_VSTR));
  310                 printf("isic%d: HSC1: VSTR: %#x\n",
  311                         dev->id_unit, HSCX_READ(1, H_VSTR));
  312                 return (0);
  313         }                   
  314 
  315         /* AVM A1 or Fritz! control register bits:      */
  316         /*        read                write             */
  317         /* 0x01  hscx irq*           RESET              */
  318         /* 0x02  isac irq*           clear counter1     */
  319         /* 0x04  counter irq*        clear counter2     */
  320         /* 0x08  always 0            irq enable         */
  321         /* 0x10  read test bit       set test bit       */
  322         /* 0x20  always 0            unused             */
  323 
  324         /*
  325          * XXX the following test may be destructive, to prevent the
  326          * worst case, we save the byte first, and in case the test
  327          * fails, we write back the saved byte .....
  328          */
  329 
  330         savebyte = inb(dev->id_iobase + AVM_CONF_REG);
  331         
  332         /* write low to test bit */
  333 
  334         outb(dev->id_iobase + AVM_CONF_REG, 0x00);
  335         
  336         /* test bit and next higher and lower bit must be 0 */
  337 
  338         if((byte = inb(dev->id_iobase + AVM_CONF_REG) & 0x38) != 0x00)
  339         {
  340                 printf("isic%d: Error, probe-1 failed, 0x%02x should be 0x00 for AVM A1/Fritz!\n",
  341                                 dev->id_unit, byte);
  342                 outb(dev->id_iobase + AVM_CONF_REG, savebyte);
  343                 return (0);
  344         }
  345 
  346         /* write high to test bit */
  347 
  348         outb(dev->id_iobase + AVM_CONF_REG, 0x10);
  349         
  350         /* test bit must be high, next higher and lower bit must be 0 */
  351 
  352         if((byte = inb(dev->id_iobase + AVM_CONF_REG) & 0x38) != 0x10)
  353         {
  354                 printf("isic%d: Error, probe-2 failed, 0x%02x should be 0x10 for AVM A1/Fritz!\n",
  355                                 dev->id_unit, byte);
  356                 outb(dev->id_iobase + AVM_CONF_REG, savebyte);
  357                 return (0);
  358         }
  359 
  360         return (1);
  361 }
  362 
  363 #else
  364 
  365 int
  366 isic_probe_avma1(struct isic_attach_args *ia)
  367 {
  368         u_int8_t savebyte, v1, v2;
  369 
  370         /* 
  371          * Read HSCX A/B VSTR.
  372          * Expected value for AVM A1 is 0x04 or 0x05 and for the
  373          * AVM Fritz!Card is 0x05 in the least significant bits.
  374          */
  375 
  376         v1 = bus_space_read_1(ia->ia_maps[ISIC_WHAT_HSCXA+1].t, ia->ia_maps[ISIC_WHAT_HSCXA+1].h, H_VSTR) & 0x0f;
  377         v2 = bus_space_read_1(ia->ia_maps[ISIC_WHAT_HSCXB+1].t, ia->ia_maps[ISIC_WHAT_HSCXB+1].h, H_VSTR) & 0x0f;
  378         if (v1 != v2 || (v1 != 0x05 && v1 != 0x04))
  379                 return 0;
  380 
  381         /* AVM A1 or Fritz! control register bits:      */
  382         /*        read                write             */
  383         /* 0x01  hscx irq*           RESET              */
  384         /* 0x02  isac irq*           clear counter1     */
  385         /* 0x04  counter irq*        clear counter2     */
  386         /* 0x08  always 0            irq enable         */
  387         /* 0x10  read test bit       set test bit       */
  388         /* 0x20  always 0            unused             */
  389 
  390         /*
  391          * XXX the following test may be destructive, to prevent the
  392          * worst case, we save the byte first, and in case the test
  393          * fails, we write back the saved byte .....
  394          */
  395 
  396         savebyte = bus_space_read_1(ia->ia_maps[0].t, ia->ia_maps[0].h, 0);
  397         
  398         /* write low to test bit */
  399 
  400         bus_space_write_1(ia->ia_maps[0].t, ia->ia_maps[0].h, 0, 0);
  401         
  402         /* test bit and next higher and lower bit must be 0 */
  403 
  404         if((bus_space_read_1(ia->ia_maps[0].t, ia->ia_maps[0].h, 0) & 0x38) != 0x00)
  405         {
  406                 bus_space_write_1(ia->ia_maps[0].t, ia->ia_maps[0].h, 0, savebyte);
  407                 return 0;
  408         }
  409 
  410         /* write high to test bit */
  411 
  412         bus_space_write_1(ia->ia_maps[0].t, ia->ia_maps[0].h, 0, 0x10);
  413         
  414         /* test bit must be high, next higher and lower bit must be 0 */
  415 
  416         if((bus_space_read_1(ia->ia_maps[0].t, ia->ia_maps[0].h, 0) & 0x38) != 0x10)
  417         {
  418                 bus_space_write_1(ia->ia_maps[0].t, ia->ia_maps[0].h, 0, savebyte);
  419                 return 0;
  420         }
  421 
  422         return (1);
  423 }
  424 #endif
  425 
  426 /*---------------------------------------------------------------------------*
  427  *      isic_attach_avma1 - attach AVM A1 and compatibles
  428  *---------------------------------------------------------------------------*/
  429 #ifdef __FreeBSD__
  430 int
  431 isic_attach_avma1(struct isa_device *dev)
  432 {
  433         struct isic_softc *sc = &l1_sc[dev->id_unit];
  434 
  435         /* reset the HSCX and ISAC chips */
  436         
  437         outb(dev->id_iobase + AVM_CONF_REG, 0x00);
  438         DELAY(SEC_DELAY / 10);
  439 
  440         outb(dev->id_iobase + AVM_CONF_REG, AVM_CONF_WR_RESET);
  441         DELAY(SEC_DELAY / 10);
  442 
  443         outb(dev->id_iobase + AVM_CONF_REG, 0x00);
  444         DELAY(SEC_DELAY / 10);
  445 
  446         /* setup IRQ */
  447 
  448         outb(dev->id_iobase + AVM_CONF_IRQ, (ffs(sc->sc_irq)) - 1);
  449         DELAY(SEC_DELAY / 10);
  450 
  451         /* enable IRQ, disable counter IRQ */
  452 
  453         outb(dev->id_iobase + AVM_CONF_REG, AVM_CONF_WR_IRQEN |
  454                 AVM_CONF_WR_CCH | AVM_CONF_WR_CCL);
  455         DELAY(SEC_DELAY / 10);
  456 
  457         return (1);
  458 }
  459 
  460 #else
  461 
  462 int
  463 isic_attach_avma1(struct isic_softc *sc)
  464 {
  465         bus_space_tag_t t = sc->sc_maps[0].t;
  466         bus_space_handle_t h = sc->sc_maps[0].h;
  467 
  468         sc->clearirq = NULL;
  469         sc->readreg = avma1_read_reg;
  470         sc->writereg = avma1_write_reg;
  471 
  472         sc->readfifo = avma1_read_fifo;
  473         sc->writefifo = avma1_write_fifo;
  474 
  475         /* setup IOM bus type */
  476         
  477         sc->sc_bustyp = BUS_TYPE_IOM2;
  478 
  479         sc->sc_ipac = 0;
  480         sc->sc_bfifolen = HSCX_FIFO_LEN;
  481         
  482         /* reset the HSCX and ISAC chips */
  483         
  484         bus_space_write_1(t, h, 0, 0x00);
  485         DELAY(SEC_DELAY / 10);
  486 
  487         bus_space_write_1(t, h, 0, AVM_CONF_WR_RESET);
  488         DELAY(SEC_DELAY / 10);
  489 
  490         bus_space_write_1(t, h, 0, 0x00);
  491         DELAY(SEC_DELAY / 10);
  492 
  493         /* setup IRQ */
  494 
  495         bus_space_write_1(t, h, 1, sc->sc_irq);
  496         DELAY(SEC_DELAY / 10);
  497 
  498         /* enable IRQ, disable counter IRQ */
  499 
  500         bus_space_write_1(t, h, 0, AVM_CONF_WR_IRQEN |
  501                 AVM_CONF_WR_CCH | AVM_CONF_WR_CCL);
  502         DELAY(SEC_DELAY / 10);
  503 
  504         return (1);
  505 }
  506 #endif
  507 
  508 #endif /* ISICISA_AVM_A1 */

Cache object: 6ad3bd836d2b51ec781382485f25521d


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