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 (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 */
}
}
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++;
}
}
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)
/* 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;
}
next_entry:
i = next_tuple(link, &tuple, &parse);
}
}
/* 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)
if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))
goto found_port;
}
}
i = next_tuple(link, &tuple, &parse);
}
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)
/* 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;
}
next_entry:
i = next_tuple(link, &tuple, &parse);
}
}
/* 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)
if (!pcmcia_loop_config(link, btuart_check_config_notpicky, NULL))
goto found_port;
}
}
i = next_tuple(link, &tuple, &parse);
}
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);
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;
}
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);
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 (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 */
}
}
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++;
}
}
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,45 +154,34 @@ 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;
do {
devname[0] = 0;
if (link->prod_id[1])
strlcpy(devname, link->prod_id[1], sizeof(devname));
@ -200,37 +189,15 @@ static int avmcs_config(struct pcmcia_device *link)
/*
* 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;
}
if (pcmcia_loop_config(link, avmcs_configcheck, NULL))
return -ENODEV;
do {
/*
* 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);
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;
}
if (pcmcia_loop_config(link, avma1cs_configcheck, NULL))
return -ENODEV;
do {
/*
* 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);
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;
if (cfg->index == 0)
return -ENODEV;
/* 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;
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))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
p_dev->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;
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) {
link->io.Attributes2 = link->io.Attributes1;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
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(link, &link->io) != 0)
goto next_entry;
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;
}
return 0;
}
/* If we got this far, we're cool! */
break;
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,10 +327,9 @@ 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);
}
}
/* After a card is removed, pcmciamtd_release() will unregister the
@ -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

@ -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_config(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)
{
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);
int i;
cistpl_io_t *io = &cfg->io;
DEBUG(0, "axnet_config(0x%p)\n", link);
if (cfg->index == 0 || cfg->io.nwin == 0)
return -ENODEV;
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;
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);
link->io.BasePort2 = io->win[1-i].base;
link->io.NumPorts2 = io->win[1-i].len;
p_dev->io.BasePort2 = io->win[1-i].base;
p_dev->io.NumPorts2 = io->win[1-i].len;
} else {
i = link->io.NumPorts2 = 0;
i = p_dev->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;
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;
}
next_entry:
last_ret = pcmcia_get_next_tuple(link, &tuple);
}
if (last_ret != CS_SUCCESS) {
static int axnet_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
axnet_dev_t *info = PRIV(dev);
int i, j, last_ret, last_fn;
DECLARE_MAC_BUF(mac);
DEBUG(0, "axnet_config(0x%p)\n", link);
/* don't trust the CIS on this; Linksys got it wrong */
link->conf.Present = 0x63;
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)
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;
}
@ -960,7 +936,10 @@ 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; }
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)))
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,89 +206,55 @@ 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_config(struct pcmcia_device *link)
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)
{
tuple_t tuple;
cisparse_t parse;
local_info_t *dev;
int last_fn, last_ret;
u_char buf[64];
win_req_t req;
memreq_t map;
win_req_t *req = priv_data;
dev = link->priv;
DEBUG(0, "airo_config(0x%p)\n", link);
/*
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.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;
if (cfg->index == 0)
return -ENODEV;
/* 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->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;
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))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
p_dev->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;
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) {
link->io.Attributes2 = link->io.Attributes1;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
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(link, &link->io) != 0)
goto next_entry;
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
return -ENODEV;
/*
Now set up a common memory window, if needed. There is room
@ -301,26 +267,57 @@ static int airo_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.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 ((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! */
break;
next_entry:
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
return 0;
}
static int airo_config(struct pcmcia_device *link)
{
local_info_t *dev;
win_req_t *req;
int last_fn, last_ret;
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.
*/
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
@ -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);
last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
if (last_ret) {
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) {
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);
last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
if (last_ret) {
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) {
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,50 +149,42 @@ 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));
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));

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)
{
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 = 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;
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;
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,13 +504,14 @@ 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",
dev_printk(KERN_NOTICE, &skt->dev,
"pccard: %s card inserted into slot %d\n",
(skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
skt->sock);
@ -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;
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 */
#ifdef CONFIG_PCMCIA_DEBUG
extern int cs_debug_level(int);
#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);
/* rsrc_mgr.c */
void release_resource_db(struct pcmcia_socket *s);
/* socket_sysfs.c */
extern int pccard_sysfs_add_socket(struct device *dev);
extern void pccard_sysfs_remove_socket(struct device *dev);
/* 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);
int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len,
void *ptr);
/* In cistpl.c */
/*
* 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);
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);
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);
struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt);
void pcmcia_put_socket(struct pcmcia_socket *skt);
/* 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 verify_cis_cache(struct pcmcia_socket *s);
int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse);
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);
/* In rsrc_mgr */
/* 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 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);
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);
void release_resource_db(struct pcmcia_socket *s);
/* In socket_sysfs.c */
extern int pccard_sysfs_add_socket(struct device *dev);
extern void pccard_sysfs_remove_socket(struct device *dev);
/*
* Stuff internal to module "pcmcia".
*/
/* ds.c */
extern struct bus_type pcmcia_bus_type;
/* 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);
/* 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;
struct pcmcia_callback{
struct module *owner;
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);
};
extern struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev);
extern void pcmcia_put_dev(struct pcmcia_device *p_dev);
int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
unsigned int function);
#define cs_socket_name(skt) ((skt)->dev.bus_id)
/* 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);
#ifdef DEBUG
extern int cs_debug_level(int);
#else /* CONFIG_PCMCIA_IOCTL */
#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)
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;
}
#else
#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0)
#endif
#define cs_err(skt, fmt, arg...) \
printk(KERN_ERR "cs: %s: " fmt, (skt)->dev.bus_id , ## arg)
#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,7 +41,7 @@ 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);
@ -51,8 +50,13 @@ module_param_named(pc_debug, ds_pc_debug, int, 0644);
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,7 +457,8 @@ 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,
ds_dev_dbg(2, leftover ? &leftover->dev : &s->dev,
"pcmcia_card_remove(%d) %s\n", s->sock,
leftover ? leftover->devname : "");
if (!leftover)
@ -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,12 +516,14 @@ 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",
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",
dev_printk(KERN_INFO, dev,
"pcmcia: driver %s did not release window properly\n",
p_drv->drv.name);
/* references from pcmcia_probe_device */
@ -603,7 +573,8 @@ 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 "
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,7 +685,8 @@ 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",
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,16 +831,16 @@ 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",
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,7 +1239,8 @@ 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 "
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;
@ -1287,7 +1248,7 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
}
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,12 +1352,13 @@ 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",
ds_dev_dbg(1, &skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
event, priority, skt);
switch (event) {
@ -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

@ -131,10 +131,13 @@ static int add_interval(struct resource_map *map, u_long base, u_long num)
break;
}
q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
if (!q) return CS_OUT_OF_RESOURCE;
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 CS_SUCCESS;
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:",
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,7 +373,7 @@ 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:",
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);
@ -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,7 +801,8 @@ 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 "
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);
@ -806,7 +814,8 @@ 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 "
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);

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;
}
@ -598,8 +599,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 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,9 +833,11 @@ 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",
dev_printk(KERN_INFO, &socket->dev->dev,
"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",
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 */
@ -858,7 +863,8 @@ 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",
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);
@ -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,7 +960,8 @@ 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",
dev_printk(KERN_INFO, &socket->dev->dev,
"ISA IRQ mask 0x%04x, PCI irq %d\n",
socket->socket.irq_mask, socket->cb_irq);
}
@ -1051,7 +1052,8 @@ 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 "
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, */
@ -1061,7 +1063,8 @@ 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 "
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);
@ -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,42 +140,39 @@ 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));
@ -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)
/*====================================================================*/
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;
struct nsp_cs_configdata {
nsp_hw_data *data;
win_req_t req;
memreq_t map;
cistpl_cftable_entry_t dflt = { 0 };
struct Scsi_Host *host;
nsp_hw_data *data = &nsp_data_base;
};
nsp_dbg(NSP_DEBUG_INIT, "in");
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;
tuple.Attributes = 0;
tuple.TupleData = tuple_data;
tuple.TupleDataMax = sizeof(tuple_data);
tuple.TupleOffset = 0;
/* 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;
if (cfg->index == 0)
return -ENODEV;
/* 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 =
p_dev->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;
} 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;
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))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
p_dev->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;
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) {
link->io.Attributes2 = link->io.Attributes1;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
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(link, &link->io) != 0)
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
goto next_entry;
}
if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
memreq_t map;
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)
(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(link->win, &map) != 0)
if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
goto next_entry;
data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
data->MmioLength = req.Size;
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! */
break;
return 0;
}
next_entry:
nsp_dbg(NSP_DEBUG_INIT, "next");
pcmcia_disable_device(link);
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
pcmcia_disable_device(p_dev);
return -ENODEV;
}
static int nsp_cs_config(struct pcmcia_device *link)
{
int ret;
scsi_info_t *info = link->priv;
struct nsp_cs_configdata *cfg_mem;
struct Scsi_Host *host;
nsp_hw_data *data = &nsp_data_base;
nsp_dbg(NSP_DEBUG_INIT, "in");
cfg_mem = kzalloc(sizeof(cfg_mem), GFP_KERNEL);
if (!cfg_mem)
return -ENOMEM;
cfg_mem->data = data;
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)
/* 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;
}
next_entry:
i = next_tuple(link, tuple, parse);
}
}
}
/* 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)
if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
goto found_port;
}
}
i = next_tuple(link, tuple, parse);
}
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;
}
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_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 (pcmcia_loop_config(link, multi_config_check, &base2)) {
/* If that didn't work, look for two windows */
if (i != CS_SUCCESS) {
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;
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;
}
i = next_tuple(link, tuple, parse);
}
}
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,52 +124,40 @@ 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.
@ -181,8 +169,8 @@ static int ixj_config(struct pcmcia_device * link)
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(struct pcmcia_device *link)
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)
{
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;
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
!= 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->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))
link->conf.Vpp =
p_dev->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;
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)
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;
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;
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;
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 (pcmcia_request_io(link, &link->io) != 0)
goto next_entry;
return pcmcia_request_io(p_dev, &p_dev->io);
}
break;
next_entry:
pcmcia_disable_device(link);
last_ret = pcmcia_get_next_tuple(link, &tuple);
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;
int last_fn, last_ret;
DBG(0, "sl811_cs_config(0x%p)\n", link);
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

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

@ -86,7 +86,6 @@ 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;
@ -103,62 +102,6 @@ typedef struct pccard_mem_map {
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 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;
u8 reserved:3;
} pcmcia_state;
struct work_struct device_add; /* for adding further pseudo-multifunction
* devices */
/* 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 */