Commit 0e6f9d2708409cd8e864cdb94edbe599872a19d1
1 parent
ed58872aa3
Exists in
master
and in
7 other branches
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>
Showing 5 changed files with 183 additions and 198 deletions Side-by-side Diff
drivers/scsi/pcmcia/aha152x_stub.c
... | ... | @@ -140,44 +140,40 @@ |
140 | 140 | #define CS_CHECK(fn, ret) \ |
141 | 141 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
142 | 142 | |
143 | +static 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 | + | |
143 | 162 | static int aha152x_config_cs(struct pcmcia_device *link) |
144 | 163 | { |
145 | 164 | scsi_info_t *info = link->priv; |
146 | 165 | struct aha152x_setup s; |
147 | - tuple_t tuple; | |
148 | - cisparse_t parse; | |
149 | - int i, last_ret, last_fn; | |
150 | - u_char tuple_data[64]; | |
166 | + int last_ret, last_fn; | |
151 | 167 | struct Scsi_Host *host; |
152 | - | |
168 | + | |
153 | 169 | DEBUG(0, "aha152x_config(0x%p)\n", link); |
154 | 170 | |
155 | - tuple.TupleData = tuple_data; | |
156 | - tuple.TupleDataMax = 64; | |
157 | - tuple.TupleOffset = 0; | |
158 | - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | |
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)); | |
171 | + last_ret = pcmcia_loop_config(link, aha152x_config_check, NULL); | |
172 | + if (last_ret) { | |
173 | + cs_error(link, RequestIO, last_ret); | |
174 | + goto failed; | |
179 | 175 | } |
180 | - | |
176 | + | |
181 | 177 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); |
182 | 178 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); |
183 | 179 | |
... | ... | @@ -208,6 +204,7 @@ |
208 | 204 | |
209 | 205 | cs_failed: |
210 | 206 | cs_error(link, last_fn, last_ret); |
207 | +failed: | |
211 | 208 | aha152x_release_cs(link); |
212 | 209 | return -ENODEV; |
213 | 210 | } |
drivers/scsi/pcmcia/fdomain_stub.c
... | ... | @@ -123,34 +123,29 @@ |
123 | 123 | #define CS_CHECK(fn, ret) \ |
124 | 124 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
125 | 125 | |
126 | +static 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 | + | |
126 | 136 | static int fdomain_config(struct pcmcia_device *link) |
127 | 137 | { |
128 | 138 | scsi_info_t *info = link->priv; |
129 | - tuple_t tuple; | |
130 | - cisparse_t parse; | |
131 | - int i, last_ret, last_fn; | |
132 | - u_char tuple_data[64]; | |
139 | + int last_ret, last_fn; | |
133 | 140 | char str[22]; |
134 | 141 | struct Scsi_Host *host; |
135 | 142 | |
136 | 143 | DEBUG(0, "fdomain_config(0x%p)\n", link); |
137 | 144 | |
138 | - tuple.TupleData = tuple_data; | |
139 | - tuple.TupleDataMax = 64; | |
140 | - tuple.TupleOffset = 0; | |
141 | - | |
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)); | |
145 | + last_ret = pcmcia_loop_config(link, fdomain_config_check, NULL); | |
146 | + if (last_ret) { | |
147 | + cs_error(link, RequestIO, last_ret); | |
148 | + goto failed; | |
154 | 149 | } |
155 | 150 | |
156 | 151 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); |
... | ... | @@ -181,6 +176,7 @@ |
181 | 176 | |
182 | 177 | cs_failed: |
183 | 178 | cs_error(link, last_fn, last_ret); |
179 | +failed: | |
184 | 180 | fdomain_release(link); |
185 | 181 | return -ENODEV; |
186 | 182 | } /* fdomain_config */ |
drivers/scsi/pcmcia/nsp_cs.c
... | ... | @@ -1607,134 +1607,137 @@ |
1607 | 1607 | is received, to configure the PCMCIA socket, and to make the |
1608 | 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 | 1610 | |
1628 | - nsp_dbg(NSP_DEBUG_INIT, "in"); | |
1611 | +struct nsp_cs_configdata { | |
1612 | + nsp_hw_data *data; | |
1613 | + win_req_t req; | |
1614 | + config_info_t conf; | |
1615 | + cistpl_cftable_entry_t dflt; | |
1616 | +}; | |
1629 | 1617 | |
1630 | - tuple.Attributes = 0; | |
1631 | - tuple.TupleData = tuple_data; | |
1632 | - tuple.TupleDataMax = sizeof(tuple_data); | |
1633 | - tuple.TupleOffset = 0; | |
1618 | +static int nsp_cs_config_check(struct pcmcia_device *p_dev, | |
1619 | + cistpl_cftable_entry_t *cfg, | |
1620 | + void *priv_data) | |
1621 | +{ | |
1622 | + struct nsp_cs_configdata *cfg_mem = priv_data; | |
1634 | 1623 | |
1635 | - /* Look up the current Vcc */ | |
1636 | - CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); | |
1624 | + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) | |
1625 | + memcpy(&cfg_mem->dflt, cfg, sizeof(cistpl_cftable_entry_t)); | |
1626 | + if (cfg->index == 0) | |
1627 | + return -ENODEV; | |
1637 | 1628 | |
1638 | - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | |
1639 | - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | |
1640 | - while (1) { | |
1641 | - cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); | |
1629 | + p_dev->conf.ConfigIndex = cfg->index; | |
1642 | 1630 | |
1643 | - if (pcmcia_get_tuple_data(link, &tuple) != 0 || | |
1644 | - pcmcia_parse_tuple(link, &tuple, &parse) != 0) | |
1645 | - goto next_entry; | |
1631 | + /* Does this card need audio output? */ | |
1632 | + if (cfg->flags & CISTPL_CFTABLE_AUDIO) { | |
1633 | + p_dev->conf.Attributes |= CONF_ENABLE_SPKR; | |
1634 | + p_dev->conf.Status = CCSR_AUDIO_ENA; | |
1635 | + } | |
1646 | 1636 | |
1647 | - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } | |
1648 | - if (cfg->index == 0) { goto next_entry; } | |
1649 | - link->conf.ConfigIndex = cfg->index; | |
1650 | - | |
1651 | - /* Does this card need audio output? */ | |
1652 | - if (cfg->flags & CISTPL_CFTABLE_AUDIO) { | |
1653 | - link->conf.Attributes |= CONF_ENABLE_SPKR; | |
1654 | - link->conf.Status = CCSR_AUDIO_ENA; | |
1637 | + /* Use power settings for Vcc and Vpp if present */ | |
1638 | + /* Note that the CIS values need to be rescaled */ | |
1639 | + if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { | |
1640 | + if (cfg_mem->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) | |
1641 | + return -ENODEV; | |
1642 | + else if (cfg_mem->dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { | |
1643 | + if (cfg_mem->conf.Vcc != cfg_mem->dflt.vcc.param[CISTPL_POWER_VNOM]/10000) | |
1644 | + return -ENODEV; | |
1655 | 1645 | } |
1656 | 1646 | |
1657 | - /* Use power settings for Vcc and Vpp if present */ | |
1658 | - /* Note that the CIS values need to be rescaled */ | |
1659 | - if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { | |
1660 | - if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) { | |
1661 | - goto next_entry; | |
1662 | - } | |
1663 | - } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { | |
1664 | - if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) { | |
1665 | - goto next_entry; | |
1666 | - } | |
1667 | - } | |
1668 | - | |
1669 | 1647 | if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) { |
1670 | - link->conf.Vpp = | |
1648 | + p_dev->conf.Vpp = | |
1671 | 1649 | cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; |
1672 | - } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) { | |
1673 | - link->conf.Vpp = | |
1674 | - dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; | |
1650 | + } else if (cfg_mem->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) { | |
1651 | + p_dev->conf.Vpp = | |
1652 | + cfg_mem->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; | |
1675 | 1653 | } |
1676 | 1654 | |
1677 | 1655 | /* Do we need to allocate an interrupt? */ |
1678 | - if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) { | |
1679 | - link->conf.Attributes |= CONF_ENABLE_IRQ; | |
1656 | + if (cfg->irq.IRQInfo1 || cfg_mem->dflt.irq.IRQInfo1) { | |
1657 | + p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | |
1680 | 1658 | } |
1681 | 1659 | |
1682 | 1660 | /* IO window settings */ |
1683 | - link->io.NumPorts1 = link->io.NumPorts2 = 0; | |
1684 | - if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { | |
1685 | - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; | |
1686 | - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | |
1661 | + p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; | |
1662 | + if ((cfg->io.nwin > 0) || (cfg_mem->dflt.io.nwin > 0)) { | |
1663 | + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &cfg_mem->dflt.io; | |
1664 | + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | |
1687 | 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 | 1667 | if (!(io->flags & CISTPL_IO_16BIT)) |
1690 | - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | |
1691 | - link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | |
1692 | - link->io.BasePort1 = io->win[0].base; | |
1693 | - link->io.NumPorts1 = io->win[0].len; | |
1668 | + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | |
1669 | + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | |
1670 | + p_dev->io.BasePort1 = io->win[0].base; | |
1671 | + p_dev->io.NumPorts1 = io->win[0].len; | |
1694 | 1672 | if (io->nwin > 1) { |
1695 | - link->io.Attributes2 = link->io.Attributes1; | |
1696 | - link->io.BasePort2 = io->win[1].base; | |
1697 | - link->io.NumPorts2 = io->win[1].len; | |
1673 | + p_dev->io.Attributes2 = p_dev->io.Attributes1; | |
1674 | + p_dev->io.BasePort2 = io->win[1].base; | |
1675 | + p_dev->io.NumPorts2 = io->win[1].len; | |
1698 | 1676 | } |
1699 | 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 | 1679 | goto next_entry; |
1702 | 1680 | } |
1703 | 1681 | |
1704 | - if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { | |
1705 | - cistpl_mem_t *mem = | |
1706 | - (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; | |
1707 | - req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; | |
1708 | - req.Attributes |= WIN_ENABLE; | |
1709 | - req.Base = mem->win[0].host_addr; | |
1710 | - req.Size = mem->win[0].len; | |
1711 | - if (req.Size < 0x1000) { | |
1712 | - req.Size = 0x1000; | |
1713 | - } | |
1714 | - req.AccessSpeed = 0; | |
1715 | - if (pcmcia_request_window(&link, &req, &link->win) != 0) | |
1682 | + if ((cfg->mem.nwin > 0) || (cfg_mem->dflt.mem.nwin > 0)) { | |
1683 | + memreq_t map; | |
1684 | + cistpl_mem_t *mem = | |
1685 | + (cfg->mem.nwin) ? &cfg->mem : &cfg_mem->dflt.mem; | |
1686 | + cfg_mem->req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; | |
1687 | + cfg_mem->req.Attributes |= WIN_ENABLE; | |
1688 | + cfg_mem->req.Base = mem->win[0].host_addr; | |
1689 | + cfg_mem->req.Size = mem->win[0].len; | |
1690 | + if (cfg_mem->req.Size < 0x1000) | |
1691 | + cfg_mem->req.Size = 0x1000; | |
1692 | + cfg_mem->req.AccessSpeed = 0; | |
1693 | + if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0) | |
1716 | 1694 | goto next_entry; |
1717 | 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 | 1697 | goto next_entry; |
1720 | 1698 | |
1721 | - data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size); | |
1722 | - data->MmioLength = req.Size; | |
1699 | + cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size); | |
1700 | + cfg_mem->data->MmioLength = cfg_mem->req.Size; | |
1723 | 1701 | } |
1724 | 1702 | /* If we got this far, we're cool! */ |
1725 | - break; | |
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)); | |
1703 | + return 0; | |
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 | 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)); | |
1737 | 1736 | |
1737 | + ret = pcmcia_request_configuration(link, &link->conf); | |
1738 | + if (ret) | |
1739 | + goto cs_failed; | |
1740 | + | |
1738 | 1741 | if (free_ports) { |
1739 | 1742 | if (link->io.BasePort1) { |
1740 | 1743 | release_region(link->io.BasePort1, link->io.NumPorts1); |
1741 | 1744 | |
1742 | 1745 | |
1743 | 1746 | |
1744 | 1747 | |
... | ... | @@ -1791,20 +1794,20 @@ |
1791 | 1794 | printk(" & 0x%04x-0x%04x", link->io.BasePort2, |
1792 | 1795 | link->io.BasePort2+link->io.NumPorts2-1); |
1793 | 1796 | if (link->win) |
1794 | - printk(", mem 0x%06lx-0x%06lx", req.Base, | |
1795 | - req.Base+req.Size-1); | |
1797 | + printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base, | |
1798 | + cfg_mem->req.Base+cfg_mem->req.Size-1); | |
1796 | 1799 | printk("\n"); |
1797 | 1800 | |
1801 | + kfree(cfg_mem); | |
1798 | 1802 | return 0; |
1799 | 1803 | |
1800 | 1804 | cs_failed: |
1801 | 1805 | nsp_dbg(NSP_DEBUG_INIT, "config fail"); |
1802 | - cs_error(link, last_fn, last_ret); | |
1803 | 1806 | nsp_cs_release(link); |
1807 | + kfree(cfg_mem); | |
1804 | 1808 | |
1805 | 1809 | return -ENODEV; |
1806 | 1810 | } /* nsp_cs_config */ |
1807 | -#undef CS_CHECK | |
1808 | 1811 | |
1809 | 1812 | |
1810 | 1813 | /*====================================================================== |
drivers/scsi/pcmcia/qlogic_stub.c
... | ... | @@ -195,39 +195,32 @@ |
195 | 195 | #define CS_CHECK(fn, ret) \ |
196 | 196 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
197 | 197 | |
198 | +static 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 | + | |
198 | 212 | static int qlogic_config(struct pcmcia_device * link) |
199 | 213 | { |
200 | 214 | scsi_info_t *info = link->priv; |
201 | - tuple_t tuple; | |
202 | - cisparse_t parse; | |
203 | - int i, last_ret, last_fn; | |
204 | - unsigned short tuple_data[32]; | |
215 | + int last_ret, last_fn; | |
205 | 216 | struct Scsi_Host *host; |
206 | 217 | |
207 | 218 | DEBUG(0, "qlogic_config(0x%p)\n", link); |
208 | 219 | |
209 | - info->manf_id = link->manf_id; | |
210 | - | |
211 | - tuple.TupleData = (cisdata_t *) tuple_data; | |
212 | - tuple.TupleDataMax = 64; | |
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)); | |
220 | + last_ret = pcmcia_loop_config(link, qlogic_config_check, NULL); | |
221 | + if (last_ret) { | |
222 | + cs_error(link, RequestIO, last_ret); | |
223 | + goto failed; | |
231 | 224 | } |
232 | 225 | |
233 | 226 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); |
... | ... | @@ -262,6 +255,7 @@ |
262 | 255 | cs_failed: |
263 | 256 | cs_error(link, last_fn, last_ret); |
264 | 257 | pcmcia_disable_device(link); |
258 | +failed: | |
265 | 259 | return -ENODEV; |
266 | 260 | |
267 | 261 | } /* qlogic_config */ |
drivers/scsi/pcmcia/sym53c500_cs.c
... | ... | @@ -700,15 +700,26 @@ |
700 | 700 | #define CS_CHECK(fn, ret) \ |
701 | 701 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
702 | 702 | |
703 | +static 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 | + | |
703 | 717 | static int |
704 | 718 | SYM53C500_config(struct pcmcia_device *link) |
705 | 719 | { |
706 | 720 | struct scsi_info_t *info = link->priv; |
707 | - tuple_t tuple; | |
708 | - cisparse_t parse; | |
709 | - int i, last_ret, last_fn; | |
721 | + int last_ret, last_fn; | |
710 | 722 | int irq_level, port_base; |
711 | - unsigned short tuple_data[32]; | |
712 | 723 | struct Scsi_Host *host; |
713 | 724 | struct scsi_host_template *tpnt = &sym53c500_driver_template; |
714 | 725 | struct sym53c500_data *data; |
... | ... | @@ -717,27 +728,10 @@ |
717 | 728 | |
718 | 729 | info->manf_id = link->manf_id; |
719 | 730 | |
720 | - tuple.TupleData = (cisdata_t *)tuple_data; | |
721 | - tuple.TupleDataMax = 64; | |
722 | - tuple.TupleOffset = 0; | |
723 | - | |
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 | - } | |
739 | -next_entry: | |
740 | - CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); | |
731 | + last_ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL); | |
732 | + if (last_ret) { | |
733 | + cs_error(link, RequestIO, last_ret); | |
734 | + goto failed; | |
741 | 735 | } |
742 | 736 | |
743 | 737 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); |
... | ... | @@ -831,6 +825,7 @@ |
831 | 825 | |
832 | 826 | cs_failed: |
833 | 827 | cs_error(link, last_fn, last_ret); |
828 | +failed: | |
834 | 829 | SYM53C500_release(link); |
835 | 830 | return -ENODEV; |
836 | 831 | } /* SYM53C500_config */ |