dect
/
linux-2.6
Archived
13
0
Fork 0

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: (49 commits)
  pcmcia: ioctl-internal definitions
  pcmcia: cistpl header cleanup
  pcmcia: remove unused argument to pcmcia_parse_tuple()
  pcmcia: card services header cleanup
  pcmcia: device_id header cleanup
  pcmcia: encapsulate ioaddr_t
  pcmcia: cleanup device driver header file
  pcmcia: cleanup socket services header file
  pcmcia: merge ds_internal.h into cs_internal.h
  pcmcia: cleanup cs_internal.h
  pcmcia: cs_internal.h is internal
  pcmcia: use dev_printk for cs_error()
  pcmcia: remove CS_ error codes alltogether
  pcmcia: deprecate CS_BAD_TUPLE
  pcmcia: deprecate CS_BAD_ARGS
  pcmcia: deprecate CS_BAD_BASE, CS_BAD_IRQ, CS_BAD_OFFSET and CS_BAD_SIZE
  pcmcia: deprecate CS_BAD_ATTRIBUTE, CS_BAD_TYPE and CS_BAD_PAGE
  pcmcia: deprecate CS_NO_MORE_ITEMS
  pcmcia: deprecate CS_IN_USE
  pcmcia: deprecate CS_CONFIGURATION_LOCKED
  ...

Fix trivial conflict in drivers/pcmcia/ds.c manually
This commit is contained in:
Linus Torvalds 2008-10-13 14:12:40 -07:00
commit 2be4ff2f08
82 changed files with 3016 additions and 3301 deletions

View File

@ -1,5 +1,11 @@
This file details changes in 2.6 which affect PCMCIA card driver authors:
* New configuration loop helper (as of 2.6.28)
By calling pcmcia_loop_config(), a driver can iterate over all available
configuration options. During a driver's probe() phase, one doesn't need
to use pcmcia_get_{first,next}_tuple, pcmcia_get_tuple_data and
pcmcia_parse_tuple directly in most if not all cases.
* New release helper (as of 2.6.17)
Instead of calling pcmcia_release_{configuration,io,irq,win}, all that's
necessary now is calling pcmcia_disable_device. As there is no valid

View File

@ -148,6 +148,64 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
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;
/* Check for matching Vcc, unless we're desperate */
if (!stk->skip_vcc) {
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))
pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
pdev->io.BasePort1 = io->win[0].base;
pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
if (!(io->flags & CISTPL_IO_16BIT))
pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
if (io->nwin == 2) {
pdev->io.NumPorts1 = 8;
pdev->io.BasePort2 = io->win[1].base;
pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1;
if (pcmcia_request_io(pdev, &pdev->io) != 0)
return -ENODEV;
stk->ctl_base = pdev->io.BasePort2;
} else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
pdev->io.NumPorts1 = io->win[0].len;
pdev->io.NumPorts2 = 0;
if (pcmcia_request_io(pdev, &pdev->io) != 0)
return -ENODEV;
stk->ctl_base = pdev->io.BasePort1 + 0x0e;
} else
return -ENODEV;
/* If we've got this far, we're done */
return 0;
}
return -ENODEV;
}
/**
* pcmcia_init_one - attach a PCMCIA interface
* @pdev: pcmcia device
@ -161,19 +219,11 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
struct ata_host *host;
struct ata_port *ap;
struct ata_pcmcia_info *info;
tuple_t tuple;
struct {
unsigned short buf[128];
cisparse_t parse;
config_info_t conf;
cistpl_cftable_entry_t dflt;
} *stk = NULL;
cistpl_cftable_entry_t *cfg;
int pass, last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p;
struct pcmcia_config_check *stk = NULL;
int last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p;
unsigned long io_base, ctl_base;
void __iomem *io_addr, *ctl_addr;
int n_ports = 1;
struct ata_port_operations *ops = &pcmcia_port_ops;
info = kzalloc(sizeof(*info), GFP_KERNEL);
@ -193,96 +243,27 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
pdev->conf.Attributes = CONF_ENABLE_IRQ;
pdev->conf.IntType = INT_MEMORY_AND_IO;
/* Allocate resoure probing structures */
stk = kzalloc(sizeof(*stk), GFP_KERNEL);
if (!stk)
goto out1;
cfg = &stk->parse.cftable_entry;
/* Tuples we are walking */
tuple.TupleData = (cisdata_t *)&stk->buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
tuple.Attributes = 0;
/* See if we have a manufacturer identifier. Use it to set is_kme for
vendor quirks */
is_kme = ((pdev->manf_id == MANFID_KME) &&
((pdev->card_id == PRODID_KME_KXLC005_A) ||
(pdev->card_id == PRODID_KME_KXLC005_B)));
/* Not sure if this is right... look up the current Vcc */
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(pdev, &stk->conf));
/* link->conf.Vcc = stk->conf.Vcc; */
/* Allocate resoure probing structures */
pass = io_base = ctl_base = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
stk = kzalloc(sizeof(*stk), GFP_KERNEL);
if (!stk)
goto out1;
stk->is_kme = is_kme;
stk->skip_vcc = io_base = ctl_base = 0;
/* Now munch the resources looking for a suitable set */
while (1) {
if (pcmcia_get_tuple_data(pdev, &tuple) != 0)
goto next_entry;
if (pcmcia_parse_tuple(pdev, &tuple, &stk->parse) != 0)
goto next_entry;
/* Check for matching Vcc, unless we're desperate */
if (!pass) {
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
goto next_entry;
} else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
goto next_entry;
}
}
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
pdev->conf.Vpp = stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
pdev->conf.ConfigIndex = cfg->index;
pdev->io.BasePort1 = io->win[0].base;
pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
if (!(io->flags & CISTPL_IO_16BIT))
pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
if (io->nwin == 2) {
pdev->io.NumPorts1 = 8;
pdev->io.BasePort2 = io->win[1].base;
pdev->io.NumPorts2 = (is_kme) ? 2 : 1;
if (pcmcia_request_io(pdev, &pdev->io) != 0)
goto next_entry;
io_base = pdev->io.BasePort1;
ctl_base = pdev->io.BasePort2;
} else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
pdev->io.NumPorts1 = io->win[0].len;
pdev->io.NumPorts2 = 0;
if (pcmcia_request_io(pdev, &pdev->io) != 0)
goto next_entry;
io_base = pdev->io.BasePort1;
ctl_base = pdev->io.BasePort1 + 0x0e;
} else
goto next_entry;
/* If we've got this far, we're done */
break;
}
next_entry:
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
if (pass) {
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(pdev, &tuple));
} else if (pcmcia_get_next_tuple(pdev, &tuple) != 0) {
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
memset(&stk->dflt, 0, sizeof(stk->dflt));
pass++;
}
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 */
}
io_base = pdev->io.BasePort1;
ctl_base = stk->ctl_base;
CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf));
@ -384,6 +365,7 @@ static struct pcmcia_device_id pcmcia_devices[] = {
PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904),
PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */
PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */
PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */
PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
@ -404,9 +386,9 @@ static struct pcmcia_device_id pcmcia_devices[] = {
PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591),
PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),

View File

@ -901,23 +901,23 @@ static int bluecard_config(struct pcmcia_device *link)
for (n = 0; n < 0x400; n += 0x40) {
link->io.BasePort1 = n ^ 0x300;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
if (i == 0)
break;
}
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestIO, i);
goto failed;
}
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestIRQ, i);
link->irq.AssignedIRQ = 0;
}
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestConfiguration, i);
goto failed;
}

View File

@ -678,101 +678,78 @@ static void bt3c_detach(struct pcmcia_device *link)
kfree(info);
}
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
static int bt3c_check_config(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
int i;
unsigned long try = (unsigned long) priv_data;
i = pcmcia_get_tuple_data(handle, tuple);
if (i != CS_SUCCESS)
return i;
return pcmcia_parse_tuple(handle, tuple, parse);
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
(cf->io.win[0].base != 0)) {
p_dev->io.BasePort1 = cf->io.win[0].base;
p_dev->io.IOAddrLines = (try == 0) ? 16 :
cf->io.flags & CISTPL_IO_LINES_MASK;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
return -ENODEV;
}
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS)
return CS_NO_MORE_ITEMS;
return get_tuple(handle, tuple, parse);
}
static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
int j;
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
{
if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
return CS_NO_MORE_ITEMS;
return get_tuple(handle, tuple, parse);
if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
for (j = 0; j < 5; j++) {
p_dev->io.BasePort1 = base[j];
p_dev->io.IOAddrLines = base[j] ? 16 : 3;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
}
return -ENODEV;
}
static int bt3c_config(struct pcmcia_device *link)
{
static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
bt3c_info_t *info = link->priv;
tuple_t tuple;
u_short buf[256];
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
int i, j, try;
int i;
unsigned long try;
/* First pass: look for a config entry that looks normal. */
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
/* Two tries: without IO aliases, then with aliases */
for (try = 0; try < 2; try++) {
i = first_tuple(link, &tuple, &parse);
while (i != CS_NO_MORE_ITEMS) {
if (i != CS_SUCCESS)
goto next_entry;
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
goto found_port;
}
next_entry:
i = next_tuple(link, &tuple, &parse);
}
}
/* First pass: look for a config entry that looks normal.
Two tries: without IO aliases, then with aliases */
for (try = 0; try < 2; try++)
if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))
goto found_port;
/* Second pass: try to find an entry that isn't picky about
its base address, then try to grab any standard serial port
address, and finally try to get any free port. */
i = first_tuple(link, &tuple, &parse);
while (i != CS_NO_MORE_ITEMS) {
if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
link->conf.ConfigIndex = cf->index;
for (j = 0; j < 5; j++) {
link->io.BasePort1 = base[j];
link->io.IOAddrLines = base[j] ? 16 : 3;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
goto found_port;
}
}
i = next_tuple(link, &tuple, &parse);
}
if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))
goto found_port;
BT_ERR("No usable port range found");
cs_error(link, RequestIO, -ENODEV);
goto failed;
found_port:
if (i != CS_SUCCESS) {
BT_ERR("No usable port range found");
cs_error(link, RequestIO, i);
goto failed;
}
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestIRQ, i);
link->irq.AssignedIRQ = 0;
}
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestConfiguration, i);
goto failed;
}

View File

@ -607,102 +607,78 @@ static void btuart_detach(struct pcmcia_device *link)
kfree(info);
}
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
static int btuart_check_config(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
int i;
int *try = priv_data;
i = pcmcia_get_tuple_data(handle, tuple);
if (i != CS_SUCCESS)
return i;
return pcmcia_parse_tuple(handle, tuple, parse);
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
(cf->io.win[0].base != 0)) {
p_dev->io.BasePort1 = cf->io.win[0].base;
p_dev->io.IOAddrLines = (*try == 0) ? 16 :
cf->io.flags & CISTPL_IO_LINES_MASK;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
return -ENODEV;
}
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
static int btuart_check_config_notpicky(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS)
return CS_NO_MORE_ITEMS;
return get_tuple(handle, tuple, parse);
}
static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
int j;
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
{
if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
return CS_NO_MORE_ITEMS;
return get_tuple(handle, tuple, parse);
if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
for (j = 0; j < 5; j++) {
p_dev->io.BasePort1 = base[j];
p_dev->io.IOAddrLines = base[j] ? 16 : 3;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
}
return -ENODEV;
}
static int btuart_config(struct pcmcia_device *link)
{
static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
btuart_info_t *info = link->priv;
tuple_t tuple;
u_short buf[256];
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
int i, j, try;
int i;
int try;
/* First pass: look for a config entry that looks normal. */
tuple.TupleData = (cisdata_t *) buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
/* Two tries: without IO aliases, then with aliases */
for (try = 0; try < 2; try++) {
i = first_tuple(link, &tuple, &parse);
while (i != CS_NO_MORE_ITEMS) {
if (i != CS_SUCCESS)
goto next_entry;
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
goto found_port;
}
next_entry:
i = next_tuple(link, &tuple, &parse);
}
}
/* First pass: look for a config entry that looks normal.
Two tries: without IO aliases, then with aliases */
for (try = 0; try < 2; try++)
if (!pcmcia_loop_config(link, btuart_check_config, &try))
goto found_port;
/* Second pass: try to find an entry that isn't picky about
its base address, then try to grab any standard serial port
address, and finally try to get any free port. */
i = first_tuple(link, &tuple, &parse);
while (i != CS_NO_MORE_ITEMS) {
if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
&& ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
link->conf.ConfigIndex = cf->index;
for (j = 0; j < 5; j++) {
link->io.BasePort1 = base[j];
link->io.IOAddrLines = base[j] ? 16 : 3;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
goto found_port;
}
}
i = next_tuple(link, &tuple, &parse);
}
if (!pcmcia_loop_config(link, btuart_check_config_notpicky, NULL))
goto found_port;
BT_ERR("No usable port range found");
cs_error(link, RequestIO, -ENODEV);
goto failed;
found_port:
if (i != CS_SUCCESS) {
BT_ERR("No usable port range found");
cs_error(link, RequestIO, i);
goto failed;
}
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestIRQ, i);
link->irq.AssignedIRQ = 0;
}
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestConfiguration, i);
goto failed;
}

View File

@ -590,75 +590,40 @@ static void dtl1_detach(struct pcmcia_device *link)
kfree(info);
}
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
static int dtl1_confcheck(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
int i;
i = pcmcia_get_tuple_data(handle, tuple);
if (i != CS_SUCCESS)
return i;
return pcmcia_parse_tuple(handle, tuple, parse);
}
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
{
if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS)
return CS_NO_MORE_ITEMS;
return get_tuple(handle, tuple, parse);
}
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
{
if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
return CS_NO_MORE_ITEMS;
return get_tuple(handle, tuple, parse);
if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
p_dev->io.BasePort1 = cf->io.win[0].base;
p_dev->io.NumPorts1 = cf->io.win[0].len; /*yo */
p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
return -ENODEV;
}
static int dtl1_config(struct pcmcia_device *link)
{
dtl1_info_t *info = link->priv;
tuple_t tuple;
u_short buf[256];
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
int i;
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
/* Look for a generic full-sized window */
link->io.NumPorts1 = 8;
i = first_tuple(link, &tuple, &parse);
while (i != CS_NO_MORE_ITEMS) {
if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
link->io.NumPorts1 = cf->io.win[0].len; /*yo */
link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
break;
}
i = next_tuple(link, &tuple, &parse);
}
if (i != CS_SUCCESS) {
cs_error(link, RequestIO, i);
if (!pcmcia_loop_config(link, dtl1_confcheck, NULL))
goto failed;
}
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestIRQ, i);
link->irq.AssignedIRQ = 0;
}
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestConfiguration, i);
goto failed;
}

View File

@ -1759,65 +1759,40 @@ static void cmm_cm4000_release(struct pcmcia_device * link)
/*==== Interface to PCMCIA Layer =======================================*/
static int cm4000_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
if (!cfg->io.nwin)
return -ENODEV;
/* Get the IOaddr */
p_dev->io.BasePort1 = cfg->io.win[0].base;
p_dev->io.NumPorts1 = cfg->io.win[0].len;
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(cfg->io.flags & CISTPL_IO_8BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(cfg->io.flags & CISTPL_IO_16BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
return pcmcia_request_io(p_dev, &p_dev->io);
}
static int cm4000_config(struct pcmcia_device * link, int devno)
{
struct cm4000_dev *dev;
tuple_t tuple;
cisparse_t parse;
u_char buf[64];
int fail_fn, fail_rc;
int rc;
/* read the config-tuples */
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
link->io.BasePort2 = 0;
link->io.NumPorts2 = 0;
link->io.Attributes2 = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
for (rc = pcmcia_get_first_tuple(link, &tuple);
rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(link, &tuple)) {
rc = pcmcia_get_tuple_data(link, &tuple);
if (rc != CS_SUCCESS)
continue;
rc = pcmcia_parse_tuple(link, &tuple, &parse);
if (rc != CS_SUCCESS)
continue;
link->conf.ConfigIndex = parse.cftable_entry.index;
if (!parse.cftable_entry.io.nwin)
continue;
/* Get the IOaddr */
link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines = parse.cftable_entry.io.flags
& CISTPL_IO_LINES_MASK;
rc = pcmcia_request_io(link, &link->io);
if (rc == CS_SUCCESS)
break; /* we are done */
}
if (rc != CS_SUCCESS)
if (pcmcia_loop_config(link, cm4000_config_check, NULL))
goto cs_release;
link->conf.IntType = 00000002;
if ((fail_rc =
pcmcia_request_configuration(link, &link->conf)) != CS_SUCCESS) {
fail_fn = RequestConfiguration;
if (pcmcia_request_configuration(link, &link->conf))
goto cs_release;
}
dev = link->priv;
sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno);

View File

@ -526,65 +526,49 @@ static void cm4040_reader_release(struct pcmcia_device *link)
return;
}
static int cm4040_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
int rc;
if (!cfg->io.nwin)
return -ENODEV;
/* Get the IOaddr */
p_dev->io.BasePort1 = cfg->io.win[0].base;
p_dev->io.NumPorts1 = cfg->io.win[0].len;
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(cfg->io.flags & CISTPL_IO_8BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(cfg->io.flags & CISTPL_IO_16BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
rc = pcmcia_request_io(p_dev, &p_dev->io);
dev_printk(KERN_INFO, &handle_to_dev(p_dev),
"pcmcia_request_io returned 0x%x\n", rc);
return rc;
}
static int reader_config(struct pcmcia_device *link, int devno)
{
struct reader_dev *dev;
tuple_t tuple;
cisparse_t parse;
u_char buf[64];
int fail_fn, fail_rc;
int rc;
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
int fail_rc;
link->io.BasePort2 = 0;
link->io.NumPorts2 = 0;
link->io.Attributes2 = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
for (rc = pcmcia_get_first_tuple(link, &tuple);
rc == CS_SUCCESS;
rc = pcmcia_get_next_tuple(link, &tuple)) {
rc = pcmcia_get_tuple_data(link, &tuple);
if (rc != CS_SUCCESS)
continue;
rc = pcmcia_parse_tuple(link, &tuple, &parse);
if (rc != CS_SUCCESS)
continue;
link->conf.ConfigIndex = parse.cftable_entry.index;
if (!parse.cftable_entry.io.nwin)
continue;
link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines = parse.cftable_entry.io.flags
& CISTPL_IO_LINES_MASK;
rc = pcmcia_request_io(link, &link->io);
dev_printk(KERN_INFO, &handle_to_dev(link), "foo");
if (rc == CS_SUCCESS)
break;
else
dev_printk(KERN_INFO, &handle_to_dev(link),
"pcmcia_request_io failed 0x%x\n", rc);
}
if (rc != CS_SUCCESS)
if (pcmcia_loop_config(link, cm4040_config_check, NULL))
goto cs_release;
link->conf.IntType = 00000002;
if ((fail_rc = pcmcia_request_configuration(link,&link->conf))
!=CS_SUCCESS) {
fail_fn = RequestConfiguration;
fail_rc = pcmcia_request_configuration(link, &link->conf);
if (fail_rc != 0) {
dev_printk(KERN_INFO, &handle_to_dev(link),
"pcmcia_request_configuration failed 0x%x\n",
fail_rc);

View File

@ -65,9 +65,9 @@ static void signalled_reboot_work(struct work_struct *work_reboot)
struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev,
work_reboot);
struct pcmcia_device *link = ipw->link;
int ret = pccard_reset_card(link->socket);
int ret = pcmcia_reset_card(link->socket);
if (ret != CS_SUCCESS)
if (ret != 0)
cs_error(link, ResetCard, ret);
}
@ -83,7 +83,6 @@ static int config_ipwireless(struct ipw_dev *ipw)
{
struct pcmcia_device *link = ipw->link;
int ret;
config_info_t conf;
tuple_t tuple;
unsigned short buf[64];
cisparse_t parse;
@ -105,7 +104,7 @@ static int config_ipwireless(struct ipw_dev *ipw)
while (ret == 0) {
ret = pcmcia_get_tuple_data(link, &tuple);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, GetTupleData, ret);
goto exit0;
}
@ -116,21 +115,21 @@ static int config_ipwireless(struct ipw_dev *ipw)
ret = pcmcia_get_first_tuple(link, &tuple);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, GetFirstTuple, ret);
goto exit0;
}
ret = pcmcia_get_tuple_data(link, &tuple);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, GetTupleData, ret);
goto exit0;
}
ret = pcmcia_parse_tuple(link, &tuple, &parse);
ret = pcmcia_parse_tuple(&tuple, &parse);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, ParseTuple, ret);
goto exit0;
}
@ -152,21 +151,21 @@ static int config_ipwireless(struct ipw_dev *ipw)
ret = pcmcia_get_first_tuple(link, &tuple);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, GetFirstTuple, ret);
goto exit0;
}
ret = pcmcia_get_tuple_data(link, &tuple);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, GetTupleData, ret);
goto exit0;
}
ret = pcmcia_parse_tuple(link, &tuple, &parse);
ret = pcmcia_parse_tuple(&tuple, &parse);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, GetTupleData, ret);
goto exit0;
}
@ -181,7 +180,7 @@ static int config_ipwireless(struct ipw_dev *ipw)
ret = pcmcia_request_io(link, &link->io);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, RequestIO, ret);
goto exit0;
}
@ -195,21 +194,21 @@ static int config_ipwireless(struct ipw_dev *ipw)
ret = pcmcia_get_first_tuple(link, &tuple);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, GetFirstTuple, ret);
goto exit1;
}
ret = pcmcia_get_tuple_data(link, &tuple);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, GetTupleData, ret);
goto exit1;
}
ret = pcmcia_parse_tuple(link, &tuple, &parse);
ret = pcmcia_parse_tuple(&tuple, &parse);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, ParseTuple, ret);
goto exit1;
}
@ -227,7 +226,7 @@ static int config_ipwireless(struct ipw_dev *ipw)
ret = pcmcia_request_window(&link, &ipw->request_common_memory,
&ipw->handle_common_memory);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, RequestWindow, ret);
goto exit1;
}
@ -239,7 +238,7 @@ static int config_ipwireless(struct ipw_dev *ipw)
ret = pcmcia_map_mem_page(ipw->handle_common_memory,
&memreq_common_memory);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, MapMemPage, ret);
goto exit1;
}
@ -261,7 +260,7 @@ static int config_ipwireless(struct ipw_dev *ipw)
ret = pcmcia_request_window(&link, &ipw->request_attr_memory,
&ipw->handle_attr_memory);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, RequestWindow, ret);
goto exit2;
}
@ -272,7 +271,7 @@ static int config_ipwireless(struct ipw_dev *ipw)
ret = pcmcia_map_mem_page(ipw->handle_attr_memory,
&memreq_attr_memory);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, MapMemPage, ret);
goto exit2;
}
@ -292,20 +291,11 @@ static int config_ipwireless(struct ipw_dev *ipw)
ret = pcmcia_request_irq(link, &link->irq);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, RequestIRQ, ret);
goto exit3;
}
/* Look up current Vcc */
ret = pcmcia_get_configuration_info(link, &conf);
if (ret != CS_SUCCESS) {
cs_error(link, GetConfigurationInfo, ret);
goto exit4;
}
printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n",
ipw->is_v2_card ? "V2/V3" : "V1");
printk(KERN_INFO IPWIRELESS_PCCARD_NAME
@ -341,7 +331,7 @@ static int config_ipwireless(struct ipw_dev *ipw)
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, RequestConfiguration, ret);
goto exit4;
}

View File

@ -601,7 +601,7 @@ static int mgslpc_config(struct pcmcia_device *link)
cfg = &(parse.cftable_entry);
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
if (cfg->index == 0)

View File

@ -219,103 +219,91 @@ out_release:
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
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;
/* Check for matching Vcc, unless we're desperate */
if (!stk->skip_vcc) {
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))
pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
pdev->conf.ConfigIndex = cfg->index;
pdev->io.BasePort1 = io->win[0].base;
pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
if (!(io->flags & CISTPL_IO_16BIT))
pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
if (io->nwin == 2) {
pdev->io.NumPorts1 = 8;
pdev->io.BasePort2 = io->win[1].base;
pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1;
if (pcmcia_request_io(pdev, &pdev->io) != 0)
return -ENODEV;
stk->ctl_base = pdev->io.BasePort2;
} else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
pdev->io.NumPorts1 = io->win[0].len;
pdev->io.NumPorts2 = 0;
if (pcmcia_request_io(pdev, &pdev->io) != 0)
return -ENODEV;
stk->ctl_base = pdev->io.BasePort1 + 0x0e;
} else
return -ENODEV;
/* If we've got this far, we're done */
return 0;
}
return -ENODEV;
}
static int ide_config(struct pcmcia_device *link)
{
ide_info_t *info = link->priv;
tuple_t tuple;
struct {
u_short buf[128];
cisparse_t parse;
config_info_t conf;
cistpl_cftable_entry_t dflt;
} *stk = NULL;
cistpl_cftable_entry_t *cfg;
int pass, last_ret = 0, last_fn = 0, is_kme = 0;
struct pcmcia_config_check *stk = NULL;
int last_ret = 0, last_fn = 0, is_kme = 0;
unsigned long io_base, ctl_base;
struct ide_host *host;
DEBUG(0, "ide_config(0x%p)\n", link);
stk = kzalloc(sizeof(*stk), GFP_KERNEL);
if (!stk) goto err_mem;
cfg = &stk->parse.cftable_entry;
tuple.TupleData = (cisdata_t *)&stk->buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
tuple.Attributes = 0;
is_kme = ((link->manf_id == MANFID_KME) &&
((link->card_id == PRODID_KME_KXLC005_A) ||
(link->card_id == PRODID_KME_KXLC005_B)));
/* Not sure if this is right... look up the current Vcc */
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf));
stk = kzalloc(sizeof(*stk), GFP_KERNEL);
if (!stk)
goto err_mem;
stk->is_kme = is_kme;
stk->skip_vcc = io_base = ctl_base = 0;
pass = io_base = ctl_base = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
if (pcmcia_get_tuple_data(link, &tuple) != 0) goto next_entry;
if (pcmcia_parse_tuple(link, &tuple, &stk->parse) != 0) goto next_entry;
/* Check for matching Vcc, unless we're desperate */
if (!pass) {
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
goto next_entry;
} else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
goto next_entry;
}
}
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp =
stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
link->conf.ConfigIndex = cfg->index;
link->io.BasePort1 = io->win[0].base;
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
if (!(io->flags & CISTPL_IO_16BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
if (io->nwin == 2) {
link->io.NumPorts1 = 8;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = (is_kme) ? 2 : 1;
if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry;
io_base = link->io.BasePort1;
ctl_base = link->io.BasePort2;
} else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
link->io.NumPorts1 = io->win[0].len;
link->io.NumPorts2 = 0;
if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry;
io_base = link->io.BasePort1;
ctl_base = link->io.BasePort1 + 0x0e;
} else goto next_entry;
/* If we've got this far, we're done */
break;
}
next_entry:
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
if (pass) {
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
} else if (pcmcia_get_next_tuple(link, &tuple) != 0) {
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
memset(&stk->dflt, 0, sizeof(stk->dflt));
pass++;
}
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 */
}
io_base = link->io.BasePort1;
ctl_base = stk->ctl_base;
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
@ -403,8 +391,10 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000), /* I-O Data CFA */
PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001), /* Mitsubishi CFA */
PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904),
PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */
PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */
PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */
PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */

View File

@ -154,83 +154,50 @@ static void avmcs_detach(struct pcmcia_device *link)
======================================================================*/
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
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)
{
int i = pcmcia_get_tuple_data(handle, tuple);
if (i != CS_SUCCESS) return i;
return pcmcia_parse_tuple(handle, tuple, parse);
}
if (cf->io.nwin <= 0)
return -ENODEV;
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_first_tuple(handle, tuple);
if (i != CS_SUCCESS) return i;
return get_tuple(handle, tuple, parse);
}
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_next_tuple(handle, tuple);
if (i != CS_SUCCESS) return i;
return get_tuple(handle, tuple, parse);
p_dev->io.BasePort1 = cf->io.win[0].base;
p_dev->io.NumPorts1 = cf->io.win[0].len;
p_dev->io.NumPorts2 = 0;
printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
p_dev->io.BasePort1,
p_dev->io.BasePort1+p_dev->io.NumPorts1-1);
return pcmcia_request_io(p_dev, &p_dev->io);
}
static int avmcs_config(struct pcmcia_device *link)
{
tuple_t tuple;
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
local_info_t *dev;
int i;
u_char buf[64];
char devname[128];
int cardtype;
int (*addcard)(unsigned int port, unsigned irq);
dev = link->priv;
devname[0] = 0;
if (link->prod_id[1])
strlcpy(devname, link->prod_id[1], sizeof(devname));
/*
* find IO port
*/
if (pcmcia_loop_config(link, avmcs_configcheck, NULL))
return -ENODEV;
do {
devname[0] = 0;
if (link->prod_id[1])
strlcpy(devname, link->prod_id[1], sizeof(devname));
/*
* find IO port
*/
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
i = first_tuple(link, &tuple, &parse);
while (i == CS_SUCCESS) {
if (cf->io.nwin > 0) {
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
link->io.NumPorts1 = cf->io.win[0].len;
link->io.NumPorts2 = 0;
printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1);
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) goto found_port;
}
i = next_tuple(link, &tuple, &parse);
}
found_port:
if (i != CS_SUCCESS) {
cs_error(link, RequestIO, i);
break;
}
/*
* allocate an interrupt line
*/
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestIRQ, i);
/* undo */
pcmcia_disable_device(link);
@ -241,7 +208,7 @@ found_port:
* configure the PCMCIA socket
*/
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestConfiguration, i);
pcmcia_disable_device(link);
break;

View File

@ -174,38 +174,29 @@ static void avma1cs_detach(struct pcmcia_device *link)
======================================================================*/
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
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)
{
int i = pcmcia_get_tuple_data(handle, tuple);
if (i != CS_SUCCESS) return i;
return pcmcia_parse_tuple(handle, tuple, parse);
if (cf->io.nwin <= 0)
return -ENODEV;
p_dev->io.BasePort1 = cf->io.win[0].base;
p_dev->io.NumPorts1 = cf->io.win[0].len;
p_dev->io.NumPorts2 = 0;
printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
p_dev->io.BasePort1,
p_dev->io.BasePort1+p_dev->io.NumPorts1-1);
return pcmcia_request_io(p_dev, &p_dev->io);
}
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_first_tuple(handle, tuple);
if (i != CS_SUCCESS) return i;
return get_tuple(handle, tuple, parse);
}
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_next_tuple(handle, tuple);
if (i != CS_SUCCESS) return i;
return get_tuple(handle, tuple, parse);
}
static int avma1cs_config(struct pcmcia_device *link)
{
tuple_t tuple;
cisparse_t parse;
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
local_info_t *dev;
int i;
u_char buf[64];
char devname[128];
IsdnCard_t icard;
int busy = 0;
@ -214,45 +205,19 @@ static int avma1cs_config(struct pcmcia_device *link)
DEBUG(0, "avma1cs_config(0x%p)\n", link);
devname[0] = 0;
if (link->prod_id[1])
strlcpy(devname, link->prod_id[1], sizeof(devname));
if (pcmcia_loop_config(link, avma1cs_configcheck, NULL))
return -ENODEV;
do {
devname[0] = 0;
if (link->prod_id[1])
strlcpy(devname, link->prod_id[1], sizeof(devname));
/*
* find IO port
*/
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
i = first_tuple(link, &tuple, &parse);
while (i == CS_SUCCESS) {
if (cf->io.nwin > 0) {
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
link->io.NumPorts1 = cf->io.win[0].len;
link->io.NumPorts2 = 0;
printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1 - 1);
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) goto found_port;
}
i = next_tuple(link, &tuple, &parse);
}
found_port:
if (i != CS_SUCCESS) {
cs_error(link, RequestIO, i);
break;
}
/*
* allocate an interrupt line
*/
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestIRQ, i);
/* undo */
pcmcia_disable_device(link);
@ -263,7 +228,7 @@ found_port:
* configure the PCMCIA socket
*/
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestConfiguration, i);
pcmcia_disable_device(link);
break;

View File

