Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6: (22 commits)
  pcmcia: synclink_cs: fix information leak to userland
  pcmcia: don't call flush_scheduled_work() spuriously
  serial_cs: drop spurious flush_scheduled_work() call
  pcmcia/yenta: guide users in case of problems with O2-bridges
  pcmcia: fix unused function compile warning
  pcmcia: vrc4173_cardu: Fix error path for pci_release_regions and pci_disable_device
  pcmcia: add a few debug statements
  pcmcia: remove obsolete and wrong comments
  pcmcia: avoid messages on module (un)loading
  pcmcia: move driver name to struct pcmcia_driver
  pcmcia: remove the "Finally, report what we've done" message
  pcmcia: use autoconfiguration feature for ioports and iomem
  pcmcia: introduce autoconfiguration feature
  pcmcia: Documentation update
  pcmcia: convert pcmcia_request_configuration to pcmcia_enable_device
  pcmcia: move config_{base,index,regs} to struct pcmcia_device
  pcmcia: simplify IntType
  pcmcia: simplify Status, ExtStatus register access
  pcmcia: remove Pin, Copy configuration register access
  pcmcia: move Vpp setup to struct pcmcia_device
  ...
This commit is contained in:
Linus Torvalds 2010-10-21 14:25:16 -07:00
commit b65378898c
96 changed files with 1325 additions and 4133 deletions

View file

@ -1,4 +1,29 @@
This file details changes in 2.6 which affect PCMCIA card driver authors: 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
stored in struct pcmcia_device, e.g. in the fields config_flags,
config_index, config_base, vpp.
* pcmcia_request_window changes (as of 2.6.36)
Instead of win_req_t, drivers are now requested to fill out
struct pcmcia_device *p_dev->resource[2,3,4,5] for up to four ioport
ranges. After a call to pcmcia_request_window(), the regions found there
are reserved and may be used immediately -- until pcmcia_release_window()
is called.
* pcmcia_request_io changes (as of 2.6.36) * pcmcia_request_io changes (as of 2.6.36)
Instead of io_req_t, drivers are now requested to fill out Instead of io_req_t, drivers are now requested to fill out
struct pcmcia_device *p_dev->resource[0,1] for up to two ioport struct pcmcia_device *p_dev->resource[0,1] for up to two ioport

View file

@ -34,7 +34,6 @@
#include <linux/ata.h> #include <linux/ata.h>
#include <linux/libata.h> #include <linux/libata.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
@ -168,63 +167,26 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
}; };
struct pcmcia_config_check { static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data)
unsigned long ctl_base;
int skip_vcc;
int is_kme;
};
static int pcmcia_check_one_config(struct pcmcia_device *pdev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
struct pcmcia_config_check *stk = priv_data; int *is_kme = priv_data;
/* Check for matching Vcc, unless we're desperate */ if (!(pdev->resource[0]->flags & IO_DATA_PATH_WIDTH_8)) {
if (!stk->skip_vcc) { pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
return -ENODEV;
} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
return -ENODEV;
}
} }
pdev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) if (pdev->resource[1]->end) {
pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; pdev->resource[0]->end = 8;
else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) pdev->resource[1]->end = (*is_kme) ? 2 : 1;
pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; } else {
if (pdev->resource[0]->end < 16)
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
return -ENODEV; return -ENODEV;
/* If we've got this far, we're done */
return 0;
} }
return -ENODEV;
return pcmcia_request_io(pdev);
} }
/** /**
@ -239,7 +201,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
{ {
struct ata_host *host; struct ata_host *host;
struct ata_port *ap; struct ata_port *ap;
struct pcmcia_config_check *stk = NULL;
int is_kme = 0, ret = -ENOMEM, p; int is_kme = 0, ret = -ENOMEM, p;
unsigned long io_base, ctl_base; unsigned long io_base, ctl_base;
void __iomem *io_addr, *ctl_addr; void __iomem *io_addr, *ctl_addr;
@ -247,10 +208,8 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
struct ata_port_operations *ops = &pcmcia_port_ops; struct ata_port_operations *ops = &pcmcia_port_ops;
/* Set up attributes in order to probe card and get resources */ /* Set up attributes in order to probe card and get resources */
pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; pdev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO |
pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
pdev->conf.Attributes = CONF_ENABLE_IRQ;
pdev->conf.IntType = INT_MEMORY_AND_IO;
/* See if we have a manufacturer identifier. Use it to set is_kme for /* See if we have a manufacturer identifier. Use it to set is_kme for
vendor quirks */ vendor quirks */
@ -258,25 +217,21 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
((pdev->card_id == PRODID_KME_KXLC005_A) || ((pdev->card_id == PRODID_KME_KXLC005_A) ||
(pdev->card_id == PRODID_KME_KXLC005_B))); (pdev->card_id == PRODID_KME_KXLC005_B)));
/* Allocate resoure probing structures */ if (pcmcia_loop_config(pdev, pcmcia_check_one_config, &is_kme)) {
pdev->config_flags &= ~CONF_AUTO_CHECK_VCC;
stk = kzalloc(sizeof(*stk), GFP_KERNEL); if (pcmcia_loop_config(pdev, pcmcia_check_one_config, &is_kme))
if (!stk)
goto out1;
stk->is_kme = is_kme;
stk->skip_vcc = io_base = ctl_base = 0;
if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) {
stk->skip_vcc = 1;
if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk))
goto failed; /* No suitable config found */ goto failed; /* No suitable config found */
} }
io_base = pdev->resource[0]->start; 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) if (!pdev->irq)
goto failed; goto failed;
ret = pcmcia_request_configuration(pdev, &pdev->conf); ret = pcmcia_enable_device(pdev);
if (ret) if (ret)
goto failed; goto failed;
@ -329,13 +284,10 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
goto failed; goto failed;
pdev->priv = host; pdev->priv = host;
kfree(stk);
return 0; return 0;
failed: failed:
kfree(stk);
pcmcia_disable_device(pdev); pcmcia_disable_device(pdev);
out1:
return ret; return ret;
} }
@ -430,9 +382,7 @@ MODULE_DEVICE_TABLE(pcmcia, pcmcia_devices);
static struct pcmcia_driver pcmcia_driver = { static struct pcmcia_driver pcmcia_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = DRV_NAME,
.name = DRV_NAME,
},
.id_table = pcmcia_devices, .id_table = pcmcia_devices,
.probe = pcmcia_init_one, .probe = pcmcia_init_one,
.remove = pcmcia_remove_one, .remove = pcmcia_remove_one,

View file

@ -39,7 +39,6 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/io.h> #include <linux/io.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -865,8 +864,7 @@ static int bluecard_probe(struct pcmcia_device *link)
info->p_dev = link; info->p_dev = link;
link->priv = info; link->priv = info;
link->conf.Attributes = CONF_ENABLE_IRQ; link->config_flags |= CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
return bluecard_config(link); return bluecard_config(link);
} }
@ -886,7 +884,7 @@ static int bluecard_config(struct pcmcia_device *link)
bluecard_info_t *info = link->priv; bluecard_info_t *info = link->priv;
int i, n; int i, n;
link->conf.ConfigIndex = 0x20; link->config_index = 0x20;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
link->resource[0]->end = 64; link->resource[0]->end = 64;
@ -906,7 +904,7 @@ static int bluecard_config(struct pcmcia_device *link)
if (i != 0) if (i != 0)
goto failed; goto failed;
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_enable_device(link);
if (i != 0) if (i != 0)
goto failed; goto failed;
@ -942,9 +940,7 @@ MODULE_DEVICE_TABLE(pcmcia, bluecard_ids);
static struct pcmcia_driver bluecard_driver = { static struct pcmcia_driver bluecard_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "bluecard_cs",
.name = "bluecard_cs",
},
.probe = bluecard_probe, .probe = bluecard_probe,
.remove = bluecard_detach, .remove = bluecard_detach,
.id_table = bluecard_ids, .id_table = bluecard_ids,

View file

@ -45,7 +45,6 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -657,11 +656,8 @@ static int bt3c_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->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
link->resource[0]->end = 8; CONF_AUTO_SET_IO;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
return bt3c_config(link); return bt3c_config(link);
} }
@ -675,43 +671,41 @@ static void bt3c_detach(struct pcmcia_device *link)
kfree(info); kfree(info);
} }
static int bt3c_check_config(struct pcmcia_device *p_dev, static int bt3c_check_config(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
unsigned long try = (unsigned long) priv_data; int *try = priv_data;
p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; if (try == 0)
p_dev->io_lines = 16;
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0))
p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; return -EINVAL;
if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
(cf->io.win[0].base != 0)) { p_dev->resource[0]->end = 8;
p_dev->resource[0]->start = cf->io.win[0].base; p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
if (!pcmcia_request_io(p_dev)) p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
return 0;
} return pcmcia_request_io(p_dev);
return -ENODEV;
} }
static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev, static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data) void *priv_data)
{ {
static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
int j; int j;
if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { if (p_dev->io_lines > 3)
for (j = 0; j < 5; j++) { return -ENODEV;
p_dev->resource[0]->start = base[j];
p_dev->io_lines = base[j] ? 16 : 3; p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
if (!pcmcia_request_io(p_dev)) p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
return 0; 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; return -ENODEV;
} }
@ -742,7 +736,7 @@ found_port:
if (i != 0) if (i != 0)
goto failed; goto failed;
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_enable_device(link);
if (i != 0) if (i != 0)
goto failed; goto failed;
@ -775,9 +769,7 @@ MODULE_DEVICE_TABLE(pcmcia, bt3c_ids);
static struct pcmcia_driver bt3c_driver = { static struct pcmcia_driver bt3c_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "bt3c_cs",
.name = "bt3c_cs",
},
.probe = bt3c_probe, .probe = bt3c_probe,
.remove = bt3c_detach, .remove = bt3c_detach,
.id_table = bt3c_ids, .id_table = bt3c_ids,

View file

@ -41,7 +41,6 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -586,11 +585,8 @@ static int btuart_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->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
link->resource[0]->end = 8; CONF_AUTO_SET_IO;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
return btuart_config(link); return btuart_config(link);
} }
@ -604,43 +600,41 @@ static void btuart_detach(struct pcmcia_device *link)
kfree(info); kfree(info);
} }
static int btuart_check_config(struct pcmcia_device *p_dev, static int btuart_check_config(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
int *try = priv_data; int *try = priv_data;
p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; if (try == 0)
p_dev->io_lines = 16;
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0))
p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; return -EINVAL;
if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
(cf->io.win[0].base != 0)) { p_dev->resource[0]->end = 8;
p_dev->resource[0]->start = cf->io.win[0].base; p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
if (!pcmcia_request_io(p_dev)) p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
return 0;
} return pcmcia_request_io(p_dev);
return -ENODEV;
} }
static int btuart_check_config_notpicky(struct pcmcia_device *p_dev, 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) void *priv_data)
{ {
static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
int j; int j;
if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { if (p_dev->io_lines > 3)
for (j = 0; j < 5; j++) { return -ENODEV;
p_dev->resource[0]->start = base[j];
p_dev->io_lines = base[j] ? 16 : 3; p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
if (!pcmcia_request_io(p_dev)) p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
return 0; 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; return -ENODEV;
} }
@ -671,7 +665,7 @@ found_port:
if (i != 0) if (i != 0)
goto failed; goto failed;
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_enable_device(link);
if (i != 0) if (i != 0)
goto failed; goto failed;
@ -703,9 +697,7 @@ MODULE_DEVICE_TABLE(pcmcia, btuart_ids);
static struct pcmcia_driver btuart_driver = { static struct pcmcia_driver btuart_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "btuart_cs",
.name = "btuart_cs",
},
.probe = btuart_probe, .probe = btuart_probe,
.remove = btuart_detach, .remove = btuart_detach,
.id_table = btuart_ids, .id_table = btuart_ids,

View file

@ -41,7 +41,6 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -572,11 +571,7 @@ static int dtl1_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->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
link->resource[0]->end = 8;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
return dtl1_config(link); return dtl1_config(link);
} }
@ -591,18 +586,14 @@ static void dtl1_detach(struct pcmcia_device *link)
kfree(info); kfree(info);
} }
static int dtl1_confcheck(struct pcmcia_device *p_dev, static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
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; return -ENODEV;
p_dev->resource[0]->start = cf->io.win[0].base; p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->end = cf->io.win[0].len; /*yo */ p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK;
return pcmcia_request_io(p_dev); return pcmcia_request_io(p_dev);
} }
@ -620,7 +611,7 @@ static int dtl1_config(struct pcmcia_device *link)
if (i != 0) if (i != 0)
goto failed; goto failed;
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_enable_device(link);
if (i != 0) if (i != 0)
goto failed; goto failed;
@ -656,9 +647,7 @@ MODULE_DEVICE_TABLE(pcmcia, dtl1_ids);
static struct pcmcia_driver dtl1_driver = { static struct pcmcia_driver dtl1_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "dtl1_cs",
.name = "dtl1_cs",
},
.probe = dtl1_probe, .probe = dtl1_probe,
.remove = dtl1_detach, .remove = dtl1_detach,
.id_table = dtl1_ids, .id_table = dtl1_ids,

View file

@ -34,7 +34,6 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/io.h> #include <linux/io.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
@ -55,8 +54,6 @@
__func__ , ## args); \ __func__ , ## args); \
} while (0) } while (0)
static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte";
#define T_1SEC (HZ) #define T_1SEC (HZ)
#define T_10MSEC msecs_to_jiffies(10) #define T_10MSEC msecs_to_jiffies(10)
#define T_20MSEC msecs_to_jiffies(20) #define T_20MSEC msecs_to_jiffies(20)
@ -1742,20 +1739,8 @@ static void cmm_cm4000_release(struct pcmcia_device * link)
/*==== Interface to PCMCIA Layer =======================================*/ /*==== Interface to PCMCIA Layer =======================================*/
static int cm4000_config_check(struct pcmcia_device *p_dev, static int cm4000_config_check(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
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); return pcmcia_request_io(p_dev);
} }
@ -1763,13 +1748,13 @@ static int cm4000_config(struct pcmcia_device * link, int devno)
{ {
struct cm4000_dev *dev; struct cm4000_dev *dev;
link->config_flags |= CONF_AUTO_SET_IO;
/* read the config-tuples */ /* read the config-tuples */
if (pcmcia_loop_config(link, cm4000_config_check, NULL)) if (pcmcia_loop_config(link, cm4000_config_check, NULL))
goto cs_release; goto cs_release;
link->conf.IntType = 00000002; if (pcmcia_enable_device(link))
if (pcmcia_request_configuration(link, &link->conf))
goto cs_release; goto cs_release;
dev = link->priv; dev = link->priv;
@ -1829,7 +1814,6 @@ static int cm4000_probe(struct pcmcia_device *link)
dev->p_dev = link; dev->p_dev = link;
link->priv = dev; link->priv = dev;
link->conf.IntType = INT_MEMORY_AND_IO;
dev_table[i] = link; dev_table[i] = link;
init_waitqueue_head(&dev->devq); init_waitqueue_head(&dev->devq);
@ -1891,9 +1875,7 @@ MODULE_DEVICE_TABLE(pcmcia, cm4000_ids);
static struct pcmcia_driver cm4000_driver = { static struct pcmcia_driver cm4000_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "cm4000_cs",
.name = "cm4000_cs",
},
.probe = cm4000_probe, .probe = cm4000_probe,
.remove = cm4000_detach, .remove = cm4000_detach,
.suspend = cm4000_suspend, .suspend = cm4000_suspend,
@ -1905,8 +1887,6 @@ static int __init cmm_init(void)
{ {
int rc; int rc;
printk(KERN_INFO "%s\n", version);
cmm_class = class_create(THIS_MODULE, "cardman_4000"); cmm_class = class_create(THIS_MODULE, "cardman_4000");
if (IS_ERR(cmm_class)) if (IS_ERR(cmm_class))
return PTR_ERR(cmm_class); return PTR_ERR(cmm_class);
@ -1931,7 +1911,6 @@ static int __init cmm_init(void)
static void __exit cmm_exit(void) static void __exit cmm_exit(void)
{ {
printk(KERN_INFO MODULE_NAME ": unloading\n");
pcmcia_unregister_driver(&cm4000_driver); pcmcia_unregister_driver(&cm4000_driver);
unregister_chrdev(major, DEVICE_NAME); unregister_chrdev(major, DEVICE_NAME);
class_destroy(cmm_class); class_destroy(cmm_class);

View file

@ -29,7 +29,6 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
@ -49,9 +48,6 @@
__func__ , ## args); \ __func__ , ## args); \
} while (0) } while (0)
static char *version =
"OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte";
#define CCID_DRIVER_BULK_DEFAULT_TIMEOUT (150*HZ) #define CCID_DRIVER_BULK_DEFAULT_TIMEOUT (150*HZ)
#define CCID_DRIVER_ASYNC_POWERUP_TIMEOUT (35*HZ) #define CCID_DRIVER_ASYNC_POWERUP_TIMEOUT (35*HZ)
#define CCID_DRIVER_MINIMUM_TIMEOUT (3*HZ) #define CCID_DRIVER_MINIMUM_TIMEOUT (3*HZ)
@ -516,26 +512,9 @@ static void cm4040_reader_release(struct pcmcia_device *link)
return; return;
} }
static int cm4040_config_check(struct pcmcia_device *p_dev, static int cm4040_config_check(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
int rc; return pcmcia_request_io(p_dev);
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;
} }
@ -544,15 +523,15 @@ static int reader_config(struct pcmcia_device *link, int devno)
struct reader_dev *dev; struct reader_dev *dev;
int fail_rc; int fail_rc;
link->config_flags |= CONF_AUTO_SET_IO;
if (pcmcia_loop_config(link, cm4040_config_check, NULL)) if (pcmcia_loop_config(link, cm4040_config_check, NULL))
goto cs_release; goto cs_release;
link->conf.IntType = 00000002; fail_rc = pcmcia_enable_device(link);
fail_rc = pcmcia_request_configuration(link, &link->conf);
if (fail_rc != 0) { if (fail_rc != 0) {
dev_printk(KERN_INFO, &link->dev, dev_printk(KERN_INFO, &link->dev,
"pcmcia_request_configuration failed 0x%x\n", "pcmcia_enable_device failed 0x%x\n",
fail_rc); fail_rc);
goto cs_release; goto cs_release;
} }
@ -599,7 +578,6 @@ static int reader_probe(struct pcmcia_device *link)
link->priv = dev; link->priv = dev;
dev->p_dev = link; dev->p_dev = link;
link->conf.IntType = INT_MEMORY_AND_IO;
dev_table[i] = link; dev_table[i] = link;
init_waitqueue_head(&dev->devq); init_waitqueue_head(&dev->devq);
@ -662,9 +640,7 @@ MODULE_DEVICE_TABLE(pcmcia, cm4040_ids);
static struct pcmcia_driver reader_driver = { static struct pcmcia_driver reader_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "cm4040_cs",
.name = "cm4040_cs",
},
.probe = reader_probe, .probe = reader_probe,
.remove = reader_detach, .remove = reader_detach,
.id_table = cm4040_ids, .id_table = cm4040_ids,
@ -674,7 +650,6 @@ static int __init cm4040_init(void)
{ {
int rc; int rc;
printk(KERN_INFO "%s\n", version);
cmx_class = class_create(THIS_MODULE, "cardman_4040"); cmx_class = class_create(THIS_MODULE, "cardman_4040");
if (IS_ERR(cmx_class)) if (IS_ERR(cmx_class))
return PTR_ERR(cmx_class); return PTR_ERR(cmx_class);
@ -699,7 +674,6 @@ static int __init cm4040_init(void)
static void __exit cm4040_exit(void) static void __exit cm4040_exit(void)
{ {
printk(KERN_INFO MODULE_NAME ": unloading\n");
pcmcia_unregister_driver(&reader_driver); pcmcia_unregister_driver(&reader_driver);
unregister_chrdev(major, DEVICE_NAME); unregister_chrdev(major, DEVICE_NAME);
class_destroy(cmx_class); class_destroy(cmx_class);

View file

@ -32,7 +32,6 @@
#include <pcmcia/device_id.h> #include <pcmcia/device_id.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/cs.h>
static struct pcmcia_device_id ipw_ids[] = { static struct pcmcia_device_id ipw_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x02f2, 0x0100), PCMCIA_DEVICE_MANF_CARD(0x02f2, 0x0100),
@ -76,23 +75,18 @@ static void signalled_reboot_callback(void *callback_data)
schedule_work(&ipw->work_reboot); schedule_work(&ipw->work_reboot);
} }
static int ipwireless_probe(struct pcmcia_device *p_dev, static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
struct ipw_dev *ipw = priv_data; struct ipw_dev *ipw = priv_data;
struct resource *io_resource; struct resource *io_resource;
int ret; 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]->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. */ /* 0x40 causes it to generate level mode interrupts. */
/* 0x04 enables IREQ pin. */ /* 0x04 enables IREQ pin. */
p_dev->conf.ConfigIndex = cfg->index | 0x44; p_dev->config_index |= 0x44;
p_dev->io_lines = 16; p_dev->io_lines = 16;
ret = pcmcia_request_io(p_dev); ret = pcmcia_request_io(p_dev);
if (ret) if (ret)
@ -102,65 +96,49 @@ static int ipwireless_probe(struct pcmcia_device *p_dev,
resource_size(p_dev->resource[0]), resource_size(p_dev->resource[0]),
IPWIRELESS_PCCARD_NAME); IPWIRELESS_PCCARD_NAME);
if (cfg->mem.nwin == 0) p_dev->resource[2]->flags |=
return 0;
ipw->request_common_memory.Attributes =
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
ipw->request_common_memory.Base = cfg->mem.win[0].host_addr;
ipw->request_common_memory.Size = cfg->mem.win[0].len;
if (ipw->request_common_memory.Size < 0x1000)
ipw->request_common_memory.Size = 0x1000;
ipw->request_common_memory.AccessSpeed = 0;
ret = pcmcia_request_window(p_dev, &ipw->request_common_memory,
&ipw->handle_common_memory);
ret = pcmcia_request_window(p_dev, p_dev->resource[2], 0);
if (ret != 0) if (ret != 0)
goto exit1; goto exit1;
ret = pcmcia_map_mem_page(p_dev, ipw->handle_common_memory, ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2], p_dev->card_addr);
cfg->mem.win[0].card_addr);
if (ret != 0) if (ret != 0)
goto exit2; goto exit2;
ipw->is_v2_card = cfg->mem.win[0].len == 0x100; ipw->is_v2_card = resource_size(p_dev->resource[2]) == 0x100;
ipw->common_memory = ioremap(ipw->request_common_memory.Base, ipw->attr_memory = ioremap(p_dev->resource[2]->start,
ipw->request_common_memory.Size); resource_size(p_dev->resource[2]));
request_mem_region(ipw->request_common_memory.Base, request_mem_region(p_dev->resource[2]->start,
ipw->request_common_memory.Size, resource_size(p_dev->resource[2]),
IPWIRELESS_PCCARD_NAME); IPWIRELESS_PCCARD_NAME);
ipw->request_attr_memory.Attributes = p_dev->resource[3]->flags |= WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM |
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE; WIN_ENABLE;
ipw->request_attr_memory.Base = 0; p_dev->resource[3]->end = 0; /* this used to be 0x1000 */
ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */ ret = pcmcia_request_window(p_dev, p_dev->resource[3], 0);
ipw->request_attr_memory.AccessSpeed = 0;
ret = pcmcia_request_window(p_dev, &ipw->request_attr_memory,
&ipw->handle_attr_memory);
if (ret != 0) if (ret != 0)
goto exit2; goto exit2;
ret = pcmcia_map_mem_page(p_dev, ipw->handle_attr_memory, 0); ret = pcmcia_map_mem_page(p_dev, p_dev->resource[3], 0);
if (ret != 0) if (ret != 0)
goto exit3; goto exit3;
ipw->attr_memory = ioremap(ipw->request_attr_memory.Base, ipw->attr_memory = ioremap(p_dev->resource[3]->start,
ipw->request_attr_memory.Size); resource_size(p_dev->resource[3]));
request_mem_region(ipw->request_attr_memory.Base, request_mem_region(p_dev->resource[3]->start,
ipw->request_attr_memory.Size, IPWIRELESS_PCCARD_NAME); resource_size(p_dev->resource[3]),
IPWIRELESS_PCCARD_NAME);
return 0; return 0;
exit3: exit3:
exit2: exit2:
if (ipw->common_memory) { if (ipw->common_memory) {
release_mem_region(ipw->request_common_memory.Base, release_mem_region(p_dev->resource[2]->start,
ipw->request_common_memory.Size); resource_size(p_dev->resource[2]));
iounmap(ipw->common_memory); iounmap(ipw->common_memory);
} }
exit1: exit1:
@ -175,14 +153,13 @@ static int config_ipwireless(struct ipw_dev *ipw)
int ret = 0; int ret = 0;
ipw->is_v2_card = 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); ret = pcmcia_loop_config(link, ipwireless_probe, ipw);
if (ret != 0) if (ret != 0)
return ret; return ret;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
INIT_WORK(&ipw->work_reboot, signalled_reboot_work); INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
ipwireless_init_hardware_v1(ipw->hardware, link->resource[0]->start, ipwireless_init_hardware_v1(ipw->hardware, link->resource[0]->start,
@ -201,13 +178,9 @@ static int config_ipwireless(struct ipw_dev *ipw)
(unsigned int) link->irq); (unsigned int) link->irq);
if (ipw->attr_memory && ipw->common_memory) if (ipw->attr_memory && ipw->common_memory)
printk(KERN_INFO IPWIRELESS_PCCARD_NAME printk(KERN_INFO IPWIRELESS_PCCARD_NAME
": attr memory 0x%08lx-0x%08lx, common memory 0x%08lx-0x%08lx\n", ": attr memory %pR, common memory %pR\n",
ipw->request_attr_memory.Base, link->resource[3],
ipw->request_attr_memory.Base link->resource[2]);
+ ipw->request_attr_memory.Size - 1,
ipw->request_common_memory.Base,
ipw->request_common_memory.Base
+ ipw->request_common_memory.Size - 1);
ipw->network = ipwireless_network_create(ipw->hardware); ipw->network = ipwireless_network_create(ipw->hardware);
if (!ipw->network) if (!ipw->network)
@ -223,25 +196,23 @@ static int config_ipwireless(struct ipw_dev *ipw)
* Do the RequestConfiguration last, because it enables interrupts. * Do the RequestConfiguration last, because it enables interrupts.
* Then we don't get any interrupts before we're ready for them. * Then we don't get any interrupts before we're ready for them.
*/ */
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret != 0) if (ret != 0)
goto exit; goto exit;
return 0; return 0;
exit: exit:
if (ipw->attr_memory) {
release_mem_region(ipw->request_attr_memory.Base,
ipw->request_attr_memory.Size);
iounmap(ipw->attr_memory);
}
if (ipw->common_memory) { if (ipw->common_memory) {
release_mem_region(ipw->request_common_memory.Base, release_mem_region(link->resource[2]->start,
ipw->request_common_memory.Size); resource_size(link->resource[2]));
iounmap(ipw->common_memory); iounmap(ipw->common_memory);
} }
if (ipw->attr_memory) {
release_mem_region(link->resource[3]->start,
resource_size(link->resource[3]));
iounmap(ipw->attr_memory);
}
pcmcia_disable_device(link); pcmcia_disable_device(link);
return -1; return -1;
} }
@ -249,13 +220,13 @@ exit:
static void release_ipwireless(struct ipw_dev *ipw) static void release_ipwireless(struct ipw_dev *ipw)
{ {
if (ipw->common_memory) { if (ipw->common_memory) {
release_mem_region(ipw->request_common_memory.Base, release_mem_region(ipw->link->resource[2]->start,
ipw->request_common_memory.Size); resource_size(ipw->link->resource[2]));
iounmap(ipw->common_memory); iounmap(ipw->common_memory);
} }
if (ipw->attr_memory) { if (ipw->attr_memory) {
release_mem_region(ipw->request_attr_memory.Base, release_mem_region(ipw->link->resource[3]->start,
ipw->request_attr_memory.Size); resource_size(ipw->link->resource[3]));
iounmap(ipw->attr_memory); iounmap(ipw->attr_memory);
} }
pcmcia_disable_device(ipw->link); pcmcia_disable_device(ipw->link);
@ -324,7 +295,7 @@ static struct pcmcia_driver me = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.probe = ipwireless_attach, .probe = ipwireless_attach,
.remove = ipwireless_detach, .remove = ipwireless_detach,
.drv = { .name = IPWIRELESS_PCCARD_NAME }, .name = IPWIRELESS_PCCARD_NAME,
.id_table = ipw_ids .id_table = ipw_ids
}; };
@ -336,9 +307,6 @@ static int __init init_ipwireless(void)
{ {
int ret; int ret;
printk(KERN_INFO IPWIRELESS_PCCARD_NAME " "
IPWIRELESS_PCMCIA_VERSION " by " IPWIRELESS_PCMCIA_AUTHOR "\n");
ret = ipwireless_tty_init(); ret = ipwireless_tty_init();
if (ret != 0) if (ret != 0)
return ret; return ret;
@ -355,9 +323,6 @@ static int __init init_ipwireless(void)
*/ */
static void __exit exit_ipwireless(void) static void __exit exit_ipwireless(void)
{ {
printk(KERN_INFO IPWIRELESS_PCCARD_NAME " "
IPWIRELESS_PCMCIA_VERSION " removed\n");
pcmcia_unregister_driver(&me); pcmcia_unregister_driver(&me);
ipwireless_tty_release(); ipwireless_tty_release();
} }

View file

@ -21,7 +21,6 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/types.h> #include <linux/types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -45,13 +44,9 @@ struct ipw_dev {
struct pcmcia_device *link; struct pcmcia_device *link;
int is_v2_card; int is_v2_card;
window_handle_t handle_attr_memory;
void __iomem *attr_memory; void __iomem *attr_memory;
win_req_t request_attr_memory;
window_handle_t handle_common_memory;
void __iomem *common_memory; void __iomem *common_memory;
win_req_t request_common_memory;
/* Reference to attribute memory, containing CIS data */ /* Reference to attribute memory, containing CIS data */
void *attribute_memory; void *attribute_memory;

View file

@ -21,7 +21,6 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>

View file

@ -70,7 +70,6 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/hdlc.h> #include <linux/hdlc.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -550,9 +549,6 @@ static int mgslpc_probe(struct pcmcia_device *link)
/* Initialize the struct pcmcia_device structure */ /* Initialize the struct pcmcia_device structure */
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
ret = mgslpc_config(link); ret = mgslpc_config(link);
if (ret) if (ret)
return ret; return ret;
@ -565,20 +561,8 @@ static int mgslpc_probe(struct pcmcia_device *link)
/* Card has been inserted. /* Card has been inserted.
*/ */
static int mgslpc_ioprobe(struct pcmcia_device *p_dev, static int mgslpc_ioprobe(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
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); return pcmcia_request_io(p_dev);
} }
@ -590,32 +574,24 @@ static int mgslpc_config(struct pcmcia_device *link)
if (debug_level >= DEBUG_LEVEL_INFO) if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_config(0x%p)\n", link); 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); ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL);
if (ret != 0) if (ret != 0)
goto failed; goto failed;
link->conf.Attributes = CONF_ENABLE_IRQ; link->config_index = 8;
link->conf.IntType = INT_MEMORY_AND_IO; link->config_regs = PRESENT_OPTION;
link->conf.ConfigIndex = 8;
link->conf.Present = PRESENT_OPTION;
ret = pcmcia_request_irq(link, mgslpc_isr); ret = pcmcia_request_irq(link, mgslpc_isr);
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
info->io_base = link->resource[0]->start; info->io_base = link->resource[0]->start;
info->irq_level = link->irq; info->irq_level = link->irq;
dev_info(&link->dev, "index 0x%02x:",
link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq);
if (link->resource[0])
printk(", io %pR", link->resource[0]);
printk("\n");
return 0; return 0;
failed: failed:
@ -2797,9 +2773,7 @@ MODULE_DEVICE_TABLE(pcmcia, mgslpc_ids);
static struct pcmcia_driver mgslpc_driver = { static struct pcmcia_driver mgslpc_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "synclink_cs",
.name = "synclink_cs",
},
.probe = mgslpc_probe, .probe = mgslpc_probe,
.remove = mgslpc_detach, .remove = mgslpc_detach,
.id_table = mgslpc_ids, .id_table = mgslpc_ids,
@ -2835,8 +2809,6 @@ static void synclink_cs_cleanup(void)
{ {
int rc; int rc;
printk("Unloading %s: version %s\n", driver_name, driver_version);
while(mgslpc_device_list) while(mgslpc_device_list)
mgslpc_remove_device(mgslpc_device_list); mgslpc_remove_device(mgslpc_device_list);
@ -2859,8 +2831,6 @@ static int __init synclink_cs_init(void)
BREAKPOINT(); BREAKPOINT();
} }
printk("%s %s\n", driver_name, driver_version);
if ((rc = pcmcia_register_driver(&mgslpc_driver)) < 0) if ((rc = pcmcia_register_driver(&mgslpc_driver)) < 0)
return rc; return rc;
@ -4127,6 +4097,8 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (cmd != SIOCWANDEV) if (cmd != SIOCWANDEV)
return hdlc_ioctl(dev, ifr, cmd); return hdlc_ioctl(dev, ifr, cmd);
memset(&new_line, 0, size);
switch(ifr->ifr_settings.type) { switch(ifr->ifr_settings.type) {
case IF_GET_IFACE: /* return current sync_serial_settings */ case IF_GET_IFACE: /* return current sync_serial_settings */

View file

@ -43,7 +43,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
@ -72,17 +71,6 @@ static int ide_config(struct pcmcia_device *);
static void ide_detach(struct pcmcia_device *p_dev); static void ide_detach(struct pcmcia_device *p_dev);
/*======================================================================
ide_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
======================================================================*/
static int ide_probe(struct pcmcia_device *link) static int ide_probe(struct pcmcia_device *link)
{ {
ide_info_t *info; ide_info_t *info;
@ -97,23 +85,12 @@ static int ide_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_AUTO; link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO |
link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
return ide_config(link); return ide_config(link);
} /* ide_attach */ } /* ide_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void ide_detach(struct pcmcia_device *link) static void ide_detach(struct pcmcia_device *link)
{ {
ide_info_t *info = link->priv; ide_info_t *info = link->priv;
@ -187,79 +164,31 @@ out_release:
return NULL; return NULL;
} }
/*====================================================================== static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data)
ide_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
ide device available to the system.
======================================================================*/
struct pcmcia_config_check {
unsigned long ctl_base;
int skip_vcc;
int is_kme;
};
static int pcmcia_check_one_config(struct pcmcia_device *pdev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
struct pcmcia_config_check *stk = priv_data; int *is_kme = priv_data;
/* Check for matching Vcc, unless we're desperate */ if (!(pdev->resource[0]->flags & IO_DATA_PATH_WIDTH_8)) {
if (!stk->skip_vcc) { pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
return -ENODEV;
} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
return -ENODEV;
}
} }
pdev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) if (pdev->resource[1]->end) {
pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; pdev->resource[0]->end = 8;
else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) pdev->resource[1]->end = (*is_kme) ? 2 : 1;
pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; } else {
if (pdev->resource[0]->end < 16)
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->conf.ConfigIndex = 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
return -ENODEV; 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) static int ide_config(struct pcmcia_device *link)
{ {
ide_info_t *info = link->priv; ide_info_t *info = link->priv;
struct pcmcia_config_check *stk = NULL;
int ret = 0, is_kme = 0; int ret = 0, is_kme = 0;
unsigned long io_base, ctl_base; unsigned long io_base, ctl_base;
struct ide_host *host; struct ide_host *host;
@ -270,23 +199,21 @@ static int ide_config(struct pcmcia_device *link)
((link->card_id == PRODID_KME_KXLC005_A) || ((link->card_id == PRODID_KME_KXLC005_A) ||
(link->card_id == PRODID_KME_KXLC005_B))); (link->card_id == PRODID_KME_KXLC005_B)));
stk = kzalloc(sizeof(*stk), GFP_KERNEL); if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme)) {
if (!stk) link->config_flags &= ~CONF_AUTO_CHECK_VCC;
goto err_mem; if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme))
stk->is_kme = is_kme;
stk->skip_vcc = io_base = ctl_base = 0;
if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) {
stk->skip_vcc = 1;
if (pcmcia_loop_config(link, pcmcia_check_one_config, stk))
goto failed; /* No suitable config found */ goto failed; /* No suitable config found */
} }
io_base = link->resource[0]->start; 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) if (!link->irq)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf);
ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
@ -311,29 +238,15 @@ static int ide_config(struct pcmcia_device *link)
info->host = host; info->host = host;
dev_info(&link->dev, "ide-cs: hd%c: Vpp = %d.%d\n", dev_info(&link->dev, "ide-cs: hd%c: Vpp = %d.%d\n",
'a' + host->ports[0]->index * 2, 'a' + host->ports[0]->index * 2,
link->conf.Vpp / 10, link->conf.Vpp % 10); link->vpp / 10, link->vpp % 10);
kfree(stk);
return 0; return 0;
err_mem:
printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
goto failed;
failed: failed:
kfree(stk);
ide_release(link); ide_release(link);
return -ENODEV; return -ENODEV;
} /* ide_config */ } /* ide_config */
/*======================================================================
After a card is removed, ide_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void ide_release(struct pcmcia_device *link) static void ide_release(struct pcmcia_device *link)
{ {
ide_info_t *info = link->priv; ide_info_t *info = link->priv;
@ -359,15 +272,6 @@ static void ide_release(struct pcmcia_device *link)
} /* ide_release */ } /* ide_release */
/*======================================================================
The card status event handler. Mostly, this schedules other
stuff to run after an event is received. A CARD_REMOVAL event
also sets some flags to discourage the ide drivers from
talking to the ports.
======================================================================*/
static struct pcmcia_device_id ide_ids[] = { static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_FUNC_ID(4), PCMCIA_DEVICE_FUNC_ID(4),
PCMCIA_DEVICE_MANF_CARD(0x0000, 0x0000), /* Corsair */ PCMCIA_DEVICE_MANF_CARD(0x0000, 0x0000), /* Corsair */
@ -440,9 +344,7 @@ MODULE_DEVICE_TABLE(pcmcia, ide_ids);
static struct pcmcia_driver ide_cs_driver = { static struct pcmcia_driver ide_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "ide-cs",
.name = "ide-cs",
},
.probe = ide_probe, .probe = ide_probe,
.remove = ide_detach, .remove = ide_detach,
.id_table = ide_ids, .id_table = ide_ids,

View file

@ -20,7 +20,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -39,87 +38,32 @@ MODULE_LICENSE("GPL");
/*====================================================================*/ /*====================================================================*/
/*
The event() function is this driver's Card Services event handler.
It will be called by Card Services when an appropriate card status
event is received. The config() and release() entry points are
used to configure or release a socket, in response to card insertion
and ejection events. They are invoked from the skeleton event
handler.
*/
static int avmcs_config(struct pcmcia_device *link); static int avmcs_config(struct pcmcia_device *link);
static void avmcs_release(struct pcmcia_device *link); static void avmcs_release(struct pcmcia_device *link);
/*
The attach() and detach() entry points are used to create and destroy
"instances" of the driver, where each instance represents everything
needed to manage one actual PCMCIA card.
*/
static void avmcs_detach(struct pcmcia_device *p_dev); static void avmcs_detach(struct pcmcia_device *p_dev);
/*======================================================================
avmcs_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
static int avmcs_probe(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 */ /* General socket configuration */
p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
p_dev->conf.IntType = INT_MEMORY_AND_IO; p_dev->config_index = 1;
p_dev->conf.ConfigIndex = 1; p_dev->config_regs = PRESENT_OPTION;
p_dev->conf.Present = PRESENT_OPTION;
return avmcs_config(p_dev); return avmcs_config(p_dev);
} /* avmcs_attach */ } /* avmcs_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void avmcs_detach(struct pcmcia_device *link) static void avmcs_detach(struct pcmcia_device *link)
{ {
avmcs_release(link); avmcs_release(link);
} /* avmcs_detach */ } /* avmcs_detach */
/*====================================================================== static int avmcs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
avmcs_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
ethernet device available to the system.
======================================================================*/
static int avmcs_configcheck(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
if (cf->io.nwin <= 0) p_dev->resource[0]->end = 16;
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]->start = cf->io.win[0].base;
p_dev->resource[0]->end = cf->io.win[0].len;
return pcmcia_request_io(p_dev); return pcmcia_request_io(p_dev);
} }
@ -150,7 +94,7 @@ static int avmcs_config(struct pcmcia_device *link)
/* /*
* configure the PCMCIA socket * configure the PCMCIA socket
*/ */
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_enable_device(link);
if (i != 0) { if (i != 0) {
pcmcia_disable_device(link); pcmcia_disable_device(link);
break; break;
@ -197,13 +141,6 @@ static int avmcs_config(struct pcmcia_device *link)
} /* avmcs_config */ } /* avmcs_config */
/*======================================================================
After a card is removed, avmcs_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void avmcs_release(struct pcmcia_device *link) static void avmcs_release(struct pcmcia_device *link)
{ {
@ -222,9 +159,7 @@ MODULE_DEVICE_TABLE(pcmcia, avmcs_ids);
static struct pcmcia_driver avmcs_driver = { static struct pcmcia_driver avmcs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "avm_cs",
.name = "avm_cs",
},
.probe = avmcs_probe, .probe = avmcs_probe,
.remove = avmcs_detach, .remove = avmcs_detach,
.id_table = avmcs_ids, .id_table = avmcs_ids,

View file

@ -20,7 +20,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include "hisax_cfg.h" #include "hisax_cfg.h"
@ -40,67 +39,22 @@ module_param(isdnprot, int, 0);
/*====================================================================*/ /*====================================================================*/
/*
The event() function is this driver's Card Services event handler.
It will be called by Card Services when an appropriate card status
event is received. The config() and release() entry points are
used to configure or release a socket, in response to card insertion
and ejection events. They are invoked from the skeleton event
handler.
*/
static int avma1cs_config(struct pcmcia_device *link) __devinit ; static int avma1cs_config(struct pcmcia_device *link) __devinit ;
static void avma1cs_release(struct pcmcia_device *link); static void avma1cs_release(struct pcmcia_device *link);
/*
The attach() and detach() entry points are used to create and destroy
"instances" of the driver, where each instance represents everything
needed to manage one actual PCMCIA card.
*/
static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ; static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ;
/*======================================================================
avma1cs_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
static int __devinit avma1cs_probe(struct pcmcia_device *p_dev) static int __devinit avma1cs_probe(struct pcmcia_device *p_dev)
{ {
dev_dbg(&p_dev->dev, "avma1cs_attach()\n"); 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 */ /* General socket configuration */
p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
p_dev->conf.IntType = INT_MEMORY_AND_IO; p_dev->config_index = 1;
p_dev->conf.ConfigIndex = 1; p_dev->config_regs = PRESENT_OPTION;
p_dev->conf.Present = PRESENT_OPTION;
return avma1cs_config(p_dev); return avma1cs_config(p_dev);
} /* avma1cs_attach */ } /* avma1cs_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void __devexit avma1cs_detach(struct pcmcia_device *link) static void __devexit avma1cs_detach(struct pcmcia_device *link)
{ {
dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link); dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link);
@ -108,26 +62,13 @@ static void __devexit avma1cs_detach(struct pcmcia_device *link)
kfree(link->priv); kfree(link->priv);
} /* avma1cs_detach */ } /* avma1cs_detach */
/*====================================================================== static int avma1cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
avma1cs_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
ethernet device available to the system.
======================================================================*/
static int avma1cs_configcheck(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
if (cf->io.nwin <= 0) p_dev->resource[0]->end = 16;
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]->start = cf->io.win[0].base;
p_dev->resource[0]->end = cf->io.win[0].len;
p_dev->io_lines = 5; p_dev->io_lines = 5;
return pcmcia_request_io(p_dev); return pcmcia_request_io(p_dev);
} }
@ -161,7 +102,7 @@ static int __devinit avma1cs_config(struct pcmcia_device *link)
/* /*
* configure the PCMCIA socket * configure the PCMCIA socket
*/ */
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_enable_device(link);
if (i != 0) { if (i != 0) {
pcmcia_disable_device(link); pcmcia_disable_device(link);
break; break;
@ -175,9 +116,6 @@ static int __devinit avma1cs_config(struct pcmcia_device *link)
return -ENODEV; return -ENODEV;
} }
printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n",
(unsigned int) link->resource[0]->start, link->irq);
icard.para[0] = link->irq; icard.para[0] = link->irq;
icard.para[1] = link->resource[0]->start; icard.para[1] = link->resource[0]->start;
icard.protocol = isdnprot; icard.protocol = isdnprot;
@ -196,14 +134,6 @@ static int __devinit avma1cs_config(struct pcmcia_device *link)
return 0; return 0;
} /* avma1cs_config */ } /* avma1cs_config */
/*======================================================================
After a card is removed, avma1cs_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void avma1cs_release(struct pcmcia_device *link) static void avma1cs_release(struct pcmcia_device *link)
{ {
unsigned long minor = (unsigned long) link->priv; unsigned long minor = (unsigned long) link->priv;
@ -216,7 +146,6 @@ static void avma1cs_release(struct pcmcia_device *link)
pcmcia_disable_device(link); pcmcia_disable_device(link);
} /* avma1cs_release */ } /* avma1cs_release */
static struct pcmcia_device_id avma1cs_ids[] = { static struct pcmcia_device_id avma1cs_ids[] = {
PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb), PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb),
PCMCIA_DEVICE_PROD_ID12("ISDN", "CARD", 0x8d9761c8, 0x01c5aa7b), PCMCIA_DEVICE_PROD_ID12("ISDN", "CARD", 0x8d9761c8, 0x01c5aa7b),
@ -226,19 +155,15 @@ MODULE_DEVICE_TABLE(pcmcia, avma1cs_ids);
static struct pcmcia_driver avma1cs_driver = { static struct pcmcia_driver avma1cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "avma1_cs",
.name = "avma1_cs",
},
.probe = avma1cs_probe, .probe = avma1cs_probe,
.remove = __devexit_p(avma1cs_detach), .remove = __devexit_p(avma1cs_detach),
.id_table = avma1cs_ids, .id_table = avma1cs_ids,
}; };
/*====================================================================*/
static int __init init_avma1_cs(void) static int __init init_avma1_cs(void)
{ {
return(pcmcia_register_driver(&avma1cs_driver)); return pcmcia_register_driver(&avma1cs_driver);
} }
static void __exit exit_avma1_cs(void) static void __exit exit_avma1_cs(void)

