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/netif/ndis/if_ndis_pccard.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) 2003
    3  *      Bill Paul <wpaul@windriver.com>.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by Bill Paul.
   16  * 4. Neither the name of the author nor the names of any co-contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
   24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   30  * THE POSSIBILITY OF SUCH DAMAGE.
   31  *
   32  * $FreeBSD: src/sys/dev/if_ndis/if_ndis_pccard.c,v 1.21 2012/11/17 01:51:54 svnexp Exp $
   33  */
   34 
   35 #include "use_usb4bsd.h"
   36 
   37 #include <sys/ctype.h>
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/kernel.h>
   41 #include <sys/module.h>
   42 #include <sys/socket.h>
   43 #include <sys/queue.h>
   44 #include <sys/sysctl.h>
   45 #include <sys/lock.h>
   46 
   47 #include <net/if.h>
   48 #include <net/if_arp.h>
   49 #include <net/if_media.h>
   50 
   51 #include <sys/bus.h>
   52 #include <sys/rman.h>
   53 
   54 #include <netproto/802_11/ieee80211_var.h>
   55 
   56 #if NUSB4BSD > 0
   57 #include <bus/u4b/usb.h>
   58 #include <bus/u4b/usbdi.h>
   59 #else
   60 #include <bus/usb/usb.h>
   61 #include <bus/usb/usbdi.h>
   62 #endif
   63 
   64 #include <emulation/ndis/pe_var.h>
   65 #include <emulation/ndis/cfg_var.h>
   66 #include <emulation/ndis/resource_var.h>
   67 #include <emulation/ndis/ntoskrnl_var.h>
   68 #include <emulation/ndis/ndis_var.h>
   69 #include <dev/netif/ndis/if_ndisvar.h>
   70 
   71 #include <bus/pccard/pccardvar.h>
   72 #include "card_if.h"
   73 
   74 MODULE_DEPEND(if_ndis, pccard, 1, 1, 1);
   75 
   76 static int ndis_probe_pccard    (device_t);
   77 static int ndis_attach_pccard   (device_t);
   78 static int ndis_detach_pccard   (device_t);
   79 static struct resource_list *ndis_get_resource_list
   80                                 (device_t, device_t);
   81 static int ndis_devcompare      (interface_type,
   82                                  struct ndis_pccard_type *, device_t);
   83 extern int ndisdrv_modevent     (module_t, int, void *);
   84 extern int ndis_attach          (device_t);
   85 extern int ndis_shutdown        (device_t);
   86 extern int ndis_detach          (device_t);
   87 extern int ndis_suspend         (device_t);
   88 extern int ndis_resume          (device_t);
   89 
   90 extern unsigned char drv_data[];
   91 
   92 static device_method_t ndis_methods[] = {
   93         /* Device interface */
   94         DEVMETHOD(device_probe,         ndis_probe_pccard),
   95         DEVMETHOD(device_attach,        ndis_attach_pccard),
   96         DEVMETHOD(device_detach,        ndis_detach_pccard),
   97         DEVMETHOD(device_shutdown,      ndis_shutdown),
   98         DEVMETHOD(device_suspend,       ndis_suspend),
   99         DEVMETHOD(device_resume,        ndis_resume),
  100 
  101         /* Bus interface. */
  102 
  103         /*
  104          * This is an awful kludge, but we need it becase pccard
  105          * does not implement a bus_get_resource_list() method.
  106          */
  107 
  108         DEVMETHOD(bus_get_resource_list, ndis_get_resource_list),
  109 
  110         DEVMETHOD_END
  111 };
  112 
  113 static driver_t ndis_driver = {
  114         "ndis",
  115         ndis_methods,
  116         sizeof(struct ndis_softc)
  117 };
  118 
  119 static devclass_t ndis_devclass;
  120 
  121 DRIVER_MODULE(if_ndis, pccard, ndis_driver, ndis_devclass, ndisdrv_modevent, NULL);
  122 
  123 static int
  124 ndis_devcompare(interface_type bustype, struct ndis_pccard_type *t,
  125     device_t dev)
  126 {
  127         const char              *prodstr, *vendstr;
  128 
  129         if (bustype != PCMCIABus)
  130                 return(FALSE);
  131 
  132         prodstr = pccard_get_product_str(dev);
  133         vendstr = pccard_get_vendor_str(dev);
  134 
  135         while(t->ndis_name != NULL) {
  136                 if (strcasecmp(vendstr, t->ndis_vid) == 0 &&
  137                     strcasecmp(prodstr, t->ndis_did) == 0) {
  138                         device_set_desc(dev, t->ndis_name);
  139                         return(TRUE);
  140                 }
  141                 t++;
  142         }
  143 
  144         return(FALSE);
  145 }
  146 
  147 /*
  148  * Probe for an NDIS device. Check the PCI vendor and device
  149  * IDs against our list and return a device name if we find a match.
  150  */
  151 static int
  152 ndis_probe_pccard(device_t dev)
  153 {
  154         driver_object           *drv;
  155         struct drvdb_ent        *db;
  156 
  157         drv = windrv_lookup(0, "PCCARD Bus");
  158         if (drv == NULL)
  159                 return(ENXIO);
  160 
  161         db = windrv_match((matchfuncptr)ndis_devcompare, dev);
  162 
  163         if (db != NULL) {
  164                 /* Create PDO for this device instance */
  165                 windrv_create_pdo(drv, dev);
  166                 return(0);
  167         }
  168 
  169         return(ENXIO);
  170 }
  171 
  172 /*
  173  * Attach the interface. Allocate softc structures, do ifmedia
  174  * setup and ethernet/BPF attach.
  175  */
  176 static int
  177 ndis_attach_pccard(device_t dev)
  178 {
  179         struct ndis_softc       *sc;
  180         int                     error = 0, rid;
  181         struct ndis_pccard_type *t;
  182         int                     devidx = 0;
  183         const char              *prodstr, *vendstr;
  184         struct drvdb_ent        *db;
  185 
  186         wlan_serialize_enter();
  187         sc = device_get_softc(dev);
  188         sc->ndis_dev = dev;
  189 
  190         db = windrv_match((matchfuncptr)ndis_devcompare, dev);
  191         if (db == NULL) {
  192                 wlan_serialize_exit();
  193                 return (ENXIO);
  194         }
  195         sc->ndis_dobj = db->windrv_object;
  196         sc->ndis_regvals = db->windrv_regvals;
  197         resource_list_init(&sc->ndis_rl);
  198 
  199         sc->ndis_io_rid = 0;
  200         sc->ndis_res_io = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
  201             &sc->ndis_io_rid, RF_ACTIVE);
  202         if (sc->ndis_res_io == NULL) {
  203                 device_printf(dev,
  204                     "couldn't map iospace\n");
  205                 error = ENXIO;
  206                 goto fail;
  207         }
  208         sc->ndis_rescnt++;
  209         resource_list_add(&sc->ndis_rl, SYS_RES_IOPORT, sc->ndis_io_rid,
  210             rman_get_start(sc->ndis_res_io), rman_get_end(sc->ndis_res_io),
  211             rman_get_size(sc->ndis_res_io), -1);
  212 
  213         rid = 0;
  214         sc->ndis_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
  215             RF_SHAREABLE | RF_ACTIVE);
  216         if (sc->ndis_irq == NULL) {
  217                 device_printf(dev,
  218                     "couldn't map interrupt\n");
  219                 error = ENXIO;
  220                 goto fail;
  221         }
  222         sc->ndis_rescnt++;
  223         resource_list_add(&sc->ndis_rl, SYS_RES_IRQ, rid,
  224             rman_get_start(sc->ndis_irq), rman_get_start(sc->ndis_irq), 1,
  225             rman_get_cpuid(sc->ndis_irq));
  226 
  227         sc->ndis_iftype = PCMCIABus;
  228 
  229         /* Figure out exactly which device we matched. */
  230 
  231         t = db->windrv_devlist;
  232 
  233         prodstr = pccard_get_product_str(dev);
  234         vendstr = pccard_get_vendor_str(dev);
  235 
  236         while(t->ndis_name != NULL) {
  237                 if (strcasecmp(vendstr, t->ndis_vid) == 0 &&
  238                     strcasecmp(prodstr, t->ndis_did) == 0)
  239                         break;
  240                 t++;
  241                 devidx++;
  242         }
  243 
  244         sc->ndis_devidx = devidx;
  245 
  246         error = ndis_attach(dev);
  247 
  248 fail:
  249         wlan_serialize_exit();
  250         return(error);
  251 }
  252 
  253 static int
  254 ndis_detach_pccard(device_t dev)
  255 {
  256         int error = 0;
  257 
  258         wlan_serialize_enter();
  259         error = ndis_detach(dev);
  260         wlan_serialize_exit();
  261         return(error);
  262 }
  263 
  264 static struct resource_list *
  265 ndis_get_resource_list(device_t dev, device_t child)
  266 {
  267         struct ndis_softc       *sc;
  268 
  269         sc = device_get_softc(dev);
  270         return (&sc->ndis_rl);
  271 }
  272 
  273 #define NDIS_AM_RID 3
  274 
  275 int
  276 ndis_alloc_amem(void *arg)
  277 {
  278         struct ndis_softc       *sc;
  279         int                     error, rid;
  280 
  281         if (arg == NULL)
  282                 return(EINVAL);
  283 
  284         sc = arg;
  285         rid = NDIS_AM_RID;
  286         sc->ndis_res_am = bus_alloc_resource(sc->ndis_dev, SYS_RES_MEMORY,
  287             &rid, 0UL, ~0UL, 0x1000, RF_ACTIVE);
  288 
  289         if (sc->ndis_res_am == NULL) {
  290                 device_printf(sc->ndis_dev,
  291                     "failed to allocate attribute memory\n");
  292                 return(ENXIO);
  293         }
  294         sc->ndis_rescnt++;
  295         resource_list_add(&sc->ndis_rl, SYS_RES_MEMORY, rid,
  296             rman_get_start(sc->ndis_res_am), rman_get_end(sc->ndis_res_am),
  297             rman_get_size(sc->ndis_res_am), -1);
  298 
  299         error = CARD_SET_MEMORY_OFFSET(device_get_parent(sc->ndis_dev),
  300             sc->ndis_dev, rid, 0, NULL);
  301 
  302         if (error) {
  303                 device_printf(sc->ndis_dev,
  304                     "CARD_SET_MEMORY_OFFSET() returned 0x%x\n", error);
  305                 return(error);
  306         }
  307 
  308         error = CARD_SET_RES_FLAGS(device_get_parent(sc->ndis_dev),
  309             sc->ndis_dev, SYS_RES_MEMORY, rid, PCCARD_A_MEM_ATTR);
  310 
  311         if (error) {
  312                 device_printf(sc->ndis_dev,
  313                     "CARD_SET_RES_FLAGS() returned 0x%x\n", error);
  314                 return(error);
  315         }
  316 
  317         sc->ndis_am_rid = rid;
  318 
  319         return(0);
  320 }
  321 
  322 void
  323 ndis_free_amem(void *arg)
  324 {
  325         struct ndis_softc       *sc;
  326 
  327         if (arg == NULL)
  328                 return;
  329 
  330         sc = arg;
  331 
  332         if (sc->ndis_res_am != NULL)
  333                 bus_release_resource(sc->ndis_dev, SYS_RES_MEMORY,
  334                     sc->ndis_am_rid, sc->ndis_res_am);
  335         resource_list_free(&sc->ndis_rl);
  336 
  337         return;
  338 }

Cache object: 1a8e73f92dfffe100874d5c252809736


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