@ -203,82 +203,55 @@ static void elsa_cs_detach(struct pcmcia_device *link)
device available to the system.
======================================================================*/
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_tuple_data(handle, tuple);
if (i != CS_SUCCESS) return i;
return pcmcia_parse_tuple(handle, tuple, parse);
}
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
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 i = pcmcia_get_first_tuple(handle, tuple);
if (i != CS_SUCCESS) return i;
return get_tuple(handle, tuple, parse);
}
int j;
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_next_tuple(handle, tuple);
if (i != CS_SUCCESS) return i;
return get_tuple(handle, tuple, parse);
if ((cf->io.nwin > 0) && cf->io.win[0].base) {
printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
p_dev->io.BasePort1 = cf->io.win[0].base;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
} else {
printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
for (j = 0x2f0; j > 0x100; j -= 0x10) {
p_dev->io.BasePort1 = j;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
}
return -ENODEV;
}
static int elsa_cs_config(struct pcmcia_device *link)
{
tuple_t tuple;
cisparse_t parse;
local_info_t *dev;
int i, j, last_fn;
u_short buf[128];
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
int i, last_fn;
IsdnCard_t icard;
DEBUG(0, "elsa_config(0x%p)\n", link);
dev = link->priv;
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
i = first_tuple(link, &tuple, &parse);
while (i == CS_SUCCESS) {
if ( (cf->io.nwin > 0) && cf->io.win[0].base) {
printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
} else {
printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
link->conf.ConfigIndex = cf->index;
for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
link->io.BasePort1 = j;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
}
break;
}
i = next_tuple(link, &tuple, &parse);
}
if (i != CS_SUCCESS) {
i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
if (i != 0) {
last_fn = RequestIO;
goto cs_failed;
}
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
if (i != 0) {
link->irq.AssignedIRQ = 0;
last_fn = RequestIRQ;
goto cs_failed;
}
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
if (i != 0) {
last_fn = RequestConfiguration;
goto cs_failed;
}

View File

@ -217,101 +217,61 @@ static void sedlbauer_detach(struct pcmcia_device *link)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static int sedlbauer_config(struct pcmcia_device *link)
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)
{
local_info_t *dev = link->priv;
tuple_t tuple;
cisparse_t parse;
int last_fn, last_ret;
u8 buf[64];
config_info_t conf;
win_req_t req;
memreq_t map;
IsdnCard_t icard;
win_req_t *req = priv_data;
DEBUG(0, "sedlbauer_config(0x%p)\n", link);
if (cfg->index == 0)
return -ENODEV;
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));
/*
In this loop, we scan the CIS for configuration table 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.
*/
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
cistpl_cftable_entry_t dflt = { 0 };
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
goto next_entry;
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
if (cfg->index == 0) goto next_entry;
link->conf.ConfigIndex = cfg->index;
/* Does this card need audio output? */
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
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 (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
goto next_entry;
} else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000)
goto next_entry;
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))
link->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
link->conf.Vpp =
dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
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? */
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
link->conf.Attributes |= CONF_ENABLE_IRQ;
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
link->io.NumPorts1 = link->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
/* new in dummy.cs 2001/01/28 MN
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
*/
link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
link->io.Attributes2 = link->io.Attributes1;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry;
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.BasePort1 = io->win[0].base;
p_dev->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
p_dev->io.Attributes2 = p_dev->io.Attributes1;
p_dev->io.BasePort2 = io->win[1].base;
p_dev->io.NumPorts2 = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
return -ENODEV;
}
/*
@ -325,30 +285,54 @@ static int sedlbauer_config(struct pcmcia_device *link)
needs to be mapped to virtual space with ioremap() before it
is used.
*/
if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
cistpl_mem_t *mem =
(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
req.Attributes |= WIN_ENABLE;
req.Base = mem->win[0].host_addr;
req.Size = mem->win[0].len;
/* new in dummy.cs 2001/01/28 MN
if (req.Size < 0x1000)
req.Size = 0x1000;
*/
req.AccessSpeed = 0;
if (pcmcia_request_window(&link, &req, &link->win) != 0)
goto next_entry;
map.Page = 0; map.CardOffset = mem->win[0].card_addr;
if (pcmcia_map_mem_page(link->win, &map) != 0)
goto next_entry;
if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
memreq_t map;
req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
req->Attributes |= WIN_ENABLE;
req->Base = mem->win[0].host_addr;
req->Size = mem->win[0].len;
req->AccessSpeed = 0;
if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
return -ENODEV;
map.Page = 0;
map.CardOffset = mem->win[0].card_addr;
if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
return -ENODEV;
}
/* If we got this far, we're cool! */
break;
return 0;
}
next_entry:
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
}
static int sedlbauer_config(struct pcmcia_device *link)
{
local_info_t *dev = link->priv;
win_req_t *req;
int last_fn, last_ret;
IsdnCard_t icard;
DEBUG(0, "sedlbauer_config(0x%p)\n", link);
req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
if (!req)
return -ENOMEM;
/*
In this loop, we scan the CIS for configuration table 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.
*/
last_ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
if (last_ret)
goto failed;
/*
Allocate an interrupt line. Note that this does not assign a
@ -387,8 +371,8 @@ static int sedlbauer_config(struct pcmcia_device *link)
printk(" & 0x%04x-0x%04x", link->io.BasePort2,
link->io.BasePort2+link->io.NumPorts2-1);
if (link->win)
printk(", mem 0x%06lx-0x%06lx", req.Base,
req.Base+req.Size-1);
printk(", mem 0x%06lx-0x%06lx", req->Base,
req->Base+req->Size-1);
printk("\n");
icard.para[0] = link->irq.AssignedIRQ;
@ -409,6 +393,7 @@ static int sedlbauer_config(struct pcmcia_device *link)
cs_failed:
cs_error(link, last_fn, last_ret);
failed:
sedlbauer_release(link);
return -ENODEV;

View File

@ -193,82 +193,55 @@ static void teles_detach(struct pcmcia_device *link)
device available to the system.
======================================================================*/
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_tuple_data(handle, tuple);
if (i != CS_SUCCESS) return i;
return pcmcia_parse_tuple(handle, tuple, parse);
}
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
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 i = pcmcia_get_first_tuple(handle, tuple);
if (i != CS_SUCCESS) return i;
return get_tuple(handle, tuple, parse);
}
int j;
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
cisparse_t *parse)
{
int i = pcmcia_get_next_tuple(handle, tuple);
if (i != CS_SUCCESS) return i;
return get_tuple(handle, tuple, parse);
if ((cf->io.nwin > 0) && cf->io.win[0].base) {
printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
p_dev->io.BasePort1 = cf->io.win[0].base;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
} else {
printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
for (j = 0x2f0; j > 0x100; j -= 0x10) {
p_dev->io.BasePort1 = j;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
}
return -ENODEV;
}
static int teles_cs_config(struct pcmcia_device *link)
{
tuple_t tuple;
cisparse_t parse;
local_info_t *dev;
int i, j, last_fn;
u_short buf[128];
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
int i, last_fn;
IsdnCard_t icard;
DEBUG(0, "teles_config(0x%p)\n", link);
dev = link->priv;
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
i = first_tuple(link, &tuple, &parse);
while (i == CS_SUCCESS) {
if ( (cf->io.nwin > 0) && cf->io.win[0].base) {
printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
} else {
printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
link->conf.ConfigIndex = cf->index;
for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
link->io.BasePort1 = j;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
}
break;
}
i = next_tuple(link, &tuple, &parse);
}
if (i != CS_SUCCESS) {
i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
if (i != 0) {
last_fn = RequestIO;
goto cs_failed;
}
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
if (i != 0) {
link->irq.AssignedIRQ = 0;
last_fn = RequestIRQ;
goto cs_failed;
}
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
if (i != 0) {
last_fn = RequestConfiguration;
goto cs_failed;
}

View File

@ -118,7 +118,8 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
dev->offset, mrq.CardOffset);
mrq.Page = 0;
if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) {
ret = pcmcia_map_mem_page(win, &mrq);
if (ret != 0) {
cs_error(dev->p_dev, MapMemPage, ret);
return NULL;
}
@ -326,9 +327,8 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
ret = pcmcia_modify_configuration(link, &mod);
if(ret != CS_SUCCESS) {
if (ret != 0)
cs_error(link, ModifyConfiguration, ret);
}
}
@ -368,14 +368,14 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link,
tuple.DesiredTuple = RETURN_FIRST_TUPLE;
rc = pcmcia_get_first_tuple(link, &tuple);
while(rc == CS_SUCCESS) {
while (rc == 0) {
rc = pcmcia_get_tuple_data(link, &tuple);
if(rc != CS_SUCCESS) {
if (rc != 0) {
cs_error(link, GetTupleData, rc);
break;
}
rc = pcmcia_parse_tuple(link, &tuple, &parse);
if(rc != CS_SUCCESS) {
rc = pcmcia_parse_tuple(&tuple, &parse);
if (rc != 0) {
cs_error(link, ParseTuple, rc);
break;
}
@ -493,18 +493,11 @@ static int pcmciamtd_config(struct pcmcia_device *link)
int last_ret = 0, last_fn = 0;
int ret;
int i;
config_info_t t;
static char *probes[] = { "jedec_probe", "cfi_probe" };
int new_name = 0;
DEBUG(3, "link=0x%p", link);
DEBUG(2, "Validating CIS");
ret = pcmcia_validate_cis(link, NULL);
if(ret != CS_SUCCESS) {
cs_error(link, GetTupleData, ret);
}
card_settings(dev, link, &new_name);
dev->pcmcia_map.phys = NO_XIP;
@ -571,10 +564,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
dev->pcmcia_map.map_priv_1 = (unsigned long)dev;
dev->pcmcia_map.map_priv_2 = (unsigned long)link->win;
DEBUG(2, "Getting configuration");
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &t));
DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2);
dev->vpp = (vpp) ? vpp : t.Vpp1;
dev->vpp = (vpp) ? vpp : link->socket.socket.Vpp;
link->conf.Attributes = 0;
if(setvpp == 2) {
link->conf.Vpp = dev->vpp;
@ -583,16 +573,10 @@ static int pcmciamtd_config(struct pcmcia_device *link)
}
link->conf.IntType = INT_MEMORY;
link->conf.ConfigBase = t.ConfigBase;
link->conf.Status = t.Status;
link->conf.Pin = t.Pin;
link->conf.Copy = t.Copy;
link->conf.ExtStatus = t.ExtStatus;
link->conf.ConfigIndex = 0;
link->conf.Present = t.Present;
DEBUG(2, "Setting Configuration");
ret = pcmcia_request_configuration(link, &link->conf);
if(ret != CS_SUCCESS) {
if (ret != 0) {
cs_error(link, RequestConfiguration, ret);
if (dev->win_base) {
iounmap(dev->win_base);

View File

@ -355,9 +355,10 @@ static int tc574_config(struct pcmcia_device *link)
for (i = j = 0; j < 0x400; j += 0x20) {
link->io.BasePort1 = j ^ 0x300;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
if (i == 0)
break;
}
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestIO, i);
goto failed;
}
@ -377,7 +378,7 @@ static int tc574_config(struct pcmcia_device *link)
tuple.TupleDataMax = 64;
tuple.TupleOffset = 0;
tuple.DesiredTuple = 0x88;
if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
if (pcmcia_get_first_tuple(link, &tuple) == 0) {
pcmcia_get_tuple_data(link, &tuple);
for (i = 0; i < 3; i++)
phys_addr[i] = htons(le16_to_cpu(buf[i]));

View File

@ -278,9 +278,10 @@ static int tc589_config(struct pcmcia_device *link)
if (multi && (j & 0x80)) continue;
link->io.BasePort1 = j ^ 0x300;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
if (i == 0)
break;
}
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestIO, i);
goto failed;
}
@ -295,7 +296,7 @@ static int tc589_config(struct pcmcia_device *link)
/* The 3c589 has an extra EEPROM for configuration info, including
the hardware address. The 3c562 puts the address in the CIS. */
tuple.DesiredTuple = 0x88;
if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
if (pcmcia_get_first_tuple(link, &tuple) == 0) {
pcmcia_get_tuple_data(link, &tuple);
for (i = 0; i < 3; i++)
phys_addr[i] = htons(le16_to_cpu(buf[i]));

View File

@ -262,7 +262,7 @@ static int try_io_port(struct pcmcia_device *link)
if (link->io.NumPorts2 > 0) {
/* for master/slave multifunction cards */
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->irq.Attributes =
link->irq.Attributes =
IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
}
} else {
@ -276,7 +276,8 @@ static int try_io_port(struct pcmcia_device *link)
link->io.BasePort1 = j ^ 0x300;
link->io.BasePort2 = (j ^ 0x300) + 0x10;
ret = pcmcia_request_io(link, &link->io);
if (ret == CS_SUCCESS) return ret;
if (ret == 0)
return ret;
}
return ret;
} else {
@ -284,59 +285,50 @@ static int try_io_port(struct pcmcia_device *link)
}
}
static int axnet_configcheck(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
int i;
cistpl_io_t *io = &cfg->io;
if (cfg->index == 0 || cfg->io.nwin == 0)
return -ENODEV;
p_dev->conf.ConfigIndex = 0x05;
/* 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->io.BasePort2 = io->win[1-i].base;
p_dev->io.NumPorts2 = io->win[1-i].len;
} else {
i = p_dev->io.NumPorts2 = 0;
}
p_dev->io.BasePort1 = io->win[i].base;
p_dev->io.NumPorts1 = io->win[i].len;
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
return try_io_port(p_dev);
return -ENODEV;
}
static int axnet_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
axnet_dev_t *info = PRIV(dev);
tuple_t tuple;
cisparse_t parse;
int i, j, last_ret, last_fn;
u_short buf[64];
DECLARE_MAC_BUF(mac);
DEBUG(0, "axnet_config(0x%p)\n", link);
tuple.Attributes = 0;
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
/* don't trust the CIS on this; Linksys got it wrong */
link->conf.Present = 0x63;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (last_ret == CS_SUCCESS) {
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
cistpl_io_t *io = &(parse.cftable_entry.io);
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
pcmcia_parse_tuple(link, &tuple, &parse) != 0 ||
cfg->index == 0 || cfg->io.nwin == 0)
goto next_entry;
link->conf.ConfigIndex = 0x05;
/* 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);
link->io.BasePort2 = io->win[1-i].base;
link->io.NumPorts2 = io->win[1-i].len;
} else {
i = link->io.NumPorts2 = 0;
}
link->io.BasePort1 = io->win[i].base;
link->io.NumPorts1 = io->win[i].len;
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
last_ret = try_io_port(link);
if (last_ret == CS_SUCCESS) break;
}
next_entry:
last_ret = pcmcia_get_next_tuple(link, &tuple);
}
if (last_ret != CS_SUCCESS) {
last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
if (last_ret != 0) {
cs_error(link, RequestIO, last_ret);
goto failed;
}

View File

@ -260,21 +260,21 @@ static int com20020_config(struct pcmcia_device *link)
DEBUG(0, "com20020_config(0x%p)\n", link);
DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1);
i = !CS_SUCCESS;
i = -ENODEV;
if (!link->io.BasePort1)
{
for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10)
{
link->io.BasePort1 = ioaddr;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
if (i == 0)
break;
}
}
else
i = pcmcia_request_io(link, &link->io);
if (i != CS_SUCCESS)
if (i != 0)
{
DEBUG(1,"arcnet: requestIO failed totally!\n");
goto failed;
@ -287,7 +287,7 @@ static int com20020_config(struct pcmcia_device *link)
link->irq.AssignedIRQ,
link->irq.IRQInfo1, link->irq.IRQInfo2);
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS)
if (i != 0)
{
DEBUG(1,"arcnet: requestIRQ failed totally!\n");
goto failed;

View File

@ -309,7 +309,8 @@ static int mfc_try_io_port(struct pcmcia_device *link)
printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n");
}
ret = pcmcia_request_io(link, &link->io);
if (ret == CS_SUCCESS) return ret;
if (ret == 0)
return ret;
}
return ret;
}
@ -325,7 +326,7 @@ static int ungermann_try_io_port(struct pcmcia_device *link)
for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) {
link->io.BasePort1 = ioaddr;
ret = pcmcia_request_io(link, &link->io);
if (ret == CS_SUCCESS) {
if (ret == 0) {
/* calculate ConfigIndex value */
link->conf.ConfigIndex =
((link->io.BasePort1 & 0x0f0) >> 3) | 0x22;
@ -356,12 +357,12 @@ static int fmvj18x_config(struct pcmcia_device *link)
tuple.TupleOffset = 0;
tuple.DesiredTuple = CISTPL_FUNCE;
tuple.TupleOffset = 0;
if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
if (pcmcia_get_first_tuple(link, &tuple) == 0) {
/* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
link->conf.ConfigIndex = parse.cftable_entry.index;
switch (link->manf_id) {
case MANFID_TDK:
@ -430,10 +431,10 @@ static int fmvj18x_config(struct pcmcia_device *link)
link->irq.Attributes =
IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
ret = mfc_try_io_port(link);
if (ret != CS_SUCCESS) goto cs_failed;
if (ret != 0) goto cs_failed;
} else if (cardtype == UNGERMANN) {
ret = ungermann_try_io_port(link);
if (ret != CS_SUCCESS) goto cs_failed;
if (ret != 0) goto cs_failed;
} else {
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
}
@ -565,7 +566,7 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
req.Base = 0; req.Size = 0;
req.AccessSpeed = 0;
i = pcmcia_request_window(&link, &req, &link->win);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestWindow, i);
return -1;
}
@ -599,7 +600,7 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
iounmap(base);
j = pcmcia_release_window(link->win);
if (j != CS_SUCCESS)
if (j != 0)
cs_error(link, ReleaseWindow, j);
return (i != 0x200) ? 0 : -1;
@ -620,7 +621,7 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
req.Base = 0; req.Size = 0;
req.AccessSpeed = 0;
i = pcmcia_request_window(&link, &req, &link->win);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestWindow, i);
return -1;
}
@ -642,7 +643,7 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
iounmap(base);
j = pcmcia_release_window(link->win);
if (j != CS_SUCCESS)
if (j != 0)
cs_error(link, ReleaseWindow, j);
return 0;

View File

@ -238,7 +238,7 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
/* Try PRIMARY card at 0xA20-0xA23 */
link->io.BasePort1 = 0xA20;
i = pcmcia_request_io(link, &link->io);
if (i != CS_SUCCESS) {
if (i != 0) {
/* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */
link->io.BasePort1 = 0xA24;
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));

View File

@ -925,7 +925,7 @@ static void mace_tx_timeout(struct net_device *dev)
printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name);
#if RESET_ON_TIMEOUT
printk("resetting card\n");
pcmcia_reset_card(link, NULL);
pcmcia_reset_card(link->socket);
#else /* #if RESET_ON_TIMEOUT */
printk("NOT resetting card\n");
#endif /* #if RESET_ON_TIMEOUT */

View File

@ -310,7 +310,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
req.Base = 0; req.Size = 0;
req.AccessSpeed = 0;
i = pcmcia_request_window(&link, &req, &link->win);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestWindow, i);
return NULL;
}
@ -333,7 +333,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
iounmap(virt);
j = pcmcia_release_window(link->win);
if (j != CS_SUCCESS)
if (j != 0)
cs_error(link, ReleaseWindow, j);
return (i < NR_INFO) ? hw_info+i : NULL;
} /* get_hwinfo */
@ -504,7 +504,8 @@ static int try_io_port(struct pcmcia_device *link)
link->io.BasePort1 = j ^ 0x300;
link->io.BasePort2 = (j ^ 0x300) + 0x10;
ret = pcmcia_request_io(link, &link->io);
if (ret == CS_SUCCESS) return ret;
if (ret == 0)
return ret;
}
return ret;
} else {
@ -512,58 +513,53 @@ static int try_io_port(struct pcmcia_device *link)
}
}
static int pcnet_confcheck(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
int *has_shmem = priv_data;
int i;
cistpl_io_t *io = &cfg->io;
if (cfg->index == 0 || cfg->io.nwin == 0)
return -EINVAL;
/* 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->io.BasePort2 = io->win[1-i].base;
p_dev->io.NumPorts2 = io->win[1-i].len;
} else {
i = p_dev->io.NumPorts2 = 0;
}
*has_shmem = ((cfg->mem.nwin == 1) &&
(cfg->mem.win[0].len >= 0x4000));
p_dev->io.BasePort1 = io->win[i].base;
p_dev->io.NumPorts1 = io->win[i].len;
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
return try_io_port(p_dev);
return 0;
}
static int pcnet_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
pcnet_dev_t *info = PRIV(dev);
tuple_t tuple;
cisparse_t parse;
int i, last_ret, last_fn, start_pg, stop_pg, cm_offset;
int last_ret, last_fn, start_pg, stop_pg, cm_offset;
int has_shmem = 0;
u_short buf[64];
hw_info_t *local_hw_info;
DECLARE_MAC_BUF(mac);
DEBUG(0, "pcnet_config(0x%p)\n", link);
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (last_ret == CS_SUCCESS) {
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
cistpl_io_t *io = &(parse.cftable_entry.io);
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
pcmcia_parse_tuple(link, &tuple, &parse) != 0 ||
cfg->index == 0 || cfg->io.nwin == 0)
goto next_entry;
link->conf.ConfigIndex = cfg->index;
/* 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);
link->io.BasePort2 = io->win[1-i].base;
link->io.NumPorts2 = io->win[1-i].len;
} else {
i = link->io.NumPorts2 = 0;
}
has_shmem = ((cfg->mem.nwin == 1) &&
(cfg->mem.win[0].len >= 0x4000));
link->io.BasePort1 = io->win[i].base;
link->io.NumPorts1 = io->win[i].len;
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
last_ret = try_io_port(link);
if (last_ret == CS_SUCCESS) break;
}
next_entry:
last_ret = pcmcia_get_next_tuple(link, &tuple);
}
if (last_ret != CS_SUCCESS) {
last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
if (last_ret) {
cs_error(link, RequestIO, last_ret);
goto failed;
}

View File

@ -409,10 +409,13 @@ static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
{
int i;
if ((i = pcmcia_get_first_tuple(handle, tuple)) != CS_SUCCESS ||
(i = pcmcia_get_tuple_data(handle, tuple)) != CS_SUCCESS)
i = pcmcia_get_first_tuple(handle, tuple);
if (i != 0)
return i;
return pcmcia_parse_tuple(handle, tuple, parse);
i = pcmcia_get_tuple_data(handle, tuple);
if (i != 0)
return i;
return pcmcia_parse_tuple(tuple, parse);
}
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
@ -420,10 +423,10 @@ static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
{
int i;
if ((i = pcmcia_get_next_tuple(handle, tuple)) != CS_SUCCESS ||
(i = pcmcia_get_tuple_data(handle, tuple)) != CS_SUCCESS)
if ((i = pcmcia_get_next_tuple(handle, tuple)) != 0 ||
(i = pcmcia_get_tuple_data(handle, tuple)) != 0)
return i;
return pcmcia_parse_tuple(handle, tuple, parse);
return pcmcia_parse_tuple(tuple, parse);
}
/*======================================================================
@ -459,27 +462,36 @@ static int mhz_3288_power(struct pcmcia_device *link)
return 0;
}
static int mhz_mfc_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
int k;
p_dev->io.BasePort2 = cf->io.win[0].base;
for (k = 0; k < 0x400; k += 0x10) {
if (k & 0x80)
continue;
p_dev->io.BasePort1 = k ^ 0x300;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
return -ENODEV;
}
static int mhz_mfc_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
struct smc_private *smc = netdev_priv(dev);
struct smc_cfg_mem *cfg_mem;
tuple_t *tuple;
cisparse_t *parse;
cistpl_cftable_entry_t *cf;
u_char *buf;
win_req_t req;
memreq_t mem;
int i, k;
int i;
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
if (!cfg_mem)
return CS_OUT_OF_RESOURCE;
tuple = &cfg_mem->tuple;
parse = &cfg_mem->parse;
cf = &parse->cftable_entry;
buf = cfg_mem->buf;
return -ENOMEM;
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
@ -489,27 +501,9 @@ static int mhz_mfc_config(struct pcmcia_device *link)
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts2 = 8;
tuple->Attributes = tuple->TupleOffset = 0;
tuple->TupleData = (cisdata_t *)buf;
tuple->TupleDataMax = 255;
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
i = first_tuple(link, tuple, parse);
/* The Megahertz combo cards have modem-like CIS entries, so
we have to explicitly try a bunch of port combinations. */
while (i == CS_SUCCESS) {
link->conf.ConfigIndex = cf->index;
link->io.BasePort2 = cf->io.win[0].base;
for (k = 0; k < 0x400; k += 0x10) {
if (k & 0x80) continue;
link->io.BasePort1 = k ^ 0x300;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
}
if (i == CS_SUCCESS) break;
i = next_tuple(link, tuple, parse);
}
if (i != CS_SUCCESS)
if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
goto free_cfg_mem;
dev->base_addr = link->io.BasePort1;
@ -518,7 +512,7 @@ static int mhz_mfc_config(struct pcmcia_device *link)
req.Base = req.Size = 0;
req.AccessSpeed = 0;
i = pcmcia_request_window(&link, &req, &link->win);
if (i != CS_SUCCESS)
if (i != 0)
goto free_cfg_mem;
smc->base = ioremap(req.Base, req.Size);
mem.CardOffset = mem.Page = 0;
@ -526,14 +520,14 @@ static int mhz_mfc_config(struct pcmcia_device *link)
mem.CardOffset = link->conf.ConfigBase;
i = pcmcia_map_mem_page(link->win, &mem);
if ((i == CS_SUCCESS)
if ((i == 0)
&& (smc->manfid == MANFID_MEGAHERTZ)
&& (smc->cardid == PRODID_MEGAHERTZ_EM3288))
mhz_3288_power(link);
free_cfg_mem:
kfree(cfg_mem);
return i;
return -ENODEV;
}
static int mhz_setup(struct pcmcia_device *link)
@ -560,12 +554,12 @@ static int mhz_setup(struct pcmcia_device *link)
/* Read the station address from the CIS. It is stored as the last
(fourth) string in the Version 1 Version/ID tuple. */
tuple->DesiredTuple = CISTPL_VERS_1;
if (first_tuple(link, tuple, parse) != CS_SUCCESS) {
if (first_tuple(link, tuple, parse) != 0) {
rc = -1;
goto free_cfg_mem;
}
/* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
if (next_tuple(link, tuple, parse) != CS_SUCCESS)
if (next_tuple(link, tuple, parse) != 0)
first_tuple(link, tuple, parse);
if (parse->version_1.ns > 3) {
station_addr = parse->version_1.str + parse->version_1.ofs[3];
@ -577,11 +571,11 @@ static int mhz_setup(struct pcmcia_device *link)
/* Another possibility: for the EM3288, in a special tuple */
tuple->DesiredTuple = 0x81;
if (pcmcia_get_first_tuple(link, tuple) != CS_SUCCESS) {
if (pcmcia_get_first_tuple(link, tuple) != 0) {
rc = -1;
goto free_cfg_mem;
}
if (pcmcia_get_tuple_data(link, tuple) != CS_SUCCESS) {
if (pcmcia_get_tuple_data(link, tuple) != 0) {
rc = -1;
goto free_cfg_mem;
}
@ -660,46 +654,27 @@ static int mot_setup(struct pcmcia_device *link)
/*====================================================================*/
static int smc_configcheck(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
p_dev->io.BasePort1 = cf->io.win[0].base;
p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
return pcmcia_request_io(p_dev, &p_dev->io);
}
static int smc_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
struct smc_cfg_mem *cfg_mem;
tuple_t *tuple;
cisparse_t *parse;
cistpl_cftable_entry_t *cf;
u_char *buf;
int i;
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
if (!cfg_mem)
return CS_OUT_OF_RESOURCE;
tuple = &cfg_mem->tuple;
parse = &cfg_mem->parse;
cf = &parse->cftable_entry;
buf = cfg_mem->buf;
tuple->Attributes = tuple->TupleOffset = 0;
tuple->TupleData = (cisdata_t *)buf;
tuple->TupleDataMax = 255;
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
link->io.NumPorts1 = 16;
i = first_tuple(link, tuple, parse);
while (i != CS_NO_MORE_ITEMS) {
if (i == CS_SUCCESS) {
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
}
i = next_tuple(link, tuple, parse);
}
if (i == CS_SUCCESS)
dev->base_addr = link->io.BasePort1;
i = pcmcia_loop_config(link, smc_configcheck, NULL);
if (!i)
dev->base_addr = link->io.BasePort1;
kfree(cfg_mem);
return i;
}
@ -715,7 +690,7 @@ static int smc_setup(struct pcmcia_device *link)
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
if (!cfg_mem)
return CS_OUT_OF_RESOURCE;
return -ENOMEM;
tuple = &cfg_mem->tuple;
parse = &cfg_mem->parse;
@ -728,12 +703,12 @@ static int smc_setup(struct pcmcia_device *link)
/* Check for a LAN function extension tuple */
tuple->DesiredTuple = CISTPL_FUNCE;
i = first_tuple(link, tuple, parse);
while (i == CS_SUCCESS) {
while (i == 0) {
if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
break;
i = next_tuple(link, tuple, parse);
}
if (i == CS_SUCCESS) {
if (i == 0) {
node_id = (cistpl_lan_node_id_t *)parse->funce.data;
if (node_id->nb == 6) {
for (i = 0; i < 6; i++)
@ -780,9 +755,10 @@ static int osi_config(struct pcmcia_device *link)
for (i = j = 0; j < 4; j++) {
link->io.BasePort2 = com[j];
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
if (i == 0)
break;
}
if (i != CS_SUCCESS) {
if (i != 0) {
/* Fallback: turn off hard decode */
link->conf.ConfigIndex = 0x03;
link->io.NumPorts2 = 0;
@ -815,13 +791,13 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
/* Read the station address from tuple 0x90, subtuple 0x04 */
tuple->DesiredTuple = 0x90;
i = pcmcia_get_first_tuple(link, tuple);
while (i == CS_SUCCESS) {
while (i == 0) {
i = pcmcia_get_tuple_data(link, tuple);
if ((i != CS_SUCCESS) || (buf[0] == 0x04))
if ((i != 0) || (buf[0] == 0x04))
break;
i = pcmcia_get_next_tuple(link, tuple);
}
if (i != CS_SUCCESS) {
if (i != 0) {
rc = -1;
goto free_cfg_mem;
}
@ -959,8 +935,11 @@ static int check_sig(struct pcmcia_device *link)
======================================================================*/
#define CS_EXIT_TEST(ret, svc, label) \
if (ret != CS_SUCCESS) { cs_error(link, svc, ret); goto label; }
#define CS_EXIT_TEST(ret, svc, label) \
if (ret != 0) { \
cs_error(link, svc, ret); \
goto label; \
}
static int smc91c92_config(struct pcmcia_device *link)
{

View File

@ -377,7 +377,7 @@ first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 &&
(err = pcmcia_get_tuple_data(handle, tuple)) == 0)
err = pcmcia_parse_tuple(handle, tuple, parse);
err = pcmcia_parse_tuple(tuple, parse);
return err;
}
@ -388,7 +388,7 @@ next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 &&
(err = pcmcia_get_tuple_data(handle, tuple)) == 0)
err = pcmcia_parse_tuple(handle, tuple, parse);
err = pcmcia_parse_tuple(tuple, parse);
return err;
}
@ -715,6 +715,47 @@ has_ce2_string(struct pcmcia_device * p_dev)
return 0;
}
static int
xirc2ps_config_modem(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
unsigned int ioaddr;
if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
p_dev->io.BasePort2 = cf->io.win[0].base;
p_dev->io.BasePort1 = ioaddr;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
}
return -ENODEV;
}
static int
xirc2ps_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
int *pass = priv_data;
if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
p_dev->io.BasePort2 = cf->io.win[0].base;
p_dev->io.BasePort1 = p_dev->io.BasePort2
+ (*pass ? (cf->index & 0x20 ? -24:8)
: (cf->index & 0x20 ? 8:-24));
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
return -ENODEV;
}
/****************
* xirc2ps_config() is scheduled to run after a CARD_INSERTION event
* is received, to configure the PCMCIA socket, and to make the
@ -725,13 +766,12 @@ xirc2ps_config(struct pcmcia_device * link)
{
struct net_device *dev = link->priv;
local_info_t *local = netdev_priv(dev);
unsigned int ioaddr;
tuple_t tuple;
cisparse_t parse;
unsigned int ioaddr;
int err, i;
u_char buf[64];
cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
DECLARE_MAC_BUF(mac);
local->dingo_ccr = NULL;
@ -846,19 +886,8 @@ xirc2ps_config(struct pcmcia_device * link)
/* Take the Modem IO port from the CIS and scan for a free
* Ethernet port */
link->io.NumPorts1 = 16; /* no Mako stuff anymore */
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
for (err = first_tuple(link, &tuple, &parse); !err;
err = next_tuple(link, &tuple, &parse)) {
if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
link->conf.ConfigIndex = cf->index ;
link->io.BasePort2 = cf->io.win[0].base;
link->io.BasePort1 = ioaddr;
if (!(err=pcmcia_request_io(link, &link->io)))
goto port_found;
}
}
}
if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL))
goto port_found;
} else {
link->io.NumPorts1 = 18;
/* We do 2 passes here: The first one uses the regular mapping and
@ -866,21 +895,9 @@ xirc2ps_config(struct pcmcia_device * link)
* mirrored every 32 bytes. Actually we use a mirrored port for
* the Mako if (on the first pass) the COR bit 5 is set.
*/
for (pass=0; pass < 2; pass++) {
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
for (err = first_tuple(link, &tuple, &parse); !err;
err = next_tuple(link, &tuple, &parse)){
if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8){
link->conf.ConfigIndex = cf->index ;
link->io.BasePort2 = cf->io.win[0].base;
link->io.BasePort1 = link->io.BasePort2
+ (pass ? (cf->index & 0x20 ? -24:8)
: (cf->index & 0x20 ? 8:-24));
if (!(err=pcmcia_request_io(link, &link->io)))
for (pass=0; pass < 2; pass++)
if (!pcmcia_loop_config(link, xirc2ps_config_check, &pass))
goto port_found;
}
}
}
/* if special option:
* try to configure as Ethernet only.
* .... */

View File

