aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/legacy/ide-cs.c
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2008-08-02 09:30:31 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2008-08-22 19:22:00 -0400
commit8e2fc39ddea7fe8c6798837da282db88a09af793 (patch)
tree7cba37b5b86f4ff25562012a14e29424e3872de0 /drivers/ide/legacy/ide-cs.c
parent498ac1899b62626bf6879a251d75c22ec564c559 (diff)
pcmcia: pcmcia_config_loop() default CIS entry handling
Many drivers use the default CIS entry within their pcmcia_config_loop() callback function. Therefore, factor the default CIS entry handling out. Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/ide/legacy/ide-cs.c')
-rw-r--r--drivers/ide/legacy/ide-cs.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 8580becf226a..cc8eeaf80275 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -222,7 +222,6 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
222 222
223struct pcmcia_config_check { 223struct pcmcia_config_check {
224 config_info_t conf; 224 config_info_t conf;
225 cistpl_cftable_entry_t dflt;
226 unsigned long ctl_base; 225 unsigned long ctl_base;
227 int skip_vcc; 226 int skip_vcc;
228 int is_kme; 227 int is_kme;
@@ -230,6 +229,7 @@ struct pcmcia_config_check {
230 229
231static int pcmcia_check_one_config(struct pcmcia_device *pdev, 230static int pcmcia_check_one_config(struct pcmcia_device *pdev,
232 cistpl_cftable_entry_t *cfg, 231 cistpl_cftable_entry_t *cfg,
232 cistpl_cftable_entry_t *dflt,
233 void *priv_data) 233 void *priv_data)
234{ 234{
235 struct pcmcia_config_check *stk = priv_data; 235 struct pcmcia_config_check *stk = priv_data;
@@ -237,21 +237,23 @@ static int pcmcia_check_one_config(struct pcmcia_device *pdev,
237 /* Check for matching Vcc, unless we're desperate */ 237 /* Check for matching Vcc, unless we're desperate */
238 if (!stk->skip_vcc) { 238 if (!stk->skip_vcc) {
239 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { 239 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
240 if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) 240 if (stk->conf.Vcc !=
241 goto next_entry; 241 cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
242 } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { 242 return -ENODEV;
243 if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) 243 } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
244 goto next_entry; 244 if (stk->conf.Vcc !=
245 dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
246 return -ENODEV;
245 } 247 }
246 } 248 }
247 249
248 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) 250 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
249 pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; 251 pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
250 else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) 252 else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
251 pdev->conf.Vpp = stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; 253 pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
252 254
253 if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) { 255 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
254 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io; 256 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
255 pdev->conf.ConfigIndex = cfg->index; 257 pdev->conf.ConfigIndex = cfg->index;
256 pdev->io.BasePort1 = io->win[0].base; 258 pdev->io.BasePort1 = io->win[0].base;
257 pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; 259 pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
@@ -262,23 +264,19 @@ static int pcmcia_check_one_config(struct pcmcia_device *pdev,
262 pdev->io.BasePort2 = io->win[1].base; 264 pdev->io.BasePort2 = io->win[1].base;
263 pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1; 265 pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1;
264 if (pcmcia_request_io(pdev, &pdev->io) != 0) 266 if (pcmcia_request_io(pdev, &pdev->io) != 0)
265 goto next_entry; 267 return -ENODEV;
266 stk->ctl_base = pdev->io.BasePort2; 268 stk->ctl_base = pdev->io.BasePort2;
267 } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { 269 } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
268 pdev->io.NumPorts1 = io->win[0].len; 270 pdev->io.NumPorts1 = io->win[0].len;
269 pdev->io.NumPorts2 = 0; 271 pdev->io.NumPorts2 = 0;
270 if (pcmcia_request_io(pdev, &pdev->io) != 0) 272 if (pcmcia_request_io(pdev, &pdev->io) != 0)
271 goto next_entry; 273 return -ENODEV;
272 stk->ctl_base = pdev->io.BasePort1 + 0x0e; 274 stk->ctl_base = pdev->io.BasePort1 + 0x0e;
273 } else 275 } else
274 goto next_entry; 276 return -ENODEV;
275 /* If we've got this far, we're done */ 277 /* If we've got this far, we're done */
276 return 0; 278 return 0;
277 } 279 }
278next_entry:
279 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
280 memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
281
282 return -ENODEV; 280 return -ENODEV;
283} 281}
284 282
@@ -305,7 +303,6 @@ static int ide_config(struct pcmcia_device *link)
305 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf)); 303 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf));
306 stk->skip_vcc = io_base = ctl_base = 0; 304 stk->skip_vcc = io_base = ctl_base = 0;
307 if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) { 305 if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) {
308 memset(&stk->dflt, 0, sizeof(stk->dflt));
309 stk->skip_vcc = 1; 306 stk->skip_vcc = 1;
310 if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) 307 if (pcmcia_loop_config(link, pcmcia_check_one_config, stk))
311 goto failed; /* No suitable config found */ 308 goto failed; /* No suitable config found */