root/dev/pcmcia/pcmcia_cis_quirks.c

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

DEFINITIONS

This source file includes following definitions.
  1. pcmcia_check_cis_quirks

    1 /*      $OpenBSD: pcmcia_cis_quirks.c,v 1.8 2005/10/27 16:42:19 deraadt Exp $   */
    2 /*      $NetBSD: pcmcia_cis_quirks.c,v 1.3 1998/12/29 09:00:28 marc Exp $       */
    3 
    4 /*
    5  * Copyright (c) 1998 Marc Horowitz.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   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. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by Marc Horowitz.
   18  * 4. 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 ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/types.h>
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/device.h>
   37 #include <sys/mbuf.h>
   38 
   39 #include <dev/pcmcia/pcmciadevs.h>
   40 #include <dev/pcmcia/pcmciareg.h>
   41 #include <dev/pcmcia/pcmciachip.h>
   42 #include <dev/pcmcia/pcmciavar.h>
   43 
   44 /* There are cards out there whose CIS flat-out lies.  This file
   45    contains struct pcmcia_function chains for those devices. */
   46 
   47 /* these structures are just static templates which are then copied
   48    into "live" allocated structures */
   49 
   50 struct pcmcia_function pcmcia_3cxem556_func0 = {
   51         0,                      /* function number */
   52         PCMCIA_FUNCTION_NETWORK,
   53         0x07,                   /* last cfe number */
   54         0x800,                  /* ccr_base */
   55         0x63,                   /* ccr_mask */
   56 };
   57 
   58 struct pcmcia_config_entry pcmcia_3cxem556_func0_cfe0 = {
   59         0x07,                   /* cfe number */
   60         PCMCIA_CFE_IO8 | PCMCIA_CFE_IO16 | PCMCIA_CFE_IRQLEVEL,
   61         PCMCIA_IFTYPE_IO,
   62         1,                      /* num_iospace */
   63         4,                      /* iomask */
   64         { { 0x0010, 0 } },      /* iospace */
   65         0xffff,                 /* irqmask */
   66         0,                      /* num_memspace */
   67         { },                    /* memspace */
   68         0,                      /* maxtwins */
   69 };
   70 
   71 static struct pcmcia_function pcmcia_3cxem556_func1 = {
   72         1,                      /* function number */
   73         PCMCIA_FUNCTION_SERIAL,
   74         0x27,                   /* last cfe number */
   75         0x900,                  /* ccr_base */
   76         0x63,                   /* ccr_mask */
   77 };
   78 
   79 static struct pcmcia_config_entry pcmcia_3cxem556_func1_cfe0 = {
   80         0x27,                   /* cfe number */
   81         PCMCIA_CFE_IO8 | PCMCIA_CFE_IRQLEVEL,
   82         PCMCIA_IFTYPE_IO,
   83         1,                      /* num_iospace */
   84         3,                      /* iomask */
   85         { { 0x0008, 0 } },      /* iospace */
   86         0xffff,                 /* irqmask */
   87         0,                      /* num_memspace */
   88         { },                    /* memspace */
   89         0,                      /* maxtwins */
   90 };
   91 
   92 struct pcmcia_function pcmcia_megahertz_xjem1144_func0 = {
   93         0,                      /* function number */
   94         PCMCIA_FUNCTION_NETWORK,
   95         0x07,                   /* last cfe number */
   96         0x200,                  /* ccr_base */
   97         0x63,                   /* ccr_mask */
   98 };
   99 
  100 struct pcmcia_config_entry pcmcia_megahertz_xjem1144_func0_cfe0 = {
  101         0x07,                   /* cfe number */
  102         PCMCIA_CFE_IO8 | PCMCIA_CFE_IO16 | PCMCIA_CFE_IRQLEVEL,
  103         PCMCIA_IFTYPE_IO,
  104         1,                      /* num_iospace */
  105         4,                      /* iomask */
  106         { { 0x0010, 0 } },      /* iospace */
  107         0xffff,                 /* irqmask */
  108         0,                      /* num_memspace */
  109         { },                    /* memspace */
  110         0,                      /* maxtwins */
  111 };
  112 
  113 static struct pcmcia_function pcmcia_megahertz_xjem1144_func1 = {
  114         1,                      /* function number */
  115         PCMCIA_FUNCTION_SERIAL,
  116         0x35,                   /* last cfe number */
  117         0x300,                  /* ccr_base */
  118         0x3,                    /* ccr_mask */
  119 };
  120 
  121 static struct pcmcia_config_entry pcmcia_megahertz_xjem1144_func1_cfe0 = {
  122         0x35,                   /* cfe number */
  123         PCMCIA_CFE_IO8 | PCMCIA_CFE_IRQLEVEL, PCMCIA_IFTYPE_IO,
  124         1,                      /* num_iospace */
  125         0,                      /* iomask */
  126         { { 0x0008, 0x2f8 } },  /* iospace */
  127         0xffff,                 /* irqmask */
  128         0,                      /* num_memspace */
  129         { },                    /* memspace */
  130         0,                      /* maxtwins */
  131 };
  132 
  133 static struct pcmcia_function pcmcia_sierra_a555_func1 = {
  134         1,                      /* function number */
  135         PCMCIA_FUNCTION_SERIAL,
  136         0x24,                   /* last cfe number */
  137         0x700,                  /* ccr_base */
  138         0x73,                   /* ccr_mask */
  139 };
  140 
  141 static struct pcmcia_config_entry pcmcia_sierra_a555_func1_cfe0 = {
  142         0x20,                   /* cfe number */
  143         PCMCIA_CFE_IO8 | PCMCIA_CFE_IRQLEVEL, PCMCIA_IFTYPE_IO,
  144         1,                      /* num_iospace */
  145         0,                      /* iomask */
  146         { { 0x0008, 0x3f8 } },  /* iospace */
  147         0x3fbc,                 /* irqmask */
  148         0,                      /* num_memspace */
  149         { },                    /* memspace */
  150         0,                      /* maxtwins */
  151 };
  152 
  153 static struct pcmcia_function pcmcia_sveclancard_func0 = {
  154         0,                      /* function number */
  155         PCMCIA_FUNCTION_NETWORK,
  156         0x1,                    /* last cfe number */
  157         0x100,                  /* ccr_base */
  158         0x1,                    /* ccr_mask */
  159 };
  160 
  161 static struct pcmcia_config_entry pcmcia_sveclancard_func0_cfe0 = {
  162         0x1,                    /* cfe number */
  163         PCMCIA_CFE_MWAIT_REQUIRED | PCMCIA_CFE_RDYBSY_ACTIVE |
  164         PCMCIA_CFE_WP_ACTIVE | PCMCIA_CFE_BVD_ACTIVE | PCMCIA_CFE_IO16,
  165         PCMCIA_IFTYPE_IO,
  166         1,                      /* num_iospace */
  167         5,                      /* iomask */
  168         { { 0x20, 0x300 } },    /* iospace */
  169         0xdeb8,                 /* irqmask */
  170         0,                      /* num_memspace */
  171         { },                    /* memspace */
  172         0,                      /* maxtwins */
  173 };
  174 
  175 static struct pcmcia_cis_quirk pcmcia_cis_quirks[] = {
  176         { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556, PCMCIA_CIS_INVALID,
  177           &pcmcia_3cxem556_func0, &pcmcia_3cxem556_func0_cfe0 },
  178         { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556, PCMCIA_CIS_INVALID,
  179           &pcmcia_3cxem556_func1, &pcmcia_3cxem556_func1_cfe0 },
  180         { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556B,
  181           PCMCIA_CIS_INVALID,
  182           &pcmcia_3cxem556_func0, &pcmcia_3cxem556_func0_cfe0 },
  183         { PCMCIA_VENDOR_3COM, PCMCIA_PRODUCT_3COM_3CXEM556B,
  184           PCMCIA_CIS_INVALID,
  185           &pcmcia_3cxem556_func1, &pcmcia_3cxem556_func1_cfe0 },
  186         { PCMCIA_VENDOR_MEGAHERTZ2, PCMCIA_PRODUCT_MEGAHERTZ2_XJEM1144,
  187           PCMCIA_CIS_INVALID, 
  188           &pcmcia_megahertz_xjem1144_func0,
  189           &pcmcia_megahertz_xjem1144_func0_cfe0 },
  190         { PCMCIA_VENDOR_MEGAHERTZ2, PCMCIA_PRODUCT_MEGAHERTZ2_XJEM1144,
  191           PCMCIA_CIS_INVALID, 
  192           &pcmcia_megahertz_xjem1144_func1,
  193           &pcmcia_megahertz_xjem1144_func1_cfe0 },
  194         { PCMCIA_VENDOR_SIERRA, PCMCIA_PRODUCT_SIERRA_A550,
  195           PCMCIA_CIS_INVALID, 
  196           &pcmcia_sierra_a555_func1, &pcmcia_sierra_a555_func1_cfe0 },
  197         { PCMCIA_VENDOR_SIERRA, PCMCIA_PRODUCT_SIERRA_A555,
  198           PCMCIA_CIS_INVALID, 
  199           &pcmcia_sierra_a555_func1, &pcmcia_sierra_a555_func1_cfe0 },
  200         { PCMCIA_VENDOR_SIERRA, PCMCIA_PRODUCT_SIERRA_A710,
  201           PCMCIA_CIS_INVALID, 
  202           &pcmcia_sierra_a555_func1, &pcmcia_sierra_a555_func1_cfe0 },
  203         { PCMCIA_VENDOR_SIERRA, PCMCIA_PRODUCT_SIERRA_AC710,
  204           PCMCIA_CIS_INVALID, 
  205           &pcmcia_sierra_a555_func1, &pcmcia_sierra_a555_func1_cfe0 },
  206         { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID,
  207           PCMCIA_CIS_SVEC_LANCARD,
  208           &pcmcia_sveclancard_func0, &pcmcia_sveclancard_func0_cfe0 },
  209 };
  210 
  211 void pcmcia_check_cis_quirks(sc)
  212         struct pcmcia_softc *sc;
  213 {
  214         int wiped = 0;
  215         int i, j;
  216         struct pcmcia_function *pf, *pf_next, *pf_last;
  217         struct pcmcia_config_entry *cfe, *cfe_next;
  218 
  219         pf = NULL;
  220         pf_last = NULL;
  221 
  222         
  223         for (i = 0; i < sizeof(pcmcia_cis_quirks)/sizeof(pcmcia_cis_quirks[0]);
  224             i++) {
  225                 if ((sc->card.manufacturer == pcmcia_cis_quirks[i].manufacturer) &&
  226                         (sc->card.product == pcmcia_cis_quirks[i].product) &&
  227                         (((sc->card.manufacturer != PCMCIA_VENDOR_INVALID) &&
  228                           (sc->card.product != PCMCIA_PRODUCT_INVALID)) ||
  229                          ((sc->card.manufacturer == PCMCIA_VENDOR_INVALID) &&
  230                           (sc->card.product == PCMCIA_PRODUCT_INVALID) &&
  231                           sc->card.cis1_info[0] &&
  232                           (strcmp(sc->card.cis1_info[0],
  233                                           pcmcia_cis_quirks[i].cis1_info[0]) == 0) &&
  234                           sc->card.cis1_info[1] &&
  235                           (strcmp(sc->card.cis1_info[1],
  236                                           pcmcia_cis_quirks[i].cis1_info[1]) == 0)))) {
  237                         if (!wiped) {
  238                                 if (pcmcia_verbose) {
  239                                         printf("%s: using CIS quirks for ", sc->dev.dv_xname);
  240                                         for (j = 0; j < 4; j++) {
  241                                                 if (sc->card.cis1_info[j] == NULL)
  242                                                         break;
  243                                                 if (j)
  244                                                         printf(", ");
  245                                                 printf("%s", sc->card.cis1_info[j]);
  246                                         }
  247                                         printf("\n");
  248                                 }
  249 
  250                                 for (pf = SIMPLEQ_FIRST(&sc->card.pf_head); pf != NULL;
  251                                      pf = pf_next) {
  252                                         for (cfe = SIMPLEQ_FIRST(&pf->cfe_head); cfe != NULL;
  253                                              cfe = cfe_next) {
  254                                                 cfe_next = SIMPLEQ_NEXT(cfe, cfe_list);
  255                                                 free(cfe, M_DEVBUF);
  256                                         }
  257                                         pf_next = SIMPLEQ_NEXT(pf, pf_list);
  258                                         free(pf, M_DEVBUF);
  259                                 }
  260 
  261                                 SIMPLEQ_INIT(&sc->card.pf_head);
  262                                 wiped = 1;
  263                         }
  264 
  265                         if (pf_last == pcmcia_cis_quirks[i].pf) {
  266                                 cfe = malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
  267                                 if (cfe == NULL)
  268                                         return;
  269                                 *cfe = *pcmcia_cis_quirks[i].cfe;
  270 
  271                                 SIMPLEQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list);
  272                         } else {
  273                                 pf = malloc(sizeof(*pf), M_DEVBUF, M_NOWAIT);
  274                                 if (pf == NULL)
  275                                         return;
  276                                 *pf = *pcmcia_cis_quirks[i].pf;
  277                                 SIMPLEQ_INIT(&pf->cfe_head);
  278 
  279                                 cfe = malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
  280                                 if (cfe == NULL)
  281                                         return;
  282                                 *cfe = *pcmcia_cis_quirks[i].cfe;
  283 
  284                                 SIMPLEQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list);
  285                                 SIMPLEQ_INSERT_TAIL(&sc->card.pf_head, pf, pf_list);
  286 
  287                                 pf_last = pcmcia_cis_quirks[i].pf;
  288                         }
  289                 }
  290         }
  291 }

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