[PATCH] pcmcia: always use device pointer to config_t

Update the remaining users using the static lookup table of the PCMCIA
function configuration to use the struct pcmcia_device-contained pointer.

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

diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index f889a44..88c96ae 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -126,10 +126,9 @@
 extern struct rw_semaphore pcmcia_socket_list_rwsem;
 extern struct list_head pcmcia_socket_list;
 int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req);
-int pccard_get_configuration_info(struct pcmcia_socket *s, unsigned int function, config_info_t *config);
+int pccard_get_configuration_info(struct pcmcia_socket *s, struct pcmcia_device *p_dev, config_info_t *config);
 int pccard_reset_card(struct pcmcia_socket *skt);
-int pccard_get_status(struct pcmcia_socket *s, unsigned int function, cs_status_t *status);
-int pccard_access_configuration_register(struct pcmcia_socket *s, unsigned int function, conf_reg_t *reg);
+int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, cs_status_t *status);
 
 
 struct pcmcia_callback{
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 80969f7..56b625d 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -70,10 +70,26 @@
 #define ds_dbg(lvl, fmt, arg...) do { } while (0)
 #endif
 
+static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
+						unsigned int function)
+{
+	struct pcmcia_device *p_dev = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+	list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
+		if (p_dev->func == function) {
+			spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+			return pcmcia_get_dev(p_dev);
+		}
+	}
+	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+	return NULL;
+}
 
 /* backwards-compatible accessing of driver --- by name! */
 
-static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info)
+static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info)
 {
 	struct device_driver *drv;
 	struct pcmcia_driver *p_drv;
@@ -583,9 +599,11 @@
 	if (buf->config.Function &&
 	   (buf->config.Function >= s->functions))
 	    ret = CS_BAD_ARGS;
-	else
-	    ret = pccard_get_configuration_info(s,
-			buf->config.Function, &buf->config);
+	else {
+	    struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
+	    ret = pccard_get_configuration_info(s, p_dev, &buf->config);
+	    pcmcia_put_dev(p_dev);
+	}
 	break;
     case DS_GET_FIRST_TUPLE:
 	down(&s->skt_sem);
@@ -609,12 +627,15 @@
 	ret = pccard_reset_card(s);
 	break;
     case DS_GET_STATUS:
-	if (buf->status.Function &&
-	   (buf->status.Function >= s->functions))
-	    ret = CS_BAD_ARGS;
-	else
-	ret = pccard_get_status(s, buf->status.Function, &buf->status);
-	break;
+	    if (buf->status.Function &&
+		(buf->status.Function >= s->functions))
+		    ret = CS_BAD_ARGS;
+	    else {
+		    struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
+		    ret = pccard_get_status(s, p_dev, &buf->status);
+		    pcmcia_put_dev(p_dev);
+	    }
+	    break;
     case DS_VALIDATE_CIS:
 	down(&s->skt_sem);
 	pcmcia_validate_mem(s);
@@ -638,12 +659,16 @@
 	    err = -EPERM;
 	    goto free_out;
 	}
-	if (buf->conf_reg.Function &&
-	   (buf->conf_reg.Function >= s->functions))
-	    ret = CS_BAD_ARGS;
-	else
-	    ret = pccard_access_configuration_register(s,
-			buf->conf_reg.Function, &buf->conf_reg);
+
+	ret = CS_BAD_ARGS;
+
+	if (!(buf->conf_reg.Function &&
+	     (buf->conf_reg.Function >= s->functions))) {
+		struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
+		if (p_dev)
+			ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
+		pcmcia_put_dev(p_dev);
+	}
 	break;
     case DS_GET_FIRST_REGION:
     case DS_GET_NEXT_REGION:
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 11a94d9..aabde8b 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -165,21 +165,19 @@
  * this and the tuple reading services.
  */
 
-int pccard_access_configuration_register(struct pcmcia_socket *s,
-					 unsigned int function,
+int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
 					 conf_reg_t *reg)
 {
+	struct pcmcia_socket *s;
 	config_t *c;
 	int addr;
 	u_char val;
 
-	if (!s || !s->config)
+	if (!p_dev || !p_dev->function_config)
 		return CS_NO_CARD;
 
-	c = &s->config[function];
-
-	if (c == NULL)
-		return CS_NO_CARD;
+	s = p_dev->socket;
+	c = p_dev->function_config;
 
 	if (!(c->state & CONFIG_LOCKED))
 		return CS_CONFIGURATION_LOCKED;
@@ -200,20 +198,12 @@
 		break;
 	}
 	return CS_SUCCESS;
-} /* pccard_access_configuration_register */
-
-int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
-					 conf_reg_t *reg)
-{
-	return pccard_access_configuration_register(p_dev->socket,
-						    p_dev->func, reg);
-}
+} /* pcmcia_access_configuration_register */
 EXPORT_SYMBOL(pcmcia_access_configuration_register);
 
 
-
 int pccard_get_configuration_info(struct pcmcia_socket *s,
-				  unsigned int function,
+				  struct pcmcia_device *p_dev,
 				  config_info_t *config)
 {
 	config_t *c;
@@ -221,7 +211,7 @@
 	if (!(s->state & SOCKET_PRESENT))
 		return CS_NO_CARD;
 
-	config->Function = function;
+	config->Function = p_dev->func;
 
 #ifdef CONFIG_CARDBUS
 	if (s->state & SOCKET_CARDBUS) {
@@ -242,7 +232,7 @@
 	}
 #endif
 
-	c = (s->config != NULL) ? &s->config[function] : NULL;
+	c = (p_dev) ? p_dev->function_config : NULL;
 
 	if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
 		config->Attributes = 0;
@@ -271,7 +261,7 @@
 int pcmcia_get_configuration_info(struct pcmcia_device *p_dev,
 				  config_info_t *config)
 {
-	return pccard_get_configuration_info(p_dev->socket, p_dev->func,
+	return pccard_get_configuration_info(p_dev->socket, p_dev,
 					     config);
 }
 EXPORT_SYMBOL(pcmcia_get_configuration_info);
@@ -317,7 +307,7 @@
  * SocketState yet: I haven't seen any point for it.
  */
 
-int pccard_get_status(struct pcmcia_socket *s, unsigned int function,
+int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev,
 		      cs_status_t *status)
 {
 	config_t *c;
@@ -334,7 +324,8 @@
 	if (!(s->state & SOCKET_PRESENT))
 		return CS_NO_CARD;
 
-	c = (s->config != NULL) ? &s->config[function] : NULL;
+	c = (p_dev) ? p_dev->function_config : NULL;
+
 	if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
 	    (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
 		u_char reg;
@@ -370,9 +361,9 @@
 	return CS_SUCCESS;
 } /* pccard_get_status */
 
-int pcmcia_get_status(client_handle_t handle, cs_status_t *status)
+int pcmcia_get_status(struct pcmcia_device *p_dev, cs_status_t *status)
 {
-	return pccard_get_status(handle->socket, handle->func, status);
+	return pccard_get_status(p_dev->socket, p_dev, status);
 }
 EXPORT_SYMBOL(pcmcia_get_status);