@ -206,126 +206,123 @@ static void airo_detach(struct pcmcia_device *link)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
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)
{
win_req_t *req = priv_data;
if (cfg->index == 0)
return -ENODEV;
/* 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;
/* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.BasePort1 = io->win[0].base;
p_dev->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
p_dev->io.Attributes2 = p_dev->io.Attributes1;
p_dev->io.BasePort2 = io->win[1].base;
p_dev->io.NumPorts2 = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
return -ENODEV;
/*
Now set up a common memory window, if needed. There is room
in the struct pcmcia_device structure for one memory window handle,
but if the base addresses need to be saved, or if multiple
windows are needed, the info should go in the private data
structure for this device.
Note that the memory window base is a physical address, and
needs to be mapped to virtual space with ioremap() before it
is used.
*/
if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
memreq_t map;
req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
req->Base = mem->win[0].host_addr;
req->Size = mem->win[0].len;
req->AccessSpeed = 0;
if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
return -ENODEV;
map.Page = 0;
map.CardOffset = mem->win[0].card_addr;
if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
return -ENODEV;
}
/* If we got this far, we're cool! */
return 0;
}
static int airo_config(struct pcmcia_device *link)
{
tuple_t tuple;
cisparse_t parse;
local_info_t *dev;
win_req_t *req;
int last_fn, last_ret;
u_char buf[64];
win_req_t req;
memreq_t map;
dev = link->priv;
DEBUG(0, "airo_config(0x%p)\n", link);
req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
if (!req)
return -ENOMEM;
/*
In this loop, we scan the CIS for configuration table 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.
* In this loop, we scan the CIS for configuration table
* 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.
*/
last_ret = pcmcia_loop_config(link, airo_cs_config_check, req);
if (last_ret)
goto failed;
/*
Allocate an interrupt line. Note that this does not assign a
handler to the interrupt, unless the 'Handler' member of the
irq structure is initialized.
*/
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
cistpl_cftable_entry_t dflt = { 0 };
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
goto next_entry;
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
if (cfg->index == 0) goto next_entry;
link->conf.ConfigIndex = cfg->index;
/* Does this card need audio output? */
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->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))
link->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
link->conf.Vpp =
dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
/* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
link->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
link->io.NumPorts1 = link->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
link->io.Attributes2 = link->io.Attributes1;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry;
/*
Now set up a common memory window, if needed. There is room
in the struct pcmcia_device structure for one memory window handle,
but if the base addresses need to be saved, or if multiple
windows are needed, the info should go in the private data
structure for this device.
Note that the memory window base is a physical address, and
needs to be mapped to virtual space with ioremap() before it
is used.
*/
if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
cistpl_mem_t *mem =
(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
req.Base = mem->win[0].host_addr;
req.Size = mem->win[0].len;
req.AccessSpeed = 0;
if (pcmcia_request_window(&link, &req, &link->win) != 0)
goto next_entry;
map.Page = 0; map.CardOffset = mem->win[0].card_addr;
if (pcmcia_map_mem_page(link->win, &map) != 0)
goto next_entry;
}
/* If we got this far, we're cool! */
break;
next_entry:
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
}
/*
Allocate an interrupt line. Note that this does not assign a
handler to the interrupt, unless the 'Handler' member of the
irq structure is initialized.
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ)
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
@ -362,14 +359,17 @@ static int airo_config(struct pcmcia_device *link)
printk(" & 0x%04x-0x%04x", link->io.BasePort2,
link->io.BasePort2+link->io.NumPorts2-1);
if (link->win)
printk(", mem 0x%06lx-0x%06lx", req.Base,
req.Base+req.Size-1);
printk(", mem 0x%06lx-0x%06lx", req->Base,
req->Base+req->Size-1);
printk("\n");
kfree(req);
return 0;
cs_failed:
cs_error(link, last_fn, last_ret);
failed:
airo_release(link);
kfree(req);
return -ENODEV;
} /* airo_config */

View File

@ -224,13 +224,58 @@ static int card_present(void *arg)
return 0;
}
static int atmel_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)
return -ENODEV;
/* 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;
/* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.BasePort1 = io->win[0].base;
p_dev->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
p_dev->io.Attributes2 = p_dev->io.Attributes1;
p_dev->io.BasePort2 = io->win[1].base;
p_dev->io.NumPorts2 = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
return pcmcia_request_io(p_dev, &p_dev->io);
}
static int atmel_config(struct pcmcia_device *link)
{
tuple_t tuple;
cisparse_t parse;
local_info_t *dev;
int last_fn, last_ret;
u_char buf[64];
struct pcmcia_device_id *did;
dev = link->priv;
@ -238,11 +283,6 @@ static int atmel_config(struct pcmcia_device *link)
DEBUG(0, "atmel_config(0x%p)\n", link);
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
/*
In this loop, we scan the CIS for configuration table entries,
each of which describes a valid card configuration, including
@ -255,66 +295,8 @@ static int atmel_config(struct pcmcia_device *link)
these things without consulting the CIS, and most client drivers
will only use the CIS to fill in implementation-defined details.
*/
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
cistpl_cftable_entry_t dflt = { 0 };
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
goto next_entry;
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
if (cfg->index == 0) goto next_entry;
link->conf.ConfigIndex = cfg->index;
/* Does this card need audio output? */
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->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))
link->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
link->conf.Vpp =
dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
/* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
link->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
link->io.NumPorts1 = link->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
link->io.Attributes2 = link->io.Attributes1;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry;
/* If we got this far, we're cool! */
break;
next_entry:
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
}
if (pcmcia_loop_config(link, atmel_config_check, NULL))
goto failed;
/*
Allocate an interrupt line. Note that this does not assign a
@ -360,6 +342,7 @@ static int atmel_config(struct pcmcia_device *link)
cs_failed:
cs_error(link, last_fn, last_ret);
failed:
atmel_release(link);
return -ENODEV;
}

View File

@ -82,13 +82,13 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
tuple.TupleOffset = 0;
res = pcmcia_get_first_tuple(dev, &tuple);
if (res != CS_SUCCESS)
if (res != 0)
goto err_kfree_ssb;
res = pcmcia_get_tuple_data(dev, &tuple);
if (res != CS_SUCCESS)
if (res != 0)
goto err_kfree_ssb;
res = pcmcia_parse_tuple(dev, &tuple, &parse);
if (res != CS_SUCCESS)
res = pcmcia_parse_tuple(&tuple, &parse);
if (res != 0)
goto err_kfree_ssb;
dev->conf.ConfigBase = parse.config.base;
@ -107,13 +107,13 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
win.Size = SSB_CORE_SIZE;
win.AccessSpeed = 250;
res = pcmcia_request_window(&dev, &win, &dev->win);
if (res != CS_SUCCESS)
if (res != 0)
goto err_kfree_ssb;
mem.CardOffset = 0;
mem.Page = 0;
res = pcmcia_map_mem_page(dev->win, &mem);
if (res != CS_SUCCESS)
if (res != 0)
goto err_disable;
dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
@ -121,11 +121,11 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
dev->irq.Handler = NULL; /* The handler is registered later. */
dev->irq.Instance = NULL;
res = pcmcia_request_irq(dev, &dev->irq);
if (res != CS_SUCCESS)
if (res != 0)
goto err_disable;
res = pcmcia_request_configuration(dev, &dev->conf);
if (res != CS_SUCCESS)
if (res != 0)
goto err_disable;
err = ssb_bus_pcmciabus_register(ssb, dev, win.Base);

View File

@ -234,7 +234,7 @@ static void sandisk_set_iobase(local_info_t *local)
reg.Value = hw_priv->link->io.BasePort1 & 0x00ff;
res = pcmcia_access_configuration_register(hw_priv->link,
&reg);
if (res != CS_SUCCESS) {
if (res != 0) {
printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -"
" res=%d\n", res);
}
@ -246,7 +246,7 @@ static void sandisk_set_iobase(local_info_t *local)
reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8;
res = pcmcia_access_configuration_register(hw_priv->link,
&reg);
if (res != CS_SUCCESS) {
if (res != 0) {
printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -"
" res=%d\n", res);
}
@ -305,7 +305,7 @@ static int sandisk_enable_wireless(struct net_device *dev)
tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
pcmcia_parse_tuple(hw_priv->link, &tuple, parse) ||
pcmcia_parse_tuple(&tuple, parse) ||
parse->longlink_mfc.nfn < 2) {
/* No multi-function links found */
ret = -ENODEV;
@ -322,7 +322,7 @@ static int sandisk_enable_wireless(struct net_device *dev)
reg.Value = COR_SOFT_RESET;
res = pcmcia_access_configuration_register(hw_priv->link,
&reg);
if (res != CS_SUCCESS) {
if (res != 0) {
printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
dev->name, res);
goto done;
@ -339,7 +339,7 @@ static int sandisk_enable_wireless(struct net_device *dev)
reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA;
res = pcmcia_access_configuration_register(hw_priv->link,
&reg);
if (res != CS_SUCCESS) {
if (res != 0) {
printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
dev->name, res);
goto done;
@ -374,7 +374,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
reg.Value = 0;
res = pcmcia_access_configuration_register(hw_priv->link,
&reg);
if (res != CS_SUCCESS) {
if (res != 0) {
printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n",
res);
return;
@ -386,7 +386,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
reg.Value |= COR_SOFT_RESET;
res = pcmcia_access_configuration_register(hw_priv->link,
&reg);
if (res != CS_SUCCESS) {
if (res != 0) {
printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n",
res);
return;
@ -399,7 +399,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
reg.Value |= COR_IREQ_ENA;
res = pcmcia_access_configuration_register(hw_priv->link,
&reg);
if (res != CS_SUCCESS) {
if (res != 0) {
printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n",
res);
return;
@ -433,7 +433,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
reg.Value = 0;
res = pcmcia_access_configuration_register(hw_priv->link,
&reg);
if (res != CS_SUCCESS) {
if (res != 0) {
printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 "
"(%d)\n", res);
return;
@ -446,7 +446,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
reg.Value |= COR_SOFT_RESET;
res = pcmcia_access_configuration_register(hw_priv->link,
&reg);
if (res != CS_SUCCESS) {
if (res != 0) {
printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 "
"(%d)\n", res);
return;
@ -460,7 +460,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
reg.Offset = CISREG_CCSR;
res = pcmcia_access_configuration_register(hw_priv->link,
&reg);
if (res != CS_SUCCESS) {
if (res != 0) {
printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 "
"(%d)\n", res);
return;
@ -472,7 +472,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
reg.Value = old_cor & ~COR_SOFT_RESET;
res = pcmcia_access_configuration_register(hw_priv->link,
&reg);
if (res != CS_SUCCESS) {
if (res != 0) {
printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 "
"(%d)\n", res);
return;
@ -532,145 +532,118 @@ static void prism2_detach(struct pcmcia_device *link)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
#define CFG_CHECK2(fn, retf) \
do { int _ret = (retf); \
if (_ret != 0) { \
PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", _ret); \
cs_error(link, fn, _ret); \
goto next_entry; \
} \
} while (0)
/* run after a CARD_INSERTION event is received to configure the PCMCIA
* 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)
return -ENODEV;
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? */
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
else if (!(p_dev->conf.Attributes & CONF_ENABLE_IRQ)) {
/* At least Compaq WL200 does not have IRQInfo1 set,
* but it does not work without interrupts.. */
printk(KERN_WARNING "Config has no IRQ info, but trying to "
"enable IRQ anyway..\n");
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->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
"io.base=0x%04x, len=%d\n", io->flags,
io->win[0].base, io->win[0].len);
if (!(io->flags & CISTPL_IO_8BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.IOAddrLines = io->flags &
CISTPL_IO_LINES_MASK;
p_dev->io.BasePort1 = io->win[0].base;
p_dev->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
p_dev->io.Attributes2 = p_dev->io.Attributes1;
p_dev->io.BasePort2 = io->win[1].base;
p_dev->io.NumPorts2 = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
return pcmcia_request_io(p_dev, &p_dev->io);
}
static int prism2_config(struct pcmcia_device *link)
{
struct net_device *dev;
struct hostap_interface *iface;
local_info_t *local;
int ret = 1;
tuple_t tuple;
cisparse_t *parse;
int last_fn, last_ret;
u_char buf[64];
config_info_t conf;
cistpl_cftable_entry_t dflt = { 0 };
struct hostap_cs_priv *hw_priv;
PDEBUG(DEBUG_FLOW, "prism2_config()\n");
parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL);
if (parse == NULL || hw_priv == NULL) {
if (hw_priv == NULL) {
ret = -ENOMEM;
goto failed;
}
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
CS_CHECK(GetConfigurationInfo,
pcmcia_get_configuration_info(link, &conf));
/* Look for an appropriate configuration table entry in the CIS */
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
for (;;) {
cistpl_cftable_entry_t *cfg = &(parse->cftable_entry);
CFG_CHECK2(GetTupleData,
pcmcia_get_tuple_data(link, &tuple));
CFG_CHECK2(ParseTuple,
pcmcia_parse_tuple(link, &tuple, parse));
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
dflt = *cfg;
if (cfg->index == 0)
goto next_entry;
link->conf.ConfigIndex = cfg->index;
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) {
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->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 (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
10000 && !ignore_cis_vcc) {
PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping"
" this entry\n");
goto next_entry;
}
} else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] /
10000 && !ignore_cis_vcc) {
PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch "
"- skipping this entry\n");
goto next_entry;
}
}
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp =
dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
/* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
link->conf.Attributes |= CONF_ENABLE_IRQ;
else if (!(link->conf.Attributes & CONF_ENABLE_IRQ)) {
/* At least Compaq WL200 does not have IRQInfo1 set,
* but it does not work without interrupts.. */
printk("Config has no IRQ info, but trying to enable "
"IRQ anyway..\n");
link->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);
link->io.NumPorts1 = link->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
"io.base=0x%04x, len=%d\n", io->flags,
io->win[0].base, io->win[0].len);
if (!(io->flags & CISTPL_IO_8BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines = io->flags &
CISTPL_IO_LINES_MASK;
link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
link->io.Attributes2 = link->io.Attributes1;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
CFG_CHECK2(RequestIO,
pcmcia_request_io(link, &link->io));
/* This configuration table entry is OK */
break;
next_entry:
CS_CHECK(GetNextTuple,
pcmcia_get_next_tuple(link, &tuple));
last_ret = pcmcia_loop_config(link, prism2_config_check, NULL);
if (last_ret) {
if (!ignore_cis_vcc)
printk(KERN_ERR "GetNextTuple(): No matching "
"CIS configuration. Maybe you need the "
"ignore_cis_vcc=1 parameter.\n");
cs_error(link, RequestIO, last_ret);
goto failed;
}
/* Need to allocate net_device before requesting IRQ handler */
@ -738,14 +711,12 @@ static int prism2_config(struct pcmcia_device *link)
if (ret == 0 && local->ddev)
strcpy(hw_priv->node.dev_name, local->ddev->name);
}
kfree(parse);
return ret;
cs_failed:
cs_error(link, last_fn, last_ret);
failed:
kfree(parse);
kfree(hw_priv);
prism2_release((u_long)link);
return ret;

View File

@ -791,7 +791,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
if ((ret = pcmcia_get_first_tuple(p_dev, &tuple)) != 0 ||
(ret = pcmcia_get_tuple_data(p_dev, &tuple)) != 0 ||
(ret = pcmcia_parse_tuple(p_dev, &tuple, &parse)) != 0)
(ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
{
lbs_pr_err("error in pcmcia_get_first_tuple etc\n");
goto out1;

View File

@ -749,9 +749,10 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
for (i = j = 0x0; j < 0x400; j += 0x20) {
link->io.BasePort1 = j ^ 0x300;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
if (i == 0)
break;
}
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestIO, i);
goto failed;
}

View File

@ -80,7 +80,7 @@ orinoco_cs_hard_reset(struct orinoco_private *priv)
/* We need atomic ops here, because we're not holding the lock */
set_bit(0, &card->hard_reset_in_progress);
err = pcmcia_reset_card(link, NULL);
err = pcmcia_reset_card(link->socket);
if (err)
return err;
@ -165,6 +165,70 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \
} while (0)
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)
goto next_entry;
/* 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) {
DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", 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, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", 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->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->io.BasePort1 = io->win[0].base;
p_dev->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
p_dev->io.Attributes2 = p_dev->io.Attributes1;
p_dev->io.BasePort2 = io->win[1].base;
p_dev->io.NumPorts2 = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
goto next_entry;
}
return 0;
next_entry:
pcmcia_disable_device(p_dev);
return -ENODEV;
};
static int
orinoco_cs_config(struct pcmcia_device *link)
{
@ -173,16 +237,8 @@ orinoco_cs_config(struct pcmcia_device *link)
struct orinoco_pccard *card = priv->card;
hermes_t *hw = &priv->hw;
int last_fn, last_ret;
u_char buf[64];
config_info_t conf;
tuple_t tuple;
cisparse_t parse;
void __iomem *mem;
/* Look up the current Vcc */
CS_CHECK(GetConfigurationInfo,
pcmcia_get_configuration_info(link, &conf));
/*
* In this loop, we scan the CIS for configuration table
* entries, each of which describes a valid card
@ -197,94 +253,14 @@ orinoco_cs_config(struct pcmcia_device *link)
* and most client drivers will only use the CIS to fill in
* implementation-defined details.
*/
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
cistpl_cftable_entry_t dflt = { .index = 0 };
if ( (pcmcia_get_tuple_data(link, &tuple) != 0)
|| (pcmcia_parse_tuple(link, &tuple, &parse) != 0))
goto next_entry;
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
dflt = *cfg;
if (cfg->index == 0)
goto next_entry;
link->conf.ConfigIndex = cfg->index;
/* 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 (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, cfg CIS = %d)\n", conf.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 (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, dflt CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
if(!ignore_cis_vcc)
goto next_entry;
}
}
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp =
dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
/* Do we need to allocate an interrupt? */
link->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
link->io.NumPorts1 = link->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io =
(cfg->io.nwin) ? &cfg->io : &dflt.io;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
link->io.Attributes1 =
IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
link->io.Attributes1 =
IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines =
io->flags & CISTPL_IO_LINES_MASK;
link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
link->io.Attributes2 =
link->io.Attributes1;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry;
}
/* If we got this far, we're cool! */
break;
next_entry:
pcmcia_disable_device(link);
last_ret = pcmcia_get_next_tuple(link, &tuple);
if (last_ret == CS_NO_MORE_ITEMS) {
last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
if (last_ret) {
if (!ignore_cis_vcc)
printk(KERN_ERR PFX "GetNextTuple(): No matching "
"CIS configuration. Maybe you need the "
"ignore_cis_vcc=1 parameter.\n");
goto cs_failed;
}
cs_error(link, RequestIO, last_ret);
goto failed;
}
/*
@ -335,7 +311,6 @@ orinoco_cs_config(struct pcmcia_device *link)
"0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id,
link->irq.AssignedIRQ, link->io.BasePort1,
link->io.BasePort1 + link->io.NumPorts1 - 1);
return 0;
cs_failed:

View File

@ -798,9 +798,9 @@ static void ray_release(struct pcmcia_device *link)
iounmap(local->amem);
/* Do bother checking to see if these succeed or not */
i = pcmcia_release_window(local->amem_handle);
if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);
if ( i != 0 ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);
i = pcmcia_release_window(local->rmem_handle);
if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);
if ( i != 0 ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);
pcmcia_disable_device(link);
DEBUG(2,"ray_release ending\n");

View File

@ -235,6 +235,70 @@ static void spectrum_cs_detach(struct pcmcia_device *link)
* device available to the system.
*/
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)
{
if (cfg->index == 0)
goto next_entry;
/* 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) {
DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", 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, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", 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->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->io.BasePort1 = io->win[0].base;
p_dev->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
p_dev->io.Attributes2 = p_dev->io.Attributes1;
p_dev->io.BasePort2 = io->win[1].base;
p_dev->io.NumPorts2 = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
goto next_entry;
}
return 0;
next_entry:
pcmcia_disable_device(p_dev);
return -ENODEV;
};
static int
spectrum_cs_config(struct pcmcia_device *link)
{
@ -243,16 +307,8 @@ spectrum_cs_config(struct pcmcia_device *link)
struct orinoco_pccard *card = priv->card;
hermes_t *hw = &priv->hw;
int last_fn, last_ret;
u_char buf[64];
config_info_t conf;
tuple_t tuple;
cisparse_t parse;
void __iomem *mem;
/* Look up the current Vcc */
CS_CHECK(GetConfigurationInfo,
pcmcia_get_configuration_info(link, &conf));
/*
* In this loop, we scan the CIS for configuration table
* entries, each of which describes a valid card
@ -267,94 +323,14 @@ spectrum_cs_config(struct pcmcia_device *link)
* and most client drivers will only use the CIS to fill in
* implementation-defined details.
*/
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
cistpl_cftable_entry_t dflt = { .index = 0 };
if ( (pcmcia_get_tuple_data(link, &tuple) != 0)
|| (pcmcia_parse_tuple(link, &tuple, &parse) != 0))
goto next_entry;
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
dflt = *cfg;
if (cfg->index == 0)
goto next_entry;
link->conf.ConfigIndex = cfg->index;
/* 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 (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.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 (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
if(!ignore_cis_vcc)
goto next_entry;
}
}
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp =
dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
/* Do we need to allocate an interrupt? */
link->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
link->io.NumPorts1 = link->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io =
(cfg->io.nwin) ? &cfg->io : &dflt.io;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
link->io.Attributes1 =
IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
link->io.Attributes1 =
IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines =
io->flags & CISTPL_IO_LINES_MASK;
link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
link->io.Attributes2 =
link->io.Attributes1;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry;
}
/* If we got this far, we're cool! */
break;
next_entry:
pcmcia_disable_device(link);
last_ret = pcmcia_get_next_tuple(link, &tuple);
if (last_ret == CS_NO_MORE_ITEMS) {
last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
if (last_ret) {
if (!ignore_cis_vcc)
printk(KERN_ERR PFX "GetNextTuple(): No matching "
"CIS configuration. Maybe you need the "
"ignore_cis_vcc=1 parameter.\n");
goto cs_failed;
}
cs_error(link, RequestIO, last_ret);
goto failed;
}
/*

View File

@ -3702,7 +3702,7 @@ wv_pcmcia_reset(struct net_device * dev)
#endif
i = pcmcia_access_configuration_register(link, &reg);
if(i != CS_SUCCESS)
if (i != 0)
{
cs_error(link, AccessConfigurationRegister, i);
return FALSE;
@ -3716,7 +3716,7 @@ wv_pcmcia_reset(struct net_device * dev)
reg.Action = CS_WRITE;
reg.Value = reg.Value | COR_SW_RESET;
i = pcmcia_access_configuration_register(link, &reg);
if(i != CS_SUCCESS)
if (i != 0)
{
cs_error(link, AccessConfigurationRegister, i);
return FALSE;
@ -3725,7 +3725,7 @@ wv_pcmcia_reset(struct net_device * dev)
reg.Action = CS_WRITE;
reg.Value = COR_LEVEL_IRQ | COR_CONFIG;
i = pcmcia_access_configuration_register(link, &reg);
if(i != CS_SUCCESS)
if (i != 0)
{
cs_error(link, AccessConfigurationRegister, i);
return FALSE;
@ -3903,7 +3903,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
do
{
i = pcmcia_request_io(link, &link->io);
if(i != CS_SUCCESS)
if (i != 0)
{
cs_error(link, RequestIO, i);
break;
@ -3914,7 +3914,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
* actually assign a handler to the interrupt.
*/
i = pcmcia_request_irq(link, &link->irq);
if(i != CS_SUCCESS)
if (i != 0)
{
cs_error(link, RequestIRQ, i);
break;
@ -3926,7 +3926,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
*/
link->conf.ConfigIndex = 1;
i = pcmcia_request_configuration(link, &link->conf);
if(i != CS_SUCCESS)
if (i != 0)
{
cs_error(link, RequestConfiguration, i);
break;
@ -3942,7 +3942,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
req.Base = req.Size = 0;
req.AccessSpeed = mem_speed;
i = pcmcia_request_window(&link, &req, &link->win);
if(i != CS_SUCCESS)
if (i != 0)
{
cs_error(link, RequestWindow, i);
break;
@ -3954,7 +3954,7 @@ wv_pcmcia_config(struct pcmcia_device * link)
mem.CardOffset = 0; mem.Page = 0;
i = pcmcia_map_mem_page(link->win, &mem);
if(i != CS_SUCCESS)
if (i != 0)
{
cs_error(link, MapMemPage, i);
break;

View File

@ -1977,10 +1977,10 @@ static int wl3501_config(struct pcmcia_device *link)
link->io.BasePort1 = j;
link->io.BasePort2 = link->io.BasePort1 + 0x10;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
if (i == 0)
break;
}
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestIO, i);
goto failed;
}

View File

@ -149,52 +149,44 @@ static void parport_detach(struct pcmcia_device *link)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
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)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
if (epp_mode)
p_dev->conf.ConfigIndex |= FORCE_EPP_MODE;
p_dev->io.BasePort1 = io->win[0].base;
p_dev->io.NumPorts1 = io->win[0].len;
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
if (io->nwin == 2) {
p_dev->io.BasePort2 = io->win[1].base;
p_dev->io.NumPorts2 = io->win[1].len;
}
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
return -ENODEV;
return 0;
}
return -ENODEV;
}
static int parport_config(struct pcmcia_device *link)
{
parport_info_t *info = link->priv;
tuple_t tuple;
u_short buf[128];
cisparse_t parse;
cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
cistpl_cftable_entry_t dflt = { 0 };
struct parport *p;
int last_ret, last_fn;
DEBUG(0, "parport_config(0x%p)\n", link);
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
goto next_entry;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
link->conf.ConfigIndex = cfg->index;
if (epp_mode)
link->conf.ConfigIndex |= FORCE_EPP_MODE;
link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len;
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
if (io->nwin == 2) {
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
}
if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry;
/* If we've got this far, we're done */
break;
}
next_entry:
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
DEBUG(0, "parport_config(0x%p)\n", link);
last_ret = pcmcia_loop_config(link, parport_config_check, NULL);
if (last_ret) {
cs_error(link, RequestIO, last_ret);
goto failed;
}
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));

View File

@ -2,10 +2,6 @@
# Makefile for the kernel pcmcia subsystem (c/o David Hinds)
#
ifeq ($(CONFIG_PCMCIA_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
endif
pcmcia_core-y += cs.o cistpl.o rsrc_mgr.o socket_sysfs.o
pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
obj-$(CONFIG_PCCARD) += pcmcia_core.o

View File

@ -292,7 +292,7 @@ au1x00_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map)
skt->spd_io[map->map] = speed;
}
map->start=(ioaddr_t)(u32)skt->virt_io;
map->start=(unsigned int)(u32)skt->virt_io;
map->stop=map->start+MAP_SIZE;
return 0;

View File

@ -116,7 +116,7 @@ struct au1000_pcmcia_socket {
struct resource res_attr;
void * virt_io;
ioaddr_t phys_io;
unsigned int phys_io;
unsigned int phys_attr;
unsigned int phys_mem;
unsigned short speed_io, speed_attr, speed_mem;

View File

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

View File

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

View File

@ -238,7 +238,7 @@ int __ref cb_alloc(struct pcmcia_socket * s)
pci_bus_add_devices(bus);
s->irq.AssignedIRQ = s->pci_irq;
return CS_SUCCESS;
return 0;
}
void cb_free(struct pcmcia_socket * s)

View File

