Commit 00990e7c authored by Dominik Brodowski's avatar Dominik Brodowski

pcmcia: use autoconfiguration feature for ioports and iomem

When CONF_AUTO_SET_IO or CONF_AUTO_SET_IOMEM are set, the corresponding
fields in struct pcmcia_device *p_dev->resource[0,1,2] are set
accordinly. Drivers wishing to override certain settings may do so in
the callback function, but they no longer need to parse the CIS entries
stored in cistpl_cftable_entry_t themselves.

CC: netdev@vger.kernel.org
CC: linux-wireless@vger.kernel.org
CC: linux-ide@vger.kernel.org
CC: linux-usb@vger.kernel.org
CC: laforge@gnumonks.org
CC: linux-mtd@lists.infradead.org
CC: linux-bluetooth@vger.kernel.org
CC: alsa-devel@alsa-project.org
CC: linux-serial@vger.kernel.org
CC: Jiri Kosina <jkosina@suse.cz>
CC: linux-scsi@vger.kernel.org
Tested-by: 's avatarWolfram Sang <w.sang@pengutronix.de>
Signed-off-by: 's avatarDominik Brodowski <linux@dominikbrodowski.net>
parent 440eed43
This file details changes in 2.6 which affect PCMCIA card driver authors:
* pcmcia_loop_config() and autoconfiguration (as of 2.6.36)
If struct pcmcia_device *p_dev->config_flags is set accordingly,
pcmcia_loop_config() now sets up certain configuration values
automatically, though the driver may still override the settings
in the callback function. The following autoconfiguration options
are provided at the moment:
CONF_AUTO_CHECK_VCC : check for matching Vcc
CONF_AUTO_SET_VPP : set Vpp
CONF_AUTO_AUDIO : auto-enable audio line, if required
CONF_AUTO_SET_IO : set ioport resources (->resource[0,1])
CONF_AUTO_SET_IOMEM : set first iomem resource (->resource[2])
* pcmcia_request_configuration -> pcmcia_enable_device (as of 2.6.36)
pcmcia_request_configuration() got renamed to pcmcia_enable_device(),
as it mirrors pcmcia_disable_device(). Configuration settings are now
......
......@@ -167,45 +167,26 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
};
struct pcmcia_config_check {
unsigned long ctl_base;
int is_kme;
};
static int pcmcia_check_one_config(struct pcmcia_device *pdev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
void *priv_data)
static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data)
{
struct pcmcia_config_check *stk = priv_data;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
pdev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
pdev->resource[0]->start = io->win[0].base;
if (!(io->flags & CISTPL_IO_16BIT)) {
pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
}
if (io->nwin == 2) {
pdev->resource[0]->end = 8;
pdev->resource[1]->start = io->win[1].base;
pdev->resource[1]->end = (stk->is_kme) ? 2 : 1;
if (pcmcia_request_io(pdev) != 0)
return -ENODEV;
stk->ctl_base = pdev->resource[1]->start;
} else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
pdev->resource[0]->end = io->win[0].len;
pdev->resource[1]->end = 0;
if (pcmcia_request_io(pdev) != 0)
return -ENODEV;
stk->ctl_base = pdev->resource[0]->start + 0x0e;
} else
int *is_kme = priv_data;
if (!(pdev->resource[0]->flags & IO_DATA_PATH_WIDTH_8)) {
pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
}
pdev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
if (pdev->resource[1]->end) {
pdev->resource[0]->end = 8;
pdev->resource[1]->end = (*is_kme) ? 2 : 1;
} else {
if (pdev->resource[0]->end < 16)
return -ENODEV;
/* If we've got this far, we're done */
return 0;
}
return -ENODEV;
return pcmcia_request_io(pdev);
}
/**
......@@ -220,7 +201,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
{
struct ata_host *host;
struct ata_port *ap;
struct pcmcia_config_check *stk = NULL;
int is_kme = 0, ret = -ENOMEM, p;
unsigned long io_base, ctl_base;
void __iomem *io_addr, *ctl_addr;
......@@ -228,10 +208,8 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
struct ata_port_operations *ops = &pcmcia_port_ops;
/* Set up attributes in order to probe card and get resources */
pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
pdev->config_flags |= CONF_ENABLE_IRQ;
pdev->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
pdev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO |
CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
/* See if we have a manufacturer identifier. Use it to set is_kme for
vendor quirks */
......@@ -239,21 +217,17 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
((pdev->card_id == PRODID_KME_KXLC005_A) ||
(pdev->card_id == PRODID_KME_KXLC005_B)));
/* Allocate resoure probing structures */
stk = kzalloc(sizeof(*stk), GFP_KERNEL);
if (!stk)
goto out1;
stk->is_kme = is_kme;
io_base = ctl_base = 0;
if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) {
if (pcmcia_loop_config(pdev, pcmcia_check_one_config, &is_kme)) {
pdev->config_flags &= ~CONF_AUTO_CHECK_VCC;
if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk))
if (pcmcia_loop_config(pdev, pcmcia_check_one_config, &is_kme))
goto failed; /* No suitable config found */
}
io_base = pdev->resource[0]->start;
ctl_base = stk->ctl_base;
if (pdev->resource[1]->end)
ctl_base = pdev->resource[1]->start;
else
ctl_base = pdev->resource[0]->start + 0x0e;
if (!pdev->irq)
goto failed;
......@@ -310,13 +284,10 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
goto failed;
pdev->priv = host;
kfree(stk);
return 0;
failed:
kfree(stk);
pcmcia_disable_device(pdev);
out1:
return ret;
}
......
......@@ -656,10 +656,8 @@ static int bt3c_probe(struct pcmcia_device *link)
info->p_dev = link;
link->priv = info;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
link->resource[0]->end = 8;
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP;
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
CONF_AUTO_SET_IO;
return bt3c_config(link);
}
......@@ -673,38 +671,41 @@ static void bt3c_detach(struct pcmcia_device *link)
kfree(info);
}
static int bt3c_check_config(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
void *priv_data)
static int bt3c_check_config(struct pcmcia_device *p_dev, void *priv_data)
{
unsigned long try = (unsigned long) priv_data;
p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
int *try = priv_data;
if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
(cf->io.win[0].base != 0)) {
p_dev->resource[0]->start = cf->io.win[0].base;
if (!pcmcia_request_io(p_dev))
return 0;
}
return -ENODEV;
if (try == 0)
p_dev->io_lines = 16;
if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0))
return -EINVAL;
p_dev->resource[0]->end = 8;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
return pcmcia_request_io(p_dev);
}
static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
void *priv_data)
{
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->resource[0]->start = base[j];
p_dev->io_lines = base[j] ? 16 : 3;
if (!pcmcia_request_io(p_dev))
return 0;
}
if (p_dev->io_lines > 3)
return -ENODEV;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->resource[0]->end = 8;
for (j = 0; j < 5; j++) {
p_dev->resource[0]->start = base[j];
p_dev->io_lines = base[j] ? 16 : 3;
if (!pcmcia_request_io(p_dev))
return 0;
}
return -ENODEV;
}
......
......@@ -585,10 +585,8 @@ static int btuart_probe(struct pcmcia_device *link)
info->p_dev = link;
link->priv = info;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
link->resource[0]->end = 8;
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP;
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
CONF_AUTO_SET_IO;
return btuart_config(link);
}
......@@ -602,38 +600,41 @@ static void btuart_detach(struct pcmcia_device *link)
kfree(info);
}
static int btuart_check_config(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
void *priv_data)
static int btuart_check_config(struct pcmcia_device *p_dev, void *priv_data)
{
int *try = priv_data;
p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
(cf->io.win[0].base != 0)) {
p_dev->resource[0]->start = cf->io.win[0].base;
if (!pcmcia_request_io(p_dev))
return 0;
}
return -ENODEV;
if (try == 0)
p_dev->io_lines = 16;
if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0))
return -EINVAL;
p_dev->resource[0]->end = 8;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
return pcmcia_request_io(p_dev);
}
static int btuart_check_config_notpicky(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
void *priv_data)
{
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->resource[0]->start = base[j];
p_dev->io_lines = base[j] ? 16 : 3;
if (!pcmcia_request_io(p_dev))
return 0;
}
if (p_dev->io_lines > 3)
return -ENODEV;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->resource[0]->end = 8;
for (j = 0; j < 5; j++) {
p_dev->resource[0]->start = base[j];
p_dev->io_lines = base[j] ? 16 : 3;
if (!pcmcia_request_io(p_dev))
return 0;
}
return -ENODEV;
}
......
......@@ -571,10 +571,7 @@ static int dtl1_probe(struct pcmcia_device *link)
info->p_dev = link;
link->priv = info;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
link->resource[0]->end = 8;
link->config_flags |= CONF_ENABLE_IRQ;
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
return dtl1_config(link);
}
......@@ -589,17 +586,14 @@ static void dtl1_detach(struct pcmcia_device *link)
kfree(info);
}
static int dtl1_confcheck(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
void *priv_data)
static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data)
{
if ((cf->io.nwin != 1) || (cf->io.win[0].len <= 8))
if ((p_dev->resource[1]->end) || (p_dev->resource[1]->end < 8))
return -ENODEV;
p_dev->resource[0]->start = cf->io.win[0].base;
p_dev->resource[0]->end = cf->io.win[0].len; /*yo */
p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
return pcmcia_request_io(p_dev);
}
......
......@@ -1741,19 +1741,8 @@ static void cmm_cm4000_release(struct pcmcia_device * link)
/*==== Interface to PCMCIA Layer =======================================*/
static int cm4000_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
void *priv_data)
static int cm4000_config_check(struct pcmcia_device *p_dev, void *priv_data)
{
if (!cfg->io.nwin)
return -ENODEV;
p_dev->resource[0]->start = cfg->io.win[0].base;
p_dev->resource[0]->end = cfg->io.win[0].len;
p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags);
p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK;
return pcmcia_request_io(p_dev);
}
......@@ -1761,6 +1750,8 @@ static int cm4000_config(struct pcmcia_device * link, int devno)
{
struct cm4000_dev *dev;
link->config_flags |= CONF_AUTO_SET_IO;
/* read the config-tuples */
if (pcmcia_loop_config(link, cm4000_config_check, NULL))
goto cs_release;
......
......@@ -515,25 +515,9 @@ static void cm4040_reader_release(struct pcmcia_device *link)
return;
}
static int cm4040_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
void *priv_data)
static int cm4040_config_check(struct pcmcia_device *p_dev, void *priv_data)
{
int rc;
if (!cfg->io.nwin)
return -ENODEV;
/* Get the IOaddr */
p_dev->resource[0]->start = cfg->io.win[0].base;
p_dev->resource[0]->end = cfg->io.win[0].len;
p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags);
p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK;
rc = pcmcia_request_io(p_dev);
dev_printk(KERN_INFO, &p_dev->dev,
"pcmcia_request_io returned 0x%x\n", rc);
return rc;
return pcmcia_request_io(p_dev);
}
......@@ -542,6 +526,8 @@ static int reader_config(struct pcmcia_device *link, int devno)
struct reader_dev *dev;
int fail_rc;
link->config_flags |= CONF_AUTO_SET_IO;
if (pcmcia_loop_config(link, cm4040_config_check, NULL))
goto cs_release;
......
......@@ -75,22 +75,18 @@ static void signalled_reboot_callback(void *callback_data)
schedule_work(&ipw->work_reboot);
}
static int ipwireless_probe(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
void *priv_data)
static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data)
{
struct ipw_dev *ipw = priv_data;
struct resource *io_resource;
int ret;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
p_dev->resource[0]->start = cfg->io.win[0].base;
p_dev->resource[0]->end = cfg->io.win[0].len;
/* 0x40 causes it to generate level mode interrupts. */
/* 0x04 enables IREQ pin. */
p_dev->config_index = cfg->index | 0x44;
p_dev->config_index |= 0x44;
p_dev->io_lines = 16;
ret = pcmcia_request_io(p_dev);
if (ret)
......@@ -100,26 +96,18 @@ static int ipwireless_probe(struct pcmcia_device *p_dev,
resource_size(p_dev->resource[0]),
IPWIRELESS_PCCARD_NAME);
if (cfg->mem.nwin == 0)
return 0;
p_dev->resource[2]->flags |=
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
p_dev->resource[2]->start = cfg->mem.win[0].host_addr;
p_dev->resource[2]->end = cfg->mem.win[0].len;
if (p_dev->resource[2]->end < 0x1000)
p_dev->resource[2]->end = 0x1000;
ret = pcmcia_request_window(p_dev, p_dev->resource[2], 0);
if (ret != 0)
goto exit1;
ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2],
cfg->mem.win[0].card_addr);
ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2], p_dev->card_addr);
if (ret != 0)
goto exit2;
ipw->is_v2_card = cfg->mem.win[0].len == 0x100;
ipw->is_v2_card = resource_size(p_dev->resource[2]) == 0x100;
ipw->attr_memory = ioremap(p_dev->resource[2]->start,
resource_size(p_dev->resource[2]));
......@@ -165,13 +153,13 @@ static int config_ipwireless(struct ipw_dev *ipw)
int ret = 0;
ipw->is_v2_card = 0;
link->config_flags |= CONF_AUTO_SET_IO | CONF_AUTO_SET_IOMEM |
CONF_ENABLE_IRQ;
ret = pcmcia_loop_config(link, ipwireless_probe, ipw);
if (ret != 0)
return ret;
link->config_flags |= CONF_ENABLE_IRQ;
INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
ipwireless_init_hardware_v1(ipw->hardware, link->resource[0]->start,
......
......@@ -561,19 +561,8 @@ static int mgslpc_probe(struct pcmcia_device *link)
/* Card has been inserted.
*/
static int mgslpc_ioprobe(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
void *priv_data)
static int mgslpc_ioprobe(struct pcmcia_device *p_dev, void *priv_data)
{
if (!cfg->io.nwin)
return -ENODEV;
p_dev->resource[0]->start = cfg->io.win[0].base;
p_dev->resource[0]->end = cfg->io.win[0].len;
p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags);
p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK;
return pcmcia_request_io(p_dev);
}
......@@ -585,11 +574,12 @@ static int mgslpc_config(struct pcmcia_device *link)
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_config(0x%p)\n", link);
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL);
if (ret != 0)
goto failed;
link->config_flags |= CONF_ENABLE_IRQ;
link->config_index = 8;
link->config_regs = PRESENT_OPTION;
......
......@@ -96,10 +96,8 @@ static int ide_probe(struct pcmcia_device *link)
info->p_dev = link;
link->priv = info;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
link->config_flags |= CONF_ENABLE_IRQ;
link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO |
CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
return ide_config(link);
} /* ide_attach */
......@@ -194,52 +192,31 @@ out_release:
======================================================================*/
struct pcmcia_config_check {
unsigned long ctl_base;
int is_kme;
};
static int pcmcia_check_one_config(struct pcmcia_device *pdev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
void *priv_data)
static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data)
{
struct pcmcia_config_check *stk = priv_data;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
pdev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
pdev->config_index = cfg->index;
pdev->resource[0]->start = io->win[0].base;
if (!(io->flags & CISTPL_IO_16BIT)) {
pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
}
if (io->nwin == 2) {
pdev->resource[0]->end = 8;
pdev->resource[1]->start = io->win[1].base;
pdev->resource[1]->end = (stk->is_kme) ? 2 : 1;
if (pcmcia_request_io(pdev) != 0)
return -ENODEV;
stk->ctl_base = pdev->resource[1]->start;
} else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
pdev->resource[0]->end = io->win[0].len;
pdev->resource[1]->end = 0;
if (pcmcia_request_io(pdev) != 0)
return -ENODEV;
stk->ctl_base = pdev->resource[0]->start + 0x0e;
} else
int *is_kme = priv_data;
if (!(pdev->resource[0]->flags & IO_DATA_PATH_WIDTH_8)) {
pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
}
pdev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
if (pdev->resource[1]->end) {
pdev->resource[0]->end = 8;
pdev->resource[1]->end = (*is_kme) ? 2 : 1;
} else {
if (pdev->resource[0]->end < 16)
return -ENODEV;
/* If we've got this far, we're done */
return 0;
}
return -ENODEV;
return pcmcia_request_io(pdev);
}
static int ide_config(struct pcmcia_device *link)
{
ide_info_t *info = link->priv;
struct pcmcia_config_check *stk = NULL;
int ret = 0, is_kme = 0;
unsigned long io_base, ctl_base;
struct ide_host *host;
......@@ -250,19 +227,16 @@ static int ide_config(struct pcmcia_device *link)
((link->card_id == PRODID_KME_KXLC005_A) ||
(link->card_id == PRODID_KME_KXLC005_B)));
stk = kzalloc(sizeof(*stk), GFP_KERNEL);
if (!stk)
goto err_mem;
stk->is_kme = is_kme;
io_base = ctl_base = 0;
if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) {
if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme)) {
link->config_flags &= ~CONF_AUTO_CHECK_VCC;
if (pcmcia_loop_config(link, pcmcia_check_one_config, stk))
if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme))
goto failed; /* No suitable config found */
}
io_base = link->resource[0]->start;
ctl_base = stk->ctl_base;
if (link->resource[1]->end)
ctl_base = link->resource[1]->start;
else
ctl_base = link->resource[0]->start + 0x0e;
if (!link->irq)
goto failed;
......@@ -294,15 +268,9 @@ static int ide_config(struct pcmcia_device *link)
'a' + host->ports[0]->index * 2,
link->vpp / 10, link->vpp % 10);
kfree(stk);
return 0;
err_mem:
printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
goto failed;
failed:
kfree(stk);
ide_release(link);
return -ENODEV;
} /* ide_config */
......
......@@ -72,13 +72,8 @@ static void avmcs_detach(struct pcmcia_device *p_dev);
static int avmcs_probe(struct pcmcia_device *p_dev)
{
/* The io structure describes IO port mapping */
p_dev->resource[0]->end = 16;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
/* General socket configuration */
p_dev->config_flags |= CONF_ENABLE_IRQ;
p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
p_dev->config_index = 1;
p_dev->config_regs = PRESENT_OPTION;
......@@ -107,16 +102,12 @@ static void avmcs_detach(struct pcmcia_device *link)
======================================================================*/
static int avmcs_configcheck(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
void *priv_data)
static int avmcs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
{
if (cf->io.nwin <= 0)
return -ENODEV;
p_dev->resource[0]->end = 16;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->resource[0]->start = cf->io.win[0].base;
p_dev->resource[0]->end = cf->io.win[0].len;
return pcmcia_request_io(p_dev);
}
......
......@@ -76,14 +76,8 @@ static int __devinit avma1cs_probe(struct pcmcia_device *p_dev)
{
dev_dbg(&p_dev->dev, "avma1cs_attach()\n");
/* The io structure describes IO port mapping */
p_dev->resource[0]->end = 16;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->resource[1]->end = 16;
p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_16;
/* General socket configuration */
p_dev->config_flags |= CONF_ENABLE_IRQ;
p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
p_dev->config_index = 1;
p_dev->config_regs = PRESENT_OPTION;
......@@ -114,17 +108,13 @@ static void __devexit avma1cs_detach(struct pcmcia_device *link)
======================================================================*/
static int avma1cs_configcheck(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
void *priv_data)
static int avma1cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
{
if (cf->io.nwin <= 0)