Move PCCARD attachment into separate file. Use the NEWCARD helper
authorJoerg Sonnenberger <joerg@dragonflybsd.org>
Wed, 13 Jul 2005 17:31:05 +0000 (17:31 +0000)
committerJoerg Sonnenberger <joerg@dragonflybsd.org>
Wed, 13 Jul 2005 17:31:05 +0000 (17:31 +0000)
functions for accessing the CIS instead of doing it manually.

Submitted-by: Sepherosa Ziehau <sepherosa@gmail.com>
Obtained-from: FreeBSD

sys/conf/files
sys/dev/netif/xe/Makefile
sys/dev/netif/xe/if_xe.c
sys/dev/netif/xe/if_xe_pccard.c [new file with mode: 0644]
sys/dev/netif/xe/if_xevar.h

index 93ae170..f0bd857 100644 (file)
@@ -1,5 +1,5 @@
 # $FreeBSD: src/sys/conf/files,v 1.340.2.137 2003/06/04 17:10:30 sam Exp $
-# $DragonFly: src/sys/conf/files,v 1.96 2005/07/09 21:58:10 swildner Exp $
+# $DragonFly: src/sys/conf/files,v 1.97 2005/07/13 17:31:05 joerg Exp $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -522,7 +522,8 @@ dev/netif/owi/if_owi.c                      optional owi
 dev/netif/owi/if_owi_pccard.c          optional owi pccard
 dev/netif/owi/if_owi_pci.c             optional owi pci
 dev/netif/owi/owi_hostap.c             optional owi
-dev/netif/xe/if_xe.c                   optional xe pccard
+dev/netif/xe/if_xe.c                   optional xe
+dev/netif/xe/if_xe_pccard.c            optional xe pccard
 vfs/gnu/ext2fs/ext2_alloc.c            optional ext2fs
 vfs/gnu/ext2fs/ext2_balloc.c   optional ext2fs
 vfs/gnu/ext2fs/ext2_inode.c            optional ext2fs
index fffc0fe..bc897ef 100644 (file)
@@ -1,8 +1,9 @@
 # $FreeBSD: src/sys/modules/xe/Makefile,v 1.1.2.1 2002/04/08 18:04:18 asmodai Exp $
-# $DragonFly: src/sys/dev/netif/xe/Makefile,v 1.3 2005/07/13 17:10:25 joerg Exp $
+# $DragonFly: src/sys/dev/netif/xe/Makefile,v 1.4 2005/07/13 17:31:05 joerg Exp $
 
 KMOD   = if_xe
-SRCS   = if_xe.c opt_bdg.h device_if.h card_if.h bus_if.h pci_if.h
+SRCS   = if_xe.c if_xe_pccard.c        \
+         opt_bdg.h device_if.h card_if.h bus_if.h pci_if.h
 SRCS   += if_xevar.h if_xereg.h
 
 .include <bsd.kmod.mk>
index 6b903ec..1d7c040 100644 (file)
@@ -25,7 +25,7 @@
  *
  *     $Id: if_xe.c,v 1.20 1999/06/13 19:17:40 scott Exp $
  * $FreeBSD: src/sys/dev/xe/if_xe.c,v 1.13.2.6 2003/02/05 22:03:57 mbr Exp $
- * $DragonFly: src/sys/dev/netif/xe/if_xe.c,v 1.24 2005/07/13 17:10:25 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/xe/if_xe.c,v 1.25 2005/07/13 17:31:05 joerg Exp $
  */
 
 /*
 #include <net/if_mib.h>
 #include <net/bpf.h>
 
-#include <bus/pccard/pccardvar.h>
-#include "card_if.h"
-
 #include "if_xereg.h"
 #include "if_xevar.h"
 
@@ -168,11 +165,6 @@ struct xe_mii_frame {
 /*
  * Prototypes start here
  */