@ -92,7 +92,8 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag
if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) {
mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s);
if (mem->res == NULL) {
printk(KERN_NOTICE "cs: unable to map card memory!\n");
dev_printk(KERN_NOTICE, &s->dev,
"cs: unable to map card memory!\n");
return NULL;
}
s->cis_virt = NULL;
@ -265,13 +266,13 @@ EXPORT_SYMBOL(pcmcia_write_cis_mem);
======================================================================*/
static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
u_int len, void *ptr)
size_t len, void *ptr)
{
struct cis_cache_entry *cis;
int ret;
if (s->fake_cis) {
if (s->fake_cis_len > addr+len)
if (s->fake_cis_len >= addr+len)
memcpy(ptr, s->fake_cis+addr, len);
else
memset(ptr, 0xff, len);
@ -351,7 +352,9 @@ int verify_cis_cache(struct pcmcia_socket *s)
buf = kmalloc(256, GFP_KERNEL);
if (buf == NULL)
return -1;
dev_printk(KERN_WARNING, &s->dev,
"no memory for verifying CIS\n");
return -ENOMEM;
list_for_each_entry(cis, &s->cis_cache, node) {
int len = cis->len;
@ -380,18 +383,22 @@ int verify_cis_cache(struct pcmcia_socket *s)
======================================================================*/
int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis)
int pcmcia_replace_cis(struct pcmcia_socket *s,
const u8 *data, const size_t len)
{
kfree(s->fake_cis);
s->fake_cis = NULL;
if (cis->Length > CISTPL_MAX_CIS_SIZE)
return CS_BAD_SIZE;
s->fake_cis = kmalloc(cis->Length, GFP_KERNEL);
if (s->fake_cis == NULL)
return CS_OUT_OF_RESOURCE;
s->fake_cis_len = cis->Length;
memcpy(s->fake_cis, cis->Data, cis->Length);
return CS_SUCCESS;
if (len > CISTPL_MAX_CIS_SIZE) {
dev_printk(KERN_WARNING, &s->dev, "replacement CIS too big\n");
return -EINVAL;
}
kfree(s->fake_cis);
s->fake_cis = kmalloc(len, GFP_KERNEL);
if (s->fake_cis == NULL) {
dev_printk(KERN_WARNING, &s->dev, "no memory to replace CIS\n");
return -ENOMEM;
}
s->fake_cis_len = len;
memcpy(s->fake_cis, data, len);
return 0;
}
EXPORT_SYMBOL(pcmcia_replace_cis);
@ -418,9 +425,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *t
int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple)
{
if (!s)
return CS_BAD_HANDLE;
return -EINVAL;
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
return -ENODEV;
tuple->TupleLink = tuple->Flags = 0;
#ifdef CONFIG_CARDBUS
if (s->state & SOCKET_CARDBUS) {
@ -440,10 +447,10 @@ int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple
!(tuple->Attributes & TUPLE_RETURN_COMMON)) {
cisdata_t req = tuple->DesiredTuple;
tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
if (pccard_get_next_tuple(s, function, tuple) == CS_SUCCESS) {
if (pccard_get_next_tuple(s, function, tuple) == 0) {
tuple->DesiredTuple = CISTPL_LINKTARGET;
if (pccard_get_next_tuple(s, function, tuple) != CS_SUCCESS)
return CS_NO_MORE_ITEMS;
if (pccard_get_next_tuple(s, function, tuple) != 0)
return -ENOSPC;
} else
tuple->CISOffset = tuple->TupleLink = 0;
tuple->DesiredTuple = req;
@ -498,9 +505,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
int ofs, i, attr;
if (!s)
return CS_BAD_HANDLE;
return -EINVAL;
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
return -ENODEV;
link[1] = tuple->TupleLink;
ofs = tuple->CISOffset + tuple->TupleLink;
@ -519,7 +526,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
/* End of chain? Follow long link if possible */
if (link[0] == CISTPL_END) {
if ((ofs = follow_link(s, tuple)) < 0)
return CS_NO_MORE_ITEMS;
return -ENOSPC;
attr = SPACE(tuple->Flags);
read_cis_cache(s, attr, ofs, 2, link);
}
@ -577,13 +584,13 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
}
if (i == MAX_TUPLES) {
cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n");
return CS_NO_MORE_ITEMS;
return -ENOSPC;
}
tuple->TupleCode = link[0];
tuple->TupleLink = link[1];
tuple->CISOffset = ofs + 2;
return CS_SUCCESS;
return 0;
}
EXPORT_SYMBOL(pccard_get_next_tuple);
@ -596,18 +603,18 @@ int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
u_int len;
if (!s)
return CS_BAD_HANDLE;
return -EINVAL;
if (tuple->TupleLink < tuple->TupleOffset)
return CS_NO_MORE_ITEMS;
return -ENOSPC;
len = tuple->TupleLink - tuple->TupleOffset;
tuple->TupleDataLen = tuple->TupleLink;
if (len == 0)
return CS_SUCCESS;
return 0;
read_cis_cache(s, SPACE(tuple->Flags),
tuple->CISOffset + tuple->TupleOffset,
_MIN(len, tuple->TupleDataMax), tuple->TupleData);
return CS_SUCCESS;
return 0;
}
EXPORT_SYMBOL(pccard_get_tuple_data);
@ -640,25 +647,31 @@ static int parse_device(tuple_t *tuple, cistpl_device_t *device)
case 3: device->dev[i].speed = 150; break;
case 4: device->dev[i].speed = 100; break;
case 7:
if (++p == q) return CS_BAD_TUPLE;
if (++p == q)
return -EINVAL;
device->dev[i].speed = SPEED_CVT(*p);
while (*p & 0x80)
if (++p == q) return CS_BAD_TUPLE;
if (++p == q)
return -EINVAL;
break;
default:
return CS_BAD_TUPLE;
return -EINVAL;
}
if (++p == q) return CS_BAD_TUPLE;
if (*p == 0xff) break;
if (++p == q)
return -EINVAL;
if (*p == 0xff)
break;
scale = *p & 7;
if (scale == 7) return CS_BAD_TUPLE;
if (scale == 7)
return -EINVAL;
device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2));
device->ndev++;
if (++p == q) break;
if (++p == q)
break;
}
return CS_SUCCESS;
return 0;
}
/*====================================================================*/
@ -667,12 +680,12 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
{
u_char *p;
if (tuple->TupleDataLen < 5)
return CS_BAD_TUPLE;
return -EINVAL;
p = (u_char *) tuple->TupleData;
csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2;
csum->len = get_unaligned_le16(p + 2);
csum->sum = *(p + 4);
return CS_SUCCESS;
return 0;
}
/*====================================================================*/
@ -680,9 +693,9 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
{
if (tuple->TupleDataLen < 4)
return CS_BAD_TUPLE;
return -EINVAL;
link->addr = get_unaligned_le32(tuple->TupleData);
return CS_SUCCESS;
return 0;
}
/*====================================================================*/
@ -697,13 +710,13 @@ static int parse_longlink_mfc(tuple_t *tuple,
link->nfn = *p; p++;
if (tuple->TupleDataLen <= link->nfn*5)
return CS_BAD_TUPLE;
return -EINVAL;
for (i = 0; i < link->nfn; i++) {
link->fn[i].space = *p; p++;
link->fn[i].addr = get_unaligned_le32(p);
p += 4;
}
return CS_SUCCESS;
return 0;
}
/*====================================================================*/
@ -713,24 +726,27 @@ static int parse_strings(u_char *p, u_char *q, int max,
{
int i, j, ns;
if (p == q) return CS_BAD_TUPLE;
if (p == q)
return -EINVAL;
ns = 0; j = 0;
for (i = 0; i < max; i++) {
if (*p == 0xff) break;
if (*p == 0xff)
break;
ofs[i] = j;
ns++;
for (;;) {
s[j++] = (*p == 0xff) ? '\0' : *p;
if ((*p == '\0') || (*p == 0xff)) break;
if (++p == q) return CS_BAD_TUPLE;
if (++p == q)
return -EINVAL;
}
if ((*p == 0xff) || (++p == q)) break;
}
if (found) {
*found = ns;
return CS_SUCCESS;
return 0;
} else {
return (ns == max) ? CS_SUCCESS : CS_BAD_TUPLE;
return (ns == max) ? 0 : -EINVAL;
}
}
@ -745,7 +761,8 @@ static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1)
vers_1->major = *p; p++;
vers_1->minor = *p; p++;
if (p >= q) return CS_BAD_TUPLE;
if (p >= q)
return -EINVAL;
return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS,
vers_1->str, vers_1->ofs, &vers_1->ns);
@ -781,7 +798,7 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
p += 2;
}
jedec->nid = nid;
return CS_SUCCESS;
return 0;
}
/*====================================================================*/
@ -789,10 +806,10 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
{
if (tuple->TupleDataLen < 4)
return CS_BAD_TUPLE;
return -EINVAL;
m->manf = get_unaligned_le16(tuple->TupleData);
m->card = get_unaligned_le16(tuple->TupleData + 2);
return CS_SUCCESS;
return 0;
}
/*====================================================================*/
@ -801,11 +818,11 @@ static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f)
{
u_char *p;
if (tuple->TupleDataLen < 2)
return CS_BAD_TUPLE;
return -EINVAL;
p = (u_char *)tuple->TupleData;
f->func = p[0];
f->sysinit = p[1];
return CS_SUCCESS;
return 0;
}
/*====================================================================*/
@ -815,12 +832,12 @@ static int parse_funce(tuple_t *tuple, cistpl_funce_t *f)
u_char *p;
int i;
if (tuple->TupleDataLen < 1)
return CS_BAD_TUPLE;
return -EINVAL;
p = (u_char *)tuple->TupleData;
f->type = p[0];
for (i = 1; i < tuple->TupleDataLen; i++)
f->data[i-1] = p[i];
return CS_SUCCESS;
return 0;
}
/*====================================================================*/
@ -834,7 +851,7 @@ static int parse_config(tuple_t *tuple, cistpl_config_t *config)
rasz = *p & 0x03;
rmsz = (*p & 0x3c) >> 2;
if (tuple->TupleDataLen < rasz+rmsz+4)
return CS_BAD_TUPLE;
return -EINVAL;
config->last_idx = *(++p);
p++;
config->base = 0;
@ -846,7 +863,7 @@ static int parse_config(tuple_t *tuple, cistpl_config_t *config)
for (i = 0; i <= rmsz; i++)
config->rmask[i>>2] += p[i] << (8*(i%4));
config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4);
return CS_SUCCESS;
return 0;
}
/*======================================================================
@ -1002,10 +1019,12 @@ static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem)
static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq)
{
if (p == q) return NULL;
if (p == q)
return NULL;
irq->IRQInfo1 = *p; p++;
if (irq->IRQInfo1 & IRQ_INFO2_VALID) {
if (p+2 > q) return NULL;
if (p+2 > q)
return NULL;
irq->IRQInfo2 = (p[1]<<8) + p[0];
p += 2;
}
@ -1026,7 +1045,8 @@ static int parse_cftable_entry(tuple_t *tuple,
if (*p & 0x40)
entry->flags |= CISTPL_CFTABLE_DEFAULT;
if (*p & 0x80) {
if (++p == q) return CS_BAD_TUPLE;
if (++p == q)
return -EINVAL;
if (*p & 0x10)
entry->flags |= CISTPL_CFTABLE_BVDS;
if (*p & 0x20)
@ -1040,30 +1060,35 @@ static int parse_cftable_entry(tuple_t *tuple,
entry->interface = 0;
/* Process optional features */
if (++p == q) return CS_BAD_TUPLE;
if (++p == q)
return -EINVAL;
features = *p; p++;
/* Power options */
if ((features & 3) > 0) {
p = parse_power(p, q, &entry->vcc);
if (p == NULL) return CS_BAD_TUPLE;
if (p == NULL)
return -EINVAL;
} else
entry->vcc.present = 0;
if ((features & 3) > 1) {
p = parse_power(p, q, &entry->vpp1);
if (p == NULL) return CS_BAD_TUPLE;
if (p == NULL)
return -EINVAL;
} else
entry->vpp1.present = 0;
if ((features & 3) > 2) {
p = parse_power(p, q, &entry->vpp2);
if (p == NULL) return CS_BAD_TUPLE;
if (p == NULL)
return -EINVAL;
} else
entry->vpp2.present = 0;
/* Timing options */
if (features & 0x04) {
p = parse_timing(p, q, &entry->timing);
if (p == NULL) return CS_BAD_TUPLE;
if (p == NULL)
return -EINVAL;
} else {
entry->timing.wait = 0;
entry->timing.ready = 0;
@ -1073,14 +1098,16 @@ static int parse_cftable_entry(tuple_t *tuple,
/* I/O window options */
if (features & 0x08) {
p = parse_io(p, q, &entry->io);
if (p == NULL) return CS_BAD_TUPLE;
if (p == NULL)
return -EINVAL;
} else
entry->io.nwin = 0;
/* Interrupt options */
if (features & 0x10) {
p = parse_irq(p, q, &entry->irq);
if (p == NULL) return CS_BAD_TUPLE;
if (p == NULL)
return -EINVAL;
} else
entry->irq.IRQInfo1 = 0;
@ -1094,7 +1121,8 @@ static int parse_cftable_entry(tuple_t *tuple,
entry->mem.win[0].card_addr = 0;
entry->mem.win[0].host_addr = 0;
p += 2;
if (p > q) return CS_BAD_TUPLE;
if (p > q)
return -EINVAL;
break;
case 0x40:
entry->mem.nwin = 1;
@ -1102,26 +1130,30 @@ static int parse_cftable_entry(tuple_t *tuple,
entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8;
entry->mem.win[0].host_addr = 0;
p += 4;
if (p > q) return CS_BAD_TUPLE;
if (p > q)
return -EINVAL;
break;
case 0x60:
p = parse_mem(p, q, &entry->mem);
if (p == NULL) return CS_BAD_TUPLE;
if (p == NULL)
return -EINVAL;
break;
}
/* Misc features */
if (features & 0x80) {
if (p == q) return CS_BAD_TUPLE;
if (p == q)
return -EINVAL;
entry->flags |= (*p << 8);
while (*p & 0x80)
if (++p == q) return CS_BAD_TUPLE;
if (++p == q)
return -EINVAL;
p++;
}
entry->subtuples = q-p;
return CS_SUCCESS;
return 0;
}
/*====================================================================*/
@ -1132,12 +1164,12 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar)
{
u_char *p;
if (tuple->TupleDataLen < 6)
return CS_BAD_TUPLE;
return -EINVAL;
p = (u_char *)tuple->TupleData;
bar->attr = *p;
p += 2;
bar->size = get_unaligned_le32(p);
return CS_SUCCESS;
return 0;
}
static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
@ -1146,12 +1178,12 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
p = (u_char *)tuple->TupleData;
if ((*p != 3) || (tuple->TupleDataLen < 6))
return CS_BAD_TUPLE;
return -EINVAL;
config->last_idx = *(++p);
p++;
config->base = get_unaligned_le32(p);
config->subtuples = tuple->TupleDataLen - 6;
return CS_SUCCESS;
return 0;
}
static int parse_cftable_entry_cb(tuple_t *tuple,
@ -1167,29 +1199,34 @@ static int parse_cftable_entry_cb(tuple_t *tuple,
entry->flags |= CISTPL_CFTABLE_DEFAULT;
/* Process optional features */
if (++p == q) return CS_BAD_TUPLE;
if (++p == q)
return -EINVAL;
features = *p; p++;
/* Power options */
if ((features & 3) > 0) {
p = parse_power(p, q, &entry->vcc);
if (p == NULL) return CS_BAD_TUPLE;
if (p == NULL)
return -EINVAL;
} else
entry->vcc.present = 0;
if ((features & 3) > 1) {
p = parse_power(p, q, &entry->vpp1);
if (p == NULL) return CS_BAD_TUPLE;
if (p == NULL)
return -EINVAL;
} else
entry->vpp1.present = 0;
if ((features & 3) > 2) {
p = parse_power(p, q, &entry->vpp2);
if (p == NULL) return CS_BAD_TUPLE;
if (p == NULL)
return -EINVAL;
} else
entry->vpp2.present = 0;
/* I/O window options */
if (features & 0x08) {
if (p == q) return CS_BAD_TUPLE;
if (p == q)
return -EINVAL;
entry->io = *p; p++;
} else
entry->io = 0;
@ -1197,32 +1234,37 @@ static int parse_cftable_entry_cb(tuple_t *tuple,
/* Interrupt options */
if (features & 0x10) {
p = parse_irq(p, q, &entry->irq);
if (p == NULL) return CS_BAD_TUPLE;
if (p == NULL)
return -EINVAL;
} else
entry->irq.IRQInfo1 = 0;
if (features & 0x20) {
if (p == q) return CS_BAD_TUPLE;
if (p == q)
return -EINVAL;
entry->mem = *p; p++;
} else
entry->mem = 0;
/* Misc features */
if (features & 0x80) {
if (p == q) return CS_BAD_TUPLE;
if (p == q)
return -EINVAL;
entry->flags |= (*p << 8);
if (*p & 0x80) {
if (++p == q) return CS_BAD_TUPLE;
if (++p == q)
return -EINVAL;
entry->flags |= (*p << 16);
}
while (*p & 0x80)
if (++p == q) return CS_BAD_TUPLE;
if (++p == q)
return -EINVAL;
p++;
}
entry->subtuples = q-p;
return CS_SUCCESS;
return 0;
}
#endif
@ -1248,7 +1290,7 @@ static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo)
p += 6;
}
geo->ngeo = n;
return CS_SUCCESS;
return 0;
}
/*====================================================================*/
@ -1258,7 +1300,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
u_char *p, *q;
if (tuple->TupleDataLen < 10)
return CS_BAD_TUPLE;
return -EINVAL;
p = tuple->TupleData;
q = p + tuple->TupleDataLen;
@ -1282,15 +1324,18 @@ static int parse_org(tuple_t *tuple, cistpl_org_t *org)
p = tuple->TupleData;
q = p + tuple->TupleDataLen;
if (p == q) return CS_BAD_TUPLE;
if (p == q)
return -EINVAL;
org->data_org = *p;
if (++p == q) return CS_BAD_TUPLE;
if (++p == q)
return -EINVAL;
for (i = 0; i < 30; i++) {
org->desc[i] = *p;
if (*p == '\0') break;
if (++p == q) return CS_BAD_TUPLE;
if (++p == q)
return -EINVAL;
}
return CS_SUCCESS;
return 0;
}
/*====================================================================*/
@ -1300,7 +1345,7 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
u_char *p;
if (tuple->TupleDataLen < 10)
return CS_BAD_TUPLE;
return -EINVAL;
p = tuple->TupleData;
@ -1309,17 +1354,17 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
fmt->offset = get_unaligned_le32(p + 2);
fmt->length = get_unaligned_le32(p + 6);
return CS_SUCCESS;
return 0;
}
/*====================================================================*/
int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse)
int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
{
int ret = CS_SUCCESS;
int ret = 0;
if (tuple->TupleDataLen > tuple->TupleDataMax)
return CS_BAD_TUPLE;
return -EINVAL;
switch (tuple->TupleCode) {
case CISTPL_DEVICE:
case CISTPL_DEVICE_A:
@ -1387,15 +1432,17 @@ int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse)
break;
case CISTPL_NO_LINK:
case CISTPL_LINKTARGET:
ret = CS_SUCCESS;
ret = 0;
break;
default:
ret = CS_UNSUPPORTED_FUNCTION;
ret = -EINVAL;
break;
}
if (ret)
__cs_dbg(0, "parse_tuple failed %d\n", ret);
return ret;
}
EXPORT_SYMBOL(pccard_parse_tuple);
EXPORT_SYMBOL(pcmcia_parse_tuple);
/*======================================================================
@ -1410,18 +1457,22 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t
int ret;
buf = kmalloc(256, GFP_KERNEL);
if (buf == NULL)
return CS_OUT_OF_RESOURCE;
if (buf == NULL) {
dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
return -ENOMEM;
}
tuple.DesiredTuple = code;
tuple.Attributes = TUPLE_RETURN_COMMON;
ret = pccard_get_first_tuple(s, function, &tuple);
if (ret != CS_SUCCESS) goto done;
if (ret != 0)
goto done;
tuple.TupleData = buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
ret = pccard_get_tuple_data(s, &tuple);
if (ret != CS_SUCCESS) goto done;
ret = pccard_parse_tuple(&tuple, parse);
if (ret != 0)
goto done;
ret = pcmcia_parse_tuple(&tuple, parse);
done:
kfree(buf);
return ret;
@ -1446,37 +1497,40 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned
int ret, reserved, dev_ok = 0, ident_ok = 0;
if (!s)
return CS_BAD_HANDLE;
return -EINVAL;
tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
if (tuple == NULL)
return CS_OUT_OF_RESOURCE;
if (tuple == NULL) {
dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
return -ENOMEM;
}
p = kmalloc(sizeof(*p), GFP_KERNEL);
if (p == NULL) {
kfree(tuple);
return CS_OUT_OF_RESOURCE;
kfree(tuple);
dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
return -ENOMEM;
}
count = reserved = 0;
tuple->DesiredTuple = RETURN_FIRST_TUPLE;
tuple->Attributes = TUPLE_RETURN_COMMON;
ret = pccard_get_first_tuple(s, function, tuple);
if (ret != CS_SUCCESS)
if (ret != 0)
goto done;
/* First tuple should be DEVICE; we should really have either that
or a CFTABLE_ENTRY of some sort */
if ((tuple->TupleCode == CISTPL_DEVICE) ||
(pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == CS_SUCCESS) ||
(pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == CS_SUCCESS))
(pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == 0) ||
(pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == 0))
dev_ok++;
/* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
tuple, for card identification. Certain old D-Link and Linksys
cards have only a broken VERS_2 tuple; hence the bogus test. */
if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == CS_SUCCESS) ||
(pccard_read_tuple(s, function, CISTPL_VERS_1, p) == CS_SUCCESS) ||
(pccard_read_tuple(s, function, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS))
if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == 0) ||
(pccard_read_tuple(s, function, CISTPL_VERS_1, p) == 0) ||
(pccard_read_tuple(s, function, CISTPL_VERS_2, p) != -ENOSPC))
ident_ok++;
if (!dev_ok && !ident_ok)
@ -1484,7 +1538,8 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned
for (count = 1; count < MAX_TUPLES; count++) {
ret = pccard_get_next_tuple(s, function, tuple);
if (ret != CS_SUCCESS) break;
if (ret != 0)
break;
if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
@ -1499,6 +1554,6 @@ done:
*info = count;
kfree(tuple);
kfree(p);
return CS_SUCCESS;
return 0;
}
EXPORT_SYMBOL(pccard_validate_cis);

View File

@ -61,7 +61,7 @@ INT_MODULE_PARM(unreset_limit, 30); /* unreset_check's */
/* Access speed for attribute memory windows */
INT_MODULE_PARM(cis_speed, 300); /* ns */
#ifdef DEBUG
#ifdef CONFIG_PCMCIA_DEBUG
static int pc_debug;
module_param(pc_debug, int, 0644);
@ -247,7 +247,8 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
wait_for_completion(&socket->thread_done);
if (!socket->thread) {
printk(KERN_WARNING "PCMCIA: warning: socket thread for socket %p did not start\n", socket);
dev_printk(KERN_WARNING, &socket->dev,
"PCMCIA: warning: socket thread did not start\n");
return -EIO;
}
@ -366,16 +367,16 @@ static int socket_reset(struct pcmcia_socket *skt)
skt->ops->get_status(skt, &status);
if (!(status & SS_DETECT))
return CS_NO_CARD;
return -ENODEV;
if (status & SS_READY)
return CS_SUCCESS;
return 0;
msleep(unreset_check * 10);
}
cs_err(skt, "time out after reset.\n");
return CS_GENERAL_FAILURE;
return -ETIMEDOUT;
}
/*
@ -412,7 +413,8 @@ static void socket_shutdown(struct pcmcia_socket *s)
s->ops->get_status(s, &status);
if (status & SS_POWERON) {
printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
dev_printk(KERN_ERR, &s->dev,
"*** DANGER *** unable to remove socket power\n");
}
cs_socket_put(s);
@ -426,14 +428,14 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
skt->ops->get_status(skt, &status);
if (!(status & SS_DETECT))
return CS_NO_CARD;
return -ENODEV;
msleep(initial_delay * 10);
for (i = 0; i < 100; i++) {
skt->ops->get_status(skt, &status);
if (!(status & SS_DETECT))
return CS_NO_CARD;
return -ENODEV;
if (!(status & SS_PENDING))
break;
@ -443,13 +445,13 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
if (status & SS_PENDING) {
cs_err(skt, "voltage interrogation timed out.\n");
return CS_GENERAL_FAILURE;
return -ETIMEDOUT;
}
if (status & SS_CARDBUS) {
if (!(skt->features & SS_CAP_CARDBUS)) {
cs_err(skt, "cardbus cards are not supported.\n");
return CS_BAD_TYPE;
return -EINVAL;
}
skt->state |= SOCKET_CARDBUS;
}
@ -463,7 +465,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
skt->socket.Vcc = skt->socket.Vpp = 50;
else {
cs_err(skt, "unsupported voltage key.\n");
return CS_BAD_TYPE;
return -EIO;
}
if (skt->power_hook)
@ -480,7 +482,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
skt->ops->get_status(skt, &status);
if (!(status & SS_POWERON)) {
cs_err(skt, "unable to apply power.\n");
return CS_BAD_TYPE;
return -EIO;
}
status = socket_reset(skt);
@ -502,15 +504,16 @@ static int socket_insert(struct pcmcia_socket *skt)
cs_dbg(skt, 4, "insert\n");
if (!cs_socket_get(skt))
return CS_NO_CARD;
return -ENODEV;
ret = socket_setup(skt, setup_delay);
if (ret == CS_SUCCESS) {
if (ret == 0) {
skt->state |= SOCKET_PRESENT;
printk(KERN_NOTICE "pccard: %s card inserted into slot %d\n",
(skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
skt->sock);
dev_printk(KERN_NOTICE, &skt->dev,
"pccard: %s card inserted into slot %d\n",
(skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
skt->sock);
#ifdef CONFIG_CARDBUS
if (skt->state & SOCKET_CARDBUS) {
@ -531,7 +534,7 @@ static int socket_insert(struct pcmcia_socket *skt)
static int socket_suspend(struct pcmcia_socket *skt)
{
if (skt->state & SOCKET_SUSPEND)
return CS_IN_USE;
return -EBUSY;
send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
skt->socket = dead_socket;
@ -540,7 +543,7 @@ static int socket_suspend(struct pcmcia_socket *skt)
skt->ops->suspend(skt);
skt->state |= SOCKET_SUSPEND;
return CS_SUCCESS;
return 0;
}
/*
@ -553,7 +556,7 @@ static int socket_resume(struct pcmcia_socket *skt)
int ret;
if (!(skt->state & SOCKET_SUSPEND))
return CS_IN_USE;
return -EBUSY;
skt->socket = dead_socket;
skt->ops->init(skt);
@ -565,7 +568,7 @@ static int socket_resume(struct pcmcia_socket *skt)
}
ret = socket_setup(skt, resume_delay);
if (ret == CS_SUCCESS) {
if (ret == 0) {
/*
* FIXME: need a better check here for cardbus cards.
*/
@ -590,12 +593,13 @@ static int socket_resume(struct pcmcia_socket *skt)
skt->state &= ~SOCKET_SUSPEND;
return CS_SUCCESS;
return 0;
}
static void socket_remove(struct pcmcia_socket *skt)
{
printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock);
dev_printk(KERN_NOTICE, &skt->dev,
"pccard: card ejected from slot %d\n", skt->sock);
socket_shutdown(skt);
}
@ -641,8 +645,8 @@ static int pccardd(void *__skt)
/* register with the device core */
ret = device_register(&skt->dev);
if (ret) {
printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n",
skt);
dev_printk(KERN_WARNING, &skt->dev,
"PCMCIA: unable to register socket\n");
skt->thread = NULL;
complete(&skt->thread_done);
return 0;
@ -748,7 +752,7 @@ EXPORT_SYMBOL(pccard_register_pcmcia);
* CIS register.
*/
int pccard_reset_card(struct pcmcia_socket *skt)
int pcmcia_reset_card(struct pcmcia_socket *skt)
{
int ret;
@ -757,15 +761,15 @@ int pccard_reset_card(struct pcmcia_socket *skt)
mutex_lock(&skt->skt_mutex);
do {
if (!(skt->state & SOCKET_PRESENT)) {
ret = CS_NO_CARD;
ret = -ENODEV;
break;
}
if (skt->state & SOCKET_SUSPEND) {
ret = CS_IN_USE;
ret = -EBUSY;
break;
}
if (skt->state & SOCKET_CARDBUS) {
ret = CS_UNSUPPORTED_FUNCTION;
ret = -EPERM;
break;
}
@ -774,20 +778,20 @@ int pccard_reset_card(struct pcmcia_socket *skt)
send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
if (skt->callback)
skt->callback->suspend(skt);
if (socket_reset(skt) == CS_SUCCESS) {
if (socket_reset(skt) == 0) {
send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
if (skt->callback)
skt->callback->resume(skt);
}
}
ret = CS_SUCCESS;
ret = 0;
} while (0);
mutex_unlock(&skt->skt_mutex);
return ret;
} /* reset_card */
EXPORT_SYMBOL(pccard_reset_card);
EXPORT_SYMBOL(pcmcia_reset_card);
/* These shut down or wake up a socket. They are sort of user
@ -802,11 +806,11 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
mutex_lock(&skt->skt_mutex);
do {
if (!(skt->state & SOCKET_PRESENT)) {
ret = CS_NO_CARD;
ret = -ENODEV;
break;
}
if (skt->state & SOCKET_CARDBUS) {
ret = CS_UNSUPPORTED_FUNCTION;
ret = -EPERM;
break;
}
if (skt->callback) {
@ -832,11 +836,11 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
mutex_lock(&skt->skt_mutex);
do {
if (!(skt->state & SOCKET_PRESENT)) {
ret = CS_NO_CARD;
ret = -ENODEV;
break;
}
if (skt->state & SOCKET_CARDBUS) {
ret = CS_UNSUPPORTED_FUNCTION;
ret = -EPERM;
break;
}
ret = socket_resume(skt);
@ -892,7 +896,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
ret = -EBUSY;
break;
}
if (socket_insert(skt) == CS_NO_CARD) {
if (socket_insert(skt) == -ENODEV) {
ret = -ENODEV;
break;
}

View File

@ -1,5 +1,5 @@
/*
* cs_internal.h
* cs_internal.h -- definitions internal to the PCMCIA core modules
*
* 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
@ -10,6 +10,12 @@
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
*
* (C) 1999 David A. Hinds
* (C) 2003 - 2008 Dominik Brodowski
*
*
* This file contains definitions _only_ needed by the PCMCIA core modules.
* It must not be included by PCMCIA socket drivers or by PCMCIA device
* drivers.
*/
#ifndef _LINUX_CS_INTERNAL_H
@ -18,29 +24,24 @@
#include <linux/kref.h>
/* Flags in client state */
#define CLIENT_CONFIG_LOCKED 0x0001
#define CLIENT_IRQ_REQ 0x0002
#define CLIENT_IO_REQ 0x0004
#define CLIENT_UNBOUND 0x0008
#define CLIENT_STALE 0x0010
#define CLIENT_WIN_REQ(i) (0x1<<(i))
#define CLIENT_CARDBUS 0x8000
/* Each card function gets one of these guys */
typedef struct config_t {
struct kref ref;
u_int state;
u_int Attributes;
u_int IntType;
u_int ConfigBase;
u_char Status, Pin, Copy, Option, ExtStatus;
u_int CardValues;
io_req_t io;
struct {
u_int Attributes;
} irq;
unsigned int state;
unsigned int Attributes;
unsigned int IntType;
unsigned int ConfigBase;
unsigned char Status, Pin, Copy, Option, ExtStatus;
unsigned int CardValues;
io_req_t io;
struct {
u_int Attributes;
} irq;
} config_t;
struct cis_cache_entry {
struct list_head node;
unsigned int addr;
@ -49,6 +50,30 @@ struct cis_cache_entry {
unsigned char cache[0];
};
struct pccard_resource_ops {
int (*validate_mem) (struct pcmcia_socket *s);
int (*adjust_io_region) (struct resource *res,
unsigned long r_start,
unsigned long r_end,
struct pcmcia_socket *s);
struct resource* (*find_io) (unsigned long base, int num,
unsigned long align,
struct pcmcia_socket *s);
struct resource* (*find_mem) (unsigned long base, unsigned long num,
unsigned long align, int low,
struct pcmcia_socket *s);
int (*add_io) (struct pcmcia_socket *s,
unsigned int action,
unsigned long r_start,
unsigned long r_end);
int (*add_mem) (struct pcmcia_socket *s,
unsigned int action,
unsigned long r_start,
unsigned long r_end);
int (*init) (struct pcmcia_socket *s);
void (*exit) (struct pcmcia_socket *s);
};
/* Flags in config state */
#define CONFIG_LOCKED 0x01
#define CONFIG_IRQ_REQ 0x02
@ -59,7 +84,6 @@ struct cis_cache_entry {
#define SOCKET_INUSE 0x0010
#define SOCKET_SUSPEND 0x0080
#define SOCKET_WIN_REQ(i) (0x0100<<(i))
#define SOCKET_REGION_INFO 0x4000
#define SOCKET_CARDBUS 0x8000
#define SOCKET_CARDBUS_CONFIG 0x10000
@ -83,69 +107,153 @@ static inline void cs_socket_put(struct pcmcia_socket *skt)
}
}
/* In cardbus.c */
int cb_alloc(struct pcmcia_socket *s);
void cb_free(struct pcmcia_socket *s);
int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len, void *ptr);
#ifdef CONFIG_PCMCIA_DEBUG
extern int cs_debug_level(int);
/* In cistpl.c */
int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,
u_int addr, u_int len, void *ptr);
void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
u_int addr, u_int len, void *ptr);
void release_cis_mem(struct pcmcia_socket *s);
void destroy_cis_cache(struct pcmcia_socket *s);
#define cs_dbg(skt, lvl, fmt, arg...) do { \
if (cs_debug_level(lvl)) \
dev_printk(KERN_DEBUG, &skt->dev, \
"cs: " fmt, ## arg); \
} while (0)
#define __cs_dbg(lvl, fmt, arg...) do { \
if (cs_debug_level(lvl)) \
printk(KERN_DEBUG \
"cs: " fmt, ## arg); \
} while (0)
#else
#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0)
#define __cs_dbg(lvl, fmt, arg...) do { } while (0)
#endif
#define cs_err(skt, fmt, arg...) \
dev_printk(KERN_ERR, &skt->dev, "cs: " fmt, ## arg)
/*
* Stuff internal to module "pcmcia_core":
*/
/* cistpl.c */
int verify_cis_cache(struct pcmcia_socket *s);
int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse);
/* In rsrc_mgr */
int pcmcia_validate_mem(struct pcmcia_socket *s);
struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align,
struct pcmcia_socket *s);
int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,
unsigned long r_end, struct pcmcia_socket *s);
struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
int low, struct pcmcia_socket *s);
/* rsrc_mgr.c */
void release_resource_db(struct pcmcia_socket *s);
/* In socket_sysfs.c */
/* socket_sysfs.c */
extern int pccard_sysfs_add_socket(struct device *dev);
extern void pccard_sysfs_remove_socket(struct device *dev);
/* In cs.c */
extern struct rw_semaphore pcmcia_socket_list_rwsem;
extern struct list_head pcmcia_socket_list;
int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req);
int pccard_get_configuration_info(struct pcmcia_socket *s, struct pcmcia_device *p_dev, config_info_t *config);
int pccard_reset_card(struct pcmcia_socket *skt);
/* cardbus.c */
int cb_alloc(struct pcmcia_socket *s);
void cb_free(struct pcmcia_socket *s);
int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len,
void *ptr);
/*
* Stuff exported by module "pcmcia_core" to module "pcmcia"
*/
struct pcmcia_callback{
struct module *owner;
int (*event) (struct pcmcia_socket *s, event_t event, int priority);
int (*event) (struct pcmcia_socket *s,
event_t event, int priority);
void (*requery) (struct pcmcia_socket *s, int new_cis);
int (*suspend) (struct pcmcia_socket *s);
int (*resume) (struct pcmcia_socket *s);
};
/* cs.c */
extern struct rw_semaphore pcmcia_socket_list_rwsem;
extern struct list_head pcmcia_socket_list;
extern struct class pcmcia_socket_class;
int pcmcia_get_window(struct pcmcia_socket *s,
window_handle_t *handle,
int idx,
win_req_t *req);
int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr);
#define cs_socket_name(skt) ((skt)->dev.bus_id)
int pcmcia_suspend_card(struct pcmcia_socket *skt);
int pcmcia_resume_card(struct pcmcia_socket *skt);
#ifdef DEBUG
extern int cs_debug_level(int);
int pcmcia_eject_card(struct pcmcia_socket *skt);
int pcmcia_insert_card(struct pcmcia_socket *skt);
#define cs_dbg(skt, lvl, fmt, arg...) do { \
if (cs_debug_level(lvl)) \
printk(KERN_DEBUG "cs: %s: " fmt, \
cs_socket_name(skt) , ## arg); \
} while (0)
struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt);
void pcmcia_put_socket(struct pcmcia_socket *skt);
#else
#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0)
#endif
/* cistpl.c */
int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,
u_int addr, u_int len, void *ptr);
void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
u_int addr, u_int len, void *ptr);
void release_cis_mem(struct pcmcia_socket *s);
void destroy_cis_cache(struct pcmcia_socket *s);
int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
cisdata_t code, void *parse);
int pcmcia_replace_cis(struct pcmcia_socket *s,
const u8 *data, const size_t len);
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function,
unsigned int *count);
#define cs_err(skt, fmt, arg...) \
printk(KERN_ERR "cs: %s: " fmt, (skt)->dev.bus_id , ## arg)
/* rsrc_mgr.c */
int pcmcia_validate_mem(struct pcmcia_socket *s);
struct resource *pcmcia_find_io_region(unsigned long base,
int num,
unsigned long align,
struct pcmcia_socket *s);
int pcmcia_adjust_io_region(struct resource *res,
unsigned long r_start,
unsigned long r_end,
struct pcmcia_socket *s);
struct resource *pcmcia_find_mem_region(u_long base,
u_long num,
u_long align,
int low,
struct pcmcia_socket *s);
/*
* Stuff internal to module "pcmcia".
*/
/* ds.c */
extern struct bus_type pcmcia_bus_type;
/* pcmcia_resource.c */
extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
#ifdef CONFIG_PCMCIA_IOCTL
/* ds.c */
extern spinlock_t pcmcia_dev_list_lock;
extern struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev);
extern void pcmcia_put_dev(struct pcmcia_device *p_dev);
struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
unsigned int function);
/* pcmcia_ioctl.c */
extern void __init pcmcia_setup_ioctl(void);
extern void __exit pcmcia_cleanup_ioctl(void);
extern void handle_event(struct pcmcia_socket *s, event_t event);
extern int handle_request(struct pcmcia_socket *s, event_t event);
#else /* CONFIG_PCMCIA_IOCTL */
static inline void __init pcmcia_setup_ioctl(void) { return; }
static inline void __exit pcmcia_cleanup_ioctl(void) { return; }
static inline void handle_event(struct pcmcia_socket *s, event_t event)
{
return;
}
static inline int handle_request(struct pcmcia_socket *s, event_t event)
{
return 0;
}
#endif /* CONFIG_PCMCIA_IOCTL */
#endif /* _LINUX_CS_INTERNAL_H */

View File

