1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

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: Dominik Brodowski <linux@dominikbrodowski.net>
This commit is contained in:
Dominik Brodowski 2008-07-29 08:38:55 +02:00
parent 0bac660a77
commit ed58872aa3
3 changed files with 102 additions and 188 deletions

View file

@ -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 :
cf->io.flags & CISTPL_IO_LINES_MASK;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
return -ENODEV;
} }
static int first_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_first_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);
}
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
{ p_dev->conf.ConfigIndex = cf->index;
if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) for (j = 0; j < 5; j++) {
return CS_NO_MORE_ITEMS; p_dev->io.BasePort1 = base[j];
return get_tuple(handle, tuple, parse); 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;
int i, j, try;
/* First pass: look for a config entry that looks normal. */ /* First pass: look for a config entry that looks normal.
tuple.TupleData = (cisdata_t *)buf; Two tries: without IO aliases, then with aliases */
tuple.TupleOffset = 0; for (try = 0; try < 2; try++)
tuple.TupleDataMax = 255; if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))
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; 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) {
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; goto found_port;
}
} BT_ERR("No usable port range found");
i = next_tuple(link, &tuple, &parse); cs_error(link, RequestIO, -ENODEV);
} goto failed;
found_port: found_port:
if (i != CS_SUCCESS) {
BT_ERR("No usable port range found");
cs_error(link, RequestIO, i);
goto failed;
}
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);

View file

@ -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 :
cf->io.flags & CISTPL_IO_LINES_MASK;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
return -ENODEV;
} }
static int first_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_first_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);
}
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
{ p_dev->conf.ConfigIndex = cf->index;
if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) for (j = 0; j < 5; j++) {
return CS_NO_MORE_ITEMS; p_dev->io.BasePort1 = base[j];
return get_tuple(handle, tuple, parse); 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;
int i, j, try;
/* First pass: look for a config entry that looks normal. */ /* First pass: look for a config entry that looks normal.
tuple.TupleData = (cisdata_t *) buf; Two tries: without IO aliases, then with aliases */
tuple.TupleOffset = 0; for (try = 0; try < 2; try++)
tuple.TupleDataMax = 255; if (!pcmcia_loop_config(link, btuart_check_config,
tuple.Attributes = 0; (void *) try))
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; 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) {
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; goto found_port;
}
} BT_ERR("No usable port range found");
i = next_tuple(link, &tuple, &parse); cs_error(link, RequestIO, -ENODEV);
} goto failed;
found_port: found_port:
if (i != CS_SUCCESS) {
BT_ERR("No usable port range found");
cs_error(link, RequestIO, i);
goto failed;
}
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);

View file

@ -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) {