Merge branches 'pcmcia-config-loop' and 'pcmcia-printk' into pcmcia
* pcmcia-config-loop: pcmcia: pcmcia_config_loop() improvement by passing vcc pcmcia: pcmcia_config_loop() default CIS entry handling pcmcia: pcmcia_config_loop() ConfigIndex unification pcmcia: use pcmcia_loop_config in misc pcmcia drivers pcmcia: use pcmcia_loop_config in net pcmcia drivers pcmcia: use pcmcia_loop_config in ISDN pcmcia drivers pcmcia: use pcmcia_loop_config in scsi pcmcia drivers pcmcia: use pcmcia_loop_config in bluetooth drivers pcmcia: use pcmcia_loop_config in pata and ide drivers pcmcia: add pcmcia_loop_config() helper * pcmcia-printk: pcmcia: don't add extra DEBUG cflag pcmcia: remove unused cs_socket_name() definition pcmcia: use dev_printk in module rsrc_nonstatic pcmcia: use dev_printk in module pcmcia pcmcia: use dev_printk in module pcmcia_core pcmcia: use dev_printk and dev_dbg in yenta_socket
This commit is contained in:
commit
ff08705860
|
@ -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
|
||||
|
|
|
@ -148,6 +148,64 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
|
|||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
|
||||
struct pcmcia_config_check {
|
||||
unsigned long ctl_base;
|
||||
int skip_vcc;
|
||||
int is_kme;
|
||||
};
|
||||
|
||||
static int pcmcia_check_one_config(struct pcmcia_device *pdev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
struct pcmcia_config_check *stk = priv_data;
|
||||
|
||||
/* Check for matching Vcc, unless we're desperate */
|
||||
if (!stk->skip_vcc) {
|
||||
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
|
||||
return -ENODEV;
|
||||
} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
|
||||
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
|
||||
pdev->io.BasePort1 = io->win[0].base;
|
||||
pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||
if (!(io->flags & CISTPL_IO_16BIT))
|
||||
pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
if (io->nwin == 2) {
|
||||
pdev->io.NumPorts1 = 8;
|
||||
pdev->io.BasePort2 = io->win[1].base;
|
||||
pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1;
|
||||
if (pcmcia_request_io(pdev, &pdev->io) != 0)
|
||||
return -ENODEV;
|
||||
stk->ctl_base = pdev->io.BasePort2;
|
||||
} else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
|
||||
pdev->io.NumPorts1 = io->win[0].len;
|
||||
pdev->io.NumPorts2 = 0;
|
||||
if (pcmcia_request_io(pdev, &pdev->io) != 0)
|
||||
return -ENODEV;
|
||||
stk->ctl_base = pdev->io.BasePort1 + 0x0e;
|
||||
} else
|
||||
return -ENODEV;
|
||||
/* If we've got this far, we're done */
|
||||
return 0;
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/**
|
||||
* pcmcia_init_one - attach a PCMCIA interface
|
||||
* @pdev: pcmcia device
|
||||
|
@ -161,19 +219,11 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
|
|||
struct ata_host *host;
|
||||
struct ata_port *ap;
|
||||
struct ata_pcmcia_info *info;
|
||||
tuple_t tuple;
|
||||
struct {
|
||||
unsigned short buf[128];
|
||||
cisparse_t parse;
|
||||
config_info_t conf;
|
||||
cistpl_cftable_entry_t dflt;
|
||||
} *stk = NULL;
|
||||
cistpl_cftable_entry_t *cfg;
|
||||
int pass, last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p;
|
||||
struct pcmcia_config_check *stk = NULL;
|
||||
int last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p;
|
||||
unsigned long io_base, ctl_base;
|
||||
void __iomem *io_addr, *ctl_addr;
|
||||
int n_ports = 1;
|
||||
|
||||
struct ata_port_operations *ops = &pcmcia_port_ops;
|
||||
|
||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||
|
@ -193,96 +243,27 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
|
|||
pdev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
pdev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
/* Allocate resoure probing structures */
|
||||
|
||||
stk = kzalloc(sizeof(*stk), GFP_KERNEL);
|
||||
if (!stk)
|
||||
goto out1;
|
||||
|
||||
cfg = &stk->parse.cftable_entry;
|
||||
|
||||
/* Tuples we are walking */
|
||||
tuple.TupleData = (cisdata_t *)&stk->buf;
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.TupleDataMax = 255;
|
||||
tuple.Attributes = 0;
|
||||
|
||||
/* See if we have a manufacturer identifier. Use it to set is_kme for
|
||||
vendor quirks */
|
||||
is_kme = ((pdev->manf_id == MANFID_KME) &&
|
||||
((pdev->card_id == PRODID_KME_KXLC005_A) ||
|
||||
(pdev->card_id == PRODID_KME_KXLC005_B)));
|
||||
|
||||
/* Not sure if this is right... look up the current Vcc */
|
||||
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(pdev, &stk->conf));
|
||||
/* link->conf.Vcc = stk->conf.Vcc; */
|
||||
/* Allocate resoure probing structures */
|
||||
|
||||
pass = io_base = ctl_base = 0;
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
tuple.Attributes = 0;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
|
||||
stk = kzalloc(sizeof(*stk), GFP_KERNEL);
|
||||
if (!stk)
|
||||
goto out1;
|
||||
stk->is_kme = is_kme;
|
||||
stk->skip_vcc = io_base = ctl_base = 0;
|
||||
|
||||
/* Now munch the resources looking for a suitable set */
|
||||
while (1) {
|
||||
if (pcmcia_get_tuple_data(pdev, &tuple) != 0)
|
||||
goto next_entry;
|
||||
if (pcmcia_parse_tuple(pdev, &tuple, &stk->parse) != 0)
|
||||
goto next_entry;
|
||||
/* Check for matching Vcc, unless we're desperate */
|
||||
if (!pass) {
|
||||
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
|
||||
goto next_entry;
|
||||
} else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
|
||||
goto next_entry;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
pdev->conf.Vpp = stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
|
||||
if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
|
||||
pdev->conf.ConfigIndex = cfg->index;
|
||||
pdev->io.BasePort1 = io->win[0].base;
|
||||
pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||
if (!(io->flags & CISTPL_IO_16BIT))
|
||||
pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
if (io->nwin == 2) {
|
||||
pdev->io.NumPorts1 = 8;
|
||||
pdev->io.BasePort2 = io->win[1].base;
|
||||
pdev->io.NumPorts2 = (is_kme) ? 2 : 1;
|
||||
if (pcmcia_request_io(pdev, &pdev->io) != 0)
|
||||
goto next_entry;
|
||||
io_base = pdev->io.BasePort1;
|
||||
ctl_base = pdev->io.BasePort2;
|
||||
} else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
|
||||
pdev->io.NumPorts1 = io->win[0].len;
|
||||
pdev->io.NumPorts2 = 0;
|
||||
if (pcmcia_request_io(pdev, &pdev->io) != 0)
|
||||
goto next_entry;
|
||||
io_base = pdev->io.BasePort1;
|
||||
ctl_base = pdev->io.BasePort1 + 0x0e;
|
||||
} else
|
||||
goto next_entry;
|
||||
/* If we've got this far, we're done */
|
||||
break;
|
||||
}
|
||||
next_entry:
|
||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
|
||||
memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
|
||||
if (pass) {
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(pdev, &tuple));
|
||||
} else if (pcmcia_get_next_tuple(pdev, &tuple) != 0) {
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
|
||||
memset(&stk->dflt, 0, sizeof(stk->dflt));
|
||||
pass++;
|
||||
}
|
||||
if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) {
|
||||
stk->skip_vcc = 1;
|
||||
if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk))
|
||||
goto failed; /* No suitable config found */
|
||||
}
|
||||
|
||||
io_base = pdev->io.BasePort1;
|
||||
ctl_base = stk->ctl_base;
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf));
|
||||
|
||||
|
|
|
@ -678,93 +678,70 @@ static void bt3c_detach(struct pcmcia_device *link)
|
|||
kfree(info);
|
||||
}
|
||||
|
||||
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
||||
static int bt3c_check_config(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cf,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
int i;
|
||||
unsigned long try = (unsigned long) priv_data;
|
||||
|
||||
i = pcmcia_get_tuple_data(handle, tuple);
|
||||
if (i != CS_SUCCESS)
|
||||
return i;
|
||||
|
||||
return pcmcia_parse_tuple(handle, tuple, parse);
|
||||
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
|
||||
(cf->io.win[0].base != 0)) {
|
||||
p_dev->io.BasePort1 = cf->io.win[0].base;
|
||||
p_dev->io.IOAddrLines = (try == 0) ? 16 :
|
||||
cf->io.flags & CISTPL_IO_LINES_MASK;
|
||||
if (!pcmcia_request_io(p_dev, &p_dev->io))
|
||||
return 0;
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
||||
static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cf,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS)
|
||||
return CS_NO_MORE_ITEMS;
|
||||
return get_tuple(handle, tuple, parse);
|
||||
}
|
||||
static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
|
||||
int j;
|
||||
|
||||
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
||||
{
|
||||
if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
|
||||
return CS_NO_MORE_ITEMS;
|
||||
return get_tuple(handle, tuple, parse);
|
||||
if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
|
||||
for (j = 0; j < 5; j++) {
|
||||
p_dev->io.BasePort1 = base[j];
|
||||
p_dev->io.IOAddrLines = base[j] ? 16 : 3;
|
||||
if (!pcmcia_request_io(p_dev, &p_dev->io))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int bt3c_config(struct pcmcia_device *link)
|
||||
{
|
||||
static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
|
||||
bt3c_info_t *info = link->priv;
|
||||
tuple_t tuple;
|
||||
u_short buf[256];
|
||||
cisparse_t parse;
|
||||
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
|
||||
int i, j, try;
|
||||
int i;
|
||||
unsigned long try;
|
||||
|
||||
/* First pass: look for a config entry that looks normal. */
|
||||
tuple.TupleData = (cisdata_t *)buf;
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.TupleDataMax = 255;
|
||||
tuple.Attributes = 0;
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
/* Two tries: without IO aliases, then with aliases */
|
||||
for (try = 0; try < 2; try++) {
|
||||
i = first_tuple(link, &tuple, &parse);
|
||||
while (i != CS_NO_MORE_ITEMS) {
|
||||
if (i != CS_SUCCESS)
|
||||
goto next_entry;
|
||||
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
|
||||
link->conf.ConfigIndex = cf->index;
|
||||
link->io.BasePort1 = cf->io.win[0].base;
|
||||
link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS)
|
||||
goto found_port;
|
||||
}
|
||||
next_entry:
|
||||
i = next_tuple(link, &tuple, &parse);
|
||||
}
|
||||
}
|
||||
/* First pass: look for a config entry that looks normal.
|
||||
Two tries: without IO aliases, then with aliases */
|
||||
for (try = 0; try < 2; try++)
|
||||
if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))
|
||||
goto found_port;
|
||||
|
||||
/* Second pass: try to find an entry that isn't picky about
|
||||
its base address, then try to grab any standard serial port
|
||||
address, and finally try to get any free port. */
|
||||
i = first_tuple(link, &tuple, &parse);
|
||||
while (i != CS_NO_MORE_ITEMS) {
|
||||
if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
|
||||
link->conf.ConfigIndex = cf->index;
|
||||
for (j = 0; j < 5; j++) {
|
||||
link->io.BasePort1 = base[j];
|
||||
link->io.IOAddrLines = base[j] ? 16 : 3;
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS)
|
||||
goto found_port;
|
||||
}
|
||||
}
|
||||
i = next_tuple(link, &tuple, &parse);
|
||||
}
|
||||
if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))
|
||||
goto found_port;
|
||||
|
||||
BT_ERR("No usable port range found");
|
||||
cs_error(link, RequestIO, -ENODEV);
|
||||
goto failed;
|
||||
|
||||
found_port:
|
||||
if (i != CS_SUCCESS) {
|
||||
BT_ERR("No usable port range found");
|
||||
cs_error(link, RequestIO, i);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != CS_SUCCESS) {
|
||||
cs_error(link, RequestIRQ, i);
|
||||
|
|
|
@ -607,94 +607,70 @@ static void btuart_detach(struct pcmcia_device *link)
|
|||
kfree(info);
|
||||
}
|
||||
|
||||
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
||||
static int btuart_check_config(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cf,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
int i;
|
||||
int *try = priv_data;
|
||||
|
||||
i = pcmcia_get_tuple_data(handle, tuple);
|
||||
if (i != CS_SUCCESS)
|
||||
return i;
|
||||
|
||||
return pcmcia_parse_tuple(handle, tuple, parse);
|
||||
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) &&
|
||||
(cf->io.win[0].base != 0)) {
|
||||
p_dev->io.BasePort1 = cf->io.win[0].base;
|
||||
p_dev->io.IOAddrLines = (*try == 0) ? 16 :
|
||||
cf->io.flags & CISTPL_IO_LINES_MASK;
|
||||
if (!pcmcia_request_io(p_dev, &p_dev->io))
|
||||
return 0;
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
||||
static int btuart_check_config_notpicky(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cf,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS)
|
||||
return CS_NO_MORE_ITEMS;
|
||||
return get_tuple(handle, tuple, parse);
|
||||
}
|
||||
static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
|
||||
int j;
|
||||
|
||||
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
||||
{
|
||||
if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
|
||||
return CS_NO_MORE_ITEMS;
|
||||
return get_tuple(handle, tuple, parse);
|
||||
if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
|
||||
for (j = 0; j < 5; j++) {
|
||||
p_dev->io.BasePort1 = base[j];
|
||||
p_dev->io.IOAddrLines = base[j] ? 16 : 3;
|
||||
if (!pcmcia_request_io(p_dev, &p_dev->io))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int btuart_config(struct pcmcia_device *link)
|
||||
{
|
||||
static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
|
||||
btuart_info_t *info = link->priv;
|
||||
tuple_t tuple;
|
||||
u_short buf[256];
|
||||
cisparse_t parse;
|
||||
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
|
||||
int i, j, try;
|
||||
int i;
|
||||
int try;
|
||||
|
||||
/* First pass: look for a config entry that looks normal. */
|
||||
tuple.TupleData = (cisdata_t *) buf;
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.TupleDataMax = 255;
|
||||
tuple.Attributes = 0;
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
/* Two tries: without IO aliases, then with aliases */
|
||||
for (try = 0; try < 2; try++) {
|
||||
i = first_tuple(link, &tuple, &parse);
|
||||
while (i != CS_NO_MORE_ITEMS) {
|
||||
if (i != CS_SUCCESS)
|
||||
goto next_entry;
|
||||
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
|
||||
link->conf.ConfigIndex = cf->index;
|
||||
link->io.BasePort1 = cf->io.win[0].base;
|
||||
link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS)
|
||||
goto found_port;
|
||||
}
|
||||
next_entry:
|
||||
i = next_tuple(link, &tuple, &parse);
|
||||
}
|
||||
}
|
||||
/* First pass: look for a config entry that looks normal.
|
||||
Two tries: without IO aliases, then with aliases */
|
||||
for (try = 0; try < 2; try++)
|
||||
if (!pcmcia_loop_config(link, btuart_check_config, &try))
|
||||
goto found_port;
|
||||
|
||||
/* Second pass: try to find an entry that isn't picky about
|
||||
its base address, then try to grab any standard serial port
|
||||
address, and finally try to get any free port. */
|
||||
i = first_tuple(link, &tuple, &parse);
|
||||
while (i != CS_NO_MORE_ITEMS) {
|
||||
if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
|
||||
&& ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
|
||||
link->conf.ConfigIndex = cf->index;
|
||||
for (j = 0; j < 5; j++) {
|
||||
link->io.BasePort1 = base[j];
|
||||
link->io.IOAddrLines = base[j] ? 16 : 3;
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS)
|
||||
goto found_port;
|
||||
}
|
||||
}
|
||||
i = next_tuple(link, &tuple, &parse);
|
||||
}
|
||||
if (!pcmcia_loop_config(link, btuart_check_config_notpicky, NULL))
|
||||
goto found_port;
|
||||
|
||||
BT_ERR("No usable port range found");
|
||||
cs_error(link, RequestIO, -ENODEV);
|
||||
goto failed;
|
||||
|
||||
found_port:
|
||||
if (i != CS_SUCCESS) {
|
||||
BT_ERR("No usable port range found");
|
||||
cs_error(link, RequestIO, i);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != CS_SUCCESS) {
|
||||
cs_error(link, RequestIRQ, i);
|
||||
|
|
|
@ -590,66 +590,31 @@ static void dtl1_detach(struct pcmcia_device *link)
|
|||
kfree(info);
|
||||
}
|
||||
|
||||
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
||||
static int dtl1_confcheck(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cf,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = pcmcia_get_tuple_data(handle, tuple);
|
||||
if (i != CS_SUCCESS)
|
||||
return i;
|
||||
|
||||
return pcmcia_parse_tuple(handle, tuple, parse);
|
||||
}
|
||||
|
||||
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
||||
{
|
||||
if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS)
|
||||
return CS_NO_MORE_ITEMS;
|
||||
return get_tuple(handle, tuple, parse);
|
||||
}
|
||||
|
||||
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
||||
{
|
||||
if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
|
||||
return CS_NO_MORE_ITEMS;
|
||||
return get_tuple(handle, tuple, parse);
|
||||
if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
|
||||
p_dev->io.BasePort1 = cf->io.win[0].base;
|
||||
p_dev->io.NumPorts1 = cf->io.win[0].len; /*yo */
|
||||
p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
|
||||
if (!pcmcia_request_io(p_dev, &p_dev->io))
|
||||
return 0;
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int dtl1_config(struct pcmcia_device *link)
|
||||
{
|
||||
dtl1_info_t *info = link->priv;
|
||||
tuple_t tuple;
|
||||
u_short buf[256];
|
||||
cisparse_t parse;
|
||||
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
|
||||
int i;
|
||||
|
||||
tuple.TupleData = (cisdata_t *)buf;
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.TupleDataMax = 255;
|
||||
tuple.Attributes = 0;
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
|
||||
/* Look for a generic full-sized window */
|
||||
link->io.NumPorts1 = 8;
|
||||
i = first_tuple(link, &tuple, &parse);
|
||||
while (i != CS_NO_MORE_ITEMS) {
|
||||
if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
|
||||
link->conf.ConfigIndex = cf->index;
|
||||
link->io.BasePort1 = cf->io.win[0].base;
|
||||
link->io.NumPorts1 = cf->io.win[0].len; /*yo */
|
||||
link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS)
|
||||
break;
|
||||
}
|
||||
i = next_tuple(link, &tuple, &parse);
|
||||
}
|
||||
|
||||
if (i != CS_SUCCESS) {
|
||||
cs_error(link, RequestIO, i);
|
||||
if (!pcmcia_loop_config(link, dtl1_confcheck, NULL))
|
||||
goto failed;
|
||||
}
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != CS_SUCCESS) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
dev_printk(KERN_INFO, &handle_to_dev(link),
|
||||
"pcmcia_request_configuration failed 0x%x\n",
|
||||
fail_rc);
|
||||
|
|
|
@ -220,103 +220,91 @@ out_release:
|
|||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
struct pcmcia_config_check {
|
||||
unsigned long ctl_base;
|
||||
int skip_vcc;
|
||||
int is_kme;
|
||||
};
|
||||
|
||||
static int pcmcia_check_one_config(struct pcmcia_device *pdev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
struct pcmcia_config_check *stk = priv_data;
|
||||
|
||||
/* Check for matching Vcc, unless we're desperate */
|
||||
if (!stk->skip_vcc) {
|
||||
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
|
||||
return -ENODEV;
|
||||
} else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
|
||||
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
|
||||
pdev->conf.ConfigIndex = cfg->index;
|
||||
pdev->io.BasePort1 = io->win[0].base;
|
||||
pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||
if (!(io->flags & CISTPL_IO_16BIT))
|
||||
pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
if (io->nwin == 2) {
|
||||
pdev->io.NumPorts1 = 8;
|
||||
pdev->io.BasePort2 = io->win[1].base;
|
||||
pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1;
|
||||
if (pcmcia_request_io(pdev, &pdev->io) != 0)
|
||||
return -ENODEV;
|
||||
stk->ctl_base = pdev->io.BasePort2;
|
||||
} else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
|
||||
pdev->io.NumPorts1 = io->win[0].len;
|
||||
pdev->io.NumPorts2 = 0;
|
||||
if (pcmcia_request_io(pdev, &pdev->io) != 0)
|
||||
return -ENODEV;
|
||||
stk->ctl_base = pdev->io.BasePort1 + 0x0e;
|
||||
} else
|
||||
return -ENODEV;
|
||||
/* If we've got this far, we're done */
|
||||
return 0;
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int ide_config(struct pcmcia_device *link)
|
||||
{
|
||||
ide_info_t *info = link->priv;
|
||||
tuple_t tuple;
|
||||
struct {
|
||||
u_short buf[128];
|
||||
cisparse_t parse;
|
||||
config_info_t conf;
|
||||
cistpl_cftable_entry_t dflt;
|
||||
} *stk = NULL;
|
||||
cistpl_cftable_entry_t *cfg;
|
||||
int pass, last_ret = 0, last_fn = 0, is_kme = 0;
|
||||
struct pcmcia_config_check *stk = NULL;
|
||||
int last_ret = 0, last_fn = 0, is_kme = 0;
|
||||
unsigned long io_base, ctl_base;
|
||||
struct ide_host *host;
|
||||
|
||||
DEBUG(0, "ide_config(0x%p)\n", link);
|
||||
|
||||
stk = kzalloc(sizeof(*stk), GFP_KERNEL);
|
||||
if (!stk) goto err_mem;
|
||||
cfg = &stk->parse.cftable_entry;
|
||||
|
||||
tuple.TupleData = (cisdata_t *)&stk->buf;
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.TupleDataMax = 255;
|
||||
tuple.Attributes = 0;
|
||||
|
||||
is_kme = ((link->manf_id == MANFID_KME) &&
|
||||
((link->card_id == PRODID_KME_KXLC005_A) ||
|
||||
(link->card_id == PRODID_KME_KXLC005_B)));
|
||||
|
||||
/* Not sure if this is right... look up the current Vcc */
|
||||
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf));
|
||||
stk = kzalloc(sizeof(*stk), GFP_KERNEL);
|
||||
if (!stk)
|
||||
goto err_mem;
|
||||
stk->is_kme = is_kme;
|
||||
stk->skip_vcc = io_base = ctl_base = 0;
|
||||
|
||||
pass = io_base = ctl_base = 0;
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
tuple.Attributes = 0;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
while (1) {
|
||||
if (pcmcia_get_tuple_data(link, &tuple) != 0) goto next_entry;
|
||||
if (pcmcia_parse_tuple(link, &tuple, &stk->parse) != 0) goto next_entry;
|
||||
|
||||
/* Check for matching Vcc, unless we're desperate */
|
||||
if (!pass) {
|
||||
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
|
||||
goto next_entry;
|
||||
} else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
|
||||
goto next_entry;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp =
|
||||
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp =
|
||||
stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
|
||||
if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
|
||||
link->conf.ConfigIndex = cfg->index;
|
||||
link->io.BasePort1 = io->win[0].base;
|
||||
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||
if (!(io->flags & CISTPL_IO_16BIT))
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
if (io->nwin == 2) {
|
||||
link->io.NumPorts1 = 8;
|
||||
link->io.BasePort2 = io->win[1].base;
|
||||
link->io.NumPorts2 = (is_kme) ? 2 : 1;
|
||||
if (pcmcia_request_io(link, &link->io) != 0)
|
||||
goto next_entry;
|
||||
io_base = link->io.BasePort1;
|
||||
ctl_base = link->io.BasePort2;
|
||||
} else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
|
||||
link->io.NumPorts1 = io->win[0].len;
|
||||
link->io.NumPorts2 = 0;
|
||||
if (pcmcia_request_io(link, &link->io) != 0)
|
||||
goto next_entry;
|
||||
io_base = link->io.BasePort1;
|
||||
ctl_base = link->io.BasePort1 + 0x0e;
|
||||
} else goto next_entry;
|
||||
/* If we've got this far, we're done */
|
||||
break;
|
||||
}
|
||||
|
||||
next_entry:
|
||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
|
||||
memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
|
||||
if (pass) {
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
} else if (pcmcia_get_next_tuple(link, &tuple) != 0) {
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
memset(&stk->dflt, 0, sizeof(stk->dflt));
|
||||
pass++;
|
||||
}
|
||||
if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) {
|
||||
stk->skip_vcc = 1;
|
||||
if (pcmcia_loop_config(link, pcmcia_check_one_config, stk))
|
||||
goto failed; /* No suitable config found */
|
||||
}
|
||||
io_base = link->io.BasePort1;
|
||||
ctl_base = stk->ctl_base;
|
||||
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
|
|
@ -154,78 +154,45 @@ static void avmcs_detach(struct pcmcia_device *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
|
||||
cisparse_t *parse)
|
||||
static int avmcs_configcheck(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cf,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
int i = pcmcia_get_tuple_data(handle, tuple);
|
||||
if (i != CS_SUCCESS) return i;
|
||||
return pcmcia_parse_tuple(handle, tuple, parse);
|
||||
}
|
||||
if (cf->io.nwin <= 0)
|
||||
return -ENODEV;
|
||||
|
||||
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
|
||||
cisparse_t *parse)
|
||||
{
|
||||
int i = pcmcia_get_first_tuple(handle, tuple);
|
||||
if (i != CS_SUCCESS) return i;
|
||||
return get_tuple(handle, tuple, parse);
|
||||
}
|
||||
|
||||
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
|
||||
cisparse_t *parse)
|
||||
{
|
||||
int i = pcmcia_get_next_tuple(handle, tuple);
|
||||
if (i != CS_SUCCESS) return i;
|
||||
return get_tuple(handle, tuple, parse);
|
||||
p_dev->io.BasePort1 = cf->io.win[0].base;
|
||||
p_dev->io.NumPorts1 = cf->io.win[0].len;
|
||||
p_dev->io.NumPorts2 = 0;
|
||||
printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
|
||||
p_dev->io.BasePort1,
|
||||
p_dev->io.BasePort1+p_dev->io.NumPorts1-1);
|
||||
return pcmcia_request_io(p_dev, &p_dev->io);
|
||||
}
|
||||
|
||||
static int avmcs_config(struct pcmcia_device *link)
|
||||
{
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
|
||||
local_info_t *dev;
|
||||
int i;
|
||||
u_char buf[64];
|
||||
char devname[128];
|
||||
int cardtype;
|
||||
int (*addcard)(unsigned int port, unsigned irq);
|
||||
|
||||
dev = link->priv;
|
||||
|
||||
devname[0] = 0;
|
||||
if (link->prod_id[1])
|
||||
strlcpy(devname, link->prod_id[1], sizeof(devname));
|
||||
|
||||
/*
|
||||
* find IO port
|
||||
*/
|
||||
if (pcmcia_loop_config(link, avmcs_configcheck, NULL))
|
||||
return -ENODEV;
|
||||
|
||||
do {
|
||||
devname[0] = 0;
|
||||
if (link->prod_id[1])
|
||||
strlcpy(devname, link->prod_id[1], sizeof(devname));
|
||||
|
||||
/*
|
||||
* find IO port
|
||||
*/
|
||||
tuple.TupleData = (cisdata_t *)buf;
|
||||
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
|
||||
tuple.Attributes = 0;
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
i = first_tuple(link, &tuple, &parse);
|
||||
while (i == CS_SUCCESS) {
|
||||
if (cf->io.nwin > 0) {
|
||||
link->conf.ConfigIndex = cf->index;
|
||||
link->io.BasePort1 = cf->io.win[0].base;
|
||||
link->io.NumPorts1 = cf->io.win[0].len;
|
||||
link->io.NumPorts2 = 0;
|
||||
printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
|
||||
link->io.BasePort1,
|
||||
link->io.BasePort1+link->io.NumPorts1-1);
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS) goto found_port;
|
||||
}
|
||||
i = next_tuple(link, &tuple, &parse);
|
||||
}
|
||||
|
||||
found_port:
|
||||
if (i != CS_SUCCESS) {
|
||||
cs_error(link, RequestIO, i);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate an interrupt line
|
||||
*/
|
||||
|
|
|
@ -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,40 +205,14 @@ static int avma1cs_config(struct pcmcia_device *link)
|
|||
|
||||
DEBUG(0, "avma1cs_config(0x%p)\n", link);
|
||||
|
||||
devname[0] = 0;
|
||||
if (link->prod_id[1])
|
||||
strlcpy(devname, link->prod_id[1], sizeof(devname));
|
||||
|
||||
if (pcmcia_loop_config(link, avma1cs_configcheck, NULL))
|
||||
return -ENODEV;
|
||||
|
||||
do {
|
||||
devname[0] = 0;
|
||||
if (link->prod_id[1])
|
||||
strlcpy(devname, link->prod_id[1], sizeof(devname));
|
||||
|
||||
/*
|
||||
* find IO port
|
||||
*/
|
||||
tuple.TupleData = (cisdata_t *)buf;
|
||||
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
|
||||
tuple.Attributes = 0;
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
i = first_tuple(link, &tuple, &parse);
|
||||
while (i == CS_SUCCESS) {
|
||||
if (cf->io.nwin > 0) {
|
||||
link->conf.ConfigIndex = cf->index;
|
||||
link->io.BasePort1 = cf->io.win[0].base;
|
||||
link->io.NumPorts1 = cf->io.win[0].len;
|
||||
link->io.NumPorts2 = 0;
|
||||
printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
|
||||
link->io.BasePort1,
|
||||
link->io.BasePort1+link->io.NumPorts1 - 1);
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS) goto found_port;
|
||||
}
|
||||
i = next_tuple(link, &tuple, &parse);
|
||||
}
|
||||
|
||||
found_port:
|
||||
if (i != CS_SUCCESS) {
|
||||
cs_error(link, RequestIO, i);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate an interrupt line
|
||||
*/
|
||||
|
|
|
@ -203,68 +203,41 @@ 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);
|
||||
}
|
||||
|
||||
i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
|
||||
if (i != CS_SUCCESS) {
|
||||
last_fn = RequestIO;
|
||||
goto cs_failed;
|
||||
|
|
|
@ -217,101 +217,61 @@ static void sedlbauer_detach(struct pcmcia_device *link)
|
|||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int sedlbauer_config(struct pcmcia_device *link)
|
||||
static int sedlbauer_config_check(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
local_info_t *dev = link->priv;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
int last_fn, last_ret;
|
||||
u8 buf[64];
|
||||
config_info_t conf;
|
||||
win_req_t req;
|
||||
memreq_t map;
|
||||
IsdnCard_t icard;
|
||||
win_req_t *req = priv_data;
|
||||
|
||||
DEBUG(0, "sedlbauer_config(0x%p)\n", link);
|
||||
if (cfg->index == 0)
|
||||
return -ENODEV;
|
||||
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
|
||||
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));
|
||||
|
||||
/*
|
||||
In this loop, we scan the CIS for configuration table entries,
|
||||
each of which describes a valid card configuration, including
|
||||
voltage, IO window, memory window, and interrupt settings.
|
||||
|
||||
We make no assumptions about the card to be configured: we use
|
||||
just the information available in the CIS. In an ideal world,
|
||||
this would work for any PCMCIA card, but it requires a complete
|
||||
and accurate CIS. In practice, a driver usually "knows" most of
|
||||
these things without consulting the CIS, and most client drivers
|
||||
will only use the CIS to fill in implementation-defined details.
|
||||
*/
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
while (1) {
|
||||
cistpl_cftable_entry_t dflt = { 0 };
|
||||
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
|
||||
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
|
||||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
|
||||
goto next_entry;
|
||||
|
||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
|
||||
if (cfg->index == 0) goto next_entry;
|
||||
link->conf.ConfigIndex = cfg->index;
|
||||
|
||||
/* Does this card need audio output? */
|
||||
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
|
||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
link->conf.Status = CCSR_AUDIO_ENA;
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
p_dev->conf.Status = CCSR_AUDIO_ENA;
|
||||
}
|
||||
|
||||
|
||||
/* Use power settings for Vcc and Vpp if present */
|
||||
/* Note that the CIS values need to be rescaled */
|
||||
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
|
||||
if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
|
||||
goto next_entry;
|
||||
} else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
|
||||
if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000)
|
||||
goto next_entry;
|
||||
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
|
||||
return -ENODEV;
|
||||
} else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) {
|
||||
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM]/10000)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp =
|
||||
cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp =
|
||||
dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
|
||||
p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
|
||||
p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
|
||||
link->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
link->io.NumPorts1 = link->io.NumPorts2 = 0;
|
||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
if (!(io->flags & CISTPL_IO_8BIT))
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||
if (!(io->flags & CISTPL_IO_16BIT))
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
/* new in dummy.cs 2001/01/28 MN
|
||||
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||
*/
|
||||
link->io.BasePort1 = io->win[0].base;
|
||||
link->io.NumPorts1 = io->win[0].len;
|
||||
if (io->nwin > 1) {
|
||||
link->io.Attributes2 = link->io.Attributes1;
|
||||
link->io.BasePort2 = io->win[1].base;
|
||||
link->io.NumPorts2 = io->win[1].len;
|
||||
}
|
||||
/* This reserves IO space but doesn't actually enable it */
|
||||
if (pcmcia_request_io(link, &link->io) != 0)
|
||||
goto next_entry;
|
||||
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
|
||||
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
if (!(io->flags & CISTPL_IO_8BIT))
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||
if (!(io->flags & CISTPL_IO_16BIT))
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
p_dev->io.BasePort1 = io->win[0].base;
|
||||
p_dev->io.NumPorts1 = io->win[0].len;
|
||||
if (io->nwin > 1) {
|
||||
p_dev->io.Attributes2 = p_dev->io.Attributes1;
|
||||
p_dev->io.BasePort2 = io->win[1].base;
|
||||
p_dev->io.NumPorts2 = io->win[1].len;
|
||||
}
|
||||
/* This reserves IO space but doesn't actually enable it */
|
||||
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -325,30 +285,54 @@ static int sedlbauer_config(struct pcmcia_device *link)
|
|||
needs to be mapped to virtual space with ioremap() before it
|
||||
is used.
|
||||
*/
|
||||
if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
|
||||
cistpl_mem_t *mem =
|
||||
(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
|
||||
req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
|
||||
req.Attributes |= WIN_ENABLE;
|
||||
req.Base = mem->win[0].host_addr;
|
||||
req.Size = mem->win[0].len;
|
||||
/* new in dummy.cs 2001/01/28 MN
|
||||
if (req.Size < 0x1000)
|
||||
req.Size = 0x1000;
|
||||
*/
|
||||
req.AccessSpeed = 0;
|
||||
if (pcmcia_request_window(&link, &req, &link->win) != 0)
|
||||
goto next_entry;
|
||||
map.Page = 0; map.CardOffset = mem->win[0].card_addr;
|
||||
if (pcmcia_map_mem_page(link->win, &map) != 0)
|
||||
goto next_entry;
|
||||
if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
|
||||
cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
|
||||
memreq_t map;
|
||||
req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
|
||||
req->Attributes |= WIN_ENABLE;
|
||||
req->Base = mem->win[0].host_addr;
|
||||
req->Size = mem->win[0].len;
|
||||
req->AccessSpeed = 0;
|
||||
if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
|
||||
return -ENODEV;
|
||||
map.Page = 0;
|
||||
map.CardOffset = mem->win[0].card_addr;
|
||||
if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
|
||||
return -ENODEV;
|
||||
}
|
||||
/* If we got this far, we're cool! */
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
next_entry:
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
}
|
||||
|
||||
|
||||
static int sedlbauer_config(struct pcmcia_device *link)
|
||||
{
|
||||
local_info_t *dev = link->priv;
|
||||
win_req_t *req;
|
||||
int last_fn, last_ret;
|
||||
IsdnCard_t icard;
|
||||
|
||||
DEBUG(0, "sedlbauer_config(0x%p)\n", link);
|
||||
|
||||
req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
In this loop, we scan the CIS for configuration table entries,
|
||||
each of which describes a valid card configuration, including
|
||||
voltage, IO window, memory window, and interrupt settings.
|
||||
|
||||
We make no assumptions about the card to be configured: we use
|
||||
just the information available in the CIS. In an ideal world,
|
||||
this would work for any PCMCIA card, but it requires a complete
|
||||
and accurate CIS. In practice, a driver usually "knows" most of
|
||||
these things without consulting the CIS, and most client drivers
|
||||
will only use the CIS to fill in implementation-defined details.
|
||||
*/
|
||||
last_ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
|
||||
if (last_ret)
|
||||
goto failed;
|
||||
|
||||
/*
|
||||
Allocate an interrupt line. Note that this does not assign a
|
||||
|
@ -387,8 +371,8 @@ static int sedlbauer_config(struct pcmcia_device *link)
|
|||
printk(" & 0x%04x-0x%04x", link->io.BasePort2,
|
||||
link->io.BasePort2+link->io.NumPorts2-1);
|
||||
if (link->win)
|
||||
printk(", mem 0x%06lx-0x%06lx", req.Base,
|
||||
req.Base+req.Size-1);
|
||||
printk(", mem 0x%06lx-0x%06lx", req->Base,
|
||||
req->Base+req->Size-1);
|
||||
printk("\n");
|
||||
|
||||
icard.para[0] = link->irq.AssignedIRQ;
|
||||
|
@ -409,6 +393,7 @@ static int sedlbauer_config(struct pcmcia_device *link)
|
|||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
sedlbauer_release(link);
|
||||
return -ENODEV;
|
||||
|
||||
|
|
|
@ -193,68 +193,41 @@ 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);
|
||||
}
|
||||
|
||||
i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
|
||||
if (i != CS_SUCCESS) {
|
||||
last_fn = RequestIO;
|
||||
goto cs_failed;
|
||||
|
|
|
@ -284,58 +284,49 @@ static int try_io_port(struct pcmcia_device *link)
|
|||
}
|
||||
}
|
||||
|
||||
static int axnet_configcheck(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
int i;
|
||||
cistpl_io_t *io = &cfg->io;
|
||||
|
||||
if (cfg->index == 0 || cfg->io.nwin == 0)
|
||||
return -ENODEV;
|
||||
|
||||
p_dev->conf.ConfigIndex = 0x05;
|
||||
/* For multifunction cards, by convention, we configure the
|
||||
network function with window 0, and serial with window 1 */
|
||||
if (io->nwin > 1) {
|
||||
i = (io->win[1].len > io->win[0].len);
|
||||
p_dev->io.BasePort2 = io->win[1-i].base;
|
||||
p_dev->io.NumPorts2 = io->win[1-i].len;
|
||||
} else {
|
||||
i = p_dev->io.NumPorts2 = 0;
|
||||
}
|
||||
p_dev->io.BasePort1 = io->win[i].base;
|
||||
p_dev->io.NumPorts1 = io->win[i].len;
|
||||
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||
if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
|
||||
return try_io_port(p_dev);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int axnet_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
axnet_dev_t *info = PRIV(dev);
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
int i, j, last_ret, last_fn;
|
||||
u_short buf[64];
|
||||
DECLARE_MAC_BUF(mac);
|
||||
|
||||
DEBUG(0, "axnet_config(0x%p)\n", link);
|
||||
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = (cisdata_t *)buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
|
||||
/* don't trust the CIS on this; Linksys got it wrong */
|
||||
link->conf.Present = 0x63;
|
||||
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
tuple.Attributes = 0;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
while (last_ret == CS_SUCCESS) {
|
||||
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
|
||||
cistpl_io_t *io = &(parse.cftable_entry.io);
|
||||
|
||||
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
|
||||
pcmcia_parse_tuple(link, &tuple, &parse) != 0 ||
|
||||
cfg->index == 0 || cfg->io.nwin == 0)
|
||||
goto next_entry;
|
||||
|
||||
link->conf.ConfigIndex = 0x05;
|
||||
/* For multifunction cards, by convention, we configure the
|
||||
network function with window 0, and serial with window 1 */
|
||||
if (io->nwin > 1) {
|
||||
i = (io->win[1].len > io->win[0].len);
|
||||
link->io.BasePort2 = io->win[1-i].base;
|
||||
link->io.NumPorts2 = io->win[1-i].len;
|
||||
} else {
|
||||
i = link->io.NumPorts2 = 0;
|
||||
}
|
||||
link->io.BasePort1 = io->win[i].base;
|
||||
link->io.NumPorts1 = io->win[i].len;
|
||||
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||
if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
|
||||
last_ret = try_io_port(link);
|
||||
if (last_ret == CS_SUCCESS) break;
|
||||
}
|
||||
next_entry:
|
||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
||||
}
|
||||
last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
|
||||
if (last_ret != CS_SUCCESS) {
|
||||
cs_error(link, RequestIO, last_ret);
|
||||
goto failed;
|
||||
|
|
|
@ -512,58 +512,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;
|
||||
}
|
||||
|
|
|
@ -459,28 +459,37 @@ 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;
|
||||
|
||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
link->conf.Status = CCSR_AUDIO_ENA;
|
||||
link->irq.Attributes =
|
||||
|
@ -489,27 +498,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;
|
||||
|
||||
|
@ -533,7 +524,7 @@ static int mhz_mfc_config(struct pcmcia_device *link)
|
|||
|
||||
free_cfg_mem:
|
||||
kfree(cfg_mem);
|
||||
return i;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int mhz_setup(struct pcmcia_device *link)
|
||||
|
@ -660,46 +651,27 @@ static int mot_setup(struct pcmcia_device *link)
|
|||
|
||||
/*====================================================================*/
|
||||
|
||||
static int smc_configcheck(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cf,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
p_dev->io.BasePort1 = cf->io.win[0].base;
|
||||
p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
|
||||
return pcmcia_request_io(p_dev, &p_dev->io);
|
||||
}
|
||||
|
||||
static int smc_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_cfg_mem *cfg_mem;
|
||||
tuple_t *tuple;
|
||||
cisparse_t *parse;
|
||||
cistpl_cftable_entry_t *cf;
|
||||
u_char *buf;
|
||||
int i;
|
||||
|
||||
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
|
||||
if (!cfg_mem)
|
||||
return CS_OUT_OF_RESOURCE;
|
||||
|
||||
tuple = &cfg_mem->tuple;
|
||||
parse = &cfg_mem->parse;
|
||||
cf = &parse->cftable_entry;
|
||||
buf = cfg_mem->buf;
|
||||
|
||||
tuple->Attributes = tuple->TupleOffset = 0;
|
||||
tuple->TupleData = (cisdata_t *)buf;
|
||||
tuple->TupleDataMax = 255;
|
||||
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
|
||||
link->io.NumPorts1 = 16;
|
||||
i = first_tuple(link, tuple, parse);
|
||||
while (i != CS_NO_MORE_ITEMS) {
|
||||
if (i == CS_SUCCESS) {
|
||||
link->conf.ConfigIndex = cf->index;
|
||||
link->io.BasePort1 = cf->io.win[0].base;
|
||||
link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS) break;
|
||||
}
|
||||
i = next_tuple(link, tuple, parse);
|
||||
}
|
||||
if (i == CS_SUCCESS)
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
i = pcmcia_loop_config(link, smc_configcheck, NULL);
|
||||
if (!i)
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
kfree(cfg_mem);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
|
@ -715,6 +715,47 @@ has_ce2_string(struct pcmcia_device * p_dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xirc2ps_config_modem(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cf,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
unsigned int ioaddr;
|
||||
|
||||
if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
|
||||
for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
|
||||
p_dev->io.BasePort2 = cf->io.win[0].base;
|
||||
p_dev->io.BasePort1 = ioaddr;
|
||||
if (!pcmcia_request_io(p_dev, &p_dev->io))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int
|
||||
xirc2ps_config_check(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cf,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
int *pass = priv_data;
|
||||
|
||||
if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
|
||||
p_dev->io.BasePort2 = cf->io.win[0].base;
|
||||
p_dev->io.BasePort1 = p_dev->io.BasePort2
|
||||
+ (*pass ? (cf->index & 0x20 ? -24:8)
|
||||
: (cf->index & 0x20 ? 8:-24));
|
||||
if (!pcmcia_request_io(p_dev, &p_dev->io))
|
||||
return 0;
|
||||
}
|
||||
return -ENODEV;
|
||||
|
||||
}
|
||||
|
||||
/****************
|
||||
* xirc2ps_config() is scheduled to run after a CARD_INSERTION event
|
||||
* is received, to configure the PCMCIA socket, and to make the
|
||||
|
@ -725,13 +766,12 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
{
|
||||
struct net_device *dev = link->priv;
|
||||
local_info_t *local = netdev_priv(dev);
|
||||
unsigned int ioaddr;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
unsigned int ioaddr;
|
||||
int err, i;
|
||||
u_char buf[64];
|
||||
cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
|
||||
cistpl_cftable_entry_t *cf = &parse.cftable_entry;
|
||||
DECLARE_MAC_BUF(mac);
|
||||
|
||||
local->dingo_ccr = NULL;
|
||||
|
@ -846,19 +886,8 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
/* Take the Modem IO port from the CIS and scan for a free
|
||||
* Ethernet port */
|
||||
link->io.NumPorts1 = 16; /* no Mako stuff anymore */
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
for (err = first_tuple(link, &tuple, &parse); !err;
|
||||
err = next_tuple(link, &tuple, &parse)) {
|
||||
if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
|
||||
for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
|
||||
link->conf.ConfigIndex = cf->index ;
|
||||
link->io.BasePort2 = cf->io.win[0].base;
|
||||
link->io.BasePort1 = ioaddr;
|
||||
if (!(err=pcmcia_request_io(link, &link->io)))
|
||||
goto port_found;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL))
|
||||
goto port_found;
|
||||
} else {
|
||||
link->io.NumPorts1 = 18;
|
||||
/* We do 2 passes here: The first one uses the regular mapping and
|
||||
|
@ -866,21 +895,9 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
* mirrored every 32 bytes. Actually we use a mirrored port for
|
||||
* the Mako if (on the first pass) the COR bit 5 is set.
|
||||
*/
|
||||
for (pass=0; pass < 2; pass++) {
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
for (err = first_tuple(link, &tuple, &parse); !err;
|
||||
err = next_tuple(link, &tuple, &parse)){
|
||||
if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8){
|
||||
link->conf.ConfigIndex = cf->index ;
|
||||
link->io.BasePort2 = cf->io.win[0].base;
|
||||
link->io.BasePort1 = link->io.BasePort2
|
||||
+ (pass ? (cf->index & 0x20 ? -24:8)
|
||||
: (cf->index & 0x20 ? 8:-24));
|
||||
if (!(err=pcmcia_request_io(link, &link->io)))
|
||||
for (pass=0; pass < 2; pass++)
|
||||
if (!pcmcia_loop_config(link, xirc2ps_config_check, &pass))
|
||||
goto port_found;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* if special option:
|
||||
* try to configure as Ethernet only.
|
||||
* .... */
|
||||
|
|
|
@ -206,126 +206,123 @@ static void airo_detach(struct pcmcia_device *link)
|
|||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int airo_cs_config_check(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
win_req_t *req = priv_data;
|
||||
|
||||
if (cfg->index == 0)
|
||||
return -ENODEV;
|
||||
|
||||
/* Does this card need audio output? */
|
||||
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
p_dev->conf.Status = CCSR_AUDIO_ENA;
|
||||
}
|
||||
|
||||
/* Use power settings for Vcc and Vpp if present */
|
||||
/* Note that the CIS values need to be rescaled */
|
||||
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
|
||||
p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
|
||||
p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
|
||||
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
if (!(io->flags & CISTPL_IO_8BIT))
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||
if (!(io->flags & CISTPL_IO_16BIT))
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
p_dev->io.BasePort1 = io->win[0].base;
|
||||
p_dev->io.NumPorts1 = io->win[0].len;
|
||||
if (io->nwin > 1) {
|
||||
p_dev->io.Attributes2 = p_dev->io.Attributes1;
|
||||
p_dev->io.BasePort2 = io->win[1].base;
|
||||
p_dev->io.NumPorts2 = io->win[1].len;
|
||||
}
|
||||
}
|
||||
|
||||
/* This reserves IO space but doesn't actually enable it */
|
||||
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
Now set up a common memory window, if needed. There is room
|
||||
in the struct pcmcia_device structure for one memory window handle,
|
||||
but if the base addresses need to be saved, or if multiple
|
||||
windows are needed, the info should go in the private data
|
||||
structure for this device.
|
||||
|
||||
Note that the memory window base is a physical address, and
|
||||
needs to be mapped to virtual space with ioremap() before it
|
||||
is used.
|
||||
*/
|
||||
if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
|
||||
cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
|
||||
memreq_t map;
|
||||
req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
|
||||
req->Base = mem->win[0].host_addr;
|
||||
req->Size = mem->win[0].len;
|
||||
req->AccessSpeed = 0;
|
||||
if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
|
||||
return -ENODEV;
|
||||
map.Page = 0;
|
||||
map.CardOffset = mem->win[0].card_addr;
|
||||
if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
|
||||
return -ENODEV;
|
||||
}
|
||||
/* If we got this far, we're cool! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int airo_config(struct pcmcia_device *link)
|
||||
{
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
local_info_t *dev;
|
||||
win_req_t *req;
|
||||
int last_fn, last_ret;
|
||||
u_char buf[64];
|
||||
win_req_t req;
|
||||
memreq_t map;
|
||||
|
||||
dev = link->priv;
|
||||
|
||||
DEBUG(0, "airo_config(0x%p)\n", link);
|
||||
|
||||
req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
In this loop, we scan the CIS for configuration table entries,
|
||||
each of which describes a valid card configuration, including
|
||||
voltage, IO window, memory window, and interrupt settings.
|
||||
|
||||
We make no assumptions about the card to be configured: we use
|
||||
just the information available in the CIS. In an ideal world,
|
||||
this would work for any PCMCIA card, but it requires a complete
|
||||
and accurate CIS. In practice, a driver usually "knows" most of
|
||||
these things without consulting the CIS, and most client drivers
|
||||
will only use the CIS to fill in implementation-defined details.
|
||||
* In this loop, we scan the CIS for configuration table
|
||||
* entries, each of which describes a valid card
|
||||
* configuration, including voltage, IO window, memory window,
|
||||
* and interrupt settings.
|
||||
*
|
||||
* We make no assumptions about the card to be configured: we
|
||||
* use just the information available in the CIS. In an ideal
|
||||
* world, this would work for any PCMCIA card, but it requires
|
||||
* a complete and accurate CIS. In practice, a driver usually
|
||||
* "knows" most of these things without consulting the CIS,
|
||||
* and most client drivers will only use the CIS to fill in
|
||||
* implementation-defined details.
|
||||
*/
|
||||
last_ret = pcmcia_loop_config(link, airo_cs_config_check, req);
|
||||
if (last_ret)
|
||||
goto failed;
|
||||
|
||||
/*
|
||||
Allocate an interrupt line. Note that this does not assign a
|
||||
handler to the interrupt, unless the 'Handler' member of the
|
||||
irq structure is initialized.
|
||||
*/
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
while (1) {
|
||||
cistpl_cftable_entry_t dflt = { 0 };
|
||||
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
|
||||
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
|
||||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
|
||||
goto next_entry;
|
||||
|
||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
|
||||
if (cfg->index == 0) goto next_entry;
|
||||
link->conf.ConfigIndex = cfg->index;
|
||||
|
||||
/* Does this card need audio output? */
|
||||
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
|
||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
link->conf.Status = CCSR_AUDIO_ENA;
|
||||
}
|
||||
|
||||
/* Use power settings for Vcc and Vpp if present */
|
||||
/* Note that the CIS values need to be rescaled */
|
||||
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp =
|
||||
cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp =
|
||||
dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
|
||||
link->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
link->io.NumPorts1 = link->io.NumPorts2 = 0;
|
||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
if (!(io->flags & CISTPL_IO_8BIT))
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||
if (!(io->flags & CISTPL_IO_16BIT))
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.BasePort1 = io->win[0].base;
|
||||
link->io.NumPorts1 = io->win[0].len;
|
||||
if (io->nwin > 1) {
|
||||
link->io.Attributes2 = link->io.Attributes1;
|
||||
link->io.BasePort2 = io->win[1].base;
|
||||
link->io.NumPorts2 = io->win[1].len;
|
||||
}
|
||||
}
|
||||
|
||||
/* This reserves IO space but doesn't actually enable it */
|
||||
if (pcmcia_request_io(link, &link->io) != 0)
|
||||
goto next_entry;
|
||||
|
||||
/*
|
||||
Now set up a common memory window, if needed. There is room
|
||||
in the struct pcmcia_device structure for one memory window handle,
|
||||
but if the base addresses need to be saved, or if multiple
|
||||
windows are needed, the info should go in the private data
|
||||
structure for this device.
|
||||
|
||||
Note that the memory window base is a physical address, and
|
||||
needs to be mapped to virtual space with ioremap() before it
|
||||
is used.
|
||||
*/
|
||||
if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
|
||||
cistpl_mem_t *mem =
|
||||
(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
|
||||
req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
|
||||
req.Base = mem->win[0].host_addr;
|
||||
req.Size = mem->win[0].len;
|
||||
req.AccessSpeed = 0;
|
||||
if (pcmcia_request_window(&link, &req, &link->win) != 0)
|
||||
goto next_entry;
|
||||
map.Page = 0; map.CardOffset = mem->win[0].card_addr;
|
||||
if (pcmcia_map_mem_page(link->win, &map) != 0)
|
||||
goto next_entry;
|
||||
}
|
||||
/* If we got this far, we're cool! */
|
||||
break;
|
||||
|
||||
next_entry:
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
}
|
||||
|
||||
/*
|
||||
Allocate an interrupt line. Note that this does not assign a
|
||||
handler to the interrupt, unless the 'Handler' member of the
|
||||
irq structure is initialized.
|
||||
*/
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
|
||||
|
@ -362,14 +359,17 @@ static int airo_config(struct pcmcia_device *link)
|
|||
printk(" & 0x%04x-0x%04x", link->io.BasePort2,
|
||||
link->io.BasePort2+link->io.NumPorts2-1);
|
||||
if (link->win)
|
||||
printk(", mem 0x%06lx-0x%06lx", req.Base,
|
||||
req.Base+req.Size-1);
|
||||
printk(", mem 0x%06lx-0x%06lx", req->Base,
|
||||
req->Base+req->Size-1);
|
||||
printk("\n");
|
||||
kfree(req);
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
airo_release(link);
|
||||
kfree(req);
|
||||
return -ENODEV;
|
||||
} /* airo_config */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -164,6 +164,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)
|
||||
{
|
||||
|
@ -172,16 +236,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
|
||||
|
@ -196,94 +252,14 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||
* and most client drivers will only use the CIS to fill in
|
||||
* implementation-defined details.
|
||||
*/
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
while (1) {
|
||||
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
|
||||
cistpl_cftable_entry_t dflt = { .index = 0 };
|
||||
|
||||
if ( (pcmcia_get_tuple_data(link, &tuple) != 0)
|
||||
|| (pcmcia_parse_tuple(link, &tuple, &parse) != 0))
|
||||
goto next_entry;
|
||||
|
||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
|
||||
dflt = *cfg;
|
||||
if (cfg->index == 0)
|
||||
goto next_entry;
|
||||
link->conf.ConfigIndex = cfg->index;
|
||||
|
||||
/* Use power settings for Vcc and Vpp if present */
|
||||
/* Note that the CIS values need to be rescaled */
|
||||
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
|
||||
DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, cfg CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
|
||||
if (!ignore_cis_vcc)
|
||||
goto next_entry;
|
||||
}
|
||||
} else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
|
||||
DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, dflt CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
|
||||
if(!ignore_cis_vcc)
|
||||
goto next_entry;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp =
|
||||
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp =
|
||||
dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
link->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
link->io.NumPorts1 = link->io.NumPorts2 = 0;
|
||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
||||
cistpl_io_t *io =
|
||||
(cfg->io.nwin) ? &cfg->io : &dflt.io;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
if (!(io->flags & CISTPL_IO_8BIT))
|
||||
link->io.Attributes1 =
|
||||
IO_DATA_PATH_WIDTH_16;
|
||||
if (!(io->flags & CISTPL_IO_16BIT))
|
||||
link->io.Attributes1 =
|
||||
IO_DATA_PATH_WIDTH_8;
|
||||
link->io.IOAddrLines =
|
||||
io->flags & CISTPL_IO_LINES_MASK;
|
||||
link->io.BasePort1 = io->win[0].base;
|
||||
link->io.NumPorts1 = io->win[0].len;
|
||||
if (io->nwin > 1) {
|
||||
link->io.Attributes2 =
|
||||
link->io.Attributes1;
|
||||
link->io.BasePort2 = io->win[1].base;
|
||||
link->io.NumPorts2 = io->win[1].len;
|
||||
}
|
||||
|
||||
/* This reserves IO space but doesn't actually enable it */
|
||||
if (pcmcia_request_io(link, &link->io) != 0)
|
||||
goto next_entry;
|
||||
}
|
||||
|
||||
|
||||
/* If we got this far, we're cool! */
|
||||
|
||||
break;
|
||||
|
||||
next_entry:
|
||||
pcmcia_disable_device(link);
|
||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
||||
if (last_ret == CS_NO_MORE_ITEMS) {
|
||||
last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
|
||||
if (last_ret) {
|
||||
if (!ignore_cis_vcc)
|
||||
printk(KERN_ERR PFX "GetNextTuple(): No matching "
|
||||
"CIS configuration. Maybe you need the "
|
||||
"ignore_cis_vcc=1 parameter.\n");
|
||||
goto cs_failed;
|
||||
}
|
||||
cs_error(link, RequestIO, last_ret);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -334,7 +310,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:
|
||||
|
|
|
@ -633,6 +633,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)
|
||||
{
|
||||
|
@ -641,16 +705,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
|
||||
|
@ -665,94 +721,14 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||
* and most client drivers will only use the CIS to fill in
|
||||
* implementation-defined details.
|
||||
*/
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
while (1) {
|
||||
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
|
||||
cistpl_cftable_entry_t dflt = { .index = 0 };
|
||||
|
||||
if ( (pcmcia_get_tuple_data(link, &tuple) != 0)
|
||||
|| (pcmcia_parse_tuple(link, &tuple, &parse) != 0))
|
||||
goto next_entry;
|
||||
|
||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
|
||||
dflt = *cfg;
|
||||
if (cfg->index == 0)
|
||||
goto next_entry;
|
||||
link->conf.ConfigIndex = cfg->index;
|
||||
|
||||
/* Use power settings for Vcc and Vpp if present */
|
||||
/* Note that the CIS values need to be rescaled */
|
||||
if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
|
||||
DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
|
||||
if (!ignore_cis_vcc)
|
||||
goto next_entry;
|
||||
}
|
||||
} else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
|
||||
DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
|
||||
if(!ignore_cis_vcc)
|
||||
goto next_entry;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp =
|
||||
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp =
|
||||
dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
link->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
link->io.NumPorts1 = link->io.NumPorts2 = 0;
|
||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
||||
cistpl_io_t *io =
|
||||
(cfg->io.nwin) ? &cfg->io : &dflt.io;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
if (!(io->flags & CISTPL_IO_8BIT))
|
||||
link->io.Attributes1 =
|
||||
IO_DATA_PATH_WIDTH_16;
|
||||
if (!(io->flags & CISTPL_IO_16BIT))
|
||||
link->io.Attributes1 =
|
||||
IO_DATA_PATH_WIDTH_8;
|
||||
link->io.IOAddrLines =
|
||||
io->flags & CISTPL_IO_LINES_MASK;
|
||||
link->io.BasePort1 = io->win[0].base;
|
||||
link->io.NumPorts1 = io->win[0].len;
|
||||
if (io->nwin > 1) {
|
||||
link->io.Attributes2 =
|
||||
link->io.Attributes1;
|
||||
link->io.BasePort2 = io->win[1].base;
|
||||
link->io.NumPorts2 = io->win[1].len;
|
||||
}
|
||||
|
||||
/* This reserves IO space but doesn't actually enable it */
|
||||
if (pcmcia_request_io(link, &link->io) != 0)
|
||||
goto next_entry;
|
||||
}
|
||||
|
||||
|
||||
/* If we got this far, we're cool! */
|
||||
|
||||
break;
|
||||
|
||||
next_entry:
|
||||
pcmcia_disable_device(link);
|
||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
||||
if (last_ret == CS_NO_MORE_ITEMS) {
|
||||
last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
|
||||
if (last_ret) {
|
||||
if (!ignore_cis_vcc)
|
||||
printk(KERN_ERR PFX "GetNextTuple(): No matching "
|
||||
"CIS configuration. Maybe you need the "
|
||||
"ignore_cis_vcc=1 parameter.\n");
|
||||
goto cs_failed;
|
||||
}
|
||||
cs_error(link, RequestIO, last_ret);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -149,52 +149,44 @@ static void parport_detach(struct pcmcia_device *link)
|
|||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int parport_config_check(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
|
||||
if (epp_mode)
|
||||
p_dev->conf.ConfigIndex |= FORCE_EPP_MODE;
|
||||
p_dev->io.BasePort1 = io->win[0].base;
|
||||
p_dev->io.NumPorts1 = io->win[0].len;
|
||||
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||
if (io->nwin == 2) {
|
||||
p_dev->io.BasePort2 = io->win[1].base;
|
||||
p_dev->io.NumPorts2 = io->win[1].len;
|
||||
}
|
||||
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int parport_config(struct pcmcia_device *link)
|
||||
{
|
||||
parport_info_t *info = link->priv;
|
||||
tuple_t tuple;
|
||||
u_short buf[128];
|
||||
cisparse_t parse;
|
||||
cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
|
||||
cistpl_cftable_entry_t dflt = { 0 };
|
||||
struct parport *p;
|
||||
int last_ret, last_fn;
|
||||
|
||||
DEBUG(0, "parport_config(0x%p)\n", link);
|
||||
|
||||
tuple.TupleData = (cisdata_t *)buf;
|
||||
tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
tuple.Attributes = 0;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
while (1) {
|
||||
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
|
||||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
|
||||
goto next_entry;
|
||||
|
||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
|
||||
link->conf.ConfigIndex = cfg->index;
|
||||
if (epp_mode)
|
||||
link->conf.ConfigIndex |= FORCE_EPP_MODE;
|
||||
link->io.BasePort1 = io->win[0].base;
|
||||
link->io.NumPorts1 = io->win[0].len;
|
||||
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||
if (io->nwin == 2) {
|
||||
link->io.BasePort2 = io->win[1].base;
|
||||
link->io.NumPorts2 = io->win[1].len;
|
||||
}
|
||||
if (pcmcia_request_io(link, &link->io) != 0)
|
||||
goto next_entry;
|
||||
/* If we've got this far, we're done */
|
||||
break;
|
||||
}
|
||||
|
||||
next_entry:
|
||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
DEBUG(0, "parport_config(0x%p)\n", link);
|
||||
|
||||
last_ret = pcmcia_loop_config(link, parport_config_check, NULL);
|
||||
if (last_ret) {
|
||||
cs_error(link, RequestIO, last_ret);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -508,9 +510,10 @@ static int socket_insert(struct pcmcia_socket *skt)
|
|||
if (ret == CS_SUCCESS) {
|
||||
skt->state |= SOCKET_PRESENT;
|
||||
|
||||
printk(KERN_NOTICE "pccard: %s card inserted into slot %d\n",
|
||||
(skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
|
||||
skt->sock);
|
||||
dev_printk(KERN_NOTICE, &skt->dev,
|
||||
"pccard: %s card inserted into slot %d\n",
|
||||
(skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
|
||||
skt->sock);
|
||||
|
||||
#ifdef CONFIG_CARDBUS
|
||||
if (skt->state & SOCKET_CARDBUS) {
|
||||
|
@ -595,7 +598,8 @@ static int socket_resume(struct pcmcia_socket *skt)
|
|||
|
||||
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;
|
||||
|
|
|
@ -130,15 +130,13 @@ struct pcmcia_callback{
|
|||
|
||||
int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
|
||||
|
||||
#define cs_socket_name(skt) ((skt)->dev.bus_id)
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef CONFIG_PCMCIA_DEBUG
|
||||
extern int cs_debug_level(int);
|
||||
|
||||
#define cs_dbg(skt, lvl, fmt, arg...) do { \
|
||||
if (cs_debug_level(lvl)) \
|
||||
printk(KERN_DEBUG "cs: %s: " fmt, \
|
||||
cs_socket_name(skt) , ## arg); \
|
||||
dev_printk(KERN_DEBUG, &skt->dev, \
|
||||
"cs: " fmt, ## arg); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
@ -146,6 +144,6 @@ extern int cs_debug_level(int);
|
|||
#endif
|
||||
|
||||
#define cs_err(skt, fmt, arg...) \
|
||||
printk(KERN_ERR "cs: %s: " fmt, (skt)->dev.bus_id , ## arg)
|
||||
dev_printk(KERN_ERR, &skt->dev, "cs: " fmt, ## arg)
|
||||
|
||||
#endif /* _LINUX_CS_INTERNAL_H */
|
||||
|
|
|
@ -42,17 +42,22 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
|
|||
MODULE_DESCRIPTION("PCMCIA Driver Services");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef CONFIG_PCMCIA_DEBUG
|
||||
int ds_pc_debug;
|
||||
|
||||
module_param_named(pc_debug, ds_pc_debug, int, 0644);
|
||||
|
||||
#define ds_dbg(lvl, fmt, arg...) do { \
|
||||
if (ds_pc_debug > (lvl)) \
|
||||
if (ds_pc_debug > (lvl)) \
|
||||
printk(KERN_DEBUG "ds: " fmt , ## arg); \
|
||||
} while (0)
|
||||
#define ds_dev_dbg(lvl, dev, fmt, arg...) do { \
|
||||
if (ds_pc_debug > (lvl)) \
|
||||
dev_printk(KERN_DEBUG, dev, "ds: " fmt , ## arg); \
|
||||
} while (0)
|
||||
#else
|
||||
#define ds_dbg(lvl, fmt, arg...) do { } while (0)
|
||||
#define ds_dev_dbg(lvl, dev, fmt, arg...) do { } while (0)
|
||||
#endif
|
||||
|
||||
spinlock_t pcmcia_dev_list_lock;
|
||||
|
@ -391,7 +396,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 +406,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;
|
||||
|
@ -427,8 +432,7 @@ static int pcmcia_device_probe(struct device * dev)
|
|||
p_drv = to_pcmcia_drv(dev->driver);
|
||||
s = p_dev->socket;
|
||||
|
||||
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))) {
|
||||
|
@ -443,15 +447,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;
|
||||
}
|
||||
|
||||
|
@ -485,8 +490,9 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
|
|||
struct pcmcia_device *tmp;
|
||||
unsigned long flags;
|
||||
|
||||
ds_dbg(2, "pcmcia_card_remove(%d) %s\n", s->sock,
|
||||
leftover ? leftover->devname : "");
|
||||
ds_dev_dbg(2, leftover ? &leftover->dev : &s->dev,
|
||||
"pcmcia_card_remove(%d) %s\n", s->sock,
|
||||
leftover ? leftover->devname : "");
|
||||
|
||||
if (!leftover)
|
||||
s->device_count = 0;
|
||||
|
@ -503,7 +509,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);
|
||||
}
|
||||
|
||||
|
@ -520,7 +526,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
|
||||
|
@ -543,13 +549,15 @@ static int pcmcia_device_remove(struct device * dev)
|
|||
|
||||
/* check for proper unloading */
|
||||
if (p_dev->_irq || p_dev->_io || p_dev->_locked)
|
||||
printk(KERN_INFO "pcmcia: driver %s did not release config properly\n",
|
||||
p_drv->drv.name);
|
||||
dev_printk(KERN_INFO, dev,
|
||||
"pcmcia: driver %s did not release config properly\n",
|
||||
p_drv->drv.name);
|
||||
|
||||
for (i = 0; i < MAX_WIN; i++)
|
||||
if (p_dev->_win & CLIENT_WIN_REQ(i))
|
||||
printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n",
|
||||
p_drv->drv.name);
|
||||
dev_printk(KERN_INFO, dev,
|
||||
"pcmcia: driver %s did not release window properly\n",
|
||||
p_drv->drv.name);
|
||||
|
||||
/* references from pcmcia_probe_device */
|
||||
pcmcia_put_dev(p_dev);
|
||||
|
@ -598,8 +606,9 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
|
|||
}
|
||||
if (!pccard_read_tuple(p_dev->socket, p_dev->func,
|
||||
CISTPL_DEVICE_GEO, devgeo)) {
|
||||
ds_dbg(0, "mem device geometry probably means "
|
||||
"FUNCID_MEMORY\n");
|
||||
ds_dev_dbg(0, &p_dev->dev,
|
||||
"mem device geometry probably means "
|
||||
"FUNCID_MEMORY\n");
|
||||
p_dev->func_id = CISTPL_FUNCID_MEMORY;
|
||||
p_dev->has_func_id = 1;
|
||||
}
|
||||
|
@ -680,7 +689,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);
|
||||
|
||||
|
@ -701,7 +710,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)
|
||||
|
@ -709,8 +718,9 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
|
|||
kref_init(&p_dev->function_config->ref);
|
||||
}
|
||||
|
||||
printk(KERN_NOTICE "pcmcia: registering new device %s\n",
|
||||
p_dev->devname);
|
||||
dev_printk(KERN_NOTICE, &p_dev->dev,
|
||||
"pcmcia: registering new device %s\n",
|
||||
p_dev->devname);
|
||||
|
||||
pcmcia_device_query(p_dev);
|
||||
|
||||
|
@ -745,19 +755,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;
|
||||
}
|
||||
|
||||
|
@ -778,7 +789,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;
|
||||
|
@ -788,8 +799,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);
|
||||
}
|
||||
|
||||
|
@ -803,7 +813,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,11 +869,12 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
|
|||
if (!filename)
|
||||
return -EINVAL;
|
||||
|
||||
ds_dbg(1, "trying to load CIS file %s\n", filename);
|
||||
ds_dev_dbg(1, &dev->dev, "trying to load CIS file %s\n", filename);
|
||||
|
||||
if (strlen(filename) > (FIRMWARE_NAME_MAX - 1)) {
|
||||
printk(KERN_WARNING "pcmcia: CIS filename is too long [%s]\n",
|
||||
filename);
|
||||
dev_printk(KERN_WARNING, &dev->dev,
|
||||
"pcmcia: CIS filename is too long [%s]\n",
|
||||
filename);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -872,14 +883,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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -983,14 +996,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);
|
||||
|
||||
|
@ -1022,11 +1035,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;
|
||||
}
|
||||
|
@ -1036,18 +1047,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++;
|
||||
|
@ -1253,7 +1261,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);
|
||||
|
@ -1264,15 +1272,16 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
|
|||
if (p_drv->suspend) {
|
||||
ret = p_drv->suspend(p_dev);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "pcmcia: device %s (driver %s) did "
|
||||
"not want to go to sleep (%d)\n",
|
||||
p_dev->devname, p_drv->drv.name, ret);
|
||||
dev_printk(KERN_ERR, dev,
|
||||
"pcmcia: device %s (driver %s) did "
|
||||
"not want to go to sleep (%d)\n",
|
||||
p_dev->devname, p_drv->drv.name, ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_dev->device_no == p_dev->func) {
|
||||
ds_dbg(2, "releasing configuration for %s\n", dev->bus_id);
|
||||
ds_dev_dbg(2, dev, "releasing configuration\n");
|
||||
pcmcia_release_configuration(p_dev);
|
||||
}
|
||||
|
||||
|
@ -1292,7 +1301,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);
|
||||
|
@ -1301,7 +1310,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;
|
||||
|
@ -1343,14 +1352,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);
|
||||
|
@ -1376,13 +1385,14 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
|
|||
struct pcmcia_socket *s = pcmcia_get_socket(skt);
|
||||
|
||||
if (!s) {
|
||||
printk(KERN_ERR "PCMCIA obtaining reference to socket %p " \
|
||||
"failed, event 0x%x lost!\n", skt, event);
|
||||
dev_printk(KERN_ERR, &skt->dev,
|
||||
"PCMCIA obtaining reference to socket " \
|
||||
"failed, event 0x%x lost!\n", event);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
|
||||
event, priority, skt);
|
||||
ds_dev_dbg(1, &skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
|
||||
event, priority, skt);
|
||||
|
||||
switch (event) {
|
||||
case CS_EVENT_CARD_REMOVAL:
|
||||
|
@ -1457,7 +1467,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;
|
||||
}
|
||||
|
||||
|
@ -1477,7 +1488,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);
|
||||
}
|
||||
|
|
|
@ -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)";
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -58,7 +58,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 { \
|
||||
|
|
|
@ -44,16 +44,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
|
||||
|
||||
|
||||
|
@ -802,8 +803,10 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
|
|||
/* 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;
|
||||
|
@ -909,3 +912,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(p_dev, 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);
|
||||
|
|
|
@ -194,13 +194,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
|
|||
int any;
|
||||
u_char *b, hole, most;
|
||||
|
||||
printk(KERN_INFO "cs: IO port probe %#x-%#x:",
|
||||
base, base+num-1);
|
||||
dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:",
|
||||
base, base+num-1);
|
||||
|
||||
/* First, what does a floating port look like? */
|
||||
b = kzalloc(256, GFP_KERNEL);
|
||||
if (!b) {
|
||||
printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
|
||||
dev_printk(KERN_ERR, &s->dev,
|
||||
"do_io_probe: unable to kmalloc 256 bytes");
|
||||
return;
|
||||
}
|
||||
for (i = base, most = 0; i < base+num; i += 8) {
|
||||
|
@ -366,8 +367,8 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
|
|||
struct socket_data *s_data = s->resource_data;
|
||||
u_long i, j, bad, fail, step;
|
||||
|
||||
printk(KERN_INFO "cs: memory probe 0x%06lx-0x%06lx:",
|
||||
base, base+num-1);
|
||||
dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
|
||||
base, base+num-1);
|
||||
bad = fail = 0;
|
||||
step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
|
||||
/* don't allow too large steps */
|
||||
|
@ -431,8 +432,8 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
|
|||
if (probe_mask & MEM_PROBE_HIGH) {
|
||||
if (inv_probe(s_data->mem_db.next, s) > 0)
|
||||
return 0;
|
||||
printk(KERN_NOTICE "cs: warning: no high memory space "
|
||||
"available!\n");
|
||||
dev_printk(KERN_NOTICE, &s->dev,
|
||||
"cs: warning: no high memory space available!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -794,10 +795,11 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
|
|||
if (res->flags & IORESOURCE_IO) {
|
||||
if (res == &ioport_resource)
|
||||
continue;
|
||||
printk(KERN_INFO "pcmcia: parent PCI bridge I/O "
|
||||
"window: 0x%llx - 0x%llx\n",
|
||||
(unsigned long long)res->start,
|
||||
(unsigned long long)res->end);
|
||||
dev_printk(KERN_INFO, &s->cb_dev->dev,
|
||||
"pcmcia: parent PCI bridge I/O "
|
||||
"window: 0x%llx - 0x%llx\n",
|
||||
(unsigned long long)res->start,
|
||||
(unsigned long long)res->end);
|
||||
if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
|
||||
done |= IORESOURCE_IO;
|
||||
|
||||
|
@ -806,10 +808,11 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
|
|||
if (res->flags & IORESOURCE_MEM) {
|
||||
if (res == &iomem_resource)
|
||||
continue;
|
||||
printk(KERN_INFO "pcmcia: parent PCI bridge Memory "
|
||||
"window: 0x%llx - 0x%llx\n",
|
||||
(unsigned long long)res->start,
|
||||
(unsigned long long)res->end);
|
||||
dev_printk(KERN_INFO, &s->cb_dev->dev,
|
||||
"pcmcia: parent PCI bridge Memory "
|
||||
"window: 0x%llx - 0x%llx\n",
|
||||
(unsigned long long)res->start,
|
||||
(unsigned long long)res->end);
|
||||
if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
|
||||
done |= IORESOURCE_MEM;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
#include <asm/arch/pxa-regs.h>
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef CONFIG_PCMCIA_DEBUG
|
||||
|
||||
static int pc_debug;
|
||||
module_param(pc_debug, int, 0644);
|
||||
|
|
|
@ -137,7 +137,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, ...);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -339,8 +339,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
|
|||
|
||||
mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
|
||||
devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
|
||||
printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",
|
||||
pci_name(socket->dev), mfunc, devctl);
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"TI: mfunc 0x%08x, devctl 0x%02x\n", mfunc, devctl);
|
||||
|
||||
/* make sure PCI interrupts are enabled before probing */
|
||||
ti_init(socket);
|
||||
|
@ -354,8 +354,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
|
|||
* We're here which means PCI interrupts are _not_ delivered. try to
|
||||
* find the right setting (all serial or parallel)
|
||||
*/
|
||||
printk(KERN_INFO "Yenta TI: socket %s probing PCI interrupt failed, trying to fix\n",
|
||||
pci_name(socket->dev));
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"TI: probing PCI interrupt failed, trying to fix\n");
|
||||
|
||||
/* for serial PCI make sure MFUNC3 is set to IRQSER */
|
||||
if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) {
|
||||
|
@ -379,8 +379,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
|
|||
|
||||
pci_irq_status = yenta_probe_cb_irq(socket);
|
||||
if (pci_irq_status == 1) {
|
||||
printk(KERN_INFO "Yenta TI: socket %s all-serial interrupts ok\n",
|
||||
pci_name(socket->dev));
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"TI: all-serial interrupts ok\n");
|
||||
mfunc_old = mfunc;
|
||||
goto out;
|
||||
}
|
||||
|
@ -395,8 +395,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
|
|||
}
|
||||
|
||||
/* serial PCI interrupts not working fall back to parallel */
|
||||
printk(KERN_INFO "Yenta TI: socket %s falling back to parallel PCI interrupts\n",
|
||||
pci_name(socket->dev));
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"TI: falling back to parallel PCI interrupts\n");
|
||||
devctl &= ~TI113X_DCR_IMODE_MASK;
|
||||
devctl |= TI113X_DCR_IMODE_SERIAL; /* serial ISA could be right */
|
||||
config_writeb(socket, TI113X_DEVICE_CONTROL, devctl);
|
||||
|
@ -427,8 +427,8 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
|
|||
pci_irq_status = yenta_probe_cb_irq(socket);
|
||||
if (pci_irq_status == 1) {
|
||||
mfunc_old = mfunc;
|
||||
printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts ok\n",
|
||||
pci_name(socket->dev));
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"TI: parallel PCI interrupts ok\n");
|
||||
} else {
|
||||
/* not working, back to old value */
|
||||
mfunc = mfunc_old;
|
||||
|
@ -440,8 +440,9 @@ static void ti12xx_irqroute_func0(struct yenta_socket *socket)
|
|||
out:
|
||||
if (pci_irq_status < 1) {
|
||||
socket->cb_irq = 0;
|
||||
printk(KERN_INFO "Yenta TI: socket %s no PCI interrupts. Fish. Please report.\n",
|
||||
pci_name(socket->dev));
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"Yenta TI: no PCI interrupts. Fish. "
|
||||
"Please report.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -513,8 +514,9 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
|
|||
|
||||
mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC);
|
||||
devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
|
||||
printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n",
|
||||
pci_name(socket->dev), mfunc, devctl);
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"TI: mfunc 0x%08x, devctl 0x%02x\n",
|
||||
mfunc, devctl);
|
||||
|
||||
/* if IRQs are configured as tied, align irq of func1 with func0 */
|
||||
sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
|
||||
|
@ -533,9 +535,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
|
|||
* We're here which means PCI interrupts are _not_ delivered. try to
|
||||
* find the right setting
|
||||
*/
|
||||
printk(KERN_INFO "Yenta TI: socket %s probing PCI interrupt failed, trying to fix\n",
|
||||
pci_name(socket->dev));
|
||||
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"TI: probing PCI interrupt failed, trying to fix\n");
|
||||
|
||||
/* if all serial: set INTRTIE, probe again */
|
||||
if ((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) {
|
||||
|
@ -544,8 +545,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
|
|||
if (ti12xx_tie_interrupts(socket, &old_irq)) {
|
||||
pci_irq_status = yenta_probe_cb_irq(socket);
|
||||
if (pci_irq_status == 1) {
|
||||
printk(KERN_INFO "Yenta TI: socket %s all-serial interrupts, tied ok\n",
|
||||
pci_name(socket->dev));
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"TI: all-serial interrupts, tied ok\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -582,8 +583,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
|
|||
|
||||
pci_irq_status = yenta_probe_cb_irq(socket);
|
||||
if (pci_irq_status == 1) {
|
||||
printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts ok\n",
|
||||
pci_name(socket->dev));
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"TI: parallel PCI interrupts ok\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -593,13 +594,13 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
|
|||
if (pci_irq_status == -1)
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
/* still nothing: set INTRTIE */
|
||||
if (ti12xx_tie_interrupts(socket, &old_irq)) {
|
||||
pci_irq_status = yenta_probe_cb_irq(socket);
|
||||
if (pci_irq_status == 1) {
|
||||
printk(KERN_INFO "Yenta TI: socket %s parallel PCI interrupts, tied ok\n",
|
||||
pci_name(socket->dev));
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"TI: parallel PCI interrupts, tied ok\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -610,8 +611,8 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket)
|
|||
out:
|
||||
if (pci_irq_status < 1) {
|
||||
socket->cb_irq = 0;
|
||||
printk(KERN_INFO "Yenta TI: socket %s no PCI interrupts. Fish. Please report.\n",
|
||||
pci_name(socket->dev));
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"TI: no PCI interrupts. Fish. Please report.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -815,11 +816,13 @@ static int ti12xx_override(struct yenta_socket *socket)
|
|||
/* make sure that memory burst is active */
|
||||
val_orig = val = config_readl(socket, TI113X_SYSTEM_CONTROL);
|
||||
if (disable_clkrun && PCI_FUNC(socket->dev->devfn) == 0) {
|
||||
printk(KERN_INFO "Yenta: Disabling CLKRUN feature\n");
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"Disabling CLKRUN feature\n");
|
||||
val |= TI113X_SCR_KEEPCLK;
|
||||
}
|
||||
if (!(val & TI122X_SCR_MRBURSTUP)) {
|
||||
printk(KERN_INFO "Yenta: Enabling burst memory read transactions\n");
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"Enabling burst memory read transactions\n");
|
||||
val |= TI122X_SCR_MRBURSTUP;
|
||||
}
|
||||
if (val_orig != val)
|
||||
|
@ -830,10 +833,12 @@ static int ti12xx_override(struct yenta_socket *socket)
|
|||
* CSC interrupts to PCI rather than INTVAL.
|
||||
*/
|
||||
val = config_readb(socket, TI1250_DIAGNOSTIC);
|
||||
printk(KERN_INFO "Yenta: Using %s to route CSC interrupts to PCI\n",
|
||||
(val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL");
|
||||
printk(KERN_INFO "Yenta: Routing CardBus interrupts to %s\n",
|
||||
(val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA");
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"Using %s to route CSC interrupts to PCI\n",
|
||||
(val & TI1250_DIAG_PCI_CSC) ? "CSCINT" : "INTVAL");
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"Routing CardBus interrupts to %s\n",
|
||||
(val & TI1250_DIAG_PCI_IREQ) ? "PCI" : "ISA");
|
||||
|
||||
/* do irqrouting, depending on function */
|
||||
if (PCI_FUNC(socket->dev->devfn) == 0)
|
||||
|
@ -858,8 +863,9 @@ static int ti1250_override(struct yenta_socket *socket)
|
|||
diag |= TI1250_DIAG_PCI_CSC | TI1250_DIAG_PCI_IREQ;
|
||||
|
||||
if (diag != old) {
|
||||
printk(KERN_INFO "Yenta: adjusting diagnostic: %02x -> %02x\n",
|
||||
old, diag);
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"adjusting diagnostic: %02x -> %02x\n",
|
||||
old, diag);
|
||||
config_writeb(socket, TI1250_DIAGNOSTIC, diag);
|
||||
}
|
||||
|
||||
|
@ -924,7 +930,9 @@ static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
|
|||
/* default to clear TLTEnable bit, old behaviour */
|
||||
test_c9 &= ~ENE_TEST_C9_TLTENABLE;
|
||||
|
||||
printk(KERN_INFO "yenta EnE: chaning testregister 0xC9, %02x -> %02x\n", old_c9, test_c9);
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"EnE: chaning testregister 0xC9, %02x -> %02x\n",
|
||||
old_c9, test_c9);
|
||||
config_writeb(socket, ENE_TEST_C9, test_c9);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,11 +38,7 @@ static int pwr_irqs_off;
|
|||
module_param(pwr_irqs_off, bool, 0644);
|
||||
MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!");
|
||||
|
||||
#if 0
|
||||
#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
|
||||
#else
|
||||
#define debug(x,args...)
|
||||
#endif
|
||||
#define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args)
|
||||
|
||||
/* Don't ask.. */
|
||||
#define to_cycles(ns) ((ns)/120)
|
||||
|
@ -69,13 +65,13 @@ MODULE_PARM_DESC (override_bios, "yenta ignore bios resource allocation");
|
|||
static inline u32 cb_readl(struct yenta_socket *socket, unsigned reg)
|
||||
{
|
||||
u32 val = readl(socket->base + reg);
|
||||
debug("%p %04x %08x\n", socket, reg, val);
|
||||
debug("%04x %08x\n", socket, reg, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void cb_writel(struct yenta_socket *socket, unsigned reg, u32 val)
|
||||
{
|
||||
debug("%p %04x %08x\n", socket, reg, val);
|
||||
debug("%04x %08x\n", socket, reg, val);
|
||||
writel(val, socket->base + reg);
|
||||
readl(socket->base + reg); /* avoid problems with PCI write posting */
|
||||
}
|
||||
|
@ -84,7 +80,7 @@ static inline u8 config_readb(struct yenta_socket *socket, unsigned offset)
|
|||
{
|
||||
u8 val;
|
||||
pci_read_config_byte(socket->dev, offset, &val);
|
||||
debug("%p %04x %02x\n", socket, offset, val);
|
||||
debug("%04x %02x\n", socket, offset, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -92,7 +88,7 @@ static inline u16 config_readw(struct yenta_socket *socket, unsigned offset)
|
|||
{
|
||||
u16 val;
|
||||
pci_read_config_word(socket->dev, offset, &val);
|
||||
debug("%p %04x %04x\n", socket, offset, val);
|
||||
debug("%04x %04x\n", socket, offset, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -100,32 +96,32 @@ static inline u32 config_readl(struct yenta_socket *socket, unsigned offset)
|
|||
{
|
||||
u32 val;
|
||||
pci_read_config_dword(socket->dev, offset, &val);
|
||||
debug("%p %04x %08x\n", socket, offset, val);
|
||||
debug("%04x %08x\n", socket, offset, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void config_writeb(struct yenta_socket *socket, unsigned offset, u8 val)
|
||||
{
|
||||
debug("%p %04x %02x\n", socket, offset, val);
|
||||
debug("%04x %02x\n", socket, offset, val);
|
||||
pci_write_config_byte(socket->dev, offset, val);
|
||||
}
|
||||
|
||||
static inline void config_writew(struct yenta_socket *socket, unsigned offset, u16 val)
|
||||
{
|
||||
debug("%p %04x %04x\n", socket, offset, val);
|
||||
debug("%04x %04x\n", socket, offset, val);
|
||||
pci_write_config_word(socket->dev, offset, val);
|
||||
}
|
||||
|
||||
static inline void config_writel(struct yenta_socket *socket, unsigned offset, u32 val)
|
||||
{
|
||||
debug("%p %04x %08x\n", socket, offset, val);
|
||||
debug("%04x %08x\n", socket, offset, val);
|
||||
pci_write_config_dword(socket->dev, offset, val);
|
||||
}
|
||||
|
||||
static inline u8 exca_readb(struct yenta_socket *socket, unsigned reg)
|
||||
{
|
||||
u8 val = readb(socket->base + 0x800 + reg);
|
||||
debug("%p %04x %02x\n", socket, reg, val);
|
||||
debug("%04x %02x\n", socket, reg, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -134,20 +130,20 @@ static inline u8 exca_readw(struct yenta_socket *socket, unsigned reg)
|
|||
u16 val;
|
||||
val = readb(socket->base + 0x800 + reg);
|
||||
val |= readb(socket->base + 0x800 + reg + 1) << 8;
|
||||
debug("%p %04x %04x\n", socket, reg, val);
|
||||
debug("%04x %04x\n", socket, reg, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void exca_writeb(struct yenta_socket *socket, unsigned reg, u8 val)
|
||||
{
|
||||
debug("%p %04x %02x\n", socket, reg, val);
|
||||
debug("%04x %02x\n", socket, reg, val);
|
||||
writeb(val, socket->base + 0x800 + reg);
|
||||
readb(socket->base + 0x800 + reg); /* PCI write posting... */
|
||||
}
|
||||
|
||||
static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
|
||||
{
|
||||
debug("%p %04x %04x\n", socket, reg, val);
|
||||
debug("%04x %04x\n", socket, reg, val);
|
||||
writeb(val, socket->base + 0x800 + reg);
|
||||
writeb(val >> 8, socket->base + 0x800 + reg + 1);
|
||||
|
||||
|
@ -207,7 +203,7 @@ static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)
|
|||
|
||||
|
||||
if (state & CB_CBCARD) {
|
||||
val |= SS_CARDBUS;
|
||||
val |= SS_CARDBUS;
|
||||
val |= (state & CB_CARDSTS) ? SS_STSCHG : 0;
|
||||
val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
|
||||
val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
|
||||
|
@ -650,8 +646,10 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
|
|||
root = pci_find_parent_resource(socket->dev, res);
|
||||
if (root && (request_resource(root, res) == 0))
|
||||
return 0;
|
||||
printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n",
|
||||
pci_name(socket->dev), nr);
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"Preassigned resource %d busy or not available, "
|
||||
"reconfiguring...\n",
|
||||
nr);
|
||||
}
|
||||
|
||||
if (type & IORESOURCE_IO) {
|
||||
|
@ -674,8 +672,9 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
|
|||
return 1;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
|
||||
pci_name(socket->dev), type);
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"no resource of type %x available, trying to continue...\n",
|
||||
type);
|
||||
res->start = res->end = res->flags = 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -923,7 +922,8 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
|
|||
socket->probe_status = 0;
|
||||
|
||||
if (request_irq(socket->cb_irq, yenta_probe_handler, IRQF_SHARED, "yenta", socket)) {
|
||||
printk(KERN_WARNING "Yenta: request_irq() in yenta_probe_cb_irq() failed!\n");
|
||||
dev_printk(KERN_WARNING, &socket->dev->dev,
|
||||
"request_irq() in yenta_probe_cb_irq() failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -960,8 +960,9 @@ static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_i
|
|||
else
|
||||
socket->socket.irq_mask = 0;
|
||||
|
||||
printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n",
|
||||
socket->socket.irq_mask, socket->cb_irq);
|
||||
dev_printk(KERN_INFO, &socket->dev->dev,
|
||||
"ISA IRQ mask 0x%04x, PCI irq %d\n",
|
||||
socket->socket.irq_mask, socket->cb_irq);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1051,8 +1052,9 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge)
|
|||
|
||||
/* Show that the wanted subordinate number is not possible: */
|
||||
if (cardbus_bridge->subordinate > upper_limit)
|
||||
printk(KERN_WARNING "Yenta: Upper limit for fixing this "
|
||||
"bridge's parent bridge: #%02x\n", upper_limit);
|
||||
dev_printk(KERN_WARNING, &cardbus_bridge->dev,
|
||||
"Upper limit for fixing this "
|
||||
"bridge's parent bridge: #%02x\n", upper_limit);
|
||||
|
||||
/* If we have room to increase the bridge's subordinate number, */
|
||||
if (bridge_to_fix->subordinate < upper_limit) {
|
||||
|
@ -1061,10 +1063,11 @@ static void yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge)
|
|||
unsigned char subordinate_to_assign =
|
||||
min(cardbus_bridge->subordinate, upper_limit);
|
||||
|
||||
printk(KERN_INFO "Yenta: Raising subordinate bus# of parent "
|
||||
"bus (#%02x) from #%02x to #%02x\n",
|
||||
bridge_to_fix->number,
|
||||
bridge_to_fix->subordinate, subordinate_to_assign);
|
||||
dev_printk(KERN_INFO, &bridge_to_fix->dev,
|
||||
"Raising subordinate bus# of parent "
|
||||
"bus (#%02x) from #%02x to #%02x\n",
|
||||
bridge_to_fix->number,
|
||||
bridge_to_fix->subordinate, subordinate_to_assign);
|
||||
|
||||
/* Save the new subordinate in the bus struct of the bridge */
|
||||
bridge_to_fix->subordinate = subordinate_to_assign;
|
||||
|
@ -1091,8 +1094,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
|
|||
* Bail out if so.
|
||||
*/
|
||||
if (!dev->subordinate) {
|
||||
printk(KERN_ERR "Yenta: no bus associated with %s! "
|
||||
"(try 'pci=assign-busses')\n", pci_name(dev));
|
||||
dev_printk(KERN_ERR, &dev->dev, "no bus associated! "
|
||||
"(try 'pci=assign-busses')\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -1127,7 +1130,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
|
|||
goto disable;
|
||||
|
||||
if (!pci_resource_start(dev, 0)) {
|
||||
printk(KERN_ERR "No cardbus resource!\n");
|
||||
dev_printk(KERN_ERR, &dev->dev, "No cardbus resource!\n");
|
||||
ret = -ENODEV;
|
||||
goto release;
|
||||
}
|
||||
|
@ -1146,8 +1149,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
|
|||
* report the subsystem vendor and device for help debugging
|
||||
* the irq stuff...
|
||||
*/
|
||||
printk(KERN_INFO "Yenta: CardBus bridge found at %s [%04x:%04x]\n",
|
||||
pci_name(dev), dev->subsystem_vendor, dev->subsystem_device);
|
||||
dev_printk(KERN_INFO, &dev->dev, "CardBus bridge found [%04x:%04x]\n",
|
||||
dev->subsystem_vendor, dev->subsystem_device);
|
||||
|
||||
yenta_config_init(socket);
|
||||
|
||||
|
@ -1179,8 +1182,12 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
|
|||
socket->poll_timer.data = (unsigned long)socket;
|
||||
socket->poll_timer.expires = jiffies + HZ;
|
||||
add_timer(&socket->poll_timer);
|
||||
printk(KERN_INFO "Yenta: no PCI IRQ, CardBus support disabled for this socket.\n"
|
||||
KERN_INFO "Yenta: check your BIOS CardBus, BIOS IRQ or ACPI settings.\n");
|
||||
dev_printk(KERN_INFO, &dev->dev,
|
||||
"no PCI IRQ, CardBus support disabled for this "
|
||||
"socket.\n");
|
||||
dev_printk(KERN_INFO, &dev->dev,
|
||||
"check your BIOS CardBus, BIOS IRQ or ACPI "
|
||||
"settings.\n");
|
||||
} else {
|
||||
socket->socket.features |= SS_CAP_CARDBUS;
|
||||
}
|
||||
|
@ -1188,7 +1195,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
|
|||
/* Figure out what the dang thing can do for the PCMCIA layer... */
|
||||
yenta_interrogate(socket);
|
||||
yenta_get_socket_capabilities(socket, isa_interrupts);
|
||||
printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
|
||||
dev_printk(KERN_INFO, &dev->dev,
|
||||
"Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
|
||||
|
||||
yenta_fixup_parent_bridge(dev->subordinate);
|
||||
|
||||
|
|
|
@ -140,44 +140,41 @@ static void aha152x_detach(struct pcmcia_device *link)
|
|||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int aha152x_config_check(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
/* For New Media T&J, look for a SCSI window */
|
||||
if (cfg->io.win[0].len >= 0x20)
|
||||
p_dev->io.BasePort1 = cfg->io.win[0].base;
|
||||
else if ((cfg->io.nwin > 1) &&
|
||||
(cfg->io.win[1].len >= 0x20))
|
||||
p_dev->io.BasePort1 = cfg->io.win[1].base;
|
||||
if ((cfg->io.nwin > 0) &&
|
||||
(p_dev->io.BasePort1 < 0xffff)) {
|
||||
if (!pcmcia_request_io(p_dev, &p_dev->io))
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int aha152x_config_cs(struct pcmcia_device *link)
|
||||
{
|
||||
scsi_info_t *info = link->priv;
|
||||
struct aha152x_setup s;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
int i, last_ret, last_fn;
|
||||
u_char tuple_data[64];
|
||||
int last_ret, last_fn;
|
||||
struct Scsi_Host *host;
|
||||
|
||||
|
||||
DEBUG(0, "aha152x_config(0x%p)\n", link);
|
||||
|
||||
tuple.TupleData = tuple_data;
|
||||
tuple.TupleDataMax = 64;
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
tuple.Attributes = 0;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
while (1) {
|
||||
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
|
||||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
|
||||
goto next_entry;
|
||||
/* For New Media T&J, look for a SCSI window */
|
||||
if (parse.cftable_entry.io.win[0].len >= 0x20)
|
||||
link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
|
||||
else if ((parse.cftable_entry.io.nwin > 1) &&
|
||||
(parse.cftable_entry.io.win[1].len >= 0x20))
|
||||
link->io.BasePort1 = parse.cftable_entry.io.win[1].base;
|
||||
if ((parse.cftable_entry.io.nwin > 0) &&
|
||||
(link->io.BasePort1 < 0xffff)) {
|
||||
link->conf.ConfigIndex = parse.cftable_entry.index;
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS) break;
|
||||
}
|
||||
next_entry:
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
last_ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
|
||||
if (last_ret) {
|
||||
cs_error(link, RequestIO, last_ret);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
|
@ -208,6 +205,7 @@ static int aha152x_config_cs(struct pcmcia_device *link)
|
|||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
aha152x_release_cs(link);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -1607,133 +1607,129 @@ static void nsp_cs_detach(struct pcmcia_device *link)
|
|||
is received, to configure the PCMCIA socket, and to make the
|
||||
ethernet device available to the system.
|
||||
======================================================================*/
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
/*====================================================================*/
|
||||
|
||||
struct nsp_cs_configdata {
|
||||
nsp_hw_data *data;
|
||||
win_req_t req;
|
||||
};
|
||||
|
||||
static int nsp_cs_config_check(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
struct nsp_cs_configdata *cfg_mem = priv_data;
|
||||
|
||||
if (cfg->index == 0)
|
||||
return -ENODEV;
|
||||
|
||||
/* Does this card need audio output? */
|
||||
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
p_dev->conf.Status = CCSR_AUDIO_ENA;
|
||||
}
|
||||
|
||||
/* Use power settings for Vcc and Vpp if present */
|
||||
/* Note that the CIS values need to be rescaled */
|
||||
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
|
||||
if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
|
||||
return -ENODEV;
|
||||
else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) {
|
||||
if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM]/10000)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
p_dev->conf.Vpp =
|
||||
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
} else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
p_dev->conf.Vpp =
|
||||
dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
}
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
|
||||
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
if (!(io->flags & CISTPL_IO_8BIT))
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||
if (!(io->flags & CISTPL_IO_16BIT))
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||
p_dev->io.BasePort1 = io->win[0].base;
|
||||
p_dev->io.NumPorts1 = io->win[0].len;
|
||||
if (io->nwin > 1) {
|
||||
p_dev->io.Attributes2 = p_dev->io.Attributes1;
|
||||
p_dev->io.BasePort2 = io->win[1].base;
|
||||
p_dev->io.NumPorts2 = io->win[1].len;
|
||||
}
|
||||
/* This reserves IO space but doesn't actually enable it */
|
||||
if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
|
||||
goto next_entry;
|
||||
}
|
||||
|
||||
if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
|
||||
memreq_t map;
|
||||
cistpl_mem_t *mem =
|
||||
(cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
|
||||
cfg_mem->req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
|
||||
cfg_mem->req.Attributes |= WIN_ENABLE;
|
||||
cfg_mem->req.Base = mem->win[0].host_addr;
|
||||
cfg_mem->req.Size = mem->win[0].len;
|
||||
if (cfg_mem->req.Size < 0x1000)
|
||||
cfg_mem->req.Size = 0x1000;
|
||||
cfg_mem->req.AccessSpeed = 0;
|
||||
if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0)
|
||||
goto next_entry;
|
||||
map.Page = 0; map.CardOffset = mem->win[0].card_addr;
|
||||
if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
|
||||
goto next_entry;
|
||||
|
||||
cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size);
|
||||
cfg_mem->data->MmioLength = cfg_mem->req.Size;
|
||||
}
|
||||
/* If we got this far, we're cool! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
next_entry:
|
||||
nsp_dbg(NSP_DEBUG_INIT, "next");
|
||||
pcmcia_disable_device(p_dev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int nsp_cs_config(struct pcmcia_device *link)
|
||||
{
|
||||
int ret;
|
||||
scsi_info_t *info = link->priv;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
int last_ret, last_fn;
|
||||
unsigned char tuple_data[64];
|
||||
config_info_t conf;
|
||||
win_req_t req;
|
||||
memreq_t map;
|
||||
cistpl_cftable_entry_t dflt = { 0 };
|
||||
struct nsp_cs_configdata *cfg_mem;
|
||||
struct Scsi_Host *host;
|
||||
nsp_hw_data *data = &nsp_data_base;
|
||||
|
||||
nsp_dbg(NSP_DEBUG_INIT, "in");
|
||||
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = tuple_data;
|
||||
tuple.TupleDataMax = sizeof(tuple_data);
|
||||
tuple.TupleOffset = 0;
|
||||
cfg_mem = kzalloc(sizeof(cfg_mem), GFP_KERNEL);
|
||||
if (!cfg_mem)
|
||||
return -ENOMEM;
|
||||
cfg_mem->data = data;
|
||||
|
||||
/* Look up the current Vcc */
|
||||
CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));
|
||||
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
while (1) {
|
||||
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
|
||||
|
||||
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
|
||||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
|
||||
goto next_entry;
|
||||
|
||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
|
||||
if (cfg->index == 0) { goto next_entry; }
|
||||
link->conf.ConfigIndex = cfg->index;
|
||||
|
||||
/* Does this card need audio output? */
|
||||
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
|
||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
link->conf.Status = CCSR_AUDIO_ENA;
|
||||
}
|
||||
|
||||
/* Use power settings for Vcc and Vpp if present */
|
||||
/* Note that the CIS values need to be rescaled */
|
||||
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
|
||||
if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
|
||||
goto next_entry;
|
||||
}
|
||||
} else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
|
||||
if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
|
||||
goto next_entry;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
link->conf.Vpp =
|
||||
cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
} else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
|
||||
link->conf.Vpp =
|
||||
dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
}
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
|
||||
link->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
}
|
||||
|
||||
/* IO window settings */
|
||||
link->io.NumPorts1 = link->io.NumPorts2 = 0;
|
||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
if (!(io->flags & CISTPL_IO_8BIT))
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||
if (!(io->flags & CISTPL_IO_16BIT))
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||
link->io.BasePort1 = io->win[0].base;
|
||||
link->io.NumPorts1 = io->win[0].len;
|
||||
if (io->nwin > 1) {
|
||||
link->io.Attributes2 = link->io.Attributes1;
|
||||
link->io.BasePort2 = io->win[1].base;
|
||||
link->io.NumPorts2 = io->win[1].len;
|
||||
}
|
||||
/* This reserves IO space but doesn't actually enable it */
|
||||
if (pcmcia_request_io(link, &link->io) != 0)
|
||||
goto next_entry;
|
||||
}
|
||||
|
||||
if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
|
||||
cistpl_mem_t *mem =
|
||||
(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
|
||||
req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
|
||||
req.Attributes |= WIN_ENABLE;
|
||||
req.Base = mem->win[0].host_addr;
|
||||
req.Size = mem->win[0].len;
|
||||
if (req.Size < 0x1000) {
|
||||
req.Size = 0x1000;
|
||||
}
|
||||
req.AccessSpeed = 0;
|
||||
if (pcmcia_request_window(&link, &req, &link->win) != 0)
|
||||
goto next_entry;
|
||||
map.Page = 0; map.CardOffset = mem->win[0].card_addr;
|
||||
if (pcmcia_map_mem_page(link->win, &map) != 0)
|
||||
goto next_entry;
|
||||
|
||||
data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
|
||||
data->MmioLength = req.Size;
|
||||
}
|
||||
/* If we got this far, we're cool! */
|
||||
break;
|
||||
|
||||
next_entry:
|
||||
nsp_dbg(NSP_DEBUG_INIT, "next");
|
||||
pcmcia_disable_device(link);
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
}
|
||||
ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem);
|
||||
goto cs_failed;
|
||||
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
if (pcmcia_request_irq(link, &link->irq))
|
||||
goto cs_failed;
|
||||
}
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto cs_failed;
|
||||
|
||||
if (free_ports) {
|
||||
if (link->io.BasePort1) {
|
||||
|
@ -1791,20 +1787,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
|
||||
|
||||
|
||||
/*======================================================================
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -439,43 +439,57 @@ first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
|
|||
return pcmcia_parse_tuple(handle, tuple, parse);
|
||||
}
|
||||
|
||||
static int
|
||||
next_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
|
||||
/*====================================================================*/
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
return i;
|
||||
return pcmcia_parse_tuple(handle, tuple, parse);
|
||||
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 };
|
||||
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)
|
||||
{
|
||||
static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
|
||||
static const int size_table[2] = { 8, 16 };
|
||||
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, try;
|
||||
|
||||
/* If the card is already configured, look up the port and irq */
|
||||
i = pcmcia_get_configuration_info(link, &config);
|
||||
|
@ -490,70 +504,28 @@ static int simple_config(struct pcmcia_device *link)
|
|||
info->slave = 1;
|
||||
}
|
||||
if (info->slave) {
|
||||
kfree(cfg_mem);
|
||||
return setup_serial(link, info, port, config.AssignedIRQ);
|
||||
}
|
||||
}
|
||||
|
||||
/* First pass: look for a config entry that looks normal. */
|
||||
tuple->TupleData = (cisdata_t *) buf;
|
||||
tuple->TupleOffset = 0;
|
||||
tuple->TupleDataMax = 255;
|
||||
tuple->Attributes = 0;
|
||||
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
/* Two tries: without IO aliases, then with aliases */
|
||||
for (s = 0; s < 2; s++) {
|
||||
for (try = 0; try < 2; try++) {
|
||||
i = first_tuple(link, tuple, parse);
|
||||
while (i != CS_NO_MORE_ITEMS) {
|
||||
if (i != CS_SUCCESS)
|
||||
goto next_entry;
|
||||
if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp =
|
||||
cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
|
||||
if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) &&
|
||||
(cf->io.win[0].base != 0)) {
|
||||
link->conf.ConfigIndex = cf->index;
|
||||
link->io.BasePort1 = cf->io.win[0].base;
|
||||
link->io.IOAddrLines = (try == 0) ?
|
||||
16 : cf->io.flags & CISTPL_IO_LINES_MASK;
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS)
|
||||
goto found_port;
|
||||
}
|
||||
next_entry:
|
||||
i = next_tuple(link, tuple, parse);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* First pass: look for a config entry that looks normal.
|
||||
* Two tries: without IO aliases, then with aliases */
|
||||
for (try = 0; try < 4; try++)
|
||||
if (!pcmcia_loop_config(link, simple_config_check, &try))
|
||||
goto found_port;
|
||||
|
||||
/* Second pass: try to find an entry that isn't picky about
|
||||
its base address, then try to grab any standard serial port
|
||||
address, and finally try to get any free port. */
|
||||
i = first_tuple(link, tuple, parse);
|
||||
while (i != CS_NO_MORE_ITEMS) {
|
||||
if ((i == CS_SUCCESS) && (cf->io.nwin > 0) &&
|
||||
((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
|
||||
link->conf.ConfigIndex = cf->index;
|
||||
for (j = 0; j < 5; j++) {
|
||||
link->io.BasePort1 = base[j];
|
||||
link->io.IOAddrLines = base[j] ? 16 : 3;
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
if (i == CS_SUCCESS)
|
||||
goto found_port;
|
||||
}
|
||||
}
|
||||
i = next_tuple(link, tuple, parse);
|
||||
}
|
||||
if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
|
||||
goto found_port;
|
||||
|
||||
found_port:
|
||||
if (i != CS_SUCCESS) {
|
||||
printk(KERN_NOTICE
|
||||
"serial_cs: no usable port range found, giving up\n");
|
||||
cs_error(link, RequestIO, i);
|
||||
kfree(cfg_mem);
|
||||
return -1;
|
||||
}
|
||||
printk(KERN_NOTICE
|
||||
"serial_cs: no usable port range found, giving up\n");
|
||||
cs_error(link, RequestIO, i);
|
||||
return -1;
|
||||
|
||||
found_port:
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != CS_SUCCESS) {
|
||||
cs_error(link, RequestIRQ, i);
|
||||
|
@ -571,86 +543,74 @@ next_entry:
|
|||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != CS_SUCCESS) {
|
||||
cs_error(link, RequestConfiguration, i);
|
||||
kfree(cfg_mem);
|
||||
return -1;
|
||||
}
|
||||
kfree(cfg_mem);
|
||||
return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
|
||||
}
|
||||
|
||||
static int multi_config(struct pcmcia_device * link)
|
||||
static int multi_config_check(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cf,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
int *base2 = priv_data;
|
||||
|
||||
/* The quad port cards have bad CIS's, so just look for a
|
||||
window larger than 8 ports and assume it will be right */
|
||||
if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
|
||||
p_dev->io.BasePort1 = cf->io.win[0].base;
|
||||
p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
|
||||
if (!pcmcia_request_io(p_dev, &p_dev->io)) {
|
||||
*base2 = p_dev->io.BasePort1 + 8;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cf,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
int *base2 = priv_data;
|
||||
|
||||
if (cf->io.nwin == 2) {
|
||||
p_dev->io.BasePort1 = cf->io.win[0].base;
|
||||
p_dev->io.BasePort2 = cf->io.win[1].base;
|
||||
p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
|
||||
if (!pcmcia_request_io(p_dev, &p_dev->io)) {
|
||||
*base2 = p_dev->io.BasePort2;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int multi_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct serial_info *info = link->priv;
|
||||
struct serial_cfg_mem *cfg_mem;
|
||||
tuple_t *tuple;
|
||||
u_char *buf;
|
||||
cisparse_t *parse;
|
||||
cistpl_cftable_entry_t *cf;
|
||||
int i, rc, base2 = 0;
|
||||
|
||||
cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
|
||||
if (!cfg_mem)
|
||||
return -1;
|
||||
tuple = &cfg_mem->tuple;
|
||||
parse = &cfg_mem->parse;
|
||||
cf = &parse->cftable_entry;
|
||||
buf = cfg_mem->buf;
|
||||
|
||||
tuple->TupleData = (cisdata_t *) buf;
|
||||
tuple->TupleOffset = 0;
|
||||
tuple->TupleDataMax = 255;
|
||||
tuple->Attributes = 0;
|
||||
tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
int i, base2 = 0;
|
||||
|
||||
/* First, look for a generic full-sized window */
|
||||
link->io.NumPorts1 = info->multi * 8;
|
||||
i = first_tuple(link, tuple, parse);
|
||||
while (i != CS_NO_MORE_ITEMS) {
|
||||
/* The quad port cards have bad CIS's, so just look for a
|
||||
window larger than 8 ports and assume it will be right */
|
||||
if ((i == CS_SUCCESS) && (cf->io.nwin == 1) &&
|
||||
(cf->io.win[0].len > 8)) {
|
||||
link->conf.ConfigIndex = cf->index;
|
||||
link->io.BasePort1 = cf->io.win[0].base;
|
||||
link->io.IOAddrLines =
|
||||
cf->io.flags & CISTPL_IO_LINES_MASK;
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
base2 = link->io.BasePort1 + 8;
|
||||
if (i == CS_SUCCESS)
|
||||
break;
|
||||
}
|
||||
i = next_tuple(link, tuple, parse);
|
||||
}
|
||||
|
||||
/* If that didn't work, look for two windows */
|
||||
if (i != CS_SUCCESS) {
|
||||
if (pcmcia_loop_config(link, multi_config_check, &base2)) {
|
||||
/* If that didn't work, look for two windows */
|
||||
link->io.NumPorts1 = link->io.NumPorts2 = 8;
|
||||
info->multi = 2;
|
||||
i = first_tuple(link, tuple, parse);
|
||||
while (i != CS_NO_MORE_ITEMS) {
|
||||
if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) {
|
||||
link->conf.ConfigIndex = cf->index;
|
||||
link->io.BasePort1 = cf->io.win[0].base;
|
||||
link->io.BasePort2 = cf->io.win[1].base;
|
||||
link->io.IOAddrLines =
|
||||
cf->io.flags & CISTPL_IO_LINES_MASK;
|
||||
i = pcmcia_request_io(link, &link->io);
|
||||
base2 = link->io.BasePort2;
|
||||
if (i == CS_SUCCESS)
|
||||
break;
|
||||
}
|
||||
i = next_tuple(link, tuple, parse);
|
||||
if (pcmcia_loop_config(link, multi_config_check_notpicky,
|
||||
&base2)) {
|
||||
printk(KERN_NOTICE "serial_cs: no usable port range"
|
||||
"found, giving up\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
if (i != CS_SUCCESS) {
|
||||
cs_error(link, RequestIO, i);
|
||||
rc = -1;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != CS_SUCCESS) {
|
||||
/* 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);
|
||||
|
@ -666,8 +626,7 @@ static int multi_config(struct pcmcia_device * link)
|
|||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != CS_SUCCESS) {
|
||||
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;
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
|
|
|
@ -124,65 +124,53 @@ static void ixj_get_serial(struct pcmcia_device * link, IXJ * j)
|
|||
return;
|
||||
}
|
||||
|
||||
static int ixj_config_check(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
|
||||
p_dev->io.BasePort1 = io->win[0].base;
|
||||
p_dev->io.NumPorts1 = io->win[0].len;
|
||||
if (io->nwin == 2) {
|
||||
p_dev->io.BasePort2 = io->win[1].base;
|
||||
p_dev->io.NumPorts2 = io->win[1].len;
|
||||
}
|
||||
if (!pcmcia_request_io(p_dev, &p_dev->io))
|
||||
return 0;
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int ixj_config(struct pcmcia_device * link)
|
||||
{
|
||||
IXJ *j;
|
||||
ixj_info_t *info;
|
||||
tuple_t tuple;
|
||||
u_short buf[128];
|
||||
cisparse_t parse;
|
||||
cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
|
||||
cistpl_cftable_entry_t dflt =
|
||||
{
|
||||
0
|
||||
};
|
||||
int last_ret, last_fn;
|
||||
cistpl_cftable_entry_t dflt = { 0 };
|
||||
|
||||
info = link->priv;
|
||||
DEBUG(0, "ixj_config(0x%p)\n", link);
|
||||
tuple.TupleData = (cisdata_t *) buf;
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.TupleDataMax = 255;
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
tuple.Attributes = 0;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
while (1) {
|
||||
if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
|
||||
pcmcia_parse_tuple(link, &tuple, &parse) != 0)
|
||||
goto next_entry;
|
||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
|
||||
link->conf.ConfigIndex = cfg->index;
|
||||
link->io.BasePort1 = io->win[0].base;
|
||||
link->io.NumPorts1 = io->win[0].len;
|
||||
if (io->nwin == 2) {
|
||||
link->io.BasePort2 = io->win[1].base;
|
||||
link->io.NumPorts2 = io->win[1].len;
|
||||
}
|
||||
if (pcmcia_request_io(link, &link->io) != 0)
|
||||
goto next_entry;
|
||||
/* If we've got this far, we're done */
|
||||
break;
|
||||
}
|
||||
next_entry:
|
||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
|
||||
dflt = *cfg;
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
}
|
||||
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
if (pcmcia_loop_config(link, ixj_config_check, &dflt))
|
||||
goto cs_failed;
|
||||
|
||||
if (pcmcia_request_configuration(link, &link->conf))
|
||||
goto cs_failed;
|
||||
|
||||
/*
|
||||
* Register the card with the core.
|
||||
*/
|
||||
j=ixj_pcmcia_probe(link->io.BasePort1,link->io.BasePort1 + 0x10);
|
||||
*/
|
||||
j = ixj_pcmcia_probe(link->io.BasePort1, link->io.BasePort1 + 0x10);
|
||||
|
||||
info->ndev = 1;
|
||||
info->node.major = PHONE_MAJOR;
|
||||
link->dev_node = &info->node;
|
||||
ixj_get_serial(link, j);
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
ixj_cs_release(link);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -155,97 +155,72 @@ static void sl811_cs_release(struct pcmcia_device * link)
|
|||
platform_device_unregister(&platform_dev);
|
||||
}
|
||||
|
||||
static int sl811_cs_config_check(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
if (cfg->index == 0)
|
||||
return -ENODEV;
|
||||
|
||||
/* Use power settings for Vcc and Vpp if present */
|
||||
/* Note that the CIS values need to be rescaled */
|
||||
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
|
||||
if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 != vcc)
|
||||
return -ENODEV;
|
||||
} else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) {
|
||||
if (dflt->vcc.param[CISTPL_POWER_VNOM]/10000 != vcc)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
|
||||
p_dev->conf.Vpp =
|
||||
cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
|
||||
p_dev->conf.Vpp =
|
||||
dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
|
||||
/* we need an interrupt */
|
||||
if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
|
||||
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
|
||||
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||
p_dev->io.BasePort1 = io->win[0].base;
|
||||
p_dev->io.NumPorts1 = io->win[0].len;
|
||||
|
||||
return pcmcia_request_io(p_dev, &p_dev->io);
|
||||
}
|
||||
pcmcia_disable_device(p_dev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
static int sl811_cs_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct device *parent = &handle_to_dev(link);
|
||||
local_info_t *dev = link->priv;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
int last_fn, last_ret;
|
||||
u_char buf[64];
|
||||
config_info_t conf;
|
||||
cistpl_cftable_entry_t dflt = { 0 };
|
||||
|
||||
DBG(0, "sl811_cs_config(0x%p)\n", link);
|
||||
|
||||
/* Look up the current Vcc */
|
||||
CS_CHECK(GetConfigurationInfo,
|
||||
pcmcia_get_configuration_info(link, &conf));
|
||||
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
while (1) {
|
||||
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
|
||||
|
||||
if (pcmcia_get_tuple_data(link, &tuple) != 0
|
||||
|| pcmcia_parse_tuple(link, &tuple, &parse)
|
||||
!= 0)
|
||||
goto next_entry;
|
||||
|
||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) {
|
||||
dflt = *cfg;
|
||||
}
|
||||
|
||||
if (cfg->index == 0)
|
||||
goto next_entry;
|
||||
|
||||
link->conf.ConfigIndex = cfg->index;
|
||||
|
||||
/* Use power settings for Vcc and Vpp if present */
|
||||
/* Note that the CIS values need to be rescaled */
|
||||
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
|
||||
if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000
|
||||
!= conf.Vcc)
|
||||
goto next_entry;
|
||||
} else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
|
||||
if (dflt.vcc.param[CISTPL_POWER_VNOM]/10000
|
||||
!= conf.Vcc)
|
||||
goto next_entry;
|
||||
}
|
||||
|
||||
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp =
|
||||
cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
|
||||
link->conf.Vpp =
|
||||
dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
|
||||
|
||||
/* we need an interrupt */
|
||||
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
|
||||
link->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
link->io.NumPorts1 = link->io.NumPorts2 = 0;
|
||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
|
||||
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||
link->io.BasePort1 = io->win[0].base;
|
||||
link->io.NumPorts1 = io->win[0].len;
|
||||
|
||||
if (pcmcia_request_io(link, &link->io) != 0)
|
||||
goto next_entry;
|
||||
}
|
||||
break;
|
||||
|
||||
next_entry:
|
||||
pcmcia_disable_device(link);
|
||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
||||
}
|
||||
if (pcmcia_loop_config(link, sl811_cs_config_check, NULL))
|
||||
goto failed;
|
||||
|
||||
/* require an IRQ and two registers */
|
||||
if (!link->io.NumPorts1 || link->io.NumPorts1 < 2)
|
||||
goto cs_failed;
|
||||
goto failed;
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
CS_CHECK(RequestIRQ,
|
||||
pcmcia_request_irq(link, &link->irq));
|
||||
else
|
||||
goto cs_failed;
|
||||
goto failed;
|
||||
|
||||
CS_CHECK(RequestConfiguration,
|
||||
pcmcia_request_configuration(link, &link->conf));
|
||||
|
@ -266,8 +241,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;
|
||||
}
|
||||
|
|
|
@ -607,4 +607,12 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned
|
|||
#define pcmcia_validate_cis(p_dev, info) \
|
||||
pccard_validate_cis(p_dev->socket, p_dev->func, info)
|
||||
|
||||
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);
|
||||
|
||||
#endif /* LINUX_CISTPL_H */
|
||||
|
|
Loading…
Reference in New Issue