View file

@ -46,7 +46,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -64,26 +63,8 @@ MODULE_LICENSE("Dual MPL/GPL");
static int protocol = 2; /* EURO-ISDN Default */ static int protocol = 2; /* EURO-ISDN Default */
module_param(protocol, int, 0); module_param(protocol, int, 0);
/*====================================================================*/
/*
The event() function is this driver's Card Services event handler.
It will be called by Card Services when an appropriate card status
event is received. The config() and release() entry points are
used to configure or release a socket, in response to card insertion
and ejection events. They are invoked from the elsa_cs event
handler.
*/
static int elsa_cs_config(struct pcmcia_device *link) __devinit ; static int elsa_cs_config(struct pcmcia_device *link) __devinit ;
static void elsa_cs_release(struct pcmcia_device *link); static void elsa_cs_release(struct pcmcia_device *link);
/*
The attach() and detach() entry points are used to create and destroy
"instances" of the driver, where each instance represents everything
needed to manage one actual PCMCIA card.
*/
static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit; static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit;
typedef struct local_info_t { typedef struct local_info_t {
@ -92,18 +73,6 @@ typedef struct local_info_t {
int cardnr; int cardnr;
} local_info_t; } local_info_t;
/*======================================================================
elsa_cs_attach() creates an "instance" of the driver, allocatingx
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
static int __devinit elsa_cs_probe(struct pcmcia_device *link) static int __devinit elsa_cs_probe(struct pcmcia_device *link)
{ {
local_info_t *local; local_info_t *local;
@ -119,31 +88,9 @@ static int __devinit elsa_cs_probe(struct pcmcia_device *link)
local->cardnr = -1; local->cardnr = -1;
/*
General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost
everything. In most clients, many details (i.e., number, sizes,
and attributes of IO windows) are fixed by the nature of the
device, and can be hard-wired here.
*/
link->resource[0]->end = 8;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
return elsa_cs_config(link); return elsa_cs_config(link);
} /* elsa_cs_attach */ } /* elsa_cs_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void __devexit elsa_cs_detach(struct pcmcia_device *link) static void __devexit elsa_cs_detach(struct pcmcia_device *link)
{ {
local_info_t *info = link->priv; local_info_t *info = link->priv;
@ -156,27 +103,17 @@ static void __devexit elsa_cs_detach(struct pcmcia_device *link)
kfree(info); kfree(info);
} /* elsa_cs_detach */ } /* elsa_cs_detach */
/*====================================================================== static int elsa_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
elsa_cs_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
======================================================================*/
static int elsa_cs_configcheck(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
int j; int j;
p_dev->io_lines = 3; p_dev->io_lines = 3;
p_dev->resource[0]->end = 8;
p_dev->resource[0]->flags &= IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
if ((cf->io.nwin > 0) && cf->io.win[0].base) { if ((p_dev->resource[0]->end) && p_dev->resource[0]->start) {
printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
p_dev->resource[0]->start = cf->io.win[0].base;
if (!pcmcia_request_io(p_dev)) if (!pcmcia_request_io(p_dev))
return 0; return 0;
} else { } else {
@ -199,6 +136,8 @@ static int __devinit elsa_cs_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "elsa_config(0x%p)\n", link); dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
dev = link->priv; dev = link->priv;
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL); i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
if (i != 0) if (i != 0)
goto failed; goto failed;
@ -206,21 +145,10 @@ static int __devinit elsa_cs_config(struct pcmcia_device *link)
if (!link->irq) if (!link->irq)
goto failed; goto failed;
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_enable_device(link);
if (i != 0) if (i != 0)
goto failed; goto failed;
/* Finally, report what we've done */
dev_info(&link->dev, "index 0x%02x: ",
link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq);
if (link->resource[0])
printk(" & %pR", link->resource[0]);
if (link->resource[1])
printk(" & %pR", link->resource[1]);
printk("\n");
icard.para[0] = link->irq; icard.para[0] = link->irq;
icard.para[1] = link->resource[0]->start; icard.para[1] = link->resource[0]->start;
icard.protocol = protocol; icard.protocol = protocol;
@ -240,14 +168,6 @@ failed:
return -ENODEV; return -ENODEV;
} /* elsa_cs_config */ } /* elsa_cs_config */
/*======================================================================
After a card is removed, elsa_cs_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void elsa_cs_release(struct pcmcia_device *link) static void elsa_cs_release(struct pcmcia_device *link)
{ {
local_info_t *local = link->priv; local_info_t *local = link->priv;
@ -291,9 +211,7 @@ MODULE_DEVICE_TABLE(pcmcia, elsa_ids);
static struct pcmcia_driver elsa_cs_driver = { static struct pcmcia_driver elsa_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "elsa_cs",
.name = "elsa_cs",
},
.probe = elsa_cs_probe, .probe = elsa_cs_probe,
.remove = __devexit_p(elsa_cs_detach), .remove = __devexit_p(elsa_cs_detach),
.id_table = elsa_ids, .id_table = elsa_ids,

View file

@ -46,7 +46,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -64,26 +63,9 @@ MODULE_LICENSE("Dual MPL/GPL");
static int protocol = 2; /* EURO-ISDN Default */ static int protocol = 2; /* EURO-ISDN Default */
module_param(protocol, int, 0); module_param(protocol, int, 0);
/*====================================================================*/
/*
The event() function is this driver's Card Services event handler.
It will be called by Card Services when an appropriate card status
event is received. The config() and release() entry points are
used to configure or release a socket, in response to card
insertion and ejection events. They are invoked from the sedlbauer
event handler.
*/
static int sedlbauer_config(struct pcmcia_device *link) __devinit ; static int sedlbauer_config(struct pcmcia_device *link) __devinit ;
static void sedlbauer_release(struct pcmcia_device *link); static void sedlbauer_release(struct pcmcia_device *link);
/*
The attach() and detach() entry points are used to create and destroy
"instances" of the driver, where each instance represents everything
needed to manage one actual PCMCIA card.
*/
static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit; static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit;
typedef struct local_info_t { typedef struct local_info_t {
@ -92,18 +74,6 @@ typedef struct local_info_t {
int cardnr; int cardnr;
} local_info_t; } local_info_t;
/*======================================================================
sedlbauer_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
static int __devinit sedlbauer_probe(struct pcmcia_device *link) static int __devinit sedlbauer_probe(struct pcmcia_device *link)
{ {
local_info_t *local; local_info_t *local;
@ -118,35 +88,9 @@ static int __devinit sedlbauer_probe(struct pcmcia_device *link)
local->p_dev = link; local->p_dev = link;
link->priv = local; link->priv = local;
/*
General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost
everything. In most clients, many details (i.e., number, sizes,
and attributes of IO windows) are fixed by the nature of the
device, and can be hard-wired here.
*/
/* from old sedl_cs
*/
/* The io structure describes IO port mapping */
link->resource[0]->end = 8;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
return sedlbauer_config(link); return sedlbauer_config(link);
} /* sedlbauer_attach */ } /* sedlbauer_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void __devexit sedlbauer_detach(struct pcmcia_device *link) static void __devexit sedlbauer_detach(struct pcmcia_device *link)
{ {
dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link); dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link);
@ -158,70 +102,15 @@ static void __devexit sedlbauer_detach(struct pcmcia_device *link)
kfree(link->priv); kfree(link->priv);
} /* sedlbauer_detach */ } /* sedlbauer_detach */
/*====================================================================== static int sedlbauer_config_check(struct pcmcia_device *p_dev, void *priv_data)
sedlbauer_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
======================================================================*/
static int sedlbauer_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
if (cfg->index == 0) if (p_dev->config_index == 0)
return -ENODEV; return -EINVAL;
/* Does this card need audio output? */ p_dev->io_lines = 3;
if (cfg->flags & CISTPL_CFTABLE_AUDIO) { return pcmcia_request_io(p_dev);
p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
p_dev->conf.Status = CCSR_AUDIO_ENA;
}
/* Use power settings for Vcc and Vpp if present */
/* Note that the CIS values need to be rescaled */
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
return -ENODEV;
} else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) {
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM]/10000)
return -ENODEV;
}
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
if (io->nwin > 1) {
p_dev->resource[1]->flags = p_dev->resource[0]->flags;
p_dev->resource[1]->start = io->win[1].base;
p_dev->resource[1]->end = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
p_dev->io_lines = 3;
if (pcmcia_request_io(p_dev) != 0)
return -ENODEV;
}
return 0;
} }
static int __devinit sedlbauer_config(struct pcmcia_device *link) static int __devinit sedlbauer_config(struct pcmcia_device *link)
{ {
int ret; int ret;
@ -229,44 +118,17 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link); dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link);
/* link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
In this loop, we scan the CIS for configuration table entries, CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
each of which describes a valid card configuration, including
voltage, IO window, memory window, and interrupt settings.
We make no assumptions about the card to be configured: we use
just the information available in the CIS. In an ideal world,
this would work for any PCMCIA card, but it requires a complete
and accurate CIS. In practice, a driver usually "knows" most of
these things without consulting the CIS, and most client drivers
will only use the CIS to fill in implementation-defined details.
*/
ret = pcmcia_loop_config(link, sedlbauer_config_check, NULL); ret = pcmcia_loop_config(link, sedlbauer_config_check, NULL);
if (ret) if (ret)
goto failed; goto failed;
/* ret = pcmcia_enable_device(link);
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
/* Finally, report what we've done */
dev_info(&link->dev, "index 0x%02x:",
link->conf.ConfigIndex);
if (link->conf.Vpp)
printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq);
if (link->resource[0])
printk(" & %pR", link->resource[0]);
if (link->resource[1])
printk(" & %pR", link->resource[1]);
printk("\n");
icard.para[0] = link->irq; icard.para[0] = link->irq;
icard.para[1] = link->resource[0]->start; icard.para[1] = link->resource[0]->start;
icard.protocol = protocol; icard.protocol = protocol;
@ -290,14 +152,6 @@ failed:
} /* sedlbauer_config */ } /* sedlbauer_config */
/*======================================================================
After a card is removed, sedlbauer_release() will unregister the
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void sedlbauer_release(struct pcmcia_device *link) static void sedlbauer_release(struct pcmcia_device *link)
{ {
local_info_t *local = link->priv; local_info_t *local = link->priv;
@ -346,9 +200,7 @@ MODULE_DEVICE_TABLE(pcmcia, sedlbauer_ids);
static struct pcmcia_driver sedlbauer_driver = { static struct pcmcia_driver sedlbauer_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "sedlbauer_cs",
.name = "sedlbauer_cs",
},
.probe = sedlbauer_probe, .probe = sedlbauer_probe,
.remove = __devexit_p(sedlbauer_detach), .remove = __devexit_p(sedlbauer_detach),
.id_table = sedlbauer_ids, .id_table = sedlbauer_ids,

View file

@ -27,7 +27,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -45,26 +44,8 @@ MODULE_LICENSE("GPL");
static int protocol = 2; /* EURO-ISDN Default */ static int protocol = 2; /* EURO-ISDN Default */
module_param(protocol, int, 0); module_param(protocol, int, 0);
/*====================================================================*/
/*
The event() function is this driver's Card Services event handler.
It will be called by Card Services when an appropriate card status
event is received. The config() and release() entry points are
used to configure or release a socket, in response to card insertion
and ejection events. They are invoked from the teles_cs event
handler.
*/
static int teles_cs_config(struct pcmcia_device *link) __devinit ; static int teles_cs_config(struct pcmcia_device *link) __devinit ;
static void teles_cs_release(struct pcmcia_device *link); static void teles_cs_release(struct pcmcia_device *link);
/*
The attach() and detach() entry points are used to create and destroy
"instances" of the driver, where each instance represents everything
needed to manage one actual PCMCIA card.
*/
static void teles_detach(struct pcmcia_device *p_dev) __devexit ; static void teles_detach(struct pcmcia_device *p_dev) __devexit ;
typedef struct local_info_t { typedef struct local_info_t {
@ -73,18 +54,6 @@ typedef struct local_info_t {
int cardnr; int cardnr;
} local_info_t; } local_info_t;
/*======================================================================
teles_attach() creates an "instance" of the driver, allocatingx
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
static int __devinit teles_probe(struct pcmcia_device *link) static int __devinit teles_probe(struct pcmcia_device *link)
{ {
local_info_t *local; local_info_t *local;
@ -99,31 +68,11 @@ static int __devinit teles_probe(struct pcmcia_device *link)
local->p_dev = link; local->p_dev = link;
link->priv = local; link->priv = local;
/* link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost
everything. In most clients, many details (i.e., number, sizes,
and attributes of IO windows) are fixed by the nature of the
device, and can be hard-wired here.
*/
link->resource[0]->end = 96;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
return teles_cs_config(link); return teles_cs_config(link);
} /* teles_attach */ } /* teles_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void __devexit teles_detach(struct pcmcia_device *link) static void __devexit teles_detach(struct pcmcia_device *link)
{ {
local_info_t *info = link->priv; local_info_t *info = link->priv;
@ -136,27 +85,17 @@ static void __devexit teles_detach(struct pcmcia_device *link)
kfree(info); kfree(info);
} /* teles_detach */ } /* teles_detach */
/*====================================================================== static int teles_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
teles_cs_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
======================================================================*/
static int teles_cs_configcheck(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
int j; int j;
p_dev->io_lines = 5; p_dev->io_lines = 5;
p_dev->resource[0]->end = 96;
p_dev->resource[0]->flags &= IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
if ((cf->io.nwin > 0) && cf->io.win[0].base) { if ((p_dev->resource[0]->end) && p_dev->resource[0]->start) {
printk(KERN_INFO "(teles_cs: looks like the 96 model)\n"); printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
p_dev->resource[0]->start = cf->io.win[0].base;
if (!pcmcia_request_io(p_dev)) if (!pcmcia_request_io(p_dev))
return 0; return 0;
} else { } else {
@ -186,21 +125,10 @@ static int __devinit teles_cs_config(struct pcmcia_device *link)
if (!link->irq) if (!link->irq)
goto cs_failed; goto cs_failed;
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_enable_device(link);
if (i != 0) if (i != 0)
goto cs_failed; goto cs_failed;
/* Finally, report what we've done */
dev_info(&link->dev, "index 0x%02x:",
link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq);
if (link->resource[0])
printk(" & %pR", link->resource[0]);
if (link->resource[1])
printk(" & %pR", link->resource[1]);
printk("\n");
icard.para[0] = link->irq; icard.para[0] = link->irq;
icard.para[1] = link->resource[0]->start; icard.para[1] = link->resource[0]->start;
icard.protocol = protocol; icard.protocol = protocol;
@ -222,14 +150,6 @@ cs_failed:
return -ENODEV; return -ENODEV;
} /* teles_cs_config */ } /* teles_cs_config */
/*======================================================================
After a card is removed, teles_cs_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void teles_cs_release(struct pcmcia_device *link) static void teles_cs_release(struct pcmcia_device *link)
{ {
local_info_t *local = link->priv; local_info_t *local = link->priv;
@ -273,9 +193,7 @@ MODULE_DEVICE_TABLE(pcmcia, teles_ids);
static struct pcmcia_driver teles_cs_driver = { static struct pcmcia_driver teles_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "teles_cs",
.name = "teles_cs",
},
.probe = teles_probe, .probe = teles_probe,
.remove = __devexit_p(teles_detach), .remove = __devexit_p(teles_detach),
.id_table = teles_ids, .id_table = teles_ids,

View file

@ -30,7 +30,6 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <linux/io.h> #include <linux/io.h>
@ -536,9 +535,7 @@ static int sdricoh_pcmcia_resume(struct pcmcia_device *link)
#endif #endif
static struct pcmcia_driver sdricoh_driver = { static struct pcmcia_driver sdricoh_driver = {
.drv = { .name = DRIVER_NAME,
.name = DRIVER_NAME,
},
.probe = sdricoh_pcmcia_probe, .probe = sdricoh_pcmcia_probe,
.remove = sdricoh_pcmcia_detach, .remove = sdricoh_pcmcia_detach,
.id_table = pcmcia_ids, .id_table = pcmcia_ids,

View file

@ -16,7 +16,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -101,7 +100,7 @@ MODULE_PARM_DESC(mem_type, "Set Memory type (0=Flash, 1=RAM, 2=ROM, default=0)")
static caddr_t remap_window(struct map_info *map, unsigned long to) static caddr_t remap_window(struct map_info *map, unsigned long to)
{ {
struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1; struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
window_handle_t win = (window_handle_t)map->map_priv_2; struct resource *win = (struct resource *) map->map_priv_2;
unsigned int offset; unsigned int offset;
int ret; int ret;
@ -316,30 +315,19 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
{ {
struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1; struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
struct pcmcia_device *link = dev->p_dev; struct pcmcia_device *link = dev->p_dev;
modconf_t mod;
int ret;
mod.Attributes = CONF_VPP1_CHANGE_VALID | CONF_VPP2_CHANGE_VALID;
mod.Vcc = 0;
mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0;
DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp); DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
ret = pcmcia_modify_configuration(link, &mod); pcmcia_fixup_vpp(link, on ? dev->vpp : 0);
} }
/* After a card is removed, pcmciamtd_release() will unregister the
* device, and release the PCMCIA configuration. If the device is
* still open, this will be postponed until it is closed.
*/
static void pcmciamtd_release(struct pcmcia_device *link) static void pcmciamtd_release(struct pcmcia_device *link)
{ {
struct pcmciamtd_dev *dev = link->priv; struct pcmciamtd_dev *dev = link->priv;
DEBUG(3, "link = 0x%p", link); DEBUG(3, "link = 0x%p", link);
if (link->win) { if (link->resource[2]->end) {
if(dev->win_base) { if(dev->win_base) {
iounmap(dev->win_base); iounmap(dev->win_base);
dev->win_base = NULL; dev->win_base = NULL;
@ -482,18 +470,12 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *p_dev
} }
/* pcmciamtd_config() is scheduled to run after a CARD_INSERTION event
* is received, to configure the PCMCIA socket, and to make the
* MTD device available to the system.
*/
static int pcmciamtd_config(struct pcmcia_device *link) static int pcmciamtd_config(struct pcmcia_device *link)
{ {
struct pcmciamtd_dev *dev = link->priv; struct pcmciamtd_dev *dev = link->priv;
struct mtd_info *mtd = NULL; struct mtd_info *mtd = NULL;
win_req_t req;
int ret; int ret;
int i; int i, j = 0;
static char *probes[] = { "jedec_probe", "cfi_probe" }; static char *probes[] = { "jedec_probe", "cfi_probe" };
int new_name = 0; int new_name = 0;
@ -520,28 +502,34 @@ static int pcmciamtd_config(struct pcmcia_device *link)
* smaller windows until we succeed * smaller windows until we succeed
*/ */
req.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE; link->resource[2]->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE;
req.Attributes |= (dev->pcmcia_map.bankwidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16; link->resource[2]->flags |= (dev->pcmcia_map.bankwidth == 1) ?
req.Base = 0; WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16;
req.AccessSpeed = mem_speed; link->resource[2]->start = 0;
link->win = (window_handle_t)link; link->resource[2]->end = (force_size) ? force_size << 20 :
req.Size = (force_size) ? force_size << 20 : MAX_PCMCIA_ADDR; MAX_PCMCIA_ADDR;
dev->win_size = 0; dev->win_size = 0;
do { do {
int ret; int ret;
DEBUG(2, "requesting window with size = %dKiB memspeed = %d", DEBUG(2, "requesting window with size = %luKiB memspeed = %d",
req.Size >> 10, req.AccessSpeed); (unsigned long) resource_size(link->resource[2]) >> 10,
ret = pcmcia_request_window(link, &req, &link->win); mem_speed);
ret = pcmcia_request_window(link, link->resource[2], mem_speed);
DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size); DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
if(ret) { if(ret) {
req.Size >>= 1; j++;
link->resource[2]->start = 0;
link->resource[2]->end = (force_size) ?
force_size << 20 : MAX_PCMCIA_ADDR;
link->resource[2]->end >>= j;
} else { } else {
DEBUG(2, "Got window of size %dKiB", req.Size >> 10); DEBUG(2, "Got window of size %luKiB", (unsigned long)
dev->win_size = req.Size; resource_size(link->resource[2]) >> 10);
dev->win_size = resource_size(link->resource[2]);
break; break;
} }
} while(req.Size >= 0x1000); } while (link->resource[2]->end >= 0x1000);
DEBUG(2, "dev->win_size = %d", dev->win_size); DEBUG(2, "dev->win_size = %d", dev->win_size);
@ -553,33 +541,31 @@ static int pcmciamtd_config(struct pcmcia_device *link)
DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
/* Get write protect status */ /* Get write protect status */
DEBUG(2, "window handle = 0x%8.8lx", (unsigned long)link->win); dev->win_base = ioremap(link->resource[2]->start,
dev->win_base = ioremap(req.Base, req.Size); resource_size(link->resource[2]));
if(!dev->win_base) { if(!dev->win_base) {
dev_err(&dev->p_dev->dev, "ioremap(%lu, %u) failed\n", dev_err(&dev->p_dev->dev, "ioremap(%pR) failed\n",
req.Base, req.Size); link->resource[2]);
pcmciamtd_release(link); pcmciamtd_release(link);
return -ENODEV; return -ENODEV;
} }
DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x", DEBUG(1, "mapped window dev = %p @ %pR, base = %p",
dev, req.Base, dev->win_base, req.Size); dev, link->resource[2], dev->win_base);
dev->offset = 0; dev->offset = 0;
dev->pcmcia_map.map_priv_1 = (unsigned long)dev; dev->pcmcia_map.map_priv_1 = (unsigned long)dev;
dev->pcmcia_map.map_priv_2 = (unsigned long)link->win; dev->pcmcia_map.map_priv_2 = (unsigned long)link->resource[2];
dev->vpp = (vpp) ? vpp : link->socket->socket.Vpp; dev->vpp = (vpp) ? vpp : link->socket->socket.Vpp;
link->conf.Attributes = 0;
if(setvpp == 2) { if(setvpp == 2) {
link->conf.Vpp = dev->vpp; link->vpp = dev->vpp;
} else { } else {
link->conf.Vpp = 0; link->vpp = 0;
} }
link->conf.IntType = INT_MEMORY; link->config_index = 0;
link->conf.ConfigIndex = 0;
DEBUG(2, "Setting Configuration"); DEBUG(2, "Setting Configuration");
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret != 0) { if (ret != 0) {
if (dev->win_base) { if (dev->win_base) {
iounmap(dev->win_base); iounmap(dev->win_base);
@ -680,12 +666,6 @@ static int pcmciamtd_resume(struct pcmcia_device *dev)
} }
/* This deletes a driver "instance". The device is de-registered
* with Card Services. If it has been released, all local data
* structures are freed. Otherwise, the structures will be freed
* when the device is released.
*/
static void pcmciamtd_detach(struct pcmcia_device *link) static void pcmciamtd_detach(struct pcmcia_device *link)
{ {
struct pcmciamtd_dev *dev = link->priv; struct pcmciamtd_dev *dev = link->priv;
@ -703,11 +683,6 @@ static void pcmciamtd_detach(struct pcmcia_device *link)
} }
/* pcmciamtd_attach() creates an "instance" of the driver, allocating
* local data structures for one device. The device is registered
* with Card Services.
*/
static int pcmciamtd_probe(struct pcmcia_device *link) static int pcmciamtd_probe(struct pcmcia_device *link)
{ {
struct pcmciamtd_dev *dev; struct pcmciamtd_dev *dev;
@ -720,9 +695,6 @@ static int pcmciamtd_probe(struct pcmcia_device *link)
dev->p_dev = link; dev->p_dev = link;
link->priv = dev; link->priv = dev;
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY;
return pcmciamtd_config(link); return pcmciamtd_config(link);
} }
@ -757,9 +729,7 @@ static struct pcmcia_device_id pcmciamtd_ids[] = {
MODULE_DEVICE_TABLE(pcmcia, pcmciamtd_ids); MODULE_DEVICE_TABLE(pcmcia, pcmciamtd_ids);
static struct pcmcia_driver pcmciamtd_driver = { static struct pcmcia_driver pcmciamtd_driver = {
.drv = { .name = "pcmciamtd",
.name = "pcmciamtd"
},
.probe = pcmciamtd_probe, .probe = pcmciamtd_probe,
.remove = pcmciamtd_detach, .remove = pcmciamtd_detach,
.owner = THIS_MODULE, .owner = THIS_MODULE,
@ -771,8 +741,6 @@ static struct pcmcia_driver pcmciamtd_driver = {
static int __init init_pcmciamtd(void) static int __init init_pcmciamtd(void)
{ {
info(DRIVER_DESC);
if(bankwidth && bankwidth != 1 && bankwidth != 2) { if(bankwidth && bankwidth != 1 && bankwidth != 2) {
info("bad bankwidth (%d), using default", bankwidth); info("bad bankwidth (%d), using default", bankwidth);
bankwidth = 2; bankwidth = 2;

View file

@ -87,7 +87,6 @@ earlier 3Com products.
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/mii.h> #include <linux/mii.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
@ -280,25 +279,15 @@ static int tc574_probe(struct pcmcia_device *link)
spin_lock_init(&lp->window_lock); spin_lock_init(&lp->window_lock);
link->resource[0]->end = 32; link->resource[0]->end = 32;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16; link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
link->conf.Attributes = CONF_ENABLE_IRQ; link->config_flags |= CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->config_index = 1;
link->conf.ConfigIndex = 1;
dev->netdev_ops = &el3_netdev_ops; dev->netdev_ops = &el3_netdev_ops;
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
return tc574_config(link); return tc574_config(link);
} /* tc574_attach */ }
/*
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
*/
static void tc574_detach(struct pcmcia_device *link) static void tc574_detach(struct pcmcia_device *link)
{ {
@ -313,12 +302,6 @@ static void tc574_detach(struct pcmcia_device *link)
free_netdev(dev); free_netdev(dev);
} /* tc574_detach */ } /* tc574_detach */
/*
tc574_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
ethernet device available to the system.
*/
static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
static int tc574_config(struct pcmcia_device *link) static int tc574_config(struct pcmcia_device *link)
@ -352,7 +335,7 @@ static int tc574_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
@ -465,12 +448,6 @@ failed:
} /* tc574_config */ } /* tc574_config */
/*
After a card is removed, tc574_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
*/
static void tc574_release(struct pcmcia_device *link) static void tc574_release(struct pcmcia_device *link)
{ {
pcmcia_disable_device(link); pcmcia_disable_device(link);
@ -1198,9 +1175,7 @@ MODULE_DEVICE_TABLE(pcmcia, tc574_ids);
static struct pcmcia_driver tc574_driver = { static struct pcmcia_driver tc574_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "3c574_cs",
.name = "3c574_cs",
},
.probe = tc574_probe, .probe = tc574_probe,
.remove = tc574_detach, .remove = tc574_detach,
.id_table = tc574_ids, .id_table = tc574_ids,

View file

@ -41,7 +41,6 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
@ -176,14 +175,6 @@ static const struct ethtool_ops netdev_ethtool_ops;
static void tc589_detach(struct pcmcia_device *p_dev); static void tc589_detach(struct pcmcia_device *p_dev);
/*======================================================================
tc589_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
======================================================================*/
static const struct net_device_ops el3_netdev_ops = { static const struct net_device_ops el3_netdev_ops = {
.ndo_open = el3_open, .ndo_open = el3_open,
.ndo_stop = el3_close, .ndo_stop = el3_close,
@ -216,9 +207,8 @@ static int tc589_probe(struct pcmcia_device *link)
link->resource[0]->end = 16; link->resource[0]->end = 16;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16; link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
link->conf.Attributes = CONF_ENABLE_IRQ; link->config_flags |= CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->config_index = 1;
link->conf.ConfigIndex = 1;
dev->netdev_ops = &el3_netdev_ops; dev->netdev_ops = &el3_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
@ -226,16 +216,7 @@ static int tc589_probe(struct pcmcia_device *link)
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
return tc589_config(link); return tc589_config(link);
} /* tc589_attach */ }
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void tc589_detach(struct pcmcia_device *link) static void tc589_detach(struct pcmcia_device *link)
{ {
@ -250,14 +231,6 @@ static void tc589_detach(struct pcmcia_device *link)
free_netdev(dev); free_netdev(dev);
} /* tc589_detach */ } /* tc589_detach */
/*======================================================================
tc589_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
ethernet device available to the system.
======================================================================*/
static int tc589_config(struct pcmcia_device *link) static int tc589_config(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
@ -294,7 +267,7 @@ static int tc589_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
@ -352,14 +325,6 @@ failed:
return -ENODEV; return -ENODEV;
} /* tc589_config */ } /* tc589_config */
/*======================================================================
After a card is removed, tc589_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void tc589_release(struct pcmcia_device *link) static void tc589_release(struct pcmcia_device *link)
{ {
pcmcia_disable_device(link); pcmcia_disable_device(link);
@ -955,9 +920,7 @@ MODULE_DEVICE_TABLE(pcmcia, tc589_ids);
static struct pcmcia_driver tc589_driver = { static struct pcmcia_driver tc589_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "3c589_cs",
.name = "3c589_cs",
},
.probe = tc589_probe, .probe = tc589_probe,
.remove = tc589_detach, .remove = tc589_detach,
.id_table = tc589_ids, .id_table = tc589_ids,

View file

@ -39,7 +39,6 @@
#include <linux/mii.h> #include <linux/mii.h>
#include "../8390.h" #include "../8390.h"
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -140,14 +139,6 @@ static const struct net_device_ops axnet_netdev_ops = {
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
}; };
/*======================================================================
axnet_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
======================================================================*/
static int axnet_probe(struct pcmcia_device *link) static int axnet_probe(struct pcmcia_device *link)
{ {
axnet_dev_t *info; axnet_dev_t *info;
@ -166,8 +157,7 @@ static int axnet_probe(struct pcmcia_device *link)
info = PRIV(dev); info = PRIV(dev);
info->p_dev = link; info->p_dev = link;
link->priv = dev; link->priv = dev;
link->conf.Attributes = CONF_ENABLE_IRQ; link->config_flags |= CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
dev->netdev_ops = &axnet_netdev_ops; dev->netdev_ops = &axnet_netdev_ops;
@ -177,15 +167,6 @@ static int axnet_probe(struct pcmcia_device *link)
return axnet_config(link); return axnet_config(link);
} /* axnet_attach */ } /* axnet_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void axnet_detach(struct pcmcia_device *link) static void axnet_detach(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
@ -231,7 +212,7 @@ static int get_prom(struct pcmcia_device *link)
}; };
/* Not much of a test, but the alternatives are messy */ /* Not much of a test, but the alternatives are messy */
if (link->conf.ConfigBase != 0x03c0) if (link->config_base != 0x03c0)
return 0; return 0;
axnet_reset_8390(dev); axnet_reset_8390(dev);
@ -248,14 +229,6 @@ static int get_prom(struct pcmcia_device *link)
return 1; return 1;
} /* get_prom */ } /* get_prom */
/*======================================================================
axnet_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
ethernet device available to the system.
======================================================================*/
static int try_io_port(struct pcmcia_device *link) static int try_io_port(struct pcmcia_device *link)
{ {
int j, ret; int j, ret;
@ -286,35 +259,16 @@ static int try_io_port(struct pcmcia_device *link)
} }
} }
static int axnet_configcheck(struct pcmcia_device *p_dev, static int axnet_configcheck(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
int i; if (p_dev->config_index == 0)
cistpl_io_t *io = &cfg->io; return -EINVAL;
if (cfg->index == 0 || cfg->io.nwin == 0) p_dev->config_index = 0x05;
if (p_dev->resource[0]->end + p_dev->resource[1]->end < 32)
return -ENODEV; return -ENODEV;
p_dev->conf.ConfigIndex = 0x05; return try_io_port(p_dev);
/* For multifunction cards, by convention, we configure the
network function with window 0, and serial with window 1 */
if (io->nwin > 1) {
i = (io->win[1].len > io->win[0].len);
p_dev->resource[1]->start = io->win[1-i].base;
p_dev->resource[1]->end = io->win[1-i].len;
} else {
i = p_dev->resource[1]->end = 0;
}
p_dev->resource[0]->start = io->win[i].base;
p_dev->resource[0]->end = io->win[i].len;
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32)
return try_io_port(p_dev);
return -ENODEV;
} }
static int axnet_config(struct pcmcia_device *link) static int axnet_config(struct pcmcia_device *link)
@ -326,20 +280,19 @@ static int axnet_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "axnet_config(0x%p)\n", link); dev_dbg(&link->dev, "axnet_config(0x%p)\n", link);
/* don't trust the CIS on this; Linksys got it wrong */ /* don't trust the CIS on this; Linksys got it wrong */
link->conf.Present = 0x63; link->config_regs = 0x63;
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
ret = pcmcia_loop_config(link, axnet_configcheck, NULL); ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
if (ret != 0) if (ret != 0)
goto failed; goto failed;
if (!link->irq) if (!link->irq)
goto failed; goto failed;
if (resource_size(link->resource[1]) == 8)
link->config_flags |= CONF_ENABLE_SPKR;
if (resource_size(link->resource[1]) == 8) { ret = pcmcia_enable_device(link);
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
}
ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
@ -414,14 +367,6 @@ failed:
return -ENODEV; return -ENODEV;
} /* axnet_config */ } /* axnet_config */
/*======================================================================
After a card is removed, axnet_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void axnet_release(struct pcmcia_device *link) static void axnet_release(struct pcmcia_device *link)
{ {
pcmcia_disable_device(link); pcmcia_disable_device(link);
@ -783,9 +728,7 @@ MODULE_DEVICE_TABLE(pcmcia, axnet_ids);
static struct pcmcia_driver axnet_cs_driver = { static struct pcmcia_driver axnet_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "axnet_cs",
.name = "axnet_cs",
},
.probe = axnet_probe, .probe = axnet_probe,
.remove = axnet_detach, .remove = axnet_detach,
.id_table = axnet_ids, .id_table = axnet_ids,

View file

@ -43,7 +43,6 @@
#include <linux/arcdevice.h> #include <linux/arcdevice.h>
#include <linux/com20020.h> #include <linux/com20020.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -123,14 +122,6 @@ typedef struct com20020_dev_t {
struct net_device *dev; struct net_device *dev;
} com20020_dev_t; } com20020_dev_t;
/*======================================================================
com20020_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
======================================================================*/
static int com20020_probe(struct pcmcia_device *p_dev) static int com20020_probe(struct pcmcia_device *p_dev)
{ {
com20020_dev_t *info; com20020_dev_t *info;
@ -160,8 +151,7 @@ static int com20020_probe(struct pcmcia_device *p_dev)
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->resource[0]->end = 16; p_dev->resource[0]->end = 16;
p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->config_flags |= CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
info->dev = dev; info->dev = dev;
p_dev->priv = info; p_dev->priv = info;
@ -174,15 +164,6 @@ fail_alloc_info:
return -ENOMEM; return -ENOMEM;
} /* com20020_attach */ } /* com20020_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void com20020_detach(struct pcmcia_device *link) static void com20020_detach(struct pcmcia_device *link)
{ {
struct com20020_dev_t *info = link->priv; struct com20020_dev_t *info = link->priv;
@ -221,14 +202,6 @@ static void com20020_detach(struct pcmcia_device *link)
} /* com20020_detach */ } /* com20020_detach */
/*======================================================================
com20020_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
======================================================================*/
static int com20020_config(struct pcmcia_device *link) static int com20020_config(struct pcmcia_device *link)
{ {
struct arcnet_local *lp; struct arcnet_local *lp;
@ -282,7 +255,7 @@ static int com20020_config(struct pcmcia_device *link)
dev->irq = link->irq; dev->irq = link->irq;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
@ -316,14 +289,6 @@ failed:
return -ENODEV; return -ENODEV;
} /* com20020_config */ } /* com20020_config */
/*======================================================================
After a card is removed, com20020_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void com20020_release(struct pcmcia_device *link) static void com20020_release(struct pcmcia_device *link)
{ {
dev_dbg(&link->dev, "com20020_release\n"); dev_dbg(&link->dev, "com20020_release\n");
@ -366,9 +331,7 @@ MODULE_DEVICE_TABLE(pcmcia, com20020_ids);
static struct pcmcia_driver com20020_cs_driver = { static struct pcmcia_driver com20020_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "com20020_cs",
.name = "com20020_cs",
},
.probe = com20020_probe, .probe = com20020_probe,
.remove = com20020_detach, .remove = com20020_detach,
.id_table = com20020_ids, .id_table = com20020_ids,

View file

@ -49,7 +49,6 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -252,8 +251,7 @@ static int fmvj18x_probe(struct pcmcia_device *link)
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
/* General socket configuration */ /* General socket configuration */
link->conf.Attributes = CONF_ENABLE_IRQ; link->config_flags |= CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
dev->netdev_ops = &fjn_netdev_ops; dev->netdev_ops = &fjn_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
@ -313,7 +311,7 @@ static int ungermann_try_io_port(struct pcmcia_device *link)
ret = pcmcia_request_io(link); ret = pcmcia_request_io(link);
if (ret == 0) { if (ret == 0) {
/* calculate ConfigIndex value */ /* calculate ConfigIndex value */
link->conf.ConfigIndex = link->config_index =
((link->resource[0]->start & 0x0f0) >> 3) | 0x22; ((link->resource[0]->start & 0x0f0) >> 3) | 0x22;
return ret; return ret;
} }
@ -321,11 +319,7 @@ static int ungermann_try_io_port(struct pcmcia_device *link)
return ret; /* RequestIO failed */ return ret; /* RequestIO failed */
} }
static int fmvj18x_ioprobe(struct pcmcia_device *p_dev, static int fmvj18x_ioprobe(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
return 0; /* strange, but that's what the code did already before... */ return 0; /* strange, but that's what the code did already before... */
} }
@ -362,28 +356,28 @@ static int fmvj18x_config(struct pcmcia_device *link)
link->card_id == PRODID_TDK_NP9610 || link->card_id == PRODID_TDK_NP9610 ||
link->card_id == PRODID_TDK_MN3200) { link->card_id == PRODID_TDK_MN3200) {
/* MultiFunction Card */ /* MultiFunction Card */
link->conf.ConfigBase = 0x800; link->config_base = 0x800;
link->conf.ConfigIndex = 0x47; link->config_index = 0x47;
link->resource[1]->end = 8; link->resource[1]->end = 8;
} }
break; break;
case MANFID_NEC: case MANFID_NEC:
cardtype = NEC; /* MultiFunction Card */ cardtype = NEC; /* MultiFunction Card */
link->conf.ConfigBase = 0x800; link->config_base = 0x800;
link->conf.ConfigIndex = 0x47; link->config_index = 0x47;
link->resource[1]->end = 8; link->resource[1]->end = 8;
break; break;
case MANFID_KME: case MANFID_KME:
cardtype = KME; /* MultiFunction Card */ cardtype = KME; /* MultiFunction Card */
link->conf.ConfigBase = 0x800; link->config_base = 0x800;
link->conf.ConfigIndex = 0x47; link->config_index = 0x47;
link->resource[1]->end = 8; link->resource[1]->end = 8;
break; break;
case MANFID_CONTEC: case MANFID_CONTEC:
cardtype = CONTEC; cardtype = CONTEC;
break; break;
case MANFID_FUJITSU: case MANFID_FUJITSU:
if (link->conf.ConfigBase == 0x0fe0) if (link->config_base == 0x0fe0)
cardtype = MBH10302; cardtype = MBH10302;
else if (link->card_id == PRODID_FUJITSU_MBH10302) else if (link->card_id == PRODID_FUJITSU_MBH10302)
/* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302), /* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302),
@ -403,10 +397,10 @@ static int fmvj18x_config(struct pcmcia_device *link)
case MANFID_FUJITSU: case MANFID_FUJITSU:
if (link->card_id == PRODID_FUJITSU_MBH10304) { if (link->card_id == PRODID_FUJITSU_MBH10304) {
cardtype = XXX10304; /* MBH10304 with buggy CIS */ cardtype = XXX10304; /* MBH10304 with buggy CIS */
link->conf.ConfigIndex = 0x20; link->config_index = 0x20;
} else { } else {
cardtype = MBH10302; /* NextCom NC5310, etc. */ cardtype = MBH10302; /* NextCom NC5310, etc. */
link->conf.ConfigIndex = 1; link->config_index = 1;
} }
break; break;
case MANFID_UNGERMANN: case MANFID_UNGERMANN:
@ -414,7 +408,7 @@ static int fmvj18x_config(struct pcmcia_device *link)
break; break;
default: default:
cardtype = MBH10302; cardtype = MBH10302;
link->conf.ConfigIndex = 1; link->config_index = 1;
} }
} }
@ -432,7 +426,7 @@ static int fmvj18x_config(struct pcmcia_device *link)
ret = pcmcia_request_irq(link, fjn_interrupt); ret = pcmcia_request_irq(link, fjn_interrupt);
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
@ -544,20 +538,18 @@ failed:
static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id) static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
{ {
win_req_t req;
u_char __iomem *base; u_char __iomem *base;
int i, j; int i, j;
/* Allocate a small memory window */ /* Allocate a small memory window */
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; link->resource[2]->flags |= WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
req.Base = 0; req.Size = 0; link->resource[2]->start = 0; link->resource[2]->end = 0;
req.AccessSpeed = 0; i = pcmcia_request_window(link, link->resource[2], 0);
i = pcmcia_request_window(link, &req, &link->win);
if (i != 0) if (i != 0)
return -1; return -1;
base = ioremap(req.Base, req.Size); base = ioremap(link->resource[2]->start, resource_size(link->resource[2]));
pcmcia_map_mem_page(link, link->win, 0); pcmcia_map_mem_page(link, link->resource[2], 0);
/* /*
* MBH10304 CISTPL_FUNCE_LAN_NODE_ID format * MBH10304 CISTPL_FUNCE_LAN_NODE_ID format
@ -582,7 +574,7 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
} }
iounmap(base); iounmap(base);
j = pcmcia_release_window(link, link->win); j = pcmcia_release_window(link, link->resource[2]);
return (i != 0x200) ? 0 : -1; return (i != 0x200) ? 0 : -1;
} /* fmvj18x_get_hwinfo */ } /* fmvj18x_get_hwinfo */
@ -590,27 +582,26 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
static int fmvj18x_setup_mfc(struct pcmcia_device *link) static int fmvj18x_setup_mfc(struct pcmcia_device *link)
{ {
win_req_t req;
int i; int i;
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
unsigned int ioaddr; unsigned int ioaddr;
local_info_t *lp = netdev_priv(dev); local_info_t *lp = netdev_priv(dev);
/* Allocate a small memory window */ /* Allocate a small memory window */
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; link->resource[3]->flags = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
req.Base = 0; req.Size = 0; link->resource[3]->start = link->resource[3]->end = 0;
req.AccessSpeed = 0; i = pcmcia_request_window(link, link->resource[3], 0);
i = pcmcia_request_window(link, &req, &link->win);
if (i != 0) if (i != 0)
return -1; return -1;
lp->base = ioremap(req.Base, req.Size); lp->base = ioremap(link->resource[3]->start,
resource_size(link->resource[3]));
if (lp->base == NULL) { if (lp->base == NULL) {
printk(KERN_NOTICE "fmvj18x_cs: ioremap failed\n"); printk(KERN_NOTICE "fmvj18x_cs: ioremap failed\n");
return -1; return -1;
} }
i = pcmcia_map_mem_page(link, link->win, 0); i = pcmcia_map_mem_page(link, link->resource[3], 0);
if (i != 0) { if (i != 0) {
iounmap(lp->base); iounmap(lp->base);
lp->base = NULL; lp->base = NULL;
@ -638,7 +629,6 @@ static void fmvj18x_release(struct pcmcia_device *link)
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
local_info_t *lp = netdev_priv(dev); local_info_t *lp = netdev_priv(dev);
u_char __iomem *tmp; u_char __iomem *tmp;
int j;
dev_dbg(&link->dev, "fmvj18x_release\n"); dev_dbg(&link->dev, "fmvj18x_release\n");
@ -646,7 +636,6 @@ static void fmvj18x_release(struct pcmcia_device *link)
tmp = lp->base; tmp = lp->base;
lp->base = NULL; /* set NULL before iounmap */ lp->base = NULL; /* set NULL before iounmap */
iounmap(tmp); iounmap(tmp);
j = pcmcia_release_window(link, link->win);
} }
pcmcia_disable_device(link); pcmcia_disable_device(link);
@ -708,9 +697,7 @@ MODULE_DEVICE_TABLE(pcmcia, fmvj18x_ids);
static struct pcmcia_driver fmvj18x_cs_driver = { static struct pcmcia_driver fmvj18x_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "fmvj18x_cs",
.name = "fmvj18x_cs",
},
.probe = fmvj18x_probe, .probe = fmvj18x_probe,
.remove = fmvj18x_detach, .remove = fmvj18x_detach,
.id_table = fmvj18x_ids, .id_table = fmvj18x_ids,

View file

@ -57,7 +57,6 @@
#include <linux/trdevice.h> #include <linux/trdevice.h>
#include <linux/ibmtr.h> #include <linux/ibmtr.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -102,9 +101,8 @@ static void ibmtr_detach(struct pcmcia_device *p_dev);
typedef struct ibmtr_dev_t { typedef struct ibmtr_dev_t {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
struct net_device *dev; struct net_device *dev;
window_handle_t sram_win_handle; struct tok_info *ti;
struct tok_info *ti;
} ibmtr_dev_t; } ibmtr_dev_t;
static void netdev_get_drvinfo(struct net_device *dev, static void netdev_get_drvinfo(struct net_device *dev,
@ -123,14 +121,6 @@ static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) {
return tok_interrupt(irq, dev); return tok_interrupt(irq, dev);
}; };
/*======================================================================
ibmtr_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
======================================================================*/
static int __devinit ibmtr_attach(struct pcmcia_device *link) static int __devinit ibmtr_attach(struct pcmcia_device *link)
{ {
ibmtr_dev_t *info; ibmtr_dev_t *info;
@ -153,9 +143,8 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
link->resource[0]->end = 4; link->resource[0]->end = 4;
link->conf.Attributes = CONF_ENABLE_IRQ; link->config_flags |= CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->config_regs = PRESENT_OPTION;
link->conf.Present = PRESENT_OPTION;
info->dev = dev; info->dev = dev;
@ -164,15 +153,6 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
return ibmtr_config(link); return ibmtr_config(link);
} /* ibmtr_attach */ } /* ibmtr_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void ibmtr_detach(struct pcmcia_device *link) static void ibmtr_detach(struct pcmcia_device *link)
{ {
struct ibmtr_dev_t *info = link->priv; struct ibmtr_dev_t *info = link->priv;
@ -197,26 +177,17 @@ static void ibmtr_detach(struct pcmcia_device *link)
kfree(info); kfree(info);
} /* ibmtr_detach */ } /* ibmtr_detach */
/*======================================================================
ibmtr_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
token-ring device available to the system.
======================================================================*/
static int __devinit ibmtr_config(struct pcmcia_device *link) static int __devinit ibmtr_config(struct pcmcia_device *link)
{ {
ibmtr_dev_t *info = link->priv; ibmtr_dev_t *info = link->priv;
struct net_device *dev = info->dev; struct net_device *dev = info->dev;
struct tok_info *ti = netdev_priv(dev); struct tok_info *ti = netdev_priv(dev);
win_req_t req;
int i, ret; int i, ret;
dev_dbg(&link->dev, "ibmtr_config\n"); dev_dbg(&link->dev, "ibmtr_config\n");
link->conf.ConfigIndex = 0x61;
link->io_lines = 16; link->io_lines = 16;
link->config_index = 0x61;
/* Determine if this is PRIMARY or ALTERNATE. */ /* Determine if this is PRIMARY or ALTERNATE. */
@ -240,39 +211,39 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq); ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
/* Allocate the MMIO memory window */ /* Allocate the MMIO memory window */
req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE; link->resource[2]->flags |= WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
req.Attributes |= WIN_USE_WAIT; link->resource[2]->flags |= WIN_USE_WAIT;
req.Base = 0; link->resource[2]->start = 0;
req.Size = 0x2000; link->resource[2]->end = 0x2000;
req.AccessSpeed = 250; ret = pcmcia_request_window(link, link->resource[2], 250);
ret = pcmcia_request_window(link, &req, &link->win);
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_map_mem_page(link, link->win, mmiobase); ret = pcmcia_map_mem_page(link, link->resource[2], mmiobase);
if (ret) if (ret)
goto failed; goto failed;
ti->mmio = ioremap(req.Base, req.Size); ti->mmio = ioremap(link->resource[2]->start,
resource_size(link->resource[2]));
/* Allocate the SRAM memory window */ /* Allocate the SRAM memory window */
req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE; link->resource[3]->flags = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
req.Attributes |= WIN_USE_WAIT; link->resource[3]->flags |= WIN_USE_WAIT;
req.Base = 0; link->resource[3]->start = 0;
req.Size = sramsize * 1024; link->resource[3]->end = sramsize * 1024;
req.AccessSpeed = 250; ret = pcmcia_request_window(link, link->resource[3], 250);
ret = pcmcia_request_window(link, &req, &info->sram_win_handle);
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_map_mem_page(link, info->sram_win_handle, srambase); ret = pcmcia_map_mem_page(link, link->resource[3], srambase);
if (ret) if (ret)
goto failed; goto failed;
ti->sram_base = srambase >> 12; ti->sram_base = srambase >> 12;
ti->sram_virt = ioremap(req.Base, req.Size); ti->sram_virt = ioremap(link->resource[3]->start,
ti->sram_phys = req.Base; resource_size(link->resource[3]));
ti->sram_phys = link->resource[3]->start;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
@ -301,14 +272,6 @@ failed:
return -ENODEV; return -ENODEV;
} /* ibmtr_config */ } /* ibmtr_config */
/*======================================================================
After a card is removed, ibmtr_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void ibmtr_release(struct pcmcia_device *link) static void ibmtr_release(struct pcmcia_device *link)
{ {
ibmtr_dev_t *info = link->priv; ibmtr_dev_t *info = link->priv;
@ -316,7 +279,7 @@ static void ibmtr_release(struct pcmcia_device *link)
dev_dbg(&link->dev, "ibmtr_release\n"); dev_dbg(&link->dev, "ibmtr_release\n");
if (link->win) { if (link->resource[2]->end) {
struct tok_info *ti = netdev_priv(dev); struct tok_info *ti = netdev_priv(dev);
iounmap(ti->mmio); iounmap(ti->mmio);
} }
@ -398,9 +361,7 @@ MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids);
static struct pcmcia_driver ibmtr_cs_driver = { static struct pcmcia_driver ibmtr_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "ibmtr_cs",
.name = "ibmtr_cs",
},
.probe = ibmtr_attach, .probe = ibmtr_attach,
.remove = ibmtr_detach, .remove = ibmtr_detach,
.id_table = ibmtr_ids, .id_table = ibmtr_ids,

View file

@ -146,7 +146,6 @@ Include Files
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <pcmcia/cs.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -435,13 +434,6 @@ static const struct net_device_ops mace_netdev_ops = {
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
}; };
/* ----------------------------------------------------------------------------
nmclan_attach
Creates an "instance" of the driver, allocating local data
structures for one device. The device is registered with Card
Services.
---------------------------------------------------------------------------- */
static int nmclan_probe(struct pcmcia_device *link) static int nmclan_probe(struct pcmcia_device *link)
{ {
mace_private *lp; mace_private *lp;
@ -460,10 +452,9 @@ static int nmclan_probe(struct pcmcia_device *link)
spin_lock_init(&lp->bank_lock); spin_lock_init(&lp->bank_lock);
link->resource[0]->end = 32; link->resource[0]->end = 32;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
link->conf.Attributes = CONF_ENABLE_IRQ; link->config_flags |= CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->config_index = 1;
link->conf.ConfigIndex = 1; link->config_regs = PRESENT_OPTION;
link->conf.Present = PRESENT_OPTION;
lp->tx_free_frames=AM2150_MAX_TX_FRAMES; lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
@ -474,14 +465,6 @@ static int nmclan_probe(struct pcmcia_device *link)
return nmclan_config(link); return nmclan_config(link);
} /* nmclan_attach */ } /* nmclan_attach */
/* ----------------------------------------------------------------------------
nmclan_detach
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
---------------------------------------------------------------------------- */
static void nmclan_detach(struct pcmcia_device *link) static void nmclan_detach(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
@ -625,13 +608,6 @@ static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr)
return 0; return 0;
} /* mace_init */ } /* mace_init */
/* ----------------------------------------------------------------------------
nmclan_config
This routine is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
ethernet device available to the system.
---------------------------------------------------------------------------- */
static int nmclan_config(struct pcmcia_device *link) static int nmclan_config(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
@ -650,7 +626,7 @@ static int nmclan_config(struct pcmcia_device *link)
ret = pcmcia_request_exclusive_irq(link, mace_interrupt); ret = pcmcia_request_exclusive_irq(link, mace_interrupt);
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
@ -712,12 +688,6 @@ failed:
return -ENODEV; return -ENODEV;
} /* nmclan_config */ } /* nmclan_config */
/* ----------------------------------------------------------------------------
nmclan_release
After a card is removed, nmclan_release() will unregister the
net device, and release the PCMCIA configuration. If the device
is still open, this will be postponed until it is closed.
---------------------------------------------------------------------------- */
static void nmclan_release(struct pcmcia_device *link) static void nmclan_release(struct pcmcia_device *link)
{ {
dev_dbg(&link->dev, "nmclan_release\n"); dev_dbg(&link->dev, "nmclan_release\n");
@ -1535,9 +1505,7 @@ MODULE_DEVICE_TABLE(pcmcia, nmclan_ids);
static struct pcmcia_driver nmclan_cs_driver = { static struct pcmcia_driver nmclan_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "nmclan_cs",
.name = "nmclan_cs",
},
.probe = nmclan_probe, .probe = nmclan_probe,
.remove = nmclan_detach, .remove = nmclan_detach,
.id_table = nmclan_ids, .id_table = nmclan_ids,

View file

@ -42,7 +42,6 @@
#include <linux/mii.h> #include <linux/mii.h>
#include "../8390.h" #include "../8390.h"
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -238,14 +237,6 @@ static const struct net_device_ops pcnet_netdev_ops = {
#endif #endif
}; };
/*======================================================================
pcnet_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
======================================================================*/
static int pcnet_probe(struct pcmcia_device *link) static int pcnet_probe(struct pcmcia_device *link)
{ {
pcnet_dev_t *info; pcnet_dev_t *info;
@ -260,23 +251,13 @@ static int pcnet_probe(struct pcmcia_device *link)
info->p_dev = link; info->p_dev = link;
link->priv = dev; link->priv = dev;
link->conf.Attributes = CONF_ENABLE_IRQ; link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
link->conf.IntType = INT_MEMORY_AND_IO;
dev->netdev_ops = &pcnet_netdev_ops; dev->netdev_ops = &pcnet_netdev_ops;
return pcnet_config(link); return pcnet_config(link);
} /* pcnet_attach */ } /* pcnet_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void pcnet_detach(struct pcmcia_device *link) static void pcnet_detach(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
@ -300,22 +281,22 @@ static void pcnet_detach(struct pcmcia_device *link)
static hw_info_t *get_hwinfo(struct pcmcia_device *link) static hw_info_t *get_hwinfo(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
win_req_t req;
u_char __iomem *base, *virt; u_char __iomem *base, *virt;
int i, j; int i, j;
/* Allocate a small memory window */ /* Allocate a small memory window */
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; link->resource[2]->flags |= WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
req.Base = 0; req.Size = 0; link->resource[2]->start = 0; link->resource[2]->end = 0;
req.AccessSpeed = 0; i = pcmcia_request_window(link, link->resource[2], 0);
i = pcmcia_request_window(link, &req, &link->win);
if (i != 0) if (i != 0)
return NULL; return NULL;
virt = ioremap(req.Base, req.Size); virt = ioremap(link->resource[2]->start,
resource_size(link->resource[2]));
for (i = 0; i < NR_INFO; i++) { for (i = 0; i < NR_INFO; i++) {
pcmcia_map_mem_page(link, link->win, hw_info[i].offset & ~(req.Size-1)); pcmcia_map_mem_page(link, link->resource[2],
base = &virt[hw_info[i].offset & (req.Size-1)]; hw_info[i].offset & ~(resource_size(link->resource[2])-1));
base = &virt[hw_info[i].offset & (resource_size(link->resource[2])-1)];
if ((readb(base+0) == hw_info[i].a0) && if ((readb(base+0) == hw_info[i].a0) &&
(readb(base+2) == hw_info[i].a1) && (readb(base+2) == hw_info[i].a1) &&
(readb(base+4) == hw_info[i].a2)) { (readb(base+4) == hw_info[i].a2)) {
@ -326,7 +307,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
} }
iounmap(virt); iounmap(virt);
j = pcmcia_release_window(link, link->win); j = pcmcia_release_window(link, link->resource[2]);
return (i < NR_INFO) ? hw_info+i : NULL; return (i < NR_INFO) ? hw_info+i : NULL;
} /* get_hwinfo */ } /* get_hwinfo */
@ -421,7 +402,7 @@ static hw_info_t *get_ax88190(struct pcmcia_device *link)
int i, j; int i, j;
/* Not much of a test, but the alternatives are messy */ /* Not much of a test, but the alternatives are messy */
if (link->conf.ConfigBase != 0x03c0) if (link->config_base != 0x03c0)
return NULL; return NULL;
outb_p(0x01, ioaddr + EN0_DCFG); /* Set word-wide access. */ outb_p(0x01, ioaddr + EN0_DCFG); /* Set word-wide access. */
@ -463,14 +444,6 @@ static hw_info_t *get_hwired(struct pcmcia_device *link)
return &default_info; return &default_info;
} /* get_hwired */ } /* get_hwired */
/*======================================================================
pcnet_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
ethernet device available to the system.
======================================================================*/
static int try_io_port(struct pcmcia_device *link) static int try_io_port(struct pcmcia_device *link)
{ {
int j, ret; int j, ret;
@ -502,43 +475,22 @@ static int try_io_port(struct pcmcia_device *link)
} }
} }
static int pcnet_confcheck(struct pcmcia_device *p_dev, static int pcnet_confcheck(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
int *priv = priv_data; int *priv = priv_data;
int try = (*priv & 0x1); int try = (*priv & 0x1);
int i;
cistpl_io_t *io = &cfg->io;
if (cfg->index == 0 || cfg->io.nwin == 0) *priv &= (p_dev->resource[2]->end >= 0x4000) ? 0x10 : ~0x10;
if (p_dev->config_index == 0)
return -EINVAL; return -EINVAL;
/* For multifunction cards, by convention, we configure the if (p_dev->resource[0]->end + p_dev->resource[1]->end < 32)
network function with window 0, and serial with window 1 */ return -EINVAL;
if (io->nwin > 1) {
i = (io->win[1].len > io->win[0].len);
p_dev->resource[1]->start = io->win[1-i].base;
p_dev->resource[1]->end = io->win[1-i].len;
} else {
i = p_dev->resource[1]->end = 0;
}
*priv &= ((cfg->mem.nwin == 1) && if (try)
(cfg->mem.win[0].len >= 0x4000)) ? 0x10 : ~0x10;
p_dev->resource[0]->start = io->win[i].base;
p_dev->resource[0]->end = io->win[i].len;
if (!try)
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
else
p_dev->io_lines = 16; p_dev->io_lines = 16;
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 -EINVAL;
} }
static hw_info_t *pcnet_try_config(struct pcmcia_device *link, static hw_info_t *pcnet_try_config(struct pcmcia_device *link,
@ -560,15 +512,14 @@ static hw_info_t *pcnet_try_config(struct pcmcia_device *link,
if (!link->irq) if (!link->irq)
return NULL; return NULL;
if (resource_size(link->resource[1]) == 8) { if (resource_size(link->resource[1]) == 8)
link->conf.Attributes |= CONF_ENABLE_SPKR; link->config_flags |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
}
if ((link->manf_id == MANFID_IBM) && if ((link->manf_id == MANFID_IBM) &&
(link->card_id == PRODID_IBM_HOME_AND_AWAY)) (link->card_id == PRODID_IBM_HOME_AND_AWAY))
link->conf.ConfigIndex |= 0x10; link->config_index |= 0x10;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
return NULL; return NULL;
@ -583,7 +534,7 @@ static hw_info_t *pcnet_try_config(struct pcmcia_device *link,
} else } else
dev->if_port = 0; dev->if_port = 0;
if ((link->conf.ConfigBase == 0x03c0) && if ((link->config_base == 0x03c0) &&
(link->manf_id == 0x149) && (link->card_id == 0xc1ab)) { (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
dev_info(&link->dev, dev_info(&link->dev,
"this is an AX88190 card - use axnet_cs instead.\n"); "this is an AX88190 card - use axnet_cs instead.\n");
@ -689,14 +640,6 @@ failed:
return -ENODEV; return -ENODEV;
} /* pcnet_config */ } /* pcnet_config */
/*======================================================================
After a card is removed, pcnet_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void pcnet_release(struct pcmcia_device *link) static void pcnet_release(struct pcmcia_device *link)
{ {
pcnet_dev_t *info = PRIV(link->priv); pcnet_dev_t *info = PRIV(link->priv);
@ -709,15 +652,6 @@ static void pcnet_release(struct pcmcia_device *link)
pcmcia_disable_device(link); pcmcia_disable_device(link);
} }
/*======================================================================
The card status event handler. Mostly, this schedules other
stuff to run after an event is received. A CARD_REMOVAL event
also sets some flags to discourage the net drivers from trying
to talk to the card any more.
======================================================================*/
static int pcnet_suspend(struct pcmcia_device *link) static int pcnet_suspend(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
@ -1486,7 +1420,6 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
pcnet_dev_t *info = PRIV(dev); pcnet_dev_t *info = PRIV(dev);
win_req_t req;
int i, window_size, offset, ret; int i, window_size, offset, ret;
window_size = (stop_pg - start_pg) << 8; window_size = (stop_pg - start_pg) << 8;
@ -1497,22 +1430,22 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
window_size = roundup_pow_of_two(window_size); window_size = roundup_pow_of_two(window_size);
/* Allocate a memory window */ /* Allocate a memory window */
req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE; link->resource[3]->flags |= WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
req.Attributes |= WIN_USE_WAIT; link->resource[3]->flags |= WIN_USE_WAIT;
req.Base = 0; req.Size = window_size; link->resource[3]->start = 0; link->resource[3]->end = window_size;
req.AccessSpeed = mem_speed; ret = pcmcia_request_window(link, link->resource[3], mem_speed);
ret = pcmcia_request_window(link, &req, &link->win);
if (ret) if (ret)
goto failed; goto failed;
offset = (start_pg << 8) + cm_offset; offset = (start_pg << 8) + cm_offset;
offset -= offset % window_size; offset -= offset % window_size;
ret = pcmcia_map_mem_page(link, link->win, offset); ret = pcmcia_map_mem_page(link, link->resource[3], offset);
if (ret) if (ret)
goto failed; goto failed;
/* Try scribbling on the buffer */ /* Try scribbling on the buffer */
info->base = ioremap(req.Base, window_size); info->base = ioremap(link->resource[3]->start,
resource_size(link->resource[3]));
for (i = 0; i < (TX_PAGES<<8); i += 2) for (i = 0; i < (TX_PAGES<<8); i += 2)
__raw_writew((i>>1), info->base+offset+i); __raw_writew((i>>1), info->base+offset+i);
udelay(100); udelay(100);
@ -1521,19 +1454,20 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
pcnet_reset_8390(dev); pcnet_reset_8390(dev);
if (i != (TX_PAGES<<8)) { if (i != (TX_PAGES<<8)) {
iounmap(info->base); iounmap(info->base);
pcmcia_release_window(link, link->win); pcmcia_release_window(link, link->resource[3]);
info->base = NULL; link->win = 0; info->base = NULL;
goto failed; goto failed;
} }
ei_status.mem = info->base + offset; ei_status.mem = info->base + offset;
ei_status.priv = req.Size; ei_status.priv = resource_size(link->resource[3]);
dev->mem_start = (u_long)ei_status.mem; dev->mem_start = (u_long)ei_status.mem;
dev->mem_end = dev->mem_start + req.Size; dev->mem_end = dev->mem_start + resource_size(link->resource[3]);
ei_status.tx_start_page = start_pg; ei_status.tx_start_page = start_pg;
ei_status.rx_start_page = start_pg + TX_PAGES; ei_status.rx_start_page = start_pg + TX_PAGES;
ei_status.stop_page = start_pg + ((req.Size - offset) >> 8); ei_status.stop_page = start_pg + (
(resource_size(link->resource[3]) - offset) >> 8);
/* set up block i/o functions */ /* set up block i/o functions */
ei_status.get_8390_hdr = &shmem_get_8390_hdr; ei_status.get_8390_hdr = &shmem_get_8390_hdr;
@ -1772,9 +1706,7 @@ MODULE_FIRMWARE("cis/PE-200.cis");
MODULE_FIRMWARE("cis/tamarack.cis"); MODULE_FIRMWARE("cis/tamarack.cis");
static struct pcmcia_driver pcnet_driver = { static struct pcmcia_driver pcnet_driver = {
.drv = { .name = "pcnet_cs",
.name = "pcnet_cs",
},
.probe = pcnet_probe, .probe = pcnet_probe,
.remove = pcnet_detach, .remove = pcnet_detach,
.owner = THIS_MODULE, .owner = THIS_MODULE,

View file

@ -44,7 +44,6 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
@ -300,14 +299,6 @@ static const struct net_device_ops smc_netdev_ops = {
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
}; };
/*======================================================================
smc91c92_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
======================================================================*/
static int smc91c92_probe(struct pcmcia_device *link) static int smc91c92_probe(struct pcmcia_device *link)
{ {
struct smc_private *smc; struct smc_private *smc;
@ -324,10 +315,6 @@ static int smc91c92_probe(struct pcmcia_device *link)
link->priv = dev; link->priv = dev;
spin_lock_init(&smc->lock); spin_lock_init(&smc->lock);
link->resource[0]->end = 16;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
/* The SMC91c92-specific entries in the device structure. */ /* The SMC91c92-specific entries in the device structure. */
dev->netdev_ops = &smc_netdev_ops; dev->netdev_ops = &smc_netdev_ops;
@ -343,15 +330,6 @@ static int smc91c92_probe(struct pcmcia_device *link)
return smc91c92_config(link); return smc91c92_config(link);
} /* smc91c92_attach */ } /* smc91c92_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void smc91c92_detach(struct pcmcia_device *link) static void smc91c92_detach(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
@ -412,26 +390,28 @@ static int mhz_3288_power(struct pcmcia_device *link)
mdelay(200); mdelay(200);
/* Now read and write the COR... */ /* Now read and write the COR... */
tmp = readb(smc->base + link->conf.ConfigBase + CISREG_COR); tmp = readb(smc->base + link->config_base + CISREG_COR);
udelay(5); udelay(5);
writeb(tmp, smc->base + link->conf.ConfigBase + CISREG_COR); writeb(tmp, smc->base + link->config_base + CISREG_COR);
return 0; return 0;
} }
static int mhz_mfc_config_check(struct pcmcia_device *p_dev, static int mhz_mfc_config_check(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
int k; int k;
p_dev->resource[1]->start = cf->io.win[0].base; p_dev->io_lines = 16;
p_dev->resource[1]->start = p_dev->resource[0]->start;
p_dev->resource[1]->end = 8;
p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->resource[0]->end = 16;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
for (k = 0; k < 0x400; k += 0x10) { for (k = 0; k < 0x400; k += 0x10) {
if (k & 0x80) if (k & 0x80)
continue; continue;
p_dev->resource[0]->start = k ^ 0x300; p_dev->resource[0]->start = k ^ 0x300;
p_dev->io_lines = 16;
if (!pcmcia_request_io(p_dev)) if (!pcmcia_request_io(p_dev))
return 0; return 0;
} }
@ -442,14 +422,11 @@ static int mhz_mfc_config(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
struct smc_private *smc = netdev_priv(dev); struct smc_private *smc = netdev_priv(dev);
win_req_t req;
unsigned int offset; unsigned int offset;
int i; int i;
link->conf.Attributes |= CONF_ENABLE_SPKR; link->config_flags |= CONF_ENABLE_SPKR | CONF_ENABLE_IRQ |
link->conf.Status = CCSR_AUDIO_ENA; CONF_AUTO_SET_IO;
link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
link->resource[1]->end = 8;
/* The Megahertz combo cards have modem-like CIS entries, so /* The Megahertz combo cards have modem-like CIS entries, so
we have to explicitly try a bunch of port combinations. */ we have to explicitly try a bunch of port combinations. */
@ -459,16 +436,16 @@ static int mhz_mfc_config(struct pcmcia_device *link)
dev->base_addr = link->resource[0]->start; dev->base_addr = link->resource[0]->start;
/* Allocate a memory window, for accessing the ISR */ /* Allocate a memory window, for accessing the ISR */
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; link->resource[2]->flags = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
req.Base = req.Size = 0; link->resource[2]->start = link->resource[2]->end = 0;
req.AccessSpeed = 0; i = pcmcia_request_window(link, link->resource[2], 0);
i = pcmcia_request_window(link, &req, &link->win);
if (i != 0) if (i != 0)
return -ENODEV; return -ENODEV;
smc->base = ioremap(req.Base, req.Size); smc->base = ioremap(link->resource[2]->start,
offset = (smc->manfid == MANFID_MOTOROLA) ? link->conf.ConfigBase : 0; resource_size(link->resource[2]));
i = pcmcia_map_mem_page(link, link->win, offset); offset = (smc->manfid == MANFID_MOTOROLA) ? link->config_base : 0;
i = pcmcia_map_mem_page(link, link->resource[2], offset);
if ((i == 0) && if ((i == 0) &&
(smc->manfid == MANFID_MEGAHERTZ) && (smc->manfid == MANFID_MEGAHERTZ) &&
(smc->cardid == PRODID_MEGAHERTZ_EM3288)) (smc->cardid == PRODID_MEGAHERTZ_EM3288))
@ -591,14 +568,12 @@ static int mot_setup(struct pcmcia_device *link)
/*====================================================================*/ /*====================================================================*/
static int smc_configcheck(struct pcmcia_device *p_dev, static int smc_configcheck(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
p_dev->resource[0]->start = cf->io.win[0].base; p_dev->resource[0]->end = 16;
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_AUTO;
return pcmcia_request_io(p_dev); return pcmcia_request_io(p_dev);
} }
@ -607,7 +582,8 @@ static int smc_config(struct pcmcia_device *link)
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
int i; int i;
link->resource[0]->end = 16; link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
i = pcmcia_loop_config(link, smc_configcheck, NULL); i = pcmcia_loop_config(link, smc_configcheck, NULL);
if (!i) if (!i)
dev->base_addr = link->resource[0]->start; dev->base_addr = link->resource[0]->start;
@ -640,15 +616,14 @@ static int osi_config(struct pcmcia_device *link)
static const unsigned int com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; static const unsigned int com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
int i, j; int i, j;
link->conf.Attributes |= CONF_ENABLE_SPKR; link->config_flags |= CONF_ENABLE_SPKR | CONF_ENABLE_IRQ;
link->conf.Status = CCSR_AUDIO_ENA;
link->resource[0]->end = 64; link->resource[0]->end = 64;
link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
link->resource[1]->end = 8; link->resource[1]->end = 8;
/* Enable Hard Decode, LAN, Modem */ /* Enable Hard Decode, LAN, Modem */
link->conf.ConfigIndex = 0x23;
link->io_lines = 16; link->io_lines = 16;
link->config_index = 0x23;
for (i = j = 0; j < 4; j++) { for (i = j = 0; j < 4; j++) {
link->resource[1]->start = com[j]; link->resource[1]->start = com[j];
@ -658,7 +633,7 @@ static int osi_config(struct pcmcia_device *link)
} }
if (i != 0) { if (i != 0) {
/* Fallback: turn off hard decode */ /* Fallback: turn off hard decode */
link->conf.ConfigIndex = 0x03; link->config_index = 0x03;
link->resource[1]->end = 0; link->resource[1]->end = 0;
i = pcmcia_request_io(link); i = pcmcia_request_io(link);
} }
@ -817,27 +792,16 @@ static int check_sig(struct pcmcia_device *link)
} }
if (width) { if (width) {
modconf_t mod = {
.Attributes = CONF_IO_CHANGE_WIDTH,
};
printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
smc91c92_suspend(link); smc91c92_suspend(link);
pcmcia_modify_configuration(link, &mod); pcmcia_fixup_iowidth(link);
smc91c92_resume(link); smc91c92_resume(link);
return check_sig(link); return check_sig(link);
} }
return -ENODEV; return -ENODEV;
} }
/*======================================================================
smc91c92_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
ethernet device available to the system.
======================================================================*/
static int smc91c92_config(struct pcmcia_device *link) static int smc91c92_config(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
@ -869,7 +833,7 @@ static int smc91c92_config(struct pcmcia_device *link)
i = pcmcia_request_irq(link, smc_interrupt); i = pcmcia_request_irq(link, smc_interrupt);
if (i) if (i)
goto config_failed; goto config_failed;
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_enable_device(link);
if (i) if (i)
goto config_failed; goto config_failed;
@ -988,18 +952,10 @@ config_failed:
return -ENODEV; return -ENODEV;
} /* smc91c92_config */ } /* smc91c92_config */
/*======================================================================
After a card is removed, smc91c92_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void smc91c92_release(struct pcmcia_device *link) static void smc91c92_release(struct pcmcia_device *link)
{ {
dev_dbg(&link->dev, "smc91c92_release\n"); dev_dbg(&link->dev, "smc91c92_release\n");
if (link->win) { if (link->resource[2]->end) {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
struct smc_private *smc = netdev_priv(dev); struct smc_private *smc = netdev_priv(dev);
iounmap(smc->base); iounmap(smc->base);
@ -2101,9 +2057,7 @@ MODULE_DEVICE_TABLE(pcmcia, smc91c92_ids);
static struct pcmcia_driver smc91c92_cs_driver = { static struct pcmcia_driver smc91c92_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "smc91c92_cs",
.name = "smc91c92_cs",
},
.probe = smc91c92_probe, .probe = smc91c92_probe,
.remove = smc91c92_detach, .remove = smc91c92_detach,
.id_table = smc91c92_ids, .id_table = smc91c92_ids,

View file

@ -82,7 +82,6 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/mii.h> #include <linux/mii.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
@ -267,33 +266,11 @@ static unsigned mii_rd(unsigned int ioaddr, u_char phyaddr, u_char phyreg);
static void mii_wr(unsigned int ioaddr, u_char phyaddr, u_char phyreg, static void mii_wr(unsigned int ioaddr, u_char phyaddr, u_char phyreg,
unsigned data, int len); unsigned data, int len);
/*
* The event() function is this driver's Card Services event handler.
* It will be called by Card Services when an appropriate card status
* event is received. The config() and release() entry points are
* used to configure or release a socket, in response to card insertion
* and ejection events. They are invoked from the event handler.
*/
static int has_ce2_string(struct pcmcia_device * link); static int has_ce2_string(struct pcmcia_device * link);
static int xirc2ps_config(struct pcmcia_device * link); static int xirc2ps_config(struct pcmcia_device * link);
static void xirc2ps_release(struct pcmcia_device * link); static void xirc2ps_release(struct pcmcia_device * link);
/****************
* The attach() and detach() entry points are used to create and destroy
* "instances" of the driver, where each instance represents everything
* needed to manage one actual PCMCIA card.
*/
static void xirc2ps_detach(struct pcmcia_device *p_dev); static void xirc2ps_detach(struct pcmcia_device *p_dev);
/****************
* You'll also need to prototype all the functions that will actually
* be used to talk to your device. See 'pcmem_cs' for a good example
* of a fully self-sufficient driver; the other drivers rely more or
* less on other parts of the kernel.
*/
static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id); static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id);
typedef struct local_info_t { typedef struct local_info_t {
@ -501,16 +478,6 @@ static const struct net_device_ops netdev_ops = {
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
}; };
/****************
* xirc2ps_attach() creates an "instance" of the driver, allocating
* local data structures for one device. The device is registered
* with Card Services.
*
* The dev_link structure is initialized, but we don't actually
* configure the card at this point -- we wait until we receive a
* card insertion event.
*/
static int static int
xirc2ps_probe(struct pcmcia_device *link) xirc2ps_probe(struct pcmcia_device *link)
{ {
@ -529,9 +496,7 @@ xirc2ps_probe(struct pcmcia_device *link)
link->priv = dev; link->priv = dev;
/* General socket configuration */ /* General socket configuration */
link->conf.Attributes = CONF_ENABLE_IRQ; link->config_index = 1;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
/* Fill in card specific entries */ /* Fill in card specific entries */
dev->netdev_ops = &netdev_ops; dev->netdev_ops = &netdev_ops;
@ -542,13 +507,6 @@ xirc2ps_probe(struct pcmcia_device *link)
return xirc2ps_config(link); return xirc2ps_config(link);
} /* xirc2ps_attach */ } /* xirc2ps_attach */
/****************
* This deletes a driver "instance". The device is de-registered
* with Card Services. If it has been released, all local data
* structures are freed. Otherwise, the structures will be freed
* when the device is released.
*/
static void static void
xirc2ps_detach(struct pcmcia_device *link) xirc2ps_detach(struct pcmcia_device *link)
{ {
@ -667,44 +625,53 @@ has_ce2_string(struct pcmcia_device * p_dev)
} }
static int static int
xirc2ps_config_modem(struct pcmcia_device *p_dev, xirc2ps_config_modem(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
unsigned int ioaddr; unsigned int ioaddr;
if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { if ((p_dev->resource[0]->start & 0xf) == 8)
for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { return -ENODEV;
p_dev->resource[1]->start = cf->io.win[0].base;
p_dev->resource[0]->start = ioaddr; p_dev->resource[0]->end = 16;
if (!pcmcia_request_io(p_dev)) p_dev->resource[1]->end = 8;
return 0; p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
} p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->io_lines = 10;
p_dev->resource[1]->start = p_dev->resource[0]->start;
for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
p_dev->resource[0]->start = ioaddr;
if (!pcmcia_request_io(p_dev))
return 0;
} }
return -ENODEV; return -ENODEV;
} }
static int static int
xirc2ps_config_check(struct pcmcia_device *p_dev, xirc2ps_config_check(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
int *pass = priv_data; int *pass = priv_data;
resource_size_t tmp = p_dev->resource[1]->start;
if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { tmp += (*pass ? (p_dev->config_index & 0x20 ? -24 : 8)
p_dev->resource[1]->start = cf->io.win[0].base; : (p_dev->config_index & 0x20 ? 8 : -24));
p_dev->resource[0]->start = p_dev->resource[1]->start
+ (*pass ? (cf->index & 0x20 ? -24:8)
: (cf->index & 0x20 ? 8:-24));
if (!pcmcia_request_io(p_dev))
return 0;
}
return -ENODEV;
if ((p_dev->resource[0]->start & 0xf) == 8)
return -ENODEV;
p_dev->resource[0]->end = 18;
p_dev->resource[1]->end = 8;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->io_lines = 10;
p_dev->resource[1]->start = p_dev->resource[0]->start;
p_dev->resource[0]->start = tmp;
return pcmcia_request_io(p_dev);
} }
@ -727,11 +694,6 @@ static int pcmcia_get_mac_ce(struct pcmcia_device *p_dev,
}; };
/****************
* xirc2ps_config() is scheduled to run after a CARD_INSERTION event
* is received, to configure the PCMCIA socket, and to make the
* ethernet device available to the system.
*/
static int static int
xirc2ps_config(struct pcmcia_device * link) xirc2ps_config(struct pcmcia_device * link)
{ {
@ -807,32 +769,24 @@ xirc2ps_config(struct pcmcia_device * link)
goto failure; goto failure;
} }
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
link->io_lines = 10;
if (local->modem) { if (local->modem) {
int pass; int pass;
link->config_flags |= CONF_AUTO_SET_IO;
if (do_sound) {
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status |= CCSR_AUDIO_ENA;
}
link->resource[1]->end = 8;
link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
if (local->dingo) { if (local->dingo) {
/* Take the Modem IO port from the CIS and scan for a free /* Take the Modem IO port from the CIS and scan for a free
* Ethernet port */ * Ethernet port */
link->resource[0]->end = 16; /* no Mako stuff anymore */
if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL)) if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL))
goto port_found; goto port_found;
} else { } else {
link->resource[0]->end = 18;
/* We do 2 passes here: The first one uses the regular mapping and /* We do 2 passes here: The first one uses the regular mapping and
* the second tries again, thereby considering that the 32 ports are * the second tries again, thereby considering that the 32 ports are
* mirrored every 32 bytes. Actually we use a mirrored port for * mirrored every 32 bytes. Actually we use a mirrored port for
* the Mako if (on the first pass) the COR bit 5 is set. * the Mako if (on the first pass) the COR bit 5 is set.
*/ */
for (pass=0; pass < 2; pass++) for (pass=0; pass < 2; pass++)
if (!pcmcia_loop_config(link, xirc2ps_config_check, &pass)) if (!pcmcia_loop_config(link, xirc2ps_config_check,
&pass))
goto port_found; goto port_found;
/* if special option: /* if special option:
* try to configure as Ethernet only. * try to configure as Ethernet only.
@ -840,7 +794,9 @@ xirc2ps_config(struct pcmcia_device * link)
} }
printk(KNOT_XIRC "no ports available\n"); printk(KNOT_XIRC "no ports available\n");
} else { } else {
link->io_lines = 10;
link->resource[0]->end = 16; link->resource[0]->end = 16;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
link->resource[0]->start = ioaddr; link->resource[0]->start = ioaddr;
if (!(err = pcmcia_request_io(link))) if (!(err = pcmcia_request_io(link)))
@ -861,16 +817,14 @@ xirc2ps_config(struct pcmcia_device * link)
if ((err=pcmcia_request_irq(link, xirc2ps_interrupt))) if ((err=pcmcia_request_irq(link, xirc2ps_interrupt)))
goto config_error; goto config_error;
/**************** link->config_flags |= CONF_ENABLE_IRQ;
* This actually configures the PCMCIA socket -- setting up if (do_sound)
* the I/O windows and the interrupt mapping. link->config_flags |= CONF_ENABLE_SPKR;
*/
if ((err=pcmcia_request_configuration(link, &link->conf))) if ((err = pcmcia_enable_device(link)))
goto config_error; goto config_error;
if (local->dingo) { if (local->dingo) {
win_req_t req;
/* Reset the modem's BAR to the correct value /* Reset the modem's BAR to the correct value
* This is necessary because in the RequestConfiguration call, * This is necessary because in the RequestConfiguration call,
* the base address of the ethernet port (BasePort1) is written * the base address of the ethernet port (BasePort1) is written
@ -890,14 +844,14 @@ xirc2ps_config(struct pcmcia_device * link)
* is at 0x0800. So we allocate a window into the attribute * is at 0x0800. So we allocate a window into the attribute
* memory and write direct to the CIS registers * memory and write direct to the CIS registers
*/ */
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; link->resource[2]->flags = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM |
req.Base = req.Size = 0; WIN_ENABLE;
req.AccessSpeed = 0; link->resource[2]->start = link->resource[2]->end = 0;
if ((err = pcmcia_request_window(link, &req, &link->win))) if ((err = pcmcia_request_window(link, link->resource[2], 0)))
goto config_error; goto config_error;
local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800; local->dingo_ccr = ioremap(link->resource[2]->start, 0x1000) + 0x0800;
if ((err = pcmcia_map_mem_page(link, link->win, 0))) if ((err = pcmcia_map_mem_page(link, link->resource[2], 0)))
goto config_error; goto config_error;
/* Setup the CCRs; there are no infos in the CIS about the Ethernet /* Setup the CCRs; there are no infos in the CIS about the Ethernet
@ -978,17 +932,12 @@ xirc2ps_config(struct pcmcia_device * link)
return -ENODEV; return -ENODEV;
} /* xirc2ps_config */ } /* xirc2ps_config */
/****************
* After a card is removed, xirc2ps_release() will unregister the net
* device, and release the PCMCIA configuration. If the device is
* still open, this will be postponed until it is closed.
*/
static void static void
xirc2ps_release(struct pcmcia_device *link) xirc2ps_release(struct pcmcia_device *link)
{ {
dev_dbg(&link->dev, "release\n"); dev_dbg(&link->dev, "release\n");
if (link->win) { if (link->resource[2]->end) {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
local_info_t *local = netdev_priv(dev); local_info_t *local = netdev_priv(dev);
if (local->dingo) if (local->dingo)
@ -1830,9 +1779,7 @@ MODULE_DEVICE_TABLE(pcmcia, xirc2ps_ids);
static struct pcmcia_driver xirc2ps_cs_driver = { static struct pcmcia_driver xirc2ps_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "xirc2ps_cs",
.name = "xirc2ps_cs",
},
.probe = xirc2ps_probe, .probe = xirc2ps_probe,
.remove = xirc2ps_detach, .remove = xirc2ps_detach,
.id_table = xirc2ps_ids, .id_table = xirc2ps_ids,

View file

@ -32,7 +32,6 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -54,58 +53,21 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
/*====================================================================*/ /*====================================================================*/
/*
The event() function is this driver's Card Services event handler.
It will be called by Card Services when an appropriate card status
event is received. The config() and release() entry points are
used to configure or release a socket, in response to card
insertion and ejection events. They are invoked from the airo_cs
event handler.
*/
static int airo_config(struct pcmcia_device *link); static int airo_config(struct pcmcia_device *link);
static void airo_release(struct pcmcia_device *link); static void airo_release(struct pcmcia_device *link);
/*
The attach() and detach() entry points are used to create and destroy
"instances" of the driver, where each instance represents everything
needed to manage one actual PCMCIA card.
*/
static void airo_detach(struct pcmcia_device *p_dev); static void airo_detach(struct pcmcia_device *p_dev);
typedef struct local_info_t { typedef struct local_info_t {
struct net_device *eth_dev; struct net_device *eth_dev;
} local_info_t; } local_info_t;
/*======================================================================
airo_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
static int airo_probe(struct pcmcia_device *p_dev) static int airo_probe(struct pcmcia_device *p_dev)
{ {
local_info_t *local; local_info_t *local;
dev_dbg(&p_dev->dev, "airo_attach()\n"); dev_dbg(&p_dev->dev, "airo_attach()\n");
/*
General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost
everything. In most clients, many details (i.e., number, sizes,
and attributes of IO windows) are fixed by the nature of the
device, and can be hard-wired here.
*/
p_dev->conf.Attributes = 0;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
/* Allocate space for private device-specific data */ /* Allocate space for private device-specific data */
local = kzalloc(sizeof(local_info_t), GFP_KERNEL); local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) { if (!local) {
@ -117,15 +79,6 @@ static int airo_probe(struct pcmcia_device *p_dev)
return airo_config(p_dev); return airo_config(p_dev);
} /* airo_attach */ } /* airo_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void airo_detach(struct pcmcia_device *link) static void airo_detach(struct pcmcia_device *link)
{ {
dev_dbg(&link->dev, "airo_detach\n"); dev_dbg(&link->dev, "airo_detach\n");
@ -140,60 +93,12 @@ static void airo_detach(struct pcmcia_device *link)
kfree(link->priv); kfree(link->priv);
} /* airo_detach */ } /* airo_detach */
/*====================================================================== static int airo_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
airo_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
======================================================================*/
static int airo_cs_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
if (cfg->index == 0) if (p_dev->config_index == 0)
return -ENODEV; return -EINVAL;
/* Does this card need audio output? */ return pcmcia_request_io(p_dev);
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
p_dev->conf.Status = CCSR_AUDIO_ENA;
}
/* Use power settings for Vcc and Vpp if present */
/* Note that the CIS values need to be rescaled */
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
p_dev->resource[1]->flags = p_dev->resource[0]->flags;
p_dev->resource[1]->start = io->win[1].base;
p_dev->resource[1]->end = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(p_dev) != 0)
return -ENODEV;
/* If we got this far, we're cool! */
return 0;
} }
@ -206,20 +111,9 @@ static int airo_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "airo_config\n"); dev_dbg(&link->dev, "airo_config\n");
/* link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
* In this loop, we scan the CIS for configuration table CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
* entries, each of which describes a valid card
* configuration, including voltage, IO window, memory window,
* and interrupt settings.
*
* We make no assumptions about the card to be configured: we
* use just the information available in the CIS. In an ideal
* world, this would work for any PCMCIA card, but it requires
* a complete and accurate CIS. In practice, a driver usually
* "knows" most of these things without consulting the CIS,
* and most client drivers will only use the CIS to fill in
* implementation-defined details.
*/
ret = pcmcia_loop_config(link, airo_cs_config_check, NULL); ret = pcmcia_loop_config(link, airo_cs_config_check, NULL);
if (ret) if (ret)
goto failed; goto failed;
@ -227,12 +121,7 @@ static int airo_config(struct pcmcia_device *link)
if (!link->irq) if (!link->irq)
goto failed; goto failed;
/* ret = pcmcia_enable_device(link);
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
((local_info_t *)link->priv)->eth_dev = ((local_info_t *)link->priv)->eth_dev =
@ -241,17 +130,6 @@ static int airo_config(struct pcmcia_device *link)
if (!((local_info_t *)link->priv)->eth_dev) if (!((local_info_t *)link->priv)->eth_dev)
goto failed; goto failed;
/* Finally, report what we've done */
dev_info(&link->dev, "index 0x%02x: ",
link->conf.ConfigIndex);
if (link->conf.Vpp)
printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
printk(", irq %d", link->irq);
if (link->resource[0])
printk(" & %pR", link->resource[0]);
if (link->resource[1])
printk(" & %pR", link->resource[1]);
printk("\n");
return 0; return 0;
failed: failed:
@ -259,14 +137,6 @@ static int airo_config(struct pcmcia_device *link)
return -ENODEV; return -ENODEV;
} /* airo_config */ } /* airo_config */
/*======================================================================
After a card is removed, airo_release() will unregister the
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void airo_release(struct pcmcia_device *link) static void airo_release(struct pcmcia_device *link)
{ {
dev_dbg(&link->dev, "airo_release\n"); dev_dbg(&link->dev, "airo_release\n");
@ -305,9 +175,7 @@ MODULE_DEVICE_TABLE(pcmcia, airo_ids);
static struct pcmcia_driver airo_driver = { static struct pcmcia_driver airo_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "airo_cs",
.name = "airo_cs",
},
.probe = airo_probe, .probe = airo_probe,
.remove = airo_detach, .remove = airo_detach,
.id_table = airo_ids, .id_table = airo_ids,
@ -315,12 +183,12 @@ static struct pcmcia_driver airo_driver = {
.resume = airo_resume, .resume = airo_resume,
}; };
static int airo_cs_init(void) static int __init airo_cs_init(void)
{ {
return pcmcia_register_driver(&airo_driver); return pcmcia_register_driver(&airo_driver);
} }
static void airo_cs_cleanup(void) static void __exit airo_cs_cleanup(void)
{ {
pcmcia_unregister_driver(&airo_driver); pcmcia_unregister_driver(&airo_driver);
} }

View file

@ -42,7 +42,6 @@
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/device.h> #include <linux/device.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -64,58 +63,21 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
/*====================================================================*/ /*====================================================================*/
/*
The event() function is this driver's Card Services event handler.
It will be called by Card Services when an appropriate card status
event is received. The config() and release() entry points are
used to configure or release a socket, in response to card
insertion and ejection events. They are invoked from the atmel_cs
event handler.
*/
static int atmel_config(struct pcmcia_device *link); static int atmel_config(struct pcmcia_device *link);
static void atmel_release(struct pcmcia_device *link); static void atmel_release(struct pcmcia_device *link);
/*
The attach() and detach() entry points are used to create and destroy
"instances" of the driver, where each instance represents everything
needed to manage one actual PCMCIA card.
*/
static void atmel_detach(struct pcmcia_device *p_dev); static void atmel_detach(struct pcmcia_device *p_dev);
typedef struct local_info_t { typedef struct local_info_t {
struct net_device *eth_dev; struct net_device *eth_dev;
} local_info_t; } local_info_t;
/*======================================================================
atmel_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
static int atmel_probe(struct pcmcia_device *p_dev) static int atmel_probe(struct pcmcia_device *p_dev)
{ {
local_info_t *local; local_info_t *local;
dev_dbg(&p_dev->dev, "atmel_attach()\n"); dev_dbg(&p_dev->dev, "atmel_attach()\n");
/*
General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost
everything. In most clients, many details (i.e., number, sizes,
and attributes of IO windows) are fixed by the nature of the
device, and can be hard-wired here.
*/
p_dev->conf.Attributes = 0;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
/* Allocate space for private device-specific data */ /* Allocate space for private device-specific data */
local = kzalloc(sizeof(local_info_t), GFP_KERNEL); local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) { if (!local) {
@ -127,15 +89,6 @@ static int atmel_probe(struct pcmcia_device *p_dev)
return atmel_config(p_dev); return atmel_config(p_dev);
} /* atmel_attach */ } /* atmel_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void atmel_detach(struct pcmcia_device *link) static void atmel_detach(struct pcmcia_device *link)
{ {
dev_dbg(&link->dev, "atmel_detach\n"); dev_dbg(&link->dev, "atmel_detach\n");
@ -145,14 +98,6 @@ static void atmel_detach(struct pcmcia_device *link)
kfree(link->priv); kfree(link->priv);
} }
/*======================================================================
atmel_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
======================================================================*/
/* Call-back function to interrogate PCMCIA-specific information /* Call-back function to interrogate PCMCIA-specific information
about the current existance of the card */ about the current existance of the card */
static int card_present(void *arg) static int card_present(void *arg)
@ -165,47 +110,11 @@ static int card_present(void *arg)
return 0; return 0;
} }
static int atmel_config_check(struct pcmcia_device *p_dev, static int atmel_config_check(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
if (cfg->index == 0) if (p_dev->config_index == 0)
return -ENODEV; return -EINVAL;
/* Does this card need audio output? */
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
p_dev->conf.Status = CCSR_AUDIO_ENA;
}
/* Use power settings for Vcc and Vpp if present */
/* Note that the CIS values need to be rescaled */
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
p_dev->resource[1]->flags = p_dev->resource[0]->flags;
p_dev->resource[1]->start = io->win[1].base;
p_dev->resource[1]->end = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
return pcmcia_request_io(p_dev); return pcmcia_request_io(p_dev);
} }
@ -220,18 +129,9 @@ static int atmel_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "atmel_config\n"); dev_dbg(&link->dev, "atmel_config\n");
/* link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
In this loop, we scan the CIS for configuration table entries, CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
each of which describes a valid card configuration, including
voltage, IO window, memory window, and interrupt settings.
We make no assumptions about the card to be configured: we use
just the information available in the CIS. In an ideal world,
this would work for any PCMCIA card, but it requires a complete
and accurate CIS. In practice, a driver usually "knows" most of
these things without consulting the CIS, and most client drivers
will only use the CIS to fill in implementation-defined details.
*/
if (pcmcia_loop_config(link, atmel_config_check, NULL)) if (pcmcia_loop_config(link, atmel_config_check, NULL))
goto failed; goto failed;
@ -240,12 +140,7 @@ static int atmel_config(struct pcmcia_device *link)
goto failed; goto failed;
} }
/* ret = pcmcia_enable_device(link);
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
@ -267,14 +162,6 @@ static int atmel_config(struct pcmcia_device *link)
return -ENODEV; return -ENODEV;
} }
/*======================================================================
After a card is removed, atmel_release() will unregister the
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void atmel_release(struct pcmcia_device *link) static void atmel_release(struct pcmcia_device *link)
{ {
struct net_device *dev = ((local_info_t*)link->priv)->eth_dev; struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
@ -353,9 +240,7 @@ MODULE_DEVICE_TABLE(pcmcia, atmel_ids);
static struct pcmcia_driver atmel_driver = { static struct pcmcia_driver atmel_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "atmel_cs",
.name = "atmel_cs",
},
.probe = atmel_probe, .probe = atmel_probe,
.remove = atmel_detach, .remove = atmel_detach,
.id_table = atmel_ids, .id_table = atmel_ids,
@ -363,12 +248,12 @@ static struct pcmcia_driver atmel_driver = {
.resume = atmel_resume, .resume = atmel_resume,
}; };
static int atmel_cs_init(void) static int __init atmel_cs_init(void)
{ {
return pcmcia_register_driver(&atmel_driver); return pcmcia_register_driver(&atmel_driver);
} }
static void atmel_cs_cleanup(void) static void __exit atmel_cs_cleanup(void)
{ {
pcmcia_unregister_driver(&atmel_driver); pcmcia_unregister_driver(&atmel_driver);
} }

View file

@ -26,7 +26,6 @@
#include <linux/ssb/ssb.h> #include <linux/ssb/ssb.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -63,7 +62,6 @@ static int b43_pcmcia_resume(struct pcmcia_device *dev)
static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
{ {
struct ssb_bus *ssb; struct ssb_bus *ssb;
win_req_t win;
int err = -ENOMEM; int err = -ENOMEM;
int res = 0; int res = 0;
@ -73,30 +71,28 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
err = -ENODEV; err = -ENODEV;
dev->conf.Attributes = CONF_ENABLE_IRQ; dev->config_flags |= CONF_ENABLE_IRQ;
dev->conf.IntType = INT_MEMORY_AND_IO;
win.Attributes = WIN_ENABLE | WIN_DATA_WIDTH_16 | dev->resource[2]->flags |= WIN_ENABLE | WIN_DATA_WIDTH_16 |
WIN_USE_WAIT; WIN_USE_WAIT;
win.Base = 0; dev->resource[2]->start = 0;
win.Size = SSB_CORE_SIZE; dev->resource[2]->end = SSB_CORE_SIZE;
win.AccessSpeed = 250; res = pcmcia_request_window(dev, dev->resource[2], 250);
res = pcmcia_request_window(dev, &win, &dev->win);
if (res != 0) if (res != 0)
goto err_kfree_ssb; goto err_kfree_ssb;
res = pcmcia_map_mem_page(dev, dev->win, 0); res = pcmcia_map_mem_page(dev, dev->resource[2], 0);
if (res != 0) if (res != 0)
goto err_disable; goto err_disable;
if (!dev->irq) if (!dev->irq)
goto err_disable; goto err_disable;
res = pcmcia_request_configuration(dev, &dev->conf); res = pcmcia_enable_device(dev);
if (res != 0) if (res != 0)
goto err_disable; goto err_disable;
err = ssb_bus_pcmciabus_register(ssb, dev, win.Base); err = ssb_bus_pcmciabus_register(ssb, dev, dev->resource[2]->start);
if (err) if (err)
goto err_disable; goto err_disable;
dev->priv = ssb; dev->priv = ssb;
@ -125,9 +121,7 @@ static void __devexit b43_pcmcia_remove(struct pcmcia_device *dev)
static struct pcmcia_driver b43_pcmcia_driver = { static struct pcmcia_driver b43_pcmcia_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "b43-pcmcia",
.name = "b43-pcmcia",
},
.id_table = b43_pcmcia_tbl, .id_table = b43_pcmcia_tbl,
.probe = b43_pcmcia_probe, .probe = b43_pcmcia_probe,
.remove = __devexit_p(b43_pcmcia_remove), .remove = __devexit_p(b43_pcmcia_remove),

View file

@ -12,7 +12,6 @@
#include <linux/wireless.h> #include <linux/wireless.h>
#include <net/iw_handler.h> #include <net/iw_handler.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -437,7 +436,6 @@ static int hostap_cs_probe(struct pcmcia_device *p_dev)
int ret; int ret;
PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info); PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info);
p_dev->conf.IntType = INT_MEMORY_AND_IO;
ret = prism2_config(p_dev); ret = prism2_config(p_dev);
if (ret) { if (ret) {
@ -468,74 +466,11 @@ static void prism2_detach(struct pcmcia_device *link)
} }
/* run after a CARD_INSERTION event is received to configure the PCMCIA static int prism2_config_check(struct pcmcia_device *p_dev, void *priv_data)
* socket and make the device available to the system */
static int prism2_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
if (cfg->index == 0) if (p_dev->config_index == 0)
return -ENODEV; return -EINVAL;
PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X "
"(default 0x%02X)\n", cfg->index, dflt->index);
/* Does this card need audio output? */
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
p_dev->conf.Status = CCSR_AUDIO_ENA;
}
/* Use power settings for Vcc and Vpp if present */
/* Note that the CIS values need to be rescaled */
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
10000 && !ignore_cis_vcc) {
PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping"
" this entry\n");
return -ENODEV;
}
} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] /
10000 && !ignore_cis_vcc) {
PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch "
"- skipping this entry\n");
return -ENODEV;
}
}
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
/* Do we need to allocate an interrupt? */
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
"dflt->io.nwin=%d\n",
cfg->io.nwin, dflt->io.nwin);
p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
p_dev->resource[1]->flags = p_dev->resource[0]->flags;
p_dev->resource[1]->start = io->win[1].base;
p_dev->resource[1]->end = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
return pcmcia_request_io(p_dev); return pcmcia_request_io(p_dev);
} }
@ -557,6 +492,10 @@ static int prism2_config(struct pcmcia_device *link)
} }
/* Look for an appropriate configuration table entry in the CIS */ /* Look for an appropriate configuration table entry in the CIS */
link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO |
CONF_AUTO_CHECK_VCC | CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
if (ignore_cis_vcc)
link->config_flags &= ~CONF_AUTO_CHECK_VCC;
ret = pcmcia_loop_config(link, prism2_config_check, NULL); ret = pcmcia_loop_config(link, prism2_config_check, NULL);
if (ret) { if (ret) {
if (!ignore_cis_vcc) if (!ignore_cis_vcc)
@ -588,12 +527,7 @@ static int prism2_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed_unlock; goto failed_unlock;
/* ret = pcmcia_enable_device(link);
* This actually configures the PCMCIA socket -- setting up
* the I/O windows and the interrupt mapping, and putting the
* card and host interface into "Memory and IO" mode.
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed_unlock; goto failed_unlock;
@ -602,20 +536,6 @@ static int prism2_config(struct pcmcia_device *link)
spin_unlock_irqrestore(&local->irq_init_lock, flags); spin_unlock_irqrestore(&local->irq_init_lock, flags);
/* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x: ",
dev_info, link->conf.ConfigIndex);
if (link->conf.Vpp)
printk(", Vpp %d.%d", link->conf.Vpp / 10,
link->conf.Vpp % 10);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq);
if (link->resource[0])
printk(" & %pR", link->resource[0]);
if (link->resource[1])
printk(" & %pR", link->resource[1]);
printk("\n");
local->shutdown = 0; local->shutdown = 0;
sandisk_enable_wireless(dev); sandisk_enable_wireless(dev);
@ -627,7 +547,7 @@ static int prism2_config(struct pcmcia_device *link)
return ret; return ret;
failed_unlock: failed_unlock:
spin_unlock_irqrestore(&local->irq_init_lock, flags); spin_unlock_irqrestore(&local->irq_init_lock, flags);
failed: failed:
kfree(hw_priv); kfree(hw_priv);
prism2_release((u_long)link); prism2_release((u_long)link);
@ -779,9 +699,7 @@ MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
static struct pcmcia_driver hostap_driver = { static struct pcmcia_driver hostap_driver = {
.drv = { .name = "hostap_cs",
.name = "hostap_cs",
},
.probe = hostap_cs_probe, .probe = hostap_cs_probe,
.remove = prism2_detach, .remove = prism2_detach,
.owner = THIS_MODULE, .owner = THIS_MODULE,

View file

@ -28,7 +28,6 @@
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -761,15 +760,6 @@ static int if_cs_host_to_card(struct lbs_private *priv,
} }
/********************************************************************/
/* Card Services */
/********************************************************************/
/*
* After a card is removed, if_cs_release() will unregister the
* device, and release the PCMCIA configuration. If the device is
* still open, this will be postponed until it is closed.
*/
static void if_cs_release(struct pcmcia_device *p_dev) static void if_cs_release(struct pcmcia_device *p_dev)
{ {
struct if_cs_card *card = p_dev->priv; struct if_cs_card *card = p_dev->priv;
@ -785,31 +775,12 @@ static void if_cs_release(struct pcmcia_device *p_dev)
} }
/* static int if_cs_ioprobe(struct pcmcia_device *p_dev, void *priv_data)
* This creates an "instance" of the driver, allocating local data
* structures for one device. The device is registered with Card
* Services.
*
* The dev_link structure is initialized, but we don't actually
* configure the card at this point -- we wait until we receive a card
* insertion event.
*/
static int if_cs_ioprobe(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; 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;
/* Do we need to allocate an interrupt? */ if (p_dev->resource[1]->end) {
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
if (cfg->io.nwin != 1) {
lbs_pr_err("wrong CIS (check number of IO windows)\n"); lbs_pr_err("wrong CIS (check number of IO windows)\n");
return -ENODEV; return -ENODEV;
} }
@ -835,15 +806,13 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
card->p_dev = p_dev; card->p_dev = p_dev;
p_dev->priv = card; p_dev->priv = card;
p_dev->conf.Attributes = 0; p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) { if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) {
lbs_pr_err("error in pcmcia_loop_config\n"); lbs_pr_err("error in pcmcia_loop_config\n");
goto out1; goto out1;
} }
/* /*
* Allocate an interrupt line. Note that this does not assign * Allocate an interrupt line. Note that this does not assign
* a handler to the interrupt, unless the 'Handler' member of * a handler to the interrupt, unless the 'Handler' member of
@ -861,14 +830,9 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
goto out1; goto out1;
} }
/* ret = pcmcia_enable_device(p_dev);
* This actually configures the PCMCIA socket -- setting up
* the I/O windows and the interrupt mapping, and putting the
* card and host interface into "Memory and IO" mode.
*/
ret = pcmcia_request_configuration(p_dev, &p_dev->conf);
if (ret) { if (ret) {
lbs_pr_err("error in pcmcia_request_configuration\n"); lbs_pr_err("error in pcmcia_enable_device\n");
goto out2; goto out2;
} }
@ -962,12 +926,6 @@ out:
} }
/*
* This deletes a driver "instance". The device is de-registered with
* Card Services. If it has been released, all local data structures
* are freed. Otherwise, the structures will be freed when the device
* is released.
*/
static void if_cs_detach(struct pcmcia_device *p_dev) static void if_cs_detach(struct pcmcia_device *p_dev)
{ {
struct if_cs_card *card = p_dev->priv; struct if_cs_card *card = p_dev->priv;
@ -1000,9 +958,7 @@ MODULE_DEVICE_TABLE(pcmcia, if_cs_ids);
static struct pcmcia_driver lbs_driver = { static struct pcmcia_driver lbs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = DRV_NAME,
.name = DRV_NAME,
},
.probe = if_cs_probe, .probe = if_cs_probe,
.remove = if_cs_detach, .remove = if_cs_detach,
.id_table = if_cs_ids, .id_table = if_cs_ids,

View file

@ -17,7 +17,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -93,14 +92,6 @@ orinoco_cs_hard_reset(struct orinoco_private *priv)
/* PCMCIA stuff */ /* PCMCIA stuff */
/********************************************************************/ /********************************************************************/
/*
* This creates an "instance" of the driver, allocating local data
* structures for one device. The device is registered with Card
* Services.
*
* The dev_link structure is initialized, but we don't actually
* configure the card at this point -- we wait until we receive a card
* insertion event. */
static int static int
orinoco_cs_probe(struct pcmcia_device *link) orinoco_cs_probe(struct pcmcia_device *link)
{ {
@ -117,23 +108,9 @@ orinoco_cs_probe(struct pcmcia_device *link)
card->p_dev = link; card->p_dev = link;
link->priv = priv; link->priv = priv;
/* General socket configuration defaults can go here. In this
* client, we assume very little, and rely on the CIS for
* almost everything. In most clients, many details (i.e.,
* number, sizes, and attributes of IO windows) are fixed by
* the nature of the device, and can be hard-wired here. */
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
return orinoco_cs_config(link); return orinoco_cs_config(link);
} /* orinoco_cs_attach */ } /* orinoco_cs_attach */
/*
* This deletes a driver "instance". The device is de-registered with
* Card Services. If it has been released, all local data structures
* are freed. Otherwise, the structures will be freed when the device
* is released.
*/
static void orinoco_cs_detach(struct pcmcia_device *link) static void orinoco_cs_detach(struct pcmcia_device *link)
{ {
struct orinoco_private *priv = link->priv; struct orinoco_private *priv = link->priv;
@ -145,76 +122,12 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
free_orinocodev(priv); free_orinocodev(priv);
} /* orinoco_cs_detach */ } /* orinoco_cs_detach */
/* static int orinoco_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
* orinoco_cs_config() is scheduled to run after a CARD_INSERTION
* event is received, to configure the PCMCIA socket, and to make the
* device available to the system.
*/
static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
if (cfg->index == 0) if (p_dev->config_index == 0)
goto next_entry; return -EINVAL;
/* Use power settings for Vcc and Vpp if present */ return pcmcia_request_io(p_dev);
/* Note that the CIS values need to be rescaled */
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
DEBUG(2, "%s: Vcc mismatch (vcc = %d, CIS = %d)\n",
__func__, vcc,
cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
if (!ignore_cis_vcc)
goto next_entry;
}
} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) {
DEBUG(2, "%s: Vcc mismatch (vcc = %d, CIS = %d)\n",
__func__, vcc,
dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
if (!ignore_cis_vcc)
goto next_entry;
}
}
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
p_dev->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
p_dev->conf.Vpp =
dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
/* Do we need to allocate an interrupt? */
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
p_dev->resource[1]->flags = p_dev->resource[0]->flags;
p_dev->resource[1]->start = io->win[1].base;
p_dev->resource[1]->end = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(p_dev) != 0)
goto next_entry;
}
return 0;
next_entry:
pcmcia_disable_device(p_dev);
return -ENODEV;
}; };
static int static int
@ -225,20 +138,10 @@ orinoco_cs_config(struct pcmcia_device *link)
int ret; int ret;
void __iomem *mem; void __iomem *mem;
/* link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC |
* In this loop, we scan the CIS for configuration table CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
* entries, each of which describes a valid card if (ignore_cis_vcc)
* configuration, including voltage, IO window, memory window, link->config_flags &= ~CONF_AUTO_CHECK_VCC;
* and interrupt settings.
*
* We make no assumptions about the card to be configured: we
* use just the information available in the CIS. In an ideal
* world, this would work for any PCMCIA card, but it requires
* a complete and accurate CIS. In practice, a driver usually
* "knows" most of these things without consulting the CIS,
* and most client drivers will only use the CIS to fill in
* implementation-defined details.
*/
ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL); ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
if (ret) { if (ret) {
if (!ignore_cis_vcc) if (!ignore_cis_vcc)
@ -262,12 +165,7 @@ orinoco_cs_config(struct pcmcia_device *link)
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
/* ret = pcmcia_enable_device(link);
* This actually configures the PCMCIA socket -- setting up
* the I/O windows and the interrupt mapping, and putting the
* card and host interface into "Memory and IO" mode.
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
@ -291,11 +189,6 @@ orinoco_cs_config(struct pcmcia_device *link)
return -ENODEV; return -ENODEV;
} /* orinoco_cs_config */ } /* orinoco_cs_config */
/*
* After a card is removed, orinoco_cs_release() will unregister the
* device, and release the PCMCIA configuration. If the device is
* still open, this will be postponed until it is closed.
*/
static void static void
orinoco_cs_release(struct pcmcia_device *link) orinoco_cs_release(struct pcmcia_device *link)
{ {
@ -344,12 +237,6 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
/* Module initialization */ /* Module initialization */
/********************************************************************/ /********************************************************************/
/* Can't be declared "const" or the whole __initdata section will
* become const */
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
" (David Gibson <hermes@gibson.dropbear.id.au>, "
"Pavel Roskin <proski@gnu.org>, et al)";
static struct pcmcia_device_id orinoco_cs_ids[] = { static struct pcmcia_device_id orinoco_cs_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */ PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */
PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */ PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */
@ -441,9 +328,7 @@ MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids);
static struct pcmcia_driver orinoco_driver = { static struct pcmcia_driver orinoco_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = DRIVER_NAME,
.name = DRIVER_NAME,
},
.probe = orinoco_cs_probe, .probe = orinoco_cs_probe,
.remove = orinoco_cs_detach, .remove = orinoco_cs_detach,
.id_table = orinoco_cs_ids, .id_table = orinoco_cs_ids,
@ -454,8 +339,6 @@ static struct pcmcia_driver orinoco_driver = {
static int __init static int __init
init_orinoco_cs(void) init_orinoco_cs(void)
{ {
printk(KERN_DEBUG "%s\n", version);
return pcmcia_register_driver(&orinoco_driver); return pcmcia_register_driver(&orinoco_driver);
} }

View file

@ -25,7 +25,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -154,14 +153,6 @@ spectrum_cs_stop_firmware(struct orinoco_private *priv, int idle)
/* PCMCIA stuff */ /* PCMCIA stuff */
/********************************************************************/ /********************************************************************/
/*
* This creates an "instance" of the driver, allocating local data
* structures for one device. The device is registered with Card
* Services.
*
* The dev_link structure is initialized, but we don't actually
* configure the card at this point -- we wait until we receive a card
* insertion event. */
static int static int
spectrum_cs_probe(struct pcmcia_device *link) spectrum_cs_probe(struct pcmcia_device *link)
{ {
@ -179,23 +170,9 @@ spectrum_cs_probe(struct pcmcia_device *link)
card->p_dev = link; card->p_dev = link;
link->priv = priv; link->priv = priv;
/* General socket configuration defaults can go here. In this
* client, we assume very little, and rely on the CIS for
* almost everything. In most clients, many details (i.e.,
* number, sizes, and attributes of IO windows) are fixed by
* the nature of the device, and can be hard-wired here. */
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
return spectrum_cs_config(link); return spectrum_cs_config(link);
} /* spectrum_cs_attach */ } /* spectrum_cs_attach */
/*
* This deletes a driver "instance". The device is de-registered with
* Card Services. If it has been released, all local data structures
* are freed. Otherwise, the structures will be freed when the device
* is released.
*/
static void spectrum_cs_detach(struct pcmcia_device *link) static void spectrum_cs_detach(struct pcmcia_device *link)
{ {
struct orinoco_private *priv = link->priv; struct orinoco_private *priv = link->priv;
@ -207,76 +184,13 @@ static void spectrum_cs_detach(struct pcmcia_device *link)
free_orinocodev(priv); free_orinocodev(priv);
} /* spectrum_cs_detach */ } /* spectrum_cs_detach */
/*
* spectrum_cs_config() is scheduled to run after a CARD_INSERTION
* event is received, to configure the PCMCIA socket, and to make the
* device available to the system.
*/
static int spectrum_cs_config_check(struct pcmcia_device *p_dev, static int spectrum_cs_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data) void *priv_data)
{ {
if (cfg->index == 0) if (p_dev->config_index == 0)
goto next_entry; return -EINVAL;
/* Use power settings for Vcc and Vpp if present */ return pcmcia_request_io(p_dev);
/* Note that the CIS values need to be rescaled */
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
DEBUG(2, "%s: Vcc mismatch (vcc = %d, CIS = %d)\n",
__func__, vcc,
cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
if (!ignore_cis_vcc)
goto next_entry;
}
} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) {
DEBUG(2, "%s: Vcc mismatch (vcc = %d, CIS = %d)\n",
__func__, vcc,
dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
if (!ignore_cis_vcc)
goto next_entry;
}
}
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
p_dev->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
p_dev->conf.Vpp =
dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
/* Do we need to allocate an interrupt? */
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
p_dev->resource[1]->flags = p_dev->resource[0]->flags;
p_dev->resource[1]->start = io->win[1].base;
p_dev->resource[1]->end = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(p_dev) != 0)
goto next_entry;
}
return 0;
next_entry:
pcmcia_disable_device(p_dev);
return -ENODEV;
}; };
static int static int
@ -287,20 +201,10 @@ spectrum_cs_config(struct pcmcia_device *link)
int ret; int ret;
void __iomem *mem; void __iomem *mem;
/* link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC |
* In this loop, we scan the CIS for configuration table CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
* entries, each of which describes a valid card if (ignore_cis_vcc)
* configuration, including voltage, IO window, memory window, link->config_flags &= ~CONF_AUTO_CHECK_VCC;
* and interrupt settings.
*
* We make no assumptions about the card to be configured: we
* use just the information available in the CIS. In an ideal
* world, this would work for any PCMCIA card, but it requires
* a complete and accurate CIS. In practice, a driver usually
* "knows" most of these things without consulting the CIS,
* and most client drivers will only use the CIS to fill in
* implementation-defined details.
*/
ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL); ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
if (ret) { if (ret) {
if (!ignore_cis_vcc) if (!ignore_cis_vcc)
@ -325,12 +229,7 @@ spectrum_cs_config(struct pcmcia_device *link)
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
hw->eeprom_pda = true; hw->eeprom_pda = true;
/* ret = pcmcia_enable_device(link);
* This actually configures the PCMCIA socket -- setting up
* the I/O windows and the interrupt mapping, and putting the
* card and host interface into "Memory and IO" mode.
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
@ -358,11 +257,6 @@ spectrum_cs_config(struct pcmcia_device *link)
return -ENODEV; return -ENODEV;
} /* spectrum_cs_config */ } /* spectrum_cs_config */
/*
* After a card is removed, spectrum_cs_release() will unregister the
* device, and release the PCMCIA configuration. If the device is
* still open, this will be postponed until it is closed.
*/
static void static void
spectrum_cs_release(struct pcmcia_device *link) spectrum_cs_release(struct pcmcia_device *link)
{ {
@ -407,12 +301,6 @@ spectrum_cs_resume(struct pcmcia_device *link)
/* Module initialization */ /* Module initialization */
/********************************************************************/ /********************************************************************/
/* Can't be declared "const" or the whole __initdata section will
* become const */
static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
" (Pavel Roskin <proski@gnu.org>,"
" David Gibson <hermes@gibson.dropbear.id.au>, et al)";
static struct pcmcia_device_id spectrum_cs_ids[] = { static struct pcmcia_device_id spectrum_cs_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4137 */ PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4137 */
PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */ PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
@ -423,9 +311,7 @@ MODULE_DEVICE_TABLE(pcmcia, spectrum_cs_ids);
static struct pcmcia_driver orinoco_driver = { static struct pcmcia_driver orinoco_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = DRIVER_NAME,
.name = DRIVER_NAME,
},
.probe = spectrum_cs_probe, .probe = spectrum_cs_probe,
.remove = spectrum_cs_detach, .remove = spectrum_cs_detach,
.suspend = spectrum_cs_suspend, .suspend = spectrum_cs_suspend,
@ -436,8 +322,6 @@ static struct pcmcia_driver orinoco_driver = {
static int __init static int __init
init_spectrum_cs(void) init_spectrum_cs(void)
{ {
printk(KERN_DEBUG "%s\n", version);
return pcmcia_register_driver(&orinoco_driver); return pcmcia_register_driver(&orinoco_driver);
} }

View file

@ -46,7 +46,6 @@
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/ieee80211.h> #include <linux/ieee80211.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -169,13 +168,6 @@ static int bc;
*/ */
static char *phy_addr = NULL; static char *phy_addr = NULL;
/* A struct pcmcia_device structure has fields for most things that are needed
to keep track of a socket, but there will usually be some device
specific information that also needs to be kept track of. The
'priv' pointer in a struct pcmcia_device structure can be used to point to
a device-specific private data structure, like this.
*/
static unsigned int ray_mem_speed = 500; static unsigned int ray_mem_speed = 500;
/* WARNING: THIS DRIVER IS NOT CAPABLE OF HANDLING MULTIPLE DEVICES! */ /* WARNING: THIS DRIVER IS NOT CAPABLE OF HANDLING MULTIPLE DEVICES! */
@ -290,14 +282,6 @@ static const struct net_device_ops ray_netdev_ops = {
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
}; };
/*=============================================================================
ray_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
=============================================================================*/
static int ray_probe(struct pcmcia_device *p_dev) static int ray_probe(struct pcmcia_device *p_dev)
{ {
ray_dev_t *local; ray_dev_t *local;
@ -318,9 +302,8 @@ static int ray_probe(struct pcmcia_device *p_dev)
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
/* General socket configuration */ /* General socket configuration */
p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->config_flags |= CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO; p_dev->config_index = 1;
p_dev->conf.ConfigIndex = 1;
p_dev->priv = dev; p_dev->priv = dev;
@ -353,12 +336,6 @@ fail_alloc_dev:
return -ENOMEM; return -ENOMEM;
} /* ray_attach */ } /* ray_attach */
/*=============================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
=============================================================================*/
static void ray_detach(struct pcmcia_device *link) static void ray_detach(struct pcmcia_device *link)
{ {
struct net_device *dev; struct net_device *dev;
@ -381,17 +358,11 @@ static void ray_detach(struct pcmcia_device *link)
dev_dbg(&link->dev, "ray_cs ray_detach ending\n"); dev_dbg(&link->dev, "ray_cs ray_detach ending\n");
} /* ray_detach */ } /* ray_detach */
/*=============================================================================
ray_config() is run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
ethernet device available to the system.
=============================================================================*/
#define MAX_TUPLE_SIZE 128 #define MAX_TUPLE_SIZE 128
static int ray_config(struct pcmcia_device *link) static int ray_config(struct pcmcia_device *link)
{ {
int ret = 0; int ret = 0;
int i; int i;
win_req_t req;
struct net_device *dev = (struct net_device *)link->priv; struct net_device *dev = (struct net_device *)link->priv;
ray_dev_t *local = netdev_priv(dev); ray_dev_t *local = netdev_priv(dev);
@ -412,54 +383,50 @@ static int ray_config(struct pcmcia_device *link)
goto failed; goto failed;
dev->irq = link->irq; dev->irq = link->irq;
/* This actually configures the PCMCIA socket -- setting up ret = pcmcia_enable_device(link);
the I/O windows and the interrupt mapping.
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
/*** Set up 32k window for shared memory (transmit and control) ************/ /*** Set up 32k window for shared memory (transmit and control) ************/
req.Attributes = link->resource[2]->flags |= WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT; link->resource[2]->start = 0;
req.Base = 0; link->resource[2]->end = 0x8000;
req.Size = 0x8000; ret = pcmcia_request_window(link, link->resource[2], ray_mem_speed);
req.AccessSpeed = ray_mem_speed;
ret = pcmcia_request_window(link, &req, &link->win);
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_map_mem_page(link, link->win, 0); ret = pcmcia_map_mem_page(link, link->resource[2], 0);
if (ret) if (ret)
goto failed; goto failed;
local->sram = ioremap(req.Base, req.Size); local->sram = ioremap(link->resource[2]->start,
resource_size(link->resource[2]));
/*** Set up 16k window for shared memory (receive buffer) ***************/ /*** Set up 16k window for shared memory (receive buffer) ***************/
req.Attributes = link->resource[3]->flags |=
WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT; WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
req.Base = 0; link->resource[3]->start = 0;
req.Size = 0x4000; link->resource[3]->end = 0x4000;
req.AccessSpeed = ray_mem_speed; ret = pcmcia_request_window(link, link->resource[3], ray_mem_speed);
ret = pcmcia_request_window(link, &req, &local->rmem_handle);
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_map_mem_page(link, local->rmem_handle, 0x8000); ret = pcmcia_map_mem_page(link, link->resource[3], 0x8000);
if (ret) if (ret)
goto failed; goto failed;
local->rmem = ioremap(req.Base, req.Size); local->rmem = ioremap(link->resource[3]->start,
resource_size(link->resource[3]));
/*** Set up window for attribute memory ***********************************/ /*** Set up window for attribute memory ***********************************/
req.Attributes = link->resource[4]->flags |=
WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT; WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT;
req.Base = 0; link->resource[4]->start = 0;
req.Size = 0x1000; link->resource[4]->end = 0x1000;
req.AccessSpeed = ray_mem_speed; ret = pcmcia_request_window(link, link->resource[4], ray_mem_speed);
ret = pcmcia_request_window(link, &req, &local->amem_handle);
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_map_mem_page(link, local->amem_handle, 0); ret = pcmcia_map_mem_page(link, link->resource[4], 0);
if (ret) if (ret)
goto failed; goto failed;
local->amem = ioremap(req.Base, req.Size); local->amem = ioremap(link->resource[4]->start,
resource_size(link->resource[4]));
dev_dbg(&link->dev, "ray_config sram=%p\n", local->sram); dev_dbg(&link->dev, "ray_config sram=%p\n", local->sram);
dev_dbg(&link->dev, "ray_config rmem=%p\n", local->rmem); dev_dbg(&link->dev, "ray_config rmem=%p\n", local->rmem);
@ -775,11 +742,7 @@ static void join_net(u_long data)
local->card_status = CARD_DOING_ACQ; local->card_status = CARD_DOING_ACQ;
} }
/*============================================================================
After a card is removed, ray_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
=============================================================================*/
static void ray_release(struct pcmcia_device *link) static void ray_release(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
@ -2847,9 +2810,7 @@ MODULE_DEVICE_TABLE(pcmcia, ray_ids);
static struct pcmcia_driver ray_driver = { static struct pcmcia_driver ray_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "ray_cs",
.name = "ray_cs",
},
.probe = ray_probe, .probe = ray_probe,
.remove = ray_detach, .remove = ray_detach,
.id_table = ray_ids, .id_table = ray_ids,

View file

@ -25,8 +25,6 @@ struct beacon_rx {
typedef struct ray_dev_t { typedef struct ray_dev_t {
int card_status; int card_status;
int authentication_state; int authentication_state;
window_handle_t amem_handle; /* handle to window for attribute memory */
window_handle_t rmem_handle; /* handle to window for rx buffer on card */
void __iomem *sram; /* pointer to beginning of shared RAM */ void __iomem *sram; /* pointer to beginning of shared RAM */
void __iomem *amem; /* pointer to attribute mem window */ void __iomem *amem; /* pointer to attribute mem window */
void __iomem *rmem; /* pointer to receive buffer window */ void __iomem *rmem; /* pointer to receive buffer window */

View file

@ -48,7 +48,6 @@
#include <net/iw_handler.h> #include <net/iw_handler.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -78,13 +77,6 @@
#define WL3501_RESUME 0 #define WL3501_RESUME 0
#define WL3501_SUSPEND 1 #define WL3501_SUSPEND 1
/*
* The event() function is this driver's Card Services event handler. It will
* be called by Card Services when an appropriate card status event is
* received. The config() and release() entry points are used to configure or
* release a socket, in response to card insertion and ejection events. They
* are invoked from the wl24 event handler.
*/
static int wl3501_config(struct pcmcia_device *link); static int wl3501_config(struct pcmcia_device *link);
static void wl3501_release(struct pcmcia_device *link); static void wl3501_release(struct pcmcia_device *link);
@ -1869,15 +1861,6 @@ static const struct net_device_ops wl3501_netdev_ops = {
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
}; };
/**
* wl3501_attach - creates an "instance" of the driver
*
* Creates an "instance" of the driver, allocating local data structures for
* one device. The device is registered with Card Services.
*
* The dev_link structure is initialized, but we don't actually configure the
* card at this point -- we wait until we receive a card insertion event.
*/
static int wl3501_probe(struct pcmcia_device *p_dev) static int wl3501_probe(struct pcmcia_device *p_dev)
{ {
struct net_device *dev; struct net_device *dev;
@ -1888,9 +1871,8 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
p_dev->resource[0]->flags = IO_DATA_PATH_WIDTH_8; p_dev->resource[0]->flags = IO_DATA_PATH_WIDTH_8;
/* General socket configuration */ /* General socket configuration */
p_dev->conf.Attributes = CONF_ENABLE_IRQ; p_dev->config_flags = CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO; p_dev->config_index = 1;
p_dev->conf.ConfigIndex = 1;
dev = alloc_etherdev(sizeof(struct wl3501_card)); dev = alloc_etherdev(sizeof(struct wl3501_card));
if (!dev) if (!dev)
@ -1914,14 +1896,6 @@ out_link:
return -ENOMEM; return -ENOMEM;
} }
/**
* wl3501_config - configure the PCMCIA socket and make eth device available
* @link - FILL_IN
*
* wl3501_config() is scheduled to run after a CARD_INSERTION event is
* received, to configure the PCMCIA socket, and to make the ethernet device
* available to the system.
*/
static int wl3501_config(struct pcmcia_device *link) static int wl3501_config(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
@ -1952,10 +1926,7 @@ static int wl3501_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
/* This actually configures the PCMCIA socket -- setting up the I/O ret = pcmcia_enable_device(link);
* windows and the interrupt mapping. */
ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
@ -2010,14 +1981,6 @@ failed:
return -ENODEV; return -ENODEV;
} }
/**
* wl3501_release - unregister the net, release PCMCIA configuration
* @arg - link
*
* After a card is removed, wl3501_release() will unregister the net device,
* and release the PCMCIA configuration. If the device is still open, this
* will be postponed until it is closed.
*/
static void wl3501_release(struct pcmcia_device *link) static void wl3501_release(struct pcmcia_device *link)
{ {
pcmcia_disable_device(link); pcmcia_disable_device(link);
@ -2056,9 +2019,7 @@ MODULE_DEVICE_TABLE(pcmcia, wl3501_ids);
static struct pcmcia_driver wl3501_driver = { static struct pcmcia_driver wl3501_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "wl3501_cs",
.name = "wl3501_cs",
},
.probe = wl3501_probe, .probe = wl3501_probe,
.remove = wl3501_detach, .remove = wl3501_detach,
.id_table = wl3501_ids, .id_table = wl3501_ids,

View file

@ -48,7 +48,6 @@
#include <linux/parport.h> #include <linux/parport.h>
#include <linux/parport_pc.h> #include <linux/parport_pc.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
@ -81,14 +80,6 @@ static void parport_detach(struct pcmcia_device *p_dev);
static int parport_config(struct pcmcia_device *link); static int parport_config(struct pcmcia_device *link);
static void parport_cs_release(struct pcmcia_device *); static void parport_cs_release(struct pcmcia_device *);
/*======================================================================
parport_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
======================================================================*/
static int parport_probe(struct pcmcia_device *link) static int parport_probe(struct pcmcia_device *link)
{ {
parport_info_t *info; parport_info_t *info;
@ -101,23 +92,11 @@ static int parport_probe(struct pcmcia_device *link)
link->priv = info; link->priv = info;
info->p_dev = link; info->p_dev = link;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
return parport_config(link); return parport_config(link);
} /* parport_attach */ } /* parport_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void parport_detach(struct pcmcia_device *link) static void parport_detach(struct pcmcia_device *link)
{ {
dev_dbg(&link->dev, "parport_detach\n"); dev_dbg(&link->dev, "parport_detach\n");
@ -127,36 +106,14 @@ static void parport_detach(struct pcmcia_device *link)
kfree(link->priv); kfree(link->priv);
} /* parport_detach */ } /* parport_detach */
/*====================================================================== static int parport_config_check(struct pcmcia_device *p_dev, void *priv_data)
parport_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
parport device available to the system.
======================================================================*/
static int parport_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
if (epp_mode) p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->conf.ConfigIndex |= FORCE_EPP_MODE;
p_dev->resource[0]->start = io->win[0].base; return pcmcia_request_io(p_dev);
p_dev->resource[0]->end = io->win[0].len;
if (io->nwin == 2) {
p_dev->resource[1]->start = io->win[1].base;
p_dev->resource[1]->end = io->win[1].len;
}
if (pcmcia_request_io(p_dev) != 0)
return -ENODEV;
return 0;
}
return -ENODEV;
} }
static int parport_config(struct pcmcia_device *link) static int parport_config(struct pcmcia_device *link)
@ -167,13 +124,16 @@ static int parport_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "parport_config\n"); dev_dbg(&link->dev, "parport_config\n");
if (epp_mode)
link->config_index |= FORCE_EPP_MODE;
ret = pcmcia_loop_config(link, parport_config_check, NULL); ret = pcmcia_loop_config(link, parport_config_check, NULL);
if (ret) if (ret)
goto failed; goto failed;
if (!link->irq) if (!link->irq)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
@ -202,14 +162,6 @@ failed:
return -ENODEV; return -ENODEV;
} /* parport_config */ } /* parport_config */
/*======================================================================
After a card is removed, parport_cs_release() will unregister the
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void parport_cs_release(struct pcmcia_device *link) static void parport_cs_release(struct pcmcia_device *link)
{ {
parport_info_t *info = link->priv; parport_info_t *info = link->priv;
@ -236,9 +188,7 @@ MODULE_DEVICE_TABLE(pcmcia, parport_ids);
static struct pcmcia_driver parport_cs_driver = { static struct pcmcia_driver parport_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "parport_cs",
.name = "parport_cs",
},
.probe = parport_probe, .probe = parport_probe,
.remove = parport_detach, .remove = parport_detach,
.id_table = parport_ids, .id_table = parport_ids,

View file

@ -441,14 +441,12 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops,
out_err: out_err:
flush_scheduled_work();
ops->hw_shutdown(skt); ops->hw_shutdown(skt);
while (i-- > 0) { while (i-- > 0) {
skt = PCMCIA_SOCKET(i); skt = PCMCIA_SOCKET(i);
del_timer_sync(&skt->poll_timer); del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket); pcmcia_unregister_socket(&skt->socket);
flush_scheduled_work();
if (i == 0) { if (i == 0) {
iounmap(skt->virt_io + (u32)mips_io_port_base); iounmap(skt->virt_io + (u32)mips_io_port_base);
skt->virt_io = NULL; skt->virt_io = NULL;
@ -480,7 +478,6 @@ int au1x00_drv_pcmcia_remove(struct platform_device *dev)
del_timer_sync(&skt->poll_timer); del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket); pcmcia_unregister_socket(&skt->socket);
flush_scheduled_work();
skt->ops->hw_shutdown(skt); skt->ops->hw_shutdown(skt);
au1x00_pcmcia_config_skt(skt, &dead_socket); au1x00_pcmcia_config_skt(skt, &dead_socket);
iounmap(skt->virt_io + (u32)mips_io_port_base); iounmap(skt->virt_io + (u32)mips_io_port_base);

View file

@ -23,7 +23,6 @@
/* include the world */ /* include the world */
#include <pcmcia/cs.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include "cs_internal.h" #include "cs_internal.h"

View file

@ -31,7 +31,6 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/types.h> #include <linux/types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>

View file

@ -28,7 +28,6 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include "cs_internal.h" #include "cs_internal.h"

View file

@ -33,7 +33,6 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -845,7 +844,7 @@ static int pcmcia_socket_dev_resume_noirq(struct device *dev)
return __pcmcia_pm_op(dev, socket_early_resume); return __pcmcia_pm_op(dev, socket_early_resume);
} }
static int pcmcia_socket_dev_resume(struct device *dev) static int __used pcmcia_socket_dev_resume(struct device *dev)
{ {
return __pcmcia_pm_op(dev, socket_late_resume); return __pcmcia_pm_op(dev, socket_late_resume);
} }

