X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fpcmcia%2Fpcmcia_ioctl.c;h=13a7132cf6885577bbb096e24e87dd32d3fee754;hb=d801c1409ef7d45339cbe8ac9de28ade6ed4699a;hp=d4c3f9aa3d837c7b949809c6e4f5c3cd1a2aea6d;hpb=3f9c5f4cb7e00d424a56a6431e9c98b3b17851e4;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index d4c3f9a..13a7132 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -38,7 +39,6 @@ #include #include "cs_internal.h" -#include "ds_internal.h" static int major_dev = -1; @@ -58,31 +58,19 @@ typedef struct user_info_t { } user_info_t; -#ifdef CONFIG_PCMCIA_DEBUG -extern int ds_pc_debug; - -#define ds_dbg(lvl, fmt, arg...) do { \ - if (ds_pc_debug >= lvl) \ - printk(KERN_DEBUG "ds: " fmt , ## arg); \ -} while (0) -#else -#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); + 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; } @@ -99,44 +87,47 @@ static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info) 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 *d) +static int proc_read_drivers_callback(struct device_driver *driver, void *_m) { - char **p = d; + struct seq_file *m = _m; struct pcmcia_driver *p_drv = container_of(driver, struct pcmcia_driver, drv); - *p += sprintf(*p, "%-24.24s 1 %d\n", p_drv->drv.name, + seq_printf(m, "%-24.24s 1 %d\n", p_drv->drv.name, #ifdef CONFIG_MODULE_UNLOAD (p_drv->owner) ? module_refcount(p_drv->owner) : 1 #else 1 #endif ); - d = (void *) p; - return 0; } -static int proc_read_drivers(char *buf, char **start, off_t pos, - int count, int *eof, void *data) +static int pccard_drivers_proc_show(struct seq_file *m, void *v) { - char *p = buf; - int rc; - - rc = bus_for_each_drv(&pcmcia_bus_type, NULL, - (void *) &p, proc_read_drivers_callback); - if (rc < 0) - return rc; + return bus_for_each_drv(&pcmcia_bus_type, NULL, + m, proc_read_drivers_callback); +} - return (p - buf); +static int pccard_drivers_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, pccard_drivers_proc_show, NULL); } + +static const struct file_operations pccard_drivers_proc_fops = { + .owner = THIS_MODULE, + .open = pccard_drivers_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif @@ -166,7 +157,8 @@ static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) #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; } @@ -176,7 +168,6 @@ static int pcmcia_adjust_resource_info(adjust_t *adj) { 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) { @@ -189,21 +180,20 @@ static int pcmcia_adjust_resource_info(adjust_t *adj) /* 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; @@ -215,17 +205,71 @@ static int pcmcia_adjust_resource_info(adjust_t *adj) * 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 @@ -287,7 +331,7 @@ static int pccard_get_status(struct pcmcia_socket *s, return 0; } /* pccard_get_status */ -int pccard_get_configuration_info(struct pcmcia_socket *s, +static int pccard_get_configuration_info(struct pcmcia_socket *s, struct pcmcia_device *p_dev, config_info_t *config) { @@ -422,13 +466,12 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info) struct pcmcia_driver *p_drv; struct pcmcia_device *p_dev; int ret = 0; - unsigned long flags; s = pcmcia_get_socket(s); if (!s) return -EINVAL; - ds_dbg(2, "bind_request(%d, '%s')\n", s->sock, + pr_debug("bind_request(%d, '%s')\n", s->sock, (char *)bind_info->dev_info); p_drv = get_pcmcia_driver(&bind_info->dev_info); @@ -442,8 +485,8 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info) 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) { @@ -451,7 +494,7 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info) * 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; @@ -459,7 +502,7 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info) /* 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; @@ -468,12 +511,12 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info) /* 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) { @@ -511,7 +554,7 @@ rescan: err_put: pcmcia_put_socket(s); - return (ret); + return ret; } /* bind_request */ #ifdef CONFIG_CARDBUS @@ -530,7 +573,6 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int dev_node_t *node; struct pcmcia_device *p_dev; struct pcmcia_driver *p_drv; - unsigned long flags; int ret = 0; #ifdef CONFIG_CARDBUS @@ -569,7 +611,7 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int } #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); @@ -578,11 +620,11 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int 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) { @@ -608,7 +650,7 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int err_put: pcmcia_put_dev(p_dev); - return (ret); + return ret; } /* get_device_info */ @@ -617,10 +659,10 @@ static int ds_open(struct inode *inode, struct file *file) 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; - ds_dbg(0, "ds_open(socket %d)\n", i); + pr_debug("ds_open(socket %d)\n", i); lock_kernel(); s = pcmcia_get_socket_by_nr(i); @@ -682,7 +724,7 @@ static int ds_release(struct inode *inode, struct file *file) struct pcmcia_socket *s; user_info_t *user, **link; - ds_dbg(0, "ds_release(socket %d)\n", iminor(inode)); + pr_debug("ds_release(socket %d)\n", iminor(inode)); user = file->private_data; if (CHECK_USER(user)) @@ -691,12 +733,13 @@ static int ds_release(struct inode *inode, struct file *file) 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; @@ -716,7 +759,7 @@ static ssize_t ds_read(struct file *file, char __user *buf, user_info_t *user; int ret; - ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode)); + pr_debug("ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode)); if (count < 4) return -EINVAL; @@ -727,7 +770,7 @@ static ssize_t ds_read(struct file *file, char __user *buf, s = user->socket; if (s->pcmcia_state.dead) - return -EIO; + return -EIO; ret = wait_event_interruptible(s->queue, !queue_empty(user)); if (ret == 0) @@ -741,7 +784,7 @@ static ssize_t ds_read(struct file *file, char __user *buf, static ssize_t ds_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode)); + pr_debug("ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode)); if (count != 4) return -EINVAL; @@ -759,7 +802,7 @@ static u_int ds_poll(struct file *file, poll_table *wait) struct pcmcia_socket *s; user_info_t *user; - ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode)); + pr_debug("ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode)); user = file->private_data; if (CHECK_USER(user)) @@ -777,7 +820,7 @@ static u_int ds_poll(struct file *file, poll_table *wait) /*====================================================================*/ -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; @@ -787,7 +830,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, ds_ioctl_arg_t *buf; user_info_t *user; - ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg); + pr_debug("ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg); user = file->private_data; if (CHECK_USER(user)) @@ -795,10 +838,11 @@ static int ds_ioctl(struct inode * inode, struct file * file, 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)) @@ -806,13 +850,13 @@ static int ds_ioctl(struct inode * inode, struct file * file, if (cmd & IOC_IN) { if (!access_ok(VERIFY_READ, uarg, size)) { - ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT); + pr_debug("ds_ioctl(): verify_read = %d\n", -EFAULT); return -EFAULT; } } if (cmd & IOC_OUT) { if (!access_ok(VERIFY_WRITE, uarg, size)) { - ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT); + pr_debug("ds_ioctl(): verify_write = %d\n", -EFAULT); return -EFAULT; } } @@ -859,10 +903,10 @@ static int ds_ioctl(struct inode * inode, struct file * file, break; case DS_PARSE_TUPLE: buf->tuple.TupleData = buf->tuple_parse.data; - ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse); + ret = pcmcia_parse_tuple(&buf->tuple, &buf->tuple_parse.parse); break; case DS_RESET_CARD: - ret = pccard_reset_card(s); + ret = pcmcia_reset_card(s); break; case DS_GET_STATUS: if (buf->status.Function && @@ -878,19 +922,19 @@ static int ds_ioctl(struct inode * inode, struct file * file, mutex_lock(&s->skt_mutex); pcmcia_validate_mem(s); mutex_unlock(&s->skt_mutex); - ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo.Chains); + 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)) { @@ -916,26 +960,23 @@ static int ds_ioctl(struct inode * inode, struct file * file, err = -EPERM; goto free_out; } else { - static int printed = 0; - if (!printed) { - printk(KERN_WARNING "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n"); - printk(KERN_WARNING "MTD handling any more.\n"); - printed++; - } + printk_once(KERN_WARNING + "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n"); + printk_once(KERN_WARNING "MTD handling any more.\n"); } err = -EINVAL; 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(buf->win_info.handle, + ret = pcmcia_get_mem_page(s, buf->win_info.handle, &buf->win_info.map); break; case DS_REPLACE_CIS: @@ -962,7 +1003,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, } if ((err == 0) && (ret != 0)) { - ds_dbg(2, "ds_ioctl: ret = %d\n", ret); + pr_debug("ds_ioctl: ret = %d\n", ret); switch (ret) { case -ENODEV: case -EINVAL: @@ -980,8 +1021,8 @@ static int ds_ioctl(struct inode * inode, struct file * file, } 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: @@ -1001,7 +1042,8 @@ static const struct file_operations ds_fops = { .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 */ @@ -1015,12 +1057,13 @@ void __init pcmcia_setup_ioctl(void) { #ifdef CONFIG_PROC_FS proc_pccard = proc_mkdir("bus/pccard", NULL); if (proc_pccard) - create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL); + proc_create("drivers", 0, proc_pccard, &pccard_drivers_proc_fops); #endif } -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);