unsigned int function)
{
struct pcmcia_device *p_dev = NULL;
- unsigned long flags;
- spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+ mutex_lock(&s->ops_mutex);
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);
+ mutex_unlock(&s->ops_mutex);
return pcmcia_get_dev(p_dev);
}
}
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
return NULL;
}
p_drv = container_of(drv, struct pcmcia_driver, drv);
- return (p_drv);
+ return p_drv;
}
#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *proc_pccard = NULL;
+static struct proc_dir_entry *proc_pccard;
static int proc_read_drivers_callback(struct device_driver *driver, void *_m)
{
#else
-static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
+static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
+{
return 0;
}
{
struct pcmcia_socket *s;
int ret = -ENOSYS;
- unsigned long flags;
down_read(&pcmcia_socket_list_rwsem);
list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
/* you can't use the old interface if the new
* one was used before */
- spin_lock_irqsave(&s->lock, flags);
+ mutex_lock(&s->ops_mutex);
if ((s->resource_setup_new) &&
!(s->resource_setup_old)) {
- spin_unlock_irqrestore(&s->lock, flags);
+ mutex_unlock(&s->ops_mutex);
continue;
} else if (!(s->resource_setup_old))
s->resource_setup_old = 1;
- spin_unlock_irqrestore(&s->lock, flags);
switch (adj->Resource) {
case RES_MEMORY_RANGE:
begin = adj->resource.memory.Base;
end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
if (s->resource_ops->add_mem)
- ret =s->resource_ops->add_mem(s, adj->Action, begin, end);
+ ret = s->resource_ops->add_mem(s, adj->Action, begin, end);
case RES_IO_RANGE:
begin = adj->resource.io.BasePort;
end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
* last call to adjust_resource_info, we
* always need to assume this is the latest
* one... */
- spin_lock_irqsave(&s->lock, flags);
s->resource_setup_done = 1;
- spin_unlock_irqrestore(&s->lock, flags);
}
+ mutex_unlock(&s->ops_mutex);
}
}
up_read(&pcmcia_socket_list_rwsem);
- return (ret);
+ return ret;
}
+
+/** pcmcia_get_window
+ */
+static int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *wh_out,
+ window_handle_t wh, win_req_t *req)
+{
+ pccard_mem_map *win;
+ window_handle_t w;
+
+ wh--;
+ if (!s || !(s->state & SOCKET_PRESENT))
+ return -ENODEV;
+ if (wh >= MAX_WIN)
+ return -EINVAL;
+ for (w = wh; w < MAX_WIN; w++)
+ if (s->state & SOCKET_WIN_REQ(w))
+ break;
+ if (w == MAX_WIN)
+ return -EINVAL;
+ win = &s->win[w];
+ req->Base = win->res->start;
+ req->Size = win->res->end - win->res->start + 1;
+ req->AccessSpeed = win->speed;
+ req->Attributes = 0;
+ if (win->flags & MAP_ATTRIB)
+ req->Attributes |= WIN_MEMORY_TYPE_AM;
+ if (win->flags & MAP_ACTIVE)
+ req->Attributes |= WIN_ENABLE;
+ if (win->flags & MAP_16BIT)
+ req->Attributes |= WIN_DATA_WIDTH_16;
+ if (win->flags & MAP_USE_WAIT)
+ req->Attributes |= WIN_USE_WAIT;
+
+ *wh_out = w + 1;
+ return 0;
+} /* pcmcia_get_window */
+
+
+/** pcmcia_get_mem_page
+ *
+ * Change the card address of an already open memory window.
+ */
+static int pcmcia_get_mem_page(struct pcmcia_socket *skt, window_handle_t wh,
+ memreq_t *req)
+{
+ wh--;
+ if (wh >= MAX_WIN)
+ return -EINVAL;
+
+ req->Page = 0;
+ req->CardOffset = skt->win[wh].card_start;
+ return 0;
+} /* pcmcia_get_mem_page */
+
+
/** pccard_get_status
*
* Get the current socket state bits. We don't support the latched
struct pcmcia_driver *p_drv;
struct pcmcia_device *p_dev;
int ret = 0;
- unsigned long flags;
s = pcmcia_get_socket(s);
if (!s)
goto err_put_driver;
}
- spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
- list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
+ mutex_lock(&s->ops_mutex);
+ list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
if (p_dev->func == bind_info->function) {
if ((p_dev->dev.driver == &p_drv->drv)) {
if (p_dev->cardmgr) {
* registered, and it was registered
* by userspace before, we need to
* return the "instance". */
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
bind_info->instance = p_dev;
ret = -EBUSY;
goto err_put_module;
/* the correct driver managed to bind
* itself magically to the correct
* device. */
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
p_dev->cardmgr = p_drv;
ret = 0;
goto err_put_module;
/* there's already a device available where
* no device has been bound to yet. So we don't
* need to register a device! */
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
goto rescan;
}
}
}
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
p_dev = pcmcia_device_add(s, bind_info->function);
if (!p_dev) {
err_put:
pcmcia_put_socket(s);
- return (ret);
+ return ret;
} /* bind_request */
#ifdef CONFIG_CARDBUS
dev_node_t *node;
struct pcmcia_device *p_dev;
struct pcmcia_driver *p_drv;
- unsigned long flags;
int ret = 0;
#ifdef CONFIG_CARDBUS
}
#endif
- spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+ mutex_lock(&s->ops_mutex);
list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
if (p_dev->func == bind_info->function) {
p_dev = pcmcia_get_dev(p_dev);
goto found;
}
}
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
return -ENODEV;
found:
- spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ mutex_unlock(&s->ops_mutex);
p_drv = to_pcmcia_drv(p_dev->dev.driver);
if (p_drv && !p_dev->_locked) {
err_put:
pcmcia_put_dev(p_dev);
- return (ret);
+ return ret;
} /* get_device_info */
socket_t i = iminor(inode);
struct pcmcia_socket *s;
user_info_t *user;
- static int warning_printed = 0;
+ static int warning_printed;
int ret = 0;
pr_debug("ds_open(socket %d)\n", i);
s = user->socket;
/* Unlink user data structure */
- if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+ if ((file->f_flags & O_ACCMODE) != O_RDONLY)
s->pcmcia_state.busy = 0;
- }
+
file->private_data = NULL;
for (link = &s->user; *link; link = &(*link)->next)
- if (*link == user) break;
+ if (*link == user)
+ break;
if (link == NULL)
goto out;
*link = user->next;
s = user->socket;
if (s->pcmcia_state.dead)
- return -EIO;
+ return -EIO;
ret = wait_event_interruptible(s->queue, !queue_empty(user));
if (ret == 0)
/*====================================================================*/
-static int ds_ioctl(struct inode * inode, struct file * file,
+static int ds_ioctl(struct inode *inode, struct file *file,
u_int cmd, u_long arg)
{
struct pcmcia_socket *s;
s = user->socket;
if (s->pcmcia_state.dead)
- return -EIO;
+ return -EIO;
size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
- if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
+ if (size > sizeof(ds_ioctl_arg_t))
+ return -EINVAL;
/* Permission check */
if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
ret = pccard_validate_cis(s, &buf->cisinfo.Chains);
break;
case DS_SUSPEND_CARD:
- ret = pcmcia_suspend_card(s);
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_SUSPEND);
break;
case DS_RESUME_CARD:
- ret = pcmcia_resume_card(s);
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_RESUME);
break;
case DS_EJECT_CARD:
- err = pcmcia_eject_card(s);
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_EJECT);
break;
case DS_INSERT_CARD:
- err = pcmcia_insert_card(s);
+ pcmcia_parse_uevents(s, PCMCIA_UEVENT_INSERT);
break;
case DS_ACCESS_CONFIGURATION_REGISTER:
if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
goto free_out;
break;
case DS_GET_FIRST_WINDOW:
- ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
+ ret = pcmcia_get_window(s, &buf->win_info.handle, 1,
&buf->win_info.window);
break;
case DS_GET_NEXT_WINDOW:
ret = pcmcia_get_window(s, &buf->win_info.handle,
- buf->win_info.handle->index + 1, &buf->win_info.window);
+ buf->win_info.handle + 1, &buf->win_info.window);
break;
case DS_GET_MEM_PAGE:
ret = pcmcia_get_mem_page(s, buf->win_info.handle,
}
if (cmd & IOC_OUT) {
- if (__copy_to_user(uarg, (char *)buf, size))
- err = -EFAULT;
+ if (__copy_to_user(uarg, (char *)buf, size))
+ err = -EFAULT;
}
free_out:
.poll = ds_poll,
};
-void __init pcmcia_setup_ioctl(void) {
+void __init pcmcia_setup_ioctl(void)
+{
int i;
/* Set up character device for user mode clients */
}
-void __exit pcmcia_cleanup_ioctl(void) {
+void __exit pcmcia_cleanup_ioctl(void)
+{
#ifdef CONFIG_PROC_FS
if (proc_pccard) {
remove_proc_entry("drivers", proc_pccard);