View file

@ -33,18 +33,9 @@
typedef struct config_t { typedef struct config_t {
struct kref ref; struct kref ref;
unsigned int state; unsigned int state;
unsigned int Attributes;
unsigned int IntType;
unsigned int ConfigBase;
unsigned char Status, Pin, Copy, Option, ExtStatus;
unsigned int CardValues;
struct resource io[MAX_IO_WIN]; /* io ports */ struct resource io[MAX_IO_WIN]; /* io ports */
struct resource mem[MAX_WIN]; /* mem areas */ struct resource mem[MAX_WIN]; /* mem areas */
struct {
u_int Attributes;
} irq;
} config_t; } config_t;

View file

@ -26,7 +26,6 @@
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
@ -52,7 +51,7 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
if (!p_drv->probe || !p_drv->remove) if (!p_drv->probe || !p_drv->remove)
printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback " printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback "
"function\n", p_drv->drv.name); "function\n", p_drv->name);
while (did && did->match_flags) { while (did && did->match_flags) {
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
@ -65,7 +64,7 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
printk(KERN_DEBUG "pcmcia: %s: invalid hash for " printk(KERN_DEBUG "pcmcia: %s: invalid hash for "
"product string \"%s\": is 0x%x, should " "product string \"%s\": is 0x%x, should "
"be 0x%x\n", p_drv->drv.name, did->prod_id[i], "be 0x%x\n", p_drv->name, did->prod_id[i],
did->prod_id_hash[i], hash); did->prod_id_hash[i], hash);
printk(KERN_DEBUG "pcmcia: see " printk(KERN_DEBUG "pcmcia: see "
"Documentation/pcmcia/devicetable.txt for " "Documentation/pcmcia/devicetable.txt for "
@ -180,10 +179,11 @@ int pcmcia_register_driver(struct pcmcia_driver *driver)
/* initialize common fields */ /* initialize common fields */
driver->drv.bus = &pcmcia_bus_type; driver->drv.bus = &pcmcia_bus_type;
driver->drv.owner = driver->owner; driver->drv.owner = driver->owner;
driver->drv.name = driver->name;
mutex_init(&driver->dynids.lock); mutex_init(&driver->dynids.lock);
INIT_LIST_HEAD(&driver->dynids.list); INIT_LIST_HEAD(&driver->dynids.list);
pr_debug("registering driver %s\n", driver->drv.name); pr_debug("registering driver %s\n", driver->name);
error = driver_register(&driver->drv); error = driver_register(&driver->drv);
if (error < 0) if (error < 0)
@ -203,7 +203,7 @@ EXPORT_SYMBOL(pcmcia_register_driver);
*/ */
void pcmcia_unregister_driver(struct pcmcia_driver *driver) void pcmcia_unregister_driver(struct pcmcia_driver *driver)
{ {
pr_debug("unregistering driver %s\n", driver->drv.name); pr_debug("unregistering driver %s\n", driver->name);
driver_unregister(&driver->drv); driver_unregister(&driver->drv);
pcmcia_free_dynids(driver); pcmcia_free_dynids(driver);
} }
@ -264,7 +264,7 @@ static int pcmcia_device_probe(struct device *dev)
p_drv = to_pcmcia_drv(dev->driver); p_drv = to_pcmcia_drv(dev->driver);
s = p_dev->socket; s = p_dev->socket;
dev_dbg(dev, "trying to bind to %s\n", p_drv->drv.name); dev_dbg(dev, "trying to bind to %s\n", p_drv->name);
if ((!p_drv->probe) || (!p_dev->function_config) || if ((!p_drv->probe) || (!p_dev->function_config) ||
(!try_module_get(p_drv->owner))) { (!try_module_get(p_drv->owner))) {
@ -276,21 +276,28 @@ static int pcmcia_device_probe(struct device *dev)
ret = pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_CONFIG, ret = pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_CONFIG,
&cis_config); &cis_config);
if (!ret) { if (!ret) {
p_dev->conf.ConfigBase = cis_config.base; p_dev->config_base = cis_config.base;
p_dev->conf.Present = cis_config.rmask[0]; p_dev->config_regs = cis_config.rmask[0];
dev_dbg(dev, "base %x, regs %x", p_dev->config_base,
p_dev->config_regs);
} else { } else {
dev_printk(KERN_INFO, dev, dev_printk(KERN_INFO, dev,
"pcmcia: could not parse base and rmask0 of CIS\n"); "pcmcia: could not parse base and rmask0 of CIS\n");
p_dev->conf.ConfigBase = 0; p_dev->config_base = 0;
p_dev->conf.Present = 0; p_dev->config_regs = 0;
} }
ret = p_drv->probe(p_dev); ret = p_drv->probe(p_dev);
if (ret) { if (ret) {
dev_dbg(dev, "binding to %s failed with %d\n", dev_dbg(dev, "binding to %s failed with %d\n",
p_drv->drv.name, ret); p_drv->name, ret);
goto put_module; goto put_module;
} }
dev_dbg(dev, "%s bound: Vpp %d.%d, idx %x, IRQ %d", p_drv->name,
p_dev->vpp/10, p_dev->vpp%10, p_dev->config_index, p_dev->irq);
dev_dbg(dev, "resources: ioport %pR %pR iomem %pR %pR %pR",
p_dev->resource[0], p_dev->resource[1], p_dev->resource[2],
p_dev->resource[3], p_dev->resource[4]);
mutex_lock(&s->ops_mutex); mutex_lock(&s->ops_mutex);
if ((s->pcmcia_pfc) && if ((s->pcmcia_pfc) &&
@ -374,13 +381,13 @@ static int pcmcia_device_remove(struct device *dev)
if (p_dev->_irq || p_dev->_io || p_dev->_locked) if (p_dev->_irq || p_dev->_io || p_dev->_locked)
dev_printk(KERN_INFO, dev, dev_printk(KERN_INFO, dev,
"pcmcia: driver %s did not release config properly\n", "pcmcia: driver %s did not release config properly\n",
p_drv->drv.name); p_drv->name);
for (i = 0; i < MAX_WIN; i++) for (i = 0; i < MAX_WIN; i++)
if (p_dev->_win & CLIENT_WIN_REQ(i)) if (p_dev->_win & CLIENT_WIN_REQ(i))
dev_printk(KERN_INFO, dev, dev_printk(KERN_INFO, dev,
"pcmcia: driver %s did not release window properly\n", "pcmcia: driver %s did not release window properly\n",
p_drv->drv.name); p_drv->name);
/* references from pcmcia_probe_device */ /* references from pcmcia_probe_device */
pcmcia_put_dev(p_dev); pcmcia_put_dev(p_dev);
@ -1136,7 +1143,7 @@ static int pcmcia_dev_suspend(struct device *dev, pm_message_t state)
dev_printk(KERN_ERR, dev, dev_printk(KERN_ERR, dev,
"pcmcia: device %s (driver %s) did " "pcmcia: device %s (driver %s) did "
"not want to go to sleep (%d)\n", "not want to go to sleep (%d)\n",
p_dev->devname, p_drv->drv.name, ret); p_dev->devname, p_drv->name, ret);
mutex_lock(&p_dev->socket->ops_mutex); mutex_lock(&p_dev->socket->ops_mutex);
p_dev->suspended = 0; p_dev->suspended = 0;
mutex_unlock(&p_dev->socket->ops_mutex); mutex_unlock(&p_dev->socket->ops_mutex);
@ -1178,7 +1185,7 @@ static int pcmcia_dev_resume(struct device *dev)
if (p_dev->device_no == p_dev->func) { if (p_dev->device_no == p_dev->func) {
dev_dbg(dev, "requesting configuration\n"); dev_dbg(dev, "requesting configuration\n");
ret = pcmcia_request_configuration(p_dev, &p_dev->conf); ret = pcmcia_enable_device(p_dev);
if (ret) if (ret)
goto out; goto out;
} }

View file

@ -16,7 +16,6 @@
#include <linux/device.h> #include <linux/device.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>

View file

@ -51,7 +51,6 @@
#include <asm/system.h> #include <asm/system.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <linux/isapnp.h> #include <linux/isapnp.h>

View file

@ -27,7 +27,6 @@
#include <asm/system.h> #include <asm/system.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#undef MAX_IO_WIN /* FIXME */ #undef MAX_IO_WIN /* FIXME */
#define MAX_IO_WIN 1 #define MAX_IO_WIN 1

View file

@ -28,7 +28,6 @@
#include <asm/addrspace.h> #include <asm/addrspace.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h>
/* XXX: should be moved into asm/irq.h */ /* XXX: should be moved into asm/irq.h */
#define PCC0_IRQ 24 #define PCC0_IRQ 24

View file

@ -59,7 +59,6 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/fs_pd.h> #include <asm/fs_pd.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args) #define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args)

View file

@ -153,14 +153,14 @@ static int o2micro_override(struct yenta_socket *socket)
if (use_speedup) { if (use_speedup) {
dev_info(&socket->dev->dev, dev_info(&socket->dev->dev,
"O2: enabling read prefetch/write burst\n"); "O2: enabling read prefetch/write burst. If you experience problems or performance issues, use the yenta_socket parameter 'o2_speedup=off'\n");
config_writeb(socket, O2_RESERVED1, config_writeb(socket, O2_RESERVED1,
a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST); a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
config_writeb(socket, O2_RESERVED2, config_writeb(socket, O2_RESERVED2,
b | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST); b | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
} else { } else {
dev_info(&socket->dev->dev, dev_info(&socket->dev->dev,
"O2: disabling read prefetch/write burst\n"); "O2: disabling read prefetch/write burst. If you experience problems or performance issues, use the yenta_socket parameter 'o2_speedup=on'\n");
config_writeb(socket, O2_RESERVED1, config_writeb(socket, O2_RESERVED1,
a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST)); a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
config_writeb(socket, O2_RESERVED2, config_writeb(socket, O2_RESERVED2,

View file

@ -6,7 +6,7 @@
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
* *
* Copyright (C) 1999 David A. Hinds * Copyright (C) 1999 David A. Hinds
* Copyright (C) 2004-2009 Dominik Brodowski * Copyright (C) 2004-2010 Dominik Brodowski
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
@ -22,7 +22,6 @@
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include "cs_internal.h" #include "cs_internal.h"
@ -126,14 +125,24 @@ next_entry:
return ret; return ret;
} }
/**
* pcmcia_io_cfg_data_width() - convert cfgtable to data path width parameter
*/
static int pcmcia_io_cfg_data_width(unsigned int flags)
{
if (!(flags & CISTPL_IO_8BIT))
return IO_DATA_PATH_WIDTH_16;
if (!(flags & CISTPL_IO_16BIT))
return IO_DATA_PATH_WIDTH_8;
return IO_DATA_PATH_WIDTH_AUTO;
}
struct pcmcia_cfg_mem { struct pcmcia_cfg_mem {
struct pcmcia_device *p_dev; struct pcmcia_device *p_dev;
int (*conf_check) (struct pcmcia_device *p_dev, void *priv_data);
void *priv_data; void *priv_data;
int (*conf_check) (struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data);
cisparse_t parse; cisparse_t parse;
cistpl_cftable_entry_t dflt; cistpl_cftable_entry_t dflt;
}; };
@ -147,25 +156,102 @@ struct pcmcia_cfg_mem {
*/ */
static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv) static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
{ {
cistpl_cftable_entry_t *cfg = &parse->cftable_entry;
struct pcmcia_cfg_mem *cfg_mem = priv; struct pcmcia_cfg_mem *cfg_mem = priv;
struct pcmcia_device *p_dev = cfg_mem->p_dev;
cistpl_cftable_entry_t *cfg = &parse->cftable_entry;
cistpl_cftable_entry_t *dflt = &cfg_mem->dflt;
unsigned int flags = p_dev->config_flags;
unsigned int vcc = p_dev->socket->socket.Vcc;
dev_dbg(&p_dev->dev, "testing configuration %x, autoconf %x\n",
cfg->index, flags);
/* default values */ /* default values */
cfg_mem->p_dev->conf.ConfigIndex = cfg->index; cfg_mem->p_dev->config_index = cfg->index;
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
cfg_mem->dflt = *cfg; cfg_mem->dflt = *cfg;
return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt, /* check for matching Vcc? */
cfg_mem->p_dev->socket->socket.Vcc, if (flags & CONF_AUTO_CHECK_VCC) {
cfg_mem->priv_data); if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
return -ENODEV;
} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
return -ENODEV;
}
}
/* set Vpp? */
if (flags & CONF_AUTO_SET_VPP) {
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
p_dev->vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
p_dev->vpp =
dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
}
/* enable audio? */
if ((flags & CONF_AUTO_AUDIO) && (cfg->flags & CISTPL_CFTABLE_AUDIO))
p_dev->config_flags |= CONF_ENABLE_SPKR;
/* IO window settings? */
if (flags & CONF_AUTO_SET_IO) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
int i = 0;
p_dev->resource[0]->start = p_dev->resource[0]->end = 0;
p_dev->resource[1]->start = p_dev->resource[1]->end = 0;
if (io->nwin == 0)
return -ENODEV;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
if (io->nwin > 1) {
/* For multifunction cards, by convention, we
* configure the network function with window 0,
* and serial with window 1 */
i = (io->win[1].len > io->win[0].len);
p_dev->resource[1]->flags = p_dev->resource[0]->flags;
p_dev->resource[1]->start = io->win[1-i].base;
p_dev->resource[1]->end = io->win[1-i].len;
}
p_dev->resource[0]->start = io->win[i].base;
p_dev->resource[0]->end = io->win[i].len;
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
}
/* MEM window settings? */
if (flags & CONF_AUTO_SET_IOMEM) {
/* so far, we only set one memory window */
cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
p_dev->resource[2]->start = p_dev->resource[2]->end = 0;
if (mem->nwin == 0)
return -ENODEV;
p_dev->resource[2]->start = mem->win[0].host_addr;
p_dev->resource[2]->end = mem->win[0].len;
if (p_dev->resource[2]->end < 0x1000)
p_dev->resource[2]->end = 0x1000;
p_dev->card_addr = mem->win[0].card_addr;
}
dev_dbg(&p_dev->dev,
"checking configuration %x: %pr %pr %pr (%d lines)\n",
p_dev->config_index, p_dev->resource[0], p_dev->resource[1],
p_dev->resource[2], p_dev->io_lines);
return cfg_mem->conf_check(p_dev, cfg_mem->priv_data);
} }
/** /**
* pcmcia_loop_config() - loop over configuration options * pcmcia_loop_config() - loop over configuration options
* @p_dev: the struct pcmcia_device which we need to loop for. * @p_dev: the struct pcmcia_device which we need to loop for.
* @conf_check: function to call for each configuration option. * @conf_check: function to call for each configuration option.
* It gets passed the struct pcmcia_device, the CIS data * It gets passed the struct pcmcia_device and private data
* describing the configuration option, and private data
* being passed to pcmcia_loop_config() * being passed to pcmcia_loop_config()
* @priv_data: private data to be passed to the conf_check function. * @priv_data: private data to be passed to the conf_check function.
* *
@ -175,9 +261,6 @@ static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
*/ */
int pcmcia_loop_config(struct pcmcia_device *p_dev, int pcmcia_loop_config(struct pcmcia_device *p_dev,
int (*conf_check) (struct pcmcia_device *p_dev, int (*conf_check) (struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data), void *priv_data),
void *priv_data) void *priv_data)
{ {

View file

@ -6,7 +6,7 @@
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
* *
* Copyright (C) 1999 David A. Hinds * Copyright (C) 1999 David A. Hinds
* Copyright (C) 2004-2005 Dominik Brodowski * Copyright (C) 2004-2010 Dominik Brodowski
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
@ -26,7 +26,6 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -56,6 +55,12 @@ struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
} }
/**
* release_io_space() - release IO ports allocated with alloc_io_space()
* @s: pcmcia socket
* @res: resource to release
*
*/
static void release_io_space(struct pcmcia_socket *s, struct resource *res) static void release_io_space(struct pcmcia_socket *s, struct resource *res)
{ {
resource_size_t num = resource_size(res); resource_size_t num = resource_size(res);
@ -81,9 +86,14 @@ static void release_io_space(struct pcmcia_socket *s, struct resource *res)
} }
} }
} }
} /* release_io_space */ }
/** alloc_io_space
/**
* alloc_io_space() - allocate IO ports for use by a PCMCIA device
* @s: pcmcia socket
* @res: resource to allocate (begin: begin, end: size)
* @lines: number of IO lines decoded by the PCMCIA card
* *
* Special stuff for managing IO windows, because they are scarce * Special stuff for managing IO windows, because they are scarce
*/ */
@ -135,7 +145,7 @@ static int alloc_io_space(struct pcmcia_socket *s, struct resource *res,
} }
dev_dbg(&s->dev, "alloc_io_space request result %d: %pR\n", ret, res); dev_dbg(&s->dev, "alloc_io_space request result %d: %pR\n", ret, res);
return ret; return ret;
} /* alloc_io_space */ }
/** /**
@ -168,14 +178,14 @@ static int pcmcia_access_config(struct pcmcia_device *p_dev,
return -EACCES; return -EACCES;
} }
addr = (c->ConfigBase + where) >> 1; addr = (p_dev->config_base + where) >> 1;
ret = accessf(s, 1, addr, 1, val); ret = accessf(s, 1, addr, 1, val);
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
return ret; return ret;
} /* pcmcia_access_config */ }
/** /**
@ -204,11 +214,20 @@ int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val)
EXPORT_SYMBOL(pcmcia_write_config_byte); EXPORT_SYMBOL(pcmcia_write_config_byte);
int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh, /**
* pcmcia_map_mem_page() - modify iomem window to point to a different offset
* @p_dev: pcmcia device
* @res: iomem resource already enabled by pcmcia_request_window()
* @offset: card_offset to map
*
* pcmcia_map_mem_page() modifies what can be read and written by accessing
* an iomem range previously enabled by pcmcia_request_window(), by setting
* the card_offset value to @offset.
*/
int pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res,
unsigned int offset) unsigned int offset)
{ {
struct pcmcia_socket *s = p_dev->socket; struct pcmcia_socket *s = p_dev->socket;
struct resource *res = wh;
unsigned int w; unsigned int w;
int ret; int ret;
@ -223,98 +242,111 @@ int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh,
dev_warn(&p_dev->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 */ }
EXPORT_SYMBOL(pcmcia_map_mem_page); EXPORT_SYMBOL(pcmcia_map_mem_page);
/** pcmcia_modify_configuration /**
* pcmcia_fixup_iowidth() - reduce io width to 8bit
* @p_dev: pcmcia device
* *
* Modify a locked socket configuration * pcmcia_fixup_iowidth() allows a PCMCIA device driver to reduce the
* IO width to 8bit after having called pcmcia_enable_device()
* previously.
*/ */
int pcmcia_modify_configuration(struct pcmcia_device *p_dev, int pcmcia_fixup_iowidth(struct pcmcia_device *p_dev)
modconf_t *mod)
{ {
struct pcmcia_socket *s; struct pcmcia_socket *s = p_dev->socket;
config_t *c; pccard_io_map io_off = { 0, 0, 0, 0, 1 };
int ret; pccard_io_map io_on;
int i, ret = 0;
s = p_dev->socket;
mutex_lock(&s->ops_mutex); mutex_lock(&s->ops_mutex);
c = p_dev->function_config;
if (!(s->state & SOCKET_PRESENT)) { dev_dbg(&p_dev->dev, "fixup iowidth to 8bit\n");
dev_dbg(&p_dev->dev, "No card present\n");
ret = -ENODEV; if (!(s->state & SOCKET_PRESENT) ||
goto unlock; !(p_dev->function_config->state & CONFIG_LOCKED)) {
} dev_dbg(&p_dev->dev, "No card? Config not locked?\n");
if (!(c->state & CONFIG_LOCKED)) {
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)) { io_on.speed = io_speed;
dev_dbg(&p_dev->dev, for (i = 0; i < MAX_IO_WIN; i++) {
"changing Vcc or IRQ is not allowed at this time\n"); if (!s->io[i].res)
ret = -EINVAL; continue;
goto unlock; io_off.map = i;
io_on.map = i;
io_on.flags = MAP_ACTIVE | IO_DATA_PATH_WIDTH_8;
io_on.start = s->io[i].res->start;
io_on.stop = s->io[i].res->end;
s->ops->set_io_map(s, &io_off);
mdelay(40);
s->ops->set_io_map(s, &io_on);
} }
/* We only allow changing Vpp1 and Vpp2 to the same value */
if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
if (mod->Vpp1 != mod->Vpp2) {
dev_dbg(&p_dev->dev,
"Vpp1 and Vpp2 must be the same\n");
ret = -EINVAL;
goto unlock;
}
s->socket.Vpp = mod->Vpp1;
if (s->ops->set_socket(s, &s->socket)) {
dev_printk(KERN_WARNING, &p_dev->dev,
"Unable to set VPP\n");
ret = -EIO;
goto unlock;
}
} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
dev_dbg(&p_dev->dev,
"changing Vcc is not allowed at this time\n");
ret = -EINVAL;
goto unlock;
}
if (mod->Attributes & CONF_IO_CHANGE_WIDTH) {
pccard_io_map io_off = { 0, 0, 0, 0, 1 };
pccard_io_map io_on;
int i;
io_on.speed = io_speed;
for (i = 0; i < MAX_IO_WIN; i++) {
if (!s->io[i].res)
continue;
io_off.map = i;
io_on.map = i;
io_on.flags = MAP_ACTIVE | IO_DATA_PATH_WIDTH_8;
io_on.start = s->io[i].res->start;
io_on.stop = s->io[i].res->end;
s->ops->set_io_map(s, &io_off);
mdelay(40);
s->ops->set_io_map(s, &io_on);
}
}
ret = 0;
unlock: unlock:
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
return ret; return ret;
} /* modify_configuration */ }
EXPORT_SYMBOL(pcmcia_modify_configuration); EXPORT_SYMBOL(pcmcia_fixup_iowidth);
/**
* pcmcia_fixup_vpp() - set Vpp to a new voltage level
* @p_dev: pcmcia device
* @new_vpp: new Vpp voltage
*
* pcmcia_fixup_vpp() allows a PCMCIA device driver to set Vpp to
* a new voltage level between calls to pcmcia_enable_device()
* and pcmcia_disable_device().
*/
int pcmcia_fixup_vpp(struct pcmcia_device *p_dev, unsigned char new_vpp)
{
struct pcmcia_socket *s = p_dev->socket;
int ret = 0;
mutex_lock(&s->ops_mutex);
dev_dbg(&p_dev->dev, "fixup Vpp to %d\n", new_vpp);
if (!(s->state & SOCKET_PRESENT) ||
!(p_dev->function_config->state & CONFIG_LOCKED)) {
dev_dbg(&p_dev->dev, "No card? Config not locked?\n");
ret = -EACCES;
goto unlock;
}
s->socket.Vpp = new_vpp;
if (s->ops->set_socket(s, &s->socket)) {
dev_warn(&p_dev->dev, "Unable to set VPP\n");
ret = -EIO;
goto unlock;
}
p_dev->vpp = new_vpp;
unlock:
mutex_unlock(&s->ops_mutex);
return ret;
}
EXPORT_SYMBOL(pcmcia_fixup_vpp);
/**
* pcmcia_release_configuration() - physically disable a PCMCIA device
* @p_dev: pcmcia device
*
* pcmcia_release_configuration() is the 1:1 counterpart to
* pcmcia_enable_device(): If a PCMCIA device is no longer used by any
* driver, the Vpp voltage is set to 0, IRQs will no longer be generated,
* and I/O ranges will be disabled. As pcmcia_release_io() and
* pcmcia_release_window() still need to be called, device drivers are
* expected to call pcmcia_disable_device() instead.
*/
int pcmcia_release_configuration(struct pcmcia_device *p_dev) int pcmcia_release_configuration(struct pcmcia_device *p_dev)
{ {
pccard_io_map io = { 0, 0, 0, 0, 1 }; pccard_io_map io = { 0, 0, 0, 0, 1 };
@ -327,7 +359,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
if (p_dev->_locked) { if (p_dev->_locked) {
p_dev->_locked = 0; p_dev->_locked = 0;
if (--(s->lock_count) == 0) { if (--(s->lock_count) == 0) {
s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */ s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */
s->socket.Vpp = 0; s->socket.Vpp = 0;
s->socket.io_irq = 0; s->socket.io_irq = 0;
s->ops->set_socket(s, &s->socket); s->ops->set_socket(s, &s->socket);
@ -349,16 +381,18 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
return 0; return 0;
} /* pcmcia_release_configuration */ }
/** pcmcia_release_io /**
* pcmcia_release_io() - release I/O allocated by a PCMCIA device
* @p_dev: pcmcia device
* *
* Release_io() releases the I/O ranges allocated by a client. This * pcmcia_release_io() releases the I/O ranges allocated by a PCMCIA
* may be invoked some time after a card ejection has already dumped * device. This may be invoked some time after a card ejection has
* the actual socket configuration, so if the client is "stale", we * already dumped the actual socket configuration, so if the client is
* don't bother checking the port ranges against the current socket * "stale", we don't bother checking the port ranges against the
* values. * current socket values.
*/ */
static int pcmcia_release_io(struct pcmcia_device *p_dev) static int pcmcia_release_io(struct pcmcia_device *p_dev)
{ {
@ -387,6 +421,14 @@ out:
} /* pcmcia_release_io */ } /* pcmcia_release_io */
/**
* pcmcia_release_window() - release reserved iomem for PCMCIA devices
* @p_dev: pcmcia device
* @res: iomem resource to release
*
* pcmcia_release_window() releases &struct resource *res which was
* previously reserved by calling pcmcia_request_window().
*/
int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res) int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res)
{ {
struct pcmcia_socket *s = p_dev->socket; struct pcmcia_socket *s = p_dev->socket;
@ -420,6 +462,8 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res)
kfree(win->res); kfree(win->res);
win->res = NULL; win->res = NULL;
} }
res->start = res->end = 0;
res->flags = IORESOURCE_MEM;
p_dev->_win &= ~CLIENT_WIN_REQ(w); p_dev->_win &= ~CLIENT_WIN_REQ(w);
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
@ -428,23 +472,30 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res)
EXPORT_SYMBOL(pcmcia_release_window); EXPORT_SYMBOL(pcmcia_release_window);
int pcmcia_request_configuration(struct pcmcia_device *p_dev, /**
config_req_t *req) * pcmcia_enable_device() - set up and activate a PCMCIA device
* @p_dev: the associated PCMCIA device
*
* pcmcia_enable_device() physically enables a PCMCIA device. It parses
* the flags passed to in @flags and stored in @p_dev->flags and sets up
* the Vpp voltage, enables the speaker line, I/O ports and store proper
* values to configuration registers.
*/
int pcmcia_enable_device(struct pcmcia_device *p_dev)
{ {
int i; int i;
u_int base; unsigned int base;
struct pcmcia_socket *s = p_dev->socket; struct pcmcia_socket *s = p_dev->socket;
config_t *c; config_t *c;
pccard_io_map iomap; pccard_io_map iomap;
unsigned char status = 0;
unsigned char ext_status = 0;
unsigned char option = 0;
unsigned int flags = p_dev->config_flags;
if (!(s->state & SOCKET_PRESENT)) if (!(s->state & SOCKET_PRESENT))
return -ENODEV; return -ENODEV;
if (req->IntType & INT_CARDBUS) {
dev_dbg(&p_dev->dev, "IntType may not be INT_CARDBUS\n");
return -EINVAL;
}
mutex_lock(&s->ops_mutex); mutex_lock(&s->ops_mutex);
c = p_dev->function_config; c = p_dev->function_config;
if (c->state & CONFIG_LOCKED) { if (c->state & CONFIG_LOCKED) {
@ -454,7 +505,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
} }
/* Do power control. We don't allow changes in Vcc. */ /* Do power control. We don't allow changes in Vcc. */
s->socket.Vpp = req->Vpp; s->socket.Vpp = p_dev->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, &p_dev->dev, dev_printk(KERN_WARNING, &p_dev->dev,
@ -463,64 +514,72 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
} }
/* Pick memory or I/O card, DMA mode, interrupt */ /* Pick memory or I/O card, DMA mode, interrupt */
c->IntType = req->IntType; if (p_dev->_io)
c->Attributes = req->Attributes;
if (req->IntType & INT_MEMORY_AND_IO)
s->socket.flags |= SS_IOCARD; s->socket.flags |= SS_IOCARD;
if (req->IntType & INT_ZOOMED_VIDEO) if (flags & CONF_ENABLE_SPKR) {
s->socket.flags |= SS_ZVCARD | SS_IOCARD;
if (req->Attributes & CONF_ENABLE_DMA)
s->socket.flags |= SS_DMA_MODE;
if (req->Attributes & CONF_ENABLE_SPKR)
s->socket.flags |= SS_SPKR_ENA; s->socket.flags |= SS_SPKR_ENA;
if (req->Attributes & CONF_ENABLE_IRQ) status = CCSR_AUDIO_ENA;
if (!(p_dev->config_regs & PRESENT_STATUS))
dev_warn(&p_dev->dev, "speaker requested, but "
"PRESENT_STATUS not set!\n");
}
if (flags & CONF_ENABLE_IRQ)
s->socket.io_irq = s->pcmcia_irq; s->socket.io_irq = s->pcmcia_irq;
else else
s->socket.io_irq = 0; s->socket.io_irq = 0;
if (flags & CONF_ENABLE_ESR) {
p_dev->config_regs |= PRESENT_EXT_STATUS;
ext_status = ESR_REQ_ATTN_ENA;
}
s->ops->set_socket(s, &s->socket); s->ops->set_socket(s, &s->socket);
s->lock_count++; s->lock_count++;
dev_dbg(&p_dev->dev,
"enable_device: V %d, flags %x, base %x, regs %x, idx %x\n",
p_dev->vpp, flags, p_dev->config_base, p_dev->config_regs,
p_dev->config_index);
/* Set up CIS configuration registers */ /* Set up CIS configuration registers */
base = c->ConfigBase = req->ConfigBase; base = p_dev->config_base;
c->CardValues = req->Present; if (p_dev->config_regs & PRESENT_COPY) {
if (req->Present & PRESENT_COPY) { u16 tmp = 0;
c->Copy = req->Copy; dev_dbg(&p_dev->dev, "clearing CISREG_SCR\n");
pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy); pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &tmp);
} }
if (req->Present & PRESENT_OPTION) { if (p_dev->config_regs & PRESENT_PIN_REPLACE) {
u16 tmp = 0;
dev_dbg(&p_dev->dev, "clearing CISREG_PRR\n");
pcmcia_write_cis_mem(s, 1, (base + CISREG_PRR)>>1, 1, &tmp);
}
if (p_dev->config_regs & PRESENT_OPTION) {
if (s->functions == 1) { if (s->functions == 1) {
c->Option = req->ConfigIndex & COR_CONFIG_MASK; option = p_dev->config_index & COR_CONFIG_MASK;
} else { } else {
c->Option = req->ConfigIndex & COR_MFC_CONFIG_MASK; option = p_dev->config_index & COR_MFC_CONFIG_MASK;
c->Option |= COR_FUNC_ENA|COR_IREQ_ENA; option |= COR_FUNC_ENA|COR_IREQ_ENA;
if (req->Present & PRESENT_IOBASE_0) if (p_dev->config_regs & PRESENT_IOBASE_0)
c->Option |= COR_ADDR_DECODE; option |= COR_ADDR_DECODE;
} }
if ((req->Attributes & CONF_ENABLE_IRQ) && if ((flags & CONF_ENABLE_IRQ) &&
!(req->Attributes & CONF_ENABLE_PULSE_IRQ)) !(flags & CONF_ENABLE_PULSE_IRQ))
c->Option |= COR_LEVEL_REQ; option |= COR_LEVEL_REQ;
pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option); pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &option);
mdelay(40); mdelay(40);
} }
if (req->Present & PRESENT_STATUS) { if (p_dev->config_regs & PRESENT_STATUS)
c->Status = req->Status; pcmcia_write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &status);
pcmcia_write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &c->Status);
} if (p_dev->config_regs & PRESENT_EXT_STATUS)
if (req->Present & PRESENT_PIN_REPLACE) { pcmcia_write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1,
c->Pin = req->Pin; &ext_status);
pcmcia_write_cis_mem(s, 1, (base + CISREG_PRR)>>1, 1, &c->Pin);
} if (p_dev->config_regs & PRESENT_IOBASE_0) {
if (req->Present & PRESENT_EXT_STATUS) {
c->ExtStatus = req->ExtStatus;
pcmcia_write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1, &c->ExtStatus);
}
if (req->Present & PRESENT_IOBASE_0) {
u8 b = c->io[0].start & 0xff; u8 b = c->io[0].start & 0xff;
pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b); pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b);
b = (c->io[0].start >> 8) & 0xff; b = (c->io[0].start >> 8) & 0xff;
pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b); pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b);
} }
if (req->Present & PRESENT_IOSIZE) { if (p_dev->config_regs & PRESENT_IOSIZE) {
u8 b = resource_size(&c->io[0]) + resource_size(&c->io[1]) - 1; u8 b = resource_size(&c->io[0]) + resource_size(&c->io[1]) - 1;
pcmcia_write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b); pcmcia_write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b);
} }
@ -551,14 +610,15 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
p_dev->_locked = 1; p_dev->_locked = 1;
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
return 0; return 0;
} /* pcmcia_request_configuration */ } /* pcmcia_enable_device */
EXPORT_SYMBOL(pcmcia_request_configuration); EXPORT_SYMBOL(pcmcia_enable_device);
/** /**
* pcmcia_request_io() - attempt to reserve port ranges for PCMCIA devices * pcmcia_request_io() - attempt to reserve port ranges for PCMCIA devices
* @p_dev: the associated PCMCIA device
* *
* pcmcia_request_io() attepts to reserve the IO port ranges specified in * pcmcia_request_io() attempts to reserve the IO port ranges specified in
* &struct pcmcia_device @p_dev->resource[0] and @p_dev->resource[1]. The * &struct pcmcia_device @p_dev->resource[0] and @p_dev->resource[1]. The
* "start" value is the requested start of the IO port resource; "end" * "start" value is the requested start of the IO port resource; "end"
* reflects the number of ports requested. The number of IO lines requested * reflects the number of ports requested. The number of IO lines requested
@ -622,11 +682,13 @@ EXPORT_SYMBOL(pcmcia_request_io);
/** /**
* pcmcia_request_irq() - attempt to request a IRQ for a PCMCIA device * pcmcia_request_irq() - attempt to request a IRQ for a PCMCIA device
* @p_dev: the associated PCMCIA device
* @handler: IRQ handler to register
* *
* pcmcia_request_irq() is a wrapper around request_irq which will allow * pcmcia_request_irq() is a wrapper around request_irq() which allows
* the PCMCIA core to clean up the registration in pcmcia_disable_device(). * the PCMCIA core to clean up the registration in pcmcia_disable_device().
* Drivers are free to use request_irq() directly, but then they need to * Drivers are free to use request_irq() directly, but then they need to
* call free_irq themselfves, too. Also, only IRQF_SHARED capable IRQ * call free_irq() themselfves, too. Also, only %IRQF_SHARED capable IRQ
* handlers are allowed. * handlers are allowed.
*/ */
int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev, int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev,
@ -649,12 +711,14 @@ EXPORT_SYMBOL(pcmcia_request_irq);
/** /**
* pcmcia_request_exclusive_irq() - attempt to request an exclusive IRQ first * pcmcia_request_exclusive_irq() - attempt to request an exclusive IRQ first
* @p_dev: the associated PCMCIA device
* @handler: IRQ handler to register
* *
* pcmcia_request_exclusive_irq() is a wrapper around request_irq which * pcmcia_request_exclusive_irq() is a wrapper around request_irq() which
* attempts first to request an exclusive IRQ. If it fails, it also accepts * attempts first to request an exclusive IRQ. If it fails, it also accepts
* a shared IRQ, but prints out a warning. PCMCIA drivers should allow for * a shared IRQ, but prints out a warning. PCMCIA drivers should allow for
* IRQ sharing and either use request_irq directly (then they need to call * IRQ sharing and either use request_irq directly (then they need to call
* free_irq themselves, too), or the pcmcia_request_irq() function. * free_irq() themselves, too), or the pcmcia_request_irq() function.
*/ */
int __must_check int __must_check
__pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, __pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev,
@ -795,38 +859,47 @@ int pcmcia_setup_irq(struct pcmcia_device *p_dev)
} }
/** pcmcia_request_window /**
* pcmcia_request_window() - attempt to reserve iomem for PCMCIA devices
* @p_dev: the associated PCMCIA device
* @res: &struct resource pointing to p_dev->resource[2..5]
* @speed: access speed
* *
* Request_window() establishes a mapping between card memory space * pcmcia_request_window() attepts to reserve an iomem ranges specified in
* and system memory space. * &struct resource @res pointing to one of the entries in
* &struct pcmcia_device @p_dev->resource[2..5]. The "start" value is the
* requested start of the IO mem resource; "end" reflects the size
* requested.
*/ */
int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_handle_t *wh) int pcmcia_request_window(struct pcmcia_device *p_dev, struct resource *res,
unsigned int speed)
{ {
struct pcmcia_socket *s = p_dev->socket; struct pcmcia_socket *s = p_dev->socket;
pccard_mem_map *win; pccard_mem_map *win;
u_long align; u_long align;
struct resource *res;
int w; int w;
dev_dbg(&p_dev->dev, "request_window %pR %d\n", res, speed);
if (!(s->state & SOCKET_PRESENT)) { if (!(s->state & SOCKET_PRESENT)) {
dev_dbg(&p_dev->dev, "No card present\n"); dev_dbg(&p_dev->dev, "No card present\n");
return -ENODEV; return -ENODEV;
} }
/* Window size defaults to smallest available */ /* Window size defaults to smallest available */
if (req->Size == 0) if (res->end == 0)
req->Size = s->map_size; res->end = s->map_size;
align = (s->features & SS_CAP_MEM_ALIGN) ? req->Size : s->map_size; align = (s->features & SS_CAP_MEM_ALIGN) ? res->end : s->map_size;
if (req->Size & (s->map_size-1)) { if (res->end & (s->map_size-1)) {
dev_dbg(&p_dev->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 ((res->start && (s->features & SS_CAP_STATIC_MAP)) ||
(req->Base & (align-1))) { (res->start & (align-1))) {
dev_dbg(&p_dev->dev, "invalid base address\n"); dev_dbg(&p_dev->dev, "invalid base address\n");
return -EINVAL; return -EINVAL;
} }
if (req->Base) if (res->start)
align = 0; align = 0;
/* Allocate system memory window */ /* Allocate system memory window */
@ -843,7 +916,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
win = &s->win[w]; win = &s->win[w];
if (!(s->features & SS_CAP_STATIC_MAP)) { if (!(s->features & SS_CAP_STATIC_MAP)) {
win->res = pcmcia_find_mem_region(req->Base, req->Size, align, win->res = pcmcia_find_mem_region(res->start, res->end, align,
0, s); 0, s);
if (!win->res) { if (!win->res) {
dev_dbg(&p_dev->dev, "allocating mem region failed\n"); dev_dbg(&p_dev->dev, "allocating mem region failed\n");
@ -855,8 +928,8 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
/* Configure the socket controller */ /* Configure the socket controller */
win->map = w+1; win->map = w+1;
win->flags = req->Attributes; win->flags = res->flags & WIN_FLAGS_MAP;
win->speed = req->AccessSpeed; win->speed = speed;
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) {
@ -868,17 +941,14 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
/* Return window handle */ /* Return window handle */
if (s->features & SS_CAP_STATIC_MAP) if (s->features & SS_CAP_STATIC_MAP)
req->Base = win->static_start; res->start = win->static_start;
else else
req->Base = win->res->start; res->start = win->res->start;
/* convert to new-style resources */ /* convert to new-style resources */
res = p_dev->resource[w + MAX_IO_WIN]; res->end += res->start - 1;
res->start = req->Base; res->flags &= ~WIN_FLAGS_REQ;
res->end = req->Base + req->Size - 1; res->flags |= (win->map << 2) | IORESOURCE_MEM;
res->flags &= ~IORESOURCE_BITS;
res->flags |= (req->Attributes & WIN_FLAGS_MAP) | (win->map << 2);
res->flags |= IORESOURCE_MEM;
res->parent = win->res; res->parent = win->res;
if (win->res) if (win->res)
request_resource(&iomem_resource, res); request_resource(&iomem_resource, res);
@ -886,15 +956,30 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha
dev_dbg(&p_dev->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;
return 0; return 0;
} /* pcmcia_request_window */ } /* pcmcia_request_window */
EXPORT_SYMBOL(pcmcia_request_window); EXPORT_SYMBOL(pcmcia_request_window);
/**
* pcmcia_disable_device() - disable and clean up a PCMCIA device
* @p_dev: the associated PCMCIA device
*
* pcmcia_disable_device() is the driver-callable counterpart to
* pcmcia_enable_device(): If a PCMCIA device is no longer used,
* drivers are expected to clean up and disable the device by calling
* this function. Any I/O ranges (iomem and ioports) will be released,
* the Vpp voltage will be set to 0, and IRQs will no longer be
* generated -- at least if there is no other card function (of
* multifunction devices) being used.
*/
void pcmcia_disable_device(struct pcmcia_device *p_dev) void pcmcia_disable_device(struct pcmcia_device *p_dev)
{ {
int i; int i;
dev_dbg(&p_dev->dev, "disabling device\n");
for (i = 0; i < MAX_WIN; i++) { for (i = 0; i < MAX_WIN; i++) {
struct resource *res = p_dev->resource[MAX_IO_WIN + i]; struct resource *res = p_dev->resource[MAX_IO_WIN + i];
if (res->flags & WIN_FLAGS_REQ) if (res->flags & WIN_FLAGS_REQ)

View file

@ -18,7 +18,6 @@
#include <linux/io.h> #include <linux/io.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <asm/system.h> #include <asm/system.h>

View file

@ -17,7 +17,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include "cs_internal.h" #include "cs_internal.h"

View file

@ -17,7 +17,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include "cs_internal.h" #include "cs_internal.h"

View file

@ -29,7 +29,6 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include "cs_internal.h" #include "cs_internal.h"

View file

@ -35,7 +35,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <asm/hardware/scoop.h> #include <asm/hardware/scoop.h>

View file

@ -627,8 +627,6 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
pcmcia_unregister_socket(&skt->socket); pcmcia_unregister_socket(&skt->socket);
flush_scheduled_work();
skt->ops->hw_shutdown(skt); skt->ops->hw_shutdown(skt);
soc_common_pcmcia_config_skt(skt, &dead_socket); soc_common_pcmcia_config_skt(skt, &dead_socket);
@ -720,8 +718,6 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
pcmcia_unregister_socket(&skt->socket); pcmcia_unregister_socket(&skt->socket);
out_err_7: out_err_7:
flush_scheduled_work();
skt->ops->hw_shutdown(skt); skt->ops->hw_shutdown(skt);
out_err_6: out_err_6:
list_del(&skt->node); list_del(&skt->node);

View file

@ -11,7 +11,6 @@
/* include the world */ /* include the world */
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>

View file

@ -27,7 +27,6 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>

View file

@ -49,7 +49,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include "tcic.h" #include "tcic.h"

View file

@ -461,7 +461,7 @@ static int __devinit vrc4173_cardu_probe(struct pci_dev *dev,
{ {
vrc4173_socket_t *socket; vrc4173_socket_t *socket;
unsigned long start, len, flags; unsigned long start, len, flags;
int slot, err; int slot, err, ret;
slot = vrc4173_cardu_slots++; slot = vrc4173_cardu_slots++;
socket = &cardu_sockets[slot]; socket = &cardu_sockets[slot];
@ -474,43 +474,63 @@ static int __devinit vrc4173_cardu_probe(struct pci_dev *dev,
return err; return err;
start = pci_resource_start(dev, 0); start = pci_resource_start(dev, 0);
if (start == 0) if (start == 0) {
return -ENODEV; ret = -ENODEV;
goto disable;
}
len = pci_resource_len(dev, 0); len = pci_resource_len(dev, 0);
if (len == 0) if (len == 0) {
return -ENODEV; ret = -ENODEV;
goto disable;
}
if (((flags = pci_resource_flags(dev, 0)) & IORESOURCE_MEM) == 0) flags = pci_resource_flags(dev, 0);
return -EBUSY; if ((flags & IORESOURCE_MEM) == 0) {
ret = -EBUSY;
goto disable;
}
if ((err = pci_request_regions(dev, socket->name)) < 0) err = pci_request_regions(dev, socket->name);
return err; if (err < 0) {
ret = err;
goto disable;
}
socket->base = ioremap(start, len); socket->base = ioremap(start, len);
if (socket->base == NULL) if (socket->base == NULL) {
return -ENODEV; ret = -ENODEV;
goto release;
}
socket->dev = dev; socket->dev = dev;
socket->pcmcia_socket = pcmcia_register_socket(slot, &cardu_operations, 1); socket->pcmcia_socket = pcmcia_register_socket(slot, &cardu_operations, 1);
if (socket->pcmcia_socket == NULL) { if (socket->pcmcia_socket == NULL) {
iounmap(socket->base); ret = -ENOMEM;
socket->base = NULL; goto unmap;
return -ENOMEM;
} }
if (request_irq(dev->irq, cardu_interrupt, IRQF_SHARED, socket->name, socket) < 0) { if (request_irq(dev->irq, cardu_interrupt, IRQF_SHARED, socket->name, socket) < 0) {
pcmcia_unregister_socket(socket->pcmcia_socket); ret = -EBUSY;
socket->pcmcia_socket = NULL; goto unregister;
iounmap(socket->base);
socket->base = NULL;
return -EBUSY;
} }
printk(KERN_INFO "%s at %#08lx, IRQ %d\n", socket->name, start, dev->irq); printk(KERN_INFO "%s at %#08lx, IRQ %d\n", socket->name, start, dev->irq);
return 0; return 0;
unregister:
pcmcia_unregister_socket(socket->pcmcia_socket);
socket->pcmcia_socket = NULL;
unmap:
iounmap(socket->base);
socket->base = NULL;
release:
pci_release_regions(dev);
disable:
pci_disable_device(dev);
return ret;
} }
static int __devinit vrc4173_cardu_setup(char *options) static int __devinit vrc4173_cardu_setup(char *options)

View file

@ -17,7 +17,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>

View file

@ -20,7 +20,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include "yenta_socket.h" #include "yenta_socket.h"
#include "i82365.h" #include "i82365.h"

View file

@ -49,7 +49,6 @@
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include "aha152x.h" #include "aha152x.h"
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -86,8 +85,6 @@ static void aha152x_release_cs(struct pcmcia_device *link);
static void aha152x_detach(struct pcmcia_device *p_dev); static void aha152x_detach(struct pcmcia_device *p_dev);
static int aha152x_config_cs(struct pcmcia_device *link); static int aha152x_config_cs(struct pcmcia_device *link);
static struct pcmcia_device *dev_list;
static int aha152x_probe(struct pcmcia_device *link) static int aha152x_probe(struct pcmcia_device *link)
{ {
scsi_info_t *info; scsi_info_t *info;
@ -100,11 +97,8 @@ static int aha152x_probe(struct pcmcia_device *link)
info->p_dev = link; info->p_dev = link;
link->priv = info; link->priv = info;
link->resource[0]->end = 0x20; link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->config_regs = PRESENT_OPTION;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.Present = PRESENT_OPTION;
return aha152x_config_cs(link); return aha152x_config_cs(link);
} /* aha152x_attach */ } /* aha152x_attach */
@ -123,25 +117,24 @@ static void aha152x_detach(struct pcmcia_device *link)
/*====================================================================*/ /*====================================================================*/
static int aha152x_config_check(struct pcmcia_device *p_dev, static int aha152x_config_check(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
p_dev->io_lines = 10; p_dev->io_lines = 10;
/* For New Media T&J, look for a SCSI window */ /* For New Media T&J, look for a SCSI window */
if (cfg->io.win[0].len >= 0x20) if ((p_dev->resource[0]->end < 0x20) &&
p_dev->resource[0]->start = cfg->io.win[0].base; (p_dev->resource[1]->end >= 0x20))
else if ((cfg->io.nwin > 1) && p_dev->resource[0]->start = p_dev->resource[1]->start;
(cfg->io.win[1].len >= 0x20))
p_dev->resource[0]->start = cfg->io.win[1].base; if (p_dev->resource[0]->start >= 0xffff)
if ((cfg->io.nwin > 0) && return -EINVAL;
(p_dev->resource[0]->start < 0xffff)) {
if (!pcmcia_request_io(p_dev)) p_dev->resource[1]->start = p_dev->resource[1]->end = 0;
return 0; p_dev->resource[0]->end = 0x20;
} p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
return -EINVAL; p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
return pcmcia_request_io(p_dev);
} }
static int aha152x_config_cs(struct pcmcia_device *link) static int aha152x_config_cs(struct pcmcia_device *link)
@ -160,7 +153,7 @@ static int aha152x_config_cs(struct pcmcia_device *link)
if (!link->irq) if (!link->irq)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
@ -221,9 +214,7 @@ MODULE_DEVICE_TABLE(pcmcia, aha152x_ids);
static struct pcmcia_driver aha152x_cs_driver = { static struct pcmcia_driver aha152x_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "aha152x_cs",
.name = "aha152x_cs",
},
.probe = aha152x_probe, .probe = aha152x_probe,
.remove = aha152x_detach, .remove = aha152x_detach,
.id_table = aha152x_ids, .id_table = aha152x_ids,
@ -238,7 +229,6 @@ static int __init init_aha152x_cs(void)
static void __exit exit_aha152x_cs(void) static void __exit exit_aha152x_cs(void)
{ {
pcmcia_unregister_driver(&aha152x_cs_driver); pcmcia_unregister_driver(&aha152x_cs_driver);
BUG_ON(dev_list != NULL);
} }
module_init(init_aha152x_cs); module_init(init_aha152x_cs);

View file

@ -46,7 +46,6 @@
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include "fdomain.h" #include "fdomain.h"
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -83,11 +82,8 @@ static int fdomain_probe(struct pcmcia_device *link)
info->p_dev = link; info->p_dev = link;
link->priv = info; link->priv = info;
link->resource[0]->end = 0x10; link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->config_regs = PRESENT_OPTION;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.Present = PRESENT_OPTION;
return fdomain_config(link); return fdomain_config(link);
} /* fdomain_attach */ } /* fdomain_attach */
@ -105,14 +101,12 @@ static void fdomain_detach(struct pcmcia_device *link)
/*====================================================================*/ /*====================================================================*/
static int fdomain_config_check(struct pcmcia_device *p_dev, static int fdomain_config_check(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
p_dev->io_lines = 10; p_dev->io_lines = 10;
p_dev->resource[0]->start = cfg->io.win[0].base; p_dev->resource[0]->end = 0x10;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
return pcmcia_request_io(p_dev); return pcmcia_request_io(p_dev);
} }
@ -132,7 +126,7 @@ static int fdomain_config(struct pcmcia_device *link)
if (!link->irq) if (!link->irq)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
@ -194,9 +188,7 @@ MODULE_DEVICE_TABLE(pcmcia, fdomain_ids);
static struct pcmcia_driver fdomain_cs_driver = { static struct pcmcia_driver fdomain_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "fdomain_cs",
.name = "fdomain_cs",
},
.probe = fdomain_probe, .probe = fdomain_probe,
.remove = fdomain_detach, .remove = fdomain_detach,
.id_table = fdomain_ids, .id_table = fdomain_ids,

View file

@ -47,7 +47,6 @@
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_ioctl.h> #include <scsi/scsi_ioctl.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -1531,15 +1530,6 @@ static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt)
PCMCIA functions PCMCIA functions
**********************************************************************/ **********************************************************************/
/*======================================================================
nsp_cs_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
static int nsp_cs_probe(struct pcmcia_device *link) static int nsp_cs_probe(struct pcmcia_device *link)
{ {
scsi_info_t *info; scsi_info_t *info;
@ -1557,14 +1547,6 @@ static int nsp_cs_probe(struct pcmcia_device *link)
nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info); nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
/* The io structure describes IO port mapping */
link->resource[0]->end = 0x10;
link->resource[0]->flags = IO_DATA_PATH_WIDTH_AUTO;
/* General socket configuration */
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
ret = nsp_cs_config(link); ret = nsp_cs_config(link);
nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
@ -1572,12 +1554,6 @@ static int nsp_cs_probe(struct pcmcia_device *link)
} /* nsp_cs_attach */ } /* nsp_cs_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void nsp_cs_detach(struct pcmcia_device *link) static void nsp_cs_detach(struct pcmcia_device *link)
{ {
nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link); nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
@ -1590,98 +1566,36 @@ static void nsp_cs_detach(struct pcmcia_device *link)
} /* nsp_cs_detach */ } /* nsp_cs_detach */
/*====================================================================== static int nsp_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
nsp_cs_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
ethernet device available to the system.
======================================================================*/
struct nsp_cs_configdata {
nsp_hw_data *data;
win_req_t req;
};
static int nsp_cs_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
struct nsp_cs_configdata *cfg_mem = priv_data; nsp_hw_data *data = priv_data;
if (cfg->index == 0) if (p_dev->config_index == 0)
return -ENODEV; return -ENODEV;
/* Does this card need audio output? */ /* This reserves IO space but doesn't actually enable it */
if (cfg->flags & CISTPL_CFTABLE_AUDIO) { if (pcmcia_request_io(p_dev) != 0)
p_dev->conf.Attributes |= CONF_ENABLE_SPKR; goto next_entry;
p_dev->conf.Status = CCSR_AUDIO_ENA;
} if (resource_size(p_dev->resource[2])) {
p_dev->resource[2]->flags |= (WIN_DATA_WIDTH_16 |
/* Use power settings for Vcc and Vpp if present */ WIN_MEMORY_TYPE_CM |
/* Note that the CIS values need to be rescaled */ WIN_ENABLE);
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { if (p_dev->resource[2]->end < 0x1000)
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) p_dev->resource[2]->end = 0x1000;
return -ENODEV; if (pcmcia_request_window(p_dev, p_dev->resource[2], 0) != 0)
else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) { goto next_entry;
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM]/10000) if (pcmcia_map_mem_page(p_dev, p_dev->resource[2],
return -ENODEV; p_dev->card_addr) != 0)
} goto next_entry;
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) { data->MmioAddress = (unsigned long)
p_dev->conf.Vpp = ioremap_nocache(p_dev->resource[2]->start,
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; resource_size(p_dev->resource[2]));
} else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) { data->MmioLength = resource_size(p_dev->resource[2]);
p_dev->conf.Vpp =
dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
}
/* Do we need to allocate an interrupt? */
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
p_dev->resource[1]->flags =
p_dev->resource[0]->flags;
p_dev->resource[1]->start = io->win[1].base;
p_dev->resource[1]->end = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(p_dev) != 0)
goto next_entry;
}
if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
cistpl_mem_t *mem =
(cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
cfg_mem->req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
cfg_mem->req.Attributes |= WIN_ENABLE;
cfg_mem->req.Base = mem->win[0].host_addr;
cfg_mem->req.Size = mem->win[0].len;
if (cfg_mem->req.Size < 0x1000)
cfg_mem->req.Size = 0x1000;
cfg_mem->req.AccessSpeed = 0;
if (pcmcia_request_window(p_dev, &cfg_mem->req, &p_dev->win) != 0)
goto next_entry;
if (pcmcia_map_mem_page(p_dev, p_dev->win,
mem->win[0].card_addr) != 0)
goto next_entry;
cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size);
cfg_mem->data->MmioLength = cfg_mem->req.Size;
}
/* If we got this far, we're cool! */
return 0;
} }
/* If we got this far, we're cool! */
return 0;
next_entry: next_entry:
nsp_dbg(NSP_DEBUG_INIT, "next"); nsp_dbg(NSP_DEBUG_INIT, "next");
@ -1693,25 +1607,23 @@ static int nsp_cs_config(struct pcmcia_device *link)
{ {
int ret; int ret;
scsi_info_t *info = link->priv; scsi_info_t *info = link->priv;
struct nsp_cs_configdata *cfg_mem;
struct Scsi_Host *host; struct Scsi_Host *host;
nsp_hw_data *data = &nsp_data_base; nsp_hw_data *data = &nsp_data_base;
nsp_dbg(NSP_DEBUG_INIT, "in"); nsp_dbg(NSP_DEBUG_INIT, "in");
cfg_mem = kzalloc(sizeof(*cfg_mem), GFP_KERNEL); link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
if (!cfg_mem) CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IOMEM |
return -ENOMEM; CONF_AUTO_SET_IO;
cfg_mem->data = data;
ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem); ret = pcmcia_loop_config(link, nsp_cs_config_check, data);
if (ret) if (ret)
goto cs_failed; goto cs_failed;
if (pcmcia_request_irq(link, nspintr)) if (pcmcia_request_irq(link, nspintr))
goto cs_failed; goto cs_failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto cs_failed; goto cs_failed;
@ -1754,41 +1666,16 @@ static int nsp_cs_config(struct pcmcia_device *link)
info->host = host; info->host = host;
/* Finally, report what we've done */
printk(KERN_INFO "nsp_cs: index 0x%02x: ",
link->conf.ConfigIndex);
if (link->conf.Vpp) {
printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
}
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
printk(", irq %d", link->irq);
}
if (link->resource[0])
printk(", io %pR", link->resource[0]);
if (link->resource[1])
printk(" & %pR", link->resource[1]);
if (link->win)
printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base,
cfg_mem->req.Base+cfg_mem->req.Size-1);
printk("\n");
kfree(cfg_mem);
return 0; return 0;
cs_failed: cs_failed:
nsp_dbg(NSP_DEBUG_INIT, "config fail"); nsp_dbg(NSP_DEBUG_INIT, "config fail");
nsp_cs_release(link); nsp_cs_release(link);
kfree(cfg_mem);
return -ENODEV; return -ENODEV;
} /* nsp_cs_config */ } /* nsp_cs_config */
/*======================================================================
After a card is removed, nsp_cs_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void nsp_cs_release(struct pcmcia_device *link) static void nsp_cs_release(struct pcmcia_device *link)
{ {
scsi_info_t *info = link->priv; scsi_info_t *info = link->priv;
@ -1807,7 +1694,7 @@ static void nsp_cs_release(struct pcmcia_device *link)
scsi_remove_host(info->host); scsi_remove_host(info->host);
} }
if (link->win) { if (resource_size(link->resource[2])) {
if (data != NULL) { if (data != NULL) {
iounmap((void *)(data->MmioAddress)); iounmap((void *)(data->MmioAddress));
} }
@ -1877,9 +1764,7 @@ MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
static struct pcmcia_driver nsp_driver = { static struct pcmcia_driver nsp_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "nsp_cs",
.name = "nsp_cs",
},
.probe = nsp_cs_probe, .probe = nsp_cs_probe,
.remove = nsp_cs_detach, .remove = nsp_cs_detach,
.id_table = nsp_cs_ids, .id_table = nsp_cs_ids,
@ -1889,14 +1774,11 @@ static struct pcmcia_driver nsp_driver = {
static int __init nsp_cs_init(void) static int __init nsp_cs_init(void)
{ {
nsp_msg(KERN_INFO, "loading...");
return pcmcia_register_driver(&nsp_driver); return pcmcia_register_driver(&nsp_driver);
} }
static void __exit nsp_cs_exit(void) static void __exit nsp_cs_exit(void)
{ {
nsp_msg(KERN_INFO, "unloading...");
pcmcia_unregister_driver(&nsp_driver); pcmcia_unregister_driver(&nsp_driver);
} }

View file

@ -48,7 +48,6 @@
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include "../qlogicfas408.h" #include "../qlogicfas408.h"
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
@ -156,11 +155,8 @@ static int qlogic_probe(struct pcmcia_device *link)
return -ENOMEM; return -ENOMEM;
info->p_dev = link; info->p_dev = link;
link->priv = info; link->priv = info;
link->resource[0]->end = 16; link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->config_regs = PRESENT_OPTION;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.Present = PRESENT_OPTION;
return qlogic_config(link); return qlogic_config(link);
} /* qlogic_attach */ } /* qlogic_attach */
@ -178,15 +174,11 @@ static void qlogic_detach(struct pcmcia_device *link)
/*====================================================================*/ /*====================================================================*/
static int qlogic_config_check(struct pcmcia_device *p_dev, static int qlogic_config_check(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
p_dev->io_lines = 10; p_dev->io_lines = 10;
p_dev->resource[0]->start = cfg->io.win[0].base; p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->end = cfg->io.win[0].len; p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
if (p_dev->resource[0]->start == 0) if (p_dev->resource[0]->start == 0)
return -ENODEV; return -ENODEV;
@ -209,7 +201,7 @@ static int qlogic_config(struct pcmcia_device * link)
if (!link->irq) if (!link->irq)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
@ -264,7 +256,7 @@ static int qlogic_resume(struct pcmcia_device *link)
{ {
scsi_info_t *info = link->priv; scsi_info_t *info = link->priv;
pcmcia_request_configuration(link, &link->conf); pcmcia_enable_device(link);
if ((info->manf_id == MANFID_MACNICA) || if ((info->manf_id == MANFID_MACNICA) ||
(info->manf_id == MANFID_PIONEER) || (info->manf_id == MANFID_PIONEER) ||
(info->manf_id == 0x0098)) { (info->manf_id == 0x0098)) {
@ -302,9 +294,7 @@ MODULE_DEVICE_TABLE(pcmcia, qlogic_ids);
static struct pcmcia_driver qlogic_cs_driver = { static struct pcmcia_driver qlogic_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = {
.name = "qlogic_cs", .name = "qlogic_cs",
},
.probe = qlogic_probe, .probe = qlogic_probe,
.remove = qlogic_detach, .remove = qlogic_detach,
.id_table = qlogic_ids, .id_table = qlogic_ids,

View file

@ -71,7 +71,6 @@
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
@ -684,15 +683,11 @@ static struct scsi_host_template sym53c500_driver_template = {
.shost_attrs = SYM53C500_shost_attrs .shost_attrs = SYM53C500_shost_attrs
}; };
static int SYM53C500_config_check(struct pcmcia_device *p_dev, static int SYM53C500_config_check(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
p_dev->io_lines = 10; p_dev->io_lines = 10;
p_dev->resource[0]->start = cfg->io.win[0].base; p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->end = cfg->io.win[0].len; p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
if (p_dev->resource[0]->start == 0) if (p_dev->resource[0]->start == 0)
return -ENODEV; return -ENODEV;
@ -721,7 +716,7 @@ SYM53C500_config(struct pcmcia_device *link)
if (!link->irq) if (!link->irq)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
@ -859,10 +854,7 @@ SYM53C500_probe(struct pcmcia_device *link)
return -ENOMEM; return -ENOMEM;
info->p_dev = link; info->p_dev = link;
link->priv = info; link->priv = info;
link->resource[0]->end = 16; link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
return SYM53C500_config(link); return SYM53C500_config(link);
} /* SYM53C500_attach */ } /* SYM53C500_attach */
@ -881,9 +873,7 @@ MODULE_DEVICE_TABLE(pcmcia, sym53c500_ids);
static struct pcmcia_driver sym53c500_cs_driver = { static struct pcmcia_driver sym53c500_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "sym53c500_cs",
.name = "sym53c500_cs",
},
.probe = SYM53C500_probe, .probe = SYM53C500_probe,
.remove = SYM53C500_detach, .remove = SYM53C500_detach,
.id_table = sym53c500_ids, .id_table = sym53c500_ids,

View file

@ -45,7 +45,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -183,10 +182,8 @@ static void quirk_config_socket(struct pcmcia_device *link)
{ {
struct serial_info *info = link->priv; struct serial_info *info = link->priv;
if (info->multi) { if (info->multi)
link->conf.Present |= PRESENT_EXT_STATUS; link->config_flags |= CONF_ENABLE_ESR;
link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
}
} }
static const struct serial_quirk quirks[] = { static const struct serial_quirk quirks[] = {
@ -265,13 +262,6 @@ static const struct serial_quirk quirks[] = {
static int serial_config(struct pcmcia_device * link); static int serial_config(struct pcmcia_device * link);
/*======================================================================
After a card is removed, serial_remove() will unregister
the serial device(s), and release the PCMCIA configuration.
======================================================================*/
static void serial_remove(struct pcmcia_device *link) static void serial_remove(struct pcmcia_device *link)
{ {
struct serial_info *info = link->priv; struct serial_info *info = link->priv;
@ -314,14 +304,6 @@ static int serial_resume(struct pcmcia_device *link)
return 0; return 0;
} }
/*======================================================================
serial_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
======================================================================*/
static int serial_probe(struct pcmcia_device *link) static int serial_probe(struct pcmcia_device *link)
{ {
struct serial_info *info; struct serial_info *info;
@ -335,36 +317,19 @@ static int serial_probe(struct pcmcia_device *link)
info->p_dev = link; info->p_dev = link;
link->priv = info; link->priv = info;
link->conf.Attributes = CONF_ENABLE_IRQ; link->config_flags |= CONF_ENABLE_IRQ;
if (do_sound) { if (do_sound)
link->conf.Attributes |= CONF_ENABLE_SPKR; link->config_flags |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
}
link->conf.IntType = INT_MEMORY_AND_IO;
return serial_config(link); return serial_config(link);
} }
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void serial_detach(struct pcmcia_device *link) static void serial_detach(struct pcmcia_device *link)
{ {
struct serial_info *info = link->priv; struct serial_info *info = link->priv;
dev_dbg(&link->dev, "serial_detach\n"); dev_dbg(&link->dev, "serial_detach\n");
/*
* Ensure any outstanding scheduled tasks are completed.
*/
flush_scheduled_work();
/* /*
* Ensure that the ports have been released. * Ensure that the ports have been released.
*/ */
@ -430,47 +395,45 @@ static int pfc_config(struct pcmcia_device *p_dev)
return -ENODEV; return -ENODEV;
} }
static int simple_config_check(struct pcmcia_device *p_dev, static int simple_config_check(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
static const int size_table[2] = { 8, 16 }; static const int size_table[2] = { 8, 16 };
int *try = priv_data; int *try = priv_data;
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) if (p_dev->resource[0]->start == 0)
p_dev->conf.Vpp = return -ENODEV;
cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
p_dev->io_lines = ((*try & 0x1) == 0) ? if ((*try & 0x1) == 0)
16 : cf->io.flags & CISTPL_IO_LINES_MASK; p_dev->io_lines = 16;
if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[(*try >> 1)]) if (p_dev->resource[0]->end != size_table[(*try >> 1)])
&& (cf->io.win[0].base != 0)) { return -ENODEV;
p_dev->resource[0]->start = cf->io.win[0].base;
if (!pcmcia_request_io(p_dev)) p_dev->resource[0]->end = 8;
return 0; p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
} p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
return -EINVAL;
return pcmcia_request_io(p_dev);
} }
static int simple_config_check_notpicky(struct pcmcia_device *p_dev, static int simple_config_check_notpicky(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data) void *priv_data)
{ {
static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
int j; int j;
if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { if (p_dev->io_lines > 3)
for (j = 0; j < 5; j++) { return -ENODEV;
p_dev->resource[0]->start = base[j];
p_dev->io_lines = base[j] ? 16 : 3; p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
if (!pcmcia_request_io(p_dev)) p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
return 0; 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; return -ENODEV;
} }
@ -480,11 +443,9 @@ 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;
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
link->resource[0]->end = 8;
/* 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 */
link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_SET_IO;
for (try = 0; try < 4; try++) for (try = 0; try < 4; try++)
if (!pcmcia_loop_config(link, simple_config_check, &try)) if (!pcmcia_loop_config(link, simple_config_check, &try))
goto found_port; goto found_port;
@ -500,7 +461,7 @@ static int simple_config(struct pcmcia_device *link)
found_port: found_port:
if (info->multi && (info->manfid == MANFID_3COM)) if (info->multi && (info->manfid == MANFID_3COM))
link->conf.ConfigIndex &= ~(0x08); link->config_index &= ~(0x08);
/* /*
* Apply any configuration quirks. * Apply any configuration quirks.
@ -508,51 +469,50 @@ found_port:
if (info->quirk && info->quirk->config) if (info->quirk && info->quirk->config)
info->quirk->config(link); info->quirk->config(link);
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_enable_device(link);
if (i != 0) if (i != 0)
return -1; return -1;
return setup_serial(link, info, link->resource[0]->start, link->irq); return setup_serial(link, info, link->resource[0]->start, link->irq);
} }
static int multi_config_check(struct pcmcia_device *p_dev, static int multi_config_check(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
int *base2 = priv_data; int *multi = priv_data;
if (p_dev->resource[1]->end)
return -EINVAL;
/* The quad port cards have bad CIS's, so just look for a /* The quad port cards have bad CIS's, so just look for a
window larger than 8 ports and assume it will be right */ window larger than 8 ports and assume it will be right */
if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { if (p_dev->resource[0]->end <= 8)
p_dev->resource[0]->start = cf->io.win[0].base; return -EINVAL;
p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK;
if (!pcmcia_request_io(p_dev)) { p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
*base2 = p_dev->resource[0]->start + 8; p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
return 0; p_dev->resource[0]->end = *multi * 8;
}
} if (pcmcia_request_io(p_dev))
return -ENODEV; return -ENODEV;
return 0;
} }
static int multi_config_check_notpicky(struct pcmcia_device *p_dev, static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data) void *priv_data)
{ {
int *base2 = priv_data; int *base2 = priv_data;
if (cf->io.nwin == 2) { if (!p_dev->resource[0]->end || !p_dev->resource[1]->end)
p_dev->resource[0]->start = cf->io.win[0].base; return -ENODEV;
p_dev->resource[1]->start = cf->io.win[1].base;
p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK; p_dev->resource[0]->end = p_dev->resource[1]->end = 8;
if (!pcmcia_request_io(p_dev)) { p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
*base2 = p_dev->resource[1]->start; p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
return 0;
} if (pcmcia_request_io(p_dev))
} return -ENODEV;
return -ENODEV;
*base2 = p_dev->resource[0]->start + 8;
return 0;
} }
static int multi_config(struct pcmcia_device *link) static int multi_config(struct pcmcia_device *link)
@ -560,12 +520,12 @@ static int multi_config(struct pcmcia_device *link)
struct serial_info *info = link->priv; struct serial_info *info = link->priv;
int i, base2 = 0; int i, base2 = 0;
link->config_flags |= CONF_AUTO_SET_IO;
/* 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; if (!pcmcia_loop_config(link, multi_config_check, &info->multi))
link->resource[0]->end = info->multi * 8; base2 = link->resource[0]->start + 8;
if (pcmcia_loop_config(link, multi_config_check, &base2)) { else {
/* If that didn't work, look for two windows */ /* If that didn't work, look for two windows */
link->resource[0]->end = link->resource[1]->end = 8;
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)) {
@ -584,7 +544,7 @@ static int multi_config(struct pcmcia_device *link)
if (info->quirk && info->quirk->config) if (info->quirk && info->quirk->config)
info->quirk->config(link); info->quirk->config(link);
i = pcmcia_request_configuration(link, &link->conf); i = pcmcia_enable_device(link);
if (i != 0) if (i != 0)
return -ENODEV; return -ENODEV;
@ -596,11 +556,11 @@ static int multi_config(struct pcmcia_device *link)
info->prodid == PRODID_POSSIO_GCC)) { info->prodid == PRODID_POSSIO_GCC)) {
int err; int err;
if (link->conf.ConfigIndex == 1 || if (link->config_index == 1 ||
link->conf.ConfigIndex == 3) { link->config_index == 3) {
err = setup_serial(link, info, base2, err = setup_serial(link, info, base2,
link->irq); link->irq);
base2 = link->resource[0]->start;; base2 = link->resource[0]->start;
} else { } else {
err = setup_serial(link, info, link->resource[0]->start, err = setup_serial(link, info, link->resource[0]->start,
link->irq); link->irq);
@ -624,33 +584,24 @@ static int multi_config(struct pcmcia_device *link)
return 0; return 0;
} }
static int serial_check_for_multi(struct pcmcia_device *p_dev, static int serial_check_for_multi(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
struct serial_info *info = p_dev->priv; struct serial_info *info = p_dev->priv;
if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) if (!p_dev->resource[0]->end)
info->multi = cf->io.win[0].len >> 3; return -EINVAL;
if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && if ((!p_dev->resource[1]->end) && (p_dev->resource[0]->end % 8 == 0))
(cf->io.win[1].len == 8)) info->multi = p_dev->resource[0]->end >> 3;
if ((p_dev->resource[1]->end) && (p_dev->resource[0]->end == 8)
&& (p_dev->resource[1]->end == 8))
info->multi = 2; info->multi = 2;
return 0; /* break */ return 0; /* break */
} }
/*======================================================================
serial_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
serial device available to the system.
======================================================================*/
static int serial_config(struct pcmcia_device * link) static int serial_config(struct pcmcia_device * link)
{ {
struct serial_info *info = link->priv; struct serial_info *info = link->priv;
@ -894,9 +845,7 @@ MODULE_FIRMWARE("cis/RS-COM-2P.cis");
static struct pcmcia_driver serial_cs_driver = { static struct pcmcia_driver serial_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "serial_cs",
.name = "serial_cs",
},
.probe = serial_probe, .probe = serial_probe,
.remove = serial_detach, .remove = serial_detach,
.id_table = serial_ids, .id_table = serial_ids,

View file

@ -20,7 +20,6 @@
#include <linux/mmc/sdio_func.h> #include <linux/mmc/sdio_func.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>

View file

@ -13,7 +13,6 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>

View file

@ -17,7 +17,6 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/io.h> #include <linux/io.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>

View file

@ -37,7 +37,6 @@ Status: experimental
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -692,10 +691,6 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)
local->link = link; local->link = link;
link->priv = local; link->priv = local;
/* Initialize the pcmcia_device structure */
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
cur_dev = link; cur_dev = link;
das16cs_pcmcia_config(link); das16cs_pcmcia_config(link);
@ -715,37 +710,12 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link)
static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev, static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data) void *priv_data)
{ {
if (cfg->index == 0) if (p_dev->config_index == 0)
return -EINVAL; return -EINVAL;
/* Do we need to allocate an interrupt? */ return pcmcia_request_io(p_dev);
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
p_dev->resource[1]->flags = p_dev->resource[0]->flags;
p_dev->resource[1]->start = io->win[1].base;
p_dev->resource[1]->end = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
return pcmcia_request_io(p_dev);
}
return 0;
} }
static void das16cs_pcmcia_config(struct pcmcia_device *link) static void das16cs_pcmcia_config(struct pcmcia_device *link)
@ -754,6 +724,9 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "das16cs_pcmcia_config\n"); dev_dbg(&link->dev, "das16cs_pcmcia_config\n");
/* Do we need to allocate an interrupt? */
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL); ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL);
if (ret) { if (ret) {
dev_warn(&link->dev, "no configuration found\n"); dev_warn(&link->dev, "no configuration found\n");
@ -763,25 +736,10 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)
if (!link->irq) if (!link->irq)
goto failed; goto failed;
/* ret = pcmcia_enable_device(link);
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
/* Finally, report what we've done */
dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %u", link->irq);
if (link->resource[0])
printk(", io %pR", link->resource[0]);
if (link->resource[1])
printk(", io %pR", link->resource[1]);
printk("\n");
return; return;
failed: failed:
@ -832,9 +790,7 @@ struct pcmcia_driver das16cs_driver = {
.resume = das16cs_pcmcia_resume, .resume = das16cs_pcmcia_resume,
.id_table = das16cs_id_table, .id_table = das16cs_id_table,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "cb_das16_cs",
.name = "cb_das16_cs",
},
}; };
static int __init init_das16cs_pcmcia_cs(void) static int __init init_das16cs_pcmcia_cs(void)

