Commit ed58872a authored by Dominik Brodowski's avatar Dominik Brodowski

pcmcia: use pcmcia_loop_config in bluetooth drivers

Use the config loop helper in bluetooth pcmcia drivers.

CC: Marcel Holtmann <marcel@holtmann.org>
CC: linux-bluetooth@vger.kernel.org
Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
parent 0bac660a
...@@ -678,93 +678,68 @@ static void bt3c_detach(struct pcmcia_device *link) ...@@ -678,93 +678,68 @@ static void bt3c_detach(struct pcmcia_device *link)
kfree(info); kfree(info);
} }
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) static int bt3c_check_config(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
void *priv_data)
{ {
int i; unsigned long try = (unsigned long) priv_data;
i = pcmcia_get_tuple_data(handle, tuple); if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
if (i != CS_SUCCESS) p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
return i; if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
(cf->io.win[0].base != 0)) {
return pcmcia_parse_tuple(handle, tuple, parse); p_dev->conf.ConfigIndex = cf->index;
} p_dev->io.BasePort1 = cf->io.win[0].base;
p_dev->io.IOAddrLines = (try == 0) ? 16 :
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) cf->io.flags & CISTPL_IO_LINES_MASK;
{ if (!pcmcia_request_io(p_dev, &p_dev->io))
if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) return 0;
return CS_NO_MORE_ITEMS; }
return get_tuple(handle, tuple, parse); return -ENODEV;
} }
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
void *priv_data)
{ {
if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
return CS_NO_MORE_ITEMS; int j;
return get_tuple(handle, tuple, parse);
if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
p_dev->conf.ConfigIndex = cf->index;
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 bt3c_config(struct pcmcia_device *link) static int bt3c_config(struct pcmcia_device *link)
{ {
static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
bt3c_info_t *info = link->priv; bt3c_info_t *info = link->priv;
tuple_t tuple; int i;
u_short buf[256]; unsigned long try;
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry; /* First pass: look for a config entry that looks normal.
int i, j, try; Two tries: without IO aliases, then with aliases */
for (try = 0; try < 2; try++)
/* First pass: look for a config entry that looks normal. */ if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))
tuple.TupleData = (cisdata_t *)buf; goto found_port;
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);
}
}
/* Second pass: try to find an entry that isn't picky about /* Second pass: try to find an entry that isn't picky about
its base address, then try to grab any standard serial port its base address, then try to grab any standard serial port
address, and finally try to get any free port. */ address, and finally try to get any free port. */
i = first_tuple(link, &tuple, &parse); if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))
while (i != CS_NO_MORE_ITEMS) { goto found_port;
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);
}
found_port: BT_ERR("No usable port range found");
if (i != CS_SUCCESS) { cs_error(link, RequestIO, -ENODEV);
BT_ERR("No usable port range found"); goto failed;
cs_error(link, RequestIO, i);
goto failed;
}
found_port:
i = pcmcia_request_irq(link, &link->irq); i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) { if (i != CS_SUCCESS) {
cs_error(link, RequestIRQ, i); cs_error(link, RequestIRQ, i);
......
...@@ -607,94 +607,69 @@ static void btuart_detach(struct pcmcia_device *link) ...@@ -607,94 +607,69 @@ static void btuart_detach(struct pcmcia_device *link)
kfree(info); 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,
void *priv_data)
{ {
int i; unsigned long try = (unsigned long) priv_data;
i = pcmcia_get_tuple_data(handle, tuple); if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
if (i != CS_SUCCESS) p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
return i; if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
(cf->io.win[0].base != 0)) {
return pcmcia_parse_tuple(handle, tuple, parse); p_dev->conf.ConfigIndex = cf->index;
} p_dev->io.BasePort1 = cf->io.win[0].base;
p_dev->io.IOAddrLines = (try == 0) ? 16 :
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) cf->io.flags & CISTPL_IO_LINES_MASK;
{ if (!pcmcia_request_io(p_dev, &p_dev->io))
if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) return 0;
return CS_NO_MORE_ITEMS; }
return get_tuple(handle, tuple, parse); 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,
void *priv_data)
{ {
if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
return CS_NO_MORE_ITEMS; int j;
return get_tuple(handle, tuple, parse);
if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
p_dev->conf.ConfigIndex = cf->index;
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 int btuart_config(struct pcmcia_device *link)
{ {
static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
btuart_info_t *info = link->priv; btuart_info_t *info = link->priv;
tuple_t tuple; int i;
u_short buf[256]; unsigned long try;
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry; /* First pass: look for a config entry that looks normal.
int i, j, try; Two tries: without IO aliases, then with aliases */
for (try = 0; try < 2; try++)
/* First pass: look for a config entry that looks normal. */ if (!pcmcia_loop_config(link, btuart_check_config,
tuple.TupleData = (cisdata_t *) buf; (void *) try))
tuple.TupleOffset = 0; goto found_port;
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);
}
}
/* Second pass: try to find an entry that isn't picky about /* Second pass: try to find an entry that isn't picky about
its base address, then try to grab any standard serial port its base address, then try to grab any standard serial port
address, and finally try to get any free port. */ address, and finally try to get any free port. */
i = first_tuple(link, &tuple, &parse); if (!pcmcia_loop_config(link, btuart_check_config_notpicky, NULL))
while (i != CS_NO_MORE_ITEMS) { goto found_port;
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);
}
found_port: BT_ERR("No usable port range found");
if (i != CS_SUCCESS) { cs_error(link, RequestIO, -ENODEV);
BT_ERR("No usable port range found"); goto failed;
cs_error(link, RequestIO, i);
goto failed;
}
found_port:
i = pcmcia_request_irq(link, &link->irq); i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) { if (i != CS_SUCCESS) {
cs_error(link, RequestIRQ, i); cs_error(link, RequestIRQ, i);
......
...@@ -590,66 +590,30 @@ static void dtl1_detach(struct pcmcia_device *link) ...@@ -590,66 +590,30 @@ static void dtl1_detach(struct pcmcia_device *link)
kfree(info); kfree(info);
} }
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) static int dtl1_confcheck(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
void *priv_data)
{ {
int i; if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
p_dev->conf.ConfigIndex = cf->index;
i = pcmcia_get_tuple_data(handle, tuple); p_dev->io.BasePort1 = cf->io.win[0].base;
if (i != CS_SUCCESS) p_dev->io.NumPorts1 = cf->io.win[0].len; /*yo */
return i; p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return pcmcia_parse_tuple(handle, tuple, parse); return 0;
} }
return -ENODEV;
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);
}
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
{
if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
return CS_NO_MORE_ITEMS;
return get_tuple(handle, tuple, parse);
} }
static int dtl1_config(struct pcmcia_device *link) static int dtl1_config(struct pcmcia_device *link)
{ {
dtl1_info_t *info = link->priv; dtl1_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; int i;
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
/* Look for a generic full-sized window */ /* Look for a generic full-sized window */
link->io.NumPorts1 = 8; link->io.NumPorts1 = 8;
i = first_tuple(link, &tuple, &parse); if (!pcmcia_loop_config(link, dtl1_confcheck, NULL))
while (i != CS_NO_MORE_ITEMS) {
if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
link->io.NumPorts1 = cf->io.win[0].len; /*yo */
link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
break;
}
i = next_tuple(link, &tuple, &parse);
}
if (i != CS_SUCCESS) {
cs_error(link, RequestIO, i);
goto failed; goto failed;
}
i = pcmcia_request_irq(link, &link->irq); i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) { if (i != CS_SUCCESS) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment