[PATCH] pcmcia: use bitfield instead of p_state and state

Instead of the two status values struct pcmcia_device->p_state and state,
use descriptive bitfields. Most value-checking in drivers was invalid, as
the core now only calls the ->remove() (a.k.a. detach) function in case the
attachement _and_ configuration was successful.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>

diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index ecc579b..d6164cd 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -23,7 +23,7 @@
 #define CLIENT_IO_REQ		0x0004
 #define CLIENT_UNBOUND		0x0008
 #define CLIENT_STALE		0x0010
-#define CLIENT_WIN_REQ(i)	(0x20<<(i))
+#define CLIENT_WIN_REQ(i)	(0x1<<(i))
 #define CLIENT_CARDBUS		0x8000
 
 #define REGION_MAGIC	0xE3C9
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 34e634a..8c87343 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -390,8 +390,6 @@
 		goto put_dev;
 	}
 
-	p_dev->p_state &= ~CLIENT_UNBOUND;
-
 	ret = p_drv->probe(p_dev);
 	if (ret)
 		goto put_module;
@@ -433,17 +431,16 @@
 	       	p_drv->remove(p_dev);
 
 	/* check for proper unloading */
-	if (p_dev->p_state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
+	if (p_dev->_irq || p_dev->_io || p_dev->_locked)
 		printk(KERN_INFO "pcmcia: driver %s did not release config properly\n",
 		       p_drv->drv.name);
 
 	for (i = 0; i < MAX_WIN; i++)
-		if (p_dev->p_state & CLIENT_WIN_REQ(i))
+		if (p_dev->_win & CLIENT_WIN_REQ(i))
 			printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n",
 			       p_drv->drv.name);
 
 	/* references from pcmcia_probe_device */
-	p_dev->p_state = CLIENT_UNBOUND;
 	pcmcia_put_dev(p_dev);
 	module_put(p_drv->owner);
 
@@ -472,7 +469,6 @@
 		}
 		p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
 		list_del(&p_dev->socket_device_list);
-		p_dev->p_state |= CLIENT_STALE;
 		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 
 		device_unregister(&p_dev->dev);
@@ -602,9 +598,6 @@
 	sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id);
 
 	/* compat */
-	p_dev->p_state = CLIENT_UNBOUND;
-
-
 	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
 
 	/*
@@ -1033,15 +1026,18 @@
 	if (dev->driver)
 		p_drv = to_pcmcia_drv(dev->driver);
 
-	if (p_drv && p_drv->suspend) {
+	if (!p_drv)
+		goto out;
+
+	if (p_drv->suspend) {
 		ret = p_drv->suspend(p_dev);
 		if (ret)
 			goto out;
-		if ((p_dev->state & DEV_CONFIG) &&
-		    !(p_dev->state & DEV_SUSPEND_NORELEASE))
-			pcmcia_release_configuration(p_dev);
 	}
 
+	if (p_dev->device_no == p_dev->func)
+		pcmcia_release_configuration(p_dev);
+
  out:
 	if (!ret)
 		p_dev->suspended = 1;
@@ -1058,17 +1054,18 @@
 	if (dev->driver)
 		p_drv = to_pcmcia_drv(dev->driver);
 
-	if (p_drv && p_drv->resume) {
-		if ((p_dev->state & DEV_CONFIG) &&
-		    !(p_dev->state & DEV_SUSPEND_NORELEASE)){
-			ret = pcmcia_request_configuration(p_dev,
-							   &p_dev->conf);
-			if (ret)
-				goto out;
-		}
-		ret = p_drv->resume(p_dev);
+	if (!p_drv)
+		goto out;
+
+	if (p_dev->device_no == p_dev->func) {
+		ret = pcmcia_request_configuration(p_dev, &p_dev->conf);
+		if (ret)
+			goto out;
 	}
 
+	if (p_drv->resume)
+		ret = p_drv->resume(p_dev);
+
  out:
 	if (!ret)
 		p_dev->suspended = 0;
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 2b11a332..c53db7c 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -304,6 +304,7 @@
 {
 	dev_node_t *node;
 	struct pcmcia_device *p_dev;
+	struct pcmcia_driver *p_drv;
 	unsigned long flags;
 	int ret = 0;
 
@@ -358,7 +359,8 @@
  found:
 	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 
-	if (p_dev->state & DEV_CONFIG_PENDING) {
+	p_drv = to_pcmcia_drv(p_dev->dev.driver);
+	if (p_drv && !p_dev->_locked) {
 		ret = -EAGAIN;
 		goto err_put;
 	}
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index dbf167c..45063b4 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -476,8 +476,8 @@
 	config_t *c = p_dev->function_config;
 	int i;
 
-	if (p_dev->p_state & CLIENT_CONFIG_LOCKED) {
-		p_dev->p_state &= ~CLIENT_CONFIG_LOCKED;
+	if (p_dev->_locked) {
+		p_dev->_locked = 0;
 		if (--(s->lock_count) == 0) {
 			s->socket.flags = SS_OUTPUT_ENA;   /* Is this correct? */
 			s->socket.Vpp = 0;
