summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2000-09-22 01:15:26 +0000
committerWarner Losh <imp@FreeBSD.org>2000-09-22 01:15:26 +0000
commit8456e16e247e0524d5c85d47b2d3004879a6b5bf (patch)
tree0f3edac60595f926ce8acb8e50d8517caf6360e7
parente45ccde7c6ce7b180520c264149e1832422965f4 (diff)
Notes
-rw-r--r--sys/dev/pccard/pccard.c55
-rw-r--r--sys/dev/pccard/pccardvar.h46
2 files changed, 93 insertions, 8 deletions
diff --git a/sys/dev/pccard/pccard.c b/sys/dev/pccard/pccard.c
index 39564fe84d75..4b71b167b6d2 100644
--- a/sys/dev/pccard/pccard.c
+++ b/sys/dev/pccard/pccard.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pcmcia.c,v 1.13 1998/12/24 04:51:59 marc Exp $ */
+/* $NetBSD: pcmcia.c,v 1.23 2000/07/28 19:17:02 drochner Exp $ */
/* $FreeBSD$ */
/*
@@ -205,6 +205,59 @@ pccard_detach_card(device_t dev, int flags)
return 0;
}
+const struct pccard_product *
+pccard_product_lookup(device_t dev, const struct pccard_product *tab,
+ size_t ent_size, pccard_product_match_fn matchfn)
+{
+ const struct pccard_product *ent;
+ int matches;
+ u_int32_t fcn;
+ u_int32_t vendor;
+ u_int32_t prod;
+ char *vendorstr;
+ char *prodstr;
+
+#ifdef DIAGNOSTIC
+ if (sizeof *ent > ent_size)
+ panic("pccard_product_lookup: bogus ent_size %ld",
+ (long) ent_size);
+#endif
+ if (pccard_get_vendor(dev, &vendor))
+ return (NULL);
+ if (pccard_get_product(dev, &prod))
+ return (NULL);
+ if (pccard_get_function_number(dev, &fcn))
+ return (NULL);
+ if (pccard_get_vendor_str(dev, &vendorstr))
+ return (NULL);
+ if (pccard_get_product_str(dev, &prodstr))
+ return (NULL);
+ for (ent = tab; ent->pp_name != NULL;
+ ent = (const struct pccard_product *)
+ ((const char *) ent + ent_size)) {
+ matches = 1;
+ if (matches && ent->pp_vendor != PCCARD_VENDOR_ANY &&
+ vendor != ent->pp_vendor)
+ matches = 0;
+ if (matches && ent->pp_product != PCCARD_PRODUCT_ANY &&
+ prod != ent->pp_product)
+ matches = 0;
+ if (matches && fcn != ent->pp_expfunc)
+ matches = 0;
+ if (matches && ent->pp_vendor_str &&
+ strcmp(ent->pp_vendor_str, vendorstr) != 0)
+ matches = 0;
+ if (matches && ent->pp_product_str &&
+ strcmp(ent->pp_product_str, prodstr) != 0)
+ matches = 0;
+ if (matchfn != NULL)
+ matches = (*matchfn)(dev, ent, matches);
+ if (matches)
+ return (ent);
+ }
+ return (NULL);
+}
+
static int
pccard_card_gettype(device_t dev, int *type)
{
diff --git a/sys/dev/pccard/pccardvar.h b/sys/dev/pccard/pccardvar.h
index a91d2fbff387..8b40c5516b27 100644
--- a/sys/dev/pccard/pccardvar.h
+++ b/sys/dev/pccard/pccardvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: pcmciavar.h,v 1.9 1998/12/29 09:00:28 marc Exp $ */
+/* $NetBSD: pcmciavar.h,v 1.12 2000/02/08 12:51:31 enami Exp $ */
/* $FreeBSD$ */
/*
@@ -200,6 +200,24 @@ struct pccard_tuple {
bus_space_handle_t memh;
};
+struct pccard_product {
+ const char *pp_name; /* NULL if end of table */
+#define PCCARD_VENDOR_ANY ((u_int32_t) -1)
+ u_int32_t pp_vendor;
+#define PCCARD_PRODUCT_ANY ((u_int32_t) -1)
+ u_int32_t pp_product;
+ int pp_expfunc;
+ const char *pp_vendor_str; /* NULL to not match */
+ const char *pp_product_str; /* NULL to not match */
+};
+
+typedef int (*pccard_product_match_fn) (device_t dev,
+ const struct pccard_product *ent, int vpfmatch);
+
+const struct pccard_product
+ *pccard_product_lookup(device_t dev, const struct pccard_product *tab,
+ size_t ent_size, pccard_product_match_fn matchfn);
+
void pccard_read_cis(struct pccard_softc *);
void pccard_check_cis_quirks(device_t);
void pccard_print_cis(device_t);
@@ -276,16 +294,30 @@ int pccard_compat_attach(device_t dev);
/* ivar interface */
enum {
PCCARD_IVAR_ETHADDR, /* read ethernet address from CIS tupple */
+ PCCARD_IVAR_VENDOR,
+ PCCARD_IVAR_PRODUCT,
+ PCCARD_IVAR_FUNCTION_NUMBER,
+ PCCARD_IVAR_VENDOR_STR, /* CIS string for "Manufacturer" */
+ PCCARD_IVAR_PRODUCT_STR,/* CIS strnig for "Product" */
+ PCCARD_IVAR_CIS3_STR /* Some cards need this */
};
-/* read ethernet address from CIS tupple */
-__inline static int
-pccard_get_ether(device_t dev, u_char *enaddr)
-{
- return BUS_READ_IVAR(device_get_parent(dev), dev,
- PCCARD_IVAR_ETHADDR, (uintptr_t *)enaddr);
+#define PCCARD_ACCESSOR(A, B, T) \
+__inline static int \
+pccard_get_ ## A(device_t dev, T *t) \
+{ \
+ return BUS_READ_IVAR(device_get_parent(dev), dev, \
+ PCCARD_IVAR_ ## B, (uintptr_t *) t); \
}
+PCCARD_ACCESSOR(ether, ETHADDR, u_int8_t)
+PCCARD_ACCESSOR(vendor, VENDOR, u_int32_t)
+PCCARD_ACCESSOR(product, PRODUCT, u_int32_t)
+PCCARD_ACCESSOR(function_number,FUNCTION_NUMBER, u_int32_t)
+PCCARD_ACCESSOR(vendor_str, VENDOR_STR, char *)
+PCCARD_ACCESSOR(product_str, PRODUCT_STR, char *)
+PCCARD_ACCESSOR(cis3_str, CIS3_STR, char *)
+
enum {
PCCARD_A_MEM_ATTR = 0x1
};