Merge branch 'urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6

* 'urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6:
  pcmcia pcnet_cs: try setting io_lines to 16 if card setup fails
  pcmcia: per-device, not per-socket debug messages
  pcmcia serial_cs.c: fix multifunction card handling
This commit is contained in:
Linus Torvalds 2010-09-16 12:56:12 -07:00
commit bd12e5c3a1
3 changed files with 146 additions and 106 deletions

View file

@ -508,7 +508,8 @@ static int pcnet_confcheck(struct pcmcia_device *p_dev,
unsigned int vcc, unsigned int vcc,
void *priv_data) void *priv_data)
{ {
int *has_shmem = priv_data; int *priv = priv_data;
int try = (*priv & 0x1);
int i; int i;
cistpl_io_t *io = &cfg->io; cistpl_io_t *io = &cfg->io;
@ -525,77 +526,103 @@ static int pcnet_confcheck(struct pcmcia_device *p_dev,
i = p_dev->resource[1]->end = 0; i = p_dev->resource[1]->end = 0;
} }
*has_shmem = ((cfg->mem.nwin == 1) && *priv &= ((cfg->mem.nwin == 1) &&
(cfg->mem.win[0].len >= 0x4000)); (cfg->mem.win[0].len >= 0x4000)) ? 0x10 : ~0x10;
p_dev->resource[0]->start = io->win[i].base; p_dev->resource[0]->start = io->win[i].base;
p_dev->resource[0]->end = io->win[i].len; p_dev->resource[0]->end = io->win[i].len;
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; if (!try)
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
else
p_dev->io_lines = 16;
if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32) if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32)
return try_io_port(p_dev); return try_io_port(p_dev);
return 0; return -EINVAL;
}
static hw_info_t *pcnet_try_config(struct pcmcia_device *link,
int *has_shmem, int try)
{
struct net_device *dev = link->priv;
hw_info_t *local_hw_info;
pcnet_dev_t *info = PRIV(dev);
int priv = try;
int ret;
ret = pcmcia_loop_config(link, pcnet_confcheck, &priv);
if (ret) {
dev_warn(&link->dev, "no useable port range found\n");
return NULL;
}
*has_shmem = (priv & 0x10);
if (!link->irq)
return NULL;
if (resource_size(link->resource[1]) == 8) {
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
}
if ((link->manf_id == MANFID_IBM) &&
(link->card_id == PRODID_IBM_HOME_AND_AWAY))
link->conf.ConfigIndex |= 0x10;
ret = pcmcia_request_configuration(link, &link->conf);
if (ret)
return NULL;
dev->irq = link->irq;
dev->base_addr = link->resource[0]->start;
if (info->flags & HAS_MISC_REG) {
if ((if_port == 1) || (if_port == 2))
dev->if_port = if_port;
else
dev_notice(&link->dev, "invalid if_port requested\n");
} else
dev->if_port = 0;
if ((link->conf.ConfigBase == 0x03c0) &&
(link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
dev_info(&link->dev,
"this is an AX88190 card - use axnet_cs instead.\n");
return NULL;
}
local_hw_info = get_hwinfo(link);
if (!local_hw_info)
local_hw_info = get_prom(link);
if (!local_hw_info)
local_hw_info = get_dl10019(link);
if (!local_hw_info)
local_hw_info = get_ax88190(link);
if (!local_hw_info)
local_hw_info = get_hwired(link);
return local_hw_info;
} }
static int pcnet_config(struct pcmcia_device *link) static int pcnet_config(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
pcnet_dev_t *info = PRIV(dev); pcnet_dev_t *info = PRIV(dev);
int ret, start_pg, stop_pg, cm_offset; int start_pg, stop_pg, cm_offset;
int has_shmem = 0; int has_shmem = 0;
hw_info_t *local_hw_info; hw_info_t *local_hw_info;
dev_dbg(&link->dev, "pcnet_config\n"); dev_dbg(&link->dev, "pcnet_config\n");
ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem); local_hw_info = pcnet_try_config(link, &has_shmem, 0);
if (ret) if (!local_hw_info) {
goto failed; /* check whether forcing io_lines to 16 helps... */
pcmcia_disable_device(link);
if (!link->irq) local_hw_info = pcnet_try_config(link, &has_shmem, 1);
goto failed; if (local_hw_info == NULL) {
dev_notice(&link->dev, "unable to read hardware net"
if (resource_size(link->resource[1]) == 8) { " address for io base %#3lx\n", dev->base_addr);
link->conf.Attributes |= CONF_ENABLE_SPKR; goto failed;
link->conf.Status = CCSR_AUDIO_ENA; }
}
if ((link->manf_id == MANFID_IBM) &&
(link->card_id == PRODID_IBM_HOME_AND_AWAY))
link->conf.ConfigIndex |= 0x10;
ret = pcmcia_request_configuration(link, &link->conf);
if (ret)
goto failed;
dev->irq = link->irq;
dev->base_addr = link->resource[0]->start;
if (info->flags & HAS_MISC_REG) {
if ((if_port == 1) || (if_port == 2))
dev->if_port = if_port;
else
printk(KERN_NOTICE "pcnet_cs: invalid if_port requested\n");
} else {
dev->if_port = 0;
}
if ((link->conf.ConfigBase == 0x03c0) &&
(link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n");
printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n");
goto failed;
}
local_hw_info = get_hwinfo(link);
if (local_hw_info == NULL)
local_hw_info = get_prom(link);
if (local_hw_info == NULL)
local_hw_info = get_dl10019(link);
if (local_hw_info == NULL)
local_hw_info = get_ax88190(link);
if (local_hw_info == NULL)
local_hw_info = get_hwired(link);
if (local_hw_info == NULL) {
printk(KERN_NOTICE "pcnet_cs: unable to read hardware net"
" address for io base %#3lx\n", dev->base_addr);
goto failed;
} }
info->flags = local_hw_info->flags; info->flags = local_hw_info->flags;

View file

@ -163,7 +163,7 @@ static int pcmcia_access_config(struct pcmcia_device *p_dev,
c = p_dev->function_config; c = p_dev->function_config;
if (!(c->state & CONFIG_LOCKED)) { if (!(c->state & CONFIG_LOCKED)) {
dev_dbg(&s->dev, "Configuration isnt't locked\n"); dev_dbg(&p_dev->dev, "Configuration isnt't locked\n");
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
return -EACCES; return -EACCES;
} }
@ -220,7 +220,7 @@ int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh,
s->win[w].card_start = offset; s->win[w].card_start = offset;
ret = s->ops->set_mem_map(s, &s->win[w]); ret = s->ops->set_mem_map(s, &s->win[w]);
if (ret) if (ret)
dev_warn(&s->dev, "failed to set_mem_map\n"); dev_warn(&p_dev->dev, "failed to set_mem_map\n");
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
return ret; return ret;
} /* pcmcia_map_mem_page */ } /* pcmcia_map_mem_page */
@ -244,18 +244,18 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
c = p_dev->function_config; c = p_dev->function_config;
if (!(s->state & SOCKET_PRESENT)) { if (!(s->state & SOCKET_PRESENT)) {
dev_dbg(&s->dev, "No card present\n"); dev_dbg(&p_dev->dev, "No card present\n");
ret = -ENODEV; ret = -ENODEV;
goto unlock; goto unlock;
} }
if (!(c->state & CONFIG_LOCKED)) { if (!(c->state & CONFIG_LOCKED)) {
dev_dbg(&s->dev, "Configuration isnt't locked\n"); dev_dbg(&p_dev->dev, "Configuration isnt't locked\n");
ret = -EACCES; ret = -EACCES;
goto unlock; goto unlock;
} }
if (mod->Attributes & (CONF_IRQ_CHANGE_VALID | CONF_VCC_CHANGE_VALID)) { if (mod->Attributes & (CONF_IRQ_CHANGE_VALID | CONF_VCC_CHANGE_VALID)) {
dev_dbg(&s->dev, dev_dbg(&p_dev->dev,
"changing Vcc or IRQ is not allowed at this time\n"); "changing Vcc or IRQ is not allowed at this time\n");
ret = -EINVAL; ret = -EINVAL;
goto unlock; goto unlock;
@ -265,20 +265,22 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) && if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) { (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
if (mod->Vpp1 != mod->Vpp2) { if (mod->Vpp1 != mod->Vpp2) {
dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n"); dev_dbg(&p_dev->dev,
"Vpp1 and Vpp2 must be the same\n");
ret = -EINVAL; ret = -EINVAL;
goto unlock; goto unlock;
} }
s->socket.Vpp = mod->Vpp1; s->socket.Vpp = mod->Vpp1;
if (s->ops->set_socket(s, &s->socket)) { if (s->ops->set_socket(s, &s->socket)) {
dev_printk(KERN_WARNING, &s->dev, dev_printk(KERN_WARNING, &p_dev->dev,
"Unable to set VPP\n"); "Unable to set VPP\n");
ret = -EIO; ret = -EIO;
goto unlock; goto unlock;
} }
} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) || } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) { (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); dev_dbg(&p_dev->dev,
"changing Vcc is not allowed at this time\n");
ret = -EINVAL; ret = -EINVAL;
goto unlock; goto unlock;
} }
@ -401,7 +403,7 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res)
win = &s->win[w]; win = &s->win[w];
if (!(p_dev->_win & CLIENT_WIN_REQ(w))) { if (!(p_dev->_win & CLIENT_WIN_REQ(w))) {
dev_dbg(&s->dev, "not releasing unknown window\n"); dev_dbg(&p_dev->dev, "not releasing unknown window\n");
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
return -EINVAL; return -EINVAL;
} }
@ -439,7 +441,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
return -ENODEV; return -ENODEV;
if (req->IntType & INT_CARDBUS) { if (req->IntType & INT_CARDBUS) {
dev_dbg(&s->dev, "IntType may not be INT_CARDBUS\n"); dev_dbg(&p_dev->dev, "IntType may not be INT_CARDBUS\n");
return -EINVAL; return -EINVAL;
} }
@ -447,7 +449,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
c = p_dev->function_config; c = p_dev->function_config;
if (c->state & CONFIG_LOCKED) { if (c->state & CONFIG_LOCKED) {
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
dev_dbg(&s->dev, "Configuration is locked\n"); dev_dbg(&p_dev->dev, "Configuration is locked\n");
return -EACCES; return -EACCES;
} }
@ -455,7 +457,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
s->socket.Vpp = req->Vpp; s->socket.Vpp = req->Vpp;
if (s->ops->set_socket(s, &s->socket)) { if (s->ops->set_socket(s, &s->socket)) {
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
dev_printk(KERN_WARNING, &s->dev, dev_printk(KERN_WARNING, &p_dev->dev,
"Unable to set socket state\n"); "Unable to set socket state\n");
return -EINVAL; return -EINVAL;
} }
@ -569,19 +571,20 @@ int pcmcia_request_io(struct pcmcia_device *p_dev)
int ret = -EINVAL; int ret = -EINVAL;
mutex_lock(&s->ops_mutex); mutex_lock(&s->ops_mutex);
dev_dbg(&s->dev, "pcmcia_request_io: %pR , %pR", &c->io[0], &c->io[1]); dev_dbg(&p_dev->dev, "pcmcia_request_io: %pR , %pR",
&c->io[0], &c->io[1]);
if (!(s->state & SOCKET_PRESENT)) { if (!(s->state & SOCKET_PRESENT)) {
dev_dbg(&s->dev, "pcmcia_request_io: No card present\n"); dev_dbg(&p_dev->dev, "pcmcia_request_io: No card present\n");
goto out; goto out;
} }
if (c->state & CONFIG_LOCKED) { if (c->state & CONFIG_LOCKED) {
dev_dbg(&s->dev, "Configuration is locked\n"); dev_dbg(&p_dev->dev, "Configuration is locked\n");
goto out; goto out;
} }
if (c->state & CONFIG_IO_REQ) { if (c->state & CONFIG_IO_REQ) {
dev_dbg(&s->dev, "IO already configured\n"); dev_dbg(&p_dev->dev, "IO already configured\n");
goto out; goto out;
} }
@ -601,7 +604,7 @@ int pcmcia_request_io(struct pcmcia_device *p_dev)
c->state |= CONFIG_IO_REQ; c->state |= CONFIG_IO_REQ;
p_dev->_io = 1; p_dev->_io = 1;
dev_dbg(&s->dev, "pcmcia_request_io succeeded: %pR , %pR", dev_dbg(&p_dev->dev, "pcmcia_request_io succeeded: %pR , %pR",
&c->io[0], &c->io[1]); &c->io[0], &c->io[1]);
out: out:
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
@ -800,7 +803,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
int w; int w;
if (!(s->state & SOCKET_PRESENT)) { if (!(s->state & SOCKET_PRESENT)) {
dev_dbg(&s->dev, "No card present\n"); dev_dbg(&p_dev->dev, "No card present\n");
return -ENODEV; return -ENODEV;
} }
@ -809,12 +812,12 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
req->Size = s->map_size; req->Size = s->map_size;
align = (s->features & SS_CAP_MEM_ALIGN) ? req->Size : s->map_size; align = (s->features & SS_CAP_MEM_ALIGN) ? req->Size : s->map_size;
if (req->Size & (s->map_size-1)) { if (req->Size & (s->map_size-1)) {
dev_dbg(&s->dev, "invalid map size\n"); dev_dbg(&p_dev->dev, "invalid map size\n");
return -EINVAL; return -EINVAL;
} }
if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) || if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||
(req->Base & (align-1))) { (req->Base & (align-1))) {
dev_dbg(&s->dev, "invalid base address\n"); dev_dbg(&p_dev->dev, "invalid base address\n");
return -EINVAL; return -EINVAL;
} }
if (req->Base) if (req->Base)
@ -826,7 +829,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
if (!(s->state & SOCKET_WIN_REQ(w))) if (!(s->state & SOCKET_WIN_REQ(w)))
break; break;
if (w == MAX_WIN) { if (w == MAX_WIN) {
dev_dbg(&s->dev, "all windows are used already\n"); dev_dbg(&p_dev->dev, "all windows are used already\n");
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
return -EINVAL; return -EINVAL;
} }
@ -837,7 +840,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
win->res = pcmcia_find_mem_region(req->Base, req->Size, align, win->res = pcmcia_find_mem_region(req->Base, req->Size, align,
0, s); 0, s);
if (!win->res) { if (!win->res) {
dev_dbg(&s->dev, "allocating mem region failed\n"); dev_dbg(&p_dev->dev, "allocating mem region failed\n");
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
return -EINVAL; return -EINVAL;
} }
@ -851,7 +854,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
win->card_start = 0; win->card_start = 0;
if (s->ops->set_mem_map(s, win) != 0) { if (s->ops->set_mem_map(s, win) != 0) {
dev_dbg(&s->dev, "failed to set memory mapping\n"); dev_dbg(&p_dev->dev, "failed to set memory mapping\n");
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
return -EIO; return -EIO;
} }
@ -874,7 +877,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
if (win->res) if (win->res)
request_resource(&iomem_resource, res); request_resource(&iomem_resource, res);
dev_dbg(&s->dev, "request_window results in %pR\n", res); dev_dbg(&p_dev->dev, "request_window results in %pR\n", res);
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
*wh = res; *wh = res;