View file

@ -48,7 +48,6 @@ Command support does not exist, but could be added for this board.
#include "das08.h" #include "das08.h"
/* pcmcia includes */ /* pcmcia includes */
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -115,40 +114,15 @@ static void das08_pcmcia_release(struct pcmcia_device *link);
static int das08_pcmcia_suspend(struct pcmcia_device *p_dev); static int das08_pcmcia_suspend(struct pcmcia_device *p_dev);
static int das08_pcmcia_resume(struct pcmcia_device *p_dev); static int das08_pcmcia_resume(struct pcmcia_device *p_dev);
/*
The attach() and detach() entry points are used to create and destroy
"instances" of the driver, where each instance represents everything
needed to manage one actual PCMCIA card.
*/
static int das08_pcmcia_attach(struct pcmcia_device *); static int das08_pcmcia_attach(struct pcmcia_device *);
static void das08_pcmcia_detach(struct pcmcia_device *); static void das08_pcmcia_detach(struct pcmcia_device *);
/*
You'll also need to prototype all the functions that will actually
be used to talk to your device. See 'memory_cs' for a good example
of a fully self-sufficient driver; the other drivers rely more or
less on other parts of the kernel.
*/
struct local_info_t { struct local_info_t {
struct pcmcia_device *link; struct pcmcia_device *link;
int stop; int stop;
struct bus_operations *bus; struct bus_operations *bus;
}; };
/*======================================================================
das08_pcmcia_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
static int das08_pcmcia_attach(struct pcmcia_device *link) static int das08_pcmcia_attach(struct pcmcia_device *link)
{ {
struct local_info_t *local; struct local_info_t *local;
@ -162,16 +136,6 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
local->link = link; local->link = link;
link->priv = local; link->priv = local;
/*
General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost
everything. In most clients, many details (i.e., number, sizes,
and attributes of IO windows) are fixed by the nature of the
device, and can be hard-wired here.
*/
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
cur_dev = link; cur_dev = link;
das08_pcmcia_config(link); das08_pcmcia_config(link);
@ -179,15 +143,6 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
return 0; return 0;
} /* das08_pcmcia_attach */ } /* das08_pcmcia_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void das08_pcmcia_detach(struct pcmcia_device *link) static void das08_pcmcia_detach(struct pcmcia_device *link)
{ {
@ -203,53 +158,22 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)
static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev, static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data) void *priv_data)
{ {
if (cfg->index == 0) if (p_dev->config_index == 0)
return -ENODEV; return -EINVAL;
/* Do we need to allocate an interrupt? */ return pcmcia_request_io(p_dev);
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
p_dev->resource[1]->flags = p_dev->resource[0]->flags;
p_dev->resource[1]->start = io->win[1].base;
p_dev->resource[1]->end = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
return pcmcia_request_io(p_dev);
}
return 0;
} }
/*======================================================================
das08_pcmcia_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
======================================================================*/
static void das08_pcmcia_config(struct pcmcia_device *link) static void das08_pcmcia_config(struct pcmcia_device *link)
{ {
int ret; int ret;
dev_dbg(&link->dev, "das08_pcmcia_config\n"); dev_dbg(&link->dev, "das08_pcmcia_config\n");
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL); ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL);
if (ret) { if (ret) {
dev_warn(&link->dev, "no configuration found\n"); dev_warn(&link->dev, "no configuration found\n");
@ -259,25 +183,10 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
if (!link->irq) if (!link->irq)
goto failed; goto failed;
/* ret = pcmcia_enable_device(link);
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
/* Finally, report what we've done */
dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %u", link->irq);
if (link->resource[0])
printk(", io %pR", link->resource[0]);
if (link->resource[1])
printk(" & %pR", link->resource[1]);
printk("\n");
return; return;
failed: failed:
@ -285,32 +194,12 @@ failed:
} /* das08_pcmcia_config */ } /* das08_pcmcia_config */
/*======================================================================
After a card is removed, das08_pcmcia_release() will unregister the
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
======================================================================*/
static void das08_pcmcia_release(struct pcmcia_device *link) static void das08_pcmcia_release(struct pcmcia_device *link)
{ {
dev_dbg(&link->dev, "das08_pcmcia_release\n"); dev_dbg(&link->dev, "das08_pcmcia_release\n");
pcmcia_disable_device(link); pcmcia_disable_device(link);
} /* das08_pcmcia_release */ } /* das08_pcmcia_release */
/*======================================================================
The card status event handler. Mostly, this schedules other
stuff to run after an event is received.
When a CARD_REMOVAL event is received, we immediately set a
private flag to block future accesses to this device. All the
functions that actually access the device should check this flag
to make sure the card is still present.
======================================================================*/
static int das08_pcmcia_suspend(struct pcmcia_device *link) static int das08_pcmcia_suspend(struct pcmcia_device *link)
{ {
struct local_info_t *local = link->priv; struct local_info_t *local = link->priv;
@ -348,9 +237,7 @@ struct pcmcia_driver das08_cs_driver = {
.resume = das08_pcmcia_resume, .resume = das08_pcmcia_resume,
.id_table = das08_cs_id_table, .id_table = das08_cs_id_table,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "pcm-das08",
.name = "pcm-das08",
},
}; };
static int __init init_das08_pcmcia_cs(void) static int __init init_das08_pcmcia_cs(void)

