aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pcmcia
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
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')
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c57
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c36
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c197
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c46
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c45
5 files changed, 183 insertions, 198 deletions
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 2dd0dc9a9aed..bbcc20f2d9d0 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -140,44 +140,40 @@ static void aha152x_detach(struct pcmcia_device *link)
140#define CS_CHECK(fn, ret) \ 140#define CS_CHECK(fn, ret) \
141do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 141do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
142 142
143static int aha152x_config_check(struct pcmcia_device *p_dev,
144 cistpl_cftable_entry_t *cfg,
145 void *priv_data)
146{
147 /* For New Media T&J, look for a SCSI window */
148 if (cfg->io.win[0].len >= 0x20)
149 p_dev->io.BasePort1 = cfg->io.win[0].base;
150 else if ((cfg->io.nwin > 1) &&
151 (cfg->io.win[1].len >= 0x20))
152 p_dev->io.BasePort1 = cfg->io.win[1].base;
153 if ((cfg->io.nwin > 0) &&
154 (p_dev->io.BasePort1 < 0xffff)) {
155 p_dev->conf.ConfigIndex = cfg->index;
156 if (!pcmcia_request_io(p_dev, &p_dev->io))
157 return 0;
158 }
159 return -EINVAL;
160}
161
143static int aha152x_config_cs(struct pcmcia_device *link) 162static int aha152x_config_cs(struct pcmcia_device *link)
144{ 163{
145 scsi_info_t *info = link->priv; 164 scsi_info_t *info = link->priv;
146 struct aha152x_setup s; 165 struct aha152x_setup s;
147 tuple_t tuple; 166 int last_ret, last_fn;
148 cisparse_t parse;
149 int i, last_ret, last_fn;
150 u_char tuple_data[64];
151 struct Scsi_Host *host; 167 struct Scsi_Host *host;
152 168
153 DEBUG(0, "aha152x_config(0x%p)\n", link); 169 DEBUG(0, "aha152x_config(0x%p)\n", link);
154 170
155 tuple.TupleData = tuple_data; 171 last_ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
156 tuple.TupleDataMax = 64; 172 if (last_ret) {
157 tuple.TupleOffset = 0; 173 cs_error(link, RequestIO, last_ret);
158 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 174 goto failed;
159 tuple.Attributes = 0;
160 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
161 while (1) {
162 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
163 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
164 goto next_entry;
165 /* For New Media T&J, look for a SCSI window */
166 if (parse.cftable_entry.io.win[0].len >= 0x20)
167 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
168 else if ((parse.cftable_entry.io.nwin > 1) &&
169 (parse.cftable_entry.io.win[1].len >= 0x20))
170 link->io.BasePort1 = parse.cftable_entry.io.win[1].base;
171 if ((parse.cftable_entry.io.nwin > 0) &&
172 (link->io.BasePort1 < 0xffff)) {
173 link->conf.ConfigIndex = parse.cftable_entry.index;
174 i = pcmcia_request_io(link, &link->io);
175 if (i == CS_SUCCESS) break;
176 }
177 next_entry:
178 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
179 } 175 }
180 176
181 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 177 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
182 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); 178 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
183 179
@@ -208,6 +204,7 @@ static int aha152x_config_cs(struct pcmcia_device *link)
208 204
209cs_failed: 205cs_failed:
210 cs_error(link, last_fn, last_ret); 206 cs_error(link, last_fn, last_ret);
207failed:
211 aha152x_release_cs(link); 208 aha152x_release_cs(link);
212 return -ENODEV; 209 return -ENODEV;
213} 210}
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index d8b99351b053..fefef7d81f14 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -123,34 +123,29 @@ static void fdomain_detach(struct pcmcia_device *link)
123#define CS_CHECK(fn, ret) \ 123#define CS_CHECK(fn, ret) \
124do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 124do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
125 125
126static int fdomain_config_check(struct pcmcia_device *p_dev,
127 cistpl_cftable_entry_t *cfg,
128 void *priv_data)
129{
130 p_dev->conf.ConfigIndex = cfg->index;
131 p_dev->io.BasePort1 = cfg->io.win[0].base;
132 return pcmcia_request_io(p_dev, &p_dev->io);
133}
134
135
126static int fdomain_config(struct pcmcia_device *link) 136static int fdomain_config(struct pcmcia_device *link)
127{ 137{
128 scsi_info_t *info = link->priv; 138 scsi_info_t *info = link->priv;
129 tuple_t tuple; 139 int last_ret, last_fn;
130 cisparse_t parse;
131 int i, last_ret, last_fn;
132 u_char tuple_data[64];
133 char str[22]; 140 char str[22];
134 struct Scsi_Host *host; 141 struct Scsi_Host *host;
135 142
136 DEBUG(0, "fdomain_config(0x%p)\n", link); 143 DEBUG(0, "fdomain_config(0x%p)\n", link);
137 144
138 tuple.TupleData = tuple_data; 145 last_ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
139 tuple.TupleDataMax = 64; 146 if (last_ret) {
140 tuple.TupleOffset = 0; 147 cs_error(link, RequestIO, last_ret);
141 148 goto failed;
142 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
143 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
144 while (1) {
145 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
146 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
147 goto next_entry;
148 link->conf.ConfigIndex = parse.cftable_entry.index;
149 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
150 i = pcmcia_request_io(link, &link->io);
151 if (i == CS_SUCCESS) break;
152 next_entry:
153 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
154 } 149 }
155 150
156 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 151 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
@@ -181,6 +176,7 @@ static int fdomain_config(struct pcmcia_device *link)
181 176
182cs_failed: 177cs_failed:
183 cs_error(link, last_fn, last_ret); 178 cs_error(link, last_fn, last_ret);
179failed:
184 fdomain_release(link); 180 fdomain_release(link);
185 return -ENODEV; 181 return -ENODEV;
186} /* fdomain_config */ 182} /* fdomain_config */
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/*======================================================================
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index 67c5a58d17df..aa9b9e0968b6 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -195,39 +195,32 @@ static void qlogic_detach(struct pcmcia_device *link)
195#define CS_CHECK(fn, ret) \ 195#define CS_CHECK(fn, ret) \
196do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 196do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
197 197
198static int qlogic_config_check(struct pcmcia_device *p_dev,
199 cistpl_cftable_entry_t *cfg,
200 void *priv_data)
201{
202 p_dev->conf.ConfigIndex = cfg->index;
203 p_dev->io.BasePort1 = cfg->io.win[0].base;
204 p_dev->io.NumPorts1 = cfg->io.win[0].len;
205
206 if (p_dev->io.BasePort1 == 0)
207 return -ENODEV;
208
209 return pcmcia_request_io(p_dev, &p_dev->io);
210}
211
198static int qlogic_config(struct pcmcia_device * link) 212static int qlogic_config(struct pcmcia_device * link)
199{ 213{
200 scsi_info_t *info = link->priv; 214 scsi_info_t *info = link->priv;
201 tuple_t tuple; 215 int last_ret, last_fn;
202 cisparse_t parse;
203 int i, last_ret, last_fn;
204 unsigned short tuple_data[32];
205 struct Scsi_Host *host; 216 struct Scsi_Host *host;
206 217
207 DEBUG(0, "qlogic_config(0x%p)\n", link); 218 DEBUG(0, "qlogic_config(0x%p)\n", link);
208 219
209 info->manf_id = link->manf_id; 220 last_ret = pcmcia_loop_config(link, qlogic_config_check, NULL);
210 221 if (last_ret) {
211 tuple.TupleData = (cisdata_t *) tuple_data; 222 cs_error(link, RequestIO, last_ret);
212 tuple.TupleDataMax = 64; 223 goto failed;
213 tuple.TupleOffset = 0;
214
215 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
216 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
217 while (1) {
218 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
219 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
220 goto next_entry;
221 link->conf.ConfigIndex = parse.cftable_entry.index;
222 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
223 link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
224 if (link->io.BasePort1 != 0) {
225 i = pcmcia_request_io(link, &link->io);
226 if (i == CS_SUCCESS)
227 break;
228 }
229 next_entry:
230 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
231 } 224 }
232 225
233 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 226 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
@@ -262,6 +255,7 @@ static int qlogic_config(struct pcmcia_device * link)
262cs_failed: 255cs_failed:
263 cs_error(link, last_fn, last_ret); 256 cs_error(link, last_fn, last_ret);
264 pcmcia_disable_device(link); 257 pcmcia_disable_device(link);
258failed:
265 return -ENODEV; 259 return -ENODEV;
266 260
267} /* qlogic_config */ 261} /* qlogic_config */
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 0be232b58ffb..15369d9e3121 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -700,15 +700,26 @@ static struct scsi_host_template sym53c500_driver_template = {
700#define CS_CHECK(fn, ret) \ 700#define CS_CHECK(fn, ret) \
701do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 701do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
702 702
703static int SYM53C500_config_check(struct pcmcia_device *p_dev,
704 cistpl_cftable_entry_t *cfg,
705 void *priv_data)
706{
707 p_dev->conf.ConfigIndex = cfg->index;
708 p_dev->io.BasePort1 = cfg->io.win[0].base;
709 p_dev->io.NumPorts1 = cfg->io.win[0].len;
710
711 if (p_dev->io.BasePort1 == 0)
712 return -ENODEV;
713
714 return pcmcia_request_io(p_dev, &p_dev->io);
715}
716
703static int 717static int
704SYM53C500_config(struct pcmcia_device *link) 718SYM53C500_config(struct pcmcia_device *link)
705{ 719{
706 struct scsi_info_t *info = link->priv; 720 struct scsi_info_t *info = link->priv;
707 tuple_t tuple; 721 int last_ret, last_fn;
708 cisparse_t parse;
709 int i, last_ret, last_fn;
710 int irq_level, port_base; 722 int irq_level, port_base;
711 unsigned short tuple_data[32];
712 struct Scsi_Host *host; 723 struct Scsi_Host *host;
713 struct scsi_host_template *tpnt = &sym53c500_driver_template; 724 struct scsi_host_template *tpnt = &sym53c500_driver_template;
714 struct sym53c500_data *data; 725 struct sym53c500_data *data;
@@ -717,27 +728,10 @@ SYM53C500_config(struct pcmcia_device *link)
717 728
718 info->manf_id = link->manf_id; 729 info->manf_id = link->manf_id;
719 730
720 tuple.TupleData = (cisdata_t *)tuple_data; 731 last_ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
721 tuple.TupleDataMax = 64; 732 if (last_ret) {
722 tuple.TupleOffset = 0; 733 cs_error(link, RequestIO, last_ret);
723 734 goto failed;
724 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
725 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
726 while (1) {
727 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
728 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
729 goto next_entry;
730 link->conf.ConfigIndex = parse.cftable_entry.index;
731 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
732 link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
733
734 if (link->io.BasePort1 != 0) {
735 i = pcmcia_request_io(link, &link->io);
736 if (i == CS_SUCCESS)
737 break;
738 }
739next_entry:
740 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
741 } 735 }
742 736
743 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 737 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
@@ -831,6 +825,7 @@ err_release:
831 825
832cs_failed: 826cs_failed:
833 cs_error(link, last_fn, last_ret); 827 cs_error(link, last_fn, last_ret);
828failed:
834 SYM53C500_release(link); 829 SYM53C500_release(link);
835 return -ENODEV; 830 return -ENODEV;
836} /* SYM53C500_config */ 831} /* SYM53C500_config */