summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pcmcia/cs_internal.h5
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c57
-rw-r--r--drivers/pcmcia/pcmcia_resource.c39
3 files changed, 58 insertions, 43 deletions
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index f889a44280f5..88c96aee0f45 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -126,10 +126,9 @@ extern struct class_interface pccard_sysfs_interface;
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 80969f7e7a0b..56b625d171ae 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -70,10 +70,26 @@ extern int ds_pc_debug;
#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 @@ static int ds_ioctl(struct inode * inode, struct file * file,
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 @@ static int ds_ioctl(struct inode * inode, struct file * file,
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 @@ static int ds_ioctl(struct inode * inode, struct file * file,
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 11a94d9a15fb..aabde8be6470 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -165,21 +165,19 @@ static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,
* 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 @@ int pccard_access_configuration_register(struct pcmcia_socket *s,
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 @@ int pccard_get_configuration_info(struct pcmcia_socket *s,
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 @@ int pccard_get_configuration_info(struct pcmcia_socket *s,
}
#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 pccard_get_configuration_info(struct pcmcia_socket *s,
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 @@ EXPORT_SYMBOL(pcmcia_get_window);
* 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 @@ int pccard_get_status(struct pcmcia_socket *s, unsigned int function,
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 @@ int pccard_get_status(struct pcmcia_socket *s, unsigned int function,
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);