View file

@ -47,7 +47,6 @@ IRQ is assigned but not used.
#include <linux/ioport.h> #include <linux/ioport.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -435,47 +434,20 @@ static int dio700_detach(struct comedi_device *dev)
return 0; return 0;
}; };
/* PCMCIA crap -- watch your words, please! */
static void dio700_config(struct pcmcia_device *link); static void dio700_config(struct pcmcia_device *link);
static void dio700_release(struct pcmcia_device *link); static void dio700_release(struct pcmcia_device *link);
static int dio700_cs_suspend(struct pcmcia_device *p_dev); static int dio700_cs_suspend(struct pcmcia_device *p_dev);
static int dio700_cs_resume(struct pcmcia_device *p_dev); static int dio700_cs_resume(struct pcmcia_device *p_dev);
/*
The attach() and detach() entry points are used to create and destroy
"instances" of the driver, where each instance represents everything
needed to manage one actual PCMCIA card.
*/
static int dio700_cs_attach(struct pcmcia_device *); static int dio700_cs_attach(struct pcmcia_device *);
static void dio700_cs_detach(struct pcmcia_device *); static void dio700_cs_detach(struct pcmcia_device *);
/*
You'll also need to prototype all the functions that will actually
be used to talk to your device. See 'memory_cs' for a good example
of a fully self-sufficient driver; the other drivers rely more or
less on other parts of the kernel.
*/
struct local_info_t { struct local_info_t {
struct pcmcia_device *link; struct pcmcia_device *link;
int stop; int stop;
struct bus_operations *bus; struct bus_operations *bus;
}; };
/*======================================================================
dio700_cs_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
static int dio700_cs_attach(struct pcmcia_device *link) static int dio700_cs_attach(struct pcmcia_device *link)
{ {
struct local_info_t *local; struct local_info_t *local;
@ -491,16 +463,6 @@ static int dio700_cs_attach(struct pcmcia_device *link)
local->link = link; local->link = link;
link->priv = local; link->priv = local;
/*
General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost
everything. In most clients, many details (i.e., number, sizes,
and attributes of IO windows) are fixed by the nature of the
device, and can be hard-wired here.
*/
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
pcmcia_cur_dev = link; pcmcia_cur_dev = link;
dio700_config(link); dio700_config(link);
@ -508,15 +470,6 @@ static int dio700_cs_attach(struct pcmcia_device *link)
return 0; return 0;
} /* dio700_cs_attach */ } /* dio700_cs_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void dio700_cs_detach(struct pcmcia_device *link) static void dio700_cs_detach(struct pcmcia_device *link)
{ {
@ -532,54 +485,13 @@ static void dio700_cs_detach(struct pcmcia_device *link)
} /* dio700_cs_detach */ } /* dio700_cs_detach */
/*======================================================================
dio700_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
======================================================================*/
static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data) void *priv_data)
{ {
if (cfg->index == 0) if (p_dev->config_index == 0)
return -ENODEV; return -EINVAL;
/* Does this card need audio output? */ return pcmcia_request_io(p_dev);
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
p_dev->conf.Status = CCSR_AUDIO_ENA;
}
/* Do we need to allocate an interrupt? */
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
p_dev->resource[1]->flags = p_dev->resource[0]->flags;
p_dev->resource[1]->start = io->win[1].base;
p_dev->resource[1]->end = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(p_dev) != 0)
return -ENODEV;
}
/* If we got this far, we're cool! */
return 0;
} }
static void dio700_config(struct pcmcia_device *link) static void dio700_config(struct pcmcia_device *link)
@ -591,6 +503,9 @@ static void dio700_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "dio700_config\n"); dev_dbg(&link->dev, "dio700_config\n");
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_AUDIO |
CONF_AUTO_SET_IO;
ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, NULL); ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, NULL);
if (ret) { if (ret) {
dev_warn(&link->dev, "no configuration found\n"); dev_warn(&link->dev, "no configuration found\n");
@ -600,25 +515,10 @@ static void dio700_config(struct pcmcia_device *link)
if (!link->irq) if (!link->irq)
goto failed; goto failed;
/* ret = pcmcia_enable_device(link);
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret != 0) if (ret != 0)
goto failed; goto failed;
/* Finally, report what we've done */
dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq);
if (link->resource[0])
printk(", io %pR", link->resource[0]);
if (link->resource[1])
printk(" & %pR", link->resource[1]);
printk("\n");
return; return;
failed: failed:
@ -634,18 +534,6 @@ static void dio700_release(struct pcmcia_device *link)
pcmcia_disable_device(link); pcmcia_disable_device(link);
} /* dio700_release */ } /* dio700_release */
/*======================================================================
The card status event handler. Mostly, this schedules other
stuff to run after an event is received.
When a CARD_REMOVAL event is received, we immediately set a
private flag to block future accesses to this device. All the
functions that actually access the device should check this flag
to make sure the card is still present.
======================================================================*/
static int dio700_cs_suspend(struct pcmcia_device *link) static int dio700_cs_suspend(struct pcmcia_device *link)
{ {
struct local_info_t *local = link->priv; struct local_info_t *local = link->priv;
@ -685,9 +573,7 @@ struct pcmcia_driver dio700_cs_driver = {
.resume = dio700_cs_resume, .resume = dio700_cs_resume,
.id_table = dio700_cs_ids, .id_table = dio700_cs_ids,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "ni_daq_700",
.name = "ni_daq_700",
},
}; };
static int __init init_dio700_cs(void) static int __init init_dio700_cs(void)

