summaryrefslogtreecommitdiffstats
path: root/sys/dev/xe
diff options
context:
space:
mode:
authorshiba <shiba@FreeBSD.org>2002-02-20 14:23:58 +0000
committershiba <shiba@FreeBSD.org>2002-02-20 14:23:58 +0000
commitb7d0d162c2777065ce92fb4131f483f08ef11856 (patch)
treeda7ddeae139a0f3c578c29d9a564fa83fcda0a6b /sys/dev/xe
parent6374dfe01ce1f99c0ab4620dddd6988c4ebac1c0 (diff)
downloadFreeBSD-src-b7d0d162c2777065ce92fb4131f483f08ef11856.zip
FreeBSD-src-b7d0d162c2777065ce92fb4131f483f08ef11856.tar.gz
Update xe driver to probe and attach in a NEWCARD kernel.
And separate probe and attach routine for PC Card from if_xe.c to if_xe_pccard.c. Reviewed by: imp
Diffstat (limited to 'sys/dev/xe')
-rw-r--r--sys/dev/xe/if_xe.c313
-rw-r--r--sys/dev/xe/if_xe_pccard.c358
-rw-r--r--sys/dev/xe/if_xevar.h4
3 files changed, 365 insertions, 310 deletions
diff --git a/sys/dev/xe/if_xe.c b/sys/dev/xe/if_xe.c
index 016bb3c..20c6698 100644
--- a/sys/dev/xe/if_xe.c
+++ b/sys/dev/xe/if_xe.c
@@ -133,13 +133,9 @@
#include <net/if_mib.h>
#include <net/bpf.h>
-#include <dev/pccard/pccardvar.h>
-#include "card_if.h"
-
#include <dev/xe/if_xereg.h>
#include <dev/xe/if_xevar.h>
-
/*
* MII command structure
*/
@@ -165,11 +161,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);
@@ -215,280 +206,11 @@ static void xe_mii_dump (struct xe_softc *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 = 0, i;
- int rid;
- struct resource *r;
-
- success = 0;
-
-#ifdef XE_DEBUG
- device_printf(dev, "xe: 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 */
- 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);
-
- /* Die now if something went wrong above */
- if (success < 3)
- return ENXIO;
- if (rc != 0)
- return (rc);
-
- /* 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) {
- struct xe_softc *sc = device_get_softc(dev);
-
- sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
- ether_ifdetach(&sc->arpcom.ac_if, ETHER_BPF_SUPPORTED);
- xe_deactivate(dev);
- return 0;
-}
-
-/*
* 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;
@@ -496,21 +218,11 @@ xe_attach (device_t dev) {
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);
@@ -2233,22 +1945,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;
-
-DRIVER_MODULE(xe, pccard, xe_pccard_driver, xe_devclass, 0, 0);
diff --git a/sys/dev/xe/if_xe_pccard.c b/sys/dev/xe/if_xe_pccard.c
new file mode 100644
index 0000000..c8e6fc3
--- /dev/null
+++ b/sys/dev/xe/if_xe_pccard.c
@@ -0,0 +1,358 @@
+/*
+ * 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$
+ */
+
+#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 <dev/xe/if_xereg.h>
+#include <dev/xe/if_xevar.h>
+
+#include "card_if.h"
+#include <dev/pccard/pccardvar.h>
+#include <dev/pccard/pccarddevs.h>
+
+#define XE_VENDOR_ID_XIRCOM 0x0105
+#define XE_VENDOR_ID_COMPAQ_1 0x0138
+#define XE_VENDOR_ID_COMPAQ_2 0x0183
+#define XE_VENDOR_ID_INTEL 0x0089
+#define XE_VENDOR_ID_UNKNOWN 0
+
+struct xe_vendor_table {
+ u_int32_t vendor_id;
+ char *vendor_desc;
+} xe_vendor_devs[] = {
+ { XE_VENDOR_ID_XIRCOM, "Xircom" },
+ { XE_VENDOR_ID_COMPAQ_1, "Compaq" },
+ { XE_VENDOR_ID_COMPAQ_2, "Compaq" },
+ { XE_VENDOR_ID_INTEL, "Intel" },
+ { XE_VENDOR_ID_UNKNOWN, "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_table {
+ u_int32_t prod_type;
+ char *card_type_desc;
+ u_int32_t flags;
+} xe_card_type_devs[] = {
+ { 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 }
+};
+
+/*
+ * Prototypes
+ */
+static int xe_cem56fix(device_t dev);
+static struct xe_vendor_table *xe_vendor_lookup(u_int32_t devid,
+ struct xe_vendor_table *tbl);
+static struct xe_card_type_table *xe_card_type_lookup(u_int32_t devid,
+ struct xe_card_type_table *tbl);
+
+/*
+ * 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 = (struct xe_softc *) 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) {
+ 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_table *
+xe_vendor_lookup(u_int32_t devid, struct xe_vendor_table *tbl)
+{
+ while(tbl->vendor_id) {
+ if(tbl->vendor_id == devid)
+ return (tbl);
+ tbl++;
+ }
+ return (tbl); /* return Unknown */
+}
+
+static struct xe_card_type_table *
+xe_card_type_lookup(u_int32_t devid, struct xe_card_type_table *tbl)
+{
+ while(tbl->prod_type) {
+ if(tbl->prod_type == (devid & XE_PROD_UMASK))
+ return (tbl);
+ tbl++;
+ }
+ 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 = (struct xe_softc *) device_get_softc(dev);
+ u_int32_t vendor,prodid,prod;
+ u_int16_t prodext;
+ char *cis3_str=NULL;
+ struct xe_vendor_table *vendor_itm;
+ struct xe_card_type_table *card_itm;
+ int i;
+
+ /*
+ * PCCARD_CISTPL_MANFID = 0x20
+ */
+ pccard_get_vendor(dev, &vendor);
+ vendor_itm = xe_vendor_lookup(vendor, &xe_vendor_devs[0]);
+ scp->vendor = vendor_itm->vendor_desc;
+ pccard_get_product(dev, &prodid);
+ pccard_get_prodext(dev, &prodext);
+ /*
+ * prod(new) = rev, media, prod(old)
+ * prod(new) = (don't care), (care 0x10 bit), (care 0x0f bit)
+ */
+ prod = (prodid << 8) | prodext;
+ card_itm = xe_card_type_lookup(prod, &xe_card_type_devs[0]);
+ if(!card_itm)
+ return (ENODEV);
+ else {
+ 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
+ */
+ pccard_get_cis3_str(dev, &cis3_str);
+ if (strcmp(scp->card_type, "CE") == 0)
+ if (strcmp(cis3_str, "CE2") ==0)
+ scp->card_type = "CE2"; /* Look for "CE2" string */
+
+ /*
+ * PCCARD_CISTPL_FUNCE = 0x22
+ */
+ pccard_get_ether(dev, scp->arpcom.ac_enaddr);
+
+ /* 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);
+}
+
+/*
+ * Attach a device.
+ */
+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);
+ }
+ if ((err = xe_attach(dev))) {
+ device_printf(dev, "xe_attach() failed! (%d)\n", err);
+ return (err);
+ }
+ 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_pccard_detach(device_t dev)
+{
+ struct xe_softc *sc = device_get_softc(dev);
+
+ sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
+ ether_ifdetach(&sc->arpcom.ac_if, ETHER_BPF_SUPPORTED);
+ xe_deactivate(dev);
+ return (0);
+}
+
+static const struct pccard_product xe_pccard_products[] = {
+ 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 }
+};
+
+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) {
+ device_set_desc(dev, pp->pp_name);
+ return (0);
+ }
+ return (EIO);
+}
+
+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_pccard_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);
diff --git a/sys/dev/xe/if_xevar.h b/sys/dev/xe/if_xevar.h
index 150d25d..7cd5ac8 100644
--- a/sys/dev/xe/if_xevar.h
+++ b/sys/dev/xe/if_xevar.h
@@ -82,4 +82,8 @@ 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 dev);
+int xe_activate(device_t dev);
+void xe_deactivate(device_t dev);
+
#endif /* DEV_XE_IF_XEVAR_H */
OpenPOWER on IntegriCloud