summaryrefslogtreecommitdiff
path: root/sys/dev/pcmcia/pcmcia.c
diff options
context:
space:
mode:
authorhvozda <hvozda@cvs.openbsd.org>1996-04-29 14:17:54 +0000
committerhvozda <hvozda@cvs.openbsd.org>1996-04-29 14:17:54 +0000
commit7a9ddc83f934914d39af72bf24b67290a9e5700f (patch)
treed4e40de8eec73b77be31c346455984224213ff31 /sys/dev/pcmcia/pcmcia.c
parentfdecada6f88b495c1afc81ad3a15c0cedffa2338 (diff)
Pull in John Kohl's [jtk@netbsd.org] most recent (15Apr96) APM and PCMCIA work
(original PCMCIA framework by Stefan Grefen [grefen@convex.com]).
Diffstat (limited to 'sys/dev/pcmcia/pcmcia.c')
-rw-r--r--sys/dev/pcmcia/pcmcia.c904
1 files changed, 404 insertions, 500 deletions
diff --git a/sys/dev/pcmcia/pcmcia.c b/sys/dev/pcmcia/pcmcia.c
index 7729774be59..f37de3ef3a4 100644
--- a/sys/dev/pcmcia/pcmcia.c
+++ b/sys/dev/pcmcia/pcmcia.c
@@ -1,4 +1,6 @@
+/* $Id: pcmcia.c,v 1.3 1996/04/29 14:17:15 hvozda Exp $ */
/*
+ * Copyright (c) 1996 John T. Kohl. All rights reserved.
* Copyright (c) 1994 Stefan Grefen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,9 +29,14 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: pcmcia.c,v 1.2 1996/01/26 21:27:31 hvozda Exp $
*/
+/* XXX - these next two lines are just "glue" until the confusion over
+ pcmcia vs pcmciabus between the framework and sys/conf/files
+ gets resolved */
+#define pcmciabus_cd pcmcia_cd
+#define pcmciabus_ca pcmcia_ca
+
/* derived from scsiconf.c writte by Julian Elischer et al */
/* TODO add modload support and loadable lists of devices */
#include <sys/types.h>
@@ -39,15 +46,13 @@
#include <sys/device.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>
+#include <sys/proc.h>
+#include <sys/cpu.h>
-#include <dev/pcmcia/pcmcia.h>
-#include <dev/pcmcia/pcmciabus.h>
+#include <dev/pcmcia/pcmciavar.h>
+#include <dev/pcmcia/pcmciareg.h>
#include <dev/pcmcia/pcmcia_ioctl.h>
-#include "ed.h"
-#include "com.h"
-#include "ep.h"
-
#ifdef IBM_WD
#define PCMCIA_DEBUG
#endif
@@ -57,107 +62,57 @@
# define PPRINTF(a)
#endif
-static void pcmciadumpcf __P((struct pcmcia_conf *));
-static int pcmcia_strcmp __P((char *, char *, int, char *));
-
-void pcmcia_shuthook __P((void *));
-
-static struct pcmcia_adapter pcmcia_drivers[4];
-static int pcmcia_cntrl = 0;
-static int probed = 0;
-static struct device **deldevs = NULL;
-static int ndeldevs = 0;
-
-/* I've decided to re-ifdef these. It makes making a kernel easier
- until I either get config(8) modified to deal somehow
- or figure out a better to way declare the prototypes and
- build up the knowndevs struct. Stefan may have ideas...
-*/
-
-#if NED > 0
-extern struct pcmciadevs pcmcia_ed_devs[];
-#endif
-#if NCOM > 0
-extern struct pcmciadevs pcmcia_com_devs[];
-#endif
-#if NEP > 0
-extern struct pcmciadevs pcmcia_ep_devs[];
-#endif
-
-static struct pcmciadevs *knowndevs[] = {
-#if NED > 0
- pcmcia_ed_devs,
-#endif
-#if NCOM > 0
- pcmcia_com_devs,
-#endif
-#if NEP > 0
- pcmcia_ep_devs,
+#ifdef PCMCIA_DEBUG
+void pcmciadumpcf __P((struct pcmcia_conf *));
#endif
- NULL
-};
-#ifdef notyet
-static struct pcmciadevs *knowndevs[10] = { NULL };
-#define KNOWNSIZE (sizeof(knowndevs) / sizeof(knowndevs[0]))
-#endif
+static struct old_devs {
+ struct device *dev;
+ struct pcmciadevs *pcdev;
+} *deldevs;
+static int ndeldevs = 0;
#define PCMCIA_SERVICE(a,b,c,d,e) ((a)->chip_link->pcmcia_service(b,c,\
(void *) d,e))
#define PCMCIA_MAP_IO(a,b,c,d,e) ((a)->chip_link->pcmcia_map_io(b,c,d,e))
#define PCMCIA_MAP_INTR(a,b,c,d) ((a)->chip_link->pcmcia_map_intr(b,c,d))
-#define PCMCIA_MAP_MEM(a,b,c,d,e,f) ((a)->chip_link->pcmcia_map_mem(b,c,d,e,f))
-
-#define PCMCIA_BUS_INIT(a,b,c,d,e,f)((a)->bus_link->bus_init((b),(c),(d),(e)\
- ,(f)))
-#define PCMCIA_BUS_SEARCH(a,b,c,d) ((a)->bus_link->bus_search((b),(c),(d)))
-#define PCMCIA_BUS_PROBE(a,b,c,d,e) ((a)->bus_link->bus_probe((b),(c),(d),(e)))
-#define PCMCIA_BUS_CONFIG(a,b,c,d,e)((a)->bus_link->bus_config((b),(c),(d),(e)))
-#define PCMCIA_BUS_UNCONFIG(a,b) ((a)->bus_link->bus_unconfig((b)))
+/* XXX
+ * this is quite broken in the face of various bus mapping stuff...
+ * drivers need to cooperate with the pcmcia framework to deal with
+ * bus mapped memory. Whee.
+ */
+#define PCMCIA_MAP_MEM(a,b,c,d,e,f,g) ((a)->chip_link->pcmcia_map_mem(b,c,d,e,f,g))
-#define SCRATCH_MEM(a) ((a)->scratch_mem)
+#define SCRATCH_MEM(a) ((a)->scratch_memh)
+#define SCRATCH_BC(a) ((a)->pa_bc)
#define SCRATCH_SIZE(a) ((a)->scratch_memsiz)
#define SCRATCH_INUSE(a)((a)->scratch_inuse)
/*
* Declarations
*/
-struct pcmciadevs *pcmcia_probedev __P((struct pcmcia_link *));
-struct pcmciadevs *pcmcia_selectdev __P((char *, char *, char *, char *));
-int pcmcia_probe_bus __P((struct pcmcia_link *, int, int,
- struct pcmcia_conf *));
+int pcmcia_probedev __P((struct pcmcia_link *, struct pcmcia_cardinfo *));
+int pcmcia_probe_bus __P((int, int));
int pcmciabusmatch __P((struct device *, void *, void *));
void pcmciabusattach __P((struct device *, struct device *, void *));
+int pcmcia_mapcard __P((struct pcmcia_link *, int, struct pcmcia_conf *));
-struct cfdriver pcmciabuscd = {
- NULL, "pcmcia", pcmciabusmatch, pcmciabusattach, DV_DULL,
- sizeof(struct pcmciabus_softc), 1
-};
-
-#ifdef notyet
-int
-pcmcia_add_device(devs)
- struct pcmciadevs *devs;
-{
- int i;
-
- if (devs == NULL)
- return 0;
+int pcmcia_unconfigure __P((struct pcmcia_link *));
+int pcmcia_unmapcard __P((struct pcmcia_link *));
- for (i = 0; i < KNOWNSIZE; i++)
- if (knowndevs[i] == NULL)
- break;
+int pcmcia_print __P((void *, char *));
+int pcmcia_submatch __P((struct device *, void *, void *));
+void pcmcia_probe_link __P((struct pcmcia_link *));
- if (i == KNOWNSIZE)
- panic("Too many pcmcia devices");
+struct cfattach pcmcia_ca = {
+ sizeof(struct pcmciabus_softc), pcmciabusmatch, pcmciabusattach,
+};
- knowndevs[i] = devs;
- for (; devs->devname != NULL; devs++)
- printf("added %s\n", devs->devname);
- return i;
-}
-#endif
+struct cfdriver pcmcia_cd = {
+ NULL, "pcmcia", DV_DULL, 1
+};
+#if 0
int
pcmcia_register(adapter_softc, bus_link, chip_link, slot)
void *adapter_softc;
@@ -178,6 +133,7 @@ pcmcia_register(adapter_softc, bus_link, chip_link, slot)
}
return 0;
}
+#endif
int
pcmciabusmatch(parent, self, aux)
@@ -187,18 +143,16 @@ pcmciabusmatch(parent, self, aux)
{
struct pcmciabus_softc *sc = (void *)self;
struct cfdata *cf = sc->sc_dev.dv_cfdata;
- int i, found = 0;
+ struct pcmciabus_attach_args *pba = aux;
+ struct pcmcia_adapter *pca = pba->pba_aux;
+ int found = 0;
- PPRINTF(("- pcmciabusmatch\n"));
- if (pcmcia_cntrl <= 0)
- return 0;
+ PPRINTF(("- pcmciabusmatch %p %p\n", pba, pca));
- for (i = 0; i < 4; i++)
- if (pcmcia_drivers[i].bus_link) {
- if (PCMCIA_BUS_INIT(&pcmcia_drivers[i], parent, cf,
- aux, &pcmcia_drivers[i], 0))
- found++;
- }
+ if (pca->bus_link) {
+ if (PCMCIA_BUS_INIT(pca, parent, cf, aux, pca, 0))
+ found++;
+ }
return found != 0;
}
@@ -214,19 +168,18 @@ pcmciabusattach(parent, self, aux)
{
struct pcmciabus_softc *sc = (struct pcmciabus_softc *) self;
struct cfdata *cf = self->dv_cfdata;
- int i, found = 0;
+ struct pcmciabus_attach_args *pba = aux;
+ struct pcmcia_adapter *pca = pba->pba_aux;
PPRINTF(("- pcmciabusattach\n"));
- for (i = 0; i < 4; i++)
- if (pcmcia_drivers[i].bus_link) {
- if (PCMCIA_BUS_INIT(&pcmcia_drivers[i], parent, cf,
- aux, &pcmcia_drivers[i], 1))
- found++;
- }
-
+ if (pca->bus_link) {
+ PCMCIA_BUS_INIT(pca, parent, cf, aux, pca, 1);
+ }
printf("\n");
- pcmcia_probe_bus(NULL, sc->sc_dev.dv_unit, -1, NULL);
+ sc->sc_driver = pca;
+ sc->sc_bc = pba->pba_bc;
+ pcmcia_probe_bus(sc->sc_dev.dv_unit, -1);
}
/*
@@ -239,52 +192,52 @@ pcmcia_probe_busses(bus, slot)
{
PPRINTF(("- pcmcia_probe_busses\n"));
if (bus == -1) {
- for (bus = 0; bus < pcmciabuscd.cd_ndevs; bus++)
- if (pcmciabuscd.cd_devs[bus])
- pcmcia_probe_bus(NULL, bus, slot, NULL);
+ for (bus = 0; bus < pcmciabus_cd.cd_ndevs; bus++)
+ if (pcmciabus_cd.cd_devs[bus])
+ pcmcia_probe_bus(bus, slot);
return 0;
} else {
- return pcmcia_probe_bus(NULL, bus, slot, NULL);
+ return pcmcia_probe_bus(bus, slot);
}
}
+/* Macros to clear/set/test flags. */
+#define SET(t, f) (t) |= (f)
+#define CLR(t, f) (t) &= ~(f)
+#define ISSET(t, f) ((t) & (f))
+
/*
* Probe the requested pcmcia bus. It must be already set up.
*/
int
-pcmcia_probe_bus(link, bus, slot, cf)
- struct pcmcia_link *link;
+pcmcia_probe_bus(bus, slot)
int bus, slot;
- struct pcmcia_conf *cf;
{
struct pcmciabus_softc *pcmcia;
- int maxslot, minslot, maxlun, minlun;
- struct pcmciadevs *bestmatch = NULL;
- int spec_probe = (link != NULL);
+ int maxslot, minslot;
+ struct pcmcia_link *link;
PPRINTF(("- pcmcia_probe_bus\n"));
- if (bus < 0 || bus >= pcmciabuscd.cd_ndevs)
+ if (bus < 0 || bus >= pcmciabus_cd.cd_ndevs)
return ENXIO;
- pcmcia = pcmciabuscd.cd_devs[bus];
- if (!pcmcia)
+ pcmcia = pcmciabus_cd.cd_devs[bus];
+ if (!pcmcia || pcmcia->sc_driver == NULL) /* bus is not configured */
return ENXIO;
if (slot == -1) {
- maxslot = 7;
+ maxslot = pcmcia->sc_driver->nslots - 1;
minslot = 0;
} else {
- if (slot < 0 || slot > 7)
+ if (slot < 0 || slot >= pcmcia->sc_driver->nslots)
return EINVAL;
maxslot = minslot = slot;
}
for (slot = minslot; slot <= maxslot; slot++) {
- if (link = pcmcia->sc_link[slot]) {
+ if ((link = pcmcia->sc_link[slot])) {
if (link->devp)
continue;
}
- if (pcmcia_drivers[slot >> 1].adapter_softc == NULL)
- continue;
/*
* If we presently don't have a link block
@@ -297,88 +250,91 @@ pcmcia_probe_bus(link, bus, slot, cf)
return ENOMEM;
bzero(link, sizeof(*link));
link->opennings = 1;
- link->adapter = &pcmcia_drivers[slot >> 1];
+ link->adapter = pcmcia->sc_driver;
+ link->bus = pcmcia;
link->slot = slot;
}
- bestmatch = pcmcia_probedev(link);
- /*
- * We already know what the device is. We use a
- * special matching routine which insists that the
- * cfdata is of the right type rather than putting
- * more intelligence in individual match routines for
- * each high-level driver.
- * We must have the final probe do all of the comparisons,
- * or we could get stuck in an infinite loop trying the same
- * device repeatedly. We use the `fordriver' field of
- * the pcmcia_link for now, rather than inventing a new
- * structure just for the config_search().
- */
- if (link->fordriver == NULL) {
- if (bestmatch)
- link->fordriver = bestmatch->devname;
- else {
- if (!spec_probe) {
- link->device = NULL;
- link->devp = NULL;
- PCMCIA_SERVICE(link->adapter,
- link, PCMCIA_OP_POWER,
- 0, 0);
- }
- }
- }
+ (void) pcmcia_probe_link(link);
+ }
+ return 0;
+}
- if (spec_probe) {
- if (cf && pcmcia_mapcard(link, -1, cf) != 0)
- link->fordriver = NULL;
- }
+void
+pcmcia_probe_link(link)
+ struct pcmcia_link *link;
+{
+ struct pcmcia_cardinfo cardinfo;
+ struct pcmcia_attach_args paa;
+ struct pcmciabus_softc *pcmcia = link->bus;
+ int i;
- if (link->fordriver != NULL) {
- int i;
- struct device **delp = deldevs;
- int found = 0;
- link->device = bestmatch;
- link->flags = (link->flags &
- ~(PCMCIA_ATTACH_TYPE)) |
- PCMCIA_REATTACH;
- for (i = 0; i < ndeldevs; i++, delp++) {
- if (*delp &&
- pcmcia_configure((*delp)->dv_parent, *delp,
- link)) {
- link->flags = (link->flags &
- ~PCMCIA_ATTACH_TYPE)
- | PCMCIA_SLOT_INUSE;
- found = 1;
- *delp = NULL;
- break;
- }
- }
- if (!found) {
- link->flags = (link->flags &
- ~PCMCIA_ATTACH_TYPE) | PCMCIA_ATTACH;
- if (PCMCIA_BUS_SEARCH(link->adapter,
- &pcmcia->sc_dev,
- link, NULL)) {
- link->flags = (link->flags &
- ~PCMCIA_ATTACH_TYPE)
- | PCMCIA_SLOT_INUSE;
- } else {
- link->flags &= ~(PCMCIA_ATTACH_TYPE |
- PCMCIA_SLOT_INUSE);
- link->device = NULL;
- printf(
- "No matching config entry %s.\n",
- link->fordriver ?
- link->fordriver : "(NULL)");
- if (!spec_probe)
- PCMCIA_SERVICE(link->adapter,
- link,
- PCMCIA_OP_POWER,
- 0, 0);
- }
+ PPRINTF(("- pcmcia_probe_link %p\n", link));
+ /*
+ * Set up card and fetch card info.
+ */
+ if (pcmcia_probedev(link, &cardinfo) == 0) {
+ /* could not fetch its strings, so give up on it. */
+ PCMCIA_SERVICE(link->adapter,
+ link, PCMCIA_OP_POWER,
+ 0, 0);
+ return;
+ }
+
+ /*
+ * See if we can reattach a device.
+ */
+ CLR(link->flags, PCMCIA_ATTACH_TYPE);
+ SET(link->flags, PCMCIA_REATTACH);
+ for (i = 0; i < ndeldevs; i++) {
+ if (deldevs[i].dev) {
+ PPRINTF(("trying device\n"));
+ link->device = deldevs[i].pcdev;
+ if (pcmcia_configure(deldevs[i].dev->dv_parent,
+ deldevs[i].dev, link)) {
+ CLR(link->flags, PCMCIA_ATTACH_TYPE);
+ SET(link->flags, PCMCIA_SLOT_INUSE);
+ deldevs[i].dev = NULL;
+ deldevs[i].pcdev = NULL;
+ return;
}
}
}
- return 0;
+
+
+ paa.paa_cardinfo = &cardinfo;
+ paa.paa_link = link;
+ paa.paa_aux = NULL;
+ paa.paa_bestmatch = 0;
+ paa.paa_matchonly = 1;
+ CLR(link->flags, PCMCIA_ATTACH_TYPE);
+ SET(link->flags, PCMCIA_ATTACH);
+
+ /* Run the config matching routines to find us a good match.
+ * match routines will flag on "matchonly" and fill in stuff
+ * into the link structure, but not return any match.
+ */
+ (void) config_found_sm(&pcmcia->sc_dev,
+ &paa,
+ pcmcia_print,
+ pcmcia_submatch);
+
+ if (PCMCIA_BUS_SEARCH(link->adapter,
+ &pcmcia->sc_dev,
+ link, NULL)) {
+ CLR(link->flags, PCMCIA_ATTACH_TYPE);
+ SET(link->flags, PCMCIA_SLOT_INUSE);
+ } else {
+ CLR(link->flags, PCMCIA_ATTACH_TYPE|PCMCIA_SLOT_INUSE);
+ link->device = NULL;
+ printf("%s slot %d: No matching config entry.\n",
+ pcmcia->sc_dev.dv_xname,
+ link->slot);
+ PCMCIA_SERVICE(link->adapter,
+ link, PCMCIA_OP_POWER,
+ 0, 0);
+ link->fordriver = NULL;
+ }
+ return;
}
/*
@@ -386,16 +342,13 @@ pcmcia_probe_bus(link, bus, slot, cf)
* it is, and find the correct driver table
* entry.
*/
-struct pcmciadevs *
-pcmcia_probedev(link)
+int
+pcmcia_probedev(link, cardinfo)
struct pcmcia_link *link;
+ struct pcmcia_cardinfo *cardinfo;
{
struct pcmcia_adapter *pca = link->adapter;
u_char scratch[CIS_MAXSIZE];
- char manu[MAX_CIS_NAMELEN];
- char model[MAX_CIS_NAMELEN];
- char add_inf1[MAX_CIS_NAMELEN];
- char add_inf2[MAX_CIS_NAMELEN];
int card_stat;
int err;
int pow = 0;
@@ -403,22 +356,22 @@ pcmcia_probedev(link)
PPRINTF(("- pcmcia_probe_dev\n"));
- printf("%s slot %d:",
- ((struct device *) link->adapter->adapter_softc)->dv_xname,
- slot & 1);
+ printf("%s: slot %d ", ((struct device *) link->bus)->dv_xname, slot);
+ /* turn off power in case it's on, to get a fresh start on things: */
+ PCMCIA_SERVICE(pca, link, PCMCIA_OP_POWER, 0, 0);
if ((err = PCMCIA_SERVICE(pca, link, PCMCIA_OP_STATUS,
&card_stat, 0)) != 0) {
printf("failed to get status %d\n", err);
return NULL;
}
- if ((card_stat & PCMCIA_CARD_PRESENT) == 0) {
- printf(" <slot empty>\n");
+ if (ISSET(card_stat, PCMCIA_CARD_PRESENT) == 0) {
+ printf("is empty\n");
return NULL;
}
- if (!(card_stat & PCMCIA_POWER)) {
+ if (!ISSET(card_stat, PCMCIA_POWER)) {
pow = 1;
if ((err = PCMCIA_SERVICE(pca, link, PCMCIA_OP_POWER, 10000,
PCMCIA_POWER_ON|
@@ -428,7 +381,7 @@ pcmcia_probedev(link)
}
}
- if (!(link->flags & (PCMCIA_SLOT_INUSE | CARD_IS_MAPPED))) {
+ if (!ISSET(link->flags, (PCMCIA_SLOT_INUSE | CARD_IS_MAPPED))) {
if ((err = PCMCIA_SERVICE(pca, link, PCMCIA_OP_RESET,
500000, 0)) != 0) {
printf("failed to reset %d\n", err);
@@ -446,127 +399,25 @@ pcmcia_probedev(link)
}
if ((err = pcmcia_get_cisver1(link, scratch, sizeof(scratch),
- manu, model, add_inf1,
- add_inf2)) != 0) {
+ cardinfo->manufacturer,
+ cardinfo->model, cardinfo->add_info1,
+ cardinfo->add_info2)) != 0) {
printf("failed to get cis info %d\n", err);
goto bad;
}
- printf(" <%s, %s", manu, model);
- if (add_inf1[0])
- printf(", %s", add_inf1);
- if (add_inf2[0])
- printf(", %s", add_inf2);
+ printf("contains <%s, %s", cardinfo->manufacturer, cardinfo->model);
+ if (cardinfo->add_info1[0])
+ printf(", %s", cardinfo->add_info1);
+ if (cardinfo->add_info2[0])
+ printf(", %s", cardinfo->add_info2);
printf(">\n");
-
- /*
- * Try make as good a match as possible with
- * available sub drivers
- */
- return pcmcia_selectdev(manu, model, add_inf1, add_inf2);
+ return 1;
bad:
if (!pow)
PCMCIA_SERVICE(pca, link, PCMCIA_OP_POWER, 0, 0);
- return NULL;
-}
-
-/*
- * Try make as good a match as possible with
- * available sub drivers
- */
-struct pcmciadevs *
-pcmcia_selectdev(manu, model, add_inf1, add_inf2)
- char *manu, *model, *add_inf1, *add_inf2;
-{
- u_int bestmatches = 0;
- struct pcmciadevs *bestmatch = (struct pcmciadevs *) 0;
- struct pcmciadevs **dlist, *dentry;
-
- PPRINTF(("- pcmcia_selectdev\n"));
- for (dlist = knowndevs; *dlist; dlist++)
- for (dentry = *dlist; dentry &&
- dentry->devname != NULL; dentry++) {
- int match = 0;
-
-#ifdef PCMCIA_DEBUG
- dentry->flags |= PC_SHOWME;
-#endif
- match|=pcmcia_strcmp(dentry->manufacturer,
- manu,dentry->flags,"manufacturer")<<6;
- match|=pcmcia_strcmp(dentry->model,
- model,dentry->flags,"model")<<4;
- match|=pcmcia_strcmp(dentry->add_inf1,
- add_inf1,dentry->flags,"info1")<<2;
- match|=pcmcia_strcmp(dentry->add_inf2,
- add_inf2,dentry->flags,"info2");
-/* the following was replaced by the wildcard function called above */
-#if 0
- if (dentry->flags & PC_SHOWME)
- printf("manufacturer = `%s'-`%s'\n",
- dentry->manufacturer ?
- dentry->manufacturer :
- "X",
- manu);
- if (dentry->manufacturer) {
- if (strcmp(dentry->manufacturer, manu) == 0) {
- match |= 8;
- } else {
- continue;
- }
- }
-
- if (dentry->flags & PC_SHOWME)
- printf("model = `%s'-`%s'\n",
- dentry->model ? dentry->model :
- "X",
- model);
- if (dentry->model) {
- if (strcmp(dentry->model, model) == 0) {
- match |= 4;
- } else {
- continue;
- }
- }
-
-
- if (dentry->flags & PC_SHOWME)
- printf("info1 = `%s'-`%s'\n",
- dentry->add_inf1 ? dentry->add_inf1 :
- "X",
- add_inf1);
- if (dentry->add_inf1) {
- if (strcmp(dentry->add_inf1, add_inf1) == 0) {
- match |= 2;
- } else {
- continue;
- }
- }
-
- if (dentry->flags & PC_SHOWME)
- printf("info2 = `%s'-`%s'\n",
- dentry->add_inf2 ? dentry->add_inf2 :
- "X",
- add_inf2);
- if (dentry->add_inf2) {
- if (strcmp(dentry->add_inf2, add_inf2) == 0) {
- match |= 1;
- } else {
- continue;
- }
- }
-#endif
-#ifdef PCMCIA_DEBUG
- printf("match == %d [%d]\n",match,bestmatches);
-#endif
-
- if(match > bestmatches) {
- bestmatches = match;
- bestmatch = dentry;
- }
- }
-
- return bestmatch;
+ return 0;
}
int
@@ -579,26 +430,29 @@ pcmcia_configure(parent, self, aux)
struct pcmcia_link *link = aux;
struct cfdata *cf = dev->dv_cfdata;
struct cfdriver *cd = cf->cf_driver;
- char *devname = (char *) link->fordriver;
struct pcmciadevs *pcs = link->device;
struct pcmcia_device *pcd;
struct pcmcia_adapter *pca = link->adapter;
struct pcmcia_conf pc_cf;
+ char *devname = (char *) link->fordriver;
u_char scratch[CIS_MAXSIZE];
int mymap = 0;
PPRINTF(("- pcmcia_configure\n"));
- if (strcmp(devname, cd->cd_name) || !pca)
+ if ((devname && strcmp(devname, cd->cd_name)) || !pca)
return 0;
+ if (link->devp)
+ return 0; /* something else already attached */
+
if (pcs == NULL)
pcd = NULL;
else
pcd = pcs->dev;
- PPRINTF(("pcmcia_configure: %x\n", pcd));
- if (!(link->flags & CARD_IS_MAPPED)) {
+ PPRINTF(("pcmcia_configure: %p\n", pcd));
+ if (!ISSET(link->flags, CARD_IS_MAPPED)) {
/* read 'suggested' configuration */
PPRINTF(("pcmcia_configure: calling read cis\n"));
if (pcmcia_read_cis(link, scratch, 0, sizeof(scratch)) != 0)
@@ -615,8 +469,9 @@ pcmcia_configure(parent, self, aux)
#endif
/* and modify it (device specific) */
if (pcd && pcd->pcmcia_config) {
- PPRINTF(("pcmcia_configure: calling config\n"));
- if (pcd->pcmcia_config(link, dev, &pc_cf, cf))
+ PPRINTF(("pcmcia_configure: calling config %p %p\n",
+ pcd, pcd->pcmcia_config));
+ if ((*pcd->pcmcia_config)(link, dev, &pc_cf, cf))
return 0;
if ((pc_cf.cfgtype & CFGENTRYMASK) == CFGENTRYID) {
@@ -649,7 +504,7 @@ pcmcia_configure(parent, self, aux)
}
link->devp = dev;
- PPRINTF(("pcmcia_configure: calling bus probe\n"));
+ PPRINTF(("pcmcia_configure: calling bus attach\n"));
if (!(PCMCIA_BUS_PROBE(pca, parent, dev, cf, link))) {
PPRINTF(("pcmcia_configure: bus probe failed\n"));
goto bad;
@@ -660,39 +515,34 @@ pcmcia_configure(parent, self, aux)
goto bad;
}
- link->shuthook = shutdownhook_establish(pcmcia_shuthook,
- (void *)link);
return 1;
bad:
link->devp = NULL;
if (mymap)
pcmcia_unmapcard(link);
- printf("pcmcia_configure: configuration error\n");
+ PPRINTF(("pcmcia_configure: configuration error\n"));
return 0;
}
void
-pcmcia_shuthook(arg)
-void *arg;
+pcmcia_detach(dev, arg)
+ struct device *dev;
+ void *arg;
{
- struct pcmcia_link *link = (struct pcmcia_link *)arg;
- if (pcmcia_unconfigure(link) == 0) {
- /*
- * turn off power too.
- */
- PCMCIA_SERVICE(link->adapter, link, PCMCIA_OP_RESET, 500000, 0);
- PCMCIA_SERVICE(link->adapter, link, PCMCIA_OP_POWER, 0, 0);
- }
+ struct pcmcia_link *link = arg;
+
+ link->devp = NULL;
+ printf("%s: device %s at slot %d detached/really\n",
+ dev->dv_parent->dv_xname,
+ dev->dv_xname, link->slot);
}
int
pcmcia_unconfigure(link)
struct pcmcia_link *link;
{
- int status;
- int i, err;
- struct device **delp;
+ int i;
struct device *dev;
struct pcmcia_adapter *pca = link->adapter;
struct pcmcia_device *pcd;
@@ -706,9 +556,9 @@ pcmcia_unconfigure(link)
else
pcd = NULL;
- if (link->flags & CARD_IS_MAPPED) {
+ if (ISSET(link->flags, CARD_IS_MAPPED)) {
if (pcd && pcd->pcmcia_remove) {
- if (pcd->pcmcia_remove(link, link->devp))
+ if ((*pcd->pcmcia_remove)(link, link->devp))
return EBUSY;
}
else {
@@ -718,39 +568,56 @@ pcmcia_unconfigure(link)
if (pcmcia_unmapcard(link) != 0)
return EBUSY;
}
- delp = deldevs;
- for (i = 0; delp && *delp && i < ndeldevs; i++, delp++)
- continue;
- if (i >= ndeldevs) {
- int sz = ndeldevs ? (ndeldevs * 2) :
- (MINALLOCSIZE / sizeof(void *));
- struct device **ndel = malloc(sz * sizeof(void *),
- M_DEVBUF, M_NOWAIT);
- if (!ndel) {
- PPRINTF(("pcmcia_delete: creating dev array"));
- return ENOMEM;
- }
- bzero(ndel, sz * sizeof(void *));
- if (ndeldevs) {
- bcopy(deldevs, ndel, ndeldevs * sizeof(void *));
- free(deldevs, M_DEVBUF);
+ if (config_detach(link->devp->dv_cfdata, pcmcia_detach, link)) {
+ /* must be retained */
+ for (i = 0; deldevs && deldevs[i].dev && i < ndeldevs; i++)
+ continue;
+
+ if (i >= ndeldevs) {
+ int sz = ndeldevs ? (ndeldevs * 2) :
+ (MINALLOCSIZE / sizeof(deldevs[0]));
+ struct old_devs *ndel = malloc(sz * sizeof(deldevs[0]),
+ M_DEVBUF, M_NOWAIT);
+ if (!ndel) {
+ PPRINTF(("pcmcia_delete: creating dev array"));
+ return ENOMEM;
+ }
+ bzero(ndel, sz * sizeof(ndel[0]));
+ if (ndeldevs) {
+ bcopy(deldevs, ndel,
+ ndeldevs * sizeof(deldevs[0]));
+ free(deldevs, M_DEVBUF);
+ }
+ ndeldevs = sz - 1;
+ deldevs = ndel;
}
- ndeldevs = sz - 1;
- deldevs = ndel;
- delp = deldevs + i;
+ dev = deldevs[i].dev = link->devp;
+ deldevs[i].pcdev = link->device;
+ link->devp = NULL;
+ TAILQ_REMOVE(&alldevs, dev, dv_list);
+ printf("%s: device %s at slot %d detached/retained\n",
+ dev->dv_parent->dv_xname,
+ dev->dv_xname, link->slot);
+ /*
+ * Make this node eligible to probe again.
+ * Since we're indirectly allocating state,
+ * this device data will not get trashed later and we
+ * can hold onto it.
+ */
+/* dev->dv_cfdata->cf_fstate = FSTATE_NOTFOUND;*/
}
- dev = *delp = link->devp;
- link->devp = NULL;
- printf("device %s in pcmcia slot %d detached\n", dev->dv_xname,
- link->slot);
- shutdownhook_disestablish(link->shuthook);
- link->shuthook = 0;
return 0;
}
+/*
+ * Map the card into I/O and memory space, using the details provided
+ * with pc_cf.
+ */
+
int
pcmcia_mapcard(link, unit, pc_cf)
struct pcmcia_link *link;
+ int unit;
struct pcmcia_conf *pc_cf;
{
struct pcmcia_adapter *pca = link->adapter;
@@ -768,6 +635,7 @@ pcmcia_mapcard(link, unit, pc_cf)
splx(s);
for (i = 0; i < pc_cf->memwin; i++) {
if ((err = PCMCIA_MAP_MEM(pca, link,
+ pca->pa_bc,
(caddr_t) pc_cf->mem[i].start,
pc_cf->mem[i].caddr,
pc_cf->mem[i].len,
@@ -797,7 +665,7 @@ pcmcia_mapcard(link, unit, pc_cf)
}
}
/* Now we've mapped everything enable it */
- if ((err = PCMCIA_MAP_MEM(pca, link, SCRATCH_MEM(pca),
+ if ((err = PCMCIA_MAP_MEM(pca, link, SCRATCH_BC(pca), SCRATCH_MEM(pca),
pc_cf->cfg_off & (~(SCRATCH_SIZE(pca) - 1)), SCRATCH_SIZE(pca),
PCMCIA_MAP_ATTR | PCMCIA_LAST_WIN)) != 0) {
PPRINTF(("pcmcia_mapcard: enable err %d\n", err));
@@ -810,45 +678,59 @@ pcmcia_mapcard(link, unit, pc_cf)
goto error;
}
-#define GETMEM(x) SCRATCH_MEM(pca)[(pc_cf->cfg_off & \
- (SCRATCH_SIZE(pca) - 1)) + x]
- if ((pc_cf->cfgtype & DOSRESET)) {
- GETMEM(0) = PCMCIA_SRESET;
+#define GETMEM(x) bus_mem_read_1(pca->scratch_bc, SCRATCH_MEM(pca), \
+ (pc_cf->cfg_off & (SCRATCH_SIZE(pca)-1)) + x)
+#define PUTMEM(x,v) \
+ bus_mem_write_1(pca->scratch_bc, SCRATCH_MEM(pca), \
+ (pc_cf->cfg_off & (SCRATCH_SIZE(pca)-1)) + x, v)
+
+ if (ISSET(pc_cf->cfgtype, DOSRESET)) {
+ PUTMEM(0, PCMCIA_SRESET);
delay(50000);
}
- PPRINTF(("CMDR %x\n",((pc_cf->cfgtype & CFGENTRYID) ?
+ PPRINTF(("CMDR %x\n",(ISSET(pc_cf->cfgtype, CFGENTRYID) ?
pc_cf->cfgid |CFGENTRYID:
(pc_cf->cfgtype & CFGENTRYMASK)|1)|
(pc_cf->irq_level ? PCMCIA_LVLREQ : 0)
));
- GETMEM(0) = ((pc_cf->cfgtype & CFGENTRYID) ?
- pc_cf->cfgid |CFGENTRYID:
- (pc_cf->cfgtype & CFGENTRYMASK)|1)|
- (pc_cf->irq_level ? PCMCIA_LVLREQ : 0);
+ PUTMEM(0, (ISSET(pc_cf->cfgtype, CFGENTRYID) ?
+ pc_cf->cfgid |CFGENTRYID:
+ (pc_cf->cfgtype & CFGENTRYMASK)|1)|
+ (pc_cf->irq_level ? PCMCIA_LVLREQ : 0));
delay(50000);
- if (pc_cf->cfg_regmask & (1 << (PCMCIA_SCR / 2)))
- GETMEM(PCMCIA_SCR) = (link->slot & 1) | 0x10;
+ if (ISSET(pc_cf->cfg_regmask, (1 << (PCMCIA_SCR / 2))))
+ PUTMEM(PCMCIA_SCR, (link->slot & 1) | 0x10);
#if 0
DPRINTF(("CCSR %x\n", GETMEM(PCMCIA_CCSR]));
- if (GETMEM(PCMCIA_CCSR] & PCMCIA_POWER_DOWN) {
- GETMEM(PCMCIA_CCSR] &= ~PCMCIA_POWER_DOWN;
- DPRINTF(("CCSR now %x\n", GETMEM(PCMCIA_CCSR]));
+ if (ISSET(GETMEM(PCMCIA_CCSR), PCMCIA_POWER_DOWN)) {
+ u_char val = GETMEM(PCMCIA_CCSR);
+ CLR(val, PCMCIA_POWER_DOWN);
+ PUTMEM(PCMCIA_CCSR, var);
+ DPRINTF(("CCSR now %x\n", GETMEM(PCMCIA_CCSR)));
}
#endif
+
+ PPRINTF(("pcmcia_mapcard: about to initialize...\n"));
+
if ((err = PCMCIA_SERVICE(pca, link, PCMCIA_OP_WAIT,
- 500000, 0)) != 0)
+ 1000, 0)) != 0) {
PPRINTF(("failed to initialize %d\n", err));
+ err = 0; /* XXX */
+ }
error:
- PCMCIA_MAP_MEM(pca, link, 0, 0, 0, PCMCIA_LAST_WIN | PCMCIA_UNMAP);
+ PCMCIA_MAP_MEM(pca, link, SCRATCH_BC(pca), SCRATCH_MEM(pca), 0,
+ SCRATCH_SIZE(pca), PCMCIA_LAST_WIN | PCMCIA_UNMAP);
if (err != 0) {
+ PPRINTF(("pcmcia_mapcard: unmaping\n"));
for (i = 0; i < pc_cf->memwin; i++) {
PCMCIA_MAP_MEM(pca, link,
+ pca->pa_bc,
(caddr_t) pc_cf->mem[i].start,
pc_cf->mem[i].caddr,
pc_cf->mem[i].len,
@@ -863,12 +745,12 @@ error:
PCMCIA_MAP_8)) | i | PCMCIA_UNMAP);
}
PCMCIA_MAP_INTR(pca, link, pc_cf->irq_num, PCMCIA_UNMAP);
- link->flags &= ~CARD_IS_MAPPED;
+ CLR(link->flags, CARD_IS_MAPPED);
link->iowin = 0;
link->memwin = 0;
link->intr = 0;
} else {
- link->flags |= CARD_IS_MAPPED;
+ SET(link->flags, CARD_IS_MAPPED);
link->iowin = pc_cf->iowin;
link->memwin = pc_cf->memwin;
link->intr = pc_cf->irq_num;
@@ -891,14 +773,15 @@ pcmcia_unmapcard(link)
return ENODEV;
for (i = 0; i < link->memwin; i++)
- PCMCIA_MAP_MEM(pca, link, 0, 0, 0, (i | PCMCIA_UNMAP));
+ PCMCIA_MAP_MEM(pca, link, pca->pa_bc, 0, 0, 0,
+ (i | PCMCIA_UNMAP));
for (i = 0; i < link->iowin; i++)
PCMCIA_MAP_IO(pca, link, 0, 0, (i | PCMCIA_UNMAP));
PCMCIA_MAP_INTR(pca, link, link->intr, PCMCIA_UNMAP);
- PCMCIA_SERVICE(pca, link, PCMCIA_OP_RESET, 0, 0);
- link->flags &= ~(CARD_IS_MAPPED | PCMCIA_SLOT_INUSE);
+ PCMCIA_SERVICE(pca, link, PCMCIA_OP_RESET, 50000, 0);
+ CLR(link->flags, (CARD_IS_MAPPED | PCMCIA_SLOT_INUSE));
link->iowin = 0;
link->memwin = 0;
link->intr = 0;
@@ -906,30 +789,28 @@ pcmcia_unmapcard(link)
}
-static int
+int
pcmcia_mapcard_and_configure(link, unit, pc_cf)
struct pcmcia_link *link;
struct pcmcia_conf *pc_cf;
int unit;
{
- int err;
int mymap = 0;
+ int err;
PPRINTF(("- pcmcia_mapcard_and_configure\n"));
if (pc_cf->driver_name[0][0]) {
-#if 0
if ((err = pcmcia_mapcard(link, unit, pc_cf)) != 0) {
return err;
}
mymap=1;
-#endif
link->fordriver = pc_cf->driver_name[0];
- } else {
+ } else
link->fordriver = NULL;
- pc_cf = NULL;
- }
- pcmcia_probe_bus(link, 0, link->slot, pc_cf);
- if ((link->flags & PCMCIA_SLOT_INUSE) == 0) {
+
+ pcmcia_probe_link(link);
+
+ if (!ISSET(link->flags, PCMCIA_SLOT_INUSE)) {
if (mymap)
pcmcia_unmapcard(link);
return ENODEV;
@@ -952,7 +833,7 @@ pcmcia_read_cis(link, scratch, offs, len)
int size = SCRATCH_SIZE(pca);
volatile int *inuse = &SCRATCH_INUSE(pca);
- PPRINTF(("- pcmcia_read_cis\n"));
+ PPRINTF(("- pcmcia_read_cis: mem %p size %d\n", p, size));
if (pca == NULL)
return ENXIO;
@@ -968,15 +849,18 @@ pcmcia_read_cis(link, scratch, offs, len)
int tlen = min(len + toff, size / 2) - toff;
int i;
- if ((err = PCMCIA_MAP_MEM(pca, link, p, pgoff, size,
+ if ((err = PCMCIA_MAP_MEM(pca, link, pca->pa_bc, p, pgoff,
+ size,
PCMCIA_MAP_ATTR |
PCMCIA_LAST_WIN)) != 0)
goto error;
+ PPRINTF(("- pcmcia_read_cis: mem mapped\n"));
+
for (i = 0; i < tlen; j++, i++)
scratch[j] = p[toff + i * 2];
- PCMCIA_MAP_MEM(pca, link, p, 0, size,
+ PCMCIA_MAP_MEM(pca, link, pca->pa_bc, p, 0, size,
PCMCIA_LAST_WIN | PCMCIA_UNMAP);
len -= tlen;
}
@@ -986,21 +870,25 @@ error:
wakeup((caddr_t) inuse);
splx(s);
+ PPRINTF(("- pcmcia_read_cis return %d\n", err));
return err;
}
/* here we start our pseudodev for controlling the slots */
#define PCMCIABUS_UNIT(a) (minor(a))
-#define PCMCIABUS_SLOT(a) (a&0x7)
-#define PCMCIABUS_CHIPIID(a) (a&0x3)
-#define PCMCIABUS_CHIP 0x10
-#define PCMCIABUS_BUS 0x20
+#define PCMCIABUS_SLOT(a) (a&0x3) /* per-controller */
+#define PCMCIABUS_SLOTID(a) (a&0xf) /* system-wide assignment */
+#define PCMCIABUS_CHIPNO(a) ((a&0xf)>>2)
+#define PCMCIABUS_CHIPID(a) (a&0x3)
+#define PCMCIABUS_CHIP 0x40
+#define PCMCIABUS_BUS 0x80
+#define PCMCIABUS_BUSID(a) (a&0x3)
#define PCMCIABUS_DEVTYPE(a) ((a)&(PCMCIABUS_CHIP|PCMCIABUS_BUS))
static int busopen = 0;
static int chipopen[4] = {0, 0, 0, 0};
int
-pcmciabusopen(dev, flag, mode, p)
+pcmciaopen(dev, flag, mode, p)
dev_t dev;
int flag, mode;
struct proc *p;
@@ -1011,8 +899,6 @@ pcmciabusopen(dev, flag, mode, p)
struct pcmciabus_softc *pcmcia;
PPRINTF(("- pcmciabusopen\n"));
- if (pcmcia_cntrl == 0)
- return ENXIO;
switch (PCMCIABUS_DEVTYPE(unit)) {
case PCMCIABUS_BUS:
if (unit != PCMCIABUS_BUS)
@@ -1023,10 +909,11 @@ pcmciabusopen(dev, flag, mode, p)
break;
case PCMCIABUS_CHIP:
- chipid = PCMCIABUS_CHIPIID(unit);
- if (chipid > 3)
+ chipid = PCMCIABUS_CHIPID(unit);
+ if (chipid < 0 || chipid >= pcmciabus_cd.cd_ndevs)
return ENXIO;
- if (pcmcia_drivers[chipid].adapter_softc == NULL)
+ pcmcia = pcmciabus_cd.cd_devs[chipid];
+ if (pcmcia == NULL || pcmcia->sc_driver == NULL)
return ENXIO;
if (chipopen[chipid])
@@ -1037,20 +924,22 @@ pcmciabusopen(dev, flag, mode, p)
case 0:
slot = PCMCIABUS_SLOT(unit);
- chipid = slot >> 1;
+ chipid = PCMCIABUS_CHIPNO(unit);
- if (chipid > 7)
+ if (chipid < 0 || chipid >= pcmciabus_cd.cd_ndevs)
return ENXIO;
- if (pcmcia_drivers[chipid].adapter_softc == NULL)
+ pcmcia = pcmciabus_cd.cd_devs[chipid];
+ if (pcmcia == NULL || pcmcia->sc_driver == NULL)
return ENXIO;
- pcmcia = pcmciabuscd.cd_devs[0];
link = pcmcia->sc_link[slot];
+ if (!link)
+ return ENXIO;
- if (link->flags & PCMCIA_SLOT_OPEN)
+ if (ISSET(link->flags, PCMCIA_SLOT_OPEN))
return EBUSY;
- link->flags |= PCMCIA_SLOT_OPEN;
+ SET(link->flags, PCMCIA_SLOT_OPEN);
break;
default:
@@ -1062,7 +951,7 @@ pcmciabusopen(dev, flag, mode, p)
int
-pcmciabusclose(dev)
+pcmciaclose(dev)
{
int unit = PCMCIABUS_UNIT(dev);
int chipid, slot;
@@ -1071,25 +960,24 @@ pcmciabusclose(dev)
int s;
PPRINTF(("- pcmciabusclose\n"));
- if (pcmcia_cntrl == 0)
- return ENXIO;
switch (PCMCIABUS_DEVTYPE(unit)) {
case PCMCIABUS_BUS:
busopen = 0;
break;
case PCMCIABUS_CHIP:
- chipid = PCMCIABUS_CHIPIID(unit);
+ chipid = PCMCIABUS_CHIPID(unit);
chipopen[chipid] = 0;
break;
case 0:
slot = PCMCIABUS_SLOT(unit);
- pcmcia = pcmciabuscd.cd_devs[0];
+ chipid = PCMCIABUS_CHIPNO(unit);
+ pcmcia = pcmciabus_cd.cd_devs[chipid];
link = pcmcia->sc_link[slot];
s = splclock();
- link->flags &= ~(PCMCIA_SLOT_OPEN|PCMCIA_SLOT_EVENT);
+ CLR(link->flags, (PCMCIA_SLOT_OPEN|PCMCIA_SLOT_EVENT));
splx(s);
break;
@@ -1104,8 +992,8 @@ pcmciachip_ioctl(chipid, cmd, data)
int chipid, cmd;
caddr_t data;
{
- int err = 0;
- struct pcmcia_adapter *pca = &pcmcia_drivers[chipid];
+ struct pcmciabus_softc *pcmcia = pcmciabus_cd.cd_devs[chipid];
+ struct pcmcia_adapter *pca = pcmcia->sc_driver;
struct pcmcia_link link;
struct pcmcia_regs *pi = (void *) data;
@@ -1117,7 +1005,7 @@ pcmciachip_ioctl(chipid, cmd, data)
case PCMCIAIO_READ_REGS:
pi->chip = chipid;
link.adapter = pca;
- link.slot = chipid << 1;
+ link.slot = 0;
return PCMCIA_SERVICE(pca, &link, PCMCIA_OP_GETREGS,
pi->chip_data, 0);
}
@@ -1131,7 +1019,9 @@ pcmciaslot_ioctl(link, slotid, cmd, data)
caddr_t data;
{
int err = 0;
- struct pcmcia_adapter *pca = &pcmcia_drivers[slotid >> 1];
+ struct pcmciabus_softc *pcmcia =
+ pcmciabus_cd.cd_devs[PCMCIABUS_CHIPNO(slotid)];
+ struct pcmcia_adapter *pca = pcmcia->sc_driver;
PPRINTF(("- pcmciaslot_ioctl\n"));
if (link == NULL || pca->chip_link == NULL ||
@@ -1147,10 +1037,10 @@ pcmciaslot_ioctl(link, slotid, cmd, data)
err = PCMCIA_SERVICE(pca, link, PCMCIA_OP_STATUS,
&pi->status, 0);
if (!err) {
- pi->status |= ((link->flags & CARD_IS_MAPPED) ?
- PCMCIA_CARD_IS_MAPPED : 0) |
- ((link->flags & PCMCIA_SLOT_INUSE) ?
- PCMCIA_CARD_INUSE : 0);
+ if (ISSET(link->flags, CARD_IS_MAPPED))
+ SET(pi->status, PCMCIA_CARD_IS_MAPPED);
+ if (ISSET(link->flags, PCMCIA_SLOT_INUSE))
+ SET(pi->status, PCMCIA_CARD_INUSE);
}
return err;
}
@@ -1163,7 +1053,7 @@ pcmciaslot_ioctl(link, slotid, cmd, data)
if ((err = PCMCIA_SERVICE(pca, link, PCMCIA_OP_STATUS,
&status, 0)) != 0)
return err;
- if ((status & PCMCIA_CARD_PRESENT) == 0)
+ if (!ISSET(status, PCMCIA_CARD_PRESENT))
return ENODEV;
pi->slot = slotid;
return pcmcia_read_cis(link, pi->cis_data, 0,
@@ -1180,6 +1070,8 @@ pcmciaslot_ioctl(link, slotid, cmd, data)
return pcmcia_unconfigure(link);
case PCMCIAIO_UNMAP:
+ if (ISSET(link->flags, PCMCIA_SLOT_INUSE))
+ return EBUSY;
return pcmcia_unmapcard(link);
case PCMCIAIO_SET_POWER:
@@ -1226,11 +1118,11 @@ pcmciaslot_ioctl(link, slotid, cmd, data)
&status, 0);
if (err)
return err;
- if ((status & PCMCIA_CARD_PRESENT) == 0)
+ if (!ISSET(status, PCMCIA_CARD_PRESENT))
return ENODEV;
- if (status = pcmcia_read_cis(link, pi->cis_data, 0,
- CIS_MAXSIZE))
+ if ((status = pcmcia_read_cis(link, pi->cis_data, 0,
+ CIS_MAXSIZE)))
return status;
bzero(&pc_cf, sizeof(pc_cf));
@@ -1246,7 +1138,9 @@ pcmciaslot_ioctl(link, slotid, cmd, data)
SCRATCH_INUSE(pca) = 1;
splx(s);
- if ((err = PCMCIA_MAP_MEM(pca, link, SCRATCH_MEM(pca),
+ if ((err = PCMCIA_MAP_MEM(pca, link,
+ SCRATCH_BC(pca),
+ SCRATCH_MEM(pca),
pc_cf.cfg_off &
~(SCRATCH_SIZE(pca)-1),
SCRATCH_SIZE(pca),
@@ -1264,7 +1158,9 @@ pcmciaslot_ioctl(link, slotid, cmd, data)
}
*d++ = 0xff;
*d++ = 0xff;
- PCMCIA_MAP_MEM(pca, link, SCRATCH_MEM(pca),
+ PCMCIA_MAP_MEM(pca, link,
+ SCRATCH_BC(pca),
+ SCRATCH_MEM(pca),
0,SCRATCH_SIZE(pca),
PCMCIA_LAST_WIN|PCMCIA_UNMAP);
}
@@ -1281,49 +1177,56 @@ pcmciaslot_ioctl(link, slotid, cmd, data)
}
int
-pcmciabusioctl(dev, cmd, data, flag, p)
+pcmciaioctl(dev, cmd, data, flag, p)
dev_t dev;
int cmd;
caddr_t data;
int flag;
struct proc *p;
{
- int unit = PCMCIABUS_UNIT(dev);
+ int unit = PCMCIABUS_UNIT(dev);
+ int chipid = PCMCIABUS_CHIPNO(unit);
struct pcmciabus_softc *pcmcia;
struct pcmcia_link *link;
- PPRINTF(("- pcmciabus_ioctl\n"));
- pcmcia = pcmciabuscd.cd_devs[0];
- if (pcmcia_cntrl == 0 || pcmcia == NULL)
+ PPRINTF(("- pcmciabusioctl\n"));
+ if (chipid < 0 || chipid >= pcmciabus_cd.cd_ndevs)
return ENXIO;
+
+ pcmcia = pcmciabus_cd.cd_devs[chipid];
+ if (pcmcia == NULL)
+ return ENXIO;
+
switch (PCMCIABUS_DEVTYPE(unit)) {
#if 0
case PCMCIABUS_BUS:
- return pcmciabus_ioctl(0, cmd, data);
+ return pcmciabus_ioctl(PCMCIABUS_BUSID(unit), cmd, data);
#endif
case PCMCIABUS_CHIP:
- return pcmciachip_ioctl(PCMCIABUS_CHIPIID(unit), cmd, data);
+ return pcmciachip_ioctl(PCMCIABUS_CHIPID(unit), cmd, data);
case 0:
link = pcmcia->sc_link[PCMCIABUS_SLOT(unit)];
- return pcmciaslot_ioctl(link, PCMCIABUS_SLOT(unit), cmd, data);
+ return pcmciaslot_ioctl(link, PCMCIABUS_SLOTID(unit),
+ cmd, data);
default:
return ENXIO;
}
}
int
-pcmciabusselect(device, rw, p)
+pcmciaselect(device, rw, p)
dev_t device;
int rw;
struct proc *p;
{
int s;
int unit = PCMCIABUS_UNIT(device);
+ int chipid = PCMCIABUS_CHIPNO(unit);
struct pcmciabus_softc *pcmcia;
struct pcmcia_link *link;
- PPRINTF(("- pcmciabus_ioctl\n"));
- pcmcia = pcmciabuscd.cd_devs[0];
+ PPRINTF(("- pcmciabus_select\n"));
+ pcmcia = pcmciabus_cd.cd_devs[chipid];
switch (PCMCIABUS_DEVTYPE(unit)) {
case 0:
@@ -1335,14 +1238,14 @@ pcmciabusselect(device, rw, p)
return 0;
}
- s = splclock(); /* XXX something higher than all devices that can plug in.... */
+ s = splpcmcia();
switch (rw) {
case FREAD:
case FWRITE:
break;
case 0:
- if (link->flags & PCMCIA_SLOT_EVENT) {
- link->flags &= ~PCMCIA_SLOT_EVENT;
+ if (ISSET(link->flags, PCMCIA_SLOT_EVENT)) {
+ CLR(link->flags, PCMCIA_SLOT_EVENT);
splx(s);
return 1;
}
@@ -1354,54 +1257,14 @@ pcmciabusselect(device, rw, p)
}
int
-pcmciabusmmap()
+pcmciammap()
{
return ENXIO;
}
-/* pcmcia template string match. A '*' matches any number of characters.
- A NULL template matches all strings.
- return-value
- 0 nomatch
- 1 wildcard match
- 2 excact match
- */
-static int
-pcmcia_strcmp(templ,val,flags,msg)
- char *templ;
- char *val;
- int flags;
- char *msg;
-{
- char *ltempl=NULL,*lval=NULL;
-
- if (flags & PC_SHOWME)
- printf("%s = `%s'-`%s'\n", msg, templ ? templ : "X", val);
-
- if(templ==NULL)
- return 1;
- while(*val) {
- while(*templ=='*') {
- ltempl=++templ;
- lval=val;
- }
- if(*templ==*val) {
- templ++;
- val++;
- } else {
- if(ltempl==NULL)
- return 0;
- val=++lval;
- templ=ltempl;
- }
- }
- if(*templ!=0 && *templ!='*')
- return 0;
- return ltempl?1:2;
-}
#ifdef PCMCIA_DEBUG
-static void
+void
pcmciadumpcf(cf)
struct pcmcia_conf * cf;
{
@@ -1414,6 +1277,7 @@ pcmciadumpcf(cf)
printf("IRQ type %s%s\n", cf->irq_level ? "Level " : "",
cf->irq_pulse ? "Pulse" : "");
printf("IRQ num %x\n", cf->irq_num);
+ printf("IRQ mask %x\n", cf->irq_mask);
printf("CFG type %x %x\n", cf->cfgtype,cf->cfgid);
printf("Cardtype %s\n", cf->iocard ? "IO" : "MEM");
for (i = 0; i < cf->iowin; i++) {
@@ -1431,3 +1295,43 @@ pcmciadumpcf(cf)
}
}
#endif
+
+int
+pcmcia_print(aux, pnp)
+ void *aux;
+ char *pnp;
+{
+#if 0
+ struct pcmcia_attach_args *paa = aux;
+ printf(" slot %d", paa->paa_link->slot);
+#endif
+ return (0); /* be silent */
+}
+
+/*
+ * Filter out inappropriate configurations before heading off to
+ * the device match routines.
+ */
+int
+pcmcia_submatch(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct device *self = match;
+ struct cfdata *cf = self->dv_cfdata;
+ struct pcmcia_attach_args *paa = aux;
+ struct pcmcia_link *link = paa->paa_link;
+
+#if 0
+ printf("pcmcia_submatch: paa=%p link=%p, cf=%p\n", paa, link, cf);
+ delay(2000000);
+
+#endif
+
+ if (cf->cf_loc[6] != -1 && link->slot != cf->cf_loc[6]) {
+ printf("slot mismatch: %d cf_loc %d\n", link->slot, cf->cf_loc[6]);
+ return 0;
+ }
+
+ return ((*cf->cf_attach->ca_match)(parent, match, aux));
+}