@ -32,7 +32,6 @@
#include <pcmcia/ss.h>
#include "cs_internal.h"
#include "ds_internal.h"
/*====================================================================*/
@ -42,17 +41,22 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
MODULE_DESCRIPTION("PCMCIA Driver Services");
MODULE_LICENSE("GPL");
#ifdef DEBUG
#ifdef CONFIG_PCMCIA_DEBUG
int ds_pc_debug;
module_param_named(pc_debug, ds_pc_debug, int, 0644);
#define ds_dbg(lvl, fmt, arg...) do { \
if (ds_pc_debug > (lvl)) \
if (ds_pc_debug > (lvl)) \
printk(KERN_DEBUG "ds: " fmt , ## arg); \
} while (0)
#define ds_dev_dbg(lvl, dev, fmt, arg...) do { \
if (ds_pc_debug > (lvl)) \
dev_printk(KERN_DEBUG, dev, "ds: " fmt , ## arg); \
} while (0)
#else
#define ds_dbg(lvl, fmt, arg...) do { } while (0)
#define ds_dev_dbg(lvl, dev, fmt, arg...) do { } while (0)
#endif
spinlock_t pcmcia_dev_list_lock;
@ -64,42 +68,19 @@ spinlock_t pcmcia_dev_list_lock;
/* String tables for error messages */
typedef struct lookup_t {
int key;
char *msg;
const int key;
const char *msg;
} lookup_t;
static const lookup_t error_table[] = {
{ CS_SUCCESS, "Operation succeeded" },
{ CS_BAD_ADAPTER, "Bad adapter" },
{ CS_BAD_ATTRIBUTE, "Bad attribute", },
{ CS_BAD_BASE, "Bad base address" },
{ CS_BAD_EDC, "Bad EDC" },
{ CS_BAD_IRQ, "Bad IRQ" },
{ CS_BAD_OFFSET, "Bad offset" },
{ CS_BAD_PAGE, "Bad page number" },
{ CS_READ_FAILURE, "Read failure" },
{ CS_BAD_SIZE, "Bad size" },
{ CS_BAD_SOCKET, "Bad socket" },
{ CS_BAD_TYPE, "Bad type" },
{ CS_BAD_VCC, "Bad Vcc" },
{ CS_BAD_VPP, "Bad Vpp" },
{ CS_BAD_WINDOW, "Bad window" },
{ CS_WRITE_FAILURE, "Write failure" },
{ CS_NO_CARD, "No card present" },
{ CS_UNSUPPORTED_FUNCTION, "Usupported function" },
{ CS_UNSUPPORTED_MODE, "Unsupported mode" },
{ CS_BAD_SPEED, "Bad speed" },
{ CS_BUSY, "Resource busy" },
{ CS_GENERAL_FAILURE, "General failure" },
{ CS_WRITE_PROTECTED, "Write protected" },
{ CS_BAD_ARG_LENGTH, "Bad argument length" },
{ CS_BAD_ARGS, "Bad arguments" },
{ CS_CONFIGURATION_LOCKED, "Configuration locked" },
{ CS_IN_USE, "Resource in use" },
{ CS_NO_MORE_ITEMS, "No more items" },
{ CS_OUT_OF_RESOURCE, "Out of resource" },
{ CS_BAD_HANDLE, "Bad handle" },
{ CS_BAD_TUPLE, "Bad CIS tuple" }
{ 0, "Operation succeeded" },
{ -EIO, "Input/Output error" },
{ -ENODEV, "No card present" },
{ -EINVAL, "Bad parameter" },
{ -EACCES, "Configuration locked" },
{ -EBUSY, "Resource in use" },
{ -ENOSPC, "No more items" },
{ -ENOMEM, "Out of resource" },
};
@ -155,46 +136,32 @@ static const lookup_t service_table[] = {
{ ReplaceCIS, "ReplaceCIS" }
};
static int pcmcia_report_error(struct pcmcia_device *p_dev, error_info_t *err)
const char *pcmcia_error_func(int func)
{
int i;
char *serv;
if (!p_dev)
printk(KERN_NOTICE);
else
printk(KERN_NOTICE "%s: ", p_dev->dev.bus_id);
for (i = 0; i < ARRAY_SIZE(service_table); i++)
if (service_table[i].key == err->func)
break;
if (i < ARRAY_SIZE(service_table))
serv = service_table[i].msg;
else
serv = "Unknown service number";
if (service_table[i].key == func)
return service_table[i].msg;
return "Unknown service number";
}
EXPORT_SYMBOL(pcmcia_error_func);
const char *pcmcia_error_ret(int ret)
{
int i;
for (i = 0; i < ARRAY_SIZE(error_table); i++)
if (error_table[i].key == err->retcode)
break;
if (i < ARRAY_SIZE(error_table))
printk("%s: %s\n", serv, error_table[i].msg);
else
printk("%s: Unknown error code %#x\n", serv, err->retcode);
if (error_table[i].key == ret)
return error_table[i].msg;
return CS_SUCCESS;
} /* report_error */
/* end of code which was in cs.c before */
return "unknown";
}
EXPORT_SYMBOL(pcmcia_error_ret);
/*======================================================================*/
void cs_error(struct pcmcia_device *p_dev, int func, int ret)
{
error_info_t err = { func, ret };
pcmcia_report_error(p_dev, &err);
}
EXPORT_SYMBOL(cs_error);
static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
@ -391,7 +358,7 @@ static void pcmcia_release_function(struct kref *ref)
static void pcmcia_release_dev(struct device *dev)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
ds_dbg(1, "releasing device %s\n", p_dev->dev.bus_id);
ds_dev_dbg(1, dev, "releasing device\n");
pcmcia_put_socket(p_dev->socket);
kfree(p_dev->devname);
kref_put(&p_dev->function_config->ref, pcmcia_release_function);
@ -401,7 +368,7 @@ static void pcmcia_release_dev(struct device *dev)
static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc)
{
if (!s->pcmcia_state.device_add_pending) {
ds_dbg(1, "scheduling to add %s secondary"
ds_dev_dbg(1, &s->dev, "scheduling to add %s secondary"
" device to %d\n", mfc ? "mfc" : "pfc", s->sock);
s->pcmcia_state.device_add_pending = 1;
s->pcmcia_state.mfc_pfc = mfc;
@ -439,8 +406,7 @@ static int pcmcia_device_probe(struct device * dev)
*/
did = p_dev->dev.driver_data;
ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id,
p_drv->drv.name);
ds_dev_dbg(1, dev, "trying to bind to %s\n", p_drv->drv.name);
if ((!p_drv->probe) || (!p_dev->function_config) ||
(!try_module_get(p_drv->owner))) {
@ -455,15 +421,16 @@ static int pcmcia_device_probe(struct device * dev)
p_dev->conf.ConfigBase = cis_config.base;
p_dev->conf.Present = cis_config.rmask[0];
} else {
printk(KERN_INFO "pcmcia: could not parse base and rmask0 of CIS\n");
dev_printk(KERN_INFO, dev,
"pcmcia: could not parse base and rmask0 of CIS\n");
p_dev->conf.ConfigBase = 0;
p_dev->conf.Present = 0;
}
ret = p_drv->probe(p_dev);
if (ret) {
ds_dbg(1, "binding %s to %s failed with %d\n",
p_dev->dev.bus_id, p_drv->drv.name, ret);
ds_dev_dbg(1, dev, "binding to %s failed with %d\n",
p_drv->drv.name, ret);
goto put_module;
}
@ -490,8 +457,9 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
struct pcmcia_device *tmp;
unsigned long flags;
ds_dbg(2, "pcmcia_card_remove(%d) %s\n", s->sock,
leftover ? leftover->devname : "");
ds_dev_dbg(2, leftover ? &leftover->dev : &s->dev,
"pcmcia_card_remove(%d) %s\n", s->sock,
leftover ? leftover->devname : "");
if (!leftover)
s->device_count = 0;
@ -508,7 +476,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
p_dev->_removed=1;
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
ds_dbg(2, "unregistering device %s\n", p_dev->dev.bus_id);
ds_dev_dbg(2, &p_dev->dev, "unregistering device\n");
device_unregister(&p_dev->dev);
}
@ -525,7 +493,7 @@ static int pcmcia_device_remove(struct device * dev)
p_dev = to_pcmcia_dev(dev);
p_drv = to_pcmcia_drv(dev->driver);
ds_dbg(1, "removing device %s\n", p_dev->dev.bus_id);
ds_dev_dbg(1, dev, "removing device\n");
/* If we're removing the primary module driving a
* pseudo multi-function card, we need to unbind
@ -548,13 +516,15 @@ static int pcmcia_device_remove(struct device * dev)
/* check for proper unloading */
if (p_dev->_irq || p_dev->_io || p_dev->_locked)
printk(KERN_INFO "pcmcia: driver %s did not release config properly\n",
p_drv->drv.name);
dev_printk(KERN_INFO, dev,
"pcmcia: driver %s did not release config properly\n",
p_drv->drv.name);
for (i = 0; i < MAX_WIN; i++)
if (p_dev->_win & CLIENT_WIN_REQ(i))
printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n",
p_drv->drv.name);
dev_printk(KERN_INFO, dev,
"pcmcia: driver %s did not release window properly\n",
p_drv->drv.name);
/* references from pcmcia_probe_device */
pcmcia_put_dev(p_dev);
@ -603,8 +573,9 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
}
if (!pccard_read_tuple(p_dev->socket, p_dev->func,
CISTPL_DEVICE_GEO, devgeo)) {
ds_dbg(0, "mem device geometry probably means "
"FUNCID_MEMORY\n");
ds_dev_dbg(0, &p_dev->dev,
"mem device geometry probably means "
"FUNCID_MEMORY\n");
p_dev->func_id = CISTPL_FUNCID_MEMORY;
p_dev->has_func_id = 1;
}
@ -685,7 +656,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
if (!p_dev->devname)
goto err_free;
sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id);
ds_dbg(3, "devname is %s\n", p_dev->devname);
ds_dev_dbg(3, &p_dev->dev, "devname is %s\n", p_dev->devname);
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
@ -706,7 +677,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
if (!p_dev->function_config) {
ds_dbg(3, "creating config_t for %s\n", p_dev->dev.bus_id);
ds_dev_dbg(3, &p_dev->dev, "creating config_t\n");
p_dev->function_config = kzalloc(sizeof(struct config_t),
GFP_KERNEL);
if (!p_dev->function_config)
@ -714,8 +685,9 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
kref_init(&p_dev->function_config->ref);
}
printk(KERN_NOTICE "pcmcia: registering new device %s\n",
p_dev->devname);
dev_printk(KERN_NOTICE, &p_dev->dev,
"pcmcia: registering new device %s\n",
p_dev->devname);
pcmcia_device_query(p_dev);
@ -750,19 +722,20 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
int ret = 0;
if (!(s->resource_setup_done)) {
ds_dbg(3, "no resources available, delaying card_add\n");
ds_dev_dbg(3, &s->dev,
"no resources available, delaying card_add\n");
return -EAGAIN; /* try again, but later... */
}
if (pcmcia_validate_mem(s)) {
ds_dbg(3, "validating mem resources failed, "
ds_dev_dbg(3, &s->dev, "validating mem resources failed, "
"delaying card_add\n");
return -EAGAIN; /* try again, but later... */
}
ret = pccard_validate_cis(s, BIND_FN_ALL, &no_chains);
if (ret || !no_chains) {
ds_dbg(0, "invalid CIS or invalid resources\n");
ds_dev_dbg(0, &s->dev, "invalid CIS or invalid resources\n");
return -ENODEV;
}
@ -783,7 +756,7 @@ static void pcmcia_delayed_add_device(struct work_struct *work)
{
struct pcmcia_socket *s =
container_of(work, struct pcmcia_socket, device_add);
ds_dbg(1, "adding additional device to %d\n", s->sock);
ds_dev_dbg(1, &s->dev, "adding additional device to %d\n", s->sock);
pcmcia_device_add(s, s->pcmcia_state.mfc_pfc);
s->pcmcia_state.device_add_pending = 0;
s->pcmcia_state.mfc_pfc = 0;
@ -793,8 +766,7 @@ static int pcmcia_requery(struct device *dev, void * _data)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
if (!p_dev->dev.driver) {
ds_dbg(1, "update device information for %s\n",
p_dev->dev.bus_id);
ds_dev_dbg(1, dev, "update device information\n");
pcmcia_device_query(p_dev);
}
@ -808,7 +780,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis)
unsigned long flags;
/* must be called with skt_mutex held */
ds_dbg(0, "re-scanning socket %d\n", skt->sock);
ds_dev_dbg(0, &skt->dev, "re-scanning socket %d\n", skt->sock);
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
if (list_empty(&skt->devices_list))
@ -859,17 +831,17 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
int ret = -ENOMEM;
int no_funcs;
int old_funcs;
cisdump_t *cis;
cistpl_longlink_mfc_t mfc;
if (!filename)
return -EINVAL;
ds_dbg(1, "trying to load CIS file %s\n", filename);
ds_dev_dbg(1, &dev->dev, "trying to load CIS file %s\n", filename);
if (strlen(filename) > (FIRMWARE_NAME_MAX - 1)) {
printk(KERN_WARNING "pcmcia: CIS filename is too long [%s]\n",
filename);
dev_printk(KERN_WARNING, &dev->dev,
"pcmcia: CIS filename is too long [%s]\n",
filename);
return -EINVAL;
}
@ -878,23 +850,16 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
if (request_firmware(&fw, path, &dev->dev) == 0) {
if (fw->size >= CISTPL_MAX_CIS_SIZE) {
ret = -EINVAL;
printk(KERN_ERR "pcmcia: CIS override is too big\n");
dev_printk(KERN_ERR, &dev->dev,
"pcmcia: CIS override is too big\n");
goto release;
}
cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
if (!cis) {
ret = -ENOMEM;
goto release;
}
cis->Length = fw->size + 1;
memcpy(cis->Data, fw->data, fw->size);
if (!pcmcia_replace_cis(s, cis))
if (!pcmcia_replace_cis(s, fw->data, fw->size))
ret = 0;
else {
printk(KERN_ERR "pcmcia: CIS override failed\n");
dev_printk(KERN_ERR, &dev->dev,
"pcmcia: CIS override failed\n");
goto release;
}
@ -998,14 +963,14 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
* after it has re-checked that there is no possible module
* with a prod_id/manf_id/card_id match.
*/
ds_dbg(0, "skipping FUNC_ID match for %s until userspace "
"interaction\n", dev->dev.bus_id);
ds_dev_dbg(0, &dev->dev,
"skipping FUNC_ID match until userspace interaction\n");
if (!dev->allow_func_id_match)
return 0;
}
if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
ds_dbg(0, "device %s needs a fake CIS\n", dev->dev.bus_id);
ds_dev_dbg(0, &dev->dev, "device needs a fake CIS\n");
if (!dev->socket->fake_cis)
pcmcia_load_firmware(dev, did->cisfile);
@ -1037,11 +1002,9 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
/* match dynamic devices first */
spin_lock(&p_drv->dynids.lock);
list_for_each_entry(dynid, &p_drv->dynids.list, node) {
ds_dbg(3, "trying to match %s to %s\n", dev->bus_id,
drv->name);
ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name);
if (pcmcia_devmatch(p_dev, &dynid->id)) {
ds_dbg(0, "matched %s to %s\n", dev->bus_id,
drv->name);
ds_dev_dbg(0, dev, "matched to %s\n", drv->name);
spin_unlock(&p_drv->dynids.lock);
return 1;
}
@ -1051,18 +1014,15 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
#ifdef CONFIG_PCMCIA_IOCTL
/* matching by cardmgr */
if (p_dev->cardmgr == p_drv) {
ds_dbg(0, "cardmgr matched %s to %s\n", dev->bus_id,
drv->name);
ds_dev_dbg(0, dev, "cardmgr matched to %s\n", drv->name);
return 1;
}
#endif
while (did && did->match_flags) {
ds_dbg(3, "trying to match %s to %s\n", dev->bus_id,
drv->name);
ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name);
if (pcmcia_devmatch(p_dev, did)) {
ds_dbg(0, "matched %s to %s\n", dev->bus_id,
drv->name);
ds_dev_dbg(0, dev, "matched to %s\n", drv->name);
return 1;
}
did++;
@ -1268,7 +1228,7 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
if (p_dev->suspended)
return 0;
ds_dbg(2, "suspending %s\n", dev->bus_id);
ds_dev_dbg(2, dev, "suspending\n");
if (dev->driver)
p_drv = to_pcmcia_drv(dev->driver);
@ -1279,15 +1239,16 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
if (p_drv->suspend) {
ret = p_drv->suspend(p_dev);
if (ret) {
printk(KERN_ERR "pcmcia: device %s (driver %s) did "
"not want to go to sleep (%d)\n",
p_dev->devname, p_drv->drv.name, ret);
dev_printk(KERN_ERR, dev,
"pcmcia: device %s (driver %s) did "
"not want to go to sleep (%d)\n",
p_dev->devname, p_drv->drv.name, ret);
goto out;
}
}
if (p_dev->device_no == p_dev->func) {
ds_dbg(2, "releasing configuration for %s\n", dev->bus_id);
ds_dev_dbg(2, dev, "releasing configuration\n");
pcmcia_release_configuration(p_dev);
}
@ -1307,7 +1268,7 @@ static int pcmcia_dev_resume(struct device * dev)
if (!p_dev->suspended)
return 0;
ds_dbg(2, "resuming %s\n", dev->bus_id);
ds_dev_dbg(2, dev, "resuming\n");
if (dev->driver)
p_drv = to_pcmcia_drv(dev->driver);
@ -1316,7 +1277,7 @@ static int pcmcia_dev_resume(struct device * dev)
goto out;
if (p_dev->device_no == p_dev->func) {
ds_dbg(2, "requesting configuration for %s\n", dev->bus_id);
ds_dev_dbg(2, dev, "requesting configuration\n");
ret = pcmcia_request_configuration(p_dev, &p_dev->conf);
if (ret)
goto out;
@ -1358,14 +1319,14 @@ static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
static int pcmcia_bus_resume(struct pcmcia_socket *skt)
{
ds_dbg(2, "resuming socket %d\n", skt->sock);
ds_dev_dbg(2, &skt->dev, "resuming socket %d\n", skt->sock);
bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
return 0;
}
static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
{
ds_dbg(2, "suspending socket %d\n", skt->sock);
ds_dev_dbg(2, &skt->dev, "suspending socket %d\n", skt->sock);
if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
pcmcia_bus_suspend_callback)) {
pcmcia_bus_resume(skt);
@ -1391,13 +1352,14 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
struct pcmcia_socket *s = pcmcia_get_socket(skt);
if (!s) {
printk(KERN_ERR "PCMCIA obtaining reference to socket %p " \
"failed, event 0x%x lost!\n", skt, event);
dev_printk(KERN_ERR, &skt->dev,
"PCMCIA obtaining reference to socket " \
"failed, event 0x%x lost!\n", event);
return -ENODEV;
}
ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
event, priority, skt);
ds_dev_dbg(1, &skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
event, priority, skt);
switch (event) {
case CS_EVENT_CARD_REMOVAL:
@ -1472,7 +1434,8 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev,
socket = pcmcia_get_socket(socket);
if (!socket) {
printk(KERN_ERR "PCMCIA obtaining reference to socket %p failed\n", socket);
dev_printk(KERN_ERR, dev,
"PCMCIA obtaining reference to socket failed\n");
return -ENODEV;
}
@ -1492,7 +1455,7 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev,
ret = pccard_register_pcmcia(socket, &pcmcia_bus_callback);
if (ret) {
printk(KERN_ERR "PCMCIA registration PCCard core failed for socket %p\n", socket);
dev_printk(KERN_ERR, dev, "PCMCIA registration failed\n");
pcmcia_put_socket(socket);
return (ret);
}

View File

@ -1,23 +0,0 @@
/* ds_internal.h - internal header for 16-bit PCMCIA devices management */
extern spinlock_t pcmcia_dev_list_lock;
extern struct bus_type pcmcia_bus_type;
extern struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev);
extern void pcmcia_put_dev(struct pcmcia_device *p_dev);
struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function);
extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
#ifdef CONFIG_PCMCIA_IOCTL
extern void __init pcmcia_setup_ioctl(void);
extern void __exit pcmcia_cleanup_ioctl(void);
extern void handle_event(struct pcmcia_socket *s, event_t event);
extern int handle_request(struct pcmcia_socket *s, event_t event);
#else
static inline void __init pcmcia_setup_ioctl(void) { return; }
static inline void __exit pcmcia_cleanup_ioctl(void) { return; }
static inline void handle_event(struct pcmcia_socket *s, event_t event) { return; }
static inline int handle_request(struct pcmcia_socket *s, event_t event) { return CS_SUCCESS; }
#endif

View File

@ -46,7 +46,6 @@
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
#include <pcmcia/ss.h>
#include "cs_internal.h"
#define MODNAME "hd64465_ss"

View File

@ -63,7 +63,7 @@
#include "vg468.h"
#include "ricoh.h"
#ifdef DEBUG
#ifdef CONFIG_PCMCIA_DEBUG
static const char version[] =
"i82365.c 1.265 1999/11/10 18:36:21 (David Hinds)";

View File

@ -38,7 +38,7 @@
#include "m32r_cfc.h"
#ifdef DEBUG
#ifdef CONFIG_PCMCIA_DEBUG
static int m32r_cfc_debug;
module_param(m32r_cfc_debug, int, 0644);
#define debug(lvl, fmt, arg...) do { \
@ -505,7 +505,7 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
}
#ifdef DEBUG
#ifdef CONFIG_PCMCIA_DEBUG
if(state->flags & SS_IOCARD){
debug(3, ":IOCARD");
}

View File

@ -45,7 +45,7 @@
#define PCC_DEBUG_DBEX
#ifdef DEBUG
#ifdef CONFIG_PCMCIA_DEBUG
static int m32r_pcc_debug;
module_param(m32r_pcc_debug, int, 0644);
#define debug(lvl, fmt, arg...) do { \
@ -460,7 +460,7 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
pcc_set(sock,PCCSIGCR,reg);
#ifdef DEBUG
#ifdef CONFIG_PCMCIA_DEBUG
if(state->flags & SS_IOCARD){
debug(3, ":IOCARD");
}

View File

@ -64,8 +64,8 @@
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
#ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG;
#ifdef CONFIG_PCMCIA_DEBUG
static int pc_debug;
module_param(pc_debug, int, 0);
#define dprintk(args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
#else

View File

