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