View file

@ -335,8 +335,6 @@ static int serial_probe(struct pcmcia_device *link)
info->p_dev = link; info->p_dev = link;
link->priv = info; link->priv = info;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
link->resource[0]->end = 8;
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
if (do_sound) { if (do_sound) {
link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Attributes |= CONF_ENABLE_SPKR;
@ -411,6 +409,27 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
/*====================================================================*/ /*====================================================================*/
static int pfc_config(struct pcmcia_device *p_dev)
{
unsigned int port = 0;
struct serial_info *info = p_dev->priv;
if ((p_dev->resource[1]->end != 0) &&
(resource_size(p_dev->resource[1]) == 8)) {
port = p_dev->resource[1]->start;
info->slave = 1;
} else if ((info->manfid == MANFID_OSITECH) &&
(resource_size(p_dev->resource[0]) == 0x40)) {
port = p_dev->resource[0]->start + 0x28;
info->slave = 1;
}
if (info->slave)
return setup_serial(p_dev, info, port, p_dev->irq);
dev_warn(&p_dev->dev, "no usable port range found, giving up\n");
return -ENODEV;
}
static int simple_config_check(struct pcmcia_device *p_dev, static int simple_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf, cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt, cistpl_cftable_entry_t *dflt,
@ -461,23 +480,8 @@ static int simple_config(struct pcmcia_device *link)
struct serial_info *info = link->priv; struct serial_info *info = link->priv;
int i = -ENODEV, try; int i = -ENODEV, try;
/* If the card is already configured, look up the port and irq */ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
if (link->function_config) { link->resource[0]->end = 8;
unsigned int port = 0;
if ((link->resource[1]->end != 0) &&
(resource_size(link->resource[1]) == 8)) {
port = link->resource[1]->end;
info->slave = 1;
} else if ((info->manfid == MANFID_OSITECH) &&
(resource_size(link->resource[0]) == 0x40)) {
port = link->resource[0]->start + 0x28;
info->slave = 1;
}
if (info->slave) {
return setup_serial(link, info, port,
link->irq);
}
}
/* First pass: look for a config entry that looks normal. /* First pass: look for a config entry that looks normal.
* Two tries: without IO aliases, then with aliases */ * Two tries: without IO aliases, then with aliases */
@ -491,8 +495,7 @@ static int simple_config(struct pcmcia_device *link)
if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL)) if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
goto found_port; goto found_port;
printk(KERN_NOTICE dev_warn(&link->dev, "no usable port range found, giving up\n");
"serial_cs: no usable port range found, giving up\n");
return -1; return -1;
found_port: found_port:
@ -558,6 +561,7 @@ static int multi_config(struct pcmcia_device *link)
int i, base2 = 0; int i, base2 = 0;
/* First, look for a generic full-sized window */ /* First, look for a generic full-sized window */
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
link->resource[0]->end = info->multi * 8; link->resource[0]->end = info->multi * 8;
if (pcmcia_loop_config(link, multi_config_check, &base2)) { if (pcmcia_loop_config(link, multi_config_check, &base2)) {
/* If that didn't work, look for two windows */ /* If that didn't work, look for two windows */
@ -565,15 +569,14 @@ static int multi_config(struct pcmcia_device *link)
info->multi = 2; info->multi = 2;
if (pcmcia_loop_config(link, multi_config_check_notpicky, if (pcmcia_loop_config(link, multi_config_check_notpicky,
&base2)) { &base2)) {
printk(KERN_NOTICE "serial_cs: no usable port range" dev_warn(&link->dev, "no usable port range "
"found, giving up\n"); "found, giving up\n");
return -ENODEV; return -ENODEV;
} }
} }
if (!link->irq) if (!link->irq)
dev_warn(&link->dev, dev_warn(&link->dev, "no usable IRQ found, continuing...\n");
"serial_cs: no usable IRQ found, continuing...\n");
/* /*
* Apply any configuration quirks. * Apply any configuration quirks.
@ -675,6 +678,7 @@ static int serial_config(struct pcmcia_device * link)
multifunction cards that ask for appropriate IO port ranges */ multifunction cards that ask for appropriate IO port ranges */
if ((info->multi == 0) && if ((info->multi == 0) &&
(link->has_func_id) && (link->has_func_id) &&
(link->socket->pcmcia_pfc == 0) &&
((link->func_id == CISTPL_FUNCID_MULTI) || ((link->func_id == CISTPL_FUNCID_MULTI) ||
(link->func_id == CISTPL_FUNCID_SERIAL))) (link->func_id == CISTPL_FUNCID_SERIAL)))
pcmcia_loop_config(link, serial_check_for_multi, info); pcmcia_loop_config(link, serial_check_for_multi, info);
@ -685,7 +689,13 @@ static int serial_config(struct pcmcia_device * link)
if (info->quirk && info->quirk->multi != -1) if (info->quirk && info->quirk->multi != -1)
info->multi = info->quirk->multi; info->multi = info->quirk->multi;
if (info->multi > 1) dev_info(&link->dev,
"trying to set up [0x%04x:0x%04x] (pfc: %d, multi: %d, quirk: %p)\n",
link->manf_id, link->card_id,
link->socket->pcmcia_pfc, info->multi, info->quirk);
if (link->socket->pcmcia_pfc)
i = pfc_config(link);
else if (info->multi > 1)
i = multi_config(link); i = multi_config(link);
else else
i = simple_config(link); i = simple_config(link);
@ -704,7 +714,7 @@ static int serial_config(struct pcmcia_device * link)
return 0; return 0;
failed: failed:
dev_warn(&link->dev, "serial_cs: failed to initialize\n"); dev_warn(&link->dev, "failed to initialize\n");
serial_remove(link); serial_remove(link);
return -ENODEV; return -ENODEV;
} }