diff options
82 files changed, 3005 insertions, 3290 deletions
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt index 96f155e6875..059934363ca 100644 --- a/Documentation/pcmcia/driver-changes.txt +++ b/Documentation/pcmcia/driver-changes.txt @@ -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 diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 41b4361bbf6..02b596b9cf6 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -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; */ - - pass = io_base = ctl_base = 0; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple)); - - /* 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; - } - } + /* Allocate resoure probing structures */ - 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++; - } - } + stk = kzalloc(sizeof(*stk), GFP_KERNEL); + if (!stk) + goto out1; + stk->is_kme = is_kme; + stk->skip_vcc = io_base = ctl_base = 0; + if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) { + stk->skip_vcc = 1; + if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) + goto failed; /* No suitable config found */ + } + io_base = pdev->io.BasePort1; + ctl_base = stk->ctl_base; CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf)); @@ -384,6 +365,7 @@ static struct pcmcia_device_id pcmcia_devices[] = { PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904), PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */ + PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */ PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */ PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), @@ -404,9 +386,9 @@ static struct pcmcia_device_id pcmcia_devices[] = { PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591), PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728), PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), - PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420), PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae), PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178), + PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420), PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178), PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753), PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e), diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index bcf57927b7a..e6ee21d99d9 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -901,23 +901,23 @@ static int bluecard_config(struct pcmcia_device *link) for (n = 0; n < 0x400; n += 0x40) { link->io.BasePort1 = n ^ 0x300; i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) + if (i == 0) break; } - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestIO, i); goto failed; } i = pcmcia_request_irq(link, &link->irq); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } i = pcmcia_request_configuration(link, &link->conf); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestConfiguration, i); goto failed; } diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 27058477cc8..2cbe70b6647 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -678,101 +678,78 @@ static void bt3c_detach(struct pcmcia_device *link) kfree(info); } -static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) +static int bt3c_check_config(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cf, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) { - int i; - - 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); + unsigned long try = (unsigned long) 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 == 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 next_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_next_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; + + 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; - - /* 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); - } - } + int i; + unsigned long try; + + /* 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; -found_port: - if (i != CS_SUCCESS) { - BT_ERR("No usable port range found"); - cs_error(link, RequestIO, i); - goto failed; - } + BT_ERR("No usable port range found"); + cs_error(link, RequestIO, -ENODEV); + goto failed; +found_port: i = pcmcia_request_irq(link, &link->irq); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } i = pcmcia_request_configuration(link, &link->conf); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestConfiguration, i); goto failed; } diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 68d1d258e6a..8e556b7ff9f 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -607,102 +607,78 @@ static void btuart_detach(struct pcmcia_device *link) kfree(info); } -static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) +static int btuart_check_config(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cf, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) { - int i; - - 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); + 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 == 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 next_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_next_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; + + 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; - - /* 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); - } - } + int i; + int try; + + /* 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; -found_port: - if (i != CS_SUCCESS) { - BT_ERR("No usable port range found"); - cs_error(link, RequestIO, i); - goto failed; - } + BT_ERR("No usable port range found"); + cs_error(link, RequestIO, -ENODEV); + goto failed; +found_port: i = pcmcia_request_irq(link, &link->irq); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } i = pcmcia_request_configuration(link, &link->conf); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestConfiguration, i); goto failed; } diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index dae45cdf02b..e6e6b037695 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -590,75 +590,40 @@ static void dtl1_detach(struct pcmcia_device *link) kfree(info); } -static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) +static int dtl1_confcheck(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cf, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) { - int i; - - i = pcmcia_get_tuple_data(handle, tuple); - if (i != CS_SUCCESS) - return i; - - return pcmcia_parse_tuple(handle, tuple, parse); -} - -static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) -{ - if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) - return CS_NO_MORE_ITEMS; - return get_tuple(handle, tuple, parse); -} - -static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) -{ - if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS) - return CS_NO_MORE_ITEMS; - return get_tuple(handle, tuple, parse); + if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { + p_dev->io.BasePort1 = cf->io.win[0].base; + p_dev->io.NumPorts1 = cf->io.win[0].len; /*yo */ + p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; + if (!pcmcia_request_io(p_dev, &p_dev->io)) + return 0; + } + return -ENODEV; } static int dtl1_config(struct pcmcia_device *link) { dtl1_info_t *info = link->priv; - tuple_t tuple; - u_short buf[256]; - cisparse_t parse; - cistpl_cftable_entry_t *cf = &parse.cftable_entry; int i; - tuple.TupleData = (cisdata_t *)buf; - tuple.TupleOffset = 0; - tuple.TupleDataMax = 255; - tuple.Attributes = 0; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - /* Look for a generic full-sized window */ link->io.NumPorts1 = 8; - i = first_tuple(link, &tuple, &parse); - while (i != CS_NO_MORE_ITEMS) { - if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { - link->conf.ConfigIndex = cf->index; - link->io.BasePort1 = cf->io.win[0].base; - link->io.NumPorts1 = cf->io.win[0].len; /*yo */ - link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) - break; - } - i = next_tuple(link, &tuple, &parse); - } - - if (i != CS_SUCCESS) { - cs_error(link, RequestIO, i); + if (!pcmcia_loop_config(link, dtl1_confcheck, NULL)) goto failed; - } i = pcmcia_request_irq(link, &link->irq); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } i = pcmcia_request_configuration(link, &link->conf); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestConfiguration, i); goto failed; } diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index f070ae7bd91..1c5bf99895e 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -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); diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 0b5934bef7a..2d7c906435b 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -526,65 +526,49 @@ static void cm4040_reader_release(struct pcmcia_device *link) return; } -static int reader_config(struct pcmcia_device *link, int devno) +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) { - struct reader_dev *dev; - tuple_t tuple; - cisparse_t parse; - u_char buf[64]; - int fail_fn, fail_rc; 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; +} + - tuple.Attributes = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; +static int reader_config(struct pcmcia_device *link, int devno) +{ + struct reader_dev *dev; + int fail_rc; link->io.BasePort2 = 0; link->io.NumPorts2 = 0; link->io.Attributes2 = 0; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - for (rc = pcmcia_get_first_tuple(link, &tuple); - rc == CS_SUCCESS; - rc = pcmcia_get_next_tuple(link, &tuple)) { - rc = pcmcia_get_tuple_data(link, &tuple); - if (rc != CS_SUCCESS) - continue; - rc = pcmcia_parse_tuple(link, &tuple, &parse); - if (rc != CS_SUCCESS) - continue; - - link->conf.ConfigIndex = parse.cftable_entry.index; - - if (!parse.cftable_entry.io.nwin) - continue; - - link->io.BasePort1 = parse.cftable_entry.io.win[0].base; - link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = parse.cftable_entry.io.flags - & CISTPL_IO_LINES_MASK; - rc = pcmcia_request_io(link, &link->io); - - dev_printk(KERN_INFO, &handle_to_dev(link), "foo"); - if (rc == CS_SUCCESS) - break; - else - dev_printk(KERN_INFO, &handle_to_dev(link), - "pcmcia_request_io failed 0x%x\n", rc); - } - if (rc != CS_SUCCESS) + + if (pcmcia_loop_config(link, cm4040_config_check, NULL)) goto cs_release; link->conf.IntType = 00000002; - if ((fail_rc = pcmcia_request_configuration(link,&link->conf)) - !=CS_SUCCESS) { - fail_fn = RequestConfiguration; + fail_rc = pcmcia_request_configuration(link, &link->conf); + if (fail_rc != 0) { dev_printk(KERN_INFO, &handle_to_dev(link), "pcmcia_request_configuration failed 0x%x\n", fail_rc); diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index 5eca7a99afe..5216fce0c62 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c @@ -65,9 +65,9 @@ static void signalled_reboot_work(struct work_struct *work_reboot) struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev, work_reboot); struct pcmcia_device *link = ipw->link; - int ret = pccard_reset_card(link->socket); + int ret = pcmcia_reset_card(link->socket); - if (ret != CS_SUCCESS) + if (ret != 0) cs_error(link, ResetCard, ret); } @@ -83,7 +83,6 @@ static int config_ipwireless(struct ipw_dev *ipw) { struct pcmcia_device *link = ipw->link; int ret; - config_info_t conf; tuple_t tuple; unsigned short buf[64]; cisparse_t parse; @@ -105,7 +104,7 @@ static int config_ipwireless(struct ipw_dev *ipw) while (ret == 0) { ret = pcmcia_get_tuple_data(link, &tuple); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, GetTupleData, ret); goto exit0; } @@ -116,21 +115,21 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_get_first_tuple(link, &tuple); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, GetFirstTuple, ret); goto exit0; } ret = pcmcia_get_tuple_data(link, &tuple); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, GetTupleData, ret); goto exit0; } - ret = pcmcia_parse_tuple(link, &tuple, &parse); + ret = pcmcia_parse_tuple(&tuple, &parse); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, ParseTuple, ret); goto exit0; } @@ -152,21 +151,21 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_get_first_tuple(link, &tuple); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, GetFirstTuple, ret); goto exit0; } ret = pcmcia_get_tuple_data(link, &tuple); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, GetTupleData, ret); goto exit0; } - ret = pcmcia_parse_tuple(link, &tuple, &parse); + ret = pcmcia_parse_tuple(&tuple, &parse); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, GetTupleData, ret); goto exit0; } @@ -181,7 +180,7 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_request_io(link, &link->io); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, RequestIO, ret); goto exit0; } @@ -195,21 +194,21 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_get_first_tuple(link, &tuple); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, GetFirstTuple, ret); goto exit1; } ret = pcmcia_get_tuple_data(link, &tuple); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, GetTupleData, ret); goto exit1; } - ret = pcmcia_parse_tuple(link, &tuple, &parse); + ret = pcmcia_parse_tuple(&tuple, &parse); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, ParseTuple, ret); goto exit1; } @@ -227,7 +226,7 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_request_window(&link, &ipw->request_common_memory, &ipw->handle_common_memory); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, RequestWindow, ret); goto exit1; } @@ -239,7 +238,7 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_map_mem_page(ipw->handle_common_memory, &memreq_common_memory); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, MapMemPage, ret); goto exit1; } @@ -261,7 +260,7 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_request_window(&link, &ipw->request_attr_memory, &ipw->handle_attr_memory); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, RequestWindow, ret); goto exit2; } @@ -272,7 +271,7 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_map_mem_page(ipw->handle_attr_memory, &memreq_attr_memory); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, MapMemPage, ret); goto exit2; } @@ -292,20 +291,11 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_request_irq(link, &link->irq); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, RequestIRQ, ret); goto exit3; } - /* Look up current Vcc */ - - ret = pcmcia_get_configuration_info(link, &conf); - - if (ret != CS_SUCCESS) { - cs_error(link, GetConfigurationInfo, ret); - goto exit4; - } - printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n", ipw->is_v2_card ? "V2/V3" : "V1"); printk(KERN_INFO IPWIRELESS_PCCARD_NAME @@ -341,7 +331,7 @@ static int config_ipwireless(struct ipw_dev *ipw) */ ret = pcmcia_request_configuration(link, &link->conf); - if (ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, RequestConfiguration, ret); goto exit4; } diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index c240562c218..9a626e50b79 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -601,7 +601,7 @@ static int mgslpc_config(struct pcmcia_device *link) cfg = &(parse.cftable_entry); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse)); if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; if (cfg->index == 0) diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index ee6fc30d5e2..cb199c815b5 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -219,103 +219,91 @@ out_release: #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) +struct pcmcia_config_check { + unsigned long ctl_base; + int skip_vcc; + int is_kme; +}; + +static int pcmcia_check_one_config(struct pcmcia_device *pdev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + struct pcmcia_config_check *stk = priv_data; + + /* Check for matching Vcc, unless we're desperate */ + if (!stk->skip_vcc) { + if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) + return -ENODEV; + } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) + return -ENODEV; + } + } + + if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) + pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; + else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) + pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; + + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + pdev->conf.ConfigIndex = cfg->index; + pdev->io.BasePort1 = io->win[0].base; + pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + if (!(io->flags & CISTPL_IO_16BIT)) + pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + if (io->nwin == 2) { + pdev->io.NumPorts1 = 8; + pdev->io.BasePort2 = io->win[1].base; + pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1; + if (pcmcia_request_io(pdev, &pdev->io) != 0) + return -ENODEV; + stk->ctl_base = pdev->io.BasePort2; + } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { + pdev->io.NumPorts1 = io->win[0].len; + pdev->io.NumPorts2 = 0; + if (pcmcia_request_io(pdev, &pdev->io) != 0) + return -ENODEV; + stk->ctl_base = pdev->io.BasePort1 + 0x0e; + } else + return -ENODEV; + /* If we've got this far, we're done */ + return 0; + } + return -ENODEV; +} + static int ide_config(struct pcmcia_device *link) { ide_info_t *info = link->priv; - tuple_t tuple; - struct { - u_short buf[128]; - cisparse_t parse; - config_info_t conf; - cistpl_cftable_entry_t dflt; - } *stk = NULL; - cistpl_cftable_entry_t *cfg; - int pass, last_ret = 0, last_fn = 0, is_kme = 0; + struct pcmcia_config_check *stk = NULL; + int last_ret = 0, last_fn = 0, is_kme = 0; unsigned long io_base, ctl_base; struct ide_host *host; DEBUG(0, "ide_config(0x%p)\n", link); - stk = kzalloc(sizeof(*stk), GFP_KERNEL); - if (!stk) goto err_mem; - cfg = &stk->parse.cftable_entry; - - tuple.TupleData = (cisdata_t *)&stk->buf; - tuple.TupleOffset = 0; - tuple.TupleDataMax = 255; - tuple.Attributes = 0; - is_kme = ((link->manf_id == MANFID_KME) && ((link->card_id == PRODID_KME_KXLC005_A) || (link->card_id == PRODID_KME_KXLC005_B))); - /* Not sure if this is right... look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf)); - - 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++; - } + stk = kzalloc(sizeof(*stk), GFP_KERNEL); + if (!stk) + goto err_mem; + stk->is_kme = is_kme; + stk->skip_vcc = io_base = ctl_base = 0; + + if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) { + stk->skip_vcc = 1; + if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) + goto failed; /* No suitable config found */ } + io_base = link->io.BasePort1; + ctl_base = stk->ctl_base; CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); @@ -403,8 +391,10 @@ static struct pcmcia_device_id ide_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000), /* I-O Data CFA */ PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001), /* Mitsubishi CFA */ PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704), + PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904), PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */ PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000), /* Kingston */ + PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620), /* TI emulated */ PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */ PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d), PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */ diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index a5b941c327f..c72565520e4 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c @@ -154,83 +154,50 @@ static void avmcs_detach(struct pcmcia_device *link) ======================================================================*/ -static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, - cisparse_t *parse) +static int avmcs_configcheck(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cf, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) { - int i = pcmcia_get_tuple_data(handle, tuple); - if (i != CS_SUCCESS) return i; - return pcmcia_parse_tuple(handle, tuple, parse); -} - -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); + 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 "avm_cs: testing i/o %#x-%#x\n", + p_dev->io.BasePort1, + p_dev->io.BasePort1+p_dev->io.NumPorts1-1); + return pcmcia_request_io(p_dev, &p_dev->io); } static int avmcs_config(struct pcmcia_device *link) { - tuple_t tuple; - cisparse_t parse; - cistpl_cftable_entry_t *cf = &parse.cftable_entry; local_info_t *dev; int i; - u_char buf[64]; char devname[128]; int cardtype; int (*addcard)(unsigned int port, unsigned irq); dev = link->priv; - do { - devname[0] = 0; - if (link->prod_id[1]) - strlcpy(devname, link->prod_id[1], sizeof(devname)); + 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; - } + /* + * find IO port + */ + if (pcmcia_loop_config(link, avmcs_configcheck, NULL)) + return -ENODEV; + do { /* * allocate an interrupt line */ i = pcmcia_request_irq(link, &link->irq); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestIRQ, i); /* undo */ pcmcia_disable_device(link); @@ -241,7 +208,7 @@ found_port: * configure the PCMCIA socket */ i = pcmcia_request_configuration(link, &link->conf); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestConfiguration, i); pcmcia_disable_device(link); break; diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index fc6cc2c065b..23560c897ec 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c @@ -174,38 +174,29 @@ static void avma1cs_detach(struct pcmcia_device *link) ======================================================================*/ -static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, - cisparse_t *parse) +static int avma1cs_configcheck(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cf, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) { - int i = pcmcia_get_tuple_data(handle, tuple); - if (i != CS_SUCCESS) return i; - return pcmcia_parse_tuple(handle, tuple, parse); + if (cf->io.nwin <= 0) + return -ENODEV; + + p_dev->io.BasePort1 = cf->io.win[0].base; + p_dev->io.NumPorts1 = cf->io.win[0].len; + p_dev->io.NumPorts2 = 0; + printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n", + p_dev->io.BasePort1, + p_dev->io.BasePort1+p_dev->io.NumPorts1-1); + return pcmcia_request_io(p_dev, &p_dev->io); } -static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, - cisparse_t *parse) -{ - int i = pcmcia_get_first_tuple(handle, tuple); - if (i != CS_SUCCESS) return i; - return get_tuple(handle, tuple, parse); -} - -static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, - cisparse_t *parse) -{ - int i = pcmcia_get_next_tuple(handle, tuple); - if (i != CS_SUCCESS) return i; - return get_tuple(handle, tuple, parse); -} static int avma1cs_config(struct pcmcia_device *link) { - tuple_t tuple; - cisparse_t parse; - cistpl_cftable_entry_t *cf = &parse.cftable_entry; local_info_t *dev; int i; - u_char buf[64]; char devname[128]; IsdnCard_t icard; int busy = 0; @@ -214,45 +205,19 @@ static int avma1cs_config(struct pcmcia_device *link) DEBUG(0, "avma1cs_config(0x%p)\n", link); - do { - devname[0] = 0; - if (link->prod_id[1]) - strlcpy(devname, link->prod_id[1], sizeof(devname)); + 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); - } + if (pcmcia_loop_config(link, avma1cs_configcheck, NULL)) + return -ENODEV; -found_port: - if (i != CS_SUCCESS) { - cs_error(link, RequestIO, i); - break; - } - + do { /* * allocate an interrupt line */ i = pcmcia_request_irq(link, &link->irq); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestIRQ, i); /* undo */ pcmcia_disable_device(link); @@ -263,7 +228,7 @@ found_port: * configure the PCMCIA socket */ i = pcmcia_request_configuration(link, &link->conf); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestConfiguration, i); pcmcia_disable_device(link); break; diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index db7e64424af..f4d0fe29bcf 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -203,82 +203,55 @@ static void elsa_cs_detach(struct pcmcia_device *link) device available to the system. ======================================================================*/ -static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, - cisparse_t *parse) -{ - int i = pcmcia_get_tuple_data(handle, tuple); - if (i != CS_SUCCESS) return i; - return pcmcia_parse_tuple(handle, tuple, parse); -} - -static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, - cisparse_t *parse) -{ - 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) +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_next_tuple(handle, tuple); - if (i != CS_SUCCESS) return i; - return get_tuple(handle, tuple, parse); + int j; + + if ((cf->io.nwin > 0) && cf->io.win[0].base) { + printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); + p_dev->io.BasePort1 = cf->io.win[0].base; + if (!pcmcia_request_io(p_dev, &p_dev->io)) + return 0; + } else { + printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); + for (j = 0x2f0; j > 0x100; j -= 0x10) { + p_dev->io.BasePort1 = j; + if (!pcmcia_request_io(p_dev, &p_dev->io)) + return 0; + } + } + return -ENODEV; } static int elsa_cs_config(struct pcmcia_device *link) { - tuple_t tuple; - cisparse_t parse; local_info_t *dev; - int i, j, last_fn; - u_short buf[128]; - cistpl_cftable_entry_t *cf = &parse.cftable_entry; + int i, last_fn; IsdnCard_t icard; DEBUG(0, "elsa_config(0x%p)\n", link); dev = link->priv; - tuple.TupleData = (cisdata_t *)buf; - tuple.TupleOffset = 0; tuple.TupleDataMax = 255; - tuple.Attributes = 0; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - i = first_tuple(link, &tuple, &parse); - while (i == CS_SUCCESS) { - if ( (cf->io.nwin > 0) && cf->io.win[0].base) { - printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); - link->conf.ConfigIndex = cf->index; - link->io.BasePort1 = cf->io.win[0].base; - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) break; - } else { - printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); - link->conf.ConfigIndex = cf->index; - for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { - link->io.BasePort1 = j; - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) break; - } - break; - } - i = next_tuple(link, &tuple, &parse); - } - - if (i != CS_SUCCESS) { + i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL); + if (i != 0) { last_fn = RequestIO; goto cs_failed; } i = pcmcia_request_irq(link, &link->irq); - if (i != CS_SUCCESS) { + if (i != 0) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } i = pcmcia_request_configuration(link, &link->conf); - if (i != CS_SUCCESS) { + if (i != 0) { last_fn = RequestConfiguration; goto cs_failed; } diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 439cb530def..9a3c9f5e4fe 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -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; - - DEBUG(0, "sedlbauer_config(0x%p)\n", link); - - tuple.Attributes = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; + win_req_t *req = priv_data; - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); + if (cfg->index == 0) + return -ENODEV; - /* - 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; diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index ab4bd455450..623d111544d 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -193,82 +193,55 @@ static void teles_detach(struct pcmcia_device *link) device available to the system. ======================================================================*/ -static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, - cisparse_t *parse) -{ - int i = pcmcia_get_tuple_data(handle, tuple); - if (i != CS_SUCCESS) return i; - return pcmcia_parse_tuple(handle, tuple, parse); -} - -static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, - cisparse_t *parse) -{ - 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) +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_next_tuple(handle, tuple); - if (i != CS_SUCCESS) return i; - return get_tuple(handle, tuple, parse); + int j; + + if ((cf->io.nwin > 0) && cf->io.win[0].base) { + printk(KERN_INFO "(teles_cs: looks like the 96 model)\n"); + p_dev->io.BasePort1 = cf->io.win[0].base; + if (!pcmcia_request_io(p_dev, &p_dev->io)) + return 0; + } else { + printk(KERN_INFO "(teles_cs: looks like the 97 model)\n"); + for (j = 0x2f0; j > 0x100; j -= 0x10) { + p_dev->io.BasePort1 = j; + if (!pcmcia_request_io(p_dev, &p_dev->io)) + return 0; + } + } + return -ENODEV; } static int teles_cs_config(struct pcmcia_device *link) { - tuple_t tuple; - cisparse_t parse; local_info_t *dev; - int i, j, last_fn; - u_short buf[128]; - cistpl_cftable_entry_t *cf = &parse.cftable_entry; + int i, last_fn; IsdnCard_t icard; DEBUG(0, "teles_config(0x%p)\n", link); dev = link->priv; - tuple.TupleData = (cisdata_t *)buf; - tuple.TupleOffset = 0; tuple.TupleDataMax = 255; - tuple.Attributes = 0; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - i = first_tuple(link, &tuple, &parse); - while (i == CS_SUCCESS) { - if ( (cf->io.nwin > 0) && cf->io.win[0].base) { - printk(KERN_INFO "(teles_cs: looks like the 96 model)\n"); - link->conf.ConfigIndex = cf->index; - link->io.BasePort1 = cf->io.win[0].base; - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) break; - } else { - printk(KERN_INFO "(teles_cs: looks like the 97 model)\n"); - link->conf.ConfigIndex = cf->index; - for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { - link->io.BasePort1 = j; - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) break; - } - break; - } - i = next_tuple(link, &tuple, &parse); - } - - if (i != CS_SUCCESS) { + i = pcmcia_loop_config(link, teles_cs_configcheck, NULL); + if (i != 0) { last_fn = RequestIO; goto cs_failed; } i = pcmcia_request_irq(link, &link->irq); - if (i != CS_SUCCESS) { + if (i != 0) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } i = pcmcia_request_configuration(link, &link->conf); - if (i != CS_SUCCESS) { + if (i != 0) { last_fn = RequestConfiguration; goto cs_failed; } diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index 90924fb0048..d600c2deff7 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -118,7 +118,8 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x", dev->offset, mrq.CardOffset); mrq.Page = 0; - if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) { + ret = pcmcia_map_mem_page(win, &mrq); + if (ret != 0) { cs_error(dev->p_dev, MapMemPage, ret); return NULL; } @@ -326,9 +327,8 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on) DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp); ret = pcmcia_modify_configuration(link, &mod); - if(ret != CS_SUCCESS) { + if (ret != 0) cs_error(link, ModifyConfiguration, ret); - } } @@ -368,14 +368,14 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, tuple.DesiredTuple = RETURN_FIRST_TUPLE; rc = pcmcia_get_first_tuple(link, &tuple); - while(rc == CS_SUCCESS) { + while (rc == 0) { rc = pcmcia_get_tuple_data(link, &tuple); - if(rc != CS_SUCCESS) { + if (rc != 0) { cs_error(link, GetTupleData, rc); break; } - rc = pcmcia_parse_tuple(link, &tuple, &parse); - if(rc != CS_SUCCESS) { + rc = pcmcia_parse_tuple(&tuple, &parse); + if (rc != 0) { cs_error(link, ParseTuple, rc); break; } @@ -493,18 +493,11 @@ static int pcmciamtd_config(struct pcmcia_device *link) int last_ret = 0, last_fn = 0; int ret; int i; - config_info_t t; static char *probes[] = { "jedec_probe", "cfi_probe" }; int new_name = 0; DEBUG(3, "link=0x%p", link); - DEBUG(2, "Validating CIS"); - ret = pcmcia_validate_cis(link, NULL); - if(ret != CS_SUCCESS) { - cs_error(link, GetTupleData, ret); - } - card_settings(dev, link, &new_name); dev->pcmcia_map.phys = NO_XIP; @@ -571,10 +564,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) dev->pcmcia_map.map_priv_1 = (unsigned long)dev; dev->pcmcia_map.map_priv_2 = (unsigned long)link->win; - DEBUG(2, "Getting configuration"); - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &t)); - DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2); - dev->vpp = (vpp) ? vpp : t.Vpp1; + dev->vpp = (vpp) ? vpp : link->socket.socket.Vpp; link->conf.Attributes = 0; if(setvpp == 2) { link->conf.Vpp = dev->vpp; @@ -583,16 +573,10 @@ static int pcmciamtd_config(struct pcmcia_device *link) } link->conf.IntType = INT_MEMORY; - link->conf.ConfigBase = t.ConfigBase; - link->conf.Status = t.Status; - link->conf.Pin = t.Pin; - link->conf.Copy = t.Copy; - link->conf.ExtStatus = t.ExtStatus; link->conf.ConfigIndex = 0; - link->conf.Present = t.Present; DEBUG(2, "Setting Configuration"); ret = pcmcia_request_configuration(link, &link->conf); - if(ret != CS_SUCCESS) { + if (ret != 0) { cs_error(link, RequestConfiguration, ret); if (dev->win_base) { iounmap(dev->win_base); diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 7112fd5e0e1..08c4dd89607 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -355,9 +355,10 @@ static int tc574_config(struct pcmcia_device *link) for (i = j = 0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) break; + if (i == 0) + break; } - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestIO, i); goto failed; } @@ -377,7 +378,7 @@ static int tc574_config(struct pcmcia_device *link) tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.DesiredTuple = 0x88; - if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { + if (pcmcia_get_first_tuple(link, &tuple) == 0) { pcmcia_get_tuple_data(link, &tuple); for (i = 0; i < 3; i++) phys_addr[i] = htons(le16_to_cpu(buf[i])); diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 549a6455842..0b28d0d8ffa 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -278,9 +278,10 @@ static int tc589_config(struct pcmcia_device *link) if (multi && (j & 0x80)) continue; link->io.BasePort1 = j ^ 0x300; i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) break; + if (i == 0) + break; } - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestIO, i); goto failed; } @@ -295,7 +296,7 @@ static int tc589_config(struct pcmcia_device *link) /* The 3c589 has an extra EEPROM for configuration info, including the hardware address. The 3c562 puts the address in the CIS. */ tuple.DesiredTuple = 0x88; - if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { + if (pcmcia_get_first_tuple(link, &tuple) == 0) { pcmcia_get_tuple_data(link, &tuple); for (i = 0; i < 3; i++) phys_addr[i] = htons(le16_to_cpu(buf[i])); diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 52bf11b73c6..b37a498939a 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -262,7 +262,7 @@ static int try_io_port(struct pcmcia_device *link) if (link->io.NumPorts2 > 0) { /* for master/slave multifunction cards */ link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - link->irq.Attributes = + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; } } else { @@ -276,7 +276,8 @@ static int try_io_port(struct pcmcia_device *link) link->io.BasePort1 = j ^ 0x300; link->io.BasePort2 = (j ^ 0x300) + 0x10; ret = pcmcia_request_io(link, &link->io); - if (ret == CS_SUCCESS) return ret; + if (ret == 0) + return ret; } return ret; } else { @@ -284,59 +285,50 @@ static int try_io_port(struct pcmcia_device *link) } } +static int axnet_configcheck(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + int i; + cistpl_io_t *io = &cfg->io; + + if (cfg->index == 0 || cfg->io.nwin == 0) + return -ENODEV; + + p_dev->conf.ConfigIndex = 0x05; + /* For multifunction cards, by convention, we configure the + network function with window 0, and serial with window 1 */ + if (io->nwin > 1) { + i = (io->win[1].len > io->win[0].len); + p_dev->io.BasePort2 = io->win[1-i].base; + p_dev->io.NumPorts2 = io->win[1-i].len; + } else { + i = p_dev->io.NumPorts2 = 0; + } + p_dev->io.BasePort1 = io->win[i].base; + p_dev->io.NumPorts1 = io->win[i].len; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32) + return try_io_port(p_dev); + + return -ENODEV; +} + static int axnet_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; axnet_dev_t *info = PRIV(dev); - tuple_t tuple; - cisparse_t parse; int i, j, last_ret, last_fn; - u_short buf[64]; DECLARE_MAC_BUF(mac); DEBUG(0, "axnet_config(0x%p)\n", link); - tuple.Attributes = 0; - tuple.TupleData = (cisdata_t *)buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; - /* don't trust the CIS on this; Linksys got it wrong */ link->conf.Present = 0x63; - - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - while (last_ret == CS_SUCCESS) { - cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - cistpl_io_t *io = &(parse.cftable_entry.io); - - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0 || - cfg->index == 0 || cfg->io.nwin == 0) - goto next_entry; - - link->conf.ConfigIndex = 0x05; - /* For multifunction cards, by convention, we configure the - network function with window 0, and serial with window 1 */ - if (io->nwin > 1) { - i = (io->win[1].len > io->win[0].len); - link->io.BasePort2 = io->win[1-i].base; - link->io.NumPorts2 = io->win[1-i].len; - } else { - i = link->io.NumPorts2 = 0; - } - link->io.BasePort1 = io->win[i].base; - link->io.NumPorts1 = io->win[i].len; - link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) { - last_ret = try_io_port(link); - if (last_ret == CS_SUCCESS) break; - } - next_entry: - last_ret = pcmcia_get_next_tuple(link, &tuple); - } - if (last_ret != CS_SUCCESS) { + last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL); + if (last_ret != 0) { cs_error(link, RequestIO, last_ret); goto failed; } diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index ea9414c4d90..831090c7562 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c @@ -260,21 +260,21 @@ static int com20020_config(struct pcmcia_device *link) DEBUG(0, "com20020_config(0x%p)\n", link); DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1); - i = !CS_SUCCESS; + i = -ENODEV; if (!link->io.BasePort1) { for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10) { link->io.BasePort1 = ioaddr; i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) + if (i == 0) break; } } else i = pcmcia_request_io(link, &link->io); - if (i != CS_SUCCESS) + if (i != 0) { DEBUG(1,"arcnet: requestIO failed totally!\n"); goto failed; @@ -287,7 +287,7 @@ static int com20020_config(struct pcmcia_device *link) link->irq.AssignedIRQ, link->irq.IRQInfo1, link->irq.IRQInfo2); i = pcmcia_request_irq(link, &link->irq); - if (i != CS_SUCCESS) + if (i != 0) { DEBUG(1,"arcnet: requestIRQ failed totally!\n"); goto failed; diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index a550c9bd126..69d916daa7b 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -309,7 +309,8 @@ static int mfc_try_io_port(struct pcmcia_device *link) printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n"); } ret = pcmcia_request_io(link, &link->io); - if (ret == CS_SUCCESS) return ret; + if (ret == 0) + return ret; } return ret; } @@ -325,7 +326,7 @@ static int ungermann_try_io_port(struct pcmcia_device *link) for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) { link->io.BasePort1 = ioaddr; ret = pcmcia_request_io(link, &link->io); - if (ret == CS_SUCCESS) { + if (ret == 0) { /* calculate ConfigIndex value */ link->conf.ConfigIndex = ((link->io.BasePort1 & 0x0f0) >> 3) | 0x22; @@ -356,12 +357,12 @@ static int fmvj18x_config(struct pcmcia_device *link) tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_FUNCE; tuple.TupleOffset = 0; - if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { + if (pcmcia_get_first_tuple(link, &tuple) == 0) { /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse)); link->conf.ConfigIndex = parse.cftable_entry.index; switch (link->manf_id) { case MANFID_TDK: @@ -430,10 +431,10 @@ static int fmvj18x_config(struct pcmcia_device *link) link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT; ret = mfc_try_io_port(link); - if (ret != CS_SUCCESS) goto cs_failed; + if (ret != 0) goto cs_failed; } else if (cardtype == UNGERMANN) { ret = ungermann_try_io_port(link); - if (ret != CS_SUCCESS) goto cs_failed; + if (ret != 0) goto cs_failed; } else { CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); } @@ -565,7 +566,7 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id) req.Base = 0; req.Size = 0; req.AccessSpeed = 0; i = pcmcia_request_window(&link, &req, &link->win); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestWindow, i); return -1; } @@ -599,7 +600,7 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id) iounmap(base); j = pcmcia_release_window(link->win); - if (j != CS_SUCCESS) + if (j != 0) cs_error(link, ReleaseWindow, j); return (i != 0x200) ? 0 : -1; @@ -620,7 +621,7 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link) req.Base = 0; req.Size = 0; req.AccessSpeed = 0; i = pcmcia_request_window(&link, &req, &link->win); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestWindow, i); return -1; } @@ -642,7 +643,7 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link) iounmap(base); j = pcmcia_release_window(link->win); - if (j != CS_SUCCESS) + if (j != 0) cs_error(link, ReleaseWindow, j); return 0; diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index 4eafa4f42cf..cf3cca4642f 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c @@ -238,7 +238,7 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) /* Try PRIMARY card at 0xA20-0xA23 */ link->io.BasePort1 = 0xA20; i = pcmcia_request_io(link, &link->io); - if (i != CS_SUCCESS) { + if (i != 0) { /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */ link->io.BasePort1 = 0xA24; CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index cfcbea9b7e2..54df34f21c5 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -925,7 +925,7 @@ static void mace_tx_timeout(struct net_device *dev) printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name); #if RESET_ON_TIMEOUT printk("resetting card\n"); - pcmcia_reset_card(link, NULL); + pcmcia_reset_card(link->socket); #else /* #if RESET_ON_TIMEOUT */ printk("NOT resetting card\n"); #endif /* #if RESET_ON_TIMEOUT */ diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index ebc1ae6bcbe..e40d6301aa7 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -310,7 +310,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link) req.Base = 0; req.Size = 0; req.AccessSpeed = 0; i = pcmcia_request_window(&link, &req, &link->win); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestWindow, i); return NULL; } @@ -333,7 +333,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link) iounmap(virt); j = pcmcia_release_window(link->win); - if (j != CS_SUCCESS) + if (j != 0) cs_error(link, ReleaseWindow, j); return (i < NR_INFO) ? hw_info+i : NULL; } /* get_hwinfo */ @@ -504,7 +504,8 @@ static int try_io_port(struct pcmcia_device *link) link->io.BasePort1 = j ^ 0x300; link->io.BasePort2 = (j ^ 0x300) + 0x10; ret = pcmcia_request_io(link, &link->io); - if (ret == CS_SUCCESS) return ret; + if (ret == 0) + return ret; } return ret; } else { @@ -512,58 +513,53 @@ static int try_io_port(struct pcmcia_device *link) } } +static int pcnet_confcheck(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + int *has_shmem = priv_data; + int i; + cistpl_io_t *io = &cfg->io; + + if (cfg->index == 0 || cfg->io.nwin == 0) + return -EINVAL; + + /* For multifunction cards, by convention, we configure the + network function with window 0, and serial with window 1 */ + if (io->nwin > 1) { + i = (io->win[1].len > io->win[0].len); + p_dev->io.BasePort2 = io->win[1-i].base; + p_dev->io.NumPorts2 = io->win[1-i].len; + } else { + i = p_dev->io.NumPorts2 = 0; + } + + *has_shmem = ((cfg->mem.nwin == 1) && + (cfg->mem.win[0].len >= 0x4000)); + p_dev->io.BasePort1 = io->win[i].base; + p_dev->io.NumPorts1 = io->win[i].len; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32) + return try_io_port(p_dev); + + return 0; +} + static int pcnet_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; pcnet_dev_t *info = PRIV(dev); - tuple_t tuple; - cisparse_t parse; - int i, last_ret, last_fn, start_pg, stop_pg, cm_offset; + int last_ret, last_fn, start_pg, stop_pg, cm_offset; int has_shmem = 0; - u_short buf[64]; hw_info_t *local_hw_info; DECLARE_MAC_BUF(mac); DEBUG(0, "pcnet_config(0x%p)\n", link); - tuple.TupleData = (cisdata_t *)buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - while (last_ret == CS_SUCCESS) { - cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - cistpl_io_t *io = &(parse.cftable_entry.io); - - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0 || - cfg->index == 0 || cfg->io.nwin == 0) - goto next_entry; - - link->conf.ConfigIndex = cfg->index; - /* For multifunction cards, by convention, we configure the - network function with window 0, and serial with window 1 */ - if (io->nwin > 1) { - i = (io->win[1].len > io->win[0].len); - link->io.BasePort2 = io->win[1-i].base; - link->io.NumPorts2 = io->win[1-i].len; - } else { - i = link->io.NumPorts2 = 0; - } - has_shmem = ((cfg->mem.nwin == 1) && - (cfg->mem.win[0].len >= 0x4000)); - link->io.BasePort1 = io->win[i].base; - link->io.NumPorts1 = io->win[i].len; - link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) { - last_ret = try_io_port(link); - if (last_ret == CS_SUCCESS) break; - } - next_entry: - last_ret = pcmcia_get_next_tuple(link, &tuple); - } - if (last_ret != CS_SUCCESS) { + last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem); + if (last_ret) { cs_error(link, RequestIO, last_ret); goto failed; } diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 250eb1954c3..c74d6656d26 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -409,10 +409,13 @@ static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, { int i; - if ((i = pcmcia_get_first_tuple(handle, tuple)) != CS_SUCCESS || - (i = pcmcia_get_tuple_data(handle, tuple)) != CS_SUCCESS) + i = pcmcia_get_first_tuple(handle, tuple); + if (i != 0) return i; - return pcmcia_parse_tuple(handle, tuple, parse); + i = pcmcia_get_tuple_data(handle, tuple); + if (i != 0) + return i; + return pcmcia_parse_tuple(tuple, parse); } static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, @@ -420,10 +423,10 @@ static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, { int i; - if ((i = pcmcia_get_next_tuple(handle, tuple)) != CS_SUCCESS || - (i = pcmcia_get_tuple_data(handle, tuple)) != CS_SUCCESS) + if ((i = pcmcia_get_next_tuple(handle, tuple)) != 0 || + (i = pcmcia_get_tuple_data(handle, tuple)) != 0) return i; - return pcmcia_parse_tuple(handle, tuple, parse); + return pcmcia_parse_tuple(tuple, parse); } /*====================================================================== @@ -459,27 +462,36 @@ static int mhz_3288_power(struct pcmcia_device *link) return 0; } +static int mhz_mfc_config_check(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cf, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + int k; + p_dev->io.BasePort2 = cf->io.win[0].base; + for (k = 0; k < 0x400; k += 0x10) { + if (k & 0x80) + continue; + p_dev->io.BasePort1 = k ^ 0x300; + if (!pcmcia_request_io(p_dev, &p_dev->io)) + return 0; + } + return -ENODEV; +} + static int mhz_mfc_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); struct smc_cfg_mem *cfg_mem; - tuple_t *tuple; - cisparse_t *parse; - cistpl_cftable_entry_t *cf; - u_char *buf; win_req_t req; memreq_t mem; - int i, k; + int i; cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); if (!cfg_mem) - return CS_OUT_OF_RESOURCE; - - tuple = &cfg_mem->tuple; - parse = &cfg_mem->parse; - cf = &parse->cftable_entry; - buf = cfg_mem->buf; + return -ENOMEM; link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; @@ -489,27 +501,9 @@ static int mhz_mfc_config(struct pcmcia_device *link) link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts2 = 8; - tuple->Attributes = tuple->TupleOffset = 0; - tuple->TupleData = (cisdata_t *)buf; - tuple->TupleDataMax = 255; - tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; - - i = first_tuple(link, tuple, parse); /* The Megahertz combo cards have modem-like CIS entries, so we have to explicitly try a bunch of port combinations. */ - while (i == CS_SUCCESS) { - link->conf.ConfigIndex = cf->index; - link->io.BasePort2 = cf->io.win[0].base; - for (k = 0; k < 0x400; k += 0x10) { - if (k & 0x80) continue; - link->io.BasePort1 = k ^ 0x300; - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) break; - } - if (i == CS_SUCCESS) break; - i = next_tuple(link, tuple, parse); - } - if (i != CS_SUCCESS) + if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL)) goto free_cfg_mem; dev->base_addr = link->io.BasePort1; @@ -518,7 +512,7 @@ static int mhz_mfc_config(struct pcmcia_device *link) req.Base = req.Size = 0; req.AccessSpeed = 0; i = pcmcia_request_window(&link, &req, &link->win); - if (i != CS_SUCCESS) + if (i != 0) goto free_cfg_mem; smc->base = ioremap(req.Base, req.Size); mem.CardOffset = mem.Page = 0; @@ -526,14 +520,14 @@ static int mhz_mfc_config(struct pcmcia_device *link) mem.CardOffset = link->conf.ConfigBase; i = pcmcia_map_mem_page(link->win, &mem); - if ((i == CS_SUCCESS) + if ((i == 0) && (smc->manfid == MANFID_MEGAHERTZ) && (smc->cardid == PRODID_MEGAHERTZ_EM3288)) mhz_3288_power(link); free_cfg_mem: kfree(cfg_mem); - return i; + return -ENODEV; } static int mhz_setup(struct pcmcia_device *link) @@ -560,12 +554,12 @@ static int mhz_setup(struct pcmcia_device *link) /* Read the station address from the CIS. It is stored as the last (fourth) string in the Version 1 Version/ID tuple. */ tuple->DesiredTuple = CISTPL_VERS_1; - if (first_tuple(link, tuple, parse) != CS_SUCCESS) { + if (first_tuple(link, tuple, parse) != 0) { rc = -1; goto free_cfg_mem; } /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ - if (next_tuple(link, tuple, parse) != CS_SUCCESS) + if (next_tuple(link, tuple, parse) != 0) first_tuple(link, tuple, parse); if (parse->version_1.ns > 3) { station_addr = parse->version_1.str + parse->version_1.ofs[3]; @@ -577,11 +571,11 @@ static int mhz_setup(struct pcmcia_device *link) /* Another possibility: for the EM3288, in a special tuple */ tuple->DesiredTuple = 0x81; - if (pcmcia_get_first_tuple(link, tuple) != CS_SUCCESS) { + if (pcmcia_get_first_tuple(link, tuple) != 0) { rc = -1; goto free_cfg_mem; } - if (pcmcia_get_tuple_data(link, tuple) != CS_SUCCESS) { + if (pcmcia_get_tuple_data(link, tuple) != 0) { rc = -1; goto free_cfg_mem; } @@ -660,46 +654,27 @@ static int mot_setup(struct pcmcia_device *link) /*====================================================================*/ +static int smc_configcheck(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cf, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + p_dev->io.BasePort1 = cf->io.win[0].base; + p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; + return pcmcia_request_io(p_dev, &p_dev->io); +} + static int smc_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; - struct smc_cfg_mem *cfg_mem; - tuple_t *tuple; - cisparse_t *parse; - cistpl_cftable_entry_t *cf; - u_char *buf; int i; - cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); - if (!cfg_mem) - return CS_OUT_OF_RESOURCE; - - tuple = &cfg_mem->tuple; - parse = &cfg_mem->parse; - cf = &parse->cftable_entry; - buf = cfg_mem->buf; - - tuple->Attributes = tuple->TupleOffset = 0; - tuple->TupleData = (cisdata_t *)buf; - tuple->TupleDataMax = 255; - tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; - link->io.NumPorts1 = 16; - i = first_tuple(link, tuple, parse); - while (i != CS_NO_MORE_ITEMS) { - if (i == CS_SUCCESS) { - link->conf.ConfigIndex = cf->index; - link->io.BasePort1 = cf->io.win[0].base; - link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) break; - } - i = next_tuple(link, tuple, parse); - } - if (i == CS_SUCCESS) - dev->base_addr = link->io.BasePort1; + i = pcmcia_loop_config(link, smc_configcheck, NULL); + if (!i) + dev->base_addr = link->io.BasePort1; - kfree(cfg_mem); return i; } @@ -715,7 +690,7 @@ static int smc_setup(struct pcmcia_device *link) cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); if (!cfg_mem) - return CS_OUT_OF_RESOURCE; + return -ENOMEM; tuple = &cfg_mem->tuple; parse = &cfg_mem->parse; @@ -728,12 +703,12 @@ static int smc_setup(struct pcmcia_device *link) /* Check for a LAN function extension tuple */ tuple->DesiredTuple = CISTPL_FUNCE; i = first_tuple(link, tuple, parse); - while (i == CS_SUCCESS) { + while (i == 0) { if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID) break; i = next_tuple(link, tuple, parse); } - if (i == CS_SUCCESS) { + if (i == 0) { node_id = (cistpl_lan_node_id_t *)parse->funce.data; if (node_id->nb == 6) { for (i = 0; i < 6; i++) @@ -780,9 +755,10 @@ static int osi_config(struct pcmcia_device *link) for (i = j = 0; j < 4; j++) { link->io.BasePort2 = com[j]; i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) break; + if (i == 0) + break; } - if (i != CS_SUCCESS) { + if (i != 0) { /* Fallback: turn off hard decode */ link->conf.ConfigIndex = 0x03; link->io.NumPorts2 = 0; @@ -815,13 +791,13 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid) /* Read the station address from tuple 0x90, subtuple 0x04 */ tuple->DesiredTuple = 0x90; i = pcmcia_get_first_tuple(link, tuple); - while (i == CS_SUCCESS) { + while (i == 0) { i = pcmcia_get_tuple_data(link, tuple); - if ((i != CS_SUCCESS) || (buf[0] == 0x04)) + if ((i != 0) || (buf[0] == 0x04)) break; i = pcmcia_get_next_tuple(link, tuple); } - if (i != CS_SUCCESS) { + if (i != 0) { rc = -1; goto free_cfg_mem; } @@ -959,8 +935,11 @@ static int check_sig(struct pcmcia_device *link) ======================================================================*/ -#define CS_EXIT_TEST(ret, svc, label) \ -if (ret != CS_SUCCESS) { cs_error(link, svc, ret); goto label; } +#define CS_EXIT_TEST(ret, svc, label) \ +if (ret != 0) { \ + cs_error(link, svc, ret); \ + goto label; \ +} static int smc91c92_config(struct pcmcia_device *link) { diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index c33a3d52356..e1fd585e713 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -377,7 +377,7 @@ first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 && (err = pcmcia_get_tuple_data(handle, tuple)) == 0) - err = pcmcia_parse_tuple(handle, tuple, parse); + err = pcmcia_parse_tuple(tuple, parse); return err; } @@ -388,7 +388,7 @@ next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 && (err = pcmcia_get_tuple_data(handle, tuple)) == 0) - err = pcmcia_parse_tuple(handle, tuple, parse); + err = pcmcia_parse_tuple(tuple, parse); return err; } @@ -715,6 +715,47 @@ has_ce2_string(struct pcmcia_device * p_dev) return 0; } +static int +xirc2ps_config_modem(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cf, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + unsigned int ioaddr; + + if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { + for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { + p_dev->io.BasePort2 = cf->io.win[0].base; + p_dev->io.BasePort1 = ioaddr; + if (!pcmcia_request_io(p_dev, &p_dev->io)) + return 0; + } + } + return -ENODEV; +} + +static int +xirc2ps_config_check(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cf, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + int *pass = priv_data; + + if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { + p_dev->io.BasePort2 = cf->io.win[0].base; + p_dev->io.BasePort1 = p_dev->io.BasePort2 + + (*pass ? (cf->index & 0x20 ? -24:8) + : (cf->index & 0x20 ? 8:-24)); + if (!pcmcia_request_io(p_dev, &p_dev->io)) + return 0; + } + return -ENODEV; + +} + /**************** * xirc2ps_config() is scheduled to run after a CARD_INSERTION event * is received, to configure the PCMCIA socket, and to make the @@ -725,13 +766,12 @@ xirc2ps_config(struct pcmcia_device * link) { struct net_device *dev = link->priv; local_info_t *local = netdev_priv(dev); + unsigned int ioaddr; tuple_t tuple; cisparse_t parse; - unsigned int ioaddr; int err, i; u_char buf[64]; cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data; - cistpl_cftable_entry_t *cf = &parse.cftable_entry; DECLARE_MAC_BUF(mac); local->dingo_ccr = NULL; @@ -846,19 +886,8 @@ xirc2ps_config(struct pcmcia_device * link) /* Take the Modem IO port from the CIS and scan for a free * Ethernet port */ link->io.NumPorts1 = 16; /* no Mako stuff anymore */ - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - for (err = first_tuple(link, &tuple, &parse); !err; - err = next_tuple(link, &tuple, &parse)) { - if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { - for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { - link->conf.ConfigIndex = cf->index ; - link->io.BasePort2 = cf->io.win[0].base; - link->io.BasePort1 = ioaddr; - if (!(err=pcmcia_request_io(link, &link->io))) - goto port_found; - } - } - } + if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL)) + goto port_found; } else { link->io.NumPorts1 = 18; /* We do 2 passes here: The first one uses the regular mapping and @@ -866,21 +895,9 @@ xirc2ps_config(struct pcmcia_device * link) * mirrored every 32 bytes. Actually we use a mirrored port for * the Mako if (on the first pass) the COR bit 5 is set. */ - for (pass=0; pass < 2; pass++) { - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - for (err = first_tuple(link, &tuple, &parse); !err; - err = next_tuple(link, &tuple, &parse)){ - if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8){ - link->conf.ConfigIndex = cf->index ; - link->io.BasePort2 = cf->io.win[0].base; - link->io.BasePort1 = link->io.BasePort2 - + (pass ? (cf->index & 0x20 ? -24:8) - : (cf->index & 0x20 ? 8:-24)); - if (!(err=pcmcia_request_io(link, &link->io))) + for (pass=0; pass < 2; pass++) + if (!pcmcia_loop_config(link, xirc2ps_config_check, &pass)) goto port_found; - } - } - } /* if special option: * try to configure as Ethernet only. * .... */ diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index fd72e427cb2..27696c20f4c 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c @@ -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. + */ + last_ret = pcmcia_loop_config(link, airo_cs_config_check, req); + if (last_ret) + goto failed; + /* - 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. + 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 */ diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index d2388e8d179..77406245dc7 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -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; } diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c index b8aa16307f7..3cfc30307a2 100644 --- a/drivers/net/wireless/b43/pcmcia.c +++ b/drivers/net/wireless/b43/pcmcia.c @@ -82,13 +82,13 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) tuple.TupleOffset = 0; res = pcmcia_get_first_tuple(dev, &tuple); - if (res != CS_SUCCESS) + if (res != 0) goto err_kfree_ssb; res = pcmcia_get_tuple_data(dev, &tuple); - if (res != CS_SUCCESS) + if (res != 0) goto err_kfree_ssb; - res = pcmcia_parse_tuple(dev, &tuple, &parse); - if (res != CS_SUCCESS) + res = pcmcia_parse_tuple(&tuple, &parse); + if (res != 0) goto err_kfree_ssb; dev->conf.ConfigBase = parse.config.base; @@ -107,13 +107,13 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) win.Size = SSB_CORE_SIZE; win.AccessSpeed = 250; res = pcmcia_request_window(&dev, &win, &dev->win); - if (res != CS_SUCCESS) + if (res != 0) goto err_kfree_ssb; mem.CardOffset = 0; mem.Page = 0; res = pcmcia_map_mem_page(dev->win, &mem); - if (res != CS_SUCCESS) + if (res != 0) goto err_disable; dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; @@ -121,11 +121,11 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) dev->irq.Handler = NULL; /* The handler is registered later. */ dev->irq.Instance = NULL; res = pcmcia_request_irq(dev, &dev->irq); - if (res != CS_SUCCESS) + if (res != 0) goto err_disable; res = pcmcia_request_configuration(dev, &dev->conf); - if (res != CS_SUCCESS) + if (res != 0) goto err_disable; err = ssb_bus_pcmciabus_register(ssb, dev, win.Base); diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 3b4e55cf33c..63374027735 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -234,7 +234,7 @@ static void sandisk_set_iobase(local_info_t *local) reg.Value = hw_priv->link->io.BasePort1 & 0x00ff; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != CS_SUCCESS) { + if (res != 0) { printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -" " res=%d\n", res); } @@ -246,7 +246,7 @@ static void sandisk_set_iobase(local_info_t *local) reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != CS_SUCCESS) { + if (res != 0) { printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -" " res=%d\n", res); } @@ -305,7 +305,7 @@ static int sandisk_enable_wireless(struct net_device *dev) tuple.DesiredTuple = CISTPL_LONGLINK_MFC; if (pcmcia_get_first_tuple(hw_priv->link, &tuple) || pcmcia_get_tuple_data(hw_priv->link, &tuple) || - pcmcia_parse_tuple(hw_priv->link, &tuple, parse) || + pcmcia_parse_tuple(&tuple, parse) || parse->longlink_mfc.nfn < 2) { /* No multi-function links found */ ret = -ENODEV; @@ -322,7 +322,7 @@ static int sandisk_enable_wireless(struct net_device *dev) reg.Value = COR_SOFT_RESET; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != CS_SUCCESS) { + if (res != 0) { printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", dev->name, res); goto done; @@ -339,7 +339,7 @@ static int sandisk_enable_wireless(struct net_device *dev) reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != CS_SUCCESS) { + if (res != 0) { printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", dev->name, res); goto done; @@ -374,7 +374,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local) reg.Value = 0; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != CS_SUCCESS) { + if (res != 0) { printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n", res); return; @@ -386,7 +386,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local) reg.Value |= COR_SOFT_RESET; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != CS_SUCCESS) { + if (res != 0) { printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n", res); return; @@ -399,7 +399,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local) reg.Value |= COR_IREQ_ENA; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != CS_SUCCESS) { + if (res != 0) { printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n", res); return; @@ -433,7 +433,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Value = 0; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != CS_SUCCESS) { + if (res != 0) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 " "(%d)\n", res); return; @@ -446,7 +446,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Value |= COR_SOFT_RESET; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != CS_SUCCESS) { + if (res != 0) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 " "(%d)\n", res); return; @@ -460,7 +460,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Offset = CISREG_CCSR; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != CS_SUCCESS) { + if (res != 0) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 " "(%d)\n", res); return; @@ -472,7 +472,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr) reg.Value = old_cor & ~COR_SOFT_RESET; res = pcmcia_access_configuration_register(hw_priv->link, ®); - if (res != CS_SUCCESS) { + if (res != 0) { printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 " "(%d)\n", res); return; @@ -532,145 +532,118 @@ static void prism2_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -#define CFG_CHECK2(fn, retf) \ -do { int _ret = (retf); \ -if (_ret != 0) { \ - PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", _ret); \ - cs_error(link, fn, _ret); \ - goto next_entry; \ -} \ -} while (0) - /* run after a CARD_INSERTION event is received to configure the PCMCIA * socket and make the device available to the system */ + +static int prism2_config_check(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + if (cfg->index == 0) + return -ENODEV; + + PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X " + "(default 0x%02X)\n", cfg->index, dflt->index); + + /* Does this card need audio output? */ + if (cfg->flags & CISTPL_CFTABLE_AUDIO) { + p_dev->conf.Attributes |= CONF_ENABLE_SPKR; + p_dev->conf.Status = CCSR_AUDIO_ENA; + } + + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / + 10000 && !ignore_cis_vcc) { + PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping" + " this entry\n"); + return -ENODEV; + } + } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / + 10000 && !ignore_cis_vcc) { + PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch " + "- skipping this entry\n"); + return -ENODEV; + } + } + + if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) + p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; + else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) + p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; + + /* Do we need to allocate an interrupt? */ + if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + else if (!(p_dev->conf.Attributes & CONF_ENABLE_IRQ)) { + /* At least Compaq WL200 does not have IRQInfo1 set, + * but it does not work without interrupts.. */ + printk(KERN_WARNING "Config has no IRQ info, but trying to " + "enable IRQ anyway..\n"); + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + } + + /* IO window settings */ + PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d " + "dflt->io.nwin=%d\n", + cfg->io.nwin, dflt->io.nwin); + p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, " + "io.base=0x%04x, len=%d\n", io->flags, + io->win[0].base, io->win[0].len); + if (!(io->flags & CISTPL_IO_8BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = io->flags & + CISTPL_IO_LINES_MASK; + p_dev->io.BasePort1 = io->win[0].base; + p_dev->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + p_dev->io.Attributes2 = p_dev->io.Attributes1; + p_dev->io.BasePort2 = io->win[1].base; + p_dev->io.NumPorts2 = io->win[1].len; + } + } + + /* This reserves IO space but doesn't actually enable it */ + return pcmcia_request_io(p_dev, &p_dev->io); +} + static int prism2_config(struct pcmcia_device *link) { struct net_device *dev; struct hostap_interface *iface; local_info_t *local; int ret = 1; - tuple_t tuple; - cisparse_t *parse; int last_fn, last_ret; - u_char buf[64]; - config_info_t conf; - cistpl_cftable_entry_t dflt = { 0 }; struct hostap_cs_priv *hw_priv; PDEBUG(DEBUG_FLOW, "prism2_config()\n"); - parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL); hw_priv = kzalloc(sizeof(*hw_priv), GFP_KERNEL); - if (parse == NULL || hw_priv == NULL) { + if (hw_priv == NULL) { ret = -ENOMEM; goto failed; } - tuple.Attributes = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; - - CS_CHECK(GetConfigurationInfo, - pcmcia_get_configuration_info(link, &conf)); - /* Look for an appropriate configuration table entry in the CIS */ - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - for (;;) { - cistpl_cftable_entry_t *cfg = &(parse->cftable_entry); - CFG_CHECK2(GetTupleData, - pcmcia_get_tuple_data(link, &tuple)); - CFG_CHECK2(ParseTuple, - pcmcia_parse_tuple(link, &tuple, parse)); - - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) - dflt = *cfg; - if (cfg->index == 0) - goto next_entry; - link->conf.ConfigIndex = cfg->index; - PDEBUG(DEBUG_EXTRA, "Checking CFTABLE_ENTRY 0x%02X " - "(default 0x%02X)\n", cfg->index, dflt.index); - - /* Does this card need audio output? */ - if (cfg->flags & CISTPL_CFTABLE_AUDIO) { - link->conf.Attributes |= CONF_ENABLE_SPKR; - link->conf.Status = CCSR_AUDIO_ENA; - } - - /* Use power settings for Vcc and Vpp if present */ - /* Note that the CIS values need to be rescaled */ - if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / - 10000 && !ignore_cis_vcc) { - PDEBUG(DEBUG_EXTRA, " Vcc mismatch - skipping" - " this entry\n"); - goto next_entry; - } - } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / - 10000 && !ignore_cis_vcc) { - PDEBUG(DEBUG_EXTRA, " Vcc (default) mismatch " - "- skipping this entry\n"); - goto next_entry; - } - } - - if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = - cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; - else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = - dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; - - /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) - link->conf.Attributes |= CONF_ENABLE_IRQ; - else if (!(link->conf.Attributes & CONF_ENABLE_IRQ)) { - /* At least Compaq WL200 does not have IRQInfo1 set, - * but it does not work without interrupts.. */ - printk("Config has no IRQ info, but trying to enable " - "IRQ anyway..\n"); - link->conf.Attributes |= CONF_ENABLE_IRQ; - } - - /* IO window settings */ - PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d " - "dflt.io.nwin=%d\n", - cfg->io.nwin, dflt.io.nwin); - link->io.NumPorts1 = link->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, " - "io.base=0x%04x, len=%d\n", io->flags, - io->win[0].base, io->win[0].len); - if (!(io->flags & CISTPL_IO_8BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = io->flags & - CISTPL_IO_LINES_MASK; - link->io.BasePort1 = io->win[0].base; - link->io.NumPorts1 = io->win[0].len; - if (io->nwin > 1) { - link->io.Attributes2 = link->io.Attributes1; - link->io.BasePort2 = io->win[1].base; - link->io.NumPorts2 = io->win[1].len; - } - } - - /* This reserves IO space but doesn't actually enable it */ - CFG_CHECK2(RequestIO, - pcmcia_request_io(link, &link->io)); - - /* This configuration table entry is OK */ - break; - - next_entry: - CS_CHECK(GetNextTuple, - pcmcia_get_next_tuple(link, &tuple)); + last_ret = pcmcia_loop_config(link, prism2_config_check, NULL); + if (last_ret) { + if (!ignore_cis_vcc) + printk(KERN_ERR "GetNextTuple(): No matching " + "CIS configuration. Maybe you need the " + "ignore_cis_vcc=1 parameter.\n"); + cs_error(link, RequestIO, last_ret); + goto failed; } /* Need to allocate net_device before requesting IRQ handler */ @@ -738,14 +711,12 @@ static int prism2_config(struct pcmcia_device *link) if (ret == 0 && local->ddev) strcpy(hw_priv->node.dev_name, local->ddev->name); } - kfree(parse); return ret; cs_failed: cs_error(link, last_fn, last_ret); failed: - kfree(parse); kfree(hw_priv); prism2_release((u_long)link); return ret; diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index e3505c110af..842a08d1f10 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -791,7 +791,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev) tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; if ((ret = pcmcia_get_first_tuple(p_dev, &tuple)) != 0 || (ret = pcmcia_get_tuple_data(p_dev, &tuple)) != 0 || - (ret = pcmcia_parse_tuple(p_dev, &tuple, &parse)) != 0) + (ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) { lbs_pr_err("error in pcmcia_get_first_tuple etc\n"); goto out1; diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c index 25bae7933aa..a670f36b5f3 100644 --- a/drivers/net/wireless/netwave_cs.c +++ b/drivers/net/wireless/netwave_cs.c @@ -749,9 +749,10 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { for (i = j = 0x0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) break; + if (i == 0) + break; } - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestIO, i); goto failed; } diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c index 9eaa252c243..e585684e59a 100644 --- a/drivers/net/wireless/orinoco_cs.c +++ b/drivers/net/wireless/orinoco_cs.c @@ -80,7 +80,7 @@ orinoco_cs_hard_reset(struct orinoco_private *priv) /* We need atomic ops here, because we're not holding the lock */ set_bit(0, &card->hard_reset_in_progress); - err = pcmcia_reset_card(link, NULL); + err = pcmcia_reset_card(link->socket); if (err) return err; @@ -165,6 +165,70 @@ static void orinoco_cs_detach(struct pcmcia_device *link) last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \ } while (0) +static int orinoco_cs_config_check(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + if (cfg->index == 0) + goto next_entry; + + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) { + DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000); + if (!ignore_cis_vcc) + goto next_entry; + } + } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) { + DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000); + if (!ignore_cis_vcc) + goto next_entry; + } + } + + if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) + p_dev->conf.Vpp = + cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; + else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) + p_dev->conf.Vpp = + dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; + + /* Do we need to allocate an interrupt? */ + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->io.BasePort1 = io->win[0].base; + p_dev->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + p_dev->io.Attributes2 = p_dev->io.Attributes1; + p_dev->io.BasePort2 = io->win[1].base; + p_dev->io.NumPorts2 = io->win[1].len; + } + + /* This reserves IO space but doesn't actually enable it */ + if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + goto next_entry; + } + return 0; + +next_entry: + pcmcia_disable_device(p_dev); + return -ENODEV; +}; + static int orinoco_cs_config(struct pcmcia_device *link) { @@ -173,16 +237,8 @@ orinoco_cs_config(struct pcmcia_device *link) struct orinoco_pccard *card = priv->card; hermes_t *hw = &priv->hw; int last_fn, last_ret; - u_char buf[64]; - config_info_t conf; - tuple_t tuple; - cisparse_t parse; void __iomem *mem; - /* Look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, - pcmcia_get_configuration_info(link, &conf)); - /* * In this loop, we scan the CIS for configuration table * entries, each of which describes a valid card @@ -197,94 +253,14 @@ orinoco_cs_config(struct pcmcia_device *link) * and most client drivers will only use the CIS to fill in * implementation-defined details. */ - tuple.Attributes = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - while (1) { - cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - cistpl_cftable_entry_t dflt = { .index = 0 }; - - if ( (pcmcia_get_tuple_data(link, &tuple) != 0) - || (pcmcia_parse_tuple(link, &tuple, &parse) != 0)) - goto next_entry; - - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) - dflt = *cfg; - if (cfg->index == 0) - goto next_entry; - link->conf.ConfigIndex = cfg->index; - - /* Use power settings for Vcc and Vpp if present */ - /* Note that the CIS values need to be rescaled */ - if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) { - DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, cfg CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000); - if (!ignore_cis_vcc) - goto next_entry; - } - } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) { - DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, dflt CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000); - if(!ignore_cis_vcc) - goto next_entry; - } - } - - if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = - cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; - else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = - dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; - - /* Do we need to allocate an interrupt? */ - link->conf.Attributes |= CONF_ENABLE_IRQ; - - /* IO window settings */ - link->io.NumPorts1 = link->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { - cistpl_io_t *io = - (cfg->io.nwin) ? &cfg->io : &dflt.io; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - link->io.Attributes1 = - IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - link->io.Attributes1 = - IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = - io->flags & CISTPL_IO_LINES_MASK; - link->io.BasePort1 = io->win[0].base; - link->io.NumPorts1 = io->win[0].len; - if (io->nwin > 1) { - link->io.Attributes2 = - link->io.Attributes1; - link->io.BasePort2 = io->win[1].base; - link->io.NumPorts2 = io->win[1].len; - } - - /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link, &link->io) != 0) - goto next_entry; - } - - - /* If we got this far, we're cool! */ - - break; - - next_entry: - pcmcia_disable_device(link); - last_ret = pcmcia_get_next_tuple(link, &tuple); - if (last_ret == CS_NO_MORE_ITEMS) { + last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL); + if (last_ret) { + if (!ignore_cis_vcc) printk(KERN_ERR PFX "GetNextTuple(): No matching " "CIS configuration. Maybe you need the " "ignore_cis_vcc=1 parameter.\n"); - goto cs_failed; - } + cs_error(link, RequestIO, last_ret); + goto failed; } /* @@ -335,7 +311,6 @@ orinoco_cs_config(struct pcmcia_device *link) "0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id, link->irq.AssignedIRQ, link->io.BasePort1, link->io.BasePort1 + link->io.NumPorts1 - 1); - return 0; cs_failed: diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 44da0d19b5c..1404a571752 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -798,9 +798,9 @@ static void ray_release(struct pcmcia_device *link) iounmap(local->amem); /* Do bother checking to see if these succeed or not */ i = pcmcia_release_window(local->amem_handle); - if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i); + if ( i != 0 ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i); i = pcmcia_release_window(local->rmem_handle); - if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i); + if ( i != 0 ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i); pcmcia_disable_device(link); DEBUG(2,"ray_release ending\n"); diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c index 67b26d3c3cd..b0c71c3be46 100644 --- a/drivers/net/wireless/spectrum_cs.c +++ b/drivers/net/wireless/spectrum_cs.c @@ -235,6 +235,70 @@ static void spectrum_cs_detach(struct pcmcia_device *link) * device available to the system. */ +static int spectrum_cs_config_check(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + if (cfg->index == 0) + goto next_entry; + + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) { + DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000); + if (!ignore_cis_vcc) + goto next_entry; + } + } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) { + if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) { + DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n", vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000); + if (!ignore_cis_vcc) + goto next_entry; + } + } + + if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) + p_dev->conf.Vpp = + cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; + else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) + p_dev->conf.Vpp = + dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; + + /* Do we need to allocate an interrupt? */ + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(io->flags & CISTPL_IO_8BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(io->flags & CISTPL_IO_16BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->io.BasePort1 = io->win[0].base; + p_dev->io.NumPorts1 = io->win[0].len; + if (io->nwin > 1) { + p_dev->io.Attributes2 = p_dev->io.Attributes1; + p_dev->io.BasePort2 = io->win[1].base; + p_dev->io.NumPorts2 = io->win[1].len; + } + + /* This reserves IO space but doesn't actually enable it */ + if (pcmcia_request_io(p_dev, &p_dev->io) != 0) + goto next_entry; + } + return 0; + +next_entry: + pcmcia_disable_device(p_dev); + return -ENODEV; +}; + static int spectrum_cs_config(struct pcmcia_device *link) { @@ -243,16 +307,8 @@ spectrum_cs_config(struct pcmcia_device *link) struct orinoco_pccard *card = priv->card; hermes_t *hw = &priv->hw; int last_fn, last_ret; - u_char buf[64]; - config_info_t conf; - tuple_t tuple; - cisparse_t parse; void __iomem *mem; - /* Look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, - pcmcia_get_configuration_info(link, &conf)); - /* * In this loop, we scan the CIS for configuration table * entries, each of which describes a valid card @@ -267,94 +323,14 @@ spectrum_cs_config(struct pcmcia_device *link) * and most client drivers will only use the CIS to fill in * implementation-defined details. */ - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - tuple.Attributes = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - while (1) { - cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - cistpl_cftable_entry_t dflt = { .index = 0 }; - - if ( (pcmcia_get_tuple_data(link, &tuple) != 0) - || (pcmcia_parse_tuple(link, &tuple, &parse) != 0)) - goto next_entry; - - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) - dflt = *cfg; - if (cfg->index == 0) - goto next_entry; - link->conf.ConfigIndex = cfg->index; - - /* Use power settings for Vcc and Vpp if present */ - /* Note that the CIS values need to be rescaled */ - if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) { - DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000); - if (!ignore_cis_vcc) - goto next_entry; - } - } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { - if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) { - DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000); - if(!ignore_cis_vcc) - goto next_entry; - } - } - - if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = - cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; - else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = - dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; - - /* Do we need to allocate an interrupt? */ - link->conf.Attributes |= CONF_ENABLE_IRQ; - - /* IO window settings */ - link->io.NumPorts1 = link->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { - cistpl_io_t *io = - (cfg->io.nwin) ? &cfg->io : &dflt.io; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - link->io.Attributes1 = - IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - link->io.Attributes1 = - IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = - io->flags & CISTPL_IO_LINES_MASK; - link->io.BasePort1 = io->win[0].base; - link->io.NumPorts1 = io->win[0].len; - if (io->nwin > 1) { - link->io.Attributes2 = - link->io.Attributes1; - link->io.BasePort2 = io->win[1].base; - link->io.NumPorts2 = io->win[1].len; - } - - /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link, &link->io) != 0) - goto next_entry; - } - - - /* If we got this far, we're cool! */ - - break; - - next_entry: - pcmcia_disable_device(link); - last_ret = pcmcia_get_next_tuple(link, &tuple); - if (last_ret == CS_NO_MORE_ITEMS) { + last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL); + if (last_ret) { + if (!ignore_cis_vcc) printk(KERN_ERR PFX "GetNextTuple(): No matching " "CIS configuration. Maybe you need the " "ignore_cis_vcc=1 parameter.\n"); - goto cs_failed; - } + cs_error(link, RequestIO, last_ret); + goto failed; } /* diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index b5de38a9b79..e124b1d6267 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c @@ -3702,7 +3702,7 @@ wv_pcmcia_reset(struct net_device * dev) #endif i = pcmcia_access_configuration_register(link, ®); - if(i != CS_SUCCESS) + if (i != 0) { cs_error(link, AccessConfigurationRegister, i); return FALSE; @@ -3716,7 +3716,7 @@ wv_pcmcia_reset(struct net_device * dev) reg.Action = CS_WRITE; reg.Value = reg.Value | COR_SW_RESET; i = pcmcia_access_configuration_register(link, ®); - if(i != CS_SUCCESS) + if (i != 0) { cs_error(link, AccessConfigurationRegister, i); return FALSE; @@ -3725,7 +3725,7 @@ wv_pcmcia_reset(struct net_device * dev) reg.Action = CS_WRITE; reg.Value = COR_LEVEL_IRQ | COR_CONFIG; i = pcmcia_access_configuration_register(link, ®); - if(i != CS_SUCCESS) + if (i != 0) { cs_error(link, AccessConfigurationRegister, i); return FALSE; @@ -3903,7 +3903,7 @@ wv_pcmcia_config(struct pcmcia_device * link) do { i = pcmcia_request_io(link, &link->io); - if(i != CS_SUCCESS) + if (i != 0) { cs_error(link, RequestIO, i); break; @@ -3914,7 +3914,7 @@ wv_pcmcia_config(struct pcmcia_device * link) * actually assign a handler to the interrupt. */ i = pcmcia_request_irq(link, &link->irq); - if(i != CS_SUCCESS) + if (i != 0) { cs_error(link, RequestIRQ, i); break; @@ -3926,7 +3926,7 @@ wv_pcmcia_config(struct pcmcia_device * link) */ link->conf.ConfigIndex = 1; i = pcmcia_request_configuration(link, &link->conf); - if(i != CS_SUCCESS) + if (i != 0) { cs_error(link, RequestConfiguration, i); break; @@ -3942,7 +3942,7 @@ wv_pcmcia_config(struct pcmcia_device * link) req.Base = req.Size = 0; req.AccessSpeed = mem_speed; i = pcmcia_request_window(&link, &req, &link->win); - if(i != CS_SUCCESS) + if (i != 0) { cs_error(link, RequestWindow, i); break; @@ -3954,7 +3954,7 @@ wv_pcmcia_config(struct pcmcia_device * link) mem.CardOffset = 0; mem.Page = 0; i = pcmcia_map_mem_page(link->win, &mem); - if(i != CS_SUCCESS) + if (i != 0) { cs_error(link, MapMemPage, i); break; diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 74a5ad2f122..68789c6e1ce 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -1977,10 +1977,10 @@ static int wl3501_config(struct pcmcia_device *link) link->io.BasePort1 = j; link->io.BasePort2 = link->io.BasePort1 + 0x10; i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) + if (i == 0) break; } - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestIO, i); goto failed; } diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index 00e1d9620f7..b1899e9c1f6 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c @@ -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)); + + 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)); diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index a87902de8d3..74d1c906c5d 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile @@ -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 diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index 75e8f8505e4..fc1de46fd20 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c @@ -292,7 +292,7 @@ au1x00_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map) skt->spd_io[map->map] = speed; } - map->start=(ioaddr_t)(u32)skt->virt_io; + map->start=(unsigned int)(u32)skt->virt_io; map->stop=map->start+MAP_SIZE; return 0; diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h index a53ef590251..13a4fbc5871 100644 --- a/drivers/pcmcia/au1000_generic.h +++ b/drivers/pcmcia/au1000_generic.h @@ -116,7 +116,7 @@ struct au1000_pcmcia_socket { struct resource res_attr; void * virt_io; - ioaddr_t phys_io; + unsigned int phys_io; unsigned int phys_attr; unsigned int phys_mem; unsigned short speed_io, speed_attr, speed_mem; diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c index aa1cd4d3aa2..d6b4bd1db7d 100644 --- a/drivers/pcmcia/au1000_pb1x00.c +++ b/drivers/pcmcia/au1000_pb1x00.c @@ -37,7 +37,6 @@ #include <pcmcia/ss.h> #include <pcmcia/cistpl.h> #include <pcmcia/bus_ops.h> -#include "cs_internal.h" #include <asm/io.h> #include <asm/irq.h> diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c index 8a9b18cee84..9627390835c 100644 --- a/drivers/pcmcia/au1000_xxs1500.c +++ b/drivers/pcmcia/au1000_xxs1500.c @@ -41,7 +41,6 @@ #include <pcmcia/ss.h> #include <pcmcia/cistpl.h> #include <pcmcia/bus_ops.h> -#include "cs_internal.h" #include <asm/io.h> #include <asm/irq.h> diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index 911ca0e8dfc..db77e1f3309 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c @@ -238,7 +238,7 @@ int __ref cb_alloc(struct pcmcia_socket * s) pci_bus_add_devices(bus); s->irq.AssignedIRQ = s->pci_irq; - return CS_SUCCESS; + return 0; } void cb_free(struct pcmcia_socket * s) diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 65129b54eb0..dcce9f5d846 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -92,7 +92,8 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) { mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); if (mem->res == NULL) { - printk(KERN_NOTICE "cs: unable to map card memory!\n"); + dev_printk(KERN_NOTICE, &s->dev, + "cs: unable to map card memory!\n"); return NULL; } s->cis_virt = NULL; @@ -265,13 +266,13 @@ EXPORT_SYMBOL(pcmcia_write_cis_mem); ======================================================================*/ static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, - u_int len, void *ptr) + size_t len, void *ptr) { struct cis_cache_entry *cis; int ret; if (s->fake_cis) { - if (s->fake_cis_len > addr+len) + if (s->fake_cis_len >= addr+len) memcpy(ptr, s->fake_cis+addr, len); else memset(ptr, 0xff, len); @@ -351,7 +352,9 @@ int verify_cis_cache(struct pcmcia_socket *s) buf = kmalloc(256, GFP_KERNEL); if (buf == NULL) - return -1; + dev_printk(KERN_WARNING, &s->dev, + "no memory for verifying CIS\n"); + return -ENOMEM; list_for_each_entry(cis, &s->cis_cache, node) { int len = cis->len; @@ -380,18 +383,22 @@ int verify_cis_cache(struct pcmcia_socket *s) ======================================================================*/ -int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis) +int pcmcia_replace_cis(struct pcmcia_socket *s, + const u8 *data, const size_t len) { - kfree(s->fake_cis); - s->fake_cis = NULL; - if (cis->Length > CISTPL_MAX_CIS_SIZE) - return CS_BAD_SIZE; - s->fake_cis = kmalloc(cis->Length, GFP_KERNEL); - if (s->fake_cis == NULL) - return CS_OUT_OF_RESOURCE; - s->fake_cis_len = cis->Length; - memcpy(s->fake_cis, cis->Data, cis->Length); - return CS_SUCCESS; + if (len > CISTPL_MAX_CIS_SIZE) { + dev_printk(KERN_WARNING, &s->dev, "replacement CIS too big\n"); + return -EINVAL; + } + kfree(s->fake_cis); + s->fake_cis = kmalloc(len, GFP_KERNEL); + if (s->fake_cis == NULL) { + dev_printk(KERN_WARNING, &s->dev, "no memory to replace CIS\n"); + return -ENOMEM; + } + s->fake_cis_len = len; + memcpy(s->fake_cis, data, len); + return 0; } EXPORT_SYMBOL(pcmcia_replace_cis); @@ -418,9 +425,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *t int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple) { if (!s) - return CS_BAD_HANDLE; + return -EINVAL; if (!(s->state & SOCKET_PRESENT)) - return CS_NO_CARD; + return -ENODEV; tuple->TupleLink = tuple->Flags = 0; #ifdef CONFIG_CARDBUS if (s->state & SOCKET_CARDBUS) { @@ -440,10 +447,10 @@ int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple !(tuple->Attributes & TUPLE_RETURN_COMMON)) { cisdata_t req = tuple->DesiredTuple; tuple->DesiredTuple = CISTPL_LONGLINK_MFC; - if (pccard_get_next_tuple(s, function, tuple) == CS_SUCCESS) { + if (pccard_get_next_tuple(s, function, tuple) == 0) { tuple->DesiredTuple = CISTPL_LINKTARGET; - if (pccard_get_next_tuple(s, function, tuple) != CS_SUCCESS) - return CS_NO_MORE_ITEMS; + if (pccard_get_next_tuple(s, function, tuple) != 0) + return -ENOSPC; } else tuple->CISOffset = tuple->TupleLink = 0; tuple->DesiredTuple = req; @@ -498,9 +505,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ int ofs, i, attr; if (!s) - return CS_BAD_HANDLE; + return -EINVAL; if (!(s->state & SOCKET_PRESENT)) - return CS_NO_CARD; + return -ENODEV; link[1] = tuple->TupleLink; ofs = tuple->CISOffset + tuple->TupleLink; @@ -519,7 +526,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ /* End of chain? Follow long link if possible */ if (link[0] == CISTPL_END) { if ((ofs = follow_link(s, tuple)) < 0) - return CS_NO_MORE_ITEMS; + return -ENOSPC; attr = SPACE(tuple->Flags); read_cis_cache(s, attr, ofs, 2, link); } @@ -577,13 +584,13 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ } if (i == MAX_TUPLES) { cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n"); - return CS_NO_MORE_ITEMS; + return -ENOSPC; } tuple->TupleCode = link[0]; tuple->TupleLink = link[1]; tuple->CISOffset = ofs + 2; - return CS_SUCCESS; + return 0; } EXPORT_SYMBOL(pccard_get_next_tuple); @@ -596,18 +603,18 @@ int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple) u_int len; if (!s) - return CS_BAD_HANDLE; + return -EINVAL; if (tuple->TupleLink < tuple->TupleOffset) - return CS_NO_MORE_ITEMS; + return -ENOSPC; len = tuple->TupleLink - tuple->TupleOffset; tuple->TupleDataLen = tuple->TupleLink; if (len == 0) - return CS_SUCCESS; + return 0; read_cis_cache(s, SPACE(tuple->Flags), tuple->CISOffset + tuple->TupleOffset, _MIN(len, tuple->TupleDataMax), tuple->TupleData); - return CS_SUCCESS; + return 0; } EXPORT_SYMBOL(pccard_get_tuple_data); @@ -640,25 +647,31 @@ static int parse_device(tuple_t *tuple, cistpl_device_t *device) case 3: device->dev[i].speed = 150; break; case 4: device->dev[i].speed = 100; break; case 7: - if (++p == q) return CS_BAD_TUPLE; + if (++p == q) + return -EINVAL; device->dev[i].speed = SPEED_CVT(*p); while (*p & 0x80) - if (++p == q) return CS_BAD_TUPLE; + if (++p == q) + return -EINVAL; break; default: - return CS_BAD_TUPLE; + return -EINVAL; } - if (++p == q) return CS_BAD_TUPLE; - if (*p == 0xff) break; + if (++p == q) + return -EINVAL; + if (*p == 0xff) + break; scale = *p & 7; - if (scale == 7) return CS_BAD_TUPLE; + if (scale == 7) + return -EINVAL; device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2)); device->ndev++; - if (++p == q) break; + if (++p == q) + break; } - return CS_SUCCESS; + return 0; } /*====================================================================*/ @@ -667,12 +680,12 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum) { u_char *p; if (tuple->TupleDataLen < 5) - return CS_BAD_TUPLE; + return -EINVAL; p = (u_char *) tuple->TupleData; csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2; csum->len = get_unaligned_le16(p + 2); csum->sum = *(p + 4); - return CS_SUCCESS; + return 0; } /*====================================================================*/ @@ -680,9 +693,9 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum) static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link) { if (tuple->TupleDataLen < 4) - return CS_BAD_TUPLE; + return -EINVAL; link->addr = get_unaligned_le32(tuple->TupleData); - return CS_SUCCESS; + return 0; } /*====================================================================*/ @@ -697,13 +710,13 @@ static int parse_longlink_mfc(tuple_t *tuple, link->nfn = *p; p++; if (tuple->TupleDataLen <= link->nfn*5) - return CS_BAD_TUPLE; + return -EINVAL; for (i = 0; i < link->nfn; i++) { link->fn[i].space = *p; p++; link->fn[i].addr = get_unaligned_le32(p); p += 4; } - return CS_SUCCESS; + return 0; } /*====================================================================*/ @@ -713,24 +726,27 @@ static int parse_strings(u_char *p, u_char *q, int max, { int i, j, ns; - if (p == q) return CS_BAD_TUPLE; + if (p == q) + return -EINVAL; ns = 0; j = 0; for (i = 0; i < max; i++) { - if (*p == 0xff) break; + if (*p == 0xff) + break; ofs[i] = j; ns++; for (;;) { s[j++] = (*p == 0xff) ? '\0' : *p; if ((*p == '\0') || (*p == 0xff)) break; - if (++p == q) return CS_BAD_TUPLE; + if (++p == q) + return -EINVAL; } if ((*p == 0xff) || (++p == q)) break; } if (found) { *found = ns; - return CS_SUCCESS; + return 0; } else { - return (ns == max) ? CS_SUCCESS : CS_BAD_TUPLE; + return (ns == max) ? 0 : -EINVAL; } } @@ -745,7 +761,8 @@ static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1) vers_1->major = *p; p++; vers_1->minor = *p; p++; - if (p >= q) return CS_BAD_TUPLE; + if (p >= q) + return -EINVAL; return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS, vers_1->str, vers_1->ofs, &vers_1->ns); @@ -781,7 +798,7 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec) p += 2; } jedec->nid = nid; - return CS_SUCCESS; + return 0; } /*====================================================================*/ @@ -789,10 +806,10 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec) static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m) { if (tuple->TupleDataLen < 4) - return CS_BAD_TUPLE; + return -EINVAL; m->manf = get_unaligned_le16(tuple->TupleData); m->card = get_unaligned_le16(tuple->TupleData + 2); - return CS_SUCCESS; + return 0; } /*====================================================================*/ @@ -801,11 +818,11 @@ static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f) { u_char *p; if (tuple->TupleDataLen < 2) - return CS_BAD_TUPLE; + return -EINVAL; p = (u_char *)tuple->TupleData; f->func = p[0]; f->sysinit = p[1]; - return CS_SUCCESS; + return 0; } /*====================================================================*/ @@ -815,12 +832,12 @@ static int parse_funce(tuple_t *tuple, cistpl_funce_t *f) u_char *p; int i; if (tuple->TupleDataLen < 1) - return CS_BAD_TUPLE; + return -EINVAL; p = (u_char *)tuple->TupleData; f->type = p[0]; for (i = 1; i < tuple->TupleDataLen; i++) f->data[i-1] = p[i]; - return CS_SUCCESS; + return 0; } /*====================================================================*/ @@ -834,7 +851,7 @@ static int parse_config(tuple_t *tuple, cistpl_config_t *config) rasz = *p & 0x03; rmsz = (*p & 0x3c) >> 2; if (tuple->TupleDataLen < rasz+rmsz+4) - return CS_BAD_TUPLE; + return -EINVAL; config->last_idx = *(++p); p++; config->base = 0; @@ -846,7 +863,7 @@ static int parse_config(tuple_t *tuple, cistpl_config_t *config) for (i = 0; i <= rmsz; i++) config->rmask[i>>2] += p[i] << (8*(i%4)); config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4); - return CS_SUCCESS; + return 0; } /*====================================================================== @@ -1002,10 +1019,12 @@ static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem) static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq) { - if (p == q) return NULL; + if (p == q) + return NULL; irq->IRQInfo1 = *p; p++; if (irq->IRQInfo1 & IRQ_INFO2_VALID) { - if (p+2 > q) return NULL; + if (p+2 > q) + return NULL; irq->IRQInfo2 = (p[1]<<8) + p[0]; p += 2; } @@ -1026,7 +1045,8 @@ static int parse_cftable_entry(tuple_t *tuple, if (*p & 0x40) entry->flags |= CISTPL_CFTABLE_DEFAULT; if (*p & 0x80) { - if (++p == q) return CS_BAD_TUPLE; + if (++p == q) + return -EINVAL; if (*p & 0x10) entry->flags |= CISTPL_CFTABLE_BVDS; if (*p & 0x20) @@ -1040,30 +1060,35 @@ static int parse_cftable_entry(tuple_t *tuple, entry->interface = 0; /* Process optional features */ - if (++p == q) return CS_BAD_TUPLE; + if (++p == q) + return -EINVAL; features = *p; p++; /* Power options */ if ((features & 3) > 0) { p = parse_power(p, q, &entry->vcc); - if (p == NULL) return CS_BAD_TUPLE; + if (p == NULL) + return -EINVAL; } else entry->vcc.present = 0; if ((features & 3) > 1) { p = parse_power(p, q, &entry->vpp1); - if (p == NULL) return CS_BAD_TUPLE; + if (p == NULL) + return -EINVAL; } else entry->vpp1.present = 0; if ((features & 3) > 2) { p = parse_power(p, q, &entry->vpp2); - if (p == NULL) return CS_BAD_TUPLE; + if (p == NULL) + return -EINVAL; } else entry->vpp2.present = 0; /* Timing options */ if (features & 0x04) { p = parse_timing(p, q, &entry->timing); - if (p == NULL) return CS_BAD_TUPLE; + if (p == NULL) + return -EINVAL; } else { entry->timing.wait = 0; entry->timing.ready = 0; @@ -1073,14 +1098,16 @@ static int parse_cftable_entry(tuple_t *tuple, /* I/O window options */ if (features & 0x08) { p = parse_io(p, q, &entry->io); - if (p == NULL) return CS_BAD_TUPLE; + if (p == NULL) + return -EINVAL; } else entry->io.nwin = 0; /* Interrupt options */ if (features & 0x10) { p = parse_irq(p, q, &entry->irq); - if (p == NULL) return CS_BAD_TUPLE; + if (p == NULL) + return -EINVAL; } else entry->irq.IRQInfo1 = 0; @@ -1094,7 +1121,8 @@ static int parse_cftable_entry(tuple_t *tuple, entry->mem.win[0].card_addr = 0; entry->mem.win[0].host_addr = 0; p += 2; - if (p > q) return CS_BAD_TUPLE; + if (p > q) + return -EINVAL; break; case 0x40: entry->mem.nwin = 1; @@ -1102,26 +1130,30 @@ static int parse_cftable_entry(tuple_t *tuple, entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8; entry->mem.win[0].host_addr = 0; p += 4; - if (p > q) return CS_BAD_TUPLE; + if (p > q) + return -EINVAL; break; case 0x60: p = parse_mem(p, q, &entry->mem); - if (p == NULL) return CS_BAD_TUPLE; + if (p == NULL) + return -EINVAL; break; } /* Misc features */ if (features & 0x80) { - if (p == q) return CS_BAD_TUPLE; + if (p == q) + return -EINVAL; entry->flags |= (*p << 8); while (*p & 0x80) - if (++p == q) return CS_BAD_TUPLE; + if (++p == q) + return -EINVAL; p++; } entry->subtuples = q-p; - return CS_SUCCESS; + return 0; } /*====================================================================*/ @@ -1132,12 +1164,12 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar) { u_char *p; if (tuple->TupleDataLen < 6) - return CS_BAD_TUPLE; + return -EINVAL; p = (u_char *)tuple->TupleData; bar->attr = *p; p += 2; bar->size = get_unaligned_le32(p); - return CS_SUCCESS; + return 0; } static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config) @@ -1146,12 +1178,12 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config) p = (u_char *)tuple->TupleData; if ((*p != 3) || (tuple->TupleDataLen < 6)) - return CS_BAD_TUPLE; + return -EINVAL; config->last_idx = *(++p); p++; config->base = get_unaligned_le32(p); config->subtuples = tuple->TupleDataLen - 6; - return CS_SUCCESS; + return 0; } static int parse_cftable_entry_cb(tuple_t *tuple, @@ -1167,29 +1199,34 @@ static int parse_cftable_entry_cb(tuple_t *tuple, entry->flags |= CISTPL_CFTABLE_DEFAULT; /* Process optional features */ - if (++p == q) return CS_BAD_TUPLE; + if (++p == q) + return -EINVAL; features = *p; p++; /* Power options */ if ((features & 3) > 0) { p = parse_power(p, q, &entry->vcc); - if (p == NULL) return CS_BAD_TUPLE; + if (p == NULL) + return -EINVAL; } else entry->vcc.present = 0; if ((features & 3) > 1) { p = parse_power(p, q, &entry->vpp1); - if (p == NULL) return CS_BAD_TUPLE; + if (p == NULL) + return -EINVAL; } else entry->vpp1.present = 0; if ((features & 3) > 2) { p = parse_power(p, q, &entry->vpp2); - if (p == NULL) return CS_BAD_TUPLE; + if (p == NULL) + return -EINVAL; } else entry->vpp2.present = 0; /* I/O window options */ if (features & 0x08) { - if (p == q) return CS_BAD_TUPLE; + if (p == q) + return -EINVAL; entry->io = *p; p++; } else entry->io = 0; @@ -1197,32 +1234,37 @@ static int parse_cftable_entry_cb(tuple_t *tuple, /* Interrupt options */ if (features & 0x10) { p = parse_irq(p, q, &entry->irq); - if (p == NULL) return CS_BAD_TUPLE; + if (p == NULL) + return -EINVAL; } else entry->irq.IRQInfo1 = 0; if (features & 0x20) { - if (p == q) return CS_BAD_TUPLE; + if (p == q) + return -EINVAL; entry->mem = *p; p++; } else entry->mem = 0; /* Misc features */ if (features & 0x80) { - if (p == q) return CS_BAD_TUPLE; + if (p == q) + return -EINVAL; entry->flags |= (*p << 8); if (*p & 0x80) { - if (++p == q) return CS_BAD_TUPLE; + if (++p == q) + return -EINVAL; entry->flags |= (*p << 16); } while (*p & 0x80) - if (++p == q) return CS_BAD_TUPLE; + if (++p == q) + return -EINVAL; p++; } entry->subtuples = q-p; - return CS_SUCCESS; + return 0; } #endif @@ -1248,7 +1290,7 @@ static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo) p += 6; } geo->ngeo = n; - return CS_SUCCESS; + return 0; } /*====================================================================*/ @@ -1258,7 +1300,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2) u_char *p, *q; if (tuple->TupleDataLen < 10) - return CS_BAD_TUPLE; + return -EINVAL; p = tuple->TupleData; q = p + tuple->TupleDataLen; @@ -1282,15 +1324,18 @@ static int parse_org(tuple_t *tuple, cistpl_org_t *org) p = tuple->TupleData; q = p + tuple->TupleDataLen; - if (p == q) return CS_BAD_TUPLE; + if (p == q) + return -EINVAL; org->data_org = *p; - if (++p == q) return CS_BAD_TUPLE; + if (++p == q) + return -EINVAL; for (i = 0; i < 30; i++) { org->desc[i] = *p; if (*p == '\0') break; - if (++p == q) return CS_BAD_TUPLE; + if (++p == q) + return -EINVAL; } - return CS_SUCCESS; + return 0; } /*====================================================================*/ @@ -1300,7 +1345,7 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt) u_char *p; if (tuple->TupleDataLen < 10) - return CS_BAD_TUPLE; + return -EINVAL; p = tuple->TupleData; @@ -1309,17 +1354,17 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt) fmt->offset = get_unaligned_le32(p + 2); fmt->length = get_unaligned_le32(p + 6); - return CS_SUCCESS; + return 0; } /*====================================================================*/ -int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse) +int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse) { - int ret = CS_SUCCESS; + int ret = 0; if (tuple->TupleDataLen > tuple->TupleDataMax) - return CS_BAD_TUPLE; + return -EINVAL; switch (tuple->TupleCode) { case CISTPL_DEVICE: case CISTPL_DEVICE_A: @@ -1387,15 +1432,17 @@ int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse) break; case CISTPL_NO_LINK: case CISTPL_LINKTARGET: - ret = CS_SUCCESS; + ret = 0; break; default: - ret = CS_UNSUPPORTED_FUNCTION; + ret = -EINVAL; break; } + if (ret) + __cs_dbg(0, "parse_tuple failed %d\n", ret); return ret; } -EXPORT_SYMBOL(pccard_parse_tuple); +EXPORT_SYMBOL(pcmcia_parse_tuple); /*====================================================================== @@ -1410,18 +1457,22 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t int ret; buf = kmalloc(256, GFP_KERNEL); - if (buf == NULL) - return CS_OUT_OF_RESOURCE; + if (buf == NULL) { + dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); + return -ENOMEM; + } tuple.DesiredTuple = code; tuple.Attributes = TUPLE_RETURN_COMMON; ret = pccard_get_first_tuple(s, function, &tuple); - if (ret != CS_SUCCESS) goto done; + if (ret != 0) + goto done; tuple.TupleData = buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; ret = pccard_get_tuple_data(s, &tuple); - if (ret != CS_SUCCESS) goto done; - ret = pccard_parse_tuple(&tuple, parse); + if (ret != 0) + goto done; + ret = pcmcia_parse_tuple(&tuple, parse); done: kfree(buf); return ret; @@ -1446,37 +1497,40 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned int ret, reserved, dev_ok = 0, ident_ok = 0; if (!s) - return CS_BAD_HANDLE; + return -EINVAL; tuple = kmalloc(sizeof(*tuple), GFP_KERNEL); - if (tuple == NULL) - return CS_OUT_OF_RESOURCE; + if (tuple == NULL) { + dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n"); + return -ENOMEM; + } p = kmalloc(sizeof(*p), GFP_KERNEL); if (p == NULL) { - kfree(tuple); - return CS_OUT_OF_RESOURCE; + kfree(tuple); + dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n"); + return -ENOMEM; } count = reserved = 0; tuple->DesiredTuple = RETURN_FIRST_TUPLE; tuple->Attributes = TUPLE_RETURN_COMMON; ret = pccard_get_first_tuple(s, function, tuple); - if (ret != CS_SUCCESS) + if (ret != 0) goto done; /* First tuple should be DEVICE; we should really have either that or a CFTABLE_ENTRY of some sort */ if ((tuple->TupleCode == CISTPL_DEVICE) || - (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == CS_SUCCESS) || - (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == CS_SUCCESS)) + (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == 0) || + (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == 0)) dev_ok++; /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2 tuple, for card identification. Certain old D-Link and Linksys cards have only a broken VERS_2 tuple; hence the bogus test. */ - if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == CS_SUCCESS) || - (pccard_read_tuple(s, function, CISTPL_VERS_1, p) == CS_SUCCESS) || - (pccard_read_tuple(s, function, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS)) + if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == 0) || + (pccard_read_tuple(s, function, CISTPL_VERS_1, p) == 0) || + (pccard_read_tuple(s, function, CISTPL_VERS_2, p) != -ENOSPC)) ident_ok++; if (!dev_ok && !ident_ok) @@ -1484,7 +1538,8 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned for (count = 1; count < MAX_TUPLES; count++) { ret = pccard_get_next_tuple(s, function, tuple); - if (ret != CS_SUCCESS) break; + if (ret != 0) + break; if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) || ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) || ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff))) @@ -1499,6 +1554,6 @@ done: *info = count; kfree(tuple); kfree(p); - return CS_SUCCESS; + return 0; } EXPORT_SYMBOL(pccard_validate_cis); diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index d1207393fc3..c68c5d33828 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -61,7 +61,7 @@ INT_MODULE_PARM(unreset_limit, 30); /* unreset_check's */ /* Access speed for attribute memory windows */ INT_MODULE_PARM(cis_speed, 300); /* ns */ -#ifdef DEBUG +#ifdef CONFIG_PCMCIA_DEBUG static int pc_debug; module_param(pc_debug, int, 0644); @@ -247,7 +247,8 @@ int pcmcia_register_socket(struct pcmcia_socket *socket) wait_for_completion(&socket->thread_done); if (!socket->thread) { - printk(KERN_WARNING "PCMCIA: warning: socket thread for socket %p did not start\n", socket); + dev_printk(KERN_WARNING, &socket->dev, + "PCMCIA: warning: socket thread did not start\n"); return -EIO; } @@ -366,16 +367,16 @@ static int socket_reset(struct pcmcia_socket *skt) skt->ops->get_status(skt, &status); if (!(status & SS_DETECT)) - return CS_NO_CARD; + return -ENODEV; if (status & SS_READY) - return CS_SUCCESS; + return 0; msleep(unreset_check * 10); } cs_err(skt, "time out after reset.\n"); - return CS_GENERAL_FAILURE; + return -ETIMEDOUT; } /* @@ -412,7 +413,8 @@ static void socket_shutdown(struct pcmcia_socket *s) s->ops->get_status(s, &status); if (status & SS_POWERON) { - printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s); + dev_printk(KERN_ERR, &s->dev, + "*** DANGER *** unable to remove socket power\n"); } cs_socket_put(s); @@ -426,14 +428,14 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay) skt->ops->get_status(skt, &status); if (!(status & SS_DETECT)) - return CS_NO_CARD; + return -ENODEV; msleep(initial_delay * 10); for (i = 0; i < 100; i++) { skt->ops->get_status(skt, &status); if (!(status & SS_DETECT)) - return CS_NO_CARD; + return -ENODEV; if (!(status & SS_PENDING)) break; @@ -443,13 +445,13 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay) if (status & SS_PENDING) { cs_err(skt, "voltage interrogation timed out.\n"); - return CS_GENERAL_FAILURE; + return -ETIMEDOUT; } if (status & SS_CARDBUS) { if (!(skt->features & SS_CAP_CARDBUS)) { cs_err(skt, "cardbus cards are not supported.\n"); - return CS_BAD_TYPE; + return -EINVAL; } skt->state |= SOCKET_CARDBUS; } @@ -463,7 +465,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay) skt->socket.Vcc = skt->socket.Vpp = 50; else { cs_err(skt, "unsupported voltage key.\n"); - return CS_BAD_TYPE; + return -EIO; } if (skt->power_hook) @@ -480,7 +482,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay) skt->ops->get_status(skt, &status); if (!(status & SS_POWERON)) { cs_err(skt, "unable to apply power.\n"); - return CS_BAD_TYPE; + return -EIO; } status = socket_reset(skt); @@ -502,15 +504,16 @@ static int socket_insert(struct pcmcia_socket *skt) cs_dbg(skt, 4, "insert\n"); if (!cs_socket_get(skt)) - return CS_NO_CARD; + return -ENODEV; ret = socket_setup(skt, setup_delay); - if (ret == CS_SUCCESS) { + if (ret == 0) { skt->state |= SOCKET_PRESENT; - printk(KERN_NOTICE "pccard: %s card inserted into slot %d\n", - (skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA", - skt->sock); + dev_printk(KERN_NOTICE, &skt->dev, + "pccard: %s card inserted into slot %d\n", + (skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA", + skt->sock); #ifdef CONFIG_CARDBUS if (skt->state & SOCKET_CARDBUS) { @@ -531,7 +534,7 @@ static int socket_insert(struct pcmcia_socket *skt) static int socket_suspend(struct pcmcia_socket *skt) { if (skt->state & SOCKET_SUSPEND) - return CS_IN_USE; + return -EBUSY; send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW); skt->socket = dead_socket; @@ -540,7 +543,7 @@ static int socket_suspend(struct pcmcia_socket *skt) skt->ops->suspend(skt); skt->state |= SOCKET_SUSPEND; - return CS_SUCCESS; + return 0; } /* @@ -553,7 +556,7 @@ static int socket_resume(struct pcmcia_socket *skt) int ret; if (!(skt->state & SOCKET_SUSPEND)) - return CS_IN_USE; + return -EBUSY; skt->socket = dead_socket; skt->ops->init(skt); @@ -565,7 +568,7 @@ static int socket_resume(struct pcmcia_socket *skt) } ret = socket_setup(skt, resume_delay); - if (ret == CS_SUCCESS) { + if (ret == 0) { /* * FIXME: need a better check here for cardbus cards. */ @@ -590,12 +593,13 @@ static int socket_resume(struct pcmcia_socket *skt) skt->state &= ~SOCKET_SUSPEND; - return CS_SUCCESS; + return 0; } static void socket_remove(struct pcmcia_socket *skt) { - printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock); + dev_printk(KERN_NOTICE, &skt->dev, + "pccard: card ejected from slot %d\n", skt->sock); socket_shutdown(skt); } @@ -641,8 +645,8 @@ static int pccardd(void *__skt) /* register with the device core */ ret = device_register(&skt->dev); if (ret) { - printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n", - skt); + dev_printk(KERN_WARNING, &skt->dev, + "PCMCIA: unable to register socket\n"); skt->thread = NULL; complete(&skt->thread_done); return 0; @@ -748,7 +752,7 @@ EXPORT_SYMBOL(pccard_register_pcmcia); * CIS register. */ -int pccard_reset_card(struct pcmcia_socket *skt) +int pcmcia_reset_card(struct pcmcia_socket *skt) { int ret; @@ -757,15 +761,15 @@ int pccard_reset_card(struct pcmcia_socket *skt) mutex_lock(&skt->skt_mutex); do { if (!(skt->state & SOCKET_PRESENT)) { - ret = CS_NO_CARD; + ret = -ENODEV; break; } if (skt->state & SOCKET_SUSPEND) { - ret = CS_IN_USE; + ret = -EBUSY; break; } if (skt->state & SOCKET_CARDBUS) { - ret = CS_UNSUPPORTED_FUNCTION; + ret = -EPERM; break; } @@ -774,20 +778,20 @@ int pccard_reset_card(struct pcmcia_socket *skt) send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW); if (skt->callback) skt->callback->suspend(skt); - if (socket_reset(skt) == CS_SUCCESS) { + if (socket_reset(skt) == 0) { send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW); if (skt->callback) skt->callback->resume(skt); } } - ret = CS_SUCCESS; + ret = 0; } while (0); mutex_unlock(&skt->skt_mutex); return ret; } /* reset_card */ -EXPORT_SYMBOL(pccard_reset_card); +EXPORT_SYMBOL(pcmcia_reset_card); /* These shut down or wake up a socket. They are sort of user @@ -802,11 +806,11 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt) mutex_lock(&skt->skt_mutex); do { if (!(skt->state & SOCKET_PRESENT)) { - ret = CS_NO_CARD; + ret = -ENODEV; break; } if (skt->state & SOCKET_CARDBUS) { - ret = CS_UNSUPPORTED_FUNCTION; + ret = -EPERM; break; } if (skt->callback) { @@ -832,11 +836,11 @@ int pcmcia_resume_card(struct pcmcia_socket *skt) mutex_lock(&skt->skt_mutex); do { if (!(skt->state & SOCKET_PRESENT)) { - ret = CS_NO_CARD; + ret = -ENODEV; break; } if (skt->state & SOCKET_CARDBUS) { - ret = CS_UNSUPPORTED_FUNCTION; + ret = -EPERM; break; } ret = socket_resume(skt); @@ -892,7 +896,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt) ret = -EBUSY; break; } - if (socket_insert(skt) == CS_NO_CARD) { + if (socket_insert(skt) == -ENODEV) { ret = -ENODEV; break; } diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 63dc1a28bda..79615e6d540 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -1,5 +1,5 @@ /* - * cs_internal.h + * cs_internal.h -- definitions internal to the PCMCIA core modules * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -10,6 +10,12 @@ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * (C) 1999 David A. Hinds + * (C) 2003 - 2008 Dominik Brodowski + * + * + * This file contains definitions _only_ needed by the PCMCIA core modules. + * It must not be included by PCMCIA socket drivers or by PCMCIA device + * drivers. */ #ifndef _LINUX_CS_INTERNAL_H @@ -18,29 +24,24 @@ #include <linux/kref.h> /* Flags in client state */ -#define CLIENT_CONFIG_LOCKED 0x0001 -#define CLIENT_IRQ_REQ 0x0002 -#define CLIENT_IO_REQ 0x0004 -#define CLIENT_UNBOUND 0x0008 -#define CLIENT_STALE 0x0010 #define CLIENT_WIN_REQ(i) (0x1<<(i)) -#define CLIENT_CARDBUS 0x8000 /* Each card function gets one of these guys */ typedef struct config_t { struct kref ref; - u_int state; - u_int Attributes; - u_int IntType; - u_int ConfigBase; - u_char Status, Pin, Copy, Option, ExtStatus; - u_int CardValues; - io_req_t io; - struct { - u_int Attributes; - } irq; + unsigned int state; + unsigned int Attributes; + unsigned int IntType; + unsigned int ConfigBase; + unsigned char Status, Pin, Copy, Option, ExtStatus; + unsigned int CardValues; + io_req_t io; + struct { + u_int Attributes; + } irq; } config_t; + struct cis_cache_entry { struct list_head node; unsigned int addr; @@ -49,6 +50,30 @@ struct cis_cache_entry { unsigned char cache[0]; }; +struct pccard_resource_ops { + int (*validate_mem) (struct pcmcia_socket *s); + int (*adjust_io_region) (struct resource *res, + unsigned long r_start, + unsigned long r_end, + struct pcmcia_socket *s); + struct resource* (*find_io) (unsigned long base, int num, + unsigned long align, + struct pcmcia_socket *s); + struct resource* (*find_mem) (unsigned long base, unsigned long num, + unsigned long align, int low, + struct pcmcia_socket *s); + int (*add_io) (struct pcmcia_socket *s, + unsigned int action, + unsigned long r_start, + unsigned long r_end); + int (*add_mem) (struct pcmcia_socket *s, + unsigned int action, + unsigned long r_start, + unsigned long r_end); + int (*init) (struct pcmcia_socket *s); + void (*exit) (struct pcmcia_socket *s); +}; + /* Flags in config state */ #define CONFIG_LOCKED 0x01 #define CONFIG_IRQ_REQ 0x02 @@ -59,7 +84,6 @@ struct cis_cache_entry { #define SOCKET_INUSE 0x0010 #define SOCKET_SUSPEND 0x0080 #define SOCKET_WIN_REQ(i) (0x0100<<(i)) -#define SOCKET_REGION_INFO 0x4000 #define SOCKET_CARDBUS 0x8000 #define SOCKET_CARDBUS_CONFIG 0x10000 @@ -83,69 +107,153 @@ static inline void cs_socket_put(struct pcmcia_socket *skt) } } -/* In cardbus.c */ -int cb_alloc(struct pcmcia_socket *s); -void cb_free(struct pcmcia_socket *s); -int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len, void *ptr); +#ifdef CONFIG_PCMCIA_DEBUG +extern int cs_debug_level(int); -/* In cistpl.c */ -int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, - u_int addr, u_int len, void *ptr); -void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, - u_int addr, u_int len, void *ptr); -void release_cis_mem(struct pcmcia_socket *s); -void destroy_cis_cache(struct pcmcia_socket *s); +#define cs_dbg(skt, lvl, fmt, arg...) do { \ + if (cs_debug_level(lvl)) \ + dev_printk(KERN_DEBUG, &skt->dev, \ + "cs: " fmt, ## arg); \ +} while (0) +#define __cs_dbg(lvl, fmt, arg...) do { \ + if (cs_debug_level(lvl)) \ + printk(KERN_DEBUG \ + "cs: " fmt, ## arg); \ +} while (0) + +#else +#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0) +#define __cs_dbg(lvl, fmt, arg...) do { } while (0) +#endif + +#define cs_err(skt, fmt, arg...) \ + dev_printk(KERN_ERR, &skt->dev, "cs: " fmt, ## arg) + + +/* + * Stuff internal to module "pcmcia_core": + */ + +/* cistpl.c */ int verify_cis_cache(struct pcmcia_socket *s); -int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse); -/* In rsrc_mgr */ -int pcmcia_validate_mem(struct pcmcia_socket *s); -struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align, - struct pcmcia_socket *s); -int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start, - unsigned long r_end, struct pcmcia_socket *s); -struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align, - int low, struct pcmcia_socket *s); +/* rsrc_mgr.c */ void release_resource_db(struct pcmcia_socket *s); -/* In socket_sysfs.c */ +/* socket_sysfs.c */ extern int pccard_sysfs_add_socket(struct device *dev); extern void pccard_sysfs_remove_socket(struct device *dev); -/* In cs.c */ -extern struct rw_semaphore pcmcia_socket_list_rwsem; -extern struct list_head pcmcia_socket_list; -int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req); -int pccard_get_configuration_info(struct pcmcia_socket *s, struct pcmcia_device *p_dev, config_info_t *config); -int pccard_reset_card(struct pcmcia_socket *skt); +/* cardbus.c */ +int cb_alloc(struct pcmcia_socket *s); +void cb_free(struct pcmcia_socket *s); +int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len, + void *ptr); + +/* + * Stuff exported by module "pcmcia_core" to module "pcmcia" + */ + struct pcmcia_callback{ struct module *owner; - int (*event) (struct pcmcia_socket *s, event_t event, int priority); + int (*event) (struct pcmcia_socket *s, + event_t event, int priority); void (*requery) (struct pcmcia_socket *s, int new_cis); int (*suspend) (struct pcmcia_socket *s); int (*resume) (struct pcmcia_socket *s); }; +/* cs.c */ +extern struct rw_semaphore pcmcia_socket_list_rwsem; +extern struct list_head pcmcia_socket_list; +extern struct class pcmcia_socket_class; + +int pcmcia_get_window(struct pcmcia_socket *s, + window_handle_t *handle, + int idx, + win_req_t *req); int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c); +struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr); -#define cs_socket_name(skt) ((skt)->dev.bus_id) +int pcmcia_suspend_card(struct pcmcia_socket *skt); +int pcmcia_resume_card(struct pcmcia_socket *skt); -#ifdef DEBUG -extern int cs_debug_level(int); +int pcmcia_eject_card(struct pcmcia_socket *skt); +int pcmcia_insert_card(struct pcmcia_socket *skt); -#define cs_dbg(skt, lvl, fmt, arg...) do { \ - if (cs_debug_level(lvl)) \ - printk(KERN_DEBUG "cs: %s: " fmt, \ - cs_socket_name(skt) , ## arg); \ -} while (0) +struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt); +void pcmcia_put_socket(struct pcmcia_socket *skt); -#else -#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0) -#endif +/* cistpl.c */ +int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, + u_int addr, u_int len, void *ptr); +void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, + u_int addr, u_int len, void *ptr); +void release_cis_mem(struct pcmcia_socket *s); +void destroy_cis_cache(struct pcmcia_socket *s); +int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, + cisdata_t code, void *parse); +int pcmcia_replace_cis(struct pcmcia_socket *s, + const u8 *data, const size_t len); +int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, + unsigned int *count); -#define cs_err(skt, fmt, arg...) \ - printk(KERN_ERR "cs: %s: " fmt, (skt)->dev.bus_id , ## arg) +/* rsrc_mgr.c */ +int pcmcia_validate_mem(struct pcmcia_socket *s); +struct resource *pcmcia_find_io_region(unsigned long base, + int num, + unsigned long align, + struct pcmcia_socket *s); +int pcmcia_adjust_io_region(struct resource *res, + unsigned long r_start, + unsigned long r_end, + struct pcmcia_socket *s); +struct resource *pcmcia_find_mem_region(u_long base, + u_long num, + u_long align, + int low, + struct pcmcia_socket *s); + +/* + * Stuff internal to module "pcmcia". + */ +/* ds.c */ +extern struct bus_type pcmcia_bus_type; + +/* pcmcia_resource.c */ +extern int pcmcia_release_configuration(struct pcmcia_device *p_dev); + +#ifdef CONFIG_PCMCIA_IOCTL +/* ds.c */ +extern spinlock_t pcmcia_dev_list_lock; + +extern struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev); +extern void pcmcia_put_dev(struct pcmcia_device *p_dev); + +struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, + unsigned int function); + +/* pcmcia_ioctl.c */ +extern void __init pcmcia_setup_ioctl(void); +extern void __exit pcmcia_cleanup_ioctl(void); +extern void handle_event(struct pcmcia_socket *s, event_t event); +extern int handle_request(struct pcmcia_socket *s, event_t event); + +#else /* CONFIG_PCMCIA_IOCTL */ + +static inline void __init pcmcia_setup_ioctl(void) { return; } +static inline void __exit pcmcia_cleanup_ioctl(void) { return; } +static inline void handle_event(struct pcmcia_socket *s, event_t event) +{ + return; +} +static inline int handle_request(struct pcmcia_socket *s, event_t event) +{ + return 0; +} + +#endif /* CONFIG_PCMCIA_IOCTL */ #endif /* _LINUX_CS_INTERNAL_H */ diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 34c83d3ca0f..79566025549 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -32,7 +32,6 @@ #include <pcmcia/ss.h> #include "cs_internal.h" -#include "ds_internal.h" /*====================================================================*/ @@ -42,17 +41,22 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>"); MODULE_DESCRIPTION("PCMCIA Driver Services"); MODULE_LICENSE("GPL"); -#ifdef DEBUG +#ifdef CONFIG_PCMCIA_DEBUG int ds_pc_debug; module_param_named(pc_debug, ds_pc_debug, int, 0644); #define ds_dbg(lvl, fmt, arg...) do { \ - if (ds_pc_debug > (lvl)) \ + if (ds_pc_debug > (lvl)) \ printk(KERN_DEBUG "ds: " fmt , ## arg); \ } while (0) +#define ds_dev_dbg(lvl, dev, fmt, arg...) do { \ + if (ds_pc_debug > (lvl)) \ + dev_printk(KERN_DEBUG, dev, "ds: " fmt , ## arg); \ +} while (0) #else #define ds_dbg(lvl, fmt, arg...) do { } while (0) +#define ds_dev_dbg(lvl, dev, fmt, arg...) do { } while (0) #endif spinlock_t pcmcia_dev_list_lock; @@ -64,42 +68,19 @@ spinlock_t pcmcia_dev_list_lock; /* String tables for error messages */ typedef struct lookup_t { - int key; - char *msg; + const int key; + const char *msg; } lookup_t; static const lookup_t error_table[] = { - { CS_SUCCESS, "Operation succeeded" }, - { CS_BAD_ADAPTER, "Bad adapter" }, - { CS_BAD_ATTRIBUTE, "Bad attribute", }, - { CS_BAD_BASE, "Bad base address" }, - { CS_BAD_EDC, "Bad EDC" }, - { CS_BAD_IRQ, "Bad IRQ" }, - { CS_BAD_OFFSET, "Bad offset" }, - { CS_BAD_PAGE, "Bad page number" }, - { CS_READ_FAILURE, "Read failure" }, - { CS_BAD_SIZE, "Bad size" }, - { CS_BAD_SOCKET, "Bad socket" }, - { CS_BAD_TYPE, "Bad type" }, - { CS_BAD_VCC, "Bad Vcc" }, - { CS_BAD_VPP, "Bad Vpp" }, - { CS_BAD_WINDOW, "Bad window" }, - { CS_WRITE_FAILURE, "Write failure" }, - { CS_NO_CARD, "No card present" }, - { CS_UNSUPPORTED_FUNCTION, "Usupported function" }, - { CS_UNSUPPORTED_MODE, "Unsupported mode" }, - { CS_BAD_SPEED, "Bad speed" }, - { CS_BUSY, "Resource busy" }, - { CS_GENERAL_FAILURE, "General failure" }, - { CS_WRITE_PROTECTED, "Write protected" }, - { CS_BAD_ARG_LENGTH, "Bad argument length" }, - { CS_BAD_ARGS, "Bad arguments" }, - { CS_CONFIGURATION_LOCKED, "Configuration locked" }, - { CS_IN_USE, "Resource in use" }, - { CS_NO_MORE_ITEMS, "No more items" }, - { CS_OUT_OF_RESOURCE, "Out of resource" }, - { CS_BAD_HANDLE, "Bad handle" }, - { CS_BAD_TUPLE, "Bad CIS tuple" } + { 0, "Operation succeeded" }, + { -EIO, "Input/Output error" }, + { -ENODEV, "No card present" }, + { -EINVAL, "Bad parameter" }, + { -EACCES, "Configuration locked" }, + { -EBUSY, "Resource in use" }, + { -ENOSPC, "No more items" }, + { -ENOMEM, "Out of resource" }, }; @@ -155,46 +136,32 @@ static const lookup_t service_table[] = { { ReplaceCIS, "ReplaceCIS" } }; - -static int pcmcia_report_error(struct pcmcia_device *p_dev, error_info_t *err) +const char *pcmcia_error_func(int func) { int i; - char *serv; - - if (!p_dev) - printk(KERN_NOTICE); - else - printk(KERN_NOTICE "%s: ", p_dev->dev.bus_id); for (i = 0; i < ARRAY_SIZE(service_table); i++) - if (service_table[i].key == err->func) - break; - if (i < ARRAY_SIZE(service_table)) - serv = service_table[i].msg; - else - serv = "Unknown service number"; + if (service_table[i].key == func) + return service_table[i].msg; - for (i = 0; i < ARRAY_SIZE(error_table); i++) - if (error_table[i].key == err->retcode) - break; - if (i < ARRAY_SIZE(error_table)) - printk("%s: %s\n", serv, error_table[i].msg); - else - printk("%s: Unknown error code %#x\n", serv, err->retcode); + return "Unknown service number"; +} +EXPORT_SYMBOL(pcmcia_error_func); - return CS_SUCCESS; -} /* report_error */ +const char *pcmcia_error_ret(int ret) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(error_table); i++) + if (error_table[i].key == ret) + return error_table[i].msg; -/* end of code which was in cs.c before */ + return "unknown"; +} +EXPORT_SYMBOL(pcmcia_error_ret); /*======================================================================*/ -void cs_error(struct pcmcia_device *p_dev, int func, int ret) -{ - error_info_t err = { func, ret }; - pcmcia_report_error(p_dev, &err); -} -EXPORT_SYMBOL(cs_error); static void pcmcia_check_driver(struct pcmcia_driver *p_drv) @@ -391,7 +358,7 @@ static void pcmcia_release_function(struct kref *ref) static void pcmcia_release_dev(struct device *dev) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); - ds_dbg(1, "releasing device %s\n", p_dev->dev.bus_id); + ds_dev_dbg(1, dev, "releasing device\n"); pcmcia_put_socket(p_dev->socket); kfree(p_dev->devname); kref_put(&p_dev->function_config->ref, pcmcia_release_function); @@ -401,7 +368,7 @@ static void pcmcia_release_dev(struct device *dev) static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc) { if (!s->pcmcia_state.device_add_pending) { - ds_dbg(1, "scheduling to add %s secondary" + ds_dev_dbg(1, &s->dev, "scheduling to add %s secondary" " device to %d\n", mfc ? "mfc" : "pfc", s->sock); s->pcmcia_state.device_add_pending = 1; s->pcmcia_state.mfc_pfc = mfc; @@ -439,8 +406,7 @@ static int pcmcia_device_probe(struct device * dev) */ did = p_dev->dev.driver_data; - ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id, - p_drv->drv.name); + ds_dev_dbg(1, dev, "trying to bind to %s\n", p_drv->drv.name); if ((!p_drv->probe) || (!p_dev->function_config) || (!try_module_get(p_drv->owner))) { @@ -455,15 +421,16 @@ static int pcmcia_device_probe(struct device * dev) p_dev->conf.ConfigBase = cis_config.base; p_dev->conf.Present = cis_config.rmask[0]; } else { - printk(KERN_INFO "pcmcia: could not parse base and rmask0 of CIS\n"); + dev_printk(KERN_INFO, dev, + "pcmcia: could not parse base and rmask0 of CIS\n"); p_dev->conf.ConfigBase = 0; p_dev->conf.Present = 0; } ret = p_drv->probe(p_dev); if (ret) { - ds_dbg(1, "binding %s to %s failed with %d\n", - p_dev->dev.bus_id, p_drv->drv.name, ret); + ds_dev_dbg(1, dev, "binding to %s failed with %d\n", + p_drv->drv.name, ret); goto put_module; } @@ -490,8 +457,9 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le struct pcmcia_device *tmp; unsigned long flags; - ds_dbg(2, "pcmcia_card_remove(%d) %s\n", s->sock, - leftover ? leftover->devname : ""); + ds_dev_dbg(2, leftover ? &leftover->dev : &s->dev, + "pcmcia_card_remove(%d) %s\n", s->sock, + leftover ? leftover->devname : ""); if (!leftover) s->device_count = 0; @@ -508,7 +476,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le p_dev->_removed=1; spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - ds_dbg(2, "unregistering device %s\n", p_dev->dev.bus_id); + ds_dev_dbg(2, &p_dev->dev, "unregistering device\n"); device_unregister(&p_dev->dev); } @@ -525,7 +493,7 @@ static int pcmcia_device_remove(struct device * dev) p_dev = to_pcmcia_dev(dev); p_drv = to_pcmcia_drv(dev->driver); - ds_dbg(1, "removing device %s\n", p_dev->dev.bus_id); + ds_dev_dbg(1, dev, "removing device\n"); /* If we're removing the primary module driving a * pseudo multi-function card, we need to unbind @@ -548,13 +516,15 @@ static int pcmcia_device_remove(struct device * dev) /* check for proper unloading */ if (p_dev->_irq || p_dev->_io || p_dev->_locked) - printk(KERN_INFO "pcmcia: driver %s did not release config properly\n", - p_drv->drv.name); + dev_printk(KERN_INFO, dev, + "pcmcia: driver %s did not release config properly\n", + p_drv->drv.name); for (i = 0; i < MAX_WIN; i++) if (p_dev->_win & CLIENT_WIN_REQ(i)) - printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n", - p_drv->drv.name); + dev_printk(KERN_INFO, dev, + "pcmcia: driver %s did not release window properly\n", + p_drv->drv.name); /* references from pcmcia_probe_device */ pcmcia_put_dev(p_dev); @@ -603,8 +573,9 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) } if (!pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_DEVICE_GEO, devgeo)) { - ds_dbg(0, "mem device geometry probably means " - "FUNCID_MEMORY\n"); + ds_dev_dbg(0, &p_dev->dev, + "mem device geometry probably means " + "FUNCID_MEMORY\n"); p_dev->func_id = CISTPL_FUNCID_MEMORY; p_dev->has_func_id = 1; } @@ -685,7 +656,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f if (!p_dev->devname) goto err_free; sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id); - ds_dbg(3, "devname is %s\n", p_dev->devname); + ds_dev_dbg(3, &p_dev->dev, "devname is %s\n", p_dev->devname); spin_lock_irqsave(&pcmcia_dev_list_lock, flags); @@ -706,7 +677,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); if (!p_dev->function_config) { - ds_dbg(3, "creating config_t for %s\n", p_dev->dev.bus_id); + ds_dev_dbg(3, &p_dev->dev, "creating config_t\n"); p_dev->function_config = kzalloc(sizeof(struct config_t), GFP_KERNEL); if (!p_dev->function_config) @@ -714,8 +685,9 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f kref_init(&p_dev->function_config->ref); } - printk(KERN_NOTICE "pcmcia: registering new device %s\n", - p_dev->devname); + dev_printk(KERN_NOTICE, &p_dev->dev, + "pcmcia: registering new device %s\n", + p_dev->devname); pcmcia_device_query(p_dev); @@ -750,19 +722,20 @@ static int pcmcia_card_add(struct pcmcia_socket *s) int ret = 0; if (!(s->resource_setup_done)) { - ds_dbg(3, "no resources available, delaying card_add\n"); + ds_dev_dbg(3, &s->dev, + "no resources available, delaying card_add\n"); return -EAGAIN; /* try again, but later... */ } if (pcmcia_validate_mem(s)) { - ds_dbg(3, "validating mem resources failed, " + ds_dev_dbg(3, &s->dev, "validating mem resources failed, " "delaying card_add\n"); return -EAGAIN; /* try again, but later... */ } ret = pccard_validate_cis(s, BIND_FN_ALL, &no_chains); if (ret || !no_chains) { - ds_dbg(0, "invalid CIS or invalid resources\n"); + ds_dev_dbg(0, &s->dev, "invalid CIS or invalid resources\n"); return -ENODEV; } @@ -783,7 +756,7 @@ static void pcmcia_delayed_add_device(struct work_struct *work) { struct pcmcia_socket *s = container_of(work, struct pcmcia_socket, device_add); - ds_dbg(1, "adding additional device to %d\n", s->sock); + ds_dev_dbg(1, &s->dev, "adding additional device to %d\n", s->sock); pcmcia_device_add(s, s->pcmcia_state.mfc_pfc); s->pcmcia_state.device_add_pending = 0; s->pcmcia_state.mfc_pfc = 0; @@ -793,8 +766,7 @@ static int pcmcia_requery(struct device *dev, void * _data) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); if (!p_dev->dev.driver) { - ds_dbg(1, "update device information for %s\n", - p_dev->dev.bus_id); + ds_dev_dbg(1, dev, "update device information\n"); pcmcia_device_query(p_dev); } @@ -808,7 +780,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis) unsigned long flags; /* must be called with skt_mutex held */ - ds_dbg(0, "re-scanning socket %d\n", skt->sock); + ds_dev_dbg(0, &skt->dev, "re-scanning socket %d\n", skt->sock); spin_lock_irqsave(&pcmcia_dev_list_lock, flags); if (list_empty(&skt->devices_list)) @@ -859,17 +831,17 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) int ret = -ENOMEM; int no_funcs; int old_funcs; - cisdump_t *cis; cistpl_longlink_mfc_t mfc; if (!filename) return -EINVAL; - ds_dbg(1, "trying to load CIS file %s\n", filename); + ds_dev_dbg(1, &dev->dev, "trying to load CIS file %s\n", filename); if (strlen(filename) > (FIRMWARE_NAME_MAX - 1)) { - printk(KERN_WARNING "pcmcia: CIS filename is too long [%s]\n", - filename); + dev_printk(KERN_WARNING, &dev->dev, + "pcmcia: CIS filename is too long [%s]\n", + filename); return -EINVAL; } @@ -878,23 +850,16 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) if (request_firmware(&fw, path, &dev->dev) == 0) { if (fw->size >= CISTPL_MAX_CIS_SIZE) { ret = -EINVAL; - printk(KERN_ERR "pcmcia: CIS override is too big\n"); + dev_printk(KERN_ERR, &dev->dev, + "pcmcia: CIS override is too big\n"); goto release; } - cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); - if (!cis) { - ret = -ENOMEM; - goto release; - } - - cis->Length = fw->size + 1; - memcpy(cis->Data, fw->data, fw->size); - - if (!pcmcia_replace_cis(s, cis)) + if (!pcmcia_replace_cis(s, fw->data, fw->size)) ret = 0; else { - printk(KERN_ERR "pcmcia: CIS override failed\n"); + dev_printk(KERN_ERR, &dev->dev, + "pcmcia: CIS override failed\n"); goto release; } @@ -998,14 +963,14 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, * after it has re-checked that there is no possible module * with a prod_id/manf_id/card_id match. */ - ds_dbg(0, "skipping FUNC_ID match for %s until userspace " - "interaction\n", dev->dev.bus_id); + ds_dev_dbg(0, &dev->dev, + "skipping FUNC_ID match until userspace interaction\n"); if (!dev->allow_func_id_match) return 0; } if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { - ds_dbg(0, "device %s needs a fake CIS\n", dev->dev.bus_id); + ds_dev_dbg(0, &dev->dev, "device needs a fake CIS\n"); if (!dev->socket->fake_cis) pcmcia_load_firmware(dev, did->cisfile); @@ -1037,11 +1002,9 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { /* match dynamic devices first */ spin_lock(&p_drv->dynids.lock); list_for_each_entry(dynid, &p_drv->dynids.list, node) { - ds_dbg(3, "trying to match %s to %s\n", dev->bus_id, - drv->name); + ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name); if (pcmcia_devmatch(p_dev, &dynid->id)) { - ds_dbg(0, "matched %s to %s\n", dev->bus_id, - drv->name); + ds_dev_dbg(0, dev, "matched to %s\n", drv->name); spin_unlock(&p_drv->dynids.lock); return 1; } @@ -1051,18 +1014,15 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { #ifdef CONFIG_PCMCIA_IOCTL /* matching by cardmgr */ if (p_dev->cardmgr == p_drv) { - ds_dbg(0, "cardmgr matched %s to %s\n", dev->bus_id, - drv->name); + ds_dev_dbg(0, dev, "cardmgr matched to %s\n", drv->name); return 1; } #endif while (did && did->match_flags) { - ds_dbg(3, "trying to match %s to %s\n", dev->bus_id, - drv->name); + ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name); if (pcmcia_devmatch(p_dev, did)) { - ds_dbg(0, "matched %s to %s\n", dev->bus_id, - drv->name); + ds_dev_dbg(0, dev, "matched to %s\n", drv->name); return 1; } did++; @@ -1268,7 +1228,7 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) if (p_dev->suspended) return 0; - ds_dbg(2, "suspending %s\n", dev->bus_id); + ds_dev_dbg(2, dev, "suspending\n"); if (dev->driver) p_drv = to_pcmcia_drv(dev->driver); @@ -1279,15 +1239,16 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) if (p_drv->suspend) { ret = p_drv->suspend(p_dev); if (ret) { - printk(KERN_ERR "pcmcia: device %s (driver %s) did " - "not want to go to sleep (%d)\n", - p_dev->devname, p_drv->drv.name, ret); + dev_printk(KERN_ERR, dev, + "pcmcia: device %s (driver %s) did " + "not want to go to sleep (%d)\n", + p_dev->devname, p_drv->drv.name, ret); goto out; } } if (p_dev->device_no == p_dev->func) { - ds_dbg(2, "releasing configuration for %s\n", dev->bus_id); + ds_dev_dbg(2, dev, "releasing configuration\n"); pcmcia_release_configuration(p_dev); } @@ -1307,7 +1268,7 @@ static int pcmcia_dev_resume(struct device * dev) if (!p_dev->suspended) return 0; - ds_dbg(2, "resuming %s\n", dev->bus_id); + ds_dev_dbg(2, dev, "resuming\n"); if (dev->driver) p_drv = to_pcmcia_drv(dev->driver); @@ -1316,7 +1277,7 @@ static int pcmcia_dev_resume(struct device * dev) goto out; if (p_dev->device_no == p_dev->func) { - ds_dbg(2, "requesting configuration for %s\n", dev->bus_id); + ds_dev_dbg(2, dev, "requesting configuration\n"); ret = pcmcia_request_configuration(p_dev, &p_dev->conf); if (ret) goto out; @@ -1358,14 +1319,14 @@ static int pcmcia_bus_resume_callback(struct device *dev, void * _data) static int pcmcia_bus_resume(struct pcmcia_socket *skt) { - ds_dbg(2, "resuming socket %d\n", skt->sock); + ds_dev_dbg(2, &skt->dev, "resuming socket %d\n", skt->sock); bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback); return 0; } static int pcmcia_bus_suspend(struct pcmcia_socket *skt) { - ds_dbg(2, "suspending socket %d\n", skt->sock); + ds_dev_dbg(2, &skt->dev, "suspending socket %d\n", skt->sock); if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_suspend_callback)) { pcmcia_bus_resume(skt); @@ -1391,13 +1352,14 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) struct pcmcia_socket *s = pcmcia_get_socket(skt); if (!s) { - printk(KERN_ERR "PCMCIA obtaining reference to socket %p " \ - "failed, event 0x%x lost!\n", skt, event); + dev_printk(KERN_ERR, &skt->dev, + "PCMCIA obtaining reference to socket " \ + "failed, event 0x%x lost!\n", event); return -ENODEV; } - ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n", - event, priority, skt); + ds_dev_dbg(1, &skt->dev, "ds_event(0x%06x, %d, 0x%p)\n", + event, priority, skt); switch (event) { case CS_EVENT_CARD_REMOVAL: @@ -1472,7 +1434,8 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, socket = pcmcia_get_socket(socket); if (!socket) { - printk(KERN_ERR "PCMCIA obtaining reference to socket %p failed\n", socket); + dev_printk(KERN_ERR, dev, + "PCMCIA obtaining reference to socket failed\n"); return -ENODEV; } @@ -1492,7 +1455,7 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, ret = pccard_register_pcmcia(socket, &pcmcia_bus_callback); if (ret) { - printk(KERN_ERR "PCMCIA registration PCCard core failed for socket %p\n", socket); + dev_printk(KERN_ERR, dev, "PCMCIA registration failed\n"); pcmcia_put_socket(socket); return (ret); } diff --git a/drivers/pcmcia/ds_internal.h b/drivers/pcmcia/ds_internal.h deleted file mode 100644 index 3a2b25e6ed7..00000000000 --- a/drivers/pcmcia/ds_internal.h +++ /dev/null @@ -1,23 +0,0 @@ -/* ds_internal.h - internal header for 16-bit PCMCIA devices management */ - -extern spinlock_t pcmcia_dev_list_lock; -extern struct bus_type pcmcia_bus_type; - -extern struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev); -extern void pcmcia_put_dev(struct pcmcia_device *p_dev); - -struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function); - -extern int pcmcia_release_configuration(struct pcmcia_device *p_dev); - -#ifdef CONFIG_PCMCIA_IOCTL -extern void __init pcmcia_setup_ioctl(void); -extern void __exit pcmcia_cleanup_ioctl(void); -extern void handle_event(struct pcmcia_socket *s, event_t event); -extern int handle_request(struct pcmcia_socket *s, event_t event); -#else -static inline void __init pcmcia_setup_ioctl(void) { return; } -static inline void __exit pcmcia_cleanup_ioctl(void) { return; } -static inline void handle_event(struct pcmcia_socket *s, event_t event) { return; } -static inline int handle_request(struct pcmcia_socket *s, event_t event) { return CS_SUCCESS; } -#endif diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c index fb2bc1fb015..117dc12ab43 100644 --- a/drivers/pcmcia/hd64465_ss.c +++ b/drivers/pcmcia/hd64465_ss.c @@ -46,7 +46,6 @@ #include <pcmcia/cistpl.h> #include <pcmcia/ds.h> #include <pcmcia/ss.h> -#include "cs_internal.h" #define MODNAME "hd64465_ss" diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 68f6b2702bc..71653ab8489 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -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)"; diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 3616da22715..2ab4f22c21d 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c @@ -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"); } diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 2b42b7155e3..2f108c23dbd 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c @@ -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"); } diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index ff66604e90d..d1ad0966392 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -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 diff --git a/drivers/pcmcia/o2micro.h b/drivers/pcmcia/o2micro.h index a234ce1967a..5554015a781 100644 --- a/drivers/pcmcia/o2micro.h +++ b/drivers/pcmcia/o2micro.h @@ -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, diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 419f97fc9a6..1703b20cad5 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -38,7 +38,6 @@ #include <pcmcia/ss.h> #include "cs_internal.h" -#include "ds_internal.h" static int major_dev = -1; @@ -58,7 +57,7 @@ typedef struct user_info_t { } user_info_t; -#ifdef DEBUG +#ifdef CONFIG_PCMCIA_DEBUG extern int ds_pc_debug; #define ds_dbg(lvl, fmt, arg...) do { \ @@ -149,7 +148,7 @@ static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) irq = adj->resource.irq.IRQ; if ((irq < 0) || (irq > 15)) - return CS_BAD_IRQ; + return -EINVAL; if (adj->Action != REMOVE_MANAGED_RESOURCE) return 0; @@ -167,7 +166,7 @@ static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) #else static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) { - return CS_SUCCESS; + return 0; } #endif @@ -175,7 +174,7 @@ static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) { static int pcmcia_adjust_resource_info(adjust_t *adj) { struct pcmcia_socket *s; - int ret = CS_UNSUPPORTED_FUNCTION; + int ret = -ENOSYS; unsigned long flags; down_read(&pcmcia_socket_list_rwsem); @@ -248,7 +247,7 @@ static int pccard_get_status(struct pcmcia_socket *s, if (s->state & SOCKET_SUSPEND) status->CardState |= CS_EVENT_PM_SUSPEND; if (!(s->state & SOCKET_PRESENT)) - return CS_NO_CARD; + return -ENODEV; c = (p_dev) ? p_dev->function_config : NULL; @@ -274,7 +273,7 @@ static int pccard_get_status(struct pcmcia_socket *s, status->CardState |= (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; } - return CS_SUCCESS; + return 0; } status->CardState |= (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0; @@ -284,9 +283,81 @@ static int pccard_get_status(struct pcmcia_socket *s, (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0; status->CardState |= (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0; - return CS_SUCCESS; + return 0; } /* pccard_get_status */ +int pccard_get_configuration_info(struct pcmcia_socket *s, + struct pcmcia_device *p_dev, + config_info_t *config) +{ + config_t *c; + + if (!(s->state & SOCKET_PRESENT)) + return -ENODEV; + + +#ifdef CONFIG_CARDBUS + if (s->state & SOCKET_CARDBUS) { + memset(config, 0, sizeof(config_info_t)); + config->Vcc = s->socket.Vcc; + config->Vpp1 = config->Vpp2 = s->socket.Vpp; + config->Option = s->cb_dev->subordinate->number; + if (s->state & SOCKET_CARDBUS_CONFIG) { + config->Attributes = CONF_VALID_CLIENT; + config->IntType = INT_CARDBUS; + config->AssignedIRQ = s->irq.AssignedIRQ; + if (config->AssignedIRQ) + config->Attributes |= CONF_ENABLE_IRQ; + if (s->io[0].res) { + config->BasePort1 = s->io[0].res->start; + config->NumPorts1 = s->io[0].res->end - + config->BasePort1 + 1; + } + } + return 0; + } +#endif + + if (p_dev) { + c = p_dev->function_config; + config->Function = p_dev->func; + } else { + c = NULL; + config->Function = 0; + } + + if ((c == NULL) || !(c->state & CONFIG_LOCKED)) { + config->Attributes = 0; + config->Vcc = s->socket.Vcc; + config->Vpp1 = config->Vpp2 = s->socket.Vpp; + return 0; + } + + config->Attributes = c->Attributes | CONF_VALID_CLIENT; + config->Vcc = s->socket.Vcc; + config->Vpp1 = config->Vpp2 = s->socket.Vpp; + config->IntType = c->IntType; + config->ConfigBase = c->ConfigBase; + config->Status = c->Status; + config->Pin = c->Pin; + config->Copy = c->Copy; + config->Option = c->Option; + config->ExtStatus = c->ExtStatus; + config->Present = config->CardValues = c->CardValues; + config->IRQAttributes = c->irq.Attributes; + config->AssignedIRQ = s->irq.AssignedIRQ; + config->BasePort1 = c->io.BasePort1; + config->NumPorts1 = c->io.NumPorts1; + config->Attributes1 = c->io.Attributes1; + config->BasePort2 = c->io.BasePort2; + config->NumPorts2 = c->io.NumPorts2; + config->Attributes2 = c->io.Attributes2; + config->IOAddrLines = c->io.IOAddrLines; + + return 0; +} /* pccard_get_configuration_info */ + + /*====================================================================== These manage a ring buffer of events pending for one user process @@ -764,7 +835,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, case DS_GET_CONFIGURATION_INFO: if (buf->config.Function && (buf->config.Function >= s->functions)) - ret = CS_BAD_ARGS; + ret = -EINVAL; else { struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function); ret = pccard_get_configuration_info(s, p_dev, &buf->config); @@ -787,15 +858,15 @@ static int ds_ioctl(struct inode * inode, struct file * file, break; case DS_PARSE_TUPLE: buf->tuple.TupleData = buf->tuple_parse.data; - ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse); + ret = pcmcia_parse_tuple(&buf->tuple, &buf->tuple_parse.parse); break; case DS_RESET_CARD: - ret = pccard_reset_card(s); + ret = pcmcia_reset_card(s); break; case DS_GET_STATUS: if (buf->status.Function && (buf->status.Function >= s->functions)) - ret = CS_BAD_ARGS; + ret = -EINVAL; else { struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function); ret = pccard_get_status(s, p_dev, &buf->status); @@ -826,7 +897,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, goto free_out; } - ret = CS_BAD_ARGS; + ret = -EINVAL; if (!(buf->conf_reg.Function && (buf->conf_reg.Function >= s->functions))) { @@ -867,7 +938,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, &buf->win_info.map); break; case DS_REPLACE_CIS: - ret = pcmcia_replace_cis(s, &buf->cisdump); + ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length); break; case DS_BIND_REQUEST: if (!capable(CAP_SYS_ADMIN)) { @@ -889,22 +960,19 @@ static int ds_ioctl(struct inode * inode, struct file * file, err = -EINVAL; } - if ((err == 0) && (ret != CS_SUCCESS)) { + if ((err == 0) && (ret != 0)) { ds_dbg(2, "ds_ioctl: ret = %d\n", ret); switch (ret) { - case CS_BAD_SOCKET: case CS_NO_CARD: - err = -ENODEV; break; - case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ: - case CS_BAD_TUPLE: - err = -EINVAL; break; - case CS_IN_USE: - err = -EBUSY; break; - case CS_OUT_OF_RESOURCE: + case -ENODEV: + case -EINVAL: + case -EBUSY: + case -ENOSYS: + err = ret; + break; + case -ENOMEM: err = -ENOSPC; break; - case CS_NO_MORE_ITEMS: + case -ENOSPC: err = -ENODATA; break; - case CS_UNSUPPORTED_FUNCTION: - err = -ENOSYS; break; default: err = -EIO; break; } diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 4884a18cf9e..afea2b2558b 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -29,7 +29,6 @@ #include <pcmcia/ds.h> #include "cs_internal.h" -#include "ds_internal.h" /* Access speed for IO windows */ @@ -44,16 +43,17 @@ static u8 pcmcia_used_irq[NR_IRQS]; #endif -#ifdef DEBUG +#ifdef CONFIG_PCMCIA_DEBUG extern int ds_pc_debug; #define ds_dbg(skt, lvl, fmt, arg...) do { \ if (ds_pc_debug >= lvl) \ - printk(KERN_DEBUG "pcmcia_resource: %s: " fmt, \ - cs_socket_name(skt) , ## arg); \ + dev_printk(KERN_DEBUG, &skt->dev, \ + "pcmcia_resource: " fmt, \ + ## arg); \ } while (0) #else -#define ds_dbg(lvl, fmt, arg...) do { } while (0) +#define ds_dbg(skt, lvl, fmt, arg...) do { } while (0) #endif @@ -168,13 +168,13 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, u_char val; if (!p_dev || !p_dev->function_config) - return CS_NO_CARD; + return -EINVAL; s = p_dev->socket; c = p_dev->function_config; if (!(c->state & CONFIG_LOCKED)) - return CS_CONFIGURATION_LOCKED; + return -EACCES; addr = (c->ConfigBase + reg->Offset) >> 1; @@ -188,93 +188,14 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, pcmcia_write_cis_mem(s, 1, addr, 1, &val); break; default: - return CS_BAD_ARGS; + return -EINVAL; break; } - return CS_SUCCESS; + return 0; } /* pcmcia_access_configuration_register */ EXPORT_SYMBOL(pcmcia_access_configuration_register); -int pccard_get_configuration_info(struct pcmcia_socket *s, - struct pcmcia_device *p_dev, - config_info_t *config) -{ - config_t *c; - - if (!(s->state & SOCKET_PRESENT)) - return CS_NO_CARD; - - -#ifdef CONFIG_CARDBUS - if (s->state & SOCKET_CARDBUS) { - memset(config, 0, sizeof(config_info_t)); - config->Vcc = s->socket.Vcc; - config->Vpp1 = config->Vpp2 = s->socket.Vpp; - config->Option = s->cb_dev->subordinate->number; - if (s->state & SOCKET_CARDBUS_CONFIG) { - config->Attributes = CONF_VALID_CLIENT; - config->IntType = INT_CARDBUS; - config->AssignedIRQ = s->irq.AssignedIRQ; - if (config->AssignedIRQ) - config->Attributes |= CONF_ENABLE_IRQ; - if (s->io[0].res) { - config->BasePort1 = s->io[0].res->start; - config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1; - } - } - return CS_SUCCESS; - } -#endif - - if (p_dev) { - c = p_dev->function_config; - config->Function = p_dev->func; - } else { - c = NULL; - config->Function = 0; - } - - if ((c == NULL) || !(c->state & CONFIG_LOCKED)) { - config->Attributes = 0; - config->Vcc = s->socket.Vcc; - config->Vpp1 = config->Vpp2 = s->socket.Vpp; - return CS_SUCCESS; - } - - config->Attributes = c->Attributes | CONF_VALID_CLIENT; - config->Vcc = s->socket.Vcc; - config->Vpp1 = config->Vpp2 = s->socket.Vpp; - config->IntType = c->IntType; - config->ConfigBase = c->ConfigBase; - config->Status = c->Status; - config->Pin = c->Pin; - config->Copy = c->Copy; - config->Option = c->Option; - config->ExtStatus = c->ExtStatus; - config->Present = config->CardValues = c->CardValues; - config->IRQAttributes = c->irq.Attributes; - config->AssignedIRQ = s->irq.AssignedIRQ; - config->BasePort1 = c->io.BasePort1; - config->NumPorts1 = c->io.NumPorts1; - config->Attributes1 = c->io.Attributes1; - config->BasePort2 = c->io.BasePort2; - config->NumPorts2 = c->io.NumPorts2; - config->Attributes2 = c->io.Attributes2; - config->IOAddrLines = c->io.IOAddrLines; - - return CS_SUCCESS; -} /* pccard_get_configuration_info */ - -int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, - config_info_t *config) -{ - return pccard_get_configuration_info(p_dev->socket, p_dev, - config); -} -EXPORT_SYMBOL(pcmcia_get_configuration_info); - - /** pcmcia_get_window */ int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, @@ -284,12 +205,12 @@ int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int w; if (!s || !(s->state & SOCKET_PRESENT)) - return CS_NO_CARD; + return -ENODEV; for (w = idx; w < MAX_WIN; w++) if (s->state & SOCKET_WIN_REQ(w)) break; if (w == MAX_WIN) - return CS_NO_MORE_ITEMS; + return -EINVAL; win = &s->win[w]; req->Base = win->ctl.res->start; req->Size = win->ctl.res->end - win->ctl.res->start + 1; @@ -304,7 +225,7 @@ int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, if (win->ctl.flags & MAP_USE_WAIT) req->Attributes |= WIN_USE_WAIT; *handle = win; - return CS_SUCCESS; + return 0; } /* pcmcia_get_window */ EXPORT_SYMBOL(pcmcia_get_window); @@ -316,10 +237,10 @@ EXPORT_SYMBOL(pcmcia_get_window); int pcmcia_get_mem_page(window_handle_t win, memreq_t *req) { if ((win == NULL) || (win->magic != WINDOW_MAGIC)) - return CS_BAD_HANDLE; + return -EINVAL; req->Page = 0; req->CardOffset = win->ctl.card_start; - return CS_SUCCESS; + return 0; } /* pcmcia_get_mem_page */ EXPORT_SYMBOL(pcmcia_get_mem_page); @@ -328,14 +249,18 @@ int pcmcia_map_mem_page(window_handle_t win, memreq_t *req) { struct pcmcia_socket *s; if ((win == NULL) || (win->magic != WINDOW_MAGIC)) - return CS_BAD_HANDLE; - if (req->Page != 0) - return CS_BAD_PAGE; + return -EINVAL; s = win->sock; + if (req->Page != 0) { + ds_dbg(s, 0, "failure: requested page is zero\n"); + return -EINVAL; + } win->ctl.card_start = req->CardOffset; - if (s->ops->set_mem_map(s, &win->ctl) != 0) - return CS_BAD_OFFSET; - return CS_SUCCESS; + if (s->ops->set_mem_map(s, &win->ctl) != 0) { + ds_dbg(s, 0, "failed to set_mem_map\n"); + return -EIO; + } + return 0; } /* pcmcia_map_mem_page */ EXPORT_SYMBOL(pcmcia_map_mem_page); @@ -354,9 +279,9 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, c = p_dev->function_config; if (!(s->state & SOCKET_PRESENT)) - return CS_NO_CARD; + return -ENODEV; if (!(c->state & CONFIG_LOCKED)) - return CS_CONFIGURATION_LOCKED; + return -EACCES; if (mod->Attributes & CONF_IRQ_CHANGE_VALID) { if (mod->Attributes & CONF_ENABLE_IRQ) { @@ -369,20 +294,28 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, s->ops->set_socket(s, &s->socket); } - if (mod->Attributes & CONF_VCC_CHANGE_VALID) - return CS_BAD_VCC; + if (mod->Attributes & CONF_VCC_CHANGE_VALID) { + ds_dbg(s, 0, "changing Vcc is not allowed at this time\n"); + return -EINVAL; + } /* We only allow changing Vpp1 and Vpp2 to the same value */ if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) && (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { if (mod->Vpp1 != mod->Vpp2) - return CS_BAD_VPP; + ds_dbg(s, 0, "Vpp1 and Vpp2 must be the same\n"); + return -EINVAL; s->socket.Vpp = mod->Vpp1; - if (s->ops->set_socket(s, &s->socket)) - return CS_BAD_VPP; + if (s->ops->set_socket(s, &s->socket)) { + dev_printk(KERN_WARNING, &s->dev, + "Unable to set VPP\n"); + return -EIO; + } } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) || - (mod->Attributes & CONF_VPP2_CHANGE_VALID)) - return CS_BAD_VPP; + (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { + ds_dbg(s, 0, "changing Vcc is not allowed at this time\n"); + return -EINVAL; + } if (mod->Attributes & CONF_IO_CHANGE_WIDTH) { pccard_io_map io_off = { 0, 0, 0, 0, 1 }; @@ -406,7 +339,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, } } - return CS_SUCCESS; + return 0; } /* modify_configuration */ EXPORT_SYMBOL(pcmcia_modify_configuration); @@ -441,7 +374,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev) } } - return CS_SUCCESS; + return 0; } /* pcmcia_release_configuration */ @@ -459,7 +392,7 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) config_t *c = p_dev->function_config; if (!p_dev->_io ) - return CS_BAD_HANDLE; + return -EINVAL; p_dev->_io = 0; @@ -467,7 +400,7 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) (c->io.NumPorts1 != req->NumPorts1) || (c->io.BasePort2 != req->BasePort2) || (c->io.NumPorts2 != req->NumPorts2)) - return CS_BAD_ARGS; + return -EINVAL; c->state &= ~CONFIG_IO_REQ; @@ -475,7 +408,7 @@ static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) if (req->NumPorts2) release_io_space(s, req->BasePort2, req->NumPorts2); - return CS_SUCCESS; + return 0; } /* pcmcia_release_io */ @@ -485,15 +418,19 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) config_t *c= p_dev->function_config; if (!p_dev->_irq) - return CS_BAD_HANDLE; + return -EINVAL; p_dev->_irq = 0; if (c->state & CONFIG_LOCKED) - return CS_CONFIGURATION_LOCKED; - if (c->irq.Attributes != req->Attributes) - return CS_BAD_ATTRIBUTE; - if (s->irq.AssignedIRQ != req->AssignedIRQ) - return CS_BAD_IRQ; + return -EACCES; + if (c->irq.Attributes != req->Attributes) { + ds_dbg(s, 0, "IRQ attributes must match assigned ones\n"); + return -EINVAL; + } + if (s->irq.AssignedIRQ != req->AssignedIRQ) { + ds_dbg(s, 0, "IRQ must match assigned one\n"); + return -EINVAL; + } if (--s->irq.Config == 0) { c->state &= ~CONFIG_IRQ_REQ; s->irq.AssignedIRQ = 0; @@ -507,7 +444,7 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) pcmcia_used_irq[req->AssignedIRQ]--; #endif - return CS_SUCCESS; + return 0; } /* pcmcia_release_irq */ @@ -516,10 +453,10 @@ int pcmcia_release_window(window_handle_t win) struct pcmcia_socket *s; if ((win == NULL) || (win->magic != WINDOW_MAGIC)) - return CS_BAD_HANDLE; + return -EINVAL; s = win->sock; if (!(win->handle->_win & CLIENT_WIN_REQ(win->index))) - return CS_BAD_HANDLE; + return -EINVAL; /* Shut down memory window */ win->ctl.flags &= ~MAP_ACTIVE; @@ -536,7 +473,7 @@ int pcmcia_release_window(window_handle_t win) win->magic = 0; - return CS_SUCCESS; + return 0; } /* pcmcia_release_window */ EXPORT_SYMBOL(pcmcia_release_window); @@ -551,18 +488,23 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, pccard_io_map iomap; if (!(s->state & SOCKET_PRESENT)) - return CS_NO_CARD; + return -ENODEV;; - if (req->IntType & INT_CARDBUS) - return CS_UNSUPPORTED_MODE; + if (req->IntType & INT_CARDBUS) { + ds_dbg(p_dev->socket, 0, "IntType may not be INT_CARDBUS\n"); + return -EINVAL; + } c = p_dev->function_config; if (c->state & CONFIG_LOCKED) - return CS_CONFIGURATION_LOCKED; + return -EACCES; /* Do power control. We don't allow changes in Vcc. */ s->socket.Vpp = req->Vpp; - if (s->ops->set_socket(s, &s->socket)) - return CS_BAD_VPP; + if (s->ops->set_socket(s, &s->socket)) { + dev_printk(KERN_WARNING, &s->dev, + "Unable to set socket state\n"); + return -EINVAL; + } /* Pick memory or I/O card, DMA mode, interrupt */ c->IntType = req->IntType; @@ -651,7 +593,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, c->state |= CONFIG_LOCKED; p_dev->_locked = 1; - return CS_SUCCESS; + return 0; } /* pcmcia_request_configuration */ EXPORT_SYMBOL(pcmcia_request_configuration); @@ -667,37 +609,48 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) config_t *c; if (!(s->state & SOCKET_PRESENT)) - return CS_NO_CARD; + return -ENODEV; if (!req) - return CS_UNSUPPORTED_MODE; + return -EINVAL; c = p_dev->function_config; if (c->state & CONFIG_LOCKED) - return CS_CONFIGURATION_LOCKED; - if (c->state & CONFIG_IO_REQ) - return CS_IN_USE; - if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) - return CS_BAD_ATTRIBUTE; + return -EACCES; + if (c->state & CONFIG_IO_REQ) { + ds_dbg(s, 0, "IO already configured\n"); + return -EBUSY; + } + if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) { + ds_dbg(s, 0, "bad attribute setting for IO region 1\n"); + return -EINVAL; + } if ((req->NumPorts2 > 0) && - (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) - return CS_BAD_ATTRIBUTE; + (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) { + ds_dbg(s, 0, "bad attribute setting for IO region 2\n"); + return -EINVAL; + } + ds_dbg(s, 1, "trying to allocate resource 1\n"); if (alloc_io_space(s, req->Attributes1, &req->BasePort1, - req->NumPorts1, req->IOAddrLines)) - return CS_IN_USE; + req->NumPorts1, req->IOAddrLines)) { + ds_dbg(s, 0, "allocation of resource 1 failed\n"); + return -EBUSY; + } if (req->NumPorts2) { + ds_dbg(s, 1, "trying to allocate resource 2\n"); if (alloc_io_space(s, req->Attributes2, &req->BasePort2, req->NumPorts2, req->IOAddrLines)) { + ds_dbg(s, 0, "allocation of resource 2 failed\n"); release_io_space(s, req->BasePort1, req->NumPorts1); - return CS_IN_USE; + return -EBUSY; } } c->io = *req; c->state |= CONFIG_IO_REQ; p_dev->_io = 1; - return CS_SUCCESS; + return 0; } /* pcmcia_request_io */ EXPORT_SYMBOL(pcmcia_request_io); @@ -723,16 +676,18 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) { struct pcmcia_socket *s = p_dev->socket; config_t *c; - int ret = CS_IN_USE, irq = 0; + int ret = -EINVAL, irq = 0; int type; if (!(s->state & SOCKET_PRESENT)) - return CS_NO_CARD; + return -ENODEV; c = p_dev->function_config; if (c->state & CONFIG_LOCKED) - return CS_CONFIGURATION_LOCKED; - if (c->state & CONFIG_IRQ_REQ) - return CS_IN_USE; + return -EACCES; + if (c->state & CONFIG_IRQ_REQ) { + ds_dbg(s, 0, "IRQ already configured\n"); + return -EBUSY; + } /* Decide what type of interrupt we are registering */ type = 0; @@ -795,15 +750,19 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) } if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) { - if (request_irq(irq, req->Handler, type, p_dev->devname, req->Instance)) - return CS_IN_USE; + ret = request_irq(irq, req->Handler, type, + p_dev->devname, req->Instance); + if (ret) + return ret; } /* Make sure the fact the request type was overridden is passed back */ if (type == IRQF_SHARED && !(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) { req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING; - printk(KERN_WARNING "pcmcia: request for exclusive IRQ could not be fulfilled.\n"); - printk(KERN_WARNING "pcmcia: the driver needs updating to supported shared IRQ lines.\n"); + dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: " + "request for exclusive IRQ could not be fulfilled.\n"); + dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver " + "needs updating to supported shared IRQ lines.\n"); } c->irq.Attributes = req->Attributes; s->irq.AssignedIRQ = req->AssignedIRQ = irq; @@ -816,7 +775,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) pcmcia_used_irq[irq]++; #endif - return CS_SUCCESS; + return 0; } /* pcmcia_request_irq */ EXPORT_SYMBOL(pcmcia_request_irq); @@ -834,9 +793,11 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h int w; if (!(s->state & SOCKET_PRESENT)) - return CS_NO_CARD; - if (req->Attributes & (WIN_PAGED | WIN_SHARED)) - return CS_BAD_ATTRIBUTE; + return -ENODEV; + if (req->Attributes & (WIN_PAGED | WIN_SHARED)) { + ds_dbg(s, 0, "bad attribute setting for iomem region\n"); + return -EINVAL; + } /* Window size defaults to smallest available */ if (req->Size == 0) @@ -844,19 +805,25 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h align = (((s->features & SS_CAP_MEM_ALIGN) || (req->Attributes & WIN_STRICT_ALIGN)) ? req->Size : s->map_size); - if (req->Size & (s->map_size-1)) - return CS_BAD_SIZE; + if (req->Size & (s->map_size-1)) { + ds_dbg(s, 0, "invalid map size\n"); + return -EINVAL; + } if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) || - (req->Base & (align-1))) - return CS_BAD_BASE; + (req->Base & (align-1))) { + ds_dbg(s, 0, "invalid base address\n"); + return -EINVAL; + } if (req->Base) align = 0; /* Allocate system memory window */ for (w = 0; w < MAX_WIN; w++) if (!(s->state & SOCKET_WIN_REQ(w))) break; - if (w == MAX_WIN) - return CS_OUT_OF_RESOURCE; + if (w == MAX_WIN) { + ds_dbg(s, 0, "all windows are used already\n"); + return -EINVAL; + } win = &s->win[w]; win->magic = WINDOW_MAGIC; @@ -867,8 +834,10 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h if (!(s->features & SS_CAP_STATIC_MAP)) { win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align, (req->Attributes & WIN_MAP_BELOW_1MB), s); - if (!win->ctl.res) - return CS_IN_USE; + if (!win->ctl.res) { + ds_dbg(s, 0, "allocating mem region failed\n"); + return -EINVAL; + } } (*p_dev)->_win |= CLIENT_WIN_REQ(w); @@ -885,8 +854,10 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h if (req->Attributes & WIN_USE_WAIT) win->ctl.flags |= MAP_USE_WAIT; win->ctl.card_start = 0; - if (s->ops->set_mem_map(s, &win->ctl) != 0) - return CS_BAD_ARGS; + if (s->ops->set_mem_map(s, &win->ctl) != 0) { + ds_dbg(s, 0, "failed to set memory mapping\n"); + return -EIO; + } s->state |= SOCKET_WIN_REQ(w); /* Return window handle */ @@ -897,7 +868,7 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h } *wh = win; - return CS_SUCCESS; + return 0; } /* pcmcia_request_window */ EXPORT_SYMBOL(pcmcia_request_window); @@ -909,3 +880,79 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) { pcmcia_release_window(p_dev->win); } EXPORT_SYMBOL(pcmcia_disable_device); + + +struct pcmcia_cfg_mem { + tuple_t tuple; + cisparse_t parse; + u8 buf[256]; + cistpl_cftable_entry_t dflt; +}; + +/** + * pcmcia_loop_config() - loop over configuration options + * @p_dev: the struct pcmcia_device which we need to loop for. + * @conf_check: function to call for each configuration option. + * It gets passed the struct pcmcia_device, the CIS data + * describing the configuration option, and private data + * being passed to pcmcia_loop_config() + * @priv_data: private data to be passed to the conf_check function. + * + * pcmcia_loop_config() loops over all configuration options, and calls + * the driver-specific conf_check() for each one, checking whether + * it is a valid one. + */ +int pcmcia_loop_config(struct pcmcia_device *p_dev, + int (*conf_check) (struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data), + void *priv_data) +{ + struct pcmcia_cfg_mem *cfg_mem; + + tuple_t *tuple; + int ret = -ENODEV; + unsigned int vcc; + + cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL); + if (cfg_mem == NULL) + return -ENOMEM; + + /* get the current Vcc setting */ + vcc = p_dev->socket->socket.Vcc; + + tuple = &cfg_mem->tuple; + tuple->TupleData = cfg_mem->buf; + tuple->TupleDataMax = 255; + tuple->TupleOffset = 0; + tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple->Attributes = 0; + + ret = pcmcia_get_first_tuple(p_dev, tuple); + while (!ret) { + cistpl_cftable_entry_t *cfg = &cfg_mem->parse.cftable_entry; + + if (pcmcia_get_tuple_data(p_dev, tuple)) + goto next_entry; + + if (pcmcia_parse_tuple(tuple, &cfg_mem->parse)) + goto next_entry; + + /* default values */ + p_dev->conf.ConfigIndex = cfg->index; + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) + cfg_mem->dflt = *cfg; + + ret = conf_check(p_dev, cfg, &cfg_mem->dflt, vcc, priv_data); + if (!ret) + break; + +next_entry: + ret = pcmcia_get_next_tuple(p_dev, tuple); + } + + return ret; +} +EXPORT_SYMBOL(pcmcia_loop_config); diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 13f1e0fd3f3..bb9ddb9532e 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -36,7 +36,6 @@ #include <pcmcia/ss.h> #include <pcmcia/cistpl.h> -#include "cs_internal.h" #include "soc_common.h" #include "pxa2xx_base.h" diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 203e579ebbd..17f4ecf1c0c 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -122,19 +122,22 @@ static void free_region(struct resource *res) static int add_interval(struct resource_map *map, u_long base, u_long num) { - struct resource_map *p, *q; + struct resource_map *p, *q; - for (p = map; ; p = p->next) { - if ((p != map) && (p->base+p->num-1 >= base)) - return -1; - if ((p->next == map) || (p->next->base > base+num-1)) - break; - } - q = kmalloc(sizeof(struct resource_map), GFP_KERNEL); - if (!q) return CS_OUT_OF_RESOURCE; - q->base = base; q->num = num; - q->next = p->next; p->next = q; - return CS_SUCCESS; + for (p = map; ; p = p->next) { + if ((p != map) && (p->base+p->num-1 >= base)) + return -1; + if ((p->next == map) || (p->next->base > base+num-1)) + break; + } + q = kmalloc(sizeof(struct resource_map), GFP_KERNEL); + if (!q) { + printk(KERN_WARNING "out of memory to update resources\n"); + return -ENOMEM; + } + q->base = base; q->num = num; + q->next = p->next; p->next = q; + return 0; } /*====================================================================*/ @@ -166,7 +169,10 @@ static int sub_interval(struct resource_map *map, u_long base, u_long num) } else { /* Split the block into two pieces */ p = kmalloc(sizeof(struct resource_map), GFP_KERNEL); - if (!p) return CS_OUT_OF_RESOURCE; + if (!p) { + printk(KERN_WARNING "out of memory to update resources\n"); + return -ENOMEM; + } p->base = base+num; p->num = q->base+q->num - p->base; q->num = base - q->base; @@ -174,7 +180,7 @@ static int sub_interval(struct resource_map *map, u_long base, u_long num) } } } - return CS_SUCCESS; + return 0; } /*====================================================================== @@ -194,13 +200,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, int any; u_char *b, hole, most; - printk(KERN_INFO "cs: IO port probe %#x-%#x:", - base, base+num-1); + dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:", + base, base+num-1); /* First, what does a floating port look like? */ b = kzalloc(256, GFP_KERNEL); if (!b) { - printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes"); + dev_printk(KERN_ERR, &s->dev, + "do_io_probe: unable to kmalloc 256 bytes"); return; } for (i = base, most = 0; i < base+num; i += 8) { @@ -366,8 +373,8 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s) struct socket_data *s_data = s->resource_data; u_long i, j, bad, fail, step; - printk(KERN_INFO "cs: memory probe 0x%06lx-0x%06lx:", - base, base+num-1); + dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:", + base, base+num-1); bad = fail = 0; step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff); /* don't allow too large steps */ @@ -431,8 +438,8 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) if (probe_mask & MEM_PROBE_HIGH) { if (inv_probe(s_data->mem_db.next, s) > 0) return 0; - printk(KERN_NOTICE "cs: warning: no high memory space " - "available!\n"); + dev_printk(KERN_NOTICE, &s->dev, + "cs: warning: no high memory space available!\n"); return -ENODEV; } @@ -794,10 +801,11 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) if (res->flags & IORESOURCE_IO) { if (res == &ioport_resource) continue; - printk(KERN_INFO "pcmcia: parent PCI bridge I/O " - "window: 0x%llx - 0x%llx\n", - (unsigned long long)res->start, - (unsigned long long)res->end); + dev_printk(KERN_INFO, &s->cb_dev->dev, + "pcmcia: parent PCI bridge I/O " + "window: 0x%llx - 0x%llx\n", + (unsigned long long)res->start, + (unsigned long long)res->end); if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end)) done |= IORESOURCE_IO; @@ -806,10 +814,11 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) if (res->flags & IORESOURCE_MEM) { if (res == &iomem_resource) continue; - printk(KERN_INFO "pcmcia: parent PCI bridge Memory " - "window: 0x%llx - 0x%llx\n", - (unsigned long long)res->start, - (unsigned long long)res->end); + dev_printk(KERN_INFO, &s->cb_dev->dev, + "pcmcia: parent PCI bridge Memory " + "window: 0x%llx - 0x%llx\n", + (unsigned long long)res->start, + (unsigned long long)res->end); if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end)) done |= IORESOURCE_MEM; } diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index da397215322..f49ac666615 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -54,7 +54,7 @@ #include <mach/pxa-regs.h> #endif -#ifdef DEBUG +#ifdef CONFIG_PCMCIA_DEBUG static int pc_debug; module_param(pc_debug, int, 0644); diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index 91ef6a0da3a..38c67375f36 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h @@ -15,7 +15,6 @@ #include <pcmcia/cs.h> #include <pcmcia/ss.h> #include <pcmcia/cistpl.h> -#include "cs_internal.h" struct device; @@ -137,7 +136,7 @@ extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_lev extern int soc_common_drv_pcmcia_remove(struct device *dev); -#ifdef DEBUG +#ifdef CONFIG_PCMCIA_DEBUG extern void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func, int lvl, const char *fmt, ...); diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index 006a29e91d8..ff9a3bb3c88 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c @@ -316,27 +316,18 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, size_t count) { struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj)); - cisdump_t *cis; int error; if (off) return -EINVAL; - if (count >= 0x200) + if (count >= CISTPL_MAX_CIS_SIZE) return -EINVAL; if (!(s->state & SOCKET_PRESENT)) return -ENODEV; - cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); - if (!cis) - return -ENOMEM; - - cis->Length = count + 1; - memcpy(cis->Data, buf, count); - - error = pcmcia_replace_cis(s, cis); - kfree(cis); + error = pcmcia_replace_cis(s, buf, count); if (error) return -EIO; diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index 5792bd5c54f..2a613e920fd 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c @@ -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); diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index 129db7bd06c..aaa70227bfb 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h @@ -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); } diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 0ab1fb65cdc..3ecd7c99d8e 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -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); diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 2dd0dc9a9ae..165ff884f48 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -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; } diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index d8b99351b05..06254f46a0d 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -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 */ diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 24e6cb8396e..11a61ea8d5d 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -1606,133 +1606,129 @@ static void nsp_cs_detach(struct pcmcia_device *link) is received, to configure the PCMCIA socket, and to make the ethernet device available to the system. ======================================================================*/ -#define CS_CHECK(fn, ret) \ -do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -/*====================================================================*/ -static int nsp_cs_config(struct pcmcia_device *link) -{ - int ret; - scsi_info_t *info = link->priv; - tuple_t tuple; - cisparse_t parse; - int last_ret, last_fn; - unsigned char tuple_data[64]; - config_info_t conf; - win_req_t req; - memreq_t map; - cistpl_cftable_entry_t dflt = { 0 }; - struct Scsi_Host *host; - nsp_hw_data *data = &nsp_data_base; - - nsp_dbg(NSP_DEBUG_INIT, "in"); - - tuple.Attributes = 0; - tuple.TupleData = tuple_data; - tuple.TupleDataMax = sizeof(tuple_data); - tuple.TupleOffset = 0; - - /* Look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - while (1) { - cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); +struct nsp_cs_configdata { + nsp_hw_data *data; + win_req_t req; +}; - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0) - goto next_entry; +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->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } - if (cfg->index == 0) { goto next_entry; } - link->conf.ConfigIndex = cfg->index; + if (cfg->index == 0) + return -ENODEV; - /* Does this card need audio output? */ - if (cfg->flags & CISTPL_CFTABLE_AUDIO) { - link->conf.Attributes |= CONF_ENABLE_SPKR; - link->conf.Status = CCSR_AUDIO_ENA; - } + /* 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 (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; - } + /* 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)) { - link->conf.Vpp = + p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; - } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) { - link->conf.Vpp = - dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; + } else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) { + p_dev->conf.Vpp = + dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; } /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) { - link->conf.Attributes |= CONF_ENABLE_IRQ; - } + if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ - link->io.NumPorts1 = link->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; if (!(io->flags & CISTPL_IO_8BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; if (!(io->flags & CISTPL_IO_16BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - link->io.BasePort1 = io->win[0].base; - link->io.NumPorts1 = io->win[0].len; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->io.BasePort1 = io->win[0].base; + p_dev->io.NumPorts1 = io->win[0].len; if (io->nwin > 1) { - link->io.Attributes2 = link->io.Attributes1; - link->io.BasePort2 = io->win[1].base; - link->io.NumPorts2 = io->win[1].len; + p_dev->io.Attributes2 = p_dev->io.Attributes1; + p_dev->io.BasePort2 = io->win[1].base; + p_dev->io.NumPorts2 = io->win[1].len; } /* This reserves IO space but doesn't actually enable it */ - if (pcmcia_request_io(link, &link->io) != 0) + if (pcmcia_request_io(p_dev, &p_dev->io) != 0) goto next_entry; } - if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { - 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) + 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(link->win, &map) != 0) + if (pcmcia_map_mem_page(p_dev->win, &map) != 0) goto next_entry; - data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size); - data->MmioLength = req.Size; + cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size); + cfg_mem->data->MmioLength = cfg_mem->req.Size; } /* If we got this far, we're cool! */ - break; - - next_entry: - nsp_dbg(NSP_DEBUG_INIT, "next"); - pcmcia_disable_device(link); - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); + 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; + struct nsp_cs_configdata *cfg_mem; + struct Scsi_Host *host; + nsp_hw_data *data = &nsp_data_base; + + nsp_dbg(NSP_DEBUG_INIT, "in"); + + cfg_mem = kzalloc(sizeof(cfg_mem), GFP_KERNEL); + if (!cfg_mem) + return -ENOMEM; + cfg_mem->data = data; + + ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem); + goto cs_failed; + if (link->conf.Attributes & CONF_ENABLE_IRQ) { - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); + if (pcmcia_request_irq(link, &link->irq)) + goto cs_failed; } - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + + ret = pcmcia_request_configuration(link, &link->conf); + if (ret) + goto cs_failed; if (free_ports) { if (link->io.BasePort1) { @@ -1790,20 +1786,20 @@ static int nsp_cs_config(struct pcmcia_device *link) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); if (link->win) - printk(", mem 0x%06lx-0x%06lx", req.Base, - req.Base+req.Size-1); + printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base, + cfg_mem->req.Base+cfg_mem->req.Size-1); printk("\n"); + kfree(cfg_mem); return 0; cs_failed: nsp_dbg(NSP_DEBUG_INIT, "config fail"); - cs_error(link, last_fn, last_ret); nsp_cs_release(link); + kfree(cfg_mem); return -ENODEV; } /* nsp_cs_config */ -#undef CS_CHECK /*====================================================================== diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index 67c5a58d17d..20c3e5e6d88 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -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 */ diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index 0be232b58ff..b330c11a175 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -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 */ diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 164d2a42eb5..7546aa887fa 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -431,131 +431,103 @@ first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse) { int i; i = pcmcia_get_first_tuple(handle, tuple); - if (i != CS_SUCCESS) - return CS_NO_MORE_ITEMS; - i = pcmcia_get_tuple_data(handle, tuple); - if (i != CS_SUCCESS) + if (i != 0) return i; - return pcmcia_parse_tuple(handle, tuple, parse); -} - -static int -next_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse) -{ - int i; - i = pcmcia_get_next_tuple(handle, tuple); - if (i != CS_SUCCESS) - return CS_NO_MORE_ITEMS; i = pcmcia_get_tuple_data(handle, tuple); - if (i != CS_SUCCESS) + if (i != 0) return i; - return pcmcia_parse_tuple(handle, tuple, parse); + return pcmcia_parse_tuple(tuple, parse); } /*====================================================================*/ -static int simple_config(struct pcmcia_device *link) +static int simple_config_check(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cf, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) { - static const 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; + 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; +} - cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); - if (!cfg_mem) - return -1; +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; +} - tuple = &cfg_mem->tuple; - parse = &cfg_mem->parse; - cf = &parse->cftable_entry; - buf = cfg_mem->buf; +static int simple_config(struct pcmcia_device *link) +{ + struct serial_info *info = link->priv; + int i = -ENODEV, try; /* If the card is already configured, look up the port and irq */ - i = pcmcia_get_configuration_info(link, &config); - if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) { + if (link->function_config) { unsigned int port = 0; - if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) { - port = config.BasePort2; + if ((link->io.BasePort2 != 0) && + (link->io.NumPorts2 == 8)) { + port = link->io.BasePort2; info->slave = 1; } else if ((info->manfid == MANFID_OSITECH) && - (config.NumPorts1 == 0x40)) { - port = config.BasePort1 + 0x28; + (link->io.NumPorts1 == 0x40)) { + port = link->io.BasePort1 + 0x28; info->slave = 1; } if (info->slave) { - kfree(cfg_mem); - return setup_serial(link, info, port, config.AssignedIRQ); + return setup_serial(link, info, port, + link->irq.AssignedIRQ); } } - /* First pass: look for a config entry that looks normal. */ - tuple->TupleData = (cisdata_t *) buf; - tuple->TupleOffset = 0; - tuple->TupleDataMax = 255; - tuple->Attributes = 0; - tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; - /* Two tries: without IO aliases, then with aliases */ - for (s = 0; s < 2; s++) { - for (try = 0; try < 2; try++) { - i = first_tuple(link, tuple, parse); - while (i != CS_NO_MORE_ITEMS) { - if (i != CS_SUCCESS) - goto next_entry; - if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) - link->conf.Vpp = - cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; - if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) && - (cf->io.win[0].base != 0)) { - link->conf.ConfigIndex = cf->index; - link->io.BasePort1 = cf->io.win[0].base; - link->io.IOAddrLines = (try == 0) ? - 16 : cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) - goto found_port; - } -next_entry: - i = next_tuple(link, tuple, parse); - } - } - } + /* First pass: look for a config entry that looks normal. + * Two tries: without IO aliases, then with aliases */ + for (try = 0; try < 4; try++) + if (!pcmcia_loop_config(link, simple_config_check, &try)) + goto found_port; + /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ - i = first_tuple(link, tuple, parse); - while (i != CS_NO_MORE_ITEMS) { - if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && - ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { - link->conf.ConfigIndex = cf->index; - for (j = 0; j < 5; j++) { - link->io.BasePort1 = base[j]; - link->io.IOAddrLines = base[j] ? 16 : 3; - i = pcmcia_request_io(link, &link->io); - if (i == CS_SUCCESS) - goto found_port; - } - } - i = next_tuple(link, tuple, parse); - } + if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL)) + goto found_port; - found_port: - if (i != CS_SUCCESS) { - printk(KERN_NOTICE - "serial_cs: no usable port range found, giving up\n"); - cs_error(link, RequestIO, i); - kfree(cfg_mem); - return -1; - } + printk(KERN_NOTICE + "serial_cs: no usable port range found, giving up\n"); + cs_error(link, RequestIO, i); + return -1; +found_port: i = pcmcia_request_irq(link, &link->irq); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } @@ -569,88 +541,76 @@ next_entry: info->quirk->config(link); i = pcmcia_request_configuration(link, &link->conf); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestConfiguration, i); - kfree(cfg_mem); return -1; } - kfree(cfg_mem); return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); } -static int multi_config(struct pcmcia_device * link) +static int multi_config_check(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cf, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) { - 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; + 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; +} - 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; +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; +} - tuple->TupleData = (cisdata_t *) buf; - tuple->TupleOffset = 0; - tuple->TupleDataMax = 255; - tuple->Attributes = 0; - tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; +static int multi_config(struct pcmcia_device *link) +{ + struct serial_info *info = link->priv; + int i, base2 = 0; /* First, look for a generic full-sized window */ link->io.NumPorts1 = info->multi * 8; - i = first_tuple(link, tuple, parse); - while (i != CS_NO_MORE_ITEMS) { - /* The quad port cards have bad CIS's, so just look for a - window larger than 8 ports and assume it will be right */ - if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && - (cf->io.win[0].len > 8)) { - link->conf.ConfigIndex = cf->index; - link->io.BasePort1 = cf->io.win[0].base; - link->io.IOAddrLines = - cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link, &link->io); - base2 = link->io.BasePort1 + 8; - if (i == CS_SUCCESS) - break; - } - i = next_tuple(link, tuple, parse); - } - - /* If that didn't work, look for two windows */ - if (i != CS_SUCCESS) { + if (pcmcia_loop_config(link, multi_config_check, &base2)) { + /* If that didn't work, look for two windows */ link->io.NumPorts1 = link->io.NumPorts2 = 8; info->multi = 2; - i = first_tuple(link, tuple, parse); - while (i != CS_NO_MORE_ITEMS) { - if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { - link->conf.ConfigIndex = cf->index; - link->io.BasePort1 = cf->io.win[0].base; - link->io.BasePort2 = cf->io.win[1].base; - link->io.IOAddrLines = - cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link, &link->io); - base2 = link->io.BasePort2; - if (i == CS_SUCCESS) - break; - } - i = next_tuple(link, tuple, parse); + if (pcmcia_loop_config(link, multi_config_check_notpicky, + &base2)) { + printk(KERN_NOTICE "serial_cs: no usable port range" + "found, giving up\n"); + return -ENODEV; } } - if (i != CS_SUCCESS) { - cs_error(link, RequestIO, i); - rc = -1; - goto free_cfg_mem; - } - i = pcmcia_request_irq(link, &link->irq); - if (i != CS_SUCCESS) { + if (i != 0) { + /* FIXME: comment does not fit, error handling does not fit */ printk(KERN_NOTICE "serial_cs: no usable port range found, giving up\n"); cs_error(link, RequestIRQ, i); @@ -664,10 +624,9 @@ static int multi_config(struct pcmcia_device * link) info->quirk->config(link); i = pcmcia_request_configuration(link, &link->conf); - if (i != CS_SUCCESS) { + if (i != 0) { cs_error(link, RequestConfiguration, i); - rc = -1; - goto free_cfg_mem; + return -ENODEV; } /* The Oxford Semiconductor OXCF950 cards are in fact single-port: @@ -678,7 +637,8 @@ static int multi_config(struct pcmcia_device * link) info->prodid == PRODID_POSSIO_GCC)) { int err; - if (cf->index == 1 || cf->index == 3) { + if (link->conf.ConfigIndex == 1 || + link->conf.ConfigIndex == 3) { err = setup_serial(link, info, base2, link->irq.AssignedIRQ); base2 = link->io.BasePort1; @@ -695,18 +655,14 @@ static int multi_config(struct pcmcia_device * link) if (info->quirk && info->quirk->wakeup) info->quirk->wakeup(link); - rc = 0; - goto free_cfg_mem; + return 0; } setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); for (i = 0; i < info->multi - 1; i++) setup_serial(link, info, base2 + (8 * i), link->irq.AssignedIRQ); - rc = 0; -free_cfg_mem: - kfree(cfg_mem); - return rc; + return 0; } /*====================================================================== @@ -746,7 +702,7 @@ static int serial_config(struct pcmcia_device * link) /* Is this a compliant multifunction card? */ tuple->DesiredTuple = CISTPL_LONGLINK_MFC; tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; - info->multi = (first_tuple(link, tuple, parse) == CS_SUCCESS); + info->multi = (first_tuple(link, tuple, parse) == 0); /* Is this a multiport card? */ tuple->DesiredTuple = CISTPL_MANFID; @@ -770,7 +726,7 @@ static int serial_config(struct pcmcia_device * link) ((link->func_id == CISTPL_FUNCID_MULTI) || (link->func_id == CISTPL_FUNCID_SERIAL))) { tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; - if (first_tuple(link, tuple, parse) == CS_SUCCESS) { + if (first_tuple(link, tuple, parse) == 0) { if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) info->multi = cf->io.win[0].len >> 3; if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c index 24c2a46c147..fbfadbac67e 100644 --- a/drivers/ssb/pcmcia.c +++ b/drivers/ssb/pcmcia.c @@ -80,7 +80,7 @@ static int ssb_pcmcia_cfg_write(struct ssb_bus *bus, u8 offset, u8 value) reg.Action = CS_WRITE; reg.Value = value; res = pcmcia_access_configuration_register(bus->host_pcmcia, ®); - if (unlikely(res != CS_SUCCESS)) + if (unlikely(res != 0)) return -EBUSY; return 0; @@ -96,7 +96,7 @@ static int ssb_pcmcia_cfg_read(struct ssb_bus *bus, u8 offset, u8 *value) reg.Offset = offset; reg.Action = CS_READ; res = pcmcia_access_configuration_register(bus->host_pcmcia, ®); - if (unlikely(res != CS_SUCCESS)) + if (unlikely(res != 0)) return -EBUSY; *value = reg.Value; @@ -638,17 +638,17 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus, tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple); - GOTO_ERROR_ON(res != CS_SUCCESS, "MAC first tpl"); + GOTO_ERROR_ON(res != 0, "MAC first tpl"); res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple); - GOTO_ERROR_ON(res != CS_SUCCESS, "MAC first tpl data"); + GOTO_ERROR_ON(res != 0, "MAC first tpl data"); while (1) { GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1"); if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID) break; res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple); - GOTO_ERROR_ON(res != CS_SUCCESS, "MAC next tpl"); + GOTO_ERROR_ON(res != 0, "MAC next tpl"); res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple); - GOTO_ERROR_ON(res != CS_SUCCESS, "MAC next tpl data"); + GOTO_ERROR_ON(res != 0, "MAC next tpl data"); } GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size"); memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN); @@ -659,9 +659,9 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus, tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple); - GOTO_ERROR_ON(res != CS_SUCCESS, "VEN first tpl"); + GOTO_ERROR_ON(res != 0, "VEN first tpl"); res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple); - GOTO_ERROR_ON(res != CS_SUCCESS, "VEN first tpl data"); + GOTO_ERROR_ON(res != 0, "VEN first tpl data"); while (1) { GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1"); switch (tuple.TupleData[0]) { @@ -733,11 +733,11 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus, break; } res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple); - if (res == CS_NO_MORE_ITEMS) + if (res == -ENOSPC) break; - GOTO_ERROR_ON(res != CS_SUCCESS, "VEN next tpl"); + GOTO_ERROR_ON(res != 0, "VEN next tpl"); res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple); - GOTO_ERROR_ON(res != CS_SUCCESS, "VEN next tpl data"); + GOTO_ERROR_ON(res != 0, "VEN next tpl data"); } return 0; diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c index ff9a29b7633..347c3ed1d9f 100644 --- a/drivers/telephony/ixj_pcmcia.c +++ b/drivers/telephony/ixj_pcmcia.c @@ -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; } diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 5da63f53500..516848dd9b4 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -112,7 +112,8 @@ static struct platform_device platform_dev = { .num_resources = ARRAY_SIZE(resources), }; -static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) +static int sl811_hc_init(struct device *parent, resource_size_t base_addr, + int irq) { if (platform_dev.dev.parent) return -EBUSY; @@ -155,97 +156,72 @@ static void sl811_cs_release(struct pcmcia_device * link) platform_device_unregister(&platform_dev); } +static int sl811_cs_config_check(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + if (cfg->index == 0) + return -ENODEV; + + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { + if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 != vcc) + return -ENODEV; + } else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) { + if (dflt->vcc.param[CISTPL_POWER_VNOM]/10000 != vcc) + return -ENODEV; + } + + if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) + p_dev->conf.Vpp = + cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; + else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) + p_dev->conf.Vpp = + dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; + + /* we need an interrupt */ + if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1) + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; + + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + p_dev->io.BasePort1 = io->win[0].base; + p_dev->io.NumPorts1 = io->win[0].len; + + return pcmcia_request_io(p_dev, &p_dev->io); + } + pcmcia_disable_device(p_dev); + return -ENODEV; +} + + static int sl811_cs_config(struct pcmcia_device *link) { struct device *parent = &handle_to_dev(link); local_info_t *dev = link->priv; - tuple_t tuple; - cisparse_t parse; int last_fn, last_ret; - u_char buf[64]; - config_info_t conf; - cistpl_cftable_entry_t dflt = { 0 }; DBG(0, "sl811_cs_config(0x%p)\n", link); - /* Look up the current Vcc */ - CS_CHECK(GetConfigurationInfo, - pcmcia_get_configuration_info(link, &conf)); - - tuple.Attributes = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - while (1) { - cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - - if (pcmcia_get_tuple_data(link, &tuple) != 0 - || pcmcia_parse_tuple(link, &tuple, &parse) - != 0) - goto next_entry; - - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { - dflt = *cfg; - } - - if (cfg->index == 0) - goto next_entry; - - link->conf.ConfigIndex = cfg->index; - - /* Use power settings for Vcc and Vpp if present */ - /* Note that the CIS values need to be rescaled */ - if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { - if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 - != conf.Vcc) - goto next_entry; - } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { - if (dflt.vcc.param[CISTPL_POWER_VNOM]/10000 - != conf.Vcc) - goto next_entry; - } - - if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vpp = - cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; - else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) - link->conf.Vpp = - dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; - - /* we need an interrupt */ - if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) - link->conf.Attributes |= CONF_ENABLE_IRQ; - - /* IO window settings */ - link->io.NumPorts1 = link->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; - - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - link->io.BasePort1 = io->win[0].base; - link->io.NumPorts1 = io->win[0].len; - - if (pcmcia_request_io(link, &link->io) != 0) - goto next_entry; - } - break; - -next_entry: - pcmcia_disable_device(link); - last_ret = pcmcia_get_next_tuple(link, &tuple); - } + if (pcmcia_loop_config(link, sl811_cs_config_check, NULL)) + goto failed; /* require an IRQ and two registers */ if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) - goto cs_failed; + goto failed; if (link->conf.Attributes & CONF_ENABLE_IRQ) CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); else - goto cs_failed; + goto failed; CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); @@ -266,8 +242,9 @@ next_entry: if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) < 0) { cs_failed: - printk("sl811_cs_config failed\n"); cs_error(link, last_fn, last_ret); +failed: + printk(KERN_WARNING "sl811_cs_config failed\n"); sl811_cs_release(link); return -ENODEV; } diff --git a/include/pcmcia/ciscode.h b/include/pcmcia/ciscode.h index ad6e278ba7f..b417985708f 100644 --- a/include/pcmcia/ciscode.h +++ b/include/pcmcia/ciscode.h @@ -119,7 +119,7 @@ #define MANFID_TOSHIBA 0x0098 -#define MANFID_UNGERMANN 0x02c0 +#define MANFID_UNGERMANN 0x02c0 #define MANFID_XIRCOM 0x0105 diff --git a/include/pcmcia/cistpl.h b/include/pcmcia/cistpl.h index e2e10c1e9a0..cfdd5af77dc 100644 --- a/include/pcmcia/cistpl.h +++ b/include/pcmcia/cistpl.h @@ -573,44 +573,6 @@ typedef struct tuple_t { #define TUPLE_RETURN_LINK 0x01 #define TUPLE_RETURN_COMMON 0x02 -/* For ValidateCIS */ -typedef struct cisinfo_t { - u_int Chains; -} cisinfo_t; - #define CISTPL_MAX_CIS_SIZE 0x200 -/* For ReplaceCIS */ -typedef struct cisdump_t { - u_int Length; - cisdata_t Data[CISTPL_MAX_CIS_SIZE]; -} cisdump_t; - - -int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis); - -/* don't use outside of PCMCIA core yet */ -int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *tuple); -int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple); -int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple); -int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse); - -int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned int *count); - -/* ... but use these wrappers instead */ -#define pcmcia_get_first_tuple(p_dev, tuple) \ - pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple) - -#define pcmcia_get_next_tuple(p_dev, tuple) \ - pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple) - -#define pcmcia_get_tuple_data(p_dev, tuple) \ - pccard_get_tuple_data(p_dev->socket, tuple) - -#define pcmcia_parse_tuple(p_dev, tuple, parse) \ - pccard_parse_tuple(tuple, parse) - -#define pcmcia_validate_cis(p_dev, info) \ - pccard_validate_cis(p_dev->socket, p_dev->func, info) - #endif /* LINUX_CISTPL_H */ diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h index 45d84b27578..904468a191e 100644 --- a/include/pcmcia/cs.h +++ b/include/pcmcia/cs.h @@ -28,72 +28,16 @@ typedef struct conf_reg_t { #define CS_WRITE 2 /* for AdjustResourceInfo */ -typedef struct adjust_t { - u_int Action; - u_int Resource; - u_int Attributes; - union { - struct memory { - u_long Base; - u_long Size; - } memory; - struct io { - ioaddr_t BasePort; - ioaddr_t NumPorts; - u_int IOAddrLines; - } io; - struct irq { - u_int IRQ; - } irq; - } resource; -} adjust_t; - /* Action field */ #define REMOVE_MANAGED_RESOURCE 1 #define ADD_MANAGED_RESOURCE 2 -#define GET_FIRST_MANAGED_RESOURCE 3 -#define GET_NEXT_MANAGED_RESOURCE 4 -/* Resource field */ -#define RES_MEMORY_RANGE 1 -#define RES_IO_RANGE 2 -#define RES_IRQ 3 -/* Attribute field */ -#define RES_IRQ_TYPE 0x03 -#define RES_IRQ_TYPE_EXCLUSIVE 0 -#define RES_IRQ_TYPE_TIME 1 -#define RES_IRQ_TYPE_DYNAMIC 2 -#define RES_IRQ_CSC 0x04 -#define RES_SHARED 0x08 -#define RES_RESERVED 0x10 -#define RES_ALLOCATED 0x20 -#define RES_REMOVED 0x40 + typedef struct event_callback_args_t { struct pcmcia_device *client_handle; void *client_data; } event_callback_args_t; -/* for GetConfigurationInfo */ -typedef struct config_info_t { - u_char Function; - u_int Attributes; - u_int Vcc, Vpp1, Vpp2; - u_int IntType; - u_int ConfigBase; - u_char Status, Pin, Copy, Option, ExtStatus; - u_int Present; - u_int CardValues; - u_int AssignedIRQ; - u_int IRQAttributes; - ioaddr_t BasePort1; - ioaddr_t NumPorts1; - u_int Attributes1; - ioaddr_t BasePort2; - ioaddr_t NumPorts2; - u_int Attributes2; - u_int IOAddrLines; -} config_info_t; - /* For CardValues field */ #define CV_OPTION_VALUE 0x01 #define CV_STATUS_VALUE 0x02 @@ -257,22 +201,6 @@ typedef struct win_req_t { #define WIN_BAR_MASK 0xe000 #define WIN_BAR_SHIFT 13 -/* Attributes for RegisterClient -- UNUSED -- */ -#define INFO_MASTER_CLIENT 0x01 -#define INFO_IO_CLIENT 0x02 -#define INFO_MTD_CLIENT 0x04 -#define INFO_MEM_CLIENT 0x08 -#define MAX_NUM_CLIENTS 3 - -#define INFO_CARD_SHARE 0x10 -#define INFO_CARD_EXCL 0x20 - -typedef struct cs_status_t { - u_char Function; - event_t CardState; - event_t SocketState; -} cs_status_t; - typedef struct error_info_t { int func; int retcode; @@ -308,95 +236,4 @@ typedef struct error_info_t { #define CS_EVENT_3VCARD 0x200000 #define CS_EVENT_XVCARD 0x400000 -/* Return codes */ -#define CS_SUCCESS 0x00 -#define CS_BAD_ADAPTER 0x01 -#define CS_BAD_ATTRIBUTE 0x02 -#define CS_BAD_BASE 0x03 -#define CS_BAD_EDC 0x04 -#define CS_BAD_IRQ 0x06 -#define CS_BAD_OFFSET 0x07 -#define CS_BAD_PAGE 0x08 -#define CS_READ_FAILURE 0x09 -#define CS_BAD_SIZE 0x0a -#define CS_BAD_SOCKET 0x0b -#define CS_BAD_TYPE 0x0d -#define CS_BAD_VCC 0x0e -#define CS_BAD_VPP 0x0f -#define CS_BAD_WINDOW 0x11 -#define CS_WRITE_FAILURE 0x12 -#define CS_NO_CARD 0x14 -#define CS_UNSUPPORTED_FUNCTION 0x15 -#define CS_UNSUPPORTED_MODE 0x16 -#define CS_BAD_SPEED 0x17 -#define CS_BUSY 0x18 -#define CS_GENERAL_FAILURE 0x19 -#define CS_WRITE_PROTECTED 0x1a -#define CS_BAD_ARG_LENGTH 0x1b -#define CS_BAD_ARGS 0x1c -#define CS_CONFIGURATION_LOCKED 0x1d -#define CS_IN_USE 0x1e -#define CS_NO_MORE_ITEMS 0x1f -#define CS_OUT_OF_RESOURCE 0x20 -#define CS_BAD_HANDLE 0x21 - -#define CS_BAD_TUPLE 0x40 - -#ifdef __KERNEL__ - -/* - * The main Card Services entry point - */ - -enum service { - AccessConfigurationRegister, AddSocketServices, - AdjustResourceInfo, CheckEraseQueue, CloseMemory, CopyMemory, - DeregisterClient, DeregisterEraseQueue, GetCardServicesInfo, - GetClientInfo, GetConfigurationInfo, GetEventMask, - GetFirstClient, GetFirstPartion, GetFirstRegion, GetFirstTuple, - GetNextClient, GetNextPartition, GetNextRegion, GetNextTuple, - GetStatus, GetTupleData, MapLogSocket, MapLogWindow, MapMemPage, - MapPhySocket, MapPhyWindow, ModifyConfiguration, ModifyWindow, - OpenMemory, ParseTuple, ReadMemory, RegisterClient, - RegisterEraseQueue, RegisterMTD, RegisterTimer, - ReleaseConfiguration, ReleaseExclusive, ReleaseIO, ReleaseIRQ, - ReleaseSocketMask, ReleaseWindow, ReplaceSocketServices, - RequestConfiguration, RequestExclusive, RequestIO, RequestIRQ, - RequestSocketMask, RequestWindow, ResetCard, ReturnSSEntry, - SetEventMask, SetRegion, ValidateCIS, VendorSpecific, - WriteMemory, BindDevice, BindMTD, ReportError, - SuspendCard, ResumeCard, EjectCard, InsertCard, ReplaceCIS, - GetFirstWindow, GetNextWindow, GetMemPage -}; - -struct pcmcia_socket; - -int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, conf_reg_t *reg); -int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, config_info_t *config); -int pcmcia_get_mem_page(window_handle_t win, memreq_t *req); -int pcmcia_map_mem_page(window_handle_t win, memreq_t *req); -int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod); -int pcmcia_release_window(window_handle_t win); -int pcmcia_request_configuration(struct pcmcia_device *p_dev, config_req_t *req); -int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req); -int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req); -int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh); -int pcmcia_suspend_card(struct pcmcia_socket *skt); -int pcmcia_resume_card(struct pcmcia_socket *skt); -int pcmcia_eject_card(struct pcmcia_socket *skt); -int pcmcia_insert_card(struct pcmcia_socket *skt); -int pccard_reset_card(struct pcmcia_socket *skt); - -struct pcmcia_device * pcmcia_dev_present(struct pcmcia_device *p_dev); -void pcmcia_disable_device(struct pcmcia_device *p_dev); - -struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt); -void pcmcia_put_socket(struct pcmcia_socket *skt); - -/* compatibility functions */ -#define pcmcia_reset_card(p_dev, req) \ - pccard_reset_card(p_dev->socket) - -#endif /* __KERNEL__ */ - #endif /* _LINUX_CS_H */ diff --git a/include/pcmcia/cs_types.h b/include/pcmcia/cs_types.h index f402a0f435b..315965a3793 100644 --- a/include/pcmcia/cs_types.h +++ b/include/pcmcia/cs_types.h @@ -21,14 +21,6 @@ #include <sys/types.h> #endif -#if defined(__arm__) || defined(__mips__) || defined(__avr32__) || \ - defined(__bfin__) -/* This (ioaddr_t) is exposed to userspace & hence cannot be changed. */ -typedef u_int ioaddr_t; -#else -typedef u_short ioaddr_t; -#endif - typedef u_short socket_t; typedef u_int event_t; typedef u_char cisdata_t; diff --git a/include/pcmcia/device_id.h b/include/pcmcia/device_id.h index e04e0b0d9a2..c33ea08352b 100644 --- a/include/pcmcia/device_id.h +++ b/include/pcmcia/device_id.h @@ -1,10 +1,19 @@ /* - * Copyright (2003-2004) Dominik Brodowski <linux@brodo.de> - * David Woodhouse + * device_id.h -- PCMCIA driver matching helpers * - * License: GPL v2 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * (C) 2003 - 2004 David Woodhouse + * (C) 2003 - 2004 Dominik Brodowski */ +#ifndef _LINUX_PCMCIA_DEVICE_ID_H +#define _LINUX_PCMCIA_DEVICE_ID_H + +#ifdef __KERNEL__ + #define PCMCIA_DEVICE_MANF_CARD(manf, card) { \ .match_flags = PCMCIA_DEV_ID_MATCH_MANF_ID| \ PCMCIA_DEV_ID_MATCH_CARD_ID, \ @@ -256,3 +265,6 @@ #define PCMCIA_DEVICE_NULL { .match_flags = 0, } + +#endif /* __KERNEL__ */ +#endif /* _LINUX_PCMCIA_DEVICE_ID_H */ diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index b316027c853..a2be80b9a09 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h @@ -10,7 +10,7 @@ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * (C) 1999 David A. Hinds - * (C) 2003 - 2004 Dominik Brodowski + * (C) 2003 - 2008 Dominik Brodowski */ #ifndef _LINUX_DS_H @@ -23,108 +23,21 @@ #include <pcmcia/cs_types.h> #include <pcmcia/device_id.h> -typedef struct tuple_parse_t { - tuple_t tuple; - cisdata_t data[255]; - cisparse_t parse; -} tuple_parse_t; - -typedef struct win_info_t { - window_handle_t handle; - win_req_t window; - memreq_t map; -} win_info_t; - -typedef struct bind_info_t { - dev_info_t dev_info; - u_char function; - struct pcmcia_device *instance; - char name[DEV_NAME_LEN]; - u_short major, minor; - void *next; -} bind_info_t; - -typedef struct mtd_info_t { - dev_info_t dev_info; - u_int Attributes; - u_int CardOffset; -} mtd_info_t; - -typedef struct region_info_t { - u_int Attributes; - u_int CardOffset; - u_int RegionSize; - u_int AccessSpeed; - u_int BlockSize; - u_int PartMultiple; - u_char JedecMfr, JedecInfo; - memory_handle_t next; -} region_info_t; -#define REGION_TYPE 0x0001 -#define REGION_TYPE_CM 0x0000 -#define REGION_TYPE_AM 0x0001 -#define REGION_PREFETCH 0x0008 -#define REGION_CACHEABLE 0x0010 -#define REGION_BAR_MASK 0xe000 -#define REGION_BAR_SHIFT 13 - -typedef union ds_ioctl_arg_t { - adjust_t adjust; - config_info_t config; - tuple_t tuple; - tuple_parse_t tuple_parse; - client_req_t client_req; - cs_status_t status; - conf_reg_t conf_reg; - cisinfo_t cisinfo; - region_info_t region; - bind_info_t bind_info; - mtd_info_t mtd_info; - win_info_t win_info; - cisdump_t cisdump; -} ds_ioctl_arg_t; - -#define DS_ADJUST_RESOURCE_INFO _IOWR('d', 2, adjust_t) -#define DS_GET_CONFIGURATION_INFO _IOWR('d', 3, config_info_t) -#define DS_GET_FIRST_TUPLE _IOWR('d', 4, tuple_t) -#define DS_GET_NEXT_TUPLE _IOWR('d', 5, tuple_t) -#define DS_GET_TUPLE_DATA _IOWR('d', 6, tuple_parse_t) -#define DS_PARSE_TUPLE _IOWR('d', 7, tuple_parse_t) -#define DS_RESET_CARD _IO ('d', 8) -#define DS_GET_STATUS _IOWR('d', 9, cs_status_t) -#define DS_ACCESS_CONFIGURATION_REGISTER _IOWR('d', 10, conf_reg_t) -#define DS_VALIDATE_CIS _IOR ('d', 11, cisinfo_t) -#define DS_SUSPEND_CARD _IO ('d', 12) -#define DS_RESUME_CARD _IO ('d', 13) -#define DS_EJECT_CARD _IO ('d', 14) -#define DS_INSERT_CARD _IO ('d', 15) -#define DS_GET_FIRST_REGION _IOWR('d', 16, region_info_t) -#define DS_GET_NEXT_REGION _IOWR('d', 17, region_info_t) -#define DS_REPLACE_CIS _IOWR('d', 18, cisdump_t) -#define DS_GET_FIRST_WINDOW _IOR ('d', 19, win_info_t) -#define DS_GET_NEXT_WINDOW _IOWR('d', 20, win_info_t) -#define DS_GET_MEM_PAGE _IOWR('d', 21, win_info_t) - -#define DS_BIND_REQUEST _IOWR('d', 60, bind_info_t) -#define DS_GET_DEVICE_INFO _IOWR('d', 61, bind_info_t) -#define DS_GET_NEXT_DEVICE _IOWR('d', 62, bind_info_t) -#define DS_UNBIND_REQUEST _IOW ('d', 63, bind_info_t) -#define DS_BIND_MTD _IOWR('d', 64, mtd_info_t) - #ifdef __KERNEL__ #include <linux/device.h> #include <pcmcia/ss.h> -typedef struct dev_node_t { - char dev_name[DEV_NAME_LEN]; - u_short major, minor; - struct dev_node_t *next; -} dev_node_t; - - +/* + * PCMCIA device drivers (16-bit cards only; 32-bit cards require CardBus + * a.k.a. PCI drivers + */ struct pcmcia_socket; +struct pcmcia_device; struct config_t; +/* dynamic device IDs for PCMCIA device drivers. See + * Documentation/pcmcia/driver.txt for details. +*/ struct pcmcia_dynids { spinlock_t lock; struct list_head list; @@ -147,6 +60,14 @@ struct pcmcia_driver { int pcmcia_register_driver(struct pcmcia_driver *driver); void pcmcia_unregister_driver(struct pcmcia_driver *driver); +/* Some drivers use dev_node_t to store char or block device information. + * Don't use this in new drivers, though. + */ +typedef struct dev_node_t { + char dev_name[DEV_NAME_LEN]; + u_short major, minor; + struct dev_node_t *next; +} dev_node_t; struct pcmcia_device { /* the socket and the device_no [for multifunction devices] @@ -216,10 +137,304 @@ struct pcmcia_device { #define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev) #define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv) +/* deprecated -- don't use! */ #define handle_to_dev(handle) (handle->dev) -/* error reporting */ -void cs_error(struct pcmcia_device *handle, int func, int ret); + +/* (deprecated) error reporting by PCMCIA devices. Use dev_printk() + * or dev_dbg() directly in the driver, without referring to pcmcia_error_func() + * and/or pcmcia_error_ret() for those functions will go away soon. + */ +enum service { + AccessConfigurationRegister, AddSocketServices, + AdjustResourceInfo, CheckEraseQueue, CloseMemory, CopyMemory, + DeregisterClient, DeregisterEraseQueue, GetCardServicesInfo, + GetClientInfo, GetConfigurationInfo, GetEventMask, + GetFirstClient, GetFirstPartion, GetFirstRegion, GetFirstTuple, + GetNextClient, GetNextPartition, GetNextRegion, GetNextTuple, + GetStatus, GetTupleData, MapLogSocket, MapLogWindow, MapMemPage, + MapPhySocket, MapPhyWindow, ModifyConfiguration, ModifyWindow, + OpenMemory, ParseTuple, ReadMemory, RegisterClient, + RegisterEraseQueue, RegisterMTD, RegisterTimer, + ReleaseConfiguration, ReleaseExclusive, ReleaseIO, ReleaseIRQ, + ReleaseSocketMask, ReleaseWindow, ReplaceSocketServices, + RequestConfiguration, RequestExclusive, RequestIO, RequestIRQ, + RequestSocketMask, RequestWindow, ResetCard, ReturnSSEntry, + SetEventMask, SetRegion, ValidateCIS, VendorSpecific, + WriteMemory, BindDevice, BindMTD, ReportError, + SuspendCard, ResumeCard, EjectCard, InsertCard, ReplaceCIS, + GetFirstWindow, GetNextWindow, GetMemPage +}; +const char *pcmcia_error_func(int func); +const char *pcmcia_error_ret(int ret); + +#define cs_error(p_dev, func, ret) \ + { \ + dev_printk(KERN_NOTICE, &p_dev->dev, \ + "%s : %s\n", \ + pcmcia_error_func(func), \ + pcmcia_error_ret(ret)); \ + } + +/* CIS access. + * Use the pcmcia_* versions in PCMCIA drivers + */ +int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse); + +int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, + tuple_t *tuple); +#define pcmcia_get_first_tuple(p_dev, tuple) \ + pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple) + +int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, + tuple_t *tuple); +#define pcmcia_get_next_tuple(p_dev, tuple) \ + pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple) + +int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple); +#define pcmcia_get_tuple_data(p_dev, tuple) \ + pccard_get_tuple_data(p_dev->socket, tuple) + + +/* loop CIS entries for valid configuration */ +int pcmcia_loop_config(struct pcmcia_device *p_dev, + int (*conf_check) (struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cf, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data), + void *priv_data); + +/* is the device still there? */ +struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *p_dev); + +/* low-level interface reset */ +int pcmcia_reset_card(struct pcmcia_socket *skt); + +/* CIS config */ +int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, + conf_reg_t *reg); + +/* device configuration */ +int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req); +int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req); +int pcmcia_request_configuration(struct pcmcia_device *p_dev, + config_req_t *req); + +int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, + window_handle_t *wh); +int pcmcia_release_window(window_handle_t win); + +int pcmcia_get_mem_page(window_handle_t win, memreq_t *req); +int pcmcia_map_mem_page(window_handle_t win, memreq_t *req); + +int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod); +void pcmcia_disable_device(struct pcmcia_device *p_dev); #endif /* __KERNEL__ */ + + + +/* Below, there are only definitions which are used by + * - the PCMCIA ioctl + * - deprecated PCMCIA userspace tools only + * + * here be dragons ... here be dragons ... here be dragons ... here be drag + */ + +#if defined(CONFIG_PCMCIA_IOCTL) || !defined(__KERNEL__) + +#if defined(__arm__) || defined(__mips__) || defined(__avr32__) || \ + defined(__bfin__) +/* This (ioaddr_t) is exposed to userspace & hence cannot be changed. */ +typedef u_int ioaddr_t; +#else +typedef u_short ioaddr_t; +#endif + +/* for AdjustResourceInfo */ +typedef struct adjust_t { + u_int Action; + u_int Resource; + u_int Attributes; + union { + struct memory { + u_long Base; + u_long Size; + } memory; + struct io { + ioaddr_t BasePort; + ioaddr_t NumPorts; + u_int IOAddrLines; + } io; + struct irq { + u_int IRQ; + } irq; + } resource; +} adjust_t; + +/* Action field */ +#define REMOVE_MANAGED_RESOURCE 1 +#define ADD_MANAGED_RESOURCE 2 +#define GET_FIRST_MANAGED_RESOURCE 3 +#define GET_NEXT_MANAGED_RESOURCE 4 +/* Resource field */ +#define RES_MEMORY_RANGE 1 +#define RES_IO_RANGE 2 +#define RES_IRQ 3 +/* Attribute field */ +#define RES_IRQ_TYPE 0x03 +#define RES_IRQ_TYPE_EXCLUSIVE 0 +#define RES_IRQ_TYPE_TIME 1 +#define RES_IRQ_TYPE_DYNAMIC 2 +#define RES_IRQ_CSC 0x04 +#define RES_SHARED 0x08 +#define RES_RESERVED 0x10 +#define RES_ALLOCATED 0x20 +#define RES_REMOVED 0x40 + + +typedef struct tuple_parse_t { + tuple_t tuple; + cisdata_t data[255]; + cisparse_t parse; +} tuple_parse_t; + +typedef struct win_info_t { + window_handle_t handle; + win_req_t window; + memreq_t map; +} win_info_t; + +typedef struct bind_info_t { + dev_info_t dev_info; + u_char function; + struct pcmcia_device *instance; + char name[DEV_NAME_LEN]; + u_short major, minor; + void *next; +} bind_info_t; + +typedef struct mtd_info_t { + dev_info_t dev_info; + u_int Attributes; + u_int CardOffset; +} mtd_info_t; + +typedef struct region_info_t { + u_int Attributes; + u_int CardOffset; + u_int RegionSize; + u_int AccessSpeed; + u_int BlockSize; + u_int PartMultiple; + u_char JedecMfr, JedecInfo; + memory_handle_t next; +} region_info_t; + +#define REGION_TYPE 0x0001 +#define REGION_TYPE_CM 0x0000 +#define REGION_TYPE_AM 0x0001 +#define REGION_PREFETCH 0x0008 +#define REGION_CACHEABLE 0x0010 +#define REGION_BAR_MASK 0xe000 +#define REGION_BAR_SHIFT 13 + +/* For ReplaceCIS */ +typedef struct cisdump_t { + u_int Length; + cisdata_t Data[CISTPL_MAX_CIS_SIZE]; +} cisdump_t; + +/* for GetConfigurationInfo */ +typedef struct config_info_t { + u_char Function; + u_int Attributes; + u_int Vcc, Vpp1, Vpp2; + u_int IntType; + u_int ConfigBase; + u_char Status, Pin, Copy, Option, ExtStatus; + u_int Present; + u_int CardValues; + u_int AssignedIRQ; + u_int IRQAttributes; + ioaddr_t BasePort1; + ioaddr_t NumPorts1; + u_int Attributes1; + ioaddr_t BasePort2; + ioaddr_t NumPorts2; + u_int Attributes2; + u_int IOAddrLines; +} config_info_t; + +/* For ValidateCIS */ +typedef struct cisinfo_t { + u_int Chains; +} cisinfo_t; + +typedef struct cs_status_t { + u_char Function; + event_t CardState; + event_t SocketState; +} cs_status_t; + +typedef union ds_ioctl_arg_t { + adjust_t adjust; + config_info_t config; + tuple_t tuple; + tuple_parse_t tuple_parse; + client_req_t client_req; + cs_status_t status; + conf_reg_t conf_reg; + cisinfo_t cisinfo; + region_info_t region; + bind_info_t bind_info; + mtd_info_t mtd_info; + win_info_t win_info; + cisdump_t cisdump; +} ds_ioctl_arg_t; + +#define DS_ADJUST_RESOURCE_INFO _IOWR('d', 2, adjust_t) +#define DS_GET_CONFIGURATION_INFO _IOWR('d', 3, config_info_t) +#define DS_GET_FIRST_TUPLE _IOWR('d', 4, tuple_t) +#define DS_GET_NEXT_TUPLE _IOWR('d', 5, tuple_t) +#define DS_GET_TUPLE_DATA _IOWR('d', 6, tuple_parse_t) +#define DS_PARSE_TUPLE _IOWR('d', 7, tuple_parse_t) +#define DS_RESET_CARD _IO ('d', 8) +#define DS_GET_STATUS _IOWR('d', 9, cs_status_t) +#define DS_ACCESS_CONFIGURATION_REGISTER _IOWR('d', 10, conf_reg_t) +#define DS_VALIDATE_CIS _IOR ('d', 11, cisinfo_t) +#define DS_SUSPEND_CARD _IO ('d', 12) +#define DS_RESUME_CARD _IO ('d', 13) +#define DS_EJECT_CARD _IO ('d', 14) +#define DS_INSERT_CARD _IO ('d', 15) +#define DS_GET_FIRST_REGION _IOWR('d', 16, region_info_t) +#define DS_GET_NEXT_REGION _IOWR('d', 17, region_info_t) +#define DS_REPLACE_CIS _IOWR('d', 18, cisdump_t) +#define DS_GET_FIRST_WINDOW _IOR ('d', 19, win_info_t) +#define DS_GET_NEXT_WINDOW _IOWR('d', 20, win_info_t) +#define DS_GET_MEM_PAGE _IOWR('d', 21, win_info_t) + +#define DS_BIND_REQUEST _IOWR('d', 60, bind_info_t) +#define DS_GET_DEVICE_INFO _IOWR('d', 61, bind_info_t) +#define DS_GET_NEXT_DEVICE _IOWR('d', 62, bind_info_t) +#define DS_UNBIND_REQUEST _IOW ('d', 63, bind_info_t) +#define DS_BIND_MTD _IOWR('d', 64, mtd_info_t) + + +/* used in userspace only */ +#define CS_IN_USE 0x1e + +#define INFO_MASTER_CLIENT 0x01 +#define INFO_IO_CLIENT 0x02 +#define INFO_MTD_CLIENT 0x04 +#define INFO_MEM_CLIENT 0x08 +#define MAX_NUM_CLIENTS 3 + +#define INFO_CARD_SHARE 0x10 +#define INFO_CARD_EXCL 0x20 + + +#endif /* !defined(__KERNEL__) || defined(CONFIG_PCMCIA_IOCTL) */ + #endif /* _LINUX_DS_H */ diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index ed919dd9bb5..9b4ac9385f5 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h @@ -53,10 +53,10 @@ /* for GetSocket, SetSocket */ typedef struct socket_state_t { - u_int flags; - u_int csc_mask; - u_char Vcc, Vpp; - u_char io_irq; + u_int flags; + u_int csc_mask; + u_char Vcc, Vpp; + u_char io_irq; } socket_state_t; extern socket_state_t dead_socket; @@ -86,79 +86,22 @@ extern socket_state_t dead_socket; #define HOOK_POWER_PRE 0x01 #define HOOK_POWER_POST 0x02 - typedef struct pccard_io_map { - u_char map; - u_char flags; - u_short speed; - u_int start, stop; + u_char map; + u_char flags; + u_short speed; + u_int start, stop; } pccard_io_map; typedef struct pccard_mem_map { - u_char map; - u_char flags; - u_short speed; - u_long static_start; - u_int card_start; - struct resource *res; + u_char map; + u_char flags; + u_short speed; + u_long static_start; + u_int card_start; + struct resource *res; } pccard_mem_map; -typedef struct cb_bridge_map { - u_char map; - u_char flags; - u_int start, stop; -} cb_bridge_map; - -/* - * Socket operations. - */ -struct pcmcia_socket; - -struct pccard_operations { - int (*init)(struct pcmcia_socket *sock); - int (*suspend)(struct pcmcia_socket *sock); - int (*get_status)(struct pcmcia_socket *sock, u_int *value); - int (*set_socket)(struct pcmcia_socket *sock, socket_state_t *state); - int (*set_io_map)(struct pcmcia_socket *sock, struct pccard_io_map *io); - int (*set_mem_map)(struct pcmcia_socket *sock, struct pccard_mem_map *mem); -}; - -struct pccard_resource_ops { - int (*validate_mem) (struct pcmcia_socket *s); - int (*adjust_io_region) (struct resource *res, - unsigned long r_start, - unsigned long r_end, - struct pcmcia_socket *s); - struct resource* (*find_io) (unsigned long base, int num, - unsigned long align, - struct pcmcia_socket *s); - struct resource* (*find_mem) (unsigned long base, unsigned long num, - unsigned long align, int low, - struct pcmcia_socket *s); - int (*add_io) (struct pcmcia_socket *s, - unsigned int action, - unsigned long r_start, - unsigned long r_end); - int (*add_mem) (struct pcmcia_socket *s, - unsigned int action, - unsigned long r_start, - unsigned long r_end); - int (*init) (struct pcmcia_socket *s); - void (*exit) (struct pcmcia_socket *s); -}; -/* SS_CAP_STATIC_MAP */ -extern struct pccard_resource_ops pccard_static_ops; -/* !SS_CAP_STATIC_MAP */ -extern struct pccard_resource_ops pccard_nonstatic_ops; - -/* static mem, dynamic IO sockets */ -extern struct pccard_resource_ops pccard_iodyn_ops; - -/* - * Calls to set up low-level "Socket Services" drivers - */ -struct pcmcia_socket; - typedef struct io_window_t { u_int InUse, Config; struct resource *res; @@ -179,10 +122,25 @@ typedef struct window_t { /* Maximum number of memory windows per socket */ #define MAX_WIN 4 + +/* + * Socket operations. + */ +struct pcmcia_socket; +struct pccard_resource_ops; struct config_t; struct pcmcia_callback; struct user_info_t; +struct pccard_operations { + int (*init)(struct pcmcia_socket *s); + int (*suspend)(struct pcmcia_socket *s); + int (*get_status)(struct pcmcia_socket *s, u_int *value); + int (*set_socket)(struct pcmcia_socket *s, socket_state_t *state); + int (*set_io_map)(struct pcmcia_socket *s, struct pccard_io_map *io); + int (*set_mem_map)(struct pcmcia_socket *s, struct pccard_mem_map *mem); +}; + struct pcmcia_socket { struct module *owner; spinlock_t lock; @@ -199,8 +157,8 @@ struct pcmcia_socket { io_window_t io[MAX_IO_WIN]; window_t win[MAX_WIN]; struct list_head cis_cache; - u_int fake_cis_len; - char *fake_cis; + size_t fake_cis_len; + u8 *fake_cis; struct list_head socket_list; struct completion socket_released; @@ -218,12 +176,12 @@ struct pcmcia_socket { struct pci_dev * cb_dev; - /* socket setup is done so resources should be able to be allocated. Only - * if set to 1, calls to find_{io,mem}_region are handled, and insertion - * events are actually managed by the PCMCIA layer.*/ + /* socket setup is done so resources should be able to be allocated. + * Only if set to 1, calls to find_{io,mem}_region are handled, and + * insertio events are actually managed by the PCMCIA layer.*/ u8 resource_setup_done:1; - /* is set to one if resource setup is done using adjust_resource_info() */ + /* It's old if resource setup is done using adjust_resource_info() */ u8 resource_setup_old:1; u8 resource_setup_new:1; @@ -236,75 +194,101 @@ struct pcmcia_socket { /* Zoom video behaviour is so chip specific its not worth adding this to _ops */ - void (*zoom_video)(struct pcmcia_socket *, int); + void (*zoom_video)(struct pcmcia_socket *, + int); /* so is power hook */ int (*power_hook)(struct pcmcia_socket *sock, int operation); -#ifdef CONFIG_CARDBUS + /* allows tuning the CB bridge before loading driver for the CB card */ +#ifdef CONFIG_CARDBUS void (*tune_bridge)(struct pcmcia_socket *sock, struct pci_bus *bus); #endif /* state thread */ - struct mutex skt_mutex; /* protects socket h/w state */ - struct task_struct *thread; struct completion thread_done; - spinlock_t thread_lock; /* protects thread_events */ unsigned int thread_events; + /* protects socket h/w state */ + struct mutex skt_mutex; + /* protects thread_events */ + spinlock_t thread_lock; /* pcmcia (16-bit) */ struct pcmcia_callback *callback; #if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) - struct list_head devices_list; /* PCMCIA devices */ - u8 device_count; /* the number of devices, used - * only internally and subject - * to incorrectness and change */ + /* The following elements refer to 16-bit PCMCIA devices inserted + * into the socket */ + struct list_head devices_list; + + /* the number of devices, used only internally and subject to + * incorrectness and change */ + u8 device_count; + /* 16-bit state: */ struct { - u8 present:1, /* PCMCIA card is present in socket */ - busy:1, /* "master" ioctl is used */ - dead:1, /* pcmcia module is being unloaded */ - device_add_pending:1, /* a multifunction-device - * add event is pending */ - mfc_pfc:1, /* the pending event adds a mfc (1) or pfc (0) */ - reserved:3; - } pcmcia_state; - - struct work_struct device_add; /* for adding further pseudo-multifunction - * devices */ + /* PCMCIA card is present in socket */ + u8 present:1; + /* "master" ioctl is used */ + u8 busy:1; + /* pcmcia module is being unloaded */ + u8 dead:1; + /* a multifunction-device add event is pending */ + u8 device_add_pending:1; + /* the pending event adds a mfc (1) or pfc (0) */ + u8 mfc_pfc:1; + + u8 reserved:3; + } pcmcia_state; + + + /* for adding further pseudo-multifunction devices */ + struct work_struct device_add; #ifdef CONFIG_PCMCIA_IOCTL struct user_info_t *user; wait_queue_head_t queue; -#endif -#endif +#endif /* CONFIG_PCMCIA_IOCTL */ +#endif /* CONFIG_PCMCIA */ /* cardbus (32-bit) */ #ifdef CONFIG_CARDBUS struct resource * cb_cis_res; void __iomem *cb_cis_virt; -#endif +#endif /* CONFIG_CARDBUS */ /* socket device */ struct device dev; - void *driver_data; /* data internal to the socket driver */ - + /* data internal to the socket driver */ + void *driver_data; }; -struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr); +/* socket drivers must define the resource operations type they use. There + * are three options: + * - pccard_static_ops iomem and ioport areas are assigned statically + * - pccard_iodyn_ops iomem areas is assigned statically, ioport + * areas dynamically + * - pccard_nonstatic_ops iomem and ioport areas are assigned dynamically. + * If this option is selected, use + * "select PCCARD_NONSTATIC" in Kconfig. + */ +extern struct pccard_resource_ops pccard_static_ops; +extern struct pccard_resource_ops pccard_iodyn_ops; +extern struct pccard_resource_ops pccard_nonstatic_ops; +/* socket drivers are expected to use these callbacks in their .drv struct */ +extern int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state); +extern int pcmcia_socket_dev_resume(struct device *dev); + +/* socket drivers use this callback in their IRQ handler */ +extern void pcmcia_parse_events(struct pcmcia_socket *socket, + unsigned int events); -extern void pcmcia_parse_events(struct pcmcia_socket *socket, unsigned int events); +/* to register and unregister a socket */ extern int pcmcia_register_socket(struct pcmcia_socket *socket); extern void pcmcia_unregister_socket(struct pcmcia_socket *socket); -extern struct class pcmcia_socket_class; - -/* socket drivers are expected to use these callbacks in their .drv struct */ -extern int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state); -extern int pcmcia_socket_dev_resume(struct device *dev); #endif /* _LINUX_SS_H */ |