diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/das08_cs.c')
-rw-r--r-- | drivers/staging/comedi/drivers/das08_cs.c | 203 |
1 files changed, 55 insertions, 148 deletions
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index 9cab21e..9b945e5 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -110,25 +110,6 @@ static int das08_cs_attach(struct comedi_device *dev, ======================================================================*/ -/* - All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If - you do not define PCMCIA_DEBUG at all, all the debug code will be - left out. If you compile with PCMCIA_DEBUG=0, the debug code will - be present but disabled -- but it can then be enabled for specific - modules at load time with a 'pc_debug=#' option to insmod. -*/ - -#ifdef PCMCIA_DEBUG -static int pc_debug = PCMCIA_DEBUG; -module_param(pc_debug, int, 0644); -#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) -static const char *version = - "das08.c pcmcia code (Frank Hess), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)"; -#else -#define DEBUG(n, args...) -#endif - -/*====================================================================*/ static void das08_pcmcia_config(struct pcmcia_device *link); static void das08_pcmcia_release(struct pcmcia_device *link); static int das08_pcmcia_suspend(struct pcmcia_device *p_dev); @@ -181,7 +162,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link) { struct local_info_t *local; - DEBUG(0, "das08_pcmcia_attach()\n"); + dev_dbg(&link->dev, "das08_pcmcia_attach()\n"); /* Allocate space for private device-specific data */ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); @@ -192,7 +173,6 @@ static int das08_pcmcia_attach(struct pcmcia_device *link) /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = NULL; /* @@ -224,7 +204,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link) static void das08_pcmcia_detach(struct pcmcia_device *link) { - DEBUG(0, "das08_pcmcia_detach(0x%p)\n", link); + dev_dbg(&link->dev, "das08_pcmcia_detach\n"); if (link->dev_node) { ((struct local_info_t *)link->priv)->stop = 1; @@ -237,6 +217,44 @@ static void das08_pcmcia_detach(struct pcmcia_device *link) } /* das08_pcmcia_detach */ + +static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + if (cfg->index == 0) + return -ENODEV; + + /* Do we need to allocate an interrupt? */ + if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->io.BasePort1 = io->win[0].base; + p_dev->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + p_dev->io.Attributes2 = p_dev->io.Attributes1; + p_dev->io.BasePort2 = io->win[1].base; + p_dev->io.NumPorts2 = io->win[1].len; + } + /* This reserves IO space but doesn't actually enable it */ + return pcmcia_request_io(p_dev, &p_dev->io); + } + return 0; +} + + /*====================================================================== das08_pcmcia_config() is scheduled to run after a CARD_INSERTION event @@ -248,128 +266,20 @@ static void das08_pcmcia_detach(struct pcmcia_device *link) static void das08_pcmcia_config(struct pcmcia_device *link) { struct local_info_t *dev = link->priv; - tuple_t tuple; - cisparse_t parse; - int last_fn, last_ret; - u_char buf[64]; - cistpl_cftable_entry_t dflt = { 0 }; - - DEBUG(0, "das08_pcmcia_config(0x%p)\n", link); - - /* - This reads the card's CONFIG tuple to find its configuration - registers. - */ - tuple.DesiredTuple = CISTPL_CONFIG; - tuple.Attributes = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; - last_fn = GetFirstTuple; - - last_ret = pcmcia_get_first_tuple(link, &tuple); - if (last_ret) - goto cs_failed; - - last_fn = GetTupleData; - - last_ret = pcmcia_get_tuple_data(link, &tuple); - if (last_ret) - goto cs_failed; - - last_fn = ParseTuple; - - last_ret = pcmcia_parse_tuple(&tuple, &parse); - if (last_ret) - goto cs_failed; - - link->conf.ConfigBase = parse.config.base; - link->conf.Present = parse.config.rmask[0]; - - /* - In this loop, we scan the CIS for configuration table entries, - each of which describes a valid card configuration, including - voltage, IO window, memory window, and interrupt settings. - - We make no assumptions about the card to be configured: we use - just the information available in the CIS. In an ideal world, - this would work for any PCMCIA card, but it requires a complete - and accurate CIS. In practice, a driver usually "knows" most of - these things without consulting the CIS, and most client drivers - will only use the CIS to fill in implementation-defined details. - */ - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - last_fn = GetFirstTuple; - - last_ret = pcmcia_get_first_tuple(link, &tuple); - if (last_ret) - goto cs_failed; - - while (1) { - cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - - last_ret = pcmcia_get_tuple_data(link, &tuple); - if (last_ret) - goto next_entry; - - last_ret = pcmcia_parse_tuple(&tuple, &parse); - if (last_ret) - goto next_entry; - - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) - dflt = *cfg; - if (cfg->index == 0) - goto next_entry; - link->conf.ConfigIndex = cfg->index; - - /* Does this card need audio output? */ -/* if (cfg->flags & CISTPL_CFTABLE_AUDIO) { - link->conf.Attributes |= CONF_ENABLE_SPKR; - link->conf.Status = CCSR_AUDIO_ENA; - } -*/ - /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) - link->conf.Attributes |= CONF_ENABLE_IRQ; - - /* IO window settings */ - link->io.NumPorts1 = link->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - link->io.BasePort1 = io->win[0].base; - link->io.NumPorts1 = io->win[0].len; - if (io->nwin > 1) { - link->io.Attributes2 = link->io.Attributes1; - link->io.BasePort2 = io->win[1].base; - link->io.NumPorts2 = io->win[1].len; - } - /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link, &link->io) != 0) - goto next_entry; - } - - /* If we got this far, we're cool! */ - break; + int ret; -next_entry: - last_fn = GetNextTuple; + dev_dbg(&link->dev, "das08_pcmcia_config\n"); - last_ret = pcmcia_get_next_tuple(link, &tuple); - if (last_ret) - goto cs_failed; + ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL); + if (ret) { + dev_warn(&link->dev, "no configuration found\n"); + goto failed; } if (link->conf.Attributes & CONF_ENABLE_IRQ) { - last_fn = RequestIRQ; - last_ret = pcmcia_request_irq(link, &link->irq); - if (last_ret) - goto cs_failed; + ret = pcmcia_request_irq(link, &link->irq); + if (ret) + goto failed; } /* @@ -377,10 +287,9 @@ next_entry: the I/O windows and the interrupt mapping, and putting the card and host interface into "Memory and IO" mode. */ - last_fn = RequestConfiguration; - last_ret = pcmcia_request_configuration(link, &link->conf); - if (last_ret) - goto cs_failed; + ret = pcmcia_request_configuration(link, &link->conf); + if (ret) + goto failed; /* At this point, the dev_node_t structure(s) need to be @@ -405,8 +314,7 @@ next_entry: return; -cs_failed: - cs_error(link, last_fn, last_ret); +failed: das08_pcmcia_release(link); } /* das08_pcmcia_config */ @@ -421,7 +329,7 @@ cs_failed: static void das08_pcmcia_release(struct pcmcia_device *link) { - DEBUG(0, "das08_pcmcia_release(0x%p)\n", link); + dev_dbg(&link->dev, "das08_pcmcia_release\n"); pcmcia_disable_device(link); } /* das08_pcmcia_release */ @@ -477,14 +385,13 @@ struct pcmcia_driver das08_cs_driver = { static int __init init_das08_pcmcia_cs(void) { - DEBUG(0, "%s\n", version); pcmcia_register_driver(&das08_cs_driver); return 0; } static void __exit exit_das08_pcmcia_cs(void) { - DEBUG(0, "das08_pcmcia_cs: unloading\n"); + pr_debug("das08_pcmcia_cs: unloading\n"); pcmcia_unregister_driver(&das08_cs_driver); } |