View file

@ -48,7 +48,6 @@ the PCMCIA interface.
#include "8255.h" #include "8255.h"
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -187,47 +186,20 @@ static int dio24_detach(struct comedi_device *dev)
return 0; return 0;
}; };
/* PCMCIA crap -- watch your words! */
static void dio24_config(struct pcmcia_device *link); static void dio24_config(struct pcmcia_device *link);
static void dio24_release(struct pcmcia_device *link); static void dio24_release(struct pcmcia_device *link);
static int dio24_cs_suspend(struct pcmcia_device *p_dev); static int dio24_cs_suspend(struct pcmcia_device *p_dev);
static int dio24_cs_resume(struct pcmcia_device *p_dev); static int dio24_cs_resume(struct pcmcia_device *p_dev);
/*
The attach() and detach() entry points are used to create and destroy
"instances" of the driver, where each instance represents everything
needed to manage one actual PCMCIA card.
*/
static int dio24_cs_attach(struct pcmcia_device *); static int dio24_cs_attach(struct pcmcia_device *);
static void dio24_cs_detach(struct pcmcia_device *); static void dio24_cs_detach(struct pcmcia_device *);
/*
You'll also need to prototype all the functions that will actually
be used to talk to your device. See 'memory_cs' for a good example
of a fully self-sufficient driver; the other drivers rely more or
less on other parts of the kernel.
*/
struct local_info_t { struct local_info_t {
struct pcmcia_device *link; struct pcmcia_device *link;
int stop; int stop;
struct bus_operations *bus; struct bus_operations *bus;
}; };
/*======================================================================
dio24_cs_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
static int dio24_cs_attach(struct pcmcia_device *link) static int dio24_cs_attach(struct pcmcia_device *link)
{ {
struct local_info_t *local; struct local_info_t *local;
@ -243,16 +215,6 @@ static int dio24_cs_attach(struct pcmcia_device *link)
local->link = link; local->link = link;
link->priv = local; link->priv = local;
/*
General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost
everything. In most clients, many details (i.e., number, sizes,
and attributes of IO windows) are fixed by the nature of the
device, and can be hard-wired here.
*/
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
pcmcia_cur_dev = link; pcmcia_cur_dev = link;
dio24_config(link); dio24_config(link);
@ -260,15 +222,6 @@ static int dio24_cs_attach(struct pcmcia_device *link)
return 0; return 0;
} /* dio24_cs_attach */ } /* dio24_cs_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void dio24_cs_detach(struct pcmcia_device *link) static void dio24_cs_detach(struct pcmcia_device *link)
{ {
@ -284,54 +237,13 @@ static void dio24_cs_detach(struct pcmcia_device *link)
} /* dio24_cs_detach */ } /* dio24_cs_detach */
/*======================================================================
dio24_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
======================================================================*/
static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev, static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data) void *priv_data)
{ {
if (cfg->index == 0) if (p_dev->config_index == 0)
return -ENODEV; return -EINVAL;
/* Does this card need audio output? */ return pcmcia_request_io(p_dev);
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
p_dev->conf.Status = CCSR_AUDIO_ENA;
}
/* Do we need to allocate an interrupt? */
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
p_dev->resource[1]->flags = p_dev->resource[0]->flags;
p_dev->resource[1]->start = io->win[1].base;
p_dev->resource[1]->end = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(p_dev) != 0)
return -ENODEV;
}
/* If we got this far, we're cool! */
return 0;
} }
static void dio24_config(struct pcmcia_device *link) static void dio24_config(struct pcmcia_device *link)
@ -342,6 +254,9 @@ static void dio24_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "dio24_config\n"); dev_dbg(&link->dev, "dio24_config\n");
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_AUDIO |
CONF_AUTO_SET_IO;
ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, NULL); ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, NULL);
if (ret) { if (ret) {
dev_warn(&link->dev, "no configuration found\n"); dev_warn(&link->dev, "no configuration found\n");
@ -351,25 +266,10 @@ static void dio24_config(struct pcmcia_device *link)
if (!link->irq) if (!link->irq)
goto failed; goto failed;
/* ret = pcmcia_enable_device(link);
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
/* Finally, report what we've done */
dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq);
if (link->resource[0])
printk(" & %pR", link->resource[0]);
if (link->resource[1])
printk(" & %pR", link->resource[1]);
printk("\n");
return; return;
failed: failed:
@ -385,18 +285,6 @@ static void dio24_release(struct pcmcia_device *link)
pcmcia_disable_device(link); pcmcia_disable_device(link);
} /* dio24_release */ } /* dio24_release */
/*======================================================================
The card status event handler. Mostly, this schedules other
stuff to run after an event is received.
When a CARD_REMOVAL event is received, we immediately set a
private flag to block future accesses to this device. All the
functions that actually access the device should check this flag
to make sure the card is still present.
======================================================================*/
static int dio24_cs_suspend(struct pcmcia_device *link) static int dio24_cs_suspend(struct pcmcia_device *link)
{ {
struct local_info_t *local = link->priv; struct local_info_t *local = link->priv;
@ -435,9 +323,7 @@ struct pcmcia_driver dio24_cs_driver = {
.resume = dio24_cs_resume, .resume = dio24_cs_resume,
.id_table = dio24_cs_ids, .id_table = dio24_cs_ids,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "ni_daq_dio24",
.name = "ni_daq_dio24",
},
}; };
static int __init init_dio24_cs(void) static int __init init_dio24_cs(void)