-static int      xe_probe               (device_t dev);
-static int      xe_attach              (device_t dev);
-static int      xe_detach              (device_t dev);
-static int      xe_activate            (device_t dev);
-static void     xe_deactivate          (device_t dev);
 static void      xe_init               (void *xscp);
 static void      xe_start              (struct ifnet *ifp);
 static int       xe_ioctl              (struct ifnet *ifp, u_long command, caddr_t data, struct ucred *);
@@ -219,270 +211,15 @@ static void      xe_mii_dump             (struct xe_softc *scp);
 #define XE_MII_DUMP(scp)
 #endif
 
-/*
- * Fixing for RealPort cards - they need a little furtling to get the
- * ethernet working
- */
-static int
-xe_cem56fix(device_t dev)
-{
-  struct xe_softc *sc = (struct xe_softc *) device_get_softc(dev);
-  bus_space_tag_t bst;
-  bus_space_handle_t bsh;
-  struct resource *r;
-  int rid;
-  int ioport;
-
-#ifdef XE_DEBUG
-  device_printf(dev, "Hacking your Realport, master\n");
-#endif
-#if XE_DEBUG > 1
-  device_printf(dev, "Realport port 0x%0lx, size 0x%0lx\n",
-      bus_get_resource_start(dev, SYS_RES_IOPORT, sc->port_rid),
-      bus_get_resource_count(dev, SYS_RES_IOPORT, sc->port_rid));
-#endif
-
-  rid = 0;
-  r = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 4 << 10, RF_ACTIVE);
-  if (!r) {
-#if XE_DEBUG > 0
-    device_printf(dev, "Can't map in attribute memory\n");
-#endif
-    return -1;
-  }
-
-  bsh = rman_get_bushandle(r);
-  bst = rman_get_bustag(r);
-
-  CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY, rid,
-      PCCARD_A_MEM_ATTR);
-
-  bus_space_write_1(bst, bsh, DINGO_ECOR, DINGO_ECOR_IRQ_LEVEL |
-                                         DINGO_ECOR_INT_ENABLE |
-                                         DINGO_ECOR_IOB_ENABLE |
-                                                 DINGO_ECOR_ETH_ENABLE);
-  ioport = bus_get_resource_start(dev, SYS_RES_IOPORT, sc->port_rid);
-  bus_space_write_1(bst, bsh, DINGO_EBAR0, ioport & 0xff);
-  bus_space_write_1(bst, bsh, DINGO_EBAR1, (ioport >> 8) & 0xff);
-
-  bus_space_write_1(bst, bsh, DINGO_DCOR0, DINGO_DCOR0_SF_INT);
-  bus_space_write_1(bst, bsh, DINGO_DCOR1, DINGO_DCOR1_INT_LEVEL |
-                                          DINGO_DCOR1_EEDIO);
-  bus_space_write_1(bst, bsh, DINGO_DCOR2, 0x00);
-  bus_space_write_1(bst, bsh, DINGO_DCOR3, 0x00);
-  bus_space_write_1(bst, bsh, DINGO_DCOR4, 0x00);
-
-  bus_release_resource(dev, SYS_RES_MEMORY, rid, r);
-
-  /* success! */
-  return 0;
-}
-       
-/*
- * PCMCIA probe routine.
- * Probe and identify the device.  Called by the slot manager when the card is 
- * inserted or the machine wakes up from suspend mode.  Assmes that the slot
- * structure has been initialised already.
- */
-static int
-xe_probe(device_t dev)
-{
-  struct xe_softc *scp = (struct xe_softc *) device_get_softc(dev);
-  bus_space_tag_t bst;
-  bus_space_handle_t bsh;
-  int buf;
-  u_char ver_str[CISTPL_BUFSIZE>>1];
-  off_t offs;
-  int success, rc, i;
-  int rid;
-  struct resource *r;
-
-  success = 0;
-
-#ifdef XE_DEBUG
-  device_printf(dev, "Probing\n");
-#endif
-
-  /* Map in the CIS */
-  rid = 0;
-  r = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 4 << 10, RF_ACTIVE);
-  if (!r) {
-#ifdef XE_DEBUG
-    device_printf(dev, "Can't map in cis\n");
-#endif
-    return ENOMEM;
-  }
-  bsh = rman_get_bushandle(r);
-  bst = rman_get_bustag(r);
-  buf = 0;
-
-  CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY, rid,
-      PCCARD_A_MEM_ATTR);
-
-  /* Grep through CIS looking for relevant tuples */
-  rc = 0;
-  offs = 0;
-  do {
-    u_int16_t vendor;
-    u_int8_t rev, media, prod;
-
-    switch (CISTPL_TYPE(buf)) {
-
-    case 0x15: /* Grab version string (needed to ID some weird CE2's) */
-#if XE_DEBUG > 1
-      device_printf(dev, "Got version string (0x15)\n");
-#endif
-      for (i = 0; i < CISTPL_LEN(buf); ver_str[i] = CISTPL_DATA(buf, i++));
-      ver_str[i] = '\0';
-      ver_str[(CISTPL_BUFSIZE>>1) - 1] = CISTPL_LEN(buf);
-      success++;
-      break;
-
-    case 0x20: /* Figure out what type of card we have */
-#if XE_DEBUG > 1
-      device_printf(dev, "Got card ID (0x20)\n");
-#endif
-      vendor = CISTPL_DATA(buf, 0) + (CISTPL_DATA(buf, 1) << 8);
-      rev = CISTPL_DATA(buf, 2);
-      media = CISTPL_DATA(buf, 3);
-      prod = CISTPL_DATA(buf, 4);
-
-      switch (vendor) {        /* Get vendor ID */
-      case 0x0105:
-        scp->vendor = "Xircom"; break;
-      case 0x0138:
-      case 0x0183:
-       scp->vendor = "Compaq"; break;
-      case 0x0089:
-       scp->vendor = "Intel"; break;
-      default:
-       scp->vendor = "Unknown";
-      }
-
-      if (!((prod & 0x40) && (media & 0x01))) {
-#if XE_DEBUG > 1
-       device_printf(dev, "Not a PCMCIA Ethernet card!\n");
-#endif
-       rc = ENODEV;            /* Not a PCMCIA Ethernet device */
-      } else {
-       if (media & 0x10) {     /* Ethernet/modem cards */
-#if XE_DEBUG > 1
-         device_printf(dev, "Card is Ethernet/modem combo\n");
-#endif
-         scp->modem = 1;
-         switch (prod & 0x0f) {
-         case 1:
-           scp->card_type = "CEM"; break;
-         case 2:
-           scp->ce2 = 1;
-           scp->card_type = "CEM2"; break;
-         case 3:
-           scp->ce2 = 1;
-           scp->card_type = "CEM3"; break;
-         case 4:
-           scp->ce2 = 1;
-           scp->card_type = "CEM33"; break;
-         case 5:
-           scp->mohawk = 1;
-           scp->card_type = "CEM56M"; break;
-         case 6:
-         case 7:               /* Some kind of RealPort card */
-           scp->mohawk = 1;
-           scp->dingo = 1;
-           scp->card_type = "CEM56"; break;
-         default:
-           rc = ENODEV;
-         }
-       } else {                /* Ethernet-only cards */
-#if XE_DEBUG > 1
-         device_printf(dev, "Card is Ethernet only\n");
-#endif
-         switch (prod & 0x0f) {
-         case 1:
-           scp->card_type = "CE"; break;
-         case 2:
-           scp->ce2 = 1;
-           scp->card_type = "CE2"; break;
-         case 3:
-           scp->mohawk = 1;
-           scp->card_type = "CE3"; break;
-         default:
-           rc = ENODEV;
-         }
-       }
-      }
-      success++;
-      break;
-
-    case 0x22: /* Get MAC address */
-      if ((CISTPL_LEN(buf) == 8) &&
-         (CISTPL_DATA(buf, 0) == 0x04) &&
-         (CISTPL_DATA(buf, 1) == ETHER_ADDR_LEN)) {
-#if XE_DEBUG > 1
-       device_printf(dev, "Got MAC address (0x22)\n");
-#endif
-       for (i = 0; i < ETHER_ADDR_LEN; i++)
-          scp->arpcom.ac_enaddr[i] = CISTPL_DATA(buf, i+2);
-      }
-      success++;
-      break;
-    default:
-      break;
-    }
-
-    if (CISTPL_TYPE(buf) == 0xff)
-      break;
-    /* Skip to next tuple */
-    buf += ((CISTPL_LEN(buf) + 2) << 1);
-
-  } while (1);
-
-  /* unmap the cis */
-  bus_release_resource(dev, SYS_RES_MEMORY, rid, r);
-
-  if (rc)
-    return(rc);
-
-  /* Die now if something went wrong above */
-  if (success < 3)
-    return ENXIO;
-
-  /* Check for certain strange CE2's that look like CE's */
-  if (strcmp(scp->card_type, "CE") == 0) {
-    u_char *str = ver_str;
-#if XE_DEBUG > 1
-    device_printf(dev, "Checking for weird CE2 string\n");
-#endif
-    str += strlen(str) + 1;                    /* Skip forward to 3rd version string */
-    str += strlen(str) + 1;
-    str += strlen(str) + 1;
-    for (i = 0; i < strlen(str) - 2; i++) {
-      if (bcmp(&str[i], "CE2", 3) ==0) {       /* Look for "CE2" string */
-       scp->card_type = "CE2";
-      }
-    }
-  }
-
-  /* Reject unsupported cards */
-  if (strcmp(scp->card_type, "CE") == 0 || strcmp(scp->card_type, "CEM") == 0) {
-    device_printf(dev, "Sorry, your %s card is not supported :(\n",
-     scp->card_type);
-    return ENODEV;
-  }
-
-  /* Success */
-  return 0;
-}
-
 /*
  * The device entry is being removed, probably because someone ejected the
  * card.  The interface should have been brought down manually before calling
  * this function; if not you may well lose packets.  In any case, I shut down
  * the card and the interface, and hope for the best.
  */