@@ -516,10 +516,10 @@
 	struct pcmcia_socket *s = p_dev->socket;
 	config_t *c = p_dev->function_config;
 
-	if (!(p_dev->p_state & CLIENT_IO_REQ))
+	if (!p_dev->_io )
 		return CS_BAD_HANDLE;
 
-	p_dev->p_state &= ~CLIENT_IO_REQ;
+	p_dev->_io = 0;
 
 	if ((c->io.BasePort1 != req->BasePort1) ||
 	    (c->io.NumPorts1 != req->NumPorts1) ||
@@ -542,9 +542,9 @@
 	struct pcmcia_socket *s = p_dev->socket;
 	config_t *c= p_dev->function_config;
 
-	if (!(p_dev->p_state & CLIENT_IRQ_REQ))
+	if (!p_dev->_irq)
 		return CS_BAD_HANDLE;
-	p_dev->p_state &= ~CLIENT_IRQ_REQ;
+	p_dev->_irq = 0;
 
 	if (c->state & CONFIG_LOCKED)
 		return CS_CONFIGURATION_LOCKED;
@@ -576,7 +576,7 @@
 	if ((win == NULL) || (win->magic != WINDOW_MAGIC))
 		return CS_BAD_HANDLE;
 	s = win->sock;
-	if (!(win->handle->p_state & CLIENT_WIN_REQ(win->index)))
+	if (!(win->handle->_win & CLIENT_WIN_REQ(win->index)))
 		return CS_BAD_HANDLE;
 
 	/* Shut down memory window */
@@ -590,7 +590,7 @@
 		kfree(win->ctl.res);
 		win->ctl.res = NULL;
 	}
-	win->handle->p_state &= ~CLIENT_WIN_REQ(win->index);
+	win->handle->_win &= ~CLIENT_WIN_REQ(win->index);
 
 	win->magic = 0;
 
@@ -708,7 +708,7 @@
 	}
 
 	c->state |= CONFIG_LOCKED;
-	p_dev->p_state |= CLIENT_CONFIG_LOCKED;
+	p_dev->_locked = 1;
 	return CS_SUCCESS;
 } /* pcmcia_request_configuration */
 EXPORT_SYMBOL(pcmcia_request_configuration);
@@ -754,7 +754,7 @@
 
 	c->io = *req;
 	c->state |= CONFIG_IO_REQ;
-	p_dev->p_state |= CLIENT_IO_REQ;
+	p_dev->_io = 1;
 	return CS_SUCCESS;
 } /* pcmcia_request_io */
 EXPORT_SYMBOL(pcmcia_request_io);
@@ -850,7 +850,7 @@
 	s->irq.Config++;
 
 	c->state |= CONFIG_IRQ_REQ;
-	p_dev->p_state |= CLIENT_IRQ_REQ;
+	p_dev->_irq = 1;
 
 #ifdef CONFIG_PCMCIA_PROBE
 	pcmcia_used_irq[irq]++;
@@ -910,7 +910,7 @@
 		if (!win->ctl.res)
 			return CS_IN_USE;
 	}
-	(*p_dev)->p_state |= CLIENT_WIN_REQ(w);
+	(*p_dev)->_win |= CLIENT_WIN_REQ(w);
 
 	/* Configure the socket controller */
 	win->ctl.map = w+1;