View file

@ -71,7 +71,6 @@ NI manuals:
#include "comedi_fc.h" #include "comedi_fc.h"
#include "ni_labpc.h" #include "ni_labpc.h"
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -153,59 +152,20 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return labpc_common_attach(dev, iobase, irq, 0); return labpc_common_attach(dev, iobase, irq, 0);
} }
/*====================================================================*/
/*
The event() function is this driver's Card Services event handler.
It will be called by Card Services when an appropriate card status
event is received. The config() and release() entry points are
used to configure or release a socket, in response to card
insertion and ejection events. They are invoked from the dummy
event handler.
Kernel version 2.6.16 upwards uses suspend() and resume() functions
instead of an event() function.
*/
static void labpc_config(struct pcmcia_device *link); static void labpc_config(struct pcmcia_device *link);
static void labpc_release(struct pcmcia_device *link); static void labpc_release(struct pcmcia_device *link);
static int labpc_cs_suspend(struct pcmcia_device *p_dev); static int labpc_cs_suspend(struct pcmcia_device *p_dev);
static int labpc_cs_resume(struct pcmcia_device *p_dev); static int labpc_cs_resume(struct pcmcia_device *p_dev);
/*
The attach() and detach() entry points are used to create and destroy
"instances" of the driver, where each instance represents everything
needed to manage one actual PCMCIA card.
*/
static int labpc_cs_attach(struct pcmcia_device *); static int labpc_cs_attach(struct pcmcia_device *);
static void labpc_cs_detach(struct pcmcia_device *); static void labpc_cs_detach(struct pcmcia_device *);
/*
You'll also need to prototype all the functions that will actually
be used to talk to your device. See 'memory_cs' for a good example
of a fully self-sufficient driver; the other drivers rely more or
less on other parts of the kernel.
*/
struct local_info_t { struct local_info_t {
struct pcmcia_device *link; struct pcmcia_device *link;
int stop; int stop;
struct bus_operations *bus; struct bus_operations *bus;
}; };
/*======================================================================
labpc_cs_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
static int labpc_cs_attach(struct pcmcia_device *link) static int labpc_cs_attach(struct pcmcia_device *link)
{ {
struct local_info_t *local; struct local_info_t *local;
@ -219,16 +179,6 @@ static int labpc_cs_attach(struct pcmcia_device *link)
local->link = link; local->link = link;
link->priv = local; link->priv = local;
/*
General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost
everything. In most clients, many details (i.e., number, sizes,
and attributes of IO windows) are fixed by the nature of the
device, and can be hard-wired here.
*/
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
pcmcia_cur_dev = link; pcmcia_cur_dev = link;
labpc_config(link); labpc_config(link);
@ -236,15 +186,6 @@ static int labpc_cs_attach(struct pcmcia_device *link)
return 0; return 0;
} /* labpc_cs_attach */ } /* labpc_cs_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void labpc_cs_detach(struct pcmcia_device *link) static void labpc_cs_detach(struct pcmcia_device *link)
{ {
dev_dbg(&link->dev, "labpc_cs_detach\n"); dev_dbg(&link->dev, "labpc_cs_detach\n");
@ -263,54 +204,13 @@ static void labpc_cs_detach(struct pcmcia_device *link)
} /* labpc_cs_detach */ } /* labpc_cs_detach */
/*======================================================================
labpc_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
======================================================================*/
static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev, static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data) void *priv_data)
{ {
if (cfg->index == 0) if (p_dev->config_index == 0)
return -ENODEV; return -EINVAL;
/* Does this card need audio output? */ return pcmcia_request_io(p_dev);
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
p_dev->conf.Status = CCSR_AUDIO_ENA;
}
/* Do we need to allocate an interrupt? */
p_dev->conf.Attributes |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
/* IO window settings */
p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
p_dev->resource[1]->flags = p_dev->resource[0]->flags;
p_dev->resource[1]->start = io->win[1].base;
p_dev->resource[1]->end = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(p_dev) != 0)
return -ENODEV;
}
/* If we got this far, we're cool! */
return 0;
} }
@ -320,6 +220,9 @@ static void labpc_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "labpc_config\n"); dev_dbg(&link->dev, "labpc_config\n");
link->config_flags |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ |
CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, NULL); ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, NULL);
if (ret) { if (ret) {
dev_warn(&link->dev, "no configuration found\n"); dev_warn(&link->dev, "no configuration found\n");
@ -329,25 +232,10 @@ static void labpc_config(struct pcmcia_device *link)
if (!link->irq) if (!link->irq)
goto failed; goto failed;
/* ret = pcmcia_enable_device(link);
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
/* Finally, report what we've done */
dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq);
if (link->resource[0])
printk(" & %pR", link->resource[0]);
if (link->resource[1])
printk(" & %pR", link->resource[1]);
printk("\n");
return; return;
failed: failed:
@ -362,18 +250,6 @@ static void labpc_release(struct pcmcia_device *link)
pcmcia_disable_device(link); pcmcia_disable_device(link);
} /* labpc_release */ } /* labpc_release */
/*======================================================================
The card status event handler. Mostly, this schedules other
stuff to run after an event is received.
When a CARD_REMOVAL event is received, we immediately set a
private flag to block future accesses to this device. All the
functions that actually access the device should check this flag
to make sure the card is still present.
======================================================================*/
static int labpc_cs_suspend(struct pcmcia_device *link) static int labpc_cs_suspend(struct pcmcia_device *link)
{ {
struct local_info_t *local = link->priv; struct local_info_t *local = link->priv;
@ -391,8 +267,6 @@ static int labpc_cs_resume(struct pcmcia_device *link)
return 0; return 0;
} /* labpc_cs_resume */ } /* labpc_cs_resume */
/*====================================================================*/
static struct pcmcia_device_id labpc_cs_ids[] = { static struct pcmcia_device_id labpc_cs_ids[] = {
/* N.B. These IDs should match those in labpc_cs_boards (ni_labpc.c) */ /* N.B. These IDs should match those in labpc_cs_boards (ni_labpc.c) */
PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0103), /* daqcard-1200 */ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0103), /* daqcard-1200 */
@ -411,9 +285,7 @@ struct pcmcia_driver labpc_cs_driver = {
.resume = labpc_cs_resume, .resume = labpc_cs_resume,
.id_table = labpc_cs_ids, .id_table = labpc_cs_ids,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "daqcard-1200",
.name = "daqcard-1200",
},
}; };
static int __init init_labpc_cs(void) static int __init init_labpc_cs(void)

