diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-07-30 07:13:46 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-09-29 11:20:24 -0400 |
commit | 00990e7ce0b0e596fe41d9c64d6933ea70084003 (patch) | |
tree | 189e0dd92860feba84231c66955749574cac5d6d /drivers/ide | |
parent | 440eed43e2a95bb842488755683716814da10f2b (diff) |
pcmcia: use autoconfiguration feature for ioports and iomem
When CONF_AUTO_SET_IO or CONF_AUTO_SET_IOMEM are set, the corresponding
fields in struct pcmcia_device *p_dev->resource[0,1,2] are set
accordinly. Drivers wishing to override certain settings may do so in
the callback function, but they no longer need to parse the CIS entries
stored in cistpl_cftable_entry_t themselves.
CC: netdev@vger.kernel.org
CC: linux-wireless@vger.kernel.org
CC: linux-ide@vger.kernel.org
CC: linux-usb@vger.kernel.org
CC: laforge@gnumonks.org
CC: linux-mtd@lists.infradead.org
CC: linux-bluetooth@vger.kernel.org
CC: alsa-devel@alsa-project.org
CC: linux-serial@vger.kernel.org
CC: Jiri Kosina <jkosina@suse.cz>
CC: linux-scsi@vger.kernel.org
Tested-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ide-cs.c | 82 |
1 files changed, 25 insertions, 57 deletions
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c index 25b8a105a98d..c389d9a28881 100644 --- a/drivers/ide/ide-cs.c +++ b/drivers/ide/ide-cs.c | |||
@@ -96,10 +96,8 @@ static int ide_probe(struct pcmcia_device *link) | |||
96 | info->p_dev = link; | 96 | info->p_dev = link; |
97 | link->priv = info; | 97 | link->priv = info; |
98 | 98 | ||
99 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; | 99 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO | |
100 | link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; | 100 | CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC; |
101 | link->config_flags |= CONF_ENABLE_IRQ; | ||
102 | link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC; | ||
103 | 101 | ||
104 | return ide_config(link); | 102 | return ide_config(link); |
105 | } /* ide_attach */ | 103 | } /* ide_attach */ |
@@ -194,52 +192,31 @@ out_release: | |||
194 | 192 | ||
195 | ======================================================================*/ | 193 | ======================================================================*/ |
196 | 194 | ||
197 | struct pcmcia_config_check { | 195 | static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data) |
198 | unsigned long ctl_base; | ||
199 | int is_kme; | ||
200 | }; | ||
201 | |||
202 | static int pcmcia_check_one_config(struct pcmcia_device *pdev, | ||
203 | cistpl_cftable_entry_t *cfg, | ||
204 | cistpl_cftable_entry_t *dflt, | ||
205 | void *priv_data) | ||
206 | { | 196 | { |
207 | struct pcmcia_config_check *stk = priv_data; | 197 | int *is_kme = priv_data; |
208 | 198 | ||
209 | if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { | 199 | if (!(pdev->resource[0]->flags & IO_DATA_PATH_WIDTH_8)) { |
210 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; | 200 | pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
211 | pdev->io_lines = io->flags & CISTPL_IO_LINES_MASK; | 201 | pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; |
212 | pdev->config_index = cfg->index; | 202 | } |
213 | pdev->resource[0]->start = io->win[0].base; | 203 | pdev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH; |
214 | if (!(io->flags & CISTPL_IO_16BIT)) { | 204 | pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; |
215 | pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; | 205 | |
216 | pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | 206 | if (pdev->resource[1]->end) { |
217 | } | 207 | pdev->resource[0]->end = 8; |
218 | if (io->nwin == 2) { | 208 | pdev->resource[1]->end = (*is_kme) ? 2 : 1; |
219 | pdev->resource[0]->end = 8; | 209 | } else { |
220 | pdev->resource[1]->start = io->win[1].base; | 210 | if (pdev->resource[0]->end < 16) |
221 | pdev->resource[1]->end = (stk->is_kme) ? 2 : 1; | ||
222 | if (pcmcia_request_io(pdev) != 0) | ||
223 | return -ENODEV; | ||
224 | stk->ctl_base = pdev->resource[1]->start; | ||
225 | } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { | ||
226 | pdev->resource[0]->end = io->win[0].len; | ||
227 | pdev->resource[1]->end = 0; | ||
228 | if (pcmcia_request_io(pdev) != 0) | ||
229 | return -ENODEV; | ||
230 | stk->ctl_base = pdev->resource[0]->start + 0x0e; | ||
231 | } else | ||
232 | return -ENODEV; | 211 | return -ENODEV; |
233 | /* If we've got this far, we're done */ | ||
234 | return 0; | ||
235 | } | 212 | } |
236 | return -ENODEV; | 213 | |
214 | return pcmcia_request_io(pdev); | ||
237 | } | 215 | } |
238 | 216 | ||
239 | static int ide_config(struct pcmcia_device *link) | 217 | static int ide_config(struct pcmcia_device *link) |
240 | { | 218 | { |
241 | ide_info_t *info = link->priv; | 219 | ide_info_t *info = link->priv; |
242 | struct pcmcia_config_check *stk = NULL; | ||
243 | int ret = 0, is_kme = 0; | 220 | int ret = 0, is_kme = 0; |
244 | unsigned long io_base, ctl_base; | 221 | unsigned long io_base, ctl_base; |
245 | struct ide_host *host; | 222 | struct ide_host *host; |
@@ -250,19 +227,16 @@ static int ide_config(struct pcmcia_device *link) | |||
250 | ((link->card_id == PRODID_KME_KXLC005_A) || | 227 | ((link->card_id == PRODID_KME_KXLC005_A) || |
251 | (link->card_id == PRODID_KME_KXLC005_B))); | 228 | (link->card_id == PRODID_KME_KXLC005_B))); |
252 | 229 | ||
253 | stk = kzalloc(sizeof(*stk), GFP_KERNEL); | 230 | if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme)) { |
254 | if (!stk) | ||
255 | goto err_mem; | ||
256 | stk->is_kme = is_kme; | ||
257 | io_base = ctl_base = 0; | ||
258 | |||
259 | if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) { | ||
260 | link->config_flags &= ~CONF_AUTO_CHECK_VCC; | 231 | link->config_flags &= ~CONF_AUTO_CHECK_VCC; |
261 | if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) | 232 | if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme)) |
262 | goto failed; /* No suitable config found */ | 233 | goto failed; /* No suitable config found */ |
263 | } | 234 | } |
264 | io_base = link->resource[0]->start; | 235 | io_base = link->resource[0]->start; |
265 | ctl_base = stk->ctl_base; | 236 | if (link->resource[1]->end) |
237 | ctl_base = link->resource[1]->start; | ||
238 | else | ||
239 | ctl_base = link->resource[0]->start + 0x0e; | ||
266 | 240 | ||
267 | if (!link->irq) | 241 | if (!link->irq) |
268 | goto failed; | 242 | goto failed; |
@@ -294,15 +268,9 @@ static int ide_config(struct pcmcia_device *link) | |||
294 | 'a' + host->ports[0]->index * 2, | 268 | 'a' + host->ports[0]->index * 2, |
295 | link->vpp / 10, link->vpp % 10); | 269 | link->vpp / 10, link->vpp % 10); |
296 | 270 | ||
297 | kfree(stk); | ||
298 | return 0; | 271 | return 0; |
299 | 272 | ||
300 | err_mem: | ||
301 | printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n"); | ||
302 | goto failed; | ||
303 | |||
304 | failed: | 273 | failed: |
305 | kfree(stk); | ||
306 | ide_release(link); | 274 | ide_release(link); |
307 | return -ENODEV; | 275 | return -ENODEV; |
308 | } /* ide_config */ | 276 | } /* ide_config */ |