@ -140,7 +140,8 @@ static int o2micro_override(struct yenta_socket *socket)
a = config_readb(socket, O2_RESERVED1);
b = config_readb(socket, O2_RESERVED2);
printk(KERN_INFO "Yenta O2: res at 0x94/0xD4: %02x/%02x\n", a, b);
dev_printk(KERN_INFO, &socket->dev->dev,
"O2: res at 0x94/0xD4: %02x/%02x\n", a, b);
switch (socket->dev->device) {
/*
@ -153,7 +154,9 @@ static int o2micro_override(struct yenta_socket *socket)
case PCI_DEVICE_ID_O2_6812:
case PCI_DEVICE_ID_O2_6832:
case PCI_DEVICE_ID_O2_6836:
printk(KERN_INFO "Yenta O2: old bridge, disabling read prefetch/write burst\n");
dev_printk(KERN_INFO, &socket->dev->dev,
"Yenta O2: old bridge, disabling read "
"prefetch/write burst\n");
config_writeb(socket, O2_RESERVED1,
a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
config_writeb(socket, O2_RESERVED2,
@ -161,7 +164,8 @@ static int o2micro_override(struct yenta_socket *socket)
break;
default:
printk(KERN_INFO "Yenta O2: enabling read prefetch/write burst\n");
dev_printk(KERN_INFO , &socket->dev->dev,
"O2: enabling read prefetch/write burst\n");
config_writeb(socket, O2_RESERVED1,
a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
config_writeb(socket, O2_RESERVED2,

View File

@ -38,7 +38,6 @@
#include <pcmcia/ss.h>
#include "cs_internal.h"
#include "ds_internal.h"
static int major_dev = -1;
@ -58,7 +57,7 @@ typedef struct user_info_t {
} user_info_t;
#ifdef DEBUG
#ifdef CONFIG_PCMCIA_DEBUG
extern int ds_pc_debug;
#define ds_dbg(lvl, fmt, arg...) do { \
@ -149,7 +148,7 @@ static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
irq = adj->resource.irq.IRQ;
if ((irq < 0) || (irq > 15))
return CS_BAD_IRQ;
return -EINVAL;
if (adj->Action != REMOVE_MANAGED_RESOURCE)
return 0;
@ -167,7 +166,7 @@ static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
#else
static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
return CS_SUCCESS;
return 0;
}
#endif
@ -175,7 +174,7 @@ static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
static int pcmcia_adjust_resource_info(adjust_t *adj)
{
struct pcmcia_socket *s;
int ret = CS_UNSUPPORTED_FUNCTION;
int ret = -ENOSYS;
unsigned long flags;
down_read(&pcmcia_socket_list_rwsem);
@ -248,7 +247,7 @@ static int pccard_get_status(struct pcmcia_socket *s,
if (s->state & SOCKET_SUSPEND)
status->CardState |= CS_EVENT_PM_SUSPEND;
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
return -ENODEV;
c = (p_dev) ? p_dev->function_config : NULL;
@ -274,7 +273,7 @@ static int pccard_get_status(struct pcmcia_socket *s,
status->CardState |=
(reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
}
return CS_SUCCESS;
return 0;
}
status->CardState |=
(val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
@ -284,9 +283,81 @@ static int pccard_get_status(struct pcmcia_socket *s,
(val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
status->CardState |=
(val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
return CS_SUCCESS;
return 0;
} /* pccard_get_status */
int pccard_get_configuration_info(struct pcmcia_socket *s,
struct pcmcia_device *p_dev,
config_info_t *config)
{
config_t *c;
if (!(s->state & SOCKET_PRESENT))
return -ENODEV;
#ifdef CONFIG_CARDBUS
if (s->state & SOCKET_CARDBUS) {
memset(config, 0, sizeof(config_info_t));
config->Vcc = s->socket.Vcc;
config->Vpp1 = config->Vpp2 = s->socket.Vpp;
config->Option = s->cb_dev->subordinate->number;
if (s->state & SOCKET_CARDBUS_CONFIG) {
config->Attributes = CONF_VALID_CLIENT;
config->IntType = INT_CARDBUS;
config->AssignedIRQ = s->irq.AssignedIRQ;
if (config->AssignedIRQ)
config->Attributes |= CONF_ENABLE_IRQ;
if (s->io[0].res) {
config->BasePort1 = s->io[0].res->start;
config->NumPorts1 = s->io[0].res->end -
config->BasePort1 + 1;
}
}
return 0;
}
#endif
if (p_dev) {
c = p_dev->function_config;
config->Function = p_dev->func;
} else {
c = NULL;
config->Function = 0;
}
if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
config->Attributes = 0;
config->Vcc = s->socket.Vcc;
config->Vpp1 = config->Vpp2 = s->socket.Vpp;
return 0;
}
config->Attributes = c->Attributes | CONF_VALID_CLIENT;
config->Vcc = s->socket.Vcc;
config->Vpp1 = config->Vpp2 = s->socket.Vpp;
config->IntType = c->IntType;
config->ConfigBase = c->ConfigBase;
config->Status = c->Status;
config->Pin = c->Pin;
config->Copy = c->Copy;
config->Option = c->Option;
config->ExtStatus = c->ExtStatus;
config->Present = config->CardValues = c->CardValues;
config->IRQAttributes = c->irq.Attributes;
config->AssignedIRQ = s->irq.AssignedIRQ;
config->BasePort1 = c->io.BasePort1;
config->NumPorts1 = c->io.NumPorts1;
config->Attributes1 = c->io.Attributes1;
config->BasePort2 = c->io.BasePort2;
config->NumPorts2 = c->io.NumPorts2;
config->Attributes2 = c->io.Attributes2;
config->IOAddrLines = c->io.IOAddrLines;
return 0;
} /* pccard_get_configuration_info */
/*======================================================================
These manage a ring buffer of events pending for one user process
@ -764,7 +835,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
case DS_GET_CONFIGURATION_INFO:
if (buf->config.Function &&
(buf->config.Function >= s->functions))
ret = CS_BAD_ARGS;
ret = -EINVAL;
else {
struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
ret = pccard_get_configuration_info(s, p_dev, &buf->config);
@ -787,15 +858,15 @@ static int ds_ioctl(struct inode * inode, struct file * file,
break;
case DS_PARSE_TUPLE:
buf->tuple.TupleData = buf->tuple_parse.data;
ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
ret = pcmcia_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
break;
case DS_RESET_CARD:
ret = pccard_reset_card(s);
ret = pcmcia_reset_card(s);
break;
case DS_GET_STATUS:
if (buf->status.Function &&
(buf->status.Function >= s->functions))
ret = CS_BAD_ARGS;
ret = -EINVAL;
else {
struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
ret = pccard_get_status(s, p_dev, &buf->status);
@ -826,7 +897,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
goto free_out;
}
ret = CS_BAD_ARGS;
ret = -EINVAL;
if (!(buf->conf_reg.Function &&
(buf->conf_reg.Function >= s->functions))) {
@ -867,7 +938,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
&buf->win_info.map);
break;
case DS_REPLACE_CIS:
ret = pcmcia_replace_cis(s, &buf->cisdump);
ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length);
break;
case DS_BIND_REQUEST:
if (!capable(CAP_SYS_ADMIN)) {
@ -889,22 +960,19 @@ static int ds_ioctl(struct inode * inode, struct file * file,
err = -EINVAL;
}
if ((err == 0) && (ret != CS_SUCCESS)) {
if ((err == 0) && (ret != 0)) {
ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
switch (ret) {
case CS_BAD_SOCKET: case CS_NO_CARD:
err = -ENODEV; break;
case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
case CS_BAD_TUPLE:
err = -EINVAL; break;
case CS_IN_USE:
err = -EBUSY; break;
case CS_OUT_OF_RESOURCE:
case -ENODEV:
case -EINVAL:
case -EBUSY:
case -ENOSYS:
err = ret;
break;
case -ENOMEM:
err = -ENOSPC; break;
case CS_NO_MORE_ITEMS:
case -ENOSPC:
err = -ENODATA; break;
case CS_UNSUPPORTED_FUNCTION:
err = -ENOSYS; break;
default:
err = -EIO; break;
}

View File

@ -29,7 +29,6 @@
#include <pcmcia/ds.h>
#include "cs_internal.h"
#include "ds_internal.h"
/* Access speed for IO windows */
@ -44,16 +43,17 @@ static u8 pcmcia_used_irq[NR_IRQS];
#endif
#ifdef DEBUG
#ifdef CONFIG_PCMCIA_DEBUG
extern int ds_pc_debug;
#define ds_dbg(skt, lvl, fmt, arg...) do { \
if (ds_pc_debug >= lvl) \
printk(KERN_DEBUG "pcmcia_resource: %s: " fmt, \
cs_socket_name(skt) , ## arg); \
dev_printk(KERN_DEBUG, &skt->dev, \
"pcmcia_resource: " fmt, \
## arg); \
} while (0)
#else
#define ds_dbg(lvl, fmt, arg...) do { } while (0)
#define ds_dbg(skt, lvl, fmt, arg...) do { } while (0)
#endif
@ -168,13 +168,13 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
u_char val;
if (!p_dev || !p_dev->function_config)
return CS_NO_CARD;
return -EINVAL;
s = p_dev->socket;
c = p_dev->function_config;
if (!(c->state & CONFIG_LOCKED))
return CS_CONFIGURATION_LOCKED;
return -EACCES;
addr = (c->ConfigBase + reg->Offset) >> 1;
@ -188,93 +188,14 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
pcmcia_write_cis_mem(s, 1, addr, 1, &val);
break;
default:
return CS_BAD_ARGS;
return -EINVAL;
break;
}
return CS_SUCCESS;
return 0;
} /* pcmcia_access_configuration_register */
EXPORT_SYMBOL(pcmcia_access_configuration_register);
int pccard_get_configuration_info(struct pcmcia_socket *s,
struct pcmcia_device *p_dev,
config_info_t *config)
{
config_t *c;
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
#ifdef CONFIG_CARDBUS
if (s->state & SOCKET_CARDBUS) {
memset(config, 0, sizeof(config_info_t));
config->Vcc = s->socket.Vcc;
config->Vpp1 = config->Vpp2 = s->socket.Vpp;
config->Option = s->cb_dev->subordinate->number;
if (s->state & SOCKET_CARDBUS_CONFIG) {
config->Attributes = CONF_VALID_CLIENT;
config->IntType = INT_CARDBUS;
config->AssignedIRQ = s->irq.AssignedIRQ;
if (config->AssignedIRQ)
config->Attributes |= CONF_ENABLE_IRQ;
if (s->io[0].res) {
config->BasePort1 = s->io[0].res->start;
config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1;
}
}
return CS_SUCCESS;
}
#endif
if (p_dev) {
c = p_dev->function_config;
config->Function = p_dev->func;
} else {
c = NULL;
config->Function = 0;
}
if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
config->Attributes = 0;
config->Vcc = s->socket.Vcc;
config->Vpp1 = config->Vpp2 = s->socket.Vpp;
return CS_SUCCESS;
}
config->Attributes = c->Attributes | CONF_VALID_CLIENT;
config->Vcc = s->socket.Vcc;
config->Vpp1 = config->Vpp2 = s->socket.Vpp;
config->IntType = c->IntType;
config->ConfigBase = c->ConfigBase;
config->Status = c->Status;
config->Pin = c->Pin;
config->Copy = c->Copy;
config->Option = c->Option;
config->ExtStatus = c->ExtStatus;
config->Present = config->CardValues = c->CardValues;
config->IRQAttributes = c->irq.Attributes;
config->AssignedIRQ = s->irq.AssignedIRQ;
config->BasePort1 = c->io.BasePort1;
config->NumPorts1 = c->io.NumPorts1;
config->Attributes1 = c->io.Attributes1;
config->BasePort2 = c->io.BasePort2;
config->NumPorts2 = c->io.NumPorts2;
config->Attributes2 = c->io.Attributes2;
config->IOAddrLines = c->io.IOAddrLines;
return CS_SUCCESS;
} /* pccard_get_configuration_info */
int pcmcia_get_configuration_info(struct pcmcia_device *p_dev,
config_info_t *config)
{
return pccard_get_configuration_info(p_dev->socket, p_dev,
config);
}
EXPORT_SYMBOL(pcmcia_get_configuration_info);
/** pcmcia_get_window
*/
int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,
@ -284,12 +205,12 @@ int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,
int w;
if (!s || !(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
return -ENODEV;
for (w = idx; w < MAX_WIN; w++)
if (s->state & SOCKET_WIN_REQ(w))
break;
if (w == MAX_WIN)
return CS_NO_MORE_ITEMS;
return -EINVAL;
win = &s->win[w];
req->Base = win->ctl.res->start;
req->Size = win->ctl.res->end - win->ctl.res->start + 1;
@ -304,7 +225,7 @@ int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,
if (win->ctl.flags & MAP_USE_WAIT)
req->Attributes |= WIN_USE_WAIT;
*handle = win;
return CS_SUCCESS;
return 0;
} /* pcmcia_get_window */
EXPORT_SYMBOL(pcmcia_get_window);
@ -316,10 +237,10 @@ EXPORT_SYMBOL(pcmcia_get_window);
int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)
{
if ((win == NULL) || (win->magic != WINDOW_MAGIC))
return CS_BAD_HANDLE;
return -EINVAL;
req->Page = 0;
req->CardOffset = win->ctl.card_start;
return CS_SUCCESS;
return 0;
} /* pcmcia_get_mem_page */
EXPORT_SYMBOL(pcmcia_get_mem_page);
@ -328,14 +249,18 @@ int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)
{
struct pcmcia_socket *s;
if ((win == NULL) || (win->magic != WINDOW_MAGIC))
return CS_BAD_HANDLE;
if (req->Page != 0)
return CS_BAD_PAGE;
return -EINVAL;
s = win->sock;
if (req->Page != 0) {
ds_dbg(s, 0, "failure: requested page is zero\n");
return -EINVAL;
}
win->ctl.card_start = req->CardOffset;
if (s->ops->set_mem_map(s, &win->ctl) != 0)
return CS_BAD_OFFSET;
return CS_SUCCESS;
if (s->ops->set_mem_map(s, &win->ctl) != 0) {
ds_dbg(s, 0, "failed to set_mem_map\n");
return -EIO;
}
return 0;
} /* pcmcia_map_mem_page */
EXPORT_SYMBOL(pcmcia_map_mem_page);
@ -354,9 +279,9 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
c = p_dev->function_config;
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
return -ENODEV;
if (!(c->state & CONFIG_LOCKED))
return CS_CONFIGURATION_LOCKED;
return -EACCES;
if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
if (mod->Attributes & CONF_ENABLE_IRQ) {
@ -369,20 +294,28 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
s->ops->set_socket(s, &s->socket);
}
if (mod->Attributes & CONF_VCC_CHANGE_VALID)
return CS_BAD_VCC;
if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
ds_dbg(s, 0, "changing Vcc is not allowed at this time\n");
return -EINVAL;
}
/* 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)
return CS_BAD_VPP;
ds_dbg(s, 0, "Vpp1 and Vpp2 must be the same\n");
return -EINVAL;
s->socket.Vpp = mod->Vpp1;
if (s->ops->set_socket(s, &s->socket))
return CS_BAD_VPP;
if (s->ops->set_socket(s, &s->socket)) {
dev_printk(KERN_WARNING, &s->dev,
"Unable to set VPP\n");
return -EIO;
}
} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
(mod->Attributes & CONF_VPP2_CHANGE_VALID))
return CS_BAD_VPP;
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
ds_dbg(s, 0, "changing Vcc is not allowed at this time\n");
return -EINVAL;
}
if (mod->Attributes & CONF_IO_CHANGE_WIDTH) {
pccard_io_map io_off = { 0, 0, 0, 0, 1 };
@ -406,7 +339,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
}
}
return CS_SUCCESS;
return 0;
} /* modify_configuration */
EXPORT_SYMBOL(pcmcia_modify_configuration);
@ -441,7 +374,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
}
}
return CS_SUCCESS;
return 0;
} /* pcmcia_release_configuration */
@ -459,7 +392,7 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
config_t *c = p_dev->function_config;
if (!p_dev->_io )
return CS_BAD_HANDLE;
return -EINVAL;
p_dev->_io = 0;
@ -467,7 +400,7 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
(c->io.NumPorts1 != req->NumPorts1) ||
(c->io.BasePort2 != req->BasePort2) ||
(c->io.NumPorts2 != req->NumPorts2))
return CS_BAD_ARGS;
return -EINVAL;
c->state &= ~CONFIG_IO_REQ;
@ -475,7 +408,7 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
if (req->NumPorts2)
release_io_space(s, req->BasePort2, req->NumPorts2);
return CS_SUCCESS;
return 0;
} /* pcmcia_release_io */
@ -485,15 +418,19 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
config_t *c= p_dev->function_config;
if (!p_dev->_irq)
return CS_BAD_HANDLE;
return -EINVAL;
p_dev->_irq = 0;
if (c->state & CONFIG_LOCKED)
return CS_CONFIGURATION_LOCKED;
if (c->irq.Attributes != req->Attributes)
return CS_BAD_ATTRIBUTE;
if (s->irq.AssignedIRQ != req->AssignedIRQ)
return CS_BAD_IRQ;
return -EACCES;
if (c->irq.Attributes != req->Attributes) {
ds_dbg(s, 0, "IRQ attributes must match assigned ones\n");
return -EINVAL;
}
if (s->irq.AssignedIRQ != req->AssignedIRQ) {
ds_dbg(s, 0, "IRQ must match assigned one\n");
return -EINVAL;
}
if (--s->irq.Config == 0) {
c->state &= ~CONFIG_IRQ_REQ;
s->irq.AssignedIRQ = 0;
@ -507,7 +444,7 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
pcmcia_used_irq[req->AssignedIRQ]--;
#endif
return CS_SUCCESS;
return 0;
} /* pcmcia_release_irq */
@ -516,10 +453,10 @@ int pcmcia_release_window(window_handle_t win)
struct pcmcia_socket *s;
if ((win == NULL) || (win->magic != WINDOW_MAGIC))
return CS_BAD_HANDLE;
return -EINVAL;
s = win->sock;
if (!(win->handle->_win & CLIENT_WIN_REQ(win->index)))
return CS_BAD_HANDLE;
return -EINVAL;
/* Shut down memory window */
win->ctl.flags &= ~MAP_ACTIVE;
@ -536,7 +473,7 @@ int pcmcia_release_window(window_handle_t win)
win->magic = 0;
return CS_SUCCESS;
return 0;
} /* pcmcia_release_window */
EXPORT_SYMBOL(pcmcia_release_window);
@ -551,18 +488,23 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
pccard_io_map iomap;
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
return -ENODEV;;
if (req->IntType & INT_CARDBUS)
return CS_UNSUPPORTED_MODE;
if (req->IntType & INT_CARDBUS) {
ds_dbg(p_dev->socket, 0, "IntType may not be INT_CARDBUS\n");
return -EINVAL;
}
c = p_dev->function_config;
if (c->state & CONFIG_LOCKED)
return CS_CONFIGURATION_LOCKED;
return -EACCES;
/* Do power control. We don't allow changes in Vcc. */
s->socket.Vpp = req->Vpp;
if (s->ops->set_socket(s, &s->socket))
return CS_BAD_VPP;
if (s->ops->set_socket(s, &s->socket)) {
dev_printk(KERN_WARNING, &s->dev,
"Unable to set socket state\n");
return -EINVAL;
}
/* Pick memory or I/O card, DMA mode, interrupt */
c->IntType = req->IntType;
@ -651,7 +593,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
c->state |= CONFIG_LOCKED;
p_dev->_locked = 1;
return CS_SUCCESS;
return 0;
} /* pcmcia_request_configuration */
EXPORT_SYMBOL(pcmcia_request_configuration);
@ -667,37 +609,48 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
config_t *c;
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
return -ENODEV;
if (!req)
return CS_UNSUPPORTED_MODE;
return -EINVAL;
c = p_dev->function_config;
if (c->state & CONFIG_LOCKED)
return CS_CONFIGURATION_LOCKED;
if (c->state & CONFIG_IO_REQ)
return CS_IN_USE;
if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))
return CS_BAD_ATTRIBUTE;
return -EACCES;
if (c->state & CONFIG_IO_REQ) {
ds_dbg(s, 0, "IO already configured\n");
return -EBUSY;
}
if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) {
ds_dbg(s, 0, "bad attribute setting for IO region 1\n");
return -EINVAL;
}
if ((req->NumPorts2 > 0) &&
(req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)))
return CS_BAD_ATTRIBUTE;
(req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) {
ds_dbg(s, 0, "bad attribute setting for IO region 2\n");
return -EINVAL;
}
ds_dbg(s, 1, "trying to allocate resource 1\n");
if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
req->NumPorts1, req->IOAddrLines))
return CS_IN_USE;
req->NumPorts1, req->IOAddrLines)) {
ds_dbg(s, 0, "allocation of resource 1 failed\n");
return -EBUSY;
}
if (req->NumPorts2) {
ds_dbg(s, 1, "trying to allocate resource 2\n");
if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
req->NumPorts2, req->IOAddrLines)) {
ds_dbg(s, 0, "allocation of resource 2 failed\n");
release_io_space(s, req->BasePort1, req->NumPorts1);
return CS_IN_USE;
return -EBUSY;
}
}
c->io = *req;
c->state |= CONFIG_IO_REQ;
p_dev->_io = 1;
return CS_SUCCESS;
return 0;
} /* pcmcia_request_io */
EXPORT_SYMBOL(pcmcia_request_io);
@ -723,16 +676,18 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
{
struct pcmcia_socket *s = p_dev->socket;
config_t *c;
int ret = CS_IN_USE, irq = 0;
int ret = -EINVAL, irq = 0;
int type;
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
return -ENODEV;
c = p_dev->function_config;
if (c->state & CONFIG_LOCKED)
return CS_CONFIGURATION_LOCKED;
if (c->state & CONFIG_IRQ_REQ)
return CS_IN_USE;
return -EACCES;
if (c->state & CONFIG_IRQ_REQ) {
ds_dbg(s, 0, "IRQ already configured\n");
return -EBUSY;
}
/* Decide what type of interrupt we are registering */
type = 0;
@ -795,15 +750,19 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
}
if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) {
if (request_irq(irq, req->Handler, type, p_dev->devname, req->Instance))
return CS_IN_USE;
ret = request_irq(irq, req->Handler, type,
p_dev->devname, req->Instance);
if (ret)
return ret;
}
/* Make sure the fact the request type was overridden is passed back */
if (type == IRQF_SHARED && !(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) {
req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
printk(KERN_WARNING "pcmcia: request for exclusive IRQ could not be fulfilled.\n");
printk(KERN_WARNING "pcmcia: the driver needs updating to supported shared IRQ lines.\n");
dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: "
"request for exclusive IRQ could not be fulfilled.\n");
dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver "
"needs updating to supported shared IRQ lines.\n");
}
c->irq.Attributes = req->Attributes;
s->irq.AssignedIRQ = req->AssignedIRQ = irq;
@ -816,7 +775,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
pcmcia_used_irq[irq]++;
#endif
return CS_SUCCESS;
return 0;
} /* pcmcia_request_irq */
EXPORT_SYMBOL(pcmcia_request_irq);
@ -834,9 +793,11 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
int w;
if (!(s->state & SOCKET_PRESENT))
return CS_NO_CARD;
if (req->Attributes & (WIN_PAGED | WIN_SHARED))
return CS_BAD_ATTRIBUTE;
return -ENODEV;
if (req->Attributes & (WIN_PAGED | WIN_SHARED)) {
ds_dbg(s, 0, "bad attribute setting for iomem region\n");
return -EINVAL;
}
/* Window size defaults to smallest available */
if (req->Size == 0)
@ -844,19 +805,25 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
align = (((s->features & SS_CAP_MEM_ALIGN) ||
(req->Attributes & WIN_STRICT_ALIGN)) ?
req->Size : s->map_size);
if (req->Size & (s->map_size-1))
return CS_BAD_SIZE;
if (req->Size & (s->map_size-1)) {
ds_dbg(s, 0, "invalid map size\n");
return -EINVAL;
}
if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||
(req->Base & (align-1)))
return CS_BAD_BASE;
(req->Base & (align-1))) {
ds_dbg(s, 0, "invalid base address\n");
return -EINVAL;
}
if (req->Base)
align = 0;
/* Allocate system memory window */
for (w = 0; w < MAX_WIN; w++)
if (!(s->state & SOCKET_WIN_REQ(w))) break;
if (w == MAX_WIN)
return CS_OUT_OF_RESOURCE;
if (w == MAX_WIN) {
ds_dbg(s, 0, "all windows are used already\n");
return -EINVAL;
}
win = &s->win[w];
win->magic = WINDOW_MAGIC;
@ -867,8 +834,10 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
if (!(s->features & SS_CAP_STATIC_MAP)) {
win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align,
(req->Attributes & WIN_MAP_BELOW_1MB), s);
if (!win->ctl.res)
return CS_IN_USE;
if (!win->ctl.res) {
ds_dbg(s, 0, "allocating mem region failed\n");
return -EINVAL;
}
}
(*p_dev)->_win |= CLIENT_WIN_REQ(w);
@ -885,8 +854,10 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
if (req->Attributes & WIN_USE_WAIT)
win->ctl.flags |= MAP_USE_WAIT;
win->ctl.card_start = 0;
if (s->ops->set_mem_map(s, &win->ctl) != 0)
return CS_BAD_ARGS;
if (s->ops->set_mem_map(s, &win->ctl) != 0) {
ds_dbg(s, 0, "failed to set memory mapping\n");
return -EIO;
}
s->state |= SOCKET_WIN_REQ(w);
/* Return window handle */
@ -897,7 +868,7 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
}
*wh = win;
return CS_SUCCESS;
return 0;
} /* pcmcia_request_window */
EXPORT_SYMBOL(pcmcia_request_window);
@ -909,3 +880,79 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) {
pcmcia_release_window(p_dev->win);
}
EXPORT_SYMBOL(pcmcia_disable_device);
struct pcmcia_cfg_mem {
tuple_t tuple;
cisparse_t parse;
u8 buf[256];
cistpl_cftable_entry_t dflt;
};
/**
* pcmcia_loop_config() - loop over configuration options
* @p_dev: the struct pcmcia_device which we need to loop for.
* @conf_check: function to call for each configuration option.
* It gets passed the struct pcmcia_device, the CIS data
* describing the configuration option, and private data
* being passed to pcmcia_loop_config()
* @priv_data: private data to be passed to the conf_check function.
*
* pcmcia_loop_config() loops over all configuration options, and calls
* the driver-specific conf_check() for each one, checking whether
* it is a valid one.
*/
int pcmcia_loop_config(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)
{
struct pcmcia_cfg_mem *cfg_mem;
tuple_t *tuple;
int ret = -ENODEV;
unsigned int vcc;
cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
if (cfg_mem == NULL)
return -ENOMEM;
/* get the current Vcc setting */
vcc = p_dev->socket->socket.Vcc;
tuple = &cfg_mem->tuple;
tuple->TupleData = cfg_mem->buf;
tuple->TupleDataMax = 255;
tuple->TupleOffset = 0;
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple->Attributes = 0;
ret = pcmcia_get_first_tuple(p_dev, tuple);
while (!ret) {
cistpl_cftable_entry_t *cfg = &cfg_mem->parse.cftable_entry;
if (pcmcia_get_tuple_data(p_dev, tuple))
goto next_entry;
if (pcmcia_parse_tuple(tuple, &cfg_mem->parse))
goto next_entry;
/* default values */
p_dev->conf.ConfigIndex = cfg->index;
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
cfg_mem->dflt = *cfg;
ret = conf_check(p_dev, cfg, &cfg_mem->dflt, vcc, priv_data);
if (!ret)
break;
next_entry:
ret = pcmcia_get_next_tuple(p_dev, tuple);
}
return ret;
}
EXPORT_SYMBOL(pcmcia_loop_config);

View File

@ -36,7 +36,6 @@
#include <pcmcia/ss.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
#include "soc_common.h"
#include "pxa2xx_base.h"

View File

@ -122,19 +122,22 @@ static void free_region(struct resource *res)
static int add_interval(struct resource_map *map, u_long base, u_long num)
{
struct resource_map *p, *q;
struct resource_map *p, *q;
for (p = map; ; p = p->next) {
if ((p != map) && (p->base+p->num-1 >= base))
return -1;
if ((p->next == map) || (p->next->base > base+num-1))
break;
}
q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
if (!q) return CS_OUT_OF_RESOURCE;
q->base = base; q->num = num;
q->next = p->next; p->next = q;
return CS_SUCCESS;
for (p = map; ; p = p->next) {
if ((p != map) && (p->base+p->num-1 >= base))
return -1;
if ((p->next == map) || (p->next->base > base+num-1))
break;
}
q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
if (!q) {
printk(KERN_WARNING "out of memory to update resources\n");
return -ENOMEM;
}
q->base = base; q->num = num;
q->next = p->next; p->next = q;
return 0;
}
/*====================================================================*/
@ -166,7 +169,10 @@ static int sub_interval(struct resource_map *map, u_long base, u_long num)
} else {
/* Split the block into two pieces */
p = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
if (!p) return CS_OUT_OF_RESOURCE;
if (!p) {
printk(KERN_WARNING "out of memory to update resources\n");
return -ENOMEM;
}
p->base = base+num;
p->num = q->base+q->num - p->base;
q->num = base - q->base;
@ -174,7 +180,7 @@ static int sub_interval(struct resource_map *map, u_long base, u_long num)
}
}
}
return CS_SUCCESS;
return 0;
}
/*======================================================================
@ -194,13 +200,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
int any;
u_char *b, hole, most;
printk(KERN_INFO "cs: IO port probe %#x-%#x:",
base, base+num-1);
dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:",
base, base+num-1);
/* First, what does a floating port look like? */
b = kzalloc(256, GFP_KERNEL);
if (!b) {
printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
dev_printk(KERN_ERR, &s->dev,
"do_io_probe: unable to kmalloc 256 bytes");
return;
}
for (i = base, most = 0; i < base+num; i += 8) {
@ -366,8 +373,8 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
struct socket_data *s_data = s->resource_data;
u_long i, j, bad, fail, step;
printk(KERN_INFO "cs: memory probe 0x%06lx-0x%06lx:",
base, base+num-1);
dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
base, base+num-1);
bad = fail = 0;
step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
/* don't allow too large steps */
@ -431,8 +438,8 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
if (probe_mask & MEM_PROBE_HIGH) {
if (inv_probe(s_data->mem_db.next, s) > 0)
return 0;
printk(KERN_NOTICE "cs: warning: no high memory space "
"available!\n");
dev_printk(KERN_NOTICE, &s->dev,
"cs: warning: no high memory space available!\n");
return -ENODEV;
}
@ -794,10 +801,11 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
if (res->flags & IORESOURCE_IO) {
if (res == &ioport_resource)
continue;
printk(KERN_INFO "pcmcia: parent PCI bridge I/O "
"window: 0x%llx - 0x%llx\n",
(unsigned long long)res->start,
(unsigned long long)res->end);
dev_printk(KERN_INFO, &s->cb_dev->dev,
"pcmcia: parent PCI bridge I/O "
"window: 0x%llx - 0x%llx\n",
(unsigned long long)res->start,
(unsigned long long)res->end);
if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
done |= IORESOURCE_IO;
@ -806,10 +814,11 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
if (res->flags & IORESOURCE_MEM) {
if (res == &iomem_resource)
continue;
printk(KERN_INFO "pcmcia: parent PCI bridge Memory "
"window: 0x%llx - 0x%llx\n",
(unsigned long long)res->start,
(unsigned long long)res->end);
dev_printk(KERN_INFO, &s->cb_dev->dev,
"pcmcia: parent PCI bridge Memory "
"window: 0x%llx - 0x%llx\n",
(unsigned long long)res->start,
(unsigned long long)res->end);
if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
done |= IORESOURCE_MEM;
}

View File

@ -54,7 +54,7 @@
#include <mach/pxa-regs.h>
#endif
#ifdef DEBUG
#ifdef CONFIG_PCMCIA_DEBUG
static int pc_debug;
module_param(pc_debug, int, 0644);

View File

@ -15,7 +15,6 @@
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
struct device;
@ -137,7 +136,7 @@ extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_lev
extern int soc_common_drv_pcmcia_remove(struct device *dev);
#ifdef DEBUG
#ifdef CONFIG_PCMCIA_DEBUG
extern void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
int lvl, const char *fmt, ...);

View File

@ -316,27 +316,18 @@ static ssize_t pccard_store_cis(struct kobject *kobj,
char *buf, loff_t off, size_t count)
{
struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj));
cisdump_t *cis;
int error;
if (off)
return -EINVAL;
if (count >= 0x200)
if (count >= CISTPL_MAX_CIS_SIZE)
return -EINVAL;
if (!(s->state & SOCKET_PRESENT))
return -ENODEV;
cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
if (!cis)
return -ENOMEM;
cis->Length = count + 1;
memcpy(cis->Data, buf, count);
error = pcmcia_replace_cis(s, cis);
kfree(cis);
error = pcmcia_replace_cis(s, buf, count);
if (error)
return -EIO;

View File

@ -55,7 +55,7 @@
#include <pcmcia/ss.h>
#include "tcic.h"
#ifdef DEBUG
#ifdef CONFIG_PCMCIA_DEBUG
static int pc_debug;
module_param(pc_debug, int, 0644);

View File

@ -339,8 +339,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",
pci_name(socket->dev), mfunc, devctl);
dev_printk(KERN_INFO, &socket->dev->dev,
"TI: mfunc 0x%08x, devctl 0x%02x\n", mfunc, devctl);
/* make sure PCI interrupts are enabled before probing */
ti_init(socket);
@ -354,8 +354,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
* We're here which means PCI interrupts are _not_ delivered. try to
* find the right setting (all serial or parallel)
*/
printk(KERN_INFO "Yenta TI: socket %s probing PCI interrupt failed, trying to fix\n",
pci_name(socket->dev));
dev_printk(KERN_INFO, &socket->dev->dev,
"TI: probing PCI interrupt failed, trying to fix\n");
/* for serial PCI make sure MFUNC3 is set to IRQSER */
if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) {
@ -379,8 +379,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
pci_irq_status = yenta_probe_cb_irq(socket);
if (pci_irq_status == 1) {
printk(KERN_INFO "Yenta TI: socket %s all-serial interrupts ok\n",
pci_name(socket->dev));
dev_printk(KERN_INFO, &socket->dev->dev,
"TI: all-serial interrupts ok\n");
mfunc_old = mfunc;
goto out;
}
@ -395,8 +395,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
}
/* serial PCI interrupts not working fall back to parallel */
printk(KERN_INFO "Yenta TI: socket %s falling back to parallel PCI interrupts\n",
pci_name(socket->dev));
dev_printk(KERN_INFO, &socket->dev->dev,
"TI: falling back to parallel PCI interrupts\n");
devctl &= ~TI113X_DCR_IMODE_MASK;
devctl |= TI113X_DCR_IMODE_SERIAL; /* serial ISA could be right */
config_writeb(socket, TI113X_DEVICE_CONTROL, devctl);
@ -427,8 +427,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
pci_irq_status = yenta_probe_cb_irq(socket);
if (pci_irq_status == 1) {
mfunc_old = mfunc;
printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts ok\n",
pci_name(socket->dev));
dev_printk(KERN_INFO, &socket->dev->dev,
"TI: parallel PCI interrupts ok\n");
} else {
/* not working, back to old value */
mfunc = mfunc_old;
@ -440,8 +440,9 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
out:
if (pci_irq_status < 1) {
socket->cb_irq = 0;
printk(KERN_INFO "Yenta TI: socket %s no PCI interrupts. Fish. Please report.\n",
pci_name(socket->dev));
dev_printk(KERN_INFO, &socket->dev->dev,
"Yenta TI: no PCI interrupts. Fish. "
"Please report.\n");
}
}
@ -513,8 +514,9 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",
pci_name(socket->dev), mfunc, devctl);
dev_printk(KERN_INFO, &socket->dev->dev,
"TI: mfunc 0x%08x, devctl 0x%02x\n",
mfunc, devctl);
/* if IRQs are configured as tied, align irq of func1 with func0 */
sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
@ -533,9 +535,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
* We're here which means PCI interrupts are _not_ delivered. try to
* find the right setting
*/
printk(KERN_INFO "Yenta TI: socket %s probing PCI interrupt failed, trying to fix\n",
pci_name(socket->dev));
dev_printk(KERN_INFO, &socket->dev->dev,
"TI: probing PCI interrupt failed, trying to fix\n");
/* if all serial: set INTRTIE, probe again */
if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) {
@ -544,8 +545,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
if (ti12xx_tie_interrupts(socket, &old_irq)) {
pci_irq_status = yenta_probe_cb_irq(socket);
if (pci_irq_status == 1) {
printk(KERN_INFO "Yenta TI: socket %s all-serial interrupts, tied ok\n",
pci_name(socket->dev));
dev_printk(KERN_INFO, &socket->dev->dev,
"TI: all-serial interrupts, tied ok\n");
goto out;
}
@ -582,8 +583,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
pci_irq_status = yenta_probe_cb_irq(socket);
if (pci_irq_status == 1) {
printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts ok\n",
pci_name(socket->dev));
dev_printk(KERN_INFO, &socket->dev->dev,
"TI: parallel PCI interrupts ok\n");
goto out;
}
@ -593,13 +594,13 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
if (pci_irq_status == -1)
goto out;
}
/* still nothing: set INTRTIE */
if (ti12xx_tie_interrupts(socket, &old_irq)) {
pci_irq_status = yenta_probe_cb_irq(socket);
if (pci_irq_status == 1) {
printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts, tied ok\n",
pci_name(socket->dev));
dev_printk(KERN_INFO, &socket->dev->dev,
"TI: parallel PCI interrupts, tied ok\n");
goto out;
}
@ -610,8 +611,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
out:
if (pci_irq_status < 1) {
socket->cb_irq = 0;
printk(KERN_INFO "Yenta TI: socket %s no PCI interrupts. Fish. Please report.\n",
pci_name(socket->dev));
dev_printk(KERN_INFO, &socket->dev->dev,
"TI: no PCI interrupts. Fish. Please report.\n");
}
}
@ -815,11 +816,13 @@ static int ti12xx_override(struct yenta_socket *socket)
/* make sure that memory burst is active */
val_orig = val = config_readl(socket, TI113X_SYSTEM_CONTROL);
if (disable_clkrun && PCI_FUNC(socket->dev->devfn) == 0) {
printk(KERN_INFO "Yenta: Disabling CLKRUN feature\n");
dev_printk(KERN_INFO, &socket->dev->dev,
"Disabling CLKRUN feature\n");
val |= TI113X_SCR_KEEPCLK;
}
if (!(val & TI122X_SCR_MRBURSTUP)) {
printk(KERN_INFO "Yenta: Enabling burst memory read transactions\n");
dev_printk(KERN_INFO, &socket->dev->dev,
"Enabling burst memory read transactions\n");
val |= TI122X_SCR_MRBURSTUP;
}
if (val_orig != val)
@ -830,10 +833,12 @@ static int ti12xx_override(struct yenta_socket *socket)
* CSC interrupts to PCI rather than INTVAL.
*/
val = config_readb(socket, TI1250_DIAGNOSTIC);
printk(KERN_INFO "Yenta: Using %s to route CSC interrupts to PCI\n",
(val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL");
printk(KERN_INFO "Yenta: Routing CardBus interrupts to %s\n",
(val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA");
dev_printk(KERN_INFO, &socket->dev->dev,
"Using %s to route CSC interrupts to PCI\n",
(val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL");
dev_printk(KERN_INFO, &socket->dev->dev,
"Routing CardBus interrupts to %s\n",
(val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA");
/* do irqrouting, depending on function */
if (PCI_FUNC(socket->dev->devfn) == 0)
@ -858,8 +863,9 @@ static int ti1250_override(struct yenta_socket *socket)
diag |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ;
if (diag != old) {
printk(KERN_INFO "Yenta: adjusting diagnostic: %02x -> %02x\n",
old, diag);
dev_printk(KERN_INFO, &socket->dev->dev,
"adjusting diagnostic: %02x -> %02x\n",
old, diag);
config_writeb(socket, TI1250_DIAGNOSTIC, diag);
}
@ -924,7 +930,9 @@ static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
/* default to clear TLTEnable bit, old behaviour */
test_c9 &= ~ENE_TEST_C9_TLTENABLE;
printk(KERN_INFO "yenta EnE: chaning testregister 0xC9, %02x -> %02x\n", old_c9, test_c9);
dev_printk(KERN_INFO, &socket->dev->dev,
"EnE: chaning testregister 0xC9, %02x -> %02x\n",
old_c9, test_c9);
config_writeb(socket, ENE_TEST_C9, test_c9);
}

View File

@ -38,11 +38,7 @@ static int pwr_irqs_off;
module_param(pwr_irqs_off, bool, 0644);
MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!");
#if 0
#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
#else
#define debug(x,args...)
#endif
#define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args)
/* Don't ask.. */
#define to_cycles(ns) ((ns)/120)
@ -69,13 +65,13 @@ MODULE_PARM_DESC (override_bios, "yenta ignore bios resource allocation");
static inline u32 cb_readl(struct yenta_socket *socket, unsigned reg)
{
u32 val = readl(socket->base + reg);
debug("%p %04x %08x\n", socket, reg, val);
debug("%04x %08x\n", socket, reg, val);
return val;
}
static inline void cb_writel(struct yenta_socket *socket, unsigned reg, u32 val)
{
debug("%p %04x %08x\n", socket, reg, val);
debug("%04x %08x\n", socket, reg, val);
writel(val, socket->base + reg);
readl(socket->base + reg); /* avoid problems with PCI write posting */
}
@ -84,7 +80,7 @@ static inline u8 config_readb(struct yenta_socket *socket, unsigned offset)
{
u8 val;
pci_read_config_byte(socket->dev, offset, &val);
debug("%p %04x %02x\n", socket, offset, val);
debug("%04x %02x\n", socket, offset, val);
return val;
}
@ -92,7 +88,7 @@ static inline u16 config_readw(struct yenta_socket *socket, unsigned offset)
{
u16 val;
pci_read_config_word(socket->dev, offset, &val);
debug("%p %04x %04x\n", socket, offset, val);
debug("%04x %04x\n", socket, offset, val);
return val;
}
@ -100,32 +96,32 @@ static inline u32 config_readl(struct yenta_socket *socket, unsigned offset)
{
u32 val;
pci_read_config_dword(socket->dev, offset, &val);
debug("%p %04x %08x\n", socket, offset, val);
debug("%04x %08x\n", socket, offset, val);
return val;
}
static inline void config_writeb(struct yenta_socket *socket, unsigned offset, u8 val)
{
debug("%p %04x %02x\n", socket, offset, val);
debug("%04x %02x\n", socket, offset, val);
pci_write_config_byte(socket->dev, offset, val);
}
static inline void config_writew(struct yenta_socket *socket, unsigned offset, u16 val)
{
debug("%p %04x %04x\n", socket, offset, val);
debug("%04x %04x\n", socket, offset, val);
pci_write_config_word(socket->dev, offset, val);
}
static inline void config_writel(struct yenta_socket *socket, unsigned offset, u32 val)
{
debug("%p %04x %08x\n", socket, offset, val);
debug("%04x %08x\n", socket, offset, val);
pci_write_config_dword(socket->dev, offset, val);
}
static inline u8 exca_readb(struct yenta_socket *socket, unsigned reg)
{
u8 val = readb(socket->base + 0x800 + reg);
debug("%p %04x %02x\n", socket, reg, val);
debug("%04x %02x\n", socket, reg, val);
return val;
}
@ -134,20 +130,20 @@ static inline u8 exca_readw(struct yenta_socket *socket, unsigned reg)
u16 val;
val = readb(socket->base + 0x800 + reg);
val |= readb(socket->base + 0x800 + reg + 1) << 8;
debug("%p %04x %04x\n", socket, reg, val);
debug("%04x %04x\n", socket, reg, val);
return val;
}
static inline void exca_writeb(struct yenta_socket *socket, unsigned reg, u8 val)
{
debug("%p %04x %02x\n", socket, reg, val);
debug("%04x %02x\n", socket, reg, val);
writeb(val, socket->base + 0x800 + reg);
readb(socket->base + 0x800 + reg); /* PCI write posting... */
}
static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
{
debug("%p %04x %04x\n", socket, reg, val);
debug("%04x %04x\n", socket, reg, val);
writeb(val, socket->base + 0x800 + reg);
writeb(val >> 8, socket->base + 0x800 + reg + 1);
@ -207,7 +203,7 @@ static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)
if (state & CB_CBCARD) {
val |= SS_CARDBUS;
val |= SS_CARDBUS;
val |= (state & CB_CARDSTS) ? SS_STSCHG : 0;
val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
@ -650,8 +646,10 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
root = pci_find_parent_resource(socket->dev, res);
if (root && (request_resource(root, res) == 0))
return 0;
printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n",
pci_name(socket->dev), nr);
dev_printk(KERN_INFO, &socket->dev->dev,
"Preassigned resource %d busy or not available, "
"reconfiguring...\n",
nr);
}
if (type & IORESOURCE_IO) {
@ -674,8 +672,9 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
return 1;
}
printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
pci_name(socket->dev), type);
dev_printk(KERN_INFO, &socket->dev->dev,
"no resource of type %x available, trying to continue...\n",
type);
res->start = res->end = res->flags = 0;
return 0;
}
@ -923,7 +922,8 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
socket->probe_status = 0;
if (request_irq(socket->cb_irq, yenta_probe_handler, IRQF_SHARED, "yenta", socket)) {
printk(KERN_WARNING "Yenta: request_irq() in yenta_probe_cb_irq() failed!\n");
dev_printk(KERN_WARNING, &socket->dev->dev,
"request_irq() in yenta_probe_cb_irq() failed!\n");
return -1;
}
@ -960,8 +960,9 @@ static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_i
else
socket->socket.irq_mask = 0;
printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n",
socket->socket.irq_mask, socket->cb_irq);
dev_printk(KERN_INFO, &socket->dev->dev,
"ISA IRQ mask 0x%04x, PCI irq %d\n",
socket->socket.irq_mask, socket->cb_irq);
}
/*
@ -1051,8 +1052,9 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge)
/* Show that the wanted subordinate number is not possible: */
if (cardbus_bridge->subordinate > upper_limit)
printk(KERN_WARNING "Yenta: Upper limit for fixing this "
"bridge's parent bridge: #%02x\n", upper_limit);
dev_printk(KERN_WARNING, &cardbus_bridge->dev,
"Upper limit for fixing this "
"bridge's parent bridge: #%02x\n", upper_limit);
/* If we have room to increase the bridge's subordinate number, */
if (bridge_to_fix->subordinate < upper_limit) {
@ -1061,10 +1063,11 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge)
unsigned char subordinate_to_assign =
min(cardbus_bridge->subordinate, upper_limit);
printk(KERN_INFO "Yenta: Raising subordinate bus# of parent "
"bus (#%02x) from #%02x to #%02x\n",
bridge_to_fix->number,
bridge_to_fix->subordinate, subordinate_to_assign);
dev_printk(KERN_INFO, &bridge_to_fix->dev,
"Raising subordinate bus# of parent "
"bus (#%02x) from #%02x to #%02x\n",
bridge_to_fix->number,
bridge_to_fix->subordinate, subordinate_to_assign);
/* Save the new subordinate in the bus struct of the bridge */
bridge_to_fix->subordinate = subordinate_to_assign;
@ -1091,8 +1094,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
* Bail out if so.
*/
if (!dev->subordinate) {
printk(KERN_ERR "Yenta: no bus associated with %s! "
"(try 'pci=assign-busses')\n", pci_name(dev));
dev_printk(KERN_ERR, &dev->dev, "no bus associated! "
"(try 'pci=assign-busses')\n");
return -ENODEV;
}
@ -1127,7 +1130,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
goto disable;
if (!pci_resource_start(dev, 0)) {
printk(KERN_ERR "No cardbus resource!\n");
dev_printk(KERN_ERR, &dev->dev, "No cardbus resource!\n");
ret = -ENODEV;
goto release;
}
@ -1146,8 +1149,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
* report the subsystem vendor and device for help debugging
* the irq stuff...
*/
printk(KERN_INFO "Yenta: CardBus bridge found at %s [%04x:%04x]\n",
pci_name(dev), dev->subsystem_vendor, dev->subsystem_device);
dev_printk(KERN_INFO, &dev->dev, "CardBus bridge found [%04x:%04x]\n",
dev->subsystem_vendor, dev->subsystem_device);
yenta_config_init(socket);
@ -1179,8 +1182,12 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
socket->poll_timer.data = (unsigned long)socket;
socket->poll_timer.expires = jiffies + HZ;
add_timer(&socket->poll_timer);
printk(KERN_INFO "Yenta: no PCI IRQ, CardBus support disabled for this socket.\n"
KERN_INFO "Yenta: check your BIOS CardBus, BIOS IRQ or ACPI settings.\n");
dev_printk(KERN_INFO, &dev->dev,
"no PCI IRQ, CardBus support disabled for this "
"socket.\n");
dev_printk(KERN_INFO, &dev->dev,
"check your BIOS CardBus, BIOS IRQ or ACPI "
"settings.\n");
} else {
socket->socket.features |= SS_CAP_CARDBUS;
}
@ -1188,7 +1195,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
/* Figure out what the dang thing can do for the PCMCIA layer... */
yenta_interrogate(socket);
yenta_get_socket_capabilities(socket, isa_interrupts);
printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
dev_printk(KERN_INFO, &dev->dev,
"Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
yenta_fixup_parent_bridge(dev->subordinate);

View File

@ -140,44 +140,41 @@ static void aha152x_detach(struct pcmcia_device *link)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static int aha152x_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
/* For New Media T&J, look for a SCSI window */
if (cfg->io.win[0].len >= 0x20)
p_dev->io.BasePort1 = cfg->io.win[0].base;
else if ((cfg->io.nwin > 1) &&
(cfg->io.win[1].len >= 0x20))
p_dev->io.BasePort1 = cfg->io.win[1].base;
if ((cfg->io.nwin > 0) &&
(p_dev->io.BasePort1 < 0xffff)) {
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
return -EINVAL;
}
static int aha152x_config_cs(struct pcmcia_device *link)
{
scsi_info_t *info = link->priv;
struct aha152x_setup s;
tuple_t tuple;
cisparse_t parse;
int i, last_ret, last_fn;
u_char tuple_data[64];
int last_ret, last_fn;
struct Scsi_Host *host;
DEBUG(0, "aha152x_config(0x%p)\n", link);
tuple.TupleData = tuple_data;
tuple.TupleDataMax = 64;
tuple.TupleOffset = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
goto next_entry;
/* For New Media T&J, look for a SCSI window */
if (parse.cftable_entry.io.win[0].len >= 0x20)
link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
else if ((parse.cftable_entry.io.nwin > 1) &&
(parse.cftable_entry.io.win[1].len >= 0x20))
link->io.BasePort1 = parse.cftable_entry.io.win[1].base;
if ((parse.cftable_entry.io.nwin > 0) &&
(link->io.BasePort1 < 0xffff)) {
link->conf.ConfigIndex = parse.cftable_entry.index;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
}
next_entry:
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
last_ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
if (last_ret) {
cs_error(link, RequestIO, last_ret);
goto failed;
}
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
@ -208,6 +205,7 @@ static int aha152x_config_cs(struct pcmcia_device *link)
cs_failed:
cs_error(link, last_fn, last_ret);
failed:
aha152x_release_cs(link);
return -ENODEV;
}

View File

@ -123,34 +123,30 @@ static void fdomain_detach(struct pcmcia_device *link)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static int fdomain_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
p_dev->io.BasePort1 = cfg->io.win[0].base;
return pcmcia_request_io(p_dev, &p_dev->io);
}
static int fdomain_config(struct pcmcia_device *link)
{
scsi_info_t *info = link->priv;
tuple_t tuple;
cisparse_t parse;
int i, last_ret, last_fn;
u_char tuple_data[64];
int last_ret, last_fn;
char str[22];
struct Scsi_Host *host;
DEBUG(0, "fdomain_config(0x%p)\n", link);
tuple.TupleData = tuple_data;
tuple.TupleDataMax = 64;
tuple.TupleOffset = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
goto next_entry;
link->conf.ConfigIndex = parse.cftable_entry.index;
link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS) break;
next_entry:
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
last_ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
if (last_ret) {
cs_error(link, RequestIO, last_ret);
goto failed;
}
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
@ -181,6 +177,7 @@ static int fdomain_config(struct pcmcia_device *link)
cs_failed:
cs_error(link, last_fn, last_ret);
failed:
fdomain_release(link);
return -ENODEV;
} /* fdomain_config */

