From c04edbf2f4194d1f76dd6d0fc5d64600867eae70 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 4 Feb 2013 16:41:30 -0700 Subject: [PATCH] staging: comedi: quatech_daqp_cs: convert to auto attach Convert this pcmcia driver to the comedi auto attach mechanism. This allows getting rid of the static data that held "A list of "instances" of the device" that was used to pass the pcmcia_device pointer from the pcmcia_driver to the comedi_driver. Also, remove the now unused variables in the private data that were used to pass the pcmcia_device. Remove the code that pulled the model number of the card out of the PCMCIA CIS and stashed it in the private data since it is not used in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/quatech_daqp_cs.c | 169 ++++-------------- 1 file changed, 33 insertions(+), 136 deletions(-) diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 2c35d75aef52..64092363fd31 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -62,10 +62,7 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308 #define MAX_DEV 4 struct local_info_t { - struct pcmcia_device *link; int stop; - int table_index; - char board_name[32]; enum { semaphore, buffer } interrupt_mode; @@ -76,10 +73,6 @@ struct local_info_t { int count; }; -/* A list of "instances" of the device. */ - -static struct local_info_t *dev_table[MAX_DEV] = { NULL, /* ... */ }; - /* The DAQP communicates with the system through a 16 byte I/O window. */ #define DAQP_FIFO_SIZE 4096 @@ -725,43 +718,43 @@ static int daqp_do_insn_write(struct comedi_device *dev, return 1; } -/* daqp_attach is called via comedi_config to attach a comedi device - * to a /dev/comedi*. Note that this is different from daqp_cs_attach() - * which is called by the pcmcia subsystem to attach the PCMCIA card - * when it is inserted. - */ +static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data) +{ + if (p_dev->config_index == 0) + return -EINVAL; + + return pcmcia_request_io(p_dev); +} -static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int daqp_auto_attach(struct comedi_device *dev, + unsigned long context) { + struct pcmcia_device *link = comedi_to_pcmcia_dev(dev); struct local_info_t *local; struct comedi_subdevice *s; int ret; - if (it->options[0] < 0 || it->options[0] >= MAX_DEV) - return -ENODEV; + dev->board_name = dev->driver->driver_name; - local = dev_table[it->options[0]]; + /* Allocate space for private device-specific data */ + local = kzalloc(sizeof(*local), GFP_KERNEL); if (!local) - return -ENODEV; - - /* Typically brittle code that I don't completely understand, - * but "it works on my card". The intent is to pull the model - * number of the card out the PCMCIA CIS and stash it away as - * the COMEDI board_name. Looks like the third field in - * CISTPL_VERS_1 (offset 2) holds what we're looking for. If - * it doesn't work, who cares, just leave it as "DAQP". - */ + return -ENOMEM; - strcpy(local->board_name, "DAQP"); - dev->board_name = local->board_name; - if (local->link->prod_id[2]) { - if (strncmp(local->link->prod_id[2], "DAQP", 4) == 0) { - strncpy(local->board_name, local->link->prod_id[2], - sizeof(local->board_name)); - } - } + link->config_flags |= CONF_AUTO_SET_IO | CONF_ENABLE_IRQ; + ret = pcmcia_loop_config(link, daqp_pcmcia_config_loop, NULL); + if (ret) + return ret; - dev->iobase = local->link->resource[0]->start; + link->priv = local; + ret = pcmcia_request_irq(link, daqp_interrupt); + if (ret) + return ret; + + ret = pcmcia_enable_device(link); + if (ret) + return ret; + dev->iobase = link->resource[0]->start; ret = comedi_alloc_subdevices(dev, 4); if (ret) @@ -811,51 +804,18 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void daqp_detach(struct comedi_device *dev) { - /* Nothing to cleanup */ + struct pcmcia_device *link = comedi_to_pcmcia_dev(dev); + + pcmcia_disable_device(link); } static struct comedi_driver driver_daqp = { .driver_name = "quatech_daqp_cs", .module = THIS_MODULE, - .attach = daqp_attach, + .auto_attach = daqp_auto_attach, .detach = daqp_detach, }; -/*==================================================================== - - PCMCIA interface code - - The rest of the code in this file is based on dummy_cs.c v1.24 - from the Linux pcmcia_cs distribution v3.1.8 and is subject - to the following license agreement. - - The remaining contents of this file are subject to the Mozilla Public - License Version 1.1 (the "License"); you may not use this file - except in compliance with the License. You may obtain a copy of - the License at http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - implied. See the License for the specific language governing - rights and limitations under the License. - - The initial developer of the original code is David A. Hinds - . Portions created by David A. Hinds - are Copyright (C) 1999 David A. Hinds. All Rights Reserved. - - Alternatively, the contents of this file may be used under the - terms of the GNU Public License version 2 (the "GPL"), in which - case the provisions of the GPL are applicable instead of the - above. If you wish to allow the use of your version of this file - only under the terms of the GPL and not to allow others to use - your version of this file under the MPL, indicate your decision - by deleting the provisions above and replace them with the notice - and other provisions required by the GPL. If you do not delete - the provisions above, a recipient may use your version of this - file under either the MPL or the GPL. - -======================================================================*/ - static int daqp_cs_suspend(struct pcmcia_device *link) { struct local_info_t *local = link->priv; @@ -874,74 +834,11 @@ static int daqp_cs_resume(struct pcmcia_device *link) return 0; } -static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data) -{ - if (p_dev->config_index == 0) - return -EINVAL; - - return pcmcia_request_io(p_dev); -} - static int daqp_cs_attach(struct pcmcia_device *link) { - struct local_info_t *local; - int ret; - int i; - - for (i = 0; i < MAX_DEV; i++) - if (dev_table[i] == NULL) - break; - if (i == MAX_DEV) { - dev_notice(&link->dev, "no devices available\n"); - return -ENODEV; - } - - /* Allocate space for private device-specific data */ - local = kzalloc(sizeof(*local), GFP_KERNEL); - if (!local) - return -ENOMEM; - - local->table_index = i; - dev_table[i] = local; - local->link = link; - link->priv = local; - - link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; - - ret = pcmcia_loop_config(link, daqp_pcmcia_config_loop, NULL); - if (ret) { - dev_warn(&link->dev, "no configuration found\n"); - goto failed; - } - - ret = pcmcia_request_irq(link, daqp_interrupt); - if (ret) - goto failed; - - ret = pcmcia_enable_device(link); - if (ret) - goto failed; - - return 0; - -failed: - pcmcia_disable_device(link); - return ret; -} - -static void daqp_cs_detach(struct pcmcia_device *link) -{ - struct local_info_t *dev = link->priv; - - dev->stop = 1; - pcmcia_disable_device(link); - - /* Unlink device structure, and free it */ - dev_table[dev->table_index] = NULL; - kfree(dev); + return comedi_pcmcia_auto_config(link, &driver_daqp); } -/*====================================================================*/ static const struct pcmcia_device_id daqp_cs_id_table[] = { PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0027), PCMCIA_DEVICE_NULL @@ -953,7 +850,7 @@ static struct pcmcia_driver daqp_cs_driver = { .owner = THIS_MODULE, .id_table = daqp_cs_id_table, .probe = daqp_cs_attach, - .remove = daqp_cs_detach, + .remove = comedi_pcmcia_auto_unconfig, .suspend = daqp_cs_suspend, .resume = daqp_cs_resume, }; -- 2.20.1