-static int
-xe_detach(device_t dev) {
+int
+xe_detach(device_t dev)
+{
   struct xe_softc *sc = device_get_softc(dev);
 
   sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING; 
@@ -495,30 +232,20 @@ xe_detach(device_t dev) {
 /*
  * Attach a device.
  */
-static int
-xe_attach (device_t dev) {
+int
+xe_attach (device_t dev)
+{
   struct xe_softc *scp = device_get_softc(dev);
-  int err;
 
 #ifdef XE_DEBUG
   device_printf(dev, "attach\n");
 #endif
 
-  if ((err = xe_activate(dev)) != 0)
-    return (err);
-
   /* Fill in some private data */
   scp->ifp = &scp->arpcom.ac_if;
   scp->ifm = &scp->ifmedia;
   scp->autoneg_status = 0;
 
-  /* Hack RealPorts into submission */
-  if (scp->dingo && xe_cem56fix(dev) < 0) {
-    device_printf(dev, "Unable to fix your RealPort\n");
-    xe_deactivate(dev);
-    return ENODEV;
-  }
-
   /* Hopefully safe to read this here */
   XE_SELECT_PAGE(4);
   scp->version = XE_INB(XE_BOV);
@@ -2221,24 +1948,3 @@ xe_deactivate(device_t dev)
        sc->irq_res = 0;
        return;
 }
-
-static device_method_t xe_pccard_methods[] = {
-       /* Device interface */
-       DEVMETHOD(device_probe,         xe_probe),
-       DEVMETHOD(device_attach,        xe_attach),
-       DEVMETHOD(device_detach,        xe_detach),
-
-       { 0, 0 }
-};
-
-static driver_t xe_pccard_driver = {
-       "xe",
-       xe_pccard_methods,
-       sizeof(struct xe_softc),
-};
-
-devclass_t xe_devclass;
-
-DECLARE_DUMMY_MODULE(if_xe);
-DRIVER_MODULE(if_xe, pccard, xe_pccard_driver, xe_devclass, 0, 0);
-
diff --git a/sys/dev/netif/xe/if_xe_pccard.c b/sys/dev/netif/xe/if_xe_pccard.c
new file mode 100644 (file)
index 0000000..7dc673a
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 2002 Takeshi Shibagaki
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * xe pccard interface driver
+ *
+ * $FreeBSD: src/sys/dev/xe/if_xe_pccard.c,v 1.1 2002/02/20 14:23:58 shiba Exp $
+ * $DragonFly: src/sys/dev/netif/xe/if_xe_pccard.c,v 1.1 2005/07/13 17:31:05 joerg Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+#include <net/ethernet.h>
+#include <net/if.h> 
+#include <net/if_arp.h>
+#include <net/if_media.h>
+#include <net/if_mib.h>
+
+#include <bus/pccard/pccardvar.h>
+#include <bus/pccard/pccarddevs.h>
+#include "card_if.h"
+
+#include "if_xereg.h"
+#include "if_xevar.h"
+
+static const struct pccard_product xe_pccard_products[] = {
+       PCMCIA_CARD(ACCTON, EN2226, 0),
+       PCMCIA_CARD(COMPAQ2, CPQ_10_100, 0),
+       PCMCIA_CARD(INTEL, EEPRO100, 0),
+       PCMCIA_CARD(XIRCOM, CE, 0),
+       PCMCIA_CARD(XIRCOM, CE2, 0),
+       PCMCIA_CARD(XIRCOM, CE3, 0),
+       PCMCIA_CARD(XIRCOM, CEM, 0),
+       PCMCIA_CARD(XIRCOM, CEM28, 0),
+       PCMCIA_CARD(XIRCOM, CEM33, 0),
+       PCMCIA_CARD(XIRCOM, CEM56, 0),
+       PCMCIA_CARD(XIRCOM, REM56, 0),
+       PCMCIA_CARD(XIRCOM, CNW_801, 0),
+       PCMCIA_CARD(XIRCOM, CNW_802, 0),
+        { NULL }
+};
+
+struct xe_vendor {
+       uint32_t         vendor_id;
+       const char      *vendor_desc;
+} xe_vendors[] = {
+       { PCMCIA_VENDOR_XIRCOM,         "Xircom" },
+       { PCMCIA_VENDOR_COMPAQ,         "Compaq" },
+       { PCMCIA_VENDOR_COMPAQ2,        "Compaq" },
+       { PCMCIA_VENDOR_INTEL,          "Intel" },
+       { 0,                            "Unknown" }
+};
+
+#define XE_CARD_TYPE_FLAGS_NO          0x0
+#define XE_CARD_TYPE_FLAGS_CE2         0x1
+#define XE_CARD_TYPE_FLAGS_MOHAWK      0x2
+#define XE_CARD_TYPE_FLAGS_DINGO       0x4
+
+#define XE_PROD_UMASK          0x100f
+#define XE_PROD_MODEM_UMASK    0x1000
+#define XE_PROD_SINGLE_ID1     0x1
+#define XE_PROD_SINGLE_ID2     0x2
+#define XE_PROD_SINGLE_ID3     0x3
+#define XE_PROD_MULTI_ID1      0x1001
+#define XE_PROD_MULTI_ID2      0x1002
+#define XE_PROD_MULTI_ID3      0x1003
+#define XE_PROD_MULTI_ID4      0x1004
+#define XE_PROD_MULTI_ID5      0x1005
+#define XE_PROD_MULTI_ID6      0x1006
+#define XE_PROD_MULTI_ID7      0x1007
+
+struct xe_card_type {
+       uint32_t         prod_type;
+       const char      *card_type_desc;
+       uint32_t         flags;
+} xe_card_types[] = {
+       { XE_PROD_MULTI_ID1,    "CEM",          XE_CARD_TYPE_FLAGS_NO },
+       { XE_PROD_MULTI_ID2,    "CEM2",         XE_CARD_TYPE_FLAGS_CE2 },
+       { XE_PROD_MULTI_ID3,    "CEM3",         XE_CARD_TYPE_FLAGS_CE2 },
+       { XE_PROD_MULTI_ID4,    "CEM33",        XE_CARD_TYPE_FLAGS_CE2 },
+       { XE_PROD_MULTI_ID5,    "CEM56M",       XE_CARD_TYPE_FLAGS_MOHAWK },
+       { XE_PROD_MULTI_ID6,    "CEM56",        XE_CARD_TYPE_FLAGS_MOHAWK |
+                                               XE_CARD_TYPE_FLAGS_DINGO },
+       { XE_PROD_MULTI_ID7,    "CEM56",        XE_CARD_TYPE_FLAGS_MOHAWK |
+                                               XE_CARD_TYPE_FLAGS_DINGO },
+       { XE_PROD_SINGLE_ID1,   "CE",           XE_CARD_TYPE_FLAGS_NO },
+       { XE_PROD_SINGLE_ID2,   "CE2",          XE_CARD_TYPE_FLAGS_CE2 },
+       { XE_PROD_SINGLE_ID3,   "CE3",          XE_CARD_TYPE_FLAGS_MOHAWK },
+       { 0, NULL, -1 }
+};
+
+static struct xe_vendor                *xe_vendor_lookup       (uint32_t);
+static struct xe_card_type     *xe_card_type_lookup    (uint32_t);
+
+static int     xe_cem56fix     (device_t);
+static int     xe_pccard_probe (device_t);
+static int     xe_pccard_match (device_t);
+static int     xe_pccard_attach(device_t);
+
+static device_method_t xe_pccard_methods[] = {
+       /* Device interface */
+       DEVMETHOD(device_probe,         pccard_compat_probe),
+       DEVMETHOD(device_attach,        pccard_compat_attach),
+       DEVMETHOD(device_detach,        xe_detach),
+
+       /* Card interface */
+       DEVMETHOD(card_compat_match,    xe_pccard_match),
+       DEVMETHOD(card_compat_probe,    xe_pccard_probe),
+       DEVMETHOD(card_compat_attach,   xe_pccard_attach),
+
+        { 0, 0 }
+};
+
+static driver_t xe_pccard_driver = {
+       "xe",
+       xe_pccard_methods,
+       sizeof(struct xe_softc),
+};
+
+devclass_t xe_devclass;
+DRIVER_MODULE(xe, pccard, xe_pccard_driver, xe_devclass, 0, 0);
+
+/*
+ * Fixing for RealPort cards - they need a little furtling to get the
+ * ethernet working. But this codes don't work well in NEWCARD.
+ */
+static int
+xe_cem56fix(device_t dev)
+{
+       struct xe_softc *sc = device_get_softc(dev);
+       bus_space_tag_t bst;
+       bus_space_handle_t bsh;
+       struct resource *r;
+       int rid;
+       int ioport;
+
+       device_printf(dev, "Realport port 0x%0lx, size 0x%0lx\n",
+           bus_get_resource_start(dev, SYS_RES_IOPORT, sc->port_rid),
+           bus_get_resource_count(dev, SYS_RES_IOPORT, sc->port_rid));
+
+       rid = 0;
+       r = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0,
+                              ~0, 4 << 10, RF_ACTIVE);
+       if (r == NULL) {
+               device_printf(dev, "Can't map in attribute memory\n");
+               return -1;
+       }
+
+       bsh = rman_get_bushandle(r);
+       bst = rman_get_bustag(r);
+
+       CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY, rid,
+                          PCCARD_A_MEM_ATTR);
+
+       bus_space_write_1(bst, bsh, DINGO_ECOR, DINGO_ECOR_IRQ_LEVEL |
+                                               DINGO_ECOR_INT_ENABLE |
+                                               DINGO_ECOR_IOB_ENABLE |
+                                               DINGO_ECOR_ETH_ENABLE);
+       ioport = bus_get_resource_start(dev, SYS_RES_IOPORT, sc->port_rid);
+       bus_space_write_1(bst, bsh, DINGO_EBAR0, ioport & 0xff);
+       bus_space_write_1(bst, bsh, DINGO_EBAR1, (ioport >> 8) & 0xff);
+
+       bus_space_write_1(bst, bsh, DINGO_DCOR0, DINGO_DCOR0_SF_INT);
+       bus_space_write_1(bst, bsh, DINGO_DCOR1, DINGO_DCOR1_INT_LEVEL |
+                                                DINGO_DCOR1_EEDIO);
+       bus_space_write_1(bst, bsh, DINGO_DCOR2, 0x00);
+       bus_space_write_1(bst, bsh, DINGO_DCOR3, 0x00);
+       bus_space_write_1(bst, bsh, DINGO_DCOR4, 0x00);
+
+       bus_release_resource(dev, SYS_RES_MEMORY, rid, r);
+
+       /* success! */
+       return 0;
+}
+
+static struct xe_vendor *
+xe_vendor_lookup(uint32_t vendor_id)
+{
+       struct xe_vendor *v;
+
+       for (v = xe_vendors; v->vendor_id != 0; ++v) {
+               if(v->vendor_id == vendor_id)
+                       break;
+       }
+       return v;
+}
+      
+static struct xe_card_type *
+xe_card_type_lookup(uint32_t prod)
+{
+       struct xe_card_type *ct;
+
+       for (ct = xe_card_types; ct->card_type_desc != NULL; ++ct) {
+               if(ct->prod_type == (prod & XE_PROD_UMASK))
+                       return ct;
+       }
+       return NULL;
+}
+
+/*
+ * PCMCIA probe routine.
+ * Identify the device.  Called from the bus driver when the card is
+ * inserted or otherwise powers up.
+ */
+static int
+xe_pccard_probe(device_t dev)
+{
+       struct xe_softc *scp = device_get_softc(dev);
+       uint32_t vendor, product, prod;
+       uint16_t prodext;
+       uint8_t *ether_addr;
+       const char *cis3_str=NULL;
+       struct xe_vendor *vendor_itm;
+       struct xe_card_type *card_itm;
+       int i;
+
+       /*
+        * PCCARD_CISTPL_MANFID = 0x20
+        */
+       vendor = pccard_get_vendor(dev);
+       vendor_itm = xe_vendor_lookup(vendor);
+       /*
+        * We always have some vendor here, although
+        * vendor description may be "Unknown".
+        */
+       scp->vendor = vendor_itm->vendor_desc;
+
+       product = pccard_get_product(dev);
+       prodext = pccard_get_prodext(dev);
+
+       /*
+        * prod(new) =  rev, media, prod(old)
+        * prod(new) =  (don't care), (care 0x10 bit), (care 0x0f bit)
+        */
+       prod = (product << 8) | prodext;
+       card_itm = xe_card_type_lookup(prod);
+       if (card_itm == NULL)
+               return ENODEV;
+
+       scp->card_type = card_itm->card_type_desc;
+       if (card_itm->prod_type & XE_PROD_MODEM_UMASK)
+               scp->modem = 1;
+
+       for (i = 1; i != XE_CARD_TYPE_FLAGS_DINGO; i = i << 1) {
+               switch(i & card_itm->flags) {
+               case XE_CARD_TYPE_FLAGS_CE2:
+                       scp->ce2 = 1;
+                       break;
+               case XE_CARD_TYPE_FLAGS_MOHAWK:
+                       scp->mohawk = 1;
+                       break;
+               case XE_CARD_TYPE_FLAGS_DINGO:
+                       scp->dingo = 1;
+                       break;
+               }
+       }
+
+       /*
+        * PCCARD_CISTPL_VERS_1 = 0x15
+        *
+        * Check for certain strange CE2's that look like CE's:
+        * match 3rd version string against "CE2"
+        */
+       cis3_str = pccard_get_cis3_str(dev);
+       if (strcmp(scp->card_type, "CE") == 0)
+               if (strcmp(cis3_str, "CE2") ==0)
+                       scp->card_type = "CE2";
+
+       /*
+        * PCCARD_CISTPL_FUNCE = 0x22
+        */
+       ether_addr = pccard_get_ether(dev);
+       bcopy(ether_addr, scp->arpcom.ac_enaddr, ETHER_ADDR_LEN);
+
+       /* Reject unsupported cards */
+       if (strcmp(scp->card_type, "CE") == 0 ||
+           strcmp(scp->card_type, "CEM") == 0) {
+               device_printf(dev, "Sorry, your %s card is not supported :(\n",
+                             scp->card_type);
+               return ENODEV;
+       }
+
+       /* Success */
+       return 0;
+}
+
+static int
+xe_pccard_attach(device_t dev)
+{
+       struct xe_softc *scp = device_get_softc(dev);
+       int err;
+
+       if ((err = xe_activate(dev)) != 0)
+               return err;
+         
+       /* Hack RealPorts into submission */
+       if (scp->dingo && xe_cem56fix(dev) < 0) {
+               device_printf(dev, "Unable to fix your RealPort\n");
+               xe_deactivate(dev);
+               return ENODEV;
+       }
+       return xe_attach(dev);
+}
+
+static int
+xe_pccard_match(device_t dev)
+{
+       const struct pccard_product *pp;
+
+       if ((pp = pccard_product_lookup(dev, xe_pccard_products,
+            sizeof(xe_pccard_products[0]), NULL)) != NULL) {
+               if (pp->pp_name != NULL)
+                       device_set_desc(dev, pp->pp_name);
+               return 0;
+       }
+       return EIO;
+}
index 2f4413e..fccce8d 100644 (file)
@@ -25,7 +25,7 @@
  *
  *     $Id: if_xe.c,v 1.20 1999/06/13 19:17:40 scott Exp $
  * $FreeBSD: src/sys/dev/xe/if_xevar.h,v 1.1.2.1 2000/06/01 01:23:53 imp Exp $
- * $DragonFly: src/sys/dev/netif/xe/if_xevar.h,v 1.4 2005/07/13 17:10:25 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/xe/if_xevar.h,v 1.5 2005/07/13 17:31:05 joerg Exp $
  */
 #ifndef DEV_XE_IF_XEDEV_H
 #define DEV_XE_IF_XEDEV_H
@@ -40,8 +40,8 @@ struct xe_softc {
   struct callout xe_timer;
   struct ifnet *ifp;
   struct ifmedia *ifm;
-  char *card_type;     /* Card model name */
-  char *vendor;                /* Card manufacturer */
+  const char *card_type;       /* Card model name */
+  const char *vendor;          /* Card manufacturer */
   bus_space_tag_t bst; /* Bus space tag for card */
   bus_space_handle_t bsh; /* Bus space handle for card */
   void *intrhand;
@@ -82,4 +82,9 @@ struct xe_softc {
 #define CISTPL_LEN(tpl)                bus_space_read_1(bst, bsh, tpl + 2)
 #define CISTPL_DATA(tpl,pos)   bus_space_read_1(bst, bsh, tpl+ 4 + ((pos)<<1))
 
+int    xe_attach(device_t);
+int    xe_detach(device_t);
+int    xe_activate(device_t);
+void   xe_deactivate(device_t);
+
 #endif /* DEV_XE_IF_XEVAR_H */