View File

@ -1606,133 +1606,129 @@ static void nsp_cs_detach(struct pcmcia_device *link)
is received, to configure the PCMCIA socket, and to make the
ethernet device available to the system.
======================================================================*/
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
/*====================================================================*/
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;
if (cfg->index == 0)
return -ENODEV;
/* 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)
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;
}
/* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->io.BasePort1 = io->win[0].base;
p_dev->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
p_dev->io.Attributes2 = p_dev->io.Attributes1;
p_dev->io.BasePort2 = io->win[1].base;
p_dev->io.NumPorts2 = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
goto next_entry;
}
if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
memreq_t map;
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;
map.Page = 0; map.CardOffset = mem->win[0].card_addr;
if (pcmcia_map_mem_page(p_dev->win, &map) != 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;
}
next_entry:
nsp_dbg(NSP_DEBUG_INIT, "next");
pcmcia_disable_device(p_dev);
return -ENODEV;
}
static int nsp_cs_config(struct pcmcia_device *link)
{
int ret;
scsi_info_t *info = link->priv;
tuple_t tuple;
cisparse_t parse;
int last_ret, last_fn;
unsigned char tuple_data[64];
config_info_t conf;
win_req_t req;
memreq_t map;
cistpl_cftable_entry_t dflt = { 0 };
struct nsp_cs_configdata *cfg_mem;
struct Scsi_Host *host;
nsp_hw_data *data = &nsp_data_base;
nsp_dbg(NSP_DEBUG_INIT, "in");
tuple.Attributes = 0;
tuple.TupleData = tuple_data;
tuple.TupleDataMax = sizeof(tuple_data);
tuple.TupleOffset = 0;
cfg_mem = kzalloc(sizeof(cfg_mem), GFP_KERNEL);
if (!cfg_mem)
return -ENOMEM;
cfg_mem->data = data;
/* Look up the current Vcc */
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
goto next_entry;
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
if (cfg->index == 0) { goto next_entry; }
link->conf.ConfigIndex = cfg->index;
/* Does this card need audio output? */
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->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 (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
goto next_entry;
}
} else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
goto next_entry;
}
}
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
link->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
} else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
link->conf.Vpp =
dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
}
/* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
link->conf.Attributes |= CONF_ENABLE_IRQ;
}
/* IO window settings */
link->io.NumPorts1 = link->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
link->io.Attributes2 = link->io.Attributes1;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry;
}
if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
cistpl_mem_t *mem =
(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
req.Attributes |= WIN_ENABLE;
req.Base = mem->win[0].host_addr;
req.Size = mem->win[0].len;
if (req.Size < 0x1000) {
req.Size = 0x1000;
}
req.AccessSpeed = 0;
if (pcmcia_request_window(&link, &req, &link->win) != 0)
goto next_entry;
map.Page = 0; map.CardOffset = mem->win[0].card_addr;
if (pcmcia_map_mem_page(link->win, &map) != 0)
goto next_entry;
data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
data->MmioLength = req.Size;
}
/* If we got this far, we're cool! */
break;
next_entry:
nsp_dbg(NSP_DEBUG_INIT, "next");
pcmcia_disable_device(link);
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
}
ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem);
goto cs_failed;
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
if (pcmcia_request_irq(link, &link->irq))
goto cs_failed;
}
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
ret = pcmcia_request_configuration(link, &link->conf);
if (ret)
goto cs_failed;
if (free_ports) {
if (link->io.BasePort1) {
@ -1790,20 +1786,20 @@ static int nsp_cs_config(struct pcmcia_device *link)
printk(" & 0x%04x-0x%04x", link->io.BasePort2,
link->io.BasePort2+link->io.NumPorts2-1);
if (link->win)
printk(", mem 0x%06lx-0x%06lx", req.Base,
req.Base+req.Size-1);
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;
cs_failed:
nsp_dbg(NSP_DEBUG_INIT, "config fail");
cs_error(link, last_fn, last_ret);
nsp_cs_release(link);
kfree(cfg_mem);
return -ENODEV;
} /* nsp_cs_config */
#undef CS_CHECK
/*======================================================================

View File

@ -195,39 +195,33 @@ static void qlogic_detach(struct pcmcia_device *link)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static int qlogic_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
p_dev->io.BasePort1 = cfg->io.win[0].base;
p_dev->io.NumPorts1 = cfg->io.win[0].len;
if (p_dev->io.BasePort1 == 0)
return -ENODEV;
return pcmcia_request_io(p_dev, &p_dev->io);
}
static int qlogic_config(struct pcmcia_device * link)
{
scsi_info_t *info = link->priv;
tuple_t tuple;
cisparse_t parse;
int i, last_ret, last_fn;
unsigned short tuple_data[32];
int last_ret, last_fn;
struct Scsi_Host *host;
DEBUG(0, "qlogic_config(0x%p)\n", link);
info->manf_id = link->manf_id;
tuple.TupleData = (cisdata_t *) tuple_data;
tuple.TupleDataMax = 64;
tuple.TupleOffset = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
goto next_entry;
link->conf.ConfigIndex = parse.cftable_entry.index;
link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
if (link->io.BasePort1 != 0) {
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
break;
}
next_entry:
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
last_ret = pcmcia_loop_config(link, qlogic_config_check, NULL);
if (last_ret) {
cs_error(link, RequestIO, last_ret);
goto failed;
}
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
@ -262,6 +256,7 @@ static int qlogic_config(struct pcmcia_device * link)
cs_failed:
cs_error(link, last_fn, last_ret);
pcmcia_disable_device(link);
failed:
return -ENODEV;
} /* qlogic_config */

View File

@ -700,15 +700,27 @@ static struct scsi_host_template sym53c500_driver_template = {
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static int SYM53C500_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
p_dev->io.BasePort1 = cfg->io.win[0].base;
p_dev->io.NumPorts1 = cfg->io.win[0].len;
if (p_dev->io.BasePort1 == 0)
return -ENODEV;
return pcmcia_request_io(p_dev, &p_dev->io);
}
static int
SYM53C500_config(struct pcmcia_device *link)
{
struct scsi_info_t *info = link->priv;
tuple_t tuple;
cisparse_t parse;
int i, last_ret, last_fn;
int last_ret, last_fn;
int irq_level, port_base;
unsigned short tuple_data[32];
struct Scsi_Host *host;
struct scsi_host_template *tpnt = &sym53c500_driver_template;
struct sym53c500_data *data;
@ -717,27 +729,10 @@ SYM53C500_config(struct pcmcia_device *link)
info->manf_id = link->manf_id;
tuple.TupleData = (cisdata_t *)tuple_data;
tuple.TupleDataMax = 64;
tuple.TupleOffset = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
goto next_entry;
link->conf.ConfigIndex = parse.cftable_entry.index;
link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
if (link->io.BasePort1 != 0) {
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
break;
}
next_entry:
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
last_ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
if (last_ret) {
cs_error(link, RequestIO, last_ret);
goto failed;
}
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
@ -831,6 +826,7 @@ err_release:
cs_failed:
cs_error(link, last_fn, last_ret);
failed:
SYM53C500_release(link);
return -ENODEV;
} /* SYM53C500_config */

View File

@ -431,131 +431,103 @@ first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
{
int i;
i = pcmcia_get_first_tuple(handle, tuple);
if (i != CS_SUCCESS)
return CS_NO_MORE_ITEMS;
i = pcmcia_get_tuple_data(handle, tuple);
if (i != CS_SUCCESS)
if (i != 0)
return i;
return pcmcia_parse_tuple(handle, tuple, parse);
}
static int
next_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
{
int i;
i = pcmcia_get_next_tuple(handle, tuple);
if (i != CS_SUCCESS)
return CS_NO_MORE_ITEMS;
i = pcmcia_get_tuple_data(handle, tuple);
if (i != CS_SUCCESS)
if (i != 0)
return i;
return pcmcia_parse_tuple(handle, tuple, parse);
return pcmcia_parse_tuple(tuple, parse);
}
/*====================================================================*/
static int simple_config(struct pcmcia_device *link)
static int simple_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
static const int size_table[2] = { 8, 16 };
int *try = priv_data;
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
p_dev->conf.Vpp =
cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[(*try >> 1)])
&& (cf->io.win[0].base != 0)) {
p_dev->io.BasePort1 = cf->io.win[0].base;
p_dev->io.IOAddrLines = ((*try & 0x1) == 0) ?
16 : cf->io.flags & CISTPL_IO_LINES_MASK;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
return -EINVAL;
}
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)
{
static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
static const int size_table[2] = { 8, 16 };
int j;
if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
for (j = 0; j < 5; j++) {
p_dev->io.BasePort1 = base[j];
p_dev->io.IOAddrLines = base[j] ? 16 : 3;
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
}
return -ENODEV;
}
static int simple_config(struct pcmcia_device *link)
{
struct serial_info *info = link->priv;
struct serial_cfg_mem *cfg_mem;
tuple_t *tuple;
u_char *buf;
cisparse_t *parse;
cistpl_cftable_entry_t *cf;
config_info_t config;
int i, j, try;
int s;
cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
if (!cfg_mem)
return -1;
tuple = &cfg_mem->tuple;
parse = &cfg_mem->parse;
cf = &parse->cftable_entry;
buf = cfg_mem->buf;
int i = -ENODEV, try;
/* If the card is already configured, look up the port and irq */
i = pcmcia_get_configuration_info(link, &config);
if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) {
if (link->function_config) {
unsigned int port = 0;
if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) {
port = config.BasePort2;
if ((link->io.BasePort2 != 0) &&
(link->io.NumPorts2 == 8)) {
port = link->io.BasePort2;
info->slave = 1;
} else if ((info->manfid == MANFID_OSITECH) &&
(config.NumPorts1 == 0x40)) {
port = config.BasePort1 + 0x28;
(link->io.NumPorts1 == 0x40)) {
port = link->io.BasePort1 + 0x28;
info->slave = 1;
}
if (info->slave) {
kfree(cfg_mem);
return setup_serial(link, info, port, config.AssignedIRQ);
return setup_serial(link, info, port,
link->irq.AssignedIRQ);
}
}
/* First pass: look for a config entry that looks normal. */
tuple->TupleData = (cisdata_t *) buf;
tuple->TupleOffset = 0;
tuple->TupleDataMax = 255;
tuple->Attributes = 0;
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
/* Two tries: without IO aliases, then with aliases */
for (s = 0; s < 2; s++) {
for (try = 0; try < 2; try++) {
i = first_tuple(link, tuple, parse);
while (i != CS_NO_MORE_ITEMS) {
if (i != CS_SUCCESS)
goto next_entry;
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
link->conf.Vpp =
cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) &&
(cf->io.win[0].base != 0)) {
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
link->io.IOAddrLines = (try == 0) ?
16 : cf->io.flags & CISTPL_IO_LINES_MASK;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
goto found_port;
}
next_entry:
i = next_tuple(link, tuple, parse);
}
}
}
/* First pass: look for a config entry that looks normal.
* Two tries: without IO aliases, then with aliases */
for (try = 0; try < 4; try++)
if (!pcmcia_loop_config(link, simple_config_check, &try))
goto found_port;
/* Second pass: try to find an entry that isn't picky about
its base address, then try to grab any standard serial port
address, and finally try to get any free port. */
i = first_tuple(link, tuple, parse);
while (i != CS_NO_MORE_ITEMS) {
if ((i == CS_SUCCESS) && (cf->io.nwin > 0) &&
((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
link->conf.ConfigIndex = cf->index;
for (j = 0; j < 5; j++) {
link->io.BasePort1 = base[j];
link->io.IOAddrLines = base[j] ? 16 : 3;
i = pcmcia_request_io(link, &link->io);
if (i == CS_SUCCESS)
goto found_port;
}
}
i = next_tuple(link, tuple, parse);
}
if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
goto found_port;
found_port:
if (i != CS_SUCCESS) {
printk(KERN_NOTICE
"serial_cs: no usable port range found, giving up\n");
cs_error(link, RequestIO, i);
kfree(cfg_mem);
return -1;
}
printk(KERN_NOTICE
"serial_cs: no usable port range found, giving up\n");
cs_error(link, RequestIO, i);
return -1;
found_port:
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestIRQ, i);
link->irq.AssignedIRQ = 0;
}
@ -569,88 +541,76 @@ next_entry:
info->quirk->config(link);
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestConfiguration, i);
kfree(cfg_mem);
return -1;
}
kfree(cfg_mem);
return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
}
static int multi_config(struct pcmcia_device * link)
static int multi_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cf,
cistpl_cftable_entry_t *dflt,
unsigned int vcc,
void *priv_data)
{
int *base2 = priv_data;
/* The quad port cards have bad CIS's, so just look for a
window larger than 8 ports and assume it will be right */
if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
p_dev->io.BasePort1 = cf->io.win[0].base;
p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
if (!pcmcia_request_io(p_dev, &p_dev->io)) {
*base2 = p_dev->io.BasePort1 + 8;
return 0;
}
}
return -ENODEV;
}
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)
{
int *base2 = priv_data;
if (cf->io.nwin == 2) {
p_dev->io.BasePort1 = cf->io.win[0].base;
p_dev->io.BasePort2 = cf->io.win[1].base;
p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
if (!pcmcia_request_io(p_dev, &p_dev->io)) {
*base2 = p_dev->io.BasePort2;
return 0;
}
}
return -ENODEV;
}
static int multi_config(struct pcmcia_device *link)
{
struct serial_info *info = link->priv;
struct serial_cfg_mem *cfg_mem;
tuple_t *tuple;
u_char *buf;
cisparse_t *parse;
cistpl_cftable_entry_t *cf;
int i, rc, base2 = 0;
cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
if (!cfg_mem)
return -1;
tuple = &cfg_mem->tuple;
parse = &cfg_mem->parse;
cf = &parse->cftable_entry;
buf = cfg_mem->buf;
tuple->TupleData = (cisdata_t *) buf;
tuple->TupleOffset = 0;
tuple->TupleDataMax = 255;
tuple->Attributes = 0;
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
int i, base2 = 0;
/* First, look for a generic full-sized window */
link->io.NumPorts1 = info->multi * 8;
i = first_tuple(link, tuple, parse);
while (i != CS_NO_MORE_ITEMS) {
/* The quad port cards have bad CIS's, so just look for a
window larger than 8 ports and assume it will be right */
if ((i == CS_SUCCESS) && (cf->io.nwin == 1) &&
(cf->io.win[0].len > 8)) {
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
link->io.IOAddrLines =
cf->io.flags & CISTPL_IO_LINES_MASK;
i = pcmcia_request_io(link, &link->io);
base2 = link->io.BasePort1 + 8;
if (i == CS_SUCCESS)
break;
}
i = next_tuple(link, tuple, parse);
}
/* If that didn't work, look for two windows */
if (i != CS_SUCCESS) {
if (pcmcia_loop_config(link, multi_config_check, &base2)) {
/* If that didn't work, look for two windows */
link->io.NumPorts1 = link->io.NumPorts2 = 8;
info->multi = 2;
i = first_tuple(link, tuple, parse);
while (i != CS_NO_MORE_ITEMS) {
if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) {
link->conf.ConfigIndex = cf->index;
link->io.BasePort1 = cf->io.win[0].base;
link->io.BasePort2 = cf->io.win[1].base;
link->io.IOAddrLines =
cf->io.flags & CISTPL_IO_LINES_MASK;
i = pcmcia_request_io(link, &link->io);
base2 = link->io.BasePort2;
if (i == CS_SUCCESS)
break;
}
i = next_tuple(link, tuple, parse);
if (pcmcia_loop_config(link, multi_config_check_notpicky,
&base2)) {
printk(KERN_NOTICE "serial_cs: no usable port range"
"found, giving up\n");
return -ENODEV;
}
}
if (i != CS_SUCCESS) {
cs_error(link, RequestIO, i);
rc = -1;
goto free_cfg_mem;
}
i = pcmcia_request_irq(link, &link->irq);
if (i != CS_SUCCESS) {
if (i != 0) {
/* FIXME: comment does not fit, error handling does not fit */
printk(KERN_NOTICE
"serial_cs: no usable port range found, giving up\n");
cs_error(link, RequestIRQ, i);
@ -664,10 +624,9 @@ static int multi_config(struct pcmcia_device * link)
info->quirk->config(link);
i = pcmcia_request_configuration(link, &link->conf);
if (i != CS_SUCCESS) {
if (i != 0) {
cs_error(link, RequestConfiguration, i);
rc = -1;
goto free_cfg_mem;
return -ENODEV;
}
/* The Oxford Semiconductor OXCF950 cards are in fact single-port:
@ -678,7 +637,8 @@ static int multi_config(struct pcmcia_device * link)
info->prodid == PRODID_POSSIO_GCC)) {
int err;
if (cf->index == 1 || cf->index == 3) {
if (link->conf.ConfigIndex == 1 ||
link->conf.ConfigIndex == 3) {
err = setup_serial(link, info, base2,
link->irq.AssignedIRQ);
base2 = link->io.BasePort1;
@ -695,18 +655,14 @@ static int multi_config(struct pcmcia_device * link)
if (info->quirk && info->quirk->wakeup)
info->quirk->wakeup(link);
rc = 0;
goto free_cfg_mem;
return 0;
}
setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
for (i = 0; i < info->multi - 1; i++)
setup_serial(link, info, base2 + (8 * i),
link->irq.AssignedIRQ);
rc = 0;
free_cfg_mem:
kfree(cfg_mem);
return rc;
return 0;
}
/*======================================================================
@ -746,7 +702,7 @@ static int serial_config(struct pcmcia_device * link)
/* Is this a compliant multifunction card? */
tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
info->multi = (first_tuple(link, tuple, parse) == CS_SUCCESS);
info->multi = (first_tuple(link, tuple, parse) == 0);
/* Is this a multiport card? */
tuple->DesiredTuple = CISTPL_MANFID;
@ -770,7 +726,7 @@ static int serial_config(struct pcmcia_device * link)
((link->func_id == CISTPL_FUNCID_MULTI) ||
(link->func_id == CISTPL_FUNCID_SERIAL))) {
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
if (first_tuple(link, tuple, parse) == 0) {
if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
info->multi = cf->io.win[0].len >> 3;
if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&

View File

@ -80,7 +80,7 @@ static int ssb_pcmcia_cfg_write(struct ssb_bus *bus, u8 offset, u8 value)
reg.Action = CS_WRITE;
reg.Value = value;
res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
if (unlikely(res != CS_SUCCESS))
if (unlikely(res != 0))
return -EBUSY;
return 0;
@ -96,7 +96,7 @@ static int ssb_pcmcia_cfg_read(struct ssb_bus *bus, u8 offset, u8 *value)
reg.Offset = offset;
reg.Action = CS_READ;
res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
if (unlikely(res != CS_SUCCESS))
if (unlikely(res != 0))
return -EBUSY;
*value = reg.Value;
@ -638,17 +638,17 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
GOTO_ERROR_ON(res != CS_SUCCESS, "MAC first tpl");
GOTO_ERROR_ON(res != 0, "MAC first tpl");
res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
GOTO_ERROR_ON(res != CS_SUCCESS, "MAC first tpl data");
GOTO_ERROR_ON(res != 0, "MAC first tpl data");
while (1) {
GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1");
if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID)
break;
res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
GOTO_ERROR_ON(res != CS_SUCCESS, "MAC next tpl");
GOTO_ERROR_ON(res != 0, "MAC next tpl");
res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
GOTO_ERROR_ON(res != CS_SUCCESS, "MAC next tpl data");
GOTO_ERROR_ON(res != 0, "MAC next tpl data");
}
GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size");
memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN);
@ -659,9 +659,9 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
GOTO_ERROR_ON(res != CS_SUCCESS, "VEN first tpl");
GOTO_ERROR_ON(res != 0, "VEN first tpl");
res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
GOTO_ERROR_ON(res != CS_SUCCESS, "VEN first tpl data");
GOTO_ERROR_ON(res != 0, "VEN first tpl data");
while (1) {
GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1");
switch (tuple.TupleData[0]) {
@ -733,11 +733,11 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
break;
}
res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
if (res == CS_NO_MORE_ITEMS)
if (res == -ENOSPC)
break;
GOTO_ERROR_ON(res != CS_SUCCESS, "VEN next tpl");
GOTO_ERROR_ON(res != 0, "VEN next tpl");
res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
GOTO_ERROR_ON(res != CS_SUCCESS, "VEN next tpl data");
GOTO_ERROR_ON(res != 0, "VEN next tpl data");
}
return 0;

View File

@ -124,65 +124,53 @@ static void ixj_get_serial(struct pcmcia_device * link, IXJ * j)
return;
}
static int ixj_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)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io.BasePort1 = io->win[0].base;
p_dev->io.NumPorts1 = io->win[0].len;
if (io->nwin == 2) {
p_dev->io.BasePort2 = io->win[1].base;
p_dev->io.NumPorts2 = io->win[1].len;
}
if (!pcmcia_request_io(p_dev, &p_dev->io))
return 0;
}
return -ENODEV;
}
static int ixj_config(struct pcmcia_device * link)
{
IXJ *j;
ixj_info_t *info;
tuple_t tuple;
u_short buf[128];
cisparse_t parse;
cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
cistpl_cftable_entry_t dflt =
{
0
};
int last_ret, last_fn;
cistpl_cftable_entry_t dflt = { 0 };
info = link->priv;
DEBUG(0, "ixj_config(0x%p)\n", link);
tuple.TupleData = (cisdata_t *) buf;
tuple.TupleOffset = 0;
tuple.TupleDataMax = 255;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.Attributes = 0;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
goto next_entry;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
link->conf.ConfigIndex = cfg->index;
link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len;
if (io->nwin == 2) {
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
}
if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry;
/* If we've got this far, we're done */
break;
}
next_entry:
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
dflt = *cfg;
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
}
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
if (pcmcia_loop_config(link, ixj_config_check, &dflt))
goto cs_failed;
if (pcmcia_request_configuration(link, &link->conf))
goto cs_failed;
/*
* Register the card with the core.
*/
j=ixj_pcmcia_probe(link->io.BasePort1,link->io.BasePort1 + 0x10);
*/
j = ixj_pcmcia_probe(link->io.BasePort1, link->io.BasePort1 + 0x10);
info->ndev = 1;
info->node.major = PHONE_MAJOR;
link->dev_node = &info->node;
ixj_get_serial(link, j);
return 0;
cs_failed:
cs_error(link, last_fn, last_ret);
ixj_cs_release(link);
return -ENODEV;
}

View File

@ -112,7 +112,8 @@ static struct platform_device platform_dev = {
.num_resources = ARRAY_SIZE(resources),
};
static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq)
static int sl811_hc_init(struct device *parent, resource_size_t base_addr,
int irq)
{
if (platform_dev.dev.parent)
return -EBUSY;
@ -155,97 +156,72 @@ static void sl811_cs_release(struct pcmcia_device * link)
platform_device_unregister(&platform_dev);
}
static int sl811_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)
return -ENODEV;
/* 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 (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 */
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
p_dev->io.BasePort1 = io->win[0].base;
p_dev->io.NumPorts1 = io->win[0].len;
return pcmcia_request_io(p_dev, &p_dev->io);
}
pcmcia_disable_device(p_dev);
return -ENODEV;
}
static int sl811_cs_config(struct pcmcia_device *link)
{
struct device *parent = &handle_to_dev(link);
local_info_t *dev = link->priv;
tuple_t tuple;
cisparse_t parse;
int last_fn, last_ret;
u_char buf[64];
config_info_t conf;
cistpl_cftable_entry_t dflt = { 0 };
DBG(0, "sl811_cs_config(0x%p)\n", link);
/* Look up the current Vcc */
CS_CHECK(GetConfigurationInfo,
pcmcia_get_configuration_info(link, &conf));
tuple.Attributes = 0;
tuple.TupleData = buf;
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
while (1) {
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
if (pcmcia_get_tuple_data(link, &tuple) != 0
|| pcmcia_parse_tuple(link, &tuple, &parse)
!= 0)
goto next_entry;
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) {
dflt = *cfg;
}
if (cfg->index == 0)
goto next_entry;
link->conf.ConfigIndex = cfg->index;
/* 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 (cfg->vcc.param[CISTPL_POWER_VNOM]/10000
!= conf.Vcc)
goto next_entry;
} else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
if (dflt.vcc.param[CISTPL_POWER_VNOM]/10000
!= conf.Vcc)
goto next_entry;
}
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
link->conf.Vpp =
cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
link->conf.Vpp =
dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
/* we need an interrupt */
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
link->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
link->io.NumPorts1 = link->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len;
if (pcmcia_request_io(link, &link->io) != 0)
goto next_entry;
}
break;
next_entry:
pcmcia_disable_device(link);
last_ret = pcmcia_get_next_tuple(link, &tuple);
}
if (pcmcia_loop_config(link, sl811_cs_config_check, NULL))
goto failed;
/* require an IRQ and two registers */
if (!link->io.NumPorts1 || link->io.NumPorts1 < 2)
goto cs_failed;
goto failed;
if (link->conf.Attributes & CONF_ENABLE_IRQ)
CS_CHECK(RequestIRQ,
pcmcia_request_irq(link, &link->irq));
else
goto cs_failed;
goto failed;
CS_CHECK(RequestConfiguration,
pcmcia_request_configuration(link, &link->conf));
@ -266,8 +242,9 @@ next_entry:
if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ)
< 0) {
cs_failed:
printk("sl811_cs_config failed\n");
cs_error(link, last_fn, last_ret);
failed:
printk(KERN_WARNING "sl811_cs_config failed\n");
sl811_cs_release(link);
return -ENODEV;
}

View File

@ -119,7 +119,7 @@
#define MANFID_TOSHIBA 0x0098
#define MANFID_UNGERMANN 0x02c0
#define MANFID_UNGERMANN 0x02c0
#define MANFID_XIRCOM 0x0105

View File

