diff options
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/legacy/ide-cs.c | 33 |
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 | ||
223 | struct pcmcia_config_check { | 223 | struct 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 | ||
231 | static int pcmcia_check_one_config(struct pcmcia_device *pdev, | 230 | static 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 | } |
278 | next_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 */ |