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/isapnp/isic_isapnp_elsa_qs1i.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) 1997, 1999 Hellmuth Michaelis. All rights reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   23  * SUCH DAMAGE.
   24  *
   25  *---------------------------------------------------------------------------
   26  *
   27  *      isic - I4B Siemens ISDN Chipset Driver for ELSA Quickstep 1000pro ISA
   28  *      =====================================================================
   29  *
   30  *      $Id: isic_isapnp_elsa_qs1i.c,v 1.9 2002/04/15 08:11:00 martin Exp $
   31  *
   32  *      last edit-date: [Fri Jan  5 11:38:29 2001]
   33  *
   34  *---------------------------------------------------------------------------*/
   35 
   36 #include <sys/cdefs.h>
   37 __KERNEL_RCSID(0, "$NetBSD: isic_isapnp_elsa_qs1i.c,v 1.9 2002/04/15 08:11:00 martin Exp $");
   38 
   39 #include "opt_isicpnp.h"
   40 #if defined(ISICPNP_ELSA_QS1ISA) || defined(ISICPNP_ELSA_PCC16)
   41 
   42 #include <sys/param.h>
   43 #include <sys/kernel.h>
   44 #include <sys/systm.h>
   45 #include <sys/mbuf.h>
   46 #include <sys/socket.h>
   47 #include <net/if.h>
   48 
   49 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
   50 #include <sys/callout.h>
   51 #endif
   52 
   53 #ifdef __FreeBSD__
   54 #if __FreeBSD__ >= 3
   55 #include <sys/ioccom.h>
   56 #else
   57 #include <sys/ioctl.h>
   58 #endif
   59 #include <machine/clock.h>
   60 #include <i386/isa/isa_device.h>
   61 #include <i386/isa/pnp.h>
   62 #else
   63 #include <machine/bus.h>
   64 #include <sys/device.h>
   65 #endif
   66 
   67 #ifdef __FreeBSD__
   68 #include <machine/i4b_debug.h>
   69 #include <machine/i4b_ioctl.h>
   70 #else
   71 #include <netisdn/i4b_debug.h>
   72 #include <netisdn/i4b_ioctl.h>
   73 #endif
   74 
   75 #include <netisdn/i4b_global.h>
   76 #include <netisdn/i4b_l2.h>
   77 #include <netisdn/i4b_l1l2.h>
   78 #include <netisdn/i4b_mbuf.h>
   79 
   80 #include <dev/ic/isic_l1.h>
   81 #include <dev/ic/isac.h>
   82 #include <dev/ic/hscx.h>
   83 
   84 #ifdef __FreeBSD__
   85 static void i4b_eq1i_clrirq(void* base);
   86 #else
   87 static void i4b_eq1i_clrirq(struct isic_softc *sc);
   88 void isic_attach_Eqs1pi __P((struct isic_softc *sc));
   89 static void elsa_command_req(struct isic_softc *sc, int command, void *data);
   90 static void elsa_led_handler(void *);
   91 #endif
   92 
   93 /* masks for register encoded in base addr */
   94 
   95 #define ELSA_BASE_MASK          0x0ffff
   96 #define ELSA_OFF_MASK           0xf0000
   97 
   98 /* register id's to be encoded in base addr */
   99 
  100 #define ELSA_IDISAC             0x00000
  101 #define ELSA_IDHSCXA            0x10000
  102 #define ELSA_IDHSCXB            0x20000
  103 
  104 /* offsets from base address */
  105 
  106 #define ELSA_OFF_ISAC           0x00
  107 #define ELSA_OFF_HSCX           0x02
  108 #define ELSA_OFF_OFF            0x03
  109 #define ELSA_OFF_CTRL           0x04
  110 #define ELSA_OFF_CFG            0x05
  111 #define ELSA_OFF_TIMR           0x06
  112 #define ELSA_OFF_IRQ            0x07
  113 
  114 /* control register (write access) */
  115 
  116 #define ELSA_CTRL_LED_YELLOW    0x02
  117 #define ELSA_CTRL_LED_GREEN     0x08
  118 #define ELSA_CTRL_RESET         0x20
  119 #define ELSA_CTRL_TIMEREN       0x80
  120 #define ELSA_CTRL_SECRET        0x50
  121 
  122 /*---------------------------------------------------------------------------*
  123  *      ELSA QuickStep 1000pro/ISA clear IRQ routine
  124  *---------------------------------------------------------------------------*/
  125 #ifdef __FreeBSD__
  126 static void
  127 i4b_eq1i_clrirq(void* base)
  128 {
  129         outb((u_int)base + ELSA_OFF_IRQ, 0);
  130 }
  131 
  132 #else
  133 static void
  134 i4b_eq1i_clrirq(struct isic_softc *sc)
  135 {
  136         bus_space_tag_t t = sc->sc_maps[0].t;
  137         bus_space_handle_t h = sc->sc_maps[0].h;
  138         bus_space_write_1(t, h, ELSA_OFF_IRQ, 0);
  139 }
  140 #endif
  141 
  142 /*---------------------------------------------------------------------------*
  143  *      ELSA QuickStep 1000pro/ISA ISAC get fifo routine
  144  *---------------------------------------------------------------------------*/
  145 #ifdef __FreeBSD__
  146 
  147 static void             
  148 eqs1pi_read_fifo(void *buf, const void *base, size_t len)
  149 {
  150         if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXB)
  151         {
  152                 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, 0x40);
  153                 insb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX), (u_char *)buf, (u_int)len);
  154         }
  155         else if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXA)
  156         {
  157                 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, 0);
  158                 insb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX), (u_char *)buf, (u_int)len);
  159         }               
  160         else /* if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDISAC) */
  161         {
  162                 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, 0);
  163                 insb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ISAC), (u_char *)buf, (u_int)len);
  164         }               
  165 }
  166 
  167 #else
  168 
  169 static void
  170 eqs1pi_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
  171 {
  172         bus_space_tag_t t = sc->sc_maps[0].t;
  173         bus_space_handle_t h = sc->sc_maps[0].h;
  174         switch (what) {
  175                 case ISIC_WHAT_ISAC:
  176                         bus_space_write_1(t, h, ELSA_OFF_OFF, 0);
  177                         bus_space_read_multi_1(t, h, ELSA_OFF_ISAC, buf, size);
  178                         break;
  179                 case ISIC_WHAT_HSCXA:
  180                         bus_space_write_1(t, h, ELSA_OFF_OFF, 0);
  181                         bus_space_read_multi_1(t, h, ELSA_OFF_HSCX, buf, size);
  182                         break;
  183                 case ISIC_WHAT_HSCXB:
  184                         bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40);
  185                         bus_space_read_multi_1(t, h, ELSA_OFF_HSCX, buf, size);
  186                         break;
  187         }
  188 }
  189 
  190 #endif
  191 
  192 /*---------------------------------------------------------------------------*
  193  *      ELSA QuickStep 1000pro/ISA ISAC put fifo routine
  194  *---------------------------------------------------------------------------*/
  195 #ifdef __FreeBSD__
  196 
  197 static void
  198 eqs1pi_write_fifo(void *base, const void *buf, size_t len)
  199 {
  200         if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXB)
  201         {
  202                 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, 0x40);
  203                 outsb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX), (u_char *)buf, (u_int)len);
  204         }
  205         else if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXA)
  206         {
  207                 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, 0);
  208                 outsb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX), (u_char *)buf, (u_int)len);
  209         }               
  210         else /* if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDISAC) */
  211         {
  212                 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, 0);
  213                 outsb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ISAC), (u_char *)buf, (u_int)len);
  214         }
  215 }
  216 
  217 #else
  218 
  219 static void
  220 eqs1pi_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
  221 {
  222         bus_space_tag_t t = sc->sc_maps[0].t;
  223         bus_space_handle_t h = sc->sc_maps[0].h;
  224         switch (what) {
  225                 case ISIC_WHAT_ISAC:
  226                         bus_space_write_1(t, h, ELSA_OFF_OFF, 0);
  227                         bus_space_write_multi_1(t, h, ELSA_OFF_ISAC, (u_int8_t*)buf, size);
  228                         break;
  229                 case ISIC_WHAT_HSCXA:
  230                         bus_space_write_1(t, h, ELSA_OFF_OFF, 0);
  231                         bus_space_write_multi_1(t, h, ELSA_OFF_HSCX, (u_int8_t*)buf, size);
  232                         break;
  233                 case ISIC_WHAT_HSCXB:
  234                         bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40);
  235                         bus_space_write_multi_1(t, h, ELSA_OFF_HSCX, (u_int8_t*)buf, size);
  236                         break;
  237         }
  238 }
  239 #endif
  240 
  241 /*---------------------------------------------------------------------------*
  242  *      ELSA QuickStep 1000pro/ISA ISAC put register routine
  243  *---------------------------------------------------------------------------*/
  244 #ifdef __FreeBSD__
  245 
  246 static void
  247 eqs1pi_write_reg(u_char *base, u_int offset, u_int v)
  248 {
  249         if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXB)
  250         {
  251                 outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, (u_char)(offset+0x40));
  252                 outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX, (u_char)v);
  253         }               
  254         else if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXA)
  255         {
  256                 outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, (u_char)offset);
  257                 outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX, (u_char)v);
  258         }               
  259         else /* if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDISAC) */
  260         {
  261                 outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, (u_char)offset);
  262                 outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ISAC, (u_char)v);
  263         }               
  264 }
  265 
  266 #else
  267 
  268 static void
  269 eqs1pi_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
  270 {
  271         bus_space_tag_t t = sc->sc_maps[0].t;
  272         bus_space_handle_t h = sc->sc_maps[0].h;
  273         switch (what) {
  274                 case ISIC_WHAT_ISAC:
  275                         bus_space_write_1(t, h, ELSA_OFF_OFF, offs);
  276                         bus_space_write_1(t, h, ELSA_OFF_ISAC, data);
  277                         break;
  278                 case ISIC_WHAT_HSCXA:
  279                         bus_space_write_1(t, h, ELSA_OFF_OFF, offs);
  280                         bus_space_write_1(t, h, ELSA_OFF_HSCX, data);
  281                         break;
  282                 case ISIC_WHAT_HSCXB:
  283                         bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40+offs);
  284                         bus_space_write_1(t, h, ELSA_OFF_HSCX, data);
  285                         break;
  286         }
  287 }
  288 #endif
  289 
  290 /*---------------------------------------------------------------------------*
  291  *      ELSA QuickStep 1000pro/ISA ISAC get register routine
  292  *---------------------------------------------------------------------------*/
  293 #ifdef __FreeBSD__
  294 
  295 static u_char
  296 eqs1pi_read_reg(u_char *base, u_int offset)
  297 {
  298         if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXB)
  299         {
  300                 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, (u_char)(offset+0x40));
  301                 return(inb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX));
  302         }
  303         else if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXA)
  304         {
  305                 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, (u_char)offset);
  306                 return(inb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX));
  307         }               
  308         else /* if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDISAC) */
  309         {
  310                 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, (u_char)offset);
  311                 return(inb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ISAC));
  312         }               
  313 }
  314 
  315 #else
  316 
  317 static u_int8_t
  318 eqs1pi_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
  319 {
  320         bus_space_tag_t t = sc->sc_maps[0].t;
  321         bus_space_handle_t h = sc->sc_maps[0].h;
  322         switch (what) {
  323                 case ISIC_WHAT_ISAC:
  324                         bus_space_write_1(t, h, ELSA_OFF_OFF, offs);
  325                         return bus_space_read_1(t, h, ELSA_OFF_ISAC);
  326                 case ISIC_WHAT_HSCXA:
  327                         bus_space_write_1(t, h, ELSA_OFF_OFF, offs);
  328                         return bus_space_read_1(t, h, ELSA_OFF_HSCX);
  329                 case ISIC_WHAT_HSCXB:
  330                         bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40+offs);
  331                         return bus_space_read_1(t, h, ELSA_OFF_HSCX);
  332         }
  333         return 0;
  334 }
  335 
  336 #endif
  337 
  338 #ifdef __FreeBSD__
  339 
  340 /*---------------------------------------------------------------------------*
  341  *      isic_probe_Eqs1pi - probe for ELSA QuickStep 1000pro/ISA and compatibles
  342  *---------------------------------------------------------------------------*/
  343 int
  344 isic_probe_Eqs1pi(struct isa_device *dev, unsigned int iobase2)
  345 {
  346         struct isic_softc *sc = &l1_sc[dev->id_unit];
  347         
  348         /* check max unit range */
  349         
  350         if(dev->id_unit >= ISIC_MAXUNIT)
  351         {
  352                 printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for ELSA QuickStep 1000pro/ISA!\n",
  353                                 dev->id_unit, dev->id_unit);
  354                 return(0);      
  355         }       
  356         sc->sc_unit = dev->id_unit;
  357 
  358         /* check IRQ validity */
  359 
  360         switch(ffs(dev->id_irq) - 1)
  361         {
  362                 case 3:
  363                 case 4:         
  364                 case 5:
  365                 case 7:
  366                 case 10:
  367                 case 11:
  368                 case 12:
  369                 case 15:                
  370                         break;
  371                         
  372                 default:
  373                         printf("isic%d: Error, invalid IRQ [%d] specified for ELSA QuickStep 1000pro/ISA!\n",
  374                                 dev->id_unit, ffs(dev->id_irq)-1);
  375                         return(0);
  376                         break;
  377         }
  378         sc->sc_irq = dev->id_irq;
  379 
  380         /* check if memory addr specified */
  381 
  382         if(dev->id_maddr)
  383         {
  384                 printf("isic%d: Error, mem addr 0x%lx specified for ELSA QuickStep 1000pro/ISA!\n",
  385                         dev->id_unit, (u_long)dev->id_maddr);
  386                 return(0);
  387         }
  388         dev->id_msize = 0;
  389         
  390         /* check if we got an iobase */
  391 
  392         if(!((dev->id_iobase >= 0x160) && (dev->id_iobase <= 0x360)))
  393         {
  394                 printf("isic%d: Error, invalid iobase 0x%x specified for ELSA QuickStep 1000pro/ISA!\n",
  395                         dev->id_unit, dev->id_iobase);
  396                 return(0);
  397         }
  398         sc->sc_port = dev->id_iobase;
  399 
  400         /* setup access routines */
  401 
  402         sc->clearirq = i4b_eq1i_clrirq;
  403         sc->readreg = eqs1pi_read_reg;
  404         sc->writereg = eqs1pi_write_reg;
  405 
  406         sc->readfifo = eqs1pi_read_fifo;
  407         sc->writefifo = eqs1pi_write_fifo;
  408 
  409         /* setup card type */
  410         
  411         sc->sc_cardtyp = CARD_TYPEP_ELSAQS1ISA;
  412 
  413         /* setup IOM bus type */
  414         
  415         sc->sc_bustyp = BUS_TYPE_IOM2;
  416 
  417         sc->sc_ipac = 0;
  418         sc->sc_bfifolen = HSCX_FIFO_LEN;        
  419 
  420         /* setup ISAC and HSCX base addr */
  421         
  422         ISAC_BASE   = (caddr_t) ((u_int)dev->id_iobase | ELSA_IDISAC);
  423         HSCX_A_BASE = (caddr_t) ((u_int)dev->id_iobase | ELSA_IDHSCXA);
  424         HSCX_B_BASE = (caddr_t) ((u_int)dev->id_iobase | ELSA_IDHSCXB);
  425 
  426         /* 
  427          * Read HSCX A/B VSTR.  Expected value for the ELSA QuickStep 1000pro
  428          * ISA card is 0x05 ( = version 2.1 ) in the least significant bits.
  429          */
  430 
  431         if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) ||
  432             ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
  433         {
  434                 printf("isic%d: HSCX VSTR test failed for ELSA QuickStep 1000pro/ISA\n",
  435                         dev->id_unit);
  436                 printf("isic%d: HSC0: VSTR: %#x\n",
  437                         dev->id_unit, HSCX_READ(0, H_VSTR));
  438                 printf("isic%d: HSC1: VSTR: %#x\n",
  439                         dev->id_unit, HSCX_READ(1, H_VSTR));
  440                 return (0);
  441         }                   
  442 
  443         return (1);
  444 }
  445 
  446 /*---------------------------------------------------------------------------*
  447  *      isic_attach_s0163P - attach ELSA QuickStep 1000pro/ISA
  448  *---------------------------------------------------------------------------*/
  449 int
  450 isic_attach_Eqs1pi(struct isa_device *dev, unsigned int iobase2)
  451 {
  452         u_char byte = ELSA_CTRL_SECRET;
  453 
  454         byte &= ~ELSA_CTRL_RESET;
  455         outb(dev->id_iobase + ELSA_OFF_CTRL, byte);
  456         DELAY(20);
  457         byte |= ELSA_CTRL_RESET;
  458         outb(dev->id_iobase + ELSA_OFF_CTRL, byte);
  459 
  460         DELAY(20);
  461         outb(dev->id_iobase + ELSA_OFF_IRQ, 0xff);
  462 
  463         return(1);
  464 }
  465 
  466 #else /* !__FreeBSD__ */
  467 
  468 static void
  469 elsa_command_req(struct isic_softc *sc, int command, void *data)
  470 {
  471         int v, s, blink;
  472         u_int8_t led_val;
  473 
  474         switch (command) {
  475         case CMR_DOPEN:
  476                 s = splnet();
  477 
  478                 v = ELSA_CTRL_SECRET & ~ELSA_CTRL_RESET;
  479                 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h,
  480                     ELSA_OFF_CTRL, v);
  481                 delay(20);
  482                 v |= ELSA_CTRL_RESET;
  483                 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h,
  484                     ELSA_OFF_CTRL, v);
  485                 delay(20);
  486                 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h,
  487                     ELSA_OFF_IRQ, 0xff);
  488 
  489                 splx(s);
  490                 break;
  491 
  492         case CMR_DCLOSE:
  493                 s = splnet();
  494                 callout_stop(&sc->sc_driver_callout);
  495                 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h,
  496                     ELSA_OFF_IRQ, 0);
  497                 v = ELSA_CTRL_SECRET & ~ELSA_CTRL_RESET;
  498                 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h,
  499                     ELSA_OFF_CTRL, v);
  500                 delay(20);
  501                 v |= ELSA_CTRL_RESET;
  502                 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h,
  503                     ELSA_OFF_CTRL, v);
  504                 splx(s);
  505                 break;
  506 
  507         case CMR_SETLEDS:
  508                 /* the magic value and keep reset off */
  509                 led_val = ELSA_CTRL_SECRET|ELSA_CTRL_RESET;
  510 
  511                 /* now see what LEDs we want to add */
  512                 v = (int)data;
  513                 if (v & CMRLEDS_TEI)
  514                         led_val |= ELSA_CTRL_LED_GREEN;
  515                 blink = 0;
  516                 if (v & (CMRLEDS_B0|CMRLEDS_B1)) {
  517                         led_val |= ELSA_CTRL_LED_YELLOW;
  518                         if ((v & (CMRLEDS_B0|CMRLEDS_B1)) == (CMRLEDS_B0|CMRLEDS_B1))
  519                                 blink = hz/4;
  520                         else
  521                                 blink = hz;
  522                         sc->sc_driver_specific = v;
  523                 }
  524 
  525                 s = splnet();
  526                 bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h,
  527                     ELSA_OFF_CTRL, led_val);
  528                 callout_stop(&sc->sc_driver_callout);
  529                 if (blink)
  530                         callout_reset(&sc->sc_driver_callout, blink,
  531                             elsa_led_handler, sc);
  532                 splx(s);
  533 
  534                 break;
  535 
  536         default:
  537                 return;
  538         }
  539 }
  540 
  541 static void
  542 elsa_led_handler(void *token)
  543 {
  544         struct isic_softc *sc = token;
  545         int v, s, blink, off = 0;
  546         u_int8_t led_val = ELSA_CTRL_SECRET|ELSA_CTRL_RESET;
  547 
  548         s = splnet();
  549         v = sc->sc_driver_specific;
  550         if (v > 0) {
  551                 /* turn blinking LED off */
  552                 v = -sc->sc_driver_specific;
  553                 sc->sc_driver_specific = v;
  554                 off = 1;
  555         } else {
  556                 sc->sc_driver_specific = -v;
  557         }
  558         if (v & CMRLEDS_TEI)
  559                 led_val |= ELSA_CTRL_LED_GREEN;
  560         blink = 0;
  561         if (off == 0) {
  562                 if (v & (CMRLEDS_B0|CMRLEDS_B1))
  563                         led_val |= ELSA_CTRL_LED_YELLOW;
  564         }
  565         if ((v & (CMRLEDS_B0|CMRLEDS_B1)) == (CMRLEDS_B0|CMRLEDS_B1))
  566                 blink = hz/4;
  567         else
  568                 blink = hz;
  569 
  570         bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h,
  571             ELSA_OFF_CTRL, led_val);
  572         if (blink)
  573                 callout_reset(&sc->sc_driver_callout, blink,
  574                     elsa_led_handler, sc);
  575         splx(s);
  576 }
  577 
  578 void
  579 isic_attach_Eqs1pi(struct isic_softc *sc)
  580 {
  581         /* setup access routines */
  582 
  583         sc->clearirq = i4b_eq1i_clrirq;
  584         sc->readreg = eqs1pi_read_reg;
  585         sc->writereg = eqs1pi_write_reg;
  586 
  587         sc->readfifo = eqs1pi_read_fifo;
  588         sc->writefifo = eqs1pi_write_fifo;
  589 
  590         sc->drv_command = elsa_command_req;
  591 
  592         /* setup card type */
  593         
  594         sc->sc_cardtyp = CARD_TYPEP_ELSAQS1ISA;
  595 
  596         /* setup IOM bus type */
  597         
  598         sc->sc_bustyp = BUS_TYPE_IOM2;
  599 
  600         sc->sc_ipac = 0;
  601         sc->sc_bfifolen = HSCX_FIFO_LEN;
  602 
  603         callout_init(&sc->sc_driver_callout);
  604         sc->sc_driver_specific = 0;
  605 }
  606 
  607 #endif
  608 
  609 #endif /* ISICPNP_ELSA_QS1ISA or ISICPNP_ELSA_PCC16 */

Cache object: 7d12e125931a5e022019b68e59c3e875


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