[RFC PATCH 5/11] pcmcia updates (post 2.6.16): add pcmcia_disable_device()

Dominik Brodowski linux at dominikbrodowski.net
Sun Jan 15 14:12:02 EST 2006


Subject: [PATCH] pcmcia: add pcmcia_disable_device
From: Dominik Brodowski <linux at dominikbrodowski.net>
Date: 1137313959 +0100

pcmcia_disable_device(struct pcmcia_device *p_dev) performs the necessary
cleanups upon device or driver removal: it calls the appropriate
pcmcia_release_* functions, and can replace (most) of the current drivers'
_release() functions.

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

---

 Documentation/pcmcia/driver-changes.txt |    6 +++
 drivers/bluetooth/bluecard_cs.c         |    8 ---
 drivers/bluetooth/bt3c_cs.c             |    8 ---
 drivers/bluetooth/btuart_cs.c           |    8 ---
 drivers/bluetooth/dtl1_cs.c             |    8 ---
 drivers/char/pcmcia/cm4000_cs.c         |    3 -
 drivers/char/pcmcia/cm4040_cs.c         |    3 -
 drivers/char/pcmcia/synclink_cs.c       |   10 ----
 drivers/ide/legacy/ide-cs.c             |    8 ---
 drivers/isdn/hardware/avm/avm_cs.c      |   12 +----
 drivers/isdn/hisax/avma1_cs.c           |   17 ++-----
 drivers/isdn/hisax/elsa_cs.c            |   10 ----
 drivers/isdn/hisax/sedlbauer_cs.c       |   17 -------
 drivers/isdn/hisax/teles_cs.c           |   10 ----
 drivers/net/pcmcia/3c574_cs.c           |    8 ---
 drivers/net/pcmcia/3c589_cs.c           |    8 ---
 drivers/net/pcmcia/axnet_cs.c           |    8 ---
 drivers/net/pcmcia/com20020_cs.c        |   12 +----
 drivers/net/pcmcia/fmvj18x_cs.c         |   12 +----
 drivers/net/pcmcia/ibmtr_cs.c           |   23 ++++------
 drivers/net/pcmcia/nmclan_cs.c          |   10 +---
 drivers/net/pcmcia/pcnet_cs.c           |   15 ++-----
 drivers/net/pcmcia/smc91c92_cs.c        |   21 +++------
 drivers/net/pcmcia/xirc2ps_cs.c         |   22 +++-------
 drivers/net/wireless/airo_cs.c          |   19 --------
 drivers/net/wireless/atmel_cs.c         |   21 +++------
 drivers/net/wireless/hostap/hostap_cs.c |   11 -----
 drivers/net/wireless/netwave_cs.c       |   19 +++-----
 drivers/net/wireless/orinoco_cs.c       |    8 ---
 drivers/net/wireless/spectrum_cs.c      |    8 ---
 drivers/net/wireless/wavelan_cs.c       |   18 +++-----
 drivers/net/wireless/wl3501_cs.c        |   10 +---
 drivers/parport/parport_cs.c            |   26 ++++-------
 drivers/pcmcia/pcmcia_resource.c        |   71 ++++++++++++++++++-------------
 drivers/scsi/pcmcia/aha152x_stub.c      |    8 ---
 drivers/scsi/pcmcia/fdomain_stub.c      |   17 ++-----
 drivers/scsi/pcmcia/nsp_cs.c            |   11 +----
 drivers/scsi/pcmcia/qlogic_stub.c       |    9 +---
 drivers/scsi/pcmcia/sym53c500_cs.c      |    8 ---
 drivers/serial/serial_cs.c              |    7 +--
 include/pcmcia/cs.h                     |    2 +
 sound/pcmcia/pdaudiocf/pdaudiocf.c      |    8 ---
 sound/pcmcia/vx/vxpocket.c              |    8 ---
 43 files changed, 154 insertions(+), 402 deletions(-)

