diff options
Diffstat (limited to 'drivers/ata/pata_pcmcia.c')
-rw-r--r-- | drivers/ata/pata_pcmcia.c | 33 |
1 files changed, 15 insertions, 18 deletions
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 4b8bd2021a9..20982065a49 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c | |||
@@ -151,7 +151,6 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | |||
151 | 151 | ||
152 | struct pcmcia_config_check { | 152 | struct pcmcia_config_check { |
153 | config_info_t conf; | 153 | config_info_t conf; |
154 | cistpl_cftable_entry_t dflt; | ||
155 | unsigned long ctl_base; | 154 | unsigned long ctl_base; |
156 | int skip_vcc; | 155 | int skip_vcc; |
157 | int is_kme; | 156 | int is_kme; |
@@ -159,6 +158,7 @@ struct pcmcia_config_check { | |||
159 | 158 | ||
160 | static int pcmcia_check_one_config(struct pcmcia_device *pdev, | 159 | static int pcmcia_check_one_config(struct pcmcia_device *pdev, |
161 | cistpl_cftable_entry_t *cfg, | 160 | cistpl_cftable_entry_t *cfg, |
161 | cistpl_cftable_entry_t *dflt, | ||
162 | void *priv_data) | 162 | void *priv_data) |
163 | { | 163 | { |
164 | struct pcmcia_config_check *stk = priv_data; | 164 | struct pcmcia_config_check *stk = priv_data; |
@@ -166,21 +166,23 @@ static int pcmcia_check_one_config(struct pcmcia_device *pdev, | |||
166 | /* Check for matching Vcc, unless we're desperate */ | 166 | /* Check for matching Vcc, unless we're desperate */ |
167 | if (!stk->skip_vcc) { | 167 | if (!stk->skip_vcc) { |
168 | if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { | 168 | if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { |
169 | if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) | 169 | if (stk->conf.Vcc != |
170 | goto next_entry; | 170 | cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) |
171 | } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { | 171 | return -ENODEV; |
172 | if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) | 172 | } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) { |
173 | goto next_entry; | 173 | if (stk->conf.Vcc != |
174 | dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) | ||
175 | return -ENODEV; | ||
174 | } | 176 | } |
175 | } | 177 | } |
176 | 178 | ||
177 | if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) | 179 | if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) |
178 | pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; | 180 | pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; |
179 | else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) | 181 | else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM)) |
180 | pdev->conf.Vpp = stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; | 182 | pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000; |
181 | 183 | ||
182 | if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) { | 184 | if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { |
183 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io; | 185 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; |
184 | pdev->io.BasePort1 = io->win[0].base; | 186 | pdev->io.BasePort1 = io->win[0].base; |
185 | pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | 187 | pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; |
186 | if (!(io->flags & CISTPL_IO_16BIT)) | 188 | if (!(io->flags & CISTPL_IO_16BIT)) |
@@ -190,23 +192,19 @@ static int pcmcia_check_one_config(struct pcmcia_device *pdev, | |||
190 | pdev->io.BasePort2 = io->win[1].base; | 192 | pdev->io.BasePort2 = io->win[1].base; |
191 | pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1; | 193 | pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1; |
192 | if (pcmcia_request_io(pdev, &pdev->io) != 0) | 194 | if (pcmcia_request_io(pdev, &pdev->io) != 0) |
193 | goto next_entry; | 195 | return -ENODEV; |
194 | stk->ctl_base = pdev->io.BasePort2; | 196 | stk->ctl_base = pdev->io.BasePort2; |
195 | } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { | 197 | } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { |
196 | pdev->io.NumPorts1 = io->win[0].len; | 198 | pdev->io.NumPorts1 = io->win[0].len; |
197 | pdev->io.NumPorts2 = 0; | 199 | pdev->io.NumPorts2 = 0; |
198 | if (pcmcia_request_io(pdev, &pdev->io) != 0) | 200 | if (pcmcia_request_io(pdev, &pdev->io) != 0) |
199 | goto next_entry; | 201 | return -ENODEV; |
200 | stk->ctl_base = pdev->io.BasePort1 + 0x0e; | 202 | stk->ctl_base = pdev->io.BasePort1 + 0x0e; |
201 | } else | 203 | } else |
202 | goto next_entry; | 204 | return -ENODEV; |
203 | /* If we've got this far, we're done */ | 205 | /* If we've got this far, we're done */ |
204 | return 0; | 206 | return 0; |
205 | } | 207 | } |
206 | next_entry: | ||
207 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) | ||
208 | memcpy(&stk->dflt, cfg, sizeof(stk->dflt)); | ||
209 | |||
210 | return -ENODEV; | 208 | return -ENODEV; |
211 | } | 209 | } |
212 | 210 | ||
@@ -264,7 +262,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) | |||
264 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(pdev, &stk->conf)); | 262 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(pdev, &stk->conf)); |
265 | stk->skip_vcc = io_base = ctl_base = 0; | 263 | stk->skip_vcc = io_base = ctl_base = 0; |
266 | if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) { | 264 | if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) { |
267 | memset(&stk->dflt, 0, sizeof(stk->dflt)); | ||
268 | stk->skip_vcc = 1; | 265 | stk->skip_vcc = 1; |
269 | if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) | 266 | if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) |
270 | goto failed; /* No suitable config found */ | 267 | goto failed; /* No suitable config found */ |