aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pcmcia/nsp_cs.c
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2008-07-29 02:38:55 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2008-08-22 19:21:23 -0400
commit0e6f9d2708409cd8e864cdb94edbe599872a19d1 (patch)
tree398f993c6a50996483e9b48285f4971fa72e6e4e /drivers/scsi/pcmcia/nsp_cs.c
parented58872aa33e16a0d5352080e47c65fa14e6ad1c (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.c197
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) \
1611do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
1612/*====================================================================*/
1613static 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; 1611struct 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; 1618static 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
1706next_entry:
1707 nsp_dbg(NSP_DEBUG_INIT, "next");
1708 pcmcia_disable_device(p_dev);
1709 return -ENODEV;
1710}
1711
1712static 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/*======================================================================