Full patch at:
http://kernel.org/git/?p=linux/kernel/git/brodo/pcmcia-2.6.git;a=commit;h=936a48bb6155abe236cdec3a73319f1da0769726


5475d199e89af7aae4782cf379fad976de9069c5
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt
index 97420f0..c89a5e2 100644
--- a/Documentation/pcmcia/driver-changes.txt
+++ b/Documentation/pcmcia/driver-changes.txt
@@ -1,5 +1,11 @@
 This file details changes in 2.6 which affect PCMCIA card driver authors:
 
+* New release helper (as of 2.6.17)
+   Instead of calling pcmcia_release_{configuration,io,irq,win}, all that's
+   necessary now is calling pcmcia_disable_device. As there is no valid
+   reason left to call pcmcia_release_io and pcmcia_release_irq, they will
+   be removed soon.
+
 * Unify detach and REMOVAL event code, as well as attach and INSERTION
   code (as of 2.6.16)
        void (*remove)          (struct pcmcia_device *dev);
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 9888bc1..128e416 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -1002,13 +1002,7 @@ static void bluecard_release(dev_link_t 
 
 	del_timer(&(info->timer));
 
-	link->dev = NULL;
-
-	pcmcia_release_configuration(link->handle);
-	pcmcia_release_io(link->handle, &link->io);
-	pcmcia_release_irq(link->handle, &link->irq);
-
-	link->state &= ~DEV_CONFIG;
+	pcmcia_disable_device(link->handle);
 }
 
 static int bluecard_suspend(struct pcmcia_device *dev)
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index dbd5571..555c869 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -451,20 +451,20 @@ int pcmcia_release_configuration(struct 
 {
 	pccard_io_map io = { 0, 0, 0, 0, 1 };
 	struct pcmcia_socket *s = p_dev->socket;
+	config_t *c = p_dev->function_config;
 	int i;
 
-	if (!(p_dev->state & CLIENT_CONFIG_LOCKED))
-		return CS_BAD_HANDLE;
-	p_dev->state &= ~CLIENT_CONFIG_LOCKED;
-
-	if (!(p_dev->state & CLIENT_STALE)) {
-		config_t *c = p_dev->function_config;
+	if (p_dev->state & CLIENT_CONFIG_LOCKED) {
+		p_dev->state &= ~CLIENT_CONFIG_LOCKED;
 		if (--(s->lock_count) == 0) {
 			s->socket.flags = SS_OUTPUT_ENA;   /* Is this correct? */
 			s->socket.Vpp = 0;
 			s->socket.io_irq = 0;
 			s->ops->set_socket(s, &s->socket);
 		}
+	}
+	if (c->state & CONFIG_LOCKED) {
+		c->state &= ~CONFIG_LOCKED;
 		if (c->state & CONFIG_IO_REQ)
 			for (i = 0; i < MAX_IO_WIN; i++) {
 				if (!s->io[i].res)
@@ -475,7 +475,6 @@ int pcmcia_release_configuration(struct 
 				io.map = i;
 				s->ops->set_io_map(s, &io);
 			}
-		c->state &= ~CONFIG_LOCKED;
 	}
 
 	return CS_SUCCESS;
@@ -494,22 +493,20 @@ EXPORT_SYMBOL(pcmcia_release_configurati
 int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
 {
 	struct pcmcia_socket *s = p_dev->socket;
+	config_t *c = p_dev->function_config;
 
 	if (!(p_dev->state & CLIENT_IO_REQ))
 		return CS_BAD_HANDLE;
+
 	p_dev->state &= ~CLIENT_IO_REQ;
 
-	if (!(p_dev->state & CLIENT_STALE)) {
-		config_t *c = p_dev->function_config;
-		if (c->state & CONFIG_LOCKED)
-			return CS_CONFIGURATION_LOCKED;
-		if ((c->io.BasePort1 != req->BasePort1) ||
-		    (c->io.NumPorts1 != req->NumPorts1) ||
-		    (c->io.BasePort2 != req->BasePort2) ||
-		    (c->io.NumPorts2 != req->NumPorts2))
-			return CS_BAD_ARGS;
-		c->state &= ~CONFIG_IO_REQ;
-	}
+	if ((c->io.BasePort1 != req->BasePort1) ||
+	    (c->io.NumPorts1 != req->NumPorts1) ||
+	    (c->io.BasePort2 != req->BasePort2) ||
+	    (c->io.NumPorts2 != req->NumPorts2))
+		return CS_BAD_ARGS;
+
+	c->state &= ~CONFIG_IO_REQ;
 
 	release_io_space(s, req->BasePort1, req->NumPorts1);
 	if (req->NumPorts2)
@@ -523,22 +520,21 @@ EXPORT_SYMBOL(pcmcia_release_io);
 int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
 {
 	struct pcmcia_socket *s = p_dev->socket;
+	config_t *c= p_dev->function_config;
+
 	if (!(p_dev->state & CLIENT_IRQ_REQ))
 		return CS_BAD_HANDLE;
 	p_dev->state &= ~CLIENT_IRQ_REQ;
 
-	if (!(p_dev->state & CLIENT_STALE)) {
-		config_t *c= p_dev->function_config;
-		if (c->state & CONFIG_LOCKED)
-			return CS_CONFIGURATION_LOCKED;
-		if (c->irq.Attributes != req->Attributes)
-			return CS_BAD_ATTRIBUTE;
-		if (s->irq.AssignedIRQ != req->AssignedIRQ)
-			return CS_BAD_IRQ;
-		if (--s->irq.Config == 0) {
-			c->state &= ~CONFIG_IRQ_REQ;
-			s->irq.AssignedIRQ = 0;
-		}
+	if (c->state & CONFIG_LOCKED)
+		return CS_CONFIGURATION_LOCKED;
+	if (c->irq.Attributes != req->Attributes)
+		return CS_BAD_ATTRIBUTE;
+	if (s->irq.AssignedIRQ != req->AssignedIRQ)
+		return CS_BAD_IRQ;
+	if (--s->irq.Config == 0) {
+		c->state &= ~CONFIG_IRQ_REQ;
+		s->irq.AssignedIRQ = 0;
 	}
 
 	if (req->Attributes & IRQ_HANDLE_PRESENT) {
@@ -929,3 +925,18 @@ int pcmcia_request_window(struct pcmcia_
 	return CS_SUCCESS;
 } /* pcmcia_request_window */
 EXPORT_SYMBOL(pcmcia_request_window);
+
+void pcmcia_disable_device(struct pcmcia_device *p_dev) {
+	if (!p_dev->instance)
+		return;
+
+	pcmcia_release_configuration(p_dev);
+	pcmcia_release_io(p_dev, &p_dev->instance->io);
+	pcmcia_release_irq(p_dev, &p_dev->instance->irq);
+	if (&p_dev->instance->win)
+		pcmcia_release_window(p_dev->instance->win);
+
+	p_dev->instance->dev = NULL;
+	p_dev->instance->state &= ~DEV_CONFIG;
+}
+EXPORT_SYMBOL(pcmcia_disable_device);
diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h
index eda32a5..a5d8df2 100644
--- a/include/pcmcia/cs.h
+++ b/include/pcmcia/cs.h
@@ -392,6 +392,8 @@ int pcmcia_eject_card(struct pcmcia_sock
 int pcmcia_insert_card(struct pcmcia_socket *skt);
 int pccard_reset_card(struct pcmcia_socket *skt);
 
+void pcmcia_disable_device(struct pcmcia_device *p_dev);
+
 struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt);
 void pcmcia_put_socket(struct pcmcia_socket *skt);
 
-- 
1.1.2



More information about the linux-pcmcia mailing list