diff options
Diffstat (limited to 'drivers/bluetooth/btuart_cs.c')
-rw-r--r-- | drivers/bluetooth/btuart_cs.c | 126 |
1 files changed, 51 insertions, 75 deletions
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 68d1d258e6a4..8e556b7ff9f6 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -607,102 +607,78 @@ static void btuart_detach(struct pcmcia_device *link) kfree(info); } -static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) +static int btuart_check_config(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cf, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) { - int i; - - i = pcmcia_get_tuple_data(handle, tuple); - if (i != CS_SUCCESS) - return i; - - return pcmcia_parse_tuple(handle, tuple, parse); -} - -static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) -{ - if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) - return CS_NO_MORE_ITEMS; - return get_tuple(handle, tuple, parse); + int *try = priv_data; + + if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) + p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; + if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && + (cf->io.win[0].base != 0)) { + p_dev->io.BasePort1 = cf->io.win[0].base; + p_dev->io.IOAddrLines = (*try == 0) ? 16 : + cf->io.flags & CISTPL_IO_LINES_MASK; + if (!pcmcia_request_io(p_dev, &p_dev->io)) + return 0; + } + return -ENODEV; } -static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) +static int btuart_check_config_notpicky(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cf, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) { - if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) - return CS_NO_MORE_ITEMS; - return get_tuple(handle, tuple, parse); + static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; + int j; + + if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { + for (j = 0; j < 5; j++) { + p_dev->io.BasePort1 = base[j]; + p_dev->io.IOAddrLines = base[j] ? 16 : 3; + if (!pcmcia_request_io(p_dev, &p_dev->io)) + return 0; + } + } + return -ENODEV; } static int btuart_config(struct pcmcia_device *link) { - static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; btuart_info_t *info = link->priv; - tuple_t tuple; - u_short buf[256]; - cisparse_t parse; - cistpl_cftable_entry_t *cf = &parse.cftable_entry; - int i, j, try; - - /* First pass: look for a config entry that looks normal. */ - tuple.TupleData = (cisdata_t *) buf; - tuple.TupleOffset = 0; - tuple.TupleDataMax = 255; - tuple.Attributes = 0; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - /* Two tries: without IO aliases, then with aliases */ - for (try = 0; try < 2; try++) { - i = first_tuple(link, &tuple, &parse); - while (i != CS_NO_MORE_ITEMS) { - if (i != CS_SUCCESS) - goto next_entry; - if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; - if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { - link->conf.ConfigIndex = cf->index; - link->io.BasePort1 = cf->io.win[0].base; - link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) - goto found_port; - } -next_entry: - i = next_tuple(link, &tuple, &parse); - } - } + int i; + int try; + + /* First pass: look for a config entry that looks normal. + Two tries: without IO aliases, then with aliases */ + for (try = 0; try < 2; try++) + if (!pcmcia_loop_config(link, btuart_check_config, &try)) + goto found_port; /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ - i = first_tuple(link, &tuple, &parse); - while (i != CS_NO_MORE_ITEMS) { - if ((i == CS_SUCCESS) && (cf->io.nwin > 0) - && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { - link->conf.ConfigIndex = cf->index; - for (j = 0; j < 5; j++) { - link->io.BasePort1 = base[j]; - link->io.IOAddrLines = base[j] ? 16 : 3; - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) - goto found_port; - } - } - i = next_tuple(link, &tuple, &parse); - } + if (!pcmcia_loop_config(link, btuart_check_config_notpicky, NULL)) + goto found_port; -found_port: - if (i != CS_SUCCESS) { - BT_ERR("No usable port range found"); - cs_error(link, RequestIO, i); - goto failed; - } + BT_ERR("No usable port range found"); + cs_error(link, RequestIO, -ENODEV); + goto failed; +found_port: i = pcmcia_request_irq(link, &link->irq); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } i = pcmcia_request_configuration(link, &link->conf); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestConfiguration, i); goto failed; } |