View file

@ -48,7 +48,6 @@ See the notes in the ni_atmio.o driver.
#include "ni_stc.h" #include "ni_stc.h"
#include "8255.h" #include "8255.h"
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -263,11 +262,6 @@ static struct pcmcia_device *cur_dev = NULL;
static int cs_attach(struct pcmcia_device *link) static int cs_attach(struct pcmcia_device *link)
{ {
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
link->resource[0]->end = 16;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
cur_dev = link; cur_dev = link;
mio_cs_config(link); mio_cs_config(link);
@ -301,16 +295,12 @@ static int mio_cs_resume(struct pcmcia_device *link)
} }
static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev, static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
int base, ret; int base, ret;
p_dev->resource[0]->end = cfg->io.win[0].len; p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK; p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
for (base = 0x000; base < 0x400; base += 0x20) { for (base = 0x000; base < 0x400; base += 0x20) {
p_dev->resource[0]->start = base; p_dev->resource[0]->start = base;
@ -327,6 +317,7 @@ static void mio_cs_config(struct pcmcia_device *link)
int ret; int ret;
DPRINTK("mio_cs_config(link=%p)\n", link); DPRINTK("mio_cs_config(link=%p)\n", link);
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
ret = pcmcia_loop_config(link, mio_pcmcia_config_loop, NULL); ret = pcmcia_loop_config(link, mio_pcmcia_config_loop, NULL);
if (ret) { if (ret) {
@ -337,7 +328,7 @@ static void mio_cs_config(struct pcmcia_device *link)
if (!link->irq) if (!link->irq)
dev_info(&link->dev, "no IRQ available\n"); dev_info(&link->dev, "no IRQ available\n");
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
} }
static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
@ -446,9 +437,7 @@ struct pcmcia_driver ni_mio_cs_driver = {
.resume = &mio_cs_resume, .resume = &mio_cs_resume,
.id_table = ni_mio_cs_ids, .id_table = ni_mio_cs_ids,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "ni_mio_cs",
.name = "ni_mio_cs",
},
}; };
int init_module(void) int init_module(void)

View file

@ -50,7 +50,6 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308
#include "../comedidev.h" #include "../comedidev.h"
#include <linux/semaphore.h> #include <linux/semaphore.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -969,43 +968,14 @@ static int daqp_detach(struct comedi_device *dev)
======================================================================*/ ======================================================================*/
/*
The event() function is this driver's Card Services event handler.
It will be called by Card Services when an appropriate card status
event is received. The config() and release() entry points are
used to configure or release a socket, in response to card
insertion and ejection events.
Kernel version 2.6.16 upwards uses suspend() and resume() functions
instead of an event() function.
*/
static void daqp_cs_config(struct pcmcia_device *link); static void daqp_cs_config(struct pcmcia_device *link);
static void daqp_cs_release(struct pcmcia_device *link); static void daqp_cs_release(struct pcmcia_device *link);
static int daqp_cs_suspend(struct pcmcia_device *p_dev); static int daqp_cs_suspend(struct pcmcia_device *p_dev);
static int daqp_cs_resume(struct pcmcia_device *p_dev); static int daqp_cs_resume(struct pcmcia_device *p_dev);
/*
The attach() and detach() entry points are used to create and destroy
"instances" of the driver, where each instance represents everything
needed to manage one actual PCMCIA card.
*/
static int daqp_cs_attach(struct pcmcia_device *); static int daqp_cs_attach(struct pcmcia_device *);
static void daqp_cs_detach(struct pcmcia_device *); static void daqp_cs_detach(struct pcmcia_device *);
/*======================================================================
daqp_cs_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
static int daqp_cs_attach(struct pcmcia_device *link) static int daqp_cs_attach(struct pcmcia_device *link)
{ {
struct local_info_t *local; struct local_info_t *local;
@ -1031,30 +1001,11 @@ static int daqp_cs_attach(struct pcmcia_device *link)
local->link = link; local->link = link;
link->priv = local; link->priv = local;
/*
General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost
everything. In most clients, many details (i.e., number, sizes,
and attributes of IO windows) are fixed by the nature of the
device, and can be hard-wired here.
*/
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
daqp_cs_config(link); daqp_cs_config(link);
return 0; return 0;
} /* daqp_cs_attach */ } /* daqp_cs_attach */
/*======================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
static void daqp_cs_detach(struct pcmcia_device *link) static void daqp_cs_detach(struct pcmcia_device *link)
{ {
struct local_info_t *dev = link->priv; struct local_info_t *dev = link->priv;
@ -1070,45 +1021,11 @@ static void daqp_cs_detach(struct pcmcia_device *link)
} /* daqp_cs_detach */ } /* daqp_cs_detach */
/*====================================================================== static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data)
daqp_cs_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
======================================================================*/
static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
if (cfg->index == 0) if (p_dev->config_index == 0)
return -ENODEV; return -EINVAL;
/* Do we need to allocate an interrupt? */
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->flags |=
pcmcia_io_cfg_data_width(io->flags);
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
p_dev->resource[1]->flags = p_dev->resource[0]->flags;
p_dev->resource[1]->start = io->win[1].base;
p_dev->resource[1]->end = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
return pcmcia_request_io(p_dev); return pcmcia_request_io(p_dev);
} }
@ -1118,6 +1035,8 @@ static void daqp_cs_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "daqp_cs_config\n"); dev_dbg(&link->dev, "daqp_cs_config\n");
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
ret = pcmcia_loop_config(link, daqp_pcmcia_config_loop, NULL); ret = pcmcia_loop_config(link, daqp_pcmcia_config_loop, NULL);
if (ret) { if (ret) {
dev_warn(&link->dev, "no configuration found\n"); dev_warn(&link->dev, "no configuration found\n");
@ -1128,25 +1047,10 @@ static void daqp_cs_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
/* ret = pcmcia_enable_device(link);
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret) if (ret)
goto failed; goto failed;
/* Finally, report what we've done */
dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %u", link->irq);
if (link->resource[0])
printk(" & %pR", link->resource[0]);
if (link->resource[1])
printk(" & %pR", link->resource[1]);
printk("\n");
return; return;
failed: failed:
@ -1161,18 +1065,6 @@ static void daqp_cs_release(struct pcmcia_device *link)
pcmcia_disable_device(link); pcmcia_disable_device(link);
} /* daqp_cs_release */ } /* daqp_cs_release */
/*======================================================================
The card status event handler. Mostly, this schedules other
stuff to run after an event is received.
When a CARD_REMOVAL event is received, we immediately set a
private flag to block future accesses to this device. All the
functions that actually access the device should check this flag
to make sure the card is still present.
======================================================================*/
static int daqp_cs_suspend(struct pcmcia_device *link) static int daqp_cs_suspend(struct pcmcia_device *link)
{ {
struct local_info_t *local = link->priv; struct local_info_t *local = link->priv;
@ -1212,9 +1104,7 @@ static struct pcmcia_driver daqp_cs_driver = {
.resume = daqp_cs_resume, .resume = daqp_cs_resume,
.id_table = daqp_cs_id_table, .id_table = daqp_cs_id_table,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "quatech_daqp_cs",
.name = "quatech_daqp_cs",
},
}; };
int __init init_module(void) int __init init_module(void)

View file

@ -83,7 +83,6 @@
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>
@ -147,10 +146,9 @@ static int wl_adapter_attach(struct pcmcia_device *link)
link->resource[0]->end = HCF_NUM_IO_PORTS; link->resource[0]->end = HCF_NUM_IO_PORTS;
link->resource[0]->flags= IO_DATA_PATH_WIDTH_16; link->resource[0]->flags= IO_DATA_PATH_WIDTH_16;
link->conf.Attributes = CONF_ENABLE_IRQ; link->config_flags |= CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->config_index = 5;
link->conf.ConfigIndex = 5; link->config_regs = PRESENT_OPTION;
link->conf.Present = PRESENT_OPTION;
link->priv = dev; link->priv = dev;
lp = wl_priv(dev); lp = wl_priv(dev);
@ -165,27 +163,6 @@ static int wl_adapter_attach(struct pcmcia_device *link)
/*******************************************************************************
* wl_adapter_detach()
*******************************************************************************
*
* DESCRIPTION:
*
* This deletes a driver "instance". The device is de-registered with Card
* Services. If it has been released, then the net device is unregistered, and
* all local data structures are freed. Otherwise, the structures will be
* freed when the device is released.
*
* PARAMETERS:
*
* link - pointer to the dev_link_t structure representing the device to
* detach
*
* RETURNS:
*
* N/A
*
******************************************************************************/
static void wl_adapter_detach(struct pcmcia_device *link) static void wl_adapter_detach(struct pcmcia_device *link)
{ {
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
@ -209,26 +186,6 @@ static void wl_adapter_detach(struct pcmcia_device *link)
/*============================================================================*/ /*============================================================================*/
/*******************************************************************************
* wl_adapter_release()
*******************************************************************************
*
* DESCRIPTION:
*
* After a card is removed, this routine will release the PCMCIA
* configuration. If the device is still open, this will be postponed until it
* is closed.
*
* PARAMETERS:
*
* arg - a u_long representing a pointer to a dev_link_t structure for the
* device to be released.
*
* RETURNS:
*
* N/A
*
******************************************************************************/
void wl_adapter_release(struct pcmcia_device *link) void wl_adapter_release(struct pcmcia_device *link)
{ {
DBG_FUNC("wl_adapter_release"); DBG_FUNC("wl_adapter_release");
@ -268,26 +225,6 @@ static int wl_adapter_resume(struct pcmcia_device *link)
return 0; return 0;
} /* wl_adapter_resume */ } /* wl_adapter_resume */
/*******************************************************************************
* wl_adapter_insert()
*******************************************************************************
*
* DESCRIPTION:
*
* wl_adapter_insert() is scheduled to run after a CARD_INSERTION event is
* received, to configure the PCMCIA socket, and to make the ethernet device
* available to the system.
*
* PARAMETERS:
*
* link - pointer to the dev_link_t structure representing the device to
* insert
*
* RETURNS:
*
* N/A
*
******************************************************************************/
void wl_adapter_insert(struct pcmcia_device *link) void wl_adapter_insert(struct pcmcia_device *link)
{ {
struct net_device *dev; struct net_device *dev;
@ -302,7 +239,7 @@ void wl_adapter_insert(struct pcmcia_device *link)
dev = link->priv; dev = link->priv;
/* Do we need to allocate an interrupt? */ /* Do we need to allocate an interrupt? */
link->conf.Attributes |= CONF_ENABLE_IRQ; link->config_flags |= CONF_ENABLE_IRQ;
link->io_lines = 6; link->io_lines = 6;
ret = pcmcia_request_io(link); ret = pcmcia_request_io(link);
@ -313,7 +250,7 @@ void wl_adapter_insert(struct pcmcia_device *link)
if (ret != 0) if (ret != 0)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret != 0) if (ret != 0)
goto failed; goto failed;
@ -457,9 +394,7 @@ MODULE_DEVICE_TABLE(pcmcia, wl_adapter_ids);
static struct pcmcia_driver wlags49_driver = { static struct pcmcia_driver wlags49_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = DRIVER_NAME,
.name = DRIVER_NAME,
},
.probe = wl_adapter_attach, .probe = wl_adapter_attach,
.remove = wl_adapter_detach, .remove = wl_adapter_detach,
.id_table = wl_adapter_ids, .id_table = wl_adapter_ids,

View file

@ -69,7 +69,6 @@
******************************************************************************/ ******************************************************************************/
#include <linux/version.h> #include <linux/version.h>
#ifdef BUS_PCMCIA #ifdef BUS_PCMCIA
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ciscode.h> #include <pcmcia/ciscode.h>

View file

@ -414,25 +414,6 @@ extern memimage fw_image; // firmware image to be downloaded
#endif /* HCF_STA */ #endif /* HCF_STA */
/*******************************************************************************
* wl_insert()
*******************************************************************************
*
* DESCRIPTION:
*
* wl_insert() is scheduled to run after a CARD_INSERTION event is
* received, to configure the PCMCIA socket, and to make the ethernet device
* available to the system.
*
* PARAMETERS:
*
* dev - a pointer to the net_device struct of the wireless device
*
* RETURNS:
*
* TRUE or FALSE
*
******************************************************************************/
int wl_insert( struct net_device *dev ) int wl_insert( struct net_device *dev )
{ {
int result = 0; int result = 0;

View file

@ -8,7 +8,6 @@
#include <linux/errno.h> /* error codes */ #include <linux/errno.h> /* error codes */
#include <linux/slab.h> #include <linux/slab.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -32,9 +31,6 @@ static int ixj_probe(struct pcmcia_device *p_dev)
{ {
dev_dbg(&p_dev->dev, "ixj_attach()\n"); dev_dbg(&p_dev->dev, "ixj_attach()\n");
/* Create new ixj device */ /* Create new ixj device */
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
p_dev->priv = kzalloc(sizeof(struct ixj_info_t), GFP_KERNEL); p_dev->priv = kzalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
if (!p_dev->priv) { if (!p_dev->priv) {
return -ENOMEM; return -ENOMEM;
@ -111,40 +107,31 @@ failed:
return; return;
} }
static int ixj_config_check(struct pcmcia_device *p_dev, static int ixj_config_check(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->resource[0]->start = io->win[0].base; p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
p_dev->resource[0]->end = io->win[0].len; p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->io_lines = 3; p_dev->io_lines = 3;
if (io->nwin == 2) {
p_dev->resource[1]->start = io->win[1].base; return pcmcia_request_io(p_dev);
p_dev->resource[1]->end = io->win[1].len;
}
if (!pcmcia_request_io(p_dev))
return 0;
}
return -ENODEV;
} }
static int ixj_config(struct pcmcia_device * link) static int ixj_config(struct pcmcia_device * link)
{ {
IXJ *j; IXJ *j;
ixj_info_t *info; ixj_info_t *info;
cistpl_cftable_entry_t dflt = { 0 };
info = link->priv; info = link->priv;
dev_dbg(&link->dev, "ixj_config\n"); dev_dbg(&link->dev, "ixj_config\n");
if (pcmcia_loop_config(link, ixj_config_check, &dflt)) link->config_flags = CONF_AUTO_SET_IO;
if (pcmcia_loop_config(link, ixj_config_check, NULL))
goto failed; goto failed;
if (pcmcia_request_configuration(link, &link->conf)) if (pcmcia_enable_device(link))
goto failed; goto failed;
/* /*
@ -178,9 +165,7 @@ MODULE_DEVICE_TABLE(pcmcia, ixj_ids);
static struct pcmcia_driver ixj_driver = { static struct pcmcia_driver ixj_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "ixj_cs",
.name = "ixj_cs",
},
.probe = ixj_probe, .probe = ixj_probe,
.remove = ixj_detach, .remove = ixj_detach,
.id_table = ixj_ids, .id_table = ixj_ids,

View file

@ -20,7 +20,6 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h> #include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
@ -132,49 +131,12 @@ static void sl811_cs_release(struct pcmcia_device * link)
platform_device_unregister(&platform_dev); platform_device_unregister(&platform_dev);
} }
static int sl811_cs_config_check(struct pcmcia_device *p_dev, static int sl811_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{ {
if (cfg->index == 0) if (p_dev->config_index == 0)
return -ENODEV; return -EINVAL;
/* Use power settings for Vcc and Vpp if present */ return pcmcia_request_io(p_dev);
/* Note that the CIS values need to be rescaled */
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 != vcc)
return -ENODEV;
} else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) {
if (dflt->vcc.param[CISTPL_POWER_VNOM]/10000 != vcc)
return -ENODEV;
}
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
p_dev->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
p_dev->conf.Vpp =
dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
/* we need an interrupt */
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
p_dev->resource[0]->start = io->win[0].base;
p_dev->resource[0]->end = io->win[0].len;
return pcmcia_request_io(p_dev);
}
pcmcia_disable_device(p_dev);
return -ENODEV;
} }
@ -185,6 +147,9 @@ static int sl811_cs_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "sl811_cs_config\n"); dev_dbg(&link->dev, "sl811_cs_config\n");
link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
CONF_AUTO_CHECK_VCC | CONF_AUTO_SET_IO;
if (pcmcia_loop_config(link, sl811_cs_config_check, NULL)) if (pcmcia_loop_config(link, sl811_cs_config_check, NULL))
goto failed; goto failed;
@ -195,18 +160,10 @@ static int sl811_cs_config(struct pcmcia_device *link)
if (!link->irq) if (!link->irq)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
dev_info(&link->dev, "index 0x%02x: ",
link->conf.ConfigIndex);
if (link->conf.Vpp)
printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
printk(", irq %d", link->irq);
printk(", io %pR", link->resource[0]);
printk("\n");
if (sl811_hc_init(parent, link->resource[0]->start, link->irq) if (sl811_hc_init(parent, link->resource[0]->start, link->irq)
< 0) { < 0) {
failed: failed:
@ -227,9 +184,6 @@ static int sl811_cs_probe(struct pcmcia_device *link)
local->p_dev = link; local->p_dev = link;
link->priv = local; link->priv = local;
link->conf.Attributes = 0;
link->conf.IntType = INT_MEMORY_AND_IO;
return sl811_cs_config(link); return sl811_cs_config(link);
} }
@ -241,9 +195,7 @@ MODULE_DEVICE_TABLE(pcmcia, sl811_ids);
static struct pcmcia_driver sl811_cs_driver = { static struct pcmcia_driver sl811_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "sl811_cs",
.name = "sl811_cs",
},
.probe = sl811_cs_probe, .probe = sl811_cs_probe,
.remove = sl811_cs_detach, .remove = sl811_cs_detach,
.id_table = sl811_ids, .id_table = sl811_ids,

View file

@ -1,95 +0,0 @@
/*
* cs.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The initial developer of the original code is David A. Hinds
* <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
*
* (C) 1999 David A. Hinds
*/
#ifndef _LINUX_CS_H
#define _LINUX_CS_H
#ifdef __KERNEL__
#include <linux/interrupt.h>
#endif
/* ModifyConfiguration */
typedef struct modconf_t {
u_int Attributes;
u_int Vcc, Vpp1, Vpp2;
} modconf_t;
/* Attributes for ModifyConfiguration */
#define CONF_IRQ_CHANGE_VALID 0x0100
#define CONF_VCC_CHANGE_VALID 0x0200
#define CONF_VPP1_CHANGE_VALID 0x0400
#define CONF_VPP2_CHANGE_VALID 0x0800
#define CONF_IO_CHANGE_WIDTH 0x1000
/* For RequestConfiguration */
typedef struct config_req_t {
u_int Attributes;
u_int Vpp; /* both Vpp1 and Vpp2 */
u_int IntType;
u_int ConfigBase;
u_char Status, Pin, Copy, ExtStatus;
u_char ConfigIndex;
u_int Present;
} config_req_t;
/* Attributes for RequestConfiguration */
#define CONF_ENABLE_IRQ 0x01
#define CONF_ENABLE_DMA 0x02
#define CONF_ENABLE_SPKR 0x04
#define CONF_ENABLE_PULSE_IRQ 0x08
#define CONF_VALID_CLIENT 0x100
/* IntType field */
#define INT_MEMORY 0x01
#define INT_MEMORY_AND_IO 0x02
#define INT_CARDBUS 0x04
#define INT_ZOOMED_VIDEO 0x08
/* Configuration registers present */
#define PRESENT_OPTION 0x001
#define PRESENT_STATUS 0x002
#define PRESENT_PIN_REPLACE 0x004
#define PRESENT_COPY 0x008
#define PRESENT_EXT_STATUS 0x010
#define PRESENT_IOBASE_0 0x020
#define PRESENT_IOBASE_1 0x040
#define PRESENT_IOBASE_2 0x080
#define PRESENT_IOBASE_3 0x100
#define PRESENT_IOSIZE 0x200
/* For RequestWindow */
typedef struct win_req_t {
u_int Attributes;
u_long Base;
u_int Size;
u_int AccessSpeed;
} win_req_t;
/* Attributes for RequestWindow */
#define WIN_MEMORY_TYPE_CM 0x00 /* default */
#define WIN_MEMORY_TYPE_AM 0x20 /* MAP_ATTRIB */
#define WIN_DATA_WIDTH_8 0x00 /* default */
#define WIN_DATA_WIDTH_16 0x02 /* MAP_16BIT */
#define WIN_ENABLE 0x01 /* MAP_ACTIVE */
#define WIN_USE_WAIT 0x40 /* MAP_USE_WAIT */
#define WIN_FLAGS_MAP 0x63 /* MAP_ATTRIB | MAP_16BIT | MAP_ACTIVE |
MAP_USE_WAIT */
#define WIN_FLAGS_REQ 0x1c /* mapping to socket->win[i]:
0x04 -> 0
0x08 -> 1
0x0c -> 2
0x10 -> 3 */
#endif /* _LINUX_CS_H */

View file

@ -24,9 +24,11 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/device.h> #include <linux/device.h>
#include <linux/interrupt.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <asm/atomic.h> #include <asm/atomic.h>
/* /*
* PCMCIA device drivers (16-bit cards only; 32-bit cards require CardBus * PCMCIA device drivers (16-bit cards only; 32-bit cards require CardBus
* a.k.a. PCI drivers * a.k.a. PCI drivers
@ -36,8 +38,6 @@ struct pcmcia_device;
struct config_t; struct config_t;
struct net_device; struct net_device;
typedef struct resource *window_handle_t;
/* dynamic device IDs for PCMCIA device drivers. See /* dynamic device IDs for PCMCIA device drivers. See
* Documentation/pcmcia/driver.txt for details. * Documentation/pcmcia/driver.txt for details.
*/ */
@ -47,6 +47,8 @@ struct pcmcia_dynids {
}; };
struct pcmcia_driver { struct pcmcia_driver {
const char *name;
int (*probe) (struct pcmcia_device *dev); int (*probe) (struct pcmcia_device *dev);
void (*remove) (struct pcmcia_device *dev); void (*remove) (struct pcmcia_device *dev);
@ -90,15 +92,17 @@ struct pcmcia_device {
struct list_head socket_device_list; struct list_head socket_device_list;
/* deprecated, will be cleaned up soon */
config_req_t conf;
window_handle_t win;
/* device setup */ /* device setup */
unsigned int irq; unsigned int irq;
struct resource *resource[PCMCIA_NUM_RESOURCES]; struct resource *resource[PCMCIA_NUM_RESOURCES];
resource_size_t card_addr; /* for the 1st IOMEM resource */
unsigned int vpp;
unsigned int io_lines; /* number of I/O lines */ unsigned int config_flags; /* CONF_ENABLE_ flags below */
unsigned int config_base;
unsigned int config_index;
unsigned int config_regs; /* PRESENT_ flags below */
unsigned int io_lines; /* number of I/O lines */
/* Is the device suspended? */ /* Is the device suspended? */
u16 suspended:1; u16 suspended:1;
@ -174,9 +178,6 @@ int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse);
/* loop CIS entries for valid configuration */ /* loop CIS entries for valid configuration */
int pcmcia_loop_config(struct pcmcia_device *p_dev, int pcmcia_loop_config(struct pcmcia_device *p_dev,
int (*conf_check) (struct pcmcia_device *p_dev, int (*conf_check) (struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data), void *priv_data),
void *priv_data); void *priv_data);
@ -206,16 +207,17 @@ pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev,
int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev, int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev,
irq_handler_t handler); irq_handler_t handler);
int pcmcia_request_configuration(struct pcmcia_device *p_dev, int pcmcia_enable_device(struct pcmcia_device *p_dev);
config_req_t *req);
int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, int pcmcia_request_window(struct pcmcia_device *p_dev, struct resource *res,
window_handle_t *wh); unsigned int speed);
int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t win); int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res);
int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t win, int pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res,
unsigned int offset); unsigned int offset);
int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod); int pcmcia_fixup_vpp(struct pcmcia_device *p_dev, unsigned char new_vpp);
int pcmcia_fixup_iowidth(struct pcmcia_device *p_dev);
void pcmcia_disable_device(struct pcmcia_device *p_dev); void pcmcia_disable_device(struct pcmcia_device *p_dev);
/* IO ports */ /* IO ports */
@ -224,15 +226,46 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev);
#define IO_DATA_PATH_WIDTH_16 0x08 #define IO_DATA_PATH_WIDTH_16 0x08
#define IO_DATA_PATH_WIDTH_AUTO 0x10 #define IO_DATA_PATH_WIDTH_AUTO 0x10
/* convert flag found in cfgtable to data path width parameter */ /* IO memory */
static inline int pcmcia_io_cfg_data_width(unsigned int flags) #define WIN_MEMORY_TYPE_CM 0x00 /* default */
{ #define WIN_MEMORY_TYPE_AM 0x20 /* MAP_ATTRIB */
if (!(flags & CISTPL_IO_8BIT)) #define WIN_DATA_WIDTH_8 0x00 /* default */
return IO_DATA_PATH_WIDTH_16; #define WIN_DATA_WIDTH_16 0x02 /* MAP_16BIT */
if (!(flags & CISTPL_IO_16BIT)) #define WIN_ENABLE 0x01 /* MAP_ACTIVE */
return IO_DATA_PATH_WIDTH_8; #define WIN_USE_WAIT 0x40 /* MAP_USE_WAIT */
return IO_DATA_PATH_WIDTH_AUTO;
} #define WIN_FLAGS_MAP 0x63 /* MAP_ATTRIB | MAP_16BIT | MAP_ACTIVE |
MAP_USE_WAIT */
#define WIN_FLAGS_REQ 0x1c /* mapping to socket->win[i]:
0x04 -> 0
0x08 -> 1
0x0c -> 2
0x10 -> 3 */
/* config_reg{ister}s present for this PCMCIA device */
#define PRESENT_OPTION 0x001
#define PRESENT_STATUS 0x002
#define PRESENT_PIN_REPLACE 0x004
#define PRESENT_COPY 0x008
#define PRESENT_EXT_STATUS 0x010
#define PRESENT_IOBASE_0 0x020
#define PRESENT_IOBASE_1 0x040
#define PRESENT_IOBASE_2 0x080
#define PRESENT_IOBASE_3 0x100
#define PRESENT_IOSIZE 0x200
/* flags to be passed to pcmcia_enable_device() */
#define CONF_ENABLE_IRQ 0x0001
#define CONF_ENABLE_SPKR 0x0002
#define CONF_ENABLE_PULSE_IRQ 0x0004
#define CONF_ENABLE_ESR 0x0008
/* flags used by pcmcia_loop_config() autoconfiguration */
#define CONF_AUTO_CHECK_VCC 0x0100 /* check for matching Vcc? */
#define CONF_AUTO_SET_VPP 0x0200 /* set Vpp? */
#define CONF_AUTO_AUDIO 0x0400 /* enable audio line? */
#define CONF_AUTO_SET_IO 0x0800 /* set ->resource[0,1] */
#define CONF_AUTO_SET_IOMEM 0x1000 /* set ->resource[2] */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */

View file

@ -19,7 +19,6 @@
#include <linux/sched.h> /* task_struct, completion */ #include <linux/sched.h> /* task_struct, completion */
#include <linux/mutex.h> #include <linux/mutex.h>
#include <pcmcia/cs.h>
#ifdef CONFIG_CARDBUS #ifdef CONFIG_CARDBUS
#include <linux/pci.h> #include <linux/pci.h>
#endif #endif

View file

@ -142,10 +142,9 @@ static int snd_pdacf_probe(struct pcmcia_device *link)
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
link->resource[0]->end = 16; link->resource[0]->end = 16;
link->conf.Attributes = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ; link->config_flags = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->config_index = 1;
link->conf.ConfigIndex = 1; link->config_regs = PRESENT_OPTION;
link->conf.Present = PRESENT_OPTION;
return pdacf_config(link); return pdacf_config(link);
} }
@ -217,7 +216,8 @@ static int pdacf_config(struct pcmcia_device *link)
int ret; int ret;
snd_printdd(KERN_DEBUG "pdacf_config called\n"); snd_printdd(KERN_DEBUG "pdacf_config called\n");
link->conf.ConfigIndex = 0x5; link->config_index = 0x5;
link->config_flags |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
ret = pcmcia_request_io(link); ret = pcmcia_request_io(link);
if (ret) if (ret)
@ -227,7 +227,7 @@ static int pdacf_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
@ -287,9 +287,7 @@ MODULE_DEVICE_TABLE(pcmcia, snd_pdacf_ids);
static struct pcmcia_driver pdacf_cs_driver = { static struct pcmcia_driver pdacf_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "snd-pdaudiocf",
.name = "snd-pdaudiocf",
},
.probe = snd_pdacf_probe, .probe = snd_pdacf_probe,
.remove = snd_pdacf_detach, .remove = snd_pdacf_detach,
.id_table = snd_pdacf_ids, .id_table = snd_pdacf_ids,

View file

@ -24,7 +24,6 @@
#include <sound/pcm.h> #include <sound/pcm.h>
#include <asm/io.h> #include <asm/io.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>

View file

@ -2,7 +2,7 @@
* Driver for Digigram VXpocket V2/440 soundcards * Driver for Digigram VXpocket V2/440 soundcards
* *
* Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de> * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@ -162,10 +162,9 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl,
link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
link->resource[0]->end = 16; link->resource[0]->end = 16;
link->conf.Attributes = CONF_ENABLE_IRQ; link->config_flags |= CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO; link->config_index = 1;
link->conf.ConfigIndex = 1; link->config_regs = PRESENT_OPTION;
link->conf.Present = PRESENT_OPTION;
*chip_ret = vxp; *chip_ret = vxp;
return 0; return 0;
@ -234,7 +233,7 @@ static int vxpocket_config(struct pcmcia_device *link)
if (ret) if (ret)
goto failed; goto failed;
ret = pcmcia_request_configuration(link, &link->conf); ret = pcmcia_enable_device(link);
if (ret) if (ret)
goto failed; goto failed;
@ -359,9 +358,7 @@ MODULE_DEVICE_TABLE(pcmcia, vxp_ids);
static struct pcmcia_driver vxp_cs_driver = { static struct pcmcia_driver vxp_cs_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.drv = { .name = "snd-vxpocket",
.name = "snd-vxpocket",
},
.probe = vxpocket_probe, .probe = vxpocket_probe,
.remove = vxpocket_detach, .remove = vxpocket_detach,
.id_table = vxp_ids, .id_table = vxp_ids,

View file

@ -23,7 +23,6 @@
#include <sound/vx_core.h> #include <sound/vx_core.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>