@ -573,44 +573,6 @@ typedef struct tuple_t {
#define TUPLE_RETURN_LINK 0x01
#define TUPLE_RETURN_COMMON 0x02
/* For ValidateCIS */
typedef struct cisinfo_t {
u_int Chains;
} cisinfo_t;
#define CISTPL_MAX_CIS_SIZE 0x200
/* For ReplaceCIS */
typedef struct cisdump_t {
u_int Length;
cisdata_t Data[CISTPL_MAX_CIS_SIZE];
} cisdump_t;
int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis);
/* don't use outside of PCMCIA core yet */
int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *tuple);
int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple);
int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse);
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned int *count);
/* ... but use these wrappers instead */
#define pcmcia_get_first_tuple(p_dev, tuple) \
pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple)
#define pcmcia_get_next_tuple(p_dev, tuple) \
pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple)
#define pcmcia_get_tuple_data(p_dev, tuple) \
pccard_get_tuple_data(p_dev->socket, tuple)
#define pcmcia_parse_tuple(p_dev, tuple, parse) \
pccard_parse_tuple(tuple, parse)
#define pcmcia_validate_cis(p_dev, info) \
pccard_validate_cis(p_dev->socket, p_dev->func, info)
#endif /* LINUX_CISTPL_H */

View File

@ -28,72 +28,16 @@ typedef struct conf_reg_t {
#define CS_WRITE 2
/* for AdjustResourceInfo */
typedef struct adjust_t {
u_int Action;
u_int Resource;
u_int Attributes;
union {
struct memory {
u_long Base;
u_long Size;
} memory;
struct io {
ioaddr_t BasePort;
ioaddr_t NumPorts;
u_int IOAddrLines;
} io;
struct irq {
u_int IRQ;
} irq;
} resource;
} adjust_t;
/* Action field */
#define REMOVE_MANAGED_RESOURCE 1
#define ADD_MANAGED_RESOURCE 2
#define GET_FIRST_MANAGED_RESOURCE 3
#define GET_NEXT_MANAGED_RESOURCE 4
/* Resource field */
#define RES_MEMORY_RANGE 1
#define RES_IO_RANGE 2
#define RES_IRQ 3
/* Attribute field */
#define RES_IRQ_TYPE 0x03
#define RES_IRQ_TYPE_EXCLUSIVE 0
#define RES_IRQ_TYPE_TIME 1
#define RES_IRQ_TYPE_DYNAMIC 2
#define RES_IRQ_CSC 0x04
#define RES_SHARED 0x08
#define RES_RESERVED 0x10
#define RES_ALLOCATED 0x20
#define RES_REMOVED 0x40
typedef struct event_callback_args_t {
struct pcmcia_device *client_handle;
void *client_data;
} event_callback_args_t;
/* for GetConfigurationInfo */
typedef struct config_info_t {
u_char Function;
u_int Attributes;
u_int Vcc, Vpp1, Vpp2;
u_int IntType;
u_int ConfigBase;
u_char Status, Pin, Copy, Option, ExtStatus;
u_int Present;
u_int CardValues;
u_int AssignedIRQ;
u_int IRQAttributes;
ioaddr_t BasePort1;
ioaddr_t NumPorts1;
u_int Attributes1;
ioaddr_t BasePort2;
ioaddr_t NumPorts2;
u_int Attributes2;
u_int IOAddrLines;
} config_info_t;
/* For CardValues field */
#define CV_OPTION_VALUE 0x01
#define CV_STATUS_VALUE 0x02
@ -257,22 +201,6 @@ typedef struct win_req_t {
#define WIN_BAR_MASK 0xe000
#define WIN_BAR_SHIFT 13
/* Attributes for RegisterClient -- UNUSED -- */
#define INFO_MASTER_CLIENT 0x01
#define INFO_IO_CLIENT 0x02
#define INFO_MTD_CLIENT 0x04
#define INFO_MEM_CLIENT 0x08
#define MAX_NUM_CLIENTS 3
#define INFO_CARD_SHARE 0x10
#define INFO_CARD_EXCL 0x20
typedef struct cs_status_t {
u_char Function;
event_t CardState;
event_t SocketState;
} cs_status_t;
typedef struct error_info_t {
int func;
int retcode;
@ -308,95 +236,4 @@ typedef struct error_info_t {
#define CS_EVENT_3VCARD 0x200000
#define CS_EVENT_XVCARD 0x400000
/* Return codes */
#define CS_SUCCESS 0x00
#define CS_BAD_ADAPTER 0x01
#define CS_BAD_ATTRIBUTE 0x02
#define CS_BAD_BASE 0x03
#define CS_BAD_EDC 0x04
#define CS_BAD_IRQ 0x06
#define CS_BAD_OFFSET 0x07
#define CS_BAD_PAGE 0x08
#define CS_READ_FAILURE 0x09
#define CS_BAD_SIZE 0x0a
#define CS_BAD_SOCKET 0x0b
#define CS_BAD_TYPE 0x0d
#define CS_BAD_VCC 0x0e
#define CS_BAD_VPP 0x0f
#define CS_BAD_WINDOW 0x11
#define CS_WRITE_FAILURE 0x12
#define CS_NO_CARD 0x14
#define CS_UNSUPPORTED_FUNCTION 0x15
#define CS_UNSUPPORTED_MODE 0x16
#define CS_BAD_SPEED 0x17
#define CS_BUSY 0x18
#define CS_GENERAL_FAILURE 0x19
#define CS_WRITE_PROTECTED 0x1a
#define CS_BAD_ARG_LENGTH 0x1b
#define CS_BAD_ARGS 0x1c
#define CS_CONFIGURATION_LOCKED 0x1d
#define CS_IN_USE 0x1e
#define CS_NO_MORE_ITEMS 0x1f
#define CS_OUT_OF_RESOURCE 0x20
#define CS_BAD_HANDLE 0x21
#define CS_BAD_TUPLE 0x40
#ifdef __KERNEL__
/*
* The main Card Services entry point
*/
enum service {
AccessConfigurationRegister, AddSocketServices,
AdjustResourceInfo, CheckEraseQueue, CloseMemory, CopyMemory,
DeregisterClient, DeregisterEraseQueue, GetCardServicesInfo,
GetClientInfo, GetConfigurationInfo, GetEventMask,
GetFirstClient, GetFirstPartion, GetFirstRegion, GetFirstTuple,
GetNextClient, GetNextPartition, GetNextRegion, GetNextTuple,
GetStatus, GetTupleData, MapLogSocket, MapLogWindow, MapMemPage,
MapPhySocket, MapPhyWindow, ModifyConfiguration, ModifyWindow,
OpenMemory, ParseTuple, ReadMemory, RegisterClient,
RegisterEraseQueue, RegisterMTD, RegisterTimer,
ReleaseConfiguration, ReleaseExclusive, ReleaseIO, ReleaseIRQ,
ReleaseSocketMask, ReleaseWindow, ReplaceSocketServices,
RequestConfiguration, RequestExclusive, RequestIO, RequestIRQ,
RequestSocketMask, RequestWindow, ResetCard, ReturnSSEntry,
SetEventMask, SetRegion, ValidateCIS, VendorSpecific,
WriteMemory, BindDevice, BindMTD, ReportError,
SuspendCard, ResumeCard, EjectCard, InsertCard, ReplaceCIS,
GetFirstWindow, GetNextWindow, GetMemPage
};
struct pcmcia_socket;
int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, conf_reg_t *reg);
int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, config_info_t *config);
int pcmcia_get_mem_page(window_handle_t win, memreq_t *req);
int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod);
int pcmcia_release_window(window_handle_t win);
int pcmcia_request_configuration(struct pcmcia_device *p_dev, config_req_t *req);
int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req);
int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req);
int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh);
int pcmcia_suspend_card(struct pcmcia_socket *skt);
int pcmcia_resume_card(struct pcmcia_socket *skt);
int pcmcia_eject_card(struct pcmcia_socket *skt);
int pcmcia_insert_card(struct pcmcia_socket *skt);
int pccard_reset_card(struct pcmcia_socket *skt);
struct pcmcia_device * pcmcia_dev_present(struct pcmcia_device *p_dev);
void pcmcia_disable_device(struct pcmcia_device *p_dev);
struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt);
void pcmcia_put_socket(struct pcmcia_socket *skt);
/* compatibility functions */
#define pcmcia_reset_card(p_dev, req) \
pccard_reset_card(p_dev->socket)
#endif /* __KERNEL__ */
#endif /* _LINUX_CS_H */

View File

@ -21,14 +21,6 @@
#include <sys/types.h>
#endif
#if defined(__arm__) || defined(__mips__) || defined(__avr32__) || \
defined(__bfin__)
/* This (ioaddr_t) is exposed to userspace & hence cannot be changed. */
typedef u_int ioaddr_t;
#else
typedef u_short ioaddr_t;
#endif
typedef u_short socket_t;
typedef u_int event_t;
typedef u_char cisdata_t;

View File

@ -1,10 +1,19 @@
/*
* Copyright (2003-2004) Dominik Brodowski <linux@brodo.de>
* David Woodhouse
* device_id.h -- PCMCIA driver matching helpers
*
* License: GPL v2
* 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.
*
* (C) 2003 - 2004 David Woodhouse
* (C) 2003 - 2004 Dominik Brodowski
*/
#ifndef _LINUX_PCMCIA_DEVICE_ID_H
#define _LINUX_PCMCIA_DEVICE_ID_H
#ifdef __KERNEL__
#define PCMCIA_DEVICE_MANF_CARD(manf, card) { \
.match_flags = PCMCIA_DEV_ID_MATCH_MANF_ID| \
PCMCIA_DEV_ID_MATCH_CARD_ID, \
@ -256,3 +265,6 @@
#define PCMCIA_DEVICE_NULL { .match_flags = 0, }
#endif /* __KERNEL__ */
#endif /* _LINUX_PCMCIA_DEVICE_ID_H */

View File

@ -10,7 +10,7 @@
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
*
* (C) 1999 David A. Hinds
* (C) 2003 - 2004 Dominik Brodowski
* (C) 2003 - 2008 Dominik Brodowski
*/
#ifndef _LINUX_DS_H
@ -23,108 +23,21 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/device_id.h>
typedef struct tuple_parse_t {
tuple_t tuple;
cisdata_t data[255];
cisparse_t parse;
} tuple_parse_t;
typedef struct win_info_t {
window_handle_t handle;
win_req_t window;
memreq_t map;
} win_info_t;
typedef struct bind_info_t {
dev_info_t dev_info;
u_char function;
struct pcmcia_device *instance;
char name[DEV_NAME_LEN];
u_short major, minor;
void *next;
} bind_info_t;
typedef struct mtd_info_t {
dev_info_t dev_info;
u_int Attributes;
u_int CardOffset;
} mtd_info_t;
typedef struct region_info_t {
u_int Attributes;
u_int CardOffset;
u_int RegionSize;
u_int AccessSpeed;
u_int BlockSize;
u_int PartMultiple;
u_char JedecMfr, JedecInfo;
memory_handle_t next;
} region_info_t;
#define REGION_TYPE 0x0001
#define REGION_TYPE_CM 0x0000
#define REGION_TYPE_AM 0x0001
#define REGION_PREFETCH 0x0008
#define REGION_CACHEABLE 0x0010
#define REGION_BAR_MASK 0xe000
#define REGION_BAR_SHIFT 13
typedef union ds_ioctl_arg_t {
adjust_t adjust;
config_info_t config;
tuple_t tuple;
tuple_parse_t tuple_parse;
client_req_t client_req;
cs_status_t status;
conf_reg_t conf_reg;
cisinfo_t cisinfo;
region_info_t region;
bind_info_t bind_info;
mtd_info_t mtd_info;
win_info_t win_info;
cisdump_t cisdump;
} ds_ioctl_arg_t;
#define DS_ADJUST_RESOURCE_INFO _IOWR('d', 2, adjust_t)
#define DS_GET_CONFIGURATION_INFO _IOWR('d', 3, config_info_t)
#define DS_GET_FIRST_TUPLE _IOWR('d', 4, tuple_t)
#define DS_GET_NEXT_TUPLE _IOWR('d', 5, tuple_t)
#define DS_GET_TUPLE_DATA _IOWR('d', 6, tuple_parse_t)
#define DS_PARSE_TUPLE _IOWR('d', 7, tuple_parse_t)
#define DS_RESET_CARD _IO ('d', 8)
#define DS_GET_STATUS _IOWR('d', 9, cs_status_t)
#define DS_ACCESS_CONFIGURATION_REGISTER _IOWR('d', 10, conf_reg_t)
#define DS_VALIDATE_CIS _IOR ('d', 11, cisinfo_t)
#define DS_SUSPEND_CARD _IO ('d', 12)
#define DS_RESUME_CARD _IO ('d', 13)
#define DS_EJECT_CARD _IO ('d', 14)
#define DS_INSERT_CARD _IO ('d', 15)
#define DS_GET_FIRST_REGION _IOWR('d', 16, region_info_t)
#define DS_GET_NEXT_REGION _IOWR('d', 17, region_info_t)
#define DS_REPLACE_CIS _IOWR('d', 18, cisdump_t)
#define DS_GET_FIRST_WINDOW _IOR ('d', 19, win_info_t)
#define DS_GET_NEXT_WINDOW _IOWR('d', 20, win_info_t)
#define DS_GET_MEM_PAGE _IOWR('d', 21, win_info_t)
#define DS_BIND_REQUEST _IOWR('d', 60, bind_info_t)
#define DS_GET_DEVICE_INFO _IOWR('d', 61, bind_info_t)
#define DS_GET_NEXT_DEVICE _IOWR('d', 62, bind_info_t)
#define DS_UNBIND_REQUEST _IOW ('d', 63, bind_info_t)
#define DS_BIND_MTD _IOWR('d', 64, mtd_info_t)
#ifdef __KERNEL__
#include <linux/device.h>
#include <pcmcia/ss.h>
typedef struct dev_node_t {
char dev_name[DEV_NAME_LEN];
u_short major, minor;
struct dev_node_t *next;
} dev_node_t;
/*
* PCMCIA device drivers (16-bit cards only; 32-bit cards require CardBus
* a.k.a. PCI drivers
*/
struct pcmcia_socket;
struct pcmcia_device;
struct config_t;
/* dynamic device IDs for PCMCIA device drivers. See
* Documentation/pcmcia/driver.txt for details.
*/
struct pcmcia_dynids {
spinlock_t lock;
struct list_head list;
@ -147,6 +60,14 @@ struct pcmcia_driver {
int pcmcia_register_driver(struct pcmcia_driver *driver);
void pcmcia_unregister_driver(struct pcmcia_driver *driver);
/* Some drivers use dev_node_t to store char or block device information.
* Don't use this in new drivers, though.
*/
typedef struct dev_node_t {
char dev_name[DEV_NAME_LEN];
u_short major, minor;
struct dev_node_t *next;
} dev_node_t;
struct pcmcia_device {
/* the socket and the device_no [for multifunction devices]
@ -216,10 +137,304 @@ struct pcmcia_device {
#define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev)
#define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv)
/* deprecated -- don't use! */
#define handle_to_dev(handle) (handle->dev)
/* error reporting */
void cs_error(struct pcmcia_device *handle, int func, int ret);
/* (deprecated) error reporting by PCMCIA devices. Use dev_printk()
* or dev_dbg() directly in the driver, without referring to pcmcia_error_func()
* and/or pcmcia_error_ret() for those functions will go away soon.
*/
enum service {
AccessConfigurationRegister, AddSocketServices,
AdjustResourceInfo, CheckEraseQueue, CloseMemory, CopyMemory,
DeregisterClient, DeregisterEraseQueue, GetCardServicesInfo,
GetClientInfo, GetConfigurationInfo, GetEventMask,
GetFirstClient, GetFirstPartion, GetFirstRegion, GetFirstTuple,
GetNextClient, GetNextPartition, GetNextRegion, GetNextTuple,
GetStatus, GetTupleData, MapLogSocket, MapLogWindow, MapMemPage,
MapPhySocket, MapPhyWindow, ModifyConfiguration, ModifyWindow,
OpenMemory, ParseTuple, ReadMemory, RegisterClient,
RegisterEraseQueue, RegisterMTD, RegisterTimer,
ReleaseConfiguration, ReleaseExclusive, ReleaseIO, ReleaseIRQ,
ReleaseSocketMask, ReleaseWindow, ReplaceSocketServices,
RequestConfiguration, RequestExclusive, RequestIO, RequestIRQ,
RequestSocketMask, RequestWindow, ResetCard, ReturnSSEntry,
SetEventMask, SetRegion, ValidateCIS, VendorSpecific,
WriteMemory, BindDevice, BindMTD, ReportError,
SuspendCard, ResumeCard, EjectCard, InsertCard, ReplaceCIS,
GetFirstWindow, GetNextWindow, GetMemPage
};
const char *pcmcia_error_func(int func);
const char *pcmcia_error_ret(int ret);
#define cs_error(p_dev, func, ret) \
{ \
dev_printk(KERN_NOTICE, &p_dev->dev, \
"%s : %s\n", \
pcmcia_error_func(func), \
pcmcia_error_ret(ret)); \
}
/* CIS access.
* Use the pcmcia_* versions in PCMCIA drivers
*/
int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse);
int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
tuple_t *tuple);
#define pcmcia_get_first_tuple(p_dev, tuple) \
pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple)
int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
tuple_t *tuple);
#define pcmcia_get_next_tuple(p_dev, tuple) \
pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple)
int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
#define pcmcia_get_tuple_data(p_dev, tuple) \
pccard_get_tuple_data(p_dev->socket, tuple)
/* loop CIS entries for valid configuration */
int pcmcia_loop_config(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);
/* is the device still there? */
struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *p_dev);
/* low-level interface reset */
int pcmcia_reset_card(struct pcmcia_socket *skt);
/* CIS config */
int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
conf_reg_t *reg);
/* device configuration */
int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req);
int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req);
int pcmcia_request_configuration(struct pcmcia_device *p_dev,
config_req_t *req);
int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req,
window_handle_t *wh);
int pcmcia_release_window(window_handle_t win);
int pcmcia_get_mem_page(window_handle_t win, memreq_t *req);
int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod);
void pcmcia_disable_device(struct pcmcia_device *p_dev);
#endif /* __KERNEL__ */
/* Below, there are only definitions which are used by
* - the PCMCIA ioctl
* - deprecated PCMCIA userspace tools only
*
* here be dragons ... here be dragons ... here be dragons ... here be drag
*/
#if defined(CONFIG_PCMCIA_IOCTL) || !defined(__KERNEL__)
#if defined(__arm__) || defined(__mips__) || defined(__avr32__) || \
defined(__bfin__)
/* This (ioaddr_t) is exposed to userspace & hence cannot be changed. */
typedef u_int ioaddr_t;
#else
typedef u_short ioaddr_t;
#endif
/* for AdjustResourceInfo */
typedef struct adjust_t {
u_int Action;
u_int Resource;
u_int Attributes;
union {
struct memory {
u_long Base;
u_long Size;
} memory;
struct io {
ioaddr_t BasePort;
ioaddr_t NumPorts;
u_int IOAddrLines;
} io;
struct irq {
u_int IRQ;
} irq;
} resource;
} adjust_t;
/* Action field */
#define REMOVE_MANAGED_RESOURCE 1
#define ADD_MANAGED_RESOURCE 2
#define GET_FIRST_MANAGED_RESOURCE 3
#define GET_NEXT_MANAGED_RESOURCE 4
/* Resource field */
#define RES_MEMORY_RANGE 1
#define RES_IO_RANGE 2
#define RES_IRQ 3
/* Attribute field */
#define RES_IRQ_TYPE 0x03
#define RES_IRQ_TYPE_EXCLUSIVE 0
#define RES_IRQ_TYPE_TIME 1
#define RES_IRQ_TYPE_DYNAMIC 2
#define RES_IRQ_CSC 0x04
#define RES_SHARED 0x08
#define RES_RESERVED 0x10
#define RES_ALLOCATED 0x20
#define RES_REMOVED 0x40
typedef struct tuple_parse_t {
tuple_t tuple;
cisdata_t data[255];
cisparse_t parse;
} tuple_parse_t;
typedef struct win_info_t {
window_handle_t handle;
win_req_t window;
memreq_t map;
} win_info_t;
typedef struct bind_info_t {
dev_info_t dev_info;
u_char function;
struct pcmcia_device *instance;
char name[DEV_NAME_LEN];
u_short major, minor;
void *next;
} bind_info_t;
typedef struct mtd_info_t {
dev_info_t dev_info;
u_int Attributes;
u_int CardOffset;
} mtd_info_t;
typedef struct region_info_t {
u_int Attributes;
u_int CardOffset;
u_int RegionSize;
u_int AccessSpeed;
u_int BlockSize;
u_int PartMultiple;
u_char JedecMfr, JedecInfo;
memory_handle_t next;
} region_info_t;
#define REGION_TYPE 0x0001
#define REGION_TYPE_CM 0x0000
#define REGION_TYPE_AM 0x0001
#define REGION_PREFETCH 0x0008
#define REGION_CACHEABLE 0x0010
#define REGION_BAR_MASK 0xe000
#define REGION_BAR_SHIFT 13
/* For ReplaceCIS */
typedef struct cisdump_t {
u_int Length;
cisdata_t Data[CISTPL_MAX_CIS_SIZE];
} cisdump_t;
/* for GetConfigurationInfo */
typedef struct config_info_t {
u_char Function;
u_int Attributes;
u_int Vcc, Vpp1, Vpp2;
u_int IntType;
u_int ConfigBase;
u_char Status, Pin, Copy, Option, ExtStatus;
u_int Present;
u_int CardValues;
u_int AssignedIRQ;
u_int IRQAttributes;
ioaddr_t BasePort1;
ioaddr_t NumPorts1;
u_int Attributes1;
ioaddr_t BasePort2;
ioaddr_t NumPorts2;
u_int Attributes2;
u_int IOAddrLines;
} config_info_t;
/* For ValidateCIS */
typedef struct cisinfo_t {
u_int Chains;
} cisinfo_t;
typedef struct cs_status_t {
u_char Function;
event_t CardState;
event_t SocketState;
} cs_status_t;
typedef union ds_ioctl_arg_t {
adjust_t adjust;
config_info_t config;
tuple_t tuple;
tuple_parse_t tuple_parse;
client_req_t client_req;
cs_status_t status;
conf_reg_t conf_reg;
cisinfo_t cisinfo;
region_info_t region;
bind_info_t bind_info;
mtd_info_t mtd_info;
win_info_t win_info;
cisdump_t cisdump;
} ds_ioctl_arg_t;
#define DS_ADJUST_RESOURCE_INFO _IOWR('d', 2, adjust_t)
#define DS_GET_CONFIGURATION_INFO _IOWR('d', 3, config_info_t)
#define DS_GET_FIRST_TUPLE _IOWR('d', 4, tuple_t)
#define DS_GET_NEXT_TUPLE _IOWR('d', 5, tuple_t)
#define DS_GET_TUPLE_DATA _IOWR('d', 6, tuple_parse_t)
#define DS_PARSE_TUPLE _IOWR('d', 7, tuple_parse_t)
#define DS_RESET_CARD _IO ('d', 8)
#define DS_GET_STATUS _IOWR('d', 9, cs_status_t)
#define DS_ACCESS_CONFIGURATION_REGISTER _IOWR('d', 10, conf_reg_t)
#define DS_VALIDATE_CIS _IOR ('d', 11, cisinfo_t)
#define DS_SUSPEND_CARD _IO ('d', 12)
#define DS_RESUME_CARD _IO ('d', 13)
#define DS_EJECT_CARD _IO ('d', 14)
#define DS_INSERT_CARD _IO ('d', 15)
#define DS_GET_FIRST_REGION _IOWR('d', 16, region_info_t)
#define DS_GET_NEXT_REGION _IOWR('d', 17, region_info_t)
#define DS_REPLACE_CIS _IOWR('d', 18, cisdump_t)
#define DS_GET_FIRST_WINDOW _IOR ('d', 19, win_info_t)
#define DS_GET_NEXT_WINDOW _IOWR('d', 20, win_info_t)
#define DS_GET_MEM_PAGE _IOWR('d', 21, win_info_t)
#define DS_BIND_REQUEST _IOWR('d', 60, bind_info_t)
#define DS_GET_DEVICE_INFO _IOWR('d', 61, bind_info_t)
#define DS_GET_NEXT_DEVICE _IOWR('d', 62, bind_info_t)
#define DS_UNBIND_REQUEST _IOW ('d', 63, bind_info_t)
#define DS_BIND_MTD _IOWR('d', 64, mtd_info_t)
/* used in userspace only */
#define CS_IN_USE 0x1e
#define INFO_MASTER_CLIENT 0x01
#define INFO_IO_CLIENT 0x02
#define INFO_MTD_CLIENT 0x04
#define INFO_MEM_CLIENT 0x08
#define MAX_NUM_CLIENTS 3
#define INFO_CARD_SHARE 0x10
#define INFO_CARD_EXCL 0x20
#endif /* !defined(__KERNEL__) || defined(CONFIG_PCMCIA_IOCTL) */
#endif /* _LINUX_DS_H */

View File

@ -53,10 +53,10 @@
/* for GetSocket, SetSocket */
typedef struct socket_state_t {
u_int flags;
u_int csc_mask;
u_char Vcc, Vpp;
u_char io_irq;
u_int flags;
u_int csc_mask;
u_char Vcc, Vpp;
u_char io_irq;
} socket_state_t;
extern socket_state_t dead_socket;
@ -86,79 +86,22 @@ extern socket_state_t dead_socket;
#define HOOK_POWER_PRE 0x01
#define HOOK_POWER_POST 0x02
typedef struct pccard_io_map {
u_char map;
u_char flags;
u_short speed;
u_int start, stop;
u_char map;
u_char flags;
u_short speed;
u_int start, stop;
} pccard_io_map;
typedef struct pccard_mem_map {
u_char map;
u_char flags;
u_short speed;
u_long static_start;
u_int card_start;
struct resource *res;
u_char map;
u_char flags;
u_short speed;
u_long static_start;
u_int card_start;
struct resource *res;
} pccard_mem_map;
typedef struct cb_bridge_map {
u_char map;
u_char flags;
u_int start, stop;
} cb_bridge_map;
/*
* Socket operations.
*/
struct pcmcia_socket;
struct pccard_operations {
int (*init)(struct pcmcia_socket *sock);
int (*suspend)(struct pcmcia_socket *sock);
int (*get_status)(struct pcmcia_socket *sock, u_int *value);
int (*set_socket)(struct pcmcia_socket *sock, socket_state_t *state);
int (*set_io_map)(struct pcmcia_socket *sock, struct pccard_io_map *io);
int (*set_mem_map)(struct pcmcia_socket *sock, struct pccard_mem_map *mem);
};
struct pccard_resource_ops {
int (*validate_mem) (struct pcmcia_socket *s);
int (*adjust_io_region) (struct resource *res,
unsigned long r_start,
unsigned long r_end,
struct pcmcia_socket *s);
struct resource* (*find_io) (unsigned long base, int num,
unsigned long align,
struct pcmcia_socket *s);
struct resource* (*find_mem) (unsigned long base, unsigned long num,
unsigned long align, int low,
struct pcmcia_socket *s);
int (*add_io) (struct pcmcia_socket *s,
unsigned int action,
unsigned long r_start,
unsigned long r_end);
int (*add_mem) (struct pcmcia_socket *s,
unsigned int action,
unsigned long r_start,
unsigned long r_end);
int (*init) (struct pcmcia_socket *s);
void (*exit) (struct pcmcia_socket *s);
};
/* SS_CAP_STATIC_MAP */
extern struct pccard_resource_ops pccard_static_ops;
/* !SS_CAP_STATIC_MAP */
extern struct pccard_resource_ops pccard_nonstatic_ops;
/* static mem, dynamic IO sockets */
extern struct pccard_resource_ops pccard_iodyn_ops;
/*
* Calls to set up low-level "Socket Services" drivers
*/
struct pcmcia_socket;
typedef struct io_window_t {
u_int InUse, Config;
struct resource *res;
@ -179,10 +122,25 @@ typedef struct window_t {
/* Maximum number of memory windows per socket */
#define MAX_WIN 4
/*
* Socket operations.
*/
struct pcmcia_socket;
struct pccard_resource_ops;
struct config_t;
struct pcmcia_callback;
struct user_info_t;
struct pccard_operations {
int (*init)(struct pcmcia_socket *s);
int (*suspend)(struct pcmcia_socket *s);
int (*get_status)(struct pcmcia_socket *s, u_int *value);
int (*set_socket)(struct pcmcia_socket *s, socket_state_t *state);
int (*set_io_map)(struct pcmcia_socket *s, struct pccard_io_map *io);
int (*set_mem_map)(struct pcmcia_socket *s, struct pccard_mem_map *mem);
};
struct pcmcia_socket {
struct module *owner;
spinlock_t lock;
@ -199,8 +157,8 @@ struct pcmcia_socket {
io_window_t io[MAX_IO_WIN];
window_t win[MAX_WIN];
struct list_head cis_cache;
u_int fake_cis_len;
char *fake_cis;
size_t fake_cis_len;
u8 *fake_cis;
struct list_head socket_list;
struct completion socket_released;
@ -218,12 +176,12 @@ struct pcmcia_socket {
struct pci_dev * cb_dev;
/* socket setup is done so resources should be able to be allocated. Only
* if set to 1, calls to find_{io,mem}_region are handled, and insertion
* events are actually managed by the PCMCIA layer.*/
/* socket setup is done so resources should be able to be allocated.
* Only if set to 1, calls to find_{io,mem}_region are handled, and
* insertio events are actually managed by the PCMCIA layer.*/
u8 resource_setup_done:1;
/* is set to one if resource setup is done using adjust_resource_info() */
/* It's old if resource setup is done using adjust_resource_info() */
u8 resource_setup_old:1;
u8 resource_setup_new:1;
@ -236,75 +194,101 @@ struct pcmcia_socket {
/* Zoom video behaviour is so chip specific its not worth adding
this to _ops */
void (*zoom_video)(struct pcmcia_socket *, int);
void (*zoom_video)(struct pcmcia_socket *,
int);
/* so is power hook */
int (*power_hook)(struct pcmcia_socket *sock, int operation);
#ifdef CONFIG_CARDBUS
/* allows tuning the CB bridge before loading driver for the CB card */
#ifdef CONFIG_CARDBUS
void (*tune_bridge)(struct pcmcia_socket *sock, struct pci_bus *bus);
#endif
/* state thread */
struct mutex skt_mutex; /* protects socket h/w state */
struct task_struct *thread;
struct completion thread_done;
spinlock_t thread_lock; /* protects thread_events */
unsigned int thread_events;
/* protects socket h/w state */
struct mutex skt_mutex;
/* protects thread_events */
spinlock_t thread_lock;
/* pcmcia (16-bit) */
struct pcmcia_callback *callback;
#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
struct list_head devices_list; /* PCMCIA devices */
u8 device_count; /* the number of devices, used
* only internally and subject
* to incorrectness and change */
/* The following elements refer to 16-bit PCMCIA devices inserted
* into the socket */
struct list_head devices_list;
/* the number of devices, used only internally and subject to
* incorrectness and change */
u8 device_count;
/* 16-bit state: */
struct {
u8 present:1, /* PCMCIA card is present in socket */
busy:1, /* "master" ioctl is used */
dead:1, /* pcmcia module is being unloaded */
device_add_pending:1, /* a multifunction-device
* add event is pending */
mfc_pfc:1, /* the pending event adds a mfc (1) or pfc (0) */
reserved:3;
} pcmcia_state;
/* PCMCIA card is present in socket */
u8 present:1;
/* "master" ioctl is used */
u8 busy:1;
/* pcmcia module is being unloaded */
u8 dead:1;
/* a multifunction-device add event is pending */
u8 device_add_pending:1;
/* the pending event adds a mfc (1) or pfc (0) */
u8 mfc_pfc:1;
struct work_struct device_add; /* for adding further pseudo-multifunction
* devices */
u8 reserved:3;
} pcmcia_state;
/* for adding further pseudo-multifunction devices */
struct work_struct device_add;
#ifdef CONFIG_PCMCIA_IOCTL
struct user_info_t *user;
wait_queue_head_t queue;
#endif
#endif
#endif /* CONFIG_PCMCIA_IOCTL */
#endif /* CONFIG_PCMCIA */
/* cardbus (32-bit) */
#ifdef CONFIG_CARDBUS
struct resource * cb_cis_res;
void __iomem *cb_cis_virt;
#endif
#endif /* CONFIG_CARDBUS */
/* socket device */
struct device dev;
void *driver_data; /* data internal to the socket driver */
/* data internal to the socket driver */
void *driver_data;
};
struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr);
extern void pcmcia_parse_events(struct pcmcia_socket *socket, unsigned int events);
extern int pcmcia_register_socket(struct pcmcia_socket *socket);
extern void pcmcia_unregister_socket(struct pcmcia_socket *socket);
extern struct class pcmcia_socket_class;
/* socket drivers must define the resource operations type they use. There
* are three options:
* - pccard_static_ops iomem and ioport areas are assigned statically
* - pccard_iodyn_ops iomem areas is assigned statically, ioport
* areas dynamically
* - pccard_nonstatic_ops iomem and ioport areas are assigned dynamically.
* If this option is selected, use
* "select PCCARD_NONSTATIC" in Kconfig.
*/
extern struct pccard_resource_ops pccard_static_ops;
extern struct pccard_resource_ops pccard_iodyn_ops;
extern struct pccard_resource_ops pccard_nonstatic_ops;
/* socket drivers are expected to use these callbacks in their .drv struct */
extern int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state);
extern int pcmcia_socket_dev_resume(struct device *dev);
/* socket drivers use this callback in their IRQ handler */
extern void pcmcia_parse_events(struct pcmcia_socket *socket,
unsigned int events);
/* to register and unregister a socket */
extern int pcmcia_register_socket(struct pcmcia_socket *socket);
extern void pcmcia_unregister_socket(struct pcmcia_socket *socket);
#endif /* _LINUX_SS_H */