diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2008-07-29 02:38:55 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2008-08-22 19:21:23 -0400 |
commit | 0e6f9d2708409cd8e864cdb94edbe599872a19d1 (patch) | |
tree | 398f993c6a50996483e9b48285f4971fa72e6e4e /drivers/scsi/pcmcia/nsp_cs.c | |
parent | ed58872aa33e16a0d5352080e47c65fa14e6ad1c (diff) |
pcmcia: use pcmcia_loop_config in scsi pcmcia drivers
Use the config loop helper in scsi pcmcia drivers.
CC: James E.J. Bottomley <James.Bottomley@HansenPartnership.com>
CC: linux-scsi@vger.kernel.org
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/scsi/pcmcia/nsp_cs.c')
-rw-r--r-- | drivers/scsi/pcmcia/nsp_cs.c | 197 |
1 files changed, 100 insertions, 97 deletions
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index a221b6ef9fa9..a29a6f29c977 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c | |||
@@ -1607,133 +1607,136 @@ static void nsp_cs_detach(struct pcmcia_device *link) | |||
1607 | is received, to configure the PCMCIA socket, and to make the | 1607 | is received, to configure the PCMCIA socket, and to make the |
1608 | ethernet device available to the system. | 1608 | ethernet device available to the system. |
1609 | ======================================================================*/ | 1609 | ======================================================================*/ |
1610 | #define CS_CHECK(fn, ret) \ | ||
1611 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | ||
1612 | /*====================================================================*/ | ||
1613 | static int nsp_cs_config(struct pcmcia_device *link) | ||
1614 | { | ||
1615 | int ret; | ||
1616 | scsi_info_t *info = link->priv; | ||
1617 | tuple_t tuple; | ||
1618 | cisparse_t parse; | ||
1619 | int last_ret, last_fn; | ||
1620 | unsigned char tuple_data[64]; | ||
1621 | config_info_t conf; | ||
1622 | win_req_t req; | ||
1623 | memreq_t map; | ||
1624 | cistpl_cftable_entry_t dflt = { 0 }; | ||
1625 | struct Scsi_Host *host; | ||
1626 | nsp_hw_data *data = &nsp_data_base; | ||
1627 | |||
1628 | nsp_dbg(NSP_DEBUG_INIT, "in"); | ||
1629 | 1610 | ||
1630 | tuple.Attributes = 0; | 1611 | struct nsp_cs_configdata { |
1631 | tuple.TupleData = tuple_data; | 1612 | nsp_hw_data *data; |
1632 | tuple.TupleDataMax = sizeof(tuple_data); | 1613 | win_req_t req; |
1633 | tuple.TupleOffset = 0; | 1614 | config_info_t conf; |
1634 | 1615 | cistpl_cftable_entry_t dflt; | |
1635 | /* Look up the current Vcc */ | 1616 | }; |
1636 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); | ||
1637 | 1617 | ||
1638 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 1618 | static int nsp_cs_config_check(struct pcmcia_device *p_dev, |
1639 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 1619 | cistpl_cftable_entry_t *cfg, |
1640 | while (1) { | 1620 | void *priv_data) |
1641 | cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); | 1621 | { |
1622 | struct nsp_cs_configdata *cfg_mem = priv_data; | ||
1642 | 1623 | ||
1643 | if (pcmcia_get_tuple_data(link, &tuple) != 0 || | 1624 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) |
1644 | pcmcia_parse_tuple(link, &tuple, &parse) != 0) | 1625 | memcpy(&cfg_mem->dflt, cfg, sizeof(cistpl_cftable_entry_t)); |
1645 | goto next_entry; | 1626 | if (cfg->index == 0) |
1627 | return -ENODEV; | ||
1646 | 1628 | ||
1647 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } | 1629 | p_dev->conf.ConfigIndex = cfg->index; |
1648 | if (cfg->index == 0) { goto next_entry; } | ||
1649 | link->conf.ConfigIndex = cfg->index; | ||
1650 | 1630 | ||
1651 | /* Does this card need audio output? */ | 1631 | /* Does this card need audio output? */ |
1652 | if (cfg->flags & CISTPL_CFTABLE_AUDIO) { | 1632 | if (cfg->flags & CISTPL_CFTABLE_AUDIO) { |
1653 | link->conf.Attributes |= CONF_ENABLE_SPKR; | 1633 | p_dev->conf.Attributes |= CONF_ENABLE_SPKR; |
1654 | link->conf.Status = CCSR_AUDIO_ENA; | 1634 | p_dev->conf.Status = CCSR_AUDIO_ENA; |
1655 | } | 1635 | } |
1656 | 1636 | ||
1657 | /* Use power settings for Vcc and Vpp if present */ | 1637 | /* Use power settings for Vcc and Vpp if present */ |
1658 | /* Note that the CIS values need to be rescaled */ | 1638 | /* Note that the CIS values need to be rescaled */ |
1659 | if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { | 1639 | if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { |
1660 | if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) { | 1640 | if (cfg_mem->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) |
1661 | goto next_entry; | 1641 | return -ENODEV; |
1662 | } | 1642 | else if (cfg_mem->dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { |
1663 | } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { | 1643 | if (cfg_mem->conf.Vcc != cfg_mem->dflt.vcc.param[CISTPL_POWER_VNOM]/10000) |
1664 | if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) { | 1644 | return -ENODEV; |
1665 | goto next_entry; | ||
1666 | } | ||
1667 | } | 1645 | } |
1668 | 1646 | ||
1669 | if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) { | 1647 | if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) { |
1670 | link->conf.Vpp = | 1648 | p_dev->conf.Vpp = |
1671 | cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; | 1649 | cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; |
1672 | } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) { | 1650 | } else if (cfg_mem->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) { |
1673 | link->conf.Vpp = | 1651 | p_dev->conf.Vpp = |
1674 | dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; | 1652 | cfg_mem->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; |
1675 | } | 1653 | } |
1676 | 1654 | ||
1677 | /* Do we need to allocate an interrupt? */ | 1655 | /* Do we need to allocate an interrupt? */ |
1678 | if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) { | 1656 | if (cfg->irq.IRQInfo1 || cfg_mem->dflt.irq.IRQInfo1) { |
1679 | link->conf.Attributes |= CONF_ENABLE_IRQ; | 1657 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; |
1680 | } | 1658 | } |
1681 | 1659 | ||
1682 | /* IO window settings */ | 1660 | /* IO window settings */ |
1683 | link->io.NumPorts1 = link->io.NumPorts2 = 0; | 1661 | p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; |
1684 | if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { | 1662 | if ((cfg->io.nwin > 0) || (cfg_mem->dflt.io.nwin > 0)) { |
1685 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; | 1663 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &cfg_mem->dflt.io; |
1686 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 1664 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
1687 | if (!(io->flags & CISTPL_IO_8BIT)) | 1665 | if (!(io->flags & CISTPL_IO_8BIT)) |
1688 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | 1666 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; |
1689 | if (!(io->flags & CISTPL_IO_16BIT)) | 1667 | if (!(io->flags & CISTPL_IO_16BIT)) |
1690 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 1668 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
1691 | link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | 1669 | p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; |
1692 | link->io.BasePort1 = io->win[0].base; | 1670 | p_dev->io.BasePort1 = io->win[0].base; |
1693 | link->io.NumPorts1 = io->win[0].len; | 1671 | p_dev->io.NumPorts1 = io->win[0].len; |
1694 | if (io->nwin > 1) { | 1672 | if (io->nwin > 1) { |
1695 | link->io.Attributes2 = link->io.Attributes1; | 1673 | p_dev->io.Attributes2 = p_dev->io.Attributes1; |
1696 | link->io.BasePort2 = io->win[1].base; | 1674 | p_dev->io.BasePort2 = io->win[1].base; |
1697 | link->io.NumPorts2 = io->win[1].len; | 1675 | p_dev->io.NumPorts2 = io->win[1].len; |
1698 | } | 1676 | } |
1699 | /* This reserves IO space but doesn't actually enable it */ | 1677 | /* This reserves IO space but doesn't actually enable it */ |
1700 | if (pcmcia_request_io(link, &link->io) != 0) | 1678 | if (pcmcia_request_io(p_dev, &p_dev->io) != 0) |
1701 | goto next_entry; | 1679 | goto next_entry; |
1702 | } | 1680 | } |
1703 | 1681 | ||
1704 | if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { | 1682 | if ((cfg->mem.nwin > 0) || (cfg_mem->dflt.mem.nwin > 0)) { |
1705 | cistpl_mem_t *mem = | 1683 | memreq_t map; |
1706 | (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; | 1684 | cistpl_mem_t *mem = |
1707 | req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; | 1685 | (cfg->mem.nwin) ? &cfg->mem : &cfg_mem->dflt.mem; |
1708 | req.Attributes |= WIN_ENABLE; | 1686 | cfg_mem->req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; |
1709 | req.Base = mem->win[0].host_addr; | 1687 | cfg_mem->req.Attributes |= WIN_ENABLE; |
1710 | req.Size = mem->win[0].len; | 1688 | cfg_mem->req.Base = mem->win[0].host_addr; |
1711 | if (req.Size < 0x1000) { | 1689 | cfg_mem->req.Size = mem->win[0].len; |
1712 | req.Size = 0x1000; | 1690 | if (cfg_mem->req.Size < 0x1000) |
1713 | } | 1691 | cfg_mem->req.Size = 0x1000; |
1714 | req.AccessSpeed = 0; | 1692 | cfg_mem->req.AccessSpeed = 0; |
1715 | if (pcmcia_request_window(&link, &req, &link->win) != 0) | 1693 | if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0) |
1716 | goto next_entry; | 1694 | goto next_entry; |
1717 | map.Page = 0; map.CardOffset = mem->win[0].card_addr; | 1695 | map.Page = 0; map.CardOffset = mem->win[0].card_addr; |
1718 | if (pcmcia_map_mem_page(link->win, &map) != 0) | 1696 | if (pcmcia_map_mem_page(p_dev->win, &map) != 0) |
1719 | goto next_entry; | 1697 | goto next_entry; |
1720 | 1698 | ||
1721 | data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size); | 1699 | cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size); |
1722 | data->MmioLength = req.Size; | 1700 | cfg_mem->data->MmioLength = cfg_mem->req.Size; |
1723 | } | 1701 | } |
1724 | /* If we got this far, we're cool! */ | 1702 | /* If we got this far, we're cool! */ |
1725 | break; | 1703 | return 0; |
1726 | |||
1727 | next_entry: | ||
1728 | nsp_dbg(NSP_DEBUG_INIT, "next"); | ||
1729 | pcmcia_disable_device(link); | ||
1730 | CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); | ||
1731 | } | 1704 | } |
1732 | 1705 | ||
1706 | next_entry: | ||
1707 | nsp_dbg(NSP_DEBUG_INIT, "next"); | ||
1708 | pcmcia_disable_device(p_dev); | ||
1709 | return -ENODEV; | ||
1710 | } | ||
1711 | |||
1712 | static int nsp_cs_config(struct pcmcia_device *link) | ||
1713 | { | ||
1714 | int ret; | ||
1715 | scsi_info_t *info = link->priv; | ||
1716 | struct nsp_cs_configdata *cfg_mem; | ||
1717 | struct Scsi_Host *host; | ||
1718 | nsp_hw_data *data = &nsp_data_base; | ||
1719 | |||
1720 | nsp_dbg(NSP_DEBUG_INIT, "in"); | ||
1721 | |||
1722 | cfg_mem = kzalloc(sizeof(cfg_mem), GFP_KERNEL); | ||
1723 | if (!cfg_mem) | ||
1724 | return -ENOMEM; | ||
1725 | cfg_mem->data = data; | ||
1726 | |||
1727 | /* Look up the current Vcc */ | ||
1728 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &cfg_mem->conf)); | ||
1729 | ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem); | ||
1730 | goto cs_failed; | ||
1731 | |||
1733 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | 1732 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { |
1734 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); | 1733 | if (pcmcia_request_irq(link, &link->irq)) |
1734 | goto cs_failed; | ||
1735 | } | 1735 | } |
1736 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); | 1736 | |
1737 | ret = pcmcia_request_configuration(link, &link->conf); | ||
1738 | if (ret) | ||
1739 | goto cs_failed; | ||
1737 | 1740 | ||
1738 | if (free_ports) { | 1741 | if (free_ports) { |
1739 | if (link->io.BasePort1) { | 1742 | if (link->io.BasePort1) { |
@@ -1791,20 +1794,20 @@ static int nsp_cs_config(struct pcmcia_device *link) | |||
1791 | printk(" & 0x%04x-0x%04x", link->io.BasePort2, | 1794 | printk(" & 0x%04x-0x%04x", link->io.BasePort2, |
1792 | link->io.BasePort2+link->io.NumPorts2-1); | 1795 | link->io.BasePort2+link->io.NumPorts2-1); |
1793 | if (link->win) | 1796 | if (link->win) |
1794 | printk(", mem 0x%06lx-0x%06lx", req.Base, | 1797 | printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base, |
1795 | req.Base+req.Size-1); | 1798 | cfg_mem->req.Base+cfg_mem->req.Size-1); |
1796 | printk("\n"); | 1799 | printk("\n"); |
1797 | 1800 | ||
1801 | kfree(cfg_mem); | ||
1798 | return 0; | 1802 | return 0; |
1799 | 1803 | ||
1800 | cs_failed: | 1804 | cs_failed: |
1801 | nsp_dbg(NSP_DEBUG_INIT, "config fail"); | 1805 | nsp_dbg(NSP_DEBUG_INIT, "config fail"); |
1802 | cs_error(link, last_fn, last_ret); | ||
1803 | nsp_cs_release(link); | 1806 | nsp_cs_release(link); |
1807 | kfree(cfg_mem); | ||
1804 | 1808 | ||
1805 | return -ENODEV; | 1809 | return -ENODEV; |
1806 | } /* nsp_cs_config */ | 1810 | } /* nsp_cs_config */ |
1807 | #undef CS_CHECK | ||
1808 | 1811 | ||
1809 | 1812 | ||
1810 | /*====================================================================== | 1813 | /*====================================================================== |